diff --git a/doc/guides/nics/hns3.rst b/doc/guides/nics/hns3.rst
index 3366562..9592551 100644
--- a/doc/guides/nics/hns3.rst
+++ b/doc/guides/nics/hns3.rst
@@ -84,6 +84,15 @@ Runtime Config Options
   be first checked, if meets, use the ``vec``. Then, ``simple``, at last
   ``common``.
 
+- ``dev_caps_mask`` (default ``0``)
+
+  Used to mask the capability which queried from firmware.
+  This args take hexadecimal bitmask where each bit represents whether mask
+  corresponding capability. eg. If the capability is 0xFFFF queried from
+  firmware, and the args value is 0xF which means the bit0~bit3 should be
+  masked off, then the capability will be 0xFFF0.
+  Its main purpose is to debug and avoid problems.
+
 Driver compilation and testing
 ------------------------------
 
diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c
index 75d5299..04e5786 100644
--- a/drivers/net/hns3/hns3_cmd.c
+++ b/drivers/net/hns3/hns3_cmd.c
@@ -411,6 +411,68 @@ hns3_cmd_send(struct hns3_hw *hw, struct hns3_cmd_desc *desc, int num)
 	return retval;
 }
 
+static const char *
+hns3_get_caps_name(uint32_t caps_id)
+{
+	const struct {
+		enum HNS3_CAPS_BITS caps;
+		const char *name;
+	} dev_caps[] = {
+		{ HNS3_CAPS_UDP_GSO_B,         "udp_gso"         },
+		{ HNS3_CAPS_ATR_B,             "atr"             },
+		{ HNS3_CAPS_FD_QUEUE_REGION_B, "fd_queue_region" },
+		{ HNS3_CAPS_PTP_B,             "ptp"             },
+		{ HNS3_CAPS_INT_QL_B,          "int_ql"          },
+		{ HNS3_CAPS_SIMPLE_BD_B,       "simple_bd"       },
+		{ HNS3_CAPS_TX_PUSH_B,         "tx_push"         },
+		{ HNS3_CAPS_PHY_IMP_B,         "phy_imp"         },
+		{ HNS3_CAPS_TQP_TXRX_INDEP_B,  "tqp_txrx_indep"  },
+		{ HNS3_CAPS_HW_PAD_B,          "hw_pad"          },
+		{ HNS3_CAPS_STASH_B,           "stash"           },
+		{ HNS3_CAPS_UDP_TUNNEL_CSUM_B, "udp_tunnel_csum" },
+		{ HNS3_CAPS_RAS_IMP_B,         "ras_imp"         },
+		{ HNS3_CAPS_FEC_B,             "fec"             },
+		{ HNS3_CAPS_PAUSE_B,           "pause"           },
+		{ HNS3_CAPS_RXD_ADV_LAYOUT_B,  "rxd_adv_layout"  }
+	};
+	uint32_t i;
+
+	for (i = 0; i < RTE_DIM(dev_caps); i++) {
+		if (dev_caps[i].caps == caps_id)
+			return dev_caps[i].name;
+	}
+
+	return "unknown";
+}
+
+static void
+hns3_mask_capability(struct hns3_hw *hw,
+		     struct hns3_query_version_cmd *cmd)
+{
+#define MAX_CAPS_BIT	64
+
+	struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw);
+	uint64_t caps_org, caps_new, caps_masked;
+	uint32_t i;
+
+	if (hns->dev_caps_mask == 0)
+		return;
+
+	memcpy(&caps_org, &cmd->caps[0], sizeof(caps_org));
+	caps_org = rte_le_to_cpu_64(caps_org);
+	caps_new = caps_org ^ (caps_org & hns->dev_caps_mask);
+	caps_masked = caps_org ^ caps_new;
+	caps_new = rte_cpu_to_le_64(caps_new);
+	memcpy(&cmd->caps[0], &caps_new, sizeof(caps_new));
+
+	for (i = 0; i < MAX_CAPS_BIT; i++) {
+		if (!(caps_masked & BIT_ULL(i)))
+			continue;
+		hns3_info(hw, "mask capabiliy: id-%u, name-%s.",
+			  i, hns3_get_caps_name(i));
+	}
+}
+
 static void
 hns3_parse_capability(struct hns3_hw *hw,
 		      struct hns3_query_version_cmd *cmd)
@@ -478,6 +540,11 @@ hns3_cmd_query_firmware_version_and_capability(struct hns3_hw *hw)
 		return ret;
 
 	hw->fw_version = rte_le_to_cpu_32(resp->firmware);
+	/*
+	 * Make sure mask the capability before parse capability because it
+	 * may overwrite resp's data.
+	 */
+	hns3_mask_capability(hw, resp);
 	hns3_parse_capability(hw, resp);
 
 	return 0;
diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c
index 1832d26..8601cf0 100644
--- a/drivers/net/hns3/hns3_ethdev.c
+++ b/drivers/net/hns3/hns3_ethdev.c
@@ -7208,6 +7208,19 @@ hns3_get_io_hint_func_name(uint32_t hint)
 	}
 }
 
+static int
+hns3_parse_dev_caps_mask(const char *key, const char *value, void *extra_args)
+{
+	uint64_t val;
+
+	RTE_SET_USED(key);
+
+	val = strtoull(value, NULL, 16);
+	*(uint64_t *)extra_args = val;
+
+	return 0;
+}
+
 void
 hns3_parse_devargs(struct rte_eth_dev *dev)
 {
@@ -7215,6 +7228,7 @@ hns3_parse_devargs(struct rte_eth_dev *dev)
 	uint32_t rx_func_hint = HNS3_IO_FUNC_HINT_NONE;
 	uint32_t tx_func_hint = HNS3_IO_FUNC_HINT_NONE;
 	struct hns3_hw *hw = &hns->hw;
+	uint64_t dev_caps_mask = 0;
 	struct rte_kvargs *kvlist;
 
 	if (dev->device->devargs == NULL)
@@ -7228,6 +7242,8 @@ hns3_parse_devargs(struct rte_eth_dev *dev)
 			   &hns3_parse_io_hint_func, &rx_func_hint);
 	rte_kvargs_process(kvlist, HNS3_DEVARG_TX_FUNC_HINT,
 			   &hns3_parse_io_hint_func, &tx_func_hint);
+	rte_kvargs_process(kvlist, HNS3_DEVARG_DEV_CAPS_MASK,
+			   &hns3_parse_dev_caps_mask, &dev_caps_mask);
 	rte_kvargs_free(kvlist);
 
 	if (rx_func_hint != HNS3_IO_FUNC_HINT_NONE)
@@ -7238,6 +7254,11 @@ hns3_parse_devargs(struct rte_eth_dev *dev)
 		hns3_warn(hw, "parsed %s = %s.", HNS3_DEVARG_TX_FUNC_HINT,
 			  hns3_get_io_hint_func_name(tx_func_hint));
 	hns->tx_func_hint = tx_func_hint;
+
+	if (dev_caps_mask != 0)
+		hns3_warn(hw, "parsed %s = 0x%" PRIx64 ".",
+			  HNS3_DEVARG_DEV_CAPS_MASK, dev_caps_mask);
+	hns->dev_caps_mask = dev_caps_mask;
 }
 
 static const struct eth_dev_ops hns3_eth_dev_ops = {
@@ -7505,6 +7526,7 @@ RTE_PMD_REGISTER_PCI_TABLE(net_hns3, pci_id_hns3_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_hns3, "* igb_uio | vfio-pci");
 RTE_PMD_REGISTER_PARAM_STRING(net_hns3,
 		HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common "
-		HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common ");
+		HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "
+		HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> ");
 RTE_LOG_REGISTER(hns3_logtype_init, pmd.net.hns3.init, NOTICE);
 RTE_LOG_REGISTER(hns3_logtype_driver, pmd.net.hns3.driver, NOTICE);
diff --git a/drivers/net/hns3/hns3_ethdev.h b/drivers/net/hns3/hns3_ethdev.h
index 7b7d359..07b313c 100644
--- a/drivers/net/hns3/hns3_ethdev.h
+++ b/drivers/net/hns3/hns3_ethdev.h
@@ -822,6 +822,8 @@ struct hns3_adapter {
 	uint32_t rx_func_hint;
 	uint32_t tx_func_hint;
 
+	uint64_t dev_caps_mask;
+
 	struct hns3_ptype_table ptype_tbl __rte_cache_min_aligned;
 };
 
@@ -836,6 +838,8 @@ enum {
 #define HNS3_DEVARG_RX_FUNC_HINT	"rx_func_hint"
 #define HNS3_DEVARG_TX_FUNC_HINT	"tx_func_hint"
 
+#define HNS3_DEVARG_DEV_CAPS_MASK	"dev_caps_mask"
+
 #define HNS3_DEV_SUPPORT_DCB_B			0x0
 #define HNS3_DEV_SUPPORT_COPPER_B		0x1
 #define HNS3_DEV_SUPPORT_UDP_GSO_B		0x2
diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c
index 5770c47..273a938 100644
--- a/drivers/net/hns3/hns3_ethdev_vf.c
+++ b/drivers/net/hns3/hns3_ethdev_vf.c
@@ -3074,4 +3074,5 @@ RTE_PMD_REGISTER_PCI_TABLE(net_hns3_vf, pci_id_hns3vf_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_hns3_vf, "* igb_uio | vfio-pci");
 RTE_PMD_REGISTER_PARAM_STRING(net_hns3_vf,
 		HNS3_DEVARG_RX_FUNC_HINT "=vec|sve|simple|common "
-		HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common ");
+		HNS3_DEVARG_TX_FUNC_HINT "=vec|sve|simple|common "
+		HNS3_DEVARG_DEV_CAPS_MASK "=<1-65535> ");
