diff options
| author | Conrad Meyer <cem@FreeBSD.org> | 2016-09-22 00:25:23 +0000 |
|---|---|---|
| committer | Conrad Meyer <cem@FreeBSD.org> | 2016-09-22 00:25:23 +0000 |
| commit | 14410265b6a2d5ef5fc50948bd229efec968ac78 (patch) | |
| tree | 7ff758c0073e79bb6b8b9efbb4f325f6333d0fb5 /sys/dev/oce | |
| parent | 764c812d8473c3487ca6a200e3bee2b469729995 (diff) | |
Notes
Diffstat (limited to 'sys/dev/oce')
| -rw-r--r-- | sys/dev/oce/oce_hw.c | 5 | ||||
| -rw-r--r-- | sys/dev/oce/oce_hw.h | 527 | ||||
| -rw-r--r-- | sys/dev/oce/oce_if.c | 1136 | ||||
| -rw-r--r-- | sys/dev/oce/oce_if.h | 122 | ||||
| -rw-r--r-- | sys/dev/oce/oce_mbox.c | 304 | ||||
| -rw-r--r-- | sys/dev/oce/oce_queue.c | 285 | ||||
| -rw-r--r-- | sys/dev/oce/oce_sysctl.c | 175 |
7 files changed, 493 insertions, 2061 deletions
diff --git a/sys/dev/oce/oce_hw.c b/sys/dev/oce/oce_hw.c index 72f3c556f85e..aad5795a97e5 100644 --- a/sys/dev/oce/oce_hw.c +++ b/sys/dev/oce/oce_hw.c @@ -393,11 +393,6 @@ oce_create_nw_interface(POCE_SOFTC sc) if (IS_SH(sc) || IS_XE201(sc)) capab_flags |= MBX_RX_IFACE_FLAGS_MULTICAST; - if (sc->enable_hwlro) { - capab_flags |= MBX_RX_IFACE_FLAGS_LRO; - capab_en_flags |= MBX_RX_IFACE_FLAGS_LRO; - } - /* enable capabilities controlled via driver startup parameters */ if (is_rss_enabled(sc)) capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS; diff --git a/sys/dev/oce/oce_hw.h b/sys/dev/oce/oce_hw.h index edb029c1e282..1ad3f7889e0b 100644 --- a/sys/dev/oce/oce_hw.h +++ b/sys/dev/oce/oce_hw.h @@ -111,9 +111,6 @@ #define PD_MPU_MBOX_DB 0x0160 #define PD_MQ_DB 0x0140 -#define DB_OFFSET 0xc0 -#define DB_LRO_RQ_ID_MASK 0x7FF - /* EQE completion types */ #define EQ_MINOR_CODE_COMPLETION 0x00 #define EQ_MINOR_CODE_OTHER 0x01 @@ -183,7 +180,6 @@ #define ASYNC_EVENT_GRP5 0x5 #define ASYNC_EVENT_CODE_DEBUG 0x6 #define ASYNC_EVENT_PVID_STATE 0x3 -#define ASYNC_EVENT_OS2BMC 0x5 #define ASYNC_EVENT_DEBUG_QNQ 0x1 #define ASYNC_EVENT_CODE_SLIPORT 0x11 #define VLAN_VID_MASK 0x0FFF @@ -726,34 +722,6 @@ struct oce_async_cqe_link_state { } u0; }; -/* OS2BMC async event */ -struct oce_async_evt_grp5_os2bmc { - union { - struct { - uint32_t lrn_enable:1; - uint32_t lrn_disable:1; - uint32_t mgmt_enable:1; - uint32_t mgmt_disable:1; - uint32_t rsvd0:12; - uint32_t vlan_tag:16; - uint32_t arp_filter:1; - uint32_t dhcp_client_filt:1; - uint32_t dhcp_server_filt:1; - uint32_t net_bios_filt:1; - uint32_t rsvd1:3; - uint32_t bcast_filt:1; - uint32_t ipv6_nbr_filt:1; - uint32_t ipv6_ra_filt:1; - uint32_t ipv6_ras_filt:1; - uint32_t rsvd2[4]; - uint32_t mcast_filt:1; - uint32_t rsvd3:16; - uint32_t evt_tag; - uint32_t dword3; - } s; - uint32_t dword[4]; - } u; -}; /* PVID aync event */ struct oce_async_event_grp5_pvid_state { @@ -1428,7 +1396,7 @@ typedef union oce_cq_ctx_u { uint32_t dw5rsvd3:1; uint32_t eventable:1; /* dw6 */ - uint32_t eq_id:16; + uint32_t eq_id:8; uint32_t dw6rsvd1:15; uint32_t armed:1; /* dw7 */ @@ -2435,8 +2403,8 @@ struct oce_nic_hdr_wqe { uint32_t tcpcs:1; uint32_t udpcs:1; uint32_t ipcs:1; - uint32_t mgmt:1; - uint32_t lso6:1; + uint32_t rsvd3:1; + uint32_t rsvd2:1; uint32_t forward:1; uint32_t crc:1; uint32_t event:1; @@ -2458,8 +2426,8 @@ struct oce_nic_hdr_wqe { uint32_t event:1; uint32_t crc:1; uint32_t forward:1; - uint32_t lso6:1; - uint32_t mgmt:1; + uint32_t rsvd2:1; + uint32_t rsvd3:1; uint32_t ipcs:1; uint32_t udpcs:1; uint32_t tcpcs:1; @@ -3042,53 +3010,6 @@ struct oce_rxf_stats_v0 { uint32_t rsvd1[6]; }; -struct oce_port_rxf_stats_v2 { - uint32_t rsvd0[10]; - uint32_t roce_bytes_received_lsd; - uint32_t roce_bytes_received_msd; - uint32_t rsvd1[5]; - uint32_t roce_frames_received; - uint32_t rx_crc_errors; - uint32_t rx_alignment_symbol_errors; - uint32_t rx_pause_frames; - uint32_t rx_priority_pause_frames; - uint32_t rx_control_frames; - uint32_t rx_in_range_errors; - uint32_t rx_out_range_errors; - uint32_t rx_frame_too_long; - uint32_t rx_address_match_errors; - uint32_t rx_dropped_too_small; - uint32_t rx_dropped_too_short; - uint32_t rx_dropped_header_too_small; - uint32_t rx_dropped_tcp_length; - uint32_t rx_dropped_runt; - uint32_t rsvd2[10]; - uint32_t rx_ip_checksum_errs; - uint32_t rx_tcp_checksum_errs; - uint32_t rx_udp_checksum_errs; - uint32_t rsvd3[7]; - uint32_t rx_switched_unicast_packets; - uint32_t rx_switched_multicast_packets; - uint32_t rx_switched_broadcast_packets; - uint32_t rsvd4[3]; - uint32_t tx_pauseframes; - uint32_t tx_priority_pauseframes; - uint32_t tx_controlframes; - uint32_t rsvd5[10]; - uint32_t rxpp_fifo_overflow_drop; - uint32_t rx_input_fifo_overflow_drop; - uint32_t pmem_fifo_overflow_drop; - uint32_t jabber_events; - uint32_t rsvd6[3]; - uint32_t rx_drops_payload_size; - uint32_t rx_drops_clipped_header; - uint32_t rx_drops_crc; - uint32_t roce_drops_payload_len; - uint32_t roce_drops_crc; - uint32_t rsvd7[19]; -}; - - struct oce_port_rxf_stats_v1 { uint32_t rsvd0[12]; uint32_t rx_crc_errors; @@ -3125,20 +3046,6 @@ struct oce_port_rxf_stats_v1 { uint32_t rsvd5[3]; }; -struct oce_rxf_stats_v2 { - struct oce_port_rxf_stats_v2 port[4]; - uint32_t rsvd0[2]; - uint32_t rx_drops_no_pbuf; - uint32_t rx_drops_no_txpb; - uint32_t rx_drops_no_erx_descr; - uint32_t rx_drops_no_tpre_descr; - uint32_t rsvd1[6]; - uint32_t rx_drops_too_many_frags; - uint32_t rx_drops_invalid_ring; - uint32_t forwarded_packets; - uint32_t rx_drops_mtu; - uint32_t rsvd2[35]; -}; struct oce_rxf_stats_v1 { struct oce_port_rxf_stats_v1 port[4]; @@ -3155,11 +3062,6 @@ struct oce_rxf_stats_v1 { uint32_t rsvd2[14]; }; -struct oce_erx_stats_v2 { - uint32_t rx_drops_no_fragments[136]; - uint32_t rsvd[3]; -}; - struct oce_erx_stats_v1 { uint32_t rx_drops_no_fragments[68]; uint32_t rsvd[4]; @@ -3176,15 +3078,6 @@ struct oce_pmem_stats { uint32_t rsvd[5]; }; -struct oce_hw_stats_v2 { - struct oce_rxf_stats_v2 rxf; - uint32_t rsvd0[OCE_TXP_SW_SZ]; - struct oce_erx_stats_v2 erx; - struct oce_pmem_stats pmem; - uint32_t rsvd1[18]; -}; - - struct oce_hw_stats_v1 { struct oce_rxf_stats_v1 rxf; uint32_t rsvd0[OCE_TXP_SW_SZ]; @@ -3200,22 +3093,32 @@ struct oce_hw_stats_v0 { struct oce_pmem_stats pmem; }; -#define MBX_GET_NIC_STATS(version) \ - struct mbx_get_nic_stats_v##version { \ - struct mbx_hdr hdr; \ - union { \ - struct { \ - uint32_t rsvd0; \ - } req; \ - union { \ - struct oce_hw_stats_v##version stats; \ - } rsp; \ - } params; \ -} +struct mbx_get_nic_stats_v0 { + struct mbx_hdr hdr; + union { + struct { + uint32_t rsvd0; + } req; + + union { + struct oce_hw_stats_v0 stats; + } rsp; + } params; +}; + +struct mbx_get_nic_stats { + struct mbx_hdr hdr; + union { + struct { + uint32_t rsvd0; + } req; + + struct { + struct oce_hw_stats_v1 stats; + } rsp; + } params; +}; -MBX_GET_NIC_STATS(0); -MBX_GET_NIC_STATS(1); -MBX_GET_NIC_STATS(2); /* [18(0x12)] NIC_GET_PPORT_STATS */ struct pport_stats { @@ -3825,373 +3728,3 @@ enum OCE_QUEUE_RX_STATS { QUEUE_RX_BUFFER_ERRORS = 8, QUEUE_RX_N_WORDS = 10 }; - -/* HW LRO structures */ -struct mbx_nic_query_lro_capabilities { - struct mbx_hdr hdr; - union { - struct { - uint32_t rsvd[6]; - } req; - struct { -#ifdef _BIG_ENDIAN - uint32_t lro_flags; - uint16_t lro_rq_cnt; - uint16_t plro_max_offload; - uint32_t rsvd[4]; -#else - uint32_t lro_flags; - uint16_t plro_max_offload; - uint16_t lro_rq_cnt; - uint32_t rsvd[4]; -#endif - } rsp; - } params; -}; - -struct mbx_nic_set_iface_lro_config { - struct mbx_hdr hdr; - union { - struct { -#ifdef _BIG_ENDIAN - uint32_t lro_flags; - uint32_t iface_id; - uint32_t max_clsc_byte_cnt; - uint32_t max_clsc_seg_cnt; - uint32_t max_clsc_usec_delay; - uint32_t min_clsc_frame_byte_cnt; - uint32_t rsvd[2]; -#else - uint32_t lro_flags; - uint32_t iface_id; - uint32_t max_clsc_byte_cnt; - uint32_t max_clsc_seg_cnt; - uint32_t max_clsc_usec_delay; - uint32_t min_clsc_frame_byte_cnt; - uint32_t rsvd[2]; -#endif - } req; - struct { -#ifdef _BIG_ENDIAN - uint32_t lro_flags; - uint32_t rsvd[7]; -#else - uint32_t lro_flags; - uint32_t rsvd[7]; -#endif - } rsp; - } params; -}; - - -struct mbx_create_nic_rq_v2 { - struct mbx_hdr hdr; - union { - struct { -#ifdef _BIG_ENDIAN - uint8_t num_pages; - uint8_t frag_size; - uint16_t cq_id; - - uint32_t if_id; - - uint16_t page_size; - uint16_t max_frame_size; - - uint16_t rsvd; - uint16_t pd_id; - - uint16_t rsvd1; - uint16_t rq_flags; - - uint16_t hds_fixed_offset; - uint8_t hds_start; - uint8_t hds_frag; - - uint16_t hds_backfill_size; - uint16_t hds_frag_size; - - uint32_t rbq_id; - - uint32_t rsvd2[8]; - - struct phys_addr pages[2]; -#else - uint16_t cq_id; - uint8_t frag_size; - uint8_t num_pages; - - uint32_t if_id; - - uint16_t max_frame_size; - uint16_t page_size; - - uint16_t pd_id; - uint16_t rsvd; - - uint16_t rq_flags; - uint16_t rsvd1; - - uint8_t hds_frag; - uint8_t hds_start; - uint16_t hds_fixed_offset; - - uint16_t hds_frag_size; - uint16_t hds_backfill_size; - - uint32_t rbq_id; - - uint32_t rsvd2[8]; - - struct phys_addr pages[2]; -#endif - } req; - struct { -#ifdef _BIG_ENDIAN - uint8_t rsvd0; - uint8_t rss_cpuid; - uint16_t rq_id; - - uint8_t db_format; - uint8_t db_reg_set; - uint16_t rsvd1; - - uint32_t db_offset; - - uint32_t rsvd2; - - uint16_t rsvd3; - uint16_t rq_flags; - -#else - uint16_t rq_id; - uint8_t rss_cpuid; - uint8_t rsvd0; - - uint16_t rsvd1; - uint8_t db_reg_set; - uint8_t db_format; - - uint32_t db_offset; - - uint32_t rsvd2; - - uint16_t rq_flags; - uint16_t rsvd3; -#endif - } rsp; - - } params; -}; - -struct mbx_delete_nic_rq_v1 { - struct mbx_hdr hdr; - union { - struct { -#ifdef _BIG_ENDIAN - uint16_t bypass_flush; - uint16_t rq_id; - uint16_t rsvd; - uint16_t rq_flags; -#else - uint16_t rq_id; - uint16_t bypass_flush; - uint16_t rq_flags; - uint16_t rsvd; -#endif - } req; - struct { - uint32_t rsvd[2]; - } rsp; - } params; -}; - -struct nic_hwlro_singleton_cqe { -#ifdef _BIG_ENDIAN - /* dw 0 */ - uint32_t ip_opt:1; - uint32_t vtp:1; - uint32_t pkt_size:14; - uint32_t vlan_tag:16; - - /* dw 1 */ - uint32_t num_frags:3; - uint32_t rsvd1:3; - uint32_t frag_index:10; - uint32_t rsvd:8; - uint32_t ipv6_frame:1; - uint32_t l4_cksum_pass:1; - uint32_t ip_cksum_pass:1; - uint32_t udpframe:1; - uint32_t tcpframe:1; - uint32_t ipframe:1; - uint32_t rss_hp:1; - uint32_t error:1; - - /* dw 2 */ - uint32_t valid:1; - uint32_t cqe_type:2; - uint32_t debug:7; - uint32_t rsvd4:6; - uint32_t data_offset:8; - uint32_t rsvd3:3; - uint32_t rss_bank:1; - uint32_t qnq:1; - uint32_t rsvd2:3; - - /* dw 3 */ - uint32_t rss_hash_value; -#else - /* dw 0 */ - uint32_t vlan_tag:16; - uint32_t pkt_size:14; - uint32_t vtp:1; - uint32_t ip_opt:1; - - /* dw 1 */ - uint32_t error:1; - uint32_t rss_hp:1; - uint32_t ipframe:1; - uint32_t tcpframe:1; - uint32_t udpframe:1; - uint32_t ip_cksum_pass:1; - uint32_t l4_cksum_pass:1; - uint32_t ipv6_frame:1; - uint32_t rsvd:8; - uint32_t frag_index:10; - uint32_t rsvd1:3; - uint32_t num_frags:3; - - /* dw 2 */ - uint32_t rsvd2:3; - uint32_t qnq:1; - uint32_t rss_bank:1; - uint32_t rsvd3:3; - uint32_t data_offset:8; - uint32_t rsvd4:6; - uint32_t debug:7; - uint32_t cqe_type:2; - uint32_t valid:1; - - /* dw 3 */ - uint32_t rss_hash_value; -#endif -}; - -struct nic_hwlro_cqe_part1 { -#ifdef _BIG_ENDIAN - /* dw 0 */ - uint32_t tcp_timestamp_val; - - /* dw 1 */ - uint32_t tcp_timestamp_ecr; - - /* dw 2 */ - uint32_t valid:1; - uint32_t cqe_type:2; - uint32_t rsvd3:7; - uint32_t rss_policy:4; - uint32_t rsvd2:2; - uint32_t data_offset:8; - uint32_t rsvd1:1; - uint32_t lro_desc:1; - uint32_t lro_timer_pop:1; - uint32_t rss_bank:1; - uint32_t qnq:1; - uint32_t rsvd:2; - uint32_t rss_flush:1; - - /* dw 3 */ - uint32_t rss_hash_value; -#else - /* dw 0 */ - uint32_t tcp_timestamp_val; - - /* dw 1 */ - uint32_t tcp_timestamp_ecr; - - /* dw 2 */ - uint32_t rss_flush:1; - uint32_t rsvd:2; - uint32_t qnq:1; - uint32_t rss_bank:1; - uint32_t lro_timer_pop:1; - uint32_t lro_desc:1; - uint32_t rsvd1:1; - uint32_t data_offset:8; - uint32_t rsvd2:2; - uint32_t rss_policy:4; - uint32_t rsvd3:7; - uint32_t cqe_type:2; - uint32_t valid:1; - - /* dw 3 */ - uint32_t rss_hash_value; -#endif -}; - -struct nic_hwlro_cqe_part2 { -#ifdef _BIG_ENDIAN - /* dw 0 */ - uint32_t ip_opt:1; - uint32_t vtp:1; - uint32_t pkt_size:14; - uint32_t vlan_tag:16; - - /* dw 1 */ - uint32_t tcp_window:16; - uint32_t coalesced_size:16; - - /* dw 2 */ - uint32_t valid:1; - uint32_t cqe_type:2; - uint32_t rsvd:2; - uint32_t push:1; - uint32_t ts_opt:1; - uint32_t threshold:1; - uint32_t seg_cnt:8; - uint32_t frame_lifespan:8; - uint32_t ipv6_frame:1; - uint32_t l4_cksum_pass:1; - uint32_t ip_cksum_pass:1; - uint32_t udpframe:1; - uint32_t tcpframe:1; - uint32_t ipframe:1; - uint32_t rss_hp:1; - uint32_t error:1; - - /* dw 3 */ - uint32_t tcp_ack_num; -#else - /* dw 0 */ - uint32_t vlan_tag:16; - uint32_t pkt_size:14; - uint32_t vtp:1; - uint32_t ip_opt:1; - - /* dw 1 */ - uint32_t coalesced_size:16; - uint32_t tcp_window:16; - - /* dw 2 */ - uint32_t error:1; - uint32_t rss_hp:1; - uint32_t ipframe:1; - uint32_t tcpframe:1; - uint32_t udpframe:1; - uint32_t ip_cksum_pass:1; - uint32_t l4_cksum_pass:1; - uint32_t ipv6_frame:1; - uint32_t frame_lifespan:8; - uint32_t seg_cnt:8; - uint32_t threshold:1; - uint32_t ts_opt:1; - uint32_t push:1; - uint32_t rsvd:2; - uint32_t cqe_type:2; - uint32_t valid:1; - - /* dw 3 */ - uint32_t tcp_ack_num; -#endif -}; diff --git a/sys/dev/oce/oce_if.c b/sys/dev/oce/oce_if.c index d09977eb6a89..370461291234 100644 --- a/sys/dev/oce/oce_if.c +++ b/sys/dev/oce/oce_if.c @@ -42,92 +42,77 @@ #include "opt_inet.h" #include "oce_if.h" -#include "oce_user.h" - -#define is_tso_pkt(m) (m->m_pkthdr.csum_flags & CSUM_TSO) /* UE Status Low CSR */ static char *ue_status_low_desc[] = { - "CEV", - "CTX", - "DBUF", - "ERX", - "Host", - "MPU", - "NDMA", - "PTC ", - "RDMA ", - "RXF ", - "RXIPS ", - "RXULP0 ", - "RXULP1 ", - "RXULP2 ", - "TIM ", - "TPOST ", - "TPRE ", - "TXIPS ", - "TXULP0 ", - "TXULP1 ", - "UC ", - "WDMA ", - "TXULP2 ", - "HOST1 ", - "P0_OB_LINK ", - "P1_OB_LINK ", - "HOST_GPIO ", - "MBOX ", - "AXGMAC0", - "AXGMAC1", - "JTAG", - "MPU_INTPEND" + "CEV", + "CTX", + "DBUF", + "ERX", + "Host", + "MPU", + "NDMA", + "PTC ", + "RDMA ", + "RXF ", + "RXIPS ", + "RXULP0 ", + "RXULP1 ", + "RXULP2 ", + "TIM ", + "TPOST ", + "TPRE ", + "TXIPS ", + "TXULP0 ", + "TXULP1 ", + "UC ", + "WDMA ", + "TXULP2 ", + "HOST1 ", + "P0_OB_LINK ", + "P1_OB_LINK ", + "HOST_GPIO ", + "MBOX ", + "AXGMAC0", + "AXGMAC1", + "JTAG", + "MPU_INTPEND" }; /* UE Status High CSR */ static char *ue_status_hi_desc[] = { - "LPCMEMHOST", - "MGMT_MAC", - "PCS0ONLINE", - "MPU_IRAM", - "PCS1ONLINE", - "PCTL0", - "PCTL1", - "PMEM", - "RR", - "TXPB", - "RXPP", - "XAUI", - "TXP", - "ARM", - "IPC", - "HOST2", - "HOST3", - "HOST4", - "HOST5", - "HOST6", - "HOST7", - "HOST8", - "HOST9", - "NETC", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown", - "Unknown" -}; - -struct oce_common_cqe_info{ - uint8_t vtp:1; - uint8_t l4_cksum_pass:1; - uint8_t ip_cksum_pass:1; - uint8_t ipv6_frame:1; - uint8_t qnq:1; - uint8_t rsvd:3; - uint8_t num_frags; - uint16_t pkt_size; - uint16_t vtag; + "LPCMEMHOST", + "MGMT_MAC", + "PCS0ONLINE", + "MPU_IRAM", + "PCS1ONLINE", + "PCTL0", + "PCTL1", + "PMEM", + "RR", + "TXPB", + "RXPP", + "XAUI", + "TXP", + "ARM", + "IPC", + "HOST2", + "HOST3", + "HOST4", + "HOST5", + "HOST6", + "HOST7", + "HOST8", + "HOST9", + "NETC", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown", + "Unknown" }; @@ -155,19 +140,17 @@ static int oce_media_change(struct ifnet *ifp); /* Transmit routines prototypes */ static int oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index); static void oce_tx_restart(POCE_SOFTC sc, struct oce_wq *wq); -static void oce_process_tx_completion(struct oce_wq *wq); +static void oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, + uint32_t status); static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq); /* Receive routines prototypes */ +static void oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe); static int oce_cqe_vtp_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe); static int oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe); -static void oce_rx(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe); -static void oce_check_rx_bufs(POCE_SOFTC sc, uint32_t num_cqes, struct oce_rq *rq); -static uint16_t oce_rq_handler_lro(void *arg); -static void oce_correct_header(struct mbuf *m, struct nic_hwlro_cqe_part1 *cqe1, struct nic_hwlro_cqe_part2 *cqe2); -static void oce_rx_lro(struct oce_rq *rq, struct nic_hwlro_singleton_cqe *cqe, struct nic_hwlro_cqe_part2 *cqe2); -static void oce_rx_mbuf_chain(struct oce_rq *rq, struct oce_common_cqe_info *cqe_info, struct mbuf **m); +static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx, + struct oce_nic_rx_cqe *cqe); /* Helper function prototypes in this file */ static int oce_attach_ifp(POCE_SOFTC sc); @@ -186,12 +169,11 @@ static void process_link_state(POCE_SOFTC sc, static int oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m); static void oce_get_config(POCE_SOFTC sc); static struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete); -static void oce_read_env_variables(POCE_SOFTC sc); - /* IP specific */ #if defined(INET6) || defined(INET) static int oce_init_lro(POCE_SOFTC sc); +static void oce_rx_flush_lro(struct oce_rq *rq); static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp); #endif @@ -224,7 +206,7 @@ const char component_revision[32] = {"///" COMPONENT_REVISION "///"}; /* Module capabilites and parameters */ uint32_t oce_max_rsp_handled = OCE_MAX_RSP_HANDLED; uint32_t oce_enable_rss = OCE_MODCAP_RSS; -uint32_t oce_rq_buf_size = 2048; + TUNABLE_INT("hw.oce.max_rsp_handled", &oce_max_rsp_handled); TUNABLE_INT("hw.oce.enable_rss", &oce_enable_rss); @@ -240,10 +222,8 @@ static uint32_t supportedDevices[] = { (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_SH }; -POCE_SOFTC softc_head = NULL; -POCE_SOFTC softc_tail = NULL; -struct oce_rdma_if *oce_rdma_if = NULL; + /***************************************************************************** * Driver entry points functions * @@ -312,8 +292,7 @@ oce_attach(device_t dev) sc->tx_ring_size = OCE_TX_RING_SIZE; sc->rx_ring_size = OCE_RX_RING_SIZE; - /* receive fragment size should be multiple of 2K */ - sc->rq_frag_size = ((oce_rq_buf_size / 2048) * 2048); + sc->rq_frag_size = OCE_RQ_BUF_SIZE; sc->flow_control = OCE_DEFAULT_FLOW_CONTROL; sc->promisc = OCE_DEFAULT_PROMISCUOUS; @@ -325,8 +304,6 @@ oce_attach(device_t dev) if (rc) goto pci_res_free; - oce_read_env_variables(sc); - oce_get_config(sc); setup_max_queues_want(sc); @@ -364,19 +341,11 @@ oce_attach(device_t dev) oce_add_sysctls(sc); - callout_init(&sc->timer, CALLOUT_MPSAFE); + callout_init(&sc->timer, 1); rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc); if (rc) goto stats_free; - sc->next =NULL; - if (softc_tail != NULL) { - softc_tail->next = sc; - } else { - softc_head = sc; - } - softc_tail = sc; - return 0; stats_free: @@ -414,22 +383,6 @@ static int oce_detach(device_t dev) { POCE_SOFTC sc = device_get_softc(dev); - POCE_SOFTC poce_sc_tmp, *ppoce_sc_tmp1, poce_sc_tmp2 = NULL; - - poce_sc_tmp = softc_head; - ppoce_sc_tmp1 = &softc_head; - while (poce_sc_tmp != NULL) { - if (poce_sc_tmp == sc) { - *ppoce_sc_tmp1 = sc->next; - if (sc->next == NULL) { - softc_tail = poce_sc_tmp2; - } - break; - } - poce_sc_tmp2 = poce_sc_tmp; - ppoce_sc_tmp1 = &poce_sc_tmp->next; - poce_sc_tmp = poce_sc_tmp->next; - } LOCK(&sc->dev_lock); oce_if_deactivate(sc); @@ -567,16 +520,8 @@ oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data) oce_vid_config(sc); } #if defined(INET6) || defined(INET) - if (u & IFCAP_LRO) { + if (u & IFCAP_LRO) ifp->if_capenable ^= IFCAP_LRO; - if(sc->enable_hwlro) { - if(ifp->if_capenable & IFCAP_LRO) { - rc = oce_mbox_nic_set_iface_lro_config(sc, 1); - }else { - rc = oce_mbox_nic_set_iface_lro_config(sc, 0); - } - } - } #endif break; @@ -618,9 +563,6 @@ oce_multiq_start(struct ifnet *ifp, struct mbuf *m) int queue_index = 0; int status = 0; - if (!sc->link_status) - return ENXIO; - if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE) queue_index = m->m_pkthdr.flowid % sc->nwqs; @@ -711,41 +653,20 @@ oce_setup_intr(POCE_SOFTC sc) { int rc = 0, use_intx = 0; int vector = 0, req_vectors = 0; - int tot_req_vectors, tot_vectors; if (is_rss_enabled(sc)) req_vectors = MAX((sc->nrqs - 1), sc->nwqs); else req_vectors = 1; - tot_req_vectors = req_vectors; - if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) { - if (req_vectors > 1) { - tot_req_vectors += OCE_RDMA_VECTORS; - sc->roce_intr_count = OCE_RDMA_VECTORS; - } - } - - if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) { + if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) { sc->intr_count = req_vectors; - tot_vectors = tot_req_vectors; - rc = pci_alloc_msix(sc->dev, &tot_vectors); + rc = pci_alloc_msix(sc->dev, &sc->intr_count); if (rc != 0) { use_intx = 1; pci_release_msi(sc->dev); - } else { - if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) { - if (tot_vectors < tot_req_vectors) { - if (sc->intr_count < (2 * OCE_RDMA_VECTORS)) { - sc->roce_intr_count = (tot_vectors / 2); - } - sc->intr_count = tot_vectors - sc->roce_intr_count; - } - } else { - sc->intr_count = tot_vectors; - } - sc->flags |= OCE_FLAGS_USING_MSIX; - } + } else + sc->flags |= OCE_FLAGS_USING_MSIX; } else use_intx = 1; @@ -933,79 +854,6 @@ oce_media_change(struct ifnet *ifp) } -static void oce_is_pkt_dest_bmc(POCE_SOFTC sc, - struct mbuf *m, boolean_t *os2bmc, - struct mbuf **m_new) -{ - struct ether_header *eh = NULL; - - eh = mtod(m, struct ether_header *); - - if (!is_os2bmc_enabled(sc) || *os2bmc) { - *os2bmc = FALSE; - goto done; - } - if (!ETHER_IS_MULTICAST(eh->ether_dhost)) - goto done; - - if (is_mc_allowed_on_bmc(sc, eh) || - is_bc_allowed_on_bmc(sc, eh) || - is_arp_allowed_on_bmc(sc, ntohs(eh->ether_type))) { - *os2bmc = TRUE; - goto done; - } - - if (mtod(m, struct ip *)->ip_p == IPPROTO_IPV6) { - struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); - uint8_t nexthdr = ip6->ip6_nxt; - if (nexthdr == IPPROTO_ICMPV6) { - struct icmp6_hdr *icmp6 = (struct icmp6_hdr *)(ip6 + 1); - switch (icmp6->icmp6_type) { - case ND_ROUTER_ADVERT: - *os2bmc = is_ipv6_ra_filt_enabled(sc); - goto done; - case ND_NEIGHBOR_ADVERT: - *os2bmc = is_ipv6_na_filt_enabled(sc); - goto done; - default: - break; - } - } - } - - if (mtod(m, struct ip *)->ip_p == IPPROTO_UDP) { - struct ip *ip = mtod(m, struct ip *); - int iphlen = ip->ip_hl << 2; - struct udphdr *uh = (struct udphdr *)((caddr_t)ip + iphlen); - switch (uh->uh_dport) { - case DHCP_CLIENT_PORT: - *os2bmc = is_dhcp_client_filt_enabled(sc); - goto done; - case DHCP_SERVER_PORT: - *os2bmc = is_dhcp_srvr_filt_enabled(sc); - goto done; - case NET_BIOS_PORT1: - case NET_BIOS_PORT2: - *os2bmc = is_nbios_filt_enabled(sc); - goto done; - case DHCPV6_RAS_PORT: - *os2bmc = is_ipv6_ras_filt_enabled(sc); - goto done; - default: - break; - } - } -done: - if (*os2bmc) { - *m_new = m_dup(m, M_NOWAIT); - if (!*m_new) { - *os2bmc = FALSE; - return; - } - *m_new = oce_insert_vlan_tag(sc, *m_new, NULL); - } -} - /***************************************************************************** @@ -1017,16 +865,14 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index) { int rc = 0, i, retry_cnt = 0; bus_dma_segment_t segs[OCE_MAX_TX_ELEMENTS]; - struct mbuf *m, *m_temp, *m_new = NULL; + struct mbuf *m, *m_temp; struct oce_wq *wq = sc->wq[wq_index]; struct oce_packet_desc *pd; struct oce_nic_hdr_wqe *nichdr; struct oce_nic_frag_wqe *nicfrag; - struct ether_header *eh = NULL; int num_wqes; uint32_t reg_value; boolean_t complete = TRUE; - boolean_t os2bmc = FALSE; m = *mpp; if (!m) @@ -1037,13 +883,6 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index) goto free_ret; } - /* Don't allow non-TSO packets longer than MTU */ - if (!is_tso_pkt(m)) { - eh = mtod(m, struct ether_header *); - if(m->m_pkthdr.len > ETHER_MAX_FRAME(sc->ifp, eh->ether_type, FALSE)) - goto free_ret; - } - if(oce_tx_asic_stall_verify(sc, m)) { m = oce_insert_vlan_tag(sc, m, &complete); if(!m) { @@ -1053,19 +892,6 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, int wq_index) } - /* Lancer, SH ASIC has a bug wherein Packets that are 32 bytes or less - * may cause a transmit stall on that port. So the work-around is to - * pad short packets (<= 32 bytes) to a 36-byte length. - */ - if(IS_SH(sc) || IS_XE201(sc) ) { - if(m->m_pkthdr.len <= 32) { - char buf[36]; - bzero((void *)buf, 36); - m_append(m, (36 - m->m_pkthdr.len), buf); - } - } - -tx_start: if (m->m_pkthdr.csum_flags & CSUM_TSO) { /* consolidate packet buffers for TSO/LSO segment offload */ #if defined(INET6) || defined(INET) @@ -1079,9 +905,7 @@ tx_start: } } - pd = &wq->pckts[wq->pkt_desc_head]; - retry: rc = bus_dmamap_load_mbuf_sg(wq->tag, pd->map, @@ -1111,7 +935,6 @@ retry: nichdr->u0.dw[3] = 0; nichdr->u0.s.complete = complete; - nichdr->u0.s.mgmt = os2bmc; nichdr->u0.s.event = 1; nichdr->u0.s.crc = 1; nichdr->u0.s.forward = 0; @@ -1175,12 +998,6 @@ retry: bus_dmamap_sync(wq->ring->dma.tag, wq->ring->dma.map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); reg_value = (num_wqes << 16) | wq->wq_id; - - /* if os2bmc is not enabled or if the pkt is already tagged as - bmc, do nothing - */ - oce_is_pkt_dest_bmc(sc, m, &os2bmc, &m_new); - OCE_WRITE_REG32(sc, db, wq->db_offset, reg_value); } else if (rc == EFBIG) { @@ -1198,11 +1015,6 @@ retry: return rc; else goto free_ret; - - if (os2bmc) { - m = m_new; - goto tx_start; - } return 0; @@ -1214,7 +1026,7 @@ free_ret: static void -oce_process_tx_completion(struct oce_wq *wq) +oce_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, uint32_t status) { struct oce_packet_desc *pd; POCE_SOFTC sc = (POCE_SOFTC) wq->parent; @@ -1401,7 +1213,6 @@ oce_wq_handler(void *arg) struct oce_nic_tx_cqe *cqe; int num_cqes = 0; - LOCK(&wq->tx_compl_lock); bus_dmamap_sync(cq->ring->dma.tag, cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_tx_cqe); @@ -1412,7 +1223,7 @@ oce_wq_handler(void *arg) if (wq->ring->cidx >= wq->ring->num_items) wq->ring->cidx -= wq->ring->num_items; - oce_process_tx_completion(wq); + oce_tx_complete(wq, cqe->u0.s.wqe_index, cqe->u0.s.status); wq->tx_stats.tx_compl++; cqe->u0.dw[3] = 0; RING_GET(cq->ring, 1); @@ -1425,9 +1236,8 @@ oce_wq_handler(void *arg) if (num_cqes) oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); - - UNLOCK(&wq->tx_compl_lock); - return num_cqes; + + return 0; } @@ -1482,216 +1292,19 @@ oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq) *****************************************************************************/ static void -oce_correct_header(struct mbuf *m, struct nic_hwlro_cqe_part1 *cqe1, struct nic_hwlro_cqe_part2 *cqe2) -{ - uint32_t *p; - struct ether_header *eh = NULL; - struct tcphdr *tcp_hdr = NULL; - struct ip *ip4_hdr = NULL; - struct ip6_hdr *ip6 = NULL; - uint32_t payload_len = 0; - - eh = mtod(m, struct ether_header *); - /* correct IP header */ - if(!cqe2->ipv6_frame) { - ip4_hdr = (struct ip *)((char*)eh + sizeof(struct ether_header)); - ip4_hdr->ip_ttl = cqe2->frame_lifespan; - ip4_hdr->ip_len = htons(cqe2->coalesced_size - sizeof(struct ether_header)); - tcp_hdr = (struct tcphdr *)((char*)ip4_hdr + sizeof(struct ip)); - }else { - ip6 = (struct ip6_hdr *)((char*)eh + sizeof(struct ether_header)); - ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim = cqe2->frame_lifespan; - payload_len = cqe2->coalesced_size - sizeof(struct ether_header) - - sizeof(struct ip6_hdr); - ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(payload_len); - tcp_hdr = (struct tcphdr *)((char*)ip6 + sizeof(struct ip6_hdr)); - } - - /* correct tcp header */ - tcp_hdr->th_ack = htonl(cqe2->tcp_ack_num); - if(cqe2->push) { - tcp_hdr->th_flags |= TH_PUSH; - } - tcp_hdr->th_win = htons(cqe2->tcp_window); - tcp_hdr->th_sum = 0xffff; - if(cqe2->ts_opt) { - p = (uint32_t *)((char*)tcp_hdr + sizeof(struct tcphdr) + 2); - *p = cqe1->tcp_timestamp_val; - *(p+1) = cqe1->tcp_timestamp_ecr; - } - - return; -} - -static void -oce_rx_mbuf_chain(struct oce_rq *rq, struct oce_common_cqe_info *cqe_info, struct mbuf **m) -{ - POCE_SOFTC sc = (POCE_SOFTC) rq->parent; - uint32_t i = 0, frag_len = 0; - uint32_t len = cqe_info->pkt_size; - struct oce_packet_desc *pd; - struct mbuf *tail = NULL; - - for (i = 0; i < cqe_info->num_frags; i++) { - if (rq->ring->cidx == rq->ring->pidx) { - device_printf(sc->dev, - "oce_rx_mbuf_chain: Invalid RX completion - Queue is empty\n"); - return; - } - pd = &rq->pckts[rq->ring->cidx]; - - bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(rq->tag, pd->map); - RING_GET(rq->ring, 1); - rq->pending--; - - frag_len = (len > rq->cfg.frag_size) ? rq->cfg.frag_size : len; - pd->mbuf->m_len = frag_len; - - if (tail != NULL) { - /* additional fragments */ - pd->mbuf->m_flags &= ~M_PKTHDR; - tail->m_next = pd->mbuf; - if(rq->islro) - tail->m_nextpkt = NULL; - tail = pd->mbuf; - } else { - /* first fragment, fill out much of the packet header */ - pd->mbuf->m_pkthdr.len = len; - if(rq->islro) - pd->mbuf->m_nextpkt = NULL; - pd->mbuf->m_pkthdr.csum_flags = 0; - if (IF_CSUM_ENABLED(sc)) { - if (cqe_info->l4_cksum_pass) { - if(!cqe_info->ipv6_frame) { /* IPV4 */ - pd->mbuf->m_pkthdr.csum_flags |= - (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); - }else { /* IPV6 frame */ - if(rq->islro) { - pd->mbuf->m_pkthdr.csum_flags |= - (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); - } - } - pd->mbuf->m_pkthdr.csum_data = 0xffff; - } - if (cqe_info->ip_cksum_pass) { - pd->mbuf->m_pkthdr.csum_flags |= - (CSUM_IP_CHECKED|CSUM_IP_VALID); - } - } - *m = tail = pd->mbuf; - } - pd->mbuf = NULL; - len -= frag_len; - } - - return; -} - -static void -oce_rx_lro(struct oce_rq *rq, struct nic_hwlro_singleton_cqe *cqe, struct nic_hwlro_cqe_part2 *cqe2) -{ - POCE_SOFTC sc = (POCE_SOFTC) rq->parent; - struct nic_hwlro_cqe_part1 *cqe1 = NULL; - struct mbuf *m = NULL; - struct oce_common_cqe_info cq_info; - - /* parse cqe */ - if(cqe2 == NULL) { - cq_info.pkt_size = cqe->pkt_size; - cq_info.vtag = cqe->vlan_tag; - cq_info.l4_cksum_pass = cqe->l4_cksum_pass; - cq_info.ip_cksum_pass = cqe->ip_cksum_pass; - cq_info.ipv6_frame = cqe->ipv6_frame; - cq_info.vtp = cqe->vtp; - cq_info.qnq = cqe->qnq; - }else { - cqe1 = (struct nic_hwlro_cqe_part1 *)cqe; - cq_info.pkt_size = cqe2->coalesced_size; - cq_info.vtag = cqe2->vlan_tag; - cq_info.l4_cksum_pass = cqe2->l4_cksum_pass; - cq_info.ip_cksum_pass = cqe2->ip_cksum_pass; - cq_info.ipv6_frame = cqe2->ipv6_frame; - cq_info.vtp = cqe2->vtp; - cq_info.qnq = cqe1->qnq; - } - - cq_info.vtag = BSWAP_16(cq_info.vtag); - - cq_info.num_frags = cq_info.pkt_size / rq->cfg.frag_size; - if(cq_info.pkt_size % rq->cfg.frag_size) - cq_info.num_frags++; - - oce_rx_mbuf_chain(rq, &cq_info, &m); - - if (m) { - if(cqe2) { - //assert(cqe2->valid != 0); - - //assert(cqe2->cqe_type != 2); - oce_correct_header(m, cqe1, cqe2); - } - - m->m_pkthdr.rcvif = sc->ifp; -#if __FreeBSD_version >= 800000 - if (rq->queue_index) - m->m_pkthdr.flowid = (rq->queue_index - 1); - else - m->m_pkthdr.flowid = rq->queue_index; - M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE); -#endif - /* This deternies if vlan tag is Valid */ - if (cq_info.vtp) { - if (sc->function_mode & FNM_FLEX10_MODE) { - /* FLEX10. If QnQ is not set, neglect VLAN */ - if (cq_info.qnq) { - m->m_pkthdr.ether_vtag = cq_info.vtag; - m->m_flags |= M_VLANTAG; - } - } else if (sc->pvid != (cq_info.vtag & VLAN_VID_MASK)) { - /* In UMC mode generally pvid will be striped by - hw. But in some cases we have seen it comes - with pvid. So if pvid == vlan, neglect vlan. - */ - m->m_pkthdr.ether_vtag = cq_info.vtag; - m->m_flags |= M_VLANTAG; - } - } - if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1); - - (*sc->ifp->if_input) (sc->ifp, m); - - /* Update rx stats per queue */ - rq->rx_stats.rx_pkts++; - rq->rx_stats.rx_bytes += cq_info.pkt_size; - rq->rx_stats.rx_frags += cq_info.num_frags; - rq->rx_stats.rx_ucast_pkts++; - } - return; -} - -static void -oce_rx(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe) +oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe) { + uint32_t out; + struct oce_packet_desc *pd; POCE_SOFTC sc = (POCE_SOFTC) rq->parent; - int len; - struct mbuf *m = NULL; - struct oce_common_cqe_info cq_info; - uint16_t vtag = 0; - - /* Is it a flush compl that has no data */ - if(!cqe->u0.s.num_fragments) - goto exit; + int i, len, frag_len; + struct mbuf *m = NULL, *tail = NULL; + uint16_t vtag; len = cqe->u0.s.pkt_size; if (!len) { /*partial DMA workaround for Lancer*/ - oce_discard_rx_comp(rq, cqe->u0.s.num_fragments); - goto exit; - } - - if (!oce_cqe_portid_valid(sc, cqe)) { - oce_discard_rx_comp(rq, cqe->u0.s.num_fragments); + oce_discard_rx_comp(rq, cqe); goto exit; } @@ -1700,16 +1313,61 @@ oce_rx(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe) vtag = BSWAP_16(cqe->u0.s.vlan_tag); else vtag = cqe->u0.s.vlan_tag; - - cq_info.l4_cksum_pass = cqe->u0.s.l4_cksum_pass; - cq_info.ip_cksum_pass = cqe->u0.s.ip_cksum_pass; - cq_info.ipv6_frame = cqe->u0.s.ip_ver; - cq_info.num_frags = cqe->u0.s.num_fragments; - cq_info.pkt_size = cqe->u0.s.pkt_size; - oce_rx_mbuf_chain(rq, &cq_info, &m); + + for (i = 0; i < cqe->u0.s.num_fragments; i++) { + + if (rq->packets_out == rq->packets_in) { + device_printf(sc->dev, + "RQ transmit descriptor missing\n"); + } + out = rq->packets_out + 1; + if (out == OCE_RQ_PACKET_ARRAY_SIZE) + out = 0; + pd = &rq->pckts[rq->packets_out]; + rq->packets_out = out; + + bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(rq->tag, pd->map); + rq->pending--; + + frag_len = (len > rq->cfg.frag_size) ? rq->cfg.frag_size : len; + pd->mbuf->m_len = frag_len; + + if (tail != NULL) { + /* additional fragments */ + pd->mbuf->m_flags &= ~M_PKTHDR; + tail->m_next = pd->mbuf; + tail = pd->mbuf; + } else { + /* first fragment, fill out much of the packet header */ + pd->mbuf->m_pkthdr.len = len; + pd->mbuf->m_pkthdr.csum_flags = 0; + if (IF_CSUM_ENABLED(sc)) { + if (cqe->u0.s.l4_cksum_pass) { + pd->mbuf->m_pkthdr.csum_flags |= + (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); + pd->mbuf->m_pkthdr.csum_data = 0xffff; + } + if (cqe->u0.s.ip_cksum_pass) { + if (!cqe->u0.s.ip_ver) { /* IPV4 */ + pd->mbuf->m_pkthdr.csum_flags |= + (CSUM_IP_CHECKED|CSUM_IP_VALID); + } + } + } + m = tail = pd->mbuf; + } + pd->mbuf = NULL; + len -= frag_len; + } if (m) { + if (!oce_cqe_portid_valid(sc, cqe)) { + m_freem(m); + goto exit; + } + m->m_pkthdr.rcvif = sc->ifp; #if __FreeBSD_version >= 800000 if (rq->queue_index) @@ -1771,30 +1429,31 @@ exit: } -void -oce_discard_rx_comp(struct oce_rq *rq, int num_frags) +static void +oce_discard_rx_comp(struct oce_rq *rq, struct oce_nic_rx_cqe *cqe) { - uint32_t i = 0; + uint32_t out, i = 0; struct oce_packet_desc *pd; POCE_SOFTC sc = (POCE_SOFTC) rq->parent; + int num_frags = cqe->u0.s.num_fragments; for (i = 0; i < num_frags; i++) { - if (rq->ring->cidx == rq->ring->pidx) { - device_printf(sc->dev, - "oce_discard_rx_comp: Invalid RX completion - Queue is empty\n"); - return; - } - pd = &rq->pckts[rq->ring->cidx]; - bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(rq->tag, pd->map); - if (pd->mbuf != NULL) { - m_freem(pd->mbuf); - pd->mbuf = NULL; - } + if (rq->packets_out == rq->packets_in) { + device_printf(sc->dev, + "RQ transmit descriptor missing\n"); + } + out = rq->packets_out + 1; + if (out == OCE_RQ_PACKET_ARRAY_SIZE) + out = 0; + pd = &rq->pckts[rq->packets_out]; + rq->packets_out = out; - RING_GET(rq->ring, 1); - rq->pending--; + bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(rq->tag, pd->map); + rq->pending--; + m_freem(pd->mbuf); } + } @@ -1834,7 +1493,7 @@ oce_cqe_portid_valid(POCE_SOFTC sc, struct oce_nic_rx_cqe *cqe) } #if defined(INET6) || defined(INET) -void +static void oce_rx_flush_lro(struct oce_rq *rq) { struct lro_ctrl *lro = &rq->lro; @@ -1894,30 +1553,27 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int count) int nsegs, added = 0; struct oce_nic_rqe *rqe; pd_rxulp_db_t rxdb_reg; - uint32_t val = 0; - uint32_t oce_max_rq_posts = 64; bzero(&rxdb_reg, sizeof(pd_rxulp_db_t)); for (i = 0; i < count; i++) { - in = (rq->ring->pidx + 1) % OCE_RQ_PACKET_ARRAY_SIZE; + in = rq->packets_in + 1; + if (in == OCE_RQ_PACKET_ARRAY_SIZE) + in = 0; + if (in == rq->packets_out) + break; /* no more room */ - pd = &rq->pckts[rq->ring->pidx]; - pd->mbuf = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, oce_rq_buf_size); - if (pd->mbuf == NULL) { - device_printf(sc->dev, "mbuf allocation failed, size = %d\n",oce_rq_buf_size); + pd = &rq->pckts[rq->packets_in]; + pd->mbuf = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); + if (pd->mbuf == NULL) break; - } - pd->mbuf->m_nextpkt = NULL; - - pd->mbuf->m_len = pd->mbuf->m_pkthdr.len = rq->cfg.frag_size; + pd->mbuf->m_len = pd->mbuf->m_pkthdr.len = MCLBYTES; rc = bus_dmamap_load_mbuf_sg(rq->tag, pd->map, pd->mbuf, segs, &nsegs, BUS_DMA_NOWAIT); if (rc) { m_free(pd->mbuf); - device_printf(sc->dev, "bus_dmamap_load_mbuf_sg failed rc = %d\n", rc); break; } @@ -1926,6 +1582,7 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int count) continue; } + rq->packets_in = in; bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_PREREAD); rqe = RING_GET_PRODUCER_ITEM_VA(rq->ring, struct oce_nic_rqe); @@ -1936,124 +1593,23 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int count) added++; rq->pending++; } - oce_max_rq_posts = sc->enable_hwlro ? OCE_HWLRO_MAX_RQ_POSTS : OCE_MAX_RQ_POSTS; if (added != 0) { - for (i = added / oce_max_rq_posts; i > 0; i--) { - rxdb_reg.bits.num_posted = oce_max_rq_posts; + for (i = added / OCE_MAX_RQ_POSTS; i > 0; i--) { + rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS; rxdb_reg.bits.qid = rq->rq_id; - if(rq->islro) { - val |= rq->rq_id & DB_LRO_RQ_ID_MASK; - val |= oce_max_rq_posts << 16; - OCE_WRITE_REG32(sc, db, DB_OFFSET, val); - }else { - OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0); - } - added -= oce_max_rq_posts; + OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0); + added -= OCE_MAX_RQ_POSTS; } if (added > 0) { rxdb_reg.bits.qid = rq->rq_id; rxdb_reg.bits.num_posted = added; - if(rq->islro) { - val |= rq->rq_id & DB_LRO_RQ_ID_MASK; - val |= added << 16; - OCE_WRITE_REG32(sc, db, DB_OFFSET, val); - }else { - OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0); - } + OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0); } } return 0; } -static void -oce_check_rx_bufs(POCE_SOFTC sc, uint32_t num_cqes, struct oce_rq *rq) -{ - if (num_cqes) { - oce_arm_cq(sc, rq->cq->cq_id, num_cqes, FALSE); - if(!sc->enable_hwlro) { - if((OCE_RQ_PACKET_ARRAY_SIZE - rq->pending) > 1) - oce_alloc_rx_bufs(rq, ((OCE_RQ_PACKET_ARRAY_SIZE - rq->pending) - 1)); - }else { - if ((OCE_RQ_PACKET_ARRAY_SIZE -1 - rq->pending) > 64) - oce_alloc_rx_bufs(rq, 64); - } - } - - return; -} - -uint16_t -oce_rq_handler_lro(void *arg) -{ - struct oce_rq *rq = (struct oce_rq *)arg; - struct oce_cq *cq = rq->cq; - POCE_SOFTC sc = rq->parent; - struct nic_hwlro_singleton_cqe *cqe; - struct nic_hwlro_cqe_part2 *cqe2; - int num_cqes = 0; - - LOCK(&rq->rx_lock); - bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); - cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe); - while (cqe->valid) { - if(cqe->cqe_type == 0) { /* singleton cqe */ - /* we should not get singleton cqe after cqe1 on same rq */ - if(rq->cqe_firstpart != NULL) { - device_printf(sc->dev, "Got singleton cqe after cqe1 \n"); - goto exit_rq_handler_lro; - } - if(cqe->error != 0) { - rq->rx_stats.rxcp_err++; - if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); - } - oce_rx_lro(rq, cqe, NULL); - rq->rx_stats.rx_compl++; - cqe->valid = 0; - RING_GET(cq->ring, 1); - num_cqes++; - if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled)) - break; - }else if(cqe->cqe_type == 0x1) { /* first part */ - /* we should not get cqe1 after cqe1 on same rq */ - if(rq->cqe_firstpart != NULL) { - device_printf(sc->dev, "Got cqe1 after cqe1 \n"); - goto exit_rq_handler_lro; - } - rq->cqe_firstpart = (struct nic_hwlro_cqe_part1 *)cqe; - RING_GET(cq->ring, 1); - }else if(cqe->cqe_type == 0x2) { /* second part */ - cqe2 = (struct nic_hwlro_cqe_part2 *)cqe; - if(cqe2->error != 0) { - rq->rx_stats.rxcp_err++; - if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); - } - /* We should not get cqe2 without cqe1 */ - if(rq->cqe_firstpart == NULL) { - device_printf(sc->dev, "Got cqe2 without cqe1 \n"); - goto exit_rq_handler_lro; - } - oce_rx_lro(rq, (struct nic_hwlro_singleton_cqe *)rq->cqe_firstpart, cqe2); - - rq->rx_stats.rx_compl++; - rq->cqe_firstpart->valid = 0; - cqe2->valid = 0; - rq->cqe_firstpart = NULL; - - RING_GET(cq->ring, 1); - num_cqes += 2; - if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled)) - break; - } - - bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); - cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe); - } - oce_check_rx_bufs(sc, num_cqes, rq); -exit_rq_handler_lro: - UNLOCK(&rq->rx_lock); - return 0; -} /* Handle the Completion Queue for receive */ uint16_t @@ -2063,26 +1619,23 @@ oce_rq_handler(void *arg) struct oce_cq *cq = rq->cq; POCE_SOFTC sc = rq->parent; struct oce_nic_rx_cqe *cqe; - int num_cqes = 0; + int num_cqes = 0, rq_buffers_used = 0; + - if(rq->islro) { - oce_rq_handler_lro(arg); - return 0; - } - LOCK(&rq->rx_lock); bus_dmamap_sync(cq->ring->dma.tag, cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe); while (cqe->u0.dw[2]) { DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe)); + RING_GET(rq->ring, 1); if (cqe->u0.s.error == 0) { - oce_rx(rq, cqe); + oce_rx(rq, cqe->u0.s.frag_index, cqe); } else { rq->rx_stats.rxcp_err++; if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); /* Post L3/L4 errors to stack.*/ - oce_rx(rq, cqe); + oce_rx(rq, cqe->u0.s.frag_index, cqe); } rq->rx_stats.rx_compl++; cqe->u0.dw[2] = 0; @@ -2104,12 +1657,17 @@ oce_rq_handler(void *arg) } #if defined(INET6) || defined(INET) - if (IF_LRO_ENABLED(sc)) - oce_rx_flush_lro(rq); + if (IF_LRO_ENABLED(sc)) + oce_rx_flush_lro(rq); #endif + + if (num_cqes) { + oce_arm_cq(sc, cq->cq_id, num_cqes, FALSE); + rq_buffers_used = OCE_RQ_PACKET_ARRAY_SIZE - rq->pending; + if (rq_buffers_used > 1) + oce_alloc_rx_bufs(rq, (rq_buffers_used - 1)); + } - oce_check_rx_bufs(sc, num_cqes, rq); - UNLOCK(&rq->rx_lock); return 0; } @@ -2338,53 +1896,45 @@ oce_eqd_set_periodic(POCE_SOFTC sc) struct oce_eq *eqo; uint64_t now = 0, delta; int eqd, i, num = 0; - uint32_t tx_reqs = 0, rxpkts = 0, pps; - struct oce_wq *wq; - struct oce_rq *rq; - - #define ticks_to_msecs(t) (1000 * (t) / hz) + uint32_t ips = 0; + int tps; for (i = 0 ; i < sc->neqs; i++) { eqo = sc->eq[i]; aic = &sc->aic_obj[i]; /* When setting the static eq delay from the user space */ if (!aic->enable) { - if (aic->ticks) - aic->ticks = 0; eqd = aic->et_eqd; goto modify_eqd; } - rq = sc->rq[i]; - rxpkts = rq->rx_stats.rx_pkts; - wq = sc->wq[i]; - tx_reqs = wq->tx_stats.tx_reqs; now = ticks; - if (!aic->ticks || now < aic->ticks || - rxpkts < aic->prev_rxpkts || tx_reqs < aic->prev_txreqs) { - aic->prev_rxpkts = rxpkts; - aic->prev_txreqs = tx_reqs; - aic->ticks = now; - continue; - } + /* Over flow check */ + if ((now < aic->ticks) || (eqo->intr < aic->intr_prev)) + goto done; + + delta = now - aic->ticks; + tps = delta/hz; - delta = ticks_to_msecs(now - aic->ticks); + /* Interrupt rate based on elapsed ticks */ + if(tps) + ips = (uint32_t)(eqo->intr - aic->intr_prev) / tps; - pps = (((uint32_t)(rxpkts - aic->prev_rxpkts) * 1000) / delta) + - (((uint32_t)(tx_reqs - aic->prev_txreqs) * 1000) / delta); - eqd = (pps / 15000) << 2; - if (eqd < 8) + if (ips > INTR_RATE_HWM) + eqd = aic->cur_eqd + 20; + else if (ips < INTR_RATE_LWM) + eqd = aic->cur_eqd / 2; + else + goto done; + + if (eqd < 10) eqd = 0; /* Make sure that the eq delay is in the known range */ eqd = min(eqd, aic->max_eqd); eqd = max(eqd, aic->min_eqd); - aic->prev_rxpkts = rxpkts; - aic->prev_txreqs = tx_reqs; - aic->ticks = now; - modify_eqd: if (eqd != aic->cur_eqd) { set_eqd[num].delay_multiplier = (eqd * 65)/100; @@ -2392,16 +1942,14 @@ modify_eqd: aic->cur_eqd = eqd; num++; } +done: + aic->intr_prev = eqo->intr; + aic->ticks = now; } /* Is there atleast one eq that needs to be modified? */ - for(i = 0; i < num; i += 8) { - if((num - i) >=8 ) - oce_mbox_eqd_modify_periodic(sc, &set_eqd[i], 8); - else - oce_mbox_eqd_modify_periodic(sc, &set_eqd[i], (num - i)); - } - + if(num) + oce_mbox_eqd_modify_periodic(sc, set_eqd, num); } static void oce_detect_hw_error(POCE_SOFTC sc) @@ -2489,44 +2037,6 @@ oce_local_timer(void *arg) callout_reset(&sc->timer, hz, oce_local_timer, sc); } -static void -oce_tx_compl_clean(POCE_SOFTC sc) -{ - struct oce_wq *wq; - int i = 0, timeo = 0, num_wqes = 0; - int pending_txqs = sc->nwqs; - - /* Stop polling for compls when HW has been silent for 10ms or - * hw_error or no outstanding completions expected - */ - do { - pending_txqs = sc->nwqs; - - for_all_wq_queues(sc, wq, i) { - num_wqes = oce_wq_handler(wq); - - if(num_wqes) - timeo = 0; - - if(!wq->ring->num_used) - pending_txqs--; - } - - if (pending_txqs == 0 || ++timeo > 10 || sc->hw_error) - break; - - DELAY(1000); - } while (TRUE); - - for_all_wq_queues(sc, wq, i) { - while(wq->ring->num_used) { - LOCK(&wq->tx_compl_lock); - oce_process_tx_completion(wq); - UNLOCK(&wq->tx_compl_lock); - } - } - -} /* NOTE : This should only be called holding * DEVICE_LOCK. @@ -2534,14 +2044,28 @@ oce_tx_compl_clean(POCE_SOFTC sc) static void oce_if_deactivate(POCE_SOFTC sc) { - int i; + int i, mtime = 0; + int wait_req = 0; struct oce_rq *rq; struct oce_wq *wq; struct oce_eq *eq; sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - oce_tx_compl_clean(sc); + /*Wait for max of 400ms for TX completions to be done */ + while (mtime < 400) { + wait_req = 0; + for_all_wq_queues(sc, wq, i) { + if (wq->ring->num_used) { + wait_req = 1; + DELAY(1); + break; + } + } + mtime += 1; + if (!wait_req) + break; + } /* Stop intrs and finish any bottom halves pending */ oce_hw_intr_disable(sc); @@ -2628,50 +2152,6 @@ process_link_state(POCE_SOFTC sc, struct oce_async_cqe_link_state *acqe) } -static void oce_async_grp5_osbmc_process(POCE_SOFTC sc, - struct oce_async_evt_grp5_os2bmc *evt) -{ - DW_SWAP(evt, sizeof(struct oce_async_evt_grp5_os2bmc)); - if (evt->u.s.mgmt_enable) - sc->flags |= OCE_FLAGS_OS2BMC; - else - return; - - sc->bmc_filt_mask = evt->u.s.arp_filter; - sc->bmc_filt_mask |= (evt->u.s.dhcp_client_filt << 1); - sc->bmc_filt_mask |= (evt->u.s.dhcp_server_filt << 2); - sc->bmc_filt_mask |= (evt->u.s.net_bios_filt << 3); - sc->bmc_filt_mask |= (evt->u.s.bcast_filt << 4); - sc->bmc_filt_mask |= (evt->u.s.ipv6_nbr_filt << 5); - sc->bmc_filt_mask |= (evt->u.s.ipv6_ra_filt << 6); - sc->bmc_filt_mask |= (evt->u.s.ipv6_ras_filt << 7); - sc->bmc_filt_mask |= (evt->u.s.mcast_filt << 8); -} - - -static void oce_process_grp5_events(POCE_SOFTC sc, struct oce_mq_cqe *cqe) -{ - struct oce_async_event_grp5_pvid_state *gcqe; - struct oce_async_evt_grp5_os2bmc *bmccqe; - - switch (cqe->u0.s.async_type) { - case ASYNC_EVENT_PVID_STATE: - /* GRP5 PVID */ - gcqe = (struct oce_async_event_grp5_pvid_state *)cqe; - if (gcqe->enabled) - sc->pvid = gcqe->tag & VLAN_VID_MASK; - else - sc->pvid = 0; - break; - case ASYNC_EVENT_OS2BMC: - bmccqe = (struct oce_async_evt_grp5_os2bmc *)cqe; - oce_async_grp5_osbmc_process(sc, bmccqe); - break; - default: - break; - } -} - /* Handle the Completion Queue for the Mailbox/Async notifications */ uint16_t oce_mq_handler(void *arg) @@ -2682,6 +2162,7 @@ oce_mq_handler(void *arg) int num_cqes = 0, evt_type = 0, optype = 0; struct oce_mq_cqe *cqe; struct oce_async_cqe_link_state *acqe; + struct oce_async_event_grp5_pvid_state *gcqe; struct oce_async_event_qnq *dbgcqe; @@ -2698,11 +2179,21 @@ oce_mq_handler(void *arg) /* Link status evt */ acqe = (struct oce_async_cqe_link_state *)cqe; process_link_state(sc, acqe); - } else if (evt_type == ASYNC_EVENT_GRP5) { - oce_process_grp5_events(sc, cqe); - } else if (evt_type == ASYNC_EVENT_CODE_DEBUG && - optype == ASYNC_EVENT_DEBUG_QNQ) { - dbgcqe = (struct oce_async_event_qnq *)cqe; + } else if ((evt_type == ASYNC_EVENT_GRP5) && + (optype == ASYNC_EVENT_PVID_STATE)) { + /* GRP5 PVID */ + gcqe = + (struct oce_async_event_grp5_pvid_state *)cqe; + if (gcqe->enabled) + sc->pvid = gcqe->tag & VLAN_VID_MASK; + else + sc->pvid = 0; + + } + else if(evt_type == ASYNC_EVENT_CODE_DEBUG && + optype == ASYNC_EVENT_DEBUG_QNQ) { + dbgcqe = + (struct oce_async_event_qnq *)cqe; if(dbgcqe->valid) sc->qnqid = dbgcqe->vlan_tag; sc->qnq_debug_event = TRUE; @@ -2812,8 +2303,7 @@ oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete) if(sc->pvid) { if(!vlan_tag) vlan_tag = sc->pvid; - if (complete) - *complete = FALSE; + *complete = FALSE; } if(vlan_tag) { @@ -2822,9 +2312,7 @@ oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete) if(sc->qnqid) { m = ether_vlanencap(m, sc->qnqid); - - if (complete) - *complete = FALSE; + *complete = FALSE; } return m; } @@ -2865,129 +2353,3 @@ oce_get_config(POCE_SOFTC sc) sc->max_vlans = MAX_VLANFILTER_SIZE; } } - -static void -oce_rdma_close(void) -{ - if (oce_rdma_if != NULL) { - oce_rdma_if = NULL; - } -} - -static void -oce_get_mac_addr(POCE_SOFTC sc, uint8_t *macaddr) -{ - memcpy(macaddr, sc->macaddr.mac_addr, 6); -} - -int -oce_register_rdma(POCE_RDMA_INFO rdma_info, POCE_RDMA_IF rdma_if) -{ - POCE_SOFTC sc; - struct oce_dev_info di; - int i; - - if ((rdma_info == NULL) || (rdma_if == NULL)) { - return -EINVAL; - } - - if ((rdma_info->size != OCE_RDMA_INFO_SIZE) || - (rdma_if->size != OCE_RDMA_IF_SIZE)) { - return -ENXIO; - } - - rdma_info->close = oce_rdma_close; - rdma_info->mbox_post = oce_mbox_post; - rdma_info->common_req_hdr_init = mbx_common_req_hdr_init; - rdma_info->get_mac_addr = oce_get_mac_addr; - - oce_rdma_if = rdma_if; - - sc = softc_head; - while (sc != NULL) { - if (oce_rdma_if->announce != NULL) { - memset(&di, 0, sizeof(di)); - di.dev = sc->dev; - di.softc = sc; - di.ifp = sc->ifp; - di.db_bhandle = sc->db_bhandle; - di.db_btag = sc->db_btag; - di.db_page_size = 4096; - if (sc->flags & OCE_FLAGS_USING_MSIX) { - di.intr_mode = OCE_INTERRUPT_MODE_MSIX; - } else if (sc->flags & OCE_FLAGS_USING_MSI) { - di.intr_mode = OCE_INTERRUPT_MODE_MSI; - } else { - di.intr_mode = OCE_INTERRUPT_MODE_INTX; - } - di.dev_family = OCE_GEN2_FAMILY; // fixme: must detect skyhawk - if (di.intr_mode != OCE_INTERRUPT_MODE_INTX) { - di.msix.num_vectors = sc->intr_count + sc->roce_intr_count; - di.msix.start_vector = sc->intr_count; - for (i=0; i<di.msix.num_vectors; i++) { - di.msix.vector_list[i] = sc->intrs[i].vector; - } - } else { - } - memcpy(di.mac_addr, sc->macaddr.mac_addr, 6); - di.vendor_id = pci_get_vendor(sc->dev); - di.dev_id = pci_get_device(sc->dev); - - if (sc->rdma_flags & OCE_RDMA_FLAG_SUPPORTED) { - di.flags |= OCE_RDMA_INFO_RDMA_SUPPORTED; - } - - rdma_if->announce(&di); - sc = sc->next; - } - } - - return 0; -} - -static void -oce_read_env_variables( POCE_SOFTC sc ) -{ - char *value = NULL; - int rc = 0; - - /* read if user wants to enable hwlro or swlro */ - //value = getenv("oce_enable_hwlro"); - if(value && IS_SH(sc)) { - sc->enable_hwlro = strtol(value, NULL, 10); - if(sc->enable_hwlro) { - rc = oce_mbox_nic_query_lro_capabilities(sc, NULL, NULL); - if(rc) { - device_printf(sc->dev, "no hardware lro support\n"); - device_printf(sc->dev, "software lro enabled\n"); - sc->enable_hwlro = 0; - }else { - device_printf(sc->dev, "hardware lro enabled\n"); - oce_max_rsp_handled = 32; - } - }else { - device_printf(sc->dev, "software lro enabled\n"); - } - }else { - sc->enable_hwlro = 0; - } - - /* read mbuf size */ - //value = getenv("oce_rq_buf_size"); - if(value && IS_SH(sc)) { - oce_rq_buf_size = strtol(value, NULL, 10); - switch(oce_rq_buf_size) { - case 2048: - case 4096: - case 9216: - case 16384: - break; - - default: - device_printf(sc->dev, " Supported oce_rq_buf_size values are 2K, 4K, 9K, 16K \n"); - oce_rq_buf_size = 2048; - } - } - - return; -} diff --git a/sys/dev/oce/oce_if.h b/sys/dev/oce/oce_if.h index d6c1a0a454d4..99707e496783 100644 --- a/sys/dev/oce/oce_if.h +++ b/sys/dev/oce/oce_if.h @@ -85,14 +85,13 @@ #include <netinet/tcp.h> #include <netinet/sctp.h> #include <netinet/tcp_lro.h> -#include <netinet/icmp6.h> #include <machine/bus.h> #include "oce_hw.h" /* OCE device driver module component revision informaiton */ -#define COMPONENT_REVISION "11.0.50.0" +#define COMPONENT_REVISION "10.0.664.0" /* OCE devices supported by this driver */ #define PCI_VENDOR_EMULEX 0x10df /* Emulex */ @@ -143,6 +142,7 @@ extern int mp_ncpus; /* system's total active cpu cores */ #define OCE_DEFAULT_WQ_EQD 16 #define OCE_MAX_PACKET_Q 16 +#define OCE_RQ_BUF_SIZE 2048 #define OCE_LSO_MAX_SIZE (64 * 1024) #define LONG_TIMEOUT 30 #define OCE_MAX_JUMBO_FRAME_SIZE 9018 @@ -150,15 +150,11 @@ extern int mp_ncpus; /* system's total active cpu cores */ ETHER_VLAN_ENCAP_LEN - \ ETHER_HDR_LEN) -#define OCE_RDMA_VECTORS 2 - #define OCE_MAX_TX_ELEMENTS 29 #define OCE_MAX_TX_DESC 1024 #define OCE_MAX_TX_SIZE 65535 -#define OCE_MAX_TSO_SIZE (65535 - ETHER_HDR_LEN) #define OCE_MAX_RX_SIZE 4096 #define OCE_MAX_RQ_POSTS 255 -#define OCE_HWLRO_MAX_RQ_POSTS 64 #define OCE_DEFAULT_PROMISCUOUS 0 @@ -507,7 +503,7 @@ struct oce_drv_stats { #define INTR_RATE_LWM 10000 #define OCE_MAX_EQD 128u -#define OCE_MIN_EQD 0u +#define OCE_MIN_EQD 50u struct oce_set_eqd { uint32_t eq_id; @@ -522,8 +518,7 @@ struct oce_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ uint32_t cur_eqd; /* in usecs */ uint32_t et_eqd; /* configured value when aic is off */ uint64_t ticks; - uint64_t prev_rxpkts; - uint64_t prev_txreqs; + uint64_t intr_prev; }; #define MAX_LOCK_DESC_LEN 32 @@ -614,8 +609,7 @@ struct oce_eq { enum cq_len { CQ_LEN_256 = 256, CQ_LEN_512 = 512, - CQ_LEN_1024 = 1024, - CQ_LEN_2048 = 2048 + CQ_LEN_1024 = 1024 }; struct cq_config { @@ -691,7 +685,6 @@ struct oce_tx_queue_stats { struct oce_wq { OCE_LOCK tx_lock; - OCE_LOCK tx_compl_lock; void *parent; oce_ring_buffer_t *ring; struct oce_cq *cq; @@ -737,7 +730,6 @@ struct oce_rx_queue_stats { uint32_t rx_frags; uint32_t prev_rx_frags; uint32_t rx_fps; - uint32_t rx_drops_no_frags; /* HW has no fetched frags */ }; @@ -752,6 +744,8 @@ struct oce_rq { void *pad1; bus_dma_tag_t tag; struct oce_packet_desc pckts[OCE_RQ_PACKET_ARRAY_SIZE]; + uint32_t packets_in; + uint32_t packets_out; uint32_t pending; #ifdef notdef struct mbuf *head; @@ -763,8 +757,6 @@ struct oce_rq { struct oce_rx_queue_stats rx_stats; struct lro_ctrl lro; int lro_pkts_queued; - int islro; - struct nic_hwlro_cqe_part1 *cqe_firstpart; }; @@ -789,7 +781,6 @@ struct link_status { #define OCE_FLAGS_XE201 0x00000400 #define OCE_FLAGS_BE2 0x00000800 #define OCE_FLAGS_SH 0x00001000 -#define OCE_FLAGS_OS2BMC 0x00002000 #define OCE_DEV_BE2_CFG_BAR 1 #define OCE_DEV_CFG_BAR 0 @@ -824,7 +815,6 @@ typedef struct oce_softc { OCE_INTR_INFO intrs[OCE_MAX_EQ]; int intr_count; - int roce_intr_count; struct ifnet *ifp; @@ -834,7 +824,6 @@ typedef struct oce_softc { uint8_t duplex; uint32_t qos_link_speed; uint32_t speed; - uint32_t enable_hwlro; char fw_version[32]; struct mac_address_format macaddr; @@ -892,15 +881,9 @@ typedef struct oce_softc { uint16_t qnqid; uint32_t pvid; uint32_t max_vlans; - uint32_t bmc_filt_mask; - - void *rdma_context; - uint32_t rdma_flags; - struct oce_softc *next; } OCE_SOFTC, *POCE_SOFTC; -#define OCE_RDMA_FLAG_SUPPORTED 0x00000001 /************************************************** @@ -950,7 +933,7 @@ typedef struct oce_softc { : (bus_space_write_1((sc)->devcfg_btag, \ (sc)->devcfg_bhandle,o,v))) -void oce_rx_flush_lro(struct oce_rq *rq); + /*********************************************************** * DMA memory functions ***********************************************************/ @@ -1000,9 +983,6 @@ uint32_t oce_page_list(oce_ring_buffer_t *ring, struct phys_addr *pa_list); * cleanup functions ***********************************************************/ void oce_stop_rx(POCE_SOFTC sc); -void oce_discard_rx_comp(struct oce_rq *rq, int num_frags); -void oce_rx_cq_clean(struct oce_rq *rq); -void oce_rx_cq_clean_hwlro(struct oce_rq *rq); void oce_intr_free(POCE_SOFTC sc); void oce_free_posted_rxbuf(struct oce_rq *rq); #if defined(INET6) || defined(INET) @@ -1035,8 +1015,7 @@ int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable); int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl); int oce_get_link_status(POCE_SOFTC sc, struct link_status *link); int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); -int oce_mbox_get_nic_stats_v1(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); -int oce_mbox_get_nic_stats_v2(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); +int oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem); int oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem, uint32_t reset_stats); int oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem, @@ -1107,16 +1086,10 @@ int oce_refresh_nic_stats(POCE_SOFTC sc); int oce_stats_init(POCE_SOFTC sc); void oce_stats_free(POCE_SOFTC sc); -/* hw lro functions */ -int oce_mbox_nic_query_lro_capabilities(POCE_SOFTC sc, uint32_t *lro_rq_cnt, uint32_t *lro_flags); -int oce_mbox_nic_set_iface_lro_config(POCE_SOFTC sc, int enable); -int oce_mbox_create_rq_v2(struct oce_rq *rq); - /* Capabilities */ #define OCE_MODCAP_RSS 1 #define OCE_MAX_RSP_HANDLED 64 extern uint32_t oce_max_rsp_handled; /* max responses */ -extern uint32_t oce_rq_buf_size; #define OCE_MAC_LOOPBACK 0x0 #define OCE_PHY_LOOPBACK 0x1 @@ -1186,80 +1159,3 @@ static inline int MPU_EP_SEMAPHORE(POCE_SOFTC sc) #define IS_QNQ_OR_UMC(sc) ((sc->pvid && (sc->function_mode & FNM_UMC_MODE ))\ || (sc->qnqid && (sc->function_mode & FNM_FLEX10_MODE))) -struct oce_rdma_info; -extern struct oce_rdma_if *oce_rdma_if; - - - -/* OS2BMC related */ - -#define DHCP_CLIENT_PORT 68 -#define DHCP_SERVER_PORT 67 -#define NET_BIOS_PORT1 137 -#define NET_BIOS_PORT2 138 -#define DHCPV6_RAS_PORT 547 - -#define BMC_FILT_BROADCAST_ARP ((uint32_t)(1)) -#define BMC_FILT_BROADCAST_DHCP_CLIENT ((uint32_t)(1 << 1)) -#define BMC_FILT_BROADCAST_DHCP_SERVER ((uint32_t)(1 << 2)) -#define BMC_FILT_BROADCAST_NET_BIOS ((uint32_t)(1 << 3)) -#define BMC_FILT_BROADCAST ((uint32_t)(1 << 4)) -#define BMC_FILT_MULTICAST_IPV6_NEIGH_ADVER ((uint32_t)(1 << 5)) -#define BMC_FILT_MULTICAST_IPV6_RA ((uint32_t)(1 << 6)) -#define BMC_FILT_MULTICAST_IPV6_RAS ((uint32_t)(1 << 7)) -#define BMC_FILT_MULTICAST ((uint32_t)(1 << 8)) - -#define ND_ROUTER_ADVERT 134 -#define ND_NEIGHBOR_ADVERT 136 - -#define is_mc_allowed_on_bmc(sc, eh) \ - (!is_multicast_filt_enabled(sc) && \ - ETHER_IS_MULTICAST(eh->ether_dhost) && \ - !ETHER_IS_BROADCAST(eh->ether_dhost)) - -#define is_bc_allowed_on_bmc(sc, eh) \ - (!is_broadcast_filt_enabled(sc) && \ - ETHER_IS_BROADCAST(eh->ether_dhost)) - -#define is_arp_allowed_on_bmc(sc, et) \ - (is_arp(et) && is_arp_filt_enabled(sc)) - -#define is_arp(et) (et == ETHERTYPE_ARP) - -#define is_arp_filt_enabled(sc) \ - (sc->bmc_filt_mask & (BMC_FILT_BROADCAST_ARP)) - -#define is_dhcp_client_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_BROADCAST_DHCP_CLIENT) - -#define is_dhcp_srvr_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_BROADCAST_DHCP_SERVER) - -#define is_nbios_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_BROADCAST_NET_BIOS) - -#define is_ipv6_na_filt_enabled(sc) \ - (sc->bmc_filt_mask & \ - BMC_FILT_MULTICAST_IPV6_NEIGH_ADVER) - -#define is_ipv6_ra_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_MULTICAST_IPV6_RA) - -#define is_ipv6_ras_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_MULTICAST_IPV6_RAS) - -#define is_broadcast_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_BROADCAST) - -#define is_multicast_filt_enabled(sc) \ - (sc->bmc_filt_mask & BMC_FILT_MULTICAST) - -#define is_os2bmc_enabled(sc) (sc->flags & OCE_FLAGS_OS2BMC) - -#define LRO_FLAGS_HASH_MODE 0x00000001 -#define LRO_FLAGS_RSS_MODE 0x00000004 -#define LRO_FLAGS_CLSC_IPV4 0x00000010 -#define LRO_FLAGS_CLSC_IPV6 0x00000020 -#define NIC_RQ_FLAGS_RSS 0x0001 -#define NIC_RQ_FLAGS_LRO 0x0020 - diff --git a/sys/dev/oce/oce_mbox.c b/sys/dev/oce/oce_mbox.c index 3c303b5ae17f..cb2ae81a013d 100644 --- a/sys/dev/oce/oce_mbox.c +++ b/sys/dev/oce/oce_mbox.c @@ -495,10 +495,6 @@ oce_get_fw_config(POCE_SOFTC sc) sc->asic_revision = HOST_32(fwcmd->params.rsp.asic_revision); sc->port_id = HOST_32(fwcmd->params.rsp.port_id); sc->function_mode = HOST_32(fwcmd->params.rsp.function_mode); - if ((sc->function_mode & (ULP_NIC_MODE | ULP_RDMA_MODE)) == - (ULP_NIC_MODE | ULP_RDMA_MODE)) { - sc->rdma_flags = OCE_RDMA_FLAG_SUPPORTED; - } sc->function_caps = HOST_32(fwcmd->params.rsp.function_caps); if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) { @@ -771,7 +767,7 @@ oce_rss_itbl_init(POCE_SOFTC sc, struct mbx_config_nic_rss *fwcmd) /* fill log2 value indicating the size of the CPU table */ if (rc == 0) - fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(INDIRECTION_TABLE_ENTRIES)); + fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(i)); return rc; } @@ -812,15 +808,9 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss) RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV6 | RSS_ENABLE_TCP_IPV6); - - if(!sc->enable_hwlro) - fwcmd->params.req.flush = OCE_FLUSH; - else - fwcmd->params.req.flush = 0; - + fwcmd->params.req.flush = OCE_FLUSH; fwcmd->params.req.if_id = LE_32(if_id); - srandom(arc4random()); /* random entropy seed */ read_random(fwcmd->params.req.hash, sizeof(fwcmd->params.req.hash)); rc = oce_rss_itbl_init(sc, fwcmd); @@ -874,7 +864,7 @@ oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable) req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS; if (enable & 0x02) - req->iface_flags |= MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS; + req->iface_flags = MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS; req->if_id = sc->if_id; @@ -978,58 +968,104 @@ error: } + +int +oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) +{ + struct oce_mbx mbx; + struct mbx_get_nic_stats_v0 *fwcmd; + int rc = 0; + + bzero(&mbx, sizeof(struct oce_mbx)); + + fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v0); + bzero(fwcmd, sizeof(struct mbx_get_nic_stats_v0)); + + mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, + MBX_SUBSYSTEM_NIC, + NIC_GET_STATS, + MBX_TIMEOUT_SEC, + sizeof(struct mbx_get_nic_stats_v0), + OCE_MBX_VER_V0); + + mbx.u0.s.embedded = 0; + mbx.u0.s.sge_count = 1; + + oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE); + + mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr); + mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr); + mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats_v0); + + mbx.payload_length = sizeof(struct mbx_get_nic_stats_v0); + + DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); + + rc = oce_mbox_post(sc, &mbx, NULL); + + oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE); + + if (!rc) + rc = fwcmd->hdr.u0.rsp.status; + if (rc) + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); + return rc; +} + + + /** * @brief Function to get NIC statistics - * @param sc software handle to the device - * @param *stats pointer to where to store statistics - * @param reset_stats resets statistics of set - * @returns 0 on success, EIO on failure - * @note command depricated in Lancer + * @param sc software handle to the device + * @param *stats pointer to where to store statistics + * @param reset_stats resets statistics of set + * @returns 0 on success, EIO on failure + * @note command depricated in Lancer */ -#define OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, version) \ -int \ -oce_mbox_get_nic_stats_v##version(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) \ -{ \ - struct oce_mbx mbx; \ - struct mbx_get_nic_stats_v##version *fwcmd; \ - int rc = 0; \ - \ - bzero(&mbx, sizeof(struct oce_mbx)); \ - fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v##version); \ - bzero(fwcmd, sizeof(*fwcmd)); \ - \ - mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, \ - MBX_SUBSYSTEM_NIC, \ - NIC_GET_STATS, \ - MBX_TIMEOUT_SEC, \ - sizeof(*fwcmd), \ - OCE_MBX_VER_V##version); \ - \ - mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */ \ - mbx.u0.s.sge_count = 1; /* using scatter gather instead */ \ - \ - oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE); \ - mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr); \ - mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr); \ - mbx.payload.u0.u1.sgl[0].length = sizeof(*fwcmd); \ - mbx.payload_length = sizeof(*fwcmd); \ - DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); \ - \ - rc = oce_mbox_post(sc, &mbx, NULL); \ - oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE); \ - if (!rc) \ - rc = fwcmd->hdr.u0.rsp.status; \ - if (rc) \ - device_printf(sc->dev, \ - "%s failed - cmd status: %d addi status: %d\n", \ - __FUNCTION__, rc, \ - fwcmd->hdr.u0.rsp.additional_status); \ - return rc; \ -} +int +oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem) +{ + struct oce_mbx mbx; + struct mbx_get_nic_stats *fwcmd; + int rc = 0; + + bzero(&mbx, sizeof(struct oce_mbx)); + fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats); + bzero(fwcmd, sizeof(struct mbx_get_nic_stats)); + + mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, + MBX_SUBSYSTEM_NIC, + NIC_GET_STATS, + MBX_TIMEOUT_SEC, + sizeof(struct mbx_get_nic_stats), + OCE_MBX_VER_V1); -OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 0); -OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 1); -OCE_MBOX_GET_NIC_STATS(sc, pstats_dma_mem, 2); + + mbx.u0.s.embedded = 0; /* stats too large for embedded mbx rsp */ + mbx.u0.s.sge_count = 1; /* using scatter gather instead */ + + oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE); + mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr); + mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr); + mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats); + + mbx.payload_length = sizeof(struct mbx_get_nic_stats); + DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ); + + rc = oce_mbox_post(sc, &mbx, NULL); + oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE); + if (!rc) + rc = fwcmd->hdr.u0.rsp.status; + if (rc) + device_printf(sc->dev, + "%s failed - cmd status: %d addi status: %d\n", + __FUNCTION__, rc, + fwcmd->hdr.u0.rsp.additional_status); + return rc; +} /** @@ -2184,149 +2220,3 @@ error: return rc; } - -/* hw lro functions */ - -int -oce_mbox_nic_query_lro_capabilities(POCE_SOFTC sc, uint32_t *lro_rq_cnt, uint32_t *lro_flags) -{ - struct oce_mbx mbx; - struct mbx_nic_query_lro_capabilities *fwcmd; - int rc = 0; - - bzero(&mbx, sizeof(struct oce_mbx)); - - fwcmd = (struct mbx_nic_query_lro_capabilities *)&mbx.payload; - mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, - MBX_SUBSYSTEM_NIC, - 0x20,MBX_TIMEOUT_SEC, - sizeof(struct mbx_nic_query_lro_capabilities), - OCE_MBX_VER_V0); - - mbx.u0.s.embedded = 1; - mbx.payload_length = sizeof(struct mbx_nic_query_lro_capabilities); - - rc = oce_mbox_post(sc, &mbx, NULL); - if (!rc) - rc = fwcmd->hdr.u0.rsp.status; - if (rc) { - device_printf(sc->dev, - "%s failed - cmd status: %d addi status: %d\n", - __FUNCTION__, rc, - fwcmd->hdr.u0.rsp.additional_status); - - return rc; - } - if(lro_flags) - *lro_flags = HOST_32(fwcmd->params.rsp.lro_flags); - - if(lro_rq_cnt) - *lro_rq_cnt = HOST_16(fwcmd->params.rsp.lro_rq_cnt); - - return rc; -} - -int -oce_mbox_nic_set_iface_lro_config(POCE_SOFTC sc, int enable) -{ - struct oce_mbx mbx; - struct mbx_nic_set_iface_lro_config *fwcmd; - int rc = 0; - - bzero(&mbx, sizeof(struct oce_mbx)); - - fwcmd = (struct mbx_nic_set_iface_lro_config *)&mbx.payload; - mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, - MBX_SUBSYSTEM_NIC, - 0x26,MBX_TIMEOUT_SEC, - sizeof(struct mbx_nic_set_iface_lro_config), - OCE_MBX_VER_V0); - - mbx.u0.s.embedded = 1; - mbx.payload_length = sizeof(struct mbx_nic_set_iface_lro_config); - - fwcmd->params.req.iface_id = sc->if_id; - fwcmd->params.req.lro_flags = 0; - - if(enable) { - fwcmd->params.req.lro_flags = LRO_FLAGS_HASH_MODE | LRO_FLAGS_RSS_MODE; - fwcmd->params.req.lro_flags |= LRO_FLAGS_CLSC_IPV4 | LRO_FLAGS_CLSC_IPV6; - - fwcmd->params.req.max_clsc_byte_cnt = 64*1024; /* min = 2974, max = 0xfa59 */ - fwcmd->params.req.max_clsc_seg_cnt = 43; /* min = 2, max = 64 */ - fwcmd->params.req.max_clsc_usec_delay = 18; /* min = 1, max = 256 */ - fwcmd->params.req.min_clsc_frame_byte_cnt = 0; /* min = 1, max = 9014 */ - } - - rc = oce_mbox_post(sc, &mbx, NULL); - if (!rc) - rc = fwcmd->hdr.u0.rsp.status; - if (rc) { - device_printf(sc->dev, - "%s failed - cmd status: %d addi status: %d\n", - __FUNCTION__, rc, - fwcmd->hdr.u0.rsp.additional_status); - - return rc; - } - return rc; -} - -int -oce_mbox_create_rq_v2(struct oce_rq *rq) -{ - struct oce_mbx mbx; - struct mbx_create_nic_rq_v2 *fwcmd; - POCE_SOFTC sc = rq->parent; - int rc = 0, num_pages = 0; - - if (rq->qstate == QCREATED) - return 0; - - bzero(&mbx, sizeof(struct oce_mbx)); - - fwcmd = (struct mbx_create_nic_rq_v2 *)&mbx.payload; - mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0, - MBX_SUBSYSTEM_NIC, - 0x08, MBX_TIMEOUT_SEC, - sizeof(struct mbx_create_nic_rq_v2), - OCE_MBX_VER_V2); - - /* oce_page_list will also prepare pages */ - num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]); - - fwcmd->params.req.cq_id = rq->cq->cq_id; - fwcmd->params.req.frag_size = rq->cfg.frag_size/2048; - fwcmd->params.req.num_pages = num_pages; - - fwcmd->params.req.if_id = sc->if_id; - - fwcmd->params.req.max_frame_size = rq->cfg.mtu; - fwcmd->params.req.page_size = 1; - if(rq->cfg.is_rss_queue) { - fwcmd->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO); - }else { - device_printf(sc->dev, - "non rss lro queue should not be created \n"); - goto error; - } - mbx.u0.s.embedded = 1; - mbx.payload_length = sizeof(struct mbx_create_nic_rq_v2); - - rc = oce_mbox_post(sc, &mbx, NULL); - if (!rc) - rc = fwcmd->hdr.u0.rsp.status; - if (rc) { - device_printf(sc->dev, - "%s failed - cmd status: %d addi status: %d\n", - __FUNCTION__, rc, - fwcmd->hdr.u0.rsp.additional_status); - goto error; - } - rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id); - rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid; - -error: - return rc; -} - diff --git a/sys/dev/oce/oce_queue.c b/sys/dev/oce/oce_queue.c index e14621e63a3a..308c16d54846 100644 --- a/sys/dev/oce/oce_queue.c +++ b/sys/dev/oce/oce_queue.c @@ -66,7 +66,7 @@ static struct oce_mq *oce_mq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len); static void oce_mq_free(struct oce_mq *mq); static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx - *mbx, size_t req_size, enum qtype qtype, int version); + *mbx, size_t req_size, enum qtype qtype); struct oce_cq *oce_cq_create(POCE_SOFTC sc, struct oce_eq *eq, uint32_t q_len, @@ -120,10 +120,9 @@ oce_queue_init_all(POCE_SOFTC sc) aic->min_eqd = OCE_MIN_EQD; aic->et_eqd = OCE_MIN_EQD; aic->enable = TRUE; - - sc->eq[vector] = oce_eq_create(sc, sc->enable_hwlro ? EQ_LEN_2048 : EQ_LEN_1024, - EQE_SIZE_4,0, vector); + sc->eq[vector] = oce_eq_create(sc, EQ_LEN_1024, EQE_SIZE_4, + 0, vector); if (!sc->eq[vector]) goto error; } @@ -170,10 +169,6 @@ oce_queue_release_all(POCE_SOFTC sc) struct oce_rq *rq; struct oce_eq *eq; - /* before deleting lro queues, we have to disable hwlro */ - if(sc->enable_hwlro) - oce_mbox_nic_set_iface_lro_config(sc, 0); - for_all_rq_queues(sc, rq, i) { if (rq) { oce_rq_del(sc->rq[i]); @@ -259,7 +254,6 @@ oce_wq *oce_wq_init(POCE_SOFTC sc, uint32_t q_len, uint32_t wq_type) LOCK_CREATE(&wq->tx_lock, "TX_lock"); - LOCK_CREATE(&wq->tx_compl_lock, "WQ_HANDLER_LOCK"); #if __FreeBSD_version >= 800000 /* Allocate buf ring for multiqueue*/ @@ -310,7 +304,6 @@ oce_wq_free(struct oce_wq *wq) buf_ring_free(wq->br, M_DEVBUF); LOCK_DESTROY(&wq->tx_lock); - LOCK_DESTROY(&wq->tx_compl_lock); free(wq, M_DEVBUF); } @@ -381,7 +374,7 @@ oce_wq_del(struct oce_wq *wq) fwcmd = (struct mbx_delete_nic_wq *)&mbx.payload; fwcmd->params.req.wq_id = wq->wq_id; (void)oce_destroy_q(sc, &mbx, - sizeof(struct mbx_delete_nic_wq), QTYPE_WQ, 0); + sizeof(struct mbx_delete_nic_wq), QTYPE_WQ); wq->qstate = QDELETED; } @@ -429,17 +422,20 @@ oce_rq *oce_rq_init(POCE_SOFTC sc, rq->cfg.eqd = 0; rq->lro_pkts_queued = 0; rq->cfg.is_rss_queue = rss; + rq->packets_in = 0; + rq->packets_out = 0; rq->pending = 0; rq->parent = (void *)sc; rc = bus_dma_tag_create(bus_get_dma_tag(sc->dev), - 1, 0, - BUS_SPACE_MAXADDR, - BUS_SPACE_MAXADDR, - NULL, NULL, - oce_rq_buf_size, - 1, oce_rq_buf_size, 0, NULL, NULL, &rq->tag); + 1, 0, + BUS_SPACE_MAXADDR, + BUS_SPACE_MAXADDR, + NULL, NULL, + OCE_MAX_RX_SIZE, + 1, PAGE_SIZE, 0, NULL, NULL, &rq->tag); + if (rc) goto free_rq; @@ -516,10 +512,10 @@ oce_rq_create(struct oce_rq *rq, uint32_t if_id, struct oce_eq *eq) POCE_SOFTC sc = rq->parent; struct oce_cq *cq; - cq = oce_cq_create(sc, eq, - sc->enable_hwlro ? CQ_LEN_2048 : CQ_LEN_1024, - sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3); - + cq = oce_cq_create(sc, + eq, + CQ_LEN_1024, + sizeof(struct oce_nic_rx_cqe), 0, 1, 0, 3); if (!cq) return ENXIO; @@ -552,20 +548,14 @@ oce_rq_del(struct oce_rq *rq) POCE_SOFTC sc = (POCE_SOFTC) rq->parent; struct oce_mbx mbx; struct mbx_delete_nic_rq *fwcmd; - struct mbx_delete_nic_rq_v1 *fwcmd1; if (rq->qstate == QCREATED) { bzero(&mbx, sizeof(mbx)); - if(!rq->islro) { - fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; - fwcmd->params.req.rq_id = rq->rq_id; - (void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq), QTYPE_RQ, 0); - }else { - fwcmd1 = (struct mbx_delete_nic_rq_v1 *)&mbx.payload; - fwcmd1->params.req.rq_id = rq->rq_id; - fwcmd1->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO); - (void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq_v1), QTYPE_RQ, 1); - } + + fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; + fwcmd->params.req.rq_id = rq->rq_id; + (void)oce_destroy_q(sc, &mbx, + sizeof(struct mbx_delete_nic_rq), QTYPE_RQ); rq->qstate = QDELETED; } @@ -642,7 +632,7 @@ oce_eq_del(struct oce_eq *eq) fwcmd = (struct mbx_destroy_common_eq *)&mbx.payload; fwcmd->params.req.id = eq->eq_id; (void)oce_destroy_q(sc, &mbx, - sizeof(struct mbx_destroy_common_eq), QTYPE_EQ, 0); + sizeof(struct mbx_destroy_common_eq), QTYPE_EQ); } if (eq->ring != NULL) { @@ -793,7 +783,7 @@ oce_mq_free(struct oce_mq *mq) fwcmd->params.req.id = mq->mq_id; (void) oce_destroy_q(sc, &mbx, sizeof (struct mbx_destroy_common_mq), - QTYPE_MQ, 0); + QTYPE_MQ); } mq->qstate = QDELETED; } @@ -820,7 +810,7 @@ oce_mq_free(struct oce_mq *mq) */ static int oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size, - enum qtype qtype, int version) + enum qtype qtype) { struct mbx_hdr *hdr = (struct mbx_hdr *)&mbx->payload; int opcode; @@ -854,7 +844,7 @@ oce_destroy_q(POCE_SOFTC sc, struct oce_mbx *mbx, size_t req_size, mbx_common_req_hdr_init(hdr, 0, 0, subsys, opcode, MBX_TIMEOUT_SEC, req_size, - version); + OCE_MBX_VER_V0); mbx->u0.s.embedded = 1; mbx->payload_length = (uint32_t) req_size; @@ -942,7 +932,7 @@ oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq) fwcmd = (struct mbx_destroy_common_cq *)&mbx.payload; fwcmd->params.req.id = cq->cq_id; (void)oce_destroy_q(sc, &mbx, - sizeof(struct mbx_destroy_common_cq), QTYPE_CQ, 0); + sizeof(struct mbx_destroy_common_cq), QTYPE_CQ); /*NOW destroy the ring */ oce_destroy_ring_buffer(sc, cq->ring); cq->ring = NULL; @@ -961,17 +951,12 @@ oce_cq_del(POCE_SOFTC sc, struct oce_cq *cq) int oce_start_rq(struct oce_rq *rq) { - POCE_SOFTC sc = (POCE_SOFTC) rq->parent; int rc; - if(sc->enable_hwlro) - rc = oce_alloc_rx_bufs(rq, 960); - else - rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len - 1); + rc = oce_alloc_rx_bufs(rq, rq->cfg.q_len); if (rc == 0) oce_arm_cq(rq->parent, rq->cq->cq_id, 0, TRUE); - return rc; } @@ -1163,7 +1148,7 @@ oce_free_posted_rxbuf(struct oce_rq *rq) while (rq->pending) { - pd = &rq->pckts[rq->ring->cidx]; + pd = &rq->pckts[rq->packets_out]; bus_dmamap_sync(rq->tag, pd->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(rq->tag, pd->map); if (pd->mbuf != NULL) { @@ -1171,179 +1156,44 @@ oce_free_posted_rxbuf(struct oce_rq *rq) pd->mbuf = NULL; } - RING_GET(rq->ring,1); + if ((rq->packets_out + 1) == OCE_RQ_PACKET_ARRAY_SIZE) + rq->packets_out = 0; + else + rq->packets_out++; + rq->pending--; } } void -oce_rx_cq_clean_hwlro(struct oce_rq *rq) -{ - struct oce_cq *cq = rq->cq; - POCE_SOFTC sc = rq->parent; - struct nic_hwlro_singleton_cqe *cqe; - struct nic_hwlro_cqe_part2 *cqe2; - int flush_wait = 0; - int flush_compl = 0; - int num_frags = 0; - - for (;;) { - bus_dmamap_sync(cq->ring->dma.tag,cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); - cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct nic_hwlro_singleton_cqe); - if(cqe->valid) { - if(cqe->cqe_type == 0) { /* singleton cqe */ - /* we should not get singleton cqe after cqe1 on same rq */ - if(rq->cqe_firstpart != NULL) { - device_printf(sc->dev, "Got singleton cqe after cqe1 \n"); - goto exit_rx_cq_clean_hwlro; - } - num_frags = cqe->pkt_size / rq->cfg.frag_size; - if(cqe->pkt_size % rq->cfg.frag_size) - num_frags++; - oce_discard_rx_comp(rq, num_frags); - /* Check if CQE is flush completion */ - if(!cqe->pkt_size) - flush_compl = 1; - cqe->valid = 0; - RING_GET(cq->ring, 1); - }else if(cqe->cqe_type == 0x1) { /* first part */ - /* we should not get cqe1 after cqe1 on same rq */ - if(rq->cqe_firstpart != NULL) { - device_printf(sc->dev, "Got cqe1 after cqe1 \n"); - goto exit_rx_cq_clean_hwlro; - } - rq->cqe_firstpart = (struct nic_hwlro_cqe_part1 *)cqe; - RING_GET(cq->ring, 1); - }else if(cqe->cqe_type == 0x2) { /* second part */ - cqe2 = (struct nic_hwlro_cqe_part2 *)cqe; - /* We should not get cqe2 without cqe1 */ - if(rq->cqe_firstpart == NULL) { - device_printf(sc->dev, "Got cqe2 without cqe1 \n"); - goto exit_rx_cq_clean_hwlro; - } - num_frags = cqe2->coalesced_size / rq->cfg.frag_size; - if(cqe2->coalesced_size % rq->cfg.frag_size) - num_frags++; - - /* Flush completion will always come in singleton CQE */ - oce_discard_rx_comp(rq, num_frags); - - rq->cqe_firstpart->valid = 0; - cqe2->valid = 0; - rq->cqe_firstpart = NULL; - RING_GET(cq->ring, 1); - } - oce_arm_cq(sc, cq->cq_id, 1, FALSE); - if(flush_compl) - break; - }else { - if (flush_wait++ > 100) { - device_printf(sc->dev, "did not receive hwlro flush compl\n"); - break; - } - oce_arm_cq(sc, cq->cq_id, 0, TRUE); - DELAY(1000); - } - } - - /* After cleanup, leave the CQ in unarmed state */ - oce_arm_cq(sc, cq->cq_id, 0, FALSE); - -exit_rx_cq_clean_hwlro: - return; -} - - -void -oce_rx_cq_clean(struct oce_rq *rq) +oce_stop_rx(POCE_SOFTC sc) { - struct oce_nic_rx_cqe *cqe; - struct oce_cq *cq; - POCE_SOFTC sc; - int flush_wait = 0; - int flush_compl = 0; - sc = rq->parent; - cq = rq->cq; - - for (;;) { - bus_dmamap_sync(cq->ring->dma.tag, - cq->ring->dma.map, BUS_DMASYNC_POSTWRITE); - cqe = RING_GET_CONSUMER_ITEM_VA(cq->ring, struct oce_nic_rx_cqe); - if(RQ_CQE_VALID(cqe)) { - DW_SWAP((uint32_t *) cqe, sizeof(oce_rq_cqe)); - oce_discard_rx_comp(rq, cqe->u0.s.num_fragments); - /* Check if CQE is flush completion */ - if((cqe->u0.s.num_fragments==0)&&(cqe->u0.s.pkt_size == 0)&&(cqe->u0.s.error == 0)) - flush_compl = 1; - - RQ_CQE_INVALIDATE(cqe); - RING_GET(cq->ring, 1); -#if defined(INET6) || defined(INET) - if (IF_LRO_ENABLED(sc)) - oce_rx_flush_lro(rq); -#endif - oce_arm_cq(sc, cq->cq_id, 1, FALSE); - if(flush_compl) - break; - }else { - if (flush_wait++ > 100) { - device_printf(sc->dev, "did not receive flush compl\n"); - break; - } - oce_arm_cq(sc, cq->cq_id, 0, TRUE); - DELAY(1000); - } - } + struct oce_mbx mbx; + struct mbx_delete_nic_rq *fwcmd; + struct oce_rq *rq; + int i = 0; - /* After cleanup, leave the CQ in unarmed state */ - oce_arm_cq(sc, cq->cq_id, 0, FALSE); -} + for_all_rq_queues(sc, rq, i) { + if (rq->qstate == QCREATED) { + /* Delete rxq in firmware */ -void -oce_stop_rx(POCE_SOFTC sc) -{ - struct oce_mbx mbx; - struct mbx_delete_nic_rq *fwcmd; - struct mbx_delete_nic_rq_v1 *fwcmd1; - struct oce_rq *rq; - int i = 0; - - /* before deleting disable hwlro */ - if(sc->enable_hwlro) - oce_mbox_nic_set_iface_lro_config(sc, 0); + bzero(&mbx, sizeof(mbx)); + fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; + fwcmd->params.req.rq_id = rq->rq_id; - for_all_rq_queues(sc, rq, i) { - if (rq->qstate == QCREATED) { - /* Delete rxq in firmware */ - LOCK(&rq->rx_lock); + (void)oce_destroy_q(sc, &mbx, + sizeof(struct mbx_delete_nic_rq), QTYPE_RQ); - bzero(&mbx, sizeof(mbx)); - if(!rq->islro) { - fwcmd = (struct mbx_delete_nic_rq *)&mbx.payload; - fwcmd->params.req.rq_id = rq->rq_id; - (void)oce_destroy_q(sc, &mbx, sizeof(struct mbx_delete_nic_rq), QTYPE_RQ, 0); - }else { - fwcmd1 = (struct mbx_delete_nic_rq_v1 *)&mbx.payload; - fwcmd1->params.req.rq_id = rq->rq_id; - fwcmd1->params.req.rq_flags = (NIC_RQ_FLAGS_RSS | NIC_RQ_FLAGS_LRO); + rq->qstate = QDELETED; - (void)oce_destroy_q(sc,&mbx,sizeof(struct mbx_delete_nic_rq_v1),QTYPE_RQ,1); - } - rq->qstate = QDELETED; + DELAY(1); - DELAY(1000); + /* Free posted RX buffers that are not used */ + oce_free_posted_rxbuf(rq); - if(!rq->islro) - oce_rx_cq_clean(rq); - else - oce_rx_cq_clean_hwlro(rq); - - /* Free posted RX buffers that are not used */ - oce_free_posted_rxbuf(rq); - UNLOCK(&rq->rx_lock); - } - } + } + } } @@ -1357,28 +1207,16 @@ oce_start_rx(POCE_SOFTC sc) for_all_rq_queues(sc, rq, i) { if (rq->qstate == QCREATED) continue; - if((i == 0) || (!sc->enable_hwlro)) { - rc = oce_mbox_create_rq(rq); - if (rc) - goto error; - rq->islro = 0; - }else { - rc = oce_mbox_create_rq_v2(rq); - if (rc) - goto error; - rq->islro = 1; - } - /* reset queue pointers */ - rq->qstate = QCREATED; - rq->pending = 0; - rq->ring->cidx = 0; - rq->ring->pidx = 0; - } - - if(sc->enable_hwlro) { - rc = oce_mbox_nic_set_iface_lro_config(sc, 1); + rc = oce_mbox_create_rq(rq); if (rc) goto error; + /* reset queue pointers */ + rq->qstate = QCREATED; + rq->pending = 0; + rq->ring->cidx = 0; + rq->ring->pidx = 0; + rq->packets_in = 0; + rq->packets_out = 0; } DELAY(1); @@ -1391,7 +1229,6 @@ oce_start_rx(POCE_SOFTC sc) } - DELAY(1); return rc; error: device_printf(sc->dev, "Start RX failed\n"); diff --git a/sys/dev/oce/oce_sysctl.c b/sys/dev/oce/oce_sysctl.c index 1fe4a636af74..61adf93ac69d 100644 --- a/sys/dev/oce/oce_sysctl.c +++ b/sys/dev/oce/oce_sysctl.c @@ -43,7 +43,6 @@ static void copy_stats_to_sc_xe201(POCE_SOFTC sc); static void copy_stats_to_sc_be3(POCE_SOFTC sc); static void copy_stats_to_sc_be2(POCE_SOFTC sc); -static void copy_stats_to_sc_sh(POCE_SOFTC sc); static int oce_sysctl_loopback(SYSCTL_HANDLER_ARGS); static int oce_sys_aic_enable(SYSCTL_HANDLER_ARGS); static int oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw); @@ -183,8 +182,6 @@ oce_sys_aic_enable(SYSCTL_HANDLER_ARGS) POCE_SOFTC sc = (struct oce_softc *)arg1; struct oce_aic_obj *aic; - /* set current value for proper sysctl logging */ - value = sc->aic_obj[0].enable; status = sysctl_handle_int(oidp, &value, 0, req); if (status || !req->newptr) return status; @@ -485,34 +482,34 @@ ret: return rc; } -#define UFI_TYPE2 2 -#define UFI_TYPE3 3 -#define UFI_TYPE3R 10 -#define UFI_TYPE4 4 -#define UFI_TYPE4R 11 +#define UFI_TYPE2 2 +#define UFI_TYPE3 3 +#define UFI_TYPE3R 10 +#define UFI_TYPE4 4 +#define UFI_TYPE4R 11 static int oce_get_ufi_type(POCE_SOFTC sc, - const struct flash_file_hdr *fhdr) + const struct flash_file_hdr *fhdr) { - if (fhdr == NULL) - goto be_get_ufi_exit; + if (fhdr == NULL) + goto be_get_ufi_exit; - if (IS_SH(sc) && fhdr->build[0] == '4') { - if (fhdr->asic_type_rev >= 0x10) - return UFI_TYPE4R; - else - return UFI_TYPE4; - } else if (IS_BE3(sc) && fhdr->build[0] == '3') { - if (fhdr->asic_type_rev == 0x10) - return UFI_TYPE3R; - else - return UFI_TYPE3; - } else if (IS_BE2(sc) && fhdr->build[0] == '2') - return UFI_TYPE2; + if (IS_SH(sc) && fhdr->build[0] == '4') { + if (fhdr->asic_type_rev >= 0x10) + return UFI_TYPE4R; + else + return UFI_TYPE4; + } else if (IS_BE3(sc) && fhdr->build[0] == '3') { + if (fhdr->asic_type_rev == 0x10) + return UFI_TYPE3R; + else + return UFI_TYPE3; + } else if (IS_BE2(sc) && fhdr->build[0] == '2') + return UFI_TYPE2; be_get_ufi_exit: - device_printf(sc->dev, - "UFI and Interface are not compatible for flashing\n"); - return -1; + device_printf(sc->dev, + "UFI and Interface are not compatible for flashing\n"); + return -1; } @@ -780,11 +777,7 @@ oce_add_stats_sysctls_be3(POCE_SOFTC sc, SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rxcp_err", CTLFLAG_RD, &sc->rq[i]->rx_stats.rxcp_err, 0, "Received Completion Errors"); - if(IS_SH(sc)) { - SYSCTL_ADD_UINT(ctx, queue_stats_list, OID_AUTO, "rx_drops_no_frags", - CTLFLAG_RD, &sc->rq[i]->rx_stats.rx_drops_no_frags, 0, - "num of packet drops due to no fragments"); - } + } rx_stats_node = SYSCTL_ADD_NODE(ctx, @@ -1379,10 +1372,10 @@ copy_stats_to_sc_be3(POCE_SOFTC sc) struct oce_pmem_stats *pmem; struct oce_rxf_stats_v1 *rxf_stats; struct oce_port_rxf_stats_v1 *port_stats; - struct mbx_get_nic_stats_v1 *nic_mbx; + struct mbx_get_nic_stats *nic_mbx; uint32_t port = sc->port_id; - nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats_v1); + nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats); pmem = &nic_mbx->params.rsp.stats.pmem; rxf_stats = &nic_mbx->params.rsp.stats.rxf; port_stats = &nic_mbx->params.rsp.stats.rxf.port[port]; @@ -1436,91 +1429,18 @@ copy_stats_to_sc_be3(POCE_SOFTC sc) adapter_stats->eth_red_drops = pmem->eth_red_drops; } -static void -copy_stats_to_sc_sh(POCE_SOFTC sc) -{ - struct oce_be_stats *adapter_stats; - struct oce_pmem_stats *pmem; - struct oce_rxf_stats_v2 *rxf_stats; - struct oce_port_rxf_stats_v2 *port_stats; - struct mbx_get_nic_stats_v2 *nic_mbx; - struct oce_erx_stats_v2 *erx_stats; - uint32_t port = sc->port_id; - - nic_mbx = OCE_DMAPTR(&sc->stats_mem, struct mbx_get_nic_stats_v2); - pmem = &nic_mbx->params.rsp.stats.pmem; - rxf_stats = &nic_mbx->params.rsp.stats.rxf; - erx_stats = &nic_mbx->params.rsp.stats.erx; - port_stats = &nic_mbx->params.rsp.stats.rxf.port[port]; - - adapter_stats = &sc->oce_stats_info.u0.be; - - /* Update stats */ - adapter_stats->pmem_fifo_overflow_drop = - port_stats->pmem_fifo_overflow_drop; - adapter_stats->rx_priority_pause_frames = - port_stats->rx_priority_pause_frames; - adapter_stats->rx_pause_frames = port_stats->rx_pause_frames; - adapter_stats->rx_crc_errors = port_stats->rx_crc_errors; - adapter_stats->rx_control_frames = port_stats->rx_control_frames; - adapter_stats->rx_in_range_errors = port_stats->rx_in_range_errors; - adapter_stats->rx_frame_too_long = port_stats->rx_frame_too_long; - adapter_stats->rx_dropped_runt = port_stats->rx_dropped_runt; - adapter_stats->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs; - adapter_stats->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs; - adapter_stats->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs; - adapter_stats->rx_dropped_tcp_length = - port_stats->rx_dropped_tcp_length; - adapter_stats->rx_dropped_too_small = port_stats->rx_dropped_too_small; - adapter_stats->rx_dropped_too_short = port_stats->rx_dropped_too_short; - adapter_stats->rx_out_range_errors = port_stats->rx_out_range_errors; - adapter_stats->rx_dropped_header_too_small = - port_stats->rx_dropped_header_too_small; - adapter_stats->rx_input_fifo_overflow_drop = - port_stats->rx_input_fifo_overflow_drop; - adapter_stats->rx_address_match_errors = - port_stats->rx_address_match_errors; - adapter_stats->rx_alignment_symbol_errors = - port_stats->rx_alignment_symbol_errors; - adapter_stats->rxpp_fifo_overflow_drop = - port_stats->rxpp_fifo_overflow_drop; - adapter_stats->tx_pauseframes = port_stats->tx_pauseframes; - adapter_stats->tx_controlframes = port_stats->tx_controlframes; - adapter_stats->jabber_events = port_stats->jabber_events; - - adapter_stats->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; - adapter_stats->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; - adapter_stats->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; - adapter_stats->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; - adapter_stats->forwarded_packets = rxf_stats->forwarded_packets; - adapter_stats->rx_drops_mtu = rxf_stats->rx_drops_mtu; - adapter_stats->rx_drops_no_tpre_descr = - rxf_stats->rx_drops_no_tpre_descr; - adapter_stats->rx_drops_too_many_frags = - rxf_stats->rx_drops_too_many_frags; - - adapter_stats->eth_red_drops = pmem->eth_red_drops; - - /* populate erx stats */ - for (int i = 0; i < sc->nrqs; i++) - sc->rq[i]->rx_stats.rx_drops_no_frags = erx_stats->rx_drops_no_fragments[sc->rq[i]->rq_id]; -} - - int oce_stats_init(POCE_SOFTC sc) { - int rc = 0, sz = 0; - - - if( IS_BE2(sc) ) - sz = sizeof(struct mbx_get_nic_stats_v0); - else if( IS_BE3(sc) ) - sz = sizeof(struct mbx_get_nic_stats_v1); - else if( IS_SH(sc)) - sz = sizeof(struct mbx_get_nic_stats_v2); - else if( IS_XE201(sc) ) + int rc = 0, sz; + + if (IS_BE(sc) || IS_SH(sc)) { + if (sc->flags & OCE_FLAGS_BE2) + sz = sizeof(struct mbx_get_nic_stats_v0); + else + sz = sizeof(struct mbx_get_nic_stats); + } else sz = sizeof(struct mbx_get_pport_stats); rc = oce_dma_alloc(sc, sz, &sc->stats_mem, 0); @@ -1543,24 +1463,23 @@ oce_refresh_nic_stats(POCE_SOFTC sc) { int rc = 0, reset = 0; - if( IS_BE2(sc) ) { - rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem); - if (!rc) - copy_stats_to_sc_be2(sc); - }else if( IS_BE3(sc) ) { - rc = oce_mbox_get_nic_stats_v1(sc, &sc->stats_mem); - if (!rc) - copy_stats_to_sc_be3(sc); - }else if( IS_SH(sc)) { - rc = oce_mbox_get_nic_stats_v2(sc, &sc->stats_mem); - if (!rc) - copy_stats_to_sc_sh(sc); - }else if( IS_XE201(sc) ){ + if (IS_BE(sc) || IS_SH(sc)) { + if (sc->flags & OCE_FLAGS_BE2) { + rc = oce_mbox_get_nic_stats_v0(sc, &sc->stats_mem); + if (!rc) + copy_stats_to_sc_be2(sc); + } else { + rc = oce_mbox_get_nic_stats(sc, &sc->stats_mem); + if (!rc) + copy_stats_to_sc_be3(sc); + } + + } else { rc = oce_mbox_get_pport_stats(sc, &sc->stats_mem, reset); if (!rc) copy_stats_to_sc_xe201(sc); } - + return rc; } |
