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);
