19cf9c838SSomnath Kotur /* SPDX-License-Identifier: BSD-3-Clause 2d9e70b1dSRandy Schacher * Copyright(c) 2014-2023 Broadcom 39cf9c838SSomnath Kotur * All rights reserved. 49cf9c838SSomnath Kotur */ 59cf9c838SSomnath Kotur 69cf9c838SSomnath Kotur #include <rte_common.h> 749b8d40bSSomnath Kotur #include <rte_cycles.h> 89cf9c838SSomnath Kotur #include <rte_malloc.h> 99cf9c838SSomnath Kotur #include <rte_log.h> 109cf9c838SSomnath Kotur #include <rte_alarm.h> 119cf9c838SSomnath Kotur #include "bnxt.h" 129cf9c838SSomnath Kotur #include "bnxt_ulp.h" 130c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 14dd0191d5SShuanglin Wang #include "bnxt_ulp_tf.h" 159cf9c838SSomnath Kotur #include "bnxt_tf_common.h" 169cf9c838SSomnath Kotur #include "ulp_fc_mgr.h" 17306c2d28SSomnath Kotur #include "ulp_flow_db.h" 189cf9c838SSomnath Kotur #include "ulp_template_db_enum.h" 199cf9c838SSomnath Kotur #include "ulp_template_struct.h" 20dd0191d5SShuanglin Wang 21dd0191d5SShuanglin Wang static const struct bnxt_ulp_fc_core_ops * 22dd0191d5SShuanglin Wang bnxt_ulp_fc_ops_get(struct bnxt_ulp_context *ctxt) 23dd0191d5SShuanglin Wang { 24dd0191d5SShuanglin Wang int32_t rc; 25dd0191d5SShuanglin Wang enum bnxt_ulp_device_id dev_id; 26dd0191d5SShuanglin Wang const struct bnxt_ulp_fc_core_ops *func_ops; 27dd0191d5SShuanglin Wang 28dd0191d5SShuanglin Wang rc = bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id); 29dd0191d5SShuanglin Wang if (rc) 30dd0191d5SShuanglin Wang return NULL; 31dd0191d5SShuanglin Wang 32dd0191d5SShuanglin Wang switch (dev_id) { 33dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_THOR2: 34dd0191d5SShuanglin Wang func_ops = &ulp_fc_tfc_core_ops; 35dd0191d5SShuanglin Wang break; 36dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_THOR: 37dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_STINGRAY: 38dd0191d5SShuanglin Wang case BNXT_ULP_DEVICE_ID_WH_PLUS: 39dd0191d5SShuanglin Wang func_ops = &ulp_fc_tf_core_ops; 40dd0191d5SShuanglin Wang break; 41dd0191d5SShuanglin Wang default: 42dd0191d5SShuanglin Wang func_ops = NULL; 43dd0191d5SShuanglin Wang break; 44dd0191d5SShuanglin Wang } 45dd0191d5SShuanglin Wang return func_ops; 46dd0191d5SShuanglin Wang } 479cf9c838SSomnath Kotur 489cf9c838SSomnath Kotur static int 499cf9c838SSomnath Kotur ulp_fc_mgr_shadow_mem_alloc(struct hw_fc_mem_info *parms, int size) 509cf9c838SSomnath Kotur { 519cf9c838SSomnath Kotur /* Allocate memory*/ 52640bfd23SKishore Padmanabha if (!parms) 539cf9c838SSomnath Kotur return -EINVAL; 549cf9c838SSomnath Kotur 559cf9c838SSomnath Kotur parms->mem_va = rte_zmalloc("ulp_fc_info", 569cf9c838SSomnath Kotur RTE_CACHE_LINE_ROUNDUP(size), 579cf9c838SSomnath Kotur 4096); 58640bfd23SKishore Padmanabha if (!parms->mem_va) { 59dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Allocate failed mem_va\n"); 609cf9c838SSomnath Kotur return -ENOMEM; 619cf9c838SSomnath Kotur } 629cf9c838SSomnath Kotur 639cf9c838SSomnath Kotur rte_mem_lock_page(parms->mem_va); 649cf9c838SSomnath Kotur 659cf9c838SSomnath Kotur parms->mem_pa = (void *)(uintptr_t)rte_mem_virt2phy(parms->mem_va); 66ad9eed02SKishore Padmanabha if (parms->mem_pa == (void *)RTE_BAD_IOVA) { 67dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Allocate failed mem_pa\n"); 689cf9c838SSomnath Kotur return -ENOMEM; 699cf9c838SSomnath Kotur } 709cf9c838SSomnath Kotur 719cf9c838SSomnath Kotur return 0; 729cf9c838SSomnath Kotur } 739cf9c838SSomnath Kotur 749cf9c838SSomnath Kotur static void 759cf9c838SSomnath Kotur ulp_fc_mgr_shadow_mem_free(struct hw_fc_mem_info *parms) 769cf9c838SSomnath Kotur { 779cf9c838SSomnath Kotur rte_free(parms->mem_va); 789cf9c838SSomnath Kotur } 799cf9c838SSomnath Kotur 809cf9c838SSomnath Kotur /* 819cf9c838SSomnath Kotur * Allocate and Initialize all Flow Counter Manager resources for this ulp 829cf9c838SSomnath Kotur * context. 839cf9c838SSomnath Kotur * 849cf9c838SSomnath Kotur * ctxt [in] The ulp context for the Flow Counter manager. 859cf9c838SSomnath Kotur * 869cf9c838SSomnath Kotur */ 879cf9c838SSomnath Kotur int32_t 889cf9c838SSomnath Kotur ulp_fc_mgr_init(struct bnxt_ulp_context *ctxt) 899cf9c838SSomnath Kotur { 909cf9c838SSomnath Kotur struct bnxt_ulp_device_params *dparms; 919cf9c838SSomnath Kotur uint32_t dev_id, sw_acc_cntr_tbl_sz, hw_fc_mem_info_sz; 929cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 93dd0191d5SShuanglin Wang const struct bnxt_ulp_fc_core_ops *fc_ops; 9449cdf043SKishore Padmanabha uint32_t flags = 0; 959cf9c838SSomnath Kotur int i, rc; 969cf9c838SSomnath Kotur 979cf9c838SSomnath Kotur if (!ctxt) { 98dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Invalid ULP CTXT\n"); 999cf9c838SSomnath Kotur return -EINVAL; 1009cf9c838SSomnath Kotur } 1019cf9c838SSomnath Kotur 1029cf9c838SSomnath Kotur if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) { 103dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to get device id\n"); 1049cf9c838SSomnath Kotur return -EINVAL; 1059cf9c838SSomnath Kotur } 1069cf9c838SSomnath Kotur 1079cf9c838SSomnath Kotur dparms = bnxt_ulp_device_params_get(dev_id); 1089cf9c838SSomnath Kotur if (!dparms) { 109dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to device parms\n"); 110dd0191d5SShuanglin Wang return -EINVAL; 111dd0191d5SShuanglin Wang } 112dd0191d5SShuanglin Wang 11349cdf043SKishore Padmanabha /* update the features list */ 11449cdf043SKishore Padmanabha if (dparms->dev_features & BNXT_ULP_DEV_FT_STAT_SW_AGG) 11549cdf043SKishore Padmanabha flags = ULP_FLAG_FC_SW_AGG_EN; 11649cdf043SKishore Padmanabha if (dparms->dev_features & BNXT_ULP_DEV_FT_STAT_PARENT_AGG) 11749cdf043SKishore Padmanabha flags |= ULP_FLAG_FC_PARENT_AGG_EN; 11849cdf043SKishore Padmanabha 119dd0191d5SShuanglin Wang fc_ops = bnxt_ulp_fc_ops_get(ctxt); 120dd0191d5SShuanglin Wang if (fc_ops == NULL) { 121dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to get the counter ops\n"); 1229cf9c838SSomnath Kotur return -EINVAL; 1239cf9c838SSomnath Kotur } 1249cf9c838SSomnath Kotur 1259cf9c838SSomnath Kotur ulp_fc_info = rte_zmalloc("ulp_fc_info", sizeof(*ulp_fc_info), 0); 1269cf9c838SSomnath Kotur if (!ulp_fc_info) 1279cf9c838SSomnath Kotur goto error; 1289cf9c838SSomnath Kotur 129dd0191d5SShuanglin Wang ulp_fc_info->fc_ops = fc_ops; 13049cdf043SKishore Padmanabha ulp_fc_info->flags = flags; 131dd0191d5SShuanglin Wang 132*7d32c003SAriel Otilibili pthread_mutex_init(&ulp_fc_info->fc_lock, NULL); 1339cf9c838SSomnath Kotur 1349cf9c838SSomnath Kotur /* Add the FC info tbl to the ulp context. */ 1359cf9c838SSomnath Kotur bnxt_ulp_cntxt_ptr2_fc_info_set(ctxt, ulp_fc_info); 1369cf9c838SSomnath Kotur 1371993b267SShahaji Bhosle ulp_fc_info->num_counters = dparms->flow_count_db_entries; 1381993b267SShahaji Bhosle if (!ulp_fc_info->num_counters) { 1391993b267SShahaji Bhosle /* No need for software counters, call fw directly */ 140dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Sw flow counter support not enabled\n"); 1411993b267SShahaji Bhosle return 0; 1421993b267SShahaji Bhosle } 1431993b267SShahaji Bhosle 14449cdf043SKishore Padmanabha /* no need to allocate sw aggregation memory if agg is disabled */ 14549cdf043SKishore Padmanabha if (!(ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN)) 14649cdf043SKishore Padmanabha return 0; 14749cdf043SKishore Padmanabha 1489cf9c838SSomnath Kotur sw_acc_cntr_tbl_sz = sizeof(struct sw_acc_counter) * 1499cf9c838SSomnath Kotur dparms->flow_count_db_entries; 1509cf9c838SSomnath Kotur 1519cf9c838SSomnath Kotur for (i = 0; i < TF_DIR_MAX; i++) { 1529cf9c838SSomnath Kotur ulp_fc_info->sw_acc_tbl[i] = rte_zmalloc("ulp_sw_acc_cntr_tbl", 1539cf9c838SSomnath Kotur sw_acc_cntr_tbl_sz, 0); 1549cf9c838SSomnath Kotur if (!ulp_fc_info->sw_acc_tbl[i]) 1559cf9c838SSomnath Kotur goto error; 1569cf9c838SSomnath Kotur } 1579cf9c838SSomnath Kotur 1589cf9c838SSomnath Kotur hw_fc_mem_info_sz = sizeof(uint64_t) * dparms->flow_count_db_entries; 1599cf9c838SSomnath Kotur 1609cf9c838SSomnath Kotur for (i = 0; i < TF_DIR_MAX; i++) { 1619cf9c838SSomnath Kotur rc = ulp_fc_mgr_shadow_mem_alloc(&ulp_fc_info->shadow_hw_tbl[i], 1629cf9c838SSomnath Kotur hw_fc_mem_info_sz); 1639cf9c838SSomnath Kotur if (rc) 1649cf9c838SSomnath Kotur goto error; 1659cf9c838SSomnath Kotur } 1669cf9c838SSomnath Kotur 1679cf9c838SSomnath Kotur return 0; 1689cf9c838SSomnath Kotur 1699cf9c838SSomnath Kotur error: 1709cf9c838SSomnath Kotur ulp_fc_mgr_deinit(ctxt); 171dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to allocate memory for fc mgr\n"); 1729cf9c838SSomnath Kotur 1739cf9c838SSomnath Kotur return -ENOMEM; 1749cf9c838SSomnath Kotur } 1759cf9c838SSomnath Kotur 1769cf9c838SSomnath Kotur /* 1779cf9c838SSomnath Kotur * Release all resources in the Flow Counter Manager for this ulp context 1789cf9c838SSomnath Kotur * 1799cf9c838SSomnath Kotur * ctxt [in] The ulp context for the Flow Counter manager 1809cf9c838SSomnath Kotur * 1819cf9c838SSomnath Kotur */ 1829cf9c838SSomnath Kotur int32_t 1839cf9c838SSomnath Kotur ulp_fc_mgr_deinit(struct bnxt_ulp_context *ctxt) 1849cf9c838SSomnath Kotur { 1859cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 1861993b267SShahaji Bhosle struct hw_fc_mem_info *shd_info; 1879cf9c838SSomnath Kotur int i; 1889cf9c838SSomnath Kotur 1899cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 1909cf9c838SSomnath Kotur 1919cf9c838SSomnath Kotur if (!ulp_fc_info) 1929cf9c838SSomnath Kotur return -EINVAL; 1939cf9c838SSomnath Kotur 19449cdf043SKishore Padmanabha if (ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN) 1959cf9c838SSomnath Kotur ulp_fc_mgr_thread_cancel(ctxt); 1969cf9c838SSomnath Kotur 1979cf9c838SSomnath Kotur pthread_mutex_destroy(&ulp_fc_info->fc_lock); 1989cf9c838SSomnath Kotur 19949cdf043SKishore Padmanabha if (ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN) { 2009cf9c838SSomnath Kotur for (i = 0; i < TF_DIR_MAX; i++) 2019cf9c838SSomnath Kotur rte_free(ulp_fc_info->sw_acc_tbl[i]); 2029cf9c838SSomnath Kotur 2031993b267SShahaji Bhosle for (i = 0; i < TF_DIR_MAX; i++) { 2041993b267SShahaji Bhosle shd_info = &ulp_fc_info->shadow_hw_tbl[i]; 2051993b267SShahaji Bhosle ulp_fc_mgr_shadow_mem_free(shd_info); 2061993b267SShahaji Bhosle } 2071993b267SShahaji Bhosle } 2089cf9c838SSomnath Kotur 2099cf9c838SSomnath Kotur rte_free(ulp_fc_info); 2109cf9c838SSomnath Kotur 2119cf9c838SSomnath Kotur /* Safe to ignore on deinit */ 2129cf9c838SSomnath Kotur (void)bnxt_ulp_cntxt_ptr2_fc_info_set(ctxt, NULL); 2139cf9c838SSomnath Kotur 2149cf9c838SSomnath Kotur return 0; 2159cf9c838SSomnath Kotur } 2169cf9c838SSomnath Kotur 2179cf9c838SSomnath Kotur /* 2189cf9c838SSomnath Kotur * Check if the alarm thread that walks through the flows is started 2199cf9c838SSomnath Kotur * 2209cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 2219cf9c838SSomnath Kotur * 2229cf9c838SSomnath Kotur */ 2239cf9c838SSomnath Kotur bool ulp_fc_mgr_thread_isstarted(struct bnxt_ulp_context *ctxt) 2249cf9c838SSomnath Kotur { 2259cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 2269cf9c838SSomnath Kotur 2279cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 2289cf9c838SSomnath Kotur 2293fe124d2SKishore Padmanabha if (ulp_fc_info) 2309cf9c838SSomnath Kotur return !!(ulp_fc_info->flags & ULP_FLAG_FC_THREAD); 2313fe124d2SKishore Padmanabha 2323fe124d2SKishore Padmanabha return false; 2339cf9c838SSomnath Kotur } 2349cf9c838SSomnath Kotur 2359cf9c838SSomnath Kotur /* 2369cf9c838SSomnath Kotur * Setup the Flow counter timer thread that will fetch/accumulate raw counter 2379cf9c838SSomnath Kotur * data from the chip's internal flow counters 2389cf9c838SSomnath Kotur * 2399cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 2409cf9c838SSomnath Kotur * 2419cf9c838SSomnath Kotur */ 2429cf9c838SSomnath Kotur int32_t 2439cf9c838SSomnath Kotur ulp_fc_mgr_thread_start(struct bnxt_ulp_context *ctxt) 2449cf9c838SSomnath Kotur { 2459cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 2469cf9c838SSomnath Kotur 2479cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 2489cf9c838SSomnath Kotur 2493fe124d2SKishore Padmanabha if (ulp_fc_info && !(ulp_fc_info->flags & ULP_FLAG_FC_THREAD)) { 2509cf9c838SSomnath Kotur rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER, 251bf598786SKishore Padmanabha ulp_fc_mgr_alarm_cb, (void *)ctxt->cfg_data); 2529cf9c838SSomnath Kotur ulp_fc_info->flags |= ULP_FLAG_FC_THREAD; 2539cf9c838SSomnath Kotur } 2549cf9c838SSomnath Kotur 2559cf9c838SSomnath Kotur return 0; 2569cf9c838SSomnath Kotur } 2579cf9c838SSomnath Kotur 2589cf9c838SSomnath Kotur /* 2599cf9c838SSomnath Kotur * Cancel the alarm handler 2609cf9c838SSomnath Kotur * 2619cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 2629cf9c838SSomnath Kotur * 2639cf9c838SSomnath Kotur */ 2649cf9c838SSomnath Kotur void ulp_fc_mgr_thread_cancel(struct bnxt_ulp_context *ctxt) 2659cf9c838SSomnath Kotur { 2669cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 2679cf9c838SSomnath Kotur 2689cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 2699cf9c838SSomnath Kotur if (!ulp_fc_info) 2709cf9c838SSomnath Kotur return; 2719cf9c838SSomnath Kotur 2729cf9c838SSomnath Kotur ulp_fc_info->flags &= ~ULP_FLAG_FC_THREAD; 273bf598786SKishore Padmanabha rte_eal_alarm_cancel(ulp_fc_mgr_alarm_cb, ctxt->cfg_data); 2749cf9c838SSomnath Kotur } 2759cf9c838SSomnath Kotur 2769cf9c838SSomnath Kotur /* 2779cf9c838SSomnath Kotur * Alarm handler that will issue the TF-Core API to fetch 2789cf9c838SSomnath Kotur * data from the chip's internal flow counters 2799cf9c838SSomnath Kotur * 2809cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 2819cf9c838SSomnath Kotur * 2829cf9c838SSomnath Kotur */ 283306c2d28SSomnath Kotur 2849cf9c838SSomnath Kotur void 285bf598786SKishore Padmanabha ulp_fc_mgr_alarm_cb(void *arg) 2869cf9c838SSomnath Kotur { 287dd0191d5SShuanglin Wang const struct bnxt_ulp_fc_core_ops *fc_ops; 2889cf9c838SSomnath Kotur struct bnxt_ulp_device_params *dparms; 289dd0191d5SShuanglin Wang struct bnxt_ulp_fc_info *ulp_fc_info; 290dd0191d5SShuanglin Wang struct bnxt_ulp_context *ctxt; 291dd0191d5SShuanglin Wang uint32_t dev_id; 292dd0191d5SShuanglin Wang int rc = 0; 2939cf9c838SSomnath Kotur 294bf598786SKishore Padmanabha ctxt = bnxt_ulp_cntxt_entry_acquire(arg); 295d75b5512SKishore Padmanabha if (ctxt == NULL) { 296dd0191d5SShuanglin Wang BNXT_DRV_DBG(INFO, "could not get the ulp context lock\n"); 297d75b5512SKishore Padmanabha rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER, 298bf598786SKishore Padmanabha ulp_fc_mgr_alarm_cb, arg); 2999cf9c838SSomnath Kotur return; 300d75b5512SKishore Padmanabha } 301d75b5512SKishore Padmanabha 302d75b5512SKishore Padmanabha ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 303d75b5512SKishore Padmanabha if (!ulp_fc_info) { 304d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(); 305d75b5512SKishore Padmanabha return; 306d75b5512SKishore Padmanabha } 3079cf9c838SSomnath Kotur 308dd0191d5SShuanglin Wang fc_ops = ulp_fc_info->fc_ops; 309dd0191d5SShuanglin Wang 3109cf9c838SSomnath Kotur if (bnxt_ulp_cntxt_dev_id_get(ctxt, &dev_id)) { 311dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to get device id\n"); 312d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(); 3139cf9c838SSomnath Kotur return; 3149cf9c838SSomnath Kotur } 3159cf9c838SSomnath Kotur 3169cf9c838SSomnath Kotur dparms = bnxt_ulp_device_params_get(dev_id); 3179cf9c838SSomnath Kotur if (!dparms) { 318dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Failed to device parms\n"); 319d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(); 3209cf9c838SSomnath Kotur return; 3219cf9c838SSomnath Kotur } 3229cf9c838SSomnath Kotur 3239cf9c838SSomnath Kotur /* 3249cf9c838SSomnath Kotur * Take the fc_lock to ensure no flow is destroyed 3259cf9c838SSomnath Kotur * during the bulk get 3269cf9c838SSomnath Kotur */ 3279cf9c838SSomnath Kotur if (pthread_mutex_trylock(&ulp_fc_info->fc_lock)) 3289cf9c838SSomnath Kotur goto out; 3299cf9c838SSomnath Kotur 3309cf9c838SSomnath Kotur if (!ulp_fc_info->num_entries) { 3319cf9c838SSomnath Kotur pthread_mutex_unlock(&ulp_fc_info->fc_lock); 3329cf9c838SSomnath Kotur ulp_fc_mgr_thread_cancel(ctxt); 333d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(); 3349cf9c838SSomnath Kotur return; 3359cf9c838SSomnath Kotur } 336306c2d28SSomnath Kotur /* 337306c2d28SSomnath Kotur * Commented for now till GET_BULK is resolved, just get the first flow 338306c2d28SSomnath Kotur * stat for now 3399cf9c838SSomnath Kotur for (i = 0; i < TF_DIR_MAX; i++) { 3409cf9c838SSomnath Kotur rc = ulp_bulk_get_flow_stats(tfp, ulp_fc_info, i, 3419cf9c838SSomnath Kotur dparms->flow_count_db_entries); 3429cf9c838SSomnath Kotur if (rc) 3439cf9c838SSomnath Kotur break; 3449cf9c838SSomnath Kotur } 345306c2d28SSomnath Kotur */ 346640bfd23SKishore Padmanabha 347640bfd23SKishore Padmanabha /* reset the parent accumulation counters before accumulation if any */ 348640bfd23SKishore Padmanabha ulp_flow_db_parent_flow_count_reset(ctxt); 349640bfd23SKishore Padmanabha 350dd0191d5SShuanglin Wang rc = fc_ops->ulp_flow_stats_accum_update(ctxt, ulp_fc_info, dparms); 3519cf9c838SSomnath Kotur 3529cf9c838SSomnath Kotur pthread_mutex_unlock(&ulp_fc_info->fc_lock); 3539cf9c838SSomnath Kotur 3549cf9c838SSomnath Kotur /* 3559cf9c838SSomnath Kotur * If cmd fails once, no need of 3569cf9c838SSomnath Kotur * invoking again every second 3579cf9c838SSomnath Kotur */ 3589cf9c838SSomnath Kotur 3599cf9c838SSomnath Kotur if (rc) { 3609cf9c838SSomnath Kotur ulp_fc_mgr_thread_cancel(ctxt); 361d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(); 3629cf9c838SSomnath Kotur return; 3639cf9c838SSomnath Kotur } 3649cf9c838SSomnath Kotur out: 365d75b5512SKishore Padmanabha bnxt_ulp_cntxt_entry_release(); 3669cf9c838SSomnath Kotur rte_eal_alarm_set(US_PER_S * ULP_FC_TIMER, 367bf598786SKishore Padmanabha ulp_fc_mgr_alarm_cb, arg); 3689cf9c838SSomnath Kotur } 3699cf9c838SSomnath Kotur 3709cf9c838SSomnath Kotur /* 3719cf9c838SSomnath Kotur * Set the starting index that indicates the first HW flow 3729cf9c838SSomnath Kotur * counter ID 3739cf9c838SSomnath Kotur * 3749cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 3759cf9c838SSomnath Kotur * 3769cf9c838SSomnath Kotur * dir [in] The direction of the flow 3779cf9c838SSomnath Kotur * 3789cf9c838SSomnath Kotur * start_idx [in] The HW flow counter ID 3799cf9c838SSomnath Kotur * 3809cf9c838SSomnath Kotur */ 381dd0191d5SShuanglin Wang bool ulp_fc_mgr_start_idx_isset(struct bnxt_ulp_context *ctxt, uint8_t dir) 3829cf9c838SSomnath Kotur { 3839cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 3849cf9c838SSomnath Kotur 3859cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 3869cf9c838SSomnath Kotur 3873fe124d2SKishore Padmanabha if (ulp_fc_info) 388811229d4SSomnath Kotur return ulp_fc_info->shadow_hw_tbl[dir].start_idx_is_set; 3893fe124d2SKishore Padmanabha 3903fe124d2SKishore Padmanabha return false; 3919cf9c838SSomnath Kotur } 3929cf9c838SSomnath Kotur 3939cf9c838SSomnath Kotur /* 3949cf9c838SSomnath Kotur * Set the starting index that indicates the first HW flow 3959cf9c838SSomnath Kotur * counter ID 3969cf9c838SSomnath Kotur * 3979cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 3989cf9c838SSomnath Kotur * 3999cf9c838SSomnath Kotur * dir [in] The direction of the flow 4009cf9c838SSomnath Kotur * 4019cf9c838SSomnath Kotur * start_idx [in] The HW flow counter ID 4029cf9c838SSomnath Kotur * 4039cf9c838SSomnath Kotur */ 404dd0191d5SShuanglin Wang int32_t ulp_fc_mgr_start_idx_set(struct bnxt_ulp_context *ctxt, uint8_t dir, 4059cf9c838SSomnath Kotur uint32_t start_idx) 4069cf9c838SSomnath Kotur { 4079cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 4089cf9c838SSomnath Kotur 4099cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 4109cf9c838SSomnath Kotur 4119cf9c838SSomnath Kotur if (!ulp_fc_info) 4129cf9c838SSomnath Kotur return -EIO; 4139cf9c838SSomnath Kotur 414811229d4SSomnath Kotur if (!ulp_fc_info->shadow_hw_tbl[dir].start_idx_is_set) { 4159cf9c838SSomnath Kotur ulp_fc_info->shadow_hw_tbl[dir].start_idx = start_idx; 416811229d4SSomnath Kotur ulp_fc_info->shadow_hw_tbl[dir].start_idx_is_set = true; 417811229d4SSomnath Kotur } 4189cf9c838SSomnath Kotur 4199cf9c838SSomnath Kotur return 0; 4209cf9c838SSomnath Kotur } 4219cf9c838SSomnath Kotur 4229cf9c838SSomnath Kotur /* 4239cf9c838SSomnath Kotur * Set the corresponding SW accumulator table entry based on 4249cf9c838SSomnath Kotur * the difference between this counter ID and the starting 4259cf9c838SSomnath Kotur * counter ID. Also, keep track of num of active counter enabled 4269cf9c838SSomnath Kotur * flows. 4279cf9c838SSomnath Kotur * 4289cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 4299cf9c838SSomnath Kotur * 4309cf9c838SSomnath Kotur * dir [in] The direction of the flow 4319cf9c838SSomnath Kotur * 4329cf9c838SSomnath Kotur * hw_cntr_id [in] The HW flow counter ID 4339cf9c838SSomnath Kotur * 4349cf9c838SSomnath Kotur */ 4359cf9c838SSomnath Kotur int32_t ulp_fc_mgr_cntr_set(struct bnxt_ulp_context *ctxt, enum tf_dir dir, 436d9e70b1dSRandy Schacher uint32_t hw_cntr_id, 437d9e70b1dSRandy Schacher enum bnxt_ulp_session_type session_type) 4389cf9c838SSomnath Kotur { 4399cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 4409cf9c838SSomnath Kotur uint32_t sw_cntr_idx; 4419cf9c838SSomnath Kotur 4429cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 4439cf9c838SSomnath Kotur if (!ulp_fc_info) 4449cf9c838SSomnath Kotur return -EIO; 4459cf9c838SSomnath Kotur 4461993b267SShahaji Bhosle if (!ulp_fc_info->num_counters) 4471993b267SShahaji Bhosle return 0; 4481993b267SShahaji Bhosle 4499cf9c838SSomnath Kotur pthread_mutex_lock(&ulp_fc_info->fc_lock); 4509cf9c838SSomnath Kotur sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx; 4519cf9c838SSomnath Kotur ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = true; 452306c2d28SSomnath Kotur ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = hw_cntr_id; 453d9e70b1dSRandy Schacher ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].session_type = session_type; 4549cf9c838SSomnath Kotur ulp_fc_info->num_entries++; 4559cf9c838SSomnath Kotur pthread_mutex_unlock(&ulp_fc_info->fc_lock); 4569cf9c838SSomnath Kotur 4579cf9c838SSomnath Kotur return 0; 4589cf9c838SSomnath Kotur } 4599cf9c838SSomnath Kotur 4609cf9c838SSomnath Kotur /* 4619cf9c838SSomnath Kotur * Reset the corresponding SW accumulator table entry based on 4629cf9c838SSomnath Kotur * the difference between this counter ID and the starting 4639cf9c838SSomnath Kotur * counter ID. 4649cf9c838SSomnath Kotur * 4659cf9c838SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 4669cf9c838SSomnath Kotur * 4679cf9c838SSomnath Kotur * dir [in] The direction of the flow 4689cf9c838SSomnath Kotur * 4699cf9c838SSomnath Kotur * hw_cntr_id [in] The HW flow counter ID 4709cf9c838SSomnath Kotur * 4719cf9c838SSomnath Kotur */ 472dd0191d5SShuanglin Wang int32_t ulp_fc_mgr_cntr_reset(struct bnxt_ulp_context *ctxt, uint8_t dir, 4739cf9c838SSomnath Kotur uint32_t hw_cntr_id) 4749cf9c838SSomnath Kotur { 4759cf9c838SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 4769cf9c838SSomnath Kotur uint32_t sw_cntr_idx; 4779cf9c838SSomnath Kotur 4789cf9c838SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 4799cf9c838SSomnath Kotur if (!ulp_fc_info) 4809cf9c838SSomnath Kotur return -EIO; 4819cf9c838SSomnath Kotur 4821993b267SShahaji Bhosle if (!ulp_fc_info->num_counters) 4831993b267SShahaji Bhosle return 0; 4841993b267SShahaji Bhosle 4859cf9c838SSomnath Kotur pthread_mutex_lock(&ulp_fc_info->fc_lock); 4869cf9c838SSomnath Kotur sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx; 4879cf9c838SSomnath Kotur ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid = false; 488306c2d28SSomnath Kotur ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].hw_cntr_id = 0; 4896d160d77SRandy Schacher ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].session_type = 0; 4909cf9c838SSomnath Kotur ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pkt_count = 0; 4919cf9c838SSomnath Kotur ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].byte_count = 0; 492bdf4a3c6SKishore Padmanabha ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pc_flow_idx = 0; 4939cf9c838SSomnath Kotur ulp_fc_info->num_entries--; 4949cf9c838SSomnath Kotur pthread_mutex_unlock(&ulp_fc_info->fc_lock); 4959cf9c838SSomnath Kotur 4969cf9c838SSomnath Kotur return 0; 4979cf9c838SSomnath Kotur } 498306c2d28SSomnath Kotur 499306c2d28SSomnath Kotur /* 500306c2d28SSomnath Kotur * Fill the rte_flow_query_count 'data' argument passed 501306c2d28SSomnath Kotur * in the rte_flow_query() with the values obtained and 502306c2d28SSomnath Kotur * accumulated locally. 503306c2d28SSomnath Kotur * 504306c2d28SSomnath Kotur * ctxt [in] The ulp context for the flow counter manager 505306c2d28SSomnath Kotur * 506306c2d28SSomnath Kotur * flow_id [in] The HW flow ID 507306c2d28SSomnath Kotur * 508306c2d28SSomnath Kotur * count [out] The rte_flow_query_count 'data' that is set 509306c2d28SSomnath Kotur * 510306c2d28SSomnath Kotur */ 511306c2d28SSomnath Kotur int ulp_fc_mgr_query_count_get(struct bnxt_ulp_context *ctxt, 512306c2d28SSomnath Kotur uint32_t flow_id, 513306c2d28SSomnath Kotur struct rte_flow_query_count *count) 514306c2d28SSomnath Kotur { 515306c2d28SSomnath Kotur int rc = 0; 516306c2d28SSomnath Kotur uint32_t nxt_resource_index = 0; 517306c2d28SSomnath Kotur struct bnxt_ulp_fc_info *ulp_fc_info; 518dd0191d5SShuanglin Wang const struct bnxt_ulp_fc_core_ops *fc_ops; 519306c2d28SSomnath Kotur struct ulp_flow_db_res_params params; 520306c2d28SSomnath Kotur uint32_t hw_cntr_id = 0, sw_cntr_idx = 0; 52148d1c589SSomnath Kotur struct sw_acc_counter *sw_acc_tbl_entry; 522306c2d28SSomnath Kotur bool found_cntr_resource = false; 523bdf4a3c6SKishore Padmanabha bool found_parent_flow = false; 524bdf4a3c6SKishore Padmanabha uint32_t pc_idx = 0; 525f6e12015SKishore Padmanabha uint32_t session_type = 0; 526dd0191d5SShuanglin Wang uint8_t dir; 527306c2d28SSomnath Kotur 528306c2d28SSomnath Kotur ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 529306c2d28SSomnath Kotur if (!ulp_fc_info) 530306c2d28SSomnath Kotur return -ENODEV; 531306c2d28SSomnath Kotur 532dd0191d5SShuanglin Wang fc_ops = ulp_fc_info->fc_ops; 533dd0191d5SShuanglin Wang 5341f3106d4SSomnath Kotur if (bnxt_ulp_cntxt_acquire_fdb_lock(ctxt)) 5351f3106d4SSomnath Kotur return -EIO; 5361f3106d4SSomnath Kotur 537306c2d28SSomnath Kotur do { 538306c2d28SSomnath Kotur rc = ulp_flow_db_resource_get(ctxt, 53930683082SKishore Padmanabha BNXT_ULP_FDB_TYPE_REGULAR, 540306c2d28SSomnath Kotur flow_id, 541306c2d28SSomnath Kotur &nxt_resource_index, 542306c2d28SSomnath Kotur ¶ms); 543306c2d28SSomnath Kotur if (params.resource_func == 544306c2d28SSomnath Kotur BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE && 545306c2d28SSomnath Kotur (params.resource_sub_type == 5469cbfa4cfSKishore Padmanabha BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT || 547306c2d28SSomnath Kotur params.resource_sub_type == 548bdf4a3c6SKishore Padmanabha BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_EXT_COUNT)) { 549306c2d28SSomnath Kotur found_cntr_resource = true; 550306c2d28SSomnath Kotur break; 551306c2d28SSomnath Kotur } 552dd0191d5SShuanglin Wang if (params.resource_func == BNXT_ULP_RESOURCE_FUNC_CMM_STAT) { 553dd0191d5SShuanglin Wang found_cntr_resource = true; 554dd0191d5SShuanglin Wang break; 555dd0191d5SShuanglin Wang } 556bdf4a3c6SKishore Padmanabha if (params.resource_func == 557bdf4a3c6SKishore Padmanabha BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW) { 558bdf4a3c6SKishore Padmanabha found_parent_flow = true; 559bdf4a3c6SKishore Padmanabha pc_idx = params.resource_hndl; 560bdf4a3c6SKishore Padmanabha } 561bdf4a3c6SKishore Padmanabha 5621f3106d4SSomnath Kotur } while (!rc && nxt_resource_index); 563306c2d28SSomnath Kotur 5648782e4deSKishore Padmanabha if (rc || !found_cntr_resource) { 5651f3106d4SSomnath Kotur bnxt_ulp_cntxt_release_fdb_lock(ctxt); 566306c2d28SSomnath Kotur return rc; 5678782e4deSKishore Padmanabha } 568306c2d28SSomnath Kotur 569306c2d28SSomnath Kotur dir = params.direction; 570f6e12015SKishore Padmanabha session_type = ulp_flow_db_shared_session_get(¶ms); 5718782e4deSKishore Padmanabha if (!(ulp_fc_info->flags & ULP_FLAG_FC_SW_AGG_EN)) { 572f6e12015SKishore Padmanabha rc = fc_ops->ulp_flow_stat_get(ctxt, dir, session_type, 57349cdf043SKishore Padmanabha params.resource_hndl, count); 5748782e4deSKishore Padmanabha bnxt_ulp_cntxt_release_fdb_lock(ctxt); 5758782e4deSKishore Padmanabha return rc; 5768782e4deSKishore Padmanabha } 57749cdf043SKishore Padmanabha 578bdf4a3c6SKishore Padmanabha if (!found_parent_flow && 579bdf4a3c6SKishore Padmanabha params.resource_sub_type == 5809cbfa4cfSKishore Padmanabha BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT) { 581dd0191d5SShuanglin Wang hw_cntr_id = params.resource_hndl; 5828782e4deSKishore Padmanabha if (!ulp_fc_info->num_counters) { 583f6e12015SKishore Padmanabha rc = fc_ops->ulp_flow_stat_get(ctxt, dir, session_type, 584dd0191d5SShuanglin Wang hw_cntr_id, count); 5858782e4deSKishore Padmanabha bnxt_ulp_cntxt_release_fdb_lock(ctxt); 5868782e4deSKishore Padmanabha return rc; 5878782e4deSKishore Padmanabha } 5881993b267SShahaji Bhosle 5899cbfa4cfSKishore Padmanabha /* TODO: 5909cbfa4cfSKishore Padmanabha * Think about optimizing with try_lock later 5919cbfa4cfSKishore Padmanabha */ 59248d1c589SSomnath Kotur pthread_mutex_lock(&ulp_fc_info->fc_lock); 593640bfd23SKishore Padmanabha sw_cntr_idx = hw_cntr_id - 594640bfd23SKishore Padmanabha ulp_fc_info->shadow_hw_tbl[dir].start_idx; 595640bfd23SKishore Padmanabha sw_acc_tbl_entry = &ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx]; 59648d1c589SSomnath Kotur if (sw_acc_tbl_entry->pkt_count) { 597306c2d28SSomnath Kotur count->hits_set = 1; 598306c2d28SSomnath Kotur count->bytes_set = 1; 59948d1c589SSomnath Kotur count->hits = sw_acc_tbl_entry->pkt_count; 60048d1c589SSomnath Kotur count->bytes = sw_acc_tbl_entry->byte_count; 60148d1c589SSomnath Kotur } 60248d1c589SSomnath Kotur if (count->reset) { 60348d1c589SSomnath Kotur sw_acc_tbl_entry->pkt_count = 0; 60448d1c589SSomnath Kotur sw_acc_tbl_entry->byte_count = 0; 60548d1c589SSomnath Kotur } 60648d1c589SSomnath Kotur pthread_mutex_unlock(&ulp_fc_info->fc_lock); 607bdf4a3c6SKishore Padmanabha } else if (found_parent_flow && 608bdf4a3c6SKishore Padmanabha params.resource_sub_type == 609bdf4a3c6SKishore Padmanabha BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT) { 610ddaf0afaSKishore Padmanabha /* Get stats from the parent child table */ 6118782e4deSKishore Padmanabha if (ulp_flow_db_parent_flow_count_get(ctxt, flow_id, 6128782e4deSKishore Padmanabha pc_idx, 6138782e4deSKishore Padmanabha &count->hits, 6148782e4deSKishore Padmanabha &count->bytes, 6158782e4deSKishore Padmanabha count->reset)) { 6168782e4deSKishore Padmanabha bnxt_ulp_cntxt_release_fdb_lock(ctxt); 6178782e4deSKishore Padmanabha return -EIO; 6188782e4deSKishore Padmanabha } 619bdf4a3c6SKishore Padmanabha if (count->hits) 620640bfd23SKishore Padmanabha count->hits_set = 1; 621bdf4a3c6SKishore Padmanabha if (count->bytes) 622640bfd23SKishore Padmanabha count->bytes_set = 1; 623306c2d28SSomnath Kotur } else { 624306c2d28SSomnath Kotur rc = -EINVAL; 625306c2d28SSomnath Kotur } 6268782e4deSKishore Padmanabha bnxt_ulp_cntxt_release_fdb_lock(ctxt); 627306c2d28SSomnath Kotur return rc; 628306c2d28SSomnath Kotur } 629640bfd23SKishore Padmanabha 630640bfd23SKishore Padmanabha /* 631640bfd23SKishore Padmanabha * Set the parent flow if it is SW accumulation counter entry. 632640bfd23SKishore Padmanabha * 633640bfd23SKishore Padmanabha * ctxt [in] The ulp context for the flow counter manager 634640bfd23SKishore Padmanabha * 635640bfd23SKishore Padmanabha * dir [in] The direction of the flow 636640bfd23SKishore Padmanabha * 637640bfd23SKishore Padmanabha * hw_cntr_id [in] The HW flow counter ID 638640bfd23SKishore Padmanabha * 639bdf4a3c6SKishore Padmanabha * pc_idx [in] parent child db index 640640bfd23SKishore Padmanabha * 641640bfd23SKishore Padmanabha */ 642640bfd23SKishore Padmanabha int32_t ulp_fc_mgr_cntr_parent_flow_set(struct bnxt_ulp_context *ctxt, 643dd0191d5SShuanglin Wang uint8_t dir, 644640bfd23SKishore Padmanabha uint32_t hw_cntr_id, 645bdf4a3c6SKishore Padmanabha uint32_t pc_idx) 646640bfd23SKishore Padmanabha { 647640bfd23SKishore Padmanabha struct bnxt_ulp_fc_info *ulp_fc_info; 648640bfd23SKishore Padmanabha uint32_t sw_cntr_idx; 649640bfd23SKishore Padmanabha int32_t rc = 0; 650640bfd23SKishore Padmanabha 651640bfd23SKishore Padmanabha ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ctxt); 652640bfd23SKishore Padmanabha if (!ulp_fc_info) 653640bfd23SKishore Padmanabha return -EIO; 654640bfd23SKishore Padmanabha 655640bfd23SKishore Padmanabha pthread_mutex_lock(&ulp_fc_info->fc_lock); 656640bfd23SKishore Padmanabha sw_cntr_idx = hw_cntr_id - ulp_fc_info->shadow_hw_tbl[dir].start_idx; 657640bfd23SKishore Padmanabha if (ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].valid) { 658bdf4a3c6SKishore Padmanabha pc_idx |= FLOW_CNTR_PC_FLOW_VALID; 659bdf4a3c6SKishore Padmanabha ulp_fc_info->sw_acc_tbl[dir][sw_cntr_idx].pc_flow_idx = pc_idx; 660640bfd23SKishore Padmanabha } else { 661dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to set parent flow id %x:%x\n", 662bdf4a3c6SKishore Padmanabha hw_cntr_id, pc_idx); 663640bfd23SKishore Padmanabha rc = -ENOENT; 664640bfd23SKishore Padmanabha } 665640bfd23SKishore Padmanabha pthread_mutex_unlock(&ulp_fc_info->fc_lock); 666640bfd23SKishore Padmanabha 667640bfd23SKishore Padmanabha return rc; 668640bfd23SKishore Padmanabha } 669