1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
12 #include <sys/param.h>
14 #include <sys/ioctl.h>
17 #include <rte_common.h>
18 #include <rte_errno.h>
23 #include "tf_common.h"
25 #include "tf_em_common.h"
29 #include "tf_ext_flow_handle.h"
34 TF_EM_BNXT_LFC_CFA_EEM_DMABUF_EXPORT_REQ = 5,
37 struct tf_em_bnxt_lfc_req_hdr {
41 enum tf_em_req_type req_type;
44 struct tf_em_bnxt_lfc_cfa_eem_std_hdr {
48 #define TF_EM_BNXT_LFC_EEM_CFG_PRIMARY_FUNC (1 << 0)
51 struct tf_em_bnxt_lfc_dmabuf_fd {
52 int fd[TF_DIR_MAX][TF_MAX_TABLE];
59 struct tf_em_bnxt_lfc_cfa_eem_dmabuf_export_req {
60 struct tf_em_bnxt_lfc_cfa_eem_std_hdr std;
66 struct tf_em_bnxt_lfc_req {
67 struct tf_em_bnxt_lfc_req_hdr hdr;
69 struct tf_em_bnxt_lfc_cfa_eem_dmabuf_export_req
70 eem_dmabuf_export_req;
75 #define TF_EEM_BNXT_LFC_IOCTL_MAGIC 0x98
76 #define BNXT_LFC_REQ \
77 _IOW(TF_EEM_BNXT_LFC_IOCTL_MAGIC, 1, struct tf_em_bnxt_lfc_req)
82 extern void *eem_db[TF_DIR_MAX];
84 extern struct tf_tbl_scope_cb tbl_scopes[TF_NUM_TBL_SCOPE];
87 tf_em_dmabuf_mem_unmap(struct hcapi_cfa_em_table *tbl)
89 struct hcapi_cfa_em_page_tbl *tp;
91 uint32_t page_no, pg_count;
93 for (level = (tbl->num_lvl - 1); level < tbl->num_lvl; level++) {
94 tp = &tbl->pg_tbl[level];
96 pg_count = tbl->page_cnt[level];
97 for (page_no = 0; page_no < pg_count; page_no++) {
98 if (tp->pg_va_tbl != NULL &&
99 tp->pg_va_tbl[page_no] != NULL &&
101 (void)munmap(tp->pg_va_tbl[page_no],
106 tfp_free((void *)tp->pg_va_tbl);
107 tfp_free((void *)tp->pg_pa_tbl);
112 * Unregisters EM Ctx in Firmware
115 * Pointer to a TruFlow handle
118 * Pointer to a table scope control block
121 * Receive or transmit direction
124 tf_em_ctx_unreg(struct tf_tbl_scope_cb *tbl_scope_cb,
127 struct hcapi_cfa_em_ctx_mem_info *ctxp =
128 &tbl_scope_cb->em_ctx_info[dir];
129 struct hcapi_cfa_em_table *tbl;
132 for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
133 tbl = &ctxp->em_tables[i];
134 tf_em_dmabuf_mem_unmap(tbl);
138 static int tf_export_tbl_scope(int lfc_fd,
143 struct tf_em_bnxt_lfc_req tf_lfc_req;
144 struct tf_em_bnxt_lfc_dmabuf_fd *dma_fd;
145 struct tfp_calloc_parms mparms;
148 memset(&tf_lfc_req, 0, sizeof(struct tf_em_bnxt_lfc_req));
149 tf_lfc_req.hdr.ver = 1;
150 tf_lfc_req.hdr.bus = bus;
151 tf_lfc_req.hdr.devfn = devfn;
152 tf_lfc_req.hdr.req_type = TF_EM_BNXT_LFC_CFA_EEM_DMABUF_EXPORT_REQ;
153 tf_lfc_req.req.eem_dmabuf_export_req.flags = O_ACCMODE;
154 tf_lfc_req.req.eem_dmabuf_export_req.std.version = 1;
157 mparms.size = sizeof(struct tf_em_bnxt_lfc_dmabuf_fd);
158 mparms.alignment = 0;
160 dma_fd = (struct tf_em_bnxt_lfc_dmabuf_fd *)mparms.mem_va;
161 tf_lfc_req.req.eem_dmabuf_export_req.dma_fd = dma_fd;
163 rc = ioctl(lfc_fd, BNXT_LFC_REQ, &tf_lfc_req);
166 "EXT EEM export chanel_fd %d, rc=%d\n",
173 memcpy(fd, dma_fd->fd, sizeof(dma_fd->fd));
180 tf_em_dmabuf_mem_map(struct hcapi_cfa_em_table *tbl,
183 struct hcapi_cfa_em_page_tbl *tp;
188 struct tfp_calloc_parms parms;
190 for (level = (tbl->num_lvl - 1); level < tbl->num_lvl; level++) {
191 tp = &tbl->pg_tbl[level];
193 pg_count = tbl->page_cnt[level];
196 parms.nitems = pg_count;
197 parms.size = sizeof(void *);
200 if ((tfp_calloc(&parms)) != 0)
203 tp->pg_va_tbl = parms.mem_va;
204 parms.nitems = pg_count;
205 parms.size = sizeof(void *);
208 if ((tfp_calloc(&parms)) != 0) {
209 tfp_free((void *)tp->pg_va_tbl);
213 tp->pg_pa_tbl = parms.mem_va;
215 tp->pg_size = TF_EM_PAGE_SIZE;
217 for (page_no = 0; page_no < pg_count; page_no++) {
218 tp->pg_va_tbl[page_no] = mmap(NULL,
220 PROT_READ | PROT_WRITE,
224 if (tp->pg_va_tbl[page_no] == (void *)-1) {
226 "MMap memory error. level:%d page:%d pg_count:%d - %s\n",
233 offset += tp->pg_size;
241 static int tf_mmap_tbl_scope(struct tf_tbl_scope_cb *tbl_scope_cb,
246 struct hcapi_cfa_em_table *tbl;
248 if (tbl_type == TF_EFC_TABLE)
251 tbl = &tbl_scope_cb->em_ctx_info[dir].em_tables[tbl_type];
252 return tf_em_dmabuf_mem_map(tbl, dmabuf_fd);
255 #define TF_LFC_DEVICE "/dev/bnxt_lfc"
258 tf_prepare_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)
262 lfc_fd = open(TF_LFC_DEVICE, O_RDWR);
265 "EEM: open %s device error\n",
270 tbl_scope_cb->lfc_fd = lfc_fd;
276 offload_system_mmap(struct tf_tbl_scope_cb *tbl_scope_cb)
281 enum hcapi_cfa_em_table_type tbl_type;
283 rc = tf_prepare_dmabuf_bnxt_lfc_device(tbl_scope_cb);
285 TFP_DRV_LOG(ERR, "EEM: Prepare bnxt_lfc channel failed\n");
289 rc = tf_export_tbl_scope(tbl_scope_cb->lfc_fd,
290 (int *)tbl_scope_cb->fd,
292 tbl_scope_cb->devfn);
295 "export dmabuf fd failed\n");
299 tbl_scope_cb->valid = true;
301 for (dir = 0; dir < TF_DIR_MAX; dir++) {
302 for (tbl_type = TF_KEY0_TABLE; tbl_type <
303 TF_MAX_TABLE; tbl_type++) {
304 if (tbl_type == TF_EFC_TABLE)
307 dmabuf_fd = tbl_scope_cb->fd[(dir ? 0 : 1)][tbl_type];
308 rc = tf_mmap_tbl_scope(tbl_scope_cb,
314 "dir:%d tbl:%d mmap failed rc %d\n",
326 tf_destroy_dmabuf_bnxt_lfc_device(struct tf_tbl_scope_cb *tbl_scope_cb)
328 close(tbl_scope_cb->lfc_fd);
334 tf_dmabuf_alloc(struct tf *tfp, struct tf_tbl_scope_cb *tbl_scope_cb)
338 rc = tfp_msg_hwrm_oem_cmd(tfp,
339 tbl_scope_cb->em_ctx_info[TF_DIR_RX].em_tables[TF_KEY0_TABLE].num_entries);
341 PMD_DRV_LOG(ERR, "EEM: Failed to prepare system memory rc:%d\n",
348 tf_dmabuf_free(struct tf *tfp, struct tf_tbl_scope_cb *tbl_scope_cb)
352 rc = tfp_msg_hwrm_oem_cmd(tfp, 0);
354 TFP_DRV_LOG(ERR, "EEM: Failed to cleanup system memory\n");
356 tf_destroy_dmabuf_bnxt_lfc_device(tbl_scope_cb);
362 tf_em_ext_alloc(struct tf *tfp,
363 struct tf_alloc_tbl_scope_parms *parms)
366 struct tf_session *tfs;
367 struct tf_tbl_scope_cb *tbl_scope_cb;
368 struct tf_rm_allocate_parms aparms = { 0 };
369 struct tf_free_tbl_scope_parms free_parms;
370 struct tf_rm_free_parms fparms = { 0 };
373 struct hcapi_cfa_em_table *em_tables;
375 TF_CHECK_PARMS2(tfp, parms);
377 /* Retrieve the session information */
378 rc = tf_session_get_session(tfp, &tfs);
381 "Failed to lookup session, rc:%s\n",
386 aparms.rm_db = eem_db[TF_DIR_RX];
387 aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
388 aparms.index = (uint32_t *)&parms->tbl_scope_id;
389 rc = tf_rm_allocate(&aparms);
392 "Failed to allocate table scope\n");
396 tbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];
397 tbl_scope_cb->index = parms->tbl_scope_id;
398 tbl_scope_cb->tbl_scope_id = parms->tbl_scope_id;
399 tbl_scope_cb->bus = tfs->session_id.internal.bus;
400 tbl_scope_cb->devfn = tfs->session_id.internal.device;
402 for (dir = 0; dir < TF_DIR_MAX; dir++) {
403 rc = tf_msg_em_qcaps(tfp,
405 &tbl_scope_cb->em_caps[dir]);
408 "EEM: Unable to query for EEM capability,"
416 * Validate and setup table sizes
418 if (tf_em_validate_num_entries(tbl_scope_cb, parms))
421 rc = tf_dmabuf_alloc(tfp, tbl_scope_cb);
424 "System DMA buff alloc failed\n");
428 for (dir = 0; dir < TF_DIR_MAX; dir++) {
429 for (i = TF_KEY0_TABLE; i < TF_MAX_TABLE; i++) {
430 if (i == TF_EFC_TABLE)
434 &tbl_scope_cb->em_ctx_info[dir].em_tables[i];
436 rc = tf_em_size_table(em_tables, TF_EM_PAGE_SIZE);
438 TFP_DRV_LOG(ERR, "Size table failed\n");
443 em_tables = tbl_scope_cb->em_ctx_info[dir].em_tables;
444 rc = tf_create_tbl_pool_external(dir,
446 em_tables[TF_RECORD_TABLE].num_entries,
447 em_tables[TF_RECORD_TABLE].entry_size);
451 "%s TBL: Unable to allocate idx pools %s\n",
458 rc = offload_system_mmap(tbl_scope_cb);
462 "System alloc mmap failed\n");
469 free_parms.tbl_scope_id = parms->tbl_scope_id;
470 tf_em_ext_free(tfp, &free_parms);
474 /* Free Table control block */
475 fparms.rm_db = eem_db[TF_DIR_RX];
476 fparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
477 fparms.index = parms->tbl_scope_id;
483 tf_em_ext_free(struct tf *tfp,
484 struct tf_free_tbl_scope_parms *parms)
487 struct tf_session *tfs;
488 struct tf_tbl_scope_cb *tbl_scope_cb;
490 struct tf_rm_free_parms aparms = { 0 };
492 TF_CHECK_PARMS2(tfp, parms);
494 /* Retrieve the session information */
495 rc = tf_session_get_session(tfp, &tfs);
498 "Failed to lookup session, rc:%s\n",
503 tbl_scope_cb = &tbl_scopes[parms->tbl_scope_id];
505 /* Free Table control block */
506 aparms.rm_db = eem_db[TF_DIR_RX];
507 aparms.db_index = TF_EM_TBL_TYPE_TBL_SCOPE;
508 aparms.index = parms->tbl_scope_id;
509 rc = tf_rm_free(&aparms);
512 "Failed to free table scope\n");
515 for (dir = 0; dir < TF_DIR_MAX; dir++) {
516 /* Free associated external pools
518 tf_destroy_tbl_pool_external(dir,
522 tf_em_ctx_unreg(tbl_scope_cb, dir);
526 HWRM_TF_EXT_EM_OP_INPUT_OP_EXT_EM_DISABLE);
529 tf_dmabuf_free(tfp, tbl_scope_cb);