diff options
author | Jay Cliburn <jacliburn@bellsouth.net> | 2008-08-04 19:05:10 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-08-07 01:54:57 -0400 |
commit | c2ac3ef35c44195ca2b9c29275c7c6830eb2d9aa (patch) | |
tree | 448f9d1395dc415dbf752d2564626cd3cbc10ed9 /drivers/net/atlx/atl1.c | |
parent | f0f422e5735ba9f48039aa7dd4c9daa16b996c2c (diff) | |
download | kernel-crypto-c2ac3ef35c44195ca2b9c29275c7c6830eb2d9aa.tar.gz kernel-crypto-c2ac3ef35c44195ca2b9c29275c7c6830eb2d9aa.tar.xz kernel-crypto-c2ac3ef35c44195ca2b9c29275c7c6830eb2d9aa.zip |
atl1: deal with hardware rx checksum bug
The L1 hardware contains a bug that flags a fragmented IP packet
as having an incorrect TCP/UDP checksum, even though the packet
is perfectly valid and its checksum is correct. There's no way to
distinguish between one of these good packets and a packet that
actually contains a TCP/UDP checksum error, so all we can do is
allow the packet to be handed up to the higher layers and let it
be sorted out there.
Add a comment describing this condition and remove the code that
currently fails to handle what may or may not be a checksum error.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/atlx/atl1.c')
-rw-r--r-- | drivers/net/atlx/atl1.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index f12e3d12474..e6a7bb79d4d 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1790,6 +1790,17 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, { struct pci_dev *pdev = adapter->pdev; + /* + * The L1 hardware contains a bug that erroneously sets the + * PACKET_FLAG_ERR and ERR_FLAG_L4_CHKSUM bits whenever a + * fragmented IP packet is received, even though the packet + * is perfectly valid and its checksum is correct. There's + * no way to distinguish between one of these good packets + * and a packet that actually contains a TCP/UDP checksum + * error, so all we can do is allow it to be handed up to + * the higher layers and let it be sorted out there. + */ + skb->ip_summed = CHECKSUM_NONE; if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { @@ -1816,14 +1827,6 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, return; } - /* IPv4, but hardware thinks its checksum is wrong */ - if (netif_msg_rx_err(adapter)) - dev_printk(KERN_DEBUG, &pdev->dev, - "hw csum wrong, pkt_flag:%x, err_flag:%x\n", - rrd->pkt_flg, rrd->err_flg); - skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum); - adapter->hw_csum_err++; return; } |