]> git.droids-corp.org - dpdk.git/commitdiff
net/hns3: fix interrupt resources in Rx interrupt mode
authorChengchang Tang <tangchengchang@huawei.com>
Fri, 22 Jan 2021 10:18:47 +0000 (18:18 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 29 Jan 2021 17:16:12 +0000 (18:16 +0100)
For Kunpeng930, the NIC engine support 1280 tqps being taken over by
a PF. In this case, a maximum of 1281 interrupt resources are also
supported in this PF. To support the maximum number of queues, several
patches are made. But the interrupt related modification are missing.
So, in RX interrupt mode, a large number of queues will be aggregated
into one interrupt due to insufficient interrupts. It will lead to
waste of interrupt resources and reduces usability.

To utilize all these interrupt resources, related IMP command has been
extended. And, the I/O address of the extended interrupt resources are
different from the existing ones. So, a function used for calculating
the address offset has been added.

Fixes: 76d794566d43 ("net/hns3: maximize queue number")
Fixes: 27911a6e62e5 ("net/hns3: add Rx interrupts compatibility")
Cc: stable@dpdk.org
Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
drivers/net/hns3/hns3_cmd.h
drivers/net/hns3/hns3_ethdev.c
drivers/net/hns3/hns3_regs.c
drivers/net/hns3/hns3_regs.h
drivers/net/hns3/hns3_rxtx.c
drivers/net/hns3/hns3_rxtx.h

index 6152f6ead129b15325805a88bf4c78a3a62556d8..dc97a1a8525cd187815b93ecd8d1b3e518a851cb 100644 (file)
@@ -776,12 +776,16 @@ enum hns3_int_gl_idx {
 #define HNS3_TQP_ID_M          GENMASK(12, 2)
 #define HNS3_INT_GL_IDX_S      13
 #define HNS3_INT_GL_IDX_M      GENMASK(14, 13)
+#define HNS3_TQP_INT_ID_L_S    0
+#define HNS3_TQP_INT_ID_L_M    GENMASK(7, 0)
+#define HNS3_TQP_INT_ID_H_S    8
+#define HNS3_TQP_INT_ID_H_M    GENMASK(15, 8)
 struct hns3_ctrl_vector_chain_cmd {
-       uint8_t int_vector_id;
+       uint8_t int_vector_id;    /* the low order of the interrupt id */
        uint8_t int_cause_num;
        uint16_t tqp_type_and_id[HNS3_VECTOR_ELEMENTS_PER_CMD];
        uint8_t vfid;
-       uint8_t rsv;
+       uint8_t int_vector_id_h;  /* the high order of the interrupt id */
 };
 
 struct hns3_config_max_frm_size_cmd {
index b89bc48714f083bf93810714d22c9ccab08cfb15..58d4f27530c93c93f8cd8b39a2f24a8311efe8c6 100644 (file)
@@ -2232,7 +2232,7 @@ hns3_check_dcb_cfg(struct rte_eth_dev *dev)
 }
 
 static int
-hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap,
+hns3_bind_ring_with_vector(struct hns3_hw *hw, uint16_t vector_id, bool en,
                           enum hns3_ring_type queue_type, uint16_t queue_id)
 {
        struct hns3_cmd_desc desc;
@@ -2241,13 +2241,15 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap,
        enum hns3_cmd_status status;
        enum hns3_opcode_type op;
        uint16_t tqp_type_and_id = 0;
-       const char *op_str;
        uint16_t type;
        uint16_t gl;
 
-       op = mmap ? HNS3_OPC_ADD_RING_TO_VECTOR : HNS3_OPC_DEL_RING_TO_VECTOR;
+       op = en ? HNS3_OPC_ADD_RING_TO_VECTOR : HNS3_OPC_DEL_RING_TO_VECTOR;
        hns3_cmd_setup_basic_desc(&desc, op, false);
-       req->int_vector_id = vector_id;
+       req->int_vector_id = hns3_get_field(vector_id, HNS3_TQP_INT_ID_L_M,
+                                             HNS3_TQP_INT_ID_L_S);
+       req->int_vector_id_h = hns3_get_field(vector_id, HNS3_TQP_INT_ID_H_M,
+                                             HNS3_TQP_INT_ID_H_S);
 
        if (queue_type == HNS3_RING_TYPE_RX)
                gl = HNS3_RING_GL_RX;
@@ -2263,11 +2265,10 @@ hns3_bind_ring_with_vector(struct hns3_hw *hw, uint8_t vector_id, bool mmap,
                       gl);
        req->tqp_type_and_id[0] = rte_cpu_to_le_16(tqp_type_and_id);
        req->int_cause_num = 1;
-       op_str = mmap ? "Map" : "Unmap";
        status = hns3_cmd_send(hw, &desc, 1);
        if (status) {
                hns3_err(hw, "%s TQP %u fail, vector_id is %u, status is %d.",
-                        op_str, queue_id, req->int_vector_id, status);
+                        en ? "Map" : "Unmap", queue_id, vector_id, status);
                return status;
        }
 
@@ -4797,8 +4798,8 @@ hns3_map_rx_interrupt(struct rte_eth_dev *dev)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
        struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
        struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-       uint8_t base = RTE_INTR_VEC_ZERO_OFFSET;
-       uint8_t vec = RTE_INTR_VEC_ZERO_OFFSET;
+       uint16_t base = RTE_INTR_VEC_ZERO_OFFSET;
+       uint16_t vec = RTE_INTR_VEC_ZERO_OFFSET;
        uint32_t intr_vector;
        uint16_t q_id;
        int ret;
index 01550458b7665833c45e54fbfe9f75f95d7f0824..84f31576324a2f3cab7dcab41ca2f8192e1881ee 100644 (file)
@@ -301,7 +301,7 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data)
 
        reg_num = sizeof(tqp_intr_reg_addrs) / sizeof(uint32_t);
        for (j = 0; j < hw->intr_tqps_num; j++) {
-               reg_offset = HNS3_TQP_INTR_REG_SIZE * j;
+               reg_offset = hns3_get_tqp_intr_reg_offset(j);
                for (i = 0; i < reg_num; i++)
                        *data++ = hns3_read_dev(hw, tqp_intr_reg_addrs[i] +
                                                reg_offset);
index 81a0af59e446ee9512d5f7a2cdec057e14e7c913..39fc5d1b187d411bade0d04ec6380adb61230065 100644 (file)
 #define HNS3_MIN_EXTEND_QUEUE_ID               1024
 
 /* bar registers for tqp interrupt */
-#define HNS3_TQP_INTR_CTRL_REG                 0x20000
-#define HNS3_TQP_INTR_GL0_REG                  0x20100
-#define HNS3_TQP_INTR_GL1_REG                  0x20200
-#define HNS3_TQP_INTR_GL2_REG                  0x20300
-#define HNS3_TQP_INTR_RL_REG                   0x20900
-#define HNS3_TQP_INTR_TX_QL_REG                        0x20e00
-#define HNS3_TQP_INTR_RX_QL_REG                        0x20f00
-
-#define HNS3_TQP_INTR_REG_SIZE                 4
+#define HNS3_TQP_INTR_REG_BASE                 0x20000
+#define HNS3_TQP_INTR_EXT_REG_BASE             0x30000
+#define HNS3_TQP_INTR_CTRL_REG                 0
+#define HNS3_TQP_INTR_GL0_REG                  0x100
+#define HNS3_TQP_INTR_GL1_REG                  0x200
+#define HNS3_TQP_INTR_GL2_REG                  0x300
+#define HNS3_TQP_INTR_RL_REG                   0x900
+#define HNS3_TQP_INTR_TX_QL_REG                        0xe00
+#define HNS3_TQP_INTR_RX_QL_REG                        0xf00
+#define HNS3_TQP_INTR_RL_EN_B                  6
+
+#define HNS3_MIN_EXT_TQP_INTR_ID               64
+#define HNS3_TQP_INTR_LOW_ORDER_OFFSET         0x4
+#define HNS3_TQP_INTR_HIGH_ORDER_OFFSET                0x1000
+
 #define HNS3_TQP_INTR_GL_MAX                   0x1FE0
 #define HNS3_TQP_INTR_GL_DEFAULT               20
 #define HNS3_TQP_INTR_GL_UNIT_1US              BIT(31)
index b958315b1295108452dd639eb57340de80e39d60..222cf8a4bfcbeb68635e1c8cf9fd61d2e6ed2852 100644 (file)
@@ -834,6 +834,24 @@ queue_reset_fail:
        return ret;
 }
 
+uint32_t
+hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id)
+{
+       uint32_t reg_offset;
+
+       /* Need an extend offset to config queues > 64 */
+       if (tqp_intr_id < HNS3_MIN_EXT_TQP_INTR_ID)
+               reg_offset = HNS3_TQP_INTR_REG_BASE +
+                            tqp_intr_id * HNS3_TQP_INTR_LOW_ORDER_OFFSET;
+       else
+               reg_offset = HNS3_TQP_INTR_EXT_REG_BASE +
+                            tqp_intr_id / HNS3_MIN_EXT_TQP_INTR_ID *
+                            HNS3_TQP_INTR_HIGH_ORDER_OFFSET +
+                            tqp_intr_id % HNS3_MIN_EXT_TQP_INTR_ID *
+                            HNS3_TQP_INTR_LOW_ORDER_OFFSET;
+
+       return reg_offset;
+}
 
 void
 hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id,
@@ -847,7 +865,7 @@ hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id,
        if (gl_idx >= RTE_DIM(offset) || gl_value > HNS3_TQP_INTR_GL_MAX)
                return;
 
-       addr = offset[gl_idx] + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = offset[gl_idx] + hns3_get_tqp_intr_reg_offset(queue_id);
        if (hw->intr.gl_unit == HNS3_INTR_COALESCE_GL_UINT_1US)
                value = gl_value | HNS3_TQP_INTR_GL_UNIT_1US;
        else
@@ -864,7 +882,7 @@ hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id, uint16_t rl_value)
        if (rl_value > HNS3_TQP_INTR_RL_MAX)
                return;
 
-       addr = HNS3_TQP_INTR_RL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_RL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        value = HNS3_RL_USEC_TO_REG(rl_value);
        if (value > 0)
                value |= HNS3_TQP_INTR_RL_ENABLE_MASK;
@@ -885,10 +903,10 @@ hns3_set_queue_intr_ql(struct hns3_hw *hw, uint16_t queue_id, uint16_t ql_value)
        if (hw->intr.int_ql_max == HNS3_INTR_QL_NONE)
                return;
 
-       addr = HNS3_TQP_INTR_TX_QL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_TX_QL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        hns3_write_dev(hw, addr, ql_value);
 
-       addr = HNS3_TQP_INTR_RX_QL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_RX_QL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        hns3_write_dev(hw, addr, ql_value);
 }
 
@@ -897,7 +915,7 @@ hns3_queue_intr_enable(struct hns3_hw *hw, uint16_t queue_id, bool en)
 {
        uint32_t addr, value;
 
-       addr = HNS3_TQP_INTR_CTRL_REG + queue_id * HNS3_TQP_INTR_REG_SIZE;
+       addr = HNS3_TQP_INTR_CTRL_REG + hns3_get_tqp_intr_reg_offset(queue_id);
        value = en ? 1 : 0;
 
        hns3_write_dev(hw, addr, value);
index 331b507fc8ca760cfad1056e38874100b67a0452..8f5ae5cf11afe65ee11d5bf2b81590255355bb8e 100644 (file)
@@ -680,6 +680,7 @@ int hns3_tx_burst_mode_get(struct rte_eth_dev *dev,
 const uint32_t *hns3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 void hns3_init_rx_ptype_tble(struct rte_eth_dev *dev);
 void hns3_set_rxtx_function(struct rte_eth_dev *eth_dev);
+uint32_t hns3_get_tqp_intr_reg_offset(uint16_t tqp_intr_id);
 void hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id,
                            uint8_t gl_idx, uint16_t gl_value);
 void hns3_set_queue_intr_rl(struct hns3_hw *hw, uint16_t queue_id,