aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorBenjamin LaHaise <bcrl@kvack.org>2011-12-08 01:20:49 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-08 19:58:30 -0500
commit6d4cdf47d2cc9d40227c67c79a4942e36ed1b0ba (patch)
tree5c31e3f1be3ba098f57ae33796e50ea50dcee1e9 /net/8021q
parent8af2a218de38f51ea4b4fa48cac1273319ae260c (diff)
vlan: add 802.1q netpoll support
Add netpoll support to 802.1q vlan devices. Based on the netpoll support in the bridging code. Tested on a forced_eth device with netconsole. Signed-off-by: Benjamin LaHaise <bcrl@kvack.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan.h5
-rw-r--r--net/8021q/vlan_dev.c59
2 files changed, 64 insertions, 0 deletions
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 28d8dc20cb6d..a4886d94c40c 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -41,6 +41,8 @@ struct vlan_pcpu_stats {
41 u32 tx_dropped; 41 u32 tx_dropped;
42}; 42};
43 43
44struct netpoll;
45
44/** 46/**
45 * struct vlan_dev_priv - VLAN private device data 47 * struct vlan_dev_priv - VLAN private device data
46 * @nr_ingress_mappings: number of ingress priority mappings 48 * @nr_ingress_mappings: number of ingress priority mappings
@@ -68,6 +70,9 @@ struct vlan_dev_priv {
68 70
69 struct proc_dir_entry *dent; 71 struct proc_dir_entry *dent;
70 struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; 72 struct vlan_pcpu_stats __percpu *vlan_pcpu_stats;
73#ifdef CONFIG_NET_POLL_CONTROLLER
74 struct netpoll *netpoll;
75#endif
71}; 76};
72 77
73static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) 78static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 3b4db82b016f..039013923a74 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -33,6 +33,7 @@
33#include "vlan.h" 33#include "vlan.h"
34#include "vlanproc.h" 34#include "vlanproc.h"
35#include <linux/if_vlan.h> 35#include <linux/if_vlan.h>
36#include <linux/netpoll.h>
36 37
37/* 38/*
38 * Rebuild the Ethernet MAC header. This is called after an ARP 39 * Rebuild the Ethernet MAC header. This is called after an ARP
@@ -158,6 +159,8 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
158 159
159 skb_set_dev(skb, vlan_dev_priv(dev)->real_dev); 160 skb_set_dev(skb, vlan_dev_priv(dev)->real_dev);
160 len = skb->len; 161 len = skb->len;
162 if (netpoll_tx_running(dev))
163 return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
161 ret = dev_queue_xmit(skb); 164 ret = dev_queue_xmit(skb);
162 165
163 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { 166 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
@@ -660,6 +663,57 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st
660 return stats; 663 return stats;
661} 664}
662 665
666#ifdef CONFIG_NET_POLL_CONTROLLER
667void vlan_dev_poll_controller(struct net_device *dev)
668{
669 return;
670}
671
672int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo)
673{
674 struct vlan_dev_priv *info = vlan_dev_priv(dev);
675 struct net_device *real_dev = info->real_dev;
676 struct netpoll *netpoll;
677 int err = 0;
678
679 netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL);
680 err = -ENOMEM;
681 if (!netpoll)
682 goto out;
683
684 netpoll->dev = real_dev;
685 strlcpy(netpoll->dev_name, real_dev->name, IFNAMSIZ);
686
687 err = __netpoll_setup(netpoll);
688 if (err) {
689 kfree(netpoll);
690 goto out;
691 }
692
693 info->netpoll = netpoll;
694
695out:
696 return err;
697}
698
699void vlan_dev_netpoll_cleanup(struct net_device *dev)
700{
701 struct vlan_dev_priv *info = vlan_dev_priv(dev);
702 struct netpoll *netpoll = info->netpoll;
703
704 if (!netpoll)
705 return;
706
707 info->netpoll = NULL;
708
709 /* Wait for transmitting packets to finish before freeing. */
710 synchronize_rcu_bh();
711
712 __netpoll_cleanup(netpoll);
713 kfree(netpoll);
714}
715#endif /* CONFIG_NET_POLL_CONTROLLER */
716
663static const struct ethtool_ops vlan_ethtool_ops = { 717static const struct ethtool_ops vlan_ethtool_ops = {
664 .get_settings = vlan_ethtool_get_settings, 718 .get_settings = vlan_ethtool_get_settings,
665 .get_drvinfo = vlan_ethtool_get_drvinfo, 719 .get_drvinfo = vlan_ethtool_get_drvinfo,
@@ -688,6 +742,11 @@ static const struct net_device_ops vlan_netdev_ops = {
688 .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, 742 .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
689 .ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target, 743 .ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target,
690#endif 744#endif
745#ifdef CONFIG_NET_POLL_CONTROLLER
746 .ndo_poll_controller = vlan_dev_poll_controller,
747 .ndo_netpoll_setup = vlan_dev_netpoll_setup,
748 .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup,
749#endif
691 .ndo_fix_features = vlan_dev_fix_features, 750 .ndo_fix_features = vlan_dev_fix_features,
692}; 751};
693 752