aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/s2io.c59
-rw-r--r--drivers/net/s2io.h2
2 files changed, 59 insertions, 2 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index ee498d248d38..db3e394c740b 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -55,6 +55,7 @@
55#include <linux/ethtool.h> 55#include <linux/ethtool.h>
56#include <linux/version.h> 56#include <linux/version.h>
57#include <linux/workqueue.h> 57#include <linux/workqueue.h>
58#include <linux/if_vlan.h>
58 59
59#include <asm/system.h> 60#include <asm/system.h>
60#include <asm/uaccess.h> 61#include <asm/uaccess.h>
@@ -174,6 +175,30 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
174 timer.data = (unsigned long) arg; \ 175 timer.data = (unsigned long) arg; \
175 mod_timer(&timer, (jiffies + exp)) \ 176 mod_timer(&timer, (jiffies + exp)) \
176 177
178/* Add the vlan */
179static void s2io_vlan_rx_register(struct net_device *dev,
180 struct vlan_group *grp)
181{
182 nic_t *nic = dev->priv;
183 unsigned long flags;
184
185 spin_lock_irqsave(&nic->tx_lock, flags);
186 nic->vlgrp = grp;
187 spin_unlock_irqrestore(&nic->tx_lock, flags);
188}
189
190/* Unregister the vlan */
191static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
192{
193 nic_t *nic = dev->priv;
194 unsigned long flags;
195
196 spin_lock_irqsave(&nic->tx_lock, flags);
197 if (nic->vlgrp)
198 nic->vlgrp->vlan_devices[vid] = NULL;
199 spin_unlock_irqrestore(&nic->tx_lock, flags);
200}
201
177/* 202/*
178 * Constants to be programmed into the Xena's registers, to configure 203 * Constants to be programmed into the Xena's registers, to configure
179 * the XAUI. 204 * the XAUI.
@@ -2803,6 +2828,8 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
2803#ifdef NETIF_F_TSO 2828#ifdef NETIF_F_TSO
2804 int mss; 2829 int mss;
2805#endif 2830#endif
2831 u16 vlan_tag = 0;
2832 int vlan_priority = 0;
2806 mac_info_t *mac_control; 2833 mac_info_t *mac_control;
2807 struct config_param *config; 2834 struct config_param *config;
2808 2835
@@ -2821,6 +2848,13 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
2821 2848
2822 queue = 0; 2849 queue = 0;
2823 2850
2851 /* Get Fifo number to Transmit based on vlan priority */
2852 if (sp->vlgrp && vlan_tx_tag_present(skb)) {
2853 vlan_tag = vlan_tx_tag_get(skb);
2854 vlan_priority = vlan_tag >> 13;
2855 queue = config->fifo_mapping[vlan_priority];
2856 }
2857
2824 put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset; 2858 put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset;
2825 get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset; 2859 get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset;
2826 txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off]. 2860 txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off].
@@ -2857,6 +2891,11 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
2857 2891
2858 txdp->Control_2 |= config->tx_intr_type; 2892 txdp->Control_2 |= config->tx_intr_type;
2859 2893
2894 if (sp->vlgrp && vlan_tx_tag_present(skb)) {
2895 txdp->Control_2 |= TXD_VLAN_ENABLE;
2896 txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
2897 }
2898
2860 txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | 2899 txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
2861 TXD_GATHER_CODE_FIRST); 2900 TXD_GATHER_CODE_FIRST);
2862 txdp->Control_1 |= TXD_LIST_OWN_XENA; 2901 txdp->Control_1 |= TXD_LIST_OWN_XENA;
@@ -4653,10 +4692,23 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
4653 4692
4654 skb->protocol = eth_type_trans(skb, dev); 4693 skb->protocol = eth_type_trans(skb, dev);
4655#ifdef CONFIG_S2IO_NAPI 4694#ifdef CONFIG_S2IO_NAPI
4656 netif_receive_skb(skb); 4695 if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) {
4696 /* Queueing the vlan frame to the upper layer */
4697 vlan_hwaccel_receive_skb(skb, sp->vlgrp,
4698 RXD_GET_VLAN_TAG(rxdp->Control_2));
4699 } else {
4700 netif_receive_skb(skb);
4701 }
4657#else 4702#else
4658 netif_rx(skb); 4703 if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) {
4704 /* Queueing the vlan frame to the upper layer */
4705 vlan_hwaccel_rx(skb, sp->vlgrp,
4706 RXD_GET_VLAN_TAG(rxdp->Control_2));
4707 } else {
4708 netif_rx(skb);
4709 }
4659#endif 4710#endif
4711
4660 dev->last_rx = jiffies; 4712 dev->last_rx = jiffies;
4661 atomic_dec(&sp->rx_bufs_left[ring_no]); 4713 atomic_dec(&sp->rx_bufs_left[ring_no]);
4662 return SUCCESS; 4714 return SUCCESS;
@@ -4954,6 +5006,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
4954 dev->do_ioctl = &s2io_ioctl; 5006 dev->do_ioctl = &s2io_ioctl;
4955 dev->change_mtu = &s2io_change_mtu; 5007 dev->change_mtu = &s2io_change_mtu;
4956 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); 5008 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
5009 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
5010 dev->vlan_rx_register = s2io_vlan_rx_register;
5011 dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid;
4957 5012
4958 /* 5013 /*
4959 * will use eth_mac_addr() for dev->set_mac_address 5014 * will use eth_mac_addr() for dev->set_mac_address
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 263fe7a1b903..b924ef21814a 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -689,6 +689,8 @@ struct s2io_nic {
689#define CARD_UP 2 689#define CARD_UP 2
690 atomic_t card_state; 690 atomic_t card_state;
691 volatile unsigned long link_state; 691 volatile unsigned long link_state;
692 struct vlan_group *vlgrp;
693
692 spinlock_t rx_lock; 694 spinlock_t rx_lock;
693 atomic_t isr_cnt; 695 atomic_t isr_cnt;
694}; 696};