svn commit: r317113 - stable/9/sys/dev/qlxgbe
David C Somayajulu
davidcs at FreeBSD.org
Wed Apr 19 03:02:25 UTC 2017
Author: davidcs
Date: Wed Apr 19 03:02:23 2017
New Revision: 317113
URL: https://svnweb.freebsd.org/changeset/base/317113
Log:
MFC r316309
Add support for optional Soft LRO
Modified:
stable/9/sys/dev/qlxgbe/ql_hw.c
stable/9/sys/dev/qlxgbe/ql_hw.h
stable/9/sys/dev/qlxgbe/ql_isr.c
stable/9/sys/dev/qlxgbe/ql_os.c
Directory Properties:
stable/9/ (props changed)
stable/9/sys/ (props changed)
Modified: stable/9/sys/dev/qlxgbe/ql_hw.c
==============================================================================
--- stable/9/sys/dev/qlxgbe/ql_hw.c Wed Apr 19 02:59:26 2017 (r317112)
+++ stable/9/sys/dev/qlxgbe/ql_hw.c Wed Apr 19 03:02:23 2017 (r317113)
@@ -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: stable/9/sys/dev/qlxgbe/ql_hw.h
==============================================================================
--- stable/9/sys/dev/qlxgbe/ql_hw.h Wed Apr 19 02:59:26 2017 (r317112)
+++ stable/9/sys/dev/qlxgbe/ql_hw.h Wed Apr 19 03:02:23 2017 (r317113)
@@ -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: stable/9/sys/dev/qlxgbe/ql_isr.c
==============================================================================
--- stable/9/sys/dev/qlxgbe/ql_isr.c Wed Apr 19 02:59:26 2017 (r317112)
+++ stable/9/sys/dev/qlxgbe/ql_isr.c Wed Apr 19 03:02:23 2017 (r317113)
@@ -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;
@@ -161,7 +164,22 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_
mpf->m_pkthdr.flowid = sgc->rss_hash;
mpf->m_flags |= M_FLOWID;
- (*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);
@@ -703,6 +721,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: stable/9/sys/dev/qlxgbe/ql_os.c
==============================================================================
--- stable/9/sys/dev/qlxgbe/ql_os.c Wed Apr 19 02:59:26 2017 (r317112)
+++ stable/9/sys/dev/qlxgbe/ql_os.c Wed Apr 19 03:02:23 2017 (r317113)
@@ -1077,6 +1077,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);
@@ -1518,7 +1520,6 @@ qla_qflush(struct ifnet *ifp)
return;
}
-
static void
qla_stop(qla_host_t *ha)
{
More information about the svn-src-stable-9
mailing list