xref: /dpdk/drivers/common/cnxk/roc_rvu_lf.c (revision fcac76a874e6419f125e5cf6bbd38bc4097351bd)
1318ee1b0SAkhil Goyal /* SPDX-License-Identifier: BSD-3-Clause
2318ee1b0SAkhil Goyal  * Copyright(C) 2024 Marvell.
3318ee1b0SAkhil Goyal  */
4318ee1b0SAkhil Goyal 
5318ee1b0SAkhil Goyal #include "roc_api.h"
6318ee1b0SAkhil Goyal #include "roc_priv.h"
7318ee1b0SAkhil Goyal 
8318ee1b0SAkhil Goyal int
9318ee1b0SAkhil Goyal roc_rvu_lf_dev_init(struct roc_rvu_lf *roc_rvu_lf)
10318ee1b0SAkhil Goyal {
11318ee1b0SAkhil Goyal 	struct plt_pci_device *pci_dev;
12318ee1b0SAkhil Goyal 	struct dev *dev;
13318ee1b0SAkhil Goyal 	struct rvu_lf *rvu;
14318ee1b0SAkhil Goyal 	int rc;
15318ee1b0SAkhil Goyal 
16318ee1b0SAkhil Goyal 	if (roc_rvu_lf == NULL || roc_rvu_lf->pci_dev == NULL)
17318ee1b0SAkhil Goyal 		return RVU_ERR_PARAM;
18318ee1b0SAkhil Goyal 
19318ee1b0SAkhil Goyal 	rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
20318ee1b0SAkhil Goyal 	pci_dev = roc_rvu_lf->pci_dev;
21318ee1b0SAkhil Goyal 	dev = &rvu->dev;
22318ee1b0SAkhil Goyal 
23318ee1b0SAkhil Goyal 	if (rvu->dev.drv_inited)
24318ee1b0SAkhil Goyal 		return 0;
25318ee1b0SAkhil Goyal 
26318ee1b0SAkhil Goyal 	if (dev->mbox_active)
27318ee1b0SAkhil Goyal 		goto skip_dev_init;
28318ee1b0SAkhil Goyal 
29318ee1b0SAkhil Goyal 	memset(rvu, 0, sizeof(*rvu));
30318ee1b0SAkhil Goyal 
31318ee1b0SAkhil Goyal 	/* Initialize device  */
32318ee1b0SAkhil Goyal 	rc = dev_init(dev, pci_dev);
33318ee1b0SAkhil Goyal 	if (rc) {
34318ee1b0SAkhil Goyal 		plt_err("Failed to init roc device");
35318ee1b0SAkhil Goyal 		goto fail;
36318ee1b0SAkhil Goyal 	}
37318ee1b0SAkhil Goyal 
38318ee1b0SAkhil Goyal skip_dev_init:
39318ee1b0SAkhil Goyal 	dev->roc_rvu_lf = roc_rvu_lf;
40318ee1b0SAkhil Goyal 	rvu->pci_dev = pci_dev;
41318ee1b0SAkhil Goyal 
42318ee1b0SAkhil Goyal 	roc_idev_rvu_lf_set(roc_rvu_lf);
43318ee1b0SAkhil Goyal 	rvu->dev.drv_inited = true;
44318ee1b0SAkhil Goyal 
45318ee1b0SAkhil Goyal 	return 0;
46318ee1b0SAkhil Goyal fail:
47318ee1b0SAkhil Goyal 	return rc;
48318ee1b0SAkhil Goyal }
49318ee1b0SAkhil Goyal 
50318ee1b0SAkhil Goyal int
51318ee1b0SAkhil Goyal roc_rvu_lf_dev_fini(struct roc_rvu_lf *roc_rvu_lf)
52318ee1b0SAkhil Goyal {
53318ee1b0SAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
54318ee1b0SAkhil Goyal 
55318ee1b0SAkhil Goyal 	if (rvu == NULL)
56318ee1b0SAkhil Goyal 		return NIX_ERR_PARAM;
57318ee1b0SAkhil Goyal 
58318ee1b0SAkhil Goyal 	rvu->dev.drv_inited = false;
59318ee1b0SAkhil Goyal 
60318ee1b0SAkhil Goyal 	roc_idev_rvu_lf_free(roc_rvu_lf);
61318ee1b0SAkhil Goyal 
62318ee1b0SAkhil Goyal 	return dev_fini(&rvu->dev, rvu->pci_dev);
63318ee1b0SAkhil Goyal }
64f4c67d72SAkhil Goyal 
65*fcac76a8SAkhil Goyal uint16_t
66384903edSAkhil Goyal roc_rvu_lf_pf_func_get(struct roc_rvu_lf *roc_rvu_lf)
67384903edSAkhil Goyal {
68384903edSAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
69384903edSAkhil Goyal 	struct dev *dev = &rvu->dev;
70384903edSAkhil Goyal 
71384903edSAkhil Goyal 	return dev->pf_func;
72384903edSAkhil Goyal }
73384903edSAkhil Goyal 
74f4c67d72SAkhil Goyal int
750924cc0bSAkhil Goyal roc_rvu_lf_msg_id_range_set(struct roc_rvu_lf *roc_rvu_lf, uint16_t from, uint16_t to)
760924cc0bSAkhil Goyal {
770924cc0bSAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
780924cc0bSAkhil Goyal 
790924cc0bSAkhil Goyal 	if (from <= MBOX_MSG_GENERIC_MAX_ID || from > to)
800924cc0bSAkhil Goyal 		return -EINVAL;
810924cc0bSAkhil Goyal 
820924cc0bSAkhil Goyal 	rvu->msg_id_from = from;
830924cc0bSAkhil Goyal 	rvu->msg_id_to = to;
840924cc0bSAkhil Goyal 
850924cc0bSAkhil Goyal 	return 0;
860924cc0bSAkhil Goyal }
870924cc0bSAkhil Goyal 
880924cc0bSAkhil Goyal bool
890924cc0bSAkhil Goyal roc_rvu_lf_msg_id_range_check(struct roc_rvu_lf *roc_rvu_lf, uint16_t msg_id)
900924cc0bSAkhil Goyal {
910924cc0bSAkhil Goyal 	struct rvu_lf *rvu;
920924cc0bSAkhil Goyal 
930924cc0bSAkhil Goyal 	if (roc_rvu_lf == NULL)
940924cc0bSAkhil Goyal 		return 0;
950924cc0bSAkhil Goyal 
960924cc0bSAkhil Goyal 	rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
970924cc0bSAkhil Goyal 
980924cc0bSAkhil Goyal 	if (msg_id > rvu->msg_id_from && msg_id < rvu->msg_id_to)
990924cc0bSAkhil Goyal 		return 1;
1000924cc0bSAkhil Goyal 
1010924cc0bSAkhil Goyal 	return 0;
1020924cc0bSAkhil Goyal }
1030924cc0bSAkhil Goyal 
1040924cc0bSAkhil Goyal int
105384903edSAkhil Goyal roc_rvu_lf_msg_process(struct roc_rvu_lf *roc_rvu_lf, uint16_t vf, uint16_t msg_id,
106384903edSAkhil Goyal 		       void *req_data, uint16_t req_len, void *rsp_data, uint16_t rsp_len)
107384903edSAkhil Goyal {
108384903edSAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
109384903edSAkhil Goyal 	struct mbox *mbox;
110384903edSAkhil Goyal 	struct rvu_lf_msg *req;
111384903edSAkhil Goyal 	struct rvu_lf_msg *rsp;
112384903edSAkhil Goyal 	int rc = -ENOSPC;
113384903edSAkhil Goyal 	int devid = 0;
114384903edSAkhil Goyal 
115384903edSAkhil Goyal 	if (rvu->dev.vf == -1 && roc_rvu_lf_msg_id_range_check(roc_rvu_lf, msg_id)) {
116384903edSAkhil Goyal 		/* This is PF context */
117384903edSAkhil Goyal 		if (vf >= rvu->dev.maxvf)
118384903edSAkhil Goyal 			return -EINVAL;
119384903edSAkhil Goyal 		devid = vf;
120384903edSAkhil Goyal 		mbox = mbox_get(&rvu->dev.mbox_vfpf_up);
121384903edSAkhil Goyal 	} else {
122384903edSAkhil Goyal 		/* This is VF context */
123384903edSAkhil Goyal 		devid = 0; /* VF send all message to PF */
124384903edSAkhil Goyal 		mbox = mbox_get(rvu->dev.mbox);
125384903edSAkhil Goyal 	}
126384903edSAkhil Goyal 	req = (struct rvu_lf_msg *)mbox_alloc_msg_rsp(mbox, devid,
127384903edSAkhil Goyal 						      req_len + sizeof(struct rvu_lf_msg),
128384903edSAkhil Goyal 						      rsp_len + sizeof(struct rvu_lf_msg));
129384903edSAkhil Goyal 	if (!req)
130384903edSAkhil Goyal 		goto fail;
131384903edSAkhil Goyal 	mbox_memcpy(req->data, req_data, req_len);
132384903edSAkhil Goyal 	req->hdr.sig = MBOX_REQ_SIG;
133384903edSAkhil Goyal 	req->hdr.id = msg_id;
134384903edSAkhil Goyal 	req->hdr.pcifunc = roc_rvu_lf_pf_func_get(roc_rvu_lf);
135384903edSAkhil Goyal 
136384903edSAkhil Goyal 	if (rvu->dev.vf == -1) {
137384903edSAkhil Goyal 		mbox_msg_send_up(mbox, devid);
138384903edSAkhil Goyal 		rc = mbox_get_rsp(mbox, devid, (void *)&rsp);
139384903edSAkhil Goyal 		if (rc)
140384903edSAkhil Goyal 			goto fail;
141384903edSAkhil Goyal 	} else {
142384903edSAkhil Goyal 		rc = mbox_process_msg(mbox, (void *)&rsp);
143384903edSAkhil Goyal 		if (rc)
144384903edSAkhil Goyal 			goto fail;
145384903edSAkhil Goyal 	}
146384903edSAkhil Goyal 	if (rsp_len && rsp_data != NULL)
147384903edSAkhil Goyal 		mbox_memcpy(rsp_data, rsp->data, rsp_len);
148384903edSAkhil Goyal fail:
149384903edSAkhil Goyal 	mbox_put(mbox);
150384903edSAkhil Goyal 	return rc;
151384903edSAkhil Goyal }
152384903edSAkhil Goyal 
153384903edSAkhil Goyal int
154f4c67d72SAkhil Goyal roc_rvu_lf_irq_register(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq,
155f4c67d72SAkhil Goyal 			roc_rvu_lf_intr_cb_fn cb, void *data)
156f4c67d72SAkhil Goyal {
157f4c67d72SAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
158f4c67d72SAkhil Goyal 	struct plt_intr_handle *handle;
159f4c67d72SAkhil Goyal 
160f4c67d72SAkhil Goyal 	handle = rvu->pci_dev->intr_handle;
161f4c67d72SAkhil Goyal 
162f4c67d72SAkhil Goyal 	return dev_irq_register(handle, (plt_intr_callback_fn)cb, data, irq);
163f4c67d72SAkhil Goyal }
164f4c67d72SAkhil Goyal 
165f4c67d72SAkhil Goyal int
166f4c67d72SAkhil Goyal roc_rvu_lf_irq_unregister(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq,
167f4c67d72SAkhil Goyal 			  roc_rvu_lf_intr_cb_fn cb, void *data)
168f4c67d72SAkhil Goyal {
169f4c67d72SAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
170f4c67d72SAkhil Goyal 	struct plt_intr_handle *handle;
171f4c67d72SAkhil Goyal 
172f4c67d72SAkhil Goyal 	handle = rvu->pci_dev->intr_handle;
173f4c67d72SAkhil Goyal 
174f4c67d72SAkhil Goyal 	dev_irq_unregister(handle, (plt_intr_callback_fn)cb, data, irq);
175f4c67d72SAkhil Goyal 
176f4c67d72SAkhil Goyal 	return 0;
177f4c67d72SAkhil Goyal }
1787396eaceSAkhil Goyal 
1797396eaceSAkhil Goyal int
1807396eaceSAkhil Goyal roc_rvu_lf_msg_handler_register(struct roc_rvu_lf *roc_rvu_lf, roc_rvu_lf_msg_handler_cb_fn cb)
1817396eaceSAkhil Goyal {
1827396eaceSAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
1837396eaceSAkhil Goyal 	struct dev *dev = &rvu->dev;
1847396eaceSAkhil Goyal 
1857396eaceSAkhil Goyal 	if (cb == NULL)
1867396eaceSAkhil Goyal 		return -EINVAL;
1877396eaceSAkhil Goyal 
1887396eaceSAkhil Goyal 	dev->ops->msg_process_cb = (msg_process_cb_t)cb;
1897396eaceSAkhil Goyal 
1907396eaceSAkhil Goyal 	return 0;
1917396eaceSAkhil Goyal }
1927396eaceSAkhil Goyal 
1937396eaceSAkhil Goyal int
1947396eaceSAkhil Goyal roc_rvu_lf_msg_handler_unregister(struct roc_rvu_lf *roc_rvu_lf)
1957396eaceSAkhil Goyal {
1967396eaceSAkhil Goyal 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
1977396eaceSAkhil Goyal 	struct dev *dev = &rvu->dev;
1987396eaceSAkhil Goyal 
1997396eaceSAkhil Goyal 	dev->ops->msg_process_cb = NULL;
2007396eaceSAkhil Goyal 
2017396eaceSAkhil Goyal 	return 0;
2027396eaceSAkhil Goyal }
203