aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/igb/e1000_82575.h1
-rw-r--r--drivers/net/igb/e1000_defines.h1
-rw-r--r--drivers/net/igb/igb_ethtool.c12
-rw-r--r--drivers/net/igb/igb_main.c21
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
294static int igb_set_tx_csum(struct net_device *netdev, u32 data) 294static 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