xref: /linux/drivers/net/ethernet/intel/ixd/ixd_lib.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
131ddf796SLarysa Zaremba // SPDX-License-Identifier: GPL-2.0-only
231ddf796SLarysa Zaremba /* Copyright (C) 2025 Intel Corporation */
331ddf796SLarysa Zaremba 
431ddf796SLarysa Zaremba #include "ixd.h"
529735d99SLarysa Zaremba #include "ixd_ctlq.h"
6*f290d48fSAmritha Nambiar #include "ixd_devlink.h"
729735d99SLarysa Zaremba #include "ixd_virtchnl.h"
831ddf796SLarysa Zaremba 
931ddf796SLarysa Zaremba #define IXD_DFLT_MBX_Q_LEN 64
1031ddf796SLarysa Zaremba 
1131ddf796SLarysa Zaremba /**
1231ddf796SLarysa Zaremba  * ixd_init_ctlq_create_info - Initialize control queue info for creation
1331ddf796SLarysa Zaremba  * @info: destination
1431ddf796SLarysa Zaremba  * @type: type of the queue to create
1531ddf796SLarysa Zaremba  * @ctlq_reg: register assigned to the control queue
1631ddf796SLarysa Zaremba  */
ixd_init_ctlq_create_info(struct libie_ctlq_create_info * info,enum libie_ctlq_type type,const struct libie_ctlq_reg * ctlq_reg)1731ddf796SLarysa Zaremba static void ixd_init_ctlq_create_info(struct libie_ctlq_create_info *info,
1831ddf796SLarysa Zaremba 				      enum libie_ctlq_type type,
1931ddf796SLarysa Zaremba 				      const struct libie_ctlq_reg *ctlq_reg)
2031ddf796SLarysa Zaremba {
2131ddf796SLarysa Zaremba 	*info = (struct libie_ctlq_create_info) {
2231ddf796SLarysa Zaremba 		.type = type,
2331ddf796SLarysa Zaremba 		.id = -1,
2431ddf796SLarysa Zaremba 		.reg = *ctlq_reg,
2531ddf796SLarysa Zaremba 		.len = IXD_DFLT_MBX_Q_LEN,
2631ddf796SLarysa Zaremba 	};
2731ddf796SLarysa Zaremba }
2831ddf796SLarysa Zaremba 
2931ddf796SLarysa Zaremba /**
3031ddf796SLarysa Zaremba  * ixd_init_libie_xn_params - Initialize xn transaction manager creation info
3131ddf796SLarysa Zaremba  * @params: destination
3231ddf796SLarysa Zaremba  * @adapter: adapter info struct
3331ddf796SLarysa Zaremba  * @ctlqs: list of the managed queues to create
3431ddf796SLarysa Zaremba  * @num_queues: length of the queue list
3531ddf796SLarysa Zaremba  */
ixd_init_libie_xn_params(struct libie_ctlq_xn_init_params * params,struct ixd_adapter * adapter,struct libie_ctlq_create_info * ctlqs,uint num_queues)3631ddf796SLarysa Zaremba static void ixd_init_libie_xn_params(struct libie_ctlq_xn_init_params *params,
3731ddf796SLarysa Zaremba 				     struct ixd_adapter *adapter,
3831ddf796SLarysa Zaremba 				      struct libie_ctlq_create_info *ctlqs,
3931ddf796SLarysa Zaremba 				      uint num_queues)
4031ddf796SLarysa Zaremba {
4131ddf796SLarysa Zaremba 	*params = (struct libie_ctlq_xn_init_params){
4231ddf796SLarysa Zaremba 		.cctlq_info = ctlqs,
4331ddf796SLarysa Zaremba 		.ctx = &adapter->cp_ctx,
4431ddf796SLarysa Zaremba 		.num_qs = num_queues,
4531ddf796SLarysa Zaremba 	};
4631ddf796SLarysa Zaremba }
4731ddf796SLarysa Zaremba 
4831ddf796SLarysa Zaremba /**
4931ddf796SLarysa Zaremba  * ixd_adapter_fill_dflt_ctlqs - Find default control queues and store them
5031ddf796SLarysa Zaremba  * @adapter: adapter info struct
5131ddf796SLarysa Zaremba  */
ixd_adapter_fill_dflt_ctlqs(struct ixd_adapter * adapter)5231ddf796SLarysa Zaremba static void ixd_adapter_fill_dflt_ctlqs(struct ixd_adapter *adapter)
5331ddf796SLarysa Zaremba {
5431ddf796SLarysa Zaremba 	adapter->arq = libie_find_ctlq(&adapter->cp_ctx, LIBIE_CTLQ_TYPE_RX,
5531ddf796SLarysa Zaremba 				       LIBIE_CTLQ_MBX_ID);
5631ddf796SLarysa Zaremba 	adapter->asq = libie_find_ctlq(&adapter->cp_ctx, LIBIE_CTLQ_TYPE_TX,
5731ddf796SLarysa Zaremba 				       LIBIE_CTLQ_MBX_ID);
5831ddf796SLarysa Zaremba }
5931ddf796SLarysa Zaremba 
6031ddf796SLarysa Zaremba /**
6131ddf796SLarysa Zaremba  * ixd_deinit_dflt_mbx - Deinitialize default mailbox
6231ddf796SLarysa Zaremba  * @adapter: adapter info struct
6331ddf796SLarysa Zaremba  */
ixd_deinit_dflt_mbx(struct ixd_adapter * adapter)6431ddf796SLarysa Zaremba void ixd_deinit_dflt_mbx(struct ixd_adapter *adapter)
6531ddf796SLarysa Zaremba {
6629735d99SLarysa Zaremba 	cancel_delayed_work_sync(&adapter->mbx_task);
6729735d99SLarysa Zaremba 
6829735d99SLarysa Zaremba 	if (adapter->xnm)
6929735d99SLarysa Zaremba 		libie_ctlq_xn_shutdown(adapter->xnm);
7029735d99SLarysa Zaremba 
7129735d99SLarysa Zaremba 	if (adapter->asq)
7229735d99SLarysa Zaremba 		ixd_ctlq_clean_sq(adapter, true);
7329735d99SLarysa Zaremba 
7431ddf796SLarysa Zaremba 	if (adapter->xnm)
7531ddf796SLarysa Zaremba 		libie_ctlq_xn_deinit(adapter->xnm, &adapter->cp_ctx);
7631ddf796SLarysa Zaremba 
7731ddf796SLarysa Zaremba 	adapter->arq = NULL;
7831ddf796SLarysa Zaremba 	adapter->asq = NULL;
7931ddf796SLarysa Zaremba 	adapter->xnm = NULL;
8031ddf796SLarysa Zaremba }
8131ddf796SLarysa Zaremba 
8231ddf796SLarysa Zaremba /**
8331ddf796SLarysa Zaremba  * ixd_init_dflt_mbx - Setup default mailbox parameters and make request
8431ddf796SLarysa Zaremba  * @adapter: adapter info struct
8531ddf796SLarysa Zaremba  *
8631ddf796SLarysa Zaremba  * Return: %0 on success, negative errno code on failure
8731ddf796SLarysa Zaremba  */
ixd_init_dflt_mbx(struct ixd_adapter * adapter)8831ddf796SLarysa Zaremba int ixd_init_dflt_mbx(struct ixd_adapter *adapter)
8931ddf796SLarysa Zaremba {
9031ddf796SLarysa Zaremba 	struct libie_ctlq_create_info ctlqs_info[2];
9131ddf796SLarysa Zaremba 	struct libie_ctlq_xn_init_params xn_params;
9231ddf796SLarysa Zaremba 	struct libie_ctlq_reg ctlq_reg_tx;
9331ddf796SLarysa Zaremba 	struct libie_ctlq_reg ctlq_reg_rx;
9431ddf796SLarysa Zaremba 	int err;
9531ddf796SLarysa Zaremba 
9631ddf796SLarysa Zaremba 	ixd_ctlq_reg_init(adapter, &ctlq_reg_tx, &ctlq_reg_rx);
9731ddf796SLarysa Zaremba 	ixd_init_ctlq_create_info(&ctlqs_info[0], LIBIE_CTLQ_TYPE_TX,
9831ddf796SLarysa Zaremba 				  &ctlq_reg_tx);
9931ddf796SLarysa Zaremba 	ixd_init_ctlq_create_info(&ctlqs_info[1], LIBIE_CTLQ_TYPE_RX,
10031ddf796SLarysa Zaremba 				  &ctlq_reg_rx);
10131ddf796SLarysa Zaremba 	ixd_init_libie_xn_params(&xn_params, adapter, ctlqs_info,
10231ddf796SLarysa Zaremba 				 ARRAY_SIZE(ctlqs_info));
10331ddf796SLarysa Zaremba 	err = libie_ctlq_xn_init(&xn_params);
10431ddf796SLarysa Zaremba 	if (err)
10531ddf796SLarysa Zaremba 		return err;
10631ddf796SLarysa Zaremba 	adapter->xnm = xn_params.xnm;
10731ddf796SLarysa Zaremba 
10831ddf796SLarysa Zaremba 	ixd_adapter_fill_dflt_ctlqs(adapter);
10931ddf796SLarysa Zaremba 
11031ddf796SLarysa Zaremba 	if (!adapter->asq || !adapter->arq) {
11131ddf796SLarysa Zaremba 		ixd_deinit_dflt_mbx(adapter);
11231ddf796SLarysa Zaremba 		return -ENOENT;
11331ddf796SLarysa Zaremba 	}
11431ddf796SLarysa Zaremba 
11529735d99SLarysa Zaremba 	queue_delayed_work(system_dfl_wq, &adapter->mbx_task, 0);
11629735d99SLarysa Zaremba 
11731ddf796SLarysa Zaremba 	return 0;
11831ddf796SLarysa Zaremba }
11931ddf796SLarysa Zaremba 
12031ddf796SLarysa Zaremba /**
12131ddf796SLarysa Zaremba  * ixd_init_task - Initialize after reset
12231ddf796SLarysa Zaremba  * @work: init work struct
12331ddf796SLarysa Zaremba  */
ixd_init_task(struct work_struct * work)12431ddf796SLarysa Zaremba void ixd_init_task(struct work_struct *work)
12531ddf796SLarysa Zaremba {
12631ddf796SLarysa Zaremba 	struct ixd_adapter *adapter;
12731ddf796SLarysa Zaremba 	int err;
12831ddf796SLarysa Zaremba 
12931ddf796SLarysa Zaremba 	adapter = container_of(work, struct ixd_adapter,
13031ddf796SLarysa Zaremba 			       init_task.init_work.work);
13131ddf796SLarysa Zaremba 
13231ddf796SLarysa Zaremba 	if (!ixd_check_reset_complete(adapter)) {
13331ddf796SLarysa Zaremba 		if (++adapter->init_task.reset_retries < 10)
13431ddf796SLarysa Zaremba 			queue_delayed_work(system_dfl_wq,
13531ddf796SLarysa Zaremba 					   &adapter->init_task.init_work,
13631ddf796SLarysa Zaremba 					   IXD_INIT_TASK_DELAY_JIFFIES);
13731ddf796SLarysa Zaremba 		else
13831ddf796SLarysa Zaremba 			dev_err(ixd_to_dev(adapter),
13931ddf796SLarysa Zaremba 				"Device reset failed. The driver was unable to contact the device's firmware. Check that the FW is running.\n");
14031ddf796SLarysa Zaremba 		return;
14131ddf796SLarysa Zaremba 	}
14231ddf796SLarysa Zaremba 
14331ddf796SLarysa Zaremba 	adapter->init_task.reset_retries = 0;
14431ddf796SLarysa Zaremba 	err = ixd_init_dflt_mbx(adapter);
14529735d99SLarysa Zaremba 	if (err) {
14631ddf796SLarysa Zaremba 		dev_err(ixd_to_dev(adapter),
14731ddf796SLarysa Zaremba 			"Failed to initialize the default mailbox: %pe\n",
14831ddf796SLarysa Zaremba 			ERR_PTR(err));
14929735d99SLarysa Zaremba 		return;
15029735d99SLarysa Zaremba 	}
15129735d99SLarysa Zaremba 
15229735d99SLarysa Zaremba 	err = ixd_vc_dev_init(adapter);
15329735d99SLarysa Zaremba 	if (!err) {
15429735d99SLarysa Zaremba 		adapter->init_task.vc_retries = 0;
155*f290d48fSAmritha Nambiar 		adapter->init_task.success = true;
156*f290d48fSAmritha Nambiar 		ixd_devlink_register(adapter);
15729735d99SLarysa Zaremba 		return;
15829735d99SLarysa Zaremba 	}
15929735d99SLarysa Zaremba 
16029735d99SLarysa Zaremba 	libie_ctlq_xn_shutdown(adapter->xnm);
16129735d99SLarysa Zaremba 	ixd_trigger_reset(adapter);
16229735d99SLarysa Zaremba 	ixd_deinit_dflt_mbx(adapter);
16329735d99SLarysa Zaremba 	if (++adapter->init_task.vc_retries > 5 ||
16429735d99SLarysa Zaremba 	    (err != -ETIMEDOUT && err != -EAGAIN && err != -EBUSY)) {
16529735d99SLarysa Zaremba 		dev_err(ixd_to_dev(adapter),
16629735d99SLarysa Zaremba 			"Failed to establish mailbox communication with the hardware: %pe\n",
16729735d99SLarysa Zaremba 			ERR_PTR(err));
16829735d99SLarysa Zaremba 		return;
16929735d99SLarysa Zaremba 	}
17029735d99SLarysa Zaremba 
17129735d99SLarysa Zaremba 	queue_delayed_work(system_dfl_wq, &adapter->init_task.init_work,
17229735d99SLarysa Zaremba 			   IXD_INIT_TASK_DELAY_JIFFIES);
17331ddf796SLarysa Zaremba }
174