From: Chiqijun <chiqijun(a)huawei.com>
driver inclusion
category: bugfix
bugzilla: 4472
-----------------------------------------------------------------------
When using the ip link command to configure the MAC for the VF in the
PF, the status 4 will be returned when the MAC is set on the VF; when
the PF driver receives the status 4 returned by the firmwre, the MAC
setting failed and an error should be reported.
Signed-off-by: Chiqijun <chiqijun(a)huawei.com>
Reviewed-by: Wangxiaoyun <cloud.wangxiaoyun(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
---
.../net/ethernet/huawei/hinic/hinic_main.c | 7 +++-
.../net/ethernet/huawei/hinic/hinic_nic_cfg.c | 41 ++++++++++++-------
2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
index b5d0bdadf509..cf7b6ceef060 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
@@ -1305,8 +1305,11 @@ static int hinic_set_mac_addr(struct net_device *netdev, void *addr)
err = hinic_update_mac(nic_dev->hwdev, netdev->dev_addr, saddr->sa_data,
0, func_id);
- if (err)
- return err;
+ if (err) {
+ nicif_err(nic_dev, drv, netdev, "Failed to update mac, err: %d\n",
+ err);
+ return err == HINIC_PF_SET_VF_ALREADY ? -EPERM : err;
+ }
memcpy(netdev->dev_addr, saddr->sa_data, ETH_ALEN);
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c
index a42dea0ad707..2b349e17260b 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c
@@ -231,6 +231,23 @@ int hinic_get_fw_support_func(void *hwdev)
#define HINIC_ADD_VLAN_IN_MAC 0x8000
#define HINIC_VLAN_ID_MASK 0x7FFF
+#define PF_SET_VF_MAC(hwdev, status) \
+ (HINIC_FUNC_TYPE(hwdev) == TYPE_VF && \
+ (status) == HINIC_PF_SET_VF_ALREADY)
+
+static int hinic_check_mac_status(struct hinic_hwdev *hwdev, u8 status,
+ u16 vlan_id)
+{
+ if ((status && status != HINIC_MGMT_STATUS_EXIST) ||
+ (vlan_id & CHECK_IPSU_15BIT && status == HINIC_MGMT_STATUS_EXIST)) {
+ if (PF_SET_VF_MAC(hwdev, status))
+ return 0;
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
int hinic_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
{
@@ -255,17 +272,14 @@ int hinic_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_MAC, &mac_info,
sizeof(mac_info), &mac_info, &out_size);
if (err || !out_size ||
- (mac_info.status && mac_info.status != HINIC_MGMT_STATUS_EXIST &&
- mac_info.status != HINIC_PF_SET_VF_ALREADY) ||
- (mac_info.vlan_id & CHECK_IPSU_15BIT &&
- mac_info.status == HINIC_MGMT_STATUS_EXIST)) {
+ hinic_check_mac_status(hwdev, mac_info.status, mac_info.vlan_id)) {
nic_err(nic_hwdev->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.status, out_size);
- return -EINVAL;
+ return -EIO;
}
- if (mac_info.status == HINIC_PF_SET_VF_ALREADY) {
+ if (PF_SET_VF_MAC(nic_hwdev, mac_info.status)) {
nic_warn(nic_hwdev->dev_hdl, "PF has already set VF mac, Ignore set operation\n");
return HINIC_PF_SET_VF_ALREADY;
}
@@ -302,13 +316,13 @@ int hinic_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_DEL_MAC, &mac_info,
sizeof(mac_info), &mac_info, &out_size);
if (err || !out_size ||
- (mac_info.status && mac_info.status != HINIC_PF_SET_VF_ALREADY)) {
+ (mac_info.status && !PF_SET_VF_MAC(nic_hwdev, mac_info.status))) {
nic_err(nic_hwdev->dev_hdl,
"Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.status, out_size);
- return -EINVAL;
+ return -EIO;
}
- if (mac_info.status == HINIC_PF_SET_VF_ALREADY) {
+ if (PF_SET_VF_MAC(nic_hwdev, mac_info.status)) {
nic_warn(nic_hwdev->dev_hdl, "PF has already set VF mac, Ignore delete operation\n");
return HINIC_PF_SET_VF_ALREADY;
}
@@ -343,17 +357,14 @@ int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
&mac_info, sizeof(mac_info),
&mac_info, &out_size);
if (err || !out_size ||
- (mac_info.status && mac_info.status != HINIC_MGMT_STATUS_EXIST &&
- mac_info.status != HINIC_PF_SET_VF_ALREADY) ||
- (mac_info.vlan_id & CHECK_IPSU_15BIT &&
- mac_info.status == HINIC_MGMT_STATUS_EXIST)) {
+ hinic_check_mac_status(hwdev, mac_info.status, mac_info.vlan_id)) {
nic_err(nic_hwdev->dev_hdl,
"Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x\n",
err, mac_info.status, out_size);
- return -EINVAL;
+ return -EIO;
}
- if (mac_info.status == HINIC_PF_SET_VF_ALREADY) {
+ if (PF_SET_VF_MAC(nic_hwdev, mac_info.status)) {
nic_warn(nic_hwdev->dev_hdl, "PF has already set VF MAC. Ignore update operation\n");
return HINIC_PF_SET_VF_ALREADY;
}
--
2.25.1