rk29xx vmac: update function create_multicast_filter and vmac_set_multicast_list
authorlyx <lyx@rock-chips.com>
Wed, 15 Dec 2010 08:18:39 +0000 (00:18 -0800)
committerlyx <lyx@rock-chips.com>
Wed, 15 Dec 2010 08:19:08 +0000 (00:19 -0800)
drivers/net/rk29_vmac.c

index 097dc6f1666d42f87df91323b7bc49fe6772b84e..a1b5df3315d22d9016643be34c7dabd65fa70815 100755 (executable)
@@ -1225,7 +1225,29 @@ static void create_multicast_filter(struct net_device *dev,
        unsigned long *bitmask)\r
 {\r
 #if 1\r
+       struct netdev_hw_addr *ha;\r
+       unsigned long crc;\r
+       char *addrs;\r
+       struct netdev_hw_addr_list *list = &dev->dev_addrs;\r
+       \r
        printk("-----------------func %s-------------------\n", __func__);\r
+\r
+       WARN_ON(dev->mc_count == 0);\r
+       WARN_ON(dev->flags & IFF_ALLMULTI);\r
+\r
+       bitmask[0] = bitmask[1] = 0;\r
+\r
+       list_for_each_entry(ha, &list->list, list) {\r
+               addrs = ha->addr;\r
+\r
+               /* skip non-multicast addresses */\r
+               if (!(*addrs & 1))\r
+                       continue;\r
+\r
+               crc = ether_crc_le(ETH_ALEN, addrs);\r
+               set_bit(crc >> 26, bitmask);\r
+               \r
+       }\r
 #else\r
        struct netdev_hw_addr *ha;\r
        unsigned long crc;\r
@@ -1251,7 +1273,32 @@ static void create_multicast_filter(struct net_device *dev,
 static void vmac_set_multicast_list(struct net_device *dev)\r
 {\r
 #if 1\r
+       struct vmac_priv *ap = netdev_priv(dev);\r
+       unsigned long flags, bitmask[2];\r
+       int promisc, reg;\r
+\r
        printk("-----------------func %s-------------------\n", __func__);\r
+\r
+       spin_lock_irqsave(&ap->lock, flags);\r
+\r
+       promisc = !!(dev->flags & IFF_PROMISC);\r
+       reg = vmac_readl(ap, ENABLE);\r
+       if (promisc != !!(reg & PROM_MASK)) {\r
+               reg ^= PROM_MASK;\r
+               vmac_writel(ap, reg, ENABLE);\r
+       }\r
+\r
+       if (dev->flags & IFF_ALLMULTI)\r
+               memset(bitmask, 1, sizeof(bitmask));\r
+       else if (dev->mc_count == 0)\r
+               memset(bitmask, 0, sizeof(bitmask));\r
+       else\r
+               create_multicast_filter(dev, bitmask);\r
+\r
+       vmac_writel(ap, bitmask[0], LAFL);\r
+       vmac_writel(ap, bitmask[1], LAFH);\r
+\r
+       spin_unlock_irqrestore(&ap->lock, flags);\r
 #else\r
        struct vmac_priv *ap = netdev_priv(dev);\r
        unsigned long flags, bitmask[2];\r
@@ -1295,7 +1342,7 @@ static const struct net_device_ops vmac_netdev_ops = {
        .ndo_do_ioctl           = vmac_ioctl,\r
        .ndo_set_mac_address    = eth_mac_addr,\r
        .ndo_tx_timeout         = vmac_tx_timeout,\r
-       //.ndo_set_multicast_list = vmac_set_multicast_list,\r
+       .ndo_set_multicast_list = vmac_set_multicast_list,\r
        .ndo_validate_addr      = eth_validate_addr,\r
        .ndo_change_mtu         = eth_change_mtu,\r
 };\r