diff options
Diffstat (limited to 'drivers/net/igb/igb_main.c')
-rw-r--r-- | drivers/net/igb/igb_main.c | 21 |
1 files changed, 20 insertions, 1 deletions
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 | ||