net/mlx5: QPTS and QPDPM register firmware command support
The QPTS register allows changing the priority trust state between pcp and dscp. Add support to get/set trust state from device. When the port is in pcp/dscp trust state, packet is routed by hardware to matching priority based on its pcp/dscp value respectively. The QPDPM register allow channing the dscp to priority mapping. Add support to get/set dscp to priority mapping from device. Note that to change a dscp mapping, the "e" bit of this dscp structure must be set in the QPDPM firmware command. Signed-off-by: Huy Nguyen <huyn@mellanox.com> Reviewed-by: Parav Pandit <parav@mellanox.com> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
parent
71c70eb21c
commit
415a64aa8d
@ -971,3 +971,102 @@ int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode)
|
||||
return mlx5_core_access_reg(mdev, in, sizeof(in), out,
|
||||
sizeof(out), MLX5_REG_MTPPSE, 0, 1);
|
||||
}
|
||||
|
||||
int mlx5_set_trust_state(struct mlx5_core_dev *mdev, u8 trust_state)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(qpts_reg)] = {};
|
||||
u32 in[MLX5_ST_SZ_DW(qpts_reg)] = {};
|
||||
int err;
|
||||
|
||||
MLX5_SET(qpts_reg, in, local_port, 1);
|
||||
MLX5_SET(qpts_reg, in, trust_state, trust_state);
|
||||
|
||||
err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
|
||||
sizeof(out), MLX5_REG_QPTS, 0, 1);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(qpts_reg)] = {};
|
||||
u32 in[MLX5_ST_SZ_DW(qpts_reg)] = {};
|
||||
int err;
|
||||
|
||||
MLX5_SET(qpts_reg, in, local_port, 1);
|
||||
|
||||
err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
|
||||
sizeof(out), MLX5_REG_QPTS, 0, 0);
|
||||
if (!err)
|
||||
*trust_state = MLX5_GET(qpts_reg, out, trust_state);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, u8 dscp, u8 prio)
|
||||
{
|
||||
int sz = MLX5_ST_SZ_BYTES(qpdpm_reg);
|
||||
void *qpdpm_dscp;
|
||||
void *out;
|
||||
void *in;
|
||||
int err;
|
||||
|
||||
in = kzalloc(sz, GFP_KERNEL);
|
||||
out = kzalloc(sz, GFP_KERNEL);
|
||||
if (!in || !out) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
MLX5_SET(qpdpm_reg, in, local_port, 1);
|
||||
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_QPDPM, 0, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
memcpy(in, out, sz);
|
||||
MLX5_SET(qpdpm_reg, in, local_port, 1);
|
||||
|
||||
/* Update the corresponding dscp entry */
|
||||
qpdpm_dscp = MLX5_ADDR_OF(qpdpm_reg, in, dscp[dscp]);
|
||||
MLX5_SET16(qpdpm_dscp_reg, qpdpm_dscp, prio, prio);
|
||||
MLX5_SET16(qpdpm_dscp_reg, qpdpm_dscp, e, 1);
|
||||
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_QPDPM, 0, 1);
|
||||
|
||||
out:
|
||||
kfree(in);
|
||||
kfree(out);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* dscp2prio[i]: priority that dscp i mapped to */
|
||||
#define MLX5E_SUPPORTED_DSCP 64
|
||||
int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio)
|
||||
{
|
||||
int sz = MLX5_ST_SZ_BYTES(qpdpm_reg);
|
||||
void *qpdpm_dscp;
|
||||
void *out;
|
||||
void *in;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
in = kzalloc(sz, GFP_KERNEL);
|
||||
out = kzalloc(sz, GFP_KERNEL);
|
||||
if (!in || !out) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
MLX5_SET(qpdpm_reg, in, local_port, 1);
|
||||
err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_QPDPM, 0, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < (MLX5E_SUPPORTED_DSCP); i++) {
|
||||
qpdpm_dscp = MLX5_ADDR_OF(qpdpm_reg, out, dscp[i]);
|
||||
dscp2prio[i] = MLX5_GET16(qpdpm_dscp_reg, qpdpm_dscp, prio);
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(in);
|
||||
kfree(out);
|
||||
return err;
|
||||
}
|
||||
|
@ -107,8 +107,10 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_REG_QPTS = 0x4002,
|
||||
MLX5_REG_QETCR = 0x4005,
|
||||
MLX5_REG_QTCT = 0x400a,
|
||||
MLX5_REG_QPDPM = 0x4013,
|
||||
MLX5_REG_QCAM = 0x4019,
|
||||
MLX5_REG_DCBX_PARAM = 0x4020,
|
||||
MLX5_REG_DCBX_APP = 0x4021,
|
||||
@ -142,6 +144,11 @@ enum {
|
||||
MLX5_REG_MCAM = 0x907f,
|
||||
};
|
||||
|
||||
enum mlx5_qpts_trust_state {
|
||||
MLX5_QPTS_TRUST_PCP = 1,
|
||||
MLX5_QPTS_TRUST_DSCP = 2,
|
||||
};
|
||||
|
||||
enum mlx5_dcbx_oper_mode {
|
||||
MLX5E_DCBX_PARAM_VER_OPER_HOST = 0x0,
|
||||
MLX5E_DCBX_PARAM_VER_OPER_AUTO = 0x3,
|
||||
|
@ -8578,6 +8578,26 @@ struct mlx5_ifc_qetc_reg_bits {
|
||||
struct mlx5_ifc_ets_global_config_reg_bits global_configuration;
|
||||
};
|
||||
|
||||
struct mlx5_ifc_qpdpm_dscp_reg_bits {
|
||||
u8 e[0x1];
|
||||
u8 reserved_at_01[0x0b];
|
||||
u8 prio[0x04];
|
||||
};
|
||||
|
||||
struct mlx5_ifc_qpdpm_reg_bits {
|
||||
u8 reserved_at_0[0x8];
|
||||
u8 local_port[0x8];
|
||||
u8 reserved_at_10[0x10];
|
||||
struct mlx5_ifc_qpdpm_dscp_reg_bits dscp[64];
|
||||
};
|
||||
|
||||
struct mlx5_ifc_qpts_reg_bits {
|
||||
u8 reserved_at_0[0x8];
|
||||
u8 local_port[0x8];
|
||||
u8 reserved_at_10[0x2d];
|
||||
u8 trust_state[0x3];
|
||||
};
|
||||
|
||||
struct mlx5_ifc_qtct_reg_bits {
|
||||
u8 reserved_at_0[0x8];
|
||||
u8 port_number[0x8];
|
||||
|
@ -179,4 +179,9 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
|
||||
|
||||
int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
|
||||
int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
|
||||
|
||||
int mlx5_set_trust_state(struct mlx5_core_dev *mdev, u8 trust_state);
|
||||
int mlx5_query_trust_state(struct mlx5_core_dev *mdev, u8 *trust_state);
|
||||
int mlx5_set_dscp2prio(struct mlx5_core_dev *mdev, u8 dscp, u8 prio);
|
||||
int mlx5_query_dscp2prio(struct mlx5_core_dev *mdev, u8 *dscp2prio);
|
||||
#endif /* __MLX5_PORT_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user