latency.c (57110B)
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: latency.c 8 * Purpose: Switch Latency Bypass feature support for Tomahawk SKUs 9 * Requires: soc/tomahawk.h 10 */ 11 12 #include <soc/tomahawk.h> 13 14 #if defined(BCM_TOMAHAWK_SUPPORT) 15 #include <sal/types.h> 16 #include <soc/drv.h> 17 #include <soc/ll.h> 18 #include <soc/property.h> 19 #include <shared/bsl.h> 20 #include <appl/diag/system.h> 21 #include <shared/bitop.h> 22 #include <bcm_int/esw/trunk.h> 23 #include <bcm_int/esw/mbcm.h> 24 #ifdef BCM_WARM_BOOT_SUPPORT 25 #include <soc/scache.h> 26 #endif 27 28 29 #define SBUS_ADDR_BEAT_STAGEID 26 30 31 #define _SOC_TH_LATENCY_INIT_VALIDATE(unit, ret) \ 32 if (!_soc_th_latency_ctrl[unit] || !_soc_th_latency_ctrl[unit]->init) \ 33 return (ret); 34 35 #define _SOC_TH_LATENCY_CFG_VALIDATE(cfg, ret) \ 36 if (!(((cfg) >= SOC_SWITCH_BYPASS_MODE_NONE) && \ 37 ((cfg) <= SOC_SWITCH_BYPASS_MODE_EFP))) \ 38 return (ret); 39 40 #define _SOC_SWITCH_BYPASS_MODE_INVALID 0xAB 41 42 /* runtime enable/disable knob */ 43 /* temporary, will last only until system testing */ 44 #define _SOC_TH_LATENCY_RT_ENABLE_CHK(unit) \ 45 if (!soc_property_get(unit, "switch_bypass_enable", 1)) \ 46 return SOC_E_NONE; 47 48 49 extern soc_th_latency_table_cfg_t 50 soc_th_tbl_cfg[SOC_MAX_NUM_DEVICES]; 51 52 53 typedef enum { 54 _SOC_TH_IPIPE_STAGE_IDB = 0, 55 _SOC_TH_IPIPE_STAGE_IDB_IS = 1, 56 _SOC_TH_IPIPE_STAGE_IDB_OBM0 = 2, 57 _SOC_TH_IPIPE_STAGE_IDB_OBM1 = 3, 58 _SOC_TH_IPIPE_STAGE_IDB_OBM2 = 4, 59 _SOC_TH_IPIPE_STAGE_IDB_OBM3 = 5, 60 _SOC_TH_IPIPE_STAGE_IDB_OBM4 = 6, 61 _SOC_TH_IPIPE_STAGE_IDB_OBM5 = 7, 62 _SOC_TH_IPIPE_STAGE_IDB_OBM6 = 8, 63 _SOC_TH_IPIPE_STAGE_IDB_OBM7 = 9, 64 _SOC_TH_IPIPE_STAGE_ICFG = 10, 65 _SOC_TH_IPIPE_STAGE_IPARS = 11, 66 _SOC_TH_IPIPE_STAGE_IVXLT = 12, 67 _SOC_TH_IPIPE_STAGE_IVP = 13, 68 _SOC_TH_IPIPE_STAGE_IFWD = 14, 69 _SOC_TH_IPIPE_STAGE_ISS = 15, 70 _SOC_TH_IPIPE_STAGE_IRSEL1 = 16, 71 _SOC_TH_IPIPE_STAGE_ISW1 = 17, 72 _SOC_TH_IPIPE_STAGE_IFP = 18, 73 _SOC_TH_IPIPE_STAGE_IRSEL2 = 19, 74 _SOC_TH_IPIPE_STAGE_ISW2 = 20, 75 _SOC_TH_IPIPE_STAGE_ISW3 = 21, 76 _SOC_TH_IPIPE_STAGE_ISBS = 22, 77 _SOC_TH_IPIPE_STAGE_CEV = 23, 78 _SOC_TH_IPIPE_STAGE_L2_MGMT = 24, 79 _SOC_TH_IPIPE_STAGE_FLEX_CTR = 26 80 } _soc_th_ipipe_stage_e; 81 82 typedef enum { 83 _SOC_TH_EPIPE_STAGE_EARB = 0, 84 _SOC_TH_EPIPE_STAGE_EL3 = 1, 85 _SOC_TH_EPIPE_STAGE_EVLAN = 2, 86 _SOC_TH_EPIPE_STAGE_ESW = 3, 87 _SOC_TH_EPIPE_STAGE_EIPT = 4, 88 _SOC_TH_EPIPE_STAGE_EHCPM = 5, 89 _SOC_TH_EPIPE_STAGE_EPMOD = 6, 90 _SOC_TH_EPIPE_STAGE_EFPPARS = 7, 91 _SOC_TH_EPIPE_STAGE_EFP = 8, 92 _SOC_TH_EPIPE_STAGE_EFPMOD = 9, 93 _SOC_TH_EPIPE_STAGE_EDATABUF = 10, 94 _SOC_TH_EPIPE_STAGE_ESBS = 11 95 } _soc_th_epipe_stage_e; 96 97 typedef enum { 98 _SOC_TH2_IPIPE_STAGE_IDB = 0, 99 _SOC_TH2_IPIPE_STAGE_IDB_IS = 1, 100 _SOC_TH2_IPIPE_STAGE_IDB_OBM0 = 2, 101 _SOC_TH2_IPIPE_STAGE_IDB_OBM1 = 3, 102 _SOC_TH2_IPIPE_STAGE_IDB_OBM2 = 4, 103 _SOC_TH2_IPIPE_STAGE_IDB_OBM3 = 5, 104 _SOC_TH2_IPIPE_STAGE_IDB_OBM4 = 6, 105 _SOC_TH2_IPIPE_STAGE_IDB_OBM5 = 7, 106 _SOC_TH2_IPIPE_STAGE_IDB_OBM6 = 8, 107 _SOC_TH2_IPIPE_STAGE_IDB_OBM7 = 9, 108 _SOC_TH2_IPIPE_STAGE_IDB_OBM8 = 10, 109 _SOC_TH2_IPIPE_STAGE_IDB_OBM9 = 11, 110 _SOC_TH2_IPIPE_STAGE_IDB_OBM10 = 12, 111 _SOC_TH2_IPIPE_STAGE_IDB_OBM11 = 13, 112 _SOC_TH2_IPIPE_STAGE_IDB_OBM12 = 14, 113 _SOC_TH2_IPIPE_STAGE_IDB_OBM13 = 15, 114 _SOC_TH2_IPIPE_STAGE_IDB_OBM14 = 16, 115 _SOC_TH2_IPIPE_STAGE_IDB_OBM15 = 17, 116 _SOC_TH2_IPIPE_STAGE_ISBS_IDB = 18, 117 _SOC_TH2_IPIPE_STAGE_ICFG = 19, 118 _SOC_TH2_IPIPE_STAGE_IPARS = 20, 119 _SOC_TH2_IPIPE_STAGE_IVXLT = 21, 120 _SOC_TH2_IPIPE_STAGE_IVP = 22, 121 _SOC_TH2_IPIPE_STAGE_IFWD = 23, 122 _SOC_TH2_IPIPE_STAGE_IFWD_2 = 24, 123 _SOC_TH2_IPIPE_STAGE_IFWD_3 = 25, 124 _SOC_TH2_IPIPE_STAGE_IFWD_4 = 26, 125 _SOC_TH2_IPIPE_STAGE_IFWD_5 = 27, 126 _SOC_TH2_IPIPE_STAGE_IFWD_6 = 28, 127 _SOC_TH2_IPIPE_STAGE_IFWD_7 = 29, 128 _SOC_TH2_IPIPE_STAGE_IFWD_8 = 30, 129 _SOC_TH2_IPIPE_STAGE_ISS = 31, 130 _SOC_TH2_IPIPE_STAGE_IRSEL1 = 32, 131 _SOC_TH2_IPIPE_STAGE_ISW1 = 33, 132 _SOC_TH2_IPIPE_STAGE_IFP = 34, 133 _SOC_TH2_IPIPE_STAGE_IRSEL2 = 35, 134 _SOC_TH2_IPIPE_STAGE_ISW2 = 36, 135 _SOC_TH2_IPIPE_STAGE_ISW3 = 37, 136 _SOC_TH2_IPIPE_STAGE_ISBS = 38, 137 _SOC_TH2_IPIPE_STAGE_CEV = 39, 138 _SOC_TH2_IPIPE_STAGE_L2_MGMT = 40, 139 _SOC_TH2_IPIPE_STAGE_L2_MGMT_2 = 41, 140 _SOC_TH2_IPIPE_STAGE_ISW4 = 42, 141 _SOC_TH2_IPIPE_STAGE_ISBS_ISW4 = 43, 142 _SOC_TH2_IPIPE_STAGE_FLEX_CTR = 44 143 } _soc_th2_ipipe_stage_e; 144 145 typedef enum { 146 _SOC_TH2_EPIPE_STAGE_EARB = 0, 147 _SOC_TH2_EPIPE_STAGE_EL3 = 1, 148 _SOC_TH2_EPIPE_STAGE_EVLAN = 2, 149 _SOC_TH2_EPIPE_STAGE_ESW = 3, 150 _SOC_TH2_EPIPE_STAGE_EIPT = 4, 151 _SOC_TH2_EPIPE_STAGE_EHCPM = 5, 152 _SOC_TH2_EPIPE_STAGE_EPMOD = 6, 153 _SOC_TH2_EPIPE_STAGE_EFPPARS = 7, 154 _SOC_TH2_EPIPE_STAGE_EFP = 8, 155 _SOC_TH2_EPIPE_STAGE_EFPMOD = 9, 156 _SOC_TH2_EPIPE_STAGE_EDATABUF = 10, 157 _SOC_TH2_EPIPE_STAGE_ESBS = 11 158 } _soc_th2_epipe_stage_e; 159 160 /* Ingress Latency Config */ 161 typedef struct _soc_th_igr_latency_cfg_s { 162 uint32 ipars : 1; /* IPARS Latency Mode */ 163 uint32 ivxlt : 1; /* IVXLT Bypass */ 164 uint32 ivp : 1; /* IVP Bypass */ 165 uint32 ifwd : 1; /* IFWD Latency Mode */ 166 uint32 irsel1 : 1; /* IRSEL1 Latency Mode */ 167 uint32 ifp : 1; /* IFP Bypass */ 168 uint32 irsel2 : 2; /* IRSEL2 Latency Mode */ 169 uint32 isw2 : 1; /* ISW2 Latency Mode */ 170 uint32 ecmp : 2; /* ECMP Mode */ 171 uint32 reserved : 21; /* reserved */ 172 /* NOTE: DON'T ALTER FIELD ORDER */ 173 } _soc_th_igr_latency_cfg_t; 174 175 /* Egress Latency Config */ 176 typedef struct _soc_th_egr_latency_cfg_s { 177 uint32 el3 : 1; /* EL3 Latency Mode */ 178 uint32 evlan : 1; /* EVLAN Latency Mode */ 179 uint32 efp : 1; /* EFP Bypass */ 180 uint32 otag_action : 3; /* Single Outer Tag - action */ 181 uint32 potag_action : 3; /* Pri Outer Tag - action */ 182 uint32 ut_otag_action : 3; /* Untagged - action */ 183 uint32 outer_pri : 1; /* Outer PRI action */ 184 uint32 outer_cfi : 1; /* Outer CFI action */ 185 uint32 outer_tpid : 16; /* Outer Tag - TPID */ 186 uint32 reserved1 : 2; /* reserved */ 187 uint32 profile_ptr : 4; /* map PRI-CFI */ 188 uint32 pri : 3; /* PRI for Outer tag */ 189 uint32 cfi : 1; /* CFI for Outer tag */ 190 uint32 reserved2 : 24; /* reserved */ 191 /* NOTE: DON'T ALTER FIELD ORDER */ 192 } _soc_th_egr_latency_cfg_t; 193 194 /* Latency core config */ 195 typedef struct _soc_th_latency_core_cfg_s { 196 _soc_th_igr_latency_cfg_t igr; 197 _soc_th_egr_latency_cfg_t egr; 198 /* NOTE: DON'T ALTER FIELD ORDER */ 199 } _soc_th_latency_core_cfg_t; 200 201 /* Latency ctrl */ 202 typedef struct _soc_th_latency_ctrl_s { 203 uint8 init; 204 int latency; 205 soc_th_latency_table_cfg_t tbl_cfg; 206 } _soc_th_latency_ctrl_t; 207 208 #ifdef BCM_WARM_BOOT_SUPPORT 209 /* Latency Warmboot */ 210 typedef struct _soc_th_latency_wb_s { 211 int unit; 212 _soc_th_latency_ctrl_t latency_ctrl; 213 } _soc_th_latency_wb_t; 214 #endif 215 216 217 /* Latency Bypass - Core Config Table */ 218 static const _soc_th_latency_core_cfg_t 219 _soc_th_latency_cfg_tbl[] = { 220 { {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} }, /* Full Features */ 221 { {0, 1, 0, 1, 0, 0, 1, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} }, /* Balanced L2 + L3 */ 222 { {1, 1, 1, 1, 1, 1, 2, 1, 2, 0}, {1, 1, 1, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} }, /* Low Latency L2 */ 223 { {0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0x8100, 0, 0, 0, 0, 0} } /* EFP Latency*/ 224 }; 225 226 /* Latency Control */ 227 static _soc_th_latency_ctrl_t* 228 _soc_th_latency_ctrl[SOC_MAX_NUM_DEVICES] = {NULL}; 229 230 /* latency subsystem billboard */ 231 static const char * 232 lstr[] = {"normal", "balanced (L2/L3)", "low (L2)", "EFP"}; 233 234 235 /****************************************************************************** 236 * Name: _soc_th_igr_latency_config * 237 * Description: * 238 * Configure ingress latency settings on the switch * 239 * IN params: * 240 * - Unit * 241 * - Latency Mode * 242 * Returns: * 243 * - SOC_E_NONE on success * 244 * - SOC_E_* on internal errors * 245 */ 246 STATIC int 247 _soc_th_igr_latency_config( 248 int unit, 249 int latency) 250 { 251 uint32 rval = 0; 252 253 _SOC_TH_UNIT_VALIDATE(unit); 254 _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_PARAM); 255 256 /* ingress latency config */ 257 if (!SOC_IS_TOMAHAWK3(unit)) { 258 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IPARS_LATENCY_MODEf, 259 _soc_th_latency_cfg_tbl[latency].igr.ipars); 260 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IVXLT_BYPASSf, 261 _soc_th_latency_cfg_tbl[latency].igr.ivxlt); 262 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IVP_BYPASSf, 263 _soc_th_latency_cfg_tbl[latency].igr.ivp); 264 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IFWD_LATENCY_MODEf, 265 _soc_th_latency_cfg_tbl[latency].igr.ifwd); 266 267 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IRSEL1_LATENCY_MODEf, 268 _soc_th_latency_cfg_tbl[latency].igr.irsel1); 269 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IFP_BYPASSf, 270 _soc_th_latency_cfg_tbl[latency].igr.ifp); 271 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, IRSEL2_LATENCY_MODEf, 272 _soc_th_latency_cfg_tbl[latency].igr.irsel2); 273 soc_reg_field_set(unit, ING_LATENCY_CONTROLr, &rval, ISW2_LATENCY_MODEf, 274 _soc_th_latency_cfg_tbl[latency].igr.isw2); 275 SOC_IF_ERROR_RETURN(WRITE_ING_LATENCY_CONTROLr(unit, rval)); 276 277 /* ECMP latency config */ 278 SOC_IF_ERROR_RETURN(READ_ECMP_CONFIGr(unit, &rval)); 279 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, 280 _soc_th_latency_cfg_tbl[latency].igr.ecmp); 281 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 282 } 283 284 return SOC_E_NONE; 285 } 286 287 /****************************************************************************** 288 * Name: _soc_th_efp_latency_config * 289 * Description: * 290 * Configure EFP latency settings on the switch * 291 * IN params: * 292 * - Unit * 293 * - Latency Mode * 294 * Returns: * 295 * - SOC_E_NONE on success * 296 * - SOC_E_* on internal errors * 297 */ 298 STATIC int 299 _soc_th_efp_latency_config( 300 int unit, 301 int latency) 302 { 303 uint32 val = 0; 304 305 _SOC_TH_UNIT_VALIDATE(unit); 306 _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_PARAM); 307 308 soc_reg_field_set(unit, EGR_LATENCY_MODEr, &val, EFP_BYPASSf, 309 _soc_th_latency_cfg_tbl[latency].egr.efp); 310 311 SOC_IF_ERROR_RETURN(WRITE_EGR_LATENCY_MODEr(unit, val)); 312 313 return SOC_E_NONE; 314 315 } 316 /****************************************************************************** 317 * Name: _soc_th_egr_latency_config * 318 * Description: * 319 * Configure egress latency settings on the switch * 320 * IN params: * 321 * - Unit * 322 * - Latency Mode * 323 * Returns: * 324 * - SOC_E_NONE on success * 325 * - SOC_E_* on internal errors * 326 */ 327 STATIC int 328 _soc_th_egr_latency_config( 329 int unit, 330 int latency) 331 { 332 uint32 rval = 0; 333 soc_port_t port; 334 335 _SOC_TH_UNIT_VALIDATE(unit); 336 _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_PARAM); 337 338 if (!SOC_IS_TOMAHAWK3(unit)) { 339 soc_reg_field_set(unit, EGR_LATENCY_MODEr, &rval, EL3_LATENCY_MODEf, 340 _soc_th_latency_cfg_tbl[latency].egr.el3); 341 soc_reg_field_set(unit, EGR_LATENCY_MODEr, &rval, EVLAN_LATENCY_MODEf, 342 _soc_th_latency_cfg_tbl[latency].egr.evlan); 343 } 344 soc_reg_field_set(unit, EGR_LATENCY_MODEr, &rval, EFP_BYPASSf, 345 _soc_th_latency_cfg_tbl[latency].egr.efp); 346 347 SOC_IF_ERROR_RETURN(WRITE_EGR_LATENCY_MODEr(unit, rval)); 348 349 if (SOC_SWITCH_BYPASS_MODE_NONE != latency) { 350 rval = 0; 351 352 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 353 &rval, SOT_OTAG_ACTIONf, 354 _soc_th_latency_cfg_tbl[latency].egr.otag_action); 355 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 356 &rval, SOT_POTAG_ACTIONf, 357 _soc_th_latency_cfg_tbl[latency].egr.potag_action); 358 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 359 &rval, UT_OTAG_ACTIONf, 360 _soc_th_latency_cfg_tbl[latency].egr.ut_otag_action); 361 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 362 &rval, CHANGE_OUTER_PRIf, 363 _soc_th_latency_cfg_tbl[latency].egr.outer_pri); 364 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 365 &rval, CHANGE_OUTER_CFIf, 366 _soc_th_latency_cfg_tbl[latency].egr.outer_cfi); 367 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 368 &rval, OUTER_TPIDf, 369 _soc_th_latency_cfg_tbl[latency].egr.outer_tpid); 370 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, 371 &rval, OUTER_PRI_CFI_MAPPING_PTRf, 372 _soc_th_latency_cfg_tbl[latency].egr.profile_ptr); 373 374 /* EGR VLAN config */ 375 PBMP_PORT_ITER(unit, port) { 376 SOC_IF_ERROR_RETURN( 377 WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, port, rval)); 378 } 379 } 380 381 return SOC_E_NONE; 382 } 383 384 /****************************************************************************** 385 * Name: _soc_th_latency_resource_avail * 386 * Description: * 387 * Returns if the specified resource is supported/available for the * 388 * current Latency mode configured on the switch * 389 * IN params: * 390 * - Unit * 391 * - Resource Type (Register, Memory, Feature) * 392 * - Resource Name (Enumeration) * 393 * - latency mode * 394 * Returns: * 395 * - TRUE, if the resource is available * 396 * - FALSE, if the resource is unavailable * 397 */ 398 STATIC int 399 _soc_th_latency_resource_avail( 400 int unit, 401 soc_th_resource_e type, 402 int resource, 403 int latency) 404 { 405 uint32 block, pipe_stage; 406 uint8 mode; 407 uint32 access_latency_mode; 408 409 _SOC_TH_UNIT_VALIDATE(unit); 410 _SOC_TH_LATENCY_RT_ENABLE_CHK(unit); 411 412 _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_NONE); 413 414 if (_SOC_TH_MEM == type) { 415 if ((SOC_SWITCH_BYPASS_MODE_NONE == latency) && 416 SOC_MEM_IS_VALID(unit, resource)) { 417 return TRUE; 418 } 419 420 if (!SOC_MEM_IS_VALID(unit, resource)) { 421 return FALSE; 422 } 423 block = SOC_BLOCK_TYPE(unit, SOC_MEM_BLOCK_ANY(unit, resource)); 424 pipe_stage = 425 (SOC_MEM_INFO(unit, resource).base >> SBUS_ADDR_BEAT_STAGEID); 426 access_latency_mode = SOC_MEM_INFO(unit, resource).access_latency_mode; 427 } else if (_SOC_TH_REG == type) { 428 if ((SOC_SWITCH_BYPASS_MODE_NONE == latency) && 429 SOC_REG_IS_VALID(unit, resource)) { 430 return TRUE; 431 } 432 433 if (!SOC_REG_IS_VALID(unit, resource)) { 434 return FALSE; 435 } 436 block = SOC_REG_INFO(unit, resource).block[0]; 437 pipe_stage = 438 (SOC_REG_INFO(unit, resource).offset >> SBUS_ADDR_BEAT_STAGEID); 439 access_latency_mode = SOC_REG_INFO(unit, resource).access_latency_mode; 440 } else { 441 return TRUE; 442 } 443 444 #ifdef BCM_TOMAHAWK2_SUPPORT 445 if (SOC_IS_TOMAHAWK2(unit)) { 446 switch(block) { 447 case SOC_BLK_IPIPE: 448 switch(pipe_stage) { 449 case _SOC_TH2_IPIPE_STAGE_IPARS: 450 mode = _soc_th_latency_cfg_tbl[latency].igr.ipars; 451 break; 452 case _SOC_TH2_IPIPE_STAGE_IVXLT: 453 mode = _soc_th_latency_cfg_tbl[latency].igr.ivxlt; 454 break; 455 case _SOC_TH2_IPIPE_STAGE_IVP: 456 mode = _soc_th_latency_cfg_tbl[latency].igr.ivp; 457 break; 458 case _SOC_TH2_IPIPE_STAGE_IFWD: 459 mode = _soc_th_latency_cfg_tbl[latency].igr.ifwd; 460 break; 461 case _SOC_TH2_IPIPE_STAGE_IRSEL1: 462 mode = _soc_th_latency_cfg_tbl[latency].igr.irsel1; 463 break; 464 case _SOC_TH2_IPIPE_STAGE_IFP: 465 mode = _soc_th_latency_cfg_tbl[latency].igr.ifp; 466 break; 467 case _SOC_TH2_IPIPE_STAGE_IRSEL2: 468 mode = _soc_th_latency_cfg_tbl[latency].igr.irsel2; 469 break; 470 case _SOC_TH2_IPIPE_STAGE_ISW2: 471 mode = _soc_th_latency_cfg_tbl[latency].igr.isw2; 472 break; 473 default: 474 return TRUE; 475 } 476 break; 477 478 case SOC_BLK_EPIPE: 479 switch(pipe_stage) { 480 case _SOC_TH2_EPIPE_STAGE_EL3: 481 mode = _soc_th_latency_cfg_tbl[latency].egr.el3; 482 break; 483 case _SOC_TH2_EPIPE_STAGE_EVLAN: 484 mode = _soc_th_latency_cfg_tbl[latency].egr.evlan; 485 break; 486 case _SOC_TH2_EPIPE_STAGE_EFP: 487 mode = _soc_th_latency_cfg_tbl[latency].egr.efp; 488 break; 489 default: 490 return TRUE; 491 } 492 break; 493 494 default: 495 return TRUE; 496 } 497 } else 498 #endif 499 { 500 switch(block) { 501 case SOC_BLK_IPIPE: 502 switch(pipe_stage) { 503 case _SOC_TH_IPIPE_STAGE_IPARS: 504 mode = _soc_th_latency_cfg_tbl[latency].igr.ipars; 505 break; 506 case _SOC_TH_IPIPE_STAGE_IVXLT: 507 mode = _soc_th_latency_cfg_tbl[latency].igr.ivxlt; 508 break; 509 case _SOC_TH_IPIPE_STAGE_IVP: 510 mode = _soc_th_latency_cfg_tbl[latency].igr.ivp; 511 break; 512 case _SOC_TH_IPIPE_STAGE_IFWD: 513 mode = _soc_th_latency_cfg_tbl[latency].igr.ifwd; 514 break; 515 case _SOC_TH_IPIPE_STAGE_IRSEL1: 516 mode = _soc_th_latency_cfg_tbl[latency].igr.irsel1; 517 break; 518 case _SOC_TH_IPIPE_STAGE_IFP: 519 mode = _soc_th_latency_cfg_tbl[latency].igr.ifp; 520 break; 521 case _SOC_TH_IPIPE_STAGE_IRSEL2: 522 mode = _soc_th_latency_cfg_tbl[latency].igr.irsel2; 523 break; 524 case _SOC_TH_IPIPE_STAGE_ISW2: 525 mode = _soc_th_latency_cfg_tbl[latency].igr.isw2; 526 break; 527 default: 528 return TRUE; 529 } 530 break; 531 532 case SOC_BLK_EPIPE: 533 switch(pipe_stage) { 534 case _SOC_TH_EPIPE_STAGE_EL3: 535 mode = _soc_th_latency_cfg_tbl[latency].egr.el3; 536 break; 537 case _SOC_TH_EPIPE_STAGE_EVLAN: 538 mode = _soc_th_latency_cfg_tbl[latency].egr.evlan; 539 break; 540 case _SOC_TH_EPIPE_STAGE_EFP: 541 mode = _soc_th_latency_cfg_tbl[latency].egr.efp; 542 break; 543 default: 544 return TRUE; 545 } 546 break; 547 548 default: 549 return TRUE; 550 } 551 } 552 553 return (mode <= access_latency_mode); 554 } 555 556 /****************************************************************************** 557 * Name: _soc_th_latency_mem_filter * 558 * Description: * 559 * Filters out memories/tables unsupported for the current Latency mode * 560 * IN params: * 561 * - Unit * 562 * Returns: * 563 * - SOC_E_NONE on success * 564 */ 565 STATIC int 566 _soc_th_latency_mem_filter(int unit) 567 { 568 soc_mem_t mem; 569 soc_persist_t *sop; 570 SHR_BITDCL *flags; 571 int latency; 572 573 sop = SOC_PERSIST(unit); 574 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 575 for (mem = 0; mem < NUM_SOC_MEM; mem++) { 576 if (!SOC_MEM_IS_VALID(unit, mem)) { 577 continue; 578 } 579 580 if (!soc_th_latency_mem_avail(unit, mem, latency)) { 581 sop->memState[mem].index_max = -1; 582 flags = (SHR_BITDCL *) &SOC_MEM_INFO(unit, mem).flags; 583 SHR_BITCLR(flags, (SOC_MEM_FLAG_VALID - 1)); 584 } 585 } 586 587 return SOC_E_NONE; 588 } 589 590 /****************************************************************************** 591 * Name: _soc_th_latency_reg_filter * 592 * Description: * 593 * Filters out registers unsupported for the current Latency mode * 594 * IN params: * 595 * - Unit * 596 * Returns: * 597 * - SOC_E_NONE on success * 598 */ 599 STATIC int 600 _soc_th_latency_reg_filter(int unit) 601 { 602 soc_reg_t reg; 603 int latency; 604 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 605 606 for (reg = 0; reg < NUM_SOC_REG; reg++) { 607 if (!SOC_REG_IS_VALID(unit, reg)) { 608 continue; 609 } 610 611 if (!soc_th_latency_reg_avail(unit, reg, latency)) { 612 SOC_REG_INFO(unit, reg).regtype = soc_invalidreg; 613 } 614 } 615 616 if (SOC_SWITCH_BYPASS_MODE(unit) && SOC_REG_IS_VALID(unit, SHARED_TABLE_HASH_CONTROLr)) { 617 /* 618 * SW WAR to explicitly invalidate SHARED_TABLE_HASH_CONTROL register as this 619 * register is not accessible in low latency modes 620 */ 621 SOC_REG_INFO(unit, SHARED_TABLE_HASH_CONTROLr).regtype = soc_invalidreg; 622 } 623 624 return SOC_E_NONE; 625 } 626 static int mode[SOC_MAX_NUM_DEVICES]; 627 static int is_mode_get[SOC_MAX_NUM_DEVICES] = {0}; 628 629 /****************************************************************************** 630 * Name: soc_th_latency_get * 631 * Description: * 632 * Get the Latency Bypass mode configured on the Switch. * 633 * TH ASF is an internal client for this API. * 634 * IN params: * 635 * - Unit * 636 * OUT params: * 637 * - Latency Mode * 638 * Returns: * 639 * - SOC_E_NONE on success * 640 * - SOC_E_PARAM on invalid parameter * 641 */ 642 int 643 soc_th_latency_get( 644 int unit, 645 OUT int* const latency) 646 { 647 uint16 dev_id = 0; 648 int is_td3 = 0; 649 650 _SOC_TH_UNIT_VALIDATE(unit); 651 if (!latency) { 652 return SOC_E_PARAM; 653 } 654 655 soc_cm_get_id(unit, &dev_id, NULL); 656 if (dev_id >= BCM56870_DEVICE_ID && 657 dev_id <= BCM56870_DEVICE_ID + 10) { 658 is_td3 = 1; 659 } 660 661 if (_soc_th_latency_ctrl[unit] && _soc_th_latency_ctrl[unit]->init) { 662 *latency = _soc_th_latency_ctrl[unit]->latency; 663 } else if (!is_mode_get[unit]) { 664 /* reqd. for feature & mem checks that happen prior to "init soc" */ 665 *latency = soc_property_get(unit, spn_SWITCH_BYPASS_MODE, 666 SOC_SWITCH_BYPASS_MODE_NONE); 667 668 if (is_td3 || !((*latency >= SOC_SWITCH_BYPASS_MODE_NONE) && 669 (*latency <= SOC_SWITCH_BYPASS_MODE_EFP))) { 670 *latency = SOC_SWITCH_BYPASS_MODE_NONE; 671 } 672 673 mode[unit] = *latency; 674 is_mode_get[unit] = 1; 675 } else { 676 *latency = mode[unit]; 677 } 678 679 return SOC_E_NONE; 680 } 681 682 /****************************************************************************** 683 * Name: soc_th_latency_bypassed * 684 * Description: * 685 * Returns if the specified feature is supported/available for the * 686 * current Latency mode configured on the switch * 687 * IN params: * 688 * - Unit * 689 * - Feature (soc_feature_*) * 690 * Returns: * 691 * - FALSE, if the feature is supported * 692 * - TRUE, if the feature is unsupported * 693 */ 694 int 695 soc_th_latency_bypassed( 696 int unit, 697 soc_feature_t feature) 698 { 699 int latency; 700 701 _SOC_TH_UNIT_VALIDATE(unit); 702 _SOC_TH_LATENCY_RT_ENABLE_CHK(unit); 703 704 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 705 706 switch(feature) { 707 /* 708 * features supported only in NORMAL latency mode and NOT supported in either 709 * LOW (L2) or BALANCED (L2/L3) Latency modes 710 */ 711 case soc_feature_alpm: 712 case soc_feature_ptp: 713 case soc_feature_visibility: 714 case soc_feature_robust_hash: 715 case soc_feature_tunnel_6to4_secure: 716 case soc_feature_tunnel_any_in_6: 717 case soc_feature_tunnel_gre: 718 case soc_feature_tunnel_protocol_match: 719 case soc_feature_l2gre: 720 case soc_feature_l2gre_default_tunnel: 721 case soc_feature_l2_tunnel_transit_payload_tpid_parser: 722 case soc_feature_mac_based_vlan: 723 case soc_feature_ip_subnet_based_vlan: 724 case soc_feature_vfi_zero_invalid: 725 case soc_feature_hierarchical_ecmp: 726 case soc_feature_l3_ecmp_2k_groups: 727 case soc_feature_mpls_lsr_ecmp: 728 case soc_feature_sflow_counters: 729 case soc_feature_sflow_flex: 730 case soc_feature_sflow_ing_mem: 731 case soc_feature_sflow_ing_mirror: 732 case soc_feature_fp_nw_tcam_prio_order_war: 733 case soc_feature_higig2: 734 case soc_feature_hg_no_speed_change: 735 case soc_feature_xport_convertible: 736 /* Please check _bcm_esw_get_fp_mode_global before 737 * changing soc_feature_field_multi_stage. 738 */ 739 case soc_feature_field_multi_stage: 740 return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \ 741 (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1; 742 743 case soc_feature_alpm_flex_stat: 744 case soc_feature_alpm_flex_stat_v6_64: 745 if (soc_property_get(unit, spn_ALPM_FLEX_STAT_SUPPORT, 0)) { 746 return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \ 747 (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1; 748 } else { 749 return TRUE; 750 } 751 752 case soc_feature_field_compression: 753 if ((soc_property_get(unit, "fp_compression_enable", 1)) != 0) { 754 return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \ 755 (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1; 756 } else { 757 return TRUE; 758 } 759 760 case soc_feature_field_exact_match_support: 761 case soc_feature_uc_flowtracker_learn: 762 case soc_feature_uc_flowtracker_export: 763 if ((soc_property_get(unit, "fpem_mem_entries", 0)) != 0) { 764 return (SOC_SWITCH_BYPASS_MODE_NONE == latency) ? 0 : \ 765 (SOC_SWITCH_BYPASS_MODE_EFP == latency) ? 0 : 1; 766 } else { 767 return TRUE; 768 } 769 770 /* 771 * features supported in NORMAL and BALANCED Latency modes but 772 * NOT in LOW (L2) Latency 773 */ 774 case soc_feature_agm: 775 case soc_feature_vlan_pri_cfi_action: 776 case soc_feature_color_prio_map: 777 case soc_feature_bfd: 778 case soc_feature_big_icmpv6_ping_check: 779 case soc_feature_class_based_learning: 780 case soc_feature_ecmp_random: 781 case soc_feature_exact_width_match_mode: 782 case soc_feature_ecmp_resilient_hash_optimized: 783 case soc_feature_ecmp_round_robin: 784 case soc_feature_egr_vlan_check: 785 case soc_feature_field_ingress_cosq_override: 786 case soc_feature_igmp_mld_support: 787 case soc_feature_ip_mcast: 788 case soc_feature_ip_mcast_repl: 789 case soc_feature_ipmc_remap: 790 case soc_feature_ipmc_repl_penultimate: 791 case soc_feature_ipmc_use_configured_dest_mac: 792 case soc_feature_l3: 793 case soc_feature_l3_defip_map: 794 case soc_feature_l3_shared_defip_table: 795 case soc_feature_l3_dynamic_ecmp_group: 796 case soc_feature_l3_ecmp_1k_groups: 797 case soc_feature_l3_extended_host_entry: 798 case soc_feature_l3_host_ecmp_group: 799 case soc_feature_l3_iif_profile: 800 case soc_feature_l3_iif_zero_invalid: 801 case soc_feature_l3_ingress_interface: 802 case soc_feature_l3_ip4_options_profile: 803 case soc_feature_l3_ip6: 804 case soc_feature_l3_lookup_cmd: 805 case soc_feature_l3_sgv: 806 case soc_feature_l3mtu_fail_tocpu: 807 case soc_feature_l3x_parity: 808 case soc_feature_lpm_tcam: 809 case soc_feature_lpm_prefix_length_max_128: 810 case soc_feature_nat: 811 case soc_feature_pim_bidir: 812 case soc_feature_randomized_load_balance: 813 case soc_feature_repl_l3_intf_use_next_hop: 814 case soc_feature_round_robin_load_balance: 815 case soc_feature_split_repl_group_table: 816 case soc_feature_storm_control: 817 case soc_feature_udf_hashing: 818 case soc_feature_udf_multi_pipe_support: 819 case soc_feature_udf_support: 820 case soc_feature_shared_trunk_member_table: 821 case soc_feature_field: 822 case soc_feature_field_wide: 823 case soc_feature_field_intraslice_double_wide: 824 case soc_feature_field_preselector_support: 825 case soc_feature_field_ingress_triple_wide: 826 case soc_feature_field_multi_pipe_support: 827 case soc_feature_memscan_ifp_slice_adjust: 828 case soc_feature_field_action_l2_change: 829 case soc_feature_field_action_redirect_ipmc: 830 case soc_feature_field_virtual_slice_group: 831 case soc_feature_overlaid_address_class: 832 case soc_feature_field_action_redirect_ecmp: 833 case soc_feature_src_port_consistency_check_skip: 834 case soc_feature_vlan_protocol_pkt_ctrl: 835 case soc_feature_th_nh_no_overlap_ecmp: 836 case soc_feature_vlan_egress_membership_l3_only: 837 return (SOC_SWITCH_BYPASS_MODE_LOW == latency); 838 839 /* 840 * features supported ONLY in LOW (L2) and BALANCED (L2/L3) Latency 841 * mode but NOT in NORMAL Latency 842 */ 843 case soc_feature_no_tunnel: 844 case soc_feature_fast_init: 845 return (SOC_SWITCH_BYPASS_MODE_NONE == latency) || (SOC_SWITCH_BYPASS_MODE_EFP == latency); 846 847 /* 848 * features supported ONLY in LOW (L2) Latency 849 */ 850 case soc_feature_fastlag: 851 case soc_feature_fast_egr_vlan_action: 852 return (SOC_SWITCH_BYPASS_MODE_LOW != latency); 853 854 /* 855 * features supported only in BALANCED (L2/L3) Latency 856 */ 857 case soc_feature_egr_vlan_action: 858 case soc_feature_fast_ecmp: 859 return (SOC_SWITCH_BYPASS_MODE_BALANCED != latency); 860 861 /* 862 * legacy features supported in ALL THREE Latency modes 863 */ 864 case soc_feature_advanced_flex_counter: 865 case soc_feature_arl_hashed: 866 case soc_feature_arl_insert_ovr: 867 case soc_feature_basic_dos_ctrl: 868 case soc_feature_bigmac_fault_stat: 869 case soc_feature_counter_parity: 870 case soc_feature_cpuport_mirror: 871 case soc_feature_cpuport_stat_dma: 872 case soc_feature_cpuport_switched: 873 case soc_feature_dcb_reason_hi: 874 case soc_feature_dodeca_serdes: 875 case soc_feature_dual_hash: 876 case soc_feature_eee: 877 case soc_feature_ets: 878 case soc_feature_extended_pci_error: 879 case soc_feature_fe_maxframe: 880 case soc_feature_port_flow_hash: 881 case soc_feature_fifo_dma: 882 case soc_feature_fifo_dma_active: 883 case soc_feature_flex_port: 884 case soc_feature_flexible_dma_steps: 885 case soc_feature_force_forward: 886 case soc_feature_generic_counters: 887 case soc_feature_generic_table_ops: 888 case soc_feature_gmii_clkout: 889 case soc_feature_hw_stats_calc: 890 case soc_feature_l2_bulk_control: 891 case soc_feature_vlan_queue_map: 892 case soc_feature_vlan_mc_flood_ctrl: 893 case soc_feature_aging_extended: 894 case soc_feature_l2_hashed: 895 case soc_feature_l2_hw_aging_bug: 896 case soc_feature_l2_lookup_cmd: 897 case soc_feature_l2_lookup_retry: 898 case soc_feature_l2_modfifo: 899 case soc_feature_l2_overflow: 900 case soc_feature_l2_pending: 901 case soc_feature_l2_user_table: 902 case soc_feature_l2x_parity: 903 case soc_feature_led_data_offset_a0: 904 case soc_feature_led_proc: 905 case soc_feature_logical_port_num: 906 case soc_feature_lport_tab_profile: 907 case soc_feature_mbist: 908 case soc_feature_mdio_enhanced: 909 case soc_feature_mem_cache: 910 case soc_feature_mem_push_pop: 911 case soc_feature_min_cell_per_queue: 912 case soc_feature_min_resume_limit_1: 913 case soc_feature_mirror_control_mem: 914 case soc_feature_mirror_cos: 915 case soc_feature_mirror_encap_profile: 916 case soc_feature_mirror_flexible: 917 case soc_feature_mmu_config_property: 918 case soc_feature_modmap: 919 case soc_feature_modport_map_dest_is_port_or_trunk: 920 case soc_feature_module_loopback: 921 #ifdef INCLUDE_MSTP 922 case soc_feature_mstp: 923 #endif 924 case soc_feature_new_sbus_format: 925 case soc_feature_phy_cl45: 926 case soc_feature_post: 927 case soc_feature_qos_profile: 928 case soc_feature_regs_as_mem: 929 case soc_feature_remap_ut_prio: 930 case soc_feature_remote_learn_trust: 931 case soc_feature_rx_timestamp: 932 case soc_feature_rxdma_cleanup: 933 case soc_feature_sbusdma: 934 case soc_feature_schan_hw_timeout: 935 case soc_feature_schmsg_alias: 936 case soc_feature_ser_fifo: 937 case soc_feature_ser_parity: 938 case soc_feature_sgmii_autoneg: 939 case soc_feature_src_modid_base_index: 940 case soc_feature_stat_dma: 941 case soc_feature_stat_jumbo_adj: 942 case soc_feature_stat_xgs3: 943 case soc_feature_stg: 944 case soc_feature_stg_xgs: 945 case soc_feature_table_dma: 946 case soc_feature_table_hi: 947 case soc_feature_time_support: 948 case soc_feature_timesync_support: 949 case soc_feature_trunk_group_overlay: 950 case soc_feature_trunk_group_size: 951 case soc_feature_two_ingress_pipes: 952 case soc_feature_unified_port: 953 case soc_feature_vlan_ctrl: 954 case soc_feature_wesp: 955 case soc_feature_xgxs_power: 956 case soc_feature_xgxs_v7: 957 case soc_feature_xlmac: 958 case soc_feature_xy_tcam: 959 case soc_feature_xy_tcam_direct: 960 case soc_feature_shared_hash_mem: 961 case soc_feature_src_modid_blk: 962 case soc_feature_src_modid_blk_profile: 963 case soc_feature_egr_ipmc_mem_field_l3_payload_valid: 964 case soc_feature_tslam_dma: 965 return FALSE; 966 967 /* 968 * legacy features supported ONLY in NORMAL Latency mode 969 */ 970 default: 971 return (((SOC_SWITCH_BYPASS_MODE_NONE == latency) || (SOC_SWITCH_BYPASS_MODE_EFP == latency)) 972 ? (!soc_features_bcm56850_a0(unit, feature)) : TRUE); 973 } 974 975 } 976 977 /****************************************************************************** 978 * Name: soc_th2_latency_bypassed * 979 * Description: * 980 * Returns if the specified feature is supported/available for the * 981 * current Latency mode configured on the switch * 982 * IN params: * 983 * - Unit * 984 * - Feature (soc_feature_*) * 985 * Returns: * 986 * - FALSE, if the feature is supported * 987 * - TRUE, if the feature is unsupported * 988 */ 989 int 990 soc_th2_latency_bypassed( 991 int unit, 992 soc_feature_t feature) 993 { 994 int latency; 995 996 _SOC_TH_UNIT_VALIDATE(unit); 997 _SOC_TH_LATENCY_RT_ENABLE_CHK(unit); 998 999 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 1000 1001 switch(feature) { 1002 /* 1003 * features supported only in NORMAL latency mode and NOT supported in either 1004 * LOW (L2) or BALANCED (L2/L3) Latency modes 1005 */ 1006 case soc_feature_ecmp_dlb: 1007 case soc_feature_ecmp_dlb_optimized: 1008 case soc_feature_dgm: 1009 case soc_feature_ecn_wred: 1010 case soc_feature_mpls_ecn: 1011 case soc_feature_flex_hashing: 1012 case soc_feature_mpls_frr_lookup: 1013 return (SOC_SWITCH_BYPASS_MODE_NONE != latency); 1014 1015 /* 1016 * features supported in NORMAL and BALANCED Latency modes but 1017 * NOT in LOW (L2) Latency 1018 */ 1019 case soc_feature_lag_dlb: 1020 case soc_feature_hg_dlb: 1021 case soc_feature_hgt_lag_dlb_optimized: 1022 return (SOC_SWITCH_BYPASS_MODE_LOW == latency); 1023 1024 /* 1025 * features supported ONLY in LOW (L2) and BALANCED (L2/L3) Latency 1026 * mode but NOT in NORMAL Latency 1027 */ 1028 1029 /* 1030 * features supported ONLY in LOW (L2) Latency 1031 */ 1032 1033 /* 1034 * features supported only in BALANCED (L2/L3) Latency 1035 */ 1036 1037 /* 1038 * legacy features supported in ALL THREE Latency modes 1039 */ 1040 1041 /* 1042 * legacy features untouched 1043 */ 1044 default: 1045 return FALSE; 1046 } 1047 1048 } 1049 1050 /****************************************************************************** 1051 * Name: soc_th_latency_mem_avail * 1052 * Description: * 1053 * Returns if the specified memory / table is available for the * 1054 * current Latency mode configured on the switch * 1055 * IN params: * 1056 * - Unit * 1057 * - Memory/Table * 1058 * Returns: * 1059 * - TRUE, if the memory is available * 1060 * - FALSE, if the memory is unavailable * 1061 */ 1062 int 1063 soc_th_latency_mem_avail( 1064 int unit, 1065 soc_mem_t mem, 1066 int latency) 1067 { 1068 return _soc_th_latency_resource_avail(unit, _SOC_TH_MEM, mem, latency); 1069 } 1070 1071 /****************************************************************************** 1072 * Name: soc_th_latency_reg_avail * 1073 * Description: * 1074 * Returns if the specified register is available for the * 1075 * current Latency mode configured on the switch * 1076 * IN params: * 1077 * - Unit * 1078 * - Register * 1079 * Returns: * 1080 * - TRUE, if the register is available * 1081 * - FALSE, if the register is unavailable * 1082 */ 1083 int 1084 soc_th_latency_reg_avail( 1085 int unit, 1086 soc_reg_t reg, 1087 int latency) 1088 { 1089 return _soc_th_latency_resource_avail(unit, _SOC_TH_REG, reg, latency); 1090 } 1091 1092 /****************************************************************************** 1093 * Name: soc_th_latency_init * 1094 * Description: * 1095 * Configure the Switch and the SDK for the Latency Bypass mode * 1096 * specified in config.bcm * 1097 * IN params: * 1098 * - Unit * 1099 * Returns: * 1100 * - SOC_E_NONE on success * 1101 * - SOC_E_* on internal errors * 1102 */ 1103 int 1104 soc_th_latency_init(int unit) 1105 { 1106 int latency; 1107 uint32 rval = 0; 1108 _SOC_TH_UNIT_VALIDATE(unit); 1109 _SOC_TH_LATENCY_RT_ENABLE_CHK(unit); 1110 1111 #ifdef BCM_WARM_BOOT_SUPPORT 1112 if (SOC_WARM_BOOT(unit)) { 1113 /* WB recovery happens in _bcm_esw_port_wb_recover context */ 1114 return BCM_E_NONE; 1115 } 1116 #endif /* BCM_WARM_BOOT_SUPPORT */ 1117 1118 if (!(_soc_th_latency_ctrl[unit] = 1119 sal_alloc(sizeof(_soc_th_latency_ctrl_t), "TH Latency Ctrl Area"))) { 1120 return SOC_E_MEMORY; 1121 } 1122 1123 latency = soc_property_get(unit, spn_SWITCH_BYPASS_MODE, 1124 SOC_SWITCH_BYPASS_MODE_NONE); 1125 _SOC_TH_LATENCY_CFG_VALIDATE(latency, SOC_E_NONE); 1126 1127 /* Set MMU in reset */ 1128 if ((latency == SOC_SWITCH_BYPASS_MODE_LOW) || 1129 (latency == SOC_SWITCH_BYPASS_MODE_BALANCED)) { 1130 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1131 (BSL_META_U(unit, 1132 "Unit:%d Latency mode update. Mode %d. " 1133 "Initiate MMU reset\n"), 1134 unit, latency)); 1135 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 1136 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0); 1137 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 1138 } 1139 if (SOC_SWITCH_BYPASS_MODE_EFP == latency) { 1140 /* config EFP latency settings */ 1141 SOC_IF_ERROR_RETURN(_soc_th_efp_latency_config(unit, latency)); 1142 } else { 1143 /* config ingress latency settings */ 1144 SOC_IF_ERROR_RETURN(_soc_th_igr_latency_config(unit, latency)); 1145 /* config egress latency settings */ 1146 SOC_IF_ERROR_RETURN(_soc_th_egr_latency_config(unit, latency)); 1147 } 1148 1149 _soc_th_latency_ctrl[unit]->init = 1; 1150 _soc_th_latency_ctrl[unit]->latency = latency; 1151 SOC_SWITCH_BYPASS_MODE(unit) = latency; 1152 1153 /* apply reg filter for the current latency config */ 1154 SOC_IF_ERROR_RETURN(_soc_th_latency_reg_filter(unit)); 1155 /* apply memory filter for the current latency config */ 1156 SOC_IF_ERROR_RETURN(_soc_th_latency_mem_filter(unit)); 1157 1158 /* Bring MMU out of reset */ 1159 if ((latency == SOC_SWITCH_BYPASS_MODE_LOW) || 1160 (latency == SOC_SWITCH_BYPASS_MODE_BALANCED)) { 1161 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 1162 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 1163 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 1164 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1165 (BSL_META_U(unit, 1166 "Unit:%d Latency update done. MMU out of reset.\n"), 1167 unit)); 1168 } 1169 1170 sal_memcpy(&_soc_th_latency_ctrl[unit]->tbl_cfg, &soc_th_tbl_cfg[unit], 1171 sizeof(soc_th_latency_table_cfg_t)); 1172 1173 LOG_DEBUG(BSL_LS_SOC_INIT, 1174 (BSL_META_U(unit, "*** unit %d: configured for %s latency\n"), 1175 unit, lstr[latency])); 1176 1177 return SOC_E_NONE; 1178 } 1179 1180 int 1181 soc_th_latency_deinit(int unit) 1182 { 1183 if (_soc_th_latency_ctrl[unit]) { 1184 sal_free(_soc_th_latency_ctrl[unit]); 1185 _soc_th_latency_ctrl[unit] = NULL; 1186 } 1187 1188 return SOC_E_NONE; 1189 } 1190 1191 1192 /*********************************** 1193 * Latency Bypass Warmboot Support * 1194 */ 1195 #ifdef BCM_WARM_BOOT_SUPPORT 1196 1197 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 1198 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 1199 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1,2) 1200 #define BCM_WB_VERSION_1_3 SOC_SCACHE_VERSION(1,3) 1201 #define BCM_WB_VERSION_1_4 SOC_SCACHE_VERSION(1,4) 1202 #define BCM_WB_VERSION_1_5 SOC_SCACHE_VERSION(1,5) 1203 #define BCM_WB_VERSION_1_6 SOC_SCACHE_VERSION(1,6) 1204 #define BCM_WB_VERSION_1_7 SOC_SCACHE_VERSION(1,7) 1205 #define BCM_WB_VERSION_1_8 SOC_SCACHE_VERSION(1,8) 1206 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_8 1207 1208 /* reconfigure latency sw states during wb recovery */ 1209 /* level 0 - reinitializes latency wb control structure */ 1210 /* level 1 - reinitializes reg and memory filters only */ 1211 int 1212 soc_th_latency_wb_reinit(int unit, int level) 1213 { 1214 int latency_wb, latency_cfg; 1215 1216 if (!SOC_WARM_BOOT(unit)) { 1217 return SOC_E_INTERNAL; 1218 } 1219 1220 /* config.bcm's version of latency */ 1221 latency_cfg = soc_property_get(unit, spn_SWITCH_BYPASS_MODE, 1222 SOC_SWITCH_BYPASS_MODE_NONE); 1223 1224 if (0 == level) { 1225 _SOC_TH_UNIT_VALIDATE(unit); 1226 _SOC_TH_LATENCY_RT_ENABLE_CHK(unit); 1227 1228 if (!_soc_th_latency_ctrl[unit]) { 1229 return SOC_E_INTERNAL; 1230 } 1231 1232 /* rashomon */ 1233 if (1 == _soc_th_latency_ctrl[unit]->init) { 1234 /* wb's version of latency */ 1235 latency_wb = _soc_th_latency_ctrl[unit]->latency; 1236 } else { 1237 return SOC_E_INTERNAL; 1238 } 1239 1240 /* ratify the sanity of wb recovery */ 1241 if (latency_cfg == latency_wb) { 1242 _soc_th_latency_ctrl[unit]->latency = latency_cfg; 1243 } else { 1244 return SOC_E_INTERNAL; 1245 } 1246 1247 /* reconfiguration section */ 1248 SOC_SWITCH_BYPASS_MODE(unit) = _soc_th_latency_ctrl[unit]->latency; 1249 } else { 1250 if (!latency_cfg) { 1251 return SOC_E_NONE; 1252 } 1253 /* reapply reg filter */ 1254 SOC_IF_ERROR_RETURN(_soc_th_latency_reg_filter(unit)); 1255 /* reapply memory filter */ 1256 SOC_IF_ERROR_RETURN(_soc_th_latency_mem_filter(unit)); 1257 } 1258 1259 return SOC_E_NONE; /* back to normalcy */ 1260 } 1261 1262 int 1263 soc_th_latency_wb_memsz_get( 1264 int unit, 1265 OUT uint32* const mem_sz, 1266 uint16 scache_ver) 1267 { 1268 _SOC_TH_UNIT_VALIDATE(unit); 1269 if (!mem_sz) { 1270 return SOC_E_PARAM; 1271 } 1272 *mem_sz = 0; 1273 1274 if (!SOC_WARM_BOOT(unit)) { 1275 if (!_soc_th_latency_ctrl[unit] || !_soc_th_latency_ctrl[unit]->init) { 1276 return SOC_E_NONE; 1277 } 1278 } 1279 1280 *mem_sz = sizeof(_soc_th_latency_wb_t); 1281 1282 /* adjust for lower versions */ 1283 if (scache_ver < BCM_WB_VERSION_1_8) { 1284 *mem_sz -= sizeof(soc_th_latency_table_cfg_t); 1285 } 1286 1287 return SOC_E_NONE; 1288 } 1289 1290 int 1291 soc_th_latency_wb_sync( 1292 int unit, 1293 IN_OUT uint8* const wb_data) 1294 { 1295 _soc_th_latency_wb_t *wbd; 1296 1297 _SOC_TH_UNIT_VALIDATE(unit); 1298 if (!_soc_th_latency_ctrl[unit] || !_soc_th_latency_ctrl[unit]->init) { 1299 return SOC_E_NONE; 1300 } 1301 if (!wb_data) { 1302 return SOC_E_PARAM; 1303 } 1304 1305 wbd = (_soc_th_latency_wb_t *) wb_data; 1306 wbd->unit = unit; 1307 sal_memcpy(&wbd->latency_ctrl, _soc_th_latency_ctrl[unit], 1308 sizeof(_soc_th_latency_ctrl_t)); 1309 1310 return SOC_E_NONE; 1311 } 1312 1313 int 1314 soc_th_latency_wb_recover( 1315 int unit, 1316 uint8* const wb_data, 1317 uint16 scache_ver) 1318 { 1319 _soc_th_latency_wb_t *wbd; 1320 int adj = 0; /*scache ver adjustment */ 1321 1322 _SOC_TH_UNIT_VALIDATE(unit); 1323 if (!SOC_WARM_BOOT(unit)) { 1324 return SOC_E_INTERNAL; 1325 } 1326 if (!wb_data) { 1327 return SOC_E_PARAM; 1328 } 1329 1330 wbd = (_soc_th_latency_wb_t *) wb_data; 1331 if (wbd->unit == unit) { 1332 if (!(_soc_th_latency_ctrl[unit] = 1333 sal_alloc(sizeof(_soc_th_latency_ctrl_t), 1334 "TH Latency Bypass Ctrl Area"))) { 1335 return SOC_E_MEMORY; 1336 } 1337 1338 /* adjust for lower versions */ 1339 if (scache_ver < BCM_WB_VERSION_1_8) { 1340 adj = sizeof(soc_th_latency_table_cfg_t); 1341 /* backfill tbl_cfg from TH driver's global bookkeeping */ 1342 sal_memcpy(&_soc_th_latency_ctrl[unit]->tbl_cfg, &soc_th_tbl_cfg[unit], 1343 sizeof(soc_th_latency_table_cfg_t)); 1344 } 1345 1346 sal_memcpy(_soc_th_latency_ctrl[unit], &wbd->latency_ctrl, 1347 (sizeof(_soc_th_latency_ctrl_t) - adj)); 1348 } 1349 1350 SOC_IF_ERROR_RETURN(soc_th_latency_wb_reinit(unit, 0)); 1351 1352 LOG_CLI((BSL_META_U(unit, "*** unit %d: Latency subsystem warmbooted: " 1353 "configured for %s latency\n"), unit, 1354 lstr[_soc_th_latency_ctrl[unit]->latency])); 1355 1356 return SOC_E_NONE; 1357 } 1358 #endif /* BCM_WARM_BOOT_SUPPORT */ 1359 1360 /******************************** 1361 * Latency Bypass Debug Support * 1362 */ 1363 int 1364 soc_th_latency_show(int unit) 1365 { 1366 int mode; 1367 char *mode_str[3] = { 1368 "Normal latency (full features)", 1369 "Balanced (L2/L3) Latency", 1370 "Low (L2) Latency" 1371 }; 1372 1373 _SOC_TH_UNIT_VALIDATE(unit); 1374 _SOC_TH_LATENCY_INIT_VALIDATE(unit, SOC_E_INTERNAL); 1375 1376 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &mode)); 1377 LOG_CLI(("switch latency mode : %s\n", mode_str[mode])); 1378 1379 if (soc_feature(unit, soc_feature_fastlag)) { 1380 LOG_CLI(("Trunking mode : Fast LAG\n")); 1381 } 1382 if (soc_feature(unit, soc_feature_fast_ecmp)) { 1383 LOG_CLI(("ECMP mode : Fast ECMP\n")); 1384 } 1385 1386 return SOC_E_NONE; 1387 } 1388 1389 int 1390 soc_th_latency_diag(int unit) 1391 { 1392 int mode; 1393 char *mode_str[3] = { 1394 "Normal latency (full features)", 1395 "Balanced (L2/L3) Latency", 1396 "Low (L2) Latency" 1397 }; 1398 uint32 rval; 1399 uint8 ipars, ivxlt, ivp, ifwd, irsel1, ifp, irsel2, isw2; 1400 uint8 ecmp; 1401 1402 _SOC_TH_UNIT_VALIDATE(unit); 1403 _SOC_TH_LATENCY_INIT_VALIDATE(unit, SOC_E_INTERNAL); 1404 1405 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &mode)); 1406 1407 SOC_IF_ERROR_RETURN(READ_ING_LATENCY_CONTROLr(unit, &rval)); 1408 ipars = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1409 IPARS_LATENCY_MODEf); 1410 ivxlt = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1411 IVXLT_BYPASSf); 1412 ivp = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1413 IVP_BYPASSf); 1414 ifwd = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1415 IFWD_LATENCY_MODEf); 1416 irsel1 = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1417 IRSEL1_LATENCY_MODEf); 1418 ifp = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1419 IFP_BYPASSf); 1420 irsel2 = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1421 IRSEL2_LATENCY_MODEf); 1422 isw2 = soc_reg_field_get(unit, ING_LATENCY_CONTROLr, rval, 1423 ISW2_LATENCY_MODEf); 1424 1425 SOC_IF_ERROR_RETURN(READ_ECMP_CONFIGr(unit, &rval)); 1426 ecmp = soc_reg_field_get(unit, ECMP_CONFIGr, rval, ECMP_MODEf); 1427 1428 LOG_CLI(("switch latency mode : %s\n", mode_str[mode])); 1429 1430 if (soc_feature(unit, soc_feature_fastlag)) { 1431 LOG_CLI(("Trunking mode : Fast LAG\n")); 1432 } 1433 if (soc_feature(unit, soc_feature_fast_ecmp)) { 1434 LOG_CLI(("ECMP mode : Fast ECMP\n")); 1435 } 1436 1437 LOG_CLI(("Ingress Latency Configurations:\n")); 1438 LOG_CLI(("ipars ivxlt ivp ifwd irsel1 ifp irsel2 isw2 ecmp\n")); 1439 LOG_CLI(("%5d %5d %3d %4d %6d %3d %6d %4d %4d\n", 1440 ipars, ivxlt, ivp, ifwd, irsel1, ifp, irsel2, isw2, ecmp)); 1441 1442 LOG_CLI(("Egress Latency Configurations:\n")); 1443 LOG_CLI(("el3 evlan efp\n")); 1444 /* 1445 * due to an RTL issue which left EGR_LATENCY_MODE as NOTEST, we don't 1446 * have any option but to produce the sw state in lieu of the register values 1447 */ 1448 LOG_CLI(("%3d %5d %3d\n", _soc_th_latency_cfg_tbl[mode].egr.el3, 1449 _soc_th_latency_cfg_tbl[mode].egr.evlan, 1450 _soc_th_latency_cfg_tbl[mode].egr.efp)); 1451 1452 /* table configurations */ 1453 LOG_CLI(("l2_entries:%d\n", 1454 _soc_th_latency_ctrl[unit]->tbl_cfg.l2_entries)); 1455 LOG_CLI(("fixed_l2_entries:%d\n", 1456 _soc_th_latency_ctrl[unit]->tbl_cfg.fixed_l2_entries)); 1457 LOG_CLI(("shared_l2_banks:%d\n", 1458 _soc_th_latency_ctrl[unit]->tbl_cfg.shared_l2_banks)); 1459 LOG_CLI(("l3_entries:%d\n", 1460 _soc_th_latency_ctrl[unit]->tbl_cfg.l3_entries)); 1461 LOG_CLI(("fixed_l3_entries:%d\n", 1462 _soc_th_latency_ctrl[unit]->tbl_cfg.fixed_l3_entries)); 1463 LOG_CLI(("shared_l3_banks:%d\n", 1464 _soc_th_latency_ctrl[unit]->tbl_cfg.shared_l3_banks)); 1465 LOG_CLI(("fpem_entries:%d\n", 1466 _soc_th_latency_ctrl[unit]->tbl_cfg.fpem_entries)); 1467 LOG_CLI(("shared_fpem_banks:%d\n", 1468 _soc_th_latency_ctrl[unit]->tbl_cfg.shared_fpem_banks)); 1469 LOG_CLI(("alpm_enable:%d\n", 1470 _soc_th_latency_ctrl[unit]->tbl_cfg.alpm_enable)); 1471 LOG_CLI(("max_tcams:%d\n", 1472 _soc_th_latency_ctrl[unit]->tbl_cfg.max_tcams)); 1473 LOG_CLI(("tcam_depth:%d\n", 1474 _soc_th_latency_ctrl[unit]->tbl_cfg.tcam_depth)); 1475 1476 return SOC_E_NONE; 1477 } 1478 1479 #endif /* BCM_TOMAHAWK_SUPPORT */ 1480