]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
e1000e: Support RXALL feature flag.
authorBen Greear <greearb@candelatech.com>
Sat, 11 Feb 2012 15:39:51 +0000 (15:39 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 24 Feb 2012 09:44:50 +0000 (01:44 -0800)
This allows the NIC to receive all frames available, including
those with bad FCS, un-matched vlans, ethernet control frames,
and more.

Tested by sending frames with bad FCS.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/e1000e/defines.h
drivers/net/ethernet/intel/e1000e/netdev.c

index 1af30b967a4fcd588ba9b62492157c10b6d100db..3a50259171630a643e2818f56174714a6bf1ff62 100644 (file)
 #define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
 #define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
 #define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
+#define E1000_RCTL_DPF            0x00400000    /* Discard Pause Frames */
 #define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
 #define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
 #define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
index 340442c4f38151f303c0afe8538dd0a719e1ae92..c30e99ee66c66256d5735dad7344c220c5ebc62a 100644 (file)
@@ -926,7 +926,8 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
                        goto next_desc;
                }
 
-               if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
+               if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
+                            !(netdev->features & NETIF_F_RXALL))) {
                        /* recycle */
                        buffer_info->skb = skb;
                        goto next_desc;
@@ -1255,7 +1256,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
                        goto next_desc;
                }
 
-               if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
+               if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
+                            !(netdev->features & NETIF_F_RXALL))) {
                        dev_kfree_skb_irq(skb);
                        goto next_desc;
                }
@@ -1454,7 +1456,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
 
                /* errors is only valid for DD + EOP descriptors */
                if (unlikely((staterr & E1000_RXD_STAT_EOP) &&
-                            (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK))) {
+                            ((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
+                             !(netdev->features & NETIF_F_RXALL)))) {
                        /* recycle both page and skb */
                        buffer_info->skb = skb;
                        /* an error means any chain goes out the window too */
@@ -2997,6 +3000,22 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                ew32(PSRCTL, psrctl);
        }
 
+       /* 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(RFCTL, rfctl);
        ew32(RCTL, rctl);
        /* just started the receive unit, no need to restart */
@@ -6005,7 +6024,8 @@ 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_RXFCS)))
+                        NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS |
+                        NETIF_F_RXALL)))
                return 0;
 
        /*
@@ -6233,6 +6253,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        netdev->hw_features = netdev->features;
        netdev->hw_features |= NETIF_F_RXFCS;
        netdev->priv_flags |= IFF_SUPP_NOFCS;
+       netdev->hw_features |= NETIF_F_RXALL;
 
        if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
                netdev->features |= NETIF_F_HW_VLAN_FILTER;