diff options
-rw-r--r-- | drivers/net/igb/e1000_82575.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/e1000_defines.h | 1 | ||||
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 12 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 21 |
4 files changed, 31 insertions, 4 deletions
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index eaf977050368..0f16abab2565 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h | |||
@@ -130,6 +130,7 @@ struct e1000_adv_tx_context_desc { | |||
130 | #define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ | 130 | #define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ |
131 | #define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ | 131 | #define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ |
132 | #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ | 132 | #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ |
133 | #define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */ | ||
133 | /* IPSec Encrypt Enable for ESP */ | 134 | /* IPSec Encrypt Enable for ESP */ |
134 | #define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ | 135 | #define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ |
135 | #define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ | 136 | #define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ |
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 65acbbaca2d5..3bda3db73f1f 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h | |||
@@ -291,6 +291,7 @@ | |||
291 | /* Receive Checksum Control */ | 291 | /* Receive Checksum Control */ |
292 | #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ | 292 | #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ |
293 | #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ | 293 | #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ |
294 | #define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */ | ||
294 | #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ | 295 | #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ |
295 | 296 | ||
296 | /* Header split receive */ | 297 | /* Header split receive */ |
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 27eae49e79c2..b1367ce6586e 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c | |||
@@ -293,10 +293,16 @@ static u32 igb_get_tx_csum(struct net_device *netdev) | |||
293 | 293 | ||
294 | static int igb_set_tx_csum(struct net_device *netdev, u32 data) | 294 | static int igb_set_tx_csum(struct net_device *netdev, u32 data) |
295 | { | 295 | { |
296 | if (data) | 296 | struct igb_adapter *adapter = netdev_priv(netdev); |
297 | |||
298 | if (data) { | ||
297 | netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); | 299 | netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); |
298 | else | 300 | if (adapter->hw.mac.type == e1000_82576) |
299 | netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); | 301 | netdev->features |= NETIF_F_SCTP_CSUM; |
302 | } else { | ||
303 | netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | ||
304 | NETIF_F_SCTP_CSUM); | ||
305 | } | ||
300 | 306 | ||
301 | return 0; | 307 | return 0; |
302 | } | 308 | } |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index f7f861215242..bca7e9f76be4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -1345,6 +1345,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, | |||
1345 | if (pci_using_dac) | 1345 | if (pci_using_dac) |
1346 | netdev->features |= NETIF_F_HIGHDMA; | 1346 | netdev->features |= NETIF_F_HIGHDMA; |
1347 | 1347 | ||
1348 | if (adapter->hw.mac.type == e1000_82576) | ||
1349 | netdev->features |= NETIF_F_SCTP_CSUM; | ||
1350 | |||
1348 | adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw); | 1351 | adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw); |
1349 | 1352 | ||
1350 | /* before reading the NVM, reset the controller to put the device in a | 1353 | /* before reading the NVM, reset the controller to put the device in a |
@@ -2249,6 +2252,10 @@ static void igb_configure_rx(struct igb_adapter *adapter) | |||
2249 | /* Don't need to set TUOFL or IPOFL, they default to 1 */ | 2252 | /* Don't need to set TUOFL or IPOFL, they default to 1 */ |
2250 | if (!adapter->rx_csum) | 2253 | if (!adapter->rx_csum) |
2251 | rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL); | 2254 | rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL); |
2255 | else if (adapter->hw.mac.type == e1000_82576) | ||
2256 | /* Enable Receive Checksum Offload for SCTP */ | ||
2257 | rxcsum |= E1000_RXCSUM_CRCOFL; | ||
2258 | |||
2252 | wr32(E1000_RXCSUM, rxcsum); | 2259 | wr32(E1000_RXCSUM, rxcsum); |
2253 | 2260 | ||
2254 | /* Set the default pool for the PF's first queue */ | 2261 | /* Set the default pool for the PF's first queue */ |
@@ -3064,11 +3071,15 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, | |||
3064 | tu_cmd |= E1000_ADVTXD_TUCMD_IPV4; | 3071 | tu_cmd |= E1000_ADVTXD_TUCMD_IPV4; |
3065 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) | 3072 | if (ip_hdr(skb)->protocol == IPPROTO_TCP) |
3066 | tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; | 3073 | tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; |
3074 | else if (ip_hdr(skb)->protocol == IPPROTO_SCTP) | ||
3075 | tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP; | ||
3067 | break; | 3076 | break; |
3068 | case cpu_to_be16(ETH_P_IPV6): | 3077 | case cpu_to_be16(ETH_P_IPV6): |
3069 | /* XXX what about other V6 headers?? */ | 3078 | /* XXX what about other V6 headers?? */ |
3070 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) | 3079 | if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) |
3071 | tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; | 3080 | tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; |
3081 | else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP) | ||
3082 | tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP; | ||
3072 | break; | 3083 | break; |
3073 | default: | 3084 | default: |
3074 | if (unlikely(net_ratelimit())) | 3085 | if (unlikely(net_ratelimit())) |
@@ -4449,14 +4460,22 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter, | |||
4449 | /* TCP/UDP checksum error bit is set */ | 4460 | /* TCP/UDP checksum error bit is set */ |
4450 | if (status_err & | 4461 | if (status_err & |
4451 | (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) { | 4462 | (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) { |
4463 | /* | ||
4464 | * work around errata with sctp packets where the TCPE aka | ||
4465 | * L4E bit is set incorrectly on 64 byte (60 byte w/o crc) | ||
4466 | * packets, (aka let the stack check the crc32c) | ||
4467 | */ | ||
4468 | if (!((adapter->hw.mac.type == e1000_82576) && | ||
4469 | (skb->len == 60))) | ||
4470 | adapter->hw_csum_err++; | ||
4452 | /* let the stack verify checksum errors */ | 4471 | /* let the stack verify checksum errors */ |
4453 | adapter->hw_csum_err++; | ||
4454 | return; | 4472 | return; |
4455 | } | 4473 | } |
4456 | /* It must be a TCP or UDP packet with a valid checksum */ | 4474 | /* It must be a TCP or UDP packet with a valid checksum */ |
4457 | if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) | 4475 | if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) |
4458 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 4476 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
4459 | 4477 | ||
4478 | dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err); | ||
4460 | adapter->hw_csum_good++; | 4479 | adapter->hw_csum_good++; |
4461 | } | 4480 | } |
4462 | 4481 | ||