diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-08-24 16:56:49 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:53:48 -0400 |
commit | 501e4d247a7e35a4d3aa8e6973794b1586f6cb30 (patch) | |
tree | 4a9aa06c5cacb2e67d83b4daf4506599815c4aef /drivers/net/via-velocity.c | |
parent | f5279ffdce9bcff938451303126971098e23aab3 (diff) |
via-velocity: use standard VLAN interface (resend)
The via-velocity is using a non-standard VLAN interface configured
via module parameters (yuck).
Replace with the standard acceleration interface.
It solves a number of problems with being able to handle multiple
vlans, and dynamically reconfigure.
This is compile tested only, don't have this board.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/via-velocity.c')
-rw-r--r-- | drivers/net/via-velocity.c | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 511a74c6e78b..fd1ff123efa0 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <linux/mii.h> | 72 | #include <linux/mii.h> |
73 | #include <linux/in.h> | 73 | #include <linux/in.h> |
74 | #include <linux/if_arp.h> | 74 | #include <linux/if_arp.h> |
75 | #include <linux/if_vlan.h> | ||
75 | #include <linux/ip.h> | 76 | #include <linux/ip.h> |
76 | #include <linux/tcp.h> | 77 | #include <linux/tcp.h> |
77 | #include <linux/udp.h> | 78 | #include <linux/udp.h> |
@@ -111,15 +112,6 @@ VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors"); | |||
111 | #define TX_DESC_DEF 64 | 112 | #define TX_DESC_DEF 64 |
112 | VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors"); | 113 | VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors"); |
113 | 114 | ||
114 | #define VLAN_ID_MIN 0 | ||
115 | #define VLAN_ID_MAX 4095 | ||
116 | #define VLAN_ID_DEF 0 | ||
117 | /* VID_setting[] is used for setting the VID of NIC. | ||
118 | 0: default VID. | ||
119 | 1-4094: other VIDs. | ||
120 | */ | ||
121 | VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID"); | ||
122 | |||
123 | #define RX_THRESH_MIN 0 | 115 | #define RX_THRESH_MIN 0 |
124 | #define RX_THRESH_MAX 3 | 116 | #define RX_THRESH_MAX 3 |
125 | #define RX_THRESH_DEF 0 | 117 | #define RX_THRESH_DEF 0 |
@@ -147,13 +139,6 @@ VELOCITY_PARAM(rx_thresh, "Receive fifo threshold"); | |||
147 | */ | 139 | */ |
148 | VELOCITY_PARAM(DMA_length, "DMA length"); | 140 | VELOCITY_PARAM(DMA_length, "DMA length"); |
149 | 141 | ||
150 | #define TAGGING_DEF 0 | ||
151 | /* enable_tagging[] is used for enabling 802.1Q VID tagging. | ||
152 | 0: disable VID seeting(default). | ||
153 | 1: enable VID setting. | ||
154 | */ | ||
155 | VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging"); | ||
156 | |||
157 | #define IP_ALIG_DEF 0 | 142 | #define IP_ALIG_DEF 0 |
158 | /* IP_byte_align[] is used for IP header DWORD byte aligned | 143 | /* IP_byte_align[] is used for IP header DWORD byte aligned |
159 | 0: indicate the IP header won't be DWORD byte aligned.(Default) . | 144 | 0: indicate the IP header won't be DWORD byte aligned.(Default) . |
@@ -442,8 +427,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, | |||
442 | velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname); | 427 | velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname); |
443 | velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname); | 428 | velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname); |
444 | velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname); | 429 | velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname); |
445 | velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname); | 430 | |
446 | velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname); | ||
447 | velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname); | 431 | velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname); |
448 | velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname); | 432 | velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname); |
449 | velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname); | 433 | velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname); |
@@ -465,6 +449,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, | |||
465 | static void velocity_init_cam_filter(struct velocity_info *vptr) | 449 | static void velocity_init_cam_filter(struct velocity_info *vptr) |
466 | { | 450 | { |
467 | struct mac_regs __iomem * regs = vptr->mac_regs; | 451 | struct mac_regs __iomem * regs = vptr->mac_regs; |
452 | unsigned short vid; | ||
468 | 453 | ||
469 | /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ | 454 | /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ |
470 | WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); | 455 | WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); |
@@ -477,13 +462,19 @@ static void velocity_init_cam_filter(struct velocity_info *vptr) | |||
477 | mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); | 462 | mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); |
478 | 463 | ||
479 | /* Enable first VCAM */ | 464 | /* Enable first VCAM */ |
480 | if (vptr->flags & VELOCITY_FLAGS_TAGGING) { | 465 | if (vptr->vlgrp) { |
481 | /* If Tagging option is enabled and VLAN ID is not zero, then | 466 | for (vid = 0; vid < VLAN_VID_MASK; vid++) { |
482 | turn on MCFG_RTGOPT also */ | 467 | if (vlan_group_get_device(vptr->vlgrp, vid)) { |
483 | if (vptr->options.vid != 0) | 468 | /* If Tagging option is enabled and |
484 | WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); | 469 | VLAN ID is not zero, then |
485 | 470 | turn on MCFG_RTGOPT also */ | |
486 | mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM); | 471 | if (vid != 0) |
472 | WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); | ||
473 | |||
474 | mac_set_cam(regs, 0, (u8 *) &vid, | ||
475 | VELOCITY_VLAN_ID_CAM); | ||
476 | } | ||
477 | } | ||
487 | vptr->vCAMmask[0] |= 1; | 478 | vptr->vCAMmask[0] |= 1; |
488 | mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); | 479 | mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); |
489 | } else { | 480 | } else { |
@@ -494,6 +485,26 @@ static void velocity_init_cam_filter(struct velocity_info *vptr) | |||
494 | } | 485 | } |
495 | } | 486 | } |
496 | 487 | ||
488 | static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | ||
489 | { | ||
490 | struct velocity_info *vptr = netdev_priv(dev); | ||
491 | |||
492 | spin_lock_irq(&vptr->lock); | ||
493 | velocity_init_cam_filter(vptr); | ||
494 | spin_unlock_irq(&vptr->lock); | ||
495 | } | ||
496 | |||
497 | static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | ||
498 | { | ||
499 | struct velocity_info *vptr = netdev_priv(dev); | ||
500 | |||
501 | spin_lock_irq(&vptr->lock); | ||
502 | vlan_group_set_device(vptr->vlgrp, vid, NULL); | ||
503 | velocity_init_cam_filter(vptr); | ||
504 | spin_unlock_irq(&vptr->lock); | ||
505 | } | ||
506 | |||
507 | |||
497 | /** | 508 | /** |
498 | * velocity_rx_reset - handle a receive reset | 509 | * velocity_rx_reset - handle a receive reset |
499 | * @vptr: velocity we are resetting | 510 | * @vptr: velocity we are resetting |
@@ -790,13 +801,17 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi | |||
790 | dev->do_ioctl = velocity_ioctl; | 801 | dev->do_ioctl = velocity_ioctl; |
791 | dev->ethtool_ops = &velocity_ethtool_ops; | 802 | dev->ethtool_ops = &velocity_ethtool_ops; |
792 | dev->change_mtu = velocity_change_mtu; | 803 | dev->change_mtu = velocity_change_mtu; |
804 | |||
805 | dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid; | ||
806 | dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid; | ||
807 | |||
793 | #ifdef VELOCITY_ZERO_COPY_SUPPORT | 808 | #ifdef VELOCITY_ZERO_COPY_SUPPORT |
794 | dev->features |= NETIF_F_SG; | 809 | dev->features |= NETIF_F_SG; |
795 | #endif | 810 | #endif |
811 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER; | ||
796 | 812 | ||
797 | if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) { | 813 | if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) |
798 | dev->features |= NETIF_F_IP_CSUM; | 814 | dev->features |= NETIF_F_IP_CSUM; |
799 | } | ||
800 | 815 | ||
801 | ret = register_netdev(dev); | 816 | ret = register_netdev(dev); |
802 | if (ret < 0) | 817 | if (ret < 0) |
@@ -1989,8 +2004,8 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1989 | td_ptr->tdesc1.CMDZ = 2; | 2004 | td_ptr->tdesc1.CMDZ = 2; |
1990 | } | 2005 | } |
1991 | 2006 | ||
1992 | if (vptr->flags & VELOCITY_FLAGS_TAGGING) { | 2007 | if (vptr->vlgrp && vlan_tx_tag_present(skb)) { |
1993 | td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff); | 2008 | td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb); |
1994 | td_ptr->tdesc1.pqinf.priority = 0; | 2009 | td_ptr->tdesc1.pqinf.priority = 0; |
1995 | td_ptr->tdesc1.pqinf.CFI = 0; | 2010 | td_ptr->tdesc1.pqinf.CFI = 0; |
1996 | td_ptr->tdesc1.TCR |= TCR0_VETAG; | 2011 | td_ptr->tdesc1.TCR |= TCR0_VETAG; |