ft_alu_load_hw.c (124374B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: ft_group.c 8 * Purpose: The purpose of this file is to set flow tracker group methods. 9 * Requires: 10 */ 11 12 #include <bcm_int/esw/flowtracker/ft_group.h> 13 14 #ifdef BCM_FLOWTRACKER_SUPPORT 15 16 /* 17 * 1. Allocate resource for LOAD/ALU based on element. 18 * 2. Add the ALU information into the list group sw state. 19 * 3. when the entry is installed then add the entry into hw. 20 * 4. Set all the checks in hardware. 21 * 5. 22 */ 23 24 /* Group Sw state. */ 25 extern 26 bcmi_ft_group_sw_info_t **bcmi_ft_group_sw_state[BCM_MAX_NUM_UNITS]; 27 28 /* ALU/LOAD vectore. */ 29 bcmi_ft_alu_load_method_t *alu_load_methods[BCMI_FT_ALU_LOAD_MEMS]; 30 31 /* Element Informations which can take action on their own. */ 32 STATIC 33 bcmi_ft_element_alu_info_t ft_element_info[] = { 34 {bcmFlowtrackerTrackingParamTypePktCount, 35 bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionCounterIncr}, 36 {bcmFlowtrackerTrackingParamTypeByteCount, 37 bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionCounterIncrByPktBytes}, 38 {bcmFlowtrackerTrackingParamTypeVxlanNetworkId, 39 bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionUpdateValue}, 40 {bcmFlowtrackerTrackingParamTypeTunnelClass, 41 bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionUpdateValue}, 42 {bcmFlowtrackerTrackingParamTypeDosAttack, 43 bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionCounterIncr}, 44 {bcmFlowtrackerTrackingParamTypeInnerDosAttack, 45 bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionCounterIncr}, 46 {bcmFlowtrackerTrackingParamTypeCount, 0, 0} 47 }; 48 49 /*|************************************************************| 50 |******** ALU Software Install Methods. ********| 51 |************************************************************| 52 |******* Start ********| 53 |************************************************************|*/ 54 55 56 /* ALu/Load vectors. */ 57 bcmi_ft_alu_load_method_t alu32_methods[] = 58 {{bcmi_ft_alu_entry_match, 59 bcmi_ft_alu32_entry_install, 60 bcmi_ft_alu32_entry_uninstall}}; 61 62 /* ALu/Load vectors. */ 63 bcmi_ft_alu_load_method_t alu16_methods[] = 64 {{bcmi_ft_alu_entry_match, 65 bcmi_ft_alu16_entry_install, 66 bcmi_ft_alu16_entry_uninstall}}; 67 68 /* ALu/Load vectors. */ 69 bcmi_ft_alu_load_method_t load16_methods[] = 70 {{bcmi_ft_load16_entry_match, 71 bcmi_ft_load16_entry_install, 72 bcmi_ft_load16_entry_uninstall}}; 73 74 /* ALu/Load vectors. */ 75 bcmi_ft_alu_load_method_t load8_methods[] = 76 {{bcmi_ft_load8_entry_match, 77 bcmi_ft_load8_entry_install, 78 bcmi_ft_load8_entry_uninstall}}; 79 80 81 82 83 /* ALU/LOAD hw memory databases. */ 84 bcmi_ft_group_pdd_bus_info_t bcmi_load8_pdd_info[TOTAL_GROUP_LOAD8_DATA_NUM] = 85 {{BSD_FLEX_LOAD8_TRACKING_PARAM_0f, 71, 64, 1}, 86 {BSD_FLEX_LOAD8_TRACKING_PARAM_1f, 63, 56, 1}, 87 {BSD_FLEX_LOAD8_TRACKING_PARAM_2f, 55, 48, 1}, 88 {BSD_FLEX_LOAD8_TRACKING_PARAM_3f, 47, 40, 1}, 89 {BSD_FLEX_LOAD8_TRACKING_PARAM_4f, 39, 32, 1}, 90 {BSD_FLEX_LOAD8_TRACKING_PARAM_5f, 31, 24, 1}, 91 {BSD_FLEX_LOAD8_TRACKING_PARAM_6f, 23, 16, 1}, 92 {BSD_FLEX_LOAD8_TRACKING_PARAM_7f, 15, 8, 1}}; 93 94 95 96 bcmi_ft_group_pdd_bus_info_t bcmi_alu16_pdd_info[TOTAL_GROUP_ALU16_MEM] = 97 {{BSD_FLEX_ALU16_TRACKING_PARAM_0f, 215, 200, 2}, 98 {BSD_FLEX_ALU16_TRACKING_PARAM_1f, 199, 184, 2}, 99 {BSD_FLEX_ALU16_TRACKING_PARAM_2f, 183, 168, 2}, 100 {BSD_FLEX_ALU16_TRACKING_PARAM_3f, 167, 152, 2}, 101 {BSD_FLEX_ALU16_TRACKING_PARAM_4f, 151, 136, 2}, 102 {BSD_FLEX_ALU16_TRACKING_PARAM_5f, 135, 120, 2}, 103 {BSD_FLEX_ALU16_TRACKING_PARAM_6f, 119, 104, 2}, 104 {BSD_FLEX_ALU16_TRACKING_PARAM_7f, 103, 88, 2}}; 105 106 107 108 bcmi_ft_group_pdd_bus_info_t bcmi_load16_pdd_info[TOTAL_GROUP_LOAD16_DATA_NUM] = 109 {{BSD_FLEX_LOAD16_TRACKING_PARAM_0f, 471, 456, 2}, 110 {BSD_FLEX_LOAD16_TRACKING_PARAM_1f, 455, 440, 2}, 111 {BSD_FLEX_LOAD16_TRACKING_PARAM_2f, 439, 424, 2}, 112 {BSD_FLEX_LOAD16_TRACKING_PARAM_3f, 423, 408, 2}, 113 {BSD_FLEX_LOAD16_TRACKING_PARAM_4f, 407, 392, 2}, 114 {BSD_FLEX_LOAD16_TRACKING_PARAM_5f, 391, 376, 2}, 115 {BSD_FLEX_LOAD16_TRACKING_PARAM_6f, 375, 360, 2}, 116 {BSD_FLEX_LOAD16_TRACKING_PARAM_7f, 359, 344, 2}, 117 {BSD_FLEX_LOAD16_TRACKING_PARAM_8f, 343, 328, 2}, 118 {BSD_FLEX_LOAD16_TRACKING_PARAM_9f, 327, 312, 2}, 119 {BSD_FLEX_LOAD16_TRACKING_PARAM_10f, 311, 296, 2}, 120 {BSD_FLEX_LOAD16_TRACKING_PARAM_11f, 295, 280, 2}, 121 {BSD_FLEX_LOAD16_TRACKING_PARAM_12f, 279, 264, 2}, 122 {BSD_FLEX_LOAD16_TRACKING_PARAM_13f, 263, 248, 2}, 123 {BSD_FLEX_LOAD16_TRACKING_PARAM_14f, 247, 232, 2}, 124 {BSD_FLEX_LOAD16_TRACKING_PARAM_15f, 231, 216, 2}}; 125 126 bcmi_ft_group_pdd_bus_info_t bcmi_alu32_pdd_info[TOTAL_GROUP_ALU32_MEM] = 127 {{BSD_FLEX_ALU32_TRACKING_PARAM_0f, 855, 824, 4}, 128 {BSD_FLEX_ALU32_TRACKING_PARAM_1f, 823, 792, 4}, 129 {BSD_FLEX_ALU32_TRACKING_PARAM_2f, 791, 760, 4}, 130 {BSD_FLEX_ALU32_TRACKING_PARAM_3f, 759, 728, 4}, 131 {BSD_FLEX_ALU32_TRACKING_PARAM_4f, 727, 696, 4}, 132 {BSD_FLEX_ALU32_TRACKING_PARAM_5f, 695, 664, 4}, 133 {BSD_FLEX_ALU32_TRACKING_PARAM_6f, 663, 632, 4}, 134 {BSD_FLEX_ALU32_TRACKING_PARAM_7f, 631, 600, 4}, 135 {BSD_FLEX_ALU32_TRACKING_PARAM_8f, 599, 568, 4}, 136 {BSD_FLEX_ALU32_TRACKING_PARAM_9f, 567, 536, 4}, 137 {BSD_FLEX_ALU32_TRACKING_PARAM_10f, 535, 504, 4}, 138 {BSD_FLEX_ALU32_TRACKING_PARAM_11f, 503, 472, 4}}; 139 140 141 alu_load_info_t alu_32_info[TOTAL_GROUP_ALU32_MEM] = 142 {{BSC_DG_GROUP_ALU32_PROFILE_0m, -1}, 143 {BSC_DG_GROUP_ALU32_PROFILE_1m, -1}, 144 {BSC_DG_GROUP_ALU32_PROFILE_2m, -1}, 145 {BSC_DG_GROUP_ALU32_PROFILE_3m, -1}, 146 {BSC_DG_GROUP_ALU32_PROFILE_4m, -1}, 147 {BSC_DG_GROUP_ALU32_PROFILE_5m, -1}, 148 {BSC_DG_GROUP_ALU32_PROFILE_6m, -1}, 149 {BSC_DG_GROUP_ALU32_PROFILE_7m, -1}, 150 {BSC_DG_GROUP_ALU32_PROFILE_8m, -1}, 151 {BSC_DG_GROUP_ALU32_PROFILE_9m, -1}, 152 {BSC_DG_GROUP_ALU32_PROFILE_10m, -1}, 153 {BSC_DG_GROUP_ALU32_PROFILE_11m, -1}}; 154 155 156 alu_load_info_t alu_16_info[TOTAL_GROUP_ALU16_MEM] = 157 {{BSC_DG_GROUP_ALU16_PROFILE_0m, -1}, 158 {BSC_DG_GROUP_ALU16_PROFILE_1m, -1}, 159 {BSC_DG_GROUP_ALU16_PROFILE_2m, -1}, 160 {BSC_DG_GROUP_ALU16_PROFILE_3m, -1}, 161 {BSC_DG_GROUP_ALU16_PROFILE_4m, -1}, 162 {BSC_DG_GROUP_ALU16_PROFILE_5m, -1}, 163 {BSC_DG_GROUP_ALU16_PROFILE_6m, -1}, 164 {BSC_DG_GROUP_ALU16_PROFILE_7m, -1}}; 165 166 167 uint32 bcmi_dg_group_alu32_fid[TOTAL_GROUP_ALU32_MEM] = 168 {GROUP_ALU32_PROFILE_0_IDXf, 169 GROUP_ALU32_PROFILE_1_IDXf, 170 GROUP_ALU32_PROFILE_2_IDXf, 171 GROUP_ALU32_PROFILE_3_IDXf, 172 GROUP_ALU32_PROFILE_4_IDXf, 173 GROUP_ALU32_PROFILE_5_IDXf, 174 GROUP_ALU32_PROFILE_6_IDXf, 175 GROUP_ALU32_PROFILE_7_IDXf, 176 GROUP_ALU32_PROFILE_8_IDXf, 177 GROUP_ALU32_PROFILE_9_IDXf, 178 GROUP_ALU32_PROFILE_10_IDXf, 179 GROUP_ALU32_PROFILE_11_IDXf}; 180 181 uint32 bcmi_dg_group_alu16_fid[TOTAL_GROUP_ALU16_MEM] = 182 {GROUP_ALU16_PROFILE_0_IDXf, 183 GROUP_ALU16_PROFILE_1_IDXf, 184 GROUP_ALU16_PROFILE_2_IDXf, 185 GROUP_ALU16_PROFILE_3_IDXf, 186 GROUP_ALU16_PROFILE_4_IDXf, 187 GROUP_ALU16_PROFILE_5_IDXf, 188 GROUP_ALU16_PROFILE_6_IDXf, 189 GROUP_ALU16_PROFILE_7_IDXf}; 190 191 /* 192 * Debug Counters information. 193 */ 194 uint32 bcmi_ft_alu32_debug_counter[TOTAL_GROUP_ALU32_MEM] = 195 {BSC_DG_ALU32_0_EVENT_COUNTERm, 196 BSC_DG_ALU32_1_EVENT_COUNTERm, 197 BSC_DG_ALU32_2_EVENT_COUNTERm, 198 BSC_DG_ALU32_3_EVENT_COUNTERm, 199 BSC_DG_ALU32_4_EVENT_COUNTERm, 200 BSC_DG_ALU32_5_EVENT_COUNTERm, 201 BSC_DG_ALU32_6_EVENT_COUNTERm, 202 BSC_DG_ALU32_7_EVENT_COUNTERm, 203 BSC_DG_ALU32_8_EVENT_COUNTERm, 204 BSC_DG_ALU32_9_EVENT_COUNTERm, 205 BSC_DG_ALU32_10_EVENT_COUNTERm, 206 BSC_DG_ALU32_11_EVENT_COUNTERm}; 207 208 209 uint32 bcmi_ft_alu16_debug_counter[TOTAL_GROUP_ALU16_MEM] = 210 {BSC_DG_ALU16_0_EVENT_COUNTERm, 211 BSC_DG_ALU16_1_EVENT_COUNTERm, 212 BSC_DG_ALU16_2_EVENT_COUNTERm, 213 BSC_DG_ALU16_3_EVENT_COUNTERm, 214 BSC_DG_ALU16_4_EVENT_COUNTERm, 215 BSC_DG_ALU16_5_EVENT_COUNTERm, 216 BSC_DG_ALU16_6_EVENT_COUNTERm, 217 BSC_DG_ALU16_7_EVENT_COUNTERm}; 218 219 220 uint32 bcmi_dg_group_load8_fid[TOTAL_GROUP_LOAD8_MEM] = 221 {GROUP_LOAD8_PROFILE_IDXf}; 222 223 uint32 bcmi_dg_group_load16_fid[TOTAL_GROUP_LOAD16_MEM] = 224 {GROUP_LOAD16_PROFILE_IDXf}; 225 226 alu_load_info_t load_8_info[TOTAL_GROUP_LOAD8_MEM] = 227 {{BSC_DG_GROUP_LOAD8_PROFILEm, -1},}; 228 alu_load_info_t load_16_info[TOTAL_GROUP_LOAD16_MEM] = 229 {{BSC_DG_GROUP_LOAD16_PROFILEm, -1},}; 230 231 #define BCMI_FT_ALU_LOAD_MEMS 4 232 233 /* There are 4 different types of memories. */ 234 alu_load_index_info_t 235 alu_load_index_info[BCM_MAX_NUM_UNITS][BCMI_FT_ALU_LOAD_MEMS]; 236 237 /* 238 * Function: 239 * bcmi_ft_load_pdd_entry_set 240 * Purpose: 241 * Set load PDD actions. 242 * Parameters: 243 * unit - (IN) BCM device id 244 * id - (IN) FT group id. 245 * load_type - (IN) Load memory type. 246 * index - (IN) memory index. 247 * clear - (IN) set/reset 248 * 249 * Returns: 250 * NONE 251 */ 252 int 253 bcmi_ft_load_pdd_entry_set( 254 int unit, 255 bcm_flowtracker_group_t id, 256 bcmi_ft_alu_load_type_t load_type, 257 int index, 258 int clear) 259 { 260 261 uint32 trigger = 0; 262 bsc_dg_group_load16_profile_entry_t load16_entry; 263 bsc_dg_group_load8_profile_entry_t load8_entry; 264 uint32 ctrlfmt[1]; 265 uint32 *entry; 266 int start_index = 0, i; 267 soc_mem_t mem; 268 int fmt = 0; 269 270 int data[TOTAL_GROUP_LOAD16_DATA_NUM] = 271 {DATA_15f, 272 DATA_14f, 273 DATA_13f, 274 DATA_12f, 275 DATA_11f, 276 DATA_10f, 277 DATA_9f, 278 DATA_8f, 279 DATA_7f, 280 DATA_6f, 281 DATA_5f, 282 DATA_4f, 283 DATA_3f, 284 DATA_2f, 285 DATA_1f, 286 DATA_0f}; 287 288 sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t)); 289 sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t)); 290 291 if (load_type == bcmiFtAluLoadTypeLoad16) { 292 start_index = 0; 293 mem = BSC_DG_GROUP_LOAD16_PROFILEm; 294 entry = (uint32 *) (&load16_entry); 295 fmt = BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt; 296 } else { 297 start_index = 8; 298 mem = BSC_DG_GROUP_LOAD8_PROFILEm; 299 entry = (uint32 *) (&load8_entry); 300 fmt = BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt; 301 } 302 303 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, entry)); 304 305 for (i=start_index; i<16; i++) { 306 307 soc_mem_field_get(unit, mem, entry, data[i], ctrlfmt); 308 309 trigger = soc_format_field32_get(unit, fmt, ctrlfmt, LOAD_TRIGGERf); 310 311 if (trigger && (!clear)) { 312 /* Set pdd profile entry for this alu entry. */ 313 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 314 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 315 (BCMI_FT_PDD_INFO(unit, load_type)[15-i]).param_id, 1); 316 } else { 317 /* Set pdd profile entry for this alu entry. */ 318 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 319 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 320 (BCMI_FT_PDD_INFO(unit, load_type)[15-i]).param_id, 0); 321 } 322 } 323 324 return BCM_E_NONE; 325 } 326 327 /* 328 * Function: 329 * bcmi_ft_element_alu_action_get 330 * Purpose: 331 * Get ALU actions. 332 * Parameters: 333 * element - (IN) FT element type. 334 * action - (OUT) Action for element. 335 * 336 * Returns: 337 * BCM_E_XXX 338 */ 339 int 340 bcmi_ft_element_alu_action_get( 341 bcm_flowtracker_tracking_param_type_t element, 342 bcm_flowtracker_check_action_t *action) 343 { 344 345 int i = 0; 346 347 for (i = 0; i < COUNTOF(ft_element_info); i++) { 348 if (element == ft_element_info[i].element) { 349 *action = ft_element_info[i].action; 350 return BCM_E_NONE; 351 } 352 } 353 354 return BCM_E_PARAM; 355 } 356 357 /* 358 * Function: 359 * bcmi_ft_get_alu32_mem 360 * Purpose: 361 * Get alu32 enable memory banks. 362 * Parameters: 363 * unit - (IN) BCM device id. 364 * 365 * Returns: 366 * enabled memory banks 367 */ 368 int 369 bcmi_ft_get_alu32_mem(int unit) 370 { 371 372 if (soc_feature(unit, soc_feature_flowtracker_ver_1_alu32_0_1_banks)) { 373 /* Internally SDK will only pick first 2. */ 374 return 2; 375 } 376 377 return TOTAL_GROUP_ALU32_MEM; 378 } 379 380 /* 381 * Function: 382 * bcmi_ft_alu_load_init 383 * Purpose: 384 * Initialize ALU and LOAD software state. 385 * Parameters: 386 * unit - (IN) BCM device id. 387 * 388 * Returns: 389 * BCM_E_XXX 390 */ 391 int 392 bcmi_ft_alu_load_init(int unit) 393 { 394 395 int i=0, j=0; 396 int total_indexes_per_mem = 0; 397 /* The below should be done during group init. */ 398 399 /* Set ALU16 data. */ 400 BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16) = 401 TOTAL_GROUP_ALU16_MEM; 402 BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeAlu16) = alu_16_info; 403 BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu16) = bcmi_alu16_pdd_info; 404 BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeAlu16) = 405 bcmi_dg_group_alu16_fid; 406 alu_load_methods[bcmiFtAluLoadTypeAlu16] = alu16_methods; 407 408 /* Set ALU32 data. */ 409 BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32) = 410 bcmi_ft_get_alu32_mem(unit); 411 BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeAlu32) = alu_32_info; 412 BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu32) = bcmi_alu32_pdd_info; 413 BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeAlu32) = 414 bcmi_dg_group_alu32_fid; 415 alu_load_methods[bcmiFtAluLoadTypeAlu32] = alu32_methods; 416 417 /* Set LOAD8 data. */ 418 BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeLoad8) = 419 TOTAL_GROUP_LOAD8_MEM; 420 BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeLoad8) = load_8_info; 421 BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeLoad8) = bcmi_load8_pdd_info; 422 BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeLoad8) = 423 bcmi_dg_group_load8_fid; 424 alu_load_methods[bcmiFtAluLoadTypeLoad8] = load8_methods; 425 426 427 BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeLoad16) = 428 TOTAL_GROUP_LOAD16_MEM; 429 BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeLoad16) = load_16_info; 430 BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeLoad16) = bcmi_load16_pdd_info; 431 BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeLoad16) = 432 bcmi_dg_group_load16_fid; 433 alu_load_methods[bcmiFtAluLoadTypeLoad16] = load16_methods; 434 435 436 /* Set the mem size for the ALUs. */ 437 for (i=bcmiFtAluLoadTypeLoad8; i<bcmiFtAluLoadTypeNone; i++) { 438 439 total_indexes_per_mem = 0; 440 for (j=0; j<alu_load_index_info[unit][i].total_mem_count; j++) { 441 442 443 alu_load_index_info[unit][i].alu_load_info[j].mem_size = 444 soc_mem_index_count( 445 unit, alu_load_index_info[unit][i].alu_load_info[j].mem); 446 447 total_indexes_per_mem += 448 alu_load_index_info[unit][i].alu_load_info[j].mem_size; 449 450 } 451 alu_load_index_info[unit][i].total_idx_per_memory = 452 total_indexes_per_mem; 453 454 /* lets calculate indexes or all memories of one type. */ 455 alu_load_index_info[unit][i].index_bitmap = 456 sal_alloc(SHR_BITALLOCSIZE(total_indexes_per_mem), 457 "alu_load_bitmap"); 458 459 if (!alu_load_index_info[unit][i].index_bitmap) { 460 bcmi_ft_alu_load_cleanup(unit); 461 return BCM_E_MEMORY; 462 } 463 464 sal_memset(alu_load_index_info[unit][i].index_bitmap, 0, 465 SHR_BITALLOCSIZE(total_indexes_per_mem)); 466 467 /* Now allocate the ref count memory. */ 468 alu_load_index_info[unit][i].idx_refcount = 469 sal_alloc((total_indexes_per_mem * sizeof(uint32)), 470 "Indexes Refcount"); 471 472 if (!alu_load_index_info[unit][i].idx_refcount) { 473 bcmi_ft_alu_load_cleanup(unit); 474 return BCM_E_MEMORY; 475 } 476 477 sal_memset(alu_load_index_info[unit][i].idx_refcount, 0, 478 (total_indexes_per_mem * sizeof(uint32))); 479 } 480 return 0; 481 } 482 483 /* 484 * Function: 485 * bcmi_ft_alu_load_cleanup 486 * Purpose: 487 * Clear ALU and LOAD software state. 488 * Parameters: 489 * unit - (IN) BCM device id. 490 * 491 * Returns: 492 * BCM_E_XXX 493 */ 494 void 495 bcmi_ft_alu_load_cleanup(int unit) 496 { 497 498 int i=0, j=0; 499 500 /* Set the mem size for the ALUs. */ 501 for (i=bcmiFtAluLoadTypeLoad8; i<bcmiFtAluLoadTypeNone; i++) { 502 503 for (; j<alu_load_index_info[unit][i].total_mem_count; j++) { 504 505 alu_load_index_info[unit][i].alu_load_info[j].mem_size = 0; 506 alu_load_index_info[unit][i].total_idx_per_memory = 0; 507 } 508 509 /* lets calculate indexes or all memories of one type. */ 510 if (alu_load_index_info[unit][i].index_bitmap) { 511 sal_free(alu_load_index_info[unit][i].index_bitmap); 512 alu_load_index_info[unit][i].index_bitmap = NULL; 513 } 514 515 /* Now allocate the ref count memory. */ 516 if (alu_load_index_info[unit][i].idx_refcount) { 517 sal_free(alu_load_index_info[unit][i].idx_refcount); 518 alu_load_index_info[unit][i].idx_refcount = NULL; 519 } 520 } 521 522 return; 523 } 524 525 /* 526 * Function: 527 * bcmi_ft_alu_load_mem_index_get 528 * Purpose: 529 * Get hw index for ALU and load memories from sw index. 530 * Parameters: 531 * unit - (IN) BCM device id 532 * index - (IN) sw index. 533 * type - (IN) ALU/Load memory type. 534 * new_index - (OUT) memory index. 535 * mem - (OUT) memory. 536 * a_idx - (IN) array index of the memory in database. 537 * 538 * Returns: 539 * NONE 540 */ 541 void 542 bcmi_ft_alu_load_mem_index_get( 543 int unit, 544 int index, bcmi_ft_alu_load_type_t type, 545 int *new_index, soc_mem_t *mem, int *a_idx) 546 { 547 548 alu_load_info_t *temp; 549 int total_no_of_mem_entries = 0; 550 int i = 0; 551 int prev_index = 0, temp_index = 0; 552 553 total_no_of_mem_entries = BCMI_FT_ALU_INFO(unit, type).total_mem_count; 554 555 temp = BCMI_FT_ALU_INFO(unit, type).alu_load_info; 556 557 for(i=0; i<(total_no_of_mem_entries); i++) { 558 559 temp_index += temp[i].mem_size; 560 561 /* If index falls in this range then use this index. */ 562 if (temp_index > index) { 563 if (new_index != NULL) { 564 *new_index = index - prev_index; 565 } 566 if (mem != NULL) { 567 *mem = temp[i].mem; 568 } 569 if (a_idx != NULL) { 570 *a_idx = i; 571 } 572 return; 573 } 574 prev_index = temp_index; 575 } 576 } 577 578 /* 579 * Function: 580 * bcmi_ft_alu_hw_operation_get 581 * Purpose: 582 * Get hw operations based on sw operations. 583 * Parameters: 584 * unit - (IN) BCM device id 585 * operation - (IN) sw operation. 586 * check_0_operation - (IN) hw operation 1 587 * check_1_operation - (IN) hw operation 2 588 * 589 * Returns: 590 * BCM_E_XXX 591 */ 592 int 593 bcmi_ft_alu_hw_operation_get( 594 int unit, 595 bcm_flowtracker_check_operation_t operation, 596 int *check_0_operation, 597 int *check_1_operation) 598 { 599 600 601 if (operation >= bcmFlowtrackerCheckOpCount) { 602 return BCM_E_PARAM; 603 } 604 605 switch(operation) { 606 607 case bcmFlowtrackerCheckOpEqual: 608 *check_0_operation = 2; 609 break; 610 case bcmFlowtrackerCheckOpNotEqual: 611 *check_0_operation = 3; 612 break; 613 case bcmFlowtrackerCheckOpGreater: 614 *check_0_operation = 0; 615 break; 616 case bcmFlowtrackerCheckOpGreaterEqual: 617 *check_0_operation = 1; 618 break; 619 case bcmFlowtrackerCheckOpSmaller: 620 *check_1_operation = 4; 621 break; 622 case bcmFlowtrackerCheckOpSmallerEqual: 623 *check_1_operation = 5; 624 break; 625 case bcmFlowtrackerCheckOpPass: 626 *check_0_operation = 6; 627 break; 628 case bcmFlowtrackerCheckOpFail: 629 case bcmFlowtrackerCheckOpNone: 630 *check_0_operation = 7; 631 *check_1_operation = 7; 632 break; 633 case bcmFlowtrackerCheckOpInRange: 634 *check_0_operation = 1; 635 *check_1_operation = 5; 636 break; 637 case bcmFlowtrackerCheckOpOutofRange: 638 *check_0_operation = 5; 639 *check_1_operation = 1; 640 break; 641 642 default : 643 *check_0_operation = 6; 644 *check_1_operation = 6; 645 } 646 647 return BCM_E_NONE; 648 } 649 650 /* 651 * Function: 652 * bcmi_ft_flowchecker_opr_is_dual 653 * Purpose: 654 * Check if hw operations is using dual actions. 655 * Parameters: 656 * unit - (IN) BCM device id 657 * operation - (IN) sw operation. 658 * 659 * Returns: 660 * TRUE/FALSE 661 */ 662 int 663 bcmi_ft_flowchecker_opr_is_dual( 664 int unit, 665 bcm_flowtracker_check_operation_t operation) 666 { 667 668 switch(operation) { 669 670 case bcmFlowtrackerCheckOpInRange: 671 case bcmFlowtrackerCheckOpOutofRange: 672 return 1; 673 break; 674 675 default: 676 return 0; 677 } 678 679 return 0; 680 } 681 682 /* 683 * Function: 684 * bcmi_ft_flowchecker_data_is_valid 685 * Purpose: 686 * Check if flowchecker data is valid 687 * Parameters: 688 * unit - (IN) BCM device id 689 * fc_info - (IN) Flowchecker information. 690 * 691 * Returns: 692 * TRUE/FALSE 693 */ 694 int 695 bcmi_ft_flowchecker_data_is_valid( 696 int unit, 697 bcmi_flowtracker_flowchecker_info_t *fc_info) 698 { 699 700 if (bcmi_ft_flowchecker_opr_is_dual(unit, fc_info->check1.operation)) { 701 /* 702 * If check1 is already using both hw operation 703 * then check 1 should be empty. 704 */ 705 if (fc_info->check2.param != bcmFlowtrackerTrackingParamTypeNone) { 706 return 0; 707 } 708 } 709 710 return 1; 711 } 712 713 /* 714 * Function: 715 * bcmi_ft_flowchecker_values_get 716 * Purpose: 717 * Check if flowchecker data is valid 718 * Parameters: 719 * unit - (IN) BCM device id 720 * fc_info - (IN) Flowchecker information. 721 * val1 - (OUT) value for check 1. 722 * val2 - (OUT) value for check 2. 723 * opr1 - (OUT) operation for check 1. 724 * opr2 - (OUT) operation for check 2. 725 * 726 * Returns: 727 * BCM_E_XXX 728 */ 729 int 730 bcmi_ft_flowchecker_values_get(int unit, 731 bcmi_flowtracker_flowchecker_info_t *fc_info, 732 int *val1, int *val2, int *opr1, int *opr2) 733 { 734 int l_opr1 = -1, l_opr2 = -1; 735 736 *val1 = *val2 = *opr1 = *opr2 = -1; 737 738 /* Sanity check first. */ 739 if (!bcmi_ft_flowchecker_data_is_valid(unit, fc_info)) { 740 return BCM_E_PARAM; 741 } 742 743 if (fc_info->check1.param) { 744 /* Get check1 operation and value first. */ 745 BCM_IF_ERROR_RETURN(bcmi_ft_alu_hw_operation_get(unit, 746 fc_info->check1.operation, &l_opr1, &l_opr2)); 747 748 *opr1 = ((l_opr1 == -1) ? l_opr2 : l_opr1); 749 *val1 = ((l_opr1 == -1) ? fc_info->check1.max_value : 750 fc_info->check1.min_value); 751 752 if (l_opr1 != -1) { 753 754 /* 755 * if both operations are valid on first check, 756 * then it is range operation which has two opr and val. 757 */ 758 *opr2 = ((l_opr2 != -1) ? l_opr2 : -1); 759 *val2 = fc_info->check1.max_value; 760 } 761 762 if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) { 763 764 /* Special Processing for Dos Attacks. */ 765 if (((fc_info->check1.param == 766 bcmFlowtrackerTrackingParamTypeDosAttack) || 767 (fc_info->check1.param == 768 bcmFlowtrackerTrackingParamTypeInnerDosAttack)) && 769 (fc_info->action_info.action == 770 bcmFlowtrackerCheckActionUpdateValue)) { 771 772 /* Mark both of the alu entries to make a combined test. */ 773 if (fc_info->check1.min_value) { 774 *val1 = fc_info->check1.min_value & 0xffff; 775 *val2 = (fc_info->check1.min_value >> 16) & 0xffff; 776 *opr2 = *opr1; 777 } else { 778 *val1 = fc_info->check1.max_value & 0xffff; 779 *val2 = (fc_info->check1.max_value >> 16) & 0xffff; 780 *opr1 = *opr2; 781 } 782 } 783 } 784 } 785 786 l_opr1 = l_opr2 = -1; 787 788 if (fc_info->check2.param) { 789 /* Get check1 operation and value first. */ 790 BCM_IF_ERROR_RETURN(bcmi_ft_alu_hw_operation_get(unit, 791 fc_info->check2.operation, &l_opr1, &l_opr2)); 792 793 *opr2 = ((l_opr1 == -1) ? l_opr2 : l_opr1); 794 *val2 = ((l_opr1 == -1) ? fc_info->check2.max_value : 795 fc_info->check2.min_value); 796 797 } 798 799 return BCM_E_NONE; 800 } 801 802 /* 803 * Function: 804 * bcmi_ft_kmap_val_get 805 * Purpose: 806 * Get ALU KMAP value. 807 * Parameters: 808 * unit - (IN) BCM device id. 809 * param - (IN) tracking paramete. 810 * kmap_val - (OUT) Kmap value. 811 * 812 * Returns: 813 * BCM_E_XXX 814 */ 815 int 816 bcmi_ft_kmap_val_get( 817 int unit, 818 bcmi_flowtracker_flowchecker_info_t *fc_info, 819 bcm_flowtracker_check_operation_t operation, 820 uint32 *kmap_val) 821 { 822 823 824 if (operation >= bcmFlowtrackerCheckOpCount) { 825 return BCM_E_PARAM; 826 } 827 828 829 if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) { 830 831 if (((fc_info->check1.param == 832 bcmFlowtrackerTrackingParamTypeDosAttack) || 833 (fc_info->check1.param == 834 bcmFlowtrackerTrackingParamTypeInnerDosAttack)) && 835 (fc_info->check1.operation == bcmFlowtrackerCheckOpNotEqual) && 836 (fc_info->action_info.action == 837 bcmFlowtrackerCheckActionUpdateValue)) { 838 839 *kmap_val = 0xa004; 840 return BCM_E_NONE; 841 } 842 } 843 844 845 switch(operation) { 846 847 case bcmFlowtrackerCheckOpOutofRange: 848 *kmap_val = 0x2004; 849 break; 850 default: 851 *kmap_val = 0x8000; 852 break; 853 } 854 855 return BCM_E_NONE; 856 } 857 858 /* 859 * Function: 860 * bcmi_ft_alu_hw_action_get 861 * Purpose: 862 * Get ALU hardware actions. 863 * Parameters: 864 * unit - (IN) BCM device id. 865 * action - (OUT) software Action for element. 866 * hw_action - (OUT) Action for element. 867 * 868 * Returns: 869 * BCM_E_XXX 870 */ 871 int 872 bcmi_ft_alu_hw_action_get( 873 int unit, 874 bcm_flowtracker_tracking_param_type_t param, 875 bcm_flowtracker_check_action_t action, 876 int *hw_action) 877 { 878 879 if (action >= bcmFlowtrackerCheckActionCount) { 880 return BCM_E_PARAM; 881 } 882 883 switch(action) { 884 885 case bcmFlowtrackerCheckActionNone: 886 *hw_action = 0; 887 break; 888 889 case bcmFlowtrackerCheckActionCounterIncr: 890 *hw_action = 1; 891 break; 892 893 case bcmFlowtrackerCheckActionCounterIncrByPktBytes: 894 *hw_action = 2; 895 break; 896 897 case bcmFlowtrackerCheckActionCounterIncrByValue: 898 *hw_action = 3; 899 break; 900 901 case bcmFlowtrackerCheckActionUpdateLowerValue: 902 *hw_action = 4; 903 break; 904 905 case bcmFlowtrackerCheckActionUpdateHigherValue: 906 *hw_action = 5; 907 break; 908 case bcmFlowtrackerCheckActionUpdateValue: 909 910 if ((param == bcmFlowtrackerTrackingParamTypeDosAttack) || 911 (param == bcmFlowtrackerTrackingParamTypeInnerDosAttack)) { 912 *hw_action = 8; 913 } else { 914 *hw_action = 6; 915 } 916 break; 917 918 case bcmFlowtrackerCheckActionUpdateAverageValue: 919 *hw_action = 7; 920 break; 921 922 default: 923 *hw_action = 0; 924 return BCM_E_PARAM; 925 } 926 927 return BCM_E_NONE; 928 } 929 930 931 /* 932 * Function: 933 * bcmi_ft_alu_load_values_normalize 934 * Purpose: 935 * Get ALU/Load values to get ALU/LOAD types. 936 * Parameters: 937 * unit - (IN) BCM device id. 938 * info - (IN) Group ALU/LOAD data element. 939 * length - (OUT) length of extractor. 940 * alu - (OUT) ALU or LOAD. 941 * Returns: 942 * BCM_E_XXX 943 */ 944 int 945 bcmi_ft_alu_load_values_normalize( 946 int unit, 947 bcmi_ft_group_alu_info_t *info, 948 int *length, 949 int *alu) 950 { 951 952 if (!info || !length || !alu) { 953 return BCM_E_PARAM; 954 } 955 956 if (info->element_type2) { 957 /* Cannot support ALU and LOAD mixed elements. */ 958 if (info->key1.is_alu != info->key2.is_alu) { 959 return BCM_E_PARAM; 960 } 961 } 962 963 *alu = info->key1.is_alu; 964 965 /* Get the bigger length. */ 966 *length = ((info->key1.length > info->key2.length) ? 967 info->key1.length : info->key2.length); 968 969 return BCM_E_NONE; 970 } 971 /* 972 * Function: 973 * bcmi_ft_alu_load_type_get 974 * Purpose: 975 * Get ALU/Load type based on length/params. 976 * Parameters: 977 * unit - (IN) BCM device id. 978 * alu - (IN) Is alu required. 979 * length - (IN) length of extractor. 980 * type - (OUT) type of load/ALU. 981 * Returns: 982 * BCM_E_XXX 983 */ 984 int 985 bcmi_ft_alu_load_type_get( 986 int unit, 987 int alu, 988 int length, 989 bcmi_ft_alu_load_type_t *type) 990 { 991 992 993 int min_extractor_length = 0; 994 int local_type = 0; 995 int is_alu = 0; 996 997 /* 998 * These checks should not fail as they are checked when 999 * information is added into the group. 1000 * For now, keeping the length checks with fixed numbers. 1001 * 32 is for ALU32 check and 16 is for LOAD16 and ALU16. 1002 */ 1003 if (alu && ((length > 32) || (length < 8))) { 1004 return BCM_E_PARAM; 1005 } 1006 1007 1008 if ((!alu) && (length > 16)) { 1009 return BCM_E_PARAM; 1010 } 1011 1012 if (alu && ((length >=8) && (length < 16))) { 1013 /* 1014 * if ALU is required but we have less than 16 bit of length 1015 * then this might be a case where extractor is not aligned properly. 1016 * Hence we will change length accordingly to pick correct alu type. 1017 */ 1018 length = 16; 1019 } 1020 1021 /* Get the min extractor length for each memory. */ 1022 min_extractor_length = ((alu) ? 16 : 8); 1023 1024 /* ALu memories are in upper indexes. */ 1025 is_alu = alu; 1026 is_alu <<= 1; 1027 1028 /* based on the alu type and length, get the type of memory to use. */ 1029 local_type = is_alu + ((length > min_extractor_length) ? 1 : 0); 1030 1031 1032 switch (local_type) { 1033 case 0 : 1034 *type = bcmiFtAluLoadTypeLoad8; 1035 break; 1036 1037 case 1 : 1038 *type = bcmiFtAluLoadTypeLoad16; 1039 break; 1040 case 2 : 1041 *type = bcmiFtAluLoadTypeAlu16; 1042 break; 1043 case 3 : 1044 *type = bcmiFtAluLoadTypeAlu32; 1045 break; 1046 default: 1047 return BCM_E_PARAM; 1048 } 1049 1050 return BCM_E_NONE; 1051 } 1052 1053 /* 1054 * Function: 1055 * bcmi_ft_alu_check_free_index 1056 * Purpose: 1057 * Check ALU/Load type based on group. 1058 * Parameters: 1059 * unit - (IN) BCM device id. 1060 * id - (IN) FT group id. 1061 * alu_load_type - (IN) type of load/ALU. 1062 * index - (IN) Free index of that memory. 1063 * Returns: 1064 * BCM_E_XXX 1065 */ 1066 int 1067 bcmi_ft_alu_check_free_index( 1068 int unit, 1069 bcm_flowtracker_group_t id, 1070 bcmi_ft_alu_load_type_t alu_load_type, 1071 int index) 1072 { 1073 1074 uint32 *in_use_array = NULL; 1075 int temp_index; 1076 uint32 mem_idx = 0; 1077 int size_per_mem = 0; 1078 1079 /* Get the total indexes for this type of memory. */ 1080 size_per_mem = 1081 alu_load_index_info[unit][alu_load_type].alu_load_info->mem_size; 1082 1083 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 1084 in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id); 1085 } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) { 1086 in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id); 1087 } 1088 1089 temp_index = index; 1090 size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx); 1091 1092 /* Check which memory idx, this entry index belongs to. */ 1093 while (temp_index >= size_per_mem) { 1094 1095 temp_index -= size_per_mem; 1096 mem_idx++; 1097 size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx); 1098 } 1099 1100 if (in_use_array != NULL) { 1101 /* This ALU memory is used. go for next one. */ 1102 if (in_use_array[mem_idx]) { 1103 return FALSE; 1104 } 1105 } 1106 1107 return TRUE; 1108 } 1109 1110 1111 /* 1112 * Function: 1113 * bcmi_ft_alu_get_free_index 1114 * Purpose: 1115 * Get ALU/Load type based on length/params. 1116 * Parameters: 1117 * unit - (IN) BCM device id. 1118 * id - (IN) FT group id. 1119 * alu_load_type - (IN) type of load/ALU. 1120 * index - (OUT) Free index of that memory. 1121 * Returns: 1122 * BCM_E_XXX 1123 */ 1124 int 1125 bcmi_ft_alu_get_free_index( 1126 int unit, 1127 bcm_flowtracker_group_t id, 1128 bcmi_ft_alu_load_type_t alu_load_type, 1129 int *index) 1130 { 1131 1132 int i = 0; 1133 uint32 *in_use_array = NULL; 1134 uint32 total_mems = 1; 1135 uint32 mem_idx = 0; 1136 int size_per_mem = 0; 1137 int start_index = 0, end_index = 0; 1138 1139 *index = -1; 1140 1141 /* Get the total indexes for this type of memory. */ 1142 size_per_mem = 1143 alu_load_index_info[unit][alu_load_type].alu_load_info->mem_size; 1144 1145 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 1146 in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id); 1147 total_mems = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16); 1148 } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) { 1149 in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id); 1150 total_mems = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32); 1151 } 1152 1153 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 1154 (BSL_META_U(unit, "total_mems=%d\n"), total_mems)); 1155 1156 1157 /* start index should be where the free index starts. */ 1158 while (mem_idx < total_mems) { 1159 1160 size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx); 1161 1162 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 1163 (BSL_META_U(unit, "mem_idx = %d, size_per_mem=%d\n"), 1164 mem_idx, size_per_mem)); 1165 1166 if (in_use_array != NULL) { 1167 /* This ALU memory is used. go for next one. */ 1168 if ((in_use_array[mem_idx]) || 1169 (bcmi_ft_chip_debug_mem_check(unit, alu_load_type, mem_idx))) { 1170 1171 mem_idx++; 1172 start_index += size_per_mem; 1173 continue; 1174 } 1175 } 1176 /* set the end index according to the indexes in that memory. */ 1177 end_index = start_index + size_per_mem; 1178 1179 /* 1180 * Cannot not index 0 for ALU/LOAD. 1181 * If index 0 is used then Group may point to it and 1182 * malicious actions can be taken on that flow. 1183 */ 1184 i = start_index; 1185 i += ((start_index == 0) ? 1 : 0); 1186 1187 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 1188 (BSL_META_U(unit, "start_index = %d, end_index=%d\n"), 1189 start_index, end_index)); 1190 1191 /* based on the above index. select the bitmap. */ 1192 for (; i<end_index; i++) { 1193 if (!(SHR_BITGET(BCMI_FT_ALU_LOAD_BITMAP 1194 (unit, alu_load_type), i))) { 1195 1196 *index = i; 1197 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 1198 (BSL_META_U(unit, "mem_idx = %d, index = %d\n"), 1199 mem_idx, *index)); 1200 return BCM_E_NONE; 1201 } 1202 } 1203 start_index += size_per_mem; 1204 mem_idx++; 1205 } 1206 1207 return BCM_E_RESOURCE; 1208 } 1209 1210 /* 1211 * Function: 1212 * bcmi_ft_alu_entry_match 1213 * Purpose: 1214 * Match Load 16 entry in hardware 1215 * Parameters: 1216 * unit - (IN) BCM device id 1217 * id - (IN) FT group id. 1218 * info - (IN) ALU/Load information of group. 1219 * load16_indexes - (IN) Load 16 indexes in group 1220 * index - (OUT) sw index. 1221 * 1222 * Returns: 1223 * BCM_E_XXX 1224 */ 1225 int 1226 bcmi_ft_alu_entry_match( 1227 int unit, 1228 bcm_flowtracker_group_t id, 1229 bcmi_ft_group_alu_info_t *group_alu_info, 1230 bcmi_ft_alu_hash_info_t *alu_info, 1231 int *load16_indexes, int *index) 1232 { 1233 1234 1235 /* 1236 * Need to compare all the fields to check if 1237 * this is exact match. 1238 * location, length, type, 1239 * update location, update operation. 1240 * export threshold and operation. 1241 */ 1242 if (group_alu_info->key1.location != 1243 alu_info->key.location) { 1244 return BCM_E_NOT_FOUND; 1245 } 1246 1247 if (group_alu_info->key1.length != 1248 alu_info->key.length) { 1249 return BCM_E_NOT_FOUND; 1250 } 1251 1252 if (group_alu_info->key1.is_alu != 1253 alu_info->key.is_alu) { 1254 return BCM_E_NOT_FOUND; 1255 } 1256 1257 if (group_alu_info->element_type1 != 1258 alu_info->param) { 1259 return BCM_E_NOT_FOUND; 1260 } 1261 1262 if (BCMI_FT_GROUP_FTFP_DATA(unit, id).direction != 1263 (alu_info->direction)) { 1264 return BCM_E_NOT_FOUND; 1265 } 1266 1267 /* 1268 * For ALU based memories, we need to make sure that 1269 * other than basic data, update and export data should 1270 * also match. 1271 */ 1272 if (bcmi_ft_check_list_compare(unit, &(alu_info->head), 1273 group_alu_info->flowchecker_id)) { 1274 return BCM_E_NOT_FOUND; 1275 } 1276 1277 return BCM_E_NONE; 1278 } 1279 1280 /* 1281 * Function: 1282 * bcmi_ft_check_action_shift_bits_get 1283 * Purpose: 1284 * Get the shift bits, if required, for writing 1285 * threshold value in hardware. 1286 * Parameters: 1287 * unit - (IN) BCM device id 1288 * action - (IN) FT Check Action. 1289 * info - (IN) ALU/Load information of group. 1290 * shift_bits - (OUT) Number of bits threshold needs 1291 * to be shifted before writing to hardware. 1292 * 1293 * Returns: 1294 * None. 1295 */ 1296 void 1297 bcmi_ft_check_action_shift_bits_get( 1298 int unit, 1299 bcm_flowtracker_check_action_t action, 1300 bcmi_ft_group_alu_info_t *info, 1301 int *shift_bits) 1302 { 1303 int shift_required = FALSE; 1304 1305 *shift_bits = 0; 1306 1307 switch(action) { 1308 1309 case bcmFlowtrackerCheckActionNone: 1310 case bcmFlowtrackerCheckActionCounterIncr: 1311 case bcmFlowtrackerCheckActionCounterIncrByPktBytes: 1312 shift_required = FALSE; 1313 break; 1314 1315 case bcmFlowtrackerCheckActionCounterIncrByValue: 1316 case bcmFlowtrackerCheckActionUpdateLowerValue: 1317 case bcmFlowtrackerCheckActionUpdateHigherValue: 1318 case bcmFlowtrackerCheckActionUpdateValue: 1319 case bcmFlowtrackerCheckActionUpdateAverageValue: 1320 shift_required = TRUE; 1321 break; 1322 1323 default: 1324 shift_required = FALSE; 1325 } 1326 1327 if (shift_required == TRUE) { 1328 *shift_bits = info->action_key.location % 16; 1329 } 1330 } 1331 1332 /*|************************************************************| 1333 |******** ALU Software Install Methods. ********| 1334 |************************************************************| 1335 |******* End ********| 1336 |************************************************************|*/ 1337 1338 1339 1340 1341 /*|************************************************************| 1342 |******** ALU Hardware Install Methods. ********| 1343 |************************************************************| 1344 |******* Start ********| 1345 |************************************************************|*/ 1346 1347 1348 /* 1349 * Function: 1350 * bcmi_ft_flowchecker_alu_base_control_set 1351 * Purpose: 1352 * Set base control memory for ALUs.. 1353 * Parameters: 1354 * unit - (IN) BCM device id 1355 * id - (IN) FT group id. 1356 * alu_info - (IN) ALU information of group. 1357 * alu_fmt - (IN) formatiinfo of memory. 1358 * 1359 * Returns: 1360 * NONE 1361 */ 1362 1363 int 1364 bcmi_ft_flowchecker_alu_base_control_set( 1365 int unit, 1366 bcm_flowtracker_group_t id, 1367 bcmi_ft_group_alu_info_t *alu_info, 1368 uint32 *alu_fmt) 1369 { 1370 int check_0_opr = -1, check_1_opr = -1; 1371 int rv = BCM_E_NONE; 1372 bcmi_flowtracker_flowchecker_info_t fc_info; 1373 int hw_action = 0; 1374 bcm_flowtracker_check_action_t alu_action = 0; 1375 int actual_location = 0, actual_location2 = 0; 1376 int update_location = 0; 1377 bcm_flowtracker_tracking_param_type_t element = 0; 1378 uint32 kmap_val = 0; 1379 int length = 16, length2 = 16; 1380 bcm_flowtracker_check_operation_t opr = bcmFlowtrackerCheckOpNone; 1381 int val1, val2, opr1, opr2; 1382 int clear_on_export = 0; 1383 int export_check_mode = 1; 1384 1385 if (alu_fmt == NULL) { 1386 return BCM_E_PARAM; 1387 } 1388 1389 if (alu_info == NULL) { 1390 return BCM_E_PARAM; 1391 } 1392 1393 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1394 val1 = val2 = opr1 = opr2 = -1; 1395 1396 actual_location = alu_info->key1.location; 1397 actual_location2 = alu_info->key2.location; 1398 1399 if ((alu_info->key1.location % 16) != 0) { 1400 actual_location = ((alu_info->key1.location / 16) * 16); 1401 } 1402 1403 if (alu_info->key1.length > 16) { 1404 /* ALU is at 32 bit boundary. */ 1405 length = 32; 1406 } 1407 1408 if (alu_info->element_type2) { 1409 if ((alu_info->key2.location % 16) != 0) { 1410 actual_location2 = ((alu_info->key2.location / 16) * 16); 1411 } 1412 1413 if (alu_info->key2.length > 16) { 1414 /* ALU is at 32 bit boundary. */ 1415 length2 = 32; 1416 } 1417 1418 } else { 1419 actual_location2 = actual_location; 1420 length2 = length; 1421 } 1422 1423 /* 1424 * ftfp is sending location in continuous index of 256B. 1425 * Each extractor here is 16 bytes so long, so 1426 * need to divide it by 16 to get correct location. 1427 */ 1428 actual_location = (actual_location / length); 1429 actual_location2 = (actual_location2 / length2); 1430 1431 /* Update the action location. */ 1432 if (alu_info->action_element_type) { 1433 update_location = alu_info->action_key.location / 16; 1434 element = alu_info->action_element_type; 1435 } else { 1436 update_location = actual_location; 1437 element = alu_info->element_type1; 1438 } 1439 1440 if (alu_info->flowchecker_id > 0) { 1441 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 1442 (unit, alu_info->flowchecker_id, &fc_info)); 1443 1444 rv = bcmi_ft_flowchecker_values_get(unit, &fc_info, &val1, &val2, 1445 &opr1, &opr2); 1446 opr = fc_info.check1.operation; 1447 1448 if (BCM_FAILURE(rv)) { 1449 return rv; 1450 } 1451 1452 if (opr1 != -1) { 1453 /* We can associate two flowcheckers together so that we can have . */ 1454 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1455 alu_fmt, CHECK_0_ATTR_SELECTf, actual_location); 1456 1457 /* Convert bcm layer opertaion in hw operations. */ 1458 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1459 alu_fmt, CHECK_0_OPERATIONf, opr1); 1460 1461 if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1) { 1462 soc_format_field32_set(unit, 1463 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1464 alu_fmt, TIMESTAMP_0_TRIGf, 1); 1465 } 1466 1467 if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2) { 1468 soc_format_field32_set(unit, 1469 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1470 alu_fmt, TIMESTAMP_1_TRIGf, 1); 1471 } 1472 1473 } 1474 1475 if (opr2 != -1) { 1476 1477 soc_format_field32_set(unit, 1478 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1479 alu_fmt, CHECK_1_ATTR_SELECTf, actual_location2); 1480 1481 soc_format_field32_set(unit, 1482 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1483 alu_fmt, CHECK_1_OPERATIONf, opr2); 1484 1485 soc_format_field32_set(unit, 1486 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1487 alu_fmt, CHECK_LOGIC_BIT_SELECT_1f, 1); 1488 1489 if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1) { 1490 soc_format_field32_set(unit, 1491 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1492 alu_fmt, TIMESTAMP_0_TRIGf, 1); 1493 } 1494 1495 if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2) { 1496 soc_format_field32_set(unit, 1497 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1498 alu_fmt, TIMESTAMP_1_TRIGf, 1); 1499 } 1500 1501 } 1502 1503 /* Set all the bit selects to check 0 and set KMAP accordingly.*/ 1504 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1505 alu_fmt, CHECK_LOGIC_BIT_SELECT_0f, (opr1 == -1) ? 1 : 0); 1506 1507 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1508 alu_fmt, CHECK_LOGIC_BIT_SELECT_1f, (opr2 == -1) ? 0 : 1); 1509 1510 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1511 alu_fmt, CHECK_LOGIC_BIT_SELECT_2f, (opr1 == -1) ? 1 : 0); 1512 1513 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1514 alu_fmt, CHECK_LOGIC_BIT_SELECT_3f, (opr1 == -1) ? 1 : 0); 1515 1516 /* Set ALU actions. */ 1517 alu_action = fc_info.action_info.action; 1518 1519 if (fc_info.action_info.action == bcmFlowtrackerCheckActionUpdateValue) { 1520 if (alu_info->action_key.length > 16) { 1521 /* Update cant support more than 16 length.*/ 1522 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 1523 "Action Element len (%d) is more than supported length 16 \n"), 1524 alu_info->action_key.length)); 1525 1526 return BCM_E_PARAM; 1527 } 1528 } 1529 1530 clear_on_export = ((fc_info.check1.flags & 1531 BCM_FLOWTRACKER_CHECK_DATA_CLEAR_ON_EXPORT) ? 1 : 0); 1532 1533 export_check_mode = ((fc_info.check1.flags & 1534 BCM_FLOWTRACKER_CHECK_EXPORT_MODE_THRESHOLD) ? 0 : 1); 1535 1536 } else { 1537 if ((alu_info->element_type1 <= bcmFlowtrackerTrackingParamTypeSrcIPv4) 1538 || (alu_info->element_type1 >= 1539 bcmFlowtrackerTrackingParamTypeCount)) { 1540 return BCM_E_PARAM; 1541 } 1542 /* if it is not flowchecker then only one element in alu. */ 1543 rv = bcmi_ft_element_alu_action_get 1544 (alu_info->element_type1, &alu_action); 1545 1546 if (BCM_FAILURE(rv)) { 1547 return rv; 1548 } 1549 /* We can associate two flowcheckers together so that we can have . */ 1550 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1551 alu_fmt, CHECK_0_ATTR_SELECTf, actual_location); 1552 1553 if (alu_info->key1.length <= 16) { 1554 soc_format_field32_set(unit, 1555 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1556 alu_fmt, UPDATE_ATTR_SELECTf, actual_location); 1557 } 1558 1559 /* Make Check 0 operation as always pass. */ 1560 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1561 alu_fmt, CHECK_0_OPERATIONf, 0x6); 1562 1563 /* Make Check 0 operation as always pass. */ 1564 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1565 alu_fmt, CHECK_1_OPERATIONf, 0x6); 1566 1567 /* Set all the bit selects to check 0 and set KMAP accordingly.*/ 1568 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1569 alu_fmt, CHECK_LOGIC_BIT_SELECT_0f, 0); 1570 1571 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1572 alu_fmt, CHECK_LOGIC_BIT_SELECT_1f, 0); 1573 1574 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1575 alu_fmt, CHECK_LOGIC_BIT_SELECT_2f, 0); 1576 1577 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1578 alu_fmt, CHECK_LOGIC_BIT_SELECT_3f, 0); 1579 1580 } 1581 1582 BCM_IF_ERROR_RETURN(bcmi_ft_kmap_val_get(unit, &fc_info, opr, &kmap_val)); 1583 1584 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1585 alu_fmt, FLEX_CHECK_LOGIC_KMAP_CONTROLf, kmap_val); 1586 1587 /* Now get the information about update operations. */ 1588 BCM_IF_ERROR_RETURN(bcmi_ft_alu_hw_action_get(unit, element, 1589 alu_action, &hw_action)); 1590 1591 /* Update operation with the action element. */ 1592 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1593 alu_fmt, UPDATE_ATTR_SELECTf, update_location); 1594 1595 /* Update operation with the action element. */ 1596 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1597 alu_fmt, UPDATE_OPERATIONf, hw_action); 1598 1599 1600 /* Do equal average for incoming and runnung values for now. 1601 * Encodings are: 1602 * 0 => 100% 1 => 96% 2 => 92% 3 => 88% 4 => 86% 5 => 84% 1603 * 6 => 81% 7 => 78% 8 => 75% 9 => 71%10 => 67% 11 => 63% 1604 * 12 => 59% 13 => 56% 14 => 53% 15 => 50% 16 => 47% 1605 * 17 => 44% 18 => 41% 19 => 37% 20 => 33% 1606 * 21 => 29% 22 => 25% 23 => 22% 24 => 19% 25 => 16% 26 => 14% 1607 * 27 => 12% 28 => 8% 29 => 4% 30 => 0% 31 => Reserved 1608 */ 1609 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1610 alu_fmt, UPDATE_OP_PARAMf, 0xf); 1611 1612 /* Set the load trigger for forward and reverse. */ 1613 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1614 alu_fmt, LOAD_TRIGGERf, BCMI_FT_GROUP_FTFP_DATA(unit, id).direction); 1615 1616 1617 /* Clear the data after export based on user input. */ 1618 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1619 alu_fmt, CLEAR_ON_EXPORT_ENABLEf, clear_on_export); 1620 1621 /* Export data if there is new change in existing session data. */ 1622 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1623 alu_fmt, EXPORT_CHECK_MODEf, export_check_mode); 1624 1625 /* Set export operation. */ 1626 rv = bcmi_ft_alu_hw_operation_get 1627 (unit, fc_info.export_info.operation, &check_0_opr, &check_1_opr); 1628 1629 1630 if (BCM_FAILURE(rv)) { 1631 return rv; 1632 } 1633 1634 if (check_0_opr != -1) { 1635 soc_format_field32_set(unit, 1636 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1637 alu_fmt, EXPORT_OPERATIONf, check_0_opr); 1638 } else { 1639 soc_format_field32_set(unit, 1640 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 1641 alu_fmt, EXPORT_OPERATIONf, check_1_opr); 1642 } 1643 1644 return BCM_E_NONE; 1645 } 1646 1647 /* 1648 * Function: 1649 * bcmi_ft_alu32_entry_install 1650 * Purpose: 1651 * Configure ALU32 entry in hardware 1652 * Parameters: 1653 * unit - (IN) BCM device id 1654 * id - (IN) FT group id. 1655 * info - (IN) ALU information of group. 1656 * 1657 * Returns: 1658 * BCM_E_XXX 1659 */ 1660 int 1661 bcmi_ft_alu32_entry_install( 1662 int unit, 1663 bcm_flowtracker_group_t id, 1664 bcmi_ft_group_alu_info_t *info, 1665 int *load_indexes) 1666 { 1667 1668 1669 bcmi_flowtracker_flowchecker_info_t fc_info; 1670 int rv = BCM_E_NONE; 1671 int new_index = -1; 1672 soc_mem_t mem = -1; 1673 int index = -1; 1674 int a_idx = -1; /* Array index of field/memory array. */ 1675 bcmi_ft_alu_load_type_t alu_load_type = bcmiFtAluLoadTypeAlu32; 1676 bsc_dg_group_table_entry_t dg_entry; 1677 uint32 alu_base_ctrlfmt[3]; 1678 uint32 alu32_specific_ctrlfmt[4]; 1679 uint32 alu32_ctrlfmt[7]; 1680 bsc_dg_group_alu32_profile_0_entry_t alu32_entry; 1681 int shift_bits = 0, shift_bits2 = 0; 1682 int min_value = 0, max_value = 0, threshold = 0; 1683 int val1, val2, opr1, opr2; 1684 1685 sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32)); 1686 sal_memset(alu32_specific_ctrlfmt, 0, 4*sizeof(uint32)); 1687 sal_memset(alu32_ctrlfmt, 0, 7*sizeof(uint32)); 1688 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1689 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 1690 1691 val1 = val2 = opr1 = opr2 = -1; 1692 1693 /* First insert the hash entry. info carries single alu information */ 1694 rv = bcmi_ft_alu_hash_insert 1695 (unit, id, bcmiFtAluLoadTypeAlu32, info, NULL, &index); 1696 1697 if (BCM_FAILURE(rv)) { 1698 if (rv == BCM_E_EXISTS) { 1699 bcmi_ft_alu_load_mem_index_get 1700 (unit, index, alu_load_type, &new_index, &mem, &a_idx); 1701 1702 /* Now that BCM_E_EXISTS is handled. please change rv. */ 1703 rv = BCM_E_NONE; 1704 } else { 1705 return rv; 1706 } 1707 } else { 1708 1709 /* Index is obtained, convert the index into the memory type. */ 1710 bcmi_ft_alu_load_mem_index_get 1711 (unit, index, alu_load_type, &new_index, &mem, &a_idx); 1712 1713 /* Set the software entries. */ 1714 rv = bcmi_ft_flowchecker_alu_base_control_set(unit, id, info, 1715 alu_base_ctrlfmt); 1716 1717 BCMI_CLEANUP_IF_ERROR(rv); 1718 1719 soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt, 1720 alu32_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt); 1721 1722 if (info->flowchecker_id > 0) { 1723 /* 1724 * The update for an element can still be done 1725 * without performing any check. 1726 * For example a template can just tell which 1727 * element need to be updated. 1728 * Therefore other than check elements, all other 1729 * flow checker elements should be updated even 1730 * without a flowchecker id. 1731 */ 1732 rv = bcmi_ft_flowchecker_get 1733 (unit, info->flowchecker_id, &fc_info); 1734 BCMI_CLEANUP_IF_ERROR(rv); 1735 1736 1737 if ((info->key1.location % 16) != 0) { 1738 shift_bits = (info->key1.location % 16); 1739 } 1740 1741 if (info->element_type2) { 1742 if ((info->key2.location % 16) != 0) { 1743 shift_bits2 = (info->key1.location % 16); 1744 } 1745 } else { 1746 shift_bits2 = shift_bits; 1747 } 1748 1749 bcmi_ft_flowchecker_values_get(unit, &fc_info, &val1, &val2, 1750 &opr1, &opr2); 1751 1752 if (opr1 != -1) { 1753 min_value = (val1 << shift_bits); 1754 1755 soc_format_field32_set(unit, 1756 BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt, 1757 alu32_specific_ctrlfmt, CHECK_0_THRESHOLDf, 1758 min_value); 1759 1760 if (info->key1.length > 16) { 1761 soc_format_field32_set(unit, 1762 BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt, 1763 alu32_specific_ctrlfmt, CHECK_0_ATTR_SELECT_GRANf, 1); 1764 } 1765 1766 } 1767 1768 if (opr2 != -1) { 1769 max_value = (val2 << shift_bits2); 1770 1771 soc_format_field32_set(unit, 1772 BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt, 1773 alu32_specific_ctrlfmt, CHECK_1_THRESHOLDf, 1774 max_value); 1775 1776 if (info->key1.length > 16) { 1777 soc_format_field32_set(unit, 1778 BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt, 1779 alu32_specific_ctrlfmt, CHECK_1_ATTR_SELECT_GRANf, 1); 1780 } 1781 1782 } 1783 1784 if (fc_info.export_info.export_check_threshold > 0) { 1785 1786 shift_bits2 = 0; 1787 bcmi_ft_check_action_shift_bits_get(unit, 1788 fc_info.action_info.action, info, &shift_bits2); 1789 1790 threshold = fc_info.export_info.export_check_threshold << shift_bits2; 1791 1792 soc_format_field32_set(unit, 1793 BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt, 1794 alu32_specific_ctrlfmt, EXPORT_THRESHOLDf, 1795 threshold); 1796 } 1797 } 1798 soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt, 1799 alu32_ctrlfmt, ALU32_SPECIFIC_CONTROL_BUSf, alu32_specific_ctrlfmt); 1800 1801 soc_mem_field_set(unit, mem, (uint32 *)&alu32_entry, DATAf, 1802 alu32_ctrlfmt); 1803 1804 /* The profile is set. Write into the index of group. */ 1805 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu32_entry); 1806 BCMI_CLEANUP_IF_ERROR(rv); 1807 } 1808 1809 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1810 (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"), 1811 index, alu_type_str[bcmiFtAluLoadTypeAlu32])); 1812 1813 if (BCM_SUCCESS(rv) && (index != -1)) { 1814 /* Assign the bitmap to this index. */ 1815 SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu32)), 1816 index); 1817 1818 /* Also increment the ref count on this index. */ 1819 BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeAlu32, index); 1820 1821 /* Set the groups IN use ALU memories. */ 1822 (BCMI_FT_GROUP_ALU32_MEM_USE(unit, id))[a_idx] = 1; 1823 1824 /* Update chip debug memory also if aplicable. */ 1825 bcmi_ft_chip_debug_use_mem_update(unit, 1826 bcmiFtAluLoadTypeAlu32, a_idx, 1); 1827 1828 /* Set pdd profile entry for this alu entry. */ 1829 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 1830 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1831 (BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu32)[a_idx]).param_id, 1); 1832 1833 1834 rv = soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 1835 MEM_BLOCK_ANY, id, &dg_entry); 1836 BCMI_CLEANUP1_IF_ERROR(rv); 1837 1838 1839 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry, 1840 bcmi_dg_group_alu32_fid[a_idx], new_index); 1841 1842 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ALL, 1843 id, &dg_entry); 1844 } 1845 1846 if (BCM_SUCCESS(rv)) { 1847 return rv; 1848 } 1849 1850 cleanup1: 1851 if (index != -1) { 1852 /* Also decrement the ref count on this index. */ 1853 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu32, index); 1854 1855 if (!(BCMI_FT_ALU_LOAD_REFCOUNT 1856 (unit, bcmiFtAluLoadTypeAlu32, index))) { 1857 1858 /* Clear the bitmap to this index. */ 1859 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu32)), 1860 index); 1861 } 1862 } 1863 1864 cleanup: 1865 /* remove the previously added hash table entry. */ 1866 bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu32, 1867 info, NULL, &index); 1868 1869 return rv; 1870 } 1871 1872 /* 1873 * Function: 1874 * bcmi_ft_alu16_entry_install 1875 * Purpose: 1876 * Configure ALU16 entry in hardware 1877 * Parameters: 1878 * unit - (IN) BCM device id 1879 * id - (IN) FT group id. 1880 * info - (IN) ALU information of group. 1881 * 1882 * Returns: 1883 * BCM_E_XXX 1884 */ 1885 int 1886 bcmi_ft_alu16_entry_install( 1887 int unit, 1888 bcm_flowtracker_group_t id, 1889 bcmi_ft_group_alu_info_t *info, 1890 int *load16_indexes) 1891 { 1892 1893 bcmi_flowtracker_flowchecker_info_t fc_info; 1894 int new_index = -1; 1895 soc_mem_t mem = -1; 1896 int index = -1; 1897 int rv = BCM_E_NONE; 1898 int a_idx = 0; 1899 int fid_len = 0, fid_value = 0; 1900 uint32 alu_base_ctrlfmt[3]; 1901 uint32 alu16_specific_ctrlfmt[3]; 1902 uint32 alu16_ctrlfmt[6]; 1903 bsc_dg_group_alu16_profile_0_entry_t alu16_entry; 1904 bsc_dg_group_table_entry_t dg_entry; 1905 int min_value = 0, max_value = 0, threshold = 0; 1906 int shift_bits = 0, shift_bits2 = 0; 1907 int val1, val2, opr1, opr2; 1908 1909 sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32)); 1910 sal_memset(alu16_specific_ctrlfmt, 0, 3*sizeof(uint32)); 1911 sal_memset(alu16_ctrlfmt, 0, 6*sizeof(uint32)); 1912 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1913 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 1914 1915 1916 val1 = val2 = opr1 = opr2 = -1; 1917 /* First insert the hash entry. */ 1918 rv = bcmi_ft_alu_hash_insert(unit, id, bcmiFtAluLoadTypeAlu16, info, NULL, 1919 &index); 1920 1921 if (BCM_FAILURE(rv)) { 1922 if (rv == BCM_E_EXISTS) { 1923 bcmi_ft_alu_load_mem_index_get 1924 (unit, index, bcmiFtAluLoadTypeAlu16, &new_index, &mem, &a_idx); 1925 1926 /* Now that BCM_E_EXISTS is handled. please change rv. */ 1927 rv = BCM_E_NONE; 1928 1929 } else { 1930 return rv; 1931 } 1932 } else { 1933 1934 /* Index is obtained, convert the index into the memory type. */ 1935 bcmi_ft_alu_load_mem_index_get 1936 (unit, index, bcmiFtAluLoadTypeAlu16, &new_index, &mem, &a_idx); 1937 1938 rv = bcmi_ft_flowchecker_alu_base_control_set(unit, id, info, 1939 alu_base_ctrlfmt); 1940 1941 BCMI_CLEANUP_IF_ERROR(rv); 1942 1943 soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt, 1944 alu16_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt); 1945 1946 if (info->flowchecker_id > 0) { 1947 /* 1948 * The update for an element can still be done 1949 * without performing any check. 1950 * For example a template can just tell which 1951 * element need to be updated. 1952 * Therefore other than check elements, all other 1953 * flow checker elements should be updated even 1954 * without a flowchecker id. 1955 */ 1956 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 1957 (unit, info->flowchecker_id, &fc_info)); 1958 1959 if ((info->key1.location % 16) != 0) { 1960 shift_bits = (info->key1.location % 16); 1961 } 1962 1963 if (info->element_type2) { 1964 if ((info->key2.location % 16) != 0) { 1965 shift_bits2 = (info->key1.location % 16); 1966 } 1967 } else { 1968 shift_bits2 = shift_bits; 1969 } 1970 1971 bcmi_ft_flowchecker_values_get(unit, &fc_info, &val1, &val2, 1972 &opr1, &opr2); 1973 1974 if (opr1 != -1) { 1975 min_value = (val1 << shift_bits); 1976 1977 fid_len = soc_format_field_length(unit, 1978 BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt, 1979 CHECK_0_THRESHOLDf); 1980 1981 fid_value = ((1 << fid_len) -1) ; 1982 1983 if ((min_value < 0) || (min_value > fid_value)) { 1984 return BCM_E_PARAM; 1985 } 1986 1987 soc_format_field32_set(unit, 1988 BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt, 1989 alu16_specific_ctrlfmt, CHECK_0_THRESHOLDf, 1990 min_value); 1991 1992 } 1993 1994 if (opr2 != -1) { 1995 max_value = (val2 << shift_bits2); 1996 1997 fid_len = soc_format_field_length(unit, 1998 BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt, 1999 CHECK_0_THRESHOLDf); 2000 2001 fid_value = ((1 << fid_len) -1) ; 2002 2003 if ((max_value < 0) || (max_value > fid_value)) { 2004 rv = BCM_E_PARAM; 2005 goto cleanup; 2006 } 2007 2008 soc_format_field32_set(unit, 2009 BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt, 2010 alu16_specific_ctrlfmt, CHECK_1_THRESHOLDf, 2011 max_value); 2012 2013 } 2014 2015 2016 if (fc_info.export_info.export_check_threshold > 0) { 2017 2018 shift_bits2 = 0; 2019 bcmi_ft_check_action_shift_bits_get(unit, 2020 fc_info.action_info.action, info, &shift_bits2); 2021 2022 threshold = fc_info.export_info.export_check_threshold << shift_bits2; 2023 2024 fid_len = soc_format_field_length(unit, 2025 BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt, 2026 EXPORT_THRESHOLDf); 2027 2028 fid_value = ((1 << fid_len) -1) ; 2029 2030 if ((threshold < 0) || (threshold > fid_value)) { 2031 rv = BCM_E_PARAM; 2032 goto cleanup; 2033 } 2034 2035 soc_format_field32_set(unit, 2036 BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt, 2037 alu16_specific_ctrlfmt, EXPORT_THRESHOLDf, 2038 threshold); 2039 } 2040 2041 } 2042 2043 soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt, 2044 alu16_ctrlfmt, ALU16_SPECIFIC_CONTROL_BUSf, alu16_specific_ctrlfmt); 2045 2046 soc_mem_field_set(unit, mem, ((uint32 *) &alu16_entry), DATAf, 2047 alu16_ctrlfmt); 2048 2049 /* The profile is set and now we need to write into the index of group. */ 2050 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu16_entry); 2051 BCMI_CLEANUP_IF_ERROR(rv); 2052 2053 } 2054 2055 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 2056 (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"), 2057 index, alu_type_str[bcmiFtAluLoadTypeAlu16])); 2058 2059 if ((index != -1)) { 2060 /* Assign the bitmap to this index. */ 2061 SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu16)), 2062 index); 2063 2064 /* Also increment the ref count on this index. */ 2065 BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeAlu16, index); 2066 2067 /* Set the groups IN use ALU memories. */ 2068 (BCMI_FT_GROUP_ALU16_MEM_USE(unit, id))[a_idx] = 1; 2069 2070 /* Update chip debug memory also if aplicable. */ 2071 bcmi_ft_chip_debug_use_mem_update(unit, 2072 bcmiFtAluLoadTypeAlu16, a_idx, 1); 2073 2074 /* Set pdd profile entry for this alu entry. */ 2075 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 2076 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 2077 (BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu16)[a_idx]).param_id, 1); 2078 2079 rv = soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 2080 MEM_BLOCK_ANY, id, &dg_entry); 2081 2082 BCMI_CLEANUP1_IF_ERROR(rv); 2083 2084 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry, 2085 bcmi_dg_group_alu16_fid[a_idx], new_index); 2086 2087 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ALL, 2088 id, &dg_entry); 2089 } 2090 2091 if (BCM_SUCCESS(rv)) { 2092 return rv; 2093 } 2094 2095 cleanup1: 2096 if (index != -1) { 2097 /* Also decrement the ref count on this index. */ 2098 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu16, index); 2099 2100 if (!(BCMI_FT_ALU_LOAD_REFCOUNT 2101 (unit, bcmiFtAluLoadTypeAlu16, index))) { 2102 2103 /* Clear the bitmap to this index. */ 2104 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu16)), 2105 index); 2106 } 2107 } 2108 2109 cleanup: 2110 /* remove the previously added hash table entry. */ 2111 bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu16, 2112 info, NULL, &index); 2113 2114 2115 return rv; 2116 } 2117 2118 /* 2119 * Function: 2120 * bcmi_ft_alu32_entry_uninstall 2121 * Purpose: 2122 * clear ALU32 entry in hardware 2123 * Parameters: 2124 * unit - (IN) BCM device id 2125 * id - (IN) FT group id. 2126 * info - (IN) ALU information of group. 2127 * type - (IN) ALU/LOAD type. 2128 * 2129 * Returns: 2130 * BCM_E_XXX 2131 */ 2132 int 2133 bcmi_ft_alu32_entry_uninstall( 2134 int unit, 2135 bcm_flowtracker_group_t id, 2136 bcmi_ft_group_alu_info_t *info, 2137 int *indexes) 2138 { 2139 2140 int rv = BCM_E_NONE; 2141 int new_index = -1; 2142 int index = -1; 2143 soc_mem_t mem = -1; 2144 int bit = 0; 2145 bsc_dg_group_alu32_profile_0_entry_t alu32_entry; 2146 2147 if (!info->alu_load_index && !info->alu_load_type) { 2148 /* This entry is yet to be installed, so nothing to uninstall. */ 2149 return BCM_E_NONE; 2150 } 2151 2152 index = info->alu_load_index; 2153 2154 /* Decrement the ref count on this index. */ 2155 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu32, index); 2156 2157 /* First conver the index into the memory type. */ 2158 bcmi_ft_alu_load_mem_index_get(unit, index, bcmiFtAluLoadTypeAlu32, 2159 &new_index, &mem, &bit); 2160 2161 if (!(BCMI_FT_ALU_LOAD_REFCOUNT(unit, bcmiFtAluLoadTypeAlu32, index))) { 2162 2163 sal_memset(&alu32_entry, 0, sizeof(bsc_dg_group_alu32_profile_0_entry_t)); 2164 2165 /* The profile is set and now we need to write into the index of group. */ 2166 BCM_IF_ERROR_RETURN( 2167 soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu32_entry)); 2168 2169 2170 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu32)), 2171 index); 2172 2173 /* We already found the entry above so this should always pass. */ 2174 BCM_IF_ERROR_RETURN( 2175 bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu32, 2176 info, NULL, &index)); 2177 } 2178 2179 /* Remove this memory from group. */ 2180 soc_mem_field32_modify(unit, BSC_DG_GROUP_TABLEm, id, 2181 bcmi_dg_group_alu32_fid[bit], 0); 2182 2183 /* Set the groups IN use ALU memories. */ 2184 (BCMI_FT_GROUP_ALU32_MEM_USE(unit, id))[bit] = 0; 2185 2186 /* Update chip debug memory also if aplicable. */ 2187 bcmi_ft_chip_debug_use_mem_update(unit, 2188 bcmiFtAluLoadTypeAlu32, bit, -1); 2189 2190 return rv; 2191 } 2192 2193 /* 2194 * Function: 2195 * bcmi_ft_alu16_entry_uninstall 2196 * Purpose: 2197 * clear ALU16 entry in hardware 2198 * Parameters: 2199 * unit - (IN) BCM device id 2200 * id - (IN) FT group id. 2201 * info - (IN) ALU information of group. 2202 * type - (IN) ALU/LOAD type. 2203 * 2204 * Returns: 2205 * BCM_E_XXX 2206 */ 2207 int 2208 bcmi_ft_alu16_entry_uninstall( 2209 int unit, 2210 bcm_flowtracker_group_t id, 2211 bcmi_ft_group_alu_info_t *info, 2212 int *indexes) 2213 { 2214 int rv = BCM_E_NONE; 2215 int new_index = -1; 2216 int index = -1; 2217 soc_mem_t mem = -1; 2218 int bit = 0; 2219 bsc_dg_group_alu16_profile_0_entry_t alu16_entry; 2220 2221 /* Here we just need to add into the sw list. */ 2222 /* start writing the information into hardware now. */ 2223 if (!info->alu_load_index && !info->alu_load_type) { 2224 /* This entry is yet to be installed, so nothing to uninstall. */ 2225 return BCM_E_NONE; 2226 } 2227 2228 index = info->alu_load_index; 2229 2230 /* Decrement the ref count on this index. */ 2231 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu16, index); 2232 2233 /* First conver the index into the memory type. */ 2234 bcmi_ft_alu_load_mem_index_get(unit, index, bcmiFtAluLoadTypeAlu16, 2235 &new_index, &mem, &bit); 2236 2237 if (!(BCMI_FT_ALU_LOAD_REFCOUNT(unit, bcmiFtAluLoadTypeAlu16, index))) { 2238 2239 sal_memset(&alu16_entry, 0, sizeof(bsc_dg_group_alu16_profile_0_entry_t)); 2240 2241 /* The profile is set and now we need to write into the index of group. */ 2242 BCM_IF_ERROR_RETURN( 2243 soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu16_entry)); 2244 2245 2246 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu16)), 2247 index); 2248 2249 /* We already found the entry above so this should always pass. */ 2250 BCM_IF_ERROR_RETURN( 2251 bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu16, 2252 info, NULL, &index)); 2253 } 2254 2255 /* Remove this memory from group. */ 2256 soc_mem_field32_modify(unit, BSC_DG_GROUP_TABLEm, id, 2257 bcmi_dg_group_alu16_fid[bit], 0); 2258 2259 /* Set the groups IN use ALU memories. */ 2260 (BCMI_FT_GROUP_ALU16_MEM_USE(unit, id))[bit] = 0; 2261 2262 /* Update chip debug memory also if aplicable. */ 2263 bcmi_ft_chip_debug_use_mem_update(unit, 2264 bcmiFtAluLoadTypeAlu16, bit, -1); 2265 2266 return rv; 2267 } 2268 2269 /*|************************************************************| 2270 |******** ALU Hardware Install Methods. ********| 2271 |************************************************************| 2272 |******* End ********| 2273 |************************************************************|*/ 2274 2275 2276 /****************************************************** 2277 | LOAD16 Space | 2278 */ 2279 /* 2280 * Function: 2281 * bcmi_ft_load16_entry_match 2282 * Purpose: 2283 * Match Load 16 entry in hardware 2284 * Parameters: 2285 * unit - (IN) BCM device id 2286 * id - (IN) FT group id. 2287 * info - (IN) ALU/Load information of group. 2288 * load16_indexes - (IN) Load 16 indexes in group 2289 * index - (OUT) sw index. 2290 * 2291 * Returns: 2292 * BCM_E_XXX 2293 */ 2294 int 2295 bcmi_ft_load16_entry_match( 2296 int unit, 2297 bcm_flowtracker_group_t id, 2298 bcmi_ft_group_alu_info_t *info, 2299 bcmi_ft_alu_hash_info_t *alu_info, 2300 int *load16_indexes, int *index) 2301 { 2302 2303 bcmi_ft_group_alu_info_t *local = NULL; 2304 uint32 load16_ctrlfmt[1]; 2305 bsc_dg_group_load16_profile_entry_t load16_entry; 2306 uint32 location = 0, trigger = 0; 2307 int i=0, j=0; 2308 int max = 0; 2309 int match_found = 0; 2310 2311 int data[TOTAL_GROUP_LOAD16_DATA_NUM] = 2312 {DATA_15f, 2313 DATA_14f, 2314 DATA_13f, 2315 DATA_12f, 2316 DATA_11f, 2317 DATA_10f, 2318 DATA_9f, 2319 DATA_8f, 2320 DATA_7f, 2321 DATA_6f, 2322 DATA_5f, 2323 DATA_4f, 2324 DATA_3f, 2325 DATA_2f, 2326 DATA_1f, 2327 DATA_0f}; 2328 2329 sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t)); 2330 sal_memset(load16_ctrlfmt, 0, sizeof(uint32)); 2331 2332 /* Set the max for whole table if whole table is to be checked. */ 2333 max = soc_mem_index_max(unit, BSC_DG_GROUP_LOAD16_PROFILEm); 2334 2335 /* If an index is provided then match only that index. */ 2336 if (*index != -1) { 2337 max = *index; 2338 i = *index; 2339 } 2340 2341 for (; i<=max; i++) { 2342 /* Check for the bitmap first if the entry is in use.*/ 2343 2344 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 2345 MEM_BLOCK_ANY, i, &load16_entry)); 2346 2347 for (; j<TOTAL_GROUP_LOAD16_DATA_NUM; j++) { 2348 2349 soc_mem_field_get(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 2350 (uint32 *) &load16_entry, data[j], load16_ctrlfmt); 2351 2352 trigger = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt, 2353 load16_ctrlfmt, LOAD_TRIGGERf); 2354 2355 if (load16_indexes[j] != -1) { 2356 if (!trigger) { 2357 /* 2358 * If trigger is not set but still 2359 * there is some info at that index 2360 * then this will not match this load entry. 2361 */ 2362 match_found = 0; 2363 break; 2364 } else if (trigger != 2365 BCMI_FT_GROUP_FTFP_DATA(unit, id).direction) { 2366 /* 2367 * If trigger is set but not matching 2368 * to the group direction then also no match. 2369 */ 2370 match_found = 0; 2371 break; 2372 } 2373 } else { 2374 if (trigger) { 2375 /* 2376 * If trigger is set but still 2377 * there is no info at that index 2378 * then this will not match this load entry. 2379 */ 2380 match_found = 0; 2381 } 2382 /* if trigger is also not set, then this could be match 2383 * based on the previous match result. just breack from here. 2384 */ 2385 break; 2386 } 2387 2388 local = (&(info[load16_indexes[j]])); 2389 location = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt, 2390 load16_ctrlfmt, ATTR_SELECTf); 2391 2392 if (location != (local->key1.location/16)) { 2393 /* 2394 * If entry does not match then return. 2395 * by setting that this is not a match. 2396 */ 2397 match_found = 0; 2398 break; 2399 } 2400 /* If we have reached here then that is a match for now. */ 2401 match_found = 1; 2402 } 2403 if (match_found) { 2404 break; 2405 } 2406 } 2407 2408 if (match_found) { 2409 *index = i; 2410 return BCM_E_NONE; 2411 } 2412 2413 return BCM_E_NOT_FOUND; 2414 } 2415 2416 /* 2417 * Function: 2418 * bcmi_ft_load16_entry_write 2419 * Purpose: 2420 * Write Load 16 entry in hardware 2421 * Parameters: 2422 * unit - (IN) BCM device id 2423 * id - (IN) FT group id. 2424 * info - (IN) ALU/Load information of group. 2425 * load16_indexes - (IN) Load 16 indexes in group 2426 * index - (IN) sw index. 2427 * 2428 * Returns: 2429 * BCM_E_XXX 2430 */ 2431 int 2432 bcmi_ft_load16_entry_write( 2433 int unit, 2434 bcm_flowtracker_group_t id, 2435 bcmi_ft_group_alu_info_t *info, 2436 int *load16_indexes, int index) 2437 { 2438 2439 bcmi_ft_group_alu_info_t *local = NULL; 2440 uint32 load16_ctrlfmt[1]; 2441 bsc_dg_group_load16_profile_entry_t load16_entry; 2442 uint32 location = 0; 2443 int j=0; 2444 int rv = BCM_E_NONE; 2445 2446 int data[TOTAL_GROUP_LOAD16_DATA_NUM] = 2447 {DATA_15f, 2448 DATA_14f, 2449 DATA_13f, 2450 DATA_12f, 2451 DATA_11f, 2452 DATA_10f, 2453 DATA_9f, 2454 DATA_8f, 2455 DATA_7f, 2456 DATA_6f, 2457 DATA_5f, 2458 DATA_4f, 2459 DATA_3f, 2460 DATA_2f, 2461 DATA_1f, 2462 DATA_0f}; 2463 2464 sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t)); 2465 sal_memset(load16_ctrlfmt, 0, sizeof(uint32)); 2466 2467 for (; j<TOTAL_GROUP_LOAD16_DATA_NUM; j++) { 2468 /* Now based on the incoming info, match the entries. */ 2469 if (load16_indexes[j] == -1) { 2470 break; 2471 } 2472 2473 local = (&(info[load16_indexes[j]])); 2474 2475 /* Update the load trigger based on groups direction configuration. */ 2476 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt, 2477 load16_ctrlfmt, LOAD_TRIGGERf, 2478 BCMI_FT_GROUP_FTFP_DATA(unit, id).direction); 2479 2480 location = local->key1.location; 2481 2482 /* 2483 * ftfp is sending location in continuous index of 256B. 2484 * Each extractor here is 16 bytes so long, so 2485 * need to divide it by 16 to get correct location. 2486 */ 2487 location = (location / 16); 2488 2489 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt, 2490 load16_ctrlfmt, ATTR_SELECTf, location); 2491 2492 /* Write into that entry. */ 2493 soc_mem_field_set(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 2494 (uint32 *) &load16_entry, 2495 data[j], load16_ctrlfmt); 2496 } 2497 2498 rv = soc_mem_write(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 2499 MEM_BLOCK_ANY, index, &load16_entry); 2500 2501 return rv; 2502 } 2503 2504 /* 2505 * Function: 2506 * bcmi_ft_load16_entry_install 2507 * Purpose: 2508 * Install Load 16 entry in hardware 2509 * Parameters: 2510 * unit - (IN) BCM device id 2511 * id - (IN) FT group id. 2512 * indexes - (IN) Load 16 indexes in group 2513 * 2514 * Returns: 2515 * BCM_E_XXX 2516 */ 2517 int 2518 bcmi_ft_load16_entry_install( 2519 int unit, 2520 bcm_flowtracker_group_t id, 2521 bcmi_ft_group_alu_info_t *info, 2522 int *indexes) 2523 { 2524 bcmi_ft_group_alu_info_t *temp = NULL, *local = NULL; 2525 bsc_dg_group_table_entry_t dg_entry; 2526 int rv = BCM_E_NONE; 2527 int j, index = -1; 2528 2529 if (indexes[0] == -1) { 2530 /* There is no load 16 entry. */ 2531 return BCM_E_NONE; 2532 } 2533 2534 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 2535 2536 /* assign the ALU memory chunk to local pointer. */ 2537 temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 2538 2539 rv = bcmi_ft_alu_hash_insert(unit, id, bcmiFtAluLoadTypeLoad16, 2540 temp, indexes, &index); 2541 2542 if (BCM_FAILURE(rv)) { 2543 if (rv == BCM_E_EXISTS) { 2544 /* Increment ref count and set up group table. */ 2545 BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad16, 2546 index); 2547 rv = BCM_E_NONE; 2548 } else { 2549 return rv; 2550 } 2551 } else { 2552 /* Now that we have got the index, now write into that index. */ 2553 rv = bcmi_ft_load16_entry_write(unit, id, temp, indexes, index); 2554 2555 BCMI_CLEANUP_IF_ERROR(rv); 2556 2557 if (index != -1) { 2558 /* Assign the bitmap to this index. */ 2559 SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad16)), 2560 index); 2561 2562 /* Also increment the ref count on this index. */ 2563 BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad16, 2564 index); 2565 2566 } 2567 } 2568 2569 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 2570 (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"), 2571 index, alu_type_str[bcmiFtAluLoadTypeLoad16])); 2572 2573 rv = bcmi_ft_load_pdd_entry_set 2574 (unit, id, bcmiFtAluLoadTypeLoad16, index, 0); 2575 2576 BCMI_CLEANUP1_IF_ERROR(rv); 2577 2578 /* First read the group entry. */ 2579 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 2580 MEM_BLOCK_ANY, id, &dg_entry)); 2581 2582 /* now write this index into the group. */ 2583 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, 2584 ((uint32 *)&dg_entry), GROUP_LOAD16_PROFILE_IDXf, index); 2585 2586 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, 2587 &dg_entry); 2588 BCMI_CLEANUP1_IF_ERROR(rv); 2589 2590 /* Update type and index into all the data elements. */ 2591 for (j=0; j<TOTAL_GROUP_LOAD16_DATA_NUM; j++) { 2592 /* Now based on the incoming info, match the entries. */ 2593 if (indexes[j] == -1) { 2594 break; 2595 } 2596 2597 local = (&(temp[indexes[j]])); 2598 local->alu_load_index = index; 2599 local->alu_load_type = bcmiFtAluLoadTypeLoad16; 2600 } 2601 2602 return BCM_E_NONE; 2603 2604 cleanup1: 2605 if (index != -1) { 2606 /* Also decrement the ref count on this index. */ 2607 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad16, index); 2608 2609 if (!(BCMI_FT_ALU_LOAD_REFCOUNT 2610 (unit, bcmiFtAluLoadTypeLoad16, index))) { 2611 2612 /* Clear the bitmap to this index. */ 2613 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad16)), 2614 index); 2615 } 2616 2617 bcmi_ft_load_pdd_entry_set(unit, id, bcmiFtAluLoadTypeLoad16, index, 1); 2618 } 2619 2620 cleanup: 2621 /* remove the previously added hash table entry. */ 2622 bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad16, 2623 info, NULL, &index); 2624 2625 return rv; 2626 } 2627 2628 /* 2629 * Function: 2630 * bcmi_ft_load16_entry_clear 2631 * Purpose: 2632 * Clear Load 16 entry in hardware 2633 * Parameters: 2634 * unit - (IN) BCM device id 2635 * index - (IN) Load 16 index 2636 * 2637 * Returns: 2638 * BCM_E_XXX 2639 */ 2640 int 2641 bcmi_ft_load16_entry_clear(int unit, int index) 2642 { 2643 2644 bsc_dg_group_load16_profile_entry_t load16_entry; 2645 2646 sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t)); 2647 2648 BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 2649 MEM_BLOCK_ANY, index, &load16_entry)); 2650 2651 return BCM_E_NONE; 2652 } 2653 2654 /* 2655 * Function: 2656 * bcmi_ft_load16_entry_uninstall 2657 * Purpose: 2658 * Clear Load 16 entry in hardware 2659 * Parameters: 2660 * unit - (IN) BCM device id 2661 * id - (IN) FT group id. 2662 * load16_indexes - (IN) Load 16 indexes in group 2663 * 2664 * Returns: 2665 * BCM_E_XXX 2666 */ 2667 int 2668 bcmi_ft_load16_entry_uninstall( 2669 int unit, 2670 bcm_flowtracker_group_t id, 2671 bcmi_ft_group_alu_info_t *info, 2672 int *indexes) 2673 { 2674 int index = 0; 2675 int rv = BCM_E_NONE; 2676 bsc_dg_group_table_entry_t dg_entry; 2677 2678 if (indexes[0] == -1) { 2679 /* There is no load 16 entry. */ 2680 return BCM_E_NONE; 2681 } 2682 2683 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 2684 2685 /* First remove the entry from the hash table. */ 2686 rv = bcmi_ft_alu_hash_mem_index_get(unit, id, bcmiFtAluLoadTypeLoad16, 2687 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index); 2688 2689 if (BCM_FAILURE(rv)) { 2690 /* first cleanup if something is configured. */ 2691 if (rv == BCM_E_NOT_FOUND) { 2692 /* 2693 * If this happens then it might be due to the error while adding. 2694 * No need to do anything. just return back saying that it is clean. 2695 */ 2696 return BCM_E_NONE; 2697 } else { 2698 return rv; 2699 } 2700 } 2701 2702 /* First read the group entry. */ 2703 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 2704 MEM_BLOCK_ANY, id, &dg_entry)); 2705 2706 /* now write this index into the group. */ 2707 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry, 2708 GROUP_LOAD16_PROFILE_IDXf, 0); 2709 2710 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 2711 2712 if (BCM_SUCCESS(rv)) { 2713 2714 /* Also increment the ref count on this index. */ 2715 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad16, index); 2716 2717 if (!(BCMI_FT_ALU_LOAD_REFCOUNT 2718 (unit, bcmiFtAluLoadTypeLoad16, index))) { 2719 2720 /* Assign the bitmap to this index. */ 2721 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP 2722 (unit, bcmiFtAluLoadTypeLoad16)) , index); 2723 2724 /* We already found the entry above so this should always pass. */ 2725 rv = bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad16, 2726 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index); 2727 2728 if (BCM_FAILURE(rv)) { 2729 return rv; 2730 } 2731 2732 /* Clear the entry in the profile table. */ 2733 rv = bcmi_ft_load16_entry_clear(unit, index); 2734 } 2735 } 2736 2737 return rv; 2738 } 2739 2740 2741 2742 2743 2744 /****************************************************** 2745 | LOAD8 Space | 2746 */ 2747 2748 /* 2749 * Function: 2750 * bcmi_ft_load8_entry_match 2751 * Purpose: 2752 * Match load 8 entry in hardware 2753 * Parameters: 2754 * unit - (IN) BCM device id 2755 * id - (IN) FT group id. 2756 * info - (IN) ALU/Load information of group. 2757 * load8_indexes - (IN) Load 8 indexes in group 2758 * index - (OUT) sw index. 2759 * 2760 * Returns: 2761 * BCM_E_XXX 2762 */ 2763 int 2764 bcmi_ft_load8_entry_match( 2765 int unit, 2766 bcm_flowtracker_group_t id, 2767 bcmi_ft_group_alu_info_t *info, 2768 bcmi_ft_alu_hash_info_t *alu_info, 2769 int *load8_indexes, 2770 int *index) 2771 { 2772 2773 bcmi_ft_group_alu_info_t *local = NULL; 2774 uint32 load8_ctrlfmt[1]; 2775 bsc_dg_group_load8_profile_entry_t load8_entry; 2776 uint32 location = 0, trigger = 0; 2777 int i=0, j=0; 2778 int max = 0; 2779 int match_found = 0; 2780 2781 int data[TOTAL_GROUP_LOAD8_DATA_NUM] = 2782 {DATA_7f, 2783 DATA_6f, 2784 DATA_5f, 2785 DATA_4f, 2786 DATA_3f, 2787 DATA_2f, 2788 DATA_1f, 2789 DATA_0f}; 2790 2791 sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t)); 2792 sal_memset(load8_ctrlfmt, 0, sizeof(uint32)); 2793 2794 max = soc_mem_index_max(unit, BSC_DG_GROUP_LOAD8_PROFILEm); 2795 2796 /* if the index is provided then match for only that index. */ 2797 if (*index != -1) { 2798 max = *index; 2799 i = *index; 2800 } 2801 2802 for (; i<=max; i++) { 2803 /* Check for the bitmap first if the entry is in use.*/ 2804 2805 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 2806 MEM_BLOCK_ANY, i, &load8_entry)); 2807 2808 for (; j<TOTAL_GROUP_LOAD8_DATA_NUM; j++) { 2809 2810 soc_mem_field_get(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 2811 (uint32 *) &load8_entry, data[j], load8_ctrlfmt); 2812 2813 trigger = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt, 2814 load8_ctrlfmt, LOAD_TRIGGERf); 2815 2816 if (load8_indexes[j] != -1) { 2817 if (!trigger) { 2818 /* 2819 * If trigger is not set but still 2820 * there is some info at that index 2821 * then this will not match this load entry. 2822 */ 2823 match_found = 0; 2824 break; 2825 } else if (trigger != 2826 BCMI_FT_GROUP_FTFP_DATA(unit, id).direction) { 2827 /* 2828 * If trigger is set but not matching 2829 * to the group direction then also no match. 2830 */ 2831 match_found = 0; 2832 break; 2833 } 2834 } else { 2835 if (trigger) { 2836 /* 2837 * If trigger is set but still 2838 * there is no info at that index 2839 * then this will not match this load entry. 2840 */ 2841 match_found = 0; 2842 } 2843 /* if trigger is also not set, then this could be match 2844 * based on the previous match result. just breack from here. 2845 */ 2846 break; 2847 } 2848 2849 local = (&(info[load8_indexes[j]])); 2850 location = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt, 2851 load8_ctrlfmt, ATTR_SELECTf); 2852 2853 if (location != (local->key1.location / 8)) { 2854 /* 2855 * If entry does not match then return. 2856 * by setting that this is not a match. 2857 */ 2858 match_found = 0; 2859 break; 2860 } 2861 match_found = 1; 2862 } 2863 if (match_found) { 2864 break; 2865 } 2866 } 2867 2868 if (match_found) { 2869 *index = i; 2870 return BCM_E_NONE; 2871 } 2872 2873 return BCM_E_NOT_FOUND; 2874 } 2875 2876 /* 2877 * Function: 2878 * bcmi_ft_load8_entry_write 2879 * Purpose: 2880 * Write Load 8 entry in hardware 2881 * Parameters: 2882 * unit - (IN) BCM device id 2883 * id - (IN) FT group id. 2884 * info - (IN) ALU/Load information of group. 2885 * load8_indexes - (IN) Load 8 indexes in group 2886 * index - (IN) sw index. 2887 * 2888 * Returns: 2889 * BCM_E_XXX 2890 */ 2891 int 2892 bcmi_ft_load8_entry_write( 2893 int unit, 2894 bcm_flowtracker_group_t id, 2895 bcmi_ft_group_alu_info_t *info, 2896 int *load8_indexes, 2897 int index) 2898 { 2899 2900 bcmi_ft_group_alu_info_t *local = NULL; 2901 uint32 load8_ctrlfmt[1]; 2902 bsc_dg_group_load8_profile_entry_t load8_entry; 2903 uint32 location = 0; 2904 int j=0; 2905 2906 int data[TOTAL_GROUP_LOAD8_DATA_NUM] = 2907 {DATA_7f, 2908 DATA_6f, 2909 DATA_5f, 2910 DATA_4f, 2911 DATA_3f, 2912 DATA_2f, 2913 DATA_1f, 2914 DATA_0f}; 2915 2916 sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t)); 2917 sal_memset(load8_ctrlfmt, 0, sizeof(uint32)); 2918 2919 for (; j<TOTAL_GROUP_LOAD8_DATA_NUM; j++) { 2920 /* Now based on the incoming info, match the entries. */ 2921 if (load8_indexes[j] == -1) { 2922 break; 2923 } 2924 2925 local = (&(info[load8_indexes[j]])); 2926 2927 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt, 2928 load8_ctrlfmt, LOAD_TRIGGERf, 2929 BCMI_FT_GROUP_FTFP_DATA(unit, id).direction); 2930 2931 location = local->key1.location; 2932 2933 if (location % 8) { 2934 /* if location is not at 8B boundary then return error. */ 2935 return BCM_E_PARAM; 2936 } 2937 2938 /* 2939 * ftfp is sending location in continuous index of 256B. 2940 * Each extractor here is 8 bytes so long, so 2941 * need to divide it by 32 to get correct location. 2942 */ 2943 location = (location / 8); 2944 2945 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt, 2946 load8_ctrlfmt, ATTR_SELECTf, location); 2947 2948 /* Write into that entry. */ 2949 soc_mem_field_set(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 2950 (uint32 *) &load8_entry, data[j], load8_ctrlfmt); 2951 } 2952 2953 BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 2954 MEM_BLOCK_ANY, index, &load8_entry)); 2955 2956 return BCM_E_NONE; 2957 } 2958 2959 2960 /* 2961 * Function: 2962 * bcmi_ft_load8_entry_install 2963 * Purpose: 2964 * Install Load 8 entry in hardware 2965 * Parameters: 2966 * unit - (IN) BCM device id 2967 * id - (IN) FT group id. 2968 * indexes - (IN) Load 8 indexes in group 2969 * 2970 * Returns: 2971 * BCM_E_XXX 2972 */ 2973 int 2974 bcmi_ft_load8_entry_install( 2975 int unit, 2976 bcm_flowtracker_group_t id, 2977 bcmi_ft_group_alu_info_t *info, 2978 int *indexes) 2979 { 2980 bcmi_ft_group_alu_info_t *temp = NULL, *local = NULL; 2981 bsc_dg_group_table_entry_t dg_entry; 2982 int rv = BCM_E_NONE; 2983 int j, index = -1; 2984 2985 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 2986 2987 if (indexes[0] == -1) { 2988 /* There is no load8 entry. */ 2989 return BCM_E_NONE; 2990 } 2991 2992 /* assign the ALU memory chunk to local pointer. */ 2993 temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 2994 2995 rv = bcmi_ft_alu_hash_insert(unit, id, bcmiFtAluLoadTypeLoad8, 2996 temp, indexes, &index); 2997 2998 if (BCM_FAILURE(rv)) { 2999 if (rv == BCM_E_EXISTS) { 3000 /* Increment ref count and set up group table. */ 3001 BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad8, index); 3002 rv = BCM_E_NONE; 3003 } else { 3004 return rv; 3005 } 3006 } else { 3007 /* Now that we have got the index, now write into that index. */ 3008 rv = bcmi_ft_load8_entry_write(unit, id, temp, indexes, index); 3009 BCMI_CLEANUP_IF_ERROR(rv); 3010 3011 if (index != -1) { 3012 /* Assign the bitmap to this index. */ 3013 SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad8)), 3014 index); 3015 3016 /* Also increment the ref count on this index. */ 3017 BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad8, index); 3018 } 3019 } 3020 3021 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 3022 (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"), 3023 index, alu_type_str[bcmiFtAluLoadTypeLoad8])); 3024 3025 rv = bcmi_ft_load_pdd_entry_set(unit, id, bcmiFtAluLoadTypeLoad8, index, 0); 3026 BCMI_CLEANUP_IF_ERROR(rv); 3027 3028 /* First read the group entry. */ 3029 rv = soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 3030 MEM_BLOCK_ANY, id, &dg_entry); 3031 BCMI_CLEANUP1_IF_ERROR(rv); 3032 3033 /* now write this index into the group. */ 3034 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, ((uint32 *)&dg_entry), 3035 GROUP_LOAD8_PROFILE_IDXf, index); 3036 3037 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 3038 BCMI_CLEANUP1_IF_ERROR(rv); 3039 3040 /* Update type and index into all the data elements. */ 3041 for (j = 0; j<TOTAL_GROUP_LOAD8_DATA_NUM; j++) { 3042 /* Now based on the incoming info, match the entries. */ 3043 if (indexes[j] == -1) { 3044 break; 3045 } 3046 3047 local = (&(temp[indexes[j]])); 3048 local->alu_load_index = index; 3049 local->alu_load_type = bcmiFtAluLoadTypeLoad8; 3050 } 3051 3052 return BCM_E_NONE; 3053 3054 cleanup1: 3055 if (index != -1) { 3056 /* Also decrement the ref count on this index. */ 3057 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad8, index); 3058 3059 if (!(BCMI_FT_ALU_LOAD_REFCOUNT 3060 (unit, bcmiFtAluLoadTypeLoad8, index))) { 3061 3062 /* Clear the bitmap to this index. */ 3063 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad8)), 3064 index); 3065 } 3066 3067 bcmi_ft_load_pdd_entry_set(unit, id, bcmiFtAluLoadTypeLoad8, index, 1); 3068 } 3069 3070 cleanup: 3071 /* remove the previously added hash table entry. */ 3072 bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad8, 3073 info, NULL, &index); 3074 3075 return rv; 3076 } 3077 3078 /* 3079 * Function: 3080 * bcmi_ft_load8_entry_clear 3081 * Purpose: 3082 * Clear Load 8 entry in hardware 3083 * Parameters: 3084 * unit - (IN) BCM device id 3085 * index - (IN) Load 8 index 3086 * 3087 * Returns: 3088 * BCM_E_XXX 3089 */ 3090 int 3091 bcmi_ft_load8_entry_clear(int unit, int index) 3092 { 3093 3094 bsc_dg_group_load8_profile_entry_t load8_entry; 3095 3096 sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t)); 3097 3098 BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 3099 MEM_BLOCK_ANY, index, &load8_entry)); 3100 3101 return BCM_E_NONE; 3102 } 3103 3104 /* 3105 * Function: 3106 * bcmi_ft_load8_entry_uninstall 3107 * Purpose: 3108 * uninstall Load 8 entry in hardware 3109 * Parameters: 3110 * unit - (IN) BCM device id 3111 * id - (IN) FT group id. 3112 * indexes - (IN) Load 8 indexes in group 3113 * 3114 * Returns: 3115 * BCM_E_XXX 3116 */ 3117 int 3118 bcmi_ft_load8_entry_uninstall( 3119 int unit, 3120 bcm_flowtracker_group_t id, 3121 bcmi_ft_group_alu_info_t *info, 3122 int *indexes) 3123 { 3124 int index = 0; 3125 int rv = BCM_E_NONE; 3126 bsc_dg_group_table_entry_t dg_entry; 3127 3128 if (indexes[0] == -1) { 3129 /* There is no load 16 entry. */ 3130 return BCM_E_NONE; 3131 } 3132 3133 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 3134 3135 /* First remove the entry from the hash table. */ 3136 rv = bcmi_ft_alu_hash_mem_index_get(unit, id, bcmiFtAluLoadTypeLoad8, 3137 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index); 3138 3139 if (BCM_FAILURE(rv)) { 3140 /* first cleanup if something is configured. */ 3141 if (rv == BCM_E_NOT_FOUND) { 3142 /* 3143 * If this happens then it might be due to the error while adding. 3144 * No need to do anything. just return back saying that it is clean. 3145 */ 3146 return BCM_E_NONE; 3147 } else { 3148 return rv; 3149 } 3150 } 3151 3152 /* Then clear the group table index. */ 3153 /* First read the group entry. */ 3154 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 3155 MEM_BLOCK_ANY, id, &dg_entry)); 3156 3157 /* now write this index into the group. */ 3158 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry, 3159 GROUP_LOAD8_PROFILE_IDXf, 0); 3160 3161 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 3162 3163 if (BCM_SUCCESS(rv)) { 3164 3165 /* Also increment the ref count on this index. */ 3166 BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad8, index); 3167 3168 if (!(BCMI_FT_ALU_LOAD_REFCOUNT 3169 (unit, bcmiFtAluLoadTypeLoad8, index))) { 3170 3171 /* Assign the bitmap to this index. */ 3172 SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP 3173 (unit, bcmiFtAluLoadTypeLoad8)) , index); 3174 /* We already found the entry above so this should always pass. */ 3175 rv = bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad8, 3176 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index); 3177 3178 if (BCM_FAILURE(rv)) { 3179 return rv; 3180 } 3181 3182 /* Clear the entry in the profile table. */ 3183 rv = bcmi_ft_load8_entry_clear(unit, index); 3184 } 3185 } 3186 3187 return rv; 3188 } 3189 3190 /* 3191 * Function: 3192 * bcmi_ft_group_alu_load_index_match 3193 * Purpose: 3194 * Match ALU index for this group. 3195 * Description: 3196 * Even if we may get exact same ALU 3197 * which is matching to some existing entry 3198 * in hash table, we may not use it if 3199 * THat particular ALU memory is used by this 3200 * group. So in that case, 3201 * we may have to get another index and then 3202 * while removing, we may have to make sure this 3203 * group has correct index. 3204 * Parameters: 3205 * unit - (IN) BCM device id 3206 * id - (IN) FT group id. 3207 * alu_load_type - (IN) ALU/LOAD type. 3208 * alu_info - (IN) ALU hash information of group. 3209 * Returns: 3210 * BCM_E_XXX 3211 */ 3212 int 3213 bcmi_ft_group_alu_load_index_match( 3214 int unit, 3215 bcm_flowtracker_group_t id, 3216 bcmi_ft_alu_load_type_t alu_load_type, 3217 bcmi_ft_alu_hash_info_t *alu_info) 3218 { 3219 3220 int index = -1; 3221 int new_index = -1; 3222 int a_idx = -1; /* Array index of field/memory array. */ 3223 soc_mem_t mem; 3224 uint32 *in_use_array = NULL; 3225 3226 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 3227 in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id); 3228 } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) { 3229 in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id); 3230 } 3231 3232 3233 /* Get the index from alu hash info. */ 3234 index = alu_info->alu_load_index; 3235 3236 if ((alu_load_type != bcmiFtAluLoadTypeAlu32) && 3237 (alu_load_type != bcmiFtAluLoadTypeAlu16)) { 3238 return BCM_E_NOT_FOUND; 3239 } 3240 3241 3242 /* Convert global ALU number into hw memory and index. */ 3243 bcmi_ft_alu_load_mem_index_get 3244 (unit, index, alu_load_type, &new_index, &mem, &a_idx); 3245 3246 if (new_index == -1) { 3247 return BCM_E_NOT_FOUND; 3248 } 3249 3250 if (in_use_array[a_idx]) { 3251 /* This memory is already used in group. cant use it. */ 3252 return BCM_E_NOT_FOUND; 3253 } 3254 3255 return BCM_E_NONE; 3256 } 3257 3258 /* 3259 * Function: 3260 * bcmi_ft_group_ft_mode_get 3261 * Purpose: 3262 * Set single/Double mode after checking session data. 3263 * Parameters: 3264 * unit - (IN) BCM device id 3265 * id - (IN) FT group id. 3266 * 3267 * Returns: 3268 * BCM_E_XXX 3269 */ 3270 int 3271 bcmi_ft_group_ft_mode_update( 3272 int unit, 3273 bcm_flowtracker_group_t id) 3274 { 3275 3276 int i=0; 3277 int num_alus_loads = 0; 3278 bcmi_ft_group_alu_info_t *temp = NULL; 3279 int length, total_length; 3280 bcmi_ft_group_key_data_mode_t mode = bcmiFtGroupModeSingle; 3281 3282 /* Read the group state for the ALU inforamtion. */ 3283 if (!(BCMI_FT_GROUP_EXT_DATA_OR_TS_TRIGGERS_SET(unit, id))) { 3284 return BCM_E_INTERNAL; 3285 } 3286 3287 length = total_length = 0; 3288 3289 /* assign the ALU memory chunk to local pointer. */ 3290 temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 3291 3292 /* Get total number of alus in this chunk. */ 3293 num_alus_loads = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info; 3294 3295 /* allocate the bitmap based on the type, length */ 3296 for (i=0; i<num_alus_loads; i++) { 3297 3298 length = temp->key1.length; 3299 if ((temp->key1.is_alu) && ((length >=8) && (length < 16))) { 3300 /* 3301 * if ALU is required but we have less than 16 bit of length 3302 * then this might be a case where extractor is not aligned properly. 3303 * Hence we will change length accordingly to pick correct alu type. 3304 */ 3305 length = 16; 3306 } 3307 total_length += length; 3308 temp++; 3309 } 3310 3311 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3312 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_METERf)) { 3313 total_length += 48; 3314 } 3315 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3316 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_COUNT_TO_CPUf)) { 3317 total_length += 16; 3318 } 3319 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3320 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_STATEf)) { 3321 total_length += 8; 3322 } 3323 3324 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3325 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_0f)) { 3326 total_length += 48; 3327 } 3328 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3329 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_1f)) { 3330 total_length += 48; 3331 } 3332 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3333 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_2f)) { 3334 total_length += 48; 3335 } 3336 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3337 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_3f)) { 3338 total_length += 48; 3339 } 3340 3341 if (total_length > BCMI_FT_SESSION_DATA_SINGLE_LEN) { 3342 mode = bcmiFtGroupModeDouble; 3343 bcmi_ft_group_extraction_mode_set(unit, 0, id, mode); 3344 bcmi_ft_group_extraction_mode_set(unit, 1, id, mode); 3345 } 3346 3347 return BCM_E_NONE; 3348 } 3349 3350 3351 /* We need to change the load triggers whenever we get the indication from user. */ 3352 int 3353 bcmi_ft_group_alu_load_trigger_set( 3354 int unit, 3355 bcm_flowtracker_group_t id, 3356 bcm_flowtracker_direction_t direction) 3357 { 3358 bcmi_ft_group_pdd_bus_info_t *pdd_info = NULL; 3359 int total_mems = 0; 3360 int mem_idx = 0, type=0; 3361 bsc_dg_group_table_entry_t dg_entry; 3362 int index = -1; 3363 3364 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 3365 3366 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 3367 MEM_BLOCK_ANY, id, &dg_entry)); 3368 3369 /* For all the types of memory types. */ 3370 for (type=0; type<bcmiFtAluLoadTypeNone; type++) { 3371 3372 total_mems = alu_load_index_info[unit][type].total_mem_count; 3373 3374 /* For all the alu/load types, check what memories are set in pdd. */ 3375 for (mem_idx=0; mem_idx<total_mems; mem_idx++) { 3376 /* Now get if this particular field is set in pdd. */ 3377 pdd_info = alu_load_index_info[unit][type].pdd_bus_info; 3378 3379 if (!pdd_info) { 3380 return BCM_E_INTERNAL; 3381 } 3382 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 3383 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 3384 pdd_info[mem_idx].param_id)) { 3385 3386 index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 3387 &dg_entry, 3388 (BCMI_FT_GROUP_FID_INFO(unit, type))[mem_idx]); 3389 3390 if (type == bcmiFtAluLoadTypeAlu32) { 3391 BCM_IF_ERROR_RETURN( 3392 bcmi_ft_group_alu32_trigger_set(unit, mem_idx, index, 3393 direction)); 3394 } else if (type == bcmiFtAluLoadTypeAlu16) { 3395 BCM_IF_ERROR_RETURN( 3396 bcmi_ft_group_alu16_trigger_set(unit, mem_idx, index, 3397 direction)); 3398 } else if (type == bcmiFtAluLoadTypeLoad16) { 3399 BCM_IF_ERROR_RETURN( 3400 bcmi_ft_group_load16_trigger_set(unit, mem_idx, index, 3401 direction)); 3402 } else if (type == bcmiFtAluLoadTypeLoad8) { 3403 BCM_IF_ERROR_RETURN( 3404 bcmi_ft_group_load8_trigger_set(unit, mem_idx, index, 3405 direction)); 3406 } else { 3407 return BCM_E_PARAM; 3408 } 3409 3410 } 3411 } 3412 } 3413 return BCM_E_NONE; 3414 } 3415 3416 int 3417 bcmi_ft_group_load16_trigger_set( 3418 int unit, 3419 int mem_idx, 3420 int index, 3421 bcm_flowtracker_direction_t direction) 3422 { 3423 uint32 load16_ctrlfmt[1]; 3424 bsc_dg_group_load16_profile_entry_t load16_entry; 3425 int rv = BCM_E_NONE; 3426 3427 int data[TOTAL_GROUP_LOAD16_DATA_NUM] = 3428 {DATA_15f, 3429 DATA_14f, 3430 DATA_13f, 3431 DATA_12f, 3432 DATA_11f, 3433 DATA_10f, 3434 DATA_9f, 3435 DATA_8f, 3436 DATA_7f, 3437 DATA_6f, 3438 DATA_5f, 3439 DATA_4f, 3440 DATA_3f, 3441 DATA_2f, 3442 DATA_1f, 3443 DATA_0f}; 3444 sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t)); 3445 sal_memset(load16_ctrlfmt, 0, sizeof(uint32)); 3446 3447 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 3448 MEM_BLOCK_ANY, index, &load16_entry)); 3449 3450 soc_mem_field_get(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 3451 (uint32 *) &load16_entry, data[mem_idx], load16_ctrlfmt); 3452 3453 /* Update the load trigger based on groups direction configuration. */ 3454 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt, 3455 load16_ctrlfmt, LOAD_TRIGGERf, direction); 3456 3457 rv = soc_mem_write(unit, BSC_DG_GROUP_LOAD16_PROFILEm, 3458 MEM_BLOCK_ANY, index, &load16_entry); 3459 3460 return rv; 3461 } 3462 3463 3464 3465 int 3466 bcmi_ft_group_load8_trigger_set( 3467 int unit, 3468 int mem_idx, 3469 int index, 3470 bcm_flowtracker_direction_t direction) 3471 { 3472 uint32 load8_ctrlfmt[1]; 3473 bsc_dg_group_load8_profile_entry_t load8_entry; 3474 int rv = BCM_E_NONE; 3475 int data[TOTAL_GROUP_LOAD8_DATA_NUM] = 3476 {DATA_7f, 3477 DATA_6f, 3478 DATA_5f, 3479 DATA_4f, 3480 DATA_3f, 3481 DATA_2f, 3482 DATA_1f, 3483 DATA_0f}; 3484 3485 sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t)); 3486 sal_memset(load8_ctrlfmt, 0, sizeof(uint32)); 3487 3488 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 3489 MEM_BLOCK_ANY, index, &load8_entry)); 3490 3491 soc_mem_field_get(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 3492 (uint32 *) &load8_entry, data[mem_idx], load8_ctrlfmt); 3493 3494 /* Update the load trigger based on groups direction configuration. */ 3495 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt, 3496 load8_ctrlfmt, LOAD_TRIGGERf, direction); 3497 3498 rv = soc_mem_write(unit, BSC_DG_GROUP_LOAD8_PROFILEm, 3499 MEM_BLOCK_ANY, index, &load8_entry); 3500 3501 return rv; 3502 } 3503 3504 3505 /* For load triggers on ALU memories. */ 3506 int 3507 bcmi_ft_group_alu32_trigger_set( 3508 int unit, 3509 int mem_idx, 3510 int index, 3511 bcm_flowtracker_direction_t direction) 3512 { 3513 3514 int rv = BCM_E_NONE; 3515 uint32 alu_base_ctrlfmt[3]; 3516 uint32 alu32_specific_ctrlfmt[4]; 3517 uint32 alu32_ctrlfmt[7]; 3518 bsc_dg_group_alu32_profile_0_entry_t alu32_entry; 3519 soc_mem_t mem; 3520 3521 sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32)); 3522 sal_memset(alu32_specific_ctrlfmt, 0, 4*sizeof(uint32)); 3523 sal_memset(alu32_ctrlfmt, 0, 7*sizeof(uint32)); 3524 3525 3526 mem = alu_32_info[mem_idx].mem; 3527 3528 /* The profile is set. Write into the index of group. */ 3529 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &alu32_entry); 3530 3531 soc_mem_field_get(unit, mem, (uint32 *)&alu32_entry, DATAf, 3532 alu32_ctrlfmt); 3533 3534 soc_format_field_get(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt, 3535 alu32_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt); 3536 /* Set the load trigger for forward and reverse. */ 3537 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 3538 alu_base_ctrlfmt, LOAD_TRIGGERf, direction); 3539 3540 soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt, 3541 alu32_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt); 3542 3543 soc_mem_field_set(unit, mem, (uint32 *)&alu32_entry, DATAf, 3544 alu32_ctrlfmt); 3545 3546 /* The profile is set. Write into the index of group. */ 3547 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &alu32_entry); 3548 3549 return rv; 3550 } 3551 3552 /* For load triggers on ALU memories. */ 3553 int 3554 bcmi_ft_group_alu16_trigger_set( 3555 int unit, 3556 int mem_idx, 3557 int index, 3558 bcm_flowtracker_direction_t direction) 3559 { 3560 3561 int rv = BCM_E_NONE; 3562 uint32 alu_base_ctrlfmt[3]; 3563 uint32 alu16_specific_ctrlfmt[4]; 3564 uint32 alu16_ctrlfmt[6]; 3565 bsc_dg_group_alu16_profile_0_entry_t alu16_entry; 3566 soc_mem_t mem; 3567 sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32)); 3568 sal_memset(alu16_specific_ctrlfmt, 0, 4*sizeof(uint32)); 3569 sal_memset(alu16_ctrlfmt, 0, 6*sizeof(uint32)); 3570 3571 3572 mem = alu_16_info[mem_idx].mem; 3573 3574 /* The profile is set. Write into the index of group. */ 3575 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &alu16_entry); 3576 3577 soc_mem_field_get(unit, mem, (uint32 *)&alu16_entry, DATAf, 3578 alu16_ctrlfmt); 3579 3580 soc_format_field_get(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt, 3581 alu16_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt); 3582 3583 /* Set the load trigger for forward and reverse. */ 3584 soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt, 3585 alu_base_ctrlfmt, LOAD_TRIGGERf, direction); 3586 3587 soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt, 3588 alu16_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt); 3589 3590 soc_mem_field_set(unit, mem, (uint32 *)&alu16_entry, DATAf, 3591 alu16_ctrlfmt); 3592 3593 /* The profile is set. Write into the index of group. */ 3594 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &alu16_entry); 3595 3596 return rv; 3597 } 3598 3599 /* Chip Wide Debug methods. */ 3600 int 3601 bcmi_ft_tracking_param_in_Debug_mode( 3602 int unit, 3603 bcm_flowtracker_group_t id, 3604 bcmi_ft_group_alu_info_t *group_alu_info, 3605 bcmi_ft_alu_load_type_t alu_load_type) 3606 { 3607 int i = 0; 3608 3609 if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) { 3610 return 0; 3611 } 3612 3613 if (group_alu_info == NULL) { 3614 return 0; 3615 } 3616 3617 if ((alu_load_type != bcmiFtAluLoadTypeAlu32) && 3618 (alu_load_type != bcmiFtAluLoadTypeAlu16)) { 3619 3620 return 0; 3621 } 3622 3623 for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) { 3624 if (group_alu_info->element_type1 == 3625 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).param) { 3626 return 1; 3627 } 3628 } 3629 3630 3631 return 0; 3632 } 3633 3634 3635 int 3636 bcmi_ft_chip_debug_counter_init( 3637 int unit, 3638 int mem_idx, 3639 bcmi_ft_alu_load_type_t alu_load_type, 3640 uint32 count) 3641 { 3642 3643 soc_mem_t mem; 3644 3645 if (mem_idx == -1) { 3646 return BCM_E_NONE; 3647 } 3648 3649 /* Get the free memory index of this type of memory. */ 3650 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 3651 mem = bcmi_ft_alu16_debug_counter[mem_idx]; 3652 } else { 3653 mem = bcmi_ft_alu32_debug_counter[mem_idx]; 3654 } 3655 3656 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, mem, 3657 0, COUNTf, count)); 3658 3659 return BCM_E_NONE; 3660 } 3661 3662 3663 int 3664 bcmi_ft_chip_debug_counter_get( 3665 int unit, 3666 int mem_idx, 3667 bcmi_ft_alu_load_type_t alu_load_type, 3668 uint32 *count) 3669 { 3670 3671 uint32 buf[SOC_MAX_MEM_WORDS]; 3672 soc_mem_t mem; 3673 3674 if (mem_idx == -1) { 3675 return BCM_E_NONE; 3676 } 3677 3678 if (count == NULL) { 3679 return BCM_E_PARAM; 3680 } 3681 3682 /* Get the free memory index of this type of memory. */ 3683 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 3684 mem = bcmi_ft_alu16_debug_counter[mem_idx]; 3685 } else { 3686 mem = bcmi_ft_alu32_debug_counter[mem_idx]; 3687 } 3688 3689 3690 /* Lock the memory. */ 3691 BCM_IF_ERROR_RETURN (soc_mem_read(unit, mem, MEM_BLOCK_ALL, 3692 0, buf)); 3693 3694 *count = soc_mem_field32_get(unit, mem, buf, COUNTf); 3695 3696 3697 return BCM_E_NONE; 3698 } 3699 3700 3701 void 3702 bcmi_ft_chip_debug_use_mem_update( 3703 int unit, 3704 bcmi_ft_alu_load_type_t alu_load_type, 3705 int mem_idx, 3706 int val) 3707 { 3708 3709 int *in_use_array = NULL; 3710 int *ref_count = NULL; 3711 int i = 0; 3712 3713 if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) { 3714 return; 3715 } 3716 3717 if ((alu_load_type != bcmiFtAluLoadTypeAlu32) && 3718 (alu_load_type != bcmiFtAluLoadTypeAlu16)) { 3719 3720 return; 3721 } 3722 3723 /* Get the free memory index of this type of memory. */ 3724 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 3725 in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_mem_used; 3726 ref_count = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_ref_count; 3727 } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) { 3728 in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_mem_used; 3729 ref_count = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_ref_count; 3730 } 3731 3732 ref_count[mem_idx] += val; 3733 3734 in_use_array[mem_idx] = ((ref_count[mem_idx]) ? 1 : 0); 3735 3736 /* 3737 * Now if the ref_count on this memory index is 0. 3738 * We should remove the association with tracking param too. 3739 */ 3740 if (ref_count[mem_idx] == 0) { 3741 /* Find which tracking param is using this memory.*/ 3742 for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) { 3743 if (alu_load_type != BCMI_FT_CHIP_DEBUG_PARAM(unit, i).alu_type) { 3744 continue; 3745 } 3746 3747 if (mem_idx == BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id) { 3748 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id = -1; 3749 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).alu_type = 0; 3750 break; 3751 } 3752 } 3753 } 3754 3755 return; 3756 } 3757 3758 int 3759 bcmi_ft_chip_debug_mem_check( 3760 int unit, 3761 bcmi_ft_alu_load_type_t alu_load_type, 3762 int mem_idx) 3763 { 3764 3765 int i = 0; 3766 3767 if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) { 3768 return 0; 3769 } 3770 3771 3772 /* Check in existing parameters. */ 3773 for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) { 3774 if (alu_load_type != BCMI_FT_CHIP_DEBUG_PARAM(unit, i).alu_type) { 3775 continue; 3776 } 3777 3778 if (mem_idx == BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id) { 3779 return 1; 3780 } 3781 } 3782 3783 return 0; 3784 } 3785 3786 3787 /* 3788 * Function: 3789 * bcmi_ft_chip_debug_alu_index_get 3790 * Purpose: 3791 * Get ALU/Load type based on length/params. 3792 * Parameters: 3793 * unit - (IN) BCM device id. 3794 * id - (IN) FT group id. 3795 * alu_load_type - (IN) type of load/ALU. 3796 * index - (OUT) Free index of that memory. 3797 * Returns: 3798 * BCM_E_XXX 3799 */ 3800 int 3801 bcmi_ft_chip_debug_alu_index_get( 3802 int unit, 3803 bcm_flowtracker_group_t id, 3804 bcmi_ft_group_alu_info_t *group_alu_info, 3805 bcmi_ft_alu_load_type_t alu_load_type, 3806 int *index) 3807 { 3808 3809 int i = 0; 3810 int *in_use_array = NULL; 3811 uint32 *group_in_use_array = NULL; 3812 uint32 total_mems = 1; 3813 int mem_idx = -1, mem_id = 0; 3814 int p_idx = 0; /* param index. */ 3815 int size_per_mem = 0; 3816 int start_index = 0, end_index = 0; 3817 uint32 count = 0; 3818 3819 if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) { 3820 return 0; 3821 } 3822 3823 if (group_alu_info == NULL) { 3824 return BCM_E_PARAM; 3825 } 3826 3827 if (index == NULL) { 3828 return BCM_E_PARAM; 3829 } 3830 3831 if ((alu_load_type != bcmiFtAluLoadTypeAlu32) && 3832 (alu_load_type != bcmiFtAluLoadTypeAlu16)) { 3833 3834 return BCM_E_PARAM; 3835 } 3836 3837 *index = -1; 3838 3839 /* Get the total indexes for this type of memory. */ 3840 size_per_mem = 3841 alu_load_index_info[unit][alu_load_type].alu_load_info->mem_size; 3842 3843 /* Check in existing parameters. */ 3844 for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) { 3845 if (group_alu_info->element_type1 == 3846 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).param) { 3847 mem_idx = BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id; 3848 count = BCMI_FT_CHIP_DEBUG_PARAM(unit, i).count; 3849 p_idx = i; 3850 break; 3851 } 3852 } 3853 3854 if (i == BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info) { 3855 return BCM_E_NOT_FOUND; 3856 } 3857 3858 /* Get the free memory index of this type of memory. */ 3859 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 3860 in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_mem_used; 3861 group_in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id); 3862 total_mems = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16); 3863 } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) { 3864 in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_mem_used; 3865 group_in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id); 3866 total_mems = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32); 3867 } 3868 3869 if (mem_idx == -1) { 3870 3871 /* start index should be where the free index starts. */ 3872 while (mem_id < total_mems) { 3873 if (in_use_array != NULL) { 3874 if ((in_use_array[mem_id]) || (group_in_use_array[mem_id])) { 3875 /* This ALU memory is used. go for next one. */ 3876 mem_id++; 3877 continue; 3878 } else { 3879 mem_idx = mem_id; 3880 break; 3881 } 3882 } else { 3883 return BCM_E_PARAM; 3884 } 3885 } 3886 BCM_IF_ERROR_RETURN(bcmi_ft_chip_debug_counter_init 3887 (unit, mem_idx, alu_load_type, count)); 3888 } else { 3889 if (group_in_use_array[mem_idx]) { 3890 return BCM_E_PARAM; 3891 } 3892 } 3893 3894 if (mem_idx == -1) { 3895 return BCM_E_RESOURCE; 3896 } 3897 3898 for (mem_id=0; mem_id<mem_idx; mem_id++) { 3899 size_per_mem = 3900 BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_id); 3901 3902 start_index += size_per_mem; 3903 } 3904 3905 size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx); 3906 3907 /* set the end index according to the indexes in that memory. */ 3908 end_index = start_index + size_per_mem; 3909 3910 /* 3911 * Cannot not index 0 for ALU/LOAD. 3912 * If index 0 is used then Group may point to it and 3913 * malicious actions can be taken on that flow. 3914 */ 3915 i = start_index; 3916 i += ((start_index == 0) ? 1 : 0); 3917 3918 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 3919 (BSL_META_U(unit, "start_index = %d, end_index=%d\n"), 3920 start_index, end_index)); 3921 3922 /* based on the above index. select the bitmap. */ 3923 for (; i<end_index; i++) { 3924 if (!(SHR_BITGET(BCMI_FT_ALU_LOAD_BITMAP 3925 (unit, alu_load_type), i))) { 3926 3927 *index = i; 3928 in_use_array[mem_idx] = 1; 3929 BCMI_FT_CHIP_DEBUG_PARAM(unit, p_idx).mem_id = mem_idx; 3930 BCMI_FT_CHIP_DEBUG_PARAM(unit, p_idx).alu_type = alu_load_type; 3931 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 3932 (BSL_META_U(unit, "mem_idx = %d, index = %d\n"), 3933 mem_idx, *index)); 3934 3935 return BCM_E_NONE; 3936 } 3937 } 3938 3939 return BCM_E_RESOURCE; 3940 } 3941 3942 3943 /* 3944 * Function: 3945 * bcmi_ft_chip_debug_free_alu_index 3946 * Purpose: 3947 * Get ALU/Load type based on length/params. 3948 * Parameters: 3949 * unit - (IN) BCM device id. 3950 * id - (IN) FT group id. 3951 * alu_load_type - (IN) type of load/ALU. 3952 * index - (OUT) Free index of that memory. 3953 * Returns: 3954 * BCM_E_XXX 3955 */ 3956 void 3957 bcmi_ft_chip_debug_free_alu_index ( 3958 int unit, 3959 bcmi_ft_group_alu_info_t *group_alu_info, 3960 bcmi_ft_alu_load_type_t alu_load_type) 3961 { 3962 3963 int i = 0; 3964 int *in_use_array = NULL; 3965 int *ref_count = NULL; 3966 int mem_idx = -1; 3967 3968 if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) { 3969 return; 3970 } 3971 3972 if (group_alu_info == NULL) { 3973 return; 3974 } 3975 3976 if ((alu_load_type != bcmiFtAluLoadTypeAlu32) && 3977 (alu_load_type != bcmiFtAluLoadTypeAlu16)) { 3978 3979 return; 3980 } 3981 3982 /* Get the free memory index of this type of memory. */ 3983 if (alu_load_type == bcmiFtAluLoadTypeAlu16) { 3984 in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_mem_used; 3985 ref_count = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_ref_count; 3986 } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) { 3987 in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_mem_used; 3988 ref_count = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_ref_count; 3989 } 3990 3991 3992 for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) { 3993 if (group_alu_info->element_type1 == 3994 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).param) { 3995 mem_idx = BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id; 3996 3997 break; 3998 } 3999 } 4000 4001 if (i == BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info) { 4002 /* Nothing matching found. so just return. */ 4003 return; 4004 } 4005 4006 ref_count[mem_idx]--; 4007 4008 in_use_array[mem_idx] = ((ref_count[mem_idx]) ? 1 : 0); 4009 4010 /* 4011 * Now that ref_count on this memory index is 0. 4012 * We should remove the association with tracking param too. 4013 */ 4014 4015 4016 return; 4017 } 4018 4019 4020 4021 int 4022 bcmi_ft_chip_debug_data_sanity( 4023 int unit, 4024 int num_info, 4025 bcm_flowtracker_chip_debug_info_t *info) 4026 { 4027 4028 int num_groups = 0; 4029 int i, j, k; 4030 int num_tracking_elements = 0; 4031 soc_mem_t mem; 4032 bcm_flowtracker_tracking_param_info_t *track_info = NULL; 4033 bcm_flowtracker_tracking_param_type_t param; 4034 4035 /* associate the memory. */ 4036 mem = BSC_KG_GROUP_TABLEm; 4037 4038 /* Total number of groups in device. */ 4039 num_groups = soc_mem_index_count(unit, mem); 4040 4041 for (j=0; j<num_info; j++) { 4042 param = info[j].param; 4043 4044 for (i=0; i<num_groups; i++) { 4045 if (bcmi_ft_group_is_invalid(unit, i)) { 4046 continue; 4047 } 4048 4049 num_tracking_elements = BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, i); 4050 if (!num_tracking_elements) { 4051 continue; 4052 } 4053 4054 4055 track_info = BCMI_FT_GROUP_TRACK_PARAM(unit, i); 4056 if (!track_info) { 4057 continue; 4058 } 4059 4060 for (k=0; k<num_tracking_elements; k++) { 4061 if (param == track_info[k].param) { 4062 return BCM_E_BUSY; 4063 } 4064 } 4065 } 4066 } 4067 4068 return BCM_E_NONE; 4069 4070 } 4071 4072 /* 4073 * Function: 4074 * bcmi_ft_group_alu_load_index_match_data_get 4075 * Purpose: 4076 * Get matching data for this alu index. 4077 * Parameters: 4078 * unit - (IN) BCM device id 4079 * id - (IN) FT group id. 4080 * alu_type - (IN) ALU type. 4081 * iter - (IN) alu memory iterator. 4082 * temp - (OUT) Pointer to point to data. 4083 * 4084 * Returns: 4085 * BCM_E_XXX 4086 */ 4087 int 4088 bcmi_ft_group_alu_load_index_match_data_get( 4089 int unit, 4090 bcm_flowtracker_group_t id, 4091 bcmi_ft_alu_load_type_t alu_type, 4092 int iter, 4093 bcmi_ft_group_alu_info_t **temp) 4094 { 4095 4096 int start_index=0, j=0, i=0; 4097 int num_alus_loads = 0; 4098 int mem_size = 0; 4099 4100 for (; j<iter; j++) { 4101 mem_size = 4102 alu_load_index_info[unit][alu_type]. 4103 alu_load_info[j].mem_size; 4104 start_index += mem_size; 4105 } 4106 4107 num_alus_loads = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info; 4108 4109 (*temp) = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 4110 mem_size = alu_load_index_info[unit][alu_type]. 4111 alu_load_info[iter].mem_size; 4112 4113 for (; i<num_alus_loads; i++) { 4114 4115 if ((*temp)->alu_load_type == alu_type) { 4116 if (((*temp)->alu_load_index >= start_index) && 4117 ((*temp)->alu_load_index < (start_index + mem_size))) { 4118 return BCM_E_NONE; 4119 } 4120 } 4121 (*temp)++; 4122 } 4123 4124 return BCM_E_NOT_FOUND; 4125 } 4126 4127 /* 4128 * Function: 4129 * bcmi_ft_group_alu_load_pdd_status_get 4130 * Purpose: 4131 * Get pdd status for this alu memory. 4132 * Parameters: 4133 * unit - (IN) BCM device id 4134 * id - (IN) FT group id. 4135 * alu_type - (IN) ALU type. 4136 * iter - (IN) alu memory iterator. 4137 * 4138 * Returns: 4139 * 1 = set 4140 * 0 = Not set. 4141 */ 4142 int 4143 bcmi_ft_group_alu_load_pdd_status_get( 4144 int unit, 4145 bcm_flowtracker_group_t id, 4146 bcmi_ft_alu_load_type_t alu_type, 4147 int iter) 4148 { 4149 /* 4150 * No need to check validity of group and other params. 4151 * If we are here so that all other checks are done. 4152 */ 4153 4154 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 4155 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 4156 (BCMI_FT_PDD_INFO(unit, alu_type)[iter]).param_id)) { 4157 4158 return 1; 4159 } 4160 4161 return 0; 4162 } 4163 4164 #else /* BCM_FLOWTRCAKER_SUPPORT*/ 4165 int bcmi_ft_alu_load_hw_not_empty; 4166 #endif /* BCM_FLOWTRCAKER_SUPPORT */