--- ../linux-2.6.26/drivers/net/via-velocity.c 2008-10-08 17:08:42.000000000 +0000 +++ drivers/net/via-velocity.c 2008-10-08 19:37:10.000000000 +0000 @@ -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;