aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c41
-rw-r--r--drivers/net/ethernet/intel/e1000e/param.c5
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
1334copydone: 1346copydone:
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 */