diff options
-rw-r--r-- | drivers/net/via-velocity.c | 49 | ||||
-rw-r--r-- | drivers/net/via-velocity.h | 2 |
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, | |||
501 | static void velocity_init_cam_filter(struct velocity_info *vptr) | 503 | static 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, ®s->MCFG); | 509 | WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->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, ®s->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 | ||
534 | static 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, ®s->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 | ||
542 | static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | 532 | static 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 | ||