aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2016-08-24 05:18:51 -0400
committerDavid S. Miller <davem@davemloft.net>2016-08-24 12:39:03 -0400
commitf888f58795b640442165e60a6fa93e8e623d01a5 (patch)
treec3cf1d4eeecd2b51a682a50c6674177b71122096
parentd7226c7a4dd19929d6df4ae04698da2fcf6f875a (diff)
mlxsw: spectrum: Add missing flood to router port
In case we have a layer 3 interface on top of a bridge (VLAN / FID RIF), then we should flood the following packet types to the router: * Broadcast: If DIP is the broadcast address of the interface, then we need to be able to get it to CPU by trapping it following route lookup. * Reserved IP multicast (224.0.0.X): Some control packets (e.g. OSPF) use this range and are trapped in the router block. Fixes: 99f44bb3527b ("mlxsw: spectrum: Enable L3 interfaces on top of bridge devices") 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>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/port.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c43
2 files changed, 43 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/port.h b/drivers/net/ethernet/mellanox/mlxsw/port.h
index f33b997f2b61..af371a82c35b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/port.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/port.h
@@ -56,6 +56,7 @@
56#define MLXSW_PORT_PHY_BITS_MASK (MLXSW_PORT_MAX_PHY_PORTS - 1) 56#define MLXSW_PORT_PHY_BITS_MASK (MLXSW_PORT_MAX_PHY_PORTS - 1)
57 57
58#define MLXSW_PORT_CPU_PORT 0x0 58#define MLXSW_PORT_CPU_PORT 0x0
59#define MLXSW_PORT_ROUTER_PORT (MLXSW_PORT_MAX_PHY_PORTS + 2)
59 60
60#define MLXSW_PORT_DONT_CARE (MLXSW_PORT_MAX_PORTS) 61#define MLXSW_PORT_DONT_CARE (MLXSW_PORT_MAX_PORTS)
61 62
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 1f8168906811..7291f2c4b0c7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3324,6 +3324,39 @@ static struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp,
3324 return mlxsw_sp_fid_find(mlxsw_sp, fid); 3324 return mlxsw_sp_fid_find(mlxsw_sp, fid);
3325} 3325}
3326 3326
3327static enum mlxsw_flood_table_type mlxsw_sp_flood_table_type_get(u16 fid)
3328{
3329 return mlxsw_sp_fid_is_vfid(fid) ? MLXSW_REG_SFGC_TABLE_TYPE_FID :
3330 MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFEST;
3331}
3332
3333static u16 mlxsw_sp_flood_table_index_get(u16 fid)
3334{
3335 return mlxsw_sp_fid_is_vfid(fid) ? mlxsw_sp_fid_to_vfid(fid) : fid;
3336}
3337
3338static int mlxsw_sp_router_port_flood_set(struct mlxsw_sp *mlxsw_sp, u16 fid,
3339 bool set)
3340{
3341 enum mlxsw_flood_table_type table_type;
3342 char *sftr_pl;
3343 u16 index;
3344 int err;
3345
3346 sftr_pl = kmalloc(MLXSW_REG_SFTR_LEN, GFP_KERNEL);
3347 if (!sftr_pl)
3348 return -ENOMEM;
3349
3350 table_type = mlxsw_sp_flood_table_type_get(fid);
3351 index = mlxsw_sp_flood_table_index_get(fid);
3352 mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_BM, index, table_type,
3353 1, MLXSW_PORT_ROUTER_PORT, set);
3354 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl);
3355
3356 kfree(sftr_pl);
3357 return err;
3358}
3359
3327static enum mlxsw_reg_ritr_if_type mlxsw_sp_rif_type_get(u16 fid) 3360static enum mlxsw_reg_ritr_if_type mlxsw_sp_rif_type_get(u16 fid)
3328{ 3361{
3329 if (mlxsw_sp_fid_is_vfid(fid)) 3362 if (mlxsw_sp_fid_is_vfid(fid))
@@ -3360,10 +3393,14 @@ static int mlxsw_sp_rif_bridge_create(struct mlxsw_sp *mlxsw_sp,
3360 if (rif == MLXSW_SP_RIF_MAX) 3393 if (rif == MLXSW_SP_RIF_MAX)
3361 return -ERANGE; 3394 return -ERANGE;
3362 3395
3363 err = mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, true); 3396 err = mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, true);
3364 if (err) 3397 if (err)
3365 return err; 3398 return err;
3366 3399
3400 err = mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, true);
3401 if (err)
3402 goto err_rif_bridge_op;
3403
3367 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, true); 3404 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, true);
3368 if (err) 3405 if (err)
3369 goto err_rif_fdb_op; 3406 goto err_rif_fdb_op;
@@ -3385,6 +3422,8 @@ err_rif_alloc:
3385 mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false); 3422 mlxsw_sp_rif_fdb_op(mlxsw_sp, l3_dev->dev_addr, f->fid, false);
3386err_rif_fdb_op: 3423err_rif_fdb_op:
3387 mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false); 3424 mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false);
3425err_rif_bridge_op:
3426 mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, false);
3388 return err; 3427 return err;
3389} 3428}
3390 3429
@@ -3404,6 +3443,8 @@ void mlxsw_sp_rif_bridge_destroy(struct mlxsw_sp *mlxsw_sp,
3404 3443
3405 mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false); 3444 mlxsw_sp_rif_bridge_op(mlxsw_sp, l3_dev, f->fid, rif, false);
3406 3445
3446 mlxsw_sp_router_port_flood_set(mlxsw_sp, f->fid, false);
3447
3407 netdev_dbg(l3_dev, "RIF=%d destroyed\n", rif); 3448 netdev_dbg(l3_dev, "RIF=%d destroyed\n", rif);
3408} 3449}
3409 3450