From owner-svn-src-stable@FreeBSD.ORG Fri Mar 8 18:46:22 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id BAC2F8BE; Fri, 8 Mar 2013 18:46:22 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id A10FEF76; Fri, 8 Mar 2013 18:46:22 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r28IkMlJ018802; Fri, 8 Mar 2013 18:46:22 GMT (envelope-from delphij@svn.freebsd.org) Received: (from delphij@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r28IkM9B018798; Fri, 8 Mar 2013 18:46:22 GMT (envelope-from delphij@svn.freebsd.org) Message-Id: <201303081846.r28IkM9B018798@svn.freebsd.org> From: Xin LI Date: Fri, 8 Mar 2013 18:46:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r248062 - in stable: 8/sys/dev/oce 9/sys/dev/oce X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Mar 2013 18:46:22 -0000 Author: delphij Date: Fri Mar 8 18:46:21 2013 New Revision: 248062 URL: http://svnweb.freebsd.org/changeset/base/248062 Log: MFC r231879,246799,247880,248059: Update driver to version 4.6.95.0. Submitted by: "Duvvuru,Venkat Kumar" Modified: stable/9/sys/dev/oce/oce_hw.c stable/9/sys/dev/oce/oce_hw.h stable/9/sys/dev/oce/oce_if.c stable/9/sys/dev/oce/oce_if.h stable/9/sys/dev/oce/oce_mbox.c stable/9/sys/dev/oce/oce_queue.c stable/9/sys/dev/oce/oce_sysctl.c stable/9/sys/dev/oce/oce_util.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Changes in other areas also in this revision: Modified: stable/8/sys/dev/oce/oce_hw.c stable/8/sys/dev/oce/oce_hw.h stable/8/sys/dev/oce/oce_if.c stable/8/sys/dev/oce/oce_if.h stable/8/sys/dev/oce/oce_mbox.c stable/8/sys/dev/oce/oce_queue.c stable/8/sys/dev/oce/oce_sysctl.c stable/8/sys/dev/oce/oce_util.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/dev/ (props changed) stable/8/sys/dev/oce/ (props changed) Modified: stable/9/sys/dev/oce/oce_hw.c ============================================================================== --- stable/9/sys/dev/oce/oce_hw.c Fri Mar 8 18:15:07 2013 (r248061) +++ stable/9/sys/dev/oce/oce_hw.c Fri Mar 8 18:46:21 2013 (r248062) @@ -340,8 +340,10 @@ oce_hw_shutdown(POCE_SOFTC sc) oce_stats_free(sc); /* disable hardware interrupts */ oce_hw_intr_disable(sc); +#if defined(INET6) || defined(INET) /* Free LRO resources */ oce_free_lro(sc); +#endif /* Release queue*/ oce_queue_release_all(sc); /*Delete Network Interface*/ @@ -403,11 +405,6 @@ oce_create_nw_interface(POCE_SOFTC sc) sc->if_cap_flags = capab_en_flags; - /* Enable VLAN Promisc on HW */ - rc = oce_config_vlan(sc, (uint8_t) sc->if_id, NULL, 0, 1, 1); - if (rc) - goto error; - /* set default flow control */ rc = oce_set_flow_control(sc, sc->flow_control); if (rc) @@ -475,12 +472,9 @@ oce_hw_start(POCE_SOFTC sc) return 1; if (link.logical_link_status == NTWK_LOGICAL_LINK_UP) { - sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; sc->link_status = NTWK_LOGICAL_LINK_UP; if_link_state_change(sc->ifp, LINK_STATE_UP); } else { - sc->ifp->if_drv_flags &= - ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); sc->link_status = NTWK_LOGICAL_LINK_DOWN; if_link_state_change(sc->ifp, LINK_STATE_DOWN); } @@ -494,12 +488,17 @@ oce_hw_start(POCE_SOFTC sc) rc = oce_start_mq(sc->mq); - /* we need to get MCC aync events. - So enable intrs and also arm first EQ + /* we need to get MCC aync events. So enable intrs and arm + first EQ, Other EQs will be armed after interface is UP */ oce_hw_intr_enable(sc); oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE); + /* Send first mcc cmd and after that we get gracious + MCC notifications from FW + */ + oce_first_mcc_cmd(sc); + return rc; } @@ -537,8 +536,8 @@ oce_hw_intr_disable(POCE_SOFTC sc) /** - * @brief Function for hardware update multicast filter - * @param sc software handle to the device + * @brief Function for hardware update multicast filter + * @param sc software handle to the device */ int oce_hw_update_multicast(POCE_SOFTC sc) Modified: stable/9/sys/dev/oce/oce_hw.h ============================================================================== --- stable/9/sys/dev/oce/oce_hw.h Fri Mar 8 18:15:07 2013 (r248061) +++ stable/9/sys/dev/oce/oce_hw.h Fri Mar 8 18:46:21 2013 (r248062) @@ -154,6 +154,12 @@ #define ASYNC_EVENT_CODE_LINK_STATE 0x1 #define ASYNC_EVENT_LINK_UP 0x1 #define ASYNC_EVENT_LINK_DOWN 0x0 +#define ASYNC_EVENT_GRP5 0x5 +#define ASYNC_EVENT_CODE_DEBUG 0x6 +#define ASYNC_EVENT_PVID_STATE 0x3 +#define ASYNC_EVENT_DEBUG_QNQ 0x1 +#define ASYNC_EVENT_CODE_SLIPORT 0x11 +#define VLAN_VID_MASK 0x0FFF /* port link_status */ #define ASYNC_EVENT_LOGICAL 0x02 @@ -610,7 +616,10 @@ struct oce_mq_cqe { uint32_t hpi_buffer_cmpl:1; uint32_t completed:1; uint32_t consumed:1; - uint32_t rsvd0:27; + uint32_t rsvd0:3; + uint32_t async_type:8; + uint32_t event_type:8; + uint32_t rsvd1:8; #else /* dw0 */ uint32_t completion_status:16; @@ -618,7 +627,10 @@ struct oce_mq_cqe { /* dw1 dw2 */ uint32_t mq_tag[2]; /* dw3 */ - uint32_t rsvd0:27; + uint32_t rsvd1:8; + uint32_t event_type:8; + uint32_t async_type:8; + uint32_t rsvd0:3; uint32_t consumed:1; uint32_t completed:1; uint32_t hpi_buffer_cmpl:1; @@ -687,6 +699,112 @@ struct oce_async_cqe_link_state { } u0; }; + +/* PVID aync event */ +struct oce_async_event_grp5_pvid_state { + uint8_t enabled; + uint8_t rsvd0; + uint16_t tag; + uint32_t event_tag; + uint32_t rsvd1; + uint32_t code; +}; + +/* async event indicating outer VLAN tag in QnQ */ +struct oce_async_event_qnq { + uint8_t valid; /* Indicates if outer VLAN is valid */ + uint8_t rsvd0; + uint16_t vlan_tag; + uint32_t event_tag; + uint8_t rsvd1[4]; + uint32_t code; +} ; + + +typedef union oce_mq_ext_ctx_u { + uint32_t dw[6]; + struct { + #ifdef _BIG_ENDIAN + /* dw0 */ + uint32_t dw4rsvd1:16; + uint32_t num_pages:16; + /* dw1 */ + uint32_t async_evt_bitmap; + /* dw2 */ + uint32_t cq_id:10; + uint32_t dw5rsvd2:2; + uint32_t ring_size:4; + uint32_t dw5rsvd1:16; + /* dw3 */ + uint32_t valid:1; + uint32_t dw6rsvd1:31; + /* dw4 */ + uint32_t dw7rsvd1:21; + uint32_t async_cq_id:10; + uint32_t async_cq_valid:1; + #else + /* dw0 */ + uint32_t num_pages:16; + uint32_t dw4rsvd1:16; + /* dw1 */ + uint32_t async_evt_bitmap; + /* dw2 */ + uint32_t dw5rsvd1:16; + uint32_t ring_size:4; + uint32_t dw5rsvd2:2; + uint32_t cq_id:10; + /* dw3 */ + uint32_t dw6rsvd1:31; + uint32_t valid:1; + /* dw4 */ + uint32_t async_cq_valid:1; + uint32_t async_cq_id:10; + uint32_t dw7rsvd1:21; + #endif + /* dw5 */ + uint32_t dw8rsvd1; + } v0; + struct { + #ifdef _BIG_ENDIAN + /* dw0 */ + uint32_t cq_id:16; + uint32_t num_pages:16; + /* dw1 */ + uint32_t async_evt_bitmap; + /* dw2 */ + uint32_t dw5rsvd2:12; + uint32_t ring_size:4; + uint32_t async_cq_id:16; + /* dw3 */ + uint32_t valid:1; + uint32_t dw6rsvd1:31; + /* dw4 */ + uint32_t dw7rsvd1:31; + uint32_t async_cq_valid:1; + #else + /* dw0 */ + uint32_t num_pages:16; + uint32_t cq_id:16; + /* dw1 */ + uint32_t async_evt_bitmap; + /* dw2 */ + uint32_t async_cq_id:16; + uint32_t ring_size:4; + uint32_t dw5rsvd2:12; + /* dw3 */ + uint32_t dw6rsvd1:31; + uint32_t valid:1; + /* dw4 */ + uint32_t async_cq_valid:1; + uint32_t dw7rsvd1:31; + #endif + /* dw5 */ + uint32_t dw8rsvd1; + } v1; + +} oce_mq_ext_ctx_t; + + /* MQ mailbox structure */ struct oce_bmbx { struct oce_mbx mbx; @@ -760,6 +878,7 @@ enum COMMON_SUBSYSTEM_OPCODES { OPCODE_COMMON_SET_BEACON_CONFIG = 69, OPCODE_COMMON_GET_BEACON_CONFIG = 70, OPCODE_COMMON_GET_PHYSICAL_LINK_CONFIG = 71, + OPCODE_COMMON_READ_TRANSRECEIVER_DATA = 73, OPCODE_COMMON_GET_OEM_ATTRIBUTES = 76, OPCODE_COMMON_GET_PORT_NAME = 77, OPCODE_COMMON_GET_CONFIG_SIGNATURE = 78, @@ -1342,6 +1461,23 @@ struct mbx_create_common_mq { } params; }; +struct mbx_create_common_mq_ex { + struct mbx_hdr hdr; + union { + struct { + oce_mq_ext_ctx_t context; + struct phys_addr pages[8]; + } req; + + struct { + uint32_t mq_id:16; + uint32_t rsvd0:16; + } rsp; + } params; +}; + + + /* [53] OPCODE_COMMON_DESTROY_MQ */ struct mbx_destroy_common_mq { struct mbx_hdr hdr; @@ -1584,7 +1720,7 @@ enum CQFW_FUNCTION_MODES_SUPPORTED { FNM_BE3_COMPAT_MODE = 0x10000, /* BE3 features */ FNM_VNIC_MODE = 0x20000, /* Set when IBM vNIC mode is set */ FNM_VNTAG_MODE = 0x40000, /* Set when VNTAG mode is set */ - FNM_UMC_MODE = 0x80000, /* Set when UMC mode is set */ + FNM_UMC_MODE = 0x1000000, /* Set when UMC mode is set */ FNM_UMC_DEF_EN = 0x100000, /* Set when UMC Default is set */ FNM_ONE_GB_EN = 0x200000, /* Set when 1GB Default is set */ FNM_VNIC_DEF_VALID = 0x400000, /* Set when VNIC_DEF_EN is valid */ @@ -1641,6 +1777,12 @@ struct mbx_set_common_iface_rx_filter { } params; }; +struct be_set_eqd { + uint32_t eq_id; + uint32_t phase; + uint32_t dm; +}; + /* [41] OPCODE_COMMON_MODIFY_EQ_DELAY */ struct mbx_modify_common_eq_delay { struct mbx_hdr hdr; @@ -1660,6 +1802,76 @@ struct mbx_modify_common_eq_delay { } params; }; +/* [32] OPCODE_COMMON_GET_CNTL_ATTRIBUTES */ + +struct mgmt_hba_attr { + int8_t flashrom_ver_str[32]; + int8_t manufac_name[32]; + uint32_t supp_modes; + int8_t seeprom_ver_lo; + int8_t seeprom_ver_hi; + int8_t rsvd0[2]; + uint32_t ioctl_data_struct_ver; + uint32_t ep_fw_data_struct_ver; + uint8_t ncsi_ver_str[12]; + uint32_t def_ext_to; + int8_t cntl_mod_num[32]; + int8_t cntl_desc[64]; + int8_t cntl_ser_num[32]; + int8_t ip_ver_str[32]; + int8_t fw_ver_str[32]; + int8_t bios_ver_str[32]; + int8_t redboot_ver_str[32]; + int8_t drv_ver_str[32]; + int8_t fw_on_flash_ver_str[32]; + uint32_t funcs_supp; + uint16_t max_cdblen; + uint8_t asic_rev; + uint8_t gen_guid[16]; + uint8_t hba_port_count; + uint16_t default_link_down_timeout; + uint8_t iscsi_ver_min_max; + uint8_t multifunc_dev; + uint8_t cache_valid; + uint8_t hba_status; + uint8_t max_domains_supp; + uint8_t phy_port; + uint32_t fw_post_status; + uint32_t hba_mtu[8]; + uint8_t iSCSI_feat; + uint8_t asic_gen; + uint8_t future_u8[2]; + uint32_t future_u32[3]; +}; + +struct mgmt_cntl_attr { + struct mgmt_hba_attr hba_attr; + uint16_t pci_vendor_id; + uint16_t pci_device_id; + uint16_t pci_sub_vendor_id; + uint16_t pci_sub_system_id; + uint8_t pci_bus_num; + uint8_t pci_dev_num; + uint8_t pci_func_num; + uint8_t interface_type; + uint64_t unique_id; + uint8_t netfilters; + uint8_t rsvd0[3]; + uint32_t future_u32[4]; +}; + +struct mbx_common_get_cntl_attr { + struct mbx_hdr hdr; + union { + struct { + uint32_t rsvd0; + } req; + struct { + struct mgmt_cntl_attr cntl_attr_info; + } rsp; + } params; +}; + /* [59] OPCODE_ADD_COMMON_IFACE_MAC */ struct mbx_add_common_iface_mac { struct mbx_hdr hdr; @@ -1702,6 +1914,23 @@ struct ioctl_common_function_reset { struct mbx_hdr hdr; }; +/* [73] OPCODE_COMMON_READ_TRANSRECEIVER_DATA */ +struct mbx_read_common_transrecv_data { + struct mbx_hdr hdr; + union { + struct { + uint32_t page_num; + uint32_t port; + } req; + struct { + uint32_t page_num; + uint32_t port; + uint32_t page_data[32]; + } rsp; + } params; + +}; + /* [80] OPCODE_COMMON_FUNCTION_LINK_CONFIG */ struct mbx_common_func_link_cfg { struct mbx_hdr hdr; @@ -2027,7 +2256,9 @@ enum RSS_ENABLE_FLAGS { RSS_ENABLE_IPV4 = 0x1, /* (IPV4 HASH enabled ) */ RSS_ENABLE_TCP_IPV4 = 0x2, /* (TCP IPV4 Hash enabled) */ RSS_ENABLE_IPV6 = 0x4, /* (IPV6 HASH enabled) */ - RSS_ENABLE_TCP_IPV6 = 0x8 /* (TCP IPV6 HASH */ + RSS_ENABLE_TCP_IPV6 = 0x8, /* (TCP IPV6 HASH */ + RSS_ENABLE_UDP_IPV4 = 0x10, /* UDP IPV4 HASH */ + RSS_ENABLE_UDP_IPV6 = 0x20 /* UDP IPV6 HASH */ }; #define RSS_ENABLE (RSS_ENABLE_IPV4 | RSS_ENABLE_TCP_IPV4) #define RSS_DISABLE RSS_ENABLE_NONE Modified: stable/9/sys/dev/oce/oce_if.c ============================================================================== --- stable/9/sys/dev/oce/oce_if.c Fri Mar 8 18:15:07 2013 (r248061) +++ stable/9/sys/dev/oce/oce_if.c Fri Mar 8 18:46:21 2013 (r248062) @@ -71,10 +71,6 @@ static int oce_tx(POCE_SOFTC sc, struct 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); -#if defined(INET6) || defined(INET) -static struct mbuf * oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp, - uint16_t *mss); -#endif static int oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq); @@ -82,9 +78,6 @@ static int oce_multiq_transmit(struct i 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); -#if defined(INET6) || defined(INET) -static void oce_rx_flush_lro(struct oce_rq *rq); -#endif static void oce_rx(struct oce_rq *rq, uint32_t rqe_idx, struct oce_nic_rx_cqe *cqe); @@ -96,13 +89,21 @@ static int oce_vid_config(POCE_SOFTC sc static void oce_mac_addr_set(POCE_SOFTC sc); static int oce_handle_passthrough(struct ifnet *ifp, caddr_t data); static void oce_local_timer(void *arg); -#if defined(INET6) || defined(INET) -static int oce_init_lro(POCE_SOFTC sc); -#endif static void oce_if_deactivate(POCE_SOFTC sc); static void oce_if_activate(POCE_SOFTC sc); static void setup_max_queues_want(POCE_SOFTC sc); static void update_queues_got(POCE_SOFTC sc); +static void process_link_state(POCE_SOFTC sc, + struct oce_async_cqe_link_state *acqe); +static int oce_tx_asic_stall_verify(POCE_SOFTC sc, struct mbuf *m); +static struct mbuf *oce_insert_vlan_tag(POCE_SOFTC sc, struct mbuf *m, boolean_t *complete); + +/* 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 static device_method_t oce_dispatch[] = { DEVMETHOD(device_probe, oce_probe), @@ -157,10 +158,10 @@ static uint32_t supportedDevices[] = { static int oce_probe(device_t dev) { - uint16_t vendor; - uint16_t device; - int i; - char str[80]; + uint16_t vendor = 0; + uint16_t device = 0; + int i = 0; + char str[256] = {0}; POCE_SOFTC sc; sc = device_get_softc(dev); @@ -170,11 +171,10 @@ oce_probe(device_t dev) vendor = pci_get_vendor(dev); device = pci_get_device(dev); - for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint16_t)); i++) { + for (i = 0; i < (sizeof(supportedDevices) / sizeof(uint32_t)); i++) { if (vendor == ((supportedDevices[i] >> 16) & 0xffff)) { if (device == (supportedDevices[i] & 0xffff)) { - sprintf(str, "%s:%s", - "Emulex CNA NIC function", + sprintf(str, "%s:%s", "Emulex CNA NIC function", component_revision); device_set_desc_copy(dev, str); @@ -228,37 +228,30 @@ oce_attach(device_t dev) if (rc) goto pci_res_free; - setup_max_queues_want(sc); - rc = oce_setup_intr(sc); if (rc) goto mbox_free; - rc = oce_queue_init_all(sc); if (rc) goto intr_free; - rc = oce_attach_ifp(sc); if (rc) goto queues_free; - #if defined(INET6) || defined(INET) rc = oce_init_lro(sc); if (rc) - goto ifp_free; + goto ifp_free; #endif - rc = oce_hw_start(sc); if (rc) goto lro_free; - sc->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, oce_add_vlan, sc, EVENTHANDLER_PRI_FIRST); sc->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, @@ -270,7 +263,6 @@ oce_attach(device_t dev) oce_add_sysctls(sc); - callout_init(&sc->timer, CALLOUT_MPSAFE); rc = callout_reset(&sc->timer, 2 * hz, oce_local_timer, sc); if (rc) @@ -315,9 +307,7 @@ oce_detach(device_t dev) POCE_SOFTC sc = device_get_softc(dev); LOCK(&sc->dev_lock); - oce_if_deactivate(sc); - UNLOCK(&sc->dev_lock); callout_drain(&sc->timer); @@ -359,34 +349,11 @@ oce_ioctl(struct ifnet *ifp, u_long comm uint32_t u; switch (command) { - case SIOCGIFPSRCADDR_IN6: - rc = ether_ioctl(ifp, command, data); - break; - - case SIOCGIFPSRCADDR: - rc = ether_ioctl(ifp, command, data); - break; - - case SIOCGIFSTATUS: - rc = ether_ioctl(ifp, command, data); - break; case SIOCGIFMEDIA: rc = ifmedia_ioctl(ifp, ifr, &sc->media, command); break; - case SIOCSIFMEDIA: - rc = ether_ioctl(ifp, command, data); - break; - - case SIOCGIFGENERIC: - rc = ether_ioctl(ifp, command, data); - break; - - case SIOCGETMIFCNT_IN6: - rc = ether_ioctl(ifp, command, data); - break; - case SIOCSIFMTU: if (ifr->ifr_mtu > OCE_MAX_MTU) rc = EINVAL; @@ -474,7 +441,6 @@ oce_ioctl(struct ifnet *ifp, u_long comm ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; oce_vid_config(sc); } - #if defined(INET6) || defined(INET) if (u & IFCAP_LRO) ifp->if_capenable ^= IFCAP_LRO; @@ -518,7 +484,7 @@ oce_multiq_start(struct ifnet *ifp, stru struct oce_wq *wq = NULL; int queue_index = 0; int status = 0; - + if ((m->m_flags & M_FLOWID) != 0) queue_index = m->m_pkthdr.flowid % sc->nwqs; @@ -601,6 +567,7 @@ oce_intr(void *arg, int pending) eq_arm: oce_arm_eq(sc, eq->eq_id, 0, TRUE, FALSE); + return; } @@ -666,6 +633,8 @@ oce_fast_isr(void *arg) taskqueue_enqueue_fast(ii->tq, &ii->task); + ii->eq->intr++; + return FILTER_HANDLED; } @@ -813,9 +782,7 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, struct oce_nic_frag_wqe *nicfrag; int num_wqes; uint32_t reg_value; -#if defined(INET6) || defined(INET) - uint16_t mss = 0; -#endif + boolean_t complete = TRUE; m = *mpp; if (!m) @@ -826,10 +793,19 @@ oce_tx(POCE_SOFTC sc, struct mbuf **mpp, goto free_ret; } + if(oce_tx_asic_stall_verify(sc, m)) { + m = oce_insert_vlan_tag(sc, m, &complete); + if(!m) { + device_printf(sc->dev, "Insertion unsuccessful\n"); + return 0; + } + + } + if (m->m_pkthdr.csum_flags & CSUM_TSO) { -#if defined(INET6) || defined(INET) /* consolidate packet buffers for TSO/LSO segment offload */ - m = oce_tso_setup(sc, mpp, &mss); +#if defined(INET6) || defined(INET) + m = oce_tso_setup(sc, mpp); #else m = NULL; #endif @@ -873,15 +849,15 @@ retry: nichdr->u0.dw[2] = 0; nichdr->u0.dw[3] = 0; - nichdr->u0.s.complete = 1; + nichdr->u0.s.complete = complete; nichdr->u0.s.event = 1; nichdr->u0.s.crc = 1; nichdr->u0.s.forward = 0; nichdr->u0.s.ipcs = (m->m_pkthdr.csum_flags & CSUM_IP) ? 1 : 0; nichdr->u0.s.udpcs = - (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0; + (m->m_pkthdr.csum_flags & CSUM_UDP) ? 1 : 0; nichdr->u0.s.tcpcs = - (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0; + (m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0; nichdr->u0.s.num_wqe = num_wqes; nichdr->u0.s.total_length = m->m_pkthdr.len; if (m->m_flags & M_VLANTAG) { @@ -931,7 +907,7 @@ retry: wq->tx_stats.tx_wrbs += num_wqes; wq->tx_stats.tx_bytes += m->m_pkthdr.len; wq->tx_stats.tx_pkts++; - + 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; @@ -1012,9 +988,10 @@ oce_tx_restart(POCE_SOFTC sc, struct oce } + #if defined(INET6) || defined(INET) static struct mbuf * -oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp, uint16_t *mss) +oce_tso_setup(POCE_SOFTC sc, struct mbuf **mpp) { struct mbuf *m; #ifdef INET @@ -1025,12 +1002,10 @@ oce_tso_setup(POCE_SOFTC sc, struct mbuf #endif struct ether_vlan_header *eh; struct tcphdr *th; - int total_len = 0; uint16_t etype; - int ehdrlen = 0; + int total_len = 0, ehdrlen = 0; m = *mpp; - *mss = m->m_pkthdr.tso_segsz; if (M_WRITABLE(m) == 0) { m = m_dup(*mpp, M_DONTWAIT); @@ -1049,7 +1024,6 @@ oce_tso_setup(POCE_SOFTC sc, struct mbuf ehdrlen = ETHER_HDR_LEN; } - switch (etype) { #ifdef INET case ETHERTYPE_IP: @@ -1084,7 +1058,6 @@ oce_tso_setup(POCE_SOFTC sc, struct mbuf } #endif /* INET6 || INET */ - void oce_tx_task(void *arg, int npending) { @@ -1115,22 +1088,26 @@ oce_start(struct ifnet *ifp) POCE_SOFTC sc = ifp->if_softc; struct mbuf *m; int rc = 0; + int def_q = 0; /* Defualt tx queue is 0*/ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) return; + + if (!sc->link_status) + return; do { IF_DEQUEUE(&sc->ifp->if_snd, m); if (m == NULL) break; - /* oce_start always uses default TX queue 0 */ - LOCK(&sc->wq[0]->tx_lock); - rc = oce_tx(sc, &m, 0); - UNLOCK(&sc->wq[0]->tx_lock); + + LOCK(&sc->wq[def_q]->tx_lock); + rc = oce_tx(sc, &m, def_q); + UNLOCK(&sc->wq[def_q]->tx_lock); if (rc) { if (m != NULL) { - sc->wq[0]->tx_stats.tx_stops ++; + sc->wq[def_q]->tx_stats.tx_stops ++; ifp->if_drv_flags |= IFF_DRV_OACTIVE; IFQ_DRV_PREPEND(&ifp->if_snd, m); m = NULL; @@ -1140,7 +1117,7 @@ oce_start(struct ifnet *ifp) if (m != NULL) ETHER_BPF_MTAP(ifp, m); - } while (1); + } while (TRUE); return; } @@ -1250,13 +1227,19 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i uint16_t vtag; len = cqe->u0.s.pkt_size; - vtag = cqe->u0.s.vlan_tag; if (!len) { /*partial DMA workaround for Lancer*/ oce_discard_rx_comp(rq, cqe); goto exit; } + /* Get vlan_tag value */ + if(IS_BE(sc)) + vtag = BSWAP_16(cqe->u0.s.vlan_tag); + else + vtag = cqe->u0.s.vlan_tag; + + for (i = 0; i < cqe->u0.s.num_fragments; i++) { if (rq->packets_out == rq->packets_in) { @@ -1292,7 +1275,7 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i pd->mbuf->m_pkthdr.csum_data = 0xffff; } if (cqe->u0.s.ip_cksum_pass) { - if (!cqe->u0.s.ip_ver) { //IPV4 + if (!cqe->u0.s.ip_ver) { /* IPV4 */ pd->mbuf->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID); } @@ -1315,24 +1298,20 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i m->m_pkthdr.flowid = rq->queue_index; m->m_flags |= M_FLOWID; #endif - //This deternies if vlan tag is present + /* This deternies if vlan tag is Valid */ if (oce_cqe_vtp_valid(sc, cqe)) { if (sc->function_mode & FNM_FLEX10_MODE) { - /* FLEX10 */ + /* FLEX10. If QnQ is not set, neglect VLAN */ if (cqe->u0.s.qnq) { - /* If QnQ is not set, neglect VLAN */ - if (IS_BE(sc)) - m->m_pkthdr.ether_vtag = - BSWAP_16(vtag); - else - m->m_pkthdr.ether_vtag = vtag; + m->m_pkthdr.ether_vtag = vtag; m->m_flags |= M_VLANTAG; } - } else { - if (IS_BE(sc)) - m->m_pkthdr.ether_vtag = BSWAP_16(vtag); - else - m->m_pkthdr.ether_vtag = vtag; + } else if (sc->pvid != (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 = vtag; m->m_flags |= M_VLANTAG; } } @@ -1341,7 +1320,6 @@ oce_rx(struct oce_rq *rq, uint32_t rqe_i #if defined(INET6) || defined(INET) /* Try to queue to LRO */ if (IF_LRO_ENABLED(sc) && - !(m->m_flags & M_VLANTAG) && (cqe->u0.s.ip_cksum_pass) && (cqe->u0.s.l4_cksum_pass) && (!cqe->u0.s.ip_ver) && @@ -1381,13 +1359,6 @@ oce_discard_rx_comp(struct oce_rq *rq, s POCE_SOFTC sc = (POCE_SOFTC) rq->parent; int num_frags = cqe->u0.s.num_fragments; - if (IS_XE201(sc) && cqe->u0.s.error) { - /* Lancer A0 workaround - * num_frags will be 1 more than actual in case of error - */ - if (num_frags) - num_frags -= 1; - } for (i = 0; i < num_frags; i++) { if (rq->packets_out == rq->packets_in) { device_printf(sc->dev, @@ -1417,9 +1388,8 @@ oce_cqe_vtp_valid(POCE_SOFTC sc, struct if (sc->be3_native) { cqe_v1 = (struct oce_nic_rx_cqe_v1 *)cqe; vtp = cqe_v1->u0.s.vlan_tag_present; - } else { + } else vtp = cqe->u0.s.vlan_tag_present; - } return vtp; @@ -1444,7 +1414,6 @@ oce_cqe_portid_valid(POCE_SOFTC sc, stru } - #if defined(INET6) || defined(INET) static void oce_rx_flush_lro(struct oce_rq *rq) @@ -1484,12 +1453,11 @@ oce_init_lro(POCE_SOFTC sc) return rc; } -#endif /* INET6 || INET */ + void oce_free_lro(POCE_SOFTC sc) { -#if defined(INET6) || defined(INET) struct lro_ctrl *lro = NULL; int i = 0; @@ -1498,9 +1466,8 @@ oce_free_lro(POCE_SOFTC sc) if (lro) tcp_lro_free(lro); } -#endif } - +#endif int oce_alloc_rx_bufs(struct oce_rq *rq, int count) @@ -1513,7 +1480,7 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int struct oce_nic_rqe *rqe; pd_rxulp_db_t rxdb_reg; - + bzero(&rxdb_reg, sizeof(pd_rxulp_db_t)); for (i = 0; i < count; i++) { in = rq->packets_in + 1; if (in == OCE_RQ_PACKET_ARRAY_SIZE) @@ -1554,14 +1521,12 @@ oce_alloc_rx_bufs(struct oce_rq *rq, int } if (added != 0) { for (i = added / OCE_MAX_RQ_POSTS; i > 0; i--) { - DELAY(1); rxdb_reg.bits.num_posted = OCE_MAX_RQ_POSTS; rxdb_reg.bits.qid = rq->rq_id; OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0); added -= OCE_MAX_RQ_POSTS; } if (added > 0) { - DELAY(1); rxdb_reg.bits.qid = rq->rq_id; rxdb_reg.bits.num_posted = added; OCE_WRITE_REG32(sc, db, PD_RXULP_DB, rxdb_reg.dw0); @@ -1596,13 +1561,8 @@ oce_rq_handler(void *arg) } else { rq->rx_stats.rxcp_err++; sc->ifp->if_ierrors++; - if (IS_XE201(sc)) - /* Lancer A0 no buffer workaround */ - oce_discard_rx_comp(rq, cqe); - else - /* Post L3/L4 errors to stack.*/ - oce_rx(rq, cqe->u0.s.frag_index, cqe); - + /* Post L3/L4 errors to stack.*/ + oce_rx(rq, cqe->u0.s.frag_index, cqe); } rq->rx_stats.rx_compl++; cqe->u0.dw[2] = 0; @@ -1622,6 +1582,7 @@ oce_rq_handler(void *arg) if (num_cqes >= (IS_XE201(sc) ? 8 : oce_max_rsp_handled)) break; } + #if defined(INET6) || defined(INET) if (IF_LRO_ENABLED(sc)) oce_rx_flush_lro(rq); @@ -1684,9 +1645,11 @@ oce_attach_ifp(POCE_SOFTC sc) sc->ifp->if_capabilities = OCE_IF_CAPABILITIES; sc->ifp->if_capabilities |= IFCAP_HWCSUM; sc->ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; + #if defined(INET6) || defined(INET) sc->ifp->if_capabilities |= IFCAP_TSO; sc->ifp->if_capabilities |= IFCAP_LRO; + sc->ifp->if_capabilities |= IFCAP_VLAN_HWTSO; #endif sc->ifp->if_capenable = sc->ifp->if_capabilities; @@ -1796,18 +1759,18 @@ oce_handle_passthrough(struct ifnet *ifp uint32_t req_size; struct mbx_hdr req; OCE_DMA_MEM dma_mem; - + struct mbx_common_get_cntl_attr *fw_cmd; if (copyin(priv_data, cookie, strlen(IOCTL_COOKIE))) return EFAULT; - + if (memcmp(cookie, IOCTL_COOKIE, strlen(IOCTL_COOKIE))) return EINVAL; - + ioctl_ptr = (char *)priv_data + strlen(IOCTL_COOKIE); if (copyin(ioctl_ptr, &req, sizeof(struct mbx_hdr))) return EFAULT; - + req_size = le32toh(req.u0.req.request_length); if (req_size > 65536) return EINVAL; @@ -1831,12 +1794,86 @@ oce_handle_passthrough(struct ifnet *ifp if (copyout(OCE_DMAPTR(&dma_mem,char), ioctl_ptr, req_size)) rc = EFAULT; + /* + firmware is filling all the attributes for this ioctl except + the driver version..so fill it + */ + if(req.u0.rsp.opcode == OPCODE_COMMON_GET_CNTL_ATTRIBUTES) { + fw_cmd = (struct mbx_common_get_cntl_attr *) ioctl_ptr; + strncpy(fw_cmd->params.rsp.cntl_attr_info.hba_attr.drv_ver_str, + COMPONENT_REVISION, strlen(COMPONENT_REVISION)); + } + dma_free: oce_dma_free(sc, &dma_mem); return rc; } +static void +oce_eqd_set_periodic(POCE_SOFTC sc) +{ + struct oce_set_eqd set_eqd[OCE_MAX_EQ]; + struct oce_aic_obj *aic; + struct oce_eq *eqo; + uint64_t now = 0, delta; + int eqd, i, num = 0; + 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) { + eqd = aic->et_eqd; + goto modify_eqd; + } + + now = ticks; + + /* Over flow check */ + if ((now < aic->ticks) || (eqo->intr < aic->intr_prev)) + goto done; + + delta = now - aic->ticks; + tps = delta/hz; + + /* Interrupt rate based on elapsed ticks */ + if(tps) + ips = (uint32_t)(eqo->intr - aic->intr_prev) / tps; + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***