[PATCH] S2io: VLAN support
Hi, Patch below adds VLAN support to the driver. Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com> Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
parent
25fff88eb7
commit
be3a6b02eb
2 changed files with 59 additions and 2 deletions
|
@ -55,6 +55,7 @@
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/if_vlan.h>
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
@ -174,6 +175,30 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = {
|
||||||
timer.data = (unsigned long) arg; \
|
timer.data = (unsigned long) arg; \
|
||||||
mod_timer(&timer, (jiffies + exp)) \
|
mod_timer(&timer, (jiffies + exp)) \
|
||||||
|
|
||||||
|
/* Add the vlan */
|
||||||
|
static void s2io_vlan_rx_register(struct net_device *dev,
|
||||||
|
struct vlan_group *grp)
|
||||||
|
{
|
||||||
|
nic_t *nic = dev->priv;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&nic->tx_lock, flags);
|
||||||
|
nic->vlgrp = grp;
|
||||||
|
spin_unlock_irqrestore(&nic->tx_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unregister the vlan */
|
||||||
|
static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
|
||||||
|
{
|
||||||
|
nic_t *nic = dev->priv;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&nic->tx_lock, flags);
|
||||||
|
if (nic->vlgrp)
|
||||||
|
nic->vlgrp->vlan_devices[vid] = NULL;
|
||||||
|
spin_unlock_irqrestore(&nic->tx_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constants to be programmed into the Xena's registers, to configure
|
* Constants to be programmed into the Xena's registers, to configure
|
||||||
* the XAUI.
|
* the XAUI.
|
||||||
|
@ -2803,6 +2828,8 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
#ifdef NETIF_F_TSO
|
#ifdef NETIF_F_TSO
|
||||||
int mss;
|
int mss;
|
||||||
#endif
|
#endif
|
||||||
|
u16 vlan_tag = 0;
|
||||||
|
int vlan_priority = 0;
|
||||||
mac_info_t *mac_control;
|
mac_info_t *mac_control;
|
||||||
struct config_param *config;
|
struct config_param *config;
|
||||||
|
|
||||||
|
@ -2821,6 +2848,13 @@ int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
queue = 0;
|
queue = 0;
|
||||||
|
|
||||||
|
/* Get Fifo number to Transmit based on vlan priority */
|
||||||
|
if (sp->vlgrp && vlan_tx_tag_present(skb)) {
|
||||||
|
vlan_tag = vlan_tx_tag_get(skb);
|
||||||
|
vlan_priority = vlan_tag >> 13;
|
||||||
|
queue = config->fifo_mapping[vlan_priority];
|
||||||
|
}
|
||||||
|
|
||||||
put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset;
|
put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset;
|
||||||
get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset;
|
get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset;
|
||||||
txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off].
|
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)
|
||||||
|
|
||||||
txdp->Control_2 |= config->tx_intr_type;
|
txdp->Control_2 |= config->tx_intr_type;
|
||||||
|
|
||||||
|
if (sp->vlgrp && vlan_tx_tag_present(skb)) {
|
||||||
|
txdp->Control_2 |= TXD_VLAN_ENABLE;
|
||||||
|
txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
|
||||||
|
}
|
||||||
|
|
||||||
txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
|
txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
|
||||||
TXD_GATHER_CODE_FIRST);
|
TXD_GATHER_CODE_FIRST);
|
||||||
txdp->Control_1 |= TXD_LIST_OWN_XENA;
|
txdp->Control_1 |= TXD_LIST_OWN_XENA;
|
||||||
|
@ -4653,10 +4692,23 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp)
|
||||||
|
|
||||||
skb->protocol = eth_type_trans(skb, dev);
|
skb->protocol = eth_type_trans(skb, dev);
|
||||||
#ifdef CONFIG_S2IO_NAPI
|
#ifdef CONFIG_S2IO_NAPI
|
||||||
netif_receive_skb(skb);
|
if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) {
|
||||||
|
/* Queueing the vlan frame to the upper layer */
|
||||||
|
vlan_hwaccel_receive_skb(skb, sp->vlgrp,
|
||||||
|
RXD_GET_VLAN_TAG(rxdp->Control_2));
|
||||||
|
} else {
|
||||||
|
netif_receive_skb(skb);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
netif_rx(skb);
|
if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) {
|
||||||
|
/* Queueing the vlan frame to the upper layer */
|
||||||
|
vlan_hwaccel_rx(skb, sp->vlgrp,
|
||||||
|
RXD_GET_VLAN_TAG(rxdp->Control_2));
|
||||||
|
} else {
|
||||||
|
netif_rx(skb);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dev->last_rx = jiffies;
|
dev->last_rx = jiffies;
|
||||||
atomic_dec(&sp->rx_bufs_left[ring_no]);
|
atomic_dec(&sp->rx_bufs_left[ring_no]);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -4954,6 +5006,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
|
||||||
dev->do_ioctl = &s2io_ioctl;
|
dev->do_ioctl = &s2io_ioctl;
|
||||||
dev->change_mtu = &s2io_change_mtu;
|
dev->change_mtu = &s2io_change_mtu;
|
||||||
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
||||||
|
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
|
||||||
|
dev->vlan_rx_register = s2io_vlan_rx_register;
|
||||||
|
dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* will use eth_mac_addr() for dev->set_mac_address
|
* will use eth_mac_addr() for dev->set_mac_address
|
||||||
|
|
|
@ -689,6 +689,8 @@ struct s2io_nic {
|
||||||
#define CARD_UP 2
|
#define CARD_UP 2
|
||||||
atomic_t card_state;
|
atomic_t card_state;
|
||||||
volatile unsigned long link_state;
|
volatile unsigned long link_state;
|
||||||
|
struct vlan_group *vlgrp;
|
||||||
|
|
||||||
spinlock_t rx_lock;
|
spinlock_t rx_lock;
|
||||||
atomic_t isr_cnt;
|
atomic_t isr_cnt;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue