diff options
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 55 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 4 |
2 files changed, 30 insertions, 29 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index bd8448afdf2c..e987a8afab48 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
| @@ -2235,7 +2235,7 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, | |||
| 2235 | mlxsw_sp->core = mlxsw_core; | 2235 | mlxsw_sp->core = mlxsw_core; |
| 2236 | mlxsw_sp->bus_info = mlxsw_bus_info; | 2236 | mlxsw_sp->bus_info = mlxsw_bus_info; |
| 2237 | INIT_LIST_HEAD(&mlxsw_sp->fids); | 2237 | INIT_LIST_HEAD(&mlxsw_sp->fids); |
| 2238 | INIT_LIST_HEAD(&mlxsw_sp->br_vfids.list); | 2238 | INIT_LIST_HEAD(&mlxsw_sp->vfids.list); |
| 2239 | INIT_LIST_HEAD(&mlxsw_sp->br_mids.list); | 2239 | INIT_LIST_HEAD(&mlxsw_sp->br_mids.list); |
| 2240 | 2240 | ||
| 2241 | err = mlxsw_sp_base_mac_get(mlxsw_sp); | 2241 | err = mlxsw_sp_base_mac_get(mlxsw_sp); |
| @@ -2320,6 +2320,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) | |||
| 2320 | mlxsw_sp_buffers_fini(mlxsw_sp); | 2320 | mlxsw_sp_buffers_fini(mlxsw_sp); |
| 2321 | mlxsw_sp_traps_fini(mlxsw_sp); | 2321 | mlxsw_sp_traps_fini(mlxsw_sp); |
| 2322 | mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE); | 2322 | mlxsw_sp_event_unregister(mlxsw_sp, MLXSW_TRAP_ID_PUDE); |
| 2323 | WARN_ON(!list_empty(&mlxsw_sp->vfids.list)); | ||
| 2323 | WARN_ON(!list_empty(&mlxsw_sp->fids)); | 2324 | WARN_ON(!list_empty(&mlxsw_sp->fids)); |
| 2324 | for (i = 0; i < MLXSW_SP_RIF_MAX; i++) | 2325 | for (i = 0; i < MLXSW_SP_RIF_MAX; i++) |
| 2325 | WARN_ON_ONCE(mlxsw_sp->rifs[i]); | 2326 | WARN_ON_ONCE(mlxsw_sp->rifs[i]); |
| @@ -3373,12 +3374,12 @@ static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev, | |||
| 3373 | } | 3374 | } |
| 3374 | 3375 | ||
| 3375 | static struct mlxsw_sp_fid * | 3376 | static struct mlxsw_sp_fid * |
| 3376 | mlxsw_sp_br_vfid_find(const struct mlxsw_sp *mlxsw_sp, | 3377 | mlxsw_sp_vfid_find(const struct mlxsw_sp *mlxsw_sp, |
| 3377 | const struct net_device *br_dev) | 3378 | const struct net_device *br_dev) |
| 3378 | { | 3379 | { |
| 3379 | struct mlxsw_sp_fid *f; | 3380 | struct mlxsw_sp_fid *f; |
| 3380 | 3381 | ||
| 3381 | list_for_each_entry(f, &mlxsw_sp->br_vfids.list, list) { | 3382 | list_for_each_entry(f, &mlxsw_sp->vfids.list, list) { |
| 3382 | if (f->dev == br_dev) | 3383 | if (f->dev == br_dev) |
| 3383 | return f; | 3384 | return f; |
| 3384 | } | 3385 | } |
| @@ -3386,9 +3387,9 @@ mlxsw_sp_br_vfid_find(const struct mlxsw_sp *mlxsw_sp, | |||
| 3386 | return NULL; | 3387 | return NULL; |
| 3387 | } | 3388 | } |
| 3388 | 3389 | ||
| 3389 | static u16 mlxsw_sp_avail_br_vfid_get(const struct mlxsw_sp *mlxsw_sp) | 3390 | static u16 mlxsw_sp_avail_vfid_get(const struct mlxsw_sp *mlxsw_sp) |
| 3390 | { | 3391 | { |
| 3391 | return find_first_zero_bit(mlxsw_sp->br_vfids.mapped, | 3392 | return find_first_zero_bit(mlxsw_sp->vfids.mapped, |
| 3392 | MLXSW_SP_VFID_MAX); | 3393 | MLXSW_SP_VFID_MAX); |
| 3393 | } | 3394 | } |
| 3394 | 3395 | ||
| @@ -3400,17 +3401,17 @@ static int mlxsw_sp_vfid_op(struct mlxsw_sp *mlxsw_sp, u16 fid, bool create) | |||
| 3400 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); | 3401 | return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); |
| 3401 | } | 3402 | } |
| 3402 | 3403 | ||
| 3403 | static void mlxsw_sp_vport_br_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport); | 3404 | static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport); |
| 3404 | 3405 | ||
| 3405 | static struct mlxsw_sp_fid *mlxsw_sp_br_vfid_create(struct mlxsw_sp *mlxsw_sp, | 3406 | static struct mlxsw_sp_fid *mlxsw_sp_vfid_create(struct mlxsw_sp *mlxsw_sp, |
| 3406 | struct net_device *br_dev) | 3407 | struct net_device *br_dev) |
| 3407 | { | 3408 | { |
| 3408 | struct device *dev = mlxsw_sp->bus_info->dev; | 3409 | struct device *dev = mlxsw_sp->bus_info->dev; |
| 3409 | struct mlxsw_sp_fid *f; | 3410 | struct mlxsw_sp_fid *f; |
| 3410 | u16 vfid, fid; | 3411 | u16 vfid, fid; |
| 3411 | int err; | 3412 | int err; |
| 3412 | 3413 | ||
| 3413 | vfid = mlxsw_sp_avail_br_vfid_get(mlxsw_sp); | 3414 | vfid = mlxsw_sp_avail_vfid_get(mlxsw_sp); |
| 3414 | if (vfid == MLXSW_SP_VFID_MAX) { | 3415 | if (vfid == MLXSW_SP_VFID_MAX) { |
| 3415 | dev_err(dev, "No available vFIDs\n"); | 3416 | dev_err(dev, "No available vFIDs\n"); |
| 3416 | return ERR_PTR(-ERANGE); | 3417 | return ERR_PTR(-ERANGE); |
| @@ -3427,12 +3428,12 @@ static struct mlxsw_sp_fid *mlxsw_sp_br_vfid_create(struct mlxsw_sp *mlxsw_sp, | |||
| 3427 | if (!f) | 3428 | if (!f) |
| 3428 | goto err_allocate_vfid; | 3429 | goto err_allocate_vfid; |
| 3429 | 3430 | ||
| 3430 | f->leave = mlxsw_sp_vport_br_vfid_leave; | 3431 | f->leave = mlxsw_sp_vport_vfid_leave; |
| 3431 | f->fid = fid; | 3432 | f->fid = fid; |
| 3432 | f->dev = br_dev; | 3433 | f->dev = br_dev; |
| 3433 | 3434 | ||
| 3434 | list_add(&f->list, &mlxsw_sp->br_vfids.list); | 3435 | list_add(&f->list, &mlxsw_sp->vfids.list); |
| 3435 | set_bit(vfid, mlxsw_sp->br_vfids.mapped); | 3436 | set_bit(vfid, mlxsw_sp->vfids.mapped); |
| 3436 | 3437 | ||
| 3437 | return f; | 3438 | return f; |
| 3438 | 3439 | ||
| @@ -3441,12 +3442,12 @@ err_allocate_vfid: | |||
| 3441 | return ERR_PTR(-ENOMEM); | 3442 | return ERR_PTR(-ENOMEM); |
| 3442 | } | 3443 | } |
| 3443 | 3444 | ||
| 3444 | static void mlxsw_sp_br_vfid_destroy(struct mlxsw_sp *mlxsw_sp, | 3445 | static void mlxsw_sp_vfid_destroy(struct mlxsw_sp *mlxsw_sp, |
| 3445 | struct mlxsw_sp_fid *f) | 3446 | struct mlxsw_sp_fid *f) |
| 3446 | { | 3447 | { |
| 3447 | u16 vfid = mlxsw_sp_fid_to_vfid(f->fid); | 3448 | u16 vfid = mlxsw_sp_fid_to_vfid(f->fid); |
| 3448 | 3449 | ||
| 3449 | clear_bit(vfid, mlxsw_sp->br_vfids.mapped); | 3450 | clear_bit(vfid, mlxsw_sp->vfids.mapped); |
| 3450 | list_del(&f->list); | 3451 | list_del(&f->list); |
| 3451 | 3452 | ||
| 3452 | mlxsw_sp_vfid_op(mlxsw_sp, f->fid, false); | 3453 | mlxsw_sp_vfid_op(mlxsw_sp, f->fid, false); |
| @@ -3464,15 +3465,15 @@ static int mlxsw_sp_vport_fid_map(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid, | |||
| 3464 | vid); | 3465 | vid); |
| 3465 | } | 3466 | } |
| 3466 | 3467 | ||
| 3467 | static int mlxsw_sp_vport_br_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport, | 3468 | static int mlxsw_sp_vport_vfid_join(struct mlxsw_sp_port *mlxsw_sp_vport, |
| 3468 | struct net_device *br_dev) | 3469 | struct net_device *br_dev) |
| 3469 | { | 3470 | { |
| 3470 | struct mlxsw_sp_fid *f; | 3471 | struct mlxsw_sp_fid *f; |
| 3471 | int err; | 3472 | int err; |
| 3472 | 3473 | ||
| 3473 | f = mlxsw_sp_br_vfid_find(mlxsw_sp_vport->mlxsw_sp, br_dev); | 3474 | f = mlxsw_sp_vfid_find(mlxsw_sp_vport->mlxsw_sp, br_dev); |
| 3474 | if (!f) { | 3475 | if (!f) { |
| 3475 | f = mlxsw_sp_br_vfid_create(mlxsw_sp_vport->mlxsw_sp, br_dev); | 3476 | f = mlxsw_sp_vfid_create(mlxsw_sp_vport->mlxsw_sp, br_dev); |
| 3476 | if (IS_ERR(f)) | 3477 | if (IS_ERR(f)) |
| 3477 | return PTR_ERR(f); | 3478 | return PTR_ERR(f); |
| 3478 | } | 3479 | } |
| @@ -3496,11 +3497,11 @@ err_vport_fid_map: | |||
| 3496 | mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false); | 3497 | mlxsw_sp_vport_flood_set(mlxsw_sp_vport, f->fid, false); |
| 3497 | err_vport_flood_set: | 3498 | err_vport_flood_set: |
| 3498 | if (!f->ref_count) | 3499 | if (!f->ref_count) |
| 3499 | mlxsw_sp_br_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f); | 3500 | mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f); |
| 3500 | return err; | 3501 | return err; |
| 3501 | } | 3502 | } |
| 3502 | 3503 | ||
| 3503 | static void mlxsw_sp_vport_br_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport) | 3504 | static void mlxsw_sp_vport_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport) |
| 3504 | { | 3505 | { |
| 3505 | struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); | 3506 | struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); |
| 3506 | 3507 | ||
| @@ -3514,7 +3515,7 @@ static void mlxsw_sp_vport_br_vfid_leave(struct mlxsw_sp_port *mlxsw_sp_vport) | |||
| 3514 | 3515 | ||
| 3515 | mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL); | 3516 | mlxsw_sp_vport_fid_set(mlxsw_sp_vport, NULL); |
| 3516 | if (--f->ref_count == 0) | 3517 | if (--f->ref_count == 0) |
| 3517 | mlxsw_sp_br_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f); | 3518 | mlxsw_sp_vfid_destroy(mlxsw_sp_vport->mlxsw_sp, f); |
| 3518 | } | 3519 | } |
| 3519 | 3520 | ||
| 3520 | static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport, | 3521 | static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport, |
| @@ -3528,7 +3529,7 @@ static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport, | |||
| 3528 | if (f && !WARN_ON(!f->leave)) | 3529 | if (f && !WARN_ON(!f->leave)) |
| 3529 | f->leave(mlxsw_sp_vport); | 3530 | f->leave(mlxsw_sp_vport); |
| 3530 | 3531 | ||
| 3531 | err = mlxsw_sp_vport_br_vfid_join(mlxsw_sp_vport, br_dev); | 3532 | err = mlxsw_sp_vport_vfid_join(mlxsw_sp_vport, br_dev); |
| 3532 | if (err) { | 3533 | if (err) { |
| 3533 | netdev_err(dev, "Failed to join vFID\n"); | 3534 | netdev_err(dev, "Failed to join vFID\n"); |
| 3534 | return err; | 3535 | return err; |
| @@ -3548,7 +3549,7 @@ static int mlxsw_sp_vport_bridge_join(struct mlxsw_sp_port *mlxsw_sp_vport, | |||
| 3548 | return 0; | 3549 | return 0; |
| 3549 | 3550 | ||
| 3550 | err_port_vid_learning_set: | 3551 | err_port_vid_learning_set: |
| 3551 | mlxsw_sp_vport_br_vfid_leave(mlxsw_sp_vport); | 3552 | mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport); |
| 3552 | return err; | 3553 | return err; |
| 3553 | } | 3554 | } |
| 3554 | 3555 | ||
| @@ -3558,7 +3559,7 @@ static void mlxsw_sp_vport_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_vport) | |||
| 3558 | 3559 | ||
| 3559 | mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false); | 3560 | mlxsw_sp_port_vid_learning_set(mlxsw_sp_vport, vid, false); |
| 3560 | 3561 | ||
| 3561 | mlxsw_sp_vport_br_vfid_leave(mlxsw_sp_vport); | 3562 | mlxsw_sp_vport_vfid_leave(mlxsw_sp_vport); |
| 3562 | 3563 | ||
| 3563 | mlxsw_sp_vport->learning = 0; | 3564 | mlxsw_sp_vport->learning = 0; |
| 3564 | mlxsw_sp_vport->learning_sync = 0; | 3565 | mlxsw_sp_vport->learning_sync = 0; |
| @@ -3574,7 +3575,7 @@ mlxsw_sp_port_master_bridge_check(const struct mlxsw_sp_port *mlxsw_sp_port, | |||
| 3574 | 3575 | ||
| 3575 | list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list, | 3576 | list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list, |
| 3576 | vport.list) { | 3577 | vport.list) { |
| 3577 | struct net_device *dev = mlxsw_sp_vport_br_get(mlxsw_sp_vport); | 3578 | struct net_device *dev = mlxsw_sp_vport_dev_get(mlxsw_sp_vport); |
| 3578 | 3579 | ||
| 3579 | if (dev && dev == br_dev) | 3580 | if (dev && dev == br_dev) |
| 3580 | return false; | 3581 | return false; |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index b6eeab744cda..b15b47b9161f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h | |||
| @@ -218,7 +218,7 @@ struct mlxsw_sp { | |||
| 218 | struct { | 218 | struct { |
| 219 | struct list_head list; | 219 | struct list_head list; |
| 220 | DECLARE_BITMAP(mapped, MLXSW_SP_VFID_MAX); | 220 | DECLARE_BITMAP(mapped, MLXSW_SP_VFID_MAX); |
| 221 | } br_vfids; | 221 | } vfids; |
| 222 | struct { | 222 | struct { |
| 223 | struct list_head list; | 223 | struct list_head list; |
| 224 | DECLARE_BITMAP(mapped, MLXSW_SP_MID_MAX); | 224 | DECLARE_BITMAP(mapped, MLXSW_SP_MID_MAX); |
| @@ -349,7 +349,7 @@ mlxsw_sp_vport_fid_get(const struct mlxsw_sp_port *mlxsw_sp_vport) | |||
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | static inline struct net_device * | 351 | static inline struct net_device * |
| 352 | mlxsw_sp_vport_br_get(const struct mlxsw_sp_port *mlxsw_sp_vport) | 352 | mlxsw_sp_vport_dev_get(const struct mlxsw_sp_port *mlxsw_sp_vport) |
| 353 | { | 353 | { |
| 354 | struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); | 354 | struct mlxsw_sp_fid *f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport); |
| 355 | 355 | ||
