helix5.c (284316B)
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: helix5.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 #ifdef BCM_CMICX_SUPPORT 20 #include <soc/cmicx.h> 21 #endif 22 23 #include <soc/bradley.h> 24 #include <soc/drv.h> 25 #include <soc/error.h> 26 #include <soc/debug.h> 27 #include <soc/mem.h> 28 #include <soc/i2c.h> 29 #include <soc/l2x.h> 30 31 #ifdef BCM_HELIX5_SUPPORT 32 33 #include <soc/mmu_config.h> 34 #include <soc/helix5.h> 35 #include <soc/helix5_tdm.h> 36 #include <soc/tomahawk.h> 37 #include <soc/esw/cancun.h> 38 #include <soc/soc_ser_log.h> 39 #include <soc/pstats.h> 40 #include <soc/flexport/helix5/helix5_flexport.h> 41 #include <soc/esw/portctrl.h> 42 #include <soc/scache.h> 43 #include <soc/bondoptions.h> 44 #include <shared/pack.h> 45 46 #define HX5_NUM_PHY_PORT (79) 47 #define HX5_NUM_PORT (72) 48 #define HX5_NUM_MMU_PORT (72) 49 50 #define ETHER_MODE 0 51 #define Q_MODE 1 52 53 #define PMQ0_FIRST_PHY_PORT 1 54 55 #define HX5_PORT_BLOCK_BASE_PORT(port) \ 56 SOC_INFO(unit).port_l2p_mapping[port] <= 48 ? \ 57 (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0xF)) :\ 58 (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0x3)); 59 60 #define IS_MGMT_PORT(unit,port) IS_MANAGEMENT_PORT(unit, port) 61 62 63 int 64 _soc_hx5_port_speed_cap[SOC_MAX_NUM_DEVICES][HELIX5_PHY_PORTS_PER_DEV]; 65 66 static const struct { 67 int port; 68 int phy_port; 69 int pipe; 70 int idb_port; 71 int mmu_port; 72 } hx5_anc_ports[] = { 73 { 0, 0, 0, 70, 70 }, /* cpu port */ 74 { 70, 77, 0, 71, 71 }, /* loopback port */ 75 { 71, 78, 0, 69, 69 }, /* FAE port */ 76 }; 77 78 static const soc_reg_t pvtmon_result_reg[] = { 79 TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r, 80 TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r, 81 TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r, 82 TOP_PVTMON_RESULT_6r 83 }; 84 85 extern int soc_td3_hash_mutex_init (int unit); 86 87 egr_vlan_xlate_1_hash_control_entry_t egr_vlan_1_hash_control; 88 egr_vlan_xlate_2_hash_control_entry_t egr_vlan_2_hash_control; 89 egr_vp_vlan_membership_hash_control_entry_t egr_vp_vlan_mbm_hash_control; 90 exact_match_hash_control_entry_t exact_match_hash_control; 91 ing_vp_vlan_membership_hash_control_entry_t ing_vp_vlan_mbm_hash_control; 92 l2_entry_hash_control_entry_t l2_entry_hash_control; 93 l3_entry_hash_control_entry_t l3_entry_hash_control; 94 mpls_entry_hash_control_entry_t mpls_entry_hash_control; 95 vlan_xlate_1_hash_control_entry_t vlan_1_hash_control; 96 vlan_xlate_2_hash_control_entry_t vlan_2_hash_control; 97 uft_shared_banks_control_entry_t uft_shared_banks_control; 98 ip_uat_shared_banks_control_entry_t ip_uat_shared_banks_control; 99 ep_uat_shared_banks_control_entry_t ep_uat_shared_banks_control; 100 ft_key_ss0_shared_banks_control_entry_t ft_key_ss0_shared_banks_control; 101 ft_key_ss1_shared_banks_control_entry_t ft_key_ss1_shared_banks_control; 102 103 /* 104 * Function: 105 * soc_helix5_mem_config 106 * Purpose: 107 * Configure depth of UFT/UAT memories 108 * Parameters: 109 * unit (IN) - switch unit 110 * Returns: 111 * SOC_E_* 112 */ 113 int 114 soc_helix5_mem_config(int unit) 115 { 116 soc_persist_t *sop; 117 int l2_entries, fixed_l2_entries, shared_l2_banks; 118 int num_ipv6_128b_entries = 0; 119 int config_v6_entries = 0; 120 int defip_config = 0; 121 #define _SOC_HX5_DEFIP_MAX_TCAMS 8 122 #define _SOC_HX5_DEFIP_TCAM_DEPTH 1024 /* HX5 has 8 tcams of 1K deep depth */ 123 int l3_entries, fixed_l3_entries, shared_l3_banks; 124 int fpem_entries, shared_fpem_banks; 125 int mpls_entries, vlan_xlate_1_entries, vlan_xlate_2_entries; 126 int alpm_enable = 0; 127 int mpls_4k_banks; 128 int vlan_xlate_1_4k_banks; 129 int vlan_xlate_2_4k_banks; 130 int egr_vlan_xlate_1_entries, egr_vlan_xlate_2_entries; 131 int egr_vlan_xlate_1_banks, egr_vlan_xlate_2_banks; 132 int num_lag_rh_flowset_entries; 133 134 sop = SOC_PERSIST(unit); 135 136 /* UFT BANK SIZING 137 * 138 * bank 0-1 are dedicated L2 banks (8k entries per bank) 139 * bank 8-9 are dedicated L3 banks (8k entries per bank) 140 * bank 2-7 are shared banks (16k L2/L3 or 8k FPEM entries 141 * or 24k ALPM entries per bank) 142 */ 143 144 l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, 16 * 1024); 145 fixed_l2_entries = 16 * 1024; /* 16k dedicated L2 entries, (8k * 2 banks) */ 146 if (l2_entries <= fixed_l2_entries) { 147 l2_entries = fixed_l2_entries; 148 shared_l2_banks = 0; 149 } else { 150 l2_entries -= fixed_l2_entries; 151 shared_l2_banks = (l2_entries + (16 * 1024 - 1)) / (16 * 1024); 152 l2_entries = fixed_l2_entries + shared_l2_banks * 16 * 1024; 153 } 154 155 l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, 16 * 1024); 156 fixed_l3_entries = 16 * 1024; /* 16k dedicated L3 entries, (8k * 2 banks) */ 157 if (l3_entries <= fixed_l3_entries) { 158 l3_entries = fixed_l3_entries; 159 shared_l3_banks = 0; 160 } else { 161 l3_entries -= fixed_l3_entries; 162 shared_l3_banks = (l3_entries + (16 * 1024 - 1)) / (16 * 1024); 163 l3_entries = fixed_l3_entries + shared_l3_banks * 16 * 1024; 164 } 165 166 fpem_entries = soc_property_get(unit, spn_FPEM_MEM_ENTRIES, 0); 167 shared_fpem_banks = (fpem_entries + (8 * 1024 - 1)) / (8 * 1024); 168 /* Allocate atleast 2 banks to FP for dual hash benefits */ 169 if(shared_fpem_banks == 1) { 170 if ((shared_l2_banks + shared_l3_banks) > 6) { 171 LOG_ERROR(BSL_LS_SOC_COMMON, 172 (BSL_META_U(unit, 173 "Config Error - Atleast two shared UFT" 174 "banks should be allocated to FPEM. \n"))); 175 return SOC_E_PARAM; 176 } 177 shared_fpem_banks = 2; 178 } 179 fpem_entries = shared_fpem_banks * 8 * 1024; 180 181 if (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 6) { 182 return SOC_E_PARAM; 183 } 184 185 if (soc_feature(unit, soc_feature_alpm)) { 186 alpm_enable = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0); 187 } 188 189 /* ALPM needs either 4 banks or 6 banks depending on ALPM bank mode. 190 * If more than 2 banks are already allocated to non ALPM tables (L2, L3, 191 * FPEM), then ALPM needs cannot be satisfied */ 192 if ((alpm_enable) && 193 (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 2)) { 194 return SOC_E_PARAM; 195 } 196 197 _soc_alpm_mode[unit] = alpm_enable; 198 199 /* IUAT BANK SIZING 200 * 201 * Banks 0-7 are shared banks of size 4k per bank 202 */ 203 204 mpls_entries = soc_property_get(unit, spn_MPLS_MEM_ENTRIES, 8192); 205 mpls_4k_banks = (mpls_entries + (4 * 1024 -1)) / 4096; 206 mpls_entries = mpls_4k_banks * 4 * 1024; 207 208 vlan_xlate_1_entries = soc_property_get(unit, spn_VLAN_XLATE_1_MEM_ENTRIES, 8192); 209 vlan_xlate_1_4k_banks = (vlan_xlate_1_entries + (4 * 1024 -1)) / 4096; 210 vlan_xlate_1_entries = vlan_xlate_1_4k_banks * 4 * 1024; 211 212 vlan_xlate_2_entries = soc_property_get(unit, spn_VLAN_XLATE_2_MEM_ENTRIES, 8192); 213 vlan_xlate_2_4k_banks = (vlan_xlate_2_entries + (4 * 1024 -1)) / 4096; 214 vlan_xlate_2_entries = vlan_xlate_2_4k_banks * 4 * 1024; 215 216 if (mpls_4k_banks + vlan_xlate_1_4k_banks + vlan_xlate_2_4k_banks > 8) { 217 return SOC_E_PARAM; 218 } 219 220 /* EUAT BANK SIZING 221 * 222 * Banks 0-3 are shared banks of size 4k per bank 223 */ 224 225 egr_vlan_xlate_1_entries = soc_property_get(unit, spn_EGR_VLAN_XLATE_1_MEM_ENTRIES, 8192); 226 egr_vlan_xlate_1_banks = (egr_vlan_xlate_1_entries + (4 * 1024 - 1)) / 4096; 227 egr_vlan_xlate_1_entries = egr_vlan_xlate_1_banks * 4 * 1024; 228 229 egr_vlan_xlate_2_entries = soc_property_get(unit, spn_EGR_VLAN_XLATE_2_MEM_ENTRIES, 8192); 230 egr_vlan_xlate_2_banks = (egr_vlan_xlate_2_entries + (4 * 1024 - 1)) / 4096; 231 egr_vlan_xlate_2_entries = egr_vlan_xlate_2_banks * 4 * 1024; 232 233 if (egr_vlan_xlate_1_banks + egr_vlan_xlate_2_banks > 4) { 234 return SOC_E_PARAM; 235 } 236 237 /* LP memory sizing per 8k entries 238 * Memory Bank with 1W,2W,4W support - 3.5k entries 239 * Memory Bank with 1W,2W support - 3k entries 240 * Memory Bank with 1W support - 2k entries 241 */ 242 243 /* Adjust L2 table size */ 244 sop->memState[L2Xm].index_max = l2_entries - 1; 245 sop->memState[L2_ENTRY_SINGLEm].index_max = l2_entries - 1; 246 sop->memState[L2_ENTRY_ONLY_SINGLEm].index_max = l2_entries - 1; 247 sop->memState[L2_ENTRY_ECCm].index_max = l2_entries - 1; 248 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1; 249 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1; 250 /* 2k per dedicated L2 bank, 7k per shared L2 bank */ 251 sop->memState[L2_ENTRY_LPm].index_max = ((2 * 2 * 1024) + 252 (shared_l2_banks * 7 * 1024) - 1); 253 254 /* Adjust L3 table size */ 255 sop->memState[L3_ENTRY_SINGLEm].index_max = l3_entries - 1; 256 sop->memState[L3_ENTRY_ONLY_SINGLEm].index_max = l3_entries - 1; 257 sop->memState[L3_ENTRY_ECCm].index_max = l3_entries - 1; 258 sop->memState[L3_ENTRY_DOUBLEm].index_max = l3_entries / 2 - 1; 259 sop->memState[L3_ENTRY_ONLY_DOUBLEm].index_max = l3_entries / 2 - 1; 260 sop->memState[L3_ENTRY_QUADm].index_max = l3_entries / 4 - 1; 261 sop->memState[L3_ENTRY_ONLY_QUADm].index_max = l3_entries / 4 - 1; 262 sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1; 263 /* 3.5k per dedicated L3 bank, 7k per shared L2 bank */ 264 sop->memState[L3_ENTRY_LPm].index_max = ((7 * 1024) + 265 (shared_l3_banks * 7 * 1024) - 1); 266 267 /* Adjust FP exact match table size */ 268 sop->memState[EXACT_MATCH_ECCm].index_max = fpem_entries * 2 - 1; 269 sop->memState[EXACT_MATCH_ECC_PIPE0m].index_max = fpem_entries * 2 - 1; 270 sop->memState[EXACT_MATCH_2m].index_max = fpem_entries - 1; 271 sop->memState[EXACT_MATCH_2_PIPE0m].index_max = fpem_entries - 1; 272 sop->memState[EXACT_MATCH_2_ENTRY_ONLYm].index_max = fpem_entries - 1; 273 sop->memState[EXACT_MATCH_2_ENTRY_ONLY_PIPE0m].index_max = fpem_entries - 1; 274 sop->memState[EXACT_MATCH_4m].index_max = fpem_entries / 2 - 1; 275 sop->memState[EXACT_MATCH_4_PIPE0m].index_max = fpem_entries / 2 - 1; 276 sop->memState[EXACT_MATCH_4_ENTRY_ONLYm].index_max = fpem_entries / 2 - 1; 277 sop->memState[EXACT_MATCH_4_ENTRY_ONLY_PIPE0m].index_max = fpem_entries / 2 - 1; 278 sop->memState[EXACT_MATCH_HIT_ONLYm].index_max = fpem_entries / 2 - 1; 279 /* 7k per shared FPEM bank */ 280 sop->memState[EXACT_MATCH_LPm].index_max = ((shared_fpem_banks * 7 * 1024) - 1); 281 sop->memState[EXACT_MATCH_LP_PIPE0m].index_max = ((shared_fpem_banks * 7 * 1024) - 1); 282 283 /* Adjust MPLS table size */ 284 sop->memState[MPLS_ENTRY_SINGLEm].index_max = mpls_entries - 1; 285 sop->memState[MPLS_ENTRYm].index_max = mpls_entries / 2 - 1; 286 /* 1.5k per IUAT bank */ 287 sop->memState[MPLS_ENTRY_LPm].index_max = (((mpls_4k_banks * 1536) - 1)); 288 sop->memState[MPLS_ENTRY_ECCm].index_max = mpls_entries - 1; 289 290 /* Adjust VLAN_XLATE_1 table size */ 291 sop->memState[VLAN_XLATE_1_SINGLEm].index_max = vlan_xlate_1_entries - 1; 292 sop->memState[VLAN_XLATE_1_DOUBLEm].index_max = vlan_xlate_1_entries / 2 - 1; 293 /* 1.5k per IUAT bank */ 294 sop->memState[VLAN_XLATE_1_LPm].index_max = (vlan_xlate_1_4k_banks * 1536) - 1; 295 sop->memState[VLAN_XLATE_1_ECCm].index_max = vlan_xlate_1_entries - 1; 296 297 /* Adjust VLAN_XLATE_2 table size */ 298 sop->memState[VLAN_XLATE_2_SINGLEm].index_max = vlan_xlate_2_entries - 1; 299 sop->memState[VLAN_XLATE_2_DOUBLEm].index_max = vlan_xlate_2_entries / 2 - 1; 300 /* 1.5k per IUAT bank */ 301 sop->memState[VLAN_XLATE_2_LPm].index_max = (vlan_xlate_2_4k_banks * 1536) - 1; 302 sop->memState[VLAN_XLATE_2_ECCm].index_max = vlan_xlate_2_entries - 1; 303 304 /* Adjust EGR_VLAN_XLATE_1 table size */ 305 sop->memState[EGR_VLAN_XLATE_1_SINGLEm].index_max = egr_vlan_xlate_1_entries - 1; 306 sop->memState[EGR_VLAN_XLATE_1_DOUBLEm].index_max = egr_vlan_xlate_1_entries / 2 - 1; 307 /* 1.5k per EUAT bank */ 308 sop->memState[EGR_VLAN_XLATE_1_LPm].index_max = (egr_vlan_xlate_1_banks * 1536) - 1; 309 sop->memState[EGR_VLAN_XLATE_1_ECCm].index_max = egr_vlan_xlate_1_entries - 1; 310 311 /* Adjust EGR_VLAN_XLATE_2 table size */ 312 sop->memState[EGR_VLAN_XLATE_2_SINGLEm].index_max = egr_vlan_xlate_2_entries - 1; 313 sop->memState[EGR_VLAN_XLATE_2_DOUBLEm].index_max = egr_vlan_xlate_2_entries / 2 - 1; 314 /* 1.5k per EUAT bank */ 315 sop->memState[EGR_VLAN_XLATE_2_LPm].index_max = (egr_vlan_xlate_2_banks * 1536) - 1; 316 sop->memState[EGR_VLAN_XLATE_2_ECCm].index_max = egr_vlan_xlate_2_entries - 1; 317 318 SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_HX5_DEFIP_MAX_TCAMS; 319 SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_HX5_DEFIP_TCAM_DEPTH; 320 if (soc_property_get(unit, "l3_defip_sizing", TRUE)) { 321 if (!alpm_enable) { 322 defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1); 323 324 num_ipv6_128b_entries = soc_property_get(unit, 325 spn_NUM_IPV6_LPM_128B_ENTRIES, 326 (defip_config ? 2048 : 0)); 327 num_ipv6_128b_entries = num_ipv6_128b_entries + 328 (num_ipv6_128b_entries % 2); 329 330 config_v6_entries = num_ipv6_128b_entries; 331 if (soc_property_get(unit, spn_LPM_SCALING_ENABLE, 0)) { 332 num_ipv6_128b_entries = 0; 333 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED, 1)) { 334 config_v6_entries = ((config_v6_entries / 335 SOC_CONTROL(unit)->l3_defip_tcam_size) + 336 ((config_v6_entries % 337 SOC_CONTROL(unit)->l3_defip_tcam_size) 338 ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size; 339 } 340 } 341 sop->memState[L3_DEFIP_PAIR_128m].index_max = 342 num_ipv6_128b_entries - 1; 343 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 344 num_ipv6_128b_entries - 1; 345 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 346 num_ipv6_128b_entries - 1; 347 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 348 num_ipv6_128b_entries - 1; 349 sop->memState[L3_DEFIPm].index_max = 350 (SOC_CONTROL(unit)->l3_defip_max_tcams * 351 SOC_CONTROL(unit)->l3_defip_tcam_size) - 352 (num_ipv6_128b_entries * 2) - 1; 353 354 sop->memState[L3_DEFIP_ONLYm].index_max = 355 sop->memState[L3_DEFIPm].index_max; 356 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 357 sop->memState[L3_DEFIPm].index_max; 358 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 359 sop->memState[L3_DEFIPm].index_max; 360 SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries; 361 } else { 362 if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) { 363 /* slightly different processing for v6-128 */ 364 num_ipv6_128b_entries = soc_property_get(unit, 365 spn_NUM_IPV6_LPM_128B_ENTRIES, 366 2048); 367 num_ipv6_128b_entries = num_ipv6_128b_entries + 368 (num_ipv6_128b_entries % 2); 369 config_v6_entries = num_ipv6_128b_entries; 370 sop->memState[L3_DEFIP_PAIR_128m].index_max = 371 num_ipv6_128b_entries - 1; 372 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 373 num_ipv6_128b_entries - 1; 374 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 375 num_ipv6_128b_entries - 1; 376 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 377 num_ipv6_128b_entries - 1; 378 sop->memState[L3_DEFIPm].index_max = 379 (SOC_CONTROL(unit)->l3_defip_max_tcams * 380 SOC_CONTROL(unit)->l3_defip_tcam_size) - 381 (num_ipv6_128b_entries * 2) - 1; 382 sop->memState[L3_DEFIP_ONLYm].index_max = 383 sop->memState[L3_DEFIPm].index_max; 384 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 385 sop->memState[L3_DEFIPm].index_max; 386 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 387 sop->memState[L3_DEFIPm].index_max; 388 389 SOC_CONTROL(unit)->l3_defip_index_remap = 390 (num_ipv6_128b_entries / 2) * 2; 391 } else { 392 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1; 393 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1; 394 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1; 395 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1; 396 } 397 } 398 soc_l3_defip_indexes_init(unit, config_v6_entries); 399 } 400 401 /* Adjust ALPM table size */ 402 if (alpm_enable) { 403 /* The check below is sufficient because if ALPM mode is enabled 404 * and number of shared banks used is > 2 we return SOC_E_PARAM 405 * in code at the top of this function. 406 */ 407 if (shared_l2_banks + shared_l3_banks + shared_fpem_banks > 0) { 408 sop->memState[L3_DEFIP_ALPM_RAWm].index_max = 409 (sop->memState[L3_DEFIP_ALPM_RAWm].index_max * 4) / 6; 410 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = 411 (sop->memState[L3_DEFIP_ALPM_IPV4m].index_max * 4) / 6; 412 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = 413 (sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max * 4) / 6; 414 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = 415 (sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max * 4) / 6; 416 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = 417 (sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max * 4) / 6; 418 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = 419 (sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max * 4) / 6; 420 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = 421 (sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max * 4) / 6; 422 sop->memState[L3_DEFIP_ALPM_ECCm].index_max = 423 (sop->memState[L3_DEFIP_ALPM_ECCm].index_max * 4) / 6; 424 } 425 } else { 426 sop->memState[L3_DEFIP_ALPM_RAWm].index_max = -1; 427 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = -1; 428 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = -1; 429 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = -1; 430 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = -1; 431 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = -1; 432 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = -1; 433 sop->memState[L3_DEFIP_ALPM_ECCm].index_max = -1; 434 } 435 436 /* Adjust MY_STATION_TCAM table in Emulator */ 437 if (SAL_BOOT_QUICKTURN) { 438 sop->memState[MY_STATION_TCAMm].index_max = 31; 439 sop->memState[MY_STATION_TCAM_2m].index_max = 440 sop->memState[MY_STATION_TCAMm].index_max; 441 sop->memState[MY_STATION_TCAM_2_DATA_ONLYm].index_max = 442 sop->memState[MY_STATION_TCAMm].index_max; 443 sop->memState[MY_STATION_TCAM_2_ENTRY_ONLYm].index_max = 444 sop->memState[MY_STATION_TCAMm].index_max; 445 sop->memState[MY_STATION_TCAM_DATA_ONLYm].index_max = 446 sop->memState[MY_STATION_TCAMm].index_max; 447 sop->memState[MY_STATION_TCAM_ENTRY_ONLYm].index_max = 448 sop->memState[MY_STATION_TCAMm].index_max; 449 } 450 451 SOC_IF_ERROR_RETURN(soc_trident3_init_alpm2_memory(unit)); 452 453 /* Enhanced hashing LAG/TRUNK config 454 * LAG/TRUNK share the same flow set table used in RH 455 * 32k is shared between LAG and HGT for 456 * - 16k each - default 457 * - 32K dedicated to HGT RH 458 * - 32K dedicated to LAG RH 459 */ 460 num_lag_rh_flowset_entries = soc_property_get(unit, 461 spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 16384); 462 463 switch (num_lag_rh_flowset_entries) { 464 case 0: 465 sop->memState[RH_LAG_FLOWSETm].index_max = -1; 466 break; 467 case 32768: 468 sop->memState[RH_HGT_FLOWSETm].index_max = -1; 469 break; 470 case 16384: 471 sop->memState[RH_HGT_FLOWSETm].index_max = 16383; 472 sop->memState[RH_LAG_FLOWSETm].index_max = 16383; 473 break; 474 default: 475 return SOC_E_CONFIG; 476 } 477 478 /* Adjust the Flow-tracker session table size based on the 479 supported size, these features would have been set based 480 on the OTP values */ 481 if (soc_feature(unit, soc_feature_flowtracker_ver_1_8K_ft_table)) { 482 /* 3 banks x 4k */ 483 sop->memState[FT_KEY_SINGLEm].index_max = 12287; 484 sop->memState[FT_KEY_DOUBLEm].index_max = 6143; 485 sop->memState[FT_KEY_DOUBLE_PIPE0m].index_max = 6143; 486 sop->memState[FT_KEY_ECCm].index_max = 12287; 487 } else if (soc_feature(unit, soc_feature_flowtracker_ver_1_16K_ft_table)) { 488 /* 5 banks x 4k */ 489 sop->memState[FT_KEY_SINGLEm].index_max = 20479; 490 sop->memState[FT_KEY_DOUBLEm].index_max = 10239; 491 sop->memState[FT_KEY_DOUBLE_PIPE0m].index_max = 10239; 492 sop->memState[FT_KEY_ECCm].index_max = 20479; 493 } 494 495 return SOC_E_NONE; 496 } 497 498 /* 499 * cpu port (mmu port 70): 48 queues (2570-2617) 500 * loopback port (mmu port 71): 10 queues (2560-2569) 501 */ 502 int 503 soc_helix5_num_cosq_init_port(int unit, int port) 504 { 505 soc_info_t *si; 506 int mmu_port; 507 508 si = &SOC_INFO(unit); 509 510 mmu_port = SOC_TD3_MMU_PORT(unit, port); 511 512 if (IS_CPU_PORT(unit, port)) { 513 si->port_num_cosq[port] = 48; 514 si->port_cosq_base[port] = SOC_HX5_CPU_MCQ_BASE; 515 } else if (IS_LB_PORT(unit, port)) { 516 si->port_num_cosq[port] = 10; 517 si->port_cosq_base[port] = SOC_HX5_LB_MCQ_BASE; 518 } else if (mmu_port < 16) { 519 si->port_num_cosq[port] = 26; 520 si->port_cosq_base[port] = mmu_port * 26; 521 si->port_num_uc_cosq[port] = 26; 522 si->port_uc_cosq_base[port] = mmu_port * 26; 523 si->port_num_ext_cosq[port] = 0; 524 } else { 525 si->port_num_cosq[port] = 16; 526 si->port_cosq_base[port] = SOC_HX5_DOWNLINK_PORTQ_BASE + (mmu_port - 16) * 16; 527 si->port_num_uc_cosq[port] = 16; 528 si->port_uc_cosq_base[port] = SOC_HX5_DOWNLINK_PORTQ_BASE + (mmu_port - 16) * 16; 529 si->port_num_ext_cosq[port] = 0; 530 } 531 532 return SOC_E_NONE; 533 } 534 535 /* 536 * cpu port (mmu port 70): 48 queues (1290-1337) 537 * loopback port (mmu port 71): 10 queues (1280-1289) 538 */ 539 int 540 soc_helix5_num_cosq_init(int unit) 541 { 542 int port; 543 544 PBMP_ALL_ITER(unit, port) { 545 if (!IS_FAE_PORT(unit, port)) { 546 SOC_IF_ERROR_RETURN 547 (soc_helix5_num_cosq_init_port(unit, port)); 548 } 549 } 550 551 return SOC_E_NONE; 552 } 553 554 555 STATIC int 556 soc_helix5_max_frequency_get(int unit, uint16 dev_id, uint8 rev_id, 557 int skew_id, int *frequency) 558 { 559 if (soc_feature(unit, soc_feature_untethered_otp)) { 560 /* Fill from default_frequecy, if soc_property exists from the same, overwrite 561 and also check the default is not greater than the max_frequecy */ 562 *frequency = SOC_BOND_INFO(unit)->default_core_freq; 563 *frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, *frequency); 564 if (*frequency > SOC_BOND_INFO(unit)->max_core_freq) { 565 return SOC_E_PARAM; 566 } 567 } else { 568 switch (dev_id) { 569 case BCM56370_DEVICE_ID: 570 *frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, HX5_CLK_893MHZ); 571 break; 572 default: 573 return SOC_E_INTERNAL; 574 } 575 } 576 577 return SOC_E_NONE; 578 } 579 580 /* Function to get the number of ports present in a given Port Macro */ 581 STATIC int 582 soc_hx5_ports_per_pm_get(int unit, int pm_id) 583 { 584 soc_info_t *si; 585 int phy_port, num_ports = 0, i; 586 587 si = &SOC_INFO(unit); 588 if (pm_id >= _HX5_PBLKS_PER_DEV(unit)) { 589 return SOC_E_PARAM; 590 } 591 phy_port = 1 + (pm_id * _HX5_PORTS_PER_PBLK); 592 593 for (i = 0; i < _HX5_PORTS_PER_PBLK; ) { 594 if (si->port_p2l_mapping[phy_port + i] != -1) { 595 num_ports ++; 596 i += si->port_num_lanes[si->port_p2l_mapping[phy_port + i]]; 597 } else { 598 i ++; 599 } 600 } 601 return num_ports; 602 } 603 604 STATIC int 605 _soc_hx5_port_flex_init(int unit, int is_any_cap) 606 { 607 soc_info_t *si; 608 int pm, blk_idx, blk_type, i; 609 int flex_en, phy_base, max_ports, port, phy_port; 610 int qmode = 0; 611 612 si = &SOC_INFO(unit); 613 SHR_BITCLR_RANGE(si->flexible_pm_bitmap, 0, SOC_MAX_NUM_BLKS); 614 615 /* portmap_x=y:speed:i */ 616 /* portmap_x=y:speed:cap */ 617 if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all)) || is_any_cap) { 618 SHR_BITSET_RANGE(si->flexible_pm_bitmap, 1, SOC_MAX_NUM_BLKS); 619 } else { 620 /* port_flex_enable{x}=<0...1> */ 621 /* port_flex_enable_corex=<0...1> */ 622 /* port_flex_enable=<0...1> */ 623 for (phy_port = 1; phy_port <= HELIX5_GPHY_PORTS_PER_PIPE; phy_port++) { 624 port = si->port_p2l_mapping[phy_port]; 625 if (port == -1) { 626 continue; 627 } 628 soc_helix5_port_qsgmii_mode_get(unit, port, &qmode); 629 if (qmode) { 630 continue; 631 } 632 pm = si->port_serdes[port]; 633 phy_base = HX5_PORT_BLOCK_BASE_PORT(port); 634 /* port_flex_enable_corex=<0...1> */ 635 flex_en = soc_property_suffix_num_get_only_suffix 636 (unit, pm, spn_PORT_FLEX_ENABLE, "core", -1); 637 /* port_flex_enable{x}=<0...1> */ 638 /* port_flex_enable=<0...1> */ 639 if (flex_en == -1) { 640 flex_en = soc_property_phys_port_get 641 (unit, phy_base, spn_PORT_FLEX_ENABLE, 0); 642 } 643 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 644 blk_idx = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 645 if (flex_en && (blk_idx != -1)) { 646 SHR_BITSET(si->flexible_pm_bitmap, blk_idx); 647 } 648 } 649 } 650 } 651 652 si->flex_eligible = 653 (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, SOC_MAX_NUM_BLKS)); 654 655 /* port_flex_max_ports */ 656 memset(&(si->pm_max_ports), 0xff, sizeof(si->pm_max_ports)); 657 for (phy_port = 1; phy_port <= HELIX5_GPHY_PORTS_PER_PIPE; phy_port++) { 658 port = si->port_p2l_mapping[phy_port]; 659 if (port == -1) { 660 continue; 661 } 662 soc_helix5_port_qsgmii_mode_get(unit, port, &qmode); 663 if (qmode) { 664 continue; 665 } 666 pm = si->port_serdes[port]; 667 phy_base = HX5_PORT_BLOCK_BASE_PORT(port); 668 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 669 blk_idx = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 670 if (blk_idx == -1) { 671 continue; 672 } 673 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 674 if (SHR_BITGET(si->flexible_pm_bitmap, blk_idx)) { 675 /* port_flex_max_ports{x}=y */ 676 max_ports = soc_property_phys_port_get(unit, 677 phy_base, spn_PORT_FLEX_MAX_PORTS, -1); 678 /* port_flex_max_ports_corex=y */ 679 if (max_ports == -1) { 680 max_ports = soc_property_suffix_num_get(unit, pm, 681 spn_PORT_FLEX_MAX_PORTS, "core", 16); 682 } 683 /* validation check */ 684 if ((max_ports < 0) || (max_ports > 16) ) { 685 LOG_CLI((BSL_META_U(unit, 686 "Core %d: Bad port_flex_max_ports %d"), 687 pm, max_ports)); 688 return SOC_E_CONFIG; 689 } 690 si->pm_max_ports[blk_idx] = max_ports; 691 } else { 692 si->pm_max_ports[blk_idx] = blk_type == SOC_BLK_GXPORT ? 16 : 4; 693 } 694 } 695 } 696 return SOC_E_NONE; 697 } 698 699 #define PORT_IS_FALCON(unit, phy_port) \ 700 ((phy_port > 64) && (phy_port <= 76)) ? 1 : 0 701 702 STATIC int 703 _soc_hx5_port_lanes_set(int unit, int phy_port, int *lanes, int port_bandwidth) 704 { 705 if (PORT_IS_FALCON(unit, phy_port)) { 706 *lanes = (port_bandwidth > 53000) ? 4 707 : (port_bandwidth > 42000) ? 2 708 : (port_bandwidth > 27000) ? 2 709 : (20000 == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(port_bandwidth)) ? 2 710 : 1; 711 } else { 712 *lanes = (port_bandwidth > 21000) ? 4 713 : (port_bandwidth > 11000) ? 2 714 : 1; 715 } 716 717 if (soc_property_phys_port_get(unit, 1, spn_PORT_GMII_MODE, 0) == 0) { 718 if (phy_port >=5 && phy_port <= 16) { 719 return SOC_E_CONFIG; 720 } 721 } 722 if (soc_property_phys_port_get(unit, 17, spn_PORT_GMII_MODE, 0) == 0) { 723 if (phy_port >= 21 && phy_port <= 32) { 724 return SOC_E_CONFIG; 725 } 726 } 727 if (soc_property_phys_port_get(unit, 33, spn_PORT_GMII_MODE, 0) == 0) { 728 if (phy_port >= 37 && phy_port <= 48) { 729 return SOC_E_CONFIG; 730 } 731 } 732 733 return ((*lanes == -1) ? SOC_E_CONFIG : SOC_E_NONE); 734 } 735 736 int 737 soc_hx5_port_oversub_get(int unit, int phy_port, int logical_port) 738 { 739 soc_pbmp_t pbmp; 740 int oversub_mode = 0, oversub = 0; 741 742 SOC_PBMP_CLEAR(pbmp); 743 744 oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0); 745 746 if (oversub_mode == 0) { 747 oversub = 0; 748 } else if (oversub_mode == 1) { 749 oversub = 1; 750 } else if (oversub_mode == 2) { 751 pbmp = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0); 752 if (SOC_PBMP_MEMBER(pbmp, logical_port)) { 753 oversub = 1; 754 } 755 if (phy_port > 0) { 756 oversub = soc_property_phys_port_get(unit, phy_port, 757 spn_PORT_OVERSUBSCRIBE, oversub); 758 } 759 } 760 return oversub; 761 } 762 763 STATIC void 764 _soc_hx5_mmu_idb_ports_assign(int unit) 765 { 766 int port, phy_port, mmu_port_os, mmu_port_lr; 767 soc_info_t *si; 768 769 si = &SOC_INFO(unit); 770 if (SOC_WARM_BOOT(unit) && (si->flex_eligible) ) { 771 /* Port mappings recovered from Scache */ 772 return; 773 } 774 775 776 mmu_port_os = 0; 777 778 /* PHY Ports: 61-64 779 * MMU/IDB Ports: 0-3 780 */ 781 for (phy_port = 61; phy_port <= 64; phy_port++, mmu_port_os++) { 782 si->port_p2m_mapping[phy_port] = mmu_port_os; 783 si->port_m2p_mapping[mmu_port_os] = phy_port; 784 785 port = si->port_p2l_mapping[phy_port]; 786 if (port == -1) { 787 continue; 788 } 789 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 790 } 791 792 /* PHY Ports: 69-72 793 * MMU/IDB Ports: 4-7 794 */ 795 for (phy_port = 69; phy_port <= 72; phy_port++, mmu_port_os++) { 796 si->port_p2m_mapping[phy_port] = mmu_port_os; 797 si->port_m2p_mapping[mmu_port_os] = phy_port; 798 799 port = si->port_p2l_mapping[phy_port]; 800 if (port == -1) { 801 continue; 802 } 803 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 804 } 805 806 /* PHY Ports: 65-68 807 * MMU/IDB Ports: 8-11 808 */ 809 for (phy_port = 65; phy_port <= 68; phy_port++, mmu_port_os++) { 810 si->port_p2m_mapping[phy_port] = mmu_port_os; 811 si->port_m2p_mapping[mmu_port_os] = phy_port; 812 813 port = si->port_p2l_mapping[phy_port]; 814 if (port == -1) { 815 continue; 816 } 817 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 818 } 819 820 /* PHY Ports: 73-76 821 * MMU/IDB Ports: 12-15 822 */ 823 for (phy_port = 73; phy_port <= 76; phy_port++, mmu_port_os++) { 824 si->port_p2m_mapping[phy_port] = mmu_port_os; 825 si->port_m2p_mapping[mmu_port_os] = phy_port; 826 827 port = si->port_p2l_mapping[phy_port]; 828 if (port == -1) { 829 continue; 830 } 831 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 832 } 833 834 mmu_port_lr = mmu_port_os; 835 836 837 for (phy_port = 1; phy_port <= 4; phy_port++, mmu_port_os++) { 838 si->port_p2m_mapping[phy_port] = mmu_port_os; 839 si->port_m2p_mapping[mmu_port_os] = phy_port; 840 841 port = si->port_p2l_mapping[phy_port]; 842 if (port == -1) { 843 continue; 844 } 845 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 846 } 847 848 /* PHY Ports: 17-20 849 * MMU/IDB Ports: 20-23 850 */ 851 for (phy_port = 17; phy_port <= 20; phy_port++, mmu_port_os++) { 852 si->port_p2m_mapping[phy_port] = mmu_port_os; 853 si->port_m2p_mapping[mmu_port_os] = phy_port; 854 855 port = si->port_p2l_mapping[phy_port]; 856 if (port == -1) { 857 continue; 858 } 859 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 860 } 861 862 /* PHY Ports: 33-36 863 * MMU/IDB Ports: 24-27 864 */ 865 for (phy_port = 33; phy_port <= 36; phy_port++, mmu_port_os++) { 866 si->port_p2m_mapping[phy_port] = mmu_port_os; 867 si->port_m2p_mapping[mmu_port_os] = phy_port; 868 869 port = si->port_p2l_mapping[phy_port]; 870 if (port == -1) { 871 continue; 872 } 873 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 874 } 875 876 /* PHY Ports: 49-60 877 * MMU/IDB Ports: 40-51 878 */ 879 for (phy_port = 49; phy_port <= 60; phy_port++) { 880 si->port_p2m_mapping[phy_port] = phy_port - 9; 881 si->port_m2p_mapping[phy_port - 9] = phy_port; 882 883 port = si->port_p2l_mapping[phy_port]; 884 if (port == -1) { 885 continue; 886 } 887 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 888 } 889 890 /* PHY Ports: 1-60 891 * MMU/IDB Ports within 16-68 892 * 893 * When DL ports are in LR we use a running number 894 * In Line-rate config PM4x10Q can be in GMII mode (upto 16 lanes) 895 */ 896 for (phy_port = 1; phy_port <= 60; phy_port++) { 897 port = si->port_p2l_mapping[phy_port]; 898 if ((port == -1) || IS_OVERSUB_PORT(unit, port)) { 899 continue; 900 } 901 902 si->port_p2m_mapping[phy_port] = mmu_port_lr; 903 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 904 si->port_m2p_mapping[mmu_port_lr] = phy_port; 905 mmu_port_lr++; 906 } 907 908 return; 909 } 910 911 int 912 soc_helix5_port_config_init(int unit, uint16 dev_id) 913 { 914 soc_info_t *si; 915 char *config_str, *sub_str, *sub_str_end; 916 static const char str_2p5[] = "2.5"; 917 char str_buf[8]; 918 int rv; 919 int num_port, num_phy_port, num_mmu_port; 920 int port, phy_port, mmu_port; 921 int pipe, index, bandwidth_cap, is_any_cap = FALSE; 922 int port_bandwidth; 923 char option1, option2; 924 925 si = &SOC_INFO(unit); 926 927 num_phy_port = HX5_NUM_PHY_PORT; 928 num_port = HX5_NUM_PORT; 929 num_mmu_port = HX5_NUM_MMU_PORT; 930 931 soc_helix5_max_frequency_get(unit, dev_id, -1, -1, &si->frequency); 932 933 si->bandwidth = 2048000; 934 935 936 si->oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0); 937 938 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 939 si->port_p2l_mapping[phy_port] = -1; 940 si->port_p2m_mapping[phy_port] = -1; 941 } 942 for (port = 0; port < num_port; port++) { 943 si->port_l2p_mapping[port] = -1; 944 si->port_l2i_mapping[port] = -1; 945 si->port_speed_max[port] = -1; 946 si->port_group[port] = -1; 947 si->port_serdes[port] = -1; 948 si->port_pipe[port] = -1; 949 si->port_num_lanes[port] = -1; 950 } 951 for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) { 952 si->port_m2p_mapping[mmu_port] = -1; 953 } 954 SOC_PBMP_CLEAR(si->eq_pbm); 955 SOC_PBMP_CLEAR(si->management_pbm); 956 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 957 SOC_PBMP_CLEAR(si->pipe_pbm[pipe]); 958 }; 959 SOC_PBMP_CLEAR(si->oversub_pbm); 960 SOC_PBMP_CLEAR(si->all.disabled_bitmap); 961 962 /* Populate the fixed mapped ports */ 963 for (index = 0; index < COUNTOF(hx5_anc_ports); index++) { 964 port = hx5_anc_ports[index].port; 965 phy_port = hx5_anc_ports[index].phy_port; 966 pipe = hx5_anc_ports[index].pipe;; 967 968 si->port_l2p_mapping[port] = phy_port; 969 si->port_l2i_mapping[port] = hx5_anc_ports[index].idb_port; 970 si->port_p2l_mapping[phy_port] = port; 971 si->port_p2m_mapping[phy_port] = hx5_anc_ports[index].mmu_port; 972 si->port_pipe[port] = pipe; 973 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 974 } 975 976 rv = SOC_E_NONE; 977 for (port = 1; port < num_port; port++) { 978 if (si->port_l2p_mapping[port] != -1) { /* fixed mapped port */ 979 continue; 980 } 981 982 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 983 if (config_str == NULL) { 984 continue; 985 } 986 987 /* 988 * portmap_<port>=<physical port number>:<bandwidth in Gb>[:<bandwidth cap in Gb/i(inactive)/1/2/4(num lanes)>][:<i>] 989 * eg: portmap_1=1:100 990 * or portmap_1=1:40 991 * or portmap_1=1:40:i 992 * or portmap_1=1:40:2 993 * or portmap_1=1:40:2:i 994 * or portmap_1=1:10:100 995 */ 996 sub_str = config_str; 997 998 /* Parse physical port number */ 999 phy_port = sal_ctoi(sub_str, &sub_str_end); 1000 if (sub_str == sub_str_end) { 1001 LOG_CLI((BSL_META_U(unit, 1002 "Port %d: Missing physical port information \"%s\"\n"), 1003 port, config_str)); 1004 rv = SOC_E_FAIL; 1005 continue; 1006 } 1007 if (phy_port < 0 || phy_port >= num_phy_port) { 1008 LOG_CLI((BSL_META_U(unit, 1009 "Port %d: Invalid physical port number %d\n"), 1010 port, phy_port)); 1011 rv = SOC_E_FAIL; 1012 continue; 1013 } 1014 if (port > 64) { 1015 LOG_CLI((BSL_META_U(unit, 1016 "Port %d: Invalid logical port number %d\n"), 1017 port, port)); 1018 rv = SOC_E_FAIL; 1019 continue; 1020 } 1021 /* coverity[check_after_sink : FALSE] */ 1022 if (si->port_p2l_mapping[phy_port] != -1) { 1023 LOG_CLI((BSL_META_U(unit, 1024 "Port %d: Physical port %d is used by port %d\n"), 1025 port, phy_port, si->port_p2l_mapping[phy_port])); 1026 rv = SOC_E_FAIL; 1027 continue; 1028 } 1029 1030 /* Skip ':' between physical port number and bandwidth */ 1031 sub_str = sub_str_end; 1032 if (*sub_str != '\0') { 1033 if (*sub_str != ':') { 1034 LOG_CLI((BSL_META_U(unit, 1035 "Port %d: Bad config string \"%s\"\n"), 1036 port, config_str)); 1037 rv = SOC_E_FAIL; 1038 continue; 1039 } 1040 sub_str++; 1041 } 1042 1043 /* Parse bandwidth */ 1044 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 1045 if (sub_str[index] == '\0') { 1046 break; 1047 } 1048 str_buf[index] = sub_str[index]; 1049 } 1050 str_buf[index] = '\0'; 1051 if (!sal_strcmp(str_buf, str_2p5)) { 1052 port_bandwidth = 2500; 1053 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 1054 } else { 1055 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 1056 if (sub_str == sub_str_end) { 1057 LOG_CLI((BSL_META_U(unit, 1058 "Port %d: Missing bandwidth information \"%s\"\n"), 1059 port, config_str)); 1060 rv = SOC_E_FAIL; 1061 continue; 1062 } 1063 switch (port_bandwidth) { 1064 case 1000: 1065 case 5000: 1066 case 10000: 1067 case 11000: 1068 case 20000: 1069 case 21000: 1070 case 25000: 1071 case 27000: 1072 case 40000: 1073 case 42000: 1074 case 50000: 1075 case 53000: 1076 case 100000: 1077 break; 1078 default: 1079 LOG_CLI((BSL_META_U(unit, 1080 "Port %d: Invalid bandwidth %d Gb\n"), 1081 port, port_bandwidth / 1000)); 1082 rv = SOC_E_FAIL; 1083 continue; 1084 } 1085 } 1086 1087 /* Check if option presents */ 1088 option1 = 0; option2 = 0; 1089 sub_str = sub_str_end; 1090 if (*sub_str != '\0') { 1091 /* Skip ':' between bandwidth and options */ 1092 /* Skip ':' between bandwidth and bandwidth cap or options */ 1093 if (*sub_str != ':') { 1094 LOG_CLI((BSL_META_U(unit, 1095 "Port %d: Bad config string \"%s\"\n"), 1096 port, config_str)); 1097 rv = SOC_E_FAIL; 1098 continue; 1099 } 1100 sub_str++; 1101 1102 if (*sub_str != '\0') { 1103 /* Parse bandwidth cap or options */ 1104 bandwidth_cap = sal_ctoi(sub_str, &sub_str_end) * 1000; 1105 switch (bandwidth_cap) { 1106 case 20000: 1107 case 21000: 1108 case 25000: 1109 case 27000: 1110 case 40000: 1111 case 42000: 1112 case 50000: 1113 case 53000: 1114 case 100000: 1115 sub_str = sub_str_end; 1116 _soc_hx5_port_speed_cap[unit][port] = bandwidth_cap; 1117 /* Flex config detected, port speed cap specified */ 1118 is_any_cap = TRUE; 1119 break; 1120 default: 1121 if (!(*sub_str == 'i' || *sub_str == '1' || 1122 *sub_str == 'm' || *sub_str == '2' || 1123 *sub_str == '4')) { 1124 LOG_CLI((BSL_META_U(unit, 1125 "Port %d: Bad config string " 1126 "\"%s\"\n"), 1127 port, config_str)); 1128 rv = SOC_E_FAIL; 1129 continue; 1130 } else { 1131 option1 = *sub_str; 1132 sub_str++; 1133 } 1134 } 1135 1136 /* Check if more options present */ 1137 if (*sub_str != '\0') { 1138 /* Skip ':' between options */ 1139 if (*sub_str != ':') { 1140 LOG_CLI((BSL_META_U(unit, 1141 "Port %d: Bad config string \"%s\"\n"), 1142 port, config_str)); 1143 rv = SOC_E_FAIL; 1144 continue; 1145 } 1146 sub_str++; 1147 1148 if (*sub_str != 'i' && *sub_str != 'm') { 1149 LOG_CLI((BSL_META_U(unit, 1150 "Port %d: Bad config string \"%s\"\n"), 1151 port, config_str)); 1152 rv = SOC_E_FAIL; 1153 continue; 1154 } 1155 option2 = *sub_str; 1156 sub_str++; 1157 } 1158 } 1159 } 1160 1161 /* Check trailing string */ 1162 if (*sub_str != '\0') { 1163 LOG_CLI((BSL_META_U(unit, 1164 "Port %d: Bad config string \"%s\"\n"), 1165 port, config_str)); 1166 rv = SOC_E_FAIL; 1167 continue; 1168 } 1169 1170 /* Update soc_info */ 1171 si->port_l2p_mapping[port] = phy_port; 1172 si->port_p2l_mapping[phy_port] = port; 1173 pipe = 0; 1174 1175 si->port_pipe[port] = pipe; 1176 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 1177 si->port_speed_max[port] = port_bandwidth; 1178 si->port_init_speed[port] = port_bandwidth; 1179 if (option1 == 'i') { 1180 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 1181 si->port_num_lanes[port] = -1; 1182 } else { 1183 uint32 mask; 1184 switch (option1) { 1185 case '1': si->port_num_lanes[port] = 1; break; 1186 case '2': si->port_num_lanes[port] = 2; break; 1187 case '4': si->port_num_lanes[port] = 4; break; 1188 default: 1189 if (SOC_FAILURE(_soc_hx5_port_lanes_set(unit, phy_port, 1190 &si->port_num_lanes[port], 1191 port_bandwidth))) { 1192 rv = SOC_E_FAIL; 1193 } 1194 break; 1195 } 1196 SOC_IF_ERROR_RETURN(soc_hx5_support_speeds(unit, port, &mask)); 1197 if (!(SOC_PA_SPEED(port_bandwidth) & mask)) { 1198 rv = SOC_E_FAIL; 1199 } 1200 } 1201 1202 if (option2 == 'i') { 1203 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 1204 si->port_num_lanes[port] = -1; 1205 } 1206 if (soc_hx5_port_oversub_get(unit, phy_port, port)) { 1207 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 1208 } 1209 if (phy_port <= 48) { 1210 si->port_serdes[port] = (phy_port - 1) / _HX5_PORTS_PER_PMQ_PBLK; 1211 } else { 1212 si->port_serdes[port] = ((phy_port - 1) / _HX5_PORTS_PER_PBLK) - 9; 1213 } 1214 } 1215 1216 1217 /* get flex port properties */ 1218 if (SOC_FAILURE(_soc_hx5_port_flex_init(unit, is_any_cap))) { 1219 rv = SOC_E_FAIL; 1220 } 1221 1222 _soc_hx5_mmu_idb_ports_assign(unit); 1223 #if defined(BCM_WARM_BOOT_SUPPORT) 1224 if (si->flex_eligible) { 1225 if (SOC_WARM_BOOT(unit)) { 1226 SOC_IF_ERROR_RETURN(soc_hx5_flexport_scache_recovery(unit)); 1227 } else { 1228 SOC_IF_ERROR_RETURN(soc_hx5_flexport_scache_allocate(unit)); 1229 } 1230 } 1231 #endif 1232 1233 1234 1235 si->xpe_ipipe_map[0] = 1; 1236 si->xpe_epipe_map[0] = 1; 1237 si->sc_ipipe_map[0] = 1; 1238 si->sc_epipe_map[0] = 1; 1239 si->ipipe_xpe_map[0] = 1; 1240 si->epipe_xpe_map[0] = 1; 1241 si->ipipe_sc_map[0] = 1; 1242 si->epipe_sc_map[0] = 1; 1243 1244 return rv; 1245 } 1246 1247 static uint32 _soc_hx5_temp_mon_mask[SOC_MAX_NUM_DEVICES]; 1248 1249 /* 1250 * Function: 1251 * _soc_hx5_alpm_addr_xlate_set 1252 * Purpose: 1253 * Config addrss translation for ALPM UFT tables 1254 * addr [BITS 17:12] = Entry_Per_Bank * Bank + Entry 1255 * Parameters: 1256 * unit (IN) - switch unit 1257 * mem (IN) - Memory id. 1258 * max_bank_ent (IN) - Max number of entries per bank 1259 * max_bank (IN) - Max number of banks 1260 * Returns: 1261 * SOC_E_* 1262 */ 1263 STATIC int 1264 _soc_hx5_alpm_addr_xlate_set(int unit, soc_mem_t mem, 1265 int max_bank_ent, int max_bank) 1266 { 1267 /* ALPM adressing: 1268 * Bits [11:0] - Bucket number (max 4k buckets) 1269 * Bits [14:12] - Bank id (max 6 banks) 1270 * Bits [17:15] - Entry type (depends on view, max 6) 1271 * Since Bank number is not power of 2, bits [14:12] do not correctly represent Bank id 1272 * In HW this is resolved by introducing address translation tables for each view 1273 * L3_DEFIP_ALPM_IPV4_ADDR_XLATE 1274 * L3_DEFIP_ALPM_IPV4_1_ADDR_XLATE 1275 * L3_DEFIP_ALPM_IPV6_64_ADDR_XLATE 1276 * L3_DEFIP_ALPM_IPV6_64_1_ADDR_XLATE 1277 * L3_DEFIP_ALPM_IPV6_128_ADDR_XLATE 1278 * L3_DEFIP_ALPM_RAW_ADDR_XLATE 1279 * L3_DEFIP_ALPM_ECC_ADDR_XLATE 1280 * Bits [17:12] become lookup index into these tables which tells the Bank id and Entry type 1281 */ 1282 int rv = SOC_E_NONE; 1283 int i = 0; 1284 int idx_min = 0; 1285 int idx_max = 0; 1286 int size = 0; 1287 uint8 *mbuf = NULL; 1288 void *entry_ptr; 1289 1290 idx_min = soc_mem_index_min(unit, mem); 1291 idx_max = max_bank_ent * max_bank - 1; 1292 1293 if (idx_max > soc_mem_index_max(unit, mem)) { 1294 return SOC_E_INTERNAL; 1295 } 1296 1297 size = SOC_MEM_TABLE_BYTES(unit, mem); 1298 mbuf = soc_cm_salloc(unit, size, SOC_MEM_NAME(unit, mem)); 1299 if (NULL == mbuf) { 1300 return SOC_E_MEMORY; 1301 } 1302 1303 /* i = addr [BITS 17:12] = Entry_Per_Bank * BANK_MAP + ENTRY_MAP */ 1304 for (i = idx_min; i <= idx_max; i++) { 1305 1306 entry_ptr = soc_mem_table_idx_to_pointer(unit, mem, 1307 void *, mbuf, i); 1308 sal_memcpy(entry_ptr, soc_mem_entry_null(unit, mem), 1309 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 1310 1311 soc_mem_field32_set(unit, mem, entry_ptr, ENTRY_MAPf, 1312 i / max_bank); 1313 soc_mem_field32_set(unit, mem, entry_ptr, BANK_MAPf, 1314 i % max_bank); 1315 } 1316 1317 rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, 1318 idx_min, idx_max, mbuf); 1319 soc_cm_sfree(unit, mbuf); 1320 1321 return rv; 1322 } 1323 1324 int 1325 soc_helix5_uft_uat_config(int unit) 1326 { 1327 1328 int index, shared_bank_offset = 2; 1329 int num_l2_banks, num_l3_banks, num_fpem_banks = 0; 1330 int dedicated_banks = 2; 1331 int offset_base, offset_multiplier ; 1332 int mpls_4k_banks; 1333 int vlan_xlate_1_4k_banks; 1334 int vlan_xlate_2_4k_banks; 1335 int egr_vlan_xlate_1_banks, egr_vlan_xlate_2_banks; 1336 uint32 hash_control_entry[4], shared_hash_control_entry[4], 1337 shared_4k_hash_control_entry[4]; 1338 static const soc_field_t logical_to_physical_fields[] = { 1339 LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf, 1340 LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf, 1341 LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf, 1342 LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf, 1343 LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf, 1344 LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf, 1345 LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf, 1346 LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf, 1347 LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf, 1348 LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf 1349 }; 1350 static const soc_field_t dedicated_fields[] = { 1351 HASH_OFFSET_DEDICATED_BANK_0f, HASH_OFFSET_DEDICATED_BANK_1f 1352 }; 1353 static const soc_field_t shared_fields[] = { 1354 B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, 1355 B3_HASH_OFFSETf, B4_HASH_OFFSETf, B5_HASH_OFFSETf 1356 }; 1357 /* UFT/UAT control memories programming */ 1358 SOC_IF_ERROR_RETURN 1359 (soc_helix5_hash_bank_count_get(unit, L2Xm, &num_l2_banks)); 1360 SOC_IF_ERROR_RETURN 1361 (soc_helix5_hash_bank_count_get(unit, L3_ENTRY_ONLY_SINGLEm, 1362 &num_l3_banks)); 1363 SOC_IF_ERROR_RETURN 1364 (soc_helix5_hash_bank_count_get(unit, EXACT_MATCH_2m, 1365 &num_fpem_banks)); 1366 SOC_IF_ERROR_RETURN 1367 (soc_helix5_hash_bank_count_get(unit, EGR_VLAN_XLATE_1_SINGLEm, 1368 &egr_vlan_xlate_1_banks)); 1369 SOC_IF_ERROR_RETURN 1370 (soc_helix5_hash_bank_count_get(unit, EGR_VLAN_XLATE_2_SINGLEm, 1371 &egr_vlan_xlate_2_banks)); 1372 SOC_IF_ERROR_RETURN 1373 (soc_helix5_hash_bank_count_get(unit, MPLS_ENTRY_SINGLEm, 1374 &mpls_4k_banks)); 1375 SOC_IF_ERROR_RETURN 1376 (soc_helix5_hash_bank_count_get(unit, VLAN_XLATE_1_SINGLEm, 1377 &vlan_xlate_1_4k_banks)); 1378 SOC_IF_ERROR_RETURN 1379 (soc_helix5_hash_bank_count_get(unit, VLAN_XLATE_2_SINGLEm, 1380 &vlan_xlate_2_4k_banks)); 1381 1382 if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 1383 int non_alpm = num_fpem_banks + num_l3_banks + 1384 num_l2_banks - 2 * (dedicated_banks); 1385 sal_memset(hash_control_entry, 0, 1386 sizeof(uft_shared_banks_control_entry_t)); 1387 SOC_IF_ERROR_RETURN 1388 (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1389 hash_control_entry)); 1390 if ((non_alpm) && (non_alpm <= 2)) { 1391 /* If Shared banks are used between ALPM and non-ALPM memories, 1392 * then ALPM uses Shared Bank B2, B3, B4, B5 and non-ALPM uses 1393 * B6, B7 banks 1394 */ 1395 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1396 hash_control_entry, ALPM_MODEf, 1); 1397 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1398 hash_control_entry, BANK_BYPASS_LPf, 0xf); 1399 SOC_IF_ERROR_RETURN 1400 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 1401 REG_PORT_ANY, ALPM_BANK_MODEf, 1)); 1402 (void)soc_trident3_set_alpm_banks(unit, 4); 1403 shared_bank_offset += 4; 1404 } else { 1405 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1406 hash_control_entry, ALPM_MODEf, 0); 1407 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1408 hash_control_entry, BANK_BYPASS_LPf, 0x3f); 1409 SOC_IF_ERROR_RETURN 1410 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 1411 REG_PORT_ANY, ALPM_BANK_MODEf, 0)); 1412 (void)soc_trident3_set_alpm_banks(unit, 6); 1413 } 1414 SOC_IF_ERROR_RETURN 1415 (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1416 hash_control_entry)); 1417 /* Addrss translation for ALPM UFT tables */ 1418 if (soc_feature(unit, soc_feature_alpm_addr_xlate)) { 1419 int max_bank_ent[] = {6, 4, 4, 3, 2, 1, 4}; 1420 soc_mem_t alpm_mem[] = {L3_DEFIP_ALPM_IPV4_ADDR_XLATEm, 1421 L3_DEFIP_ALPM_IPV4_1_ADDR_XLATEm, 1422 L3_DEFIP_ALPM_IPV6_64_ADDR_XLATEm, 1423 L3_DEFIP_ALPM_IPV6_64_1_ADDR_XLATEm, 1424 L3_DEFIP_ALPM_IPV6_128_ADDR_XLATEm, 1425 L3_DEFIP_ALPM_RAW_ADDR_XLATEm, 1426 L3_DEFIP_ALPM_ECC_ADDR_XLATEm}; 1427 1428 for (index = 0; index < 7; index++) { 1429 SOC_IF_ERROR_RETURN( 1430 _soc_hx5_alpm_addr_xlate_set(unit, alpm_mem[index], 1431 max_bank_ent[index], 1432 soc_trident3_get_alpm_banks(unit))); 1433 } 1434 } 1435 } 1436 1437 sal_memset(shared_hash_control_entry, 0, 1438 sizeof(uft_shared_banks_control_entry_t)); 1439 SOC_IF_ERROR_RETURN 1440 (READ_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1441 shared_hash_control_entry)); 1442 sal_memset(hash_control_entry, 0, sizeof(l2_entry_hash_control_entry_t)); 1443 SOC_IF_ERROR_RETURN 1444 (READ_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, hash_control_entry)); 1445 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , hash_control_entry, 1446 HASH_TABLE_BANK_CONFIGf, (((1 << dedicated_banks) - 1) 1447 | (((1 << (num_l2_banks - dedicated_banks)) - 1) << 1448 shared_bank_offset))); 1449 for (index = dedicated_banks ; index < num_l2_banks ; index++) { 1450 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm , hash_control_entry, 1451 logical_to_physical_fields[index], 1452 index + shared_bank_offset - dedicated_banks); 1453 } 1454 1455 offset_multiplier = 64 / num_l2_banks; 1456 offset_base = 64 % num_l2_banks; 1457 1458 for (index = 0; index < dedicated_banks; index++) { 1459 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm, hash_control_entry, 1460 dedicated_fields[index], offset_base + (index * 1461 offset_multiplier)); 1462 } 1463 1464 for (index = dedicated_banks; index < num_l2_banks; index++) { 1465 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1466 shared_hash_control_entry, shared_fields[index - 1467 dedicated_banks], offset_base + 1468 (index * offset_multiplier)); 1469 } 1470 1471 SOC_IF_ERROR_RETURN 1472 (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, hash_control_entry)); 1473 1474 sal_memset(hash_control_entry, 0, sizeof(exact_match_hash_control_entry_t)); 1475 SOC_IF_ERROR_RETURN 1476 (READ_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1477 hash_control_entry)); 1478 shared_bank_offset += (num_l2_banks - dedicated_banks) ; 1479 1480 /* Handle case where fpem banks are set to 0 */ 1481 if (num_fpem_banks) { 1482 offset_multiplier = 64 / num_fpem_banks; 1483 offset_base = 64 % num_fpem_banks; 1484 } 1485 1486 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm, hash_control_entry, 1487 HASH_TABLE_BANK_CONFIGf, 1488 ((1 << num_fpem_banks) - 1) << shared_bank_offset); 1489 for (index = 0 ; index < num_fpem_banks; index++) { 1490 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm , hash_control_entry, 1491 logical_to_physical_fields[index], index + 1492 shared_bank_offset); 1493 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1494 shared_hash_control_entry, 1495 shared_fields[shared_bank_offset + index - 1496 dedicated_banks], 1497 offset_base + (index * offset_multiplier)); 1498 } 1499 1500 SOC_IF_ERROR_RETURN 1501 (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1502 hash_control_entry)); 1503 1504 sal_memset(hash_control_entry, 0, sizeof(l3_entry_hash_control_entry_t)); 1505 SOC_IF_ERROR_RETURN 1506 (READ_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1507 hash_control_entry)); 1508 shared_bank_offset += num_fpem_banks; 1509 offset_multiplier = 64 / num_l3_banks; 1510 offset_base = 64 % num_l3_banks; 1511 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry, 1512 HASH_TABLE_BANK_CONFIGf, ((((1 << (num_l3_banks - 1513 dedicated_banks)) - 1) << shared_bank_offset) | 1514 (((1 << dedicated_banks) - 1) << 8))); 1515 1516 for (index = 0; index < dedicated_banks; index++) { 1517 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry, 1518 dedicated_fields[index], offset_base + (index * 1519 offset_multiplier)); 1520 } 1521 1522 for (index = dedicated_banks ; index < num_l3_banks ; index++) { 1523 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, hash_control_entry, 1524 logical_to_physical_fields[index], 1525 index + shared_bank_offset - dedicated_banks); 1526 soc_mem_field32_set(unit, UFT_SHARED_BANKS_CONTROLm, 1527 shared_hash_control_entry, 1528 shared_fields[shared_bank_offset + index - 1529 (dedicated_banks * 2)], 1530 offset_base + (index * offset_multiplier)); 1531 } 1532 SOC_IF_ERROR_RETURN 1533 (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1534 hash_control_entry)); 1535 SOC_IF_ERROR_RETURN 1536 (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1537 shared_hash_control_entry)); 1538 1539 sal_memset(shared_hash_control_entry, 0, 1540 sizeof(ep_uat_shared_banks_control_entry_t)); 1541 sal_memset(hash_control_entry, 0, 1542 sizeof(egr_vlan_xlate_1_hash_control_entry_t)); 1543 1544 if (egr_vlan_xlate_1_banks) { 1545 offset_base = 64 % egr_vlan_xlate_1_banks; 1546 offset_multiplier = 64 / egr_vlan_xlate_1_banks; 1547 } 1548 1549 SOC_IF_ERROR_RETURN 1550 (READ_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1551 shared_hash_control_entry)); 1552 SOC_IF_ERROR_RETURN 1553 (READ_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1554 hash_control_entry)); 1555 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 1556 hash_control_entry, HASH_TABLE_BANK_CONFIGf, 1557 ((1 << egr_vlan_xlate_1_banks) - 1)) ; 1558 1559 for(index = 0; index < egr_vlan_xlate_1_banks; index++) { 1560 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 1561 hash_control_entry, 1562 logical_to_physical_fields[index], 1563 index); 1564 soc_mem_field32_set(unit, EP_UAT_SHARED_BANKS_CONTROLm, 1565 shared_hash_control_entry, shared_fields[index], 1566 offset_base + (index * offset_multiplier)); 1567 } 1568 SOC_IF_ERROR_RETURN 1569 (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1570 hash_control_entry)); 1571 1572 sal_memset(hash_control_entry, 0, 1573 sizeof(egr_vlan_xlate_2_hash_control_entry_t)); 1574 1575 if (egr_vlan_xlate_2_banks) { 1576 offset_base = 64 % egr_vlan_xlate_2_banks; 1577 offset_multiplier = 64 / egr_vlan_xlate_2_banks; 1578 } 1579 1580 SOC_IF_ERROR_RETURN 1581 (READ_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1582 hash_control_entry)); 1583 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry, 1584 HASH_TABLE_BANK_CONFIGf, 1585 ((1 << egr_vlan_xlate_2_banks) - 1) << 1586 egr_vlan_xlate_1_banks) ; 1587 1588 for(index = 0; index < egr_vlan_xlate_2_banks; index++) { 1589 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, 1590 hash_control_entry, 1591 logical_to_physical_fields[index], 1592 index + egr_vlan_xlate_1_banks); 1593 soc_mem_field32_set(unit, EP_UAT_SHARED_BANKS_CONTROLm, 1594 shared_hash_control_entry, shared_fields[index + 1595 egr_vlan_xlate_1_banks], offset_base + (index * 1596 offset_multiplier)); 1597 } 1598 SOC_IF_ERROR_RETURN 1599 (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1600 hash_control_entry)); 1601 SOC_IF_ERROR_RETURN 1602 (WRITE_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1603 shared_hash_control_entry)); 1604 1605 sal_memset(shared_hash_control_entry, 0, 1606 sizeof(ip_uat_shared_banks_control_entry_t)); 1607 sal_memset(shared_4k_hash_control_entry, 0, 1608 sizeof(ip_uat_shared_banks_control_entry_t)); 1609 sal_memset(hash_control_entry, 0, 1610 sizeof(mpls_entry_hash_control_entry_t)); 1611 SOC_IF_ERROR_RETURN 1612 (READ_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1613 shared_hash_control_entry)); 1614 SOC_IF_ERROR_RETURN 1615 (READ_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1616 shared_4k_hash_control_entry)); 1617 SOC_IF_ERROR_RETURN 1618 (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1619 hash_control_entry)); 1620 1621 if (mpls_4k_banks) { 1622 offset_base = 64 % (mpls_4k_banks); 1623 offset_multiplier = 64 / (mpls_4k_banks); 1624 } 1625 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 1626 HASH_TABLE_BANK_CONFIGf, ((1 << mpls_4k_banks) - 1)); 1627 for(index = 0; index < mpls_4k_banks; index++) { 1628 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 1629 logical_to_physical_fields[index], index); 1630 soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm, 1631 shared_4k_hash_control_entry, shared_fields[index], 1632 offset_base + ( index * offset_multiplier)); 1633 } 1634 1635 SOC_IF_ERROR_RETURN 1636 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1637 hash_control_entry)); 1638 1639 sal_memset(hash_control_entry, 0, 1640 sizeof(vlan_xlate_1_hash_control_entry_t)); 1641 SOC_IF_ERROR_RETURN 1642 (READ_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1643 hash_control_entry)); 1644 if (vlan_xlate_1_4k_banks) { 1645 offset_base = 64 % (vlan_xlate_1_4k_banks); 1646 offset_multiplier = 64 / (vlan_xlate_1_4k_banks); 1647 } 1648 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, hash_control_entry, 1649 HASH_TABLE_BANK_CONFIGf, ((((1 << vlan_xlate_1_4k_banks) 1650 - 1) << mpls_4k_banks))); 1651 1652 for(index = 0; index < vlan_xlate_1_4k_banks; index++) { 1653 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, 1654 hash_control_entry, 1655 logical_to_physical_fields[index], index + 1656 mpls_4k_banks); 1657 soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm, 1658 shared_4k_hash_control_entry, shared_fields[index + 1659 mpls_4k_banks], offset_base + (index * 1660 offset_multiplier)); 1661 } 1662 1663 SOC_IF_ERROR_RETURN 1664 (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1665 hash_control_entry)); 1666 1667 sal_memset(hash_control_entry, 0, 1668 sizeof(vlan_xlate_2_hash_control_entry_t)); 1669 SOC_IF_ERROR_RETURN 1670 (READ_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1671 hash_control_entry)); 1672 if (vlan_xlate_2_4k_banks) { 1673 offset_base = 64 % (vlan_xlate_2_4k_banks); 1674 offset_multiplier = 64 / (vlan_xlate_2_4k_banks); 1675 } 1676 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry, 1677 HASH_TABLE_BANK_CONFIGf, ((((1 << vlan_xlate_2_4k_banks) 1678 - 1) << (mpls_4k_banks + vlan_xlate_1_4k_banks)))); 1679 1680 for(index = 0; index < vlan_xlate_2_4k_banks; index++) { 1681 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, hash_control_entry, 1682 logical_to_physical_fields[index], index + 1683 mpls_4k_banks + vlan_xlate_1_4k_banks); 1684 soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm, 1685 shared_4k_hash_control_entry, shared_fields[index + 1686 mpls_4k_banks + vlan_xlate_1_4k_banks], offset_base 1687 + (index * offset_multiplier)); 1688 } 1689 1690 SOC_IF_ERROR_RETURN 1691 (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1692 hash_control_entry)); 1693 SOC_IF_ERROR_RETURN 1694 (WRITE_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1695 shared_4k_hash_control_entry)); 1696 1697 /* Create a mutex for s/w re-ordering */ 1698 SOC_IF_ERROR_RETURN(soc_td3_hash_mutex_init (unit)); 1699 1700 return SOC_E_NONE; 1701 } 1702 1703 1704 /* 1705 * PM4X10_QTC core has two work modes: Q(QTC) mode and Ethernet(XLPORT) mode. 1706 * In QTC mode, QTC is reset via register PMQ_XGXS0_CTRL_REGr which is belong to SOC_BLK_PMQPORT block. 1707 * In Eth mode, TSC is reset via register XLPORT_XGXS0_CTRL_REGr which is belong to SOC_BLK_XLPORT block. 1708 * To reset QTC or TSC core, the work mode must be identified by register CHIP_CONFIGr which is configured in soc_helix5_chip_reset. 1709 */ 1710 int 1711 soc_helix5_port_reset(int unit) 1712 { 1713 int blk, port; 1714 uint32 rval; 1715 uint64 rval64; 1716 uint32 index, qtc_mode = ETHER_MODE; 1717 int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100; 1718 1719 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 1720 port = SOC_BLOCK_PORT(unit, blk); 1721 1722 SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval)); 1723 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1); 1724 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 1725 sal_udelay(10); 1726 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 1727 if (soc_reg_field_valid(unit, CLPORT_MAC_CONTROLr, SYS_16B_INTF_MODEf) && 1728 soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) { 1729 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, SYS_16B_INTF_MODEf, 1); 1730 } 1731 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 1732 } 1733 1734 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 1735 port = SOC_BLOCK_PORT(unit, blk); 1736 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval)); 1737 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1); 1738 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 1739 sal_udelay(10); 1740 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 1741 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 1742 1743 if (IS_QSGMII_PORT(unit, port)) { 1744 continue; 1745 } 1746 1747 SOC_IF_ERROR_RETURN(soc_reg_get(unit, XLPORT_XGXS0_CTRL_REGr, port, 0, &rval64)); 1748 soc_reg64_field32_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval64, REFSELf, 5); 1749 SOC_IF_ERROR_RETURN(soc_reg_set(unit, XLPORT_XGXS0_CTRL_REGr, port, 0, rval64)); 1750 } 1751 1752 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PMQPORT) { 1753 port = blk | SOC_REG_ADDR_BLOCK_ID_MASK; 1754 index = SOC_BLOCK_NUMBER(unit, blk); 1755 1756 SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, index, 0, &rval64)); 1757 qtc_mode = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf); 1758 if (qtc_mode == Q_MODE) { 1759 SOC_IF_ERROR_RETURN(soc_reg_get(unit, PMQ_XGXS0_CTRL_REGr, port, 0, &rval64)); 1760 soc_reg64_field32_set(unit, PMQ_XGXS0_CTRL_REGr, &rval64, REFSELf, 5); 1761 SOC_IF_ERROR_RETURN(soc_reg_set(unit, PMQ_XGXS0_CTRL_REGr, port, 0, rval64)); 1762 } 1763 } 1764 1765 /* Power off CLPORT blocks */ 1766 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 1767 port = SOC_BLOCK_PORT(unit, blk); 1768 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1)); 1769 } 1770 sal_usleep(sleep_usec + 10000); 1771 /* Power on CLPORT blocks */ 1772 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 1773 port = SOC_BLOCK_PORT(unit, blk); 1774 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0)); 1775 } 1776 1777 /* Power off XLPORT blocks */ 1778 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 1779 port = SOC_BLOCK_PORT(unit, blk); 1780 if (IS_QSGMII_PORT(unit, port)) { 1781 continue; 1782 } 1783 1784 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1)); 1785 } 1786 sal_usleep(sleep_usec + 10000); 1787 /* Power on XLPORT blocks */ 1788 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 1789 port = SOC_BLOCK_PORT(unit, blk); 1790 if (IS_QSGMII_PORT(unit, port)) { 1791 continue; 1792 } 1793 1794 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0)); 1795 } 1796 1797 /* Power off PMQ blocks */ 1798 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PMQPORT) { 1799 port = blk | SOC_REG_ADDR_BLOCK_ID_MASK; 1800 index = SOC_BLOCK_NUMBER(unit, blk); 1801 1802 SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, index, 0, &rval64)); 1803 qtc_mode = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf); 1804 if (qtc_mode == Q_MODE) { 1805 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 1)); 1806 } 1807 } 1808 sal_usleep(sleep_usec + 10000); 1809 /* Power on PMQ blocks */ 1810 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PMQPORT) { 1811 port = blk | SOC_REG_ADDR_BLOCK_ID_MASK; 1812 index = SOC_BLOCK_NUMBER(unit, blk); 1813 1814 SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, index, 0, &rval64)); 1815 qtc_mode = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf); 1816 if (qtc_mode == Q_MODE) { 1817 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_power_mode(unit, port, 0, 0)); 1818 } 1819 } 1820 1821 return SOC_E_NONE; 1822 } 1823 1824 STATIC int 1825 _soc_helix5_port_mapping_init(int unit) 1826 { 1827 soc_info_t *si; 1828 int port, phy_port, idb_port, i; 1829 soc_reg_t reg; 1830 soc_mem_t mem; 1831 uint32 rval; 1832 uint32 entry[SOC_MAX_MEM_WORDS]; 1833 int pipe = 0; 1834 int max_idx = 0; 1835 1836 si = &SOC_INFO(unit); 1837 1838 /* Ingress IDB to device port mapping */ 1839 sal_memset(&entry, 0, sizeof(entry)); 1840 mem = SOC_MEM_UNIQUE_ACC(unit, ING_PHY_TO_IDB_PORT_MAPm)[pipe]; 1841 1842 /* Set all entries to 0x7f as default */ 1843 soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, 0x7f); 1844 soc_mem_field32_set(unit, mem, &entry, VALIDf, 0); 1845 max_idx = soc_mem_index_max(unit, ING_PHY_TO_IDB_PORT_MAPm); 1846 for (phy_port = 0; phy_port <= max_idx; phy_port++) { 1847 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry)); 1848 } 1849 1850 /* Ingress IDB to device port mapping */ 1851 sal_memset(&entry, 0, 1852 sizeof(ing_idb_to_device_port_number_mapping_table_entry_t)); 1853 mem = SOC_MEM_UNIQUE_ACC(unit, ING_IDB_TO_DEVICE_PORT_NUMBER_MAPPING_TABLEm)[pipe]; 1854 /* Set all entries to 0x7f since Device Port No. 0 corresponds to CPU port*/ 1855 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, 0x7f); 1856 for (idb_port = 0; idb_port < HX5_NUM_PORT; idb_port++) { 1857 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry)); 1858 } 1859 1860 /* Ancillary ports */ 1861 for (i = 0; i < COUNTOF(hx5_anc_ports); i++) { 1862 idb_port = hx5_anc_ports[i].idb_port; 1863 phy_port = si->port_m2p_mapping[idb_port]; 1864 port = si->port_p2l_mapping[phy_port]; 1865 1866 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port); 1867 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry)); 1868 1869 /* Egress device port to physical port mapping */ 1870 rval = 0; 1871 reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr; 1872 soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf, phy_port); 1873 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1874 1875 /* MMU port to physical port mapping */ 1876 rval = 0; 1877 reg = MMU_PORT_TO_PHY_PORT_MAPPINGr; 1878 soc_reg_field_set(unit, reg, &rval, PHY_PORTf, phy_port); 1879 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1880 1881 /* MMU port to device port mapping */ 1882 rval = 0; 1883 reg = MMU_PORT_TO_DEVICE_PORT_MAPPINGr; 1884 soc_reg_field_set(unit, reg, &rval, DEVICE_PORTf, port); 1885 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1886 } 1887 /* Ingress GPP port to device port mapping */ 1888 mem = SYS_PORTMAPm; 1889 sal_memset(&entry, 0, sizeof(sys_portmap_entry_t)); 1890 for (port = 0; port < HX5_NUM_PORT; port++) { 1891 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port); 1892 SOC_IF_ERROR_RETURN 1893 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, port, &entry)); 1894 } 1895 1896 1897 #if 0 1898 /* Mapping for Front Panel ports handled in DV flexport code */ 1899 for (port = 0; port < HX5_NUM_PORT; port++) { 1900 idb_port = si->port_l2i_mapping[port]; 1901 1902 if (idb_port == -1) { 1903 continue; 1904 } 1905 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port); 1906 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, idb_port, &entry)); 1907 } 1908 1909 /* Ingress physical to IDB port mapping 1910 * This table is programmed only for front panel ports 1911 */ 1912 sal_memset(&entry, 0, sizeof(ing_phy_to_idb_port_map_entry_t)); 1913 mem = SOC_MEM_UNIQUE_ACC(unit, ING_PHY_TO_IDB_PORT_MAPm)[pipe]; 1914 for (phy_port = 1; phy_port <= _HX5_PORTS_PER_PIPE; phy_port++) { 1915 port = si->port_p2l_mapping[phy_port]; 1916 1917 if (port != -1) { 1918 idb_port = si->port_l2i_mapping[port]; 1919 if (idb_port == -1) { 1920 return SOC_E_INTERNAL; 1921 } 1922 1923 soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, idb_port); 1924 soc_mem_field32_set(unit, mem, &entry, VALIDf, 1); 1925 } else { 1926 soc_mem_field32_set(unit, mem, &entry, VALIDf, 0); 1927 } 1928 1929 SOC_IF_ERROR_RETURN 1930 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port - 1, &entry)); 1931 } 1932 1933 /* Ingress device port to GPP port mapping 1934 * PORT_TAB.SRC_SYS_PORT_ID is programmed in the general port config 1935 * init routine _bcm_fb_port_cfg_init() 1936 */ 1937 1938 /* Egress device port to physical port mapping */ 1939 rval = 0; 1940 reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr; 1941 PBMP_ALL_ITER(unit, port) { 1942 soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf, 1943 si->port_l2p_mapping[port]); 1944 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1945 } 1946 1947 /* MMU port to physical port mapping */ 1948 rval = 0; 1949 reg = MMU_PORT_TO_PHY_PORT_MAPPINGr; 1950 PBMP_ALL_ITER(unit, port) { 1951 soc_reg_field_set(unit, reg, &rval, PHY_PORTf, 1952 si->port_l2p_mapping[port]); 1953 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1954 } 1955 1956 /* MMU port to device port mapping */ 1957 rval = 0; 1958 reg = MMU_PORT_TO_DEVICE_PORT_MAPPINGr; 1959 PBMP_ALL_ITER(unit, port) { 1960 soc_reg_field_set(unit, reg, &rval, DEVICE_PORTf, port); 1961 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1962 } 1963 #endif 1964 return SOC_E_NONE; 1965 } 1966 1967 /* 1968 * Function: 1969 * _soc_helix5_latency_config 1970 * Purpose: 1971 * Configure latency in SLOT_PIPELINE_CONFIG register 1972 * Parameters: 1973 * unit (IN) - switch unit 1974 * Returns: 1975 * SOC_E_* 1976 */ 1977 1978 STATIC int 1979 _soc_helix5_latency_config(int unit) 1980 { 1981 soc_reg_t reg; 1982 uint32 rval; 1983 uint32 latency, pipe_latency_full = 455; 1984 int frequency, dpp_clk_ratio_x10; 1985 soc_info_t *si = &SOC_INFO(unit); 1986 1987 frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, si->frequency); 1988 dpp_clk_ratio_x10 = (frequency > CCLK_FREQ_1012MHZ)? 15:10; 1989 1990 reg = SLOT_PIPELINE_CONFIGr; 1991 rval = 0; 1992 latency = (pipe_latency_full * dpp_clk_ratio_x10 / 10) - 6 + 5; 1993 if ((dpp_clk_ratio_x10 == 15) && (pipe_latency_full % 2)) { 1994 latency += 1; /* To round up. */ 1995 } 1996 soc_reg_field_set(unit, reg, &rval, LATENCYf, latency); 1997 soc_reg_field_set(unit, reg, &rval, WR_ENf, 1); 1998 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 1999 2000 return SOC_E_NONE; 2001 } 2002 2003 2004 /* 2005 * Function: 2006 * _soc_hx5_set_idb_dpp_ctrl 2007 * Purpose: 2008 * Configure IDB DPP credits 2009 * Parameters: 2010 * unit (IN) - switch unit 2011 * Returns: 2012 * SOC_E_* 2013 */ 2014 static int 2015 _soc_hx5_set_idb_dpp_ctrl(int unit) 2016 { 2017 soc_reg_t reg; 2018 uint32 pipe_map, in_progress; 2019 int pipe; 2020 uint32 rval, rval0; 2021 int pipe_init_usec; 2022 soc_timeout_t to; 2023 static const soc_reg_t idb_dpp_ctrl[2] = { 2024 IDB_DPP_CTRL_PIPE0r, IDB_DPP_CTRL_PIPE1r 2025 }; 2026 2027 soc_trident3_pipe_map_get(unit, &pipe_map); 2028 2029 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2030 if (!(pipe_map & (1 << pipe))) { 2031 continue; 2032 } 2033 reg = idb_dpp_ctrl[pipe]; 2034 rval = 0; 2035 /*SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));*/ 2036 soc_reg_field_set(unit, reg, &rval, MAX_REF_CNTf, 4); 2037 soc_reg_field_set(unit, reg, &rval, MAX_SBUS_CNTf, 4); 2038 soc_reg_field_set(unit, reg, &rval, CREDITSf, 36); 2039 soc_reg_field_set(unit, reg, &rval, DONEf, 0); 2040 soc_reg_field_set(unit, reg, &rval, STARTf, 1); 2041 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 2042 } 2043 2044 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 2045 if (SAL_BOOT_SIMULATION) { 2046 pipe_init_usec = 10000000; 2047 } else { 2048 pipe_init_usec = 50000; 2049 } 2050 soc_timeout_init(&to, pipe_init_usec, 0); 2051 2052 /* Wait for DPP credit initialization done */ 2053 in_progress = pipe_map; 2054 do { 2055 for (pipe = 0; pipe < NUM_PIPE(unit) && in_progress; pipe++) { 2056 reg = SOC_REG_UNIQUE_ACC(unit, IDB_DPP_CTRLr)[pipe]; 2057 if (in_progress & (1 << pipe)) { /* not done yet */ 2058 SOC_IF_ERROR_RETURN 2059 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 2060 if (soc_reg_field_get(unit, reg, rval0, DONEf)) { 2061 in_progress ^= (1 << pipe); 2062 } 2063 } 2064 } 2065 if (soc_timeout_check(&to)) { 2066 LOG_WARN(BSL_LS_SOC_COMMON, 2067 (BSL_META_U(unit, 2068 "unit %d : IDB_DPP_CTRL timeout\n"), unit)); 2069 break; 2070 } 2071 } while (in_progress != 0); 2072 2073 return SOC_E_NONE; 2074 } 2075 2076 STATIC int 2077 _soc_helix5_tdm_init(int unit, soc_port_schedule_state_t *port_schedule_state) 2078 { 2079 soc_control_t *soc = SOC_CONTROL(unit); 2080 soc_info_t *si = &SOC_INFO(unit); 2081 soc_port_map_type_t *in_portmap; 2082 int port, speed; 2083 int i = 0; 2084 if (soc->tdm_info == NULL) { 2085 soc->tdm_info = sal_alloc(sizeof(_soc_helix5_tdm_temp_t), 2086 "Helix5 TDM info"); 2087 if (soc->tdm_info == NULL) { 2088 return SOC_E_MEMORY; 2089 } 2090 sal_memset(soc->tdm_info, 0, sizeof(_soc_helix5_tdm_temp_t)); 2091 } 2092 sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t)); 2093 #if defined(BCM_WARM_BOOT_SUPPORT) 2094 if (SOC_WARM_BOOT(unit)) { 2095 SOC_IF_ERROR_RETURN(soc_hx5_tdm_scache_recovery(unit)); 2096 return SOC_E_NONE; 2097 } else { 2098 SOC_IF_ERROR_RETURN(soc_hx5_tdm_scache_allocate(unit)); 2099 } 2100 #endif 2101 /* Core clock frequency */ 2102 port_schedule_state->frequency = si->frequency; 2103 port_schedule_state->bandwidth = si->bandwidth; 2104 port_schedule_state->io_bandwidth = si->io_bandwidth; 2105 port_schedule_state->lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);; 2106 port_schedule_state->is_flexport = 0; 2107 2108 /* Construct in_port_map */ 2109 in_portmap = &port_schedule_state->in_port_map; 2110 PBMP_PORT_ITER(unit, port) { 2111 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 2112 continue; 2113 } 2114 if (IS_HG_PORT(unit, port)) { 2115 speed = soc_port_speed_higig2eth(si->port_speed_max[port]); 2116 port_schedule_state->resource[i].encap = SOC_ENCAP_HIGIG2; 2117 } else { 2118 speed = si->port_speed_max[port]; 2119 } 2120 in_portmap->log_port_speed[port] = speed; 2121 in_portmap->port_num_lanes[port] = si->port_num_lanes[port]; 2122 2123 port_schedule_state->resource[i].physical_port = si->port_l2p_mapping[port]; 2124 port_schedule_state->resource[i].logical_port = port; 2125 port_schedule_state->resource[i].idb_port = si->port_l2i_mapping[port]; 2126 port_schedule_state->resource[i].mmu_port = si->port_l2i_mapping[port]; 2127 port_schedule_state->resource[i].num_lanes = si->port_num_lanes[port]; 2128 port_schedule_state->resource[i].speed = speed; 2129 port_schedule_state->resource[i].pipe = 0; 2130 port_schedule_state->resource[i].oversub = IS_OVERSUB_PORT(unit, port) ? 1 : 0; 2131 port_schedule_state->nport = ++i; 2132 } 2133 sal_memcpy(in_portmap->port_p2l_mapping, si->port_p2l_mapping, 2134 sizeof(int)*HELIX5_TDM_PHY_PORTS_PER_DEV); 2135 sal_memcpy(in_portmap->port_l2p_mapping, si->port_l2p_mapping, 2136 sizeof(int)*_HX5_TDM_DEV_PORTS_PER_DEV); 2137 sal_memcpy(in_portmap->port_p2m_mapping, si->port_p2m_mapping, 2138 sizeof(int)*HELIX5_TDM_PHY_PORTS_PER_DEV); 2139 sal_memcpy(in_portmap->port_m2p_mapping, si->port_m2p_mapping, 2140 sizeof(int)*_HX5_TDM_MMU_PORTS_PER_DEV); 2141 sal_memcpy(in_portmap->port_l2i_mapping, si->port_l2i_mapping, 2142 sizeof(int)*_HX5_TDM_DEV_PORTS_PER_DEV); 2143 sal_memcpy(&in_portmap->physical_pbm, &si->physical_pbm, sizeof(pbmp_t)); 2144 sal_memcpy(&in_portmap->hg2_pbm, &si->hg.bitmap, sizeof(pbmp_t)); 2145 sal_memcpy(&in_portmap->management_pbm, &si->management_pbm, 2146 sizeof(pbmp_t)); 2147 sal_memcpy(&in_portmap->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t)); 2148 2149 SOC_IF_ERROR_RETURN(soc_hx5_port_schedule_tdm_init(unit, port_schedule_state)); 2150 SOC_IF_ERROR_RETURN(soc_hx5_tdm_init(unit, port_schedule_state)); 2151 SOC_IF_ERROR_RETURN(soc_helix5_reconfigure_ports(unit, port_schedule_state)); 2152 SOC_IF_ERROR_RETURN(soc_hx5_soc_tdm_update(unit, port_schedule_state)); 2153 2154 return SOC_E_NONE; 2155 } 2156 2157 /* IDB, EDB configuration for Front Panel ports handled in DV flexport code */ 2158 STATIC int 2159 _soc_helix5_edb_init(int unit) 2160 { 2161 uint32 entry[SOC_MAX_MEM_WORDS]; 2162 int i; 2163 2164 for (i = 0; i < COUNTOF(hx5_anc_ports); i++) { 2165 /* Configure egress mmu cell credit */ 2166 sal_memset(entry, 0, sizeof(egr_mmu_cell_credit_entry_t)); 2167 soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &entry, CREDITf, 11); 2168 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm 2169 (unit, MEM_BLOCK_ALL, hx5_anc_ports[i].phy_port, &entry)); 2170 2171 /* Configure egress transmit start count */ 2172 sal_memset(entry, 0, sizeof(egr_xmit_start_count_pipe0_entry_t)); 2173 soc_EGR_XMIT_START_COUNT_PIPE0m_field32_set(unit, &entry, THRESHOLDf, 7); 2174 SOC_IF_ERROR_RETURN(WRITE_EGR_XMIT_START_COUNT_PIPE0m 2175 (unit, MEM_BLOCK_ALL, hx5_anc_ports[i].port * 16, &entry)); 2176 2177 /* Enable egress */ 2178 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 2179 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 2180 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEm 2181 (unit, MEM_BLOCK_ALL, hx5_anc_ports[i].phy_port, entry)); 2182 } 2183 return SOC_E_NONE; 2184 } 2185 2186 STATIC int 2187 _soc_helix5_idb_init(int unit) 2188 { 2189 soc_reg_t reg; 2190 uint32 rval0; 2191 2192 /* Toggle cpu port cell assembly reset to send initial credit to EP */ 2193 reg = IDB_CA_CPU_CONTROLr; 2194 rval0 = 0; 2195 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 2196 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2197 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 2198 2199 /* Toggle loopback cell assembly reset to send initial credit to EP */ 2200 reg = IDB_CA_LPBK_CONTROLr; 2201 rval0 = 0; 2202 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 2203 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2204 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 2205 2206 /* Toggle FAE port cell assembly reset to send initial credit to EP */ 2207 reg = IDB_CA_BSK_CONTROLr; 2208 rval0 = 0; 2209 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 2210 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 2211 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 2212 2213 _soc_hx5_set_idb_dpp_ctrl(unit); 2214 2215 return SOC_E_NONE; 2216 } 2217 2218 /* For a given logical port, return the OBM id and the lane number 2219 * OBM id is nothing but the Serdes/PortMacro number 2220 * Note: HX5 has three different OBM register sets 2221 */ 2222 int 2223 soc_helix5_port_obm_info_get(int unit, soc_port_t port, 2224 int *obm_id, int *lane) 2225 { 2226 soc_info_t *si; 2227 soc_port_t phy_port; 2228 int port_block_base; 2229 2230 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 2231 return SOC_E_PARAM; 2232 } 2233 si = &SOC_INFO(unit); 2234 phy_port = si->port_l2p_mapping[port]; 2235 port_block_base = HX5_PORT_BLOCK_BASE_PORT(port); 2236 if (lane != NULL) { 2237 *lane = (phy_port - port_block_base) / 4; 2238 } 2239 2240 *obm_id = si->port_serdes[port]; 2241 2242 return SOC_E_NONE; 2243 } 2244 2245 extern int 2246 (*_phy_tsce_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int); 2247 extern int 2248 (*_phy_tscf_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int); 2249 2250 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 2251 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 2252 2253 STATIC int 2254 _soc_helix5_mdio_addr_to_port(uint32 phy_addr) 2255 { 2256 int bus, offset; 2257 2258 /* Must be internal MDIO address */ 2259 if ((phy_addr & 0x80) == 0) { 2260 return 0; 2261 } 2262 2263 /* 2264 * Internal phy address: 2265 * bus 0 phy 1 to 24 are mapped to Physical port 1 to 48 2266 * bus 1 phy 1 to 16 are mapped to Physical port 49 to 64 2267 * bus 2 phy 1 to 24 are mapped to Physical port 65 to 76 2268 * bus 3 phy 1 to 24 are mapped to Physical port IPROC PM 2269 */ 2270 bus = PHY_ID_BUS_NUM(phy_addr); 2271 if (bus > 3) { 2272 return 0; 2273 } 2274 switch (bus) { 2275 case 0: offset = 0; 2276 break; 2277 case 1: offset = 48; 2278 break; 2279 case 2: offset = 64; 2280 break; 2281 case 3: offset = 76; 2282 break; 2283 default: 2284 return 0; 2285 } 2286 2287 return (phy_addr & 0x1f) + offset; 2288 } 2289 2290 STATIC int 2291 _soc_helix5_tscx_reg_read(int unit, uint32 phy_addr, 2292 uint32 phy_reg, uint32 *phy_data) 2293 { 2294 int rv, blk, blk_i, blktype, port; 2295 int qmod, inst; 2296 uint64 rval64; 2297 int phy_port = _soc_helix5_mdio_addr_to_port(phy_addr); 2298 2299 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 2300 blk = SOC_PORT_BLOCK(unit, phy_port); 2301 LOG_INFO(BSL_LS_SOC_MII, 2302 (BSL_META_U(unit, 2303 "soc_helix5_tscx_reg_read[%d]: %d/%d/%d/%d\n"), 2304 unit, phy_addr, phy_port, port, blk)); 2305 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 2306 2307 if(phy_port < 49){ 2308 inst = (phy_port - 1) / 16; 2309 SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, inst, 0, &rval64)); 2310 qmod = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf); 2311 2312 for (blk_i = 0; SOC_BLOCK_INFO(unit, blk_i).type >= 0; blk_i++) { 2313 blktype = SOC_BLOCK_INFO(unit, blk_i).type; 2314 if ((blktype == (qmod ? SOC_BLK_PMQPORT : SOC_BLK_XLPORT)) && (SOC_BLOCK_INFO(unit, blk_i).number == inst)) { 2315 blk = blk_i; 2316 break; 2317 } 2318 } 2319 } 2320 2321 rv = soc_sbus_tsc_reg_read(unit, port, blk, phy_addr, 2322 phy_reg, phy_data); 2323 return rv; 2324 } 2325 2326 STATIC int 2327 _soc_helix5_tscx_reg_write(int unit, uint32 phy_addr, 2328 uint32 phy_reg, uint32 phy_data) 2329 { 2330 int rv, blk, blk_i, blktype, port; 2331 int phy_port = _soc_helix5_mdio_addr_to_port(phy_addr); 2332 int qmod, inst; 2333 uint64 rval64; 2334 2335 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 2336 blk = SOC_PORT_BLOCK(unit, phy_port); 2337 LOG_INFO(BSL_LS_SOC_MII, 2338 (BSL_META_U(unit, 2339 "soc_helix5_tscx_reg_write[%d]: %d/%d/%d/%d\n"), 2340 unit, phy_addr, phy_port, port, blk)); 2341 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 2342 2343 if(phy_port < 49){ 2344 inst = (phy_port - 1) / 16; 2345 SOC_IF_ERROR_RETURN(soc_reg_get(unit, CHIP_CONFIGr, inst, 0, &rval64)); 2346 qmod = soc_reg64_field32_get(unit, CHIP_CONFIGr, rval64, QMODEf); 2347 2348 for (blk_i = 0; SOC_BLOCK_INFO(unit, blk_i).type >= 0; blk_i++) { 2349 blktype = SOC_BLOCK_INFO(unit, blk_i).type; 2350 if ((blktype == (qmod ? SOC_BLK_PMQPORT : SOC_BLK_XLPORT)) && (SOC_BLOCK_INFO(unit, blk_i).number == inst)) { 2351 blk = blk_i; 2352 break; 2353 } 2354 } 2355 } 2356 2357 rv = soc_sbus_tsc_reg_write(unit, port, blk, phy_addr, 2358 phy_reg, phy_data); 2359 return rv; 2360 } 2361 2362 STATIC int 2363 _soc_helix5_ft_bank_config(int unit) 2364 { 2365 soc_mem_t mem; 2366 int ft_banks; 2367 ft_key_hash_control_entry_t ft_key_ctrl; 2368 2369 if (soc_feature(unit, soc_feature_flowtracker_ver_1_8K_ft_table)) { 2370 ft_banks = 0x7; 2371 } else if (soc_feature(unit, soc_feature_flowtracker_ver_1_16K_ft_table)) { 2372 ft_banks = 0x1f; 2373 } else { 2374 ft_banks = 0x1ff; 2375 } 2376 2377 SOC_IF_ERROR_RETURN(soc_mem_read(unit, FT_KEY_HASH_CONTROLm, 2378 MEM_BLOCK_ANY, 0, &ft_key_ctrl)); 2379 2380 /* Enable banks for flowtracking. */ 2381 soc_mem_field32_set(unit, FT_KEY_HASH_CONTROLm, &ft_key_ctrl, 2382 HASH_TABLE_BANK_CONFIGf, ft_banks); 2383 2384 soc_mem_field32_set(unit, FT_KEY_HASH_CONTROLm, &ft_key_ctrl, 2385 HASH_TABLE_TEST_MODEf, 0); 2386 2387 SOC_IF_ERROR_RETURN(soc_mem_write(unit, FT_KEY_HASH_CONTROLm, 2388 MEM_BLOCK_ALL, 0, &ft_key_ctrl)); 2389 2390 mem = FT_KEY_SS0_SHARED_BANKS_CONTROLm; 2391 soc_mem_field32_set(unit, mem, 2392 (void *) &ft_key_ss0_shared_banks_control, B0_HASH_OFFSETf, 6); 2393 soc_mem_field32_set(unit, mem, 2394 (void *) &ft_key_ss0_shared_banks_control, B1_HASH_OFFSETf, 12); 2395 soc_mem_field32_set(unit, mem, 2396 (void *) &ft_key_ss0_shared_banks_control, B2_HASH_OFFSETf, 18); 2397 soc_mem_field32_set(unit, mem, 2398 (void *) &ft_key_ss0_shared_banks_control, B3_HASH_OFFSETf, 24); 2399 soc_mem_field32_set(unit, mem, 2400 (void *) &ft_key_ss0_shared_banks_control, B4_HASH_OFFSETf, 30); 2401 BCM_IF_ERROR_RETURN(WRITE_FT_KEY_SS0_SHARED_BANKS_CONTROLm(unit, 2402 MEM_BLOCK_ANY, 0, (void *) &ft_key_ss0_shared_banks_control)); 2403 2404 mem = FT_KEY_SS1_SHARED_BANKS_CONTROLm; 2405 soc_mem_field32_set(unit, mem, 2406 (void *) &ft_key_ss1_shared_banks_control, B0_HASH_OFFSETf, 6); 2407 soc_mem_field32_set(unit, mem, 2408 (void *) &ft_key_ss1_shared_banks_control, B1_HASH_OFFSETf, 12); 2409 soc_mem_field32_set(unit, mem, 2410 (void *) &ft_key_ss1_shared_banks_control, B2_HASH_OFFSETf, 18); 2411 soc_mem_field32_set(unit, mem, 2412 (void *) &ft_key_ss1_shared_banks_control, B3_HASH_OFFSETf, 24); 2413 BCM_IF_ERROR_RETURN(WRITE_FT_KEY_SS1_SHARED_BANKS_CONTROLm(unit, 2414 MEM_BLOCK_ANY, 0, (void *) &ft_key_ss1_shared_banks_control)); 2415 2416 return SOC_E_NONE; 2417 } 2418 2419 2420 STATIC int 2421 _soc_helix5_init_hash_control_reset(int unit) { 2422 2423 soc_mem_field32_set(unit, EGR_VLAN_XLATE_1_HASH_CONTROLm, 2424 &egr_vlan_1_hash_control, HASH_TABLE_BANK_CONFIGf, 0xf); 2425 SOC_IF_ERROR_RETURN 2426 (WRITE_EGR_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2427 &egr_vlan_1_hash_control)); 2428 2429 soc_mem_field32_set(unit, EGR_VLAN_XLATE_2_HASH_CONTROLm, 2430 &egr_vlan_2_hash_control, HASH_TABLE_BANK_CONFIGf, 0); 2431 SOC_IF_ERROR_RETURN 2432 (WRITE_EGR_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2433 &egr_vlan_2_hash_control)); 2434 2435 SOC_IF_ERROR_RETURN 2436 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2437 &egr_vp_vlan_mbm_hash_control)); 2438 2439 soc_mem_field32_set(unit, EXACT_MATCH_HASH_CONTROLm, 2440 &exact_match_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0); 2441 SOC_IF_ERROR_RETURN 2442 (WRITE_EXACT_MATCH_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2443 &exact_match_hash_control)); 2444 2445 SOC_IF_ERROR_RETURN 2446 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2447 &ing_vp_vlan_mbm_hash_control)); 2448 2449 soc_mem_field32_set(unit, L2_ENTRY_HASH_CONTROLm, 2450 &l2_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0x3); 2451 SOC_IF_ERROR_RETURN 2452 (WRITE_L2_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2453 &l2_entry_hash_control)); 2454 2455 soc_mem_field32_set(unit, L3_ENTRY_HASH_CONTROLm, 2456 &l3_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0xffc); 2457 SOC_IF_ERROR_RETURN 2458 (WRITE_L3_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2459 &l3_entry_hash_control)); 2460 2461 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, 2462 &mpls_entry_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0); 2463 SOC_IF_ERROR_RETURN 2464 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2465 &mpls_entry_hash_control)); 2466 2467 soc_mem_field32_set(unit, VLAN_XLATE_1_HASH_CONTROLm, 2468 &vlan_1_hash_control, HASH_TABLE_BANK_CONFIGf, 0xff); 2469 SOC_IF_ERROR_RETURN 2470 (WRITE_VLAN_XLATE_1_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2471 &vlan_1_hash_control)); 2472 2473 soc_mem_field32_set(unit, VLAN_XLATE_2_HASH_CONTROLm, 2474 &vlan_2_hash_control, HASH_TABLE_BANK_CONFIGf, 0x0); 2475 SOC_IF_ERROR_RETURN 2476 (WRITE_VLAN_XLATE_2_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2477 &vlan_2_hash_control)); 2478 2479 SOC_IF_ERROR_RETURN 2480 (WRITE_UFT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2481 &uft_shared_banks_control)); 2482 2483 SOC_IF_ERROR_RETURN 2484 (WRITE_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2485 &ip_uat_shared_banks_control)); 2486 2487 SOC_IF_ERROR_RETURN 2488 (WRITE_EP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2489 &ep_uat_shared_banks_control)); 2490 2491 SOC_IF_ERROR_RETURN 2492 (WRITE_FT_KEY_SS0_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2493 &ft_key_ss0_shared_banks_control)); 2494 2495 SOC_IF_ERROR_RETURN 2496 (WRITE_FT_KEY_SS1_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2497 &ft_key_ss1_shared_banks_control)); 2498 2499 return SOC_E_NONE; 2500 } 2501 2502 int 2503 soc_helix5_chip_reset(int unit) 2504 { 2505 #define _SOC_HX5_TEMP_MAX 130 2506 #define _SOC_HX5_DEF_TEMP_MAX 90 2507 int index; 2508 uint32 to_usec, temp_mask; 2509 uint32 rval, temp_thr; 2510 int pm = 0, field = 0, fval = 0, reg = 0, pipe = 0; 2511 int frequency = -1, freq_sel = 0; 2512 uint64 rval64; 2513 soc_field_t fields[4]; 2514 uint32 values[4]; 2515 2516 static const soc_reg_t temp_thr_reg[] = { 2517 TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr, 2518 TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr, 2519 TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr, 2520 TOP_PVTMON_6_INTR_THRESHOLDr 2521 }; 2522 static const char *temp_thr_prop[] = { 2523 "temp0_threshold", "temp1_threshold", "temp2_threshold", 2524 "temp3_threshold", "temp4_threshold", "temp5_threshold", 2525 "temp6_threshold" 2526 }; 2527 static soc_field_t egr_reset_fields[] = { 2528 PM0_RESETf, PM1_RESETf, PM2_RESETf, PM3_RESETf, 2529 PM4_RESETf, PM5_RESETf, PM6_RESETf, PM7_RESETf, 2530 PM8_RESETf, PM9_RESETf 2531 }; 2532 2533 soc_info_t *si = &SOC_INFO(unit); 2534 2535 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 2536 (10 * MILLISECOND_USEC); 2537 2538 soc_helix5_sbus_ring_map_config(unit); 2539 2540 sal_usleep(to_usec); 2541 /* Reset IP, EP, MMU and port macros */ 2542 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, 0x0)); 2543 2544 2545 /* If frequency is specificed use it , else use the si->frequency */ 2546 if (frequency == -1) { 2547 frequency = si->frequency; 2548 } 2549 2550 if (frequency > -1) { 2551 switch (frequency) { 2552 case 893: 2553 freq_sel = 0; 2554 break; 2555 case 762: 2556 freq_sel = 1; 2557 break; 2558 case 668: 2559 freq_sel = 2; 2560 break; 2561 case 587: 2562 freq_sel = 3; 2563 break; 2564 case 543: 2565 freq_sel = 4; 2566 break; 2567 case 450: 2568 freq_sel = 5; 2569 break; 2570 case 400: 2571 freq_sel = 6; 2572 break; 2573 default: 2574 LOG_ERROR(BSL_LS_SOC_COMMON, 2575 (BSL_META_U(unit, 2576 "Config Error - " 2577 "Invalid frequency set: %d\n"), si->frequency)); 2578 return SOC_E_PARAM; 2579 } 2580 2581 fields[0] = CORE_CLK_0_FREQ_SELf; 2582 values[0] = freq_sel; 2583 fields[1] = SW_CORE_CLK_0_SEL_ENf; 2584 values[1] = 1; 2585 SOC_IF_ERROR_RETURN 2586 (soc_reg_fields32_modify(unit, TOP_CORE_CLK_FREQ_SELr, 2587 REG_PORT_ANY, 2, fields, values)); 2588 } else { 2589 LOG_ERROR(BSL_LS_SOC_COMMON, 2590 (BSL_META_U(unit, 2591 "Config Error - " 2592 "Invalid frequency set: %d\n"), si->frequency)); 2593 return SOC_E_PARAM; 2594 } 2595 2596 /* Bring PLLs out of reset */ 2597 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 2598 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2599 TOP_TS_PLL_RST_Lf, 0); 2600 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2601 TOP_XG_PLL0_RST_Lf, 0); 2602 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2603 TOP_XG_PLL1_RST_Lf, 0); 2604 2605 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 2606 2607 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2608 TOP_TS_PLL_RST_Lf, 1); 2609 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2610 TOP_XG_PLL0_RST_Lf, 1); 2611 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2612 TOP_XG_PLL1_RST_Lf, 1); 2613 2614 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 2615 2616 /* Give time to lock */ 2617 sal_usleep(to_usec); 2618 2619 /* De-assert TS PLL, BS PLL0/1 post reset and bring AVS out of reset */ 2620 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 2621 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2622 TOP_TS_PLL_POST_RST_Lf, 1); 2623 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2624 TOP_XG_PLL0_POST_RST_Lf, 1); 2625 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 2626 TOP_XG_PLL1_POST_RST_Lf, 1); 2627 2628 soc_reg_field_set(unit,TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 2629 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 2630 2631 sal_usleep(to_usec); 2632 2633 /* Enable high temperature interrupt monitoring. 2634 * Default on: pvtmon6 (close to core_plls at center of die). 2635 */ 2636 temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<6); 2637 /* The above is a 9 bit mask to indicate which temp sensor to hook up to 2638 * the interrupt. 2639 */ 2640 rval = 0; 2641 for (index = 0; index <COUNTOF(temp_thr_reg); index++) { 2642 uint32 trval; 2643 2644 /* Temp = 434.10 - o_ADC_data * 0.53504 2645 * data = (434.10 - temp)/0.53504 = (434100-(temp*1000))/535 2646 * Note: Since this is a high temp value we can safely assume it to 2647 * always be a +ive number. This is in degrees celcius. 2648 */ 2649 temp_thr = soc_property_get(unit, temp_thr_prop[index], 2650 _SOC_HX5_TEMP_MAX); 2651 if (temp_thr > _SOC_HX5_TEMP_MAX) { 2652 LOG_ERROR(BSL_LS_SOC_COMMON, 2653 (BSL_META_U(unit, 2654 "Unsupported temp value %d !! Max %d. Using %d.\n"), 2655 temp_thr, _SOC_HX5_TEMP_MAX, _SOC_HX5_DEF_TEMP_MAX)); 2656 temp_thr = _SOC_HX5_DEF_TEMP_MAX; 2657 } 2658 /* Convert temperature to config data */ 2659 temp_thr = (434100-(temp_thr*1000))/535; 2660 SOC_IF_ERROR_RETURN 2661 (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval)); 2662 soc_reg_field_set(unit, temp_thr_reg[index], &trval, MIN_THRESHOLDf, 2663 temp_thr); 2664 SOC_IF_ERROR_RETURN 2665 (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval)); 2666 if (temp_mask & (1 << index)) { 2667 rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */ 2668 } 2669 } 2670 _soc_hx5_temp_mon_mask[unit] = temp_mask; 2671 2672 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_INTR_MASKr(unit, rval)); 2673 /* Enable temp mon interrupt */ 2674 #ifdef BCM_CMICX_SUPPORT 2675 if (soc_feature(unit, soc_feature_cmicx)) { 2676 2677 /* (void)soc_cmicm_intr3_enable(unit, 0x4); PVTMON_INTR bit 2 */ 2678 } 2679 #endif 2680 2681 /* Bring IP, EP, MMU and port macros out of reset */ 2682 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, 0x3fff)); 2683 sal_usleep(to_usec); 2684 2685 /* PM4x10Q QSGMII mode control 2686 */ 2687 reg = TOP_MISC_GENERIC_CONTROLr; 2688 rval = 0; 2689 if (soc_property_phys_port_get(unit, 1, spn_PORT_GMII_MODE, 0)) { 2690 soc_reg_field_set(unit, reg, &rval, PM4X10Q_0_QSGMII_MODE_ENf, 0x1); 2691 soc_reg_field32_modify(unit, CHIP_CONFIGr, 0, QMODEf, 1); 2692 } 2693 if (soc_property_phys_port_get(unit, 17, spn_PORT_GMII_MODE, 0)) { 2694 soc_reg_field_set(unit, reg, &rval, PM4X10Q_1_QSGMII_MODE_ENf, 0x1); 2695 soc_reg_field32_modify(unit, CHIP_CONFIGr, 1, QMODEf, 1); 2696 } 2697 if (soc_property_phys_port_get(unit, 33, spn_PORT_GMII_MODE, 0)) { 2698 soc_reg_field_set(unit, reg, &rval, PM4X10Q_2_QSGMII_MODE_ENf, 0x1); 2699 soc_reg_field32_modify(unit, CHIP_CONFIGr, 2, QMODEf, 1); 2700 } 2701 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 2702 2703 /* Reset egress hardware resource */ 2704 reg = SOC_REG_UNIQUE_ACC(unit, EGR_PORT_BUFFER_SFT_RESET_0r)[pipe]; 2705 2706 SOC_IF_ERROR_RETURN 2707 (soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 2708 for ( pm = 0; pm < sizeof(egr_reset_fields)/sizeof(soc_field_t); pm++) { 2709 field = egr_reset_fields[pm]; 2710 fval = 4; 2711 soc_reg64_field32_set(unit, reg, &rval64, field, fval); 2712 } 2713 /* Write the value to enable 4 lanes on the PM */ 2714 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64)); 2715 2716 /* Set it back to zero now */ 2717 for ( pm = 0; pm < sizeof(egr_reset_fields)/sizeof(soc_field_t); pm++) { 2718 field = egr_reset_fields[pm]; 2719 fval = 0; 2720 soc_reg64_field32_set(unit, reg, &rval64, field, fval); 2721 } 2722 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval64)); 2723 2724 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 2725 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROL_64r, 2726 REG_PORT_ANY, 2727 IS_TDM_ECC_ENf,1)); 2728 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROL_64r, 2729 REG_PORT_ANY, 2730 CA_CPU_ECC_ENABLEf,1)); 2731 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROL_64r, 2732 REG_PORT_ANY, 2733 CA_LPBK_ECC_ENABLEf,1)); 2734 } 2735 2736 SOC_IF_ERROR_RETURN(soc_trident3_init_idb_memory(unit)); 2737 SOC_IF_ERROR_RETURN(_soc_helix5_init_hash_control_reset(unit)); 2738 SOC_IF_ERROR_RETURN(soc_helix5_uft_uat_config(unit)); 2739 SOC_IF_ERROR_RETURN(_soc_helix5_ft_bank_config(unit)); 2740 2741 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 2742 SOC_IF_ERROR_RETURN(soc_trident3_clear_all_memory(unit)); 2743 } 2744 2745 if (soc_feature(unit, soc_feature_turbo_boot)) { 2746 uint32 def_val = 0; 2747 2748 if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED)) { 2749 def_val = 1; 2750 } 2751 if (soc_property_get(unit, "clear_on_hw_resetting", def_val)) { 2752 SOC_HW_RESET_START(unit); 2753 } 2754 } 2755 2756 #ifdef BCM_HELIX5_SUPPORT 2757 /* For HX5 A WAR is needed when reading 'CHIP_CONFIGr', since the fields 2758 PMD_PLL_CTRL_REFLK_DIV2f/PMD_PLL_CTRL_REFLK_DIV4f are swapped (Write 2759 into the register is fine) 2760 2761 Here at init, based on the feature we enable the flag and also save 2762 the the address of the register to use it when reg read is done */ 2763 if (soc_feature(unit, soc_feature_chip_config_read_war)) { 2764 int block = 0; 2765 uint8 access_type = 0; 2766 2767 si->hx5_chip_config_war_enable = 1; 2768 si->hx5_chip_config_address = -1; 2769 si->hx5_chip_config_address = soc_reg_addr_get(unit, 2770 CHIP_CONFIGr, 2771 REG_PORT_ANY, 0, 2772 SOC_REG_ADDR_OPTION_NONE, 2773 &block, &access_type); 2774 if (si->hx5_chip_config_address == -1) { 2775 LOG_ERROR(BSL_LS_SOC_COMMON, 2776 (BSL_META_U(unit, 2777 "Config Error - Invalid address for" 2778 "CHIP_CONFIG reg\n"))); 2779 return SOC_E_PARAM; 2780 } 2781 } 2782 #endif 2783 2784 return SOC_E_NONE; 2785 } 2786 2787 2788 #ifdef BCM_CMICX_SUPPORT 2789 STATIC int 2790 _soc_hx5_ledup_init(int unit) 2791 { 2792 soc_info_t *si = &SOC_INFO(unit); 2793 int freq; 2794 uint32 rval, clk_half_period, refresh_period; 2795 2796 /* WAR: Let LED accumulation work. */ 2797 SOC_IF_ERROR_RETURN(READ_IPROC_WRAP_MISC_CONTROLr(unit, &rval)); 2798 soc_reg_field_set(unit, IPROC_WRAP_MISC_CONTROLr, &rval, 2799 IPROC_PM_RST_Lf, 1); 2800 SOC_IF_ERROR_RETURN(WRITE_IPROC_WRAP_MISC_CONTROLr(unit, rval)); 2801 2802 /* freq in KHz */ 2803 freq = (si->frequency) * 1000; 2804 2805 /* For LED refresh period = 33 ms (about 30Hz) */ 2806 2807 /* refresh period 2808 * = (required refresh period in sec)*(switch clock frequency in Hz) 2809 */ 2810 refresh_period = (freq * 33); 2811 2812 rval = 0; 2813 soc_reg_field_set(unit, U0_LED_REFRESH_CTRLr, &rval, 2814 REFRESH_CYCLE_PERIODf, refresh_period); 2815 2816 SOC_IF_ERROR_RETURN(WRITE_U0_LED_REFRESH_CTRLr(unit, rval)); 2817 2818 /* For LED clock period */ 2819 /* LEDCLK_HALF_PERIOD 2820 * = [(required LED clock period in sec)/2]*(M0SS clock frequency in Hz) 2821 * 2822 * Where M0SS freqency is 858MHz and 2823 * Typical LED clock period is 200ns(5MHz) = 2*10^-7 2824 */ 2825 freq = 858 * 1000000; 2826 clk_half_period = (freq + 2500000) / 5000000; 2827 clk_half_period = clk_half_period / 2; 2828 2829 rval = 0; 2830 soc_reg_field_set(unit, U0_LED_CLK_DIV_CTRLr, &rval, 2831 LEDCLK_HALF_PERIODf, clk_half_period); 2832 2833 SOC_IF_ERROR_RETURN(WRITE_U0_LED_CLK_DIV_CTRLr(unit, rval)); 2834 2835 2836 SOC_IF_ERROR_RETURN(READ_U0_LED_ACCU_CTRLr(unit, &rval)); 2837 2838 /* Physical port 1 is the first port of TSC0 */ 2839 if (soc_property_phys_port_get(unit, PMQ0_FIRST_PHY_PORT, spn_PORT_GMII_MODE, 0)) { 2840 /* If TSC0 in Q mode */ 2841 soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval, 2842 LAST_PORTf, 15); 2843 } else { 2844 /* If TSC0 in ethernet mode */ 2845 soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval, 2846 LAST_PORTf, 0); 2847 } 2848 SOC_IF_ERROR_RETURN(WRITE_U0_LED_ACCU_CTRLr(unit, rval)); 2849 2850 /* To initialize M0s for LED or Firmware Link Scan*/ 2851 if (soc_feature(unit, soc_feature_cmicx) && !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) { 2852 /* On Helix5 (iProc 16), M0 is needed to be rest as re-running rc.soc */ 2853 rval = 1; 2854 SOC_IF_ERROR_RETURN(WRITE_U0_M0SS_CONTROLr(unit, rval)); 2855 sal_udelay(10); 2856 SOC_IF_ERROR_RETURN(soc_iproc_m0_init(unit)); 2857 } 2858 return SOC_E_NONE; 2859 } 2860 #endif /* BCM_CMICX_SUPPORT */ 2861 2862 STATIC int 2863 _soc_helix5_misc_init(int unit) 2864 { 2865 soc_control_t *soc; 2866 soc_info_t *si; 2867 soc_mem_t mem; 2868 uint64 rval64; 2869 uint32 entry[SOC_MAX_MEM_WORDS], rval; 2870 soc_pbmp_t pbmp; 2871 int port; 2872 int parity_enable; 2873 modport_map_subport_entry_t map_entry; 2874 soc_field_t fields[2]; 2875 uint32 values[2]; 2876 2877 uint32 mc_ctrl = 0; 2878 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 2879 int num_overlay_ecmp_rh_flowset_entries; 2880 int ecmp_levels = 1; 2881 #endif 2882 int num_lag_rh_flowset_entries; 2883 soc = SOC_CONTROL(unit); 2884 si = &SOC_INFO(unit); 2885 2886 /* Stop the mem scan task before all of the parity init takes place */ 2887 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 2888 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit)); 2889 2890 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 2891 if (parity_enable) { 2892 if (!SOC_WARM_BOOT(unit)) { 2893 /* Certain mems/regs need to be cleared before enabling SER */ 2894 SOC_IF_ERROR_RETURN(soc_trident3_clear_mmu_memory(unit)); 2895 /*SOC_IF_ERROR_RETURN(_soc_helix5_clear_all_port_data(unit));*/ 2896 } 2897 soc_ser_alpm_cache_check(unit); 2898 soc_ser_log_init(unit, NULL, 0); 2899 2900 SOC_IF_ERROR_RETURN(soc_hx5_ser_enable_all(unit, TRUE)); 2901 soc_hx5_ser_register(unit); 2902 2903 /*Initialize chip-specific functions for SER testing*/ 2904 soc_hx5_ser_test_register(unit); 2905 } 2906 2907 SOC_IF_ERROR_RETURN(_soc_trident3_init_mmu_memory(unit)); 2908 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval)); 2909 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, parity_enable ? 1 : 0); 2910 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, REFRESH_ENf, 1); 2911 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 2912 2913 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 2914 SOC_IF_ERROR_RETURN( 2915 _soc_cancun_load_status_clear(unit, CANCUN_SOC_FILE_TYPE_CIH)); 2916 /* Dummy call to clear garbage h/w values */ 2917 SOC_IF_ERROR_RETURN 2918 (soc_helix5_temperature_monitor_get(unit, 2919 COUNTOF(pvtmon_result_reg), 2920 NULL, 2921 NULL)); 2922 } 2923 2924 SOC_IF_ERROR_RETURN(soc_helix5_uft_uat_config(unit)); 2925 SOC_IF_ERROR_RETURN(_soc_helix5_ft_bank_config(unit)); 2926 2927 soc_cancun_init(unit); 2928 _soc_helix5_latency_config(unit); 2929 SOC_IF_ERROR_RETURN(_soc_helix5_port_mapping_init(unit)); 2930 2931 if (!SAL_BOOT_XGSSIM) { 2932 int rv; 2933 soc_port_schedule_state_t *port_schedule_state; 2934 if (soc->tdm_info == NULL) { 2935 soc->tdm_info = sal_alloc(sizeof(_soc_helix5_tdm_temp_t), 2936 "Helix5 TDM info"); 2937 if (soc->tdm_info == NULL) { 2938 return SOC_E_MEMORY; 2939 } 2940 } 2941 port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t), 2942 "Helix5 soc_port_schedule_state_t"); 2943 if (port_schedule_state == NULL) { 2944 return SOC_E_MEMORY; 2945 } 2946 2947 rv = _soc_helix5_tdm_init(unit, port_schedule_state); 2948 2949 sal_free(port_schedule_state); 2950 if (SOC_FAILURE(rv)) { 2951 return rv; 2952 } 2953 } 2954 SOC_IF_ERROR_RETURN(_soc_helix5_idb_init(unit)); 2955 SOC_IF_ERROR_RETURN(_soc_helix5_edb_init(unit)); 2956 2957 sal_memset(entry, 0, sizeof(cpu_pbm_entry_t)); 2958 soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit)); 2959 SOC_IF_ERROR_RETURN 2960 (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry)); 2961 2962 sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t)); 2963 soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit)); 2964 SOC_IF_ERROR_RETURN 2965 (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry)); 2966 2967 #if __GNUC__ > 6 2968 #pragma GCC diagnostic push 2969 #pragma GCC diagnostic ignored "-Wmemset-elt-size" 2970 #endif 2971 /* 2972 * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for 2973 * performance reasons, because the actual soc_mem_field_set() 2974 * will only write sizeof(device_loopback_ports_bitmap_entry_t)=17 2975 * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651 2976 * depending on which devices are compiled in. 2977 */ 2978 sal_memset(entry, 0, sizeof(device_loopback_ports_bitmap_entry_t)); 2979 #if __GNUC__ > 6 2980 #pragma GCC diagnostic pop 2981 #endif 2982 soc_mem_pbmp_field_set(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, entry, BITMAPf, 2983 &PBMP_LB(unit)); 2984 SOC_IF_ERROR_RETURN 2985 (soc_mem_write(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, MEM_BLOCK_ALL, 0, 2986 entry)); 2987 2988 PBMP_LB_ITER(unit, port) { 2989 mem = SOC_MEM_UNIQUE_ACC(unit, MULTIPASS_LOOPBACK_BITMAPm) 2990 [si->port_pipe[port]]; 2991 sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t)); 2992 SOC_PBMP_PORT_SET(pbmp, port); 2993 soc_mem_pbmp_field_set(unit, mem, &entry, BITMAPf, &pbmp); 2994 SOC_IF_ERROR_RETURN 2995 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry)); 2996 } 2997 2998 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 2999 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 3000 PBMP_HG_ITER(unit, port) { 3001 SOC_IF_ERROR_RETURN 3002 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 3003 } 3004 SOC_IF_ERROR_RETURN 3005 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index, 3006 entry)); 3007 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2); 3008 PBMP_LB_ITER(unit, port) { 3009 SOC_IF_ERROR_RETURN 3010 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 3011 } 3012 3013 /* Enable dual hash tables */ 3014 SOC_IF_ERROR_RETURN(soc_trident3_hash_init(unit)); 3015 3016 sal_memset(&map_entry, 0, sizeof(map_entry)); 3017 soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, ENABLEf, 1); 3018 3019 /* my_modid and other modid related initialization */ 3020 PBMP_ALL_ITER(unit, port) { 3021 /* configure logical port numbers */ 3022 soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, 3023 DESTf, port); 3024 SOC_IF_ERROR_RETURN(WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL, 3025 port, &map_entry)); 3026 } 3027 3028 /* setting up my_modid */ 3029 SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64)); 3030 3031 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 3032 MODID_0_VALIDf, 1); 3033 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 3034 MODID_0f, SOC_BASE_MODID(unit)); 3035 3036 SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64)); 3037 3038 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64)); 3039 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3040 L3SRC_HIT_ENABLEf, 1); 3041 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3042 L2DST_HIT_ENABLEf, 1); 3043 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3044 APPLY_EGR_MASK_ON_L2f, 1); 3045 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3046 APPLY_EGR_MASK_ON_L3f, 1); 3047 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3048 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 3049 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3050 ARP_VALIDATION_ENf, 1); 3051 if (soc_feature(unit, soc_feature_port_lag_failover)) { 3052 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3053 IGNORE_HG_HDR_LAG_FAILOVERf, 0); 3054 } else { 3055 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3056 IGNORE_HG_HDR_LAG_FAILOVERf, 1); 3057 } 3058 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 3059 APPLY_HG_MGID_ADJUSTf, 0xFF); 3060 3061 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64)); 3062 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 3063 * causes the outer tag to be removed from packets that don't have 3064 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 3065 */ 3066 /* Programming EGR_VLAN_CONTROL_1m table */ 3067 #if 0 3068 /* Can't call bcm function in soc layer. */ 3069 if (soc_feature(unit, soc_feature_egr_all_profile)) { 3070 PBMP_ALL_ITER(unit, port) { 3071 soc_field_t flds = {VT_MISS_UNTAGf, REMARK_OUTER_DOT1Pf}; 3072 uint32 vals = {0, 1}; 3073 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(unit, 3074 port, EGR_VLAN_CONTROL_1m, flds, vals); 3075 } 3076 } 3077 #endif 3078 3079 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 3080 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 3081 SOC_PBMP_REMOVE(pbmp, PBMP_FAE_ALL(unit)); 3082 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 3083 MEM_BLOCK_ANY, 0, &entry)); 3084 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, 3085 &pbmp); 3086 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 3087 MEM_BLOCK_ANY, 0, &entry)); 3088 3089 /* Multicast range initialization */ 3090 SOC_IF_ERROR_RETURN 3091 (soc_hbx_higig2_mcast_sizes_set(unit, 3092 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 3093 SOC_HBX_MULTICAST_RANGE_DEFAULT), 3094 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 3095 soc_mem_index_count(unit, L2MCm)), 3096 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 3097 soc_mem_index_count(unit, L3_IPMCm)))); 3098 3099 soc->mcast_size = soc_property_get(unit, spn_MULTICAST_L2_RANGE, 3100 soc_mem_index_count(unit, L2MCm)); 3101 soc->ipmc_size = soc_property_get(unit, spn_MULTICAST_L3_RANGE, 3102 soc_mem_index_count(unit, L3_IPMCm)); 3103 3104 SOC_IF_ERROR_RETURN(READ_MC_CONTROL_4r(unit, &mc_ctrl)); 3105 3106 soc_reg_field_set(unit, MC_CONTROL_4r, &mc_ctrl, 3107 ALLOW_IPMC_INDEX_WRAP_AROUNDf, 1); 3108 SOC_IF_ERROR_RETURN 3109 (WRITE_MC_CONTROL_4r(unit, mc_ctrl)); 3110 3111 3112 _phy_tsce_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set; 3113 _phy_tscf_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set; 3114 3115 /* Check if Hierarchical ECMP mode is set */ 3116 if (soc_property_get(unit, spn_L3_ECMP_LEVELS, 1) == 2) { 3117 uint32 rval = 0; 3118 uint32 ecmp_mode = 1; 3119 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode); 3120 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 3121 } else { 3122 uint32 rval = 0; 3123 uint32 ecmp_mode = 0; 3124 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode); 3125 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 3126 3127 } 3128 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr, 3129 REG_PORT_ANY, ECMP_FLOWSET_TABLE_CONFIGf, 1)); 3130 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 3131 ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1); 3132 if ((soc_feature(unit, soc_feature_riot) || 3133 soc_feature(unit, soc_feature_multi_level_ecmp)) && 3134 (ecmp_levels > 1) && soc_mem_index_count(unit,RH_ECMP_FLOWSETm)) { 3135 3136 num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit, 3137 spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0); 3138 3139 if (SOC_FIELD_RANGE_CHECK( 3140 num_overlay_ecmp_rh_flowset_entries, 0, 16384)) { 3141 num_overlay_ecmp_rh_flowset_entries = 16384; 3142 } 3143 3144 switch (num_overlay_ecmp_rh_flowset_entries) { 3145 case 0: 3146 break; 3147 case 16384: 3148 if (soc_mem_index_count(unit,RH_ECMP_FLOWSETm) >= 16384) { 3149 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 3150 ENHANCED_HASHING_CONTROLr, 3151 REG_PORT_ANY, 3152 ECMP_FLOWSET_TABLE_CONFIGf, 2)); 3153 } else { 3154 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 3155 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 3156 FUNCTION_NAME(), 3157 soc_mem_index_count(unit,RH_ECMP_FLOWSETm), 3158 num_overlay_ecmp_rh_flowset_entries)); 3159 return SOC_E_CONFIG; 3160 } 3161 break; 3162 default: 3163 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 3164 "%s: Value for overlay RH entries is not correct : %d \n"), 3165 FUNCTION_NAME(), num_overlay_ecmp_rh_flowset_entries)); 3166 return SOC_E_CONFIG; 3167 } 3168 } 3169 #endif 3170 3171 /* Setup SW2_IFP_DST_ACTION_CONTROLr */ 3172 fields[0] = HGTRUNK_RES_ENf; 3173 values[0] = 1; 3174 fields[1] = LAG_RES_ENf; 3175 values[1] = 1; 3176 SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, 3177 SW2_IFP_DST_ACTION_CONTROLr, REG_PORT_ANY, 2, fields, values)); 3178 3179 /* Enhanced hashing LAG/TRUNK config 3180 * LAG/TRUNK share the same flow set table used in RH 3181 * 32k is shared between LAG and HGT for 3182 * - 16k each - default 3183 * - 32K dedicated to HGT RH 3184 * - 32K dedicated to LAG RH 3185 */ 3186 num_lag_rh_flowset_entries = soc_property_get(unit, 3187 spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 16384); 3188 3189 switch (num_lag_rh_flowset_entries) { 3190 case 0: 3191 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 3192 ENHANCED_HASHING_CONTROL_2r, 3193 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 3194 1)); 3195 break; 3196 case 32768: 3197 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 3198 ENHANCED_HASHING_CONTROL_2r, 3199 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 3200 0)); 3201 break; 3202 case 16384: 3203 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 3204 ENHANCED_HASHING_CONTROL_2r, 3205 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 3206 2)); 3207 break; 3208 default: 3209 return SOC_E_CONFIG; 3210 } 3211 SOC_IF_ERROR_RETURN 3212 (soc_counter_tomahawk_status_enable(unit, TRUE)); 3213 3214 #ifdef BCM_CMICX_SUPPORT 3215 if (soc_feature(unit, soc_feature_cmicx) && 3216 !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) 3217 { 3218 SOC_IF_ERROR_RETURN(_soc_hx5_ledup_init(unit)); 3219 } 3220 #endif /* BCM_CMICX_SUPPORT */ 3221 3222 LOG_VERBOSE(BSL_LS_SOC_COMMON, 3223 (BSL_META_U(unit, 3224 "MISC Init completed (u=%d)\n"), unit)); 3225 3226 /* Mem Scan thread start should be the last step in Misc init */ 3227 if (parity_enable) { 3228 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 3229 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit)); 3230 } 3231 3232 return SOC_E_NONE; 3233 } 3234 3235 /* 3236 * Function used for global resource reservation (MCQE / RQE / Buf cell). 3237 * Input state: Total hardware resource. 3238 * Output state: Resource available for admission control. 3239 */ 3240 STATIC void 3241 _soc_hx5_mmu_config_dev_reserve(int unit, _soc_mmu_device_info_t *devcfg, 3242 int lossless) 3243 { 3244 int port, pm, asf_rsvd = 0; 3245 uint32 total_mcq = 0, num_ports = 0; 3246 uint32 cpu_cnt = 1, lb_cnt = 2, mgmt_cnt = 1; 3247 soc_info_t *si = &SOC_INFO(unit); 3248 3249 /* Device reservation for RQE Entry */ 3250 devcfg->total_rqe_queue_entry -= _HX5_MMU_RQE_ENTRY_RSVD_PER_XPE; 3251 3252 /* Device reservation for MCQ Entry - 6 entries for each MC queue */ 3253 if (si->flex_eligible) { 3254 for (pm = 0; pm < _HX5_PBLKS_PER_DEV(unit); pm++) { 3255 num_ports += soc_hx5_ports_per_pm_get(unit, pm); 3256 } 3257 total_mcq += (num_ports * SOC_HX5_NUM_MCAST_QUEUE_PER_PORT); 3258 } else { 3259 PBMP_ALL_ITER(unit, port) { 3260 if (IS_CPU_PORT(unit, port) || 3261 IS_LB_PORT(unit,port) || 3262 IS_MGMT_PORT(unit,port)) { 3263 continue; 3264 } 3265 total_mcq += si->port_num_cosq[port]; 3266 } 3267 } 3268 total_mcq += ((cpu_cnt * SOC_HX5_NUM_CPU_QUEUES) + 3269 (lb_cnt + mgmt_cnt) * SOC_HX5_NUM_MCAST_QUEUE_PER_PORT); 3270 3271 devcfg->total_mcq_entry -= ((total_mcq * _HX5_MCQE_RSVD_PER_MCQ) + 3272 _HX5_TDM_MCQE_RSVD_OVERSHOOT); 3273 3274 devcfg->mmu_total_cell -= asf_rsvd; 3275 } 3276 3277 STATIC void 3278 _soc_hx5_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg, 3279 int lossless) 3280 { 3281 if (devcfg == NULL) { 3282 LOG_FATAL(BSL_LS_SOC_COMMON, 3283 (BSL_META_U(unit, 3284 "MMU config data error\ 3285 (u=%d)\n"), unit)); 3286 return; 3287 } 3288 sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t)); 3289 3290 devcfg->max_pkt_byte = _HX5_MMU_MAX_PACKET_BYTES; 3291 devcfg->mmu_hdr_byte = _HX5_MMU_PACKET_HEADER_BYTES; 3292 devcfg->jumbo_pkt_size = _HX5_MMU_JUMBO_FRAME_BYTES; 3293 devcfg->default_mtu_size = _HX5_MMU_DEFAULT_MTU_BYTES; 3294 devcfg->mmu_cell_size = _HX5_MMU_BYTES_PER_CELL; 3295 devcfg->mmu_total_cell = _HX5_MMU_TOTAL_CELLS_PER_XPE; 3296 devcfg->num_pg = _HX5_MMU_NUM_PG; 3297 devcfg->num_service_pool = _HX5_MMU_NUM_POOL; 3298 devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN | 3299 SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY; 3300 devcfg->total_mcq_entry = _HX5_MMU_TOTAL_MCQ_ENTRY(unit); 3301 devcfg->rqe_queue_num = 11; 3302 devcfg->total_rqe_queue_entry = _HX5_MMU_TOTAL_RQE_ENTRY(unit); 3303 3304 _soc_hx5_mmu_config_dev_reserve(unit, devcfg, lossless); 3305 } 3306 3307 STATIC void 3308 _soc_hx5_mmu_sw_info_config (int unit, _soc_hx5_mmu_sw_config_info_t * swcfg, 3309 int lossless) 3310 { 3311 /* Default settings is lossless */ 3312 swcfg->mmu_egr_queue_min = 0; 3313 swcfg->mmu_egr_qgrp_min = 0; 3314 swcfg->mmu_total_pri_groups = 8; 3315 swcfg->mmu_active_pri_groups = 1; 3316 swcfg->mmu_pg_min = 7; 3317 swcfg->mmu_port_min = 0; 3318 swcfg->mmu_mc_egr_qentry_min = 4; 3319 swcfg->mmu_rqe_qentry_min = 8; 3320 swcfg->mmu_rqe_queue_min = 7; 3321 if (lossless == 0) 3322 { 3323 swcfg->mmu_egr_queue_min = 7; 3324 swcfg->mmu_egr_qgrp_min = 14; 3325 swcfg->mmu_pg_min = 0; 3326 } 3327 } 3328 3329 STATIC int 3330 _soc_hx5_default_pg_headroom(int unit, soc_port_t port, 3331 int lossless) 3332 { 3333 int speed = 1000, hdrm = 0; 3334 uint8 port_oversub = 0; 3335 3336 if (IS_CPU_PORT(unit, port)) { 3337 return 69; 3338 } else if (!lossless) { 3339 return 0; 3340 } else if (IS_LB_PORT(unit, port)) { 3341 return 160; 3342 } 3343 3344 speed = SOC_INFO(unit).port_speed_max[port]; 3345 3346 if (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port)) { 3347 port_oversub = 1; 3348 } 3349 if (speed <= 1000) { 3350 hdrm = 118; 3351 } else if (speed == 2500) { 3352 hdrm = 120; 3353 }else if ((speed > 2500) && (speed <= 11000)) { 3354 hdrm = port_oversub ? 194 : 160; 3355 } else if ((speed > 11000) && (speed <= 21000)) { 3356 hdrm = port_oversub ? 251 : 197; 3357 } else if ((speed > 21000) && (speed <= 27000)) { 3358 hdrm = port_oversub ? 308 : 254; 3359 } else if ((speed > 27000) && (speed <= 42000)) { 3360 hdrm = port_oversub ? 402 : 273; 3361 } else if ((speed > 42000) && (speed <= 53000)) { 3362 hdrm = port_oversub ? 431 : 350; 3363 } else if (speed >= 100000) { 3364 hdrm = port_oversub ? 766 : 572; 3365 } else { 3366 hdrm = port_oversub ? 194 : 160; 3367 } 3368 return hdrm; 3369 } 3370 3371 /* 3372 * Default phase_1 MMU settings about headroom, guarantee, dynamic, color, ... 3373 * which depend on single port/queue/qgroup/pg... 3374 * Input state: Available for admission in devcfg, configured swcfg. 3375 * Output state: Independent data filled in buf. 3376 * Version 1.1 3377 */ 3378 STATIC void 3379 _soc_hx5_mmu_config_buf_phase1(int unit, _soc_mmu_cfg_buf_t *buf, 3380 _soc_mmu_device_info_t *devcfg, 3381 _soc_hx5_mmu_sw_config_info_t *swcfg, 3382 int lossless) 3383 { 3384 soc_info_t *si; 3385 _soc_mmu_cfg_buf_pool_t *buf_pool; 3386 _soc_mmu_cfg_buf_port_t *buf_port; 3387 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 3388 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 3389 _soc_mmu_cfg_buf_queue_t *buf_queue; 3390 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 3391 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 3392 int max_packet_cells, default_mtu_cells; 3393 int port, idx; 3394 int total_pool_size = 0, asf_rsvd = 0; 3395 int rqe_entry_shared_total, qmin; 3396 3397 si = &SOC_INFO(unit); 3398 3399 LOG_VERBOSE(BSL_LS_SOC_COMMON, 3400 (BSL_META_U(unit, 3401 "Initializing default MMU config phase 1(u=%d)\n"), unit)); 3402 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 3403 devcfg->mmu_hdr_byte, 3404 devcfg->mmu_cell_size); 3405 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 3406 devcfg->mmu_hdr_byte, 3407 devcfg->mmu_cell_size); 3408 3409 total_pool_size = devcfg->mmu_total_cell + asf_rsvd; /* Add back ASF reserved. */ 3410 3411 buf->headroom = max_packet_cells; /* 1 packet per pipe. */ 3412 3413 rqe_entry_shared_total = devcfg->total_rqe_queue_entry - 3414 (_HX5_MMU_NUM_RQE_QUEUES * swcfg->mmu_rqe_qentry_min); 3415 3416 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 3417 buf_pool = &buf->pools[idx]; 3418 if (idx == 0) { /* 100% scale up by 100 */ 3419 buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 3420 buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 3421 buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 3422 buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 3423 buf_pool->total_rqe_entry = rqe_entry_shared_total; 3424 } else { 3425 buf_pool->size = 0; 3426 buf_pool->yellow_size = 0; 3427 buf_pool->red_size = 0; 3428 buf_pool->total_mcq_entry = 0; 3429 buf_pool->total_rqe_entry = 0; 3430 } 3431 } 3432 3433 for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) { 3434 queue_grp = &buf->qgroups[idx]; 3435 /* resume limits - accounted for 8 cell granularity */ 3436 queue_grp->pool_resume = 16; 3437 queue_grp->yellow_resume = 16; 3438 queue_grp->red_resume = 16; 3439 queue_grp->guarantee = swcfg->mmu_egr_qgrp_min; 3440 if (lossless) { 3441 queue_grp->discard_enable = 0; 3442 } else { 3443 queue_grp->discard_enable = 1; 3444 } 3445 } 3446 3447 PBMP_ALL_ITER(unit, port) { 3448 if (port >= SOC_MMU_CFG_PORT_MAX) { 3449 break; 3450 } 3451 buf_port = &buf->ports[port]; 3452 3453 /* internal priority to priority group mapping */ 3454 for (idx = 0; idx < _HX5_MMU_NUM_INT_PRI; idx++) { 3455 buf_port->pri_to_prigroup[idx] = 7; 3456 } 3457 3458 /* priority group to pool mapping */ 3459 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 3460 buf_port->prigroups[idx].pool_idx = 0; 3461 } 3462 3463 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 3464 buf_port_pool = &buf_port->pools[idx]; 3465 buf_port_pool->guarantee = 0; 3466 buf_port_pool->pool_limit = 0; 3467 buf_port_pool->pool_resume = 0; 3468 if (idx == 0) { 3469 buf_port_pool->pool_limit = total_pool_size; 3470 buf_port_pool->pool_resume = total_pool_size - 3471 (default_mtu_cells * 2); 3472 } 3473 } 3474 3475 buf_port->pkt_size = max_packet_cells; 3476 3477 /* priority group */ 3478 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 3479 buf_prigroup = &buf_port->prigroups[idx]; 3480 buf_prigroup->guarantee = 0; 3481 buf_prigroup->user_delay = -1; 3482 buf_prigroup->switch_delay = -1; 3483 buf_prigroup->pkt_size = max_packet_cells; 3484 buf_prigroup->device_headroom_enable = 0; 3485 buf_prigroup->pool_floor = 0; 3486 buf_prigroup->headroom = 0; 3487 buf_prigroup->pool_resume = 0; 3488 buf_prigroup->flow_control_enable = 0; 3489 if (idx == 7) { 3490 buf_prigroup->device_headroom_enable = 1; 3491 buf_prigroup->flow_control_enable = lossless; 3492 buf_prigroup->headroom = 3493 _soc_hx5_default_pg_headroom(unit, port, lossless); 3494 if (lossless) { 3495 buf_prigroup->guarantee = swcfg->mmu_pg_min; 3496 } 3497 } 3498 } 3499 3500 /* multicast queue */ 3501 if (IS_CPU_PORT(unit, port) || 3502 IS_LB_PORT(unit,port)) { 3503 qmin = swcfg->mmu_egr_queue_min; 3504 } else { 3505 qmin = 0; 3506 } 3507 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 3508 buf_queue = &buf_port->queues[idx]; 3509 buf_queue->qgroup_id = -1; 3510 buf_queue->guarantee = qmin; 3511 buf_queue->mcq_entry_guarantee = swcfg->mmu_mc_egr_qentry_min; 3512 buf_queue->color_discard_enable = 0; 3513 if (lossless) { 3514 buf_queue->discard_enable = 0; 3515 /* resume limits - accounted for 8 cell granularity */ 3516 buf_queue->pool_resume = 16; 3517 } else { 3518 buf_queue->discard_enable = 1; 3519 /* resume limits - accounted for 8 cell granularity */ 3520 buf_queue->pool_resume = 16; 3521 } 3522 } 3523 3524 /* unicast queue */ 3525 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 3526 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 3527 buf_queue->qgroup_id = -1; 3528 buf_queue->guarantee = 0; 3529 buf_queue->color_discard_enable = 0; 3530 buf_queue->qgroup_min_enable = 1; 3531 buf_queue->discard_enable = 1; 3532 buf_queue->qgroup_id = 0; 3533 if (lossless) { 3534 buf_queue->discard_enable = 0; 3535 /* resume limits - accounted for 8 cell granularity */ 3536 buf_queue->pool_resume = 16; 3537 buf_queue->yellow_resume = 16; 3538 buf_queue->red_resume = 16; 3539 } else { 3540 /* resume limits - accounted for 8 cell granularity */ 3541 buf_queue->pool_resume = 16; 3542 buf_queue->yellow_resume = 16; 3543 buf_queue->red_resume = 16; 3544 } 3545 } 3546 3547 /* queue to pool mapping */ 3548 for (idx = 0; 3549 idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) { 3550 buf_port->queues[idx].pool_idx = 0; 3551 } 3552 } 3553 3554 /* RQE */ 3555 for (idx = 0; idx < _HX5_MMU_NUM_RQE_QUEUES; idx++) { 3556 buf_rqe_queue = &buf->rqe_queues[idx]; 3557 buf_rqe_queue->pool_idx = 0; 3558 buf_rqe_queue->guarantee = swcfg->mmu_rqe_queue_min; 3559 if (lossless) { 3560 buf_rqe_queue->discard_enable = 0; 3561 } else { 3562 buf_rqe_queue->discard_enable = 1; 3563 } 3564 } 3565 } 3566 3567 /* 3568 * Default phase_2 MMU settings about shared buffer limit, which depends on 3569 * guaranteed/headroom buffers on all port/queue/qgroup/pg/... 3570 * Input state: _soc_mmu_cfg_buf_calculate processed buf. 3571 * Output state: All necessary data filled in buf. 3572 * Version 1.1 3573 */ 3574 STATIC void 3575 _soc_hx5_mmu_config_buf_phase2(int unit, _soc_mmu_cfg_buf_t *buf, 3576 _soc_mmu_device_info_t *devcfg, 3577 _soc_hx5_mmu_sw_config_info_t *swcfg, 3578 int lossless) 3579 { 3580 soc_info_t *si; 3581 _soc_mmu_cfg_buf_pool_t *buf_pool; 3582 _soc_mmu_cfg_buf_port_t *buf_port; 3583 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 3584 _soc_mmu_cfg_buf_queue_t *buf_queue; 3585 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 3586 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 3587 int port, idx, pm, ports[3] = {0}; 3588 int pg_hdrm_ob[] = {690, 372, 240}; /* PG headroom of 1/2/4-port PortMacro */ 3589 int total_pool_size = 0; 3590 int ing_rsvd_total = 0, egr_rsvd_total = 0; 3591 int ing_shared_total, egr_shared_total; 3592 int total_rsvd_qmin = 0; 3593 uint32 color_limit = 0; 3594 uint32 num_ports = 0, mgmt_cnt = 0, cpu_cnt = 0, lb_cnt = 0; 3595 uint32 cpu_hdrm = 0, lb_hdrm = 0, mgmt_hdrm = 0; 3596 3597 si = &SOC_INFO(unit); 3598 3599 LOG_VERBOSE(BSL_LS_SOC_COMMON, 3600 (BSL_META_U(unit, 3601 "Initializing default MMU config phase 2(u=%d)\n"), unit)); 3602 3603 buf_pool = &buf->pools[0]; 3604 total_pool_size = devcfg->mmu_total_cell; /* per XPE limit */ 3605 total_rsvd_qmin = swcfg->mmu_egr_queue_min * (SOC_HX5_NUM_CPU_QUEUES + 3606 _HX5_MMU_NUM_LBK_QUEUES ); 3607 3608 PBMP_ALL_ITER(unit, port) { 3609 if (IS_CPU_PORT(unit, port)) { 3610 cpu_cnt++; 3611 cpu_hdrm = _soc_hx5_default_pg_headroom(unit, port, lossless); 3612 } else if (IS_LB_PORT(unit,port)) { 3613 lb_cnt++; 3614 lb_hdrm = _soc_hx5_default_pg_headroom(unit, port, lossless); 3615 } else { 3616 num_ports++; 3617 } 3618 } 3619 if (si->flex_eligible) { 3620 num_ports = 0; 3621 for (pm = 0; pm < _HX5_PBLKS_PER_DEV(unit); pm++) { 3622 port = soc_hx5_ports_per_pm_get(unit, pm); 3623 if (port == 1) { 3624 ports[0]++; 3625 } else if (port == 2) { 3626 ports[1]++; 3627 } else if ((port == 4) || (port == 3)) { 3628 ports[2]++; 3629 port = 4; 3630 } 3631 num_ports += port; 3632 } 3633 3634 if (lossless) { 3635 ing_rsvd_total += (buf->headroom + 3636 swcfg->mmu_active_pri_groups*( 3637 ports[0]*pg_hdrm_ob[0] + 2*ports[1]*pg_hdrm_ob[1] + 3638 4*ports[2]*pg_hdrm_ob[2] + cpu_cnt*cpu_hdrm + lb_cnt*lb_hdrm) + 3639 swcfg->mmu_pg_min*swcfg->mmu_active_pri_groups*( 3640 num_ports + cpu_cnt + lb_cnt + mgmt_cnt) + 3641 swcfg->mmu_port_min*swcfg->mmu_active_pri_groups*( 3642 num_ports + cpu_cnt + lb_cnt + mgmt_cnt)); 3643 /* Management port is not included during Total PG 3644 * headroom calculation */ 3645 buf_pool->prigroup_headroom -= mgmt_hdrm; 3646 } else { 3647 ing_rsvd_total += buf->headroom + cpu_hdrm; 3648 } 3649 } else { 3650 if (lossless) { 3651 /* Management port is not included during Total PG 3652 * headroom calculation */ 3653 buf_pool->prigroup_headroom -= mgmt_hdrm; 3654 } 3655 ing_rsvd_total += (buf->headroom + buf_pool->prigroup_headroom + 3656 buf_pool->prigroup_guarantee); 3657 } 3658 3659 egr_rsvd_total += total_rsvd_qmin + 3660 ((num_ports + mgmt_cnt) * swcfg->mmu_egr_qgrp_min) + 3661 (swcfg->mmu_rqe_queue_min * _HX5_MMU_NUM_RQE_QUEUES); 3662 3663 if (lossless) { 3664 ing_rsvd_total += egr_rsvd_total; 3665 } 3666 3667 buf_pool->total_mcq_entry = _HX5_MMU_TOTAL_MCQ_ENTRY(unit) - 3668 (_HX5_MAX_MMU_MCQE_PER_XPE * _HX5_MCQE_RSVD_PER_MCQ) - 3669 _HX5_TDM_MCQE_RSVD_OVERSHOOT; 3670 3671 buf_pool->mcq_entry_reserved = _HX5_MAX_MMU_MCQE_PER_XPE * 4; 3672 3673 3674 ing_shared_total = total_pool_size - ing_rsvd_total; 3675 egr_shared_total = total_pool_size - egr_rsvd_total; 3676 3677 swcfg->ing_shared_total = ing_shared_total; 3678 swcfg->egr_shared_total = egr_shared_total; 3679 3680 LOG_VERBOSE(BSL_LS_SOC_MMU, 3681 (BSL_META_U(unit, 3682 "MMU config: Total Shared size: ingress %d egress %d\n"), 3683 ing_shared_total, egr_shared_total)); 3684 3685 color_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 3686 3687 for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) { 3688 queue_grp = &buf->qgroups[idx]; 3689 if (lossless) { 3690 queue_grp->pool_scale = -1; 3691 queue_grp->pool_limit = egr_shared_total; 3692 queue_grp->red_limit = egr_shared_total; 3693 queue_grp->yellow_limit = egr_shared_total; 3694 } else { 3695 queue_grp->pool_scale = 8; 3696 queue_grp->pool_limit = 0; 3697 queue_grp->red_limit = color_limit; 3698 queue_grp->yellow_limit = color_limit; 3699 } 3700 } 3701 3702 PBMP_ALL_ITER(unit, port) { 3703 if (port >= SOC_MMU_CFG_PORT_MAX) { 3704 break; 3705 } 3706 buf_port = &buf->ports[port]; 3707 3708 /* priority group */ 3709 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 3710 buf_prigroup = &buf_port->prigroups[idx]; 3711 buf_prigroup->pool_limit = 0; 3712 buf_prigroup->pool_scale = -1; 3713 if (idx == 7) { 3714 if (lossless) { 3715 buf_prigroup->pool_scale = 8; 3716 } else { 3717 buf_prigroup->pool_limit = ing_shared_total; 3718 } 3719 } 3720 } 3721 3722 /* multicast queue */ 3723 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 3724 buf_queue = &buf_port->queues[idx]; 3725 if (lossless) { 3726 buf_queue->pool_scale = -1; 3727 buf_queue->pool_limit = egr_shared_total; 3728 buf_queue->yellow_limit = egr_shared_total; 3729 buf_queue->red_limit = egr_shared_total; 3730 } else { 3731 buf_queue->pool_scale = 8; 3732 buf_queue->pool_limit = 0; 3733 buf_queue->yellow_limit = color_limit; 3734 buf_queue->red_limit = color_limit; 3735 } 3736 } 3737 3738 /* unicast queue */ 3739 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 3740 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 3741 if (lossless) { 3742 buf_queue->pool_scale = -1; 3743 buf_queue->pool_limit = egr_shared_total; 3744 buf_queue->red_limit = egr_shared_total; 3745 buf_queue->yellow_limit = egr_shared_total; 3746 } else { 3747 buf_queue->pool_scale = 8; 3748 buf_queue->pool_limit = 0; 3749 buf_queue->red_limit = color_limit; 3750 buf_queue->yellow_limit = color_limit; 3751 } 3752 } 3753 } 3754 3755 /* RQE */ 3756 for (idx = 0; idx < _HX5_MMU_NUM_RQE_QUEUES; idx++) { 3757 buf_rqe_queue = &buf->rqe_queues[idx]; 3758 if (lossless) { 3759 buf_rqe_queue->pool_scale = -1; 3760 buf_rqe_queue->pool_limit = egr_shared_total; 3761 buf_rqe_queue->red_limit = egr_shared_total; 3762 buf_rqe_queue->yellow_limit = egr_shared_total; 3763 } else { 3764 buf_rqe_queue->pool_scale = 8; 3765 buf_rqe_queue->pool_limit = 0; 3766 buf_rqe_queue->red_limit = color_limit; 3767 buf_rqe_queue->yellow_limit = color_limit; 3768 } 3769 } 3770 } 3771 3772 STATIC int 3773 _soc_hx5_pool_scale_to_limit(int size, int scale) 3774 { 3775 int factor = 1000; 3776 3777 switch (scale) { 3778 case 7: factor = 875; break; 3779 case 6: factor = 750; break; 3780 case 5: factor = 625; break; 3781 case 4: factor = 500; break; 3782 case 3: factor = 375; break; 3783 case 2: factor = 250; break; 3784 case 1: factor = 125; break; 3785 case 0: 3786 default: 3787 factor = 1000; break; 3788 } 3789 return (size * factor)/1000; 3790 } 3791 3792 STATIC int 3793 _soc_hx5_mmu_config_buf_set_hw_port(int unit, int port, _soc_mmu_cfg_buf_t *buf, 3794 _soc_mmu_device_info_t *devcfg, int lossless, 3795 _soc_hx5_mmu_sw_config_info_t *swcfg) 3796 { 3797 soc_info_t *si; 3798 _soc_mmu_cfg_buf_pool_t *buf_pool; 3799 _soc_mmu_cfg_buf_port_t *buf_port; 3800 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 3801 thdi_port_sp_config_entry_t thdi_sp_config; 3802 thdi_port_pg_config_entry_t pg_config_mem; 3803 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 3804 _soc_mmu_cfg_buf_queue_t *buf_queue; 3805 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 3806 soc_reg_t reg = INVALIDr; 3807 soc_mem_t mem0, mem1, mem2, mem3; 3808 uint32 fval, rval; 3809 int base, numq, enable; 3810 int idx, midx, pri, index1; 3811 int default_mtu_cells, limit, rlimit; 3812 int pipe; 3813 3814 static const soc_mem_t mmu_thdi_port_mem[] = { 3815 THDI_PORT_SP_CONFIGm, 3816 THDI_PORT_PG_CONFIGm 3817 }; 3818 static const soc_mem_t mmu_thdo_q_uc_mem[] = { 3819 MMU_THDU_CONFIG_QUEUEm, 3820 MMU_THDU_OFFSET_QUEUEm, 3821 MMU_THDU_Q_TO_QGRP_MAPm 3822 }; 3823 static const soc_mem_t mmu_thdo_port_uc_mem[] = { 3824 MMU_THDU_CONFIG_PORTm, 3825 MMU_THDU_RESUME_PORTm 3826 }; 3827 static const soc_mem_t mmu_thdo_q_mc_mem[] = { 3828 MMU_THDM_DB_QUEUE_CONFIGm, 3829 MMU_THDM_DB_QUEUE_OFFSETm, 3830 MMU_THDM_MCQE_QUEUE_CONFIGm, 3831 MMU_THDM_MCQE_QUEUE_OFFSETm 3832 }; 3833 3834 static const soc_mem_t mmu_thdo_port_mc_mem[] = { 3835 MMU_THDM_DB_PORTSP_CONFIGm, 3836 MMU_THDM_MCQE_PORTSP_CONFIGm 3837 }; 3838 3839 static const soc_field_t prigroup_reg[] = { 3840 THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r 3841 }; 3842 static const soc_field_t prigroup_field[] = { 3843 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 3844 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 3845 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 3846 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 3847 }; 3848 static const soc_field_t prigroup_spid_field[] = { 3849 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 3850 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 3851 }; 3852 3853 si = &SOC_INFO(unit); 3854 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 3855 devcfg->mmu_hdr_byte, 3856 devcfg->mmu_cell_size); 3857 3858 /* internal priority to priority group mapping */ 3859 buf_port = &buf->ports[port]; 3860 3861 for (idx = 0; idx < COUNTOF(prigroup_field); idx++) { 3862 if (idx % 8 == 0) { /* 8 fields per register */ 3863 reg = prigroup_reg[idx / 8]; 3864 rval = 0; 3865 } 3866 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 3867 buf_port->pri_to_prigroup[idx]); 3868 if (idx % 8 == 7) { /* 8 fields per register */ 3869 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 3870 } 3871 } 3872 3873 /* Input port per port settings */ 3874 pipe = si->port_pipe[port]; 3875 buf_port = &buf->ports[port]; 3876 rval = 0; 3877 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 3878 soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval, 3879 prigroup_spid_field[idx], 3880 buf_port->prigroups[idx].pool_idx); 3881 } 3882 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval)); 3883 3884 /* Per port per pool settings */ 3885 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[0])[pipe]; 3886 if (mem0 != INVALIDm) { 3887 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 3888 buf_port_pool = &buf_port->pools[idx]; 3889 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[0], 3890 idx); 3891 sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config)); 3892 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 3893 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee); 3894 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 3895 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume); 3896 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 3897 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit); 3898 SOC_IF_ERROR_RETURN 3899 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 3900 midx, &thdi_sp_config)); 3901 } 3902 } 3903 3904 fval = 0; 3905 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 3906 if (buf_port->prigroups[idx].flow_control_enable != 0) { 3907 for (pri=0; pri < 16; pri++) { 3908 if (buf_port->pri_to_prigroup[pri] == idx) { 3909 fval |= 1 << pri; 3910 } 3911 } 3912 } 3913 } 3914 3915 rval = 0; 3916 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 3917 INPUT_PORT_RX_ENABLEf, 1); 3918 if (port == CMIC_PORT (unit)) { 3919 fval = 0; 3920 } 3921 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 3922 PORT_PRI_XON_ENABLEf, fval); 3923 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 3924 PORT_PAUSE_ENABLEf, fval ? 1 : 0); 3925 SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, 3926 port, rval)); 3927 3928 rval = 0; 3929 soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 3930 PORT_MAX_PKT_SIZEf, buf_port->pkt_size); 3931 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval)); 3932 3933 /* Input port per port per priority group settings */ 3934 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[1])[pipe]; 3935 if (mem1 != INVALIDm) { 3936 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 3937 buf_prigroup = &buf->ports[port].prigroups[idx]; 3938 3939 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[1], 3940 idx); 3941 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 3942 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3943 PG_MIN_LIMITf, buf_prigroup->guarantee); 3944 3945 if (buf_prigroup->pool_scale != -1) { 3946 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3947 PG_SHARED_DYNAMICf, 1); 3948 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3949 PG_SHARED_LIMITf, 3950 buf_prigroup->pool_scale); 3951 } else { 3952 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3953 PG_SHARED_LIMITf, 3954 buf_prigroup->pool_limit); 3955 } 3956 3957 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3958 PG_GBL_HDRM_ENf, 3959 buf_prigroup->device_headroom_enable); 3960 if (!IS_FAE_PORT(unit, port)) { 3961 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3962 PG_HDRM_LIMITf, buf_prigroup->headroom); 3963 3964 soc_mem_field32_set(unit, mem1, &pg_config_mem, PG_RESET_OFFSETf, 3965 0); 3966 3967 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3968 PG_RESET_FLOORf, buf_prigroup->pool_floor); 3969 } 3970 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, midx, 3971 &pg_config_mem)); 3972 } 3973 } 3974 3975 /*********************************** 3976 * THDO 3977 */ 3978 /* Output port per port per queue setting for regular multicast queue */ 3979 pipe = si->port_pipe[port]; 3980 numq = si->port_num_cosq[port]; 3981 base = si->port_cosq_base[port]; 3982 3983 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[0])[pipe]; 3984 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[1])[pipe]; 3985 if ((numq != 0) && (mem0 != INVALIDm) && (mem1 != INVALIDm)) { 3986 for (idx = 0; idx < numq; idx++) { 3987 buf_queue = &buf->ports[port].queues[idx]; 3988 3989 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 3990 3991 soc_mem_field32_set(unit, mem0, entry0, Q_MIN_LIMITf, 0); 3992 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_ENABLEf, 1); 3993 soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_DYNAMICf, 1); 3994 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMICf, 1); 3995 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHAf, 8); 3996 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMITf, 8); 3997 soc_mem_field32_set(unit, mem0, entry0, Q_SPIDf, 0); 3998 3999 SOC_IF_ERROR_RETURN 4000 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 4001 4002 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_entry_t)); 4003 4004 soc_mem_field32_set(unit, mem1, entry0, RESUME_OFFSETf, 2); 4005 soc_mem_field32_set(unit, mem1, entry0, 4006 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 4007 soc_mem_field32_set(unit, mem1, entry0, 4008 RED_RESUME_OFFSET_PROFILE_SELf, 0); 4009 SOC_IF_ERROR_RETURN 4010 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry0)); 4011 4012 rval = 0; 4013 SOC_IF_ERROR_RETURN( 4014 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 4015 2)); 4016 4017 rval = 0; 4018 SOC_IF_ERROR_RETURN( 4019 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 4020 2)); 4021 } 4022 } 4023 4024 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[2])[pipe]; 4025 mem3 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[3])[pipe]; 4026 if ((numq != 0) && (mem2 != INVALIDm) && (mem3 != INVALIDm)) { 4027 for (idx = 0; idx < numq; idx++) { 4028 buf_queue = &buf->ports[port].queues[idx]; 4029 buf_pool = &buf->pools[buf_queue->pool_idx]; 4030 if (buf_pool->total == 0) { 4031 continue; 4032 } 4033 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 4034 4035 soc_mem_field32_set(unit, mem2, entry0, Q_MIN_LIMITf, 1); 4036 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 4037 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_DYNAMICf, 1); 4038 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_DYNAMICf, 1); 4039 soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_ALPHAf, 8); 4040 soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_LIMITf, 8); 4041 soc_mem_field32_set(unit, mem2, entry0, Q_SPIDf, 0); 4042 4043 SOC_IF_ERROR_RETURN 4044 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, entry0)); 4045 4046 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_entry_t)); 4047 4048 soc_mem_field32_set(unit, mem3, entry0, RESUME_OFFSETf, 1); 4049 soc_mem_field32_set(unit, mem3, entry0, 4050 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 4051 soc_mem_field32_set(unit, mem3, entry0, 4052 RED_RESUME_OFFSET_PROFILE_SELf, 0); 4053 SOC_IF_ERROR_RETURN 4054 (soc_mem_write(unit, mem3, MEM_BLOCK_ALL, base + idx, entry0)); 4055 4056 rval = 0; 4057 SOC_IF_ERROR_RETURN( 4058 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 4059 1)); 4060 4061 rval = 0; 4062 SOC_IF_ERROR_RETURN( 4063 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 4064 1)); 4065 } 4066 } 4067 4068 /* Per port per pool */ 4069 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 4070 buf_port_pool = &buf->ports[port].pools[idx]; 4071 if (buf_port_pool->pool_limit == 0) { 4072 continue; 4073 } 4074 4075 limit = buf_port_pool->pool_limit; 4076 rlimit = limit - (default_mtu_cells * 2); 4077 4078 if(lossless) { 4079 enable = (!IS_OVERSUB_PORT(unit, port) && si->port_speed_max[port] <= 2500) ? 1 : 0; 4080 }else { 4081 enable = 1; 4082 } 4083 4084 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[0])[pipe]; 4085 if (mem0 == INVALIDm) { 4086 continue; 4087 } 4088 4089 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, 4090 mmu_thdo_port_mc_mem[0], idx); 4091 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t)); 4092 4093 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 4094 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 4095 sal_ceil_func(limit, 8)); 4096 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 4097 sal_ceil_func(limit, 8)); 4098 4099 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMIT_ENABLEf, enable); 4100 4101 soc_mem_field32_set(unit, mem0, entry0, SHARED_RESUME_LIMITf, 4102 sal_ceil_func(rlimit, 8)); 4103 soc_mem_field32_set(unit, mem0, entry0, YELLOW_RESUME_LIMITf, 4104 sal_ceil_func(rlimit, 8)); 4105 soc_mem_field32_set(unit, mem0, entry0, RED_RESUME_LIMITf, 4106 sal_ceil_func(rlimit, 8)); 4107 4108 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 4109 index1, entry0)); 4110 4111 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[1])[pipe]; 4112 if (mem1 == INVALIDm) { 4113 continue; 4114 } 4115 buf_pool = &buf->pools[idx]; 4116 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t)); 4117 4118 limit = _HX5_MMU_TOTAL_MCQ_ENTRY(unit); 4119 4120 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMITf, 4121 (sal_ceil_func(limit, 4)) - 1); 4122 soc_mem_field32_set(unit, mem1, entry0, YELLOW_SHARED_LIMITf, 4123 (sal_ceil_func(limit, 8)) - 1); 4124 soc_mem_field32_set(unit, mem1, entry0, RED_SHARED_LIMITf, 4125 (sal_ceil_func(limit, 8)) - 1); 4126 4127 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMIT_ENABLEf, enable); 4128 4129 soc_mem_field32_set(unit, mem1, entry0, SHARED_RESUME_LIMITf, 4130 (sal_ceil_func(limit, 8)) - 2); 4131 soc_mem_field32_set(unit, mem1, entry0, YELLOW_RESUME_LIMITf, 4132 (sal_ceil_func(limit, 8)) - 2); 4133 soc_mem_field32_set(unit, mem1, entry0, RED_RESUME_LIMITf, 4134 (sal_ceil_func(limit, 8)) - 2); 4135 4136 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 4137 index1, entry0)); 4138 } 4139 4140 /* Output port per port per queue setting for regular unicast queue */ 4141 pipe = si->port_pipe[port]; 4142 /* per port regular unicast queue */ 4143 numq = si->port_num_uc_cosq[port]; 4144 base = si->port_uc_cosq_base[port]; 4145 4146 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[0])[pipe]; 4147 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[1])[pipe]; 4148 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[2])[pipe]; 4149 if ((numq != 0) && 4150 (mem0 != INVALIDm) && (mem1 != INVALIDm) && (mem2 != INVALIDm)) { 4151 for (idx = 0; idx < numq; idx++) { 4152 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx]; 4153 4154 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 4155 sal_memset(entry1, 0, sizeof(mmu_thdu_offset_queue_entry_t)); 4156 4157 soc_mem_field32_set(unit, mem0, entry0, 4158 Q_MIN_LIMIT_CELLf, buf_queue->guarantee); 4159 if (buf_queue->pool_scale != -1) { 4160 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMIC_CELLf, 1); 4161 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHA_CELLf, 4162 buf_queue->pool_scale); 4163 } else { 4164 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 4165 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMIT_CELLf, 4166 buf_queue->pool_limit); 4167 } 4168 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_CELLf, 4169 sal_ceil_func(buf_queue->pool_resume, 8)); 4170 4171 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 4172 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 4173 soc_mem_field32_set(unit, mem0, entry0, 4174 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 4175 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 4176 buf_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 4177 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 4178 buf_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 4179 } else { 4180 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 4181 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 4182 sal_ceil_func(buf_queue->yellow_limit, 8)); 4183 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 4184 sal_ceil_func(buf_queue->red_limit, 8)); 4185 } 4186 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf, 4187 sal_ceil_func(buf_queue->yellow_resume, 8)); 4188 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf, 4189 sal_ceil_func(buf_queue->red_resume, 8)); 4190 SOC_IF_ERROR_RETURN 4191 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 4192 4193 SOC_IF_ERROR_RETURN 4194 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1)); 4195 4196 sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t)); 4197 4198 if (buf_queue->qgroup_id >= 0) { 4199 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1); 4200 if (buf_queue->qgroup_min_enable) { 4201 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1); 4202 } 4203 } 4204 if (buf_queue->discard_enable) { 4205 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 4206 } 4207 4208 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, 4209 entry0)); 4210 } 4211 } 4212 4213 /* Per port per pool unicast */ 4214 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 4215 buf_pool = &buf->pools[idx]; 4216 4217 if (IS_LB_PORT(unit, port) || IS_CPU_PORT(unit, port) 4218 || IS_FAE_PORT(unit, port)) { 4219 continue; 4220 } 4221 4222 if (buf_pool->total == 0) { 4223 continue; 4224 } 4225 4226 limit = buf->ports[port].pools[idx].pool_limit; 4227 4228 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[0])[pipe]; 4229 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[1])[pipe]; 4230 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 4231 continue; 4232 } 4233 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, 4234 mmu_thdo_port_uc_mem[0], idx); 4235 sal_memset(entry0, 0, sizeof(mmu_thdu_config_port_entry_t)); 4236 sal_memset(entry1, 0, sizeof(mmu_thdu_resume_port_entry_t)); 4237 4238 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 4239 soc_mem_field32_set(unit, mem1, entry1, SHARED_RESUMEf, 4240 sal_ceil_func((limit - (default_mtu_cells * 2)), 4241 8)); 4242 4243 soc_mem_field32_set(unit, mem0, entry0, YELLOW_LIMITf, 4244 sal_ceil_func(limit, 8)); 4245 soc_mem_field32_set(unit, mem1, entry1, YELLOW_RESUMEf, 4246 sal_ceil_func((limit - (default_mtu_cells*2)), 4247 8)); 4248 4249 soc_mem_field32_set(unit, mem0, entry0, RED_LIMITf, 4250 sal_ceil_func(limit, 8)); 4251 soc_mem_field32_set(unit, mem1, entry1, RED_RESUMEf, 4252 sal_ceil_func((limit - (default_mtu_cells * 2)), 4253 8)); 4254 4255 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 4256 index1, entry0)); 4257 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 4258 index1, entry1)); 4259 } 4260 4261 return SOC_E_NONE; 4262 } 4263 4264 STATIC int 4265 _soc_hx5_mmu_config_buf_set_hw_global(int unit, _soc_mmu_cfg_buf_t *buf, 4266 _soc_mmu_device_info_t *devcfg, int lossless, 4267 _soc_hx5_mmu_sw_config_info_t *swcfg) 4268 { 4269 _soc_mmu_cfg_buf_pool_t *buf_pool; 4270 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 4271 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 4272 mmu_thdo_offset_qgroup_entry_t offset_qgrp; 4273 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 4274 soc_mem_t mem0, mem1; 4275 uint32 fval, rval, rval2, rval3; 4276 int rqlen, idx, pval; 4277 int jumbo_frame_cells, default_mtu_cells, limit; 4278 int pipe; 4279 uint64 rval64; 4280 int pool_resume = 0; 4281 4282 static const soc_mem_t mmu_thdo_qgrp_uc_mem[] = { 4283 MMU_THDU_CONFIG_QGROUPm, 4284 MMU_THDU_OFFSET_QGROUPm 4285 }; 4286 4287 jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size + 4288 devcfg->mmu_hdr_byte, 4289 devcfg->mmu_cell_size); 4290 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 4291 devcfg->mmu_hdr_byte, 4292 devcfg->mmu_cell_size); 4293 pool_resume = 2 * jumbo_frame_cells; 4294 4295 rval = 0; 4296 fval = _HX5_MMU_PHYSICAL_CELLS_PER_XPE - _HX5_MMU_RSVD_CELLS_CFAP_PER_XPE; 4297 soc_reg_field_set(unit, CFAPFULLTHRESHOLDSETr, &rval, CFAPFULLSETPOINTf, 4298 fval); 4299 SOC_IF_ERROR_RETURN( 4300 soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDSETr, -1, -1, 4301 -1, rval)); 4302 4303 rval = 0; 4304 soc_reg_field_set(unit, CFAPFULLTHRESHOLDRESETr, &rval, 4305 CFAPFULLRESETPOINTf, fval - (2 * jumbo_frame_cells)); 4306 SOC_IF_ERROR_RETURN( 4307 soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDRESETr, -1, -1, 4308 -1, rval)); 4309 4310 rval = 0; 4311 soc_reg_field_set(unit, CFAPBANKFULLr, &rval, LIMITf, 4312 _HX5_MMU_CFAP_BANK_FULL_LIMIT); 4313 for (idx = 0; idx < SOC_REG_NUMELS(unit, CFAPBANKFULLr); idx++) { 4314 SOC_IF_ERROR_RETURN( 4315 soc_trident3_xpe_reg32_set(unit, CFAPBANKFULLr, -1, -1, 4316 idx, rval)); 4317 } 4318 4319 rval = 0; 4320 SOC_IF_ERROR_RETURN(READ_MMU_SCFG_TOQ_MC_CFG0r(unit, &rval)); 4321 soc_reg_field_set(unit, MMU_SCFG_TOQ_MC_CFG0r, &rval, 4322 MCQE_FULL_THRESHOLDf, 0); 4323 SOC_IF_ERROR_RETURN(WRITE_MMU_SCFG_TOQ_MC_CFG0r(unit, rval)); 4324 4325 rval = 0; 4326 SOC_IF_ERROR_RETURN 4327 (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, 0, 0, &rval)); 4328 soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval, 4329 PEAK_COUNT_UPDATE_EN_HPf, 0); 4330 SOC_IF_ERROR_RETURN 4331 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, 0, 0, rval)); 4332 /* Input thresholds */ 4333 rval = 0; 4334 soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMITr, 4335 &rval, GLOBAL_HDRM_LIMITf, buf->headroom ); 4336 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMITr, 4337 REG_PORT_ANY, 0, rval)); 4338 4339 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 4340 buf_pool = &buf->pools[idx]; 4341 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 4342 continue; 4343 } 4344 4345 limit = swcfg->ing_shared_total; 4346 4347 rval = 0; 4348 soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, 4349 limit); 4350 SOC_IF_ERROR_RETURN( 4351 soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, 4352 -1, -1, idx, rval)); 4353 4354 rval = 0; 4355 soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 4356 OFFSETf, pool_resume); 4357 SOC_IF_ERROR_RETURN( 4358 soc_trident3_xpe_reg32_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, 4359 -1, -1, idx, rval)); 4360 4361 rval = 0; 4362 soc_reg_field_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, &rval, 4363 LIMITf, buf_pool->prigroup_headroom); 4364 SOC_IF_ERROR_RETURN( 4365 soc_trident3_xpe_reg32_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, 4366 -1, -1, idx, rval)); 4367 } 4368 4369 rval = 0; 4370 SOC_IF_ERROR_RETURN( 4371 soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr, 4372 -1, -1, 0, rval)); 4373 4374 /* output thresholds */ 4375 SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval)); 4376 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 4377 ENABLE_QUEUE_AND_GROUP_TICKETf, 1); 4378 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 4379 ENABLE_UPDATE_COLOR_RESUMEf, 0); 4380 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 4381 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0); 4382 SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval)); 4383 4384 rval = 0; 4385 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 4386 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 4387 MOP_POLICYf, 1); 4388 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 4389 4390 rval = 0; 4391 SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIGr(unit, &rval)); 4392 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 4393 MOP_POLICY_1Bf, 1); 4394 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval)); 4395 4396 /* per service pool settings */ 4397 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 4398 buf_pool = &buf->pools[idx]; 4399 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 4400 continue; 4401 } 4402 4403 limit = swcfg->egr_shared_total; 4404 4405 rval = 0; 4406 soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 4407 SHARED_LIMITf, limit); 4408 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, 4409 idx, 4410 rval)); 4411 4412 rval = 0; 4413 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 4414 &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8)); 4415 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, 4416 idx, 4417 rval)); 4418 4419 rval = 0; 4420 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 4421 &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8)); 4422 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, 4423 idx, 4424 rval)); 4425 4426 rval = 0; 4427 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 4428 &rval, RESUME_LIMITf, sal_floor_func(limit, 8)); 4429 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, 4430 idx, 4431 rval)); 4432 4433 rval = 0; 4434 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 4435 &rval, YELLOW_RESUME_LIMITf, sal_floor_func(limit, 8)); 4436 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, 4437 idx, 4438 rval)); 4439 4440 rval = 0; 4441 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 4442 &rval, RED_RESUME_LIMITf, sal_floor_func(limit, 8)); 4443 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, 4444 idx, 4445 rval)); 4446 4447 /* mcq entries */ 4448 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 4449 4450 rval = 0; 4451 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 4452 &rval, SHARED_LIMITf, sal_ceil_func(limit, 4)); 4453 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit, 4454 idx, rval)); 4455 4456 rval = 0; 4457 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 4458 &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8)); 4459 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit, 4460 idx, rval)); 4461 4462 rval = 0; 4463 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 4464 &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8)); 4465 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit, 4466 idx, rval)); 4467 4468 rval = 0; 4469 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 4470 &rval, RESUME_LIMITf, sal_ceil_func(limit, 8)); 4471 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit, 4472 idx, rval)); 4473 4474 rval = 0; 4475 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 4476 &rval, YELLOW_RESUME_LIMITf, sal_ceil_func(limit, 8)); 4477 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit, 4478 idx, rval)); 4479 4480 rval = 0; 4481 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 4482 &rval, RED_RESUME_LIMITf, sal_ceil_func(limit, 8)); 4483 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit, 4484 idx, rval)); 4485 } 4486 4487 /* configure Q-groups */ 4488 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 4489 for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) { 4490 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[0])[pipe]; 4491 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[1])[pipe]; 4492 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 4493 continue; 4494 } 4495 queue_grp = &buf->qgroups[idx]; 4496 4497 4498 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 4499 sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp)); 4500 4501 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4502 Q_MIN_LIMIT_CELLf, queue_grp->guarantee); 4503 4504 if (queue_grp->pool_scale != -1) { 4505 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4506 Q_SHARED_ALPHA_CELLf, 4507 queue_grp->pool_scale); 4508 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4509 Q_LIMIT_DYNAMIC_CELLf, 1); 4510 } else { 4511 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4512 Q_SHARED_LIMIT_CELLf, 4513 queue_grp->pool_limit); 4514 } 4515 4516 if ((queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 4517 (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 4518 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4519 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 4520 } 4521 4522 if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 4523 pval = _soc_hx5_pool_scale_to_limit(queue_grp->pool_limit, 4524 queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 4525 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4526 LIMIT_RED_CELLf, sal_ceil_func(pval, 8)); 4527 4528 } else { 4529 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4530 LIMIT_RED_CELLf, 4531 sal_ceil_func(queue_grp->red_limit, 8)); 4532 } 4533 4534 if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 4535 pval = _soc_hx5_pool_scale_to_limit(queue_grp->pool_limit, 4536 queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 4537 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4538 LIMIT_YELLOW_CELLf, sal_ceil_func(pval, 8)); 4539 4540 } else { 4541 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 4542 LIMIT_YELLOW_CELLf, 4543 sal_ceil_func(queue_grp->yellow_limit, 8)); 4544 } 4545 4546 soc_mem_field32_set(unit, mem1, &offset_qgrp, 4547 RESET_OFFSET_CELLf, 4548 sal_ceil_func(queue_grp->pool_resume, 8)); 4549 soc_mem_field32_set(unit, mem1, &offset_qgrp, 4550 RESET_OFFSET_YELLOW_CELLf, 4551 sal_ceil_func(queue_grp->pool_resume, 8)); 4552 soc_mem_field32_set(unit, mem1, &offset_qgrp, 4553 RESET_OFFSET_RED_CELLf, 4554 sal_ceil_func(queue_grp->pool_resume, 8)); 4555 SOC_IF_ERROR_RETURN 4556 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 4557 SOC_IF_ERROR_RETURN 4558 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp)); 4559 } 4560 } 4561 4562 /* RQE */ 4563 for (idx = 0; idx < _HX5_MMU_NUM_RQE_QUEUES; idx++) { 4564 buf_rqe_queue = &buf->rqe_queues[idx]; 4565 4566 rval = 0; 4567 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 4568 &rval, MIN_LIMITf, buf_rqe_queue->guarantee); 4569 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval)); 4570 4571 rval = 0; 4572 rval2 = 0; 4573 rval3 = 0; 4574 COMPILER_64_SET(rval64, 0, 0); 4575 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 4576 &rval, SPIDf, buf_rqe_queue->pool_idx); 4577 4578 if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 4579 (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 4580 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 4581 &rval, COLOR_LIMIT_DYNAMICf, 1); 4582 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 4583 SHARED_RED_LIMITf, 4584 buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 4585 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 4586 SHARED_YELLOW_LIMITf, 4587 buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 4588 } else { 4589 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 4590 SHARED_RED_LIMITf, 4591 sal_ceil_func(buf_rqe_queue->red_limit, 8)); 4592 4593 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 4594 SHARED_YELLOW_LIMITf, 4595 sal_ceil_func(buf_rqe_queue->yellow_limit, 8)); 4596 } 4597 4598 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 4599 (buf_rqe_queue->discard_enable ? 1 : 0)); 4600 4601 if (buf_rqe_queue->pool_scale != -1) { 4602 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 4603 &rval, DYNAMIC_ENABLEf, 1); 4604 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64, 4605 SHARED_ALPHAf, buf_rqe_queue->pool_scale); 4606 } else { 4607 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64, 4608 SHARED_LIMITf, buf_rqe_queue->pool_limit); 4609 } 4610 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64, 4611 RESET_OFFSETf, 2); 4612 4613 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval)); 4614 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, MMU_THDR_DB_CONFIG_PRIQr, REG_PORT_ANY, idx, rval64)); 4615 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, 4616 idx, rval3)); 4617 4618 rval = 0; 4619 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 4620 &rval, RESET_OFFSET_REDf, 2); 4621 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 4622 &rval, RESET_OFFSET_YELLOWf,2); 4623 SOC_IF_ERROR_RETURN( 4624 WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 4625 4626 /* queue entry */ 4627 buf_pool = &buf->pools[buf_rqe_queue->pool_idx]; 4628 rval = 0; 4629 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 4630 &rval, MIN_LIMITf, 4631 sal_ceil_func(buf_rqe_queue->guarantee, 8)); 4632 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval)); 4633 4634 rval = 0; 4635 rval2 = 0; 4636 rval3 = 0; 4637 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 4638 &rval, SPIDf, buf_rqe_queue->pool_idx); 4639 4640 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 4641 &rval, COLOR_LIMIT_DYNAMICf, (!lossless)); 4642 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 4643 &rval3, SHARED_RED_LIMITf, 4644 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 4645 8)): 0); 4646 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 4647 &rval3, SHARED_YELLOW_LIMITf, 4648 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 4649 8)): 0); 4650 4651 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, 4652 LIMIT_ENABLEf, !lossless); 4653 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 4654 &rval, DYNAMIC_ENABLEf, (!lossless)); 4655 4656 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 4657 SHARED_LIMITf, 4658 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 4659 8)): 8); 4660 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 4661 RESET_OFFSETf, 1); 4662 4663 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval)); 4664 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2)); 4665 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 4666 4667 rval = 0; 4668 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 4669 &rval, RESET_OFFSET_REDf, 4670 sal_ceil_func(default_mtu_cells, 8)); 4671 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 4672 &rval, RESET_OFFSET_YELLOWf, 4673 sal_ceil_func(default_mtu_cells, 8)); 4674 SOC_IF_ERROR_RETURN( 4675 WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 4676 4677 } 4678 4679 /* per pool RQE settings */ 4680 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 4681 buf_pool = &buf->pools[idx]; 4682 if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) || 4683 (buf_pool->total == 0)) { 4684 continue; 4685 } 4686 4687 limit = swcfg->egr_shared_total; 4688 4689 COMPILER_64_SET(rval64, 0, 0); 4690 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, 4691 &rval64, SHARED_LIMITf, limit); 4692 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval64, 4693 RESUME_LIMITf, sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 4694 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr(unit, idx, rval64)); 4695 4696 rval = 0; 4697 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 4698 SHARED_RED_LIMITf, 4699 sal_ceil_func(limit, 8)); 4700 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 4701 SHARED_YELLOW_LIMITf, 4702 sal_ceil_func(limit, 8)); 4703 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval)); 4704 4705 rval = 0; 4706 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 4707 RESUME_RED_LIMITf, 4708 sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 4709 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 4710 RESUME_YELLOW_LIMITf, 4711 sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 4712 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit, 4713 idx, rval)); 4714 4715 rqlen = sal_ceil_func(buf_pool->total_rqe_entry, 8); 4716 if (rqlen == 0) { 4717 continue; 4718 } 4719 4720 rval = 0; 4721 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 4722 SHARED_LIMITf, rqlen); 4723 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 4724 RESUME_LIMITf, rqlen - 1); 4725 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval)); 4726 4727 rval = 0; 4728 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 4729 SHARED_RED_LIMITf, rqlen); 4730 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 4731 SHARED_YELLOW_LIMITf, rqlen); 4732 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, 4733 idx, 4734 rval)); 4735 4736 rval = 0; 4737 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 4738 RESUME_RED_LIMITf, rqlen - 1); 4739 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 4740 RESUME_YELLOW_LIMITf, rqlen - 1); 4741 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 4742 idx, rval)); 4743 } 4744 4745 4746 /* Device level config setting */ 4747 #if 0 4748 if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) { 4749 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 4750 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 4751 UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1); 4752 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 4753 } 4754 #endif 4755 return SOC_E_NONE; 4756 } 4757 4758 STATIC int 4759 _soc_hx5_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf, 4760 _soc_mmu_device_info_t *devcfg, int lossless, 4761 _soc_hx5_mmu_sw_config_info_t *swcfg) 4762 { 4763 int port; 4764 4765 SOC_IF_ERROR_RETURN 4766 (_soc_hx5_mmu_config_buf_set_hw_global(unit, buf, devcfg, lossless, 4767 swcfg)); 4768 4769 PBMP_ALL_ITER(unit, port) { 4770 SOC_IF_ERROR_RETURN 4771 (_soc_hx5_mmu_config_buf_set_hw_port(unit, port, buf, devcfg, 4772 lossless, swcfg)); 4773 } 4774 4775 return SOC_E_NONE; 4776 } 4777 4778 int 4779 soc_hx5_mmu_config_init_port(int unit, int port) 4780 { 4781 int rv; 4782 int lossless = 1; 4783 _soc_mmu_cfg_buf_t *buf; 4784 _soc_mmu_device_info_t devcfg; 4785 _soc_hx5_mmu_sw_config_info_t swcfg; 4786 4787 buf = soc_mmu_cfg_alloc(unit); 4788 if (!buf) { 4789 return SOC_E_MEMORY; 4790 } 4791 4792 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 4793 4794 SOC_INFO(unit).mmu_lossless = lossless; 4795 _soc_hx5_mmu_init_dev_config(unit, &devcfg, lossless); 4796 _soc_hx5_mmu_sw_info_config (unit, &swcfg, lossless); 4797 4798 4799 /* Calculate the buf - global as well as per port 4800 * but _soc_hx5_mmu_config_buf_set_hw_port is only called 4801 * for that port - since it is flex operation - we don't 4802 * touch any other port */ 4803 _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4804 4805 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4806 /* Override default config */ 4807 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4808 } 4809 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 4810 if (SOC_FAILURE(rv)) { 4811 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4812 (BSL_META_U(unit, 4813 "MMU config: Use default setting\n"))); 4814 _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4815 SOC_IF_ERROR_RETURN 4816 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg)); 4817 } 4818 4819 _soc_hx5_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless); 4820 /* Override default phase 2 config */ 4821 if (SOC_SUCCESS(rv)) { 4822 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4823 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4824 } 4825 } 4826 rv = _soc_hx5_mmu_config_buf_set_hw_port(unit, port, buf, &devcfg, 4827 lossless, &swcfg); 4828 4829 soc_mmu_cfg_free(unit, buf); 4830 4831 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4832 (BSL_META_U(unit, 4833 "MMU THDI/THDO init done\n"))); 4834 return rv; 4835 } 4836 4837 STATIC int 4838 soc_hx5_mmu_config_init(int unit, int test_only) 4839 { 4840 int rv; 4841 int lossless = 1; 4842 _soc_mmu_cfg_buf_t *buf; 4843 _soc_mmu_device_info_t devcfg; 4844 _soc_hx5_mmu_sw_config_info_t swcfg; 4845 4846 buf = soc_mmu_cfg_alloc(unit); 4847 if (!buf) { 4848 return SOC_E_MEMORY; 4849 } 4850 4851 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 4852 4853 _soc_hx5_mmu_init_dev_config(unit, &devcfg, lossless); 4854 _soc_hx5_mmu_sw_info_config (unit, &swcfg, lossless); 4855 4856 _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4857 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4858 /* Override default config */ 4859 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4860 } 4861 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 4862 if (!test_only) { 4863 if (SOC_FAILURE(rv)) { 4864 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4865 (BSL_META_U(unit, 4866 "MMU config: Use default setting\n"))); 4867 _soc_hx5_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4868 SOC_IF_ERROR_RETURN 4869 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg)); 4870 } 4871 4872 _soc_hx5_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless); 4873 /* Override default phase 2 config */ 4874 if (SOC_SUCCESS(rv)) { 4875 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4876 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4877 } 4878 } 4879 rv = _soc_hx5_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, &swcfg); 4880 } 4881 4882 soc_mmu_cfg_free(unit, buf); 4883 4884 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4885 (BSL_META_U(unit, 4886 "MMU THDI/THDO init done\n"))); 4887 return rv; 4888 } 4889 4890 STATIC int 4891 _soc_hx5_thdo_hw_set(int unit, soc_port_t port, int enable) 4892 { 4893 uint64 rval64, rval64_tmp; 4894 int pipe, i; 4895 int split, pos; 4896 soc_reg_t reg[3][2] = { 4897 { 4898 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT0r, 4899 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT1r 4900 }, 4901 { 4902 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT0r, 4903 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT1r 4904 }, 4905 { 4906 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT0r, 4907 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT1r 4908 } 4909 }; 4910 4911 SOC_IF_ERROR_RETURN( 4912 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos)); 4913 4914 for (i = 0; i < 3; i++) { 4915 COMPILER_64_ZERO(rval64); 4916 COMPILER_64_ZERO(rval64_tmp); 4917 4918 if (pos < 32) { 4919 COMPILER_64_SET(rval64_tmp, 0, (1 << pos)); 4920 } else { 4921 COMPILER_64_SET(rval64_tmp, (1 << (pos - 32)), 0); 4922 } 4923 4924 SOC_IF_ERROR_RETURN 4925 (soc_trident3_xpe_reg_get(unit, reg[i][split], 4926 -1, pipe, 0, &rval64)); 4927 4928 if (enable) { 4929 COMPILER_64_OR(rval64, rval64_tmp); 4930 } else { 4931 COMPILER_64_NOT(rval64_tmp); 4932 COMPILER_64_AND(rval64, rval64_tmp); 4933 } 4934 4935 SOC_IF_ERROR_RETURN 4936 (soc_trident3_xpe_reg_set(unit, reg[i][split], 4937 -1, pipe, 0, rval64)); 4938 } 4939 4940 return SOC_E_NONE; 4941 } 4942 4943 STATIC int 4944 _soc_helix5_mmu_init(int unit) 4945 { 4946 uint32 rval = 0; 4947 int total_entries, clock_period, msbus_margin; 4948 int refresh_time_val; 4949 int val, time_refresh = 0; 4950 int enable = 1; 4951 int port; 4952 int test_only; 4953 soc_info_t *si; 4954 #ifdef BCM_WARM_BOOT_SUPPORT 4955 if (SOC_WARM_BOOT(unit)) { 4956 } else 4957 #endif 4958 { 4959 4960 test_only = (SAL_BOOT_XGSSIM) ? TRUE : FALSE; 4961 SOC_IF_ERROR_RETURN(soc_hx5_mmu_config_init(unit, test_only)); 4962 4963 4964 PBMP_ALL_ITER(unit, port) { 4965 _soc_hx5_thdo_hw_set(unit, port, enable); 4966 } 4967 si = &SOC_INFO(unit); 4968 4969 total_entries = 1572; 4970 clock_period = (1 * 10000) / si->frequency; 4971 msbus_margin = (18 * 1000) / 16; 4972 4973 refresh_time_val = clock_period * total_entries * msbus_margin; 4974 val = refresh_time_val / (10000); 4975 4976 if (val < 1000) { 4977 time_refresh = 0; 4978 } else if (val >= 1000 && val < 1500) { 4979 time_refresh = 1; 4980 } else if (val >= 1500 && val < 2000) { 4981 time_refresh = 2; 4982 } else if (val >= 2000 && val < 2500) { 4983 time_refresh = 3; 4984 } else if (val >= 2500 && val < 3000) { 4985 time_refresh = 4; 4986 } else if (val >= 3000 && val < 3500) { 4987 time_refresh = 5; 4988 } else if (val >= 3500 && val < 4000) { 4989 time_refresh = 6; 4990 } else if (val >= 4000 && val < 4500) { 4991 time_refresh = 7; 4992 } else if (val >= 4500 && val <= 5000) { 4993 time_refresh = 8; 4994 } 4995 4996 4997 /* enable WRED refresh */ 4998 SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval)); 4999 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 5000 REFRESH_DISABLEf, 0); 5001 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 5002 REFRESH_PERIODf, time_refresh); 5003 SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval)); 5004 5005 5006 SOC_IF_ERROR_RETURN 5007 (soc_trident3_sc_reg32_get(unit, MMU_1DBG_Cr, 0, 0, 0, &rval)); 5008 soc_reg_field_set(unit, MMU_1DBG_Cr, &rval, FIELD_Af, 1); 5009 SOC_IF_ERROR_RETURN 5010 (soc_trident3_sc_reg32_set(unit, MMU_1DBG_Cr, -1, -1, 0, rval)); 5011 SOC_IF_ERROR_RETURN 5012 (soc_trident3_sc_reg32_set(unit, MMU_2DBG_C_1r, -1, -1, 0, 0x4)); 5013 } 5014 return SOC_E_NONE; 5015 } 5016 5017 STATIC int 5018 _soc_hx5_mmu_config_shared_update_check(int val1, int val2, int flags) 5019 { 5020 int rv = 0; 5021 if (flags == 1) { 5022 if (val1 > val2) { 5023 rv = 1; 5024 } 5025 } else { 5026 if (val1 < val2) { 5027 rv = 1; 5028 } 5029 } 5030 return rv; 5031 } 5032 5033 #define HX5_MMU_SHARED_LIMIT_CHK(val1, val2, flags) \ 5034 _soc_hx5_mmu_config_shared_update_check((val1), (val2), (flags)) 5035 5036 int 5037 soc_hx5_mmu_config_shared_buf_recalc(int unit, int res, int thdi_shd, 5038 int thdo_db_shd, int thdo_qe_shd, 5039 int post_update) 5040 { 5041 soc_info_t *si; 5042 int pipe; 5043 uint32 entry0[SOC_MAX_MEM_WORDS], cur_limit, rval = 0, rval2 = 0; 5044 uint64 rval64; 5045 thdi_port_pg_config_entry_t pg_config_mem; 5046 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 5047 int port, base, numq, idx, midx; 5048 soc_mem_t base_mem = INVALIDm, base_mem2 = INVALIDm; 5049 soc_mem_t mem = INVALIDm, mem2 = INVALIDm; 5050 soc_reg_t reg = INVALIDr; 5051 soc_field_t field = INVALIDf; 5052 int granularity, index1; 5053 5054 si = &SOC_INFO(unit); 5055 COMPILER_64_SET(rval64, 0, 0); 5056 5057 /*********************************** 5058 * THDI 5059 */ 5060 if (res & 0x1) { /* if (res & THDI) { */ 5061 5062 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 5063 /* THDI SP entries */ 5064 rval = 0; 5065 reg = THDI_BUFFER_CELL_LIMIT_SPr; 5066 field = LIMITf; 5067 granularity = 1; 5068 SOC_IF_ERROR_RETURN 5069 (READ_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, &rval)); 5070 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5071 if ((cur_limit != 0) && 5072 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdi_shd/granularity, 5073 post_update)) { 5074 soc_reg_field_set(unit, reg, &rval, field, (thdi_shd/granularity)); 5075 SOC_IF_ERROR_RETURN( 5076 soc_trident3_xpe_reg32_set(unit, reg, 5077 -1, -1, idx, rval)); 5078 } 5079 } 5080 5081 /* Input per port settings */ 5082 base_mem = THDI_PORT_PG_CONFIGm; 5083 PBMP_ALL_ITER(unit, port) { 5084 pipe = si->port_pipe[port]; 5085 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5086 field = PG_SHARED_LIMITf; 5087 granularity = 1; 5088 /* Input port per Port-PG settings */ 5089 for (idx = 0; idx < _HX5_MMU_NUM_PG; idx++) { 5090 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 5091 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 5092 SOC_IF_ERROR_RETURN 5093 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, 5094 midx, &pg_config_mem)); 5095 if (!soc_mem_field32_get(unit, mem, &pg_config_mem, 5096 PG_SHARED_DYNAMICf)) { 5097 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, 5098 field); 5099 if ((cur_limit != 0) && 5100 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdi_shd/granularity, 5101 post_update)) { 5102 soc_mem_field32_set(unit, mem, &pg_config_mem, 5103 field, thdi_shd/granularity); 5104 } 5105 } 5106 5107 SOC_IF_ERROR_RETURN 5108 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 5109 midx, &pg_config_mem)); 5110 } 5111 } 5112 } 5113 5114 /*********************************** 5115 * THDO 5116 */ 5117 if (res & 0x2) { /* if (res & THDO) { */ 5118 /* Per SP settings */ 5119 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 5120 /* DB entries */ 5121 rval = 0; 5122 reg = MMU_THDM_DB_POOL_SHARED_LIMITr; 5123 field = SHARED_LIMITf; 5124 granularity = 1; 5125 SOC_IF_ERROR_RETURN 5126 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 5127 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5128 if ((cur_limit != 0) && 5129 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 5130 post_update)) { 5131 soc_reg_field_set(unit, reg, &rval, field, (thdo_db_shd/granularity)); 5132 SOC_IF_ERROR_RETURN 5133 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 5134 } 5135 5136 rval = 0; 5137 reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr; 5138 field = YELLOW_SHARED_LIMITf; 5139 granularity = 8; 5140 SOC_IF_ERROR_RETURN 5141 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 5142 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5143 if ((cur_limit != 0) && 5144 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity), 5145 post_update)) { 5146 soc_reg_field_set(unit, reg, &rval, field, sal_ceil_func(thdo_db_shd, granularity)); 5147 SOC_IF_ERROR_RETURN 5148 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 5149 } 5150 5151 rval = 0; 5152 reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr; 5153 field = RED_SHARED_LIMITf; 5154 granularity = 8; 5155 SOC_IF_ERROR_RETURN 5156 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 5157 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5158 if ((cur_limit != 0) && 5159 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity), 5160 post_update)) { 5161 soc_reg_field_set(unit, reg, &rval, field, sal_ceil_func(thdo_db_shd, granularity)); 5162 SOC_IF_ERROR_RETURN 5163 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 5164 } 5165 5166 /* MCQE */ 5167 rval = 0; 5168 reg = MMU_THDM_MCQE_POOL_SHARED_LIMITr; 5169 field = SHARED_LIMITf; 5170 granularity = 1; /* Value retrieved from QE. Hence no further 5171 * granularity for Non-color Shd Limit */ 5172 SOC_IF_ERROR_RETURN 5173 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 5174 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5175 if ((cur_limit != 0) && 5176 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity, 5177 post_update)) { 5178 soc_reg_field_set(unit, reg, &rval, field, 5179 (thdo_qe_shd/granularity)); 5180 SOC_IF_ERROR_RETURN 5181 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 5182 } 5183 5184 rval = 0; 5185 reg = MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr; 5186 field = YELLOW_SHARED_LIMITf; 5187 granularity = 8; 5188 SOC_IF_ERROR_RETURN 5189 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 5190 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5191 if ((cur_limit != 0) && 5192 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity, 5193 post_update)) { 5194 soc_reg_field_set(unit, reg, &rval, field, 5195 (thdo_qe_shd/granularity)); 5196 SOC_IF_ERROR_RETURN 5197 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 5198 } 5199 5200 rval = 0; 5201 reg = MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr; 5202 field = RED_SHARED_LIMITf; 5203 granularity = 8; 5204 SOC_IF_ERROR_RETURN 5205 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 5206 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5207 if ((cur_limit != 0) && 5208 HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_qe_shd/granularity, 5209 post_update)) { 5210 soc_reg_field_set(unit, reg, &rval, field, 5211 (thdo_qe_shd/granularity)); 5212 SOC_IF_ERROR_RETURN 5213 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 5214 } 5215 } 5216 5217 /* configure Q-groups */ 5218 base_mem = MMU_THDU_CONFIG_QGROUPm; 5219 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 5220 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5221 for (idx = 0; idx < SOC_HX5_MMU_CFG_QGROUP_MAX; idx++) { 5222 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 5223 5224 SOC_IF_ERROR_RETURN 5225 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 5226 5227 field = Q_SHARED_LIMIT_CELLf; 5228 granularity = 1; 5229 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) { 5230 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 5231 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 5232 post_update)) { 5233 soc_mem_field32_set(unit, mem, &cfg_qgrp, 5234 field, thdo_db_shd/granularity); 5235 } 5236 } 5237 5238 granularity = 8; 5239 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, 5240 Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 5241 field = LIMIT_RED_CELLf; 5242 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 5243 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 5244 post_update)) { 5245 soc_mem_field32_set(unit, mem, &cfg_qgrp, 5246 field, thdo_db_shd/granularity); 5247 } 5248 5249 field = LIMIT_YELLOW_CELLf; 5250 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 5251 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 5252 post_update)) { 5253 soc_mem_field32_set(unit, mem, &cfg_qgrp, 5254 field, thdo_db_shd/granularity); 5255 } 5256 } 5257 5258 SOC_IF_ERROR_RETURN 5259 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 5260 } 5261 } 5262 5263 /* Output port per port per queue setting for UC queue */ 5264 PBMP_PORT_ITER(unit, port) { 5265 base_mem = MMU_THDU_CONFIG_QUEUEm; 5266 pipe = si->port_pipe[port]; 5267 5268 /* per port UC queue */ 5269 numq = si->port_num_uc_cosq[port]; 5270 base = si->port_uc_cosq_base[port]; 5271 5272 if (numq == 0) { 5273 continue; 5274 } 5275 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5276 for (idx = 0; idx < numq; idx++) { 5277 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 5278 5279 SOC_IF_ERROR_RETURN 5280 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 5281 5282 field = Q_SHARED_LIMIT_CELLf; 5283 granularity = 1; 5284 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) { 5285 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5286 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, thdo_db_shd/granularity, 5287 post_update)) { 5288 soc_mem_field32_set(unit, mem, entry0, 5289 field, thdo_db_shd/granularity); 5290 } 5291 } 5292 5293 granularity = 8; 5294 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 5295 field = LIMIT_YELLOW_CELLf; 5296 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5297 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, sal_ceil_func(thdo_db_shd, granularity), 5298 post_update)) { 5299 soc_mem_field32_set(unit, mem, entry0, 5300 field, sal_ceil_func(thdo_db_shd, granularity)); 5301 } 5302 field = LIMIT_RED_CELLf; 5303 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5304 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5305 sal_ceil_func(thdo_db_shd, granularity), post_update)) { 5306 soc_mem_field32_set(unit, mem, entry0, 5307 field, sal_ceil_func(thdo_db_shd, granularity)); 5308 } 5309 } 5310 SOC_IF_ERROR_RETURN 5311 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 5312 } 5313 5314 /* Per port-SP unicast */ 5315 base_mem = MMU_THDU_CONFIG_PORTm; 5316 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5317 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 5318 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 5319 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t)); 5320 5321 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 5322 index1, entry0)); 5323 5324 field = SHARED_LIMITf; 5325 granularity = 1; 5326 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5327 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5328 thdo_db_shd/granularity, post_update)) { 5329 soc_mem_field32_set(unit, mem, entry0, 5330 field, thdo_db_shd/granularity); 5331 } 5332 5333 granularity = 8; 5334 field = YELLOW_LIMITf; 5335 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5336 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5337 thdo_db_shd/granularity, post_update)) { 5338 soc_mem_field32_set(unit, mem, entry0, 5339 field, thdo_db_shd/granularity); 5340 } 5341 field = RED_LIMITf; 5342 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5343 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5344 thdo_db_shd/granularity, post_update)) { 5345 soc_mem_field32_set(unit, mem, entry0, 5346 field, thdo_db_shd/granularity); 5347 } 5348 5349 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 5350 index1, entry0)); 5351 } 5352 } 5353 5354 /* Output port per port per queue setting for MC queue */ 5355 PBMP_PORT_ITER(unit, port) { 5356 base_mem = MMU_THDM_DB_PORTSP_CONFIGm; 5357 base_mem2 = MMU_THDM_MCQE_PORTSP_CONFIGm; 5358 pipe = si->port_pipe[port]; 5359 5360 /* Per Port-SP */ 5361 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5362 mem2 = SOC_MEM_UNIQUE_ACC(unit, base_mem2)[pipe]; 5363 for (idx = 0; idx < _HX5_MMU_NUM_POOL; idx++) { 5364 /* DB entries - Port-SP */ 5365 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 5366 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t)); 5367 5368 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 5369 index1, entry0)); 5370 5371 field = SHARED_LIMITf; 5372 granularity = 1; 5373 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5374 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5375 thdo_db_shd/granularity, post_update)) { 5376 soc_mem_field32_set(unit, mem, entry0, 5377 field, thdo_db_shd/granularity); 5378 } 5379 5380 field = RED_SHARED_LIMITf; 5381 granularity = 8; 5382 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5383 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5384 thdo_db_shd/granularity, post_update)) { 5385 soc_mem_field32_set(unit, mem, entry0, 5386 field, thdo_db_shd/granularity); 5387 } 5388 5389 field = YELLOW_SHARED_LIMITf; 5390 granularity = 8; 5391 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5392 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5393 thdo_db_shd/granularity, post_update)) { 5394 soc_mem_field32_set(unit, mem, entry0, 5395 field, thdo_db_shd/granularity); 5396 } 5397 5398 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 5399 index1, entry0)); 5400 5401 /* MCQE - Port-SP*/ 5402 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t)); 5403 5404 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem2, MEM_BLOCK_ALL, 5405 index1, entry0)); 5406 field = SHARED_LIMITf; 5407 granularity = 4; 5408 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field); 5409 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5410 thdo_qe_shd/granularity, post_update)) { 5411 soc_mem_field32_set(unit, mem2, entry0, 5412 field, thdo_qe_shd/granularity); 5413 } 5414 5415 field = RED_SHARED_LIMITf; 5416 granularity = 8; 5417 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field); 5418 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5419 thdo_qe_shd/granularity, post_update)) { 5420 soc_mem_field32_set(unit, mem2, entry0, 5421 field, thdo_qe_shd/granularity); 5422 } 5423 5424 field = YELLOW_SHARED_LIMITf; 5425 granularity = 8; 5426 cur_limit = soc_mem_field32_get(unit, mem2, entry0, field); 5427 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5428 thdo_qe_shd/granularity, post_update)) { 5429 soc_mem_field32_set(unit, mem2, entry0, 5430 field, thdo_qe_shd/granularity); 5431 } 5432 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 5433 index1, entry0)); 5434 5435 } 5436 5437 /* DB entries - Queue */ 5438 numq = si->port_num_cosq[port]; 5439 base = si->port_cosq_base[port]; 5440 if (numq == 0) { 5441 continue; 5442 } 5443 5444 base_mem = MMU_THDM_DB_QUEUE_CONFIGm; 5445 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5446 5447 for (idx = 0; idx < numq; idx++) { 5448 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_entry_t)); 5449 5450 SOC_IF_ERROR_RETURN 5451 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 5452 5453 field = Q_SHARED_LIMITf; 5454 granularity = 1; 5455 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 5456 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5457 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5458 thdo_db_shd/granularity, post_update)) { 5459 soc_mem_field32_set(unit, mem, entry0, 5460 field, thdo_db_shd/granularity); 5461 } 5462 } 5463 5464 granularity = 8; 5465 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 5466 field = YELLOW_SHARED_LIMITf; 5467 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5468 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5469 thdo_db_shd/granularity, post_update)) { 5470 soc_mem_field32_set(unit, mem, entry0, 5471 field, thdo_db_shd/granularity); 5472 } 5473 field = RED_SHARED_LIMITf; 5474 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5475 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5476 thdo_db_shd/granularity, post_update)) { 5477 soc_mem_field32_set(unit, mem, entry0, 5478 field, thdo_db_shd/granularity); 5479 } 5480 } 5481 SOC_IF_ERROR_RETURN 5482 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 5483 entry0)); 5484 } 5485 5486 /* MCQE - Queue */ 5487 base_mem = MMU_THDM_MCQE_QUEUE_CONFIGm; 5488 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 5489 for (idx = 0; idx < numq; idx++) { 5490 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 5491 5492 SOC_IF_ERROR_RETURN 5493 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 5494 5495 field = Q_SHARED_LIMITf; 5496 granularity = 4; 5497 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 5498 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5499 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5500 thdo_qe_shd/granularity, post_update)) { 5501 soc_mem_field32_set(unit, mem, entry0, 5502 field, thdo_qe_shd/granularity); 5503 } 5504 } 5505 5506 granularity = 8; 5507 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 5508 field = YELLOW_SHARED_LIMITf; 5509 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5510 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5511 thdo_qe_shd/granularity, post_update)) { 5512 soc_mem_field32_set(unit, mem, entry0, 5513 field, thdo_qe_shd/granularity); 5514 } 5515 field = RED_SHARED_LIMITf; 5516 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 5517 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5518 thdo_qe_shd/granularity, post_update)) { 5519 soc_mem_field32_set(unit, mem, entry0, 5520 field, thdo_qe_shd/granularity); 5521 } 5522 } 5523 SOC_IF_ERROR_RETURN 5524 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 5525 entry0)); 5526 } 5527 } 5528 5529 /* RQE */ 5530 for (idx = 0; idx < 11; idx++) { 5531 rval = 0; 5532 COMPILER_64_SET(rval64, 0, 0); 5533 5534 SOC_IF_ERROR_RETURN 5535 (READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval)); 5536 5537 reg = MMU_THDR_DB_CONFIG_PRIQr; 5538 field = SHARED_LIMITf; 5539 granularity = 1; 5540 SOC_IF_ERROR_RETURN 5541 (soc_reg64_get(unit, reg, REG_PORT_ANY, idx, &rval64)); 5542 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 5543 DYNAMIC_ENABLEf)) { 5544 cur_limit = soc_reg64_field32_get(unit, reg, rval64, field); 5545 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5546 thdo_db_shd/granularity, post_update)) { 5547 soc_reg64_field32_set(unit, reg, &rval64, field, 5548 (thdo_db_shd/granularity)); 5549 SOC_IF_ERROR_RETURN 5550 (soc_reg64_set(unit, reg, REG_PORT_ANY, idx, rval64)); 5551 } 5552 } 5553 5554 rval2 = 0; 5555 reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr; 5556 granularity = 8; 5557 SOC_IF_ERROR_RETURN 5558 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 5559 5560 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 5561 COLOR_LIMIT_DYNAMICf)) { 5562 field = SHARED_RED_LIMITf; 5563 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 5564 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5565 thdo_db_shd/granularity, post_update)) { 5566 soc_reg_field_set(unit, reg, &rval2, field, (thdo_db_shd/granularity)); 5567 } 5568 5569 field = SHARED_YELLOW_LIMITf; 5570 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 5571 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5572 thdo_db_shd/granularity, post_update)) { 5573 soc_reg_field_set(unit, reg, &rval2, field, (thdo_db_shd/granularity)); 5574 } 5575 SOC_IF_ERROR_RETURN 5576 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 5577 } 5578 5579 } 5580 /* per pool RQE settings */ 5581 for (idx = 0; idx < 4; idx++) { 5582 reg = MMU_THDR_DB_CONFIG_SPr; 5583 field = SHARED_LIMITf; 5584 granularity = 1; 5585 5586 SOC_IF_ERROR_RETURN 5587 (soc_reg64_get(unit, reg, REG_PORT_ANY, idx, &rval64)); 5588 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5589 5590 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5591 thdo_db_shd/granularity, post_update)) { 5592 soc_reg64_field32_set 5593 (unit, reg, &rval64, field, (thdo_db_shd/granularity)); 5594 SOC_IF_ERROR_RETURN 5595 (soc_reg64_set(unit, reg, REG_PORT_ANY, idx, rval64)); 5596 } 5597 5598 reg = MMU_THDR_DB_SP_SHARED_LIMITr; 5599 granularity = 8; 5600 5601 SOC_IF_ERROR_RETURN 5602 (soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 5603 5604 field = SHARED_YELLOW_LIMITf; 5605 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5606 5607 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5608 thdo_db_shd/granularity, post_update)) { 5609 soc_reg_field_set 5610 (unit, reg, &rval2, field, (thdo_db_shd/granularity)); 5611 } 5612 5613 field = SHARED_RED_LIMITf; 5614 cur_limit = soc_reg_field_get(unit, reg, rval, field); 5615 5616 if (HX5_MMU_SHARED_LIMIT_CHK(cur_limit, 5617 thdo_db_shd/granularity, post_update)) { 5618 soc_reg_field_set 5619 (unit, reg, &rval2, field, (thdo_db_shd/granularity)); 5620 } 5621 SOC_IF_ERROR_RETURN 5622 (soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 5623 } 5624 } 5625 return SOC_E_NONE; 5626 } 5627 5628 soc_pstats_tbl_desc_t 5629 _soc_hx5_pstats_tbl_desc_all = {SOC_BLK_NONE, INVALIDm, FALSE, FALSE}; 5630 /* pstats support */ 5631 soc_pstats_tbl_desc_t _soc_hx5_pstats_tbl_desc[] = { 5632 /* List all the potential memories */ 5633 #ifdef BCM_PSTATS_MEASURE 5634 { 5635 SOC_BLK_MMU_GLB, 5636 INVALIDm, 5637 FALSE, FALSE, 5638 { 5639 {MMU_INTFO_TIMESTAMPm}, 5640 {INVALIDm} 5641 } 5642 }, 5643 #endif 5644 { 5645 SOC_BLK_MMU_GLB, 5646 INVALIDm, 5647 FALSE, FALSE, 5648 { 5649 {MMU_INTFO_UTC_TIMESTAMPm}, 5650 {INVALIDm} 5651 } 5652 }, 5653 { 5654 SOC_BLK_MMU_XPE, 5655 MMU_THDU_UCQ_STATS_TABLEm, 5656 TRUE, TRUE 5657 }, 5658 { 5659 SOC_BLK_MMU_XPE, 5660 THDI_PKT_STAT_SP_SHARED_COUNTm, 5661 FALSE, FALSE 5662 }, 5663 { 5664 SOC_BLK_MMU_XPE, 5665 MMU_THDM_DB_POOL_MCUC_PKSTATm, 5666 FALSE, FALSE 5667 #ifdef BCM_PSTATS_MEASURE 5668 }, 5669 { 5670 SOC_BLK_MMU_GLB, 5671 INVALIDm, 5672 FALSE, FALSE, 5673 { 5674 {MMU_INTFO_TIMESTAMPm}, 5675 {INVALIDm} 5676 } 5677 #endif 5678 } 5679 }; 5680 5681 void 5682 soc_helix5_mmu_pstats_tbl_config_all(int unit) 5683 { 5684 soc_control_t *soc = SOC_CONTROL(unit); 5685 soc_pstats_mem_desc_t *desc, *desc_all; 5686 int ti, mi, di = 0; 5687 5688 desc_all = _soc_hx5_pstats_tbl_desc_all.desc; 5689 /* Check and strip invalid memories */ 5690 for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) { 5691 mi = 0; 5692 desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc; 5693 while (desc[mi].mem != INVALIDm) { 5694 desc_all[di] = desc[mi]; 5695 di++; 5696 mi++; 5697 } 5698 } 5699 desc_all[di].mem = INVALIDm; 5700 5701 soc->pstats_tbl_desc = &_soc_hx5_pstats_tbl_desc_all; 5702 soc->pstats_tbl_desc_count = 1; 5703 } 5704 5705 void 5706 soc_helix5_mmu_pstats_tbl_config(int unit) 5707 { 5708 soc_control_t *soc = SOC_CONTROL(unit); 5709 soc_pstats_mem_desc_t *desc; 5710 soc_mem_t bmem; 5711 int pe, mor_dma; 5712 int ti, mi, xpe, pipe; 5713 5714 soc->pstats_tbl_desc = _soc_hx5_pstats_tbl_desc; 5715 soc->pstats_tbl_desc_count = COUNTOF(_soc_hx5_pstats_tbl_desc); 5716 soc->pstats_mode = PSTATS_MODE_NULL; 5717 5718 /* Check and strip invalid memories */ 5719 for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) { 5720 mi = 0; 5721 desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc; 5722 bmem = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].bmem; 5723 if (bmem == INVALIDm) { 5724 while (desc[mi].mem != INVALIDm) { 5725 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem); 5726 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem); 5727 mi++; 5728 } 5729 continue; 5730 } 5731 pe = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].pipe_enum; 5732 mor_dma = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].mor_dma; 5733 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5734 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 5735 desc[mi].mem = pe ? SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, bmem, xpe, pipe) : 5736 SOC_MEM_UNIQUE_ACC(unit, bmem)[xpe]; 5737 if (desc[mi].mem == INVALIDm) { 5738 continue; 5739 } 5740 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem); 5741 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem); 5742 if (mor_dma) { 5743 desc[mi].mor_dma = TRUE; 5744 } 5745 mi++; 5746 if (!pe) { 5747 break; 5748 } 5749 } 5750 } 5751 desc[mi].mem = INVALIDm; 5752 } 5753 5754 if (soc_property_get(unit, "pstats_desc_all", 1)) { 5755 /* Use single desc chain */ 5756 soc_helix5_mmu_pstats_tbl_config_all(unit); 5757 } 5758 } 5759 5760 int 5761 soc_helix5_mmu_pstats_mode_set(int unit, uint32 flags) 5762 { 5763 soc_control_t *soc = SOC_CONTROL(unit); 5764 int pf = 0; 5765 uint32 rval = 0; 5766 int rv; 5767 5768 SOC_PSTATS_LOCK(unit); 5769 5770 if (flags & _HX5_MMU_PSTATS_HWM_MOD) { 5771 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5772 HWM_MODEf, 1); 5773 pf |= _HX5_MMU_PSTATS_HWM_MOD; 5774 if (flags & _HX5_MMU_PSTATS_RESET_ON_READ) { 5775 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5776 HWM_RESET_ON_READf, 1); 5777 pf |= _HX5_MMU_PSTATS_RESET_ON_READ; 5778 } 5779 } 5780 5781 if (soc_feature(unit, soc_feature_mor_dma) && 5782 (flags & _HX5_MMU_PSTATS_MOR_EN)) { 5783 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5784 MOR_ENf, 1); 5785 } 5786 if (flags & _HX5_MMU_PSTATS_MOR_EN) { 5787 pf |= _HX5_MMU_PSTATS_MOR_EN; 5788 } 5789 5790 if (flags & _HX5_MMU_PSTATS_ENABLE) { 5791 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5792 ENABLEf, 1); 5793 pf |= _HX5_MMU_PSTATS_ENABLE; 5794 if ((flags & _HX5_MMU_PSTATS_SYNC) || 5795 (flags & _HX5_MMU_PSTATS_HWM_MOD && 5796 flags & _HX5_MMU_PSTATS_RESET_ON_READ)) { 5797 soc->pstats_mode = PSTATS_MODE_PKT_SYNC; 5798 pf |= _HX5_MMU_PSTATS_SYNC; 5799 } else { 5800 soc->pstats_mode = PSTATS_MODE_PKT_BUFF; 5801 } 5802 } else { 5803 soc->pstats_mode = PSTATS_MODE_NULL; 5804 } 5805 5806 soc->pstats_flags = pf; 5807 5808 rv = WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval); 5809 5810 SOC_PSTATS_UNLOCK(unit); 5811 5812 return rv; 5813 } 5814 5815 int 5816 soc_helix5_mmu_pstats_mode_get(int unit, uint32 *flags) 5817 { 5818 int pf = 0; 5819 uint32 rval = 0; 5820 int rv; 5821 soc_reg_t reg = MMU_GCFG_PKTSTAT_OOBSTATr; 5822 5823 SOC_PSTATS_LOCK(unit); 5824 5825 rv = READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval); 5826 if (SOC_FAILURE(rv)) { 5827 SOC_PSTATS_UNLOCK(unit); 5828 return rv; 5829 } 5830 5831 if (soc_reg_field_get(unit, reg, rval, ENABLEf)) { 5832 pf |= _HX5_MMU_PSTATS_ENABLE; 5833 pf |= _HX5_MMU_PSTATS_PKT_MOD; 5834 } 5835 if (soc_reg_field_get(unit, reg, rval, HWM_MODEf)) { 5836 pf |= _HX5_MMU_PSTATS_HWM_MOD; 5837 if (soc_reg_field_get(unit, reg, rval, HWM_RESET_ON_READf)) { 5838 pf |= _HX5_MMU_PSTATS_RESET_ON_READ; 5839 } 5840 } 5841 5842 SOC_PSTATS_UNLOCK(unit); 5843 5844 *flags = pf; 5845 5846 return SOC_E_NONE; 5847 } 5848 5849 int 5850 soc_helix5_mmu_pstats_mor_enable(int unit) 5851 { 5852 soc_control_t *soc = SOC_CONTROL(unit); 5853 uint32 rval; 5854 5855 5856 if (soc->pstats_flags & _HX5_MMU_PSTATS_MOR_EN) { 5857 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval)); 5858 if ( ! soc_reg_field_get(unit, 5859 MMU_GCFG_PKTSTAT_OOBSTATr, rval, MOR_ENf)) { 5860 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 1); 5861 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval)); 5862 } 5863 } 5864 5865 return SOC_E_NONE; 5866 } 5867 5868 int 5869 soc_helix5_mmu_pstats_mor_disable(int unit) 5870 { 5871 soc_control_t *soc = SOC_CONTROL(unit); 5872 uint32 rval; 5873 5874 if (!soc_feature(unit, soc_feature_mor_dma) && 5875 (soc->pstats_flags & _HX5_MMU_PSTATS_MOR_EN)) { 5876 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval)); 5877 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 0); 5878 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval)); 5879 } 5880 5881 return SOC_E_NONE; 5882 } 5883 5884 /* 5885 * Function: 5886 * soc_hx5_port_schedule_tdm_init 5887 * Purpose: 5888 * Initialize TDM information in port_schedule_state that will be passed 5889 * to DV FlexPort API 5890 * Parameters: 5891 * unit - (IN) Unit number. 5892 * port_schedule_state - (OUT) Port resource state. 5893 * Returns: 5894 * BCM_E_xxx 5895 * Notes: 5896 * If called during Scheduler Initialization, only below values need to be 5897 * properly set: 5898 * soc_tdm_schedule_pipe_t::num_slices 5899 * soc_tdm_schedule_t:: cal_len 5900 * soc_tdm_schedule_t:: num_ovs_groups 5901 * soc_tdm_schedule_t:: ovs_group_len 5902 * soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space 5903 * soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len 5904 */ 5905 int 5906 soc_hx5_port_schedule_tdm_init(int unit, 5907 soc_port_schedule_state_t *port_schedule_state) 5908 { 5909 soc_control_t *soc = SOC_CONTROL(unit); 5910 _soc_helix5_tdm_temp_t *tdm = soc->tdm_info; 5911 /*soc_info_t *si = &SOC_INFO(unit);*/ 5912 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 5913 soc_tdm_schedule_t *sched; 5914 int pipe, hpipe, phy_port, is_flexport, group, slot; 5915 int *port_p2PBLK_inst_mapping; 5916 5917 if (tdm == NULL) { 5918 return SOC_E_INIT; 5919 } 5920 5921 is_flexport = port_schedule_state->is_flexport; 5922 /* 5923 port_schedule_state->calendar_type = si->fabric_port_enable ? 5924 _HX5_TDM_CALENDAR_UNIVERSAL : 5925 _HX5_TDM_CALENDAR_ETHERNET_OPTIMIZED; 5926 */ 5927 /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */ 5928 for (pipe = 0; pipe < HELIX5_TDM_PIPES_PER_DEV; pipe++) { 5929 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 5930 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 5931 5932 tdm_ischd->num_slices = HELIX5_OVS_HPIPE_COUNT_PER_PIPE; 5933 tdm_eschd->num_slices = HELIX5_OVS_HPIPE_COUNT_PER_PIPE; 5934 5935 if (is_flexport) { 5936 /* TDM Calendar is always in slice 0 */ 5937 sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 5938 tdm->tdm_pipe[pipe].idb_tdm, 5939 sizeof(int)*_HX5_TDM_LENGTH); 5940 sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 5941 tdm->tdm_pipe[pipe].mmu_tdm, 5942 sizeof(int)*_HX5_TDM_LENGTH); 5943 } 5944 5945 /* OVS */ 5946 for (hpipe = 0; hpipe < HELIX5_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 5947 /* IDB OVERSUB*/ 5948 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 5949 sched->cal_len = _HX5_TDM_LENGTH; 5950 sched->num_ovs_groups = HELIX5_TDM_OVS_GROUPS_PER_HPIPE; 5951 sched->ovs_group_len = HELIX5_TDM_OVS_GROUP_LENGTH; 5952 sched->num_pkt_sch_or_ovs_space = 1; 5953 sched->pkt_sch_or_ovs_space_len = _HX5_PKT_SCH_LENGTH; 5954 5955 if (is_flexport) { 5956 for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) { 5957 for (slot = 0; slot < HELIX5_TDM_OVS_GROUP_LENGTH; slot++) { 5958 sched->oversub_schedule[group][slot] = 5959 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 5960 } 5961 } 5962 for (slot = 0; slot < _HX5_PKT_SCH_LENGTH; slot++) { 5963 sched->pkt_sch_or_ovs_space[0][slot] = 5964 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 5965 } 5966 } 5967 5968 /* MMU OVERSUB */ 5969 sched = &tdm_eschd->tdm_schedule_slice[hpipe]; 5970 sched->cal_len = _HX5_TDM_LENGTH; 5971 sched->num_ovs_groups = HELIX5_TDM_OVS_GROUPS_PER_HPIPE; 5972 sched->ovs_group_len = HELIX5_TDM_OVS_GROUP_LENGTH; 5973 sched->num_pkt_sch_or_ovs_space = 1; 5974 sched->pkt_sch_or_ovs_space_len = _HX5_PKT_SCH_LENGTH; 5975 5976 if (is_flexport) { 5977 for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) { 5978 for (slot = 0; slot < HELIX5_TDM_OVS_GROUP_LENGTH; slot++) { 5979 sched->oversub_schedule[group][slot] = 5980 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 5981 } 5982 } 5983 for (slot = 0; slot < _HX5_PKT_SCH_LENGTH; slot++) { 5984 sched->pkt_sch_or_ovs_space[0][slot] = 5985 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 5986 } 5987 } 5988 } 5989 } 5990 5991 if (is_flexport) { 5992 port_p2PBLK_inst_mapping = 5993 port_schedule_state->in_port_map.port_p2PBLK_inst_mapping; 5994 /* pblk info for phy_port */ 5995 for (phy_port = 1; phy_port < HX5_NUM_EXT_PORTS; phy_port++) { 5996 if (tdm->pblk_info[phy_port].pblk_cal_idx == -1) { 5997 continue; 5998 } 5999 port_p2PBLK_inst_mapping[phy_port] = 6000 tdm->pblk_info[phy_port].pblk_cal_idx; 6001 } 6002 } 6003 return SOC_E_NONE; 6004 } 6005 6006 /* 6007 * Function: 6008 * soc_hx5_soc_tdm_update 6009 * Purpose: 6010 * Update TDM information in SOC with TDM state return from DV FlexPort API 6011 * Parameters: 6012 * unit - (IN) Unit number. 6013 * port_schedule_state - (OUT) Port resource state. 6014 * Returns: 6015 * BCM_E_xxx 6016 * Notes: 6017 */ 6018 int 6019 soc_hx5_soc_tdm_update(int unit, 6020 soc_port_schedule_state_t *port_schedule_state) 6021 { 6022 soc_control_t *soc = SOC_CONTROL(unit); 6023 _soc_helix5_tdm_temp_t *tdm = soc->tdm_info; 6024 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 6025 soc_tdm_schedule_t *sched; 6026 int pipe, hpipe, phy_port, slot; 6027 int index, group; 6028 6029 if (tdm == NULL) { 6030 return SOC_E_INIT; 6031 } 6032 6033 /* Copy info from soc_port_schedule_state_t to _soc_helix5_tdm_temp_t */ 6034 for (pipe = 0; pipe < HELIX5_TDM_PIPES_PER_DEV; pipe++) { 6035 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 6036 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 6037 6038 /* TDM Calendar is always in slice 0 */ 6039 sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm, 6040 tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 6041 sizeof(int)*_HX5_TDM_LENGTH); 6042 sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm, 6043 tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 6044 sizeof(int)*_HX5_TDM_LENGTH); 6045 6046 for (hpipe = 0; hpipe < HELIX5_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 6047 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 6048 for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) { 6049 for (slot = 0; slot < HELIX5_TDM_OVS_GROUP_LENGTH; slot++) { 6050 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot] = 6051 sched->oversub_schedule[group][slot]; 6052 } 6053 } 6054 for (slot = 0; slot < _HX5_PKT_SCH_LENGTH; slot++) { 6055 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot] = 6056 sched->pkt_sch_or_ovs_space[0][slot]; 6057 6058 } 6059 } 6060 } 6061 6062 /* pblk info init */ 6063 for (phy_port = 1; phy_port < HX5_NUM_EXT_PORTS; phy_port++) { 6064 tdm->pblk_info[phy_port].pblk_cal_idx = -1; 6065 tdm->pblk_info[phy_port].pblk_hpipe_num = -1; 6066 } 6067 6068 /* pblk info for phy_port */ 6069 for (pipe = 0; pipe < HELIX5_TDM_PIPES_PER_DEV; pipe++) { 6070 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 6071 for (hpipe = 0; hpipe < HELIX5_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 6072 for (group = 0; group < HELIX5_TDM_OVS_GROUPS_PER_HPIPE; group++) { 6073 for (index = 0; index < HELIX5_TDM_OVS_GROUP_LENGTH; index++) { 6074 phy_port = 6075 tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 6076 if (phy_port < HX5_NUM_EXT_PORTS) { 6077 tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe; 6078 tdm->pblk_info[phy_port].pblk_cal_idx = 6079 port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port]; 6080 } 6081 } 6082 } 6083 } 6084 } 6085 6086 return SOC_E_NONE; 6087 } 6088 6089 void 6090 soc_helix5_port_qsgmii_mode_get(int unit, soc_port_t port, int* qsgmii_mode) 6091 { 6092 soc_info_t *si; 6093 int phy_port, base_port; 6094 6095 si = &SOC_INFO(unit); 6096 6097 phy_port = si->port_l2p_mapping[port]; 6098 base_port = HX5_PORT_BLOCK_BASE_PORT(port); 6099 6100 if ((phy_port >= 1) && (phy_port <= 48)) { 6101 *qsgmii_mode = soc_property_phys_port_get(unit, base_port, 6102 spn_PORT_GMII_MODE, 0); 6103 } else { 6104 *qsgmii_mode = 0; 6105 } 6106 6107 return; 6108 } 6109 6110 int 6111 soc_hx5_mpls_hash_control_set(int *hash_entry) 6112 { 6113 int unit = 0; 6114 int mpls_4k_banks = 0; 6115 int index = 0; 6116 int offset_base = 0, offset_multiplier = 0; 6117 int hash_control_entry[2]; 6118 uint32 shared_4k_hash_control_entry[8]; 6119 6120 static const soc_field_t logical_to_physical_fields[] = { 6121 LOGICAL_BANK_0_PHYSICAL_BANK_LOCATIONf, 6122 LOGICAL_BANK_1_PHYSICAL_BANK_LOCATIONf, 6123 LOGICAL_BANK_2_PHYSICAL_BANK_LOCATIONf, 6124 LOGICAL_BANK_3_PHYSICAL_BANK_LOCATIONf, 6125 LOGICAL_BANK_4_PHYSICAL_BANK_LOCATIONf, 6126 LOGICAL_BANK_5_PHYSICAL_BANK_LOCATIONf, 6127 LOGICAL_BANK_6_PHYSICAL_BANK_LOCATIONf, 6128 LOGICAL_BANK_7_PHYSICAL_BANK_LOCATIONf, 6129 LOGICAL_BANK_8_PHYSICAL_BANK_LOCATIONf, 6130 LOGICAL_BANK_9_PHYSICAL_BANK_LOCATIONf 6131 }; 6132 6133 static const soc_field_t shared_fields[] = { 6134 B0_HASH_OFFSETf, B1_HASH_OFFSETf, B2_HASH_OFFSETf, B3_HASH_OFFSETf, 6135 B4_HASH_OFFSETf, B5_HASH_OFFSETf, B6_HASH_OFFSETf, B7_HASH_OFFSETf 6136 }; 6137 6138 sal_memset(hash_control_entry, 0, 6139 sizeof(mpls_entry_hash_control_entry_t)); 6140 sal_memset(shared_4k_hash_control_entry, 0, 6141 sizeof(ip_uat_shared_banks_control_entry_t)); 6142 6143 SOC_IF_ERROR_RETURN 6144 (soc_helix5_hash_bank_count_get(unit, MPLS_ENTRY_SINGLEm, 6145 &mpls_4k_banks)); 6146 SOC_IF_ERROR_RETURN 6147 (READ_IP_UAT_SHARED_BANKS_CONTROLm(unit, MEM_BLOCK_ANY, 0, 6148 shared_4k_hash_control_entry)); 6149 SOC_IF_ERROR_RETURN 6150 (READ_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ANY, 0, 6151 hash_control_entry)); 6152 sal_memcpy(hash_entry, hash_control_entry, sizeof(hash_control_entry)); 6153 6154 if (mpls_4k_banks) { 6155 offset_base = 64 % (mpls_4k_banks); 6156 offset_multiplier = 64 / (mpls_4k_banks); 6157 } 6158 6159 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 6160 HASH_TABLE_BANK_CONFIGf, ((1 << mpls_4k_banks) - 1)); 6161 for(index = 0; index < mpls_4k_banks; index++) { 6162 soc_mem_field32_set(unit, MPLS_ENTRY_HASH_CONTROLm, hash_control_entry, 6163 logical_to_physical_fields[index], index); 6164 soc_mem_field32_set(unit, IP_UAT_SHARED_BANKS_CONTROLm, 6165 shared_4k_hash_control_entry, shared_fields[index], 6166 offset_base + ( index * offset_multiplier)); 6167 } 6168 6169 SOC_IF_ERROR_RETURN 6170 (WRITE_MPLS_ENTRY_HASH_CONTROLm(unit, MEM_BLOCK_ALL, 0, 6171 hash_control_entry)); 6172 6173 return SOC_E_NONE; 6174 } 6175 6176 6177 void 6178 soc_helix5_temperature_intr(void *unit_vp, void *d1, void *d2, 6179 void *d3, void *d4) 6180 { 6181 uint32 rval, trval; 6182 int i, rv, unit = PTR_TO_INT(unit_vp); 6183 6184 if ((rv = READ_TOP_PVTMON_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) { 6185 LOG_ERROR(BSL_LS_SOC_COMMON, 6186 (BSL_META_U(unit, 6187 "TD3 Temp Intr, Reg access error.\n"))); 6188 } 6189 LOG_ERROR(BSL_LS_SOC_COMMON, 6190 (BSL_META_U(unit, 6191 "High temp interrupt: 0x%08x\n"), rval)); 6192 /* Raise event to app for it to take further graceful actions */ 6193 for (i = 0; i < 7; i++) { 6194 if (i & _soc_hx5_temp_mon_mask[unit]) { 6195 if ((rv = soc_reg32_get(unit, pvtmon_result_reg[i], REG_PORT_ANY, 0, 6196 &trval)) != SOC_E_NONE) { 6197 LOG_ERROR(BSL_LS_SOC_COMMON, 6198 (BSL_META_U(unit, 6199 "TD3 Temp Intr, Reg access error.\n"))); 6200 } 6201 trval = soc_reg_field_get(unit, pvtmon_result_reg[i], trval, 6202 PVT_DATAf); 6203 /* Convert data to temperature. 6204 * temp = 434.1-(data*0.5350) = (4341000-(trval*5350))/1000; 6205 * Note: Since this is a high temp interrupt we can safely assume 6206 * that this will end up being a +ive value. 6207 */ 6208 trval = (4341000-(trval*5350))/1000; 6209 6210 LOG_ERROR(BSL_LS_SOC_COMMON, 6211 (BSL_META_U(unit, 6212 "TempMon %d: %d deg C.\n"), i, trval)); 6213 (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM, 6214 SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval); 6215 } 6216 } 6217 /* Optionally hold system in reset. 6218 * Note: The main intention is to stop the chip from getting fried and halt 6219 * all schan accesses as the h/w will not respond anymore. 6220 * We are not implementing a gracefull recovery, the unit needs to be 6221 * rebooted after this. 6222 */ 6223 if (soc_property_get(unit, "temp_monitor_shutdown", 1)) { 6224 if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) { 6225 LOG_ERROR(BSL_LS_SOC_COMMON, 6226 (BSL_META_U(unit, 6227 "TH Temp Intr, Reg access error.\n"))); 6228 } 6229 if ((rv = WRITE_TOP_SOFT_RESET_REGr(unit, 0)) != SOC_E_NONE) { 6230 LOG_ERROR(BSL_LS_SOC_COMMON, 6231 (BSL_META_U(unit, 6232 "TH Temp Intr, Reg access error.\n"))); 6233 } 6234 if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) { 6235 LOG_ERROR(BSL_LS_SOC_COMMON, 6236 (BSL_META_U(unit, 6237 "TH Temp Intr, Reg access error.\n"))); 6238 } 6239 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf, 6240 0); 6241 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf, 6242 0); 6243 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 6244 1); 6245 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 6246 if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) { 6247 LOG_ERROR(BSL_LS_SOC_COMMON, 6248 (BSL_META_U(unit, 6249 "TH Temp Intr, Reg access error.\n"))); 6250 } 6251 if ((rv = WRITE_TOP_SOFT_RESET_REG_3r(unit, 0)) != SOC_E_NONE) { 6252 LOG_ERROR(BSL_LS_SOC_COMMON, 6253 (BSL_META_U(unit, 6254 "TH Temp Intr, Reg access error.\n"))); 6255 } 6256 6257 /* Stop all schan transactions on this unit */ 6258 #ifdef INCLUDE_I2C 6259 if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) { 6260 LOG_ERROR(BSL_LS_SOC_COMMON, 6261 (BSL_META_U(unit, 6262 "TH Temp Intr, i2c detach error.\n"))); 6263 } 6264 #endif 6265 if (!SOC_IS_RCPU_ONLY(unit)) { 6266 /* Free up DMA memory */ 6267 if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) { 6268 LOG_ERROR(BSL_LS_SOC_COMMON, 6269 (BSL_META_U(unit, 6270 "TH Temp Intr, dma detach error.\n"))); 6271 } 6272 } 6273 if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) { 6274 LOG_ERROR(BSL_LS_SOC_COMMON, 6275 (BSL_META_U(unit, 6276 "TH Temp Intr, mem scan stop error.\n"))); 6277 } 6278 /* Terminate counter module */ 6279 if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) { 6280 LOG_ERROR(BSL_LS_SOC_COMMON, 6281 (BSL_META_U(unit, 6282 "TH Temp Intr, counter stop error.\n"))); 6283 } 6284 if (SOC_SBUSDMA_DM_INFO(unit)) { 6285 if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) { 6286 LOG_ERROR(BSL_LS_SOC_COMMON, 6287 (BSL_META_U(unit, 6288 "TH Temp Intr, sbusdma stop error.\n"))); 6289 } 6290 } 6291 if (soc_feature(unit, soc_feature_arl_hashed)) { 6292 /* Stop L2X thread */ 6293 if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) { 6294 LOG_ERROR(BSL_LS_SOC_COMMON, 6295 (BSL_META_U(unit, 6296 "TH Temp Intr, L2x stop error.\n"))); 6297 } 6298 6299 } 6300 if ((rv = soc_th_l2_bulk_age_stop(unit)) != SOC_E_NONE) { 6301 LOG_ERROR(BSL_LS_SOC_COMMON, 6302 (BSL_META_U(unit, 6303 "TH Temp Intr, L2 age stop error.\n"))); 6304 } 6305 /* Disable all interrupts */ 6306 #ifdef BCM_CMICX_SUPPORT 6307 if (soc_feature(unit, soc_feature_cmicx)) { 6308 6309 } 6310 #endif 6311 SCHAN_LOCK(unit); 6312 /* Clear all outstanding DPCs owned by this unit */ 6313 sal_dpc_cancel(INT_TO_PTR(unit)); 6314 LOG_ERROR(BSL_LS_SOC_COMMON, 6315 (BSL_META_U(unit, 6316 "\nReboot the system.."))); 6317 } 6318 } 6319 6320 int 6321 soc_helix5_temperature_monitor_get(int unit, int temperature_max, 6322 soc_switch_temperature_monitor_t *temperature_array, int *temperature_count) 6323 { 6324 soc_reg_t reg; 6325 int index; 6326 uint32 rval; 6327 int fval, cur, peak; 6328 int num_entries_out; 6329 if (temperature_count) { 6330 *temperature_count = 0; 6331 } 6332 if (COUNTOF(pvtmon_result_reg) > temperature_max) { 6333 num_entries_out = temperature_max; 6334 } else { 6335 num_entries_out = COUNTOF(pvtmon_result_reg); 6336 } 6337 /* SDK-125480 temperature reading for VTMON 11 6338 * Assert TOP_AVS_RST_L. 6339 */ 6340 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 6341 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6342 TOP_AVS_RST_Lf, 0); 6343 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 6344 6345 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_3r(unit, &rval)); 6346 if ((soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_RESET_Nf) == 0) || 6347 (soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_SELECTf) != 0)) { 6348 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 0); 6349 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval)); 6350 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 1); 6351 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_SELECTf, 0); 6352 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval)); 6353 sal_usleep(1000); 6354 } 6355 6356 for (index = 0; index < num_entries_out; index++) { 6357 reg = pvtmon_result_reg[index]; 6358 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 6359 6360 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 6361 cur = (4341000-(fval*5350))/1000; 6362 6363 fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf); 6364 peak = (4341000-(fval*5350))/1000; 6365 6366 if (temperature_array) { 6367 (temperature_array + index)->curr = cur; 6368 (temperature_array + index)->peak = peak; 6369 } 6370 } 6371 6372 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 6373 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6374 TOP_PVT_MON_MIN_RST_Lf, 0); 6375 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 6376 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6377 TOP_PVT_MON_MIN_RST_Lf, 1); 6378 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 6379 6380 if (temperature_count) { 6381 *temperature_count=num_entries_out; 6382 } 6383 return SOC_E_NONE; 6384 } 6385 6386 void 6387 soc_helix5_sbus_ring_map_config(int unit) 6388 { 6389 /* 6390 * SBUS ring and block number: 6391 * ring 0: IP(1), LBPORT0(54), LBPORT1(51), LBPORT2(52), LBPORT3(53) 6392 * ring 1: EP(2) 6393 * ring 2: MMU_XPE(3), MMU_SC(4), MMU_GLB(5) 6394 * ring 3: PM7(22), PM6(21), PM5(20), PM4(19), PM3(18), PM2(17), PM1(16), 6395 * PM0(15), PM31(46), PM30(45), PM29(44), PM28(43), PM27(42), 6396 * PM26(41), PM25(40), PM24(39), CLPORT32(55) 6397 * ring 4: PM32(11), PM8(23), PM9(24), PM10(25), PM11(26), PM12(27), 6398 * PM13(28), PM14(29), PM15(30), PM16(31), PM17(32), PM18(33), 6399 * PM19(34), PM20(35), PM21(36), PM22(37), PM23(38) 6400 * ring 5: OTPC(6), AVS(59), TOP(7), SER(8) 6401 */ 6402 6403 6404 #ifdef BCM_CMICX_SUPPORT 6405 if (soc_feature(unit, soc_feature_cmicx)) { 6406 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_0_7_OFFSET,0x52222100); 6407 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_8_15_OFFSET,0x30050005); 6408 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_16_23_OFFSET,0x33333333); 6409 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_24_31_OFFSET,0x64444333); 6410 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_32_39_OFFSET,0x07500066); 6411 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_40_47_OFFSET,0x00000000); 6412 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_48_55_OFFSET,0x00000000); 6413 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_56_63_OFFSET,0x00000000); 6414 soc_pci_write(unit, CMIC_TOP_SBUS_TIMEOUT_OFFSET,0x5000); 6415 } 6416 #endif 6417 6418 return; 6419 } 6420 6421 /* 6422 * Function: 6423 * soc_hx5_support_speeds 6424 * Purpose: 6425 * Get the supported speed of port for specified lanes 6426 * Parameters: 6427 * unit - (IN) Unit number. 6428 * ports - (IN) Logical port number. 6429 * speed_mask - (IN) Bitmap for supported speed. 6430 * Returns: 6431 * BCM_E_xxx 6432 */ 6433 int 6434 soc_hx5_support_speeds(int unit, int port, uint32 *speed_mask) 6435 { 6436 uint32 speed_valid; 6437 int phy_port, lanes; 6438 soc_info_t *si = &SOC_INFO(unit); 6439 6440 phy_port = si->port_l2p_mapping[port]; 6441 lanes = si->port_num_lanes[port]; 6442 6443 switch(lanes) { 6444 case 1: 6445 /* Single Lane Port Speeds */ 6446 speed_valid = SOC_PA_SPEED_1000MB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_11GB; 6447 if (PORT_IS_FALCON(unit, phy_port)) { 6448 speed_valid |= SOC_PA_SPEED_25GB | SOC_PA_SPEED_27GB; 6449 } else { 6450 speed_valid |= SOC_PA_SPEED_10MB | SOC_PA_SPEED_100MB | 6451 SOC_PA_SPEED_2500MB | SOC_PA_SPEED_5000MB; 6452 } 6453 break; 6454 case 2: 6455 /* Dual Lane Port Speeds */ 6456 speed_valid = SOC_PA_SPEED_20GB | SOC_PA_SPEED_21GB; 6457 if (PORT_IS_FALCON(unit, phy_port)) { 6458 speed_valid |= SOC_PA_SPEED_40GB | SOC_PA_SPEED_42GB | 6459 SOC_PA_SPEED_50GB | SOC_PA_SPEED_53GB; 6460 } else { 6461 speed_valid |= SOC_PA_SPEED_10GB | SOC_PA_SPEED_11GB; 6462 } 6463 break; 6464 case 4: 6465 /* Quad Lane Port Speeds */ 6466 speed_valid = SOC_PA_SPEED_40GB | SOC_PA_SPEED_42GB | 6467 SOC_PA_SPEED_100GB; 6468 break; 6469 default: 6470 return SOC_E_PARAM; 6471 } 6472 6473 *speed_mask = speed_valid; 6474 6475 return SOC_E_NONE; 6476 } 6477 6478 6479 #ifdef BCM_WARM_BOOT_SUPPORT 6480 6481 #define SOC_FLEXPORT_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 6482 #define SOC_FLEXPORT_WB_DEFAULT_VERSION SOC_FLEXPORT_WB_VERSION_1_0 6483 6484 int 6485 soc_hx5_flexport_scache_allocate(int unit) 6486 { 6487 int rv = SOC_E_NONE; 6488 uint8 *flexport_scache_ptr; 6489 soc_scache_handle_t scache_handle; 6490 uint32 alloc_get = 0; 6491 uint32 alloc_size = 0; 6492 int stable_size; 6493 int default_ver = SOC_FLEXPORT_WB_DEFAULT_VERSION; 6494 6495 alloc_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to logical*/ 6496 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to mmu */ 6497 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* logical to phy */ 6498 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* max port speed */ 6499 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* init port speed */ 6500 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* num of lanes */ 6501 (sizeof(pbmp_t)) + /* HG bitmap */ 6502 (sizeof(pbmp_t)); /* Disabled bitmap */ 6503 6504 alloc_get = alloc_size; 6505 6506 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 6507 /* check to see if an scache table has been configured */ 6508 rv = soc_stable_size_get(unit, &stable_size); 6509 if (SOC_FAILURE(rv) || stable_size <= 0) { 6510 return rv; 6511 } 6512 6513 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6514 TRUE, &alloc_get, 6515 &flexport_scache_ptr, 6516 default_ver, 6517 NULL); 6518 6519 if (rv == SOC_E_CONFIG) { 6520 /* Probably Level1 */ 6521 return SOC_E_NONE; 6522 } 6523 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 6524 if (alloc_get != alloc_size) { 6525 /* Expected size doesn't match retrieved size */ 6526 LOG_ERROR(BSL_LS_SOC_COMMON, 6527 (BSL_META_U(unit, 6528 "ERROR: scache memory for flexport size mismatch" 6529 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6530 return SOC_E_INTERNAL; 6531 } 6532 6533 if (NULL == flexport_scache_ptr) { 6534 LOG_ERROR(BSL_LS_SOC_COMMON, 6535 (BSL_META_U(unit, 6536 "ERROR: scache memory not allocated for flexport" 6537 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6538 return SOC_E_MEMORY; 6539 } 6540 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6541 (BSL_META_U(unit, 6542 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6543 return SOC_E_NONE; 6544 6545 } 6546 6547 /* 6548 * Function: 6549 * soc_hx5_flexport_scache_sync 6550 * Purpose: 6551 * Record Port info that maybe changed during flexport for Level 2 WB 6552 * 6553 * Warm Boot Version Map: 6554 * 6555 * BCM_WB_VERSION_1_0 6556 * port_speed_max 6557 * port_init_speed 6558 * port_num_lanes 6559 * disabled_bitmap 6560 * 6561 * Parameters: 6562 * unit - StrataSwitch unit number. 6563 * Returns: 6564 * SOC_E_XXX 6565 */ 6566 int 6567 soc_hx5_flexport_scache_sync(int unit) 6568 { 6569 uint8 *flexport_scache_ptr; 6570 soc_scache_handle_t scache_handle; 6571 uint32 alloc_get = 0; 6572 uint32 alloc_size = 0; 6573 uint32 var_size = 0; 6574 soc_info_t *si = &SOC_INFO(unit); 6575 uint32 scache_offset=0; 6576 int rv = 0; 6577 6578 alloc_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to logical*/ 6579 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to mmu */ 6580 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* logical to phy */ 6581 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* max port speed */ 6582 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* init port speed */ 6583 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* num of lanes */ 6584 (sizeof(pbmp_t)) + /* HG bitmap */ 6585 (sizeof(pbmp_t)); /* Disabled bitmap */ 6586 6587 alloc_get = alloc_size; 6588 6589 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 6590 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6591 FALSE, &alloc_get, 6592 &flexport_scache_ptr, 6593 SOC_FLEXPORT_WB_DEFAULT_VERSION, 6594 NULL); 6595 if (rv == SOC_E_NOT_FOUND) { 6596 /* Probably Level1 */ 6597 return SOC_E_NONE; 6598 } 6599 if (alloc_get != alloc_size) { 6600 /* Expected size doesn't match retrieved size */ 6601 LOG_ERROR(BSL_LS_SOC_COMMON, 6602 (BSL_META_U(unit, 6603 "ERROR: scache memory for flexport size mismatch" 6604 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6605 return SOC_E_INTERNAL; 6606 } 6607 if (NULL == flexport_scache_ptr) { 6608 LOG_ERROR(BSL_LS_SOC_COMMON, 6609 (BSL_META_U(unit, 6610 "ERROR: scache memory not allocated for flexport" 6611 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6612 return SOC_E_MEMORY; 6613 } 6614 6615 /* Physical to logical port mapping */ 6616 var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV; 6617 sal_memcpy(&flexport_scache_ptr[scache_offset], 6618 si->port_p2l_mapping, var_size); 6619 scache_offset += var_size; 6620 6621 6622 /* Physical to MMU port mapping */ 6623 var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV; 6624 sal_memcpy(&flexport_scache_ptr[scache_offset], 6625 si->port_p2m_mapping, var_size); 6626 scache_offset += var_size; 6627 6628 /* Logical to Physical port mapping */ 6629 var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV; 6630 sal_memcpy(&flexport_scache_ptr[scache_offset], 6631 si->port_l2p_mapping, var_size); 6632 scache_offset += var_size; 6633 6634 /* Max port speed */ 6635 var_size = sizeof(int) * HELIX5_PHY_PORTS_PER_DEV; 6636 6637 sal_memcpy(&flexport_scache_ptr[scache_offset], 6638 si->port_speed_max, var_size); 6639 scache_offset += var_size; 6640 6641 /* Init port speed */ 6642 sal_memcpy(&flexport_scache_ptr[scache_offset], 6643 si->port_init_speed, var_size); 6644 scache_offset += var_size; 6645 6646 /* Num of lanes */ 6647 sal_memcpy(&flexport_scache_ptr[scache_offset], 6648 si->port_num_lanes, var_size); 6649 scache_offset += var_size; 6650 6651 /* HG Bitmap */ 6652 sal_memcpy(&flexport_scache_ptr[scache_offset], 6653 &si->hg.bitmap, 6654 sizeof(pbmp_t)); 6655 scache_offset += sizeof(pbmp_t); 6656 6657 /* Disabled Port Bitmap */ 6658 sal_memcpy(&flexport_scache_ptr[scache_offset], 6659 &si->all.disabled_bitmap, 6660 sizeof(pbmp_t)); 6661 scache_offset += sizeof(pbmp_t); 6662 6663 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6664 (BSL_META_U(unit, 6665 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 6666 6667 return SOC_E_NONE; 6668 } 6669 6670 /* 6671 * Function: 6672 * soc_hx5_flexport_scache_recovery 6673 * Purpose: 6674 * Recover Port info that maybe changed during flexport for Level 2 WB 6675 * 6676 * Warm Boot Version Map: 6677 * 6678 * BCM_WB_VERSION_1_0 6679 * port_p2l_mapping 6680 * port_l2p_mapping 6681 * port_speed_max 6682 * port_init_speed 6683 * port_num_lanes 6684 * disabled_bitmap 6685 * 6686 * Parameters: 6687 * unit - StrataSwitch unit number. 6688 * Returns: 6689 * SOC_E_XXX 6690 */ 6691 int 6692 soc_hx5_flexport_scache_recovery(int unit) 6693 { 6694 uint32 alloc_get = 0; 6695 uint32 alloc_size = 0; 6696 int rv = SOC_E_NONE, port, phy_port; 6697 uint8 *flexport_scache_ptr = NULL; 6698 soc_scache_handle_t scache_handle; 6699 uint32 scache_offset=0; 6700 uint32 var_size = 0; 6701 uint16 recovered_ver = 0; 6702 soc_info_t *si = &SOC_INFO(unit); 6703 6704 alloc_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to logical*/ 6705 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* phy to mmu */ 6706 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* logical to phy */ 6707 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* max port speed */ 6708 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* init port speed */ 6709 (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV) + /* num of lanes */ 6710 (sizeof(pbmp_t)) + /* HG bitmap */ 6711 (sizeof(pbmp_t)); /* Disabled bitmap */ 6712 6713 alloc_get = alloc_size; 6714 6715 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 6716 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6717 FALSE, &alloc_get, 6718 &flexport_scache_ptr, 6719 SOC_FLEXPORT_WB_DEFAULT_VERSION, 6720 &recovered_ver); 6721 if (SOC_FAILURE(rv)) { 6722 if ((rv == SOC_E_CONFIG) || 6723 (rv == SOC_E_NOT_FOUND)) { 6724 /* warmboot file does not contain this 6725 * module, or the warmboot state does not exist. 6726 * in this case return SOC_E_NOT_FOUND 6727 */ 6728 return SOC_E_NOT_FOUND; 6729 } else { 6730 /* Only Level2 - flexport treat this as a error */ 6731 LOG_ERROR(BSL_LS_SOC_COMMON, 6732 (BSL_META_U(unit, 6733 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 6734 return rv; 6735 } 6736 } 6737 if (alloc_get != alloc_size) { 6738 /* Expected size doesn't match retrieved size */ 6739 LOG_ERROR(BSL_LS_SOC_COMMON, 6740 (BSL_META_U(unit, 6741 "ERROR: scache recovery for flexport" 6742 "%s()[LINE:%d] DONE \n"), 6743 FUNCTION_NAME(), __LINE__)); 6744 return SOC_E_INTERNAL; 6745 } 6746 6747 if (NULL == flexport_scache_ptr) { 6748 LOG_ERROR(BSL_LS_SOC_COMMON, 6749 (BSL_META_U(unit, 6750 "ERROR: scache recovery for flexport" 6751 "%s()[LINE:%d] DONE \n"), 6752 FUNCTION_NAME(), __LINE__)); 6753 return SOC_E_MEMORY; 6754 } 6755 6756 /*Physical to logical port mapping */ 6757 var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV); 6758 sal_memcpy(si->port_p2l_mapping, 6759 &flexport_scache_ptr[scache_offset], 6760 var_size); 6761 scache_offset += var_size; 6762 6763 /*Physical to MMU port mapping */ 6764 var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV); 6765 sal_memcpy(si->port_p2m_mapping, 6766 &flexport_scache_ptr[scache_offset], 6767 var_size); 6768 scache_offset += var_size; 6769 6770 /*Logical to Physical port mapping*/ 6771 var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV); 6772 sal_memcpy(si->port_l2p_mapping, 6773 &flexport_scache_ptr[scache_offset], 6774 var_size); 6775 scache_offset += var_size; 6776 6777 /* Max port speed */ 6778 var_size = (sizeof(int) * HELIX5_PHY_PORTS_PER_DEV); 6779 6780 sal_memcpy(si->port_speed_max, 6781 &flexport_scache_ptr[scache_offset], 6782 var_size); 6783 scache_offset += var_size; 6784 6785 /* Init port speed */ 6786 sal_memcpy(si->port_init_speed, 6787 &flexport_scache_ptr[scache_offset], 6788 var_size); 6789 scache_offset += var_size; 6790 6791 /* Num of lanes */ 6792 sal_memcpy(si->port_num_lanes, 6793 &flexport_scache_ptr[scache_offset], 6794 var_size); 6795 scache_offset += var_size; 6796 6797 /* HG Bitmap */ 6798 sal_memcpy(&si->hg.bitmap, 6799 &flexport_scache_ptr[scache_offset], 6800 sizeof(pbmp_t)); 6801 scache_offset += sizeof(pbmp_t); 6802 6803 /* Disabled Port Bitmap */ 6804 sal_memcpy(&si->all.disabled_bitmap, 6805 &flexport_scache_ptr[scache_offset], 6806 sizeof(pbmp_t)); 6807 scache_offset += sizeof(pbmp_t); 6808 6809 SOC_PBMP_CLEAR(si->pipe_pbm[0]); 6810 6811 for (port = 1; port < HX5_NUM_PORT; port++) { 6812 phy_port = si->port_l2p_mapping[port]; 6813 if (phy_port == -1) { 6814 SOC_PBMP_PORT_REMOVE(si->oversub_pbm, port); 6815 si->port_l2i_mapping[port] = -1; 6816 si->port_serdes[port] = -1; 6817 si->port_pipe[port] = -1; 6818 continue; 6819 } 6820 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 6821 if (phy_port <= 48) { 6822 si->port_serdes[port] = (phy_port - 1) / _HX5_PORTS_PER_PMQ_PBLK; 6823 } else { 6824 si->port_serdes[port] = ((phy_port - 1) / _HX5_PORTS_PER_PBLK) - 9; 6825 } 6826 si->port_pipe[port] = 0; 6827 SOC_PBMP_PORT_ADD(si->pipe_pbm[0], port); 6828 6829 if (soc_hx5_port_oversub_get(unit, phy_port, port)) { 6830 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 6831 } 6832 } 6833 6834 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6835 (BSL_META_U(unit, 6836 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 6837 6838 return SOC_E_NONE; 6839 } 6840 6841 #define SOC_TDM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 6842 #define SOC_TDM_WB_DEFAULT_VERSION SOC_TDM_WB_VERSION_1_0 6843 6844 /* 6845 * Function: 6846 * soc_hx5_tdm_scache_allocate 6847 * Purpose: 6848 * Calculate TDM info that maybe changed during flexport for Level 2 WB 6849 * 6850 * Warm Boot Version Map: 6851 * 6852 * BCM_WB_VERSION_1_0 6853 * IDB TDM info on pipe0 6854 * MMU TDM info on pipe0 6855 * Oversub group info on pipe0 6856 * pkt shaper info on pipe0 6857 * pblk id of phy-port 6858 * port ratio 6859 * oversub ratio 6860 * 6861 * Parameters: 6862 * unit - StrataSwitch unit number. 6863 * Returns: 6864 * SOC_E_XXX 6865 */ 6866 int soc_hx5_tdm_scache_allocate(int unit) 6867 { 6868 int rv = SOC_E_NONE; 6869 uint8 *tdm_scache_ptr; 6870 soc_scache_handle_t scache_handle; 6871 uint32 alloc_get = 0; 6872 uint32 alloc_size = 0; 6873 int stable_size; 6874 int default_ver = SOC_TDM_WB_DEFAULT_VERSION; 6875 int ilen, ovs_size, pkt_shp_size, hpipes; 6876 6877 ilen = sizeof(int); 6878 ovs_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE * 6879 HELIX5_OVS_GROUP_COUNT_PER_HPIPE * 6880 HELIX5_OVS_GROUP_TDM_LENGTH; 6881 pkt_shp_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE * 6882 _HX5_PKT_SCH_LENGTH; 6883 hpipes = HELIX5_PIPES_PER_DEV * HELIX5_OVS_HPIPE_COUNT_PER_PIPE; 6884 6885 alloc_size = (ilen * HELIX5_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 6886 (ilen * HELIX5_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 6887 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 6888 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 6889 (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 6890 (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 6891 (ilen * HELIX5_PBLKS_PER_DEV) + /* port ratio */ 6892 (ilen * hpipes); /* oversub ratio */ 6893 alloc_get = alloc_size; 6894 6895 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 6896 /* check to see if an scache table has been configured */ 6897 rv = soc_stable_size_get(unit, &stable_size); 6898 if (SOC_FAILURE(rv) || stable_size <= 0) { 6899 return rv; 6900 } 6901 6902 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6903 TRUE, &alloc_get, 6904 &tdm_scache_ptr, 6905 default_ver, 6906 NULL); 6907 6908 if (rv == SOC_E_CONFIG) { 6909 /* Probably Level1 */ 6910 return SOC_E_NONE; 6911 } 6912 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 6913 if (alloc_get != alloc_size) { 6914 /* Expected size doesn't match retrieved size */ 6915 LOG_ERROR(BSL_LS_SOC_COMMON, 6916 (BSL_META_U(unit, 6917 "ERROR: scache memory for tdm size mismatch" 6918 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6919 return SOC_E_INTERNAL; 6920 } 6921 6922 if (NULL == tdm_scache_ptr) { 6923 LOG_ERROR(BSL_LS_SOC_COMMON, 6924 (BSL_META_U(unit, 6925 "ERROR: scache memory not allocated for tdm" 6926 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6927 return SOC_E_MEMORY; 6928 } 6929 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6930 (BSL_META_U(unit, 6931 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6932 return SOC_E_NONE; 6933 } 6934 6935 /* 6936 * Function: 6937 * soc_hx5_tdm_scache_sync 6938 * Purpose: 6939 * Record TDM info that maybe changed during flexport for Level 2 WB 6940 * 6941 * Warm Boot Version Map: 6942 * 6943 * BCM_WB_VERSION_1_0 6944 * IDB TDM info on pipe0 6945 * MMU TDM info on pipe0 6946 * Oversub group info on pipe0 6947 * pkt shaper info on pipe0 6948 * pblk id of phy-port 6949 * port ratio 6950 * oversub ratio 6951 * 6952 * Parameters: 6953 * unit - StrataSwitch unit number. 6954 * Returns: 6955 * SOC_E_XXX 6956 */ 6957 int soc_hx5_tdm_scache_sync(int unit) 6958 { 6959 uint8 *tdm_scache_ptr; 6960 soc_scache_handle_t scache_handle; 6961 uint32 alloc_get = 0; 6962 uint32 alloc_size = 0; 6963 uint32 var_size = 0; 6964 uint32 scache_offset=0; 6965 int rv = 0; 6966 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 6967 _soc_helix5_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info; 6968 6969 ilen = sizeof(int); 6970 ovs_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE * 6971 HELIX5_OVS_GROUP_COUNT_PER_HPIPE * 6972 HELIX5_OVS_GROUP_TDM_LENGTH; 6973 pkt_shp_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE * 6974 _HX5_PKT_SCH_LENGTH; 6975 hpipes = HELIX5_PIPES_PER_DEV * HELIX5_OVS_HPIPE_COUNT_PER_PIPE; 6976 6977 alloc_size = (ilen * HELIX5_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 6978 (ilen * HELIX5_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 6979 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 6980 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 6981 (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 6982 (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 6983 (ilen * HELIX5_PBLKS_PER_DEV) + /* port ratio */ 6984 (ilen * hpipes); /* oversub ratio */ 6985 alloc_get = alloc_size; 6986 6987 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 6988 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6989 FALSE, &alloc_get, 6990 &tdm_scache_ptr, 6991 SOC_TDM_WB_DEFAULT_VERSION, 6992 NULL); 6993 if (rv == SOC_E_NOT_FOUND) { 6994 /* Probably Level1 */ 6995 return SOC_E_NONE; 6996 } 6997 if (alloc_get != alloc_size) { 6998 /* Expected size doesn't match retrieved size */ 6999 LOG_ERROR(BSL_LS_SOC_COMMON, 7000 (BSL_META_U(unit, 7001 "ERROR: scache memory for tdm size mismatch" 7002 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 7003 return SOC_E_INTERNAL; 7004 } 7005 if (NULL == tdm_scache_ptr) { 7006 LOG_ERROR(BSL_LS_SOC_COMMON, 7007 (BSL_META_U(unit, 7008 "ERROR: scache memory not allocated for tdm" 7009 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 7010 return SOC_E_MEMORY; 7011 } 7012 7013 /* IDB TDM info on pipe0 */ 7014 var_size = ilen * HELIX5_TDM_LENGTH; 7015 sal_memcpy(&tdm_scache_ptr[scache_offset], 7016 tdm->tdm_pipe[0].idb_tdm, 7017 var_size); 7018 scache_offset += var_size; 7019 7020 /* MMU TDM info on pipe0 */ 7021 var_size = ilen * HELIX5_TDM_LENGTH; 7022 sal_memcpy(&tdm_scache_ptr[scache_offset], 7023 tdm->tdm_pipe[0].mmu_tdm, 7024 var_size); 7025 scache_offset += var_size; 7026 7027 /* Oversub group info on pipe0 */ 7028 var_size = ilen * ovs_size; 7029 sal_memcpy(&tdm_scache_ptr[scache_offset], 7030 tdm->tdm_pipe[0].ovs_tdm, 7031 var_size); 7032 scache_offset += var_size; 7033 7034 /* pkt shaper info on pipe0 */ 7035 var_size = ilen * pkt_shp_size; 7036 sal_memcpy(&tdm_scache_ptr[scache_offset], 7037 tdm->tdm_pipe[0].pkt_shaper_tdm, 7038 var_size); 7039 scache_offset += var_size; 7040 7041 /* hpipe id of phy-port */ 7042 for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) { 7043 var_size = ilen; 7044 sal_memcpy(&tdm_scache_ptr[scache_offset], 7045 &tdm->pblk_info[phy_port].pblk_hpipe_num, 7046 var_size); 7047 scache_offset += var_size; 7048 } 7049 7050 /* pblk id of phy-port */ 7051 for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) { 7052 var_size = ilen; 7053 sal_memcpy(&tdm_scache_ptr[scache_offset], 7054 &tdm->pblk_info[phy_port].pblk_cal_idx, 7055 var_size); 7056 scache_offset += var_size; 7057 } 7058 7059 /* port ratio */ 7060 var_size = ilen * HELIX5_PBLKS_PER_DEV; 7061 sal_memcpy(&tdm_scache_ptr[scache_offset], 7062 tdm->port_ratio, 7063 var_size); 7064 scache_offset += var_size; 7065 7066 /* oversub ratio */ 7067 var_size = ilen * hpipes; 7068 sal_memcpy(&tdm_scache_ptr[scache_offset], 7069 tdm->ovs_ratio_x1000, 7070 var_size); 7071 scache_offset += var_size; 7072 7073 LOG_VERBOSE(BSL_LS_SOC_COMMON, 7074 (BSL_META_U(unit, 7075 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 7076 7077 return SOC_E_NONE; 7078 } 7079 7080 /* 7081 * Function: 7082 * soc_hx5_tdm_scache_recovery 7083 * Purpose: 7084 * Recover TDM info that maybe changed during flexport for Level 2 WB 7085 * 7086 * Warm Boot Version Map: 7087 * 7088 * BCM_WB_VERSION_1_0 7089 * IDB TDM info on pipe0 7090 * MMU TDM info on pipe0 7091 * Oversub group info on pipe0 7092 * pkt shaper info on pipe0 7093 * hpipe id of phy-port 7094 * pblk id of phy-port 7095 * port ratio 7096 * oversub ratio 7097 * 7098 * Parameters: 7099 * unit - StrataSwitch unit number. 7100 * Returns: 7101 * SOC_E_XXX 7102 */ 7103 int soc_hx5_tdm_scache_recovery(int unit) 7104 { 7105 uint32 alloc_get = 0; 7106 uint32 alloc_size = 0; 7107 int rv = SOC_E_NONE; 7108 uint8 *tdm_scache_ptr = NULL; 7109 soc_scache_handle_t scache_handle; 7110 uint32 scache_offset=0; 7111 uint32 var_size = 0; 7112 uint16 recovered_ver = 0; 7113 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 7114 _soc_helix5_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info; 7115 7116 ilen = sizeof(int); 7117 ovs_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE * 7118 HELIX5_OVS_GROUP_COUNT_PER_HPIPE * 7119 HELIX5_OVS_GROUP_TDM_LENGTH; 7120 pkt_shp_size = HELIX5_OVS_HPIPE_COUNT_PER_PIPE * 7121 _HX5_PKT_SCH_LENGTH; 7122 hpipes = HELIX5_PIPES_PER_DEV * HELIX5_OVS_HPIPE_COUNT_PER_PIPE; 7123 7124 alloc_size = (ilen * HELIX5_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 7125 (ilen * HELIX5_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 7126 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 7127 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 7128 (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 7129 (ilen * HELIX5_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 7130 (ilen * HELIX5_PBLKS_PER_DEV) + /* port ratio */ 7131 (ilen * hpipes); /* oversub ratio */ 7132 alloc_get = alloc_size; 7133 7134 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 7135 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 7136 FALSE, &alloc_get, 7137 &tdm_scache_ptr, 7138 SOC_TDM_WB_DEFAULT_VERSION, 7139 &recovered_ver); 7140 if (SOC_FAILURE(rv)) { 7141 if ((rv == SOC_E_CONFIG) || 7142 (rv == SOC_E_NOT_FOUND)) { 7143 /* warmboot file does not contain this 7144 * module, or the warmboot state does not exist. 7145 * in this case return SOC_E_NOT_FOUND 7146 */ 7147 return SOC_E_NOT_FOUND; 7148 } else { 7149 /* Only Level2 - flexport treat this as a error */ 7150 LOG_ERROR(BSL_LS_SOC_COMMON, 7151 (BSL_META_U(unit, 7152 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 7153 return rv; 7154 } 7155 } 7156 if (alloc_get != alloc_size) { 7157 /* Expected size doesn't match retrieved size */ 7158 LOG_ERROR(BSL_LS_SOC_COMMON, 7159 (BSL_META_U(unit, 7160 "ERROR: scache recovery for tdm" 7161 "%s()[LINE:%d] DONE \n"), 7162 FUNCTION_NAME(), __LINE__)); 7163 return SOC_E_INTERNAL; 7164 } 7165 7166 if (NULL == tdm_scache_ptr) { 7167 LOG_ERROR(BSL_LS_SOC_COMMON, 7168 (BSL_META_U(unit, 7169 "ERROR: scache recovery for tdm" 7170 "%s()[LINE:%d] DONE \n"), 7171 FUNCTION_NAME(), __LINE__)); 7172 return SOC_E_MEMORY; 7173 } 7174 7175 /* IDB TDM info on pipe0 */ 7176 var_size = ilen * HELIX5_TDM_LENGTH; 7177 sal_memcpy(tdm->tdm_pipe[0].idb_tdm, 7178 &tdm_scache_ptr[scache_offset], 7179 var_size); 7180 scache_offset += var_size; 7181 7182 /* MMU TDM info on pipe0 */ 7183 var_size = ilen * HELIX5_TDM_LENGTH; 7184 sal_memcpy(tdm->tdm_pipe[0].mmu_tdm, 7185 &tdm_scache_ptr[scache_offset], 7186 var_size); 7187 scache_offset += var_size; 7188 7189 /* Oversub group info on pipe0 */ 7190 var_size = ilen * ovs_size; 7191 sal_memcpy(tdm->tdm_pipe[0].ovs_tdm, 7192 &tdm_scache_ptr[scache_offset], 7193 var_size); 7194 scache_offset += var_size; 7195 7196 /* pkt shaper info on pipe0 */ 7197 var_size = ilen * pkt_shp_size; 7198 sal_memcpy(tdm->tdm_pipe[0].pkt_shaper_tdm, 7199 &tdm_scache_ptr[scache_offset], 7200 var_size); 7201 scache_offset += var_size; 7202 7203 /* hpipe id of phy-port */ 7204 for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) { 7205 var_size = ilen; 7206 sal_memcpy(&tdm->pblk_info[phy_port].pblk_hpipe_num, 7207 &tdm_scache_ptr[scache_offset], 7208 var_size); 7209 scache_offset += var_size; 7210 } 7211 7212 /* pblk id of phy-port */ 7213 for (phy_port = 0; phy_port < HELIX5_PHY_PORTS_PER_DEV; phy_port++) { 7214 var_size = ilen; 7215 sal_memcpy(&tdm->pblk_info[phy_port].pblk_cal_idx, 7216 &tdm_scache_ptr[scache_offset], 7217 var_size); 7218 scache_offset += var_size; 7219 } 7220 7221 /* port ratio */ 7222 var_size = ilen * HELIX5_PBLKS_PER_DEV; 7223 sal_memcpy(tdm->port_ratio, 7224 &tdm_scache_ptr[scache_offset], 7225 var_size); 7226 scache_offset += var_size; 7227 7228 /* oversub ratio */ 7229 var_size = ilen * hpipes; 7230 sal_memcpy(tdm->ovs_ratio_x1000, 7231 &tdm_scache_ptr[scache_offset], 7232 var_size); 7233 scache_offset += var_size; 7234 7235 LOG_VERBOSE(BSL_LS_SOC_COMMON, 7236 (BSL_META_U(unit, 7237 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 7238 7239 return SOC_E_NONE; 7240 } 7241 #endif /* BCM_WARM_BOOT_SUPPORT */ 7242 7243 7244 int 7245 soc_helix5_show_voltage(int unit) 7246 { 7247 soc_reg_t reg; 7248 int index; 7249 uint32 rval = 0, fval = 0, avg = 0; 7250 7251 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_3r(unit, &rval)); 7252 if ((soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_RESET_Nf) == 0) || 7253 (soc_reg_field_get(unit, TOP_PVTMON_CTRL_3r, rval, PVTMON_SELECTf) != 4)) { 7254 7255 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 0); 7256 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval)); 7257 soc_reg_field_set(unit, TOP_PVTMON_CTRL_3r, &rval, PVTMON_RESET_Nf, 1); 7258 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_3r(unit, rval)); 7259 7260 rval = 0; 7261 soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT0f, 4); 7262 soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT1f, 4); 7263 soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT2f, 4); 7264 soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT3f, 4); 7265 soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT4f, 4); 7266 soc_reg_field_set(unit, TOP_PVTMON_CTRL_2r, &rval, PVTMON_SELECT5f, 4); 7267 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_2r(unit, rval)); 7268 7269 sal_usleep(1000); 7270 } 7271 7272 avg = 0; 7273 7274 /* Read Voltages. */ 7275 for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) { 7276 reg = pvtmon_result_reg[index]; 7277 7278 /* TOP_PVTMON_RESULT_6r is used for AVS, skip the same from 7279 voltage calculation */ 7280 if (reg == TOP_PVTMON_RESULT_6r) { 7281 continue; 7282 } 7283 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 7284 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 7285 #ifdef BCM_HELIX5_SUPPORT 7286 if (SOC_IS_HELIX5(unit)) { 7287 /* (PVT_DATA * 950) / (1024 * 0.8) */ 7288 fval = (fval * 950 * 10) / (1024 * 8); 7289 } else 7290 #endif /* BCM_HELIX5_SUPPORT */ 7291 { 7292 LOG_CLI((BSL_META_U(unit, 7293 "Voltage monitor fail: Need to add formula for current device.\n"))); 7294 return SOC_E_UNAVAIL; 7295 } 7296 avg += fval; 7297 LOG_CLI((BSL_META_U(unit, 7298 "Voltage monitor %d: voltage = %d.%03dV\n"), 7299 index, (fval/1000), (fval %1000))); 7300 } 7301 7302 /* Get count and reduce 1 since TOP_PVTMON_RESULT_6r is not not applicable */ 7303 avg /= (COUNTOF(pvtmon_result_reg) - 1); 7304 LOG_CLI((BSL_META_U(unit, 7305 "Average voltage is = %d.%03dV\n"), 7306 (avg/1000), (avg %1000))); 7307 7308 return SOC_E_NONE; 7309 } 7310 7311 /* 7312 * Function: 7313 * soc_helix5_icid_get 7314 * Purpose: 7315 * Get ICID 7316 * 7317 * Parameters: 7318 * unit - (IN) StrataSwitch unit number. 7319 * max_size - (IN) Max size of data_buf 7320 * data_buf - (OUT) data buffer to be populated 7321 * actual_size - (OUT) Actual size data in data buffer 7322 * 7323 * Return Value: 7324 * SOC_E_XXX 7325 */ 7326 int 7327 soc_helix5_icid_get(int unit, int max_size, uint8 *buffer, int *actual_size) 7328 { 7329 int w; 7330 7331 if (SOC_BOND_INFO(unit)->ic_id == NULL) { 7332 LOG_ERROR(BSL_LS_BCM_COMMON, 7333 (BSL_META_U(unit, 7334 "unit %d : Cannot read ICID data.\n"), 7335 unit)); 7336 return SOC_E_UNAVAIL; 7337 } 7338 7339 if (buffer == NULL) { 7340 /* return required buffer size of 8 bytes (64 bits) */ 7341 *actual_size = HX5_ICID_LENGTH_BYTES; 7342 return SOC_E_NONE; 7343 } 7344 7345 if (max_size != HX5_ICID_LENGTH_BYTES) { 7346 LOG_VERBOSE(BSL_LS_BCM_COMMON, 7347 (BSL_META_U(unit, 7348 "unit %d : Incorrect buffer size.\n"), 7349 unit)); 7350 return SOC_E_PARAM; 7351 } 7352 7353 for (w = 0; w < (HX5_ICID_LENGTH_BYTES/4); w++) { 7354 _SHR_PACK_U32(buffer, SOC_BOND_INFO(unit)->ic_id[w]); 7355 } 7356 7357 return SOC_E_NONE; 7358 } 7359 7360 /* 7361 * Helix5 chip driver functions. 7362 * Pls keep at the end of this file for easy access. 7363 */ 7364 soc_functions_t soc_helix5_drv_funs = { 7365 _soc_helix5_misc_init, 7366 _soc_helix5_mmu_init, 7367 soc_trident3_age_timer_get, 7368 soc_trident3_age_timer_max_get, 7369 soc_trident3_age_timer_set, 7370 soc_trident3_tscx_firmware_set, 7371 _soc_helix5_tscx_reg_read, 7372 _soc_helix5_tscx_reg_write, 7373 soc_helix5_bond_info_init 7374 }; 7375 #endif /* BCM_HELIX5_SUPPORT */