Merge branch 'mlxsw-Enable-MC-aware-mode-for-mlxsw-ports'
Ido Schimmel says: ==================== mlxsw: Enable MC-aware mode for mlxsw ports Petr says: Due to an issue in Spectrum chips, when unicast traffic shares the same queue as BUM traffic, and there is a congestion, the BUM traffic is admitted to the queue anyway, thus pushing out all UC traffic. In order to give unicast traffic precedence over BUM traffic, configure multicast-aware mode on all ports. Under multicast-aware regime, when assigning traffic class to a packet, the switch doesn't merely take the value prescribed by the QTCT register. For BUM traffic, it instead assigns that value plus 8. That limits the number of available TCs, but since mlxsw currently only uses the lower eight anyway, it is no real loss. The two TCs (UC and MC one) are then mapped to the same subgroup and strictly prioritized so that UC traffic is preferred in case of congestion. In patch #1, introduce a new register, QTCTM, which enables the multicast-aware mode. In patch #2, fix a typo in related code. In patch #3, set up TCs and QTCTM to enable multicast-aware mode. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
add0decc46
@ -3544,6 +3544,42 @@ mlxsw_reg_qpdpm_dscp_pack(char *payload, unsigned short dscp, u8 prio)
|
||||
mlxsw_reg_qpdpm_dscp_entry_prio_set(payload, dscp, prio);
|
||||
}
|
||||
|
||||
/* QTCTM - QoS Switch Traffic Class Table is Multicast-Aware Register
|
||||
* ------------------------------------------------------------------
|
||||
* This register configures if the Switch Priority to Traffic Class mapping is
|
||||
* based on Multicast packet indication. If so, then multicast packets will get
|
||||
* a Traffic Class that is plus (cap_max_tclass_data/2) the value configured by
|
||||
* QTCT.
|
||||
* By default, Switch Priority to Traffic Class mapping is not based on
|
||||
* Multicast packet indication.
|
||||
*/
|
||||
#define MLXSW_REG_QTCTM_ID 0x401A
|
||||
#define MLXSW_REG_QTCTM_LEN 0x08
|
||||
|
||||
MLXSW_REG_DEFINE(qtctm, MLXSW_REG_QTCTM_ID, MLXSW_REG_QTCTM_LEN);
|
||||
|
||||
/* reg_qtctm_local_port
|
||||
* Local port number.
|
||||
* No support for CPU port.
|
||||
* Access: Index
|
||||
*/
|
||||
MLXSW_ITEM32(reg, qtctm, local_port, 0x00, 16, 8);
|
||||
|
||||
/* reg_qtctm_mc
|
||||
* Multicast Mode
|
||||
* Whether Switch Priority to Traffic Class mapping is based on Multicast packet
|
||||
* indication (default is 0, not based on Multicast packet indication).
|
||||
*/
|
||||
MLXSW_ITEM32(reg, qtctm, mc, 0x04, 0, 1);
|
||||
|
||||
static inline void
|
||||
mlxsw_reg_qtctm_pack(char *payload, u8 local_port, bool mc)
|
||||
{
|
||||
MLXSW_REG_ZERO(qtctm, payload);
|
||||
mlxsw_reg_qtctm_local_port_set(payload, local_port);
|
||||
mlxsw_reg_qtctm_mc_set(payload, mc);
|
||||
}
|
||||
|
||||
/* PMLP - Ports Module to Local Port Register
|
||||
* ------------------------------------------
|
||||
* Configures the assignment of modules to local ports.
|
||||
@ -8761,6 +8797,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(qrwe),
|
||||
MLXSW_REG(qpdsm),
|
||||
MLXSW_REG(qpdpm),
|
||||
MLXSW_REG(qtctm),
|
||||
MLXSW_REG(pmlp),
|
||||
MLXSW_REG(pmtu),
|
||||
MLXSW_REG(ptys),
|
||||
|
@ -2793,9 +2793,16 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||
false, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlxsw_sp_port_ets_set(mlxsw_sp_port,
|
||||
MLXSW_REG_QEEC_HIERARCY_TC,
|
||||
i + 8, i,
|
||||
false, 0);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Make sure the max shaper is disabled in all hierarcies that
|
||||
/* Make sure the max shaper is disabled in all hierarchies that
|
||||
* support it.
|
||||
*/
|
||||
err = mlxsw_sp_port_ets_maxrate_set(mlxsw_sp_port,
|
||||
@ -2830,6 +2837,16 @@ static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_tc_mc_mode_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
bool enable)
|
||||
{
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
char qtctm_pl[MLXSW_REG_QTCTM_LEN];
|
||||
|
||||
mlxsw_reg_qtctm_pack(qtctm_pl, mlxsw_sp_port->local_port, enable);
|
||||
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(qtctm), qtctm_pl);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
bool split, u8 module, u8 width, u8 lane)
|
||||
{
|
||||
@ -2958,6 +2975,13 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
goto err_port_ets_init;
|
||||
}
|
||||
|
||||
err = mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, true);
|
||||
if (err) {
|
||||
dev_err(mlxsw_sp->bus_info->dev, "Port %d: Failed to initialize TC MC mode\n",
|
||||
mlxsw_sp_port->local_port);
|
||||
goto err_port_tc_mc_mode;
|
||||
}
|
||||
|
||||
/* ETS and buffers must be initialized before DCB. */
|
||||
err = mlxsw_sp_port_dcb_init(mlxsw_sp_port);
|
||||
if (err) {
|
||||
@ -3014,6 +3038,8 @@ err_port_qdiscs_init:
|
||||
err_port_fids_init:
|
||||
mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
|
||||
err_port_dcb_init:
|
||||
mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
|
||||
err_port_tc_mc_mode:
|
||||
err_port_ets_init:
|
||||
err_port_buffers_init:
|
||||
err_port_admin_status_set:
|
||||
@ -3048,6 +3074,7 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
|
||||
mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
|
||||
mlxsw_sp_port_fids_fini(mlxsw_sp_port);
|
||||
mlxsw_sp_port_dcb_fini(mlxsw_sp_port);
|
||||
mlxsw_sp_port_tc_mc_mode_set(mlxsw_sp_port, false);
|
||||
mlxsw_sp_port_swid_set(mlxsw_sp_port, MLXSW_PORT_SWID_DISABLED_PORT);
|
||||
mlxsw_sp_port_module_unmap(mlxsw_sp_port);
|
||||
kfree(mlxsw_sp_port->sample);
|
||||
|
Loading…
x
Reference in New Issue
Block a user