Some hardware set promisc when they are requested to set IFF_ALLMULTI flag.
It's ok, but if drivers set IFF_PROMISC flag when they set promisc,
it will broken upper layer handle for promisc and allmulti.
In addition, drivers can use their own hardware programming to make it.
So do not allow drivers to set IFF_* flags.
This is a general driver fix, so I didn't split it to pieces and send
to specific driver maintainers.
Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
cfg_cmd->time_low = 0x00;
cfg_cmd->time_high = 0xf2;
cfg_cmd->promisc = 0;
- if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC))
cfg_cmd->promisc = 1;
- dev->flags |= IFF_PROMISC;
- }
cfg_cmd->carr_coll = 0x00;
p->scb->cbl_offset = make16(cfg_cmd);
struct mc32_local *lp = netdev_priv(dev);
u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */
- if (dev->flags&IFF_PROMISC)
+ if ((dev->flags&IFF_PROMISC) ||
+ (dev->flags&IFF_ALLMULTI) ||
+ dev->mc_count > 10)
/* Enable promiscuous mode */
filt |= 1;
- else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
- {
- dev->flags|=IFF_PROMISC;
- filt |= 1;
- }
else if(dev->mc_count)
{
unsigned char block[62];
struct net_local *lp = netdev_priv(dev);
long ioaddr = dev->base_addr;
- if ( dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC))) {
- /* We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- dev->flags|=IFF_PROMISC;
+ if (dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
lp->addr_mode = CMR2h_PROMISC;
- } else
+ else
lp->addr_mode = CMR2h_Normal;
write_reg_high(ioaddr, CMR2, lp->addr_mode);
}
{
if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
{ /* Enable promiscuous mode */
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- dev->flags|=IFF_PROMISC;
-
de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
}
else
if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
{
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. If it was a promisc request the
- * flag is already set. If not we assert it.
- */
- dev->flags|=IFF_PROMISC;
-
eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
mode = inb(ioaddr + REG2);
outb(mode | PRMSC_Mode, ioaddr + REG2);
if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
{
- dev->flags|=IFF_PROMISC; /* Must do this */
outb(3, ioaddr + RECEIVE_MODE_REG);
} else {
outb(2, ioaddr + RECEIVE_MODE_REG);
return;
}
if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
- if (dev->flags & IFF_ALLMULTI)
- dev->flags |= IFF_PROMISC;
lp->i596_config[8] &= ~0x01;
} else {
lp->i596_config[8] |= 0x01;
PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) {
- dev->flags |= IFF_PROMISC;
outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
} else {
if (num_addrs > len) {
printk(KERN_ERR "%s: switching to promisc. mode\n",
dev->name);
- dev->flags |= IFF_PROMISC;
+ writeb(0x01, &cfg_cmd->promisc);
}
}
if (dev->flags & IFF_PROMISC)
int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
if(num_addrs > len) {
printk("%s: switching to promisc. mode\n",dev->name);
- dev->flags|=IFF_PROMISC;
+ cfg_cmd->promisc = 1;
}
}
if(dev->flags&IFF_PROMISC)
- {
- cfg_cmd->promisc=1;
- dev->flags|=IFF_PROMISC;
- }
+ cfg_cmd->promisc = 1;
cfg_cmd->carr_coll = 0x00;
p->scb->cbl_offset = make16(cfg_cmd);
else
priv->mc_count = mc_count;
}
-
- /* Since we can set the promiscuous flag when it wasn't asked
- for, make sure the net_device knows about it. */
- if (priv->promiscuous)
- dev->flags |= IFF_PROMISC;
- else
- dev->flags &= ~IFF_PROMISC;
}
/* This must be called from user context, without locks held - use
lp->mc_count = 0;
wv_82586_reconfig(dev);
-
- /* Tell the kernel that we are doing a really bad job. */
- dev->flags |= IFF_PROMISC;
}
} else
/* Are there multicast addresses to send? */
lp->mc_count = 0;
wv_82593_reconfig(dev);
-
- /* Tell the kernel that we are doing a really bad job... */
- dev->flags |= IFF_PROMISC;
}
}
else
lp->mc_count = 0;
wv_82593_reconfig(dev);
-
- /* Tell the kernel that we are doing a really bad job... */
- dev->flags |= IFF_ALLMULTI;
}
}
else