Skip to content
/ linux Public

Commit 896f399

Browse files
idoschdavem330
authored andcommitted
mlxsw: Track per-module port status
In the common port module core, track the number of logical ports that are mapped to the port module and the number of logical ports using it that are administratively up. This will be used by later patches to potentially veto and control certain operations on the module, such as reset and setting its power mode. Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 196bff2 commit 896f399

File tree

4 files changed

+113
-9
lines changed

4 files changed

+113
-9
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_env.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
struct mlxsw_env_module_info {
1616
u64 module_overheat_counter;
1717
bool is_overheat;
18+
int num_ports_mapped;
19+
int num_ports_up;
1820
};
1921

2022
struct mlxsw_env {
@@ -708,6 +710,60 @@ mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
708710
}
709711
EXPORT_SYMBOL(mlxsw_env_module_overheat_counter_get);
710712

713+
void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 module)
714+
{
715+
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
716+
717+
if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
718+
return;
719+
720+
mutex_lock(&mlxsw_env->module_info_lock);
721+
mlxsw_env->module_info[module].num_ports_mapped++;
722+
mutex_unlock(&mlxsw_env->module_info_lock);
723+
}
724+
EXPORT_SYMBOL(mlxsw_env_module_port_map);
725+
726+
void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 module)
727+
{
728+
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
729+
730+
if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
731+
return;
732+
733+
mutex_lock(&mlxsw_env->module_info_lock);
734+
mlxsw_env->module_info[module].num_ports_mapped--;
735+
mutex_unlock(&mlxsw_env->module_info_lock);
736+
}
737+
EXPORT_SYMBOL(mlxsw_env_module_port_unmap);
738+
739+
int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 module)
740+
{
741+
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
742+
743+
if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
744+
return -EINVAL;
745+
746+
mutex_lock(&mlxsw_env->module_info_lock);
747+
mlxsw_env->module_info[module].num_ports_up++;
748+
mutex_unlock(&mlxsw_env->module_info_lock);
749+
750+
return 0;
751+
}
752+
EXPORT_SYMBOL(mlxsw_env_module_port_up);
753+
754+
void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 module)
755+
{
756+
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
757+
758+
if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
759+
return;
760+
761+
mutex_lock(&mlxsw_env->module_info_lock);
762+
mlxsw_env->module_info[module].num_ports_up--;
763+
mutex_unlock(&mlxsw_env->module_info_lock);
764+
}
765+
EXPORT_SYMBOL(mlxsw_env_module_port_down);
766+
711767
int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
712768
{
713769
char mgpir_pl[MLXSW_REG_MGPIR_LEN];

drivers/net/ethernet/mellanox/mlxsw/core_env.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module,
2727
int
2828
mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
2929
u64 *p_counter);
30+
31+
void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 module);
32+
33+
void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 module);
34+
35+
int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 module);
36+
37+
void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 module);
38+
3039
int mlxsw_env_init(struct mlxsw_core *core, struct mlxsw_env **p_env);
3140
void mlxsw_env_fini(struct mlxsw_env *env);
3241

drivers/net/ethernet/mellanox/mlxsw/minimal.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,20 @@ static int mlxsw_m_base_mac_get(struct mlxsw_m *mlxsw_m)
5454
return 0;
5555
}
5656

57-
static int mlxsw_m_port_dummy_open_stop(struct net_device *dev)
57+
static int mlxsw_m_port_open(struct net_device *dev)
5858
{
59+
struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
60+
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
61+
62+
return mlxsw_env_module_port_up(mlxsw_m->core, mlxsw_m_port->module);
63+
}
64+
65+
static int mlxsw_m_port_stop(struct net_device *dev)
66+
{
67+
struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
68+
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
69+
70+
mlxsw_env_module_port_down(mlxsw_m->core, mlxsw_m_port->module);
5971
return 0;
6072
}
6173

@@ -70,8 +82,8 @@ mlxsw_m_port_get_devlink_port(struct net_device *dev)
7082
}
7183

7284
static const struct net_device_ops mlxsw_m_port_netdev_ops = {
73-
.ndo_open = mlxsw_m_port_dummy_open_stop,
74-
.ndo_stop = mlxsw_m_port_dummy_open_stop,
85+
.ndo_open = mlxsw_m_port_open,
86+
.ndo_stop = mlxsw_m_port_stop,
7587
.ndo_get_devlink_port = mlxsw_m_port_get_devlink_port,
7688
};
7789

@@ -266,6 +278,7 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u8 local_port,
266278

267279
if (WARN_ON_ONCE(module >= max_ports))
268280
return -EINVAL;
281+
mlxsw_env_module_port_map(mlxsw_m->core, module);
269282
mlxsw_m->module_to_port[module] = ++mlxsw_m->max_ports;
270283

271284
return 0;
@@ -274,6 +287,7 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u8 local_port,
274287
static void mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 module)
275288
{
276289
mlxsw_m->module_to_port[module] = -1;
290+
mlxsw_env_module_port_unmap(mlxsw_m->core, module);
277291
}
278292

279293
static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,9 @@ mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port,
539539
const struct mlxsw_sp_port_mapping *port_mapping)
540540
{
541541
char pmlp_pl[MLXSW_REG_PMLP_LEN];
542-
int i;
542+
int i, err;
543+
544+
mlxsw_env_module_port_map(mlxsw_sp->core, port_mapping->module);
543545

544546
mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
545547
mlxsw_reg_pmlp_width_set(pmlp_pl, port_mapping->width);
@@ -548,36 +550,58 @@ mlxsw_sp_port_module_map(struct mlxsw_sp *mlxsw_sp, u8 local_port,
548550
mlxsw_reg_pmlp_tx_lane_set(pmlp_pl, i, port_mapping->lane + i); /* Rx & Tx */
549551
}
550552

551-
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
553+
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
554+
if (err)
555+
goto err_pmlp_write;
556+
return 0;
557+
558+
err_pmlp_write:
559+
mlxsw_env_module_port_unmap(mlxsw_sp->core, port_mapping->module);
560+
return err;
552561
}
553562

554-
static void mlxsw_sp_port_module_unmap(struct mlxsw_sp *mlxsw_sp, u8 local_port)
563+
static void mlxsw_sp_port_module_unmap(struct mlxsw_sp *mlxsw_sp, u8 local_port,
564+
u8 module)
555565
{
556566
char pmlp_pl[MLXSW_REG_PMLP_LEN];
557567

558568
mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
559569
mlxsw_reg_pmlp_width_set(pmlp_pl, 0);
560570
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pmlp), pmlp_pl);
571+
mlxsw_env_module_port_unmap(mlxsw_sp->core, module);
561572
}
562573

563574
static int mlxsw_sp_port_open(struct net_device *dev)
564575
{
565576
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
577+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
566578
int err;
567579

568-
err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
580+
err = mlxsw_env_module_port_up(mlxsw_sp->core,
581+
mlxsw_sp_port->mapping.module);
569582
if (err)
570583
return err;
584+
err = mlxsw_sp_port_admin_status_set(mlxsw_sp_port, true);
585+
if (err)
586+
goto err_port_admin_status_set;
571587
netif_start_queue(dev);
572588
return 0;
589+
590+
err_port_admin_status_set:
591+
mlxsw_env_module_port_down(mlxsw_sp->core,
592+
mlxsw_sp_port->mapping.module);
593+
return err;
573594
}
574595

575596
static int mlxsw_sp_port_stop(struct net_device *dev)
576597
{
577598
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
599+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
578600

579601
netif_stop_queue(dev);
580602
mlxsw_sp_port_admin_status_set(mlxsw_sp_port, false);
603+
mlxsw_env_module_port_down(mlxsw_sp->core,
604+
mlxsw_sp_port->mapping.module);
581605
return 0;
582606
}
583607

@@ -1747,13 +1771,14 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
17471771
mlxsw_sp_port_swid_set(mlxsw_sp, local_port,
17481772
MLXSW_PORT_SWID_DISABLED_PORT);
17491773
err_port_swid_set:
1750-
mlxsw_sp_port_module_unmap(mlxsw_sp, local_port);
1774+
mlxsw_sp_port_module_unmap(mlxsw_sp, local_port, port_mapping->module);
17511775
return err;
17521776
}
17531777

17541778
static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
17551779
{
17561780
struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
1781+
u8 module = mlxsw_sp_port->mapping.module;
17571782

17581783
cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw);
17591784
cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw);
@@ -1775,7 +1800,7 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
17751800
mlxsw_core_port_fini(mlxsw_sp->core, local_port);
17761801
mlxsw_sp_port_swid_set(mlxsw_sp, local_port,
17771802
MLXSW_PORT_SWID_DISABLED_PORT);
1778-
mlxsw_sp_port_module_unmap(mlxsw_sp, local_port);
1803+
mlxsw_sp_port_module_unmap(mlxsw_sp, local_port, module);
17791804
}
17801805

17811806
static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp)

0 commit comments

Comments
 (0)