ixgbe: Support RX-ALL feature flag.
authorBen Greear <greearb@candelatech.com>
Thu, 8 Mar 2012 08:28:41 +0000 (08:28 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 17 Mar 2012 08:03:22 +0000 (01:03 -0700)
This allows the NIC to receive all frames available, including
those with bad FCS, ethernet control frames, and more.

Tested by sending frames with bad FCS.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

index 986897bf2b8304f63b90342cdc78f9ef50a36469..cae763c57dc7b8203b4b368561f237741962ac5c 100644 (file)
@@ -1482,8 +1482,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
        struct sk_buff *skb;
        unsigned int total_rx_bytes = 0, total_rx_packets = 0;
        const int current_node = numa_node_id();
-#ifdef IXGBE_FCOE
        struct ixgbe_adapter *adapter = q_vector->adapter;
+#ifdef IXGBE_FCOE
        int ddp_bytes = 0;
 #endif /* IXGBE_FCOE */
        u16 i;
@@ -1612,7 +1612,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 
                /* ERR_MASK will only have valid bits if EOP set */
                if (unlikely(ixgbe_test_staterr(rx_desc,
-                                           IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) {
+                                           IXGBE_RXDADV_ERR_FRAME_ERR_MASK) &&
+                   !(adapter->netdev->features & NETIF_F_RXALL))) {
                        dev_kfree_skb_any(skb);
                        goto next_desc;
                }
@@ -3342,6 +3343,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
        fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
 
        /* set all bits that we expect to always be set */
+       fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
        fctrl |= IXGBE_FCTRL_BAM;
        fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
        fctrl |= IXGBE_FCTRL_PMCF;
@@ -3390,6 +3392,18 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
                IXGBE_WRITE_REG(hw, IXGBE_VMOLR(adapter->num_vfs), vmolr);
        }
 
+       /* 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 */
+               fctrl |= (IXGBE_FCTRL_SBP | /* Receive bad packets */
+                         IXGBE_FCTRL_BAM | /* RX All Bcast Pkts */
+                         IXGBE_FCTRL_PMCF); /* RX All MAC Ctrl Pkts */
+
+               fctrl &= ~(IXGBE_FCTRL_DPF);
+               /* NOTE:  VLAN filtering is disabled by setting PROMISC */
+       }
+
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
 
        if (netdev->features & NETIF_F_HW_VLAN_RX)
@@ -7459,6 +7473,7 @@ static int ixgbe_set_features(struct net_device *netdev,
        netdev_features_t data)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       netdev_features_t changed = netdev->features ^ data;
        bool need_reset = false;
 
        /* Make sure RSC matches LRO, reset if change */
@@ -7495,6 +7510,10 @@ static int ixgbe_set_features(struct net_device *netdev,
                need_reset = true;
        }
 
+       if (changed & NETIF_F_RXALL)
+               need_reset = true;
+
+       netdev->features = data;
        if (need_reset)
                ixgbe_do_reset(netdev);
 
@@ -7773,6 +7792,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                break;
        }
 
+       netdev->hw_features |= NETIF_F_RXALL;
+
        netdev->vlan_features |= NETIF_F_TSO;
        netdev->vlan_features |= NETIF_F_TSO6;
        netdev->vlan_features |= NETIF_F_IP_CSUM;