X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Ftf_core%2Ftf_device.c;h=498e668b16998ba73112a13d79297baf0fb192fa;hb=83680d371592fcf1b66cbbfecb0fb8b3aa4ccc8d;hp=4c46cadc6d8001b2613b8c39de265036c75e5bef;hpb=a46bbb57605b40201c2bab6386a7890451224836;p=dpdk.git diff --git a/drivers/net/bnxt/tf_core/tf_device.c b/drivers/net/bnxt/tf_core/tf_device.c index 4c46cadc6d..498e668b16 100644 --- a/drivers/net/bnxt/tf_core/tf_device.c +++ b/drivers/net/bnxt/tf_core/tf_device.c @@ -1,16 +1,64 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2019-2020 Broadcom + * Copyright(c) 2019-2021 Broadcom * All rights reserved. */ #include "tf_device.h" #include "tf_device_p4.h" +#include "tf_device_p58.h" #include "tfp.h" +#include "tf_em.h" +#include "tf_rm.h" +#ifdef TF_TCAM_SHARED +#include "tf_tcam_shared.h" +#endif /* TF_TCAM_SHARED */ struct tf; /* Forward declarations */ -static int dev_unbind_p4(struct tf *tfp); +static int tf_dev_unbind_p4(struct tf *tfp); +static int tf_dev_unbind_p58(struct tf *tfp); + +/** + * Resource Reservation Check function + * + * [in] count + * Number of module subtypes + * + * [in] cfg + * Pointer to rm element config + * + * [in] reservations + * Pointer to resource reservation array + * + * Returns + * - (n) number of tables in module that have non-zero reservation count. + */ +static int +tf_dev_reservation_check(uint16_t count, + struct tf_rm_element_cfg *cfg, + uint16_t *reservations) +{ + uint16_t cnt = 0; + uint16_t *rm_num; + int i, j; + + for (i = 0; i < TF_DIR_MAX; i++) { + rm_num = (uint16_t *)reservations + i * count; + for (j = 0; j < count; j++) { + if ((cfg[j].cfg_type == TF_RM_ELEM_CFG_HCAPI || + cfg[j].cfg_type == TF_RM_ELEM_CFG_HCAPI_BA || + cfg[j].cfg_type == + TF_RM_ELEM_CFG_HCAPI_BA_PARENT || + cfg[j].cfg_type == + TF_RM_ELEM_CFG_HCAPI_BA_CHILD) && + rm_num[j] > 0) + cnt++; + } + } + + return cnt; +} /** * Device specific bind function, WH+ @@ -32,60 +80,438 @@ static int dev_unbind_p4(struct tf *tfp); * - (-EINVAL) on parameter or internal failure. */ static int -dev_bind_p4(struct tf *tfp, - bool shadow_copy, - struct tf_session_resources *resources, - struct tf_dev_info *dev_handle) +tf_dev_bind_p4(struct tf *tfp, + bool shadow_copy, + struct tf_session_resources *resources, + struct tf_dev_info *dev_handle) { int rc; int frc; + int rsv_cnt; + bool no_rsv_flag = true; struct tf_ident_cfg_parms ident_cfg; struct tf_tbl_cfg_parms tbl_cfg; struct tf_tcam_cfg_parms tcam_cfg; + struct tf_em_cfg_parms em_cfg; + struct tf_if_tbl_cfg_parms if_tbl_cfg; + struct tf_global_cfg_cfg_parms global_cfg; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + /* Initial function initialization */ + dev_handle->ops = &tf_dev_ops_p4_init; /* Initialize the modules */ - ident_cfg.num_elements = TF_IDENT_TYPE_MAX; - ident_cfg.cfg = tf_ident_p4; - ident_cfg.shadow_copy = shadow_copy; - ident_cfg.resources = resources; - rc = tf_ident_bind(tfp, &ident_cfg); + rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX, + tf_ident_p4, + (uint16_t *)resources->ident_cnt); + if (rsv_cnt) { + ident_cfg.num_elements = TF_IDENT_TYPE_MAX; + ident_cfg.cfg = tf_ident_p4; + ident_cfg.shadow_copy = shadow_copy; + ident_cfg.resources = resources; + rc = tf_ident_bind(tfp, &ident_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Identifier initialization failure\n"); + goto fail; + } + + no_rsv_flag = false; + } + + rsv_cnt = tf_dev_reservation_check(TF_TBL_TYPE_MAX, + tf_tbl_p4, + (uint16_t *)resources->tbl_cnt); + if (rsv_cnt) { + tbl_cfg.num_elements = TF_TBL_TYPE_MAX; + tbl_cfg.cfg = tf_tbl_p4; + tbl_cfg.shadow_copy = shadow_copy; + tbl_cfg.resources = resources; + rc = tf_tbl_bind(tfp, &tbl_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Table initialization failure\n"); + goto fail; + } + + no_rsv_flag = false; + } + + rsv_cnt = tf_dev_reservation_check(TF_TCAM_TBL_TYPE_MAX, + tf_tcam_p4, + (uint16_t *)resources->tcam_cnt); + if (rsv_cnt) { + tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX; + tcam_cfg.cfg = tf_tcam_p4; + tcam_cfg.shadow_copy = shadow_copy; + tcam_cfg.resources = resources; +#ifdef TF_TCAM_SHARED + rc = tf_tcam_shared_bind(tfp, &tcam_cfg); +#else /* !TF_TCAM_SHARED */ + rc = tf_tcam_bind(tfp, &tcam_cfg); +#endif + if (rc) { + TFP_DRV_LOG(ERR, + "TCAM initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + /* + * EEM + */ + + em_cfg.cfg = tf_em_ext_p4; + rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX, + em_cfg.cfg, + (uint16_t *)resources->em_cnt); + if (rsv_cnt) { + em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; + em_cfg.resources = resources; + em_cfg.mem_type = TF_EEM_MEM_TYPE_HOST; + rc = tf_em_ext_common_bind(tfp, &em_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "EEM initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + /* + * EM + */ + rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX, + tf_em_int_p4, + (uint16_t *)resources->em_cnt); + if (rsv_cnt) { + em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; + em_cfg.cfg = tf_em_int_p4; + em_cfg.resources = resources; + em_cfg.mem_type = 0; /* Not used by EM */ + + rc = tf_em_int_bind(tfp, &em_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "EM initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + /* + * There is no rm reserved for any tables + * + */ + if (no_rsv_flag) { + TFP_DRV_LOG(ERR, + "No rm reserved for any tables\n"); + return -ENOMEM; + } + + /* + * IF_TBL + */ + if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX; + if_tbl_cfg.cfg = tf_if_tbl_p4; + if_tbl_cfg.shadow_copy = shadow_copy; + rc = tf_if_tbl_bind(tfp, &if_tbl_cfg); if (rc) { TFP_DRV_LOG(ERR, - "Identifier initialization failure\n"); + "IF Table initialization failure\n"); goto fail; } - tbl_cfg.num_elements = TF_TBL_TYPE_MAX; - tbl_cfg.cfg = tf_tbl_p4; - tbl_cfg.shadow_copy = shadow_copy; - tbl_cfg.resources = resources; - rc = tf_tbl_bind(tfp, &tbl_cfg); + if (!tf_session_is_shared_session(tfs)) { + /* + * GLOBAL_CFG + */ + global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX; + global_cfg.cfg = tf_global_cfg_p4; + rc = tf_global_cfg_bind(tfp, &global_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Global Cfg initialization failure\n"); + goto fail; + } + } + /* Final function initialization */ + dev_handle->ops = &tf_dev_ops_p4; + + return 0; + + fail: + /* Cleanup of already created modules */ + frc = tf_dev_unbind_p4(tfp); + if (frc) + return frc; + + return rc; +} + +/** + * Device specific unbind function, WH+ + * + * [in] tfp + * Pointer to TF handle + * + * Returns + * - (0) if successful. + * - (-EINVAL) on failure. + */ +static int +tf_dev_unbind_p4(struct tf *tfp) +{ + int rc = 0; + bool fail = false; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + /* Unbind all the support modules. As this is only done on + * close we only report errors as everything has to be cleaned + * up regardless. + * + * In case of residuals TCAMs are cleaned up first as to + * invalidate the pipeline in a clean manner. + */ +#ifdef TF_TCAM_SHARED + rc = tf_tcam_shared_unbind(tfp); +#else /* !TF_TCAM_SHARED */ + rc = tf_tcam_unbind(tfp); +#endif /* TF_TCAM_SHARED */ + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, TCAM\n"); + fail = true; + } + + rc = tf_ident_unbind(tfp); if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, Identifier\n"); + fail = true; + } + + rc = tf_tbl_unbind(tfp); + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, Table Type\n"); + fail = true; + } + + rc = tf_em_ext_common_unbind(tfp); + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, EEM\n"); + fail = true; + } + + rc = tf_em_int_unbind(tfp); + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, EM\n"); + fail = true; + } + + if (!tf_session_is_shared_session(tfs)) { + rc = tf_if_tbl_unbind(tfp); + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, IF Table Type\n"); + fail = true; + } + + rc = tf_global_cfg_unbind(tfp); + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, Global Cfg Type\n"); + fail = true; + } + } + + if (fail) + return -1; + + return rc; +} + +/** + * Device specific bind function, THOR + * + * [in] tfp + * Pointer to TF handle + * + * [in] shadow_copy + * Flag controlling shadow copy DB creation + * + * [in] resources + * Pointer to resource allocation information + * + * [out] dev_handle + * Device handle + * + * Returns + * - (0) if successful. + * - (-EINVAL) on parameter or internal failure. + */ +static int +tf_dev_bind_p58(struct tf *tfp, + bool shadow_copy, + struct tf_session_resources *resources, + struct tf_dev_info *dev_handle) +{ + int rc; + int frc; + int rsv_cnt; + bool no_rsv_flag = true; + struct tf_ident_cfg_parms ident_cfg; + struct tf_tbl_cfg_parms tbl_cfg; + struct tf_tcam_cfg_parms tcam_cfg; + struct tf_em_cfg_parms em_cfg; + struct tf_if_tbl_cfg_parms if_tbl_cfg; + struct tf_global_cfg_cfg_parms global_cfg; + struct tf_session *tfs; + + /* Initial function initialization */ + dev_handle->ops = &tf_dev_ops_p58_init; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; + + rsv_cnt = tf_dev_reservation_check(TF_IDENT_TYPE_MAX, + tf_ident_p58, + (uint16_t *)resources->ident_cnt); + if (rsv_cnt) { + ident_cfg.num_elements = TF_IDENT_TYPE_MAX; + ident_cfg.cfg = tf_ident_p58; + ident_cfg.shadow_copy = shadow_copy; + ident_cfg.resources = resources; + rc = tf_ident_bind(tfp, &ident_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Identifier initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + rsv_cnt = tf_dev_reservation_check(TF_TBL_TYPE_MAX, + tf_tbl_p58, + (uint16_t *)resources->tbl_cnt); + if (rsv_cnt) { + tbl_cfg.num_elements = TF_TBL_TYPE_MAX; + tbl_cfg.cfg = tf_tbl_p58; + tbl_cfg.shadow_copy = shadow_copy; + tbl_cfg.resources = resources; + rc = tf_tbl_bind(tfp, &tbl_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Table initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + rsv_cnt = tf_dev_reservation_check(TF_TCAM_TBL_TYPE_MAX, + tf_tcam_p58, + (uint16_t *)resources->tcam_cnt); + if (rsv_cnt) { + tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX; + tcam_cfg.cfg = tf_tcam_p58; + tcam_cfg.shadow_copy = shadow_copy; + tcam_cfg.resources = resources; +#ifdef TF_TCAM_SHARED + rc = tf_tcam_shared_bind(tfp, &tcam_cfg); +#else /* !TF_TCAM_SHARED */ + rc = tf_tcam_bind(tfp, &tcam_cfg); +#endif + if (rc) { + TFP_DRV_LOG(ERR, + "TCAM initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + /* + * EM + */ + rsv_cnt = tf_dev_reservation_check(TF_EM_TBL_TYPE_MAX, + tf_em_int_p58, + (uint16_t *)resources->em_cnt); + if (rsv_cnt) { + em_cfg.num_elements = TF_EM_TBL_TYPE_MAX; + em_cfg.cfg = tf_em_int_p58; + em_cfg.resources = resources; + em_cfg.mem_type = 0; /* Not used by EM */ + + rc = tf_em_int_bind(tfp, &em_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "EM initialization failure\n"); + goto fail; + } + no_rsv_flag = false; + } + + /* + * There is no rm reserved for any tables + * + */ + if (no_rsv_flag) { TFP_DRV_LOG(ERR, - "Table initialization failure\n"); - goto fail; + "No rm reserved for any tables\n"); + return -ENOMEM; } - tcam_cfg.num_elements = TF_TCAM_TBL_TYPE_MAX; - tcam_cfg.cfg = tf_tcam_p4; - tcam_cfg.shadow_copy = shadow_copy; - tcam_cfg.resources = resources; - rc = tf_tcam_bind(tfp, &tcam_cfg); + /* + * IF_TBL + */ + if_tbl_cfg.num_elements = TF_IF_TBL_TYPE_MAX; + if_tbl_cfg.cfg = tf_if_tbl_p58; + if_tbl_cfg.shadow_copy = shadow_copy; + rc = tf_if_tbl_bind(tfp, &if_tbl_cfg); if (rc) { TFP_DRV_LOG(ERR, - "TCAM initialization failure\n"); + "IF Table initialization failure\n"); goto fail; } - dev_handle->type = TF_DEVICE_TYPE_WH; - dev_handle->ops = &tf_dev_ops_p4; + if (!tf_session_is_shared_session(tfs)) { + /* + * GLOBAL_CFG + */ + global_cfg.num_elements = TF_GLOBAL_CFG_TYPE_MAX; + global_cfg.cfg = tf_global_cfg_p58; + rc = tf_global_cfg_bind(tfp, &global_cfg); + if (rc) { + TFP_DRV_LOG(ERR, + "Global Cfg initialization failure\n"); + goto fail; + } + } + + /* Final function initialization */ + dev_handle->ops = &tf_dev_ops_p58; return 0; fail: /* Cleanup of already created modules */ - frc = dev_unbind_p4(tfp); + frc = tf_dev_unbind_p58(tfp); if (frc) return frc; @@ -93,7 +519,7 @@ dev_bind_p4(struct tf *tfp, } /** - * Device specific unbind function, WH+ + * Device specific unbind function, THOR * * [in] tfp * Pointer to TF handle @@ -103,36 +529,72 @@ dev_bind_p4(struct tf *tfp, * - (-EINVAL) on failure. */ static int -dev_unbind_p4(struct tf *tfp) +tf_dev_unbind_p58(struct tf *tfp) { int rc = 0; bool fail = false; + struct tf_session *tfs; + + /* Retrieve the session information */ + rc = tf_session_get_session_internal(tfp, &tfs); + if (rc) + return rc; /* Unbind all the support modules. As this is only done on * close we only report errors as everything has to be cleaned * up regardless. + * + * In case of residuals TCAMs are cleaned up first as to + * invalidate the pipeline in a clean manner. */ +#ifdef TF_TCAM_SHARED + rc = tf_tcam_shared_unbind(tfp); +#else /* !TF_TCAM_SHARED */ + rc = tf_tcam_unbind(tfp); +#endif /* TF_TCAM_SHARED */ + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, TCAM\n"); + fail = true; + } + rc = tf_ident_unbind(tfp); if (rc) { - TFP_DRV_LOG(ERR, + TFP_DRV_LOG(INFO, "Device unbind failed, Identifier\n"); fail = true; } rc = tf_tbl_unbind(tfp); if (rc) { - TFP_DRV_LOG(ERR, + TFP_DRV_LOG(INFO, "Device unbind failed, Table Type\n"); fail = true; } - rc = tf_tcam_unbind(tfp); + rc = tf_em_int_unbind(tfp); + if (rc) { + TFP_DRV_LOG(INFO, + "Device unbind failed, EM\n"); + fail = true; + } + + rc = tf_if_tbl_unbind(tfp); if (rc) { TFP_DRV_LOG(ERR, - "Device unbind failed, TCAM\n"); + "Device unbind failed, IF Table Type\n"); fail = true; } + if (!tf_session_is_shared_session(tfs)) { + rc = tf_global_cfg_unbind(tfp); + if (rc) { + TFP_DRV_LOG(ERR, + "Device unbind failed, Global Cfg Type\n"); + fail = true; + } + } + if (fail) return -1; @@ -140,18 +602,26 @@ dev_unbind_p4(struct tf *tfp) } int -dev_bind(struct tf *tfp __rte_unused, - enum tf_device_type type, - bool shadow_copy, - struct tf_session_resources *resources, - struct tf_dev_info *dev_handle) +tf_dev_bind(struct tf *tfp __rte_unused, + enum tf_device_type type, + bool shadow_copy, + struct tf_session_resources *resources, + struct tf_dev_info *dev_handle) { switch (type) { case TF_DEVICE_TYPE_WH: - return dev_bind_p4(tfp, - shadow_copy, - resources, - dev_handle); + case TF_DEVICE_TYPE_SR: + dev_handle->type = type; + return tf_dev_bind_p4(tfp, + shadow_copy, + resources, + dev_handle); + case TF_DEVICE_TYPE_THOR: + dev_handle->type = type; + return tf_dev_bind_p58(tfp, + shadow_copy, + resources, + dev_handle); default: TFP_DRV_LOG(ERR, "No such device\n"); @@ -160,12 +630,36 @@ dev_bind(struct tf *tfp __rte_unused, } int -dev_unbind(struct tf *tfp, - struct tf_dev_info *dev_handle) +tf_dev_bind_ops(enum tf_device_type type, + struct tf_dev_info *dev_handle) +{ + switch (type) { + case TF_DEVICE_TYPE_WH: + case TF_DEVICE_TYPE_SR: + dev_handle->ops = &tf_dev_ops_p4_init; + break; + case TF_DEVICE_TYPE_THOR: + dev_handle->ops = &tf_dev_ops_p58_init; + break; + default: + TFP_DRV_LOG(ERR, + "No such device\n"); + return -ENODEV; + } + + return 0; +} + +int +tf_dev_unbind(struct tf *tfp, + struct tf_dev_info *dev_handle) { switch (dev_handle->type) { case TF_DEVICE_TYPE_WH: - return dev_unbind_p4(tfp); + case TF_DEVICE_TYPE_SR: + return tf_dev_unbind_p4(tfp); + case TF_DEVICE_TYPE_THOR: + return tf_dev_unbind_p58(tfp); default: TFP_DRV_LOG(ERR, "No such device\n");