@@ -605,9 +605,8 @@ static void __devinit velocity_get_optio
static void velocity_init_cam_filter(struct velocity_info *vptr)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
-
/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
- WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG);
+ WORD_REG_BITS_ON(MCFG_PQEN, ®s->MCFG);
WORD_REG_BITS_ON(MCFG_VIDFR, ®s->MCFG);
/* Disable all CAMs */
@@ -619,11 +618,7 @@ static void velocity_init_cam_filter(str
/* Enable VCAMs */
if (vptr->vlgrp) {
unsigned int vid, i = 0;
-
- if (!vlan_group_get_device(vptr->vlgrp, 0))
- WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG);
-
- for (vid = 1; (vid < VLAN_VID_MASK); vid++) {
+ for (vid = 0; (vid < VLAN_VID_MASK); vid++) {
if (vlan_group_get_device(vptr->vlgrp, vid)) {
mac_set_vlan_cam(regs, i, (u8 *) &vid);
vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
@@ -646,19 +641,25 @@ static void velocity_vlan_rx_register(st
static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
{
struct velocity_info *vptr = netdev_priv(dev);
+ struct mac_regs __iomem * regs = vptr->mac_regs;
spin_lock_irq(&vptr->lock);
velocity_init_cam_filter(vptr);
+ if (vptr->vCAMmask[0] && !(dev->flags & IFF_PROMISC))
+ WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); /* enable vlan filtering */
spin_unlock_irq(&vptr->lock);
}
static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
struct velocity_info *vptr = netdev_priv(dev);
+ struct mac_regs __iomem * regs = vptr->mac_regs;
spin_lock_irq(&vptr->lock);
vlan_group_set_device(vptr->vlgrp, vid, NULL);
velocity_init_cam_filter(vptr);
+ if (!vptr->vCAMmask[0])
+ WORD_REG_BITS_OFF(MCFG_RTGOPT, ®s->MCFG); /* disable vlan filtering */
spin_unlock_irq(&vptr->lock);
}
@@ -2278,11 +2279,14 @@ static void velocity_set_multi(struct ne
writel(0xffffffff, ®s->MARCAM[0]);
writel(0xffffffff, ®s->MARCAM[4]);
rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
+ WORD_REG_BITS_OFF(MCFG_RTGOPT, ®s->MCFG); /* disable vlan filtering */
} else if ((dev->mc_count > vptr->multicast_limit)
|| (dev->flags & IFF_ALLMULTI)) {
writel(0xffffffff, ®s->MARCAM[0]);
writel(0xffffffff, ®s->MARCAM[4]);
rx_mode = (RCR_AM | RCR_AB);
+ if (vptr->vCAMmask[0])
+ WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); /* enable vlan filtering */
} else {
int offset = MCAM_SIZE - vptr->multicast_limit;
mac_get_cam_mask(regs, vptr->mCAMmask);
@@ -2294,6 +2298,9 @@ static void velocity_set_multi(struct ne
mac_set_cam_mask(regs, vptr->mCAMmask);
rx_mode = (RCR_AM | RCR_AB);
+
+ if (vptr->vCAMmask[0])
+ WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); /* enable vlan filtering */
}
if (dev->mtu > 1500)
rx_mode |= RCR_AL;