Commit 2fb44dd0 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Support-for-shared-buffers-in-Spectrum-2'

Ido Schimmel says:

====================
mlxsw: Support for shared buffers in Spectrum-2

Petr says:

Spectrum-2 will be configured with a different set of pools than
Spectrum-1, their sizes will be larger, and the individual quotas will
be different as well. It is therefore necessary to make the shared
buffer module aware of this dependence on chip type, and adjust the
individual tables.

In patch #1, introduce a structure for keeping per-chip immutable and
default values.

In patch #2, structures for keeping current values of SBPM and SBPR
(pool configuration and port-pool quota) are allocated dynamically to
support varying pool counts.

In patches #3 to #7, uses of individual shared buffer configuration
tables are migrated from global definitions to fields in struct
mlxsw_sp_sb_vals, which was introduced above.

Up until this point, the actual configuration is still the one suitable
for Spectrum-1. In patch #8 Spectrum-2 configuration is added.

In patch #9, port headroom configuration is changed to take into account
current recommended value for a 100-Gbps port, and the split factor.

In patch #10, requests for overlarge headroom are rejected. This avoids
potential chip freeze should such overlarge requests be made.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fdb89a31 bb6c346c
...@@ -26,6 +26,7 @@ enum mlxsw_res_id { ...@@ -26,6 +26,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_MAX_LAG_MEMBERS, MLXSW_RES_ID_MAX_LAG_MEMBERS,
MLXSW_RES_ID_MAX_BUFFER_SIZE, MLXSW_RES_ID_MAX_BUFFER_SIZE,
MLXSW_RES_ID_CELL_SIZE, MLXSW_RES_ID_CELL_SIZE,
MLXSW_RES_ID_MAX_HEADROOM_SIZE,
MLXSW_RES_ID_ACL_MAX_TCAM_REGIONS, MLXSW_RES_ID_ACL_MAX_TCAM_REGIONS,
MLXSW_RES_ID_ACL_MAX_TCAM_RULES, MLXSW_RES_ID_ACL_MAX_TCAM_RULES,
MLXSW_RES_ID_ACL_MAX_REGIONS, MLXSW_RES_ID_ACL_MAX_REGIONS,
...@@ -79,6 +80,7 @@ static u16 mlxsw_res_ids[] = { ...@@ -79,6 +80,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521, [MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521,
[MLXSW_RES_ID_MAX_BUFFER_SIZE] = 0x2802, /* Bytes */ [MLXSW_RES_ID_MAX_BUFFER_SIZE] = 0x2802, /* Bytes */
[MLXSW_RES_ID_CELL_SIZE] = 0x2803, /* Bytes */ [MLXSW_RES_ID_CELL_SIZE] = 0x2803, /* Bytes */
[MLXSW_RES_ID_MAX_HEADROOM_SIZE] = 0x2811, /* Bytes */
[MLXSW_RES_ID_ACL_MAX_TCAM_REGIONS] = 0x2901, [MLXSW_RES_ID_ACL_MAX_TCAM_REGIONS] = 0x2901,
[MLXSW_RES_ID_ACL_MAX_TCAM_RULES] = 0x2902, [MLXSW_RES_ID_ACL_MAX_TCAM_RULES] = 0x2902,
[MLXSW_RES_ID_ACL_MAX_REGIONS] = 0x2903, [MLXSW_RES_ID_ACL_MAX_REGIONS] = 0x2903,
......
...@@ -852,8 +852,12 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, ...@@ -852,8 +852,12 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
u8 pfc_en = !!my_pfc ? my_pfc->pfc_en : 0; u8 pfc_en = !!my_pfc ? my_pfc->pfc_en : 0;
u16 delay = !!my_pfc ? my_pfc->delay : 0; u16 delay = !!my_pfc ? my_pfc->delay : 0;
char pbmc_pl[MLXSW_REG_PBMC_LEN]; char pbmc_pl[MLXSW_REG_PBMC_LEN];
u32 taken_headroom_cells = 0;
u32 max_headroom_cells;
int i, j, err; int i, j, err;
max_headroom_cells = mlxsw_sp_sb_max_headroom_cells(mlxsw_sp);
mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0, 0); mlxsw_reg_pbmc_pack(pbmc_pl, mlxsw_sp_port->local_port, 0, 0);
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl); err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
if (err) if (err)
...@@ -864,6 +868,7 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, ...@@ -864,6 +868,7 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
bool pfc = false; bool pfc = false;
u16 thres_cells; u16 thres_cells;
u16 delay_cells; u16 delay_cells;
u16 total_cells;
bool lossy; bool lossy;
for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) { for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) {
...@@ -881,7 +886,13 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, ...@@ -881,7 +886,13 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu); thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu);
delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay, delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay,
pfc, pause_en); pfc, pause_en);
mlxsw_sp_pg_buf_pack(pbmc_pl, i, thres_cells + delay_cells, total_cells = thres_cells + delay_cells;
taken_headroom_cells += total_cells;
if (taken_headroom_cells > max_headroom_cells)
return -ENOBUFS;
mlxsw_sp_pg_buf_pack(pbmc_pl, i, total_cells,
thres_cells, lossy); thres_cells, lossy);
} }
...@@ -4092,6 +4103,7 @@ static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core, ...@@ -4092,6 +4103,7 @@ static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr; mlxsw_sp->nve_ops_arr = mlxsw_sp1_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp1_mac_mask; mlxsw_sp->mac_mask = mlxsw_sp1_mac_mask;
mlxsw_sp->rif_ops_arr = mlxsw_sp1_rif_ops_arr; mlxsw_sp->rif_ops_arr = mlxsw_sp1_rif_ops_arr;
mlxsw_sp->sb_vals = &mlxsw_sp1_sb_vals;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info); return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
} }
...@@ -4109,6 +4121,7 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core, ...@@ -4109,6 +4121,7 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr; mlxsw_sp->nve_ops_arr = mlxsw_sp2_nve_ops_arr;
mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask; mlxsw_sp->mac_mask = mlxsw_sp2_mac_mask;
mlxsw_sp->rif_ops_arr = mlxsw_sp2_rif_ops_arr; mlxsw_sp->rif_ops_arr = mlxsw_sp2_rif_ops_arr;
mlxsw_sp->sb_vals = &mlxsw_sp2_sb_vals;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info); return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info);
} }
......
...@@ -133,6 +133,7 @@ struct mlxsw_sp_kvdl_ops; ...@@ -133,6 +133,7 @@ struct mlxsw_sp_kvdl_ops;
struct mlxsw_sp_mr_tcam_ops; struct mlxsw_sp_mr_tcam_ops;
struct mlxsw_sp_acl_tcam_ops; struct mlxsw_sp_acl_tcam_ops;
struct mlxsw_sp_nve_ops; struct mlxsw_sp_nve_ops;
struct mlxsw_sp_sb_vals;
struct mlxsw_sp { struct mlxsw_sp {
struct mlxsw_sp_port **ports; struct mlxsw_sp_port **ports;
...@@ -167,6 +168,7 @@ struct mlxsw_sp { ...@@ -167,6 +168,7 @@ struct mlxsw_sp {
const struct mlxsw_sp_acl_tcam_ops *acl_tcam_ops; const struct mlxsw_sp_acl_tcam_ops *acl_tcam_ops;
const struct mlxsw_sp_nve_ops **nve_ops_arr; const struct mlxsw_sp_nve_ops **nve_ops_arr;
const struct mlxsw_sp_rif_ops **rif_ops_arr; const struct mlxsw_sp_rif_ops **rif_ops_arr;
const struct mlxsw_sp_sb_vals *sb_vals;
}; };
static inline struct mlxsw_sp_upper * static inline struct mlxsw_sp_upper *
...@@ -371,6 +373,10 @@ int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port, ...@@ -371,6 +373,10 @@ int mlxsw_sp_sb_occ_tc_port_bind_get(struct mlxsw_core_port *mlxsw_core_port,
u32 *p_cur, u32 *p_max); u32 *p_cur, u32 *p_max);
u32 mlxsw_sp_cells_bytes(const struct mlxsw_sp *mlxsw_sp, u32 cells); u32 mlxsw_sp_cells_bytes(const struct mlxsw_sp *mlxsw_sp, u32 cells);
u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes); u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes);
u32 mlxsw_sp_sb_max_headroom_cells(const struct mlxsw_sp *mlxsw_sp);
extern const struct mlxsw_sp_sb_vals mlxsw_sp1_sb_vals;
extern const struct mlxsw_sp_sb_vals mlxsw_sp2_sb_vals;
/* spectrum_switchdev.c */ /* spectrum_switchdev.c */
int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp); int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment