Commit f417f04d authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum: Refactor port buffer configuration

The sizes and thresholds of the priority group (PG) buffers are
configured in cells, which represent a specific amount of bytes.

The cell size can vary in different devices, so it's better to query it
from the firmware than hard coding it.

Refactor the code dealing with this value into different functions, so
that it will be easier to make the conversion in the next patch.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d3daae1b
...@@ -800,19 +800,40 @@ static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p) ...@@ -800,19 +800,40 @@ static int mlxsw_sp_port_set_mac_address(struct net_device *dev, void *p)
return 0; return 0;
} }
static void mlxsw_sp_pg_buf_pack(char *pbmc_pl, int pg_index, int mtu, static u16 mlxsw_sp_pg_buf_threshold_get(int mtu)
bool pause_en, bool pfc_en, u16 delay)
{ {
u16 pg_size = 2 * MLXSW_SP_BYTES_TO_CELLS(mtu); return 2 * MLXSW_SP_BYTES_TO_CELLS(mtu);
}
delay = pfc_en ? mlxsw_sp_pfc_delay_get(mtu, delay) : #define MLXSW_SP_CELL_FACTOR 2 /* 2 * cell_size / (IPG + cell_size + 1) */
MLXSW_SP_PAUSE_DELAY; static u16 mlxsw_sp_pfc_delay_get(int mtu, u16 delay)
{
delay = MLXSW_SP_BYTES_TO_CELLS(DIV_ROUND_UP(delay, BITS_PER_BYTE));
return MLXSW_SP_CELL_FACTOR * delay + MLXSW_SP_BYTES_TO_CELLS(mtu);
}
if (pause_en || pfc_en) /* Maximum delay buffer needed in case of PAUSE frames, in cells.
mlxsw_reg_pbmc_lossless_buffer_pack(pbmc_pl, pg_index, * Assumes 100m cable and maximum MTU.
pg_size + delay, pg_size); */
#define MLXSW_SP_PAUSE_DELAY 612
static u16 mlxsw_sp_pg_buf_delay_get(int mtu, u16 delay, bool pfc, bool pause)
{
if (pfc)
return mlxsw_sp_pfc_delay_get(mtu, delay);
else if (pause)
return MLXSW_SP_PAUSE_DELAY;
else else
mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, pg_index, pg_size); return 0;
}
static void mlxsw_sp_pg_buf_pack(char *pbmc_pl, int index, u16 size, u16 thres,
bool lossy)
{
if (lossy)
mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, index, size);
else
mlxsw_reg_pbmc_lossless_buffer_pack(pbmc_pl, index, size,
thres);
} }
int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
...@@ -833,6 +854,8 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, ...@@ -833,6 +854,8 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
bool configure = false; bool configure = false;
bool pfc = false; bool pfc = false;
bool lossy;
u16 thres;
for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) { for (j = 0; j < IEEE_8021QAZ_MAX_TCS; j++) {
if (prio_tc[j] == i) { if (prio_tc[j] == i) {
...@@ -844,7 +867,11 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu, ...@@ -844,7 +867,11 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
if (!configure) if (!configure)
continue; continue;
mlxsw_sp_pg_buf_pack(pbmc_pl, i, mtu, pause_en, pfc, delay);
lossy = !(pfc || pause_en);
thres = mlxsw_sp_pg_buf_threshold_get(mtu);
delay = mlxsw_sp_pg_buf_delay_get(mtu, delay, pfc, pause_en);
mlxsw_sp_pg_buf_pack(pbmc_pl, i, thres + delay, thres, lossy);
} }
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pbmc), pbmc_pl);
......
...@@ -73,19 +73,6 @@ ...@@ -73,19 +73,6 @@
#define MLXSW_SP_KVD_LINEAR_SIZE 65536 /* entries */ #define MLXSW_SP_KVD_LINEAR_SIZE 65536 /* entries */
#define MLXSW_SP_KVD_GRANULARITY 128 #define MLXSW_SP_KVD_GRANULARITY 128
/* Maximum delay buffer needed in case of PAUSE frames, in cells.
* Assumes 100m cable and maximum MTU.
*/
#define MLXSW_SP_PAUSE_DELAY 612
#define MLXSW_SP_CELL_FACTOR 2 /* 2 * cell_size / (IPG + cell_size + 1) */
static inline u16 mlxsw_sp_pfc_delay_get(int mtu, u16 delay)
{
delay = MLXSW_SP_BYTES_TO_CELLS(DIV_ROUND_UP(delay, BITS_PER_BYTE));
return MLXSW_SP_CELL_FACTOR * delay + MLXSW_SP_BYTES_TO_CELLS(mtu);
}
struct mlxsw_sp_port; struct mlxsw_sp_port;
struct mlxsw_sp_rif; struct mlxsw_sp_rif;
......
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