aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/via-velocity.c
diff options
context:
space:
mode:
authorFrancois Romieu <romieu@fr.zoreil.com>2008-04-24 17:32:33 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-25 02:45:23 -0400
commitd4f73c8e459d355e10051174d859ffd0ef5764c0 (patch)
treed41fba7b3878b8ac39fece05ae5818e6e1932ddd /drivers/net/via-velocity.c
parent9f3f7910c67adfb520bbae3d8b16985439a97198 (diff)
via-velocity: fix vlan receipt
- vlans were using a single CAM register (see mac_set_vlan_cam) - setting the address filtering registers for vlans is not needed when there is no vlan The non-tagged interface is filtered out as soon as a tagged (!= 0) interface is created. Its traffic appears again when an zero-tagged interface is created. Tested on Via Epia SN (VT6130 chipset) with several vlans whose tag was above or beyond 255. Signed-off-by: Séguier Régis <rseguier@e-teleport.net> Acked-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/via-velocity.c')
-rw-r--r--drivers/net/via-velocity.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index ed1afaf683a4..6b8d882d197b 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -605,7 +605,6 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
605static void velocity_init_cam_filter(struct velocity_info *vptr) 605static void velocity_init_cam_filter(struct velocity_info *vptr)
606{ 606{
607 struct mac_regs __iomem * regs = vptr->mac_regs; 607 struct mac_regs __iomem * regs = vptr->mac_regs;
608 unsigned short vid;
609 608
610 /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ 609 /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
611 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG); 610 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
@@ -617,29 +616,33 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
617 mac_set_vlan_cam_mask(regs, vptr->vCAMmask); 616 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
618 mac_set_cam_mask(regs, vptr->mCAMmask); 617 mac_set_cam_mask(regs, vptr->mCAMmask);
619 618
620 /* Enable first VCAM */ 619 /* Enable VCAMs */
621 if (vptr->vlgrp) { 620 if (vptr->vlgrp) {
622 for (vid = 0; vid < VLAN_VID_MASK; vid++) { 621 unsigned int vid, i = 0;
623 if (vlan_group_get_device(vptr->vlgrp, vid)) { 622
624 /* If Tagging option is enabled and 623 if (!vlan_group_get_device(vptr->vlgrp, 0))
625 VLAN ID is not zero, then 624 WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
626 turn on MCFG_RTGOPT also */
627 if (vid != 0)
628 WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
629 625
630 mac_set_vlan_cam(regs, 0, (u8 *) &vid); 626 for (vid = 1; (vid < VLAN_VID_MASK); vid++) {
627 if (vlan_group_get_device(vptr->vlgrp, vid)) {
628 mac_set_vlan_cam(regs, i, (u8 *) &vid);
629 vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
630 if (++i >= VCAM_SIZE)
631 break;
631 } 632 }
632 } 633 }
633 vptr->vCAMmask[0] |= 1;
634 mac_set_vlan_cam_mask(regs, vptr->vCAMmask); 634 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
635 } else {
636 u16 temp = 0;
637 mac_set_vlan_cam(regs, 0, (u8 *) &temp);
638 temp = 1;
639 mac_set_vlan_cam_mask(regs, (u8 *) &temp);
640 } 635 }
641} 636}
642 637
638static void velocity_vlan_rx_register(struct net_device *dev,
639 struct vlan_group *grp)
640{
641 struct velocity_info *vptr = netdev_priv(dev);
642
643 vptr->vlgrp = grp;
644}
645
643static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) 646static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
644{ 647{
645 struct velocity_info *vptr = netdev_priv(dev); 648 struct velocity_info *vptr = netdev_priv(dev);
@@ -959,11 +962,13 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
959 962
960 dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid; 963 dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
961 dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid; 964 dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
965 dev->vlan_rx_register = velocity_vlan_rx_register;
962 966
963#ifdef VELOCITY_ZERO_COPY_SUPPORT 967#ifdef VELOCITY_ZERO_COPY_SUPPORT
964 dev->features |= NETIF_F_SG; 968 dev->features |= NETIF_F_SG;
965#endif 969#endif
966 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER; 970 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
971 NETIF_F_HW_VLAN_RX;
967 972
968 if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) 973 if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
969 dev->features |= NETIF_F_IP_CSUM; 974 dev->features |= NETIF_F_IP_CSUM;
@@ -1597,8 +1602,13 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
1597 skb_put(skb, pkt_len - 4); 1602 skb_put(skb, pkt_len - 4);
1598 skb->protocol = eth_type_trans(skb, vptr->dev); 1603 skb->protocol = eth_type_trans(skb, vptr->dev);
1599 1604
1605 if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) {
1606 vlan_hwaccel_rx(skb, vptr->vlgrp,
1607 swab16(le16_to_cpu(rd->rdesc1.PQTAG)));
1608 } else
1609 netif_rx(skb);
1610
1600 stats->rx_bytes += pkt_len; 1611 stats->rx_bytes += pkt_len;
1601 netif_rx(skb);
1602 1612
1603 return 0; 1613 return 0;
1604} 1614}