SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_matcher.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_rte_parser.c
SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/bnxt_ulp_flow.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += tf_ulp/ulp_port_db.c
#
# Export include files
'tf_ulp/ulp_matcher.c',
'tf_ulp/ulp_rte_parser.c',
'tf_ulp/bnxt_ulp_flow.c',
+ 'tf_ulp/ulp_port_db.c',
'rte_pmd_bnxt.c')
#include "ulp_mark_mgr.h"
#include "ulp_flow_db.h"
#include "ulp_mapper.h"
+#include "ulp_port_db.h"
/* Linked list of all TF sessions. */
STAILQ_HEAD(, bnxt_ulp_session_state) bnxt_ulp_session_list =
if (rc) {
BNXT_TF_DBG(ERR,
"Failed to attach the ulp context\n");
+ return rc;
+ }
+ /* update the port database */
+ rc = ulp_port_db_dev_port_intf_update(&bp->ulp_ctx, bp);
+ if (rc) {
+ BNXT_TF_DBG(ERR,
+ "Failed to update port database\n");
}
return rc;
}
goto jump_to_error;
}
+ /* create the port database */
+ rc = ulp_port_db_init(&bp->ulp_ctx);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to create the port database\n");
+ goto jump_to_error;
+ }
+
+ /* update the port database */
+ rc = ulp_port_db_dev_port_intf_update(&bp->ulp_ctx, bp);
+ if (rc) {
+ BNXT_TF_DBG(ERR, "Failed to update port database\n");
+ goto jump_to_error;
+ }
+
/* Create the Mark database. */
rc = ulp_mark_db_init(&bp->ulp_ctx);
if (rc) {
/* cleanup the ulp mapper */
ulp_mapper_deinit(&bp->ulp_ctx);
+ /* Delete the Port database */
+ ulp_port_db_deinit(&bp->ulp_ctx);
+
/* Delete the ulp context and tf session */
ulp_ctx_detach(bp, session);
return ulp_ctx->cfg_data->mapper_data;
}
+
+/* Function to set the port database to the ulp context. */
+int32_t
+bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
+ struct bnxt_ulp_port_db *port_db)
+{
+ if (!ulp_ctx || !ulp_ctx->cfg_data)
+ return -EINVAL;
+
+ ulp_ctx->cfg_data->port_db = port_db;
+ return 0;
+}
+
+/* Function to get the port database from the ulp context. */
+struct bnxt_ulp_port_db *
+bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx)
+{
+ if (!ulp_ctx || !ulp_ctx->cfg_data)
+ return NULL;
+
+ return ulp_ctx->cfg_data->port_db;
+}
uint32_t ref_cnt;
struct bnxt_ulp_flow_db *flow_db;
void *mapper_data;
+ struct bnxt_ulp_port_db *port_db;
};
struct bnxt_ulp_context {
void *
bnxt_ulp_cntxt_ptr2_mapper_data_get(struct bnxt_ulp_context *ulp_ctx);
+/* Function to set the port database to the ulp context. */
+int32_t
+bnxt_ulp_cntxt_ptr2_port_db_set(struct bnxt_ulp_context *ulp_ctx,
+ struct bnxt_ulp_port_db *port_db);
+
+/* Function to get the port database from the ulp context. */
+struct bnxt_ulp_port_db *
+bnxt_ulp_cntxt_ptr2_port_db_get(struct bnxt_ulp_context *ulp_ctx);
+
#endif /* _BNXT_ULP_H_ */
{
struct bnxt_ulp_mapper_create_parms mapper_cparms = { 0 };
struct ulp_rte_parser_params params;
- struct bnxt_ulp_context *ulp_ctx = NULL;
+ struct bnxt_ulp_context *ulp_ctx;
uint32_t class_id, act_tmpl;
struct rte_flow *flow_id;
uint32_t fid;
/* Initialize the parser params */
memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
+ params.ulp_ctx = ulp_ctx;
if (attr->egress)
params.dir = ULP_DIR_EGRESS;
/* Function to validate the rte flow. */
static int
-bnxt_ulp_flow_validate(struct rte_eth_dev *dev __rte_unused,
+bnxt_ulp_flow_validate(struct rte_eth_dev *dev,
const struct rte_flow_attr *attr,
const struct rte_flow_item pattern[],
const struct rte_flow_action actions[],
struct ulp_rte_parser_params params;
uint32_t class_id, act_tmpl;
int ret;
+ struct bnxt_ulp_context *ulp_ctx;
if (bnxt_ulp_flow_validate_args(attr,
pattern, actions,
return -EINVAL;
}
+ ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
+ if (!ulp_ctx) {
+ BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
+ return -EINVAL;
+ }
+
/* Initialize the parser params */
memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
+ params.ulp_ctx = ulp_ctx;
if (attr->egress)
params.dir = ULP_DIR_EGRESS;
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2020 Broadcom
+ * All rights reserved.
+ */
+
+#include <rte_malloc.h>
+#include "bnxt.h"
+#include "bnxt_vnic.h"
+#include "bnxt_tf_common.h"
+#include "ulp_port_db.h"
+
+static uint32_t
+ulp_port_db_allocate_ifindex(struct bnxt_ulp_port_db *port_db)
+{
+ uint32_t idx = 1;
+
+ while (idx < port_db->ulp_intf_list_size &&
+ port_db->ulp_intf_list[idx].type != BNXT_ULP_INTF_TYPE_INVALID)
+ idx++;
+
+ if (idx >= port_db->ulp_intf_list_size) {
+ BNXT_TF_DBG(ERR, "Port DB interface list is full\n");
+ return 0;
+ }
+ return idx;
+}
+
+/*
+ * Initialize the port database. Memory is allocated in this
+ * call and assigned to the port database.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt)
+{
+ struct bnxt_ulp_port_db *port_db;
+
+ port_db = rte_zmalloc("bnxt_ulp_port_db",
+ sizeof(struct bnxt_ulp_port_db), 0);
+ if (!port_db) {
+ BNXT_TF_DBG(ERR,
+ "Failed to allocate memory for port db\n");
+ return -ENOMEM;
+ }
+
+ /* Attach the port database to the ulp context. */
+ bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, port_db);
+
+ /* index 0 is not being used hence add 1 to size */
+ port_db->ulp_intf_list_size = BNXT_PORT_DB_MAX_INTF_LIST + 1;
+ /* Allocate the port tables */
+ port_db->ulp_intf_list = rte_zmalloc("bnxt_ulp_port_db_intf_list",
+ port_db->ulp_intf_list_size *
+ sizeof(struct ulp_interface_info),
+ 0);
+ if (!port_db->ulp_intf_list) {
+ BNXT_TF_DBG(ERR,
+ "Failed to allocate mem for port interface list\n");
+ goto error_free;
+ }
+ return 0;
+
+error_free:
+ ulp_port_db_deinit(ulp_ctxt);
+ return -ENOMEM;
+}
+
+/*
+ * Deinitialize the port database. Memory is deallocated in
+ * this call.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ *
+ * Returns 0 on success.
+ */
+int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
+{
+ struct bnxt_ulp_port_db *port_db;
+
+ port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
+ if (!port_db) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+
+ /* Detach the flow database from the ulp context. */
+ bnxt_ulp_cntxt_ptr2_port_db_set(ulp_ctxt, NULL);
+
+ /* Free up all the memory. */
+ rte_free(port_db->ulp_intf_list);
+ rte_free(port_db);
+ return 0;
+}
+
+/*
+ * Update the port database.This api is called when the port
+ * details are available during the startup.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * bp [in]. ptr to the device function.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt,
+ struct bnxt *bp)
+{
+ struct bnxt_ulp_port_db *port_db;
+ uint32_t port_id = bp->eth_dev->data->port_id;
+ uint32_t ifindex;
+ struct ulp_interface_info *intf;
+ int32_t rc;
+ struct bnxt_vnic_info *vnic;
+
+ port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
+ if (!port_db) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+
+ rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctxt, port_id, &ifindex);
+ if (rc == -ENOENT) {
+ /* port not found, allocate one */
+ ifindex = ulp_port_db_allocate_ifindex(port_db);
+ if (!ifindex)
+ return -ENOMEM;
+ port_db->dev_port_list[port_id] = ifindex;
+ } else if (rc == -EINVAL) {
+ return -EINVAL;
+ }
+
+ /* update the interface details */
+ intf = &port_db->ulp_intf_list[ifindex];
+ if (BNXT_PF(bp) || BNXT_VF(bp)) {
+ if (BNXT_PF(bp)) {
+ intf->type = BNXT_ULP_INTF_TYPE_PF;
+ intf->port_svif = bp->port_svif;
+ } else {
+ intf->type = BNXT_ULP_INTF_TYPE_VF;
+ }
+ intf->func_id = bp->fw_fid;
+ intf->func_svif = bp->func_svif;
+ vnic = BNXT_GET_DEFAULT_VNIC(bp);
+ if (vnic)
+ intf->default_vnic = vnic->fw_vnic_id;
+ intf->bp = bp;
+ memcpy(intf->mac_addr, bp->mac_addr, sizeof(intf->mac_addr));
+ } else {
+ BNXT_TF_DBG(ERR, "Invalid interface type\n");
+ }
+
+ return 0;
+}
+
+/*
+ * Api to get the ulp ifindex for a given device port.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * port_id [in].device port id
+ * ifindex [out] ulp ifindex
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t port_id,
+ uint32_t *ifindex)
+{
+ struct bnxt_ulp_port_db *port_db;
+
+ *ifindex = 0;
+ port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
+ if (!port_db || port_id >= RTE_MAX_ETHPORTS) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+ if (!port_db->dev_port_list[port_id])
+ return -ENOENT;
+
+ *ifindex = port_db->dev_port_list[port_id];
+ return 0;
+}
+
+/*
+ * Api to get the function id for a given ulp ifindex.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * ifindex [in] ulp ifindex
+ * func_id [out] the function id of the given ifindex.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t ifindex,
+ uint16_t *func_id)
+{
+ struct bnxt_ulp_port_db *port_db;
+
+ port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
+ if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+ *func_id = port_db->ulp_intf_list[ifindex].func_id;
+ return 0;
+}
+
+/*
+ * Api to get the svid for a given ulp ifindex.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * ifindex [in] ulp ifindex
+ * dir [in] the direction for the flow.
+ * svif [out] the svif of the given ifindex.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t ifindex,
+ uint32_t dir,
+ uint16_t *svif)
+{
+ struct bnxt_ulp_port_db *port_db;
+
+ port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
+ if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+ if (dir == ULP_DIR_EGRESS)
+ *svif = port_db->ulp_intf_list[ifindex].func_svif;
+ else
+ *svif = port_db->ulp_intf_list[ifindex].port_svif;
+ return 0;
+}
+
+/*
+ * Api to get the vnic id for a given ulp ifindex.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * ifindex [in] ulp ifindex
+ * vnic [out] the vnic of the given ifindex.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t ifindex,
+ uint16_t *vnic)
+{
+ struct bnxt_ulp_port_db *port_db;
+
+ port_db = bnxt_ulp_cntxt_ptr2_port_db_get(ulp_ctxt);
+ if (!port_db || ifindex >= port_db->ulp_intf_list_size || !ifindex) {
+ BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+ return -EINVAL;
+ }
+ *vnic = port_db->ulp_intf_list[ifindex].default_vnic;
+ return 0;
+}
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2014-2019 Broadcom
+ * All rights reserved.
+ */
+
+#ifndef _ULP_PORT_DB_H_
+#define _ULP_PORT_DB_H_
+
+#include "bnxt_ulp.h"
+
+#define BNXT_PORT_DB_MAX_INTF_LIST 256
+
+/* enumeration of the interface types */
+enum bnxt_ulp_intf_type {
+ BNXT_ULP_INTF_TYPE_INVALID = 0,
+ BNXT_ULP_INTF_TYPE_PF = 1,
+ BNXT_ULP_INTF_TYPE_VF,
+ BNXT_ULP_INTF_TYPE_PF_REP,
+ BNXT_ULP_INTF_TYPE_VF_REP,
+ BNXT_ULP_INTF_TYPE_LAST
+};
+
+/* Structure for the Port database resource information. */
+struct ulp_interface_info {
+ enum bnxt_ulp_intf_type type;
+ uint16_t func_id;
+ uint16_t func_svif;
+ uint16_t port_svif;
+ uint16_t default_vnic;
+ uint8_t mac_addr[RTE_ETHER_ADDR_LEN];
+ /* back pointer to the bnxt driver, it is null for rep ports */
+ struct bnxt *bp;
+};
+
+/* Structure for the Port database */
+struct bnxt_ulp_port_db {
+ struct ulp_interface_info *ulp_intf_list;
+ uint32_t ulp_intf_list_size;
+
+ /* dpdk device external port list */
+ uint16_t dev_port_list[RTE_MAX_ETHPORTS];
+};
+
+/*
+ * Initialize the port database. Memory is allocated in this
+ * call and assigned to the port database.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t ulp_port_db_init(struct bnxt_ulp_context *ulp_ctxt);
+
+/*
+ * Deinitialize the port database. Memory is deallocated in
+ * this call.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ *
+ * Returns 0 on success.
+ */
+int32_t ulp_port_db_deinit(struct bnxt_ulp_context *ulp_ctxt);
+
+/*
+ * Update the port database.This api is called when the port
+ * details are available during the startup.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * bp [in]. ptr to the device function.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t ulp_port_db_dev_port_intf_update(struct bnxt_ulp_context *ulp_ctxt,
+ struct bnxt *bp);
+
+/*
+ * Api to get the ulp ifindex for a given device port.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * port_id [in].device port id
+ * ifindex [out] ulp ifindex
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_dev_port_to_ulp_index(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t port_id,
+ uint32_t *ifindex);
+
+/*
+ * Api to get the function id for a given ulp ifindex.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * ifindex [in] ulp ifindex
+ * func_id [out] the function id of the given ifindex.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_function_id_get(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t ifindex,
+ uint16_t *func_id);
+
+/*
+ * Api to get the svid for a given ulp ifindex.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * ifindex [in] ulp ifindex
+ * dir [in] the direction for the flow.
+ * svif [out] the svif of the given ifindex.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_svif_get(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t ifindex,
+ uint32_t dir,
+ uint16_t *svif);
+
+/*
+ * Api to get the vnic id for a given ulp ifindex.
+ *
+ * ulp_ctxt [in] Ptr to ulp context
+ * ifindex [in] ulp ifindex
+ * vnic [out] the vnic of the given ifindex.
+ *
+ * Returns 0 on success or negative number on failure.
+ */
+int32_t
+ulp_port_db_default_vnic_get(struct bnxt_ulp_context *ulp_ctxt,
+ uint32_t ifindex,
+ uint16_t *vnic);
+
+#endif /* _ULP_PORT_DB_H_ */
#include "ulp_rte_parser.h"
#include "ulp_utils.h"
#include "tfp.h"
+#include "ulp_port_db.h"
/* Utility function to skip the void items. */
static inline int32_t
uint16_t port_id = svif;
uint32_t dir = 0;
struct ulp_rte_hdr_field *hdr_field;
+ uint32_t ifindex;
+ int32_t rc;
if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits, BNXT_ULP_HDR_BIT_SVIF)) {
BNXT_TF_DBG(ERR,
dir = ULP_UTIL_CHF_IDX_RD(params,
BNXT_ULP_CHF_IDX_DIRECTION);
/* perform the conversion from dpdk port to bnxt svif */
- if (dir == ULP_DIR_EGRESS)
- svif = bnxt_get_svif(port_id, true);
- else
- svif = bnxt_get_svif(port_id, false);
+ rc = ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx, port_id,
+ &ifindex);
+ if (rc) {
+ BNXT_TF_DBG(ERR,
+ "Invalid port id\n");
+ return BNXT_TF_RC_ERROR;
+ }
+ ulp_port_db_svif_get(params->ulp_ctx, ifindex, dir, &svif);
+ svif = rte_cpu_to_be_16(svif);
}
hdr_field = ¶ms->hdr_field[BNXT_ULP_PROTO_HDR_FIELD_SVIF_IDX];
memcpy(hdr_field->spec, &svif, sizeof(svif));
struct ulp_rte_act_bitmap act_bitmap;
struct ulp_rte_act_prop act_prop;
uint32_t dir;
+ struct bnxt_ulp_context *ulp_ctx;
};
/* Flow Parser Header Information Structure */