From 44b0cda37534093fd9fefacd64d5fbb589c50795 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 7 Mar 2008 10:32:13 -0800 Subject: igb: Correctly get protocol information We can't look at the socket to get protocol information. We should instead look directly at the packet, and hope there are no IPv6 option headers. Signed-off-by: Mitch Williams Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6a1f23092099..928ce8287e69 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -2484,10 +2483,24 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (skb->protocol == htons(ETH_P_IP)) + switch (skb->protocol) { + case __constant_htons(ETH_P_IP): tu_cmd |= E1000_ADVTXD_TUCMD_IPV4; - if (skb->sk && (skb->sk->sk_protocol == IPPROTO_TCP)) - tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + if (ip_hdr(skb)->protocol == IPPROTO_TCP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + break; + case __constant_htons(ETH_P_IPV6): + /* XXX what about other V6 headers?? */ + if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + break; + default: + if (unlikely(net_ratelimit())) + dev_warn(&adapter->pdev->dev, + "partial checksum but proto=%x!\n", + skb->protocol); + break; + } } context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd); -- cgit v1.2.2 From 7deb07b1befc9f09dbdaed66c9613a3d08f1c061 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 16 Mar 2008 22:43:06 +0000 Subject: igb: endianness fix le16_to_cpu() should be done before mask and shift... Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 928ce8287e69..9f3168d6e239 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3452,8 +3452,8 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter, * that case, it fills the header buffer and spills the rest * into the page. */ - hlen = le16_to_cpu((rx_desc->wb.lower.lo_dword.hdr_info & - E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT); + hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) & + E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT; if (hlen > adapter->rx_ps_hdr_size) hlen = adapter->rx_ps_hdr_size; -- cgit v1.2.2 From 6d8126f988556d593f13be32cbe60dacf19c2d2c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 16 Mar 2008 22:23:24 +0000 Subject: igb trivial annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/igb/igb_main.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 9f3168d6e239..aaee02e9e3f0 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3254,6 +3254,13 @@ quit_polling: return 1; } + +static inline u32 get_head(struct igb_ring *tx_ring) +{ + void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count; + return le32_to_cpu(*(volatile __le32 *)end); +} + /** * igb_clean_tx_irq - Reclaim resources after transmit completes * @adapter: board private structure @@ -3275,9 +3282,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter, unsigned int total_bytes = 0, total_packets = 0; rmb(); - head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc - + tx_ring->count); - head = le32_to_cpu(head); + head = get_head(tx_ring); i = tx_ring->next_to_clean; while (1) { while (i != head) { @@ -3312,9 +3317,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter, } oldhead = head; rmb(); - head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc - + tx_ring->count); - head = le32_to_cpu(head); + head = get_head(tx_ring); if (head == oldhead) goto done_cleaning; } /* while (1) */ @@ -3388,7 +3391,7 @@ done_cleaning: * @vlan: descriptor vlan field as written by hardware (no le/be conversion) * @skb: pointer to sk_buff to be indicated to stack **/ -static void igb_receive_skb(struct igb_adapter *adapter, u8 status, u16 vlan, +static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan, struct sk_buff *skb) { if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) -- cgit v1.2.2