1313ac35aSVenkat Duvvuru /* SPDX-License-Identifier: BSD-3-Clause 2d9e70b1dSRandy Schacher * Copyright(c) 2014-2023 Broadcom 3313ac35aSVenkat Duvvuru * All rights reserved. 4313ac35aSVenkat Duvvuru */ 5313ac35aSVenkat Duvvuru 6191128d7SDavid Marchand #include <rte_bitops.h> 7313ac35aSVenkat Duvvuru #include <rte_malloc.h> 8191128d7SDavid Marchand 9313ac35aSVenkat Duvvuru #include "bnxt.h" 10313ac35aSVenkat Duvvuru #include "bnxt_tf_common.h" 110c036a14SPeter Spreadborough #include "bnxt_ulp_utils.h" 12313ac35aSVenkat Duvvuru #include "ulp_template_struct.h" 13696843ccSMike Baucom #include "ulp_mapper.h" 14be8acb27SKishore Padmanabha #include "ulp_flow_db.h" 159cf9c838SSomnath Kotur #include "ulp_fc_mgr.h" 160513f0afSPeter Spreadborough #include "ulp_sc_mgr.h" 17675e31d8SVenkat Duvvuru #include "ulp_tun.h" 18288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 19288becfbSShuanglin Wang #include "tf_resources.h" 20ffbc3529SShuanglin Wang #include "tfc_resources.h" 21288becfbSShuanglin Wang #endif /* TF_FLOW_SCALE_QUERY */ 22696843ccSMike Baucom 23696843ccSMike Baucom #define ULP_FLOW_DB_RES_DIR_BIT 31 24696843ccSMike Baucom #define ULP_FLOW_DB_RES_DIR_MASK 0x80000000 25f6e12015SKishore Padmanabha #define ULP_FLOW_DB_RES_NXT_MASK 0x7FFFFFFF 26696843ccSMike Baucom 27696843ccSMike Baucom /* Macro to copy the nxt_resource_idx */ 28696843ccSMike Baucom #define ULP_FLOW_DB_RES_NXT_SET(dst, src) {(dst) |= ((src) &\ 29696843ccSMike Baucom ULP_FLOW_DB_RES_NXT_MASK); } 30696843ccSMike Baucom #define ULP_FLOW_DB_RES_NXT_RESET(dst) ((dst) &= ~(ULP_FLOW_DB_RES_NXT_MASK)) 31696843ccSMike Baucom 32696843ccSMike Baucom /* 3330683082SKishore Padmanabha * Helper function to set the bit in the active flows 3405a11d7dSMike Baucom * No validation is done in this function. 3505a11d7dSMike Baucom * 3630683082SKishore Padmanabha * flow_db [in] Ptr to flow database 3730683082SKishore Padmanabha * flow_type [in] - specify default or regular 3805a11d7dSMike Baucom * idx [in] The index to bit to be set or reset. 3905a11d7dSMike Baucom * flag [in] 1 to set and 0 to reset. 4005a11d7dSMike Baucom * 4105a11d7dSMike Baucom * returns none 4205a11d7dSMike Baucom */ 4305a11d7dSMike Baucom static void 4430683082SKishore Padmanabha ulp_flow_db_active_flows_bit_set(struct bnxt_ulp_flow_db *flow_db, 4530683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 4605a11d7dSMike Baucom uint32_t idx, 4705a11d7dSMike Baucom uint32_t flag) 4805a11d7dSMike Baucom { 4930683082SKishore Padmanabha struct bnxt_ulp_flow_tbl *f_tbl = &flow_db->flow_tbl; 5030683082SKishore Padmanabha uint32_t a_idx = idx / ULP_INDEX_BITMAP_SIZE; 5105a11d7dSMike Baucom 5230683082SKishore Padmanabha if (flag) { 53ddaf0afaSKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR || flow_type == 54ddaf0afaSKishore Padmanabha BNXT_ULP_FDB_TYPE_RID) 5530683082SKishore Padmanabha ULP_INDEX_BITMAP_SET(f_tbl->active_reg_flows[a_idx], 5605a11d7dSMike Baucom idx); 57ddaf0afaSKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_DEFAULT || flow_type == 58ddaf0afaSKishore Padmanabha BNXT_ULP_FDB_TYPE_RID) 5930683082SKishore Padmanabha ULP_INDEX_BITMAP_SET(f_tbl->active_dflt_flows[a_idx], 6005a11d7dSMike Baucom idx); 6130683082SKishore Padmanabha } else { 62ddaf0afaSKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR || flow_type == 63ddaf0afaSKishore Padmanabha BNXT_ULP_FDB_TYPE_RID) 6430683082SKishore Padmanabha ULP_INDEX_BITMAP_RESET(f_tbl->active_reg_flows[a_idx], 6530683082SKishore Padmanabha idx); 66ddaf0afaSKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_DEFAULT || flow_type == 67ddaf0afaSKishore Padmanabha BNXT_ULP_FDB_TYPE_RID) 6830683082SKishore Padmanabha ULP_INDEX_BITMAP_RESET(f_tbl->active_dflt_flows[a_idx], 6930683082SKishore Padmanabha idx); 7030683082SKishore Padmanabha } 7105a11d7dSMike Baucom } 7205a11d7dSMike Baucom 7305a11d7dSMike Baucom /* 7430683082SKishore Padmanabha * Helper function to check if given fid is active flow. 7530683082SKishore Padmanabha * No validation being done in this function. 76696843ccSMike Baucom * 7730683082SKishore Padmanabha * flow_db [in] Ptr to flow database 7830683082SKishore Padmanabha * flow_type [in] - specify default or regular 79696843ccSMike Baucom * idx [in] The index to bit to be set or reset. 80696843ccSMike Baucom * 81696843ccSMike Baucom * returns 1 on set or 0 if not set. 82696843ccSMike Baucom */ 83696843ccSMike Baucom static int32_t 8430683082SKishore Padmanabha ulp_flow_db_active_flows_bit_is_set(struct bnxt_ulp_flow_db *flow_db, 8530683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 86696843ccSMike Baucom uint32_t idx) 87696843ccSMike Baucom { 8830683082SKishore Padmanabha struct bnxt_ulp_flow_tbl *f_tbl = &flow_db->flow_tbl; 8930683082SKishore Padmanabha uint32_t a_idx = idx / ULP_INDEX_BITMAP_SIZE; 90ddaf0afaSKishore Padmanabha uint32_t reg, dflt; 91696843ccSMike Baucom 92ddaf0afaSKishore Padmanabha reg = ULP_INDEX_BITMAP_GET(f_tbl->active_reg_flows[a_idx], idx); 93ddaf0afaSKishore Padmanabha dflt = ULP_INDEX_BITMAP_GET(f_tbl->active_dflt_flows[a_idx], idx); 94ddaf0afaSKishore Padmanabha 95ddaf0afaSKishore Padmanabha switch (flow_type) { 96ddaf0afaSKishore Padmanabha case BNXT_ULP_FDB_TYPE_REGULAR: 97ddaf0afaSKishore Padmanabha return (reg && !dflt); 98ddaf0afaSKishore Padmanabha case BNXT_ULP_FDB_TYPE_DEFAULT: 99ddaf0afaSKishore Padmanabha return (!reg && dflt); 100ddaf0afaSKishore Padmanabha case BNXT_ULP_FDB_TYPE_RID: 101ddaf0afaSKishore Padmanabha return (reg && dflt); 102ddaf0afaSKishore Padmanabha default: 103ddaf0afaSKishore Padmanabha return 0; 104ddaf0afaSKishore Padmanabha } 105696843ccSMike Baucom } 106696843ccSMike Baucom 107be8acb27SKishore Padmanabha static inline enum tf_dir 108be8acb27SKishore Padmanabha ulp_flow_db_resource_dir_get(struct ulp_fdb_resource_info *res_info) 109be8acb27SKishore Padmanabha { 110be8acb27SKishore Padmanabha return ((res_info->nxt_resource_idx & ULP_FLOW_DB_RES_DIR_MASK) >> 111be8acb27SKishore Padmanabha ULP_FLOW_DB_RES_DIR_BIT); 112be8acb27SKishore Padmanabha } 113be8acb27SKishore Padmanabha 114f6e12015SKishore Padmanabha static inline uint8_t 115d310d59cSKishore Padmanabha ulp_flow_db_resource_func_get(struct ulp_fdb_resource_info *res_info) 116d310d59cSKishore Padmanabha { 117f6e12015SKishore Padmanabha return res_info->resource_func; 118d310d59cSKishore Padmanabha } 119d310d59cSKishore Padmanabha 120696843ccSMike Baucom /* 121696843ccSMike Baucom * Helper function to copy the resource params to resource info 122696843ccSMike Baucom * No validation being done in this function. 123696843ccSMike Baucom * 124696843ccSMike Baucom * resource_info [out] Ptr to resource information 125696843ccSMike Baucom * params [in] The input params from the caller 126696843ccSMike Baucom * returns none 127696843ccSMike Baucom */ 128696843ccSMike Baucom static void 129696843ccSMike Baucom ulp_flow_db_res_params_to_info(struct ulp_fdb_resource_info *resource_info, 130696843ccSMike Baucom struct ulp_flow_db_res_params *params) 131696843ccSMike Baucom { 132696843ccSMike Baucom resource_info->nxt_resource_idx |= ((params->direction << 133696843ccSMike Baucom ULP_FLOW_DB_RES_DIR_BIT) & 134696843ccSMike Baucom ULP_FLOW_DB_RES_DIR_MASK); 135f6e12015SKishore Padmanabha resource_info->resource_func = params->resource_func; 136696843ccSMike Baucom resource_info->resource_type = params->resource_type; 137efcb502fSKishore Padmanabha resource_info->resource_sub_type = params->resource_sub_type; 13819994cc7SKishore Padmanabha resource_info->fdb_flags = params->fdb_flags; 139f6e12015SKishore Padmanabha resource_info->resource_hndl = params->resource_hndl; 140696843ccSMike Baucom } 141313ac35aSVenkat Duvvuru 142313ac35aSVenkat Duvvuru /* 14305a11d7dSMike Baucom * Helper function to copy the resource params to resource info 14405a11d7dSMike Baucom * No validation being done in this function. 14505a11d7dSMike Baucom * 14605a11d7dSMike Baucom * resource_info [in] Ptr to resource information 14705a11d7dSMike Baucom * params [out] The output params to the caller 14805a11d7dSMike Baucom * 14905a11d7dSMike Baucom * returns none 15005a11d7dSMike Baucom */ 15105a11d7dSMike Baucom static void 15205a11d7dSMike Baucom ulp_flow_db_res_info_to_params(struct ulp_fdb_resource_info *resource_info, 15305a11d7dSMike Baucom struct ulp_flow_db_res_params *params) 15405a11d7dSMike Baucom { 15505a11d7dSMike Baucom memset(params, 0, sizeof(struct ulp_flow_db_res_params)); 156d310d59cSKishore Padmanabha /* use the helper function to get the resource func */ 157be8acb27SKishore Padmanabha params->direction = ulp_flow_db_resource_dir_get(resource_info); 158d310d59cSKishore Padmanabha params->resource_func = ulp_flow_db_resource_func_get(resource_info); 15905a11d7dSMike Baucom params->resource_type = resource_info->resource_type; 160efcb502fSKishore Padmanabha params->resource_sub_type = resource_info->resource_sub_type; 16119994cc7SKishore Padmanabha params->fdb_flags = resource_info->fdb_flags; 162f6e12015SKishore Padmanabha params->resource_hndl = resource_info->resource_hndl; 16305a11d7dSMike Baucom } 16405a11d7dSMike Baucom 16505a11d7dSMike Baucom /* 166313ac35aSVenkat Duvvuru * Helper function to allocate the flow table and initialize 167313ac35aSVenkat Duvvuru * the stack for allocation operations. 168313ac35aSVenkat Duvvuru * 169313ac35aSVenkat Duvvuru * flow_db [in] Ptr to flow database structure 170313ac35aSVenkat Duvvuru * 171313ac35aSVenkat Duvvuru * Returns 0 on success or negative number on failure. 172313ac35aSVenkat Duvvuru */ 173313ac35aSVenkat Duvvuru static int32_t 17430683082SKishore Padmanabha ulp_flow_db_alloc_resource(struct bnxt_ulp_flow_db *flow_db) 175313ac35aSVenkat Duvvuru { 176313ac35aSVenkat Duvvuru uint32_t idx = 0; 177313ac35aSVenkat Duvvuru struct bnxt_ulp_flow_tbl *flow_tbl; 178313ac35aSVenkat Duvvuru uint32_t size; 179313ac35aSVenkat Duvvuru 18030683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 181313ac35aSVenkat Duvvuru 182313ac35aSVenkat Duvvuru size = sizeof(struct ulp_fdb_resource_info) * flow_tbl->num_resources; 183313ac35aSVenkat Duvvuru flow_tbl->flow_resources = 184313ac35aSVenkat Duvvuru rte_zmalloc("ulp_fdb_resource_info", size, 0); 185313ac35aSVenkat Duvvuru 186313ac35aSVenkat Duvvuru if (!flow_tbl->flow_resources) { 187dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to alloc memory for flow table\n"); 188313ac35aSVenkat Duvvuru return -ENOMEM; 189313ac35aSVenkat Duvvuru } 190313ac35aSVenkat Duvvuru size = sizeof(uint32_t) * flow_tbl->num_resources; 191313ac35aSVenkat Duvvuru flow_tbl->flow_tbl_stack = rte_zmalloc("flow_tbl_stack", size, 0); 192313ac35aSVenkat Duvvuru if (!flow_tbl->flow_tbl_stack) { 193dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to alloc memory flow tbl stack\n"); 194313ac35aSVenkat Duvvuru return -ENOMEM; 195313ac35aSVenkat Duvvuru } 196313ac35aSVenkat Duvvuru size = (flow_tbl->num_flows / sizeof(uint64_t)) + 1; 197f4a4421cSKishore Padmanabha size = ULP_BYTE_ROUND_OFF_8(size); 198f4a4421cSKishore Padmanabha flow_tbl->active_reg_flows = rte_zmalloc("active reg flows", size, 199f4a4421cSKishore Padmanabha ULP_BUFFER_ALIGN_64_BYTE); 20030683082SKishore Padmanabha if (!flow_tbl->active_reg_flows) { 201dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to alloc memory active reg flows\n"); 20230683082SKishore Padmanabha return -ENOMEM; 20330683082SKishore Padmanabha } 20430683082SKishore Padmanabha 205f4a4421cSKishore Padmanabha flow_tbl->active_dflt_flows = rte_zmalloc("active dflt flows", size, 206f4a4421cSKishore Padmanabha ULP_BUFFER_ALIGN_64_BYTE); 20730683082SKishore Padmanabha if (!flow_tbl->active_dflt_flows) { 208dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Failed to alloc memory active dflt flows\n"); 209313ac35aSVenkat Duvvuru return -ENOMEM; 210313ac35aSVenkat Duvvuru } 211313ac35aSVenkat Duvvuru 212313ac35aSVenkat Duvvuru /* Initialize the stack table. */ 213313ac35aSVenkat Duvvuru for (idx = 0; idx < flow_tbl->num_resources; idx++) 214313ac35aSVenkat Duvvuru flow_tbl->flow_tbl_stack[idx] = idx; 215313ac35aSVenkat Duvvuru 216313ac35aSVenkat Duvvuru /* Ignore the first element in the list. */ 217313ac35aSVenkat Duvvuru flow_tbl->head_index = 1; 218313ac35aSVenkat Duvvuru /* Tail points to the last entry in the list. */ 219313ac35aSVenkat Duvvuru flow_tbl->tail_index = flow_tbl->num_resources - 1; 220313ac35aSVenkat Duvvuru return 0; 221313ac35aSVenkat Duvvuru } 222313ac35aSVenkat Duvvuru 223313ac35aSVenkat Duvvuru /* 224313ac35aSVenkat Duvvuru * Helper function to deallocate the flow table. 225313ac35aSVenkat Duvvuru * 226313ac35aSVenkat Duvvuru * flow_db [in] Ptr to flow database structure 227313ac35aSVenkat Duvvuru * 228313ac35aSVenkat Duvvuru * Returns none. 229313ac35aSVenkat Duvvuru */ 230313ac35aSVenkat Duvvuru static void 23130683082SKishore Padmanabha ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db) 232313ac35aSVenkat Duvvuru { 23330683082SKishore Padmanabha struct bnxt_ulp_flow_tbl *flow_tbl = &flow_db->flow_tbl; 234313ac35aSVenkat Duvvuru 235313ac35aSVenkat Duvvuru /* Free all the allocated tables in the flow table. */ 23630683082SKishore Padmanabha if (flow_tbl->active_reg_flows) { 23730683082SKishore Padmanabha rte_free(flow_tbl->active_reg_flows); 23830683082SKishore Padmanabha flow_tbl->active_reg_flows = NULL; 23930683082SKishore Padmanabha } 24030683082SKishore Padmanabha if (flow_tbl->active_dflt_flows) { 24130683082SKishore Padmanabha rte_free(flow_tbl->active_dflt_flows); 24230683082SKishore Padmanabha flow_tbl->active_dflt_flows = NULL; 243313ac35aSVenkat Duvvuru } 244313ac35aSVenkat Duvvuru 245313ac35aSVenkat Duvvuru if (flow_tbl->flow_tbl_stack) { 246313ac35aSVenkat Duvvuru rte_free(flow_tbl->flow_tbl_stack); 247313ac35aSVenkat Duvvuru flow_tbl->flow_tbl_stack = NULL; 248313ac35aSVenkat Duvvuru } 249313ac35aSVenkat Duvvuru 250313ac35aSVenkat Duvvuru if (flow_tbl->flow_resources) { 251313ac35aSVenkat Duvvuru rte_free(flow_tbl->flow_resources); 252313ac35aSVenkat Duvvuru flow_tbl->flow_resources = NULL; 253313ac35aSVenkat Duvvuru } 254313ac35aSVenkat Duvvuru } 255313ac35aSVenkat Duvvuru 256313ac35aSVenkat Duvvuru /* 25774bcfc06SKishore Padmanabha * Helper function to add function id to the flow table 25874bcfc06SKishore Padmanabha * 25974bcfc06SKishore Padmanabha * flow_db [in] Ptr to flow table 26074bcfc06SKishore Padmanabha * flow_id [in] The flow id of the flow 26174bcfc06SKishore Padmanabha * func_id [in] The func_id to be set, for reset pass zero 26274bcfc06SKishore Padmanabha * 26374bcfc06SKishore Padmanabha * returns none 26474bcfc06SKishore Padmanabha */ 26574bcfc06SKishore Padmanabha static void 26674bcfc06SKishore Padmanabha ulp_flow_db_func_id_set(struct bnxt_ulp_flow_db *flow_db, 26774bcfc06SKishore Padmanabha uint32_t flow_id, 26874bcfc06SKishore Padmanabha uint32_t func_id) 26974bcfc06SKishore Padmanabha { 27074bcfc06SKishore Padmanabha /* set the function id in the function table */ 27174bcfc06SKishore Padmanabha if (flow_id < flow_db->func_id_tbl_size) 27274bcfc06SKishore Padmanabha flow_db->func_id_tbl[flow_id] = func_id; 27374bcfc06SKishore Padmanabha else /* This should never happen */ 274dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow id, flowdb corrupt\n"); 27574bcfc06SKishore Padmanabha } 27674bcfc06SKishore Padmanabha 27774bcfc06SKishore Padmanabha /* 278f4a4421cSKishore Padmanabha * Initialize the parent-child database. Memory is allocated in this 279f4a4421cSKishore Padmanabha * call and assigned to the database 280f4a4421cSKishore Padmanabha * 281f4a4421cSKishore Padmanabha * flow_db [in] Ptr to flow table 282f4a4421cSKishore Padmanabha * num_entries[in] - number of entries to allocate 283f4a4421cSKishore Padmanabha * 284f4a4421cSKishore Padmanabha * Returns 0 on success or negative number on failure. 285f4a4421cSKishore Padmanabha */ 286f4a4421cSKishore Padmanabha static int32_t 287f4a4421cSKishore Padmanabha ulp_flow_db_parent_tbl_init(struct bnxt_ulp_flow_db *flow_db, 288f4a4421cSKishore Padmanabha uint32_t num_entries) 289f4a4421cSKishore Padmanabha { 290f4a4421cSKishore Padmanabha struct ulp_fdb_parent_child_db *p_db; 291f4a4421cSKishore Padmanabha uint32_t size, idx; 292f4a4421cSKishore Padmanabha 293be8acb27SKishore Padmanabha if (!num_entries) 294be8acb27SKishore Padmanabha return 0; 295be8acb27SKishore Padmanabha 296f4a4421cSKishore Padmanabha /* update the sizes for the allocation */ 297f4a4421cSKishore Padmanabha p_db = &flow_db->parent_child_db; 298f4a4421cSKishore Padmanabha p_db->child_bitset_size = (flow_db->flow_tbl.num_flows / 299f4a4421cSKishore Padmanabha sizeof(uint64_t)) + 1; /* size in bytes */ 300f4a4421cSKishore Padmanabha p_db->child_bitset_size = ULP_BYTE_ROUND_OFF_8(p_db->child_bitset_size); 301f4a4421cSKishore Padmanabha p_db->entries_count = num_entries; 302f4a4421cSKishore Padmanabha 303f4a4421cSKishore Padmanabha /* allocate the memory */ 304f4a4421cSKishore Padmanabha p_db->parent_flow_tbl = rte_zmalloc("fdb parent flow tbl", 305f4a4421cSKishore Padmanabha sizeof(struct ulp_fdb_parent_info) * 306f4a4421cSKishore Padmanabha p_db->entries_count, 0); 307f4a4421cSKishore Padmanabha if (!p_db->parent_flow_tbl) { 308dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 309f4a4421cSKishore Padmanabha "Failed to allocate memory fdb parent flow tbl\n"); 310f4a4421cSKishore Padmanabha return -ENOMEM; 311f4a4421cSKishore Padmanabha } 312f4a4421cSKishore Padmanabha size = p_db->child_bitset_size * p_db->entries_count; 313f4a4421cSKishore Padmanabha 314f4a4421cSKishore Padmanabha /* 315f4a4421cSKishore Padmanabha * allocate the big chunk of memory to be statically carved into 316f4a4421cSKishore Padmanabha * child_fid_bitset pointer. 317f4a4421cSKishore Padmanabha */ 318f4a4421cSKishore Padmanabha p_db->parent_flow_tbl_mem = rte_zmalloc("fdb parent flow tbl mem", 319f4a4421cSKishore Padmanabha size, 320f4a4421cSKishore Padmanabha ULP_BUFFER_ALIGN_64_BYTE); 321f4a4421cSKishore Padmanabha if (!p_db->parent_flow_tbl_mem) { 322dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 323f4a4421cSKishore Padmanabha "Failed to allocate memory fdb parent flow mem\n"); 324f4a4421cSKishore Padmanabha return -ENOMEM; 325f4a4421cSKishore Padmanabha } 326f4a4421cSKishore Padmanabha 327f4a4421cSKishore Padmanabha /* set the pointers in parent table to their offsets */ 328f4a4421cSKishore Padmanabha for (idx = 0 ; idx < p_db->entries_count; idx++) { 329f4a4421cSKishore Padmanabha p_db->parent_flow_tbl[idx].child_fid_bitset = 330f4a4421cSKishore Padmanabha (uint64_t *)&p_db->parent_flow_tbl_mem[idx * 331f4a4421cSKishore Padmanabha p_db->child_bitset_size]; 332f4a4421cSKishore Padmanabha } 333f4a4421cSKishore Padmanabha /* success */ 334f4a4421cSKishore Padmanabha return 0; 335f4a4421cSKishore Padmanabha } 336f4a4421cSKishore Padmanabha 337f4a4421cSKishore Padmanabha /* 338f4a4421cSKishore Padmanabha * Deinitialize the parent-child database. Memory is deallocated in 339f4a4421cSKishore Padmanabha * this call and all flows should have been purged before this 340f4a4421cSKishore Padmanabha * call. 341f4a4421cSKishore Padmanabha * 342f4a4421cSKishore Padmanabha * flow_db [in] Ptr to flow table 343f4a4421cSKishore Padmanabha * 344f4a4421cSKishore Padmanabha * Returns none 345f4a4421cSKishore Padmanabha */ 346f4a4421cSKishore Padmanabha static void 347f4a4421cSKishore Padmanabha ulp_flow_db_parent_tbl_deinit(struct bnxt_ulp_flow_db *flow_db) 348f4a4421cSKishore Padmanabha { 349f4a4421cSKishore Padmanabha /* free the memory related to parent child database */ 350f4a4421cSKishore Padmanabha if (flow_db->parent_child_db.parent_flow_tbl_mem) { 351f4a4421cSKishore Padmanabha rte_free(flow_db->parent_child_db.parent_flow_tbl_mem); 352f4a4421cSKishore Padmanabha flow_db->parent_child_db.parent_flow_tbl_mem = NULL; 353f4a4421cSKishore Padmanabha } 354f4a4421cSKishore Padmanabha if (flow_db->parent_child_db.parent_flow_tbl) { 355f4a4421cSKishore Padmanabha rte_free(flow_db->parent_child_db.parent_flow_tbl); 356f4a4421cSKishore Padmanabha flow_db->parent_child_db.parent_flow_tbl = NULL; 357f4a4421cSKishore Padmanabha } 358f4a4421cSKishore Padmanabha } 359f4a4421cSKishore Padmanabha 360f4a4421cSKishore Padmanabha /* 361313ac35aSVenkat Duvvuru * Initialize the flow database. Memory is allocated in this 362313ac35aSVenkat Duvvuru * call and assigned to the flow database. 363313ac35aSVenkat Duvvuru * 364313ac35aSVenkat Duvvuru * ulp_ctxt [in] Ptr to ulp context 365313ac35aSVenkat Duvvuru * 366313ac35aSVenkat Duvvuru * Returns 0 on success or negative number on failure. 367313ac35aSVenkat Duvvuru */ 36830683082SKishore Padmanabha int32_t 36930683082SKishore Padmanabha ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt) 370313ac35aSVenkat Duvvuru { 371313ac35aSVenkat Duvvuru struct bnxt_ulp_device_params *dparms; 372313ac35aSVenkat Duvvuru struct bnxt_ulp_flow_tbl *flow_tbl; 373313ac35aSVenkat Duvvuru struct bnxt_ulp_flow_db *flow_db; 374191f19ceSMike Baucom uint32_t dev_id, num_flows; 375191f19ceSMike Baucom enum bnxt_ulp_flow_mem_type mtype; 376313ac35aSVenkat Duvvuru 377313ac35aSVenkat Duvvuru /* Get the dev specific number of flows that needed to be supported. */ 378313ac35aSVenkat Duvvuru if (bnxt_ulp_cntxt_dev_id_get(ulp_ctxt, &dev_id)) { 379dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid device id\n"); 380313ac35aSVenkat Duvvuru return -EINVAL; 381313ac35aSVenkat Duvvuru } 382313ac35aSVenkat Duvvuru 383313ac35aSVenkat Duvvuru dparms = bnxt_ulp_device_params_get(dev_id); 384313ac35aSVenkat Duvvuru if (!dparms) { 385dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "could not fetch the device params\n"); 386313ac35aSVenkat Duvvuru return -ENODEV; 387313ac35aSVenkat Duvvuru } 388313ac35aSVenkat Duvvuru 389313ac35aSVenkat Duvvuru flow_db = rte_zmalloc("bnxt_ulp_flow_db", 390313ac35aSVenkat Duvvuru sizeof(struct bnxt_ulp_flow_db), 0); 391313ac35aSVenkat Duvvuru if (!flow_db) { 392dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 393313ac35aSVenkat Duvvuru "Failed to allocate memory for flow table ptr\n"); 39474bcfc06SKishore Padmanabha return -ENOMEM; 395313ac35aSVenkat Duvvuru } 396313ac35aSVenkat Duvvuru 397313ac35aSVenkat Duvvuru /* Attach the flow database to the ulp context. */ 398313ac35aSVenkat Duvvuru bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, flow_db); 399313ac35aSVenkat Duvvuru 400191f19ceSMike Baucom /* Determine the number of flows based on EM type */ 4013fe124d2SKishore Padmanabha if (bnxt_ulp_cntxt_mem_type_get(ulp_ctxt, &mtype)) 4023fe124d2SKishore Padmanabha goto error_free; 4033fe124d2SKishore Padmanabha 404191f19ceSMike Baucom if (mtype == BNXT_ULP_FLOW_MEM_TYPE_INT) 405191f19ceSMike Baucom num_flows = dparms->int_flow_db_num_entries; 406191f19ceSMike Baucom else 407191f19ceSMike Baucom num_flows = dparms->ext_flow_db_num_entries; 408191f19ceSMike Baucom 409313ac35aSVenkat Duvvuru /* Populate the regular flow table limits. */ 41030683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 411191f19ceSMike Baucom flow_tbl->num_flows = num_flows + 1; 412191f19ceSMike Baucom flow_tbl->num_resources = ((num_flows + 1) * 413313ac35aSVenkat Duvvuru dparms->num_resources_per_flow); 414313ac35aSVenkat Duvvuru 41530683082SKishore Padmanabha /* Include the default flow table limits. */ 41630683082SKishore Padmanabha flow_tbl->num_flows += (BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1); 41730683082SKishore Padmanabha flow_tbl->num_resources += ((BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1) * 418313ac35aSVenkat Duvvuru BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES); 419313ac35aSVenkat Duvvuru 42030683082SKishore Padmanabha /* Allocate the resource for the flow table. */ 42130683082SKishore Padmanabha if (ulp_flow_db_alloc_resource(flow_db)) 422313ac35aSVenkat Duvvuru goto error_free; 423313ac35aSVenkat Duvvuru 42474bcfc06SKishore Padmanabha /* add 1 since we are not using index 0 for flow id */ 42530683082SKishore Padmanabha flow_db->func_id_tbl_size = flow_tbl->num_flows + 1; 42674bcfc06SKishore Padmanabha /* Allocate the function Id table */ 42774bcfc06SKishore Padmanabha flow_db->func_id_tbl = rte_zmalloc("bnxt_ulp_flow_db_func_id_table", 42874bcfc06SKishore Padmanabha flow_db->func_id_tbl_size * 42974bcfc06SKishore Padmanabha sizeof(uint16_t), 0); 43074bcfc06SKishore Padmanabha if (!flow_db->func_id_tbl) { 431dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 43274bcfc06SKishore Padmanabha "Failed to allocate mem for flow table func id\n"); 43374bcfc06SKishore Padmanabha goto error_free; 43474bcfc06SKishore Padmanabha } 435f4a4421cSKishore Padmanabha /* initialize the parent child database */ 436f4a4421cSKishore Padmanabha if (ulp_flow_db_parent_tbl_init(flow_db, 437f4a4421cSKishore Padmanabha dparms->fdb_parent_flow_entries)) { 438dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, 439f4a4421cSKishore Padmanabha "Failed to allocate mem for parent child db\n"); 440f4a4421cSKishore Padmanabha goto error_free; 441f4a4421cSKishore Padmanabha } 442f4a4421cSKishore Padmanabha 443313ac35aSVenkat Duvvuru /* All good so return. */ 444dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "FlowDB initialized with %d flows.\n", 445191f19ceSMike Baucom flow_tbl->num_flows); 446313ac35aSVenkat Duvvuru return 0; 447313ac35aSVenkat Duvvuru error_free: 448313ac35aSVenkat Duvvuru ulp_flow_db_deinit(ulp_ctxt); 449313ac35aSVenkat Duvvuru return -ENOMEM; 450313ac35aSVenkat Duvvuru } 451313ac35aSVenkat Duvvuru 452313ac35aSVenkat Duvvuru /* 453313ac35aSVenkat Duvvuru * Deinitialize the flow database. Memory is deallocated in 454313ac35aSVenkat Duvvuru * this call and all flows should have been purged before this 455313ac35aSVenkat Duvvuru * call. 456313ac35aSVenkat Duvvuru * 457313ac35aSVenkat Duvvuru * ulp_ctxt [in] Ptr to ulp context 458313ac35aSVenkat Duvvuru * 459313ac35aSVenkat Duvvuru * Returns 0 on success. 460313ac35aSVenkat Duvvuru */ 46130683082SKishore Padmanabha int32_t 46230683082SKishore Padmanabha ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt) 463313ac35aSVenkat Duvvuru { 464313ac35aSVenkat Duvvuru struct bnxt_ulp_flow_db *flow_db; 465313ac35aSVenkat Duvvuru 466313ac35aSVenkat Duvvuru flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 46709b23f8bSKishore Padmanabha if (!flow_db) 468313ac35aSVenkat Duvvuru return -EINVAL; 469313ac35aSVenkat Duvvuru 470313ac35aSVenkat Duvvuru /* Detach the flow database from the ulp context. */ 471313ac35aSVenkat Duvvuru bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL); 472313ac35aSVenkat Duvvuru 473313ac35aSVenkat Duvvuru /* Free up all the memory. */ 474f4a4421cSKishore Padmanabha ulp_flow_db_parent_tbl_deinit(flow_db); 47530683082SKishore Padmanabha ulp_flow_db_dealloc_resource(flow_db); 47674bcfc06SKishore Padmanabha rte_free(flow_db->func_id_tbl); 477313ac35aSVenkat Duvvuru rte_free(flow_db); 478313ac35aSVenkat Duvvuru 479313ac35aSVenkat Duvvuru return 0; 480313ac35aSVenkat Duvvuru } 481696843ccSMike Baucom 482696843ccSMike Baucom /* 4838f153057SMike Baucom * Allocate the flow database entry 4848f153057SMike Baucom * 4858f153057SMike Baucom * ulp_ctxt [in] Ptr to ulp_context 48630683082SKishore Padmanabha * flow_type [in] - specify default or regular 48730683082SKishore Padmanabha * func_id [in].function id of the ingress port 4888f153057SMike Baucom * fid [out] The index to the flow entry 4898f153057SMike Baucom * 4908f153057SMike Baucom * returns 0 on success and negative on failure. 4918f153057SMike Baucom */ 49230683082SKishore Padmanabha int32_t 49330683082SKishore Padmanabha ulp_flow_db_fid_alloc(struct bnxt_ulp_context *ulp_ctxt, 49430683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 49574bcfc06SKishore Padmanabha uint16_t func_id, 4968f153057SMike Baucom uint32_t *fid) 4978f153057SMike Baucom { 4988f153057SMike Baucom struct bnxt_ulp_flow_db *flow_db; 4998f153057SMike Baucom struct bnxt_ulp_flow_tbl *flow_tbl; 5008f153057SMike Baucom 5018f153057SMike Baucom *fid = 0; /* Initialize fid to invalid value */ 5028f153057SMike Baucom flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 5038f153057SMike Baucom if (!flow_db) { 504dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 5058f153057SMike Baucom return -EINVAL; 5068f153057SMike Baucom } 5078f153057SMike Baucom 508ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 509dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 51030683082SKishore Padmanabha return -EINVAL; 51130683082SKishore Padmanabha } 51230683082SKishore Padmanabha 51330683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 5148f153057SMike Baucom /* check for max flows */ 5158f153057SMike Baucom if (flow_tbl->num_flows <= flow_tbl->head_index) { 516dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow database has reached max flows\n"); 5178f153057SMike Baucom return -ENOMEM; 5188f153057SMike Baucom } 5195a640d00SMike Baucom if (flow_tbl->tail_index <= (flow_tbl->head_index + 1)) { 520dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow database has reached max resources\n"); 5215a640d00SMike Baucom return -ENOMEM; 5225a640d00SMike Baucom } 5238f153057SMike Baucom *fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index]; 5248f153057SMike Baucom flow_tbl->head_index++; 5258f153057SMike Baucom 52630683082SKishore Padmanabha /* Set the flow type */ 52730683082SKishore Padmanabha ulp_flow_db_active_flows_bit_set(flow_db, flow_type, *fid, 1); 52830683082SKishore Padmanabha 52930683082SKishore Padmanabha /* function id update is only valid for regular flow table */ 53030683082SKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR) 53174bcfc06SKishore Padmanabha ulp_flow_db_func_id_set(flow_db, *fid, func_id); 53274bcfc06SKishore Padmanabha 533dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 534dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "flow_id = %u:%u allocated\n", flow_type, *fid); 535dd0191d5SShuanglin Wang #endif 53630683082SKishore Padmanabha /* return success */ 5378f153057SMike Baucom return 0; 5388f153057SMike Baucom } 5398f153057SMike Baucom 5408f153057SMike Baucom /* 541696843ccSMike Baucom * Allocate the flow database entry. 542696843ccSMike Baucom * The params->critical_resource has to be set to 0 to allocate a new resource. 543696843ccSMike Baucom * 544696843ccSMike Baucom * ulp_ctxt [in] Ptr to ulp_context 54530683082SKishore Padmanabha * flow_type [in] Specify it is regular or default flow 546696843ccSMike Baucom * fid [in] The index to the flow entry 547696843ccSMike Baucom * params [in] The contents to be copied into resource 548696843ccSMike Baucom * 549696843ccSMike Baucom * returns 0 on success and negative on failure. 550696843ccSMike Baucom */ 55130683082SKishore Padmanabha int32_t 55230683082SKishore Padmanabha ulp_flow_db_resource_add(struct bnxt_ulp_context *ulp_ctxt, 55330683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 554696843ccSMike Baucom uint32_t fid, 555696843ccSMike Baucom struct ulp_flow_db_res_params *params) 556696843ccSMike Baucom { 557696843ccSMike Baucom struct bnxt_ulp_flow_db *flow_db; 558696843ccSMike Baucom struct bnxt_ulp_flow_tbl *flow_tbl; 559696843ccSMike Baucom struct ulp_fdb_resource_info *resource, *fid_resource; 5603fe124d2SKishore Padmanabha struct bnxt_ulp_fc_info *ulp_fc_info; 561696843ccSMike Baucom uint32_t idx; 562696843ccSMike Baucom 563696843ccSMike Baucom flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 564696843ccSMike Baucom if (!flow_db) { 565dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 566696843ccSMike Baucom return -EINVAL; 567696843ccSMike Baucom } 568696843ccSMike Baucom 569ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 570dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 571696843ccSMike Baucom return -EINVAL; 572696843ccSMike Baucom } 573696843ccSMike Baucom 57430683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 575696843ccSMike Baucom /* check for max flows */ 576696843ccSMike Baucom if (fid >= flow_tbl->num_flows || !fid) { 577dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow index\n"); 578696843ccSMike Baucom return -EINVAL; 579696843ccSMike Baucom } 580696843ccSMike Baucom 581696843ccSMike Baucom /* check if the flow is active or not */ 58230683082SKishore Padmanabha if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) { 583dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "flow does not exist %x:%x\n", flow_type, 584dd0191d5SShuanglin Wang fid); 585696843ccSMike Baucom return -EINVAL; 586696843ccSMike Baucom } 587696843ccSMike Baucom 588696843ccSMike Baucom /* check for max resource */ 5895a640d00SMike Baucom if ((flow_tbl->head_index + 1) >= flow_tbl->tail_index) { 590dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db has reached max resources\n"); 591696843ccSMike Baucom return -ENOMEM; 592696843ccSMike Baucom } 593696843ccSMike Baucom fid_resource = &flow_tbl->flow_resources[fid]; 594696843ccSMike Baucom 595f6e12015SKishore Padmanabha if (params->critical_resource && (fid_resource->fdb_flags & 596f6e12015SKishore Padmanabha ULP_FDB_FLAG_CRITICAL_RES)) { 597dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "Ignore multiple critical resources\n"); 5981993b267SShahaji Bhosle /* Ignore the multiple critical resources */ 5991993b267SShahaji Bhosle params->critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO; 6001993b267SShahaji Bhosle } 6011993b267SShahaji Bhosle 602696843ccSMike Baucom if (!params->critical_resource) { 603696843ccSMike Baucom /* Not the critical_resource so allocate a resource */ 604696843ccSMike Baucom idx = flow_tbl->flow_tbl_stack[flow_tbl->tail_index]; 605696843ccSMike Baucom resource = &flow_tbl->flow_resources[idx]; 606696843ccSMike Baucom flow_tbl->tail_index--; 607696843ccSMike Baucom 608696843ccSMike Baucom /* Update the chain list of resource*/ 609696843ccSMike Baucom ULP_FLOW_DB_RES_NXT_SET(resource->nxt_resource_idx, 610696843ccSMike Baucom fid_resource->nxt_resource_idx); 611696843ccSMike Baucom /* update the contents */ 612696843ccSMike Baucom ulp_flow_db_res_params_to_info(resource, params); 613696843ccSMike Baucom ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx); 614696843ccSMike Baucom ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx, 615696843ccSMike Baucom idx); 616696843ccSMike Baucom } else { 617696843ccSMike Baucom /* critical resource. Just update the fid resource */ 618696843ccSMike Baucom ulp_flow_db_res_params_to_info(fid_resource, params); 619f6e12015SKishore Padmanabha fid_resource->fdb_flags |= ULP_FDB_FLAG_CRITICAL_RES; 620696843ccSMike Baucom } 621696843ccSMike Baucom 6223fe124d2SKishore Padmanabha ulp_fc_info = bnxt_ulp_cntxt_ptr2_fc_info_get(ulp_ctxt); 6239cf9c838SSomnath Kotur if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 && 6249cf9c838SSomnath Kotur params->resource_sub_type == 6253fe124d2SKishore Padmanabha BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT && 6261993b267SShahaji Bhosle ulp_fc_info && ulp_fc_info->num_counters) { 6279cf9c838SSomnath Kotur /* Store the first HW counter ID for this table */ 6289cf9c838SSomnath Kotur if (!ulp_fc_mgr_start_idx_isset(ulp_ctxt, params->direction)) 6299cf9c838SSomnath Kotur ulp_fc_mgr_start_idx_set(ulp_ctxt, params->direction, 6309cf9c838SSomnath Kotur params->resource_hndl); 6319cf9c838SSomnath Kotur 6329cf9c838SSomnath Kotur ulp_fc_mgr_cntr_set(ulp_ctxt, params->direction, 633d9e70b1dSRandy Schacher params->resource_hndl, 634d9e70b1dSRandy Schacher ulp_flow_db_shared_session_get(params)); 6359cf9c838SSomnath Kotur 6369cf9c838SSomnath Kotur if (!ulp_fc_mgr_thread_isstarted(ulp_ctxt)) 6379cf9c838SSomnath Kotur ulp_fc_mgr_thread_start(ulp_ctxt); 6380513f0afSPeter Spreadborough 6390513f0afSPeter Spreadborough if (!ulp_sc_mgr_thread_isstarted(ulp_ctxt)) 6400513f0afSPeter Spreadborough ulp_sc_mgr_thread_start(ulp_ctxt); 6419cf9c838SSomnath Kotur } 6429cf9c838SSomnath Kotur 643696843ccSMike Baucom /* all good, return success */ 644696843ccSMike Baucom return 0; 645696843ccSMike Baucom } 64605a11d7dSMike Baucom 64705a11d7dSMike Baucom /* 64805a11d7dSMike Baucom * Free the flow database entry. 64905a11d7dSMike Baucom * The params->critical_resource has to be set to 1 to free the first resource. 65005a11d7dSMike Baucom * 65105a11d7dSMike Baucom * ulp_ctxt [in] Ptr to ulp_context 65230683082SKishore Padmanabha * flow_type [in] Specify it is regular or default flow 65305a11d7dSMike Baucom * fid [in] The index to the flow entry 65405a11d7dSMike Baucom * params [in/out] The contents to be copied into params. 65505a11d7dSMike Baucom * Only the critical_resource needs to be set by the caller. 65605a11d7dSMike Baucom * 65705a11d7dSMike Baucom * Returns 0 on success and negative on failure. 65805a11d7dSMike Baucom */ 65930683082SKishore Padmanabha int32_t 66030683082SKishore Padmanabha ulp_flow_db_resource_del(struct bnxt_ulp_context *ulp_ctxt, 66130683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 66205a11d7dSMike Baucom uint32_t fid, 66305a11d7dSMike Baucom struct ulp_flow_db_res_params *params) 66405a11d7dSMike Baucom { 66505a11d7dSMike Baucom struct bnxt_ulp_flow_db *flow_db; 66605a11d7dSMike Baucom struct bnxt_ulp_flow_tbl *flow_tbl; 66705a11d7dSMike Baucom struct ulp_fdb_resource_info *nxt_resource, *fid_resource; 66805a11d7dSMike Baucom uint32_t nxt_idx = 0; 66905a11d7dSMike Baucom 67005a11d7dSMike Baucom flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 67105a11d7dSMike Baucom if (!flow_db) { 672dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 67305a11d7dSMike Baucom return -EINVAL; 67405a11d7dSMike Baucom } 67505a11d7dSMike Baucom 676ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 677dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 67805a11d7dSMike Baucom return -EINVAL; 67905a11d7dSMike Baucom } 68005a11d7dSMike Baucom 68130683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 68205a11d7dSMike Baucom /* check for max flows */ 68305a11d7dSMike Baucom if (fid >= flow_tbl->num_flows || !fid) { 684dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow index %x\n", fid); 68505a11d7dSMike Baucom return -EINVAL; 68605a11d7dSMike Baucom } 68705a11d7dSMike Baucom 68805a11d7dSMike Baucom /* check if the flow is active or not */ 68930683082SKishore Padmanabha if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) { 690dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "flow does not exist %x:%x\n", flow_type, 691dd0191d5SShuanglin Wang fid); 69205a11d7dSMike Baucom return -EINVAL; 69305a11d7dSMike Baucom } 69405a11d7dSMike Baucom 69505a11d7dSMike Baucom fid_resource = &flow_tbl->flow_resources[fid]; 69605a11d7dSMike Baucom if (!params->critical_resource) { 69705a11d7dSMike Baucom /* Not the critical resource so free the resource */ 69805a11d7dSMike Baucom ULP_FLOW_DB_RES_NXT_SET(nxt_idx, 69905a11d7dSMike Baucom fid_resource->nxt_resource_idx); 70005a11d7dSMike Baucom if (!nxt_idx) { 70105a11d7dSMike Baucom /* reached end of resources */ 70205a11d7dSMike Baucom return -ENOENT; 70305a11d7dSMike Baucom } 70405a11d7dSMike Baucom nxt_resource = &flow_tbl->flow_resources[nxt_idx]; 70505a11d7dSMike Baucom 70605a11d7dSMike Baucom /* connect the fid resource to the next resource */ 70705a11d7dSMike Baucom ULP_FLOW_DB_RES_NXT_RESET(fid_resource->nxt_resource_idx); 70805a11d7dSMike Baucom ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx, 70905a11d7dSMike Baucom nxt_resource->nxt_resource_idx); 71005a11d7dSMike Baucom 71105a11d7dSMike Baucom /* update the contents to be given to caller */ 71205a11d7dSMike Baucom ulp_flow_db_res_info_to_params(nxt_resource, params); 71305a11d7dSMike Baucom 71405a11d7dSMike Baucom /* Delete the nxt_resource */ 71505a11d7dSMike Baucom memset(nxt_resource, 0, sizeof(struct ulp_fdb_resource_info)); 71605a11d7dSMike Baucom 71705a11d7dSMike Baucom /* add it to the free list */ 71805a11d7dSMike Baucom flow_tbl->tail_index++; 71905a11d7dSMike Baucom if (flow_tbl->tail_index >= flow_tbl->num_resources) { 720dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "FlowDB:Tail reached max\n"); 72105a11d7dSMike Baucom return -ENOENT; 72205a11d7dSMike Baucom } 72305a11d7dSMike Baucom flow_tbl->flow_tbl_stack[flow_tbl->tail_index] = nxt_idx; 72405a11d7dSMike Baucom 72505a11d7dSMike Baucom } else { 72605a11d7dSMike Baucom /* Critical resource. copy the contents and exit */ 72705a11d7dSMike Baucom ulp_flow_db_res_info_to_params(fid_resource, params); 72805a11d7dSMike Baucom ULP_FLOW_DB_RES_NXT_SET(nxt_idx, 72905a11d7dSMike Baucom fid_resource->nxt_resource_idx); 73005a11d7dSMike Baucom memset(fid_resource, 0, sizeof(struct ulp_fdb_resource_info)); 73105a11d7dSMike Baucom ULP_FLOW_DB_RES_NXT_SET(fid_resource->nxt_resource_idx, 73205a11d7dSMike Baucom nxt_idx); 73305a11d7dSMike Baucom } 73405a11d7dSMike Baucom 7359cf9c838SSomnath Kotur /* Now that the HW Flow counter resource is deleted, reset it's 7369cf9c838SSomnath Kotur * corresponding slot in the SW accumulation table in the Flow Counter 7379cf9c838SSomnath Kotur * manager 7389cf9c838SSomnath Kotur */ 7399cf9c838SSomnath Kotur if (params->resource_type == TF_TBL_TYPE_ACT_STATS_64 && 7409cf9c838SSomnath Kotur params->resource_sub_type == 7419cbfa4cfSKishore Padmanabha BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT) { 7429cf9c838SSomnath Kotur ulp_fc_mgr_cntr_reset(ulp_ctxt, params->direction, 7439cf9c838SSomnath Kotur params->resource_hndl); 7449cf9c838SSomnath Kotur } 7459cf9c838SSomnath Kotur 74605a11d7dSMike Baucom /* all good, return success */ 74705a11d7dSMike Baucom return 0; 74805a11d7dSMike Baucom } 74905a11d7dSMike Baucom 75005a11d7dSMike Baucom /* 75105a11d7dSMike Baucom * Free the flow database entry 75205a11d7dSMike Baucom * 75305a11d7dSMike Baucom * ulp_ctxt [in] Ptr to ulp_context 75430683082SKishore Padmanabha * flow_type [in] - specify default or regular 75505a11d7dSMike Baucom * fid [in] The index to the flow entry 75605a11d7dSMike Baucom * 75705a11d7dSMike Baucom * returns 0 on success and negative on failure. 75805a11d7dSMike Baucom */ 75930683082SKishore Padmanabha int32_t 76030683082SKishore Padmanabha ulp_flow_db_fid_free(struct bnxt_ulp_context *ulp_ctxt, 76130683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 76205a11d7dSMike Baucom uint32_t fid) 76305a11d7dSMike Baucom { 764a2417601SKishore Padmanabha struct bnxt_ulp_flow_tbl *flow_tbl; 765ddaf0afaSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 76605a11d7dSMike Baucom 76705a11d7dSMike Baucom flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 76805a11d7dSMike Baucom if (!flow_db) { 769dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 77005a11d7dSMike Baucom return -EINVAL; 77105a11d7dSMike Baucom } 77205a11d7dSMike Baucom 773ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 774dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 77505a11d7dSMike Baucom return -EINVAL; 77605a11d7dSMike Baucom } 77705a11d7dSMike Baucom 77830683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 77905a11d7dSMike Baucom 78005a11d7dSMike Baucom /* check for limits of fid */ 78105a11d7dSMike Baucom if (fid >= flow_tbl->num_flows || !fid) { 782dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow index\n"); 78305a11d7dSMike Baucom return -EINVAL; 78405a11d7dSMike Baucom } 78505a11d7dSMike Baucom 78605a11d7dSMike Baucom /* check if the flow is active or not */ 78730683082SKishore Padmanabha if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) { 788dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "flow does not exist %x:%x\n", flow_type, 789dd0191d5SShuanglin Wang fid); 79005a11d7dSMike Baucom return -EINVAL; 79105a11d7dSMike Baucom } 79205a11d7dSMike Baucom flow_tbl->head_index--; 79305a11d7dSMike Baucom if (!flow_tbl->head_index) { 794dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "FlowDB: Head Ptr is zero\n"); 79505a11d7dSMike Baucom return -ENOENT; 79605a11d7dSMike Baucom } 797ddaf0afaSKishore Padmanabha 79805a11d7dSMike Baucom flow_tbl->flow_tbl_stack[flow_tbl->head_index] = fid; 79930683082SKishore Padmanabha 80030683082SKishore Padmanabha /* Clear the flows bitmap */ 80130683082SKishore Padmanabha ulp_flow_db_active_flows_bit_set(flow_db, flow_type, fid, 0); 80230683082SKishore Padmanabha 80330683082SKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR) 80474bcfc06SKishore Padmanabha ulp_flow_db_func_id_set(flow_db, fid, 0); 80505a11d7dSMike Baucom 806dd0191d5SShuanglin Wang #ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG 807dd0191d5SShuanglin Wang BNXT_DRV_DBG(DEBUG, "flow_id = %u:%u freed\n", flow_type, fid); 808dd0191d5SShuanglin Wang #endif 80905a11d7dSMike Baucom /* all good, return success */ 81005a11d7dSMike Baucom return 0; 81105a11d7dSMike Baucom } 812edc6ca0cSKishore Padmanabha 813cd7c298aSKishore Padmanabha /* 814cd7c298aSKishore Padmanabha *Get the flow database entry details 815cd7c298aSKishore Padmanabha * 816cd7c298aSKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 81730683082SKishore Padmanabha * flow_type [in] - specify default or regular 818cd7c298aSKishore Padmanabha * fid [in] The index to the flow entry 819cd7c298aSKishore Padmanabha * nxt_idx [in/out] the index to the next entry 820cd7c298aSKishore Padmanabha * params [out] The contents to be copied into params. 821cd7c298aSKishore Padmanabha * 822cd7c298aSKishore Padmanabha * returns 0 on success and negative on failure. 823cd7c298aSKishore Padmanabha */ 82430683082SKishore Padmanabha int32_t 82530683082SKishore Padmanabha ulp_flow_db_resource_get(struct bnxt_ulp_context *ulp_ctxt, 82630683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 827cd7c298aSKishore Padmanabha uint32_t fid, 828cd7c298aSKishore Padmanabha uint32_t *nxt_idx, 829cd7c298aSKishore Padmanabha struct ulp_flow_db_res_params *params) 830cd7c298aSKishore Padmanabha { 831cd7c298aSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 832cd7c298aSKishore Padmanabha struct bnxt_ulp_flow_tbl *flow_tbl; 833cd7c298aSKishore Padmanabha struct ulp_fdb_resource_info *nxt_resource, *fid_resource; 834cd7c298aSKishore Padmanabha 835cd7c298aSKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 836cd7c298aSKishore Padmanabha if (!flow_db) { 837dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 838cd7c298aSKishore Padmanabha return -EINVAL; 839cd7c298aSKishore Padmanabha } 840cd7c298aSKishore Padmanabha 841ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 842dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 843cd7c298aSKishore Padmanabha return -EINVAL; 844cd7c298aSKishore Padmanabha } 845cd7c298aSKishore Padmanabha 84630683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 847cd7c298aSKishore Padmanabha 848cd7c298aSKishore Padmanabha /* check for limits of fid */ 849cd7c298aSKishore Padmanabha if (fid >= flow_tbl->num_flows || !fid) { 850dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow index\n"); 851cd7c298aSKishore Padmanabha return -EINVAL; 852cd7c298aSKishore Padmanabha } 853cd7c298aSKishore Padmanabha 854cd7c298aSKishore Padmanabha /* check if the flow is active or not */ 85530683082SKishore Padmanabha if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) { 856dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "flow does not exist\n"); 857cd7c298aSKishore Padmanabha return -EINVAL; 858cd7c298aSKishore Padmanabha } 859cd7c298aSKishore Padmanabha 860cd7c298aSKishore Padmanabha if (!*nxt_idx) { 861cd7c298aSKishore Padmanabha fid_resource = &flow_tbl->flow_resources[fid]; 862cd7c298aSKishore Padmanabha ulp_flow_db_res_info_to_params(fid_resource, params); 863cd7c298aSKishore Padmanabha ULP_FLOW_DB_RES_NXT_SET(*nxt_idx, 864cd7c298aSKishore Padmanabha fid_resource->nxt_resource_idx); 865cd7c298aSKishore Padmanabha } else { 866cd7c298aSKishore Padmanabha nxt_resource = &flow_tbl->flow_resources[*nxt_idx]; 867cd7c298aSKishore Padmanabha ulp_flow_db_res_info_to_params(nxt_resource, params); 868cd7c298aSKishore Padmanabha *nxt_idx = 0; 869cd7c298aSKishore Padmanabha ULP_FLOW_DB_RES_NXT_SET(*nxt_idx, 870cd7c298aSKishore Padmanabha nxt_resource->nxt_resource_idx); 871cd7c298aSKishore Padmanabha } 872cd7c298aSKishore Padmanabha 873cd7c298aSKishore Padmanabha /* all good, return success */ 874cd7c298aSKishore Padmanabha return 0; 875cd7c298aSKishore Padmanabha } 876cd7c298aSKishore Padmanabha 877cd7c298aSKishore Padmanabha /* 878cd7c298aSKishore Padmanabha * Get the flow database entry iteratively 879edc6ca0cSKishore Padmanabha * 880edc6ca0cSKishore Padmanabha * flow_tbl [in] Ptr to flow table 88130683082SKishore Padmanabha * flow_type [in] - specify default or regular 882edc6ca0cSKishore Padmanabha * fid [in/out] The index to the flow entry 883edc6ca0cSKishore Padmanabha * 884edc6ca0cSKishore Padmanabha * returns 0 on success and negative on failure. 885edc6ca0cSKishore Padmanabha */ 886edc6ca0cSKishore Padmanabha static int32_t 88730683082SKishore Padmanabha ulp_flow_db_next_entry_get(struct bnxt_ulp_flow_db *flow_db, 88830683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 889edc6ca0cSKishore Padmanabha uint32_t *fid) 890edc6ca0cSKishore Padmanabha { 891edc6ca0cSKishore Padmanabha uint32_t lfid = *fid; 89274bcfc06SKishore Padmanabha uint32_t idx, s_idx, mod_fid; 893edc6ca0cSKishore Padmanabha uint64_t bs; 89430683082SKishore Padmanabha uint64_t *active_flows; 89530683082SKishore Padmanabha struct bnxt_ulp_flow_tbl *flowtbl = &flow_db->flow_tbl; 89630683082SKishore Padmanabha 897ddaf0afaSKishore Padmanabha if (flow_type == BNXT_ULP_FDB_TYPE_REGULAR) { 89830683082SKishore Padmanabha active_flows = flowtbl->active_reg_flows; 899ddaf0afaSKishore Padmanabha } else if (flow_type == BNXT_ULP_FDB_TYPE_DEFAULT) { 90030683082SKishore Padmanabha active_flows = flowtbl->active_dflt_flows; 901ddaf0afaSKishore Padmanabha } else { 902dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type %x\n", flow_type); 903ddaf0afaSKishore Padmanabha return -EINVAL; 904ddaf0afaSKishore Padmanabha } 905edc6ca0cSKishore Padmanabha 906edc6ca0cSKishore Padmanabha do { 90774bcfc06SKishore Padmanabha /* increment the flow id to find the next valid flow id */ 908edc6ca0cSKishore Padmanabha lfid++; 909edc6ca0cSKishore Padmanabha if (lfid >= flowtbl->num_flows) 910edc6ca0cSKishore Padmanabha return -ENOENT; 911edc6ca0cSKishore Padmanabha idx = lfid / ULP_INDEX_BITMAP_SIZE; 91274bcfc06SKishore Padmanabha mod_fid = lfid % ULP_INDEX_BITMAP_SIZE; 91374bcfc06SKishore Padmanabha s_idx = idx; 91430683082SKishore Padmanabha while (!(bs = active_flows[idx])) { 915edc6ca0cSKishore Padmanabha idx++; 916edc6ca0cSKishore Padmanabha if ((idx * ULP_INDEX_BITMAP_SIZE) >= flowtbl->num_flows) 917edc6ca0cSKishore Padmanabha return -ENOENT; 918edc6ca0cSKishore Padmanabha } 91974bcfc06SKishore Padmanabha /* 92074bcfc06SKishore Padmanabha * remove the previous bits in the bitset bs to find the 92174bcfc06SKishore Padmanabha * next non zero bit in the bitset. This needs to be done 92274bcfc06SKishore Padmanabha * only if the idx is same as he one you started. 92374bcfc06SKishore Padmanabha */ 92474bcfc06SKishore Padmanabha if (s_idx == idx) 92574bcfc06SKishore Padmanabha bs &= (-1UL >> mod_fid); 926191128d7SDavid Marchand lfid = (idx * ULP_INDEX_BITMAP_SIZE) + rte_clz64(bs); 927edc6ca0cSKishore Padmanabha if (*fid >= lfid) { 928dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow Database is corrupt\n"); 929edc6ca0cSKishore Padmanabha return -ENOENT; 930edc6ca0cSKishore Padmanabha } 93130683082SKishore Padmanabha } while (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, 93230683082SKishore Padmanabha lfid)); 933edc6ca0cSKishore Padmanabha 934edc6ca0cSKishore Padmanabha /* all good, return success */ 935edc6ca0cSKishore Padmanabha *fid = lfid; 936edc6ca0cSKishore Padmanabha return 0; 937edc6ca0cSKishore Padmanabha } 938edc6ca0cSKishore Padmanabha 939edc6ca0cSKishore Padmanabha /* 940edc6ca0cSKishore Padmanabha * Flush all flows in the flow database. 941edc6ca0cSKishore Padmanabha * 942edc6ca0cSKishore Padmanabha * ulp_ctxt [in] Ptr to ulp context 94330683082SKishore Padmanabha * flow_type [in] - specify default or regular 944edc6ca0cSKishore Padmanabha * 945edc6ca0cSKishore Padmanabha * returns 0 on success or negative number on failure 946edc6ca0cSKishore Padmanabha */ 94730683082SKishore Padmanabha int32_t 94830683082SKishore Padmanabha ulp_flow_db_flush_flows(struct bnxt_ulp_context *ulp_ctx, 94930683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type) 950edc6ca0cSKishore Padmanabha { 951edc6ca0cSKishore Padmanabha uint32_t fid = 0; 952edc6ca0cSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 953edc6ca0cSKishore Padmanabha 954edc6ca0cSKishore Padmanabha if (!ulp_ctx) { 955dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Argument\n"); 956edc6ca0cSKishore Padmanabha return -EINVAL; 957edc6ca0cSKishore Padmanabha } 958edc6ca0cSKishore Padmanabha 959edc6ca0cSKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); 960edc6ca0cSKishore Padmanabha if (!flow_db) { 961dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow database not found\n"); 962edc6ca0cSKishore Padmanabha return -EINVAL; 963edc6ca0cSKishore Padmanabha } 9646c7cbc80SKishore Padmanabha if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) { 965dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 9666c7cbc80SKishore Padmanabha return -EINVAL; 9676c7cbc80SKishore Padmanabha } 9686c7cbc80SKishore Padmanabha 969288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 970288becfbSShuanglin Wang tf_resc_pause_usage_update(); 971288becfbSShuanglin Wang #endif 972ffbc3529SShuanglin Wang 97330683082SKishore Padmanabha while (!ulp_flow_db_next_entry_get(flow_db, flow_type, &fid)) 974dd0191d5SShuanglin Wang ulp_mapper_resources_free(ulp_ctx, flow_type, fid, NULL); 975ffbc3529SShuanglin Wang 976288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 977ffbc3529SShuanglin Wang ulp_resc_usage_sync(ulp_ctx); 978288becfbSShuanglin Wang #endif 979edc6ca0cSKishore Padmanabha 9806c7cbc80SKishore Padmanabha bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 9816c7cbc80SKishore Padmanabha 982edc6ca0cSKishore Padmanabha return 0; 983edc6ca0cSKishore Padmanabha } 98474bcfc06SKishore Padmanabha 98574bcfc06SKishore Padmanabha /* 98674bcfc06SKishore Padmanabha * Flush all flows in the flow database that belong to a device function. 98774bcfc06SKishore Padmanabha * 98874bcfc06SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp context 98930683082SKishore Padmanabha * func_id [in] - The port function id 99074bcfc06SKishore Padmanabha * 99174bcfc06SKishore Padmanabha * returns 0 on success or negative number on failure 99274bcfc06SKishore Padmanabha */ 99374bcfc06SKishore Padmanabha int32_t 99474bcfc06SKishore Padmanabha ulp_flow_db_function_flow_flush(struct bnxt_ulp_context *ulp_ctx, 99574bcfc06SKishore Padmanabha uint16_t func_id) 99674bcfc06SKishore Padmanabha { 99774bcfc06SKishore Padmanabha uint32_t flow_id = 0; 99874bcfc06SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 99974bcfc06SKishore Padmanabha 100074bcfc06SKishore Padmanabha if (!ulp_ctx || !func_id) { 1001dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Argument\n"); 100274bcfc06SKishore Padmanabha return -EINVAL; 100374bcfc06SKishore Padmanabha } 100474bcfc06SKishore Padmanabha 100574bcfc06SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); 100674bcfc06SKishore Padmanabha if (!flow_db) { 1007dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow database not found\n"); 100874bcfc06SKishore Padmanabha return -EINVAL; 100974bcfc06SKishore Padmanabha } 10106c7cbc80SKishore Padmanabha if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) { 1011dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow db lock acquire failed\n"); 10126c7cbc80SKishore Padmanabha return -EINVAL; 10136c7cbc80SKishore Padmanabha } 101430683082SKishore Padmanabha 1015288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 1016288becfbSShuanglin Wang tf_resc_pause_usage_update(); 1017288becfbSShuanglin Wang #endif 101830683082SKishore Padmanabha while (!ulp_flow_db_next_entry_get(flow_db, BNXT_ULP_FDB_TYPE_REGULAR, 101930683082SKishore Padmanabha &flow_id)) { 102074bcfc06SKishore Padmanabha if (flow_db->func_id_tbl[flow_id] == func_id) 102130683082SKishore Padmanabha ulp_mapper_resources_free(ulp_ctx, 102230683082SKishore Padmanabha BNXT_ULP_FDB_TYPE_REGULAR, 1023dd0191d5SShuanglin Wang flow_id, 1024dd0191d5SShuanglin Wang NULL); 102574bcfc06SKishore Padmanabha } 1026288becfbSShuanglin Wang #ifdef TF_FLOW_SCALE_QUERY 1027ffbc3529SShuanglin Wang ulp_resc_usage_sync(ulp_ctx); 1028288becfbSShuanglin Wang #endif 10296c7cbc80SKishore Padmanabha bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx); 103074bcfc06SKishore Padmanabha return 0; 103174bcfc06SKishore Padmanabha } 103274bcfc06SKishore Padmanabha 103374bcfc06SKishore Padmanabha /* 103474bcfc06SKishore Padmanabha * Flush all flows in the flow database that are associated with the session. 103574bcfc06SKishore Padmanabha * 103674bcfc06SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp context 103774bcfc06SKishore Padmanabha * 103874bcfc06SKishore Padmanabha * returns 0 on success or negative number on failure 103974bcfc06SKishore Padmanabha */ 104074bcfc06SKishore Padmanabha int32_t 104174bcfc06SKishore Padmanabha ulp_flow_db_session_flow_flush(struct bnxt_ulp_context *ulp_ctx) 104274bcfc06SKishore Padmanabha { 104374bcfc06SKishore Padmanabha /* 104474bcfc06SKishore Padmanabha * TBD: Tf core implementation of FW session flush shall change this 104574bcfc06SKishore Padmanabha * implementation. 104674bcfc06SKishore Padmanabha */ 104730683082SKishore Padmanabha return ulp_flow_db_flush_flows(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR); 104874bcfc06SKishore Padmanabha } 104974bcfc06SKishore Padmanabha 105074bcfc06SKishore Padmanabha /* 105174bcfc06SKishore Padmanabha * Check that flow id matches the function id or not 105274bcfc06SKishore Padmanabha * 105374bcfc06SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp context 105474bcfc06SKishore Padmanabha * flow_db [in] Ptr to flow table 105574bcfc06SKishore Padmanabha * func_id [in] The func_id to be set, for reset pass zero. 105674bcfc06SKishore Padmanabha * 105774bcfc06SKishore Padmanabha * returns true on success or false on failure 105874bcfc06SKishore Padmanabha */ 105974bcfc06SKishore Padmanabha bool 106074bcfc06SKishore Padmanabha ulp_flow_db_validate_flow_func(struct bnxt_ulp_context *ulp_ctx, 106174bcfc06SKishore Padmanabha uint32_t flow_id, 106274bcfc06SKishore Padmanabha uint32_t func_id) 106374bcfc06SKishore Padmanabha { 106474bcfc06SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 106574bcfc06SKishore Padmanabha 106674bcfc06SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); 106774bcfc06SKishore Padmanabha if (!flow_db) { 1068dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow database not found\n"); 106974bcfc06SKishore Padmanabha return false; 107074bcfc06SKishore Padmanabha } 107174bcfc06SKishore Padmanabha 107274bcfc06SKishore Padmanabha /* set the function id in the function table */ 107374bcfc06SKishore Padmanabha if (flow_id < flow_db->func_id_tbl_size && func_id && 107474bcfc06SKishore Padmanabha flow_db->func_id_tbl[flow_id] == func_id) 107574bcfc06SKishore Padmanabha return true; 107674bcfc06SKishore Padmanabha 107774bcfc06SKishore Padmanabha return false; 107874bcfc06SKishore Padmanabha } 1079d310d59cSKishore Padmanabha 1080d310d59cSKishore Padmanabha /* 1081d310d59cSKishore Padmanabha * Internal api to traverse the resource list within a flow 1082d310d59cSKishore Padmanabha * and match a resource based on resource func and resource 1083d310d59cSKishore Padmanabha * sub type. This api should be used only for resources that 1084d310d59cSKishore Padmanabha * are unique and do not have multiple instances of resource 1085d310d59cSKishore Padmanabha * func and sub type combination since it will return only 1086d310d59cSKishore Padmanabha * the first match. 1087d310d59cSKishore Padmanabha */ 1088d310d59cSKishore Padmanabha static int32_t 1089640bfd23SKishore Padmanabha ulp_flow_db_resource_params_get(struct bnxt_ulp_context *ulp_ctx, 109030683082SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 1091d310d59cSKishore Padmanabha uint32_t flow_id, 1092d310d59cSKishore Padmanabha uint32_t resource_func, 1093d310d59cSKishore Padmanabha uint32_t res_subtype, 1094640bfd23SKishore Padmanabha struct ulp_flow_db_res_params *params) 1095d310d59cSKishore Padmanabha { 1096d310d59cSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1097d310d59cSKishore Padmanabha struct bnxt_ulp_flow_tbl *flow_tbl; 1098d310d59cSKishore Padmanabha struct ulp_fdb_resource_info *fid_res; 1099d310d59cSKishore Padmanabha uint32_t res_id; 1100d310d59cSKishore Padmanabha 1101d310d59cSKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx); 1102d310d59cSKishore Padmanabha if (!flow_db) { 1103dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Flow database not found\n"); 1104d310d59cSKishore Padmanabha return -EINVAL; 1105d310d59cSKishore Padmanabha } 1106d310d59cSKishore Padmanabha 1107640bfd23SKishore Padmanabha if (!params) { 1108dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "invalid argument\n"); 1109640bfd23SKishore Padmanabha return -EINVAL; 1110640bfd23SKishore Padmanabha } 1111640bfd23SKishore Padmanabha 1112ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 1113dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 111430683082SKishore Padmanabha return -EINVAL; 111530683082SKishore Padmanabha } 111630683082SKishore Padmanabha 111730683082SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 1118d310d59cSKishore Padmanabha 1119d310d59cSKishore Padmanabha /* check for limits of fid */ 1120d310d59cSKishore Padmanabha if (flow_id >= flow_tbl->num_flows || !flow_id) { 1121dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow index\n"); 1122d310d59cSKishore Padmanabha return -EINVAL; 1123d310d59cSKishore Padmanabha } 1124d310d59cSKishore Padmanabha 1125d310d59cSKishore Padmanabha /* check if the flow is active or not */ 112630683082SKishore Padmanabha if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, flow_id)) { 1127dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "flow does not exist\n"); 1128d310d59cSKishore Padmanabha return -EINVAL; 1129d310d59cSKishore Padmanabha } 1130d310d59cSKishore Padmanabha /* Iterate the resource to get the resource handle */ 1131d310d59cSKishore Padmanabha res_id = flow_id; 1132640bfd23SKishore Padmanabha memset(params, 0, sizeof(struct ulp_flow_db_res_params)); 1133d310d59cSKishore Padmanabha while (res_id) { 1134d310d59cSKishore Padmanabha fid_res = &flow_tbl->flow_resources[res_id]; 1135f6e12015SKishore Padmanabha if (ulp_flow_db_resource_func_get(fid_res) == resource_func && 1136f6e12015SKishore Padmanabha fid_res->resource_sub_type == res_subtype) { 1137f6e12015SKishore Padmanabha ulp_flow_db_res_info_to_params(fid_res, params); 1138d310d59cSKishore Padmanabha return 0; 1139d310d59cSKishore Padmanabha } 1140d310d59cSKishore Padmanabha res_id = 0; 1141d310d59cSKishore Padmanabha ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx); 1142d310d59cSKishore Padmanabha } 1143d310d59cSKishore Padmanabha return -ENOENT; 1144d310d59cSKishore Padmanabha } 1145d310d59cSKishore Padmanabha 1146d310d59cSKishore Padmanabha /* 1147d310d59cSKishore Padmanabha * Api to get the cfa action pointer from a flow. 1148d310d59cSKishore Padmanabha * 1149d310d59cSKishore Padmanabha * ulp_ctxt [in] Ptr to ulp context 1150d310d59cSKishore Padmanabha * flow_id [in] flow id 1151d310d59cSKishore Padmanabha * cfa_action [out] The resource handle stored in the flow database 1152d310d59cSKishore Padmanabha * 1153d310d59cSKishore Padmanabha * returns 0 on success 1154d310d59cSKishore Padmanabha */ 1155d310d59cSKishore Padmanabha int32_t 1156d310d59cSKishore Padmanabha ulp_default_flow_db_cfa_action_get(struct bnxt_ulp_context *ulp_ctx, 1157d310d59cSKishore Padmanabha uint32_t flow_id, 1158dd0191d5SShuanglin Wang uint32_t *cfa_action) 1159d310d59cSKishore Padmanabha { 11609cbfa4cfSKishore Padmanabha uint8_t sub_typ = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_VFR_CFA_ACTION; 1161640bfd23SKishore Padmanabha struct ulp_flow_db_res_params params; 1162d310d59cSKishore Padmanabha int32_t rc; 1163d310d59cSKishore Padmanabha 1164640bfd23SKishore Padmanabha rc = ulp_flow_db_resource_params_get(ulp_ctx, 116530683082SKishore Padmanabha BNXT_ULP_FDB_TYPE_DEFAULT, 1166d310d59cSKishore Padmanabha flow_id, 1167d310d59cSKishore Padmanabha BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE, 11689cbfa4cfSKishore Padmanabha sub_typ, ¶ms); 1169d310d59cSKishore Padmanabha if (rc) { 117061a7ca1fSKishore Padmanabha BNXT_DRV_DBG(DEBUG, "CFA Action ptr not found for flow id %u\n", 1171d310d59cSKishore Padmanabha flow_id); 1172d310d59cSKishore Padmanabha return -ENOENT; 1173d310d59cSKishore Padmanabha } 1174640bfd23SKishore Padmanabha *cfa_action = params.resource_hndl; 1175d310d59cSKishore Padmanabha return 0; 1176d310d59cSKishore Padmanabha } 1177f4a4421cSKishore Padmanabha 1178bdf4a3c6SKishore Padmanabha /* internal validation function for parent flow tbl */ 1179*a089734aSShuanglin Wang struct ulp_fdb_parent_info * 1180bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_entry_get(struct bnxt_ulp_context *ulp_ctxt, 1181bdf4a3c6SKishore Padmanabha uint32_t pc_idx) 1182bdf4a3c6SKishore Padmanabha { 1183bdf4a3c6SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1184bdf4a3c6SKishore Padmanabha 1185bdf4a3c6SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1186bdf4a3c6SKishore Padmanabha if (!flow_db) { 1187dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 1188bdf4a3c6SKishore Padmanabha return NULL; 1189bdf4a3c6SKishore Padmanabha } 1190bdf4a3c6SKishore Padmanabha 1191bdf4a3c6SKishore Padmanabha /* check for max flows */ 1192bdf4a3c6SKishore Padmanabha if (pc_idx >= BNXT_ULP_MAX_TUN_CACHE_ENTRIES) { 1193dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid tunnel index\n"); 1194bdf4a3c6SKishore Padmanabha return NULL; 1195bdf4a3c6SKishore Padmanabha } 1196bdf4a3c6SKishore Padmanabha 1197bdf4a3c6SKishore Padmanabha /* No support for parent child db then just exit */ 1198bdf4a3c6SKishore Padmanabha if (!flow_db->parent_child_db.entries_count) { 1199dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db not supported\n"); 1200bdf4a3c6SKishore Padmanabha return NULL; 1201bdf4a3c6SKishore Padmanabha } 1202bdf4a3c6SKishore Padmanabha if (!flow_db->parent_child_db.parent_flow_tbl[pc_idx].valid) { 1203dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Not a valid tunnel index\n"); 1204bdf4a3c6SKishore Padmanabha return NULL; 1205bdf4a3c6SKishore Padmanabha } 1206bdf4a3c6SKishore Padmanabha 1207bdf4a3c6SKishore Padmanabha return &flow_db->parent_child_db.parent_flow_tbl[pc_idx]; 1208bdf4a3c6SKishore Padmanabha } 1209bdf4a3c6SKishore Padmanabha 1210bdf4a3c6SKishore Padmanabha /* internal validation function for parent flow tbl */ 1211bdf4a3c6SKishore Padmanabha static struct bnxt_ulp_flow_db * 1212bdf4a3c6SKishore Padmanabha ulp_flow_db_parent_arg_validation(struct bnxt_ulp_context *ulp_ctxt, 1213bdf4a3c6SKishore Padmanabha uint32_t tun_idx) 1214bdf4a3c6SKishore Padmanabha { 1215bdf4a3c6SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1216bdf4a3c6SKishore Padmanabha 1217bdf4a3c6SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1218bdf4a3c6SKishore Padmanabha if (!flow_db) { 1219dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 1220bdf4a3c6SKishore Padmanabha return NULL; 1221bdf4a3c6SKishore Padmanabha } 1222bdf4a3c6SKishore Padmanabha 1223bdf4a3c6SKishore Padmanabha /* check for max flows */ 1224bdf4a3c6SKishore Padmanabha if (tun_idx >= BNXT_ULP_MAX_TUN_CACHE_ENTRIES) { 1225dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid tunnel index\n"); 1226bdf4a3c6SKishore Padmanabha return NULL; 1227bdf4a3c6SKishore Padmanabha } 1228bdf4a3c6SKishore Padmanabha 1229bdf4a3c6SKishore Padmanabha /* No support for parent child db then just exit */ 1230bdf4a3c6SKishore Padmanabha if (!flow_db->parent_child_db.entries_count) { 1231dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db not supported\n"); 1232bdf4a3c6SKishore Padmanabha return NULL; 1233bdf4a3c6SKishore Padmanabha } 1234bdf4a3c6SKishore Padmanabha 1235bdf4a3c6SKishore Padmanabha return flow_db; 1236bdf4a3c6SKishore Padmanabha } 1237bdf4a3c6SKishore Padmanabha 1238f4a4421cSKishore Padmanabha /* 1239f4a4421cSKishore Padmanabha * Allocate the entry in the parent-child database 1240f4a4421cSKishore Padmanabha * 1241f4a4421cSKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1242bdf4a3c6SKishore Padmanabha * tun_idx [in] The tunnel index of the flow entry 1243f4a4421cSKishore Padmanabha * 1244f4a4421cSKishore Padmanabha * returns index on success and negative on failure. 1245f4a4421cSKishore Padmanabha */ 1246bdf4a3c6SKishore Padmanabha static int32_t 1247bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_idx_alloc(struct bnxt_ulp_context *ulp_ctxt, 1248bdf4a3c6SKishore Padmanabha uint32_t tun_idx) 1249f4a4421cSKishore Padmanabha { 1250f4a4421cSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1251f4a4421cSKishore Padmanabha struct ulp_fdb_parent_child_db *p_pdb; 1252f4a4421cSKishore Padmanabha uint32_t idx, free_idx = 0; 1253f4a4421cSKishore Padmanabha 1254640bfd23SKishore Padmanabha /* validate the arguments */ 1255bdf4a3c6SKishore Padmanabha flow_db = ulp_flow_db_parent_arg_validation(ulp_ctxt, tun_idx); 1256f4a4421cSKishore Padmanabha if (!flow_db) { 1257dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db validation failed\n"); 1258be8acb27SKishore Padmanabha return -EINVAL; 1259be8acb27SKishore Padmanabha } 1260be8acb27SKishore Padmanabha 1261f4a4421cSKishore Padmanabha p_pdb = &flow_db->parent_child_db; 1262640bfd23SKishore Padmanabha for (idx = 0; idx < p_pdb->entries_count; idx++) { 1263bdf4a3c6SKishore Padmanabha if (p_pdb->parent_flow_tbl[idx].valid && 1264bdf4a3c6SKishore Padmanabha p_pdb->parent_flow_tbl[idx].tun_idx == tun_idx) { 1265bdf4a3c6SKishore Padmanabha return idx; 1266f4a4421cSKishore Padmanabha } 1267bdf4a3c6SKishore Padmanabha if (!p_pdb->parent_flow_tbl[idx].valid && !free_idx) 1268f4a4421cSKishore Padmanabha free_idx = idx + 1; 1269f4a4421cSKishore Padmanabha } 1270f4a4421cSKishore Padmanabha /* no free slots */ 1271f4a4421cSKishore Padmanabha if (!free_idx) { 1272dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db is full\n"); 1273f4a4421cSKishore Padmanabha return -ENOMEM; 1274f4a4421cSKishore Padmanabha } 1275f4a4421cSKishore Padmanabha 1276f4a4421cSKishore Padmanabha free_idx -= 1; 1277f4a4421cSKishore Padmanabha /* set the Fid in the parent child */ 1278bdf4a3c6SKishore Padmanabha p_pdb->parent_flow_tbl[free_idx].tun_idx = tun_idx; 1279bdf4a3c6SKishore Padmanabha p_pdb->parent_flow_tbl[free_idx].valid = 1; 1280f4a4421cSKishore Padmanabha return free_idx; 1281f4a4421cSKishore Padmanabha } 1282f4a4421cSKishore Padmanabha 1283f4a4421cSKishore Padmanabha /* 1284f4a4421cSKishore Padmanabha * Free the entry in the parent-child database 1285f4a4421cSKishore Padmanabha * 1286bdf4a3c6SKishore Padmanabha * pc_entry [in] Ptr to parent child db entry 1287f4a4421cSKishore Padmanabha * 1288bdf4a3c6SKishore Padmanabha * returns none. 1289bdf4a3c6SKishore Padmanabha */ 1290bdf4a3c6SKishore Padmanabha static void 1291bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_entry_free(struct bnxt_ulp_context *ulp_ctxt, 1292bdf4a3c6SKishore Padmanabha struct ulp_fdb_parent_info *pc_entry) 1293bdf4a3c6SKishore Padmanabha { 1294bdf4a3c6SKishore Padmanabha struct bnxt_tun_cache_entry *tun_tbl; 1295bdf4a3c6SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1296bdf4a3c6SKishore Padmanabha uint64_t *tmp_bitset; 1297bdf4a3c6SKishore Padmanabha 1298bdf4a3c6SKishore Padmanabha /* free the tunnel entry */ 1299bdf4a3c6SKishore Padmanabha tun_tbl = bnxt_ulp_cntxt_ptr2_tun_tbl_get(ulp_ctxt); 1300bdf4a3c6SKishore Padmanabha if (tun_tbl) 1301bdf4a3c6SKishore Padmanabha ulp_tunnel_offload_entry_clear(tun_tbl, pc_entry->tun_idx); 1302bdf4a3c6SKishore Padmanabha 1303bdf4a3c6SKishore Padmanabha /* free the child bitset*/ 1304bdf4a3c6SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1305bdf4a3c6SKishore Padmanabha if (flow_db) 1306bdf4a3c6SKishore Padmanabha memset(pc_entry->child_fid_bitset, 0, 1307bdf4a3c6SKishore Padmanabha flow_db->parent_child_db.child_bitset_size); 1308bdf4a3c6SKishore Padmanabha 1309bdf4a3c6SKishore Padmanabha /* free the contents */ 1310bdf4a3c6SKishore Padmanabha tmp_bitset = pc_entry->child_fid_bitset; 1311bdf4a3c6SKishore Padmanabha memset(pc_entry, 0, sizeof(struct ulp_fdb_parent_info)); 1312bdf4a3c6SKishore Padmanabha pc_entry->child_fid_bitset = tmp_bitset; 1313bdf4a3c6SKishore Padmanabha } 1314bdf4a3c6SKishore Padmanabha 1315bdf4a3c6SKishore Padmanabha /* 1316bdf4a3c6SKishore Padmanabha * Set or reset the parent flow in the parent-child database 1317bdf4a3c6SKishore Padmanabha * 1318bdf4a3c6SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1319bdf4a3c6SKishore Padmanabha * pc_idx [in] The index to parent child db 1320bdf4a3c6SKishore Padmanabha * parent_fid [in] The flow id of the parent flow entry 1321bdf4a3c6SKishore Padmanabha * set_flag [in] Use 1 for setting child, 0 to reset 1322bdf4a3c6SKishore Padmanabha * 1323bdf4a3c6SKishore Padmanabha * returns zero on success and negative on failure. 1324f4a4421cSKishore Padmanabha */ 1325f4a4421cSKishore Padmanabha int32_t 1326bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_parent_flow_set(struct bnxt_ulp_context *ulp_ctxt, 1327bdf4a3c6SKishore Padmanabha uint32_t pc_idx, 1328bdf4a3c6SKishore Padmanabha uint32_t parent_fid, 1329bdf4a3c6SKishore Padmanabha uint32_t set_flag) 1330f4a4421cSKishore Padmanabha { 1331bdf4a3c6SKishore Padmanabha struct ulp_fdb_parent_info *pc_entry; 1332f4a4421cSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1333f4a4421cSKishore Padmanabha 1334bdf4a3c6SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1335f4a4421cSKishore Padmanabha if (!flow_db) { 1336dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db validation failed\n"); 1337be8acb27SKishore Padmanabha return -EINVAL; 1338be8acb27SKishore Padmanabha } 1339be8acb27SKishore Padmanabha 1340bdf4a3c6SKishore Padmanabha /* check for fid validity */ 1341bdf4a3c6SKishore Padmanabha if (parent_fid >= flow_db->flow_tbl.num_flows || !parent_fid) { 1342dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid parent flow index %x\n", parent_fid); 1343f4a4421cSKishore Padmanabha return -EINVAL; 1344f4a4421cSKishore Padmanabha } 1345f4a4421cSKishore Padmanabha 1346bdf4a3c6SKishore Padmanabha /* validate the arguments and parent child entry */ 1347bdf4a3c6SKishore Padmanabha pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx); 1348bdf4a3c6SKishore Padmanabha if (!pc_entry) { 1349dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the parent child entry\n"); 1350bdf4a3c6SKishore Padmanabha return -EINVAL; 1351bdf4a3c6SKishore Padmanabha } 1352bdf4a3c6SKishore Padmanabha 1353bdf4a3c6SKishore Padmanabha if (set_flag) { 1354bdf4a3c6SKishore Padmanabha pc_entry->parent_fid = parent_fid; 13558782e4deSKishore Padmanabha pc_entry->parent_ref_cnt++; 1356bdf4a3c6SKishore Padmanabha } else { 13578782e4deSKishore Padmanabha if (pc_entry->parent_ref_cnt > 0) 13588782e4deSKishore Padmanabha pc_entry->parent_ref_cnt--; 1359bdf4a3c6SKishore Padmanabha /* Free the parent child db entry if no user present */ 13608782e4deSKishore Padmanabha if (!pc_entry->parent_ref_cnt && !pc_entry->f2_cnt) 1361bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_entry_free(ulp_ctxt, pc_entry); 1362bdf4a3c6SKishore Padmanabha } 1363bdf4a3c6SKishore Padmanabha return 0; 1364bdf4a3c6SKishore Padmanabha } 1365bdf4a3c6SKishore Padmanabha 1366f4a4421cSKishore Padmanabha /* 1367f4a4421cSKishore Padmanabha * Set or reset the child flow in the parent-child database 1368f4a4421cSKishore Padmanabha * 1369f4a4421cSKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1370bdf4a3c6SKishore Padmanabha * pc_idx [in] The index to parent child db 1371f4a4421cSKishore Padmanabha * child_fid [in] The flow id of the child flow entry 1372f4a4421cSKishore Padmanabha * set_flag [in] Use 1 for setting child, 0 to reset 1373f4a4421cSKishore Padmanabha * 1374f4a4421cSKishore Padmanabha * returns zero on success and negative on failure. 1375f4a4421cSKishore Padmanabha */ 1376f4a4421cSKishore Padmanabha int32_t 1377bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_child_flow_set(struct bnxt_ulp_context *ulp_ctxt, 1378bdf4a3c6SKishore Padmanabha uint32_t pc_idx, 1379f4a4421cSKishore Padmanabha uint32_t child_fid, 1380f4a4421cSKishore Padmanabha uint32_t set_flag) 1381f4a4421cSKishore Padmanabha { 1382bdf4a3c6SKishore Padmanabha struct ulp_fdb_parent_info *pc_entry; 1383f4a4421cSKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1384bdf4a3c6SKishore Padmanabha uint32_t a_idx; 1385f4a4421cSKishore Padmanabha uint64_t *t; 1386f4a4421cSKishore Padmanabha 1387bdf4a3c6SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1388f4a4421cSKishore Padmanabha if (!flow_db) { 1389dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db validation failed\n"); 1390f4a4421cSKishore Padmanabha return -EINVAL; 1391f4a4421cSKishore Padmanabha } 1392f4a4421cSKishore Padmanabha 1393f4a4421cSKishore Padmanabha /* check for fid validity */ 1394f4a4421cSKishore Padmanabha if (child_fid >= flow_db->flow_tbl.num_flows || !child_fid) { 1395dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid child flow index %x\n", child_fid); 1396f4a4421cSKishore Padmanabha return -EINVAL; 1397f4a4421cSKishore Padmanabha } 1398f4a4421cSKishore Padmanabha 1399bdf4a3c6SKishore Padmanabha /* validate the arguments and parent child entry */ 1400bdf4a3c6SKishore Padmanabha pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx); 1401bdf4a3c6SKishore Padmanabha if (!pc_entry) { 1402dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the parent child entry\n"); 1403be8acb27SKishore Padmanabha return -EINVAL; 1404be8acb27SKishore Padmanabha } 1405be8acb27SKishore Padmanabha 1406bdf4a3c6SKishore Padmanabha a_idx = child_fid / ULP_INDEX_BITMAP_SIZE; 1407bdf4a3c6SKishore Padmanabha t = pc_entry->child_fid_bitset; 1408bdf4a3c6SKishore Padmanabha if (set_flag) { 1409bdf4a3c6SKishore Padmanabha ULP_INDEX_BITMAP_SET(t[a_idx], child_fid); 1410bdf4a3c6SKishore Padmanabha pc_entry->f2_cnt++; 1411bdf4a3c6SKishore Padmanabha } else { 1412bdf4a3c6SKishore Padmanabha ULP_INDEX_BITMAP_RESET(t[a_idx], child_fid); 1413bdf4a3c6SKishore Padmanabha if (pc_entry->f2_cnt) 1414bdf4a3c6SKishore Padmanabha pc_entry->f2_cnt--; 14158782e4deSKishore Padmanabha if (!pc_entry->f2_cnt && !pc_entry->parent_ref_cnt) 1416bdf4a3c6SKishore Padmanabha ulp_flow_db_pc_db_entry_free(ulp_ctxt, pc_entry); 1417bdf4a3c6SKishore Padmanabha } 1418f4a4421cSKishore Padmanabha return 0; 1419f4a4421cSKishore Padmanabha } 1420f4a4421cSKishore Padmanabha 1421f4a4421cSKishore Padmanabha /* 1422f4a4421cSKishore Padmanabha * Get the next child flow in the parent-child database 1423f4a4421cSKishore Padmanabha * 1424f4a4421cSKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1425f4a4421cSKishore Padmanabha * parent_fid [in] The flow id of the parent flow entry 1426f4a4421cSKishore Padmanabha * child_fid [in/out] The flow id of the child flow entry 1427f4a4421cSKishore Padmanabha * 1428f4a4421cSKishore Padmanabha * returns zero on success and negative on failure. 1429f4a4421cSKishore Padmanabha * Pass child_fid as zero for first entry. 1430f4a4421cSKishore Padmanabha */ 1431f4a4421cSKishore Padmanabha int32_t 1432f4a4421cSKishore Padmanabha ulp_flow_db_parent_child_flow_next_entry_get(struct bnxt_ulp_flow_db *flow_db, 1433f4a4421cSKishore Padmanabha uint32_t parent_idx, 1434f4a4421cSKishore Padmanabha uint32_t *child_fid) 1435f4a4421cSKishore Padmanabha { 1436f4a4421cSKishore Padmanabha struct ulp_fdb_parent_child_db *p_pdb; 1437f4a4421cSKishore Padmanabha uint32_t idx, s_idx, mod_fid; 1438f4a4421cSKishore Padmanabha uint32_t next_fid = *child_fid; 1439f4a4421cSKishore Padmanabha uint64_t *child_bitset; 1440f4a4421cSKishore Padmanabha uint64_t bs; 1441f4a4421cSKishore Padmanabha 1442f4a4421cSKishore Padmanabha /* check for fid validity */ 1443f4a4421cSKishore Padmanabha p_pdb = &flow_db->parent_child_db; 1444f4a4421cSKishore Padmanabha if (parent_idx >= p_pdb->entries_count || 1445f4a4421cSKishore Padmanabha !p_pdb->parent_flow_tbl[parent_idx].parent_fid) { 1446dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid parent flow index %x\n", parent_idx); 1447f4a4421cSKishore Padmanabha return -EINVAL; 1448f4a4421cSKishore Padmanabha } 1449f4a4421cSKishore Padmanabha 1450f4a4421cSKishore Padmanabha child_bitset = p_pdb->parent_flow_tbl[parent_idx].child_fid_bitset; 1451f4a4421cSKishore Padmanabha do { 1452f4a4421cSKishore Padmanabha /* increment the flow id to find the next valid flow id */ 1453f4a4421cSKishore Padmanabha next_fid++; 1454f4a4421cSKishore Padmanabha if (next_fid >= flow_db->flow_tbl.num_flows) 1455f4a4421cSKishore Padmanabha return -ENOENT; 1456f4a4421cSKishore Padmanabha idx = next_fid / ULP_INDEX_BITMAP_SIZE; 1457f4a4421cSKishore Padmanabha mod_fid = next_fid % ULP_INDEX_BITMAP_SIZE; 1458f4a4421cSKishore Padmanabha s_idx = idx; 1459f4a4421cSKishore Padmanabha while (!(bs = child_bitset[idx])) { 1460f4a4421cSKishore Padmanabha idx++; 1461f4a4421cSKishore Padmanabha if ((idx * ULP_INDEX_BITMAP_SIZE) >= 1462f4a4421cSKishore Padmanabha flow_db->flow_tbl.num_flows) 1463f4a4421cSKishore Padmanabha return -ENOENT; 1464f4a4421cSKishore Padmanabha } 1465f4a4421cSKishore Padmanabha /* 1466f4a4421cSKishore Padmanabha * remove the previous bits in the bitset bs to find the 1467f4a4421cSKishore Padmanabha * next non zero bit in the bitset. This needs to be done 1468f4a4421cSKishore Padmanabha * only if the idx is same as he one you started. 1469f4a4421cSKishore Padmanabha */ 1470f4a4421cSKishore Padmanabha if (s_idx == idx) 1471f4a4421cSKishore Padmanabha bs &= (-1UL >> mod_fid); 1472191128d7SDavid Marchand next_fid = (idx * ULP_INDEX_BITMAP_SIZE) + rte_clz64(bs); 1473f4a4421cSKishore Padmanabha if (*child_fid >= next_fid) { 1474dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Parent Child Database is corrupt\n"); 1475f4a4421cSKishore Padmanabha return -ENOENT; 1476f4a4421cSKishore Padmanabha } 1477f4a4421cSKishore Padmanabha idx = next_fid / ULP_INDEX_BITMAP_SIZE; 1478f4a4421cSKishore Padmanabha } while (!ULP_INDEX_BITMAP_GET(child_bitset[idx], next_fid)); 1479f4a4421cSKishore Padmanabha *child_fid = next_fid; 1480f4a4421cSKishore Padmanabha return 0; 1481f4a4421cSKishore Padmanabha } 1482be8acb27SKishore Padmanabha 1483be8acb27SKishore Padmanabha /* 1484640bfd23SKishore Padmanabha * Set the counter accumulation in the parent flow 1485640bfd23SKishore Padmanabha * 1486640bfd23SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1487bdf4a3c6SKishore Padmanabha * pc_idx [in] The parent child index of the parent flow entry 1488640bfd23SKishore Padmanabha * 1489640bfd23SKishore Padmanabha * returns index on success and negative on failure. 1490640bfd23SKishore Padmanabha */ 1491640bfd23SKishore Padmanabha static int32_t 1492640bfd23SKishore Padmanabha ulp_flow_db_parent_flow_count_accum_set(struct bnxt_ulp_context *ulp_ctxt, 1493bdf4a3c6SKishore Padmanabha uint32_t pc_idx) 1494640bfd23SKishore Padmanabha { 1495640bfd23SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1496640bfd23SKishore Padmanabha struct ulp_fdb_parent_child_db *p_pdb; 1497640bfd23SKishore Padmanabha 1498640bfd23SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1499640bfd23SKishore Padmanabha if (!flow_db) { 1500dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 1501640bfd23SKishore Padmanabha return -EINVAL; 1502640bfd23SKishore Padmanabha } 1503640bfd23SKishore Padmanabha 1504640bfd23SKishore Padmanabha /* check for parent idx validity */ 1505640bfd23SKishore Padmanabha p_pdb = &flow_db->parent_child_db; 1506bdf4a3c6SKishore Padmanabha if (pc_idx >= p_pdb->entries_count || 15078782e4deSKishore Padmanabha !p_pdb->parent_flow_tbl[pc_idx].parent_ref_cnt) { 1508dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid parent child index %x\n", pc_idx); 1509640bfd23SKishore Padmanabha return -EINVAL; 1510640bfd23SKishore Padmanabha } 1511640bfd23SKishore Padmanabha 1512bdf4a3c6SKishore Padmanabha p_pdb->parent_flow_tbl[pc_idx].counter_acc = 1; 1513640bfd23SKishore Padmanabha return 0; 1514640bfd23SKishore Padmanabha } 1515640bfd23SKishore Padmanabha 1516640bfd23SKishore Padmanabha /* 1517be8acb27SKishore Padmanabha * Orphan the child flow entry 1518be8acb27SKishore Padmanabha * This is called only for child flows that have 1519be8acb27SKishore Padmanabha * BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW resource 1520be8acb27SKishore Padmanabha * 1521be8acb27SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1522be8acb27SKishore Padmanabha * flow_type [in] Specify it is regular or default flow 1523be8acb27SKishore Padmanabha * fid [in] The index to the flow entry 1524be8acb27SKishore Padmanabha * 1525be8acb27SKishore Padmanabha * Returns 0 on success and negative on failure. 1526be8acb27SKishore Padmanabha */ 1527be8acb27SKishore Padmanabha int32_t 1528be8acb27SKishore Padmanabha ulp_flow_db_child_flow_reset(struct bnxt_ulp_context *ulp_ctxt, 1529be8acb27SKishore Padmanabha enum bnxt_ulp_fdb_type flow_type, 1530be8acb27SKishore Padmanabha uint32_t fid) 1531be8acb27SKishore Padmanabha { 1532be8acb27SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1533be8acb27SKishore Padmanabha struct bnxt_ulp_flow_tbl *flow_tbl; 1534be8acb27SKishore Padmanabha struct ulp_fdb_resource_info *fid_res; 1535be8acb27SKishore Padmanabha uint32_t res_id = 0; 1536be8acb27SKishore Padmanabha 1537be8acb27SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1538be8acb27SKishore Padmanabha if (!flow_db) { 1539dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid Arguments\n"); 1540be8acb27SKishore Padmanabha return -EINVAL; 1541be8acb27SKishore Padmanabha } 1542be8acb27SKishore Padmanabha 1543ddaf0afaSKishore Padmanabha if (flow_type >= BNXT_ULP_FDB_TYPE_LAST) { 1544dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow type\n"); 1545be8acb27SKishore Padmanabha return -EINVAL; 1546be8acb27SKishore Padmanabha } 1547be8acb27SKishore Padmanabha 1548be8acb27SKishore Padmanabha flow_tbl = &flow_db->flow_tbl; 1549be8acb27SKishore Padmanabha /* check for max flows */ 1550be8acb27SKishore Padmanabha if (fid >= flow_tbl->num_flows || !fid) { 1551dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Invalid flow index %x\n", fid); 1552be8acb27SKishore Padmanabha return -EINVAL; 1553be8acb27SKishore Padmanabha } 1554be8acb27SKishore Padmanabha 1555be8acb27SKishore Padmanabha /* check if the flow is active or not */ 1556be8acb27SKishore Padmanabha if (!ulp_flow_db_active_flows_bit_is_set(flow_db, flow_type, fid)) { 1557dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "flow does not exist\n"); 1558be8acb27SKishore Padmanabha return -EINVAL; 1559be8acb27SKishore Padmanabha } 1560be8acb27SKishore Padmanabha 1561be8acb27SKishore Padmanabha /* Iterate the resource to get the resource handle */ 1562be8acb27SKishore Padmanabha res_id = fid; 1563be8acb27SKishore Padmanabha while (res_id) { 1564be8acb27SKishore Padmanabha fid_res = &flow_tbl->flow_resources[res_id]; 1565be8acb27SKishore Padmanabha if (ulp_flow_db_resource_func_get(fid_res) == 1566be8acb27SKishore Padmanabha BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW) { 1567be8acb27SKishore Padmanabha /* invalidate the resource details */ 1568be8acb27SKishore Padmanabha fid_res->resource_hndl = 0; 1569be8acb27SKishore Padmanabha return 0; 1570be8acb27SKishore Padmanabha } 1571be8acb27SKishore Padmanabha res_id = 0; 1572be8acb27SKishore Padmanabha ULP_FLOW_DB_RES_NXT_SET(res_id, fid_res->nxt_resource_idx); 1573be8acb27SKishore Padmanabha } 1574be8acb27SKishore Padmanabha /* failed */ 1575be8acb27SKishore Padmanabha return -1; 1576be8acb27SKishore Padmanabha } 1577be8acb27SKishore Padmanabha 1578be8acb27SKishore Padmanabha /* 1579be8acb27SKishore Padmanabha * Create parent flow in the parent flow tbl 1580be8acb27SKishore Padmanabha * 1581be8acb27SKishore Padmanabha * parms [in] Ptr to mapper params 1582be8acb27SKishore Padmanabha * 1583be8acb27SKishore Padmanabha * Returns 0 on success and negative on failure. 1584be8acb27SKishore Padmanabha */ 1585be8acb27SKishore Padmanabha int32_t 1586be8acb27SKishore Padmanabha ulp_flow_db_parent_flow_create(struct bnxt_ulp_mapper_parms *parms) 1587be8acb27SKishore Padmanabha { 1588be8acb27SKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 1589bdf4a3c6SKishore Padmanabha uint32_t sub_typ = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT; 1590640bfd23SKishore Padmanabha struct ulp_flow_db_res_params res_params; 1591bdf4a3c6SKishore Padmanabha int32_t pc_idx; 1592be8acb27SKishore Padmanabha 1593bdf4a3c6SKishore Padmanabha /* create or get the parent child database */ 1594bdf4a3c6SKishore Padmanabha pc_idx = ulp_flow_db_pc_db_idx_alloc(parms->ulp_ctx, parms->tun_idx); 1595bdf4a3c6SKishore Padmanabha if (pc_idx < 0) { 1596dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in getting parent child db %x\n", 1597bdf4a3c6SKishore Padmanabha parms->tun_idx); 1598bdf4a3c6SKishore Padmanabha return -EINVAL; 1599bdf4a3c6SKishore Padmanabha } 1600bdf4a3c6SKishore Padmanabha 1601bdf4a3c6SKishore Padmanabha /* Update the parent fid */ 1602bdf4a3c6SKishore Padmanabha if (ulp_flow_db_pc_db_parent_flow_set(parms->ulp_ctx, pc_idx, 1603dd0191d5SShuanglin Wang parms->flow_id, 1)) { 1604dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in setting parent fid %x\n", 1605bdf4a3c6SKishore Padmanabha parms->tun_idx); 1606bdf4a3c6SKishore Padmanabha return -EINVAL; 1607be8acb27SKishore Padmanabha } 1608be8acb27SKishore Padmanabha 1609be8acb27SKishore Padmanabha /* Add the parent details in the resource list of the flow */ 1610be8acb27SKishore Padmanabha memset(&fid_parms, 0, sizeof(fid_parms)); 1611be8acb27SKishore Padmanabha fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_PARENT_FLOW; 1612bdf4a3c6SKishore Padmanabha fid_parms.resource_hndl = pc_idx; 1613be8acb27SKishore Padmanabha fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO; 1614be8acb27SKishore Padmanabha if (ulp_flow_db_resource_add(parms->ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR, 1615dd0191d5SShuanglin Wang parms->flow_id, &fid_parms)) { 1616dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in adding flow res for flow id %x\n", 1617dd0191d5SShuanglin Wang parms->flow_id); 1618be8acb27SKishore Padmanabha return -1; 1619be8acb27SKishore Padmanabha } 1620640bfd23SKishore Padmanabha 1621640bfd23SKishore Padmanabha /* check of the flow has internal counter accumulation enabled */ 1622640bfd23SKishore Padmanabha if (!ulp_flow_db_resource_params_get(parms->ulp_ctx, 1623640bfd23SKishore Padmanabha BNXT_ULP_FDB_TYPE_REGULAR, 1624dd0191d5SShuanglin Wang parms->flow_id, 1625640bfd23SKishore Padmanabha BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE, 16269cbfa4cfSKishore Padmanabha sub_typ, 1627640bfd23SKishore Padmanabha &res_params)) { 1628640bfd23SKishore Padmanabha /* Enable the counter accumulation in parent entry */ 1629640bfd23SKishore Padmanabha if (ulp_flow_db_parent_flow_count_accum_set(parms->ulp_ctx, 1630bdf4a3c6SKishore Padmanabha pc_idx)) { 1631dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in setting counter acc %x\n", 1632dd0191d5SShuanglin Wang parms->flow_id); 1633640bfd23SKishore Padmanabha return -1; 1634640bfd23SKishore Padmanabha } 1635640bfd23SKishore Padmanabha } 1636675e31d8SVenkat Duvvuru 1637*a089734aSShuanglin Wang /* Set parent flow entry idx in stats cache entry */ 1638*a089734aSShuanglin Wang ulp_sc_mgr_set_pc_idx(parms->ulp_ctx, parms->flow_id, pc_idx); 1639be8acb27SKishore Padmanabha return 0; 1640be8acb27SKishore Padmanabha } 1641be8acb27SKishore Padmanabha 1642be8acb27SKishore Padmanabha /* 1643be8acb27SKishore Padmanabha * Create child flow in the parent flow tbl 1644be8acb27SKishore Padmanabha * 1645be8acb27SKishore Padmanabha * parms [in] Ptr to mapper params 1646be8acb27SKishore Padmanabha * 1647be8acb27SKishore Padmanabha * Returns 0 on success and negative on failure. 1648be8acb27SKishore Padmanabha */ 1649be8acb27SKishore Padmanabha int32_t 1650be8acb27SKishore Padmanabha ulp_flow_db_child_flow_create(struct bnxt_ulp_mapper_parms *parms) 1651be8acb27SKishore Padmanabha { 1652be8acb27SKishore Padmanabha struct ulp_flow_db_res_params fid_parms; 16539cbfa4cfSKishore Padmanabha uint32_t sub_type = BNXT_ULP_RESOURCE_SUB_TYPE_INDEX_TABLE_INT_COUNT; 1654640bfd23SKishore Padmanabha enum bnxt_ulp_resource_func res_fun; 1655640bfd23SKishore Padmanabha struct ulp_flow_db_res_params res_p; 1656bdf4a3c6SKishore Padmanabha int32_t rc, pc_idx; 1657bdf4a3c6SKishore Padmanabha 1658bdf4a3c6SKishore Padmanabha /* create or get the parent child database */ 1659bdf4a3c6SKishore Padmanabha pc_idx = ulp_flow_db_pc_db_idx_alloc(parms->ulp_ctx, parms->tun_idx); 1660bdf4a3c6SKishore Padmanabha if (pc_idx < 0) { 1661dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in getting parent child db %x\n", 1662bdf4a3c6SKishore Padmanabha parms->tun_idx); 1663bdf4a3c6SKishore Padmanabha return -1; 1664bdf4a3c6SKishore Padmanabha } 1665be8acb27SKishore Padmanabha 1666be8acb27SKishore Padmanabha /* create the parent flow entry in parent flow table */ 1667bdf4a3c6SKishore Padmanabha rc = ulp_flow_db_pc_db_child_flow_set(parms->ulp_ctx, pc_idx, 1668dd0191d5SShuanglin Wang parms->flow_id, 1); 1669be8acb27SKishore Padmanabha if (rc) { 1670dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in setting child fid %x\n", 1671dd0191d5SShuanglin Wang parms->flow_id); 1672640bfd23SKishore Padmanabha return rc; 1673be8acb27SKishore Padmanabha } 1674be8acb27SKishore Padmanabha 1675be8acb27SKishore Padmanabha /* Add the parent details in the resource list of the flow */ 1676be8acb27SKishore Padmanabha memset(&fid_parms, 0, sizeof(fid_parms)); 1677be8acb27SKishore Padmanabha fid_parms.resource_func = BNXT_ULP_RESOURCE_FUNC_CHILD_FLOW; 1678bdf4a3c6SKishore Padmanabha fid_parms.resource_hndl = pc_idx; 1679be8acb27SKishore Padmanabha fid_parms.critical_resource = BNXT_ULP_CRITICAL_RESOURCE_NO; 1680640bfd23SKishore Padmanabha rc = ulp_flow_db_resource_add(parms->ulp_ctx, 1681640bfd23SKishore Padmanabha BNXT_ULP_FDB_TYPE_REGULAR, 1682dd0191d5SShuanglin Wang parms->flow_id, &fid_parms); 1683640bfd23SKishore Padmanabha if (rc) { 1684dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in adding flow res for flow id %x\n", 1685dd0191d5SShuanglin Wang parms->flow_id); 1686640bfd23SKishore Padmanabha return rc; 1687640bfd23SKishore Padmanabha } 1688640bfd23SKishore Padmanabha 1689640bfd23SKishore Padmanabha /* check if internal count action included for this flow.*/ 1690640bfd23SKishore Padmanabha res_fun = BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE; 1691640bfd23SKishore Padmanabha rc = ulp_flow_db_resource_params_get(parms->ulp_ctx, 1692640bfd23SKishore Padmanabha BNXT_ULP_FDB_TYPE_REGULAR, 1693dd0191d5SShuanglin Wang parms->flow_id, 1694640bfd23SKishore Padmanabha res_fun, 1695640bfd23SKishore Padmanabha sub_type, 1696640bfd23SKishore Padmanabha &res_p); 1697640bfd23SKishore Padmanabha if (!rc) { 1698640bfd23SKishore Padmanabha /* update the counter manager to include parent fid */ 1699640bfd23SKishore Padmanabha if (ulp_fc_mgr_cntr_parent_flow_set(parms->ulp_ctx, 1700640bfd23SKishore Padmanabha res_p.direction, 1701640bfd23SKishore Padmanabha res_p.resource_hndl, 1702bdf4a3c6SKishore Padmanabha pc_idx)) { 1703dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "Error in setting child %x\n", 1704dd0191d5SShuanglin Wang parms->flow_id); 1705be8acb27SKishore Padmanabha return -1; 1706be8acb27SKishore Padmanabha } 1707640bfd23SKishore Padmanabha } 1708bdf4a3c6SKishore Padmanabha 1709640bfd23SKishore Padmanabha /* return success */ 1710be8acb27SKishore Padmanabha return 0; 1711be8acb27SKishore Padmanabha } 1712640bfd23SKishore Padmanabha 1713640bfd23SKishore Padmanabha /* 1714640bfd23SKishore Padmanabha * Update the parent counters 1715640bfd23SKishore Padmanabha * 1716640bfd23SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1717bdf4a3c6SKishore Padmanabha * pc_idx [in] The parent flow entry idx 1718640bfd23SKishore Padmanabha * packet_count [in] - packet count 1719640bfd23SKishore Padmanabha * byte_count [in] - byte count 1720640bfd23SKishore Padmanabha * 1721640bfd23SKishore Padmanabha * returns 0 on success 1722640bfd23SKishore Padmanabha */ 1723640bfd23SKishore Padmanabha int32_t 1724640bfd23SKishore Padmanabha ulp_flow_db_parent_flow_count_update(struct bnxt_ulp_context *ulp_ctxt, 1725bdf4a3c6SKishore Padmanabha uint32_t pc_idx, 1726640bfd23SKishore Padmanabha uint64_t packet_count, 1727640bfd23SKishore Padmanabha uint64_t byte_count) 1728640bfd23SKishore Padmanabha { 1729bdf4a3c6SKishore Padmanabha struct ulp_fdb_parent_info *pc_entry; 1730640bfd23SKishore Padmanabha 1731bdf4a3c6SKishore Padmanabha /* validate the arguments and get parent child entry */ 1732bdf4a3c6SKishore Padmanabha pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx); 1733bdf4a3c6SKishore Padmanabha if (!pc_entry) { 1734dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the parent child entry\n"); 1735640bfd23SKishore Padmanabha return -EINVAL; 1736640bfd23SKishore Padmanabha } 1737640bfd23SKishore Padmanabha 1738bdf4a3c6SKishore Padmanabha if (pc_entry->counter_acc) { 1739bdf4a3c6SKishore Padmanabha pc_entry->pkt_count += packet_count; 1740bdf4a3c6SKishore Padmanabha pc_entry->byte_count += byte_count; 1741640bfd23SKishore Padmanabha } 1742640bfd23SKishore Padmanabha return 0; 1743640bfd23SKishore Padmanabha } 1744640bfd23SKishore Padmanabha 1745640bfd23SKishore Padmanabha /* 1746640bfd23SKishore Padmanabha * Get the parent accumulation counters 1747640bfd23SKishore Padmanabha * 1748640bfd23SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1749bdf4a3c6SKishore Padmanabha * pc_idx [in] The parent flow entry idx 1750640bfd23SKishore Padmanabha * packet_count [out] - packet count 1751640bfd23SKishore Padmanabha * byte_count [out] - byte count 1752640bfd23SKishore Padmanabha * 1753640bfd23SKishore Padmanabha * returns 0 on success 1754640bfd23SKishore Padmanabha */ 1755640bfd23SKishore Padmanabha int32_t 1756640bfd23SKishore Padmanabha ulp_flow_db_parent_flow_count_get(struct bnxt_ulp_context *ulp_ctxt, 17578782e4deSKishore Padmanabha uint32_t flow_id, 1758bdf4a3c6SKishore Padmanabha uint32_t pc_idx, uint64_t *packet_count, 1759ddaf0afaSKishore Padmanabha uint64_t *byte_count, uint8_t count_reset) 1760640bfd23SKishore Padmanabha { 1761bdf4a3c6SKishore Padmanabha struct ulp_fdb_parent_info *pc_entry; 1762640bfd23SKishore Padmanabha 1763bdf4a3c6SKishore Padmanabha /* validate the arguments and get parent child entry */ 1764bdf4a3c6SKishore Padmanabha pc_entry = ulp_flow_db_pc_db_entry_get(ulp_ctxt, pc_idx); 1765bdf4a3c6SKishore Padmanabha if (!pc_entry) { 1766dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "failed to get the parent child entry\n"); 1767640bfd23SKishore Padmanabha return -EINVAL; 1768640bfd23SKishore Padmanabha } 1769640bfd23SKishore Padmanabha 17708782e4deSKishore Padmanabha /* stale parent fid */ 17718782e4deSKishore Padmanabha if (flow_id != pc_entry->parent_fid) { 17728782e4deSKishore Padmanabha *packet_count = 0; 17738782e4deSKishore Padmanabha *byte_count = 0; 17748782e4deSKishore Padmanabha return 0; 17758782e4deSKishore Padmanabha } 17768782e4deSKishore Padmanabha 1777bdf4a3c6SKishore Padmanabha if (pc_entry->counter_acc) { 1778bdf4a3c6SKishore Padmanabha *packet_count = pc_entry->pkt_count; 1779bdf4a3c6SKishore Padmanabha *byte_count = pc_entry->byte_count; 1780ddaf0afaSKishore Padmanabha if (count_reset) { 1781bdf4a3c6SKishore Padmanabha pc_entry->pkt_count = 0; 1782bdf4a3c6SKishore Padmanabha pc_entry->byte_count = 0; 1783ddaf0afaSKishore Padmanabha } 1784640bfd23SKishore Padmanabha } 1785640bfd23SKishore Padmanabha return 0; 1786640bfd23SKishore Padmanabha } 1787640bfd23SKishore Padmanabha 1788640bfd23SKishore Padmanabha /* 1789640bfd23SKishore Padmanabha * reset the parent accumulation counters 1790640bfd23SKishore Padmanabha * 1791640bfd23SKishore Padmanabha * ulp_ctxt [in] Ptr to ulp_context 1792640bfd23SKishore Padmanabha * 1793640bfd23SKishore Padmanabha * returns none 1794640bfd23SKishore Padmanabha */ 1795640bfd23SKishore Padmanabha void 1796640bfd23SKishore Padmanabha ulp_flow_db_parent_flow_count_reset(struct bnxt_ulp_context *ulp_ctxt) 1797640bfd23SKishore Padmanabha { 1798640bfd23SKishore Padmanabha struct bnxt_ulp_flow_db *flow_db; 1799640bfd23SKishore Padmanabha struct ulp_fdb_parent_child_db *p_pdb; 1800640bfd23SKishore Padmanabha uint32_t idx; 1801640bfd23SKishore Padmanabha 1802640bfd23SKishore Padmanabha /* validate the arguments */ 1803bdf4a3c6SKishore Padmanabha flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt); 1804640bfd23SKishore Padmanabha if (!flow_db) { 1805dd0191d5SShuanglin Wang BNXT_DRV_DBG(ERR, "parent child db validation failed\n"); 1806640bfd23SKishore Padmanabha return; 1807640bfd23SKishore Padmanabha } 1808640bfd23SKishore Padmanabha 1809640bfd23SKishore Padmanabha p_pdb = &flow_db->parent_child_db; 1810640bfd23SKishore Padmanabha for (idx = 0; idx < p_pdb->entries_count; idx++) { 1811bdf4a3c6SKishore Padmanabha if (p_pdb->parent_flow_tbl[idx].valid && 1812640bfd23SKishore Padmanabha p_pdb->parent_flow_tbl[idx].counter_acc) { 1813640bfd23SKishore Padmanabha p_pdb->parent_flow_tbl[idx].pkt_count = 0; 1814640bfd23SKishore Padmanabha p_pdb->parent_flow_tbl[idx].byte_count = 0; 1815640bfd23SKishore Padmanabha } 1816640bfd23SKishore Padmanabha } 1817640bfd23SKishore Padmanabha } 181819994cc7SKishore Padmanabha 181919994cc7SKishore Padmanabha /* 182019994cc7SKishore Padmanabha * Set the shared bit for the flow db entry 182119994cc7SKishore Padmanabha * 182219994cc7SKishore Padmanabha * res [in] Ptr to fdb entry 182319994cc7SKishore Padmanabha * shared [in] shared flag 182419994cc7SKishore Padmanabha * 182519994cc7SKishore Padmanabha * returns none 182619994cc7SKishore Padmanabha */ 182719994cc7SKishore Padmanabha void ulp_flow_db_shared_session_set(struct ulp_flow_db_res_params *res, 1828d9e70b1dSRandy Schacher enum bnxt_ulp_session_type s_type) 182919994cc7SKishore Padmanabha { 1830d9e70b1dSRandy Schacher if (res && (s_type & BNXT_ULP_SESSION_TYPE_SHARED)) 183119994cc7SKishore Padmanabha res->fdb_flags |= ULP_FDB_FLAG_SHARED_SESSION; 1832d9e70b1dSRandy Schacher else if (res && (s_type & BNXT_ULP_SESSION_TYPE_SHARED_WC)) 1833d9e70b1dSRandy Schacher res->fdb_flags |= ULP_FDB_FLAG_SHARED_WC_SESSION; 1834d9e70b1dSRandy Schacher } 1835d9e70b1dSRandy Schacher 1836d9e70b1dSRandy Schacher /* 1837dd0191d5SShuanglin Wang * get the shared bit for the flow db entry 1838d9e70b1dSRandy Schacher * 1839dd0191d5SShuanglin Wang * res [in] Ptr to fdb entry 1840dd0191d5SShuanglin Wang * 1841dd0191d5SShuanglin Wang * returns session type 1842d9e70b1dSRandy Schacher */ 1843d9e70b1dSRandy Schacher enum bnxt_ulp_session_type 1844d9e70b1dSRandy Schacher ulp_flow_db_shared_session_get(struct ulp_flow_db_res_params *res) 1845d9e70b1dSRandy Schacher { 1846d9e70b1dSRandy Schacher enum bnxt_ulp_session_type stype = BNXT_ULP_SESSION_TYPE_DEFAULT; 1847d9e70b1dSRandy Schacher 1848d9e70b1dSRandy Schacher if (res && (res->fdb_flags & ULP_FDB_FLAG_SHARED_SESSION)) 1849d9e70b1dSRandy Schacher stype = BNXT_ULP_SESSION_TYPE_SHARED; 1850d9e70b1dSRandy Schacher else if (res && (res->fdb_flags & ULP_FDB_FLAG_SHARED_WC_SESSION)) 1851d9e70b1dSRandy Schacher stype = BNXT_ULP_SESSION_TYPE_SHARED_WC; 1852d9e70b1dSRandy Schacher 1853d9e70b1dSRandy Schacher return stype; 185419994cc7SKishore Padmanabha } 1855