Commit cae82d49 authored by Rajesh Borundia's avatar Rajesh Borundia Committed by David S. Miller

qlcnic: Fix estimation of recv MSS in case of LRO

o Linux stack estimates MSS from skb->len or skb_shinfo(skb)->gso_size.
In case of LRO skb->len is aggregate of len of number of packets hence MSS
obtained using skb->len would be incorrect. Incorrect estimation of recv MSS
would lead to delayed acks in some traffic patterns (which sends two or three
packets and wait for ack and only then send remaining packets). This leads to
drop in performance. Hence we need to set gso_size to MSS obtained from firmware.

o This is fixed recently in firmware hence the MSS is obtained based on
capability. If fw is capable of sending the MSS then only driver sets the gso_size.
Signed-off-by: default avatarRajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c3001b77
...@@ -258,6 +258,8 @@ struct rcv_desc { ...@@ -258,6 +258,8 @@ struct rcv_desc {
(((sts_data) >> 52) & 0x1) (((sts_data) >> 52) & 0x1)
#define qlcnic_get_lro_sts_seq_number(sts_data) \ #define qlcnic_get_lro_sts_seq_number(sts_data) \
((sts_data) & 0x0FFFFFFFF) ((sts_data) & 0x0FFFFFFFF)
#define qlcnic_get_lro_sts_mss(sts_data1) \
((sts_data1 >> 32) & 0x0FFFF)
struct status_desc { struct status_desc {
...@@ -623,6 +625,7 @@ struct qlcnic_recv_context { ...@@ -623,6 +625,7 @@ struct qlcnic_recv_context {
#define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) #define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7)
#define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) #define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8)
#define QLCNIC_CAP0_VALIDOFF (1 << 11) #define QLCNIC_CAP0_VALIDOFF (1 << 11)
#define QLCNIC_CAP0_LRO_MSS (1 << 21)
/* /*
* Context state * Context state
...@@ -829,6 +832,9 @@ struct qlcnic_mac_list_s { ...@@ -829,6 +832,9 @@ struct qlcnic_mac_list_s {
#define QLCNIC_FW_CAPABILITY_FVLANTX BIT_9 #define QLCNIC_FW_CAPABILITY_FVLANTX BIT_9
#define QLCNIC_FW_CAPABILITY_HW_LRO BIT_10 #define QLCNIC_FW_CAPABILITY_HW_LRO BIT_10
#define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK BIT_27 #define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK BIT_27
#define QLCNIC_FW_CAPABILITY_MORE_CAPS BIT_31
#define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG BIT_2
/* module types */ /* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1 #define LINKEVENT_MODULE_NOT_PRESENT 1
...@@ -918,6 +924,7 @@ struct qlcnic_ipaddr { ...@@ -918,6 +924,7 @@ struct qlcnic_ipaddr {
#define QLCNIC_NEED_FLR 0x1000 #define QLCNIC_NEED_FLR 0x1000
#define QLCNIC_FW_RESET_OWNER 0x2000 #define QLCNIC_FW_RESET_OWNER 0x2000
#define QLCNIC_FW_HANG 0x4000 #define QLCNIC_FW_HANG 0x4000
#define QLCNIC_FW_LRO_MSS_CAP 0x8000
#define QLCNIC_IS_MSI_FAMILY(adapter) \ #define QLCNIC_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
......
...@@ -237,6 +237,9 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) ...@@ -237,6 +237,9 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
| QLCNIC_CAP0_VALIDOFF); | QLCNIC_CAP0_VALIDOFF);
cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
cap |= QLCNIC_CAP0_LRO_MSS;
prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx, prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx,
msix_handler); msix_handler);
prq->txrx_sds_binding = nsds_rings - 1; prq->txrx_sds_binding = nsds_rings - 1;
......
...@@ -588,6 +588,7 @@ enum { ...@@ -588,6 +588,7 @@ enum {
#define CRB_DRIVER_VERSION (QLCNIC_REG(0x2a0)) #define CRB_DRIVER_VERSION (QLCNIC_REG(0x2a0))
#define CRB_FW_CAPABILITIES_1 (QLCNIC_CAM_RAM(0x128)) #define CRB_FW_CAPABILITIES_1 (QLCNIC_CAM_RAM(0x128))
#define CRB_FW_CAPABILITIES_2 (QLCNIC_CAM_RAM(0x12c))
#define CRB_MAC_BLOCK_START (QLCNIC_CAM_RAM(0x1c0)) #define CRB_MAC_BLOCK_START (QLCNIC_CAM_RAM(0x1c0))
/* /*
......
...@@ -1653,6 +1653,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, ...@@ -1653,6 +1653,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
length = skb->len; length = skb->len;
if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
skb_shinfo(skb)->gso_size = qlcnic_get_lro_sts_mss(sts_data1);
if (vid != 0xffff) if (vid != 0xffff)
__vlan_hwaccel_put_tag(skb, vid); __vlan_hwaccel_put_tag(skb, vid);
netif_receive_skb(skb); netif_receive_skb(skb);
......
...@@ -1136,6 +1136,8 @@ static int ...@@ -1136,6 +1136,8 @@ static int
__qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
{ {
int ring; int ring;
u32 capab2;
struct qlcnic_host_rds_ring *rds_ring; struct qlcnic_host_rds_ring *rds_ring;
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
...@@ -1146,6 +1148,12 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1146,6 +1148,12 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
if (qlcnic_set_eswitch_port_config(adapter)) if (qlcnic_set_eswitch_port_config(adapter))
return -EIO; return -EIO;
if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2);
if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
adapter->flags |= QLCNIC_FW_LRO_MSS_CAP;
}
if (qlcnic_fw_create_ctx(adapter)) if (qlcnic_fw_create_ctx(adapter))
return -EIO; return -EIO;
...@@ -1215,6 +1223,7 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1215,6 +1223,7 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_napi_disable(adapter); qlcnic_napi_disable(adapter);
qlcnic_fw_destroy_ctx(adapter); qlcnic_fw_destroy_ctx(adapter);
adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP;
qlcnic_reset_rx_buffers_list(adapter); qlcnic_reset_rx_buffers_list(adapter);
qlcnic_release_tx_buffers(adapter); qlcnic_release_tx_buffers(adapter);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment