drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/octeon_ep/octep_pfvf_mbox.c
Extension
.c
Size
14130 bytes
Lines
473
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

switch (cmd.s.opcode) {
		case OCTEP_PFVF_MBOX_CMD_GET_LINK_INFO:
			memset(&link_info, 0, sizeof(link_info));
			err = octep_ctrl_net_get_link_info(oct, vf_id, &link_info);
			if (!err) {
				mbox->message_len = sizeof(link_info);
				*((int32_t *)rsp->s_data.data) = mbox->message_len;
				memcpy(mbox->config_data, (u8 *)&link_info, sizeof(link_info));
			} else {
				rsp->s_data.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
				return;
			}
			break;
		case OCTEP_PFVF_MBOX_CMD_GET_STATS:
			memset(&rx_stats, 0, sizeof(rx_stats));
			memset(&tx_stats, 0, sizeof(tx_stats));
			err = octep_ctrl_net_get_if_stats(oct, vf_id, &rx_stats, &tx_stats);
			if (!err) {
				mbox->message_len = sizeof(rx_stats) + sizeof(tx_stats);
				*((int32_t *)rsp->s_data.data) = mbox->message_len;
				memcpy(mbox->config_data, (u8 *)&rx_stats, sizeof(rx_stats));
				memcpy(mbox->config_data + sizeof(rx_stats), (u8 *)&tx_stats,
				       sizeof(tx_stats));

			} else {
				rsp->s_data.type = OCTEP_PFVF_MBOX_TYPE_RSP_NACK;
				return;
			}
			break;
		}
		*((int32_t *)rsp->s_data.data) = mbox->message_len;
		return;
	}

	if (mbox->message_len > OCTEP_PFVF_MBOX_MAX_DATA_SIZE)
		length = OCTEP_PFVF_MBOX_MAX_DATA_SIZE;
	else
		length = mbox->message_len;

	mbox->message_len -= length;

	for (i = 0; i < length; i++) {
		rsp->s_data.data[i] =
			mbox->config_data[mbox->config_data_index];
		mbox->config_data_index++;
	}
}

void octep_pfvf_notify(struct octep_device *oct, struct octep_ctrl_mbox_msg *msg)
{
	union octep_pfvf_mbox_word notif = { 0 };
	struct octep_ctrl_net_f2h_req *req;

	req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg;
	switch (req->hdr.s.cmd) {
	case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS:
		notif.s_link_status.opcode = OCTEP_PFVF_MBOX_NOTIF_LINK_STATUS;
		notif.s_link_status.status = req->link.state;
		break;
	default:
		pr_info("Unknown mbox notif for vf: %u\n",
			req->hdr.s.cmd);
		return;
	}

	notif.s.type = OCTEP_PFVF_MBOX_TYPE_CMD;
	octep_send_notification(oct, msg->hdr.s.vf_idx, notif);
}

void octep_pfvf_mbox_work(struct work_struct *work)
{
	struct octep_pfvf_mbox_wk *wk = container_of(work, struct octep_pfvf_mbox_wk, work);
	union octep_pfvf_mbox_word cmd = { 0 };
	union octep_pfvf_mbox_word rsp = { 0 };
	struct octep_mbox *mbox = NULL;
	struct octep_device *oct = NULL;
	int vf_id;

	mbox = (struct octep_mbox *)wk->ctxptr;
	oct = (struct octep_device *)mbox->oct;
	vf_id = mbox->vf_id;

	mutex_lock(&mbox->lock);
	cmd.u64 = readq(mbox->vf_pf_data_reg);
	rsp.u64 = 0;

	switch (cmd.s.opcode) {
	case OCTEP_PFVF_MBOX_CMD_VERSION:
		octep_pfvf_validate_version(oct, vf_id, cmd, &rsp);
		break;

Annotation

Implementation Notes