Skip to content

Commit

Permalink
net/mlx5: QPTS and QPDPM register firmware command support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Huy Nguyen authored and Saeed Mahameed committed Nov 5, 2017
1 parent 71c70eb commit 415a64a
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
99 changes: 99 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
7 changes: 7 additions & 0 deletions include/linux/mlx5/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
20 changes: 20 additions & 0 deletions include/linux/mlx5/mlx5_ifc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
5 changes: 5 additions & 0 deletions include/linux/mlx5/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */

0 comments on commit 415a64a

Please sign in to comment.