xref: /linux/drivers/net/ethernet/intel/ixd/ixd_ctlq.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1*29735d99SLarysa Zaremba // SPDX-License-Identifier: GPL-2.0-only
2*29735d99SLarysa Zaremba /* Copyright (C) 2025 Intel Corporation */
3*29735d99SLarysa Zaremba 
4*29735d99SLarysa Zaremba #include "ixd.h"
5*29735d99SLarysa Zaremba #include "ixd_ctlq.h"
6*29735d99SLarysa Zaremba #include "ixd_virtchnl.h"
7*29735d99SLarysa Zaremba 
8*29735d99SLarysa Zaremba #define IXD_CTLQ_RX_TASK_DELAY_JIFFIES	msecs_to_jiffies(300)
9*29735d99SLarysa Zaremba 
10*29735d99SLarysa Zaremba /**
11*29735d99SLarysa Zaremba  * ixd_ctlq_clean_sq - Clean the send control queue after sending the message
12*29735d99SLarysa Zaremba  * @adapter: The adapter that sent the messages
13*29735d99SLarysa Zaremba  * @force: Clean regardless of send status
14*29735d99SLarysa Zaremba  *
15*29735d99SLarysa Zaremba  * Free the libie send resources after sending the message and handling
16*29735d99SLarysa Zaremba  * the response.
17*29735d99SLarysa Zaremba  */
ixd_ctlq_clean_sq(struct ixd_adapter * adapter,bool force)18*29735d99SLarysa Zaremba void ixd_ctlq_clean_sq(struct ixd_adapter *adapter, bool force)
19*29735d99SLarysa Zaremba {
20*29735d99SLarysa Zaremba 	libie_ctlq_xn_send_clean(adapter->asq, kfree, force);
21*29735d99SLarysa Zaremba }
22*29735d99SLarysa Zaremba 
23*29735d99SLarysa Zaremba /**
24*29735d99SLarysa Zaremba  * ixd_ctlq_init_sparams - Initialize control queue send parameters
25*29735d99SLarysa Zaremba  * @adapter: The adapter with initialized mailbox
26*29735d99SLarysa Zaremba  * @sparams: Parameters to initialize
27*29735d99SLarysa Zaremba  * @msg_buf: DMA-mappable pointer to the message being sent
28*29735d99SLarysa Zaremba  * @msg_size: Message size
29*29735d99SLarysa Zaremba  */
ixd_ctlq_init_sparams(struct ixd_adapter * adapter,struct libie_ctlq_xn_send_params * sparams,void * msg_buf,size_t msg_size)30*29735d99SLarysa Zaremba static void ixd_ctlq_init_sparams(struct ixd_adapter *adapter,
31*29735d99SLarysa Zaremba 				  struct libie_ctlq_xn_send_params *sparams,
32*29735d99SLarysa Zaremba 				  void *msg_buf, size_t msg_size)
33*29735d99SLarysa Zaremba {
34*29735d99SLarysa Zaremba 	*sparams = (struct libie_ctlq_xn_send_params) {
35*29735d99SLarysa Zaremba 		.rel_tx_buf = kfree,
36*29735d99SLarysa Zaremba 		.xnm = adapter->xnm,
37*29735d99SLarysa Zaremba 		.ctlq = adapter->asq,
38*29735d99SLarysa Zaremba 		.timeout_ms = IXD_CTLQ_TIMEOUT,
39*29735d99SLarysa Zaremba 		.send_buf = (struct kvec) {
40*29735d99SLarysa Zaremba 			.iov_base = msg_buf,
41*29735d99SLarysa Zaremba 			.iov_len = msg_size,
42*29735d99SLarysa Zaremba 		},
43*29735d99SLarysa Zaremba 	};
44*29735d99SLarysa Zaremba }
45*29735d99SLarysa Zaremba 
46*29735d99SLarysa Zaremba /**
47*29735d99SLarysa Zaremba  * ixd_ctlq_do_req - Perform a standard virtchnl request
48*29735d99SLarysa Zaremba  * @adapter: The adapter with initialized mailbox
49*29735d99SLarysa Zaremba  * @req: virtchnl request description
50*29735d99SLarysa Zaremba  *
51*29735d99SLarysa Zaremba  * Return: %0 if a message was sent and received a response
52*29735d99SLarysa Zaremba  * that was successfully handled by the custom callback,
53*29735d99SLarysa Zaremba  * negative error otherwise.
54*29735d99SLarysa Zaremba  */
ixd_ctlq_do_req(struct ixd_adapter * adapter,const struct ixd_ctlq_req * req)55*29735d99SLarysa Zaremba int ixd_ctlq_do_req(struct ixd_adapter *adapter, const struct ixd_ctlq_req *req)
56*29735d99SLarysa Zaremba {
57*29735d99SLarysa Zaremba 	u8 onstack_send_buff[LIBIE_CP_TX_COPYBREAK] __aligned_largest = {};
58*29735d99SLarysa Zaremba 	struct libie_ctlq_xn_send_params send_params = {};
59*29735d99SLarysa Zaremba 	struct kvec *recv_mem;
60*29735d99SLarysa Zaremba 	void *send_buff;
61*29735d99SLarysa Zaremba 	int err;
62*29735d99SLarysa Zaremba 
63*29735d99SLarysa Zaremba 	send_buff = libie_cp_can_send_onstack(req->send_size) ?
64*29735d99SLarysa Zaremba 		    &onstack_send_buff : kzalloc(req->send_size, GFP_KERNEL);
65*29735d99SLarysa Zaremba 	if (!send_buff)
66*29735d99SLarysa Zaremba 		return -ENOMEM;
67*29735d99SLarysa Zaremba 
68*29735d99SLarysa Zaremba 	ixd_ctlq_init_sparams(adapter, &send_params, send_buff,
69*29735d99SLarysa Zaremba 			      req->send_size);
70*29735d99SLarysa Zaremba 
71*29735d99SLarysa Zaremba 	send_params.chnl_opcode = req->opcode;
72*29735d99SLarysa Zaremba 
73*29735d99SLarysa Zaremba 	if (req->send_buff_init)
74*29735d99SLarysa Zaremba 		req->send_buff_init(adapter, send_buff, req->ctx);
75*29735d99SLarysa Zaremba 
76*29735d99SLarysa Zaremba 	ixd_ctlq_clean_sq(adapter, false);
77*29735d99SLarysa Zaremba 	err = libie_ctlq_xn_send(&send_params);
78*29735d99SLarysa Zaremba 	if (err)
79*29735d99SLarysa Zaremba 		return err;
80*29735d99SLarysa Zaremba 
81*29735d99SLarysa Zaremba 	recv_mem = &send_params.recv_mem;
82*29735d99SLarysa Zaremba 	if (req->recv_process)
83*29735d99SLarysa Zaremba 		err = req->recv_process(adapter, recv_mem->iov_base,
84*29735d99SLarysa Zaremba 					recv_mem->iov_len, req->ctx);
85*29735d99SLarysa Zaremba 
86*29735d99SLarysa Zaremba 	libie_ctlq_release_rx_buf(recv_mem);
87*29735d99SLarysa Zaremba 
88*29735d99SLarysa Zaremba 	return err;
89*29735d99SLarysa Zaremba }
90*29735d99SLarysa Zaremba 
91*29735d99SLarysa Zaremba /**
92*29735d99SLarysa Zaremba  * ixd_ctlq_handle_msg - Default control queue message handler
93*29735d99SLarysa Zaremba  * @ctx: Control plane communication context
94*29735d99SLarysa Zaremba  * @msg: Message received
95*29735d99SLarysa Zaremba  */
ixd_ctlq_handle_msg(struct libie_ctlq_ctx * ctx,struct libie_ctlq_msg * msg)96*29735d99SLarysa Zaremba static void ixd_ctlq_handle_msg(struct libie_ctlq_ctx *ctx,
97*29735d99SLarysa Zaremba 				struct libie_ctlq_msg *msg)
98*29735d99SLarysa Zaremba {
99*29735d99SLarysa Zaremba 	struct ixd_adapter *adapter = pci_get_drvdata(ctx->mmio_info.pdev);
100*29735d99SLarysa Zaremba 
101*29735d99SLarysa Zaremba 	if (ixd_vc_can_handle_msg(msg))
102*29735d99SLarysa Zaremba 		ixd_vc_recv_event_msg(adapter, msg);
103*29735d99SLarysa Zaremba 	else
104*29735d99SLarysa Zaremba 		dev_dbg_ratelimited(ixd_to_dev(adapter),
105*29735d99SLarysa Zaremba 				    "Received an unsupported opcode 0x%x from the CP\n",
106*29735d99SLarysa Zaremba 				    msg->chnl_opcode);
107*29735d99SLarysa Zaremba 
108*29735d99SLarysa Zaremba 	libie_ctlq_release_rx_buf(&msg->recv_mem);
109*29735d99SLarysa Zaremba }
110*29735d99SLarysa Zaremba 
111*29735d99SLarysa Zaremba /**
112*29735d99SLarysa Zaremba  * ixd_ctlq_recv_mb_msg - Receive a potential message over mailbox periodically
113*29735d99SLarysa Zaremba  * @adapter: The adapter with initialized mailbox
114*29735d99SLarysa Zaremba  */
ixd_ctlq_recv_mb_msg(struct ixd_adapter * adapter)115*29735d99SLarysa Zaremba static void ixd_ctlq_recv_mb_msg(struct ixd_adapter *adapter)
116*29735d99SLarysa Zaremba {
117*29735d99SLarysa Zaremba 	struct libie_ctlq_xn_recv_params xn_params = {
118*29735d99SLarysa Zaremba 		.xnm = adapter->xnm,
119*29735d99SLarysa Zaremba 		.ctlq = adapter->arq,
120*29735d99SLarysa Zaremba 		.ctlq_msg_handler = ixd_ctlq_handle_msg,
121*29735d99SLarysa Zaremba 		.budget = LIBIE_CTLQ_MAX_XN_ENTRIES,
122*29735d99SLarysa Zaremba 	};
123*29735d99SLarysa Zaremba 
124*29735d99SLarysa Zaremba 	libie_ctlq_xn_recv(&xn_params);
125*29735d99SLarysa Zaremba }
126*29735d99SLarysa Zaremba 
127*29735d99SLarysa Zaremba /**
128*29735d99SLarysa Zaremba  * ixd_ctlq_rx_task - Periodically check for mailbox responses and events
129*29735d99SLarysa Zaremba  * @work: work handle
130*29735d99SLarysa Zaremba  */
ixd_ctlq_rx_task(struct work_struct * work)131*29735d99SLarysa Zaremba void ixd_ctlq_rx_task(struct work_struct *work)
132*29735d99SLarysa Zaremba {
133*29735d99SLarysa Zaremba 	struct ixd_adapter *adapter;
134*29735d99SLarysa Zaremba 
135*29735d99SLarysa Zaremba 	adapter = container_of(work, struct ixd_adapter, mbx_task.work);
136*29735d99SLarysa Zaremba 
137*29735d99SLarysa Zaremba 	queue_delayed_work(system_dfl_wq, &adapter->mbx_task,
138*29735d99SLarysa Zaremba 			   IXD_CTLQ_RX_TASK_DELAY_JIFFIES);
139*29735d99SLarysa Zaremba 
140*29735d99SLarysa Zaremba 	ixd_ctlq_recv_mb_msg(adapter);
141*29735d99SLarysa Zaremba }
142