u8 rsv[23];
 };
 
-struct hclge_promisc_param {
-       u8 vf_id;
-       u8 enable;
-};
+/* for DEVICE_VERSION_V1/2, reference to promisc cmd byte8 */
+#define HCLGE_PROMISC_EN_UC    1
+#define HCLGE_PROMISC_EN_MC    2
+#define HCLGE_PROMISC_EN_BC    3
+#define HCLGE_PROMISC_TX_EN    4
+#define HCLGE_PROMISC_RX_EN    5
+
+/* for DEVICE_VERSION_V3, reference to promisc cmd byte10 */
+#define HCLGE_PROMISC_UC_RX_EN 2
+#define HCLGE_PROMISC_MC_RX_EN 3
+#define HCLGE_PROMISC_BC_RX_EN 4
+#define HCLGE_PROMISC_UC_TX_EN 5
+#define HCLGE_PROMISC_MC_TX_EN 6
+#define HCLGE_PROMISC_BC_TX_EN 7
 
-#define HCLGE_PROMISC_TX_EN_B  BIT(4)
-#define HCLGE_PROMISC_RX_EN_B  BIT(5)
-#define HCLGE_PROMISC_EN_B     1
-#define HCLGE_PROMISC_EN_ALL   0x7
-#define HCLGE_PROMISC_EN_UC    0x1
-#define HCLGE_PROMISC_EN_MC    0x2
-#define HCLGE_PROMISC_EN_BC    0x4
 struct hclge_promisc_cfg_cmd {
-       u8 flag;
+       u8 promisc;
        u8 vf_id;
-       __le16 rsv0;
-       u8 rsv1[20];
+       u8 extend_promisc;
+       u8 rsv0[21];
 };
 
 enum hclge_promisc_type {
 
        return ret;
 }
 
-static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev,
-                                     struct hclge_promisc_param *param)
+static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, u8 vf_id,
+                                     bool en_uc, bool en_mc, bool en_bc)
 {
        struct hclge_promisc_cfg_cmd *req;
        struct hclge_desc desc;
+       u8 promisc_cfg = 0;
        int ret;
 
        hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PROMISC_MODE, false);
 
        req = (struct hclge_promisc_cfg_cmd *)desc.data;
-       req->vf_id = param->vf_id;
+       req->vf_id = vf_id;
 
-       /* HCLGE_PROMISC_TX_EN_B and HCLGE_PROMISC_RX_EN_B are not supported on
-        * pdev revision(0x20), new revision support them. The
-        * value of this two fields will not return error when driver
-        * send command to fireware in revision(0x20).
-        */
-       req->flag = (param->enable << HCLGE_PROMISC_EN_B) |
-               HCLGE_PROMISC_TX_EN_B | HCLGE_PROMISC_RX_EN_B;
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_RX_EN, en_uc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_RX_EN, en_mc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_RX_EN, en_bc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_UC_TX_EN, en_uc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_MC_TX_EN, en_mc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_BC_TX_EN, en_bc ? 1 : 0);
+       req->extend_promisc = promisc_cfg;
+
+       /* to be compatible with DEVICE_VERSION_V1/2 */
+       promisc_cfg = 0;
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_UC, en_uc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_MC, en_mc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_EN_BC, en_bc ? 1 : 0);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_TX_EN, 1);
+       hnae3_set_bit(promisc_cfg, HCLGE_PROMISC_RX_EN, 1);
+       req->promisc = promisc_cfg;
 
        ret = hclge_cmd_send(&hdev->hw, &desc, 1);
        if (ret)
                dev_err(&hdev->pdev->dev,
-                       "failed to set vport %d promisc mode, ret = %d.\n",
-                       param->vf_id, ret);
+                       "failed to set vport %u promisc mode, ret = %d.\n",
+                       vf_id, ret);
 
        return ret;
 }
 
-static void hclge_promisc_param_init(struct hclge_promisc_param *param,
-                                    bool en_uc, bool en_mc, bool en_bc,
-                                    int vport_id)
-{
-       if (!param)
-               return;
-
-       memset(param, 0, sizeof(struct hclge_promisc_param));
-       if (en_uc)
-               param->enable = HCLGE_PROMISC_EN_UC;
-       if (en_mc)
-               param->enable |= HCLGE_PROMISC_EN_MC;
-       if (en_bc)
-               param->enable |= HCLGE_PROMISC_EN_BC;
-       param->vf_id = vport_id;
-}
-
 int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc,
                                 bool en_mc_pmc, bool en_bc_pmc)
 {
-       struct hclge_dev *hdev = vport->back;
-       struct hclge_promisc_param param;
-
-       hclge_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, en_bc_pmc,
-                                vport->vport_id);
-       return hclge_cmd_set_promisc_mode(hdev, ¶m);
+       return hclge_cmd_set_promisc_mode(vport->back, vport->vport_id,
+                                         en_uc_pmc, en_mc_pmc, en_bc_pmc);
 }
 
 static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,