From owner-svn-src-all@freebsd.org Tue Sep 25 23:48:45 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 98AA910938A4; Tue, 25 Sep 2018 23:48:44 +0000 (UTC) (envelope-from jpaetzel@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DEAE8640F; Tue, 25 Sep 2018 23:48:44 +0000 (UTC) (envelope-from jpaetzel@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 447587700; Tue, 25 Sep 2018 23:48:44 +0000 (UTC) (envelope-from jpaetzel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w8PNmi1Y056117; Tue, 25 Sep 2018 23:48:44 GMT (envelope-from jpaetzel@FreeBSD.org) Received: (from jpaetzel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w8PNmhpB056113; Tue, 25 Sep 2018 23:48:43 GMT (envelope-from jpaetzel@FreeBSD.org) Message-Id: <201809252348.w8PNmhpB056113@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jpaetzel set sender to jpaetzel@FreeBSD.org using -f From: Josh Paetzel Date: Tue, 25 Sep 2018 23:48:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r338938 - stable/11/sys/dev/oce X-SVN-Group: stable-11 X-SVN-Commit-Author: jpaetzel X-SVN-Commit-Paths: stable/11/sys/dev/oce X-SVN-Commit-Revision: 338938 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 Sep 2018 23:48:45 -0000 Author: jpaetzel Date: Tue Sep 25 23:48:43 2018 New Revision: 338938 URL: https://svnweb.freebsd.org/changeset/base/338938 Log: MFC r306219: Update oce to version 11.0.50.0 Submitted by: Venkat Duvvuru Added: stable/11/sys/dev/oce/oce_user.h - copied unchanged from r306219, head/sys/dev/oce/oce_user.h Modified: stable/11/sys/dev/oce/oce_hw.c stable/11/sys/dev/oce/oce_hw.h stable/11/sys/dev/oce/oce_if.c stable/11/sys/dev/oce/oce_if.h stable/11/sys/dev/oce/oce_mbox.c stable/11/sys/dev/oce/oce_queue.c stable/11/sys/dev/oce/oce_sysctl.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/oce/oce_hw.c ============================================================================== --- stable/11/sys/dev/oce/oce_hw.c Tue Sep 25 23:33:30 2018 (r338937) +++ stable/11/sys/dev/oce/oce_hw.c Tue Sep 25 23:48:43 2018 (r338938) @@ -393,6 +393,11 @@ 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; Modified: stable/11/sys/dev/oce/oce_hw.h ============================================================================== --- stable/11/sys/dev/oce/oce_hw.h Tue Sep 25 23:33:30 2018 (r338937) +++ stable/11/sys/dev/oce/oce_hw.h Tue Sep 25 23:48:43 2018 (r338938) @@ -111,6 +111,9 @@ #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 @@ -180,6 +183,7 @@ #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 @@ -722,6 +726,34 @@ 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 { @@ -1396,7 +1428,7 @@ typedef union oce_cq_ctx_u { uint32_t dw5rsvd3:1; uint32_t eventable:1; /* dw6 */ - uint32_t eq_id:8; + uint32_t eq_id:16; uint32_t dw6rsvd1:15; uint32_t armed:1; /* dw7 */ @@ -2403,8 +2435,8 @@ struct oce_nic_hdr_wqe { uint32_t tcpcs:1; uint32_t udpcs:1; uint32_t ipcs:1; - uint32_t rsvd3:1; - uint32_t rsvd2:1; + uint32_t mgmt:1; + uint32_t lso6:1; uint32_t forward:1; uint32_t crc:1; uint32_t event:1; @@ -2426,8 +2458,8 @@ struct oce_nic_hdr_wqe { uint32_t event:1; uint32_t crc:1; uint32_t forward:1; - uint32_t rsvd2:1; - uint32_t rsvd3:1; + uint32_t lso6:1; + uint32_t mgmt:1; uint32_t ipcs:1; uint32_t udpcs:1; uint32_t tcpcs:1; @@ -3010,6 +3042,53 @@ 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; @@ -3046,6 +3125,20 @@ 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]; @@ -3062,6 +3155,11 @@ 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]; @@ -3078,6 +3176,15 @@ 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]; @@ -3093,33 +3200,23 @@ struct oce_hw_stats_v0 { struct oce_pmem_stats pmem; }; -struct mbx_get_nic_stats_v0 { - struct mbx_hdr hdr; - union { - struct { - uint32_t rsvd0; - } req; +#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; \ +} - union { - struct oce_hw_stats_v0 stats; - } rsp; - } params; -}; +MBX_GET_NIC_STATS(0); +MBX_GET_NIC_STATS(1); +MBX_GET_NIC_STATS(2); -struct mbx_get_nic_stats { - struct mbx_hdr hdr; - union { - struct { - uint32_t rsvd0; - } req; - - struct { - struct oce_hw_stats_v1 stats; - } rsp; - } params; -}; - - /* [18(0x12)] NIC_GET_PPORT_STATS */ struct pport_stats { uint64_t tx_pkts; @@ -3727,4 +3824,374 @@ enum OCE_QUEUE_RX_STATS { QUEUE_RX_DROPS = 6, 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 }; Modified: stable/11/sys/dev/oce/oce_if.c ============================================================================== --- stable/11/sys/dev/oce/oce_if.c Tue Sep 25 23:33:30 2018 (r338937) +++ stable/11/sys/dev/oce/oce_if.c Tue Sep 25 23:48:43 2018 (r338938) @@ -42,80 +42,95 @@ #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" + "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; +}; + /* Driver entry points prototypes */ static int oce_probe(device_t dev); static int oce_attach(device_t dev); @@ -140,17 +155,19 @@ 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_tx_complete(struct oce_wq *wq, uint32_t wqe_idx, - uint32_t status); +static void oce_process_tx_completion(struct oce_wq *wq); 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, uint32_t rqe_idx, - 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); /* Helper function prototypes in this file */ static int oce_attach_ifp(POCE_SOFTC sc); @@ -169,11 +186,12 @@ 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 @@ -206,8 +224,8 @@ const char component_revision[32] = {"///" COMPONENT_R /* 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); @@ -222,9 +240,11 @@ 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 * *****************************************************************************/ @@ -292,7 +312,8 @@ oce_attach(device_t dev) sc->tx_ring_size = OCE_TX_RING_SIZE; sc->rx_ring_size = OCE_RX_RING_SIZE; - sc->rq_frag_size = OCE_RQ_BUF_SIZE; + /* receive fragment size should be multiple of 2K */ + sc->rq_frag_size = ((oce_rq_buf_size / 2048) * 2048); sc->flow_control = OCE_DEFAULT_FLOW_CONTROL; sc->promisc = OCE_DEFAULT_PROMISCUOUS; @@ -304,6 +325,8 @@ 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); @@ -341,11 +364,19 @@ oce_attach(device_t dev) oce_add_sysctls(sc); - callout_init(&sc->timer, 1); + callout_init(&sc->timer, CALLOUT_MPSAFE); 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: @@ -383,7 +414,23 @@ 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); UNLOCK(&sc->dev_lock); @@ -520,8 +567,16 @@ oce_ioctl(struct ifnet *ifp, u_long command, caddr_t d 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; @@ -563,6 +618,9 @@ 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; @@ -653,20 +711,41 @@ 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; - if (sc->flags & OCE_FLAGS_MSIX_CAPABLE) { + 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) { sc->intr_count = req_vectors; - rc = pci_alloc_msix(sc->dev, &sc->intr_count); + tot_vectors = tot_req_vectors; + rc = pci_alloc_msix(sc->dev, &tot_vectors); if (rc != 0) { use_intx = 1; pci_release_msi(sc->dev); - } else - sc->flags |= OCE_FLAGS_USING_MSIX; + } 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 use_intx = 1; @@ -854,8 +933,81 @@ 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 *); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***