From: Huy Nguyen <h...@mellanox.com>

The QCAM register provides capability bit for all the QoS registers
using ACCESS_REG command.

Signed-off-by: Huy Nguyen <h...@mellanox.com>
Reviewed-by: Parav Pandit <pa...@mellanox.com>
Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/fw.c       | 10 ++++++
 .../net/ethernet/mellanox/mlx5/core/mlx5_core.h    |  2 ++
 drivers/net/ethernet/mellanox/mlx5/core/port.c     | 12 +++++++
 include/linux/mlx5/device.h                        | 14 ++++++++
 include/linux/mlx5/driver.h                        |  2 ++
 include/linux/mlx5/mlx5_ifc.h                      | 40 +++++++++++++++++++++-
 6 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c 
b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
index 2c71557d1cee..5ef1b56b6a96 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -106,6 +106,13 @@ static int mlx5_get_mcam_reg(struct mlx5_core_dev *dev)
                                   MLX5_MCAM_REGS_FIRST_128);
 }
 
+static int mlx5_get_qcam_reg(struct mlx5_core_dev *dev)
+{
+       return mlx5_query_qcam_reg(dev, dev->caps.qcam,
+                                  MLX5_QCAM_FEATURE_ENHANCED_FEATURES,
+                                  MLX5_QCAM_REGS_FIRST_128);
+}
+
 int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
 {
        int err;
@@ -182,6 +189,9 @@ int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
        if (MLX5_CAP_GEN(dev, mcam_reg))
                mlx5_get_mcam_reg(dev);
 
+       if (MLX5_CAP_GEN(dev, qcam_reg))
+               mlx5_get_qcam_reg(dev);
+
        return 0;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h 
b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 8f00de2fe283..ff4a0b889a6f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -122,6 +122,8 @@ int mlx5_query_pcam_reg(struct mlx5_core_dev *dev, u32 
*pcam, u8 feature_group,
                        u8 access_reg_group);
 int mlx5_query_mcam_reg(struct mlx5_core_dev *dev, u32 *mcap, u8 feature_group,
                        u8 access_reg_group);
+int mlx5_query_qcam_reg(struct mlx5_core_dev *mdev, u32 *qcam,
+                       u8 feature_group, u8 access_reg_group);
 
 void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev);
 void mlx5_lag_remove(struct mlx5_core_dev *dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c 
b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index e07061f565d6..b6553be841f9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -98,6 +98,18 @@ int mlx5_query_mcam_reg(struct mlx5_core_dev *dev, u32 
*mcam, u8 feature_group,
        return mlx5_core_access_reg(dev, in, sz, mcam, sz, MLX5_REG_MCAM, 0, 0);
 }
 
+int mlx5_query_qcam_reg(struct mlx5_core_dev *mdev, u32 *qcam,
+                       u8 feature_group, u8 access_reg_group)
+{
+       u32 in[MLX5_ST_SZ_DW(qcam_reg)] = {};
+       int sz = MLX5_ST_SZ_BYTES(qcam_reg);
+
+       MLX5_SET(qcam_reg, in, feature_group, feature_group);
+       MLX5_SET(qcam_reg, in, access_reg_group, access_reg_group);
+
+       return mlx5_core_access_reg(mdev, in, sz, qcam, sz, MLX5_REG_QCAM, 0, 
0);
+}
+
 struct mlx5_reg_pcap {
        u8                      rsvd0;
        u8                      port_num;
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index e32dbc4934db..6d79b3f79458 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -1000,6 +1000,14 @@ enum mlx5_mcam_feature_groups {
        MLX5_MCAM_FEATURE_ENHANCED_FEATURES         = 0x0,
 };
 
+enum mlx5_qcam_reg_groups {
+       MLX5_QCAM_REGS_FIRST_128                    = 0x0,
+};
+
+enum mlx5_qcam_feature_groups {
+       MLX5_QCAM_FEATURE_ENHANCED_FEATURES         = 0x0,
+};
+
 /* GET Dev Caps macros */
 #define MLX5_CAP_GEN(mdev, cap) \
        MLX5_GET(cmd_hca_cap, mdev->caps.hca_cur[MLX5_CAP_GENERAL], cap)
@@ -1108,6 +1116,12 @@ enum mlx5_mcam_feature_groups {
 #define MLX5_CAP_MCAM_FEATURE(mdev, fld) \
        MLX5_GET(mcam_reg, (mdev)->caps.mcam, 
mng_feature_cap_mask.enhanced_features.fld)
 
+#define MLX5_CAP_QCAM_REG(mdev, fld) \
+       MLX5_GET(qcam_reg, (mdev)->caps.qcam, 
qos_access_reg_cap_mask.reg_cap.fld)
+
+#define MLX5_CAP_QCAM_FEATURE(mdev, fld) \
+       MLX5_GET(qcam_reg, (mdev)->caps.qcam, 
qos_feature_cap_mask.feature_cap.fld)
+
 #define MLX5_CAP_FPGA(mdev, cap) \
        MLX5_GET(fpga_cap, (mdev)->caps.fpga, cap)
 
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 08c77b7e59cb..ed5be52282ea 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -109,6 +109,7 @@ enum {
 enum {
        MLX5_REG_QETCR           = 0x4005,
        MLX5_REG_QTCT            = 0x400a,
+       MLX5_REG_QCAM            = 0x4019,
        MLX5_REG_DCBX_PARAM      = 0x4020,
        MLX5_REG_DCBX_APP        = 0x4021,
        MLX5_REG_FPGA_CAP        = 0x4022,
@@ -798,6 +799,7 @@ struct mlx5_core_dev {
                u32 pcam[MLX5_ST_SZ_DW(pcam_reg)];
                u32 mcam[MLX5_ST_SZ_DW(mcam_reg)];
                u32 fpga[MLX5_ST_SZ_DW(fpga_cap)];
+               u32 qcam[MLX5_ST_SZ_DW(qcam_reg)];
        } caps;
        phys_addr_t             iseg_base;
        struct mlx5_init_seg __iomem *iseg;
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 69772347f866..f127c5b310c5 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -838,7 +838,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
        u8         cc_modify_allowed[0x1];
        u8         start_pad[0x1];
        u8         cache_line_128byte[0x1];
-       u8         reserved_at_165[0xb];
+       u8         reserved_at_165[0xa];
+       u8         qcam_reg[0x1];
        u8         gid_table_size[0x10];
 
        u8         out_of_seq_cnt[0x1];
@@ -7890,6 +7891,43 @@ struct mlx5_ifc_mcam_reg_bits {
        u8         reserved_at_1c0[0x80];
 };
 
+struct mlx5_ifc_qcam_access_reg_cap_mask {
+       u8         qcam_access_reg_cap_mask_127_to_20[0x6C];
+       u8         qpdpm[0x1];
+       u8         qcam_access_reg_cap_mask_18_to_4[0x0F];
+       u8         qdpm[0x1];
+       u8         qpts[0x1];
+       u8         qcap[0x1];
+       u8         qcam_access_reg_cap_mask_0[0x1];
+};
+
+struct mlx5_ifc_qcam_qos_feature_cap_mask {
+       u8         qcam_qos_feature_cap_mask_127_to_1[0x7F];
+       u8         qpts_trust_both[0x1];
+};
+
+struct mlx5_ifc_qcam_reg_bits {
+       u8         reserved_at_0[0x8];
+       u8         feature_group[0x8];
+       u8         reserved_at_10[0x8];
+       u8         access_reg_group[0x8];
+       u8         reserved_at_20[0x20];
+
+       union {
+               struct mlx5_ifc_qcam_access_reg_cap_mask reg_cap;
+               u8  reserved_at_0[0x80];
+       } qos_access_reg_cap_mask;
+
+       u8         reserved_at_c0[0x80];
+
+       union {
+               struct mlx5_ifc_qcam_qos_feature_cap_mask feature_cap;
+               u8  reserved_at_0[0x80];
+       } qos_feature_cap_mask;
+
+       u8         reserved_at_1c0[0x80];
+};
+
 struct mlx5_ifc_pcap_reg_bits {
        u8         reserved_at_0[0x8];
        u8         local_port[0x8];
-- 
2.14.2

Reply via email to