Date: Thu, 30 Mar 2017 22:43:33 +0000 (UTC) From: David C Somayajulu <davidcs@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r316309 - head/sys/dev/qlxgbe Message-ID: <201703302243.v2UMhX2s011405@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davidcs Date: Thu Mar 30 22:43:32 2017 New Revision: 316309 URL: https://svnweb.freebsd.org/changeset/base/316309 Log: Add support for optional Soft LRO MFC after:5 days Modified: head/sys/dev/qlxgbe/ql_hw.c head/sys/dev/qlxgbe/ql_hw.h head/sys/dev/qlxgbe/ql_isr.c head/sys/dev/qlxgbe/ql_os.c Modified: head/sys/dev/qlxgbe/ql_hw.c ============================================================================== --- head/sys/dev/qlxgbe/ql_hw.c Thu Mar 30 22:26:15 2017 (r316308) +++ head/sys/dev/qlxgbe/ql_hw.c Thu Mar 30 22:43:32 2017 (r316309) @@ -440,6 +440,17 @@ ql_hw_add_sysctls(qla_host_t *ha) OID_AUTO, "enable_9kb", CTLFLAG_RW, &ha->hw.enable_9kb, ha->hw.enable_9kb, "Enable 9Kbyte Buffers when MTU = 9000"); + ha->hw.enable_hw_lro = 1; + + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "enable_hw_lro", CTLFLAG_RW, &ha->hw.enable_hw_lro, + ha->hw.enable_hw_lro, "Enable Hardware LRO; Default is true \n" + "\t 1 : Hardware LRO if LRO is enabled\n" + "\t 0 : Software LRO if LRO is enabled\n" + "\t Any change requires ifconfig down/up to take effect\n" + "\t Note that LRO may be turned off/on via ifconfig\n"); + ha->hw.mdump_active = 0; SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), @@ -2255,6 +2266,83 @@ qla_config_rss_ind_table(qla_host_t *ha) return (0); } +static int +qla_config_soft_lro(qla_host_t *ha) +{ + int i; + qla_hw_t *hw = &ha->hw; + struct lro_ctrl *lro; + + for (i = 0; i < hw->num_sds_rings; i++) { + lro = &hw->sds[i].lro; + + bzero(lro, sizeof(struct lro_ctrl)); + +#if (__FreeBSD_version >= 1100101) + if (tcp_lro_init_args(lro, ha->ifp, 0, NUM_RX_DESCRIPTORS)) { + device_printf(ha->pci_dev, + "%s: tcp_lro_init_args [%d] failed\n", + __func__, i); + return (-1); + } +#else + if (tcp_lro_init(lro)) { + device_printf(ha->pci_dev, + "%s: tcp_lro_init [%d] failed\n", + __func__, i); + return (-1); + } +#endif /* #if (__FreeBSD_version >= 1100101) */ + + lro->ifp = ha->ifp; + } + + QL_DPRINT2(ha, (ha->pci_dev, "%s: LRO initialized\n", __func__)); + return (0); +} + +static void +qla_drain_soft_lro(qla_host_t *ha) +{ + int i; + qla_hw_t *hw = &ha->hw; + struct lro_ctrl *lro; + + for (i = 0; i < hw->num_sds_rings; i++) { + lro = &hw->sds[i].lro; + +#if (__FreeBSD_version >= 1100101) + tcp_lro_flush_all(lro); +#else + struct lro_entry *queued; + + while ((!SLIST_EMPTY(&lro->lro_active))) { + queued = SLIST_FIRST(&lro->lro_active); + SLIST_REMOVE_HEAD(&lro->lro_active, next); + tcp_lro_flush(lro, queued); + } +#endif /* #if (__FreeBSD_version >= 1100101) */ + } + + return; +} + +static void +qla_free_soft_lro(qla_host_t *ha) +{ + int i; + qla_hw_t *hw = &ha->hw; + struct lro_ctrl *lro; + + for (i = 0; i < hw->num_sds_rings; i++) { + lro = &hw->sds[i].lro; + tcp_lro_free(lro); + } + + return; +} + + /* * Name: ql_del_hw_if * Function: Destroys the hardware specific entities corresponding to an @@ -2287,6 +2375,11 @@ ql_del_hw_if(qla_host_t *ha) ha->hw.flags.init_intr_cnxt = 0; } + if (ha->hw.enable_soft_lro) { + qla_drain_soft_lro(ha); + qla_free_soft_lro(ha); + } + return; } @@ -2309,7 +2402,6 @@ qla_confirm_9kb_enable(qla_host_t *ha) return; } - /* * Name: ql_init_hw_if * Function: Creates the hardware specific entities corresponding to an @@ -2416,8 +2508,19 @@ ql_init_hw_if(qla_host_t *ha) if (qla_link_event_req(ha, ha->hw.rcv_cntxt_id)) return (-1); - if (qla_config_fw_lro(ha, ha->hw.rcv_cntxt_id)) - return (-1); + if (ha->ifp->if_capenable & IFCAP_LRO) { + if (ha->hw.enable_hw_lro) { + ha->hw.enable_soft_lro = 0; + + if (qla_config_fw_lro(ha, ha->hw.rcv_cntxt_id)) + return (-1); + } else { + ha->hw.enable_soft_lro = 1; + + if (qla_config_soft_lro(ha)) + return (-1); + } + } if (qla_init_nic_func(ha)) return (-1); Modified: head/sys/dev/qlxgbe/ql_hw.h ============================================================================== --- head/sys/dev/qlxgbe/ql_hw.h Thu Mar 30 22:26:15 2017 (r316308) +++ head/sys/dev/qlxgbe/ql_hw.h Thu Mar 30 22:43:32 2017 (r316309) @@ -1674,6 +1674,8 @@ typedef struct _qla_hw { uint32_t max_tx_segs; uint32_t min_lro_pkt_size; + uint32_t enable_hw_lro; + uint32_t enable_soft_lro; uint32_t enable_9kb; uint32_t user_pri_nic; Modified: head/sys/dev/qlxgbe/ql_isr.c ============================================================================== --- head/sys/dev/qlxgbe/ql_isr.c Thu Mar 30 22:26:15 2017 (r316308) +++ head/sys/dev/qlxgbe/ql_isr.c Thu Mar 30 22:43:32 2017 (r316309) @@ -68,6 +68,9 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_ uint32_t i, rem_len = 0; uint32_t r_idx = 0; qla_rx_ring_t *rx_ring; + struct lro_ctrl *lro; + + lro = &ha->hw.sds[sds_idx].lro; if (ha->hw.num_rds_rings > 1) r_idx = sds_idx; @@ -166,7 +169,22 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_ M_HASHTYPE_SET(mpf, M_HASHTYPE_NONE); #endif /* #if __FreeBSD_version >= 1100000 */ - (*ifp->if_input)(ifp, mpf); + if (ha->hw.enable_soft_lro) { + +#if (__FreeBSD_version >= 1100101) + + tcp_lro_queue_mbuf(lro, mpf); + +#else + if (tcp_lro_rx(lro, mpf, 0)) + (*ifp->if_input)(ifp, mpf); + +#endif /* #if (__FreeBSD_version >= 1100101) */ + + + } else { + (*ifp->if_input)(ifp, mpf); + } if (sdsp->rx_free > ha->std_replenish) qla_replenish_normal_rx(ha, sdsp, r_idx); @@ -707,6 +725,28 @@ ql_rcv_isr(qla_host_t *ha, uint32_t sds_ } } + if (ha->hw.enable_soft_lro) { + struct lro_ctrl *lro; + + lro = &ha->hw.sds[sds_idx].lro; + +#if (__FreeBSD_version >= 1100101) + + tcp_lro_flush_all(lro); + +#else + struct lro_entry *queued; + + while ((!SLIST_EMPTY(&lro->lro_active))) { + queued = SLIST_FIRST(&lro->lro_active); + SLIST_REMOVE_HEAD(&lro->lro_active, next); + tcp_lro_flush(lro, queued); + } + +#endif /* #if (__FreeBSD_version >= 1100101) */ + + } + if (ha->flags.stop_rcv) goto ql_rcv_isr_exit; Modified: head/sys/dev/qlxgbe/ql_os.c ============================================================================== --- head/sys/dev/qlxgbe/ql_os.c Thu Mar 30 22:26:15 2017 (r316308) +++ head/sys/dev/qlxgbe/ql_os.c Thu Mar 30 22:43:32 2017 (r316309) @@ -1072,6 +1072,8 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; if (mask & IFCAP_VLAN_HWTSO) ifp->if_capenable ^= IFCAP_VLAN_HWTSO; + if (mask & IFCAP_LRO) + ifp->if_capenable ^= IFCAP_LRO; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) qla_init(ha); @@ -1497,7 +1499,6 @@ qla_qflush(struct ifnet *ifp) return; } - static void qla_stop(qla_host_t *ha) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703302243.v2UMhX2s011405>