Skip to content

Commit 22881ad

Browse files
pmachatadavem330
authored andcommitted
mlxsw: spectrum_buffers: Manage internal buffer in the hdroom code
Traffic mirroring modes that are in-chip implemented on egress need an internal buffer to work. As the only client, the SPAN module was managing the buffer so far. However logically it belongs to the buffers module. E.g. buffer size validation needs to take the size of the internal buffer into account. Therefore move the related code from SPAN to spectrum_buffers. Move over the callbacks that determine the minimum buffer size as a function of maximum speed and MTU. Add a field describing the internal buffer to struct mlxsw_sp_hdroom. Extend mlxsw_sp_hdroom_bufs_reset_sizes() to take care of sizing the internal buffer as well. Change the SPAN module to invoke that function and mlxsw_sp_hdroom_configure() like all the other hdroom clients. Drop the now-unnecessary mlxsw_sp_span_port_buffer_disable(). Signed-off-by: Petr Machata <[email protected]> Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a41b962 commit 22881ad

File tree

4 files changed

+113
-64
lines changed

4 files changed

+113
-64
lines changed

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,6 @@ mlxsw_sp_port_vlan_find_by_vid(const struct mlxsw_sp_port *mlxsw_sp_port,
415415
return NULL;
416416
}
417417

418-
static inline u32
419-
mlxsw_sp_port_headroom_8x_adjust(const struct mlxsw_sp_port *mlxsw_sp_port,
420-
u32 size_cells)
421-
{
422-
/* Ports with eight lanes use two headroom buffers between which the
423-
* configured headroom size is split. Therefore, multiply the calculated
424-
* headroom size by two.
425-
*/
426-
return mlxsw_sp_port->mapping.width == 8 ? 2 * size_cells : size_cells;
427-
}
428-
429418
enum mlxsw_sp_flood_type {
430419
MLXSW_SP_FLOOD_TYPE_UC,
431420
MLXSW_SP_FLOOD_TYPE_BC,
@@ -463,6 +452,17 @@ struct mlxsw_sp_hdroom {
463452
struct {
464453
struct mlxsw_sp_hdroom_buf buf[MLXSW_SP_PB_COUNT];
465454
} bufs;
455+
struct {
456+
/* Size actually configured for the internal buffer. Equal to
457+
* reserve when internal buffer is enabled.
458+
*/
459+
u32 size_cells;
460+
/* Space reserved in the headroom for the internal buffer. Port
461+
* buffers are not allowed to grow into this space.
462+
*/
463+
u32 reserve_cells;
464+
bool enable;
465+
} int_buf;
466466
int delay_bytes;
467467
int mtu;
468468
};

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

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ struct mlxsw_sp_sb_vals {
122122
};
123123

124124
struct mlxsw_sp_sb_ops {
125+
u32 (*int_buf_size_get)(int mtu, u32 speed);
125126
};
126127

127128
u32 mlxsw_sp_cells_bytes(const struct mlxsw_sp *mlxsw_sp, u32 cells)
@@ -134,6 +135,16 @@ u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, u32 bytes)
134135
return DIV_ROUND_UP(bytes, mlxsw_sp->sb->cell_size);
135136
}
136137

138+
static u32 mlxsw_sp_port_headroom_8x_adjust(const struct mlxsw_sp_port *mlxsw_sp_port,
139+
u32 size_cells)
140+
{
141+
/* Ports with eight lanes use two headroom buffers between which the
142+
* configured headroom size is split. Therefore, multiply the calculated
143+
* headroom size by two.
144+
*/
145+
return mlxsw_sp_port->mapping.width == 8 ? 2 * size_cells : size_cells;
146+
}
147+
137148
static struct mlxsw_sp_sb_pr *mlxsw_sp_sb_pr_get(struct mlxsw_sp *mlxsw_sp,
138149
u16 pool_index)
139150
{
@@ -343,6 +354,13 @@ static u16 mlxsw_sp_hdroom_buf_delay_get(const struct mlxsw_sp *mlxsw_sp,
343354
return 2 * delay_cells + mlxsw_sp_bytes_cells(mlxsw_sp, hdroom->mtu);
344355
}
345356

357+
static u32 mlxsw_sp_hdroom_int_buf_size_get(struct mlxsw_sp *mlxsw_sp, int mtu, u32 speed)
358+
{
359+
u32 buffsize = mlxsw_sp->sb_ops->int_buf_size_get(speed, mtu);
360+
361+
return mlxsw_sp_bytes_cells(mlxsw_sp, buffsize) + 1;
362+
}
363+
346364
static bool mlxsw_sp_hdroom_buf_is_used(const struct mlxsw_sp_hdroom *hdroom, int buf)
347365
{
348366
int prio;
@@ -358,8 +376,21 @@ void mlxsw_sp_hdroom_bufs_reset_sizes(struct mlxsw_sp_port *mlxsw_sp_port,
358376
struct mlxsw_sp_hdroom *hdroom)
359377
{
360378
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
379+
u16 reserve_cells;
361380
int i;
362381

382+
/* Internal buffer. */
383+
reserve_cells = mlxsw_sp_hdroom_int_buf_size_get(mlxsw_sp, mlxsw_sp_port->max_speed,
384+
mlxsw_sp_port->max_mtu);
385+
reserve_cells = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, reserve_cells);
386+
hdroom->int_buf.reserve_cells = reserve_cells;
387+
388+
if (hdroom->int_buf.enable)
389+
hdroom->int_buf.size_cells = reserve_cells;
390+
else
391+
hdroom->int_buf.size_cells = 0;
392+
393+
/* PG buffers. */
363394
for (i = 0; i < DCBX_MAX_BUFFERS; i++) {
364395
struct mlxsw_sp_hdroom_buf *buf = &hdroom->bufs.buf[i];
365396
u16 thres_cells;
@@ -442,6 +473,26 @@ static int mlxsw_sp_hdroom_configure_priomap(struct mlxsw_sp_port *mlxsw_sp_port
442473
return 0;
443474
}
444475

476+
static int mlxsw_sp_hdroom_configure_int_buf(struct mlxsw_sp_port *mlxsw_sp_port,
477+
const struct mlxsw_sp_hdroom *hdroom, bool force)
478+
{
479+
char sbib_pl[MLXSW_REG_SBIB_LEN];
480+
bool dirty;
481+
int err;
482+
483+
dirty = memcmp(&mlxsw_sp_port->hdroom->int_buf, &hdroom->int_buf, sizeof(hdroom->int_buf));
484+
if (!dirty && !force)
485+
return 0;
486+
487+
mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, hdroom->int_buf.size_cells);
488+
err = mlxsw_reg_write(mlxsw_sp_port->mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
489+
if (err)
490+
return err;
491+
492+
mlxsw_sp_port->hdroom->int_buf = hdroom->int_buf;
493+
return 0;
494+
}
495+
445496
static bool mlxsw_sp_hdroom_bufs_fit(struct mlxsw_sp *mlxsw_sp,
446497
const struct mlxsw_sp_hdroom *hdroom)
447498
{
@@ -451,6 +502,7 @@ static bool mlxsw_sp_hdroom_bufs_fit(struct mlxsw_sp *mlxsw_sp,
451502
for (i = 0; i < MLXSW_SP_PB_COUNT; i++)
452503
taken_headroom_cells += hdroom->bufs.buf[i].size_cells;
453504

505+
taken_headroom_cells += hdroom->int_buf.reserve_cells;
454506
return taken_headroom_cells <= mlxsw_sp->sb->max_headroom_cells;
455507
}
456508

@@ -493,9 +545,15 @@ static int __mlxsw_sp_hdroom_configure(struct mlxsw_sp_port *mlxsw_sp_port,
493545
if (err)
494546
goto err_configure_buffers;
495547

548+
err = mlxsw_sp_hdroom_configure_int_buf(mlxsw_sp_port, hdroom, false);
549+
if (err)
550+
goto err_configure_int_buf;
551+
496552
*mlxsw_sp_port->hdroom = *hdroom;
497553
return 0;
498554

555+
err_configure_int_buf:
556+
mlxsw_sp_hdroom_configure_buffers(mlxsw_sp_port, &tmp_hdroom, false);
499557
err_configure_buffers:
500558
mlxsw_sp_hdroom_configure_priomap(mlxsw_sp_port, &tmp_hdroom, false);
501559
err_configure_priomap:
@@ -1104,13 +1162,44 @@ const struct mlxsw_sp_sb_vals mlxsw_sp2_sb_vals = {
11041162
.cms_cpu_count = ARRAY_SIZE(mlxsw_sp_cpu_port_sb_cms),
11051163
};
11061164

1165+
static u32 mlxsw_sp1_pb_int_buf_size_get(int mtu, u32 speed)
1166+
{
1167+
return mtu * 5 / 2;
1168+
}
1169+
1170+
static u32 __mlxsw_sp_pb_int_buf_size_get(int mtu, u32 speed, u32 buffer_factor)
1171+
{
1172+
return 3 * mtu + buffer_factor * speed / 1000;
1173+
}
1174+
1175+
#define MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR 38
1176+
1177+
static u32 mlxsw_sp2_pb_int_buf_size_get(int mtu, u32 speed)
1178+
{
1179+
int factor = MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR;
1180+
1181+
return __mlxsw_sp_pb_int_buf_size_get(mtu, speed, factor);
1182+
}
1183+
1184+
#define MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR 50
1185+
1186+
static u32 mlxsw_sp3_pb_int_buf_size_get(int mtu, u32 speed)
1187+
{
1188+
int factor = MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR;
1189+
1190+
return __mlxsw_sp_pb_int_buf_size_get(mtu, speed, factor);
1191+
}
1192+
11071193
const struct mlxsw_sp_sb_ops mlxsw_sp1_sb_ops = {
1194+
.int_buf_size_get = mlxsw_sp1_pb_int_buf_size_get,
11081195
};
11091196

11101197
const struct mlxsw_sp_sb_ops mlxsw_sp2_sb_ops = {
1198+
.int_buf_size_get = mlxsw_sp2_pb_int_buf_size_get,
11111199
};
11121200

11131201
const struct mlxsw_sp_sb_ops mlxsw_sp3_sb_ops = {
1202+
.int_buf_size_get = mlxsw_sp3_pb_int_buf_size_get,
11141203
};
11151204

11161205
int mlxsw_sp_buffers_init(struct mlxsw_sp *mlxsw_sp)

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

Lines changed: 13 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -968,35 +968,26 @@ static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
968968
return 0;
969969
}
970970

971-
static u32 mlxsw_sp_span_buffsize_get(struct mlxsw_sp *mlxsw_sp, int mtu,
972-
u32 speed)
971+
static int mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
973972
{
974-
u32 buffsize = mlxsw_sp->span_ops->buffsize_get(speed, mtu);
973+
struct mlxsw_sp_hdroom hdroom;
975974

976-
return mlxsw_sp_bytes_cells(mlxsw_sp, buffsize) + 1;
975+
hdroom = *mlxsw_sp_port->hdroom;
976+
hdroom.int_buf.enable = enable;
977+
mlxsw_sp_hdroom_bufs_reset_sizes(mlxsw_sp_port, &hdroom);
978+
979+
return mlxsw_sp_hdroom_configure(mlxsw_sp_port, &hdroom);
977980
}
978981

979982
static int
980983
mlxsw_sp_span_port_buffer_enable(struct mlxsw_sp_port *mlxsw_sp_port)
981984
{
982-
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
983-
char sbib_pl[MLXSW_REG_SBIB_LEN];
984-
u32 buffsize;
985-
986-
buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, mlxsw_sp_port->max_speed,
987-
mlxsw_sp_port->max_mtu);
988-
buffsize = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, buffsize);
989-
mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize);
990-
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
985+
return mlxsw_sp_span_port_buffer_update(mlxsw_sp_port, true);
991986
}
992987

993-
static void mlxsw_sp_span_port_buffer_disable(struct mlxsw_sp *mlxsw_sp,
994-
u8 local_port)
988+
static void mlxsw_sp_span_port_buffer_disable(struct mlxsw_sp_port *mlxsw_sp_port)
995989
{
996-
char sbib_pl[MLXSW_REG_SBIB_LEN];
997-
998-
mlxsw_reg_sbib_pack(sbib_pl, local_port, 0);
999-
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
990+
mlxsw_sp_span_port_buffer_update(mlxsw_sp_port, false);
1000991
}
1001992

1002993
static struct mlxsw_sp_span_analyzed_port *
@@ -1145,18 +1136,15 @@ mlxsw_sp_span_analyzed_port_create(struct mlxsw_sp_span *span,
11451136
}
11461137

11471138
static void
1148-
mlxsw_sp_span_analyzed_port_destroy(struct mlxsw_sp_span *span,
1139+
mlxsw_sp_span_analyzed_port_destroy(struct mlxsw_sp_port *mlxsw_sp_port,
11491140
struct mlxsw_sp_span_analyzed_port *
11501141
analyzed_port)
11511142
{
1152-
struct mlxsw_sp *mlxsw_sp = span->mlxsw_sp;
1153-
11541143
/* Remove egress mirror buffer now that port is no longer analyzed
11551144
* at egress.
11561145
*/
11571146
if (!analyzed_port->ingress)
1158-
mlxsw_sp_span_port_buffer_disable(mlxsw_sp,
1159-
analyzed_port->local_port);
1147+
mlxsw_sp_span_port_buffer_disable(mlxsw_sp_port);
11601148

11611149
list_del(&analyzed_port->list);
11621150
kfree(analyzed_port);
@@ -1207,7 +1195,7 @@ void mlxsw_sp_span_analyzed_port_put(struct mlxsw_sp_port *mlxsw_sp_port,
12071195
if (!refcount_dec_and_test(&analyzed_port->ref_count))
12081196
goto out_unlock;
12091197

1210-
mlxsw_sp_span_analyzed_port_destroy(mlxsw_sp->span, analyzed_port);
1198+
mlxsw_sp_span_analyzed_port_destroy(mlxsw_sp_port, analyzed_port);
12111199

12121200
out_unlock:
12131201
mutex_unlock(&mlxsw_sp->span->analyzed_ports_lock);
@@ -1661,11 +1649,6 @@ static int mlxsw_sp1_span_init(struct mlxsw_sp *mlxsw_sp)
16611649
return 0;
16621650
}
16631651

1664-
static u32 mlxsw_sp1_span_buffsize_get(int mtu, u32 speed)
1665-
{
1666-
return mtu * 5 / 2;
1667-
}
1668-
16691652
static int mlxsw_sp1_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
16701653
u16 policer_id_base)
16711654
{
@@ -1674,7 +1657,6 @@ static int mlxsw_sp1_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
16741657

16751658
const struct mlxsw_sp_span_ops mlxsw_sp1_span_ops = {
16761659
.init = mlxsw_sp1_span_init,
1677-
.buffsize_get = mlxsw_sp1_span_buffsize_get,
16781660
.policer_id_base_set = mlxsw_sp1_span_policer_id_base_set,
16791661
};
16801662

@@ -1699,18 +1681,6 @@ static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
16991681
#define MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR 38
17001682
#define MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR 50
17011683

1702-
static u32 __mlxsw_sp_span_buffsize_get(int mtu, u32 speed, u32 buffer_factor)
1703-
{
1704-
return 3 * mtu + buffer_factor * speed / 1000;
1705-
}
1706-
1707-
static u32 mlxsw_sp2_span_buffsize_get(int mtu, u32 speed)
1708-
{
1709-
int factor = MLXSW_SP2_SPAN_EG_MIRROR_BUFFER_FACTOR;
1710-
1711-
return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
1712-
}
1713-
17141684
static int mlxsw_sp2_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
17151685
u16 policer_id_base)
17161686
{
@@ -1727,19 +1697,10 @@ static int mlxsw_sp2_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
17271697

17281698
const struct mlxsw_sp_span_ops mlxsw_sp2_span_ops = {
17291699
.init = mlxsw_sp2_span_init,
1730-
.buffsize_get = mlxsw_sp2_span_buffsize_get,
17311700
.policer_id_base_set = mlxsw_sp2_span_policer_id_base_set,
17321701
};
17331702

1734-
static u32 mlxsw_sp3_span_buffsize_get(int mtu, u32 speed)
1735-
{
1736-
int factor = MLXSW_SP3_SPAN_EG_MIRROR_BUFFER_FACTOR;
1737-
1738-
return __mlxsw_sp_span_buffsize_get(mtu, speed, factor);
1739-
}
1740-
17411703
const struct mlxsw_sp_span_ops mlxsw_sp3_span_ops = {
17421704
.init = mlxsw_sp2_span_init,
1743-
.buffsize_get = mlxsw_sp3_span_buffsize_get,
17441705
.policer_id_base_set = mlxsw_sp2_span_policer_id_base_set,
17451706
};

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ struct mlxsw_sp_span_entry_ops;
4747

4848
struct mlxsw_sp_span_ops {
4949
int (*init)(struct mlxsw_sp *mlxsw_sp);
50-
u32 (*buffsize_get)(int mtu, u32 speed);
5150
int (*policer_id_base_set)(struct mlxsw_sp *mlxsw_sp,
5251
u16 policer_id_base);
5352
};

0 commit comments

Comments
 (0)