]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net: introduce IFF_UNICAST_FLT private flag
authorJoe Jin <joe.jin@oracle.com>
Thu, 17 May 2012 06:16:29 +0000 (14:16 +0800)
committerJoe Jin <joe.jin@oracle.com>
Thu, 17 May 2012 06:31:11 +0000 (14:31 +0800)
Use IFF_UNICAST_FTL to find out if driver handles unicast address
filtering. In case it does not, promisc mode is entered.

Patch also fixes following drivers:
stmmac, niu: support uc filtering and yet it propagated
ndo_set_multicast_list
bna, benet, pxa168_eth, ks8851, ks8851_mll, ksz884x : has set
ndo_set_rx_mode but do not support uc filtering

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(backported from commit 01789349ee52e4a3faf376f1485303d9723c4f1f)

Signed-off-by: Joe Jin <joe.jin@oracle.com>
17 files changed:
drivers/net/bnx2.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/cxgb4/cxgb4_main.c
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/e1000/e1000_main.c
drivers/net/enic/enic_main.c
drivers/net/igb/igb_main.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbevf/ixgbevf_main.c
drivers/net/mv643xx_eth.c
drivers/net/niu.c
drivers/net/octeon/octeon_mgmt.c
drivers/net/stmmac/stmmac_main.c
drivers/net/virtio_net.c
include/linux/if.h
include/linux/netdevice.h
net/core/dev.c

index b217be8b212351fa8d4f3c4a02963a34ae0f2c3a..85aa6751d263e47891d9498855e532c2e5f43849 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/time.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <net/tcp.h>
@@ -8467,6 +8468,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->vlan_features = dev->hw_features;
        dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
        dev->features |= dev->hw_features;
+       dev->priv_flags |= IFF_UNICAST_FLT;
 
        if ((rc = register_netdev(dev))) {
                dev_err(&pdev->dev, "Cannot register net device\n");
index 02991f7fce92048086aa80bcd00fb126da0ff9ca..d789f63e8938680b5db2d99649758afcdba90a75 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/time.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -10709,6 +10710,8 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
        dev->netdev_ops = &bnx2x_netdev_ops;
        bnx2x_set_ethtool_ops(dev);
 
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
                NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_LRO |
                NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_HW_VLAN_TX;
index c9957b7f17b57f0d746bbf2987684b49c7ce3ba3..90b4921cac9b432ac0b414692f698ca192f17aa0 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/err.h>
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/init.h>
 #include <linux/log2.h>
@@ -3639,6 +3640,8 @@ static int __devinit init_one(struct pci_dev *pdev,
                netdev->features |= netdev->hw_features | highdma;
                netdev->vlan_features = netdev->features & VLAN_FEAT;
 
+               netdev->priv_flags |= IFF_UNICAST_FLT;
+
                netdev->netdev_ops = &cxgb4_netdev_ops;
                SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
        }
index e71c08e547e4aa789eced9428244ad68c01b5fa4..60bae0256a3b63476b90d0106d4fa7d707692097 100644 (file)
@@ -2612,6 +2612,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
                if (pci_using_dac)
                        netdev->features |= NETIF_F_HIGHDMA;
 
+               netdev->priv_flags |= IFF_UNICAST_FLT;
 #ifdef HAVE_NET_DEVICE_OPS
                netdev->netdev_ops = &cxgb4vf_netdev_ops;
 #else
index 02da62fbfe6b022ec996febc7ca369ea9d78605b..ef9494b94b94a51381e4c16662236a189eec98a0 100644 (file)
@@ -1078,6 +1078,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        netdev->vlan_features |= NETIF_F_HW_CSUM;
        netdev->vlan_features |= NETIF_F_SG;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
 
        /* initialize eeprom parameters */
index 4c1d22159e130d67d6f6b0aaa78ba957f6db5ce2..f8faa2eb9c3f165159900ea76c9538369b18cdc3 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/ethtool.h>
@@ -2441,6 +2442,8 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        if (using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        err = register_netdev(netdev);
        if (err) {
                dev_err(dev, "Cannot register net device, aborting\n");
index 7421803d2401fdf079f9e677a0c5c82fed1da750..5a06e0386f2255f1e32cf3179eb7cb3d4d6df3f9 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/net_tstamp.h>
 #include <linux/mii.h>
 #include <linux/ethtool.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
@@ -1936,6 +1937,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        if (hw->mac.type >= e1000_82576)
                netdev->features |= NETIF_F_SCTP_CSUM;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        adapter->en_mng_pt = igb_enable_mng_pass_thru(hw);
 
        /* before reading the NVM, reset the controller to put the device in a
index f915412dd50c5288ad5b17d7d09415296280ec1b..1792f479912ca74b0bb412629553757434e34934 100644 (file)
@@ -41,6 +41,7 @@
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 #include <scsi/fc/fc_fcoe.h>
@@ -7585,6 +7586,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        netdev->vlan_features |= NETIF_F_IPV6_CSUM;
        netdev->vlan_features |= NETIF_F_SG;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
                adapter->flags &= ~(IXGBE_FLAG_RSS_ENABLED |
                                    IXGBE_FLAG_DCB_ENABLED);
index 3b880a27f8d118eb6b08fcd5e23678bdf2c27653..45b007827024291377e1fa032b9c7c874becc7c5 100644 (file)
@@ -44,6 +44,7 @@
 #include <net/checksum.h>
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 
@@ -3358,6 +3359,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        /* The HW MAC address was set and/or determined in sw_init */
        memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
        memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
index a5d9b1c310b38beb48f27b3828384be3e032a006..9ad378ed31321d23036d0ad9cd2d3e8348c6b99d 100644 (file)
@@ -2919,6 +2919,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
        dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
 
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        if (mp->shared->win_protect)
index f051b9b632715873a5f288bdecf9979fcf677118..f1b3ddfbe9437a698739ccfeb07239bc0f4f843c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/bitops.h>
 #include <linux/mii.h>
+#include <linux/if.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
@@ -9700,7 +9701,7 @@ static const struct net_device_ops niu_netdev_ops = {
        .ndo_stop               = niu_close,
        .ndo_start_xmit         = niu_start_xmit,
        .ndo_get_stats          = niu_get_stats,
-       .ndo_set_multicast_list = niu_set_rx_mode,
+       .ndo_set_rx_mode        = niu_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = niu_set_mac_addr,
        .ndo_do_ioctl           = niu_ioctl,
@@ -9836,6 +9837,8 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev,
 
        niu_set_basic_features(dev);
 
+       dev->priv_flags |= IFF_UNICAST_FLT;
+
        np->regs = pci_ioremap_bar(pdev, 0);
        if (!np->regs) {
                dev_err(&pdev->dev, "Cannot map device registers, aborting\n");
index b264f0f45605409b6cd378bb5b498b23bd73f994..7ff794ef43af3c1b9cc64f1bc134b91c094ee881 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/platform_device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/slab.h>
 #include <linux/phy.h>
@@ -1101,6 +1102,8 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
        tasklet_init(&p->tx_clean_tasklet,
                     octeon_mgmt_clean_tx_tasklet, (unsigned long)p);
 
+       netdev->priv_flags |= IFF_UNICAST_FLT;
+
        netdev->netdev_ops = &octeon_mgmt_ops;
        netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
 
index e25e44a45c28b5580fc266d33fa599ca2a8a7db6..8e3a24e19df16cfe4ba9e26a16f92b46bc5c3abb 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/crc32.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/if.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
@@ -1281,7 +1282,7 @@ static int stmmac_config(struct net_device *dev, struct ifmap *map)
 }
 
 /**
- *  stmmac_multicast_list - entry point for multicast addressing
+ *  stmmac_set_rx_mode - entry point for multicast addressing
  *  @dev : pointer to the device structure
  *  Description:
  *  This function is a driver entry point which gets called by the kernel
@@ -1289,7 +1290,7 @@ static int stmmac_config(struct net_device *dev, struct ifmap *map)
  *  Return value:
  *  void.
  */
-static void stmmac_multicast_list(struct net_device *dev)
+static void stmmac_set_rx_mode(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
 
@@ -1432,7 +1433,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
        .ndo_stop = stmmac_release,
        .ndo_change_mtu = stmmac_change_mtu,
        .ndo_fix_features = stmmac_fix_features,
-       .ndo_set_multicast_list = stmmac_multicast_list,
+       .ndo_set_rx_mode = stmmac_set_rx_mode,
        .ndo_tx_timeout = stmmac_tx_timeout,
        .ndo_do_ioctl = stmmac_ioctl,
        .ndo_set_config = stmmac_config,
@@ -1512,10 +1513,12 @@ static int stmmac_mac_device_setup(struct net_device *dev)
 
        struct mac_device_info *device;
 
-       if (priv->plat->has_gmac)
+       if (priv->plat->has_gmac) {
+               dev->priv_flags |= IFF_UNICAST_FLT;
                device = dwmac1000_setup(priv->ioaddr);
-       else
+       } else {
                device = dwmac100_setup(priv->ioaddr);
+       }
 
        if (!device)
                return -ENOMEM;
index f6853247a620046a12e9dab53c9e4f3adcf4d2b2..b3263740972be9fda8b3fdfa3866d919af79066d 100644 (file)
@@ -891,6 +891,7 @@ static int virtnet_probe(struct virtio_device *vdev)
                return -ENOMEM;
 
        /* Set up network device as normal. */
+       dev->priv_flags |= IFF_UNICAST_FLT;
        dev->netdev_ops = &virtnet_netdev;
        dev->features = NETIF_F_HIGHDMA;
        SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops);
index 03489ca92ded4e1f901af97a76e0ca042297cdd0..db20bd4fd16b9189534a0cc15aa6335925cd3ace 100644 (file)
@@ -78,6 +78,7 @@
                                         * datapath port */
 #define IFF_TX_SKB_SHARING     0x10000 /* The interface supports sharing
                                         * skbs on transmit */
+#define IFF_UNICAST_FLT        0x20000         /* Supports unicast filtering   */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
index f19686d7bb6f9bff81be24777ff10d08c31576a9..6d6d03f6c517fadf0adc4b70a7bc8863080f9367 100644 (file)
@@ -749,6 +749,8 @@ struct netdev_tc_txq {
  *
  * void (*ndo_set_rx_mode)(struct net_device *dev);
  *     This function is called device changes address list filtering.
+ *     If driver handles unicast address filtering, it should set
+ *     IFF_UNICAST_FLT to its priv_flags.
  *
  * void (*ndo_set_multicast_list)(struct net_device *dev);
  *     This function is called when the multicast address list changes.
index 226ee7fd150ad7ba5fd51c05adfdc0a8461a0924..72c7201f3d4383042e0213c3f490d57d366a6412 100644 (file)
@@ -4479,9 +4479,7 @@ void __dev_set_rx_mode(struct net_device *dev)
        if (!netif_device_present(dev))
                return;
 
-       if (ops->ndo_set_rx_mode)
-               ops->ndo_set_rx_mode(dev);
-       else {
+       if (!(dev->priv_flags & IFF_UNICAST_FLT)) {
                /* Unicast addresses changes may only happen under the rtnl,
                 * therefore calling __dev_set_promiscuity here is safe.
                 */
@@ -4492,10 +4490,12 @@ void __dev_set_rx_mode(struct net_device *dev)
                        __dev_set_promiscuity(dev, -1);
                        dev->uc_promisc = 0;
                }
-
-               if (ops->ndo_set_multicast_list)
-                       ops->ndo_set_multicast_list(dev);
        }
+
+       if (ops->ndo_set_rx_mode)
+               ops->ndo_set_rx_mode(dev);
+       else if (ops->ndo_set_multicast_list)
+               ops->ndo_set_multicast_list(dev);
 }
 
 void dev_set_rx_mode(struct net_device *dev)