From 2b6b09817dcfd81ff6017da49a68fab22c1cb9c2 Mon Sep 17 00:00:00 2001 From: Chengchang Tang Date: Fri, 22 Jan 2021 18:18:47 +0800 Subject: [PATCH] net/hns3: fix interrupt resources in Rx interrupt mode 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 --- drivers/net/hns3/hns3_cmd.h | 8 ++++++-- drivers/net/hns3/hns3_ethdev.c | 17 +++++++++-------- drivers/net/hns3/hns3_regs.c | 2 +- drivers/net/hns3/hns3_regs.h | 24 +++++++++++++++--------- drivers/net/hns3/hns3_rxtx.c | 28 +++++++++++++++++++++++----- drivers/net/hns3/hns3_rxtx.h | 1 + 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h index 6152f6ead1..dc97a1a852 100644 --- a/drivers/net/hns3/hns3_cmd.h +++ b/drivers/net/hns3/hns3_cmd.h @@ -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 { diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index b89bc48714..58d4f27530 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -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; diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c index 01550458b7..84f3157632 100644 --- a/drivers/net/hns3/hns3_regs.c +++ b/drivers/net/hns3/hns3_regs.c @@ -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); diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h index 81a0af59e4..39fc5d1b18 100644 --- a/drivers/net/hns3/hns3_regs.h +++ b/drivers/net/hns3/hns3_regs.h @@ -95,15 +95,21 @@ #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) diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c index b958315b12..222cf8a4bf 100644 --- a/drivers/net/hns3/hns3_rxtx.c +++ b/drivers/net/hns3/hns3_rxtx.c @@ -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); diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h index 331b507fc8..8f5ae5cf11 100644 --- a/drivers/net/hns3/hns3_rxtx.h +++ b/drivers/net/hns3/hns3_rxtx.h @@ -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, -- 2.20.1