Skip to content

Commit 88b3d5c

Browse files
Eran Ben ElishaSaeed Mahameed
authored andcommitted
net/mlx5e: Fix port buffers cell size value
Device unit for port buffers size, xoff_threshold and xon_threshold is cells. Fix a bug in driver where cell unit size was hard-coded to 128 bytes. This hard-coded value is buggy, as it is wrong for some hardware versions. Driver to read cell size from SBCAM register and translate bytes to cell units accordingly. In order to fix the bug, this patch exposes SBCAM (Shared buffer capabilities mask) layout and defines. If SBCAM.cap_cell_size is valid, use it for all bytes to cells calculations. If not valid, fallback to 128. Cell size do not change on the fly per device. Instead of issuing SBCAM access reg command every time such translation is needed, cache it in mlx5e_dcbx as part of mlx5e_dcbnl_initialize(). Pass dcbx.port_buff_cell_sz as a param to every function that needs bytes to cells translation. While fixing the bug, move MLX5E_BUFFER_CELL_SHIFT macro to en_dcbnl.c, as it is only used by that file. Fixes: 0696d60 ("net/mlx5e: Receive buffer configuration") Signed-off-by: Eran Ben Elisha <[email protected]> Reviewed-by: Huy Nguyen <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 6a1cf4e commit 88b3d5c

File tree

6 files changed

+78
-25
lines changed

6 files changed

+78
-25
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/dcbnl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct mlx5e_dcbx {
2929
bool manual_buffer;
3030
u32 cable_len;
3131
u32 xoff;
32+
u16 port_buff_cell_sz;
3233
};
3334

3435
#define MLX5E_MAX_DSCP (64)

drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
3535
struct mlx5e_port_buffer *port_buffer)
3636
{
37+
u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
3738
struct mlx5_core_dev *mdev = priv->mdev;
3839
int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
3940
u32 total_used = 0;
@@ -57,11 +58,11 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
5758
port_buffer->buffer[i].epsb =
5859
MLX5_GET(bufferx_reg, buffer, epsb);
5960
port_buffer->buffer[i].size =
60-
MLX5_GET(bufferx_reg, buffer, size) << MLX5E_BUFFER_CELL_SHIFT;
61+
MLX5_GET(bufferx_reg, buffer, size) * port_buff_cell_sz;
6162
port_buffer->buffer[i].xon =
62-
MLX5_GET(bufferx_reg, buffer, xon_threshold) << MLX5E_BUFFER_CELL_SHIFT;
63+
MLX5_GET(bufferx_reg, buffer, xon_threshold) * port_buff_cell_sz;
6364
port_buffer->buffer[i].xoff =
64-
MLX5_GET(bufferx_reg, buffer, xoff_threshold) << MLX5E_BUFFER_CELL_SHIFT;
65+
MLX5_GET(bufferx_reg, buffer, xoff_threshold) * port_buff_cell_sz;
6566
total_used += port_buffer->buffer[i].size;
6667

6768
mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", i,
@@ -73,7 +74,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
7374
}
7475

7576
port_buffer->port_buffer_size =
76-
MLX5_GET(pbmc_reg, out, port_buffer_size) << MLX5E_BUFFER_CELL_SHIFT;
77+
MLX5_GET(pbmc_reg, out, port_buffer_size) * port_buff_cell_sz;
7778
port_buffer->spare_buffer_size =
7879
port_buffer->port_buffer_size - total_used;
7980

@@ -88,9 +89,9 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv,
8889
static int port_set_buffer(struct mlx5e_priv *priv,
8990
struct mlx5e_port_buffer *port_buffer)
9091
{
92+
u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
9193
struct mlx5_core_dev *mdev = priv->mdev;
9294
int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
93-
void *buffer;
9495
void *in;
9596
int err;
9697
int i;
@@ -104,16 +105,18 @@ static int port_set_buffer(struct mlx5e_priv *priv,
104105
goto out;
105106

106107
for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
107-
buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);
108-
109-
MLX5_SET(bufferx_reg, buffer, size,
110-
port_buffer->buffer[i].size >> MLX5E_BUFFER_CELL_SHIFT);
111-
MLX5_SET(bufferx_reg, buffer, lossy,
112-
port_buffer->buffer[i].lossy);
113-
MLX5_SET(bufferx_reg, buffer, xoff_threshold,
114-
port_buffer->buffer[i].xoff >> MLX5E_BUFFER_CELL_SHIFT);
115-
MLX5_SET(bufferx_reg, buffer, xon_threshold,
116-
port_buffer->buffer[i].xon >> MLX5E_BUFFER_CELL_SHIFT);
108+
void *buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]);
109+
u64 size = port_buffer->buffer[i].size;
110+
u64 xoff = port_buffer->buffer[i].xoff;
111+
u64 xon = port_buffer->buffer[i].xon;
112+
113+
do_div(size, port_buff_cell_sz);
114+
do_div(xoff, port_buff_cell_sz);
115+
do_div(xon, port_buff_cell_sz);
116+
MLX5_SET(bufferx_reg, buffer, size, size);
117+
MLX5_SET(bufferx_reg, buffer, lossy, port_buffer->buffer[i].lossy);
118+
MLX5_SET(bufferx_reg, buffer, xoff_threshold, xoff);
119+
MLX5_SET(bufferx_reg, buffer, xon_threshold, xon);
117120
}
118121

119122
err = mlx5e_port_set_pbmc(mdev, in);
@@ -143,7 +146,7 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
143146
}
144147

145148
static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
146-
u32 xoff, unsigned int max_mtu)
149+
u32 xoff, unsigned int max_mtu, u16 port_buff_cell_sz)
147150
{
148151
int i;
149152

@@ -155,7 +158,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
155158
}
156159

157160
if (port_buffer->buffer[i].size <
158-
(xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) {
161+
(xoff + max_mtu + port_buff_cell_sz)) {
159162
pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n",
160163
i, port_buffer->buffer[i].size);
161164
return -ENOMEM;
@@ -175,6 +178,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
175178
* @pfc_en: <input> current pfc configuration
176179
* @buffer: <input> current prio to buffer mapping
177180
* @xoff: <input> xoff value
181+
* @port_buff_cell_sz: <input> port buffer cell_size
178182
* @port_buffer: <output> port receive buffer configuration
179183
* @change: <output>
180184
*
@@ -189,7 +193,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
189193
* sets change to true if buffer configuration was modified.
190194
*/
191195
static int update_buffer_lossy(unsigned int max_mtu,
192-
u8 pfc_en, u8 *buffer, u32 xoff,
196+
u8 pfc_en, u8 *buffer, u32 xoff, u16 port_buff_cell_sz,
193197
struct mlx5e_port_buffer *port_buffer,
194198
bool *change)
195199
{
@@ -225,7 +229,7 @@ static int update_buffer_lossy(unsigned int max_mtu,
225229
}
226230

227231
if (changed) {
228-
err = update_xoff_threshold(port_buffer, xoff, max_mtu);
232+
err = update_xoff_threshold(port_buffer, xoff, max_mtu, port_buff_cell_sz);
229233
if (err)
230234
return err;
231235

@@ -262,6 +266,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
262266
u32 *buffer_size,
263267
u8 *prio2buffer)
264268
{
269+
u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz;
265270
struct mlx5e_port_buffer port_buffer;
266271
u32 xoff = calculate_xoff(priv, mtu);
267272
bool update_prio2buffer = false;
@@ -282,7 +287,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
282287

283288
if (change & MLX5E_PORT_BUFFER_CABLE_LEN) {
284289
update_buffer = true;
285-
err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
290+
err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz);
286291
if (err)
287292
return err;
288293
}
@@ -292,7 +297,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
292297
if (err)
293298
return err;
294299

295-
err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff,
300+
err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff, port_buff_cell_sz,
296301
&port_buffer, &update_buffer);
297302
if (err)
298303
return err;
@@ -304,7 +309,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
304309
if (err)
305310
return err;
306311

307-
err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer,
312+
err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, port_buff_cell_sz,
308313
xoff, &port_buffer, &update_buffer);
309314
if (err)
310315
return err;
@@ -329,15 +334,15 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
329334
return -EINVAL;
330335

331336
update_buffer = true;
332-
err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
337+
err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz);
333338
if (err)
334339
return err;
335340
}
336341

337342
/* Need to update buffer configuration if xoff value is changed */
338343
if (!update_buffer && xoff != priv->dcbx.xoff) {
339344
update_buffer = true;
340-
err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
345+
err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz);
341346
if (err)
342347
return err;
343348
}

drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
#include "port.h"
3737

3838
#define MLX5E_MAX_BUFFER 8
39-
#define MLX5E_BUFFER_CELL_SHIFT 7
4039
#define MLX5E_DEFAULT_CABLE_LEN 7 /* 7 meters */
4140

4241
#define MLX5_BUFFER_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \

drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,24 @@ static int mlx5e_trust_initialize(struct mlx5e_priv *priv)
12171217
return 0;
12181218
}
12191219

1220+
#define MLX5E_BUFFER_CELL_SHIFT 7
1221+
1222+
static u16 mlx5e_query_port_buffers_cell_size(struct mlx5e_priv *priv)
1223+
{
1224+
struct mlx5_core_dev *mdev = priv->mdev;
1225+
u32 out[MLX5_ST_SZ_DW(sbcam_reg)] = {};
1226+
u32 in[MLX5_ST_SZ_DW(sbcam_reg)] = {};
1227+
1228+
if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1229+
return (1 << MLX5E_BUFFER_CELL_SHIFT);
1230+
1231+
if (mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out),
1232+
MLX5_REG_SBCAM, 0, 0))
1233+
return (1 << MLX5E_BUFFER_CELL_SHIFT);
1234+
1235+
return MLX5_GET(sbcam_reg, out, cap_cell_size);
1236+
}
1237+
12201238
void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
12211239
{
12221240
struct mlx5e_dcbx *dcbx = &priv->dcbx;
@@ -1234,6 +1252,7 @@ void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
12341252
if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
12351253
priv->dcbx.cap |= DCB_CAP_DCBX_HOST;
12361254

1255+
priv->dcbx.port_buff_cell_sz = mlx5e_query_port_buffers_cell_size(priv);
12371256
priv->dcbx.manual_buffer = false;
12381257
priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN;
12391258

include/linux/mlx5/driver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ enum {
147147
MLX5_REG_MCDA = 0x9063,
148148
MLX5_REG_MCAM = 0x907f,
149149
MLX5_REG_MIRC = 0x9162,
150+
MLX5_REG_SBCAM = 0xB01F,
150151
MLX5_REG_RESOURCE_DUMP = 0xC000,
151152
};
152153

include/linux/mlx5/mlx5_ifc.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9960,6 +9960,34 @@ struct mlx5_ifc_pptb_reg_bits {
99609960
u8 untagged_buff[0x4];
99619961
};
99629962

9963+
struct mlx5_ifc_sbcam_reg_bits {
9964+
u8 reserved_at_0[0x8];
9965+
u8 feature_group[0x8];
9966+
u8 reserved_at_10[0x8];
9967+
u8 access_reg_group[0x8];
9968+
9969+
u8 reserved_at_20[0x20];
9970+
9971+
u8 sb_access_reg_cap_mask[4][0x20];
9972+
9973+
u8 reserved_at_c0[0x80];
9974+
9975+
u8 sb_feature_cap_mask[4][0x20];
9976+
9977+
u8 reserved_at_1c0[0x40];
9978+
9979+
u8 cap_total_buffer_size[0x20];
9980+
9981+
u8 cap_cell_size[0x10];
9982+
u8 cap_max_pg_buffers[0x8];
9983+
u8 cap_num_pool_supported[0x8];
9984+
9985+
u8 reserved_at_240[0x8];
9986+
u8 cap_sbsr_stat_size[0x8];
9987+
u8 cap_max_tclass_data[0x8];
9988+
u8 cap_max_cpu_ingress_tclass_sb[0x8];
9989+
};
9990+
99639991
struct mlx5_ifc_pbmc_reg_bits {
99649992
u8 reserved_at_0[0x8];
99659993
u8 local_port[0x8];

0 commit comments

Comments
 (0)