Apply the firmware COS mask/map when setting up Tx queues so the configured
COS value selects the intended queue.

Signed-off-by: Jiacheng Ye <[email protected]>
---
 doc/guides/rel_notes/release_26_11.rst   |  1 +
 drivers/net/hinic3/base/hinic3_hw_cfg.c  |  2 +
 drivers/net/hinic3/base/hinic3_hw_cfg.h  |  9 +++-
 drivers/net/hinic3/base/hinic3_nic_cfg.c |  2 +-
 drivers/net/hinic3/hinic3_ethdev.c       | 57 +++++++++++++++++++++---
 drivers/net/hinic3/hinic3_ethdev.h       |  2 +
 6 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/doc/guides/rel_notes/release_26_11.rst 
b/doc/guides/rel_notes/release_26_11.rst
index 31109a16a7..e1132b379a 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -96,6 +96,7 @@ New Features
 
   * Added CIR drop statistics and VF link aggregation (LAG) support.
   * Added FEC mode get and set support.
+  * Added Class of Service (COS) mask and map support.
 
 * **Updated Intel iavf driver.**
 
diff --git a/drivers/net/hinic3/base/hinic3_hw_cfg.c 
b/drivers/net/hinic3/base/hinic3_hw_cfg.c
index 8899f98515..e7971509d5 100644
--- a/drivers/net/hinic3/base/hinic3_hw_cfg.c
+++ b/drivers/net/hinic3/base/hinic3_hw_cfg.c
@@ -22,6 +22,8 @@ parse_pub_res_cap(struct service_cap *cap,
        cap->chip_svc_type = cap->svc_type;
 
        cap->cos_valid_bitmap = dev_cap->valid_cos_bitmap;
+       cap->cos_mask_mode = dev_cap->cos_mask_mode;
+       cap->cos_mask_bitmap = dev_cap->cos_mask_bitmap;
        cap->flexq_en = dev_cap->flexq_en;
 
        cap->host_total_function = dev_cap->host_total_func;
diff --git a/drivers/net/hinic3/base/hinic3_hw_cfg.h 
b/drivers/net/hinic3/base/hinic3_hw_cfg.h
index 46a9c9bf4b..217ecc92e0 100644
--- a/drivers/net/hinic3/base/hinic3_hw_cfg.h
+++ b/drivers/net/hinic3/base/hinic3_hw_cfg.h
@@ -40,6 +40,9 @@ struct service_cap {
 
        uint8_t flexq_en;
        uint8_t cos_valid_bitmap;
+       uint8_t port_cos_valid_bitmap;
+       uint8_t cos_mask_mode;
+       uint8_t cos_mask_bitmap;
        uint16_t max_vf; /**< Max VF number that PF supported. */
 
        struct nic_service_cap nic_cap; /**< NIC capability. */
@@ -80,9 +83,11 @@ struct hinic3_cfg_cmd_dev_cap {
        uint8_t flexq_en;
        uint8_t valid_cos_bitmap;
        /* Reserved for func_valid_cos_bitmap. */
-       uint16_t rsvd_cos;
+       uint16_t rsvd_valid_cos[2];
+       uint8_t cos_mask_mode;
+       uint8_t cos_mask_bitmap;
 
-       uint32_t rsvd[11];
+       uint32_t rsvd[10];
 
        /* l2nic */
        uint16_t nic_max_sq_id;
diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.c 
b/drivers/net/hinic3/base/hinic3_nic_cfg.c
index c67779349f..0a0c7e74e0 100644
--- a/drivers/net/hinic3/base/hinic3_nic_cfg.c
+++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c
@@ -1491,7 +1491,7 @@ hinic3_vf_get_default_cos(struct hinic3_hwdev *hwdev, 
uint8_t *cos_id)
                return -EIO;
        }
 
-       *cos_id = vf_dcb.state.default_cos % HINIC3_COS_NUM_MAX_HTN;
+       *cos_id = vf_dcb.state.default_cos;
 
        return 0;
 }
diff --git a/drivers/net/hinic3/hinic3_ethdev.c 
b/drivers/net/hinic3/hinic3_ethdev.c
index 6d789565d5..5a0e93ed8a 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -75,6 +75,9 @@ enum hinic3_rx_mod {
 #define HINIC3_DEFAULT_RX_MODE \
        (HINIC3_RX_MODE_UC | HINIC3_RX_MODE_MC | HINIC3_RX_MODE_BC)
 
+#define HINIC3_DEFAULT_COS_MASK                0x7
+#define HINIC3_DEFAULT_COS_MASK_BITMAP 0xff
+
 struct hinic3_xstats_name_off {
        char name[RTE_ETH_XSTATS_NAME_SIZE];
        uint32_t offset;
@@ -448,10 +451,8 @@ hinic3_deinit_mac_addr(struct rte_eth_dev *eth_dev)
 static int
 hinic3_pf_get_default_cos(struct hinic3_hwdev *hwdev, uint8_t *cos_id)
 {
-       struct hinic3_nic_dev *nic_dev = hwdev->dev_handle;
        uint8_t default_cos = 0;
        uint8_t valid_cos_bitmap;
-       uint8_t cos_num_max;
        uint8_t i;
 
        valid_cos_bitmap = hwdev->cfg_mgmt->svc_cap.cos_valid_bitmap;
@@ -460,10 +461,7 @@ hinic3_pf_get_default_cos(struct hinic3_hwdev *hwdev, 
uint8_t *cos_id)
                return -EFAULT;
        }
 
-       cos_num_max = nic_dev->feature_cap & NIC_F_HTN_CMDQ ?
-                     HINIC3_COS_NUM_MAX_HTN : HINIC3_COS_NUM_MAX;
-
-       for (i = 0; i < cos_num_max; i++) {
+       for (i = 0; i < HINIC3_COS_NUM_MAX; i++) {
                if (valid_cos_bitmap & RTE_BIT32(i))
                        /* Find max cos id as default cos. */
                        default_cos = i;
@@ -474,12 +472,53 @@ hinic3_pf_get_default_cos(struct hinic3_hwdev *hwdev, 
uint8_t *cos_id)
        return 0;
 }
 
+static void
+hinic3_get_cos_mask(struct hinic3_hwdev *hwdev, uint8_t *cos_mask)
+{
+       uint8_t cos_mask_mode;
+
+       cos_mask_mode = hwdev->cfg_mgmt->svc_cap.cos_mask_mode;
+       if (!cos_mask_mode) {
+               *cos_mask = HINIC3_DEFAULT_COS_MASK; /* default: 8 COS*/
+               PMD_DRV_LOG(INFO,
+                       "cos mask not provided by firmware, use default 0x%x",
+                       HINIC3_DEFAULT_COS_MASK);
+               return;
+       }
+
+       *cos_mask = cos_mask_mode;
+}
+
+static void
+hinic3_get_cos_mask_bitmap(struct hinic3_nic_dev *nic_dev)
+{
+       int i;
+       uint8_t default_cos = 0;
+       uint8_t cos_mask_bitmap = 
nic_dev->hwdev->cfg_mgmt->svc_cap.cos_mask_bitmap == 0
+                       ? HINIC3_DEFAULT_COS_MASK_BITMAP
+                       : nic_dev->hwdev->cfg_mgmt->svc_cap.cos_mask_bitmap;
+
+       PMD_DRV_LOG(INFO, "cos_mask_bitmap: 0x%x", cos_mask_bitmap);
+       for (i = HINIC3_COS_NUM_MAX - 1; i >= 0; i--) {
+               if (cos_mask_bitmap & RTE_BIT32(i)) {
+                       default_cos = i;
+                       break;
+               }
+       }
+
+       for (i = 0; i < HINIC3_COS_NUM_MAX; i++)
+               nic_dev->cos_map[i] = ((RTE_BIT32(i) & cos_mask_bitmap) == 0) ? 
default_cos : i;
+}
+
 static int
 hinic3_init_default_cos(struct hinic3_nic_dev *nic_dev)
 {
+       uint8_t cos_mask = 0;
        uint8_t cos_id = 0;
        int err;
 
+       hinic3_get_cos_mask(nic_dev->hwdev, &cos_mask);
+
        if (!HINIC3_IS_VF(nic_dev->hwdev)) {
                err = hinic3_pf_get_default_cos(nic_dev->hwdev, &cos_id);
                if (err) {
@@ -494,8 +533,9 @@ hinic3_init_default_cos(struct hinic3_nic_dev *nic_dev)
                }
        }
 
+       nic_dev->cos_mask = cos_mask;
        nic_dev->default_cos = cos_id;
-       PMD_DRV_LOG(DEBUG, "Default cos %d", nic_dev->default_cos);
+       PMD_DRV_LOG(DEBUG, "Default cos %d, cos mask %d", nic_dev->default_cos, 
nic_dev->cos_mask);
        return 0;
 }
 
@@ -514,6 +554,7 @@ hinic3_set_default_hw_feature(struct hinic3_nic_dev 
*nic_dev)
 {
        int err;
 
+       hinic3_get_cos_mask_bitmap(nic_dev);
        err = hinic3_init_default_cos(nic_dev);
        if (err)
                return err;
@@ -1275,6 +1316,8 @@ hinic3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t 
qid, uint16_t nb_desc,
        else
                txq->cos = nic_dev->default_cos;
 
+       txq->cos = nic_dev->cos_map[(int)(txq->cos) & nic_dev->cos_mask];
+
        txq->tx_deferred_start = tx_conf->tx_deferred_start;
        txq->tx_wqe_compact_task = HINIC3_SUPPORT_TX_WQE_COMPACT_TASK(nic_dev);
 
diff --git a/drivers/net/hinic3/hinic3_ethdev.h 
b/drivers/net/hinic3/hinic3_ethdev.h
index c1bba21486..73f47731bf 100644
--- a/drivers/net/hinic3/hinic3_ethdev.h
+++ b/drivers/net/hinic3/hinic3_ethdev.h
@@ -127,6 +127,7 @@ struct hinic3_nic_dev {
        uint8_t rx_queue_list[HINIC3_MAX_QUEUE_NUM];
        rte_spinlock_t queue_list_lock;
 
+       uint32_t cos_mask;
        uint32_t default_cos;
        uint32_t rx_csum_en;
 
@@ -149,6 +150,7 @@ struct hinic3_nic_dev {
        struct hinic3_tcam_info tcam;
        struct hinic3_ethertype_filter_list filter_ethertype_list;
        struct hinic3_fdir_rule_filter_list filter_fdir_rule_list;
+       uint8_t cos_map[HINIC3_COS_NUM_MAX];
        struct hinic3_nic_cmdq_ops *cmdq_ops;
        struct hinic3_nic_rx_ops *rx_ops;
        struct hinic3_nic_tx_ops *tx_ops;
-- 
2.33.0


Reply via email to