From: Jiri Pirko <j...@mellanox.com>

Some drivers need to implement both switchdev vlan ops and
vid_add/kill ndos. For that to work in bridge code, we need to try
switchdev op first when adding/deleting vlan id.

Signed-off-by: Jiri Pirko <j...@mellanox.com>
Signed-off-by: Ido Schimmel <ido...@mellanox.com>
---
 net/bridge/br_vlan.c | 58 ++++++++++++++++++++--------------------------------
 1 file changed, 22 insertions(+), 36 deletions(-)

diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index eae07ee..975deb9 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -72,28 +72,20 @@ static void __vlan_add_flags(struct net_bridge_vlan *v, u16 
flags)
 static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
                          u16 vid, u16 flags)
 {
-       const struct net_device_ops *ops = dev->netdev_ops;
+       struct switchdev_obj_port_vlan v = {
+               .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
+               .flags = flags,
+               .vid_begin = vid,
+               .vid_end = vid,
+       };
        int err;
 
-       /* If driver uses VLAN ndo ops, use 8021q to install vid
-        * on device, otherwise try switchdev ops to install vid.
+       /* Try switchdev op first. In case it is not supported, fallback to
+        * 8021q add.
         */
-
-       if (ops->ndo_vlan_rx_add_vid) {
-               err = vlan_vid_add(dev, br->vlan_proto, vid);
-       } else {
-               struct switchdev_obj_port_vlan v = {
-                       .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
-                       .flags = flags,
-                       .vid_begin = vid,
-                       .vid_end = vid,
-               };
-
-               err = switchdev_port_obj_add(dev, &v.obj);
-               if (err == -EOPNOTSUPP)
-                       err = 0;
-       }
-
+       err = switchdev_port_obj_add(dev, &v.obj);
+       if (err == -EOPNOTSUPP)
+               return vlan_vid_add(dev, br->vlan_proto, vid);
        return err;
 }
 
@@ -122,27 +114,21 @@ static void __vlan_del_list(struct net_bridge_vlan *v)
 static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,
                          u16 vid)
 {
-       const struct net_device_ops *ops = dev->netdev_ops;
-       int err = 0;
+       struct switchdev_obj_port_vlan v = {
+               .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
+               .vid_begin = vid,
+               .vid_end = vid,
+       };
+       int err;
 
-       /* If driver uses VLAN ndo ops, use 8021q to delete vid
-        * on device, otherwise try switchdev ops to delete vid.
+       /* Try switchdev op first. In case it is not supported, fallback to
+        * 8021q del.
         */
-
-       if (ops->ndo_vlan_rx_kill_vid) {
+       err = switchdev_port_obj_del(dev, &v.obj);
+       if (err == -EOPNOTSUPP) {
                vlan_vid_del(dev, br->vlan_proto, vid);
-       } else {
-               struct switchdev_obj_port_vlan v = {
-                       .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
-                       .vid_begin = vid,
-                       .vid_end = vid,
-               };
-
-               err = switchdev_port_obj_del(dev, &v.obj);
-               if (err == -EOPNOTSUPP)
-                       err = 0;
+               return 0;
        }
-
        return err;
 }
 
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to