Commit 532b49e4 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

mlxsw: spectrum_span: Derive SBIB from maximum port speed & MTU

The SBIB register configures the size of an internal buffer that the
Spectrum ASICs use when mirroring traffic on egress. This size should be
taken into account when validating that the port headroom buffers are not
larger than the chip can handle. Up until now this was not done, which is
incidentally not a problem, because the priority group buffers that mlxsw
auto-configures are small enough that the boundary condition could not be
violated.

However when dcbnl_setbuffer is implemented, the user has control over
sizes of PG buffers, and they might overshoot the headroom capacity.
However the size of the SBIB buffer depends on port speed, and that cannot
be vetoed. Therefore SBIB size should be deduced from maximum port speed.

Additionally, once the buffers are configured by hand, the user could get
into an uncomfortable situation where their MTU change requests get vetoed,
because the SBIB does not fit anymore. Therefore derive SBIB size from
maximum permissible MTU as well.

Remove all the code that adjusted the SBIB size whenever speed or MTU
changed.
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3232e8c6
...@@ -1003,9 +1003,6 @@ static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu) ...@@ -1003,9 +1003,6 @@ static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, mtu, pause_en); err = mlxsw_sp_port_headroom_set(mlxsw_sp_port, mtu, pause_en);
if (err) if (err)
return err; return err;
err = mlxsw_sp_span_port_mtu_update(mlxsw_sp_port, mtu);
if (err)
goto err_span_port_mtu_update;
err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, mtu); err = mlxsw_sp_port_mtu_set(mlxsw_sp_port, mtu);
if (err) if (err)
goto err_port_mtu_set; goto err_port_mtu_set;
...@@ -1013,8 +1010,6 @@ static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu) ...@@ -1013,8 +1010,6 @@ static int mlxsw_sp_port_change_mtu(struct net_device *dev, int mtu)
return 0; return 0;
err_port_mtu_set: err_port_mtu_set:
mlxsw_sp_span_port_mtu_update(mlxsw_sp_port, dev->mtu);
err_span_port_mtu_update:
mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en); mlxsw_sp_port_headroom_set(mlxsw_sp_port, dev->mtu, pause_en);
return err; return err;
} }
...@@ -1952,8 +1947,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port, ...@@ -1952,8 +1947,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
INIT_DELAYED_WORK(&mlxsw_sp_port->ptp.shaper_dw, INIT_DELAYED_WORK(&mlxsw_sp_port->ptp.shaper_dw,
mlxsw_sp->ptp_ops->shaper_work); mlxsw_sp->ptp_ops->shaper_work);
INIT_DELAYED_WORK(&mlxsw_sp_port->span.speed_update_dw,
mlxsw_sp_span_speed_update_work);
mlxsw_sp->ports[local_port] = mlxsw_sp_port; mlxsw_sp->ports[local_port] = mlxsw_sp_port;
err = register_netdev(dev); err = register_netdev(dev);
...@@ -2010,7 +2003,6 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port) ...@@ -2010,7 +2003,6 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port]; struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp->ports[local_port];
cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw); cancel_delayed_work_sync(&mlxsw_sp_port->periodic_hw_stats.update_dw);
cancel_delayed_work_sync(&mlxsw_sp_port->span.speed_update_dw);
cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw); cancel_delayed_work_sync(&mlxsw_sp_port->ptp.shaper_dw);
mlxsw_sp_port_ptp_clear(mlxsw_sp_port); mlxsw_sp_port_ptp_clear(mlxsw_sp_port);
mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp); mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
...@@ -2414,7 +2406,6 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg, ...@@ -2414,7 +2406,6 @@ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
netdev_info(mlxsw_sp_port->dev, "link up\n"); netdev_info(mlxsw_sp_port->dev, "link up\n");
netif_carrier_on(mlxsw_sp_port->dev); netif_carrier_on(mlxsw_sp_port->dev);
mlxsw_core_schedule_dw(&mlxsw_sp_port->ptp.shaper_dw, 0); mlxsw_core_schedule_dw(&mlxsw_sp_port->ptp.shaper_dw, 0);
mlxsw_core_schedule_dw(&mlxsw_sp_port->span.speed_update_dw, 0);
} else { } else {
netdev_info(mlxsw_sp_port->dev, "link down\n"); netdev_info(mlxsw_sp_port->dev, "link down\n");
netif_carrier_off(mlxsw_sp_port->dev); netif_carrier_off(mlxsw_sp_port->dev);
......
...@@ -316,9 +316,6 @@ struct mlxsw_sp_port { ...@@ -316,9 +316,6 @@ struct mlxsw_sp_port {
struct mlxsw_sp_ptp_port_stats stats; struct mlxsw_sp_ptp_port_stats stats;
} ptp; } ptp;
u8 split_base_local_port; u8 split_base_local_port;
struct {
struct delayed_work speed_update_dw;
} span;
int max_mtu; int max_mtu;
u32 max_speed; u32 max_speed;
}; };
......
...@@ -977,21 +977,14 @@ static u32 mlxsw_sp_span_buffsize_get(struct mlxsw_sp *mlxsw_sp, int mtu, ...@@ -977,21 +977,14 @@ static u32 mlxsw_sp_span_buffsize_get(struct mlxsw_sp *mlxsw_sp, int mtu,
} }
static int static int
mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu) mlxsw_sp_span_port_buffer_enable(struct mlxsw_sp_port *mlxsw_sp_port)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
char sbib_pl[MLXSW_REG_SBIB_LEN]; char sbib_pl[MLXSW_REG_SBIB_LEN];
u32 buffsize; u32 buffsize;
u32 speed;
int err;
err = mlxsw_sp_port_speed_get(mlxsw_sp_port, &speed);
if (err)
return err;
if (speed == SPEED_UNKNOWN)
speed = 0;
buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, speed, mtu); buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, mlxsw_sp_port->max_speed,
mlxsw_sp_port->max_mtu);
buffsize = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, buffsize); buffsize = mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, buffsize);
mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize); mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
...@@ -1021,48 +1014,6 @@ mlxsw_sp_span_analyzed_port_find(struct mlxsw_sp_span *span, u8 local_port, ...@@ -1021,48 +1014,6 @@ mlxsw_sp_span_analyzed_port_find(struct mlxsw_sp_span *span, u8 local_port,
return NULL; return NULL;
} }
int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
{
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
int err = 0;
/* If port is egress mirrored, the shared buffer size should be
* updated according to the mtu value
*/
mutex_lock(&mlxsw_sp->span->analyzed_ports_lock);
if (mlxsw_sp_span_analyzed_port_find(mlxsw_sp->span, port->local_port,
false))
err = mlxsw_sp_span_port_buffer_update(port, mtu);
mutex_unlock(&mlxsw_sp->span->analyzed_ports_lock);
return err;
}
void mlxsw_sp_span_speed_update_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp;
mlxsw_sp_port = container_of(dwork, struct mlxsw_sp_port,
span.speed_update_dw);
/* If port is egress mirrored, the shared buffer size should be
* updated according to the speed value.
*/
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
mutex_lock(&mlxsw_sp->span->analyzed_ports_lock);
if (mlxsw_sp_span_analyzed_port_find(mlxsw_sp->span,
mlxsw_sp_port->local_port, false))
mlxsw_sp_span_port_buffer_update(mlxsw_sp_port,
mlxsw_sp_port->dev->mtu);
mutex_unlock(&mlxsw_sp->span->analyzed_ports_lock);
}
static const struct mlxsw_sp_span_entry_ops * static const struct mlxsw_sp_span_entry_ops *
mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_span_entry_ops(struct mlxsw_sp *mlxsw_sp,
const struct net_device *to_dev) const struct net_device *to_dev)
...@@ -1180,9 +1131,7 @@ mlxsw_sp_span_analyzed_port_create(struct mlxsw_sp_span *span, ...@@ -1180,9 +1131,7 @@ mlxsw_sp_span_analyzed_port_create(struct mlxsw_sp_span *span,
* does the mirroring. * does the mirroring.
*/ */
if (!ingress) { if (!ingress) {
u16 mtu = mlxsw_sp_port->dev->mtu; err = mlxsw_sp_span_port_buffer_enable(mlxsw_sp_port);
err = mlxsw_sp_span_port_buffer_update(mlxsw_sp_port, mtu);
if (err) if (err)
goto err_buffer_update; goto err_buffer_update;
} }
......
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