Add support for optional Soft LRO
MFC after:5 days
This commit is contained in:
parent
1c2da02938
commit
a7c62c116c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=316309
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -68,6 +68,9 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_t *sgc, uint32_t sds_idx)
|
||||
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_t *sgc, uint32_t sds_idx)
|
||||
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_idx, uint32_t count)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -1072,6 +1072,8 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user