udf.c (104534B)
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 * All Rights Reserved.$ 7 * 8 * File: udf.c 9 * Purpose: BCM56870 Field Processor functions. 10 */ 11 12 #include <soc/defs.h> 13 #if defined(BCM_TRIDENT3_SUPPORT) 14 #include <shared/bsl.h> 15 #include <soc/mem.h> 16 #include <soc/drv.h> 17 #include <soc/tomahawk.h> 18 #include <soc/field.h> 19 #include <soc/format.h> 20 #include <soc/scache.h> 21 #include <soc/error.h> 22 #include <shared/bitop.h> 23 #include "include/soc/esw/cancun.h" 24 #include <include/soc/mcm/formatacc.h> 25 #include <bcm/error.h> 26 #include <bcm/module.h> 27 28 #include <bcm/udf.h> 29 #include <bcm_int/esw/udf.h> 30 31 #if defined (BCM_WARM_BOOT_SUPPORT) 32 /* Warmboot Versions */ 33 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1, 0) 34 #define BCM_WB_VERSION_2_0 SOC_SCACHE_VERSION(2, 0) 35 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_2_0 36 #endif /* BCM_WARM_BOOT_SUPPORT */ 37 38 /* Maximum number of UDF objects - (Max Chunks * number of pkt abstracts) */ 39 #define _BCM_UDF_TD3_MAX_OBJECTS(_u_) \ 40 (_BCM_UDF_CTRL_MAX_UDF_CHUNKS(_u_) * bcmUdfAbstractPktFormatLastCount) 41 42 /* UDF Object Min and Max Values. */ 43 #define _BCM_UDF_TD3_OBJ_MIN_ID 0x1 44 #define _BCM_UDF_TD3_OBJ_MAX_ID 0xfffe 45 46 /* UDF Parse limit supported by SRC_PKT_OFFSET in CMD_POLICY_DATA */ 47 #define _BCM_UDF_TD3_MAX_PARSE_LIMIT 128 48 49 /* Number of commands dedicated to UDF in CMD_POLICY_DATAf */ 50 #define _BCM_UDF_MAX_POLICY_CMDS 8 51 52 /* Device Parser level from which UDF is extracted */ 53 #define _BCM_UDF_PARSER0 3 54 #define _BCM_UDF_PARSER1 1 55 #define _BCM_UDF_PARSER2 2 56 57 /* Global UDF control structure pointers */ 58 _bcm_udf_td3_ctrl_t *udf_td3_control[BCM_MAX_NUM_UNITS]; 59 60 #define UDF_TD3_CTRL(_u_) udf_td3_control[_u_] 61 62 /* 63 * UDF Container Chunks (2 bytes each) to Destination container ID mapping. 64 * 65 * UDF Chunks Container ID 66 * ========== ============ 67 * UDF1_0 CONT_20 68 * UDF1_1 CONT_19 69 * UDF1_2 CONT_18 70 * UDF1_3 CONT_17 71 * UDF1_4 CONT_16 72 * UDF1_5 CONT_15 73 * UDF1_6 CONT_14 74 * UDF1_7 CONT_13 75 * UDF2_0 CONT_28 76 * UDF2_1 CONT_27 77 * UDF2_2 CONT_26 78 * UDF2_3 CONT_25 79 * UDF2_4 CONT_24 80 * UDF2_5 CONT_23 81 * UDF2_6 CONT_22 82 * UDF2_7 CONT_21 83 */ 84 STATIC 85 uint8 _bcm_udf_chunk_to_dest_cont_id_mapping[16] = 86 {20, 19, 18, 17, 16, 15, 14, 13, 28, 27, 26, 25, 24, 23, 22, 21}; 87 88 /* Opaque to UDF chunks */ 89 STATIC 90 uint8 _bcm_udf_opaque_cont_to_chunk_mapping[16] = 91 {7, 6, 5 ,4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8}; 92 93 /* Range Check supported UDF Chunk - UDF1_CHUNK2 */ 94 #define _BCM_UDF_TD3_RANGE_CHUNK_BMAP 0x4 95 96 /* Maximum number of Chunks Supported. */ 97 #define _BCM_UDF_TD3_MAX_CHUNKS 16 98 99 /* Maximum Chunk Bitmap. */ 100 #define _BCM_UDF_TD3_MAX_CHUNK_BMAP 0xffff 101 102 /* 103 * Global Variable to hold Abstract 104 * Packet format HW information. 105 */ 106 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *abstr_pkt_fmt_hw_info[BCM_MAX_NUM_UNITS][bcmUdfAbstractPktFormatLastCount]; 107 108 /* 109 * Macro to retrieve pointer to _bcm_udf_td3_abstr_pkt_fmt_hw_info_t 110 * structure for a given abstr pkt format. 111 */ 112 #define _UDF_ABSTR_PKT_FMT_HW_INFO_GET(_u_, _pkt_fmt_) \ 113 abstr_pkt_fmt_hw_info[_u_][_pkt_fmt_] 114 115 116 /* UDF Byte to Chunk Conversion */ 117 #define _BCM_UDF_BYTE_TO_CHUNK(_val_) (_val_/2) 118 119 /* UDF Chunk to Byte Conversion */ 120 #define _BCM_UDF_CHUNK_TO_BYTE(_val_) (_val_ * 2) 121 122 /* Validate Abstract Packet format */ 123 #define _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(_u_, _pkt_fmt_) \ 124 do { \ 125 if ((_pkt_fmt_ < bcmUdfAbstractPktFormatLlc) || \ 126 (_pkt_fmt_ >= bcmUdfAbstractPktFormatLastCount)) { \ 127 return BCM_E_PARAM; \ 128 } \ 129 if (abstr_pkt_fmt_hw_info[_u_][_pkt_fmt_]->max_extract_bytes == 0) { \ 130 return BCM_E_UNAVAIL; \ 131 } \ 132 } while (0) 133 134 /* Validate Extraction bytes for a given packet format */ 135 #define _BCM_UDF_EXTRACTION_BYTES_VALIDATE(_u_, _pkt_format_, _bytes_) \ 136 do { \ 137 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *_pkt_format_hw_info_ = NULL; \ 138 \ 139 _pkt_format_hw_info_ = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(_u_, _pkt_format_); \ 140 if (_pkt_format_hw_info_ == NULL) { \ 141 return BCM_E_INTERNAL; \ 142 } \ 143 if (_bytes_ > (_pkt_format_hw_info_->max_extract_bytes - \ 144 _pkt_format_hw_info_->extracted_bytes)) { \ 145 return BCM_E_CONFIG; \ 146 } \ 147 } while(0) 148 149 /* Validate chunk */ 150 #define _BCM_UDF_CHUNK_VALIDATE(_u_, _chunk_bmap_, _pkt_fmt_) \ 151 do { \ 152 uint32 _unavail_cbmap; \ 153 if ((_chunk_bmap_ == 0x0) || \ 154 (_chunk_bmap_ > _BCM_UDF_TD3_MAX_CHUNK_BMAP)) { \ 155 return BCM_E_PARAM; \ 156 } \ 157 _unavail_cbmap = abstr_pkt_fmt_hw_info[_u_][_pkt_fmt_]->unavail_chunk_bmap; \ 158 if (_unavail_cbmap & _chunk_bmap_) { \ 159 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, \ 160 "The chunks in the given chunk bitmap are reserved/unavailable: 0x%x\n\r"), \ 161 _unavail_cbmap & _chunk_bmap_)); \ 162 return BCM_E_CONFIG; \ 163 } \ 164 } while(0) 165 166 /* Validate Chunk bitmap */ 167 #define _BCM_UDF_OBJECT_CHUNK_IN_USE_VALIDATE(_u_, _pkt_format_, _chunk_bmap_) \ 168 do { \ 169 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *_pkt_format_hw_info_ = NULL; \ 170 \ 171 _pkt_format_hw_info_ = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(_u_, _pkt_format_); \ 172 if (_pkt_format_hw_info_ == NULL) { \ 173 return BCM_E_INTERNAL; \ 174 } \ 175 if (_pkt_format_hw_info_->chunk_bmap_used & _chunk_bmap_) { \ 176 return BCM_E_CONFIG; \ 177 } \ 178 } while(0) 179 180 /* 181 * Typedef: 182 * _BCM_UDF_ABSTRACT_PKT_FORMAT_MAPPING_DECL 183 */ 184 #define _BCM_UDF_ABSTRACT_PKT_FORMAT_MAPPING_DECL \ 185 int _rv_; \ 186 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t _pkt_fmt_hw_cfg_; 187 188 /* 189 * Typedef: 190 * _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT 191 * Purpose: 192 * Insert UDF abstract packet format configuration. 193 */ 194 #define _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(_unit_, _pkt_format_, _parser_) \ 195 do { \ 196 uint8 _stg_; \ 197 sal_memset(&_pkt_fmt_hw_cfg_, 0x0, \ 198 sizeof(_bcm_udf_td3_abstr_pkt_fmt_hw_info_t)); \ 199 (_pkt_fmt_hw_cfg_).parser = (_parser_); \ 200 (_pkt_fmt_hw_cfg_).base_offset = 0x0; \ 201 (_pkt_fmt_hw_cfg_).max_extract_bytes = 0x0; \ 202 for (_stg_ = 0; _stg_ < _BCM_UDF_MAX_PARSER_STAGES; _stg_++) { \ 203 (_pkt_fmt_hw_cfg_).stage_policy_mem[_stg_] = INVALIDm; \ 204 (_pkt_fmt_hw_cfg_).hfe_prof_ptr_arr_len[_stg_] = 0; \ 205 (_pkt_fmt_hw_cfg_).hfe_profile_ptr[_stg_] = NULL; \ 206 } \ 207 _rv_ = _bcm_udf_td3_abstr_pkt_fmt_hw_info_insert((_unit_), \ 208 (_pkt_format_), &(_pkt_fmt_hw_cfg_)); \ 209 BCM_IF_ERROR_RETURN(_rv_); \ 210 } while(0) 211 212 213 /* 214 * Macros to manage (add, delete, get) the Object Node 215 */ 216 #define _BCM_UDF_OBJ_NODE_ADD(_u_, _new_, _head_) \ 217 _UDF_DLL_NODE_ADD(_u_, _new_, _head_) 218 219 #define _BCM_UDF_OBJ_NODE_DEL(_u_, _del_, _head_) \ 220 do { \ 221 _bcm_udf_td3_obj_info_t *_temp_; \ 222 _UDF_DLL_NODE_DEL(_u_, _del_, _head_, _temp_); \ 223 } while (0) 224 225 #define _BCM_UDF_OBJ_NODE_GET(_u_, _id_, _head_, _node_) \ 226 do { \ 227 _bcm_udf_td3_obj_info_t *_temp_; \ 228 _UDF_DLL_NODE_GET(_u_, _id_, _head_, _temp_, _node_); \ 229 } while (0) 230 231 #define _BCM_UDF_OBJ_NODE_DEL_ALL(_u_, _head_) \ 232 do { \ 233 _bcm_udf_td3_obj_info_t *_temp_; \ 234 while(_head_ != NULL) { \ 235 _temp_ = _head_; \ 236 _BCM_UDF_OBJ_NODE_DEL(_u_, _temp_, _head_); \ 237 _BCM_UDF_FREE(_temp_); \ 238 } \ 239 } while (0) 240 241 #define _BCM_UDF_OBJ_NODE_NEXT(_node_) \ 242 _node_ = _node_->prev; 243 244 245 soc_field_t src_pkt_offset_p0_cmds[8] = { 246 INVALIDf, 247 INVALIDf, 248 INVALIDf, 249 INVALIDf, 250 INVALIDf, 251 INVALIDf, 252 CMD_A_8_SRC_PKT_OFFSETf, 253 CMD_A_9_SRC_PKT_OFFSETf 254 }; 255 soc_field_t valid_p0_cmds[8] = { 256 INVALIDf, 257 INVALIDf, 258 INVALIDf, 259 INVALIDf, 260 INVALIDf, 261 INVALIDf, 262 CMD_A_8_VALIDf, 263 CMD_A_9_VALIDf, 264 }; 265 266 soc_field_t src_pkt_offset_cmds[8] = { 267 CMD_C_4_SRC_PKT_OFFSETf, 268 CMD_C_5_SRC_PKT_OFFSETf, 269 CMD_C_6_SRC_PKT_OFFSETf, 270 CMD_C_7_SRC_PKT_OFFSETf, 271 CMD_C_8_SRC_PKT_OFFSETf, 272 CMD_C_9_SRC_PKT_OFFSETf, 273 CMD_C_10_SRC_PKT_OFFSETf, 274 CMD_C_11_SRC_PKT_OFFSETf 275 }; 276 soc_field_t dest_cont_id_cmds[8] = { 277 CMD_C_4_DEST_CONT_IDf, 278 CMD_C_5_DEST_CONT_IDf, 279 CMD_C_6_DEST_CONT_IDf, 280 CMD_C_7_DEST_CONT_IDf, 281 CMD_C_8_DEST_CONT_IDf, 282 CMD_C_9_DEST_CONT_IDf, 283 CMD_C_10_DEST_CONT_IDf, 284 CMD_C_11_DEST_CONT_IDf 285 }; 286 soc_field_t valid_cmds[8] = { 287 CMD_C_4_VALIDf, 288 CMD_C_5_VALIDf, 289 CMD_C_6_VALIDf, 290 CMD_C_7_VALIDf, 291 CMD_C_8_VALIDf, 292 CMD_C_9_VALIDf, 293 CMD_C_10_VALIDf, 294 CMD_C_11_VALIDf 295 }; 296 297 #define _UDF_TD3_GET_HFE_CMD_FORMAT(_parser_, _fmt_) \ 298 do { \ 299 if (_parser_ == _BCM_UDF_PARSER1) { \ 300 _fmt_ = IP_PARSER1_HFE_CMD_POLICY_DATAfmt; \ 301 } else if (_parser_ == _BCM_UDF_PARSER2) { \ 302 _fmt_ = IP_PARSER2_HFE_CMD_POLICY_DATAfmt; \ 303 } else if (_parser_ == _BCM_UDF_PARSER0) { \ 304 _fmt_ = IP_PARSER0_HFE_CMD_POLICY_DATAfmt; \ 305 } else { \ 306 _fmt_ = INVALIDfmt; \ 307 } \ 308 } while(0) 309 310 311 /* Local Structure to hold chunk information assigned to UDF object. */ 312 typedef struct _udf_obj_pkt_fmt_hw_cfg_s { 313 uint8 num_chunks; /* Number of chunks. */ 314 uint8 chunk_arr[_BCM_UDF_TD3_MAX_CHUNKS]; /* Chunk array. */ 315 uint16 cmd_bmap[_BCM_UDF_MAX_PARSER_STAGES]; /* CMD Bitmap for each stage */ 316 } _udf_obj_pkt_fmt_hw_cfg_t; 317 318 /* Function Declarations */ 319 #if defined (BCM_WARM_BOOT_SUPPORT) 320 STATIC int 321 _bcm_udf_td3_reinit(int unit); 322 323 STATIC int 324 _bcm_udf_td3_wb_alloc(int unit); 325 #endif /* BCM_WARM_BOOT_SUPPORT */ 326 STATIC int 327 _bcm_udf_td3_abstr_pkt_fmt_hw_info_insert(int unit, bcm_udf_abstract_pkt_format_t format, 328 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_format_info); 329 330 extern int 331 _bcm_field_td3_qset_udf_chunk_validate(int unit, 332 bcm_udf_chunk_info_t *udf_info, 333 bcm_udf_alloc_hints_t *hints); 334 335 soc_mem_t _udf_hfe_to_hme_mem_conv[11][2] = { 336 {IP_PARSER0_HME_STAGE_TCAM_DATA_ONLY_0m, IP_PARSER0_HFE_POLICY_TABLE_0m}, 337 {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_0m, IP_PARSER1_HFE_POLICY_TABLE_0m}, 338 {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_1m, IP_PARSER1_HFE_POLICY_TABLE_1m}, 339 {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_2m, IP_PARSER1_HFE_POLICY_TABLE_2m}, 340 {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_3m, IP_PARSER1_HFE_POLICY_TABLE_3m}, 341 {IP_PARSER1_HME_STAGE_TCAM_DATA_ONLY_4m, IP_PARSER1_HFE_POLICY_TABLE_4m}, 342 {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_0m, IP_PARSER2_HFE_POLICY_TABLE_0m}, 343 {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_1m, IP_PARSER2_HFE_POLICY_TABLE_1m}, 344 {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_2m, IP_PARSER2_HFE_POLICY_TABLE_2m}, 345 {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_3m, IP_PARSER2_HFE_POLICY_TABLE_3m}, 346 {IP_PARSER2_HME_STAGE_TCAM_DATA_ONLY_4m, IP_PARSER2_HFE_POLICY_TABLE_4m}}; 347 348 349 STATIC int 350 _udf_td3_hme_to_hfe_mem_get(soc_mem_t hme_mem, soc_mem_t *hfe_mem) { 351 int ct; 352 353 for (ct = 0; ct < 11; ct++) { 354 if (_udf_hfe_to_hme_mem_conv[ct][0] == hme_mem) { 355 *hfe_mem = _udf_hfe_to_hme_mem_conv[ct][1]; 356 break; 357 } 358 } 359 360 if (ct >= 11) { 361 return BCM_E_CONFIG; 362 } 363 364 return BCM_E_NONE; 365 } 366 367 STATIC int 368 _udf_td3_opaque_cont_to_chunk_bmap(uint32 opq_cont_bmap, uint32 *chunk_bmap) 369 { 370 int id; 371 372 for (id = 0; id < _BCM_UDF_TD3_MAX_CHUNKS; id++) { 373 if (opq_cont_bmap & (1 << id)) { 374 *chunk_bmap |= (1 << _bcm_udf_opaque_cont_to_chunk_mapping[id]); 375 } 376 } 377 378 return BCM_E_NONE; 379 } 380 381 STATIC char * 382 _udf_abstr_pkt_fmt_name(bcm_udf_abstract_pkt_format_t abstr_pkt_fmt) 383 { 384 static char *text[] = BCM_UDF_ABSTRACT_PKT_FORMAT; 385 386 if (abstr_pkt_fmt >= COUNTOF(text)) { 387 return "??"; 388 } 389 return text[abstr_pkt_fmt]; 390 } 391 392 393 /* 394 * Free UDF device control structure. 395 */ 396 int _bcm_udf_td3_ctrl_free(int unit, _bcm_udf_td3_ctrl_t *udf_ctrl) 397 { 398 if (udf_ctrl == NULL) { 399 return BCM_E_NONE; 400 } 401 402 if (udf_ctrl->udf_obj_head != NULL) { 403 _BCM_UDF_OBJ_NODE_DEL_ALL(_u_, udf_ctrl->udf_obj_head); 404 udf_ctrl->udf_obj_head = NULL; 405 } 406 407 _BCM_UDF_FREE(udf_ctrl); 408 return BCM_E_NONE; 409 } 410 411 /* 412 * Function: 413 * _bcm_udf_td3_detach 414 * Purpose: 415 * Detaches udf module and cleans software state. 416 * Parameters: 417 * unit - (IN) Unit number. 418 * Returns: 419 * BCM_E_XXX 420 * Notes: 421 */ 422 int 423 _bcm_udf_td3_detach(int unit) 424 { 425 uint8 stage; 426 bcm_udf_abstract_pkt_format_t pkt_fmt; 427 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 428 429 /* Free resources related to UDF module */ 430 BCM_IF_ERROR_RETURN(_bcm_udf_td3_ctrl_free(unit, UDF_TD3_CTRL(unit))); 431 432 UDF_TD3_CTRL(unit) = NULL; 433 434 /* Free Abstract Packet Format HW Info. */ 435 for (pkt_fmt = 0; pkt_fmt < bcmUdfAbstractPktFormatLastCount; pkt_fmt++) { 436 pkt_fmt_hw_info = abstr_pkt_fmt_hw_info[unit][pkt_fmt]; 437 if (pkt_fmt_hw_info != NULL) { 438 for (stage = 0; stage < _BCM_UDF_MAX_PARSER_STAGES; stage++) { 439 if (pkt_fmt_hw_info->hfe_profile_ptr[stage] != NULL) { 440 _BCM_UDF_FREE(pkt_fmt_hw_info->hfe_profile_ptr[stage]); 441 } 442 443 if (pkt_fmt_hw_info->cmd_policy_data[stage] != NULL) { 444 _BCM_UDF_FREE(pkt_fmt_hw_info->cmd_policy_data[stage]); 445 } 446 } 447 448 _BCM_UDF_FREE(abstr_pkt_fmt_hw_info[unit][pkt_fmt]); 449 } 450 } 451 452 return BCM_E_NONE; 453 } 454 455 /* 456 * Function: 457 * _bcm_udf_td3_ctrl_init 458 * Purpose: 459 * Initialize UDF control and internal data structures. 460 * Parameters: 461 * unit - (IN) bcm device. 462 * 463 * Returns: 464 * BCM_E_XXX 465 */ 466 STATIC int 467 _bcm_udf_td3_ctrl_init(int unit) 468 { 469 int alloc_sz; 470 _bcm_udf_td3_ctrl_t *udf_ctrl = NULL; 471 472 /* Detach module if already installed */ 473 if (UDF_TD3_CTRL(unit) != NULL) { 474 _bcm_udf_td3_detach(unit); 475 } 476 477 /* Allocating memory of UDF control structure */ 478 alloc_sz = sizeof(_bcm_udf_td3_ctrl_t); 479 _BCM_UDF_ALLOC(udf_ctrl, alloc_sz, "UDF td3 control"); 480 if (udf_ctrl == NULL) { 481 return BCM_E_MEMORY; 482 } 483 484 UDF_TD3_CTRL(unit) = udf_ctrl; 485 486 /* UDF Range Checker support */ 487 udf_ctrl->flags |= _BCM_UDF_TD3_CTRL_RANGE_CHECK; 488 489 /* 490 * Update UDF Common control fields. 491 */ 492 UDF_CONTROL(unit)->gran = _BCM_UDF_OFFSET_GRAN2; 493 UDF_CONTROL(unit)->num_chunks = _BCM_UDF_OFFSET_CHUNKS16; 494 UDF_CONTROL(unit)->min_obj_id = _BCM_UDF_TD3_OBJ_MIN_ID; 495 UDF_CONTROL(unit)->max_obj_id = _BCM_UDF_TD3_OBJ_MAX_ID; 496 UDF_CONTROL(unit)->parse_limit = _BCM_UDF_TD3_MAX_PARSE_LIMIT; 497 UDF_CONTROL(unit)->max_udfs = _BCM_UDF_TD3_MAX_OBJECTS(unit); 498 return BCM_E_NONE; 499 } 500 501 502 int 503 _bcm_udf_abstr_pkt_fmt_flex_init(int unit) 504 { 505 int rv; 506 uint32 stg, num_stage; 507 uint32 *hfe_prof_ptr_arr[_BCM_UDF_MAX_PARSER_STAGES]; 508 uint32 hfe_prof_ptr_arr_len[_BCM_UDF_MAX_PARSER_STAGES] = {0}; 509 bcm_udf_abstract_pkt_format_t pkt_fmt; 510 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 511 soc_cancun_udf_stage_info_t udf_ccinfo_arr[_BCM_UDF_MAX_PARSER_STAGES]; 512 513 for (pkt_fmt = 0; pkt_fmt < bcmUdfAbstractPktFormatLastCount; pkt_fmt++) { 514 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 515 if (pkt_fmt_hw_info == NULL) { 516 LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit, 517 "UDF Abstract pkt fmt '%s' not found in flex db.\n\r"), 518 _udf_abstr_pkt_fmt_name(pkt_fmt))); 519 continue; 520 } 521 522 num_stage = 0; 523 sal_memset(udf_ccinfo_arr, 0x0, 524 sizeof(soc_cancun_udf_stage_info_t) * _BCM_UDF_MAX_PARSER_STAGES); 525 rv = soc_cancun_udf_abstr_type_info_get(unit, pkt_fmt, 526 pkt_fmt_hw_info->parser, 527 0, NULL, NULL, 528 &num_stage, 529 hfe_prof_ptr_arr_len); 530 if (SOC_SUCCESS(rv)) { 531 if (hfe_prof_ptr_arr_len[0] == 0) { 532 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 533 "UDF Abstract pkt fmt '%s' has null hfe_prof_ptr.\n\r"), 534 _udf_abstr_pkt_fmt_name(pkt_fmt))); 535 continue; 536 } 537 538 for (stg = 0; stg < num_stage; stg++) { 539 hfe_prof_ptr_arr[stg] = NULL; 540 _BCM_UDF_ALLOC(hfe_prof_ptr_arr[stg], 541 sizeof(uint32) * hfe_prof_ptr_arr_len[stg], 542 "UDF Hfe Prof Ptr Alloc."); 543 } 544 545 rv = soc_cancun_udf_abstr_type_info_get(unit, pkt_fmt, 546 pkt_fmt_hw_info->parser, 547 num_stage, hfe_prof_ptr_arr, 548 udf_ccinfo_arr, 549 NULL, NULL); 550 } 551 552 if (SOC_FAILURE(rv)) { 553 if (rv == SOC_E_NOT_FOUND) { 554 LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit, 555 "UDF Abstract pkt fmt '%s' not found in flex db.\n\r"), 556 _udf_abstr_pkt_fmt_name(pkt_fmt))); 557 558 continue; 559 } 560 LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit, 561 "UDF Flex DB Error for Abstract pkt fmt '%s'.\n\r"), 562 _udf_abstr_pkt_fmt_name(pkt_fmt))); 563 continue; 564 } 565 566 pkt_fmt_hw_info->num_stages = num_stage; 567 for (stg = 0; stg < num_stage; stg++) { 568 pkt_fmt_hw_info->base_offset = udf_ccinfo_arr[stg].start_pos; 569 rv = _udf_td3_hme_to_hfe_mem_get(udf_ccinfo_arr[stg].policy_mem, 570 &pkt_fmt_hw_info->stage_policy_mem[stg]); 571 if (BCM_FAILURE(rv)) { 572 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 573 "Unknown Policy Mem from flex db:%d for abstr_type:[%s]\n\r"), 574 pkt_fmt_hw_info->stage_policy_mem[stg], _udf_abstr_pkt_fmt_name(pkt_fmt))); 575 return rv; 576 } 577 578 pkt_fmt_hw_info->hfe_prof_ptr_arr_len[stg] = udf_ccinfo_arr[stg].hfe_prof_ptr_arr_len; 579 pkt_fmt_hw_info->hfe_profile_ptr[stg] = udf_ccinfo_arr[stg].hfe_profile_ptr; 580 pkt_fmt_hw_info->num_cmds[stg] = (udf_ccinfo_arr[stg].size)/2; 581 pkt_fmt_hw_info->max_extract_bytes += (pkt_fmt_hw_info->num_cmds[stg] * 2); 582 rv = _udf_td3_opaque_cont_to_chunk_bmap(udf_ccinfo_arr[stg].unavail_contbmap, 583 &pkt_fmt_hw_info->unavail_chunk_bmap); 584 if (BCM_FAILURE(rv)) { 585 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 586 "Unknown Unavail Opaque container from flex db:0x%x for abstr_type:[%s]\n\r"), 587 udf_ccinfo_arr[stg].unavail_contbmap, _udf_abstr_pkt_fmt_name(pkt_fmt))); 588 return rv; 589 } 590 591 LOG_DEBUG(BSL_LS_BCM_UDF, (BSL_META_U(unit, 592 "UDF Abstract pkt fmt %d-'%s': max_extract_bytes:%d" 593 " hfe_profile_ptr:%d mem:%d unavail_chunk_bmap:0x%x.\n\r"), pkt_fmt, 594 _udf_abstr_pkt_fmt_name(pkt_fmt), pkt_fmt_hw_info->max_extract_bytes, 595 pkt_fmt_hw_info->hfe_profile_ptr[stg][0], pkt_fmt_hw_info->stage_policy_mem[stg], 596 pkt_fmt_hw_info->unavail_chunk_bmap)); 597 } 598 } 599 600 return BCM_E_NONE; 601 } 602 603 /* 604 * Initialize Abstract Packet Formats with offset and default values. 605 */ 606 int 607 _bcm_udf_abstr_pkt_format_info_init(int unit) 608 { 609 bcm_udf_abstract_pkt_format_t pkt_fmt; 610 _BCM_UDF_ABSTRACT_PKT_FORMAT_MAPPING_DECL 611 /* Validate whether UDF module is attached */ 612 if (UDF_TD3_CTRL(unit) == NULL) { 613 return BCM_E_INIT; 614 } 615 616 for (pkt_fmt = 0; pkt_fmt < bcmUdfAbstractPktFormatLastCount; pkt_fmt++) { 617 if (abstr_pkt_fmt_hw_info[unit][pkt_fmt] != NULL) { 618 sal_free(abstr_pkt_fmt_hw_info[unit][pkt_fmt]); 619 abstr_pkt_fmt_hw_info[unit][pkt_fmt] = NULL; 620 } 621 622 _BCM_UDF_ALLOC(abstr_pkt_fmt_hw_info[unit][pkt_fmt], 623 sizeof(_bcm_udf_td3_abstr_pkt_fmt_hw_info_t), 624 "UDF Abstract Pkt Format INIT"); 625 if (abstr_pkt_fmt_hw_info[unit][pkt_fmt] == NULL) { 626 return BCM_E_MEMORY; 627 } 628 } 629 630 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatLlc, 1); 631 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerLlc, 2); 632 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3, 1); 633 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3, 2); 634 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownNonIp, 1); 635 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerKnownNonIp, 2); 636 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3Mim, 1); 637 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3FcoeStdEncap, 1); 638 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3FcoeVftIfr, 1); 639 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsOneLabel, 1); 640 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsTwoLabel, 1); 641 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsThreeLabel, 1); 642 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsFourLabel, 1); 643 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3MplsMoreThanFourLabel, 1); 644 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL4, 1); 645 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL4, 2); 646 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpUnknownL5, 1); 647 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUdpUnknownL5, 2); 648 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpGpeGeneve, 1); 649 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpBfd, 1); 650 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUdpBfd, 2); 651 /* _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpBfdUnknown, 1); */ 652 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpVxlan, 1); 653 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdp1588, 1); 654 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatTcpUnknownL5, 1); 655 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerTcpUnknownL5, 2); 656 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatSctpUnknownL5, 1); 657 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerSctpUnknownL5, 2); 658 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithoutKey, 1); 659 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithKey, 1); 660 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithoutChecksumRouting, 1); 661 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GreWithoutChecksumRouting, 1); 662 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GreWithoutRouting, 1); 663 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatAchNonIp, 2); 664 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpINT, 1); 665 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatTcpUnknownL5WithIpExtnHdr, 1); 666 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3GreUnknownPayload, 1); 667 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGreWithKeyRouting, 1); 668 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GreWithKeyRouting, 1); 669 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUdp1588, 2); 670 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatTcpINT, 1); 671 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownL3FcoeUnknownRctl, 1); 672 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0, 3); 673 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0EHType0, 3); 674 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0EHType1, 3); 675 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd0EHType2, 3); 676 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2, 3); 677 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2EHType0, 3); 678 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2EHType1, 3); 679 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatHiGigPpd2EHType2, 3); 680 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatGpeIOAM, 1); 681 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatKnownMplsMcast, 1); 682 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatLoopbackHdrType0, 3); 683 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatLoopbackHdrType1, 3); 684 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4Fragmented, 1); 685 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4FragmentedWithOptions, 1); 686 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4WithoutOptions, 1); 687 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv4WithOptions, 1); 688 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL3Ipv6, 1); 689 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2, 3); 690 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2Untagged, 1); 691 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanTag, 1); 692 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanTag, 1); 693 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanTag, 1); 694 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2GbpTag, 1); 695 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanWithGbpTag, 1); 696 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanWithGbpTag, 1); 697 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanWithGbpTag, 1); 698 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2Vntag, 1); 699 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanWithVntag, 1); 700 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanWithVntag, 1); 701 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanWithVntag, 1); 702 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2Etag, 1); 703 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2OuterVlanEtag, 1); 704 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2InnerVlanEtag, 1); 705 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatL2DoubleVlanEtag, 1); 706 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL3Ipv4, 2); 707 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL3Ipv4Fragmented, 2); 708 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL3Ipv6, 2); 709 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2Untagged, 2); 710 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2OuterVlanTag, 2); 711 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2InnerVlanTag, 2); 712 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2DoubleVlanTag, 2); 713 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2GbpTag, 2); 714 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2OuterVlanWithGbpTag, 2); 715 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2InnerVlanWithGbpTag, 2); 716 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerL2DoubleVlanWithGbpTag, 2); 717 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomEtherType1, 1); 718 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomEtherType2, 1); 719 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomIpProtocol1, 1); 720 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomIpProtocol2, 1); 721 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomUdpDstPort1, 1); 722 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUnknownL3CustomUdpDstPort2, 1); 723 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomEtherType1, 2); 724 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomEtherType2, 2); 725 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomIpProtocol1, 2); 726 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomIpProtocol2, 2); 727 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomUdpDstPort1, 2); 728 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatInnerUnknownL3CustomUdpDstPort2, 2); 729 _BCM_UDF_ABSTRACT_PKT_FORMAT_CFG_INIT(unit, bcmUdfAbstractPktFormatUdpProbeBasedINT, 1); 730 731 return _bcm_udf_abstr_pkt_fmt_flex_init(unit); 732 } 733 734 735 /* 736 * Reset HFE Profile indices for all abstract pkt formats. 737 */ 738 STATIC int 739 _bcm_udf_td3_hfe_profile_hw_init(int unit) 740 { 741 int rv; 742 int len; 743 uint8 stage; 744 soc_format_t fmt; 745 soc_mem_t policy_mem; 746 uint8 buf[100]; 747 uint32 hfe_profile_ptr; 748 uint8 *cmd_pol_data_buf = NULL; 749 bcm_udf_abstract_pkt_format_t pkt_fmt; 750 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 751 752 for (pkt_fmt = bcmUdfAbstractPktFormatLlc; 753 pkt_fmt < bcmUdfAbstractPktFormatLastCount; 754 pkt_fmt++) { 755 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 756 if (pkt_fmt_hw_info == NULL) { 757 continue; 758 } 759 760 for (stage = 0; stage < pkt_fmt_hw_info->num_stages; stage++) { 761 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage]; 762 hfe_profile_ptr = pkt_fmt_hw_info->hfe_profile_ptr[stage][0]; 763 764 if (policy_mem == INVALIDm) { 765 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 766 "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"), 767 _udf_abstr_pkt_fmt_name(pkt_fmt), stage)); 768 return BCM_E_INTERNAL; 769 } 770 771 _UDF_TD3_GET_HFE_CMD_FORMAT(pkt_fmt_hw_info->parser, fmt); 772 if (fmt == INVALIDfmt) { 773 return BCM_E_INTERNAL; 774 } 775 776 sal_memset(buf, 0x0, sizeof(buf)); 777 rv = soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, 778 hfe_profile_ptr, (uint32 *) buf); 779 BCM_IF_ERROR_RETURN(rv); 780 781 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf); 782 cmd_pol_data_buf = NULL; 783 _BCM_UDF_ALLOC(cmd_pol_data_buf, len, "UDF default CMD Policy data"); 784 if (cmd_pol_data_buf == NULL) { 785 return BCM_E_MEMORY; 786 } 787 788 soc_mem_field_get(unit, policy_mem, (uint32 *)buf, 789 CMD_POLICY_DATAf, (uint32 *)cmd_pol_data_buf); 790 791 pkt_fmt_hw_info->cmd_policy_data[stage] = cmd_pol_data_buf; 792 793 #if 0 794 for (i = 0; i < _BCM_UDF_MAX_POLICY_CMDS; i++) { 795 soc_format_field32_set(unit, fmt, (uint32 *)f_buf, 796 valid_cmds[i], 0); 797 } 798 799 soc_mem_field_set(unit, policy_mem, (uint32 *)buf, 800 CMD_POLICY_DATAf, (uint32 *)f_buf); 801 802 rv = soc_mem_write(unit, policy_mem, MEM_BLOCK_ANY, 803 hfe_profile_ptr, (uint32 *)buf); 804 BCM_IF_ERROR_RETURN(rv); 805 #endif 806 807 } 808 } 809 810 return BCM_E_NONE; 811 } 812 813 /* 814 * Function: 815 * _bcm_udf_td3_init 816 * Purpose: 817 * initializes/ReInitializes the UDF module. 818 * Parameters: 819 * unit - (IN) Unit number. 820 * Returns: 821 * BCM_E_XXX 822 * Notes: 823 */ 824 int 825 _bcm_udf_td3_init(int unit) 826 { 827 int rv; 828 829 /* Init control structures */ 830 rv = _bcm_udf_td3_ctrl_init(unit); 831 BCM_IF_ERROR_GOTO_CLEANUP(rv); 832 833 /* 834 * Initialize Abstract Packet Formats with offset 835 * and default values. 836 */ 837 rv = _bcm_udf_abstr_pkt_format_info_init(unit); 838 BCM_IF_ERROR_GOTO_CLEANUP(rv); 839 840 /* Initialize hardware HFE Profile Indices with default values */ 841 rv = _bcm_udf_td3_hfe_profile_hw_init(unit); 842 BCM_IF_ERROR_GOTO_CLEANUP(rv); 843 #if defined (BCM_WARM_BOOT_SUPPORT) 844 if (SOC_WARM_BOOT(unit)) { 845 rv = _bcm_udf_td3_reinit(unit); 846 BCM_IF_ERROR_GOTO_CLEANUP(rv); 847 } else 848 #endif /* BCM_WARM_BOOT_SUPPORT */ 849 { 850 #if defined (BCM_WARM_BOOT_SUPPORT) 851 rv = _bcm_udf_td3_wb_alloc(unit); 852 BCM_IF_ERROR_GOTO_CLEANUP(rv); 853 #endif /* BCM_WARM_BOOT_SUPPORT */ 854 } 855 856 return BCM_E_NONE; 857 858 cleanup: 859 (void) _bcm_udf_td3_detach(unit); 860 return rv; 861 } 862 863 STATIC int 864 _bcm_udf_td3_abstr_pkt_fmt_hw_info_insert(int unit, bcm_udf_abstract_pkt_format_t abstr_pkt_fmt, 865 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_format_info) 866 { 867 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info = NULL; 868 869 if (pkt_format_info == NULL) { 870 return BCM_E_INTERNAL; 871 } 872 873 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, abstr_pkt_fmt); 874 if (pkt_fmt_hw_info == NULL) { 875 return BCM_E_INTERNAL; 876 } 877 878 sal_memcpy(pkt_fmt_hw_info, pkt_format_info, 879 sizeof(_bcm_udf_td3_abstr_pkt_fmt_hw_info_t)); 880 881 return BCM_E_NONE; 882 } 883 884 /* Routine to retrieve chunks from the bitmap. */ 885 int 886 _udf_chunk_bmap_to_chunks(uint32 chunk_bmap, uint8 *num_chunks, uint8 *chunk_arr) 887 { 888 uint8 bit, i; 889 uint8 num = 0; 890 891 for (i = 0; i < _BCM_UDF_TD3_MAX_CHUNKS; i++) { 892 bit = (chunk_bmap >> i) & 1; 893 if (bit) { 894 if (chunk_arr != NULL) { 895 chunk_arr[num] = i; 896 } 897 num++; 898 } 899 } 900 901 *num_chunks = num; 902 903 return BCM_E_NONE; 904 } 905 906 /* To sanitize udf_info/pkt_format_info input structures */ 907 STATIC int 908 _udf_td3_sanitize_inputs(int unit, bcm_udf_chunk_info_t *udf_info, 909 bcm_udf_alloc_hints_t *hints, 910 bcm_udf_id_t *udf_id) 911 { 912 uint8 num_chunks = 0; 913 914 /* NULL check */ 915 BCM_IF_NULL_RETURN_PARAM(udf_id); 916 BCM_IF_NULL_RETURN_PARAM(udf_info); 917 918 /* start and width should be at byte boundary */ 919 if (((udf_info->offset % 8) != 0) || ((udf_info->width % 8) != 0)) { 920 return BCM_E_PARAM; 921 } 922 923 /* start and width should be less than max byte selection */ 924 if (BITS2BYTES(udf_info->offset + udf_info->width) > 925 UDF_CONTROL(unit)->parse_limit) { 926 return BCM_E_PARAM; 927 } 928 929 /* check if pkt format is in valid range */ 930 _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(unit, udf_info->abstract_pkt_format); 931 932 /* Extraction bytes (width) Validate */ 933 _BCM_UDF_EXTRACTION_BYTES_VALIDATE(unit, udf_info->abstract_pkt_format, 934 BITS2BYTES(udf_info->width)); 935 936 if (hints != NULL) { 937 /* Replace flag is not supported. */ 938 if (hints->flags & BCM_UDF_CREATE_O_REPLACE) { 939 return BCM_E_PARAM; 940 } 941 942 /* Validate UDF ID */ 943 if (hints->flags & BCM_UDF_CREATE_O_WITHID) { 944 _BCM_UDF_ID_VALIDATE(unit, *udf_id); 945 } 946 947 /* check if chip supports Range Check */ 948 if (hints->flags & BCM_UDF_CREATE_O_RANGE_CHECK) { 949 /* Check if device supports Range Check. */ 950 if (!(UDF_TD3_CTRL(unit)->flags & _BCM_UDF_TD3_CTRL_RANGE_CHECK)) { 951 return BCM_E_PARAM; 952 } 953 954 /* 955 * If RANGE_CHECK Flag is set, chunk bitmap should be 956 * as per the device supported chunks. 957 */ 958 if (udf_info->chunk_bmap != _BCM_UDF_TD3_RANGE_CHUNK_BMAP) { 959 return BCM_E_PARAM; 960 } 961 } 962 } 963 964 /* Chunk Validate */ 965 /* Validate whether the given chunk bmap is part of reserved chunk bitmap */ 966 _BCM_UDF_CHUNK_VALIDATE(unit, udf_info->chunk_bmap, udf_info->abstract_pkt_format); 967 968 /* Validate given chunk_bmap matches with width */ 969 _udf_chunk_bmap_to_chunks(udf_info->chunk_bmap, &num_chunks, NULL); 970 if (BITS2BYTES(udf_info->width) != _BCM_UDF_CHUNK_TO_BYTE(num_chunks)) { 971 return BCM_E_PARAM; 972 } 973 974 if (hints != NULL) { 975 /* Validate whether given chunk bmap used by qualifiers in given qset */ 976 SOC_IF_ERROR_RETURN(_bcm_field_td3_qset_udf_chunk_validate(unit, udf_info, hints)); 977 } 978 979 /* Check whether chunks given in the bitmap are already in use */ 980 _BCM_UDF_OBJECT_CHUNK_IN_USE_VALIDATE(unit, udf_info->abstract_pkt_format, 981 udf_info->chunk_bmap); 982 983 return BCM_E_NONE; 984 } 985 986 /* 987 * Function: 988 * _bcm_udf_td3_object_info_add 989 * Purpose: 990 * To convert the UDF info to object info and add to the linked list. 991 * Parameters: 992 * unit - (IN) Unit number. 993 * udf_info - (IN) UDF info to be added to linked list. 994 * object_info - (INOUT) Reference to allocated object info. 995 * Returns: 996 * BCM_E_XXX 997 * Notes: 998 */ 999 STATIC int 1000 _bcm_udf_td3_object_info_add(int unit, bcm_udf_chunk_info_t *udf_info, 1001 _bcm_udf_td3_obj_info_t **obj_info) 1002 { 1003 /* Allocate memory for UDF object info. */ 1004 _BCM_UDF_ALLOC(*obj_info, sizeof(_bcm_udf_td3_obj_info_t), 1005 "UDF object info."); 1006 if (*obj_info == NULL) { 1007 return BCM_E_MEMORY; 1008 } 1009 1010 /* Insert user inputs into the object_info struct */ 1011 (*obj_info)->width = BITS2BYTES(udf_info->width); 1012 (*obj_info)->offset = BITS2BYTES(udf_info->offset); 1013 (*obj_info)->chunk_bmap = udf_info->chunk_bmap; 1014 (*obj_info)->abstr_pkt_fmt = udf_info->abstract_pkt_format; 1015 (*obj_info)->next = NULL; 1016 (*obj_info)->prev = NULL; 1017 1018 /* Add obj_info item to the linked list */ 1019 _BCM_UDF_OBJ_NODE_ADD(unit, (*obj_info), 1020 UDF_TD3_CTRL(unit)->udf_obj_head); 1021 return BCM_E_NONE; 1022 } 1023 1024 /* 1025 * Function: 1026 * _bcm_udf_td3_object_info_delete 1027 * Purpose: 1028 * Remove the UDF object info from the database for a given object. 1029 * Parameters: 1030 * unit - (IN) Unit number. 1031 * obj_info - (IN) Reference to allocated object info. 1032 * Returns: 1033 * BCM_E_XXX 1034 * Notes: 1035 */ 1036 STATIC int 1037 _bcm_udf_td3_object_info_delete(int unit, _bcm_udf_td3_obj_info_t *obj_info) 1038 { 1039 if (obj_info == NULL) { 1040 return BCM_E_PARAM; 1041 } 1042 1043 /* Delete obj_info from the linked list */ 1044 _BCM_UDF_OBJ_NODE_DEL(unit, obj_info, UDF_TD3_CTRL(unit)->udf_obj_head); 1045 _BCM_UDF_FREE(obj_info); 1046 return BCM_E_NONE; 1047 } 1048 1049 /* 1050 * Function: 1051 * _bcm_udf_td3_object_info_get 1052 * Purpose: 1053 * Retrieves UDF object info for the given udf id. 1054 * Parameters: 1055 * unit - (IN) Unit number. 1056 * udf_id - (IN) UDF Id. 1057 * obj_info - (INOUT) Retrieve udf object info. 1058 * Returns: 1059 * BCM_E_XXX 1060 * Notes: 1061 */ 1062 int 1063 _bcm_udf_td3_object_info_get( 1064 int unit, 1065 bcm_udf_id_t udf_id, 1066 _bcm_udf_td3_obj_info_t **obj_info) 1067 { 1068 _BCM_UDF_OBJ_NODE_GET(unit, udf_id, 1069 UDF_TD3_CTRL(unit)->udf_obj_head, 1070 *obj_info); 1071 1072 if (*obj_info == NULL) { 1073 return BCM_E_NOT_FOUND; 1074 } 1075 1076 return BCM_E_NONE; 1077 } 1078 1079 /* 1080 * To allocate running id for UDF IDs. 1081 */ 1082 static int 1083 _bcm_udf_td3_object_running_id_alloc(int unit, bcm_udf_id_t *udf_id) 1084 { 1085 int rv; 1086 int id; 1087 int min_id, max_id; 1088 _bcm_udf_td3_obj_info_t *obj_info = NULL; 1089 1090 min_id = UDF_CONTROL(unit)->min_obj_id; 1091 max_id = UDF_CONTROL(unit)->max_obj_id; 1092 1093 id = _BCM_UDF_OBJ_ID_RUNNING(unit); 1094 1095 if (id > max_id) { 1096 for (id = min_id; id <= max_id; id++) { 1097 rv = _bcm_udf_td3_object_info_get(unit, id, &obj_info); 1098 if (BCM_E_NOT_FOUND == rv) { 1099 break; 1100 } 1101 1102 if (BCM_FAILURE(rv)) { 1103 return BCM_E_INTERNAL; 1104 } 1105 } 1106 1107 /* All the udf ids are used up */ 1108 if (id > max_id) { 1109 return BCM_E_FULL; 1110 } 1111 } 1112 1113 *udf_id = id; 1114 1115 return BCM_E_NONE; 1116 } 1117 1118 static int _udf_parser0_chunk_to_cmd_get(int unit, uint32 chunk_bmap, 1119 uint16 *cmd_bmap) 1120 { 1121 uint8 chunk; 1122 1123 chunk = _bcm_udf_opaque_cont_to_chunk_mapping[2]; 1124 if (chunk_bmap & (1 << chunk)) { 1125 *cmd_bmap |= (1 << 6); 1126 } 1127 1128 chunk = _bcm_udf_opaque_cont_to_chunk_mapping[0]; 1129 if (chunk_bmap & (1 << chunk)) { 1130 *cmd_bmap |= (1 << 7); 1131 } 1132 1133 return BCM_E_NONE; 1134 } 1135 1136 static int 1137 _udf_td3_hw_policy_cmd_alloc( 1138 int unit, 1139 _bcm_udf_td3_obj_info_t *obj_info, 1140 _udf_obj_pkt_fmt_hw_cfg_t *cfg_data) 1141 { 1142 int i; 1143 uint8 stage; 1144 uint8 start_cmd; 1145 uint8 num_cmds_required; 1146 bcm_udf_abstract_pkt_format_t pkt_fmt; 1147 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL; 1148 1149 pkt_fmt = obj_info->abstr_pkt_fmt; 1150 hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 1151 if (hw_info == NULL) { 1152 return BCM_E_INTERNAL; 1153 } 1154 1155 if (hw_info->chunk_bmap_used & obj_info->chunk_bmap) { 1156 return BCM_E_PARAM; 1157 } 1158 1159 BCM_IF_ERROR_RETURN(_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap, 1160 &cfg_data->num_chunks, 1161 cfg_data->chunk_arr)); 1162 1163 num_cmds_required = (hw_info->parser == _BCM_UDF_PARSER0) ? 1164 0 : obj_info->width/2; 1165 1166 for (stage = 0; stage < hw_info->num_stages; stage++) { 1167 if (hw_info->stage_policy_mem[stage] != INVALIDm) { 1168 if (hw_info->parser == _BCM_UDF_PARSER0) { 1169 BCM_IF_ERROR_RETURN(_udf_parser0_chunk_to_cmd_get(unit, 1170 obj_info->chunk_bmap, 1171 &cfg_data->cmd_bmap[stage])); 1172 hw_info->valid_cmd_bmap[stage] |= cfg_data->cmd_bmap[stage]; 1173 continue; 1174 } 1175 1176 start_cmd = _BCM_UDF_MAX_POLICY_CMDS - hw_info->num_cmds[stage]; 1177 for (i = start_cmd; i < _BCM_UDF_MAX_POLICY_CMDS; i++) { 1178 if (num_cmds_required == 0) { 1179 break; 1180 } 1181 1182 /* Allocate CMD if the bit is not set */ 1183 if ((hw_info->valid_cmd_bmap[stage] & (1 << i)) == 0) { 1184 cfg_data->cmd_bmap[stage] |= (1 << i); 1185 num_cmds_required--; 1186 } 1187 } 1188 hw_info->valid_cmd_bmap[stage] |= cfg_data->cmd_bmap[stage]; 1189 } 1190 } 1191 1192 if (num_cmds_required != 0) { 1193 return BCM_E_INTERNAL; 1194 } 1195 1196 return BCM_E_NONE; 1197 } 1198 1199 /* 1200 * Install HW Policy Commands for given UDF object. 1201 */ 1202 static int 1203 _udf_td3_hw_policy_cmd_install( 1204 int unit, 1205 _bcm_udf_td3_obj_info_t *obj_info, 1206 _udf_obj_pkt_fmt_hw_cfg_t *cfg_data) 1207 { 1208 int rv; 1209 uint8 i; 1210 uint8 gran = 2; 1211 uint8 chunk; 1212 uint8 stage; 1213 uint8 chunk_ct = 0; 1214 uint8 curr_chunk = 0; 1215 uint8 hfe_ct; 1216 uint8 start_cmd; 1217 uint32 offset = 0; 1218 uint32 curr_offset = 0; 1219 uint32 dest_cont_id; 1220 soc_format_t fmt; 1221 uint32 cancun_ver; 1222 uint8 skip_hw_change = 0; 1223 bcm_udf_abstract_pkt_format_t pkt_fmt; 1224 uint8 f_buf[_BCM_UDF_MAX_PARSER_STAGES][50]; 1225 uint8 buf[_BCM_UDF_MAX_PARSER_STAGES][100]; 1226 uint16 cmd_bmap[_BCM_UDF_MAX_PARSER_STAGES]; 1227 uint8 null_update[_BCM_UDF_MAX_PARSER_STAGES] = {0}; 1228 soc_mem_t policy_mem[_BCM_UDF_MAX_PARSER_STAGES]; 1229 uint32 hfe_profile_ptr[_BCM_UDF_MAX_PARSER_STAGES]; 1230 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL; 1231 1232 pkt_fmt = obj_info->abstr_pkt_fmt; 1233 hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 1234 1235 offset = obj_info->offset; 1236 1237 sal_memset(f_buf, 0x0, sizeof(f_buf)); 1238 sal_memset(buf, 0x0, sizeof(buf)); 1239 1240 BCM_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 1241 if (SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 1242 if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) || 1243 (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) { 1244 skip_hw_change = 1; 1245 } 1246 } 1247 1248 for (stage = 0; stage < hw_info->num_stages; stage++) { 1249 cmd_bmap[stage] = cfg_data->cmd_bmap[stage]; 1250 policy_mem[stage] = hw_info->stage_policy_mem[stage]; 1251 1252 start_cmd = _BCM_UDF_MAX_POLICY_CMDS - hw_info->num_cmds[stage]; 1253 if (policy_mem[stage] == INVALIDm) { 1254 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 1255 "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"), 1256 _udf_abstr_pkt_fmt_name(pkt_fmt), stage)); 1257 return BCM_E_INTERNAL; 1258 } 1259 1260 if (skip_hw_change == 1) { 1261 continue; 1262 } 1263 1264 _UDF_TD3_GET_HFE_CMD_FORMAT(hw_info->parser, fmt); 1265 if (fmt == INVALIDfmt) { 1266 return BCM_E_INTERNAL; 1267 } 1268 1269 null_update[stage] = 0; 1270 curr_chunk = chunk_ct; 1271 curr_offset = offset; 1272 for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) { 1273 hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];; 1274 1275 rv = soc_mem_read(unit, policy_mem[stage], MEM_BLOCK_ANY, 1276 hfe_profile_ptr[stage], (uint32 *) buf[stage]); 1277 BCM_IF_ERROR_RETURN(rv); 1278 1279 soc_mem_field_get(unit, policy_mem[stage], (uint32 *)buf[stage], 1280 CMD_POLICY_DATAf, (uint32 *)f_buf[stage]); 1281 1282 for (i = start_cmd; i < _BCM_UDF_MAX_POLICY_CMDS; i++) { 1283 if (cmd_bmap[stage] & (1 << i)) { 1284 if (hw_info->parser == _BCM_UDF_PARSER0) { 1285 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1286 src_pkt_offset_p0_cmds[i], offset * 8); 1287 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1288 valid_p0_cmds[i], 1); 1289 } else { 1290 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1291 src_pkt_offset_cmds[i], offset); 1292 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1293 valid_cmds[i], 1); 1294 if (chunk_ct <= cfg_data->num_chunks) { 1295 chunk = cfg_data->chunk_arr[chunk_ct]; 1296 dest_cont_id = _bcm_udf_chunk_to_dest_cont_id_mapping[chunk]; 1297 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1298 dest_cont_id_cmds[i], dest_cont_id); 1299 chunk_ct++; 1300 } else { 1301 return BCM_E_INTERNAL; 1302 } 1303 } 1304 offset += gran; 1305 } else if (hw_info->chunk_bmap_used == 0) { 1306 if (hw_info->parser == _BCM_UDF_PARSER0) { 1307 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1308 valid_p0_cmds[i], 0); 1309 } else { 1310 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1311 valid_cmds[i], 0); 1312 } 1313 null_update[stage] = 1; 1314 } 1315 } 1316 1317 if (cmd_bmap[stage] || (null_update[stage])) { 1318 soc_mem_field_set(unit, policy_mem[stage], (uint32 *)buf[stage], 1319 CMD_POLICY_DATAf, (uint32 *)f_buf[stage]); 1320 } 1321 1322 if ((hfe_ct + 1) < hw_info->hfe_prof_ptr_arr_len[stage]) { 1323 chunk_ct = curr_chunk; 1324 offset = curr_offset; 1325 } 1326 } 1327 } 1328 1329 if (skip_hw_change == 0) { 1330 for (stage = 0; stage < hw_info->num_stages; stage++) { 1331 for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) { 1332 hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];; 1333 if (cmd_bmap[stage] || (null_update[stage])) { 1334 rv = soc_mem_write(unit, policy_mem[stage], MEM_BLOCK_ANY, 1335 hfe_profile_ptr[stage], (uint32 *)buf[stage]); 1336 BCM_IF_ERROR_RETURN(rv); 1337 } 1338 } 1339 } 1340 } 1341 1342 for (stage = 0; stage < hw_info->num_stages; stage++) { 1343 obj_info->hw_cmd_bmap[stage] = cfg_data->cmd_bmap[stage]; 1344 } 1345 hw_info->extracted_bytes += _BCM_UDF_CHUNK_TO_BYTE(cfg_data->num_chunks); 1346 hw_info->chunk_bmap_used |= obj_info->chunk_bmap; 1347 return BCM_E_NONE; 1348 } 1349 1350 /* 1351 * Un-install HW Policy Commands for given UDF object. 1352 */ 1353 STATIC 1354 int _udf_td3_hw_policy_cmd_uninstall(int unit, _bcm_udf_td3_obj_info_t *obj_info) 1355 { 1356 int rv; 1357 uint8 stage, i, hfe_ct; 1358 uint8 num_chunks = 0; 1359 uint8 start_cmd; 1360 uint8 skip_hw_init = 0; 1361 soc_format_t fmt; 1362 uint32 cancun_ver; 1363 uint8 *cmd_policy_data = NULL; 1364 bcm_udf_abstract_pkt_format_t pkt_fmt; 1365 uint8 f_buf[_BCM_UDF_MAX_PARSER_STAGES][50]; 1366 uint8 buf[_BCM_UDF_MAX_PARSER_STAGES][100]; 1367 uint16 cmd_bmap[_BCM_UDF_MAX_PARSER_STAGES]; 1368 soc_mem_t policy_mem[_BCM_UDF_MAX_PARSER_STAGES]; 1369 uint32 hfe_profile_ptr[_BCM_UDF_MAX_PARSER_STAGES]; 1370 uint8 null_update[_BCM_UDF_MAX_PARSER_STAGES] = {0}; 1371 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL; 1372 1373 pkt_fmt = obj_info->abstr_pkt_fmt; 1374 hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 1375 1376 BCM_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 1377 if (SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 1378 if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) || 1379 (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) { 1380 skip_hw_init = 1; 1381 } 1382 } 1383 1384 if (skip_hw_init == 0) { 1385 sal_memset(f_buf, 0x0, sizeof(f_buf)); 1386 sal_memset(buf, 0x0, sizeof(buf)); 1387 1388 for (stage = 0; stage < hw_info->num_stages; stage++) { 1389 cmd_bmap[stage] = obj_info->hw_cmd_bmap[stage]; 1390 policy_mem[stage] = hw_info->stage_policy_mem[stage]; 1391 cmd_policy_data = hw_info->cmd_policy_data[stage]; 1392 1393 if (policy_mem[stage] == INVALIDm) { 1394 continue; 1395 } 1396 1397 _UDF_TD3_GET_HFE_CMD_FORMAT(hw_info->parser, fmt); 1398 if (fmt == INVALIDfmt) { 1399 return BCM_E_INTERNAL; 1400 } 1401 1402 if (cmd_policy_data == NULL) { 1403 return BCM_E_INTERNAL; 1404 } 1405 1406 for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) { 1407 hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];; 1408 rv = soc_mem_read(unit, policy_mem[stage], MEM_BLOCK_ANY, 1409 hfe_profile_ptr[stage], (uint32 *) buf[stage]); 1410 BCM_IF_ERROR_RETURN(rv); 1411 soc_mem_field_get(unit, policy_mem[stage], (uint32 *)buf[stage], 1412 CMD_POLICY_DATAf, (uint32 *)f_buf[stage]); 1413 1414 start_cmd = _BCM_UDF_MAX_POLICY_CMDS - hw_info->num_cmds[stage]; 1415 for (i = start_cmd; i < _BCM_UDF_MAX_POLICY_CMDS; i++) { 1416 if (cmd_bmap[stage] & (1 << i)) { 1417 if (hw_info->parser == _BCM_UDF_PARSER0) { 1418 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1419 valid_p0_cmds[i], 0); 1420 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1421 src_pkt_offset_p0_cmds[i], 0); 1422 } else { 1423 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1424 valid_cmds[i], 0); 1425 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1426 dest_cont_id_cmds[i], 0); 1427 soc_format_field32_set(unit, fmt, (uint32 *)f_buf[stage], 1428 src_pkt_offset_cmds[i], 0); 1429 } 1430 } 1431 } 1432 1433 if (cmd_bmap[stage]) { 1434 soc_mem_field_set(unit, policy_mem[stage], (uint32 *)buf[stage], 1435 CMD_POLICY_DATAf, (uint32 *)f_buf[stage]); 1436 } 1437 1438 if (!(hw_info->chunk_bmap_used & ~(obj_info->hw_cmd_bmap[stage]))) { 1439 soc_mem_field_set(unit, policy_mem[stage], (uint32 *)buf[stage], 1440 CMD_POLICY_DATAf, (uint32 *)cmd_policy_data); 1441 null_update[stage] = 1; 1442 } 1443 } 1444 } 1445 1446 for (stage = 0; stage < hw_info->num_stages; stage++) { 1447 for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stage]; hfe_ct++) { 1448 hfe_profile_ptr[stage] = hw_info->hfe_profile_ptr[stage][hfe_ct];; 1449 if ((cmd_bmap[stage]) || (null_update[stage] == 1)) { 1450 rv = soc_mem_write(unit, policy_mem[stage], MEM_BLOCK_ANY, 1451 hfe_profile_ptr[stage], (uint32 *)buf[stage]); 1452 BCM_IF_ERROR_RETURN(rv); 1453 } 1454 } 1455 } 1456 } 1457 1458 (void)_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap, 1459 &num_chunks, NULL); 1460 1461 /* Update Abstr Pkt Format HW variables. */ 1462 for (stage = 0; stage < hw_info->num_stages; stage++) { 1463 hw_info->valid_cmd_bmap[stage] &= ~(obj_info->hw_cmd_bmap[stage]); 1464 obj_info->hw_cmd_bmap[stage] = 0x0; 1465 } 1466 hw_info->extracted_bytes -= _BCM_UDF_CHUNK_TO_BYTE(num_chunks); 1467 hw_info->chunk_bmap_used &= ~(obj_info->chunk_bmap); 1468 1469 return BCM_E_NONE; 1470 } 1471 1472 1473 /* 1474 * Function: 1475 * _bcm_udf_td3_chunk_create 1476 * Purpose: 1477 * Creates a UDF object 1478 * Parameters: 1479 * unit - (IN) Unit number. 1480 * hints - (IN) Hints to UDF allocator 1481 * udf_info - (IN) UDF Chunk Info structure 1482 * udf_id - (IN/OUT) UDF ID 1483 * Returns: 1484 * BCM_E_NONE UDF created successfully. 1485 * BCM_E_EXISTS Entry already exists. 1486 * BCM_E_FULL UDF table full. 1487 * BCM_E_UNIT Invalid BCM Unit number. 1488 * BCM_E_INIT UDF module not initialized. 1489 * BCM_E_UNAVAIL Feature not supported. 1490 * BCM_E_XXX Standard error code. 1491 * Notes: 1492 */ 1493 int 1494 _bcm_udf_td3_chunk_create( 1495 int unit, 1496 bcm_udf_alloc_hints_t *hints, 1497 bcm_udf_chunk_info_t *udf_info, 1498 bcm_udf_id_t *udf_id) 1499 { 1500 int id_running_allocated = 0; 1501 int rv = BCM_E_NONE; 1502 _udf_obj_pkt_fmt_hw_cfg_t cfg_data; 1503 _bcm_udf_td3_obj_info_t *obj_info = NULL; 1504 1505 /* UDF Device Module Init check */ 1506 if (UDF_TD3_CTRL(unit) == NULL) { 1507 return BCM_E_INIT; 1508 } 1509 1510 /* Sanitize input parameters */ 1511 rv = _udf_td3_sanitize_inputs(unit, udf_info, hints, udf_id); 1512 BCM_IF_ERROR_RETURN(rv); 1513 1514 /* Check if similar entry already existing */ 1515 if ((hints != NULL) && (hints->flags & BCM_UDF_CREATE_O_WITHID)) { 1516 /* Retrieve UDF object info; get should be successful */ 1517 rv = _bcm_udf_td3_object_info_get(unit, *udf_id, &obj_info); 1518 if (BCM_SUCCESS(rv)) { 1519 return BCM_E_EXISTS; 1520 } 1521 } else { 1522 /* Allocate new udf id */ 1523 rv = _bcm_udf_td3_object_running_id_alloc(unit, udf_id); 1524 if (BCM_FAILURE(rv)) { 1525 return rv; 1526 } else { 1527 id_running_allocated = 1; 1528 } 1529 } 1530 1531 /* Add udf info structure to linked list */ 1532 rv = _bcm_udf_td3_object_info_add(unit, udf_info, &obj_info); 1533 if ((BCM_FAILURE(rv)) || (obj_info == NULL)) { 1534 return rv; 1535 } 1536 1537 sal_memset(&cfg_data, 0x0, sizeof(cfg_data)); 1538 /* Allocate udf chunks */ 1539 rv = _udf_td3_hw_policy_cmd_alloc(unit, obj_info, &cfg_data); 1540 BCM_IF_ERROR_GOTO_CLEANUP(rv); 1541 1542 /* Install UDF object */ 1543 rv = _udf_td3_hw_policy_cmd_install(unit, obj_info, &cfg_data); 1544 BCM_IF_ERROR_GOTO_CLEANUP(rv); 1545 1546 /* update udf_id in the offset_info */ 1547 obj_info->udf_id = *udf_id; 1548 1549 if (hints != NULL) { 1550 1551 if (hints->flags & BCM_UDF_CREATE_O_FIELD_INGRESS) { 1552 obj_info->flags |= _BCM_UDF_TD3_OBJ_IFP; 1553 } 1554 if (hints->flags & BCM_UDF_CREATE_O_FIELD_LOOKUP) { 1555 obj_info->flags |= _BCM_UDF_TD3_OBJ_VFP; 1556 } 1557 if (hints->flags & BCM_UDF_CREATE_O_RANGE_CHECK) { 1558 obj_info->flags |= _BCM_UDF_TD3_OBJ_RANGE_CHECK; 1559 } 1560 } 1561 1562 cleanup: 1563 if (BCM_FAILURE(rv)) { 1564 if ((id_running_allocated == 1) && 1565 (UDF_CONTROL(unit)->udf_id_running != _BCM_UDF_TD3_OBJ_MAX_ID)) { 1566 /* Decrement the running udf id */ 1567 UDF_CONTROL(unit)->udf_id_running -= 1; 1568 } 1569 1570 /* Delete the object node */ 1571 if (obj_info != NULL) { 1572 _BCM_UDF_OBJ_NODE_DEL(unit, obj_info, 1573 UDF_TD3_CTRL(unit)->udf_obj_head); 1574 _BCM_UDF_FREE(obj_info); 1575 } 1576 } 1577 1578 return rv; 1579 } 1580 int 1581 _bcm_udf_td3_destroy(int unit, bcm_udf_id_t udf_id) 1582 { 1583 _bcm_udf_td3_obj_info_t *obj_info = NULL; 1584 1585 BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_get(unit, udf_id, &obj_info)); 1586 1587 /* De-allocate HW Resource */ 1588 BCM_IF_ERROR_RETURN(_udf_td3_hw_policy_cmd_uninstall(unit, obj_info)); 1589 /* Detach UDF object info from its database. */ 1590 BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_delete(unit, obj_info)); 1591 1592 return BCM_E_NONE; 1593 } 1594 1595 int 1596 _bcm_udf_td3_chunk_info_get( 1597 int unit, 1598 bcm_udf_id_t udf_id, 1599 bcm_udf_chunk_info_t *udf_chunk_info) 1600 { 1601 _bcm_udf_td3_obj_info_t *obj_info = NULL; 1602 1603 if (udf_chunk_info == NULL) { 1604 return BCM_E_PARAM; 1605 } 1606 1607 BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_get(unit, udf_id, &obj_info)); 1608 1609 udf_chunk_info->offset = obj_info->offset; 1610 udf_chunk_info->width = obj_info->width; 1611 udf_chunk_info->abstract_pkt_format = obj_info->abstr_pkt_fmt; 1612 udf_chunk_info->chunk_bmap = obj_info->chunk_bmap; 1613 return BCM_E_NONE; 1614 } 1615 1616 int 1617 _bcm_udf_td3_abstr_pkt_format_obj_list_get( 1618 int unit, 1619 bcm_udf_abstract_pkt_format_t abstract_pkt_format, 1620 int max, 1621 bcm_udf_id_t *udf_id_list, 1622 int *actual) 1623 { 1624 int ct = 0; 1625 bcm_udf_id_t id_list[32] = {0}; 1626 _bcm_udf_td3_obj_info_t *obj_info = NULL; 1627 1628 /* Validate input params */ 1629 if ((udf_id_list == NULL) || (actual == NULL)) { 1630 return BCM_E_PARAM; 1631 } 1632 1633 /* check if pkt format is in valid range */ 1634 _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(unit, abstract_pkt_format); 1635 1636 obj_info = UDF_TD3_CTRL(unit)->udf_obj_head; 1637 1638 while (obj_info != NULL) { 1639 if (obj_info->abstr_pkt_fmt == abstract_pkt_format) { 1640 id_list[ct++] = obj_info->udf_id; 1641 } 1642 _BCM_UDF_OBJ_NODE_NEXT(obj_info); 1643 } 1644 1645 if (ct > max) { 1646 return BCM_E_PARAM; 1647 } 1648 1649 sal_memcpy(udf_id_list, id_list, sizeof(bcm_udf_id_t) * ct); 1650 *actual = ct; 1651 return BCM_E_NONE; 1652 } 1653 1654 STATIC 1655 int _bcm_udf_td3_abstr_pkt_format_info_get( 1656 int unit, 1657 bcm_udf_abstract_pkt_format_t abstract_pkt_format, 1658 bcm_udf_abstract_pkt_format_info_t *pkt_format_info) 1659 { 1660 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 1661 1662 if (pkt_format_info == NULL) { 1663 return BCM_E_PARAM; 1664 } 1665 1666 /* Validate whether UDF module is attached */ 1667 if (UDF_TD3_CTRL(unit) == NULL) { 1668 return BCM_E_INIT; 1669 } 1670 1671 /* check if pkt format is in valid range */ 1672 _BCM_UDF_ABSTR_PKT_FORMAT_VALIDATE(unit, abstract_pkt_format); 1673 1674 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, abstract_pkt_format); 1675 if (pkt_fmt_hw_info == NULL) { 1676 return BCM_E_INTERNAL; 1677 } 1678 1679 pkt_format_info->base_offset = pkt_fmt_hw_info->base_offset; 1680 pkt_format_info->num_chunks_max = 1681 _BCM_UDF_BYTE_TO_CHUNK(pkt_fmt_hw_info->max_extract_bytes); 1682 pkt_format_info->chunk_bmap_used = pkt_fmt_hw_info->chunk_bmap_used; 1683 pkt_format_info->unavail_chunk_bmap = pkt_fmt_hw_info->unavail_chunk_bmap; 1684 1685 return BCM_E_NONE; 1686 } 1687 1688 /* ceh field string */ 1689 typedef struct _flex_ceh_field_str_s { 1690 char field_str[40]; 1691 } _flex_ceh_field_str_t; 1692 1693 /* Tunnel term type to CEH string mapping */ 1694 STATIC 1695 _flex_ceh_field_str_t flex_tunnel_term_type_arr[bcmUdfTunnelTermFlowTypeLastCount] = { 1696 {"MIM_TERM_PYLD_TYPE_IP"}, 1697 {"MIM_TERM_PYLD_TYPE_NON_IP"}, 1698 {"L2_MPLS_TERM_PYLD_TYPE_IP"}, 1699 {"L2_MPLS_TERM_PYLD_TYPE_NON_IP"}, 1700 {"L2GRE_TERM_PYLD_TYPE_IP"}, 1701 {"L2GRE_TERM_PYLD_TYPE_NON_IP"}, 1702 {"VXLAN_TERM_PYLD_TYPE_IP"}, 1703 {"VXLAN_TERM_PYLD_TYPE_NON_IP"}, 1704 {"L3_MPLS_TERM"}, 1705 {"L3_TUN_TERM"}, 1706 }; 1707 1708 STATIC 1709 _flex_ceh_field_str_t _udf_chunk_ceh_str[_BCM_UDF_TD3_MAX_CHUNKS] = { 1710 {"UDF_1_CHUNK_0"}, {"UDF_1_CHUNK_1"}, 1711 {"UDF_1_CHUNK_2"}, {"UDF_1_CHUNK_3"}, 1712 {"UDF_1_CHUNK_4"}, {"UDF_1_CHUNK_5"}, 1713 {"UDF_1_CHUNK_6"}, {"UDF_1_CHUNK_7"}, 1714 {"UDF_2_CHUNK_0"}, {"UDF_2_CHUNK_1"}, 1715 {"UDF_2_CHUNK_2"}, {"UDF_2_CHUNK_3"}, 1716 {"UDF_2_CHUNK_4"}, {"UDF_2_CHUNK_5"}, 1717 {"UDF_2_CHUNK_6"}, {"UDF_2_CHUNK_7"}, 1718 }; 1719 1720 /* 1721 * Get API to retrieve chunk bitmap. 1722 */ 1723 STATIC int 1724 _bcm_udf_td3_field_bus_merge_profile_get(int unit, 1725 bcm_udf_tunnel_term_flow_type_t flow_type, 1726 uint32 *chunk_bmap) 1727 { 1728 int rv; 1729 uint32 fmt_buf = 0; 1730 uint32 val; 1731 uint8 chunk, f; 1732 uint32 buf[100]={0}; 1733 uint32 profile_idx; 1734 soc_field_t assign_ctrl_field; 1735 soc_cancun_ceh_field_info_t ceh_info; 1736 soc_format_t fmt = FLEX_ASSIGNMENT_CTRL_FORMATfmt; 1737 soc_mem_t mem = FIELD_BUS_MERGE_PROFILEm; 1738 soc_mem_info_t *meminfo; 1739 1740 meminfo = &SOC_MEM_INFO(unit, mem); 1741 1742 /* Retrieve flow index from CEH flex db */ 1743 rv = soc_cancun_ceh_obj_field_get(unit, 1744 "FIELD_BUS_MERGE_PROFILE_INDEX", 1745 flex_tunnel_term_type_arr[flow_type].field_str, 1746 &ceh_info); 1747 if (SOC_FAILURE(rv)) { 1748 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 1749 "Flow type %d not found in CEH DB.\n\r"), flow_type)); 1750 return rv; 1751 } 1752 1753 profile_idx = ceh_info.value; 1754 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, profile_idx, buf); 1755 BCM_IF_ERROR_RETURN(rv); 1756 1757 for (chunk = 0; chunk < _BCM_UDF_TD3_MAX_CHUNKS; chunk++) { 1758 rv = soc_cancun_ceh_obj_field_get(unit, 1759 "FIELD_BUS_MERGE_PROFILE_UDF_CONTAINERS", 1760 _udf_chunk_ceh_str[chunk].field_str, 1761 &ceh_info); 1762 if (SOC_FAILURE(rv)) { 1763 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 1764 "Chunk[%d : %s] Assignment control offset not found in CEH DB.\n\r"), 1765 chunk, _udf_chunk_ceh_str[chunk].field_str)); 1766 return rv; 1767 } 1768 1769 assign_ctrl_field = INVALIDf; 1770 for (f = 0; f < meminfo->nFields; f++) { 1771 if (ceh_info.offset == meminfo->fields[f].bp) { 1772 assign_ctrl_field = meminfo->fields[f].field; 1773 break; 1774 } 1775 } 1776 1777 if (assign_ctrl_field == INVALIDf) { 1778 return BCM_E_INTERNAL; 1779 } 1780 1781 soc_mem_field_get(unit, mem, buf, assign_ctrl_field, &fmt_buf); 1782 /* coverity[address_of : FALSE] */ 1783 /* coverity[callee_ptr_arith : FALSE] */ 1784 soc_format_field_get(unit, fmt, &fmt_buf, SELECTf, &val); 1785 if (val == 0) { 1786 *chunk_bmap |= 1 << chunk; 1787 } 1788 } 1789 1790 return rv; 1791 } 1792 1793 /* 1794 * SET field bus merge profile for given UDF chunk bitmap 1795 */ 1796 STATIC int 1797 _bcm_udf_td3_field_bus_merge_profile_set(int unit, 1798 bcm_udf_tunnel_term_flow_type_t flow_type, 1799 uint32 chunk_bmap) 1800 { 1801 int rv; 1802 uint32 fmt_buf = 0; 1803 uint32 val; 1804 uint8 chunk, f; 1805 uint32 buf[100]={0}; 1806 uint32 profile_idx; 1807 soc_field_t assign_ctrl_field; 1808 soc_cancun_ceh_field_info_t ceh_info; 1809 soc_format_t fmt = FLEX_ASSIGNMENT_CTRL_FORMATfmt; 1810 soc_mem_t mem = FIELD_BUS_MERGE_PROFILEm; 1811 soc_mem_info_t *meminfo; 1812 1813 meminfo = &SOC_MEM_INFO(unit, mem); 1814 /* Retrieve flow index from CEH flex db */ 1815 rv = soc_cancun_ceh_obj_field_get(unit, 1816 "FIELD_BUS_MERGE_PROFILE_INDEX", 1817 flex_tunnel_term_type_arr[flow_type].field_str, 1818 &ceh_info); 1819 if (SOC_FAILURE(rv)) { 1820 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 1821 "Flow type %d not found in CEH DB.\n\r"), flow_type)); 1822 return rv; 1823 } 1824 1825 profile_idx = ceh_info.value; 1826 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, profile_idx, buf); 1827 BCM_IF_ERROR_RETURN(rv); 1828 1829 for (chunk = 0; chunk < _BCM_UDF_TD3_MAX_CHUNKS; chunk++) { 1830 rv = soc_cancun_ceh_obj_field_get(unit, 1831 "FIELD_BUS_MERGE_PROFILE_UDF_CONTAINERS", 1832 _udf_chunk_ceh_str[chunk].field_str, 1833 &ceh_info); 1834 if (SOC_FAILURE(rv)) { 1835 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 1836 "Chunk[%d : %s] Assignment control offset not found in CEH DB.\n\r"), 1837 chunk, _udf_chunk_ceh_str[chunk].field_str)); 1838 return rv; 1839 } 1840 1841 assign_ctrl_field = INVALIDf; 1842 for (f = 0; f < meminfo->nFields; f++) { 1843 if (ceh_info.offset == meminfo->fields[f].bp) { 1844 assign_ctrl_field = meminfo->fields[f].field; 1845 break; 1846 } 1847 } 1848 1849 if (assign_ctrl_field == INVALIDf) { 1850 return BCM_E_INTERNAL; 1851 } 1852 fmt_buf = 0x0; 1853 val = (chunk_bmap & (1 << chunk)) ? 0 : 1; 1854 soc_format_field32_set(unit, fmt, &fmt_buf, SELECTf, val); 1855 soc_mem_field_set(unit, mem, (uint32 *)buf, 1856 assign_ctrl_field, &fmt_buf); 1857 1858 } 1859 1860 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, 1861 profile_idx, buf); 1862 1863 return rv; 1864 } 1865 1866 STATIC 1867 int _bcm_udf_flow_based_chunk_arrange_set( 1868 int unit, 1869 bcm_udf_tunnel_term_flow_type_t flow_type, 1870 uint32 chunk_bmap) 1871 { 1872 if (flow_type >= bcmUdfTunnelTermFlowTypeLastCount) { 1873 return BCM_E_PARAM; 1874 } 1875 1876 if (chunk_bmap & ~((1 << _BCM_UDF_TD3_MAX_CHUNKS) - 1)) { 1877 return BCM_E_PARAM; 1878 } 1879 1880 return _bcm_udf_td3_field_bus_merge_profile_set(unit, 1881 flow_type, chunk_bmap); 1882 } 1883 1884 STATIC 1885 int _bcm_udf_flow_based_chunk_arrange_get( 1886 int unit, 1887 bcm_udf_tunnel_term_flow_type_t flow_type, 1888 uint32 *chunk_bmap) 1889 { 1890 if (chunk_bmap == NULL) { 1891 return BCM_E_PARAM; 1892 } 1893 1894 return _bcm_udf_td3_field_bus_merge_profile_get(unit, 1895 flow_type, chunk_bmap); 1896 } 1897 1898 STATIC int 1899 _bcm_udf_td3_format_field_dump(int unit, soc_mem_t mem, uint32 index) 1900 { 1901 uint32 buf[100]={0}; 1902 uint32 f_buf[50]={0}; 1903 soc_format_t fmt; 1904 uint32 id = 0, valid, dst_cont_id, src_offset; 1905 int rv; 1906 1907 if (!((mem == IP_PARSER0_HFE_POLICY_TABLE_0m) || 1908 (mem == IP_PARSER1_HFE_POLICY_TABLE_0m) || 1909 (mem == IP_PARSER1_HFE_POLICY_TABLE_1m) || 1910 (mem == IP_PARSER1_HFE_POLICY_TABLE_2m) || 1911 (mem == IP_PARSER1_HFE_POLICY_TABLE_3m) || 1912 (mem == IP_PARSER1_HFE_POLICY_TABLE_4m) || 1913 (mem == IP_PARSER2_HFE_POLICY_TABLE_0m) || 1914 (mem == IP_PARSER2_HFE_POLICY_TABLE_1m) || 1915 (mem == IP_PARSER2_HFE_POLICY_TABLE_2m) || 1916 (mem == IP_PARSER2_HFE_POLICY_TABLE_3m) || 1917 (mem == IP_PARSER2_HFE_POLICY_TABLE_4m))) { 1918 return BCM_E_NONE; 1919 } 1920 1921 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, (uint32 *)buf); 1922 BCM_IF_ERROR_RETURN(rv); 1923 1924 soc_mem_field_get(unit, mem, (uint32 *)buf, CMD_POLICY_DATAf, (uint32 *)f_buf); 1925 1926 if (mem == IP_PARSER0_HFE_POLICY_TABLE_0m) { 1927 soc_format_t fmt = IP_PARSER0_HFE_CMD_POLICY_DATAfmt; 1928 1929 LOG_CLI(("CMD VALID SRC_PKT_OFFSET\n\r")); 1930 LOG_CLI(("=== ===== ==============\n\r")); 1931 id = 8; 1932 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_A_8_VALIDf); 1933 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_A_8_SRC_PKT_OFFSETf); 1934 LOG_CLI(("%2d %5d %10d\n\r", id, valid, src_offset)); 1935 1936 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_A_9_VALIDf); 1937 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_A_9_SRC_PKT_OFFSETf); 1938 id++; LOG_CLI(("%2d %5d %10d\n\r", id, valid, src_offset)); 1939 return BCM_E_NONE; 1940 } 1941 1942 if ((mem == IP_PARSER1_HFE_POLICY_TABLE_0m) || 1943 (mem == IP_PARSER1_HFE_POLICY_TABLE_1m) || 1944 (mem == IP_PARSER1_HFE_POLICY_TABLE_2m) || 1945 (mem == IP_PARSER1_HFE_POLICY_TABLE_3m) || 1946 (mem == IP_PARSER1_HFE_POLICY_TABLE_4m)) { 1947 fmt = IP_PARSER1_HFE_CMD_POLICY_DATAfmt; 1948 } else { 1949 fmt = IP_PARSER2_HFE_CMD_POLICY_DATAfmt; 1950 } 1951 1952 LOG_CLI(("ID VALID DEST_CONT_ID SRC_PKT_OFFSET\n\r")); 1953 LOG_CLI(("== ===== ============ ==============\n\r")); 1954 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_0_VALIDf); 1955 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_0_DEST_CONT_IDf); 1956 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_0_SRC_PKT_OFFSETf); 1957 LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1958 1959 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_1_VALIDf); 1960 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_1_DEST_CONT_IDf); 1961 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_1_SRC_PKT_OFFSETf); 1962 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1963 1964 1965 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_2_VALIDf); 1966 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_2_DEST_CONT_IDf); 1967 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_2_SRC_PKT_OFFSETf); 1968 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1969 1970 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_3_VALIDf); 1971 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_3_DEST_CONT_IDf); 1972 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_3_SRC_PKT_OFFSETf); 1973 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1974 1975 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_4_VALIDf); 1976 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_4_DEST_CONT_IDf); 1977 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_4_SRC_PKT_OFFSETf); 1978 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1979 1980 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_5_VALIDf); 1981 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_5_DEST_CONT_IDf); 1982 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_5_SRC_PKT_OFFSETf); 1983 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1984 1985 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_6_VALIDf); 1986 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_6_DEST_CONT_IDf); 1987 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_6_SRC_PKT_OFFSETf); 1988 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1989 1990 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_7_VALIDf); 1991 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_7_DEST_CONT_IDf); 1992 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_7_SRC_PKT_OFFSETf); 1993 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1994 1995 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_8_VALIDf); 1996 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_8_DEST_CONT_IDf); 1997 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_8_SRC_PKT_OFFSETf); 1998 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 1999 2000 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_9_VALIDf); 2001 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_9_DEST_CONT_IDf); 2002 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_9_SRC_PKT_OFFSETf); 2003 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 2004 2005 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_10_VALIDf); 2006 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_10_DEST_CONT_IDf); 2007 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_10_SRC_PKT_OFFSETf); 2008 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 2009 2010 valid = soc_format_field32_get(unit, fmt, f_buf, CMD_C_11_VALIDf); 2011 dst_cont_id = soc_format_field32_get(unit, fmt, f_buf, CMD_C_11_DEST_CONT_IDf); 2012 src_offset = soc_format_field32_get(unit, fmt, f_buf, CMD_C_11_SRC_PKT_OFFSETf); 2013 id++; LOG_CLI(("%2d %5d %10d %10d\n\r", id, valid, dst_cont_id, src_offset)); 2014 2015 return BCM_E_NONE; 2016 } 2017 2018 STATIC 2019 void _udf_print_in_bin(uint16 n) 2020 { 2021 int ct = 0; 2022 2023 while (n) { 2024 LOG_CLI(("%d", (n & 1))); 2025 n >>= 1; 2026 2027 ct++; 2028 if (ct == 4) { 2029 LOG_CLI((" ")); 2030 ct = 0; 2031 } 2032 } 2033 } 2034 2035 int 2036 _bcm_udf_object_hw_info_dump(int unit, bcm_udf_id_t udf_id) 2037 { 2038 uint8 stg, hfe_ct; 2039 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2040 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *hw_info = NULL; 2041 2042 BCM_IF_ERROR_RETURN(_bcm_udf_td3_object_info_get(unit, udf_id, &obj_info)); 2043 2044 LOG_CLI(("UDF Object ID [%d] Information:\n\r", udf_id)); 2045 LOG_CLI(("Offset..................%d\n\r", obj_info->offset)); 2046 LOG_CLI(("Width...................%d\n\r", obj_info->width)); 2047 LOG_CLI(("Abstr Pkt Fmt...........%s\n\r", _udf_abstr_pkt_fmt_name(obj_info->abstr_pkt_fmt))); 2048 LOG_CLI(("Chunk Bitmap............0x%x\n\r", obj_info->chunk_bmap)); 2049 for (stg = 0; stg < _BCM_UDF_MAX_PARSER_STAGES; stg++) { 2050 LOG_CLI(("HW CMD Bitmap%d..........0x%x\n\r", stg, obj_info->hw_cmd_bmap[stg])); 2051 } 2052 2053 hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, obj_info->abstr_pkt_fmt); 2054 if (hw_info == NULL) { 2055 return BCM_E_INTERNAL; 2056 } 2057 2058 LOG_CLI(("Abstr Packet Format Information:\n\r")); 2059 LOG_CLI(("Parser............................%d\n\r", hw_info->parser)); 2060 LOG_CLI(("Num stages supported..............%d\n\r", hw_info->num_stages)); 2061 for (stg = 0; stg < hw_info->num_stages; stg++) { 2062 if (hw_info->stage_policy_mem[stg] != INVALIDm) { 2063 LOG_CLI(("Stage[%d] Policy Mem........................%s\n\r", stg, 2064 SOC_MEM_NAME(unit, hw_info->stage_policy_mem[stg]))); 2065 } 2066 LOG_CLI(("Stage[%d] HFE Profile Ptr....................{", stg)); 2067 for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stg]; hfe_ct++) { 2068 if (hfe_ct == (hw_info->hfe_prof_ptr_arr_len[stg] - 1)) { 2069 LOG_CLI(("%d}\n\r", hw_info->hfe_profile_ptr[stg][hfe_ct])); 2070 } else { 2071 LOG_CLI(("%d, ", hw_info->hfe_profile_ptr[stg][hfe_ct])); 2072 } 2073 } 2074 LOG_CLI(("Stage[%d] Number of CMDs supported...........%d\n\r", stg, 2075 hw_info->num_cmds[stg])); 2076 } 2077 LOG_CLI(("Maximum Extr Bytes................%d\n\r", hw_info->max_extract_bytes)); 2078 LOG_CLI(("Used Extr Bytes...................%d\n\r", hw_info->extracted_bytes)); 2079 LOG_CLI(("Chunk Bitmap Used (bits)..........0x%x (", hw_info->chunk_bmap_used)); 2080 _udf_print_in_bin((uint16)hw_info->chunk_bmap_used); 2081 LOG_CLI((")\n\r")); 2082 LOG_CLI(("Unavailable Chunk Bitmap (bits)...0x%x (", hw_info->unavail_chunk_bmap)); 2083 _udf_print_in_bin((uint16)hw_info->chunk_bmap_used); 2084 LOG_CLI((")\n\r")); 2085 for (stg = 0; stg < hw_info->num_stages; stg++) { 2086 LOG_CLI(("CMD Bitmap%d (bits)................0x%x (", stg, hw_info->valid_cmd_bmap[stg])); 2087 _udf_print_in_bin(hw_info->valid_cmd_bmap[stg]); 2088 LOG_CLI((")\n\r")); 2089 } 2090 2091 for (stg = 0; stg < hw_info->num_stages; stg++) { 2092 if (hw_info->stage_policy_mem[stg] != INVALIDm) { 2093 for (hfe_ct = 0; hfe_ct < hw_info->hfe_prof_ptr_arr_len[stg]; hfe_ct++) { 2094 _bcm_udf_td3_format_field_dump(unit, hw_info->stage_policy_mem[stg], 2095 hw_info->hfe_profile_ptr[stg][hfe_ct]); 2096 } 2097 } 2098 } 2099 2100 return BCM_E_NONE; 2101 } 2102 2103 /* 2104 * Routine to dump all the configured UDF objects info. 2105 */ 2106 STATIC void 2107 _bcm_udf_td3_sw_dump(int unit) 2108 { 2109 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2110 2111 if (UDF_TD3_CTRL(unit)->udf_obj_head == NULL) { 2112 return; 2113 } 2114 2115 obj_info = UDF_TD3_CTRL(unit)->udf_obj_head; 2116 2117 while (obj_info != NULL) { 2118 _bcm_udf_object_hw_info_dump(unit, obj_info->udf_id); 2119 _BCM_UDF_OBJ_NODE_NEXT(obj_info); 2120 } 2121 } 2122 2123 2124 /* 2125 * Routine to retrieve number of UDF objects associated 2126 * to the given UDF Chunk Bitmap 2127 */ 2128 int 2129 _bcm_udf_td3_chunk_id_multi_get( 2130 int unit, 2131 uint32 udf_chunk_bmap, 2132 int max, 2133 int *objects_list, 2134 int *actual) 2135 { 2136 int idx = 0; 2137 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2138 2139 obj_info = UDF_TD3_CTRL(unit)->udf_obj_head; 2140 while (obj_info != NULL) { 2141 if (obj_info->chunk_bmap & udf_chunk_bmap) { 2142 if (idx >= max) { 2143 return BCM_E_PARAM; 2144 } 2145 objects_list[idx++] = obj_info->udf_id; 2146 } 2147 _BCM_UDF_OBJ_NODE_NEXT(obj_info); 2148 } 2149 *actual = idx; 2150 2151 return BCM_E_NONE; 2152 } 2153 2154 /* 2155 * Routine to return UDF chunk dedicated to Range Checker. 2156 */ 2157 int 2158 _bcm_udf_td3_range_checker_chunk_info_get( 2159 int unit, 2160 uint8 *num_chunks, 2161 uint32 *chunk_bmap) 2162 { 2163 if ((num_chunks == NULL) || (chunk_bmap == NULL)) { 2164 return BCM_E_PARAM; 2165 } 2166 2167 *num_chunks = 1; 2168 *chunk_bmap = _BCM_UDF_TD3_RANGE_CHUNK_BMAP; 2169 return BCM_E_NONE; 2170 } 2171 2172 #if defined (BCM_WARM_BOOT_SUPPORT) 2173 2174 STATIC int 2175 _udf_td3_wb_abstr_pkt_fmt_recover(int unit, _bcm_udf_td3_obj_info_t *obj_info) 2176 { 2177 uint8 stg; 2178 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 2179 2180 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, obj_info->abstr_pkt_fmt); 2181 if (pkt_fmt_hw_info == NULL) { 2182 return BCM_E_INTERNAL; 2183 } 2184 2185 pkt_fmt_hw_info->extracted_bytes += obj_info->width; 2186 pkt_fmt_hw_info->chunk_bmap_used |= obj_info->chunk_bmap; 2187 for (stg = 0; stg < pkt_fmt_hw_info->num_stages; stg++) { 2188 pkt_fmt_hw_info->valid_cmd_bmap[stg] |= obj_info->hw_cmd_bmap[stg]; 2189 } 2190 2191 return BCM_E_NONE; 2192 } 2193 2194 /* 2195 * Routine to Recover UDF Object information during WarmBoot. 2196 */ 2197 STATIC int 2198 _bcm_udf_td3_wb_obj_info_recover_1_0(int unit, uint8 **scache_ptr) 2199 { 2200 _bcm_udf_td3_wb_obj_info_t *scache_obj_ptr; 2201 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2202 int ct; 2203 uint16 num_udfs = 0; 2204 uint8 num_chunks = 0; 2205 2206 /* Retrieve number of UDFs */ 2207 sal_memcpy(&num_udfs, *scache_ptr, sizeof(num_udfs)); 2208 *scache_ptr += sizeof(num_udfs); 2209 2210 /* Retrieve the UDF objects */ 2211 scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_t *)(*scache_ptr); 2212 for (ct = 0; ct < num_udfs; ct++) { 2213 /* Allocate memory for UDF object info. */ 2214 obj_info = NULL; 2215 _BCM_UDF_ALLOC(obj_info, sizeof(_bcm_udf_td3_obj_info_t), 2216 "UDF object info."); 2217 if (obj_info == NULL) { 2218 return BCM_E_MEMORY; 2219 } 2220 2221 obj_info->udf_id = scache_obj_ptr->udf_id; 2222 obj_info->offset = scache_obj_ptr->offset; 2223 obj_info->chunk_bmap = scache_obj_ptr->chunk_bmap; 2224 2225 (void)_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap, 2226 &num_chunks, NULL); 2227 obj_info->width = _BCM_UDF_CHUNK_TO_BYTE(num_chunks); 2228 obj_info->hw_cmd_bmap[0] = scache_obj_ptr->hw_cmd_bmap1; 2229 obj_info->hw_cmd_bmap[1] = scache_obj_ptr->hw_cmd_bmap2; 2230 obj_info->abstr_pkt_fmt = scache_obj_ptr->abstr_pkt_fmt; 2231 2232 BCM_IF_ERROR_RETURN(_udf_td3_wb_abstr_pkt_fmt_recover(unit, obj_info)); 2233 2234 /* Add obj_info item to the linked list */ 2235 _BCM_UDF_OBJ_NODE_ADD(unit, (obj_info), 2236 UDF_TD3_CTRL(unit)->udf_obj_head); 2237 scache_obj_ptr++; 2238 } 2239 2240 *scache_ptr = (uint8 *)scache_obj_ptr; 2241 return BCM_E_NONE; 2242 } 2243 2244 /* 2245 * Routine to recover UDF Abstract Pkt Fmt default cmd_policy_data. 2246 */ 2247 STATIC int 2248 _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_1_0(int unit, uint8 **scache_ptr) 2249 { 2250 uint8 stage, len; 2251 soc_mem_t policy_mem; 2252 uint8 buf[100]; 2253 uint32 hfe_profile_ptr; 2254 uint8 *cmd_pol_data_buf = NULL; 2255 bcm_udf_abstract_pkt_format_t pkt_fmt; 2256 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 2257 2258 for (pkt_fmt = bcmUdfAbstractPktFormatLlc; 2259 pkt_fmt < bcmUdfAbstractPktFormatLastCount; 2260 pkt_fmt++) { 2261 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 2262 if (pkt_fmt_hw_info == NULL) { 2263 continue; 2264 } 2265 2266 /* 2267 * INT containers are fixed, need not sync the containers. 2268 */ 2269 if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) || 2270 (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) { 2271 continue; 2272 } 2273 2274 for (stage = 0; stage < _BCM_UDF_MAX_PARSER_STAGES; stage++) { 2275 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage]; 2276 hfe_profile_ptr = pkt_fmt_hw_info->hfe_profile_ptr[stage][0]; 2277 2278 if (policy_mem == INVALIDm || policy_mem == 0) { 2279 continue; 2280 } 2281 2282 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf); 2283 2284 cmd_pol_data_buf = NULL; 2285 if (pkt_fmt_hw_info->chunk_bmap_used) { 2286 _BCM_UDF_ALLOC(cmd_pol_data_buf, len, "UDF WB CMD_POLICY_DATA alloc"); 2287 if (cmd_pol_data_buf == NULL) { 2288 return BCM_E_MEMORY; 2289 } 2290 2291 sal_memcpy(cmd_pol_data_buf, *scache_ptr, len); 2292 *scache_ptr += len; 2293 } else { 2294 sal_memset(buf, 0x0, sizeof(buf)); 2295 2296 BCM_IF_ERROR_RETURN(soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY, 2297 hfe_profile_ptr, (uint32 *) buf)); 2298 2299 _BCM_UDF_ALLOC(cmd_pol_data_buf, len, "UDF default CMD Policy data"); 2300 if (cmd_pol_data_buf == NULL) { 2301 return BCM_E_MEMORY; 2302 } 2303 2304 soc_mem_field_get(unit, policy_mem, (uint32 *)buf, 2305 CMD_POLICY_DATAf, (uint32 *)cmd_pol_data_buf); 2306 } 2307 2308 pkt_fmt_hw_info->cmd_policy_data[stage] = cmd_pol_data_buf; 2309 } 2310 } 2311 2312 return BCM_E_NONE; 2313 } 2314 2315 2316 /* 2317 * Routine to Recover UDF Object information during WarmBoot. 2318 */ 2319 STATIC int 2320 _bcm_udf_td3_wb_obj_info_recover_2_0(int unit, uint16 recovered_version, uint8 **scache_ptr) 2321 { 2322 int ct; 2323 uint8 stg; 2324 uint8 num_chunks = 0; 2325 uint16 num_udfs = 0; 2326 uint8 num_stages = 0; 2327 _bcm_udf_td3_wb_obj_info_2_t *scache_obj_ptr; 2328 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2329 2330 /* Retrieve number of UDFs */ 2331 sal_memcpy(&num_udfs, *scache_ptr, sizeof(num_udfs)); 2332 *scache_ptr += sizeof(num_udfs); 2333 2334 /* Retrieve the UDF objects */ 2335 scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_2_t *)(*scache_ptr); 2336 for (ct = 0; ct < num_udfs; ct++) { 2337 /* Allocate memory for UDF object info. */ 2338 obj_info = NULL; 2339 _BCM_UDF_ALLOC(obj_info, sizeof(_bcm_udf_td3_obj_info_t), 2340 "UDF object info."); 2341 if (obj_info == NULL) { 2342 return BCM_E_MEMORY; 2343 } 2344 2345 obj_info->udf_id = scache_obj_ptr->udf_id; 2346 obj_info->offset = scache_obj_ptr->offset; 2347 obj_info->chunk_bmap = scache_obj_ptr->chunk_bmap; 2348 2349 (void)_udf_chunk_bmap_to_chunks(obj_info->chunk_bmap, 2350 &num_chunks, NULL); 2351 obj_info->width = _BCM_UDF_CHUNK_TO_BYTE(num_chunks); 2352 if (recovered_version > BCM_WB_VERSION_1_0) { 2353 num_stages = scache_obj_ptr->num_stages; 2354 } else { 2355 num_stages = 2; 2356 } 2357 2358 for (stg = 0; stg < num_stages; stg++) { 2359 obj_info->hw_cmd_bmap[stg] = scache_obj_ptr->hw_cmd_bmap[stg]; 2360 } 2361 obj_info->abstr_pkt_fmt = scache_obj_ptr->abstr_pkt_fmt; 2362 2363 BCM_IF_ERROR_RETURN(_udf_td3_wb_abstr_pkt_fmt_recover(unit, obj_info)); 2364 2365 /* Add obj_info item to the linked list */ 2366 _BCM_UDF_OBJ_NODE_ADD(unit, (obj_info), 2367 UDF_TD3_CTRL(unit)->udf_obj_head); 2368 scache_obj_ptr++; 2369 } 2370 2371 *scache_ptr = (uint8 *)scache_obj_ptr; 2372 return BCM_E_NONE; 2373 } 2374 2375 /* 2376 * Routine to recover UDF Abstract Pkt Fmt default cmd_policy_data. 2377 */ 2378 STATIC int 2379 _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_2_0(int unit, uint16 recovered_version, uint8 **scache_ptr) 2380 { 2381 uint8 stage, len; 2382 soc_mem_t policy_mem; 2383 uint8 num_stages = 0; 2384 uint8 *cmd_pol_data_buf = NULL; 2385 bcm_udf_abstract_pkt_format_t pkt_fmt; 2386 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 2387 2388 for (pkt_fmt = bcmUdfAbstractPktFormatLlc; 2389 pkt_fmt < bcmUdfAbstractPktFormatLastCount; 2390 pkt_fmt++) { 2391 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 2392 if (pkt_fmt_hw_info == NULL) { 2393 continue; 2394 } 2395 2396 if (recovered_version == BCM_WB_VERSION_1_0) { 2397 if (pkt_fmt >= bcmUdfAbstractPktFormatL3GreUnknownPayload) { 2398 continue; 2399 } 2400 num_stages = 2; 2401 } else { 2402 num_stages = pkt_fmt_hw_info->num_stages; 2403 } 2404 2405 for (stage = 0; stage < num_stages; stage++) { 2406 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage]; 2407 2408 if (policy_mem == INVALIDm) { 2409 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 2410 "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"), 2411 _udf_abstr_pkt_fmt_name(pkt_fmt), stage)); 2412 continue; 2413 } 2414 2415 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf); 2416 2417 if (pkt_fmt_hw_info->chunk_bmap_used) { 2418 cmd_pol_data_buf = pkt_fmt_hw_info->cmd_policy_data[stage]; 2419 sal_memcpy(cmd_pol_data_buf, *scache_ptr, len); 2420 *scache_ptr += len; 2421 pkt_fmt_hw_info->cmd_policy_data[stage] = cmd_pol_data_buf; 2422 } 2423 } 2424 } 2425 2426 return BCM_E_NONE; 2427 } 2428 2429 2430 2431 /* 2432 * Routine to Sync UDF Object information for WarmBoot. 2433 */ 2434 STATIC int 2435 _bcm_udf_td3_wb_obj_info_sync_1_0(int unit, uint8 **scache_ptr) 2436 { 2437 _bcm_udf_td3_wb_obj_info_t *scache_obj_ptr; 2438 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2439 uint16 *scache_num_udf_ptr = NULL; 2440 uint16 num_udfs = 0; 2441 2442 scache_num_udf_ptr = (uint16 *)(*scache_ptr); 2443 *scache_ptr += sizeof(num_udfs); 2444 2445 scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_t *)(*scache_ptr); 2446 2447 obj_info = UDF_TD3_CTRL(unit)->udf_obj_head; 2448 while (obj_info != NULL) { 2449 scache_obj_ptr->udf_id = obj_info->udf_id; 2450 scache_obj_ptr->offset = obj_info->offset; 2451 scache_obj_ptr->chunk_bmap = obj_info->chunk_bmap; 2452 scache_obj_ptr->abstr_pkt_fmt = obj_info->abstr_pkt_fmt; 2453 scache_obj_ptr->hw_cmd_bmap1 = obj_info->hw_cmd_bmap[0]; 2454 scache_obj_ptr->hw_cmd_bmap2 = obj_info->hw_cmd_bmap[1]; 2455 2456 scache_obj_ptr++; 2457 num_udfs++; 2458 _BCM_UDF_OBJ_NODE_NEXT(obj_info); 2459 } 2460 sal_memcpy(scache_num_udf_ptr, &num_udfs, sizeof(num_udfs)); 2461 2462 *scache_ptr = (uint8 *)scache_obj_ptr; 2463 return BCM_E_NONE; 2464 } 2465 /* 2466 * Routine to Sync UDF Object information for WarmBoot. 2467 */ 2468 STATIC int 2469 _bcm_udf_td3_wb_obj_info_sync_2_0(int unit, uint8 **scache_ptr) 2470 { 2471 uint8 stg; 2472 _bcm_udf_td3_wb_obj_info_2_t *scache_obj_ptr; 2473 _bcm_udf_td3_obj_info_t *obj_info = NULL; 2474 uint16 *scache_num_udf_ptr = NULL; 2475 uint16 num_udfs = 0; 2476 2477 scache_num_udf_ptr = (uint16 *)(*scache_ptr); 2478 *scache_ptr += sizeof(num_udfs); 2479 2480 scache_obj_ptr = (_bcm_udf_td3_wb_obj_info_2_t *)(*scache_ptr); 2481 2482 obj_info = UDF_TD3_CTRL(unit)->udf_obj_head; 2483 while (obj_info != NULL) { 2484 scache_obj_ptr->udf_id = obj_info->udf_id; 2485 scache_obj_ptr->offset = obj_info->offset; 2486 scache_obj_ptr->chunk_bmap = obj_info->chunk_bmap; 2487 scache_obj_ptr->abstr_pkt_fmt = obj_info->abstr_pkt_fmt; 2488 scache_obj_ptr->num_stages = _BCM_UDF_MAX_PARSER_STAGES; 2489 for (stg = 0; stg < _BCM_UDF_MAX_PARSER_STAGES; stg++) { 2490 scache_obj_ptr->hw_cmd_bmap[stg] = obj_info->hw_cmd_bmap[stg]; 2491 } 2492 2493 scache_obj_ptr++; 2494 num_udfs++; 2495 _BCM_UDF_OBJ_NODE_NEXT(obj_info); 2496 } 2497 sal_memcpy(scache_num_udf_ptr, &num_udfs, sizeof(num_udfs)); 2498 2499 *scache_ptr = (uint8 *)scache_obj_ptr; 2500 return BCM_E_NONE; 2501 } 2502 2503 /* 2504 * Routine to sync UDF Abstract Pkt Fmt default cmd_policy_data. 2505 */ 2506 STATIC int 2507 _bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_1_0(int unit, uint8 **scache_ptr) 2508 { 2509 uint8 stage, len; 2510 soc_mem_t policy_mem; 2511 uint8 *cmd_policy_data = NULL; 2512 bcm_udf_abstract_pkt_format_t pkt_fmt; 2513 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 2514 2515 for (pkt_fmt = bcmUdfAbstractPktFormatLlc; 2516 pkt_fmt < bcmUdfAbstractPktFormatLastCount; 2517 pkt_fmt++) { 2518 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 2519 if (pkt_fmt_hw_info == NULL) { 2520 continue; 2521 } 2522 2523 /* 2524 * INT containers are fixed, need not sync the containers. 2525 */ 2526 if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) || 2527 (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) { 2528 continue; 2529 } 2530 2531 if (pkt_fmt_hw_info->chunk_bmap_used) { 2532 for (stage = 0; stage < _BCM_UDF_MAX_PARSER_STAGES; stage++) { 2533 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage]; 2534 cmd_policy_data = pkt_fmt_hw_info->cmd_policy_data[stage]; 2535 2536 if (policy_mem == INVALIDm || policy_mem == 0) { 2537 continue; 2538 } 2539 2540 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf); 2541 sal_memcpy(*scache_ptr, cmd_policy_data, len); 2542 *scache_ptr += len; 2543 } 2544 } 2545 } 2546 2547 return BCM_E_NONE; 2548 } 2549 2550 2551 /* 2552 * Routine to sync UDF Abstract Pkt Fmt default cmd_policy_data. 2553 */ 2554 STATIC int 2555 _bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_2_0(int unit, uint8 **scache_ptr) 2556 { 2557 uint8 stage, len; 2558 soc_mem_t policy_mem; 2559 uint32 cancun_ver; 2560 uint8 *cmd_policy_data = NULL; 2561 bcm_udf_abstract_pkt_format_t pkt_fmt; 2562 _bcm_udf_td3_abstr_pkt_fmt_hw_info_t *pkt_fmt_hw_info; 2563 2564 for (pkt_fmt = bcmUdfAbstractPktFormatLlc; 2565 pkt_fmt < bcmUdfAbstractPktFormatLastCount; 2566 pkt_fmt++) { 2567 pkt_fmt_hw_info = _UDF_ABSTR_PKT_FMT_HW_INFO_GET(unit, pkt_fmt); 2568 if (pkt_fmt_hw_info == NULL) { 2569 continue; 2570 } 2571 2572 /* 2573 * INT containers are fixed, need not sync the containers. 2574 */ 2575 BCM_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 2576 if (SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 2577 if ((pkt_fmt == bcmUdfAbstractPktFormatUdpINT) || 2578 (pkt_fmt == bcmUdfAbstractPktFormatTcpINT)) { 2579 continue; 2580 } 2581 } 2582 2583 if (pkt_fmt_hw_info->chunk_bmap_used) { 2584 for (stage = 0; stage < pkt_fmt_hw_info->num_stages; stage++) { 2585 policy_mem = pkt_fmt_hw_info->stage_policy_mem[stage]; 2586 cmd_policy_data = pkt_fmt_hw_info->cmd_policy_data[stage]; 2587 2588 if (policy_mem == INVALIDm || policy_mem == 0) { 2589 LOG_ERROR(BSL_LS_BCM_UDF, (BSL_META_U(unit, 2590 "Invalid Policy mem for Abstract pkt fmt '%s', stage:%d.\n\r"), 2591 _udf_abstr_pkt_fmt_name(pkt_fmt), stage)); 2592 return BCM_E_INTERNAL; 2593 } 2594 2595 len = soc_mem_field_length(unit, policy_mem, CMD_POLICY_DATAf); 2596 sal_memcpy(*scache_ptr, cmd_policy_data, len); 2597 *scache_ptr += len; 2598 } 2599 } 2600 } 2601 2602 return BCM_E_NONE; 2603 } 2604 2605 2606 /* 2607 * Function: 2608 * _bcm_udf_td3_udf_wb_sync 2609 * Purpose: 2610 * Syncs UDF warmboot state to scache 2611 * Parameters: 2612 * unit - (IN) Unit number. 2613 * Returns: 2614 * BCM_E_XXX 2615 * Notes: 2616 */ 2617 STATIC int 2618 _bcm_udf_td3_wb_sync(int unit) 2619 { 2620 uint8 *scache_ptr; 2621 soc_scache_handle_t scache_handle; 2622 2623 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_UDF, 0); 2624 2625 BCM_IF_ERROR_RETURN 2626 (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 2627 0, &scache_ptr, 2628 BCM_WB_DEFAULT_VERSION, NULL)); 2629 if (UDF_CONTROL(unit) != NULL) { 2630 if (BCM_WB_DEFAULT_VERSION == BCM_WB_VERSION_1_0) { 2631 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_obj_info_sync_1_0(unit, &scache_ptr)); 2632 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_1_0(unit, &scache_ptr)); 2633 } else { 2634 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_obj_info_sync_2_0(unit, &scache_ptr)); 2635 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_abstr_pkt_fmt_info_sync_2_0(unit, &scache_ptr)); 2636 } 2637 } 2638 return BCM_E_NONE; 2639 } 2640 2641 /* Returns required scache size in bytes for version = 1_0 */ 2642 STATIC int 2643 _bcm_udf_td3_wb_scache_size_get_1_0(int unit, int *req_scache_size) 2644 { 2645 int len; 2646 int alloc_size = 0; 2647 2648 /* Number of UDFs */ 2649 alloc_size += sizeof(uint16); 2650 2651 /* Max UDF Object Nodes. */ 2652 alloc_size += (UDF_CONTROL(unit)->max_udfs * 2653 sizeof(_bcm_udf_td3_wb_obj_info_t)); 2654 2655 /* Max UDF Abstract Type CMD_POLICY_DATA. */ 2656 len = soc_mem_field_length(unit, IP_PARSER1_HFE_POLICY_TABLE_3m, CMD_POLICY_DATAf); 2657 alloc_size += ((bcmUdfAbstractPktFormatLastCount - 1) * len); 2658 2659 *req_scache_size = alloc_size; 2660 2661 return BCM_E_NONE; 2662 } 2663 2664 /* Returns required scache size in bytes for version = 2_0 */ 2665 STATIC int 2666 _bcm_udf_td3_wb_scache_size_get_2_0(int unit, int *req_scache_size) 2667 { 2668 int len; 2669 int alloc_size = 0; 2670 2671 /* Number of UDFs */ 2672 alloc_size += sizeof(uint16); 2673 2674 /* Max UDF Object Nodes. */ 2675 alloc_size += (UDF_CONTROL(unit)->max_udfs * 2676 sizeof(_bcm_udf_td3_wb_obj_info_2_t)); 2677 2678 /* Max UDF Abstract Type CMD_POLICY_DATA. */ 2679 len = soc_mem_field_length(unit, IP_PARSER1_HFE_POLICY_TABLE_3m, CMD_POLICY_DATAf); 2680 alloc_size += ((bcmUdfAbstractPktFormatLastCount - 1) * len); 2681 2682 *req_scache_size = alloc_size; 2683 2684 return BCM_E_NONE; 2685 } 2686 2687 2688 /* Returns required scache size for UDF module */ 2689 STATIC int 2690 _bcm_udf_td3_wb_scache_size_get(int unit, int *req_scache_size) 2691 { 2692 if (BCM_WB_DEFAULT_VERSION > BCM_WB_VERSION_1_0) { 2693 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_scache_size_get_2_0(unit, 2694 req_scache_size)); 2695 } else { 2696 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_scache_size_get_1_0(unit, 2697 req_scache_size)); 2698 } 2699 return BCM_E_NONE; 2700 } 2701 2702 /* Allocates required scache size for the UDF module recovery */ 2703 STATIC int 2704 _bcm_udf_td3_wb_alloc(int unit) 2705 { 2706 int rv; 2707 int req_scache_size; 2708 uint8 *scache_ptr; 2709 soc_scache_handle_t scache_handle; 2710 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_UDF, 0); 2711 2712 rv = _bcm_udf_td3_wb_scache_size_get(unit, &req_scache_size); 2713 BCM_IF_ERROR_RETURN(rv); 2714 2715 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 2716 req_scache_size, &scache_ptr, 2717 BCM_WB_DEFAULT_VERSION, NULL); 2718 2719 if (BCM_E_NOT_FOUND == rv) { 2720 /* Proceed with Level 1 Warm Boot */ 2721 rv = BCM_E_NONE; 2722 } 2723 2724 return rv; 2725 } 2726 2727 2728 /* 2729 * Function: 2730 * _bcm_udf_td3_reinit 2731 * Purpose: 2732 * Recovers UDF warmboot state from scache 2733 * Parameters: 2734 * unit - (IN) Unit number. 2735 * Returns: 2736 * BCM_E_XXX 2737 * Notes: 2738 */ 2739 STATIC int 2740 _bcm_udf_td3_reinit(int unit) 2741 { 2742 int rv = BCM_E_INTERNAL; 2743 uint8 *scache_ptr; 2744 uint16 recovered_ver = 0; 2745 soc_scache_handle_t scache_handle; 2746 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_UDF, 0); 2747 2748 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 2749 0, &scache_ptr, 2750 BCM_WB_DEFAULT_VERSION, &recovered_ver); 2751 if (BCM_E_NOT_FOUND == rv) { 2752 /* Proceed with Level 1 Warm Boot */ 2753 rv = BCM_E_NONE; 2754 } 2755 2756 BCM_IF_ERROR_RETURN(rv); 2757 2758 if (recovered_ver > BCM_WB_VERSION_1_0) { 2759 rv = _bcm_udf_td3_wb_obj_info_recover_2_0(unit, recovered_ver, &scache_ptr); 2760 BCM_IF_ERROR_RETURN(rv); 2761 2762 rv = _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_2_0(unit, recovered_ver, &scache_ptr); 2763 BCM_IF_ERROR_RETURN(rv); 2764 } else if (recovered_ver == BCM_WB_VERSION_1_0) { 2765 rv = _bcm_udf_td3_wb_obj_info_recover_1_0(unit, &scache_ptr); 2766 BCM_IF_ERROR_RETURN(rv); 2767 2768 rv = _bcm_udf_td3_wb_abstr_pkt_fmt_info_recover_1_0(unit, &scache_ptr); 2769 BCM_IF_ERROR_RETURN(rv); 2770 } 2771 2772 if (BCM_SUCCESS(rv) && 2773 (recovered_ver < BCM_WB_DEFAULT_VERSION)) { 2774 /* 2775 * This will handle the below cases 2776 * 1. When warboot from release which didn't had UDF module in SCACHE or 2777 * 2. The current release SCACHE size required is more than previous version or 2778 * 3. Level 1 warmboot in this case memory will not be allocated. 2779 */ 2780 BCM_IF_ERROR_RETURN(_bcm_udf_td3_wb_alloc(unit)); 2781 } 2782 return rv; 2783 } 2784 2785 #endif /* BCM_WARM_BOOT_SUPPORT */ 2786 /* 2787 * Routine to dump UDF mem info. 2788 */ 2789 STATIC void 2790 _bcm_udf_td3_sw_mem_dump(int unit, soc_mem_t mem, int idx) 2791 { 2792 _bcm_udf_td3_format_field_dump(unit, mem, idx); 2793 } 2794 2795 2796 /* 2797 * Function: 2798 * _bcm_udf_td3_functions_init 2799 * 2800 * Purpose: 2801 * Set up functions pointers 2802 * 2803 * Parameters: 2804 * functions - (IN/OUT) Pointer to device specific UDF module utility 2805 * routines. 2806 * 2807 * Returns: 2808 * Nothing 2809 */ 2810 void 2811 _bcm_udf_td3_functions_init(_bcm_udf_funct_t *functions) 2812 { 2813 functions->udf_init = _bcm_udf_td3_init; 2814 functions->udf_detach = _bcm_udf_td3_detach; 2815 functions->udf_chunk_create = _bcm_udf_td3_chunk_create; 2816 functions->udf_destroy = _bcm_udf_td3_destroy; 2817 functions->udf_chunk_info_get = _bcm_udf_td3_chunk_info_get; 2818 functions->udf_flow_based_chunk_arrange_set = 2819 _bcm_udf_flow_based_chunk_arrange_set; 2820 functions->udf_flow_based_chunk_arrange_get = 2821 _bcm_udf_flow_based_chunk_arrange_get; 2822 functions->udf_abstr_pkt_format_obj_list_get = 2823 _bcm_udf_td3_abstr_pkt_format_obj_list_get; 2824 functions->udf_abstr_pkt_format_info_get = 2825 _bcm_udf_td3_abstr_pkt_format_info_get; 2826 #ifdef BCM_WARM_BOOT_SUPPORT 2827 functions->udf_wb_sync = _bcm_udf_td3_wb_sync; 2828 #endif /* BCM_WARM_BOOT_SUPPORT */ 2829 functions->udf_range_checker_chunk_info_get = 2830 _bcm_udf_td3_range_checker_chunk_info_get; 2831 functions->udf_sw_dump = _bcm_udf_td3_sw_dump; 2832 functions->udf_sw_mem_dump = _bcm_udf_td3_sw_mem_dump; 2833 } 2834 #endif /* (BCM_TRIDENT3_SUPPORT) */