Branch data Line data Source code
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 : 0 : 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 [ # # # # ]: 0 : 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 : 0 : dev = &rvu->dev;
22 : :
23 [ # # ]: 0 : if (rvu->dev.drv_inited)
24 : : return 0;
25 : :
26 [ # # ]: 0 : if (dev->mbox_active)
27 : 0 : goto skip_dev_init;
28 : :
29 : : memset(rvu, 0, sizeof(*rvu));
30 : :
31 : : /* Initialize device */
32 : 0 : rc = dev_init(dev, pci_dev);
33 [ # # ]: 0 : if (rc) {
34 : 0 : plt_err("Failed to init roc device");
35 : 0 : goto fail;
36 : : }
37 : :
38 : 0 : skip_dev_init:
39 : 0 : dev->roc_rvu_lf = roc_rvu_lf;
40 : 0 : rvu->pci_dev = pci_dev;
41 : :
42 : 0 : roc_idev_rvu_lf_set(roc_rvu_lf);
43 : 0 : rvu->dev.drv_inited = true;
44 : :
45 : 0 : return 0;
46 : : fail:
47 : 0 : return rc;
48 : : }
49 : :
50 : : int
51 : 0 : 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 : 0 : rvu->dev.drv_inited = false;
59 : :
60 : 0 : roc_idev_rvu_lf_free(roc_rvu_lf);
61 : :
62 : 0 : return dev_fini(&rvu->dev, rvu->pci_dev);
63 : : }
64 : :
65 : : uint16_t
66 : 0 : 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 : 0 : return dev->pf_func;
72 : : }
73 : :
74 : : int
75 : 0 : 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 [ # # ]: 0 : if (from <= MBOX_MSG_GENERIC_MAX_ID || from > to)
80 : : return -EINVAL;
81 : :
82 : 0 : rvu->msg_id_from = from;
83 : 0 : rvu->msg_id_to = to;
84 : :
85 : 0 : return 0;
86 : : }
87 : :
88 : : bool
89 : 0 : 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 [ # # ]: 0 : if (roc_rvu_lf == NULL)
94 : : return 0;
95 : :
96 : : rvu = roc_rvu_lf_to_rvu_priv(roc_rvu_lf);
97 : :
98 [ # # # # ]: 0 : if (msg_id > rvu->msg_id_from && msg_id < rvu->msg_id_to)
99 : 0 : return 1;
100 : :
101 : : return 0;
102 : : }
103 : :
104 : : int
105 : 0 : 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 [ # # # # ]: 0 : if (rvu->dev.vf == -1 && roc_rvu_lf_msg_id_range_check(roc_rvu_lf, msg_id)) {
116 : : /* This is PF context */
117 [ # # ]: 0 : if (vf >= rvu->dev.maxvf)
118 : : return -EINVAL;
119 : 0 : devid = vf;
120 : 0 : 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 : 0 : mbox = mbox_get(rvu->dev.mbox);
125 : : }
126 : 0 : req = (struct rvu_lf_msg *)mbox_alloc_msg_rsp(mbox, devid,
127 : 0 : req_len + sizeof(struct rvu_lf_msg),
128 : 0 : rsp_len + sizeof(struct rvu_lf_msg));
129 [ # # ]: 0 : if (!req)
130 : 0 : goto fail;
131 [ # # ]: 0 : mbox_memcpy(req->data, req_data, req_len);
132 : 0 : req->hdr.sig = MBOX_REQ_SIG;
133 : 0 : req->hdr.id = msg_id;
134 : 0 : req->hdr.pcifunc = roc_rvu_lf_pf_func_get(roc_rvu_lf);
135 : :
136 [ # # ]: 0 : if (rvu->dev.vf == -1) {
137 : 0 : mbox_msg_send_up(mbox, devid);
138 : 0 : rc = mbox_get_rsp(mbox, devid, (void *)&rsp);
139 [ # # ]: 0 : if (rc)
140 : 0 : goto fail;
141 : : } else {
142 : : rc = mbox_process_msg(mbox, (void *)&rsp);
143 [ # # ]: 0 : if (rc)
144 : 0 : goto fail;
145 : : }
146 [ # # ]: 0 : if (rsp_len && rsp_data != NULL)
147 : 0 : mbox_memcpy(rsp_data, rsp->data, rsp_len);
148 : 0 : fail:
149 : : mbox_put(mbox);
150 : 0 : return rc;
151 : : }
152 : :
153 : : int
154 : 0 : 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 : 0 : handle = rvu->pci_dev->intr_handle;
161 : :
162 : 0 : return dev_irq_register(handle, (plt_intr_callback_fn)cb, data, irq);
163 : : }
164 : :
165 : : int
166 : 0 : 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 : 0 : handle = rvu->pci_dev->intr_handle;
173 : :
174 : 0 : dev_irq_unregister(handle, (plt_intr_callback_fn)cb, data, irq);
175 : :
176 : 0 : return 0;
177 : : }
178 : :
179 : : int
180 : 0 : 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 [ # # ]: 0 : if (cb == NULL)
186 : : return -EINVAL;
187 : :
188 : 0 : dev->ops->msg_process_cb = (msg_process_cb_t)cb;
189 : :
190 : 0 : return 0;
191 : : }
192 : :
193 : : int
194 : 0 : 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 : 0 : dev->ops->msg_process_cb = NULL;
200 : :
201 : 0 : return 0;
202 : : }
|