flowtracker.c (19097B)
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 * Flowtracker - Flow Tracking embedded APP interface 8 * Purpose: API to configure flowtracker embedded app interface. 9 */ 10 #if defined(INCLUDE_FLOWTRACKER) 11 12 #include <shared/bsl.h> 13 #include <soc/defs.h> 14 #include <soc/drv.h> 15 #include <soc/format.h> 16 #include <soc/tomahawk.h> 17 #include <shared/alloc.h> 18 #include <shared/idxres_fl.h> 19 20 #include <bcm/types.h> 21 #include <bcm/error.h> 22 23 #include <bcm_int/esw/flowtracker.h> 24 #include <bcm_int/esw/tomahawk.h> 25 #include <bcm_int/esw/maverick2.h> 26 #include <bcm_int/esw/xgs5.h> 27 #include <bcm_int/esw/switch.h> 28 29 /* 30 * Function: 31 * _bcm_mv2_flowtracker_config_init 32 * Purpose: 33 * Validate config variables. 34 * Program FLOW_TRACKER_CONFIG register as per config variables. 35 * Program HASH_CONTROL register to enable FT in hw. 36 * Program FT_GROUP_TABLE_CONFIG index 0 with thresold value 0. 37 * Parameters: 38 * unit - (IN) BCM device number 39 * Returns: 40 * BCM_E_XXX - BCM error code. 41 * Notes: 42 * This api should be called only if flow tracker is enabled 43 * using config variable "flowtracker_enable". Check is done 44 * before calling api. 45 */ 46 int 47 _bcm_mv2_flowtracker_config_init(int unit, _bcm_int_ft_info_t *ft_info) 48 { 49 uint32 hash_control = 0; 50 ft_group_table_config_entry_t ft_grp_entry; 51 uint32 ft_config = 0; 52 uint32 ft_max_flows = 0; 53 uint32 ft_max_counters_per_flow = 0; 54 uint8 ft_table_mode = 0; 55 uint8 ft_cntr_alloc_mode = 0; 56 57 /* Validate input variable */ 58 if (ft_info == NULL) { 59 return BCM_E_PARAM; 60 } 61 62 /* Initialise variables */ 63 sal_memset(&ft_grp_entry, 0, sizeof(ft_grp_entry)); 64 65 /* Step 1: Validate config variables "flowtracker_max_flows" 66 * and "flowtracker_max_counters_per_flow" 67 */ 68 ft_max_flows = soc_property_get(unit,spn_FLOWTRACKER_MAX_FLOWS, 69 BCM_INT_FT_DEF_MAX_FLOWS); 70 ft_max_counters_per_flow = soc_property_get(unit,spn_FLOWTRACKER_MAX_COUNTERS_PER_FLOW, 71 BCM_INT_FT_DEF_MAX_COUNTERS_PER_FLOW); 72 if (!(ft_max_counters_per_flow == 1 || 73 ft_max_counters_per_flow == 2 || 74 ft_max_counters_per_flow == 4)) { 75 return BCM_E_CONFIG; 76 } 77 78 if (!(ft_max_flows == 16384 || 79 ft_max_flows == 32768)) { 80 return BCM_E_CONFIG; 81 } 82 83 if (ft_max_flows == 32768 && ft_max_counters_per_flow == 1) { 84 ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_MIXED_MODE1_ID; 85 } else if (ft_max_flows == 32768 && ft_max_counters_per_flow == 2) { 86 ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_MIXED_MODE2_ID; 87 } else if (ft_max_flows == 16384 && ft_max_counters_per_flow == 1) { 88 ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_QW_MODE1_ID; 89 } else if (ft_max_flows == 16384 && ft_max_counters_per_flow == 2) { 90 ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_QW_MODE2_ID; 91 } else if (ft_max_flows == 16384 && ft_max_counters_per_flow == 4) { 92 ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_QW_MODE3_ID; 93 } else { 94 return (BCM_E_CONFIG); 95 } 96 97 /* Step 2: Configure FLOW_TRACKER_CONFIG register as per mode 98 * decided in step 1 */ 99 if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE1_ID) { 100 ft_table_mode = 0; 101 ft_cntr_alloc_mode = 0; 102 } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE2_ID) { 103 ft_table_mode = 0; 104 ft_cntr_alloc_mode = 1; 105 } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE1_ID) { 106 ft_table_mode = 1; 107 ft_cntr_alloc_mode = 0; 108 } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE2_ID) { 109 ft_table_mode = 1; 110 ft_cntr_alloc_mode = 1; 111 } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE3_ID) { 112 ft_table_mode = 1; 113 ft_cntr_alloc_mode = 2; 114 } else { 115 return (BCM_E_CONFIG); 116 } 117 118 soc_reg_field_set(unit, FLOW_TRACKER_CONFIGr, 119 &ft_config, FLOW_TABLE_MODEf, ft_table_mode); 120 soc_reg_field_set(unit, FLOW_TRACKER_CONFIGr, 121 &ft_config, FLEX_CNTR_ALLOC_MODf, ft_cntr_alloc_mode); 122 BCM_IF_ERROR_RETURN(WRITE_FLOW_TRACKER_CONFIGr(unit, ft_config)); 123 124 /* Step 3: Enable flow tracking using exact match table */ 125 BCM_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &hash_control)); 126 127 soc_reg_field_set(unit, HASH_CONTROLr, 128 &hash_control, FLOW_TRACKER_ENABLEf, 1); 129 130 BCM_IF_ERROR_RETURN(WRITE_HASH_CONTROLr(unit, hash_control)); 131 132 /* Step 4: Reserve GROUP ID 0 and program it with threshold value 0 */ 133 BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL, 134 0, &ft_grp_entry)); 135 136 return BCM_E_NONE; 137 } 138 139 /* 140 * Function: 141 * _bcm_mv2_flowtracker_config_detach 142 * Purpose: 143 * Disable flow tracker module in hardware. 144 * Parameters: 145 * unit - (IN) BCM device number 146 * Returns: 147 * BCM_E_XXX - BCM error code. 148 */ 149 int 150 _bcm_mv2_flowtracker_config_detach(int unit) 151 { 152 uint32 hash_control = 0; 153 uint32 ft_config = 0; 154 155 BCM_IF_ERROR_RETURN(WRITE_FLOW_TRACKER_CONFIGr(unit, ft_config)); 156 157 /* Disable flow tracking using exact match table */ 158 BCM_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &hash_control)); 159 160 soc_reg_field_set(unit, HASH_CONTROLr, 161 &hash_control, FLOW_TRACKER_ENABLEf, 0); 162 163 BCM_IF_ERROR_RETURN(WRITE_HASH_CONTROLr(unit, hash_control)); 164 165 return BCM_E_NONE; 166 } 167 168 /* 169 * Function: 170 * _bcm_mv2_flowtracker_config_mode_pools_get 171 * Purpose: 172 * Get number of stats reserved for provided flow tracker config mode. 173 * Parameters: 174 * unit - (IN) BCM device number 175 * ft_config_mode - (IN) Flow Tracker Config Mode 176 * no_of_stats - (OUT) Number of flex counters reserved 177 * Returns: 178 * BCM_E_XXX - BCM error code. 179 */ 180 int 181 _bcm_mv2_flowtracker_config_mode_stats_get(int unit, 182 uint8 ft_config_mode, 183 uint32 *no_of_stats) 184 { 185 /* Validate input variable */ 186 if (no_of_stats == NULL) { 187 return (BCM_E_PARAM); 188 } 189 190 if (ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE1_ID) { 191 *no_of_stats = MV2_FT_CONFIG_MODE_MIXED_MODE1_FLEX_COUNTERS; 192 } else if (ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE2_ID) { 193 *no_of_stats = MV2_FT_CONFIG_MODE_MIXED_MODE2_FLEX_COUNTERS; 194 } else if (ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE1_ID) { 195 *no_of_stats = MV2_FT_CONFIG_MODE_QW_MODE1_FLEX_COUNTERS; 196 } else if (ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE2_ID) { 197 *no_of_stats = MV2_FT_CONFIG_MODE_QW_MODE2_FLEX_COUNTERS; 198 } else if (ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE3_ID) { 199 *no_of_stats = MV2_FT_CONFIG_MODE_QW_MODE3_FLEX_COUNTERS; 200 } else { 201 return (BCM_E_PARAM); 202 } 203 204 return (BCM_E_NONE); 205 } 206 207 /* 208 * Function: 209 * _bcm_mv2_ft_group_flex_policy_data_set 210 * Purpose: 211 * Set data ub entry buffer at specified offset and given width. 212 * Parameters: 213 * p_fn_data - (IN/OUT) Update with p_data value 214 * p_data - (IN) data 215 * offset - (IN) Offset in p_fn_data 216 * width - (IN) Width of data 217 * Returns: 218 * BCM_E_XXX - BCM error code. 219 */ 220 STATIC int 221 _bcm_mv2_ft_group_flex_policy_data_set(uint32 *p_fn_data, 222 uint32 *p_data, 223 uint32 offset, 224 uint32 width) 225 { 226 uint32 u32_mask; 227 int idx, wp, bp, len; 228 229 if (NULL == p_fn_data || NULL == p_data) { 230 LOG_VERBOSE(BSL_LS_BCM_FLOWTRACKER, (BSL_META("Invalid Parameters\n"))); 231 return BCM_E_PARAM; 232 } 233 234 wp = offset / 32; 235 bp = offset & (32 - 1); 236 idx = 0; 237 238 for (len = width; len > 0; len -= 32) { 239 if (bp) { 240 if (len < 32) { 241 u32_mask = (1 << len) - 1; 242 if ((p_data[idx] & ~u32_mask) != 0) { 243 return (BCM_E_PARAM); 244 } 245 } else { 246 u32_mask = 0xffffffff; 247 } 248 249 p_fn_data[wp] &= ~(u32_mask << bp); 250 p_fn_data[wp++] |= p_data[idx] << bp; 251 p_fn_data[wp] &= ~(u32_mask >> (32 - bp)); 252 p_fn_data[wp] |= p_data[idx] >> (32 - bp) & ((1 << bp) - 1); 253 254 } else { 255 if (len < 32) { 256 u32_mask = (1 << len) - 1; 257 if ((p_data[idx] & ~u32_mask) != 0) { 258 return (BCM_E_PARAM); 259 } 260 p_fn_data[wp] &= ~u32_mask; 261 p_fn_data[wp++] |= p_data[idx]; 262 } else { 263 p_fn_data[wp++] = p_data[idx]; 264 } 265 } 266 267 idx++; 268 } 269 270 return BCM_E_NONE; 271 } 272 273 274 /* 275 * Function: 276 * _bcm_mv2_flowtracker_flow_group_default_config_set 277 * Purpose: 278 * Sets Default Flowtracker group properties when created. 279 * Parameters: 280 * unit - (IN) BCM device number 281 * id - (IN) Flowtracker Group Id 282 * Returns: 283 * BCM_E_XXX - BCM error code. 284 * Notes: 285 * When Flow Tracker Group is created, certain properties like 286 * flex stat mode and enable_disable control need to be programmed 287 * by default. This api will program certain flow tracker group 288 * level properties. 289 */ 290 291 int 292 _bcm_mv2_flowtracker_flow_group_default_config_set(int unit, 293 bcm_flowtracker_group_t id) 294 { 295 uint32 fmt_len = 0; 296 uint32 meter_data_buf = 0; 297 soc_field_info_t *field_info = NULL; 298 ft_group_table_config_entry_t ft_grp_config_entry; 299 300 /* Initialise Flow Group Entry */ 301 sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry)); 302 303 /* Read entry at given ft group index */ 304 BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit, 305 MEM_BLOCK_ANY, id, &ft_grp_config_entry)); 306 307 /* Enable Flex Stat on Flow Group by default */ 308 soc_FT_GROUP_TABLE_CONFIGm_field32_set(unit, 309 &ft_grp_config_entry, 310 FIXED_ASSOCIATED_DATAf, 311 1 << MV2_FT_FLEX_STAT_ENABLE_BIT); 312 313 /* Set default flex stat mode */ 314 315 /* METER_PAIR_MODE_MODIFIER must be set for EM to see the incoming color. 316 * This is needed for EM to apply ColorAware actions in ETRAP mode. However 317 * setting this bit can be done unconditionally as it does not do anything 318 * if no actions are applied. 319 */ 320 field_info = soc_mem_fieldinfo_get(unit, 321 FT_GROUP_TABLE_CONFIGm, FLEX_POLICY_DATAf); 322 if (field_info != NULL) { 323 /* Set Meter_pair_mode_modifier */ 324 soc_format_field32_set(unit, IFP_METER_SETfmt, 325 &meter_data_buf, 326 METER_PAIR_MODE_MODIFIERf, 1); 327 328 /* Get length of format */ 329 fmt_len = soc_format_field_length(unit, IFP_METER_SETfmt, METERf); 330 331 /* Set Flex policy Data in FT_GROUP_TABLE_CONFIGm */ 332 BCM_IF_ERROR_RETURN(_bcm_mv2_ft_group_flex_policy_data_set( 333 (uint32 *)&ft_grp_config_entry, 334 &meter_data_buf, field_info->bp, fmt_len)); 335 } 336 337 /* Set default flow tracker group property */ 338 BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL, 339 id, &ft_grp_config_entry)); 340 return BCM_E_NONE; 341 } 342 343 /* 344 * Function: 345 * _bcm_mv2_flowtracker_flow_group_config_clear 346 * Purpose: 347 * Clears Flowtracker group properties. 348 * Parameters: 349 * unit - (IN) BCM device number 350 * id - (IN) Flowtracker Group Id 351 * Returns: 352 * BCM_E_XXX - BCM error code. 353 */ 354 int 355 _bcm_mv2_flowtracker_flow_group_config_clear(int unit, 356 bcm_flowtracker_group_t id) 357 { 358 soc_mem_t mem = FT_GROUP_TABLE_CONFIGm; 359 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 360 id, soc_mem_entry_null(unit, mem))); 361 return BCM_E_NONE; 362 } 363 364 /* 365 * Function: 366 * _bcm_mv2_flowtracker_flow_group_flow_limit_set 367 * Purpose: 368 * Set Flow Threshold limit associated to a Flowtracker group. 369 * Determines number of maximum flow allowed to be learnt on a flow. 370 * Parameters: 371 * unit - (IN) BCM device number 372 * id - (IN) Flowtracker Group Id 373 * flow_limit - (IN) Threshold of flow allowed to learn in Flowtracker group. 374 * Returns: 375 * BCM_E_XXX - BCM error code. 376 */ 377 int 378 _bcm_mv2_flowtracker_flow_group_flow_limit_set(int unit, 379 bcm_flowtracker_group_t id, 380 uint32 flow_limit) 381 { 382 ft_group_table_config_entry_t ft_grp_config_entry; 383 384 /* Initialise Flow Group Entry */ 385 sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry)); 386 387 /* Read entry at given ft group index */ 388 BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit, 389 MEM_BLOCK_ANY, id, &ft_grp_config_entry)); 390 391 /* Set Flow Thresold Limit in entry buffer */ 392 soc_FT_GROUP_TABLE_CONFIGm_field32_set(unit, 393 &ft_grp_config_entry, 394 FLOW_THRESHOLDf, flow_limit); 395 396 /* Set FLow Threshold Limit in a flow tracker group */ 397 BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL, 398 id, &ft_grp_config_entry)); 399 return BCM_E_NONE; 400 } 401 402 /* 403 * Function: 404 * _bcm_mv2_flowtracker_flow_group_flow_limit_get 405 * Purpose: 406 * Get Flow Threshold limit associated to a Flowtracker group. 407 * Determines number of maximum flow allowed to be learnt on a flow. 408 * Parameters: 409 * unit - (IN) BCM device number 410 * id - (IN) Flowtracker Group Id 411 * flow_limit - (OUT) Threshold of flow allowed to learn in Flowtracker group. 412 * Returns: 413 * BCM_E_XXX - BCM error code. 414 */ 415 int 416 _bcm_mv2_flowtracker_flow_group_flow_limit_get(int unit, 417 bcm_flowtracker_group_t id, 418 uint32 *flow_limit) 419 { 420 ft_group_table_config_entry_t ft_grp_config_entry; 421 422 /* Initialise Flow Group Entry */ 423 sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry)); 424 425 /* Read entry at given ft group index */ 426 BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit, 427 MEM_BLOCK_ANY, id, &ft_grp_config_entry)); 428 429 *flow_limit = soc_FT_GROUP_TABLE_CONFIGm_field32_get(unit, 430 &ft_grp_config_entry, FLOW_THRESHOLDf); 431 432 return BCM_E_NONE; 433 } 434 435 /* 436 * Function: 437 * _bcm_mv2_flowtracker_flow_group_stat_modeid_set 438 * Purpose: 439 * Set Stat Modeid to a Flowtracker group. 440 * Determines offset for counters to increment based on packet attributes. 441 * Parameters: 442 * unit - (IN) BCM device number 443 * id - (IN) Flowtracker Group Id 444 * stat_modeid - (IN) Stat Modeid to be associated to a group 445 * Returns: 446 * BCM_E_XXX - BCM error code. 447 */ 448 int 449 _bcm_mv2_flowtracker_flow_group_stat_modeid_set(int unit, 450 bcm_flowtracker_group_t id, 451 uint32 stat_modeid) 452 { 453 ft_group_table_config_entry_t ft_grp_config_entry; 454 uint32 flex_counter_enable = 0; 455 uint32 flex_stat_modeid = 0; 456 uint32 fixed_assoc_data = 0; 457 458 /* Initialise Flow Group Entry */ 459 sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry)); 460 461 /* Read entry at given ft group index */ 462 BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit, 463 MEM_BLOCK_ANY, id, &ft_grp_config_entry)); 464 465 flex_counter_enable = 1 << MV2_FT_FLEX_STAT_ENABLE_BIT; 466 flex_stat_modeid = stat_modeid << MV2_FT_FLEX_STAT_MODEID_BIT; 467 fixed_assoc_data = flex_counter_enable | flex_stat_modeid; 468 469 /* Set Stat Modeid in entry buffer */ 470 soc_FT_GROUP_TABLE_CONFIGm_field32_set(unit, 471 &ft_grp_config_entry, 472 FIXED_ASSOCIATED_DATAf, 473 fixed_assoc_data); 474 475 /* Set Stat Modeid in a flow tracker group */ 476 BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL, 477 id, &ft_grp_config_entry)); 478 return BCM_E_NONE; 479 } 480 481 /* 482 * Function: 483 * _bcm_mv2_flowtracker_flow_group_stat_modeid_get 484 * Purpose: 485 * Get Stat Modeid associated to a Flowtracker group. 486 * Determines offset for counters to increment based on packet attributes. 487 * Parameters: 488 * unit - (IN) BCM device number 489 * id - (IN) Flowtracker Group Id 490 * stat_modeid - (OUT) Stat Modeid associated to a group 491 * Returns: 492 * BCM_E_XXX - BCM error code. 493 */ 494 int 495 _bcm_mv2_flowtracker_flow_group_stat_modeid_get(int unit, 496 bcm_flowtracker_group_t id, 497 uint32 *stat_modeid) 498 { 499 ft_group_table_config_entry_t ft_grp_config_entry; 500 uint32 fixed_assoc_data = 0; 501 502 /* Initialise Flow Group Entry */ 503 sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry)); 504 505 /* Read entry at given ft group index */ 506 BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit, 507 MEM_BLOCK_ANY, 508 id, &ft_grp_config_entry)); 509 510 fixed_assoc_data = soc_FT_GROUP_TABLE_CONFIGm_field32_get(unit, 511 &ft_grp_config_entry, FIXED_ASSOCIATED_DATAf); 512 513 *stat_modeid = fixed_assoc_data >> MV2_FT_FLEX_STAT_MODEID_BIT & 0x3; 514 515 return BCM_E_NONE; 516 } 517 518 /* 519 * Function: 520 * _bcm_mv2_flowtracker_flow_group_flow_count_get 521 * Purpose: 522 * Retreive Flow Count associated to a Flowtracker group. 523 * Determines number of flow learnt in a group. 524 * Parameters: 525 * unit - (IN) BCM device number 526 * id - (IN) Flowtracker Group Id 527 * flow_count - (OUT) No. of flows learnt in Flowtracker group. 528 * Returns: 529 * BCM_E_XXX - BCM error code. 530 */ 531 int 532 _bcm_mv2_flowtracker_flow_group_flow_count_get(int unit, 533 bcm_flowtracker_group_t id, 534 uint32 *flow_count) 535 { 536 ft_group_table_cnt_entry_t ft_grp_cnt_entry; 537 538 /* Initialise Flow Group Entry */ 539 sal_memset(&ft_grp_cnt_entry, 0, sizeof(ft_grp_cnt_entry)); 540 541 /* Read entry at given ft group index */ 542 BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CNTm(unit, 543 MEM_BLOCK_ANY, id, &ft_grp_cnt_entry)); 544 545 /* Retreive Flow Count for a flow tracker group */ 546 *flow_count = soc_FT_GROUP_TABLE_CNTm_field32_get(unit, 547 &ft_grp_cnt_entry, FLOW_CNTf); 548 549 return BCM_E_NONE; 550 } 551 552 #else /* INCLUDE_FLOWTRACKER */ 553 int _bcm_mv2_ft_not_empty; 554 #endif /* INCLUDE_FLOWTRACKER */