trident3.c (546291B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: trident3.c 8 * Purpose: 9 * Requires: 10 */ 11 12 13 #include <shared/bsl.h> 14 15 #include <sal/core/boot.h> 16 #include <sal/core/dpc.h> 17 #include <shared/bsl.h> 18 #include <soc/tdm/core/tdm_top.h> 19 #include <soc/tdm/tomahawk/tdm_th_soc.h> 20 #ifdef BCM_CMICX_SUPPORT 21 #include <soc/cmicx.h> 22 #include <soc/cmicx_miim.h> 23 #include <shared/cmicfw/iproc_m0ssq.h> 24 #endif 25 26 #include <soc/bradley.h> 27 #include <soc/drv.h> 28 #include <soc/error.h> 29 #include <soc/debug.h> 30 #include <soc/mem.h> 31 #include <soc/i2c.h> 32 #include <soc/l2x.h> 33 34 #ifdef BCM_TRIDENT3_SUPPORT 35 36 #include <soc/mmu_config.h> 37 #include <soc/trident3.h> 38 #include <soc/trident3_tdm.h> 39 #include <soc/tomahawk.h> 40 #include <soc/esw/cancun.h> 41 #include <soc/soc_ser_log.h> 42 #include <soc/pstats.h> 43 #include <soc/scache.h> 44 #include <soc/flexport/trident3/trident3_flexport_defines.h> 45 46 #define _TDM_LENGTH 256 47 #define _OVS_GROUP_COUNT 6 48 #define _OVS_GROUP_TDM_LENGTH 12 49 #define TD3_NUM_PHY_PORT (132) 50 #define TD3_NUM_PORT (132) 51 #define TD3_NUM_MMU_PORT (226) 52 53 /* Value hardcoded in set_tdm.c, definition needs to be matched */ 54 #define PORT_STATE_UNUSED 0 55 #define PORT_STATE_LINERATE 1 56 #define PORT_STATE_OVERSUB 2 57 #define PORT_STATE_CONTINUATION 3 /* part of other port */ 58 59 #define PORT_BLOCK_BASE_PORT(port) \ 60 (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0x3)); 61 62 /* IUAT number of shared banks */ 63 64 #define SOC_IUAT_8K_BANKS 4 65 #define SOC_IUAT_16K_BANKS 4 66 67 #define IS_MGMT_PORT(unit,port) IS_MANAGEMENT_PORT(unit, port) 68 69 static int num_shared_alpm_banks[SOC_MAX_NUM_DEVICES] = {8}; 70 static soc_mem_t *_soc_td3_alpm_bkt_view_map[SOC_MAX_NUM_DEVICES]; 71 static int8 *_soc_td3_alpm2_bnk_fmt_map[SOC_MAX_NUM_DEVICES]; 72 int 73 _soc_td3_port_speed_cap[SOC_MAX_NUM_DEVICES][TRIDENT3_PHY_PORTS_PER_DEV]; 74 75 typedef struct _soc_td3_mmu_traffic_ctrl_s { 76 uint8 thdo_drop_bmp[TD3_NUM_PORT]; 77 } _soc_td3_mmu_traffic_ctrl_t; 78 79 #define MMU_TRAFFIC_EN_CTRL (1 << 1) 80 #define PORT_TX_EN_CTRL (1 << 2) 81 static _soc_td3_mmu_traffic_ctrl_t 82 *_soc_td3_mmu_traffic_ctrl[SOC_MAX_NUM_DEVICES]; 83 static sal_mutex_t _fwd_ctrl_lock[SOC_MAX_NUM_DEVICES]; 84 #define FWD_CTRL_LOCK(unit) \ 85 sal_mutex_take(_fwd_ctrl_lock[unit], sal_mutex_FOREVER) 86 #define FWD_CTRL_UNLOCK(unit) \ 87 sal_mutex_give(_fwd_ctrl_lock[unit]) 88 89 int soc_td3_rx_etype_niv[SOC_MAX_NUM_DEVICES]; 90 int soc_td3_rx_etype_pe[SOC_MAX_NUM_DEVICES]; 91 92 int 93 _soc_trident3_init_mmu_memory(int unit); 94 int 95 soc_trident3_init_alpm2_memory(int unit); 96 /* Externs */ 97 extern int soc_trident3_get_alpm_banks(int unit); 98 extern int soc_td3_hash_mutex_init (int unit); 99 100 static const soc_reg_t pvtmon_result_reg[] = { 101 TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r, 102 TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r, 103 TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r, 104 TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r, 105 TOP_PVTMON_RESULT_8r, TOP_PVTMON_RESULT_9r, 106 TOP_PVTMON_RESULT_10r, TOP_PVTMON_RESULT_11r 107 }; 108 109 #ifdef BCM_MAVERICK2_SUPPORT 110 static const soc_reg_t pvtmon_result_reg_mv2[] = { 111 TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r, 112 TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r, 113 TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r, 114 TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r, 115 TOP_PVTMON_RESULT_8r, TOP_PVTMON_RESULT_11r 116 }; 117 #endif 118 119 egr_vlan_xlate_1_hash_control_entry_t egr_vlan_1_hash_control; 120 egr_vlan_xlate_2_hash_control_entry_t egr_vlan_2_hash_control; 121 egr_vp_vlan_membership_hash_control_entry_t egr_vp_vlan_mbm_hash_control; 122 exact_match_hash_control_entry_t exact_match_hash_control; 123 ing_dnat_address_type_hash_control_entry_t ing_dnat_hash_control; 124 ing_vp_vlan_membership_hash_control_entry_t ing_vp_vlan_mbm_hash_control; 125 l2_entry_hash_control_entry_t l2_entry_hash_control; 126 l3_entry_hash_control_entry_t l3_entry_hash_control; 127 mpls_entry_hash_control_entry_t mpls_entry_hash_control; 128 subport_id_to_sgpp_map_hash_control_entry_t subport_hash_control; 129 vlan_xlate_1_hash_control_entry_t vlan_1_hash_control; 130 vlan_xlate_2_hash_control_entry_t vlan_2_hash_control; 131 uft_shared_banks_control_entry_t uft_shared_banks_control; 132 ip_uat_16k_shared_banks_control_entry_t ip_uat_16k_shared_banks_control; 133 ip_uat_8k_shared_banks_control_entry_t ip_uat_8k_shared_banks_control; 134 ep_uat_shared_banks_control_entry_t ep_uat_shared_banks_control; 135 136 int 137 soc_trident3_init_alpm2_memory(int unit) 138 { 139 if (_soc_td3_alpm2_bnk_fmt_map[unit] != NULL) { 140 sal_free(_soc_td3_alpm2_bnk_fmt_map[unit]); 141 _soc_td3_alpm2_bnk_fmt_map[unit] = NULL; 142 } 143 144 if (NULL == _soc_td3_alpm2_bnk_fmt_map[unit]) { 145 if ((_soc_td3_alpm2_bnk_fmt_map[unit] = sal_alloc(sizeof(int8) * \ 146 soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm), "alpm_bnt_map")) \ 147 == NULL) { 148 return SOC_E_MEMORY; 149 } 150 } 151 152 sal_memset(_soc_td3_alpm2_bnk_fmt_map[unit], 0, 153 sizeof(int8) * soc_mem_index_count(unit, L3_DEFIP_ALPM_RAWm)); 154 return SOC_E_NONE; 155 } 156 157 int 158 soc_td3_post_mmu_init_update(int unit) 159 { 160 int port; 161 soc_info_t *si = &SOC_INFO(unit); 162 163 PBMP_ALL_ITER(unit, port) { 164 /* Set init speed to max speed by default */ 165 si->port_init_speed[port] = si->port_speed_max[port]; 166 if (_soc_td3_port_speed_cap[unit][port]) { 167 /* If cap speed is available then adjust max speed for further use */ 168 si->port_speed_max[port] = _soc_td3_port_speed_cap[unit][port]; 169 } 170 } 171 return SOC_E_NONE; 172 } 173 174 /* 175 * Function: 176 * soc_trident3_iuat_sizing 177 * Purpose: 178 * Given number of entries for IUAT memory, determine number of 8k and 16k 179 * IUAT banks (already allocated + shared banks for requesting module) 180 * Parameters: 181 * unit (IN) - switch unit 182 * iuat entries (IN) - number of memory entries 183 * iuat_16k (IN/OUT) - total number of allocated 16k banks 184 * iuat_8k (IN/OUT) - total number of allocated 8k banks 185 * Returns: 186 * SOC_E_* 187 */ 188 int 189 soc_trident3_iuat_sizing(int unit, int iuat_entries, int *iuat_16k, int *iuat_8k) 190 { 191 if (iuat_entries == 0) { 192 return SOC_E_NONE; 193 } else if (iuat_entries <= (8 *1024)) { 194 /* Minimum hash table size should be > 8k */ 195 return SOC_E_PARAM; 196 } 197 198 /* Recurse for iuat_entries > 32k */ 199 while (iuat_entries > (32 * 1024)) { 200 int residual_entries = 32 * 1024; 201 SOC_IF_ERROR_RETURN 202 (soc_trident3_iuat_sizing(unit, residual_entries, iuat_16k, iuat_8k)); 203 iuat_entries -= residual_entries; 204 } 205 206 /* Allocation Policy - Minimum Number of banks to be allocated is 2 207 * Preferable if banks allocated are of the same size 208 */ 209 210 /* Depending on number of iuat entries, there are several allocation schemes 211 * possible. They are listed in order of priority. If none of them are 212 * possible, error is returned. 213 */ 214 215 /* This case works only when iuat_entries > 32k and recursion has happened */ 216 if(iuat_entries <= 8 * 1024) { 217 if ((*iuat_8k + 1) <= SOC_IUAT_8K_BANKS) { 218 *iuat_8k += 1; 219 } else { 220 return SOC_E_PARAM; 221 } 222 } else if (iuat_entries <= 16 * 1024) { 223 /* For iuat entries in range 1 to (16 * 1024) 224 * 1. Allocate two 8k banks 225 */ 226 if ((*iuat_8k + 2) <= SOC_IUAT_8K_BANKS) { 227 *iuat_8k += 2; 228 } else { 229 return SOC_E_PARAM; 230 } 231 } else if (iuat_entries <= 24 * 1024) { 232 /* For iuat entries in range (16 * 1024) + 1 to 24 * 1024 233 * 1. Allocate two 16k banks 234 * 2. Allocate one 16k bank and one 8k bank 235 * 3. Allocate three 8k banks 236 */ 237 if ((*iuat_16k + 2) <= SOC_IUAT_16K_BANKS){ 238 *iuat_16k += 2; 239 } else if (((*iuat_16k + 1) <= SOC_IUAT_16K_BANKS) && 240 ((*iuat_8k + 1) <= SOC_IUAT_8K_BANKS)) { 241 *iuat_8k += 1; 242 *iuat_16k += 1; 243 } else if ((*iuat_8k + 3) <= SOC_IUAT_8K_BANKS) { 244 *iuat_8k += 3; 245 } else { 246 return SOC_E_PARAM; 247 } 248 } else { /* remaining case: (iuat_entries <= 32 * 1024) */ 249 /* For iuat entries in range (24 * 1024) + 1 to 32 * 1024, 250 * 1. Allocate two 16k banks 251 * 2. Allocate four 8k banks 252 * 3. Allocate two 8k banks and one 16k bank. 253 */ 254 if ((*iuat_16k + 2) <= SOC_IUAT_16K_BANKS) { 255 *iuat_16k += 2; 256 } else if ((*iuat_8k + 4) <= SOC_IUAT_8K_BANKS) { 257 *iuat_8k += 4; 258 } else if(((*iuat_8k + 2) <= SOC_IUAT_8K_BANKS) && 259 (*iuat_16k + 1) <= SOC_IUAT_16K_BANKS) { 260 *iuat_8k += 2; 261 *iuat_16k += 1; 262 } else { 263 return SOC_E_PARAM; 264 } 265 } 266 return SOC_E_NONE; 267 } 268 269 /* 270 * Function: 271 * soc_trident3_mem_config 272 * Purpose: 273 * Configure depth of UFT/UAT memories 274 * Parameters: 275 * unit (IN) - switch unit 276 * Returns: 277 * SOC_E_* 278 */ 279 int 280 soc_trident3_mem_config(int unit) 281 { 282 soc_persist_t *sop; 283 int l2_entries, fixed_l2_entries, shared_l2_banks; 284 int num_ipv6_128b_entries = 0; 285 int config_v6_entries = 0; 286 int defip_config = 0; 287 #define _SOC_TD3_DEFIP_MAX_TCAMS 8 288 #define _SOC_TD3_DEFIP_TCAM_DEPTH 2048 289 int l3_entries, fixed_l3_entries, shared_l3_banks; 290 int fpem_entries, shared_fpem_banks; 291 int mpls_entries, vlan_xlate_1_entries, vlan_xlate_2_entries; 292 int alpm_enable = 0; 293 int mpls_16k_banks, mpls_8k_banks; 294 int vlan_xlate_1_16k_banks, vlan_xlate_1_8k_banks; 295 int vlan_xlate_2_16k_banks, vlan_xlate_2_8k_banks; 296 int uat_16k_banks, uat_8k_banks; 297 int egr_vlan_xlate_1_entries, egr_vlan_xlate_2_entries; 298 int egr_vlan_xlate_1_banks, egr_vlan_xlate_2_banks; 299 int num_lag_rh_flowset_entries; 300 301 sop = SOC_PERSIST(unit); 302 303 /* UFT BANK SIZING 304 * 305 * bank 0-1 are dedicated L2 banks (16k entries per bank) 306 * bank 10-11 are dedicated L3 banks (8k entries per bank) 307 * bank 2-9 are shared banks (32k L2/L3 or 16k FPEM entries 308 * or 48k ALPM entries per bank) 309 */ 310 311 l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, 32 * 1024); 312 fixed_l2_entries = 32 * 1024; /* 32k dedicated L2 entries, (16k * 2 banks) */ 313 if (l2_entries < fixed_l2_entries) { 314 l2_entries = fixed_l2_entries; 315 shared_l2_banks = 0; 316 } else { 317 l2_entries -= fixed_l2_entries; 318 shared_l2_banks = (l2_entries + (32 * 1024 - 1)) / (32 * 1024); 319 l2_entries = fixed_l2_entries + shared_l2_banks * 32 * 1024; 320 } 321 322 l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, 16 * 1024); 323 fixed_l3_entries = 16 * 1024; /* 16k dedicated L3 entries, (8k * 2 banks) */ 324 if (l3_entries < fixed_l3_entries) { 325 l3_entries = fixed_l3_entries; 326 shared_l3_banks = 0; 327 } else { 328 l3_entries -= fixed_l3_entries; 329 shared_l3_banks = (l3_entries + (32 * 1024 - 1)) / (32 * 1024); 330 l3_entries = fixed_l3_entries + shared_l3_banks * 32 * 1024; 331 } 332 333 fpem_entries = soc_property_get(unit, spn_FPEM_MEM_ENTRIES, 0); 334 shared_fpem_banks = (fpem_entries + (16 * 1024 - 1)) / (16 * 1024); 335 /* Allocate atleast 2 banks to FP for dual hash benefits */ 336 if(shared_fpem_banks == 1) { 337 if ((shared_l2_banks + shared_l3_banks) > 6) { 338 LOG_ERROR(BSL_LS_SOC_COMMON, 339 (BSL_META_U(unit, 340 "Config Error - Atleast two shared UFT" 341 "banks should be allocated to FPEM. \n"))); 342 return SOC_E_PARAM; 343 } 344 shared_fpem_banks = 2; 345 } 346 fpem_entries = shared_fpem_banks * 16 * 1024; 347 348 if (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 8) { 349 return SOC_E_PARAM; 350 } 351 352 if (soc_feature(unit, soc_feature_alpm)) { 353 alpm_enable = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0); 354 } 355 356 /* ALPM needs either 4 banks or 8 banks depending on ALPM bank mode. 357 * If more than 4 banks are already allocated to non ALPM tables (L2, L3, 358 * FPEM), then ALPM needs cannot be satisfied */ 359 if ((alpm_enable) && 360 (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 4)) { 361 return SOC_E_PARAM; 362 } 363 364 _soc_alpm_mode[unit] = alpm_enable; 365 366 /* IUAT BANK SIZING 367 * 368 * Banks 0-3 are shared banks of size 8k per bank 369 * Banks 4-7 are shared banks of size 16k per bank 370 */ 371 372 uat_16k_banks = 0; uat_8k_banks = 0; 373 mpls_entries = soc_property_get(unit, spn_MPLS_MEM_ENTRIES, 32768); 374 SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, mpls_entries, 375 &uat_16k_banks, &uat_8k_banks)); 376 mpls_16k_banks = uat_16k_banks; 377 mpls_8k_banks = uat_8k_banks; 378 mpls_entries = mpls_16k_banks * 16 * 1024 + mpls_8k_banks * 8 * 1024; 379 380 vlan_xlate_1_entries = soc_property_get(unit, spn_VLAN_XLATE_1_MEM_ENTRIES, 381 32768); 382 SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, vlan_xlate_1_entries, 383 &uat_16k_banks, &uat_8k_banks)); 384 vlan_xlate_1_16k_banks = uat_16k_banks - mpls_16k_banks; 385 vlan_xlate_1_8k_banks = uat_8k_banks - mpls_8k_banks; 386 vlan_xlate_1_entries = vlan_xlate_1_16k_banks * 16 * 1024 + 387 vlan_xlate_1_8k_banks * 8 * 1024; 388 389 vlan_xlate_2_entries = soc_property_get(unit, spn_VLAN_XLATE_2_MEM_ENTRIES, 390 32768); 391 SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, vlan_xlate_2_entries, 392 &uat_16k_banks, &uat_8k_banks)); 393 vlan_xlate_2_16k_banks = uat_16k_banks - mpls_16k_banks - 394 vlan_xlate_1_16k_banks; 395 vlan_xlate_2_8k_banks = uat_8k_banks - mpls_8k_banks - vlan_xlate_1_8k_banks; 396 vlan_xlate_2_entries = vlan_xlate_2_16k_banks * 16 * 1024 + 397 vlan_xlate_2_8k_banks * 8 * 1024; 398 399 /* EUAT BANK SIZING 400 * 401 * Banks 0-3 are shared banks of size 8k per bank 402 */ 403 404 egr_vlan_xlate_1_entries = soc_property_get(unit, 405 spn_EGR_VLAN_XLATE_1_MEM_ENTRIES, 16384); 406 egr_vlan_xlate_1_banks = (egr_vlan_xlate_1_entries + (8 * 1024 - 1)) / 407 ( 8 * 1024); 408 egr_vlan_xlate_1_entries = egr_vlan_xlate_1_banks * 8 * 1024; 409 410 egr_vlan_xlate_2_entries = soc_property_get(unit, 411 spn_EGR_VLAN_XLATE_2_MEM_ENTRIES, 16384); 412 egr_vlan_xlate_2_banks = (egr_vlan_xlate_2_entries + (8 * 1024 - 1)) / 413 ( 8 * 1024); 414 egr_vlan_xlate_2_entries = egr_vlan_xlate_2_banks * 8 * 1024; 415 416 if (egr_vlan_xlate_1_banks + egr_vlan_xlate_2_banks > 4) { 417 return SOC_E_PARAM; 418 } 419 420 /* LP memory sizing 421 * Memory Bank with 1W,2W,4W support - 3.5k entries 422 * Memory Bank with 1W,2W support - 3k entries 423 * Memory Bank with 1W support - 2k entries 424 */ 425 426 /* Adjust L2 table size */ 427 sop->memState[L2Xm].index_max = l2_entries - 1; 428 sop->memState[L2_ENTRY_SINGLEm].index_max = l2_entries - 1; 429 sop->memState[L2_ENTRY_ONLY_SINGLEm].index_max = l2_entries - 1; 430 sop->memState[L2_ENTRY_ECCm].index_max = l2_entries - 1; 431 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1; 432 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1; 433 /* 4k per dedicated L2 bank, 14k per shared L2 bank */ 434 sop->memState[L2_ENTRY_LPm].index_max = (2 * 4 * 1024) + 435 (shared_l2_banks * 14 * 1024) - 1; 436 437 /* Adjust L3 table size */ 438 sop->memState[L3_ENTRY_SINGLEm].index_max = l3_entries - 1; 439 sop->memState[L3_ENTRY_ONLY_SINGLEm].index_max = l3_entries - 1; 440 sop->memState[L3_ENTRY_ECCm].index_max = l3_entries - 1; 441 sop->memState[L3_ENTRY_DOUBLEm].index_max = l3_entries / 2 - 1; 442 sop->memState[L3_ENTRY_ONLY_DOUBLEm].index_max = l3_entries / 2 - 1; 443 sop->memState[L3_ENTRY_QUADm].index_max = l3_entries / 4 - 1; 444 sop->memState[L3_ENTRY_ONLY_QUADm].index_max = l3_entries / 4 - 1; 445 sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1; 446 /* 3.5k per dedicated L3 bank, 14k per shared L3 bank */ 447 /* 2 * 3.5 * 1024 is replaced by 7 * 1024 to avoid automatic type 448 * conversion, which could force shared_l3_banks to double type */ 449 sop->memState[L3_ENTRY_LPm].index_max = (7 * 1024) + 450 (shared_l3_banks * 14 * 1024) - 1; 451 452 /* Adjust FP exact match table size */ 453 sop->memState[EXACT_MATCH_2m].index_max = fpem_entries - 1; 454 sop->memState[EXACT_MATCH_2_PIPE0m].index_max = fpem_entries - 1; 455 sop->memState[EXACT_MATCH_2_PIPE1m].index_max = fpem_entries - 1; 456 sop->memState[EXACT_MATCH_2_ENTRY_ONLYm].index_max = fpem_entries - 1; 457 sop->memState[EXACT_MATCH_2_ENTRY_ONLY_PIPE0m].index_max = fpem_entries - 1; 458 sop->memState[EXACT_MATCH_2_ENTRY_ONLY_PIPE1m].index_max = fpem_entries - 1; 459 sop->memState[EXACT_MATCH_4m].index_max = fpem_entries / 2 - 1; 460 sop->memState[EXACT_MATCH_4_PIPE0m].index_max = fpem_entries / 2 - 1; 461 sop->memState[EXACT_MATCH_4_PIPE1m].index_max = fpem_entries / 2 - 1; 462 sop->memState[EXACT_MATCH_4_ENTRY_ONLYm].index_max = fpem_entries / 2 - 1; 463 sop->memState[EXACT_MATCH_4_ENTRY_ONLY_PIPE0m].index_max = fpem_entries / 2 - 1; 464 sop->memState[EXACT_MATCH_4_ENTRY_ONLY_PIPE1m].index_max = fpem_entries / 2 - 1; 465 sop->memState[EXACT_MATCH_HIT_ONLYm].index_max = fpem_entries / 2 - 1; 466 sop->memState[EXACT_MATCH_ECCm].index_max = fpem_entries * 2 - 1; 467 sop->memState[EXACT_MATCH_ECC_PIPE0m].index_max = fpem_entries * 2 - 1; 468 sop->memState[EXACT_MATCH_ECC_PIPE1m].index_max = fpem_entries * 2 - 1; 469 /* 14k per shared FPEM bank */ 470 sop->memState[EXACT_MATCH_LPm].index_max = 471 shared_fpem_banks * 14 * 1024 - 1; 472 sop->memState[EXACT_MATCH_LP_PIPE0m].index_max = 473 shared_fpem_banks * 14 * 1024 -1; 474 sop->memState[EXACT_MATCH_LP_PIPE1m].index_max = 475 shared_fpem_banks * 14 * 1024 -1; 476 477 /* Adjust MPLS table size */ 478 479 sop->memState[MPLS_ENTRY_SINGLEm].index_max = mpls_entries - 1; 480 sop->memState[MPLS_ENTRYm].index_max = mpls_entries / 2 - 1; 481 /* 3k per 8k bank and 6k per 8k bank */ 482 sop->memState[MPLS_ENTRY_LPm].index_max = (mpls_8k_banks * 3 * 1024 + 483 mpls_16k_banks * 2 * 3 * 1024) - 1; 484 sop->memState[MPLS_ENTRY_ECCm].index_max = mpls_entries - 1; 485 486 /* Adjust VLAN_XLATE_1 table size */ 487 488 sop->memState[VLAN_XLATE_1_SINGLEm].index_max = vlan_xlate_1_entries - 1; 489 sop->memState[VLAN_XLATE_1_DOUBLEm].index_max = vlan_xlate_1_entries / 2 - 1; 490 /* 3k per 8k bank and 6k per 8k bank */ 491 sop->memState[VLAN_XLATE_1_LPm].index_max = ((vlan_xlate_1_16k_banks * 2 * 3 * 1024) 492 + (vlan_xlate_1_8k_banks * 3 * 1024)) - 1; 493 sop->memState[VLAN_XLATE_1_ECCm].index_max = vlan_xlate_1_entries - 1; 494 495 /* Adjust VLAN_XLATE_2 table size */ 496 497 sop->memState[VLAN_XLATE_2_SINGLEm].index_max = vlan_xlate_2_entries - 1; 498 sop->memState[VLAN_XLATE_2_DOUBLEm].index_max = vlan_xlate_2_entries / 2 - 1; 499 /* 3k per 8k bank and 6k per 8k bank */ 500 sop->memState[VLAN_XLATE_2_LPm].index_max = (vlan_xlate_2_16k_banks * 2 * 3 * 1024) 501 + (vlan_xlate_2_8k_banks * 3 * 1024) - 1; 502 sop->memState[VLAN_XLATE_2_ECCm].index_max = vlan_xlate_2_entries - 1; 503 504 /* Adjust EGR_VLAN_XLATE_1 table size */ 505 506 sop->memState[EGR_VLAN_XLATE_1_SINGLEm].index_max = egr_vlan_xlate_1_entries - 1; 507 sop->memState[EGR_VLAN_XLATE_1_DOUBLEm].index_max = egr_vlan_xlate_1_entries / 2 - 1; 508 /* 3k per bank */ 509 sop->memState[EGR_VLAN_XLATE_1_LPm].index_max = egr_vlan_xlate_1_banks * 3 * 1024 - 1; 510 sop->memState[EGR_VLAN_XLATE_1_ECCm].index_max = egr_vlan_xlate_1_entries - 1; 511 512 /* Adjust EGR_VLAN_XLATE_2 table size */ 513 514 sop->memState[EGR_VLAN_XLATE_2_SINGLEm].index_max = egr_vlan_xlate_2_entries - 1; 515 sop->memState[EGR_VLAN_XLATE_2_DOUBLEm].index_max = egr_vlan_xlate_2_entries / 2 - 1; 516 /* 3k per bank */ 517 sop->memState[EGR_VLAN_XLATE_2_LPm].index_max = egr_vlan_xlate_2_banks * 3 * 1024 - 1; 518 sop->memState[EGR_VLAN_XLATE_2_ECCm].index_max = egr_vlan_xlate_2_entries - 1; 519 520 521 SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_TD3_DEFIP_MAX_TCAMS; 522 SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_TD3_DEFIP_TCAM_DEPTH; 523 524 if (soc_property_get(unit, "l3_defip_sizing", TRUE)) { 525 if (!alpm_enable) { 526 defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1); 527 528 num_ipv6_128b_entries = soc_property_get(unit, 529 spn_NUM_IPV6_LPM_128B_ENTRIES, 530 (defip_config ? 4096 : 0)); 531 num_ipv6_128b_entries = num_ipv6_128b_entries + 532 (num_ipv6_128b_entries % 2); 533 534 config_v6_entries = num_ipv6_128b_entries; 535 if (soc_property_get(unit, spn_LPM_SCALING_ENABLE, 0)) { 536 num_ipv6_128b_entries = 0; 537 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED, 1)) { 538 config_v6_entries = ((config_v6_entries / 539 SOC_CONTROL(unit)->l3_defip_tcam_size) + 540 ((config_v6_entries % 541 SOC_CONTROL(unit)->l3_defip_tcam_size) 542 ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size; 543 } 544 } 545 sop->memState[L3_DEFIP_PAIR_128m].index_max = 546 num_ipv6_128b_entries - 1; 547 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 548 num_ipv6_128b_entries - 1; 549 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 550 num_ipv6_128b_entries - 1; 551 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 552 num_ipv6_128b_entries - 1; 553 sop->memState[L3_DEFIPm].index_max = 554 (SOC_CONTROL(unit)->l3_defip_max_tcams * 555 SOC_CONTROL(unit)->l3_defip_tcam_size) - 556 (num_ipv6_128b_entries * 2) - 1; 557 558 sop->memState[L3_DEFIP_ONLYm].index_max = 559 sop->memState[L3_DEFIPm].index_max; 560 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 561 sop->memState[L3_DEFIPm].index_max; 562 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 563 sop->memState[L3_DEFIPm].index_max; 564 SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries; 565 } else { 566 if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) { 567 /* slightly different processing for v6-128 */ 568 num_ipv6_128b_entries = soc_property_get(unit, 569 spn_NUM_IPV6_LPM_128B_ENTRIES, 570 4096); 571 num_ipv6_128b_entries = num_ipv6_128b_entries + 572 (num_ipv6_128b_entries % 2); 573 config_v6_entries = num_ipv6_128b_entries; 574 sop->memState[L3_DEFIP_PAIR_128m].index_max = 575 num_ipv6_128b_entries - 1; 576 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 577 num_ipv6_128b_entries - 1; 578 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 579 num_ipv6_128b_entries - 1; 580 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 581 num_ipv6_128b_entries - 1; 582 sop->memState[L3_DEFIPm].index_max = 583 (SOC_CONTROL(unit)->l3_defip_max_tcams * 584 SOC_CONTROL(unit)->l3_defip_tcam_size) - 585 (num_ipv6_128b_entries * 2) - 1; 586 587 sop->memState[L3_DEFIP_ONLYm].index_max = 588 sop->memState[L3_DEFIPm].index_max; 589 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 590 sop->memState[L3_DEFIPm].index_max; 591 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 592 sop->memState[L3_DEFIPm].index_max; 593 594 SOC_CONTROL(unit)->l3_defip_index_remap = 595 (num_ipv6_128b_entries / 2) * 2; 596 } else { 597 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1; 598 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1; 599 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1; 600 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1; 601 } 602 } 603 soc_l3_defip_indexes_init(unit, config_v6_entries); 604 } 605 606 /* Adjust ALPM table size */ 607 if (alpm_enable) { 608 /* The check below is sufficient because if ALPM mode is enabled 609 * and number of shared banks used is > 4 we return SOC_E_PARAM 610 * in code at the top of this function. 611 */ 612 if (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 0) { 613 sop->memState[L3_DEFIP_ALPM_RAWm].index_max = 614 sop->memState[L3_DEFIP_ALPM_RAWm].index_max/2; 615 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = 616 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max/2; 617 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = 618 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max/2; 619 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = 620 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max/2; 621 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = 622 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max/2; 623 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = 624 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max/2; 625 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = 626 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max/2; 627 sop->memState[L3_DEFIP_ALPM_ECCm].index_max = 628 sop->memState[L3_DEFIP_ALPM_ECCm].index_max/2; 629 } 630 } else { 631 sop->memState[L3_DEFIP_ALPM_RAWm].index_max = -1; 632 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = -1; 633 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = -1; 634 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = -1; 635 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = -1; 636 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = -1; 637 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = -1; 638 sop->memState[L3_DEFIP_ALPM_ECCm].index_max = -1; 639 } 640 641 /* Adjust MY_STATION_TCAM table in Emulator */ 642 if (SAL_BOOT_QUICKTURN) { 643 sop->memState[MY_STATION_TCAMm].index_max = 31; 644 sop->memState[MY_STATION_TCAM_2m].index_max = 645 sop->memState[MY_STATION_TCAMm].index_max; 646 sop->memState[MY_STATION_TCAM_2_DATA_ONLYm].index_max = 647 sop->memState[MY_STATION_TCAMm].index_max; 648 sop->memState[MY_STATION_TCAM_2_ENTRY_ONLYm].index_max = 649 sop->memState[MY_STATION_TCAMm].index_max; 650 sop->memState[MY_STATION_TCAM_DATA_ONLYm].index_max = 651 sop->memState[MY_STATION_TCAMm].index_max; 652 sop->memState[MY_STATION_TCAM_ENTRY_ONLYm].index_max = 653 sop->memState[MY_STATION_TCAMm].index_max; 654 } 655 656 if (_soc_td3_alpm_bkt_view_map[unit] != NULL) { 657 sal_free(_soc_td3_alpm_bkt_view_map[unit]); 658 _soc_td3_alpm_bkt_view_map[unit] = NULL; 659 } 660 661 if (NULL == _soc_td3_alpm_bkt_view_map[unit]) { 662 if ((_soc_td3_alpm_bkt_view_map[unit] = 663 sal_alloc(sizeof(soc_mem_t) * SOC_TD3_ALPM_MAX_BKTS(unit), 664 "alpm_bkt_map")) == NULL) { 665 return SOC_E_MEMORY; 666 } 667 } 668 669 sal_memset(_soc_td3_alpm_bkt_view_map[unit], INVALIDm, 670 sizeof(soc_mem_t) * SOC_TD3_ALPM_MAX_BKTS(unit)); 671 672 if (soc_trident3_alpm_mode_get(unit)) { 673 SOC_IF_ERROR_RETURN(soc_trident3_init_alpm2_memory(unit)); 674 } 675 676 /* Enhanced hashing LAG/TRUNK config 677 * LAG/TRUNK share the same flow set table used in RH 678 * 64k is shared between LAG and HGT for 679 * - 32k each - default 680 * - 64K dedicated to HGT RH 681 * - 64K dedicated to LAG RH 682 */ 683 num_lag_rh_flowset_entries = soc_property_get(unit, 684 spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 32768); 685 686 switch (num_lag_rh_flowset_entries) { 687 case 0: 688 sop->memState[RH_LAG_FLOWSETm].index_max = -1; 689 sop->memState[RH_LAG_FLOWSET_PIPE0m].index_max = -1; 690 sop->memState[RH_LAG_FLOWSET_PIPE1m].index_max = -1; 691 break; 692 case 65536: 693 sop->memState[RH_HGT_FLOWSETm].index_max = -1; 694 sop->memState[RH_HGT_FLOWSET_PIPE0m].index_max = -1; 695 sop->memState[RH_HGT_FLOWSET_PIPE1m].index_max = -1; 696 break; 697 case 32768: 698 sop->memState[RH_HGT_FLOWSETm].index_max = 32767; 699 sop->memState[RH_HGT_FLOWSET_PIPE0m].index_max = 32767; 700 sop->memState[RH_HGT_FLOWSET_PIPE1m].index_max = 32767; 701 sop->memState[RH_LAG_FLOWSETm].index_max = 32767; 702 sop->memState[RH_LAG_FLOWSET_PIPE0m].index_max = 32767; 703 sop->memState[RH_LAG_FLOWSET_PIPE1m].index_max = 32767; 704 break; 705 default: 706 return SOC_E_CONFIG; 707 } 708 return SOC_E_NONE; 709 } 710 711 void 712 _soc_trident3_alpm2_bnk_fmt_set(int unit, int index, int8 fmt) 713 { 714 _soc_td3_alpm2_bnk_fmt_map[unit][index] = fmt; 715 } 716 717 int8 718 _soc_trident3_alpm2_bnk_fmt_get(int unit, int index) 719 { 720 return _soc_td3_alpm2_bnk_fmt_map[unit][index]; 721 } 722 723 void 724 _soc_trident3_alpm_bkt_view_set(int unit, int index, soc_mem_t view) 725 { 726 int bkt = soc_trident3_get_alpm_banks(unit); 727 if (bkt == 8) { 728 bkt = 3; 729 } else if (bkt == 4) { 730 bkt = 2; 731 } else if (bkt == 2) { 732 bkt = 1; 733 } 734 bkt = (index >> bkt) & SOC_TD3_ALPM_BKT_MASK(unit); 735 736 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt set index:%d bkt:%d view:%s\n"), 737 unit, index, bkt, SOC_MEM_NAME(unit, view))); 738 _soc_td3_alpm_bkt_view_map[unit][bkt] = view; 739 } 740 741 soc_mem_t 742 _soc_trident3_alpm_bkt_view_get(int unit, int index) 743 { 744 soc_mem_t view; 745 int bkt = soc_trident3_get_alpm_banks(unit); 746 if (bkt == 8) { 747 bkt = 3; 748 } else if (bkt == 4) { 749 bkt = 2; 750 } else if (bkt == 2) { 751 bkt = 1; 752 } 753 bkt = (index >> bkt) & SOC_TD3_ALPM_BKT_MASK(unit); 754 755 view = _soc_td3_alpm_bkt_view_map[unit][bkt]; 756 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt get index:%d bkt:%d view:%s\n"), 757 unit, index, bkt, SOC_MEM_NAME(unit, view))); 758 return view; 759 } 760 761 int 762 soc_trident3_mem_cpu_write_control(int unit, soc_mem_t mem, int copyno, 763 int enable, int *orig_enable) 764 { 765 soc_reg_t reg; 766 soc_field_t field; 767 uint32 rval, fval; 768 int blk, port, block_info_index; 769 uint32 orig_fval, enable_fval, disable_fval; 770 771 enable_fval = 1; 772 disable_fval = 0; 773 774 switch (mem) { 775 case CLPORT_WC_UCMEM_DATAm: 776 reg = CLPORT_WC_UCMEM_CTRLr; 777 field = ACCESS_MODEf; 778 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 779 port = SOC_BLOCK_PORT(unit, blk); 780 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 781 /* It will use the setting from the last block */ 782 *orig_enable = soc_reg_field_get(unit, reg, rval, field); 783 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 784 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 785 } 786 return SOC_E_NONE; 787 default: 788 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 789 if ((SOC_BLOCK_TYPE(unit, block_info_index) == SOC_BLK_MMU_XPE) || 790 (SOC_BLOCK_TYPE(unit, block_info_index) == SOC_BLK_MMU_SED) || 791 (SOC_BLOCK_TYPE(unit, block_info_index) == SOC_BLK_MMU_SC)){ 792 reg = MMU_GCFG_MISCCONFIGr; 793 field = REFRESH_ENf; 794 enable_fval = 0; 795 disable_fval = 1; 796 SOC_IF_ERROR_RETURN 797 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 798 orig_fval = soc_reg_field_get(unit, reg, rval, field); 799 fval = enable ? enable_fval : disable_fval; 800 *orig_enable = orig_fval == enable_fval; 801 if (fval != orig_fval) { 802 soc_reg_field_set(unit, reg, &rval, field, fval); 803 SOC_IF_ERROR_RETURN 804 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 805 } 806 } 807 return _soc_trident2_mem_cpu_write_control(unit, mem, copyno, 808 enable, orig_enable); 809 } 810 return SOC_E_NONE; 811 812 #if 0 813 soc_reg_t reg; 814 soc_field_t field; 815 int blk, port; 816 uint32 rval; 817 818 switch (mem) { 819 case CLPORT_WC_UCMEM_DATAm: 820 reg = CLPORT_WC_UCMEM_CTRLr; 821 field = ACCESS_MODEf; 822 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 823 port = SOC_BLOCK_PORT(unit, blk); 824 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 825 /* It will use the setting from the last block */ 826 *orig_enable = soc_reg_field_get(unit, reg, rval, field); 827 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 828 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 829 } 830 return SOC_E_NONE; 831 default: 832 return _soc_trident2_mem_cpu_write_control(unit, mem, copyno, 833 enable, orig_enable); 834 } 835 #endif 836 } 837 838 839 int 840 soc_trident3_reg_cpu_write_control(int unit, int enable) 841 { 842 uint32 intfo_dis = 0; 843 844 if (enable) { 845 /* Disable HW updates */ 846 soc_reg_field_set(unit, INTFO_HW_UPDATE_DISr, &intfo_dis, 847 EG_SPf, 1); 848 soc_reg_field_set(unit, INTFO_HW_UPDATE_DISr, &intfo_dis, 849 ING_SPf, 1); 850 soc_reg_field_set(unit, INTFO_HW_UPDATE_DISr, &intfo_dis, 851 CONGST_STf, 1); 852 } 853 SOC_IF_ERROR_RETURN(WRITE_INTFO_HW_UPDATE_DISr(unit, intfo_dis)); 854 855 return SOC_E_NONE; 856 } 857 858 soc_mem_t 859 _soc_trident3_pmem(int unit, int port, soc_mem_t mema, soc_mem_t memb) 860 { 861 return (SOC_INFO(unit).port_pipe[port]) ? memb : mema; 862 } 863 864 uint32 _soc_td3_mmu_port(int unit, int port) 865 { 866 soc_info_t *si = &SOC_INFO(unit); 867 return si->port_p2m_mapping[si->port_l2p_mapping[port]]; 868 } 869 870 /* 871 * cpu port (mmu port 64): 48 queues (650-697) 872 * loopback port (mmu port 65, 193): 10 queues (640-649) 873 * mgmt port (mmu port 192): 10 UC, 10 MC queues 874 */ 875 int 876 soc_trident3_num_cosq_init_port(int unit, int port) 877 { 878 soc_info_t *si; 879 int mmu_port; 880 881 si = &SOC_INFO(unit); 882 883 mmu_port = SOC_TD3_MMU_PORT(unit, port); 884 885 if (IS_CPU_PORT(unit, port)) { 886 si->port_num_cosq[port] = 48; 887 si->port_cosq_base[port] = SOC_TD3_CPU_MCQ_BASE; 888 } else if (IS_LB_PORT(unit, port)) { 889 si->port_num_cosq[port] = 10; 890 si->port_cosq_base[port] = SOC_TD3_LB_MCQ_BASE; 891 } else if (IS_MGMT_PORT(unit, port)) { 892 si->port_num_cosq[port] = 10; 893 si->port_num_uc_cosq[port] = 10; 894 if (si->port_l2p_mapping[port] == 128) { 895 /* 2nd Mgmt port */ 896 si->port_cosq_base[port] = SOC_TD3_SECOND_MGMT_BASE; 897 si->port_uc_cosq_base[port] = SOC_TD3_SECOND_MGMT_BASE; 898 } else { 899 si->port_cosq_base[port] = SOC_TD3_MGMT_MCQ_BASE; 900 si->port_uc_cosq_base[port] = SOC_TD3_MGMT_UCQ_BASE; 901 } 902 } else { 903 si->port_num_cosq[port] = 10; 904 si->port_cosq_base[port] = 905 (mmu_port % 64) * 10; 906 si->port_num_uc_cosq[port] = 10; 907 si->port_uc_cosq_base[port] = 908 (mmu_port % 64) * 10; 909 si->port_num_ext_cosq[port] = 0; 910 } 911 912 return SOC_E_NONE; 913 } 914 915 /* 916 * cpu port (mmu port 64): 48 queues (650-697) 917 * loopback port (mmu port 65, 193): 10 queues (640-649) 918 * mgmt port (mmu port 192): 10 UC, 10 MC queues 919 */ 920 int 921 soc_trident3_num_cosq_init(int unit) 922 { 923 int port; 924 925 PBMP_ALL_ITER(unit, port) { 926 SOC_IF_ERROR_RETURN 927 (soc_trident3_num_cosq_init_port(unit, port)); 928 } 929 930 return SOC_E_NONE; 931 } 932 933 STATIC int 934 soc_trident3_max_frequency_get(int unit, uint16 dev_id, uint8 rev_id, 935 int skew_id, int *frequency) 936 { 937 switch (dev_id) { 938 case BCM56870_DEVICE_ID: 939 case BCM56873_DEVICE_ID: 940 *frequency = CCLK_FREQ_1525MHZ; 941 break; 942 default: 943 return SOC_E_INTERNAL; 944 } 945 946 return SOC_E_NONE; 947 } 948 949 void 950 soc_trident3_tsc_map_get(int unit, uint32 *tsc_map) 951 { 952 *tsc_map = 0xffffffff; 953 } 954 955 void 956 soc_trident3_pipe_map_get(int unit, uint32 *pipe_map) 957 { 958 soc_info_t *si; 959 int port; 960 961 si = &SOC_INFO(unit); 962 963 *pipe_map = 0; 964 PBMP_LB_ITER(unit, port) { 965 *pipe_map |= 1 << si->port_pipe[port]; 966 } 967 } 968 969 /* 970 * #1 single: 100 - x - x - x SOC_TD3_PORT_RATIO_SINGLE 971 * #2 single: 40 - x - x - x SOC_TD3_PORT_RATIO_TRI_023_2_1_1 972 * #3 dual: 50 - x - 50 - x SOC_TD3_PORT_RATIO_DUAL_1_1 973 * #4 dual: 40 - x - 40 - x SOC_TD3_PORT_RATIO_DUAL_1_1 974 * #5 dual: 20 - x - 20 - x SOC_TD3_PORT_RATIO_DUAL_1_1 975 * #6 dual: 40 - x - 20 - x SOC_TD3_PORT_RATIO_DUAL_2_1 976 * #7 dual: 20 - x - 40 - x SOC_TD3_PORT_RATIO_DUAL_1_2 977 * #8 tri: 50 - x - 25/x - 25/x SOC_TD3_PORT_RATIO_TRI_023_2_1_1 978 * #9 tri: 20 - x - 10/x - 10/x SOC_TD3_PORT_RATIO_TRI_023_2_1_1 979 * #10 tri: 40 - x - 10/x - 10/x SOC_TD3_PORT_RATIO_TRI_023_4_1_1 980 * #11 tri: 25/x - 25/x - 50 - x SOC_TD3_PORT_RATIO_TRI_012_1_1_2 981 * #12 tri: 10/x - 10/x - 20 - x SOC_TD3_PORT_RATIO_TRI_012_1_1_2 982 * #13 tri: 10/x - 10/x - 40 - x SOC_TD3_PORT_RATIO_TRI_012_1_1_4 983 * #14 quad: 25/x - 25/x - 25/x - 25/x SOC_TD3_PORT_RATIO_QUAD 984 * #15 quad: 10/x - 10/x - 10/x - 10/x SOC_TD3_PORT_RATIO_QUAD 985 */ 986 void 987 soc_trident3_port_ratio_get(int unit, int clport, int *mode) 988 { 989 soc_info_t *si; 990 int port, phy_port_base, lane; 991 int num_lanes[_TD3_PORTS_PER_PBLK]; 992 int speed_max[_TD3_PORTS_PER_PBLK]; 993 994 si = &SOC_INFO(unit); 995 phy_port_base = 1 + clport * _TD3_PORTS_PER_PBLK; 996 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane += 2) { 997 port = si->port_p2l_mapping[phy_port_base + lane]; 998 if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 999 num_lanes[lane] = -1; 1000 speed_max[lane] = -1; 1001 } else { 1002 num_lanes[lane] = si->port_num_lanes[port]; 1003 speed_max[lane] = si->port_speed_max[port]; 1004 } 1005 } 1006 1007 if (num_lanes[0] == 4) { 1008 *mode = SOC_TD3_PORT_RATIO_SINGLE; 1009 } else if (num_lanes[0] == 2 && num_lanes[2] == 2) { 1010 if (speed_max[0] == speed_max[2]) { 1011 *mode = SOC_TD3_PORT_RATIO_DUAL_1_1; 1012 } else if (speed_max[0] > speed_max[2]) { 1013 *mode = SOC_TD3_PORT_RATIO_DUAL_2_1; 1014 } else { 1015 *mode = SOC_TD3_PORT_RATIO_DUAL_1_2; 1016 } 1017 } else if (num_lanes[0] == 2) { 1018 if (num_lanes[2] == -1) { 1019 *mode = SOC_TD3_PORT_RATIO_DUAL_1_1; 1020 } else { 1021 *mode = (speed_max[0] == 20000 || speed_max[0] == 21000 ) ? 1022 SOC_TD3_PORT_RATIO_TRI_023_2_1_1 : SOC_TD3_PORT_RATIO_TRI_023_4_1_1; 1023 } 1024 } else if (num_lanes[2] == 2) { 1025 if (num_lanes[0] == -1) { 1026 *mode = SOC_TD3_PORT_RATIO_DUAL_1_1; 1027 } else { 1028 *mode = (speed_max[2] == 20000 || speed_max[2] == 21000 ) ? 1029 SOC_TD3_PORT_RATIO_TRI_012_1_1_2 : SOC_TD3_PORT_RATIO_TRI_012_1_1_4; 1030 } 1031 } else { 1032 *mode = SOC_TD3_PORT_RATIO_QUAD; 1033 } 1034 } 1035 1036 #if 0 1037 STATIC void 1038 _soc_trident3_pipe_bandwidth_get(int unit, int pipe, 1039 int *max_pipe_core_bandwidth, 1040 int *pipe_linerate_bandwidth, 1041 int *pipe_oversub_bandwidth) 1042 { 1043 soc_info_t *si; 1044 int port; 1045 int bandwidth; 1046 1047 si = &SOC_INFO(unit); 1048 1049 *max_pipe_core_bandwidth = si->bandwidth / 4; 1050 1051 *pipe_linerate_bandwidth = 0; 1052 *pipe_oversub_bandwidth = 0; 1053 PBMP_PORT_ITER(unit, port) { 1054 if (si->port_pipe[port] != pipe) { 1055 continue; 1056 } 1057 bandwidth = si->port_speed_max[port] >= 2500 ? 1058 si->port_speed_max[port] : 2500; 1059 if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 1060 *pipe_oversub_bandwidth += bandwidth; 1061 } else { 1062 *pipe_linerate_bandwidth += bandwidth; 1063 } 1064 } 1065 /* 10G cpu/management, 5G loopback, 10G purge/refresh */ 1066 *pipe_linerate_bandwidth += 25; 1067 } 1068 #endif 1069 1070 #if defined(BCM_TD3_ASF_EXCLUDE) 1071 /* 1072 * Cut-through class encoding 1073 * 0 - SAF 1074 * 1 - 10GE 1075 * 2 - HG[11] 1076 * 3 - 20GE 1077 * 4 - 21[HG} 1078 * 5 - 25GE 1079 * 6 - HG[27] 1080 * 7 - 40GE 1081 * 8 - HG[42] 1082 * 9 - 50GE 1083 * 10 - HG[53] 1084 * 11 - 100GE 1085 * 12 - HG[106] 1086 */ 1087 STATIC void 1088 _soc_trident3_speed_to_ct_class_mapping(int unit, int speed, int *ct_class) 1089 { 1090 if (speed >= 40000) { 1091 if (speed >= 100000) { 1092 *ct_class = speed > 100000 ? 12 : 11; 1093 } else if (speed >= 50000) { 1094 *ct_class = speed > 50000 ? 10 : 9; 1095 } else { 1096 *ct_class = speed > 40000 ? 8 : 7; 1097 } 1098 } else { 1099 if (speed >= 25000) { 1100 *ct_class = speed > 25000 ? 6 : 5; 1101 } else if (speed >= 20000) { 1102 *ct_class = speed > 20000 ? 4 : 3; 1103 } else { 1104 *ct_class = speed > 10000 ? 2 : 1; 1105 } 1106 } 1107 } 1108 #endif 1109 1110 /* 1111 * Oversubscription group speed class encoding 1112 * 0 - 0 1113 * 1 - 2 (10G) 1114 * 2 - 4 (20G) 1115 * 3 - 5 (25G) 1116 * 4 - 8 (40G) 1117 * 5 - 10 (50G) 1118 * 6 - 20 (100G) 1119 */ 1120 STATIC void 1121 _soc_trident3_speed_to_ovs_class_mapping(int unit, int speed, int *ovs_class) 1122 { 1123 if (speed >= 40000) { 1124 if (speed >= 100000) { 1125 *ovs_class = 6; 1126 } else if (speed >= 50000) { 1127 *ovs_class = 5; 1128 } else { 1129 *ovs_class = 4; 1130 } 1131 } else { 1132 if (speed >= 25000) { 1133 *ovs_class = 3; 1134 } else if (speed >= 20000) { 1135 *ovs_class = 2; 1136 } else { 1137 *ovs_class = 1; 1138 } 1139 } 1140 } 1141 1142 /* Function to get the number of ports present in a given Port Macro */ 1143 STATIC int 1144 soc_td3_ports_per_pm_get(int unit, int pm_id) 1145 { 1146 soc_info_t *si; 1147 int phy_port, num_ports = 0, i; 1148 1149 si = &SOC_INFO(unit); 1150 if (pm_id >= _TD3_PBLKS_PER_DEV(unit)) { 1151 return SOC_E_PARAM; 1152 } 1153 phy_port = 1 + (pm_id * _TD3_PORTS_PER_PBLK); 1154 1155 for (i = 0; i < _TD3_PORTS_PER_PBLK; ) { 1156 if (si->port_p2l_mapping[phy_port + i] != -1) { 1157 num_ports ++; 1158 i += si->port_num_lanes[si->port_p2l_mapping[phy_port + i]]; 1159 } else { 1160 i ++; 1161 } 1162 } 1163 return num_ports; 1164 } 1165 1166 STATIC int 1167 _soc_td3_port_flex_init(int unit, int is_any_cap) 1168 { 1169 soc_info_t *si; 1170 int pm, blk_idx, blk_type; 1171 int flex_en, static_ports, max_ports; 1172 1173 si = &SOC_INFO(unit); 1174 SHR_BITCLR_RANGE(si->flexible_pm_bitmap, 0, SOC_MAX_NUM_BLKS); 1175 1176 /* portmap_x=y:speed:i */ 1177 /* portmap_x=y:speed:cap */ 1178 if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all)) || is_any_cap) { 1179 SHR_BITSET_RANGE(si->flexible_pm_bitmap, 2, _TD3_PBLKS_PER_DEV(unit)); 1180 } else { 1181 /* port_flex_enable{x}=<0...1> */ 1182 /* port_flex_enable_corex=<0...1> */ 1183 /* port_flex_enable=<0...1> */ 1184 for (blk_idx = 0; (blk_idx < SOC_MAX_NUM_BLKS) && (SOC_BLOCK_TYPE(unit, blk_idx)!= -1); blk_idx++) { 1185 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 1186 pm = SOC_BLOCK_NUMBER(unit, blk_idx); 1187 if (blk_type == SOC_BLK_CLPORT) { 1188 /* port_flex_enable_corex=<0...1> */ 1189 flex_en = soc_property_suffix_num_get_only_suffix(unit, 1190 pm, spn_PORT_FLEX_ENABLE, "core", -1); 1191 /* port_flex_enable{x}=<0...1> */ 1192 /* port_flex_enable=<0...1> */ 1193 if (flex_en == -1) { 1194 flex_en = soc_property_phys_port_get(unit, 1195 (pm * _TD3_PORTS_PER_PBLK + 1), 1196 spn_PORT_FLEX_ENABLE, 0); 1197 } 1198 if (flex_en) { 1199 SHR_BITSET(si->flexible_pm_bitmap, blk_idx); 1200 } 1201 } 1202 } 1203 } 1204 1205 si->flex_eligible = 1206 (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, _TD3_PBLKS_PER_DEV(unit))); 1207 1208 /* port_flex_max_ports */ 1209 memset(&(si->pm_max_ports), 0xff, sizeof(si->pm_max_ports)); 1210 for (blk_idx = 0; (blk_idx < SOC_MAX_NUM_BLKS) && (SOC_BLOCK_TYPE(unit, blk_idx)!= -1); blk_idx++) { 1211 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 1212 pm = SOC_BLOCK_NUMBER(unit, blk_idx); 1213 if (blk_type == SOC_BLK_CLPORT) { 1214 static_ports = soc_td3_ports_per_pm_get(unit, pm); 1215 if (SHR_BITGET(si->flexible_pm_bitmap, blk_idx)) { 1216 /* port_flex_max_ports{x}=y */ 1217 max_ports = soc_property_phys_port_get(unit, 1218 (pm * _TD3_PORTS_PER_PBLK + 1), 1219 spn_PORT_FLEX_MAX_PORTS, -1); 1220 /* port_flex_max_ports_corex=y */ 1221 if (max_ports == -1) { 1222 max_ports = soc_property_suffix_num_get(unit, pm, 1223 spn_PORT_FLEX_MAX_PORTS, "core", 4); 1224 } 1225 /* validation check */ 1226 if ((max_ports < 0) || (max_ports > 4) || (max_ports < static_ports)) { 1227 LOG_CLI((BSL_META_U(unit, 1228 "Core %d: Bad port_flex_max_ports %d; static ports %d"), 1229 pm, max_ports, static_ports)); 1230 return SOC_E_CONFIG; 1231 } 1232 si->pm_max_ports[blk_idx] = max_ports; 1233 } else { 1234 si->pm_max_ports[blk_idx] = static_ports; 1235 } 1236 1237 } 1238 } 1239 1240 return SOC_E_NONE; 1241 } 1242 1243 /* 1244 * Function: 1245 * soc_trident3_port_map_validity_check 1246 * Purpose: 1247 * Logical Port <-> Physical port map is fixed in Trident3. 1248 * This function checks if port map used in config.bcm is correct. 1249 * Parameters: 1250 * unit (IN) - switch unit 1251 * port (IN) - device port 1252 * phy_port (IN) - physical port 1253 * Returns: 1254 * SOC_E_FAIL OR SOC_E_NONE 1255 */ 1256 int 1257 soc_trident3_port_map_validity_check(int unit, int port, int phy_port) { 1258 1259 int pmap_err = 0; 1260 1261 if ((port >= 0) && (port <= 64)) { 1262 if (port != phy_port) { 1263 pmap_err = 1; 1264 } 1265 } else if((port == 65) && (phy_port != 130)) { 1266 pmap_err = 1; 1267 } else if ((port == 66) && (phy_port != 129)) { 1268 pmap_err = 1; 1269 } else if((port >= 67) && (port <= 130)) { 1270 if (port != phy_port + 2) { 1271 pmap_err = 1; 1272 } 1273 } else if((port == 131) && (phy_port != 131)) { 1274 pmap_err = 1; 1275 } 1276 1277 if (pmap_err) { 1278 LOG_CLI((BSL_META_U(unit, 1279 "Port %d: Invalid port map configuration\n"), 1280 port)); 1281 return SOC_E_FAIL; 1282 } 1283 1284 return SOC_E_NONE; 1285 } 1286 1287 /* 1288 * Trident3 port mapping 1289 * 1290 * physical idb/ device mmu 1291 * port idb port port port 1292 * CMIC 0 0/64 0 64 1293 * CLPORT0-7 1-32 0/0-31 1-32 0-31 1294 * CLPORT8-15 33-64 0/32-63 33-64 32-63 1295 * CLPORT16-23 65-96 1/0-32 67-98 128-159 1296 * CLPORT24-31 97-128 1/32-63 99-130 160-191 1297 * MGMT 129 1/64 66 192 1298 * LBPORT0 130 0/65 65 65 1299 * LBPORT1 131 1/65 131 193 1300 * Although MMU port number is flexible within the above range, it is 1301 * configured as a fixed mapped to physical port number 1302 */ 1303 int 1304 soc_trident3_port_config_init(int unit, uint16 dev_id) 1305 { 1306 #if defined(BCM_56870_A0) 1307 soc_info_t *si; 1308 char *config_str, *sub_str, *sub_str_end; 1309 static const char str_2p5[] = "2.5"; 1310 char str_buf[8]; 1311 int rv, oversub_mode; 1312 int num_port, num_phy_port, num_mmu_port; 1313 int port, phy_port, mmu_port, idb_port; 1314 int pipe, xpe, sc, index, bandwidth_cap, is_any_cap = FALSE; 1315 int port_bandwidth, blk_idx; 1316 char option1=0, option2=0; 1317 uint32 pipe_map, xpe_map, sc_map, ipipe_map, epipe_map; 1318 soc_pbmp_t oversub_pbm; 1319 int list_len, frequency; 1320 static const int freq_list[] = { 1525, 1425, 1325, 1012, 850 }; 1321 const char *str_ratio[] = { "2:3", "1:1" }; 1322 static const int dpp_ratio_x10_list[] = { 1323 15, /* core clk : pp clk ratio is 3:2 (default) */ 1324 10 /* core clk : pp clk ratio is 1:1 */ 1325 }; 1326 1327 static const struct { 1328 int port; 1329 int phy_port; 1330 int pipe; 1331 int idb_port; 1332 int mmu_port; 1333 } fixed_ports[] = { 1334 { 0, 0, 0, 64, 64 }, /* cpu port */ 1335 { 65, 130, 0, 65, 65 }, /* loopback port 0 */ 1336 { 131, 131, 1, 65, 193 }, /* loopback port 1 */ 1337 }; 1338 1339 si = &SOC_INFO(unit); 1340 1341 num_phy_port = TD3_NUM_PHY_PORT; 1342 num_port = TD3_NUM_PORT; 1343 num_mmu_port = TD3_NUM_MMU_PORT; 1344 1345 soc_trident3_max_frequency_get(unit, dev_id, -1, -1, &si->frequency); 1346 frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, -1); 1347 1348 /* Core CLK frequency */ 1349 if (frequency != -1 && frequency <= si->frequency) { 1350 list_len = COUNTOF(freq_list); 1351 for (index = 0; index < list_len; index++) { 1352 if (freq_list[index] <= si->frequency && 1353 frequency == freq_list[index]) { 1354 break; 1355 } 1356 } 1357 1358 if (index < list_len) { 1359 si->frequency = frequency; 1360 } else { 1361 LOG_CLI((BSL_META_U(unit, 1362 "*** Input core clock frequency %dMHz is not " 1363 "supported!\n"), frequency)); 1364 } 1365 } 1366 1367 config_str = soc_property_get_str(unit, spn_DPP_CLOCK_RATIO); 1368 if (config_str) { 1369 list_len = COUNTOF(dpp_ratio_x10_list); 1370 for (index = 0; index < list_len; index++) { 1371 if (!sal_strcmp(config_str, str_ratio[index])) { 1372 break; 1373 } 1374 } 1375 if (index < list_len && 1376 !(si->frequency > 1012 && dpp_ratio_x10_list[index] == 10)) { 1377 /* ratio 1:1 with core freq larger than 1125MHz is not supported */ 1378 si->dpp_clk_ratio_x10 = dpp_ratio_x10_list[index]; 1379 } else { 1380 LOG_CLI((BSL_META_U(unit, 1381 "*** Input dpp clock frequency ratio %s is not " 1382 "supported with core frequency %d!\n"), 1383 config_str, si->frequency)); 1384 } 1385 } 1386 1387 si->bandwidth = 2048000; 1388 1389 1390 oversub_pbm = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0); 1391 oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 1) || 1392 SOC_PBMP_NOT_NULL(oversub_pbm); 1393 1394 si->oversub_mode = oversub_mode; 1395 si->os_mixed_sister_25_50_enable = soc_property_get(unit, 1396 spn_OVERSUBSCRIBE_MIXED_SISTER_25_50_ENABLE, 0); 1397 1398 /* Line rate mode requires DPR 1:1 and Core frequency no more than 1125MHz */ 1399 if ((!si->oversub_mode)) { 1400 if (si->frequency > 1012) { 1401 LOG_CLI((BSL_META_U(unit, 1402 "*** Input core clock frequency %dMHz is not " 1403 "supported with line rate mode! " 1404 "Must be no more than 1012MHz.\n"), si->frequency)); 1405 return SOC_E_FAIL; 1406 } 1407 if (si->dpp_clk_ratio_x10 != 10) { 1408 LOG_CLI((BSL_META_U(unit, 1409 "*** Input dpp clock frequency ratio %s is not " 1410 "supported with line rate mode! " 1411 "Must be 1:1.\n"), (config_str ? config_str : ""))); 1412 return SOC_E_FAIL; 1413 } 1414 } 1415 1416 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 1417 si->port_p2l_mapping[phy_port] = -1; 1418 si->port_p2m_mapping[phy_port] = -1; 1419 } 1420 for (port = 0; port < num_port; port++) { 1421 si->port_l2p_mapping[port] = -1; 1422 si->port_l2i_mapping[port] = -1; 1423 si->port_speed_max[port] = -1; 1424 si->port_group[port] = -1; 1425 si->port_serdes[port] = -1; 1426 si->port_pipe[port] = -1; 1427 si->port_num_lanes[port] = -1; 1428 } 1429 for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) { 1430 si->port_m2p_mapping[mmu_port] = -1; 1431 } 1432 SOC_PBMP_CLEAR(si->eq_pbm); 1433 SOC_PBMP_CLEAR(si->management_pbm); 1434 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1435 SOC_PBMP_CLEAR(si->pipe_pbm[pipe]); 1436 }; 1437 SOC_PBMP_CLEAR(si->oversub_pbm); 1438 SOC_PBMP_CLEAR(si->all.disabled_bitmap); 1439 1440 /* Populate the fixed mapped ports */ 1441 for (index = 0; index < COUNTOF(fixed_ports); index++) { 1442 port = fixed_ports[index].port; 1443 phy_port = fixed_ports[index].phy_port; 1444 pipe = fixed_ports[index].pipe;; 1445 1446 si->port_l2p_mapping[port] = phy_port; 1447 si->port_l2i_mapping[port] = fixed_ports[index].idb_port; 1448 si->port_p2l_mapping[phy_port] = port; 1449 si->port_p2m_mapping[phy_port] = fixed_ports[index].mmu_port; 1450 si->port_pipe[port] = pipe; 1451 } 1452 1453 rv = SOC_E_NONE; 1454 for (port = 1; port < num_port; port++) { 1455 if (si->port_l2p_mapping[port] != -1) { /* fixed mapped port */ 1456 continue; 1457 } 1458 1459 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 1460 if (config_str == NULL) { 1461 continue; 1462 } 1463 1464 /* 1465 * portmap_<port>=<physical port number>:<bandwidth in Gb>[:<bandwidth cap in Gb/i(inactive)/1/2/4(num lanes)>][:<i>] 1466 * eg: portmap_1=1:100 1467 * or portmap_1=1:40 1468 * or portmap_1=1:40:i 1469 * or portmap_1=1:40:2 1470 * or portmap_1=1:40:2:i 1471 * or portmap_1=1:10:100 1472 */ 1473 sub_str = config_str; 1474 1475 /* Parse physical port number */ 1476 phy_port = sal_ctoi(sub_str, &sub_str_end); 1477 if (sub_str == sub_str_end) { 1478 LOG_CLI((BSL_META_U(unit, 1479 "Port %d: Missing physical port information \"%s\"\n"), 1480 port, config_str)); 1481 rv = SOC_E_FAIL; 1482 continue; 1483 } 1484 if (phy_port < 0 || phy_port >= num_phy_port) { 1485 LOG_CLI((BSL_META_U(unit, 1486 "Port %d: Invalid physical port number %d\n"), 1487 port, phy_port)); 1488 rv = SOC_E_FAIL; 1489 continue; 1490 } 1491 /* coverity[check_after_sink : FALSE] */ 1492 if (si->port_p2l_mapping[phy_port] != -1) { 1493 LOG_CLI((BSL_META_U(unit, 1494 "Port %d: Physical port %d is used by port %d\n"), 1495 port, phy_port, si->port_p2l_mapping[phy_port])); 1496 rv = SOC_E_FAIL; 1497 continue; 1498 } 1499 1500 /* Skip ':' between physical port number and bandwidth */ 1501 sub_str = sub_str_end; 1502 if (*sub_str != '\0') { 1503 if (*sub_str != ':') { 1504 LOG_CLI((BSL_META_U(unit, 1505 "Port %d: Bad config string \"%s\"\n"), 1506 port, config_str)); 1507 rv = SOC_E_FAIL; 1508 continue; 1509 } 1510 sub_str++; 1511 } 1512 1513 if (soc_trident3_port_map_validity_check(unit, port, phy_port)) { 1514 rv = SOC_E_FAIL; 1515 continue; 1516 } 1517 1518 /* Parse bandwidth */ 1519 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 1520 if (sub_str[index] == '\0') { 1521 break; 1522 } 1523 str_buf[index] = sub_str[index]; 1524 } 1525 str_buf[index] = '\0'; 1526 if (!sal_strcmp(str_buf, str_2p5)) { 1527 port_bandwidth = 2500; 1528 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 1529 } else { 1530 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 1531 if (sub_str == sub_str_end) { 1532 LOG_CLI((BSL_META_U(unit, 1533 "Port %d: Missing bandwidth information \"%s\"\n"), 1534 port, config_str)); 1535 rv = SOC_E_FAIL; 1536 continue; 1537 } 1538 switch (port_bandwidth) { 1539 case 1000: 1540 case 10000: 1541 case 11000: 1542 case 20000: 1543 case 21000: 1544 case 25000: 1545 case 27000: 1546 case 40000: 1547 case 42000: 1548 case 50000: 1549 case 53000: 1550 case 100000: 1551 case 106000: 1552 break; 1553 default: 1554 LOG_CLI((BSL_META_U(unit, 1555 "Port %d: Invalid bandwidth %d Gb\n"), 1556 port, port_bandwidth / 1000)); 1557 rv = SOC_E_FAIL; 1558 continue; 1559 } 1560 if ((!si->oversub_mode) && ((port_bandwidth == 100000) || 1561 (port_bandwidth == 106000))) { 1562 LOG_CLI((BSL_META_U(unit, 1563 "Port %d: %d Gb is Invalid bandwidth for line rate configuration\n"), 1564 port, port_bandwidth / 1000)); 1565 return SOC_E_FAIL; 1566 } 1567 } 1568 1569 /* Check if option presents */ 1570 option1 = 0; option2 = 0; 1571 sub_str = sub_str_end; 1572 if (*sub_str != '\0') { 1573 /* Skip ':' between bandwidth and options */ 1574 /* Skip ':' between bandwidth and bandwidth cap or options */ 1575 if (*sub_str != ':') { 1576 LOG_CLI((BSL_META_U(unit, 1577 "Port %d: Bad config string \"%s\"\n"), 1578 port, config_str)); 1579 rv = SOC_E_FAIL; 1580 continue; 1581 } 1582 sub_str++; 1583 1584 if (*sub_str != '\0') { 1585 /* Parse bandwidth cap or options */ 1586 bandwidth_cap = sal_ctoi(sub_str, &sub_str_end) * 1000; 1587 switch (bandwidth_cap) { 1588 case 20000: 1589 case 21000: 1590 case 25000: 1591 case 27000: 1592 case 40000: 1593 case 42000: 1594 case 50000: 1595 case 53000: 1596 case 100000: 1597 case 106000: 1598 sub_str = sub_str_end; 1599 _soc_td3_port_speed_cap[unit][port] = bandwidth_cap; 1600 /* Flex config detected, port speed cap specified */ 1601 is_any_cap = TRUE; 1602 break; 1603 default: 1604 if (!(*sub_str == 'i' || *sub_str == '1' || 1605 *sub_str == 'm' || *sub_str == '2' || 1606 *sub_str == '4')) { 1607 LOG_CLI((BSL_META_U(unit, 1608 "Port %d: Bad config string " 1609 "\"%s\"\n"), 1610 port, config_str)); 1611 rv = SOC_E_FAIL; 1612 continue; 1613 } else { 1614 option1 = *sub_str; 1615 sub_str++; 1616 } 1617 } 1618 1619 /* Check if more options present */ 1620 if (*sub_str != '\0') { 1621 /* Skip ':' between options */ 1622 if (*sub_str != ':') { 1623 LOG_CLI((BSL_META_U(unit, 1624 "Port %d: Bad config string \"%s\"\n"), 1625 port, config_str)); 1626 rv = SOC_E_FAIL; 1627 continue; 1628 } 1629 sub_str++; 1630 1631 if (*sub_str != 'i' && *sub_str != 'm') { 1632 LOG_CLI((BSL_META_U(unit, 1633 "Port %d: Bad config string \"%s\"\n"), 1634 port, config_str)); 1635 rv = SOC_E_FAIL; 1636 continue; 1637 } 1638 option2 = *sub_str; 1639 sub_str++; 1640 } 1641 } 1642 } 1643 1644 /* Check trailing string */ 1645 if (*sub_str != '\0') { 1646 LOG_CLI((BSL_META_U(unit, 1647 "Port %d: Bad config string \"%s\"\n"), 1648 port, config_str)); 1649 rv = SOC_E_FAIL; 1650 continue; 1651 } 1652 1653 /* Update soc_info */ 1654 si->port_l2p_mapping[port] = phy_port; 1655 si->port_p2l_mapping[phy_port] = port; 1656 if (phy_port == 129) { /* management port 0 */ 1657 pipe = 1; 1658 si->port_l2i_mapping[port] = 64; 1659 si->port_p2m_mapping[phy_port] = 192; 1660 si->port_serdes[port] = 32; 1661 SOC_PBMP_PORT_ADD(si->management_pbm, port); 1662 if (option2 == 'm'){ 1663 si->port_num_lanes[port] = (option1 == '4')? 4 : (option1 == '2')? 2 : 1; 1664 } else { 1665 si->port_num_lanes[port] = 1; 1666 } 1667 } else if ((phy_port == 128) && ((option1 == 'm')||(option2 == 'm'))) { /* Management port 1 */ 1668 pipe = 1; 1669 si->port_l2i_mapping[port] = 63; /* Local MMU Port */ 1670 si->port_p2m_mapping[phy_port] = 191; /* Global MMU Port */ 1671 si->port_serdes[port] = 32; 1672 SOC_PORT_BLOCK(unit, phy_port) = SOC_PORT_BLOCK(unit, 129); /* lane 2 */ 1673 SOC_PORT_BINDEX(unit, phy_port) = 2; 1674 SOC_PBMP_PORT_ADD(si->management_pbm, port); 1675 if (option2 == 'm'){ 1676 si->port_num_lanes[port] = (option1 == '2')? 2 : 1; 1677 } else { 1678 si->port_num_lanes[port] = 1; 1679 } 1680 } else { 1681 idb_port = (phy_port - 1) % _TD3_PORTS_PER_PIPE; 1682 pipe = (phy_port - 1) / _TD3_PORTS_PER_PIPE; 1683 si->port_l2i_mapping[port] = idb_port; 1684 si->port_p2m_mapping[phy_port] = (pipe << 7) | idb_port; 1685 si->port_serdes[port] = (phy_port - 1) / _TD3_PORTS_PER_PBLK; 1686 if (phy_port == 128) { 1687 SOC_PORT_BLOCK(unit, phy_port) = SOC_PORT_BLOCK(unit, 127); 1688 SOC_PORT_BINDEX(unit, phy_port) = SOC_PORT_BINDEX(unit, 127) + 1; 1689 } 1690 } 1691 si->port_pipe[port] = pipe; 1692 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 1693 si->port_speed_max[port] = port_bandwidth; 1694 if (option1 == 'i') { 1695 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 1696 } else { 1697 if ((option2 != 'm') && (option1 != 'm')) { 1698 switch (option1) { 1699 case '1': si->port_num_lanes[port] = 1; break; 1700 case '2': si->port_num_lanes[port] = 2; break; 1701 case '4': si->port_num_lanes[port] = 4; break; 1702 default: si->port_num_lanes[port] = 4; break; 1703 } 1704 } 1705 } 1706 if (option2 == 'i') { 1707 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 1708 } 1709 if (oversub_mode) { 1710 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 1711 } 1712 } 1713 1714 for (index = 1; index < COUNTOF(fixed_ports); index++) { 1715 pipe = fixed_ports[index].pipe; 1716 if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) { 1717 /* Remove loopback port if the entire pipe is not in use */ 1718 port = fixed_ports[index].port; 1719 phy_port = fixed_ports[index].phy_port; 1720 si->port_l2p_mapping[port] = -1; 1721 si->port_l2i_mapping[port] = -1; 1722 si->port_p2l_mapping[phy_port] = -1; 1723 si->port_p2m_mapping[phy_port] = -1; 1724 si->port_pipe[port] = -1; 1725 } else { 1726 port = fixed_ports[index].port; 1727 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 1728 } 1729 } 1730 1731 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 1732 LOG_CLI((BSL_META_U(unit, 1733 "physical to logical mapping:"))); 1734 for (index = 0; index < num_phy_port; index++) { 1735 if (index % 16 == 0) { 1736 LOG_CLI((BSL_META_U(unit, 1737 "\n "))); 1738 } 1739 LOG_CLI((BSL_META_U(unit, 1740 " %3d"), si->port_p2l_mapping[index])); 1741 } 1742 LOG_CLI((BSL_META_U(unit, 1743 "\n"))); 1744 LOG_CLI((BSL_META_U(unit, 1745 "physical port bandwidth:"))); 1746 for (index = 0; index < num_phy_port; index++) { 1747 if (index % 16 == 0) { 1748 LOG_CLI((BSL_META_U(unit, 1749 "\n "))); 1750 } 1751 port = si->port_p2l_mapping[index]; 1752 if (port == -1) { 1753 LOG_CLI((BSL_META_U(unit, 1754 " -1"))); 1755 } else if (si->port_speed_max[port] == 2500) { 1756 LOG_CLI((BSL_META_U(unit, 1757 " 2.5"))); 1758 } else { 1759 LOG_CLI((BSL_META_U(unit, 1760 " %3d"), si->port_speed_max[port] / 1000)); 1761 } 1762 } 1763 LOG_CLI((BSL_META_U(unit, 1764 "\n"))); 1765 1766 LOG_CLI((BSL_META_U(unit, 1767 "physical to mmu mapping:"))); 1768 for (index = 0; index < num_phy_port; index++) { 1769 if (index % 16 == 0) { 1770 LOG_CLI((BSL_META_U(unit, 1771 "\n "))); 1772 } 1773 LOG_CLI((BSL_META_U(unit, 1774 " %3d"), si->port_p2m_mapping[index])); 1775 } 1776 LOG_CLI((BSL_META_U(unit, 1777 "\n"))); 1778 } 1779 1780 1781 1782 /* Setup port_num_lanes */ 1783 for (port = 0; port < num_port; port++) { 1784 if (si->port_speed_max[port] > 53000) { 1785 si->port_num_lanes[port] = 4; 1786 } else if (si->port_speed_max[port] == 40000 || 1787 si->port_speed_max[port] == 42000) { 1788 /* Note: 40G, HG[42] can operate either in dual or quad lane mode 1789 Check if adjacent ports exist to set dual lane mode */ 1790 phy_port = si->port_l2p_mapping[port]; 1791 if (phy_port >= 1 && phy_port <= 127 && phy_port != -1) { 1792 int sis_port; 1793 1794 if (phy_port % 4 == 1) { 1795 sis_port = si->port_p2l_mapping[phy_port+2]; 1796 if ((si->port_speed_max[sis_port] > 0) && 1797 !SOC_PBMP_MEMBER(si->all.disabled_bitmap, sis_port)) { 1798 si->port_num_lanes[port] = 2; 1799 } 1800 } else if (phy_port % 4 == 3) { 1801 sis_port = si->port_p2l_mapping[phy_port-2]; 1802 if ((si->port_speed_max[sis_port] > 0) && 1803 !SOC_PBMP_MEMBER(si->all.disabled_bitmap, sis_port)) { 1804 si->port_num_lanes[port] = 2; 1805 } 1806 } 1807 } 1808 /* Else set to quad lane mode by default if the user did not 1809 specify anything and no sister ports existed */ 1810 if (si->port_num_lanes[port] == -1) { 1811 si->port_num_lanes[port] = 4; 1812 } 1813 } else if ((si->port_speed_max[port] >= 20000) && 1814 !(si->port_speed_max[port] == 25000 || 1815 si->port_speed_max[port] == 27000)) { 1816 /* 50G, HG[53], 20G MLD, HG[21] use 2 lanes */ 1817 si->port_num_lanes[port] = 2; 1818 } else if (si->port_speed_max[port] > 0) { 1819 /* 10G XFI, HG[11], 25G XFI and HG[27] use 1 lane */ 1820 if (!SOC_PBMP_MEMBER(SOC_INFO(unit).management_pbm, port)) { 1821 si->port_num_lanes[port] = 1; 1822 } 1823 } 1824 } 1825 1826 /* get flex port properties */ 1827 if (SOC_FAILURE(_soc_td3_port_flex_init(unit, is_any_cap))) { 1828 rv = SOC_E_FAIL; 1829 } 1830 1831 #if defined(BCM_WARM_BOOT_SUPPORT) 1832 if (si->flex_eligible) { 1833 if (SOC_WARM_BOOT(unit)) { 1834 SOC_IF_ERROR_RETURN( 1835 soc_td3_flexport_scache_recovery(unit)); 1836 } else { 1837 SOC_IF_ERROR_RETURN( 1838 soc_td3_flexport_scache_allocate(unit)); 1839 } 1840 } 1841 #endif 1842 1843 /* 1844 * After WARM BOOT flex port scache recovery, P/L and L/P bit map changed 1845 * Need to redo bit map creation per port type. 1846 */ 1847 1848 /* Setup high speed port (HSP) pbm */ 1849 for (port = 0; port < num_port; port++) { 1850 phy_port = si->port_l2p_mapping[port]; 1851 if (phy_port == -1) { 1852 continue; 1853 } 1854 1855 if (phy_port == 129) { /* management port 0 */ 1856 pipe = 1; 1857 si->port_l2i_mapping[port] = 64; 1858 si->port_p2m_mapping[phy_port] = 192; 1859 si->port_serdes[port] = 32; 1860 SOC_PBMP_PORT_ADD(si->management_pbm, port); 1861 } else if ((phy_port == 128) && (option1 == 'm')) { /* Management port 1 */ 1862 pipe = 1; 1863 si->port_l2i_mapping[port] = 63; /* Local MMU Port */ 1864 si->port_p2m_mapping[phy_port] = 191; /* Global MMU Port */ 1865 si->port_serdes[port] = 32; 1866 SOC_PORT_BLOCK(unit, phy_port) = SOC_PORT_BLOCK(unit, 129); /* lane 2 */ 1867 SOC_PORT_BINDEX(unit, phy_port) = 2; 1868 SOC_PBMP_PORT_ADD(si->management_pbm, port); 1869 } else if (phy_port >= 130) { /* loopback port (130 and 131 in TD3) */ 1870 pipe = phy_port - 130; 1871 idb_port = 65; 1872 } else if (phy_port == 0) { 1873 pipe = 0; 1874 } else { 1875 idb_port = (phy_port - 1) % _TD3_PORTS_PER_PIPE; 1876 pipe = (phy_port - 1) / _TD3_PORTS_PER_PIPE; 1877 si->port_l2i_mapping[port] = idb_port; 1878 si->port_p2m_mapping[phy_port] = (pipe << 7) | idb_port; 1879 si->port_serdes[port] = (phy_port - 1) / _TD3_PORTS_PER_PBLK; 1880 } 1881 si->port_pipe[port] = pipe; 1882 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 1883 1884 if (oversub_mode) { 1885 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 1886 } 1887 1888 if (si->port_speed_max[port] >= 40000) { 1889 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 1890 } 1891 } 1892 1893 /* Setup pipe/xpe mapping 1894 * XPE_E / XPE_D (SC/SED): IP 0/1 EP 0/1 1895 */ 1896 pipe_map = 0; 1897 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1898 if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) { 1899 continue; 1900 } 1901 pipe_map |= 1 << pipe; 1902 } 1903 xpe_map = 0; 1904 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 1905 ipipe_map = 0x3 & pipe_map; 1906 epipe_map = 0x3 & pipe_map; 1907 if (ipipe_map == 0 || epipe_map == 0) { 1908 continue; 1909 } 1910 xpe_map |= 1 << xpe; 1911 si->xpe_ipipe_map[xpe] = ipipe_map; 1912 si->xpe_epipe_map[xpe] = epipe_map; 1913 } 1914 sc_map = 0; 1915 for (sc = 0; sc < NUM_SLICE(unit); sc++) { 1916 ipipe_map = pipe_map; 1917 epipe_map = 0x3 & pipe_map; 1918 if (ipipe_map == 0 || epipe_map == 0) { 1919 continue; 1920 } 1921 sc_map |= 1 << sc; 1922 si->sc_ipipe_map[sc] = ipipe_map; 1923 si->sc_epipe_map[sc] = epipe_map; 1924 } 1925 for (pipe = 0; pipe < SOC_MAX_NUM_PIPES; pipe++) { 1926 /* Number of pipes is 4 in Tomahawk */ 1927 /* coverity[overrun-local : FALSE] */ 1928 if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) { 1929 continue; 1930 } 1931 /* coverity[overrun-local : FALSE] */ 1932 si->ipipe_xpe_map[pipe] = 0x1 & xpe_map; 1933 /* coverity[overrun-local : FALSE] */ 1934 si->epipe_xpe_map[pipe] = 0x1 & xpe_map; 1935 /* coverity[overrun-local : FALSE] */ 1936 si->ipipe_sc_map[pipe] = 0x1 & sc_map; 1937 /* coverity[overrun-local : FALSE] */ 1938 si->epipe_sc_map[pipe] = 0x1 & sc_map; 1939 } 1940 1941 /* Setup clport refclk master block bitmap. 1942 * In TD3, there are 8 port macros (clport 6,7,24,25) that 1943 * will driven directly from the system board and they will act as the 1944 * refclk master to drive the other instances. 1945 */ 1946 SHR_BITCLR_RANGE(si->pm_ref_master_bitmap, 0, SOC_MAX_NUM_BLKS); 1947 for (blk_idx = 0; (blk_idx < SOC_MAX_NUM_BLKS) && (SOC_BLOCK_TYPE(unit, blk_idx)!= -1); blk_idx++) { 1948 int blknum = SOC_BLOCK_NUMBER(unit, blk_idx); 1949 int blktype = SOC_BLOCK_TYPE(unit, blk_idx); 1950 1951 /* CLPORTs 7,8,23,24 provide master clock for other ports */ 1952 if (blktype == SOC_BLK_CLPORT) { 1953 if ((blknum == 7 || blknum == 8 || blknum == 23 || blknum == 24)) { 1954 SHR_BITSET(si->pm_ref_master_bitmap, blk_idx); 1955 } 1956 } 1957 } 1958 1959 return rv; 1960 #else 1961 return SOC_E_UNAVAIL; 1962 #endif 1963 } 1964 1965 #if !defined(BCM_TD3_ASF_EXCLUDE) 1966 int 1967 soc_td3_port_oversub_ratio_get( 1968 int unit, 1969 soc_port_t port, 1970 OUT int* const ratio) 1971 { 1972 soc_info_t *si; 1973 _soc_trident3_tdm_temp_t *tdm; 1974 int pipe, hpipe, max_ovs_ratio; 1975 1976 if (!ratio) { 1977 return SOC_E_PARAM; 1978 } 1979 1980 if (SAL_BOOT_XGSSIM) { 1981 *ratio = 0; 1982 return SOC_E_NONE; 1983 } 1984 1985 si = &SOC_INFO(unit); 1986 tdm = SOC_CONTROL(unit)->tdm_info; 1987 1988 if (!si || !tdm) { 1989 return SOC_E_INTERNAL; 1990 } 1991 1992 max_ovs_ratio = 0; 1993 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1994 for (hpipe = 0; hpipe < TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 1995 if (max_ovs_ratio < tdm->ovs_ratio_x1000[pipe][hpipe]) { 1996 max_ovs_ratio = tdm->ovs_ratio_x1000[pipe][hpipe]; 1997 } 1998 } 1999 } 2000 *ratio = max_ovs_ratio; 2001 2002 return SOC_E_NONE; 2003 } 2004 #endif 2005 2006 uint32 soc_td3_temp_mon_mask[SOC_MAX_NUM_DEVICES]={0}; 2007 2008 /* 2009 * Function: 2010 * soc_td3_set_idb_dpp_ctrl 2011 * Purpose: 2012 * Configure IDB DPP credits 2013 * Parameters: 2014 * unit (IN) - switch unit 2015 * Returns: 2016 * SOC_E_* 2017 */ 2018 int 2019 soc_td3_set_idb_dpp_ctrl(int unit) 2020 { 2021 soc_reg_t reg; 2022 uint32 pipe_map, in_progress; 2023 int pipe; 2024 uint32 rval, rval0; 2025 int pipe_init_usec; 2026 soc_timeout_t to; 2027 static const soc_reg_t idb_dpp_ctrl[2] = { 2028 IDB_DPP_CTRL_PIPE0r, IDB_DPP_CTRL_PIPE1r 2029 }; 2030 2031 soc_trident3_pipe_map_get(unit, &pipe_map); 2032 2033 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2034 if (!(pipe_map & (1 << pipe))) { 2035 continue; 2036 } 2037 reg = idb_dpp_ctrl[pipe]; 2038 rval = 0; 2039 /*SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));*/ 2040 soc_reg_field_set(unit, reg, &rval, MAX_REF_CNTf, 4); 2041 soc_reg_field_set(unit, reg, &rval, MAX_SBUS_CNTf, 4); 2042 soc_reg_field_set(unit, reg, &rval, CREDITSf, 62); 2043 soc_reg_field_set(unit, reg, &rval, DONEf, 0); 2044 soc_reg_field_set(unit, reg, &rval, STARTf, 1); 2045 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 2046 } 2047 2048 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 2049 if (SAL_BOOT_SIMULATION) { 2050 pipe_init_usec = 10000000; 2051 } else { 2052 pipe_init_usec = 50000; 2053 } 2054 soc_timeout_init(&to, pipe_init_usec, 0); 2055 2056 /* Wait for DPP credit initialization done */ 2057 in_progress = pipe_map; 2058 do { 2059 for (pipe = 0; pipe < NUM_PIPE(unit) && in_progress; pipe++) { 2060 reg = SOC_REG_UNIQUE_ACC(unit, IDB_DPP_CTRLr)[pipe]; 2061 if (in_progress & (1 << pipe)) { /* not done yet */ 2062 SOC_IF_ERROR_RETURN 2063 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 2064 if (soc_reg_field_get(unit, reg, rval0, DONEf)) { 2065 in_progress ^= (1 << pipe); 2066 } 2067 } 2068 } 2069 if (soc_timeout_check(&to)) { 2070 LOG_WARN(BSL_LS_SOC_COMMON, 2071 (BSL_META_U(unit, 2072 "unit %d : IDB_DPP_CTRL timeout\n"), unit)); 2073 break; 2074 } 2075 } while (in_progress != 0); 2076 2077 return SOC_E_NONE; 2078 } 2079 2080 STATIC int 2081 _soc_trident3_idb_init(int unit) 2082 { 2083 soc_info_t *si; 2084 _soc_trident3_tdm_temp_t *tdm; 2085 soc_reg_t reg; 2086 soc_field_t field; 2087 int block_info_idx, pipe, clport, obm, lane; 2088 int port, phy_port_base, lport; 2089 int lossless, i, count; 2090 uint32 rval0, rval1, fval; 2091 uint32 rval_port_cfg = 0, rval_max_usage_cfg = 0; 2092 uint64 rval64; 2093 int num_lanes, oversub_ratio_idx; 2094 uint32 entry[SOC_MAX_MEM_WORDS]; 2095 soc_mem_t mem; 2096 2097 static const struct _obm_setting_s { 2098 int discard_limit; 2099 int lossless_xoff; 2100 int lossy_only_lossy_low_pri; 2101 int port_xoff[3]; /* for oversub ratio 1.5, 1.8, and above */ 2102 int lossy_low_pri[3]; /* for oversub ratio 1.5, 1.8, and above */ 2103 int lossy_discard[3]; /* for oversub ratio 1.5, 1.8, and above */ 2104 int buffer_start[4]; 2105 int buffer_end[4]; 2106 } obm_settings[] = { /* indexed by number of lanes */ 2107 { /* 0 - invalid */ 0 }, 2108 { /* 1 lane */ 2109 1148, 136, 806, 2110 { 428, 428, 428 }, /* port_xoff */ 2111 { 235, 235, 235 }, /* lossy_low_pri */ 2112 { 573, 573, 573 }, /* lossy_discard */ 2113 { 0, 1152, 2304, 3456}, /* buffer_start */ 2114 { 1151, 2303, 3455, 4607} /* buffer_end */ 2115 }, 2116 { /* 2 lanes */ 2117 2300, 324, 1958, 2118 { 1310, 1310, 1310 }, /* port_xoff */ 2119 { 235, 235, 235 }, /* lossy_low_pri */ 2120 { 573, 573, 573 }, /* lossy_discard */ 2121 { 0, 0, 2304, 0 }, /* buffer_start */ 2122 { 2303, 4607, 4607, 4607} /* buffer_end */ 2123 }, 2124 { /* 3 - invalid */ 0 }, 2125 { /* 4 lanes */ 2126 4604, 774, 4262, 2127 { 2989, 2989, 2989 }, /* port_xoff */ 2128 { 235, 235, 235 }, /* lossy_low_pri */ 2129 { 573, 573, 573 }, /* lossy_discard */ 2130 { 0, 0, 0, 0 }, /* buffer_start */ 2131 { 4607, 4607, 4607, 4607} /* buffer_end */ 2132 } 2133 }; 2134 2135 static const soc_reg_t obm_ctrl_regs[] = { 2136 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 2137 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 2138 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 2139 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, 2140 IDB_OBM8_CONTROLr, IDB_OBM9_CONTROLr, 2141 IDB_OBM10_CONTROLr, IDB_OBM11_CONTROLr, 2142 IDB_OBM12_CONTROLr, IDB_OBM13_CONTROLr, 2143 IDB_OBM14_CONTROLr, IDB_OBM15_CONTROLr 2144 }; 2145 static const soc_reg_t obm_ca_ctrl_regs[] = { 2146 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, 2147 IDB_OBM2_CA_CONTROLr, IDB_OBM3_CA_CONTROLr, 2148 IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 2149 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 2150 IDB_OBM8_CA_CONTROLr, IDB_OBM9_CA_CONTROLr, 2151 IDB_OBM10_CA_CONTROLr, IDB_OBM11_CA_CONTROLr, 2152 IDB_OBM12_CA_CONTROLr, IDB_OBM13_CA_CONTROLr, 2153 IDB_OBM14_CA_CONTROLr, IDB_OBM15_CA_CONTROLr 2154 }; 2155 static const soc_reg_t obm_thresh_regs[] = { 2156 IDB_OBM0_THRESHOLDr, IDB_OBM1_THRESHOLDr, 2157 IDB_OBM2_THRESHOLDr, IDB_OBM3_THRESHOLDr, 2158 IDB_OBM4_THRESHOLDr, IDB_OBM5_THRESHOLDr, 2159 IDB_OBM6_THRESHOLDr, IDB_OBM7_THRESHOLDr, 2160 IDB_OBM8_THRESHOLDr, IDB_OBM9_THRESHOLDr, 2161 IDB_OBM10_THRESHOLDr, IDB_OBM11_THRESHOLDr, 2162 IDB_OBM12_THRESHOLDr, IDB_OBM13_THRESHOLDr, 2163 IDB_OBM14_THRESHOLDr, IDB_OBM15_THRESHOLDr 2164 }; 2165 static const soc_reg_t obm_thresh_1_regs[] = { 2166 IDB_OBM0_THRESHOLD_1r, IDB_OBM1_THRESHOLD_1r, 2167 IDB_OBM2_THRESHOLD_1r, IDB_OBM3_THRESHOLD_1r, 2168 IDB_OBM4_THRESHOLD_1r, IDB_OBM5_THRESHOLD_1r, 2169 IDB_OBM6_THRESHOLD_1r, IDB_OBM7_THRESHOLD_1r, 2170 IDB_OBM8_THRESHOLD_1r, IDB_OBM9_THRESHOLD_1r, 2171 IDB_OBM10_THRESHOLD_1r, IDB_OBM11_THRESHOLD_1r, 2172 IDB_OBM12_THRESHOLD_1r, IDB_OBM13_THRESHOLD_1r, 2173 IDB_OBM14_THRESHOLD_1r, IDB_OBM15_THRESHOLD_1r 2174 }; 2175 static const soc_reg_t obm_fc_thresh_regs[] = { 2176 IDB_OBM0_FC_THRESHOLDr, IDB_OBM1_FC_THRESHOLDr, 2177 IDB_OBM2_FC_THRESHOLDr, IDB_OBM3_FC_THRESHOLDr, 2178 IDB_OBM4_FC_THRESHOLDr, IDB_OBM5_FC_THRESHOLDr, 2179 IDB_OBM6_FC_THRESHOLDr, IDB_OBM7_FC_THRESHOLDr, 2180 IDB_OBM8_FC_THRESHOLDr, IDB_OBM9_FC_THRESHOLDr, 2181 IDB_OBM10_FC_THRESHOLDr, IDB_OBM11_FC_THRESHOLDr, 2182 IDB_OBM12_FC_THRESHOLDr, IDB_OBM13_FC_THRESHOLDr, 2183 IDB_OBM14_FC_THRESHOLDr, IDB_OBM15_FC_THRESHOLDr 2184 }; 2185 static const soc_reg_t obm_fc_thresh_1_regs[] = { 2186 IDB_OBM0_FC_THRESHOLD_1r, IDB_OBM1_FC_THRESHOLD_1r, 2187 IDB_OBM2_FC_THRESHOLD_1r, IDB_OBM3_FC_THRESHOLD_1r, 2188 IDB_OBM4_FC_THRESHOLD_1r, IDB_OBM5_FC_THRESHOLD_1r, 2189 IDB_OBM6_FC_THRESHOLD_1r, IDB_OBM7_FC_THRESHOLD_1r, 2190 IDB_OBM8_FC_THRESHOLD_1r, IDB_OBM9_FC_THRESHOLD_1r, 2191 IDB_OBM10_FC_THRESHOLD_1r, IDB_OBM11_FC_THRESHOLD_1r, 2192 IDB_OBM12_FC_THRESHOLD_1r, IDB_OBM13_FC_THRESHOLD_1r, 2193 IDB_OBM14_FC_THRESHOLD_1r, IDB_OBM15_FC_THRESHOLD_1r 2194 }; 2195 static const soc_reg_t obm_shared_regs[] = { 2196 IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr, 2197 IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr, 2198 IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr, 2199 IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr, 2200 IDB_OBM8_SHARED_CONFIGr, IDB_OBM9_SHARED_CONFIGr, 2201 IDB_OBM10_SHARED_CONFIGr, IDB_OBM11_SHARED_CONFIGr, 2202 IDB_OBM12_SHARED_CONFIGr, IDB_OBM13_SHARED_CONFIGr, 2203 IDB_OBM14_SHARED_CONFIGr, IDB_OBM15_SHARED_CONFIGr 2204 }; 2205 static const soc_reg_t obm_max_usage_regs[] = { 2206 IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr, 2207 IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr, 2208 IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr, 2209 IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr, 2210 IDB_OBM8_MAX_USAGE_SELECTr, IDB_OBM9_MAX_USAGE_SELECTr, 2211 IDB_OBM10_MAX_USAGE_SELECTr, IDB_OBM11_MAX_USAGE_SELECTr, 2212 IDB_OBM12_MAX_USAGE_SELECTr, IDB_OBM13_MAX_USAGE_SELECTr, 2213 IDB_OBM14_MAX_USAGE_SELECTr, IDB_OBM15_MAX_USAGE_SELECTr 2214 }; 2215 static const soc_field_t obm_bypass_fields[] = { 2216 PORT0_BYPASS_ENABLEf, PORT1_BYPASS_ENABLEf, 2217 PORT2_BYPASS_ENABLEf, PORT3_BYPASS_ENABLEf 2218 }; 2219 static const soc_field_t obm_oversub_fields[] = { 2220 PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf, 2221 PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf 2222 }; 2223 static const soc_field_t obm_ca_sop_fields[] = { 2224 PORT0_CA_SOPf, PORT1_CA_SOPf, PORT2_CA_SOPf, PORT3_CA_SOPf 2225 }; 2226 static const soc_reg_t obm_port_config_regs[] = { 2227 IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr, 2228 IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr, 2229 IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr, 2230 IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr, 2231 IDB_OBM8_PORT_CONFIGr, IDB_OBM9_PORT_CONFIGr, 2232 IDB_OBM10_PORT_CONFIGr, IDB_OBM11_PORT_CONFIGr, 2233 IDB_OBM12_PORT_CONFIGr, IDB_OBM13_PORT_CONFIGr, 2234 IDB_OBM14_PORT_CONFIGr, IDB_OBM15_PORT_CONFIGr 2235 }; 2236 static const soc_reg_t obm_fc_config_regs[] = { 2237 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 2238 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 2239 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 2240 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr, 2241 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr, 2242 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr, 2243 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr, 2244 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr 2245 }; 2246 static const soc_reg_t obm_buffer_config_regs[] = { 2247 IDB_OBM0_BUFFER_CONFIGr, IDB_OBM1_BUFFER_CONFIGr, 2248 IDB_OBM2_BUFFER_CONFIGr, IDB_OBM3_BUFFER_CONFIGr, 2249 IDB_OBM4_BUFFER_CONFIGr, IDB_OBM5_BUFFER_CONFIGr, 2250 IDB_OBM6_BUFFER_CONFIGr, IDB_OBM7_BUFFER_CONFIGr, 2251 IDB_OBM8_BUFFER_CONFIGr, IDB_OBM9_BUFFER_CONFIGr, 2252 IDB_OBM10_BUFFER_CONFIGr, IDB_OBM11_BUFFER_CONFIGr, 2253 IDB_OBM12_BUFFER_CONFIGr, IDB_OBM13_BUFFER_CONFIGr, 2254 IDB_OBM14_BUFFER_CONFIGr, IDB_OBM15_BUFFER_CONFIGr 2255 }; 2256 static const soc_mem_t obm_pri_map_mem[][4] = { 2257 {IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m, 2258 IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m 2259 }, 2260 {IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m, 2261 IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m 2262 }, 2263 {IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m, 2264 IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m 2265 }, 2266 {IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m, 2267 IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m 2268 }, 2269 {IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m, 2270 IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m 2271 }, 2272 {IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m, 2273 IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m 2274 }, 2275 {IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m, 2276 IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m 2277 }, 2278 {IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m, 2279 IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m 2280 }, 2281 {IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m, 2282 IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m 2283 }, 2284 {IDB_OBM9_PRI_MAP_PORT0m, IDB_OBM9_PRI_MAP_PORT1m, 2285 IDB_OBM9_PRI_MAP_PORT2m, IDB_OBM9_PRI_MAP_PORT3m 2286 }, 2287 {IDB_OBM10_PRI_MAP_PORT0m, IDB_OBM10_PRI_MAP_PORT1m, 2288 IDB_OBM10_PRI_MAP_PORT2m, IDB_OBM10_PRI_MAP_PORT3m 2289 }, 2290 {IDB_OBM11_PRI_MAP_PORT0m, IDB_OBM11_PRI_MAP_PORT1m, 2291 IDB_OBM11_PRI_MAP_PORT2m, IDB_OBM11_PRI_MAP_PORT3m 2292 }, 2293 {IDB_OBM12_PRI_MAP_PORT0m, IDB_OBM12_PRI_MAP_PORT1m, 2294 IDB_OBM12_PRI_MAP_PORT2m, IDB_OBM12_PRI_MAP_PORT3m 2295 }, 2296 {IDB_OBM13_PRI_MAP_PORT0m, IDB_OBM13_PRI_MAP_PORT1m, 2297 IDB_OBM13_PRI_MAP_PORT2m, IDB_OBM13_PRI_MAP_PORT3m 2298 }, 2299 {IDB_OBM14_PRI_MAP_PORT0m, IDB_OBM14_PRI_MAP_PORT1m, 2300 IDB_OBM14_PRI_MAP_PORT2m, IDB_OBM14_PRI_MAP_PORT3m 2301 }, 2302 {IDB_OBM15_PRI_MAP_PORT0m, IDB_OBM15_PRI_MAP_PORT1m, 2303 IDB_OBM15_PRI_MAP_PORT2m, IDB_OBM15_PRI_MAP_PORT3m 2304 }, 2305 }; 2306 2307 static const soc_field_t obm_ob_pri_fields[] = { 2308 OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf, 2309 OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf, 2310 OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf, 2311 OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf, 2312 OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf, 2313 OFFSET15_OB_PRIORITYf 2314 }; 2315 static const int hw_mode_values[SOC_TD3_PORT_RATIO_COUNT] = { 2316 0, 1, 1, 1, 3, 5, 4, 6, 2 2317 }; 2318 2319 si = &SOC_INFO(unit); 2320 tdm = SOC_CONTROL(unit)->tdm_info; 2321 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 2322 2323 rval_port_cfg = 0; 2324 reg = SOC_REG_UNIQUE_ACC(unit, obm_port_config_regs[0])[0]; 2325 soc_reg_field_set(unit, reg, &rval_port_cfg, PORT_PRIf, 2); 2326 2327 rval_max_usage_cfg = 0; 2328 reg = SOC_REG_UNIQUE_ACC(unit, obm_max_usage_regs[0])[0]; 2329 soc_reg_field_set(unit, reg, &rval_max_usage_cfg, PRIORITY_SELECTf, 2); 2330 2331 sal_memset(entry, 0, sizeof(idb_obm0_pri_map_port0_entry_t)); 2332 mem = SOC_MEM_UNIQUE_ACC(unit, obm_pri_map_mem[0][0])[0]; 2333 2334 count = COUNTOF(obm_ob_pri_fields); 2335 for (i = 0; i < count; i++) { 2336 soc_mem_field32_set(unit, mem, entry, obm_ob_pri_fields[i], 2); 2337 } 2338 2339 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 2340 port = SOC_BLOCK_PORT(unit, block_info_idx); 2341 phy_port_base = PORT_BLOCK_BASE_PORT(port); 2342 pipe = si->port_pipe[port]; 2343 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 2344 obm = clport & 0xF; 2345 2346 /* Set cell assembly mode then toggle reset to send initial credit 2347 * to EP */ 2348 reg = SOC_REG_UNIQUE_ACC(unit, obm_ca_ctrl_regs[obm])[pipe]; 2349 rval0 = 0; 2350 soc_reg_field_set(unit, reg, &rval0, PORT_MODEf, 2351 hw_mode_values[tdm->port_ratio[clport]]); 2352 2353 rval1 = rval0; 2354 /* PORT_RESETf is a 4 bit field, set to all one's in the next step */ 2355 soc_reg_field_set(unit, reg, &rval0, PORT0_RESETf, 1); 2356 soc_reg_field_set(unit, reg, &rval0, PORT1_RESETf, 1); 2357 soc_reg_field_set(unit, reg, &rval0, PORT2_RESETf, 1); 2358 soc_reg_field_set(unit, reg, &rval0, PORT3_RESETf, 1); 2359 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2360 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval1)); 2361 2362 if (!SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 2363 continue; 2364 } 2365 2366 /* Enable oversub */ 2367 reg = SOC_REG_UNIQUE_ACC(unit, obm_ctrl_regs[obm])[pipe]; 2368 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 2369 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane++) { 2370 if (si->port_p2l_mapping[phy_port_base + lane] == -1) { 2371 continue; 2372 } 2373 field = obm_bypass_fields[lane]; 2374 soc_reg_field_set(unit, reg, &rval0, field, 1); 2375 field = obm_oversub_fields[lane]; 2376 soc_reg_field_set(unit, reg, &rval0, field, 1); 2377 lport = si->port_p2l_mapping[phy_port_base + lane]; 2378 /* Update CA_SOP settings */ 2379 if (si->port_speed_max[lport] < 100000) { 2380 field = obm_ca_sop_fields[lane]; 2381 soc_reg_field_set(unit, reg, &rval0, field, 0); 2382 } 2383 } 2384 2385 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2386 if (!SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 2387 continue; 2388 } 2389 2390 /* Configure buffer */ 2391 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane++) { 2392 port = si->port_p2l_mapping[phy_port_base + lane]; 2393 if (port == -1) { 2394 continue; 2395 } 2396 num_lanes = si->port_num_lanes[port]; 2397 reg = SOC_REG_UNIQUE_ACC(unit, obm_buffer_config_regs[obm])[pipe]; 2398 SOC_IF_ERROR_RETURN 2399 (soc_reg32_get(unit, reg, REG_PORT_ANY, lane, &rval0)); 2400 fval = obm_settings[num_lanes].buffer_start[lane]; 2401 soc_reg_field_set(unit, reg, &rval0, BUFFER_STARTf, fval); 2402 fval = obm_settings[num_lanes].buffer_end[lane]; 2403 soc_reg_field_set(unit, reg, &rval0, BUFFER_ENDf, fval); 2404 SOC_IF_ERROR_RETURN 2405 (soc_reg32_set(unit, reg, REG_PORT_ANY, lane, rval0)); 2406 } 2407 2408 /* Configure shared config */ 2409 reg = SOC_REG_UNIQUE_ACC(unit, obm_shared_regs[obm])[pipe]; 2410 SOC_IF_ERROR_RETURN 2411 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 2412 soc_reg64_field32_set(unit, reg, &rval64, SOP_DISCARD_MODEf, 1); 2413 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 2414 2415 if (lossless) { 2416 if ((tdm->ovs_ratio_x1000[pipe][0] + tdm->ovs_ratio_x1000[pipe][1]) >= 1800) { /* ratio >= 1.8 */ 2417 oversub_ratio_idx = 2; 2418 } else if ((tdm->ovs_ratio_x1000[pipe][0] + tdm->ovs_ratio_x1000[pipe][1]) >= 1500) { /* ratio >= 1.5 */ 2419 oversub_ratio_idx = 1; 2420 } else { 2421 oversub_ratio_idx = 0; 2422 } 2423 2424 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane++) { 2425 port = si->port_p2l_mapping[phy_port_base + lane]; 2426 if (port == -1) { 2427 continue; 2428 } 2429 num_lanes = si->port_num_lanes[port]; 2430 2431 /* Configure threshold */ 2432 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_regs[obm])[pipe]; 2433 SOC_IF_ERROR_RETURN 2434 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2435 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 2436 4604); 2437 fval = obm_settings[num_lanes].lossy_low_pri[oversub_ratio_idx]; 2438 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, fval); 2439 fval = obm_settings[num_lanes].lossy_discard[oversub_ratio_idx]; 2440 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, fval); 2441 SOC_IF_ERROR_RETURN 2442 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2443 2444 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_1_regs[obm])[pipe]; 2445 SOC_IF_ERROR_RETURN 2446 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2447 fval = obm_settings[num_lanes].discard_limit; 2448 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, fval); 2449 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 2450 4604); 2451 SOC_IF_ERROR_RETURN 2452 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2453 2454 /* Configure flow control threshold */ 2455 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_regs[obm])[pipe]; 2456 SOC_IF_ERROR_RETURN 2457 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2458 fval = obm_settings[num_lanes].lossless_xoff; 2459 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, 2460 fval); 2461 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, 2462 fval - 30); 2463 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, fval); 2464 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 2465 fval - 30); 2466 SOC_IF_ERROR_RETURN 2467 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2468 2469 /* Configure flow control threshold_1 */ 2470 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_1_regs[obm])[pipe]; 2471 SOC_IF_ERROR_RETURN 2472 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2473 fval = obm_settings[num_lanes].port_xoff[oversub_ratio_idx]; 2474 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, fval); 2475 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, fval - 30); 2476 SOC_IF_ERROR_RETURN 2477 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2478 2479 /* Configure flow control config */ 2480 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 2481 SOC_IF_ERROR_RETURN 2482 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2483 soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, 1); 2484 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, 1); 2485 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, 0); 2486 soc_reg64_field32_set(unit, reg, &rval64, 2487 LOSSLESS0_PRIORITY_PROFILEf, 0xffff); 2488 soc_reg64_field32_set(unit, reg, &rval64, 2489 LOSSLESS1_PRIORITY_PROFILEf, 0); 2490 soc_reg64_field32_set(unit, reg, &rval64, 2491 XOFF_REFRESH_TIMERf, 0x100); 2492 SOC_IF_ERROR_RETURN 2493 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2494 2495 /* OBM Port config */ 2496 reg = SOC_REG_UNIQUE_ACC(unit, obm_port_config_regs[obm])[pipe]; 2497 SOC_IF_ERROR_RETURN 2498 (soc_reg32_set(unit, reg, REG_PORT_ANY, lane, 2499 rval_port_cfg)); 2500 mem = SOC_MEM_UNIQUE_ACC 2501 (unit, obm_pri_map_mem[obm][lane])[pipe]; 2502 SOC_IF_ERROR_RETURN 2503 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry)); 2504 } 2505 reg = SOC_REG_UNIQUE_ACC(unit, obm_max_usage_regs[obm])[pipe]; 2506 SOC_IF_ERROR_RETURN 2507 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval_max_usage_cfg)); 2508 } else { /* lossy */ 2509 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane++) { 2510 port = si->port_p2l_mapping[phy_port_base + lane]; 2511 if (port == -1) { 2512 continue; 2513 } 2514 num_lanes = si->port_num_lanes[port]; 2515 2516 /* Configure threshold */ 2517 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_regs[obm])[pipe]; 2518 SOC_IF_ERROR_RETURN 2519 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2520 fval = obm_settings[num_lanes].discard_limit; 2521 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, 2522 fval - 4); 2523 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 2524 4604); 2525 fval = obm_settings[num_lanes].lossy_only_lossy_low_pri; 2526 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, fval); 2527 SOC_IF_ERROR_RETURN 2528 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2529 2530 /* Configure threshold_1 */ 2531 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_1_regs[obm])[pipe]; 2532 SOC_IF_ERROR_RETURN 2533 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2534 fval = obm_settings[num_lanes].discard_limit; 2535 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, fval); 2536 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 2537 4604); 2538 SOC_IF_ERROR_RETURN 2539 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2540 2541 /* Configure flow control threshold */ 2542 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_1_regs[obm])[pipe]; 2543 SOC_IF_ERROR_RETURN 2544 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2545 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, 4604); 2546 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, 4604); 2547 SOC_IF_ERROR_RETURN 2548 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2549 2550 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_regs[obm])[pipe]; 2551 SOC_IF_ERROR_RETURN 2552 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2553 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, 2554 4604); 2555 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, 4604); 2556 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 4604); 2557 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 2558 4604); 2559 SOC_IF_ERROR_RETURN 2560 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2561 2562 /* Configure flow control config */ 2563 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 2564 SOC_IF_ERROR_RETURN 2565 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 2566 soc_reg64_field32_set(unit, reg, &rval64, 2567 XOFF_REFRESH_TIMERf, 0x100); 2568 SOC_IF_ERROR_RETURN 2569 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 2570 } 2571 } 2572 } 2573 2574 /* Toggle cpu port cell assembly reset to send initial credit to EP */ 2575 reg = IDB_CA_CPU_CONTROLr; 2576 rval0 = 0; 2577 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 2578 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2579 sal_msleep(5); 2580 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 2581 2582 /* Toggle loopback cell assembly reset to send initial credit to EP */ 2583 reg = IDB_CA_LPBK_CONTROLr; 2584 rval0 = 0; 2585 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 2586 PBMP_LB_ITER(unit, port) { 2587 reg = SOC_REG_UNIQUE_ACC(unit, IDB_CA_LPBK_CONTROLr) 2588 [si->port_pipe[port]] ; 2589 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2590 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 2591 } 2592 2593 soc_td3_set_idb_dpp_ctrl(unit); 2594 2595 return SOC_E_NONE; 2596 } 2597 #ifdef BCM_WARM_BOOT_SUPPORT 2598 2599 #define SOC_TDM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 2600 #define SOC_TDM_WB_DEFAULT_VERSION SOC_TDM_WB_VERSION_1_0 2601 2602 int soc_td3_tdm_scache_allocate(int unit) 2603 { 2604 int rv = SOC_E_NONE; 2605 uint8 *tdm_scache_ptr; 2606 soc_scache_handle_t scache_handle; 2607 uint32 alloc_get = 0; 2608 uint32 alloc_size = 0; 2609 int stable_size; 2610 int default_ver = SOC_TDM_WB_DEFAULT_VERSION; 2611 int ilen, ovs_size, pkt_shp_size, hpipes; 2612 2613 ilen = sizeof(int); 2614 ovs_size = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE * 2615 TRIDENT3_OVS_GROUP_COUNT_PER_HPIPE * 2616 TRIDENT3_OVS_GROUP_TDM_LENGTH; 2617 pkt_shp_size = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE * 2618 TRIDENT3_PKT_SCH_LENGTH; 2619 hpipes = TRIDENT3_PIPES_PER_DEV * TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; 2620 2621 alloc_size = (ilen * TRIDENT3_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 2622 (ilen * TRIDENT3_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 2623 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 2624 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 2625 (ilen * TRIDENT3_TDM_LENGTH) + /* IDB TDM info on pipe1 */ 2626 (ilen * TRIDENT3_TDM_LENGTH) + /* MMU TDM info on pipe1 */ 2627 (ilen * ovs_size) + /* Oversub group info on pipe1 */ 2628 (ilen * pkt_shp_size) + /* pkt shaper info on pipe1 */ 2629 (ilen * TRIDENT3_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 2630 (ilen * TRIDENT3_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 2631 (ilen * TRIDENT3_PBLKS_PER_DEV) + /* port ratio */ 2632 (ilen * hpipes); /* oversub ratio */ 2633 alloc_get = alloc_size; 2634 2635 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 2636 /* check to see if an scache table has been configured */ 2637 rv = soc_stable_size_get(unit, &stable_size); 2638 if (SOC_FAILURE(rv) || stable_size <= 0) { 2639 return rv; 2640 } 2641 2642 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 2643 TRUE, &alloc_get, 2644 &tdm_scache_ptr, 2645 default_ver, 2646 NULL); 2647 2648 if (rv == SOC_E_CONFIG) { 2649 /* Probably Level1 */ 2650 return SOC_E_NONE; 2651 } 2652 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 2653 if (alloc_get != alloc_size) { 2654 /* Expected size doesn't match retrieved size */ 2655 LOG_ERROR(BSL_LS_SOC_COMMON, 2656 (BSL_META_U(unit, 2657 "ERROR: scache memory for tdm size mismatch" 2658 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 2659 return SOC_E_INTERNAL; 2660 } 2661 2662 if (NULL == tdm_scache_ptr) { 2663 LOG_ERROR(BSL_LS_SOC_COMMON, 2664 (BSL_META_U(unit, 2665 "ERROR: scache memory not allocated for tdm" 2666 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 2667 return SOC_E_MEMORY; 2668 } 2669 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2670 (BSL_META_U(unit, 2671 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 2672 return SOC_E_NONE; 2673 } 2674 2675 2676 /* 2677 * Function: 2678 * soc_td3_tdm_scache_sync 2679 * Purpose: 2680 * Record TDM info that maybe changed during flexport for Level 2 WB 2681 * 2682 * Warm Boot Version Map: 2683 * 2684 * BCM_WB_VERSION_1_0 2685 * IDB TDM info on pipe0 2686 * MMU TDM info on pipe0 2687 * Oversub group info on pipe0 2688 * pkt shaper info on pipe0 2689 * IDB TDM info on pipe1 2690 * MMU TDM info on pipe1 2691 * Oversub group info on pipe1 2692 * pkt shaper info on pipe1 2693 * pblk id of phy-port 2694 * port ratio 2695 * oversub ratio 2696 * 2697 * Parameters: 2698 * unit - StrataSwitch unit number. 2699 * Returns: 2700 * SOC_E_XXX 2701 */ 2702 int soc_td3_tdm_scache_sync(int unit) 2703 { 2704 uint8 *tdm_scache_ptr; 2705 soc_scache_handle_t scache_handle; 2706 uint32 alloc_get = 0; 2707 uint32 alloc_size = 0; 2708 uint32 var_size = 0; 2709 uint32 scache_offset=0; 2710 int rv = 0; 2711 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 2712 _soc_trident3_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info; 2713 2714 ilen = sizeof(int); 2715 ovs_size = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE * 2716 TRIDENT3_OVS_GROUP_COUNT_PER_HPIPE * 2717 TRIDENT3_OVS_GROUP_TDM_LENGTH; 2718 pkt_shp_size = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE * 2719 TRIDENT3_PKT_SCH_LENGTH; 2720 hpipes = TRIDENT3_PIPES_PER_DEV * TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; 2721 2722 alloc_size = (ilen * TRIDENT3_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 2723 (ilen * TRIDENT3_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 2724 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 2725 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 2726 (ilen * TRIDENT3_TDM_LENGTH) + /* IDB TDM info on pipe1 */ 2727 (ilen * TRIDENT3_TDM_LENGTH) + /* MMU TDM info on pipe1 */ 2728 (ilen * ovs_size) + /* Oversub group info on pipe1 */ 2729 (ilen * pkt_shp_size) + /* pkt shaper info on pipe1 */ 2730 (ilen * TRIDENT3_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 2731 (ilen * TRIDENT3_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 2732 (ilen * TRIDENT3_PBLKS_PER_DEV) + /* port ratio */ 2733 (ilen * hpipes); /* oversub ratio */ 2734 alloc_get = alloc_size; 2735 2736 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 2737 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 2738 FALSE, &alloc_get, 2739 &tdm_scache_ptr, 2740 SOC_TDM_WB_DEFAULT_VERSION, 2741 NULL); 2742 if (rv == SOC_E_NOT_FOUND) { 2743 /* Probably Level1 */ 2744 return SOC_E_NONE; 2745 } 2746 if (alloc_get != alloc_size) { 2747 /* Expected size doesn't match retrieved size */ 2748 LOG_ERROR(BSL_LS_SOC_COMMON, 2749 (BSL_META_U(unit, 2750 "ERROR: scache memory for tdm size mismatch" 2751 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 2752 return SOC_E_INTERNAL; 2753 } 2754 if (NULL == tdm_scache_ptr) { 2755 LOG_ERROR(BSL_LS_SOC_COMMON, 2756 (BSL_META_U(unit, 2757 "ERROR: scache memory not allocated for tdm" 2758 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 2759 return SOC_E_MEMORY; 2760 } 2761 2762 /* IDB TDM info on pipe0 */ 2763 var_size = ilen * TRIDENT3_TDM_LENGTH; 2764 sal_memcpy(&tdm_scache_ptr[scache_offset], 2765 tdm->tdm_pipe[0].idb_tdm, 2766 var_size); 2767 scache_offset += var_size; 2768 2769 /* MMU TDM info on pipe0 */ 2770 var_size = ilen * TRIDENT3_TDM_LENGTH; 2771 sal_memcpy(&tdm_scache_ptr[scache_offset], 2772 tdm->tdm_pipe[0].mmu_tdm, 2773 var_size); 2774 scache_offset += var_size; 2775 2776 /* Oversub group info on pipe0 */ 2777 var_size = ilen * ovs_size; 2778 sal_memcpy(&tdm_scache_ptr[scache_offset], 2779 tdm->tdm_pipe[0].ovs_tdm, 2780 var_size); 2781 scache_offset += var_size; 2782 2783 /* pkt shaper info on pipe0 */ 2784 var_size = ilen * pkt_shp_size; 2785 sal_memcpy(&tdm_scache_ptr[scache_offset], 2786 tdm->tdm_pipe[0].pkt_shaper_tdm, 2787 var_size); 2788 scache_offset += var_size; 2789 2790 /* IDB TDM info on pipe1 */ 2791 var_size = ilen * TRIDENT3_TDM_LENGTH; 2792 sal_memcpy(&tdm_scache_ptr[scache_offset], 2793 tdm->tdm_pipe[1].idb_tdm, 2794 var_size); 2795 scache_offset += var_size; 2796 2797 /* MMU TDM info on pipe1 */ 2798 var_size = ilen * TRIDENT3_TDM_LENGTH; 2799 sal_memcpy(&tdm_scache_ptr[scache_offset], 2800 tdm->tdm_pipe[1].mmu_tdm, 2801 var_size); 2802 scache_offset += var_size; 2803 2804 /* Oversub group info on pipe1 */ 2805 var_size = ilen * ovs_size; 2806 sal_memcpy(&tdm_scache_ptr[scache_offset], 2807 tdm->tdm_pipe[1].ovs_tdm, 2808 var_size); 2809 scache_offset += var_size; 2810 2811 /* pkt shaper info on pipe1 */ 2812 var_size = ilen * pkt_shp_size; 2813 sal_memcpy(&tdm_scache_ptr[scache_offset], 2814 tdm->tdm_pipe[1].pkt_shaper_tdm, 2815 var_size); 2816 scache_offset += var_size; 2817 2818 /* hpipe id of phy-port */ 2819 for (phy_port = 0; phy_port < TRIDENT3_PHY_PORTS_PER_DEV; phy_port++) { 2820 var_size = ilen; 2821 sal_memcpy(&tdm_scache_ptr[scache_offset], 2822 &tdm->pblk_info[phy_port].pblk_hpipe_num, 2823 var_size); 2824 scache_offset += var_size; 2825 } 2826 2827 /* pblk id of phy-port */ 2828 for (phy_port = 0; phy_port < TRIDENT3_PHY_PORTS_PER_DEV; phy_port++) { 2829 var_size = ilen; 2830 sal_memcpy(&tdm_scache_ptr[scache_offset], 2831 &tdm->pblk_info[phy_port].pblk_cal_idx, 2832 var_size); 2833 scache_offset += var_size; 2834 } 2835 2836 /* port ratio */ 2837 var_size = ilen * TRIDENT3_PBLKS_PER_DEV; 2838 sal_memcpy(&tdm_scache_ptr[scache_offset], 2839 tdm->port_ratio, 2840 var_size); 2841 scache_offset += var_size; 2842 2843 /* oversub ratio */ 2844 var_size = ilen * hpipes; 2845 sal_memcpy(&tdm_scache_ptr[scache_offset], 2846 tdm->ovs_ratio_x1000, 2847 var_size); 2848 scache_offset += var_size; 2849 2850 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2851 (BSL_META_U(unit, 2852 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 2853 2854 return SOC_E_NONE; 2855 } 2856 2857 /* 2858 * Function: 2859 * soc_td3_tdm_scache_recovery 2860 * Purpose: 2861 * Recover TDM info that maybe changed during flexport for Level 2 WB 2862 * 2863 * Warm Boot Version Map: 2864 * 2865 * BCM_WB_VERSION_1_0 2866 * IDB TDM info on pipe0 2867 * MMU TDM info on pipe0 2868 * Oversub group info on pipe0 2869 * pkt shaper info on pipe0 2870 * IDB TDM info on pipe1 2871 * MMU TDM info on pipe1 2872 * Oversub group info on pipe1 2873 * pkt shaper info on pipe1 2874 * hpipe id of phy-port 2875 * pblk id of phy-port 2876 * port ratio 2877 * oversub ratio 2878 * 2879 * Parameters: 2880 * unit - StrataSwitch unit number. 2881 * Returns: 2882 * SOC_E_XXX 2883 */ 2884 int soc_td3_tdm_scache_recovery(int unit) 2885 { 2886 uint32 alloc_get = 0; 2887 uint32 alloc_size = 0; 2888 int rv = SOC_E_NONE; 2889 uint8 *tdm_scache_ptr = NULL; 2890 soc_scache_handle_t scache_handle; 2891 uint32 scache_offset=0; 2892 uint32 var_size = 0; 2893 uint16 recovered_ver = 0; 2894 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 2895 _soc_trident3_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info; 2896 2897 ilen = sizeof(int); 2898 ovs_size = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE * 2899 TRIDENT3_OVS_GROUP_COUNT_PER_HPIPE * 2900 TRIDENT3_OVS_GROUP_TDM_LENGTH; 2901 pkt_shp_size = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE * 2902 TRIDENT3_PKT_SCH_LENGTH; 2903 hpipes = TRIDENT3_PIPES_PER_DEV * TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; 2904 2905 alloc_size = (ilen * TRIDENT3_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 2906 (ilen * TRIDENT3_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 2907 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 2908 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 2909 (ilen * TRIDENT3_TDM_LENGTH) + /* IDB TDM info on pipe1 */ 2910 (ilen * TRIDENT3_TDM_LENGTH) + /* MMU TDM info on pipe1 */ 2911 (ilen * ovs_size) + /* Oversub group info on pipe1 */ 2912 (ilen * pkt_shp_size) + /* pkt shaper info on pipe1 */ 2913 (ilen * TRIDENT3_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 2914 (ilen * TRIDENT3_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 2915 (ilen * TRIDENT3_PBLKS_PER_DEV) + /* port ratio */ 2916 (ilen * hpipes); /* oversub ratio */ 2917 alloc_get = alloc_size; 2918 2919 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 2920 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 2921 FALSE, &alloc_get, 2922 &tdm_scache_ptr, 2923 SOC_TDM_WB_DEFAULT_VERSION, 2924 &recovered_ver); 2925 if (SOC_FAILURE(rv)) { 2926 if ((rv == SOC_E_CONFIG) || 2927 (rv == SOC_E_NOT_FOUND)) { 2928 /* warmboot file does not contain this 2929 * module, or the warmboot state does not exist. 2930 * in this case return SOC_E_NOT_FOUND 2931 */ 2932 return SOC_E_NOT_FOUND; 2933 } else { 2934 /* Only Level2 - flexport treat this as a error */ 2935 LOG_ERROR(BSL_LS_SOC_COMMON, 2936 (BSL_META_U(unit, 2937 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 2938 return rv; 2939 } 2940 } 2941 if (alloc_get != alloc_size) { 2942 /* Expected size doesn't match retrieved size */ 2943 LOG_ERROR(BSL_LS_SOC_COMMON, 2944 (BSL_META_U(unit, 2945 "ERROR: scache recovery for tdm" 2946 "%s()[LINE:%d] DONE \n"), 2947 FUNCTION_NAME(), __LINE__)); 2948 return SOC_E_INTERNAL; 2949 } 2950 2951 if (NULL == tdm_scache_ptr) { 2952 LOG_ERROR(BSL_LS_SOC_COMMON, 2953 (BSL_META_U(unit, 2954 "ERROR: scache recovery for tdm" 2955 "%s()[LINE:%d] DONE \n"), 2956 FUNCTION_NAME(), __LINE__)); 2957 return SOC_E_MEMORY; 2958 } 2959 2960 /* IDB TDM info on pipe0 */ 2961 var_size = ilen * TRIDENT3_TDM_LENGTH; 2962 sal_memcpy(tdm->tdm_pipe[0].idb_tdm, 2963 &tdm_scache_ptr[scache_offset], 2964 var_size); 2965 scache_offset += var_size; 2966 2967 /* MMU TDM info on pipe0 */ 2968 var_size = ilen * TRIDENT3_TDM_LENGTH; 2969 sal_memcpy(tdm->tdm_pipe[0].mmu_tdm, 2970 &tdm_scache_ptr[scache_offset], 2971 var_size); 2972 scache_offset += var_size; 2973 2974 /* Oversub group info on pipe0 */ 2975 var_size = ilen * ovs_size; 2976 sal_memcpy(tdm->tdm_pipe[0].ovs_tdm, 2977 &tdm_scache_ptr[scache_offset], 2978 var_size); 2979 scache_offset += var_size; 2980 2981 /* pkt shaper info on pipe0 */ 2982 var_size = ilen * pkt_shp_size; 2983 sal_memcpy(tdm->tdm_pipe[0].pkt_shaper_tdm, 2984 &tdm_scache_ptr[scache_offset], 2985 var_size); 2986 scache_offset += var_size; 2987 2988 /* IDB TDM info on pipe1 */ 2989 var_size = ilen * TRIDENT3_TDM_LENGTH; 2990 sal_memcpy(tdm->tdm_pipe[1].idb_tdm, 2991 &tdm_scache_ptr[scache_offset], 2992 var_size); 2993 scache_offset += var_size; 2994 2995 /* MMU TDM info on pipe1 */ 2996 var_size = ilen * TRIDENT3_TDM_LENGTH; 2997 sal_memcpy(tdm->tdm_pipe[1].mmu_tdm, 2998 &tdm_scache_ptr[scache_offset], 2999 var_size); 3000 scache_offset += var_size; 3001 3002 /* Oversub group info on pipe1 */ 3003 var_size = ilen * ovs_size; 3004 sal_memcpy(tdm->tdm_pipe[1].ovs_tdm, 3005 &tdm_scache_ptr[scache_offset], 3006 var_size); 3007 scache_offset += var_size; 3008 3009 /* pkt shaper info on pipe1 */ 3010 var_size = ilen * pkt_shp_size; 3011 sal_memcpy(tdm->tdm_pipe[1].pkt_shaper_tdm, 3012 &tdm_scache_ptr[scache_offset], 3013 var_size); 3014 scache_offset += var_size; 3015 3016 /* hpipe id of phy-port */ 3017 for (phy_port = 0; phy_port < TRIDENT3_PHY_PORTS_PER_DEV; phy_port++) { 3018 var_size = ilen; 3019 sal_memcpy(&tdm->pblk_info[phy_port].pblk_hpipe_num, 3020 &tdm_scache_ptr[scache_offset], 3021 var_size); 3022 scache_offset += var_size; 3023 } 3024 3025 /* pblk id of phy-port */ 3026 for (phy_port = 0; phy_port < TRIDENT3_PHY_PORTS_PER_DEV; phy_port++) { 3027 var_size = ilen; 3028 sal_memcpy(&tdm->pblk_info[phy_port].pblk_cal_idx, 3029 &tdm_scache_ptr[scache_offset], 3030 var_size); 3031 scache_offset += var_size; 3032 } 3033 3034 /* port ratio */ 3035 var_size = ilen * TRIDENT3_PBLKS_PER_DEV; 3036 sal_memcpy(tdm->port_ratio, 3037 &tdm_scache_ptr[scache_offset], 3038 var_size); 3039 scache_offset += var_size; 3040 3041 /* oversub ratio */ 3042 var_size = ilen * hpipes; 3043 sal_memcpy(tdm->ovs_ratio_x1000, 3044 &tdm_scache_ptr[scache_offset], 3045 var_size); 3046 scache_offset += var_size; 3047 3048 LOG_VERBOSE(BSL_LS_SOC_COMMON, 3049 (BSL_META_U(unit, 3050 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 3051 3052 return SOC_E_NONE; 3053 } 3054 #endif /* BCM_WARM_BOOT_SUPPORT */ 3055 3056 #define TD3_UFT_HASH_OFFSET_MAX 51 3057 #define TD3_EUAT_HASH_OFFSET_MAX 53 3058 #define TD3_UAT_8K_HASH_OFFSET_MAX 53 3059 #define TD3_UAT_16K_HASH_OFFSET_MAX 52 3060 3061 int 3062 soc_trident3_uft_uat_config(int unit) { 3063 int index, shared_bank_offset = 2; 3064 int num_l2_banks, num_l3_banks, num_fpem_banks = 0; 3065 int dedicated_banks = 2; 3066 int num_entries, shared_hash_offset; 3067 int uat_16k_banks = 0, uat_8k_banks = 0; 3068 int mpls_16k_banks, mpls_8k_banks; 3069 int vlan_xlate_1_16k_banks, vlan_xlate_1_8k_banks; 3070 int vlan_xlate_2_16k_banks, vlan_xlate_2_8k_banks; 3071 int egr_vlan_xlate_1_banks, egr_vlan_xlate_2_banks; 3072 int m, mem_sz; 3073 uint32 hash_control_entry[4], shared_hash_control_entry[4], 3074 shared_8k_hash_control_entry[4]; 3075 soc_mem_t dedicated_bank_mems[] = { 3076 ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm, 3077 EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm, 3078 ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm, 3079 SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm 3080 }; 3081 3082 static const soc_field_t logical_to_physical_fields[] = { 3083 LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf, 3084 LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf, 3085 LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf, 3086 LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf, 3087 LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf, 3088 LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf, 3089 LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf, 3090 LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf, 3091 LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf, 3092 LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf 3093 }; 3094 static const soc_field_t dedicated_fields[] = { 3095 HASH_OFFSET_DEDICATED_BANK_0f, HASH_OFFSET_DEDICATED_BANK_1f 3096 }; 3097 static const soc_field_t shared_fields[] = { 3098 B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf, 3099 B4_HASH_OFFSETf, B5_HASH_OFFSETf, B6_HASH_OFFSETf, B7_HASH_OFFSETf 3100 }; 3101 /* UFT/UAT control memories programming */ 3102 SOC_IF_ERROR_RETURN 3103 (soc_trident3_hash_bank_count_get(unit, L2Xm, &num_l2_banks)); 3104 SOC_IF_ERROR_RETURN 3105 (soc_trident3_hash_bank_count_get(unit, L3_ENTRY_ONLY_SINGLEm, 3106 &num_l3_banks)); 3107 SOC_IF_ERROR_RETURN 3108 (soc_trident3_hash_bank_count_get(unit, EXACT_MATCH_2m, 3109 &num_fpem_banks)); 3110 SOC_IF_ERROR_RETURN 3111 (soc_trident3_hash_bank_count_get(unit, EGR_VLAN_XLATE_1_SINGLEm, 3112 &egr_vlan_xlate_1_banks)); 3113 SOC_IF_ERROR_RETURN 3114 (soc_trident3_hash_bank_count_get(unit, EGR_VLAN_XLATE_2_SINGLEm, 3115 &egr_vlan_xlate_2_banks)); 3116 3117 if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 3118 int non_alpm = num_fpem_banks + num_l3_banks + 3119 num_l2_banks - 2 * (dedicated_banks); 3120 sal_memset(hash_control_entry, 0, 3121 sizeof(uft_shared_banks_control_entry_t)); 3122 SOC_IF_ERROR_RETURN 3123 (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3124 hash_control_entry)); 3125 if ((non_alpm) && (non_alpm <= 4)) { 3126 /* If Shared banks are used between ALPM and non-ALPM memories, 3127 * then ALPM uses Shared Bank B2, B3, B4, B5 and non-ALPM uses 3128 * B6, B7, B8, B9 banks 3129 */ 3130 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3131 hash_control_entry, ALPM_MODEf, 1); 3132 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3133 hash_control_entry, BANK_BYPASS_LPf, 0xf); 3134 num_shared_alpm_banks[unit] = 4; 3135 shared_bank_offset += 4; 3136 } else { 3137 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3138 hash_control_entry, ALPM_MODEf, 0); 3139 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3140 hash_control_entry, BANK_BYPASS_LPf, 0xff); 3141 num_shared_alpm_banks[unit] = 8; 3142 } 3143 SOC_IF_ERROR_RETURN 3144 (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3145 hash_control_entry)); 3146 SOC_IF_ERROR_RETURN 3147 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 3148 REG_PORT_ANY, ALPM_BANK_MODEf, 3149 num_shared_alpm_banks[unit] <= 4)); 3150 } 3151 3152 sal_memset(shared_hash_control_entry, 0, 3153 sizeof(uft_shared_banks_control_entry_t)); 3154 SOC_IF_ERROR_RETURN 3155 (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3156 shared_hash_control_entry)); 3157 sal_memset(hash_control_entry, 0, sizeof(l2_entry_hash_control_entry_t)); 3158 SOC_IF_ERROR_RETURN 3159 (READ_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 3160 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , hash_control_entry, 3161 HASH_TABLE_BANK_CONFIGf, (((1 << dedicated_banks) - 1) 3162 | (((1 << (num_l2_banks - dedicated_banks)) - 1) << 3163 shared_bank_offset))); 3164 for (index = dedicated_banks ; index < num_l2_banks ; index++) { 3165 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , hash_control_entry, 3166 logical_to_physical_fields[index], 3167 index + shared_bank_offset - dedicated_banks); 3168 } 3169 3170 for (index = 0; index < dedicated_banks; index++) { 3171 shared_hash_offset = (index == (num_l2_banks-1))? TD3_UFT_HASH_OFFSET_MAX : 3172 ((index * TD3_UFT_HASH_OFFSET_MAX) / (num_l2_banks-1)); 3173 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm, hash_control_entry, 3174 dedicated_fields[index], shared_hash_offset); 3175 } 3176 3177 for (index = dedicated_banks; index < num_l2_banks; index++) { 3178 shared_hash_offset = (index == (num_l2_banks-1))? TD3_UFT_HASH_OFFSET_MAX : 3179 ((index * TD3_UFT_HASH_OFFSET_MAX) / (num_l2_banks-1)); 3180 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3181 shared_hash_control_entry, shared_fields[index - 3182 dedicated_banks], shared_hash_offset); 3183 } 3184 3185 SOC_IF_ERROR_RETURN 3186 (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, hash_control_entry)); 3187 3188 /* Memories with only dedicated banks */ 3189 mem_sz = sizeof(dedicated_bank_mems) / sizeof(dedicated_bank_mems[0]); 3190 for (m = 0; m < mem_sz; m++) { 3191 sal_memset(hash_control_entry, 0, sizeof(hash_control_entry)); 3192 SOC_IF_ERROR_RETURN( 3193 soc_mem_read(unit, dedicated_bank_mems[m], MEM_BLOCK_ANY, 0, 3194 hash_control_entry)); 3195 for (index = 0; index < dedicated_banks; index++) { 3196 soc_mem_field32_set(unit, dedicated_bank_mems[m], 3197 hash_control_entry, dedicated_fields[index], 0 + (index * 32)); 3198 } 3199 SOC_IF_ERROR_RETURN( 3200 soc_mem_write(unit, dedicated_bank_mems[m], MEM_BLOCK_ANY, 0, 3201 hash_control_entry)); 3202 } 3203 3204 /* Exact match */ 3205 sal_memset(hash_control_entry, 0, sizeof(exact_match_hash_control_entry_t)); 3206 SOC_IF_ERROR_RETURN 3207 (READ_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3208 hash_control_entry)); 3209 shared_bank_offset += (num_l2_banks - dedicated_banks) ; 3210 3211 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm, hash_control_entry, 3212 HASH_TABLE_BANK_CONFIGf, 3213 ((1 << num_fpem_banks) - 1) << shared_bank_offset); 3214 for (index = 0 ; index < num_fpem_banks; index++) { 3215 shared_hash_offset = (index == (num_fpem_banks-1)) ? TD3_UFT_HASH_OFFSET_MAX : 3216 ((index * TD3_UFT_HASH_OFFSET_MAX) / (num_fpem_banks-1)); 3217 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm , hash_control_entry, 3218 logical_to_physical_fields[index], index + 3219 shared_bank_offset); 3220 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3221 shared_hash_control_entry, 3222 shared_fields[shared_bank_offset + index - 3223 dedicated_banks], shared_hash_offset); 3224 } 3225 3226 SOC_IF_ERROR_RETURN 3227 (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3228 hash_control_entry)); 3229 3230 sal_memset(hash_control_entry, 0, sizeof(l3_entry_hash_control_entry_t)); 3231 SOC_IF_ERROR_RETURN 3232 (READ_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3233 hash_control_entry)); 3234 shared_bank_offset += num_fpem_banks; 3235 3236 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry, 3237 HASH_TABLE_BANK_CONFIGf, ((((1 << (num_l3_banks - 3238 dedicated_banks)) - 1) << shared_bank_offset) | 3239 (((1 << dedicated_banks) - 1) << 10))); 3240 3241 for (index = 0; index < dedicated_banks; index++) { 3242 shared_hash_offset = (index == (num_l3_banks-1))? TD3_UFT_HASH_OFFSET_MAX : 3243 ((index * TD3_UFT_HASH_OFFSET_MAX)/(num_l3_banks-1)); 3244 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry, 3245 dedicated_fields[index], shared_hash_offset); 3246 } 3247 3248 for (index = dedicated_banks ; index < num_l3_banks ; index++) { 3249 shared_hash_offset = (index == (num_l3_banks-1))? TD3_UFT_HASH_OFFSET_MAX : 3250 ((index * TD3_UFT_HASH_OFFSET_MAX)/(num_l3_banks-1)); 3251 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry, 3252 logical_to_physical_fields[index], 3253 index + shared_bank_offset - dedicated_banks); 3254 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 3255 shared_hash_control_entry, 3256 shared_fields[shared_bank_offset + index - 3257 (dedicated_banks * 2)], shared_hash_offset); 3258 } 3259 SOC_IF_ERROR_RETURN 3260 (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3261 hash_control_entry)); 3262 SOC_IF_ERROR_RETURN 3263 (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3264 shared_hash_control_entry)); 3265 3266 sal_memset(shared_hash_control_entry, 0, 3267 sizeof(ep_uat_shared_banks_control_entry_t)); 3268 sal_memset(hash_control_entry, 0, 3269 sizeof(egr_vlan_xlate_1_hash_control_entry_t)); 3270 3271 SOC_IF_ERROR_RETURN 3272 (READ_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3273 shared_hash_control_entry)); 3274 SOC_IF_ERROR_RETURN 3275 (READ_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3276 hash_control_entry)); 3277 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 3278 hash_control_entry, HASH_TABLE_BANK_CONFIGf, 3279 ((1 << egr_vlan_xlate_1_banks) - 1)) ; 3280 3281 for(index = 0; index < egr_vlan_xlate_1_banks; index++) { 3282 shared_hash_offset = (index == (egr_vlan_xlate_1_banks-1))? 3283 TD3_EUAT_HASH_OFFSET_MAX : 3284 ((index * TD3_EUAT_HASH_OFFSET_MAX) / (egr_vlan_xlate_1_banks-1)); 3285 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 3286 hash_control_entry, 3287 logical_to_physical_fields[index], 3288 index); 3289 soc_mem_field32_set(unit, EP_UAT_SHARED_BANKS_CONTROLm, 3290 shared_hash_control_entry, shared_fields[index], 3291 shared_hash_offset); 3292 } 3293 SOC_IF_ERROR_RETURN 3294 (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3295 hash_control_entry)); 3296 3297 sal_memset(hash_control_entry, 0, 3298 sizeof(egr_vlan_xlate_2_hash_control_entry_t)); 3299 3300 SOC_IF_ERROR_RETURN 3301 (READ_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3302 hash_control_entry)); 3303 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry, 3304 HASH_TABLE_BANK_CONFIGf, 3305 ((1 << egr_vlan_xlate_2_banks) - 1) << 3306 egr_vlan_xlate_1_banks) ; 3307 3308 for(index = 0; index < egr_vlan_xlate_2_banks; index++) { 3309 shared_hash_offset = (index == (egr_vlan_xlate_2_banks-1))? 3310 TD3_EUAT_HASH_OFFSET_MAX : 3311 ((index * TD3_EUAT_HASH_OFFSET_MAX) / (egr_vlan_xlate_2_banks-1)); 3312 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, 3313 hash_control_entry, 3314 logical_to_physical_fields[index], 3315 index + egr_vlan_xlate_1_banks); 3316 soc_mem_field32_set(unit, EP_UAT_SHARED_BANKS_CONTROLm, 3317 shared_hash_control_entry, shared_fields[index + 3318 egr_vlan_xlate_1_banks], shared_hash_offset); 3319 } 3320 SOC_IF_ERROR_RETURN 3321 (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3322 hash_control_entry)); 3323 SOC_IF_ERROR_RETURN 3324 (WRITE_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3325 shared_hash_control_entry)); 3326 3327 sal_memset(shared_hash_control_entry, 0, 3328 sizeof(ip_uat_16k_shared_banks_control_entry_t)); 3329 sal_memset(shared_8k_hash_control_entry, 0, 3330 sizeof(ip_uat_8k_shared_banks_control_entry_t)); 3331 sal_memset(hash_control_entry, 0, 3332 sizeof(mpls_entry_hash_control_entry_t)); 3333 SOC_IF_ERROR_RETURN 3334 (READ_IP_UAT_16K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3335 shared_hash_control_entry)); 3336 SOC_IF_ERROR_RETURN 3337 (READ_IP_UAT_8K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3338 shared_8k_hash_control_entry)); 3339 SOC_IF_ERROR_RETURN 3340 (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3341 hash_control_entry)); 3342 3343 num_entries = soc_mem_index_count(unit, MPLS_ENTRY_SINGLEm); 3344 SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, num_entries, 3345 &uat_16k_banks, &uat_8k_banks)); 3346 mpls_16k_banks = uat_16k_banks; 3347 mpls_8k_banks = uat_8k_banks; 3348 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 3349 HASH_TABLE_BANK_CONFIGf, (((1 << mpls_8k_banks) - 1) | 3350 (((1 << mpls_16k_banks) - 1) << 4))); 3351 3352 for(index = 0; index < mpls_8k_banks; index++) { 3353 shared_hash_offset = (index == (mpls_8k_banks-1))? 3354 TD3_UAT_8K_HASH_OFFSET_MAX : 3355 ((index * TD3_UAT_8K_HASH_OFFSET_MAX) / (mpls_8k_banks-1)); 3356 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 3357 logical_to_physical_fields[index], index); 3358 soc_mem_field32_set(unit, IP_UAT_8K_SHARED_BANKS_CONTROLm, 3359 shared_8k_hash_control_entry, shared_fields[index], 3360 shared_hash_offset); 3361 } 3362 3363 for(index = 0; index < mpls_16k_banks; index++) { 3364 shared_hash_offset = (index == (mpls_16k_banks-1))? 3365 TD3_UAT_16K_HASH_OFFSET_MAX : 3366 ((index * TD3_UAT_16K_HASH_OFFSET_MAX) / (mpls_16k_banks-1)); 3367 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, 3368 hash_control_entry, 3369 logical_to_physical_fields[index + mpls_8k_banks], index + 4); 3370 soc_mem_field32_set(unit, IP_UAT_16K_SHARED_BANKS_CONTROLm, 3371 shared_hash_control_entry, shared_fields[index], 3372 shared_hash_offset); 3373 } 3374 SOC_IF_ERROR_RETURN 3375 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3376 hash_control_entry)); 3377 3378 sal_memset(hash_control_entry, 0, 3379 sizeof(vlan_xlate_1_hash_control_entry_t)); 3380 SOC_IF_ERROR_RETURN 3381 (READ_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3382 hash_control_entry)); 3383 num_entries = soc_mem_index_count(unit, VLAN_XLATE_1_SINGLEm); 3384 SOC_IF_ERROR_RETURN( 3385 soc_trident3_iuat_sizing(unit, num_entries, &uat_16k_banks, 3386 &uat_8k_banks)); 3387 vlan_xlate_1_16k_banks = uat_16k_banks - mpls_16k_banks; 3388 vlan_xlate_1_8k_banks = uat_8k_banks - mpls_8k_banks; 3389 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, hash_control_entry, 3390 HASH_TABLE_BANK_CONFIGf, ((((1 << vlan_xlate_1_8k_banks) 3391 - 1) << mpls_8k_banks) | 3392 (((1 << vlan_xlate_1_16k_banks) - 1) << (4 + 3393 mpls_16k_banks)))); 3394 3395 for(index = 0; index < vlan_xlate_1_8k_banks; index++) { 3396 shared_hash_offset = (index == (vlan_xlate_1_8k_banks-1))? 3397 TD3_UAT_8K_HASH_OFFSET_MAX : 3398 ((index * TD3_UAT_8K_HASH_OFFSET_MAX) / (vlan_xlate_1_8k_banks-1)); 3399 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, 3400 hash_control_entry, 3401 logical_to_physical_fields[index], index + 3402 mpls_8k_banks); 3403 soc_mem_field32_set(unit, IP_UAT_8K_SHARED_BANKS_CONTROLm, 3404 shared_8k_hash_control_entry, shared_fields[index + 3405 mpls_8k_banks], shared_hash_offset); 3406 } 3407 3408 for(index = 0; index < vlan_xlate_1_16k_banks; index++) { 3409 shared_hash_offset = (index == (vlan_xlate_1_16k_banks-1))? 3410 TD3_UAT_16K_HASH_OFFSET_MAX : 3411 ((index * TD3_UAT_16K_HASH_OFFSET_MAX) / (vlan_xlate_1_16k_banks-1)); 3412 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, 3413 hash_control_entry, 3414 logical_to_physical_fields[index + vlan_xlate_1_8k_banks], index + 3415 mpls_16k_banks + 4); 3416 soc_mem_field32_set(unit, IP_UAT_16K_SHARED_BANKS_CONTROLm, 3417 shared_hash_control_entry, shared_fields[index + 3418 mpls_16k_banks], shared_hash_offset); 3419 } 3420 SOC_IF_ERROR_RETURN 3421 (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3422 hash_control_entry)); 3423 3424 sal_memset(hash_control_entry, 0, 3425 sizeof(vlan_xlate_2_hash_control_entry_t)); 3426 SOC_IF_ERROR_RETURN 3427 (READ_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 3428 hash_control_entry)); 3429 num_entries = soc_mem_index_count(unit, VLAN_XLATE_2_SINGLEm); 3430 SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, num_entries, 3431 &uat_16k_banks, &uat_8k_banks)); 3432 vlan_xlate_2_16k_banks = uat_16k_banks - mpls_16k_banks - 3433 vlan_xlate_1_16k_banks; 3434 vlan_xlate_2_8k_banks = uat_8k_banks - mpls_8k_banks - 3435 vlan_xlate_1_8k_banks; 3436 3437 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry, 3438 HASH_TABLE_BANK_CONFIGf, ((((1 << vlan_xlate_2_8k_banks) 3439 - 1) << (mpls_8k_banks + vlan_xlate_1_8k_banks)) | 3440 (((1 << vlan_xlate_2_16k_banks) - 1) << (4 + 3441 mpls_16k_banks + vlan_xlate_1_16k_banks )))); 3442 3443 for(index = 0; index < vlan_xlate_2_8k_banks; index++) { 3444 shared_hash_offset = (index == (vlan_xlate_2_8k_banks-1))? 3445 TD3_UAT_8K_HASH_OFFSET_MAX : 3446 ((index * TD3_UAT_8K_HASH_OFFSET_MAX) / (vlan_xlate_2_8k_banks-1)); 3447 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry, 3448 logical_to_physical_fields[index], index + 3449 mpls_8k_banks + vlan_xlate_1_8k_banks); 3450 soc_mem_field32_set(unit, IP_UAT_8K_SHARED_BANKS_CONTROLm, 3451 shared_8k_hash_control_entry, shared_fields[index + 3452 mpls_8k_banks + vlan_xlate_1_8k_banks], 3453 shared_hash_offset); 3454 } 3455 3456 for(index = 0; index < vlan_xlate_2_16k_banks; index++) { 3457 shared_hash_offset = (index == (vlan_xlate_2_16k_banks-1))? 3458 TD3_UAT_16K_HASH_OFFSET_MAX : 3459 ((index * TD3_UAT_16K_HASH_OFFSET_MAX) / (vlan_xlate_2_16k_banks-1)); 3460 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, 3461 hash_control_entry, 3462 logical_to_physical_fields[index + vlan_xlate_2_8k_banks], index + 3463 mpls_16k_banks + vlan_xlate_1_16k_banks + 4); 3464 soc_mem_field32_set(unit, IP_UAT_16K_SHARED_BANKS_CONTROLm, 3465 shared_hash_control_entry, shared_fields[index + 3466 mpls_16k_banks + vlan_xlate_1_16k_banks], 3467 shared_hash_offset); 3468 } 3469 SOC_IF_ERROR_RETURN 3470 (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3471 hash_control_entry)); 3472 SOC_IF_ERROR_RETURN 3473 (WRITE_IP_UAT_8K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3474 shared_8k_hash_control_entry)); 3475 SOC_IF_ERROR_RETURN 3476 (WRITE_IP_UAT_16K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3477 shared_hash_control_entry)); 3478 3479 /* Create a mutex for s/w re-ordering */ 3480 SOC_IF_ERROR_RETURN(soc_td3_hash_mutex_init (unit)); 3481 3482 return SOC_E_NONE; 3483 3484 } 3485 3486 int 3487 soc_trident3_init_idb_memory(int unit) 3488 { 3489 uint32 pipe_map; 3490 soc_reg_t reg; 3491 int pipe, chip_num_pipe; 3492 uint32 rval, in_progress; 3493 int pipe_init_usec; 3494 soc_timeout_t to; 3495 static const soc_reg_t idb_tdm_config_reg[TRIDENT3_TDM_PIPES_PER_DEV] = { 3496 IS_TDM_CONFIG_PIPE0r, IS_TDM_CONFIG_PIPE1r 3497 }; 3498 static const soc_reg_t idb_opp_sched_config[TRIDENT3_TDM_PIPES_PER_DEV] = { 3499 IS_OPP_SCHED_CFG_PIPE0r, IS_OPP_SCHED_CFG_PIPE1r 3500 }; 3501 3502 soc_trident3_pipe_map_get(unit, &pipe_map); 3503 3504 /* While full chip emulaiton database is used, if only PIPE0 ports are configured 3505 * NUM_PIPE is overwritten to 1, however we still need to reset entire chip using 3506 * chip_num_pipe which reflects total number of pipes in the chip. 3507 */ 3508 chip_num_pipe = soc_property_get(unit, "num_pipe", NUM_PIPE(unit)); 3509 3510 /* Initialize IDB memory */ 3511 rval = 0; 3512 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 3513 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 3514 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, REGIONf, 1); 3515 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x100); 3516 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3517 3518 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 3519 if (SAL_BOOT_SIMULATION) { 3520 pipe_init_usec = 10000000; 3521 } else { 3522 pipe_init_usec = 50000; 3523 } 3524 soc_timeout_init(&to, pipe_init_usec, 0); 3525 3526 /* Wait for IDB memory initialization done */ 3527 in_progress = pipe_map; 3528 do { 3529 for (pipe = 0; pipe < chip_num_pipe && in_progress; pipe++) { 3530 reg = SOC_REG_UNIQUE_ACC(unit, ING_HW_RESET_CONTROL_2r)[pipe]; 3531 if (in_progress & (1 << pipe)) { /* not done yet */ 3532 SOC_IF_ERROR_RETURN 3533 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3534 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3535 in_progress ^= (1 << pipe); 3536 } 3537 } 3538 } 3539 if (soc_timeout_check(&to)) { 3540 LOG_WARN(BSL_LS_SOC_COMMON, 3541 (BSL_META_U(unit, 3542 "unit %d : ING_HW_RESET timeout\n"), unit)); 3543 break; 3544 } 3545 } while (in_progress != 0); 3546 rval = 0; 3547 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, REGIONf, 1); 3548 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3549 3550 for (pipe = 0; pipe < chip_num_pipe; pipe++) { 3551 3552 rval = 0; 3553 reg = idb_tdm_config_reg[pipe]; 3554 soc_reg_field_set(unit, reg, &rval, ENABLEf, 1); 3555 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 3556 3557 reg = idb_opp_sched_config[pipe]; 3558 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3559 soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf, 1); 3560 soc_reg_field_set(unit, reg, &rval, OPP1_SPACINGf, 6); 3561 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 3562 } 3563 3564 return SOC_E_NONE; 3565 } 3566 3567 int 3568 soc_trident3_clear_all_memory(int unit) 3569 { 3570 uint32 pipe_map; 3571 int block_info_idx; 3572 soc_reg_t reg; 3573 int pipe, port, index, count; 3574 uint32 rval, in_progress; 3575 int pipe_init_usec; 3576 soc_timeout_t to; 3577 uint32 hash_control_entry[4]; 3578 uint32 bitmap = 0, uft_bmap=0; 3579 soc_mem_t hmem = L3_ENTRY_HASH_CONTROLm; 3580 static const struct { 3581 soc_mem_t mem; 3582 uint32 skip_flags; /* always skip on QUICKTURN or XGSSIM */ 3583 } cam_list[] = { 3584 { CPU_COS_MAPm, BOOT_F_PLISIM }, 3585 { DST_COMPRESSIONm, BOOT_F_PLISIM }, 3586 { EFP_TCAMm, BOOT_F_PLISIM }, 3587 { EGR_FIELD_EXTRACTION_PROFILE_1_TCAMm, BOOT_F_PLISIM }, 3588 { EGR_FIELD_EXTRACTION_PROFILE_2_TCAMm, BOOT_F_PLISIM }, 3589 { EGR_PKT_FLOW_SELECT_TCAMm, BOOT_F_PLISIM }, 3590 { EGR_QOS_CTRL_TCAMm, BOOT_F_PLISIM }, 3591 { EGR_ZONE_0_EDITOR_CONTROL_TCAMm, BOOT_F_PLISIM }, 3592 { EGR_ZONE_1_EDITOR_CONTROL_TCAMm, BOOT_F_PLISIM }, 3593 { EGR_ZONE_2_EDITOR_CONTROL_TCAMm, BOOT_F_PLISIM }, 3594 { EGR_ZONE_3_EDITOR_CONTROL_TCAMm, BOOT_F_PLISIM }, 3595 { EGR_ZONE_4_EDITOR_CONTROL_TCAMm, BOOT_F_PLISIM }, 3596 { EXACT_MATCH_LOGICAL_TABLE_SELECTm, BOOT_F_PLISIM }, 3597 { FLEX_RTAG7_HASH_TCAMm, BOOT_F_PLISIM }, 3598 { IFP_LOGICAL_TABLE_SELECTm, BOOT_F_PLISIM }, 3599 { IFP_TCAMm, BOOT_F_PLISIM }, 3600 { ING_SNATm, BOOT_F_PLISIM }, 3601 { IP_MULTICAST_TCAMm, BOOT_F_PLISIM }, 3602 { L2_USER_ENTRYm, BOOT_F_PLISIM }, 3603 { L3_DEFIPm, BOOT_F_PLISIM }, 3604 { L3_DEFIP_PAIR_128m, BOOT_F_PLISIM }, 3605 { L3_TUNNELm, BOOT_F_PLISIM }, 3606 { MY_STATION_TCAMm, BOOT_F_PLISIM }, 3607 { MY_STATION_TCAM_2m, BOOT_F_PLISIM }, 3608 { PHB_SELECT_TCAMm, BOOT_F_PLISIM }, 3609 { PKT_FLOW_SELECT_TCAM_0m, BOOT_F_PLISIM }, 3610 { PKT_FLOW_SELECT_TCAM_1m, BOOT_F_PLISIM }, 3611 { PKT_FLOW_SELECT_TCAM_2m, BOOT_F_PLISIM }, 3612 { SRC_COMPRESSIONm, BOOT_F_PLISIM }, 3613 { VFP_TCAMm, BOOT_F_PLISIM }, 3614 { VLAN_SUBNETm, 0 },/* VLAN API needs all 0 mask */ 3615 }; 3616 3617 soc_trident3_pipe_map_get(unit, &pipe_map); 3618 3619 SOC_IF_ERROR_RETURN(soc_mem_read(unit, L2_ENTRY_HASH_CONTROLm, 3620 MEM_BLOCK_ALL, 0, hash_control_entry)); 3621 uft_bmap |= soc_mem_field32_get(unit, L2_ENTRY_HASH_CONTROLm, 3622 hash_control_entry, HASH_TABLE_BANK_CONFIGf); 3623 3624 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EXACT_MATCH_HASH_CONTROLm, 3625 MEM_BLOCK_ALL, 0, hash_control_entry)); 3626 uft_bmap |= soc_mem_field32_get(unit, EXACT_MATCH_HASH_CONTROLm, 3627 hash_control_entry, HASH_TABLE_BANK_CONFIGf); 3628 3629 /* L3_ENTRY_HASH_CONTROL->HASH_TABLE_BANK_CONFIG must be set to cover shared 3630 * UFT banks, that are not included in other hash control during HW MEM RESET ALL 3631 * and also include dedicated L3 banks. 3632 */ 3633 SOC_IF_ERROR_RETURN(soc_mem_read(unit, hmem, MEM_BLOCK_ALL, 0, 3634 hash_control_entry)); 3635 bitmap = soc_mem_field32_get(unit, hmem, hash_control_entry, 3636 HASH_TABLE_BANK_CONFIGf); 3637 3638 uft_bmap = 0xFFC & ~uft_bmap; 3639 soc_mem_field32_set(unit, hmem, hash_control_entry, HASH_TABLE_BANK_CONFIGf, uft_bmap); 3640 SOC_IF_ERROR_RETURN(soc_mem_write(unit, hmem, MEM_BLOCK_ALL, 0, hash_control_entry)); 3641 3642 /* Initial IPIPE memory */ 3643 rval = 0; 3644 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 3645 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 3646 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 3647 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, REGIONf, 0); 3648 /* Set count to # entries of largest IPIPE table */ 3649 count = soc_mem_index_count(unit, ING_L3_NEXT_HOPm); 3650 3651 if (SOC_MEM_IS_VALID(unit, BSC_AG_AGE_TABLEm)) { 3652 if (count < soc_mem_index_count(unit, BSC_AG_AGE_TABLEm)) { 3653 count = soc_mem_index_count(unit, BSC_AG_AGE_TABLEm); 3654 } 3655 } 3656 3657 if (count < soc_mem_index_count(unit, L2Xm)) { 3658 count = soc_mem_index_count(unit, L2Xm); 3659 } 3660 if (count < soc_mem_index_count(unit, L3_ENTRY_ONLY_SINGLEm)) { 3661 count = soc_mem_index_count(unit, L3_ENTRY_ONLY_SINGLEm); 3662 } 3663 /*if (count < soc_mem_index_count(unit, FPEM_ECCm)) { 3664 count = soc_mem_index_count(unit, FPEM_ECCm); 3665 } */ 3666 if (count < soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 3667 count = soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m); 3668 } 3669 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, count); 3670 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3671 3672 /* Initial EPIPE memory */ 3673 rval = 0; 3674 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 3675 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 3676 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 3677 /* Set count to # entries in largest EPIPE table (EGR_L3_NEXT_HOP) */ 3678 count = soc_mem_index_count(unit, EGR_L3_NEXT_HOPm); 3679 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, count); 3680 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 3681 3682 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 3683 if (SAL_BOOT_SIMULATION) { 3684 pipe_init_usec = 10000000; 3685 } else { 3686 pipe_init_usec = 50000; 3687 } 3688 soc_timeout_init(&to, pipe_init_usec, 0); 3689 3690 /* Wait for IPIPE memory initialization done */ 3691 in_progress = pipe_map; 3692 do { 3693 for (pipe = 0; pipe < NUM_PIPE(unit) && in_progress; pipe++) { 3694 reg = SOC_REG_UNIQUE_ACC(unit, ING_HW_RESET_CONTROL_2r)[pipe]; 3695 if (in_progress & (1 << pipe)) { /* not done yet */ 3696 SOC_IF_ERROR_RETURN 3697 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3698 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3699 in_progress ^= 1 << pipe; 3700 } 3701 } 3702 } 3703 if (soc_timeout_check(&to)) { 3704 LOG_WARN(BSL_LS_SOC_COMMON, 3705 (BSL_META_U(unit, 3706 "unit %d : ING_HW_RESET timeout\n"), unit)); 3707 break; 3708 } 3709 } while (in_progress != 0); 3710 3711 /* Restore L3_ENTRY_HASH_CONTROL->HASH_TABLE_BANK_CONFIG value */ 3712 soc_mem_field32_set(unit, hmem, hash_control_entry, HASH_TABLE_BANK_CONFIGf, bitmap); 3713 SOC_IF_ERROR_RETURN(soc_mem_write(unit, hmem, MEM_BLOCK_ALL, 0, hash_control_entry)); 3714 3715 /* Wait for EPIPE memory initialization done */ 3716 in_progress = pipe_map; 3717 do { 3718 for (pipe = 0; pipe < NUM_PIPE(unit) && in_progress; pipe++) { 3719 reg = SOC_REG_UNIQUE_ACC(unit, EGR_HW_RESET_CONTROL_1r)[pipe]; 3720 if (in_progress & (1 << pipe)) { /* not done yet */ 3721 SOC_IF_ERROR_RETURN 3722 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3723 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3724 in_progress ^= 1 << pipe; 3725 } 3726 } 3727 } 3728 if (soc_timeout_check(&to)) { 3729 LOG_WARN(BSL_LS_SOC_COMMON, 3730 (BSL_META_U(unit, 3731 "unit %d : EGR_HW_RESET timeout\n"), unit)); 3732 break; 3733 } 3734 } while (in_progress != 0); 3735 3736 rval = 0; 3737 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3738 rval = SOC_REG_INFO(unit, EGR_HW_RESET_CONTROL_1r).rst_val_lo; 3739 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 3740 3741 /* Initial IDB memory */ 3742 SOC_IF_ERROR_RETURN(WRITE_IDB_HW_CONTROLr(unit, 0)); 3743 rval = 0; 3744 soc_reg_field_set(unit, IDB_HW_CONTROLr, &rval, IS_MEM_INITf, 1); 3745 SOC_IF_ERROR_RETURN(WRITE_IDB_HW_CONTROLr(unit, rval)); 3746 SOC_IF_ERROR_RETURN(WRITE_IDB_HW_CONTROLr(unit, 0)); 3747 3748 /* Initial PORT MIB counter */ 3749 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 3750 port = SOC_BLOCK_PORT(unit, block_info_idx); 3751 soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 3752 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval)); 3753 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0)); 3754 } 3755 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) { 3756 port = SOC_BLOCK_PORT(unit, block_info_idx); 3757 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 3758 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval)); 3759 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0)); 3760 } 3761 3762 /* TCAM tables are not handled by hardware reset control */ 3763 if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_XGSSIM) { 3764 for (index = 0; index < COUNTOF(cam_list); index++) { 3765 if (sal_boot_flags_get() & cam_list[index].skip_flags) { 3766 continue; 3767 } 3768 3769 if (!SOC_MEM_IS_VALID(unit, cam_list[index].mem)) { 3770 continue; 3771 } 3772 SOC_IF_ERROR_RETURN 3773 (soc_mem_clear(unit, cam_list[index].mem, COPYNO_ALL, TRUE)); 3774 } 3775 } 3776 3777 /* TD3-1847 */ 3778 if (!SOC_WARM_BOOT(unit)) { 3779 /* Clear the higher 32k of RH_*_flowset table */ 3780 if (soc_mem_index_count(unit, RH_LAG_FLOWSETm)) { 3781 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 3782 REG_PORT_ANY, RH_DLB_SELECTIONf, 1)); 3783 SOC_IF_ERROR_RETURN 3784 (soc_mem_clear(unit, RH_LAG_FLOWSETm, COPYNO_ALL, TRUE)); 3785 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 3786 REG_PORT_ANY, RH_DLB_SELECTIONf, 0)); 3787 } 3788 if (soc_mem_index_count(unit, RH_HGT_FLOWSETm)) { 3789 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 3790 REG_PORT_ANY, RH_DLB_SELECTIONf, 1)); 3791 3792 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 3793 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 2)); 3794 SOC_IF_ERROR_RETURN 3795 (soc_mem_clear(unit, RH_HGT_FLOWSETm, COPYNO_ALL, TRUE)); 3796 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 3797 REG_PORT_ANY, RH_DLB_SELECTIONf, 0)); 3798 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 3799 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 0)); 3800 } 3801 } 3802 3803 soc_td3_rx_etype_niv[unit] = 0; 3804 soc_td3_rx_etype_pe[unit] = 0; 3805 3806 return SOC_E_NONE; 3807 3808 } 3809 3810 /* Determine a PLL's current DCO value. The PLL should be checked to ensure 3811 that it is locked prior to calling this function */ 3812 int 3813 _soc_trident3_pll_dco_code_get(int unit, soc_td3_plls_e pll, uint32 *dco_code) 3814 { 3815 soc_reg_t stat_ctrl_reg; 3816 soc_reg_t stat_reg; 3817 soc_field_t stat_sel_fld, stat_rst_fld, stat_mode_fld, stat_update_fld; 3818 soc_field_t stat_fld; 3819 uint32 rval; 3820 3821 stat_sel_fld = STAT_SELECTf; 3822 stat_rst_fld = STAT_RESETf; 3823 stat_mode_fld = STAT_MODEf; 3824 stat_update_fld = STAT_UPDATEf; 3825 stat_fld = PLL_STATUSf; 3826 switch (pll) { 3827 case SOC_TD3_TS_PLL: 3828 stat_ctrl_reg = TOP_TS_PLL_CTRL_4r; 3829 stat_reg = TOP_TS_PLL_STATUSr; 3830 break; 3831 case SOC_TD3_BS_PLL0: 3832 stat_ctrl_reg = TOP_BS_PLL0_CTRL_4r; 3833 stat_reg = TOP_BS_PLL0_STATUSr; 3834 break; 3835 case SOC_TD3_BS_PLL1: 3836 stat_ctrl_reg = TOP_BS_PLL1_CTRL_4r; 3837 stat_reg = TOP_BS_PLL1_STATUSr; 3838 break; 3839 default: 3840 return SOC_E_PARAM; 3841 } 3842 3843 /* Configure the stat logic to read the DCO value */ 3844 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, stat_ctrl_reg, REG_PORT_ANY, 0, 3845 &rval)); 3846 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_sel_fld, 4); /* DCO */ 3847 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_mode_fld, 3); /* avg */ 3848 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_rst_fld, 1); 3849 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_update_fld, 0); 3850 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, stat_ctrl_reg, REG_PORT_ANY, 0, 3851 rval)); 3852 3853 /* Take out of reset */ 3854 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_rst_fld, 0); 3855 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, stat_ctrl_reg, REG_PORT_ANY, 0, 3856 rval)); 3857 3858 /* Initiate a capture */ 3859 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_update_fld, 1); 3860 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, stat_ctrl_reg, REG_PORT_ANY, 0, 3861 rval)); 3862 3863 sal_usleep(10 * MILLISECOND_USEC); 3864 3865 /* Get the DCO code */ 3866 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, stat_reg, REG_PORT_ANY, 0, 3867 &rval)); 3868 *dco_code = soc_reg_field_get(unit, stat_reg, rval, stat_fld); 3869 3870 /* Clear the capture state */ 3871 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, stat_ctrl_reg, REG_PORT_ANY, 0, 3872 &rval)); 3873 soc_reg_field_set(unit, stat_ctrl_reg, &rval, stat_update_fld, 0); 3874 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, stat_ctrl_reg, REG_PORT_ANY, 0, 3875 rval)); 3876 3877 return SOC_E_NONE; 3878 } 3879 3880 /* Linearly scale the DCO code as a function of the VCO's frequency */ 3881 int 3882 _soc_td3_pll_dco_normalize(uint32 *dco_code, uint32 ref_freq, uint32 ndiv) 3883 { 3884 static const int int_ref_freq = 50000000; 3885 3886 *dco_code <<= 20; 3887 if (ref_freq <= 0) { 3888 *dco_code /= (int_ref_freq / 100000 * ndiv); 3889 } else { 3890 *dco_code /= (ref_freq / 100000 * ndiv); 3891 } 3892 3893 return SOC_E_NONE; 3894 } 3895 3896 int soc_td3_frequency_init(int unit) 3897 { 3898 static const int freq_list[] = { 1525, 1425, 1325, 1012, 850 }; 3899 static const int freq_sel_list[] = { 2, 3, 4, 6, 7 }; 3900 3901 const char *str_ratio[] = { "2:3", "1:1" }; 3902 char *config_str; 3903 static const int dpp_ratio_x10_list[] = { 3904 15, /* core clk : pp clk ratio is 3:2 (default) */ 3905 10 /* core clk : pp clk ratio is 1:1 */ 3906 }; 3907 3908 soc_field_t fields[3]; 3909 uint32 values[3]; 3910 soc_info_t *si = &SOC_INFO(unit); 3911 3912 int index, list_len, frequency, freq_sel=2; 3913 3914 soc_trident3_max_frequency_get(unit, BCM56870_DEVICE_ID, -1, -1, &si->frequency); 3915 frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, -1); 3916 3917 /* Frequency is not selected.., so we go default setting. Nothing to do. */ 3918 if (frequency == -1) { 3919 return (SOC_E_NONE); 3920 } 3921 3922 /* Frequency is more than max allowed, use max value. */ 3923 if (frequency > si->frequency) { 3924 LOG_CLI((BSL_META_U(unit, 3925 "*** Input core clock frequency %dMHz is not " 3926 "supported, (max allowed : %dMHz!\n"), 3927 frequency, si->frequency)); 3928 3929 frequency = si->frequency; 3930 } 3931 3932 /* Check if Core CLK frequency is correct */ 3933 list_len = COUNTOF(freq_list); 3934 for (index = 0; index < list_len; index++) { 3935 if (freq_list[index] <= si->frequency && 3936 frequency == freq_list[index]) { 3937 si->frequency = frequency; 3938 si->dpp_clk_ratio_x10 = (frequency > CCLK_FREQ_1012MHZ)? 3939 dpp_ratio_x10_list[0] : 3940 dpp_ratio_x10_list[1]; 3941 freq_sel = freq_sel_list[index]; 3942 break; 3943 } 3944 } 3945 3946 if (index >= list_len) { 3947 LOG_CLI((BSL_META_U(unit, 3948 "*** Input core clock frequency %dMHz is not " 3949 "supported!\n"), frequency)); 3950 return (SOC_E_PARAM); 3951 } 3952 3953 /* Check if user specified dpp ratio and validate it */ 3954 config_str = soc_property_get_str(unit, spn_DPP_CLOCK_RATIO); 3955 if (config_str) { 3956 list_len = COUNTOF(dpp_ratio_x10_list); 3957 for (index = 0; index < list_len; index++) { 3958 if (!sal_strcmp(config_str, str_ratio[index])) { 3959 break; 3960 } 3961 } 3962 if (index < list_len && 3963 !(si->frequency > 1012 && dpp_ratio_x10_list[index] == 10)) { 3964 /* ratio 1:1 with core freq larger than 1125MHz is not supported */ 3965 si->dpp_clk_ratio_x10 = dpp_ratio_x10_list[index]; 3966 } else { 3967 LOG_CLI((BSL_META_U(unit, 3968 "*** Input dpp clock frequency ratio %s is not " 3969 "supported with core frequency %d!\n"), 3970 config_str, si->frequency)); 3971 return (SOC_E_PARAM); 3972 } 3973 } 3974 3975 fields[0] = CORE_CLK_0_FREQ_SELf; 3976 values[0] = freq_sel; 3977 fields[1] = SW_CORE_CLK_0_SEL_ENf; 3978 values[1] = 1; 3979 fields[2] = DPP_CLK_RATIO_SELf; 3980 values[2] = (si->dpp_clk_ratio_x10 == 10)? 3 : 1; 3981 3982 SOC_IF_ERROR_RETURN 3983 (soc_reg_fields32_modify(unit, TOP_CORE_CLK_FREQ_SELr, 3984 REG_PORT_ANY, 3, fields, values)); 3985 return (SOC_E_NONE); 3986 } 3987 3988 int 3989 _soc_trident3_init_hash_control_reset(int unit) { 3990 3991 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 3992 &egr_vlan_1_hash_control, HASH_TABLE_BANK_CONFIGf, 0xf); 3993 SOC_IF_ERROR_RETURN 3994 (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 3995 &egr_vlan_1_hash_control)); 3996 3997 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, 3998 &egr_vlan_2_hash_control, HASH_TABLE_BANK_CONFIGf, 0); 3999 SOC_IF_ERROR_RETURN 4000 (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4001 &egr_vlan_2_hash_control)); 4002 4003 SOC_IF_ERROR_RETURN 4004 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4005 &egr_vp_vlan_mbm_hash_control)); 4006 4007 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm, 4008 &exact_match_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0); 4009 SOC_IF_ERROR_RETURN 4010 (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4011 &exact_match_hash_control)); 4012 4013 SOC_IF_ERROR_RETURN 4014 (WRITE_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4015 &ing_dnat_hash_control)); 4016 4017 SOC_IF_ERROR_RETURN 4018 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4019 &ing_vp_vlan_mbm_hash_control)); 4020 4021 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm, 4022 &l2_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0x3); 4023 SOC_IF_ERROR_RETURN 4024 (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4025 &l2_entry_hash_control)); 4026 4027 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, 4028 &l3_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0xffc); 4029 SOC_IF_ERROR_RETURN 4030 (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4031 &l3_entry_hash_control)); 4032 4033 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, 4034 &mpls_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0); 4035 SOC_IF_ERROR_RETURN 4036 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4037 &mpls_entry_hash_control)); 4038 4039 SOC_IF_ERROR_RETURN 4040 (WRITE_SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4041 &subport_hash_control)); 4042 4043 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, 4044 &vlan_1_hash_control, HASH_TABLE_BANK_CONFIGf, 0xff); 4045 SOC_IF_ERROR_RETURN 4046 (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4047 &vlan_1_hash_control)); 4048 4049 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, 4050 &vlan_2_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0); 4051 SOC_IF_ERROR_RETURN 4052 (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4053 &vlan_2_hash_control)); 4054 4055 SOC_IF_ERROR_RETURN 4056 (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4057 &uft_shared_banks_control)); 4058 4059 SOC_IF_ERROR_RETURN 4060 (WRITE_IP_UAT_16K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4061 &ip_uat_16k_shared_banks_control)); 4062 4063 SOC_IF_ERROR_RETURN 4064 (WRITE_IP_UAT_8K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4065 &ip_uat_8k_shared_banks_control)); 4066 4067 SOC_IF_ERROR_RETURN 4068 (WRITE_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 4069 &ep_uat_shared_banks_control)); 4070 return SOC_E_NONE; 4071 } 4072 4073 int 4074 soc_trident3_chip_reset(int unit) 4075 { 4076 #define _SOC_TD3_BSPLL_COUNT 2 4077 #define _SOC_TD3_PLL_CFG_FIELDS 4 4078 #define _SOC_TD3_TEMP_MAX 130 4079 #define _SOC_TD3_DEF_TEMP_MAX 90 4080 #if 0 4081 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 4082 int num_overlay_ecmp_rh_flowset_entries; 4083 int ecmp_levels = 1; 4084 #endif 4085 #endif 4086 4087 soc_reg_t reg; 4088 int index, parity_enable; 4089 uint32 to_usec, temp_mask; 4090 uint32 rval, temp_thr; 4091 uint32 dco_code, dco_code_target; 4092 int ref_freq; 4093 char blank = 0; 4094 static const soc_pll_16_param_t ts_pll_params[] = { 4095 /* 25MHz external reference clock */ 4096 {25000000, 25, 2, 10, 3, 10, 1, 200, {10, 20, 32, 10, 200, 40}}, 4097 /* 50MHz external reference clock */ 4098 {50000000, 50, 2, 10, 3, 10, 1, 100, {10, 0, 0, 0, 200, 40}}, 4099 /* 50MHz internal reference clock from core PLL */ 4100 { 0, 50, 2, 10, 3, 10, 1, 100, {10, 0, 0, 0, 200, 40}} 4101 }; 4102 static const soc_pll_16_param_t bs_pll_params[] = { 4103 /* 12.8MHz external reference clock */ 4104 {12800000, 1, 2, 10, 3, 10, 1, 200, {128, 0, 0, 0, 0, 0}}, 4105 /* 20MHz external reference clock */ 4106 {20000000, 1, 2, 10, 3, 10, 1, 125, {125, 0, 0, 0, 0, 0}}, 4107 /* 25MHz external reference clock */ 4108 {25000000, 1, 2, 10, 3, 10, 1, 100, {125, 0, 0, 0, 0, 0}}, 4109 /* 32MHz external reference clock */ 4110 {32000000, 1, 2, 10, 3, 10, 1, 80, {128, 0, 0, 0, 0, 0}}, 4111 /* 50MHz external reference clock */ 4112 {50000000, 1, 2, 10, 3, 10, 1, 50, {125, 0, 0, 0, 0, 0}}, 4113 /* 50MHz internal reference clock from core PLL */ 4114 { 0, 0, 2, 10, 3, 10, 1, 50, {125, 0, 0, 0, 0, 0}} 4115 }; 4116 static const int auto_ref = -1; 4117 static const uint32 dco_poison = 0xffff; 4118 4119 static const soc_reg_t temp_thr_reg[] = { 4120 TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr, 4121 TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr, 4122 TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr, 4123 TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr, 4124 TOP_PVTMON_8_INTR_THRESHOLDr, TOP_PVTMON_9_INTR_THRESHOLDr, 4125 TOP_PVTMON_10_INTR_THRESHOLDr, TOP_PVTMON_11_INTR_THRESHOLDr 4126 }; 4127 static const char *temp_thr_prop[] = { 4128 "temp0_threshold", "temp1_threshold", "temp2_threshold", 4129 "temp3_threshold", "temp4_threshold", "temp5_threshold", 4130 "temp6_threshold", "temp7_threshold", "temp8_threshold", 4131 "temp9_threshold", "temp10_threshold","temp11_threshold" 4132 }; 4133 4134 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 4135 (10 * MILLISECOND_USEC); 4136 4137 /* 4138 * SBUS ring and block number: 4139 * ring 0: IP(1), LBPORT0(54), LBPORT1(51), LBPORT2(52), LBPORT3(53) 4140 * ring 1: EP(2) 4141 * ring 2: MMU_XPE(3), MMU_SC(4), MMU_GLB(5) 4142 * ring 3: PM7(22), PM6(21), PM5(20), PM4(19), PM3(18), PM2(17), PM1(16), 4143 * PM0(15), PM31(46), PM30(45), PM29(44), PM28(43), PM27(42), 4144 * PM26(41), PM25(40), PM24(39), CLPORT32(55) 4145 * ring 4: PM32(11), PM8(23), PM9(24), PM10(25), PM11(26), PM12(27), 4146 * PM13(28), PM14(29), PM15(30), PM16(31), PM17(32), PM18(33), 4147 * PM19(34), PM20(35), PM21(36), PM22(37), PM23(38) 4148 * ring 5: OTPC(6), AVS(59), TOP(7), SER(8) 4149 */ 4150 4151 4152 #ifdef BCM_CMICX_SUPPORT 4153 if (soc_feature(unit, soc_feature_cmicx)) { 4154 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_0_7_OFFSET,0x52222100); 4155 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_8_15_OFFSET,0x30053005); 4156 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_16_23_OFFSET,0x43333333); 4157 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_24_31_OFFSET,0x64444444); 4158 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_32_39_OFFSET,0x76666666); 4159 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_40_47_OFFSET,0x07777777); 4160 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_48_55_OFFSET,0x00000000); 4161 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_56_63_OFFSET,0x00005000); 4162 soc_pci_write(unit, CMIC_TOP_SBUS_TIMEOUT_OFFSET,0x5000); 4163 } 4164 #endif 4165 4166 /* Reset all mHost processors */ 4167 SOC_IF_ERROR_RETURN(WRITE_MHOST_0_CR5_RST_CTRLr(unit, 0)); 4168 SOC_IF_ERROR_RETURN(WRITE_MHOST_1_CR5_RST_CTRLr(unit, 0)); 4169 /*Reset the common UARTs */ 4170 SOC_IF_ERROR_RETURN(WRITE_IPROCPERIPH_UART0_UART_SRRr(unit, 1)); 4171 SOC_IF_ERROR_RETURN(WRITE_IPROCPERIPH_UART1_UART_SRRr(unit, 1)); 4172 4173 sal_usleep(to_usec); 4174 4175 #if 1 4176 SOC_IF_ERROR_RETURN(soc_td3_frequency_init(unit)); 4177 #endif 4178 4179 /* Bring up TS PLL */ 4180 ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, auto_ref); 4181 index = (ref_freq == auto_ref) ? (COUNTOF(ts_pll_params) - 1) : 0; 4182 dco_code_target = dco_poison; 4183 4184 for (; index < COUNTOF(ts_pll_params); index++) { 4185 if (ref_freq != auto_ref && 4186 ts_pll_params[index].ref_freq != ref_freq) { 4187 continue; 4188 } 4189 4190 /* Place in reset */ 4191 SOC_IF_ERROR_RETURN 4192 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 4193 TOP_TS_PLL_RST_Lf, 0)); 4194 4195 /* Set N-divider value */ 4196 SOC_IF_ERROR_RETURN 4197 (soc_reg_field32_modify(unit, TOP_TS_PLL_CTRL_0r, REG_PORT_ANY, 4198 NDIV_INTf, ts_pll_params[index].ndiv)); 4199 4200 /* Select internal or external clock source */ 4201 SOC_IF_ERROR_RETURN 4202 (soc_reg_field32_modify(unit, TOP_TS_PLL_CTRL_2r, REG_PORT_ANY, 4203 REFCLK_SOURCE_SELf, 4204 ts_pll_params[index].ref_freq == 0 ? 0 : 1)); 4205 4206 /* Set new reference frequency info */ 4207 SOC_IF_ERROR_RETURN 4208 (soc_reg_field32_modify(unit, TOP_TS_PLL_CTRL_3r, REG_PORT_ANY, 4209 FREFEFF_INFOf, 4210 ts_pll_params[index].ref_freq_info)); 4211 4212 /* Take out of reset */ 4213 SOC_IF_ERROR_RETURN 4214 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 4215 TOP_TS_PLL_RST_Lf, 1)); 4216 4217 /* Give time to lock */ 4218 sal_usleep(to_usec); 4219 4220 /* Check PLL lock status */ 4221 reg = TOP_TS_PLL_STATUSr; 4222 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4223 if (SAL_BOOT_SIMULATION || 4224 soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 4225 if (ref_freq == auto_ref && dco_code_target == dco_poison) { 4226 /* If auto freq, get DCO value for later comparison */ 4227 SOC_IF_ERROR_RETURN( 4228 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_TS_PLL, 4229 &dco_code_target)); 4230 _soc_td3_pll_dco_normalize(&dco_code_target, 4231 ts_pll_params[index].ref_freq, 4232 ts_pll_params[index].ndiv); 4233 4234 /* Start iterating over all of the available frequencies */ 4235 index = -1; 4236 } else if (ref_freq == auto_ref) { 4237 /* Make sure the current DCO code is close to the target */ 4238 SOC_IF_ERROR_RETURN( 4239 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_TS_PLL, 4240 &dco_code)); 4241 4242 _soc_td3_pll_dco_normalize(&dco_code, 4243 ts_pll_params[index].ref_freq, 4244 ts_pll_params[index].ndiv); 4245 4246 if (dco_code >= (dco_code_target - 400) && 4247 dco_code <= (dco_code_target + 400)) { 4248 if (ts_pll_params[index].ref_freq) { 4249 LOG_WARN(BSL_LS_SOC_COMMON, 4250 (BSL_META_U(unit, 4251 "TS_PLL locked on unit %d using " 4252 "%d.%dMHz external reference clock\n" 4253 "Recommended to add \"%s=%u\" " 4254 "config variable\n"), 4255 unit, 4256 ts_pll_params[index].ref_freq / 1000000, 4257 ts_pll_params[index].ref_freq / 100000 % 10, 4258 spn_PTP_TS_PLL_FREF, 4259 ts_pll_params[index].ref_freq)); 4260 } else { 4261 LOG_WARN(BSL_LS_SOC_COMMON, 4262 (BSL_META_U(unit, "TS_PLL locked on unit %d using " 4263 "internal reference clock\n"), unit)); 4264 } 4265 break; 4266 } else { 4267 continue; 4268 } 4269 } else { 4270 /* PLL locked at desired frequency */ 4271 break; 4272 } 4273 } else if (ref_freq != auto_ref) { 4274 /* Not able to lock at desired frequency */ 4275 LOG_ERROR(BSL_LS_SOC_COMMON, 4276 (BSL_META_U(unit, 4277 "TS_PLL failed to lock on unit %d " 4278 "status = 0x%08x\n"), unit, rval)); 4279 return SOC_E_INIT; 4280 } 4281 } 4282 4283 /* Bring up BS0 PLL */ 4284 ref_freq = soc_property_suffix_num_get(unit, 0, spn_PTP_BS_FREF, 4285 &blank, auto_ref); 4286 index = (ref_freq == auto_ref) ? (COUNTOF(bs_pll_params) - 1) : 0; 4287 dco_code_target = dco_poison; 4288 4289 for (; index < COUNTOF(bs_pll_params); index++) { 4290 if (ref_freq != auto_ref && 4291 bs_pll_params[index].ref_freq != ref_freq) { 4292 continue; 4293 } 4294 4295 /* Place in reset */ 4296 SOC_IF_ERROR_RETURN 4297 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 4298 TOP_BS_PLL0_RST_Lf, 0)); 4299 4300 /* Set N-divider value */ 4301 SOC_IF_ERROR_RETURN 4302 (soc_reg_field32_modify(unit, TOP_BS_PLL0_CTRL_0r, REG_PORT_ANY, 4303 NDIV_INTf, bs_pll_params[index].ndiv)); 4304 4305 /* Select internal or external clock source */ 4306 SOC_IF_ERROR_RETURN 4307 (soc_reg_field32_modify(unit, TOP_BS_PLL0_CTRL_2r, REG_PORT_ANY, 4308 REFCLK_SOURCE_SELf, 4309 bs_pll_params[index].ref_freq == 0 ? 0 : 1)); 4310 4311 /* Set new reference frequency info */ 4312 SOC_IF_ERROR_RETURN 4313 (soc_reg_field32_modify(unit, TOP_BS_PLL0_CTRL_3r, REG_PORT_ANY, 4314 FREFEFF_INFOf, 4315 bs_pll_params[index].ref_freq_info)); 4316 4317 /* Take out of reset */ 4318 SOC_IF_ERROR_RETURN 4319 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 4320 TOP_BS_PLL0_RST_Lf, 1)); 4321 4322 /* Give time to lock */ 4323 sal_usleep(to_usec); 4324 4325 /* Check PLL lock status */ 4326 reg = TOP_TS_PLL_STATUSr; 4327 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4328 if (SAL_BOOT_SIMULATION || 4329 soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 4330 if (ref_freq == auto_ref && dco_code_target == dco_poison) { 4331 /* If auto freq, get DCO value for later comparison */ 4332 SOC_IF_ERROR_RETURN( 4333 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL0, 4334 &dco_code_target)); 4335 _soc_td3_pll_dco_normalize(&dco_code_target, 4336 bs_pll_params[index].ref_freq, 4337 bs_pll_params[index].ndiv); 4338 4339 /* Start iterating over all of the available frequencies */ 4340 index = -1; 4341 } else if (ref_freq == auto_ref) { 4342 /* Make sure the current DCO code is close to the target */ 4343 SOC_IF_ERROR_RETURN( 4344 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL0, 4345 &dco_code)); 4346 _soc_td3_pll_dco_normalize(&dco_code, 4347 bs_pll_params[index].ref_freq, 4348 bs_pll_params[index].ndiv); 4349 4350 /* LOG_WARN(BSL_LS_SOC_COMMON, 4351 (BSL_META_U(unit, 4352 "BS_PLL0: %d %d %d\n"), 4353 bs_pll_params[index].ref_freq, 4354 dco_code, 4355 dco_code_target)); */ 4356 4357 if (dco_code >= (dco_code_target - 400) && 4358 dco_code <= (dco_code_target + 400)) { 4359 if (bs_pll_params[index].ref_freq) { 4360 LOG_WARN(BSL_LS_SOC_COMMON, 4361 (BSL_META_U(unit, 4362 "BS_PLL0 locked on unit %d using " 4363 "%d.%dMHz external reference clock\n" 4364 "Recommended to add \"%s_0=%u\" " 4365 "config variable\n"), 4366 unit, 4367 bs_pll_params[index].ref_freq / 1000000, 4368 bs_pll_params[index].ref_freq / 100000 % 10, 4369 spn_PTP_BS_FREF, 4370 bs_pll_params[index].ref_freq)); 4371 } else { 4372 LOG_WARN(BSL_LS_SOC_COMMON, 4373 (BSL_META_U(unit, "BS_PLL0 locked on unit %d using " 4374 "internal reference clock\n"), unit)); 4375 } 4376 break; 4377 } else { 4378 continue; 4379 } 4380 } else { 4381 /* PLL locked at desired frequency */ 4382 break; 4383 } 4384 } else if (ref_freq != auto_ref) { 4385 /* Not able to lock at desired frequency */ 4386 LOG_ERROR(BSL_LS_SOC_COMMON, 4387 (BSL_META_U(unit, 4388 "BS_PLL0 failed to lock on unit %d " 4389 "status = 0x%08x\n"), unit, rval)); 4390 return SOC_E_INIT; 4391 } 4392 } 4393 4394 /* Bring up BS1 PLL */ 4395 ref_freq = soc_property_suffix_num_get(unit, 1, spn_PTP_BS_FREF, 4396 &blank, auto_ref); 4397 index = (ref_freq == auto_ref) ? (COUNTOF(bs_pll_params) - 1) : 0; 4398 dco_code_target = dco_poison; 4399 4400 for (; index < COUNTOF(bs_pll_params); index++) { 4401 if (ref_freq != auto_ref && 4402 bs_pll_params[index].ref_freq != ref_freq) { 4403 continue; 4404 } 4405 4406 /* Place in reset */ 4407 SOC_IF_ERROR_RETURN 4408 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 4409 TOP_BS_PLL1_RST_Lf, 0)); 4410 4411 /* Set N-divider value */ 4412 SOC_IF_ERROR_RETURN 4413 (soc_reg_field32_modify(unit, TOP_BS_PLL1_CTRL_0r, REG_PORT_ANY, 4414 NDIV_INTf, bs_pll_params[index].ndiv)); 4415 4416 /* Select internal or external clock source */ 4417 SOC_IF_ERROR_RETURN 4418 (soc_reg_field32_modify(unit, TOP_BS_PLL1_CTRL_2r, REG_PORT_ANY, 4419 REFCLK_SOURCE_SELf, 4420 bs_pll_params[index].ref_freq == 0 ? 0 : 1)); 4421 4422 /* Set new reference frequency info */ 4423 SOC_IF_ERROR_RETURN 4424 (soc_reg_field32_modify(unit, TOP_BS_PLL1_CTRL_3r, REG_PORT_ANY, 4425 FREFEFF_INFOf, 4426 bs_pll_params[index].ref_freq_info)); 4427 4428 /* Take out of reset */ 4429 SOC_IF_ERROR_RETURN 4430 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 4431 TOP_BS_PLL1_RST_Lf, 1)); 4432 4433 /* Give time to lock */ 4434 sal_usleep(to_usec); 4435 4436 /* Check PLL lock status */ 4437 reg = TOP_TS_PLL_STATUSr; 4438 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4439 if (SAL_BOOT_SIMULATION || 4440 soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 4441 if (ref_freq == auto_ref && dco_code_target == dco_poison) { 4442 /* If auto freq, get DCO value for later comparison */ 4443 SOC_IF_ERROR_RETURN( 4444 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL1, 4445 &dco_code_target)); 4446 _soc_td3_pll_dco_normalize(&dco_code_target, 4447 bs_pll_params[index].ref_freq, 4448 bs_pll_params[index].ndiv); 4449 4450 /* Start iterating over all of the available frequencies */ 4451 index = -1; 4452 } else if (ref_freq == auto_ref) { 4453 /* Make sure the current DCO code is close to the target */ 4454 SOC_IF_ERROR_RETURN( 4455 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL1, 4456 &dco_code)); 4457 _soc_td3_pll_dco_normalize(&dco_code, 4458 bs_pll_params[index].ref_freq, 4459 bs_pll_params[index].ndiv); 4460 4461 if (dco_code >= (dco_code_target - 400) && 4462 dco_code <= (dco_code_target + 400)) { 4463 if (bs_pll_params[index].ref_freq) { 4464 LOG_WARN(BSL_LS_SOC_COMMON, 4465 (BSL_META_U(unit, 4466 "BS_PLL1 locked on unit %d using " 4467 "%d.%dMHz external reference clock\n" 4468 "Recommended to add \"%s_1=%u\" " 4469 "config variable\n"), 4470 unit, 4471 bs_pll_params[index].ref_freq / 1000000, 4472 bs_pll_params[index].ref_freq / 100000 % 10, 4473 spn_PTP_BS_FREF, 4474 bs_pll_params[index].ref_freq)); 4475 } else { 4476 LOG_WARN(BSL_LS_SOC_COMMON, 4477 (BSL_META_U(unit, "BS_PLL1 locked on unit %d using " 4478 "internal reference clock\n"), unit)); 4479 } 4480 break; 4481 } else { 4482 continue; 4483 } 4484 } else { 4485 /* PLL locked at desired frequency */ 4486 break; 4487 } 4488 } else if (ref_freq != auto_ref) { 4489 /* Not able to lock at desired frequency */ 4490 LOG_ERROR(BSL_LS_SOC_COMMON, 4491 (BSL_META_U(unit, 4492 "BS_PLL1 failed to lock on unit %d " 4493 "status = 0x%08x\n"), unit, rval)); 4494 return SOC_E_INIT; 4495 } 4496 } 4497 4498 /* De-assert TS PLL, BS PLL0/1 post reset and bring AVS out of reset */ 4499 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 4500 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4501 TOP_TS_PLL_POST_RST_Lf, 1); 4502 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4503 TOP_BS_PLL0_POST_RST_Lf, 1); 4504 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4505 TOP_BS_PLL1_POST_RST_Lf, 1); 4506 soc_reg_field_set(unit,TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 4507 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 4508 4509 sal_usleep(to_usec); 4510 4511 /* Enable high temperature interrupt monitoring. 4512 * Default on: pvtmon[0-7] (enable all pvtmons). */ 4513 temp_mask = soc_property_get(unit, "temp_monitor_select", 4514 ((1 << COUNTOF(temp_thr_reg)) - 1)); 4515 /* The above is a 8 bit mask to indicate which temp sensor to hook up to 4516 * the interrupt. */ 4517 rval = 0; 4518 for (index = 0; index <COUNTOF(temp_thr_reg); index++) { 4519 uint32 trval; 4520 4521 /* Temp = 434.10 - o_ADC_data * 0.53504 4522 * data = (434.10 - temp)/0.53504 = (434100-(temp*1000))/535 4523 * Note: Since this is a high temp value we can safely assume it to 4524 * always be a +ive number. This is in degrees celcius. 4525 */ 4526 temp_thr = soc_property_get(unit, temp_thr_prop[index], 4527 _SOC_TD3_DEF_TEMP_MAX); 4528 if (temp_thr > _SOC_TD3_TEMP_MAX) { 4529 LOG_ERROR(BSL_LS_SOC_COMMON, 4530 (BSL_META_U(unit, 4531 "Unsupported temp value %d !! Max %d. Using %d.\n"), 4532 temp_thr, _SOC_TD3_TEMP_MAX, _SOC_TD3_DEF_TEMP_MAX)); 4533 temp_thr = _SOC_TD3_DEF_TEMP_MAX; 4534 } 4535 /* Convert temperature to config data */ 4536 temp_thr = (434100-(temp_thr*1000))/535; 4537 SOC_IF_ERROR_RETURN 4538 (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval)); 4539 soc_reg_field_set(unit, temp_thr_reg[index], &trval, MIN_THRESHOLDf, 4540 temp_thr); 4541 SOC_IF_ERROR_RETURN 4542 (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval)); 4543 if (temp_mask & (1 << index)) { 4544 rval |= (1 << ((index * 2) + 1)); /*2 bits per pvtmon, using min*/ 4545 } 4546 } 4547 soc_td3_temp_mon_mask[unit] = temp_mask; 4548 4549 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_INTR_MASKr(unit, rval)); 4550 /* Enable temp mon interrupt */ 4551 #ifdef BCM_CMICX_SUPPORT 4552 if (soc_feature(unit, soc_feature_cmicx)) { 4553 4554 /* (void)soc_cmicm_intr3_enable(unit, 0x4); PVTMON_INTR bit 2 */ 4555 } 4556 #endif 4557 4558 /* Bring port blocks out of reset */ 4559 rval = 0; 4560 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PM32_RST_Lf, 1); 4561 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1); 4562 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 4563 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, 0xffffffff)); 4564 sal_usleep(to_usec); 4565 4566 /* Bring IP, EP, and MMU blocks out of reset */ 4567 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 4568 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1); 4569 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1); 4570 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 4571 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 4572 4573 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 4574 if (parity_enable) { 4575 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 4576 REG_PORT_ANY, 4577 IS_TDM_ECC_ENf,1)); 4578 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 4579 REG_PORT_ANY, 4580 CA_CPU_ECC_ENABLEf,1)); 4581 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 4582 REG_PORT_ANY, 4583 CA_LPBK_ECC_ENABLEf,1)); 4584 } 4585 4586 sal_usleep(to_usec); 4587 SOC_IF_ERROR_RETURN(soc_trident3_init_idb_memory(unit)); 4588 SOC_IF_ERROR_RETURN(_soc_trident3_init_hash_control_reset(unit)); 4589 SOC_IF_ERROR_RETURN(soc_trident3_uft_uat_config(unit)); 4590 4591 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 4592 SOC_IF_ERROR_RETURN(soc_trident3_clear_all_memory(unit)); 4593 } 4594 4595 if (soc_feature(unit, soc_feature_turbo_boot)) { 4596 uint32 def_val = 0; 4597 4598 if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED)) { 4599 def_val = 1; 4600 } 4601 if (soc_property_get(unit, "clear_on_hw_resetting", def_val)) { 4602 SOC_HW_RESET_START(unit); 4603 } 4604 } 4605 4606 return SOC_E_NONE; 4607 } 4608 4609 4610 4611 int 4612 soc_trident3_port_reset(int unit) 4613 { 4614 int blk, port; 4615 uint32 rval; 4616 uint64 rval64; 4617 int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100; 4618 4619 if (soc_feature(unit, soc_feature_pm_refclk_master)) { 4620 soc_info_t *si = &SOC_INFO(unit); 4621 if (!SHR_BITNULL_RANGE(si->pm_ref_master_bitmap, 0, 4622 SOC_MAX_NUM_BLKS)) { 4623 soc_xgxs_reset_master_tsc(unit); 4624 } 4625 } 4626 4627 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 4628 port = SOC_BLOCK_PORT(unit, blk); 4629 4630 SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval)); 4631 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1); 4632 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 4633 sal_udelay(10); 4634 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 4635 if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, SYS_16B_INTF_MODEf) && 4636 soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) { 4637 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, SYS_16B_INTF_MODEf, 1); 4638 } 4639 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 4640 } 4641 4642 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 4643 port = SOC_BLOCK_PORT(unit, blk); 4644 4645 SOC_IF_ERROR_RETURN(soc_reg_get(unit, XLPORT_XGXS0_CTRL_REGr, 4646 port, 0, &rval64)); 4647 soc_reg64_field32_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval64, 4648 REFSELf, 3); 4649 SOC_IF_ERROR_RETURN(soc_reg_set(unit, XLPORT_XGXS0_CTRL_REGr, 4650 port, 0, rval64)); 4651 4652 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval)); 4653 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1); 4654 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 4655 sal_udelay(10); 4656 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 4657 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 4658 } 4659 4660 /* Power off CLPORT blocks */ 4661 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 4662 port = SOC_BLOCK_PORT(unit, blk); 4663 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1)); 4664 } 4665 sal_usleep(sleep_usec + 10000); 4666 /* Power on CLPORT blocks */ 4667 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 4668 port = SOC_BLOCK_PORT(unit, blk); 4669 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0)); 4670 } 4671 4672 /* Power off XLPORT blocks */ 4673 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 4674 port = SOC_BLOCK_PORT(unit, blk); 4675 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1)); 4676 } 4677 sal_usleep(sleep_usec + 10000); 4678 /* Power off XLPORT blocks */ 4679 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 4680 port = SOC_BLOCK_PORT(unit, blk); 4681 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0)); 4682 } 4683 return SOC_E_NONE; 4684 } 4685 4686 int 4687 soc_trident3_port_speed_update(int unit, soc_port_t port, int speed) 4688 { 4689 soc_info_t *si; 4690 soc_reg_t reg; 4691 soc_field_t field; 4692 uint32 rval, fval, mode; 4693 uint64 rval64; 4694 uint32 entry[SOC_MAX_MEM_WORDS]; 4695 int pipe, phy_port; 4696 int p, count = 1, ports[2] = {-1, -1}; 4697 #if defined(BCM_TD3_ASF_EXCLUDE) 4698 int class; 4699 #else 4700 int rv; 4701 #endif 4702 4703 static soc_field_t egr_reset_fields[] = { 4704 PM0_RESETf, PM1_RESETf, PM2_RESETf, PM3_RESETf, 4705 PM4_RESETf, PM5_RESETf, PM6_RESETf, PM7_RESETf 4706 }; 4707 4708 si = &SOC_INFO(unit); 4709 phy_port = si->port_l2p_mapping[port]; 4710 #if 0 4711 mmu_port = si->port_p2m_mapping[phy_port]; 4712 #endif 4713 pipe = si->port_pipe[port]; 4714 4715 /* Special handling for single lane and tri mode ports */ 4716 if (si->port_num_lanes[port] < 4) { 4717 /* Get the current mode */ 4718 SOC_IF_ERROR_RETURN(READ_CLPORT_MODE_REGr(unit, port, &rval)); 4719 mode = soc_reg_field_get(unit, CLPORT_MODE_REGr, rval, 4720 XPORT0_CORE_PORT_MODEf); 4721 4722 /* Figure out the number of ports that will be affected */ 4723 switch (mode) { 4724 case SOC_TD3_PORT_MODE_QUAD: 4725 count = 2; 4726 break; 4727 case SOC_TD3_PORT_MODE_TRI_012: 4728 count = SOC_PORT_BINDEX(unit, phy_port) > 1 ? 1 : 2; 4729 break; 4730 case SOC_TD3_PORT_MODE_TRI_023: 4731 count = SOC_PORT_BINDEX(unit, phy_port) > 1 ? 2 : 1; 4732 break; 4733 default: 4734 break; 4735 } 4736 4737 /* Setup the list of ports to be updated */ 4738 if (SOC_PORT_BINDEX(unit, phy_port) % 2) { 4739 ports[1] = port; 4740 ports[0] = si->port_l2p_mapping[phy_port-1]; 4741 } else { 4742 ports[0] = port; /* This will handle 2xdual lane mode as well */ 4743 ports[1] = si->port_l2p_mapping[phy_port+1]; 4744 } 4745 } else { 4746 ports[0] = port; 4747 } 4748 4749 /* Update MMU and EP credits */ 4750 /* De-assert EGR_ENABLE */ 4751 sal_memset(&entry, 0, sizeof(entry)); 4752 for (p = 0; p < count; p++) { 4753 if (ports[p] < 0) { 4754 continue; 4755 } 4756 SOC_IF_ERROR_RETURN 4757 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[ports[p]], &entry)); 4758 } 4759 4760 /* Clear MMU port credit before Resetting egress */ 4761 reg = MMU_PORT_CREDITr; 4762 for (p = 0; p < count; p++) { 4763 if (ports[p] < 0) { 4764 continue; 4765 } 4766 rval = 0; 4767 soc_reg_field_set(unit, reg, &rval, INITIALIZEf, 1); 4768 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, ports[p], 0, rval)); 4769 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, ports[p], 0, 0)); 4770 } 4771 4772 #if defined(BCM_TD3_ASF_EXCLUDE) 4773 if (IS_CL_PORT(unit, port)) { 4774 /* Update cut-through speed class */ 4775 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 4776 if (soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, ENABLEf)) { 4777 _soc_trident3_speed_to_ct_class_mapping(unit, speed, &class); 4778 4779 rval = 0; 4780 soc_reg_field_set(unit, ASF_IPORT_CFGr, &rval, ASF_PORT_SPEEDf, 4781 class); 4782 SOC_IF_ERROR_RETURN(WRITE_ASF_IPORT_CFGr(unit, port, rval)); 4783 4784 sal_memset(entry, 0, sizeof(egr_ip_cut_thru_class_entry_t)); 4785 soc_mem_field32_set(unit, EGR_IP_CUT_THRU_CLASSm, entry, 4786 CUT_THRU_CLASSf, class); 4787 SOC_IF_ERROR_RETURN 4788 (soc_mem_write(unit, EGR_IP_CUT_THRU_CLASSm, MEM_BLOCK_ALL, 4789 port, entry)); 4790 } 4791 } 4792 #endif 4793 4794 /* Updtae HSP port multicast T2OQ setting */ 4795 #if 0 4796 if (SOC_PBMP_MEMBER(si->eq_pbm, port)) { 4797 int inst; 4798 static soc_field_t t2oq_fields[] = { 4799 IS_MC_T2OQ_PORT0f, IS_MC_T2OQ_PORT1f 4800 }; 4801 reg = MMU_SCFG_TOQ_MC_CFG1r; 4802 inst = (pipe >> 1) | SOC_REG_ADDR_INSTANCE_MASK; 4803 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, 0, &rval)); 4804 field = t2oq_fields[pipe & 0x01]; 4805 fval = soc_reg_field_get(unit, reg, rval, field); 4806 if (speed >= 40000) { 4807 fval |= 1 << (mmu_port & 0x0f); 4808 } else { 4809 fval &= ~(1 << (mmu_port & 0x0f)); 4810 } 4811 soc_reg_field_set(unit, reg, &rval, field, fval); 4812 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval)); 4813 } 4814 #endif 4815 4816 #if !defined(BCM_TD3_ASF_EXCLUDE) 4817 if (soc_feature(unit, soc_feature_asf_multimode)) { 4818 rv = soc_td3_port_asf_mode_set(unit, port, 4819 speed, _SOC_TD3_ASF_MODE_CFG_UPDATE); 4820 if ((SOC_E_NONE != rv) && (SOC_E_UNAVAIL != rv)) { 4821 return rv; 4822 } 4823 } 4824 #endif 4825 4826 /* Reset egress hardware resource */ 4827 reg = SOC_REG_UNIQUE_ACC(unit, EGR_PORT_BUFFER_SFT_RESET_0r)[pipe]; 4828 field = egr_reset_fields[si->port_serdes[port] % 8]; 4829 if (4 == si->port_num_lanes[port]) { 4830 /* reset all 4 lanes */ 4831 fval = 4; 4832 } else if (SOC_PORT_BINDEX(unit, phy_port) < 2) { /* reset lanes 0 and 1 */ 4833 fval = 1; 4834 } else { /* reset lanes 2 and 3 */ 4835 fval = 2; 4836 } 4837 SOC_IF_ERROR_RETURN 4838 (soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 4839 soc_reg64_field32_set(unit, reg, &rval64, field, fval); 4840 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64)); 4841 soc_reg64_field32_set(unit, reg, &rval64, field, 0); 4842 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64)); 4843 4844 /* Enable egress */ 4845 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 4846 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 4847 for (p = 0; p < count; p++) { 4848 if (ports[p] < 0) { 4849 continue; 4850 } 4851 SOC_IF_ERROR_RETURN 4852 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[ports[p]], entry)); 4853 } 4854 return SOC_E_NONE; 4855 } 4856 4857 int 4858 soc_trident3_xpe_base_index_check(int unit, int base_type, int xpe, 4859 int base_index, char *msg) 4860 { 4861 soc_info_t *si; 4862 int pipe; 4863 uint32 map; 4864 char *base_name; 4865 4866 si = &SOC_INFO(unit); 4867 4868 if (xpe == -1 || base_index == -1) { 4869 return SOC_E_NONE; 4870 } 4871 4872 if (xpe < NUM_XPE(unit) && si->xpe_ipipe_map[xpe] == 0) { 4873 if (msg) { 4874 LOG_CLI((BSL_META_U(unit, 4875 "%s: XPE%d is not in config\n"), 4876 msg, xpe)); 4877 } 4878 return SOC_E_PARAM; 4879 } 4880 4881 switch (base_type) { 4882 case 0: /* IPORT */ 4883 case 1: /* EPORT */ 4884 base_name = base_type == 0 ? "IPORT" : "EPORT"; 4885 pipe = si->port_pipe[base_index]; 4886 if (pipe == -1) { 4887 if (msg) { 4888 LOG_CLI((BSL_META_U(unit, 4889 "%s: %s%d is not in config\n"), 4890 msg, base_name, base_index)); 4891 } 4892 } else if (xpe < NUM_XPE(unit)) { /* Unique access type */ 4893 map = base_type == 0 ? 4894 si->ipipe_xpe_map[pipe] : si->epipe_xpe_map[pipe]; 4895 if (map & (1 << xpe)) { 4896 break; 4897 } 4898 if (msg != NULL) { 4899 LOG_CLI((BSL_META_U(unit, 4900 "%s: %s%d is not in XPE%d\n"), 4901 msg, base_name, base_index, xpe)); 4902 } 4903 } else { 4904 break; 4905 } 4906 return SOC_E_PARAM; 4907 case 2: /* IPIPE */ 4908 case 3: /* EPIPE */ 4909 if (base_type == 2) { 4910 base_name = "IPIPE"; 4911 map = si->ipipe_xpe_map[base_index]; 4912 } else { 4913 base_name = "EPIPE"; 4914 map = si->epipe_xpe_map[base_index]; 4915 } 4916 if (map == 0) { 4917 if (msg) { 4918 LOG_CLI((BSL_META_U(unit, 4919 "%s: %s%d is not in config\n"), 4920 msg, base_name, base_index)); 4921 } 4922 } else if (xpe < NUM_XPE(unit)) { /* Unique access type */ 4923 if (map & (1 << xpe)) { 4924 break; 4925 } 4926 if (msg != NULL) { 4927 LOG_CLI((BSL_META_U(unit, 4928 "%s: %s%d is not in XPE%d\n"), 4929 msg, base_name, base_index, xpe)); 4930 } 4931 } else { 4932 break; 4933 } 4934 return SOC_E_PARAM; 4935 case 4: /* CHIP */ 4936 break; 4937 case 5: /* XPE */ 4938 if (si->xpe_ipipe_map[base_index] != 0) { 4939 break; 4940 } 4941 if (msg != NULL) { 4942 LOG_CLI((BSL_META_U(unit, 4943 "%s: XPE%d is not in config\n"), 4944 msg, base_index)); 4945 } 4946 return SOC_E_PARAM; 4947 case 6: /* SLICE */ 4948 if (si->sc_ipipe_map[base_index] == 0) { 4949 LOG_CLI((BSL_META_U(unit, 4950 "%s: SLICE%d is not in config\n"), 4951 msg, base_index)); 4952 } else if (xpe < NUM_XPE(unit)) { /* Unique access type */ 4953 if (xpe & 1) { /* XPE 1 and 3 are in slice 1 */ 4954 if (base_index == 1) { 4955 break; 4956 } 4957 } else { /* XPE 0 and 2 are in slice 0 */ 4958 if (base_index == 0) { 4959 break; 4960 } 4961 } 4962 if (msg != NULL) { 4963 LOG_CLI((BSL_META_U(unit, 4964 "%s: XPE%d is not in SLICE%d\n"), 4965 msg, xpe, base_index)); 4966 } 4967 } else { 4968 break; 4969 } 4970 return SOC_E_PARAM; 4971 case 7: /* LAYER */ 4972 if (xpe & 2) { /* XPE 2 and 3 are in layer 1 */ 4973 if (base_index == 1) { 4974 break; 4975 } 4976 } else { /* XPE 0 and 1 are in layer 0 */ 4977 if (base_index == 0) { 4978 break; 4979 } 4980 } 4981 if (msg) { 4982 LOG_CLI((BSL_META_U(unit, 4983 "%s: XPE%d is not in LAYER%d\n"), 4984 msg, xpe, base_index)); 4985 } 4986 return SOC_E_PARAM; 4987 } 4988 4989 return SOC_E_NONE; 4990 } 4991 4992 int soc_trident3_get_alpm_banks(int unit) 4993 { 4994 return num_shared_alpm_banks[unit]; 4995 } 4996 4997 int soc_trident3_set_alpm_banks(int unit, int banks) 4998 { 4999 num_shared_alpm_banks[unit] = banks; 5000 return 0; 5001 } 5002 5003 int soc_trident3_alpm_mode_get(int unit) 5004 { 5005 return _soc_alpm_mode[unit]; 5006 } 5007 5008 int soc_trident3_mem_basetype_get(int unit, soc_mem_t mem) 5009 { 5010 int base_type; 5011 5012 base_type = ((SOC_MEM_INFO(unit, mem).base) >> 23) & 0x7; 5013 return base_type; 5014 } 5015 5016 int soc_trident3_mem_is_xpe(int unit, soc_mem_t mem) 5017 { 5018 int block_info_index; 5019 5020 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 5021 5022 if (SOC_BLOCK_TYPE(unit, block_info_index) == SOC_BLK_MMU_XPE) { 5023 return 1; 5024 } else { 5025 return 0; 5026 } 5027 } 5028 5029 /* Function to check if given XPE/PIPE combo matches for the given mem's base 5030 * type definition. 5031 */ 5032 int 5033 soc_trident3_mem_xpe_pipe_check(int unit, soc_mem_t mem, int xpe, int pipe) 5034 { 5035 int rv = SOC_E_NONE; 5036 int block_info_index, base_type; 5037 5038 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 5039 if (SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_XPE) { 5040 return SOC_E_PARAM; 5041 } 5042 5043 base_type = soc_trident3_mem_basetype_get(unit, mem); 5044 rv = soc_trident3_xpe_base_index_check(unit, base_type, xpe, pipe, NULL); 5045 5046 if (rv == SOC_E_PARAM) { 5047 rv = SOC_E_UNAVAIL; 5048 } 5049 5050 return rv; 5051 } 5052 5053 STATIC int 5054 _soc_trident3_xpe_reg_check(int unit, soc_reg_t reg, int xpe, int base_index) 5055 { 5056 int acc_type, base_type; 5057 5058 if (!SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, SOC_BLK_MMU_XPE)) { 5059 LOG_CLI((BSL_META_U(unit, 5060 "%s is not XPE register\n"), SOC_REG_NAME(unit, reg))); 5061 return SOC_E_PARAM; 5062 } 5063 5064 if (SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { /* UNIQUE base register */ 5065 if (xpe == -1 || xpe >= NUM_XPE(unit)) { 5066 LOG_CLI((BSL_META_U(unit, 5067 "%s bad XPE value %d\n"), 5068 SOC_REG_NAME(unit, reg), xpe)); 5069 return SOC_E_PARAM; 5070 } 5071 } else { 5072 acc_type = SOC_REG_ACC_TYPE(unit, reg); 5073 if (acc_type < NUM_XPE(unit)) { /* UNIQUE per XPE register */ 5074 if (xpe != acc_type) { 5075 LOG_CLI((BSL_META_U(unit, 5076 "Ovveride XPE value %d with ACC_TYPE of %s\n"), 5077 xpe, SOC_REG_NAME(unit, reg))); 5078 } 5079 xpe = acc_type; 5080 } else { /* non-UNIQUE register */ 5081 return SOC_E_NONE; 5082 } 5083 } 5084 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 5085 5086 return soc_trident3_xpe_base_index_check(unit, base_type, xpe, base_index, 5087 SOC_REG_NAME(unit, reg)); 5088 } 5089 5090 #if 0 5091 STATIC int 5092 _soc_trident3_xpe_mem_check(int unit, soc_mem_t mem, int xpe, int base_index) 5093 { 5094 int block_info_index, acc_type, base_type; 5095 5096 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 5097 if (SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_XPE) { 5098 LOG_CLI((BSL_META_U(unit, 5099 "%s is not XPE register\n"), SOC_MEM_NAME(unit, mem))); 5100 return SOC_E_PARAM; 5101 } 5102 5103 if (SOC_MEM_UNIQUE_ACC(unit, mem) != NULL) { /* UNIQUE base memory */ 5104 if (xpe == -1 || xpe >= NUM_XPE(unit)) { 5105 LOG_CLI((BSL_META_U(unit, 5106 "%s bad XPE value %d\n"), 5107 SOC_MEM_NAME(unit, mem), xpe)); 5108 return SOC_E_PARAM; 5109 } 5110 } else { 5111 acc_type = SOC_MEM_ACC_TYPE(unit, mem); 5112 if (acc_type < NUM_XPE(unit)) { /* UNIQUE per XPE memory */ 5113 if (xpe != acc_type) { 5114 LOG_CLI((BSL_META_U(unit, 5115 "Ovveride XPE value %d with ACC_TYPE of %s\n"), 5116 xpe, SOC_MEM_NAME(unit, mem))); 5117 xpe = acc_type; 5118 } 5119 } else { /* non-UNIQUE memory */ 5120 return SOC_E_NONE; 5121 } 5122 } 5123 base_type = ((SOC_MEM_INFO(unit, mem).base) >> 23) & 0x7; 5124 5125 return soc_trident3_xpe_base_index_check(unit, base_type, xpe, base_index, 5126 SOC_MEM_NAME(unit, mem)); 5127 } 5128 #endif 5129 5130 /* 5131 * Parameters for soc_trident3_xpe_reg_access and soc_trident3_xpe_mem_access: 5132 * 5133 * base unique reg/ xpe write action read action 5134 * index type mem 5135 * ==== ====== ===== === ================ ================= 5136 * #1 -1 no - - all XPEs/pipes first pipe in the first XPE 5137 * #2 -1 yes base -1 (same as #1) 5138 * #3 -1 yes base 0-3 all pipes in the XPE first pipe in the XPE 5139 * #4 -1 yes xpe0-3 - (same as #3) 5140 * #5 0-3 no - - applicable XPEs first XPE has the pipe 5141 * #6 0-3 yes base -1 (same as #5) 5142 * #7 0-3 yes base 0-3 the XPE/pipe the XPE/pipe 5143 * #8 0-3 yes xpe0-3 - (same as #7) 5144 * 5145 * - S/W will loop through base types (i.e. pipes) if base_index==-1 5146 * - S/W will loop through applicable XPEs if xpe==-1 on unique access type 5147 * base view (H/W will do the loop for other access types) 5148 * - base_index will be ignored if the table does not have multiple sections 5149 * for example ACC_TYPE==UNIQUE BASE_TYPE==XPE 5150 */ 5151 STATIC int 5152 _soc_trident3_xpe_reg_access(int unit, soc_reg_t reg, int xpe, int base_index, 5153 int index, uint64 *data, int write) 5154 { 5155 soc_info_t *si; 5156 soc_reg_t orig_reg; 5157 int port; 5158 int base_type, break_after_first; 5159 int base_index_count; 5160 uint32 base_index_map, xpe_map=0; 5161 soc_pbmp_t base_index_pbmp; 5162 uint32 inst; 5163 5164 si = &SOC_INFO(unit); 5165 orig_reg = reg; 5166 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 5167 break_after_first = TRUE; 5168 5169 if (xpe >= 0 && base_index >= 0) { 5170 SOC_IF_ERROR_RETURN 5171 (_soc_trident3_xpe_reg_check(unit, reg, xpe, base_index)); 5172 } 5173 5174 switch (base_type) { 5175 case 0: /* IPORT */ 5176 case 1: /* EPORT */ 5177 if (xpe >= 0 && SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { 5178 reg = SOC_REG_UNIQUE_ACC(unit, reg)[xpe]; 5179 } 5180 5181 if (base_index == -1) { 5182 SOC_PBMP_ASSIGN(base_index_pbmp, PBMP_ALL(unit)); 5183 } else { 5184 /* This argument is logical port, same as soc_reg_get/set */ 5185 SOC_PBMP_PORT_SET(base_index_pbmp, base_index); 5186 } 5187 5188 SOC_PBMP_ITER(base_index_pbmp, port) { 5189 /* Loop through XPE(s) only on UNIQUE type base register */ 5190 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 5191 if (base_index < -1) { 5192 return SOC_E_PARAM; 5193 } else if (base_index == -1) { 5194 xpe_map = 0xf; 5195 } else { 5196 xpe_map = base_type == 0 ? 5197 si->ipipe_xpe_map[base_index] : 5198 si->epipe_xpe_map[base_index]; 5199 } 5200 if (write) { 5201 break_after_first = FALSE; 5202 } 5203 } 5204 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5205 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 5206 if (!(xpe_map & (1 << xpe))) { 5207 continue; 5208 } 5209 reg = SOC_REG_UNIQUE_ACC(unit, orig_reg)[xpe]; 5210 } 5211 if (write) { 5212 SOC_IF_ERROR_RETURN 5213 (soc_reg_set(unit, reg, port, index, *data)); 5214 } else { 5215 SOC_IF_ERROR_RETURN 5216 (soc_reg_get(unit, reg, port, index, data)); 5217 } 5218 if (break_after_first) { 5219 break; 5220 } 5221 } 5222 } 5223 break; 5224 case 2: /* IPIPE */ 5225 case 3: /* EPIPE */ 5226 if (xpe >= 0 && SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { 5227 reg = SOC_REG_UNIQUE_ACC(unit, reg)[xpe]; 5228 } 5229 5230 soc_trident3_pipe_map_get(unit, &base_index_map); 5231 if (base_index != -1) { 5232 base_index_map &= 1 << base_index; 5233 if (base_index_map == 0) { 5234 return SOC_E_PARAM; 5235 } 5236 } 5237 5238 for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) { 5239 if (!(base_index_map & (1 << base_index))) { 5240 continue; 5241 } 5242 /* Loop through XPE(s) only on UNIQUE type base register */ 5243 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 5244 xpe_map = base_type == 2 ? 5245 si->ipipe_xpe_map[base_index] : 5246 si->epipe_xpe_map[base_index]; 5247 if (write) { 5248 break_after_first = FALSE; 5249 } 5250 } 5251 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5252 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 5253 if (!(xpe_map & (1 << xpe))) { 5254 continue; 5255 } 5256 reg = SOC_REG_UNIQUE_ACC(unit, orig_reg)[xpe]; 5257 } 5258 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5259 if (write) { 5260 SOC_IF_ERROR_RETURN 5261 (soc_reg_set(unit, reg, inst, index, *data)); 5262 } else { 5263 SOC_IF_ERROR_RETURN 5264 (soc_reg_get(unit, reg, inst, index, data)); 5265 } 5266 if (break_after_first) { 5267 break; 5268 } 5269 } 5270 } 5271 break; 5272 case 4: /* CHIP */ 5273 if (write) { 5274 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, 0, index, *data)); 5275 } else { 5276 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, 0, index, data)); 5277 } 5278 break; 5279 case 5: /* XPE */ 5280 if (xpe >= 0 && SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { 5281 reg = SOC_REG_UNIQUE_ACC(unit, reg)[xpe]; 5282 } 5283 5284 if (SOC_REG_UNIQUE_ACC(unit, reg) != NULL || 5285 SOC_REG_ACC_TYPE(unit, reg) < NUM_XPE(unit)) { 5286 base_index_map = 1; 5287 } else if (base_index == -1) { 5288 base_index_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5289 } else { 5290 base_index_map = 1 << base_index; 5291 } 5292 5293 /* Loop through XPE(s) only on UNIQUE type base register */ 5294 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 5295 xpe_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5296 break_after_first = FALSE; 5297 } 5298 5299 for (base_index = 0; base_index < NUM_XPE(unit); base_index++) { 5300 if (!(base_index_map & (1 << base_index))) { 5301 continue; 5302 } 5303 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5304 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 5305 if (!(xpe_map & (1 << xpe))) { 5306 continue; 5307 } 5308 reg = SOC_REG_UNIQUE_ACC(unit, orig_reg)[xpe]; 5309 } 5310 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5311 if (write) { 5312 SOC_IF_ERROR_RETURN 5313 (soc_reg_set(unit, reg, inst, index, *data)); 5314 } else { 5315 SOC_IF_ERROR_RETURN 5316 (soc_reg_get(unit, reg, inst, index, data)); 5317 } 5318 if (break_after_first) { 5319 break; 5320 } 5321 } 5322 } 5323 break; 5324 case 6: /* SLICE */ 5325 case 7: /* LAYER */ 5326 /* No unique access type for such base_type */ 5327 if (base_index == -1) { 5328 base_index_map = base_type == 6 ? si->ipipe_sc_map[0] : 0x3; 5329 } else { 5330 base_index_map = 1 << base_index; 5331 } 5332 5333 base_index_count = base_type == 6 ? NUM_SLICE(unit) : NUM_LAYER(unit); 5334 for (base_index = 0; base_index < base_index_count; base_index++) { 5335 if (!(base_index_map & (1 << base_index))) { 5336 continue; 5337 } 5338 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5339 if (write) { 5340 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5341 } else { 5342 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5343 } 5344 } 5345 break; 5346 /* No default case as base_type can have value only between 0-7 */ 5347 } 5348 5349 return SOC_E_NONE; 5350 } 5351 #if 0 5352 STATIC int 5353 _soc_trident3_xpe_mem_access(int unit, soc_mem_t mem, int xpe, int base_index, 5354 int copyno, int offset_in_section, 5355 void *entry_data, int write) 5356 { 5357 soc_info_t *si; 5358 soc_mem_t orig_mem; 5359 int index, section_size; 5360 int base_type, break_after_first; 5361 uint32 base_index_map, xpe_map=0; 5362 5363 si = &SOC_INFO(unit); 5364 orig_mem = mem; 5365 base_type = ((SOC_MEM_INFO(unit, mem).base) >> 23) & 0x7; 5366 section_size = SOC_MEM_INFO(unit, mem).section_size; 5367 break_after_first = TRUE; 5368 5369 if (xpe >= 0 && base_index >= 0) { 5370 SOC_IF_ERROR_RETURN 5371 (_soc_trident3_xpe_mem_check(unit, mem, xpe, base_index)); 5372 } 5373 5374 switch (base_type) { 5375 case 2: /* IPIPE */ 5376 case 3: /* EPIPE */ 5377 if (xpe >= 0 && SOC_MEM_UNIQUE_ACC(unit, mem) != NULL) { 5378 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[xpe]; 5379 } 5380 5381 /* All tables with such base_type should have multiple sections */ 5382 soc_trident3_pipe_map_get(unit, &base_index_map); 5383 if (base_index != -1) { 5384 base_index_map &= 1 << base_index; 5385 if (base_index_map == 0) { 5386 return SOC_E_PARAM; 5387 } 5388 } 5389 5390 for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) { 5391 if (!(base_index_map & (1 << base_index))) { 5392 continue; 5393 } 5394 /* Loop through XPE(s) only on UNIQUE type base memory */ 5395 if (SOC_MEM_UNIQUE_ACC(unit, orig_mem) != NULL) { 5396 xpe_map = base_type == 2 ? 5397 si->ipipe_xpe_map[base_index] : 5398 si->epipe_xpe_map[base_index]; 5399 if (write) { 5400 break_after_first = FALSE; 5401 } 5402 } 5403 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5404 if (SOC_MEM_UNIQUE_ACC(unit, orig_mem) != NULL) { 5405 if (!(xpe_map & (1 << xpe))) { 5406 continue; 5407 } 5408 mem = SOC_MEM_UNIQUE_ACC(unit, orig_mem)[xpe]; 5409 } 5410 index = base_index * section_size + offset_in_section; 5411 if (write) { 5412 SOC_IF_ERROR_RETURN 5413 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5414 } else { 5415 SOC_IF_ERROR_RETURN 5416 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5417 } 5418 if (break_after_first) { 5419 break; 5420 } 5421 } 5422 } 5423 break; 5424 case 4: /* CHIP */ 5425 index = offset_in_section; 5426 if (write) { 5427 SOC_IF_ERROR_RETURN 5428 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5429 } else { 5430 SOC_IF_ERROR_RETURN 5431 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5432 } 5433 break; 5434 case 5: /* XPE */ 5435 if (xpe >= 0 && SOC_MEM_UNIQUE_ACC(unit, mem) != NULL) { 5436 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[xpe]; 5437 } 5438 5439 if (SOC_MEM_UNIQUE_ACC(unit, mem) != NULL || 5440 SOC_MEM_ACC_TYPE(unit, mem) < NUM_XPE(unit)) { 5441 /* Single section table handling for unique acc_type */ 5442 base_index_map = 1; 5443 } else if (base_index == -1) { 5444 base_index_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5445 } else { 5446 base_index_map = 1 << base_index; 5447 } 5448 5449 /* Loop through XPE(s) only on UNIQUE type base memory */ 5450 if (SOC_MEM_UNIQUE_ACC(unit, mem) != NULL) { 5451 xpe_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5452 break_after_first = FALSE; 5453 } 5454 5455 for (base_index = 0; base_index < NUM_XPE(unit); base_index++) { 5456 if (!(base_index_map & (1 << base_index))) { 5457 continue; 5458 } 5459 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5460 if (SOC_MEM_UNIQUE_ACC(unit, orig_mem) != NULL) { 5461 if (!(xpe_map & (1 << xpe))) { 5462 continue; 5463 } 5464 mem = SOC_MEM_UNIQUE_ACC(unit, orig_mem)[xpe]; 5465 } 5466 index = base_index * section_size + offset_in_section; 5467 if (write) { 5468 SOC_IF_ERROR_RETURN 5469 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5470 } else { 5471 SOC_IF_ERROR_RETURN 5472 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5473 } 5474 if (break_after_first) { 5475 break; 5476 } 5477 } 5478 } 5479 break; 5480 case 6: /* SLICE */ 5481 /* No unique access type for such base_type */ 5482 if (base_index == -1) { 5483 base_index_map = si->ipipe_sc_map[0]; 5484 } else { 5485 base_index_map = 1 << base_index; 5486 } 5487 5488 for (base_index = 0; base_index < NUM_SLICE(unit); base_index++) { 5489 if (!(base_index_map & (1 << base_index))) { 5490 continue; 5491 } 5492 index = base_index * section_size + offset_in_section; 5493 if (write) { 5494 SOC_IF_ERROR_RETURN 5495 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5496 } else { 5497 SOC_IF_ERROR_RETURN 5498 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5499 } 5500 } 5501 break; 5502 case 0: /* IPORT */ 5503 case 1: /* EPORT */ 5504 case 7: /* LAYER */ 5505 default: 5506 return SOC_E_INTERNAL; 5507 } 5508 5509 return SOC_E_NONE; 5510 } 5511 #endif 5512 int 5513 soc_trident3_sc_base_index_check(int unit, int base_type, int sc, 5514 int base_index, char *msg) 5515 { 5516 soc_info_t *si; 5517 int pipe; 5518 uint32 map; 5519 char *base_name; 5520 5521 si = &SOC_INFO(unit); 5522 5523 if (sc == -1 || base_index == -1) { 5524 return SOC_E_NONE; 5525 } 5526 5527 if (sc < NUM_SLICE(unit) && si->sc_ipipe_map[sc] == 0) { 5528 if (msg) { 5529 LOG_CLI((BSL_META_U(unit, 5530 "%s: SC%d is not in config\n"), 5531 msg, sc)); 5532 } 5533 return SOC_E_PARAM; 5534 } 5535 5536 switch (base_type) { 5537 case 0: /* IPORT */ 5538 case 1: /* EPORT */ 5539 base_name = base_type == 0 ? "IPORT" : "EPORT"; 5540 pipe = si->port_pipe[base_index]; 5541 if (pipe == -1) { 5542 if (msg) { 5543 LOG_CLI((BSL_META_U(unit, 5544 "%s: %s%d is not in config\n"), 5545 msg, base_name, base_index)); 5546 } 5547 } else if (sc < NUM_SLICE(unit)) { /* Unique access type */ 5548 map = base_type == 0 ? 5549 si->ipipe_sc_map[pipe] : si->epipe_sc_map[pipe]; 5550 if (map & (1 << sc)) { 5551 break; 5552 } 5553 if (msg != NULL) { 5554 LOG_CLI((BSL_META_U(unit, 5555 "%s: %s%d is not in SC%d\n"), 5556 msg, base_name, base_index, sc)); 5557 } 5558 } else { 5559 break; 5560 } 5561 return SOC_E_PARAM; 5562 case 2: /* IPIPE */ 5563 case 3: /* EPIPE */ 5564 if (base_type == 2) { 5565 base_name = "IPIPE"; 5566 map = si->ipipe_sc_map[base_index]; 5567 } else { 5568 base_name = "EPIPE"; 5569 map = si->epipe_sc_map[base_index]; 5570 } 5571 if (map == 0) { 5572 if (msg) { 5573 LOG_CLI((BSL_META_U(unit, 5574 "%s: %s%d is not in config\n"), 5575 msg, base_name, base_index)); 5576 } 5577 } else if (sc < NUM_SLICE(unit)) { /* Unique access type */ 5578 if (map & (1 << sc)) { 5579 break; 5580 } 5581 if (msg != NULL) { 5582 LOG_CLI((BSL_META_U(unit, 5583 "%s: %s%d is not in SC%d\n"), 5584 msg, base_name, base_index, sc)); 5585 } 5586 } else { 5587 break; 5588 } 5589 return SOC_E_PARAM; 5590 case 4: /* CHIP */ 5591 break; 5592 case 5: /* XPE */ 5593 if (si->xpe_ipipe_map[base_index] == 0) { 5594 if (msg != NULL) { 5595 LOG_CLI((BSL_META_U(unit, 5596 "%s: XPE%d is not in config\n"), 5597 msg, base_index)); 5598 } 5599 } else if (sc < NUM_SLICE(unit)) { /* Unique access type */ 5600 if (sc == 0) { /* XPE 0 and 2 are in slice 0 */ 5601 if (base_index == 0 || base_index == 2) { 5602 break; 5603 } 5604 } else { /* XPE 1 and 3 are in slice 1 */ 5605 if (base_index == 1 || base_index == 3) { 5606 break; 5607 } 5608 } 5609 if (msg != NULL) { 5610 LOG_CLI((BSL_META_U(unit, 5611 "%s: XPE%d is not in SLICE%d\n"), 5612 msg, base_index, sc)); 5613 } 5614 } else { 5615 break; 5616 } 5617 return SOC_E_PARAM; 5618 case 6: /* SLICE */ 5619 case 7: /* LAYER, not used */ 5620 break; 5621 } 5622 5623 return SOC_E_NONE; 5624 } 5625 5626 STATIC int 5627 _soc_trident3_sc_reg_check(int unit, soc_reg_t reg, int sc, int base_index) 5628 { 5629 int acc_type, base_type; 5630 5631 if (!SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, SOC_BLK_MMU_SC)) { 5632 LOG_CLI((BSL_META_U(unit, 5633 "%s is not SC register\n"), SOC_REG_NAME(unit, reg))); 5634 return SOC_E_PARAM; 5635 } 5636 5637 if (SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { /* UNIQUE base register */ 5638 if (sc == -1 || sc >= NUM_SLICE(unit)) { 5639 LOG_CLI((BSL_META_U(unit, 5640 "%s bad SC value %d\n"), 5641 SOC_REG_NAME(unit, reg), sc)); 5642 return SOC_E_PARAM; 5643 } 5644 } else { 5645 acc_type = SOC_REG_ACC_TYPE(unit, reg); 5646 if (acc_type < NUM_SLICE(unit)) { /* UNIQUE per SC register */ 5647 if (sc != acc_type) { 5648 LOG_CLI((BSL_META_U(unit, 5649 "Ovveride SC value %d with ACC_TYPE of %s\n"), 5650 sc, SOC_REG_NAME(unit, reg))); 5651 } 5652 sc = acc_type; 5653 } else { /* non-UNIQUE register */ 5654 return SOC_E_NONE; 5655 } 5656 } 5657 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 5658 5659 return soc_trident3_sc_base_index_check(unit, base_type, sc, base_index, 5660 SOC_REG_NAME(unit, reg)); 5661 } 5662 5663 #if 0 5664 STATIC int 5665 _soc_trident3_sc_mem_check(int unit, soc_mem_t mem, int sc, int base_index) 5666 { 5667 int block_info_index, acc_type, base_type; 5668 5669 block_info_index = SOC_MEM_BLOCK_ANY(unit, mem); 5670 if (SOC_BLOCK_TYPE(unit, block_info_index) != SOC_BLK_MMU_SC) { 5671 LOG_CLI((BSL_META_U(unit, 5672 "%s is not SC register\n"), SOC_MEM_NAME(unit, mem))); 5673 return SOC_E_PARAM; 5674 } 5675 5676 if (SOC_MEM_UNIQUE_ACC(unit, mem) != NULL) { /* UNIQUE base memory */ 5677 if (sc == -1 || sc >= NUM_SLICE(unit)) { 5678 LOG_CLI((BSL_META_U(unit, 5679 "%s bad SC value %d\n"), 5680 SOC_MEM_NAME(unit, mem), sc)); 5681 return SOC_E_PARAM; 5682 } 5683 } else { 5684 acc_type = SOC_MEM_ACC_TYPE(unit, mem); 5685 if (acc_type < NUM_SLICE(unit)) { /* UNIQUE per SC memory */ 5686 if (sc != acc_type) { 5687 LOG_CLI((BSL_META_U(unit, 5688 "Ovveride SC value %d with ACC_TYPE of %s\n"), 5689 sc, SOC_MEM_NAME(unit, mem))); 5690 sc = acc_type; 5691 } 5692 } else { /* non-UNIQUE memory */ 5693 return SOC_E_NONE; 5694 } 5695 } 5696 base_type = ((SOC_MEM_INFO(unit, mem).base) >> 23) & 0x7; 5697 5698 return soc_trident3_sc_base_index_check(unit, base_type, sc, base_index, 5699 SOC_MEM_NAME(unit, mem)); 5700 } 5701 #endif 5702 5703 STATIC int 5704 _soc_trident3_sc_reg_access(int unit, soc_reg_t reg, int sc, int base_index, 5705 int index, uint64 *data, int write) 5706 { 5707 soc_info_t *si; 5708 int port; 5709 int base_type; 5710 uint32 base_index_map; 5711 soc_pbmp_t base_index_pbmp; 5712 uint32 inst; 5713 5714 si = &SOC_INFO(unit); 5715 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 5716 5717 if (sc >= 0 && base_index >= 0) { 5718 SOC_IF_ERROR_RETURN 5719 (_soc_trident3_sc_reg_check(unit, reg, sc, base_index)); 5720 } 5721 5722 switch (base_type) { 5723 case 0: /* IPORT */ 5724 case 1: /* EPORT */ 5725 /* No unique access type for such base_type */ 5726 if (base_index == -1) { 5727 SOC_PBMP_ASSIGN(base_index_pbmp, PBMP_ALL(unit)); 5728 } else { 5729 /* This argument is logical port, same as soc_reg_get/set */ 5730 SOC_PBMP_PORT_SET(base_index_pbmp, base_index); 5731 } 5732 5733 SOC_PBMP_ITER(base_index_pbmp, port) { 5734 if (write) { 5735 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, index, *data)); 5736 } else { 5737 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, index, data)); 5738 } 5739 } 5740 break; 5741 case 2: /* IPIPE */ 5742 case 3: /* EPIPE */ 5743 /* No unique access type for such base_type */ 5744 soc_trident3_pipe_map_get(unit, &base_index_map); 5745 if (base_index != -1) { 5746 base_index_map &= 1 << base_index; 5747 if (base_index_map == 0) { 5748 return SOC_E_PARAM; 5749 } 5750 } 5751 5752 for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) { 5753 if (!(base_index_map & (1 << base_index))) { 5754 continue; 5755 } 5756 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5757 if (write) { 5758 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5759 } else { 5760 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5761 } 5762 } 5763 break; 5764 case 4: /* CHIP */ 5765 if (write) { 5766 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, 0, index, *data)); 5767 } else { 5768 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, 0, index, data)); 5769 } 5770 break; 5771 case 5: /* XPE */ 5772 /* No unique access type for such base_type */ 5773 if (base_index == -1) { 5774 base_index_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5775 } else { 5776 base_index_map = 1 << base_index; 5777 } 5778 5779 for (base_index = 0; base_index < NUM_SLICE(unit); base_index++) { 5780 if (!(base_index_map & (1 << base_index))) { 5781 continue; 5782 } 5783 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5784 if (write) { 5785 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5786 } else { 5787 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5788 } 5789 } 5790 break; 5791 case 6: /* SLICE */ 5792 if (sc >= 0 && SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { 5793 reg = SOC_REG_UNIQUE_ACC(unit, reg)[sc]; 5794 } 5795 if (base_index == -1) { 5796 base_index_map = si->ipipe_sc_map[0];; 5797 } else { 5798 base_index_map = 1 << base_index; 5799 } 5800 for (base_index = 0; base_index < NUM_SLICE(unit); base_index++) { 5801 if (!(base_index_map & (1 << base_index))) { 5802 continue; 5803 } 5804 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5805 if (write) { 5806 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5807 } else { 5808 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5809 } 5810 } 5811 break; 5812 case 7: /* LAYER */ 5813 default: 5814 return SOC_E_INTERNAL; 5815 } 5816 5817 return SOC_E_NONE; 5818 } 5819 #if 0 5820 STATIC int 5821 _soc_trident3_sc_mem_access(int unit, soc_mem_t mem, int sc, int base_index, 5822 int copyno, int offset_in_section, void *entry_data, 5823 int write) 5824 { 5825 soc_info_t *si; 5826 soc_mem_t orig_mem; 5827 int index, section_size; 5828 int base_type, break_after_first; 5829 uint32 base_index_map, sc_map=0; 5830 5831 si = &SOC_INFO(unit); 5832 orig_mem = mem; 5833 base_type = ((SOC_MEM_INFO(unit, mem).base) >> 23) & 0x7; 5834 section_size = SOC_MEM_INFO(unit, mem).section_size; 5835 break_after_first = TRUE; 5836 5837 if (sc >= 0 && base_index >= 0) { 5838 SOC_IF_ERROR_RETURN 5839 (_soc_trident3_sc_mem_check(unit, mem, sc, base_index)); 5840 } 5841 5842 switch (base_type) { 5843 case 2: /* IPIPE */ 5844 case 3: /* EPIPE */ 5845 if (sc >= 0 && SOC_MEM_UNIQUE_ACC(unit, mem) != NULL) { 5846 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[sc]; 5847 } 5848 5849 /* All tables with such base_type should have multiple sections */ 5850 soc_trident3_pipe_map_get(unit, &base_index_map); 5851 if (base_index != -1) { 5852 base_index_map &= 1 << base_index; 5853 if (base_index_map == 0) { 5854 return SOC_E_PARAM; 5855 } 5856 } 5857 5858 for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) { 5859 if (!(base_index_map & (1 << base_index))) { 5860 continue; 5861 } 5862 /* Loop through SC(s) only on UNIQUE type base memory */ 5863 if (SOC_MEM_UNIQUE_ACC(unit, orig_mem) != NULL) { 5864 sc_map = base_type == 2 ? 5865 si->ipipe_sc_map[base_index] : 5866 si->epipe_sc_map[base_index]; 5867 if (write) { 5868 break_after_first = FALSE; 5869 } 5870 } 5871 for (sc = 0; sc < NUM_SLICE(unit); sc++) { 5872 if (SOC_MEM_UNIQUE_ACC(unit, orig_mem) != NULL) { 5873 if (!(sc_map & (1 << sc))) { 5874 continue; 5875 } 5876 mem = SOC_MEM_UNIQUE_ACC(unit, orig_mem)[sc]; 5877 } 5878 index = base_index * section_size + offset_in_section; 5879 if (write) { 5880 SOC_IF_ERROR_RETURN 5881 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5882 } else { 5883 SOC_IF_ERROR_RETURN 5884 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5885 } 5886 if (break_after_first) { 5887 break; 5888 } 5889 } 5890 } 5891 break; 5892 case 5: /* XPE */ 5893 /* No unique access type for such base_type */ 5894 if (base_index == -1) { 5895 base_index_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5896 } else { 5897 base_index_map = 1 << base_index; 5898 } 5899 5900 for (base_index = 0; base_index < NUM_SLICE(unit); base_index++) { 5901 if (!(base_index_map & (1 << base_index))) { 5902 continue; 5903 } 5904 index = base_index * section_size + offset_in_section; 5905 if (write) { 5906 SOC_IF_ERROR_RETURN 5907 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5908 } else { 5909 SOC_IF_ERROR_RETURN 5910 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5911 } 5912 } 5913 break; 5914 case 6: /* SLICE */ 5915 /* No unique access type for such base_type */ 5916 if (base_index == -1) { 5917 base_index_map = si->ipipe_sc_map[0]; 5918 } else { 5919 base_index_map = 1 << base_index; 5920 } 5921 for (base_index = 0; base_index < NUM_SLICE(unit); base_index++) { 5922 if (!(base_index_map & (1 << base_index))) { 5923 continue; 5924 } 5925 index = base_index * section_size + offset_in_section; 5926 if (write) { 5927 SOC_IF_ERROR_RETURN 5928 (soc_mem_write(unit, mem, copyno, index, entry_data)); 5929 } else { 5930 SOC_IF_ERROR_RETURN 5931 (soc_mem_read(unit, mem, copyno, index, entry_data)); 5932 } 5933 } 5934 break; 5935 case 0: /* IPORT */ 5936 case 1: /* EPORT */ 5937 case 4: /* CHIP */ 5938 case 7: /* LAYER */ 5939 default: 5940 return SOC_E_INTERNAL; 5941 } 5942 5943 return SOC_E_NONE; 5944 } 5945 #endif 5946 5947 int 5948 soc_trident3_sed_base_index_check(int unit, int base_type, int sed, 5949 int base_index, char *msg) 5950 { 5951 soc_info_t *si; 5952 int pipe; 5953 uint32 map; 5954 char *base_name; 5955 5956 si = &SOC_INFO(unit); 5957 5958 if (sed == -1 || base_index == -1) { 5959 return SOC_E_NONE; 5960 } 5961 5962 if (sed < NUM_SED(unit) && si->sed_ipipe_map[sed] == 0) { 5963 if (msg) { 5964 LOG_CLI((BSL_META_U(unit, 5965 "%s: SED%d is not in config\n"), 5966 msg, sed)); 5967 } 5968 return SOC_E_PARAM; 5969 } 5970 5971 switch (base_type) { 5972 case 0: /* IPORT */ 5973 case 1: /* EPORT */ 5974 base_name = base_type == 0 ? "IPORT" : "EPORT"; 5975 pipe = si->port_pipe[base_index]; 5976 if (pipe == -1) { 5977 if (msg) { 5978 LOG_CLI((BSL_META_U(unit, 5979 "%s: %s%d is not in config\n"), 5980 msg, base_name, base_index)); 5981 } 5982 } else if (sed < NUM_SED(unit)) { /* Unique access type */ 5983 map = base_type == 0 ? 5984 si->ipipe_sed_map[pipe] : si->epipe_sed_map[pipe]; 5985 if (map & (1 << sed)) { 5986 break; 5987 } 5988 if (msg != NULL) { 5989 LOG_CLI((BSL_META_U(unit, 5990 "%s: %s%d is not in SED%d\n"), 5991 msg, base_name, base_index, sed)); 5992 } 5993 } else { 5994 break; 5995 } 5996 return SOC_E_PARAM; 5997 case 2: /* IPIPE */ 5998 case 3: /* EPIPE */ 5999 if (base_type == 2) { 6000 base_name = "IPIPE"; 6001 map = si->ipipe_sed_map[base_index]; 6002 } else { 6003 base_name = "EPIPE"; 6004 map = si->epipe_sed_map[base_index]; 6005 } 6006 if (map == 0) { 6007 if (msg) { 6008 LOG_CLI((BSL_META_U(unit, 6009 "%s: %s%d is not in config\n"), 6010 msg, base_name, base_index)); 6011 } 6012 } else if (sed < NUM_SED(unit)) { /* Unique access type */ 6013 if (map & (1 << sed)) { 6014 break; 6015 } 6016 if (msg != NULL) { 6017 LOG_CLI((BSL_META_U(unit, 6018 "%s: %s%d is not in SED%d\n"), 6019 msg, base_name, base_index, sed)); 6020 } 6021 } else { 6022 break; 6023 } 6024 return SOC_E_PARAM; 6025 case 4: /* CHIP */ 6026 break; 6027 case 5: /* XPE */ 6028 if (si->xpe_ipipe_map[base_index] == 0) { 6029 if (msg != NULL) { 6030 LOG_CLI((BSL_META_U(unit, 6031 "%s: XPE%d is not in config\n"), 6032 msg, base_index)); 6033 } 6034 } else if (sed < NUM_SED(unit)) { /* Unique access type */ 6035 if (sed == 0) { /* XPE 0 and 2 are in slice 0 */ 6036 if (base_index == 0 || base_index == 2) { 6037 break; 6038 } 6039 } else { /* XPE 1 and 3 are in slice 1 */ 6040 if (base_index == 1 || base_index == 3) { 6041 break; 6042 } 6043 } 6044 if (msg != NULL) { 6045 LOG_CLI((BSL_META_U(unit, 6046 "%s: XPE%d is not in SLICE%d\n"), 6047 msg, base_index, sed)); 6048 } 6049 } else { 6050 break; 6051 } 6052 return SOC_E_PARAM; 6053 case 6: /* SLICE */ 6054 case 7: /* LAYER, not used */ 6055 break; 6056 } 6057 6058 return SOC_E_NONE; 6059 } 6060 6061 STATIC int 6062 _soc_trident3_sed_reg_check(int unit, soc_reg_t reg, int sed, int base_index) 6063 { 6064 int acc_type, base_type; 6065 6066 if (!SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, SOC_BLK_MMU_SED)) { 6067 LOG_CLI((BSL_META_U(unit, 6068 "%s is not SED register\n"), SOC_REG_NAME(unit, reg))); 6069 return SOC_E_PARAM; 6070 } 6071 6072 if (SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { /* UNIQUE base register */ 6073 if (sed == -1 || sed >= NUM_SED(unit)) { 6074 LOG_CLI((BSL_META_U(unit, 6075 "%s bad SED value %d\n"), 6076 SOC_REG_NAME(unit, reg), sed)); 6077 return SOC_E_PARAM; 6078 } 6079 } else { 6080 acc_type = SOC_REG_ACC_TYPE(unit, reg); 6081 if (acc_type < NUM_SED(unit)) { /* UNIQUE per SED register */ 6082 if (sed != acc_type) { 6083 LOG_CLI((BSL_META_U(unit, 6084 "Override SED value %d with ACC_TYPE of %s\n"), 6085 sed, SOC_REG_NAME(unit, reg))); 6086 } 6087 sed = acc_type; 6088 } else { /* non-UNIQUE register */ 6089 return SOC_E_NONE; 6090 } 6091 } 6092 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 6093 6094 return soc_trident3_sed_base_index_check(unit, base_type, sed, base_index, 6095 SOC_REG_NAME(unit, reg)); 6096 } 6097 STATIC int 6098 _soc_trident3_sed_reg_access(int unit, soc_reg_t reg, int sed, int base_index, 6099 int index, uint64 *data, int write) 6100 { 6101 soc_info_t *si; 6102 soc_reg_t orig_reg; 6103 int port; 6104 int base_type, break_after_first; 6105 int base_index_count; 6106 uint32 base_index_map; 6107 soc_pbmp_t base_index_pbmp; 6108 uint32 inst; 6109 6110 si = &SOC_INFO(unit); 6111 orig_reg = reg; 6112 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 6113 break_after_first = TRUE; 6114 6115 if (sed >= 0 && base_index >= 0) { 6116 SOC_IF_ERROR_RETURN 6117 (_soc_trident3_sed_reg_check(unit, reg, sed, base_index)); 6118 } 6119 6120 switch (base_type) { 6121 case 0: /* IPORT */ 6122 case 1: /* EPORT */ 6123 if (base_index == -1) { 6124 SOC_PBMP_ASSIGN(base_index_pbmp, PBMP_ALL(unit)); 6125 } else { 6126 /* This argument is logical port, same as soc_reg_get/set */ 6127 SOC_PBMP_PORT_SET(base_index_pbmp, base_index); 6128 } 6129 6130 SOC_PBMP_ITER(base_index_pbmp, port) { 6131 if (write) { 6132 SOC_IF_ERROR_RETURN 6133 (soc_reg_set(unit, reg, port, index, *data)); 6134 } else { 6135 SOC_IF_ERROR_RETURN 6136 (soc_reg_get(unit, reg, port, index, data)); 6137 } 6138 } 6139 break; 6140 case 2: /* IPIPE */ 6141 case 3: /* EPIPE */ 6142 if (sed >= 0 && SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { 6143 reg = SOC_REG_UNIQUE_ACC(unit, reg)[sed]; 6144 } 6145 6146 soc_trident3_pipe_map_get(unit, &base_index_map); 6147 if (base_index != -1) { 6148 base_index_map &= 1 << base_index; 6149 if (base_index_map == 0) { 6150 return SOC_E_PARAM; 6151 } 6152 } 6153 6154 for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) { 6155 if (!(base_index_map & (1 << base_index))) { 6156 continue; 6157 } 6158 if (SOC_REG_UNIQUE_ACC(unit, orig_reg) != NULL) { 6159 reg = SOC_REG_UNIQUE_ACC(unit, orig_reg)[sed]; 6160 } 6161 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 6162 if (write) { 6163 SOC_IF_ERROR_RETURN 6164 (soc_reg_set(unit, reg, inst, index, *data)); 6165 } else { 6166 SOC_IF_ERROR_RETURN 6167 (soc_reg_get(unit, reg, inst, index, data)); 6168 } 6169 if (break_after_first) { 6170 break; 6171 } 6172 } 6173 break; 6174 case 4: /* CHIP */ 6175 if (write) { 6176 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, 0, index, *data)); 6177 } else { 6178 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, 0, index, data)); 6179 } 6180 break; 6181 case 5: /* XPE */ 6182 if (base_index == -1) { 6183 base_index_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 6184 } else { 6185 base_index_map = 1 << base_index; 6186 } 6187 for (base_index = 0; base_index < NUM_XPE(unit); base_index++) { 6188 if (!(base_index_map & (1 << base_index))) { 6189 continue; 6190 } 6191 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 6192 if (write) { 6193 SOC_IF_ERROR_RETURN 6194 (soc_reg_set(unit, reg, inst, index, *data)); 6195 } else { 6196 SOC_IF_ERROR_RETURN 6197 (soc_reg_get(unit, reg, inst, index, data)); 6198 } 6199 } 6200 break; 6201 case 6: /* SLICE */ 6202 case 7: /* LAYER */ 6203 /* No unique access type for such base_type */ 6204 if (base_index == -1) { 6205 base_index_map = base_type == 6 ? si->ipipe_sc_map[0] : 0x3; 6206 } else { 6207 base_index_map = 1 << base_index; 6208 } 6209 6210 base_index_count = base_type == 6 ? NUM_SLICE(unit) : NUM_LAYER(unit); 6211 for (base_index = 0; base_index < base_index_count; base_index++) { 6212 if (!(base_index_map & (1 << base_index))) { 6213 continue; 6214 } 6215 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 6216 if (write) { 6217 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 6218 } else { 6219 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 6220 } 6221 } 6222 break; 6223 /* No default case as base_type can have value only between 0-7 */ 6224 } 6225 6226 return SOC_E_NONE; 6227 } 6228 6229 6230 int 6231 soc_trident3_xpe_reg32_set(int unit, soc_reg_t reg, int xpe, int base_index, 6232 int index, uint32 data) 6233 { 6234 uint64 data64; 6235 6236 COMPILER_64_SET(data64, 0, data); 6237 SOC_IF_ERROR_RETURN(_soc_trident3_xpe_reg_access(unit, reg, xpe, base_index, 6238 index, &data64, TRUE)); 6239 6240 return SOC_E_NONE; 6241 } 6242 6243 int 6244 soc_trident3_xpe_reg32_get(int unit, soc_reg_t reg, int xpe, int base_index, 6245 int index, uint32 *data) 6246 { 6247 uint64 data64; 6248 6249 COMPILER_64_SET(data64, 0, *data); 6250 SOC_IF_ERROR_RETURN(_soc_trident3_xpe_reg_access(unit, reg, xpe, base_index, 6251 index, &data64, FALSE)); 6252 *data = COMPILER_64_LO(data64); 6253 6254 return SOC_E_NONE; 6255 } 6256 6257 int 6258 soc_trident3_xpe_reg_set(int unit, soc_reg_t reg, int xpe, int base_index, 6259 int index, uint64 data) 6260 { 6261 return _soc_trident3_xpe_reg_access(unit, reg, xpe, base_index, 6262 index, &data, TRUE); 6263 } 6264 6265 int 6266 soc_trident3_xpe_reg_get(int unit, soc_reg_t reg, int xpe, int base_index, 6267 int index, uint64 *data) 6268 { 6269 return _soc_trident3_xpe_reg_access(unit, reg, xpe, base_index, 6270 index, data, FALSE); 6271 } 6272 #if 0 6273 int 6274 soc_trident3_xpe_mem_write(int unit, soc_mem_t mem, int xpe, int base_index, 6275 int copyno, int offset_in_section, void *entry_data) 6276 { 6277 return _soc_trident3_xpe_mem_access(unit, mem, xpe, base_index, copyno, 6278 offset_in_section, entry_data, TRUE); 6279 } 6280 6281 int 6282 soc_trident3_xpe_mem_read(int unit, soc_mem_t mem, int xpe, int base_index, 6283 int copyno, int offset_in_section, void *entry_data) 6284 { 6285 return _soc_trident3_xpe_mem_access(unit, mem, xpe, base_index, copyno, 6286 offset_in_section, entry_data, FALSE); 6287 } 6288 #endif 6289 int 6290 soc_trident3_sc_reg32_set(int unit, soc_reg_t reg, int sc, int base_index, 6291 int index, uint32 data) 6292 { 6293 uint64 data64; 6294 6295 COMPILER_64_SET(data64, 0, data); 6296 SOC_IF_ERROR_RETURN(_soc_trident3_sc_reg_access(unit, reg, sc, base_index, 6297 index, &data64, TRUE)); 6298 6299 return SOC_E_NONE; 6300 } 6301 6302 int 6303 soc_trident3_sc_reg32_get(int unit, soc_reg_t reg, int sc, int base_index, 6304 int index, uint32 *data) 6305 { 6306 uint64 data64; 6307 6308 COMPILER_64_SET(data64, 0, *data); 6309 SOC_IF_ERROR_RETURN(_soc_trident3_sc_reg_access(unit, reg, sc, base_index, 6310 index, &data64, FALSE)); 6311 *data = COMPILER_64_LO(data64); 6312 6313 return SOC_E_NONE; 6314 } 6315 6316 int 6317 soc_trident3_sc_reg_set(int unit, soc_reg_t reg, int sc, int base_index, 6318 int index, uint64 data) 6319 { 6320 return _soc_trident3_sc_reg_access(unit, reg, sc, base_index, 6321 index, &data, TRUE); 6322 } 6323 6324 int 6325 soc_trident3_sc_reg_get(int unit, soc_reg_t reg, int sc, int base_index, 6326 int index, uint64 *data) 6327 { 6328 return _soc_trident3_sc_reg_access(unit, reg, sc, base_index, 6329 index, data, FALSE); 6330 } 6331 #if 0 6332 int 6333 soc_trident3_sc_mem_write(int unit, soc_mem_t mem, int sc, int base_index, 6334 int copyno, int offset_in_section, void *entry_data) 6335 { 6336 return _soc_trident3_sc_mem_access(unit, mem, sc, base_index, copyno, 6337 offset_in_section, entry_data, TRUE); 6338 } 6339 6340 int 6341 soc_trident3_sc_mem_read(int unit, soc_mem_t mem, int sc, int base_index, 6342 int copyno, int offset_in_section, void *entry_data) 6343 { 6344 return _soc_trident3_sc_mem_access(unit, mem, sc, base_index, copyno, 6345 offset_in_section, entry_data, FALSE); 6346 } 6347 #endif 6348 6349 int 6350 soc_trident3_sed_reg32_set(int unit, soc_reg_t reg, int sed, int base_index, 6351 int index, uint32 data) 6352 { 6353 uint64 data64; 6354 6355 COMPILER_64_SET(data64, 0, data); 6356 SOC_IF_ERROR_RETURN(_soc_trident3_sed_reg_access(unit, reg, sed, base_index, 6357 index, &data64, TRUE)); 6358 6359 return SOC_E_NONE; 6360 } 6361 6362 int 6363 soc_trident3_sed_reg32_get(int unit, soc_reg_t reg, int sed, int base_index, 6364 int index, uint32 *data) 6365 { 6366 uint64 data64; 6367 6368 COMPILER_64_SET(data64, 0, *data); 6369 SOC_IF_ERROR_RETURN(_soc_trident3_sed_reg_access(unit, reg, sed, base_index, 6370 index, &data64, FALSE)); 6371 *data = COMPILER_64_LO(data64); 6372 6373 return SOC_E_NONE; 6374 } 6375 6376 int 6377 soc_trident3_sed_reg_set(int unit, soc_reg_t reg, int sed, int base_index, 6378 int index, uint64 data) 6379 { 6380 return _soc_trident3_sed_reg_access(unit, reg, sed, base_index, 6381 index, &data, TRUE); 6382 } 6383 6384 int 6385 soc_trident3_sed_reg_get(int unit, soc_reg_t reg, int sed, int base_index, 6386 int index, uint64 *data) 6387 { 6388 return _soc_trident3_sed_reg_access(unit, reg, sed, base_index, 6389 index, data, FALSE); 6390 } 6391 6392 6393 #if defined(BCM_TD3_ASF_EXCLUDE) 6394 int 6395 soc_trident3_cut_through_update(int unit, soc_port_t port, int enable) 6396 { 6397 soc_info_t *si; 6398 _soc_trident3_tdm_temp_t *tdm; 6399 int pipe, class, index; 6400 uint32 entry[SOC_MAX_MEM_WORDS]; 6401 int *start_count; 6402 static int start_count_saf[13] = 6403 { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18 }; 6404 static int start_count_linerate[13] = 6405 { 18, 27, 27, 21, 21, 18, 18, 12, 12, 12, 12, 15, 15 }; 6406 static int start_count_oversub_2_1[13] = 6407 { 18, 57, 57, 51, 51, 45, 45, 39, 39, 33, 33, 33, 33 }; 6408 static int start_count_oversub_3_2[13] = 6409 { 18, 45, 45, 39, 39, 36, 36, 27, 27, 24, 24, 24, 24 }; 6410 6411 si = &SOC_INFO(unit); 6412 tdm = SOC_CONTROL(unit)->tdm_info; 6413 6414 if (enable) { 6415 if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 6416 pipe = si->port_pipe[port]; 6417 if (tdm->ovs_ratio_x1000[pipe][0] + tdm->ovs_ratio_x1000[pipe][1] > 1500) { 6418 /* More than 3:2 oversubscription ratio */ 6419 start_count = start_count_oversub_2_1; 6420 } else { 6421 start_count = start_count_oversub_3_2; 6422 } 6423 } else { 6424 start_count = start_count_linerate; 6425 } 6426 } else { 6427 start_count = start_count_saf; 6428 } 6429 6430 sal_memset(entry, 0, sizeof(egr_xmit_start_count_entry_t)); 6431 for (class = 0; class < 13; class++) { 6432 soc_mem_field32_set(unit, EGR_XMIT_START_COUNTm, entry, THRESHOLDf, 6433 start_count[class]); 6434 index = (port % 66) * 16 + class; 6435 SOC_IF_ERROR_RETURN 6436 (WRITE_EGR_XMIT_START_COUNTm(unit, MEM_BLOCK_ALL, index, entry)); 6437 } 6438 6439 return SOC_E_NONE; 6440 } 6441 #endif 6442 6443 int 6444 _soc_trident3_init_mmu_memory(int unit) 6445 { 6446 uint32 rval = 0; 6447 int alloc_size; 6448 6449 if (_fwd_ctrl_lock[unit] == NULL) { 6450 _fwd_ctrl_lock[unit] = sal_mutex_create("_fwd_ctrl_lock"); 6451 } 6452 if (_fwd_ctrl_lock[unit] == NULL) { 6453 return SOC_E_MEMORY; 6454 } 6455 6456 if (_soc_td3_mmu_traffic_ctrl[unit] == NULL) { 6457 alloc_size = sizeof(_soc_td3_mmu_traffic_ctrl_t); 6458 _soc_td3_mmu_traffic_ctrl[unit] = 6459 sal_alloc(alloc_size,"_soc_td3_mmu_traffic_ctrl"); 6460 if (_soc_td3_mmu_traffic_ctrl[unit] == NULL) { 6461 return SOC_E_MEMORY; 6462 } 6463 sal_memset(_soc_td3_mmu_traffic_ctrl[unit], 0, alloc_size); 6464 } 6465 6466 /* Initialize MMU memory */ 6467 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, 0)); 6468 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, 1); 6469 /* Need to assert PARITY_EN before setting INIT_MEM to start memory initialization */ 6470 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 6471 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, INIT_MEMf, 1); 6472 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 6473 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, INIT_MEMf, 0); 6474 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 6475 sal_usleep(20); 6476 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, 0); 6477 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 6478 return SOC_E_NONE; 6479 } 6480 6481 int 6482 soc_trident3_clear_mmu_memory(int unit) 6483 { 6484 #define SOC_MMU_BASE_TYPE_IPORT 0 6485 #define SOC_MMU_BASE_TYPE_EPORT 1 6486 #define SOC_MMU_BASE_TYPE_IPIPE 2 6487 #define SOC_MMU_BASE_TYPE_EPIPE 3 6488 #define SOC_MMU_BASE_TYPE_CHIP 4 6489 #define SOC_MMU_BASE_TYPE_XPE 5 6490 #define SOC_MMU_BASE_TYPE_SC 6 6491 #define SOC_MMU_BASE_TYPE_LAYER 7 6492 int i, j, use_base_type_views, base_type, index, num_views; 6493 uint32 entry[SOC_MAX_MEM_WORDS]; 6494 soc_mem_t mem; 6495 static const struct { 6496 soc_mem_t mem; /* base view */ 6497 int use_base_type_views; /* 1 means use xpe/sc/etc views */ 6498 int index; /* -1 means clear entire mem */ 6499 } mem_list[] = { 6500 { MMU_CBPDATA0m, 1, 0 }, 6501 { MMU_CBPDATA32m, 1, 0 }, 6502 { MMU_CBPDATA64m, 1, 0 }, 6503 { MMU_CBPDATA96m, 1, 0 }, 6504 { MMU_CBPDATA128m, 1, 0 }, 6505 { MMU_CBPDATA160m, 1, 0 }, 6506 { MMU_CBPDATA192m, 1, 0 }, 6507 { MMU_CBPDATA224m, 1, 0 }, 6508 { MMU_CBPDATA256m, 1, 0 }, 6509 { MMU_CBPDATA288m, 1, 0 }, 6510 { INVALIDm, 0, -1 } 6511 }; 6512 for (i = 0; mem_list[i].mem != INVALIDm; i++) { 6513 mem = mem_list[i].mem; 6514 if (!SOC_MEM_IS_VALID(unit, mem)) { 6515 continue; 6516 } 6517 6518 index = mem_list[i].index; 6519 use_base_type_views = mem_list[i].use_base_type_views; 6520 if (use_base_type_views) { 6521 base_type = soc_trident3_mem_basetype_get(unit, mem); 6522 switch (base_type) { 6523 case SOC_MMU_BASE_TYPE_XPE: 6524 num_views = NUM_XPE(unit); 6525 break; 6526 case SOC_MMU_BASE_TYPE_SC: 6527 num_views = NUM_SLICE(unit); 6528 break; 6529 case SOC_MMU_BASE_TYPE_LAYER: 6530 num_views = NUM_LAYER(unit); 6531 break; 6532 case SOC_MMU_BASE_TYPE_IPIPE: 6533 case SOC_MMU_BASE_TYPE_EPIPE: 6534 num_views = NUM_PIPE(unit); 6535 break; 6536 default: 6537 num_views = -1; /* not supported */ 6538 break; 6539 } 6540 if (num_views < 0) { 6541 LOG_ERROR(BSL_LS_SOC_COMMON, 6542 (BSL_META_U(unit, 6543 "mmu_mem %s, base_type %d will not be" 6544 "cleared \n"), 6545 SOC_MEM_NAME(unit,mem), base_type)); 6546 continue; 6547 } 6548 } else { 6549 num_views = 0; /* dont_care */ 6550 } 6551 6552 sal_memset(entry, 0x0, 6553 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 6554 if (use_base_type_views) { 6555 for (j = 0; j < num_views; j++) { 6556 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6557 (BSL_META_U(unit, 6558 "mmu_mem %s, index %d will be " 6559 "cleared \n"), 6560 SOC_MEM_NAME(unit, SOC_MEM_UNIQUE_ACC(unit, mem)[j]), 6561 index)); 6562 if (index >= 0) { 6563 SOC_IF_ERROR_RETURN 6564 (soc_mem_write(unit, 6565 SOC_MEM_UNIQUE_ACC(unit, mem)[j], 6566 MEM_BLOCK_ALL, index, entry)); 6567 } else { 6568 SOC_IF_ERROR_RETURN 6569 (soc_mem_clear(unit, 6570 SOC_MEM_UNIQUE_ACC(unit, mem)[j], 6571 COPYNO_ALL, TRUE)); 6572 } 6573 } 6574 } else { 6575 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6576 (BSL_META_U(unit, 6577 "mmu_mem %s, index %d will be " 6578 "cleared \n"), 6579 SOC_MEM_NAME(unit, mem), index)); 6580 if (index >= 0) { 6581 SOC_IF_ERROR_RETURN 6582 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 6583 entry)); 6584 } else { 6585 SOC_IF_ERROR_RETURN 6586 (soc_mem_clear(unit, mem, COPYNO_ALL, TRUE)); 6587 } 6588 } 6589 } 6590 return SOC_E_NONE; 6591 } 6592 6593 STATIC int 6594 _soc_trident3_port_mapping_init(int unit) 6595 { 6596 soc_info_t *si; 6597 int port, phy_port, idb_port; 6598 int num_port, num_phy_port; 6599 soc_reg_t reg; 6600 soc_mem_t mem; 6601 uint32 rval; 6602 uint32 entry[SOC_MAX_MEM_WORDS]; 6603 int pipe; 6604 6605 /* 6606 * 96 entries MMU_CHFC_SYSPORT_MAPPINGm.SYS_PORT 6607 * 256 entries SYS_PORTMAPm.DEVICE_PORT_NUMBER 6608 */ 6609 6610 si = &SOC_INFO(unit); 6611 6612 num_port = soc_mem_index_count(unit, ING_DEVICE_PORTm) - 1; 6613 num_phy_port = TD3_NUM_PHY_PORT; 6614 6615 /* Ingress physical to device port mapping */ 6616 sal_memset(&entry, 0, 6617 sizeof(ing_idb_to_device_port_number_mapping_table_entry_t)); 6618 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 6619 port = si->port_p2l_mapping[phy_port]; 6620 if (port != -1) { 6621 pipe = si->port_pipe[port]; 6622 idb_port = si->port_l2i_mapping[port]; 6623 } else if (phy_port >= 130) { /* loopback port (130 and 131 in TD3) */ 6624 pipe = phy_port - 130; 6625 idb_port = 65; 6626 } else if (phy_port == 129) { /* management port 0 (if not in use) */ 6627 pipe = 1; 6628 idb_port = 64; 6629 } else { 6630 pipe = (phy_port - 1) / _TD3_PORTS_PER_PIPE; 6631 idb_port = (phy_port -1 ) % _TD3_PORTS_PER_PIPE; 6632 } 6633 mem = SOC_MEM_UNIQUE_ACC 6634 (unit, ING_IDB_TO_DEVICE_PORT_NUMBER_MAPPING_TABLEm)[pipe]; 6635 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, 6636 port == -1 ? 0xff : port); 6637 SOC_IF_ERROR_RETURN 6638 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry)); 6639 } 6640 6641 /* Ingress GPP port to device port mapping */ 6642 mem = SYS_PORTMAPm; 6643 sal_memset(&entry, 0, sizeof(sys_portmap_entry_t)); 6644 for (port = 0; port < num_port; port++) { 6645 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port); 6646 SOC_IF_ERROR_RETURN 6647 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, port, &entry)); 6648 } 6649 6650 /* Ingress device port to GPP port mapping 6651 * PORT_TAB.SRC_SYS_PORT_ID is programmed in the general port config 6652 * init routine _bcm_fb_port_cfg_init() 6653 */ 6654 6655 /* Egress device port to physical port mapping */ 6656 rval = 0; 6657 reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr; 6658 PBMP_ALL_ITER(unit, port) { 6659 soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf, 6660 si->port_l2p_mapping[port]); 6661 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 6662 } 6663 6664 /* MMU port to physical port mapping */ 6665 rval = 0; 6666 reg = MMU_PORT_TO_PHY_PORT_MAPPINGr; 6667 PBMP_ALL_ITER(unit, port) { 6668 soc_reg_field_set(unit, reg, &rval, PHY_PORTf, 6669 si->port_l2p_mapping[port]); 6670 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 6671 } 6672 6673 /* MMU port to system port mapping */ 6674 rval = 0; 6675 reg = MMU_PORT_TO_SYSTEM_PORT_MAPPINGr; 6676 PBMP_ALL_ITER(unit, port) { 6677 soc_reg_field_set(unit, reg, &rval, SYSTEM_PORTf, port); 6678 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 6679 } 6680 6681 return SOC_E_NONE; 6682 } 6683 6684 /* 6685 * Function: 6686 * soc_trident3_latency_config 6687 * Purpose: 6688 * Configure latency in SLOT_PIPELINE_CONFIG register 6689 * Parameters: 6690 * unit (IN) - switch unit 6691 * Returns: 6692 * SOC_E_* 6693 */ 6694 6695 int 6696 soc_trident3_latency_config(int unit) 6697 { 6698 soc_reg_t reg; 6699 uint32 rval; 6700 uint32 latency, pipe_latency_full = 467; 6701 int frequency, dpp_clk_ratio_x10; 6702 soc_info_t *si = &SOC_INFO(unit); 6703 6704 frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, si->frequency); 6705 dpp_clk_ratio_x10 = (frequency > CCLK_FREQ_1012MHZ)? 15:10; 6706 6707 reg = SLOT_PIPELINE_CONFIGr; 6708 rval = 0; 6709 latency = (pipe_latency_full * dpp_clk_ratio_x10 / 10) - 6 + 5; 6710 if ((dpp_clk_ratio_x10 == 15) && (pipe_latency_full % 2)) { 6711 /* 6712 * COVERITY 6713 * pipe_latency_full is subject to change. This checker will not be True. 6714 * It is kept intentionally as a defensive check for future development. 6715 */ 6716 /* coverity[dead_error_line] */ 6717 latency += 1; /* To round up. */ 6718 } 6719 soc_reg_field_set(unit, reg, &rval, LATENCYf, latency); 6720 soc_reg_field_set(unit, reg, &rval, WR_ENf, 1); 6721 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 6722 6723 return SOC_E_NONE; 6724 } 6725 6726 6727 6728 #if 0 6729 STATIC int 6730 _soc_trident3_tdm_idb_oversub_group_set(int unit) 6731 { 6732 soc_info_t *si; 6733 _soc_tomahawk_tdm_t *tdm; 6734 uint32 pipe_map; 6735 int block_info_idx; 6736 soc_reg_t reg; 6737 int pipe, clport, group, lane, slot, id, mode, ovs_class; 6738 int port, phy_port, phy_port_base, idb_port; 6739 int speed_max; 6740 uint32 rval; 6741 static const soc_reg_t grp_tbl_regs[] = { 6742 IS_OVR_SUB_GRP0_TBLr, IS_OVR_SUB_GRP1_TBLr, 6743 IS_OVR_SUB_GRP2_TBLr, IS_OVR_SUB_GRP3_TBLr, 6744 IS_OVR_SUB_GRP4_TBLr, IS_OVR_SUB_GRP5_TBLr 6745 }; 6746 static const soc_reg_t pblk_calendar_regs[] ={ 6747 IS_PBLK0_CALENDARr, IS_PBLK1_CALENDARr, 6748 IS_PBLK2_CALENDARr, IS_PBLK3_CALENDARr, 6749 IS_PBLK4_CALENDARr, IS_PBLK5_CALENDARr, 6750 IS_PBLK6_CALENDARr, IS_PBLK7_CALENDARr 6751 }; 6752 static int pblk_slots[SOC_TD3_PORT_RATIO_COUNT][7] = { 6753 { 0, -1, 0, 0, -1, 0, -1 }, /* SOC_TD3_PORT_RATIO_SINGLE */ 6754 { 0, -1, 2, 0, -1, 2, -1 }, /* SOC_TD3_PORT_RATIO_DUAL_1_1 */ 6755 { 0, 0, 2, 0, 0, 2, -1 }, /* SOC_TD3_PORT_RATIO_DUAL_2_1 */ 6756 { 0, 2, 2, 0, 2, 2, -1 }, /* SOC_TD3_PORT_RATIO_DUAL_1_2 */ 6757 { 0, -1, 2, 0, -1, 3, -1 }, /* SOC_TD3_PORT_RATIO_TRI_023_2_1_1 */ 6758 { 0, 0, 2, 0, 0, 3, -1 }, /* SOC_TD3_PORT_RATIO_TRI_023_4_1_1 */ 6759 { 0, -1, 2, 1, -1, 2, -1 }, /* SOC_TD3_PORT_RATIO_TRI_012_1_1_2 */ 6760 { 0, 2, 2, 1, 2, 2, -1 }, /* SOC_TD3_PORT_RATIO_TRI_012_1_1_4 */ 6761 { 0, -1, 2, 1, -1, 3, -1 } /* SOC_TD3_PORT_RATIO_QUAD */ 6762 }; 6763 6764 si = &SOC_INFO(unit); 6765 tdm = SOC_CONTROL(unit)->tdm_info; 6766 6767 soc_trident3_pipe_map_get(unit, &pipe_map); 6768 6769 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6770 if (!(pipe_map & (1 << pipe))) { 6771 continue; 6772 } 6773 6774 for (group = 0; group < _OVS_GROUP_COUNT; group++) { 6775 reg = SOC_REG_UNIQUE_ACC(unit, grp_tbl_regs[group])[pipe]; 6776 rval = 0; 6777 for (slot = 0; slot < _OVS_GROUP_TDM_LENGTH; slot++) { 6778 phy_port = tdm->idb_ovs_tdm[pipe][group][slot]; 6779 if (phy_port >= _SOC_TH_TDM_NUM_EXT_PORTS) { 6780 idb_port = 0x3f; 6781 id = -1; 6782 } else { 6783 port = si->port_p2l_mapping[phy_port]; 6784 idb_port = si->port_l2i_mapping[port]; 6785 id = si->port_serdes[port]; 6786 } 6787 soc_reg_field_set(unit, reg, &rval, PHY_PORT_IDf, id & 0x7); 6788 soc_reg_field_set(unit, reg, &rval, PORT_NUMf, idb_port); 6789 SOC_IF_ERROR_RETURN 6790 (soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval)); 6791 } 6792 } 6793 } 6794 6795 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6796 if (!(pipe_map & (1 << pipe))) { 6797 continue; 6798 } 6799 6800 reg = SOC_REG_UNIQUE_ACC(unit, IS_OVR_SUB_GRP_CFGr)[pipe]; 6801 for (group = 0; group < _OVS_GROUP_COUNT; group++) { 6802 phy_port = tdm->idb_ovs_tdm[pipe][group][0]; 6803 if (phy_port >= _SOC_TH_TDM_NUM_EXT_PORTS) { 6804 continue; 6805 } 6806 port = si->port_p2l_mapping[phy_port]; 6807 speed_max = 25000 * si->port_num_lanes[port]; 6808 if (speed_max > si->port_speed_max[port]) { 6809 speed_max = si->port_speed_max[port]; 6810 } 6811 _soc_trident3_speed_to_ovs_class_mapping(unit, speed_max, 6812 &ovs_class); 6813 rval = 0; 6814 soc_reg_field_set(unit, reg, &rval, SAME_SPACINGf, 4); 6815 soc_reg_field_set(unit, reg, &rval, SPEEDf, ovs_class); 6816 SOC_IF_ERROR_RETURN 6817 (soc_reg32_set(unit, reg, REG_PORT_ANY, group, rval)); 6818 } 6819 } 6820 6821 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 6822 port = SOC_BLOCK_PORT(unit, block_info_idx); 6823 phy_port_base = PORT_BLOCK_BASE_PORT(port); 6824 pipe = si->port_pipe[port]; 6825 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 6826 6827 mode = tdm->port_ratio[clport]; 6828 reg = SOC_REG_UNIQUE_ACC(unit, pblk_calendar_regs[clport & 0x7])[pipe]; 6829 rval = 0; 6830 soc_reg_field_set(unit, reg, &rval, VALIDf, 1); 6831 soc_reg_field_set(unit, reg, &rval, SPACINGf, 4); 6832 for (slot = 0; slot < 7; slot++) { 6833 lane = pblk_slots[mode][slot]; 6834 if (lane == -1) { 6835 SOC_IF_ERROR_RETURN 6836 (soc_reg32_set(unit, reg, REG_PORT_ANY, slot, 0)); 6837 continue; 6838 } 6839 port = si->port_p2l_mapping[phy_port_base + lane]; 6840 idb_port = si->port_l2i_mapping[port]; 6841 soc_reg_field_set(unit, reg, &rval, PORT_NUMf, idb_port); 6842 SOC_IF_ERROR_RETURN 6843 (soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval)); 6844 } 6845 } 6846 6847 return SOC_E_NONE; 6848 } 6849 6850 STATIC int 6851 _soc_trident3_tdm_idb_opportunistic_set(int unit, int enable) 6852 { 6853 soc_reg_t reg; 6854 uint32 pipe_map; 6855 int pipe; 6856 uint32 rval; 6857 6858 soc_trident3_pipe_map_get(unit, &pipe_map); 6859 6860 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6861 if (!(pipe_map & (1 << pipe))) { 6862 continue; 6863 } 6864 6865 reg = SOC_REG_UNIQUE_ACC(unit, IS_CPU_LB_OPP_CFGr)[pipe]; 6866 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 6867 soc_reg_field_set(unit, reg, &rval, CPU_OPP_ENf, enable ? 1 : 0); 6868 soc_reg_field_set(unit, reg, &rval, LB_OPP_ENf, enable ? 1 : 0); 6869 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 6870 6871 reg = SOC_REG_UNIQUE_ACC(unit, IS_OPP_SCHED_CFGr)[pipe]; 6872 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 6873 soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf, enable ? 1 : 0); 6874 soc_reg_field_set(unit, reg, &rval, OPP2_PORT_ENf, enable ? 1 : 0); 6875 soc_reg_field_set(unit, reg, &rval, OPP_OVR_SUB_ENf, enable ? 1 : 0); 6876 soc_reg_field_set(unit, reg, &rval, DISABLE_PORT_NUMf, 0); 6877 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 6878 } 6879 6880 return SOC_E_NONE; 6881 } 6882 6883 STATIC int 6884 _soc_trident3_tdm_idb_hsp_set(int unit) 6885 { 6886 soc_info_t *si; 6887 soc_reg_t reg; 6888 uint32 pipe_map; 6889 int pipe; 6890 int port, idb_port; 6891 uint32 port_map[NUM_PIPE(unit)]; 6892 uint32 rval; 6893 6894 si = &SOC_INFO(unit); 6895 6896 soc_trident3_pipe_map_get(unit, &pipe_map); 6897 6898 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6899 port_map[pipe] = 0; 6900 } 6901 SOC_PBMP_ITER(si->eq_pbm, port) { 6902 pipe = si->port_pipe[port]; 6903 idb_port = si->port_l2i_mapping[port]; 6904 port_map[pipe] |= 1 << idb_port; 6905 } 6906 6907 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6908 if (!(pipe_map & (1 << pipe))) { 6909 continue; 6910 } 6911 6912 reg = SOC_REG_UNIQUE_ACC(unit, IS_TDM_HSPr)[pipe]; 6913 soc_reg_field_set(unit, reg, &rval, PORT_BMPf, port_map[pipe]); 6914 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 6915 } 6916 6917 return SOC_E_NONE; 6918 } 6919 #endif 6920 6921 6922 6923 #if 0 6924 STATIC int 6925 _soc_trident3_tdm_mmu_oversub_group_set(int unit) 6926 { 6927 soc_info_t *si; 6928 _soc_tomahawk_tdm_t *tdm; 6929 uint32 pipe_map; 6930 int block_info_idx; 6931 soc_reg_t reg; 6932 int pipe, clport, group, lane, slot, id, mode, ovs_class; 6933 int port, phy_port, phy_port_base, mmu_port, inst; 6934 int speed_max; 6935 uint32 rval; 6936 static const soc_reg_t grp_tbl_regs[] = { 6937 OVR_SUB_GRP0_TBLr, OVR_SUB_GRP1_TBLr, 6938 OVR_SUB_GRP2_TBLr, OVR_SUB_GRP3_TBLr, 6939 OVR_SUB_GRP4_TBLr, OVR_SUB_GRP5_TBLr 6940 }; 6941 static const soc_reg_t pblk_calendar_regs[] = { 6942 PBLK0_CALENDARr, PBLK1_CALENDARr, PBLK2_CALENDARr, PBLK3_CALENDARr, 6943 PBLK4_CALENDARr, PBLK5_CALENDARr, PBLK6_CALENDARr, PBLK7_CALENDARr 6944 }; 6945 static const int pblk_slots[SOC_TD3_PORT_RATIO_COUNT][7] = { 6946 { 0, -1, 0, 0, -1, 0, -1 }, /* SOC_TD3_PORT_RATIO_SINGLE */ 6947 { 0, -1, 2, 0, -1, 2, -1 }, /* SOC_TD3_PORT_RATIO_DUAL_1_1 */ 6948 { 0, 0, 2, 0, 0, 2, -1 }, /* SOC_TD3_PORT_RATIO_DUAL_2_1 */ 6949 { 0, 2, 2, 0, 2, 2, -1 }, /* SOC_TD3_PORT_RATIO_DUAL_1_2 */ 6950 { 0, -1, 2, 0, -1, 3, -1 }, /* SOC_TD3_PORT_RATIO_TRI_023_2_1_1 */ 6951 { 0, 0, 2, 0, 0, 3, -1 }, /* SOC_TD3_PORT_RATIO_TRI_023_4_1_1 */ 6952 { 0, -1, 2, 1, -1, 2, -1 }, /* SOC_TD3_PORT_RATIO_TRI_012_1_1_2 */ 6953 { 0, 2, 2, 1, 2, 2, -1 }, /* SOC_TD3_PORT_RATIO_TRI_012_1_1_4 */ 6954 { 0, -1, 2, 1, -1, 3, -1 } /* SOC_TD3_PORT_RATIO_QUAD */ 6955 }; 6956 6957 si = &SOC_INFO(unit); 6958 tdm = SOC_CONTROL(unit)->tdm_info; 6959 6960 soc_trident3_pipe_map_get(unit, &pipe_map); 6961 6962 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6963 if (!(pipe_map & (1 << pipe))) { 6964 continue; 6965 } 6966 6967 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 6968 for (group = 0; group < _OVS_GROUP_COUNT; group++) { 6969 reg = grp_tbl_regs[group]; 6970 rval = 0; 6971 for (slot = 0; slot < _OVS_GROUP_TDM_LENGTH; slot++) { 6972 phy_port = tdm->mmu_ovs_tdm[pipe][group][slot]; 6973 if (phy_port >= _SOC_TH_TDM_NUM_EXT_PORTS) { 6974 mmu_port = 0x3f; 6975 id = -1; 6976 } else { 6977 mmu_port = si->port_p2m_mapping[phy_port]; 6978 port = si->port_p2l_mapping[phy_port]; 6979 id = si->port_serdes[port]; 6980 } 6981 soc_reg_field_set(unit, reg, &rval, PHY_PORT_IDf, id & 0x7); 6982 soc_reg_field_set(unit, reg, &rval, PORT_NUMf, 6983 mmu_port & 0x3f); 6984 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, slot, rval)); 6985 } 6986 } 6987 } 6988 6989 reg = OVR_SUB_GRP_CFGr; 6990 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 6991 if (!(pipe_map & (1 << pipe))) { 6992 continue; 6993 } 6994 6995 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 6996 for (group = 0; group < _OVS_GROUP_COUNT; group++) { 6997 phy_port = tdm->mmu_ovs_tdm[pipe][group][0]; 6998 if (phy_port >= _SOC_TH_TDM_NUM_EXT_PORTS) { 6999 continue; 7000 } 7001 port = si->port_p2l_mapping[phy_port]; 7002 speed_max = 25000 * si->port_num_lanes[port]; 7003 if (speed_max > si->port_speed_max[port]) { 7004 speed_max = si->port_speed_max[port]; 7005 } 7006 _soc_trident3_speed_to_ovs_class_mapping(unit, speed_max, 7007 &ovs_class); 7008 rval = 0; 7009 soc_reg_field_set(unit, reg, &rval, SAME_SPACINGf, 7010 speed_max >= 40000 ? 4 : 8); 7011 soc_reg_field_set(unit, reg, &rval, SPEEDf, ovs_class); 7012 SOC_IF_ERROR_RETURN 7013 (soc_reg32_set(unit, reg, inst, group, rval)); 7014 } 7015 } 7016 7017 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 7018 port = SOC_BLOCK_PORT(unit, block_info_idx); 7019 phy_port_base = PORT_BLOCK_BASE_PORT(port); 7020 speed_max = 25000 * si->port_num_lanes[port]; 7021 if (speed_max > si->port_speed_max[port]) { 7022 speed_max = si->port_speed_max[port]; 7023 } 7024 pipe = si->port_pipe[port]; 7025 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 7026 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 7027 7028 mode = tdm->port_ratio[clport]; 7029 reg = pblk_calendar_regs[clport & 0x7]; 7030 rval = 0; 7031 soc_reg_field_set(unit, reg, &rval, VALIDf, 1); 7032 soc_reg_field_set(unit, reg, &rval, SPACINGf, 7033 speed_max >= 40000 ? 4 : 8); 7034 for (slot = 0; slot < 7; slot++) { 7035 lane = pblk_slots[mode][slot]; 7036 if (lane == -1) { 7037 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, slot, 0)); 7038 continue; 7039 } 7040 mmu_port = si->port_p2m_mapping[phy_port_base + lane]; 7041 soc_reg_field_set(unit, reg, &rval, PORT_NUMf, mmu_port & 0x3f); 7042 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, slot, rval)); 7043 } 7044 } 7045 7046 return SOC_E_NONE; 7047 } 7048 7049 STATIC int 7050 _soc_trident3_tdm_mmu_opportunistic_set(int unit, int enable) 7051 { 7052 uint32 pipe_map; 7053 soc_reg_t reg; 7054 int pipe; 7055 int inst; 7056 uint32 rval; 7057 7058 soc_trident3_pipe_map_get(unit, &pipe_map); 7059 7060 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 7061 if (!(pipe_map & (1 << pipe))) { 7062 continue; 7063 } 7064 7065 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 7066 7067 reg = CPU_LB_OPP_CFGr; 7068 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, 0, &rval)); 7069 soc_reg_field_set(unit, reg, &rval, CPU_OPP_ENf, enable ? 1 : 0); 7070 soc_reg_field_set(unit, reg, &rval, LB_OPP_ENf, enable ? 1 : 0); 7071 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval)); 7072 7073 reg = OPP_SCHED_CFGr; 7074 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, 0, &rval)); 7075 soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf, enable ? 1 : 0); 7076 soc_reg_field_set(unit, reg, &rval, OPP2_PORT_ENf, enable ? 1 : 0); 7077 soc_reg_field_set(unit, reg, &rval, OPP_OVR_SUB_ENf, enable ? 1 : 0); 7078 soc_reg_field_set(unit, reg, &rval, DISABLE_PORT_NUMf, 0); 7079 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval)); 7080 } 7081 7082 return SOC_E_NONE; 7083 } 7084 7085 STATIC int 7086 _soc_trident3_tdm_mmu_hsp_set(int unit) 7087 { 7088 soc_info_t *si; 7089 uint32 pipe_map; 7090 soc_reg_t reg; 7091 int pipe; 7092 int port, phy_port, mmu_port, inst; 7093 uint32 port_map[NUM_PIPE(unit)]; 7094 uint32 rval; 7095 7096 si = &SOC_INFO(unit); 7097 7098 soc_trident3_pipe_map_get(unit, &pipe_map); 7099 7100 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 7101 port_map[pipe] = 0; 7102 } 7103 SOC_PBMP_ITER(si->eq_pbm, port) { 7104 pipe = si->port_pipe[port]; 7105 phy_port = si->port_l2p_mapping[port]; 7106 mmu_port = si->port_p2m_mapping[phy_port]; 7107 port_map[pipe] |= 1 << (mmu_port & 0x1f); 7108 } 7109 7110 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 7111 if (!(pipe_map & (1 << pipe))) { 7112 continue; 7113 } 7114 7115 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 7116 7117 reg = TDM_HSPr; 7118 soc_reg_field_set(unit, reg, &rval, PORT_BMPf, port_map[pipe]); 7119 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval)); 7120 } 7121 7122 return SOC_E_NONE; 7123 } 7124 #endif 7125 7126 int 7127 soc_trident3_hash_init(int unit) 7128 { 7129 /* Robust Hash initialization */ 7130 #ifdef SOC_ROBUST_HASH 7131 subport_id_to_sgpp_map_key_attributes_entry_t sgpp_map_attr; 7132 7133 /* Initialize Robust Hash Global Datastructure */ 7134 if (soc_feature(unit, soc_feature_robust_hash)) { 7135 uint32 seed = 0; 7136 uint32 hash_control_entry[4]; 7137 7138 if (NULL == ROBUSTHASH(unit)) { 7139 ROBUSTHASH(unit) = sal_alloc(sizeof(soc_robust_hash_db_t), 7140 "soc_robust_hash"); 7141 if (ROBUSTHASH(unit) == NULL) { 7142 return SOC_E_MEMORY; 7143 } 7144 sal_memset(ROBUSTHASH(unit), 0, sizeof(soc_robust_hash_db_t)); 7145 } 7146 7147 /* L2 Robust Hash Init */ 7148 7149 sal_memset(hash_control_entry, 0, sizeof(hash_control_entry)); 7150 7151 /* Disable robust hash for L2 - this config variable is used only 7152 * for debug purposes*/ 7153 if ((soc_property_get(unit, "robust_hash_disable_l2", 0)) == 1) { 7154 SOC_IF_ERROR_RETURN 7155 (READ_L2_ENTRY_HASH_CONTROLm 7156 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7157 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , 7158 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7159 SOC_IF_ERROR_RETURN 7160 (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7161 hash_control_entry)); 7162 ROBUSTHASH(unit)->l2.enable = 0; 7163 } else { 7164 /* Enable robust hashing */ 7165 SOC_IF_ERROR_RETURN 7166 (READ_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7167 hash_control_entry)); 7168 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm, 7169 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7170 SOC_IF_ERROR_RETURN 7171 (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7172 hash_control_entry)); 7173 ROBUSTHASH(unit)->l2.enable = 1; 7174 7175 /* Configure remap and action tables for L2 table */ 7176 ROBUSTHASH(unit)->l2.remap_tab[0] = L2_ENTRY_REMAP_TABLE_Am; 7177 ROBUSTHASH(unit)->l2.remap_tab[1] = L2_ENTRY_REMAP_TABLE_Bm; 7178 ROBUSTHASH(unit)->l2.action_tab[0] = L2_ENTRY_ACTION_TABLE_Am; 7179 ROBUSTHASH(unit)->l2.action_tab[1] = L2_ENTRY_ACTION_TABLE_Bm; 7180 7181 /* Initialize seed for robust hash */ 7182 seed = soc_property_get(unit, spn_ROBUST_HASH_SEED_L2, 16777213); 7183 7184 SOC_IF_ERROR_RETURN 7185 (soc_robust_hash_table_set(unit, 7186 &(ROBUSTHASH(unit)->l2), 7187 seed)); 7188 } 7189 7190 /* L3 Robust Hash Init */ 7191 7192 sal_memset(hash_control_entry, 0, sizeof(hash_control_entry)); 7193 7194 /* Disable robust hash for L3 - this config variable is used only 7195 * for debug purposes*/ 7196 if ((soc_property_get(unit, "robust_hash_disable_l3", 0)) == 1) { 7197 SOC_IF_ERROR_RETURN 7198 (READ_L3_ENTRY_HASH_CONTROLm 7199 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7200 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm , 7201 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7202 SOC_IF_ERROR_RETURN 7203 (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7204 hash_control_entry)); 7205 ROBUSTHASH(unit)->l3.enable = 0; 7206 } else { 7207 /* Enable robust hashing */ 7208 SOC_IF_ERROR_RETURN 7209 (READ_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7210 hash_control_entry)); 7211 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, 7212 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7213 SOC_IF_ERROR_RETURN 7214 (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7215 hash_control_entry)); 7216 ROBUSTHASH(unit)->l3.enable = 1; 7217 7218 /* Configure remap and action tables for L3 table */ 7219 ROBUSTHASH(unit)->l3.remap_tab[0] = L3_ENTRY_REMAP_TABLE_Am; 7220 ROBUSTHASH(unit)->l3.remap_tab[1] = L3_ENTRY_REMAP_TABLE_Bm; 7221 ROBUSTHASH(unit)->l3.action_tab[0] = L3_ENTRY_ACTION_TABLE_Am; 7222 ROBUSTHASH(unit)->l3.action_tab[1] = L3_ENTRY_ACTION_TABLE_Bm; 7223 7224 /* Initialize seed for robust hash */ 7225 seed = soc_property_get(unit, spn_ROBUST_HASH_SEED_L3, 16777213); 7226 7227 SOC_IF_ERROR_RETURN 7228 (soc_robust_hash_table_set(unit, 7229 &(ROBUSTHASH(unit)->l3), 7230 seed)); 7231 } 7232 7233 /* Exact Match Robust Hash Init */ 7234 7235 sal_memset 7236 (hash_control_entry, 0, sizeof(hash_control_entry)); 7237 7238 /* Disable robust hash for EM - this config variable is used only 7239 * for debug purposes*/ 7240 if ((soc_property_get 7241 (unit, "robust_hash_disable_exact_match", 0)) == 1) { 7242 SOC_IF_ERROR_RETURN 7243 (READ_EXACT_MATCH_HASH_CONTROLm 7244 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7245 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm , 7246 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7247 SOC_IF_ERROR_RETURN 7248 (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7249 hash_control_entry)); 7250 ROBUSTHASH(unit)->exact_match.enable = 0; 7251 } else { 7252 /* Enable robust hashing */ 7253 SOC_IF_ERROR_RETURN 7254 (READ_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7255 hash_control_entry)); 7256 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm, 7257 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7258 SOC_IF_ERROR_RETURN 7259 (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7260 hash_control_entry)); 7261 ROBUSTHASH(unit)->exact_match.enable = 1; 7262 7263 /* Configure remap and action tables for EM table */ 7264 ROBUSTHASH(unit)->exact_match.remap_tab[0] = EXACT_MATCH_REMAP_TABLE_Am; 7265 ROBUSTHASH(unit)->exact_match.remap_tab[1] = EXACT_MATCH_REMAP_TABLE_Bm; 7266 ROBUSTHASH(unit)->exact_match.action_tab[0] = EXACT_MATCH_ACTION_TABLE_Am; 7267 ROBUSTHASH(unit)->exact_match.action_tab[1] = EXACT_MATCH_ACTION_TABLE_Bm; 7268 7269 /* Initialize seed for robust hash */ 7270 seed = soc_property_get 7271 (unit, spn_ROBUST_HASH_SEED_EXACT_MATCH, 16777213); 7272 7273 SOC_IF_ERROR_RETURN 7274 (soc_robust_hash_table_set(unit, 7275 &(ROBUSTHASH(unit)->exact_match), 7276 seed)); 7277 } 7278 7279 /* Vlan Xlate 1 Robust Hash Init */ 7280 7281 sal_memset 7282 (hash_control_entry, 0, sizeof(hash_control_entry)); 7283 7284 /* Disable robust hash for Vlan Xlate 1 - this config variable is used 7285 * only for debug purposes*/ 7286 if ((soc_property_get 7287 (unit, "robust_hash_disable_vlan1", 0)) == 1) { 7288 SOC_IF_ERROR_RETURN 7289 (READ_VLAN_XLATE_1_HASH_CONTROLm 7290 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7291 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm , 7292 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7293 SOC_IF_ERROR_RETURN 7294 (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7295 hash_control_entry)); 7296 ROBUSTHASH(unit)->ing_xlate_1.enable = 0; 7297 } else { 7298 /* Enable robust hashing */ 7299 SOC_IF_ERROR_RETURN 7300 (READ_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7301 hash_control_entry)); 7302 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, 7303 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7304 SOC_IF_ERROR_RETURN 7305 (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7306 hash_control_entry)); 7307 ROBUSTHASH(unit)->ing_xlate_1.enable = 1; 7308 7309 /* Configure remap and action tables for VLAN XLATE 1 table */ 7310 ROBUSTHASH(unit)->ing_xlate_1.remap_tab[0] = VLAN_XLATE_1_REMAP_TABLE_Am; 7311 ROBUSTHASH(unit)->ing_xlate_1.remap_tab[1] = VLAN_XLATE_1_REMAP_TABLE_Bm; 7312 ROBUSTHASH(unit)->ing_xlate_1.action_tab[0] = VLAN_XLATE_1_ACTION_TABLE_Am; 7313 ROBUSTHASH(unit)->ing_xlate_1.action_tab[1] = VLAN_XLATE_1_ACTION_TABLE_Bm; 7314 7315 /* Initialize seed for robust hash */ 7316 seed = soc_property_get 7317 (unit, spn_ROBUST_HASH_SEED_VLAN_1, 16777213); 7318 7319 SOC_IF_ERROR_RETURN 7320 (soc_robust_hash_table_set(unit, 7321 &(ROBUSTHASH(unit)->ing_xlate_1), 7322 seed)); 7323 } 7324 7325 /* Vlan Xlate 2 Robust Hash Init */ 7326 7327 sal_memset 7328 (hash_control_entry, 0, sizeof(hash_control_entry)); 7329 7330 /* Disable robust hash for Vlan Xlate 2 - this config variable is used 7331 * only for debug purposes*/ 7332 if ((soc_property_get 7333 (unit, "robust_hash_disable_vlan2", 0)) == 1) { 7334 SOC_IF_ERROR_RETURN 7335 (READ_VLAN_XLATE_2_HASH_CONTROLm 7336 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7337 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm , 7338 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7339 SOC_IF_ERROR_RETURN 7340 (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7341 hash_control_entry)); 7342 ROBUSTHASH(unit)->ing_xlate_2.enable = 0; 7343 } else { 7344 /* Enable robust hashing */ 7345 SOC_IF_ERROR_RETURN 7346 (READ_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7347 hash_control_entry)); 7348 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, 7349 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7350 SOC_IF_ERROR_RETURN 7351 (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7352 hash_control_entry)); 7353 ROBUSTHASH(unit)->ing_xlate_2.enable = 1; 7354 7355 /* Configure remap and action tables for VLAN XLATE 2 table */ 7356 ROBUSTHASH(unit)->ing_xlate_2.remap_tab[0] = VLAN_XLATE_2_REMAP_TABLE_Am; 7357 ROBUSTHASH(unit)->ing_xlate_2.remap_tab[1] = VLAN_XLATE_2_REMAP_TABLE_Bm; 7358 ROBUSTHASH(unit)->ing_xlate_2.action_tab[0] = VLAN_XLATE_2_ACTION_TABLE_Am; 7359 ROBUSTHASH(unit)->ing_xlate_2.action_tab[1] = VLAN_XLATE_2_ACTION_TABLE_Bm; 7360 7361 /* Initialize seed for robust hash */ 7362 seed = soc_property_get 7363 (unit, spn_ROBUST_HASH_SEED_VLAN_2, 16777213); 7364 7365 SOC_IF_ERROR_RETURN 7366 (soc_robust_hash_table_set(unit, 7367 &(ROBUSTHASH(unit)->ing_xlate_2), 7368 seed)); 7369 } 7370 7371 /* Egr Vlan Xlate 1 Robust Hash Init */ 7372 7373 sal_memset 7374 (hash_control_entry, 0, sizeof(hash_control_entry)); 7375 7376 /* Disable robust hash for Egr Vlan Xlate 1 - this config variable is 7377 * used only for debug purposes*/ 7378 if ((soc_property_get 7379 (unit, "robust_hash_disable_egress_vlan1", 0)) == 1) { 7380 SOC_IF_ERROR_RETURN 7381 (READ_EGR_VLAN_XLATE_1_HASH_CONTROLm 7382 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7383 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm , 7384 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7385 SOC_IF_ERROR_RETURN 7386 (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7387 hash_control_entry)); 7388 ROBUSTHASH(unit)->egr_xlate_1.enable = 0; 7389 } else { 7390 /* Enable robust hashing */ 7391 SOC_IF_ERROR_RETURN 7392 (READ_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7393 hash_control_entry)); 7394 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 7395 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7396 SOC_IF_ERROR_RETURN 7397 (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7398 hash_control_entry)); 7399 ROBUSTHASH(unit)->egr_xlate_1.enable = 1; 7400 7401 /* Configure remap and action tables for EGR VLAN XLATE 1 table */ 7402 ROBUSTHASH(unit)->egr_xlate_1.remap_tab[0] = EGR_VLAN_XLATE_1_REMAP_TABLE_Am; 7403 ROBUSTHASH(unit)->egr_xlate_1.remap_tab[1] = EGR_VLAN_XLATE_1_REMAP_TABLE_Bm; 7404 ROBUSTHASH(unit)->egr_xlate_1.action_tab[0] = EGR_VLAN_XLATE_1_ACTION_TABLE_Am; 7405 ROBUSTHASH(unit)->egr_xlate_1.action_tab[1] = EGR_VLAN_XLATE_1_ACTION_TABLE_Bm; 7406 7407 /* Initialize seed for robust hash */ 7408 seed = soc_property_get 7409 (unit, spn_ROBUST_HASH_SEED_EGRESS_VLAN_1, 16777213); 7410 7411 SOC_IF_ERROR_RETURN 7412 (soc_robust_hash_table_set(unit, 7413 &(ROBUSTHASH(unit)->egr_xlate_1), 7414 seed)); 7415 } 7416 7417 /* Egr Vlan Xlate 2 Robust Hash Init */ 7418 7419 sal_memset 7420 (hash_control_entry, 0, sizeof(hash_control_entry)); 7421 7422 /* Disable robust hash for Egr Vlan Xlate 2 - this config variable is 7423 * used only for debug purposes*/ 7424 if ((soc_property_get 7425 (unit, "robust_hash_disable_egress_vlan2", 0)) == 1) { 7426 SOC_IF_ERROR_RETURN 7427 (READ_EGR_VLAN_XLATE_2_HASH_CONTROLm 7428 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7429 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm , 7430 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7431 SOC_IF_ERROR_RETURN 7432 (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7433 hash_control_entry)); 7434 ROBUSTHASH(unit)->egr_xlate_2.enable = 0; 7435 } else { 7436 /* Enable robust hashing */ 7437 SOC_IF_ERROR_RETURN 7438 (READ_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7439 hash_control_entry)); 7440 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, 7441 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7442 SOC_IF_ERROR_RETURN 7443 (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7444 hash_control_entry)); 7445 ROBUSTHASH(unit)->egr_xlate_2.enable = 1; 7446 7447 /* Configure remap and action tables for EGR VLAN XLATE 2 table */ 7448 ROBUSTHASH(unit)->egr_xlate_2.remap_tab[0] = EGR_VLAN_XLATE_2_REMAP_TABLE_Am; 7449 ROBUSTHASH(unit)->egr_xlate_2.remap_tab[1] = EGR_VLAN_XLATE_2_REMAP_TABLE_Bm; 7450 ROBUSTHASH(unit)->egr_xlate_2.action_tab[0] = EGR_VLAN_XLATE_2_ACTION_TABLE_Am; 7451 ROBUSTHASH(unit)->egr_xlate_2.action_tab[1] = EGR_VLAN_XLATE_2_ACTION_TABLE_Bm; 7452 7453 /* Initialize seed for robust hash */ 7454 seed = soc_property_get 7455 (unit, spn_ROBUST_HASH_SEED_EGRESS_VLAN_2, 16777213); 7456 7457 SOC_IF_ERROR_RETURN 7458 (soc_robust_hash_table_set(unit, 7459 &(ROBUSTHASH(unit)->egr_xlate_2), 7460 seed)); 7461 } 7462 /* Ing vlan vp Robust Hash Init */ 7463 7464 sal_memset 7465 (hash_control_entry, 0, sizeof(hash_control_entry)); 7466 7467 /* Disable robust hash for ing vp vlan - this config variable is 7468 * used only for debug purposes*/ 7469 if ((soc_property_get 7470 (unit, "robust_hash_disable_ing_vp_vlan", 0)) == 1) { 7471 SOC_IF_ERROR_RETURN 7472 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm 7473 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7474 soc_mem_field32_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm , 7475 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7476 SOC_IF_ERROR_RETURN 7477 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm 7478 (unit, MEM_BLOCK_ALL, 0, hash_control_entry)); 7479 ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 0; 7480 } else { 7481 /* Enable robust hashing */ 7482 SOC_IF_ERROR_RETURN 7483 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 7484 0, hash_control_entry)); 7485 soc_mem_field32_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm, 7486 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7487 SOC_IF_ERROR_RETURN 7488 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7489 hash_control_entry)); 7490 ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 1; 7491 7492 /* Configure remap and action tables for ing vp vlan table */ 7493 ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[0] = 7494 ING_VP_VLAN_MEMBERSHIP_REMAP_TABLE_Am; 7495 ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[1] = 7496 ING_VP_VLAN_MEMBERSHIP_REMAP_TABLE_Bm; 7497 ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[0] = 7498 ING_VP_VLAN_MEMBERSHIP_ACTION_TABLE_Am; 7499 ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[1] = 7500 ING_VP_VLAN_MEMBERSHIP_ACTION_TABLE_Bm; 7501 7502 seed = soc_property_get(unit, 7503 spn_ROBUST_HASH_SEED_INGRESS_VP_VLAN, 7504 16777213); 7505 7506 SOC_IF_ERROR_RETURN 7507 (soc_robust_hash_table_set(unit, 7508 &(ROBUSTHASH(unit)->ing_vp_vlan_member), 7509 seed)); 7510 } 7511 7512 /* Egr vlan vp Robust Hash Init */ 7513 7514 sal_memset 7515 (hash_control_entry, 0, sizeof(hash_control_entry)); 7516 /* Disable robust hash for egr vp vlan - this config variable is 7517 * used only for debug purposes*/ 7518 if ((soc_property_get 7519 (unit, "robust_hash_disable_egr_vp_vlan", 0)) == 1) { 7520 SOC_IF_ERROR_RETURN 7521 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm 7522 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7523 soc_mem_field32_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm , 7524 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7525 SOC_IF_ERROR_RETURN 7526 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm 7527 (unit, MEM_BLOCK_ALL, 0, hash_control_entry)); 7528 ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 0; 7529 } else { 7530 /* Enable robust hashing */ 7531 SOC_IF_ERROR_RETURN 7532 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 7533 0, hash_control_entry)); 7534 soc_mem_field32_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm, 7535 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7536 SOC_IF_ERROR_RETURN 7537 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7538 hash_control_entry)); 7539 ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 1; 7540 7541 /* Configure remap and action tables for ing vp vlan table */ 7542 ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[0] = 7543 EGR_VP_VLAN_MEMBERSHIP_REMAP_TABLE_Am; 7544 ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[1] = 7545 EGR_VP_VLAN_MEMBERSHIP_REMAP_TABLE_Bm; 7546 ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[0] = 7547 EGR_VP_VLAN_MEMBERSHIP_ACTION_TABLE_Am; 7548 ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[1] = 7549 EGR_VP_VLAN_MEMBERSHIP_ACTION_TABLE_Bm; 7550 7551 seed = soc_property_get(unit, 7552 spn_ROBUST_HASH_SEED_EGRESS_VP_VLAN, 7553 16777213); 7554 7555 SOC_IF_ERROR_RETURN 7556 (soc_robust_hash_table_set(unit, 7557 &(ROBUSTHASH(unit)->egr_vp_vlan_member), 7558 seed)); 7559 } 7560 7561 /* Mpls Robust Hash Init */ 7562 7563 sal_memset 7564 (hash_control_entry, 0, sizeof(hash_control_entry)); 7565 7566 /* Disable robust hash for mpls - this config variable is 7567 * used only for debug purposes*/ 7568 if ((soc_property_get 7569 (unit, "robust_hash_disable_mpls", 0)) == 1) { 7570 SOC_IF_ERROR_RETURN 7571 (READ_MPLS_ENTRY_HASH_CONTROLm 7572 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7573 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm , 7574 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7575 SOC_IF_ERROR_RETURN 7576 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7577 hash_control_entry)); 7578 ROBUSTHASH(unit)->mpls_entry.enable = 0; 7579 } else { 7580 /* Enable robust hashing */ 7581 SOC_IF_ERROR_RETURN 7582 (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7583 hash_control_entry)); 7584 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, 7585 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7586 SOC_IF_ERROR_RETURN 7587 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7588 hash_control_entry)); 7589 ROBUSTHASH(unit)->mpls_entry.enable = 1; 7590 7591 /* Configure remap and action tables for MPLS ENTRY table */ 7592 ROBUSTHASH(unit)->mpls_entry.remap_tab[0] = 7593 MPLS_ENTRY_REMAP_TABLE_Am; 7594 ROBUSTHASH(unit)->mpls_entry.remap_tab[1] = 7595 MPLS_ENTRY_REMAP_TABLE_Bm; 7596 ROBUSTHASH(unit)->mpls_entry.action_tab[0] = 7597 MPLS_ENTRY_ACTION_TABLE_Am; 7598 ROBUSTHASH(unit)->mpls_entry.action_tab[1] = 7599 MPLS_ENTRY_ACTION_TABLE_Bm; 7600 7601 /* Initialize seed for robust hash */ 7602 seed = soc_property_get 7603 (unit, spn_ROBUST_HASH_SEED_MPLS, 16777213); 7604 7605 SOC_IF_ERROR_RETURN 7606 (soc_robust_hash_table_set(unit, 7607 &(ROBUSTHASH(unit)->mpls_entry), 7608 seed)); 7609 } 7610 7611 if (SOC_MEM_IS_VALID(unit, ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm)) { 7612 /* Ing Dnat Address Robust Hash Init */ 7613 7614 sal_memset 7615 (hash_control_entry, 0, sizeof(hash_control_entry)); 7616 7617 /* Disable robust hash for ing dnat address type - this config variable 7618 * is used only for debug purposes*/ 7619 if ((soc_property_get 7620 (unit, "robust_hash_disable_ing_dnat_address", 0)) == 1) { 7621 SOC_IF_ERROR_RETURN 7622 (READ_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm 7623 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7624 soc_mem_field32_set(unit, ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm , 7625 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7626 SOC_IF_ERROR_RETURN 7627 (WRITE_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7628 hash_control_entry)); 7629 ROBUSTHASH(unit)->ing_dnat_address.enable = 0; 7630 } else { 7631 /* Enable robust hashing */ 7632 SOC_IF_ERROR_RETURN 7633 (READ_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7634 hash_control_entry)); 7635 soc_mem_field32_set(unit, ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm, 7636 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7637 SOC_IF_ERROR_RETURN 7638 (WRITE_ING_DNAT_ADDRESS_TYPE_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7639 hash_control_entry)); 7640 ROBUSTHASH(unit)->ing_dnat_address.enable = 1; 7641 7642 /* Configure remap and action tables for ING DNAT ADDRESS table */ 7643 ROBUSTHASH(unit)->ing_dnat_address.remap_tab[0] = 7644 ING_DNAT_ADDRESS_TYPE_REMAP_TABLE_Am; 7645 ROBUSTHASH(unit)->ing_dnat_address.remap_tab[1] = 7646 ING_DNAT_ADDRESS_TYPE_REMAP_TABLE_Bm; 7647 ROBUSTHASH(unit)->ing_dnat_address.action_tab[0] = 7648 ING_DNAT_ADDRESS_TYPE_ACTION_TABLE_Am; 7649 ROBUSTHASH(unit)->ing_dnat_address.action_tab[1] = 7650 ING_DNAT_ADDRESS_TYPE_ACTION_TABLE_Bm; 7651 7652 /* Initialize seed for robust hash */ 7653 seed = soc_property_get 7654 (unit, spn_ROBUST_HASH_SEED_ING_DNAT_ADDRESS, 16777213); 7655 7656 SOC_IF_ERROR_RETURN 7657 (soc_robust_hash_table_set(unit, 7658 &(ROBUSTHASH(unit)->ing_dnat_address), 7659 seed)); 7660 } 7661 } 7662 7663 if (SOC_MEM_IS_VALID(unit, SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm)) { 7664 /* Subport id to sgpp map Robust Hash Init */ 7665 7666 sal_memset(hash_control_entry, 0, sizeof(hash_control_entry)); 7667 7668 /* Disable robust hash for subport id to sgpp map - this config 7669 * variable is used only for debug purposes */ 7670 if ((soc_property_get 7671 (unit, "robust_hash_disable_subport_id_sgpp_map", 0)) == 1) { 7672 SOC_IF_ERROR_RETURN 7673 (READ_SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm 7674 (unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 7675 soc_mem_field32_set(unit, SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm , 7676 hash_control_entry, ROBUST_HASH_ENf, 0x0); 7677 SOC_IF_ERROR_RETURN 7678 (WRITE_SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7679 hash_control_entry)); 7680 ROBUSTHASH(unit)->subport_id_sgpp_map.enable = 0; 7681 } else { 7682 /* Enable robust hashing */ 7683 SOC_IF_ERROR_RETURN 7684 (READ_SUBPORT_ID_TO_SGPP_MAP_KEY_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 0, 7685 &sgpp_map_attr)); 7686 soc_mem_field32_set(unit, SUBPORT_ID_TO_SGPP_MAP_KEY_ATTRIBUTESm, 7687 &sgpp_map_attr, KEY_WIDTHf, 0x5); 7688 SOC_IF_ERROR_RETURN 7689 (WRITE_SUBPORT_ID_TO_SGPP_MAP_KEY_ATTRIBUTESm(unit, MEM_BLOCK_ALL, 0, 7690 &sgpp_map_attr)); 7691 SOC_IF_ERROR_RETURN 7692 (READ_SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 7693 hash_control_entry)); 7694 soc_mem_field32_set(unit, SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm, 7695 hash_control_entry, ROBUST_HASH_ENf, 0x1); 7696 SOC_IF_ERROR_RETURN 7697 (WRITE_SUBPORT_ID_TO_SGPP_MAP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 7698 hash_control_entry)); 7699 ROBUSTHASH(unit)->subport_id_sgpp_map.enable = 1; 7700 7701 /* Configure remap and action tables for Subport id to sgpp map table */ 7702 ROBUSTHASH(unit)->subport_id_sgpp_map.remap_tab[0] = 7703 SUBPORT_ID_TO_SGPP_MAP_REMAP_TABLE_Am; 7704 ROBUSTHASH(unit)->subport_id_sgpp_map.remap_tab[1] = 7705 SUBPORT_ID_TO_SGPP_MAP_REMAP_TABLE_Bm; 7706 ROBUSTHASH(unit)->subport_id_sgpp_map.action_tab[0] = 7707 SUBPORT_ID_TO_SGPP_MAP_ACTION_TABLE_Am; 7708 ROBUSTHASH(unit)->subport_id_sgpp_map.action_tab[1] = 7709 SUBPORT_ID_TO_SGPP_MAP_ACTION_TABLE_Bm; 7710 7711 /* Initialize seed for robust hash */ 7712 seed = soc_property_get 7713 (unit, spn_ROBUST_HASH_SEED_SUBPORT_ID_TO_SGPP_MAP, 16777213); 7714 7715 SOC_IF_ERROR_RETURN 7716 (soc_robust_hash_table_set(unit, 7717 &(ROBUSTHASH(unit)->subport_id_sgpp_map), 7718 seed)); 7719 } 7720 } 7721 } 7722 #endif /* SOC_ROBUST_HASH */ 7723 return SOC_E_NONE; 7724 } 7725 7726 STATIC int _soc_trident3_tdm_init(int unit) 7727 { 7728 soc_control_t *soc = SOC_CONTROL(unit); 7729 soc_info_t *si = &SOC_INFO(unit); 7730 soc_port_schedule_state_t *port_schedule_state; 7731 soc_port_map_type_t *in_portmap; 7732 int port, speed; 7733 int rv; 7734 if (soc->tdm_info == NULL) { 7735 soc->tdm_info = sal_alloc(sizeof(_soc_trident3_tdm_temp_t), 7736 "Trident3 TDM info"); 7737 if (soc->tdm_info == NULL) { 7738 return SOC_E_MEMORY; 7739 } 7740 sal_memset(soc->tdm_info, 0, sizeof(_soc_trident3_tdm_temp_t)); 7741 } 7742 7743 #if defined(BCM_WARM_BOOT_SUPPORT) 7744 if (SOC_WARM_BOOT(unit)) { 7745 SOC_IF_ERROR_RETURN( 7746 soc_td3_tdm_scache_recovery(unit)); 7747 return SOC_E_NONE; 7748 } else { 7749 SOC_IF_ERROR_RETURN( 7750 soc_td3_tdm_scache_allocate(unit)); 7751 } 7752 #endif 7753 port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t), 7754 "Trident3 soc_port_schedule_state_t"); 7755 if (port_schedule_state == NULL) { 7756 return SOC_E_MEMORY; 7757 } 7758 sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t)); 7759 /* Core clock frequency */ 7760 port_schedule_state->frequency = si->frequency; 7761 7762 /* Construct in_port_map */ 7763 in_portmap = &port_schedule_state->in_port_map; 7764 PBMP_PORT_ITER(unit, port) { 7765 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 7766 continue; 7767 } 7768 if (IS_HG_PORT(unit, port)) { 7769 speed = soc_port_speed_higig2eth(si->port_speed_max[port]); 7770 } else { 7771 speed = si->port_speed_max[port]; 7772 } 7773 in_portmap->log_port_speed[port] = speed; 7774 in_portmap->port_num_lanes[port] = si->port_num_lanes[port]; 7775 } 7776 sal_memcpy(in_portmap->port_p2l_mapping, si->port_p2l_mapping, 7777 sizeof(int)*TRIDENT3_TDM_PHY_PORTS_PER_DEV); 7778 sal_memcpy(in_portmap->port_l2p_mapping, si->port_l2p_mapping, 7779 sizeof(int)*_TD3_TDM_DEV_PORTS_PER_DEV); 7780 sal_memcpy(in_portmap->port_p2m_mapping, si->port_p2m_mapping, 7781 sizeof(int)*TRIDENT3_TDM_PHY_PORTS_PER_DEV); 7782 sal_memcpy(in_portmap->port_m2p_mapping, si->port_m2p_mapping, 7783 sizeof(int)*_TD3_TDM_MMU_PORTS_PER_DEV); 7784 sal_memcpy(in_portmap->port_l2i_mapping, si->port_l2i_mapping, 7785 sizeof(int)*_TD3_TDM_DEV_PORTS_PER_DEV); 7786 sal_memcpy(&in_portmap->physical_pbm, &si->physical_pbm, sizeof(pbmp_t)); 7787 sal_memcpy(&in_portmap->hg2_pbm, &si->hg.bitmap, sizeof(pbmp_t)); 7788 sal_memcpy(&in_portmap->management_pbm, &si->management_pbm, 7789 sizeof(pbmp_t)); 7790 sal_memcpy(&in_portmap->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t)); 7791 7792 port_schedule_state->is_flexport = 0; 7793 rv = soc_td3_port_schedule_tdm_init(unit, port_schedule_state); 7794 7795 rv = soc_td3_tdm_init(unit, port_schedule_state); 7796 if (rv != SOC_E_NONE) { 7797 LOG_CLI((BSL_META_U(unit, 7798 "Unsupported config for TDM calendar generation\n"))); 7799 sal_free(port_schedule_state); 7800 return rv; 7801 } 7802 rv = soc_td3_soc_tdm_update(unit, port_schedule_state); 7803 7804 sal_free(port_schedule_state); 7805 7806 return rv; 7807 } 7808 7809 /* For a given logical port, return the OBM id and the lane number */ 7810 int 7811 soc_trident3_port_obm_info_get(int unit, soc_port_t port, 7812 int *obm_id, int *lane) 7813 { 7814 soc_info_t *si; 7815 soc_port_t phy_port; 7816 int clport, port_block_base; 7817 7818 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 7819 (SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port))) { 7820 return SOC_E_PARAM; 7821 } 7822 si = &SOC_INFO(unit); 7823 phy_port = si->port_l2p_mapping[port]; 7824 port_block_base = PORT_BLOCK_BASE_PORT(port); 7825 if (lane != NULL) { 7826 *lane = (phy_port - port_block_base) % _TD3_PORTS_PER_PBLK; 7827 } 7828 7829 clport = si->port_serdes[port]; 7830 if ((obm_id != NULL) && (NUM_PIPE(unit) != 1)) { 7831 *obm_id = clport & 0xF; 7832 } else { 7833 *obm_id = clport; 7834 } 7835 return SOC_E_NONE; 7836 } 7837 7838 extern int 7839 (*_phy_tsce_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int); 7840 extern int 7841 (*_phy_tscf_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int); 7842 7843 int 7844 soc_trident3_tscx_firmware_set(int unit, int port, uint8 *array, int datalen) 7845 { 7846 soc_mem_t mem = IS_CL_PORT(unit, port) ? 7847 CLPORT_WC_UCMEM_DATAm : XLPORT_WC_UCMEM_DATAm; 7848 soc_reg_t reg = IS_CL_PORT(unit, port) ? 7849 CLPORT_WC_UCMEM_CTRLr : XLPORT_WC_UCMEM_CTRLr; 7850 7851 return soc_warpcore_firmware_set(unit, port, array, datalen, 0, mem, reg); 7852 } 7853 7854 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 7855 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 7856 7857 STATIC int 7858 _soc_trident3_mdio_addr_to_port(uint32 phy_addr) 7859 { 7860 int bus, offset; 7861 7862 /* Must be internal MDIO address */ 7863 if ((phy_addr & 0x80) == 0) { 7864 return 0; 7865 } 7866 7867 /* 7868 * Internal phy address: 7869 * bus 0 phy 1 to 24 are mapped to Physical port 1 to 24 7870 * bus 1 phy 1 to 16 are mapped to Physical port 25 to 40 7871 * bus 2 phy 1 to 24 are mapped to Physical port 41 to 84 7872 * bus 3 phy 1 to 24 are mapped to Physical port 85 to 88 7873 * bus 4 phy 1 to 16 are mapped to Physical port 89 to 104 7874 * bus 5 phy 1 to 24 are mapped to Physical port 105 to 128 7875 * bus 6 phy 1 is mapped to Physical port 129 and 7876 * phy 3 is mapped to Physical port 131 7877 */ 7878 bus = PHY_ID_BUS_NUM(phy_addr); 7879 if (bus > 6) { 7880 return 0; 7881 } 7882 switch (bus) { 7883 case 0: offset = 0; 7884 break; 7885 case 1: offset = 24; 7886 break; 7887 case 2: offset = 40; 7888 break; 7889 case 3: offset = 84; 7890 break; 7891 case 4: offset = 88; 7892 break; 7893 case 5: offset = 104; 7894 break; 7895 case 6: offset = 128; 7896 if ((phy_addr & 0x1f) == 2 || (phy_addr & 0x1f) > 3) { 7897 return 0; 7898 } 7899 break; 7900 default: 7901 return 0; 7902 } 7903 7904 return (phy_addr & 0x1f) + offset; 7905 } 7906 7907 STATIC int 7908 _soc_trident3_tscx_reg_read(int unit, uint32 phy_addr, 7909 uint32 phy_reg, uint32 *phy_data) 7910 { 7911 int rv, blk, port; 7912 int phy_port = _soc_trident3_mdio_addr_to_port(phy_addr); 7913 7914 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 7915 blk = SOC_PORT_BLOCK(unit, phy_port); 7916 LOG_INFO(BSL_LS_SOC_MII, 7917 (BSL_META_U(unit, 7918 "soc_trident3_tscx_reg_read[%d]: %d/%d/%d/%d\n"), 7919 unit, phy_addr, phy_port, port, blk)); 7920 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 7921 rv = soc_sbus_tsc_reg_read(unit, port, blk, phy_addr, 7922 phy_reg, phy_data); 7923 return rv; 7924 } 7925 7926 STATIC int 7927 _soc_trident3_tscx_reg_write(int unit, uint32 phy_addr, 7928 uint32 phy_reg, uint32 phy_data) 7929 { 7930 int rv, blk, port; 7931 int phy_port = _soc_trident3_mdio_addr_to_port(phy_addr); 7932 7933 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 7934 blk = SOC_PORT_BLOCK(unit, phy_port); 7935 LOG_INFO(BSL_LS_SOC_MII, 7936 (BSL_META_U(unit, 7937 "soc_trident3_tscx_reg_write[%d]: %d/%d/%d/%d\n"), 7938 unit, phy_addr, phy_port, port, blk)); 7939 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 7940 rv = soc_sbus_tsc_reg_write(unit, port, blk, phy_addr, 7941 phy_reg, phy_data); 7942 return rv; 7943 } 7944 7945 #ifdef BCM_CMICX_SUPPORT 7946 STATIC int 7947 _soc_td3_ledup_init(int unit) 7948 { 7949 soc_info_t *si = &SOC_INFO(unit); 7950 int freq; 7951 uint32 rval, clk_half_period, refresh_period; 7952 7953 /* freq in KHz */ 7954 freq = (si->frequency) * 1000; 7955 7956 /* For LED refresh period = 33 ms (about 30Hz) */ 7957 7958 /* refresh period 7959 = (required refresh period in sec)*(switch clock frequency in Hz) 7960 */ 7961 refresh_period = (freq * 33); 7962 7963 rval = 0; 7964 soc_reg_field_set(unit, U0_LED_REFRESH_CTRLr, &rval, 7965 REFRESH_CYCLE_PERIODf, refresh_period); 7966 7967 SOC_IF_ERROR_RETURN(WRITE_U0_LED_REFRESH_CTRLr(unit, rval)); 7968 7969 /* For LED clock period */ 7970 /* LEDCLK_HALF_PERIOD 7971 = [(required LED clock period in sec)/2]*(M0SS clock frequency in Hz) 7972 7973 Where M0SS freqency is 858MHz and 7974 Typical LED clock period is 200ns(5MHz) = 2*10^-7 7975 */ 7976 freq = 858 * 1000000; 7977 clk_half_period = (freq + 2500000) / 5000000; 7978 clk_half_period = clk_half_period / 2; 7979 7980 rval = 0; 7981 soc_reg_field_set(unit, U0_LED_CLK_DIV_CTRLr, &rval, 7982 LEDCLK_HALF_PERIODf, clk_half_period); 7983 7984 SOC_IF_ERROR_RETURN(WRITE_U0_LED_CLK_DIV_CTRLr(unit, rval)); 7985 7986 /* Fixed for TD3 7987 * When PM shift out the led data, it shift out lane 3 first,followed by lane 2, 1, and 0. 7988 * The LAST_PORT value to be the port number of sub-port 0. (124 for TD3) 7989 */ 7990 7991 SOC_IF_ERROR_RETURN(READ_U0_LED_ACCU_CTRLr(unit, &rval)); 7992 soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval, 7993 LAST_PORTf, 124); 7994 soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval, 7995 PORT_ENDIANNESSf, 1); 7996 SOC_IF_ERROR_RETURN(WRITE_U0_LED_ACCU_CTRLr(unit, rval)); 7997 7998 /* Initialize M0s for LED and Firmware Link Scan*/ 7999 SOC_IF_ERROR_RETURN(soc_iproc_m0_init(unit)); 8000 8001 return SOC_E_NONE; 8002 } 8003 8004 #endif /* BCM_CMICX_SUPPORT */ 8005 8006 /* 8007 * Function: 8008 * _soc_trident3_mmu_ep_credit_reset 8009 * Purpose: 8010 * Initalize EP credits in MMU so EP is in charge 8011 * of distributing the correct number of credits. 8012 * Parameters: 8013 * unit - (IN) Unit number. 8014 * port - (IN) Logical SOC port number. 8015 * Returns: 8016 * SOC_E_XXX 8017 */ 8018 STATIC int 8019 _soc_trident3_mmu_ep_credit_reset(int unit, soc_port_t port) 8020 { 8021 soc_reg_t reg; 8022 uint32 rval = 0; 8023 8024 reg = MMU_PORT_CREDITr; 8025 8026 soc_reg_field_set(unit, reg, &rval, INITIALIZEf, 1); 8027 SOC_IF_ERROR_RETURN 8028 (soc_reg32_set(unit, reg, port, 0, rval)); 8029 SOC_IF_ERROR_RETURN 8030 (soc_reg32_set(unit, reg, port, 0, 0)); 8031 8032 return SOC_E_NONE; 8033 } 8034 8035 /* 8036 * Function: 8037 * _soc_trident3_ing_fsaf_init 8038 * Purpose: 8039 * Initalize ForceSAF global settings. 8040 * Currently, duration register is set. Should always be 8041 * targeted for a minimum duration of 2us. 8042 * Parameters: 8043 * unit - (IN) Unit number. 8044 * port - (IN) Logical SOC port number. 8045 * Returns: 8046 * SOC_E_XXX 8047 * Note: 8048 * Per port settings leverage ASF init process. 8049 */ 8050 STATIC int 8051 _soc_trident3_ing_fsaf_init(int unit) 8052 { 8053 int pipe; 8054 int duration; 8055 uint64 rval64; 8056 soc_info_t *si = &SOC_INFO(unit); 8057 soc_reg_t reg; 8058 static const soc_reg_t idb_fsaf_cfg = IDB_DBG_Br; 8059 8060 duration = si->frequency * 2; 8061 for (pipe = 0; pipe < si->num_pipe; pipe ++) { 8062 reg = SOC_REG_UNIQUE_ACC(unit, idb_fsaf_cfg)[pipe]; 8063 SOC_IF_ERROR_RETURN 8064 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 8065 soc_reg64_field32_set(unit, reg, &rval64, FIELD_Af, duration); 8066 SOC_IF_ERROR_RETURN 8067 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 8068 } 8069 8070 return SOC_E_NONE; 8071 } 8072 8073 /* 8074 * Function: 8075 * soc_trident3_edb_buf_reset 8076 * Purpose: 8077 * Initialize EP credits in MMU, release EDB port buffer and 8078 * enable cell request in EP. 8079 * Parameters: 8080 * unit - (IN) Unit number. 8081 * port - (IN) Logical SOC port number. 8082 * reset - (IN) Reset. 8083 * Returns: 8084 * SOC_E_XXX 8085 */ 8086 int 8087 soc_trident3_edb_buf_reset(int unit, soc_port_t port, int reset) 8088 { 8089 soc_info_t *si = &SOC_INFO(unit); 8090 uint32 entry[SOC_MAX_MEM_WORDS]; 8091 int phy_port; 8092 uint32 rval; 8093 int level; 8094 soc_timeout_t to; 8095 int wait_time = 250000; 8096 8097 if (SAL_BOOT_QUICKTURN) { 8098 wait_time *= 20; 8099 } 8100 8101 /* Get physical port */ 8102 phy_port = si->port_l2p_mapping[port]; 8103 if (phy_port == -1) { 8104 return SOC_E_INTERNAL; 8105 } 8106 8107 if (reset) { 8108 /* Set register to get number of used entries in EDB buffer */ 8109 SOC_IF_ERROR_RETURN 8110 (READ_EGR_EDB_MISC_CTRLr(unit, &rval)); 8111 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, 8112 SELECT_CURRENT_USED_ENTRIESf, 1); 8113 SOC_IF_ERROR_RETURN 8114 (WRITE_EGR_EDB_MISC_CTRLr(unit, rval)); 8115 8116 soc_timeout_init(&to, wait_time, 0); 8117 8118 /* Poll until EDB buffer is empty */ 8119 for (;;) { 8120 SOC_IF_ERROR_RETURN 8121 (READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, 8122 phy_port, entry)); 8123 level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, 8124 entry, LEVELf); 8125 if (level == 0) { 8126 break; 8127 } 8128 if (soc_timeout_check(&to)) { 8129 LOG_ERROR(BSL_LS_SOC_PORT, 8130 (BSL_META_U(unit, 8131 "EDB buffer drain timeout: " 8132 "port %d, %s, " 8133 "timeout (pending: %d)\n"), 8134 unit, SOC_PORT_NAME(unit, port), level)); 8135 return SOC_E_INTERNAL; 8136 } 8137 } 8138 8139 /* 8140 * Hold EDB port buffer in reset state and disable cell 8141 * request generation in EP. 8142 */ 8143 SOC_IF_ERROR_RETURN 8144 (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 8145 phy_port, entry)); 8146 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 8147 entry, ENABLEf, 1); 8148 SOC_IF_ERROR_RETURN 8149 (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 8150 phy_port, entry)); 8151 SOC_IF_ERROR_RETURN 8152 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 8153 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 0); 8154 SOC_IF_ERROR_RETURN 8155 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 8156 8157 } else { 8158 8159 /* Initialize EP credits in MMU */ 8160 SOC_IF_ERROR_RETURN(_soc_trident3_mmu_ep_credit_reset(unit, port)); 8161 8162 /* 8163 * Release EDB port buffer reset and 8164 * enable cell request generation in EP. 8165 */ 8166 SOC_IF_ERROR_RETURN 8167 (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 8168 phy_port, entry)); 8169 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 8170 entry, ENABLEf, 0); 8171 SOC_IF_ERROR_RETURN 8172 (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 8173 phy_port, entry)); 8174 8175 SOC_IF_ERROR_RETURN 8176 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 8177 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 8178 SOC_IF_ERROR_RETURN 8179 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 8180 } 8181 8182 return SOC_E_NONE; 8183 } 8184 8185 soc_error_t 8186 soc_trident3_idb_buf_reset(int unit, soc_port_t port, int reset) 8187 { 8188 soc_reg_t reg, reg1; 8189 int port_block_base, phy_port, lane; 8190 int pipe, obm, clport, obm_usage_count = ~0, ca_empty = 0; 8191 uint32 rval; 8192 uint64 rval1, rval2; 8193 soc_info_t *si = &SOC_INFO(unit); 8194 static const soc_reg_t idb_obm_usage_regs[] = { 8195 IDB_OBM0_USAGEr, IDB_OBM1_USAGEr, 8196 IDB_OBM2_USAGEr, IDB_OBM3_USAGEr, 8197 IDB_OBM4_USAGEr, IDB_OBM5_USAGEr, 8198 IDB_OBM6_USAGEr, IDB_OBM7_USAGEr, 8199 IDB_OBM8_USAGEr, IDB_OBM9_USAGEr, 8200 IDB_OBM10_USAGEr, IDB_OBM11_USAGEr, 8201 IDB_OBM12_USAGEr, IDB_OBM13_USAGEr, 8202 IDB_OBM14_USAGEr, IDB_OBM15_USAGEr 8203 }; 8204 static const soc_reg_t idb_obm_ca_status_regs[] = { 8205 IDB_OBM0_CA_HW_STATUSr, IDB_OBM1_CA_HW_STATUSr, 8206 IDB_OBM2_CA_HW_STATUSr, IDB_OBM3_CA_HW_STATUSr, 8207 IDB_OBM4_CA_HW_STATUSr, IDB_OBM5_CA_HW_STATUSr, 8208 IDB_OBM6_CA_HW_STATUSr, IDB_OBM7_CA_HW_STATUSr, 8209 IDB_OBM8_CA_HW_STATUSr, IDB_OBM9_CA_HW_STATUSr, 8210 IDB_OBM10_CA_HW_STATUSr, IDB_OBM11_CA_HW_STATUSr, 8211 IDB_OBM12_CA_HW_STATUSr, IDB_OBM13_CA_HW_STATUSr, 8212 IDB_OBM14_CA_HW_STATUSr, IDB_OBM15_CA_HW_STATUSr 8213 }; 8214 static const soc_reg_t obm_ctrl_regs[] = { 8215 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 8216 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 8217 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 8218 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, 8219 IDB_OBM8_CONTROLr, IDB_OBM9_CONTROLr, 8220 IDB_OBM10_CONTROLr, IDB_OBM11_CONTROLr, 8221 IDB_OBM12_CONTROLr, IDB_OBM13_CONTROLr, 8222 IDB_OBM14_CONTROLr, IDB_OBM15_CONTROLr 8223 }; 8224 static const soc_reg_t obm_ca_ctrl_regs[] = { 8225 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, 8226 IDB_OBM2_CA_CONTROLr, IDB_OBM3_CA_CONTROLr, 8227 IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 8228 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 8229 IDB_OBM8_CA_CONTROLr, IDB_OBM9_CA_CONTROLr, 8230 IDB_OBM10_CA_CONTROLr, IDB_OBM11_CA_CONTROLr, 8231 IDB_OBM12_CA_CONTROLr, IDB_OBM13_CA_CONTROLr, 8232 IDB_OBM14_CA_CONTROLr, IDB_OBM15_CA_CONTROLr, 8233 }; 8234 static const soc_field_t fifo_empty_port_fields[] = { 8235 FIFO_EMPTY_PORT0f, FIFO_EMPTY_PORT1f, FIFO_EMPTY_PORT2f, 8236 FIFO_EMPTY_PORT3f 8237 }; 8238 static const soc_field_t port_reset_fields[] = { 8239 PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf 8240 }; 8241 8242 phy_port = si->port_l2p_mapping[port]; 8243 port_block_base = PORT_BLOCK_BASE_PORT(port); 8244 lane = phy_port - port_block_base; 8245 pipe = si->port_pipe[port]; 8246 clport = si->port_serdes[port]; 8247 obm = clport & 0xF; 8248 8249 if (reset && !SAL_BOOT_SIMULATION) { 8250 soc_timeout_t to; 8251 8252 reg = SOC_REG_UNIQUE_ACC(unit, idb_obm_usage_regs[obm])[pipe]; 8253 reg1 = SOC_REG_UNIQUE_ACC(unit, idb_obm_ca_status_regs[obm])[pipe]; 8254 8255 soc_timeout_init(&to, 250000, 0); 8256 /* Poll until IDB buffer is empty */ 8257 for (;;) { 8258 if (0 != obm_usage_count) { 8259 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, lane, 8260 &rval1)); 8261 obm_usage_count = soc_reg64_field32_get(unit, reg, rval1, 8262 TOTAL_COUNTf); 8263 } 8264 if (0 == ca_empty) { 8265 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, 8266 &rval2)); 8267 ca_empty = soc_reg64_field32_get(unit, reg1, rval2, 8268 fifo_empty_port_fields[lane]); 8269 } 8270 if ((0 == obm_usage_count) && (1 == ca_empty)) { 8271 break; 8272 } 8273 if (soc_timeout_check(&to)) { 8274 LOG_ERROR(BSL_LS_SOC_COMMON, 8275 (BSL_META_U(unit, 8276 "IDBBufferDrainTimeOut:port %d,%s, timeout" 8277 "(idb_obm_usage: %d) " 8278 "(ca_fifo_empty: %d)\n"), 8279 unit, SOC_PORT_NAME(unit, port), obm_usage_count, 8280 ca_empty)); 8281 return SOC_E_INTERNAL; 8282 } 8283 } 8284 } 8285 8286 reg = SOC_REG_UNIQUE_ACC(unit, obm_ctrl_regs[obm])[pipe]; 8287 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 8288 soc_reg_field_set(unit, reg, &rval, port_reset_fields[lane], reset); 8289 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 8290 8291 reg = SOC_REG_UNIQUE_ACC(unit, obm_ca_ctrl_regs[obm])[pipe]; 8292 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 8293 soc_reg_field_set(unit, reg, &rval, port_reset_fields[lane], reset); 8294 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 8295 8296 return SOC_E_NONE; 8297 } 8298 8299 /* 8300 * Function: 8301 * soc_td3_speed_class_validate 8302 * Purpose: 8303 * Check speed classes 8304 * Parameters: 8305 * unit - (IN) Unit number. 8306 * Returns: 8307 * SOC_E_XXX 8308 * Note: 8309 * This function is called at early stage of initialization for 8310 * port configuration check. 8311 */ 8312 int 8313 soc_td3_speed_class_validate(int unit) 8314 { 8315 soc_info_t *si = &SOC_INFO(unit); 8316 int port, speed; 8317 uint32 speed_mask, count; 8318 8319 speed_mask = 0; 8320 PBMP_PORT_ITER(unit, port) { 8321 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) || 8322 IS_MANAGEMENT_PORT(unit, port) || IS_CPU_PORT(unit, port) || 8323 IS_LB_PORT(unit, port)) { 8324 continue; 8325 } 8326 speed = soc_port_speed_higig2eth(si->port_speed_max[port]); 8327 speed_mask |= SOC_PA_SPEED(speed); 8328 } 8329 8330 count = _shr_popcount(speed_mask); 8331 if (count > ((si->oversub_mode) ? 5 : 4)) { 8332 LOG_ERROR(BSL_LS_BCM_COMMON, 8333 (BSL_META_U(unit, 8334 "No port configurations with more than 4 port " 8335 "speed classes are supported.\n"))); 8336 return SOC_E_CONFIG; 8337 } 8338 8339 if(SOC_FAILURE(soc_td3_speed_mix_validate(unit, speed_mask))) { 8340 return SOC_E_CONFIG; 8341 } 8342 8343 return SOC_E_NONE; 8344 } 8345 8346 8347 STATIC int 8348 _soc_trident3_misc_init(int unit) 8349 { 8350 #if defined(BCM_56870_A0) 8351 soc_control_t *soc; 8352 soc_info_t *si; 8353 int block_info_idx; 8354 soc_mem_t mem; 8355 soc_reg_t reg; 8356 uint32 rval, fval; 8357 uint64 rval64; 8358 soc_field_t fields[2]; 8359 uint32 values[2]; 8360 uint32 entry[SOC_MAX_MEM_WORDS]; 8361 soc_pbmp_t pbmp; 8362 int clport, lane, mode, index, factor; 8363 uint32 correction_duration, detection_duration; 8364 int port, phy_port, phy_port_base; 8365 int parity_enable, pbm_count=0; 8366 modport_map_subport_entry_t map_entry; 8367 ing_dest_port_enable_entry_t ingr_entry; 8368 8369 static soc_field_t port_fields[_TD3_PORTS_PER_PBLK] = { 8370 PORT0f, PORT1f, PORT2f, PORT3f 8371 }; 8372 static const int mode_encodings[SOC_TD3_PORT_RATIO_COUNT] = { 8373 4, 3, 3, 3, 2, 2, 1, 1, 0 8374 }; 8375 uint32 mc_ctrl = 0; 8376 int fabric_port_enable = 1; 8377 int int_divisor, ext_divisor, delay; 8378 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 8379 int num_overlay_ecmp_rh_flowset_entries; 8380 int ecmp_levels = 1; 8381 #endif 8382 int num_lag_rh_flowset_entries; 8383 8384 soc = SOC_CONTROL(unit); 8385 si = &SOC_INFO(unit); 8386 8387 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 8388 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit)); 8389 8390 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 8391 if (parity_enable) { 8392 if (!SOC_WARM_BOOT(unit)) { 8393 /* Initialize PORT MIB counter */ 8394 rval = 0; 8395 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 8396 port = SOC_BLOCK_PORT(unit, block_info_idx); 8397 soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 8398 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval)); 8399 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0)); 8400 } 8401 rval = 0; 8402 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) { 8403 port = SOC_BLOCK_PORT(unit, block_info_idx); 8404 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 8405 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval)); 8406 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0)); 8407 } 8408 /* Certain mems/regs need to be cleared before enabling SER */ 8409 SOC_IF_ERROR_RETURN(soc_trident3_clear_mmu_memory(unit)); 8410 /*SOC_IF_ERROR_RETURN(_soc_trident3_clear_all_port_data(unit));*/ 8411 } 8412 soc_ser_alpm_cache_check(unit); 8413 soc_ser_log_init(unit, NULL, 0); 8414 8415 /* Enable l2_mgmt interrupt */ 8416 SOC_IF_ERROR_RETURN 8417 (soc_reg_field32_modify(unit, L2_MGMT_INTR_MASKr, REG_PORT_ANY, 8418 SER_FIFO_NOT_EMPTYf, 1)); 8419 8420 #ifdef BCM_CMICX_SUPPORT 8421 if (soc_feature(unit, soc_feature_cmicx)) { 8422 8423 /* (void)soc_cmicm_intr3_enable(unit, 0x2); L2_MGMT_TO_CMIC_INTR bit 1 */ 8424 } 8425 #endif 8426 soc_trident3_tcam_ser_init(unit); 8427 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_all(unit, TRUE)); 8428 soc_trident3_ser_register(unit); 8429 8430 #if defined(SER_TR_TEST_SUPPORT) 8431 /*Initialize chip-specific functions for SER testing*/ 8432 soc_td3_ser_test_register(unit); 8433 #endif /*defined(SER_TR_TEST_SUPPORT*/ 8434 } 8435 8436 #ifdef BCM_CMICX_SUPPORT 8437 if (soc_feature(unit, soc_feature_cmicx) && !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) { 8438 SOC_IF_ERROR_RETURN(_soc_td3_ledup_init(unit)); 8439 } 8440 #endif /* BCM_CMICX_SUPPORT */ 8441 8442 SOC_IF_ERROR_RETURN(_soc_trident3_init_mmu_memory(unit)); 8443 8444 if (parity_enable) { 8445 SOC_IF_ERROR_RETURN(soc_trident3_ser_enable_parity_table_all(unit, TRUE)); 8446 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval)); 8447 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, 1); 8448 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 8449 } 8450 8451 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 8452 SOC_IF_ERROR_RETURN( 8453 _soc_cancun_load_status_clear(unit, CANCUN_SOC_FILE_TYPE_CIH)); 8454 /* Dummy call to clear garbage h/w values */ 8455 SOC_IF_ERROR_RETURN 8456 (soc_trident3_temperature_monitor_get(unit, 8457 COUNTOF(pvtmon_result_reg), 8458 NULL, 8459 NULL)); 8460 } 8461 8462 /* UFT/UAT config programming */ 8463 SOC_IF_ERROR_RETURN(soc_trident3_uft_uat_config(unit)); 8464 soc_cancun_init(unit); 8465 soc_trident3_latency_config(unit); 8466 _soc_trident3_port_mapping_init(unit); 8467 8468 /* 8469 * Parse config at init time and cache property value for use at 8470 * run time 8471 */ 8472 if (SOC_PBMP_NOT_NULL(PBMP_HG_ALL(unit))) { 8473 fabric_port_enable = 1; 8474 } else { 8475 fabric_port_enable = soc_property_get(unit, spn_FABRIC_PORT_ENABLE, 1); 8476 } 8477 SOC_CONTROL_LOCK(unit); 8478 si->fabric_port_enable = fabric_port_enable; 8479 SOC_CONTROL_UNLOCK(unit); 8480 8481 8482 if (!SAL_BOOT_XGSSIM) { 8483 if (soc->tdm_info == NULL) { 8484 soc->tdm_info = sal_alloc(sizeof(_soc_trident3_tdm_temp_t), 8485 "Trident3 TDM info"); 8486 if (soc->tdm_info == NULL) { 8487 return SOC_E_MEMORY; 8488 } 8489 sal_memset(soc->tdm_info, 0, sizeof(_soc_trident3_tdm_temp_t)); 8490 } 8491 _soc_trident3_tdm_init(unit); 8492 _soc_trident3_idb_init(unit); 8493 } 8494 8495 /* Check the speed classes */ 8496 SOC_IF_ERROR_RETURN(soc_td3_speed_class_validate(unit)); 8497 8498 sal_memset(entry, 0, sizeof(cpu_pbm_entry_t)); 8499 soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit)); 8500 SOC_IF_ERROR_RETURN 8501 (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry)); 8502 8503 sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t)); 8504 soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit)); 8505 SOC_IF_ERROR_RETURN 8506 (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry)); 8507 8508 #if __GNUC__ > 6 8509 #pragma GCC diagnostic push 8510 #pragma GCC diagnostic ignored "-Wmemset-elt-size" 8511 #endif 8512 /* 8513 * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for 8514 * performance reasons, because the actual soc_mem_field_set() 8515 * will only write sizeof(device_loopback_ports_bitmap_entry_t)=17 8516 * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651 8517 * depending on which devices are compiled in. 8518 */ 8519 sal_memset(entry, 0, sizeof(device_loopback_ports_bitmap_entry_t)); 8520 #if __GNUC__ > 6 8521 #pragma GCC diagnostic pop 8522 #endif 8523 soc_mem_pbmp_field_set(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, entry, BITMAPf, 8524 &PBMP_LB(unit)); 8525 SOC_IF_ERROR_RETURN 8526 (soc_mem_write(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, MEM_BLOCK_ALL, 0, 8527 entry)); 8528 8529 PBMP_LB_ITER(unit, port) { 8530 mem = SOC_MEM_UNIQUE_ACC(unit, MULTIPASS_LOOPBACK_BITMAPm) 8531 [si->port_pipe[port]]; 8532 sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t)); 8533 SOC_PBMP_PORT_SET(pbmp, port); 8534 soc_mem_pbmp_field_set(unit, mem, &entry, BITMAPf, &pbmp); 8535 SOC_IF_ERROR_RETURN 8536 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry)); 8537 } 8538 8539 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 8540 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 8541 PBMP_HG_ITER(unit, port) { 8542 SOC_IF_ERROR_RETURN 8543 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 8544 } 8545 SOC_IF_ERROR_RETURN 8546 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index, 8547 entry)); 8548 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2); 8549 PBMP_LB_ITER(unit, port) { 8550 SOC_IF_ERROR_RETURN 8551 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 8552 } 8553 8554 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 8555 port = SOC_BLOCK_PORT(unit, block_info_idx); 8556 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 8557 phy_port_base = PORT_BLOCK_BASE_PORT(port); 8558 8559 /* Assert CLPORT soft reset */ 8560 rval = 0; 8561 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane++) { 8562 if (si->port_p2l_mapping[phy_port_base + lane] != -1) { 8563 soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &rval, 8564 port_fields[lane], 1); 8565 } 8566 } 8567 SOC_IF_ERROR_RETURN(WRITE_CLPORT_SOFT_RESETr(unit, port, rval)); 8568 8569 /* Set port mode */ 8570 soc_trident3_port_ratio_get(unit, clport, &mode); 8571 rval = 0; 8572 soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_CORE_PORT_MODEf, 8573 mode_encodings[mode]); 8574 soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_PHY_PORT_MODEf, 8575 mode_encodings[mode]); 8576 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MODE_REGr(unit, port, rval)); 8577 8578 /* De-assert XLPORT soft reset */ 8579 SOC_IF_ERROR_RETURN(WRITE_CLPORT_SOFT_RESETr(unit, port, 0)); 8580 8581 /* Enable CLPORT */ 8582 rval = 0; 8583 for (lane = 0; lane < _TD3_PORTS_PER_PBLK; lane++) { 8584 if (si->port_p2l_mapping[phy_port_base + lane] != -1) { 8585 soc_reg_field_set(unit, CLPORT_ENABLE_REGr, &rval, 8586 port_fields[lane], 1); 8587 } 8588 } 8589 SOC_IF_ERROR_RETURN(WRITE_CLPORT_ENABLE_REGr(unit, port, rval)); 8590 } 8591 8592 SOC_PBMP_COUNT(si->management_pbm, pbm_count); 8593 /* In case of dual management port - program top misc control */ 8594 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROLr(unit,&rval)); 8595 soc_reg_field_set(unit, TOP_MISC_CONTROLr, &rval, ENABLE_2ND_MGMT_PORTf, 8596 (pbm_count > 1)? 1 : 0); 8597 WRITE_TOP_MISC_CONTROLr(unit, rval); 8598 8599 SOC_IF_ERROR_RETURN(READ_SECOND_MGMT_PORTr(unit,&rval)); 8600 soc_reg_field_set(unit, SECOND_MGMT_PORTr, &rval, ENABLEf, 8601 (pbm_count > 1)? 1 : 0); 8602 WRITE_SECOND_MGMT_PORTr(unit, rval); 8603 8604 SOC_PBMP_ITER(si->management_pbm, port) { 8605 /* Assert XLPORT soft reset */ 8606 rval = 0; 8607 if (si->port_p2l_mapping[129] != -1) { /* management port 0 */ 8608 soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &rval, PORT0f, 1); 8609 } 8610 if (si->port_p2l_mapping[128] != -1) { /* management port 1 */ 8611 soc_reg_field_set(unit, XLPORT_SOFT_RESETr, &rval, PORT2f, 1); 8612 } 8613 SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, rval)); 8614 8615 /* Set port mode to DUAL */ 8616 rval = 0; 8617 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, XPORT0_CORE_PORT_MODEf, 8618 3); 8619 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, XPORT0_PHY_PORT_MODEf, 8620 3); 8621 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 8622 8623 /* De-assert XLPORT soft reset */ 8624 SOC_IF_ERROR_RETURN(WRITE_XLPORT_SOFT_RESETr(unit, port, 0)); 8625 8626 /* Enable XLPORT */ 8627 rval = 0; 8628 if (si->port_p2l_mapping[129] != -1) { /* management port 0 */ 8629 soc_reg_field_set(unit, XLPORT_ENABLE_REGr, &rval, PORT0f, 1); 8630 } 8631 if (si->port_p2l_mapping[128] != -1) { /* management port 0 */ 8632 soc_reg_field_set(unit, XLPORT_ENABLE_REGr, &rval, PORT2f, 1); 8633 } 8634 SOC_IF_ERROR_RETURN(WRITE_XLPORT_ENABLE_REGr(unit, port, rval)); 8635 } 8636 8637 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval)); 8638 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, REFRESH_ENf, 1); 8639 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 8640 8641 /* Enable dual hash tables */ 8642 SOC_IF_ERROR_RETURN(soc_trident3_hash_init(unit)); 8643 8644 /* Configure EP credit */ 8645 sal_memset(entry, 0, sizeof(egr_mmu_cell_credit_entry_t)); 8646 PBMP_ALL_ITER(unit, port) { 8647 SOC_IF_ERROR_RETURN( 8648 soc_td3_port_asf_speed_to_mmu_cell_credit(unit, port, 8649 si->port_speed_max[port], &fval)); 8650 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 8651 si->port_l2p_mapping[port], &entry)); 8652 soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &entry, CREDITf, fval); 8653 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ALL, 8654 si->port_l2p_mapping[port], &entry)); 8655 } 8656 8657 /* Configure egress transmit start count */ 8658 PBMP_ALL_ITER(unit, port) { 8659 SOC_IF_ERROR_RETURN( 8660 soc_td3_port_asf_xmit_start_count_set(unit, port, 8661 si->port_speed_max[port], _SOC_TD3_ASF_MODE_SAF, 0)); 8662 } 8663 8664 /* Ingress Force SAF */ 8665 SOC_IF_ERROR_RETURN(_soc_trident3_ing_fsaf_init(unit)); 8666 8667 /* Egress Force SAF */ 8668 if (SOC_PBMP_NOT_NULL(si->oversub_pbm)) { 8669 factor = 178125; 8670 mem = EDB_1DBG_Bm; 8671 sal_memset(entry, 0, sizeof(edb_1dbg_b_entry_t)); 8672 8673 PBMP_ALL_ITER(unit, port) { 8674 fval = ((si->port_speed_max[port] / 10) * factor) / 100000; 8675 soc_mem_field32_set(unit, mem, &entry, FIELD_Bf, fval); 8676 SOC_IF_ERROR_RETURN 8677 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 8678 si->port_l2p_mapping[port], entry)); 8679 } 8680 8681 for (index = 0; index < NUM_PIPE(unit); index++) { 8682 if (SOC_PBMP_IS_NULL(si->pipe_pbm[index])) { 8683 continue; 8684 } 8685 reg = SOC_REG_UNIQUE_ACC(unit, EDB_1DBG_Ar)[index]; 8686 SOC_IF_ERROR_RETURN 8687 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 8688 correction_duration = 135 * si->frequency / 10; 8689 detection_duration = 15 * si->frequency / 10; 8690 soc_reg64_field32_set(unit, EDB_1DBG_Ar, &rval64, FIELD_Af, detection_duration); 8691 soc_reg64_field32_set(unit, EDB_1DBG_Ar, &rval64, FIELD_Bf, correction_duration); 8692 soc_reg64_field32_set(unit, EDB_1DBG_Ar, &rval64, FIELD_Cf, 25); 8693 SOC_IF_ERROR_RETURN 8694 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 8695 } 8696 } 8697 8698 /* Enable egress */ 8699 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 8700 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 8701 PBMP_ALL_ITER(unit, port) { 8702 phy_port = si->port_l2p_mapping[port]; 8703 SOC_IF_ERROR_RETURN 8704 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 8705 } 8706 8707 sal_memset(entry, 0, sizeof(epc_link_bmap_entry_t)); 8708 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, 8709 &PBMP_CMIC(unit)); 8710 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry)); 8711 8712 /* enable all ports */ 8713 sal_memset(&ingr_entry, 0, sizeof(ingr_entry)); 8714 soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, &ingr_entry, 8715 PORT_BITMAPf, &PBMP_ALL(unit)); 8716 SOC_IF_ERROR_RETURN( 8717 WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0, &ingr_entry)); 8718 8719 sal_memset(&map_entry, 0, sizeof(map_entry)); 8720 soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, ENABLEf, 1); 8721 8722 /* my_modid and other modid related initialization */ 8723 PBMP_ALL_ITER(unit, port) { 8724 /* configure logical port numbers */ 8725 soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, 8726 DESTf, port); 8727 SOC_IF_ERROR_RETURN(WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL, 8728 port, &map_entry)); 8729 } 8730 8731 /* setting up my_modid */ 8732 SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64)); 8733 8734 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 8735 MODID_0_VALIDf, 1); 8736 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 8737 MODID_0f, SOC_BASE_MODID(unit)); 8738 8739 SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64)); 8740 8741 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64)); 8742 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8743 L3SRC_HIT_ENABLEf, 1); 8744 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8745 L2DST_HIT_ENABLEf, 1); 8746 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8747 APPLY_EGR_MASK_ON_L2f, 1); 8748 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8749 APPLY_EGR_MASK_ON_L3f, 1); 8750 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8751 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 8752 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8753 ARP_VALIDATION_ENf, 1); 8754 if (soc_feature(unit, soc_feature_port_lag_failover)) { 8755 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8756 IGNORE_HG_HDR_LAG_FAILOVERf, 0); 8757 } else { 8758 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8759 IGNORE_HG_HDR_LAG_FAILOVERf, 1); 8760 } 8761 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 8762 APPLY_HG_MGID_ADJUSTf, 0xFF); 8763 8764 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64)); 8765 8766 8767 8768 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 8769 * causes the outer tag to be removed from packets that don't have 8770 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 8771 */ 8772 /* Programming EGR_VLAN_CONTROL_1m table */ 8773 #if 0 8774 /* Can't call bcm function in soc layer. */ 8775 if (soc_feature(unit, soc_feature_egr_all_profile)) { 8776 PBMP_ALL_ITER(unit, port) { 8777 soc_field_t flds = {VT_MISS_UNTAGf, REMARK_OUTER_DOT1Pf}; 8778 uint32 vals = {0, 1}; 8779 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(unit, 8780 port, EGR_VLAN_CONTROL_1m, flds, vals); 8781 } 8782 } 8783 #endif 8784 8785 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 8786 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 8787 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 8788 MEM_BLOCK_ANY, 0, &entry)); 8789 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, 8790 &pbmp); 8791 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 8792 MEM_BLOCK_ANY, 0, &entry)); 8793 8794 /* Multicast range initialization */ 8795 SOC_IF_ERROR_RETURN 8796 (soc_hbx_higig2_mcast_sizes_set(unit, 8797 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 8798 SOC_HBX_MULTICAST_RANGE_DEFAULT), 8799 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 8800 soc_mem_index_count(unit, L2MCm)), 8801 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 8802 soc_mem_index_count(unit, L3_IPMCm)))); 8803 8804 soc->mcast_size = soc_property_get(unit, spn_MULTICAST_L2_RANGE, 8805 soc_mem_index_count(unit, L2MCm)); 8806 soc->ipmc_size = soc_property_get(unit, spn_MULTICAST_L3_RANGE, 8807 soc_mem_index_count(unit, L3_IPMCm)); 8808 8809 SOC_IF_ERROR_RETURN(READ_MC_CONTROL_4r(unit, &mc_ctrl)); 8810 8811 soc_reg_field_set(unit, MC_CONTROL_4r, &mc_ctrl, 8812 ALLOW_IPMC_INDEX_WRAP_AROUNDf, 1); 8813 SOC_IF_ERROR_RETURN 8814 (WRITE_MC_CONTROL_4r(unit, mc_ctrl)); 8815 8816 /* spn_RATE_EXT_MDIO_DIVIDEND and spn_RATE_INT_MDIO_DIVIDEND are 8817 * NOT applicable to TRIDENT3. 8818 */ 8819 8820 /* MDIO Clock Frquency for TD3 is 250 MHz 8821 * Set external MDIO freq to around 5 MHz 8822 * Hence divisor is set to 50 8823 */ 8824 8825 ext_divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, 50); 8826 8827 /* 8828 * Set internal MDIO freq to around 10 MHz 8829 * Valid range is from 2.5MHz to 20MHz 8830 * Hence divisor is set to 25 8831 */ 8832 int_divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, 25); 8833 8834 delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1); 8835 if (delay < 0 || delay > 255) { 8836 /* valid range for delay is 0-255 8837 * if outside this range, skip configuring delay 8838 */ 8839 delay = -1; 8840 } 8841 8842 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8843 (BSL_META_U(unit, 8844 "Config MIIM rings with int divisor %d, ext divisor %d, delay %d\n"), 8845 int_divisor, ext_divisor, delay)); 8846 8847 soc_cmicx_miim_divider_set_all(unit, int_divisor, ext_divisor, delay); 8848 8849 8850 _phy_tsce_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set; 8851 _phy_tscf_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set; 8852 8853 /* Check if Hierarchical ECMP mode is set */ 8854 if (soc_property_get(unit, spn_L3_ECMP_LEVELS, 1) == 2) { 8855 uint32 ecmp_mode = 1; 8856 rval = 0; 8857 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode); 8858 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 8859 8860 } else { 8861 uint32 rval = 0; 8862 uint32 ecmp_mode = 0; 8863 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode); 8864 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 8865 8866 } 8867 8868 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr, 8869 REG_PORT_ANY, ECMP_FLOWSET_TABLE_CONFIGf, 1)); 8870 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 8871 ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1); 8872 if ((soc_feature(unit, soc_feature_riot) || 8873 soc_feature(unit, soc_feature_multi_level_ecmp)) && 8874 ecmp_levels > 1 && soc_mem_index_count(unit,RH_ECMP_FLOWSETm)) { 8875 8876 num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit, 8877 spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0); 8878 8879 if (SOC_FIELD_RANGE_CHECK( 8880 num_overlay_ecmp_rh_flowset_entries, 0, 32768)) { 8881 num_overlay_ecmp_rh_flowset_entries = 32768; 8882 } 8883 8884 switch (num_overlay_ecmp_rh_flowset_entries) { 8885 case 0: 8886 break; 8887 case 32768: 8888 if (soc_mem_index_count(unit,RH_ECMP_FLOWSETm) >= 32768) { 8889 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 8890 ENHANCED_HASHING_CONTROLr, 8891 REG_PORT_ANY, ECMP_FLOWSET_TABLE_CONFIGf, 2)); 8892 } else { 8893 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 8894 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 8895 FUNCTION_NAME(), soc_mem_index_count(unit,RH_ECMP_FLOWSETm), 8896 num_overlay_ecmp_rh_flowset_entries)); 8897 return SOC_E_CONFIG; 8898 } 8899 break; 8900 default: 8901 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 8902 "%s: Value for overlay RH entries is not correct : %d \n"), 8903 FUNCTION_NAME(), num_overlay_ecmp_rh_flowset_entries)); 8904 return SOC_E_CONFIG; 8905 } 8906 } 8907 #endif 8908 8909 /* Setup SW2_FP_DST_ACTION_CONTROL */ 8910 fields[0] = HGTRUNK_RES_ENf; 8911 values[0] = 1; 8912 fields[1] = LAG_RES_ENf; 8913 values[1] = 1; 8914 SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, 8915 SW2_IFP_DST_ACTION_CONTROLr, 8916 REG_PORT_ANY, 2, fields, values)); 8917 8918 /* Enhanced hashing LAG/TRUNK config 8919 * LAG/TRUNK share the same flow set table used in RH 8920 * 64k is shared between LAG and HGT for 8921 * - 32k each - default 8922 * - 64K dedicated to HGT RH 8923 * - 64K dedicated to LAG RH 8924 */ 8925 num_lag_rh_flowset_entries = soc_property_get(unit, 8926 spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 32768); 8927 8928 switch (num_lag_rh_flowset_entries) { 8929 case 0: 8930 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 8931 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 1)); 8932 break; 8933 case 65536: 8934 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 8935 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 0)); 8936 break; 8937 case 32768: 8938 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 8939 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 2)); 8940 break; 8941 default: 8942 return SOC_E_CONFIG; 8943 } 8944 SOC_IF_ERROR_RETURN 8945 (soc_counter_tomahawk_status_enable(unit, TRUE)); 8946 8947 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8948 (BSL_META_U(unit, 8949 "MISC Init completed (u=%d)\n"), unit)); 8950 8951 /* Mem Scan thread start should be the last step in Misc init */ 8952 if (parity_enable) { 8953 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 8954 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit)); 8955 } 8956 8957 return SOC_E_NONE; 8958 #else 8959 return SOC_E_UNAVAIL; 8960 #endif 8961 } 8962 8963 8964 /* 8965 * Function used for index calculation of certain memories, 8966 * where index is derived from more than one key. 8967 * Eg. (Port, SP) or (Port, PG) 8968 * Defined as Macro: SOC_TD3_MMU_PIPED_MEM_INDEX 8969 * Note: If no special indexig required, return the same index. 8970 */ 8971 uint32 _soc_td3_piped_mem_index(int unit, soc_port_t port, 8972 soc_mem_t mem, int arr_off) 8973 { 8974 int mmu_port, index; 8975 8976 mmu_port = SOC_TD3_MMU_PORT(unit, port); 8977 8978 switch (mem) { 8979 case MMU_THDM_DB_PORTSP_CONFIGm: 8980 case MMU_THDM_MCQE_PORTSP_CONFIGm: 8981 #ifdef BCM_MAVERICK2_SUPPORT 8982 if (SOC_IS_MAVERICK2(unit)) { 8983 index = ((mmu_port & SOC_TD3_MMU_PORT_STRIDE) * _TD3_MMU_NUM_POOL) 8984 + arr_off; 8985 } else 8986 #endif 8987 { 8988 index = (_TD3_PORTS_PER_PIPE * arr_off) + (mmu_port & 8989 SOC_TD3_MMU_PORT_STRIDE); 8990 } 8991 break; 8992 case THDI_PORT_SP_CONFIGm: 8993 case MMU_THDU_CONFIG_PORTm: 8994 case MMU_THDU_RESUME_PORTm: 8995 case MMU_THDU_COUNTER_PORTm: 8996 index = ((mmu_port & SOC_TD3_MMU_PORT_STRIDE) * _TD3_MMU_NUM_POOL) 8997 + arr_off; 8998 break; 8999 case THDI_PORT_PG_CONFIGm: 9000 index = ((mmu_port & SOC_TD3_MMU_PORT_STRIDE) * _TD3_MMU_NUM_PG) 9001 + arr_off; 9002 break; 9003 default: 9004 return arr_off; 9005 } 9006 9007 return index; 9008 } 9009 9010 /* 9011 * Function: 9012 * soc_td3_mmu_bmp_reg_pos_get 9013 * Purpose: 9014 * Helper function for register resolve. 9015 * Can be used for registers that include only bitmap field. 9016 * Each bit in the bitmap is MMU port. 9017 * 2 splited registers are used to accomodate 66 ports for each pipe. 9018 * Parameters: 9019 * unit - (IN) Unit number. 9020 * port - (IN) Logical SOC port number. 9021 * pipe - (OUT) Pipe number. 9022 * split - (OUT) Reg split number. 9023 * pos - (OUT) Position in bitmap. 9024 * Returns: 9025 * SOC_E_XXX 9026 */ 9027 int 9028 soc_td3_mmu_bmp_reg_pos_get(int unit, soc_port_t port, 9029 int *pipe, int *split, int *pos) 9030 { 9031 int pipe_tmp, mmu_port, phy_port; 9032 int split_tmp, pos_tmp; 9033 soc_info_t *si; 9034 9035 si = &SOC_INFO(unit); 9036 pipe_tmp = si->port_pipe[port]; 9037 phy_port = si->port_l2p_mapping[port]; 9038 mmu_port = si->port_p2m_mapping[phy_port]; 9039 /* Reg config is per pipe, get local MMU port. */ 9040 mmu_port = mmu_port & SOC_TD3_MMU_PORT_STRIDE; 9041 9042 if (mmu_port < 64) { 9043 split_tmp = 0; 9044 pos_tmp = mmu_port; 9045 } else { 9046 split_tmp = 1; 9047 pos_tmp = mmu_port - 64; 9048 } 9049 9050 if (pipe != NULL) { 9051 *pipe = pipe_tmp; 9052 } 9053 if (split != NULL) { 9054 *split = split_tmp; 9055 } 9056 if (pos != NULL) { 9057 *pos = pos_tmp; 9058 } 9059 9060 return SOC_E_NONE; 9061 } 9062 9063 STATIC int 9064 _soc_td3_thdo_hw_get(int unit, soc_port_t port, int *enable) 9065 { 9066 uint64 rval64; 9067 int pipe, i; 9068 int split, pos; 9069 soc_reg_t reg[3][2] = { 9070 { 9071 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT0r, 9072 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT1r 9073 }, 9074 { 9075 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT0r, 9076 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT1r 9077 }, 9078 { 9079 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT0r, 9080 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT1r 9081 } 9082 }; 9083 9084 SOC_IF_ERROR_RETURN( 9085 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos)); 9086 9087 COMPILER_64_ZERO(rval64); 9088 *enable = TRUE; 9089 for (i = 0; i < 3; i++) { 9090 SOC_IF_ERROR_RETURN 9091 (soc_trident3_xpe_reg_get(unit, reg[i][split], 9092 -1, pipe, 0, &rval64)); 9093 9094 if (!COMPILER_64_BITTEST(rval64, pos)) { 9095 *enable = FALSE; 9096 break; 9097 } 9098 } 9099 #ifdef INCLUDE_AVS 9100 /* Register trident3 related functions */ 9101 SOC_IF_ERROR_RETURN(soc_td3_avs_init(unit)); 9102 #endif /* INCLUDE_AVS */ 9103 return SOC_E_NONE; 9104 } 9105 9106 STATIC int 9107 _soc_td3_thdo_hw_set(int unit, soc_port_t port, int enable) 9108 { 9109 uint64 rval64, rval64_tmp; 9110 int pipe, i; 9111 int split, pos; 9112 soc_reg_t reg[3][2] = { 9113 { 9114 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT0r, 9115 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT1r 9116 }, 9117 { 9118 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT0r, 9119 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT1r 9120 }, 9121 { 9122 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT0r, 9123 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT1r 9124 } 9125 }; 9126 9127 SOC_IF_ERROR_RETURN( 9128 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos)); 9129 9130 for (i = 0; i < 3; i++) { 9131 COMPILER_64_ZERO(rval64); 9132 COMPILER_64_ZERO(rval64_tmp); 9133 9134 if (pos < 32) { 9135 COMPILER_64_SET(rval64_tmp, 0, (1 << pos)); 9136 } else { 9137 COMPILER_64_SET(rval64_tmp, (1 << (pos - 32)), 0); 9138 } 9139 9140 SOC_IF_ERROR_RETURN 9141 (soc_trident3_xpe_reg_get(unit, reg[i][split], 9142 -1, pipe, 0, &rval64)); 9143 9144 if (enable) { 9145 COMPILER_64_OR(rval64, rval64_tmp); 9146 } else { 9147 COMPILER_64_NOT(rval64_tmp); 9148 COMPILER_64_AND(rval64, rval64_tmp); 9149 } 9150 9151 SOC_IF_ERROR_RETURN 9152 (soc_trident3_xpe_reg_set(unit, reg[i][split], 9153 -1, pipe, 0, rval64)); 9154 } 9155 9156 return SOC_E_NONE; 9157 } 9158 9159 /* 9160 * Funtion to caltulate global buffer reserve for ASF. 9161 */ 9162 STATIC int 9163 _soc_td3_mmu_config_buf_asf(int unit, int lossless, int *cnt) 9164 { 9165 soc_info_t *si; 9166 int pm, oversub, num_ports, ports[3], asf = 0; 9167 static int asf_profile[SOC_MAX_NUM_DEVICES] = {-2}; 9168 int asf_reserved_cells[3][3][2] = /* 1/2/4 port, asf profile, line/oversub*/ 9169 { 9170 {{ 0, 0}, {16, 31}, { 39, 50}}, /* 1-port PM */ 9171 {{ 0, 0}, {32, 62}, { 78, 100}}, /* 2-ports PM */ 9172 {{ 0, 0}, {64, 124}, {156, 200}}, /* 3/4-ports PM */ 9173 }; 9174 9175 /* To init static array to -1 */ 9176 if (asf_profile[0] == -2) { 9177 sal_memset(asf_profile, -1, sizeof(asf_profile)); 9178 } 9179 9180 if (asf_profile[unit] == -1) { 9181 asf_profile[unit] = soc_property_get(unit, spn_ASF_MEM_PROFILE, 9182 _SOC_TD3_ASF_MEM_PROFILE_SIMILAR); 9183 if ((asf_profile[unit] > _SOC_TD3_ASF_MEM_PROFILE_EXTREME) 9184 || (asf_profile[unit] < _SOC_TD3_ASF_MEM_PROFILE_NONE)) { 9185 asf_profile[unit] = _SOC_TD3_ASF_MEM_PROFILE_NONE; 9186 } 9187 } 9188 9189 si = &SOC_INFO(unit); 9190 oversub = SOC_PBMP_IS_NULL(si->oversub_pbm)? 0 : 1; 9191 9192 ports[0] = ports[1] = ports[2] = 0; 9193 for (pm = 0; pm < _TD3_PBLKS_PER_DEV(unit); pm++) { 9194 num_ports = soc_td3_ports_per_pm_get(unit, pm); 9195 if (num_ports == 1) { 9196 ports[0]++; 9197 } else if (num_ports == 2) { 9198 ports[1]++; 9199 } else if ((num_ports == 4) || (num_ports == 3)) { 9200 ports[2]++; 9201 } 9202 } 9203 9204 asf = asf_reserved_cells[0][asf_profile[unit]][oversub] * ports[0] 9205 + asf_reserved_cells[1][asf_profile[unit]][oversub] * ports[1] 9206 + asf_reserved_cells[2][asf_profile[unit]][oversub] * ports[2]; 9207 9208 if (cnt != NULL) { 9209 *cnt = asf; 9210 } 9211 9212 return SOC_E_NONE; 9213 } 9214 9215 /* 9216 * Function used for global resource reservation (MCQE / RQE / Buf cell). 9217 * Input state: Total hardware resource. 9218 * Output state: Resource available for admission control. 9219 */ 9220 STATIC void 9221 _soc_td3_mmu_config_dev_reserve(int unit, _soc_mmu_device_info_t *devcfg, 9222 int lossless) 9223 { 9224 int port, pm, asf_rsvd = 0; 9225 uint32 total_mcq = 0, num_ports = 0; 9226 uint32 cpu_cnt = 1, lb_cnt = 2, mgmt_cnt = 1; 9227 soc_info_t *si = &SOC_INFO(unit); 9228 9229 /* Device reservation for RQE Entry */ 9230 devcfg->total_rqe_queue_entry -= _TD3_MMU_RQE_ENTRY_RSVD_PER_XPE; 9231 9232 /* Device reservation for MCQ Entry - 6 entries for each MC queue */ 9233 if (si->flex_eligible) { 9234 for (pm = 0; pm < _TD3_PBLKS_PER_DEV(unit); pm++) { 9235 num_ports += soc_td3_ports_per_pm_get(unit, pm); 9236 } 9237 total_mcq += (num_ports * SOC_TD3_NUM_MCAST_QUEUE_PER_PORT); 9238 } else { 9239 PBMP_ALL_ITER(unit, port) { 9240 if (IS_CPU_PORT(unit, port) || 9241 IS_LB_PORT(unit,port) || 9242 IS_MGMT_PORT(unit,port)) { 9243 continue; 9244 } 9245 total_mcq += si->port_num_cosq[port]; 9246 } 9247 } 9248 total_mcq += ((cpu_cnt * SOC_TD3_NUM_CPU_QUEUES) + 9249 (lb_cnt + mgmt_cnt) * SOC_TD3_NUM_MCAST_QUEUE_PER_PORT); 9250 9251 devcfg->total_mcq_entry -= ((total_mcq * _TD3_MCQE_RSVD_PER_MCQ) + 9252 _TD3_TDM_MCQE_RSVD_OVERSHOOT); 9253 9254 /* Device reservation for buffer cell */ 9255 (void)_soc_td3_mmu_config_buf_asf(unit, lossless, &asf_rsvd); 9256 devcfg->mmu_total_cell -= asf_rsvd; 9257 } 9258 9259 STATIC void 9260 _soc_td3_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg, 9261 int lossless) 9262 { 9263 if (devcfg == NULL) { 9264 LOG_FATAL(BSL_LS_SOC_COMMON, 9265 (BSL_META_U(unit, 9266 "MMU config data error\ 9267 (u=%d)\n"), unit)); 9268 return; 9269 } 9270 sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t)); 9271 9272 devcfg->max_pkt_byte = _TD3_MMU_MAX_PACKET_BYTES; 9273 devcfg->mmu_hdr_byte = _TD3_MMU_PACKET_HEADER_BYTES; 9274 devcfg->jumbo_pkt_size = _TD3_MMU_JUMBO_FRAME_BYTES; 9275 devcfg->default_mtu_size = _TD3_MMU_DEFAULT_MTU_BYTES; 9276 devcfg->mmu_cell_size = _TD3_MMU_BYTES_PER_CELL; 9277 devcfg->mmu_total_cell = _TD3_MMU_TOTAL_CELLS_PER_XPE; 9278 devcfg->num_pg = _TD3_MMU_NUM_PG; 9279 devcfg->num_service_pool = _TD3_MMU_NUM_POOL; 9280 devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN | 9281 SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY; 9282 devcfg->total_mcq_entry = _TD3_MMU_TOTAL_MCQ_ENTRY(unit); 9283 devcfg->rqe_queue_num = 11; 9284 devcfg->total_rqe_queue_entry = _TD3_MMU_TOTAL_RQE_ENTRY(unit); 9285 9286 _soc_td3_mmu_config_dev_reserve(unit, devcfg, lossless); 9287 } 9288 9289 STATIC void 9290 _soc_td3_mmu_sw_info_config (int unit, _soc_td3_mmu_sw_config_info_t * swcfg, 9291 int lossless) 9292 { 9293 /* Default settings is lossless */ 9294 swcfg->mmu_egr_queue_min = 0; 9295 swcfg->mmu_egr_qgrp_min = 0; 9296 swcfg->mmu_total_pri_groups = 8; 9297 swcfg->mmu_active_pri_groups = 1; 9298 swcfg->mmu_pg_min = 8; 9299 swcfg->mmu_port_min = 0; 9300 swcfg->mmu_mc_egr_qentry_min = 0; 9301 swcfg->mmu_rqe_qentry_min = 8; 9302 swcfg->mmu_rqe_queue_min = 8; 9303 if (lossless == 0) 9304 { 9305 swcfg->mmu_egr_queue_min = 8; 9306 swcfg->mmu_egr_qgrp_min = 16; 9307 swcfg->mmu_pg_min = 0; 9308 } 9309 } 9310 9311 STATIC int 9312 _soc_td3_default_pg_headroom(int unit, soc_port_t port, 9313 int lossless) 9314 { 9315 int speed = 1000, hdrm = 0; 9316 uint8 port_oversub = 0; 9317 9318 if (IS_CPU_PORT(unit, port)) { 9319 return 77; 9320 } else if (!lossless) { 9321 return 0; 9322 } else if (IS_LB_PORT(unit, port)) { 9323 return 150; 9324 } 9325 9326 speed = SOC_INFO(unit).port_speed_max[port]; 9327 9328 if (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port)) { 9329 port_oversub = 1; 9330 } 9331 if ((speed >= 1000) && (speed <= 10000)) { 9332 hdrm = port_oversub ? 194 : 160; 9333 } else if ((speed > 10000) && (speed <= 20000)) { 9334 hdrm = port_oversub ? 231 : 197; 9335 } else if ((speed > 20000) && (speed <= 25000)) { 9336 hdrm = port_oversub ? 288 : 254; 9337 } else if ((speed > 25000) && (speed <= 42000)) { 9338 hdrm = port_oversub ? 355 : 274; 9339 } else if ((speed > 42000) && (speed <= 50000)) { 9340 hdrm = port_oversub ? 432 : 351; 9341 } else if (speed >= 100000) { 9342 hdrm = port_oversub ? 768 : 574; 9343 } else { 9344 hdrm = port_oversub ? 194 : 160; 9345 } 9346 return hdrm; 9347 } 9348 9349 /* 9350 * Default phase_1 MMU settings about headroom, guarantee, dynamic, color, ... 9351 * which depend on single port/queue/qgroup/pg... 9352 * Input state: Available for admission in devcfg, configured swcfg. 9353 * Output state: Independent data filled in buf. 9354 * Version 1.1 9355 */ 9356 STATIC void 9357 _soc_td3_mmu_config_buf_phase1(int unit, _soc_mmu_cfg_buf_t *buf, 9358 _soc_mmu_device_info_t *devcfg, 9359 _soc_td3_mmu_sw_config_info_t *swcfg, 9360 int lossless) 9361 { 9362 soc_info_t *si; 9363 _soc_mmu_cfg_buf_pool_t *buf_pool; 9364 _soc_mmu_cfg_buf_port_t *buf_port; 9365 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 9366 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 9367 _soc_mmu_cfg_buf_queue_t *buf_queue; 9368 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 9369 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 9370 int max_packet_cells, default_mtu_cells; 9371 int port, idx; 9372 int total_pool_size = 0, asf_rsvd = 0; 9373 int rqe_entry_shared_total, qmin; 9374 9375 si = &SOC_INFO(unit); 9376 9377 LOG_VERBOSE(BSL_LS_SOC_COMMON, 9378 (BSL_META_U(unit, 9379 "Initializing default MMU config phase 1(u=%d)\n"), unit)); 9380 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 9381 devcfg->mmu_hdr_byte, 9382 devcfg->mmu_cell_size); 9383 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 9384 devcfg->mmu_hdr_byte, 9385 devcfg->mmu_cell_size); 9386 9387 (void)_soc_td3_mmu_config_buf_asf(unit, lossless, &asf_rsvd); 9388 total_pool_size = devcfg->mmu_total_cell + asf_rsvd; /* Add back ASF reserved. */ 9389 9390 buf->headroom = 2 * max_packet_cells; /* 1 packet per pipe. */ 9391 9392 rqe_entry_shared_total = devcfg->total_rqe_queue_entry - 9393 (_TD3_MMU_NUM_RQE_QUEUES * swcfg->mmu_rqe_qentry_min); 9394 9395 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 9396 buf_pool = &buf->pools[idx]; 9397 if (idx == 0) { /* 100% scale up by 100 */ 9398 buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 9399 buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 9400 buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 9401 buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 9402 buf_pool->total_rqe_entry = rqe_entry_shared_total; 9403 } else { 9404 buf_pool->size = 0; 9405 buf_pool->yellow_size = 0; 9406 buf_pool->red_size = 0; 9407 buf_pool->total_mcq_entry = 0; 9408 buf_pool->total_rqe_entry = 0; 9409 } 9410 } 9411 9412 for (idx = 0; idx < SOC_TD3_MMU_CFG_QGROUP_MAX; idx++) { 9413 queue_grp = &buf->qgroups[idx]; 9414 /* resume limits - accounted for 8 cell granularity */ 9415 queue_grp->pool_resume = 16; 9416 queue_grp->yellow_resume = 16; 9417 queue_grp->red_resume = 16; 9418 queue_grp->guarantee = swcfg->mmu_egr_qgrp_min; 9419 if (lossless) { 9420 queue_grp->discard_enable = 0; 9421 } else { 9422 queue_grp->discard_enable = 1; 9423 } 9424 } 9425 9426 PBMP_ALL_ITER(unit, port) { 9427 if (port >= SOC_MMU_CFG_PORT_MAX) { 9428 break; 9429 } 9430 buf_port = &buf->ports[port]; 9431 9432 /* internal priority to priority group mapping */ 9433 for (idx = 0; idx < _TD3_MMU_NUM_INT_PRI; idx++) { 9434 buf_port->pri_to_prigroup[idx] = 7; 9435 } 9436 9437 /* priority group to pool mapping */ 9438 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 9439 buf_port->prigroups[idx].pool_idx = 0; 9440 } 9441 9442 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 9443 buf_port_pool = &buf_port->pools[idx]; 9444 buf_port_pool->guarantee = 0; 9445 buf_port_pool->pool_limit = 0; 9446 buf_port_pool->pool_resume = 0; 9447 if (idx == 0) { 9448 buf_port_pool->pool_limit = total_pool_size; 9449 buf_port_pool->pool_resume = total_pool_size - 9450 (default_mtu_cells * 2); 9451 } 9452 } 9453 9454 buf_port->pkt_size = max_packet_cells; 9455 9456 /* priority group */ 9457 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 9458 buf_prigroup = &buf_port->prigroups[idx]; 9459 buf_prigroup->guarantee = 0; 9460 buf_prigroup->user_delay = -1; 9461 buf_prigroup->switch_delay = -1; 9462 buf_prigroup->pkt_size = max_packet_cells; 9463 buf_prigroup->device_headroom_enable = 0; 9464 buf_prigroup->pool_floor = 0; 9465 buf_prigroup->headroom = 0; 9466 buf_prigroup->pool_resume = 0; 9467 buf_prigroup->flow_control_enable = 0; 9468 if (idx == 7) { 9469 buf_prigroup->device_headroom_enable = 1; 9470 buf_prigroup->flow_control_enable = lossless; 9471 buf_prigroup->headroom = 9472 _soc_td3_default_pg_headroom(unit, port, lossless); 9473 if (lossless) { 9474 buf_prigroup->guarantee = swcfg->mmu_pg_min; 9475 } 9476 } 9477 } 9478 9479 /* multicast queue */ 9480 if (IS_CPU_PORT(unit, port) || 9481 IS_LB_PORT(unit,port)) { 9482 qmin = swcfg->mmu_egr_queue_min; 9483 } else { 9484 qmin = 0; 9485 } 9486 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 9487 buf_queue = &buf_port->queues[idx]; 9488 buf_queue->qgroup_id = -1; 9489 buf_queue->guarantee = qmin; 9490 buf_queue->mcq_entry_guarantee = swcfg->mmu_mc_egr_qentry_min; 9491 buf_queue->color_discard_enable = 0; 9492 if (lossless) { 9493 buf_queue->discard_enable = 0; 9494 /* resume limits - accounted for 8 cell granularity */ 9495 buf_queue->pool_resume = 16; 9496 } else { 9497 buf_queue->discard_enable = 1; 9498 /* resume limits - accounted for 8 cell granularity */ 9499 buf_queue->pool_resume = 16; 9500 } 9501 } 9502 9503 /* unicast queue */ 9504 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 9505 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 9506 buf_queue->qgroup_id = -1; 9507 buf_queue->guarantee = 0; 9508 buf_queue->color_discard_enable = 0; 9509 if (lossless) { 9510 buf_queue->discard_enable = 0; 9511 /* resume limits - accounted for 8 cell granularity */ 9512 buf_queue->pool_resume = 16; 9513 buf_queue->yellow_resume = 16; 9514 buf_queue->red_resume = 16; 9515 } else { 9516 buf_queue->discard_enable = 1; 9517 /* resume limits - accounted for 8 cell granularity */ 9518 buf_queue->pool_resume = 16; 9519 buf_queue->yellow_resume = 16; 9520 buf_queue->red_resume = 16; 9521 buf_queue->qgroup_id = 0; 9522 buf_queue->qgroup_min_enable = 1; 9523 } 9524 } 9525 9526 /* queue to pool mapping */ 9527 for (idx = 0; 9528 idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) { 9529 buf_port->queues[idx].pool_idx = 0; 9530 } 9531 } 9532 9533 /* RQE */ 9534 for (idx = 0; idx < _TD3_MMU_NUM_RQE_QUEUES; idx++) { 9535 buf_rqe_queue = &buf->rqe_queues[idx]; 9536 buf_rqe_queue->pool_idx = 0; 9537 buf_rqe_queue->guarantee = swcfg->mmu_rqe_queue_min; 9538 if (lossless) { 9539 buf_rqe_queue->discard_enable = 0; 9540 } else { 9541 buf_rqe_queue->discard_enable = 1; 9542 } 9543 } 9544 } 9545 9546 /* 9547 * Default phase_2 MMU settings about shared buffer limit, which depends on 9548 * guaranteed/headroom buffers on all port/queue/qgroup/pg/... 9549 * Input state: _soc_mmu_cfg_buf_calculate processed buf. 9550 * Output state: All necessary data filled in buf. 9551 * Version 1.1 9552 */ 9553 STATIC void 9554 _soc_td3_mmu_config_buf_phase2(int unit, _soc_mmu_cfg_buf_t *buf, 9555 _soc_mmu_device_info_t *devcfg, 9556 _soc_td3_mmu_sw_config_info_t *swcfg, 9557 int lossless) 9558 { 9559 soc_info_t *si; 9560 _soc_mmu_cfg_buf_pool_t *buf_pool; 9561 _soc_mmu_cfg_buf_port_t *buf_port; 9562 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 9563 _soc_mmu_cfg_buf_queue_t *buf_queue; 9564 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 9565 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 9566 int port, idx, pm, ports[3] = {0}; 9567 int pg_hdrm_ob[] = {699, 379, 224}; /* PG headroom of 1/2/4-port PortMacro */ 9568 int total_pool_size = 0; 9569 int ing_rsvd_total = 0, egr_rsvd_total = 0; 9570 int ing_shared_total, egr_shared_total; 9571 int total_rsvd_qmin = 0; 9572 uint32 color_limit = 0; 9573 uint32 num_ports = 0, mgmt_cnt = 0, cpu_cnt = 0, lb_cnt = 0; 9574 uint32 cpu_hdrm = 0, lb_hdrm = 0, mgmt_hdrm = 0; 9575 9576 si = &SOC_INFO(unit); 9577 9578 LOG_VERBOSE(BSL_LS_SOC_COMMON, 9579 (BSL_META_U(unit, 9580 "Initializing default MMU config phase 2(u=%d)\n"), unit)); 9581 9582 buf_pool = &buf->pools[0]; 9583 total_pool_size = devcfg->mmu_total_cell; /* per XPE limit */ 9584 total_rsvd_qmin = swcfg->mmu_egr_queue_min * (SOC_TD3_NUM_CPU_QUEUES + 9585 (SOC_TD3_NUM_MCAST_QUEUE_PER_PORT * 2)); 9586 9587 PBMP_ALL_ITER(unit, port) { 9588 if (IS_CPU_PORT(unit, port)) { 9589 cpu_cnt++; 9590 cpu_hdrm = _soc_td3_default_pg_headroom(unit, port, lossless); 9591 } else if (IS_LB_PORT(unit,port)) { 9592 lb_cnt++; 9593 lb_hdrm = _soc_td3_default_pg_headroom(unit, port, lossless); 9594 } else if (IS_MGMT_PORT(unit,port)) { 9595 mgmt_cnt++; 9596 mgmt_hdrm = _soc_td3_default_pg_headroom(unit, port, lossless); 9597 } else { 9598 num_ports++; 9599 } 9600 } 9601 if (si->flex_eligible) { 9602 num_ports = 0; 9603 for (pm = 0; pm < _TD3_PBLKS_PER_DEV(unit); pm++) { 9604 port = soc_td3_ports_per_pm_get(unit, pm); 9605 if (port == 1) { 9606 ports[0]++; 9607 } else if (port == 2) { 9608 ports[1]++; 9609 } else if ((port == 4) || (port == 3)) { 9610 ports[2]++; 9611 port = 4; 9612 } 9613 num_ports += port; 9614 } 9615 9616 if (lossless) { 9617 ing_rsvd_total += (buf->headroom + 9618 swcfg->mmu_active_pri_groups*( 9619 ports[0]*pg_hdrm_ob[0] + 2*ports[1]*pg_hdrm_ob[1] + 9620 4*ports[2]*pg_hdrm_ob[2] + cpu_cnt*cpu_hdrm + lb_cnt*lb_hdrm) + 9621 swcfg->mmu_pg_min*swcfg->mmu_active_pri_groups*( 9622 num_ports + cpu_cnt + lb_cnt + mgmt_cnt) + 9623 swcfg->mmu_port_min*swcfg->mmu_active_pri_groups*( 9624 num_ports + cpu_cnt + lb_cnt + mgmt_cnt)); 9625 /* Management port is not included during Total PG 9626 * headroom calculation */ 9627 buf_pool->prigroup_headroom -= mgmt_hdrm; 9628 } else { 9629 ing_rsvd_total += buf->headroom + cpu_hdrm; 9630 } 9631 } else { 9632 if (lossless) { 9633 /* Management port is not included during Total PG 9634 * headroom calculation */ 9635 buf_pool->prigroup_headroom -= mgmt_hdrm; 9636 } 9637 ing_rsvd_total += (buf->headroom + buf_pool->prigroup_headroom + 9638 buf_pool->prigroup_guarantee); 9639 } 9640 9641 egr_rsvd_total += total_rsvd_qmin + 9642 ((num_ports + mgmt_cnt) * swcfg->mmu_egr_qgrp_min) + 9643 (swcfg->mmu_rqe_queue_min * _TD3_MMU_NUM_RQE_QUEUES); 9644 9645 if (lossless) { 9646 ing_rsvd_total += egr_rsvd_total; 9647 } 9648 9649 ing_shared_total = total_pool_size - ing_rsvd_total; 9650 egr_shared_total = total_pool_size - egr_rsvd_total; 9651 9652 swcfg->ing_shared_total = ing_shared_total; 9653 swcfg->egr_shared_total = egr_shared_total; 9654 9655 LOG_VERBOSE(BSL_LS_SOC_MMU, 9656 (BSL_META_U(unit, 9657 "MMU config: Total Shared size: ingress %d egress %d\n"), 9658 ing_shared_total, egr_shared_total)); 9659 9660 color_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 9661 9662 for (idx = 0; idx < SOC_TD3_MMU_CFG_QGROUP_MAX; idx++) { 9663 queue_grp = &buf->qgroups[idx]; 9664 if (lossless) { 9665 queue_grp->pool_scale = -1; 9666 queue_grp->pool_limit = egr_shared_total; 9667 queue_grp->red_limit = egr_shared_total; 9668 queue_grp->yellow_limit = egr_shared_total; 9669 } else { 9670 queue_grp->pool_scale = 8; 9671 queue_grp->pool_limit = 0; 9672 queue_grp->red_limit = color_limit; 9673 queue_grp->yellow_limit = color_limit; 9674 } 9675 } 9676 9677 PBMP_ALL_ITER(unit, port) { 9678 if (port >= SOC_MMU_CFG_PORT_MAX) { 9679 break; 9680 } 9681 buf_port = &buf->ports[port]; 9682 9683 /* priority group */ 9684 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 9685 buf_prigroup = &buf_port->prigroups[idx]; 9686 buf_prigroup->pool_limit = 0; 9687 buf_prigroup->pool_scale = -1; 9688 if (idx == 7) { 9689 if (lossless) { 9690 buf_prigroup->pool_scale = 8; 9691 } else { 9692 buf_prigroup->pool_limit = ing_shared_total; 9693 } 9694 } 9695 } 9696 9697 /* multicast queue */ 9698 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 9699 buf_queue = &buf_port->queues[idx]; 9700 if (lossless) { 9701 buf_queue->pool_scale = -1; 9702 buf_queue->pool_limit = egr_shared_total; 9703 buf_queue->yellow_limit = egr_shared_total; 9704 buf_queue->red_limit = egr_shared_total; 9705 } else { 9706 buf_queue->pool_scale = 8; 9707 buf_queue->pool_limit = 0; 9708 buf_queue->yellow_limit = color_limit 9709 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 9710 buf_queue->red_limit = color_limit 9711 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 9712 } 9713 } 9714 9715 /* unicast queue */ 9716 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 9717 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 9718 if (lossless) { 9719 buf_queue->pool_scale = -1; 9720 buf_queue->pool_limit = egr_shared_total; 9721 buf_queue->red_limit = egr_shared_total; 9722 buf_queue->yellow_limit = egr_shared_total; 9723 } else { 9724 buf_queue->pool_scale = 8; 9725 buf_queue->pool_limit = 0; 9726 buf_queue->red_limit = color_limit 9727 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 9728 buf_queue->yellow_limit = color_limit 9729 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 9730 } 9731 } 9732 } 9733 9734 /* RQE */ 9735 for (idx = 0; idx < _TD3_MMU_NUM_RQE_QUEUES; idx++) { 9736 buf_rqe_queue = &buf->rqe_queues[idx]; 9737 if (lossless) { 9738 buf_rqe_queue->pool_scale = -1; 9739 buf_rqe_queue->pool_limit = egr_shared_total; 9740 buf_rqe_queue->red_limit = egr_shared_total; 9741 buf_rqe_queue->yellow_limit = egr_shared_total; 9742 } else { 9743 buf_rqe_queue->pool_scale = 8; 9744 buf_rqe_queue->pool_limit = 0; 9745 buf_rqe_queue->red_limit = color_limit; 9746 buf_rqe_queue->yellow_limit = color_limit; 9747 } 9748 } 9749 } 9750 9751 STATIC int 9752 _soc_td3_pool_scale_to_limit(int size, int scale) 9753 { 9754 int factor = 1000; 9755 9756 switch (scale) { 9757 case 7: factor = 875; break; 9758 case 6: factor = 750; break; 9759 case 5: factor = 625; break; 9760 case 4: factor = 500; break; 9761 case 3: factor = 375; break; 9762 case 2: factor = 250; break; 9763 case 1: factor = 125; break; 9764 case 0: 9765 default: 9766 factor = 1000; break; 9767 } 9768 return (size * factor)/1000; 9769 } 9770 9771 STATIC int 9772 _soc_td3_mmu_config_buf_set_hw_port(int unit, int port, _soc_mmu_cfg_buf_t *buf, 9773 _soc_mmu_device_info_t *devcfg, int lossless, 9774 _soc_td3_mmu_sw_config_info_t *swcfg) 9775 { 9776 soc_info_t *si; 9777 _soc_mmu_cfg_buf_pool_t *buf_pool; 9778 _soc_mmu_cfg_buf_port_t *buf_port; 9779 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 9780 thdi_port_sp_config_entry_t thdi_sp_config; 9781 thdi_port_pg_config_entry_t pg_config_mem; 9782 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 9783 _soc_mmu_cfg_buf_queue_t *buf_queue; 9784 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 9785 soc_reg_t reg = INVALIDr; 9786 soc_mem_t mem0, mem1, mem2, mem3; 9787 uint32 fval, rval; 9788 int base, numq; 9789 int idx, midx, pri, index1; 9790 int default_mtu_cells, limit, rlimit; 9791 int pipe; 9792 9793 static const soc_mem_t mmu_thdi_port_mem[] = { 9794 THDI_PORT_SP_CONFIGm, 9795 THDI_PORT_PG_CONFIGm 9796 }; 9797 static const soc_mem_t mmu_thdo_q_uc_mem[] = { 9798 MMU_THDU_CONFIG_QUEUEm, 9799 MMU_THDU_OFFSET_QUEUEm, 9800 MMU_THDU_Q_TO_QGRP_MAPm 9801 }; 9802 static const soc_mem_t mmu_thdo_port_uc_mem[] = { 9803 MMU_THDU_CONFIG_PORTm, 9804 MMU_THDU_RESUME_PORTm 9805 }; 9806 static const soc_mem_t mmu_thdo_q_mc_mem[] = { 9807 MMU_THDM_DB_QUEUE_CONFIGm, 9808 MMU_THDM_DB_QUEUE_OFFSETm, 9809 MMU_THDM_MCQE_QUEUE_CONFIGm, 9810 MMU_THDM_MCQE_QUEUE_OFFSETm 9811 }; 9812 9813 static const soc_mem_t mmu_thdo_port_mc_mem[] = { 9814 MMU_THDM_DB_PORTSP_CONFIGm, 9815 MMU_THDM_MCQE_PORTSP_CONFIGm 9816 }; 9817 9818 static const soc_field_t prigroup_reg[] = { 9819 THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r 9820 }; 9821 static const soc_field_t prigroup_field[] = { 9822 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 9823 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 9824 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 9825 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 9826 }; 9827 static const soc_field_t prigroup_spid_field[] = { 9828 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 9829 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 9830 }; 9831 9832 si = &SOC_INFO(unit); 9833 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 9834 devcfg->mmu_hdr_byte, 9835 devcfg->mmu_cell_size); 9836 9837 /* internal priority to priority group mapping */ 9838 buf_port = &buf->ports[port]; 9839 9840 for (idx = 0; idx < COUNTOF(prigroup_field); idx++) { 9841 if (idx % 8 == 0) { /* 8 fields per register */ 9842 reg = prigroup_reg[idx / 8]; 9843 rval = 0; 9844 } 9845 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 9846 buf_port->pri_to_prigroup[idx]); 9847 if (idx % 8 == 7) { /* 8 fields per register */ 9848 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 9849 } 9850 } 9851 9852 /* Input port per port settings */ 9853 pipe = si->port_pipe[port]; 9854 buf_port = &buf->ports[port]; 9855 9856 rval = 0; 9857 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 9858 soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval, 9859 prigroup_spid_field[idx], 9860 buf_port->prigroups[idx].pool_idx); 9861 } 9862 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval)); 9863 9864 /* Per port per pool settings */ 9865 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[0])[pipe]; 9866 if (mem0 != INVALIDm) { 9867 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 9868 buf_port_pool = &buf_port->pools[idx]; 9869 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[0], 9870 idx); 9871 sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config)); 9872 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 9873 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee); 9874 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 9875 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume); 9876 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 9877 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit); 9878 SOC_IF_ERROR_RETURN 9879 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 9880 midx, &thdi_sp_config)); 9881 } 9882 } 9883 9884 fval = 0; 9885 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 9886 if (buf_port->prigroups[idx].flow_control_enable != 0) { 9887 for (pri=0; pri < 16; pri++) { 9888 if (buf_port->pri_to_prigroup[pri] == idx) { 9889 fval |= 1 << pri; 9890 } 9891 } 9892 } 9893 } 9894 9895 rval = 0; 9896 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 9897 INPUT_PORT_RX_ENABLEf, 1); 9898 if (port == CMIC_PORT (unit)) { 9899 fval = 0; 9900 } 9901 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 9902 PORT_PRI_XON_ENABLEf, fval); 9903 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 9904 PORT_PAUSE_ENABLEf, fval ? 1 : 0); 9905 SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, 9906 port, rval)); 9907 9908 rval = 0; 9909 soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 9910 PORT_MAX_PKT_SIZEf, buf_port->pkt_size); 9911 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval)); 9912 9913 /* Input port per port per priority group settings */ 9914 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[1])[pipe]; 9915 if (mem1 != INVALIDm) { 9916 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 9917 buf_prigroup = &buf->ports[port].prigroups[idx]; 9918 9919 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[1], 9920 idx); 9921 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 9922 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9923 PG_MIN_LIMITf, buf_prigroup->guarantee); 9924 9925 if (buf_prigroup->pool_scale != -1) { 9926 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9927 PG_SHARED_DYNAMICf, 1); 9928 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9929 PG_SHARED_LIMITf, 9930 buf_prigroup->pool_scale); 9931 } else { 9932 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9933 PG_SHARED_LIMITf, 9934 buf_prigroup->pool_limit); 9935 } 9936 9937 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9938 PG_GBL_HDRM_ENf, 9939 buf_prigroup->device_headroom_enable); 9940 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9941 PG_HDRM_LIMITf, buf_prigroup->headroom); 9942 9943 soc_mem_field32_set(unit, mem1, &pg_config_mem, PG_RESET_OFFSETf, 9944 0); 9945 9946 soc_mem_field32_set(unit, mem1, &pg_config_mem, 9947 PG_RESET_FLOORf, buf_prigroup->pool_floor); 9948 9949 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, midx, 9950 &pg_config_mem)); 9951 } 9952 } 9953 9954 /*********************************** 9955 * THDO 9956 */ 9957 /* Output port per port per queue setting for regular multicast queue */ 9958 pipe = si->port_pipe[port]; 9959 numq = si->port_num_cosq[port]; 9960 base = si->port_cosq_base[port]; 9961 9962 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[0])[pipe]; 9963 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[1])[pipe]; 9964 if ((numq != 0) && (mem0 != INVALIDm) && (mem1 != INVALIDm)) { 9965 for (idx = 0; idx < numq; idx++) { 9966 buf_queue = &buf->ports[port].queues[idx]; 9967 9968 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 9969 9970 soc_mem_field32_set(unit, mem0, entry0, Q_MIN_LIMITf, 9971 buf_queue->guarantee); 9972 if (buf_queue->discard_enable) { 9973 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_ENABLEf, 1); 9974 } 9975 if (buf_queue->color_discard_enable) { 9976 soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 9977 } 9978 if (buf_queue->pool_scale != -1) { 9979 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMICf, 1); 9980 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHAf, 9981 buf_queue->pool_scale); 9982 } else { 9983 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 9984 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMITf, 9985 buf_queue->pool_limit); 9986 } 9987 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 9988 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 9989 soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_DYNAMICf, 1); 9990 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 9991 buf_queue->yellow_limit 9992 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 9993 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 9994 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 9995 buf_queue->red_limit 9996 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 9997 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 9998 } else { 9999 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 10000 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 10001 sal_ceil_func(buf_queue->yellow_limit, 8)); 10002 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 10003 sal_ceil_func(buf_queue->red_limit, 8)); 10004 } 10005 10006 soc_mem_field32_set(unit, mem0, entry0, Q_SPIDf, buf_queue->pool_idx); 10007 10008 SOC_IF_ERROR_RETURN 10009 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 10010 10011 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_entry_t)); 10012 10013 soc_mem_field32_set(unit, mem1, entry0, RESUME_OFFSETf, 10014 (default_mtu_cells * 2)/8); 10015 soc_mem_field32_set(unit, mem1, entry0, 10016 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 10017 soc_mem_field32_set(unit, mem1, entry0, 10018 RED_RESUME_OFFSET_PROFILE_SELf, 0); 10019 SOC_IF_ERROR_RETURN 10020 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry0)); 10021 10022 rval = 0; 10023 SOC_IF_ERROR_RETURN( 10024 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 10025 2)); 10026 10027 rval = 0; 10028 SOC_IF_ERROR_RETURN( 10029 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 10030 2)); 10031 } 10032 } 10033 10034 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[2])[pipe]; 10035 mem3 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[3])[pipe]; 10036 if ((numq != 0) && (mem2 != INVALIDm) && (mem3 != INVALIDm)) { 10037 for (idx = 0; idx < numq; idx++) { 10038 buf_queue = &buf->ports[port].queues[idx]; 10039 buf_pool = &buf->pools[buf_queue->pool_idx]; 10040 if (buf_pool->total == 0) { 10041 continue; 10042 } 10043 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 10044 10045 soc_mem_field32_set(unit, mem2, entry0, Q_MIN_LIMITf, 10046 sal_ceil_func(buf_queue->mcq_entry_guarantee, 4)); 10047 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 10048 10049 if (buf_queue->discard_enable) { 10050 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 10051 } 10052 if (buf_queue->color_discard_enable) { 10053 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 10054 } 10055 if (buf_queue->pool_scale != -1) { 10056 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_DYNAMICf, 1); 10057 soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_ALPHAf, 10058 buf_queue->pool_scale); 10059 } else { 10060 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 10061 soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_LIMITf, 10062 sal_ceil_func(limit, 4)); 10063 } 10064 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 10065 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 10066 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_DYNAMICf, 1); 10067 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, 10068 buf_queue->yellow_limit 10069 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 10070 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 10071 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, 10072 buf_queue->red_limit 10073 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 10074 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 10075 } else { 10076 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 10077 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, 10078 sal_ceil_func(limit, 8)); 10079 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, 10080 sal_ceil_func(limit, 8)); 10081 } 10082 10083 soc_mem_field32_set(unit, mem2, entry0, Q_SPIDf, buf_queue->pool_idx); 10084 10085 SOC_IF_ERROR_RETURN 10086 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, entry0)); 10087 10088 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_entry_t)); 10089 10090 soc_mem_field32_set(unit, mem3, entry0, RESUME_OFFSETf, 1); 10091 soc_mem_field32_set(unit, mem3, entry0, 10092 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 10093 soc_mem_field32_set(unit, mem3, entry0, 10094 RED_RESUME_OFFSET_PROFILE_SELf, 0); 10095 SOC_IF_ERROR_RETURN 10096 (soc_mem_write(unit, mem3, MEM_BLOCK_ALL, base + idx, entry0)); 10097 10098 rval = 0; 10099 SOC_IF_ERROR_RETURN( 10100 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 10101 1)); 10102 10103 rval = 0; 10104 SOC_IF_ERROR_RETURN( 10105 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 10106 1)); 10107 } 10108 } 10109 10110 /* Per port per pool */ 10111 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 10112 buf_port_pool = &buf->ports[port].pools[idx]; 10113 if (buf_port_pool->pool_limit == 0) { 10114 continue; 10115 } 10116 10117 limit = buf_port_pool->pool_limit; 10118 rlimit = limit - (default_mtu_cells * 2); 10119 10120 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[0])[pipe]; 10121 if (mem0 == INVALIDm) { 10122 continue; 10123 } 10124 10125 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, 10126 mmu_thdo_port_mc_mem[0], idx); 10127 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t)); 10128 10129 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 10130 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 10131 sal_ceil_func(limit, 8)); 10132 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 10133 sal_ceil_func(limit, 8)); 10134 10135 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMIT_ENABLEf, 10136 !lossless); 10137 10138 soc_mem_field32_set(unit, mem0, entry0, SHARED_RESUME_LIMITf, 10139 sal_ceil_func(rlimit, 8)); 10140 soc_mem_field32_set(unit, mem0, entry0, YELLOW_RESUME_LIMITf, 10141 sal_ceil_func(rlimit, 8)); 10142 soc_mem_field32_set(unit, mem0, entry0, RED_RESUME_LIMITf, 10143 sal_ceil_func(rlimit, 8)); 10144 10145 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 10146 index1, entry0)); 10147 10148 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[1])[pipe]; 10149 if (mem1 == INVALIDm) { 10150 continue; 10151 } 10152 buf_pool = &buf->pools[idx]; 10153 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t)); 10154 10155 limit = _TD3_MMU_TOTAL_MCQ_ENTRY(unit); 10156 10157 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMITf, 10158 (sal_ceil_func(limit, 4)) - 1); 10159 soc_mem_field32_set(unit, mem1, entry0, YELLOW_SHARED_LIMITf, 10160 (sal_ceil_func(limit, 8)) - 1); 10161 soc_mem_field32_set(unit, mem1, entry0, RED_SHARED_LIMITf, 10162 (sal_ceil_func(limit, 8)) - 1); 10163 10164 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMIT_ENABLEf, 10165 !lossless); 10166 10167 soc_mem_field32_set(unit, mem1, entry0, SHARED_RESUME_LIMITf, 10168 (sal_ceil_func(limit, 8)) - 2); 10169 soc_mem_field32_set(unit, mem1, entry0, YELLOW_RESUME_LIMITf, 10170 (sal_ceil_func(limit, 8)) - 2); 10171 soc_mem_field32_set(unit, mem1, entry0, RED_RESUME_LIMITf, 10172 (sal_ceil_func(limit, 8)) - 2); 10173 10174 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 10175 index1, entry0)); 10176 } 10177 10178 /* Output port per port per queue setting for regular unicast queue */ 10179 pipe = si->port_pipe[port]; 10180 /* per port regular unicast queue */ 10181 numq = si->port_num_uc_cosq[port]; 10182 base = si->port_uc_cosq_base[port]; 10183 10184 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[0])[pipe]; 10185 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[1])[pipe]; 10186 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[2])[pipe]; 10187 if ((numq != 0) && 10188 (mem0 != INVALIDm) && (mem1 != INVALIDm) && (mem2 != INVALIDm)) { 10189 for (idx = 0; idx < numq; idx++) { 10190 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx]; 10191 10192 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 10193 sal_memset(entry1, 0, sizeof(mmu_thdu_offset_queue_entry_t)); 10194 10195 soc_mem_field32_set(unit, mem0, entry0, 10196 Q_MIN_LIMIT_CELLf, buf_queue->guarantee); 10197 if (buf_queue->pool_scale != -1) { 10198 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMIC_CELLf, 1); 10199 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHA_CELLf, 10200 buf_queue->pool_scale); 10201 } else { 10202 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 10203 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMIT_CELLf, 10204 buf_queue->pool_limit); 10205 } 10206 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_CELLf, 10207 sal_ceil_func(buf_queue->pool_resume, 8)); 10208 10209 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 10210 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 10211 soc_mem_field32_set(unit, mem0, entry0, 10212 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 10213 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 10214 buf_queue->yellow_limit 10215 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 10216 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 10217 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 10218 buf_queue->red_limit 10219 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 10220 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 10221 } else { 10222 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 10223 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 10224 sal_ceil_func(buf_queue->yellow_limit, 8)); 10225 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 10226 sal_ceil_func(buf_queue->red_limit, 8)); 10227 } 10228 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf, 10229 sal_ceil_func(buf_queue->yellow_resume, 8)); 10230 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf, 10231 sal_ceil_func(buf_queue->red_resume, 8)); 10232 SOC_IF_ERROR_RETURN 10233 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 10234 10235 SOC_IF_ERROR_RETURN 10236 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1)); 10237 10238 sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t)); 10239 10240 if (buf_queue->qgroup_id >= 0) { 10241 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1); 10242 if (buf_queue->qgroup_min_enable) { 10243 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1); 10244 } 10245 } 10246 if (buf_queue->discard_enable) { 10247 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 10248 } 10249 10250 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, 10251 entry0)); 10252 } 10253 } 10254 10255 /* Per port per pool unicast */ 10256 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 10257 buf_pool = &buf->pools[idx]; 10258 10259 if (buf_pool->total == 0) { 10260 continue; 10261 } 10262 10263 limit = buf->ports[port].pools[idx].pool_limit; 10264 10265 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[0])[pipe]; 10266 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[1])[pipe]; 10267 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 10268 continue; 10269 } 10270 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, 10271 mmu_thdo_port_uc_mem[0], idx); 10272 sal_memset(entry0, 0, sizeof(mmu_thdu_config_port_entry_t)); 10273 sal_memset(entry1, 0, sizeof(mmu_thdu_resume_port_entry_t)); 10274 10275 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 10276 soc_mem_field32_set(unit, mem1, entry1, SHARED_RESUMEf, 10277 sal_ceil_func((limit - (default_mtu_cells * 2)), 10278 8)); 10279 10280 soc_mem_field32_set(unit, mem0, entry0, YELLOW_LIMITf, 10281 sal_ceil_func(limit, 8)); 10282 soc_mem_field32_set(unit, mem1, entry1, YELLOW_RESUMEf, 10283 sal_ceil_func((limit - (default_mtu_cells*2)), 10284 8)); 10285 10286 soc_mem_field32_set(unit, mem0, entry0, RED_LIMITf, 10287 sal_ceil_func(limit, 8)); 10288 soc_mem_field32_set(unit, mem1, entry1, RED_RESUMEf, 10289 sal_ceil_func((limit - (default_mtu_cells * 2)), 10290 8)); 10291 10292 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 10293 index1, entry0)); 10294 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 10295 index1, entry1)); 10296 } 10297 10298 return SOC_E_NONE; 10299 } 10300 10301 STATIC int 10302 _soc_td3_mmu_config_buf_set_hw_global(int unit, _soc_mmu_cfg_buf_t *buf, 10303 _soc_mmu_device_info_t *devcfg, int lossless, 10304 _soc_td3_mmu_sw_config_info_t *swcfg) 10305 { 10306 _soc_mmu_cfg_buf_pool_t *buf_pool; 10307 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 10308 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 10309 mmu_thdo_offset_qgroup_entry_t offset_qgrp; 10310 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 10311 soc_mem_t mem0, mem1; 10312 uint32 fval, rval, rval2, rval3; 10313 int rqlen, idx, pval; 10314 int jumbo_frame_cells, default_mtu_cells, limit; 10315 int pipe; 10316 uint64 rval64; 10317 uint64 rval2_64; 10318 int pool_resume = 0; 10319 10320 static const soc_mem_t mmu_thdo_qgrp_uc_mem[] = { 10321 MMU_THDU_CONFIG_QGROUPm, 10322 MMU_THDU_OFFSET_QGROUPm 10323 }; 10324 10325 jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size + 10326 devcfg->mmu_hdr_byte, 10327 devcfg->mmu_cell_size); 10328 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 10329 devcfg->mmu_hdr_byte, 10330 devcfg->mmu_cell_size); 10331 pool_resume = 2 * jumbo_frame_cells; 10332 10333 rval = 0; 10334 fval = _TD3_MMU_PHYSICAL_CELLS_PER_XPE - _TD3_MMU_RSVD_CELLS_CFAP_PER_XPE; 10335 soc_reg_field_set(unit, CFAPFULLTHRESHOLDSETr, &rval, CFAPFULLSETPOINTf, 10336 fval); 10337 SOC_IF_ERROR_RETURN( 10338 soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDSETr, -1, -1, 10339 -1, rval)); 10340 10341 rval = 0; 10342 soc_reg_field_set(unit, CFAPFULLTHRESHOLDRESETr, &rval, 10343 CFAPFULLRESETPOINTf, fval - (2 * jumbo_frame_cells)); 10344 SOC_IF_ERROR_RETURN( 10345 soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDRESETr, -1, -1, 10346 -1, rval)); 10347 10348 rval = 0; 10349 soc_reg_field_set(unit, CFAPBANKFULLr, &rval, LIMITf, 10350 _TD3_MMU_CFAP_BANK_FULL_LIMIT); 10351 for (idx = 0; idx < SOC_REG_NUMELS(unit, CFAPBANKFULLr); idx++) { 10352 SOC_IF_ERROR_RETURN( 10353 soc_trident3_xpe_reg32_set(unit, CFAPBANKFULLr, -1, -1, 10354 idx, rval)); 10355 } 10356 10357 rval = 0; 10358 SOC_IF_ERROR_RETURN(READ_MMU_SCFG_TOQ_MC_CFG0r(unit, &rval)); 10359 soc_reg_field_set(unit, MMU_SCFG_TOQ_MC_CFG0r, &rval, 10360 MCQE_FULL_THRESHOLDf, 0); 10361 SOC_IF_ERROR_RETURN(WRITE_MMU_SCFG_TOQ_MC_CFG0r(unit, rval)); 10362 10363 rval = 0; 10364 for (idx = 0; idx < 2; idx++) { 10365 SOC_IF_ERROR_RETURN 10366 (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, idx, 0, &rval)); 10367 soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval, 10368 PEAK_COUNT_UPDATE_EN_HPf, 0); 10369 SOC_IF_ERROR_RETURN 10370 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, idx, 0, rval)); 10371 } 10372 10373 /* Input thresholds */ 10374 rval = 0; 10375 soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMITr, 10376 &rval, GLOBAL_HDRM_LIMITf, buf->headroom / 2); 10377 SOC_IF_ERROR_RETURN( 10378 soc_trident3_xpe_reg32_set(unit, THDI_GLOBAL_HDRM_LIMITr, -1, -1, 0, 10379 rval)); 10380 10381 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 10382 buf_pool = &buf->pools[idx]; 10383 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 10384 continue; 10385 } 10386 10387 limit = swcfg->ing_shared_total; 10388 10389 rval = 0; 10390 soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, 10391 limit); 10392 SOC_IF_ERROR_RETURN( 10393 soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, 10394 -1, -1, idx, rval)); 10395 10396 rval = 0; 10397 soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 10398 OFFSETf, pool_resume); 10399 SOC_IF_ERROR_RETURN( 10400 soc_trident3_xpe_reg32_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, 10401 -1, -1, idx, rval)); 10402 10403 rval = 0; 10404 soc_reg_field_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, &rval, 10405 LIMITf, buf_pool->prigroup_headroom); 10406 SOC_IF_ERROR_RETURN( 10407 soc_trident3_xpe_reg32_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, 10408 -1, -1, idx, rval)); 10409 } 10410 10411 rval = 0; 10412 SOC_IF_ERROR_RETURN( 10413 soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr, 10414 -1, -1, 0, rval)); 10415 10416 /* output thresholds */ 10417 SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval)); 10418 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 10419 ENABLE_QUEUE_AND_GROUP_TICKETf, 1); 10420 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 10421 ENABLE_UPDATE_COLOR_RESUMEf, 0); 10422 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 10423 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0); 10424 SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval)); 10425 10426 rval = 0; 10427 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 10428 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 10429 MOP_POLICYf, 1); 10430 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 10431 10432 rval = 0; 10433 SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIGr(unit, &rval)); 10434 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 10435 MOP_POLICY_1Bf, 1); 10436 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval)); 10437 10438 /* per service pool settings */ 10439 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 10440 buf_pool = &buf->pools[idx]; 10441 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 10442 continue; 10443 } 10444 10445 limit = swcfg->egr_shared_total; 10446 10447 rval = 0; 10448 soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 10449 SHARED_LIMITf, limit); 10450 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, 10451 idx, 10452 rval)); 10453 10454 rval = 0; 10455 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 10456 &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8)); 10457 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, 10458 idx, 10459 rval)); 10460 10461 rval = 0; 10462 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 10463 &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8)); 10464 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, 10465 idx, 10466 rval)); 10467 10468 rval = 0; 10469 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 10470 &rval, RESUME_LIMITf, sal_ceil_func(limit, 8)); 10471 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, 10472 idx, 10473 rval)); 10474 10475 rval = 0; 10476 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 10477 &rval, YELLOW_RESUME_LIMITf, sal_ceil_func(limit, 8)); 10478 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, 10479 idx, 10480 rval)); 10481 10482 rval = 0; 10483 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 10484 &rval, RED_RESUME_LIMITf, sal_ceil_func(limit, 8)); 10485 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, 10486 idx, 10487 rval)); 10488 10489 /* mcq entries */ 10490 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 10491 10492 rval = 0; 10493 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 10494 &rval, SHARED_LIMITf, sal_ceil_func(limit, 4)); 10495 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit, 10496 idx, rval)); 10497 10498 rval = 0; 10499 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 10500 &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8)); 10501 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit, 10502 idx, rval)); 10503 10504 rval = 0; 10505 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 10506 &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8)); 10507 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit, 10508 idx, rval)); 10509 10510 rval = 0; 10511 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 10512 &rval, RESUME_LIMITf, sal_ceil_func(limit, 8)); 10513 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit, 10514 idx, rval)); 10515 10516 rval = 0; 10517 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 10518 &rval, YELLOW_RESUME_LIMITf, sal_ceil_func(limit, 8)); 10519 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit, 10520 idx, rval)); 10521 10522 rval = 0; 10523 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 10524 &rval, RED_RESUME_LIMITf, sal_ceil_func(limit, 8)); 10525 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit, 10526 idx, rval)); 10527 } 10528 10529 /* configure Q-groups */ 10530 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 10531 for (idx = 0; idx < SOC_TD3_MMU_CFG_QGROUP_MAX; idx++) { 10532 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[0])[pipe]; 10533 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[1])[pipe]; 10534 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 10535 continue; 10536 } 10537 queue_grp = &buf->qgroups[idx]; 10538 10539 10540 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 10541 sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp)); 10542 10543 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10544 Q_MIN_LIMIT_CELLf, queue_grp->guarantee); 10545 10546 if (queue_grp->pool_scale != -1) { 10547 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10548 Q_SHARED_ALPHA_CELLf, 10549 queue_grp->pool_scale); 10550 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10551 Q_LIMIT_DYNAMIC_CELLf, 1); 10552 } else { 10553 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10554 Q_SHARED_LIMIT_CELLf, 10555 queue_grp->pool_limit); 10556 } 10557 10558 if ((queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 10559 (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 10560 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10561 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 10562 } 10563 10564 if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 10565 pval = _soc_td3_pool_scale_to_limit(queue_grp->pool_limit, 10566 queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 10567 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10568 LIMIT_RED_CELLf, sal_ceil_func(pval, 8)); 10569 10570 } else { 10571 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10572 LIMIT_RED_CELLf, 10573 sal_ceil_func(queue_grp->red_limit, 8)); 10574 } 10575 10576 if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 10577 pval = _soc_td3_pool_scale_to_limit(queue_grp->pool_limit, 10578 queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 10579 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10580 LIMIT_YELLOW_CELLf, sal_ceil_func(pval, 8)); 10581 10582 } else { 10583 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 10584 LIMIT_YELLOW_CELLf, 10585 sal_ceil_func(queue_grp->yellow_limit, 8)); 10586 } 10587 10588 soc_mem_field32_set(unit, mem1, &offset_qgrp, 10589 RESET_OFFSET_CELLf, 10590 sal_ceil_func(queue_grp->pool_resume, 8)); 10591 soc_mem_field32_set(unit, mem1, &offset_qgrp, 10592 RESET_OFFSET_YELLOW_CELLf, 10593 sal_ceil_func(queue_grp->pool_resume, 8)); 10594 soc_mem_field32_set(unit, mem1, &offset_qgrp, 10595 RESET_OFFSET_RED_CELLf, 10596 sal_ceil_func(queue_grp->pool_resume, 8)); 10597 SOC_IF_ERROR_RETURN 10598 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 10599 SOC_IF_ERROR_RETURN 10600 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp)); 10601 } 10602 } 10603 10604 /* RQE */ 10605 for (idx = 0; idx < _TD3_MMU_NUM_RQE_QUEUES; idx++) { 10606 buf_rqe_queue = &buf->rqe_queues[idx]; 10607 10608 rval = 0; 10609 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 10610 &rval, MIN_LIMITf, buf_rqe_queue->guarantee); 10611 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval)); 10612 10613 rval = 0; 10614 rval2 = 0; 10615 rval3 = 0; 10616 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 10617 &rval, SPIDf, buf_rqe_queue->pool_idx); 10618 10619 if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 10620 (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 10621 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 10622 &rval, COLOR_LIMIT_DYNAMICf, 1); 10623 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 10624 SHARED_RED_LIMITf, 10625 buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 10626 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 10627 SHARED_YELLOW_LIMITf, 10628 buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 10629 } else { 10630 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 10631 SHARED_RED_LIMITf, 10632 sal_ceil_func(buf_rqe_queue->red_limit, 8)); 10633 10634 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 10635 SHARED_YELLOW_LIMITf, 10636 sal_ceil_func(buf_rqe_queue->yellow_limit, 8)); 10637 } 10638 10639 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 10640 (buf_rqe_queue->discard_enable ? 1 : 0)); 10641 10642 if (buf_rqe_queue->pool_scale != -1) { 10643 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 10644 &rval, DYNAMIC_ENABLEf, 1); 10645 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 10646 SHARED_ALPHAf, buf_rqe_queue->pool_scale); 10647 } else { 10648 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 10649 SHARED_LIMITf, buf_rqe_queue->pool_limit); 10650 } 10651 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 10652 RESET_OFFSETf, 2); 10653 10654 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval)); 10655 10656 COMPILER_64_SET(rval2_64, 0, rval2); 10657 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr(unit, idx, rval2_64)); 10658 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, 10659 idx, rval3)); 10660 10661 rval = 0; 10662 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 10663 &rval, RESET_OFFSET_REDf, 2); 10664 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 10665 &rval, RESET_OFFSET_YELLOWf, 2); 10666 SOC_IF_ERROR_RETURN( 10667 WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 10668 10669 /* queue entry */ 10670 buf_pool = &buf->pools[buf_rqe_queue->pool_idx]; 10671 rval = 0; 10672 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 10673 &rval, MIN_LIMITf, 10674 sal_ceil_func(buf_rqe_queue->guarantee, 8)); 10675 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval)); 10676 10677 rval = 0; 10678 rval2 = 0; 10679 rval3 = 0; 10680 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 10681 &rval, SPIDf, buf_rqe_queue->pool_idx); 10682 10683 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 10684 &rval, COLOR_LIMIT_DYNAMICf, (!lossless)); 10685 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 10686 &rval3, SHARED_RED_LIMITf, 10687 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 10688 8)): 0); 10689 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 10690 &rval3, SHARED_YELLOW_LIMITf, 10691 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 10692 8)): 0); 10693 10694 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, 10695 LIMIT_ENABLEf, !lossless); 10696 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 10697 &rval, DYNAMIC_ENABLEf, (!lossless)); 10698 10699 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 10700 SHARED_LIMITf, 10701 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 10702 8)): 8); 10703 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 10704 RESET_OFFSETf, 1); 10705 10706 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval)); 10707 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2)); 10708 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 10709 10710 rval = 0; 10711 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 10712 &rval, RESET_OFFSET_REDf, 10713 sal_ceil_func(default_mtu_cells, 8)); 10714 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 10715 &rval, RESET_OFFSET_YELLOWf, 10716 sal_ceil_func(default_mtu_cells, 8)); 10717 SOC_IF_ERROR_RETURN( 10718 WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 10719 10720 } 10721 10722 /* per pool RQE settings */ 10723 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 10724 buf_pool = &buf->pools[idx]; 10725 if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) || 10726 (buf_pool->total == 0)) { 10727 continue; 10728 } 10729 10730 limit = swcfg->egr_shared_total; 10731 10732 COMPILER_64_ZERO(rval64); 10733 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, 10734 &rval64, SHARED_LIMITf, limit); 10735 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval64, 10736 RESUME_LIMITf, sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 10737 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr(unit, idx, rval64)); 10738 10739 rval = 0; 10740 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 10741 SHARED_RED_LIMITf, 10742 sal_ceil_func(limit, 8)); 10743 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 10744 SHARED_YELLOW_LIMITf, 10745 sal_ceil_func(limit, 8)); 10746 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval)); 10747 10748 rval = 0; 10749 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 10750 RESUME_RED_LIMITf, 10751 sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 10752 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 10753 RESUME_YELLOW_LIMITf, 10754 sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 10755 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit, 10756 idx, rval)); 10757 10758 rqlen = sal_ceil_func(buf_pool->total_rqe_entry, 8); 10759 if (rqlen == 0) { 10760 continue; 10761 } 10762 10763 rval = 0; 10764 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 10765 SHARED_LIMITf, rqlen); 10766 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 10767 RESUME_LIMITf, rqlen - 1); 10768 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval)); 10769 10770 rval = 0; 10771 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 10772 SHARED_RED_LIMITf, rqlen); 10773 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 10774 SHARED_YELLOW_LIMITf, rqlen); 10775 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, 10776 idx, 10777 rval)); 10778 10779 rval = 0; 10780 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 10781 RESUME_RED_LIMITf, rqlen - 1); 10782 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 10783 RESUME_YELLOW_LIMITf, rqlen - 1); 10784 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 10785 idx, rval)); 10786 } 10787 10788 10789 /* Device level config setting */ 10790 #if 0 10791 if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) { 10792 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 10793 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 10794 UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1); 10795 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 10796 } 10797 #endif 10798 return SOC_E_NONE; 10799 } 10800 10801 STATIC int 10802 _soc_td3_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf, 10803 _soc_mmu_device_info_t *devcfg, int lossless, 10804 _soc_td3_mmu_sw_config_info_t *swcfg) 10805 { 10806 int port; 10807 10808 SOC_IF_ERROR_RETURN 10809 (_soc_td3_mmu_config_buf_set_hw_global(unit, buf, devcfg, lossless, 10810 swcfg)); 10811 10812 PBMP_ALL_ITER(unit, port) { 10813 SOC_IF_ERROR_RETURN 10814 (_soc_td3_mmu_config_buf_set_hw_port(unit, port, buf, devcfg, 10815 lossless, swcfg)); 10816 } 10817 10818 return SOC_E_NONE; 10819 } 10820 10821 int 10822 soc_td3_mmu_config_init_port(int unit, int port) 10823 { 10824 int rv; 10825 int lossless = 1; 10826 _soc_mmu_cfg_buf_t *buf; 10827 _soc_mmu_device_info_t devcfg; 10828 _soc_td3_mmu_sw_config_info_t swcfg; 10829 10830 buf = soc_mmu_cfg_alloc(unit); 10831 if (!buf) { 10832 return SOC_E_MEMORY; 10833 } 10834 10835 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 10836 10837 _soc_td3_mmu_init_dev_config(unit, &devcfg, lossless); 10838 _soc_td3_mmu_sw_info_config (unit, &swcfg, lossless); 10839 10840 10841 /* Calculate the buf - global as well as per port 10842 * but _soc_td3_mmu_config_buf_set_hw_port is only called 10843 * for that port - since it is flex operation - we don't 10844 * touch any other port */ 10845 _soc_td3_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 10846 10847 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 10848 /* Override default config */ 10849 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 10850 } 10851 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 10852 if (SOC_FAILURE(rv)) { 10853 LOG_VERBOSE(BSL_LS_SOC_COMMON, 10854 (BSL_META_U(unit, 10855 "MMU config: Use default setting\n"))); 10856 _soc_td3_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 10857 SOC_IF_ERROR_RETURN 10858 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg)); 10859 } 10860 10861 _soc_td3_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless); 10862 /* Override default phase 2 config */ 10863 if (SOC_SUCCESS(rv)) { 10864 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 10865 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 10866 } 10867 } 10868 rv = _soc_td3_mmu_config_buf_set_hw_port(unit, port, buf, &devcfg, 10869 lossless, &swcfg); 10870 10871 soc_mmu_cfg_free(unit, buf); 10872 10873 LOG_VERBOSE(BSL_LS_SOC_COMMON, 10874 (BSL_META_U(unit, 10875 "MMU THDI/THDO init done\n"))); 10876 return rv; 10877 } 10878 10879 /* Default MMU settings - Version 3.0 */ 10880 STATIC int 10881 soc_td3_mmu_config_init(int unit, int test_only) 10882 { 10883 int rv; 10884 int lossless = 1; 10885 _soc_mmu_cfg_buf_t *buf; 10886 _soc_mmu_device_info_t devcfg; 10887 _soc_td3_mmu_sw_config_info_t swcfg; 10888 10889 buf = soc_mmu_cfg_alloc(unit); 10890 if (!buf) { 10891 return SOC_E_MEMORY; 10892 } 10893 10894 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 10895 SOC_INFO(unit).mmu_lossless = lossless; 10896 10897 _soc_td3_mmu_init_dev_config(unit, &devcfg, lossless); 10898 _soc_td3_mmu_sw_info_config (unit, &swcfg, lossless); 10899 10900 _soc_td3_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 10901 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 10902 /* Override default config */ 10903 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 10904 } 10905 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 10906 if (!test_only) { 10907 if (SOC_FAILURE(rv)) { 10908 LOG_VERBOSE(BSL_LS_SOC_COMMON, 10909 (BSL_META_U(unit, 10910 "MMU config: Use default setting\n"))); 10911 _soc_td3_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 10912 SOC_IF_ERROR_RETURN 10913 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg)); 10914 } 10915 10916 _soc_td3_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless); 10917 /* Override default phase 2 config */ 10918 if (SOC_SUCCESS(rv)) { 10919 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 10920 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 10921 } 10922 } 10923 rv = _soc_td3_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, &swcfg); 10924 } 10925 10926 soc_mmu_cfg_free(unit, buf); 10927 10928 LOG_VERBOSE(BSL_LS_SOC_COMMON, 10929 (BSL_META_U(unit, 10930 "MMU THDI/THDO init done\n"))); 10931 return rv; 10932 } 10933 10934 STATIC int 10935 _soc_trident3_mmu_init(int unit) 10936 { 10937 int port; 10938 int enable = 1; 10939 int test_only; 10940 uint32 rval = 0; 10941 10942 #ifdef BCM_WARM_BOOT_SUPPORT 10943 if (SOC_WARM_BOOT(unit)) { 10944 } else 10945 #endif 10946 { 10947 test_only = (SAL_BOOT_XGSSIM) ? TRUE : FALSE; 10948 SOC_IF_ERROR_RETURN(soc_td3_mmu_config_init(unit, test_only)); 10949 10950 PBMP_ALL_ITER(unit, port) { 10951 _soc_td3_thdo_hw_set(unit, port, enable); 10952 } 10953 } 10954 10955 /* enable WRED refresh */ 10956 SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval)); 10957 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 10958 REFRESH_DISABLEf, 0); 10959 SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval)); 10960 10961 SOC_IF_ERROR_RETURN(soc_td3_post_mmu_init_update(unit)); 10962 return SOC_E_NONE; 10963 } 10964 10965 int 10966 soc_trident3_age_timer_get(int unit, int *age_seconds, int *enabled) 10967 { 10968 soc_control_t *soc = SOC_CONTROL(unit); 10969 *enabled = soc->l2x_age_pid != SAL_THREAD_ERROR && 10970 soc->l2x_age_enable ? 10971 1 : 0; 10972 *age_seconds = soc->l2x_age_pid != SAL_THREAD_ERROR && 10973 soc->l2x_age_enable ? 10974 soc->l2x_age_interval : 0; 10975 return SOC_E_NONE; 10976 } 10977 10978 int 10979 soc_trident3_age_timer_max_get(int unit, int *max_seconds) 10980 { 10981 *max_seconds = 0x7fffffff; 10982 return SOC_E_NONE; 10983 } 10984 10985 int 10986 soc_trident3_age_timer_set(int unit, int age_seconds, int enable) 10987 { 10988 soc_control_t *soc = SOC_CONTROL(unit); 10989 sal_usecs_t interval = soc->l2x_age_interval; 10990 10991 if (soc->l2x_age_interval) { 10992 if (!enable) { 10993 soc->l2x_age_enable = 0; 10994 } else { 10995 if (age_seconds) { 10996 SOC_CONTROL_LOCK(unit); 10997 soc->l2x_age_interval = age_seconds; 10998 SOC_CONTROL_UNLOCK(unit); 10999 } 11000 soc->l2x_age_enable = 1; 11001 if (interval != age_seconds) { 11002 sal_sem_give(soc->l2x_age_notify); 11003 } 11004 } 11005 } else { 11006 if (enable) { 11007 soc->l2x_age_enable = 1; 11008 SOC_IF_ERROR_RETURN 11009 (soc_th_l2_bulk_age_start(unit, age_seconds)); 11010 } 11011 } 11012 11013 return SOC_E_NONE; 11014 } 11015 11016 STATIC int 11017 soc_trident3_oversub_group_find(int unit, soc_td3_port_lanes_t *lanes_ctrl) 11018 { 11019 soc_info_t *si = &SOC_INFO(unit); 11020 soc_reg_t reg; 11021 int port_base, phy_port_base, idb_port_base, mmu_port_base; 11022 int port, mmu_port, id, inst; 11023 uint32 rval, fval; 11024 int pipe, group, slot, count, i; 11025 int cur_ids[4], cur_ids_len; 11026 int ids_len; 11027 int slots[4], slots_len; 11028 int speed_max, cur_speed_max; 11029 static const soc_reg_t idb_grp_tbl_regs[] = { 11030 IS_OVR_SUB_GRP0_TBLr, IS_OVR_SUB_GRP1_TBLr, 11031 IS_OVR_SUB_GRP2_TBLr, IS_OVR_SUB_GRP3_TBLr, 11032 IS_OVR_SUB_GRP4_TBLr, IS_OVR_SUB_GRP5_TBLr 11033 }; 11034 static const soc_reg_t mmu_grp_tbl_regs[] = { 11035 OVR_SUB_GRP0_TBLr, OVR_SUB_GRP1_TBLr, 11036 OVR_SUB_GRP2_TBLr, OVR_SUB_GRP3_TBLr, 11037 OVR_SUB_GRP4_TBLr, OVR_SUB_GRP5_TBLr 11038 }; 11039 11040 port_base = lanes_ctrl->port_base; 11041 phy_port_base = si->port_l2p_mapping[port_base]; 11042 idb_port_base = si->port_l2i_mapping[port_base]; 11043 mmu_port_base = si->port_p2m_mapping[phy_port_base]; 11044 pipe = si->port_pipe[port_base]; 11045 11046 /* Figure out the new speed group */ 11047 speed_max = 25000 * lanes_ctrl->lanes; 11048 if (speed_max > si->port_speed_max[port_base]) { 11049 speed_max = si->port_speed_max[port_base]; 11050 } 11051 _soc_trident3_speed_to_ovs_class_mapping(unit, speed_max, 11052 &lanes_ctrl->class); 11053 11054 /* Figure out the current speed group */ 11055 cur_speed_max = 25000 * lanes_ctrl->cur_lanes; 11056 if (cur_speed_max > si->port_speed_max[port_base]) { 11057 cur_speed_max = si->port_speed_max[port_base]; 11058 } 11059 _soc_trident3_speed_to_ovs_class_mapping(unit, cur_speed_max, 11060 &lanes_ctrl->cur_class); 11061 11062 /* Construct new and old idb port list for oversub group replacement */ 11063 cur_ids[0] = idb_port_base; 11064 ids_len = cur_ids_len = 1; 11065 if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) { 11066 /* idb port(s) to be removed */ 11067 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11068 port = si->port_p2l_mapping[lanes_ctrl->phy_ports[i]]; 11069 cur_ids[1 + i] = si->port_l2i_mapping[port]; 11070 } 11071 cur_ids_len += lanes_ctrl->phy_ports_len; 11072 } else { /* idb port(s) to be added */ 11073 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11074 port = si->port_p2l_mapping[lanes_ctrl->phy_ports[i]]; 11075 } 11076 ids_len += lanes_ctrl->phy_ports_len; 11077 } 11078 11079 lanes_ctrl->idb_group = -1; 11080 lanes_ctrl->idb_slots[0] = -1; 11081 lanes_ctrl->cur_idb_slots[0] = -1; 11082 for (group = 0; group < _OVS_GROUP_COUNT; group++) { 11083 reg = SOC_REG_UNIQUE_ACC(unit, IS_OVR_SUB_GRP_CFGr)[pipe]; 11084 SOC_IF_ERROR_RETURN 11085 (soc_reg32_get(unit, reg, REG_PORT_ANY, group, &rval)); 11086 fval = soc_reg_field_get(unit, reg, rval, SPEEDf); 11087 if (fval == 0) { /* unused idb port oversub group */ 11088 if (lanes_ctrl->idb_group == -1) { 11089 lanes_ctrl->idb_group = group; 11090 } 11091 continue; 11092 } else if (fval == lanes_ctrl->class) { 11093 if (lanes_ctrl->idb_slots[0] == -1) { /* hasn't found the group */ 11094 /* Find slot(s) for new idb port oversub group */ 11095 reg = SOC_REG_UNIQUE_ACC(unit, idb_grp_tbl_regs[group])[pipe]; 11096 count = _OVS_GROUP_TDM_LENGTH / 11097 (_TD3_PORTS_PER_PBLK / lanes_ctrl->lanes); 11098 slots_len = 0; 11099 for (slot = 0; slot < count; slot++) { 11100 SOC_IF_ERROR_RETURN 11101 (soc_reg32_get(unit, reg, REG_PORT_ANY, slot, &rval)); 11102 if (soc_reg_field_get(unit, reg, rval, PORT_NUMf) != 0x3f) { 11103 continue; 11104 } 11105 slots[slots_len] = slot; 11106 slots_len++; 11107 if (slots_len == ids_len) { 11108 /* Enough free slots in an existing group */ 11109 lanes_ctrl->idb_group = group; 11110 for (i = 0; i < slots_len; i++) { 11111 lanes_ctrl->idb_slots[i] = slots[i]; 11112 } 11113 break; 11114 } 11115 } 11116 } 11117 } else if (fval == lanes_ctrl->cur_class) { 11118 if (lanes_ctrl->cur_idb_slots[0] == -1) { 11119 /* Find slot(s) used by the currnet idb port oversub group */ 11120 reg = SOC_REG_UNIQUE_ACC(unit, idb_grp_tbl_regs[group])[pipe]; 11121 count = _OVS_GROUP_TDM_LENGTH / 11122 (_TD3_PORTS_PER_PBLK / lanes_ctrl->cur_lanes); 11123 slots_len = 0; 11124 lanes_ctrl->cur_idb_empty = TRUE; 11125 for (slot = 0; slot < count; slot++) { 11126 SOC_IF_ERROR_RETURN 11127 (soc_reg32_get(unit, reg, REG_PORT_ANY, slot, &rval)); 11128 id = soc_reg_field_get(unit, reg, rval, PORT_NUMf); 11129 if (id == 0x3f) { 11130 continue; 11131 } 11132 for (i = 0; i < cur_ids_len; i++) { 11133 if (id == cur_ids[i]) { 11134 slots[slots_len] = slot; 11135 slots_len++; 11136 break; 11137 } 11138 } 11139 if (i == cur_ids_len) { 11140 lanes_ctrl->cur_idb_empty = FALSE; 11141 } else if (slots_len == cur_ids_len) { 11142 lanes_ctrl->cur_idb_group = group; 11143 for (i = 0; i < slots_len; i++) { 11144 lanes_ctrl->cur_idb_slots[i] = slots[i]; 11145 } 11146 } 11147 if (lanes_ctrl->cur_idb_slots[0] != -1 && 11148 !lanes_ctrl->cur_idb_empty) { 11149 break; 11150 } 11151 } 11152 } 11153 } 11154 if (lanes_ctrl->idb_slots[0] != -1 && 11155 lanes_ctrl->cur_idb_slots[0] != -1) { 11156 break; 11157 } 11158 } 11159 11160 if (lanes_ctrl->idb_group == -1) { 11161 return SOC_E_FULL; 11162 } 11163 11164 /* Construct new and old mmu port list for oversub group replacement */ 11165 cur_ids[0] = mmu_port_base & 0x3f; 11166 ids_len = cur_ids_len = 1; 11167 if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) { 11168 /* mmu port(s) to be removed */ 11169 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11170 mmu_port = si->port_p2m_mapping[lanes_ctrl->phy_ports[i]]; 11171 cur_ids[1 + i] = mmu_port & 0x3f; 11172 } 11173 cur_ids_len += lanes_ctrl->phy_ports_len; 11174 } else { /* mmu port(s) to be added */ 11175 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11176 mmu_port = si->port_p2m_mapping[lanes_ctrl->phy_ports[i]]; 11177 } 11178 ids_len += lanes_ctrl->phy_ports_len; 11179 } 11180 11181 lanes_ctrl->mmu_group = -1; 11182 lanes_ctrl->mmu_slots[0] = -1; 11183 lanes_ctrl->cur_mmu_slots[0] = -1; 11184 for (group = 0; group < _OVS_GROUP_COUNT; group++) { 11185 reg = OVR_SUB_GRP_CFGr; 11186 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 11187 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, group, &rval)); 11188 fval = soc_reg_field_get(unit, reg, rval, SPEEDf); 11189 if (fval == 0) { /* unused mmu port oversub group */ 11190 if (lanes_ctrl->mmu_group == -1) { 11191 lanes_ctrl->mmu_group = group; 11192 } 11193 continue; 11194 } else if (fval == lanes_ctrl->class) { 11195 if (lanes_ctrl->mmu_slots[0] == -1) { /* hasn't found the group */ 11196 /* Find slot(s) for new mmu port oversub group */ 11197 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 11198 reg = mmu_grp_tbl_regs[group]; 11199 count = _OVS_GROUP_TDM_LENGTH / 11200 (_TD3_PORTS_PER_PBLK / lanes_ctrl->lanes); 11201 slots_len = 0; 11202 for (slot = 0; slot < count; slot++) { 11203 SOC_IF_ERROR_RETURN 11204 (soc_reg32_get(unit, reg, inst, slot, &rval)); 11205 if (soc_reg_field_get(unit, reg, rval, PORT_NUMf) != 0x3f) { 11206 continue; 11207 } 11208 slots[slots_len] = slot; 11209 slots_len++; 11210 if (slots_len == ids_len) { 11211 /* Enough free slots in an existing group */ 11212 lanes_ctrl->mmu_group = group; 11213 for (i = 0; i < slots_len; i++) { 11214 lanes_ctrl->mmu_slots[i] = slots[i]; 11215 } 11216 break; 11217 } 11218 } 11219 } 11220 } else if (fval == lanes_ctrl->cur_class) { 11221 if (lanes_ctrl->cur_mmu_slots[0] == -1) { 11222 /* Find slot(s) used by the currnet mmu port oversub group */ 11223 reg = mmu_grp_tbl_regs[group]; 11224 inst = pipe | SOC_REG_ADDR_INSTANCE_MASK; 11225 count = _OVS_GROUP_TDM_LENGTH / 11226 (_TD3_PORTS_PER_PBLK / lanes_ctrl->cur_lanes); 11227 slots_len = 0; 11228 lanes_ctrl->cur_mmu_empty = TRUE; 11229 for (slot = 0; slot < count; slot++) { 11230 SOC_IF_ERROR_RETURN 11231 (soc_reg32_get(unit, reg, inst, slot, &rval)); 11232 id = soc_reg_field_get(unit, reg, rval, PORT_NUMf); 11233 if (id == 0x3f) { 11234 continue; 11235 } 11236 for (i = 0; i < cur_ids_len; i++) { 11237 if (id == cur_ids[i]) { 11238 slots[slots_len] = slot; 11239 slots_len++; 11240 break; 11241 } 11242 } 11243 if (i == cur_ids_len) { 11244 lanes_ctrl->cur_mmu_empty = FALSE; 11245 } else if (slots_len == cur_ids_len) { 11246 lanes_ctrl->cur_mmu_group = group; 11247 for (i = 0; i < slots_len; i++) { 11248 lanes_ctrl->cur_mmu_slots[i] = slots[i]; 11249 } 11250 } 11251 if (lanes_ctrl->cur_mmu_slots[0] != -1 && 11252 !lanes_ctrl->cur_mmu_empty) { 11253 break; 11254 } 11255 } 11256 } 11257 } 11258 if (lanes_ctrl->mmu_slots[0] != -1 && 11259 lanes_ctrl->cur_mmu_slots[0] != -1) { 11260 break; 11261 } 11262 } 11263 11264 if (lanes_ctrl->mmu_group == -1) { 11265 return SOC_E_FULL; 11266 } 11267 11268 return SOC_E_NONE; 11269 } 11270 11271 /* 11272 * Function: 11273 * soc_trident3_port_lanes_validate 11274 * Description: 11275 * Validate if the specified number of lanes can be configured on a port, 11276 * If the request can be done, fill in the control structure which will 11277 * be used by the routines programming the hardware. 11278 * Parameters: 11279 * unit - Device number 11280 * lanes_ctrl - Control structure 11281 * 11282 * Each TSC can be configured into following 5 mode: 11283 * Lane number 0 1 2 3 11284 * ------------ ----------- -------- ------------ -------- 11285 * single port 100G/40G x x x 11286 * dual port 50G/d40G/20G x 50G/d40G/20G x 11287 * tri_023 port 50G/d40g/20G x 25G/10G 25G/10G 11288 * tri_012 port 25G/10G 25G/10G 50G/d40G/20G x 11289 * quad port 25G/10G 25G/10G 25G/10G 25G/10G 11290 * 11291 * (Note: All of the above apply to equivalent HG line rate speeds as well) 11292 * 11293 * lanes mode valid lane index 11294 * ------------ ---------------- ---------------- 11295 * new current new current 11296 * --- ------- ------- ------- 11297 * #1 4 1 single quad 0 11298 * #2 4 1 single tri_012 0 11299 * #3 4 2 single tri_023 0 11300 * #4 4 2 single dual 0 11301 * #5 2 1 tri_023 quad 0 11302 * #6 2 1 tri_012 quad 2 11303 * #7 2 1 dual tri_023 2 11304 * #8 2 1 dual tri_012 0 11305 * #9 2 4 dual single 0 11306 * #10 1 2 tri_023 dual 2 11307 * #11 1 2 tri_012 dual 0 11308 * #12 1 2 quad tri_023 0 11309 * #13 1 2 quad tri_012 2 11310 * #14 1 4 quad single 0 11311 * Following mode change requires 2 transition 11312 * - from single to tri_023: #9 + #10 11313 * - from single to tri_012: #9 + #11 11314 * Following mode change are the result of lane change on multiple ports 11315 * - from quad to dual: #12 + #7 or #13 + #8 11316 * - from dual to quad: #10 + #12 or #11 + # 13 11317 * - from tri_023 to tri_012: #7 + #11 or #12 + #6 11318 * - from tri_012 to tri_023: #8 + #10 or #13 + #5 11319 * 11320 * Logical port number will stay the same after conversion, for example 11321 * converting single port to dual port, the logical port number of lane 0 11322 * will be changed. 11323 */ 11324 int 11325 soc_trident3_port_lanes_validate(int unit, soc_td3_port_lanes_t *lanes_ctrl) 11326 { 11327 soc_info_t *si = &SOC_INFO(unit); 11328 int port_base, phy_port_base; 11329 uint32 rval; 11330 int i; 11331 11332 /* Find physical and mmu port number for the specified port */ 11333 port_base = lanes_ctrl->port_base; 11334 phy_port_base = si->port_l2p_mapping[port_base]; 11335 if (phy_port_base == -1) { 11336 return SOC_E_PORT; 11337 } 11338 lanes_ctrl->oversub = SOC_PBMP_MEMBER(si->oversub_pbm, port_base); 11339 11340 /* Find lane index for the specified port (base port) */ 11341 lanes_ctrl->bindex = SOC_PORT_BINDEX(unit, phy_port_base); 11342 11343 /* Get the current mode */ 11344 SOC_IF_ERROR_RETURN(READ_CLPORT_MODE_REGr(unit, port_base, &rval)); 11345 lanes_ctrl->cur_mode = soc_reg_field_get(unit, CLPORT_MODE_REGr, rval, 11346 XPORT0_CORE_PORT_MODEf); 11347 11348 /* Figure out the current number of lanes */ 11349 switch (lanes_ctrl->cur_mode) { 11350 case SOC_TD3_PORT_MODE_QUAD: 11351 lanes_ctrl->cur_lanes = 1; 11352 break; 11353 case SOC_TD3_PORT_MODE_TRI_012: 11354 lanes_ctrl->cur_lanes = lanes_ctrl->bindex == 0 ? 1 : 2; 11355 break; 11356 case SOC_TD3_PORT_MODE_TRI_023: 11357 lanes_ctrl->cur_lanes = lanes_ctrl->bindex == 0 ? 2 : 1; 11358 break; 11359 case SOC_TD3_PORT_MODE_DUAL: 11360 lanes_ctrl->cur_lanes = 2; 11361 break; 11362 case SOC_TD3_PORT_MODE_SINGLE: 11363 lanes_ctrl->cur_lanes = 4; 11364 break; 11365 default: 11366 return SOC_E_FAIL; 11367 } 11368 /* Validate new number of lanes */ 11369 if (lanes_ctrl->lanes == 4 || lanes_ctrl->cur_lanes == 4) { 11370 if (lanes_ctrl->bindex & 0x3) { 11371 return SOC_E_PARAM; 11372 } 11373 } else if (lanes_ctrl->lanes == 2 || lanes_ctrl->cur_lanes == 2) { 11374 if (lanes_ctrl->bindex & 0x1) { 11375 return SOC_E_PARAM; 11376 } 11377 } else if (lanes_ctrl->lanes != 1) { 11378 return SOC_E_PARAM; 11379 } 11380 11381 /* No change to number of lanes */ 11382 if (lanes_ctrl->lanes == lanes_ctrl->cur_lanes) { 11383 return SOC_E_NONE; 11384 } 11385 11386 if (lanes_ctrl->oversub) { 11387 SOC_IF_ERROR_RETURN(soc_trident3_oversub_group_find(unit, lanes_ctrl)); 11388 } 11389 11390 /* Figure out new mode */ 11391 if (lanes_ctrl->lanes == 4) { 11392 lanes_ctrl->mode = 4; 11393 } else if (lanes_ctrl->lanes == 2) { 11394 if (lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_QUAD) { 11395 lanes_ctrl->mode = lanes_ctrl->bindex == 0 ? 11396 SOC_TD3_PORT_MODE_TRI_023 : SOC_TD3_PORT_MODE_TRI_012; 11397 } else { 11398 lanes_ctrl->mode = SOC_TD3_PORT_MODE_DUAL; 11399 } 11400 } else{ 11401 if (lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_DUAL) { 11402 lanes_ctrl->mode = lanes_ctrl->bindex == 0 ? 11403 SOC_TD3_PORT_MODE_TRI_012 : SOC_TD3_PORT_MODE_TRI_023; 11404 } else { 11405 lanes_ctrl->mode = SOC_TD3_PORT_MODE_QUAD; 11406 } 11407 } 11408 11409 lanes_ctrl->phy_ports_len = 0; 11410 if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) { 11411 /* Figure out which port(s) to be removed */ 11412 if (lanes_ctrl->lanes == 4) { 11413 if (lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_TRI_012 || 11414 lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_QUAD) { 11415 if (si->port_p2l_mapping[phy_port_base + 1] != -1) { 11416 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11417 phy_port_base + 1; 11418 } 11419 } 11420 if (si->port_p2l_mapping[phy_port_base + 2] != -1) { 11421 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11422 phy_port_base + 2; 11423 } 11424 if (lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_TRI_023 || 11425 lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_QUAD) { 11426 if (si->port_p2l_mapping[phy_port_base + 3] != -1) { 11427 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11428 phy_port_base + 3; 11429 } 11430 } 11431 } else { 11432 if (si->port_p2l_mapping[phy_port_base + 1] != -1) { 11433 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11434 phy_port_base + 1; 11435 } 11436 } 11437 } else { /* Figure out which port(s) to be added */ 11438 if (lanes_ctrl->lanes == 2) { 11439 if (si->port_p2l_mapping[phy_port_base + 2] != -1) { 11440 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11441 phy_port_base + 2; 11442 } 11443 } else { 11444 if (si->port_p2l_mapping[phy_port_base + 1] != -1) { 11445 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11446 phy_port_base + 1; 11447 } 11448 if (lanes_ctrl->cur_mode == SOC_TD3_PORT_MODE_SINGLE) { 11449 if (si->port_p2l_mapping[phy_port_base + 2] != -1) { 11450 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11451 phy_port_base + 2; 11452 } 11453 if (si->port_p2l_mapping[phy_port_base + 3] != -1) { 11454 lanes_ctrl->phy_ports[lanes_ctrl->phy_ports_len++] = 11455 phy_port_base + 3; 11456 } 11457 } 11458 } 11459 } 11460 11461 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 11462 static char *mode_name[] = { 11463 "QUAD", "TRI_012", "TRI_023", "DUAL", "SINGLE" 11464 }; 11465 LOG_CLI((BSL_META_U(unit, 11466 "port %d physical port %d bindex %d\n"), 11467 port_base, phy_port_base, lanes_ctrl->bindex)); 11468 LOG_CLI((BSL_META_U(unit, 11469 " mode (new:%s cur:%s) lanes (new:%d cur:%d)\n"), 11470 mode_name[lanes_ctrl->mode], 11471 mode_name[lanes_ctrl->cur_mode], 11472 lanes_ctrl->lanes, lanes_ctrl->cur_lanes)); 11473 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11474 LOG_CLI((BSL_META_U(unit, 11475 " %s physical port %d (port %d)\n"), 11476 lanes_ctrl->lanes > lanes_ctrl->cur_lanes ? 11477 "del" : "add", 11478 lanes_ctrl->phy_ports[i], 11479 si->port_p2l_mapping[lanes_ctrl->phy_ports[i]])); 11480 } 11481 if (lanes_ctrl->idb_group != -1) { 11482 LOG_CLI((BSL_META_U(unit, 11483 "new idb group %d slot %d"), 11484 lanes_ctrl->idb_group, lanes_ctrl->idb_slots[0])); 11485 if (lanes_ctrl->lanes < lanes_ctrl->cur_lanes && 11486 lanes_ctrl->idb_slots[0] != -1) { 11487 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11488 LOG_CLI((BSL_META_U(unit, 11489 " slot %d"), lanes_ctrl->idb_slots[i])); 11490 } 11491 } 11492 LOG_CLI((BSL_META_U(unit, 11493 "\n"))); 11494 } 11495 LOG_CLI((BSL_META_U(unit, 11496 "cur idb group %d slot %d"), 11497 lanes_ctrl->cur_idb_group, lanes_ctrl->cur_idb_slots[0])); 11498 if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) { 11499 /* port(s) to be removed */ 11500 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11501 LOG_CLI((BSL_META_U(unit, 11502 " slot %d"), lanes_ctrl->idb_slots[i])); 11503 } 11504 } 11505 LOG_CLI((BSL_META_U(unit, 11506 "\n"))); 11507 11508 if (lanes_ctrl->mmu_group != -1) { 11509 LOG_CLI((BSL_META_U(unit, 11510 "new mmu group %d slot %d"), 11511 lanes_ctrl->mmu_group, lanes_ctrl->mmu_slots[0])); 11512 if (lanes_ctrl->lanes < lanes_ctrl->cur_lanes && 11513 lanes_ctrl->mmu_slots[0] != -1) { 11514 /* port(s) to be added */ 11515 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11516 LOG_CLI((BSL_META_U(unit, 11517 " slot %d"), lanes_ctrl->mmu_slots[i])); 11518 } 11519 } 11520 LOG_CLI((BSL_META_U(unit, 11521 "\n"))); 11522 } 11523 LOG_CLI((BSL_META_U(unit, 11524 "cur mmu group %d slot %d"), 11525 lanes_ctrl->cur_mmu_group, lanes_ctrl->cur_mmu_slots[0])); 11526 if (lanes_ctrl->lanes > lanes_ctrl->cur_lanes) { 11527 /* port(s) to be removed */ 11528 for (i = 0; i < lanes_ctrl->phy_ports_len; i++) { 11529 LOG_CLI((BSL_META_U(unit, 11530 " slot %d"), lanes_ctrl->mmu_slots[i])); 11531 } 11532 } 11533 LOG_CLI((BSL_META_U(unit, 11534 "\n"))); 11535 } 11536 11537 return SOC_E_NONE; 11538 } 11539 11540 soc_error_t 11541 soc_td3_granular_speed_get(int unit, soc_port_t port, int *speed) 11542 { 11543 uint32 fval; 11544 egr_mmu_cell_credit_entry_t credit_entry; 11545 11546 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 11547 SOC_INFO(unit).port_l2p_mapping[port], &credit_entry)); 11548 fval = soc_EGR_MMU_CELL_CREDITm_field32_get(unit, &credit_entry, CREDITf); 11549 11550 SOC_IF_ERROR_RETURN(soc_td3_port_asf_mmu_cell_credit_to_speed(unit, 11551 port, (uint8) fval, speed)); 11552 return SOC_E_NONE; 11553 } 11554 11555 int soc_td3_mmu_traffic_ctrl_size(int unit, int *req_scache_size) 11556 { 11557 *req_scache_size += sizeof(_soc_td3_mmu_traffic_ctrl_t); 11558 11559 return SOC_E_NONE; 11560 } 11561 11562 int soc_td3_mmu_traffic_ctrl_wb_sync(int unit, uint8 **scache_ptr) 11563 { 11564 _soc_td3_mmu_traffic_ctrl_t *mmu_traffic_ctrl_scache_p; 11565 _soc_td3_mmu_traffic_ctrl_t *mmu_traffic_ctrl; 11566 11567 mmu_traffic_ctrl_scache_p = 11568 (_soc_td3_mmu_traffic_ctrl_t *)(*scache_ptr); 11569 11570 mmu_traffic_ctrl = _soc_td3_mmu_traffic_ctrl[unit]; 11571 if (mmu_traffic_ctrl == NULL || mmu_traffic_ctrl_scache_p == NULL) { 11572 return SOC_E_NONE; 11573 } 11574 sal_memcpy(mmu_traffic_ctrl_scache_p, mmu_traffic_ctrl, 11575 sizeof(_soc_td3_mmu_traffic_ctrl_t)); 11576 mmu_traffic_ctrl_scache_p++; 11577 11578 *scache_ptr = (uint8 *)mmu_traffic_ctrl_scache_p; 11579 11580 return SOC_E_NONE; 11581 } 11582 11583 int soc_td3_mmu_traffic_ctrl_wb_restore(int unit, uint8 **scache_ptr) 11584 { 11585 _soc_td3_mmu_traffic_ctrl_t *mmu_traffic_ctrl_scache_p; 11586 _soc_td3_mmu_traffic_ctrl_t *mmu_traffic_ctrl; 11587 11588 mmu_traffic_ctrl_scache_p = 11589 (_soc_td3_mmu_traffic_ctrl_t *)(*scache_ptr); 11590 11591 mmu_traffic_ctrl = _soc_td3_mmu_traffic_ctrl[unit]; 11592 if (mmu_traffic_ctrl == NULL || mmu_traffic_ctrl_scache_p == NULL) { 11593 return SOC_E_NONE; 11594 } 11595 sal_memcpy(mmu_traffic_ctrl, mmu_traffic_ctrl_scache_p, 11596 sizeof(_soc_td3_mmu_traffic_ctrl_t)); 11597 mmu_traffic_ctrl_scache_p++; 11598 11599 *scache_ptr = (uint8 *)mmu_traffic_ctrl_scache_p; 11600 11601 return SOC_E_NONE; 11602 } 11603 11604 /* 11605 * Function: 11606 * _soc_td3_port_thdo_rx_enable_set 11607 * Purpose: 11608 * enable/disable the traffic to the port according to 11609 * different callers. 11610 * the traffic to the port can be enabled only if all of the callers 11611 * are to enable it. 11612 * Parameters: 11613 * unit - (IN) unit number 11614 * port - (IN) local port 11615 * enable - (IN) enable/disable the traffic to the port. 11616 * flag - (IN) different callers. 11617 * Returns: 11618 * BCM_E_XXX 11619 */ 11620 STATIC int 11621 _soc_td3_port_thdo_rx_enable_set(int unit, soc_port_t port, 11622 int enable, uint8 flag) 11623 { 11624 int rv = SOC_E_NONE; 11625 uint8 *thdo_drop_bmp; 11626 _soc_td3_mmu_traffic_ctrl_t *mmu_traffic_ctrl; 11627 11628 FWD_CTRL_LOCK(unit); 11629 11630 mmu_traffic_ctrl = _soc_td3_mmu_traffic_ctrl[unit]; 11631 if (mmu_traffic_ctrl == NULL) { 11632 FWD_CTRL_UNLOCK(unit); 11633 return SOC_E_INIT; 11634 } 11635 LOG_INFO(BSL_LS_SOC_MMU, 11636 (BSL_META_UP(unit, port, 11637 "[SET]MMU Tx enable set: %d, flag: 0x%02x.\n"), 11638 enable, flag)); 11639 11640 thdo_drop_bmp = &(mmu_traffic_ctrl->thdo_drop_bmp[port]); 11641 11642 if (!enable) { 11643 if (*thdo_drop_bmp & flag) { 11644 /*self if already in thdo drop. No HW Op.*/ 11645 } else { 11646 if (*thdo_drop_bmp == 0) { 11647 rv = _soc_td3_thdo_hw_set(unit, port, enable); 11648 if (SOC_FAILURE(rv)) { 11649 LOG_ERROR(BSL_LS_SOC_COMMON, 11650 (BSL_META_U(unit, 11651 "Clear the registers fail.\n"))); 11652 FWD_CTRL_UNLOCK(unit); 11653 return rv; 11654 } 11655 } 11656 } 11657 11658 *thdo_drop_bmp |= flag; 11659 } else { 11660 if ((*thdo_drop_bmp != 0) && (*thdo_drop_bmp != flag)) { 11661 /*other callers are in thdo drop. No HW Op.*/ 11662 } else { 11663 /*Ok, only self is in thdo drop, enbable it*/ 11664 rv = _soc_td3_thdo_hw_set(unit, port, enable); 11665 if (SOC_FAILURE(rv)) { 11666 LOG_ERROR(BSL_LS_SOC_COMMON, 11667 (BSL_META_U(unit, 11668 "Set the registers fail.\n"))); 11669 FWD_CTRL_UNLOCK(unit); 11670 return rv; 11671 } 11672 } 11673 11674 *thdo_drop_bmp &= ~flag; 11675 } 11676 11677 FWD_CTRL_UNLOCK(unit); 11678 11679 LOG_INFO(BSL_LS_SOC_MMU, 11680 (BSL_META_UP(unit, port, 11681 "[SET]MMU Tx drop bmp: 0x%02x.\n"), 11682 *thdo_drop_bmp)); 11683 return rv; 11684 } 11685 11686 /* 11687 * Function: 11688 * _soc_td3_port_thdo_rx_enable_get 11689 * Purpose: 11690 * Get port traffic enqueue status. 11691 * Parameters: 11692 * unit - (IN) unit number 11693 * port - (IN) local port 11694 * enable - (OUT) traffic to the port status. 11695 * False if UC/MC is disabled. 11696 * Returns: 11697 * BCM_E_XXX 11698 */ 11699 STATIC int 11700 _soc_td3_port_thdo_rx_enable_get(int unit, soc_port_t port, 11701 int *enable) 11702 { 11703 int rv = SOC_E_NONE; 11704 11705 rv = _soc_td3_thdo_hw_get(unit, port, enable); 11706 LOG_INFO(BSL_LS_SOC_MMU, 11707 (BSL_META_UP(unit, port, 11708 "[GET]MMU Tx drop bmp: 0x%02x, enable status: %d.\n"), 11709 _soc_td3_mmu_traffic_ctrl[unit]->thdo_drop_bmp[port], 11710 *enable)); 11711 11712 return rv; 11713 } 11714 11715 /* 11716 * Function: 11717 * soc_td3_port_mmu_rx_enable_set 11718 * Purpose: 11719 * enable/disable mmu rx traffic from the gport. 11720 * Parameters: 11721 * unit - (IN) unit number 11722 * port - (IN) PORT identifier 11723 * enable - (IN) enable/disable 11724 * Returns: 11725 * BCM_E_XXX 11726 */ 11727 int 11728 soc_td3_port_mmu_rx_enable_set(int unit, soc_port_t port, 11729 int enable) 11730 { 11731 uint32 rval; 11732 11733 /* Disable/Enable INPUT_PORT_RX to the port */ 11734 SOC_IF_ERROR_RETURN 11735 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr, 11736 port, 0, &rval)); 11737 11738 if (!enable) { 11739 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 11740 INPUT_PORT_RX_ENABLEf, 0); 11741 } else { 11742 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 11743 INPUT_PORT_RX_ENABLEf, 1); 11744 } 11745 11746 SOC_IF_ERROR_RETURN 11747 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr, 11748 port, 0, rval)); 11749 LOG_INFO(BSL_LS_SOC_MMU, 11750 (BSL_META_UP(unit, port, 11751 "[SET]MMU Rx enable: %d.\n"), 11752 enable)); 11753 11754 return SOC_E_NONE; 11755 } 11756 11757 /* 11758 * Function: 11759 * soc_td3_port_mmu_rx_enable_get 11760 * Purpose: 11761 * Get status of mmu rx traffic from the gport. 11762 * Parameters: 11763 * unit - (IN) unit number 11764 * port - (IN) PORT identifier 11765 * enable - (OUT) enable/disable 11766 * Returns: 11767 * BCM_E_XXX 11768 */ 11769 int 11770 soc_td3_port_mmu_rx_enable_get(int unit, soc_port_t port, 11771 int *enable) 11772 { 11773 uint32 rval; 11774 11775 /* Disable/Enable INPUT_PORT_RX to the port */ 11776 SOC_IF_ERROR_RETURN 11777 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr, 11778 port, 0, &rval)); 11779 11780 if (enable != NULL) { 11781 *enable = soc_reg_field_get(unit, THDI_INPUT_PORT_XON_ENABLESr, rval, 11782 INPUT_PORT_RX_ENABLEf); 11783 LOG_INFO(BSL_LS_SOC_MMU, 11784 (BSL_META_UP(unit, port, 11785 "[GET]MMU Rx enable status: %d.\n"), 11786 *enable)); 11787 } 11788 11789 return SOC_E_NONE; 11790 } 11791 11792 int 11793 soc_td3_port_traffic_egr_enable_set(int unit, soc_port_t port, 11794 int enable) 11795 { 11796 return _soc_td3_port_thdo_rx_enable_set(unit, port, enable, 11797 PORT_TX_EN_CTRL); 11798 } 11799 11800 int 11801 soc_td3_port_mmu_tx_enable_set(int unit, soc_port_t port, 11802 int enable) 11803 { 11804 return _soc_td3_port_thdo_rx_enable_set(unit, port, enable, 11805 MMU_TRAFFIC_EN_CTRL); 11806 } 11807 11808 int 11809 soc_td3_port_mmu_tx_enable_get(int unit, soc_port_t port, 11810 int *enable) 11811 { 11812 return _soc_td3_port_thdo_rx_enable_get(unit, port, enable); 11813 } 11814 11815 void 11816 soc_trident3_temperature_intr(void *unit_vp, void *d1, void *d2, 11817 void *d3, void *d4) 11818 { 11819 uint32 rval, trval; 11820 int i, rv, unit = PTR_TO_INT(unit_vp); 11821 const soc_reg_t *pvtmon_result_register=NULL; 11822 int num_entries_out; 11823 #ifdef BCM_MAVERICK2_SUPPORT 11824 if (SOC_IS_MAVERICK2(unit)) { 11825 pvtmon_result_register = &pvtmon_result_reg_mv2[0]; 11826 num_entries_out = COUNTOF(pvtmon_result_reg_mv2); 11827 } else 11828 #endif 11829 { 11830 pvtmon_result_register = &pvtmon_result_reg[0]; 11831 num_entries_out = COUNTOF(pvtmon_result_reg); 11832 } 11833 11834 11835 if ((rv = READ_TOP_PVTMON_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) { 11836 LOG_ERROR(BSL_LS_SOC_COMMON, 11837 (BSL_META_U(unit, 11838 "TD3 Temp Intr, Reg access error.\n"))); 11839 } 11840 LOG_ERROR(BSL_LS_SOC_COMMON, 11841 (BSL_META_U(unit, 11842 "High temp interrupt: 0x%08x\n"), rval)); 11843 /* Raise event to app for it to take further graceful actions */ 11844 for (i = 0; i < num_entries_out; i++) { 11845 if (i & soc_td3_temp_mon_mask[unit]) { 11846 if ((rv = soc_reg32_get(unit, pvtmon_result_register[i], REG_PORT_ANY, 0, 11847 &trval)) != SOC_E_NONE) { 11848 LOG_ERROR(BSL_LS_SOC_COMMON, 11849 (BSL_META_U(unit, 11850 "TD3 Temp Intr, Reg access error.\n"))); 11851 } 11852 trval = soc_reg_field_get(unit, pvtmon_result_register[i], trval, 11853 PVT_DATAf); 11854 /* Convert data to temperature. 11855 * temp = 434.1-(data*0.5350) = (4341000-(trval*5350))/1000; 11856 * Note: Since this is a high temp interrupt we can safely assume 11857 * that this will end up being a +ive value. 11858 */ 11859 trval = (4341000-(trval*5350))/1000; 11860 11861 LOG_ERROR(BSL_LS_SOC_COMMON, 11862 (BSL_META_U(unit, 11863 "TempMon %d: %d deg C.\n"), i, trval)); 11864 (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM, 11865 SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval); 11866 } 11867 } 11868 /* Optionally hold system in reset. 11869 * Note: The main intention is to stop the chip from getting fried and halt 11870 * all schan accesses as the h/w will not respond anymore. 11871 * We are not implementing a gracefull recovery, the unit needs to be 11872 * rebooted after this. 11873 */ 11874 if (soc_property_get(unit, "temp_monitor_shutdown", 1)) { 11875 if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) { 11876 LOG_ERROR(BSL_LS_SOC_COMMON, 11877 (BSL_META_U(unit, 11878 "TH Temp Intr, Reg access error.\n"))); 11879 } 11880 if ((rv = WRITE_TOP_SOFT_RESET_REGr(unit, 0)) != SOC_E_NONE) { 11881 LOG_ERROR(BSL_LS_SOC_COMMON, 11882 (BSL_META_U(unit, 11883 "TH Temp Intr, Reg access error.\n"))); 11884 } 11885 if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) { 11886 LOG_ERROR(BSL_LS_SOC_COMMON, 11887 (BSL_META_U(unit, 11888 "TH Temp Intr, Reg access error.\n"))); 11889 } 11890 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf, 11891 0); 11892 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf, 11893 0); 11894 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL2_RST_Lf, 11895 0); 11896 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL3_RST_Lf, 11897 0); 11898 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 11899 1); 11900 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf, 11901 0); 11902 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf, 11903 0); 11904 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 11905 if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) { 11906 LOG_ERROR(BSL_LS_SOC_COMMON, 11907 (BSL_META_U(unit, 11908 "TH Temp Intr, Reg access error.\n"))); 11909 } 11910 if ((rv = WRITE_TOP_SOFT_RESET_REG_3r(unit, 0)) != SOC_E_NONE) { 11911 LOG_ERROR(BSL_LS_SOC_COMMON, 11912 (BSL_META_U(unit, 11913 "TH Temp Intr, Reg access error.\n"))); 11914 } 11915 11916 /* Stop all schan transactions on this unit */ 11917 #ifdef INCLUDE_I2C 11918 if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) { 11919 LOG_ERROR(BSL_LS_SOC_COMMON, 11920 (BSL_META_U(unit, 11921 "TH Temp Intr, i2c detach error.\n"))); 11922 } 11923 #endif 11924 if (!SOC_IS_RCPU_ONLY(unit)) { 11925 /* Free up DMA memory */ 11926 if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) { 11927 LOG_ERROR(BSL_LS_SOC_COMMON, 11928 (BSL_META_U(unit, 11929 "TH Temp Intr, dma detach error.\n"))); 11930 } 11931 } 11932 if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) { 11933 LOG_ERROR(BSL_LS_SOC_COMMON, 11934 (BSL_META_U(unit, 11935 "TH Temp Intr, mem scan stop error.\n"))); 11936 } 11937 /* Terminate counter module */ 11938 if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) { 11939 LOG_ERROR(BSL_LS_SOC_COMMON, 11940 (BSL_META_U(unit, 11941 "TH Temp Intr, counter stop error.\n"))); 11942 } 11943 if (SOC_SBUSDMA_DM_INFO(unit)) { 11944 if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) { 11945 LOG_ERROR(BSL_LS_SOC_COMMON, 11946 (BSL_META_U(unit, 11947 "TH Temp Intr, sbusdma stop error.\n"))); 11948 } 11949 } 11950 if (soc_feature(unit, soc_feature_arl_hashed)) { 11951 /* Stop L2X thread */ 11952 if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) { 11953 LOG_ERROR(BSL_LS_SOC_COMMON, 11954 (BSL_META_U(unit, 11955 "TH Temp Intr, L2x stop error.\n"))); 11956 } 11957 11958 } 11959 if ((rv = soc_th_l2_bulk_age_stop(unit)) != SOC_E_NONE) { 11960 LOG_ERROR(BSL_LS_SOC_COMMON, 11961 (BSL_META_U(unit, 11962 "TH Temp Intr, L2 age stop error.\n"))); 11963 } 11964 /* Disable all interrupts */ 11965 #ifdef BCM_CMICX_SUPPORT 11966 if (soc_feature(unit, soc_feature_cmicx)) { 11967 11968 } 11969 #endif 11970 SCHAN_LOCK(unit); 11971 /* Clear all outstanding DPCs owned by this unit */ 11972 sal_dpc_cancel(INT_TO_PTR(unit)); 11973 LOG_ERROR(BSL_LS_SOC_COMMON, 11974 (BSL_META_U(unit, 11975 "\nReboot the system.."))); 11976 } 11977 } 11978 11979 int 11980 soc_trident3_temperature_monitor_get(int unit, int temperature_max, 11981 soc_switch_temperature_monitor_t *temperature_array, int *temperature_count) 11982 { 11983 soc_reg_t reg; 11984 int index; 11985 uint32 rval; 11986 int fval, cur, peak; 11987 int num_entries_out; 11988 const soc_reg_t *pvtmon_result_register=NULL; 11989 #ifdef BCM_MAVERICK2_SUPPORT 11990 if (SOC_IS_MAVERICK2(unit)) { 11991 pvtmon_result_register = &pvtmon_result_reg_mv2[0]; 11992 if (COUNTOF(pvtmon_result_reg_mv2) > temperature_max) { 11993 num_entries_out = temperature_max; 11994 } else { 11995 num_entries_out = COUNTOF(pvtmon_result_reg_mv2); 11996 } 11997 } else 11998 #endif 11999 { 12000 pvtmon_result_register = &pvtmon_result_reg[0]; 12001 if (COUNTOF(pvtmon_result_reg) > temperature_max) { 12002 num_entries_out = temperature_max; 12003 } else { 12004 num_entries_out = COUNTOF(pvtmon_result_reg); 12005 } 12006 } 12007 if (temperature_count) { 12008 *temperature_count = 0; 12009 } 12010 /* SDK-125480 temperature reading for VTMON 11 12011 * Assert TOP_AVS_RST_L. 12012 */ 12013 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 12014 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 12015 TOP_AVS_RST_Lf, 0); 12016 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 12017 12018 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_3r(unit, &rval)); 12019 if ((soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_RESET_Nf) == 0) || 12020 (soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_SELECTf) != 0)) { 12021 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 0); 12022 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval)); 12023 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 1); 12024 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_SELECTf, 0); 12025 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval)); 12026 sal_usleep(1000); 12027 } 12028 12029 for (index = 0; index < num_entries_out; index++) { 12030 reg = pvtmon_result_register[index]; 12031 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 12032 12033 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 12034 cur = (4341000-(fval*5350))/1000; 12035 12036 fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf); 12037 peak = (4341000-(fval*5350))/1000; 12038 12039 if (temperature_array) { 12040 (temperature_array + index)->curr = cur; 12041 (temperature_array + index)->peak = peak; 12042 } 12043 } 12044 12045 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 12046 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 12047 TOP_PVT_MON_MIN_RST_Lf, 0); 12048 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 12049 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 12050 TOP_PVT_MON_MIN_RST_Lf, 1); 12051 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 12052 12053 if (temperature_count) { 12054 *temperature_count=num_entries_out; 12055 } 12056 return SOC_E_NONE; 12057 } 12058 12059 int 12060 soc_trident3_show_ring_osc(int unit) 12061 { 12062 static const struct { 12063 int osc_sel; 12064 soc_field_t field0; 12065 int value0; 12066 soc_field_t field1; 12067 int value1; 12068 char *name; 12069 } osc_tbl[] = { 12070 { 0, OSC_0_SELf, 0, INVALIDf, -1, "Core ring 0 HVT min" }, 12071 { 0, OSC_0_SELf, 1, INVALIDf, -1, "Core ring 0 HVT mid" }, 12072 { 0, OSC_0_SELf, 2, INVALIDf, -1, "Core ring 0 HVT max" }, 12073 { 0, OSC_0_SELf, 3, INVALIDf, -1, "Core ring 0 SVT min" }, 12074 { 1, OSC_1_SELf, 0, INVALIDf, -1, "Core ring 1 HVT min" }, 12075 { 1, OSC_1_SELf, 1, INVALIDf, -1, "Core ring 1 HVT mid" }, 12076 { 1, OSC_1_SELf, 2, INVALIDf, -1, "Core ring 1 HVT max" }, 12077 { 1, OSC_1_SELf, 3, INVALIDf, -1, "Core ring 1 SVT min" }, 12078 { 0, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" }, 12079 { 0, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" }, 12080 { 1, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" }, 12081 { 1, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" }, 12082 { 2, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" }, 12083 { 3, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" }, 12084 { 4, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" }, 12085 { 5, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" }, 12086 { 6, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" }, 12087 { 7, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" }, 12088 { 8, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" }, 12089 { 9, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" }, 12090 }; 12091 soc_reg_t ctrl_reg, stat_reg; 12092 uint32 rval, fval; 12093 int index, core_clk, quo, rem, frac, retry; 12094 12095 core_clk = SOC_INFO(unit).frequency * 1024; 12096 ctrl_reg = TOP_RING_OSC_CTRLr; 12097 stat_reg = TOP_OSC_COUNT_STATr; 12098 12099 for (index = 0; index < COUNTOF(osc_tbl); index++) { 12100 rval = 0; 12101 /* 12102 * set OSC_CNT_RSTBf to 0 to do softreset 12103 * set OSC_CNT_START to 0 to hold the counter until it selects 12104 * the input signal 12105 */ 12106 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 12107 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_ENABLEf, 1); 12108 soc_reg_field_set(unit, ctrl_reg, &rval, IROSC_ENf, 1); 12109 soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field0, 12110 osc_tbl[index].value0); 12111 if (osc_tbl[index].field1 != INVALIDf) { 12112 soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field1, 12113 osc_tbl[index].value1); 12114 } 12115 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_SELf, 12116 osc_tbl[index].osc_sel); 12117 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 12118 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_RSTBf, 1); 12119 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 12120 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_STARTf, 1); 12121 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 12122 12123 for (retry = 0; retry < 10; retry++) { 12124 sal_usleep(1000); 12125 SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval)); 12126 if (!soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_DONEf)) { 12127 continue; 12128 } 12129 12130 fval = soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_VALUEf); 12131 quo = core_clk / fval; 12132 rem = core_clk - quo * fval; 12133 frac = (rem * 10000) / fval; 12134 LOG_CLI((BSL_META_U(unit, 12135 "%s: %d.%04d Mhz\n"), 12136 osc_tbl[index].name, quo, frac)); 12137 break; 12138 } 12139 } 12140 12141 return SOC_E_NONE; 12142 } 12143 12144 STATIC _soc_td3_bst_hw_cb td3_bst_cb; 12145 extern int bst_td3_cfap_trigger_status[SOC_MAX_NUM_DEVICES]; 12146 int 12147 soc_td3_process_mmu_bst(int unit, int xpe, soc_field_t field) 12148 { 12149 int rv = SOC_E_NONE; 12150 if (field == BST_CFAP_INT_STATf) { 12151 bst_td3_cfap_trigger_status[unit] = 1; 12152 } 12153 if (td3_bst_cb != NULL) { 12154 rv = td3_bst_cb(unit); 12155 } 12156 return rv; 12157 } 12158 12159 int soc_td3_set_bst_callback(int unit, _soc_td3_bst_hw_cb cb) 12160 { 12161 td3_bst_cb = cb; 12162 return SOC_E_NONE; 12163 } 12164 12165 STATIC _soc_td3_tcb_hw_cb td3_tcb_cb; 12166 12167 int 12168 soc_td3_process_mmu_tcb(int unit, int xpe, soc_field_t field) 12169 { 12170 int rv = SOC_E_NONE; 12171 if (td3_tcb_cb != NULL) { 12172 rv = td3_tcb_cb(unit); 12173 } 12174 return rv; 12175 } 12176 12177 int soc_td3_set_tcb_callback(int unit, _soc_td3_tcb_hw_cb cb) 12178 { 12179 td3_tcb_cb = cb; 12180 return SOC_E_NONE; 12181 } 12182 12183 STATIC int 12184 _soc_td3_mmu_config_shared_update_check(int val1, int val2, int flags) 12185 { 12186 int rv = 0; 12187 if (flags == 1) { 12188 if (val1 > val2) { 12189 rv = 1; 12190 } 12191 } else { 12192 if (val1 < val2) { 12193 rv = 1; 12194 } 12195 } 12196 return rv; 12197 } 12198 12199 #define TD3_MMU_SHARED_LIMIT_CHK(val1, val2, flags) \ 12200 _soc_td3_mmu_config_shared_update_check((val1), (val2), (flags)) 12201 12202 12203 int 12204 soc_td3_mmu_config_shared_buf_recalc(int unit, int res, int thdi_shd, 12205 int thdo_db_shd, int thdo_qe_shd, 12206 int post_update) 12207 { 12208 soc_info_t *si; 12209 int pipe; 12210 uint32 entry0[SOC_MAX_MEM_WORDS], cur_limit, rval = 0, rval2 = 0; 12211 uint64 rval64; 12212 thdi_port_pg_config_entry_t pg_config_mem; 12213 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 12214 int port, base, numq, idx, midx; 12215 soc_mem_t base_mem = INVALIDm, base_mem2 = INVALIDm; 12216 soc_mem_t mem = INVALIDm, mem2 = INVALIDm; 12217 soc_reg_t reg = INVALIDr; 12218 soc_field_t field = INVALIDf; 12219 int granularity, index1; 12220 12221 COMPILER_64_ZERO(rval64); 12222 si = &SOC_INFO(unit); 12223 12224 /*********************************** 12225 * THDI 12226 */ 12227 if (res & 0x1) { /* if (res & THDI) { */ 12228 12229 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 12230 /* THDI SP entries */ 12231 rval = 0; 12232 reg = THDI_BUFFER_CELL_LIMIT_SPr; 12233 field = LIMITf; 12234 granularity = 1; 12235 SOC_IF_ERROR_RETURN 12236 (READ_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, &rval)); 12237 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12238 if ((cur_limit != 0) && 12239 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdi_shd/granularity, 12240 post_update)) { 12241 soc_reg_field_set(unit, reg, &rval, field, (thdi_shd/granularity)); 12242 SOC_IF_ERROR_RETURN( 12243 soc_trident3_xpe_reg32_set(unit, reg, 12244 -1, -1, idx, rval)); 12245 } 12246 } 12247 12248 /* Input per port settings */ 12249 base_mem = THDI_PORT_PG_CONFIGm; 12250 PBMP_ALL_ITER(unit, port) { 12251 pipe = si->port_pipe[port]; 12252 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12253 field = PG_SHARED_LIMITf; 12254 granularity = 1; 12255 /* Input port per Port-PG settings */ 12256 for (idx = 0; idx < _TD3_MMU_NUM_PG; idx++) { 12257 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12258 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 12259 SOC_IF_ERROR_RETURN 12260 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, 12261 midx, &pg_config_mem)); 12262 if (!soc_mem_field32_get(unit, mem, &pg_config_mem, 12263 PG_SHARED_DYNAMICf)) { 12264 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, 12265 field); 12266 if ((cur_limit != 0) && 12267 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdi_shd/granularity, 12268 post_update)) { 12269 soc_mem_field32_set(unit, mem, &pg_config_mem, 12270 field, thdi_shd/granularity); 12271 } 12272 } 12273 12274 SOC_IF_ERROR_RETURN 12275 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 12276 midx, &pg_config_mem)); 12277 } 12278 } 12279 } 12280 12281 /*********************************** 12282 * THDO 12283 */ 12284 if (res & 0x2) { /* if (res & THDO) { */ 12285 /* Per SP settings */ 12286 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 12287 /* DB entries */ 12288 rval = 0; 12289 reg = MMU_THDM_DB_POOL_SHARED_LIMITr; 12290 field = SHARED_LIMITf; 12291 granularity = 1; 12292 SOC_IF_ERROR_RETURN 12293 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12294 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12295 if ((cur_limit != 0) && 12296 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 12297 post_update)) { 12298 soc_reg_field_set(unit, reg, &rval, field, (thdo_db_shd/granularity)); 12299 SOC_IF_ERROR_RETURN 12300 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12301 } 12302 12303 rval = 0; 12304 reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr; 12305 field = YELLOW_SHARED_LIMITf; 12306 granularity = 8; 12307 SOC_IF_ERROR_RETURN 12308 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12309 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12310 if ((cur_limit != 0) && 12311 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity), 12312 post_update)) { 12313 soc_reg_field_set(unit, reg, &rval, field, sal_ceil_func(thdo_db_shd, granularity)); 12314 SOC_IF_ERROR_RETURN 12315 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12316 } 12317 12318 rval = 0; 12319 reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr; 12320 field = RED_SHARED_LIMITf; 12321 granularity = 8; 12322 SOC_IF_ERROR_RETURN 12323 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12324 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12325 if ((cur_limit != 0) && 12326 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity), 12327 post_update)) { 12328 soc_reg_field_set(unit, reg, &rval, field, sal_ceil_func(thdo_db_shd, granularity)); 12329 SOC_IF_ERROR_RETURN 12330 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12331 } 12332 12333 /* MCQE */ 12334 rval = 0; 12335 reg = MMU_THDM_MCQE_POOL_SHARED_LIMITr; 12336 field = SHARED_LIMITf; 12337 granularity = 1; /* Value retrieved from QE. Hence no further 12338 * granularity for Non-color Shd Limit */ 12339 SOC_IF_ERROR_RETURN 12340 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12341 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12342 if ((cur_limit != 0) && 12343 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity, 12344 post_update)) { 12345 soc_reg_field_set(unit, reg, &rval, field, 12346 (thdo_qe_shd/granularity)); 12347 SOC_IF_ERROR_RETURN 12348 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12349 } 12350 12351 rval = 0; 12352 reg = MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr; 12353 field = YELLOW_SHARED_LIMITf; 12354 granularity = 8; 12355 SOC_IF_ERROR_RETURN 12356 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12357 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12358 if ((cur_limit != 0) && 12359 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity, 12360 post_update)) { 12361 soc_reg_field_set(unit, reg, &rval, field, 12362 (thdo_qe_shd/granularity)); 12363 SOC_IF_ERROR_RETURN 12364 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12365 } 12366 12367 rval = 0; 12368 reg = MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr; 12369 field = RED_SHARED_LIMITf; 12370 granularity = 8; 12371 SOC_IF_ERROR_RETURN 12372 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12373 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12374 if ((cur_limit != 0) && 12375 TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity, 12376 post_update)) { 12377 soc_reg_field_set(unit, reg, &rval, field, 12378 (thdo_qe_shd/granularity)); 12379 SOC_IF_ERROR_RETURN 12380 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12381 } 12382 } 12383 12384 /* configure Q-groups */ 12385 base_mem = MMU_THDU_CONFIG_QGROUPm; 12386 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 12387 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12388 for (idx = 0; idx < SOC_TD3_MMU_CFG_QGROUP_MAX; idx++) { 12389 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 12390 12391 SOC_IF_ERROR_RETURN 12392 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12393 12394 field = Q_SHARED_LIMIT_CELLf; 12395 granularity = 1; 12396 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) { 12397 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12398 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 12399 post_update)) { 12400 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12401 field, thdo_db_shd/granularity); 12402 } 12403 } 12404 12405 granularity = 8; 12406 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, 12407 Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 12408 field = LIMIT_RED_CELLf; 12409 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12410 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 12411 post_update)) { 12412 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12413 field, thdo_db_shd/granularity); 12414 } 12415 12416 field = LIMIT_YELLOW_CELLf; 12417 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12418 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 12419 post_update)) { 12420 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12421 field, thdo_db_shd/granularity); 12422 } 12423 } 12424 12425 SOC_IF_ERROR_RETURN 12426 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12427 } 12428 } 12429 12430 /* Output port per port per queue setting for UC queue */ 12431 PBMP_PORT_ITER(unit, port) { 12432 base_mem = MMU_THDU_CONFIG_QUEUEm; 12433 pipe = si->port_pipe[port]; 12434 12435 /* per port UC queue */ 12436 numq = si->port_num_uc_cosq[port]; 12437 base = si->port_uc_cosq_base[port]; 12438 12439 if (numq == 0) { 12440 continue; 12441 } 12442 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12443 for (idx = 0; idx < numq; idx++) { 12444 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 12445 12446 SOC_IF_ERROR_RETURN 12447 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12448 12449 field = Q_SHARED_LIMIT_CELLf; 12450 granularity = 1; 12451 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) { 12452 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12453 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 12454 post_update)) { 12455 soc_mem_field32_set(unit, mem, entry0, 12456 field, thdo_db_shd/granularity); 12457 } 12458 } 12459 12460 granularity = 8; 12461 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 12462 field = LIMIT_YELLOW_CELLf; 12463 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12464 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity), 12465 post_update)) { 12466 soc_mem_field32_set(unit, mem, entry0, 12467 field, sal_ceil_func(thdo_db_shd, granularity)); 12468 } 12469 field = LIMIT_RED_CELLf; 12470 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12471 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12472 sal_ceil_func(thdo_db_shd, granularity), post_update)) { 12473 soc_mem_field32_set(unit, mem, entry0, 12474 field, sal_ceil_func(thdo_db_shd, granularity)); 12475 } 12476 } 12477 SOC_IF_ERROR_RETURN 12478 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12479 } 12480 12481 /* Per port-SP unicast */ 12482 base_mem = MMU_THDU_CONFIG_PORTm; 12483 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12484 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 12485 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12486 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t)); 12487 12488 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 12489 index1, entry0)); 12490 12491 field = SHARED_LIMITf; 12492 granularity = 1; 12493 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12494 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12495 thdo_db_shd/granularity, post_update)) { 12496 soc_mem_field32_set(unit, mem, entry0, 12497 field, thdo_db_shd/granularity); 12498 } 12499 12500 granularity = 8; 12501 field = YELLOW_LIMITf; 12502 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12503 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12504 thdo_db_shd/granularity, post_update)) { 12505 soc_mem_field32_set(unit, mem, entry0, 12506 field, thdo_db_shd/granularity); 12507 } 12508 field = RED_LIMITf; 12509 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12510 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12511 thdo_db_shd/granularity, post_update)) { 12512 soc_mem_field32_set(unit, mem, entry0, 12513 field, thdo_db_shd/granularity); 12514 } 12515 12516 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 12517 index1, entry0)); 12518 } 12519 } 12520 12521 /* Output port per port per queue setting for MC queue */ 12522 PBMP_PORT_ITER(unit, port) { 12523 base_mem = MMU_THDM_DB_PORTSP_CONFIGm; 12524 base_mem2 = MMU_THDM_MCQE_PORTSP_CONFIGm; 12525 pipe = si->port_pipe[port]; 12526 12527 /* Per Port-SP */ 12528 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12529 mem2 = SOC_MEM_UNIQUE_ACC(unit, base_mem2)[pipe]; 12530 for (idx = 0; idx < _TD3_MMU_NUM_POOL; idx++) { 12531 /* DB entries - Port-SP */ 12532 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12533 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t)); 12534 12535 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 12536 index1, entry0)); 12537 12538 field = SHARED_LIMITf; 12539 granularity = 1; 12540 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12541 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12542 thdo_db_shd/granularity, post_update)) { 12543 soc_mem_field32_set(unit, mem, entry0, 12544 field, thdo_db_shd/granularity); 12545 } 12546 12547 field = RED_SHARED_LIMITf; 12548 granularity = 8; 12549 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12550 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12551 thdo_db_shd/granularity, post_update)) { 12552 soc_mem_field32_set(unit, mem, entry0, 12553 field, thdo_db_shd/granularity); 12554 } 12555 12556 field = YELLOW_SHARED_LIMITf; 12557 granularity = 8; 12558 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12559 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12560 thdo_db_shd/granularity, post_update)) { 12561 soc_mem_field32_set(unit, mem, entry0, 12562 field, thdo_db_shd/granularity); 12563 } 12564 12565 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 12566 index1, entry0)); 12567 12568 /* MCQE - Port-SP*/ 12569 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t)); 12570 12571 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem2, MEM_BLOCK_ALL, 12572 index1, entry0)); 12573 field = SHARED_LIMITf; 12574 granularity = 4; 12575 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field); 12576 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12577 thdo_qe_shd/granularity, post_update)) { 12578 soc_mem_field32_set(unit, mem2, entry0, 12579 field, thdo_qe_shd/granularity); 12580 } 12581 12582 field = RED_SHARED_LIMITf; 12583 granularity = 8; 12584 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field); 12585 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12586 thdo_qe_shd/granularity, post_update)) { 12587 soc_mem_field32_set(unit, mem2, entry0, 12588 field, thdo_qe_shd/granularity); 12589 } 12590 12591 field = YELLOW_SHARED_LIMITf; 12592 granularity = 8; 12593 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field); 12594 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12595 thdo_qe_shd/granularity, post_update)) { 12596 soc_mem_field32_set(unit, mem2, entry0, 12597 field, thdo_qe_shd/granularity); 12598 } 12599 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 12600 index1, entry0)); 12601 12602 } 12603 12604 /* DB entries - Queue */ 12605 numq = si->port_num_cosq[port]; 12606 base = si->port_cosq_base[port]; 12607 if (numq == 0) { 12608 continue; 12609 } 12610 12611 base_mem = MMU_THDM_DB_QUEUE_CONFIGm; 12612 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12613 12614 for (idx = 0; idx < numq; idx++) { 12615 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_entry_t)); 12616 12617 SOC_IF_ERROR_RETURN 12618 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12619 12620 field = Q_SHARED_LIMITf; 12621 granularity = 1; 12622 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 12623 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12624 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12625 thdo_db_shd/granularity, post_update)) { 12626 soc_mem_field32_set(unit, mem, entry0, 12627 field, thdo_db_shd/granularity); 12628 } 12629 } 12630 12631 granularity = 8; 12632 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 12633 field = YELLOW_SHARED_LIMITf; 12634 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12635 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12636 sal_ceil_func(thdo_db_shd, granularity), post_update)) { 12637 soc_mem_field32_set(unit, mem, entry0, 12638 field, sal_ceil_func(thdo_db_shd, granularity)); 12639 } 12640 field = RED_SHARED_LIMITf; 12641 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12642 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12643 sal_ceil_func(thdo_db_shd, granularity), post_update)) { 12644 soc_mem_field32_set(unit, mem, entry0, 12645 field, sal_ceil_func(thdo_db_shd, granularity)); 12646 } 12647 } 12648 SOC_IF_ERROR_RETURN 12649 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 12650 entry0)); 12651 } 12652 12653 /* MCQE - Queue */ 12654 base_mem = MMU_THDM_MCQE_QUEUE_CONFIGm; 12655 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 12656 for (idx = 0; idx < numq; idx++) { 12657 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 12658 12659 SOC_IF_ERROR_RETURN 12660 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12661 12662 field = Q_SHARED_LIMITf; 12663 granularity = 4; 12664 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 12665 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12666 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12667 thdo_qe_shd/granularity, post_update)) { 12668 soc_mem_field32_set(unit, mem, entry0, 12669 field, thdo_qe_shd/granularity); 12670 } 12671 } 12672 12673 granularity = 8; 12674 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 12675 field = YELLOW_SHARED_LIMITf; 12676 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12677 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12678 thdo_qe_shd/granularity, post_update)) { 12679 soc_mem_field32_set(unit, mem, entry0, 12680 field, thdo_qe_shd/granularity); 12681 } 12682 field = RED_SHARED_LIMITf; 12683 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12684 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12685 thdo_qe_shd/granularity, post_update)) { 12686 soc_mem_field32_set(unit, mem, entry0, 12687 field, thdo_qe_shd/granularity); 12688 } 12689 } 12690 SOC_IF_ERROR_RETURN 12691 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 12692 entry0)); 12693 } 12694 } 12695 12696 /* RQE */ 12697 for (idx = 0; idx < 11; idx++) { 12698 rval = 0; 12699 COMPILER_64_ZERO(rval64); 12700 12701 SOC_IF_ERROR_RETURN 12702 (READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval)); 12703 12704 reg = MMU_THDR_DB_CONFIG_PRIQr; 12705 field = SHARED_LIMITf; 12706 granularity = 1; 12707 SOC_IF_ERROR_RETURN 12708 (soc_reg64_get(unit, reg, REG_PORT_ANY, idx, &rval64)); 12709 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 12710 DYNAMIC_ENABLEf)) { 12711 cur_limit = soc_reg64_field32_get(unit, reg, rval64, field); 12712 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12713 thdo_db_shd/granularity, post_update)) { 12714 soc_reg64_field32_set(unit, reg, &rval64, field, 12715 (thdo_db_shd/granularity)); 12716 SOC_IF_ERROR_RETURN 12717 (soc_reg64_set(unit, reg, REG_PORT_ANY, idx, rval64)); 12718 } 12719 } 12720 12721 rval2 = 0; 12722 reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr; 12723 granularity = 8; 12724 SOC_IF_ERROR_RETURN 12725 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 12726 12727 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 12728 COLOR_LIMIT_DYNAMICf)) { 12729 field = SHARED_RED_LIMITf; 12730 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 12731 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12732 thdo_db_shd/granularity, post_update)) { 12733 soc_reg_field_set(unit, reg, &rval2, field, (thdo_db_shd/granularity)); 12734 } 12735 12736 field = SHARED_YELLOW_LIMITf; 12737 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 12738 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12739 thdo_db_shd/granularity, post_update)) { 12740 soc_reg_field_set(unit, reg, &rval2, field, (thdo_db_shd/granularity)); 12741 } 12742 SOC_IF_ERROR_RETURN 12743 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 12744 } 12745 12746 } 12747 /* per pool RQE settings */ 12748 for (idx = 0; idx < 4; idx++) { 12749 reg = MMU_THDR_DB_CONFIG_SPr; 12750 field = SHARED_LIMITf; 12751 granularity = 1; 12752 12753 SOC_IF_ERROR_RETURN 12754 (soc_reg64_get(unit, reg, REG_PORT_ANY, idx, &rval64)); 12755 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12756 12757 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12758 thdo_db_shd/granularity, post_update)) { 12759 soc_reg64_field32_set 12760 (unit, reg, &rval64, field, (thdo_db_shd/granularity)); 12761 SOC_IF_ERROR_RETURN 12762 (soc_reg64_set(unit, reg, REG_PORT_ANY, idx, rval64)); 12763 } 12764 12765 reg = MMU_THDR_DB_SP_SHARED_LIMITr; 12766 granularity = 8; 12767 12768 SOC_IF_ERROR_RETURN 12769 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 12770 12771 field = SHARED_YELLOW_LIMITf; 12772 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12773 12774 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12775 thdo_db_shd/granularity, post_update)) { 12776 soc_reg_field_set 12777 (unit, reg, &rval2, field, (thdo_db_shd/granularity)); 12778 } 12779 12780 field = SHARED_RED_LIMITf; 12781 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12782 12783 if (TD3_MMU_SHARED_LIMIT_CHK(cur_limit, 12784 thdo_db_shd/granularity, post_update)) { 12785 soc_reg_field_set 12786 (unit, reg, &rval2, field, (thdo_db_shd/granularity)); 12787 } 12788 SOC_IF_ERROR_RETURN 12789 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 12790 } 12791 } 12792 return SOC_E_NONE; 12793 } 12794 12795 void 12796 soc_trident3_process_func_intr(void *unit_vp, void *d1, void *d2, void *d3, void *d4) 12797 { 12798 int rv = SOC_E_NONE; 12799 int unit = PTR_TO_INT(unit_vp); 12800 uint32 rval; 12801 char prefix_str[10]; 12802 sal_sprintf(prefix_str, "Unit: %d \n", unit); 12803 12804 rv = READ_L2_MGMT_INTRr(unit, &rval); 12805 if (SOC_FAILURE(rv)) { 12806 LOG_ERROR(BSL_LS_SOC_COMMON, 12807 (BSL_META_U(unit, "Error reading %s reg !!\n"), 12808 SOC_REG_NAME(unit, L2_MGMT_INTRr))); 12809 return; 12810 } 12811 12812 if (soc_reg_field_get(unit, L2_MGMT_INTRr, rval, SER_FIFO_NOT_EMPTYf)) { 12813 (void) soc_trident3_process_ser_fifo(unit, SOC_BLK_IPIPE, 12814 0, /* pipe */ 12815 prefix_str, 12816 1); /* l2_mgmt_ser_fifo */ 12817 } 12818 if (soc_reg_field_get(unit, L2_MGMT_INTRr, rval, L2_LEARN_INSERT_FAILUREf)) { 12819 soc_td2_l2_overflow_interrupt_handler(unit); 12820 } 12821 12822 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */ 12823 if (d4 != NULL) { 12824 #ifdef BCM_CMICX_SUPPORT 12825 if (soc_feature(unit, soc_feature_cmicx)) { 12826 (void)soc_cmic_intr_enable(unit, PTR_TO_INT(d4)); 12827 } 12828 #endif 12829 } 12830 } 12831 12832 12833 /* 12834 * All non-parity related interrupts must be handled in this function. 12835 * All unserviced intr_status bits must either be serviced or disabled. 12836 * 12837 * Note: 12838 * 1. MEM_PAR_ERR_STATf is handled by trident3/ser.c, so ignore this 12839 * 2. blocktype (in) can only be SOC_BLK_MMU_XPE/SC/SED 12840 */ 12841 int 12842 soc_td3_mmu_non_ser_intr_handler(int unit, soc_block_t blocktype, 12843 int mmu_base_index, 12844 uint32 rval_intr_status_reg) 12845 { 12846 /*This need each other block to implement the non-ser interrupt handler */ 12847 int i; 12848 uint32 rval = 0; 12849 soc_reg_t intr_stat_reg, intr_clr_reg; 12850 12851 static soc_field_t xpe_intr_field_list[] = { 12852 MEM_PAR_ERR_STATf, /* handled by trident3/ser.c, so ignore this */ 12853 BST_THDI_INT_STATf, 12854 BST_THDO_INT_STATf, 12855 DEQ0_NOT_IP_ERR_STATf, 12856 DEQ1_NOT_IP_ERR_STATf, 12857 ENQX_TO_CFG_MAX_CELL_INTR_0_STATf, 12858 ENQX_TO_CFG_MAX_CELL_INTR_1_STATf, 12859 TCB_FREEZE_INT_STATf, 12860 INVALIDf 12861 }; 12862 12863 static soc_field_t sed_intr_field_list[] = { 12864 CFAP_MEM_FAIL_STATf, 12865 MEM_PAR_ERR_STATf, 12866 BST_CFAP_INT_STATf, 12867 START_BY_START_ERR_STATf, 12868 INVALIDf 12869 }; 12870 12871 if (blocktype == SOC_BLK_MMU_XPE) { 12872 intr_stat_reg = MMU_XCFG_XPE_CPU_INT_STATr; 12873 intr_clr_reg = MMU_XCFG_XPE_CPU_INT_CLEARr; 12874 for (i = 0; xpe_intr_field_list[i] != INVALIDf; i++) { 12875 if (!soc_reg_field_valid(unit, intr_stat_reg, xpe_intr_field_list[i])) { 12876 continue; 12877 } 12878 if (!soc_reg_field_get(unit, intr_stat_reg, 12879 rval_intr_status_reg, 12880 xpe_intr_field_list[i])) { 12881 continue; 12882 } 12883 switch (xpe_intr_field_list[i]) { 12884 case BST_THDI_INT_STATf: 12885 case BST_THDO_INT_STATf: 12886 /* interrupt processing */ 12887 LOG_VERBOSE(BSL_LS_SOC_COMMON, 12888 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 12889 "from xpe = %0d \n"), 12890 unit, SOC_FIELD_NAME(unit, xpe_intr_field_list[i]), 12891 mmu_base_index)); 12892 12893 /* clear the interrupt */ 12894 SOC_IF_ERROR_RETURN 12895 (soc_trident3_xpe_reg32_get(unit, intr_clr_reg, 12896 mmu_base_index, mmu_base_index, 12897 0, &rval)); 12898 rval |= (1 << i); 12899 SOC_IF_ERROR_RETURN 12900 (soc_trident3_xpe_reg32_set(unit, intr_clr_reg, 12901 mmu_base_index, mmu_base_index, 12902 0, rval)); 12903 SOC_IF_ERROR_RETURN 12904 (soc_td3_process_mmu_bst(unit, mmu_base_index, 12905 xpe_intr_field_list[i])); 12906 break; 12907 case TCB_FREEZE_INT_STATf: 12908 /* interrupt processing */ 12909 LOG_VERBOSE(BSL_LS_SOC_COMMON, 12910 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 12911 "from xpe = %0d \n"), 12912 unit, SOC_FIELD_NAME(unit, xpe_intr_field_list[i]), 12913 mmu_base_index)); 12914 12915 /* clear the interrupt */ 12916 SOC_IF_ERROR_RETURN 12917 (soc_trident3_xpe_reg32_get(unit, intr_clr_reg, 12918 mmu_base_index, mmu_base_index, 12919 0, &rval)); 12920 rval |= (1 << i); 12921 SOC_IF_ERROR_RETURN 12922 (soc_trident3_xpe_reg32_set(unit, intr_clr_reg, 12923 mmu_base_index, mmu_base_index, 12924 0, rval)); 12925 SOC_IF_ERROR_RETURN 12926 (soc_td3_process_mmu_tcb(unit, mmu_base_index, 12927 xpe_intr_field_list[i])); 12928 break; 12929 default: 12930 LOG_ERROR(BSL_LS_SOC_COMMON, 12931 (BSL_META_U(unit, "Unit: %0d -- Could not service %s " 12932 "intr from xpe = %0d \n"), 12933 unit, SOC_FIELD_NAME(unit, xpe_intr_field_list[i]), 12934 mmu_base_index)); 12935 break; 12936 } 12937 } 12938 return SOC_E_NONE; 12939 } 12940 12941 if (blocktype == SOC_BLK_MMU_SED) { 12942 intr_stat_reg = MMU_SEDCFG_SED_CPU_INT_STATr; 12943 intr_clr_reg = MMU_SEDCFG_SED_CPU_INT_CLEARr; 12944 for (i = 0; sed_intr_field_list[i] != INVALIDf; i++) { 12945 if (!soc_reg_field_valid(unit, intr_stat_reg, sed_intr_field_list[i])) { 12946 continue; 12947 } 12948 if (!soc_reg_field_get(unit, intr_stat_reg, 12949 rval_intr_status_reg, 12950 sed_intr_field_list[i])) { 12951 continue; 12952 } 12953 switch (sed_intr_field_list[i]) { 12954 case BST_CFAP_INT_STATf: 12955 /* interrupt processing */ 12956 LOG_VERBOSE(BSL_LS_SOC_COMMON, 12957 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 12958 "from sed = %0d \n"), 12959 unit, SOC_FIELD_NAME(unit, sed_intr_field_list[i]), 12960 mmu_base_index)); 12961 12962 /* clear the interrupt */ 12963 SOC_IF_ERROR_RETURN 12964 (soc_trident3_sed_reg32_get(unit, intr_clr_reg, 12965 mmu_base_index, mmu_base_index, 12966 0, &rval)); 12967 rval |= (1 << i); 12968 SOC_IF_ERROR_RETURN 12969 (soc_trident3_sed_reg32_set(unit, intr_clr_reg, 12970 mmu_base_index, mmu_base_index, 12971 0, rval)); 12972 SOC_IF_ERROR_RETURN 12973 (soc_td3_process_mmu_bst(unit, mmu_base_index, 12974 sed_intr_field_list[i])); 12975 break; 12976 case CFAP_MEM_FAIL_STATf: 12977 /* interrupt processing */ 12978 LOG_VERBOSE(BSL_LS_SOC_COMMON, 12979 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 12980 "from sed = %0d \n"), 12981 unit, SOC_FIELD_NAME(unit, sed_intr_field_list[i]), 12982 mmu_base_index)); 12983 12984 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 12985 SOC_SWITCH_EVENT_DATA_ERROR_CFAP_MEM_FAIL, -1, -1); 12986 12987 /* clear the interrupt */ 12988 SOC_IF_ERROR_RETURN 12989 (soc_trident3_sed_reg32_get(unit, intr_clr_reg, 12990 mmu_base_index, mmu_base_index, 12991 0, &rval)); 12992 rval |= (1 << i); 12993 SOC_IF_ERROR_RETURN 12994 (soc_trident3_sed_reg32_set(unit, intr_clr_reg, 12995 mmu_base_index, mmu_base_index, 12996 0, rval)); 12997 break; 12998 default: 12999 LOG_ERROR(BSL_LS_SOC_COMMON, 13000 (BSL_META_U(unit, "Unit: %0d -- Could not service %s " 13001 "intr from sed = %0d \n"), 13002 unit, SOC_FIELD_NAME(unit, sed_intr_field_list[i]), 13003 mmu_base_index)); 13004 break; 13005 } 13006 } 13007 return SOC_E_NONE; 13008 } 13009 13010 return SOC_E_NONE; 13011 } 13012 13013 /* 13014 * Function: 13015 * soc_td3_subport_init 13016 * Purpose: 13017 * Setup the pbm fields from config variables for the COE application 13018 * Parameters: 13019 * unit - (IN) Device number. 13020 * Returns: 13021 * NONE 13022 */ 13023 void soc_td3_subport_init(int unit) 13024 { 13025 soc_port_t port; 13026 soc_info_t *si=&SOC_INFO(unit); 13027 soc_pbmp_t pbmp_subport; 13028 int num_subport = 0; 13029 13030 SOC_PBMP_CLEAR(si->subtag_pbm); 13031 SOC_PBMP_CLEAR(si->subtag_allowed_pbm); 13032 SOC_PBMP_CLEAR(si->subtag.bitmap); 13033 13034 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 13035 si->port_num_subport[port] = 0; 13036 } 13037 13038 pbmp_subport = soc_property_get_pbmp(unit, spn_PBMP_SUBPORT, 0); 13039 13040 SOC_PBMP_ASSIGN(si->subtag_allowed_pbm, pbmp_subport); 13041 13042 if (SOC_PBMP_NOT_NULL(si->subtag_allowed_pbm)) { 13043 /* Iterate through SubTag ports and reserve subport indices */ 13044 SOC_PBMP_ITER(si->subtag_allowed_pbm, port) { 13045 13046 num_subport = 13047 soc_property_port_get(unit, port, spn_NUM_SUBPORTS, 0); 13048 13049 if (num_subport > TD3_MAX_SUBPORT_COE_PORT_PER_CASPORT) { 13050 LOG_ERROR(BSL_LS_SOC_COMMON, 13051 (BSL_META_U(unit, 13052 "\nCONFIG ERROR\n" 13053 "num_subports_%d on port %d exceed max value," 13054 "setting it to the max allowed value %d\n\n"), 13055 num_subport, port, 13056 TD3_MAX_SUBPORT_COE_PORT_PER_CASPORT)); 13057 num_subport = TD3_MAX_SUBPORT_COE_PORT_PER_CASPORT; 13058 } 13059 13060 if (port < SOC_MAX_NUM_PORTS) { 13061 si->port_num_subport[port] = num_subport; 13062 13063 } 13064 } 13065 } 13066 13067 /* Initialize the number of COE modules */ 13068 si->num_coe_modules = TD3_MAX_COE_MODULES; 13069 } 13070 13071 soc_pstats_tbl_desc_t 13072 _soc_td3_pstats_tbl_desc_all = {SOC_BLK_NONE, INVALIDm, FALSE, FALSE}; 13073 /* pstats support */ 13074 soc_pstats_tbl_desc_t _soc_td3_pstats_tbl_desc[] = { 13075 /* List all the potential memories */ 13076 #ifdef BCM_PSTATS_MEASURE 13077 { 13078 SOC_BLK_MMU_GLB, 13079 INVALIDm, 13080 FALSE, FALSE, 13081 { 13082 {MMU_INTFO_TIMESTAMPm}, 13083 {INVALIDm} 13084 } 13085 }, 13086 #endif 13087 { 13088 SOC_BLK_MMU_GLB, 13089 INVALIDm, 13090 FALSE, FALSE, 13091 { 13092 {MMU_INTFO_UTC_TIMESTAMPm}, 13093 {INVALIDm} 13094 } 13095 }, 13096 { 13097 SOC_BLK_MMU_XPE, 13098 MMU_THDU_UCQ_STATS_TABLEm, 13099 TRUE, TRUE 13100 }, 13101 { 13102 SOC_BLK_MMU_XPE, 13103 THDI_PKT_STAT_SP_SHARED_COUNTm, 13104 FALSE, FALSE 13105 }, 13106 { 13107 SOC_BLK_MMU_XPE, 13108 MMU_THDM_DB_POOL_MCUC_PKSTATm, 13109 FALSE, FALSE 13110 #ifdef BCM_PSTATS_MEASURE 13111 }, 13112 { 13113 SOC_BLK_MMU_GLB, 13114 INVALIDm, 13115 FALSE, FALSE, 13116 { 13117 {MMU_INTFO_TIMESTAMPm}, 13118 {INVALIDm} 13119 } 13120 #endif 13121 } 13122 }; 13123 13124 void 13125 soc_trident3_mmu_pstats_tbl_config_all(int unit) 13126 { 13127 soc_control_t *soc = SOC_CONTROL(unit); 13128 soc_pstats_mem_desc_t *desc, *desc_all; 13129 int ti, mi, di = 0; 13130 13131 desc_all = _soc_td3_pstats_tbl_desc_all.desc; 13132 /* Check and strip invalid memories */ 13133 for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) { 13134 mi = 0; 13135 desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc; 13136 while (desc[mi].mem != INVALIDm) { 13137 desc_all[di] = desc[mi]; 13138 di++; 13139 mi++; 13140 } 13141 } 13142 desc_all[di].mem = INVALIDm; 13143 13144 soc->pstats_tbl_desc = &_soc_td3_pstats_tbl_desc_all; 13145 soc->pstats_tbl_desc_count = 1; 13146 } 13147 13148 void 13149 soc_trident3_mmu_pstats_tbl_config(int unit) 13150 { 13151 soc_control_t *soc = SOC_CONTROL(unit); 13152 soc_pstats_mem_desc_t *desc; 13153 soc_mem_t bmem; 13154 int pe, mor_dma; 13155 int ti, mi, xpe, pipe; 13156 13157 soc->pstats_tbl_desc = _soc_td3_pstats_tbl_desc; 13158 soc->pstats_tbl_desc_count = COUNTOF(_soc_td3_pstats_tbl_desc); 13159 soc->pstats_mode = PSTATS_MODE_NULL; 13160 13161 /* Check and strip invalid memories */ 13162 for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) { 13163 mi = 0; 13164 desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc; 13165 bmem = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].bmem; 13166 if (bmem == INVALIDm) { 13167 while (desc[mi].mem != INVALIDm) { 13168 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem); 13169 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem); 13170 mi++; 13171 } 13172 continue; 13173 } 13174 pe = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].pipe_enum; 13175 mor_dma = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].mor_dma; 13176 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 13177 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 13178 desc[mi].mem = pe ? SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, bmem, xpe, pipe) : 13179 SOC_MEM_UNIQUE_ACC(unit, bmem)[xpe]; 13180 if (desc[mi].mem == INVALIDm) { 13181 continue; 13182 } 13183 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem); 13184 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem); 13185 if (mor_dma) { 13186 desc[mi].mor_dma = TRUE; 13187 } 13188 mi++; 13189 if (!pe) { 13190 break; 13191 } 13192 } 13193 } 13194 desc[mi].mem = INVALIDm; 13195 } 13196 13197 if (soc_property_get(unit, "pstats_desc_all", 1)) { 13198 /* Use single desc chain */ 13199 soc_trident3_mmu_pstats_tbl_config_all(unit); 13200 } 13201 } 13202 13203 int 13204 soc_trident3_mmu_pstats_mode_set(int unit, uint32 flags) 13205 { 13206 soc_control_t *soc = SOC_CONTROL(unit); 13207 int pf = 0; 13208 uint32 rval = 0; 13209 int rv; 13210 13211 SOC_PSTATS_LOCK(unit); 13212 13213 if (flags & _TD3_MMU_PSTATS_HWM_MOD) { 13214 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 13215 HWM_MODEf, 1); 13216 pf |= _TD3_MMU_PSTATS_HWM_MOD; 13217 if (flags & _TD3_MMU_PSTATS_RESET_ON_READ) { 13218 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 13219 HWM_RESET_ON_READf, 1); 13220 pf |= _TD3_MMU_PSTATS_RESET_ON_READ; 13221 } 13222 } 13223 13224 if (flags & _TD3_MMU_PSTATS_PKT_MOD) { 13225 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 13226 SELECTf, 1); 13227 pf |= _TD3_MMU_PSTATS_PKT_MOD; 13228 if (soc_feature(unit, soc_feature_mor_dma) && 13229 (flags & _TD3_MMU_PSTATS_MOR_EN)) { 13230 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 13231 MOR_ENf, 1); 13232 } 13233 if (flags & _TD3_MMU_PSTATS_MOR_EN) { 13234 pf |= _TD3_MMU_PSTATS_MOR_EN; 13235 } 13236 } 13237 13238 if (flags & _TD3_MMU_PSTATS_ENABLE) { 13239 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 13240 ENABLEf, 1); 13241 pf |= _TD3_MMU_PSTATS_ENABLE; 13242 if (flags & _TD3_MMU_PSTATS_PKT_MOD) { 13243 if ((flags & _TD3_MMU_PSTATS_SYNC) || 13244 (flags & _TD3_MMU_PSTATS_HWM_MOD && 13245 flags & _TD3_MMU_PSTATS_RESET_ON_READ)) { 13246 soc->pstats_mode = PSTATS_MODE_PKT_SYNC; 13247 pf |= _TD3_MMU_PSTATS_SYNC; 13248 } else { 13249 soc->pstats_mode = PSTATS_MODE_PKT_BUFF; 13250 } 13251 } else { 13252 soc->pstats_mode = PSTATS_MODE_OOB; 13253 } 13254 } else { 13255 soc->pstats_mode = PSTATS_MODE_NULL; 13256 } 13257 13258 soc->pstats_flags = pf; 13259 13260 rv = WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval); 13261 13262 SOC_PSTATS_UNLOCK(unit); 13263 13264 return rv; 13265 } 13266 13267 int 13268 soc_trident3_mmu_pstats_mode_get(int unit, uint32 *flags) 13269 { 13270 int pf = 0; 13271 uint32 rval = 0; 13272 int rv; 13273 soc_reg_t reg = MMU_GCFG_PKTSTAT_OOBSTATr; 13274 13275 SOC_PSTATS_LOCK(unit); 13276 13277 rv = READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval); 13278 if (SOC_FAILURE(rv)) { 13279 SOC_PSTATS_UNLOCK(unit); 13280 return rv; 13281 } 13282 13283 if (soc_reg_field_get(unit, reg, rval, ENABLEf)) { 13284 pf |= _TD3_MMU_PSTATS_ENABLE; 13285 if (soc_reg_field_get(unit, reg, rval, SELECTf)) { 13286 pf |= _TD3_MMU_PSTATS_PKT_MOD; 13287 } 13288 } 13289 if (soc_reg_field_get(unit, reg, rval, HWM_MODEf)) { 13290 pf |= _TD3_MMU_PSTATS_HWM_MOD; 13291 if (soc_reg_field_get(unit, reg, rval, HWM_RESET_ON_READf)) { 13292 pf |= _TD3_MMU_PSTATS_RESET_ON_READ; 13293 } 13294 } 13295 13296 SOC_PSTATS_UNLOCK(unit); 13297 13298 *flags = pf; 13299 13300 return SOC_E_NONE; 13301 } 13302 13303 int 13304 soc_trident3_mmu_pstats_mor_enable(int unit) 13305 { 13306 soc_control_t *soc = SOC_CONTROL(unit); 13307 uint32 rval; 13308 13309 13310 if (soc->pstats_flags & _TD3_MMU_PSTATS_MOR_EN) { 13311 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval)); 13312 if ( ! soc_reg_field_get(unit, 13313 MMU_GCFG_PKTSTAT_OOBSTATr, rval, MOR_ENf)) { 13314 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 1); 13315 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval)); 13316 } 13317 } 13318 13319 return SOC_E_NONE; 13320 } 13321 13322 int 13323 soc_trident3_mmu_pstats_mor_disable(int unit) 13324 { 13325 soc_control_t *soc = SOC_CONTROL(unit); 13326 uint32 rval; 13327 13328 if (!soc_feature(unit, soc_feature_mor_dma) && 13329 (soc->pstats_flags & _TD3_MMU_PSTATS_MOR_EN)) { 13330 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval)); 13331 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 0); 13332 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval)); 13333 } 13334 13335 return SOC_E_NONE; 13336 } 13337 13338 int 13339 soc_trident3_mmu_splitter_reset(int unit) 13340 { 13341 uint32 rval; 13342 13343 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_SPLITTERr(unit, &rval)); 13344 soc_reg_field_set(unit, MMU_GCFG_SPLITTERr, &rval, RESET_SBUSf, 1); 13345 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_SPLITTERr(unit, rval)); 13346 13347 return SOC_E_NONE; 13348 } 13349 /* 13350 * Function: 13351 * soc_td3_port_schedule_tdm_init 13352 * Purpose: 13353 * Initialize TDM information in port_schedule_state that will be passed 13354 * to DV FlexPort API 13355 * Parameters: 13356 * unit - (IN) Unit number. 13357 * port_schedule_state - (OUT) Port resource state. 13358 * Returns: 13359 * BCM_E_xxx 13360 * Notes: 13361 * If called during Scheduler Initialization, only below values need to be 13362 * properly set: 13363 * soc_tdm_schedule_pipe_t::num_slices 13364 * soc_tdm_schedule_t:: cal_len 13365 * soc_tdm_schedule_t:: num_ovs_groups 13366 * soc_tdm_schedule_t:: ovs_group_len 13367 * soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space 13368 * soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len 13369 */ 13370 int 13371 soc_td3_port_schedule_tdm_init(int unit, 13372 soc_port_schedule_state_t *port_schedule_state) 13373 { 13374 soc_control_t *soc = SOC_CONTROL(unit); 13375 _soc_trident3_tdm_temp_t *tdm = soc->tdm_info; 13376 /*soc_info_t *si = &SOC_INFO(unit);*/ 13377 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 13378 soc_tdm_schedule_t *sched; 13379 int pipe, hpipe, phy_port, is_flexport, group, slot; 13380 int *port_p2PBLK_inst_mapping; 13381 13382 if (tdm == NULL) { 13383 return SOC_E_INIT; 13384 } 13385 13386 is_flexport = port_schedule_state->is_flexport; 13387 /* 13388 port_schedule_state->calendar_type = si->fabric_port_enable ? 13389 _TD3_TDM_CALENDAR_UNIVERSAL : 13390 _TD3_TDM_CALENDAR_ETHERNET_OPTIMIZED; 13391 */ 13392 /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */ 13393 for (pipe = 0; pipe < TRIDENT3_TDM_PIPES_PER_DEV; pipe++) { 13394 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 13395 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 13396 13397 tdm_ischd->num_slices = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; 13398 tdm_eschd->num_slices = TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; 13399 13400 if (is_flexport) { 13401 /* TDM Calendar is always in slice 0 */ 13402 sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 13403 tdm->tdm_pipe[pipe].idb_tdm, 13404 sizeof(int)*_TD3_TDM_LENGTH); 13405 sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 13406 tdm->tdm_pipe[pipe].mmu_tdm, 13407 sizeof(int)*_TD3_TDM_LENGTH); 13408 } 13409 13410 /* OVS */ 13411 for (hpipe = 0; hpipe < TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 13412 /* IDB OVERSUB*/ 13413 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 13414 sched->cal_len = _TD3_TDM_LENGTH; 13415 sched->num_ovs_groups = TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; 13416 sched->ovs_group_len = TRIDENT3_TDM_OVS_GROUP_LENGTH; 13417 sched->num_pkt_sch_or_ovs_space = 1; 13418 sched->pkt_sch_or_ovs_space_len = _TD3_PKT_SCH_LENGTH; 13419 13420 if (is_flexport) { 13421 for (group = 0; group < TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; group++) { 13422 for (slot = 0; slot < TRIDENT3_TDM_OVS_GROUP_LENGTH; slot++) { 13423 sched->oversub_schedule[group][slot] = 13424 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 13425 } 13426 } 13427 for (slot = 0; slot < _TD3_PKT_SCH_LENGTH; slot++) { 13428 sched->pkt_sch_or_ovs_space[0][slot] = 13429 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 13430 } 13431 } 13432 13433 /* MMU OVERSUB */ 13434 sched = &tdm_eschd->tdm_schedule_slice[hpipe]; 13435 sched->cal_len = _TD3_TDM_LENGTH; 13436 sched->num_ovs_groups = TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; 13437 sched->ovs_group_len = TRIDENT3_TDM_OVS_GROUP_LENGTH; 13438 sched->num_pkt_sch_or_ovs_space = 1; 13439 sched->pkt_sch_or_ovs_space_len = _TD3_PKT_SCH_LENGTH; 13440 13441 if (is_flexport) { 13442 for (group = 0; group < TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; group++) { 13443 for (slot = 0; slot < TRIDENT3_TDM_OVS_GROUP_LENGTH; slot++) { 13444 sched->oversub_schedule[group][slot] = 13445 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 13446 } 13447 } 13448 for (slot = 0; slot < _TD3_PKT_SCH_LENGTH; slot++) { 13449 sched->pkt_sch_or_ovs_space[0][slot] = 13450 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 13451 } 13452 } 13453 } 13454 } 13455 13456 if (is_flexport) { 13457 port_p2PBLK_inst_mapping = 13458 port_schedule_state->in_port_map.port_p2PBLK_inst_mapping; 13459 /* pblk info for phy_port */ 13460 for (phy_port = 1; phy_port < TD3_NUM_EXT_PORTS; phy_port++) { 13461 if (tdm->pblk_info[phy_port].pblk_cal_idx == -1) { 13462 continue; 13463 } 13464 port_p2PBLK_inst_mapping[phy_port] = 13465 tdm->pblk_info[phy_port].pblk_cal_idx; 13466 } 13467 } 13468 return SOC_E_NONE; 13469 } 13470 13471 /* 13472 * Function: 13473 * soc_td3_soc_tdm_update 13474 * Purpose: 13475 * Update TDM information in SOC with TDM state return from DV FlexPort API 13476 * Parameters: 13477 * unit - (IN) Unit number. 13478 * port_schedule_state - (OUT) Port resource state. 13479 * Returns: 13480 * BCM_E_xxx 13481 * Notes: 13482 */ 13483 int 13484 soc_td3_soc_tdm_update(int unit, 13485 soc_port_schedule_state_t *port_schedule_state) 13486 { 13487 soc_control_t *soc = SOC_CONTROL(unit); 13488 soc_info_t *si = &SOC_INFO(unit); 13489 _soc_trident3_tdm_temp_t *tdm = soc->tdm_info; 13490 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 13491 soc_tdm_schedule_t *sched; 13492 int pipe, hpipe, port, phy_port, clport, slot; 13493 int length, ovs_core_slot_count, ovs_io_slot_count, port_slot_count; 13494 int index, group; 13495 13496 if (tdm == NULL) { 13497 return SOC_E_INIT; 13498 } 13499 13500 /* Copy info from soc_port_schedule_state_t to _soc_trident3_tdm_temp_t */ 13501 for (pipe = 0; pipe < TRIDENT3_TDM_PIPES_PER_DEV; pipe++) { 13502 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 13503 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 13504 13505 /* TDM Calendar is always in slice 0 */ 13506 sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm, 13507 tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 13508 sizeof(int)*_TD3_TDM_LENGTH); 13509 sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm, 13510 tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 13511 sizeof(int)*_TD3_TDM_LENGTH); 13512 13513 for (hpipe = 0; hpipe < TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 13514 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 13515 for (group = 0; group < TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; group++) { 13516 for (slot = 0; slot < TRIDENT3_TDM_OVS_GROUP_LENGTH; slot++) { 13517 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot] = 13518 sched->oversub_schedule[group][slot]; 13519 } 13520 } 13521 for (slot = 0; slot < _TD3_PKT_SCH_LENGTH; slot++) { 13522 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot] = 13523 sched->pkt_sch_or_ovs_space[0][slot]; 13524 13525 } 13526 } 13527 } 13528 13529 /* pblk info init */ 13530 for (phy_port = 1; phy_port < TD3_NUM_EXT_PORTS; phy_port++) { 13531 tdm->pblk_info[phy_port].pblk_cal_idx = -1; 13532 tdm->pblk_info[phy_port].pblk_hpipe_num = -1; 13533 } 13534 13535 /* pblk info for phy_port */ 13536 for (pipe = 0; pipe < TRIDENT3_TDM_PIPES_PER_DEV; pipe++) { 13537 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 13538 for (hpipe = 0; hpipe < TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 13539 for (group = 0; group < TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; group++) { 13540 for (index = 0; index < TRIDENT3_TDM_OVS_GROUP_LENGTH; index++) { 13541 phy_port = 13542 tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 13543 if (phy_port < TD3_NUM_EXT_PORTS) { 13544 tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe; 13545 tdm->pblk_info[phy_port].pblk_cal_idx = 13546 port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port]; 13547 } 13548 } 13549 } 13550 } 13551 } 13552 13553 /* CLPORT port ratio */ 13554 for (clport = 0; clport < TRIDENT3_TDM_PBLKS_PER_DEV; clport++) { 13555 soc_td3_tdm_get_port_ratio(unit, port_schedule_state, clport, 13556 &tdm->port_ratio[clport], 1); 13557 } 13558 13559 /* Calculate the oversub ratio */ 13560 for (pipe = 0; pipe < TRIDENT3_TDM_PIPES_PER_DEV; pipe++) { 13561 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 13562 /* Count number of OVSB_TOKEN assigned by the TDM code */ 13563 for (length = _TD3_TDM_LENGTH; length > 0; length--) { 13564 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[length - 1] 13565 != TD3_NUM_EXT_PORTS) { 13566 break; 13567 } 13568 } 13569 ovs_core_slot_count = 0; 13570 for (index = 0; index < length; index++) { 13571 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[index] 13572 == TD3_OVSB_TOKEN) { 13573 ovs_core_slot_count++; 13574 } 13575 } 13576 13577 /* Count number of slot needed for half-pipe's oversub I/O bandwidth */ 13578 for (hpipe = 0; hpipe < TRIDENT3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 13579 ovs_io_slot_count = 0; 13580 for (group = 0; group < TRIDENT3_TDM_OVS_GROUPS_PER_HPIPE; group++) { 13581 for (index = 0; index < TRIDENT3_TDM_OVS_GROUP_LENGTH; index++) { 13582 phy_port = tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 13583 if (phy_port == TD3_NUM_EXT_PORTS) { 13584 continue; 13585 } 13586 port = si->port_p2l_mapping[phy_port]; 13587 13588 if ((port == -1) || IS_CPU_PORT(unit, port) || 13589 IS_LB_PORT(unit, port) || 13590 (phy_port ==TRIDENT3_TDM_PHY_MGMT0)) { 13591 LOG_ERROR(BSL_LS_SOC_PORT, 13592 (BSL_META_U(unit, 13593 "Flexport: Invalid physical " 13594 "port %d in OverSub table.\n"), 13595 phy_port)); 13596 continue; 13597 } 13598 port_slot_count = si->port_speed_max[port] / 2500; 13599 ovs_io_slot_count += port_slot_count; 13600 } 13601 } 13602 if (ovs_core_slot_count != 0) { 13603 tdm->ovs_ratio_x1000[pipe][hpipe] = 13604 ovs_io_slot_count * 1000 / (ovs_core_slot_count / 2); 13605 } 13606 } 13607 } 13608 13609 return SOC_E_NONE; 13610 } 13611 13612 STATIC int 13613 _soc_trident3_mmu_port_empty_check(int unit, soc_port_t port, int *empty) 13614 { 13615 soc_reg_t status_reg[2] = {Q_SCHED_PORT_EMPTY_STATUS_SPLIT0r, 13616 Q_SCHED_PORT_EMPTY_STATUS_SPLIT1r}; 13617 soc_reg_t reg; 13618 int pipe, split, pos; 13619 uint64 rval64; 13620 13621 SOC_IF_ERROR_RETURN( 13622 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos)); 13623 reg = status_reg[split]; 13624 13625 COMPILER_64_ZERO(rval64); 13626 SOC_IF_ERROR_RETURN 13627 (soc_reg_get(unit, reg, pipe, 0, &rval64)); 13628 13629 if (pos < 32) { 13630 *empty = COMPILER_64_LO(rval64) & (1 << pos) ? TRUE : FALSE; 13631 } else { 13632 *empty = COMPILER_64_HI(rval64) & (1 << (pos - 32)) ? 13633 TRUE : FALSE; 13634 } 13635 13636 return SOC_E_NONE; 13637 } 13638 13639 int 13640 soc_trident3_mmu_port_flush_hw(int unit, soc_port_t port, uint32 drain_timeout) 13641 { 13642 uint64 rval64; 13643 uint64 pbits64, mtro64; 13644 uint32 rval; 13645 int pipe, split; 13646 int empty, pos; 13647 soc_timeout_t to; 13648 soc_reg_t flush_reg, mtro_reg; 13649 soc_field_t initiate_val; 13650 soc_reg_t reg_flush[2] = {Q_SCHED_PORT_FLUSH_SPLIT0r, 13651 Q_SCHED_PORT_FLUSH_SPLIT1r}; 13652 soc_reg_t reg_mtro[2] = {MTRO_PORT_ENTITY_DISABLE_SPLIT0r, 13653 MTRO_PORT_ENTITY_DISABLE_SPLIT1r}; 13654 13655 COMPILER_64_ZERO(rval64); 13656 COMPILER_64_ZERO(pbits64); 13657 13658 SOC_IF_ERROR_RETURN( 13659 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos)); 13660 flush_reg = reg_flush[split]; 13661 mtro_reg = reg_mtro[split]; 13662 13663 if (pos < 32) { 13664 COMPILER_64_SET(pbits64, 0, (1 << pos)); 13665 } else { 13666 COMPILER_64_SET(pbits64, (1 << (pos - 32)), 0); 13667 } 13668 13669 SOC_IF_ERROR_RETURN 13670 (_soc_trident3_mmu_port_empty_check(unit, port, &empty)); 13671 if (empty) { 13672 return SOC_E_NONE; 13673 } 13674 13675 /* Read the Port flush Register */ 13676 SOC_IF_ERROR_RETURN 13677 (soc_reg_get(unit, flush_reg, pipe, 0, &rval64)); 13678 13679 COMPILER_64_OR(rval64, pbits64); 13680 13681 /* Port Not Empty - Initiate Flush */ 13682 /* ENABLEf is the only field in FLUSH reg. Hence writing it directly */ 13683 SOC_IF_ERROR_RETURN 13684 (soc_reg_set(unit, flush_reg, pipe, 0, rval64)); 13685 13686 /* Disable Shaper Updates */ 13687 SOC_IF_ERROR_RETURN 13688 (soc_reg_get(unit, mtro_reg, pipe, 0, &rval64)); 13689 COMPILER_64_COPY(mtro64, rval64); 13690 COMPILER_64_AND(mtro64, pbits64); 13691 13692 COMPILER_64_OR(rval64, pbits64); 13693 13694 /* METERING_DISABLEf is the only field in reg. Hence writing it directly */ 13695 SOC_IF_ERROR_RETURN 13696 (soc_reg_set(unit, mtro_reg, pipe, 0, rval64)); 13697 13698 /* Initiate RQE FIFO Flush */ 13699 SOC_IF_ERROR_RETURN 13700 (soc_reg32_get(unit, Q_SCHED_RQE_SNAPSHOTr, pipe, 0, &rval)); 13701 initiate_val = 0x1; 13702 soc_reg_field_set(unit, Q_SCHED_RQE_SNAPSHOTr, &rval, 13703 INITIATEf, initiate_val); 13704 SOC_IF_ERROR_RETURN 13705 (soc_reg32_set(unit, Q_SCHED_RQE_SNAPSHOTr, pipe, 0, rval)); 13706 13707 /* Restart timeout */ 13708 initiate_val = 0x1; 13709 empty = 0; 13710 soc_timeout_init(&to, drain_timeout, 0); 13711 for (;;) { 13712 if (initiate_val != 0) { 13713 SOC_IF_ERROR_RETURN 13714 (soc_reg32_get(unit, Q_SCHED_RQE_SNAPSHOTr, pipe, 0, &rval)); 13715 initiate_val = soc_reg_field_get(unit, Q_SCHED_RQE_SNAPSHOTr, 13716 rval, INITIATEf); 13717 } else { /* Completion of Snapshot Process */ 13718 SOC_IF_ERROR_RETURN 13719 (_soc_trident3_mmu_port_empty_check(unit, port, &empty)); 13720 if (empty) { 13721 break; 13722 } 13723 } 13724 13725 if (soc_timeout_check(&to)) { 13726 SOC_IF_ERROR_RETURN 13727 (soc_reg32_get(unit, Q_SCHED_RQE_SNAPSHOTr, pipe, 0, &rval)); 13728 initiate_val = soc_reg_field_get(unit, Q_SCHED_RQE_SNAPSHOTr, 13729 rval, INITIATEf); 13730 if (initiate_val == 0) { 13731 /* Completion of Snapshot Process */ 13732 SOC_IF_ERROR_RETURN 13733 (_soc_trident3_mmu_port_empty_check(unit, port, &empty)); 13734 } 13735 break; 13736 } 13737 } 13738 13739 COMPILER_64_NOT(pbits64); 13740 /* Restore Shaper Updates */ 13741 SOC_IF_ERROR_RETURN 13742 (soc_reg_get(unit, mtro_reg, pipe, 0, &rval64)); 13743 COMPILER_64_AND(rval64, pbits64); 13744 COMPILER_64_OR(rval64, mtro64); 13745 /* METERING_DISABLEf is the only field in reg. Hence writing it directly */ 13746 SOC_IF_ERROR_RETURN 13747 (soc_reg_set(unit, mtro_reg, pipe, 0, rval64)); 13748 13749 /* Read the Port flush Register */ 13750 SOC_IF_ERROR_RETURN 13751 (soc_reg_get(unit, flush_reg, pipe, 0, &rval64)); 13752 COMPILER_64_AND(rval64, pbits64); 13753 /* Port Empty - Disable Flush */ 13754 /* ENABLEf is the only field in FLUSH reg. Hence writing it directly */ 13755 SOC_IF_ERROR_RETURN 13756 (soc_reg_set(unit, flush_reg, pipe, 0, rval64)); 13757 13758 if ((initiate_val == 0) && (empty)) { 13759 LOG_VERBOSE(BSL_LS_SOC_COMMON, 13760 (BSL_META_U(unit, 13761 "MacDrain:port %d,%s, " 13762 "Drained successfully\n"), 13763 unit, SOC_PORT_NAME(unit, port))); 13764 } else { 13765 LOG_ERROR(BSL_LS_SOC_COMMON, 13766 (BSL_META_U(unit, 13767 "MacDrainError:port %d,%s, " 13768 "Unable to drain packets from MMU\n"), 13769 unit, SOC_PORT_NAME(unit, port))); 13770 return SOC_E_INTERNAL; 13771 } 13772 return SOC_E_NONE; 13773 } 13774 13775 soc_error_t 13776 soc_td3_subsidiary_ports_get(int unit, soc_port_t port, soc_pbmp_t *pbmp) 13777 { 13778 soc_info_t *si = &SOC_INFO(unit); 13779 soc_port_t phy_port_base, phy_port; 13780 soc_pbmp_t pbm; 13781 int max_subport; 13782 13783 if (!SOC_PORT_VALID(unit, port) || IS_CPU_PORT(unit, port) || 13784 IS_LB_PORT(unit, port) || 13785 SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port)) { 13786 /* CPU, LB and Management ports do not support flexport */ 13787 return SOC_E_PORT; 13788 } 13789 13790 phy_port = si->port_l2p_mapping[port]; 13791 if (-1 == phy_port) { 13792 return SOC_E_PORT; 13793 } 13794 phy_port_base = PORT_BLOCK_BASE_PORT(port); 13795 13796 /* Only lane 0 and lane 2 of a PM can be controlling ports */ 13797 if ((phy_port_base != phy_port) && ((phy_port_base + 2) != phy_port)) { 13798 /* Not a controlling port */ 13799 return SOC_E_PORT; 13800 } 13801 max_subport = phy_port + (4 - ((phy_port - 1) % 4)); 13802 SOC_PBMP_CLEAR(pbm); 13803 for (; phy_port < max_subport; phy_port++) { 13804 if (si->port_p2l_mapping[phy_port] == -1) { 13805 continue; 13806 } 13807 SOC_PBMP_PORT_ADD(pbm, si->port_p2l_mapping[phy_port]); 13808 } 13809 SOC_PBMP_ASSIGN(*pbmp, pbm); 13810 13811 return SOC_E_NONE; 13812 } 13813 13814 int 13815 soc_td3_mpls_hash_control_set(int *hash_entry) 13816 { 13817 int unit = 0; 13818 int mpls_16k_banks = 0,mpls_8k_banks = 0; 13819 int uat_16k_banks = 0,uat_8k_banks = 0; 13820 int index = 0; 13821 int num_entries = 0, shared_hash_offset = 0; 13822 int hash_control_entry[2]; 13823 uint32 shared_hash_control_entry[4]; 13824 uint32 shared_8k_hash_control_entry[4]; 13825 13826 static const soc_field_t logical_to_physical_fields[] = { 13827 LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf, 13828 LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf, 13829 LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf, 13830 LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf, 13831 LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf, 13832 LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf, 13833 LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf, 13834 LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf, 13835 LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf, 13836 LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf 13837 }; 13838 13839 static const soc_field_t shared_fields[] = { 13840 B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf, 13841 B4_HASH_OFFSETf, B5_HASH_OFFSETf, B6_HASH_OFFSETf, B7_HASH_OFFSETf 13842 }; 13843 13844 sal_memset(hash_control_entry, 0, 13845 sizeof(mpls_entry_hash_control_entry_t)); 13846 sal_memset(shared_hash_control_entry, 0, 13847 sizeof(uft_shared_banks_control_entry_t)); 13848 sal_memset(shared_8k_hash_control_entry, 0, 13849 sizeof(ip_uat_8k_shared_banks_control_entry_t)); 13850 13851 SOC_IF_ERROR_RETURN 13852 (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 13853 shared_hash_control_entry)); 13854 SOC_IF_ERROR_RETURN 13855 (READ_IP_UAT_8K_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 13856 shared_8k_hash_control_entry)); 13857 SOC_IF_ERROR_RETURN 13858 (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 13859 hash_control_entry)); 13860 sal_memcpy(hash_entry, hash_control_entry, sizeof(hash_control_entry)); 13861 13862 num_entries = soc_mem_index_count(unit, MPLS_ENTRY_SINGLEm); 13863 SOC_IF_ERROR_RETURN(soc_trident3_iuat_sizing(unit, num_entries, 13864 &uat_16k_banks, &uat_8k_banks)); 13865 mpls_16k_banks = uat_16k_banks; 13866 mpls_8k_banks = uat_8k_banks; 13867 13868 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 13869 HASH_TABLE_BANK_CONFIGf, (((1 << mpls_8k_banks) - 1) | 13870 (((1 << mpls_16k_banks) - 1) << 4))); 13871 13872 for(index = 0; index < mpls_8k_banks; index++) { 13873 shared_hash_offset = (index == (mpls_8k_banks-1))? 13874 TD3_UAT_8K_HASH_OFFSET_MAX : 13875 ((index * TD3_UAT_8K_HASH_OFFSET_MAX) / (mpls_8k_banks-1)); 13876 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 13877 logical_to_physical_fields[index], index); 13878 soc_mem_field32_set(unit, IP_UAT_8K_SHARED_BANKS_CONTROLm, 13879 shared_8k_hash_control_entry, shared_fields[index], 13880 shared_hash_offset); 13881 } 13882 13883 for(index = 0; index < mpls_16k_banks; index++) { 13884 shared_hash_offset = (index == (mpls_16k_banks-1))? 13885 TD3_UAT_16K_HASH_OFFSET_MAX : 13886 ((index * TD3_UAT_16K_HASH_OFFSET_MAX) / (mpls_16k_banks-1)); 13887 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, 13888 hash_control_entry, 13889 logical_to_physical_fields[index], index + 4); 13890 soc_mem_field32_set(unit, IP_UAT_16K_SHARED_BANKS_CONTROLm, 13891 shared_hash_control_entry, shared_fields[index], 13892 shared_hash_offset); 13893 } 13894 13895 SOC_IF_ERROR_RETURN 13896 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 13897 hash_control_entry)); 13898 13899 return SOC_E_NONE; 13900 } 13901 void soc_td3_hgoe_feature_update(int unit) { 13902 if (!soc_feature(unit, soc_feature_higig_over_ethernet)) { 13903 return; 13904 } 13905 /* if HGOE is enabled, disable the following features */ 13906 /* L3 */ 13907 SOC_FEATURE_CLEAR(unit, soc_feature_l3); 13908 SOC_FEATURE_CLEAR(unit, soc_feature_l3_ip6); 13909 SOC_FEATURE_CLEAR(unit, soc_feature_l3_entry_key_type); 13910 SOC_FEATURE_CLEAR(unit, soc_feature_lpm_tcam); 13911 SOC_FEATURE_CLEAR(unit, soc_feature_ip_mcast); 13912 SOC_FEATURE_CLEAR(unit, soc_feature_ip_mcast_repl); 13913 SOC_FEATURE_CLEAR(unit, soc_feature_ipmc_unicast); 13914 SOC_FEATURE_CLEAR(unit, soc_feature_ipmc_use_configured_dest_mac); 13915 SOC_FEATURE_CLEAR(unit, soc_feature_urpf); 13916 SOC_FEATURE_CLEAR(unit, soc_feature_l3mc_use_egress_next_hop); 13917 SOC_FEATURE_CLEAR(unit, soc_feature_l3_sgv); 13918 SOC_FEATURE_CLEAR(unit, soc_feature_l3_dynamic_ecmp_group); 13919 SOC_FEATURE_CLEAR(unit, soc_feature_l3_ingress_interface); 13920 SOC_FEATURE_CLEAR(unit, soc_feature_l3_iif_zero_invalid); 13921 SOC_FEATURE_CLEAR(unit, soc_feature_l3_iif_under_4k); 13922 SOC_FEATURE_CLEAR(unit, soc_feature_ecmp_dlb); 13923 SOC_FEATURE_CLEAR(unit, soc_feature_ecmp_dlb_optimized); 13924 SOC_FEATURE_CLEAR(unit, soc_feature_ecmp_dlb_property_force_set); 13925 SOC_FEATURE_CLEAR(unit, soc_feature_l3_iif_profile); 13926 SOC_FEATURE_CLEAR(unit, soc_feature_l3_ingress_interface); 13927 SOC_FEATURE_CLEAR(unit, soc_feature_nat); 13928 SOC_FEATURE_CLEAR(unit, soc_feature_l2gre); 13929 SOC_FEATURE_CLEAR(unit, soc_feature_l2gre_default_tunnel); 13930 SOC_FEATURE_CLEAR(unit, soc_feature_l3_lookup_cmd); 13931 SOC_FEATURE_CLEAR(unit, soc_feature_l3_shared_defip_table); 13932 SOC_FEATURE_CLEAR(unit, soc_feature_l3_ip4_options_profile); 13933 SOC_FEATURE_CLEAR(unit, soc_feature_repl_l3_intf_use_next_hop); 13934 SOC_FEATURE_CLEAR(unit, soc_feature_l3_extended_host_entry); 13935 SOC_FEATURE_CLEAR(unit, soc_feature_l3_ecmp_1k_groups); 13936 SOC_FEATURE_CLEAR(unit, soc_feature_l3_defip_map); 13937 SOC_FEATURE_CLEAR(unit, soc_feature_l3_host_ecmp_group); 13938 SOC_FEATURE_CLEAR(unit, soc_feature_niv); 13939 SOC_FEATURE_CLEAR(unit, soc_feature_vlan_vp); 13940 SOC_FEATURE_CLEAR(unit, soc_feature_vp_lag); 13941 SOC_FEATURE_CLEAR(unit, soc_feature_virtual_switching); 13942 SOC_FEATURE_SET(unit, soc_feature_int_common_init); 13943 SOC_FEATURE_CLEAR(unit, soc_feature_mim); 13944 13945 /* ALPM */ 13946 SOC_FEATURE_CLEAR(unit, soc_feature_alpm); 13947 SOC_FEATURE_CLEAR(unit, soc_feature_alpm2); 13948 13949 /* MPLS */ 13950 13951 SOC_FEATURE_CLEAR(unit, soc_feature_mpls); 13952 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_enhanced); 13953 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_entropy); 13954 SOC_FEATURE_CLEAR(unit, soc_feature_td2p_mpls_entropy_label); 13955 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_lsr_ecmp); 13956 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_segment_routing); 13957 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_failover); 13958 SOC_FEATURE_CLEAR(unit, soc_feature_flex_ctr_mpls_3_label_count); 13959 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_exp_to_phb_cng_map); 13960 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_software_failover); 13961 SOC_FEATURE_CLEAR(unit, soc_feature_mpls_frr); 13962 13963 /* VXLAN */ 13964 SOC_FEATURE_CLEAR(unit, soc_feature_vxlan); 13965 SOC_FEATURE_CLEAR(unit, soc_feature_vrf_aware_vxlan_termination); 13966 13967 /* TRILL */ 13968 SOC_FEATURE_CLEAR(unit, soc_feature_trill); 13969 SOC_FEATURE_CLEAR(unit, soc_feature_fcoe); 13970 13971 } 13972 13973 /* 13974 * Enable flow based UDF extraction. 13975 * Few containers are disabled by default for certain flows. 13976 * This routine enables UDF extraction for various protocols 13977 */ 13978 13979 int 13980 soc_td3_flow_based_udf_enable(int unit) 13981 { 13982 13983 uint32 rval = 0; 13984 13985 if (!soc_feature(unit, soc_feature_enable_flow_based_udf_extraction)) { 13986 return SOC_E_NONE; 13987 } 13988 13989 13990 SOC_IF_ERROR_RETURN(READ_EGR_FLEX_CONFIGr(unit, &rval)); 13991 soc_reg_field_set(unit, EGR_FLEX_CONFIGr, &rval, 13992 ENABLE_FLEX_MIM_ISID_EXTRACTIONf, 1); 13993 SOC_IF_ERROR_RETURN(WRITE_EGR_FLEX_CONFIGr(unit, rval)); 13994 13995 rval = 0; 13996 SOC_IF_ERROR_RETURN(READ_ING_FLEX_CONFIGr(unit, &rval)); 13997 soc_reg_field_set(unit, ING_FLEX_CONFIGr, &rval, 13998 ENABLE_BFD_VER_EXTRACTIONf, 1); 13999 soc_reg_field_set(unit, ING_FLEX_CONFIGr, &rval, 14000 ENABLE_IPSEC_SPI_EXTRACTIONf, 1); 14001 soc_reg_field_set(unit, ING_FLEX_CONFIGr, &rval, 14002 ENABLE_IPV4_FLAGS_FRAG_OFFSET_EXTRACTIONf, 1); 14003 soc_reg_field_set(unit, ING_FLEX_CONFIGr, &rval, 14004 ENABLE_LLC_HDR_EXTRACTIONf, 1); 14005 soc_reg_field_set(unit, ING_FLEX_CONFIGr, &rval, 14006 GPE_IOAM_ENABLEf, 1); 14007 SOC_IF_ERROR_RETURN(WRITE_ING_FLEX_CONFIGr(unit, rval)); 14008 14009 return SOC_E_NONE; 14010 } 14011 14012 /* 14013 * Trident3 chip driver functions. 14014 * Pls keep at the end of this file for easy access. 14015 */ 14016 soc_functions_t soc_trident3_drv_funs = { 14017 _soc_trident3_misc_init, 14018 _soc_trident3_mmu_init, 14019 soc_trident3_age_timer_get, 14020 soc_trident3_age_timer_max_get, 14021 soc_trident3_age_timer_set, 14022 soc_trident3_tscx_firmware_set, 14023 _soc_trident3_tscx_reg_read, 14024 _soc_trident3_tscx_reg_write, 14025 soc_trident3_bond_info_init, 14026 }; 14027 #endif /* BCM_TOMAHAWK_SUPPORT */