[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1359489180-10012-2-git-send-email-vyasevic@redhat.com>
Date: Tue, 29 Jan 2013 14:52:48 -0500
From: Vlad Yasevich <vyasevic@...hat.com>
To: shemminger@...tta.com
Cc: bridge@...ts.linux-foundation.org, davem@...emloft.net,
netdev@...r.kernel.org, shmulik.ladkani@...il.com
Subject: [PATCH 01/13] vlan: wrap hw-acceleration calls in separate functions.
Wrap VLAN hardware acceleration calls into separate functions. This way
other code can re-use it.
Signed-off-by: Vlad Yasevich <vyasevic@...hat.com>
---
include/linux/if_vlan.h | 21 ++++++++++++
net/8021q/vlan.c | 4 +--
net/8021q/vlan_core.c | 81 +++++++++++++++++++++++++++++++++++++---------
3 files changed, 87 insertions(+), 19 deletions(-)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index d06cc5c..b658eda 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -93,6 +93,10 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);
extern bool vlan_do_receive(struct sk_buff **skb);
extern struct sk_buff *vlan_untag(struct sk_buff *skb);
+extern bool vlan_hw_buggy(const struct net_device *dev);
+extern int vlan_vid_add_hw(struct net_device *dev, unsigned short vid);
+extern int vlan_vid_del_hw(struct net_device *dev, unsigned short vid);
+
extern int vlan_vid_add(struct net_device *dev, unsigned short vid);
extern void vlan_vid_del(struct net_device *dev, unsigned short vid);
@@ -155,6 +159,23 @@ static inline bool vlan_uses_dev(const struct net_device *dev)
{
return false;
}
+
+static inline bool vlan_hw_buggy(const struct net_device *dev)
+{
+ return false;
+}
+
+static inline int vlan_vid_add_hw(struct net_device *dev,
+ unsigned short vid)
+{
+ return 0;
+}
+
+static inline int vlan_vid_del_hw(struct net_device *dev,
+ unsigned short vid)
+{
+ return 0;
+}
#endif
/**
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index babfde9..540d759 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -117,15 +117,13 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
{
const char *name = real_dev->name;
- const struct net_device_ops *ops = real_dev->netdev_ops;
if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
pr_info("VLANs not supported on %s\n", name);
return -EOPNOTSUPP;
}
- if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
- (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) {
+ if (vlan_hw_buggy(real_dev)) {
pr_info("Device %s has buggy VLAN hw accel\n", name);
return -EOPNOTSUPP;
}
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 380440b..d044dd3 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -145,6 +145,63 @@ err_free:
return NULL;
}
+/**
+ * vlan_hw_buggy - Check to see if VLAN hw acceleration is supported.
+ * @dev: netdevice of the lowerdev/hw nic
+ *
+ * Checks to see if HW and driver report VLAN acceleration correctly.
+ */
+bool vlan_hw_buggy(const struct net_device *dev)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+
+ if ((dev->features & NETIF_F_HW_VLAN_FILTER) &&
+ (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(vlan_hw_buggy);
+
+/**
+ * vlan_vid_add_hw - Add the VLAN vid to the HW filter
+ * @dev: netdevice of the lowerdev/hw nic
+ * @vid: vlan id.
+ *
+ * Inserts the vid into the HW vlan filter table if hw supports it.
+ */
+int vlan_vid_add_hw(struct net_device *dev, unsigned short vid)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+ int err = 0;
+
+ if ((dev->features & NETIF_F_HW_VLAN_FILTER) &&
+ ops->ndo_vlan_rx_add_vid)
+ err = ops->ndo_vlan_rx_add_vid(dev, vid);
+
+ return err;
+}
+EXPORT_SYMBOL(vlan_vid_add_hw);
+
+/**
+ * vlan_vid_del_hw - Delete the VLAN vid from the HW filter
+ * @dev: netdevice of the lowerdev/hw nic
+ * @vid: vlan id.
+ *
+ * Delete the vid from the HW vlan filter table if hw supports it.
+ */
+int vlan_vid_del_hw(struct net_device *dev, unsigned short vid)
+{
+ const struct net_device_ops *ops = dev->netdev_ops;
+ int err = 0;
+
+ if ((dev->features & NETIF_F_HW_VLAN_FILTER) &&
+ ops->ndo_vlan_rx_kill_vid)
+ err = ops->ndo_vlan_rx_add_vid(dev, vid);
+
+ return err;
+}
+EXPORT_SYMBOL(vlan_vid_del_hw);
/*
* vlan info and vid list
@@ -216,7 +273,6 @@ static int __vlan_vid_add(struct vlan_info *vlan_info, unsigned short vid,
struct vlan_vid_info **pvid_info)
{
struct net_device *dev = vlan_info->real_dev;
- const struct net_device_ops *ops = dev->netdev_ops;
struct vlan_vid_info *vid_info;
int err;
@@ -224,13 +280,10 @@ static int __vlan_vid_add(struct vlan_info *vlan_info, unsigned short vid,
if (!vid_info)
return -ENOMEM;
- if ((dev->features & NETIF_F_HW_VLAN_FILTER) &&
- ops->ndo_vlan_rx_add_vid) {
- err = ops->ndo_vlan_rx_add_vid(dev, vid);
- if (err) {
- kfree(vid_info);
- return err;
- }
+ err = vlan_vid_add_hw(dev, vid);
+ if (err) {
+ kfree(vid_info);
+ return err;
}
list_add(&vid_info->list, &vlan_info->vid_list);
vlan_info->nr_vids++;
@@ -278,17 +331,13 @@ static void __vlan_vid_del(struct vlan_info *vlan_info,
struct vlan_vid_info *vid_info)
{
struct net_device *dev = vlan_info->real_dev;
- const struct net_device_ops *ops = dev->netdev_ops;
unsigned short vid = vid_info->vid;
int err;
- if ((dev->features & NETIF_F_HW_VLAN_FILTER) &&
- ops->ndo_vlan_rx_kill_vid) {
- err = ops->ndo_vlan_rx_kill_vid(dev, vid);
- if (err) {
- pr_warn("failed to kill vid %d for device %s\n",
- vid, dev->name);
- }
+ err = vlan_vid_del_hw(dev, vid);
+ if (err) {
+ pr_warn("failed to kill vid %d for device %s\n",
+ vid, dev->name);
}
list_del(&vid_info->list);
kfree(vid_info);
--
1.7.7.6
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists