drivers/net/ethernet/huawei/hinic/hinic_sriov.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/huawei/hinic/hinic_sriov.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/huawei/hinic/hinic_sriov.c
Extension
.c
Size
39360 bytes
Lines
1365
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			dev_err(&hwdev->func_to_io.hwif->pdev->dev, "Failed to set VF %d MAC\n",
				HW_VF_ID_TO_OS(vf_id));
			return err;
		}
	}

	if (hinic_vf_info_vlanprio(hwdev, vf_id)) {
		err = hinic_set_vf_vlan(hwdev, true, vf_info->pf_vlan,
					vf_info->pf_qos, vf_id);
		if (err) {
			dev_err(&hwdev->hwif->pdev->dev, "Failed to add VF %d VLAN_QOS\n",
				HW_VF_ID_TO_OS(vf_id));
			return err;
		}
	}

	if (vf_info->max_rate) {
		err = hinic_set_vf_tx_rate(hwdev, vf_id, vf_info->max_rate,
					   vf_info->min_rate);
		if (err) {
			dev_err(&hwdev->hwif->pdev->dev, "Failed to set VF %d max rate: %d, min rate: %d\n",
				HW_VF_ID_TO_OS(vf_id), vf_info->max_rate,
				vf_info->min_rate);
			return err;
		}
	}

	return 0;
}

static int hinic_register_vf_msg_handler(void *hwdev, u16 vf_id,
					 void *buf_in, u16 in_size,
					 void *buf_out, u16 *out_size)
{
	struct hinic_register_vf *register_info = buf_out;
	struct hinic_hwdev *hw_dev = hwdev;
	struct hinic_func_to_io *nic_io;
	int err;

	nic_io = &hw_dev->func_to_io;
	if (vf_id > nic_io->max_vfs) {
		dev_err(&hw_dev->hwif->pdev->dev, "Register VF id %d exceed limit[0-%d]\n",
			HW_VF_ID_TO_OS(vf_id), HW_VF_ID_TO_OS(nic_io->max_vfs));
		register_info->status = EFAULT;
		return -EFAULT;
	}

	*out_size = sizeof(*register_info);
	err = hinic_init_vf_config(hw_dev, vf_id);
	if (err) {
		register_info->status = EFAULT;
		return err;
	}

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = true;

	return 0;
}

static int hinic_unregister_vf_msg_handler(void *hwdev, u16 vf_id,
					   void *buf_in, u16 in_size,
					   void *buf_out, u16 *out_size)
{
	struct hinic_hwdev *hw_dev = hwdev;
	struct hinic_func_to_io *nic_io;

	nic_io = &hw_dev->func_to_io;
	*out_size = 0;
	if (vf_id > nic_io->max_vfs)
		return 0;

	nic_io->vf_infos[HW_VF_ID_TO_OS(vf_id)].registered = false;

	return 0;
}

static int hinic_change_vf_mtu_msg_handler(void *hwdev, u16 vf_id,
					   void *buf_in, u16 in_size,
					   void *buf_out, u16 *out_size)
{
	struct hinic_hwdev *hw_dev = hwdev;
	int err;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_CHANGE_MTU, buf_in,
				 in_size, buf_out, out_size);
	if (err) {
		dev_err(&hw_dev->hwif->pdev->dev, "Failed to set VF %u mtu\n",
			vf_id);
		return err;

Annotation

Implementation Notes