Commit e825b731 authored by Ben Greear's avatar Ben Greear Committed by Jeff Kirsher

e1000: Support RX-ALL flag.

This allows the NIC to receive errored frames (bad FCS, etc)
and pass them up the stack.  This can be useful when using
sniffers.
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 68df25d6
...@@ -827,9 +827,10 @@ static int e1000_set_features(struct net_device *netdev, ...@@ -827,9 +827,10 @@ static int e1000_set_features(struct net_device *netdev,
if (changed & NETIF_F_HW_VLAN_RX) if (changed & NETIF_F_HW_VLAN_RX)
e1000_vlan_mode(netdev, features); e1000_vlan_mode(netdev, features);
if (!(changed & NETIF_F_RXCSUM)) if (!(changed & (NETIF_F_RXCSUM | NETIF_F_RXALL)))
return 0; return 0;
netdev->features = features;
adapter->rx_csum = !!(features & NETIF_F_RXCSUM); adapter->rx_csum = !!(features & NETIF_F_RXCSUM);
if (netif_running(netdev)) if (netif_running(netdev))
...@@ -1074,6 +1075,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, ...@@ -1074,6 +1075,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
netdev->features |= netdev->hw_features; netdev->features |= netdev->hw_features;
netdev->hw_features |= NETIF_F_RXCSUM; netdev->hw_features |= NETIF_F_RXCSUM;
netdev->hw_features |= NETIF_F_RXALL;
netdev->hw_features |= NETIF_F_RXFCS; netdev->hw_features |= NETIF_F_RXFCS;
if (pci_using_dac) { if (pci_using_dac) {
...@@ -1841,6 +1843,22 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) ...@@ -1841,6 +1843,22 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
break; break;
} }
/* This is useful for sniffing bad packets. */
if (adapter->netdev->features & NETIF_F_RXALL) {
/* UPE and MPE will be handled by normal PROMISC logic
* in e1000e_set_rx_mode */
rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
E1000_RCTL_BAM | /* RX All Bcast Pkts */
E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
E1000_RCTL_DPF | /* Allow filtered pause */
E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
* and that breaks VLANs.
*/
}
ew32(RCTL, rctl); ew32(RCTL, rctl);
} }
...@@ -4057,6 +4075,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, ...@@ -4057,6 +4075,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
irq_flags); irq_flags);
length--; length--;
} else { } else {
if (netdev->features & NETIF_F_RXALL)
goto process_skb;
/* recycle both page and skb */ /* recycle both page and skb */
buffer_info->skb = skb; buffer_info->skb = skb;
/* an error means any chain goes out the window /* an error means any chain goes out the window
...@@ -4069,6 +4089,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, ...@@ -4069,6 +4089,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
} }
#define rxtop rx_ring->rx_skb_top #define rxtop rx_ring->rx_skb_top
process_skb:
if (!(status & E1000_RXD_STAT_EOP)) { if (!(status & E1000_RXD_STAT_EOP)) {
/* this descriptor is only the beginning (or middle) */ /* this descriptor is only the beginning (or middle) */
if (!rxtop) { if (!rxtop) {
...@@ -4276,12 +4297,15 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, ...@@ -4276,12 +4297,15 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
flags); flags);
length--; length--;
} else { } else {
if (netdev->features & NETIF_F_RXALL)
goto process_skb;
/* recycle */ /* recycle */
buffer_info->skb = skb; buffer_info->skb = skb;
goto next_desc; goto next_desc;
} }
} }
process_skb:
total_rx_bytes += (length - 4); /* don't count FCS */ total_rx_bytes += (length - 4); /* don't count FCS */
total_rx_packets++; total_rx_packets++;
......
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