Skip to content

Commit 5ec2ee7

Browse files
idoschdavem330
authored andcommitted
mlxsw: Query maximum number of ports from firmware
We currently hard code the maximum number of ports in the driver, but this may change in future devices, so query it from the firmware instead. Fallback to a maximum of 64 ports in case this number can't be queried. This should only happen in SwitchX-2 for which this number is correct. 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>
1 parent 8494ab0 commit 5ec2ee7

File tree

9 files changed

+125
-45
lines changed

9 files changed

+125
-45
lines changed

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

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,42 @@ struct mlxsw_core {
110110
struct mlxsw_res res;
111111
struct mlxsw_hwmon *hwmon;
112112
struct mlxsw_thermal *thermal;
113-
struct mlxsw_core_port ports[MLXSW_PORT_MAX_PORTS];
113+
struct mlxsw_core_port *ports;
114+
unsigned int max_ports;
114115
unsigned long driver_priv[0];
115116
/* driver_priv has to be always the last item */
116117
};
117118

119+
#define MLXSW_PORT_MAX_PORTS_DEFAULT 0x40
120+
121+
static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core)
122+
{
123+
/* Switch ports are numbered from 1 to queried value */
124+
if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_SYSTEM_PORT))
125+
mlxsw_core->max_ports = MLXSW_CORE_RES_GET(mlxsw_core,
126+
MAX_SYSTEM_PORT) + 1;
127+
else
128+
mlxsw_core->max_ports = MLXSW_PORT_MAX_PORTS_DEFAULT + 1;
129+
130+
mlxsw_core->ports = kcalloc(mlxsw_core->max_ports,
131+
sizeof(struct mlxsw_core_port), GFP_KERNEL);
132+
if (!mlxsw_core->ports)
133+
return -ENOMEM;
134+
135+
return 0;
136+
}
137+
138+
static void mlxsw_ports_fini(struct mlxsw_core *mlxsw_core)
139+
{
140+
kfree(mlxsw_core->ports);
141+
}
142+
143+
unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core)
144+
{
145+
return mlxsw_core->max_ports;
146+
}
147+
EXPORT_SYMBOL(mlxsw_core_max_ports);
148+
118149
void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core)
119150
{
120151
return mlxsw_core->driver_priv;
@@ -733,7 +764,7 @@ static int mlxsw_devlink_port_split(struct devlink *devlink,
733764
{
734765
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
735766

736-
if (port_index >= MLXSW_PORT_MAX_PORTS)
767+
if (port_index >= mlxsw_core->max_ports)
737768
return -EINVAL;
738769
if (!mlxsw_core->driver->port_split)
739770
return -EOPNOTSUPP;
@@ -745,7 +776,7 @@ static int mlxsw_devlink_port_unsplit(struct devlink *devlink,
745776
{
746777
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
747778

748-
if (port_index >= MLXSW_PORT_MAX_PORTS)
779+
if (port_index >= mlxsw_core->max_ports)
749780
return -EINVAL;
750781
if (!mlxsw_core->driver->port_unsplit)
751782
return -EOPNOTSUPP;
@@ -972,6 +1003,10 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
9721003
if (err)
9731004
goto err_bus_init;
9741005

1006+
err = mlxsw_ports_init(mlxsw_core);
1007+
if (err)
1008+
goto err_ports_init;
1009+
9751010
if (MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG) &&
9761011
MLXSW_CORE_RES_VALID(mlxsw_core, MAX_LAG_MEMBERS)) {
9771012
alloc_size = sizeof(u8) *
@@ -1019,6 +1054,8 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
10191054
err_emad_init:
10201055
kfree(mlxsw_core->lag.mapping);
10211056
err_alloc_lag_mapping:
1057+
mlxsw_ports_fini(mlxsw_core);
1058+
err_ports_init:
10221059
mlxsw_bus->fini(bus_priv);
10231060
err_bus_init:
10241061
devlink_free(devlink);
@@ -1039,6 +1076,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core)
10391076
devlink_unregister(devlink);
10401077
mlxsw_emad_fini(mlxsw_core);
10411078
kfree(mlxsw_core->lag.mapping);
1079+
mlxsw_ports_fini(mlxsw_core);
10421080
mlxsw_core->bus->fini(mlxsw_core->bus_priv);
10431081
devlink_free(devlink);
10441082
mlxsw_core_driver_put(device_kind);
@@ -1508,7 +1546,7 @@ void mlxsw_core_skb_receive(struct mlxsw_core *mlxsw_core, struct sk_buff *skb,
15081546
__func__, local_port, rx_info->trap_id);
15091547

15101548
if ((rx_info->trap_id >= MLXSW_TRAP_ID_MAX) ||
1511-
(local_port >= MLXSW_PORT_MAX_PORTS))
1549+
(local_port >= mlxsw_core->max_ports))
15121550
goto drop;
15131551

15141552
rcu_read_lock();

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ struct mlxsw_driver;
5757
struct mlxsw_bus;
5858
struct mlxsw_bus_info;
5959

60+
unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
61+
6062
void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
6163

6264
int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,12 @@
4949

5050
#define MLXSW_PORT_MID 0xd000
5151

52-
#define MLXSW_PORT_MAX_PHY_PORTS 0x40
53-
#define MLXSW_PORT_MAX_PORTS (MLXSW_PORT_MAX_PHY_PORTS + 1)
54-
5552
#define MLXSW_PORT_MAX_IB_PHY_PORTS 36
5653
#define MLXSW_PORT_MAX_IB_PORTS (MLXSW_PORT_MAX_IB_PHY_PORTS + 1)
5754

58-
#define MLXSW_PORT_DEVID_BITS_OFFSET 10
59-
#define MLXSW_PORT_PHY_BITS_OFFSET 4
60-
#define MLXSW_PORT_PHY_BITS_MASK (MLXSW_PORT_MAX_PHY_PORTS - 1)
61-
6255
#define MLXSW_PORT_CPU_PORT 0x0
63-
#define MLXSW_PORT_ROUTER_PORT (MLXSW_PORT_MAX_PHY_PORTS + 2)
6456

65-
#define MLXSW_PORT_DONT_CARE (MLXSW_PORT_MAX_PORTS)
57+
#define MLXSW_PORT_DONT_CARE 0xFF
6658

6759
#define MLXSW_PORT_MODULE_MAX_WIDTH 4
6860

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2595,25 +2595,33 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
25952595
{
25962596
int i;
25972597

2598-
for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++)
2598+
for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++)
25992599
if (mlxsw_sp_port_created(mlxsw_sp, i))
26002600
mlxsw_sp_port_remove(mlxsw_sp, i);
2601+
kfree(mlxsw_sp->port_to_module);
26012602
kfree(mlxsw_sp->ports);
26022603
}
26032604

26042605
static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
26052606
{
2607+
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
26062608
u8 module, width, lane;
26072609
size_t alloc_size;
26082610
int i;
26092611
int err;
26102612

2611-
alloc_size = sizeof(struct mlxsw_sp_port *) * MLXSW_PORT_MAX_PORTS;
2613+
alloc_size = sizeof(struct mlxsw_sp_port *) * max_ports;
26122614
mlxsw_sp->ports = kzalloc(alloc_size, GFP_KERNEL);
26132615
if (!mlxsw_sp->ports)
26142616
return -ENOMEM;
26152617

2616-
for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++) {
2618+
mlxsw_sp->port_to_module = kcalloc(max_ports, sizeof(u8), GFP_KERNEL);
2619+
if (!mlxsw_sp->port_to_module) {
2620+
err = -ENOMEM;
2621+
goto err_port_to_module_alloc;
2622+
}
2623+
2624+
for (i = 1; i < max_ports; i++) {
26172625
err = mlxsw_sp_port_module_info_get(mlxsw_sp, i, &module,
26182626
&width, &lane);
26192627
if (err)
@@ -2633,6 +2641,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
26332641
for (i--; i >= 1; i--)
26342642
if (mlxsw_sp_port_created(mlxsw_sp, i))
26352643
mlxsw_sp_port_remove(mlxsw_sp, i);
2644+
kfree(mlxsw_sp->port_to_module);
2645+
err_port_to_module_alloc:
26362646
kfree(mlxsw_sp->ports);
26372647
return err;
26382648
}

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,14 @@ struct mlxsw_sp_sb_pm {
152152
#define MLXSW_SP_SB_POOL_COUNT 4
153153
#define MLXSW_SP_SB_TC_COUNT 8
154154

155+
struct mlxsw_sp_sb_port {
156+
struct mlxsw_sp_sb_cm cms[2][MLXSW_SP_SB_TC_COUNT];
157+
struct mlxsw_sp_sb_pm pms[2][MLXSW_SP_SB_POOL_COUNT];
158+
};
159+
155160
struct mlxsw_sp_sb {
156161
struct mlxsw_sp_sb_pr prs[2][MLXSW_SP_SB_POOL_COUNT];
157-
struct {
158-
struct mlxsw_sp_sb_cm cms[2][MLXSW_SP_SB_TC_COUNT];
159-
struct mlxsw_sp_sb_pm pms[2][MLXSW_SP_SB_POOL_COUNT];
160-
} ports[MLXSW_PORT_MAX_PORTS];
162+
struct mlxsw_sp_sb_port *ports;
161163
};
162164

163165
#define MLXSW_SP_PREFIX_COUNT (sizeof(struct in6_addr) * BITS_PER_BYTE)
@@ -273,7 +275,7 @@ struct mlxsw_sp {
273275
u32 ageing_time;
274276
struct mlxsw_sp_upper master_bridge;
275277
struct mlxsw_sp_upper *lags;
276-
u8 port_to_module[MLXSW_PORT_MAX_PORTS];
278+
u8 *port_to_module;
277279
struct mlxsw_sp_sb sb;
278280
struct mlxsw_sp_router router;
279281
struct mlxsw_sp_acl *acl;

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

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,25 @@ static int mlxsw_sp_port_headroom_init(struct mlxsw_sp_port *mlxsw_sp_port)
209209
return mlxsw_sp_port_pb_prio_init(mlxsw_sp_port);
210210
}
211211

212-
#define MLXSW_SP_SB_PR_INGRESS_SIZE \
213-
(15000000 - (2 * 20000 * MLXSW_PORT_MAX_PORTS))
212+
static int mlxsw_sp_sb_ports_init(struct mlxsw_sp *mlxsw_sp)
213+
{
214+
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
215+
216+
mlxsw_sp->sb.ports = kcalloc(max_ports, sizeof(struct mlxsw_sp_sb_port),
217+
GFP_KERNEL);
218+
if (!mlxsw_sp->sb.ports)
219+
return -ENOMEM;
220+
return 0;
221+
}
222+
223+
static void mlxsw_sp_sb_ports_fini(struct mlxsw_sp *mlxsw_sp)
224+
{
225+
kfree(mlxsw_sp->sb.ports);
226+
}
227+
228+
#define MLXSW_SP_SB_PR_INGRESS_SIZE 12440000
214229
#define MLXSW_SP_SB_PR_INGRESS_MNG_SIZE (200 * 1000)
215-
#define MLXSW_SP_SB_PR_EGRESS_SIZE \
216-
(14000000 - (8 * 1500 * MLXSW_PORT_MAX_PORTS))
230+
#define MLXSW_SP_SB_PR_EGRESS_SIZE 13232000
217231

218232
#define MLXSW_SP_SB_PR(_mode, _size) \
219233
{ \
@@ -528,26 +542,41 @@ int mlxsw_sp_buffers_init(struct mlxsw_sp *mlxsw_sp)
528542
{
529543
int err;
530544

531-
err = mlxsw_sp_sb_prs_init(mlxsw_sp);
545+
err = mlxsw_sp_sb_ports_init(mlxsw_sp);
532546
if (err)
533547
return err;
548+
err = mlxsw_sp_sb_prs_init(mlxsw_sp);
549+
if (err)
550+
goto err_sb_prs_init;
534551
err = mlxsw_sp_cpu_port_sb_cms_init(mlxsw_sp);
535552
if (err)
536-
return err;
553+
goto err_sb_cpu_port_sb_cms_init;
537554
err = mlxsw_sp_sb_mms_init(mlxsw_sp);
538555
if (err)
539-
return err;
540-
return devlink_sb_register(priv_to_devlink(mlxsw_sp->core), 0,
541-
MLXSW_SP_SB_SIZE,
542-
MLXSW_SP_SB_POOL_COUNT,
543-
MLXSW_SP_SB_POOL_COUNT,
544-
MLXSW_SP_SB_TC_COUNT,
545-
MLXSW_SP_SB_TC_COUNT);
556+
goto err_sb_mms_init;
557+
err = devlink_sb_register(priv_to_devlink(mlxsw_sp->core), 0,
558+
MLXSW_SP_SB_SIZE,
559+
MLXSW_SP_SB_POOL_COUNT,
560+
MLXSW_SP_SB_POOL_COUNT,
561+
MLXSW_SP_SB_TC_COUNT,
562+
MLXSW_SP_SB_TC_COUNT);
563+
if (err)
564+
goto err_devlink_sb_register;
565+
566+
return 0;
567+
568+
err_devlink_sb_register:
569+
err_sb_mms_init:
570+
err_sb_cpu_port_sb_cms_init:
571+
err_sb_prs_init:
572+
mlxsw_sp_sb_ports_fini(mlxsw_sp);
573+
return err;
546574
}
547575

548576
void mlxsw_sp_buffers_fini(struct mlxsw_sp *mlxsw_sp)
549577
{
550578
devlink_sb_unregister(priv_to_devlink(mlxsw_sp->core), 0);
579+
mlxsw_sp_sb_ports_fini(mlxsw_sp);
551580
}
552581

553582
int mlxsw_sp_port_buffers_init(struct mlxsw_sp_port *mlxsw_sp_port)
@@ -761,7 +790,7 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core,
761790

762791
masked_count = 0;
763792
for (local_port = cb_ctx.local_port_1;
764-
local_port < MLXSW_PORT_MAX_PORTS; local_port++) {
793+
local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
765794
if (!mlxsw_sp->ports[local_port])
766795
continue;
767796
for (i = 0; i < MLXSW_SP_SB_TC_COUNT; i++) {
@@ -775,7 +804,7 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core,
775804
}
776805
masked_count = 0;
777806
for (local_port = cb_ctx.local_port_1;
778-
local_port < MLXSW_PORT_MAX_PORTS; local_port++) {
807+
local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
779808
if (!mlxsw_sp->ports[local_port])
780809
continue;
781810
for (i = 0; i < MLXSW_SP_SB_TC_COUNT; i++) {
@@ -817,7 +846,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
817846
mlxsw_reg_sbsr_pg_buff_mask_set(sbsr_pl, i, 1);
818847
mlxsw_reg_sbsr_tclass_mask_set(sbsr_pl, i, 1);
819848
}
820-
for (; local_port < MLXSW_PORT_MAX_PORTS; local_port++) {
849+
for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
821850
if (!mlxsw_sp->ports[local_port])
822851
continue;
823852
mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1);
@@ -847,7 +876,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
847876
cb_priv);
848877
if (err)
849878
goto out;
850-
if (local_port < MLXSW_PORT_MAX_PORTS)
879+
if (local_port < mlxsw_core_max_ports(mlxsw_core))
851880
goto next_batch;
852881

853882
out:
@@ -882,7 +911,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
882911
mlxsw_reg_sbsr_pg_buff_mask_set(sbsr_pl, i, 1);
883912
mlxsw_reg_sbsr_tclass_mask_set(sbsr_pl, i, 1);
884913
}
885-
for (; local_port < MLXSW_PORT_MAX_PORTS; local_port++) {
914+
for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
886915
if (!mlxsw_sp->ports[local_port])
887916
continue;
888917
mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1);
@@ -908,7 +937,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
908937
&bulk_list, NULL, 0);
909938
if (err)
910939
goto out;
911-
if (local_port < MLXSW_PORT_MAX_PORTS)
940+
if (local_port < mlxsw_core_max_ports(mlxsw_core))
912941
goto next_batch;
913942

914943
out:

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2976,6 +2976,11 @@ static struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp,
29762976
return mlxsw_sp_fid_find(mlxsw_sp, fid);
29772977
}
29782978

2979+
static u8 mlxsw_sp_router_port(const struct mlxsw_sp *mlxsw_sp)
2980+
{
2981+
return mlxsw_core_max_ports(mlxsw_sp->core) + 1;
2982+
}
2983+
29792984
static enum mlxsw_flood_table_type mlxsw_sp_flood_table_type_get(u16 fid)
29802985
{
29812986
return mlxsw_sp_fid_is_vfid(fid) ? MLXSW_REG_SFGC_TABLE_TYPE_FID :
@@ -2990,6 +2995,7 @@ static u16 mlxsw_sp_flood_table_index_get(u16 fid)
29902995
static int mlxsw_sp_router_port_flood_set(struct mlxsw_sp *mlxsw_sp, u16 fid,
29912996
bool set)
29922997
{
2998+
u8 router_port = mlxsw_sp_router_port(mlxsw_sp);
29932999
enum mlxsw_flood_table_type table_type;
29943000
char *sftr_pl;
29953001
u16 index;
@@ -3002,7 +3008,7 @@ static int mlxsw_sp_router_port_flood_set(struct mlxsw_sp *mlxsw_sp, u16 fid,
30023008
table_type = mlxsw_sp_flood_table_type_get(fid);
30033009
index = mlxsw_sp_flood_table_index_get(fid);
30043010
mlxsw_reg_sftr_pack(sftr_pl, MLXSW_SP_FLOOD_TABLE_BC, index, table_type,
3005-
1, MLXSW_PORT_ROUTER_PORT, set);
3011+
1, router_port, set);
30063012
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sftr), sftr_pl);
30073013

30083014
kfree(sftr_pl);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ static int mlxsw_sp_port_smid_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 mid,
10121012

10131013
mlxsw_reg_smid_pack(smid_pl, mid, mlxsw_sp_port->local_port, add);
10141014
if (clear_all_ports) {
1015-
for (i = 1; i < MLXSW_PORT_MAX_PORTS; i++)
1015+
for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++)
10161016
if (mlxsw_sp->ports[i])
10171017
mlxsw_reg_smid_port_mask_set(smid_pl, i, 1);
10181018
}

0 commit comments

Comments
 (0)