Commit 0184039a authored by Ben Greear's avatar Ben Greear Committed by Jeff Kirsher

e1000e: Support RXFCS feature flag.

This enables enabling/disabling reception of the Ethernet
FCS.  This can be useful when sniffing packets.

For e1000e, enabling RXFCS can change the default
behaviour for how the NIC handles CRC.  Disabling RXFCS
will take the NIC back to defaults, which can be configured
as part of the module options.
Signed-off-by: default avatarBen Greear <greearb@candelatech.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 36eabda3
......@@ -461,6 +461,7 @@ struct e1000_info {
#define FLAG2_CHECK_PHY_HANG (1 << 9)
#define FLAG2_NO_DISABLE_RX (1 << 10)
#define FLAG2_PCIM2PCI_ARBITER_WA (1 << 11)
#define FLAG2_DFLT_CRC_STRIPPING (1 << 12)
#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
......
......@@ -933,8 +933,16 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
}
/* adjust length to remove Ethernet CRC */
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
length -= 4;
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
/* If configured to store CRC, don't subtract FCS,
* but keep the FCS bytes out of the total_rx_bytes
* counter
*/
if (netdev->features & NETIF_F_RXFCS)
total_rx_bytes -= 4;
else
length -= 4;
}
total_rx_bytes += length;
total_rx_packets++;
......@@ -1301,8 +1309,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
DMA_FROM_DEVICE);
/* remove the CRC */
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
l1 -= 4;
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
if (!(netdev->features & NETIF_F_RXFCS))
l1 -= 4;
}
skb_put(skb, l1);
goto copydone;
......@@ -1328,8 +1338,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
/* strip the ethernet crc, problem is we're using pages now so
* this whole operation can get a little cpu intensive
*/
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
pskb_trim(skb, skb->len - 4);
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
if (!(netdev->features & NETIF_F_RXFCS))
pskb_trim(skb, skb->len - 4);
}
copydone:
total_rx_bytes += skb->len;
......@@ -5982,7 +5994,7 @@ static int e1000_set_features(struct net_device *netdev,
adapter->flags |= FLAG_TSO_FORCE;
if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX |
NETIF_F_RXCSUM | NETIF_F_RXHASH)))
NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS)))
return 0;
/*
......@@ -5996,6 +6008,20 @@ static int e1000_set_features(struct net_device *netdev,
return -EINVAL;
}
if (changed & NETIF_F_RXFCS) {
if (features & NETIF_F_RXFCS) {
adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
} else {
/* We need to take it back to defaults, which might mean
* stripping is still disabled at the adapter level.
*/
if (adapter->flags2 & FLAG2_DFLT_CRC_STRIPPING)
adapter->flags2 |= FLAG2_CRC_STRIPPING;
else
adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
}
}
netdev->features = features;
if (netif_running(netdev))
......@@ -6194,6 +6220,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
/* Set user-changeable features (subset of all device features) */
netdev->hw_features = netdev->features;
netdev->hw_features |= NETIF_F_RXFCS;
if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
netdev->features |= NETIF_F_HW_VLAN_FILTER;
......
......@@ -463,10 +463,13 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
if (num_CrcStripping > bd) {
unsigned int crc_stripping = CrcStripping[bd];
e1000_validate_option(&crc_stripping, &opt, adapter);
if (crc_stripping == OPTION_ENABLED)
if (crc_stripping == OPTION_ENABLED) {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
}
} else {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
adapter->flags2 |= FLAG2_DFLT_CRC_STRIPPING;
}
}
{ /* Kumeran Lock Loss Workaround */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment