diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-03-11 07:55:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-13 14:27:23 -0400 |
commit | c3c6496dc3d94d87bb0da86cf0bf48764577bf77 (patch) | |
tree | 590533161de2317b27c1af6ebee34b22db08009d /drivers/net/qlge | |
parent | 9fae6c3f648e38f023b99b5f5a5280907b2e796e (diff) |
qlge: bugfix: Increase filter on inbound csum.
Chip does not do UDP checksum when fragmentation occurs.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/qlge')
-rw-r--r-- | drivers/net/qlge/qlge.h | 1 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 38 |
2 files changed, 27 insertions, 12 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index e6fdce9206cc..aff9c5fec738 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -927,6 +927,7 @@ struct ib_mac_iocb_rsp { | |||
927 | u8 flags1; | 927 | u8 flags1; |
928 | #define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */ | 928 | #define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */ |
929 | #define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */ | 929 | #define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */ |
930 | #define IB_MAC_CSUM_ERR_MASK 0x1c /* A mask to use for csum errs */ | ||
930 | #define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ | 931 | #define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ |
931 | #define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ | 932 | #define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ |
932 | #define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */ | 933 | #define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */ |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 8ea72dc60f79..87787b1ecab2 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -1436,18 +1436,32 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, | |||
1436 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { | 1436 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { |
1437 | QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n"); | 1437 | QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n"); |
1438 | } | 1438 | } |
1439 | if (ib_mac_rsp->flags1 & (IB_MAC_IOCB_RSP_IE | IB_MAC_IOCB_RSP_TE)) { | 1439 | |
1440 | QPRINTK(qdev, RX_STATUS, ERR, | 1440 | skb->protocol = eth_type_trans(skb, ndev); |
1441 | "Bad checksum for this %s packet.\n", | 1441 | skb->ip_summed = CHECKSUM_NONE; |
1442 | ((ib_mac_rsp-> | 1442 | |
1443 | flags2 & IB_MAC_IOCB_RSP_T) ? "TCP" : "UDP")); | 1443 | /* If rx checksum is on, and there are no |
1444 | skb->ip_summed = CHECKSUM_NONE; | 1444 | * csum or frame errors. |
1445 | } else if (qdev->rx_csum && | 1445 | */ |
1446 | ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) || | 1446 | if (qdev->rx_csum && |
1447 | ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && | 1447 | !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && |
1448 | !(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_NU)))) { | 1448 | !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { |
1449 | QPRINTK(qdev, RX_STATUS, DEBUG, "RX checksum done!\n"); | 1449 | /* TCP frame. */ |
1450 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1450 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { |
1451 | QPRINTK(qdev, RX_STATUS, DEBUG, | ||
1452 | "TCP checksum done!\n"); | ||
1453 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1454 | } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && | ||
1455 | (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { | ||
1456 | /* Unfragmented ipv4 UDP frame. */ | ||
1457 | struct iphdr *iph = (struct iphdr *) skb->data; | ||
1458 | if (!(iph->frag_off & | ||
1459 | cpu_to_be16(IP_MF|IP_OFFSET))) { | ||
1460 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1461 | QPRINTK(qdev, RX_STATUS, DEBUG, | ||
1462 | "TCP checksum done!\n"); | ||
1463 | } | ||
1464 | } | ||
1451 | } | 1465 | } |
1452 | qdev->stats.rx_packets++; | 1466 | qdev->stats.rx_packets++; |
1453 | qdev->stats.rx_bytes += skb->len; | 1467 | qdev->stats.rx_bytes += skb->len; |