1c88d3638SLiron Himi /* SPDX-License-Identifier: BSD-3-Clause
2c88d3638SLiron Himi * Copyright(C) 2021 Marvell.
3c88d3638SLiron Himi */
4c88d3638SLiron Himi
5c88d3638SLiron Himi #include "roc_api.h"
6c88d3638SLiron Himi #include "roc_priv.h"
7c88d3638SLiron Himi
8c88d3638SLiron Himi #define REE0_PF 19
9c88d3638SLiron Himi #define REE1_PF 20
10c88d3638SLiron Himi
11c88d3638SLiron Himi static int
roc_ree_available_queues_get(struct roc_ree_vf * vf,uint16_t * nb_queues)12c88d3638SLiron Himi roc_ree_available_queues_get(struct roc_ree_vf *vf, uint16_t *nb_queues)
13c88d3638SLiron Himi {
14c88d3638SLiron Himi struct free_rsrcs_rsp *rsp;
15c88d3638SLiron Himi struct dev *dev = vf->dev;
16c88d3638SLiron Himi int ret;
17c88d3638SLiron Himi
18c88d3638SLiron Himi mbox_alloc_msg_free_rsrc_cnt(dev->mbox);
19c88d3638SLiron Himi
20c88d3638SLiron Himi ret = mbox_process_msg(dev->mbox, (void *)&rsp);
21c88d3638SLiron Himi if (ret)
22c88d3638SLiron Himi return -EIO;
23c88d3638SLiron Himi
24c88d3638SLiron Himi if (vf->block_address == RVU_BLOCK_ADDR_REE0)
25c88d3638SLiron Himi *nb_queues = rsp->ree0;
26c88d3638SLiron Himi else
27c88d3638SLiron Himi *nb_queues = rsp->ree1;
28c88d3638SLiron Himi return 0;
29c88d3638SLiron Himi }
30c88d3638SLiron Himi
31c88d3638SLiron Himi static int
roc_ree_max_matches_get(struct roc_ree_vf * vf,uint8_t * max_matches)32c88d3638SLiron Himi roc_ree_max_matches_get(struct roc_ree_vf *vf, uint8_t *max_matches)
33c88d3638SLiron Himi {
34c88d3638SLiron Himi uint64_t val;
35c88d3638SLiron Himi int ret;
36c88d3638SLiron Himi
37c88d3638SLiron Himi ret = roc_ree_af_reg_read(vf, REE_AF_REEXM_MAX_MATCH, &val);
38c88d3638SLiron Himi if (ret)
39c88d3638SLiron Himi return ret;
40c88d3638SLiron Himi
41c88d3638SLiron Himi *max_matches = val;
42c88d3638SLiron Himi return 0;
43c88d3638SLiron Himi }
44c88d3638SLiron Himi
45c88d3638SLiron Himi int
roc_ree_queues_attach(struct roc_ree_vf * vf,uint8_t nb_queues)46c88d3638SLiron Himi roc_ree_queues_attach(struct roc_ree_vf *vf, uint8_t nb_queues)
47c88d3638SLiron Himi {
48c88d3638SLiron Himi struct rsrc_attach_req *req;
49c88d3638SLiron Himi struct mbox *mbox;
50c88d3638SLiron Himi
51c88d3638SLiron Himi mbox = vf->dev->mbox;
52c88d3638SLiron Himi /* Ask AF to attach required LFs */
53c88d3638SLiron Himi req = mbox_alloc_msg_attach_resources(mbox);
54c88d3638SLiron Himi if (req == NULL) {
55c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
56c88d3638SLiron Himi return -EFAULT;
57c88d3638SLiron Himi }
58c88d3638SLiron Himi
59c88d3638SLiron Himi /* 1 LF = 1 queue */
60c88d3638SLiron Himi req->reelfs = nb_queues;
61c88d3638SLiron Himi req->ree_blkaddr = vf->block_address;
62c88d3638SLiron Himi
63c88d3638SLiron Himi if (mbox_process(mbox) < 0)
64c88d3638SLiron Himi return -EIO;
65c88d3638SLiron Himi
66c88d3638SLiron Himi /* Update number of attached queues */
67c88d3638SLiron Himi vf->nb_queues = nb_queues;
68c88d3638SLiron Himi
69c88d3638SLiron Himi return 0;
70c88d3638SLiron Himi }
71c88d3638SLiron Himi
72c88d3638SLiron Himi int
roc_ree_queues_detach(struct roc_ree_vf * vf)73c88d3638SLiron Himi roc_ree_queues_detach(struct roc_ree_vf *vf)
74c88d3638SLiron Himi {
75c88d3638SLiron Himi struct rsrc_detach_req *req;
76c88d3638SLiron Himi struct mbox *mbox;
77c88d3638SLiron Himi
78c88d3638SLiron Himi mbox = vf->dev->mbox;
79c88d3638SLiron Himi req = mbox_alloc_msg_detach_resources(mbox);
80c88d3638SLiron Himi if (req == NULL) {
81c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
82c88d3638SLiron Himi return -EFAULT;
83c88d3638SLiron Himi }
84c88d3638SLiron Himi req->reelfs = true;
85c88d3638SLiron Himi req->partial = true;
86c88d3638SLiron Himi if (mbox_process(mbox) < 0)
87c88d3638SLiron Himi return -EIO;
88c88d3638SLiron Himi
89c88d3638SLiron Himi /* Queues have been detached */
90c88d3638SLiron Himi vf->nb_queues = 0;
91c88d3638SLiron Himi
92c88d3638SLiron Himi return 0;
93c88d3638SLiron Himi }
94c88d3638SLiron Himi
95c88d3638SLiron Himi int
roc_ree_msix_offsets_get(struct roc_ree_vf * vf)96c88d3638SLiron Himi roc_ree_msix_offsets_get(struct roc_ree_vf *vf)
97c88d3638SLiron Himi {
98c88d3638SLiron Himi struct msix_offset_rsp *rsp;
99c88d3638SLiron Himi struct mbox *mbox;
100c88d3638SLiron Himi uint32_t i, ret;
101c88d3638SLiron Himi
102c88d3638SLiron Himi /* Get REE MSI-X vector offsets */
103c88d3638SLiron Himi mbox = vf->dev->mbox;
104c88d3638SLiron Himi mbox_alloc_msg_msix_offset(mbox);
105c88d3638SLiron Himi
106c88d3638SLiron Himi ret = mbox_process_msg(mbox, (void *)&rsp);
107c88d3638SLiron Himi if (ret)
108c88d3638SLiron Himi return ret;
109c88d3638SLiron Himi
110c88d3638SLiron Himi for (i = 0; i < vf->nb_queues; i++) {
111c88d3638SLiron Himi if (vf->block_address == RVU_BLOCK_ADDR_REE0)
112c88d3638SLiron Himi vf->lf_msixoff[i] = rsp->ree0_lf_msixoff[i];
113c88d3638SLiron Himi else
114c88d3638SLiron Himi vf->lf_msixoff[i] = rsp->ree1_lf_msixoff[i];
115c88d3638SLiron Himi plt_ree_dbg("lf_msixoff[%d] 0x%x", i, vf->lf_msixoff[i]);
116c88d3638SLiron Himi }
117c88d3638SLiron Himi
118c88d3638SLiron Himi return 0;
119c88d3638SLiron Himi }
120c88d3638SLiron Himi
121c88d3638SLiron Himi static int
ree_send_mbox_msg(struct roc_ree_vf * vf)122c88d3638SLiron Himi ree_send_mbox_msg(struct roc_ree_vf *vf)
123c88d3638SLiron Himi {
124c88d3638SLiron Himi struct mbox *mbox = vf->dev->mbox;
125c88d3638SLiron Himi int ret;
126c88d3638SLiron Himi
127c88d3638SLiron Himi mbox_msg_send(mbox, 0);
128c88d3638SLiron Himi
129c88d3638SLiron Himi ret = mbox_wait_for_rsp(mbox, 0);
130c88d3638SLiron Himi if (ret < 0) {
131c88d3638SLiron Himi plt_err("Could not get mailbox response");
132c88d3638SLiron Himi return ret;
133c88d3638SLiron Himi }
134c88d3638SLiron Himi
135c88d3638SLiron Himi return 0;
136c88d3638SLiron Himi }
137c88d3638SLiron Himi
138c88d3638SLiron Himi int
roc_ree_config_lf(struct roc_ree_vf * vf,uint8_t lf,uint8_t pri,uint32_t size)139c88d3638SLiron Himi roc_ree_config_lf(struct roc_ree_vf *vf, uint8_t lf, uint8_t pri, uint32_t size)
140c88d3638SLiron Himi {
141c88d3638SLiron Himi struct ree_lf_req_msg *req;
142c88d3638SLiron Himi struct mbox *mbox;
143c88d3638SLiron Himi int ret;
144c88d3638SLiron Himi
145c88d3638SLiron Himi mbox = vf->dev->mbox;
146c88d3638SLiron Himi req = mbox_alloc_msg_ree_config_lf(mbox);
147c88d3638SLiron Himi if (req == NULL) {
148c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
149c88d3638SLiron Himi return -EFAULT;
150c88d3638SLiron Himi }
151c88d3638SLiron Himi
152c88d3638SLiron Himi req->lf = lf;
153c88d3638SLiron Himi req->pri = pri ? 1 : 0;
154c88d3638SLiron Himi req->size = size;
155c88d3638SLiron Himi req->blkaddr = vf->block_address;
156c88d3638SLiron Himi
157c88d3638SLiron Himi ret = mbox_process(mbox);
158c88d3638SLiron Himi if (ret < 0) {
159c88d3638SLiron Himi plt_err("Could not get mailbox response");
160c88d3638SLiron Himi return ret;
161c88d3638SLiron Himi }
162c88d3638SLiron Himi return 0;
163c88d3638SLiron Himi }
164c88d3638SLiron Himi
165c88d3638SLiron Himi int
roc_ree_af_reg_read(struct roc_ree_vf * vf,uint64_t reg,uint64_t * val)166c88d3638SLiron Himi roc_ree_af_reg_read(struct roc_ree_vf *vf, uint64_t reg, uint64_t *val)
167c88d3638SLiron Himi {
168c88d3638SLiron Himi struct ree_rd_wr_reg_msg *msg;
169c88d3638SLiron Himi struct mbox_dev *mdev;
170c88d3638SLiron Himi struct mbox *mbox;
171c88d3638SLiron Himi int ret, off;
172c88d3638SLiron Himi
173c88d3638SLiron Himi mbox = vf->dev->mbox;
174c88d3638SLiron Himi mdev = &mbox->dev[0];
175c88d3638SLiron Himi msg = (struct ree_rd_wr_reg_msg *)mbox_alloc_msg_rsp(
176c88d3638SLiron Himi mbox, 0, sizeof(*msg), sizeof(*msg));
177c88d3638SLiron Himi if (msg == NULL) {
178c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
179c88d3638SLiron Himi return -EFAULT;
180c88d3638SLiron Himi }
181c88d3638SLiron Himi
182c88d3638SLiron Himi msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
183c88d3638SLiron Himi msg->hdr.sig = MBOX_REQ_SIG;
184c88d3638SLiron Himi msg->hdr.pcifunc = vf->dev->pf_func;
185c88d3638SLiron Himi msg->is_write = 0;
186c88d3638SLiron Himi msg->reg_offset = reg;
187c88d3638SLiron Himi msg->ret_val = val;
188c88d3638SLiron Himi msg->blkaddr = vf->block_address;
189c88d3638SLiron Himi
190c88d3638SLiron Himi ret = ree_send_mbox_msg(vf);
191c88d3638SLiron Himi if (ret < 0)
192c88d3638SLiron Himi return ret;
193c88d3638SLiron Himi
194c88d3638SLiron Himi off = mbox->rx_start +
195c88d3638SLiron Himi RTE_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
196c88d3638SLiron Himi msg = (struct ree_rd_wr_reg_msg *)((uintptr_t)mdev->mbase + off);
197c88d3638SLiron Himi
198c88d3638SLiron Himi *val = msg->val;
199c88d3638SLiron Himi
200c88d3638SLiron Himi return 0;
201c88d3638SLiron Himi }
202c88d3638SLiron Himi
203c88d3638SLiron Himi int
roc_ree_af_reg_write(struct roc_ree_vf * vf,uint64_t reg,uint64_t val)204c88d3638SLiron Himi roc_ree_af_reg_write(struct roc_ree_vf *vf, uint64_t reg, uint64_t val)
205c88d3638SLiron Himi {
206c88d3638SLiron Himi struct ree_rd_wr_reg_msg *msg;
207c88d3638SLiron Himi struct mbox *mbox;
208c88d3638SLiron Himi
209c88d3638SLiron Himi mbox = vf->dev->mbox;
210c88d3638SLiron Himi msg = (struct ree_rd_wr_reg_msg *)mbox_alloc_msg_rsp(
211c88d3638SLiron Himi mbox, 0, sizeof(*msg), sizeof(*msg));
212c88d3638SLiron Himi if (msg == NULL) {
213c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
214c88d3638SLiron Himi return -EFAULT;
215c88d3638SLiron Himi }
216c88d3638SLiron Himi
217c88d3638SLiron Himi msg->hdr.id = MBOX_MSG_REE_RD_WR_REGISTER;
218c88d3638SLiron Himi msg->hdr.sig = MBOX_REQ_SIG;
219c88d3638SLiron Himi msg->hdr.pcifunc = vf->dev->pf_func;
220c88d3638SLiron Himi msg->is_write = 1;
221c88d3638SLiron Himi msg->reg_offset = reg;
222c88d3638SLiron Himi msg->val = val;
223c88d3638SLiron Himi msg->blkaddr = vf->block_address;
224c88d3638SLiron Himi
225c88d3638SLiron Himi return ree_send_mbox_msg(vf);
226c88d3638SLiron Himi }
227c88d3638SLiron Himi
228c88d3638SLiron Himi int
roc_ree_rule_db_get(struct roc_ree_vf * vf,char * rule_db,uint32_t rule_db_len,char * rule_dbi,uint32_t rule_dbi_len)229c88d3638SLiron Himi roc_ree_rule_db_get(struct roc_ree_vf *vf, char *rule_db, uint32_t rule_db_len,
230c88d3638SLiron Himi char *rule_dbi, uint32_t rule_dbi_len)
231c88d3638SLiron Himi {
232c88d3638SLiron Himi struct ree_rule_db_get_req_msg *req;
233c88d3638SLiron Himi struct ree_rule_db_get_rsp_msg *rsp;
234c88d3638SLiron Himi char *rule_db_ptr = (char *)rule_db;
235c88d3638SLiron Himi struct mbox *mbox;
236c88d3638SLiron Himi int ret, last = 0;
237c88d3638SLiron Himi uint32_t len = 0;
238c88d3638SLiron Himi
239c88d3638SLiron Himi mbox = vf->dev->mbox;
240c88d3638SLiron Himi if (!rule_db) {
241c88d3638SLiron Himi plt_err("Couldn't return rule db due to NULL pointer");
242c88d3638SLiron Himi return -EFAULT;
243c88d3638SLiron Himi }
244c88d3638SLiron Himi
245c88d3638SLiron Himi while (!last) {
246c88d3638SLiron Himi req = (struct ree_rule_db_get_req_msg *)mbox_alloc_msg_rsp(
247c88d3638SLiron Himi mbox, 0, sizeof(*req), sizeof(*rsp));
248c88d3638SLiron Himi if (!req) {
249c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
250c88d3638SLiron Himi return -EFAULT;
251c88d3638SLiron Himi }
252c88d3638SLiron Himi
253c88d3638SLiron Himi req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
254c88d3638SLiron Himi req->hdr.sig = MBOX_REQ_SIG;
255c88d3638SLiron Himi req->hdr.pcifunc = vf->dev->pf_func;
256c88d3638SLiron Himi req->blkaddr = vf->block_address;
257c88d3638SLiron Himi req->is_dbi = 0;
258c88d3638SLiron Himi req->offset = len;
259c88d3638SLiron Himi ret = mbox_process_msg(mbox, (void *)&rsp);
260c88d3638SLiron Himi if (ret)
261c88d3638SLiron Himi return ret;
262c88d3638SLiron Himi if (rule_db_len < len + rsp->len) {
263c88d3638SLiron Himi plt_err("Rule db size is too small");
264c88d3638SLiron Himi return -EFAULT;
265c88d3638SLiron Himi }
266c88d3638SLiron Himi mbox_memcpy(rule_db_ptr, rsp->rule_db, rsp->len);
267c88d3638SLiron Himi len += rsp->len;
268c88d3638SLiron Himi rule_db_ptr = rule_db_ptr + rsp->len;
269c88d3638SLiron Himi last = rsp->is_last;
270c88d3638SLiron Himi }
271c88d3638SLiron Himi
272c88d3638SLiron Himi if (rule_dbi) {
273c88d3638SLiron Himi req = (struct ree_rule_db_get_req_msg *)mbox_alloc_msg_rsp(
274c88d3638SLiron Himi mbox, 0, sizeof(*req), sizeof(*rsp));
275c88d3638SLiron Himi if (!req) {
276c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
277c88d3638SLiron Himi return -EFAULT;
278c88d3638SLiron Himi }
279c88d3638SLiron Himi
280c88d3638SLiron Himi req->hdr.id = MBOX_MSG_REE_RULE_DB_GET;
281c88d3638SLiron Himi req->hdr.sig = MBOX_REQ_SIG;
282c88d3638SLiron Himi req->hdr.pcifunc = vf->dev->pf_func;
283c88d3638SLiron Himi req->blkaddr = vf->block_address;
284c88d3638SLiron Himi req->is_dbi = 1;
285c88d3638SLiron Himi req->offset = 0;
286c88d3638SLiron Himi
287c88d3638SLiron Himi ret = mbox_process_msg(mbox, (void *)&rsp);
288c88d3638SLiron Himi if (ret)
289c88d3638SLiron Himi return ret;
290c88d3638SLiron Himi if (rule_dbi_len < rsp->len) {
291c88d3638SLiron Himi plt_err("Rule dbi size is too small");
292c88d3638SLiron Himi return -EFAULT;
293c88d3638SLiron Himi }
294c88d3638SLiron Himi mbox_memcpy(rule_dbi, rsp->rule_db, rsp->len);
295c88d3638SLiron Himi }
296c88d3638SLiron Himi return 0;
297c88d3638SLiron Himi }
298c88d3638SLiron Himi
299c88d3638SLiron Himi int
roc_ree_rule_db_len_get(struct roc_ree_vf * vf,uint32_t * rule_db_len,uint32_t * rule_dbi_len)300c88d3638SLiron Himi roc_ree_rule_db_len_get(struct roc_ree_vf *vf, uint32_t *rule_db_len,
301c88d3638SLiron Himi uint32_t *rule_dbi_len)
302c88d3638SLiron Himi {
303c88d3638SLiron Himi struct ree_rule_db_len_rsp_msg *rsp;
304c88d3638SLiron Himi struct ree_req_msg *req;
305c88d3638SLiron Himi struct mbox *mbox;
306c88d3638SLiron Himi int ret;
307c88d3638SLiron Himi
308c88d3638SLiron Himi mbox = vf->dev->mbox;
309c88d3638SLiron Himi req = (struct ree_req_msg *)mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
310c88d3638SLiron Himi sizeof(*rsp));
311c88d3638SLiron Himi if (!req) {
312c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
313c88d3638SLiron Himi return -EFAULT;
314c88d3638SLiron Himi }
315c88d3638SLiron Himi
316c88d3638SLiron Himi req->hdr.id = MBOX_MSG_REE_RULE_DB_LEN_GET;
317c88d3638SLiron Himi req->hdr.sig = MBOX_REQ_SIG;
318c88d3638SLiron Himi req->hdr.pcifunc = vf->dev->pf_func;
319c88d3638SLiron Himi req->blkaddr = vf->block_address;
320c88d3638SLiron Himi ret = mbox_process_msg(mbox, (void *)&rsp);
321c88d3638SLiron Himi if (ret)
322c88d3638SLiron Himi return ret;
323c88d3638SLiron Himi if (rule_db_len != NULL)
324c88d3638SLiron Himi *rule_db_len = rsp->len;
325c88d3638SLiron Himi if (rule_dbi_len != NULL)
326c88d3638SLiron Himi *rule_dbi_len = rsp->inc_len;
327c88d3638SLiron Himi
328c88d3638SLiron Himi return 0;
329c88d3638SLiron Himi }
330c88d3638SLiron Himi
331c88d3638SLiron Himi static int
ree_db_msg(struct roc_ree_vf * vf,const char * db,uint32_t db_len,int inc,int dbi)332c88d3638SLiron Himi ree_db_msg(struct roc_ree_vf *vf, const char *db, uint32_t db_len, int inc,
333c88d3638SLiron Himi int dbi)
334c88d3638SLiron Himi {
335c88d3638SLiron Himi uint32_t len_left = db_len, offset = 0;
336c88d3638SLiron Himi struct ree_rule_db_prog_req_msg *req;
337c88d3638SLiron Himi const char *rule_db_ptr = db;
338c88d3638SLiron Himi struct mbox *mbox;
339c88d3638SLiron Himi struct msg_rsp *rsp;
340c88d3638SLiron Himi int ret;
341c88d3638SLiron Himi
342c88d3638SLiron Himi mbox = vf->dev->mbox;
343c88d3638SLiron Himi while (len_left) {
344c88d3638SLiron Himi req = (struct ree_rule_db_prog_req_msg *)mbox_alloc_msg_rsp(
345c88d3638SLiron Himi mbox, 0, sizeof(*req), sizeof(*rsp));
346c88d3638SLiron Himi if (!req) {
347c88d3638SLiron Himi plt_err("Could not allocate mailbox message");
348c88d3638SLiron Himi return -EFAULT;
349c88d3638SLiron Himi }
350c88d3638SLiron Himi req->hdr.id = MBOX_MSG_REE_RULE_DB_PROG;
351c88d3638SLiron Himi req->hdr.sig = MBOX_REQ_SIG;
352c88d3638SLiron Himi req->hdr.pcifunc = vf->dev->pf_func;
353c88d3638SLiron Himi req->offset = offset;
354c88d3638SLiron Himi req->total_len = db_len;
355c88d3638SLiron Himi req->len = REE_RULE_DB_REQ_BLOCK_SIZE;
356c88d3638SLiron Himi req->is_incremental = inc;
357c88d3638SLiron Himi req->is_dbi = dbi;
358c88d3638SLiron Himi req->blkaddr = vf->block_address;
359c88d3638SLiron Himi
360c88d3638SLiron Himi if (len_left < REE_RULE_DB_REQ_BLOCK_SIZE) {
361c88d3638SLiron Himi req->is_last = true;
362c88d3638SLiron Himi req->len = len_left;
363c88d3638SLiron Himi }
364c88d3638SLiron Himi mbox_memcpy(req->rule_db, rule_db_ptr, req->len);
365c88d3638SLiron Himi ret = mbox_process_msg(mbox, (void *)&rsp);
366c88d3638SLiron Himi if (ret) {
367c88d3638SLiron Himi plt_err("Programming mailbox processing failed");
368c88d3638SLiron Himi return ret;
369c88d3638SLiron Himi }
370c88d3638SLiron Himi len_left -= req->len;
371c88d3638SLiron Himi offset += req->len;
372c88d3638SLiron Himi rule_db_ptr = rule_db_ptr + req->len;
373c88d3638SLiron Himi }
374c88d3638SLiron Himi return 0;
375c88d3638SLiron Himi }
376c88d3638SLiron Himi
377c88d3638SLiron Himi int
roc_ree_rule_db_prog(struct roc_ree_vf * vf,const char * rule_db,uint32_t rule_db_len,const char * rule_dbi,uint32_t rule_dbi_len)378c88d3638SLiron Himi roc_ree_rule_db_prog(struct roc_ree_vf *vf, const char *rule_db,
379c88d3638SLiron Himi uint32_t rule_db_len, const char *rule_dbi,
380c88d3638SLiron Himi uint32_t rule_dbi_len)
381c88d3638SLiron Himi {
382c88d3638SLiron Himi int inc, ret;
383c88d3638SLiron Himi
384c88d3638SLiron Himi if (rule_db_len == 0) {
385c88d3638SLiron Himi plt_err("Couldn't program empty rule db");
386c88d3638SLiron Himi return -EFAULT;
387c88d3638SLiron Himi }
388c88d3638SLiron Himi inc = (rule_dbi_len != 0);
389c88d3638SLiron Himi if ((rule_db == NULL) || (inc && (rule_dbi == NULL))) {
390c88d3638SLiron Himi plt_err("Couldn't program NULL rule db");
391c88d3638SLiron Himi return -EFAULT;
392c88d3638SLiron Himi }
393c88d3638SLiron Himi if (inc) {
394c88d3638SLiron Himi ret = ree_db_msg(vf, rule_dbi, rule_dbi_len, inc, 1);
395c88d3638SLiron Himi if (ret)
396c88d3638SLiron Himi return ret;
397c88d3638SLiron Himi }
398c88d3638SLiron Himi return ree_db_msg(vf, rule_db, rule_db_len, inc, 0);
399c88d3638SLiron Himi }
400c88d3638SLiron Himi
401c88d3638SLiron Himi static int
ree_get_blkaddr(struct dev * dev)402c88d3638SLiron Himi ree_get_blkaddr(struct dev *dev)
403c88d3638SLiron Himi {
404c88d3638SLiron Himi int pf;
405c88d3638SLiron Himi
406c88d3638SLiron Himi pf = dev_get_pf(dev->pf_func);
407c88d3638SLiron Himi if (pf == REE0_PF)
408c88d3638SLiron Himi return RVU_BLOCK_ADDR_REE0;
409c88d3638SLiron Himi else if (pf == REE1_PF)
410c88d3638SLiron Himi return RVU_BLOCK_ADDR_REE1;
411c88d3638SLiron Himi else
412c88d3638SLiron Himi return 0;
413c88d3638SLiron Himi }
414c88d3638SLiron Himi
415c88d3638SLiron Himi uintptr_t
roc_ree_qp_get_base(struct roc_ree_vf * vf,uint16_t qp_id)416c88d3638SLiron Himi roc_ree_qp_get_base(struct roc_ree_vf *vf, uint16_t qp_id)
417c88d3638SLiron Himi {
418c88d3638SLiron Himi return REE_LF_BAR2(vf, qp_id);
419c88d3638SLiron Himi }
420c88d3638SLiron Himi
421c88d3638SLiron Himi static void
roc_ree_lf_err_intr_handler(void * param)422c88d3638SLiron Himi roc_ree_lf_err_intr_handler(void *param)
423c88d3638SLiron Himi {
424c88d3638SLiron Himi uintptr_t base = (uintptr_t)param;
425c88d3638SLiron Himi uint8_t lf_id;
426c88d3638SLiron Himi uint64_t intr;
427c88d3638SLiron Himi
428c88d3638SLiron Himi lf_id = (base >> 12) & 0xFF;
429c88d3638SLiron Himi
430c88d3638SLiron Himi intr = plt_read64(base + REE_LF_MISC_INT);
431c88d3638SLiron Himi if (intr == 0)
432c88d3638SLiron Himi return;
433c88d3638SLiron Himi
434c88d3638SLiron Himi plt_ree_dbg("LF %d MISC_INT: 0x%" PRIx64 "", lf_id, intr);
435c88d3638SLiron Himi
436c88d3638SLiron Himi /* Clear interrupt */
437c88d3638SLiron Himi plt_write64(intr, base + REE_LF_MISC_INT);
438c88d3638SLiron Himi }
439c88d3638SLiron Himi
440c88d3638SLiron Himi static void
roc_ree_lf_err_intr_unregister(struct roc_ree_vf * vf,uint16_t msix_off,uintptr_t base)441c88d3638SLiron Himi roc_ree_lf_err_intr_unregister(struct roc_ree_vf *vf, uint16_t msix_off,
442c88d3638SLiron Himi uintptr_t base)
443c88d3638SLiron Himi {
444*7557e3f5SJerin Jacob struct plt_pci_device *pci_dev = vf->pci_dev;
445c88d3638SLiron Himi
446c88d3638SLiron Himi /* Disable error interrupts */
447c88d3638SLiron Himi plt_write64(~0ull, base + REE_LF_MISC_INT_ENA_W1C);
448c88d3638SLiron Himi
449c88d3638SLiron Himi dev_irq_unregister(pci_dev->intr_handle,
450c88d3638SLiron Himi roc_ree_lf_err_intr_handler, (void *)base, msix_off);
451c88d3638SLiron Himi }
452c88d3638SLiron Himi
453c88d3638SLiron Himi void
roc_ree_err_intr_unregister(struct roc_ree_vf * vf)454c88d3638SLiron Himi roc_ree_err_intr_unregister(struct roc_ree_vf *vf)
455c88d3638SLiron Himi {
456c88d3638SLiron Himi uintptr_t base;
457c88d3638SLiron Himi uint32_t i;
458c88d3638SLiron Himi
459c88d3638SLiron Himi for (i = 0; i < vf->nb_queues; i++) {
460c88d3638SLiron Himi base = REE_LF_BAR2(vf, i);
461c88d3638SLiron Himi roc_ree_lf_err_intr_unregister(vf, vf->lf_msixoff[i], base);
462c88d3638SLiron Himi }
463c88d3638SLiron Himi
464c88d3638SLiron Himi vf->err_intr_registered = 0;
465c88d3638SLiron Himi }
466c88d3638SLiron Himi
467c88d3638SLiron Himi static int
roc_ree_lf_err_intr_register(struct roc_ree_vf * vf,uint16_t msix_off,uintptr_t base)468c88d3638SLiron Himi roc_ree_lf_err_intr_register(struct roc_ree_vf *vf, uint16_t msix_off,
469c88d3638SLiron Himi uintptr_t base)
470c88d3638SLiron Himi {
471*7557e3f5SJerin Jacob struct plt_pci_device *pci_dev = vf->pci_dev;
472c88d3638SLiron Himi int ret;
473c88d3638SLiron Himi
474c88d3638SLiron Himi /* Disable error interrupts */
475c88d3638SLiron Himi plt_write64(~0ull, base + REE_LF_MISC_INT_ENA_W1C);
476c88d3638SLiron Himi
477c88d3638SLiron Himi /* Register error interrupt handler */
478c88d3638SLiron Himi ret = dev_irq_register(pci_dev->intr_handle,
479c88d3638SLiron Himi roc_ree_lf_err_intr_handler, (void *)base,
480c88d3638SLiron Himi msix_off);
481c88d3638SLiron Himi if (ret)
482c88d3638SLiron Himi return ret;
483c88d3638SLiron Himi
484c88d3638SLiron Himi /* Enable error interrupts */
485c88d3638SLiron Himi plt_write64(~0ull, base + REE_LF_MISC_INT_ENA_W1S);
486c88d3638SLiron Himi
487c88d3638SLiron Himi return 0;
488c88d3638SLiron Himi }
489c88d3638SLiron Himi
490c88d3638SLiron Himi int
roc_ree_err_intr_register(struct roc_ree_vf * vf)491c88d3638SLiron Himi roc_ree_err_intr_register(struct roc_ree_vf *vf)
492c88d3638SLiron Himi {
493c88d3638SLiron Himi uint32_t i, j, ret;
494c88d3638SLiron Himi uintptr_t base;
495c88d3638SLiron Himi
496c88d3638SLiron Himi for (i = 0; i < vf->nb_queues; i++) {
497c88d3638SLiron Himi if (vf->lf_msixoff[i] == MSIX_VECTOR_INVALID) {
498c88d3638SLiron Himi plt_err("Invalid REE LF MSI-X offset: 0x%x",
499c88d3638SLiron Himi vf->lf_msixoff[i]);
500c88d3638SLiron Himi return -EINVAL;
501c88d3638SLiron Himi }
502c88d3638SLiron Himi }
503c88d3638SLiron Himi
504c88d3638SLiron Himi for (i = 0; i < vf->nb_queues; i++) {
505c88d3638SLiron Himi base = REE_LF_BAR2(vf, i);
506c88d3638SLiron Himi ret = roc_ree_lf_err_intr_register(vf, vf->lf_msixoff[i], base);
507c88d3638SLiron Himi if (ret)
508c88d3638SLiron Himi goto intr_unregister;
509c88d3638SLiron Himi }
510c88d3638SLiron Himi
511c88d3638SLiron Himi vf->err_intr_registered = 1;
512c88d3638SLiron Himi return 0;
513c88d3638SLiron Himi
514c88d3638SLiron Himi intr_unregister:
515c88d3638SLiron Himi /* Unregister the ones already registered */
516c88d3638SLiron Himi for (j = 0; j < i; j++) {
517c88d3638SLiron Himi base = REE_LF_BAR2(vf, j);
518c88d3638SLiron Himi roc_ree_lf_err_intr_unregister(vf, vf->lf_msixoff[j], base);
519c88d3638SLiron Himi }
520c88d3638SLiron Himi return ret;
521c88d3638SLiron Himi }
522c88d3638SLiron Himi
523c88d3638SLiron Himi int
roc_ree_iq_enable(struct roc_ree_vf * vf,const struct roc_ree_qp * qp,uint8_t pri,uint32_t size_div2)524c88d3638SLiron Himi roc_ree_iq_enable(struct roc_ree_vf *vf, const struct roc_ree_qp *qp,
525c88d3638SLiron Himi uint8_t pri, uint32_t size_div2)
526c88d3638SLiron Himi {
527c88d3638SLiron Himi uint64_t val;
528c88d3638SLiron Himi
529c88d3638SLiron Himi /* Set instruction queue size and priority */
530c88d3638SLiron Himi roc_ree_config_lf(vf, qp->id, pri, size_div2);
531c88d3638SLiron Himi
532c88d3638SLiron Himi /* Set instruction queue base address */
533c88d3638SLiron Himi /* Should be written after SBUF_CTL and before LF_ENA */
534c88d3638SLiron Himi
535c88d3638SLiron Himi val = plt_read64(qp->base + REE_LF_SBUF_ADDR);
536c88d3638SLiron Himi val &= ~REE_LF_SBUF_ADDR_PTR_MASK;
537c88d3638SLiron Himi val |= FIELD_PREP(REE_LF_SBUF_ADDR_PTR_MASK, qp->iq_dma_addr >> 7);
538c88d3638SLiron Himi plt_write64(val, qp->base + REE_LF_SBUF_ADDR);
539c88d3638SLiron Himi
540c88d3638SLiron Himi /* Enable instruction queue */
541c88d3638SLiron Himi
542c88d3638SLiron Himi val = plt_read64(qp->base + REE_LF_ENA);
543c88d3638SLiron Himi val &= ~REE_LF_ENA_ENA_MASK;
544c88d3638SLiron Himi val |= FIELD_PREP(REE_LF_ENA_ENA_MASK, 1);
545c88d3638SLiron Himi plt_write64(val, qp->base + REE_LF_ENA);
546c88d3638SLiron Himi
547c88d3638SLiron Himi return 0;
548c88d3638SLiron Himi }
549c88d3638SLiron Himi
550c88d3638SLiron Himi void
roc_ree_iq_disable(struct roc_ree_qp * qp)551c88d3638SLiron Himi roc_ree_iq_disable(struct roc_ree_qp *qp)
552c88d3638SLiron Himi {
553c88d3638SLiron Himi uint64_t val;
554c88d3638SLiron Himi
555c88d3638SLiron Himi /* Stop instruction execution */
556c88d3638SLiron Himi val = plt_read64(qp->base + REE_LF_ENA);
557c88d3638SLiron Himi val &= ~REE_LF_ENA_ENA_MASK;
558c88d3638SLiron Himi val |= FIELD_PREP(REE_LF_ENA_ENA_MASK, 0);
559c88d3638SLiron Himi plt_write64(val, qp->base + REE_LF_ENA);
560c88d3638SLiron Himi }
561c88d3638SLiron Himi
562c88d3638SLiron Himi int
roc_ree_dev_init(struct roc_ree_vf * vf)563c88d3638SLiron Himi roc_ree_dev_init(struct roc_ree_vf *vf)
564c88d3638SLiron Himi {
565c88d3638SLiron Himi struct plt_pci_device *pci_dev;
566c88d3638SLiron Himi struct ree *ree;
567c88d3638SLiron Himi struct dev *dev;
568c88d3638SLiron Himi uint8_t max_matches = 0;
569c88d3638SLiron Himi uint16_t nb_queues = 0;
570c88d3638SLiron Himi int rc;
571c88d3638SLiron Himi
572c88d3638SLiron Himi if (vf == NULL || vf->pci_dev == NULL)
573c88d3638SLiron Himi return -EINVAL;
574c88d3638SLiron Himi
575c88d3638SLiron Himi PLT_STATIC_ASSERT(sizeof(struct ree) <= ROC_REE_MEM_SZ);
576c88d3638SLiron Himi
577c88d3638SLiron Himi ree = roc_ree_to_ree_priv(vf);
578c88d3638SLiron Himi memset(ree, 0, sizeof(*ree));
579c88d3638SLiron Himi vf->dev = &ree->dev;
580c88d3638SLiron Himi
581c88d3638SLiron Himi pci_dev = vf->pci_dev;
582c88d3638SLiron Himi dev = vf->dev;
583c88d3638SLiron Himi
584c88d3638SLiron Himi /* Initialize device */
585c88d3638SLiron Himi rc = dev_init(dev, pci_dev);
586c88d3638SLiron Himi if (rc) {
587c88d3638SLiron Himi plt_err("Failed to init roc device");
588c88d3638SLiron Himi goto fail;
589c88d3638SLiron Himi }
590c88d3638SLiron Himi
591c88d3638SLiron Himi /* Get REE block address */
592c88d3638SLiron Himi vf->block_address = ree_get_blkaddr(dev);
593c88d3638SLiron Himi if (!vf->block_address) {
594c88d3638SLiron Himi plt_err("Could not determine block PF number");
595c88d3638SLiron Himi goto fail;
596c88d3638SLiron Himi }
597c88d3638SLiron Himi
598c88d3638SLiron Himi /* Get number of queues available on the device */
599c88d3638SLiron Himi rc = roc_ree_available_queues_get(vf, &nb_queues);
600c88d3638SLiron Himi if (rc) {
601c88d3638SLiron Himi plt_err("Could not determine the number of queues available");
602c88d3638SLiron Himi goto fail;
603c88d3638SLiron Himi }
604c88d3638SLiron Himi
605c88d3638SLiron Himi /* Don't exceed the limits set per VF */
606c88d3638SLiron Himi nb_queues = RTE_MIN(nb_queues, REE_MAX_QUEUES_PER_VF);
607c88d3638SLiron Himi
608c88d3638SLiron Himi if (nb_queues == 0) {
609c88d3638SLiron Himi plt_err("No free queues available on the device");
610c88d3638SLiron Himi goto fail;
611c88d3638SLiron Himi }
612c88d3638SLiron Himi
613c88d3638SLiron Himi vf->max_queues = nb_queues;
614c88d3638SLiron Himi
615c88d3638SLiron Himi plt_ree_dbg("Max queues supported by device: %d", vf->max_queues);
616c88d3638SLiron Himi
617c88d3638SLiron Himi /* Get number of maximum matches supported on the device */
618c88d3638SLiron Himi rc = roc_ree_max_matches_get(vf, &max_matches);
619c88d3638SLiron Himi if (rc) {
620c88d3638SLiron Himi plt_err("Could not determine the maximum matches supported");
621c88d3638SLiron Himi goto fail;
622c88d3638SLiron Himi }
623c88d3638SLiron Himi /* Don't exceed the limits set per VF */
624c88d3638SLiron Himi max_matches = RTE_MIN(max_matches, REE_MAX_MATCHES_PER_VF);
625c88d3638SLiron Himi if (max_matches == 0) {
626c88d3638SLiron Himi plt_err("Could not determine the maximum matches supported");
627c88d3638SLiron Himi goto fail;
628c88d3638SLiron Himi }
629c88d3638SLiron Himi
630c88d3638SLiron Himi vf->max_matches = max_matches;
631c88d3638SLiron Himi
632c88d3638SLiron Himi plt_ree_dbg("Max matches supported by device: %d", vf->max_matches);
633c88d3638SLiron Himi fail:
634c88d3638SLiron Himi return rc;
635c88d3638SLiron Himi }
636c88d3638SLiron Himi
637c88d3638SLiron Himi int
roc_ree_dev_fini(struct roc_ree_vf * vf)638c88d3638SLiron Himi roc_ree_dev_fini(struct roc_ree_vf *vf)
639c88d3638SLiron Himi {
640c88d3638SLiron Himi if (vf == NULL)
641c88d3638SLiron Himi return -EINVAL;
642c88d3638SLiron Himi
643c88d3638SLiron Himi vf->max_matches = 0;
644c88d3638SLiron Himi vf->max_queues = 0;
645c88d3638SLiron Himi
646c88d3638SLiron Himi return dev_fini(vf->dev, vf->pci_dev);
647c88d3638SLiron Himi }
648