drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c
Extension
.c
Size
8733 bytes
Lines
333
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 (!mgmt_work->msg) {
			kfree(mgmt_work);
			return;
		}
	} else {
		mgmt_work->msg = NULL;
	}

	mgmt_work->pf_to_mgmt = pf_to_mgmt;
	mgmt_work->msg_len = recv_msg->msg_len;
	mgmt_work->msg_id = recv_msg->msg_id;
	mgmt_work->mod = recv_msg->mod;
	mgmt_work->cmd = recv_msg->cmd;
	mgmt_work->async_mgmt_to_pf = recv_msg->async_mgmt_to_pf;

	INIT_WORK(&mgmt_work->work, hinic3_recv_mgmt_msg_work_handler);
	queue_work(pf_to_mgmt->workq, &mgmt_work->work);
}

static void
hinic3_recv_mgmt_msg_handler(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt,
			     const u8 *header,
			     struct hinic3_recv_msg *recv_msg)
{
	struct hinic3_hwdev *hwdev = pf_to_mgmt->hwdev;
	const void *seg_data;
	__le64 msg_header;
	bool is_complete;
	u8 dir, msg_id;
	int err;

	msg_header = *(__force __le64 *)header;
	dir = MBOX_MSG_HEADER_GET(msg_header, DIRECTION);
	msg_id = MBOX_MSG_HEADER_GET(msg_header, MSG_ID);
	/* Don't need to get anything from hw when cmd is async */
	if (dir == MBOX_MSG_RESP && (msg_id & MGMT_ASYNC_MSG_FLAG))
		return;

	seg_data = header + sizeof(msg_header);
	err = hinic3_recv_msg_add_seg(recv_msg, msg_header,
				      seg_data, &is_complete);
	if (err) {
		dev_err(hwdev->dev, "invalid receive segment\n");
		/* set seq_id to invalid seq_id */
		recv_msg->seq_id = MGMT_BOGUS_SEQ_ID;

		return;
	}

	if (!is_complete)
		return;

	recv_msg->cmd = MBOX_MSG_HEADER_GET(msg_header, CMD);
	recv_msg->mod = MBOX_MSG_HEADER_GET(msg_header, MODULE);
	recv_msg->async_mgmt_to_pf = MBOX_MSG_HEADER_GET(msg_header, NO_ACK);
	recv_msg->seq_id = MGMT_BOGUS_SEQ_ID;

	if (dir == MBOX_MSG_RESP)
		hinic3_mgmt_resp_msg_handler(pf_to_mgmt, recv_msg);
	else
		hinic3_init_mgmt_msg_work(pf_to_mgmt, recv_msg);
}

static int alloc_recv_msg(struct hinic3_recv_msg *recv_msg)
{
	recv_msg->seq_id = MGMT_BOGUS_SEQ_ID;

	recv_msg->msg = kzalloc(MGMT_MAX_PF_BUF_SIZE, GFP_KERNEL);
	if (!recv_msg->msg)
		return -ENOMEM;

	return 0;
}

static void free_recv_msg(struct hinic3_recv_msg *recv_msg)
{
	kfree(recv_msg->msg);
}

static int alloc_msg_buf(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt)
{
	struct device *dev = pf_to_mgmt->hwdev->dev;
	int err;

	err = alloc_recv_msg(&pf_to_mgmt->recv_msg_from_mgmt);
	if (err) {
		dev_err(dev, "Failed to allocate recv msg\n");
		return err;
	}

Annotation

Implementation Notes