mlxsw: spectrum_switchdev: Reduce scope of bridge struct
authorIdo Schimmel <idosch@mellanox.com>
Tue, 16 May 2017 17:38:26 +0000 (19:38 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 May 2017 18:06:54 +0000 (14:06 -0400)
Some attributes in the global chip struct are only relevant for bridge
operation, so encapsulate them in their own struct that isn't exposed to
non-bridge code.

This will also help us later, when we add more bridge-specific
attributes.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c

index 88357cee767986073ae02f9560454d1b538d72b5..166be18541117ae6ee22ab076d5a8c97fcd4d7b2 100644 (file)
@@ -3312,7 +3312,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
        mlxsw_sp->bus_info = mlxsw_bus_info;
        INIT_LIST_HEAD(&mlxsw_sp->fids);
        INIT_LIST_HEAD(&mlxsw_sp->vfids.list);
-       INIT_LIST_HEAD(&mlxsw_sp->br_mids.list);
 
        err = mlxsw_sp_base_mac_get(mlxsw_sp);
        if (err) {
@@ -3659,21 +3658,26 @@ static void mlxsw_sp_master_bridge_gone_sync(struct mlxsw_sp *mlxsw_sp)
 static bool mlxsw_sp_master_bridge_check(struct mlxsw_sp *mlxsw_sp,
                                         struct net_device *br_dev)
 {
-       return !mlxsw_sp->master_bridge.dev ||
-              mlxsw_sp->master_bridge.dev == br_dev;
+       struct mlxsw_sp_upper *master_bridge = mlxsw_sp_master_bridge(mlxsw_sp);
+
+       return !master_bridge->dev || master_bridge->dev == br_dev;
 }
 
 static void mlxsw_sp_master_bridge_inc(struct mlxsw_sp *mlxsw_sp,
                                       struct net_device *br_dev)
 {
-       mlxsw_sp->master_bridge.dev = br_dev;
-       mlxsw_sp->master_bridge.ref_count++;
+       struct mlxsw_sp_upper *master_bridge = mlxsw_sp_master_bridge(mlxsw_sp);
+
+       master_bridge->dev = br_dev;
+       master_bridge->ref_count++;
 }
 
 static void mlxsw_sp_master_bridge_dec(struct mlxsw_sp *mlxsw_sp)
 {
-       if (--mlxsw_sp->master_bridge.ref_count == 0) {
-               mlxsw_sp->master_bridge.dev = NULL;
+       struct mlxsw_sp_upper *master_bridge = mlxsw_sp_master_bridge(mlxsw_sp);
+
+       if (--master_bridge->ref_count == 0) {
+               master_bridge->dev = NULL;
                /* It's possible upper VLAN devices are still holding
                 * references to underlying FIDs. Drop the reference
                 * and release the resources if it was the last one.
@@ -4272,7 +4276,7 @@ static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
                if (!is_vlan_dev(upper_dev))
                        return -EINVAL;
                if (is_vlan_dev(upper_dev) &&
-                   br_dev != mlxsw_sp->master_bridge.dev)
+                   br_dev != mlxsw_sp_master_bridge(mlxsw_sp)->dev)
                        return -EINVAL;
                break;
        case NETDEV_CHANGEUPPER:
index 2eb2230678aee0e641204ed72ceb042c5a23fe60..7c9e2f191b2ee5c66573c91a9d157e43fff9d0fb 100644 (file)
@@ -149,6 +149,7 @@ struct mlxsw_sp_port_mall_tc_entry {
 };
 
 struct mlxsw_sp_sb;
+struct mlxsw_sp_bridge;
 struct mlxsw_sp_router;
 struct mlxsw_sp_acl;
 struct mlxsw_sp_counter_pool;
@@ -158,29 +159,16 @@ struct mlxsw_sp {
                struct list_head list;
                DECLARE_BITMAP(mapped, MLXSW_SP_VFID_MAX);
        } vfids;
-       struct {
-               struct list_head list;
-               DECLARE_BITMAP(mapped, MLXSW_SP_MID_MAX);
-       } br_mids;
        struct list_head fids;  /* VLAN-aware bridge FIDs */
        struct mlxsw_sp_rif **rifs;
        struct mlxsw_sp_port **ports;
        struct mlxsw_core *core;
        const struct mlxsw_bus_info *bus_info;
        unsigned char base_mac[ETH_ALEN];
-       struct {
-               struct delayed_work dw;
-#define MLXSW_SP_DEFAULT_LEARNING_INTERVAL 100
-               unsigned int interval; /* ms */
-       } fdb_notify;
-#define MLXSW_SP_MIN_AGEING_TIME 10
-#define MLXSW_SP_MAX_AGEING_TIME 1000000
-#define MLXSW_SP_DEFAULT_AGEING_TIME 300
-       u32 ageing_time;
-       struct mlxsw_sp_upper master_bridge;
        struct mlxsw_sp_upper *lags;
        u8 *port_to_module;
        struct mlxsw_sp_sb *sb;
+       struct mlxsw_sp_bridge *bridge;
        struct mlxsw_sp_router *router;
        struct mlxsw_sp_acl *acl;
        struct {
@@ -425,6 +413,7 @@ int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port,
 u32 mlxsw_sp_cells_bytes(const struct mlxsw_sp *mlxsw_sp, u32 cells);
 u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes);
 
+struct mlxsw_sp_upper *mlxsw_sp_master_bridge(const struct mlxsw_sp *mlxsw_sp);
 int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp);
 int mlxsw_sp_port_vlan_init(struct mlxsw_sp_port *mlxsw_sp_port);
index 28f7f54c76f9a962d07d885dcb735778eaf7b507..434e091d340bcdfffd15b5b83636851fbcc2b2ad 100644 (file)
@@ -3193,7 +3193,7 @@ static struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp,
 
        if (is_vlan_dev(l3_dev))
                fid = vlan_dev_vlan_id(l3_dev);
-       else if (mlxsw_sp->master_bridge.dev == l3_dev)
+       else if (mlxsw_sp_master_bridge(mlxsw_sp)->dev == l3_dev)
                fid = 1;
        else
                return mlxsw_sp_vfid_find(mlxsw_sp, l3_dev);
@@ -3389,7 +3389,7 @@ static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev,
                return __mlxsw_sp_inetaddr_lag_event(vlan_dev, real_dev, event,
                                                     vid);
        else if (netif_is_bridge_master(real_dev) &&
-                mlxsw_sp->master_bridge.dev == real_dev)
+                mlxsw_sp_master_bridge(mlxsw_sp)->dev == real_dev)
                return mlxsw_sp_inetaddr_bridge_event(vlan_dev, real_dev,
                                                      event);
 
index 0d8411f1f954c5668bc3bd26f721589f2ccf205d..85790d38d2f0d7b6c3967dd5b3724dead9239d39 100644 (file)
 #include "core.h"
 #include "reg.h"
 
+struct mlxsw_sp_bridge {
+       struct mlxsw_sp *mlxsw_sp;
+       struct {
+               struct delayed_work dw;
+#define MLXSW_SP_DEFAULT_LEARNING_INTERVAL 100
+               unsigned int interval; /* ms */
+       } fdb_notify;
+#define MLXSW_SP_MIN_AGEING_TIME 10
+#define MLXSW_SP_MAX_AGEING_TIME 1000000
+#define MLXSW_SP_DEFAULT_AGEING_TIME 300
+       u32 ageing_time;
+       struct mlxsw_sp_upper master_bridge;
+       struct list_head mids_list;
+       DECLARE_BITMAP(mids_bitmap, MLXSW_SP_MID_MAX);
+};
+
+struct mlxsw_sp_upper *mlxsw_sp_master_bridge(const struct mlxsw_sp *mlxsw_sp)
+{
+       return &mlxsw_sp->bridge->master_bridge;
+}
+
 static u16 mlxsw_sp_port_vid_to_fid_get(struct mlxsw_sp_port *mlxsw_sp_port,
                                        u16 vid)
 {
@@ -397,7 +418,7 @@ static int mlxsw_sp_ageing_set(struct mlxsw_sp *mlxsw_sp, u32 ageing_time)
        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdat), sfdat_pl);
        if (err)
                return err;
-       mlxsw_sp->ageing_time = ageing_time;
+       mlxsw_sp->bridge->ageing_time = ageing_time;
        return 0;
 }
 
@@ -428,7 +449,8 @@ static int mlxsw_sp_port_attr_br_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port,
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
 
        /* SWITCHDEV_TRANS_PREPARE phase */
-       if ((!vlan_enabled) && (mlxsw_sp->master_bridge.dev == orig_dev)) {
+       if ((!vlan_enabled) &&
+           (mlxsw_sp->bridge->master_bridge.dev == orig_dev)) {
                netdev_err(mlxsw_sp_port->dev, "Bridge must be vlan-aware\n");
                return -EINVAL;
        }
@@ -1006,7 +1028,7 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_get(struct mlxsw_sp *mlxsw_sp,
 {
        struct mlxsw_sp_mid *mid;
 
-       list_for_each_entry(mid, &mlxsw_sp->br_mids.list, list) {
+       list_for_each_entry(mid, &mlxsw_sp->bridge->mids_list, list) {
                if (ether_addr_equal(mid->addr, addr) && mid->fid == fid)
                        return mid;
        }
@@ -1020,7 +1042,7 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
        struct mlxsw_sp_mid *mid;
        u16 mid_idx;
 
-       mid_idx = find_first_zero_bit(mlxsw_sp->br_mids.mapped,
+       mid_idx = find_first_zero_bit(mlxsw_sp->bridge->mids_bitmap,
                                      MLXSW_SP_MID_MAX);
        if (mid_idx == MLXSW_SP_MID_MAX)
                return NULL;
@@ -1029,12 +1051,12 @@ static struct mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
        if (!mid)
                return NULL;
 
-       set_bit(mid_idx, mlxsw_sp->br_mids.mapped);
+       set_bit(mid_idx, mlxsw_sp->bridge->mids_bitmap);
        ether_addr_copy(mid->addr, addr);
        mid->fid = fid;
        mid->mid = mid_idx;
        mid->ref_count = 0;
-       list_add_tail(&mid->list, &mlxsw_sp->br_mids.list);
+       list_add_tail(&mid->list, &mlxsw_sp->bridge->mids_list);
 
        return mid;
 }
@@ -1044,7 +1066,7 @@ static int __mlxsw_sp_mc_dec_ref(struct mlxsw_sp *mlxsw_sp,
 {
        if (--mid->ref_count == 0) {
                list_del(&mid->list);
-               clear_bit(mid->mid, mlxsw_sp->br_mids.mapped);
+               clear_bit(mid->mid, mlxsw_sp->bridge->mids_bitmap);
                kfree(mid);
                return 1;
        }
@@ -1600,12 +1622,15 @@ static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp,
 
 static void mlxsw_sp_fdb_notify_work_schedule(struct mlxsw_sp *mlxsw_sp)
 {
-       mlxsw_core_schedule_dw(&mlxsw_sp->fdb_notify.dw,
-                              msecs_to_jiffies(mlxsw_sp->fdb_notify.interval));
+       struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
+
+       mlxsw_core_schedule_dw(&bridge->fdb_notify.dw,
+                              msecs_to_jiffies(bridge->fdb_notify.interval));
 }
 
 static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
 {
+       struct mlxsw_sp_bridge *bridge;
        struct mlxsw_sp *mlxsw_sp;
        char *sfn_pl;
        u8 num_rec;
@@ -1616,7 +1641,8 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
        if (!sfn_pl)
                return;
 
-       mlxsw_sp = container_of(work, struct mlxsw_sp, fdb_notify.dw.work);
+       bridge = container_of(work, struct mlxsw_sp_bridge, fdb_notify.dw.work);
+       mlxsw_sp = bridge->mlxsw_sp;
 
        rtnl_lock();
        mlxsw_reg_sfn_pack(sfn_pl);
@@ -1637,6 +1663,7 @@ out:
 
 static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
 {
+       struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
        int err;
 
        err = mlxsw_sp_ageing_set(mlxsw_sp, MLXSW_SP_DEFAULT_AGEING_TIME);
@@ -1644,25 +1671,37 @@ static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
                dev_err(mlxsw_sp->bus_info->dev, "Failed to set default ageing time\n");
                return err;
        }
-       INIT_DELAYED_WORK(&mlxsw_sp->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
-       mlxsw_sp->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
+       INIT_DELAYED_WORK(&bridge->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
+       bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
        mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
        return 0;
 }
 
 static void mlxsw_sp_fdb_fini(struct mlxsw_sp *mlxsw_sp)
 {
-       cancel_delayed_work_sync(&mlxsw_sp->fdb_notify.dw);
+       cancel_delayed_work_sync(&mlxsw_sp->bridge->fdb_notify.dw);
 }
 
 int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp)
 {
+       struct mlxsw_sp_bridge *bridge;
+
+       bridge = kzalloc(sizeof(*mlxsw_sp->bridge), GFP_KERNEL);
+       if (!bridge)
+               return -ENOMEM;
+       mlxsw_sp->bridge = bridge;
+       bridge->mlxsw_sp = mlxsw_sp;
+
+       INIT_LIST_HEAD(&mlxsw_sp->bridge->mids_list);
+
        return mlxsw_sp_fdb_init(mlxsw_sp);
 }
 
 void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
 {
        mlxsw_sp_fdb_fini(mlxsw_sp);
+       WARN_ON(!list_empty(&mlxsw_sp->bridge->mids_list));
+       kfree(mlxsw_sp->bridge);
 }
 
 void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port)