From patchwork Tue Sep 29 12:01:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79188 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id BD74DA04C0; Tue, 29 Sep 2020 14:01:49 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D01A81DA33; Tue, 29 Sep 2020 14:01:29 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id DEA551BE86 for ; Tue, 29 Sep 2020 14:01:25 +0200 (CEST) X-ASG-Debug-ID: 1601380883-149d11049b296780001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id DsT8CGbvhHwsLydA (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:23 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:23 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:09 +0800 X-ASG-Orig-Subj: [PATCH v2 1/9] net/hns3: expand the number of queues for one TC up to 512 Message-ID: <20200929120117.50394-2-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380883 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 11605 Subject: [dpdk-dev] [PATCH v2 1/9] net/hns3: expand the number of queues for one TC up to 512 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Huisong Li The maximum number of queues for one TC hns3 PF PMD driver supported is 64 based on hns3 network engine with revision_id equals 0x21, while it is expanded up to 512 on hns3 network engine with revision_id equals 0x30. So the following points need to be modified to maintain better compatibility. 1) Using a extended rss_size_max field as the maximum queue number of one TC PF driver supported. 2) The data type of the RSS redirection table needs to be changed from uint8_t to uint16_t. 3) rss_tc_mode modification The bitwidth of tc_offset, meaning the rx queue index, has to expand from 10 bit to 11 bits. The tc_size, meaning the exponent with base 2 of queues supported on TC, needs to expand from 3 bits to 4 bits. 4) RSS indirection table modification Currently, a field with 7 bits width is used to record the queue index for RSS indirection table. It means that PF needs to expand the queue index field to 9 bits. As the RSS indirection table config command reserved 4 bytes to configure the RSS queue index, a extern field can be added. So an entries of RSS indirection table queue index has two fields to set: rss_result_l and rss_result_h, while rss_result_l records the lower 8 bits and rss_result_h records the higher 1 bit. In addition, 2~4 modifications is also compatible with hns3 VF PMD driver. Signed-off-by: Huisong Li Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_cmd.h | 17 ++++++++++++----- drivers/net/hns3/hns3_ethdev.c | 16 ++++++++++++++++ drivers/net/hns3/hns3_ethdev.h | 2 ++ drivers/net/hns3/hns3_fdir.c | 1 - drivers/net/hns3/hns3_flow.c | 8 +++----- drivers/net/hns3/hns3_rss.c | 34 +++++++++++++++++++++++++--------- drivers/net/hns3/hns3_rss.h | 5 +++-- 7 files changed, 61 insertions(+), 22 deletions(-) diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h index 0b531d9..dd50484 100644 --- a/drivers/net/hns3/hns3_cmd.h +++ b/drivers/net/hns3/hns3_cmd.h @@ -441,6 +441,8 @@ struct hns3_umv_spc_alc_cmd { #define HNS3_CFG_SPEED_ABILITY_M GENMASK(7, 0) #define HNS3_CFG_UMV_TBL_SPACE_S 16 #define HNS3_CFG_UMV_TBL_SPACE_M GENMASK(31, 16) +#define HNS3_CFG_EXT_RSS_SIZE_S 0 +#define HNS3_CFG_EXT_RSS_SIZE_M GENMASK(3, 0) #define HNS3_ACCEPT_TAG1_B 0 #define HNS3_ACCEPT_UNTAG1_B 1 @@ -567,20 +569,25 @@ struct hns3_rss_input_tuple_cmd { uint8_t rsv[16]; }; -#define HNS3_RSS_CFG_TBL_SIZE 16 +#define HNS3_RSS_CFG_TBL_SIZE 16 +#define HNS3_RSS_CFG_TBL_SIZE_H 4 +#define HNS3_RSS_CFG_TBL_BW_H 2 +#define HNS3_RSS_CFG_TBL_BW_L 8 /* Configure the indirection table, opcode:0x0D07 */ struct hns3_rss_indirection_table_cmd { uint16_t start_table_index; /* Bit3~0 must be 0x0. */ uint16_t rss_set_bitmap; - uint8_t rsv[4]; - uint8_t rss_result[HNS3_RSS_CFG_TBL_SIZE]; + uint8_t rss_result_h[HNS3_RSS_CFG_TBL_SIZE_H]; + uint8_t rss_result_l[HNS3_RSS_CFG_TBL_SIZE]; }; #define HNS3_RSS_TC_OFFSET_S 0 -#define HNS3_RSS_TC_OFFSET_M (0x3ff << HNS3_RSS_TC_OFFSET_S) +#define HNS3_RSS_TC_OFFSET_M GENMASK(10, 0) +#define HNS3_RSS_TC_SIZE_MSB_S 11 +#define HNS3_RSS_TC_SIZE_MSB_OFFSET 3 #define HNS3_RSS_TC_SIZE_S 12 -#define HNS3_RSS_TC_SIZE_M (0x7 << HNS3_RSS_TC_SIZE_S) +#define HNS3_RSS_TC_SIZE_M GENMASK(14, 12) #define HNS3_RSS_TC_VALID_B 15 /* Configure the tc_size and tc_offset, opcode:0x0D08 */ diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 99bcc7a..c45b1b3 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -2709,6 +2709,7 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) { struct hns3_cfg_param_cmd *req; uint64_t mac_addr_tmp_high; + uint8_t ext_rss_size_max; uint64_t mac_addr_tmp; uint32_t i; @@ -2761,6 +2762,21 @@ hns3_parse_cfg(struct hns3_cfg *cfg, struct hns3_cmd_desc *desc) HNS3_CFG_UMV_TBL_SPACE_S); if (!cfg->umv_space) cfg->umv_space = HNS3_DEFAULT_UMV_SPACE_PER_PF; + + ext_rss_size_max = hns3_get_field(rte_le_to_cpu_32(req->param[2]), + HNS3_CFG_EXT_RSS_SIZE_M, + HNS3_CFG_EXT_RSS_SIZE_S); + + /* + * Field ext_rss_size_max obtained from firmware will be more flexible + * for future changes and expansions, which is an exponent of 2, instead + * of reading out directly. If this field is not zero, hns3 PF PMD + * driver uses it as rss_size_max under one TC. Device, whose revision + * id is greater than or equal to PCI_REVISION_ID_HIP09_A, obtains the + * maximum number of queues supported under a TC through this field. + */ + if (ext_rss_size_max) + cfg->rss_size_max = 1U << ext_rss_size_max; } /* hns3_get_board_cfg: query the static parameter from NCL_config file in flash diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h index c2d0a75..3c5ccc7 100644 --- a/drivers/net/hns3/hns3_ethdev.h +++ b/drivers/net/hns3/hns3_ethdev.h @@ -64,6 +64,8 @@ #define HNS3_HIP08_MIN_TX_PKT_LEN 33 #define HNS3_HIP09_MIN_TX_PKT_LEN 9 +#define HNS3_BITS_PER_BYTE 8 + #define HNS3_4_TCS 4 #define HNS3_8_TCS 8 diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c index 65ab19d..e6a065b 100644 --- a/drivers/net/hns3/hns3_fdir.c +++ b/drivers/net/hns3/hns3_fdir.c @@ -125,7 +125,6 @@ static const struct key_info tuple_key_info[] = { {INNER_SCTP_TAG, 32}, }; -#define HNS3_BITS_PER_BYTE 8 #define MAX_KEY_LENGTH 400 #define MAX_200B_KEY_LENGTH 200 #define MAX_META_DATA_LENGTH 16 diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c index 2cdfb68..f8e5f05 100644 --- a/drivers/net/hns3/hns3_flow.c +++ b/drivers/net/hns3/hns3_flow.c @@ -1531,15 +1531,14 @@ hns3_update_indir_table(struct rte_eth_dev *dev, { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; - uint8_t indir_tbl[HNS3_RSS_IND_TBL_SIZE]; + uint16_t indir_tbl[HNS3_RSS_IND_TBL_SIZE]; uint16_t j, allow_rss_queues; - uint8_t queue_id; uint32_t i; allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max); /* Fill in redirection table */ memcpy(indir_tbl, hw->rss_info.rss_indirection_tbl, - HNS3_RSS_IND_TBL_SIZE); + sizeof(hw->rss_info.rss_indirection_tbl)); for (i = 0, j = 0; i < HNS3_RSS_IND_TBL_SIZE; i++, j++) { j %= num; if (conf->queue[j] >= allow_rss_queues) { @@ -1549,8 +1548,7 @@ hns3_update_indir_table(struct rte_eth_dev *dev, allow_rss_queues); return -EINVAL; } - queue_id = conf->queue[j]; - indir_tbl[i] = queue_id; + indir_tbl[i] = conf->queue[j]; } return hns3_set_rss_indir_table(hw, indir_tbl, HNS3_RSS_IND_TBL_SIZE); diff --git a/drivers/net/hns3/hns3_rss.c b/drivers/net/hns3/hns3_rss.c index 5b51512..a8b8143 100644 --- a/drivers/net/hns3/hns3_rss.c +++ b/drivers/net/hns3/hns3_rss.c @@ -266,11 +266,15 @@ hns3_set_rss_input_tuple(struct hns3_hw *hw) * Used to configure the indirection table of rss. */ int -hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) +hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) { struct hns3_rss_indirection_table_cmd *req; struct hns3_cmd_desc desc; - int ret, i, j, num; + uint8_t qid_msb_off; + uint8_t qid_msb_val; + uint16_t q_id; + uint16_t i, j; + int ret; req = (struct hns3_rss_indirection_table_cmd *)desc.data; @@ -281,9 +285,17 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { - num = i * HNS3_RSS_CFG_TBL_SIZE + j; - req->rss_result[j] = indir[num]; + q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; + req->rss_result_l[j] = q_id & 0xff; + + qid_msb_off = + j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; + qid_msb_val = (q_id >> HNS3_RSS_CFG_TBL_BW_L & 0x1) + << (j * HNS3_RSS_CFG_TBL_BW_H % + HNS3_BITS_PER_BYTE); + req->rss_result_h[qid_msb_off] |= qid_msb_val; } + ret = hns3_cmd_send(hw, &desc, 1); if (ret) { hns3_err(hw, @@ -294,7 +306,8 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) } /* Update redirection table of hw */ - memcpy(hw->rss_info.rss_indirection_tbl, indir, HNS3_RSS_IND_TBL_SIZE); + memcpy(hw->rss_info.rss_indirection_tbl, indir, + sizeof(hw->rss_info.rss_indirection_tbl)); return 0; } @@ -302,10 +315,11 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size) int hns3_rss_reset_indir_table(struct hns3_hw *hw) { - uint8_t *lut; + uint16_t *lut; int ret; - lut = rte_zmalloc("hns3_rss_lut", HNS3_RSS_IND_TBL_SIZE, 0); + lut = rte_zmalloc("hns3_rss_lut", + HNS3_RSS_IND_TBL_SIZE * sizeof(uint16_t), 0); if (lut == NULL) { hns3_err(hw, "No hns3_rss_lut memory can be allocated"); return -ENOMEM; @@ -487,7 +501,7 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, struct hns3_hw *hw = &hns->hw; struct hns3_rss_conf *rss_cfg = &hw->rss_info; uint16_t i, indir_size = HNS3_RSS_IND_TBL_SIZE; /* Table size is 512 */ - uint8_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; + uint16_t indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; uint16_t idx, shift, allow_rss_queues; int ret; @@ -499,7 +513,7 @@ hns3_dev_rss_reta_update(struct rte_eth_dev *dev, } rte_spinlock_lock(&hw->lock); memcpy(indirection_tbl, rss_cfg->rss_indirection_tbl, - HNS3_RSS_IND_TBL_SIZE); + sizeof(rss_cfg->rss_indirection_tbl)); allow_rss_queues = RTE_MIN(dev->data->nb_rx_queues, hw->rss_size_max); for (i = 0; i < reta_size; i++) { idx = i / RTE_RETA_GROUP_SIZE; @@ -598,6 +612,8 @@ hns3_set_rss_tc_mode(struct hns3_hw *hw) hns3_set_bit(mode, HNS3_RSS_TC_VALID_B, (tc_valid[i] & 0x1)); hns3_set_field(mode, HNS3_RSS_TC_SIZE_M, HNS3_RSS_TC_SIZE_S, tc_size[i]); + if (tc_size[i] >> HNS3_RSS_TC_SIZE_MSB_OFFSET > 0) + hns3_set_bit(mode, HNS3_RSS_TC_SIZE_MSB_S, 1); hns3_set_field(mode, HNS3_RSS_TC_OFFSET_M, HNS3_RSS_TC_OFFSET_S, tc_offset[i]); diff --git a/drivers/net/hns3/hns3_rss.h b/drivers/net/hns3/hns3_rss.h index 8fa1b30..b5ac8ae 100644 --- a/drivers/net/hns3/hns3_rss.h +++ b/drivers/net/hns3/hns3_rss.h @@ -45,7 +45,7 @@ struct hns3_rss_conf { uint8_t hash_algo; /* hash function type definited by hardware */ uint8_t key[HNS3_RSS_KEY_SIZE]; /* Hash key */ struct hns3_rss_tuple_cfg rss_tuple_sets; - uint8_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; /* Shadow table */ + uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE]; /* Shadow table */ uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ bool valid; /* check if RSS rule is valid */ }; @@ -97,7 +97,8 @@ int hns3_dev_rss_reta_query(struct rte_eth_dev *dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size); void hns3_set_default_rss_args(struct hns3_hw *hw); -int hns3_set_rss_indir_table(struct hns3_hw *hw, uint8_t *indir, uint16_t size); +int hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, + uint16_t size); int hns3_rss_reset_indir_table(struct hns3_hw *hw); int hns3_config_rss(struct hns3_adapter *hns); void hns3_rss_uninit(struct hns3_adapter *hns); From patchwork Tue Sep 29 12:01:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79193 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 311B5A04C0; Tue, 29 Sep 2020 14:03:48 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4EE921DA8D; Tue, 29 Sep 2020 14:01:41 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id 796BC1BDDC for ; Tue, 29 Sep 2020 14:01:26 +0200 (CEST) X-ASG-Debug-ID: 1601380884-149d11049a296780001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id kEGdNygePRq9y3PC (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:24 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:23 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:10 +0800 X-ASG-Orig-Subj: [PATCH v2 2/9] net/hns3: maximize the queue number Message-ID: <20200929120117.50394-3-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380884 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 39702 Subject: [dpdk-dev] [PATCH v2 2/9] net/hns3: maximize the queue number X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: "Wei Hu (Xavier)" The maximum number of queues for hns3 PF and VF driver is 64 based on hns3 network engine with revision_id equals 0x21. Based on hns3 network engine with revision_id equals 0x30, the hns3 PF PMD driver can support up to 1280 queues, and hns3 VF PMD driver can support up to 128 queues. The following points need to be modified to support maximizing queue number and maintain better compatibility: 1) Maximizing the number of queues for hns3 PF and VF PMD driver In current version, VF is not supported when PF is driven by hns3 PMD driver. If maximum queue numbers allocated to PF PMD driver is less than total tqps_num allocated to this port, all remaining number of queues are mapped to VF function, which is unreasonable. So we fix that all remaining number of queues are mapped to PF function. Using RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF which comes from configuration file to limit the queue number allocated to PF device based on hns3 network engine with revision_id greater than 0x30. And PF device still keep the maximum 64 queues based on hns3 network engine with revision_id equals 0x21. Remove restriction of the macro HNS3_MAX_TQP_NUM_PER_FUNC on the maximum number of queues in hns3 VF PMD driver and use the value allocated by hns3 PF kernel netdev driver. 2) According to the queue number allocated to PF device, a variable array for Rx and Tx queue is dynamically allocated to record the statistics of Rx and Tx queues during the .dev_init ops implementation function. 3) Add an extended field in hns3_pf_res_cmd to support the case that numbers of queue are greater than 1024. 4) Use new base address of Rx or Tx queue if QUEUE_ID of Rx or Tx queue is greater than 1024. 5) Remove queue id mask and use all bits of actual queue_id as the queue_id to configure hardware. 6) Currently, 0~9 bits of qset_id in hns3_nq_to_qs_link_cmd used to record actual qset id and 10 bit as VLD bit are configured to hardware. So we also need to use 11~15 bits when actual qset_id is greater than 1024. 7) The number of queue sets based on different network engine are different. We use it to calculate group number and configure to hardware in the backpressure configuration. 8) Adding check operations for number of Rx and Tx queue user configured when mapping queue to tc Rx queue numbers under a single TC must be less than rss_size_max supported by a single TC. Rx and Tx queue numbers are allocated to every TC by average. So Rx and Tx queue numbers must be an integer multiple of 2, or redundant queues are not available. 9) We can specify which packets enter the queue with a specific queue number, when creating flow table rules by rte_flow API. Currently, driver uses 0~9 bits to record the queue_id. So it is necessary to extend one bit field to record queue_id and configure to hardware, if the queue_id is greater than 1024. Signed-off-by: Huisong Li Signed-off-by: Wei Hu (Xavier) --- v1 -> v2: fix typo. replace 'fpr' with 'for'. --- config/rte_config.h | 3 + drivers/net/hns3/hns3_cmd.h | 7 +- drivers/net/hns3/hns3_dcb.c | 138 +++++++++++++++++++++++++++++++------- drivers/net/hns3/hns3_dcb.h | 21 +++--- drivers/net/hns3/hns3_ethdev.c | 100 +++++++++++++++++++-------- drivers/net/hns3/hns3_ethdev.h | 30 ++++++++- drivers/net/hns3/hns3_ethdev_vf.c | 59 +++++++++------- drivers/net/hns3/hns3_fdir.c | 5 ++ drivers/net/hns3/hns3_regs.c | 2 +- drivers/net/hns3/hns3_regs.h | 3 + drivers/net/hns3/hns3_rxtx.c | 28 ++++++-- drivers/net/hns3/hns3_rxtx.h | 2 + drivers/net/hns3/hns3_stats.c | 73 +++++++++++++++----- drivers/net/hns3/hns3_stats.h | 6 +- 14 files changed, 362 insertions(+), 115 deletions(-) diff --git a/config/rte_config.h b/config/rte_config.h index 0bae630..03d90d7 100644 --- a/config/rte_config.h +++ b/config/rte_config.h @@ -117,6 +117,9 @@ /* fm10k defines */ #define RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE 1 +/* hns3 defines */ +#define RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF 256 + /* i40e defines */ #define RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC 1 #undef RTE_LIBRTE_I40E_16BYTE_RX_DESC diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h index dd50484..ecca75c 100644 --- a/drivers/net/hns3/hns3_cmd.h +++ b/drivers/net/hns3/hns3_cmd.h @@ -9,7 +9,6 @@ #define HNS3_CMDQ_RX_INVLD_B 0 #define HNS3_CMDQ_RX_OUTVLD_B 1 #define HNS3_CMD_DESC_ALIGNMENT 4096 -#define HNS3_QUEUE_ID_MASK 0x1ff #define HNS3_CMD_FLAG_NEXT BIT(2) struct hns3_hw; @@ -388,7 +387,8 @@ struct hns3_pf_res_cmd { uint16_t pf_own_fun_number; uint16_t tx_buf_size; uint16_t dv_buf_size; - uint16_t tqp_num_ext; + /* number of queues that exceed 1024 */ + uint16_t ext_tqp_num; uint16_t roh_pf_intr_vector_number; uint32_t rsv[1]; }; @@ -671,7 +671,6 @@ struct hns3_config_mac_speed_dup_cmd { uint8_t rsv[22]; }; -#define HNS3_RING_ID_MASK GENMASK(9, 0) #define HNS3_TQP_ENABLE_B 0 #define HNS3_MAC_CFG_AN_EN_B 0 @@ -835,7 +834,7 @@ struct hns3_dev_specs_0_cmd { uint32_t max_tm_rate; }; -#define HNS3_MAX_TQP_NUM_PER_FUNC 64 +#define HNS3_MAX_TQP_NUM_HIP08_PF 64 #define HNS3_DEFAULT_TX_BUF 0x4000 /* 16k bytes */ #define HNS3_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ #define HNS3_DEFAULT_DV 0xA000 /* 40k byte */ diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c index c1be49e..fecedff 100644 --- a/drivers/net/hns3/hns3_dcb.c +++ b/drivers/net/hns3/hns3_dcb.c @@ -576,21 +576,31 @@ hns3_dcb_pri_shaper_cfg(struct hns3_hw *hw) return ret; } -void +static int hns3_set_rss_size(struct hns3_hw *hw, uint16_t nb_rx_q) { struct hns3_rss_conf *rss_cfg = &hw->rss_info; uint16_t rx_qnum_per_tc; + uint16_t used_rx_queues; int i; rx_qnum_per_tc = nb_rx_q / hw->num_tc; - rx_qnum_per_tc = RTE_MIN(hw->rss_size_max, rx_qnum_per_tc); - if (hw->alloc_rss_size != rx_qnum_per_tc) { - hns3_info(hw, "rss size changes from %u to %u", - hw->alloc_rss_size, rx_qnum_per_tc); - hw->alloc_rss_size = rx_qnum_per_tc; + if (rx_qnum_per_tc > hw->rss_size_max) { + hns3_err(hw, "rx queue number of per tc (%u) is greater than " + "value (%u) hardware supported.", + rx_qnum_per_tc, hw->rss_size_max); + return -EINVAL; } - hw->used_rx_queues = hw->num_tc * hw->alloc_rss_size; + + used_rx_queues = hw->num_tc * rx_qnum_per_tc; + if (used_rx_queues != nb_rx_q) { + hns3_err(hw, "rx queue number (%u) configured must be an " + "integral multiple of valid tc number (%u).", + nb_rx_q, hw->num_tc); + return -EINVAL; + } + hw->alloc_rss_size = rx_qnum_per_tc; + hw->used_rx_queues = used_rx_queues; /* * When rss size is changed, we need to update rss redirection table @@ -604,15 +614,29 @@ hns3_set_rss_size(struct hns3_hw *hw, uint16_t nb_rx_q) rss_cfg->rss_indirection_tbl[i] = i % hw->alloc_rss_size; } + + return 0; } -void -hns3_tc_queue_mapping_cfg(struct hns3_hw *hw, uint16_t nb_queue) +static int +hns3_tc_queue_mapping_cfg(struct hns3_hw *hw, uint16_t nb_tx_q) { struct hns3_tc_queue_info *tc_queue; + uint16_t used_tx_queues; + uint16_t tx_qnum_per_tc; uint8_t i; - hw->tx_qnum_per_tc = nb_queue / hw->num_tc; + tx_qnum_per_tc = nb_tx_q / hw->num_tc; + used_tx_queues = hw->num_tc * tx_qnum_per_tc; + if (used_tx_queues != nb_tx_q) { + hns3_err(hw, "tx queue number (%u) configured must be an " + "integral multiple of valid tc number (%u).", + nb_tx_q, hw->num_tc); + return -EINVAL; + } + + hw->used_tx_queues = used_tx_queues; + hw->tx_qnum_per_tc = tx_qnum_per_tc; for (i = 0; i < HNS3_MAX_TC_NUM; i++) { tc_queue = &hw->tc_queue[i]; if (hw->hw_tc_map & BIT(i) && i < hw->num_tc) { @@ -628,22 +652,39 @@ hns3_tc_queue_mapping_cfg(struct hns3_hw *hw, uint16_t nb_queue) tc_queue->tc = 0; } } - hw->used_tx_queues = hw->num_tc * hw->tx_qnum_per_tc; + + return 0; } -static void +int +hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, uint16_t nb_tx_q) +{ + int ret; + + ret = hns3_set_rss_size(hw, nb_rx_q); + if (ret) + return ret; + + return hns3_tc_queue_mapping_cfg(hw, nb_tx_q); +} + +static int hns3_dcb_update_tc_queue_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, uint16_t nb_tx_q) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_pf *pf = &hns->pf; + int ret; hw->num_tc = hw->dcb_info.num_tc; - hns3_set_rss_size(hw, nb_rx_q); - hns3_tc_queue_mapping_cfg(hw, nb_tx_q); + ret = hns3_queue_to_tc_mapping(hw, nb_rx_q, nb_tx_q); + if (ret) + return ret; if (!hns->is_vf) memcpy(pf->prio_tc, hw->dcb_info.prio_tc, HNS3_MAX_USER_PRIO); + + return 0; } int @@ -886,13 +927,35 @@ hns3_q_to_qs_map_cfg(struct hns3_hw *hw, uint16_t q_id, uint16_t qs_id) { struct hns3_nq_to_qs_link_cmd *map; struct hns3_cmd_desc desc; + uint16_t tmp_qs_id = 0; + uint16_t qs_id_l; + uint16_t qs_id_h; hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_TM_NQ_TO_QS_LINK, false); map = (struct hns3_nq_to_qs_link_cmd *)desc.data; map->nq_id = rte_cpu_to_le_16(q_id); - map->qset_id = rte_cpu_to_le_16(qs_id | HNS3_DCB_Q_QS_LINK_VLD_MSK); + + /* + * Network engine with revision_id 0x21 uses 0~9 bit of qs_id to + * configure qset_id. So we need to convert qs_id to the follow + * format to support qset_id > 1024. + * qs_id: | 15 | 14 ~ 10 | 9 ~ 0 | + * / / \ \ + * / / \ \ + * qset_id: | 15 ~ 11 | 10 | 9 ~ 0 | + * | qs_id_h | vld | qs_id_l | + */ + qs_id_l = hns3_get_field(qs_id, HNS3_DCB_QS_ID_L_MSK, + HNS3_DCB_QS_ID_L_S); + qs_id_h = hns3_get_field(qs_id, HNS3_DCB_QS_ID_H_MSK, + HNS3_DCB_QS_ID_H_S); + hns3_set_field(tmp_qs_id, HNS3_DCB_QS_ID_L_MSK, HNS3_DCB_QS_ID_L_S, + qs_id_l); + hns3_set_field(tmp_qs_id, HNS3_DCB_QS_ID_H_EXT_MSK, + HNS3_DCB_QS_ID_H_EXT_S, qs_id_h); + map->qset_id = rte_cpu_to_le_16(tmp_qs_id | HNS3_DCB_Q_QS_LINK_VLD_MSK); return hns3_cmd_send(hw, &desc, 1); } @@ -1291,7 +1354,7 @@ hns3_dcb_cfg_validate(struct hns3_adapter *hns, uint8_t *tc, bool *changed) *changed = true; } -static void +static int hns3_dcb_info_cfg(struct hns3_adapter *hns) { struct rte_eth_dcb_rx_conf *dcb_rx_conf; @@ -1299,6 +1362,7 @@ hns3_dcb_info_cfg(struct hns3_adapter *hns) struct hns3_hw *hw = &hns->hw; uint8_t tc_bw, bw_rest; uint8_t i, j; + int ret; dcb_rx_conf = &hw->data->dev_conf.rx_adv_conf.dcb_rx_conf; pf->local_max_tc = (uint8_t)dcb_rx_conf->nb_tcs; @@ -1338,8 +1402,12 @@ hns3_dcb_info_cfg(struct hns3_adapter *hns) for (i = 0; i < HNS3_MAX_USER_PRIO; i++) hw->dcb_info.prio_tc[i] = dcb_rx_conf->dcb_tc[i]; - hns3_dcb_update_tc_queue_mapping(hw, hw->data->nb_rx_queues, - hw->data->nb_tx_queues); + ret = hns3_dcb_update_tc_queue_mapping(hw, hw->data->nb_rx_queues, + hw->data->nb_tx_queues); + if (ret) + hns3_err(hw, "update tc queue mapping failed, ret = %d.", ret); + + return ret; } static int @@ -1378,9 +1446,8 @@ hns3_dcb_info_update(struct hns3_adapter *hns, uint8_t num_tc) hw->dcb_info.num_tc = 1; } hw->hw_tc_map = bit_map; - hns3_dcb_info_cfg(hns); - return 0; + return hns3_dcb_info_cfg(hns); } static int @@ -1505,6 +1572,7 @@ hns3_dcb_init(struct hns3_hw *hw) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_pf *pf = &hns->pf; + uint16_t default_tqp_num; int ret; PMD_INIT_FUNC_TRACE(); @@ -1525,11 +1593,24 @@ hns3_dcb_init(struct hns3_hw *hw) ret = hns3_dcb_info_init(hw); if (ret) { - hns3_err(hw, "dcb info init failed: %d", ret); + hns3_err(hw, "dcb info init failed, ret = %d.", ret); + return ret; + } + + /* + * The number of queues configured by default cannot exceed + * the maximum number of queues for a single TC. + */ + default_tqp_num = RTE_MIN(hw->rss_size_max, + hw->tqps_num / hw->dcb_info.num_tc); + ret = hns3_dcb_update_tc_queue_mapping(hw, default_tqp_num, + default_tqp_num); + if (ret) { + hns3_err(hw, + "update tc queue mapping failed, ret = %d.", + ret); return ret; } - hns3_dcb_update_tc_queue_mapping(hw, hw->tqps_num, - hw->tqps_num); } /* @@ -1541,7 +1622,7 @@ hns3_dcb_init(struct hns3_hw *hw) */ ret = hns3_dcb_init_hw(hw); if (ret) { - hns3_err(hw, "dcb init hardware failed: %d", ret); + hns3_err(hw, "dcb init hardware failed, ret = %d.", ret); return ret; } @@ -1556,10 +1637,15 @@ hns3_update_queue_map_configure(struct hns3_adapter *hns) uint16_t nb_tx_q = hw->data->nb_tx_queues; int ret; - hns3_dcb_update_tc_queue_mapping(hw, nb_rx_q, nb_tx_q); + ret = hns3_dcb_update_tc_queue_mapping(hw, nb_rx_q, nb_tx_q); + if (ret) { + hns3_err(hw, "failed to update tc queue mapping, ret = %d.", + ret); + return ret; + } ret = hns3_q_to_qs_map(hw); if (ret) - hns3_err(hw, "failed to map nq to qs! ret = %d", ret); + hns3_err(hw, "failed to map nq to qs, ret = %d.", ret); return ret; } diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h index 557d88b..05c9786 100644 --- a/drivers/net/hns3/hns3_dcb.h +++ b/drivers/net/hns3/hns3_dcb.h @@ -52,6 +52,12 @@ struct hns3_qs_to_pri_link_cmd { uint16_t rsvd; uint8_t priority; #define HNS3_DCB_QS_PRI_LINK_VLD_MSK BIT(0) +#define HNS3_DCB_QS_ID_L_MSK GENMASK(9, 0) +#define HNS3_DCB_QS_ID_L_S 0 +#define HNS3_DCB_QS_ID_H_MSK GENMASK(14, 10) +#define HNS3_DCB_QS_ID_H_S 10 +#define HNS3_DCB_QS_ID_H_EXT_S 11 +#define HNS3_DCB_QS_ID_H_EXT_MSK GENMASK(15, 11) uint8_t link_vld; uint8_t rsvd1[18]; }; @@ -89,11 +95,12 @@ struct hns3_pg_shapping_cmd { uint32_t rsvd1[4]; }; -#define HNS3_BP_GRP_NUM 32 +#define HNS3_BP_GRP_NUM 32 #define HNS3_BP_SUB_GRP_ID_S 0 #define HNS3_BP_SUB_GRP_ID_M GENMASK(4, 0) #define HNS3_BP_GRP_ID_S 5 #define HNS3_BP_GRP_ID_M GENMASK(9, 5) + struct hns3_bp_to_qs_map_cmd { uint8_t tc_id; uint8_t rsvd[2]; @@ -165,15 +172,13 @@ int hns3_dcb_init_hw(struct hns3_hw *hw); int hns3_dcb_info_init(struct hns3_hw *hw); -int -hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf); - -int -hns3_dcb_pfc_enable(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf); +int hns3_fc_enable(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf); -void hns3_set_rss_size(struct hns3_hw *hw, uint16_t nb_rx_q); +int hns3_dcb_pfc_enable(struct rte_eth_dev *dev, + struct rte_eth_pfc_conf *pfc_conf); -void hns3_tc_queue_mapping_cfg(struct hns3_hw *hw, uint16_t nb_queue); +int hns3_queue_to_tc_mapping(struct hns3_hw *hw, uint16_t nb_rx_q, + uint16_t nb_tx_q); int hns3_dcb_cfg_update(struct hns3_adapter *hns); diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index c45b1b3..6e0f52b 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -2660,6 +2660,49 @@ hns3_query_function_status(struct hns3_hw *hw) } static int +hns3_get_pf_max_tqp_num(struct hns3_hw *hw) +{ + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + struct hns3_pf *pf = &hns->pf; + + if (pf->tqp_config_mode == HNS3_FLEX_MAX_TQP_NUM_MODE) { + /* + * The total_tqps_num obtained from firmware is maximum tqp + * numbers of this port, which should be used for PF and VFs. + * There is no need for pf to have so many tqp numbers in + * most cases. RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF, + * coming from config file, is assigned to maximum queue number + * for the PF of this port by user. So users can modify the + * maximum queue number of PF according to their own application + * scenarios, which is more flexible to use. In addition, many + * memories can be saved due to allocating queue statistics + * room according to the actual number of queues required. The + * maximum queue number of PF for network engine with + * revision_id greater than 0x30 is assigned by config file. + */ + if (RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF <= 0) { + hns3_err(hw, "RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF(%d) " + "must be greater than 0.", + RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF); + return -EINVAL; + } + + hw->tqps_num = RTE_MIN(RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF, + hw->total_tqps_num); + } else { + /* + * Due to the limitation on the number of PF interrupts + * available, the maximum queue number assigned to PF on + * the network engine with revision_id 0x21 is 64. + */ + hw->tqps_num = RTE_MIN(hw->total_tqps_num, + HNS3_MAX_TQP_NUM_HIP08_PF); + } + + return 0; +} + +static int hns3_query_pf_resource(struct hns3_hw *hw) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); @@ -2676,9 +2719,13 @@ hns3_query_pf_resource(struct hns3_hw *hw) } req = (struct hns3_pf_res_cmd *)desc.data; - hw->total_tqps_num = rte_le_to_cpu_16(req->tqp_num); + hw->total_tqps_num = rte_le_to_cpu_16(req->tqp_num) + + rte_le_to_cpu_16(req->ext_tqp_num); + ret = hns3_get_pf_max_tqp_num(hw); + if (ret) + return ret; + pf->pkt_buf_size = rte_le_to_cpu_16(req->buf_size) << HNS3_BUF_UNIT_S; - hw->tqps_num = RTE_MIN(hw->total_tqps_num, HNS3_MAX_TQP_NUM_PER_FUNC); pf->func_num = rte_le_to_cpu_16(req->pf_own_fun_number); if (req->tx_buf_size) @@ -2902,7 +2949,9 @@ hns3_query_dev_specifications(struct hns3_hw *hw) static int hns3_get_capability(struct hns3_hw *hw) { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct rte_pci_device *pci_dev; + struct hns3_pf *pf = &hns->pf; struct rte_eth_dev *eth_dev; uint16_t device_id; uint8_t revision; @@ -2936,6 +2985,7 @@ hns3_get_capability(struct hns3_hw *hw) hw->tso_mode = HNS3_TSO_SW_CAL_PSEUDO_H_CSUM; hw->vlan_mode = HNS3_SW_SHIFT_AND_DISCARD_MODE; hw->min_tx_pkt_len = HNS3_HIP08_MIN_TX_PKT_LEN; + pf->tqp_config_mode = HNS3_FIXED_MAX_TQP_NUM_MODE; return 0; } @@ -2953,6 +3003,7 @@ hns3_get_capability(struct hns3_hw *hw) hw->tso_mode = HNS3_TSO_HW_CAL_PSEUDO_H_CSUM; hw->vlan_mode = HNS3_HW_SHIFT_AND_DISCARD_MODE; hw->min_tx_pkt_len = HNS3_HIP09_MIN_TX_PKT_LEN; + pf->tqp_config_mode = HNS3_FLEX_MAX_TQP_NUM_MODE; return 0; } @@ -3048,7 +3099,7 @@ hns3_get_configuration(struct hns3_hw *hw) ret = hns3_get_board_configuration(hw); if (ret) - PMD_INIT_LOG(ERR, "Failed to get board configuration: %d", ret); + PMD_INIT_LOG(ERR, "failed to get board configuration: %d", ret); return ret; } @@ -3081,29 +3132,18 @@ hns3_map_tqps_to_func(struct hns3_hw *hw, uint16_t func_id, uint16_t tqp_pid, static int hns3_map_tqp(struct hns3_hw *hw) { - uint16_t tqps_num = hw->total_tqps_num; - uint16_t func_id; - uint16_t tqp_id; - bool is_pf; - int num; int ret; int i; /* - * In current version VF is not supported when PF is driven by DPDK - * driver, so we allocate tqps to PF as much as possible. + * In current version, VF is not supported when PF is driven by DPDK + * driver, so we assign total tqps_num tqps allocated to this port + * to PF. */ - tqp_id = 0; - num = DIV_ROUND_UP(hw->total_tqps_num, HNS3_MAX_TQP_NUM_PER_FUNC); - for (func_id = HNS3_PF_FUNC_ID; func_id < num; func_id++) { - is_pf = func_id == HNS3_PF_FUNC_ID ? true : false; - for (i = 0; - i < HNS3_MAX_TQP_NUM_PER_FUNC && tqp_id < tqps_num; i++) { - ret = hns3_map_tqps_to_func(hw, func_id, tqp_id++, i, - is_pf); - if (ret) - return ret; - } + for (i = 0; i < hw->total_tqps_num; i++) { + ret = hns3_map_tqps_to_func(hw, HNS3_PF_FUNC_ID, i, i, true); + if (ret) + return ret; } return 0; @@ -4558,17 +4598,21 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) goto err_get_config; } + ret = hns3_tqp_stats_init(hw); + if (ret) + goto err_get_config; + ret = hns3_init_hardware(hns); if (ret) { PMD_INIT_LOG(ERR, "Failed to init hardware: %d", ret); - goto err_get_config; + goto err_init_hw; } /* Initialize flow director filter list & hash */ ret = hns3_fdir_filter_init(hns); if (ret) { PMD_INIT_LOG(ERR, "Failed to alloc hashmap for fdir: %d", ret); - goto err_hw_init; + goto err_fdir; } hns3_set_default_rss_args(hw); @@ -4577,16 +4621,17 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) if (ret) { PMD_INIT_LOG(ERR, "fail to enable hw error interrupts: %d", ret); - goto err_fdir; + goto err_enable_intr; } return 0; -err_fdir: +err_enable_intr: hns3_fdir_filter_uninit(hns); -err_hw_init: +err_fdir: hns3_uninit_umv_space(hw); - +err_init_hw: + hns3_tqp_stats_uninit(hw); err_get_config: hns3_pf_disable_irq0(hw); rte_intr_disable(&pci_dev->intr_handle); @@ -4618,6 +4663,7 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) hns3_promisc_uninit(hw); hns3_fdir_filter_uninit(hns); hns3_uninit_umv_space(hw); + hns3_tqp_stats_uninit(hw); hns3_pf_disable_irq0(hw); rte_intr_disable(&pci_dev->intr_handle); hns3_intr_unregister(&pci_dev->intr_handle, hns3_interrupt_handler, diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h index 3c5ccc7..22c6a15 100644 --- a/drivers/net/hns3/hns3_ethdev.h +++ b/drivers/net/hns3/hns3_ethdev.h @@ -134,9 +134,9 @@ enum hns3_fc_status { }; struct hns3_tc_queue_info { - uint8_t tqp_offset; /* TQP offset from base TQP */ - uint8_t tqp_count; /* Total TQPs */ - uint8_t tc; /* TC index */ + uint16_t tqp_offset; /* TQP offset from base TQP */ + uint16_t tqp_count; /* Total TQPs */ + uint8_t tc; /* TC index */ bool enable; /* If this TC is enable or not */ }; @@ -661,11 +661,35 @@ struct hns3_ptype_table { uint32_t ol4table[HNS3_OL4TBL_NUM]; }; +#define HNS3_FIXED_MAX_TQP_NUM_MODE 0 +#define HNS3_FLEX_MAX_TQP_NUM_MODE 1 + struct hns3_pf { struct hns3_adapter *adapter; bool is_main_pf; uint16_t func_num; /* num functions of this pf, include pf and vfs */ + /* + * tqp_config mode + * tqp_config_mode value range: + * HNS3_FIXED_MAX_TQP_NUM_MODE, + * HNS3_FLEX_MAX_TQP_NUM_MODE + * + * - HNS3_FIXED_MAX_TQP_NUM_MODE + * There is a limitation on the number of pf interrupts available for + * on some versions of network engines. In this case, the maximum + * queue number of pf can not be greater than the interrupt number, + * such as pf of network engine with revision_id 0x21. So the maximum + * number of queues must be fixed. + * + * - HNS3_FLEX_MAX_TQP_NUM_MODE + * In this mode, the maximum queue number of pf has not any constraint + * and comes from the macro RTE_LIBRTE_HNS3_MAX_TQP_NUM_PER_PF + * in the config file. Users can modify the macro according to their + * own application scenarios, which is more flexible to use. + */ + uint8_t tqp_config_mode; + uint32_t pkt_buf_size; /* Total pf buf size for tx/rx */ uint32_t tx_buf_size; /* Tx buffer size for each TC */ uint32_t dv_buf_size; /* Dv buffer size for each TC */ diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c index 4c73441..0b949e9 100644 --- a/drivers/net/hns3/hns3_ethdev_vf.c +++ b/drivers/net/hns3/hns3_ethdev_vf.c @@ -1191,20 +1191,21 @@ hns3vf_get_capability(struct hns3_hw *hw) static int hns3vf_check_tqp_info(struct hns3_hw *hw) { - uint16_t tqps_num; + if (hw->tqps_num == 0) { + PMD_INIT_LOG(ERR, "Get invalid tqps_num(0) from PF."); + return -EINVAL; + } - tqps_num = hw->tqps_num; - if (tqps_num > HNS3_MAX_TQP_NUM_PER_FUNC || tqps_num == 0) { - PMD_INIT_LOG(ERR, "Get invalid tqps_num(%u) from PF. valid " - "range: 1~%d", - tqps_num, HNS3_MAX_TQP_NUM_PER_FUNC); + if (hw->rss_size_max == 0) { + PMD_INIT_LOG(ERR, "Get invalid rss_size_max(0) from PF."); return -EINVAL; } - hw->alloc_rss_size = RTE_MIN(hw->rss_size_max, hw->tqps_num); + hw->tqps_num = RTE_MIN(hw->rss_size_max, hw->tqps_num); return 0; } + static int hns3vf_get_port_base_vlan_filter_state(struct hns3_hw *hw) { @@ -1295,6 +1296,7 @@ hns3vf_get_tc_info(struct hns3_hw *hw) { uint8_t resp_msg; int ret; + int i; ret = hns3_send_mbx_msg(hw, HNS3_MBX_GET_TCINFO, 0, NULL, 0, true, &resp_msg, sizeof(resp_msg)); @@ -1306,6 +1308,11 @@ hns3vf_get_tc_info(struct hns3_hw *hw) hw->hw_tc_map = resp_msg; + for (i = 0; i < HNS3_MAX_TC_NUM; i++) { + if (hw->hw_tc_map & BIT(i)) + hw->num_tc++; + } + return 0; } @@ -1366,17 +1373,10 @@ hns3vf_get_configuration(struct hns3_hw *hw) } static int -hns3vf_set_tc_info(struct hns3_adapter *hns) +hns3vf_set_tc_queue_mapping(struct hns3_adapter *hns, uint16_t nb_rx_q, + uint16_t nb_tx_q) { struct hns3_hw *hw = &hns->hw; - uint16_t nb_rx_q = hw->data->nb_rx_queues; - uint16_t nb_tx_q = hw->data->nb_tx_queues; - uint8_t i; - - hw->num_tc = 0; - for (i = 0; i < HNS3_MAX_TC_NUM; i++) - if (hw->hw_tc_map & BIT(i)) - hw->num_tc++; if (nb_rx_q < hw->num_tc) { hns3_err(hw, "number of Rx queues(%d) is less than tcs(%d).", @@ -1390,10 +1390,7 @@ hns3vf_set_tc_info(struct hns3_adapter *hns) return -EINVAL; } - hns3_set_rss_size(hw, nb_rx_q); - hns3_tc_queue_mapping_cfg(hw, nb_tx_q); - - return 0; + return hns3_queue_to_tc_mapping(hw, nb_rx_q, nb_tx_q); } static void @@ -1783,20 +1780,33 @@ hns3vf_init_vf(struct rte_eth_dev *eth_dev) goto err_get_config; } + ret = hns3_tqp_stats_init(hw); + if (ret) + goto err_get_config; + + ret = hns3vf_set_tc_queue_mapping(hns, hw->tqps_num, hw->tqps_num); + if (ret) { + PMD_INIT_LOG(ERR, "failed to set tc info, ret = %d.", ret); + goto err_set_tc_queue; + } + ret = hns3vf_clear_vport_list(hw); if (ret) { PMD_INIT_LOG(ERR, "Failed to clear tbl list: %d", ret); - goto err_get_config; + goto err_set_tc_queue; } ret = hns3vf_init_hardware(hns); if (ret) - goto err_get_config; + goto err_set_tc_queue; hns3_set_default_rss_args(hw); return 0; +err_set_tc_queue: + hns3_tqp_stats_uninit(hw); + err_get_config: hns3vf_disable_irq0(hw); rte_intr_disable(&pci_dev->intr_handle); @@ -1825,6 +1835,7 @@ hns3vf_uninit_vf(struct rte_eth_dev *eth_dev) (void)hns3_config_gro(hw, false); (void)hns3vf_set_alive(hw, false); (void)hns3vf_set_promisc_mode(hw, false, false, false); + hns3_tqp_stats_uninit(hw); hns3vf_disable_irq0(hw); rte_intr_disable(&pci_dev->intr_handle); hns3_intr_unregister(&pci_dev->intr_handle, hns3vf_interrupt_handler, @@ -2004,9 +2015,11 @@ static int hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) { struct hns3_hw *hw = &hns->hw; + uint16_t nb_rx_q = hw->data->nb_rx_queues; + uint16_t nb_tx_q = hw->data->nb_tx_queues; int ret; - ret = hns3vf_set_tc_info(hns); + ret = hns3vf_set_tc_queue_mapping(hns, nb_rx_q, nb_tx_q); if (ret) return ret; diff --git a/drivers/net/hns3/hns3_fdir.c b/drivers/net/hns3/hns3_fdir.c index e6a065b..79e3028 100644 --- a/drivers/net/hns3/hns3_fdir.c +++ b/drivers/net/hns3/hns3_fdir.c @@ -46,6 +46,8 @@ #define HNS3_FD_AD_QUEUE_REGION_SIZE_M GENMASK(20, 17) #define HNS3_FD_AD_COUNTER_HIGH_BIT 7 #define HNS3_FD_AD_COUNTER_HIGH_BIT_B 26 +#define HNS3_FD_AD_QUEUE_ID_HIGH_BIT 10 +#define HNS3_FD_AD_QUEUE_ID_HIGH_BIT_B 21 enum HNS3_PORT_TYPE { HOST_PORT, @@ -437,6 +439,9 @@ static int hns3_fd_ad_config(struct hns3_hw *hw, int loc, /* set extend bit if counter_id is in [128 ~ 255] */ if (action->counter_id & BIT(HNS3_FD_AD_COUNTER_HIGH_BIT)) hns3_set_bit(ad_data, HNS3_FD_AD_COUNTER_HIGH_BIT_B, 1); + /* set extend bit if queue id > 1024 */ + if (action->queue_id & BIT(HNS3_FD_AD_QUEUE_ID_HIGH_BIT)) + hns3_set_bit(ad_data, HNS3_FD_AD_QUEUE_ID_HIGH_BIT_B, 1); ad_data <<= HNS3_FD_AD_DATA_S; hns3_set_bit(ad_data, HNS3_FD_AD_DROP_B, action->drop_packet); if (action->nb_queues == 1) diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c index 63c8602..a76f42c 100644 --- a/drivers/net/hns3/hns3_regs.c +++ b/drivers/net/hns3/hns3_regs.c @@ -295,7 +295,7 @@ hns3_direct_access_regs(struct hns3_hw *hw, uint32_t *data) reg_um = sizeof(ring_reg_addrs) / sizeof(uint32_t); separator_num = MAX_SEPARATE_NUM - reg_um % REG_NUM_PER_LINE; for (j = 0; j < hw->tqps_num; j++) { - reg_offset = HNS3_TQP_REG_OFFSET + HNS3_TQP_REG_SIZE * j; + reg_offset = hns3_get_tqp_reg_offset(j); for (i = 0; i < reg_um; i++) *data++ = hns3_read_dev(hw, ring_reg_addrs[i] + reg_offset); diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h index 5cf924e..d83c3b3 100644 --- a/drivers/net/hns3/hns3_regs.h +++ b/drivers/net/hns3/hns3_regs.h @@ -89,6 +89,9 @@ #define HNS3_TQP_REG_OFFSET 0x80000 #define HNS3_TQP_REG_SIZE 0x200 +#define HNS3_TQP_EXT_REG_OFFSET 0x100 +#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 diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c index 930aa28..e3f0db4 100644 --- a/drivers/net/hns3/hns3_rxtx.c +++ b/drivers/net/hns3/hns3_rxtx.c @@ -405,7 +405,7 @@ hns3_tqp_enable(struct hns3_hw *hw, uint16_t queue_id, bool enable) req = (struct hns3_cfg_com_tqp_queue_cmd *)desc.data; hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_CFG_COM_TQP_QUEUE, false); - req->tqp_id = rte_cpu_to_le_16(queue_id & HNS3_RING_ID_MASK); + req->tqp_id = rte_cpu_to_le_16(queue_id); req->stream_id = 0; hns3_set_bit(req->enable, HNS3_TQP_ENABLE_B, enable ? 1 : 0); @@ -426,7 +426,7 @@ hns3_send_reset_tqp_cmd(struct hns3_hw *hw, uint16_t queue_id, bool enable) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RESET_TQP_QUEUE, false); req = (struct hns3_reset_tqp_queue_cmd *)desc.data; - req->tqp_id = rte_cpu_to_le_16(queue_id & HNS3_RING_ID_MASK); + req->tqp_id = rte_cpu_to_le_16(queue_id); hns3_set_bit(req->reset_req, HNS3_TQP_RESET_B, enable ? 1 : 0); ret = hns3_cmd_send(hw, &desc, 1); @@ -446,7 +446,7 @@ hns3_get_reset_status(struct hns3_hw *hw, uint16_t queue_id) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RESET_TQP_QUEUE, true); req = (struct hns3_reset_tqp_queue_cmd *)desc.data; - req->tqp_id = rte_cpu_to_le_16(queue_id & HNS3_RING_ID_MASK); + req->tqp_id = rte_cpu_to_le_16(queue_id); ret = hns3_cmd_send(hw, &desc, 1); if (ret) { @@ -1341,6 +1341,22 @@ hns3_rx_queue_conf_check(struct hns3_hw *hw, const struct rte_eth_rxconf *conf, return 0; } +uint32_t +hns3_get_tqp_reg_offset(uint16_t queue_id) +{ + uint32_t reg_offset; + + /* Need an extend offset to config queue > 1024 */ + if (queue_id < HNS3_MIN_EXTEND_QUEUE_ID) + reg_offset = HNS3_TQP_REG_OFFSET + queue_id * HNS3_TQP_REG_SIZE; + else + reg_offset = HNS3_TQP_REG_OFFSET + HNS3_TQP_EXT_REG_OFFSET + + (queue_id - HNS3_MIN_EXTEND_QUEUE_ID) * + HNS3_TQP_REG_SIZE; + + return reg_offset; +} + int hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, unsigned int socket_id, const struct rte_eth_rxconf *conf, @@ -1422,6 +1438,8 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, rxq->configured = true; rxq->io_base = (void *)((char *)hw->io_base + HNS3_TQP_REG_OFFSET + idx * HNS3_TQP_REG_SIZE); + rxq->io_base = (void *)((char *)hw->io_base + + hns3_get_tqp_reg_offset(idx)); rxq->io_head_reg = (volatile void *)((char *)rxq->io_base + HNS3_RING_RX_HEAD_REG); rxq->rx_buf_len = rx_buf_size; @@ -2183,8 +2201,8 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, txq->pvid_sw_shift_en = false; txq->max_non_tso_bd_num = hw->max_non_tso_bd_num; txq->configured = true; - txq->io_base = (void *)((char *)hw->io_base + HNS3_TQP_REG_OFFSET + - idx * HNS3_TQP_REG_SIZE); + txq->io_base = (void *)((char *)hw->io_base + + hns3_get_tqp_reg_offset(idx)); txq->io_tail_reg = (volatile void *)((char *)txq->io_base + HNS3_RING_TX_TAIL_REG); txq->min_tx_pkt_len = hw->min_tx_pkt_len; diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h index d7d70f6..cdfe115 100644 --- a/drivers/net/hns3/hns3_rxtx.h +++ b/drivers/net/hns3/hns3_rxtx.h @@ -661,4 +661,6 @@ void hns3_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, struct rte_eth_rxq_info *qinfo); void hns3_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, struct rte_eth_txq_info *qinfo); +uint32_t hns3_get_tqp_reg_offset(uint16_t idx); + #endif /* _HNS3_RXTX_H_ */ diff --git a/drivers/net/hns3/hns3_stats.c b/drivers/net/hns3/hns3_stats.c index e8846b9..8c3c7cc 100644 --- a/drivers/net/hns3/hns3_stats.c +++ b/drivers/net/hns3/hns3_stats.c @@ -330,6 +330,8 @@ static const struct hns3_xstats_name_offset hns3_tx_queue_strings[] = { #define HNS3_FIX_NUM_STATS (HNS3_NUM_MAC_STATS + HNS3_NUM_ERROR_INT_XSTATS + \ HNS3_NUM_RESET_XSTATS) +static void hns3_tqp_stats_clear(struct hns3_hw *hw); + /* * Query all the MAC statistics data of Network ICL command ,opcode id: 0x0034. * This command is used before send 'query_mac_stat command', the descriptor @@ -456,8 +458,7 @@ hns3_update_tqp_stats(struct hns3_hw *hw) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_RX_STATUS, true); - desc.data[0] = rte_cpu_to_le_32((uint32_t)i & - HNS3_QUEUE_ID_MASK); + desc.data[0] = rte_cpu_to_le_32((uint32_t)i); ret = hns3_cmd_send(hw, &desc, 1); if (ret) { hns3_err(hw, "Failed to query RX No.%d queue stat: %d", @@ -471,8 +472,7 @@ hns3_update_tqp_stats(struct hns3_hw *hw) hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_QUERY_TX_STATUS, true); - desc.data[0] = rte_cpu_to_le_32((uint32_t)i & - HNS3_QUEUE_ID_MASK); + desc.data[0] = rte_cpu_to_le_32((uint32_t)i); ret = hns3_cmd_send(hw, &desc, 1); if (ret) { hns3_err(hw, "Failed to query TX No.%d queue stat: %d", @@ -553,7 +553,6 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) { struct hns3_adapter *hns = eth_dev->data->dev_private; struct hns3_hw *hw = &hns->hw; - struct hns3_tqp_stats *stats = &hw->tqp_stats; struct hns3_cmd_desc desc_reset; struct hns3_rx_queue *rxq; struct hns3_tx_queue *txq; @@ -561,14 +560,13 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) int ret; /* - * If this is a reset xstats is NULL, and we have cleared the - * registers by reading them. + * Note: Reading hardware statistics of rx/tx queue packet number + * will clear them. */ for (i = 0; i < hw->tqps_num; i++) { hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_RX_STATUS, true); - desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i & - HNS3_QUEUE_ID_MASK); + desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i); ret = hns3_cmd_send(hw, &desc_reset, 1); if (ret) { hns3_err(hw, "Failed to reset RX No.%d queue stat: %d", @@ -578,8 +576,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) hns3_cmd_setup_basic_desc(&desc_reset, HNS3_OPC_QUERY_TX_STATUS, true); - desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i & - HNS3_QUEUE_ID_MASK); + desc_reset.data[0] = rte_cpu_to_le_32((uint32_t)i); ret = hns3_cmd_send(hw, &desc_reset, 1); if (ret) { hns3_err(hw, "Failed to reset TX No.%d queue stat: %d", @@ -614,7 +611,7 @@ hns3_stats_reset(struct rte_eth_dev *eth_dev) } } - memset(stats, 0, sizeof(struct hns3_tqp_stats)); + hns3_tqp_stats_clear(hw); return 0; } @@ -668,8 +665,7 @@ hns3_get_queue_stats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, /* Get rx queue stats */ for (j = 0; j < dev->data->nb_rx_queues; j++) { for (i = 0; i < HNS3_NUM_RX_QUEUE_STATS; i++) { - reg_offset = HNS3_TQP_REG_OFFSET + - HNS3_TQP_REG_SIZE * j; + reg_offset = hns3_get_tqp_reg_offset(j); xstats[*count].value = hns3_read_dev(hw, reg_offset + hns3_rx_queue_strings[i].offset); xstats[*count].id = *count; @@ -680,8 +676,7 @@ hns3_get_queue_stats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, /* Get tx queue stats */ for (j = 0; j < dev->data->nb_tx_queues; j++) { for (i = 0; i < HNS3_NUM_TX_QUEUE_STATS; i++) { - reg_offset = HNS3_TQP_REG_OFFSET + - HNS3_TQP_REG_SIZE * j; + reg_offset = hns3_get_tqp_reg_offset(j); xstats[*count].value = hns3_read_dev(hw, reg_offset + hns3_tx_queue_strings[i].offset); xstats[*count].id = *count; @@ -1071,3 +1066,49 @@ hns3_dev_xstats_reset(struct rte_eth_dev *dev) return 0; } + +int +hns3_tqp_stats_init(struct hns3_hw *hw) +{ + struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats; + + tqp_stats->rcb_rx_ring_pktnum = rte_zmalloc("hns3_rx_ring_pkt_num", + sizeof(uint64_t) * hw->tqps_num, 0); + if (tqp_stats->rcb_rx_ring_pktnum == NULL) { + hns3_err(hw, "failed to allocate rx_ring pkt_num."); + return -ENOMEM; + } + + tqp_stats->rcb_tx_ring_pktnum = rte_zmalloc("hns3_tx_ring_pkt_num", + sizeof(uint64_t) * hw->tqps_num, 0); + if (tqp_stats->rcb_tx_ring_pktnum == NULL) { + hns3_err(hw, "failed to allocate tx_ring pkt_num."); + rte_free(tqp_stats->rcb_rx_ring_pktnum); + tqp_stats->rcb_rx_ring_pktnum = NULL; + return -ENOMEM; + } + + return 0; +} + +void +hns3_tqp_stats_uninit(struct hns3_hw *hw) +{ + struct hns3_tqp_stats *tqp_stats = &hw->tqp_stats; + + rte_free(tqp_stats->rcb_rx_ring_pktnum); + tqp_stats->rcb_rx_ring_pktnum = NULL; + rte_free(tqp_stats->rcb_tx_ring_pktnum); + tqp_stats->rcb_tx_ring_pktnum = NULL; +} + +static void +hns3_tqp_stats_clear(struct hns3_hw *hw) +{ + struct hns3_tqp_stats *stats = &hw->tqp_stats; + + stats->rcb_rx_ring_pktnum_rcd = 0; + stats->rcb_tx_ring_pktnum_rcd = 0; + memset(stats->rcb_rx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num); + memset(stats->rcb_tx_ring_pktnum, 0, sizeof(uint64_t) * hw->tqps_num); +} diff --git a/drivers/net/hns3/hns3_stats.h b/drivers/net/hns3/hns3_stats.h index 07570cb..9fcd5f9 100644 --- a/drivers/net/hns3/hns3_stats.h +++ b/drivers/net/hns3/hns3_stats.h @@ -14,8 +14,8 @@ struct hns3_tqp_stats { uint64_t rcb_tx_ring_pktnum_rcd; /* Total num of transmitted packets */ uint64_t rcb_rx_ring_pktnum_rcd; /* Total num of received packets */ - uint64_t rcb_tx_ring_pktnum[HNS3_MAX_TQP_NUM_PER_FUNC]; - uint64_t rcb_rx_ring_pktnum[HNS3_MAX_TQP_NUM_PER_FUNC]; + uint64_t *rcb_rx_ring_pktnum; + uint64_t *rcb_tx_ring_pktnum; }; /* mac stats, Statistics counters collected by the MAC, opcode id: 0x0032 */ @@ -149,5 +149,7 @@ int hns3_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, uint32_t size); int hns3_stats_reset(struct rte_eth_dev *dev); void hns3_error_int_stats_add(struct hns3_adapter *hns, const char *err); +int hns3_tqp_stats_init(struct hns3_hw *hw); +void hns3_tqp_stats_uninit(struct hns3_hw *hw); #endif /* _HNS3_STATS_H_ */ From patchwork Tue Sep 29 12:01:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79190 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id B83F9A04C0; Tue, 29 Sep 2020 14:02:37 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 641271DA62; Tue, 29 Sep 2020 14:01:34 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id D6E991BE9A for ; Tue, 29 Sep 2020 14:01:26 +0200 (CEST) X-ASG-Debug-ID: 1601380884-149d11049a296790001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id JDjHaM3JBAX9KAQ7 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:24 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:24 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:11 +0800 X-ASG-Orig-Subj: [PATCH v2 3/9] net/hns3: fix error type when validating RSS flow action Message-ID: <20200929120117.50394-4-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380884 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 3758 Subject: [dpdk-dev] [PATCH v2 3/9] net/hns3: fix error type when validating RSS flow action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: "Wei Hu (Xavier)" Because the macro named RTE_FLOW_ERROR_TYPE_ACTION_CONF indicates a action configuration and the macro named RTE_FLOW_ERROR_TYPE_ACTION indicates a specific action, the driver needs to return RTE_FLOW_ERROR_ACTION_CONF type and notify the user when a RSS configuration is invalid with actions list in the internal function named hns3_parse_rss_filter called by the '.validate' ops implementation function named hns3_flow_validate. Besides, this patch removes some unnecessary judgment lines in hns3_parse_rss_filter. Fixes: c37ca66f2b27 ("net/hns3: support RSS") Cc: stable@dpdk.org Signed-off-by: Lijun Ou Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_flow.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c index f8e5f05..a6676d6 100644 --- a/drivers/net/hns3/hns3_flow.c +++ b/drivers/net/hns3/hns3_flow.c @@ -1356,7 +1356,6 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, const struct rte_flow_action_rss *rss; const struct rte_flow_action *act; uint32_t act_index = 0; - uint64_t flow_types; uint16_t n; NEXT_ITEM_OF_ACTION(act, actions, act_index); @@ -1364,7 +1363,7 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, if (rss == NULL) { return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, "no valid queues"); } @@ -1372,48 +1371,32 @@ hns3_parse_rss_filter(struct rte_eth_dev *dev, if (rss->queue[n] < dev->data->nb_rx_queues) continue; return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, "queue id > max number of queues"); } - /* Parse flow types of RSS */ if (!(rss->types & HNS3_ETH_RSS_SUPPORT) && rss->types) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, "Flow types is unsupported by " "hns3's RSS"); - - flow_types = rss->types & HNS3_ETH_RSS_SUPPORT; - if (flow_types != rss->types) - hns3_warn(hw, "RSS flow types(%" PRIx64 ") include unsupported " - "flow types", rss->types); - - /* Parse RSS related parameters from RSS configuration */ - switch (rss->func) { - case RTE_ETH_HASH_FUNCTION_DEFAULT: - case RTE_ETH_HASH_FUNCTION_TOEPLITZ: - case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: - case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: - break; - default: + if (rss->func >= RTE_ETH_HASH_FUNCTION_MAX) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, act, - "input RSS hash functions are not supported"); - } - + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, + "RSS hash func are not supported"); if (rss->level) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, act, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, "a nonzero RSS encapsulation level is not supported"); if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key)) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, act, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, "RSS hash key must be exactly 40 bytes"); if (rss->queue_num > RTE_DIM(rss_conf->queue)) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, act, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, "too many queues for RSS context"); if (rss->types & (ETH_RSS_L4_DST_ONLY | ETH_RSS_L4_SRC_ONLY) && From patchwork Tue Sep 29 12:01:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79189 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 15C75A04C0; Tue, 29 Sep 2020 14:02:20 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9DA801DA5D; Tue, 29 Sep 2020 14:01:32 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id 9AD1E1BE86 for ; Tue, 29 Sep 2020 14:01:26 +0200 (CEST) X-ASG-Debug-ID: 1601380885-149d11049b2967b0001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id 1zGaIDE98o64m0p2 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:25 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:24 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:12 +0800 X-ASG-Orig-Subj: [PATCH v2 4/9] net/hns3: set suitable type when initial flow error struct Message-ID: <20200929120117.50394-5-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380885 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 8605 Subject: [dpdk-dev] [PATCH v2 4/9] net/hns3: set suitable type when initial flow error struct X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: "Wei Hu (Xavier)" The API of rte_flow_error_set is used to pass detail error information to caller, this patch sets suitable type when calling rte_flow_error_set API. Fixes: fcba820d9b9e ("net/hns3: support flow director") Fixes: c37ca66f2b27 ("net/hns3: support RSS") Cc: stable@dpdk.org Signed-off-by: Chengwen Feng Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_flow.c | 54 ++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c index a6676d6..4fb129e 100644 --- a/drivers/net/hns3/hns3_flow.c +++ b/drivers/net/hns3/hns3_flow.c @@ -168,9 +168,9 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, if (cnt) { if (!cnt->shared || cnt->shared != shared) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - cnt, - "Counter id is used,shared flag not match"); + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + cnt, + "Counter id is used, shared flag not match"); cnt->ref_cnt++; return 0; } @@ -178,7 +178,7 @@ hns3_counter_new(struct rte_eth_dev *dev, uint32_t shared, uint32_t id, cnt = rte_zmalloc("hns3 counter", sizeof(*cnt), 0); if (cnt == NULL) return rte_flow_error_set(error, ENOMEM, - RTE_FLOW_ERROR_TYPE_ACTION, cnt, + RTE_FLOW_ERROR_TYPE_HANDLE, cnt, "Alloc mem for counter failed"); cnt->id = id; cnt->shared = shared; @@ -206,13 +206,13 @@ hns3_counter_query(struct rte_eth_dev *dev, struct rte_flow *flow, cnt = hns3_counter_lookup(dev, flow->counter_id); if (cnt == NULL) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Can't find counter id"); ret = hns3_get_count(&hns->hw, flow->counter_id, &value); if (ret) { rte_flow_error_set(error, -ret, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Read counter fail."); return ret; } @@ -374,9 +374,9 @@ hns3_handle_actions(struct rte_eth_dev *dev, (const struct rte_flow_action_mark *)actions->conf; if (mark->id >= HNS3_MAX_FILTER_ID) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - actions, - "Invalid Mark ID"); + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + actions, + "Invalid Mark ID"); rule->fd_id = mark->id; rule->flags |= HNS3_RULE_FLAG_FDID; break; @@ -390,9 +390,9 @@ hns3_handle_actions(struct rte_eth_dev *dev, counter_num = pf->fdir.fd_cfg.cnt_num[HNS3_FD_STAGE_1]; if (act_count->id >= counter_num) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - actions, - "Invalid counter id"); + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + actions, + "Invalid counter id"); rule->act_cnt = *act_count; rule->flags |= HNS3_RULE_FLAG_COUNTER; break; @@ -556,7 +556,7 @@ hns3_parse_ipv4(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, ipv4_mask->hdr.time_to_live || ipv4_mask->hdr.hdr_checksum) { return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Only support src & dst ip,tos,proto in IPV4"); } @@ -621,7 +621,7 @@ hns3_parse_ipv6(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (ipv6_mask->hdr.vtc_flow || ipv6_mask->hdr.payload_len || ipv6_mask->hdr.hop_limits) { return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Only support src & dst ip,proto in IPV6"); } @@ -681,7 +681,7 @@ hns3_parse_tcp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, tcp_mask->hdr.rx_win || tcp_mask->hdr.cksum || tcp_mask->hdr.tcp_urp) { return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Only support src & dst port in TCP"); } @@ -728,7 +728,7 @@ hns3_parse_udp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, udp_mask = item->mask; if (udp_mask->hdr.dgram_len || udp_mask->hdr.dgram_cksum) { return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Only support src & dst port in UDP"); } @@ -775,7 +775,7 @@ hns3_parse_sctp(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, sctp_mask = item->mask; if (sctp_mask->hdr.cksum) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Only support src & dst port in SCTP"); @@ -920,14 +920,14 @@ hns3_parse_vxlan(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (vxlan_mask->flags) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Flags is not supported in VxLAN"); /* VNI must be totally masked or not. */ if (memcmp(vxlan_mask->vni, full_mask, VNI_OR_TNI_LEN) && memcmp(vxlan_mask->vni, zero_mask, VNI_OR_TNI_LEN)) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "VNI must be totally masked or not in VxLAN"); if (vxlan_mask->vni[0]) { hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1); @@ -971,14 +971,14 @@ hns3_parse_nvgre(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (nvgre_mask->protocol || nvgre_mask->c_k_s_rsvd0_ver) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Ver/protocal is not supported in NVGRE"); /* TNI must be totally masked or not. */ if (memcmp(nvgre_mask->tni, full_mask, VNI_OR_TNI_LEN) && memcmp(nvgre_mask->tni, zero_mask, VNI_OR_TNI_LEN)) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "TNI must be totally masked or not in NVGRE"); if (nvgre_mask->tni[0]) { @@ -1025,13 +1025,13 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, if (geneve_mask->ver_opt_len_o_c_rsvd0 || geneve_mask->protocol) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "Ver/protocal is not supported in GENEVE"); /* VNI must be totally masked or not. */ if (memcmp(geneve_mask->vni, full_mask, VNI_OR_TNI_LEN) && memcmp(geneve_mask->vni, zero_mask, VNI_OR_TNI_LEN)) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, item, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, "VNI must be totally masked or not in GENEVE"); if (geneve_mask->vni[0]) { hns3_set_bit(rule->input_set, OUTER_TUN_VNI, 1); @@ -1062,7 +1062,7 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, break; default: return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_HANDLE, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, "Unsupported tunnel type!"); } if (ret) @@ -1116,7 +1116,7 @@ hns3_parse_normal(const struct rte_flow_item *item, break; default: return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_HANDLE, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, "Unsupported normal type!"); } @@ -1132,7 +1132,7 @@ hns3_validate_item(const struct rte_flow_item *item, if (item->last) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, item, + RTE_FLOW_ERROR_TYPE_ITEM_LAST, item, "Not supported last point for range"); for (i = 0; i < step_mngr.count; i++) { @@ -1218,7 +1218,7 @@ hns3_parse_fdir_filter(struct rte_eth_dev *dev, if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_PERFECT) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ITEM_NUM, NULL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "fdir_conf.mode isn't perfect"); step_mngr.items = first_items; From patchwork Tue Sep 29 12:01:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79196 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 07539A04C0; Tue, 29 Sep 2020 14:05:04 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5C4981D6CC; Tue, 29 Sep 2020 14:01:48 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id 5DA631DA89 for ; Tue, 29 Sep 2020 14:01:39 +0200 (CEST) X-ASG-Debug-ID: 1601380885-149d11049b2967b0002-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id P18vCncZsk5Ra7R9 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:25 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:25 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:13 +0800 X-ASG-Orig-Subj: [PATCH v2 5/9] net/hns3: offload calculating the shapping para to firmware Message-ID: <20200929120117.50394-6-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380885 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 8925 Subject: [dpdk-dev] [PATCH v2 5/9] net/hns3: offload calculating the shapping para to firmware X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Huisong Li In order to have more flexible selection of shapping algorithm based on different versions of hns3 network engine, moves the algorithm of calculating shapping parameter to firmware to execute. If bit HNS3_TM_RATE_VLD_B of flag field of struct named hns3_pri_shapping_cmd, hns3_pg_shapping_cmd or hns3_port_shapping_cmd is set to 1, firmware of network engine, which device revision_id is greater than and equal to 0x30, will recalculate the shapping parameters according to the xxx_rate field of struct hns3_xxx_shapping_cmd and the opcode of scheduling level, and configure to hardware. But driver still needs to calculate shapping parameters and configure firmware, so as to be compatible with the network engine with revision_id eqauls 0x21. And the rate and the flag will be ignored based on the network engine with revision_id equals 0x21. Signed-off-by: Huisong Li Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_dcb.c | 55 +++++++++++++++++++++++++++++++++++---------- drivers/net/hns3/hns3_dcb.h | 39 +++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c index fecedff..857e79e 100644 --- a/drivers/net/hns3/hns3_dcb.c +++ b/drivers/net/hns3/hns3_dcb.c @@ -365,12 +365,22 @@ hns3_dcb_port_shaper_cfg(struct hns3_hw *hw) shap_cfg_cmd->port_shapping_para = rte_cpu_to_le_32(shapping_para); + /* + * Configure the port_rate and set bit HNS3_TM_RATE_VLD_B of flag + * field in hns3_port_shapping_cmd to require firmware to recalculate + * shapping parameters. And whether the parameters are recalculated + * depends on the firmware version. But driver still needs to + * calculate it and configure to firmware for better compatibility. + */ + shap_cfg_cmd->port_rate = rte_cpu_to_le_32(hw->mac.link_speed); + hns3_set_bit(shap_cfg_cmd->flag, HNS3_TM_RATE_VLD_B, 1); + return hns3_cmd_send(hw, &desc, 1); } static int hns3_dcb_pg_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, - uint8_t pg_id, uint32_t shapping_para) + uint8_t pg_id, uint32_t shapping_para, uint32_t rate) { struct hns3_pg_shapping_cmd *shap_cfg_cmd; enum hns3_opcode_type opcode; @@ -386,6 +396,16 @@ hns3_dcb_pg_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, shap_cfg_cmd->pg_shapping_para = rte_cpu_to_le_32(shapping_para); + /* + * Configure the pg_rate and set bit HNS3_TM_RATE_VLD_B of flag field in + * hns3_pg_shapping_cmd to require firmware to recalculate shapping + * parameters. And whether parameters are recalculated depends on + * the firmware version. But driver still needs to calculate it and + * configure to firmware for better compatibility. + */ + shap_cfg_cmd->pg_rate = rte_cpu_to_le_32(rate); + hns3_set_bit(shap_cfg_cmd->flag, HNS3_TM_RATE_VLD_B, 1); + return hns3_cmd_send(hw, &desc, 1); } @@ -397,6 +417,7 @@ hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) struct hns3_pf *pf = &hns->pf; uint32_t ir_u, ir_b, ir_s; uint32_t shaper_para; + uint32_t rate; uint8_t i; int ret; @@ -406,10 +427,10 @@ hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) /* Pg to pri */ for (i = 0; i < hw->dcb_info.num_pg; i++) { + rate = hw->dcb_info.pg_info[i].bw_limit; + /* Calc shaper para */ - ret = hns3_shaper_para_calc(hw, - hw->dcb_info.pg_info[i].bw_limit, - HNS3_SHAPER_LVL_PG, + ret = hns3_shaper_para_calc(hw, rate, HNS3_SHAPER_LVL_PG, &shaper_parameter); if (ret) { hns3_err(hw, "calculate shaper parameter failed: %d", @@ -422,7 +443,7 @@ hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) HNS3_SHAPER_BS_S_DEF); ret = hns3_dcb_pg_shapping_cfg(hw, HNS3_DCB_SHAP_C_BUCKET, i, - shaper_para); + shaper_para, rate); if (ret) { hns3_err(hw, "config PG CIR shaper parameter failed: %d", @@ -438,7 +459,7 @@ hns3_dcb_pg_shaper_cfg(struct hns3_hw *hw) HNS3_SHAPER_BS_S_DEF); ret = hns3_dcb_pg_shapping_cfg(hw, HNS3_DCB_SHAP_P_BUCKET, i, - shaper_para); + shaper_para, rate); if (ret) { hns3_err(hw, "config PG PIR shaper parameter failed: %d", @@ -486,7 +507,7 @@ hns3_dcb_pri_schd_mode_cfg(struct hns3_hw *hw, uint8_t pri_id) static int hns3_dcb_pri_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, - uint8_t pri_id, uint32_t shapping_para) + uint8_t pri_id, uint32_t shapping_para, uint32_t rate) { struct hns3_pri_shapping_cmd *shap_cfg_cmd; enum hns3_opcode_type opcode; @@ -503,6 +524,16 @@ hns3_dcb_pri_shapping_cfg(struct hns3_hw *hw, enum hns3_shap_bucket bucket, shap_cfg_cmd->pri_shapping_para = rte_cpu_to_le_32(shapping_para); + /* + * Configure the pri_rate and set bit HNS3_TM_RATE_VLD_B of flag + * field in hns3_pri_shapping_cmd to require firmware to recalculate + * shapping parameters. And whether the parameters are recalculated + * depends on the firmware version. But driver still needs to + * calculate it and configure to firmware for better compatibility. + */ + shap_cfg_cmd->pri_rate = rte_cpu_to_le_32(rate); + hns3_set_bit(shap_cfg_cmd->flag, HNS3_TM_RATE_VLD_B, 1); + return hns3_cmd_send(hw, &desc, 1); } @@ -512,12 +543,12 @@ hns3_dcb_pri_tc_base_shaper_cfg(struct hns3_hw *hw) struct hns3_shaper_parameter shaper_parameter; uint32_t ir_u, ir_b, ir_s; uint32_t shaper_para; + uint32_t rate; int ret, i; for (i = 0; i < hw->dcb_info.num_tc; i++) { - ret = hns3_shaper_para_calc(hw, - hw->dcb_info.tc_info[i].bw_limit, - HNS3_SHAPER_LVL_PRI, + rate = hw->dcb_info.tc_info[i].bw_limit; + ret = hns3_shaper_para_calc(hw, rate, HNS3_SHAPER_LVL_PRI, &shaper_parameter); if (ret) { hns3_err(hw, "calculate shaper parameter failed: %d", @@ -530,7 +561,7 @@ hns3_dcb_pri_tc_base_shaper_cfg(struct hns3_hw *hw) HNS3_SHAPER_BS_S_DEF); ret = hns3_dcb_pri_shapping_cfg(hw, HNS3_DCB_SHAP_C_BUCKET, i, - shaper_para); + shaper_para, rate); if (ret) { hns3_err(hw, "config priority CIR shaper parameter failed: %d", @@ -546,7 +577,7 @@ hns3_dcb_pri_tc_base_shaper_cfg(struct hns3_hw *hw) HNS3_SHAPER_BS_S_DEF); ret = hns3_dcb_pri_shapping_cfg(hw, HNS3_DCB_SHAP_P_BUCKET, i, - shaper_para); + shaper_para, rate); if (ret) { hns3_err(hw, "config priority PIR shaper parameter failed: %d", diff --git a/drivers/net/hns3/hns3_dcb.h b/drivers/net/hns3/hns3_dcb.h index 05c9786..39ff332 100644 --- a/drivers/net/hns3/hns3_dcb.h +++ b/drivers/net/hns3/hns3_dcb.h @@ -16,7 +16,7 @@ /* SP or DWRR */ #define HNS3_DCB_TX_SCHD_DWRR_MSK BIT(0) -#define HNS3_DCB_TX_SCHD_SP_MSK (0xFE) +#define HNS3_DCB_TX_SCHD_SP_MSK 0xFE enum hns3_shap_bucket { HNS3_DCB_SHAP_C_BUCKET = 0, @@ -81,18 +81,46 @@ struct hns3_nq_to_qs_link_cmd { #define HNS3_DCB_SHAP_BS_S_MSK GENMASK(25, 21) #define HNS3_DCB_SHAP_BS_S_LSH 21 +/* + * For more flexible selection of shapping algorithm in different network + * engine, the algorithm calculating shapping parameter is moved to firmware to + * execute. Bit HNS3_TM_RATE_VLD_B of flag field in hns3_pri_shapping_cmd, + * hns3_pg_shapping_cmd or hns3_port_shapping_cmd is set to 1 to require + * firmware to recalculate shapping parameters. However, whether the parameters + * are recalculated depends on the firmware version. If firmware doesn't support + * the calculation of shapping parameters, such as on network engine with + * revision id 0x21, the value driver calculated will be used to configure to + * hardware. On the contrary, firmware ignores configuration of driver + * and recalculates the parameter. + */ +#define HNS3_TM_RATE_VLD_B 0 + struct hns3_pri_shapping_cmd { uint8_t pri_id; uint8_t rsvd[3]; uint32_t pri_shapping_para; - uint32_t rsvd1[4]; + uint8_t flag; + uint8_t rsvd1[3]; + uint32_t pri_rate; /* Unit Mbps */ + uint8_t rsvd2[8]; }; struct hns3_pg_shapping_cmd { uint8_t pg_id; uint8_t rsvd[3]; uint32_t pg_shapping_para; - uint32_t rsvd1[4]; + uint8_t flag; + uint8_t rsvd1[3]; + uint32_t pg_rate; /* Unit Mbps */ + uint8_t rsvd2[8]; +}; + +struct hns3_port_shapping_cmd { + uint32_t port_shapping_para; + uint8_t flag; + uint8_t rsvd[3]; + uint32_t port_rate; /* Unit Mbps */ + uint8_t rsvd1[12]; }; #define HNS3_BP_GRP_NUM 32 @@ -115,11 +143,6 @@ struct hns3_pfc_en_cmd { uint8_t rsvd[22]; }; -struct hns3_port_shapping_cmd { - uint32_t port_shapping_para; - uint32_t rsvd[5]; -}; - struct hns3_cfg_pause_param_cmd { uint8_t mac_addr[RTE_ETHER_ADDR_LEN]; uint8_t pause_trans_gap; From patchwork Tue Sep 29 12:01:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79191 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4AA4FA04C0; Tue, 29 Sep 2020 14:03:05 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 069681DA76; Tue, 29 Sep 2020 14:01:38 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id EE47C1DA10 for ; Tue, 29 Sep 2020 14:01:28 +0200 (CEST) X-ASG-Debug-ID: 1601380885-149d11049b2967c0001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id JBaiFqc6CGE0ZgJI (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:25 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:25 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:14 +0800 X-ASG-Orig-Subj: [PATCH v2 6/9] net/hns3: set max scheduling rate based on actual board Message-ID: <20200929120117.50394-7-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380885 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 2533 Subject: [dpdk-dev] [PATCH v2 6/9] net/hns3: set max scheduling rate based on actual board X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Huisong Li Currently, max scheduling rates configuration of pg, pri and port are set to 100000Mbps, which is the maximum bandwidth of hns3 network engine with revision_id equals 0x21. However, max scheduling rate configuration should be set to hardware based on the actual hardware board environment. The max_tm_rate in struct hns3_hw, meaning the rate, is obtained from firmware. So we should use the variable to configure the max scheduling rate. Signed-off-by: Huisong Li Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_dcb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/hns3/hns3_dcb.c b/drivers/net/hns3/hns3_dcb.c index 857e79e..27ae014 100644 --- a/drivers/net/hns3/hns3_dcb.c +++ b/drivers/net/hns3/hns3_dcb.c @@ -62,9 +62,9 @@ hns3_shaper_para_calc(struct hns3_hw *hw, uint32_t ir, uint8_t shaper_level, return -EINVAL; } - if (ir > HNS3_ETHER_MAX_RATE) { - hns3_err(hw, "rate(%d) exceeds the rate driver supported " - "HNS3_ETHER_MAX_RATE(%d)", ir, HNS3_ETHER_MAX_RATE); + if (ir > hw->max_tm_rate) { + hns3_err(hw, "rate(%d) exceeds the max rate(%d) driver " + "supported.", ir, hw->max_tm_rate); return -EINVAL; } @@ -100,7 +100,7 @@ hns3_shaper_para_calc(struct hns3_hw *hw, uint32_t ir, uint8_t shaper_level, * ir_calc gets minimum value when tick is the maximum value. * At the same time, value of ir_u_calc can only be increased up * to eight after the while loop if the value of ir is equal - * to HNS3_ETHER_MAX_RATE. + * to hw->max_tm_rate. */ uint32_t numerator; do { @@ -736,7 +736,7 @@ hns3_dcb_info_init(struct hns3_hw *hw) hw->dcb_info.pg_dwrr[i] = i ? 0 : BW_MAX_PERCENT; hw->dcb_info.pg_info[i].pg_id = i; hw->dcb_info.pg_info[i].pg_sch_mode = HNS3_SCH_MODE_DWRR; - hw->dcb_info.pg_info[i].bw_limit = HNS3_ETHER_MAX_RATE; + hw->dcb_info.pg_info[i].bw_limit = hw->max_tm_rate; if (i != 0) continue; @@ -1405,7 +1405,7 @@ hns3_dcb_info_cfg(struct hns3_adapter *hns) hw->dcb_info.pg_dwrr[0] = BW_MAX_PERCENT; hw->dcb_info.pg_info[0].pg_id = 0; hw->dcb_info.pg_info[0].pg_sch_mode = HNS3_SCH_MODE_DWRR; - hw->dcb_info.pg_info[0].bw_limit = HNS3_ETHER_MAX_RATE; + hw->dcb_info.pg_info[0].bw_limit = hw->max_tm_rate; hw->dcb_info.pg_info[0].tc_bit_map = hw->hw_tc_map; /* Each tc has same bw for valid tc by default */ From patchwork Tue Sep 29 12:01:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79195 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id D2664A04C0; Tue, 29 Sep 2020 14:04:32 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DAF5D1D17C; Tue, 29 Sep 2020 14:01:44 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id 9CC881DA10 for ; Tue, 29 Sep 2020 14:01:30 +0200 (CEST) X-ASG-Debug-ID: 1601380886-149d11049a2967c0001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id uzsa5kw2MHggmsSo (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:26 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:26 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:15 +0800 X-ASG-Orig-Subj: [PATCH v2 7/9] net/hns3: support start and stop Tx or Rx queue Message-ID: <20200929120117.50394-8-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380886 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 47659 Subject: [dpdk-dev] [PATCH v2 7/9] net/hns3: support start and stop Tx or Rx queue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Chengchang Tang The new generation hns3 network engine supports independent enabling and disabling of a single Tx/Rx queue. So, it can support the queue start and stop feature. In addition, when different numbers of Tx and Rx queues need to be enabled in some applications, hns3 pmd does not need to create fake queues to enable these scenarios. This patch Add queue start and stop feature for the new generation hns3 networking engine. Cancel the creation of fake queue on the new generation network engine. And the previously improperly named queue related function was renamed to improve readability. Signed-off-by: Chengchang Tang Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_cmd.c | 2 +- drivers/net/hns3/hns3_cmd.h | 4 +- drivers/net/hns3/hns3_ethdev.c | 98 ++++-- drivers/net/hns3/hns3_ethdev_vf.c | 93 ++++-- drivers/net/hns3/hns3_regs.c | 2 + drivers/net/hns3/hns3_regs.h | 2 + drivers/net/hns3/hns3_rxtx.c | 647 +++++++++++++++++++++++++++++++------- drivers/net/hns3/hns3_rxtx.h | 16 +- 8 files changed, 691 insertions(+), 173 deletions(-) diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c index f7cfa00..589547c 100644 --- a/drivers/net/hns3/hns3_cmd.c +++ b/drivers/net/hns3/hns3_cmd.c @@ -443,7 +443,7 @@ static void hns3_parse_capability(struct hns3_hw *hw, if (hns3_get_bit(caps, HNS3_CAPS_PHY_IMP_B)) hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_COPPER_B, 1); if (hns3_get_bit(caps, HNS3_CAPS_TQP_TXRX_INDEP_B)) - hns3_set_bit(hw->capability, HNS3_CAPS_TQP_TXRX_INDEP_B, 1); + hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_INDEP_TXRX_B, 1); if (hns3_get_bit(caps, HNS3_CAPS_STASH_B)) hns3_set_bit(hw->capability, HNS3_DEV_SUPPORT_STASH_B, 1); } diff --git a/drivers/net/hns3/hns3_cmd.h b/drivers/net/hns3/hns3_cmd.h index ecca75c..bbd0034 100644 --- a/drivers/net/hns3/hns3_cmd.h +++ b/drivers/net/hns3/hns3_cmd.h @@ -159,6 +159,7 @@ enum hns3_opcode_type { HNS3_OPC_QUERY_RX_STATUS = 0x0B13, HNS3_OPC_CFG_COM_TQP_QUEUE = 0x0B20, HNS3_OPC_RESET_TQP_QUEUE = 0x0B22, + HNS3_OPC_RESET_TQP_QUEUE_INDEP = 0x0B23, /* TSO command */ HNS3_OPC_TSO_GENERIC_CONFIG = 0x0C01, @@ -810,7 +811,8 @@ struct hns3_reset_tqp_queue_cmd { uint16_t tqp_id; uint8_t reset_req; uint8_t ready_to_reset; - uint8_t rsv[20]; + uint8_t queue_direction; + uint8_t rsv[19]; }; #define HNS3_CFG_RESET_MAC_B 3 diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 6e0f52b..d6f3cc0 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -2293,20 +2293,25 @@ hns3_dev_configure(struct rte_eth_dev *dev) bool gro_en; int ret; + hw->cfg_max_queues = RTE_MAX(nb_rx_q, nb_tx_q); + /* - * Hardware does not support individually enable/disable/reset the Tx or - * Rx queue in hns3 network engine. Driver must enable/disable/reset Tx - * and Rx queues at the same time. When the numbers of Tx queues - * allocated by upper applications are not equal to the numbers of Rx - * queues, driver needs to setup fake Tx or Rx queues to adjust numbers - * of Tx/Rx queues. otherwise, network engine can not work as usual. But - * these fake queues are imperceptible, and can not be used by upper - * applications. + * Some versions of hardware network engine does not support + * individually enable/disable/reset the Tx or Rx queue. These devices + * must enable/disable/reset Tx and Rx queues at the same time. When the + * numbers of Tx queues allocated by upper applications are not equal to + * the numbers of Rx queues, driver needs to setup fake Tx or Rx queues + * to adjust numbers of Tx/Rx queues. otherwise, network engine can not + * work as usual. But these fake queues are imperceptible, and can not + * be used by upper applications. */ - ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q); - if (ret) { - hns3_err(hw, "Failed to set rx/tx fake queues: %d", ret); - return ret; + if (!hns3_dev_indep_txrx_supported(hw)) { + ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q); + if (ret) { + hns3_err(hw, "fail to set Rx/Tx fake queues, ret = %d.", + ret); + return ret; + } } hw->adapter_state = HNS3_NIC_CONFIGURING; @@ -2504,6 +2509,10 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_TX_OFFLOAD_MBUF_FAST_FREE | hns3_txvlan_cap_get(hw)); + if (hns3_dev_indep_txrx_supported(hw)) + info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + info->rx_desc_lim = (struct rte_eth_desc_lim) { .nb_max = HNS3_MAX_RING_DESC, .nb_min = HNS3_MIN_RING_DESC, @@ -4684,23 +4693,22 @@ hns3_do_start(struct hns3_adapter *hns, bool reset_queue) if (ret) return ret; - /* Enable queues */ - ret = hns3_start_queues(hns, reset_queue); + ret = hns3_init_queues(hns, reset_queue); if (ret) { - PMD_INIT_LOG(ERR, "Failed to start queues: %d", ret); + PMD_INIT_LOG(ERR, "failed to init queues, ret = %d.", ret); return ret; } - /* Enable MAC */ ret = hns3_cfg_mac_mode(hw, true); if (ret) { - PMD_INIT_LOG(ERR, "Failed to enable MAC: %d", ret); + PMD_INIT_LOG(ERR, "failed to enable MAC, ret = %d", ret); goto err_config_mac_mode; } return 0; err_config_mac_mode: - hns3_stop_queues(hns, true); + hns3_dev_release_mbufs(hns); + hns3_reset_all_tqps(hns); return ret; } @@ -4831,6 +4839,32 @@ hns3_dev_start(struct rte_eth_dev *dev) return ret; } + /* + * There are three register used to control the status of a TQP + * (contains a pair of Tx queue and Rx queue) in the new version network + * engine. One is used to control the enabling of Tx queue, the other is + * used to control the enabling of Rx queue, and the last is the master + * switch used to control the enabling of the tqp. The Tx register and + * TQP register must be enabled at the same time to enable a Tx queue. + * The same applies to the Rx queue. For the older network engine, this + * function only refresh the enabled flag, and it is used to update the + * status of queue in the dpdk framework. + */ + ret = hns3_start_all_txqs(dev); + if (ret) { + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + return ret; + } + + ret = hns3_start_all_rxqs(dev); + if (ret) { + hns3_stop_all_txqs(dev); + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + return ret; + } + hw->adapter_state = HNS3_NIC_STARTED; rte_spinlock_unlock(&hw->lock); @@ -4843,11 +4877,12 @@ hns3_dev_start(struct rte_eth_dev *dev) /* Enable interrupt of all rx queues before enabling queues */ hns3_dev_all_rx_queue_intr_enable(hw, true); + /* - * When finished the initialization, enable queues to receive/transmit - * packets. + * After finished the initialization, enable tqps to receive/transmit + * packets and refresh all queue status. */ - hns3_enable_all_queues(hw, true); + hns3_start_tqps(hw); hns3_info(hw, "hns3 dev start successful!"); return 0; @@ -4857,7 +4892,6 @@ static int hns3_do_stop(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; - bool reset_queue; int ret; ret = hns3_cfg_mac_mode(hw, false); @@ -4867,11 +4901,15 @@ hns3_do_stop(struct hns3_adapter *hns) if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) { hns3_configure_all_mac_addr(hns, true); - reset_queue = true; - } else - reset_queue = false; + ret = hns3_reset_all_tqps(hns); + if (ret) { + hns3_err(hw, "failed to reset all queues ret = %d.", + ret); + return ret; + } + } hw->mac.default_addr_setted = false; - return hns3_stop_queues(hns, reset_queue); + return 0; } static void @@ -4928,6 +4966,7 @@ hns3_dev_stop(struct rte_eth_dev *dev) rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { + hns3_stop_tqps(hw); hns3_do_stop(hns); hns3_unmap_rx_interrupt(dev); hns3_dev_release_mbufs(hns); @@ -5165,7 +5204,7 @@ hns3_reinit_dev(struct hns3_adapter *hns) return ret; } - ret = hns3_reset_all_queues(hns); + ret = hns3_reset_all_tqps(hns); if (ret) { hns3_err(hw, "Failed to reset all queues: %d", ret); return ret; @@ -5443,6 +5482,7 @@ hns3_stop_service(struct hns3_adapter *hns) rte_spinlock_lock(&hw->lock); if (hns->hw.adapter_state == HNS3_NIC_STARTED || hw->adapter_state == HNS3_NIC_STOPPING) { + hns3_enable_all_queues(hw, false); hns3_do_stop(hns); hw->reset.mbuf_deferred_free = true; } else @@ -5626,6 +5666,10 @@ static const struct eth_dev_ops hns3_eth_dev_ops = { .tx_queue_setup = hns3_tx_queue_setup, .rx_queue_release = hns3_dev_rx_queue_release, .tx_queue_release = hns3_dev_tx_queue_release, + .rx_queue_start = hns3_dev_rx_queue_start, + .rx_queue_stop = hns3_dev_rx_queue_stop, + .tx_queue_start = hns3_dev_tx_queue_start, + .tx_queue_stop = hns3_dev_tx_queue_stop, .rx_queue_intr_enable = hns3_dev_rx_queue_intr_enable, .rx_queue_intr_disable = hns3_dev_rx_queue_intr_disable, .rxq_info_get = hns3_rxq_info_get, diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c index 0b949e9..849f6cc 100644 --- a/drivers/net/hns3/hns3_ethdev_vf.c +++ b/drivers/net/hns3/hns3_ethdev_vf.c @@ -757,20 +757,25 @@ hns3vf_dev_configure(struct rte_eth_dev *dev) bool gro_en; int ret; + hw->cfg_max_queues = RTE_MAX(nb_rx_q, nb_tx_q); + /* - * Hardware does not support individually enable/disable/reset the Tx or - * Rx queue in hns3 network engine. Driver must enable/disable/reset Tx - * and Rx queues at the same time. When the numbers of Tx queues - * allocated by upper applications are not equal to the numbers of Rx - * queues, driver needs to setup fake Tx or Rx queues to adjust numbers - * of Tx/Rx queues. otherwise, network engine can not work as usual. But - * these fake queues are imperceptible, and can not be used by upper - * applications. + * Some versions of hardware network engine does not support + * individually enable/disable/reset the Tx or Rx queue. These devices + * must enable/disable/reset Tx and Rx queues at the same time. When the + * numbers of Tx queues allocated by upper applications are not equal to + * the numbers of Rx queues, driver needs to setup fake Tx or Rx queues + * to adjust numbers of Tx/Rx queues. otherwise, network engine can not + * work as usual. But these fake queues are imperceptible, and can not + * be used by upper applications. */ - ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q); - if (ret) { - hns3_err(hw, "Failed to set rx/tx fake queues: %d", ret); - return ret; + if (!hns3_dev_indep_txrx_supported(hw)) { + ret = hns3_set_fake_rx_or_tx_queues(dev, nb_rx_q, nb_tx_q); + if (ret) { + hns3_err(hw, "fail to set Rx/Tx fake queues, ret = %d.", + ret); + return ret; + } } hw->adapter_state = HNS3_NIC_CONFIGURING; @@ -956,6 +961,10 @@ hns3vf_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info) DEV_TX_OFFLOAD_MBUF_FAST_FREE | hns3_txvlan_cap_get(hw)); + if (hns3_dev_indep_txrx_supported(hw)) + info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP | + RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP; + info->rx_desc_lim = (struct rte_eth_desc_lim) { .nb_max = HNS3_MAX_RING_DESC, .nb_min = HNS3_MIN_RING_DESC, @@ -1849,16 +1858,20 @@ static int hns3vf_do_stop(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; - bool reset_queue; + int ret; hw->mac.link_status = ETH_LINK_DOWN; if (rte_atomic16_read(&hw->reset.disable_cmd) == 0) { hns3vf_configure_mac_addr(hns, true); - reset_queue = true; - } else - reset_queue = false; - return hns3_stop_queues(hns, reset_queue); + ret = hns3_reset_all_tqps(hns); + if (ret) { + hns3_err(hw, "failed to reset all queues ret = %d", + ret); + return ret; + } + } + return 0; } static void @@ -1914,6 +1927,7 @@ hns3vf_dev_stop(struct rte_eth_dev *dev) rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { + hns3_stop_tqps(hw); hns3vf_do_stop(hns); hns3vf_unmap_rx_interrupt(dev); hns3_dev_release_mbufs(hns); @@ -2023,9 +2037,9 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue) if (ret) return ret; - ret = hns3_start_queues(hns, reset_queue); + ret = hns3_init_queues(hns, reset_queue); if (ret) - hns3_err(hw, "Failed to start queues: %d", ret); + hns3_err(hw, "failed to init queues, ret = %d.", ret); return ret; } @@ -2155,6 +2169,33 @@ hns3vf_dev_start(struct rte_eth_dev *dev) rte_spinlock_unlock(&hw->lock); return ret; } + + /* + * There are three register used to control the status of a TQP + * (contains a pair of Tx queue and Rx queue) in the new version network + * engine. One is used to control the enabling of Tx queue, the other is + * used to control the enabling of Rx queue, and the last is the master + * switch used to control the enabling of the tqp. The Tx register and + * TQP register must be enabled at the same time to enable a Tx queue. + * The same applies to the Rx queue. For the older network enginem, this + * function only refresh the enabled flag, and it is used to update the + * status of queue in the dpdk framework. + */ + ret = hns3_start_all_txqs(dev); + if (ret) { + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + return ret; + } + + ret = hns3_start_all_rxqs(dev); + if (ret) { + hns3_stop_all_txqs(dev); + hw->adapter_state = HNS3_NIC_CONFIGURED; + rte_spinlock_unlock(&hw->lock); + return ret; + } + hw->adapter_state = HNS3_NIC_STARTED; rte_spinlock_unlock(&hw->lock); @@ -2167,11 +2208,12 @@ hns3vf_dev_start(struct rte_eth_dev *dev) /* Enable interrupt of all rx queues before enabling queues */ hns3_dev_all_rx_queue_intr_enable(hw, true); + /* - * When finished the initialization, enable queues to receive/transmit - * packets. + * After finished the initialization, start all tqps to receive/transmit + * packets and refresh all queue status. */ - hns3_enable_all_queues(hw, true); + hns3_start_tqps(hw); return ret; } @@ -2313,6 +2355,7 @@ hns3vf_stop_service(struct hns3_adapter *hns) rte_spinlock_lock(&hw->lock); if (hw->adapter_state == HNS3_NIC_STARTED || hw->adapter_state == HNS3_NIC_STOPPING) { + hns3_enable_all_queues(hw, false); hns3vf_do_stop(hns); hw->reset.mbuf_deferred_free = true; } else @@ -2555,7 +2598,7 @@ hns3vf_reinit_dev(struct hns3_adapter *hns) rte_intr_enable(&pci_dev->intr_handle); } - ret = hns3_reset_all_queues(hns); + ret = hns3_reset_all_tqps(hns); if (ret) { hns3_err(hw, "Failed to reset all queues: %d", ret); return ret; @@ -2593,6 +2636,10 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = { .tx_queue_setup = hns3_tx_queue_setup, .rx_queue_release = hns3_dev_rx_queue_release, .tx_queue_release = hns3_dev_tx_queue_release, + .rx_queue_start = hns3_dev_rx_queue_start, + .rx_queue_stop = hns3_dev_rx_queue_stop, + .tx_queue_start = hns3_dev_tx_queue_start, + .tx_queue_stop = hns3_dev_tx_queue_stop, .rx_queue_intr_enable = hns3_dev_rx_queue_intr_enable, .rx_queue_intr_disable = hns3_dev_rx_queue_intr_disable, .rxq_info_get = hns3_rxq_info_get, diff --git a/drivers/net/hns3/hns3_regs.c b/drivers/net/hns3/hns3_regs.c index a76f42c..1b7dd72 100644 --- a/drivers/net/hns3/hns3_regs.c +++ b/drivers/net/hns3/hns3_regs.c @@ -62,6 +62,7 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG, HNS3_RING_RX_BASEADDR_H_REG, HNS3_RING_RX_BD_NUM_REG, HNS3_RING_RX_BD_LEN_REG, + HNS3_RING_RX_EN_REG, HNS3_RING_RX_MERGE_EN_REG, HNS3_RING_RX_TAIL_REG, HNS3_RING_RX_HEAD_REG, @@ -73,6 +74,7 @@ static const uint32_t ring_reg_addrs[] = {HNS3_RING_RX_BASEADDR_L_REG, HNS3_RING_TX_BASEADDR_L_REG, HNS3_RING_TX_BASEADDR_H_REG, HNS3_RING_TX_BD_NUM_REG, + HNS3_RING_TX_EN_REG, HNS3_RING_TX_PRIORITY_REG, HNS3_RING_TX_TC_REG, HNS3_RING_TX_MERGE_EN_REG, diff --git a/drivers/net/hns3/hns3_regs.h b/drivers/net/hns3/hns3_regs.h index d83c3b3..81a0af5 100644 --- a/drivers/net/hns3/hns3_regs.h +++ b/drivers/net/hns3/hns3_regs.h @@ -83,6 +83,8 @@ #define HNS3_RING_TX_BD_ERR_REG 0x00074 #define HNS3_RING_EN_REG 0x00090 +#define HNS3_RING_RX_EN_REG 0x00098 +#define HNS3_RING_TX_EN_REG 0x000d4 #define HNS3_RING_EN_B 0 diff --git a/drivers/net/hns3/hns3_rxtx.c b/drivers/net/hns3/hns3_rxtx.c index e3f0db4..60f110c 100644 --- a/drivers/net/hns3/hns3_rxtx.c +++ b/drivers/net/hns3/hns3_rxtx.c @@ -74,7 +74,7 @@ hns3_tx_queue_release_mbufs(struct hns3_tx_queue *txq) { uint16_t i; - /* Note: Fake rx queue will not enter here */ + /* Note: Fake tx queue will not enter here */ if (txq->sw_ring) { for (i = 0; i < txq->nb_tx_desc; i++) { if (txq->sw_ring[i].mbuf) { @@ -371,27 +371,159 @@ hns3_enable_all_queues(struct hns3_hw *hw, bool en) struct hns3_rx_queue *rxq; struct hns3_tx_queue *txq; uint32_t rcb_reg; + void *tqp_base; int i; for (i = 0; i < hw->cfg_max_queues; i++) { - if (i < nb_rx_q) - rxq = hw->data->rx_queues[i]; - else - rxq = hw->fkq_data.rx_queues[i - nb_rx_q]; - if (i < nb_tx_q) - txq = hw->data->tx_queues[i]; - else - txq = hw->fkq_data.tx_queues[i - nb_tx_q]; - if (rxq == NULL || txq == NULL || - (en && (rxq->rx_deferred_start || txq->tx_deferred_start))) - continue; + if (hns3_dev_indep_txrx_supported(hw)) { + rxq = i < nb_rx_q ? hw->data->rx_queues[i] : NULL; + txq = i < nb_tx_q ? hw->data->tx_queues[i] : NULL; + /* + * After initialization, rxq and txq won't be NULL at + * the same time. + */ + if (rxq != NULL) + tqp_base = rxq->io_base; + else if (txq != NULL) + tqp_base = txq->io_base; + else + return; + } else { + rxq = i < nb_rx_q ? hw->data->rx_queues[i] : + hw->fkq_data.rx_queues[i - nb_rx_q]; - rcb_reg = hns3_read_dev(rxq, HNS3_RING_EN_REG); + tqp_base = rxq->io_base; + } + /* + * This is the master switch that used to control the enabling + * of a pair of Tx and Rx queues. Both the Rx and Tx point to + * the same register + */ + rcb_reg = hns3_read_reg(tqp_base, HNS3_RING_EN_REG); if (en) rcb_reg |= BIT(HNS3_RING_EN_B); else rcb_reg &= ~BIT(HNS3_RING_EN_B); - hns3_write_dev(rxq, HNS3_RING_EN_REG, rcb_reg); + hns3_write_reg(tqp_base, HNS3_RING_EN_REG, rcb_reg); + } +} + +static void +hns3_enable_txq(struct hns3_tx_queue *txq, bool en) +{ + struct hns3_hw *hw = &txq->hns->hw; + uint32_t reg; + + if (hns3_dev_indep_txrx_supported(hw)) { + reg = hns3_read_dev(txq, HNS3_RING_TX_EN_REG); + if (en) + reg |= BIT(HNS3_RING_EN_B); + else + reg &= ~BIT(HNS3_RING_EN_B); + hns3_write_dev(txq, HNS3_RING_TX_EN_REG, reg); + } + txq->enabled = en; +} + +static void +hns3_enable_rxq(struct hns3_rx_queue *rxq, bool en) +{ + struct hns3_hw *hw = &rxq->hns->hw; + uint32_t reg; + + if (hns3_dev_indep_txrx_supported(hw)) { + reg = hns3_read_dev(rxq, HNS3_RING_RX_EN_REG); + if (en) + reg |= BIT(HNS3_RING_EN_B); + else + reg &= ~BIT(HNS3_RING_EN_B); + hns3_write_dev(rxq, HNS3_RING_RX_EN_REG, reg); + } + rxq->enabled = en; +} + +int +hns3_start_all_txqs(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_tx_queue *txq; + uint16_t i, j; + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = hw->data->tx_queues[i]; + if (!txq) { + hns3_err(hw, "Tx queue %u not available or setup.", i); + goto start_txqs_fail; + } + /* + * Tx queue is enabled by default. Therefore, the Tx queues + * needs to be disabled when deferred_start is set. There is + * another master switch used to control the enabling of a pair + * of Tx and Rx queues. And the master switch is disabled by + * default. + */ + if (txq->tx_deferred_start) + hns3_enable_txq(txq, false); + else + hns3_enable_txq(txq, true); + } + return 0; + +start_txqs_fail: + for (j = 0; j < i; j++) { + txq = hw->data->tx_queues[j]; + hns3_enable_txq(txq, false); + } + return -EINVAL; +} + +int +hns3_start_all_rxqs(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_rx_queue *rxq; + uint16_t i, j; + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq = hw->data->rx_queues[i]; + if (!rxq) { + hns3_err(hw, "Rx queue %u not available or setup.", i); + goto start_rxqs_fail; + } + /* + * Rx queue is enabled by default. Therefore, the Rx queues + * needs to be disabled when deferred_start is set. There is + * another master switch used to control the enabling of a pair + * of Tx and Rx queues. And the master switch is disabled by + * default. + */ + if (rxq->rx_deferred_start) + hns3_enable_rxq(rxq, false); + else + hns3_enable_rxq(rxq, true); + } + return 0; + +start_rxqs_fail: + for (j = 0; j < i; j++) { + rxq = hw->data->rx_queues[j]; + hns3_enable_rxq(rxq, false); + } + return -EINVAL; +} + +void +hns3_stop_all_txqs(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_tx_queue *txq; + uint16_t i; + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + txq = hw->data->tx_queues[i]; + if (!txq) + continue; + hns3_enable_txq(txq, false); } } @@ -428,16 +560,17 @@ hns3_send_reset_tqp_cmd(struct hns3_hw *hw, uint16_t queue_id, bool enable) req = (struct hns3_reset_tqp_queue_cmd *)desc.data; req->tqp_id = rte_cpu_to_le_16(queue_id); hns3_set_bit(req->reset_req, HNS3_TQP_RESET_B, enable ? 1 : 0); - ret = hns3_cmd_send(hw, &desc, 1); if (ret) - hns3_err(hw, "Send tqp reset cmd error, ret = %d", ret); + hns3_err(hw, "send tqp reset cmd error, queue_id = %u, " + "ret = %d", queue_id, ret); return ret; } static int -hns3_get_reset_status(struct hns3_hw *hw, uint16_t queue_id) +hns3_get_tqp_reset_status(struct hns3_hw *hw, uint16_t queue_id, + uint8_t *reset_status) { struct hns3_reset_tqp_queue_cmd *req; struct hns3_cmd_desc desc; @@ -450,19 +583,20 @@ hns3_get_reset_status(struct hns3_hw *hw, uint16_t queue_id) ret = hns3_cmd_send(hw, &desc, 1); if (ret) { - hns3_err(hw, "Get reset status error, ret =%d", ret); + hns3_err(hw, "get tqp reset status error, queue_id = %u, " + "ret = %d.", queue_id, ret); return ret; } - - return hns3_get_bit(req->ready_to_reset, HNS3_TQP_RESET_B); + *reset_status = hns3_get_bit(req->ready_to_reset, HNS3_TQP_RESET_B); + return ret; } static int -hns3_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) +hns3pf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) { #define HNS3_TQP_RESET_TRY_MS 200 + uint8_t reset_status; uint64_t end; - int reset_status; int ret; ret = hns3_tqp_enable(hw, queue_id, false); @@ -479,21 +613,23 @@ hns3_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) hns3_err(hw, "Send reset tqp cmd fail, ret = %d", ret); return ret; } - ret = -ETIMEDOUT; end = get_timeofday_ms() + HNS3_TQP_RESET_TRY_MS; do { /* Wait for tqp hw reset */ rte_delay_ms(HNS3_POLL_RESPONE_MS); - reset_status = hns3_get_reset_status(hw, queue_id); - if (reset_status) { - ret = 0; + ret = hns3_get_tqp_reset_status(hw, queue_id, &reset_status); + if (ret) + goto tqp_reset_fail; + + if (reset_status) break; - } } while (get_timeofday_ms() < end); - if (ret) { - hns3_err(hw, "Reset TQP fail, ret = %d", ret); - return ret; + if (!reset_status) { + ret = -ETIMEDOUT; + hns3_err(hw, "reset tqp timeout, queue_id = %u, ret = %d", + queue_id, ret); + goto tqp_reset_fail; } ret = hns3_send_reset_tqp_cmd(hw, queue_id, false); @@ -501,6 +637,10 @@ hns3_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) hns3_err(hw, "Deassert the soft reset fail, ret = %d", ret); return ret; + +tqp_reset_fail: + hns3_send_reset_tqp_cmd(hw, queue_id, false); + return ret; } static int @@ -516,28 +656,33 @@ hns3vf_reset_tqp(struct hns3_hw *hw, uint16_t queue_id) memcpy(msg_data, &queue_id, sizeof(uint16_t)); - return hns3_send_mbx_msg(hw, HNS3_MBX_QUEUE_RESET, 0, msg_data, + ret = hns3_send_mbx_msg(hw, HNS3_MBX_QUEUE_RESET, 0, msg_data, sizeof(msg_data), true, NULL, 0); + if (ret) + hns3_err(hw, "fail to reset tqp, queue_id = %u, ret = %d.", + queue_id, ret); + return ret; } static int -hns3_reset_queue(struct hns3_adapter *hns, uint16_t queue_id) +hns3_reset_tqp(struct hns3_adapter *hns, uint16_t queue_id) { struct hns3_hw *hw = &hns->hw; + if (hns->is_vf) return hns3vf_reset_tqp(hw, queue_id); else - return hns3_reset_tqp(hw, queue_id); + return hns3pf_reset_tqp(hw, queue_id); } int -hns3_reset_all_queues(struct hns3_adapter *hns) +hns3_reset_all_tqps(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; int ret, i; for (i = 0; i < hw->cfg_max_queues; i++) { - ret = hns3_reset_queue(hns, i); + ret = hns3_reset_tqp(hns, i); if (ret) { hns3_err(hw, "Failed to reset No.%d queue: %d", i, ret); return ret; @@ -546,6 +691,121 @@ hns3_reset_all_queues(struct hns3_adapter *hns) return 0; } +static int +hns3_send_reset_queue_cmd(struct hns3_hw *hw, uint16_t queue_id, + enum hns3_ring_type queue_type, bool enable) +{ + struct hns3_reset_tqp_queue_cmd *req; + struct hns3_cmd_desc desc; + int queue_direction; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RESET_TQP_QUEUE_INDEP, false); + + req = (struct hns3_reset_tqp_queue_cmd *)desc.data; + req->tqp_id = rte_cpu_to_le_16(queue_id); + queue_direction = queue_type == HNS3_RING_TYPE_TX ? 0 : 1; + req->queue_direction = rte_cpu_to_le_16(queue_direction); + hns3_set_bit(req->reset_req, HNS3_TQP_RESET_B, enable ? 1 : 0); + + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) + hns3_err(hw, "send queue reset cmd error, queue_id = %u, " + "queue_type = %s, ret = %d.", queue_id, + queue_type == HNS3_RING_TYPE_TX ? "Tx" : "Rx", ret); + return ret; +} + +static int +hns3_get_queue_reset_status(struct hns3_hw *hw, uint16_t queue_id, + enum hns3_ring_type queue_type, + uint8_t *reset_status) +{ + struct hns3_reset_tqp_queue_cmd *req; + struct hns3_cmd_desc desc; + int queue_direction; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RESET_TQP_QUEUE_INDEP, true); + + req = (struct hns3_reset_tqp_queue_cmd *)desc.data; + req->tqp_id = rte_cpu_to_le_16(queue_id); + queue_direction = queue_type == HNS3_RING_TYPE_TX ? 0 : 1; + req->queue_direction = rte_cpu_to_le_16(queue_direction); + + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { + hns3_err(hw, "get queue reset status error, queue_id = %u " + "queue_type = %s, ret = %d.", queue_id, + queue_type == HNS3_RING_TYPE_TX ? "Tx" : "Rx", ret); + return ret; + } + + *reset_status = hns3_get_bit(req->ready_to_reset, HNS3_TQP_RESET_B); + return ret; +} + +static int +hns3_reset_queue(struct hns3_hw *hw, uint16_t queue_id, + enum hns3_ring_type queue_type) +{ +#define HNS3_QUEUE_RESET_TRY_MS 200 + struct hns3_tx_queue *txq; + struct hns3_rx_queue *rxq; + uint32_t reset_wait_times; + uint32_t max_wait_times; + uint8_t reset_status; + int ret; + + if (queue_type == HNS3_RING_TYPE_TX) { + txq = hw->data->tx_queues[queue_id]; + hns3_enable_txq(txq, false); + } else { + rxq = hw->data->rx_queues[queue_id]; + hns3_enable_rxq(rxq, false); + } + + ret = hns3_send_reset_queue_cmd(hw, queue_id, queue_type, true); + if (ret) { + hns3_err(hw, "send reset queue cmd fail, ret = %d.", ret); + return ret; + } + + reset_wait_times = 0; + max_wait_times = HNS3_QUEUE_RESET_TRY_MS / HNS3_POLL_RESPONE_MS; + while (reset_wait_times < max_wait_times) { + /* Wait for queue hw reset */ + rte_delay_ms(HNS3_POLL_RESPONE_MS); + ret = hns3_get_queue_reset_status(hw, queue_id, + queue_type, &reset_status); + if (ret) + goto queue_reset_fail; + + if (reset_status) + break; + reset_wait_times++; + } + + if (!reset_status) { + hns3_err(hw, "reset queue timeout, queue_id = %u, " + "queue_type = %s", queue_id, + queue_type == HNS3_RING_TYPE_TX ? "Tx" : "Rx"); + ret = -ETIMEDOUT; + goto queue_reset_fail; + } + + ret = hns3_send_reset_queue_cmd(hw, queue_id, queue_type, false); + if (ret) + hns3_err(hw, "deassert queue reset fail, ret = %d.", ret); + + return ret; + +queue_reset_fail: + hns3_send_reset_queue_cmd(hw, queue_id, queue_type, false); + return ret; +} + + void hns3_set_queue_intr_gl(struct hns3_hw *hw, uint16_t queue_id, uint8_t gl_idx, uint16_t gl_value) @@ -658,7 +918,7 @@ hns3_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id) } static int -hns3_dev_rx_queue_start(struct hns3_adapter *hns, uint16_t idx) +hns3_init_rxq(struct hns3_adapter *hns, uint16_t idx) { struct hns3_hw *hw = &hns->hw; struct hns3_rx_queue *rxq; @@ -669,7 +929,7 @@ hns3_dev_rx_queue_start(struct hns3_adapter *hns, uint16_t idx) rxq = (struct hns3_rx_queue *)hw->data->rx_queues[idx]; ret = hns3_alloc_rx_queue_mbufs(hw, rxq); if (ret) { - hns3_err(hw, "Failed to alloc mbuf for No.%d rx queue: %d", + hns3_err(hw, "fail to alloc mbuf for Rx queue %u, ret = %d.", idx, ret); return ret; } @@ -687,7 +947,7 @@ hns3_dev_rx_queue_start(struct hns3_adapter *hns, uint16_t idx) } static void -hns3_fake_rx_queue_start(struct hns3_adapter *hns, uint16_t idx) +hns3_init_fake_rxq(struct hns3_adapter *hns, uint16_t idx) { struct hns3_hw *hw = &hns->hw; struct hns3_rx_queue *rxq; @@ -701,9 +961,8 @@ hns3_fake_rx_queue_start(struct hns3_adapter *hns, uint16_t idx) } static void -hns3_init_tx_queue(struct hns3_tx_queue *queue) +hns3_init_txq(struct hns3_tx_queue *txq) { - struct hns3_tx_queue *txq = queue; struct hns3_desc *desc; int i; @@ -721,26 +980,6 @@ hns3_init_tx_queue(struct hns3_tx_queue *queue) } static void -hns3_dev_tx_queue_start(struct hns3_adapter *hns, uint16_t idx) -{ - struct hns3_hw *hw = &hns->hw; - struct hns3_tx_queue *txq; - - txq = (struct hns3_tx_queue *)hw->data->tx_queues[idx]; - hns3_init_tx_queue(txq); -} - -static void -hns3_fake_tx_queue_start(struct hns3_adapter *hns, uint16_t idx) -{ - struct hns3_hw *hw = &hns->hw; - struct hns3_tx_queue *txq; - - txq = (struct hns3_tx_queue *)hw->fkq_data.tx_queues[idx]; - hns3_init_tx_queue(txq); -} - -static void hns3_init_tx_ring_tc(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; @@ -766,38 +1005,41 @@ hns3_init_tx_ring_tc(struct hns3_adapter *hns) } static int -hns3_start_rx_queues(struct hns3_adapter *hns) +hns3_init_rx_queues(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; struct hns3_rx_queue *rxq; - int i, j; + uint16_t i, j; int ret; /* Initialize RSS for queues */ ret = hns3_config_rss(hns); if (ret) { - hns3_err(hw, "Failed to configure rss %d", ret); + hns3_err(hw, "failed to configure rss, ret = %d.", ret); return ret; } for (i = 0; i < hw->data->nb_rx_queues; i++) { rxq = (struct hns3_rx_queue *)hw->data->rx_queues[i]; - if (rxq == NULL || rxq->rx_deferred_start) + if (!rxq) { + hns3_err(hw, "Rx queue %u not available or setup.", i); + goto out; + } + + if (rxq->rx_deferred_start) continue; - ret = hns3_dev_rx_queue_start(hns, i); + + ret = hns3_init_rxq(hns, i); if (ret) { - hns3_err(hw, "Failed to start No.%d rx queue: %d", i, + hns3_err(hw, "failed to init Rx queue %u, ret = %d.", i, ret); goto out; } } - for (i = 0; i < hw->fkq_data.nb_fake_rx_queues; i++) { - rxq = (struct hns3_rx_queue *)hw->fkq_data.rx_queues[i]; - if (rxq == NULL || rxq->rx_deferred_start) - continue; - hns3_fake_rx_queue_start(hns, i); - } + for (i = 0; i < hw->fkq_data.nb_fake_rx_queues; i++) + hns3_init_fake_rxq(hns, i); + return 0; out: @@ -809,74 +1051,104 @@ hns3_start_rx_queues(struct hns3_adapter *hns) return ret; } -static void -hns3_start_tx_queues(struct hns3_adapter *hns) +static int +hns3_init_tx_queues(struct hns3_adapter *hns) { struct hns3_hw *hw = &hns->hw; struct hns3_tx_queue *txq; - int i; + uint16_t i; for (i = 0; i < hw->data->nb_tx_queues; i++) { txq = (struct hns3_tx_queue *)hw->data->tx_queues[i]; - if (txq == NULL || txq->tx_deferred_start) + if (!txq) { + hns3_err(hw, "Tx queue %u not available or setup.", i); + return -EINVAL; + } + + if (txq->tx_deferred_start) continue; - hns3_dev_tx_queue_start(hns, i); + hns3_init_txq(txq); } for (i = 0; i < hw->fkq_data.nb_fake_tx_queues; i++) { txq = (struct hns3_tx_queue *)hw->fkq_data.tx_queues[i]; - if (txq == NULL || txq->tx_deferred_start) - continue; - hns3_fake_tx_queue_start(hns, i); + hns3_init_txq(txq); } - hns3_init_tx_ring_tc(hns); + + return 0; } /* - * Start all queues. - * Note: just init and setup queues, and don't enable queue rx&tx. + * Init all queues. + * Note: just init and setup queues, and don't enable tqps. */ int -hns3_start_queues(struct hns3_adapter *hns, bool reset_queue) +hns3_init_queues(struct hns3_adapter *hns, bool reset_queue) { struct hns3_hw *hw = &hns->hw; int ret; if (reset_queue) { - ret = hns3_reset_all_queues(hns); + ret = hns3_reset_all_tqps(hns); if (ret) { - hns3_err(hw, "Failed to reset all queues %d", ret); + hns3_err(hw, "failed to reset all queues, ret = %d.", + ret); return ret; } } - ret = hns3_start_rx_queues(hns); + ret = hns3_init_rx_queues(hns); if (ret) { - hns3_err(hw, "Failed to start rx queues: %d", ret); + hns3_err(hw, "failed to init rx queues, ret = %d.", ret); return ret; } - hns3_start_tx_queues(hns); + ret = hns3_init_tx_queues(hns); + if (ret) { + hns3_dev_release_mbufs(hns); + hns3_err(hw, "failed to init tx queues, ret = %d.", ret); + } - return 0; + return ret; } -int -hns3_stop_queues(struct hns3_adapter *hns, bool reset_queue) +void +hns3_start_tqps(struct hns3_hw *hw) { - struct hns3_hw *hw = &hns->hw; - int ret; + struct hns3_tx_queue *txq; + struct hns3_rx_queue *rxq; + uint16_t i; - hns3_enable_all_queues(hw, false); - if (reset_queue) { - ret = hns3_reset_all_queues(hns); - if (ret) { - hns3_err(hw, "Failed to reset all queues %d", ret); - return ret; - } + hns3_enable_all_queues(hw, true); + + for (i = 0; i < hw->data->nb_tx_queues; i++) { + txq = hw->data->tx_queues[i]; + if (txq->enabled) + hw->data->tx_queue_state[i] = + RTE_ETH_QUEUE_STATE_STARTED; } - return 0; + + for (i = 0; i < hw->data->nb_rx_queues; i++) { + rxq = hw->data->rx_queues[i]; + if (rxq->enabled) + hw->data->rx_queue_state[i] = + RTE_ETH_QUEUE_STATE_STARTED; + } +} + +void +hns3_stop_tqps(struct hns3_hw *hw) +{ + uint16_t i; + + hns3_enable_all_queues(hw, false); + + for (i = 0; i < hw->data->nb_tx_queues; i++) + hw->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; + + for (i = 0; i < hw->data->nb_rx_queues; i++) + hw->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; } /* @@ -1202,13 +1474,12 @@ hns3_set_fake_rx_or_tx_queues(struct rte_eth_dev *dev, uint16_t nb_rx_q, int ret; /* Setup new number of fake RX/TX queues and reconfigure device. */ - hw->cfg_max_queues = RTE_MAX(nb_rx_q, nb_tx_q); rx_need_add_nb_q = hw->cfg_max_queues - nb_rx_q; tx_need_add_nb_q = hw->cfg_max_queues - nb_tx_q; ret = hns3_fake_rx_queue_config(hw, rx_need_add_nb_q); if (ret) { hns3_err(hw, "Fail to configure fake rx queues: %d", ret); - goto cfg_fake_rx_q_fail; + return ret; } ret = hns3_fake_tx_queue_config(hw, tx_need_add_nb_q); @@ -1241,8 +1512,6 @@ hns3_set_fake_rx_or_tx_queues(struct rte_eth_dev *dev, uint16_t nb_rx_q, (void)hns3_fake_tx_queue_config(hw, 0); cfg_fake_tx_q_fail: (void)hns3_fake_rx_queue_config(hw, 0); -cfg_fake_rx_q_fail: - hw->cfg_max_queues = 0; return ret; } @@ -1258,7 +1527,7 @@ hns3_dev_release_mbufs(struct hns3_adapter *hns) if (dev_data->rx_queues) for (i = 0; i < dev_data->nb_rx_queues; i++) { rxq = dev_data->rx_queues[i]; - if (rxq == NULL || rxq->rx_deferred_start) + if (rxq == NULL) continue; hns3_rx_queue_release_mbufs(rxq); } @@ -1266,7 +1535,7 @@ hns3_dev_release_mbufs(struct hns3_adapter *hns) if (dev_data->tx_queues) for (i = 0; i < dev_data->nb_tx_queues; i++) { txq = dev_data->tx_queues[i]; - if (txq == NULL || txq->tx_deferred_start) + if (txq == NULL) continue; hns3_tx_queue_release_mbufs(txq); } @@ -1315,10 +1584,49 @@ hns3_rx_buf_len_calc(struct rte_mempool *mp, uint16_t *rx_buf_len) } static int +hns3_rxq_conf_runtime_check(struct hns3_hw *hw, uint16_t buf_size, + uint16_t nb_desc) +{ + struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; + struct rte_eth_rxmode *rxmode = &hw->data->dev_conf.rxmode; + eth_rx_burst_t pkt_burst = dev->rx_pkt_burst; + uint16_t min_vec_bds; + + /* + * HNS3 hardware network engine set scattered as default. If the driver + * is not work in scattered mode and the pkts greater than buf_size + * but smaller than max_rx_pkt_len will be distributed to multiple BDs. + * Driver cannot handle this situation. + */ + if (!hw->data->scattered_rx && rxmode->max_rx_pkt_len > buf_size) { + hns3_err(hw, "max_rx_pkt_len is not allowed to be set greater " + "than rx_buf_len if scattered is off."); + return -EINVAL; + } + + if (pkt_burst == hns3_recv_pkts_vec) { + min_vec_bds = HNS3_DEFAULT_RXQ_REARM_THRESH + + HNS3_DEFAULT_RX_BURST; + if (nb_desc < min_vec_bds || + nb_desc % HNS3_DEFAULT_RXQ_REARM_THRESH) { + hns3_err(hw, "if Rx burst mode is vector, " + "number of descriptor is required to be " + "bigger than min vector bds:%u, and could be " + "divided by rxq rearm thresh:%u.", + min_vec_bds, HNS3_DEFAULT_RXQ_REARM_THRESH); + return -EINVAL; + } + } + return 0; +} + +static int hns3_rx_queue_conf_check(struct hns3_hw *hw, const struct rte_eth_rxconf *conf, struct rte_mempool *mp, uint16_t nb_desc, uint16_t *buf_size) { + int ret; + if (nb_desc > HNS3_MAX_RING_DESC || nb_desc < HNS3_MIN_RING_DESC || nb_desc % HNS3_ALIGN_RING_DESC) { hns3_err(hw, "Number (%u) of rx descriptors is invalid", @@ -1338,6 +1646,14 @@ hns3_rx_queue_conf_check(struct hns3_hw *hw, const struct rte_eth_rxconf *conf, return -EINVAL; } + if (hw->data->dev_started) { + ret = hns3_rxq_conf_runtime_check(hw, *buf_size, nb_desc); + if (ret) { + hns3_err(hw, "Rx queue runtime setup fail."); + return ret; + } + } + return 0; } @@ -1370,11 +1686,6 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, int rx_entry_len; int ret; - if (dev->data->dev_started) { - hns3_err(hw, "rx_queue_setup after dev_start no supported"); - return -EINVAL; - } - ret = hns3_rx_queue_conf_check(hw, conf, mp, nb_desc, &rx_buf_size); if (ret) return ret; @@ -1402,7 +1713,12 @@ hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, rxq->mb_pool = mp; rxq->rx_free_thresh = (conf->rx_free_thresh > 0) ? conf->rx_free_thresh : HNS3_DEFAULT_RX_FREE_THRESH; + rxq->rx_deferred_start = conf->rx_deferred_start; + if (rxq->rx_deferred_start && !hns3_dev_indep_txrx_supported(hw)) { + hns3_warn(hw, "deferred start is not supported."); + rxq->rx_deferred_start = false; + } rx_entry_len = (rxq->nb_rx_desc + HNS3_DEFAULT_RX_BURST) * sizeof(struct hns3_entry); @@ -2132,11 +2448,6 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, int tx_entry_len; int ret; - if (dev->data->dev_started) { - hns3_err(hw, "tx_queue_setup after dev_start no supported"); - return -EINVAL; - } - ret = hns3_tx_queue_conf_check(hw, conf, nb_desc, &tx_rs_thresh, &tx_free_thresh, idx); if (ret) @@ -2160,6 +2471,11 @@ hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, } txq->tx_deferred_start = conf->tx_deferred_start; + if (txq->tx_deferred_start && !hns3_dev_indep_txrx_supported(hw)) { + hns3_warn(hw, "deferred start is not supported."); + txq->tx_deferred_start = false; + } + tx_entry_len = sizeof(struct hns3_entry) * txq->nb_tx_desc; txq->sw_ring = rte_zmalloc_socket("hns3 TX sw ring", tx_entry_len, RTE_CACHE_LINE_SIZE, socket_id); @@ -3377,3 +3693,98 @@ hns3_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, qinfo->conf.tx_free_thresh = txq->tx_free_thresh; qinfo->conf.tx_deferred_start = txq->tx_deferred_start; } + +int +hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_rx_queue *rxq = dev->data->rx_queues[rx_queue_id]; + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + int ret; + + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + + ret = hns3_reset_queue(hw, rx_queue_id, HNS3_RING_TYPE_RX); + if (ret) { + hns3_err(hw, "fail to reset Rx queue %u, ret = %d.", + rx_queue_id, ret); + return ret; + } + + ret = hns3_init_rxq(hns, rx_queue_id); + if (ret) { + hns3_err(hw, "fail to init Rx queue %u, ret = %d.", + rx_queue_id, ret); + return ret; + } + + hns3_enable_rxq(rxq, true); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + return ret; +} + +int +hns3_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_rx_queue *rxq = dev->data->rx_queues[rx_queue_id]; + + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + + hns3_enable_rxq(rxq, false); + hns3_rx_queue_release_mbufs(rxq); + dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + return 0; +} + +int +hns3_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_tx_queue *txq = dev->data->tx_queues[tx_queue_id]; + int ret; + + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + + ret = hns3_reset_queue(hw, tx_queue_id, HNS3_RING_TYPE_TX); + if (ret) { + hns3_err(hw, "fail to reset Tx queue %u, ret = %d.", + tx_queue_id, ret); + return ret; + } + + hns3_init_txq(txq); + hns3_enable_txq(txq, true); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; + + return ret; +} + +int +hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_tx_queue *txq = dev->data->tx_queues[tx_queue_id]; + + if (!hns3_dev_indep_txrx_supported(hw)) + return -ENOTSUP; + + hns3_enable_txq(txq, false); + hns3_tx_queue_release_mbufs(txq); + /* + * All the mbufs in sw_ring are released and all the pointers in sw_ring + * are set to NULL. If this queue is still called by upper layer, + * residual SW status of this txq may cause these pointers in sw_ring + * which have been set to NULL to be released again. To avoid it, + * reinit the txq. + */ + hns3_init_txq(txq); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; + + return 0; +} diff --git a/drivers/net/hns3/hns3_rxtx.h b/drivers/net/hns3/hns3_rxtx.h index cdfe115..abc7c54 100644 --- a/drivers/net/hns3/hns3_rxtx.h +++ b/drivers/net/hns3/hns3_rxtx.h @@ -307,6 +307,7 @@ struct hns3_rx_queue { * point, the pvid_sw_discard_en will be false. */ bool pvid_sw_discard_en; + bool enabled; /* indicate if Rx queue has been enabled */ uint64_t l2_errors; uint64_t pkt_len_errors; @@ -405,6 +406,7 @@ struct hns3_tx_queue { * this point. */ bool pvid_sw_shift_en; + bool enabled; /* indicate if Tx queue has been enabled */ /* * The following items are used for the abnormal errors statistics in @@ -602,13 +604,14 @@ hns3_rx_calc_ptype(struct hns3_rx_queue *rxq, const uint32_t l234_info, void hns3_dev_rx_queue_release(void *queue); void hns3_dev_tx_queue_release(void *queue); void hns3_free_all_queues(struct rte_eth_dev *dev); -int hns3_reset_all_queues(struct hns3_adapter *hns); +int hns3_reset_all_tqps(struct hns3_adapter *hns); void hns3_dev_all_rx_queue_intr_enable(struct hns3_hw *hw, bool en); int hns3_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id); int hns3_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id); void hns3_enable_all_queues(struct hns3_hw *hw, bool en); -int hns3_start_queues(struct hns3_adapter *hns, bool reset_queue); -int hns3_stop_queues(struct hns3_adapter *hns, bool reset_queue); +int hns3_init_queues(struct hns3_adapter *hns, bool reset_queue); +void hns3_start_tqps(struct hns3_hw *hw); +void hns3_stop_tqps(struct hns3_hw *hw); int hns3_rxq_iterate(struct rte_eth_dev *dev, int (*callback)(struct hns3_rx_queue *, void *), void *arg); void hns3_dev_release_mbufs(struct hns3_adapter *hns); @@ -617,6 +620,10 @@ int hns3_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, struct rte_mempool *mp); int hns3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t nb_desc, unsigned int socket, const struct rte_eth_txconf *conf); +int hns3_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id); +int hns3_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id); +int hns3_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id); +int hns3_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id); uint16_t hns3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); uint16_t hns3_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, @@ -662,5 +669,8 @@ void hns3_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, void hns3_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, struct rte_eth_txq_info *qinfo); uint32_t hns3_get_tqp_reg_offset(uint16_t idx); +int hns3_start_all_txqs(struct rte_eth_dev *dev); +int hns3_start_all_rxqs(struct rte_eth_dev *dev); +void hns3_stop_all_txqs(struct rte_eth_dev *dev); #endif /* _HNS3_RXTX_H_ */ From patchwork Tue Sep 29 12:01:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79194 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id E5BD1A04C0; Tue, 29 Sep 2020 14:04:12 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id CC3E61DA93; Tue, 29 Sep 2020 14:01:42 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id BFAFB1DA21 for ; Tue, 29 Sep 2020 14:01:28 +0200 (CEST) X-ASG-Debug-ID: 1601380886-149d11049b2967d0001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id TXDSdeh8u4WRT6Lx (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:26 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:26 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:16 +0800 X-ASG-Orig-Subj: [PATCH v2 8/9] net/hns3: check return value when reading PCI config space Message-ID: <20200929120117.50394-9-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380886 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 4205 Subject: [dpdk-dev] [PATCH v2 8/9] net/hns3: check return value when reading PCI config space X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Hongbo Zheng This patch add return value check when calling rte_pci_read_config function. Fixes: cea37e513329 ("net/hns3: fix FLR reset") Cc: stable@dpdk.org Signed-off-by: Hongbo Zheng Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_ethdev_vf.c | 62 ++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c index 849f6cc..a6cc11d 100644 --- a/drivers/net/hns3/hns3_ethdev_vf.c +++ b/drivers/net/hns3/hns3_ethdev_vf.c @@ -64,12 +64,18 @@ static int hns3vf_add_mc_mac_addr(struct hns3_hw *hw, static int hns3vf_remove_mc_mac_addr(struct hns3_hw *hw, struct rte_ether_addr *mac_addr); /* set PCI bus mastering */ -static void +static int hns3vf_set_bus_master(const struct rte_pci_device *device, bool op) { uint16_t reg; + int ret; - rte_pci_read_config(device, ®, sizeof(reg), PCI_COMMAND); + ret = rte_pci_read_config(device, ®, sizeof(reg), PCI_COMMAND); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to read PCI offset 0x%x", + PCI_COMMAND); + return ret; + } if (op) /* set the master bit */ @@ -77,7 +83,7 @@ hns3vf_set_bus_master(const struct rte_pci_device *device, bool op) else reg &= ~(PCI_COMMAND_MASTER); - rte_pci_write_config(device, ®, sizeof(reg), PCI_COMMAND); + return rte_pci_write_config(device, ®, sizeof(reg), PCI_COMMAND); } /** @@ -94,16 +100,34 @@ hns3vf_find_pci_capability(const struct rte_pci_device *device, int cap) uint8_t pos; uint8_t id; int ttl; + int ret; + + ret = rte_pci_read_config(device, &status, sizeof(status), PCI_STATUS); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to read PCI offset 0x%x", PCI_STATUS); + return 0; + } - rte_pci_read_config(device, &status, sizeof(status), PCI_STATUS); if (!(status & PCI_STATUS_CAP_LIST)) return 0; ttl = MAX_PCIE_CAPABILITY; - rte_pci_read_config(device, &pos, sizeof(pos), PCI_CAPABILITY_LIST); + ret = rte_pci_read_config(device, &pos, sizeof(pos), + PCI_CAPABILITY_LIST); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to read PCI offset 0x%x", + PCI_CAPABILITY_LIST); + return 0; + } + while (ttl-- && pos >= PCI_STD_HEADER_SIZEOF) { - rte_pci_read_config(device, &id, sizeof(id), - (pos + PCI_CAP_LIST_ID)); + ret = rte_pci_read_config(device, &id, sizeof(id), + (pos + PCI_CAP_LIST_ID)); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to read PCI offset 0x%x", + (pos + PCI_CAP_LIST_ID)); + break; + } if (id == 0xFF) break; @@ -111,8 +135,13 @@ hns3vf_find_pci_capability(const struct rte_pci_device *device, int cap) if (id == cap) return (int)pos; - rte_pci_read_config(device, &pos, sizeof(pos), - (pos + PCI_CAP_LIST_NEXT)); + ret = rte_pci_read_config(device, &pos, sizeof(pos), + (pos + PCI_CAP_LIST_NEXT)); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to read PCI offset 0x%x", + (pos + PCI_CAP_LIST_NEXT)); + break; + } } return 0; } @@ -122,11 +151,18 @@ hns3vf_enable_msix(const struct rte_pci_device *device, bool op) { uint16_t control; int pos; + int ret; pos = hns3vf_find_pci_capability(device, PCI_CAP_ID_MSIX); if (pos) { - rte_pci_read_config(device, &control, sizeof(control), + ret = rte_pci_read_config(device, &control, sizeof(control), (pos + PCI_MSIX_FLAGS)); + if (ret < 0) { + PMD_INIT_LOG(ERR, "Failed to read PCI offset 0x%x", + (pos + PCI_MSIX_FLAGS)); + return -ENXIO; + } + if (op) control |= PCI_MSIX_FLAGS_ENABLE; else @@ -2574,7 +2610,11 @@ hns3vf_reinit_dev(struct hns3_adapter *hns) if (hw->reset.level == HNS3_VF_FULL_RESET) { rte_intr_disable(&pci_dev->intr_handle); - hns3vf_set_bus_master(pci_dev, true); + ret = hns3vf_set_bus_master(pci_dev, true); + if (ret) { + hns3_err(hw, "failed to set pci bus, ret = %d", ret); + return ret; + } } /* Firmware command initialize */ From patchwork Tue Sep 29 12:01:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei Hu (Xavier)" X-Patchwork-Id: 79192 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A06A3A04C0; Tue, 29 Sep 2020 14:03:22 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 882C71DA81; Tue, 29 Sep 2020 14:01:39 +0200 (CEST) Received: from incedge.chinasoftinc.com (unknown [114.113.233.8]) by dpdk.org (Postfix) with ESMTP id 011D21DA41 for ; Tue, 29 Sep 2020 14:01:28 +0200 (CEST) X-ASG-Debug-ID: 1601380887-149d11049b2967e0001-TfluYd Received: from mail.chinasoftinc.com (inccas001.ito.icss [10.168.0.51]) by incedge.chinasoftinc.com with ESMTP id eKKI2liDLrF80wtM (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 29 Sep 2020 20:01:27 +0800 (CST) X-Barracuda-Envelope-From: huwei013@chinasoftinc.com X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.51 X-ASG-Whitelist: Client Received: from localhost.localdomain (120.133.139.157) by INCCAS001.ito.icss (10.168.0.60) with Microsoft SMTP Server id 14.3.487.0; Tue, 29 Sep 2020 20:01:26 +0800 From: "Wei Hu (Xavier)" X-Barracuda-RBL-Trusted-Forwarder: 10.168.0.60 To: CC: Date: Tue, 29 Sep 2020 20:01:17 +0800 X-ASG-Orig-Subj: [PATCH v2 9/9] net/hns3: remove redundant return value assignments Message-ID: <20200929120117.50394-10-huwei013@chinasoftinc.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20200929120117.50394-1-huwei013@chinasoftinc.com> References: <20200929110945.70761-1-huwei013@chinasoftinc.com> <20200929120117.50394-1-huwei013@chinasoftinc.com> MIME-Version: 1.0 X-Originating-IP: [120.133.139.157] X-Barracuda-Connect: inccas001.ito.icss[10.168.0.51] X-Barracuda-Start-Time: 1601380887 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://incspam.chinasofti.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at chinasoftinc.com X-Barracuda-Scan-Msg-Size: 828 Subject: [dpdk-dev] [PATCH v2 9/9] net/hns3: remove redundant return value assignments X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Hongbo Zheng When an error occurs in the reset process, -EIO is returned. The assignment of ret here is redundant, so deleted it. Signed-off-by: Hongbo Zheng Signed-off-by: Wei Hu (Xavier) --- drivers/net/hns3/hns3_intr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/hns3/hns3_intr.c b/drivers/net/hns3/hns3_intr.c index dfd7371..2565688 100644 --- a/drivers/net/hns3/hns3_intr.c +++ b/drivers/net/hns3/hns3_intr.c @@ -1888,7 +1888,6 @@ hns3_reset_process(struct hns3_adapter *hns, enum hns3_reset_level new_level) if (hw->reset.wait_data->result == HNS3_WAIT_REQUEST) rte_eal_alarm_cancel(hns3_wait_callback, hw->reset.wait_data); - ret = -EBUSY; goto err; }