From owner-svn-src-stable@freebsd.org Wed Apr 19 03:02:25 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1B343D456FD; Wed, 19 Apr 2017 03:02:25 +0000 (UTC) (envelope-from davidcs@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 mx1.freebsd.org (Postfix) with ESMTPS id E9A906E7; Wed, 19 Apr 2017 03:02:24 +0000 (UTC) (envelope-from davidcs@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3J32OcV047426; Wed, 19 Apr 2017 03:02:24 GMT (envelope-from davidcs@FreeBSD.org) Received: (from davidcs@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3J32Nbq047421; Wed, 19 Apr 2017 03:02:23 GMT (envelope-from davidcs@FreeBSD.org) Message-Id: <201704190302.v3J32Nbq047421@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: davidcs set sender to davidcs@FreeBSD.org using -f From: David C Somayajulu Date: Wed, 19 Apr 2017 03:02:23 +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: r317113 - stable/9/sys/dev/qlxgbe 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.23 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: Wed, 19 Apr 2017 03:02:25 -0000 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) {