net: hns3: add compatible handling for MAC VLAN switch parameter configuration
authorGuangbin Huang <huangguangbin2@huawei.com>
Thu, 14 Nov 2019 02:32:39 +0000 (10:32 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Nov 2019 02:06:34 +0000 (18:06 -0800)
Previously, hns3 driver just directly send specific setting bit
and mask bits of MAC VLAN switch parameter to the firmware, it
can not be compatible with the old firmware, because the old one
ignores mask bits and covers all bits with new setting bits.
So when running with old firmware, the communication between PF
and VF will fail after resetting or configuring spoof check, since
they will do the MAC VLAN switch parameter configuration.

This patch fixes this problem by reading switch parameter firstly,
then just modifies the corresponding bit and sends it to firmware.

Fixes: dd2956eab104 ("net: hns3: not allow SSU loopback while execute ethtool -t dev")
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

index 16f7d0e15b4f39285d9ee8b8363758f038858b56..c052bb33b3d34614ff0976979bbbee6a296a5c24 100644 (file)
@@ -6263,11 +6263,23 @@ static int hclge_config_switch_param(struct hclge_dev *hdev, int vfid,
 
        func_id = hclge_get_port_number(HOST_PORT, 0, vfid, 0);
        req = (struct hclge_mac_vlan_switch_cmd *)desc.data;
+
+       /* read current config parameter */
        hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_SWITCH_PARAM,
-                                  false);
+                                  true);
        req->roce_sel = HCLGE_MAC_VLAN_NIC_SEL;
        req->func_id = cpu_to_le32(func_id);
-       req->switch_param = switch_param;
+
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "read mac vlan switch parameter fail, ret = %d\n", ret);
+               return ret;
+       }
+
+       /* modify and write new config parameter */
+       hclge_cmd_reuse_desc(&desc, false);
+       req->switch_param = (req->switch_param & param_mask) | switch_param;
        req->param_mask = param_mask;
 
        ret = hclge_cmd_send(&hdev->hw, &desc, 1);