#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
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 */
{
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;
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
#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
{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
{
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) {
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);
* 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;
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,
}
/* 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;
}
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;
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;
}
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;
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]);
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 */
};
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);