drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
Extension
.c
Size
16710 bytes
Lines
673
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct net_device_ops lio_vf_rep_ndev_ops = {
	.ndo_open = lio_vf_rep_open,
	.ndo_stop = lio_vf_rep_stop,
	.ndo_start_xmit = lio_vf_rep_pkt_xmit,
	.ndo_tx_timeout = lio_vf_rep_tx_timeout,
	.ndo_get_phys_port_name = lio_vf_rep_phys_port_name,
	.ndo_get_stats64 = lio_vf_rep_get_stats64,
	.ndo_change_mtu = lio_vf_rep_change_mtu,
	.ndo_get_port_parent_id = lio_vf_get_port_parent_id,
};

static int
lio_vf_rep_send_soft_command(struct octeon_device *oct,
			     void *req, int req_size,
			     void *resp, int resp_size)
{
	int tot_resp_size = sizeof(struct lio_vf_rep_resp) + resp_size;
	struct octeon_soft_command *sc = NULL;
	struct lio_vf_rep_resp *rep_resp;
	void *sc_req;
	int err;

	sc = (struct octeon_soft_command *)
		octeon_alloc_soft_command(oct, req_size,
					  tot_resp_size, 0);
	if (!sc)
		return -ENOMEM;

	init_completion(&sc->complete);
	sc->sc_status = OCTEON_REQUEST_PENDING;

	sc_req = (struct lio_vf_rep_req *)sc->virtdptr;
	memcpy(sc_req, req, req_size);

	rep_resp = (struct lio_vf_rep_resp *)sc->virtrptr;
	memset(rep_resp, 0, tot_resp_size);
	WRITE_ONCE(rep_resp->status, 1);

	sc->iq_no = 0;
	octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
				    OPCODE_NIC_VF_REP_CMD, 0, 0, 0);

	err = octeon_send_soft_command(oct, sc);
	if (err == IQ_SEND_FAILED)
		goto free_buff;

	err = wait_for_sc_completion_timeout(oct, sc, 0);
	if (err)
		return err;

	err = READ_ONCE(rep_resp->status) ? -EBUSY : 0;
	if (err)
		dev_err(&oct->pci_dev->dev, "VF rep send config failed\n");
	else if (resp)
		memcpy(resp, (rep_resp + 1), resp_size);

	WRITE_ONCE(sc->caller_is_done, true);
	return err;

free_buff:
	octeon_free_soft_command(oct, sc);

	return err;
}

static int
lio_vf_rep_open(struct net_device *ndev)
{
	struct lio_vf_rep_desc *vf_rep = netdev_priv(ndev);
	struct lio_vf_rep_req rep_cfg;
	struct octeon_device *oct;
	int ret;

	oct = vf_rep->oct;

	memset(&rep_cfg, 0, sizeof(rep_cfg));
	rep_cfg.req_type = LIO_VF_REP_REQ_STATE;
	rep_cfg.ifidx = vf_rep->ifidx;
	rep_cfg.rep_state.state = LIO_VF_REP_STATE_UP;

	ret = lio_vf_rep_send_soft_command(oct, &rep_cfg,
					   sizeof(rep_cfg), NULL, 0);

	if (ret) {
		dev_err(&oct->pci_dev->dev,
			"VF_REP open failed with err %d\n", ret);
		return -EIO;
	}

	atomic_set(&vf_rep->ifstate, (atomic_read(&vf_rep->ifstate) |

Annotation

Implementation Notes