aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/via-velocity.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-08-24 16:56:49 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:53:48 -0400
commit501e4d247a7e35a4d3aa8e6973794b1586f6cb30 (patch)
tree4a9aa06c5cacb2e67d83b4daf4506599815c4aef /drivers/net/via-velocity.c
parentf5279ffdce9bcff938451303126971098e23aab3 (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.c73
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
112VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors"); 113VELOCITY_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*/
121VELOCITY_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*/
148VELOCITY_PARAM(DMA_length, "DMA length"); 140VELOCITY_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*/
155VELOCITY_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,
465static void velocity_init_cam_filter(struct velocity_info *vptr) 449static 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, &regs->MCFG); 455 WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->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, &regs->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, &regs->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
488static 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
497static 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;