drivers/net/ethernet/sfc/efx_devlink.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/sfc/efx_devlink.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/sfc/efx_devlink.c
Extension
.c
Size
20590 bytes
Lines
747
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

struct efx_devlink {
	struct efx_nic *efx;
};

#ifdef CONFIG_SFC_SRIOV

static int efx_devlink_port_addr_get(struct devlink_port *port, u8 *hw_addr,
				     int *hw_addr_len,
				     struct netlink_ext_ack *extack)
{
	struct efx_devlink *devlink = devlink_priv(port->devlink);
	struct mae_mport_desc *mport_desc;
	efx_qword_t pciefn;
	u32 client_id;
	int rc = 0;

	mport_desc = container_of(port, struct mae_mport_desc, dl_port);

	if (!ef100_mport_on_local_intf(devlink->efx, mport_desc)) {
		rc = -EINVAL;
		NL_SET_ERR_MSG_FMT(extack,
				   "Port not on local interface (mport: %u)",
				   mport_desc->mport_id);
		goto out;
	}

	if (ef100_mport_is_vf(mport_desc))
		EFX_POPULATE_QWORD_3(pciefn,
				     PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
				     PCIE_FUNCTION_VF, mport_desc->vf_idx,
				     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
	else
		EFX_POPULATE_QWORD_3(pciefn,
				     PCIE_FUNCTION_PF, mport_desc->pf_idx,
				     PCIE_FUNCTION_VF, PCIE_FUNCTION_VF_NULL,
				     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);

	rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
	if (rc) {
		NL_SET_ERR_MSG_FMT(extack,
				   "No internal client_ID for port (mport: %u)",
				   mport_desc->mport_id);
		goto out;
	}

	rc = ef100_get_mac_address(devlink->efx, hw_addr, client_id, true);
	if (rc != 0)
		NL_SET_ERR_MSG_FMT(extack,
				   "No available MAC for port (mport: %u)",
				   mport_desc->mport_id);
out:
	*hw_addr_len = ETH_ALEN;
	return rc;
}

static int efx_devlink_port_addr_set(struct devlink_port *port,
				     const u8 *hw_addr, int hw_addr_len,
				     struct netlink_ext_ack *extack)
{
	MCDI_DECLARE_BUF(inbuf, MC_CMD_SET_CLIENT_MAC_ADDRESSES_IN_LEN(1));
	struct efx_devlink *devlink = devlink_priv(port->devlink);
	struct mae_mport_desc *mport_desc;
	efx_qword_t pciefn;
	u32 client_id;
	int rc;

	mport_desc = container_of(port, struct mae_mport_desc, dl_port);

	if (!ef100_mport_is_vf(mport_desc)) {
		NL_SET_ERR_MSG_FMT(extack,
				   "port mac change not allowed (mport: %u)",
				   mport_desc->mport_id);
		return -EPERM;
	}

	EFX_POPULATE_QWORD_3(pciefn,
			     PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
			     PCIE_FUNCTION_VF, mport_desc->vf_idx,
			     PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);

	rc = efx_ef100_lookup_client_id(devlink->efx, pciefn, &client_id);
	if (rc) {
		NL_SET_ERR_MSG_FMT(extack,
				   "No internal client_ID for port (mport: %u)",
				   mport_desc->mport_id);
		return rc;
	}

	MCDI_SET_DWORD(inbuf, SET_CLIENT_MAC_ADDRESSES_IN_CLIENT_HANDLE,
		       client_id);

Annotation

Implementation Notes