aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/atlx/atl1.c
diff options
context:
space:
mode:
authorJay Cliburn <jacliburn@bellsouth.net>2008-08-04 20:05:10 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-08-07 01:54:57 -0400
commitc2ac3ef35c44195ca2b9c29275c7c6830eb2d9aa (patch)
tree448f9d1395dc415dbf752d2564626cd3cbc10ed9 /drivers/net/atlx/atl1.c
parentf0f422e5735ba9f48039aa7dd4c9daa16b996c2c (diff)
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.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index f12e3d12474b..e6a7bb79d4df 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,
1790{ 1790{
1791 struct pci_dev *pdev = adapter->pdev; 1791 struct pci_dev *pdev = adapter->pdev;
1792 1792
1793 /*
1794 * The L1 hardware contains a bug that erroneously sets the
1795 * PACKET_FLAG_ERR and ERR_FLAG_L4_CHKSUM bits whenever a
1796 * fragmented IP packet is received, even though the packet
1797 * is perfectly valid and its checksum is correct. There's
1798 * no way to distinguish between one of these good packets
1799 * and a packet that actually contains a TCP/UDP checksum
1800 * error, so all we can do is allow it to be handed up to
1801 * the higher layers and let it be sorted out there.
1802 */
1803
1793 skb->ip_summed = CHECKSUM_NONE; 1804 skb->ip_summed = CHECKSUM_NONE;
1794 1805
1795 if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { 1806 if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
@@ -1816,14 +1827,6 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
1816 return; 1827 return;
1817 } 1828 }
1818 1829
1819 /* IPv4, but hardware thinks its checksum is wrong */
1820 if (netif_msg_rx_err(adapter))
1821 dev_printk(KERN_DEBUG, &pdev->dev,
1822 "hw csum wrong, pkt_flag:%x, err_flag:%x\n",
1823 rrd->pkt_flg, rrd->err_flg);
1824 skb->ip_summed = CHECKSUM_COMPLETE;
1825 skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
1826 adapter->hw_csum_err++;
1827 return; 1830 return;
1828} 1831}
1829 1832