1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2014-2021 Broadcom 3 * All rights reserved. 4 */ 5 6 #include <string.h> 7 8 #include "tfc.h" 9 #include "tfo.h" 10 #include "tfc_util.h" 11 12 const char * 13 tfc_dir_2_str(enum cfa_dir dir) 14 { 15 switch (dir) { 16 case CFA_DIR_RX: 17 return "RX"; 18 case CFA_DIR_TX: 19 return "TX"; 20 default: 21 return "Invalid direction"; 22 } 23 } 24 25 const char * 26 tfc_ident_2_str(enum cfa_resource_subtype_ident id_stype) 27 { 28 switch (id_stype) { 29 case CFA_RSUBTYPE_IDENT_L2CTX: 30 return "ident_l2_ctx"; 31 case CFA_RSUBTYPE_IDENT_PROF_FUNC: 32 return "ident_prof_func"; 33 case CFA_RSUBTYPE_IDENT_WC_PROF: 34 return "ident_wc_prof"; 35 case CFA_RSUBTYPE_IDENT_EM_PROF: 36 return "ident_em_prof"; 37 case CFA_RSUBTYPE_IDENT_L2_FUNC: 38 return "ident_l2_func"; 39 default: 40 return "Invalid identifier subtype"; 41 } 42 } 43 44 const char * 45 tfc_tcam_2_str(enum cfa_resource_subtype_tcam tcam_stype) 46 { 47 switch (tcam_stype) { 48 case CFA_RSUBTYPE_TCAM_L2CTX: 49 return "tcam_l2_ctx"; 50 case CFA_RSUBTYPE_TCAM_PROF_TCAM: 51 return "tcam_prof_tcam"; 52 case CFA_RSUBTYPE_TCAM_WC: 53 return "tcam_wc"; 54 case CFA_RSUBTYPE_TCAM_CT_RULE: 55 return "tcam_ct_rule"; 56 case CFA_RSUBTYPE_TCAM_VEB: 57 return "tcam_veb"; 58 case CFA_RSUBTYPE_TCAM_FEATURE_CHAIN: 59 return "tcam_fc"; 60 default: 61 return "Invalid tcam subtype"; 62 } 63 } 64 65 const char * 66 tfc_idx_tbl_2_str(enum cfa_resource_subtype_idx_tbl tbl_stype) 67 { 68 switch (tbl_stype) { 69 case CFA_RSUBTYPE_IDX_TBL_STAT64: 70 return "idx_tbl_64b_statistics"; 71 case CFA_RSUBTYPE_IDX_TBL_METER_PROF: 72 return "idx_tbl_meter_prof"; 73 case CFA_RSUBTYPE_IDX_TBL_METER_INST: 74 return "idx_tbl_meter_inst"; 75 case CFA_RSUBTYPE_IDX_TBL_MIRROR: 76 return "idx_tbl_mirror"; 77 case CFA_RSUBTYPE_IDX_TBL_METADATA_PROF: 78 return "idx_tbl_metadata_prof"; 79 case CFA_RSUBTYPE_IDX_TBL_METADATA_LKUP: 80 return "idx_tbl_metadata_lkup"; 81 case CFA_RSUBTYPE_IDX_TBL_METADATA_ACT: 82 return "idx_tbl_metadata_act"; 83 case CFA_RSUBTYPE_IDX_TBL_EM_FKB: 84 return "idx_tbl_em_fkb"; 85 case CFA_RSUBTYPE_IDX_TBL_WC_FKB: 86 return "idx_tbl_wc_fkb"; 87 case CFA_RSUBTYPE_IDX_TBL_EM_FKB_MASK: 88 return "idx_tbl_em_fkb_mask"; 89 case CFA_RSUBTYPE_IDX_TBL_CT_STATE: 90 return "idx_tbl_ct_state"; 91 case CFA_RSUBTYPE_IDX_TBL_RANGE_PROF: 92 return "idx_tbl_range_prof"; 93 case CFA_RSUBTYPE_IDX_TBL_RANGE_ENTRY: 94 return "idx_tbl_range_entry"; 95 default: 96 return "Invalid idx tbl subtype"; 97 } 98 } 99 100 const char * 101 tfc_if_tbl_2_str(enum cfa_resource_subtype_if_tbl tbl_stype) 102 { 103 switch (tbl_stype) { 104 case CFA_RSUBTYPE_IF_TBL_ILT: 105 return "if_tbl_ilt"; 106 case CFA_RSUBTYPE_IF_TBL_VSPT: 107 return "if_tbl_vspt"; 108 case CFA_RSUBTYPE_IF_TBL_PROF_PARIF_DFLT_ACT_PTR: 109 return "if_tbl_parif_dflt_act_ptr"; 110 case CFA_RSUBTYPE_IF_TBL_PROF_PARIF_ERR_ACT_PTR: 111 return "if_tbl_parif_err_act_ptr"; 112 case CFA_RSUBTYPE_IF_TBL_EPOCH0: 113 return "if_tbl_epoch0"; 114 case CFA_RSUBTYPE_IF_TBL_EPOCH1: 115 return "if_tbl_epoch1"; 116 case CFA_RSUBTYPE_IF_TBL_LAG: 117 return "if_tbl_lag"; 118 default: 119 return "Invalid if tbl subtype"; 120 } 121 } 122 123 const char * 124 tfc_ts_region_2_str(enum cfa_region_type region, enum cfa_dir dir) 125 { 126 switch (region) { 127 case CFA_REGION_TYPE_LKUP: 128 if (dir == CFA_DIR_RX) 129 return "ts_lookup_rx"; 130 else if (dir == CFA_DIR_TX) 131 return "lookup_tx"; 132 else 133 return "ts_lookup_invalid_dir"; 134 case CFA_REGION_TYPE_ACT: 135 if (dir == CFA_DIR_RX) 136 return "ts_action_rx"; 137 else if (dir == CFA_DIR_TX) 138 return "ts_action_tx"; 139 else 140 return "ts_action_invalid_dir"; 141 default: 142 return "Invalid ts region"; 143 } 144 } 145 146 uint32_t 147 tfc_getbits(uint32_t *data, int offset, int blen) 148 { 149 int start = offset >> 5; 150 int end = (offset + blen - 1) >> 5; 151 uint32_t val = data[start] >> (offset & 0x1f); 152 153 if (start != end) 154 val |= (data[start + 1] << (32 - (offset & 0x1f))); 155 return (blen == 32) ? val : (val & ((1 << blen) - 1)); 156 } 157 158 #define BITS_IN_VAR(x) (sizeof(x) * 8) 159 160 /* 161 * Calculate the smallest power of 2 that is >= x. The return value is the 162 * exponent of 2. 163 */ 164 uint32_t next_pow2(uint32_t x) 165 { 166 /* 167 * This algorithm calculates the nearest power of 2 greater than or 168 * equal to x: 169 * The function __builtin_clz returns the number of leading 0-bits in 170 * an unsigned int. 171 * Subtract this from the number of bits in x to get the power of 2. In 172 * the examples below, an int is assumed to have 32 bits. 173 * 174 * Example 1: 175 * x == 2 176 * __builtin_clz(1) = 31 177 * 32 - 31 = 1 178 * 2^1 = 2 179 * Example 2: 180 * x = 63 181 * __builtin_clz(62) = 26 182 * 32 - 26 = 6 183 * 2^6 = 64 184 */ 185 return x == 1 ? 1 : (BITS_IN_VAR(x) - __builtin_clz(x - 1)); 186 } 187 188 /* 189 * Calculate the largest power of 2 that is less than x. The return value is 190 * the exponent of 2. 191 */ 192 uint32_t prev_pow2(uint32_t x) 193 { 194 /* 195 * This algorithm calculates the nearest power of 2 less than x: 196 * The function __builtin_clz returns the number of leading 0-bits in 197 * an unsigned int. 198 * Subtract this from one less than the number of bits in x to get 199 * the power of 2. In the examples below, an int is assumed to have 200 * 32 bits. 201 * 202 * Example 1: 203 * x = 2 204 * __builtin_clz(1) = 31 205 * 31 - 31 = 0 206 * 2^0 = 1 207 * Example 2: 208 * x = 63 209 * __builtin_clz(62) = 26 210 * 31 - 26 = 5 211 * 2^5 = 32 212 * Example 3: 213 * x = 64 214 * __builtin_clz(63) = 26 215 * 31 - 26 = 5 216 * 2^5 = 32 217 */ 218 return x == 1 ? 0 : (BITS_IN_VAR(x) - 1 - __builtin_clz(x - 1)); 219 } 220 221 uint32_t roundup32(uint32_t x, uint32_t y) 222 { 223 return ((x + y - 1) / y) * y; 224 } 225 226 uint64_t roundup64(uint64_t x, uint64_t y) 227 { 228 return ((x + y - 1) / y) * y; 229 } 230