Skip to content

Commit 01328e2

Browse files
vadimp-nvidiakuba-moo
authored andcommitted
mlxsw: minimal: Extend module to port mapping with slot index
The interfaces for ports found on line card are created and removed dynamically after line card is getting active or inactive. Introduce per line card array with module to port mapping. For each port get 'slot_index' through PMLP register and set port mapping for the relevant [slot_index][module] entry. Split module and port allocation into separate routines. Split per line card port creation and removing into separate routines. Motivation to re-use these routines for line card operations. Signed-off-by: Vadim Pasternak <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Petr Machata <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 9421c8b commit 01328e2

File tree

1 file changed

+163
-52
lines changed

1 file changed

+163
-52
lines changed

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

Lines changed: 163 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,20 @@ static const struct mlxsw_fw_rev mlxsw_m_fw_rev = {
2626

2727
struct mlxsw_m_port;
2828

29+
struct mlxsw_m_line_card {
30+
bool active;
31+
int module_to_port[];
32+
};
33+
2934
struct mlxsw_m {
3035
struct mlxsw_m_port **ports;
31-
int *module_to_port;
3236
struct mlxsw_core *core;
3337
const struct mlxsw_bus_info *bus_info;
3438
u8 base_mac[ETH_ALEN];
3539
u8 max_ports;
40+
u8 max_modules_per_slot; /* Maximum number of modules per-slot. */
41+
u8 num_of_slots; /* Including the main board. */
42+
struct mlxsw_m_line_card **line_cards;
3643
};
3744

3845
struct mlxsw_m_port {
@@ -191,7 +198,7 @@ static const struct ethtool_ops mlxsw_m_port_ethtool_ops = {
191198

192199
static int
193200
mlxsw_m_port_module_info_get(struct mlxsw_m *mlxsw_m, u16 local_port,
194-
u8 *p_module, u8 *p_width)
201+
u8 *p_module, u8 *p_width, u8 *p_slot_index)
195202
{
196203
char pmlp_pl[MLXSW_REG_PMLP_LEN];
197204
int err;
@@ -202,6 +209,7 @@ mlxsw_m_port_module_info_get(struct mlxsw_m *mlxsw_m, u16 local_port,
202209
return err;
203210
*p_module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
204211
*p_width = mlxsw_reg_pmlp_width_get(pmlp_pl);
212+
*p_slot_index = mlxsw_reg_pmlp_slot_index_get(pmlp_pl, 0);
205213

206214
return 0;
207215
}
@@ -223,6 +231,11 @@ mlxsw_m_port_dev_addr_get(struct mlxsw_m_port *mlxsw_m_port)
223231
return 0;
224232
}
225233

234+
static bool mlxsw_m_port_created(struct mlxsw_m *mlxsw_m, u16 local_port)
235+
{
236+
return mlxsw_m->ports[local_port];
237+
}
238+
226239
static int
227240
mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u16 local_port, u8 slot_index,
228241
u8 module)
@@ -300,16 +313,23 @@ static void mlxsw_m_port_remove(struct mlxsw_m *mlxsw_m, u16 local_port)
300313
mlxsw_core_port_fini(mlxsw_m->core, local_port);
301314
}
302315

316+
static int*
317+
mlxsw_m_port_mapping_get(struct mlxsw_m *mlxsw_m, u8 slot_index, u8 module)
318+
{
319+
return &mlxsw_m->line_cards[slot_index]->module_to_port[module];
320+
}
321+
303322
static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u16 local_port,
304323
u8 *last_module)
305324
{
306325
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
307-
u8 module, width;
326+
u8 module, width, slot_index;
327+
int *module_to_port;
308328
int err;
309329

310330
/* Fill out to local port mapping array */
311331
err = mlxsw_m_port_module_info_get(mlxsw_m, local_port, &module,
312-
&width);
332+
&width, &slot_index);
313333
if (err)
314334
return err;
315335

@@ -322,107 +342,198 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u16 local_port,
322342

323343
if (WARN_ON_ONCE(module >= max_ports))
324344
return -EINVAL;
325-
mlxsw_env_module_port_map(mlxsw_m->core, 0, module);
326-
mlxsw_m->module_to_port[module] = ++mlxsw_m->max_ports;
345+
mlxsw_env_module_port_map(mlxsw_m->core, slot_index, module);
346+
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, module);
347+
*module_to_port = local_port;
327348

328349
return 0;
329350
}
330351

331352
static void
332353
mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index, u8 module)
333354
{
334-
mlxsw_m->module_to_port[module] = -1;
355+
int *module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
356+
module);
357+
*module_to_port = -1;
335358
mlxsw_env_module_port_unmap(mlxsw_m->core, slot_index, module);
336359
}
337360

338361
static int mlxsw_m_linecards_init(struct mlxsw_m *mlxsw_m)
339362
{
340363
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
341-
int i, err;
364+
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
365+
u8 num_of_modules;
366+
int i, j, err;
367+
368+
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
369+
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mgpir), mgpir_pl);
370+
if (err)
371+
return err;
372+
373+
mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, &num_of_modules,
374+
&mlxsw_m->num_of_slots);
375+
/* If the system is modular, get the maximum number of modules per-slot.
376+
* Otherwise, get the maximum number of modules on the main board.
377+
*/
378+
if (mlxsw_m->num_of_slots)
379+
mlxsw_m->max_modules_per_slot =
380+
mlxsw_reg_mgpir_max_modules_per_slot_get(mgpir_pl);
381+
else
382+
mlxsw_m->max_modules_per_slot = num_of_modules;
383+
/* Add slot for main board. */
384+
mlxsw_m->num_of_slots += 1;
342385

343386
mlxsw_m->ports = kcalloc(max_ports, sizeof(*mlxsw_m->ports),
344387
GFP_KERNEL);
345388
if (!mlxsw_m->ports)
346389
return -ENOMEM;
347390

348-
mlxsw_m->module_to_port = kmalloc_array(max_ports, sizeof(int),
349-
GFP_KERNEL);
350-
if (!mlxsw_m->module_to_port) {
351-
err = -ENOMEM;
352-
goto err_module_to_port_alloc;
391+
mlxsw_m->line_cards = kcalloc(mlxsw_m->num_of_slots,
392+
sizeof(*mlxsw_m->line_cards),
393+
GFP_KERNEL);
394+
if (!mlxsw_m->line_cards)
395+
goto err_kcalloc;
396+
397+
for (i = 0; i < mlxsw_m->num_of_slots; i++) {
398+
mlxsw_m->line_cards[i] =
399+
kzalloc(struct_size(mlxsw_m->line_cards[i],
400+
module_to_port,
401+
mlxsw_m->max_modules_per_slot),
402+
GFP_KERNEL);
403+
if (!mlxsw_m->line_cards[i])
404+
goto err_kmalloc_array;
405+
406+
/* Invalidate the entries of module to local port mapping array. */
407+
for (j = 0; j < mlxsw_m->max_modules_per_slot; j++)
408+
mlxsw_m->line_cards[i]->module_to_port[j] = -1;
353409
}
354410

355-
/* Invalidate the entries of module to local port mapping array */
356-
for (i = 0; i < max_ports; i++)
357-
mlxsw_m->module_to_port[i] = -1;
358-
359411
return 0;
360412

361-
err_module_to_port_alloc:
413+
err_kmalloc_array:
414+
for (i--; i >= 0; i--)
415+
kfree(mlxsw_m->line_cards[i]);
416+
err_kcalloc:
362417
kfree(mlxsw_m->ports);
363418
return err;
364419
}
365420

366421
static void mlxsw_m_linecards_fini(struct mlxsw_m *mlxsw_m)
367422
{
368-
kfree(mlxsw_m->module_to_port);
423+
int i = mlxsw_m->num_of_slots;
424+
425+
for (i--; i >= 0; i--)
426+
kfree(mlxsw_m->line_cards[i]);
427+
kfree(mlxsw_m->line_cards);
369428
kfree(mlxsw_m->ports);
370429
}
371430

372-
static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
431+
static void
432+
mlxsw_m_linecard_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index)
373433
{
374-
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
375-
u8 last_module = max_ports;
376434
int i;
377-
int err;
378435

379-
/* Fill out module to local port mapping array */
380-
for (i = 1; i < max_ports; i++) {
381-
err = mlxsw_m_port_module_map(mlxsw_m, i, &last_module);
382-
if (err)
383-
goto err_module_to_port_map;
436+
for (i = mlxsw_m->max_modules_per_slot - 1; i >= 0; i--) {
437+
int *module_to_port;
438+
439+
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
440+
if (*module_to_port > 0)
441+
mlxsw_m_port_module_unmap(mlxsw_m, slot_index, i);
384442
}
443+
}
385444

386-
/* Create port objects for each valid entry */
387-
for (i = 0; i < mlxsw_m->max_ports; i++) {
388-
if (mlxsw_m->module_to_port[i] > 0) {
389-
err = mlxsw_m_port_create(mlxsw_m,
390-
mlxsw_m->module_to_port[i],
391-
0, i);
445+
static int
446+
mlxsw_m_linecard_ports_create(struct mlxsw_m *mlxsw_m, u8 slot_index)
447+
{
448+
int *module_to_port;
449+
int i, err;
450+
451+
for (i = 0; i < mlxsw_m->max_modules_per_slot; i++) {
452+
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
453+
if (*module_to_port > 0) {
454+
err = mlxsw_m_port_create(mlxsw_m, *module_to_port,
455+
slot_index, i);
392456
if (err)
393-
goto err_module_to_port_create;
457+
goto err_port_create;
458+
/* Mark slot as active */
459+
if (!mlxsw_m->line_cards[slot_index]->active)
460+
mlxsw_m->line_cards[slot_index]->active = true;
394461
}
395462
}
396-
397463
return 0;
398464

399-
err_module_to_port_create:
465+
err_port_create:
400466
for (i--; i >= 0; i--) {
401-
if (mlxsw_m->module_to_port[i] > 0)
402-
mlxsw_m_port_remove(mlxsw_m,
403-
mlxsw_m->module_to_port[i]);
467+
module_to_port = mlxsw_m_port_mapping_get(mlxsw_m, slot_index, i);
468+
if (*module_to_port > 0 &&
469+
mlxsw_m_port_created(mlxsw_m, *module_to_port)) {
470+
mlxsw_m_port_remove(mlxsw_m, *module_to_port);
471+
/* Mark slot as inactive */
472+
if (mlxsw_m->line_cards[slot_index]->active)
473+
mlxsw_m->line_cards[slot_index]->active = false;
474+
}
404475
}
405-
i = max_ports;
406-
err_module_to_port_map:
407-
for (i--; i > 0; i--)
408-
mlxsw_m_port_module_unmap(mlxsw_m, 0, i);
409476
return err;
410477
}
411478

412-
static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
479+
static void
480+
mlxsw_m_linecard_ports_remove(struct mlxsw_m *mlxsw_m, u8 slot_index)
413481
{
414482
int i;
415483

416-
for (i = 0; i < mlxsw_m->max_ports; i++) {
417-
if (mlxsw_m->module_to_port[i] > 0) {
418-
mlxsw_m_port_remove(mlxsw_m,
419-
mlxsw_m->module_to_port[i]);
420-
mlxsw_m_port_module_unmap(mlxsw_m, 0, i);
484+
for (i = 0; i < mlxsw_m->max_modules_per_slot; i++) {
485+
int *module_to_port = mlxsw_m_port_mapping_get(mlxsw_m,
486+
slot_index, i);
487+
488+
if (*module_to_port > 0 &&
489+
mlxsw_m_port_created(mlxsw_m, *module_to_port)) {
490+
mlxsw_m_port_remove(mlxsw_m, *module_to_port);
491+
mlxsw_m_port_module_unmap(mlxsw_m, slot_index, i);
421492
}
422493
}
494+
}
423495

424-
kfree(mlxsw_m->module_to_port);
425-
kfree(mlxsw_m->ports);
496+
static int mlxsw_m_ports_module_map(struct mlxsw_m *mlxsw_m)
497+
{
498+
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
499+
u8 last_module = max_ports;
500+
int i, err;
501+
502+
for (i = 1; i < max_ports; i++) {
503+
err = mlxsw_m_port_module_map(mlxsw_m, i, &last_module);
504+
if (err)
505+
return err;
506+
}
507+
508+
return 0;
509+
}
510+
511+
static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
512+
{
513+
int err;
514+
515+
/* Fill out module to local port mapping array */
516+
err = mlxsw_m_ports_module_map(mlxsw_m);
517+
if (err)
518+
goto err_ports_module_map;
519+
520+
/* Create port objects for each valid entry */
521+
err = mlxsw_m_linecard_ports_create(mlxsw_m, 0);
522+
if (err)
523+
goto err_linecard_ports_create;
524+
525+
return 0;
526+
527+
err_linecard_ports_create:
528+
err_ports_module_map:
529+
mlxsw_m_linecard_port_module_unmap(mlxsw_m, 0);
530+
531+
return err;
532+
}
533+
534+
static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
535+
{
536+
mlxsw_m_linecard_ports_remove(mlxsw_m, 0);
426537
}
427538

428539
static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)

0 commit comments

Comments
 (0)