diff options
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/netdev.c | 41 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/e1000e/param.c | 5 |
3 files changed, 39 insertions, 8 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 45e5ae8a9fb7..04a21fcb827e 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h | |||
@@ -461,6 +461,7 @@ struct e1000_info { | |||
461 | #define FLAG2_CHECK_PHY_HANG (1 << 9) | 461 | #define FLAG2_CHECK_PHY_HANG (1 << 9) |
462 | #define FLAG2_NO_DISABLE_RX (1 << 10) | 462 | #define FLAG2_NO_DISABLE_RX (1 << 10) |
463 | #define FLAG2_PCIM2PCI_ARBITER_WA (1 << 11) | 463 | #define FLAG2_PCIM2PCI_ARBITER_WA (1 << 11) |
464 | #define FLAG2_DFLT_CRC_STRIPPING (1 << 12) | ||
464 | 465 | ||
465 | #define E1000_RX_DESC_PS(R, i) \ | 466 | #define E1000_RX_DESC_PS(R, i) \ |
466 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) | 467 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index c079b9b0810d..30c8c15d0396 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -933,8 +933,16 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, | |||
933 | } | 933 | } |
934 | 934 | ||
935 | /* adjust length to remove Ethernet CRC */ | 935 | /* adjust length to remove Ethernet CRC */ |
936 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | 936 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) { |
937 | length -= 4; | 937 | /* If configured to store CRC, don't subtract FCS, |
938 | * but keep the FCS bytes out of the total_rx_bytes | ||
939 | * counter | ||
940 | */ | ||
941 | if (netdev->features & NETIF_F_RXFCS) | ||
942 | total_rx_bytes -= 4; | ||
943 | else | ||
944 | length -= 4; | ||
945 | } | ||
938 | 946 | ||
939 | total_rx_bytes += length; | 947 | total_rx_bytes += length; |
940 | total_rx_packets++; | 948 | total_rx_packets++; |
@@ -1301,8 +1309,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, | |||
1301 | DMA_FROM_DEVICE); | 1309 | DMA_FROM_DEVICE); |
1302 | 1310 | ||
1303 | /* remove the CRC */ | 1311 | /* remove the CRC */ |
1304 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | 1312 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) { |
1305 | l1 -= 4; | 1313 | if (!(netdev->features & NETIF_F_RXFCS)) |
1314 | l1 -= 4; | ||
1315 | } | ||
1306 | 1316 | ||
1307 | skb_put(skb, l1); | 1317 | skb_put(skb, l1); |
1308 | goto copydone; | 1318 | goto copydone; |
@@ -1328,8 +1338,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, | |||
1328 | /* strip the ethernet crc, problem is we're using pages now so | 1338 | /* strip the ethernet crc, problem is we're using pages now so |
1329 | * this whole operation can get a little cpu intensive | 1339 | * this whole operation can get a little cpu intensive |
1330 | */ | 1340 | */ |
1331 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | 1341 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) { |
1332 | pskb_trim(skb, skb->len - 4); | 1342 | if (!(netdev->features & NETIF_F_RXFCS)) |
1343 | pskb_trim(skb, skb->len - 4); | ||
1344 | } | ||
1333 | 1345 | ||
1334 | copydone: | 1346 | copydone: |
1335 | total_rx_bytes += skb->len; | 1347 | total_rx_bytes += skb->len; |
@@ -5982,7 +5994,7 @@ static int e1000_set_features(struct net_device *netdev, | |||
5982 | adapter->flags |= FLAG_TSO_FORCE; | 5994 | adapter->flags |= FLAG_TSO_FORCE; |
5983 | 5995 | ||
5984 | if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | | 5996 | if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | |
5985 | NETIF_F_RXCSUM | NETIF_F_RXHASH))) | 5997 | NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS))) |
5986 | return 0; | 5998 | return 0; |
5987 | 5999 | ||
5988 | /* | 6000 | /* |
@@ -5996,6 +6008,20 @@ static int e1000_set_features(struct net_device *netdev, | |||
5996 | return -EINVAL; | 6008 | return -EINVAL; |
5997 | } | 6009 | } |
5998 | 6010 | ||
6011 | if (changed & NETIF_F_RXFCS) { | ||
6012 | if (features & NETIF_F_RXFCS) { | ||
6013 | adapter->flags2 &= ~FLAG2_CRC_STRIPPING; | ||
6014 | } else { | ||
6015 | /* We need to take it back to defaults, which might mean | ||
6016 | * stripping is still disabled at the adapter level. | ||
6017 | */ | ||
6018 | if (adapter->flags2 & FLAG2_DFLT_CRC_STRIPPING) | ||
6019 | adapter->flags2 |= FLAG2_CRC_STRIPPING; | ||
6020 | else | ||
6021 | adapter->flags2 &= ~FLAG2_CRC_STRIPPING; | ||
6022 | } | ||
6023 | } | ||
6024 | |||
5999 | netdev->features = features; | 6025 | netdev->features = features; |
6000 | 6026 | ||
6001 | if (netif_running(netdev)) | 6027 | if (netif_running(netdev)) |
@@ -6194,6 +6220,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
6194 | 6220 | ||
6195 | /* Set user-changeable features (subset of all device features) */ | 6221 | /* Set user-changeable features (subset of all device features) */ |
6196 | netdev->hw_features = netdev->features; | 6222 | netdev->hw_features = netdev->features; |
6223 | netdev->hw_features |= NETIF_F_RXFCS; | ||
6197 | 6224 | ||
6198 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) | 6225 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) |
6199 | netdev->features |= NETIF_F_HW_VLAN_FILTER; | 6226 | netdev->features |= NETIF_F_HW_VLAN_FILTER; |
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 9c6a56d804a4..ff796e42c3eb 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c | |||
@@ -463,10 +463,13 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) | |||
463 | if (num_CrcStripping > bd) { | 463 | if (num_CrcStripping > bd) { |
464 | unsigned int crc_stripping = CrcStripping[bd]; | 464 | unsigned int crc_stripping = CrcStripping[bd]; |
465 | e1000_validate_option(&crc_stripping, &opt, adapter); | 465 | e1000_validate_option(&crc_stripping, &opt, adapter); |
466 | if (crc_stripping == OPTION_ENABLED) | 466 | if (crc_stripping == OPTION_ENABLED) { |
467 | adapter->flags2 |= FLAG2_CRC_STRIPPING; | 467 | adapter->flags2 |= FLAG2_CRC_STRIPPING; |
468 | adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING; | ||
469 | } | ||
468 | } else { | 470 | } else { |
469 | adapter->flags2 |= FLAG2_CRC_STRIPPING; | 471 | adapter->flags2 |= FLAG2_CRC_STRIPPING; |
472 | adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING; | ||
470 | } | 473 | } |
471 | } | 474 | } |
472 | { /* Kumeran Lock Loss Workaround */ | 475 | { /* Kumeran Lock Loss Workaround */ |