Skip to content

Commit

Permalink
atl1: fix broken TSO
Browse files Browse the repository at this point in the history
The L1 tx packet descriptor expects TCP Header Length to be expressed as a
number of 32-bit dwords.  The atl1 driver uses tcp_hdrlen() to populate the
field, but tcp_hdrlen() returns the header length in bytes, not in dwords.
Add a shift to convert tcp_hdrlen() to dwords when we write it to the tpd.

Also, some of our bit assignments are made to the wrong tpd words.  Change
those to the correct words.

Finally, since all this fixes TSO, enable TSO by default.

Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Jay Cliburn authored and Jeff Garzik committed Mar 17, 2008
1 parent 305282b commit 9d90fb1
Showing 1 changed file with 11 additions and 18 deletions.
29 changes: 11 additions & 18 deletions drivers/net/atlx/atl1.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
* A very incomplete list of things that need to be dealt with:
*
* TODO:
* Fix TSO; tx performance is horrible with TSO enabled.
* Wake on LAN.
* Add more ethtool functions.
* Fix abstruse irq enable/disable condition described here:
Expand Down Expand Up @@ -1308,8 +1307,8 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;

tso->tsopl |= (iph->ihl &
CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT;
tso->tsopl |= (tcp_hdrlen(skb) &
TSO_PARAM_IPHL_MASK) << TSO_PARAM_IPHL_SHIFT;
tso->tsopl |= ((tcp_hdrlen(skb) >> 2) &
TSO_PARAM_TCPHDRLEN_MASK) <<
TSO_PARAM_TCPHDRLEN_SHIFT;
tso->tsopl |= (skb_shinfo(skb)->gso_size &
Expand Down Expand Up @@ -1472,16 +1471,16 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
tpd->desc.tso.tsopl = descr->tso.tsopl;
tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
tpd->desc.data = descr->data;
tpd->desc.csum.csumpu |= (cpu_to_le16(buffer_info->length) &
CSUM_PARAM_BUFLEN_MASK) << CSUM_PARAM_BUFLEN_SHIFT;
tpd->desc.tso.tsopu |= (cpu_to_le16(buffer_info->length) &
TSO_PARAM_BUFLEN_MASK) << TSO_PARAM_BUFLEN_SHIFT;

val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
TSO_PARAM_SEGMENT_MASK;
if (val && !j)
tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT;

if (j == (count - 1))
tpd->desc.csum.csumpl |= 1 << CSUM_PARAM_EOP_SHIFT;
tpd->desc.tso.tsopl |= 1 << TSO_PARAM_EOP_SHIFT;

if (++tpd_next_to_use == tpd_ring->count)
tpd_next_to_use = 0;
Expand Down Expand Up @@ -1574,9 +1573,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
vlan_tag = vlan_tx_tag_get(skb);
vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
((vlan_tag >> 9) & 0x8);
param.csum.csumpl |= 1 << CSUM_PARAM_INSVLAG_SHIFT;
param.csum.csumpu |= (vlan_tag & CSUM_PARAM_VALANTAG_MASK) <<
CSUM_PARAM_VALAN_SHIFT;
param.tso.tsopl |= 1 << TSO_PARAM_INSVLAG_SHIFT;
param.tso.tsopu |= (vlan_tag & TSO_PARAM_VLANTAG_MASK) <<
TSO_PARAM_VLAN_SHIFT;
}

tso = atl1_tso(adapter, skb, &param.tso);
Expand All @@ -1595,8 +1594,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}

val = (param.csum.csumpl >> CSUM_PARAM_SEGMENT_SHIFT) &
CSUM_PARAM_SEGMENT_MASK;
val = (param.tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
TSO_PARAM_SEGMENT_MASK;
atl1_tx_map(adapter, skb, 1 == val);
atl1_tx_queue(adapter, count, &param);
netdev->trans_start = jiffies;
Expand Down Expand Up @@ -2091,13 +2090,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->features = NETIF_F_HW_CSUM;
netdev->features |= NETIF_F_SG;
netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);

/*
* FIXME - Until tso performance gets fixed, disable the feature.
* Enable it with ethtool -K if desired.
*/
/* netdev->features |= NETIF_F_TSO; */

netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_LLTX;

/*
Expand Down

0 comments on commit 9d90fb1

Please sign in to comment.