aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/via-velocity.c49
-rw-r--r--drivers/net/via-velocity.h2
2 files changed, 21 insertions, 30 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index f92924283d3b..a9aa4a3fbfbe 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -45,6 +45,7 @@
45 45
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/types.h> 47#include <linux/types.h>
48#include <linux/bitops.h>
48#include <linux/init.h> 49#include <linux/init.h>
49#include <linux/mm.h> 50#include <linux/mm.h>
50#include <linux/errno.h> 51#include <linux/errno.h>
@@ -76,6 +77,7 @@
76#include <linux/udp.h> 77#include <linux/udp.h>
77#include <linux/crc-ccitt.h> 78#include <linux/crc-ccitt.h>
78#include <linux/crc32.h> 79#include <linux/crc32.h>
80#include <linux/if_vlan.h>
79 81
80#include "via-velocity.h" 82#include "via-velocity.h"
81 83
@@ -501,6 +503,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
501static void velocity_init_cam_filter(struct velocity_info *vptr) 503static void velocity_init_cam_filter(struct velocity_info *vptr)
502{ 504{
503 struct mac_regs __iomem *regs = vptr->mac_regs; 505 struct mac_regs __iomem *regs = vptr->mac_regs;
506 unsigned int vid, i = 0;
504 507
505 /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ 508 /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
506 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG); 509 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
@@ -513,30 +516,17 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
513 mac_set_cam_mask(regs, vptr->mCAMmask); 516 mac_set_cam_mask(regs, vptr->mCAMmask);
514 517
515 /* Enable VCAMs */ 518 /* Enable VCAMs */
516 if (vptr->vlgrp) {
517 unsigned int vid, i = 0;
518
519 if (!vlan_group_get_device(vptr->vlgrp, 0))
520 WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
521
522 for (vid = 1; (vid < VLAN_VID_MASK); vid++) {
523 if (vlan_group_get_device(vptr->vlgrp, vid)) {
524 mac_set_vlan_cam(regs, i, (u8 *) &vid);
525 vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
526 if (++i >= VCAM_SIZE)
527 break;
528 }
529 }
530 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
531 }
532}
533 519
534static void velocity_vlan_rx_register(struct net_device *dev, 520 if (test_bit(0, vptr->active_vlans))
535 struct vlan_group *grp) 521 WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
536{
537 struct velocity_info *vptr = netdev_priv(dev);
538 522
539 vptr->vlgrp = grp; 523 for_each_set_bit(vid, vptr->active_vlans, VLAN_N_VID) {
524 mac_set_vlan_cam(regs, i, (u8 *) &vid);
525 vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
526 if (++i >= VCAM_SIZE)
527 break;
528 }
529 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
540} 530}
541 531
542static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) 532static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
@@ -544,6 +534,7 @@ static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
544 struct velocity_info *vptr = netdev_priv(dev); 534 struct velocity_info *vptr = netdev_priv(dev);
545 535
546 spin_lock_irq(&vptr->lock); 536 spin_lock_irq(&vptr->lock);
537 set_bit(vid, vptr->active_vlans);
547 velocity_init_cam_filter(vptr); 538 velocity_init_cam_filter(vptr);
548 spin_unlock_irq(&vptr->lock); 539 spin_unlock_irq(&vptr->lock);
549} 540}
@@ -553,7 +544,7 @@ static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid
553 struct velocity_info *vptr = netdev_priv(dev); 544 struct velocity_info *vptr = netdev_priv(dev);
554 545
555 spin_lock_irq(&vptr->lock); 546 spin_lock_irq(&vptr->lock);
556 vlan_group_set_device(vptr->vlgrp, vid, NULL); 547 clear_bit(vid, vptr->active_vlans);
557 velocity_init_cam_filter(vptr); 548 velocity_init_cam_filter(vptr);
558 spin_unlock_irq(&vptr->lock); 549 spin_unlock_irq(&vptr->lock);
559} 550}
@@ -2094,11 +2085,12 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
2094 skb_put(skb, pkt_len - 4); 2085 skb_put(skb, pkt_len - 4);
2095 skb->protocol = eth_type_trans(skb, vptr->dev); 2086 skb->protocol = eth_type_trans(skb, vptr->dev);
2096 2087
2097 if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) { 2088 if (rd->rdesc0.RSR & RSR_DETAG) {
2098 vlan_hwaccel_rx(skb, vptr->vlgrp, 2089 u16 vid = swab16(le16_to_cpu(rd->rdesc1.PQTAG));
2099 swab16(le16_to_cpu(rd->rdesc1.PQTAG))); 2090
2100 } else 2091 __vlan_hwaccel_put_tag(skb, vid);
2101 netif_rx(skb); 2092 }
2093 netif_rx(skb);
2102 2094
2103 stats->rx_bytes += pkt_len; 2095 stats->rx_bytes += pkt_len;
2104 2096
@@ -2641,7 +2633,6 @@ static const struct net_device_ops velocity_netdev_ops = {
2641 .ndo_do_ioctl = velocity_ioctl, 2633 .ndo_do_ioctl = velocity_ioctl,
2642 .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid, 2634 .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid,
2643 .ndo_vlan_rx_kill_vid = velocity_vlan_rx_kill_vid, 2635 .ndo_vlan_rx_kill_vid = velocity_vlan_rx_kill_vid,
2644 .ndo_vlan_rx_register = velocity_vlan_rx_register,
2645}; 2636};
2646 2637
2647/** 2638/**
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 0f1f05f6c4f8..4cb9f13485e9 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1437,7 +1437,7 @@ struct velocity_info {
1437 struct pci_dev *pdev; 1437 struct pci_dev *pdev;
1438 struct net_device *dev; 1438 struct net_device *dev;
1439 1439
1440 struct vlan_group *vlgrp; 1440 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
1441 u8 ip_addr[4]; 1441 u8 ip_addr[4];
1442 enum chip_type chip_id; 1442 enum chip_type chip_id;
1443 1443