net/mlx5: PPTB and PBMC register firmware command support
authorHuy Nguyen <huyn@mellanox.com>
Fri, 2 Mar 2018 21:47:01 +0000 (15:47 -0600)
committerSaeed Mahameed <saeedm@mellanox.com>
Thu, 24 May 2018 21:23:33 +0000 (14:23 -0700)
Add firmware command interface to read and write PPTB and PBMC
registers.

PPTB register enables mappings priority to a specific receive buffer.

PBMC registers enables changing the receive buffer's configuration such
as buffer size, xon/xoff thresholds, buffer's lossy property and
buffer's shared property.

Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en/port.c
drivers/net/ethernet/mellanox/mlx5/core/en/port.h
include/linux/mlx5/driver.h
include/linux/mlx5/mlx5_ifc.h

index 9f04542..24e3b56 100644 (file)
@@ -127,3 +127,111 @@ u32 mlx5e_port_speed2linkmodes(u32 speed)
 
        return link_modes;
 }
+
+int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out)
+{
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
+       void *in;
+       int err;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       if (!in)
+               return -ENOMEM;
+
+       MLX5_SET(pbmc_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 0);
+
+       kfree(in);
+       return err;
+}
+
+int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in)
+{
+       int sz = MLX5_ST_SZ_BYTES(pbmc_reg);
+       void *out;
+       int err;
+
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!out)
+               return -ENOMEM;
+
+       MLX5_SET(pbmc_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PBMC, 0, 1);
+
+       kfree(out);
+       return err;
+}
+
+/* buffer[i]: buffer that priority i mapped to */
+int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
+{
+       int sz = MLX5_ST_SZ_BYTES(pptb_reg);
+       u32 prio_x_buff;
+       void *out;
+       void *in;
+       int prio;
+       int err;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!in || !out) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       MLX5_SET(pptb_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
+       if (err)
+               goto out;
+
+       prio_x_buff = MLX5_GET(pptb_reg, out, prio_x_buff);
+       for (prio = 0; prio < 8; prio++) {
+               buffer[prio] = (u8)(prio_x_buff >> (4 * prio)) & 0xF;
+               mlx5_core_dbg(mdev, "prio %d, buffer %d\n", prio, buffer[prio]);
+       }
+out:
+       kfree(in);
+       kfree(out);
+       return err;
+}
+
+int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer)
+{
+       int sz = MLX5_ST_SZ_BYTES(pptb_reg);
+       u32 prio_x_buff;
+       void *out;
+       void *in;
+       int prio;
+       int err;
+
+       in = kzalloc(sz, GFP_KERNEL);
+       out = kzalloc(sz, GFP_KERNEL);
+       if (!in || !out) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       /* First query the pptb register */
+       MLX5_SET(pptb_reg, in, local_port, 1);
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 0);
+       if (err)
+               goto out;
+
+       memcpy(in, out, sz);
+       MLX5_SET(pptb_reg, in, local_port, 1);
+
+       /* Update the pm and prio_x_buff */
+       MLX5_SET(pptb_reg, in, pm, 0xFF);
+
+       prio_x_buff = 0;
+       for (prio = 0; prio < 8; prio++)
+               prio_x_buff |= (buffer[prio] << (4 * prio));
+       MLX5_SET(pptb_reg, in, prio_x_buff, prio_x_buff);
+
+       err = mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPTB, 0, 1);
+
+out:
+       kfree(in);
+       kfree(out);
+       return err;
+}
index 7aae38e..f8cbd81 100644 (file)
@@ -40,4 +40,9 @@ u32 mlx5e_port_ptys2speed(u32 eth_proto_oper);
 int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
 int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
 u32 mlx5e_port_speed2linkmodes(u32 speed);
+
+int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out);
+int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in);
+int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
+int mlx5e_port_set_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer);
 #endif
index d703774..92d2924 100644 (file)
@@ -124,6 +124,8 @@ enum {
        MLX5_REG_PAOS            = 0x5006,
        MLX5_REG_PFCC            = 0x5007,
        MLX5_REG_PPCNT           = 0x5008,
+       MLX5_REG_PPTB            = 0x500b,
+       MLX5_REG_PBMC            = 0x500c,
        MLX5_REG_PMAOS           = 0x5012,
        MLX5_REG_PUDE            = 0x5009,
        MLX5_REG_PMPE            = 0x5010,
index f687989..edbddea 100644 (file)
@@ -8788,6 +8788,41 @@ struct mlx5_ifc_qpts_reg_bits {
        u8         trust_state[0x3];
 };
 
+struct mlx5_ifc_pptb_reg_bits {
+       u8         reserved_at_0[0x2];
+       u8         mm[0x2];
+       u8         reserved_at_4[0x4];
+       u8         local_port[0x8];
+       u8         reserved_at_10[0x6];
+       u8         cm[0x1];
+       u8         um[0x1];
+       u8         pm[0x8];
+
+       u8         prio_x_buff[0x20];
+
+       u8         pm_msb[0x8];
+       u8         reserved_at_48[0x10];
+       u8         ctrl_buff[0x4];
+       u8         untagged_buff[0x4];
+};
+
+struct mlx5_ifc_pbmc_reg_bits {
+       u8         reserved_at_0[0x8];
+       u8         local_port[0x8];
+       u8         reserved_at_10[0x10];
+
+       u8         xoff_timer_value[0x10];
+       u8         xoff_refresh[0x10];
+
+       u8         reserved_at_40[0x9];
+       u8         fullness_threshold[0x7];
+       u8         port_buffer_size[0x10];
+
+       struct mlx5_ifc_bufferx_reg_bits buffer[10];
+
+       u8         reserved_at_2e0[0x40];
+};
+
 struct mlx5_ifc_qtct_reg_bits {
        u8         reserved_at_0[0x8];
        u8         port_number[0x8];