Commit cce4abf9 authored by Chiqijun's avatar Chiqijun Committed by Yang Yingliang
Browse files

net/hinic: Fix the firmware compatibility bug in the MAC reuse scenario



driver inclusion
category: bugfix
bugzilla: 4472

-----------------------------------------------------------------------

2.3.0.1 and later drivers and firmware add MAC reuse feature, when the
driver is compatible with firmware version 2.3.0.0 and before, if the ip
link command is used to configure the MAC and VLAN for the VF, it will
cause the VF network anomaly.

To solve this problem, the driver obtains the function capability from
the firmware when loading, and determines whether to support MAC reuse
for different processing.

Signed-off-by: default avatarChiqijun <chiqijun@huawei.com>
Reviewed-by: default avatarZengweiliang <zengweiliang.zengweiliang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 9598e34f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -319,6 +319,7 @@ struct hinic_hwdev {
	struct hinic_board_info board_info;
#define MGMT_VERSION_MAX_LEN	32
	u8	mgmt_ver[MGMT_VERSION_MAX_LEN];
	u64	fw_support_func_flag;
};

int hinic_init_comm_ch(struct hinic_hwdev *hwdev);
+11 −0
Original line number Diff line number Diff line
@@ -690,6 +690,15 @@ struct hinic_port_rt_cmd {
	u8	rsvd1[6];
};

struct fw_support_func {
	u8	status;
	u8	version;
	u8	rsvd0[6];

	u64	flag;
	u64	rsvd;
};

struct hinic_vf_dcb_state {
	u8	status;
	u8	version;
@@ -741,6 +750,8 @@ int hinic_init_function_table(void *hwdev, u16 rx_buf_sz);

int hinic_get_base_qpn(void *hwdev, u16 *global_qpn);

int hinic_get_fw_support_func(void *hwdev);

int hinic_vf_func_init(struct hinic_hwdev *hwdev);

void hinic_vf_func_free(struct hinic_hwdev *hwdev);
+42 −3
Original line number Diff line number Diff line
@@ -201,6 +201,34 @@ int hinic_get_base_qpn(void *hwdev, u16 *global_qpn)
	return 0;
}

int hinic_get_fw_support_func(void *hwdev)
{
	struct fw_support_func support_flag = {0};
	struct hinic_hwdev *dev = hwdev;
	u16 out_size = sizeof(support_flag);
	int err;

	if (!hwdev)
		return -EINVAL;

	err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
				     HINIC_PORT_CMD_GET_FW_SUPPORT_FLAG,
				     &support_flag, sizeof(support_flag),
				     &support_flag, &out_size, 0);
	if (support_flag.status == HINIC_MGMT_CMD_UNSUPPORTED) {
		nic_info(dev->dev_hdl, "Current firmware doesn't support to get function capability\n");
		support_flag.flag = 0;
	} else if (support_flag.status || err || !out_size) {
		nic_err(dev->dev_hdl, "Failed to get function capability, err: %d, status: 0x%x, out size: 0x%x\n",
			err, support_flag.status, out_size);
		return -EFAULT;
	}

	dev->fw_support_func_flag = support_flag.flag;

	return 0;
}

#define HINIC_ADD_VLAN_IN_MAC	0x8000
#define HINIC_VLAN_ID_MASK	0x7FFF

@@ -352,6 +380,11 @@ int hinic_update_mac_vlan(void *hwdev, u16 old_vlan, u16 new_vlan, int vf_id)
	if (!vf_info->pf_set_mac)
		return 0;

	if (!FW_SUPPORT_MAC_REUSE_FUNC(dev)) {
		nic_info(dev->dev_hdl, "Current firmware doesn't support mac reuse\n");
		return 0;
	}

	func_id = hinic_glb_pf_vf_offset(dev) + (u16)vf_id;
	vlan_id = old_vlan;
	if (vlan_id)
@@ -2562,9 +2595,14 @@ static int hinic_init_vf_config(struct hinic_hwdev *hwdev, u16 vf_id)
	vf_info = hwdev->nic_io->vf_infos + HW_VF_ID_TO_OS(vf_id);
	if (vf_info->pf_set_mac) {
		func_id = hinic_glb_pf_vf_offset(hwdev) + vf_id;
		if (FW_SUPPORT_MAC_REUSE_FUNC(hwdev)) {
			vlan_id = vf_info->pf_vlan;
			if (vlan_id)
				vlan_id |= HINIC_ADD_VLAN_IN_MAC;
		} else {
			vlan_id = 0;
		}

		err = hinic_set_mac(hwdev, vf_info->vf_mac_addr, vlan_id,
				    func_id);
		if (err) {
@@ -4065,3 +4103,4 @@ int hinic_get_sfp_type(void *hwdev, u8 *data0, u8 *data1)

	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@
#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)

#define FW_SUPPORT_MAC_REUSE		0x1
#define FW_SUPPORT_MAC_REUSE_FUNC(hwdev)	\
	((hwdev)->fw_support_func_flag & FW_SUPPORT_MAC_REUSE)

#define HINIC_VLAN_PRIORITY_SHIFT	13

#define HINIC_RSS_INDIR_SIZE		256
+9 −1
Original line number Diff line number Diff line
@@ -831,9 +831,17 @@ int hinic_init_nic_hwdev(void *hwdev, u16 rx_buff_len)
	}

	/* VFs don't set port routine command report */
	if (hinic_func_type(dev) != TYPE_VF)
	if (hinic_func_type(dev) != TYPE_VF) {
		/* Get the fw support mac reuse flag */
		err = hinic_get_fw_support_func(hwdev);
		if (err) {
			nic_err(dev->dev_hdl, "Failed to get function capability\n");
			return err;
		}

		/* Inform mgmt to send sfp's information to driver */
		err = hinic_set_port_routine_cmd_report(hwdev, true);
	}

	return err;
}
Loading