xref: /dpdk/drivers/common/cnxk/roc_rvu_lf.c (revision fcac76a874e6419f125e5cf6bbd38bc4097351bd)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2024 Marvell.
3  */
4 
5 #include "roc_api.h"
6 #include "roc_priv.h"
7 
8 int
9 roc_rvu_lf_dev_init(struct roc_rvu_lf *roc_rvu_lf)
10 {
11 	struct plt_pci_device *pci_dev;
12 	struct dev *dev;
13 	struct rvu_lf *rvu;
14 	int rc;
15 
16 	if (roc_rvu_lf == NULL || roc_rvu_lf->pci_dev == NULL)
17 		return RVU_ERR_PARAM;
18 
19 	rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
20 	pci_dev = roc_rvu_lf->pci_dev;
21 	dev = &rvu->dev;
22 
23 	if (rvu->dev.drv_inited)
24 		return 0;
25 
26 	if (dev->mbox_active)
27 		goto skip_dev_init;
28 
29 	memset(rvu, 0, sizeof(*rvu));
30 
31 	/* Initialize device  */
32 	rc = dev_init(dev, pci_dev);
33 	if (rc) {
34 		plt_err("Failed to init roc device");
35 		goto fail;
36 	}
37 
38 skip_dev_init:
39 	dev->roc_rvu_lf = roc_rvu_lf;
40 	rvu->pci_dev = pci_dev;
41 
42 	roc_idev_rvu_lf_set(roc_rvu_lf);
43 	rvu->dev.drv_inited = true;
44 
45 	return 0;
46 fail:
47 	return rc;
48 }
49 
50 int
51 roc_rvu_lf_dev_fini(struct roc_rvu_lf *roc_rvu_lf)
52 {
53 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
54 
55 	if (rvu == NULL)
56 		return NIX_ERR_PARAM;
57 
58 	rvu->dev.drv_inited = false;
59 
60 	roc_idev_rvu_lf_free(roc_rvu_lf);
61 
62 	return dev_fini(&rvu->dev, rvu->pci_dev);
63 }
64 
65 uint16_t
66 roc_rvu_lf_pf_func_get(struct roc_rvu_lf *roc_rvu_lf)
67 {
68 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
69 	struct dev *dev = &rvu->dev;
70 
71 	return dev->pf_func;
72 }
73 
74 int
75 roc_rvu_lf_msg_id_range_set(struct roc_rvu_lf *roc_rvu_lf, uint16_t from, uint16_t to)
76 {
77 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
78 
79 	if (from <= MBOX_MSG_GENERIC_MAX_ID || from > to)
80 		return -EINVAL;
81 
82 	rvu->msg_id_from = from;
83 	rvu->msg_id_to = to;
84 
85 	return 0;
86 }
87 
88 bool
89 roc_rvu_lf_msg_id_range_check(struct roc_rvu_lf *roc_rvu_lf, uint16_t msg_id)
90 {
91 	struct rvu_lf *rvu;
92 
93 	if (roc_rvu_lf == NULL)
94 		return 0;
95 
96 	rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
97 
98 	if (msg_id > rvu->msg_id_from && msg_id < rvu->msg_id_to)
99 		return 1;
100 
101 	return 0;
102 }
103 
104 int
105 roc_rvu_lf_msg_process(struct roc_rvu_lf *roc_rvu_lf, uint16_t vf, uint16_t msg_id,
106 		       void *req_data, uint16_t req_len, void *rsp_data, uint16_t rsp_len)
107 {
108 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
109 	struct mbox *mbox;
110 	struct rvu_lf_msg *req;
111 	struct rvu_lf_msg *rsp;
112 	int rc = -ENOSPC;
113 	int devid = 0;
114 
115 	if (rvu->dev.vf == -1 && roc_rvu_lf_msg_id_range_check(roc_rvu_lf, msg_id)) {
116 		/* This is PF context */
117 		if (vf >= rvu->dev.maxvf)
118 			return -EINVAL;
119 		devid = vf;
120 		mbox = mbox_get(&rvu->dev.mbox_vfpf_up);
121 	} else {
122 		/* This is VF context */
123 		devid = 0; /* VF send all message to PF */
124 		mbox = mbox_get(rvu->dev.mbox);
125 	}
126 	req = (struct rvu_lf_msg *)mbox_alloc_msg_rsp(mbox, devid,
127 						      req_len + sizeof(struct rvu_lf_msg),
128 						      rsp_len + sizeof(struct rvu_lf_msg));
129 	if (!req)
130 		goto fail;
131 	mbox_memcpy(req->data, req_data, req_len);
132 	req->hdr.sig = MBOX_REQ_SIG;
133 	req->hdr.id = msg_id;
134 	req->hdr.pcifunc = roc_rvu_lf_pf_func_get(roc_rvu_lf);
135 
136 	if (rvu->dev.vf == -1) {
137 		mbox_msg_send_up(mbox, devid);
138 		rc = mbox_get_rsp(mbox, devid, (void *)&rsp);
139 		if (rc)
140 			goto fail;
141 	} else {
142 		rc = mbox_process_msg(mbox, (void *)&rsp);
143 		if (rc)
144 			goto fail;
145 	}
146 	if (rsp_len && rsp_data != NULL)
147 		mbox_memcpy(rsp_data, rsp->data, rsp_len);
148 fail:
149 	mbox_put(mbox);
150 	return rc;
151 }
152 
153 int
154 roc_rvu_lf_irq_register(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq,
155 			roc_rvu_lf_intr_cb_fn cb, void *data)
156 {
157 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
158 	struct plt_intr_handle *handle;
159 
160 	handle = rvu->pci_dev->intr_handle;
161 
162 	return dev_irq_register(handle, (plt_intr_callback_fn)cb, data, irq);
163 }
164 
165 int
166 roc_rvu_lf_irq_unregister(struct roc_rvu_lf *roc_rvu_lf, unsigned int irq,
167 			  roc_rvu_lf_intr_cb_fn cb, void *data)
168 {
169 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
170 	struct plt_intr_handle *handle;
171 
172 	handle = rvu->pci_dev->intr_handle;
173 
174 	dev_irq_unregister(handle, (plt_intr_callback_fn)cb, data, irq);
175 
176 	return 0;
177 }
178 
179 int
180 roc_rvu_lf_msg_handler_register(struct roc_rvu_lf *roc_rvu_lf, roc_rvu_lf_msg_handler_cb_fn cb)
181 {
182 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
183 	struct dev *dev = &rvu->dev;
184 
185 	if (cb == NULL)
186 		return -EINVAL;
187 
188 	dev->ops->msg_process_cb = (msg_process_cb_t)cb;
189 
190 	return 0;
191 }
192 
193 int
194 roc_rvu_lf_msg_handler_unregister(struct roc_rvu_lf *roc_rvu_lf)
195 {
196 	struct rvu_lf *rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
197 	struct dev *dev = &rvu->dev;
198 
199 	dev->ops->msg_process_cb = NULL;
200 
201 	return 0;
202 }
203