Skip to content

Commit

Permalink
netxen_nic: Fix estimation of recv MSS in case of LRO
Browse files Browse the repository at this point in the history
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: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Rajesh Borundia authored and David S. Miller committed May 10, 2012
1 parent d612698 commit 01da0c2
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
10 changes: 8 additions & 2 deletions drivers/net/ethernet/qlogic/netxen/netxen_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@

#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
#define _NETXEN_NIC_LINUX_SUBVERSION 78
#define NETXEN_NIC_LINUX_VERSIONID "4.0.78"
#define _NETXEN_NIC_LINUX_SUBVERSION 79
#define NETXEN_NIC_LINUX_VERSIONID "4.0.79"

#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
Expand Down Expand Up @@ -419,6 +419,8 @@ struct rcv_desc {
(((sts_data) >> 52) & 0x1)
#define netxen_get_lro_sts_seq_number(sts_data) \
((sts_data) & 0x0FFFFFFFF)
#define netxen_get_lro_sts_mss(sts_data1) \
((sts_data1 >> 32) & 0x0FFFF)


struct status_desc {
Expand Down Expand Up @@ -794,6 +796,7 @@ struct netxen_cmd_args {
#define NX_CAP0_JUMBO_CONTIGUOUS NX_CAP_BIT(0, 7)
#define NX_CAP0_LRO_CONTIGUOUS NX_CAP_BIT(0, 8)
#define NX_CAP0_HW_LRO NX_CAP_BIT(0, 10)
#define NX_CAP0_HW_LRO_MSS NX_CAP_BIT(0, 21)

/*
* Context state
Expand Down Expand Up @@ -1073,6 +1076,8 @@ typedef struct {
#define NX_FW_CAPABILITY_FVLANTX (1 << 9)
#define NX_FW_CAPABILITY_HW_LRO (1 << 10)
#define NX_FW_CAPABILITY_GBE_LINK_CFG (1 << 11)
#define NX_FW_CAPABILITY_MORE_CAPS (1 << 31)
#define NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG (1 << 2)

/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1
Expand Down Expand Up @@ -1155,6 +1160,7 @@ typedef struct {
#define NETXEN_NIC_BRIDGE_ENABLED 0X10
#define NETXEN_NIC_DIAG_ENABLED 0x20
#define NETXEN_FW_RESET_OWNER 0x40
#define NETXEN_FW_MSS_CAP 0x80
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS);

if (adapter->flags & NETXEN_FW_MSS_CAP)
cap |= NX_CAP0_HW_LRO_MSS;

prq->capabilities[0] = cpu_to_le32(cap);
prq->host_int_crb_mode =
cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ enum {
#define CRB_SW_INT_MASK_3 (NETXEN_NIC_REG(0x1e8))

#define CRB_FW_CAPABILITIES_1 (NETXEN_CAM_RAM(0x128))
#define CRB_FW_CAPABILITIES_2 (NETXEN_CAM_RAM(0x12c))
#define CRB_MAC_BLOCK_START (NETXEN_CAM_RAM(0x1c0))

/*
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,6 @@ netxen_validate_firmware(struct netxen_adapter *adapter)
_build(file_fw_ver));
return -EINVAL;
}

val = nx_get_bios_version(adapter);
netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
if ((__force u32)val != bios) {
Expand Down Expand Up @@ -1661,6 +1660,9 @@ netxen_process_lro(struct netxen_adapter *adapter,

length = skb->len;

if (adapter->flags & NETXEN_FW_MSS_CAP)
skb_shinfo(skb)->gso_size = netxen_get_lro_sts_mss(sts_data1);

netif_receive_skb(skb);

adapter->stats.lro_pkts++;
Expand Down
9 changes: 8 additions & 1 deletion drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
int err, ring;
struct nx_host_rds_ring *rds_ring;
struct nx_host_tx_ring *tx_ring;
u32 capab2;

if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
return 0;
Expand All @@ -1192,6 +1193,13 @@ netxen_nic_attach(struct netxen_adapter *adapter)
if (err)
return err;

adapter->flags &= ~NETXEN_FW_MSS_CAP;
if (adapter->capabilities & NX_FW_CAPABILITY_MORE_CAPS) {
capab2 = NXRD32(adapter, CRB_FW_CAPABILITIES_2);
if (capab2 & NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
adapter->flags |= NETXEN_FW_MSS_CAP;
}

err = netxen_napi_add(adapter, netdev);
if (err)
return err;
Expand Down Expand Up @@ -1810,7 +1818,6 @@ netxen_tso_check(struct net_device *netdev,
flags = FLAGS_VLAN_TAGGED;

} else if (vlan_tx_tag_present(skb)) {

flags = FLAGS_VLAN_OOB;
vid = vlan_tx_tag_get(skb);
netxen_set_tx_vlan_tci(first_desc, vid);
Expand Down

0 comments on commit 01da0c2

Please sign in to comment.