diff options
author | Ron Mercer <ron.mercer@qlogic.com> | 2009-03-09 06:59:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-10 07:43:51 -0400 |
commit | d555f5921f2b0d9f65b547dd0be67c870ff5a56f (patch) | |
tree | 563ca25955fdffa702871ef68eaa090b8b2900c4 | |
parent | a75ee7f1ccace560642e5dc6b1c0e22c73da5a8c (diff) |
qlge: Increase filtering for inbound csum settings.
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>
-rw-r--r-- | drivers/net/qlge/qlge.h | 1 | ||||
-rw-r--r-- | drivers/net/qlge/qlge_main.c | 41 |
2 files changed, 29 insertions, 13 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 9918106f2a53..fcb159e4df54 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -977,6 +977,7 @@ struct ib_mac_iocb_rsp { | |||
977 | u8 flags1; | 977 | u8 flags1; |
978 | #define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */ | 978 | #define IB_MAC_IOCB_RSP_OI 0x01 /* Overide intr delay */ |
979 | #define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */ | 979 | #define IB_MAC_IOCB_RSP_I 0x02 /* Disble Intr Generation */ |
980 | #define IB_MAC_CSUM_ERR_MASK 0x1c /* A mask to use for csum errs */ | ||
980 | #define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ | 981 | #define IB_MAC_IOCB_RSP_TE 0x04 /* Checksum error */ |
981 | #define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ | 982 | #define IB_MAC_IOCB_RSP_NU 0x08 /* No checksum rcvd */ |
982 | #define IB_MAC_IOCB_RSP_IE 0x10 /* IPv4 checksum error */ | 983 | #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 bc04aebc9289..498d4bf52116 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -1531,22 +1531,37 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev, | |||
1531 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { | 1531 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) { |
1532 | QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n"); | 1532 | QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n"); |
1533 | } | 1533 | } |
1534 | if (ib_mac_rsp->flags1 & (IB_MAC_IOCB_RSP_IE | IB_MAC_IOCB_RSP_TE)) { | 1534 | |
1535 | QPRINTK(qdev, RX_STATUS, ERR, | 1535 | |
1536 | "Bad checksum for this %s packet.\n", | 1536 | skb->protocol = eth_type_trans(skb, ndev); |
1537 | ((ib_mac_rsp-> | 1537 | skb->ip_summed = CHECKSUM_NONE; |
1538 | flags2 & IB_MAC_IOCB_RSP_T) ? "TCP" : "UDP")); | 1538 | |
1539 | skb->ip_summed = CHECKSUM_NONE; | 1539 | /* If rx checksum is on, and there are no |
1540 | } else if (qdev->rx_csum && | 1540 | * csum or frame errors. |
1541 | ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) || | 1541 | */ |
1542 | ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && | 1542 | if (qdev->rx_csum && |
1543 | !(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_NU)))) { | 1543 | !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) && |
1544 | QPRINTK(qdev, RX_STATUS, DEBUG, "RX checksum done!\n"); | 1544 | !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { |
1545 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1545 | /* TCP frame. */ |
1546 | if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) { | ||
1547 | QPRINTK(qdev, RX_STATUS, DEBUG, | ||
1548 | "TCP checksum done!\n"); | ||
1549 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1550 | } else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) && | ||
1551 | (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) { | ||
1552 | /* Unfragmented ipv4 UDP frame. */ | ||
1553 | struct iphdr *iph = (struct iphdr *) skb->data; | ||
1554 | if (!(iph->frag_off & | ||
1555 | cpu_to_be16(IP_MF|IP_OFFSET))) { | ||
1556 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1557 | QPRINTK(qdev, RX_STATUS, DEBUG, | ||
1558 | "TCP checksum done!\n"); | ||
1559 | } | ||
1560 | } | ||
1546 | } | 1561 | } |
1562 | |||
1547 | qdev->stats.rx_packets++; | 1563 | qdev->stats.rx_packets++; |
1548 | qdev->stats.rx_bytes += skb->len; | 1564 | qdev->stats.rx_bytes += skb->len; |
1549 | skb->protocol = eth_type_trans(skb, ndev); | ||
1550 | skb_record_rx_queue(skb, rx_ring - &qdev->rx_ring[0]); | 1565 | skb_record_rx_queue(skb, rx_ring - &qdev->rx_ring[0]); |
1551 | if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) { | 1566 | if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) { |
1552 | QPRINTK(qdev, RX_STATUS, DEBUG, | 1567 | QPRINTK(qdev, RX_STATUS, DEBUG, |