|
@@ -1845,29 +1845,19 @@ static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
|
|
|
struct netdev_hw_addr *ha;
|
|
|
int i;
|
|
|
|
|
|
- if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
|
|
|
- int port_num;
|
|
|
- u32 accept;
|
|
|
+ if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI))
|
|
|
+ goto promiscuous;
|
|
|
|
|
|
-oom:
|
|
|
- port_num = mp->port_num;
|
|
|
- accept = 0x01010101;
|
|
|
- for (i = 0; i < 0x100; i += 4) {
|
|
|
- wrl(mp, SPECIAL_MCAST_TABLE(port_num) + i, accept);
|
|
|
- wrl(mp, OTHER_MCAST_TABLE(port_num) + i, accept);
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- mc_spec = kzalloc(0x200, GFP_ATOMIC);
|
|
|
- if (mc_spec == NULL)
|
|
|
- goto oom;
|
|
|
- mc_other = mc_spec + (0x100 >> 2);
|
|
|
+ /* Allocate both mc_spec and mc_other tables */
|
|
|
+ mc_spec = kcalloc(128, sizeof(u32), GFP_ATOMIC);
|
|
|
+ if (!mc_spec)
|
|
|
+ goto promiscuous;
|
|
|
+ mc_other = &mc_spec[64];
|
|
|
|
|
|
netdev_for_each_mc_addr(ha, dev) {
|
|
|
u8 *a = ha->addr;
|
|
|
u32 *table;
|
|
|
- int entry;
|
|
|
+ u8 entry;
|
|
|
|
|
|
if (memcmp(a, "\x01\x00\x5e\x00\x00", 5) == 0) {
|
|
|
table = mc_spec;
|
|
@@ -1880,12 +1870,23 @@ oom:
|
|
|
table[entry >> 2] |= 1 << (8 * (entry & 3));
|
|
|
}
|
|
|
|
|
|
- for (i = 0; i < 0x100; i += 4) {
|
|
|
- wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i, mc_spec[i >> 2]);
|
|
|
- wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i, mc_other[i >> 2]);
|
|
|
+ for (i = 0; i < 64; i++) {
|
|
|
+ wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i * sizeof(u32),
|
|
|
+ mc_spec[i]);
|
|
|
+ wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i * sizeof(u32),
|
|
|
+ mc_other[i]);
|
|
|
}
|
|
|
|
|
|
kfree(mc_spec);
|
|
|
+ return;
|
|
|
+
|
|
|
+promiscuous:
|
|
|
+ for (i = 0; i < 64; i++) {
|
|
|
+ wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i * sizeof(u32),
|
|
|
+ 0x01010101u);
|
|
|
+ wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i * sizeof(u32),
|
|
|
+ 0x01010101u);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void mv643xx_eth_set_rx_mode(struct net_device *dev)
|