monterey.c (649746B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 * 6 * File: monterey.c 7 * Purpose: 8 * Requires: 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <sal/core/boot.h> 14 #include <soc/bradley.h> 15 #include <soc/drv.h> 16 #include <soc/error.h> 17 #include <soc/debug.h> 18 #include <soc/mem.h> 19 #include <soc/monterey.h> 20 #include <soc/apache.h> 21 #include <soc/i2c.h> 22 #include <soc/mspi.h> 23 #include <soc/l2x.h> 24 #include <soc/soc_ser_log.h> 25 #include <soc/trident2.h> 26 #include <soc/tdm/core/tdm_top.h> 27 #include <soc/mcm/memregs.h> 28 #ifdef BCM_MONTEREY_SUPPORT 29 30 #ifdef ALPM_ENABLE 31 #include <soc/lpm.h> 32 #include <soc/alpm.h> 33 #include <soc/esw/alpm_int.h> 34 #endif /* ALPM_ENABLE */ 35 36 #include <soc/mmu_config.h> 37 #include <soc/post.h> 38 39 #include <soc/esw/portctrl.h> 40 #include <soc/bondoptions.h> 41 42 #ifdef PORTMOD_SUPPORT 43 #include <soc/portmod/portmod.h> 44 #endif /* PORTMOD_SUPPORT */ 45 #ifdef CPRIMOD_SUPPORT 46 #include <soc/cprimod/cprimod.h> 47 #include <shared/cpri.h> 48 #endif /* CPRIMOD_SUPPORT */ 49 #ifdef INCLUDE_XFLOW_MACSEC 50 #include <bcm_int/common/xflow_macsec_cmn.h> 51 #endif 52 53 #include <soc/iproc.h> 54 #include <bcm/pkt.h> 55 #include <bcm/tx.h> 56 57 #define _MONTEREY_BYTES_PER_OBM_CELL 16 58 #define _MONTEREY_CELLS_PER_OBM 1020 59 60 #define _MONTEREY_LOG_PORTS_PER_PIPE 67 61 #define _MONTEREY_MMU_PORTS_PER_PIPE 67 62 #define _SOC_MONTEREY_MAX_PORT (_MONTEREY_LOG_PORTS_PER_PIPE) 63 64 #define _MONTEREY_MMU_PACKET_HEADER_BYTES 64 /* bytes */ 65 #define _MONTEREY_MMU_JUMBO_FRAME_BYTES 9216 /* bytes */ 66 #define _MONTEREY_MMU_DEFAULT_MTU_BYTES 1536 /* bytes */ 67 68 #define _MONTEREY_MMU_BYTES_PER_CELL 208 /* bytes (1664 bits) */ 69 #define _MONTEREY_MMU_NUM_PG 8 70 #define _MONTEREY_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE 50 71 #define _MONTEREY_MMU_PG_MIN 8 72 73 #define SOC_MONTEREY_MMU_CFG_QGROUP_MAX 128 74 75 #define SOC_MONTEREY_MMU_MCQ_ENTRY 12288 76 #define SOC_MONTEREY_MMU_RQE_ENTRY 1024 77 78 #define _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit) SOC_MONTEREY_MMU_MCQ_ENTRY 79 80 #define _MONTEREY_MMU_TOTAL_RQE_ENTRY(unit) SOC_MONTEREY_MMU_RQE_ENTRY 81 82 #define _SOC_MONTEREY_DEFIP_MAX_TCAMS 8 83 #define _SOC_MONTEREY_DEFIP_TCAM_DEPTH 64 84 85 #define IS_OVERSUB_PORT(unit,port) \ 86 (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) 87 88 #define INVALID_PORT -1 89 90 /* defines for Reserved Buffer for Flex Port Macro when new Flex Port is 91 enabled */ 92 /* lossless defines */ 93 #define _MN_RSVD_BUF_10G_FLEX_HDRM_LOSSLESS 185 94 #define _MN_RSVD_BUF_25G_FLEX_HDRM_LOSSLESS 214 95 96 #define _MN_RSVD_BUF_FLEX_QGRP 16 97 #define _MN_RSVD_BUF_10G_FLEX_ASF 4 98 #define _MN_RSVD_BUF_25G_FLEX_ASF 16 99 100 /* defines for Reserved Buffer for Ports when Flex Port for the macro is NOT 101 enabled*/ 102 #define _MN_RSVD_BUF_NON_FLEX_OB_100G_HDRM_LOSSLESS 687 103 #define _MN_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS 558 104 #define _MN_RSVD_BUF_NON_FLEX_OB_50G_HDRM_LOSSLESS 352 105 #define _MN_RSVD_BUF_NON_FLEX_50G_HDRM_LOSSLESS 298 106 #define _MN_RSVD_BUF_NON_FLEX_OB_40G_HDRM_LOSSLESS 338 107 #define _MN_RSVD_BUF_NON_FLEX_40G_HDRM_LOSSLESS 284 108 #define _MN_RSVD_BUF_NON_FLEX_OB_25G_HDRM_LOSSLESS 214 109 #define _MN_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS 191 110 #define _MN_RSVD_BUF_NON_FLEX_OB_20G_HDRM_LOSSLESS 206 111 #define _MN_RSVD_BUF_NON_FLEX_20G_HDRM_LOSSLESS 183 112 #define _MN_RSVD_BUF_NON_FLEX_OB_10G_HDRM_LOSSLESS 185 113 #define _MN_RSVD_BUF_NON_FLEX_10G_HDRM_LOSSLESS 162 114 #define _MN_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS 8 115 #define _MN_RSVD_BUF_NON_FLEX_PGMIN 8 116 #define _MN_RSVD_BUF_NON_FLEX_QGRP 16 117 #define _MN_RSVD_BUF_NON_FLEX_ASF 16 118 #define _MN_RSVD_BUF_NON_FLEX_10G_ASF 4 119 /* mmu_mc_egr_qentry_min in Settings sheet */ 120 #define _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD 6 121 #define _MN_RSVD_BUF_10G_FLEX_QGRP 16 122 #define _MN_MMU_NUM_MCQ_PORT_MACRO 10 123 #define _MN_MMU_RDB_PORT_MIN 90 124 125 #define _MN_MMU_EXPRESS_BUFFER_TOTAL_1 11550 126 #define _MN_MMU_EXPRESS_BUFFER_TOTAL_2 12170 127 128 /* 129 * TDM algo does not support all speeds. SDK needs to adjust 130 * the speeds to what is supported in the algorithm. 131 * 132 * Anything < 1G will be passed as 1G. 133 * 5G needs to be passed as 10G. 134 * 2.5G is supported in the TDM. We can pass as is. 135 */ 136 #define MONTEREY_TDM_SPEED_ADJUST(unit, port, speed) \ 137 do { \ 138 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed); \ 139 if ((speed > 0) && (speed < 10000)) { \ 140 if (IS_OVERSUB_PORT(unit, port)) { \ 141 speed = 10000; \ 142 } else if (speed < 1000) { \ 143 speed = 1000; \ 144 } else if (speed == 5000) { \ 145 speed = 10000; \ 146 } \ 147 } \ 148 } while (0) 149 int soc_monterey_is_any_port_flex_enable(int unit); 150 int soc_mn_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled); 151 int 152 bcmi_mn_preemption_capability_get(int unit, bcm_port_t port, 153 uint32* arg); 154 155 typedef enum { 156 _SOC_PARITY_TYPE_NONE, 157 _SOC_PARITY_TYPE_GENERIC, 158 _SOC_PARITY_TYPE_PARITY, 159 _SOC_PARITY_TYPE_ECC, 160 _SOC_PARITY_TYPE_MMU_SER, 161 _SOC_PARITY_TYPE_START_ERR, 162 _SOC_PARITY_TYPE_SER, 163 _SOC_PARITY_TYPE_BST, 164 _SOC_PARITY_TYPE_MAC_RX_CDC, 165 _SOC_PARITY_TYPE_MAC_TX_CDC, 166 _SOC_PARITY_TYPE_MAC_RX_TS, 167 _SOC_PARITY_TYPE_MIB, 168 _SOC_PARITY_TYPE_OBM 169 #ifdef INCLUDE_XFLOW_MACSEC 170 ,_SOC_PARITY_TYPE_MACSEC_SER, 171 _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL 172 #endif 173 } _soc_monterey_ser_info_type_t; 174 175 typedef struct _soc_monterey_fifo_ser_info_s { 176 soc_reg_t enable_reg; 177 soc_field_t enable_field; 178 uint8 type; /* 0: mem, 1: reg, 2: bus */ 179 soc_mem_t mem; 180 soc_reg_t reg; 181 char *name_str; /* Used when mem == INVALIDm or reg == INVALIDr or type == bus 182 (either not accessible or multiple) */ 183 } _soc_monterey_fifo_ser_info_t; 184 185 typedef struct _soc_monterey_ser_block_info_s { 186 int type; 187 soc_block_t blocktype; 188 char name[16]; 189 soc_reg_t fifo_reset_reg; 190 void *info; 191 } _soc_monterey_ser_block_info_t; 192 193 typedef struct _soc_monterey_ser_reg_s { 194 soc_reg_t reg; 195 char *mem_str; 196 } _soc_monterey_ser_reg_t; 197 198 typedef struct _soc_monterey_ser_info_s { 199 _soc_monterey_ser_info_type_t type; 200 struct _soc_monterey_ser_info_s *info; 201 int id; 202 soc_field_t group_reg_enable_field; 203 soc_field_t group_reg_status_field; 204 soc_mem_t mem; 205 char *mem_str; 206 soc_reg_t enable_reg; 207 soc_field_t enable_field; 208 soc_reg_t intr_status_reg; 209 _soc_monterey_ser_reg_t *intr_status_reg_list; 210 soc_reg_t intr_clr_reg; 211 soc_field_t intr_clr_field; 212 soc_field_t *intr_clr_field_list; 213 } _soc_monterey_ser_info_t; 214 215 typedef struct _soc_monterey_ser_route_block_s { 216 uint32 cmic_bit; 217 soc_block_t blocktype; 218 soc_reg_t enable_reg; 219 soc_reg_t status_reg; 220 soc_field_t enable_field; 221 _soc_monterey_ser_info_t *info; 222 uint8 id; 223 } _soc_monterey_ser_route_block_t; 224 225 typedef struct _soc_monterey_intr_info_s { 226 _soc_monterey_ser_info_type_t type; 227 struct _soc_monterey_ser_info_s *info; 228 int id; 229 soc_field_t group_reg_enable_field; 230 soc_field_t group_reg_status_field; 231 soc_mem_t mem; 232 char *mem_str; 233 soc_reg_t enable_reg; 234 soc_field_t enable_field; 235 soc_reg_t intr_status_reg; 236 _soc_monterey_ser_reg_t *intr_status_reg_list; 237 soc_reg_t intr_clr_reg; 238 soc_field_t intr_clr_field; 239 soc_field_t *intr_clr_field_list; 240 } _soc_monterey_intr_info_t; 241 242 typedef struct _soc_monterey_intr_route_block_s { 243 uint32 cmic_bit; 244 soc_block_t blocktype; 245 soc_reg_t enable_reg; 246 soc_reg_t status_reg; 247 soc_field_t enable_field; 248 _soc_monterey_intr_info_t *info; 249 uint8 id; 250 } _soc_monterey_pm_cpri_intr_info_t; 251 252 typedef struct _soc_monterey_pm_ecc_info_s { 253 _soc_monterey_ser_info_type_t type; 254 _shr_cpri_ecc_err_type_t ecc_err_type; /* 1-bit, 2-bit, multi-bit */ 255 int port; 256 soc_mem_t mem; 257 uint32 mem_index; 258 char *mem_str; 259 } _soc_monterey_pm_ecc_info_t; 260 261 typedef struct _soc_monterey_mmu_traffic_ctrl_s { 262 uint8 thdo_drop_bmp[_SOC_MONTEREY_MAX_PORT]; 263 } _soc_monterey_mmu_traffic_ctrl_t; 264 265 typedef struct _soc_mn_mmu_buffer_config_s { 266 int total_physical_memory; 267 int cfapfullsetpoint; 268 int total_cell_memory; 269 int num_mem_banks; 270 int num_10g_ports; 271 int num_20g_ports; 272 int num_40g_ports; 273 int num_100g_ports; 274 int num_ovsb_10g_ports; 275 int num_ovsb_20g_ports; 276 int num_ovsb_40g_ports; 277 int num_ovsb_100g_ports; 278 } _soc_mn_mmu_buffer_config_t; 279 280 #define _MN_NUM_SKEWS 1 281 STATIC _soc_mn_mmu_buffer_config_t soc_mn_buffer_config[_MN_NUM_SKEWS] = { 282 { 24576, 20416, 20416, 6, 64, 0, 0, 0, 64, 0, 0, 0 } 283 }; 284 STATIC int _soc_mn_skew_index; 285 286 #define _MONTEREY_MMU_PHYSICAL_CELLS \ 287 soc_mn_buffer_config[_soc_mn_skew_index].total_physical_memory 288 289 #define _MONTEREY_CFAPFULLSETPOINT \ 290 soc_mn_buffer_config[_soc_mn_skew_index].cfapfullsetpoint 291 #define _MONTEREY_MMU_RSVD_CELLS_CFAP \ 292 soc_mn_buffer_config[_soc_mn_skew_index].num_mem_banks * \ 293 (23 + 2 + 10) 294 295 #define _MONTEREY_MMU_TOTAL_CELLS \ 296 soc_mn_buffer_config[_soc_mn_skew_index].total_cell_memory 297 298 #define MAC_ENABLE_SET_CTRL (1 << 0) 299 #define MMU_TRAFFIC_EN_CTRL (1 << 1) 300 #define COSQ_SCHED_SET_CTRL (1 << 2) 301 static _soc_monterey_mmu_traffic_ctrl_t 302 *_soc_monterey_mmu_traffic_ctrl[SOC_MAX_NUM_DEVICES]; 303 static sal_mutex_t _fwd_ctrl_lock[SOC_MAX_NUM_DEVICES]; 304 #define FWD_CTRL_LOCK(unit) \ 305 sal_mutex_take(_fwd_ctrl_lock[unit], sal_mutex_FOREVER) 306 #define FWD_CTRL_UNLOCK(unit) \ 307 sal_mutex_give(_fwd_ctrl_lock[unit]) 308 309 typedef struct tsc_dpll_refclk_connect 310 { 311 int pll0_refclk_select; /* 0: select PAD ref clock; 1: select internal LC ref clock, refer to pll0_lc_refclk_select*/ 312 int pll0_master_enable; /* 0: disable; 1: enable ref clock output for other PLL */ 313 int pll0_lc_refclk_select; /* 0: select pll0_lc_refclk; 1 select pll1_lc_refclk */ 314 int pll1_refclk_select; /* 0: select PAD ref clock; 1: select internal LC ref clock, refer to pll1_lc_refclk_select*/ 315 int pll1_master_enable; /* 0: disable; 1: enable ref clock output for other PLL */ 316 int pll1_lc_refclk_select; /* 0: select pll0_lc_refclk; 1: select pll1_lc_refclk */ 317 }tsc_dpll_refclk_connect_t; 318 319 #define PM_NUM 16 320 321 /* CPM cores: TSC0 - TSC2, TSC13 - TSC15 */ 322 /* select pll0_lc_refclk (122.88MHz) as CPRI */ 323 /* select pll1_lc_refclk (156.25MHz) as ETH */ 324 /* PM4X25 cores: TSC3 - TSC4, TSC11 - TSC12 */ 325 /* TSC3/TSC12 are master PLL core */ 326 /* select pll0_lc_refclk */ 327 /* PM4X10 cores: TSC5 - TSC7, TSC8 - TSC10 */ 328 /* TSC6/TSC9 are master PLL core */ 329 /* select pll0_lc_refclk */ 330 /* This table is for all CPM cores working in Ethernet */ 331 tsc_dpll_refclk_connect_t monterey_tsc_refclk_connect[PM_NUM] = 332 { 333 /* TSC0 CPM4X25 */ 334 /* PLL0/PLL1 select LC refclk; disable refclk output; select pll1_lc_refclk */ 335 {1, 0, 1, 1, 0, 1}, 336 /* TSC1 CPM4X25 */ 337 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll1_lc_refclk */ 338 {1, 0, 1, 1, 0, 1}, 339 /* TSC2 CPM4X25 PLL1 master PLL*/ 340 /* PLL0 select LC refclk, disable refclk output, select pll1_lc_refclk */ 341 /* PLL1 select LC refclk, enable refclk output, select pll1_lc_refclk */ 342 {1, 0, 1, 1, 1, 1}, 343 /* TSC3 PM4X25 PLL0 master PLL*/ 344 /* PLL0 select LC refclk, enable refclk output, select pll0_lc_refclk */ 345 /* PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 346 {1, 1, 0, 1, 0, 0}, 347 /* TSC4 PM4X25 */ 348 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 349 {1, 0, 0, 1, 0, 0}, 350 /* TSC5 PM4X10 */ 351 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 352 {1, 0, 0, 1, 0, 0}, 353 /* TSC6 PM4X10 PLL0/PLL1 master pll*/ 354 /* PLL0/PLL1 select LC refclk, enable refclk output, select pll0_lc_refclk */ 355 {1, 1, 0, 1, 1, 0}, 356 /* TSC7 PM4X10 */ 357 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 358 {1, 0, 0, 1, 0, 0}, 359 /* TSC8 PM4X10 */ 360 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 361 {1, 0, 0, 1, 0, 0}, 362 /* TSC9 PM4X10 PLL0/PLL1 master pll*/ 363 /* PLL0/PLL1 select LC refclk, enable refclk output, select pll0_lc_refclk */ 364 {1, 1, 0, 1, 1, 0}, 365 /* TSC10 PM4X10 */ 366 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 367 {1, 0, 0, 1, 0, 0}, 368 /* TSC11 PM4X25 */ 369 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 370 {1, 0, 0, 1, 0, 0}, 371 /* TSC12 PM4X25 PLL0 master PLL*/ 372 /* PLL0 select LC refclk, enable refclk output, select pll0_lc_refclk */ 373 /* PLL1 select LC refclk, disable refclk output, select pll0_lc_refclk */ 374 {1, 1, 0, 1, 0, 0}, 375 /* TSC13 CPM4X25 PLL1 master PLL*/ 376 /* PLL0 select LC refclk, disable refclk output, select pll1_lc_refclk */ 377 /* PLL1 select LC refclk, enable refclk output, select pll1_lc_refclk */ 378 {1, 0, 1, 1, 1, 1}, 379 /* TSC14 CPM4X25 */ 380 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll1_lc_refclk */ 381 {1, 0, 1, 1, 0, 1}, 382 /* TSC15 CPM4X25 */ 383 /* PLL0/PLL1 select LC refclk, disable refclk output, select pll1_lc_refclk */ 384 {1, 0, 1, 1, 0, 1} 385 }; 386 387 #define monterey_tsc_is_master_pll(pm) \ 388 monterey_tsc_refclk_connect[pm].pll0_master_enable || \ 389 monterey_tsc_refclk_connect[pm].pll1_master_enable 390 391 /* Forward declarations */ 392 STATIC int 393 _soc_monterey_mdio_reg_read(int unit, uint32 phy_addr, 394 uint32 phy_reg, uint32 *phy_data); 395 STATIC int 396 _soc_monterey_mdio_reg_write(int unit, uint32 phy_addr, 397 uint32 phy_reg, uint32 phy_data); 398 399 #define _SOC_MONTEREY_SER_TYPE_REG 0 400 #define _SOC_MONTEREY_SER_TYPE_MEM 1 401 #define _SOC_MONTEREY_SER_TYPE_BUS 2 402 #define _SOC_MONTEREY_SER_TYPE_BUF 3 403 404 /* These are now generated from the regsfile processing into bcm56670_a0.c 405 structures are defined in chip.h */ 406 extern _soc_mem_ser_en_info_t _soc_bcm56670_a0_ip_mem_ser_info[]; 407 extern _soc_reg_ser_en_info_t _soc_bcm56670_a0_ip_reg_ser_info[]; 408 extern _soc_mem_ser_en_info_t _soc_bcm56670_a0_ep_mem_ser_info[]; 409 extern _soc_reg_ser_en_info_t _soc_bcm56670_a0_ep_reg_ser_info[]; 410 extern _soc_mem_ser_en_info_t _soc_bcm56670_a0_mmu_mem_ser_info[]; 411 #if defined(BCM_56670_B0) && defined(INCLUDE_XFLOW_MACSEC) 412 extern _soc_mem_ser_en_info_t _soc_bcm56670_b0_macsec_mem_ser_info[]; 413 #endif 414 415 /* These can be re-used from TD2P. As naming is SOC independent 416 * and information is same we'll reuse them here 417 */ 418 extern _soc_buffer_ser_en_info_t _soc_mmu_buffer_ser_info[]; 419 420 421 static _soc_bus_ser_en_info_t _soc_monterey_ip_bus_ser_info [] = { 422 { "IPARS", IPARS_SER_CONTROLr, IPARS_BUS_PARITY_ENf }, 423 { "IRSEL1", IRSEL1_SER_CONTROLr, IRSEL1_BUS_PARITY_ENf }, 424 { "IRSEL2", IRSEL2_SER_CONTROLr, IRSEL2_BUS_PARITY_ENf }, 425 { "ISW1", ISW1_SER_CONTROLr, ISW1_BUS_PARITY_ENf }, 426 { "IVXLT", IVXLT_SER_CONTROLr, IVXLT_BUS_PARITY_ENf }, 427 { "LEARN_FIFO", IARB_SER_CONTROLr, LEARN_FIFO_ECC_ENf }, 428 { "MPLS", MPLS_SER_CONTROLr, MPLS_BUS_PAR_ENf, }, 429 { "SW2_EOP_BUF_C", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_C_PARITY_ENf }, 430 { "SW2_EOP_BUF_A", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_A_PARITY_ENf }, 431 { "VP", VP_SER_CONTROLr, VP_BUS_PAR_ENf }, 432 { "IFP", IFP_PARITY_CONTROLr, IFP_BUS_PARITY_ENf }, 433 { "IL2L3", IL2L3_BUS_SER_CONTROLr, PARITY_ENf }, 434 { "", INVALIDr } /* end */ 435 }; 436 437 static _soc_buffer_ser_en_info_t _soc_monterey_ip_buffer_ser_info[] = { 438 { "COUNTER_STAGING", IFP_PARITY_CONTROLr, COUNTER_MUX_DATA_STAGING_PARITY_ENf }, 439 { "METER_STAGING", IFP_PARITY_CONTROLr, METER_MUX_DATA_STAGING_PARITY_ENf }, 440 { "CMIC", IARB_SER_CONTROLr, CMIC_BUF_ECC_ENf }, 441 { "IP STATS COUNTERS", ISW2_SER_CONTROL_1r, IP_COUNTERS_PARITY_ENf }, 442 { "RDISC/RUC/RPORTD/RDBGC0", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST0_PARITY_ENf }, 443 { "HG STATS COUNTERS", ISW2_SER_CONTROL_1r, HG_COUNTERS_PARITY_ENf }, 444 { "RDBGC5/RDBGC6/RDBGC7/RDBGC8", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST2_PARITY_ENf }, 445 { "RDBGC1/RDBGC2/RDBGC3/RDBGC4", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST1_PARITY_ENf }, 446 { "ING_NIV_RX_FRAMES_ERRe", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_ERROR_DROP_PARITY_ENf }, 447 { "ING_NIV_RX_FRAMES_FRWD", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_FORWARDING_DROP_PARITY_ENf }, 448 { "ING_NIV_RX_FRAMES_VLAN", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_VLAN_TAGGED_PARITY_ENf }, 449 { "DLB_HGT_FLOWSET_TIME", DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_ENf }, 450 { "DLB_HGT_FLOWSET", DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_PARITY_ENf }, 451 452 { "", INVALIDr } 453 }; 454 static _soc_buffer_ser_en_info_t _soc_monterey_ep_buffer_ser_info[] = { 455 { "INITBUF", EGR_EL3_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf }, 456 { "EGR MPB", EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf }, 457 { "EDB_CM_MEM", EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf }, 458 { "XLP5_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf }, 459 { "XLP4_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf }, 460 { "XLP3_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf }, 461 { "XLP2_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf }, 462 { "XLP1_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf }, 463 { "XLP0_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf }, 464 { "CLP9_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP9_ECC_ENf }, 465 { "CLP8_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP8_ECC_ENf }, 466 { "CLP7_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP7_ECC_ENf }, 467 { "CLP6_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP6_ECC_ENf }, 468 { "CLP5_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP5_ECC_ENf }, 469 { "CLP4_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP4_ECC_ENf }, 470 { "CLP3_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP3_ECC_ENf }, 471 { "CLP2_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP2_ECC_ENf }, 472 { "CLP1_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP1_ECC_ENf }, 473 { "CLP0_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP0_ECC_ENf }, 474 { "LPBK_BUF", EGR_EDATABUF_PARITY_CONTROLr, LBP_ECC_ENf }, 475 { "XLP5_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP5_ECC_ENf }, 476 { "XLP4_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP4_ECC_ENf }, 477 { "XLP3_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP3_ECC_ENf }, 478 { "XLP2_PREEMPT__CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP2_ECC_ENf }, 479 { "XLP1_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP1_ECC_ENf }, 480 { "XLP0_PREEMPT__CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP0_ECC_ENf }, 481 { "CLP9_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP9_ECC_ENf }, 482 { "CLP8_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP8_ECC_ENf }, 483 { "CLP7_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP7_ECC_ENf }, 484 { "CLP_6PREEMPT__CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP6_ECC_ENf }, 485 { "CLP5_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP5_ECC_ENf }, 486 { "CLP4_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP4_ECC_ENf }, 487 { "CLP3_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP3_ECC_ENf }, 488 { "CLP2_PREEMPT__CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP2_ECC_ENf }, 489 { "CLP1_PREEMPT_CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP1_ECC_ENf }, 490 { "CLP_0PREEMPT__CELL_BUF", EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP0_ECC_ENf }, 491 { "XLP5_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP5_ECC_ENf }, 492 { "XLP4_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP4_ECC_ENf }, 493 { "XLP3_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP3_ECC_ENf }, 494 { "XLP2_PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP2_ECC_ENf }, 495 { "XLP1_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP1_ECC_ENf }, 496 { "XLP0_PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP0_ECC_ENf }, 497 { "CLP9_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP9_ECC_ENf }, 498 { "CLP8_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP8_ECC_ENf }, 499 { "CLP7_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP7_ECC_ENf }, 500 { "CLP_6PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP6_ECC_ENf }, 501 { "CLP5_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP5_ECC_ENf }, 502 { "CLP4_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP4_ECC_ENf }, 503 { "CLP3_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP3_ECC_ENf }, 504 { "CLP2_PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP2_ECC_ENf }, 505 { "CLP1_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP1_ECC_ENf }, 506 { "CLP0_PREEMPT_CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP0_ECC_ENf }, 507 { "EP_XLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP5_ECC_ENf }, 508 { "EP_XLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP4_ECC_ENf }, 509 { "EP_XLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP3_ECC_ENf }, 510 { "EP_XLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP2_ECC_ENf }, 511 { "EP_XLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP1_ECC_ENf }, 512 { "EP_XLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP0_ECC_ENf }, 513 { "EP_CLP9__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP9_ECC_ENf }, 514 { "EP_CLP8__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP8_ECC_ENf }, 515 { "EP_CLP7__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP7_ECC_ENf }, 516 { "EP_CLP6__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP6_ECC_ENf }, 517 { "EP_CLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP5_ECC_ENf }, 518 { "EP_CLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP4_ECC_ENf }, 519 { "EP_CLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP3_ECC_ENf }, 520 { "EP_CLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP2_ECC_ENf }, 521 { "EP_CLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP1_ECC_ENf }, 522 { "EP_CLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP0_ECC_ENf }, 523 { "EP_XLP5__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP5_ECC_ENf }, 524 { "EP_XLP4__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP4_ECC_ENf }, 525 { "EP_XLP3__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP3_ECC_ENf }, 526 { "EP_XLP2__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP2_ECC_ENf }, 527 { "EP_XLP1__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP1_ECC_ENf }, 528 { "EP_XLP0__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP0_ECC_ENf }, 529 { "EP_CLP9__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP9_ECC_ENf }, 530 { "EP_CLP8__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP8_ECC_ENf }, 531 { "EP_CLP7__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP7_ECC_ENf }, 532 { "EP_CLP6__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP6_ECC_ENf }, 533 { "EP_CLP5__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP5_ECC_ENf }, 534 { "EP_CLP4__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP4_ECC_ENf }, 535 { "EP_CLP3__PKT-LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP3_ECC_ENf }, 536 { "EP_CLP2__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP2_ECC_ENf }, 537 { "EP_CLP1__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP1_ECC_ENf }, 538 { "EP_CLP0__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP0_ECC_ENf }, 539 540 541 { "", INVALIDr } 542 }; 543 544 545 546 static _soc_bus_ser_en_info_t _soc_ep_bus_ser_info [] = { 547 { "EFP", EFP_PARITY_CONTROLr, EFP_BUS_PARITY_ENf }, 548 { "EFPPARS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_BUS_PARITY_ENf }, 549 { "EHCPM", EGR_EHCPM_SER_CONTROLr, EHCPM_BUS_PARITY_ENf }, 550 { "EPMOD", EGR_EPMOD_SER_CONTROLr, EPMOD_BUS_PARITY_ENf }, 551 { "EVLAN", EGR_VLAN_SER_CONTROLr, EVLAN_BUS_PARITY_ENf }, 552 { "", INVALIDr } /* end */ 553 }; 554 555 556 557 static const _soc_monterey_ser_block_info_t _soc_monterey_ser_block_info[] = { 558 { _SOC_MONTEREY_SER_TYPE_REG, SOC_BLK_IPIPE, "IPIPE regs", INVALIDr, _soc_bcm56670_a0_ip_reg_ser_info }, 559 { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_IPIPE, "IPIPE mems", ING_SER_FIFO_CTRLr, _soc_bcm56670_a0_ip_mem_ser_info }, 560 { _SOC_MONTEREY_SER_TYPE_BUS, SOC_BLK_IPIPE, "IPIPE buses",INVALIDr, _soc_monterey_ip_bus_ser_info }, 561 { _SOC_MONTEREY_SER_TYPE_BUF, SOC_BLK_IPIPE, "IPIPE buff" ,INVALIDr, _soc_monterey_ip_buffer_ser_info }, 562 { _SOC_MONTEREY_SER_TYPE_REG, SOC_BLK_EPIPE, "EPIPE regs", INVALIDr, _soc_bcm56670_a0_ep_reg_ser_info }, 563 { _SOC_MONTEREY_SER_TYPE_BUS, SOC_BLK_EPIPE, "EPIPE buses",INVALIDr, _soc_ep_bus_ser_info }, 564 { _SOC_MONTEREY_SER_TYPE_BUF, SOC_BLK_EPIPE, "EPIPE buff" ,INVALIDr, _soc_monterey_ep_buffer_ser_info }, 565 { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_EPIPE, "EPIPE mems", EGR_SER_FIFO_CTRLr, _soc_bcm56670_a0_ep_mem_ser_info }, 566 { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_MMU, "MMU mems", INVALIDr, _soc_bcm56670_a0_mmu_mem_ser_info }, 567 { _SOC_MONTEREY_SER_TYPE_BUF, SOC_BLK_MMU, "MMU buff", INVALIDr, _soc_mmu_buffer_ser_info }, 568 #if defined(BCM_56670_B0) && defined(INCLUDE_XFLOW_MACSEC) 569 { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_MACSEC,"MACSEC mems", INVALIDr, _soc_bcm56670_b0_macsec_mem_ser_info }, 570 #endif 571 { -1, 0 } 572 }; 573 574 575 STATIC _soc_monterey_ser_info_t _soc_monterey_mmu_ser_info[] = { 576 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 577 DEQ_NOT_IP_ERR_ENf, 578 DEQ_NOT_IP_ERRf, 579 INVALIDm, "MMU DEQ NOT IP", 580 INVALIDr, INVALIDf, 581 INVALIDr, NULL, 582 INVALIDr, INVALIDf, NULL }, 583 { _SOC_PARITY_TYPE_START_ERR, NULL, 0, 584 START_BY_START_ERR_ENf, 585 START_BY_START_ERRf, 586 INVALIDm, "MMU START BY START", 587 INVALIDr, INVALIDf, 588 INVALIDr, NULL, 589 INVALIDr, INVALIDf, NULL }, 590 { _SOC_PARITY_TYPE_MMU_SER, NULL, 0, 591 MEM_PAR_ERR_ENf, 592 MEM_PAR_ERRf, 593 INVALIDm, "MMU MEM PAR", 594 INVALIDr, INVALIDf, 595 MEM_FAIL_INT_STATr, NULL, 596 INVALIDr, INVALIDf, NULL }, 597 { _SOC_PARITY_TYPE_BST, NULL, 0, 598 INVALIDf, 599 BST_THDI_INTf, 600 INVALIDm, NULL, 601 INVALIDr, INVALIDf, 602 INVALIDr, NULL, 603 INVALIDr, INVALIDf, NULL }, 604 { _SOC_PARITY_TYPE_BST, NULL, 0, 605 INVALIDf, 606 BST_THDO_INTf, 607 INVALIDm, NULL, 608 INVALIDr, INVALIDf, 609 INVALIDr, NULL, 610 INVALIDr, INVALIDf, NULL }, 611 { _SOC_PARITY_TYPE_BST, NULL, 0, 612 INVALIDf, 613 BST_CFAP_INTf, 614 INVALIDm, NULL, 615 INVALIDr, INVALIDf, 616 INVALIDr, NULL, 617 INVALIDr, INVALIDf, NULL }, 618 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 619 }; 620 621 STATIC _soc_monterey_ser_reg_t _soc_monterey_pg_bod_status_reg[] = { 622 { PGW_BOD_CA0_ECC_STATUSr, "PGW BOD CA0 ECC" }, 623 { PGW_BOD_CA1_ECC_STATUSr, "PGW BOD CA1 ECC" }, 624 { PGW_BOD_CA2_ECC_STATUSr, "PGW BOD CA2 ECC" }, 625 { PGW_BOD_CA3_ECC_STATUSr, "PGW BOD CA3 ECC" }, 626 { PGW_BOD_CA4_ECC_STATUSr, "PGW BOD CA4 ECC" }, 627 { PGW_BOD_CA5_ECC_STATUSr, "PGW BOD CA5 ECC" }, 628 { PGW_BOD_CA6_ECC_STATUSr, "PGW BOD CA6 ECC" }, 629 { PGW_BOD_CA7_ECC_STATUSr, "PGW BOD CA7 ECC" }, 630 { INVALIDr } 631 }; 632 STATIC _soc_monterey_ser_info_t _soc_monterey_pg_ser_info[] = { 633 { _SOC_PARITY_TYPE_ECC, NULL, 0, 634 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 635 PGW_OBM_DATA_MEM_ECC_ERRf, 636 INVALIDm, "PGW OBM0", 637 IDB_OBM0_SER_CONTROLr, DATA_ECC_ENABLEf, 638 IDB_OBM0_DATA_ECC_STATUSr, NULL, 639 INVALIDr, INVALIDf, NULL }, 640 { _SOC_PARITY_TYPE_ECC, NULL, 0, 641 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 642 PGW_OBM_DATA_MEM_ECC_ERRf, 643 INVALIDm, "PGW OBM1", 644 IDB_OBM1_SER_CONTROLr, DATA_ECC_ENABLEf, 645 IDB_OBM1_DATA_ECC_STATUSr, NULL, 646 INVALIDr, INVALIDf, NULL }, 647 { _SOC_PARITY_TYPE_ECC, NULL, 0, 648 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 649 PGW_OBM_DATA_MEM_ECC_ERRf, 650 INVALIDm, "PGW OBM2", 651 IDB_OBM2_SER_CONTROLr, DATA_ECC_ENABLEf, 652 IDB_OBM2_DATA_ECC_STATUSr, NULL, 653 INVALIDr, INVALIDf, NULL }, 654 { _SOC_PARITY_TYPE_ECC, NULL, 0, 655 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 656 PGW_OBM_DATA_MEM_ECC_ERRf, 657 INVALIDm, "PGW OBM3", 658 IDB_OBM3_SER_CONTROLr, DATA_ECC_ENABLEf, 659 IDB_OBM3_DATA_ECC_STATUSr, NULL, 660 INVALIDr, INVALIDf, NULL }, 661 { _SOC_PARITY_TYPE_ECC, NULL, 0, 662 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 663 PGW_OBM_DATA_MEM_ECC_ERRf, 664 INVALIDm, "PGW OBM4", 665 IDB_OBM4_SER_CONTROLr, DATA_ECC_ENABLEf, 666 IDB_OBM4_DATA_ECC_STATUSr, NULL, 667 INVALIDr, INVALIDf, NULL }, 668 { _SOC_PARITY_TYPE_ECC, NULL, 0, 669 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 670 PGW_OBM_DATA_MEM_ECC_ERRf, 671 INVALIDm, "PGW OBM5", 672 IDB_OBM5_SER_CONTROLr, DATA_ECC_ENABLEf, 673 IDB_OBM5_DATA_ECC_STATUSr, NULL, 674 INVALIDr, INVALIDf, NULL }, 675 { _SOC_PARITY_TYPE_ECC, NULL, 0, 676 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 677 PGW_OBM_DATA_MEM_ECC_ERRf, 678 INVALIDm, "PGW OBM6", 679 IDB_OBM6_SER_CONTROLr, DATA_ECC_ENABLEf, 680 IDB_OBM6_DATA_ECC_STATUSr, NULL, 681 INVALIDr, INVALIDf, NULL }, 682 { _SOC_PARITY_TYPE_ECC, NULL, 0, 683 PGW_OBM_DATA_MEM_ECC_ERR_ENf, 684 PGW_OBM_DATA_MEM_ECC_ERRf, 685 INVALIDm, "PGW OBM7", 686 IDB_OBM7_SER_CONTROLr, DATA_ECC_ENABLEf, 687 IDB_OBM7_DATA_ECC_STATUSr, NULL, 688 INVALIDr, INVALIDf, NULL }, 689 { _SOC_PARITY_TYPE_ECC, NULL, 0, 690 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 691 PGW_OBM_QUEUE_MEM_ECC_ERRf, 692 INVALIDm, "PGW OBM0", 693 IDB_OBM0_QUEUE_SER_CONTROLr, ECC_ENABLEf, 694 IDB_OBM0_QUEUE_ECC_STATUSr, NULL, 695 INVALIDr, INVALIDf, NULL }, 696 { _SOC_PARITY_TYPE_ECC, NULL, 0, 697 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 698 PGW_OBM_QUEUE_MEM_ECC_ERRf, 699 INVALIDm, "PGW OBM1", 700 IDB_OBM1_QUEUE_SER_CONTROLr, ECC_ENABLEf, 701 IDB_OBM1_QUEUE_ECC_STATUSr, NULL, 702 INVALIDr, INVALIDf, NULL }, 703 { _SOC_PARITY_TYPE_ECC, NULL, 0, 704 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 705 PGW_OBM_QUEUE_MEM_ECC_ERRf, 706 INVALIDm, "PGW OBM2", 707 IDB_OBM2_QUEUE_SER_CONTROLr, ECC_ENABLEf, 708 IDB_OBM2_QUEUE_ECC_STATUSr, NULL, 709 INVALIDr, INVALIDf, NULL }, 710 { _SOC_PARITY_TYPE_ECC, NULL, 0, 711 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 712 PGW_OBM_QUEUE_MEM_ECC_ERRf, 713 INVALIDm, "PGW OBM3", 714 IDB_OBM3_QUEUE_SER_CONTROLr, ECC_ENABLEf, 715 IDB_OBM3_QUEUE_ECC_STATUSr, NULL, 716 INVALIDr, INVALIDf, NULL }, 717 { _SOC_PARITY_TYPE_ECC, NULL, 0, 718 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 719 PGW_OBM_QUEUE_MEM_ECC_ERRf, 720 INVALIDm, "PGW OBM4", 721 IDB_OBM4_QUEUE_SER_CONTROLr, ECC_ENABLEf, 722 IDB_OBM4_QUEUE_ECC_STATUSr, NULL, 723 INVALIDr, INVALIDf, NULL }, 724 { _SOC_PARITY_TYPE_ECC, NULL, 0, 725 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 726 PGW_OBM_QUEUE_MEM_ECC_ERRf, 727 INVALIDm, "PGW OBM5", 728 IDB_OBM5_QUEUE_SER_CONTROLr, ECC_ENABLEf, 729 IDB_OBM5_QUEUE_ECC_STATUSr, NULL, 730 INVALIDr, INVALIDf, NULL }, 731 { _SOC_PARITY_TYPE_ECC, NULL, 0, 732 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 733 PGW_OBM_QUEUE_MEM_ECC_ERRf, 734 INVALIDm, "PGW OBM6", 735 IDB_OBM6_QUEUE_SER_CONTROLr, ECC_ENABLEf, 736 IDB_OBM6_QUEUE_ECC_STATUSr, NULL, 737 INVALIDr, INVALIDf, NULL }, 738 { _SOC_PARITY_TYPE_ECC, NULL, 0, 739 PGW_OBM_QUEUE_MEM_ECC_ERR_ENf , 740 PGW_OBM_QUEUE_MEM_ECC_ERRf, 741 INVALIDm, "PGW OBM7", 742 IDB_OBM7_QUEUE_SER_CONTROLr, ECC_ENABLEf, 743 IDB_OBM7_QUEUE_ECC_STATUSr, NULL, 744 INVALIDr, INVALIDf, NULL }, 745 746 { _SOC_PARITY_TYPE_ECC, NULL, 0, 747 PGW_CA_DATA_MEM_ECC_ERR_ENf, 748 PGW_CA_DATA_MEM_ECC_ERRf, 749 INVALIDm, "PGW BOD", 750 PGW_BOD_ECC_ENABLEr, BOD_ECC_ENABLEf, 751 INVALIDr, _soc_monterey_pg_bod_status_reg, 752 INVALIDr, INVALIDf, NULL }, 753 { _SOC_PARITY_TYPE_OBM, NULL, 0, 754 PGW_OBM_DROPS_OR_CA_OVERFLOW_ERR_ENf, 755 PGW_OBM_DROPS_OR_CA_OVERFLOW_ERRf, 756 INVALIDm, "PGW OBM", 757 INVALIDr, INVALIDr, 758 INVALIDr, NULL, 759 INVALIDr, INVALIDf, NULL }, 760 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 761 }; 762 763 764 #ifdef INCLUDE_XFLOW_MACSEC 765 STATIC _soc_monterey_ser_info_t _soc_monterey_macsec_ser_info[] = { 766 { _SOC_PARITY_TYPE_MACSEC_SER, NULL, 0, 767 ECCERR_INT_ENf, 768 INVALIDf, 769 INVALIDm, NULL, 770 INVALIDr, INVALIDf, 771 INVALIDr, NULL, 772 INVALIDr, INVALIDf, NULL }, 773 { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0, 774 EGRESS_SA_SOFT_EXPIRE_INT_ENf, 775 INVALIDf, 776 INVALIDm, NULL, 777 INVALIDr, INVALIDf, 778 INVALIDr, NULL, 779 INVALIDr, INVALIDf, NULL }, 780 { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0, 781 EGRESS_SA_EXPIRE_INT_ENf, 782 INVALIDf, 783 INVALIDm, NULL, 784 INVALIDr, INVALIDf, 785 INVALIDr, NULL, 786 INVALIDr, INVALIDf, NULL }, 787 { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0, 788 INGRESS_SA_SOFT_EXPIRE_INT_ENf, 789 INVALIDf, 790 INVALIDm, NULL, 791 INVALIDr, INVALIDf, 792 INVALIDr, NULL, 793 INVALIDr, INVALIDf, NULL }, 794 { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0, 795 INGRESS_SA_EXPIRE_INT_ENf, 796 INVALIDf, 797 INVALIDm, NULL, 798 INVALIDr, INVALIDf, 799 INVALIDr, NULL, 800 INVALIDr, INVALIDf, NULL }, 801 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 802 }; 803 #endif 804 static const 805 _soc_monterey_ser_route_block_t _soc_monterey_ser_route_blocks_irq3[] = { 806 { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */ 807 SOC_BLK_MMU, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, INVALIDf, 808 _soc_monterey_mmu_ser_info, 0 }, 809 { 0x00000002, /* EP1_TO_CMIC_PERR_INTR */ 810 SOC_BLK_EPIPE, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf, NULL, 0 }, 811 { 0x00000004, /* EP2_TO_CMIC_PERR_INTR */ 812 SOC_BLK_EPIPE, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf, NULL, 0 }, 813 { 0x00000008, /* IP0_TO_CMIC_PERR_INTR */ 814 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 815 { 0x00000010, /* IP1_TO_CMIC_PERR_INTR */ 816 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 817 { 0x00000020, /* IP2_TO_CMIC_PERR_INTR */ 818 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 819 { 0x00000040, /* IP3_TO_CMIC_PERR_INTR */ 820 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 821 { 0x00000080, /* IP4_TO_CMIC_PERR_INTR */ 822 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 823 { 0x00000100, /* IP5_TO_CMIC_PERR_INTR */ 824 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 825 { 0x00000200, /* PGW_0_TO_CMIC_PERR_INTR */ 826 SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf, 827 _soc_monterey_pg_ser_info, 0 }, 828 { 0x00000400, /* PGW_1_TO_CMIC_PERR_INTR */ 829 SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf, 830 _soc_monterey_pg_ser_info, 1 }, 831 /* bits 11 12 13 and 14 do not look SER related. Leaving them alone */ 832 { 0 } /* table terminator */ 833 }; 834 /* 835 static soc_field_t _soc_monterey_pm_rx_cdc_clear_field[] = { 836 CLEAR_RX_CDC_SINGLE_BIT_ERRf, CLEAR_RX_CDC_DOUBLE_BIT_ERRf 837 }; 838 static soc_field_t _soc_monterey_pm_tx_cdc_clear_field[] = { 839 CLEAR_TX_CDC_SINGLE_BIT_ERRf, CLEAR_TX_CDC_DOUBLE_BIT_ERRf 840 }; 841 842 843 static soc_field_t _soc_monterey_pm_rx_ts_clear_field[] = { 844 CLEAR_RX_TS_MEM_SINGLE_BIT_ERRf, CLEAR_RX_TS_MEM_DOUBLE_BIT_ERRf 845 }; 846 */ 847 static _soc_monterey_ser_reg_t _soc_monterey_pm_xlp_rx_status_reg[] = { 848 { XLPORT_MIB_RSC0_ECC_STATUSr, "XLP MIB RSC0 ECC" }, 849 { XLPORT_MIB_RSC1_ECC_STATUSr, "XLP MIB RSC1 ECC"}, 850 { INVALIDr } 851 852 }; 853 static _soc_monterey_ser_reg_t _soc_monterey_pm_xlp_tx_status_reg[] = { 854 { XLPORT_MIB_TSC0_ECC_STATUSr, "XLP MIB TSC0 ECC" }, 855 { XLPORT_MIB_TSC1_ECC_STATUSr, "XLP MIB TSC1 ECC" }, 856 { INVALIDr } 857 }; 858 859 static _soc_monterey_ser_info_t _soc_monterey_xlport_ser_info[] = { 860 /* In addition to below we have TSC_ERROR, RX_FLOWCONTROL_REQ_FULL 861 * interrupts in XLPORT. Currently not being handled. 862 */ 863 { _SOC_PARITY_TYPE_MIB, NULL, 0, 864 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 865 INVALIDm, "MIB RX Statistic Counter memory", 866 XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, 867 INVALIDr, _soc_monterey_pm_xlp_rx_status_reg, 868 XLPORT_MIB_RESETr, INVALIDf, NULL 869 }, 870 { _SOC_PARITY_TYPE_MIB, NULL, 0, 871 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 872 INVALIDm, "MIB TX Statistic Counter memory", 873 XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, 874 INVALIDr, _soc_monterey_pm_xlp_tx_status_reg, 875 XLPORT_MIB_RESETr, INVALIDf, NULL 876 }, 877 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 878 }; 879 880 static _soc_monterey_ser_reg_t _soc_monterey_pm_clp_rx_status_reg[] = { 881 { CLPORT_MIB_RSC0_ECC_STATUSr, "CLP MIB RSC0 ECC" }, 882 { CLPORT_MIB_RSC1_ECC_STATUSr, "CLP MIB RSC1 ECC" } 883 }; 884 885 static _soc_monterey_ser_reg_t _soc_monterey_pm_clp_tx_status_reg[] = { 886 { CLPORT_MIB_TSC0_ECC_STATUSr, "CLP MIB TSC0 ECC" }, 887 { CLPORT_MIB_TSC1_ECC_STATUSr, "CLP MIB TSC1 ECC" } 888 }; 889 static _soc_monterey_ser_info_t _soc_monterey_clport_ser_info[] = { 890 /* In addition to below we have TSC_ERROR, PMD_ERR, RX_FLOWCONTROL_REQ_FULL 891 * interrupts in CLPORT. Currently not being handled 892 */ 893 { _SOC_PARITY_TYPE_MIB, NULL, 0, 894 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 895 INVALIDm, "MIB RX Statistic Counter memory", 896 CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, 897 INVALIDr, _soc_monterey_pm_clp_rx_status_reg, 898 CLPORT_MIB_RESETr, INVALIDf, NULL 899 }, 900 { _SOC_PARITY_TYPE_MIB, NULL, 0, 901 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 902 INVALIDm, "MIB TX Statistic Counter memory", 903 CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, 904 INVALIDr, _soc_monterey_pm_clp_tx_status_reg, 905 CLPORT_MIB_RESETr, INVALIDf, NULL 906 }, 907 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 908 }; 909 910 911 static const 912 _soc_monterey_ser_route_block_t _soc_monterey_ser_route_blocks_irq4[] = { 913 {0x00000001, /* Port Macro0 (PM0) interrupt */ 914 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 915 _soc_monterey_clport_ser_info, 0}, 916 {0x00000002, /* Port Macro1 (PM1) interrupt */ 917 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 918 _soc_monterey_clport_ser_info, 1}, 919 {0x00000004, /* Port Macro2 (PM2) interrupt */ 920 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 921 _soc_monterey_clport_ser_info, 2}, 922 {0x00000008, /* Port Macro3 (PM3) interrupt */ 923 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 924 _soc_monterey_clport_ser_info, 3}, 925 {0x00000010, /* Port Macro4 (PM4) interrupt */ 926 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 927 _soc_monterey_clport_ser_info, 0}, 928 {0x00000020, /* Port Macro5 (PM5) interrupt */ 929 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 930 _soc_monterey_xlport_ser_info, 1}, 931 {0x00000040, /* Port Macro6 (PM6) interrupt */ 932 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 933 _soc_monterey_xlport_ser_info, 2}, 934 {0x00000080, /* Port Macro7 (PM7) interrupt */ 935 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 936 _soc_monterey_xlport_ser_info, 7}, 937 {0x00000100, /* Port Macro8 (PM8) interrupt */ 938 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 939 _soc_monterey_xlport_ser_info, 8}, 940 {0x00000200, /* Port Macro9 (PM9) interrupt */ 941 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 942 _soc_monterey_xlport_ser_info, 9}, 943 {0x00000400, /* Port Macro10 (PM10) interrupt */ 944 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 945 _soc_monterey_xlport_ser_info, 10}, 946 {0x00000800, /* Port Macro11 (PM11) interrupt */ 947 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 948 _soc_monterey_clport_ser_info, 1}, 949 {0x00001000, /* Port Macro12 (PM12) interrupt */ 950 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 951 _soc_monterey_clport_ser_info, 4}, 952 {0x00002000, /* Port Macro13 (PM13) interrupt */ 953 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 954 _soc_monterey_clport_ser_info, 5}, 955 /* Bits 14-31 are reserved */ 956 {0} /* table terminator */ 957 }; 958 959 #ifdef INCLUDE_XFLOW_MACSEC 960 static const 961 _soc_monterey_ser_route_block_t _soc_monterey_macsec_ser_route_blocks_irq4[] = { 962 { 0x400000, /* MACSEC_INTR */ 963 SOC_BLK_MACSEC, SP_GLB_INTR_ENr, SP_GLB_INTR_STATUSr, INVALIDf, 964 _soc_monterey_macsec_ser_info, 0 }, 965 {0} /* table terminator */ 966 }; 967 #endif 968 969 _soc_monterey_pm_cpri_intr_info_t 970 _soc_monterey_pm_cpri_intr_info_irq4[] = { 971 {0x00010000, /* Port Macro0 (PM0) CPRI interrupt */ 972 SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf, 973 NULL, 0}, 974 {0x00020000, /* Port Macro1 (PM1) CPRI interrupt */ 975 SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf, 976 NULL, 1}, 977 {0x00040000, /* Port Macro2 (PM2) CPRI interrupt */ 978 SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf, 979 NULL, 2}, 980 {0x00080000, /* Port Macro13 (PM13) CPRI interrupt */ 981 SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf, 982 NULL, 3}, 983 {0x00100000, /* Port Macro14 (PM14) CPRI interrupt */ 984 SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf, 985 NULL, 4}, 986 {0x00200000, /* Port Macro15 (PM15) interrupt */ 987 SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf, 988 NULL, 5}, 989 /* _soc_monterey_intr_info, 0}, */ 990 {0} /* table terminator */ 991 }; 992 993 static soc_ser_functions_t _monterey_ser_functions; 994 static soc_pm_intr_functions_t _monterey_pm_intr_functions; 995 996 extern uint8 _soc_alpm_mode[SOC_MAX_NUM_DEVICES]; 997 998 static uint32 _monterey_ser_delay = 0; 999 1000 /* Values map to HW encodings */ 1001 enum soc_mn_port_ca_mode_e { 1002 SOC_MN_PORT_CA_MODE_SINGLE = 0, 1003 SOC_MN_PORT_CA_MODE_DUAL = 1, 1004 SOC_MN_PORT_CA_MODE_QUAD = 2, 1005 SOC_MN_PORT_CA_MODE_TRI_211 = 3, 1006 SOC_MN_PORT_CA_MODE_TRI_112 = 4, 1007 SOC_MN_PORT_CA_MODE_TRI_411 = 5, 1008 SOC_MN_PORT_CA_MODE_TRI_114 = 6, 1009 SOC_MN_PORT_CA_MODE_COUNT /* unused */ 1010 }; 1011 int IS_ROE_ENABLED(int unit) { 1012 uint16 dev_id; 1013 uint8 rev_id; 1014 1015 soc_cm_get_id(unit, &dev_id, &rev_id); 1016 if (dev_id == BCM56675_DEVICE_ID) { 1017 return FALSE; 1018 } else { 1019 return TRUE; 1020 } 1021 } 1022 STATIC int 1023 _soc_monterey_thdo_hw_set(int unit, soc_port_t port, int enable); 1024 /* 1025 * SINGLE => {VALUE => 0, DESC => "Port 0 valid. 10G/20G/25G/40G/50G/100G."}, 1026 * DUAL => {VALUE => 1, DESC => "Port 0 and 2 valid. 10G/20G/25G/40G/50G."}, 1027 * QUAD => {VALUE => 2, DESC => "Port 0, 1, 2, and 3 valid. 10G/20G/25G."}, 1028 * TRI211 => {VALUE => 3, DESC => "Port 0 is 20G, port 2 10G, and port 3 10G."}, 1029 * TRI112 => {VALUE => 4, DESC => "Port 0 is 10G, port 1 10G, and port 2 20G."}, 1030 * TRI411 => {VALUE => 5, DESC => "Port 0 is 40G, port 2 10G, and port 3 10G."}, 1031 * TRI114 => {VALUE => 6, DESC => "Port 0 is 10G, port 1 10G, and port 2 40G."}, 1032 */ 1033 STATIC int 1034 soc_monterey_port_ca_mode_get(int unit, int flexport, int xlp, int *mode) 1035 { 1036 soc_info_t *si; 1037 int port, phy_port_base, lane; 1038 int num_lanes[MONTEREY_PORTS_PER_TSC]; 1039 int speed_max[MONTEREY_PORTS_PER_TSC]; 1040 1041 si = &SOC_INFO(unit); 1042 *mode = SOC_MN_PORT_CA_MODE_QUAD; 1043 1044 phy_port_base = 1 + (xlp * MONTEREY_PORTS_PER_TSC); 1045 for (lane = 0; lane < MONTEREY_PORTS_PER_TSC; lane++) { 1046 port = si->port_p2l_mapping[phy_port_base + lane]; 1047 if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 1048 num_lanes[lane] = -1; 1049 speed_max[lane] = -1; 1050 } else { 1051 num_lanes[lane] = si->port_num_lanes[port]; 1052 speed_max[lane] = si->port_speed_max[port]; 1053 } 1054 } 1055 1056 if (num_lanes[0] >= 4) { 1057 *mode = SOC_MN_PORT_CA_MODE_SINGLE; 1058 } else if ((num_lanes[0] == 2) && (num_lanes[2] == 2)) { 1059 *mode = SOC_MN_PORT_CA_MODE_DUAL; 1060 } else if ((num_lanes[0] == 1) && (num_lanes[1] == 1) && 1061 (num_lanes[2] == 1) && (num_lanes[3] == 1)) { 1062 *mode = SOC_MN_PORT_CA_MODE_QUAD; 1063 } else if (num_lanes[0] == 2) { 1064 *mode = (speed_max[0] >= 40000) ? 1065 SOC_MN_PORT_CA_MODE_TRI_411 : SOC_MN_PORT_CA_MODE_TRI_211; 1066 } else if (num_lanes[2] == 2) { 1067 *mode = (speed_max[2] >= 40000) ? 1068 SOC_MN_PORT_CA_MODE_TRI_114 : SOC_MN_PORT_CA_MODE_TRI_112; 1069 } 1070 return SOC_E_NONE; 1071 } 1072 1073 1074 int 1075 _soc_monterey_idb_port_init(int unit, int reset, int lossless, soc_port_t port) 1076 { 1077 soc_info_t *si; 1078 soc_mem_t mem; 1079 soc_reg_t reg; 1080 int obm, pgw, pgw_inst, index; 1081 int port_osub, phy_port, subport; 1082 uint32 rval32 ; 1083 uint64 rval64; 1084 idb_obm0_pri_map_port0_entry_t entry; 1085 1086 uint32 discard_limit = 0, express_discard = 0, lossy_discard = 0, lossy_low_pri = 0; 1087 uint32 port_xon = 0, port_xoff = 0, lossless0_xon = 0 ,lossless0_xoff = 0; 1088 1089 static const soc_reg_t obm_ctrl_regs[] = { 1090 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 1091 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 1092 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 1093 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr 1094 }; 1095 static const soc_reg_t obm_thresh0_regs[] = { 1096 IDB_OBM0_THRESHOLD_0r, IDB_OBM1_THRESHOLD_0r, 1097 IDB_OBM2_THRESHOLD_0r, IDB_OBM3_THRESHOLD_0r, 1098 IDB_OBM4_THRESHOLD_0r, IDB_OBM5_THRESHOLD_0r, 1099 IDB_OBM6_THRESHOLD_0r, IDB_OBM7_THRESHOLD_0r 1100 }; 1101 static const soc_reg_t obm_thresh1_regs[] = { 1102 IDB_OBM0_THRESHOLD_1r, IDB_OBM1_THRESHOLD_1r, 1103 IDB_OBM2_THRESHOLD_1r, IDB_OBM3_THRESHOLD_1r, 1104 IDB_OBM4_THRESHOLD_1r, IDB_OBM5_THRESHOLD_1r, 1105 IDB_OBM6_THRESHOLD_1r, IDB_OBM7_THRESHOLD_1r 1106 }; 1107 static const soc_reg_t obm_fc_thresh0_regs[] = { 1108 IDB_OBM0_FC_THRESHOLD_0r, IDB_OBM1_FC_THRESHOLD_0r, 1109 IDB_OBM2_FC_THRESHOLD_0r, IDB_OBM3_FC_THRESHOLD_0r, 1110 IDB_OBM4_FC_THRESHOLD_0r, IDB_OBM5_FC_THRESHOLD_0r, 1111 IDB_OBM6_FC_THRESHOLD_0r, IDB_OBM7_FC_THRESHOLD_0r 1112 }; 1113 static const soc_reg_t obm_fc_thresh1_regs[] = { 1114 IDB_OBM0_FC_THRESHOLD_1r, IDB_OBM1_FC_THRESHOLD_1r, 1115 IDB_OBM2_FC_THRESHOLD_1r, IDB_OBM3_FC_THRESHOLD_1r, 1116 IDB_OBM4_FC_THRESHOLD_1r, IDB_OBM5_FC_THRESHOLD_1r, 1117 IDB_OBM6_FC_THRESHOLD_1r, IDB_OBM7_FC_THRESHOLD_1r 1118 }; 1119 static const soc_reg_t obm_shared_regs[] = { 1120 IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr, 1121 IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr, 1122 IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr, 1123 IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr 1124 }; 1125 static const soc_reg_t obm_max_usage_regs[] = { 1126 IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr, 1127 IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr, 1128 IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr, 1129 IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr 1130 }; 1131 1132 static const soc_reg_t obm_port_config_regs[] = { 1133 IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr, 1134 IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr, 1135 IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr, 1136 IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr 1137 }; 1138 static const soc_reg_t obm_fc_config_regs[] = { 1139 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 1140 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 1141 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 1142 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr 1143 }; 1144 1145 static const soc_reg_t obm_bank_config_regs[] = { 1146 IDB_OBM0_BANK_CONFIGr, IDB_OBM1_BANK_CONFIGr, 1147 IDB_OBM2_BANK_CONFIGr, IDB_OBM3_BANK_CONFIGr, 1148 IDB_OBM4_BANK_CONFIGr, IDB_OBM5_BANK_CONFIGr, 1149 IDB_OBM6_BANK_CONFIGr, IDB_OBM7_BANK_CONFIGr 1150 }; 1151 1152 static const soc_field_t obm_oversub_fields[] = { 1153 PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf, 1154 PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf 1155 }; 1156 1157 static const soc_mem_t obm_pri_map_port_mem[] = { 1158 IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m, 1159 IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m, 1160 IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m, 1161 IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m, 1162 IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m, 1163 IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m, 1164 IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m, 1165 IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m, 1166 IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m, 1167 IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m, 1168 IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m, 1169 IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m, 1170 IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m, 1171 IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m, 1172 IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m, 1173 IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m, 1174 IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m, 1175 IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m, 1176 }; 1177 1178 1179 static const soc_field_t offset_ob_prio[] = { 1180 OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf, 1181 OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf, 1182 OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf, 1183 OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf, 1184 OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf, 1185 OFFSET15_OB_PRIORITYf, 1186 }; 1187 static const soc_reg_t obm_ct_thresh_regs[] = { 1188 IDB_OBM0_CT_THRESHOLDr, IDB_OBM1_CT_THRESHOLDr, 1189 IDB_OBM2_CT_THRESHOLDr, IDB_OBM3_CT_THRESHOLDr, 1190 IDB_OBM4_CT_THRESHOLDr, IDB_OBM5_CT_THRESHOLDr, 1191 IDB_OBM6_CT_THRESHOLDr, IDB_OBM7_CT_THRESHOLDr, 1192 IDB_OBM8_CT_THRESHOLDr, 1193 }; 1194 1195 soc_pbmp_t pbmp_xport_roe_backplane; 1196 soc_pbmp_t pbmp_xport_roe_bbu; 1197 soc_pbmp_t pbmp_xport_roe_mcu; 1198 soc_pbmp_t pbmp_xport_roe_fronthaul; 1199 1200 1201 SOC_PBMP_CLEAR(pbmp_xport_roe_backplane); 1202 SOC_PBMP_CLEAR(pbmp_xport_roe_bbu); 1203 SOC_PBMP_CLEAR(pbmp_xport_roe_mcu); 1204 SOC_PBMP_CLEAR(pbmp_xport_roe_fronthaul); 1205 si = &SOC_INFO(unit); 1206 1207 /* Calculation of obm and lanes(subport) 1208 obm is 0 for phy_port 1 to 4 1209 1 for phy port 5 to 8 and so on till 8 for phy_port 33 to 36 1210 Similarly obm 0 for phy_port 37 to 40 and so on 1211 lane(subport) is 0,1,2,3 for phy_port 1,2,3,4 resp 1212 lane(subport) is 0,1,2,3 for phy_port 5,6,7,8 resp and so on 1213 Block index is PGW0 for ports 1 to 36 1214 Block index is PGW1 for ports 37 to 72 1215 */ 1216 phy_port = si->port_l2p_mapping[port]; 1217 1218 /* Deleting a port */ 1219 if (phy_port == -1) { 1220 return SOC_E_PARAM; 1221 } 1222 1223 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port)) { 1224 /* nothing to do for non-idb ports */ 1225 return SOC_E_NONE; 1226 } 1227 1228 /* OBM group (num groups = num tsc's) belongs to PGW0/PGW1 */ 1229 obm = si->port_serdes[port]; 1230 obm %= MONTEREY_TSCS_PER_PGW; 1231 1232 pgw = si->port_group[port]; 1233 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 1234 subport = (phy_port - 1) % MONTEREY_PORTS_PER_TSC; 1235 pbmp_xport_roe_backplane = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_BACKPLANE, 1236 pbmp_xport_roe_backplane); 1237 pbmp_xport_roe_bbu = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_BBU, 1238 pbmp_xport_roe_bbu); 1239 pbmp_xport_roe_mcu = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_MCU, 1240 pbmp_xport_roe_mcu); 1241 pbmp_xport_roe_fronthaul = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_FRONTHAUL, 1242 pbmp_xport_roe_fronthaul); 1243 1244 if(!IS_CPRI_PORT(unit,port)) { 1245 1246 COMPILER_64_ZERO(rval64); 1247 SOC_IF_ERROR_RETURN(READ_PGW_OBM_PARSING_CONTROLr(unit, port ,&rval64)); 1248 soc_reg64_field32_set(unit, PGW_OBM_PARSING_CONTROLr, 1249 &rval64, USE_PM_PREEMPT_INPUTf , 0); 1250 SOC_IF_ERROR_RETURN(WRITE_PGW_OBM_PARSING_CONTROLr(unit, port, rval64)); 1251 } 1252 if (si->port_speed_max[port] <= 11000) { 1253 discard_limit = 375; 1254 if(IS_CPRI_PORT(unit,port)) { 1255 discard_limit = 383; 1256 express_discard = 383; 1257 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1258 express_discard = 187; 1259 } 1260 else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1261 express_discard = 0; 1262 } else { 1263 express_discard = lossless ? 1535 : 375; 1264 } 1265 if(IS_CPRI_PORT(unit,port)) { 1266 lossy_discard = 187; 1267 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1268 lossy_discard = 187; 1269 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1270 lossy_discard = 375; 1271 } else { 1272 lossy_discard = lossless ? 196 : 371; 1273 } 1274 if(IS_CPRI_PORT(unit,port)) { 1275 lossy_low_pri = 187; 1276 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1277 lossy_low_pri = 165; 1278 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1279 lossy_low_pri = 268; 1280 } else { 1281 lossy_low_pri = lossless ? 100 : 282; 1282 } 1283 port_xon = lossless ? 223 : 1535; 1284 port_xoff = lossless ? 233 : 1535; 1285 lossless0_xon = lossless ? 36 : 1535; 1286 lossless0_xoff = lossless ? 46 : 1535; 1287 } else if (si->port_speed_max[port] <= 21000) { 1288 discard_limit = 383; 1289 if(IS_CPRI_PORT(unit,port)) { 1290 express_discard = 383; 1291 discard_limit = 383; 1292 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1293 express_discard = 187; 1294 } 1295 else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1296 express_discard = 0; 1297 } else { 1298 express_discard = lossless ? 1535 : 375; 1299 } 1300 if(IS_CPRI_PORT(unit,port)) { 1301 lossy_discard = 187; 1302 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1303 lossy_discard = 187; 1304 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1305 lossy_discard = 375; 1306 } else { 1307 lossy_discard = lossless ? 196 : 371; 1308 } 1309 if(IS_CPRI_PORT(unit,port)) { 1310 lossy_low_pri = 0; 1311 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1312 lossy_low_pri = 165; 1313 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1314 lossy_low_pri = 268; 1315 } else { 1316 lossy_low_pri = lossless ? 100 : 282; 1317 } 1318 port_xon = lossless ? 206 : 1535; 1319 port_xoff = lossless ? 216 : 1535; 1320 lossless0_xon = lossless ? 36 : 1535; 1321 lossless0_xoff = lossless ? 46 : 1535; 1322 } else if (si->port_speed_max[port] <= 27000) { 1323 discard_limit = 375; 1324 if(IS_CPRI_PORT(unit,port)) { 1325 express_discard = 383; 1326 discard_limit = 383; 1327 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1328 express_discard = 187; 1329 } 1330 else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1331 express_discard = 0; 1332 } else { 1333 express_discard = lossless ? 1535 : 375; 1334 } 1335 if(IS_CPRI_PORT(unit,port)) { 1336 lossy_discard = 0; 1337 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1338 lossy_discard = 187; 1339 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1340 lossy_discard = 375; 1341 } else { 1342 lossy_discard = lossless ? 196 : 371; 1343 } 1344 if(IS_CPRI_PORT(unit,port)) { 1345 lossy_low_pri = 0; 1346 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1347 lossy_low_pri = 165; 1348 } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1349 lossy_low_pri = 268; 1350 } else { 1351 lossy_low_pri = lossless ? 100 : 282; 1352 } 1353 port_xon = lossless ? 198 : 1535; 1354 port_xoff = lossless ? 208 : 1535; 1355 lossless0_xon = lossless ? 36 : 1535; 1356 lossless0_xoff = lossless ? 46 : 1535; 1357 } else if (si->port_speed_max[port] <= 42000) { 1358 if((SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) || 1359 (SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port))) { 1360 discard_limit = 1512 ; 1361 1362 } else { 1363 discard_limit = 754; 1364 } 1365 express_discard = lossless ? 1535 : 756; 1366 if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1367 express_discard = 0; 1368 } 1369 if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 1370 lossy_discard = 756; 1371 } else { 1372 lossy_discard = lossless ? 196 : 750; 1373 } 1374 if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port) || 1375 SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 1376 lossy_low_pri = 670; 1377 } else { 1378 lossy_low_pri = lossless ? 100 : 661; 1379 } 1380 port_xon = lossless ? 499 : 1535; 1381 port_xoff = lossless ? 509 : 1535; 1382 lossless0_xon = lossless ? 98 : 1535; 1383 lossless0_xoff = lossless ? 108 : 1535; 1384 } else if (si->port_speed_max[port] <= 53000) { 1385 if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 1386 discard_limit = 754; 1387 } else { 1388 discard_limit = 1512; 1389 } 1390 if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 1391 express_discard = 377; 1392 } 1393 else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1394 express_discard = 0; 1395 } else { 1396 express_discard = 754; 1397 } 1398 if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 1399 lossy_discard = 377; 1400 } else { 1401 lossy_discard = lossless ? 196 : 750; 1402 } 1403 if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 1404 lossy_low_pri = 334; 1405 } else { 1406 lossy_low_pri = lossless ? 100 : 661; 1407 } 1408 port_xon = lossless ? 483 : 1535; 1409 port_xoff = lossless ? 493 : 1535; 1410 lossless0_xon = lossless ? 98 : 1535; 1411 lossless0_xoff = lossless ? 108 : 1535; 1412 } else { /* greter than 53000 including 106000 */ 1413 discard_limit = 1512; 1414 if(SOC_PBMP_MEMBER(pbmp_xport_roe_fronthaul, port)) { 1415 express_discard = 756; 1416 } 1417 else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1418 express_discard = 0; 1419 } else { 1420 express_discard = lossless ? 1535 : 1512; 1421 } 1422 if(SOC_PBMP_MEMBER(pbmp_xport_roe_fronthaul, port)) { 1423 lossy_discard = 756; 1424 } else { 1425 lossy_discard = lossless ? 196 : 1508; 1426 } 1427 if(SOC_PBMP_MEMBER(pbmp_xport_roe_fronthaul, port)) { 1428 lossy_low_pri = 670; 1429 } else { 1430 lossy_low_pri = lossless ? 100 : 1419; 1431 } 1432 port_xon = lossless ? 483 : 1535; 1433 port_xoff = lossless ? 493 : 1535; 1434 lossless0_xon = lossless ? 248 : 1535; 1435 lossless0_xoff = lossless ? 258 : 1535; 1436 } 1437 1438 if (reset) { 1439 discard_limit = 0; 1440 lossy_discard = 0; 1441 lossy_low_pri = 0; 1442 port_xon = 0; 1443 port_xoff = 0; 1444 lossless0_xon = 0; 1445 lossless0_xoff = 0; 1446 } 1447 1448 1449 rval32 = 0; 1450 reg = obm_port_config_regs[obm]; 1451 1452 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32)); 1453 soc_reg_field_set(unit, reg, &rval32, PORT_PRIf, 2); 1454 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32)); 1455 1456 rval32 = 0; 1457 reg = obm_max_usage_regs[obm]; 1458 1459 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32)); 1460 soc_reg_field_set(unit, reg, &rval32, PRIORITY_SELECTf, 2); 1461 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32)); 1462 1463 COMPILER_64_ZERO(rval64); 1464 reg = obm_thresh0_regs[obm]; 1465 1466 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1467 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 1535); 1468 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 1535); 1469 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, lossy_discard); 1470 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, lossy_low_pri); 1471 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_MINf, 0); 1472 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1473 1474 COMPILER_64_ZERO(rval64); 1475 reg = obm_thresh1_regs[obm]; 1476 1477 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1478 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, discard_limit); 1479 soc_reg64_field32_set(unit, reg, &rval64, EXPRESS_DISCARDf, express_discard); 1480 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1481 1482 rval32 = 0; 1483 reg = obm_shared_regs[obm]; 1484 1485 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32)); 1486 soc_reg_field_set(unit, reg, &rval32, SOP_DISCARD_MODEf, 1); 1487 soc_reg_field_set(unit, reg, &rval32, SOP_THRESHOLDf, 1535); 1488 soc_reg_field_set(unit, reg, &rval32, DISCARD_THRESHOLDf, 1535); 1489 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32)); 1490 1491 COMPILER_64_ZERO(rval64); 1492 reg = obm_fc_thresh0_regs[obm]; 1493 1494 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1495 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, port_xoff); 1496 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 1535); 1497 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 1535); 1498 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, lossless0_xon); 1499 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, lossless0_xoff); 1500 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1501 1502 COMPILER_64_ZERO(rval64); 1503 reg = obm_fc_thresh1_regs[obm]; 1504 1505 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1506 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, port_xon); 1507 soc_reg64_field32_set(unit, reg, &rval64, EXPRESS_XONf, 1535); 1508 soc_reg64_field32_set(unit, reg, &rval64, EXPRESS_XOFFf, 1535); 1509 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1510 1511 if (!IS_OVERSUB_PORT(unit, port) || 1512 ((IS_OVERSUB_PORT(unit, port)) && 1513 ((si->port_speed_max[port] == 40000) || 1514 (si->port_speed_max[port] == 42000)))) { 1515 COMPILER_64_ZERO(rval64); 1516 reg = obm_ct_thresh_regs[obm]; 1517 1518 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1519 soc_reg64_field32_set(unit, reg, &rval64, CUT_THROUGH_OKf, 2); 1520 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1521 } 1522 1523 COMPILER_64_ZERO(rval64); 1524 reg = obm_fc_config_regs[obm]; 1525 1526 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1527 soc_reg64_field32_set(unit, reg, &rval64, XOFF_REFRESH_TIMERf, 256); 1528 soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, lossless ? 1 : 0); 1529 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, lossless ? 1 : 0); 1530 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, 1531 lossless ? 65535 : 0); 1532 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1533 1534 COMPILER_64_ZERO(rval64); 1535 reg = obm_bank_config_regs[obm]; 1536 1537 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1538 soc_reg64_field32_set(unit, reg, &rval64, BANK_DISCARD_THRESHOLDf, 760); 1539 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1540 1541 rval32 = 0; 1542 reg = obm_ctrl_regs[obm]; 1543 port_osub = 1; 1544 1545 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32)); 1546 soc_reg_field_set(unit, reg, &rval32, obm_oversub_fields[subport], port_osub); 1547 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32)); 1548 1549 if (lossless) { 1550 mem = obm_pri_map_port_mem[(phy_port - 1) % MONTEREY_PORTS_PER_PGW]; 1551 sal_memset(&entry, 0, sizeof(entry)); 1552 SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_get(unit, mem, pgw, &entry)); 1553 for (index = 0; index < COUNTOF(offset_ob_prio); index++) { 1554 soc_mem_field32_set(unit, mem, &entry, offset_ob_prio[index], 2); 1555 } 1556 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry)); 1557 SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_set(unit, mem, pgw, &entry)); 1558 } else if (IS_ROE_ENABLED(unit)) { 1559 mem = obm_pri_map_port_mem[(phy_port - 1) % MONTEREY_PORTS_PER_PGW]; 1560 sal_memset(&entry, 0, sizeof(entry)); 1561 SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_get(unit, mem, pgw, &entry)); 1562 1563 for (index = 0; index < COUNTOF(offset_ob_prio); index++) { 1564 if (IS_CPRI_PORT(unit,port)) { 1565 soc_mem_field32_set(unit, mem, &entry, 1566 offset_ob_prio[index], 4); 1567 } else if ((index == 1 || index == 2 || index == 3 )) { 1568 if (index == 3) { 1569 soc_mem_field32_set(unit, mem, &entry, 1570 offset_ob_prio[index], 1); 1571 } else { 1572 if (!SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 1573 soc_mem_field32_set(unit, mem, &entry, 1574 offset_ob_prio[index], 4); 1575 } 1576 } 1577 } 1578 } 1579 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry)); 1580 SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_set(unit, mem, pgw, &entry)); 1581 } 1582 1583 return SOC_E_NONE; 1584 } 1585 STATIC int 1586 _soc_monterey_port_blk_ca_mode_set(int unit, int flexport, int xlp) 1587 { 1588 int rv; 1589 soc_reg_t reg; 1590 int ca_port_mode = 0; 1591 int pgw_inst; 1592 uint32 r32val0, r32val1; 1593 1594 static const soc_reg_t obm_ca_ctrl_regs[] = { 1595 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr, 1596 IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 1597 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 1598 }; 1599 1600 /* Calculate the mode of the Cell Assembly for the port block */ 1601 rv = soc_monterey_port_ca_mode_get(unit, flexport, xlp, &ca_port_mode); 1602 SOC_IF_ERROR_RETURN(rv); 1603 1604 r32val0 = 0; 1605 reg = obm_ca_ctrl_regs[xlp % MONTEREY_TSCS_PER_PGW]; 1606 pgw_inst = ((xlp / MONTEREY_TSCS_PER_PGW) | SOC_REG_ADDR_INSTANCE_MASK); 1607 /* Debug output */ 1608 LOG_VERBOSE(BSL_LS_SOC_PORT, 1609 (BSL_META_U(unit, 1610 "Port Block CellAssembly Mode: " 1611 "xlp=%d pgw=%d reg=%s ca_mode=%d \n"), 1612 xlp, (xlp / MONTEREY_TSCS_PER_PGW), SOC_REG_NAME(unit, reg), ca_port_mode)); 1613 1614 1615 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &r32val0)); 1616 soc_reg_field_set(unit, reg, &r32val0, PORT_MODEf, ca_port_mode); 1617 r32val1 = r32val0; 1618 if (!flexport) { 1619 soc_reg_field_set(unit, reg, &r32val0, PORT0_RESETf, 1); 1620 soc_reg_field_set(unit, reg, &r32val0, PORT1_RESETf, 1); 1621 soc_reg_field_set(unit, reg, &r32val0, PORT2_RESETf, 1); 1622 soc_reg_field_set(unit, reg, &r32val0, PORT3_RESETf, 1); 1623 1624 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val0)); 1625 } 1626 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val1)); 1627 1628 return SOC_E_NONE; 1629 } 1630 1631 int 1632 soc_monterey_idb_init(int unit) 1633 { 1634 int rv; 1635 int lossless; 1636 soc_port_t port; 1637 int xlp, blk_index; 1638 soc_block_t port_blocks[] = {SOC_BLK_XLPORT, 1639 SOC_BLK_CLPORT, 1640 SOC_BLOCK_TYPE_INVALID}; 1641 1642 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 1643 /* Per-port settings */ 1644 PBMP_ALL_ITER(unit, port) { 1645 SOC_IF_ERROR_RETURN(_soc_monterey_idb_port_init(unit, FALSE, lossless, port)); 1646 } 1647 1648 SOC_BLOCKS_ITER(unit, blk_index, port_blocks) { 1649 port = SOC_BLOCK_PORT(unit, blk_index); 1650 xlp = SOC_INFO(unit).port_serdes[port]; 1651 rv = _soc_monterey_port_blk_ca_mode_set(unit, FALSE, xlp); 1652 SOC_IF_ERROR_RETURN(rv); 1653 } 1654 1655 return SOC_E_NONE; 1656 } 1657 1658 1659 STATIC int 1660 soc_mn_mmu_delay_insertion_set (int unit, int port) 1661 { 1662 int phy_port, mmu_port; 1663 int val = 0; 1664 uint32 rval; 1665 soc_info_t *si; 1666 1667 si = &SOC_INFO(unit); 1668 1669 phy_port = si->port_l2p_mapping[port]; 1670 mmu_port = si->port_p2m_mapping[phy_port]; 1671 1672 1673 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, 1674 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, &rval)); 1675 1676 if (IS_OVERSUB_PORT(unit, port ) && si->port_speed_max[port] >= 20000) { 1677 val = 120 + (sal_rand() % 20); 1678 } else { 1679 /* linerate port or OS with < 20G */ 1680 } 1681 soc_reg_field_set(unit, ES_PIPE0_MMU_3DBG_Cr, &rval, FIELD_Af, val); 1682 1683 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, 1684 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, rval)); 1685 1686 return SOC_E_NONE; 1687 } 1688 1689 1690 STATIC int 1691 _soc_monterey_ser_enable_info(int unit, int block_info_idx, int inst, int port, 1692 soc_reg_t group_reg, uint64 *group_rval, 1693 const _soc_monterey_ser_info_t *info_list, 1694 soc_mem_t mem, int enable); 1695 1696 STATIC int 1697 _soc_monterey_ser_enable_mmu_1bit_ecc (int unit, int enable) 1698 { 1699 int i, f; 1700 uint64 rval64; 1701 uint32 rval; 1702 soc_field_info_t *fieldp; 1703 soc_reg_info_t *regp; 1704 soc_reg_t reg; 1705 1706 soc_reg_t _1b_reg_list[] = { 1707 CFAP_EN_COR_ERR_RPTr, 1708 MMU_DEQ_EN_COR_ERR_RPTr, 1709 MMU_ENQ_EN_COR_ERR_RPTr, 1710 MMU_EPRG_EN_COR_ERR_RPTr, 1711 INTFI_EN_COR_ERR_RPTr, 1712 MMU_PQE_EN_COR_ERR_RPTr, 1713 RQE_EN_COR_ERR_RPTr, 1714 MMU_TDM_EN_COR_ERR_RPTr, 1715 THDI_EN_COR_ERR_RPTr, 1716 MMU_THDM_DB_EN_COR_ERR_RPTr, 1717 MMU_THDM_MCQE_EN_COR_ERR_RPTr, 1718 MMU_THDU_EN_COR_ERR_RPTr, 1719 MMU_TOQ_EN_COR_ERR_RPTr, 1720 HSP_EN_COR_ERR_RPTr 1721 }; 1722 for (i = 0; i < COUNTOF(_1b_reg_list); i++) { 1723 reg = _1b_reg_list[i]; 1724 regp = &(SOC_REG_INFO(unit, reg)); 1725 if (SOC_REG_IS_64(unit, reg)) { 1726 SOC_IF_ERROR_RETURN 1727 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 1728 for (f = 0; f < regp->nFields; f++) { 1729 fieldp = &(regp->fields[f]); 1730 soc_reg64_field32_set(unit, reg, &rval64, fieldp->field, 1731 enable ? 1 : 0); 1732 } 1733 SOC_IF_ERROR_RETURN 1734 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 1735 } else { 1736 SOC_IF_ERROR_RETURN 1737 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 1738 for (f = 0; f < regp->nFields; f++) { 1739 fieldp = &(regp->fields[f]); 1740 soc_reg_field_set(unit, reg, &rval, fieldp->field, 1741 enable ? 1 : 0); 1742 } 1743 SOC_IF_ERROR_RETURN 1744 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 1745 } 1746 } 1747 1748 return SOC_E_NONE; 1749 } 1750 1751 1752 #ifdef INCLUDE_XFLOW_MACSEC 1753 STATIC int 1754 _soc_monterey_macsec_ser_enable (int unit, int enable) 1755 { 1756 #ifdef BCM_56670_B0 1757 int i; 1758 uint32 rval; 1759 soc_reg_t reg; 1760 soc_field_t field; 1761 _soc_mem_ser_en_info_t * macsec_mem_ser_info = _soc_bcm56670_b0_macsec_mem_ser_info; 1762 1763 for (i = 0; macsec_mem_ser_info[i].mem != INVALIDm; i++) { 1764 reg = macsec_mem_ser_info[i].en_ctrl.ctrl_type.en_reg; 1765 field = macsec_mem_ser_info[i].en_ctrl.en_fld; 1766 SOC_IF_ERROR_RETURN 1767 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 1768 soc_reg_field_set(unit, reg, &rval, field, 1769 enable ? 0 : 1); 1770 SOC_IF_ERROR_RETURN 1771 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 1772 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1773 "SER enable for: %s\n"), 1774 SOC_MEM_NAME(unit, macsec_mem_ser_info[i].mem))); 1775 1776 } 1777 #endif 1778 return SOC_E_NONE; 1779 } 1780 #endif 1781 1782 STATIC int 1783 _soc_monterey_ser_enable_info(int unit, int block_info_idx, int inst, int port, 1784 soc_reg_t group_reg, uint64 *group_rval, 1785 const _soc_monterey_ser_info_t *info_list, 1786 soc_mem_t mem, int enable) 1787 { 1788 const _soc_monterey_ser_info_t *info; 1789 int info_index, rv, rv1; 1790 soc_reg_t reg; 1791 uint32 rval; 1792 uint64 rval64, mac_err_mask; 1793 #ifdef INCLUDE_XFLOW_MACSEC 1794 uint8 parity_enable = 0; 1795 #endif 1796 1797 rv = SOC_E_NOT_FOUND; 1798 1799 /* Loop through each info entry in the list */ 1800 for (info_index = 0; ; info_index++) { 1801 info = &info_list[info_index]; 1802 if (info->type == _SOC_PARITY_TYPE_NONE) { 1803 /* End of table */ 1804 break; 1805 } 1806 1807 if (mem != INVALIDm && info->mem != mem) { 1808 continue; 1809 } 1810 1811 rv = SOC_E_NONE; 1812 1813 /* Enable the info entry in the group register */ 1814 if (info->group_reg_enable_field != INVALIDf) { 1815 soc_reg64_field32_set(unit, group_reg, group_rval, 1816 info->group_reg_enable_field, enable ? 1 : 0); 1817 } 1818 1819 /* Handle different parity error reporting style */ 1820 switch (info->type) { 1821 case _SOC_PARITY_TYPE_MAC_TX_CDC: 1822 case _SOC_PARITY_TYPE_MAC_RX_CDC: 1823 case _SOC_PARITY_TYPE_MAC_RX_TS: 1824 COMPILER_64_SET(mac_err_mask, 0, 0x7800); 1825 if (info->group_reg_enable_field == INVALIDf) { 1826 COMPILER_64_OR(*group_rval, mac_err_mask); 1827 } 1828 /* fall through */ 1829 case _SOC_PARITY_TYPE_ECC: 1830 case _SOC_PARITY_TYPE_PARITY: 1831 reg = info->enable_reg; 1832 if (!SOC_REG_IS_VALID(unit, reg)) { 1833 break; 1834 } 1835 if (SOC_REG_IS_64(unit, reg)) { 1836 SOC_IF_ERROR_RETURN 1837 (soc_reg_get(unit, reg, port, 0, &rval64)); 1838 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field, 1839 enable ? 1 : 0); 1840 SOC_IF_ERROR_RETURN 1841 (soc_reg_set(unit, reg, port, 0, rval64)); 1842 } else { 1843 SOC_IF_ERROR_RETURN 1844 (soc_reg32_get(unit, reg, port, 0, &rval)); 1845 soc_reg_field_set(unit, reg, &rval, info->enable_field, 1846 enable ? 1 : 0); 1847 SOC_IF_ERROR_RETURN 1848 (soc_reg32_set(unit, reg, port, 0, rval)); 1849 } 1850 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1851 "SER enable for: %s\n"), 1852 (info->mem == INVALIDm) ? info->mem_str : 1853 SOC_MEM_NAME(unit, info->mem))); 1854 break; 1855 case _SOC_PARITY_TYPE_MMU_SER: 1856 rv1 = _soc_monterey_ser_enable_mmu_1bit_ecc(unit, enable); 1857 if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) { 1858 return rv; 1859 } 1860 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1861 "SER enable for: %s\n"), 1862 (info->mem == INVALIDm) ? info->mem_str : 1863 SOC_MEM_NAME(unit, info->mem))); 1864 break; 1865 #ifdef INCLUDE_XFLOW_MACSEC 1866 case _SOC_PARITY_TYPE_MACSEC_SER: 1867 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 1868 if (info->group_reg_enable_field != INVALIDf) { 1869 soc_reg64_field32_set(unit, group_reg, group_rval, 1870 info->group_reg_enable_field, (enable & parity_enable) ? 1 : 0); 1871 } 1872 rv1 = _soc_monterey_macsec_ser_enable(unit, (enable & parity_enable) ? 1 : 0); 1873 if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) { 1874 return rv; 1875 } 1876 break; 1877 #endif 1878 case _SOC_PARITY_TYPE_GENERIC: 1879 case _SOC_PARITY_TYPE_START_ERR: 1880 case _SOC_PARITY_TYPE_BST: 1881 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1882 "SER enable for: %s\n"), 1883 (info->mem == INVALIDm) ? info->mem_str : 1884 SOC_MEM_NAME(unit, info->mem))); 1885 default: 1886 break; 1887 } /* Handle different parity error reporting style */ 1888 if (mem != INVALIDm) { 1889 break; 1890 } 1891 1892 } /* Loop through each info entry in the route block */ 1893 1894 return rv; 1895 } 1896 1897 STATIC int 1898 _soc_monterey_pm_cpri_intr_enable(int unit, int enable) 1899 { 1900 uint32 cmic_rval = 0, cmic_bit = 0; 1901 int rbi; 1902 const _soc_monterey_pm_cpri_intr_info_t *rb; 1903 1904 SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval)); 1905 1906 for (rbi = 0; ; rbi++) { 1907 rb = &_soc_monterey_pm_cpri_intr_info_irq4[rbi]; 1908 cmic_bit = rb->cmic_bit; 1909 if (cmic_bit == 0) { 1910 /* End of table */ 1911 break; 1912 } 1913 1914 if (enable) { 1915 cmic_rval |= cmic_bit; 1916 } 1917 1918 } /* end of rbi for */ 1919 1920 if (enable) { 1921 /* Write CMIC enable register */ 1922 (void)soc_cmicm_intr4_enable(unit, cmic_rval); 1923 } else { 1924 /* Write CMIC disable register */ 1925 (void)soc_cmicm_intr4_disable(unit, cmic_rval); 1926 } 1927 1928 return SOC_E_NONE; 1929 } 1930 #ifdef INCLUDE_XFLOW_MACSEC 1931 STATIC int 1932 _soc_monterey_macsec_intr_enable (int unit, int enable) 1933 { 1934 uint32 cmic_rval = 0, cmic_bit = 0; 1935 uint64 rval64; 1936 int rbi, rv = SOC_E_NONE; 1937 const _soc_monterey_ser_route_block_t *rb; 1938 1939 SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval)); 1940 1941 for (rbi = 0; ; rbi++) { 1942 rb = &_soc_monterey_macsec_ser_route_blocks_irq4[rbi]; 1943 cmic_bit = rb->cmic_bit; 1944 if (cmic_bit == 0) { 1945 /* End of table */ 1946 break; 1947 } 1948 if (rb->info == NULL) { 1949 continue; 1950 } 1951 if (enable) { 1952 cmic_rval |= cmic_bit; 1953 } 1954 1955 if (rb->enable_reg != INVALIDr) { 1956 SOC_IF_ERROR_RETURN 1957 (soc_reg_get(unit, rb->enable_reg, REG_PORT_ANY, 0, &rval64)); 1958 1959 rv = _soc_monterey_ser_enable_info(unit, 0, rb->id, REG_PORT_ANY, 1960 rb->enable_reg, &rval64, 1961 rb->info, INVALIDm, enable); 1962 } 1963 if (rv == SOC_E_NOT_FOUND) { 1964 continue; 1965 } else if (SOC_FAILURE(rv)) { 1966 return rv; 1967 } 1968 1969 if (rb->enable_reg != INVALIDr) { 1970 /* Write per route block parity enable register */ 1971 SOC_IF_ERROR_RETURN 1972 (soc_reg_set(unit, rb->enable_reg, REG_PORT_ANY, 0, rval64)); 1973 } 1974 } /* end of rbi for */ 1975 1976 if (enable) { 1977 /* Write CMIC enable register */ 1978 (void)soc_cmicm_intr4_enable(unit, cmic_rval); 1979 } else { 1980 /* Write CMIC disable register */ 1981 (void)soc_cmicm_intr4_disable(unit, cmic_rval); 1982 } 1983 1984 return SOC_E_NONE; 1985 } 1986 #endif 1987 1988 STATIC int 1989 _soc_monterey_ser_enable_pm (int unit, int enable) 1990 { 1991 uint32 cmic_rval = 0, cmic_bit = 0; 1992 uint64 rval64; 1993 int rbi, block_info_idx, port, rv = SOC_E_NONE; 1994 const _soc_monterey_ser_route_block_t *rb; 1995 1996 SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval)); 1997 1998 for (rbi = 0; ; rbi++) { 1999 rb = &_soc_monterey_ser_route_blocks_irq4[rbi]; 2000 cmic_bit = rb->cmic_bit; 2001 if (cmic_bit == 0) { 2002 /* End of table */ 2003 break; 2004 } 2005 if (rb->info == NULL) { 2006 continue; 2007 } 2008 if (enable) { 2009 cmic_rval |= cmic_bit; 2010 } 2011 port = INVALID_PORT; 2012 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 2013 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 2014 port = SOC_BLOCK_PORT(unit, block_info_idx); 2015 break; 2016 } 2017 } 2018 2019 if (port == INVALID_PORT) { 2020 continue; 2021 } 2022 2023 if (rb->enable_reg != INVALIDr) { 2024 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 2025 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 2026 /* This port block is not configured */ 2027 continue; 2028 } 2029 SOC_IF_ERROR_RETURN 2030 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64)); 2031 2032 rv = _soc_monterey_ser_enable_info(unit, block_info_idx, rb->id, port, 2033 rb->enable_reg, &rval64, 2034 rb->info, INVALIDm, enable); 2035 } 2036 if (rv == SOC_E_NOT_FOUND) { 2037 continue; 2038 } else if (SOC_FAILURE(rv)) { 2039 return rv; 2040 } 2041 2042 if (rb->enable_reg != INVALIDr) { 2043 /* Write per route block parity enable register */ 2044 SOC_IF_ERROR_RETURN 2045 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64)); 2046 } 2047 } /* end of rbi for */ 2048 2049 if (enable) { 2050 /* Write CMIC enable register */ 2051 (void)soc_cmicm_intr4_enable(unit, cmic_rval); 2052 } else { 2053 /* Write CMIC disable register */ 2054 (void)soc_cmicm_intr4_disable(unit, cmic_rval); 2055 } 2056 2057 return SOC_E_NONE; 2058 } 2059 2060 STATIC int 2061 _soc_monterey_l3_mem_sram_info_get(int unit, int *base, int *count, 2062 soc_mem_t *view, 2063 int mem_index[][_SOC_SER_MAX_ENTRIES_PER_BKT]) 2064 { 2065 int i, j, base_index; 2066 int copyno; 2067 uint8 *vmap; 2068 uint32 *cache; 2069 struct mem_list_s { 2070 soc_mem_t mem; /* view name */ 2071 int ram_count; /* Num of entries in the bucket */ 2072 int entry_count; /* Num of writes to correct LP memory */ 2073 }; 2074 struct mem_list_s mem_list[] = { 2075 /* 2076 * If the hash bucket corresponding to the error LP index has 2077 * all single wide entries, it is sufficient to write any of the one 2078 * entry to hardware and the LP memory would be fixed in HW. 2079 * For double wide entries also writing one entry would be sufficient 2080 * to clear the error on the LP entry but for some keys we need to write 2081 * all the entries (2) in the bucket for the LP memory to be fixed. 2082 * For quad wide, anyway a single entry correction would fix the LP memory 2083 * error because the QW entry touches all the physical entries in 2084 * the bucket. 2085 */ 2086 {L3_ENTRY_IPV4_UNICASTm, 4, 1}, 2087 {L3_ENTRY_IPV4_MULTICASTm, 2, 2}, 2088 {L3_ENTRY_IPV6_UNICASTm, 2, 2}, 2089 {L3_ENTRY_IPV6_MULTICASTm, 1, 1} 2090 }; 2091 view[0] = view[1] = INVALIDm; 2092 for (i = 0; i < COUNTOF(mem_list); i++) { 2093 copyno = SOC_MEM_BLOCK_ANY(unit, mem_list[i].mem); 2094 cache = SOC_MEM_STATE(unit, mem_list[i].mem).cache[copyno]; 2095 vmap = SOC_MEM_STATE(unit, mem_list[i].mem).vmap[copyno]; 2096 if (mem_list[i].mem == L3_ENTRY_IPV4_UNICASTm) { 2097 /* 2098 * Each LP memory index corresponds to 4 single wide entries. 2099 * The ISS (shared) region will start after the dedicated region. 2100 */ 2101 base_index = (soc_mem_index_count(unit, L3_ENTRY_LPm) * 4) 2102 + (*base * 4); 2103 } else if ((mem_list[i].mem == L3_ENTRY_IPV4_MULTICASTm) || 2104 (mem_list[i].mem == L3_ENTRY_IPV6_UNICASTm)) { 2105 /* 2106 * Each LP memory index corresponds to 2 double wide entries. 2107 * The ISS (shared) region will start after the dedicated region. 2108 */ 2109 base_index = (soc_mem_index_count(unit, L3_ENTRY_LPm) * 2) 2110 + (*base * 2); 2111 } else { 2112 /* 2113 * Each LP memory index corresponds to 1 quad wide entry. 2114 * The ISS (shared) region will start after the dedicated region. 2115 */ 2116 base_index = soc_mem_index_count(unit, L3_ENTRY_LPm) + *base; 2117 } 2118 2119 for (j = 0; j < mem_list[i].ram_count; j++) { 2120 if ((cache != NULL) && (vmap != NULL) && 2121 (CACHE_VMAP_TST(vmap, base_index+j))) { 2122 if ((mem_list[i].mem == L3_ENTRY_IPV4_UNICASTm) || 2123 (mem_list[i].mem == L3_ENTRY_IPV6_MULTICASTm)) { 2124 view[0] = mem_list[i].mem; 2125 *count = mem_list[i].entry_count; 2126 mem_index[0][0] = base_index; 2127 } else { 2128 view[j] = mem_list[i].mem; 2129 *count = mem_list[i].entry_count; 2130 mem_index[j][0] = base_index+j; 2131 } 2132 } 2133 } 2134 if (*count == 1) { 2135 break; 2136 } 2137 } 2138 /* 2139 * For double wide views, if only one entry is valid in a given bucket, 2140 * the other entry in the same bucket also needs to be written (any double 2141 * wide view is fine because we will be writing null-entry anyway). 2142 * Using the same view as its neighbor here. The index for the view is 2143 * either +1 or -1 based on the original base_index. E.g., if the base_index 2144 * is 2048, the correction indexes would be 2048 (with the orig entry data) 2145 * and 2049 (with null-entry). If the base_index is 2049, the correction 2146 * indexes would be 2049 (with the orig entry data) and 2048 (with 2147 * null-entry). 2148 */ 2149 if (*count == 2) { 2150 if ((view[0] == INVALIDm) && (view[1] != INVALIDm)) { 2151 view[0] = view[1]; 2152 mem_index[0][0] = mem_index[1][0] - 1; 2153 } else if ((view[1] == INVALIDm) && (view[0] != INVALIDm)) { 2154 view[1] = view[0]; 2155 mem_index[1][0] = mem_index[0][0] + 1; 2156 } 2157 } 2158 if (!(*count)) { 2159 /* Default view as L3_ENTRY_IPV4_UNICASTm */ 2160 view[0] = mem_list[0].mem; 2161 *count = mem_list[0].entry_count; 2162 mem_index[0][0] = (soc_mem_index_count(unit, L3_ENTRY_LPm) * 4) 2163 + (*base * 4); 2164 } 2165 return SOC_E_NONE; 2166 } 2167 2168 STATIC int 2169 _soc_monterey_ser_enable_all (int unit, int enable) 2170 { 2171 uint8 rbi, bcount, type; 2172 uint16 pcount; 2173 uint32 cmic_rval; 2174 uint32 rval, cmic_bit; 2175 int port = REG_PORT_ANY; 2176 int rv, block_info_idx; 2177 uint64 rval64; 2178 soc_reg_t reg, ecc1b_reg; 2179 soc_field_t field, ecc1b_field; 2180 _soc_reg_ser_en_info_t *reg_info; 2181 _soc_mem_ser_en_info_t *mem_info; 2182 _soc_bus_ser_en_info_t *bus_info; 2183 _soc_buffer_ser_en_info_t *buf_info; 2184 char *str_type; 2185 char *str_name; 2186 const _soc_monterey_ser_route_block_t *rb; 2187 const _soc_monterey_ser_block_info_t *ser_block_info; 2188 static char *parity_module_str[4] = {"REG", "MEM", "BUS", "BUF"}; 2189 int done = 0; 2190 2191 /* coverity[result_independent_of_operands] */ 2192 SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK3r(unit, &cmic_rval)); 2193 2194 /* Enable new fifo mechanism based SER stuff */ 2195 ser_block_info = _soc_monterey_ser_block_info; 2196 for (bcount = 0; ser_block_info[bcount].blocktype; bcount++) { 2197 done = 0; 2198 if (SOC_BLK_MACSEC == ser_block_info[bcount].blocktype) { 2199 continue; 2200 } 2201 2202 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, 2203 (BSL_META_U(unit, 2204 "Unit %d SER enable for: %s\n"), 2205 unit, ser_block_info[bcount].name)); 2206 2207 type = ser_block_info[bcount].type; 2208 reg_info = (_soc_reg_ser_en_info_t*)ser_block_info[bcount].info; 2209 mem_info = (_soc_mem_ser_en_info_t*)ser_block_info[bcount].info; 2210 bus_info = (_soc_bus_ser_en_info_t*)ser_block_info[bcount].info; 2211 buf_info = (_soc_buffer_ser_en_info_t*)ser_block_info[bcount].info; 2212 for (pcount = 0; ; pcount++) { 2213 ecc1b_reg = INVALIDr; 2214 ecc1b_field = INVALIDf; 2215 switch (type) { 2216 case _SOC_MONTEREY_SER_TYPE_REG: 2217 if (reg_info[pcount].reg == INVALIDr) { 2218 done = 1; 2219 } else { 2220 reg = reg_info[pcount].en_ctrl.ctrl_type.en_reg; 2221 field = reg_info[pcount].en_ctrl.en_fld; 2222 str_name = SOC_REG_NAME(unit, reg_info[pcount].reg); 2223 } 2224 break; 2225 case _SOC_MONTEREY_SER_TYPE_MEM: 2226 if (mem_info[pcount].mem == INVALIDm) { 2227 done = 1; 2228 } else { 2229 if (soc_feature(unit, soc_feature_parity_injection_l2)) { 2230 if ((mem_info[pcount].mem == L2_USER_ENTRYm) || 2231 (mem_info[pcount].mem == L2_USER_ENTRY_DATA_ONLYm)){ 2232 continue; 2233 } 2234 } 2235 if (SOC_MEM_INFO(unit, mem_info[pcount].mem).flags & 2236 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP) { 2237 continue; 2238 } 2239 reg = mem_info[pcount].en_ctrl.ctrl_type.en_reg; 2240 field = mem_info[pcount].en_ctrl.en_fld; 2241 ecc1b_reg = mem_info[pcount].ecc1b_ctrl.ctrl_type.en_reg; 2242 ecc1b_field = mem_info[pcount].ecc1b_ctrl.en_fld; 2243 str_name = SOC_MEM_NAME(unit, mem_info[pcount].mem); 2244 } 2245 break; 2246 case _SOC_MONTEREY_SER_TYPE_BUS: 2247 if (bus_info[pcount].en_reg == INVALIDr) { 2248 done = 1; 2249 } else { 2250 reg = bus_info[pcount].en_reg; 2251 field = bus_info[pcount].en_fld; 2252 str_name = bus_info[pcount].bus_name; 2253 } 2254 break; 2255 case _SOC_MONTEREY_SER_TYPE_BUF: 2256 if (buf_info[pcount].en_reg == INVALIDr) { 2257 done = 1; 2258 } else { 2259 reg = buf_info[pcount].en_reg; 2260 field = buf_info[pcount].en_fld; 2261 str_name = buf_info[pcount].buffer_name; 2262 } 2263 break; 2264 default: 2265 LOG_ERROR(BSL_LS_SOC_MEM, 2266 (BSL_META_U(unit, 2267 "Unknown parity module [bcount: %d][pcount: %d].\n"), 2268 bcount, pcount)); 2269 return SOC_E_INTERNAL; 2270 } 2271 if (done) { 2272 break; 2273 } else { 2274 str_type = parity_module_str[type]; 2275 } 2276 /* NOTE: Do not use the field modify routine in the following as 2277 some regs do not return the correct value due to which the 2278 modify routine skips the write */ 2279 if (SOC_REG_IS_64(unit, reg)) { 2280 SOC_IF_ERROR_RETURN 2281 (soc_reg_get(unit, reg, port, 0, &rval64)); 2282 soc_reg64_field32_set(unit, reg, &rval64, field, enable ? 1 : 0); 2283 SOC_IF_ERROR_RETURN 2284 (soc_reg_set(unit, reg, port, 0, rval64)); 2285 } else { 2286 SOC_IF_ERROR_RETURN 2287 (soc_reg32_get(unit, reg, port, 0, &rval)); 2288 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 2289 SOC_IF_ERROR_RETURN 2290 (soc_reg32_set(unit, reg, port, 0, rval)); 2291 } 2292 if (ecc1b_reg != INVALIDr && ecc1b_field != INVALIDf) { 2293 if (SOC_REG_IS_64(unit, ecc1b_reg)) { 2294 SOC_IF_ERROR_RETURN 2295 (soc_reg_get(unit, ecc1b_reg, port, 0, &rval64)); 2296 soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, enable ? 1 : 0); 2297 SOC_IF_ERROR_RETURN 2298 (soc_reg_set(unit, ecc1b_reg, port, 0, rval64)); 2299 } else { 2300 SOC_IF_ERROR_RETURN 2301 (soc_reg32_get(unit, ecc1b_reg, port, 0, &rval)); 2302 soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, enable ? 1 : 0); 2303 if (20 == SOC_REG_ACC_TYPE(unit, ecc1b_reg)) { 2304 SOC_IF_ERROR_RETURN( 2305 soc_reg32_set(unit, ecc1b_reg, \ 2306 SOC_REG_ADDR_INSTANCE_MASK, 0, rval)); 2307 } else { 2308 SOC_IF_ERROR_RETURN 2309 (soc_reg32_set(unit, ecc1b_reg, port, 0, rval)); 2310 } 2311 } 2312 } 2313 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, 2314 (BSL_META_U(unit, 2315 "SER enable for %s: %s\n"), 2316 str_type, str_name)); 2317 } 2318 2319 /* Loop through each place-and-route of block entry 2320 Handle entries with valid REG & FIELD values */ 2321 for (rbi = 0; ; rbi++) { 2322 rb = &_soc_monterey_ser_route_blocks_irq3[rbi]; 2323 cmic_bit = rb->cmic_bit; 2324 if (cmic_bit == 0) { 2325 /* End of table */ 2326 break; 2327 } 2328 if (rb->blocktype == ser_block_info[bcount].blocktype) { 2329 cmic_rval |= cmic_bit; 2330 if (rb->enable_reg != INVALIDr && rb->enable_field != INVALIDf) { 2331 SOC_IF_ERROR_RETURN 2332 (soc_reg_field32_modify(unit, rb->enable_reg, 2333 REG_PORT_ANY, rb->enable_field, enable ? 1 : 0)); 2334 } 2335 } 2336 } 2337 2338 /* reset (toggle) fifo if applicable */ 2339 if (ser_block_info[bcount].fifo_reset_reg != INVALIDr) { 2340 SOC_IF_ERROR_RETURN 2341 (soc_reg_field32_modify(unit, 2342 ser_block_info[bcount].fifo_reset_reg, 2343 REG_PORT_ANY, FIFO_RESETf, 1)); 2344 SOC_IF_ERROR_RETURN 2345 (soc_reg_field32_modify(unit, 2346 ser_block_info[bcount].fifo_reset_reg, 2347 REG_PORT_ANY, FIFO_RESETf, 0)); 2348 } 2349 } 2350 2351 /* Enable 1B error reporting for some special items */ 2352 2353 /* Description of IARB_EN_COR_ERR_RPT says, supress these errors 2354 * by setting bits. So basically we are supressing error reporting 2355 * by setting bits. 2356 * Then again, following TD2P code... 2357 */ 2358 SOC_IF_ERROR_RETURN 2359 (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 2360 REG_PORT_ANY, 2361 CMIC_BUFFER_1BIT_ERROR_REPORTf,enable?1:0)); 2362 SOC_IF_ERROR_RETURN 2363 (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 2364 REG_PORT_ANY, 2365 LEARN_FIFO_1BIT_ERROR_REPORTf, enable?1:0)); 2366 2367 /* Loop through each place-and-route block 2368 Handle entries with non-null INFO */ 2369 for (rbi = 0; ; rbi++) { 2370 rb = &_soc_monterey_ser_route_blocks_irq3[rbi]; 2371 cmic_bit = rb->cmic_bit; 2372 if (cmic_bit == 0) { 2373 /* End of table */ 2374 break; 2375 } 2376 if (rb->info == NULL) { 2377 continue; 2378 } 2379 if (enable) { 2380 cmic_rval |= cmic_bit; 2381 } 2382 2383 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 2384 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 2385 port = SOC_BLOCK_PORT(unit, block_info_idx); 2386 break; 2387 } 2388 } 2389 if (rb->enable_reg != INVALIDr) { 2390 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 2391 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 2392 /* This port block is not configured */ 2393 continue; 2394 } 2395 SOC_IF_ERROR_RETURN 2396 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64)); 2397 } 2398 2399 rv = _soc_monterey_ser_enable_info(unit, block_info_idx, rb->id, port, 2400 rb->enable_reg, &rval64, 2401 rb->info, INVALIDm, enable); 2402 if (rv == SOC_E_NOT_FOUND) { 2403 continue; 2404 } else if (SOC_FAILURE(rv)) { 2405 return rv; 2406 } 2407 2408 if (rb->enable_reg != INVALIDr) { 2409 /* Write per route block parity enable register */ 2410 SOC_IF_ERROR_RETURN 2411 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64)); 2412 } 2413 } 2414 2415 if (enable) { 2416 uint32 rval1; 2417 /* MMU enables */ 2418 2419 SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1)); 2420 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0); 2421 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 2422 2423 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2424 2425 soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0); 2426 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2427 2428 soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1); 2429 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2430 2431 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */ 2432 2433 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1); 2434 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 2435 2436 /* Write CMIC enable register */ 2437 (void)soc_cmicm_intr3_enable(unit, cmic_rval); 2438 } else { 2439 /* MMU disables */ 2440 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2441 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0); 2442 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2443 SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0)); 2444 2445 /* Write CMIC disable register */ 2446 (void)soc_cmicm_intr3_disable(unit, cmic_rval); 2447 } 2448 2449 SOC_IF_ERROR_RETURN(_soc_monterey_ser_enable_pm(unit,enable)); 2450 2451 return SOC_E_NONE; 2452 } 2453 2454 STATIC int 2455 _soc_monterey_clear_mmu_memory(int unit, soc_mem_t mem) 2456 { 2457 int i, count; 2458 static soc_mem_t mmu_mems[] = { 2459 MMU_INTFI_XPIPE_FC_MAP_TBL0m, 2460 MMU_INTFI_XPIPE_FC_MAP_TBL1m, 2461 MMU_INTFI_XPIPE_FC_MAP_TBL2m 2462 }; 2463 2464 count = COUNTOF(mmu_mems); 2465 /* MMU mem clear to avoid SER issue */ 2466 for (i = 0; i < count; i++) { 2467 if (mem != INVALIDm) { 2468 if (mem == mmu_mems[i]) { 2469 SOC_IF_ERROR_RETURN 2470 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE)); 2471 break; 2472 } 2473 } else { 2474 SOC_IF_ERROR_RETURN 2475 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE)); 2476 } 2477 } 2478 return SOC_E_NONE; 2479 } 2480 2481 static int _soc_mn_num_shared_alpm_banks[SOC_MAX_NUM_DEVICES] = {0}; 2482 static soc_mem_t *_soc_monterey_alpm_bkt_view_map[SOC_MAX_NUM_DEVICES]; 2483 #define _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks) ((num_uft_banks == 4) ? 0xFFFF : 0x7FFF) 2484 #define _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks) ((num_uft_banks == 4) ? 16 : 15) 2485 2486 int 2487 _soc_monterey_mem_sram_info_get (int unit, soc_mem_t mem, int index, 2488 _soc_ser_sram_info_t *sram_info) 2489 { 2490 int i, base, offset ; 2491 int entries_per_ram = 0, contiguous = 0; 2492 2493 sram_info->disable_reg = INVALIDr; 2494 sram_info->disable_field = INVALIDf; 2495 sram_info->force_reg = INVALIDr; 2496 sram_info->force_field = INVALIDf; 2497 2498 switch (mem) { 2499 case L2Xm: 2500 case L2_ENTRY_ONLY_ECCm: 2501 if (mem == L2Xm) { 2502 sram_info->disable_reg = L2_ENTRY_PARITY_CONTROLr; 2503 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2504 } 2505 2506 sram_info->ram_count = SOC_MONTEREY_NUM_EL_L2; 2507 entries_per_ram = SOC_MONTEREY_RAM_OFFSET_L2_BANK; 2508 offset = index % entries_per_ram; 2509 base = offset; 2510 if (index >= SOC_MONTEREY_NUM_ENTRIES_PER_L2_BANK) { 2511 base = offset + SOC_MONTEREY_NUM_ENTRIES_PER_L2_BANK; 2512 } 2513 break; 2514 case L3_ENTRY_ONLYm: 2515 case L3_ENTRY_IPV4_UNICASTm: 2516 case L3_ENTRY_IPV4_MULTICASTm: 2517 case L3_ENTRY_IPV6_UNICASTm: 2518 case L3_ENTRY_IPV6_MULTICASTm: 2519 case L3_ENTRY_ONLY_ECCm: 2520 sram_info->ram_count = 4; 2521 entries_per_ram = 2048; 2522 base = index; 2523 break; 2524 2525 case VLAN_MACm: 2526 case VLAN_XLATEm: 2527 case VLAN_XLATE_ECCm: 2528 contiguous = 1; 2529 sram_info->disable_reg = VLAN_XLATE_DBGCTRL_0r; 2530 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2531 sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r; 2532 sram_info->force_field = FORCE_XOR_GENf; 2533 sram_info->ram_count = SOC_MONTEREY_NUM_EL_VLAN_XLATE; 2534 base = (index/4) * 4; 2535 break; 2536 case EGR_VLAN_XLATEm: 2537 case EGR_VLAN_XLATE_ECCm: 2538 contiguous = 1; 2539 sram_info->disable_reg = EGR_VLAN_XLATE_CONTROLr; 2540 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2541 sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr; 2542 sram_info->force_field = FORCE_XOR_GENf; 2543 sram_info->ram_count = SOC_MONTEREY_NUM_EL_EGR_VLAN_XLATE; 2544 base = (index/4) * 4; 2545 break; 2546 case ING_L3_NEXT_HOPm: 2547 sram_info->ram_count = SOC_MONTEREY_NUM_EL_ING_L3_NEXT_HOP; 2548 entries_per_ram = SOC_MONTEREY_RAM_OFFSET_ING_L3_NEXT_HOP; 2549 base = index % entries_per_ram; 2550 break; 2551 case L3_IPMCm: 2552 sram_info->ram_count = SOC_MONTEREY_NUM_EL_L3_IPMC; 2553 entries_per_ram = SOC_MONTEREY_RAM_OFFSET_L3_IPMC; 2554 base = index % entries_per_ram; 2555 break; 2556 case L2MCm: 2557 sram_info->ram_count = SOC_MONTEREY_NUM_EL_L2MC; 2558 entries_per_ram = SOC_MONTEREY_RAM_OFFSET_L2MC; 2559 base = index % entries_per_ram; 2560 break; 2561 case L2_ENTRY_LPm: 2562 case L3_ENTRY_LPm: 2563 case VLAN_XLATE_LPm: 2564 case EGR_VLAN_XLATE_LPm: 2565 sram_info->view[0] = mem; 2566 sram_info->index_count[0] = 1; 2567 sram_info->ram_count = 1; 2568 entries_per_ram = 0; 2569 base = index; 2570 break; 2571 case L2_ENTRY_ISS_LPm: 2572 base = (soc_mem_index_count(unit, L2_ENTRY_LPm) * 4) + (index * 4); 2573 sram_info->ram_count = 1; 2574 sram_info->view[0] = L2Xm; 2575 break; 2576 case L3_ENTRY_ISS_LPm: 2577 base = index; 2578 SOC_IF_ERROR_RETURN(_soc_monterey_l3_mem_sram_info_get(unit, &base, 2579 &sram_info->ram_count, &sram_info->view[0], 2580 sram_info->mem_indexes)); 2581 return SOC_E_NONE; 2582 default: 2583 return SOC_E_PARAM; 2584 } 2585 sram_info->mem_indexes[0][0] = base; 2586 if (contiguous) { 2587 for (i = 1; i < sram_info->ram_count; i++) { 2588 sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 1; 2589 } 2590 } else { 2591 for (i = 1; i < sram_info->ram_count; i++) { 2592 sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + entries_per_ram; 2593 } 2594 } 2595 return SOC_E_NONE; 2596 } 2597 2598 2599 STATIC int 2600 _soc_monterey_mmu_init_default_val(int unit) 2601 { 2602 2603 return SOC_E_NONE; 2604 } 2605 2606 int 2607 _soc_monterey_mem_ser_control(int unit, soc_mem_t mem, int copyno, 2608 int enable) 2609 { 2610 if (enable) { 2611 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr, 2612 REG_PORT_ANY, TOP_MMU_RST_Lf, 0)); 2613 sal_usleep(1000); 2614 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr, 2615 REG_PORT_ANY, TOP_MMU_RST_Lf, 1)); 2616 sal_usleep(1000); 2617 } 2618 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 2619 SOC_IF_ERROR_RETURN(_soc_monterey_clear_mmu_memory(unit, INVALIDm)); 2620 SOC_IF_ERROR_RETURN(_soc_monterey_ser_enable_all(unit, enable)); 2621 } 2622 if (enable) { 2623 SOC_IF_ERROR_RETURN 2624 (_soc_monterey_mmu_init_default_val(unit)); 2625 } 2626 return SOC_E_NONE; 2627 } 2628 2629 void 2630 _soc_monterey_mem_parity_info(int unit, int block_info_idx, int pipe, 2631 soc_field_t field_enum, uint32 *minfo) 2632 { 2633 *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) 2634 | ((pipe & 0xff) << SOC_ERROR_PIPE_BP) 2635 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK); 2636 } 2637 2638 int 2639 _soc_monterey_mem_is_dyn(int unit, soc_mem_t mem) 2640 { 2641 if (SOC_MEM_FIELD_VALID(unit, mem, HITf) || 2642 SOC_MEM_FIELD_VALID(unit, mem, HIT0f) || 2643 SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) || 2644 SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) || 2645 SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) || 2646 SOC_MEM_FIELD_VALID(unit, mem, HITSAf) || 2647 SOC_MEM_FIELD_VALID(unit, mem, HITDAf) || 2648 SOC_MEM_FIELD_VALID(unit, mem, B0_HITf) || 2649 SOC_MEM_FIELD_VALID(unit, mem, B1_HITf)) { 2650 return 1; 2651 } 2652 return 0; 2653 } 2654 2655 int 2656 _soc_monterey_populate_ser_log(int unit, soc_reg_t parity_enable_reg, 2657 soc_field_t parity_enable_field, 2658 soc_mem_t mem, 2659 int mem_block, 2660 soc_acc_type_t acc_type, 2661 int index, 2662 sal_usecs_t detect_time, 2663 uint32 sblk, 2664 uint32 address) 2665 { 2666 uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 2667 int log_entry_size, id, entry_dw; 2668 uint32 *cache; 2669 uint8 *vmap; 2670 soc_ser_log_tlv_memory_t log_mem; 2671 soc_ser_log_tlv_generic_t log_generic; 2672 #ifdef INCLUDE_XFLOW_MACSEC 2673 int block_type = SOC_BLOCK_TYPE(unit, mem_block); 2674 #endif 2675 2676 sal_memset(&log_generic, 0, sizeof(log_generic)); 2677 sal_memset(&log_mem, 0, sizeof(log_mem)); 2678 2679 /* 2680 must be large enough for at least generic and terminator, as well as the 2681 memory type since we might decode it in soc_ser_correction. 2682 */ 2683 log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 + 2684 sizeof(soc_ser_log_tlv_generic_t) + 2685 sizeof(soc_ser_log_tlv_memory_t); 2686 2687 if (mem == INVALIDm) { 2688 mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address); 2689 if (mem != INVALIDm) { 2690 if (sblk) { 2691 SOC_MEM_BLOCK_ITER(unit, mem, mem_block) { 2692 if (SOC_BLOCK2OFFSET(unit, mem_block) == sblk) { 2693 break; 2694 } 2695 } 2696 } else { 2697 mem_block = SOC_MEM_BLOCK_ANY(unit, mem); 2698 } 2699 } 2700 } 2701 /* 2702 If we have decoded the memory we can record its contents/cache 2703 */ 2704 if((mem != INVALIDm) && 2705 (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) { 2706 entry_dw = soc_mem_entry_words(unit, mem); 2707 2708 /* Check to make sure this isn't a duplicate */ 2709 /* Search for a log entry with the same mem, and index with within the last 5 seconds */ 2710 if (soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()) > 0) { 2711 return 0; 2712 } 2713 2714 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2715 2716 cache = SOC_MEM_STATE(unit, mem).cache[mem_block]; 2717 vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block]; 2718 if (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CACHABLE) { 2719 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2720 } 2721 2722 /* create the entry based on determined size, save id */ 2723 id = soc_ser_log_create_entry(unit, log_entry_size); 2724 2725 /* Add the memory information to the log now so we can detect duplicate errors */ 2726 log_generic.time = detect_time; 2727 log_mem.memory = mem; 2728 log_mem.index = index; 2729 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY, 2730 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 2731 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC, 2732 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 2733 2734 /* Disable Parity */ 2735 if (!_soc_monterey_mem_is_dyn(unit, mem) && 2736 (parity_enable_reg != INVALIDr) && 2737 (parity_enable_field != INVALIDf)) { 2738 #ifdef INCLUDE_XFLOW_MACSEC 2739 if (soc_feature(unit, soc_feature_xflow_macsec)) { 2740 if (soc_reg_field32_modify(unit, parity_enable_reg, 2741 REG_PORT_ANY, parity_enable_field, (block_type != SOC_BLK_MACSEC) ? 0 : 1) < 0) { 2742 return 0; 2743 } 2744 } else 2745 #endif 2746 { 2747 if (soc_reg_field32_modify(unit, parity_enable_reg, 2748 REG_PORT_ANY, parity_enable_field, 0) < 0) { 2749 return 0; 2750 } 2751 } 2752 } 2753 2754 /* Enable Parity */ 2755 if (!_soc_monterey_mem_is_dyn(unit, mem) && 2756 (parity_enable_reg != INVALIDr) && 2757 (parity_enable_field != INVALIDf)) { 2758 #ifdef INCLUDE_XFLOW_MACSEC 2759 if (soc_feature(unit, soc_feature_xflow_macsec)) { 2760 if (soc_reg_field32_modify(unit, parity_enable_reg, 2761 REG_PORT_ANY, parity_enable_field, (block_type != SOC_BLK_MACSEC) ? 0 : 1) < 0) { 2762 return 0; 2763 } 2764 } else 2765 #endif 2766 { 2767 if (soc_reg_field32_modify(unit, parity_enable_reg, 2768 REG_PORT_ANY, parity_enable_field, 0) < 0) { 2769 return 0; 2770 } 2771 } 2772 2773 /*Enable NACK on read */ 2774 soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN, 2775 mem, 0, mem_block, 2776 index, tmp_entry); 2777 /* fill in the memory contents tlv */ 2778 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS, 2779 entry_dw*4, tmp_entry) < 0) { 2780 return 0; 2781 } 2782 2783 #ifdef INCLUDE_XFLOW_MACSEC 2784 if (soc_feature(unit, soc_feature_xflow_macsec)) { 2785 if (soc_reg_field32_modify(unit, parity_enable_reg, 2786 REG_PORT_ANY, parity_enable_field, (block_type != SOC_BLK_MACSEC) ? 1 : 0) < 0) { 2787 return 0; 2788 } 2789 } else 2790 #endif 2791 { 2792 if (soc_reg_field32_modify(unit, parity_enable_reg, 2793 REG_PORT_ANY, parity_enable_field, 1) < 0) { 2794 return 0; 2795 } 2796 2797 } 2798 2799 } 2800 2801 2802 if(cache != NULL && CACHE_VMAP_TST(vmap, index)) { 2803 /* fill in the memory cache tlv */ 2804 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE, 2805 entry_dw*4, (cache + index*entry_dw)) < 0) { 2806 return 0; 2807 } 2808 } 2809 } else { 2810 id = soc_ser_log_create_entry(unit, log_entry_size); 2811 } 2812 2813 return id; 2814 } 2815 2816 STATIC int 2817 _soc_monterey_ser_process_parity(int unit, int block_info_idx, int pipe, 2818 int port, const _soc_monterey_ser_info_t *info, 2819 int schan, char *prefix_str, char *mem_str) 2820 { 2821 int rv; 2822 _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr; 2823 soc_reg_t reg; 2824 uint32 rval, minfo; 2825 uint32 multiple, entry_idx, idx, has_error; 2826 char *mem_str_ptr; 2827 _soc_ser_correct_info_t spci; 2828 2829 if (schan) { 2830 /* Some table does not have NACK register */ 2831 return SOC_E_NONE; 2832 } else { 2833 if (info->intr_status_reg != INVALIDr) { 2834 reg_entry[0].reg = info->intr_status_reg; 2835 reg_entry[0].mem_str = NULL; 2836 reg_entry[1].reg = INVALIDr; 2837 reg_ptr = reg_entry; 2838 } else if (info->intr_status_reg_list != NULL) { 2839 reg_ptr = info->intr_status_reg_list; 2840 } else { 2841 return SOC_E_NONE; 2842 } 2843 } 2844 2845 has_error = FALSE; 2846 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2847 reg = reg_ptr[idx].reg; 2848 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2849 reg_ptr[idx].mem_str : mem_str; 2850 SOC_IF_ERROR_RETURN 2851 (soc_reg32_get(unit, reg, port, 0, &rval)); 2852 2853 if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) { 2854 has_error = TRUE; 2855 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2856 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2857 _soc_monterey_mem_parity_info(unit, block_info_idx, pipe, 2858 info->group_reg_status_field, &minfo); 2859 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2860 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2861 entry_idx, minfo); 2862 LOG_ERROR(BSL_LS_SOC_COMMON, 2863 (BSL_META_U(unit, 2864 "%s %s entry %d parity error\n"), 2865 prefix_str, mem_str_ptr, entry_idx)); 2866 if (multiple) { 2867 LOG_ERROR(BSL_LS_SOC_COMMON, 2868 (BSL_META_U(unit, 2869 "%s %s has multiple parity errors\n"), 2870 prefix_str, mem_str_ptr)); 2871 } 2872 if (idx == 0 && info->mem != INVALIDm) { 2873 sal_memset(&spci, 0, sizeof(spci)); 2874 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 2875 if (multiple) { 2876 spci.flags |= SOC_SER_ERR_MULTI; 2877 } 2878 spci.reg = INVALIDr; 2879 spci.mem = info->mem; 2880 spci.blk_type = -1; 2881 spci.index = entry_idx; 2882 spci.parity_type = info->type; 2883 spci.detect_time = sal_time_usecs(); 2884 spci.log_id = _soc_monterey_populate_ser_log(unit, 2885 info->enable_reg, 2886 info->enable_field, 2887 spci.mem, 2888 SOC_MEM_BLOCK_ANY(unit, spci.mem), 2889 spci.acc_type, 2890 spci.index, 2891 spci.detect_time, 2892 spci.sblk, 2893 spci.addr); 2894 rv = soc_ser_correction(unit, &spci); 2895 if (spci.log_id != 0) { 2896 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2897 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 2898 spci.log_id, 0); 2899 } 2900 if (SOC_FAILURE(rv)) { 2901 /* Add reporting failed to correct event flag to 2902 * application */ 2903 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2904 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2905 entry_idx, minfo); 2906 return rv; 2907 } 2908 } 2909 } 2910 2911 /* Clear parity status */ 2912 SOC_IF_ERROR_RETURN 2913 (soc_reg32_set(unit, reg, port, 0, 0)); 2914 } 2915 2916 if (!has_error) { 2917 LOG_ERROR(BSL_LS_SOC_COMMON, 2918 (BSL_META_U(unit, 2919 "%s %s parity hardware inconsistency\n"), 2920 prefix_str, mem_str)); 2921 } 2922 2923 return SOC_E_NONE; 2924 } 2925 2926 STATIC int 2927 _soc_monterey_ser_process_ecc(int unit, int block_info_idx, int pipe, int port, 2928 const _soc_monterey_ser_info_t *info, 2929 int schan, char *prefix_str, char *mem_str) 2930 { 2931 int rv; 2932 _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr; 2933 soc_reg_t reg = INVALIDr; 2934 uint32 rval, minfo,has_error = 0; 2935 uint64 rval64; 2936 uint32 ecc_err, multiple, double_bit, entry_idx, idx; 2937 char *mem_str_ptr; 2938 _soc_ser_correct_info_t spci; 2939 2940 if (schan) { 2941 /* Some table does not have NACK register */ 2942 return SOC_E_NONE; 2943 } else { 2944 if (info->intr_status_reg != INVALIDr) { 2945 reg_entry[0].reg = info->intr_status_reg; 2946 reg_entry[0].mem_str = NULL; 2947 reg_entry[1].reg = INVALIDr; 2948 reg_ptr = reg_entry; 2949 } else if (info->intr_status_reg_list != NULL) { 2950 reg_ptr = info->intr_status_reg_list; 2951 } else { 2952 return SOC_E_NONE; 2953 } 2954 } 2955 2956 has_error = FALSE; 2957 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2958 reg = reg_ptr[idx].reg; 2959 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2960 reg_ptr[idx].mem_str : mem_str; 2961 if (SOC_REG_IS_64(unit, reg)) { 2962 SOC_IF_ERROR_RETURN 2963 (soc_reg64_get(unit, reg, port, 0, &rval64)); 2964 ecc_err = soc_reg64_field32_get(unit, reg, rval64, ECC_ERRf); 2965 multiple = soc_reg64_field32_get(unit, reg, rval64, MULTIPLE_ERRf); 2966 double_bit = soc_reg64_field32_get(unit, reg, rval64, DOUBLE_BIT_ERRf); 2967 entry_idx = soc_reg64_field32_get(unit, reg, rval64, ENTRY_IDXf); 2968 } else { 2969 SOC_IF_ERROR_RETURN 2970 (soc_reg32_get(unit, reg, port, 0, &rval)); 2971 ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf); 2972 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2973 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf); 2974 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2975 } 2976 2977 if (ecc_err) { 2978 has_error = TRUE; 2979 } 2980 _soc_monterey_mem_parity_info(unit, block_info_idx, pipe, 2981 info->group_reg_status_field, &minfo); 2982 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2983 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 2984 entry_idx, minfo); 2985 sal_memset(&spci, 0, sizeof(spci)); 2986 if (double_bit) { 2987 spci.double_bit = 1; 2988 LOG_ERROR(BSL_LS_SOC_COMMON, 2989 (BSL_META_U(unit, 2990 "%s %s entry %d double-bit ECC error\n"), 2991 prefix_str, mem_str_ptr, entry_idx)); 2992 } else { 2993 LOG_ERROR(BSL_LS_SOC_COMMON, 2994 (BSL_META_U(unit, 2995 "%s %s entry %d ECC error\n"), 2996 prefix_str, mem_str_ptr, entry_idx)); 2997 } 2998 if (multiple) { 2999 LOG_ERROR(BSL_LS_SOC_COMMON, 3000 (BSL_META_U(unit, 3001 "%s %s has multiple ECC errors\n"), 3002 prefix_str, mem_str_ptr)); 3003 } 3004 if (idx == 0 && info->mem != INVALIDm) { 3005 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 3006 if (multiple) { 3007 spci.flags |= SOC_SER_ERR_MULTI; 3008 } 3009 spci.reg = INVALIDr; 3010 spci.mem = info->mem; 3011 spci.blk_type = -1; 3012 spci.index = entry_idx; 3013 spci.parity_type = info->type; 3014 spci.detect_time = sal_time_usecs(); 3015 spci.log_id = _soc_monterey_populate_ser_log(unit, 3016 info->enable_reg, 3017 info->enable_field, 3018 spci.mem, 3019 SOC_MEM_BLOCK_ANY(unit, spci.mem), 3020 spci.acc_type, 3021 spci.index, 3022 spci.detect_time, 3023 spci.sblk, 3024 spci.addr); 3025 rv = soc_ser_correction(unit, &spci); 3026 if (spci.log_id != 0) { 3027 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3028 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3029 spci.log_id, 0); 3030 } 3031 if (SOC_FAILURE(rv)) { 3032 /* Add reporting failed to correct event flag to 3033 * application */ 3034 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3035 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3036 entry_idx, minfo); 3037 return rv; 3038 } 3039 } 3040 3041 if (SOC_REG_IS_64(unit, reg)) { 3042 COMPILER_64_ZERO(rval64); 3043 SOC_IF_ERROR_RETURN 3044 (soc_reg64_set(unit, reg, port, 0, rval64)); 3045 } else { 3046 SOC_IF_ERROR_RETURN 3047 (soc_reg32_set(unit, reg, port, 0, 0)); 3048 } 3049 } 3050 if (!has_error) { 3051 LOG_ERROR(BSL_LS_SOC_COMMON, 3052 (BSL_META_U(unit, 3053 "%s %s ECC hardware inconsistency\n"), 3054 prefix_str, mem_str)); 3055 } 3056 3057 return SOC_E_NONE; 3058 } 3059 3060 STATIC int 3061 _soc_monterey_ser_process_mac(int unit, int block_info_idx, int pipe, int port, 3062 const _soc_monterey_ser_info_t *info, 3063 int schan, char *prefix_str, char *mem_str) 3064 { 3065 _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr; 3066 soc_reg_t reg; 3067 soc_field_t single_bit_f, double_bit_f; 3068 uint64 rval; 3069 uint32 single_bit = 0, double_bit = 0, idx; 3070 char *mem_str_ptr; 3071 3072 if (schan) { 3073 /* Some table does not have NACK register */ 3074 return SOC_E_NONE; 3075 } else { 3076 if (info->intr_status_reg != INVALIDr) { 3077 reg_entry[0].reg = info->intr_status_reg; 3078 reg_entry[0].mem_str = NULL; 3079 reg_entry[1].reg = INVALIDr; 3080 reg_ptr = reg_entry; 3081 } else if (info->intr_status_reg_list != NULL) { 3082 reg_ptr = info->intr_status_reg_list; 3083 } else { 3084 return SOC_E_NONE; 3085 } 3086 } 3087 3088 switch (info->type) { 3089 case _SOC_PARITY_TYPE_MAC_TX_CDC: 3090 single_bit_f = TX_CDC_SINGLE_BIT_ERRf; 3091 double_bit_f = TX_CDC_DOUBLE_BIT_ERRf; 3092 break; 3093 case _SOC_PARITY_TYPE_MAC_RX_CDC: 3094 single_bit_f = RX_CDC_SINGLE_BIT_ERRf; 3095 double_bit_f = RX_CDC_DOUBLE_BIT_ERRf; 3096 break; 3097 case _SOC_PARITY_TYPE_MAC_RX_TS: 3098 single_bit_f = RX_TS_MEM_SINGLE_BIT_ERRf; 3099 double_bit_f = RX_TS_MEM_DOUBLE_BIT_ERRf; 3100 break; 3101 default: 3102 return SOC_E_PARAM; 3103 } 3104 3105 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 3106 reg = reg_ptr[idx].reg; 3107 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? reg_ptr[idx].mem_str : mem_str; 3108 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, reg, port, 0, &rval)); 3109 3110 single_bit = soc_reg64_field32_get(unit, reg, rval, single_bit_f); 3111 double_bit = soc_reg64_field32_get(unit, reg, rval, double_bit_f); 3112 if (single_bit || double_bit) { 3113 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3114 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0); 3115 if (double_bit) { 3116 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3117 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 3118 LOG_ERROR(BSL_LS_SOC_COMMON, 3119 (BSL_META_U(unit, 3120 "%s %s double-bit ECC error on port %d\n"), 3121 prefix_str, mem_str_ptr, port)); 3122 } else { 3123 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3124 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0); 3125 LOG_ERROR(BSL_LS_SOC_COMMON, 3126 (BSL_META_U(unit, 3127 "%s %s single-bit ECC error on port %d\n"), 3128 prefix_str, mem_str_ptr, port)); 3129 } 3130 } 3131 3132 /* Clear parity status by a rising edge on intr_clr_field in intr_clr_reg */ 3133 SOC_IF_ERROR_RETURN 3134 (soc_reg64_get(unit, info->intr_clr_reg, port, 0, &rval)); 3135 if (single_bit) { 3136 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 0); 3137 SOC_IF_ERROR_RETURN 3138 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 3139 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 1); 3140 SOC_IF_ERROR_RETURN 3141 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 3142 } 3143 if (double_bit) { 3144 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 0); 3145 SOC_IF_ERROR_RETURN 3146 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 3147 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 1); 3148 SOC_IF_ERROR_RETURN 3149 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 3150 } 3151 } 3152 3153 return SOC_E_NONE; 3154 } 3155 STATIC int 3156 _soc_monterey_ser_process_mib(int unit, int block_info_idx, int pipe, int port, 3157 const _soc_monterey_ser_info_t *info, 3158 int schan, char *prefix_str, char *mem_str) 3159 { 3160 _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr; 3161 soc_reg_t reg; 3162 uint32 rval; 3163 uint32 ecc_err, multiple, double_bit, entry_idx, idx, has_error; 3164 char *mem_str_ptr; 3165 if (schan) { 3166 /* Some table does not have NACK register */ 3167 return SOC_E_NONE; 3168 } else { 3169 if (info->intr_status_reg != INVALIDr) { 3170 reg_entry[0].reg = info->intr_status_reg; 3171 reg_entry[0].mem_str = NULL; 3172 reg_entry[1].reg = INVALIDr; 3173 reg_ptr = reg_entry; 3174 } else if (info->intr_status_reg_list != NULL) { 3175 reg_ptr = info->intr_status_reg_list; 3176 } else { 3177 return SOC_E_NONE; 3178 } 3179 } 3180 has_error = FALSE; 3181 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 3182 reg = reg_ptr[idx].reg; 3183 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 3184 reg_ptr[idx].mem_str : mem_str; 3185 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 3186 ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf); 3187 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 3188 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf); 3189 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 3190 if (ecc_err) { 3191 has_error = TRUE; 3192 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3193 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0); 3194 if (double_bit) { 3195 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3196 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 3197 entry_idx, 0); 3198 3199 LOG_ERROR(BSL_LS_SOC_COMMON, 3200 (BSL_META_U 3201 (unit, "%s %s double-bit ECC error on port %d\n"), 3202 prefix_str, mem_str_ptr, port)); 3203 } else { 3204 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3205 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 3206 entry_idx, 0); 3207 LOG_ERROR(BSL_LS_SOC_COMMON, 3208 (BSL_META_U 3209 (unit, "%s %s single-bit ECC error on port %d\n"), 3210 prefix_str, mem_str_ptr, port)); 3211 3212 } 3213 if (multiple) { 3214 LOG_ERROR(BSL_LS_SOC_COMMON, 3215 (BSL_META_U(unit, "%s %s has multiple ECC errors\n"), 3216 prefix_str, mem_str_ptr)); 3217 } 3218 if (double_bit) { 3219 /* Entry Idx: 3220 * 0-15 Port 0 3221 * 16-31 Port 1 3222 * 32-47 Port 2 3223 * 48-63 Port 3 3224 * In case of double-bit error we need to reset MIB counters 3225 * for that port to recover 3226 */ 3227 rval = 0x1 << ((entry_idx & 63) / 16); 3228 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, rval)); 3229 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, 0x0)); 3230 } 3231 } 3232 /* Clear parity status */ 3233 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, 0)); 3234 } 3235 if (!has_error) { 3236 LOG_ERROR(BSL_LS_SOC_COMMON, 3237 (BSL_META_U(unit, "%s %s ECC hardware inconsistency\n"), 3238 prefix_str, mem_str)); 3239 } 3240 return SOC_E_NONE; 3241 } 3242 3243 STATIC void 3244 _soc_monterey_ser_control_reg_get(int unit, 3245 void *fifo_ser_list, 3246 soc_mem_t mem, 3247 soc_reg_t *ser_control_reg, 3248 soc_field_t *ser_enable_field) 3249 { 3250 int i; 3251 _soc_mem_ser_en_info_t *ser_en_info = NULL; 3252 3253 if ((fifo_ser_list == NULL) || (ser_control_reg == NULL) || 3254 (ser_enable_field == NULL)) { 3255 return; 3256 } 3257 3258 ser_en_info = (_soc_mem_ser_en_info_t*)fifo_ser_list; 3259 for (i = 0; ser_en_info[i].mem != INVALIDm; i++) { 3260 if (ser_en_info[i].mem == mem) { 3261 *ser_control_reg = ser_en_info[i].en_ctrl.ctrl_type.en_reg; 3262 *ser_enable_field = ser_en_info[i].en_ctrl.en_fld; 3263 break; 3264 } 3265 } 3266 } 3267 3268 STATIC int 3269 _soc_monterey_ser_process_mmu_err (int unit, int block_info_idx, 3270 const _soc_monterey_ser_info_t *info, 3271 char *prefix_str) 3272 { 3273 uint32 rval, err, addr, bidx; 3274 uint64 rval64; 3275 soc_reg_t reg = MMU_MEM_FAIL_ADDR_64r; 3276 uint8 blk_idx; 3277 uint32 sblk = 0; 3278 int rv = SOC_E_NONE; 3279 _soc_ser_correct_info_t spci; 3280 soc_reg_t parity_enable_reg = INVALIDr; 3281 soc_field_t parity_enable_field = INVALIDf; 3282 3283 SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval)); 3284 if (soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)) { 3285 LOG_ERROR(BSL_LS_SOC_COMMON, 3286 (BSL_META_U(unit, 3287 "MMU SER interrupt with empty fifo !!\n"))); 3288 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval)); 3289 LOG_ERROR(BSL_LS_SOC_COMMON, 3290 (BSL_META_U(unit, 3291 "MMU ERR status: 0x%08x\n"), rval)); 3292 SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0)); 3293 return rv; 3294 } 3295 SOC_BLOCK_ITER(unit, blk_idx, SOC_BLK_MMU) { 3296 sblk = SOC_BLOCK2SCH(unit, blk_idx); 3297 break; 3298 } 3299 do { 3300 SOC_IF_ERROR_RETURN(READ_MMU_MEM_FAIL_ADDR_64r(unit, &rval64)); 3301 err = soc_reg64_field32_get(unit, reg, rval64, ERR_TYPEf); 3302 addr = soc_reg64_field32_get(unit, reg, rval64, EADDRf); 3303 bidx = soc_reg64_field32_get(unit, reg, rval64, BIDXf); 3304 3305 LOG_ERROR(BSL_LS_SOC_COMMON, 3306 (BSL_META_U(unit, 3307 "MMU ERR Type: %s, Addr: 0x%08x, module: %d\n"), 3308 (err == 1) ? "1B error" : "2B error", addr, bidx)); 3309 3310 /* Address reported in MMU_MEM_FAIL_ADDR_64 is the entry offset within 3311 * MMU sub block. The complete Sbus address is composed of MMU sub block 3312 * base address and offset within MMU sub block address space. 3313 */ 3314 addr = (bidx << 26) | addr; 3315 sal_memset(&spci, 0, sizeof(spci)); 3316 spci.flags |= SOC_SER_SRC_MEM; 3317 spci.reg = INVALIDr; 3318 spci.mem = INVALIDm; 3319 spci.acc_type = -1; 3320 spci.blk_type = SOC_BLK_MMU; 3321 spci.sblk = sblk; 3322 spci.detect_time = sal_time_usecs(); 3323 3324 /* Try to decode memory */ 3325 spci.mem = soc_addr_to_mem_extended(unit, sblk, _SOC_ACC_TYPE_PIPE_ANY, addr); 3326 if (spci.mem != INVALIDm) { 3327 spci.index = addr - soc_mem_base(unit, spci.mem); 3328 spci.flags |= SOC_SER_REG_MEM_KNOWN; 3329 _soc_monterey_ser_control_reg_get(unit, 3330 _soc_bcm56670_a0_mmu_mem_ser_info, 3331 spci.mem, 3332 &parity_enable_reg, 3333 &parity_enable_field); 3334 } else { 3335 spci.flags |= SOC_SER_REG_MEM_UNKNOWN; 3336 } 3337 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3338 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 3339 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr); 3340 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 3341 spci.log_id = _soc_monterey_populate_ser_log(unit, parity_enable_reg, 3342 parity_enable_field, 3343 spci.mem, blk_idx, 3344 _SOC_ACC_TYPE_PIPE_ANY, 3345 spci.index, 3346 spci.detect_time, spci.sblk, 3347 spci.addr); 3348 if ((spci.mem == INVALIDm) || 3349 (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != 0)) { 3350 rv = soc_ser_correction(unit, &spci); 3351 if (SOC_FAILURE(rv)) { 3352 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3353 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3354 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr); 3355 } 3356 } else { 3357 rv = SOC_E_NONE; 3358 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3359 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 3360 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr); 3361 } 3362 3363 if (spci.log_id != 0) { 3364 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3365 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3366 spci.log_id, 0); 3367 } 3368 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_CTRr(unit, &rval)); 3369 LOG_ERROR(BSL_LS_SOC_COMMON, 3370 (BSL_META_U(unit, 3371 "MMU ERR ctr: %d\n"), rval)); 3372 SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval)); 3373 } while (!soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)); 3374 SOC_IF_ERROR_RETURN 3375 (soc_reg_field32_modify(unit, info->intr_status_reg, REG_PORT_ANY, 3376 info->group_reg_status_field, 0)); 3377 3378 SOC_IF_ERROR_RETURN 3379 (soc_reg_field32_modify(unit, MEM_FAIL_INT_CLEARr, REG_PORT_ANY, 3380 info->group_reg_status_field, 1)); 3381 return rv; 3382 } 3383 3384 STATIC int 3385 _soc_monterey_ser_process_start_err(int unit, int block_info_idx, 3386 const _soc_monterey_ser_info_t *info, 3387 char *prefix_str) 3388 { 3389 soc_info_t *si; 3390 uint64 rval64; 3391 uint32 pbmp_31_0, pbmp_63_32; 3392 soc_pbmp_t pbmp; 3393 uint32 minfo ; 3394 int port, mmu_port, phy_port; 3395 soc_ser_log_tlv_generic_t log_generic; 3396 int log_id; 3397 3398 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 3399 3400 si = &SOC_INFO(unit); 3401 3402 /* mmu port 52-0 */ 3403 SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR_0r(unit, &rval64)); 3404 pbmp_31_0 = COMPILER_64_LO(rval64); 3405 pbmp_63_32 = COMPILER_64_HI(rval64); 3406 SOC_PBMP_CLEAR(pbmp); 3407 SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0); 3408 SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32); 3409 3410 SOC_PBMP_ITER(pbmp, mmu_port) { 3411 phy_port = si->port_m2p_mapping[mmu_port]; 3412 port = si->port_p2l_mapping[phy_port]; 3413 _soc_monterey_mem_parity_info(unit, block_info_idx, 0, 3414 info->group_reg_status_field, &minfo); 3415 /* Report uncorrectable event flag to application */ 3416 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3417 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 3418 minfo); 3419 3420 log_generic.time = sal_time_usecs(); 3421 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 3422 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 3423 log_generic.parity_type = info->type; 3424 3425 log_id = soc_ser_log_create_entry(unit, 3426 sizeof(soc_ser_log_tlv_generic_t) + 3427 sizeof(soc_ser_log_tlv_hdr_t) *2); 3428 3429 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 3430 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 3431 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3432 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 3433 LOG_ERROR(BSL_LS_SOC_COMMON, 3434 (BSL_META_U(unit, 3435 "%s port %d start error detected\n"), prefix_str, 3436 port)); 3437 } 3438 3439 /* Clear parity status */ 3440 COMPILER_64_ZERO(rval64); 3441 SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_0r(unit, rval64)); 3442 SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_1r(unit, rval64)); 3443 3444 return SOC_E_NONE; 3445 } 3446 3447 STATIC int 3448 _soc_monterey_process_ser (int unit, int block_info_idx, int inst, int pipe, 3449 int port, soc_reg_t group_reg, uint64 group_rval, 3450 const _soc_monterey_ser_info_t *info_list, 3451 char *prefix_str); 3452 3453 STATIC _soc_monterey_bst_hw_cb monterey_bst_cb; 3454 3455 STATIC int 3456 _soc_monterey_process_mmu_bst(int unit) 3457 { 3458 int rv = SOC_E_NONE; 3459 if (monterey_bst_cb) { 3460 rv = monterey_bst_cb(unit); 3461 } 3462 return rv; 3463 } 3464 3465 int soc_monterey_set_bst_callback(int unit, _soc_monterey_bst_hw_cb cb) 3466 { 3467 monterey_bst_cb = cb; 3468 return SOC_E_NONE; 3469 } 3470 3471 STATIC int 3472 _soc_monterey_ser_process_pm_ecc(int unit, int port, 3473 const _soc_monterey_pm_ecc_info_t *info) 3474 { 3475 3476 if (info->ecc_err_type) { 3477 3478 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3479 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0); 3480 3481 if (info->ecc_err_type & PORTMOD_PM_CPRI_ECC_ERR_1_BIT) { 3482 3483 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3484 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0); 3485 3486 LOG_ERROR(BSL_LS_SOC_COMMON, 3487 (BSL_META_U(unit, 3488 "\n%s[%s]\n\r " 3489 "single-bit ECC error on port %d\n"), 3490 info->mem_str, 3491 SOC_MEM_NAME(unit, info->mem), port)); 3492 3493 } else if (info->ecc_err_type & PORTMOD_PM_CPRI_ECC_ERR_2_BIT) { 3494 3495 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3496 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 3497 3498 LOG_ERROR(BSL_LS_SOC_COMMON, 3499 (BSL_META_U(unit, 3500 "\n%s[%s]\n\r " 3501 "double-bit ECC error on port %d\n"), 3502 info->mem_str, 3503 SOC_MEM_NAME(unit, info->mem), port)); 3504 3505 } else { 3506 3507 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 3508 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 3509 3510 LOG_ERROR(BSL_LS_SOC_COMMON, 3511 (BSL_META_U(unit, 3512 "\n%s[%s]\n\r " 3513 "multi-bit ECC error on port %d\n"), 3514 info->mem_str, 3515 SOC_MEM_NAME(unit, info->mem), port)); 3516 3517 } 3518 } 3519 3520 return SOC_E_NONE; 3521 } 3522 3523 STATIC int 3524 _soc_monterey_process_ser (int unit, int block_info_idx, int inst, int pipe, 3525 int port, soc_reg_t group_reg, uint64 group_rval, 3526 const _soc_monterey_ser_info_t *info_list, 3527 char *prefix_str) 3528 { 3529 const _soc_monterey_ser_info_t *info; 3530 int info_index; 3531 char *mem_str = "INVALIDm" ; 3532 uint32 minfo; 3533 soc_ser_log_tlv_generic_t log_generic; 3534 int log_id; 3535 3536 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 3537 3538 /* Loop through each info entry in the list */ 3539 for (info_index = 0; ; info_index++) { 3540 info = &info_list[info_index]; 3541 if (info->type == _SOC_PARITY_TYPE_NONE) { 3542 /* End of table */ 3543 break; 3544 } 3545 3546 /* Check status for the info entry in the group register */ 3547 if ((info->group_reg_status_field != INVALIDf) && 3548 (!soc_reg64_field32_get(unit, group_reg, group_rval, 3549 info->group_reg_status_field))) { 3550 continue; 3551 } 3552 3553 if (info->mem_str) { 3554 mem_str = info->mem_str; 3555 } else if (info->mem != INVALIDm) { 3556 mem_str = SOC_MEM_NAME(unit, info->mem); 3557 } else if (info->group_reg_status_field != INVALIDf) { 3558 3559 mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field); 3560 } 3561 3562 /* Handle different parity error reporting style */ 3563 switch (info->type) { 3564 case _SOC_PARITY_TYPE_GENERIC: 3565 _soc_monterey_mem_parity_info(unit, block_info_idx, 0, 3566 info->group_reg_status_field, &minfo); 3567 /* Report uncorrectable event flag to application */ 3568 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3569 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 3570 minfo); 3571 3572 log_generic.time = sal_time_usecs(); 3573 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 3574 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 3575 log_generic.parity_type = info->type; 3576 3577 log_id = soc_ser_log_create_entry(unit, 3578 sizeof(soc_ser_log_tlv_generic_t) + 3579 sizeof(soc_ser_log_tlv_hdr_t) *2); 3580 3581 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 3582 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 3583 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3584 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 3585 3586 LOG_ERROR(BSL_LS_SOC_COMMON, 3587 (BSL_META_U(unit, 3588 "%s %s asserted\n"), prefix_str, mem_str)); 3589 break; 3590 case _SOC_PARITY_TYPE_PARITY: 3591 /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */ 3592 SOC_IF_ERROR_RETURN 3593 (_soc_monterey_ser_process_parity(unit, block_info_idx, 3594 pipe, port, info, FALSE, 3595 prefix_str, mem_str)); 3596 break; 3597 case _SOC_PARITY_TYPE_ECC: 3598 /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */ 3599 SOC_IF_ERROR_RETURN 3600 (_soc_monterey_ser_process_ecc(unit, block_info_idx, pipe, 3601 port, info, FALSE, 3602 prefix_str, mem_str)); 3603 break; 3604 case _SOC_PARITY_TYPE_MIB: 3605 /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */ 3606 SOC_IF_ERROR_RETURN 3607 (_soc_monterey_ser_process_mib(unit, block_info_idx, pipe, 3608 port, info, FALSE, 3609 prefix_str, mem_str)); 3610 /* MIB_RX_MEM_ERR and MIB_TX_MEM_ERR in PORT_INTR_STATUS are write 1 to clear 3611 * So we write back the status we read. 3612 */ 3613 SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval)); 3614 break; 3615 case _SOC_PARITY_TYPE_MAC_TX_CDC: 3616 case _SOC_PARITY_TYPE_MAC_RX_CDC: 3617 case _SOC_PARITY_TYPE_MAC_RX_TS: 3618 /* xxx_SINGLE_BIT_ERRf, xxx_DOUBLE_BIT_ERRf */ 3619 SOC_IF_ERROR_RETURN 3620 (_soc_monterey_ser_process_mac(unit, block_info_idx, pipe, 3621 port, info, FALSE, 3622 prefix_str, mem_str)); 3623 /* MAC_RX_CDC_MEM_ERR, MAC_TX_CDC_MEM_ERR, MAC_RX_TS_CDC_MEM_ERR 3624 * in PORT_INTR_STATUS are write 1 to clear 3625 * So we write back the status we read. 3626 */ 3627 SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval)); 3628 break; 3629 case _SOC_PARITY_TYPE_START_ERR: 3630 SOC_IF_ERROR_RETURN 3631 (_soc_monterey_ser_process_start_err(unit, block_info_idx, 3632 info, prefix_str)); 3633 break; 3634 case _SOC_PARITY_TYPE_MMU_SER: 3635 SOC_IF_ERROR_RETURN 3636 (_soc_monterey_ser_process_mmu_err(unit, block_info_idx, 3637 info, prefix_str)); 3638 break; 3639 case _SOC_PARITY_TYPE_BST: 3640 SOC_IF_ERROR_RETURN(_soc_monterey_process_mmu_bst(unit)); 3641 break; 3642 case _SOC_PARITY_TYPE_OBM: 3643 SOC_IF_ERROR_RETURN(_soc_monterey_obm_interrupt_cb(unit)); 3644 break; 3645 default: 3646 break; 3647 } /* Handle different parity error reporting style */ 3648 } /* Loop through each info entry in the list */ 3649 3650 return SOC_E_NONE; 3651 } 3652 3653 STATIC char *_soc_monterey_ser_hwmem_base_info[] = { 3654 "CMIC PKT BUFFER - In Iarb", 3655 "CPU PKT BUFFER - In Iarb", 3656 "Invalid value", 3657 "EINITBUF_PACKET_BUFFER - In Iarb", 3658 "INGRESS PACKET BUFFER - In Ipars", 3659 "Invalid value", 3660 "Invalid value", 3661 "Invalid value", 3662 "Invalid value", 3663 "SW2_EOP_BUFFER_A - In Iesmif", 3664 "SW2_EOP_BUFFER_B - In Iesmif", 3665 "SW2_EOP_BUFFER_C - In Iesmif", 3666 "Invalid value", 3667 "Invalid value", 3668 "Invalid value", 3669 "Invalid value", 3670 "EP MPB DATA - In El3", 3671 "EP INITBUF - In Ehcpm", 3672 "CM DATA BUFFER - In Edatabuf", 3673 "XLP0 DATA BUFFER - In Edatabuf", 3674 "XLP1 DATA BUFFER - In Edatabuf", 3675 "XLP2 DATA BUFFER - In Edatabuf", 3676 "XLP3 DATA BUFFER - In Edatabuf", 3677 "XLP4 DATA BUFFER - In Edatabuf", 3678 "XLP5 DATA BUFFER - In Edatabuf", 3679 "XLP6 DATA BUFFER - In Edatabuf", 3680 "XLP7 DATA BUFFER - In Edatabuf", 3681 "XLP8 DATA BUFFER - In Edatabuf", 3682 "XLP9 DATA BUFFER - In Edatabuf", 3683 "XLP10 DATA BUFFER - In Edatabuf", 3684 "XLP11 DATA BUFFER - In Edatabuf", 3685 "XLP12 DATA BUFFER - In Edatabuf", 3686 "XLP13 DATA BUFFER - In Edatabuf", 3687 "CLP0 DATA BUFFER - In Edatabuf", 3688 "CLP1 DATA BUFFER - In Edatabuf", 3689 "CLP2 DATA BUFFER - In Edatabuf", 3690 "CLP3 DATA BUFFER - In Edatabuf", 3691 "XLP RESI0 DATA BUFFER - In Edatabuf", 3692 "XLP RESI1 DATA BUFFER - In Edatabuf", 3693 "XLP RESI2 DATA BUFFER - In Edatabuf", 3694 "XLP RESI3 DATA BUFFER - In Edatabuf", 3695 "Invalid value", 3696 "Invalid value", 3697 "Invalid value", 3698 "Invalid value", 3699 "Invalid value", 3700 "Invalid value", 3701 "Invalid value", 3702 "Invalid value", 3703 "XLP0 EDB CTRL BUFFER - In Edatabuf", 3704 "XLP1 EDB CTRL BUFFER - In Edatabuf", 3705 "XLP2 EDB CTRL BUFFER - In Edatabuf", 3706 "XLP3 EDB CTRL BUFFER - In Edatabuf", 3707 "XLP4 EDB CTRL BUFFER - In Edatabuf", 3708 "XLP5 EDB CTRL BUFFER - In Edatabuf", 3709 "XLP6 EDB CTRL BUFFER - In Edatabuf", 3710 "XLP7 EDB CTRL BUFFER - In Edatabuf", 3711 "XLP8 EDB CTRL BUFFER - In Edatabuf", 3712 "XLP9 EDB CTRL BUFFER - In Edatabuf", 3713 "XLP10 EDB CTRL BUFFER - In Edatabuf", 3714 "XLP11 EDB CTRL BUFFER - In Edatabuf", 3715 "XLP12 EDB CTRL BUFFER - In Edatabuf", 3716 "XLP13 EDB CTRL BUFFER - In Edatabuf", 3717 "XLP14 EDB CTRL BUFFER - In Edatabuf", 3718 "XLP15 EDB CTRL BUFFER - In Edatabuf", 3719 "CLP0 EDB CTRL BUFFER - In Edatabuf", 3720 "CLP1 EDB CTRL BUFFER - In Edatabuf", 3721 "CLP2 EDB CTRL BUFFER - In Edatabuf", 3722 "CLP3 EDB CTRL BUFFER - In Edatabuf", 3723 "LEARN FIFO - In IARB", 3724 "EGR VLAN BUS", 3725 "EGR HCPM BUS", 3726 "EGR PMOD BUS", 3727 "EGR FPPARS BUS", 3728 "EFP BUS", 3729 "IVP BUS", 3730 "ICFG BUS", 3731 "Invalid value", 3732 "Invalid value", 3733 "Invalid value", 3734 "Invalid value", 3735 "Invalid value", 3736 "Invalid value", 3737 "Invalid value", 3738 "Invalid value", 3739 "Invalid value", 3740 "IPARS BUS", 3741 "IVXLT BUS", 3742 "IMPLS BUS", 3743 "IL2L3 BUS", 3744 "Invalid value", 3745 "IFP BUS", 3746 "IRSEL1 BUS", 3747 "ISW1 BUS", 3748 "IRSEL2 BUS" 3749 }; 3750 3751 #define _SOC_MONTEREY_SER_REG 1 3752 #define _SOC_MONTEREY_SER_MEM 0 3753 3754 STATIC void 3755 _soc_monterey_print_ser_fifo_details (int unit, uint8 regmem, soc_block_t blk, 3756 uint32 sblk, int pipe, uint32 address, 3757 uint32 stage, uint32 base, uint32 index, 3758 uint32 hwmbase, uint32 type, uint32 drop, 3759 uint32 non_sbus) 3760 { 3761 uint32 hwmbase_max; 3762 3763 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityError, unit)) { 3764 switch (type) { 3765 case 0: 3766 LOG_ERROR(BSL_LS_SOC_COMMON, 3767 (BSL_META_U(unit, 3768 "Error in: SOP cell.\n"))); 3769 break; 3770 case 1: 3771 LOG_ERROR(BSL_LS_SOC_COMMON, 3772 (BSL_META_U(unit, 3773 "Error in: MOP cell.\n"))); 3774 break; 3775 case 2: 3776 LOG_ERROR(BSL_LS_SOC_COMMON, 3777 (BSL_META_U(unit, 3778 "Error in: EOP cell.\n"))); 3779 break; 3780 case 3: 3781 LOG_ERROR(BSL_LS_SOC_COMMON, 3782 (BSL_META_U(unit, 3783 "Error in: SBUS transaction.\n"))); 3784 break; 3785 case 4: 3786 LOG_ERROR(BSL_LS_SOC_COMMON, 3787 (BSL_META_U(unit, 3788 "Error in: miscellaneous transaction.\n"))); 3789 break; 3790 default: 3791 LOG_ERROR(BSL_LS_SOC_COMMON, 3792 (BSL_META_U(unit, 3793 "Invalid error reported !!\n"))); 3794 break; 3795 } 3796 LOG_ERROR(BSL_LS_SOC_COMMON, 3797 (BSL_META_U(unit, 3798 "Blk: %d, Pipe: %d, Address: 0x%08x, base: 0x%x, stage: %d, index: %d\n"), 3799 sblk, pipe, address, base, stage, index)); 3800 if (regmem == _SOC_MONTEREY_SER_MEM) { 3801 if (hwmbase >= 0x80) { 3802 hwmbase -= 0x28; /* handle the gap */ 3803 } 3804 if (non_sbus) { 3805 hwmbase_max = sizeof(_soc_monterey_ser_hwmem_base_info)/sizeof(_soc_monterey_ser_hwmem_base_info[0]); 3806 /* coverity[overrun-local] */ 3807 LOG_ERROR(BSL_LS_SOC_COMMON, 3808 (BSL_META_U(unit, 3809 "Mem hwbase: 0x%x [%s]\n"), hwmbase, 3810 (hwmbase < hwmbase_max) ? _soc_monterey_ser_hwmem_base_info[hwmbase] : "--")); 3811 } 3812 } 3813 if (drop) { 3814 LOG_ERROR(BSL_LS_SOC_COMMON, 3815 (BSL_META_U(unit, 3816 "SER caused packet drop.\n"))); 3817 } 3818 } 3819 } 3820 3821 #define IF_IPIPE_ARBITER_LOCK(_unit_, _blk_) \ 3822 if (_blk_ == SOC_BLK_IPIPE) {\ 3823 IP_ARBITER_LOCK(_unit_);\ 3824 } 3825 3826 #define IF_IPIPE_ARBITER_UNLOCK(_unit_, _blk_) \ 3827 if (_blk_ == SOC_BLK_IPIPE) {\ 3828 IP_ARBITER_UNLOCK(_unit_);\ 3829 } 3830 3831 static uint32 _monterey_ser_status_bus_fmt_get (uint32 *entry, int fld) 3832 { 3833 switch(fld) { 3834 case VALIDf: /* Bit 1*/ 3835 return (entry[0] & 0x00000001); 3836 case INSTRUCTION_TYPEf: /* Bits 1-4 */ 3837 return ((entry[0] & 0x0000001E) >> 1); 3838 case HWMEMBASEf: /* Bits 23-30 */ 3839 case MEMBASEf: 3840 return ((entry[0] & 0x7F800000) >> 23); 3841 case MEMINDEXf: /* Bits 5-22 */ 3842 return ((entry[0] & 0x007FFFE0) >> 5); 3843 case REGINDEXf: /* Bits 5-12 */ 3844 return ((entry[0] & 0x00001FE0) >> 5); 3845 case REGBASEf: /* Bits 13-29 */ 3846 return ((entry[0] & 0x3FFFE000) >> 13); 3847 case PIPE_STAGEf: /* Bits 31-36 */ 3848 return (((entry[0] & 0x80000000) >> 30) | 3849 ((entry[1] & 0x0000001F) << 1)); 3850 case ADDRESSf: /* Bits 36-5 */ 3851 return ((entry[0] >> 5) | 3852 ((entry[1] & 0x0000001F) << 27)); 3853 case DROPf: /* Bit 37 */ 3854 return (entry[1] & 0x00000020); 3855 case ECC_PARITYf: /* Bits 38-39 */ 3856 return ((entry[1] & 0x000000C0) >> 6); 3857 case MEM_TYPEf:/* Bit 40 */ 3858 return (entry[1] & 0x00000100); 3859 case NON_SBUSf: /* Bit 41 */ 3860 return (entry[1] & 0x00000200); 3861 case MULTIPLEf: /* Bit 42 */ 3862 return (entry[1] & 0x00000400); 3863 default: 3864 return -1; 3865 } 3866 } 3867 3868 int 3869 soc_monterey_mem_index_remap(int unit, int index, soc_mem_t *mem) 3870 { 3871 int logical_index = -1; 3872 switch (*mem) { 3873 case L3_DEFIPm: 3874 case L3_DEFIP_PAIR_128m: 3875 case L3_DEFIP_ONLYm: 3876 case L3_DEFIP_PAIR_128_ONLYm: 3877 case L3_DEFIP_DATA_ONLYm: 3878 case L3_DEFIP_PAIR_128_DATA_ONLYm: 3879 logical_index = soc_monterey_l3_defip_index_remap(unit, *mem, index); 3880 if (logical_index == -1) { 3881 /* This case arises when the passed index (physical) belongs 3882 * to wider view, but the passed mem is narrow view 3883 * Note that below API rewrites mem to the correct (wide) view. 3884 */ 3885 logical_index = soc_monterey_l3_defip_mem_index_get(unit, index, mem); 3886 } 3887 return logical_index; 3888 default: 3889 return index; 3890 } 3891 } 3892 3893 STATIC uint32 3894 _soc_monterey_flex_ctr_addr_check (int unit, uint32 address, soc_block_t blk, 3895 uint32 stage, uint32 index) 3896 { 3897 uint32 index2 = index; 3898 3899 3900 if ((SOC_BLK_IPIPE == blk) && (22 == stage)) { 3901 switch (address & 0xfffff000) { 3902 /* ING_FLEX_CTR_OFFSET_TABLE_*m */ 3903 case 0x56800000: 3904 case 0x56801000: 3905 case 0x56802000: 3906 case 0x56803000: 3907 case 0x56840000: 3908 case 0x56841000: 3909 case 0x56842000: 3910 case 0x56843000: 3911 index2 = address & 0x3ff; break; /* 1K depth */ 3912 /* ING_FLEX_CTR_COUNTER_TABLE_*m */ 3913 case 0x56804000: 3914 case 0x56808000: 3915 case 0x5680c000: 3916 case 0x56810000: 3917 case 0x56844000: 3918 case 0x56848000: 3919 case 0x5684c000: 3920 case 0x56850000: 3921 index2 = address & 0xfff; break; /* 4K depth */ 3922 default: 3923 break; 3924 } 3925 } 3926 3927 if ((SOC_BLK_EPIPE == blk) && (10 == stage)) { 3928 switch (address & 0XFFFFF000) { 3929 case 0x2a800000: 3930 case 0x2a801000: 3931 case 0x2a802000: 3932 case 0x2a803000: 3933 index2 = address & 0x3ff; break; /* 1K depth */ 3934 case 0x2a804000: 3935 case 0x2a808000: 3936 case 0x2a80c000: 3937 case 0x2a810000: 3938 index2 = address & 0xfff; break; /* 4K depth */ 3939 default: 3940 break; 3941 } 3942 } 3943 return index2; 3944 } 3945 3946 STATIC int 3947 _soc_monterey_process_ser_fifo (int unit, soc_block_t blk, char *prefix_str) 3948 { 3949 int rv; 3950 uint8 bidx; 3951 soc_mem_t mem; 3952 char blk_str[10]; 3953 void *ser_info_table = NULL; 3954 uint32 entry[SOC_MAX_MEM_WORDS], address = 0; 3955 uint32 reg_val = 0, mask = 0; 3956 uint32 stage = 0, addrbase = 0, index = 0, hwmbase = 0, type = 0; 3957 uint32 sblk = 0, regmem = 0, non_sbus = 0, drop = 0, ecc_parity = 0; 3958 soc_reg_t parity_enable_reg = INVALIDr; 3959 soc_field_t parity_enable_field = INVALIDf; 3960 _soc_ser_correct_info_t spci; 3961 soc_reg_t reg = INVALIDr; 3962 3963 switch (blk) { 3964 case SOC_BLK_IPIPE: 3965 mem = ING_SER_FIFOm; 3966 ser_info_table = _soc_bcm56670_a0_ip_mem_ser_info; 3967 sal_sprintf(blk_str, "IPIPE"); 3968 break; 3969 case SOC_BLK_EPIPE: 3970 mem = EGR_SER_FIFOm; 3971 ser_info_table = _soc_bcm56670_a0_ep_mem_ser_info; 3972 mask = 0x00000001; /* SER_FIFO_NON_EMPTYf */ 3973 reg = EGR_INTR_STATUSr; 3974 sal_sprintf(blk_str, "EPIPE"); 3975 break; 3976 default: 3977 return SOC_E_PARAM; 3978 } 3979 3980 IF_IPIPE_ARBITER_LOCK(unit, blk); 3981 do { 3982 sal_memset(&spci, 0, sizeof(spci)); 3983 rv = soc_mem_pop(unit, mem, MEM_BLOCK_ANY, entry); 3984 if (rv != SOC_E_NONE) { 3985 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3986 } 3987 SOC_IF_ERROR_RETURN(rv); 3988 /* process entry */ 3989 if (_monterey_ser_status_bus_fmt_get(entry,VALIDf)) { 3990 ecc_parity = _monterey_ser_status_bus_fmt_get(entry, ECC_PARITYf); 3991 regmem = _monterey_ser_status_bus_fmt_get(entry, MEM_TYPEf); 3992 address = _monterey_ser_status_bus_fmt_get(entry, ADDRESSf); 3993 stage = _monterey_ser_status_bus_fmt_get(entry, PIPE_STAGEf); 3994 type = _monterey_ser_status_bus_fmt_get(entry, INSTRUCTION_TYPEf); 3995 drop = _monterey_ser_status_bus_fmt_get(entry, DROPf); 3996 SOC_BLOCK_ITER(unit, bidx, blk) { 3997 sblk = SOC_BLOCK2SCH(unit, bidx); 3998 break; 3999 } 4000 LOG_ERROR(BSL_LS_SOC_COMMON, 4001 (BSL_META_U(unit, 4002 "%s\n"), prefix_str)); 4003 if (_monterey_ser_status_bus_fmt_get(entry, MULTIPLEf)) { 4004 LOG_ERROR(BSL_LS_SOC_COMMON, 4005 (BSL_META_U(unit, 4006 "Multiple: "))); 4007 } 4008 if (regmem == _SOC_MONTEREY_SER_REG ) { 4009 LOG_ERROR(BSL_LS_SOC_COMMON, 4010 (BSL_META_U(unit, 4011 "Reg: "))); 4012 } else { 4013 LOG_ERROR(BSL_LS_SOC_COMMON, 4014 (BSL_META_U(unit, 4015 "Mem: "))); 4016 } 4017 spci.double_bit = 0; 4018 switch (ecc_parity) { 4019 case 0: 4020 LOG_ERROR(BSL_LS_SOC_COMMON, 4021 (BSL_META_U(unit, 4022 "Parity error..\n"))); 4023 spci.parity_type = SOC_PARITY_TYPE_PARITY; 4024 break; 4025 4026 case 1: 4027 LOG_ERROR(BSL_LS_SOC_COMMON, 4028 (BSL_META_U(unit, 4029 "Corrected single bit ECC error..\n"))); 4030 spci.parity_type = SOC_PARITY_TYPE_ECC; 4031 break; 4032 case 2: 4033 LOG_ERROR(BSL_LS_SOC_COMMON, 4034 (BSL_META_U(unit, 4035 "Double or Multiple bit ECC error..\n"))); 4036 4037 spci.parity_type = SOC_PARITY_TYPE_ECC; 4038 spci.double_bit = 1; 4039 spci.flags |= SOC_SER_ERR_MULTI; 4040 4041 break; 4042 default: 4043 LOG_ERROR(BSL_LS_SOC_COMMON, 4044 (BSL_META_U(unit, 4045 "Invalid SER issue !!\n"))); 4046 4047 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 4048 return SOC_E_INTERNAL; 4049 } 4050 if (regmem == _SOC_MONTEREY_SER_MEM) { 4051 /* process mem */ 4052 non_sbus = _monterey_ser_status_bus_fmt_get(entry, NON_SBUSf); 4053 addrbase = _monterey_ser_status_bus_fmt_get(entry, MEMBASEf); 4054 index = _monterey_ser_status_bus_fmt_get(entry, MEMINDEXf); 4055 hwmbase = _monterey_ser_status_bus_fmt_get(entry, HWMEMBASEf); 4056 4057 4058 index = _soc_monterey_flex_ctr_addr_check(unit, address, blk, 4059 stage, index); 4060 if (non_sbus == 0) { 4061 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4062 ecc_parity == 0 ? 4063 SOC_SWITCH_EVENT_DATA_ERROR_PARITY : 4064 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 4065 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, 4066 address); 4067 _soc_monterey_print_ser_fifo_details(unit, 0, blk, sblk, 0, 4068 address, stage, addrbase, 4069 index, hwmbase, type, 4070 drop, non_sbus); 4071 spci.flags = SOC_SER_SRC_MEM; 4072 spci.reg = INVALIDr; 4073 spci.mem = INVALIDm; 4074 spci.blk_type = blk; 4075 spci.sblk = sblk; 4076 spci.addr = address - index; 4077 spci.index = index; 4078 spci.stage = stage; 4079 spci.detect_time = sal_time_usecs(); 4080 spci.mem = soc_addr_to_mem_extended(unit,spci.sblk, 4081 -1,spci.addr); 4082 if (spci.mem != INVALIDm) { 4083 spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 4084 spci.flags |= SOC_SER_REG_MEM_KNOWN; 4085 spci.index = soc_monterey_mem_index_remap(unit, index, &(spci.mem)); 4086 } 4087 else { 4088 /* Invalid mem, use the first acc_type_ptr*/ 4089 spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 4090 spci.flags |= SOC_SER_REG_MEM_UNKNOWN; 4091 } 4092 4093 if (spci.mem != INVALIDm) { 4094 _soc_monterey_ser_control_reg_get(unit, ser_info_table, 4095 spci.mem, 4096 &parity_enable_reg, 4097 &parity_enable_field); 4098 } 4099 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 4100 spci.log_id = _soc_monterey_populate_ser_log(unit, 4101 parity_enable_reg, 4102 parity_enable_field, 4103 spci.mem, 4104 bidx, 4105 spci.acc_type, 4106 spci.index, 4107 spci.detect_time, 4108 spci.sblk, 4109 spci.addr); 4110 4111 rv = soc_ser_correction(unit, &spci); 4112 if (SOC_FAILURE(rv)) { 4113 if (rv != SOC_E_NOT_FOUND) { 4114 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 4115 /* Add reporting failed to correct event flag to 4116 * application */ 4117 soc_event_generate(unit, 4118 SOC_SWITCH_EVENT_PARITY_ERROR, 4119 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 4120 sblk | 4121 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 4122 return rv; 4123 } 4124 } 4125 if (spci.log_id != 0) { 4126 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4127 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4128 spci.log_id, 0); 4129 } 4130 4131 } else { 4132 LOG_ERROR(BSL_LS_SOC_COMMON, 4133 (BSL_META_U(unit, 4134 "%s SER mem address un-accessable !!\n"), blk_str)); 4135 _soc_monterey_print_ser_fifo_details(unit, 0, blk, sblk, 0, address, 4136 stage, addrbase, index, hwmbase, 4137 type, drop, non_sbus); 4138 } 4139 } else { 4140 /* process reg */ 4141 non_sbus = _monterey_ser_status_bus_fmt_get(entry, NON_SBUSf); 4142 addrbase = _monterey_ser_status_bus_fmt_get(entry, REGBASEf); 4143 index = _monterey_ser_status_bus_fmt_get(entry, REGINDEXf); 4144 4145 if (non_sbus == 0) { 4146 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4147 ecc_parity == 0 ? 4148 SOC_SWITCH_EVENT_DATA_ERROR_PARITY : 4149 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 4150 sblk | 4151 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 4152 _soc_monterey_print_ser_fifo_details(unit, 1, blk, sblk, 0, 4153 address, stage, addrbase, 4154 index, 0, type, drop, 4155 non_sbus); 4156 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_UNKNOWN; 4157 spci.reg = INVALIDr; 4158 spci.mem = INVALIDm; 4159 spci.blk_type = blk; 4160 spci.sblk = sblk; 4161 spci.addr = address; 4162 spci.index = index; 4163 spci.stage = stage; 4164 spci.detect_time = sal_time_usecs(); 4165 spci.log_id = soc_ser_log_create_entry(unit, 4166 sizeof(soc_ser_log_tlv_generic_t) + 4167 sizeof(soc_ser_log_tlv_register_t) + 4168 sizeof(soc_ser_log_tlv_hdr_t) *3); 4169 rv = soc_ser_correction(unit, &spci); 4170 if (SOC_FAILURE(rv)) { 4171 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 4172 /* Add reporting failed to correct event flag to 4173 * application */ 4174 soc_event_generate(unit, 4175 SOC_SWITCH_EVENT_PARITY_ERROR, 4176 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 4177 sblk | 4178 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 4179 return rv; 4180 } 4181 if (spci.log_id != 0) { 4182 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 4183 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 4184 spci.log_id, 0); 4185 } 4186 } else { 4187 LOG_ERROR(BSL_LS_SOC_COMMON, 4188 (BSL_META_U(unit, 4189 "%s SER reg address un-accessable !!\n"), blk_str)); 4190 _soc_monterey_print_ser_fifo_details(unit, 0, blk, sblk, 0, 4191 address, stage, addrbase, 4192 index, hwmbase, type, 4193 drop, non_sbus); 4194 } 4195 } 4196 } else { 4197 LOG_ERROR(BSL_LS_SOC_COMMON, 4198 (BSL_META_U(unit, 4199 "unit %d Got invalid mem pop from %s !!\n"), 4200 unit, SOC_MEM_NAME(unit, mem))); 4201 } 4202 4203 if (rv != SOC_E_NONE) { 4204 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 4205 } 4206 4207 /* check if any more pending */ 4208 if (reg == INVALIDr) { 4209 rv = READ_CMIC_CMC0_IRQ_STAT2r(unit, ®_val); 4210 } else { 4211 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, ®_val); 4212 } 4213 SOC_IF_ERROR_RETURN(rv); 4214 } while (reg_val & mask); 4215 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 4216 4217 return SOC_E_NONE; 4218 } 4219 4220 STATIC int 4221 _soc_monterey_ser_process_irq3 (int unit, int bit_pos) 4222 { 4223 uint8 rbi; 4224 int port = REG_PORT_ANY; 4225 uint32 cmic_rval, cmic_bit; 4226 uint64 rb_enable64, rb_rval64, tmp64; 4227 const _soc_monterey_ser_route_block_t *rb; 4228 char prefix_str[10]; 4229 int block_info_idx; 4230 soc_stat_t *stat = SOC_STAT(unit); 4231 int ser_error = 0; 4232 int pgw_inst = 0 ; 4233 int pgw = 0; 4234 sal_sprintf(prefix_str, "Unit: %d \n", unit); 4235 4236 /* Read CMIC parity status register */ 4237 SOC_IF_ERROR_RETURN 4238 (READ_CMIC_CMC0_IRQ_STAT3r(unit, &cmic_rval)); 4239 if (cmic_rval == 0) { 4240 return SOC_E_NONE; 4241 } 4242 /* Loop through each place-and-route block entry */ 4243 for (rbi = 0; ; rbi++) { 4244 rb = &_soc_monterey_ser_route_blocks_irq3[rbi]; 4245 cmic_bit = rb->cmic_bit; 4246 if (cmic_bit == 0) { 4247 /* End of table */ 4248 break; 4249 } 4250 if (cmic_bit != (1 << bit_pos)) { 4251 continue; 4252 } 4253 if (!(cmic_rval & cmic_bit)) { 4254 /* No interrupt bit asserted for the route block */ 4255 continue; 4256 } 4257 if (rb->blocktype == SOC_BLK_IPIPE || rb->blocktype == SOC_BLK_EPIPE) { 4258 /* New fifo style processing */ 4259 (void)_soc_monterey_process_ser_fifo(unit, rb->blocktype, prefix_str); 4260 stat->ser_err_fifo++; 4261 } else { 4262 /* Legacy processing */ 4263 4264 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 4265 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 4266 port = SOC_BLOCK_PORT(unit, block_info_idx); 4267 break; 4268 } 4269 } 4270 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 4271 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 4272 /* This port block is not configured */ 4273 LOG_ERROR(BSL_LS_SOC_COMMON, 4274 (BSL_META_U(unit, 4275 "unit %d SER error on disabled port block %d !!\n"), 4276 unit, block_info_idx)); 4277 sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */ 4278 continue; 4279 } 4280 if(rb->blocktype == SOC_BLK_PGW_CL) { 4281 for ( pgw = 0; pgw <= 1; pgw++) 4282 { 4283 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 4284 SOC_IF_ERROR_RETURN 4285 (soc_reg_get(unit, rb->status_reg, pgw_inst, 0, &rb_rval64)); 4286 if (!COMPILER_64_IS_ZERO(rb_rval64)) { 4287 ser_error = 1; 4288 break; 4289 } 4290 } 4291 if(!ser_error) 4292 { 4293 continue; 4294 } 4295 4296 } else { 4297 /* Read per route block parity status register */ 4298 SOC_IF_ERROR_RETURN 4299 (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64)); 4300 if (COMPILER_64_IS_ZERO(rb_rval64)) { 4301 continue; 4302 } 4303 } 4304 SOC_IF_ERROR_RETURN 4305 (_soc_monterey_process_ser(unit, block_info_idx, rb->id, -1, 4306 port, rb->status_reg, rb_rval64, 4307 rb->info, prefix_str)); 4308 4309 SOC_IF_ERROR_RETURN 4310 (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64)); 4311 COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64)); 4312 COMPILER_64_NOT(tmp64); 4313 COMPILER_64_AND(rb_enable64, tmp64); 4314 SOC_IF_ERROR_RETURN 4315 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4316 COMPILER_64_OR(rb_enable64, rb_rval64); 4317 SOC_IF_ERROR_RETURN 4318 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4319 4320 stat->ser_err_int++; 4321 } 4322 } 4323 return SOC_E_NONE; 4324 } 4325 4326 STATIC int 4327 _soc_monterey_ser_process_irq4 (int unit, int bit_pos) 4328 { 4329 uint8 rbi; 4330 int port = REG_PORT_ANY; 4331 uint32 cmic_rval, cmic_bit; 4332 uint64 rb_enable64, rb_rval64, tmp64; 4333 char prefix_str[10]; 4334 int block_info_idx; 4335 soc_stat_t *stat = SOC_STAT(unit); 4336 4337 const _soc_monterey_ser_route_block_t *rb; 4338 4339 sal_sprintf(prefix_str, "\nUnit: %d: ", unit); 4340 4341 /* Read CMIC parity status register */ 4342 SOC_IF_ERROR_RETURN 4343 (READ_CMIC_CMC0_IRQ_STAT4r(unit, &cmic_rval)); 4344 if (cmic_rval == 0) { 4345 return SOC_E_NONE; 4346 } 4347 4348 /* Loop through each place-and-route block entry */ 4349 for (rbi = 0; ; rbi++) { 4350 rb = &_soc_monterey_ser_route_blocks_irq4[rbi]; 4351 cmic_bit = rb->cmic_bit; 4352 if (cmic_bit == 0) { 4353 /* End of table */ 4354 break; 4355 } 4356 if (cmic_bit != (1 << bit_pos)) { 4357 continue; 4358 } 4359 if (!(cmic_rval & cmic_bit)) { 4360 /* No interrupt bit asserted for the route block */ 4361 continue; 4362 } 4363 4364 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 4365 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 4366 port = SOC_BLOCK_PORT(unit, block_info_idx); 4367 break; 4368 } 4369 } 4370 4371 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 4372 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 4373 /* This port block is not configured */ 4374 LOG_ERROR(BSL_LS_SOC_COMMON, 4375 (BSL_META_U(unit, 4376 "unit %d SER error on disabled port block %d !!\n"), 4377 unit, block_info_idx)); 4378 sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */ 4379 continue; 4380 } 4381 4382 /* Read per route block parity status register */ 4383 SOC_IF_ERROR_RETURN 4384 (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64)); 4385 if (COMPILER_64_IS_ZERO(rb_rval64)) { 4386 continue; 4387 } 4388 4389 SOC_IF_ERROR_RETURN 4390 (_soc_monterey_process_ser(unit, block_info_idx, rb->id, -1, 4391 port, rb->status_reg, rb_rval64, 4392 rb->info, prefix_str)); 4393 SOC_IF_ERROR_RETURN 4394 (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64)); 4395 COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64)); 4396 COMPILER_64_NOT(tmp64); 4397 COMPILER_64_AND(rb_enable64, tmp64); 4398 SOC_IF_ERROR_RETURN 4399 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4400 COMPILER_64_OR(rb_enable64, rb_rval64); 4401 SOC_IF_ERROR_RETURN 4402 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4403 4404 stat->ser_err_int++; 4405 } 4406 4407 return SOC_E_NONE; 4408 } 4409 4410 #define IRQ3_STATUS_REG 3 4411 #define IRQ4_STATUS_REG 4 4412 STATIC int 4413 _soc_monterey_ser_process_all (int unit, int top_irq, int bit_pos) 4414 { 4415 switch (top_irq) { 4416 case IRQ3_STATUS_REG: 4417 SOC_IF_ERROR_RETURN(_soc_monterey_ser_process_irq3(unit,bit_pos)); 4418 break; 4419 case IRQ4_STATUS_REG: 4420 SOC_IF_ERROR_RETURN(_soc_monterey_ser_process_irq4(unit,bit_pos)); 4421 break; 4422 default: 4423 return SOC_E_INTERNAL; /* Shouldn't come here */ 4424 } 4425 4426 return SOC_E_NONE; 4427 } 4428 4429 void 4430 soc_monterey_ser_set_long_delay(int delay) 4431 { 4432 _monterey_ser_delay = delay; 4433 return; 4434 } 4435 4436 STATIC void 4437 soc_monterey_ser_error (void *unit_vp, void *d1, 4438 void *d2, void *d3, void *d4) 4439 { 4440 int unit = PTR_TO_INT(unit_vp); 4441 int irq_reg = PTR_TO_INT(d3); 4442 int old_mask = 0; 4443 4444 (void)_soc_monterey_ser_process_all(unit,irq_reg,PTR_TO_INT(d4)); 4445 4446 sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : (_monterey_ser_delay != 0 ? 10000000 : 100000)); 4447 4448 if (d2 != NULL) { 4449 old_mask = PTR_TO_INT(d2); 4450 if (irq_reg == 3) { 4451 (void)soc_cmicm_intr3_enable(unit, old_mask); 4452 } else if (irq_reg == 4) { 4453 (void)soc_cmicm_intr4_enable(unit, old_mask); 4454 } 4455 } 4456 /* soc_intr_enable(unit, IRQ_MEM_FAIL); */ 4457 } 4458 4459 /* SER processing for TCAMs */ 4460 static _soc_generic_ser_info_t _soc_monterey_tcam_ser_info_template[] = { 4461 /* HW SER engine protection */ 4462 { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4463 _SOC_SER_INTERLEAVE_MOD2, 4464 { {0, 97}, {1, 97}, {98, 193}, {99, 193} }, 0, 0, 0, 0, 4465 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA | 4466 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY}, 4467 { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY, 4468 _SOC_SER_PARITY_8BITS, 4469 _SOC_SER_INTERLEAVE_NONE, 4470 { {0, 99}, {100, 195}, {196, 291}, {292, 387} }, 0, 0, 0, 0, 4471 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA | 4472 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY}, 4473 { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4474 _SOC_SER_INTERLEAVE_MOD2, 4475 { {0, 165}, {1, 165}, {166, 353}, {167, 353} }, 0, 0, 0, 0, 4476 _SOC_SER_FLAG_XY_READ}, 4477 { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4478 _SOC_SER_INTERLEAVE_MOD2, 4479 { {0, 237}, {1, 237}, {238, 473}, {239, 473} }, 0, 0, 0, 0, 4480 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA}, 4481 { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4482 _SOC_SER_INTERLEAVE_MOD2, 4483 { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0, 4484 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA}, 4485 { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4486 _SOC_SER_INTERLEAVE_MOD2, 4487 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4488 _SOC_SER_FLAG_XY_READ}, 4489 { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4490 _SOC_SER_INTERLEAVE_MOD2, 4491 { {0, 145}, {2, 145}, {146, 289}, {148, 289} }, 0, 0, 0, 0, 4492 _SOC_SER_FLAG_XY_READ}, 4493 { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4494 _SOC_SER_INTERLEAVE_MOD2, 4495 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4496 _SOC_SER_FLAG_XY_READ}, 4497 4498 { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4499 _SOC_SER_INTERLEAVE_MOD2, 4500 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4501 _SOC_SER_FLAG_XY_READ}, 4502 { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4503 _SOC_SER_PARITY_4BITS, 4504 _SOC_SER_INTERLEAVE_MOD2, 4505 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4506 _SOC_SER_FLAG_XY_READ}, 4507 { FP_UDF_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4508 _SOC_SER_INTERLEAVE_MOD2, 4509 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4510 _SOC_SER_FLAG_XY_READ}, 4511 { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS, 4512 _SOC_SER_INTERLEAVE_MOD2, 4513 { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0, 4514 _SOC_SER_FLAG_XY_READ}, 4515 { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4516 _SOC_SER_PARITY_4BITS, 4517 _SOC_SER_INTERLEAVE_MOD2, 4518 { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0, 4519 _SOC_SER_FLAG_XY_READ}, 4520 4521 /* SW memscan SER engine protection */ 4522 { UDF_CONDITIONAL_CHECK_TABLE_CAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4523 _SOC_SER_PARITY_4BITS, 4524 _SOC_SER_INTERLEAVE_MOD2, 4525 { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0, 4526 _SOC_SER_FLAG_XY_READ}, 4527 { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 4528 _SOC_SER_PARITY_4BITS, 4529 _SOC_SER_INTERLEAVE_MOD2, 4530 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4531 _SOC_SER_FLAG_XY_READ}, 4532 /* Below memories have SW memscan SER engine protection */ 4533 { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4534 -1, -1, 4535 { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0, 4536 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE | 4537 _SOC_SER_FLAG_OVERLAY}, 4538 { FP_GM_FIELDSm, INVALIDm, _SOC_SER_TYPE_PARITY, 4539 -1, -1, 4540 { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0, 4541 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE | 4542 _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE}, 4543 #ifdef INCLUDE_XFLOW_MACSEC 4544 { ISEC_SP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4545 -1, -1, 4546 { {0, 239}, {1, 239}, {240, 480}, {241, 480} }, 0, 0, 0, 0, 4547 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE 4548 }, 4549 { ISEC_SC_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4550 -1, -1, 4551 { {0, 75}, {2, 75}, {76,153 }, {78, 153} }, 0, 0, 0, 0, 4552 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE 4553 }, 4554 #endif 4555 { INVALIDm }, 4556 }; 4557 4558 static _soc_generic_ser_info_t *_soc_monterey_tcam_ser_info[SOC_MAX_NUM_DEVICES]; 4559 4560 STATIC int 4561 _soc_monterey_tcam_ser_init (int unit) 4562 { 4563 int alloc_size; 4564 4565 /* First, make per-unit copy of the master TCAM list */ 4566 alloc_size = sizeof(_soc_monterey_tcam_ser_info_template); 4567 if (NULL == _soc_monterey_tcam_ser_info[unit]) { 4568 if ((_soc_monterey_tcam_ser_info[unit] = 4569 sal_alloc(alloc_size, "monterey tcam list")) == NULL) { 4570 return SOC_E_MEMORY; 4571 } 4572 } 4573 4574 /* Make a fresh copy of the TCAM template info */ 4575 sal_memcpy(_soc_monterey_tcam_ser_info[unit], 4576 &(_soc_monterey_tcam_ser_info_template), 4577 alloc_size); 4578 4579 return soc_generic_ser_init(unit, _soc_monterey_tcam_ser_info[unit]); 4580 } 4581 4582 STATIC void 4583 soc_monterey_ser_fail (int unit) 4584 { 4585 soc_generic_ser_process_error(unit, _soc_monterey_tcam_ser_info[unit], 4586 _SOC_PARITY_TYPE_SER); 4587 } 4588 4589 4590 int 4591 soc_monterey_mem_config(int unit) 4592 { 4593 soc_persist_t *sop; 4594 int l2_entries, cfg_l2_entries; 4595 int l3_entries, cfg_l3_entries; 4596 int min_l2_entries; 4597 int min_l3_entries; 4598 int max_l2_entries; 4599 int max_l3_entries; 4600 int num_ecmp_rh_flowset_entries; 4601 int num_ipv6_128b_entries = 0; 4602 int config_v6_entries = 0; 4603 int defip_config = 0; 4604 uint16 dev_id; 4605 uint8 rev_id; 4606 4607 sop = SOC_PERSIST(unit); 4608 soc_cm_get_id(unit, &dev_id, &rev_id); 4609 4610 min_l2_entries = 32; /* 32K dedicated L2 entries */ 4611 min_l3_entries = 8; /* 8K dedicated L3 entries */ 4612 max_l2_entries = 32; /* Dedicated (32K) + Shared (0)*/ 4613 max_l3_entries = 8; /* Dedicated (8K) + Shared (0)*/ 4614 4615 if (SAL_BOOT_SIMULATION) { 4616 /* 4617 * Smaller table lengths for BCMSIM environment. 4618 */ 4619 max_l2_entries = min_l2_entries; 4620 max_l3_entries = min_l3_entries; 4621 } 4622 4623 cfg_l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, -1); 4624 l2_entries = cfg_l2_entries == -1 ? max_l2_entries * 1024 : cfg_l2_entries; 4625 4626 if (l2_entries <= min_l2_entries * 1024) { /* Min table size */ 4627 l2_entries = min_l2_entries * 1024; 4628 } else if (l2_entries <= max_l2_entries * 1024) { 4629 /* 4630 * COVERITY 4631 * Future chips may have different min, max. Hence not removing it. 4632 */ 4633 /* coverity[dead_error_line] */ 4634 l2_entries = min_l2_entries * 1024 ; 4635 } else { 4636 LOG_CLI((BSL_META_U(unit, 4637 "The specified l2_mem_entries (%d) exceeds 272K\n"), 4638 cfg_l2_entries)); 4639 return SOC_E_PARAM; 4640 } 4641 4642 cfg_l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, -1); 4643 l3_entries = cfg_l3_entries == -1 ? (min_l3_entries * 1024 ) : cfg_l3_entries; 4644 if (l3_entries <= min_l3_entries * 1024) { /* 4k dedicated L3 entries */ 4645 l3_entries = min_l3_entries * 1024; 4646 } else if (l3_entries <= max_l3_entries * 1024) { 4647 /* 4648 * COVERITY 4649 * Future chips may have different min, max. Hence not removing it. 4650 */ 4651 /* coverity[dead_error_line] */ 4652 l3_entries = min_l3_entries * 1024 ; 4653 } else { 4654 LOG_CLI((BSL_META_U(unit, 4655 "The specified l3_mem_entries (%d) exceeds 260K\n"), 4656 cfg_l3_entries)); 4657 return SOC_E_PARAM; 4658 } 4659 4660 4661 4662 /* Adjust L2 table size */ 4663 sop->memState[L2Xm].index_max = l2_entries - 1; 4664 sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1; 4665 sop->memState[L2_ENTRY_ONLY_ECCm].index_max = l2_entries - 1; 4666 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1; 4667 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1; 4668 sop->memState[L2_ENTRY_LPm].index_max = min_l2_entries*1024 / 4 - 1; 4669 sop->memState[L2_ENTRY_ISS_LPm].index_max = 4670 (l2_entries - min_l2_entries*1024) / 4 - 1; 4671 4672 /* Adjust L3 table size */ 4673 sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1; 4674 sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1; 4675 sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = l3_entries / 2 - 1; 4676 sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = l3_entries/ 2 - 1; 4677 sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = l3_entries / 4 - 1; 4678 sop->memState[L3_ENTRY_ONLY_ECCm].index_max = l3_entries - 1; 4679 sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1; 4680 sop->memState[L3_ENTRY_LPm].index_max = min_l3_entries*1024 / 4 - 1; 4681 sop->memState[L3_ENTRY_ISS_LPm].index_max = 4682 (l3_entries - min_l3_entries*1024) / 4 - 1; 4683 4684 4685 /* LAG and ECMP resilient hashing features share the same flow set table. 4686 * The table can be configured in one of 3 modes: 4687 * - dedicated to LAG resilient hashing, 4688 * - dedicated to ECMP resilient hashing, 4689 * - split evenly between LAG and ECMP resilient hashing. 4690 */ 4691 num_ecmp_rh_flowset_entries = soc_property_get(unit, 4692 spn_ECMP_RESILIENT_HASH_SIZE, 512); 4693 switch (num_ecmp_rh_flowset_entries) { 4694 case 0: 4695 sop->memState[RH_ECMP_FLOWSETm].index_max = -1; 4696 break; 4697 case 512: 4698 sop->memState[RH_LAG_FLOWSETm].index_max /= 2; 4699 sop->memState[RH_ECMP_FLOWSETm].index_max /= 2; 4700 break; 4701 case 1024: 4702 sop->memState[RH_LAG_FLOWSETm].index_max = -1; 4703 break; 4704 default: 4705 return SOC_E_CONFIG; 4706 } 4707 4708 if (!soc_feature(unit, soc_feature_lpm_tcam)) { 4709 SOC_CONTROL(unit)->l3_defip_max_tcams = 0; 4710 } else if (soc_feature(unit, soc_feature_l3_2k_defip_table)) { 4711 SOC_CONTROL(unit)->l3_defip_max_tcams = 2; 4712 } else { 4713 SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_MONTEREY_DEFIP_MAX_TCAMS; 4714 } 4715 SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_MONTEREY_DEFIP_TCAM_DEPTH; 4716 4717 if (!soc_feature(unit, soc_feature_lpm_tcam)) { 4718 /* LPM is disabled, disable all L3_DEFIP memories */ 4719 sop->memState[L3_DEFIPm].index_max = -1; 4720 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1; 4721 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1; 4722 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1; 4723 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1; 4724 sop->memState[L3_DEFIP_ONLYm].index_max = -1; 4725 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = -1; 4726 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = -1; 4727 SOC_CONTROL(unit)->l3_defip_index_remap = 0; 4728 } else if (soc_property_get(unit, "l3_defip_sizing", TRUE)) { 4729 if (!soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) { 4730 defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1); 4731 4732 num_ipv6_128b_entries = soc_property_get(unit, 4733 spn_NUM_IPV6_LPM_128B_ENTRIES, 4734 (defip_config ? 128 : 0)); 4735 num_ipv6_128b_entries = num_ipv6_128b_entries + 4736 (num_ipv6_128b_entries % 2); 4737 4738 config_v6_entries = num_ipv6_128b_entries; 4739 if (soc_property_get(unit, spn_LPM_SCALING_ENABLE, 0)) { 4740 num_ipv6_128b_entries = 0; 4741 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED, 1)) { 4742 config_v6_entries = ((config_v6_entries / 4743 SOC_CONTROL(unit)->l3_defip_tcam_size) + 4744 ((config_v6_entries % 4745 SOC_CONTROL(unit)->l3_defip_tcam_size) 4746 ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size; 4747 } 4748 } 4749 sop->memState[L3_DEFIP_PAIR_128m].index_max = 4750 num_ipv6_128b_entries - 1; 4751 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 4752 num_ipv6_128b_entries - 1; 4753 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 4754 num_ipv6_128b_entries - 1; 4755 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 4756 num_ipv6_128b_entries - 1; 4757 sop->memState[L3_DEFIPm].index_max = 4758 (SOC_CONTROL(unit)->l3_defip_max_tcams * 4759 SOC_CONTROL(unit)->l3_defip_tcam_size) - 4760 (num_ipv6_128b_entries * 2) - 1; 4761 4762 sop->memState[L3_DEFIP_ONLYm].index_max = 4763 sop->memState[L3_DEFIPm].index_max; 4764 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 4765 sop->memState[L3_DEFIPm].index_max; 4766 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 4767 sop->memState[L3_DEFIPm].index_max; 4768 SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries; 4769 } else { 4770 if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) { 4771 /* slightly different processing for v6-128 */ 4772 num_ipv6_128b_entries = soc_property_get(unit, 4773 spn_NUM_IPV6_LPM_128B_ENTRIES, 4774 128); 4775 num_ipv6_128b_entries = num_ipv6_128b_entries + 4776 (num_ipv6_128b_entries % 2); 4777 config_v6_entries = num_ipv6_128b_entries; 4778 sop->memState[L3_DEFIP_PAIR_128m].index_max = 4779 num_ipv6_128b_entries - 1; 4780 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 4781 num_ipv6_128b_entries - 1; 4782 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 4783 num_ipv6_128b_entries - 1; 4784 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 4785 num_ipv6_128b_entries - 1; 4786 sop->memState[L3_DEFIPm].index_max = 4787 (SOC_CONTROL(unit)->l3_defip_max_tcams * 4788 SOC_CONTROL(unit)->l3_defip_tcam_size) - 4789 (num_ipv6_128b_entries * 2) - 1; 4790 4791 sop->memState[L3_DEFIP_ONLYm].index_max = 4792 sop->memState[L3_DEFIPm].index_max; 4793 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 4794 sop->memState[L3_DEFIPm].index_max; 4795 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 4796 sop->memState[L3_DEFIPm].index_max; 4797 4798 SOC_CONTROL(unit)->l3_defip_index_remap = 4799 (num_ipv6_128b_entries / 2) * 2; 4800 } else { 4801 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1; 4802 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1; 4803 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1; 4804 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1; 4805 } 4806 } 4807 soc_l3_defip_indexes_init(unit, config_v6_entries); 4808 } 4809 4810 if (NULL == _soc_monterey_alpm_bkt_view_map[unit]) { 4811 if ((_soc_monterey_alpm_bkt_view_map[unit] = 4812 sal_alloc(sizeof(soc_mem_t) * SOC_MONTEREY_ALPM_MAX_BKTS, 4813 "alpm_bkt_map")) == NULL) { 4814 return SOC_E_MEMORY; 4815 } 4816 } 4817 4818 memset(_soc_monterey_alpm_bkt_view_map[unit], INVALIDm, 4819 sizeof(soc_mem_t) * SOC_MONTEREY_ALPM_MAX_BKTS); 4820 4821 return SOC_E_NONE; 4822 } 4823 4824 int soc_monterey_get_alpm_banks(int unit) 4825 { 4826 int rv = SOC_E_NONE; 4827 soc_reg_t reg = ISS_LOG_TO_PHY_BANK_MAP_2r; 4828 uint32 bank_mode = 0; 4829 uint32 map = 0; 4830 4831 if (_soc_mn_num_shared_alpm_banks[unit] == 0) { 4832 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &map); 4833 if (rv >= 0) { 4834 bank_mode = soc_reg_field_get(unit, reg, map, ALPM_BANK_MODEf); 4835 } 4836 4837 if (bank_mode == 1) { 4838 _soc_mn_num_shared_alpm_banks[unit] = 2; 4839 } else { 4840 _soc_mn_num_shared_alpm_banks[unit] = 4; 4841 } 4842 } 4843 4844 return _soc_mn_num_shared_alpm_banks[unit]; 4845 } 4846 4847 int 4848 soc_monterey_alpm_mode_get(int unit) 4849 { 4850 return _soc_alpm_mode[unit]; 4851 } 4852 4853 #define _MONTEREY_INDEX_1K_ENTRIES 1024 4854 #define _MONTEREY_INDEX_2K_ENTRIES 2048 4855 #define _MONTEREY_INDEX_3K_ENTRIES 3072 4856 #define _MONTEREY_INDEX_4K_ENTRIES 4096 4857 #define _MONTEREY_INDEX_6K_ENTRIES 6144 4858 4859 /* Map logical (always starts from 0 and contiguous) index to physical index 4860 which can have a starting offset and/or holes. 4861 Input : logical index 4862 Returns: physical index */ 4863 int 4864 soc_monterey_l3_defip_index_map (int unit, soc_mem_t mem, int index) 4865 { 4866 int wide = 0; 4867 int alpm_mode = _soc_alpm_mode[unit]; 4868 int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf; 4869 int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap; 4870 4871 /* don't remap for ALPM */ 4872 if (defip128_tbl_sz == 0) { 4873 return index; 4874 } 4875 4876 if (mem == L3_DEFIP_PAIR_128m || 4877 mem == L3_DEFIP_PAIR_128_ONLYm || 4878 mem == L3_DEFIP_PAIR_128_DATA_ONLYm || 4879 mem == L3_DEFIP_PAIR_128_HIT_ONLYm) { 4880 wide = 1; 4881 } 4882 4883 if (alpm_mode == 2) { 4884 if (is_urpf_mode) { 4885 if (wide == 0) { 4886 if (index >= _MONTEREY_INDEX_2K_ENTRIES) { 4887 return index + (defip128_tbl_sz * 2); 4888 } 4889 return index + defip128_tbl_sz; 4890 } else { 4891 if (index >= _MONTEREY_INDEX_1K_ENTRIES) { 4892 return index + defip128_tbl_sz / 2; 4893 } 4894 return index; 4895 } 4896 } 4897 4898 /* not uRPF */ 4899 return (wide) ? index : index + (defip128_tbl_sz * 2); 4900 } 4901 if (alpm_mode == 1) { 4902 uint32 incr = soc_mem_index_count(unit, mem)/4; 4903 uint32 entries_per_tcam = _MONTEREY_INDEX_1K_ENTRIES; 4904 uint32 tcam_num, tcam_idx; 4905 uint32 cnt_128; 4906 uint32 tmp; 4907 4908 if (is_urpf_mode) { 4909 if (wide) { 4910 tcam_num = index/incr; 4911 tcam_idx = index % incr; 4912 return tcam_num * entries_per_tcam + tcam_idx; 4913 } 4914 incr = incr/2; 4915 tcam_num = index/incr; 4916 tcam_idx = index % incr; 4917 return tcam_num * entries_per_tcam + tcam_idx + 4918 defip128_tbl_sz/4; 4919 } 4920 if (wide > 0) { 4921 if (index < (soc_mem_index_count(unit, mem) / 2)) { 4922 return index; 4923 } 4924 /* make index relative to upper half */ 4925 index -= (soc_mem_index_count(unit, mem) / 2); 4926 return index + _MONTEREY_INDEX_2K_ENTRIES; 4927 } 4928 4929 cnt_128 = defip128_tbl_sz; 4930 4931 if (cnt_128/2 <= _MONTEREY_INDEX_1K_ENTRIES) { 4932 if ((cnt_128/2 + index) < _MONTEREY_INDEX_1K_ENTRIES) { 4933 return index + cnt_128/2; 4934 } else if ((cnt_128 + index) < _MONTEREY_INDEX_4K_ENTRIES) { 4935 return index + cnt_128; 4936 } else if ((cnt_128 + index + cnt_128/2) < 4937 (_MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_1K_ENTRIES)) { 4938 return index + cnt_128 + cnt_128/2; 4939 } else { 4940 return index + 2 * cnt_128; 4941 } 4942 } else if (cnt_128/2 <= _MONTEREY_INDEX_2K_ENTRIES) { 4943 tmp = cnt_128 - _MONTEREY_INDEX_2K_ENTRIES; 4944 if ((tmp/2 + index + _MONTEREY_INDEX_2K_ENTRIES) < _MONTEREY_INDEX_3K_ENTRIES) { 4945 return index + _MONTEREY_INDEX_2K_ENTRIES + tmp/2; 4946 } else if ((cnt_128 + index) < _MONTEREY_INDEX_4K_ENTRIES) { 4947 return index + cnt_128; 4948 } else if ((cnt_128 + tmp/2 + index + _MONTEREY_INDEX_2K_ENTRIES) < 4949 (_MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_3K_ENTRIES)) { 4950 return index + cnt_128 + tmp/2 + _MONTEREY_INDEX_2K_ENTRIES; 4951 } else { 4952 return index + cnt_128 * 2; 4953 } 4954 } 4955 4956 if (index < soc_mem_index_count(unit, mem)/2) { 4957 return index + defip128_tbl_sz; 4958 } else { 4959 /* make index relative to upper half */ 4960 index -= (soc_mem_index_count(unit, mem)/2); 4961 return index + 2 * _MONTEREY_INDEX_2K_ENTRIES + 4962 defip128_tbl_sz; 4963 } 4964 } 4965 4966 if (is_urpf_mode) { /* URPF mode */ 4967 return soc_l3_defip_urpf_index_map(unit, wide, index); 4968 } 4969 4970 return soc_l3_defip_index_map(unit, wide, index); 4971 } 4972 4973 /* Reverse map physical index to logical index. 4974 Input : physical index 4975 Returns: logical index */ 4976 int 4977 soc_monterey_l3_defip_index_remap(int unit, soc_mem_t mem, int index) 4978 { 4979 int wide = 0; 4980 int alpm_mode = _soc_alpm_mode[unit]; 4981 int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf; 4982 int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap; 4983 4984 /* don't remap for ALPM */ 4985 if (defip128_tbl_sz == 0) { 4986 return index; 4987 } 4988 4989 if (mem == L3_DEFIP_PAIR_128m || 4990 mem == L3_DEFIP_PAIR_128_ONLYm || 4991 mem == L3_DEFIP_PAIR_128_DATA_ONLYm || 4992 mem == L3_DEFIP_PAIR_128_HIT_ONLYm) { 4993 wide = 1; 4994 } 4995 4996 if (alpm_mode == 2) { 4997 if (is_urpf_mode) { /* URPF mode */ 4998 if (wide == 0) { 4999 if (index >= _MONTEREY_INDEX_6K_ENTRIES) { 5000 return index - (defip128_tbl_sz * 2); 5001 } 5002 return index - defip128_tbl_sz; 5003 } else { 5004 if (index >= _MONTEREY_INDEX_1K_ENTRIES) { 5005 return index - defip128_tbl_sz / 2; 5006 } 5007 return index; 5008 } 5009 } 5010 return (wide) ? index : index - (defip128_tbl_sz * 2); 5011 } 5012 if (alpm_mode == 1) { 5013 int cnt_128; 5014 5015 if (is_urpf_mode) { 5016 uint32 num_chunks, chunk_offset; 5017 if (wide) { 5018 num_chunks = index / _MONTEREY_INDEX_1K_ENTRIES; 5019 chunk_offset = index % _MONTEREY_INDEX_1K_ENTRIES; 5020 return num_chunks * soc_mem_index_count(unit, mem)/4 5021 + chunk_offset; 5022 } 5023 num_chunks = index / _MONTEREY_INDEX_1K_ENTRIES; 5024 chunk_offset = index % _MONTEREY_INDEX_1K_ENTRIES; 5025 chunk_offset -= (defip128_tbl_sz/4); 5026 return num_chunks*soc_mem_index_count(unit, mem)/8 + chunk_offset; 5027 5028 } 5029 5030 cnt_128 = defip128_tbl_sz; 5031 5032 if (wide) { 5033 if (index < cnt_128/2) { 5034 return index; 5035 } else if ((index >= _MONTEREY_INDEX_2K_ENTRIES) && 5036 (index < _MONTEREY_INDEX_2K_ENTRIES + cnt_128/2)){ 5037 return index - _MONTEREY_INDEX_2K_ENTRIES + cnt_128/2; 5038 } else { 5039 return -1; 5040 } 5041 } 5042 5043 if (cnt_128/2 <= _MONTEREY_INDEX_1K_ENTRIES) { 5044 if ((index < _MONTEREY_INDEX_1K_ENTRIES) && 5045 (index >= cnt_128/2)) { 5046 return index - cnt_128/2; 5047 } else if ((index >= _MONTEREY_INDEX_1K_ENTRIES + cnt_128/2) && 5048 (index < _MONTEREY_INDEX_4K_ENTRIES)) { 5049 return index - cnt_128; 5050 } else if ((index < _MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_1K_ENTRIES) && 5051 (index >= _MONTEREY_INDEX_4K_ENTRIES + cnt_128/2)) { 5052 return index - cnt_128 - cnt_128/2; 5053 } else { 5054 return index - cnt_128 * 2; 5055 } 5056 } else if (cnt_128/2 <= _MONTEREY_INDEX_2K_ENTRIES) { 5057 if (index < _MONTEREY_INDEX_3K_ENTRIES) { 5058 return index - _MONTEREY_INDEX_2K_ENTRIES - \ 5059 (cnt_128 - _MONTEREY_INDEX_2K_ENTRIES)/2; 5060 } else if (index < _MONTEREY_INDEX_4K_ENTRIES) { 5061 return index - cnt_128; 5062 } else if (index < _MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_3K_ENTRIES) { 5063 return index - cnt_128 - _MONTEREY_INDEX_2K_ENTRIES - \ 5064 (cnt_128 - _MONTEREY_INDEX_2K_ENTRIES)/2; 5065 } else { 5066 return index - cnt_128 * 2; 5067 } 5068 } 5069 } 5070 if (is_urpf_mode) { /* URPF mode */ 5071 return soc_l3_defip_urpf_index_remap(unit, wide, index); 5072 } 5073 5074 return soc_l3_defip_index_remap(unit, wide, index); 5075 } 5076 5077 /* Given a physical index (always in terms of the narrow entry) 5078 return the logical index and memory type */ 5079 int 5080 soc_monterey_l3_defip_mem_index_get(int unit, int pindex, soc_mem_t *mem) 5081 { 5082 return soc_l3_defip_index_mem_map(unit, pindex, mem); 5083 } 5084 5085 void 5086 _soc_monterey_alpm_bkt_view_set(int unit, int index, soc_mem_t view) 5087 { 5088 int bkt = soc_monterey_get_alpm_banks(unit) + 1; 5089 bkt = (index >> (bkt / 2)) & SOC_MONTEREY_ALPM_BKT_MASK; 5090 5091 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt set index:%d bkt:%d view:%s\n"), 5092 unit, index, bkt, SOC_MEM_NAME(unit, view))); 5093 _soc_monterey_alpm_bkt_view_map[unit][bkt] = view; 5094 } 5095 5096 soc_mem_t 5097 _soc_monterey_alpm_bkt_view_get(int unit, int index) 5098 { 5099 soc_mem_t view; 5100 int bkt = soc_monterey_get_alpm_banks(unit) + 1; 5101 bkt = (index >> (bkt / 2)) & SOC_MONTEREY_ALPM_BKT_MASK; 5102 5103 view = _soc_monterey_alpm_bkt_view_map[unit][bkt]; 5104 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt get index:%d bkt:%d view:%s\n"), 5105 unit, index, bkt, SOC_MEM_NAME(unit, view))); 5106 return view; 5107 } 5108 5109 int 5110 _soc_monterey_mem_cpu_write_control(int unit, soc_mem_t mem, int copyno, 5111 int enable, int *orig_enable) 5112 { 5113 soc_reg_t reg; 5114 soc_field_t field; 5115 int blk, port; 5116 soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, SOC_BLOCK_TYPE_INVALID}; 5117 uint32 rval, fval, orig_fval, enable_fval, disable_fval; 5118 5119 enable_fval = 1; 5120 disable_fval = 0; 5121 5122 switch (mem) { 5123 case XLPORT_WC_UCMEM_DATAm: 5124 reg = XLPORT_WC_UCMEM_CTRLr; 5125 field = ACCESS_MODEf; 5126 SOC_BLOCKS_ITER(unit, blk, xlport_blocks) { 5127 port = SOC_BLOCK_PORT(unit, blk); 5128 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 5129 /* It will use the setting from the last block */ 5130 *orig_enable = soc_reg_field_get(unit, reg, rval, field); 5131 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 5132 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 5133 } 5134 return SOC_E_NONE; 5135 case L3_DEFIP_ALPM_RAWm: 5136 case L3_DEFIP_ALPM_IPV4m: 5137 case L3_DEFIP_ALPM_IPV4_1m: 5138 case L3_DEFIP_ALPM_IPV6_64m: 5139 case L3_DEFIP_ALPM_IPV6_64_1m: 5140 case L3_DEFIP_ALPM_IPV6_128m: 5141 reg = ISS_MEMORY_CONTROL_84r; 5142 field = BYPASS_ISS_MEMORY_LPf; 5143 enable_fval = 0xf; 5144 break; 5145 case MMU_INTFI_PFC_ST_TBLm: 5146 reg = INTFI_CFGr; 5147 field = PFC_ST_TBL_DISABLEf; 5148 break; 5149 case LINK_STATUSm: 5150 reg = SW2_HW_CONTROLr; 5151 field = LINK_STATUS_UPDATE_ENABLEf; 5152 break; 5153 case MMU_INTFO_QCN_CNM_TIMER_TBLm: 5154 case MMU_INTFI_XPIPE_FC_MAP_TBL2m: 5155 case MMU_MTRI_BKPMETERINGBUCKET_MEM_0m: 5156 case MMU_MTRO_BUCKET_L0_MEM_0m: 5157 case MMU_MTRO_BUCKET_L1_MEM_0m: 5158 case MMU_MTRO_BUCKET_L1_MEM_1m: 5159 case MMU_MTRO_BUCKET_L2_MEM_0m: 5160 case MMU_MTRO_BUCKET_L2_MEM_1m: 5161 case MMU_MTRO_BUCKET_L2_MEM_2m: 5162 case MMU_MTRO_BUCKET_L2_MEM_3m: 5163 case MMU_MTRO_BUCKET_L2_MEM_4m: 5164 case MMU_MTRO_BUCKET_L2_MEM_5m: 5165 case MMU_MTRO_BUCKET_L2_MEM_6m: 5166 case MMU_MTRO_BUCKET_L2_MEM_7m: 5167 case MMU_WRED_AVG_QSIZE_X_PIPEm: 5168 case MMU_WRED_CONFIG_X_PIPEm: 5169 case MMU_WRED_PORT_SP_DROP_THD_X_PIPEm: 5170 case MMU_WRED_QGROUP_DROP_THD_X_PIPEm: 5171 case MMU_WRED_UC_QUEUE_DROP_THD_DEQ_X_PIPE_0m: 5172 case MMU_WRED_UC_QUEUE_DROP_THD_ENQ_X_PIPE_0m: 5173 reg = MISCCONFIGr; 5174 field = REFRESH_ENf; 5175 enable_fval = 0; 5176 disable_fval = 1; 5177 break; 5178 default: 5179 return SOC_E_NONE; 5180 } 5181 5182 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 5183 orig_fval = soc_reg_field_get(unit, reg, rval, field); 5184 fval = enable ? enable_fval : disable_fval; 5185 5186 *orig_enable = orig_fval == enable_fval; 5187 if (fval != orig_fval) { 5188 soc_reg_field_set(unit, reg, &rval, field, fval); 5189 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 5190 } 5191 5192 return SOC_E_NONE; 5193 } 5194 5195 /* 5196 * cpu port (mmu port 65): 48 queues (1300-1347) 5197 * loopback port (mmu port 66): 10 queues (1290- 1299) 5198 * MACSEC (mmu port 64) 10 queues (1280-1289) 5199 */ 5200 #define _MONTEREY_CPU_QUEUE_BASE 1300 5201 #define _MONTEREY_MACSEC_QUEUE_BASE 1280 5202 #define _MONTEREY_LB_QUEUE_BASE 1290 5203 #define _MONTEREY_HSP_PORTS 64 5204 #define _MONTEREY_UC_QUEUE_BASE 0 5205 #define _MONTEREY_MC_QUEUE_BASE 640 5206 #define _MONTEREY_NUMBER_OF_UC_QUEUE 640 5207 #define _MONTEREY_NUMBER_OF_MC_QUEUE 708 5208 #define IS_MN_HSP_PORT(u,p) \ 5209 ((_soc_apache_port_sched_type_get((u),(p)) == SOC_APACHE_SCHED_HSP) ? 1 : 0) 5210 5211 5212 int 5213 soc_monterey_num_cosq_init(int unit) 5214 { 5215 soc_info_t *si; 5216 int port, phy_port, mmu_port; 5217 int hsp_uc_cosq_base, hsp_mc_cosq_base; 5218 5219 si = &SOC_INFO(unit); 5220 5221 si->port_cosq_base[CMIC_PORT(unit)] = _MONTEREY_CPU_QUEUE_BASE - _MONTEREY_MC_QUEUE_BASE; 5222 si->port_num_cosq[CMIC_PORT(unit)] = 48; 5223 si->port_num_cosq[LB_PORT(unit)] = 10; 5224 si->port_cosq_base[LB_PORT(unit)] = _MONTEREY_LB_QUEUE_BASE - _MONTEREY_MC_QUEUE_BASE ; 5225 si->port_cosq_base[MACSEC_PORT(unit)] = _MONTEREY_MACSEC_QUEUE_BASE - _MONTEREY_MC_QUEUE_BASE ; 5226 si->port_num_cosq[MACSEC_PORT(unit)] = 10; 5227 si->port_cosq_base[64] = 1280 - _MONTEREY_MC_QUEUE_BASE; 5228 5229 5230 hsp_uc_cosq_base = 0; 5231 hsp_mc_cosq_base = 0; 5232 5233 for (mmu_port = 0; mmu_port < _MONTEREY_MMU_PORTS_PER_PIPE; mmu_port++) { 5234 phy_port = si->port_m2p_mapping[mmu_port]; 5235 if (phy_port == -1) { 5236 continue; 5237 } 5238 5239 port = si->port_p2l_mapping[phy_port]; 5240 if (port == -1) { 5241 continue; 5242 } 5243 5244 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port)) { 5245 continue; 5246 } 5247 5248 si->port_num_cosq[port] = 10; 5249 si->port_cosq_base[port] = hsp_mc_cosq_base + (mmu_port * si->port_num_cosq[port]); 5250 si->port_num_uc_cosq[port] = 10; 5251 /* Made port_uc_cosq_base a function of mmu_port number 5252 * rather than a running number (as calculated by 5253 * uc_cosq_base before). If it is a running number, & 5254 * the port numbers come & go dynamically (as in flex port) 5255 * uc_cosq_base overlap. With port_uc_cosq_base a function 5256 * of mmu_port, each port has a fixed offset 5257 */ 5258 si->port_uc_cosq_base[port] = hsp_uc_cosq_base + (mmu_port * 10); 5259 5260 } 5261 return SOC_E_NONE; 5262 5263 } 5264 5265 STATIC int 5266 soc_monterey_frequency_get(int unit, int *max_freq, int *def_freq) 5267 { 5268 if (soc_feature(unit, soc_feature_untethered_otp)) { 5269 *max_freq = SOC_BOND_INFO(unit)->max_core_freq; 5270 *def_freq = SOC_BOND_INFO(unit)->default_core_freq; 5271 } else { 5272 *def_freq = *max_freq = 862; 5273 } 5274 5275 return SOC_E_NONE; 5276 } 5277 5278 int 5279 soc_monterey_tsc_map_get(int unit, uint32 *tsc_map, uint32 *force_hg) 5280 { 5281 5282 if (soc_feature(unit, soc_feature_untethered_otp)) { 5283 *tsc_map = SOC_BOND_INFO(unit)->tsc_enable; 5284 *force_hg = SOC_BOND_INFO(unit)->tsc_force_hg; 5285 } else { 5286 *tsc_map = 0xffffffff; 5287 *force_hg = 0x0; 5288 } 5289 5290 return SOC_E_NONE; 5291 } 5292 5293 typedef struct soc_monterey_valid_fallback_cores_s { 5294 soc_100g_lane_config_t lane_config; 5295 int valid_lanes[3]; 5296 }soc_monterey_valid_fallback_cores_t; 5297 5298 const soc_monterey_valid_fallback_cores_t soc_monterey_valid_an_cores[] = { 5299 {SOC_LANE_CONFIG_100G_4_4_2, {TRUE, TRUE, TRUE} }, 5300 {SOC_LANE_CONFIG_100G_3_4_3, {TRUE, TRUE, TRUE} }, 5301 {SOC_LANE_CONFIG_100G_2_4_4, {TRUE, TRUE, TRUE} }, 5302 {SOC_INVALID_LANE_CONFIG} 5303 }; 5304 /* 5305 STATIC int 5306 soc_monterey_port_is_cpri_supported(int unit, int phy_port) { 5307 if (((phy_port > 0) && (phy_port < 13)) || 5308 ((phy_port > 52) && (phy_port < 65))) { 5309 return TRUE; 5310 } 5311 return FALSE; 5312 }*/ 5313 int 5314 soc_monterey_port_is_falcon(int unit, int phy_port) 5315 { 5316 5317 if (((phy_port >= 1) && (phy_port <= 20)) || 5318 ((phy_port >= 45) && (phy_port <= 64))) { 5319 return TRUE; 5320 } 5321 5322 return FALSE; 5323 } 5324 5325 STATIC int 5326 soc_monterey_port_is_2p5g_forced(int unit, int phy_port) 5327 { 5328 int tsc_id, bit_pos; 5329 if (soc_monterey_port_is_falcon(unit, phy_port) || 5330 !soc_feature(unit, soc_feature_untethered_otp)) { 5331 return FALSE; 5332 } 5333 5334 tsc_id = ((phy_port - 1) / MONTEREY_PORTS_PER_TSC); 5335 5336 /* SOC_BOND_INFO(unit)->eagle_force_2p5g is 14bit wide representing 14 Eagle TSCs in AP 5337 * In case TSC belongs in PGW 1, subtract 2 TSC falcons of PGW 0 to get correct bit pos 5338 */ 5339 bit_pos = (tsc_id >= MONTEREY_TSCS_PER_PGW) ? (tsc_id - MONTEREY_NUM_CLP_PER_PGW) : tsc_id; 5340 5341 if (!((SOC_BOND_INFO(unit)->tsce_max_2p5g) & (1 << bit_pos))) { 5342 return FALSE; 5343 } 5344 return TRUE; 5345 } 5346 5347 /* If CLPORT0/1/2/3/4/5 block is disabled */ 5348 #define IS_100G_DISABLED(clp_block) \ 5349 (soc_feature(unit, soc_feature_untethered_otp) ? (!((SOC_BOND_INFO(unit)->clmac_map) & (1 << (clp_block)))) : (0)) 5350 5351 STATIC soc_error_t 5352 _soc_monterey_port_lanes_set(int unit, int phy_port, int *lanes, int port_bandwidth) 5353 { 5354 if (soc_monterey_port_is_falcon(unit, phy_port)) { 5355 *lanes = (port_bandwidth > 53000) ? 5356 (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1 5357 : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1 5358 : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1 5359 : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1 5360 : 4 5361 : (port_bandwidth > 42000) ? 2 5362 : (port_bandwidth > 27000) ? 5363 (IS_100G_DISABLED(1) && (phy_port == 29)) ? 4 5364 : (IS_100G_DISABLED(2) && (phy_port == 33)) ? 4 5365 : (IS_100G_DISABLED(4) && (phy_port == 65)) ? 4 5366 : (IS_100G_DISABLED(5) && (phy_port == 69)) ? 4 5367 : 2 5368 : (port_bandwidth == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(21000)) ? 2 5369 : 1; 5370 } else { 5371 *lanes = ((port_bandwidth > 21000)? 4 5372 :((port_bandwidth > 11000) ? 2 5373 : 1)); 5374 } 5375 return ((*lanes == -1) ? SOC_E_CONFIG : SOC_E_NONE); 5376 } 5377 5378 /* Function to check legal BW values per port 5379 */ 5380 STATIC int 5381 _soc_monterey_port_speed_supported(int unit, int port, int phy_port, 5382 int port_lanes, int port_bandwidth) 5383 { 5384 soc_pbmp_t xe_pbmp; 5385 5386 if (port_lanes == -1) { 5387 if (SOC_FAILURE(_soc_monterey_port_lanes_set(unit, phy_port, &port_lanes, port_bandwidth))) { 5388 return FALSE; 5389 } 5390 } 5391 5392 switch (port_bandwidth) { 5393 case 1000: 5394 /* Eagles or Falcons - 1 x lanes */ 5395 return (port_lanes == 1); 5396 case 2500: 5397 case 5000: 5398 /* Eagles or Falcons - 1 x lanes */ 5399 return (port_lanes == 1); 5400 case 10000: 5401 /* Falcons - 1 x lanes and Eagles - 1, 2 or 4 lanes */ 5402 return (!soc_monterey_port_is_falcon(unit, phy_port) || 5403 (soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 1))); 5404 case 20000: 5405 /* Eagles or Falcons - 2 x lanes */ 5406 return ((!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4)) || (port_lanes == 2)); 5407 case 25000: 5408 /* Falcons only - 1 x lanes */ 5409 return ((soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 1)) || 5410 (!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4))); 5411 case 30000: 5412 /* Eagles only - 4 x lanes */ 5413 return (!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4)); 5414 case 40000: 5415 /* Eagles - 4 x lanes; Falcons - 2, 4 lanes */ 5416 return ((!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4)) || 5417 (soc_monterey_port_is_falcon(unit, phy_port) && ((port_lanes == 2) || (port_lanes == 4)))); 5418 case 50000: 5419 /* Falcons only - 2,4 lanes */ 5420 return (soc_monterey_port_is_falcon(unit, phy_port) && ((port_lanes == 2))); 5421 case 100000: 5422 /* Eagles - 10 x lanes; Falcons - 4 lanes */ 5423 return ((!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 10)) || 5424 (soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4))); 5425 5426 case 11000: 5427 case 21000: 5428 case 27000: 5429 case 42000: 5430 case 53000: 5431 case 106000: 5432 SOC_PBMP_CLEAR(xe_pbmp); 5433 xe_pbmp = soc_property_get_pbmp_default(unit, 5434 spn_PBMP_XPORT_XE, xe_pbmp); 5435 if (!SOC_PBMP_MEMBER(xe_pbmp, port)) { 5436 return _soc_monterey_port_speed_supported(unit, port, phy_port, port_lanes, SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(port_bandwidth)); 5437 } else { 5438 LOG_CLI((BSL_META_U(unit, 5439 "Port %d: Invalid HG2 bandwidth %d Gb\n"), 5440 port, port_bandwidth / 1000)); 5441 return FALSE; 5442 } 5443 break; 5444 5445 default: 5446 LOG_CLI((BSL_META_U(unit, 5447 "Port %d: Invalid bandwidth %d Gb\n"), 5448 port, port_bandwidth / 1000)); 5449 return FALSE; 5450 break; 5451 } 5452 5453 return FALSE; 5454 } 5455 5456 int 5457 soc_monterey_port_config_bandwidth_check(int unit) 5458 { 5459 int rv = SOC_E_NONE; 5460 int oversub_mode; 5461 int port_bandwidth; 5462 int *blk_port = NULL; 5463 int *blk_port_bandwidth = NULL; 5464 int index, port, phy_port, lane_count, blk, pgw; 5465 5466 int speed_lanes_1 = 0, speed_lanes_2 = 0; 5467 int blk_linerate_bandwidth, blk_oversub_bandwidth; 5468 int pgw_port[MONTEREY_PORTS_PER_PGW]; 5469 int pgw_port_bandwidth[MONTEREY_PORTS_PER_PGW]; 5470 int pgw_linerate_bandwidth[MONTEREY_PGWS_PER_DEV], pgw_oversub_bandwidth[MONTEREY_PGWS_PER_DEV]; 5471 int max_pgw_core_bandwidth[MONTEREY_PGWS_PER_DEV]; 5472 int max_pgw_oversub_bandwidth[MONTEREY_PGWS_PER_DEV]; 5473 int os_ratio[MONTEREY_PGWS_PER_DEV]; 5474 /* MAX OS ratio for a few FB5 configs is > 1.5 but is limited only to a single PGW */ 5475 int max_os_ratio = 1750, def_os_ratio = 1500; 5476 uint32 blk_configured_map, blk_inactive_map, blk_oversub_map; 5477 int falcon_lr_bandwidth = 0, falcon_os_bandwidth = 0, *falcon_bw_ptr = 0; 5478 5479 for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) { 5480 max_pgw_core_bandwidth[pgw] = (SOC_INFO(unit).bandwidth) / MONTEREY_PGWS_PER_DEV; 5481 max_pgw_oversub_bandwidth[pgw] = (SOC_INFO(unit).io_bandwidth) / MONTEREY_PGWS_PER_DEV; 5482 } 5483 5484 oversub_mode = 1; 5485 /*In monterey even the LR config is oversub as it is line rate only for 256 bytes packet*/ 5486 5487 /* Bandwidth check for ports in each XLPORT/CLPORT block */ 5488 for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) { 5489 pgw_linerate_bandwidth[pgw] = 0; 5490 pgw_oversub_bandwidth[pgw] = 0; 5491 5492 /* Prepare per PGW local variables for ease of processing */ 5493 for (index = 0; index < MONTEREY_PORTS_PER_PGW; index++) { 5494 phy_port = 1 + pgw * MONTEREY_PORTS_PER_PGW + index; 5495 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 5496 pgw_port[index] = port; 5497 if (port == -1) { 5498 pgw_port_bandwidth[index] = 0; 5499 } else { 5500 pgw_port_bandwidth[index] = SOC_INFO(unit).port_speed_max[port]; 5501 MONTEREY_TDM_SPEED_ADJUST(unit, port, pgw_port_bandwidth[index]); 5502 } 5503 } 5504 5505 for (blk = 0; blk < MONTEREY_TSCS_PER_PGW; blk++) { 5506 5507 blk_port = &pgw_port[blk * MONTEREY_PORTS_PER_TSC]; 5508 blk_port_bandwidth = &pgw_port_bandwidth[blk * MONTEREY_PORTS_PER_TSC]; 5509 5510 blk_configured_map = 0; 5511 for (index = 0; index < MONTEREY_PORTS_PER_TSC; index++) { 5512 if (blk_port[index] != -1) { 5513 blk_configured_map |= 1 << index; 5514 } 5515 } 5516 if (blk_configured_map == 0) { 5517 continue; 5518 } 5519 5520 /* Normal port block handling */ 5521 blk_inactive_map = 0; 5522 blk_oversub_map = 0; 5523 blk_linerate_bandwidth = 0; 5524 blk_oversub_bandwidth = 0; 5525 for (index = 0; index < MONTEREY_PORTS_PER_TSC; index++) { 5526 port = blk_port[index]; 5527 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 5528 if (port == -1) { 5529 continue; 5530 } 5531 port_bandwidth = blk_port_bandwidth[index]; 5532 blk_oversub_map |= 1 << index; 5533 if (SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 5534 blk_inactive_map |= 1 << index; 5535 } else { 5536 if (blk_oversub_map & (1 << index)) { 5537 falcon_bw_ptr = &falcon_os_bandwidth; 5538 blk_oversub_bandwidth += port_bandwidth; 5539 } else { 5540 falcon_bw_ptr = &falcon_lr_bandwidth; 5541 blk_linerate_bandwidth += port_bandwidth; 5542 } 5543 } 5544 5545 /* 0-4 Blocks are PM4x25(falcon) and 5-8 are PM4x10 eagle in pgw0 */ 5546 /* 0-2 eagle Blocks are PM4x10(falcon) and 3-8- are PM4x25 in pgw1 */ 5547 if ((pgw == 0 && blk >= 5 && blk <= 7) || 5548 (pgw == 1 && blk >= 0 && blk <= 2)) { 5549 5550 if((port_bandwidth > 21000 && (index != 0)) || 5551 (port_bandwidth > 11000 && (index & 1))) { 5552 5553 LOG_CLI((BSL_META_U(unit, 5554 "Port %d: Physical port %d can not " 5555 "be configured to %d Gb\n"), 5556 port, phy_port, (port_bandwidth / 1000))); 5557 rv = SOC_E_FAIL; 5558 } 5559 5560 speed_lanes_1 = 11000; 5561 speed_lanes_2 = 21000; 5562 } 5563 5564 if ((pgw == 0 && blk >= 0 && blk <= 4) || 5565 (pgw == 1 && blk >=3 && blk <= 7)) { 5566 if ((port_bandwidth > 106000) || 5567 (port_bandwidth > 53000 && (index != 0)) || 5568 (port_bandwidth > 27000 && (index & 0))) { 5569 5570 LOG_CLI((BSL_META_U(unit, 5571 "Port %d: Physical port %d can not " 5572 "be configured to %d Gb\n"), 5573 port, phy_port, (port_bandwidth / 1000))); 5574 rv = SOC_E_FAIL; 5575 } 5576 5577 speed_lanes_1 = 27000; 5578 speed_lanes_2 = 53000; 5579 if (falcon_bw_ptr) { 5580 *falcon_bw_ptr += port_bandwidth; 5581 } 5582 } 5583 } 5584 5585 /* Check if any of the lanes used by first port of block is 5586 * not used by other port */ 5587 port_bandwidth = blk_port_bandwidth[0]; 5588 if (port_bandwidth > speed_lanes_2) { 5589 lane_count = 4; 5590 } else if (port_bandwidth > speed_lanes_1) { 5591 lane_count = 2; 5592 } else { 5593 lane_count = 1; 5594 } 5595 5596 for (index = 1; index < lane_count; index++) { 5597 port = blk_port[index]; 5598 if (port == -1 || SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 5599 continue; 5600 } 5601 LOG_CLI((BSL_META_U(unit, 5602 "Port %d bandwidth %d Gb and " 5603 "port %d can not be both configured\n"), 5604 blk_port[0], port_bandwidth / 1000, port)); 5605 rv = SOC_E_FAIL; 5606 } 5607 5608 /* Check if any of the lanes used by third port of block is 5609 * not used by other port */ 5610 port_bandwidth = blk_port_bandwidth[2]; 5611 if (port_bandwidth > speed_lanes_1) { 5612 port = blk_port[3]; 5613 if (port != -1 && !SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 5614 LOG_CLI((BSL_META_U(unit, 5615 "Port %d bandwidth %d Gb and port %d " 5616 "can not be both configured\n"), 5617 blk_port[2], port_bandwidth / 1000, port)); 5618 rv = SOC_E_FAIL; 5619 } 5620 if (blk_port[0] == -1) { 5621 LOG_CLI((BSL_META_U(unit, 5622 "Physical port %d needs to be " 5623 "configured in order to work with " 5624 "port %d\n"), 5625 1 + pgw * MONTEREY_PORTS_PER_PGW + 5626 blk * MONTEREY_PORTS_PER_TSC, 5627 blk_port[2])); 5628 rv = SOC_E_FAIL; 5629 } 5630 } 5631 5632 if (blk_inactive_map == blk_configured_map) { 5633 LOG_CLI((BSL_META_U(unit, "Flex port"))); 5634 for (index = 0; index < MONTEREY_PORTS_PER_TSC; index++) { 5635 if (blk_port[index] != -1) { 5636 LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index])); 5637 } 5638 } 5639 LOG_CLI((BSL_META_U(unit, ": Can not be all inactive\n"))); 5640 rv = SOC_E_FAIL; 5641 continue; 5642 } 5643 5644 if (blk_inactive_map != 0) { 5645 if (blk_oversub_map != 0 && 5646 blk_oversub_map != blk_configured_map) { 5647 LOG_CLI((BSL_META_U(unit, "Flex port"))); 5648 for (index = 0; index < MONTEREY_PORTS_PER_TSC; 5649 index++) { 5650 if (blk_port[index] != -1) { 5651 LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index])); 5652 } 5653 } 5654 LOG_CLI((BSL_META_U(unit, 5655 ": Can not be configured to " 5656 "different oversubscription " 5657 "mode within a port block\n"))); 5658 rv = SOC_E_FAIL; 5659 continue; 5660 } 5661 } 5662 5663 if (falcon_lr_bandwidth != 0 && falcon_os_bandwidth != 0) { 5664 LOG_CLI((BSL_META_U(unit, 5665 "TDM algorith does not support mixed LR and OS ports " 5666 "modes on PM4x25 ports. LR BW = %d Gbps & OS BW = %d Gbps\n"), 5667 falcon_lr_bandwidth / 1000, falcon_os_bandwidth / 1000)); 5668 rv = SOC_E_FAIL; 5669 } 5670 5671 5672 if (blk_linerate_bandwidth != 0 && blk_oversub_map != 0) { 5673 LOG_CLI((BSL_META_U(unit, 5674 "TSC %d cannot have mixed LR and OS ports " 5675 "LR Bandwidth = %d Gbps & OS Bandwidth = %d Gbps\n"), 5676 blk, blk_linerate_bandwidth / 1000, blk_oversub_bandwidth / 1000)); 5677 rv = SOC_E_FAIL; 5678 } 5679 5680 pgw_linerate_bandwidth[pgw] += blk_linerate_bandwidth; 5681 pgw_oversub_bandwidth[pgw] += blk_oversub_bandwidth; 5682 } /* for (blk = 0; blk < MONTEREY_TSCS_PER_PGW; blk++) */ 5683 5684 if ((oversub_mode == 1) && (pgw_linerate_bandwidth[pgw] != 0)) { 5685 LOG_ERROR(BSL_LS_SOC_COMMON, 5686 (BSL_META_U(unit, "Oversub mode: Linerate BW for PGW %d is not 0.\n"), pgw)); 5687 rv = SOC_E_FAIL; 5688 } else if ((oversub_mode == 0) && (pgw_oversub_bandwidth[pgw] != 0)) { 5689 LOG_ERROR(BSL_LS_SOC_COMMON, 5690 (BSL_META_U(unit, "Linerate mode: Oversub BW for PGW %d is not 0.\n"), pgw)); 5691 rv = SOC_E_FAIL; 5692 } else if (oversub_mode == 2) { 5693 /* 5694 * OS ratio = (IO BW - LR BW) / (MAX LR BW - IO LR BW) 5695 */ 5696 os_ratio[pgw] = (((pgw_oversub_bandwidth[pgw]) * 1000) / (max_pgw_core_bandwidth[pgw] - pgw_linerate_bandwidth[pgw])); 5697 } 5698 5699 if (oversub_mode != 2) { 5700 /* Linerate Bandwidth check */ 5701 if (pgw_linerate_bandwidth[pgw] > max_pgw_core_bandwidth[pgw]) { 5702 LOG_CLI((BSL_META_U(unit, 5703 "PGW_CL%d total line rate bandwidth " 5704 "(%d Gb) exceeds %d Gb\n"), 5705 pgw, (pgw_linerate_bandwidth[pgw] / 1000), 5706 (max_pgw_core_bandwidth[pgw] / 1000))); 5707 rv = SOC_E_FAIL; 5708 } 5709 5710 /* Oversub Bandwidth check */ 5711 if ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) > max_pgw_oversub_bandwidth[pgw]) { 5712 LOG_CLI((BSL_META_U(unit, 5713 "PGW_CL%d total oversub bandwidth " 5714 "(%d Gb) exceeds %d Gb\n"), 5715 pgw, ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) / 1000), 5716 (max_pgw_oversub_bandwidth[pgw] / 1000))); 5717 rv = SOC_E_FAIL; 5718 } 5719 } 5720 /* Oversub Bandwidth check */ 5721 if ((pgw_linerate_bandwidth[pgw]+ pgw_oversub_bandwidth[pgw]) > max_pgw_oversub_bandwidth[pgw]) { 5722 LOG_CLI((BSL_META_U(unit, 5723 "PGW_CL%d total oversub bandwidth " 5724 "(%d Gb) exceeds %d Gb\n"), 5725 pgw, ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) / 1000), 5726 (max_pgw_oversub_bandwidth[pgw] / 1000))); 5727 rv = SOC_E_FAIL; 5728 } 5729 } /* for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) */ 5730 5731 if (oversub_mode == 2) { 5732 /* For mixed-mode we can have asymmetrical bandwidth distribution 5733 * Check the OS ratio in this case 5734 */ 5735 if ((os_ratio[MONTEREY_PGW0] > def_os_ratio) && (os_ratio[MONTEREY_PGW0] < max_os_ratio)) { 5736 if (os_ratio[MONTEREY_PGW1] > def_os_ratio) { 5737 LOG_CLI((BSL_META_U(unit, 5738 "PGW_CL1 total oversub bandwidth " 5739 "(%d Gb) exceeds limit\n"), 5740 ((pgw_oversub_bandwidth[MONTEREY_PGW1]) / 1000))); 5741 rv = SOC_E_FAIL; 5742 } 5743 } else if ((os_ratio[MONTEREY_PGW1] > def_os_ratio) && (os_ratio[MONTEREY_PGW1] < max_os_ratio)) { 5744 if (os_ratio[MONTEREY_PGW0] > def_os_ratio) { 5745 LOG_CLI((BSL_META_U(unit, 5746 "PGW_CL0 total oversub bandwidth " 5747 "(%d Gb) exceeds limit\n"), 5748 ((pgw_oversub_bandwidth[MONTEREY_PGW0]) / 1000))); 5749 rv = SOC_E_FAIL; 5750 } 5751 } 5752 } 5753 5754 return rv; 5755 } 5756 5757 5758 int 5759 soc_monterey_mmu_hsp_port_reserve(int unit, int port, int speed_max) 5760 { 5761 int def_freq, max_freq; 5762 int min_hsp_ovs_speed; 5763 5764 SOC_IF_ERROR_RETURN(soc_monterey_frequency_get(unit, &max_freq, &def_freq)); 5765 def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq); 5766 5767 switch (def_freq) { 5768 case 841: 5769 case 793: 5770 min_hsp_ovs_speed = 100000; 5771 break; 5772 default: 5773 min_hsp_ovs_speed = 40000; 5774 break; 5775 5776 } 5777 5778 if (IS_OVERSUB_PORT(unit, port) && speed_max >= min_hsp_ovs_speed) { 5779 return TRUE; 5780 } 5781 5782 return FALSE; 5783 } 5784 5785 5786 STATIC int 5787 soc_monterey_mmu_ports_assign(int unit) 5788 { 5789 int port, phy_port, mmu_port; 5790 int port_is_hsp; 5791 int num_phy_port = 67; 5792 soc_info_t *si; 5793 /*soc_pbmp_t pbmp;*/ 5794 int num_phy_ports = MONTEREY_PORTS_PER_PIPE; 5795 5796 si = &SOC_INFO(unit); 5797 5798 /* Setup vector-based scheduler (VBS) 5799 * a.k.a high speed port scheduler (HSP) pbm */ 5800 for (phy_port = 1; phy_port <= num_phy_ports; phy_port++) { 5801 port = si->port_p2l_mapping[phy_port]; 5802 if (port == -1) { 5803 continue; 5804 } 5805 5806 /* Usage: 5807 * port_sched_hsp_<log_port> = 1 ; Port is in HSP 5808 * port_sched_hsp_<log_port> = 0 ; Port is in LLS 5809 * port_sched_hsp_<log_port> = -1 (default) ; SDK determines sched type 5810 */ 5811 port_is_hsp = 1; 5812 5813 if (port_is_hsp) { 5814 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 5815 } else { 5816 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port); 5817 } 5818 5819 } 5820 5821 mmu_port = 0; 5822 5823 #if 0 5824 /* First assign the lowest MMU port number for VBS (HSP) ports */ 5825 pbmp = si->xpipe_pbm; 5826 SOC_PBMP_AND(pbmp, si->eq_pbm); 5827 SOC_PBMP_ITER(pbmp, port) { 5828 if ( port <= _MONTEREY_LOG_PORTS_PER_PIPE ) { 5829 phy_port = si->port_l2p_mapping[port]; 5830 if ( phy_port <= num_phy_port) { 5831 si->port_p2m_mapping[phy_port] = mmu_port; 5832 si->port_m2p_mapping[mmu_port] = phy_port; 5833 mmu_port++; 5834 } 5835 } 5836 } 5837 #endif 5838 5839 /* Assign MMU port for all OS ports with speed >= 100G */ 5840 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5841 if (si->port_p2m_mapping[phy_port] != -1) { 5842 continue; 5843 } 5844 5845 port = si->port_p2l_mapping[phy_port]; 5846 if (port == -1) { 5847 continue; 5848 } 5849 5850 if ((IS_OVERSUB_PORT(unit, port)) && 5851 (si->port_speed_max[port] >= 100000)) { 5852 si->port_p2m_mapping[phy_port] = mmu_port; 5853 si->port_m2p_mapping[mmu_port] = phy_port; 5854 mmu_port++; 5855 } 5856 } 5857 5858 /* Assign MMU port for all OS ports with speed >= 40G */ 5859 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5860 if (si->port_p2m_mapping[phy_port] != -1) { 5861 continue; 5862 } 5863 5864 port = si->port_p2l_mapping[phy_port]; 5865 if (port == -1) { 5866 continue; 5867 } 5868 5869 if ((IS_OVERSUB_PORT(unit, port)) && 5870 (si->port_speed_max[port] >= 40000)) { 5871 si->port_p2m_mapping[phy_port] = mmu_port; 5872 si->port_m2p_mapping[mmu_port] = phy_port; 5873 mmu_port++; 5874 } 5875 } 5876 5877 /* Assign MMU port for all ports with speed >= 100G */ 5878 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5879 if (si->port_p2m_mapping[phy_port] != -1) { 5880 continue; 5881 } 5882 5883 port = si->port_p2l_mapping[phy_port]; 5884 if (port == -1) { 5885 continue; 5886 } 5887 5888 if (si->port_speed_max[port] >= 100000) { 5889 si->port_p2m_mapping[phy_port] = mmu_port; 5890 si->port_m2p_mapping[mmu_port] = phy_port; 5891 mmu_port++; 5892 } 5893 } 5894 5895 /* Assign MMU port for all ports with speed >= 40G */ 5896 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5897 if (si->port_p2m_mapping[phy_port] != -1) { 5898 continue; 5899 } 5900 5901 port = si->port_p2l_mapping[phy_port]; 5902 if (port == -1) { 5903 continue; 5904 } 5905 5906 if (si->port_speed_max[port] >= 40000) { 5907 si->port_p2m_mapping[phy_port] = mmu_port; 5908 si->port_m2p_mapping[mmu_port] = phy_port; 5909 mmu_port++; 5910 } 5911 } 5912 /* Assign MMU port for 1st phy port in PM4x25|PM4x10 */ 5913 for (phy_port = 1; phy_port <= num_phy_port; phy_port += MONTEREY_PORTS_PER_TSC) { 5914 if (si->port_p2m_mapping[phy_port] != -1) { 5915 continue; 5916 } 5917 5918 if (si->port_p2l_mapping[phy_port] == -1) { 5919 continue; 5920 } 5921 5922 si->port_p2m_mapping[phy_port] = mmu_port; 5923 si->port_m2p_mapping[mmu_port] = phy_port; 5924 mmu_port++; 5925 } 5926 5927 /* Assign MMU port for all remaining ports with speeds >= 25G */ 5928 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5929 if (si->port_p2m_mapping[phy_port] != -1) { 5930 continue; 5931 } 5932 5933 port = si->port_p2l_mapping[phy_port]; 5934 if (port == -1) { 5935 continue; 5936 } 5937 5938 if (si->port_speed_max[port] >= 25000) { 5939 si->port_p2m_mapping[phy_port] = mmu_port; 5940 si->port_m2p_mapping[mmu_port] = phy_port; 5941 mmu_port++; 5942 } 5943 } 5944 5945 /* Assign MMU port for all remaining ports with speeds >= 10G */ 5946 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5947 if (si->port_p2m_mapping[phy_port] != -1) { 5948 continue; 5949 } 5950 5951 port = si->port_p2l_mapping[phy_port]; 5952 if (port == -1) { 5953 continue; 5954 } 5955 5956 if (si->port_speed_max[port] >= 10000) { 5957 si->port_p2m_mapping[phy_port] = mmu_port; 5958 si->port_m2p_mapping[mmu_port] = phy_port; 5959 mmu_port++; 5960 } 5961 } 5962 /* Assign MMU port for all remaining ports */ 5963 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5964 if (si->port_p2m_mapping[phy_port] != -1) { 5965 continue; 5966 } 5967 5968 si->port_p2m_mapping[phy_port] = mmu_port; 5969 si->port_m2p_mapping[mmu_port] = phy_port; 5970 mmu_port++; 5971 } 5972 5973 5974 return SOC_E_NONE; 5975 } 5976 STATIC int 5977 _soc_mn_ports_speed_init_update(int unit) 5978 { 5979 int port; 5980 soc_info_t *si = &SOC_INFO(unit); 5981 5982 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 5983 /* Set init speed to max speed by default */ 5984 /* Used during port probe and portmod attach */ 5985 si->port_init_speed[port] = si->port_speed_max[port]; 5986 } 5987 5988 return SOC_E_NONE; 5989 } 5990 5991 /* 5992 * Monterey port mapping 5993 * 64 physical ports: port 0-64 in X pipe 5994 * 106 logical ports 5995 * 108 mmu ports: port 0-53 in X pipe, port 64-117 in Y pipe 5996 * cpu port number is fixed: physical 0, logical 0, mmu 65 5997 * loopback port number is fixed: physical 65, logical 65, mmu 66 5998 * management port can be: 5999 * - one 10G port 6000 * - one to four ports with speed up to 2.5G each 6001 * Physical port number in eacc port group 6002 * This routine will setup: 6003 * SOC_INFO(unit).port_p2l_mapping[] 6004 * SOC_INFO(unit).port_l2p_mapping[] 6005 * SOC_INFO(unit).port_p2m_mapping[] 6006 * SOC_INFO(unit).port_m2p_mapping[] 6007 * SOC_INFO(unit).port_speed_max[] 6008 * SOC_INFO(unit).port_group[] 6009 * SOC_INFO(unit).port_serdes[] 6010 * SOC_INFO(unit).port_num_lanes[] 6011 * SOC_INFO(unit).phy_port_base[] 6012 * SOC_INFO(unit).mmu_port_base[] 6013 * 100+G port: 6014 * - can only be @ 760MHz 6015 * - needs to be HSP 6016 * - cannot be in oversubscribe mode 6017 * 40/42G port: 6018 * - needs to be HSP except @ 760MHz 6019 * - oversubscribe mode can support both cut-through and store-and-forward 6020 * sub-40G port: 6021 * - oversubscribe mode can only support store-and-forward 6022 */ 6023 int 6024 soc_monterey_port_config_init(int unit, uint16 dev_id, uint8 rev_id) 6025 { 6026 char *config_str, *sub_str, *sub_str_end; 6027 static const char str_2p5[] = "2.5"; 6028 char str_buf[8]; 6029 soc_info_t *si; 6030 int rv; 6031 int num_port, num_phy_port; 6032 int port, phy_port; 6033 int port_bandwidth, port_active_lanes; 6034 int def_freq, max_freq; 6035 soc_100g_lane_config_t lane_config = SOC_LANE_CONFIG_100G_DEFAULT; 6036 int fallback_core = SOC_LANE_CONFIG_100G_DEFAULT; 6037 int index, tsc_id; 6038 char option_inactive, option_lanes; 6039 int port_count; 6040 int oversub_mode = 0; 6041 soc_pbmp_t oversub_pbm; 6042 soc_pbmp_t xe_pbmp; 6043 soc_pbmp_t cpri_pbmp; 6044 uint32 tsc_map, force_hg; 6045 int freq_list_len; 6046 int const *freq_list; 6047 int tdm_freq = 0 ; 6048 static const int monterey_freq_list[] = { 862, 817, 667, 550, 450}; 6049 int int_ports[3][3] = { 6050 6051 /* {log, phy, mmu} */ 6052 {0, 0, 65}, /* CPU */ 6053 {65, 65, 66}, /* LB */ 6054 {66, 66, 64}, /* MACSEC */ 6055 }; 6056 6057 SOC_PBMP_CLEAR(xe_pbmp); 6058 SOC_PBMP_CLEAR(oversub_pbm); 6059 SOC_PBMP_CLEAR(cpri_pbmp); 6060 xe_pbmp = soc_property_get_pbmp_default(unit, 6061 spn_PBMP_XPORT_XE, xe_pbmp); 6062 cpri_pbmp = soc_property_get_pbmp_default(unit, 6063 spn_PBMP_XPORT_CPRI, cpri_pbmp); 6064 si = &SOC_INFO(unit); 6065 6066 { 6067 num_port = 64; 6068 num_phy_port = 64; 6069 } 6070 6071 SOC_IF_ERROR_RETURN(soc_monterey_frequency_get(unit, &max_freq, &def_freq)); 6072 def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq); 6073 tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY, 0); 6074 if (def_freq <= max_freq) { 6075 freq_list = monterey_freq_list; 6076 freq_list_len = sizeof(monterey_freq_list) / sizeof(int); 6077 for (index = 0; index < freq_list_len; index++) { 6078 if (def_freq == freq_list[index]) { 6079 break; 6080 } 6081 } 6082 6083 if (index < freq_list_len) { 6084 si->frequency = def_freq; 6085 } else { 6086 LOG_CLI((BSL_META_U(unit, 6087 "*** Input core clock frequency %dMHz is not " 6088 "supported!\n"), def_freq)); 6089 } 6090 } 6091 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6092 (BSL_META_U(unit, "Running core clock frequency %dMhz\n"), def_freq)); 6093 6094 /* Setup max I/O and core bandwidth */ 6095 switch (si->frequency) { 6096 case 862: 6097 if (tdm_freq == 862) { 6098 si->io_bandwidth = 1000000; 6099 } else if (tdm_freq == 861) { 6100 si->io_bandwidth = 800000; 6101 } else { 6102 if (soc_feature(unit, soc_feature_xflow_macsec)) { 6103 si->io_bandwidth = 920000; 6104 } else { 6105 si->io_bandwidth = 1000000; 6106 } 6107 } 6108 si->bandwidth = 548000; 6109 break; 6110 case 817: 6111 if (tdm_freq == 815) { 6112 si->io_bandwidth = 760000; 6113 } else if (tdm_freq == 816) { 6114 si->io_bandwidth = 700000; 6115 } else if (tdm_freq == 666) { 6116 si->io_bandwidth = 800000; 6117 } else if (tdm_freq == 667) { 6118 si->io_bandwidth = 800000; 6119 } else { 6120 si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 800000); 6121 if (!(si->io_bandwidth == 800000 || si->io_bandwidth == 720000 || 6122 si->io_bandwidth == 460000)) { 6123 LOG_CLI((BSL_META_U(unit, 6124 "*** Input IO Bandwidth %d is not yet " 6125 "supported using default value %d !\n"), si->io_bandwidth,800000)); 6126 si->io_bandwidth = 800000; 6127 } 6128 6129 } 6130 if (dev_id == BCM56675_DEVICE_ID) { 6131 if (soc_feature(unit, soc_feature_xflow_macsec)) { 6132 si->io_bandwidth = 860000; 6133 } else { 6134 si->io_bandwidth = 920000; 6135 } 6136 si->bandwidth = 515000; 6137 } else { 6138 si->bandwidth = 490000; 6139 } 6140 break; 6141 case 667: 6142 if (tdm_freq == 666) { 6143 si->io_bandwidth = 800000; 6144 } else if (tdm_freq == 667) { 6145 si->io_bandwidth = 800000; 6146 } else { 6147 si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 780000); 6148 if (!(si->io_bandwidth == 720000 || si->io_bandwidth == 580000 || 6149 si->io_bandwidth == 360000 || si->io_bandwidth == 780000 || 6150 si->io_bandwidth == 400000)) { 6151 LOG_CLI((BSL_META_U(unit, 6152 "*** Input IO Bandwidth %d is not yet " 6153 "supported using default value %d !\n"), si->io_bandwidth,720000)); 6154 si->io_bandwidth = 720000; 6155 } 6156 } 6157 if (dev_id == BCM56675_DEVICE_ID) { 6158 if (soc_feature(unit, soc_feature_xflow_macsec)) { 6159 si->io_bandwidth = 680000; 6160 } else { 6161 si->io_bandwidth = 720000; 6162 } 6163 si->bandwidth = 420000; 6164 } else { 6165 si->bandwidth = 490000; 6166 6167 } 6168 break; 6169 case 550: 6170 si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 400000); 6171 if (!(si->io_bandwidth == 460000 || si->io_bandwidth == 580000 || 6172 si->io_bandwidth == 280000 || si->io_bandwidth == 400000)) { 6173 LOG_CLI((BSL_META_U(unit, 6174 "*** Input IO Bandwidth %d is not yet " 6175 "supported using default value %d !\n"), si->io_bandwidth,580000)); 6176 si->io_bandwidth = 580000; 6177 } 6178 if (dev_id == BCM56675_DEVICE_ID) { 6179 si->io_bandwidth = 540000; 6180 si->bandwidth = 340000; 6181 } else { 6182 si->bandwidth = 342000; 6183 } 6184 6185 6186 break; 6187 case 450: 6188 si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 200000); 6189 si->bandwidth = 275000; 6190 if (!(si->io_bandwidth == 460000 || si->io_bandwidth == 360000 || 6191 si->io_bandwidth == 200000 || si->io_bandwidth == 400000) ) { 6192 LOG_CLI((BSL_META_U(unit, 6193 "*** Input IO Bandwidth %d is not yet " 6194 "supported using default value %d !\n"), si->io_bandwidth,460000)); 6195 si->io_bandwidth = 460000; 6196 } 6197 if (dev_id == BCM56675_DEVICE_ID) { 6198 if (soc_feature(unit, soc_feature_xflow_macsec)) { 6199 si->io_bandwidth = 420000; 6200 } else { 6201 si->io_bandwidth = 480000; 6202 } 6203 } 6204 6205 break; 6206 default: 6207 LOG_CLI((BSL_META_U(unit, 6208 "*** Input core clock frequency %dMHz is not yet " 6209 "supported!\n"), si->frequency)); 6210 return SOC_E_INTERNAL; /* unknown frequency */ 6211 } 6212 6213 6214 oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0); 6215 if (oversub_mode == 2) { 6216 oversub_pbm = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0); 6217 } 6218 6219 SOC_IF_ERROR_RETURN(soc_monterey_tsc_map_get(unit, &tsc_map, &force_hg)); 6220 6221 /* Initialize the soc_info params */ 6222 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 6223 si->port_l2p_mapping[port] = -1; 6224 si->port_speed_max[port] = -1; 6225 si->port_group[port] = -1; 6226 si->port_serdes[port] = -1; 6227 si->port_num_lanes[port] = -1; 6228 6229 /* Indexed by physical port */ 6230 si->port_p2l_mapping[port] = -1; 6231 si->port_p2m_mapping[port] = -1; 6232 6233 /* Indexed by mmu port */ 6234 si->port_m2p_mapping[port] = -1; 6235 } 6236 6237 6238 6239 for (index = 0; index < COUNTOF(int_ports); index++) { 6240 /* int_ports is an array of log, phy & mmu ports in that order */ 6241 si->port_p2l_mapping[int_ports[index][1]] = int_ports[index][0]; 6242 si->port_p2m_mapping[int_ports[index][1]] = int_ports[index][2]; 6243 6244 SOC_PBMP_PORT_SET(si->xpipe_pbm, int_ports[index][0]); 6245 } 6246 6247 6248 SOC_PBMP_CLEAR(si->oversub_pbm); 6249 SOC_PBMP_CLEAR(si->management_pbm); 6250 SOC_PBMP_CLEAR(si->all.disabled_bitmap); 6251 6252 si->phy_port_base[0] = 1; /* First physical port */ 6253 si->mmu_port_base[0] = 0; /* First mmu port */ 6254 port_count = 0; 6255 6256 rv = SOC_E_NONE; 6257 for (port = 0; port <= num_port; port++) { 6258 6259 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 6260 if (config_str == NULL) { 6261 continue; 6262 } 6263 6264 /* 6265 * portmap.<port>=<physical port number>:<bandwidth in Gb>:[<num_lanes>]:[i] 6266 */ 6267 sub_str = config_str; 6268 6269 /* Parse physical port number */ 6270 phy_port = sal_ctoi(sub_str, &sub_str_end); 6271 if (sub_str == sub_str_end) { 6272 LOG_CLI((BSL_META_U(unit, 6273 "Port %d: Missing physical port information \"%s\"\n"), 6274 port, config_str)); 6275 rv = SOC_E_FAIL; 6276 continue; 6277 } 6278 6279 /* phy_port valid range [1..72] */ 6280 if (phy_port < 1 || phy_port > num_phy_port) { 6281 LOG_CLI((BSL_META_U(unit, 6282 "Port %d: Invalid physical port number %d\n"), 6283 port, phy_port)); 6284 rv = SOC_E_FAIL; 6285 continue; 6286 } 6287 6288 tsc_id = (phy_port - 1) / MONTEREY_PORTS_PER_TSC; 6289 if (!(tsc_map & (1 << tsc_id))) { 6290 LOG_CLI((BSL_META_U(unit, 6291 "Port %d: Physical port %d is in disabled TSC %d\n"), 6292 port, phy_port, tsc_id)); 6293 rv = SOC_E_FAIL; 6294 continue; 6295 } 6296 6297 if ((force_hg & (1 << tsc_id)) && 6298 (SOC_PBMP_MEMBER(xe_pbmp, port))) { 6299 LOG_CLI((BSL_META_U(unit, 6300 "Port %d: non-hg port in TSC(%d) which is hg-only\n"), 6301 port, tsc_id)); 6302 rv = SOC_E_FAIL; 6303 continue; 6304 } 6305 6306 if (si->port_p2l_mapping[phy_port] != -1) { 6307 LOG_CLI((BSL_META_U(unit, 6308 "Port %d: Physical port %d is used by port %d\n"), 6309 port, phy_port, si->port_p2l_mapping[phy_port])); 6310 rv = SOC_E_FAIL; 6311 continue; 6312 } 6313 6314 if (port_count > num_port) { 6315 LOG_CLI((BSL_META_U(unit, 6316 "Can not configure more than %d port\n"), num_port)); 6317 rv = SOC_E_FAIL; 6318 continue; 6319 } 6320 6321 /* Skip ':' between physical port number and bandwidth */ 6322 sub_str = sub_str_end; 6323 if (*sub_str != '\0') { 6324 if (*sub_str != ':') { 6325 LOG_CLI((BSL_META_U(unit, 6326 "Port %d: Bad config string \"%s\"\n"), 6327 port, config_str)); 6328 rv = SOC_E_FAIL; 6329 continue; 6330 } 6331 sub_str++; 6332 } 6333 6334 /* Parse bandwidth - special case 2.5G */ 6335 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 6336 if (sub_str[index] == '\0') { 6337 break; 6338 } 6339 str_buf[index] = sub_str[index]; 6340 } 6341 str_buf[index] = '\0'; 6342 6343 if (!sal_strcmp(str_buf, str_2p5)) { 6344 port_bandwidth = 2500; 6345 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 6346 } else { 6347 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 6348 if (sub_str == sub_str_end) { 6349 LOG_CLI((BSL_META_U(unit, 6350 "Port %d: Missing bandwidth " 6351 "information \"%s\"\n"), 6352 port, config_str)); 6353 rv = SOC_E_FAIL; 6354 continue; 6355 } 6356 } 6357 6358 /* Check if option presents */ 6359 option_inactive = option_lanes = 0; 6360 sub_str = sub_str_end; 6361 if (*sub_str != '\0') { 6362 /* Skip ':' between bandwidth and options */ 6363 if (*sub_str != ':') { 6364 LOG_CLI((BSL_META_U(unit, 6365 "Port %d: Bad config string \"%s\"\n"), 6366 port, config_str)); 6367 rv = SOC_E_FAIL; 6368 continue; 6369 } 6370 sub_str++; 6371 6372 /* Read 100G lane configuration if present. 6373 * Skip if options are present */ 6374 if (*sub_str != '\0') { 6375 if (*sub_str == 'i') { 6376 option_inactive = *sub_str; 6377 sub_str++; 6378 } else if ((*sub_str == '1') || 6379 (*sub_str == '2') || 6380 (*sub_str == '4')) { 6381 option_lanes = *sub_str; 6382 sub_str++; 6383 6384 if (*sub_str != '\0') { 6385 if (*sub_str != 'i') { 6386 LOG_CLI((BSL_META_U(unit, 6387 "Port %d: Bad config string \"%s\"\n"), 6388 port, config_str)); 6389 rv = SOC_E_FAIL; 6390 continue; 6391 } 6392 option_inactive = *sub_str; 6393 sub_str++; 6394 } 6395 } else { 6396 LOG_CLI((BSL_META_U(unit, 6397 "Port %d: Bad config string \"%s\"\n"), 6398 port, config_str)); 6399 rv = SOC_E_FAIL; 6400 continue; 6401 } 6402 } 6403 } 6404 6405 /* Check trailing string */ 6406 if (*sub_str != '\0') { 6407 LOG_CLI((BSL_META_U(unit, 6408 "Port %d: Bad config string \"%s\"\n"), 6409 port, config_str)); 6410 rv = SOC_E_FAIL; 6411 continue; 6412 } 6413 6414 /* 6415 * Use new properties for 100GE mode lane and 6416 * fallback autoneg core if these are specified. 6417 */ 6418 switch (option_lanes) { 6419 case '1': port_active_lanes = 1; break; 6420 case '2': port_active_lanes = 2; break; 6421 case '4': port_active_lanes = 4; break; 6422 default : 6423 if (SOC_FAILURE(_soc_monterey_port_lanes_set(unit, phy_port, 6424 &port_active_lanes, 6425 port_bandwidth))) { 6426 rv = SOC_E_FAIL; 6427 } 6428 break; 6429 } 6430 if (option_inactive == 'i') { 6431 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 6432 port_active_lanes = -1; 6433 } 6434 6435 /* PORT bandwidth checks */ 6436 if ((soc_monterey_port_is_2p5g_forced(unit, phy_port)) && 6437 (port_bandwidth > 2500)) { 6438 rv = SOC_E_FAIL; 6439 LOG_CLI((BSL_META_U(unit, 6440 "Port %d: Invalid bandwidth %d Gb\n" 6441 "Max bandwidth supported is 2.5G\n"), 6442 port, port_bandwidth / 1000)); 6443 6444 continue; 6445 } 6446 if (!_soc_monterey_port_speed_supported(unit, port, phy_port, 6447 port_active_lanes, port_bandwidth)) { 6448 rv = SOC_E_FAIL; 6449 continue; 6450 } 6451 6452 6453 /* Update soc_info */ 6454 si->port_p2l_mapping[phy_port] = port; 6455 si->port_l2p_mapping[port] = phy_port; 6456 si->port_speed_max[port] = port_bandwidth; 6457 si->port_100g_lane_config[port] = lane_config; 6458 si->port_fallback_lane[port] = fallback_core; 6459 si->port_num_lanes[port] = port_active_lanes; 6460 6461 if (SOC_PBMP_MEMBER(oversub_pbm,port) || (oversub_mode == 1)) { 6462 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 6463 } 6464 6465 port_count++; 6466 } 6467 /* Legacy Flex config ":i" case detected, disabled ports in config */ 6468 if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all))) { 6469 si->flex_eligible = TRUE; 6470 } 6471 6472 #ifdef BCM_WARM_BOOT_SUPPORT 6473 if (SOC_WARM_BOOT(unit)) { 6474 rv = soc_monterey_flexport_scache_recovery(unit); 6475 if (SOC_FAILURE(rv)) { 6476 if (rv == SOC_E_NOT_FOUND) { 6477 rv = SOC_E_NONE; 6478 } else { 6479 return rv; 6480 } 6481 } 6482 } else { 6483 /* Cold boot create */ 6484 SOC_IF_ERROR_RETURN(soc_monterey_flexport_scache_allocate(unit)); 6485 } 6486 #endif /* BCM_WARM_BOOT_SUPPORT */ 6487 6488 if (port_count == 0) { 6489 #ifdef __KERNEL__ 6490 /* config.bcm is not parsed yet at the time 1st call of soc_attach 6491 in Kernel mode SDK. Shouldn't return error code. */ 6492 return SOC_E_NONE; 6493 #else 6494 #if 0 6495 if (SOC_CONTROL(unit)->soc_flags & SOC_F_ATTACHED) { /* not for PCID */ 6496 rv = SOC_E_FAIL; 6497 } 6498 #endif 6499 #endif 6500 } 6501 /* Bandwidth check for ports in each XLPORT/CLPORT block */ 6502 6503 if (SOC_SUCCESS(rv)) { 6504 rv = soc_monterey_port_config_bandwidth_check(unit); 6505 } 6506 if (SOC_FAILURE(rv)) { 6507 for (phy_port = 1; phy_port < 66; phy_port++) { 6508 si->port_p2l_mapping[phy_port] = -1; 6509 } 6510 return rv; 6511 } 6512 6513 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 6514 LOG_CLI((BSL_META_U(unit, "physical to logical mapping:"))); 6515 for (index = 0; index < num_phy_port; index++) { 6516 if (index % 16 == 0) { 6517 LOG_CLI((BSL_META_U(unit, "\n "))); 6518 } 6519 LOG_CLI((BSL_META_U(unit, " %3d"), 6520 si->port_p2l_mapping[index])); 6521 } 6522 LOG_CLI((BSL_META_U(unit, "\n"))); 6523 LOG_CLI((BSL_META_U(unit, "physical port bandwidth:"))); 6524 for (index = 0; index < num_phy_port; index++) { 6525 if (index % 16 == 0) { 6526 LOG_CLI((BSL_META_U(unit, "\n "))); 6527 } 6528 port = si->port_p2l_mapping[index]; 6529 if (port == -1) { 6530 LOG_CLI((BSL_META_U(unit, " -1"))); 6531 } else if (si->port_speed_max[port] == 2500) { 6532 LOG_CLI((BSL_META_U(unit, " 2.5"))); 6533 } else { 6534 LOG_CLI((BSL_META_U(unit, " %3d"), 6535 si->port_speed_max[port] / 1000)); 6536 } 6537 } 6538 LOG_CLI((BSL_META_U(unit, "\n"))); 6539 } 6540 6541 /* Setup port_group, num_lanes, xpipe_pbm */ 6542 for (port = 0; port <= num_port; port++) { 6543 phy_port = si->port_l2p_mapping[port]; 6544 if (phy_port == -1) { /* unused port */ 6545 continue; 6546 } 6547 /* 26 ports per PGW_CL */ 6548 si->port_group[port] = (phy_port - 1) / MONTEREY_PORTS_PER_PGW; 6549 si->port_serdes[port] = (phy_port - 1) / MONTEREY_PORTS_PER_TSC; 6550 6551 SOC_PBMP_PORT_ADD(si->xpipe_pbm, port); 6552 6553 } 6554 SOC_PBMP_ASSIGN(si->pipe_pbm[0], si->xpipe_pbm); 6555 /* Assign mmu ports for all active and inactive ports */ 6556 SOC_IF_ERROR_RETURN(soc_monterey_mmu_ports_assign(unit)); 6557 6558 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 6559 LOG_CLI((BSL_META_U(unit, "physical to mmu mapping:"))); 6560 for (index = 0; index < num_phy_port; index++) { 6561 if (index % 16 == 0) { 6562 LOG_CLI((BSL_META_U(unit, "\n "))); 6563 } 6564 LOG_CLI((BSL_META_U(unit, " %3d"), 6565 si->port_p2m_mapping[index])); 6566 } 6567 LOG_CLI((BSL_META_U(unit, "\n"))); 6568 } 6569 6570 SOC_IF_ERROR_RETURN(soc_mn_phy_info_init(unit)); 6571 /* update port_init_speed array for all ports */ 6572 SOC_IF_ERROR_RETURN(_soc_mn_ports_speed_init_update(unit)); 6573 SOC_IF_ERROR_RETURN(soc_mn_port_ovs_speed_group_validate(unit)); 6574 SOC_IF_ERROR_RETURN(soc_mn_port_mixed_sister_speed_validate(unit)); 6575 return SOC_E_NONE; 6576 } 6577 6578 soc_error_t 6579 soc_monterey_port_reg_blk_index_get(int unit, int port, soc_block_type_t blktype, int *block) 6580 { 6581 uint16 dev_id; 6582 uint8 rev_id; 6583 int phy_port; 6584 6585 soc_cm_get_id(unit, &dev_id, &rev_id); 6586 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 6587 6588 switch (blktype) { 6589 case SOC_BLK_CLG2PORT: 6590 case SOC_BLK_CLPORT: 6591 if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit, port)) { 6592 if (phy_port == 17) { 6593 *block = (rev_id == BCM56560_A0_REV_ID ? 11 : 7); 6594 } else if (phy_port == 53) { 6595 *block = (rev_id == BCM56560_A0_REV_ID ? 14 : 8); 6596 } else { 6597 return SOC_E_PARAM; 6598 } 6599 } 6600 break; 6601 case SOC_BLK_CXXPORT: 6602 if ((phy_port >= 17) && (phy_port <= 28)) { 6603 *block = (rev_id == BCM56560_A0_REV_ID ? 18 : 10); 6604 } else if ((phy_port >= 53) && (phy_port <= 64)) { 6605 *block = (rev_id == BCM56560_A0_REV_ID ? 19 : 11); 6606 } else { 6607 return SOC_E_PARAM; 6608 } 6609 break; 6610 default: 6611 break; 6612 } 6613 return SOC_E_NONE; 6614 } 6615 6616 6617 #define _SOC_MN_DEF_TEMP_MAX 130 6618 6619 static uint32 _soc_mn_temp_mon_mask[SOC_MAX_NUM_DEVICES]; 6620 6621 6622 /* 6623 * Function: _soc_monterey_tsc_disable 6624 * 6625 * Purpose: 6626 * Function to dsiable unused TSCs in the chip. 6627 */ 6628 int 6629 soc_monterey_tsc_disable(int unit) 6630 { 6631 soc_info_t *si = &SOC_INFO(unit); 6632 uint32 tsc_enable = 0; 6633 int lane, phy_port, tsc, port; 6634 6635 for (phy_port = 1; 6636 phy_port <= MONTEREY_PORTS_PER_PIPE; 6637 phy_port = (phy_port + MONTEREY_PORTS_PER_TSC)) { 6638 6639 tsc = (phy_port - 1) / MONTEREY_PORTS_PER_TSC; 6640 for (lane = 0; lane < MONTEREY_PORTS_PER_TSC; lane++) { 6641 port = si->port_p2l_mapping[phy_port + lane]; 6642 if (port != -1) { 6643 tsc_enable |= (1 << tsc); 6644 if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit,port)) { 6645 tsc_enable |= (1 << (tsc + 1)); 6646 tsc_enable |= (1 << (tsc + 2)); 6647 } 6648 break; 6649 } 6650 } 6651 } 6652 6653 /* TSC2/3/6/9/12/13 are master PLL cores. Never disable them */ 6654 tsc_enable |= 0x324c; 6655 6656 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, TOP_TSC_ENABLEr, 6657 REG_PORT_ANY, 0, tsc_enable)); 6658 6659 return SOC_E_NONE; 6660 } 6661 6662 static int 6663 _soc_monterey_tsc_refclk_set(int unit) 6664 { 6665 uint64 rval64; 6666 soc_reg_t reg; 6667 int phy_port, pm; 6668 tsc_dpll_refclk_connect_t *refclk_connect; 6669 int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100; 6670 soc_info_t *si = &SOC_INFO(unit); 6671 6672 SHR_BITCLR_RANGE(si->pm_ref_master_bitmap, 0, SOC_MAX_NUM_BLKS); 6673 6674 for(pm = 0; pm < PM_NUM; pm++) { 6675 phy_port = pm * 4 + 1; 6676 if (soc_monterey_port_is_falcon(unit, phy_port)) { 6677 reg = CLPORT_XGXS0_CTRL_REGr; 6678 } else { 6679 reg = XLPORT_XGXS0_CTRL_REGr; 6680 } 6681 refclk_connect = &monterey_tsc_refclk_connect[pm]; 6682 6683 /* set refclock connect */ 6684 SOC_REG_RST_VAL_GET(unit, reg, rval64); 6685 6686 soc_reg64_field32_set(unit, reg, &rval64, PLL0_REFIN_ENf, refclk_connect->pll0_refclk_select); 6687 soc_reg64_field32_set(unit, reg, &rval64, PLL0_REFOUT_ENf, refclk_connect->pll0_master_enable); 6688 soc_reg64_field32_set(unit, reg, &rval64, PLL0_LC_REFSELf, refclk_connect->pll0_lc_refclk_select); 6689 6690 soc_reg64_field32_set(unit, reg, &rval64, PLL1_REFIN_ENf, refclk_connect->pll1_refclk_select); 6691 soc_reg64_field32_set(unit, reg, &rval64, PLL1_REFOUT_ENf, refclk_connect->pll1_master_enable); 6692 soc_reg64_field32_set(unit, reg, &rval64, PLL1_LC_REFSELf, !refclk_connect->pll1_lc_refclk_select); 6693 6694 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64)); 6695 6696 /* OOS master PLL core */ 6697 if(monterey_tsc_is_master_pll(pm)) { 6698 /* De-assert IDDQ */ 6699 soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0); 6700 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64)); 6701 6702 /* De-assert power down */ 6703 soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0); 6704 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64)); 6705 sal_usleep(sleep_usec); 6706 6707 /* Reset XGXS */ 6708 soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0); 6709 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64)); 6710 sal_usleep(sleep_usec + 10000); 6711 6712 /* Bring XGXS out of reset */ 6713 soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1); 6714 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64)); 6715 6716 /* Mark as master pll core */ 6717 SHR_BITSET(si->pm_ref_master_bitmap, SOC_PORT_BINDEX(unit, phy_port)); 6718 } 6719 6720 /* set internal termination to 200 Ohm */ 6721 if (soc_monterey_port_is_falcon(unit, phy_port)) { 6722 if (refclk_connect->pll0_master_enable) { 6723 SOC_REG_RST_VAL_GET(unit, CLPORT_PMD_PLL0_CTRL_CONFIGr, rval64); 6724 soc_reg64_field32_set(unit, CLPORT_PMD_PLL0_CTRL_CONFIGr, &rval64, PLL0_RTERM200f, 1); 6725 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, CLPORT_PMD_PLL0_CTRL_CONFIGr, phy_port, 0, rval64)); 6726 } 6727 6728 if (refclk_connect->pll1_master_enable) { 6729 SOC_REG_RST_VAL_GET(unit, CLPORT_PMD_PLL1_CTRL_CONFIGr, rval64); 6730 soc_reg64_field32_set(unit, CLPORT_PMD_PLL1_CTRL_CONFIGr, &rval64, PLL1_RTERM200f, 1); 6731 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, CLPORT_PMD_PLL1_CTRL_CONFIGr, phy_port, 0, rval64)); 6732 } 6733 } else { 6734 if (refclk_connect->pll0_master_enable || refclk_connect->pll1_master_enable) { 6735 SOC_REG_RST_VAL_GET(unit, XLPORT_PMD_PLL_CTRL_CONFIGr, rval64); 6736 soc_reg64_field32_set(unit, XLPORT_PMD_PLL_CTRL_CONFIGr, &rval64, REFCLK_TERM_SELf, 1); 6737 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, XLPORT_PMD_PLL_CTRL_CONFIGr, phy_port, 0, rval64)); 6738 } 6739 } 6740 } 6741 6742 return SOC_E_NONE; 6743 } 6744 6745 void 6746 soc_monterey_sbus_ring_map_config(int unit) 6747 { 6748 uint16 dev_id; 6749 uint8 rev_id; 6750 6751 /* 6752 * SBUS Ring # Start Through Blocks End 6753 * 0 CMIC IP CMIC 6754 * 1 CMIC EP CMIC 6755 * 2 CMIC MMU CMIC 6756 * 3 CMIC TSC0 - TSC1 - TSC2 - TSC3 - PGW0 - TSC4_5_6 - TSC7 - TSC8 CMIC 6757 * 4 CMIC TSC9 - TSC10 - TSC11 - TSC12 - PGW1 - TSC13_14_15 - TSC16 - TSC17 CMIC 6758 * 5 CMIC TOP REGISTERS - OTPC - AVS - SER CMIC 6759 * 6 CMIC RDB CMIC 6760 * 7 CMIC Not used CMIC 6761 */ 6762 6763 WRITE_CMIC_SBUS_RING_MAP_0_7r(unit, 0x43052100); 6764 WRITE_CMIC_SBUS_RING_MAP_8_15r(unit, 0x33333333); 6765 WRITE_CMIC_SBUS_RING_MAP_16_23r(unit, 0x44444333); 6766 WRITE_CMIC_SBUS_RING_MAP_24_31r(unit, 0x50444444); 6767 WRITE_CMIC_SBUS_RING_MAP_32_39r(unit, 0x00643055); 6768 WRITE_CMIC_SBUS_RING_MAP_40_47r(unit, 0x00000000); 6769 WRITE_CMIC_SBUS_RING_MAP_48_55r(unit, 0x00000000); 6770 WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x00000000); 6771 6772 6773 soc_cm_get_id(unit, &dev_id, &rev_id); 6774 6775 if (rev_id == BCM56560_A0_REV_ID) { 6776 WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x1000); 6777 } else { 6778 WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x7d0); 6779 } 6780 6781 return; 6782 } 6783 6784 int 6785 soc_monterey_chip_reset(int unit) 6786 { 6787 uint16 dev_id; 6788 uint8 rev_id; 6789 uint32 rval, to_usec; 6790 soc_reg_t reg; 6791 int index; 6792 int num_ecmp_rh_flowset_entries; 6793 int rh_table_config_encoding; 6794 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 6795 int num_overlay_ecmp_rh_flowset_entries; 6796 int rh_bank_sel = 0x0; 6797 int ecmp_levels = 1; 6798 #endif 6799 soc_pbmp_t cpri_pbmp; 6800 int temp_mask, temp_thr, power_reset = 0; 6801 static const soc_reg_t temp_thr_reg[] = { 6802 TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr, 6803 TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr, 6804 TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr, 6805 TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr 6806 }; 6807 static const char *temp_thr_prop[] = { 6808 "temp0_threshold", "temp1_threshold", "temp2_threshold", 6809 "temp3_threshold", "temp4_threshold", "temp5_threshold", 6810 "temp6_threshold", "temp7_threshold" 6811 }; 6812 static const soc_reg_t lcpll_reset_field[] = { 6813 TOP_XG_PLL0_RST_Lf, TOP_XG_PLL1_RST_Lf, 6814 TOP_XG_PLL2_RST_Lf, TOP_XG_PLL3_RST_Lf 6815 }; 6816 static const soc_reg_t lcpll_post_reset_field[] = { 6817 TOP_XG_PLL0_POST_RST_Lf, TOP_XG_PLL1_POST_RST_Lf, 6818 TOP_XG_PLL2_POST_RST_Lf, TOP_XG_PLL3_POST_RST_Lf 6819 }; 6820 6821 6822 #if 0 6823 static const soc_reg_t lcpll_ctrl1_reg[] = { 6824 TOP_XG_PLL0_CTRL_1r, TOP_XG_PLL1_CTRL_1r, 6825 TOP_XG_PLL2_CTRL_1r, TOP_XG_PLL3_CTRL_1r, 6826 }; 6827 static const soc_reg_t lcpll_ctrl3_reg[] = { 6828 TOP_XG_PLL0_CTRL_3r, TOP_XG_PLL1_CTRL_3r, 6829 TOP_XG_PLL2_CTRL_3r, TOP_XG_PLL3_CTRL_3r 6830 }; 6831 static const soc_reg_t lcpll_ctrl4_reg[] = { 6832 TOP_XG_PLL0_CTRL_4r, TOP_XG_PLL1_CTRL_4r, 6833 TOP_XG_PLL2_CTRL_4r, TOP_XG_PLL3_CTRL_4r 6834 }; 6835 #endif 6836 static const soc_reg_t lcpll_status_reg[] = { 6837 TOP_XG_PLL0_STATUSr, TOP_XG_PLL1_STATUSr, 6838 TOP_XG_PLL2_STATUSr, TOP_XG_PLL3_STATUSr 6839 }; 6840 6841 /* Settings for 500 MHz TSPLL output clock. */ 6842 unsigned ts_ref_freq = 0; 6843 unsigned ts_idx = 0; 6844 6845 static const soc_pll_param_t ts_pll[] = { 6846 /* Fref, Ndiv_int, Ndiv_frac, Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */ 6847 {12800000, 273, 0x70000, 1, 7, 0, 2, 3, 1}, /* Ndiv = 273.4375 */ 6848 {20000000, 175, 0, 1, 7, 0, 2, 3, 1}, /* Ndiv = 175.0 */ 6849 {25000000, 140, 0, 1, 7, 0, 2, 3, 1}, /* Ndiv = 140.0 */ 6850 {32000000, 109, 0x60000, 1, 7, 0, 2, 3, 1}, /* Ndiv = 109.375 */ 6851 {50000000, 70, 0, 1, 7, 0, 2, 3, 1}, /* Ndiv = 70.0 */ 6852 { 0, 140, 0, 1, 7, 0, 2, 3, 1} /* 25 MHz, from internal reference. */ 6853 }; 6854 6855 /* Settings for 20 MHz BSPLL output clock. */ 6856 unsigned bs_ref_freq = 0; 6857 unsigned bs_idx = 0; 6858 uint32 bs_ndiv_high, bs_ndiv_low; 6859 6860 static const soc_pll_param_t bs_pll[] = { 6861 /* Fref, Ndiv_int, Ndiv_frac, Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */ 6862 {12800000, 273, 0x70000000, 1, 175, 0, 2, 3, 1}, 6863 {20000000, 175, 0, 1, 175, 0, 2, 3, 1}, 6864 {25000000, 140, 0, 1, 175, 0, 2, 3, 1}, 6865 {32000000, 109, 0x60000000, 1, 175, 0, 2, 3, 1}, 6866 {50000000, 70, 0, 1, 175, 0, 2, 3, 1}, 6867 { 0, 60, 0, 1, 150, 0, 2, 3, 1} /* 25 MHz, from internal reference. */ 6868 }; 6869 static const int monterey_freq_list[] = { 862, 817, 667, 550, 450}; 6870 int max_frequency, def_freq; 6871 int freq_list_len = 0 , sel = 0; 6872 int const *freq_list; 6873 soc_info_t *si; 6874 si = &SOC_INFO(unit); 6875 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 6876 (10 * MILLISECOND_USEC); 6877 soc_monterey_sbus_ring_map_config(unit); 6878 6879 sal_usleep(to_usec); 6880 6881 soc_cm_get_id(unit, &dev_id, &rev_id); 6882 SOC_IF_ERROR_RETURN(soc_monterey_frequency_get(unit, &max_frequency, &def_freq)); 6883 freq_list = monterey_freq_list; 6884 freq_list_len = sizeof(monterey_freq_list) / sizeof(int); 6885 if (si->frequency != def_freq) { 6886 for (sel = 0; sel < freq_list_len; sel++) { 6887 if (si->frequency == freq_list[sel]) { 6888 break; 6889 } 6890 } 6891 6892 LOG_CLI((BSL_META_U(unit, 6893 "*** change CORE_CLK_FREQ_SEL to %d\n"), sel)); 6894 LOG_CLI((BSL_META_U(unit, 6895 "*** change core clock frequency to %dMHz\n"), 6896 si->frequency)); 6897 6898 SOC_IF_ERROR_RETURN(READ_TOP_CORE_CLK_FREQ_SELr(unit, &rval)); 6899 soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval, 6900 SW_CORE_CLK_SEL_ENf, 1); 6901 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval)); 6902 soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval, 6903 CORE_CLK_FREQ_SELf, sel); 6904 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval)); 6905 6906 sal_usleep(to_usec); 6907 } 6908 6909 6910 6911 /* 6912 * For TD2+ and TD+ compatible packages where there is no 1.25V supply in the package, 6913 * ams_pll_drv_hv_disable needs to be set to 1. 6914 * 6915 * ams_pll_drv_hv_disable: This is the main TX driver mode for Falcon, and is properly enabled 6916 * when TVDD1P25 = 1.25V, and tx_drv_hv_disable is set to its default value, "0". 6917 * To prevent damage to the output driver, this bit must always be "0" if TVDD1P25 = 1.25V 6918 */ 6919 6920 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_5r(unit, &rval)); 6921 power_reset = !soc_reg_field_get(unit, TOP_XG_PLL0_CTRL_5r, rval, 6922 RESERVEDf); 6923 rval = 0 ; 6924 /* Put TS, BS PLLs to reset before changing PLL control registers */ 6925 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 6926 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6927 TOP_TS_PLL_RST_Lf, 0); 6928 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6929 TOP_BS_PLL0_RST_Lf, 0); 6930 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6931 TOP_BS_PLL1_RST_Lf, 0); 6932 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6933 TOP_TS_PLL_POST_RST_Lf, 0); 6934 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6935 TOP_BS_PLL0_POST_RST_Lf, 0); 6936 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6937 TOP_BS_PLL1_POST_RST_Lf, 0); 6938 if (power_reset) { 6939 for (index = 0; index < COUNTOF(lcpll_reset_field); index++) { 6940 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6941 lcpll_reset_field[index], 0); 6942 } 6943 6944 for (index = 0; index < COUNTOF(lcpll_post_reset_field); index++) { 6945 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 6946 lcpll_post_reset_field[index], 0); 6947 } 6948 } 6949 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 6950 if (power_reset && soc_property_get(unit, spn_LC_PLL_EXT_CLOCK, 0)) { 6951 rval = 0; 6952 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_8r(unit, &rval)); 6953 soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_8r, &rval, 6954 LEGACY_HO_LOGIC_ENf,1); 6955 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_8r(unit, rval)); 6956 6957 rval = 0; 6958 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_8r(unit, &rval)); 6959 soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_8r, &rval, 6960 LEGACY_HO_LOGIC_ENf,1); 6961 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_8r(unit, rval)); 6962 6963 rval = 0; 6964 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_0r(unit, &rval)); 6965 soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_0r, &rval, 6966 CH0_MDIVf,0x5); 6967 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_0r(unit, rval)); 6968 rval = 0; 6969 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_8r(unit, &rval)); 6970 soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_8r, &rval, 6971 PLL_FBDIV_1f,0x580); 6972 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_8r(unit, rval)); 6973 rval = 0; 6974 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_0r(unit, &rval)); 6975 soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_0r, &rval, 6976 CH0_MDIVf,0x5); 6977 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_0r(unit, rval)); 6978 rval = 0; 6979 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_8r(unit, &rval)); 6980 soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_8r, &rval, 6981 PLL_FBDIV_1f,0x580); 6982 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_8r(unit, rval)); 6983 rval = 0; 6984 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_8r(unit, &rval)); 6985 soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_8r, &rval, 6986 LEGACY_HO_LOGIC_ENf,0); 6987 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_8r(unit, rval)); 6988 6989 rval = 0; 6990 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_8r(unit, &rval)); 6991 soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_8r, &rval, 6992 LEGACY_HO_LOGIC_ENf,0); 6993 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_8r(unit, rval)); 6994 } 6995 6996 6997 rval = 0; 6998 6999 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_7r(unit, &rval)); 7000 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_7r, &rval, 7001 PI_RESETf, 0); 7002 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_7r(unit, rval)); 7003 7004 rval = 0; 7005 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_0r(unit, &rval)); 7006 soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_0r, &rval, 7007 DITHER_CTRL_N1f, SOC_MONTEREY_TS_PLL_N1); 7008 soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_0r, &rval, 7009 DITHER_CTRL_N2f, SOC_MONTEREY_TS_PLL_N2); 7010 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_0r(unit, rval)); 7011 rval = 0; 7012 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_1r(unit, &rval)); 7013 soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_1r, &rval, 7014 DITHER_CTRL_M1f, SOC_MONTEREY_TS_PLL_M1); 7015 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_1r(unit, rval)); 7016 rval = 0; 7017 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_2r(unit, &rval)); 7018 soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_2r, &rval, 7019 DITHER_CTRL_M2f, SOC_MONTEREY_TS_PLL_M1); 7020 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_2r(unit, rval)); 7021 7022 rval = 0; 7023 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_3r(unit, &rval)); 7024 soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_3r, &rval, 7025 DITHER_CTRL_PMAX1f, SOC_MONTEREY_TS_PLL_PMAX1); 7026 soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_3r, &rval, 7027 DITHER_CTRL_PMAX2f, SOC_MONTEREY_TS_PLL_PMAX2); 7028 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_3r(unit, rval)); 7029 rval = 0; 7030 /* Configure TS PLL */ 7031 ts_ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0); /* 0->internal reference */ 7032 7033 for (ts_idx = 0; ts_idx < sizeof(ts_pll)/sizeof(ts_pll[0]); ++ts_idx) { 7034 if (ts_pll[ts_idx].ref_freq == ts_ref_freq) { 7035 break; 7036 } 7037 } 7038 if (ts_idx == sizeof(ts_pll)/sizeof(ts_pll[0])) { 7039 /* Valid configuration lookup failed. Use internal reference. */ 7040 ts_idx = 5; 7041 ts_ref_freq = 0; 7042 } 7043 7044 /* Do not change PLL settings for internal reference */ 7045 if(ts_ref_freq) { 7046 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit, &rval)); 7047 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, FREF_SELf, (ts_ref_freq != 0)); 7048 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_1r(unit, rval)); 7049 7050 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit,&rval)); 7051 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, PDIVf, 7052 soc_property_get(unit, spn_PTP_TS_PLL_PDIV, ts_pll[ts_idx].pdiv)); 7053 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, CH0_MDIVf, 7054 soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, ts_pll[ts_idx].mdiv)); 7055 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_3r(unit, rval)); 7056 7057 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval)); 7058 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_INTf, 7059 soc_property_get(unit, spn_PTP_TS_PLL_N, ts_pll[ts_idx].ndiv_int)); 7060 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_FRACf, ts_pll[ts_idx].ndiv_frac); 7061 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_4r(unit, rval)); 7062 7063 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_5r(unit,&rval)); 7064 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KAf, 7065 soc_property_get(unit, spn_PTP_TS_KA, ts_pll[ts_idx].ka)); 7066 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KIf, 7067 soc_property_get(unit, spn_PTP_TS_KI, ts_pll[ts_idx].ki)); 7068 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KPf, 7069 soc_property_get(unit, spn_PTP_TS_KP, ts_pll[ts_idx].kp)); 7070 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_5r(unit, rval)); 7071 } 7072 7073 /* Set 250Mhz (implies 4ns resolution) default timesync clock to 7074 calculate assymentric delays */ 7075 SOC_TIMESYNC_PLL_CLOCK_NS(unit) = (1/250 * 1000); /* clock period in nanoseconds */ 7076 7077 /* Configure BroadSync PLLs. */ 7078 bs_ref_freq = soc_property_get(unit, spn_PTP_BS_FREF, 0); /* 0->internal reference */ 7079 7080 for (bs_idx = 0; bs_idx < sizeof(bs_pll)/sizeof(bs_pll[0]); ++bs_idx) { 7081 if (bs_pll[bs_idx].ref_freq == bs_ref_freq) { 7082 break; 7083 } 7084 } 7085 if (bs_idx == sizeof(bs_pll)/sizeof(bs_pll[0])) { 7086 /* Valid configuration lookup failed. Use internal reference. */ 7087 bs_idx = 5; 7088 bs_ref_freq = 0; 7089 } 7090 7091 /* PLL settings for internal & external reference */ 7092 7093 bs_ndiv_high = ((soc_property_get(unit, spn_PTP_BS_NDIV_INT, 7094 bs_pll[bs_idx].ndiv_int) << 6) | 7095 ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC, 7096 bs_pll[bs_idx].ndiv_frac) >> 26) & 0x3f)); 7097 bs_ndiv_low = ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC, 7098 bs_pll[bs_idx].ndiv_frac) << 6) & 0xffffc000); 7099 7100 /* Configure BS PLL0 */ 7101 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_1r(unit, &rval)); 7102 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0)); 7103 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_1r(unit, rval)); 7104 7105 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval)); 7106 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, PDIVf, 7107 soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv)); 7108 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, CH0_MDIVf, 7109 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 7110 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval)); 7111 /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */ 7112 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_5r(unit,&rval)); 7113 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low); 7114 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_5r(unit, rval)); 7115 7116 /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */ 7117 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_6r(unit,&rval)); 7118 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high); 7119 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_6r(unit, rval)); 7120 7121 #if 0 7122 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_4r(unit, &rval)); 7123 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KAf, 7124 soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka)); 7125 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KIf, 7126 soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki)); 7127 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KPf, 7128 soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp)); 7129 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_4r(unit, rval)); 7130 #endif 7131 7132 /* Configure BS PLL1 */ 7133 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_1r(unit, &rval)); 7134 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0)); 7135 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_1r(unit, rval)); 7136 7137 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval)); 7138 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, PDIVf, 7139 soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv)); 7140 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, CH0_MDIVf, 7141 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 7142 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval)); 7143 7144 /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */ 7145 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_5r(unit,&rval)); 7146 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low); 7147 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_5r(unit, rval)); 7148 7149 /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */ 7150 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_6r(unit,&rval)); 7151 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high); 7152 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_6r(unit, rval)); 7153 7154 #if 0 7155 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_4r(unit, &rval)); 7156 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KAf, 7157 soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka)); 7158 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KIf, 7159 soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki)); 7160 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KPf, 7161 soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp)); 7162 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_4r(unit, rval)); 7163 7164 #endif 7165 7166 /* Set the BS PLL update rate to 12.5M */ 7167 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_7r(unit, &rval)); 7168 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_7r, &rval, PROG_DIV_CTRLf, 0x2); 7169 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_7r(unit, rval)); 7170 7171 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_7r(unit, &rval)); 7172 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_7r, &rval, PROG_DIV_CTRLf, 0x2); 7173 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_7r(unit, rval)); 7174 7175 /* Bring LCPLL, time sync PLL, BroadSync PLL out of reset */ 7176 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 7177 if (power_reset) { 7178 for (index = 0; index < COUNTOF(lcpll_reset_field); index++) { 7179 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7180 lcpll_reset_field[index], 1); 7181 } 7182 } 7183 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 7184 1); 7185 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf, 7186 1); 7187 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf, 7188 1); 7189 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PMB_RST_Lf, 1); 7190 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_ARS_RST_Lf, 1); 7191 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1); 7192 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 7193 sal_usleep(to_usec); 7194 SOC_PBMP_CLEAR(cpri_pbmp); 7195 cpri_pbmp = soc_property_get_pbmp_default(unit, 7196 spn_PBMP_XPORT_CPRI, cpri_pbmp); 7197 if (!SAL_BOOT_SIMULATION) { 7198 /* Check LCPLL lock status */ 7199 for (index = 0; index < 4; index++) { 7200 if ((index == 0 || index == 3) && SOC_PBMP_IS_NULL(cpri_pbmp)) { 7201 continue; 7202 } 7203 reg = lcpll_status_reg[index]; 7204 SOC_IF_ERROR_RETURN 7205 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 7206 if (!soc_reg_field_get(unit, reg, rval, TOP_XGPLL_LOCKf)) { 7207 LOG_ERROR(BSL_LS_SOC_COMMON, 7208 (BSL_META_U(unit, "LCPLL %d not locked on unit %d " 7209 "status = 0x%08x\n"), index, unit, rval)); 7210 } 7211 } 7212 /* Check time sync lock status */ 7213 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_STATUSr(unit, &rval)); 7214 if (!soc_reg_field_get(unit, TOP_TS_PLL_STATUSr, rval, PLL_LOCKf)) { 7215 LOG_ERROR(BSL_LS_SOC_COMMON, 7216 (BSL_META_U(unit, "TS_PLL not locked on unit %d " 7217 "status = 0x%08x\n"), unit, rval)); 7218 } 7219 7220 /* Check BroadSync lock status */ 7221 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_STATUSr(unit, &rval)); 7222 if (!soc_reg_field_get(unit, TOP_BS_PLL0_STATUSr, rval, PLL_LOCKf)) { 7223 LOG_ERROR(BSL_LS_SOC_COMMON, 7224 (BSL_META_U(unit, "BS_PLL0 not locked on unit %d " 7225 "status = 0x%08x\n"), unit, rval)); 7226 } 7227 7228 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_STATUSr(unit, &rval)); 7229 if (!soc_reg_field_get(unit, TOP_BS_PLL1_STATUSr, rval, PLL_LOCKf)) { 7230 LOG_ERROR(BSL_LS_SOC_COMMON, 7231 (BSL_META_U(unit, "BS_PLL1 not locked on unit %d " 7232 "status = 0x%08x\n"), unit, rval)); 7233 } 7234 } 7235 7236 /* De-assert LCPLL's post reset */ 7237 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 7238 7239 if (power_reset) { 7240 for (index = 0; index < COUNTOF(lcpll_post_reset_field); index++) { 7241 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7242 lcpll_post_reset_field[index], 1); 7243 } 7244 } 7245 7246 7247 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7248 TOP_TS_PLL_POST_RST_Lf, 1); 7249 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7250 TOP_BS_PLL0_POST_RST_Lf, 1); 7251 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7252 TOP_BS_PLL1_POST_RST_Lf, 1); 7253 7254 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7255 TOP_PVT_MON_MIN_RST_Lf, 1); 7256 7257 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 7258 if (power_reset ) { 7259 rval = 0 ; 7260 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_5r(unit, &rval)); 7261 soc_reg_field_set(unit, TOP_XG_PLL0_CTRL_5r, &rval, 7262 RESERVEDf, 1); 7263 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_5r(unit, rval)); 7264 } 7265 7266 rval = 0; 7267 sal_usleep(to_usec); 7268 7269 /* Running TS1 time-staper for now. Might be changed later during 7270 * time-module porting 7271 */ 7272 if (!SAL_BOOT_SIMULATION) { 7273 7274 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &rval)); 7275 soc_reg_field_set(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, &rval, 7276 ENABLEf, 0); 7277 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, rval)); 7278 7279 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, &rval)); 7280 soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r, &rval, 7281 ACC2f, 0); 7282 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, rval)); 7283 7284 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, &rval)); 7285 soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r, &rval, 7286 ACC1f, 0); 7287 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, rval)); 7288 7289 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, &rval)); 7290 soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r, &rval, 7291 ACC0f, 0); 7292 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, rval)); 7293 7294 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &rval)); 7295 soc_reg_field_set(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, &rval, 7296 ENABLEf, 1); 7297 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, rval)); 7298 7299 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, &rval)); 7300 soc_reg_field_set(unit, NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr, &rval, 7301 UINCf, 0x2000); 7302 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, rval)); 7303 7304 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, &rval)); 7305 soc_reg_field_set(unit, NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr, &rval, 7306 LINCf, 0x0); 7307 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, rval)); 7308 7309 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval)); 7310 soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &rval, 7311 ENABLEf, 0); 7312 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval)); 7313 7314 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, &rval)); 7315 soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r, &rval, 7316 ACC2f, 0); 7317 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, rval)); 7318 7319 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, &rval)); 7320 soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r, &rval, 7321 ACC1f, 0); 7322 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, rval)); 7323 7324 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, &rval)); 7325 soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r, &rval, 7326 ACC0f, 0); 7327 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, rval)); 7328 7329 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval)); 7330 soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &rval, 7331 ENABLEf, 1); 7332 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval)); 7333 7334 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, &rval)); 7335 soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr, &rval, 7336 UINCf, 0x2000); 7337 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, rval)); 7338 7339 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, &rval)); 7340 soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr, &rval, 7341 LINCf, 0x0); 7342 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, rval)); 7343 7344 SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &rval)); 7345 soc_reg_field_set(unit, NS_TIMESYNC_COUNTER_CONFIG_SELECTr, &rval, 7346 ENABLE_COMMON_CONTROLf, 0x0); 7347 SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, rval)); 7348 } 7349 7350 /* Set correct value for BG_ADJ */ 7351 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_0r(unit, &rval)); 7352 soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, BG_ADJf, 0); 7353 soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, MODEf, 2); 7354 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_0r(unit, rval)); 7355 7356 /* Enable high temperature interrupt monitoring. 7357 * Default on: pvtmon6 (close to core_plls at center of die). 7358 */ 7359 temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<6); 7360 /* The above is a 9 bit mask to indicate which temp sensor to hook up to 7361 * the interrupt. 7362 */ 7363 rval = 0; 7364 for (index = 0; index <COUNTOF(temp_thr_reg); index++) { 7365 uint32 trval; 7366 7367 /* data = 410.04-(temp/0.48705) = (410040-(temp*1000))/487 7368 * Note: Since this is a high temp value we can safely assume it to 7369 * always be a +ive number. This is in degrees celcius. 7370 */ 7371 temp_thr = soc_property_get(unit, temp_thr_prop[index], _SOC_MN_DEF_TEMP_MAX); 7372 if (temp_thr > 410) { 7373 LOG_ERROR(BSL_LS_SOC_COMMON, 7374 (BSL_META_U(unit, 7375 "Unsupported temp value %d !! Max 410. Using %d.\n"), 7376 temp_thr, _SOC_MN_DEF_TEMP_MAX)); 7377 temp_thr = _SOC_MN_DEF_TEMP_MAX; 7378 } 7379 /* Convert temperature to config data */ 7380 temp_thr = (410040-(temp_thr*1000))/487; 7381 SOC_IF_ERROR_RETURN 7382 (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval)); 7383 soc_reg_field_set(unit, temp_thr_reg[index], &trval, MAX_THRESHOLDf, 7384 temp_thr); 7385 SOC_IF_ERROR_RETURN 7386 (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval)); 7387 if (temp_mask & (1 << index)) { 7388 rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */ 7389 } 7390 } 7391 _soc_mn_temp_mon_mask[unit] = temp_mask; 7392 7393 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_MASKr(unit, rval)); 7394 /* Enable temp mon interrupt */ 7395 (void)soc_cmicm_intr3_enable(unit, 0x4); /* PVTMON_INTR bit 2 */ 7396 7397 /* Bring port blocks out of reset */ 7398 rval = 0; 7399 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 1); 7400 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 1); 7401 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1); 7402 WRITE_TOP_SOFT_RESET_REGr(unit, rval); 7403 7404 sal_usleep(to_usec); 7405 7406 /* Bring IP, EP, and MMU blocks out of reset */ 7407 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 7408 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 7409 7410 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1); 7411 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1); 7412 7413 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 7414 7415 sal_usleep(to_usec); 7416 7417 /* Bring PMs out of reset */ 7418 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_3r(unit, &rval)); 7419 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM0_RST_Lf, 1); 7420 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM1_RST_Lf, 1); 7421 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM2_RST_Lf, 1); 7422 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM3_RST_Lf, 1); 7423 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM4_RST_Lf, 1); 7424 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM5_RST_Lf, 1); 7425 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM6_RST_Lf, 1); 7426 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM7_RST_Lf, 1); 7427 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM8_RST_Lf, 1); 7428 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM9_RST_Lf, 1); 7429 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM10_RST_Lf, 1); 7430 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM11_RST_Lf, 1); 7431 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM12_RST_Lf, 1); 7432 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM13_RST_Lf, 1); 7433 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM14_RST_Lf, 1); 7434 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM15_RST_Lf, 1); 7435 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_MACSEC_RST_Lf, 1); 7436 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, rval)); 7437 sal_usleep(to_usec); 7438 7439 7440 7441 num_ecmp_rh_flowset_entries = soc_property_get(unit, 7442 spn_ECMP_RESILIENT_HASH_SIZE, 32768); 7443 switch (num_ecmp_rh_flowset_entries) { 7444 case 0: 7445 rh_table_config_encoding = 2; 7446 break; 7447 case 32768: 7448 rh_table_config_encoding = 0; 7449 break; 7450 case 65536: 7451 rh_table_config_encoding = 1; 7452 break; 7453 default: 7454 return SOC_E_CONFIG; 7455 } 7456 7457 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 7458 ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1); 7459 if ((soc_feature(unit, soc_feature_riot) || 7460 soc_feature(unit, soc_feature_multi_level_ecmp)) && 7461 ecmp_levels > 1) { 7462 7463 num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit, 7464 spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0); 7465 7466 if (SOC_FIELD_RANGE_CHECK( 7467 num_overlay_ecmp_rh_flowset_entries, 0, 16384)) { 7468 7469 num_overlay_ecmp_rh_flowset_entries = 16384; 7470 } else if (SOC_FIELD_RANGE_CHECK( 7471 num_overlay_ecmp_rh_flowset_entries, 16384, 32768)) { 7472 7473 num_overlay_ecmp_rh_flowset_entries = 32768; 7474 } else if (SOC_FIELD_RANGE_CHECK( 7475 num_overlay_ecmp_rh_flowset_entries, 32768, 49152)) { 7476 7477 num_overlay_ecmp_rh_flowset_entries = 49152; 7478 } else if (SOC_FIELD_RANGE_CHECK( 7479 num_overlay_ecmp_rh_flowset_entries, 49152, 65536)) { 7480 7481 num_overlay_ecmp_rh_flowset_entries = 65536; 7482 } 7483 7484 switch (num_overlay_ecmp_rh_flowset_entries) { 7485 case 0: 7486 rh_bank_sel = 0x0; 7487 break; 7488 case 16384: 7489 if (num_ecmp_rh_flowset_entries >= 16384) { 7490 rh_bank_sel = 0x1; 7491 } else { 7492 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7493 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7494 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7495 num_overlay_ecmp_rh_flowset_entries)); 7496 return SOC_E_CONFIG; 7497 } 7498 break; 7499 case 32768: 7500 if (num_ecmp_rh_flowset_entries >= 32768) { 7501 rh_bank_sel = 0x3; 7502 } else { 7503 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7504 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7505 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7506 num_overlay_ecmp_rh_flowset_entries)); 7507 return SOC_E_CONFIG; 7508 } 7509 break; 7510 case 49152: 7511 if (num_ecmp_rh_flowset_entries >= 49152) { 7512 rh_bank_sel = 0x7; 7513 } else { 7514 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7515 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7516 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7517 num_overlay_ecmp_rh_flowset_entries)); 7518 return SOC_E_CONFIG; 7519 } 7520 break; 7521 case 65536: 7522 if (num_ecmp_rh_flowset_entries >= 65536) { 7523 rh_bank_sel = 0xf; 7524 } else { 7525 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7526 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7527 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7528 num_overlay_ecmp_rh_flowset_entries)); 7529 return SOC_E_CONFIG; 7530 } 7531 break; 7532 default: 7533 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7534 "%s: Value for overlay RH entries is not correct : %d \n"), 7535 FUNCTION_NAME(), num_overlay_ecmp_rh_flowset_entries)); 7536 return SOC_E_CONFIG; 7537 } 7538 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, RH_ECMP_FLOWSET_BANK_SELr, 7539 REG_PORT_ANY, BANK_SELf, 7540 rh_bank_sel)); 7541 } 7542 #endif 7543 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr, 7544 REG_PORT_ANY, RH_FLOWSET_TABLE_CONFIG_ENCODINGf, 7545 rh_table_config_encoding)); 7546 7547 READ_TOP_PVTMON_CTRL_1r(unit, &rval); 7548 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1); 7549 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 7550 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0); 7551 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 7552 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1); 7553 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 7554 /* Bypass unused Port Blocks */ 7555 /* Bypass unused Port Blocks */ 7556 if (soc_property_get(unit, "disable_unused_port_blocks", TRUE)) { 7557 SOC_IF_ERROR_RETURN(soc_monterey_tsc_disable(unit)); 7558 } 7559 7560 7561 /* Do not use SBUS MDIO by default */ 7562 SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = NULL; 7563 SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = NULL; 7564 7565 /* Optionally allow SBUS MDIO for debug */ 7566 if (soc_property_get(unit, "monterey_sbus_mdio", 1)) { 7567 SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = _soc_monterey_mdio_reg_read; 7568 SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = _soc_monterey_mdio_reg_write; 7569 } 7570 7571 if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED) && 7572 soc_feature(unit, soc_feature_turbo_boot)) { 7573 SOC_HW_RESET_START(unit); 7574 } 7575 7576 return SOC_E_NONE; 7577 } 7578 7579 int 7580 soc_monterey_tsc_reset(int unit) 7581 { 7582 int blk, port; 7583 uint32 rval; 7584 uint64 rval64; 7585 7586 7587 /* Set tsc reference clock connection */ 7588 SOC_IF_ERROR_RETURN(_soc_monterey_tsc_refclk_set(unit)); 7589 7590 /* Though TSC/MAC reset is controlled by PortMod internally, 7591 * this is needed in case access to MAC registers is needed 7592 * before PortMod attach for cases like: 7593 * - To enable SER MAC interrupts 7594 * - Various sanity register read/write tests 7595 */ 7596 7597 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 7598 port = SOC_BLOCK_PORT(unit, blk); 7599 if(!(monterey_tsc_is_master_pll(SOC_INFO(unit).port_serdes[port]))) { 7600 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7601 } 7602 7603 SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval)); 7604 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 7605 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 7606 } 7607 7608 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 7609 port = SOC_BLOCK_PORT(unit, blk); 7610 if(!(monterey_tsc_is_master_pll(SOC_INFO(unit).port_serdes[port]))) { 7611 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7612 } 7613 7614 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval)); 7615 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 7616 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 7617 } 7618 7619 PBMP_PORT_ITER(unit, port) { 7620 if(IS_CPRI_PORT(unit, port)) { 7621 /* PLL0 select pll0_lc_refclk for CPRI, keep PLL1 pll1_lc_refclk for Ethernet */ 7622 SOC_IF_ERROR_RETURN(soc_reg_get(unit, CLPORT_XGXS0_CTRL_REGr, port, 0, &rval64)); 7623 soc_reg64_field32_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval64, PLL0_LC_REFSELf, 0); 7624 SOC_IF_ERROR_RETURN(soc_reg_set(unit, CLPORT_XGXS0_CTRL_REGr, port, 0, rval64)); 7625 7626 SOC_IF_ERROR_RETURN(READ_TOP_CTRL_CONFIGr(unit, port, &rval)); 7627 soc_reg_field_set(unit, TOP_CTRL_CONFIGr, &rval, CIP_TOP_CTRLf, 0); 7628 soc_reg_field_set(unit, TOP_CTRL_CONFIGr, &rval, PMD_IDDQf, 0); 7629 soc_reg_field_set(unit, TOP_CTRL_CONFIGr, &rval, CIP_TOP_CTRLf, 0); 7630 SOC_IF_ERROR_RETURN(WRITE_TOP_CTRL_CONFIGr(unit, port, rval)); 7631 SOC_IF_ERROR_RETURN(READ_CPMPORT_PMD_CTRLr(unit, port, &rval)); 7632 soc_reg_field_set(unit, CPMPORT_PMD_CTRLr, &rval, PMD_POR_H_RSTBf, 0); 7633 SOC_IF_ERROR_RETURN(WRITE_CPMPORT_PMD_CTRLr(unit, port, rval)); 7634 7635 if (!SAL_BOOT_PLISIM) { 7636 SOC_IF_ERROR_RETURN(READ_CPRI_RST_CTRLr(unit, port, &rval)); 7637 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_TX_Hf, 0); 7638 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_RX_Hf, 0); 7639 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_CIP_TX_Hf, 0); 7640 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_CIP_RX_Hf, 0); 7641 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_DATAPATH_RX_Hf, 0); 7642 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_DATAPATH_TX_Hf, 0); 7643 SOC_IF_ERROR_RETURN(WRITE_CPRI_RST_CTRLr(unit, port, rval)); 7644 } 7645 } 7646 } 7647 /* 7648 */ 7649 return SOC_E_NONE; 7650 } 7651 7652 7653 STATIC int 7654 _soc_monterey_clear_enabled_port_data (int unit) 7655 { 7656 uint64 rval64; 7657 int port; 7658 uint32 evc = 0; 7659 egr_vlan_control_1_entry_t entry1; 7660 egr_vlan_control_2_entry_t entry2; 7661 egr_vlan_control_3_entry_t entry3; 7662 7663 sal_memset(&entry1, 0, sizeof(entry1)); 7664 sal_memset(&entry2, 0, sizeof(entry2)); 7665 sal_memset(&entry3, 0, sizeof(entry3)); 7666 7667 /* Some registers are implemented in memory, need to clear them in order 7668 * to have correct parity value */ 7669 COMPILER_64_ZERO(rval64); 7670 PBMP_ALL_ITER(unit, port) { 7671 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry1)); 7672 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry2)); 7673 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry3)); 7674 7675 SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, 0)); 7676 SOC_IF_ERROR_RETURN(WRITE_EGR_SF_SRC_MODID_CHECKr(unit, port, rval64)); 7677 SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64)); 7678 SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ALL, port, &evc)); 7679 SOC_IF_ERROR_RETURN(WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0)); 7680 SOC_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, 0)); 7681 } 7682 7683 return SOC_E_NONE; 7684 } 7685 7686 STATIC int 7687 _soc_monterey_clear_all_port_data (int unit) 7688 { 7689 int r, p; 7690 uint32 addr; 7691 7692 SOC_IF_ERROR_RETURN(_soc_monterey_clear_enabled_port_data(unit)); 7693 7694 7695 7696 /* Clear TDBGCn regs for all indexes */ 7697 for (r = 0; r < 12; r++) { 7698 addr = 0x28000000 + r*0x100; 7699 for (p = 0; p < 106; p++) { 7700 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7701 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7702 } 7703 } 7704 7705 /* Clear TPCE */ 7706 addr = 0x28000f00; 7707 for (p = 0; p < 106; p++) { 7708 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7709 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7710 } 7711 return SOC_E_NONE; 7712 } 7713 7714 STATIC int 7715 _soc_monterey_clear_all_memory(int unit, int mmu_init) 7716 { 7717 int blk; 7718 int pgw, pgw_inst, num_pgw = 0; 7719 uint32 rval, in_progress[1]; 7720 int hw_reset_to, index, count; 7721 soc_reg_t hw_reset_reg; 7722 soc_timeout_t to; 7723 static const struct { 7724 soc_mem_t mem; 7725 uint32 skip_flags; /* always skip on QUICKTURN or XGSSIM */ 7726 } cam_list[] = { 7727 { CPU_COS_MAPm, BOOT_F_PLISIM }, 7728 { EFP_TCAMm, BOOT_F_PLISIM }, 7729 { FP_GLOBAL_MASK_TCAMm, BOOT_F_PLISIM }, 7730 { FP_TCAMm, BOOT_F_PLISIM }, 7731 { VFP_TCAMm, BOOT_F_PLISIM }, 7732 { FP_UDF_TCAMm, BOOT_F_PLISIM }, 7733 { ING_SNATm, BOOT_F_PLISIM }, 7734 { IP_MULTICAST_TCAMm, BOOT_F_PLISIM }, 7735 { L2_USER_ENTRYm, BOOT_F_PLISIM }, 7736 { L3_DEFIPm, BOOT_F_PLISIM }, 7737 { L3_DEFIP_PAIR_128m, BOOT_F_PLISIM }, 7738 { L3_TUNNELm, BOOT_F_PLISIM }, 7739 { MY_STATION_TCAMm, BOOT_F_PLISIM }, 7740 { UDF_CONDITIONAL_CHECK_TABLE_CAMm, BOOT_F_PLISIM }, 7741 { MY_STATION_TCAM_2m, BOOT_F_PLISIM }, 7742 { VLAN_SUBNETm, 0 },/* VLAN API needs all 0 mask */ 7743 { MY_STATION_TCAM_2m, BOOT_F_PLISIM }, 7744 #ifdef PLISIM 7745 /* In HW, these are the same as FP_GLOBAL_MASK_TCAM. 7746 * In simulation, they are separate instances. 7747 */ 7748 { FP_GM_FIELDSm, BOOT_F_PLISIM } 7749 #endif 7750 }; 7751 7752 if (mmu_init) { 7753 uint32 rval1; 7754 /* Start MMU memory initialization */ 7755 SOC_IF_ERROR_RETURN 7756 (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 0)); 7757 7758 SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1)); 7759 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0); 7760 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 7761 SOC_IF_ERROR_RETURN 7762 (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 1)); 7763 7764 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */ 7765 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1); 7766 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 7767 } 7768 7769 SOC_IF_ERROR_RETURN 7770 (_soc_monterey_mmu_init_default_val(unit)); 7771 7772 /* 7773 * Reset the PGW, IPIPE and EPIPE block 7774 */ 7775 rval = 0; 7776 hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r; 7777 soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1); 7778 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7779 7780 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) { 7781 num_pgw += 1; 7782 pgw = SOC_BLOCK_NUMBER(unit, blk); 7783 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 7784 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, pgw_inst, 0, rval)); 7785 } 7786 7787 rval = 0; 7788 hw_reset_reg = ING_HW_RESET_CONTROL_2r; 7789 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 7790 soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1); 7791 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7792 7793 /* Set count to # entries of largest IPIPE table */ 7794 count = (1 << soc_reg_field_length(unit, hw_reset_reg, COUNTf)) - 1; 7795 soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count); 7796 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval)); 7797 7798 sal_usleep(500); 7799 rval = 0; 7800 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 7801 7802 hw_reset_reg = EGR_HW_RESET_CONTROL_1r; 7803 soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1); 7804 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7805 /* Set count to # entries of largest EPIPE table (EGR_L3_NEXT_HOP) */ 7806 count = (1 << soc_reg_field_length(unit, hw_reset_reg, COUNTf)) - 1; 7807 soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count); 7808 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval)); 7809 7810 sal_usleep(500); 7811 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 7812 if (SAL_BOOT_QUICKTURN) { 7813 hw_reset_to = 10000000; 7814 } else { 7815 hw_reset_to = 50000; 7816 } 7817 soc_timeout_init(&to, hw_reset_to, 0); 7818 7819 /* Wait for PGW memory initialization done. */ 7820 hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r; 7821 /* in_progress = ((1 << num_pgw) - 1); */ /* 1b for each PGW */ 7822 in_progress[0] = 0; 7823 SHR_BITSET_RANGE(in_progress, 0, num_pgw); /* 1b for each PGW */ 7824 7825 do { 7826 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) { 7827 pgw = SOC_BLOCK_NUMBER(unit, blk); 7828 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 7829 if (SHR_BITGET(in_progress, pgw)) { /* PGW RESET not done yet */ 7830 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, 7831 pgw_inst, 0, &rval)); 7832 7833 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7834 SHR_BITCLR(in_progress, pgw); /* Clear bit corresponding to the PGW */ 7835 } 7836 } 7837 } 7838 7839 if (soc_timeout_check(&to)) { 7840 if (!SAL_BOOT_BCMSIM) { 7841 LOG_WARN(BSL_LS_SOC_COMMON, 7842 (BSL_META_U(unit, "PGW_ING_HW_RESET timeout\n"))); 7843 } 7844 break; 7845 } 7846 } while (in_progress[0] != 0); 7847 7848 /* Wait for EPIPE memory initialization done. */ 7849 in_progress[0] = 1; 7850 hw_reset_reg = EGR_HW_RESET_CONTROL_1r; 7851 do { 7852 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval)); 7853 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7854 in_progress[0] = 0; 7855 } 7856 if (soc_timeout_check(&to)) { 7857 if (!SAL_BOOT_BCMSIM) { 7858 LOG_WARN(BSL_LS_SOC_COMMON, 7859 (BSL_META_U(unit, "EGR_HW_RESET timeout\n"))); 7860 } 7861 break; 7862 } 7863 } while (in_progress[0] != 0); 7864 7865 /* Wait for IPIPE memory initialization done. */ 7866 in_progress[0] = 1; 7867 hw_reset_reg = ING_HW_RESET_CONTROL_2r; 7868 do { 7869 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval)); 7870 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7871 in_progress[0] = 0; 7872 } 7873 7874 if (soc_timeout_check(&to)) { 7875 if (!SAL_BOOT_BCMSIM) { 7876 LOG_WARN(BSL_LS_SOC_COMMON, 7877 (BSL_META_U(unit, "ING_HW_RESET timeout\n"))); 7878 } 7879 break; 7880 } 7881 } while (in_progress[0] != 0); 7882 7883 /* TCAM tables are not handled by hardware reset control */ 7884 if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_XGSSIM && !SAL_BOOT_BCMSIM) { 7885 for (index = 0; index < sizeof(cam_list) / sizeof(cam_list[0]); 7886 index++) { 7887 if (sal_boot_flags_get() & cam_list[index].skip_flags) { 7888 continue; 7889 } 7890 SOC_IF_ERROR_RETURN 7891 (soc_mem_clear(unit, cam_list[index].mem, COPYNO_ALL, TRUE)); 7892 } 7893 } 7894 7895 return SOC_E_NONE; 7896 } 7897 7898 7899 STATIC int 7900 _soc_monterey_port_mapping_init(int unit) 7901 { 7902 soc_info_t *si; 7903 soc_mem_t mem; 7904 uint32 rval; 7905 ing_physical_to_logical_port_number_mapping_table_entry_t entry; 7906 int port, phy_port; 7907 int num_port, num_phy_port; 7908 7909 si = &SOC_INFO(unit); 7910 7911 /* Ingress physical to logical port mapping */ 7912 mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm; 7913 num_phy_port = soc_mem_index_count(unit, mem); 7914 sal_memset(&entry, 0, sizeof(entry)); 7915 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 7916 port = si->port_p2l_mapping[phy_port]; 7917 soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf, 7918 port == -1 ? 0x7f : port); 7919 SOC_IF_ERROR_RETURN 7920 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry)); 7921 } 7922 7923 /* Ingress logical to physical port mapping */ 7924 num_port = soc_mem_index_count(unit, PORT_TABm) - 1; 7925 7926 for (port = 0; port < num_port; port++) { 7927 phy_port = si->port_l2p_mapping[port]; 7928 rval = 0; 7929 if (phy_port != -1) { 7930 soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval, 7931 VALIDf, 1); 7932 7933 /* IFP_GM_LOGICAL_TO_PHYSICAL_MAPP?ING.PHYSICAL_PORT_NUM is 7934 * merely a unique stream ID, it's not physical port number */ 7935 soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval, 7936 PHYSICAL_PORT_NUMf, 7937 si->port_p2m_mapping[phy_port] & 0x7f); 7938 } 7939 SOC_IF_ERROR_RETURN 7940 (WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval)); 7941 } 7942 7943 /* Egress logical to physical port mapping */ 7944 for (port = 0; port < num_port; port++) { 7945 phy_port = si->port_l2p_mapping[port]; 7946 rval = 0; 7947 soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr, 7948 &rval, PHYSICAL_PORT_NUMBERf, 7949 phy_port == -1 ? 0x7f : phy_port); 7950 SOC_IF_ERROR_RETURN 7951 (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port, 7952 rval)); 7953 } 7954 7955 /* MMU to physical port mapping and MMU to logical port mapping */ 7956 for (port = 0; port < num_port; port++) { 7957 phy_port = si->port_l2p_mapping[port]; 7958 if (phy_port == -1) { 7959 continue; 7960 } 7961 rval = 0; 7962 soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval, 7963 PHY_PORTf, phy_port); 7964 SOC_IF_ERROR_RETURN 7965 (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, port, 0, 7966 rval)); 7967 7968 rval = 0; 7969 soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval, 7970 LOGIC_PORTf, port); 7971 SOC_IF_ERROR_RETURN 7972 (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, port, 0, 7973 rval)); 7974 } 7975 7976 return SOC_E_NONE; 7977 } 7978 7979 #define MONTEREY_PGW_TDM_LENGTH MN_LR_LLS_LEN 7980 #define MONTEREY_PGW_TDM_OVS_SIZE MN_OS_LLS_GRP_LEN 7981 #define MONTEREY_PGW_TDM_SLOTS_PER_REG 4 7982 #define MONTEREY_MMU_TDM_LENGTH 512 7983 #define MONTEREY_MMU_OVS_GROUP_COUNT MN_OS_VBS_GRP_NUM 7984 #define MONTEREY_MMU_OVS_WT_GROUP_COUNT 8 7985 #define MONTEREY_MMU_OVS_GROUP_TDM_LENGTH MN_OS_VBS_GRP_LEN 7986 #define MONTEREY_IARB_TDM_LENGTH MN_LR_IARB_STATIC_LEN 7987 7988 7989 #define OVS_TOKEN MN_OVSB_TOKEN 7990 #define IDL1_TOKEN MN_IDL1_TOKEN 7991 #define IDL2_TOKEN MN_IDL2_TOKEN 7992 #define AUX_TOKEN MN_AUX_TOKEN 7993 #define SBUS_TOKEN MN_SBUS_TOKEN 7994 7995 #define NUM_EXT_PORTS MN_NUM_EXT_PORTS 7996 7997 #define PORT_STATE_UNUSED 0 /* PORT_STATE__DISABLED */ 7998 #define PORT_STATE_LINERATE 1 /* PORT_STATE__LINERATE */ 7999 #define PORT_STATE_OVERSUB 2 /* PORT_STATE__OVERSUB */ 8000 #define PORT_STATE_SUBPORT 3 /* PORT_STATE__COMBINED */ 8001 8002 enum _mn_ovs_speed_classes { 8003 mn_ovs_speed_None = 0, 8004 mn_ovs_speed_5G = 2, 8005 mn_ovs_speed_10G = 4, 8006 mn_ovs_speed_20G = 8, 8007 mn_ovs_speed_25G = 10, 8008 mn_ovs_speed_40G = 16, 8009 mn_ovs_speed_50G = 20, 8010 mn_ovs_speed_100G = 40 8011 }; 8012 8013 /* 8014 * MMU OVS TDM min. slot bandwidth is 5G. 8015 * Anything less than 5G will be grouped together and will have provision for up to 5G. 8016 */ 8017 #define MONTEREY_TDM_MMU_SPEED_GET(unit, speed) \ 8018 do { \ 8019 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed); \ 8020 if ((speed <= 5000) && (speed > 0)) { \ 8021 speed = 5000; \ 8022 } \ 8023 } while (0) 8024 8025 int 8026 _soc_monterey_mmu_ovs_speed_class_map_get(int unit, int *speed, int *spg, uint32 *sp_spacing) 8027 { 8028 MONTEREY_TDM_MMU_SPEED_GET(unit, *speed); 8029 switch (*speed) { 8030 case 5000: 8031 *sp_spacing = 0x14; 8032 *spg = mn_ovs_speed_5G; 8033 break; 8034 case 10000: 8035 *sp_spacing = 0x14; 8036 *spg = mn_ovs_speed_10G; 8037 break; 8038 case 20000: 8039 *sp_spacing = 0x0a; 8040 *spg = mn_ovs_speed_20G; 8041 break; 8042 case 25000: 8043 *sp_spacing = 0x0a; 8044 *spg = mn_ovs_speed_25G; 8045 break; 8046 case 40000: 8047 *sp_spacing = 0x0a; 8048 *spg = mn_ovs_speed_40G; 8049 break; 8050 case 50000: 8051 *sp_spacing = 0x0a; 8052 *spg = mn_ovs_speed_50G; 8053 break; 8054 case 100000: 8055 *sp_spacing = 0x04; 8056 *spg = mn_ovs_speed_100G; 8057 break; 8058 default: 8059 *sp_spacing = 0x0; 8060 *spg = mn_ovs_speed_None; 8061 return SOC_E_FAIL; 8062 } 8063 8064 return SOC_E_NONE; 8065 8066 } 8067 8068 8069 typedef struct soc_monterey_tdm_s { 8070 int tdm_bw; 8071 int is_oversub; 8072 8073 int speed[NUM_EXT_PORTS]; 8074 int port_state[NUM_EXT_PORTS]; 8075 8076 int pgw_tdm[MONTEREY_PGWS_PER_DEV][MONTEREY_PGW_TDM_LENGTH]; 8077 int mmu_tdm[MONTEREY_MMU_TDM_LENGTH + 1]; 8078 8079 struct { 8080 int pgw_ovs_tdm[MONTEREY_PGWS_PER_DEV][MONTEREY_PGW_TDM_LENGTH]; 8081 int pgw_ovs_spacing[MONTEREY_PGWS_PER_DEV][MONTEREY_PGW_TDM_LENGTH]; 8082 } ingress_ovs_tdm; 8083 8084 struct { 8085 int mmu_ovs_group_tdm[MONTEREY_MMU_OVS_GROUP_COUNT][MONTEREY_MMU_OVS_GROUP_TDM_LENGTH]; 8086 int mmu_ovs_group_speed[MONTEREY_MMU_OVS_GROUP_COUNT]; /* Speed for each OVS grp */ 8087 int mmu_ovs_group_wt_group[MONTEREY_MMU_OVS_GROUP_COUNT]; /* Weighti group for each OVS grp */ 8088 } egress_ovs_tdm; 8089 8090 int iarb_tdm_wrap_ptr; 8091 int iarb_tdm[MONTEREY_IARB_TDM_LENGTH]; 8092 int pgw0len; 8093 int pgw1len; 8094 } soc_monterey_tdm_t; 8095 8096 8097 8098 struct soc_monterey_misc_info_s { 8099 int tdm_active_cal; 8100 uint16 tdm_wtg_used[MONTEREY_MMU_OVS_WT_GROUP_COUNT]; 8101 soc_monterey_tdm_t tdm0; 8102 soc_monterey_tdm_t tdm1; 8103 } *soc_monterey_misc_info[SOC_MAX_NUM_DEVICES] = {0}; 8104 8105 #define MN_MISC(unit) (soc_monterey_misc_info[unit]) 8106 8107 8108 8109 8110 static const soc_field_t mn_mmu_ovs_group_wt_select_fields[] = { 8111 GRP0f, GRP1f, GRP2f, GRP3f, GRP4f, GRP5f, GRP6f, GRP7f 8112 }; 8113 8114 8115 static const soc_reg_t mn_pgw_lr_tdm_regs[2][40] = { 8116 { 8117 PGW_LR_TDM_REG_0r, PGW_LR_TDM_REG_1r, 8118 PGW_LR_TDM_REG_2r, PGW_LR_TDM_REG_3r, 8119 PGW_LR_TDM_REG_4r, PGW_LR_TDM_REG_5r, 8120 PGW_LR_TDM_REG_6r, PGW_LR_TDM_REG_7r, 8121 PGW_LR_TDM_REG_8r, PGW_LR_TDM_REG_9r, 8122 PGW_LR_TDM_REG_10r, PGW_LR_TDM_REG_11r, 8123 PGW_LR_TDM_REG_12r, PGW_LR_TDM_REG_13r, 8124 PGW_LR_TDM_REG_14r, PGW_LR_TDM_REG_15r, 8125 PGW_LR_TDM_REG_16r, PGW_LR_TDM_REG_17r, 8126 PGW_LR_TDM_REG_18r, PGW_LR_TDM_REG_19r, 8127 PGW_LR_TDM_REG_20r, PGW_LR_TDM_REG_21r, 8128 PGW_LR_TDM_REG_22r, PGW_LR_TDM_REG_23r, 8129 PGW_LR_TDM_REG_24r, PGW_LR_TDM_REG_25r, 8130 PGW_LR_TDM_REG_26r, PGW_LR_TDM_REG_27r, 8131 PGW_LR_TDM_REG_28r, PGW_LR_TDM_REG_29r, 8132 PGW_LR_TDM_REG_30r, PGW_LR_TDM_REG_31r, 8133 PGW_LR_TDM_REG_32r, PGW_LR_TDM_REG_33r, 8134 PGW_LR_TDM_REG_34r, PGW_LR_TDM_REG_35r, 8135 PGW_LR_TDM_REG_36r, PGW_LR_TDM_REG_37r, 8136 PGW_LR_TDM_REG_38r, PGW_LR_TDM_REG_39r 8137 }, 8138 { 8139 PGW_LR_TDM2_REG_0r, PGW_LR_TDM2_REG_1r, 8140 PGW_LR_TDM2_REG_2r, PGW_LR_TDM2_REG_3r, 8141 PGW_LR_TDM2_REG_4r, PGW_LR_TDM2_REG_5r, 8142 PGW_LR_TDM2_REG_6r, PGW_LR_TDM2_REG_7r, 8143 PGW_LR_TDM2_REG_8r, PGW_LR_TDM2_REG_9r, 8144 PGW_LR_TDM2_REG_10r, PGW_LR_TDM2_REG_11r, 8145 PGW_LR_TDM2_REG_12r, PGW_LR_TDM2_REG_13r, 8146 PGW_LR_TDM2_REG_14r, PGW_LR_TDM2_REG_15r, 8147 PGW_LR_TDM2_REG_16r, PGW_LR_TDM2_REG_17r, 8148 PGW_LR_TDM2_REG_18r, PGW_LR_TDM2_REG_19r, 8149 PGW_LR_TDM2_REG_20r, PGW_LR_TDM2_REG_21r, 8150 PGW_LR_TDM2_REG_22r, PGW_LR_TDM2_REG_23r, 8151 PGW_LR_TDM2_REG_24r, PGW_LR_TDM2_REG_25r, 8152 PGW_LR_TDM2_REG_26r, PGW_LR_TDM2_REG_27r, 8153 PGW_LR_TDM2_REG_28r, PGW_LR_TDM2_REG_29r, 8154 PGW_LR_TDM2_REG_30r, PGW_LR_TDM2_REG_31r, 8155 PGW_LR_TDM2_REG_32r, PGW_LR_TDM2_REG_33r, 8156 PGW_LR_TDM2_REG_34r, PGW_LR_TDM2_REG_35r, 8157 PGW_LR_TDM2_REG_36r, PGW_LR_TDM2_REG_37r, 8158 PGW_LR_TDM2_REG_38r, PGW_LR_TDM2_REG_39r 8159 } 8160 }; 8161 8162 static const soc_field_t mn_pgw_tdm_fields[] = { 8163 TDM_ENTRY0_PORT_IDf, TDM_ENTRY1_PORT_IDf, 8164 TDM_ENTRY2_PORT_IDf, TDM_ENTRY3_PORT_IDf, 8165 TDM_ENTRY4_PORT_IDf, TDM_ENTRY5_PORT_IDf, 8166 TDM_ENTRY6_PORT_IDf, TDM_ENTRY7_PORT_IDf, 8167 TDM_ENTRY8_PORT_IDf, TDM_ENTRY9_PORT_IDf, 8168 TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf, 8169 TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf, 8170 TDM_ENTRY14_PORT_IDf, TDM_ENTRY15_PORT_IDf, 8171 TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf, 8172 TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf, 8173 TDM_ENTRY20_PORT_IDf, TDM_ENTRY21_PORT_IDf, 8174 TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf, 8175 TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf, 8176 TDM_ENTRY26_PORT_IDf, TDM_ENTRY27_PORT_IDf, 8177 TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf, 8178 TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf, 8179 TDM_ENTRY32_PORT_IDf, TDM_ENTRY33_PORT_IDf, 8180 TDM_ENTRY34_PORT_IDf, TDM_ENTRY35_PORT_IDf, 8181 TDM_ENTRY36_PORT_IDf, TDM_ENTRY37_PORT_IDf, 8182 TDM_ENTRY38_PORT_IDf, TDM_ENTRY39_PORT_IDf, 8183 TDM_ENTRY40_PORT_IDf, TDM_ENTRY41_PORT_IDf, 8184 TDM_ENTRY42_PORT_IDf, TDM_ENTRY43_PORT_IDf, 8185 TDM_ENTRY44_PORT_IDf, TDM_ENTRY45_PORT_IDf, 8186 TDM_ENTRY46_PORT_IDf, TDM_ENTRY47_PORT_IDf, 8187 TDM_ENTRY48_PORT_IDf, TDM_ENTRY49_PORT_IDf, 8188 TDM_ENTRY50_PORT_IDf, TDM_ENTRY51_PORT_IDf, 8189 TDM_ENTRY52_PORT_IDf, TDM_ENTRY53_PORT_IDf, 8190 TDM_ENTRY54_PORT_IDf, TDM_ENTRY55_PORT_IDf, 8191 TDM_ENTRY56_PORT_IDf, TDM_ENTRY57_PORT_IDf, 8192 TDM_ENTRY58_PORT_IDf, TDM_ENTRY59_PORT_IDf, 8193 TDM_ENTRY60_PORT_IDf, TDM_ENTRY61_PORT_IDf, 8194 TDM_ENTRY62_PORT_IDf, TDM_ENTRY63_PORT_IDf, 8195 TDM_ENTRY64_PORT_IDf, TDM_ENTRY65_PORT_IDf, 8196 TDM_ENTRY66_PORT_IDf, TDM_ENTRY67_PORT_IDf, 8197 TDM_ENTRY68_PORT_IDf, TDM_ENTRY69_PORT_IDf, 8198 TDM_ENTRY70_PORT_IDf, TDM_ENTRY71_PORT_IDf, 8199 TDM_ENTRY72_PORT_IDf, TDM_ENTRY73_PORT_IDf, 8200 TDM_ENTRY74_PORT_IDf, TDM_ENTRY75_PORT_IDf, 8201 TDM_ENTRY76_PORT_IDf, TDM_ENTRY77_PORT_IDf, 8202 TDM_ENTRY78_PORT_IDf, TDM_ENTRY79_PORT_IDf, 8203 TDM_ENTRY80_PORT_IDf, TDM_ENTRY81_PORT_IDf, 8204 TDM_ENTRY82_PORT_IDf, TDM_ENTRY83_PORT_IDf, 8205 TDM_ENTRY84_PORT_IDf, TDM_ENTRY85_PORT_IDf, 8206 TDM_ENTRY86_PORT_IDf, TDM_ENTRY87_PORT_IDf, 8207 TDM_ENTRY88_PORT_IDf, TDM_ENTRY89_PORT_IDf, 8208 TDM_ENTRY90_PORT_IDf, TDM_ENTRY91_PORT_IDf, 8209 TDM_ENTRY92_PORT_IDf, TDM_ENTRY93_PORT_IDf, 8210 TDM_ENTRY94_PORT_IDf, TDM_ENTRY95_PORT_IDf, 8211 TDM_ENTRY96_PORT_IDf, TDM_ENTRY97_PORT_IDf, 8212 TDM_ENTRY98_PORT_IDf, TDM_ENTRY99_PORT_IDf, 8213 TDM_ENTRY100_PORT_IDf, TDM_ENTRY101_PORT_IDf, 8214 TDM_ENTRY102_PORT_IDf, TDM_ENTRY103_PORT_IDf, 8215 TDM_ENTRY104_PORT_IDf, TDM_ENTRY105_PORT_IDf, 8216 TDM_ENTRY106_PORT_IDf, TDM_ENTRY107_PORT_IDf, 8217 TDM_ENTRY108_PORT_IDf, TDM_ENTRY109_PORT_IDf, 8218 TDM_ENTRY110_PORT_IDf, TDM_ENTRY111_PORT_IDf, 8219 TDM_ENTRY112_PORT_IDf, TDM_ENTRY113_PORT_IDf, 8220 TDM_ENTRY114_PORT_IDf, TDM_ENTRY115_PORT_IDf, 8221 TDM_ENTRY116_PORT_IDf, TDM_ENTRY117_PORT_IDf, 8222 TDM_ENTRY118_PORT_IDf, TDM_ENTRY119_PORT_IDf, 8223 TDM_ENTRY120_PORT_IDf, TDM_ENTRY121_PORT_IDf, 8224 TDM_ENTRY122_PORT_IDf, TDM_ENTRY123_PORT_IDf, 8225 TDM_ENTRY124_PORT_IDf, TDM_ENTRY125_PORT_IDf, 8226 TDM_ENTRY126_PORT_IDf, TDM_ENTRY127_PORT_IDf, 8227 TDM_ENTRY128_PORT_IDf, TDM_ENTRY129_PORT_IDf, 8228 TDM_ENTRY130_PORT_IDf, TDM_ENTRY131_PORT_IDf, 8229 TDM_ENTRY132_PORT_IDf, TDM_ENTRY133_PORT_IDf, 8230 TDM_ENTRY134_PORT_IDf, TDM_ENTRY135_PORT_IDf, 8231 TDM_ENTRY136_PORT_IDf, TDM_ENTRY137_PORT_IDf, 8232 TDM_ENTRY138_PORT_IDf, TDM_ENTRY139_PORT_IDf, 8233 TDM_ENTRY140_PORT_IDf, TDM_ENTRY141_PORT_IDf, 8234 TDM_ENTRY142_PORT_IDf, TDM_ENTRY143_PORT_IDf, 8235 TDM_ENTRY144_PORT_IDf, TDM_ENTRY145_PORT_IDf, 8236 TDM_ENTRY146_PORT_IDf, TDM_ENTRY147_PORT_IDf, 8237 TDM_ENTRY148_PORT_IDf, TDM_ENTRY149_PORT_IDf, 8238 TDM_ENTRY150_PORT_IDf, TDM_ENTRY151_PORT_IDf, 8239 TDM_ENTRY152_PORT_IDf, TDM_ENTRY153_PORT_IDf, 8240 TDM_ENTRY154_PORT_IDf, TDM_ENTRY155_PORT_IDf, 8241 TDM_ENTRY156_PORT_IDf, TDM_ENTRY157_PORT_IDf, 8242 TDM_ENTRY158_PORT_IDf, TDM_ENTRY159_PORT_IDf, 8243 }; 8244 8245 static const soc_reg_t mn_pgw_ovs_tdm_regs[] = { 8246 PGW_OS_TDM_REG_0r, PGW_OS_TDM_REG_1r, 8247 PGW_OS_TDM_REG_2r, PGW_OS_TDM_REG_3r, 8248 PGW_OS_TDM_REG_4r, PGW_OS_TDM_REG_5r, 8249 PGW_OS_TDM_REG_6r, PGW_OS_TDM_REG_7r, 8250 PGW_OS_TDM_REG_8r, PGW_OS_TDM_REG_9r, 8251 PGW_OS_TDM_REG_10r, PGW_OS_TDM_REG_11r 8252 }; 8253 static const soc_reg_t mn_pgw_ovs_spacing_regs[] = { 8254 PGW_OS_PORT_SPACING_REG_0r, PGW_OS_PORT_SPACING_REG_1r, 8255 PGW_OS_PORT_SPACING_REG_2r, PGW_OS_PORT_SPACING_REG_3r, 8256 PGW_OS_PORT_SPACING_REG_4r, PGW_OS_PORT_SPACING_REG_5r, 8257 PGW_OS_PORT_SPACING_REG_6r, PGW_OS_PORT_SPACING_REG_7r, 8258 PGW_OS_PORT_SPACING_REG_8r, PGW_OS_PORT_SPACING_REG_9r, 8259 PGW_OS_PORT_SPACING_REG_10r, PGW_OS_PORT_SPACING_REG_11r 8260 }; 8261 static const soc_field_t mn_pgw_spacing_fields[] = { 8262 SLOT0f, SLOT1f, SLOT2f, SLOT3f, SLOT4f, SLOT5f, SLOT6f, SLOT7f, 8263 SLOT8f, SLOT9f, SLOT10f, SLOT11f, SLOT12f, SLOT13f, SLOT14f, SLOT15f, 8264 SLOT16f, SLOT17f, SLOT18f, SLOT19f, SLOT20f, SLOT21f, SLOT22f, SLOT23f, 8265 SLOT24f, SLOT25f, SLOT26f, SLOT27f, SLOT28f, SLOT29f, SLOT30f, SLOT31f, 8266 SLOT32f, SLOT33f, SLOT34f, SLOT35f, SLOT36f, SLOT37f, SLOT38f, SLOT39f, 8267 SLOT40f, SLOT41f, SLOT42f, SLOT43f, SLOT44f, SLOT45f, SLOT46f, SLOT47f 8268 }; 8269 #define MONTEREY_PGW_TDM_HSP_SLOTS 9 8270 static const soc_reg_t pgw_hsp_config_regs[MONTEREY_PGW_TDM_HSP_SLOTS] = { 8271 PGW_HSP_CONFIG_0r, PGW_HSP_CONFIG_1r, PGW_HSP_CONFIG_2r, 8272 PGW_HSP_CONFIG_3r, PGW_HSP_CONFIG_4r, PGW_HSP_CONFIG_5r, 8273 PGW_HSP_CONFIG_6r, PGW_HSP_CONFIG_7r, PGW_HSP_CONFIG_8r, 8274 }; 8275 8276 static const soc_reg_t pgw_hsp_config_fields[MONTEREY_PGW_TDM_HSP_SLOTS] = { 8277 PHY_PORT_NO_0f, PHY_PORT_NO_1f, PHY_PORT_NO_2f, 8278 PHY_PORT_NO_3f, PHY_PORT_NO_4f, PHY_PORT_NO_5f, 8279 PHY_PORT_NO_6f, PHY_PORT_NO_7f, PHY_PORT_NO_8f, 8280 }; 8281 8282 static const soc_reg_t mn_tdm_pgw_ctrl = PGW_TDM_CONTROLr; 8283 static const soc_reg_t mn_tdm_mmu_ctrl = ES_PIPE0_TDM_CONFIGr; 8284 static const soc_reg_t mmu_ovs_group_regs[MONTEREY_MMU_OVS_GROUP_COUNT] = { 8285 ES_PIPE0_OVR_SUB_GRP0_TBLr, ES_PIPE0_OVR_SUB_GRP1_TBLr, 8286 ES_PIPE0_OVR_SUB_GRP2_TBLr, ES_PIPE0_OVR_SUB_GRP3_TBLr, 8287 ES_PIPE0_OVR_SUB_GRP4_TBLr, ES_PIPE0_OVR_SUB_GRP5_TBLr, 8288 ES_PIPE0_OVR_SUB_GRP6_TBLr, ES_PIPE0_OVR_SUB_GRP7_TBLr 8289 }; 8290 8291 static const soc_reg_t mmu_ovs_group_wt_regs[8] = { 8292 ES_PIPE0_OVR_SUB_GRP_WT0r, ES_PIPE0_OVR_SUB_GRP_WT1r, 8293 ES_PIPE0_OVR_SUB_GRP_WT2r, ES_PIPE0_OVR_SUB_GRP_WT3r, 8294 ES_PIPE0_OVR_SUB_GRP_WT4r, ES_PIPE0_OVR_SUB_GRP_WT5r, 8295 ES_PIPE0_OVR_SUB_GRP_WT6r, ES_PIPE0_OVR_SUB_GRP_WT7r 8296 }; 8297 8298 8299 8300 #define MN_TDM_WT_GRP_SPG_GET(unit, _wtg) ((MN_MISC(unit)->tdm_wtg_used[_wtg] & 0xff)) 8301 #define MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) ((MN_MISC(unit)->tdm_wtg_used[_wtg] >> 8) & 0xff) 8302 8303 #define MONTEREY_TDM_WT_GRP_SPEED_GET(unit, _wtg) ((MN_TDM_WT_GRP_SPG_GET(unit, _wtg) * 2500)) 8304 8305 8306 #define MONTEREY_TDM_WT_GRP_RESERVE(unit, _wtg, _spg) \ 8307 do { \ 8308 uint16 _tmp = (MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) + 1); \ 8309 MN_MISC(unit)->tdm_wtg_used[_wtg] = ((_spg) | (_tmp << 8)); \ 8310 } while (0) 8311 8312 #define MONTEREY_TDM_WT_GRP_FREE(unit, _wtg) \ 8313 do { \ 8314 uint16 _tmp = (MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) - 1); \ 8315 if (MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) <= 1) { \ 8316 soc_monterey_misc_info[unit]->tdm_wtg_used[_wtg] = 0; \ 8317 } else { \ 8318 soc_monterey_misc_info[unit]->tdm_wtg_used[_wtg] = \ 8319 (MN_TDM_WT_GRP_SPG_GET(unit, _wtg) | (_tmp << 8)); \ 8320 } \ 8321 } while (0) 8322 8323 #define MONTEREY_TDM_WT_GRP_LOG(unit) \ 8324 do { \ 8325 int _wtg; \ 8326 LOG_VERBOSE(BSL_LS_SOC_TDM, \ 8327 (BSL_META_U(unit, \ 8328 "Weight groups and reference counts: \n\t"))); \ 8329 for (_wtg = 0; _wtg < 4; _wtg++) { \ 8330 LOG_VERBOSE(BSL_LS_SOC_TDM, \ 8331 (BSL_META_U(unit, \ 8332 "Grp = %d Refcnt = %d Speed Grp = %d Speed = %d;"), \ 8333 _wtg, MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg), \ 8334 MN_TDM_WT_GRP_SPG_GET(unit, _wtg), \ 8335 MONTEREY_TDM_WT_GRP_SPEED_GET(unit, _wtg))); \ 8336 } \ 8337 LOG_VERBOSE(BSL_LS_SOC_TDM, (BSL_META_U(unit, "\n"))); \ 8338 } while (0) 8339 8340 #define MONTEREY_TDM_WT_GRP_USABLE(unit, _wtg, _spg) \ 8341 ((MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) == 0) || (MN_TDM_WT_GRP_SPG_GET(unit, _wtg) == _spg)) 8342 8343 #define MONTEREY_TDM_ACTIVE_CAL(unit) soc_monterey_misc_info[unit]->tdm_active_cal 8344 #define MONTEREY_TDM_STRUCT_ACTIVE(unit) (!MONTEREY_TDM_ACTIVE_CAL(unit)) ? \ 8345 &(soc_monterey_misc_info[unit]->tdm0) : &(soc_monterey_misc_info[unit]->tdm1) 8346 #define MONTEREY_TDM_STRUCT_BACKUP(unit) (MONTEREY_TDM_ACTIVE_CAL(unit)) ? \ 8347 &(soc_monterey_misc_info[unit]->tdm0) : &(soc_monterey_misc_info[unit]->tdm1) 8348 8349 #define MONTEREY_TDM_PGW_LR_REG(cur_cal, slot) mn_pgw_lr_tdm_regs[cur_cal][slot/4] 8350 8351 #define MONTEREY_TDM_PGW_OS_REG(slot) mn_pgw_ovs_tdm_regs[slot/4] 8352 8353 #define MONTEREY_TDM_PGW_OS_SPACING_REG(slot) mn_pgw_ovs_spacing_regs[slot/4] 8354 8355 #define MONTEREY_TDM_PGW_SLOT(slot) mn_pgw_tdm_fields[slot] 8356 #define MONTEREY_TDM_PGW_OS_SPACING_FIELD(slot) mn_pgw_spacing_fields[slot] 8357 8358 #define MONTEREY_TDM_MMU_TBL(cur_cal) \ 8359 (!cur_cal) ? ES_PIPE0_TDM_TABLE_0m : ES_PIPE0_TDM_TABLE_1m 8360 8361 #if !defined(SOC_NO_NAMES) 8362 #define MONTEREY_TDM_PGW_LOG(_u, _desc, _r, _f, _v) \ 8363 LOG_INFO(BSL_LS_SOC_COMMON, \ 8364 (BSL_META_U(_u, \ 8365 _desc ": %s.%s = %d\n"), \ 8366 SOC_REG_NAME(_u, _r), \ 8367 soc_fieldnames[_f], _v)) 8368 #else 8369 #define MONTEREY_TDM_PGW_LOG(_u, _desc, _r, _f, _v) \ 8370 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(_u, _desc ": = %d\n"), _v)) 8371 #endif 8372 8373 STATIC int 8374 soc_monterey_tdm_calc(int unit, soc_monterey_tdm_t *monterey_tdm) 8375 { 8376 int rv, pgw, group, index; 8377 soc_info_t *si = &SOC_INFO(unit); 8378 tdm_soc_t monterey_chip_pkg; 8379 tdm_mod_t *monterey_tdm_pkg; 8380 int tdm_freq = 0, io_bw ; 8381 uint16 dev_id; 8382 uint8 rev_id; 8383 int is_macsec = 0; 8384 sal_memset(&monterey_chip_pkg, 0, sizeof(tdm_soc_t)); 8385 8386 monterey_chip_pkg.unit = unit; 8387 monterey_chip_pkg.num_ext_ports = MN_NUM_EXT_PORTS; 8388 monterey_chip_pkg.state = sal_alloc((monterey_chip_pkg.num_ext_ports)*sizeof(int *), "port state list"); 8389 monterey_chip_pkg.speed = sal_alloc((monterey_chip_pkg.num_ext_ports)*sizeof(int *), "port speed list"); 8390 8391 for (index = 1; index < monterey_chip_pkg.num_ext_ports; index++) { 8392 monterey_chip_pkg.state[index] = monterey_tdm->port_state[index]; 8393 } 8394 monterey_chip_pkg.state[0] = 1; /* enable cpu port */ 8395 monterey_chip_pkg.state[65] = 1; /* enable loopback port */ 8396 monterey_chip_pkg.state[66] = 1; /* enable MACSEC port */ 8397 8398 for (index = 0; index < monterey_chip_pkg.num_ext_ports; index++) { 8399 monterey_chip_pkg.speed[index] = monterey_tdm->speed[index]; 8400 } 8401 if (soc_property_get(unit, "tdm_check_disable", 0)) { 8402 monterey_chip_pkg.soc_vars.mn.tdm_chk_en = 1; 8403 } else { 8404 monterey_chip_pkg.soc_vars.mn.tdm_chk_en = 0; 8405 } 8406 8407 /* 8408 * Map detected core clk frequency to TDM algorithm internal code 8409 * value. 8410 */ 8411 tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY,0); 8412 if ( tdm_freq) { 8413 monterey_chip_pkg.clk_freq =tdm_freq; 8414 } else { 8415 monterey_chip_pkg.clk_freq = si->frequency; 8416 } 8417 if ( !tdm_freq) { 8418 soc_cm_get_id(unit, &dev_id, &rev_id); 8419 if (dev_id == BCM56675_DEVICE_ID) { 8420 monterey_chip_pkg.soc_vars.mn.sku_core_bw = si->bandwidth/1000; 8421 } else { 8422 monterey_chip_pkg.soc_vars.mn.sku_core_bw = si->io_bandwidth/1000; 8423 } 8424 } else { 8425 monterey_chip_pkg.soc_vars.mn.sku_core_bw = 0; 8426 } 8427 if (soc_feature(unit, soc_feature_xflow_macsec)) { 8428 monterey_chip_pkg.soc_vars.mn.is_macsec = 1; 8429 if (dev_id == BCM56675_DEVICE_ID) { 8430 monterey_chip_pkg.soc_vars.mn.sku_core_bw -= 40; 8431 } 8432 } 8433 8434 monterey_tdm_pkg = _soc_set_tdm_tbl(SOC_SEL_TDM(&monterey_chip_pkg)); 8435 8436 if (!monterey_tdm_pkg) { 8437 LOG_CLI((BSL_META_U(unit, 8438 "Unable to configure TDM, please contact your " 8439 "Field Applications Engineer or Sales Manager for " 8440 "additional assistance.\n"))); 8441 return SOC_E_FAIL; 8442 } 8443 monterey_tdm->pgw0len = 8444 monterey_tdm_pkg->_chip_data.soc_pkg.soc_vars.mn.pgw0_len; 8445 monterey_tdm->pgw1len = 8446 monterey_tdm_pkg->_chip_data.soc_pkg.soc_vars.mn.pgw1_len; 8447 /* PGW0 LR/OS Calendars */ 8448 sal_memcpy(monterey_tdm->pgw_tdm[0], 8449 monterey_tdm_pkg->_chip_data.cal_0.cal_main, 8450 sizeof(int)*MONTEREY_PGW_TDM_LENGTH); 8451 sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[0], 8452 monterey_tdm_pkg->_chip_data.cal_0.cal_grp[0], 8453 sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE); 8454 sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[0], 8455 monterey_tdm_pkg->_chip_data.cal_0.cal_grp[1], 8456 sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE); 8457 8458 /* PGW1 LR/OS Calendars */ 8459 sal_memcpy(monterey_tdm->pgw_tdm[1], 8460 monterey_tdm_pkg->_chip_data.cal_1.cal_main, 8461 sizeof(int)*MONTEREY_PGW_TDM_LENGTH); 8462 sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[1], 8463 monterey_tdm_pkg->_chip_data.cal_1.cal_grp[0], 8464 sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE); 8465 sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[1], 8466 monterey_tdm_pkg->_chip_data.cal_1.cal_grp[1], 8467 sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE); 8468 8469 sal_memcpy(monterey_tdm->mmu_tdm, 8470 monterey_tdm_pkg->_chip_data.cal_2.cal_main, 8471 sizeof(int)*MONTEREY_MMU_TDM_LENGTH); 8472 8473 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[0], 8474 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[0], 8475 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8476 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[1], 8477 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[1], 8478 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8479 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[2], 8480 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[2], 8481 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8482 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[3], 8483 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[3], 8484 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8485 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[4], 8486 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[4], 8487 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8488 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[5], 8489 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[5], 8490 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8491 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[6], 8492 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[6], 8493 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8494 sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[7], 8495 monterey_tdm_pkg->_chip_data.cal_2.cal_grp[7], 8496 sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH); 8497 8498 sal_free(monterey_chip_pkg.state); 8499 sal_free(monterey_chip_pkg.speed); 8500 8501 monterey_tdm_pkg->_chip_exec[TDM_CHIP_EXEC__FREE](monterey_tdm_pkg); 8502 sal_free(monterey_tdm_pkg); 8503 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 8504 for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) { 8505 LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_tdm:"), pgw)); 8506 for (index = 0; index < MONTEREY_PGW_TDM_LENGTH; index++) { 8507 if (index % 16 == 0) { 8508 LOG_CLI((BSL_META_U(unit, "\n "))); 8509 } 8510 LOG_CLI((BSL_META_U(unit, " %3d"), 8511 monterey_tdm->pgw_tdm[pgw][index])); 8512 } 8513 LOG_CLI((BSL_META_U(unit, "\n"))); 8514 LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_tdm:"), pgw)); 8515 for (index = 0; index < MONTEREY_PGW_TDM_LENGTH; index++) { 8516 if (index % 16 == 0) { 8517 LOG_CLI((BSL_META_U(unit, "\n "))); 8518 } 8519 LOG_CLI((BSL_META_U(unit, " %3d"), 8520 monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][index])); 8521 } 8522 LOG_CLI((BSL_META_U(unit, "\n"))); 8523 LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_spacing:"), pgw)); 8524 for (index = 0; index < MONTEREY_PGW_TDM_LENGTH; index++) { 8525 if (index % 16 == 0) { 8526 LOG_CLI((BSL_META_U(unit, "\n "))); 8527 } 8528 LOG_CLI((BSL_META_U(unit, " %3d"), 8529 monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][index])); 8530 } 8531 LOG_CLI((BSL_META_U(unit, "\n"))); 8532 } 8533 LOG_CLI((BSL_META_U(unit, "mmu_tdm:"))); 8534 for (index = 0; index < MONTEREY_MMU_TDM_LENGTH; index++) { 8535 if (index % 16 == 0) { 8536 LOG_CLI((BSL_META_U(unit, "\n "))); 8537 } 8538 LOG_CLI((BSL_META_U(unit, " %3d"), 8539 monterey_tdm->mmu_tdm[index])); 8540 } 8541 LOG_CLI((BSL_META_U(unit, "\n"))); 8542 for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) { 8543 LOG_CLI((BSL_META_U(unit, "group %d ovs_group_tdm"), group)); 8544 for (index = 0; index < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; 8545 index++) { 8546 if (index % 16 == 0) { 8547 LOG_CLI((BSL_META_U(unit, "\n "))); 8548 } 8549 LOG_CLI((BSL_META_U(unit, " %3d"), 8550 monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][index])); 8551 } 8552 LOG_CLI((BSL_META_U(unit, "\n"))); 8553 } 8554 } 8555 8556 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 8557 LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), monterey_tdm->tdm_bw)); 8558 LOG_CLI((BSL_META_U(unit, "ovs state: %d\n"), 8559 monterey_tdm->is_oversub)); 8560 } 8561 if (!tdm_freq) { 8562 tdm_freq = si->frequency; 8563 if (dev_id == BCM56675_DEVICE_ID) { 8564 io_bw = si->bandwidth/1000; 8565 if (soc_feature(unit, soc_feature_xflow_macsec)) { 8566 io_bw -= 40 ; 8567 is_macsec = 1; 8568 } 8569 } else { 8570 io_bw = si->io_bandwidth/1000; 8571 } 8572 } else { 8573 io_bw = 0; 8574 8575 } 8576 8577 rv = tdm_mn_set_iarb_tdm(tdm_freq, 8578 monterey_tdm->is_oversub, 8579 &monterey_tdm->iarb_tdm_wrap_ptr, 8580 monterey_tdm->iarb_tdm,io_bw,is_macsec); 8581 8582 if (rv == 0) { 8583 LOG_CLI((BSL_META_U(unit, 8584 "Unable to configure IARB TDM, please contact your " 8585 "Field Applications Engineer or Sales Manager for " 8586 "additional assistance.\n"))); 8587 return SOC_E_FAIL; 8588 } 8589 8590 if ((LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO))) { 8591 LOG_CLI((BSL_META_U(unit, 8592 "iarb_tdm: (wrap_ptr %d)"), 8593 monterey_tdm->iarb_tdm_wrap_ptr)); 8594 for (index = 0; index < MONTEREY_IARB_TDM_LENGTH; index++) { 8595 if (index > monterey_tdm->iarb_tdm_wrap_ptr) { 8596 break; 8597 } 8598 if (index % 16 == 0) { 8599 LOG_CLI((BSL_META_U(unit, "\n "))); 8600 } 8601 LOG_CLI((BSL_META_U(unit, " %3d"), 8602 monterey_tdm->iarb_tdm[index])); 8603 } 8604 LOG_CLI((BSL_META_U(unit, "\n"))); 8605 } 8606 8607 return SOC_E_NONE; 8608 } 8609 8610 #define MONTEREY_PGW0_TDM_WRAP_PTR 0x8b 8611 #define MONTEREY_PGW1_TDM_WRAP_PTR 0x97 8612 8613 STATIC int 8614 _soc_monterey_tdm_min_spacing_init(int unit) 8615 { 8616 int phy_port,mmu_port ; 8617 int port,profile_x; 8618 soc_info_t *si; 8619 uint32 rval; 8620 si = &SOC_INFO(unit); 8621 8622 PBMP_PORT_ITER(unit, port) { 8623 phy_port = si->port_l2p_mapping[port]; 8624 if (phy_port == -1 ) { 8625 continue; 8626 } 8627 mmu_port = si->port_p2m_mapping[phy_port]; 8628 if (mmu_port == -1) { 8629 continue; 8630 } 8631 if (mmu_port < 16 ) { 8632 if (si->port_speed_max[port] < 50000) { 8633 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ES_PIPE0_MIN_SPACINGr, 8634 REG_PORT_ANY, 0, &rval)); 8635 profile_x = soc_reg_field_get(unit, ES_PIPE0_MIN_SPACINGr, rval, PROFILEf ); 8636 profile_x = (profile_x | (1 << mmu_port)) ; 8637 soc_reg_field_set(unit, ES_PIPE0_MIN_SPACINGr, &rval, PROFILEf, profile_x); 8638 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ES_PIPE0_MIN_SPACINGr, 8639 REG_PORT_ANY, 0, rval)); 8640 8641 8642 } 8643 8644 } 8645 } 8646 8647 return SOC_E_NONE; 8648 } 8649 8650 STATIC int 8651 soc_monterey_tdm_update(int unit, int init_time, int cur_cal, 8652 soc_monterey_tdm_t *monterey_tdm) 8653 { 8654 int ix, rv; 8655 int count, slot; 8656 int pgw, pgw_inst, length; 8657 int pgw_hsp_config_index[2] = {0, 0}; /* for each pgw */ 8658 int mmu_idle_port_ix = 0; 8659 int mmu_idle_ports[] = {76, 78, 79, 80}; /* IDLE MMU ports in Apache */ 8660 8661 soc_port_t port, phy_port, mmu_port; 8662 soc_port_t pgw_hsp_ports[2][MONTEREY_TSCS_PER_PGW] = {{0}, {0}}; 8663 8664 soc_mem_t mem; 8665 soc_reg_t reg, hsp_reg; 8666 soc_field_t field, cal_end_f, cal_end_single_f, lr_tdm_wrap_f, hsp_fields[2]; 8667 es_pipe0_tdm_table_0_entry_t entry; 8668 8669 uint32 rval, hsp_values[2]; 8670 uint64 rval64, ctrl_rval64; 8671 8672 soc_info_t *si; 8673 8674 int group, weight, wt_group; 8675 int speed_class, speed_group ,speed = 0 ; 8676 uint32 wt_group_select = 0; 8677 uint32 same_spacing = 0; 8678 uint32 speed_spacing = 0; 8679 int tdm_freq = 0; 8680 8681 si = &SOC_INFO(unit); 8682 /* Configure PGW TDM for MONTEREY */ 8683 for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) { 8684 8685 /* coverity[negative_returns : FALSE] */ 8686 if (!SOC_INFO(unit).block_valid[PGW_CL_BLOCK(unit, pgw)]) { 8687 continue; 8688 } 8689 8690 pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK; 8691 8692 rv = soc_reg_get(unit, mn_tdm_pgw_ctrl, pgw_inst, 0, &ctrl_rval64); 8693 SOC_IF_ERROR_RETURN(rv); 8694 8695 /* Configure PGW line rate ports TDM */ 8696 count = 0; 8697 COMPILER_64_ZERO(rval64); 8698 8699 for (slot= 0; slot < MONTEREY_PGW_TDM_LENGTH; slot++) { 8700 8701 reg = MONTEREY_TDM_PGW_LR_REG(cur_cal, slot); 8702 field = MONTEREY_TDM_PGW_SLOT(slot); 8703 8704 phy_port = monterey_tdm->pgw_tdm[pgw][slot]; 8705 8706 if (phy_port == NUM_EXT_PORTS) { 8707 phy_port = 0xff; 8708 } else { 8709 if (phy_port == OVS_TOKEN) { 8710 phy_port = 0x44; 8711 } 8712 } 8713 8714 8715 soc_reg64_field32_set(unit, reg, &rval64, field, phy_port); 8716 8717 MONTEREY_TDM_PGW_LOG(unit, "PGW LR TDM config", reg, field, phy_port); 8718 8719 if (((slot + 1) % MONTEREY_PGW_TDM_SLOTS_PER_REG) == 0) { 8720 8721 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64)); 8722 COMPILER_64_ZERO(rval64); 8723 } 8724 } 8725 tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY,0); 8726 switch (tdm_freq) { 8727 8728 case 815: 8729 if ( pgw == 0 ) { 8730 count =0x8b; 8731 } else { 8732 count = 0x97; 8733 } 8734 break; 8735 case 816: 8736 if ( pgw == 0 ) { 8737 count =0x83; 8738 } else { 8739 count = 0x87; 8740 } 8741 break; 8742 case 817: 8743 if ( pgw == 0 ) { 8744 count =0x8b; 8745 } else { 8746 count = 0x97; 8747 } 8748 break; 8749 8750 case 818 : 8751 count = 0x9f; 8752 break; 8753 case 819 : 8754 count =0x7f; 8755 break; 8756 case 820 : 8757 count =0x97; 8758 break; 8759 case 666: 8760 if ( pgw == 0 ) { 8761 count =0x4F; 8762 } else { 8763 count = 0x2B; 8764 } 8765 break; 8766 case 667: 8767 if ( pgw == 0 ) { 8768 count =0x37; 8769 } else { 8770 count = 0x4F; 8771 } 8772 break; 8773 case 550 : 8774 if ( pgw == 0 ) { 8775 count =0x54; 8776 } else { 8777 count = 0x50; 8778 } 8779 break; 8780 case 861 : 8781 count =0x2f; 8782 break; 8783 case 862 : 8784 count =0x2f; 8785 break; 8786 default: 8787 if ( pgw == 0 ) { 8788 count =monterey_tdm->pgw0len - 1 ; 8789 } else { 8790 count =monterey_tdm->pgw1len - 1; 8791 } 8792 break; 8793 } 8794 lr_tdm_wrap_f = (!cur_cal) ? LR_TDM_WRAP_PTRf : LR_TDM2_WRAP_PTRf; 8795 8796 if (count > 0) { 8797 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8798 lr_tdm_wrap_f, count ); 8799 } 8800 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8801 LR_TDM_SELf, cur_cal); 8802 /* Always set both LR_TDM_ENABLE and LR_TDM2_ENABLE. 8803 * Even when switching, we need to make sure the the current 8804 * calendar is active so that it services the slots until the 8805 * end of the calendar when it actually switches to the new one. 8806 */ 8807 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8808 LR_TDM_ENABLEf, 1); 8809 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8810 LR_TDM2_ENABLEf, 1); 8811 8812 /* Configure PGW oversubscription ports TDM */ 8813 count = 0; 8814 COMPILER_64_ZERO(rval64); 8815 for (slot= 0; slot < MONTEREY_PGW_TDM_OVS_SIZE; slot++) { 8816 8817 reg = MONTEREY_TDM_PGW_OS_REG(slot); 8818 field = MONTEREY_TDM_PGW_SLOT(slot); 8819 8820 phy_port = monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][slot];; 8821 MONTEREY_TDM_PGW_LOG(unit, "PGW OS TDM config", reg, field, phy_port); 8822 8823 if (phy_port == NUM_EXT_PORTS) { 8824 phy_port = 0xff; 8825 } else { 8826 count++; 8827 } 8828 8829 soc_reg64_field32_set(unit, reg, &rval64, field, phy_port); 8830 8831 if (((slot + 1) % MONTEREY_PGW_TDM_SLOTS_PER_REG) == 0) { 8832 8833 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64)); 8834 COMPILER_64_ZERO(rval64); 8835 } 8836 if (phy_port == 0xff) { 8837 continue; 8838 } 8839 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 8840 if (SOC_INFO(unit).port_speed_max[port] >= 40000) { 8841 for (ix = 0; ix < pgw_hsp_config_index[pgw]; ix++) { 8842 if (pgw_hsp_ports[pgw][ix] == phy_port) { 8843 break; 8844 } 8845 } 8846 if (ix < pgw_hsp_config_index[pgw]) { 8847 continue; 8848 } 8849 pgw_hsp_ports[pgw][pgw_hsp_config_index[pgw]] = phy_port; 8850 hsp_reg = pgw_hsp_config_regs[pgw_hsp_config_index[pgw]]; 8851 hsp_fields[0] = pgw_hsp_config_fields[pgw_hsp_config_index[pgw]]; 8852 hsp_values[0] = phy_port; 8853 hsp_fields[1] = ENTRIES_IN_CALf; 8854 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(SOC_INFO(unit).port_speed_max[port]); 8855 hsp_values[1] = speed < 10000 ? 1 : ((speed + 5000) / 10000); 8856 8857 rv = soc_reg_fields32_modify(unit, hsp_reg, pgw_inst, 8858 2, hsp_fields, hsp_values); 8859 SOC_IF_ERROR_RETURN(rv); 8860 8861 pgw_hsp_config_index[pgw] += 1; 8862 } 8863 } 8864 8865 /* Enable os_skip_cnt_arb_sel by default in Apache */ 8866 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8867 OS_SKIP_CNT_ARB_SELf, TRUE); 8868 8869 while (pgw_hsp_config_index[pgw] < MONTEREY_TSCS_PER_PGW) { 8870 hsp_reg = pgw_hsp_config_regs[pgw_hsp_config_index[pgw]]; 8871 hsp_fields[0] = pgw_hsp_config_fields[pgw_hsp_config_index[pgw]]; 8872 hsp_values[0] = 0x0; 8873 hsp_fields[1] = ENTRIES_IN_CALf; 8874 hsp_values[1] = 0x0; 8875 8876 rv = soc_reg_fields32_modify(unit, hsp_reg, pgw_inst, 8877 2, hsp_fields, hsp_values); 8878 SOC_IF_ERROR_RETURN(rv); 8879 pgw_hsp_config_index[pgw] += 1; 8880 8881 } 8882 8883 /* OS_TDM_WRAP_PTR and OS_TDM_ENABLE programming */ 8884 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8885 OS_TDM_WRAP_PTRf, (count - 1)); 8886 soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64, 8887 OS_TDM_ENABLEf, count ? 1 : 0); 8888 8889 /* Configure PGW oversubscription port spacing */ 8890 COMPILER_64_ZERO(rval64); 8891 for (slot= 0; slot < MONTEREY_PGW_TDM_OVS_SIZE; slot++) { 8892 8893 reg = MONTEREY_TDM_PGW_OS_SPACING_REG(slot); 8894 field = MONTEREY_TDM_PGW_OS_SPACING_FIELD(slot); 8895 8896 phy_port = monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][slot]; 8897 MONTEREY_TDM_PGW_LOG(unit, "PGW OS Spacing config", reg, field, phy_port); 8898 8899 soc_reg64_field32_set(unit, reg, &rval64, field, phy_port); 8900 8901 if (((slot + 1) % MONTEREY_PGW_TDM_SLOTS_PER_REG) == 0) { 8902 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64)); 8903 COMPILER_64_ZERO(rval64); 8904 } 8905 } 8906 8907 rv = soc_reg_set(unit, mn_tdm_pgw_ctrl, pgw_inst, 0, ctrl_rval64); 8908 SOC_IF_ERROR_RETURN(rv); 8909 } 8910 8911 8912 /* Configure MMU TDM */ 8913 mem = MONTEREY_TDM_MMU_TBL(cur_cal); 8914 8915 length = MONTEREY_MMU_TDM_LENGTH; 8916 while ((monterey_tdm->mmu_tdm[length] == NUM_EXT_PORTS)) { 8917 length--; 8918 } 8919 8920 rv = soc_reg32_get(unit, mn_tdm_mmu_ctrl, REG_PORT_ANY, 0, &rval); 8921 SOC_IF_ERROR_RETURN(rv); 8922 8923 sal_memset(&entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32)); 8924 8925 for (slot = 0; slot <= length; slot++) { 8926 if (!(slot % 2)) { 8927 sal_memset(&entry, 0, soc_mem_entry_words 8928 (unit, mem) * sizeof(uint32)); 8929 } 8930 phy_port = monterey_tdm->mmu_tdm[slot]; 8931 8932 /* 8933 * TDM algo inserts CMIC, LB and ANC tokens for Auxillary 8934 * bandwidth in each TDM. ANC token needs to be replaced with 8935 * internal port 77 and CMIC & LB will be mapped to their mmu ports. 8936 * 8937 * Each TDM will also have a dedicated slot for guaranteed SBUS ops. 8938 * While the ANC slots can be used for SBUS as well, there could be 8939 * cases where the PRG (being of higher priority over SBUS) hogs SBUS 8940 * operations from getting handled. MMU port 81 will be programmed for 8941 * these tokens appearing in the algorithm. 8942 * 8943 * For unclaimed bandwidth (compared to max LR BW) from each config, 8944 * TDM algo inserts IDLE tokens. The idle tokens needs to be replaced 8945 * with internal mmu ports for Purge or SBUS operations. However, since 8946 * Hardware flags 1in4 violation errors even with these internal mmu 8947 * ports, we would iterate over all available internal ports (leaving out 8948 * ANC port - 77, of course). 8949 */ 8950 8951 if ((phy_port == SBUS_TOKEN)) { 8952 mmu_port = 81; /* Dedicated token for guaranteed SBUS ops */ 8953 } else if (phy_port == AUX_TOKEN) { 8954 mmu_port = 77; /* Dedicated ANC slot */ 8955 } else if(phy_port == IDL1_TOKEN) { 8956 /* iter over all available internal ports to avoid 1:4 violation */ 8957 mmu_port = mmu_idle_ports[mmu_idle_port_ix]; 8958 mmu_idle_port_ix = (mmu_idle_port_ix + 1) % COUNTOF(mmu_idle_ports); 8959 } else if (phy_port == OVS_TOKEN) { 8960 mmu_port = 0x44; /* Oversub port */ 8961 } else if (phy_port >= NUM_EXT_PORTS) { 8962 mmu_port = 0x7f; /* Invalid Port */ 8963 } else { 8964 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 8965 } 8966 field = (slot % 2) ? PORT_NUM_ODDf : PORT_NUM_EVENf; 8967 soc_mem_field32_set(unit, mem, &entry, field, mmu_port); 8968 /* two slots in each entry; length can be odd too */ 8969 if ((slot % 2) || (slot == length)) { 8970 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 8971 (slot / 2), &entry)); 8972 } 8973 } 8974 8975 cal_end_f = (cur_cal) ? CAL1_ENDf : CAL0_ENDf; 8976 cal_end_single_f = (cur_cal) ? CAL1_END_SINGLEf : CAL0_END_SINGLEf; 8977 8978 /* 8979 * Examples: 8980 * 1) cal length = 401; cal_end = 401/2 - 0 = 200, cal_end_single = 1 8981 * 2) cal length = 402; cal_end = 402/2 - 1 = 200, cal_end_single = 0 8982 */ 8983 soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, cal_end_f, 8984 (slot % 2) ? (slot / 2): ((slot / 2) - 1)); 8985 if (slot % 2) { 8986 soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, cal_end_single_f, 1); 8987 } 8988 8989 soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, OPP_CPULB_ENf, 1); 8990 soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, ENABLEf, 1); 8991 soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, CURR_CALf, cur_cal); 8992 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, mn_tdm_mmu_ctrl, REG_PORT_ANY, 0, rval)); 8993 8994 8995 rval = 0; 8996 for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) { 8997 speed_class = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group]; 8998 reg = mmu_ovs_group_regs[group]; 8999 for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 9000 9001 phy_port = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot]; 9002 if (phy_port >= NUM_EXT_PORTS) { 9003 mmu_port = 0x7f; 9004 } else { 9005 mmu_port = si->port_p2m_mapping[phy_port]; 9006 if (speed_class == 0) { 9007 speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]]; 9008 } 9009 } 9010 soc_reg_field_set(unit, reg, &rval, MMU_PORTf, (mmu_port & 0x7f)); 9011 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval)); 9012 } 9013 9014 if (SOC_FAILURE(_soc_monterey_mmu_ovs_speed_class_map_get( 9015 unit, &speed_class, &speed_group, &speed_spacing))) { 9016 continue; 9017 } 9018 if (init_time) { 9019 9020 for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 9021 if (MONTEREY_TDM_WT_GRP_USABLE(unit, wt_group, speed_group)) { 9022 MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 9023 break; 9024 } 9025 } 9026 9027 MONTEREY_TDM_WT_GRP_LOG(unit); 9028 9029 monterey_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group; 9030 monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class; 9031 9032 } else { 9033 wt_group = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group]; 9034 speed_class = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group]; 9035 } 9036 9037 if (wt_group >= MONTEREY_MMU_OVS_WT_GROUP_COUNT) { 9038 return SOC_E_INTERNAL; 9039 } 9040 9041 /* Apache supports 4 oversub speeds only */ 9042 soc_reg_field_set(unit, ES_PIPE0_GRP_WT_SELECTr, &wt_group_select, 9043 mn_mmu_ovs_group_wt_select_fields[group], wt_group); 9044 reg = ES_PIPE0_OVR_SUB_GRP_CFGr; 9045 soc_reg_field_set(unit, reg, &same_spacing, SAME_SPACINGf, speed_spacing); 9046 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, group, same_spacing); 9047 SOC_IF_ERROR_RETURN(rv); 9048 9049 } 9050 9051 for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 9052 9053 speed_class = MONTEREY_TDM_WT_GRP_SPEED_GET(unit, wt_group); 9054 if (speed_class == 0) { 9055 weight = 0x0; 9056 } else { 9057 /* use 2500M as weight unit */ 9058 weight = (speed_class > 2500 ? speed_class : 2500) / 2500; 9059 } 9060 reg = mmu_ovs_group_wt_regs[wt_group]; 9061 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval); 9062 SOC_IF_ERROR_RETURN(rv); 9063 9064 /* The proportional weights are already programmed */ 9065 if (soc_reg_field_get(unit, reg, rval, WEIGHTf) == weight) { 9066 continue; 9067 } 9068 soc_reg_field_set(unit, reg, &rval, WEIGHTf, (weight )); 9069 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 9070 } 9071 9072 9073 reg = ES_PIPE0_GRP_WT_SELECTr; 9074 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, wt_group_select); 9075 SOC_IF_ERROR_RETURN(rv); 9076 9077 SOC_IF_ERROR_RETURN(_soc_monterey_tdm_min_spacing_init(unit)); 9078 9079 return SOC_E_NONE; 9080 } 9081 9082 STATIC int soc_mn_port_resource_tdm_calculate(int unit, soc_monterey_tdm_t *tdm); 9083 9084 9085 STATIC int 9086 soc_monterey_tdm_reinit(int unit) 9087 { 9088 soc_reg_t reg; 9089 int phy_port, mmu_port; 9090 int slot, group, wt_group, speed_group, speed_class; 9091 uint32 rval, wt_group_select, speed_spacing; 9092 9093 soc_monterey_tdm_t *monterey_tdm; 9094 soc_info_t *si = &SOC_INFO(unit); 9095 9096 reg = ES_PIPE0_TDM_CONFIGr; 9097 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 9098 MONTEREY_TDM_ACTIVE_CAL(unit) = soc_reg_field_get(unit, reg, rval, CURR_CALf); 9099 9100 monterey_tdm = MONTEREY_TDM_STRUCT_ACTIVE(unit); 9101 9102 SOC_IF_ERROR_RETURN(soc_mn_port_resource_tdm_calculate(unit, monterey_tdm)); 9103 9104 reg = ES_PIPE0_GRP_WT_SELECTr; 9105 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &wt_group_select)); 9106 9107 9108 for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) { 9109 speed_class = 0; 9110 speed_group = 0; 9111 reg = mmu_ovs_group_regs[group]; 9112 9113 wt_group = soc_reg_field_get(unit, ES_PIPE0_GRP_WT_SELECTr, wt_group_select, 9114 mn_mmu_ovs_group_wt_select_fields[group]); 9115 9116 for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 9117 9118 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, slot, &rval)); 9119 mmu_port = soc_reg_field_get(unit, reg, rval, MMU_PORTf); 9120 9121 if (mmu_port == 0x7f) { 9122 phy_port = NUM_EXT_PORTS; 9123 } else { 9124 phy_port = SOC_INFO(unit).port_m2p_mapping[mmu_port]; 9125 if (speed_class == 0) { 9126 speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]]; 9127 if (SOC_FAILURE(_soc_monterey_mmu_ovs_speed_class_map_get( 9128 unit, &speed_class, &speed_group, &speed_spacing))) { 9129 continue; 9130 } 9131 MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 9132 } 9133 } 9134 monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port; 9135 } 9136 MONTEREY_TDM_WT_GRP_LOG(unit); 9137 9138 monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class; 9139 monterey_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group; 9140 } 9141 9142 return SOC_E_NONE; 9143 } 9144 9145 STATIC int 9146 soc_monterey_tdm_init(int unit) 9147 { 9148 soc_info_t *si; 9149 soc_pbmp_t pbmp; 9150 9151 int rv, index, cur_cal; 9152 int slot, port, phy_port, mmu_port; 9153 soc_monterey_tdm_t *monterey_tdm; 9154 9155 uint32 entry[SOC_MAX_MEM_WORDS]; 9156 uint32 values[4]; 9157 soc_field_t fields[4]; 9158 soc_mem_t mem; 9159 static const soc_mem_t iarb_tdm_mem = IARB_MAIN_TDMm; 9160 9161 cur_cal = MONTEREY_TDM_ACTIVE_CAL(unit); 9162 monterey_tdm = MONTEREY_TDM_STRUCT_ACTIVE(unit); 9163 9164 sal_memset(monterey_tdm, 0, sizeof(soc_monterey_tdm_t)); 9165 9166 si = &SOC_INFO(unit); 9167 9168 PBMP_PORT_ITER(unit, port) { 9169 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 9170 continue; 9171 } 9172 phy_port = si->port_l2p_mapping[port]; 9173 9174 monterey_tdm->speed[phy_port] = si->port_speed_max[port]; 9175 MONTEREY_TDM_SPEED_ADJUST(unit, port, monterey_tdm->speed[phy_port]); 9176 9177 monterey_tdm->port_state[phy_port] = 9178 IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE; 9179 9180 /* 9181 * Primary port will be setup as line-rate or oversub. 9182 * Subsequent physical ports (sister-ports) will be either 9183 * DISABLED or SUBPORT/COMBINED mode. 9184 * 9185 * TDM Algo expects lanes info based on speed. 9186 */ 9187 if (soc_monterey_port_is_falcon(unit, phy_port)) { /* Falcons */ 9188 if (monterey_tdm->speed[phy_port] > 25000) { 9189 monterey_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 9190 } 9191 if (monterey_tdm->speed[phy_port] > 50000) { 9192 monterey_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 9193 monterey_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 9194 } 9195 } else { /* Eagles */ 9196 if (monterey_tdm->speed[phy_port] > 10000) { 9197 monterey_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 9198 } 9199 if (monterey_tdm->speed[phy_port] > 20000) { 9200 monterey_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 9201 monterey_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 9202 } 9203 if (monterey_tdm->speed[phy_port] > 40000) { 9204 monterey_tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT; 9205 monterey_tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT; 9206 monterey_tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT; 9207 monterey_tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT; 9208 monterey_tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT; 9209 monterey_tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT; 9210 } 9211 } 9212 9213 } 9214 9215 /* CPU, LB and MACSEC ports */ 9216 monterey_tdm->speed[0] = 1000; 9217 monterey_tdm->speed[65] = 1000; 9218 monterey_tdm->speed[66] = 20000; 9219 9220 monterey_tdm->tdm_bw = si->bandwidth / 1000; 9221 9222 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 9223 SOC_PBMP_AND(pbmp, si->xpipe_pbm); 9224 9225 /* tell tdm code the device is oversub if any ports is oversub */ 9226 monterey_tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp); 9227 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 9228 9229 for (slot = 0; slot <= MONTEREY_MMU_TDM_LENGTH; slot++) { 9230 monterey_tdm->mmu_tdm[slot] = NUM_EXT_PORTS; 9231 } 9232 9233 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 9234 LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), monterey_tdm->tdm_bw)); 9235 LOG_CLI((BSL_META_U(unit, "port speed:"))); 9236 for (index = 0; index < NUM_EXT_PORTS; index++) { 9237 if (index % 8 == 0) { 9238 LOG_CLI((BSL_META_U(unit, "\n "))); 9239 } 9240 LOG_CLI((BSL_META_U(unit, " %06d(%03d)"), 9241 monterey_tdm->speed[index], index)); 9242 } 9243 LOG_CLI((BSL_META_U(unit, "\n"))); 9244 LOG_CLI((BSL_META_U(unit, "port state map:"))); 9245 for (index = 0; index < NUM_EXT_PORTS; index++) { 9246 if (index % 8 == 0) { 9247 LOG_CLI((BSL_META_U(unit, "\n "))); 9248 } 9249 if (index == 0 || index == (NUM_EXT_PORTS - 1)) { 9250 LOG_CLI((BSL_META_U(unit, " --------"))); 9251 } else { 9252 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"), 9253 monterey_tdm->port_state[index], index)); 9254 } 9255 } 9256 LOG_CLI((BSL_META_U(unit, "\n"))); 9257 } 9258 9259 9260 SOC_IF_ERROR_RETURN(soc_monterey_tdm_calc(unit, monterey_tdm)); 9261 9262 SOC_IF_ERROR_RETURN(soc_monterey_tdm_update(unit, 1, cur_cal, monterey_tdm)); 9263 9264 9265 /* Configure IARB TDM */ 9266 mem = iarb_tdm_mem; 9267 sal_memset(entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32)); 9268 for (slot = 0; slot < MONTEREY_IARB_TDM_LENGTH; slot++) { 9269 if (slot > monterey_tdm->iarb_tdm_wrap_ptr) { 9270 break; 9271 } 9272 /* temp fix for tdm issue once new tdm is in place this check shold be removed*/ 9273 if ((monterey_tdm->iarb_tdm[slot] > 0x7 || monterey_tdm->iarb_tdm[slot] < 0) && 9274 slot == monterey_tdm->iarb_tdm_wrap_ptr) { 9275 monterey_tdm->iarb_tdm[slot] = 3; 9276 } 9277 if (monterey_tdm->iarb_tdm[slot] > 0x7) { 9278 LOG_ERROR(BSL_LS_SOC_COMMON, 9279 (BSL_META_U(unit, 9280 "Invalid IARB TDM slot(%d) = %d !!\n"), 9281 slot, monterey_tdm->iarb_tdm[slot])); 9282 } 9283 soc_mem_field32_set(unit, mem, entry, TDM_SLOTf, 9284 monterey_tdm->iarb_tdm[slot]); 9285 SOC_IF_ERROR_RETURN 9286 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, entry)); 9287 } 9288 9289 /* IARB_TDM_CONTROL */ 9290 fields[0] = TDM_WRAP_PTRf; 9291 values[0] = monterey_tdm->iarb_tdm_wrap_ptr - 1; 9292 fields[1] = DISABLEf; 9293 values[1] = 0; 9294 SOC_IF_ERROR_RETURN 9295 (soc_reg_fields32_modify(unit, IARB_TDM_CONTROLr, REG_PORT_ANY, 2, 9296 fields, values)); 9297 9298 9299 fields[0] = FIELD_Af; 9300 values[0] = 1023; 9301 fields[1] = FIELD_Bf; 9302 values[1] = 9215; 9303 fields[2] = FIELD_Cf; 9304 values[2] = 16; 9305 rv = soc_reg_fields32_modify(unit, EGR_FORCE_SAF_CONFIGr, REG_PORT_ANY, 3, fields, values); 9306 SOC_IF_ERROR_RETURN(rv); 9307 9308 fields[0] = FIELD_Af; 9309 values[0] = 1; 9310 fields[1] = DI_ACT_THRf; 9311 values[1] = 20; 9312 rv = soc_reg_fields32_modify(unit, ES_PIPE0_MMU_1DBG_Cr, REG_PORT_ANY, 2, fields, values); 9313 SOC_IF_ERROR_RETURN(rv); 9314 9315 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_DI_THRr, REG_PORT_ANY, OS_SLT_LMTf, 1000); 9316 SOC_IF_ERROR_RETURN(rv); 9317 9318 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_1r, REG_PORT_ANY, FIELD_Bf, 0); 9319 SOC_IF_ERROR_RETURN(rv); 9320 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_0r, REG_PORT_ANY, 9321 FIELD_Af, (si->frequency * 200)); 9322 SOC_IF_ERROR_RETURN(rv); 9323 9324 9325 /* values array for filling mmu_1dbg_a regs */ 9326 values[0] = values[1] = values[2] = 0; 9327 9328 PBMP_PORT_ITER(unit, port) { 9329 9330 phy_port = si->port_l2p_mapping[port]; 9331 if (phy_port == -1 ) { 9332 continue; 9333 } 9334 mmu_port = si->port_p2m_mapping[phy_port]; 9335 if (mmu_port == -1) { 9336 continue; 9337 } 9338 9339 SOC_IF_ERROR_RETURN(soc_mn_mmu_delay_insertion_set(unit, port)); 9340 9341 9342 } 9343 return SOC_E_NONE; 9344 } 9345 9346 STATIC int 9347 _soc_monterey_hash_init(int unit) 9348 { 9349 soc_field_t fields[4]; 9350 uint32 values[4]; 9351 9352 /* L2 dedicated banks */ 9353 fields[0] = BANK0_HASH_OFFSETf; 9354 values[0] = 0; /* CRC32_LOWER */ 9355 fields[1] = BANK1_HASH_OFFSETf; 9356 values[1] = 16; /* CRC32_UPPER */ 9357 SOC_IF_ERROR_RETURN 9358 (soc_reg_fields32_modify(unit, L2_TABLE_HASH_CONTROLr, REG_PORT_ANY, 2, 9359 fields, values)); 9360 9361 /* L3 dedicated banks */ 9362 fields[0] = BANK6_HASH_OFFSETf; 9363 values[0] = 0; /* CRC32_LOWER */ 9364 fields[1] = BANK7_HASH_OFFSETf; 9365 values[1] = 12; /* CRC32 >> 12 */ 9366 fields[2] = BANK8_HASH_OFFSETf; 9367 values[2] = 24; /* CRC16_LOWER << 8 | CRC32 >> 24 */ 9368 fields[3] = BANK9_HASH_OFFSETf; 9369 values[3] = 36; /* CRC16 >> 4 */ 9370 SOC_IF_ERROR_RETURN 9371 (soc_reg_fields32_modify(unit, L3_TABLE_HASH_CONTROLr, REG_PORT_ANY, 4, 9372 fields, values)); 9373 9374 return SOC_E_NONE; 9375 } 9376 9377 #define PORTS_PER_LED_CHAIN 64 9378 9379 STATIC int 9380 _soc_monterey_ledup_init(int unit) 9381 { 9382 uint32 rval = 0, ix; 9383 uint8 remap_value[SOC_MAX_NUM_PORTS]; 9384 int phy_port; 9385 9386 /* configure the LED scan delay cycles */ 9387 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval)); 9388 soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 0xd); 9389 soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 4); 9390 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval)); 9391 9392 rval =0; 9393 /* Initialize LED Port remap registers */ 9394 9395 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval)); 9396 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval)); 9397 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval)); 9398 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval)); 9399 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval)); 9400 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval)); 9401 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval)); 9402 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval)); 9403 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval)); 9404 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r(unit, rval)); 9405 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r(unit, rval)); 9406 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r(unit, rval)); 9407 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r(unit, rval)); 9408 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r(unit, rval)); 9409 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r(unit, rval)); 9410 9411 for (ix = 0; ix < PORTS_PER_LED_CHAIN; ix++) { 9412 /* Chain 0: Phy Ports 1-64 9413 * LED HW Status arrives descending order to CMIC 9414 * i.e Status for Port 64 comes first and for Port 1 last 9415 */ 9416 phy_port = PORTS_PER_LED_CHAIN - ix; 9417 remap_value[ix] = phy_port - 1 ; 9418 9419 } 9420 9421 /* Configure LED Port remap registers */ 9422 ix = 0; 9423 rval = 0; 9424 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_0f, remap_value[ix++]); 9425 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_1f, remap_value[ix++] ); 9426 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_2f, remap_value[ix++]); 9427 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_3f, remap_value[ix++]); 9428 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval)); 9429 9430 rval = 0; 9431 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_4f, remap_value[ix++]); 9432 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_5f, remap_value[ix++]); 9433 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_6f, remap_value[ix++]); 9434 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_7f, remap_value[ix++]); 9435 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval)); 9436 9437 rval = 0; 9438 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_8f, remap_value[ix++]); 9439 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_9f, remap_value[ix++]); 9440 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_10f, remap_value[ix++]); 9441 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_11f, remap_value[ix++]); 9442 /* coverity[result_independent_of_operands] */ 9443 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval)); 9444 9445 rval = 0; 9446 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_12f, remap_value[ix++]); 9447 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_13f, remap_value[ix++]); 9448 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_14f, remap_value[ix++]); 9449 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_15f, remap_value[ix++]); 9450 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval)); 9451 9452 rval = 0; 9453 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval,REMAP_PORT_16f, remap_value[ix++]); 9454 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_17f, remap_value[ix++]); 9455 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_18f, remap_value[ix++]); 9456 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_19f, remap_value[ix++]); 9457 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval)); 9458 9459 rval = 0; 9460 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_20f, remap_value[ix++]); 9461 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_21f, remap_value[ix++]); 9462 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_22f, remap_value[ix++]); 9463 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_23f, remap_value[ix++]); 9464 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval)); 9465 9466 rval = 0; 9467 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_24f, remap_value[ix++]); 9468 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_25f, remap_value[ix++]); 9469 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_26f, remap_value[ix++]); 9470 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_27f, remap_value[ix++]); 9471 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval)); 9472 9473 rval = 0; 9474 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_28f, remap_value[ix++]); 9475 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval,REMAP_PORT_29f, remap_value[ix++]); 9476 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_30f, remap_value[ix++]); 9477 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_31f, remap_value[ix++]); 9478 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval)); 9479 9480 rval = 0; 9481 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_32f, remap_value[ix++]); 9482 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_33f, remap_value[ix++]); 9483 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_34f, remap_value[ix++]); 9484 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_35f, remap_value[ix++]); 9485 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval)); 9486 9487 9488 9489 9490 rval = 0; 9491 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_36f, remap_value[ix++]); 9492 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_37f, remap_value[ix++]); 9493 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_38f, remap_value[ix++]); 9494 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_39f, remap_value[ix++]); 9495 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r(unit, rval)); 9496 9497 rval = 0; 9498 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_40f, remap_value[ix++]); 9499 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_41f, remap_value[ix++]); 9500 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_42f, remap_value[ix++]); 9501 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_43f, remap_value[ix++]); 9502 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r(unit, rval)); 9503 9504 rval = 0; 9505 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_44f, remap_value[ix++]); 9506 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_45f, remap_value[ix++]); 9507 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_46f, remap_value[ix++]); 9508 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_47f, remap_value[ix++]); 9509 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r(unit, rval)); 9510 9511 rval = 0; 9512 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_48f, remap_value[ix++]); 9513 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_49f, remap_value[ix++]); 9514 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_50f, remap_value[ix++]); 9515 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_51f, remap_value[ix++]); 9516 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r(unit, rval)); 9517 9518 rval = 0; 9519 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_52f, remap_value[ix++]); 9520 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_53f, remap_value[ix++]); 9521 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_54f, remap_value[ix++]); 9522 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_55f, remap_value[ix++]); 9523 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r(unit, rval)); 9524 9525 rval = 0; 9526 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_56f, remap_value[ix++]); 9527 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_57f, remap_value[ix++]); 9528 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_58f, remap_value[ix++]); 9529 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_59f, remap_value[ix++]); 9530 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r(unit, rval)); 9531 9532 rval = 0; 9533 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_60f, remap_value[ix++]); 9534 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_61f, remap_value[ix++]); 9535 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_62f, remap_value[ix++]); 9536 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_63f, remap_value[ix++]); 9537 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r(unit, rval)); 9538 9539 9540 9541 /* initialize the UP0, UP1 data ram */ 9542 rval = 0; 9543 for (ix = 0; ix < 256; ix++) { 9544 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval)); 9545 } 9546 9547 return SOC_E_NONE; 9548 } 9549 int 9550 bcm_monterey_send_packetport(int unit , int port , int cos , int num ) 9551 { 9552 9553 int j=0; 9554 int pkt_size = 256 ; 9555 bcm_pkt_t *pkt = NULL; 9556 char pkt_DA_SA[12] = {0x00,0x00,0x33,0x44,0x55,0x66,0x00,0x01,0x02,0x03,0x04,0x05}; 9557 uint8 pkt_vlan_lengthtype[6] = {0x81,0x00,0x00,0x20,0x0,0x00}; 9558 SOC_IF_ERROR_RETURN(bcm_pkt_alloc(unit, pkt_size, BCM_TX_CRC_REGEN, &pkt)); 9559 sal_memset(pkt->pkt_data[0].data, 0xAA, pkt_size); 9560 sal_memcpy(pkt->pkt_data->data, pkt_DA_SA, 12); 9561 sal_memcpy(pkt->pkt_data->data+12, pkt_vlan_lengthtype, 6); 9562 SOC_PBMP_CLEAR(pkt->tx_pbmp); /* with ether mode, clear destination pbmp */ 9563 SOC_PBMP_PORT_SET(pkt->tx_pbmp, port); 9564 SOC_PBMP_CLEAR(pkt->tx_upbmp); /* send all packets tagged */ 9565 pkt->cos = cos ; 9566 for ( j =0 ; j < num ; j++ ) { 9567 bcm_tx(unit, pkt, NULL); 9568 } 9569 return SOC_E_NONE; 9570 9571 } 9572 9573 9574 #if defined(SER_TR_TEST_SUPPORT) 9575 soc_ser_test_functions_t ser_monterey_test_fun; 9576 #endif 9577 /* 9578 STATIC int 9579 _soc_monterey_egr_buf_reset(int unit, int port, int reset) 9580 { 9581 uint32 entry[SOC_MAX_MEM_WORDS]; 9582 9583 SOC_IF_ERROR_RETURN( 9584 READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 9585 port, entry)); 9586 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 9587 entry, ENABLEf, reset); 9588 SOC_IF_ERROR_RETURN( 9589 WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 9590 port, entry)); 9591 9592 return SOC_E_NONE; 9593 } 9594 */ 9595 STATIC int 9596 _soc_portctrl_monterey_port_init(int unit) 9597 { 9598 soc_info_t *si; 9599 int port; 9600 9601 si = &SOC_INFO(unit); 9602 9603 9604 /* Cut through settings for all ports */ 9605 PBMP_ALL_ITER(unit, port) { 9606 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) ) { 9607 continue; 9608 } 9609 SOC_IF_ERROR_RETURN(soc_monterey_port_asf_set(unit, port, si->port_speed_max[port])); 9610 } 9611 9612 return SOC_E_NONE; 9613 } 9614 9615 9616 /* 9617 * Function: 9618 * soc_monterey_idb_buf_reset 9619 * Purpose: 9620 * Poll until Cell Assembly and OBM buffers are empty. 9621 * Parameters: 9622 * unit - (IN) Unit number. 9623 * port - (IN) Logical SOC port number. 9624 * reset - (IN) Reset. 9625 * Returns: 9626 * SOC_E_XXX 9627 */ 9628 int 9629 soc_monterey_idb_buf_reset(int unit, soc_port_t port, int reset) 9630 { 9631 soc_info_t *si = &SOC_INFO(unit); 9632 soc_reg_t reg; 9633 soc_field_t field; 9634 uint64 rval64; 9635 int phy_port, port_index, xlp, pgw, obm, pgw_inst; 9636 soc_timeout_t to; 9637 int use_count, fifo_empty; 9638 int wait_time = 250000; 9639 9640 static const soc_reg_t pgw_obm_use_counter_regs[] = { 9641 IDB_OBM0_USAGEr, IDB_OBM1_USAGEr, IDB_OBM2_USAGEr, 9642 IDB_OBM3_USAGEr, IDB_OBM4_USAGEr, IDB_OBM5_USAGEr, 9643 IDB_OBM6_USAGEr, IDB_OBM7_USAGEr, IDB_OBM8_USAGEr 9644 }; 9645 static const soc_reg_t obm_ctrl_regs[] = { 9646 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, IDB_OBM2_CONTROLr, 9647 IDB_OBM3_CONTROLr, IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 9648 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, IDB_OBM8_CONTROLr 9649 }; 9650 static const soc_reg_t obm_ca_ctrl_regs[] = { 9651 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr, 9652 IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 9653 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, IDB_OBM8_CA_CONTROLr 9654 }; 9655 static const soc_field_t port_reset_fields[] = { 9656 PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf 9657 }; 9658 9659 if (SAL_BOOT_QUICKTURN) { 9660 wait_time *= 20; 9661 wait_time *= 3; 9662 } 9663 /* Get physical port PGW information */ 9664 phy_port = si->port_l2p_mapping[port]; 9665 pgw = si->port_group[port]; 9666 xlp = si->port_serdes[port]; 9667 port_index = (phy_port - 1) % 4; 9668 9669 obm = xlp % MONTEREY_TSCS_PER_PGW; 9670 pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK; 9671 9672 /* Assume values returned above are valid */ 9673 reg = pgw_obm_use_counter_regs[obm]; 9674 field = TOTAL_COUNTf; 9675 9676 if (reset && (!SAL_BOOT_BCMSIM)) { 9677 /* Poll until Cell Assembly and OBM buffers are empty */ 9678 soc_timeout_init(&to, wait_time, 0); 9679 for (;;) { 9680 /* Get PGW use counter */ 9681 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, port_index, &rval64)); 9682 use_count = soc_reg64_field32_get(unit, reg, rval64, field); 9683 9684 /* Get PGW fifo empty flag */ 9685 SOC_IF_ERROR_RETURN(READ_PGW_BOD_STATUSr(unit, port, &rval64)); 9686 fifo_empty = soc_reg64_field32_get(unit, PGW_BOD_STATUSr, 9687 rval64, EXP_PGW_BOD_FIFO_EMPTYf); 9688 9689 fifo_empty |= soc_reg64_field32_get(unit, PGW_BOD_STATUSr, 9690 rval64, PREEMPT_PGW_BOD_FIFO_EMPTYf); 9691 LOG_INFO(BSL_LS_SOC_PORT, 9692 (BSL_META_U(unit, 9693 "PGW/OBM buffer reset : port %d, %s (log=%d phy=%d), " 9694 "subport: %d tsc: %d obm:%d pgw: %d" 9695 "(use_count: %d) " 9696 "(pgw_bod_fifo_emty:%d)\n"), 9697 unit, SOC_PORT_NAME(unit, port), port, phy_port, 9698 port_index, xlp, obm, pgw, 9699 use_count, fifo_empty)); 9700 9701 if ((use_count == 0) && (fifo_empty == 1)) { 9702 break; 9703 } 9704 9705 if (soc_timeout_check(&to)) { 9706 LOG_ERROR(BSL_LS_SOC_PORT, 9707 (BSL_META_U(unit, 9708 "PGW/OBM buffer reset timeout: port %d, %s, " 9709 "timeout (use_count: %d) " 9710 "(pgw_bod_fifo_emty:%d)\n"), 9711 unit, SOC_PORT_NAME(unit, port), 9712 use_count, fifo_empty)); 9713 return SOC_E_INTERNAL; 9714 } 9715 } 9716 } 9717 9718 reg = obm_ctrl_regs[obm]; 9719 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst, 9720 port_reset_fields[port_index], reset)); 9721 9722 reg = obm_ca_ctrl_regs[obm]; 9723 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst, 9724 port_reset_fields[port_index], reset)); 9725 9726 return SOC_E_NONE; 9727 } 9728 9729 STATIC int 9730 _soc_monterey_pm_intr_init(int unit) 9731 { 9732 memset(&_monterey_pm_intr_functions, 0, 9733 sizeof(_monterey_pm_intr_functions)); 9734 _monterey_pm_intr_functions._soc_port_macro_intr_f = 9735 &soc_monterey_ser_error; 9736 return SOC_E_NONE; 9737 } 9738 9739 9740 /* 9741 * Function: 9742 * _soc_monterey_mmu_ep_credit_reset 9743 * Purpose: 9744 * Initalize EP credits in MMU so EP is in charge 9745 * of distributing the correct number of credits. 9746 * Parameters: 9747 * unit - (IN) Unit number. 9748 * port - (IN) Logical SOC port number. 9749 * Returns: 9750 * SOC_E_XXX 9751 */ 9752 STATIC int 9753 _soc_monterey_mmu_ep_credit_reset(int unit, soc_port_t port) 9754 { 9755 soc_info_t *si = &SOC_INFO(unit); 9756 int phy_port; 9757 int mmu_port; 9758 soc_reg_t reg; 9759 soc_reg_t reg1; 9760 uint32 rval; 9761 9762 /* Get physical port */ 9763 phy_port = si->port_l2p_mapping[port]; 9764 if (phy_port == -1) { 9765 return SOC_E_INTERNAL; 9766 } 9767 9768 /* Get MMU port */ 9769 mmu_port = si->port_p2m_mapping[phy_port]; 9770 if (mmu_port == -1) { 9771 return SOC_E_INTERNAL; 9772 } 9773 reg = ES_PIPE0_MMU_PORT_CREDIT_PREEMPTr; 9774 reg1 = ES_PIPE0_MMU_PORT_CREDIT_EXPRESSr; 9775 9776 SOC_IF_ERROR_RETURN 9777 (soc_reg32_get(unit, reg1, REG_PORT_ANY, mmu_port, &rval)); 9778 soc_reg_field_set(unit, reg1, &rval, INIT_CREDITf, 0); 9779 SOC_IF_ERROR_RETURN 9780 (soc_reg32_set(unit, reg1, REG_PORT_ANY, mmu_port, rval)); 9781 SOC_IF_ERROR_RETURN 9782 (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval)); 9783 soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, 0); 9784 SOC_IF_ERROR_RETURN 9785 (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 9786 return SOC_E_NONE; 9787 } 9788 9789 9790 STATIC int 9791 _soc_monterey_port_credit_size_get(int unit, soc_port_t port, int *ep_credit_size) 9792 { 9793 soc_info_t *si; 9794 si = &SOC_INFO(unit); 9795 9796 /* 9797 * For MACSEC, CPU and LB port port_speed_max is -1. 9798 */ 9799 if (si->port_speed_max[port] == -1) { 9800 if (IS_MACSEC_PORT(unit, port) ) { 9801 *ep_credit_size = 20; 9802 } else { 9803 *ep_credit_size = 11; 9804 } 9805 } else if (si->port_speed_max[port] <= 11000) { 9806 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 7 : 11; 9807 } else if (si->port_speed_max[port] <= 27000) { 9808 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 11 : 16; 9809 } else if (si->port_speed_max[port] <= 42000) { 9810 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 23 : 20; 9811 } else if (si->port_speed_max[port] <= 53000) { 9812 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 17 : 23; 9813 } else { 9814 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 30 : 39; 9815 } 9816 9817 *ep_credit_size = *ep_credit_size - 1; 9818 9819 return SOC_E_NONE; 9820 } 9821 /* 9822 * Function: 9823 * _soc_monterey_mmu_ep_credit_set 9824 * Purpose: 9825 * Initalize EP credits in MMU so EP is in charge 9826 * of distributing the correct number of credits. 9827 * Parameters: 9828 * unit - (IN) Unit number. 9829 * port - (IN) Logical SOC port number. 9830 * Returns: 9831 * SOC_E_XXX 9832 */ 9833 STATIC int 9834 _soc_monterey_mmu_ep_credit_set(int unit, soc_port_t port) 9835 { 9836 soc_info_t *si = &SOC_INFO(unit); 9837 int phy_port; 9838 int mmu_port; 9839 int ep_credit_size = 0; 9840 soc_reg_t reg; 9841 uint32 rval; 9842 9843 /* Get physical port */ 9844 phy_port = si->port_l2p_mapping[port]; 9845 if (phy_port == -1) { 9846 return SOC_E_INTERNAL; 9847 } 9848 9849 /* Get MMU port */ 9850 mmu_port = si->port_p2m_mapping[phy_port]; 9851 if (mmu_port == -1) { 9852 return SOC_E_INTERNAL; 9853 } 9854 9855 /* Wait until credits are initialised at non-optimum value 9856 * EP passes MMU 1 credit per cycle, so worse case delay is 9857 * 95 cycles after EGR_ENABLE is set. 9858 * @793.75MHz, this is ~120ns. 9859 */ 9860 sal_usleep(1); 9861 9862 reg = ES_PIPE0_MMU_PORT_CREDIT_EXPRESSr; 9863 9864 SOC_IF_ERROR_RETURN(_soc_monterey_port_credit_size_get(unit, port, &ep_credit_size)); 9865 SOC_IF_ERROR_RETURN 9866 (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval)); 9867 soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, ep_credit_size); 9868 SOC_IF_ERROR_RETURN 9869 (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 9870 9871 return SOC_E_NONE; 9872 } 9873 /* 9874 * Function: 9875 * soc_monterey_edb_buf_reset 9876 * Purpose: 9877 * Initialize EP credits in MMU, release EDB port buffer and 9878 * enable cell request in EP. 9879 * Parameters: 9880 * unit - (IN) Unit number. 9881 * port - (IN) Logical SOC port number. 9882 * reset - (IN) Reset. 9883 * Returns: 9884 * SOC_E_XXX 9885 */ 9886 int 9887 soc_monterey_edb_buf_reset(int unit, soc_port_t port, int reset) 9888 { 9889 soc_info_t *si = &SOC_INFO(unit); 9890 uint32 entry[SOC_MAX_MEM_WORDS]; 9891 int phy_port; 9892 uint32 rval; 9893 int level; 9894 soc_timeout_t to; 9895 int wait_time = 250000; 9896 uint32 preemption_enable = 0; 9897 if (SAL_BOOT_QUICKTURN) { 9898 wait_time *= 20; 9899 } 9900 9901 /* Get physical port */ 9902 phy_port = si->port_l2p_mapping[port]; 9903 if (phy_port == -1) { 9904 return SOC_E_INTERNAL; 9905 } 9906 9907 if (reset) { 9908 /* Set register to get number of used entries in EDB buffer */ 9909 SOC_IF_ERROR_RETURN 9910 (READ_EGR_EDB_MISC_CTRLr(unit, &rval)); 9911 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, 9912 SELECT_CURRENT_USED_ENTRIESf, 1); 9913 SOC_IF_ERROR_RETURN 9914 (WRITE_EGR_EDB_MISC_CTRLr(unit, rval)); 9915 9916 soc_timeout_init(&to, wait_time, 0); 9917 9918 /* Poll until EDB buffer is empty */ 9919 for (;;) { 9920 SOC_IF_ERROR_RETURN 9921 (READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, 9922 phy_port, entry)); 9923 level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, 9924 entry, LEVELf); 9925 if (level == 0) { 9926 break; 9927 } 9928 if (soc_timeout_check(&to)) { 9929 LOG_ERROR(BSL_LS_SOC_PORT, 9930 (BSL_META_U(unit, 9931 "EDB buffer drain timeout: " 9932 "port %d, %s, " 9933 "timeout (pending: %d)\n"), 9934 unit, SOC_PORT_NAME(unit, port), level)); 9935 return SOC_E_INTERNAL; 9936 } 9937 } 9938 9939 /* 9940 * Hold EDB port buffer in reset state and disable cell 9941 * request generation in EP. 9942 */ 9943 SOC_IF_ERROR_RETURN 9944 (READ_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, 9945 phy_port, entry)); 9946 soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, 9947 entry, VALUEf, 1); 9948 SOC_IF_ERROR_RETURN 9949 (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, 9950 phy_port, entry)); 9951 SOC_IF_ERROR_RETURN 9952 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9953 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 0); 9954 SOC_IF_ERROR_RETURN 9955 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9956 SOC_IF_ERROR_RETURN 9957 (READ_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9958 soc_mem_field32_set(unit, EGR_PREEMPT_ENABLEm, entry, PRT_ENABLEf, 0); 9959 SOC_IF_ERROR_RETURN 9960 (WRITE_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9961 } else { 9962 9963 9964 /* 9965 * Release EDB port buffer reset and 9966 * enable cell request generation in EP. 9967 */ 9968 SOC_IF_ERROR_RETURN 9969 (READ_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, 9970 phy_port, entry)); 9971 soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm, 9972 entry, VALUEf, 0); 9973 SOC_IF_ERROR_RETURN 9974 (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL, 9975 phy_port, entry)); 9976 9977 SOC_IF_ERROR_RETURN 9978 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9979 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 9980 SOC_IF_ERROR_RETURN 9981 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9982 9983 SOC_IF_ERROR_RETURN( 9984 bcmi_mn_preemption_capability_get(unit , port , &preemption_enable)); 9985 if (preemption_enable ) { 9986 SOC_IF_ERROR_RETURN 9987 (READ_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9988 soc_mem_field32_set(unit, EGR_PREEMPT_ENABLEm, entry, PRT_ENABLEf, 1); 9989 SOC_IF_ERROR_RETURN 9990 (WRITE_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 9991 } 9992 } 9993 return SOC_E_NONE; 9994 } 9995 9996 int 9997 soc_monterey_ports_edb_config(int unit, int asf, soc_pbmp_t pbm) 9998 { 9999 int rv; 10000 /* uint32 osct_pbm; 10001 uint64 lrct_pbm;*/ 10002 soc_info_t *si; 10003 soc_port_t port, phy_port ; 10004 /*int pm_id, pgw_inst;*/ 10005 int linerate; 10006 10007 soc_mem_t edb_mem = EGR_EDB_XMIT_CTRLm; 10008 soc_mem_t edb_mem1 = EGR_PREEMPT_EDB_XMIT_CTRLm; 10009 soc_field_t edb_fields[3] = {START_CNTf, WAIT_FOR_MOPf, WAIT_FOR_2ND_MOPf}; 10010 uint32 edb_values[3] = {0}; 10011 10012 10013 si = &SOC_INFO(unit); 10014 10015 /* Remove extraneous ports from the input list */ 10016 /*osct_pbm = 0; 10017 COMPILER_64_ZERO(lrct_pbm);*/ 10018 SOC_PBMP_AND(pbm, PBMP_ALL(unit)); 10019 10020 SOC_PBMP_ITER(pbm, port) { 10021 phy_port = si->port_l2p_mapping[port]; 10022 /*mmu_port = si->port_p2m_mapping[phy_port]; 10023 pgw_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK;*/ 10024 linerate = (!SOC_PBMP_MEMBER(si->oversub_pbm, port)); 10025 10026 /* *pm_id = ((phy_port - 1) / MONTEREY_PORTS_PER_TSC) % MONTEREY_TSCS_PER_PGW;*/ 10027 if (!soc_monterey_port_is_falcon(unit, phy_port)) { /* Eagle Cores */ 10028 if (si->port_speed_max[port] <= 21000) { /* 0-21G */ 10029 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 7); 10030 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10031 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10032 10033 } else if (si->port_speed_max[port] <= 42000) { /* 21G-42G */ 10034 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 11 : 7); 10035 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10036 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10037 10038 } else { /* 42G or more (100G) */ 10039 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 4); 10040 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10041 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10042 10043 } 10044 } else { /* Falcon Cores */ 10045 if (si->port_speed_max[port] <= 11000) { /* 0-11G */ 10046 edb_values[0] = (linerate) ? (asf ? 3 : 0) : (asf ? 0 : 4); 10047 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10048 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10049 10050 } else if (si->port_speed_max[port] <= 27000) { /* 11G-27G */ 10051 edb_values[0] = (linerate) ? (asf ? 3 : 0) : (asf ? 0 : 4); 10052 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10053 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10054 10055 } else if (si->port_speed_max[port] <= 42000) { /* 27G-42G */ 10056 edb_values[0] = (linerate) ? (asf ? 3 : 0) : (asf ? 5 : 4); 10057 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10058 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10059 10060 } else { /* 42G or more (50G, 53G, 100G, 106G) */ 10061 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 4); 10062 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10063 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10064 } 10065 } 10066 10067 rv = soc_mem_fields32_modify(unit, edb_mem, phy_port, 3, edb_fields, edb_values); 10068 SOC_IF_ERROR_RETURN(rv); 10069 rv = soc_mem_fields32_modify(unit, edb_mem1, phy_port, 3, edb_fields, edb_values); 10070 10071 SOC_IF_ERROR_RETURN(rv); 10072 10073 } 10074 10075 10076 return SOC_E_NONE; 10077 } 10078 10079 10080 STATIC int 10081 soc_monterey_edb_init(int unit) 10082 { 10083 soc_pbmp_t pbm; 10084 10085 SOC_PBMP_ASSIGN(pbm, PBMP_PORT_ALL(unit)); 10086 SOC_IF_ERROR_RETURN(soc_monterey_ports_edb_config(unit, 0, pbm)); 10087 10088 return SOC_E_NONE; 10089 } 10090 10091 10092 10093 STATIC int 10094 _soc_monterey_misc_deinit (int unit) 10095 { 10096 10097 SOC_IF_ERROR_RETURN(soc_mn_phy_info_deinit(unit)); 10098 10099 if (soc_monterey_misc_info[unit] != NULL) { 10100 sal_free(soc_monterey_misc_info[unit]); 10101 soc_monterey_misc_info[unit] = NULL; 10102 } 10103 10104 return SOC_E_NONE; 10105 } 10106 10107 STATIC int 10108 soc_mnc_mem_modify_range(int unit, soc_mem_t mem, int min_idx, int max_idx, 10109 int nfields, soc_field_t *fields, uint32 *values) 10110 { 10111 uint8 *mbuf; 10112 void *entry_ptr; 10113 int e_idx, f_idx, size, rv; 10114 10115 size = SOC_MEM_TABLE_BYTES(unit, mem); 10116 mbuf = soc_cm_salloc(unit, size, "soc_mem_name[mem]"); 10117 10118 if (NULL == mbuf) { 10119 return SOC_E_MEMORY; 10120 } 10121 10122 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf); 10123 if (SOC_FAILURE(rv)) { 10124 soc_cm_sfree(unit, mbuf); 10125 return rv; 10126 } 10127 10128 for (e_idx = min_idx; e_idx <= max_idx; e_idx++) { 10129 entry_ptr = soc_mem_table_idx_to_pointer(unit, mem, void *, mbuf, e_idx); 10130 for (f_idx = 0; f_idx < nfields; f_idx++) { 10131 /* If value is -1, program entry_idx */ 10132 soc_mem_field32_set(unit, mem, entry_ptr, fields[f_idx], 10133 (values[f_idx] == -1 ? e_idx : values[f_idx])); 10134 } 10135 } 10136 10137 rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf); 10138 soc_cm_sfree(unit, mbuf); 10139 SOC_IF_ERROR_RETURN(rv); 10140 10141 return SOC_E_NONE; 10142 } 10143 10144 STATIC int 10145 _soc_monterey_misc_init (int unit) 10146 { 10147 static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 }; 10148 soc_info_t *si; 10149 uint32 rval = 0; 10150 uint64 rval64; 10151 uint32 entry[SOC_MAX_MEM_WORDS]; 10152 soc_pbmp_t pbmp; 10153 int port, min_port, max_port; 10154 int block_info_idx; 10155 int index, count, sub_sel, offset; 10156 int freq, target_freq, divisor, dividend, delay; 10157 int parity_enable = 0, cache_fpgm; 10158 soc_field_t fields[2]; 10159 uint32 values[2]; 10160 10161 10162 si = &SOC_INFO(unit); 10163 10164 if (soc_monterey_misc_info[unit] == NULL) { 10165 soc_monterey_misc_info[unit] = sal_alloc(sizeof(*soc_monterey_misc_info[unit]), 10166 "monterey misc info"); 10167 if (soc_monterey_misc_info[unit] == NULL) { 10168 return SOC_E_MEMORY; 10169 } 10170 } 10171 10172 10173 sal_memset(soc_monterey_misc_info[unit], 0, (sizeof(*soc_monterey_misc_info[unit]))); 10174 10175 /* Stop the mem scan task before all of the parity init takes place */ 10176 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 10177 SOC_IF_ERROR_RETURN(soc_monterey_shadow_create(unit)); 10178 if (!SOC_WARM_BOOT(unit)) { 10179 /* Initialize PORT MIB counter */ 10180 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 10181 port = SOC_BLOCK_PORT(unit, block_info_idx); 10182 soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10183 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval)); 10184 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0)); 10185 } 10186 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLG2PORT) { 10187 port = SOC_BLOCK_PORT(unit, block_info_idx); 10188 soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10189 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval)); 10190 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0)); 10191 } 10192 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) { 10193 port = SOC_BLOCK_PORT(unit, block_info_idx); 10194 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10195 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval)); 10196 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0)); 10197 } 10198 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORTB0) { 10199 port = SOC_BLOCK_PORT(unit, block_info_idx); 10200 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10201 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval)); 10202 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0)); 10203 } 10204 10205 } 10206 10207 /* Stop the mem scan task before all of the parity init takes place */ 10208 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 10209 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit)); 10210 10211 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 10212 if (parity_enable) { 10213 if ((!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) && 10214 !SOC_WARM_BOOT(unit)) { 10215 /* Certain mems/regs need to be cleared before enabling SER */ 10216 SOC_IF_ERROR_RETURN(_soc_monterey_clear_mmu_memory(unit, INVALIDm)); 10217 SOC_IF_ERROR_RETURN(_soc_monterey_clear_all_port_data(unit)); 10218 } 10219 SOC_IF_ERROR_RETURN(_soc_monterey_tcam_ser_init(unit)); 10220 SOC_IF_ERROR_RETURN(_soc_monterey_ser_enable_all(unit, TRUE)); 10221 #ifdef INCLUDE_MEM_SCAN 10222 soc_mem_scan_ser_list_register(unit, TRUE, 10223 _soc_monterey_tcam_ser_info[unit]); 10224 #endif 10225 memset(&_monterey_ser_functions, 0, sizeof(soc_ser_functions_t)); 10226 _monterey_ser_functions._soc_ser_fail_f = &soc_monterey_ser_fail; 10227 _monterey_ser_functions._soc_ser_parity_error_cmicm_intr_f = 10228 &soc_monterey_ser_error; 10229 soc_ser_function_register(unit, &_monterey_ser_functions); 10230 soc_monterey_ser_set_long_delay(FALSE); 10231 #if defined(SER_TR_TEST_SUPPORT) 10232 /*Initialize chip-specific functions for SER testing*/ 10233 memset(&ser_monterey_test_fun, 0, sizeof(soc_ser_test_functions_t)); 10234 ser_monterey_test_fun.inject_error_f = &soc_monterey_ser_inject_error; 10235 ser_monterey_test_fun.test_mem = &soc_monterey_ser_test_mem; 10236 ser_monterey_test_fun.test = &soc_monterey_ser_test; 10237 ser_monterey_test_fun.parity_control = &_ser_test_parity_control_reg_set; 10238 ser_monterey_test_fun.injection_support = &soc_monterey_ser_error_injection_support; 10239 soc_ser_test_functions_register(unit, &ser_monterey_test_fun); 10240 #endif /*defined(SER_TR_TEST_SUPPORT*/ 10241 10242 } 10243 10244 if (!SOC_WARM_BOOT(unit)) { 10245 SOC_IF_ERROR_RETURN 10246 (_soc_monterey_clear_all_memory(unit, (parity_enable ? 0 : 1))); 10247 if (!parity_enable) { 10248 /* Clear enabled port's regs if not done above */ 10249 SOC_IF_ERROR_RETURN(_soc_monterey_clear_enabled_port_data(unit)); 10250 } 10251 } 10252 10253 10254 SOC_IF_ERROR_RETURN(_soc_monterey_port_mapping_init(unit)); 10255 10256 if (!(SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM)) { 10257 if (!SOC_WARM_BOOT(unit)) { 10258 if(!soc_property_get(unit, "skip_tdm_init", 0)) { 10259 SOC_IF_ERROR_RETURN(soc_monterey_tdm_init(unit)); 10260 } 10261 SOC_IF_ERROR_RETURN(soc_monterey_idb_init(unit)); 10262 SOC_IF_ERROR_RETURN(soc_monterey_edb_init(unit)); 10263 } else { 10264 SOC_IF_ERROR_RETURN(soc_monterey_tdm_reinit(unit)); 10265 } 10266 } 10267 10268 sal_memset(entry, 0, sizeof(cpu_pbm_entry_t)); 10269 soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit)); 10270 SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry)); 10271 10272 sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t)); 10273 soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit)); 10274 SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry)); 10275 10276 sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t)); 10277 soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf, 10278 &PBMP_LB(unit)); 10279 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm, 10280 MEM_BLOCK_ALL, 0, entry)); 10281 10282 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 10283 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 10284 PBMP_HG_ITER(unit, port) { 10285 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, 10286 MEM_BLOCK_ALL, port, entry)); 10287 } 10288 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, 10289 si->cpu_hg_index, entry)); 10290 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2); 10291 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, 10292 LB_PORT(unit), entry)); 10293 10294 /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to 10295 * initialize the cache until now. This is the time to check for 10296 * the cache permission of this table. 10297 */ 10298 cache_fpgm = soc_feature(unit, soc_feature_mem_cache) && 10299 soc_property_get(unit, spn_MEM_CACHE_ENABLE, 10300 (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1); 10301 if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) { 10302 char mem_name[100]; 10303 char *mptr; 10304 10305 sal_memset(mem_name, 0, sizeof(mem_name)); 10306 sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_")); 10307 mptr = &mem_name[sal_strlen(mem_name)]; 10308 sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm), 10309 sizeof(mem_name) - sal_strlen(mem_name) - 1); 10310 if (soc_property_get(unit, mem_name, 0)) { 10311 cache_fpgm = 0; 10312 } 10313 } 10314 10315 if (cache_fpgm && (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) { 10316 SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |= 10317 SOC_MEM_FLAG_CACHABLE; 10318 SOC_IF_ERROR_RETURN 10319 (soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm, 10320 MEM_BLOCK_ALL, TRUE)); 10321 10322 SOC_MEM_INFO(unit, FP_GM_FIELDSm).flags |= 10323 SOC_MEM_FLAG_CACHABLE; 10324 SOC_IF_ERROR_RETURN 10325 (soc_mem_cache_set(unit, FP_GM_FIELDSm, 10326 MEM_BLOCK_ALL, TRUE)); 10327 } 10328 10329 SOC_IF_ERROR_RETURN(_soc_portctrl_monterey_port_init(unit)); 10330 SOC_IF_ERROR_RETURN(_soc_monterey_pm_intr_init(unit)); 10331 SOC_IF_ERROR_RETURN(_soc_monterey_pm_cpri_intr_enable(unit, TRUE)); 10332 10333 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 10334 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 10335 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 10336 /* Enable dual hash tables */ 10337 SOC_IF_ERROR_RETURN(_soc_monterey_hash_init(unit)); 10338 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, L3_ENTRY_CONTROL_10r, 10339 REG_PORT_ANY, DISABLE_L3_ENTRY_LPf, 0xf)); 10340 10341 rval = 0; 10342 soc_reg_field_set(unit, L2_AGE_DEBUGr, &rval, AGE_COUNTf, 10343 soc_mem_index_max(unit, L2Xm)); 10344 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_DEBUGr(unit, rval)); 10345 /* 10346 * Egress Enable (for non-serdes ports). 10347 * For PM ports, it is set during port enable/disable sequence. 10348 */ 10349 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 10350 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 10351 10352 /* Only enable internal ports in EGR_ENABLE. 10353 * The packet processing ports are enabled via port enable sequence. 10354 */ 10355 SOC_PBMP_CLEAR(pbmp); 10356 SOC_PBMP_PORT_ADD(pbmp, CMIC_PORT(unit)); 10357 SOC_PBMP_PORT_ADD(pbmp, LB_PORT(unit)); 10358 SOC_PBMP_PORT_ADD(pbmp, MACSEC_PORT(unit)); 10359 10360 PBMP_ITER(pbmp, port) { 10361 SOC_IF_ERROR_RETURN 10362 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, port, entry)); 10363 SOC_IF_ERROR_RETURN(_soc_monterey_mmu_ep_credit_set(unit, port)); 10364 } 10365 10366 SOC_PBMP_CLEAR(pbmp); 10367 SOC_PBMP_ASSIGN(pbmp, PBMP_CMIC(unit)); 10368 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, &pbmp); 10369 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry)); 10370 10371 /* 10372 * Enable all ports (except RDB port) 10373 * RDB port is an ingress-only port that should not have any packets 10374 * enqueued against it, even if the port is added to any vlan or other 10375 * forwarding table by mistake. 10376 */ 10377 #if __GNUC__ > 6 10378 #pragma GCC diagnostic push 10379 #pragma GCC diagnostic ignored "-Wmemset-elt-size" 10380 #endif 10381 /* 10382 * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for 10383 * performance reasons, because the actual soc_mem_field_set() 10384 * will only write sizeof(ing_dest_port_enable_entry_t)=20 10385 * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651 10386 * depending on which devices are compiled in. 10387 */ 10388 sal_memset(entry, 0, sizeof(ing_dest_port_enable_entry_t)); 10389 #if __GNUC__ > 6 10390 #pragma GCC diagnostic pop 10391 #endif 10392 SOC_PBMP_CLEAR(pbmp); 10393 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 10394 soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, entry, PORT_BITMAPf, &pbmp); 10395 SOC_IF_ERROR_RETURN(WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0, entry)); 10396 10397 min_port = SOC_PORT_MIN(unit, all); 10398 max_port = SOC_PORT_MAX(unit, all); 10399 10400 fields[0] = DESTf; values[0] = -1; /* -1 => port */ 10401 fields[1] = ENABLEf; values[1] = 1; 10402 SOC_IF_ERROR_RETURN(soc_mnc_mem_modify_range(unit, MODPORT_MAP_SUBPORTm, 10403 min_port, max_port, 10404 2, fields, values)); 10405 10406 /* setting up my_modid */ 10407 SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64)); 10408 10409 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 10410 MODID_0_VALIDf, 1); 10411 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 10412 MODID_0f, SOC_BASE_MODID(unit)); 10413 10414 SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64)); 10415 10416 10417 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64)); 10418 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10419 L3SRC_HIT_ENABLEf, 1); 10420 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10421 L2DST_HIT_ENABLEf, 1); 10422 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10423 APPLY_EGR_MASK_ON_L2f, 1); 10424 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10425 APPLY_EGR_MASK_ON_L3f, 1); 10426 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10427 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 10428 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10429 ARP_VALIDATION_ENf, 1); 10430 10431 /* 10432 * If riot is enabled, 10433 * MY_STATION1 will be used for tunnels. 10434 * MY_STATION2 will be used for routing. 10435 * Else, 10436 * MY_STATION1 should be used for both tunnels and routing. 10437 * For this, USE_MY_STATION1_FOR_NON_TUNNELS should be set to TRUE. 10438 */ 10439 if (!soc_feature(unit, soc_feature_riot)) { 10440 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10441 USE_MY_STATION1_FOR_NON_TUNNELSf, 1); 10442 } 10443 10444 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64)); 10445 10446 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1r, 10447 REG_PORT_ANY, RING_MODEf, 1)); 10448 10449 10450 /* T2OQ needs to be setup for all ports that require 1 in 9 spacing or less 10451 * In Apache, it is safe to program all mmu ports 0-15 in T2OQ (whether in 10452 * high speed mode or not). In TD2+, part of the MCQDB memory was re-used 10453 * for T2OQ; Apache has separate 160 deep MCQDB memory */ 10454 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOQ_MC_CFG1r, 10455 REG_PORT_ANY, IS_MC_T2OQ_PORT0f, 10456 0xffff)); 10457 10458 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 10459 * causes the outer tag to be removed from packets that don't have 10460 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 10461 */ 10462 fields[0] = VT_MISS_UNTAGf; values[0] = 0; 10463 fields[1] = REMARK_OUTER_DOT1Pf; values[1] = 1; 10464 SOC_IF_ERROR_RETURN(soc_mnc_mem_modify_range(unit, EGR_VLAN_CONTROL_1m, 10465 min_port, max_port, 10466 2, fields, values)); 10467 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 10468 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 10469 SOC_PBMP_REMOVE(pbmp, PBMP_MACSEC_ALL(unit)); 10470 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 10471 MEM_BLOCK_ANY, 0, &entry)); 10472 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, &pbmp); 10473 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 10474 MEM_BLOCK_ANY, 0, &entry)); 10475 10476 /* Multicast range initialization */ 10477 SOC_IF_ERROR_RETURN 10478 (soc_hbx_higig2_mcast_sizes_set(unit, 10479 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 10480 SOC_HBX_MULTICAST_RANGE_DEFAULT), 10481 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 10482 soc_mem_index_count(unit, L2MCm) / 2), 10483 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 10484 soc_mem_index_count(unit, L2MCm) / 2))); 10485 SOC_IF_ERROR_RETURN 10486 (soc_hbx_mcast_size_set(unit, soc_property_get(unit, 10487 spn_MULTICAST_L2_RANGE, soc_mem_index_count(unit, L2MCm) / 2))); 10488 SOC_IF_ERROR_RETURN 10489 (soc_hbx_ipmc_size_set(unit, soc_property_get(unit, 10490 spn_MULTICAST_L3_RANGE, soc_mem_index_count(unit, L2MCm) / 2))); 10491 10492 /* Setup SW2_FP_DST_ACTION_CONTROL */ 10493 fields[0] = HGTRUNK_RES_ENf; 10494 values[0] = 1; 10495 fields[1] = LAG_RES_ENf; 10496 values[1] = 1; 10497 SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr, 10498 REG_PORT_ANY, 2, fields, values)); 10499 10500 /* Populate and enable RTAG7 Macro flow offset table */ 10501 if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) { 10502 count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm); 10503 sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t)); 10504 for (index = 0; index < count; ) { 10505 for (sub_sel = 0; (sub_sel < 8) && (index < count); sub_sel++) { 10506 for (offset = 0; 10507 offset < rtag7_field_width[sub_sel] && index < count; 10508 offset++) { 10509 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10510 SUB_SEL_ECMPf, sub_sel); 10511 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10512 OFFSET_ECMPf, offset); 10513 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 10514 if ((soc_feature(unit, soc_feature_riot) || 10515 soc_feature(unit, soc_feature_multi_level_ecmp))) { 10516 10517 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10518 SUB_SEL_ECMP_LEVEL1f, sub_sel); 10519 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10520 OFFSET_ECMP_LEVEL1f, offset); 10521 } 10522 #endif 10523 SOC_IF_ERROR_RETURN 10524 (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm, 10525 MEM_BLOCK_ANY, index, &entry)); 10526 index++; 10527 } 10528 } 10529 } 10530 10531 rval = 0; 10532 soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, USE_FLOW_SEL_ECMPf, 1); 10533 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 10534 if ((soc_feature(unit, soc_feature_riot) || 10535 soc_feature(unit, soc_feature_multi_level_ecmp))) { 10536 10537 soc_reg_field_set(unit, RTAG7_HASH_SELr, 10538 &rval, USE_FLOW_SEL_ECMP1f, 1); 10539 } 10540 #endif 10541 soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, 10542 USE_FLOW_SEL_TRILL_ECMPf, 1); 10543 SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_SELr(unit, rval)); 10544 } 10545 10546 freq = si->frequency; 10547 10548 /* 10549 * Set external MDIO freq to around 6MHz 10550 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2 10551 */ 10552 target_freq = 6; 10553 divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2); 10554 divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, divisor); 10555 dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1); 10556 rval = 0; 10557 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor); 10558 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend); 10559 WRITE_CMIC_RATE_ADJUSTr(unit, rval); 10560 10561 /* 10562 * Set internal MDIO freq to around 12MHz 10563 * Valid range is from 2.5MHz to 20MHz 10564 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2 10565 * or 10566 * DIVISOR = core_clock_freq * DIVIDENT / (target_freq * 2) 10567 */ 10568 target_freq = 12; 10569 divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2); 10570 divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, divisor); 10571 dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1); 10572 rval = 0; 10573 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 10574 divisor); 10575 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 10576 dividend); 10577 WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval); 10578 10579 delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1); 10580 if (delay >= 1 && delay <= 15) { 10581 /* coverity[result_independent_of_operands] */ 10582 SOC_IF_ERROR_RETURN(READ_CMIC_MIIM_CONFIGr(unit, &rval)); 10583 soc_reg_field_set(unit, CMIC_MIIM_CONFIGr, &rval, MDIO_OUT_DELAYf, 10584 delay); 10585 /* coverity[result_independent_of_operands] */ 10586 SOC_IF_ERROR_RETURN(WRITE_CMIC_MIIM_CONFIGr(unit, rval)); 10587 } 10588 10589 if (!SOC_WARM_BOOT(unit)) { 10590 SOC_IF_ERROR_RETURN(_soc_monterey_ledup_init(unit)); 10591 } 10592 10593 if (soc_mspi_init(unit) != SOC_E_NONE) { 10594 LOG_ERROR(BSL_LS_SOC_COMMON, 10595 (BSL_META_U(unit, 10596 "unit %d : MSPI Init Failed\n"), unit)); 10597 } 10598 10599 if (parity_enable) { 10600 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 10601 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit)); 10602 } 10603 10604 soc_ser_log_init(unit, NULL, 0); 10605 10606 /* Setup config needed for EP-Redirection */ 10607 /* Enable re-direction */ 10608 rval = 0; 10609 soc_reg_field_set(unit, EP_REDIR_CONTROLr, &rval, ENABLEf, 1); 10610 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, EP_REDIR_CONTROLr, 10611 REG_PORT_ANY, 0, rval)); 10612 10613 #ifdef INCLUDE_XFLOW_MACSEC 10614 if (soc_feature(unit, soc_feature_xflow_macsec)) { 10615 SOC_IF_ERROR_RETURN(_soc_xflow_macsec_init(unit)); 10616 if (!soc_feature(unit, soc_feature_xflow_macsec_poll_intr)) { 10617 /* MACSEC has single CMIC bit for both functional and ECC interrupts */ 10618 SOC_IF_ERROR_RETURN(_soc_monterey_macsec_intr_enable(unit, TRUE)); 10619 } 10620 } 10621 #endif 10622 return SOC_E_NONE; 10623 } 10624 10625 uint32 _soc_monterey_mmu_port(int unit, int port) 10626 { 10627 soc_info_t *si = &SOC_INFO(unit); 10628 return si->port_p2m_mapping[si->port_l2p_mapping[port]]; 10629 } 10630 10631 uint32 _soc_monterey_piped_mem_index(int unit, soc_port_t port, 10632 soc_mem_t mem, int arr_off) 10633 { 10634 int mmu_port; 10635 10636 mmu_port = SOC_MONTEREY_MMU_PORT(unit, port); 10637 10638 switch (mem) { 10639 case MMU_THDM_DB_PORTSP_CONFIG_0m: 10640 case MMU_THDM_MCQE_PORTSP_CONFIG_0m: 10641 10642 return (mmu_port & 0x7f) * _MONTEREY_MMU_NUM_POOL + arr_off; 10643 case THDI_PORT_SP_CONFIG_Xm: 10644 case MMU_THDU_XPIPE_CONFIG_PORTm: 10645 case MMU_THDU_XPIPE_RESUME_PORTm: 10646 return (mmu_port & 0x7f) * _MONTEREY_MMU_NUM_POOL + arr_off; 10647 case THDI_PORT_PG_CONFIG_Xm: 10648 return (mmu_port & 0x7f) * _MONTEREY_MMU_NUM_PG + arr_off; 10649 default: 10650 return 0xffffffff; 10651 } 10652 } 10653 10654 #define _MONTEREY_MMU_BYTES_TO_CELLS(_byte_) \ 10655 (((_byte_) + _MONTEREY_MMU_BYTES_PER_CELL - 1) / _MONTEREY_MMU_BYTES_PER_CELL) 10656 10657 STATIC void 10658 _soc_monterey_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg, 10659 int lossless) 10660 { 10661 soc_info_t *si; 10662 si = &SOC_INFO(unit); 10663 10664 sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t)); 10665 10666 devcfg->max_pkt_byte = si->max_mtu; 10667 devcfg->mmu_hdr_byte = _MONTEREY_MMU_PACKET_HEADER_BYTES; 10668 devcfg->jumbo_pkt_size = _MONTEREY_MMU_JUMBO_FRAME_BYTES; 10669 devcfg->default_mtu_size = _MONTEREY_MMU_DEFAULT_MTU_BYTES; 10670 devcfg->mmu_cell_size = _MONTEREY_MMU_BYTES_PER_CELL; 10671 10672 10673 devcfg->mmu_total_cell = _MONTEREY_MMU_TOTAL_CELLS - 10674 (lossless ? 16 : 0); 10675 10676 devcfg->num_pg = _MONTEREY_MMU_NUM_PG; 10677 devcfg->num_service_pool = _MONTEREY_MMU_NUM_POOL; 10678 devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN | 10679 SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY; 10680 devcfg->total_mcq_entry = _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit); 10681 devcfg->rqe_queue_num = 11; 10682 } 10683 10684 STATIC int 10685 _soc_monterey_default_lossless_pg_headroom(int unit, soc_port_t port) 10686 { 10687 soc_info_t *si; 10688 if (IS_ROE_ENABLED(unit)) { 10689 return 0; 10690 } 10691 if (IS_CPU_PORT(unit, port) ) { 10692 return 50; 10693 } 10694 if (IS_LB_PORT(unit, port)) { 10695 return 162; 10696 } 10697 10698 if (IS_MACSEC_PORT(unit, port)) { 10699 return 117; 10700 } 10701 10702 si = &SOC_INFO(unit); 10703 if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 10704 if (si->port_speed_max[port] >= 100000) { 10705 return 687; 10706 } else if (si->port_speed_max[port] >= 50000) { 10707 return 352; 10708 } else if (si->port_speed_max[port] >= 40000) { 10709 return 338; 10710 } else if (si->port_speed_max[port] >= 25000) { 10711 return 214; 10712 } else if (si->port_speed_max[port] >= 20000) { 10713 return 206; 10714 } else { 10715 return 185; 10716 } 10717 } else { 10718 if (si->port_speed_max[port] >= 100000) { 10719 return 558; 10720 } else if (si->port_speed_max[port] >= 50000) { 10721 return 298; 10722 } else if (si->port_speed_max[port] >= 40000) { 10723 return 284; 10724 } else if (si->port_speed_max[port] >= 25000) { 10725 return 191; 10726 } else if (si->port_speed_max[port] >= 20000) { 10727 return 183; 10728 } else { 10729 return 162; 10730 } 10731 } 10732 10733 return 0; 10734 } 10735 10736 STATIC int 10737 _soc_monterey_min_cell_rsvd_per_mcq(int unit, int port, int default_val) 10738 { 10739 int freq, speed, osub; 10740 soc_info_t *si; 10741 uint8 rev_id; 10742 10743 soc_cm_get_id(unit, NULL, &rev_id); 10744 10745 if (rev_id == BCM56850_A1_REV_ID) { 10746 si = &SOC_INFO(unit); 10747 speed = si->port_speed_max[port]; 10748 osub = (SOC_PBMP_MEMBER(si->oversub_pbm, port)) ? 1 : 0; 10749 10750 if (speed <= 11000) { 10751 return (osub) ? 10 : 5; 10752 } else if (speed <= 42000) { 10753 freq = si->frequency; 10754 return ((freq >= 760) && !osub) ? 9 : 16; 10755 } 10756 } 10757 10758 return default_val; 10759 } 10760 10761 10762 /* 10763 * Function: 10764 * soc_monterey_mcq_entries_rsvd_port 10765 * Purpose: 10766 * For a given port, soc_mn_mcq_entries_rsvd_port calculates 10767 * the number of MC q entries (Reserved Egress Queue Entries). 10768 * This function only gives MC q entries for 10769 * for flex disabled ports. 10770 * For flex enabled port macros, this function is not used. 10771 * Parameters: 10772 * unit - (IN) Unit number. 10773 * port - (IN) logical port num 10774 * Returns: 10775 * Reserved Egress Queue Entries for a given port 10776 */ 10777 int soc_mn_mcq_entries_rsvd_port(int unit, int port) 10778 { 10779 int port_num_cosq; 10780 soc_info_t *si; 10781 int mcq_entry = 0; 10782 10783 si = &SOC_INFO(unit); 10784 port_num_cosq = si->port_num_cosq[port]; 10785 mcq_entry = port_num_cosq * _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD; 10786 return mcq_entry; 10787 } 10788 10789 /* 10790 * Function: 10791 * soc_mn_egr_buf_rsvd_port 10792 * Purpose: 10793 * For Cpu port or loopback port, 10794 * soc_td2p_egr_buf_rsvd_port calculates 10795 * the reserved queue min/guarantee. 10796 * This function only gives cumulative (for all queues) 10797 * queue guarantee for CPU port or Loopback port. 10798 * Parameters: 10799 * unit - (IN) Unit number. 10800 * port - (IN) logical port num for CPU port or LB port 10801 * Returns: 10802 * Reserved Cumulative (total for all queues) Queue Min/Guarantee value 10803 */ 10804 int soc_mn_egr_buf_rsvd_port(int unit, int port, int default_mtu_cells) 10805 { 10806 int port_num_cosq; 10807 soc_info_t *si; 10808 int egr_rsvd = 0; 10809 int min_cell_per_mcq; 10810 10811 if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) { 10812 return 0; 10813 } 10814 10815 si = &SOC_INFO(unit); 10816 10817 port_num_cosq = si->port_num_cosq[port]; 10818 10819 if (soc_feature(unit, soc_feature_min_cell_per_queue)) { 10820 min_cell_per_mcq = _soc_monterey_min_cell_rsvd_per_mcq 10821 (unit, port, default_mtu_cells); 10822 } else { 10823 min_cell_per_mcq = default_mtu_cells; 10824 } 10825 10826 egr_rsvd = port_num_cosq * min_cell_per_mcq; 10827 return egr_rsvd; 10828 } 10829 10830 STATIC void 10831 _soc_monterey_mmu_config_buf_default(int unit, _soc_mmu_cfg_buf_t *buf, 10832 _soc_mmu_device_info_t *devcfg, int lossless) 10833 { 10834 soc_info_t *si; 10835 _soc_mmu_cfg_buf_pool_t *buf_pool; 10836 _soc_mmu_cfg_buf_port_t *buf_port; 10837 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 10838 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 10839 _soc_mmu_cfg_buf_queue_t *buf_queue; 10840 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 10841 int max_packet_cells, pg_min, default_mtu_cells; 10842 int port, idx, per_q_guarentee; 10843 int total_pool_size = 0, egr_shared_total = 0; 10844 int q_reserved = 0, in_reserved = 0; 10845 int mcq_entry_reserved = 0; 10846 int mcq_entry_shared_total; 10847 int rqe_entry_shared_total; 10848 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 10849 int asf_rsvd = 0, ing_rsvd = 0, egr_rsvd = 0; 10850 int pool0_share = 0 ; 10851 int pool1_share = 0; 10852 int mn_mmu_express_buffer_total = _MN_MMU_EXPRESS_BUFFER_TOTAL_1; 10853 int tdm_freq = 0 ; 10854 si = &SOC_INFO(unit); 10855 LOG_VERBOSE(BSL_LS_SOC_COMMON, 10856 (BSL_META_U(unit, 10857 "Initializing default MMU config (u=%d)\n"), unit)); 10858 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 10859 devcfg->mmu_hdr_byte, 10860 devcfg->mmu_cell_size); 10861 pg_min = _MONTEREY_MMU_PG_MIN; 10862 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 10863 devcfg->mmu_hdr_byte, 10864 devcfg->mmu_cell_size); 10865 10866 total_pool_size = devcfg->mmu_total_cell; 10867 10868 buf->headroom = 2 * _MONTEREY_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE; 10869 10870 in_reserved += (buf->headroom/2); 10871 10872 per_q_guarentee = (lossless) ? 0 : default_mtu_cells; 10873 if (asf_rsvd < buf->rsvd_buffers[0].asf_rsvd_cells) { 10874 asf_rsvd = buf->rsvd_buffers[0].asf_rsvd_cells; 10875 } 10876 if (egr_rsvd < buf->rsvd_buffers[0].egr_rsvd_cells) { 10877 egr_rsvd = buf->rsvd_buffers[0].egr_rsvd_cells; 10878 } 10879 if (ing_rsvd < buf->rsvd_buffers[0].ing_rsvd_cells) { 10880 ing_rsvd = buf->rsvd_buffers[0].ing_rsvd_cells; 10881 } 10882 PBMP_ALL_ITER(unit, port) { 10883 mcq_entry_reserved += si->port_num_cosq[port] * 10884 _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD; 10885 q_reserved += (si->port_num_cosq[port] + si->port_num_uc_cosq[port]) * 10886 per_q_guarentee; 10887 } 10888 egr_shared_total = total_pool_size - q_reserved - 168; 10889 10890 10891 mcq_entry_shared_total = _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit) - mcq_entry_reserved; 10892 10893 rqe_entry_shared_total = _MONTEREY_MMU_TOTAL_RQE_ENTRY(unit) - 160 - 88; 10894 10895 /* the division needs to be diffrent for ethernet and the other sku supported 10896 * based on sku type we should update the share values 10897 */ 10898 tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY,si->frequency); 10899 if (IS_ROE_ENABLED(unit)) { 10900 if (tdm_freq == 815 || tdm_freq == 666) { 10901 mn_mmu_express_buffer_total = _MN_MMU_EXPRESS_BUFFER_TOTAL_1; 10902 } else { 10903 mn_mmu_express_buffer_total = _MN_MMU_EXPRESS_BUFFER_TOTAL_2; 10904 } 10905 } else { 10906 mn_mmu_express_buffer_total = 0; 10907 } 10908 if (IS_ROE_ENABLED(unit)) { 10909 pool0_share = total_pool_size - mn_mmu_express_buffer_total; 10910 pool1_share = mn_mmu_express_buffer_total; 10911 } else { 10912 pool0_share = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 10913 pool1_share = 0; 10914 } 10915 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 10916 buf_pool = &buf->pools[idx]; 10917 10918 if (idx == 0) { /* 43 % */ 10919 buf_pool->size = pool0_share ; 10920 buf_pool->yellow_size = pool0_share ; 10921 buf_pool->red_size = pool0_share ; 10922 buf_pool->total_mcq_entry = _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit) ; 10923 buf_pool->total_rqe_entry = rqe_entry_shared_total ; 10924 buf_pool->mcq_entry_reserved = mcq_entry_reserved; 10925 } else if (idx == 1 && IS_ROE_ENABLED(unit)) { /* 56 % of total is reservef for express traffic */ 10926 buf_pool->size = pool1_share ; 10927 buf_pool->yellow_size = pool1_share ; 10928 buf_pool->red_size = pool1_share ; 10929 buf_pool->total_mcq_entry = 0; 10930 buf_pool->total_rqe_entry = 0 ; 10931 buf_pool->mcq_entry_reserved = 0; 10932 } else { 10933 buf_pool->size = 0; 10934 buf_pool->yellow_size = 0; 10935 buf_pool->red_size = 0; 10936 buf_pool->total_mcq_entry = 0; 10937 buf_pool->total_rqe_entry = 0; 10938 buf_pool->mcq_entry_reserved = 0; 10939 } 10940 } 10941 10942 for (idx = 0; idx < SOC_MONTEREY_MMU_CFG_QGROUP_MAX; idx++) { 10943 queue_grp = &buf->qgroups[idx]; 10944 queue_grp->pool_limit = egr_shared_total; 10945 if (lossless) { 10946 queue_grp->guarantee = 0; 10947 queue_grp->pool_scale = -1; 10948 queue_grp->discard_enable = 0; 10949 queue_grp->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 10950 queue_grp->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 10951 } else { 10952 queue_grp->guarantee = 16; 10953 queue_grp->discard_enable = 1; 10954 queue_grp->pool_scale = 8; 10955 } 10956 queue_grp->pool_resume = default_mtu_cells * 2; 10957 queue_grp->yellow_resume = default_mtu_cells * 2; 10958 queue_grp->red_resume = default_mtu_cells * 2; 10959 } 10960 10961 PBMP_ALL_ITER(unit, port) { 10962 buf_port = &buf->ports[port]; 10963 10964 /* internal priority to priority group mapping */ 10965 for (idx = 0; idx < 16; idx++) { 10966 buf_port->pri_to_prigroup[idx] = 7; 10967 if (IS_ROE_ENABLED(unit)) { 10968 switch (idx) { 10969 case 1: 10970 buf_port->pri_to_prigroup[idx] = 1; 10971 break; 10972 case 3: 10973 buf_port->pri_to_prigroup[idx] = 3; 10974 break; 10975 case 5: 10976 buf_port->pri_to_prigroup[idx] = 5; 10977 break; 10978 case 7: 10979 buf_port->pri_to_prigroup[idx] = 7; 10980 break; 10981 default : 10982 buf_port->pri_to_prigroup[idx] = 0; 10983 } 10984 } 10985 if (lossless && IS_RDB_PORT(unit, port)) { 10986 if (idx < 5) { 10987 buf_port->pri_to_prigroup[idx] = idx + 2; 10988 } 10989 } 10990 } 10991 10992 /* priority group to pool mapping */ 10993 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 10994 if (IS_ROE_ENABLED(unit) && (idx == 5 || idx == 7)) { 10995 buf_port->prigroups[idx].pool_idx = 1; 10996 } else { 10997 buf_port->prigroups[idx].pool_idx = 0; 10998 } 10999 } 11000 11001 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11002 buf_port_pool = &buf_port->pools[idx]; 11003 buf_port_pool->guarantee = 0; 11004 buf_port_pool->pool_limit = 0; 11005 buf_port_pool->pool_resume = 0; 11006 if (idx == 0) { 11007 buf_port_pool->pool_limit = total_pool_size - mn_mmu_express_buffer_total; 11008 buf_port_pool->pool_resume = 11009 total_pool_size - (default_mtu_cells * 2) - mn_mmu_express_buffer_total; 11010 } else if (IS_ROE_ENABLED(unit) && (idx == 1)) { 11011 buf_port_pool->pool_limit = mn_mmu_express_buffer_total; 11012 buf_port_pool->pool_resume = 11013 mn_mmu_express_buffer_total - (default_mtu_cells * 2) ; 11014 } 11015 in_reserved += buf_port_pool->guarantee; 11016 } 11017 11018 buf_port->pkt_size = max_packet_cells; 11019 /* priority group */ 11020 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 11021 buf_prigroup = &buf_port->prigroups[idx]; 11022 buf_prigroup->guarantee = 0; 11023 buf_prigroup->user_delay = -1; 11024 buf_prigroup->switch_delay = -1; 11025 buf_prigroup->pkt_size = max_packet_cells; 11026 buf_prigroup->device_headroom_enable = 0; 11027 buf_prigroup->pool_limit = 0; 11028 buf_prigroup->pool_floor = 0; 11029 buf_prigroup->pool_scale = -1; 11030 buf_prigroup->headroom = 0; 11031 buf_prigroup->pool_resume = 0; 11032 buf_prigroup->flow_control_enable = 0; 11033 if (idx == 7) { 11034 buf_prigroup->device_headroom_enable = 1; 11035 buf_prigroup->flow_control_enable = lossless; 11036 if (lossless) { 11037 buf_prigroup->headroom = 11038 _soc_monterey_default_lossless_pg_headroom(unit, port); 11039 buf_prigroup->guarantee = pg_min; 11040 buf_prigroup->pool_scale = 8; 11041 buf_prigroup->pool_resume = default_mtu_cells * 2; 11042 } 11043 if (!lossless && IS_CPU_PORT(unit, port)) { 11044 buf_prigroup->headroom = 11045 _soc_monterey_default_lossless_pg_headroom(unit, port); 11046 } 11047 } else { 11048 buf_prigroup->device_headroom_enable = 1; 11049 } 11050 in_reserved += buf_prigroup->guarantee + buf_prigroup->headroom; 11051 } 11052 11053 /* multicast queue */ 11054 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 11055 buf_queue = &buf_port->queues[idx]; 11056 buf_queue->qgroup_id = ((1 <= port) && (port <= 64)) ? 0 : -1; 11057 buf_queue->mcq_entry_guarantee = 0; 11058 if (lossless) { 11059 buf_queue->guarantee = (((1 <= port) && (port <= 64)) || 11060 IS_CPU_PORT(unit, port) || 11061 IS_LB_PORT(unit, port)) ? 0 : default_mtu_cells; 11062 buf_queue->discard_enable = IS_MACSEC_PORT(unit, port) ? 1 : 0; 11063 buf_queue->pool_scale = IS_MACSEC_PORT(unit, port) ? 8 : -1; 11064 buf_queue->pool_limit = egr_shared_total; 11065 buf_queue->mcqe_limit = mcq_entry_shared_total; 11066 buf_queue->yellow_limit = mcq_entry_shared_total; 11067 buf_queue->red_limit = mcq_entry_shared_total; 11068 buf_queue->color_discard_enable = 0; 11069 buf_queue->pool_resume = 16; 11070 } else { 11071 buf_queue->guarantee = ((1 <= port) && (port <= 64)) ? 0 : default_mtu_cells; 11072 buf_queue->discard_enable = 1; 11073 buf_queue->pool_scale = 8; 11074 buf_queue->pool_limit = 0; 11075 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11076 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11077 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11078 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11079 buf_queue->color_discard_enable = 0; 11080 buf_queue->pool_resume = 16; 11081 } 11082 } 11083 11084 /* unicast queue */ 11085 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 11086 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 11087 if (IS_ROE_ENABLED(unit) && (idx == 5 || idx == 7)) { 11088 buf_queue->qgroup_id = ((1 <= port) && (port <= 64)) ? 2 : 1; 11089 }else { 11090 buf_queue->qgroup_id = ((1 <= port) && (port <= 64)) ? 0 : 1; 11091 } 11092 if (lossless) { 11093 buf_queue->guarantee = 0; 11094 buf_queue->discard_enable = 0; 11095 buf_queue->pool_scale = -1; 11096 buf_queue->pool_limit = egr_shared_total ; 11097 buf_queue->yellow_limit = egr_shared_total; 11098 buf_queue->red_limit = egr_shared_total; 11099 buf_queue->color_discard_enable = 0; 11100 buf_queue->pool_resume = default_mtu_cells * 2; 11101 buf_queue->yellow_resume = default_mtu_cells * 2; 11102 buf_queue->red_resume = default_mtu_cells * 2; 11103 } else { 11104 if (IS_ROE_ENABLED(unit) && (idx == 1 || idx == 3)) { 11105 buf_queue->guarantee = ((1 <= port) && (port <= 64)) ? 8 : 0; 11106 } else { 11107 buf_queue->guarantee = ((1 <= port) && (port <= 64)) ? 0 : default_mtu_cells; 11108 } 11109 buf_queue->discard_enable = 1; 11110 buf_queue->pool_scale = 8; 11111 buf_queue->pool_limit = 0; 11112 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11113 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11114 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11115 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11116 buf_queue->color_discard_enable = 0; 11117 buf_queue->pool_resume = default_mtu_cells * 2; 11118 buf_queue->yellow_resume = default_mtu_cells * 2; 11119 buf_queue->red_resume = default_mtu_cells * 2; 11120 } 11121 } 11122 11123 /* queue to pool mapping */ 11124 for (idx = 0; 11125 idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) { 11126 if(IS_ROE_ENABLED(unit) && ((idx == 15 || idx == 17) 11127 && !IS_CPU_PORT(unit, port))) { 11128 buf_port->queues[idx].pool_idx = 1; 11129 } else { 11130 buf_port->queues[idx].pool_idx = 0; 11131 } 11132 } 11133 } 11134 11135 PBMP_ALL_ITER(unit, port) { 11136 buf_port = &buf->ports[port]; 11137 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 11138 buf_prigroup = &buf_port->prigroups[idx]; 11139 if (!lossless) { 11140 if (IS_ROE_ENABLED(unit) && (idx == 5 || idx ==7)) 11141 buf_prigroup->pool_limit = mn_mmu_express_buffer_total; 11142 else { 11143 buf_prigroup->pool_limit = total_pool_size - in_reserved - 11144 mn_mmu_express_buffer_total - 16; 11145 } 11146 } 11147 } 11148 } 11149 11150 /* RQE */ 11151 for (idx = 0; idx < 11; idx++) { 11152 buf_rqe_queue = &buf->rqe_queues[idx]; 11153 buf_rqe_queue->pool_idx = 0; 11154 buf_rqe_queue->yellow_limit = egr_shared_total; 11155 buf_rqe_queue->red_limit = egr_shared_total; 11156 if (lossless) { 11157 buf_rqe_queue->guarantee = 8; 11158 buf_rqe_queue->discard_enable = 0; 11159 buf_rqe_queue->pool_scale = -1; 11160 buf_rqe_queue->pool_limit = egr_shared_total; 11161 } else { 11162 buf_rqe_queue->guarantee = default_mtu_cells; 11163 buf_rqe_queue->discard_enable = 1; 11164 buf_rqe_queue->pool_scale = 8; 11165 buf_rqe_queue->pool_limit = 0; 11166 buf_rqe_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 11167 buf_rqe_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 11168 } 11169 } 11170 11171 } 11172 11173 STATIC int 11174 _soc_monterey_pool_scale_to_limit(int size, int scale) 11175 { 11176 int factor = 1000; 11177 11178 switch (scale) { 11179 case 7: factor = 875; break; 11180 case 6: factor = 750; break; 11181 case 5: factor = 625; break; 11182 case 4: factor = 500; break; 11183 case 3: factor = 375; break; 11184 case 2: factor = 250; break; 11185 case 1: factor = 125; break; 11186 case 0: 11187 default: 11188 factor = 1000; break; 11189 } 11190 return (size * factor)/1000; 11191 } 11192 STATIC int 11193 _soc_monterey_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf, 11194 _soc_mmu_device_info_t *devcfg, int lossless, 11195 soc_port_t input_port) 11196 { 11197 soc_info_t *si; 11198 _soc_mmu_cfg_buf_pool_t *buf_pool; 11199 _soc_mmu_cfg_buf_port_t *buf_port; 11200 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 11201 _soc_mmu_cfg_buf_queue_t *buf_queue; 11202 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 11203 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 11204 soc_mem_t mem, mem1, mem2, mem3; 11205 uint32 rval, fval, rval2, rval3; 11206 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 11207 thdi_port_pg_config_entry_t pg_config_mem; 11208 thdi_port_sp_config_entry_t thdi_sp_config; 11209 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 11210 mmu_thdu_xpipe_offset_qgroup_entry_t offset_qgrp; 11211 int default_mtu_cells, limit, midx, pri, rlimit, min_resume_limit; 11212 int port, base, numq, idx; 11213 int jumbo_frame_cells, pval, rqlen, qbase; 11214 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 11215 int port_count = 0; 11216 soc_reg_t reg = INVALIDr; 11217 static const soc_field_t prigroup_reg[] = { 11218 THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r 11219 }; 11220 static const soc_field_t prigroup_field[] = { 11221 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 11222 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 11223 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 11224 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 11225 }; 11226 static const soc_field_t prigroup_spid_field[] = { 11227 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 11228 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 11229 }; 11230 int index1; 11231 int pool_resume = 0; 11232 uint16 dev_id; 11233 uint8 rev_id; 11234 int ing_rsvd = 0, egr_rsvd = 0, asf_rsvd = 0; 11235 int total_rsvd = 0 ; 11236 int cpu_hdrm = 0; 11237 int jumbo_packet_cells = 45; 11238 soc_cm_get_id(unit, &dev_id, &rev_id); 11239 11240 min_resume_limit = soc_feature(unit, soc_feature_min_resume_limit_1) ? 8 : 0; 11241 11242 si = &SOC_INFO(unit); 11243 11244 jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size + 11245 devcfg->mmu_hdr_byte, 11246 devcfg->mmu_cell_size); 11247 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 11248 devcfg->mmu_hdr_byte, 11249 devcfg->mmu_cell_size); 11250 11251 idx = 0 ; 11252 rval = 0; 11253 fval = _MONTEREY_CFAPFULLSETPOINT; 11254 if (input_port == -1) { 11255 soc_reg_field_set(unit, CFAPFULLSETPOINTr, &rval, CFAPFULLSETPOINTf, 11256 fval); 11257 SOC_IF_ERROR_RETURN(WRITE_CFAPFULLSETPOINTr(unit, rval)); 11258 rval = 0; 11259 soc_reg_field_set(unit, CFAPFULLRESETPOINTr, &rval, 11260 CFAPFULLRESETPOINTf, fval - 2 * jumbo_frame_cells); 11261 SOC_IF_ERROR_RETURN(WRITE_CFAPFULLRESETPOINTr(unit, rval)); 11262 rval = 0; 11263 SOC_IF_ERROR_RETURN(WRITE_TOQ_MC_CFG0r(unit, rval)); 11264 } 11265 if (asf_rsvd < buf->rsvd_buffers[idx].asf_rsvd_cells) { 11266 asf_rsvd = buf->rsvd_buffers[idx].asf_rsvd_cells; 11267 } 11268 if (egr_rsvd < buf->rsvd_buffers[idx].egr_rsvd_cells) { 11269 egr_rsvd = buf->rsvd_buffers[idx].egr_rsvd_cells; 11270 } 11271 if (ing_rsvd < buf->rsvd_buffers[idx].ing_rsvd_cells) { 11272 ing_rsvd = buf->rsvd_buffers[idx].ing_rsvd_cells; 11273 } 11274 LOG_VERBOSE(BSL_LS_SOC_MMU, 11275 (BSL_META_U(unit, 11276 "MMU config set HW: Cells rsvd : %d\n"), 11277 (ing_rsvd + egr_rsvd + asf_rsvd))); 11278 11279 /* internal priority to priority group mapping */ 11280 PBMP_ALL_ITER(unit, port) { 11281 if ((input_port != port) && 11282 (input_port != -1)) { 11283 continue; 11284 } 11285 buf_port = &buf->ports[port]; 11286 11287 for (idx = 0; idx < 16; idx++) { 11288 if (idx % 8 == 0) { /* 8 fields per register */ 11289 reg = prigroup_reg[idx / 8]; 11290 rval = 0; 11291 } 11292 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 11293 buf_port->pri_to_prigroup[idx]); 11294 if (idx % 8 == 7) { /* 8 fields per register */ 11295 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 11296 } 11297 } 11298 } 11299 if (input_port == -1) { 11300 /* Input thresholds */ 11301 rval = 0; 11302 soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr, 11303 &rval, GLOBAL_HDRM_LIMITf, buf->headroom/2); 11304 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr, 11305 REG_PORT_ANY, 0, rval)); 11306 11307 11308 fval = 0; 11309 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11310 if ((buf->pools[idx].size & ~_MMU_CFG_BUF_PERCENT_FLAG) != 0) { 11311 fval |= 1 << idx; 11312 } 11313 } 11314 11315 rval = 0; 11316 soc_reg_field_set(unit, THDI_BYPASSr, &rval, INPUT_THRESHOLD_BYPASSf, 0); 11317 SOC_IF_ERROR_RETURN(WRITE_THDI_BYPASSr(unit, rval)); 11318 11319 11320 rval = 0; 11321 soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, COLOR_AWAREf, 0); 11322 soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, PUBLIC_ENABLEf, 1); 11323 SOC_IF_ERROR_RETURN(WRITE_THDI_POOL_CONFIGr(unit, rval)); 11324 11325 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11326 buf_pool = &buf->pools[idx]; 11327 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 11328 continue; 11329 } 11330 ing_rsvd = buf_pool->prigroup_headroom + buf_pool->prigroup_guarantee; 11331 11332 11333 if (lossless) { 11334 limit = devcfg->mmu_total_cell - (ing_rsvd+ 11335 (buf->headroom/2) + 11336 buf_pool->queue_guarantee + asf_rsvd); 11337 } else { 11338 cpu_hdrm = _soc_monterey_default_lossless_pg_headroom( 11339 unit, 11340 CMIC_PORT(unit)); 11341 if(idx == 0) { 11342 if (IS_ROE_ENABLED(unit)) { 11343 cpu_hdrm = 0 ; 11344 } 11345 limit = buf_pool->total - 11346 (buf->headroom/2) - cpu_hdrm - asf_rsvd - 16 ; 11347 } else { 11348 limit = buf_pool->total; 11349 } 11350 } 11351 11352 PBMP_ALL_ITER(unit, port) { 11353 port_count++; 11354 } 11355 port_count -= 3; /*macsec, cpu and lb */ 11356 if (IS_ROE_ENABLED(unit)) { 11357 pool_resume = jumbo_packet_cells * 2; 11358 } else { 11359 pool_resume = (port_count / 2) * default_mtu_cells; 11360 } 11361 rval = 0; 11362 soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit); 11363 SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, rval)); 11364 11365 rval = 0; 11366 soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 11367 OFFSETf, pool_resume); 11368 SOC_IF_ERROR_RETURN(WRITE_THDI_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval)); 11369 } 11370 11371 rval = 0; 11372 SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr(unit, rval)); 11373 11374 /* output thresholds */ 11375 SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval)); 11376 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_QUEUE_AND_GROUP_TICKETf, 1); 11377 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_UPDATE_COLOR_RESUMEf, 1); 11378 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 11379 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0); 11380 SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval)); 11381 11382 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 11383 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, MOP_POLICYf, 1); 11384 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 11385 11386 /* per service pool settings */ 11387 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11388 buf_pool = &buf->pools[idx]; 11389 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 11390 continue; 11391 } 11392 total_rsvd = buf_pool->queue_guarantee ; 11393 if (idx == 0) { 11394 limit = buf_pool->total - (total_rsvd + asf_rsvd + 11395 (IS_ROE_ENABLED(unit) ? 0 : 16)); 11396 } else { 11397 limit = buf_pool->total ; 11398 } 11399 if (limit <= 0) { 11400 limit = 0; 11401 } 11402 11403 rval = 0; 11404 soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 11405 SHARED_LIMITf, limit); 11406 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, idx, rval)); 11407 11408 rval = 0; 11409 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 11410 &rval, YELLOW_SHARED_LIMITf, (limit + 7)/8); 11411 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, idx, rval)); 11412 11413 rval = 0; 11414 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 11415 &rval, RED_SHARED_LIMITf, (limit + 7)/8); 11416 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, idx, rval)); 11417 11418 rval = 0; 11419 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 11420 &rval, RESUME_LIMITf, (limit + 7) /8); 11421 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, idx, rval)); 11422 11423 rval = 0; 11424 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 11425 &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8); 11426 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, idx, rval)); 11427 11428 rval = 0; 11429 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 11430 &rval, RED_RESUME_LIMITf, (limit + 7)/8); 11431 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, idx, rval)); 11432 11433 total_rsvd = 0 ; 11434 total_rsvd = buf_pool->mcq_entry_reserved; 11435 11436 /* mcq entries */ 11437 limit = buf_pool->total_mcq_entry - total_rsvd; 11438 11439 rval = 0; 11440 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 11441 &rval, SHARED_LIMITf, limit/4); 11442 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit, 11443 idx, rval)); 11444 11445 rval = 0; 11446 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 11447 &rval, YELLOW_SHARED_LIMITf, (limit + 7)/ 8); 11448 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit, 11449 idx, rval)); 11450 11451 rval = 0; 11452 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 11453 &rval, RED_SHARED_LIMITf, (limit + 7)/8); 11454 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit, 11455 idx, rval)); 11456 11457 rval = 0; 11458 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 11459 &rval, RESUME_LIMITf, (limit + 7)/8); 11460 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit, 11461 idx, rval)); 11462 11463 rval = 0; 11464 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 11465 &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8); 11466 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit, 11467 idx, rval)); 11468 11469 rval = 0; 11470 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 11471 &rval, RED_RESUME_LIMITf, (limit + 7)/8); 11472 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit, 11473 idx, rval)); 11474 } 11475 11476 rval = 0; 11477 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 11478 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1); 11479 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 11480 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Af, 0); 11481 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval)); 11482 11483 rval = 0; 11484 soc_reg_field_set(unit, MMU_THDR_QE_CONFIGr, &rval, 11485 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1); 11486 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIGr(unit, rval)); 11487 11488 /* configure Q-groups */ 11489 for (idx = 0; idx < SOC_MONTEREY_MMU_CFG_QGROUP_MAX; idx++) { 11490 queue_grp = &buf->qgroups[idx]; 11491 11492 mem = MMU_THDU_XPIPE_CONFIG_QGROUPm; 11493 mem1 = MMU_THDU_XPIPE_OFFSET_QGROUPm; 11494 11495 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 11496 sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp)); 11497 11498 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11499 Q_MIN_LIMIT_CELLf, queue_grp->guarantee); 11500 11501 if (queue_grp->pool_scale != -1) { 11502 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11503 Q_SHARED_ALPHA_CELLf, queue_grp->pool_scale); 11504 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11505 Q_LIMIT_DYNAMIC_CELLf, 1); 11506 } else { 11507 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11508 Q_SHARED_LIMIT_CELLf, queue_grp->pool_limit); 11509 } 11510 11511 if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 11512 pval = _soc_monterey_pool_scale_to_limit(queue_grp->pool_limit, 11513 queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 11514 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11515 LIMIT_RED_CELLf, (pval + 7)/8); 11516 11517 } else { 11518 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11519 LIMIT_RED_CELLf, queue_grp->red_limit); 11520 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11521 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 11522 } 11523 11524 if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 11525 pval = _soc_monterey_pool_scale_to_limit(queue_grp->pool_limit, 11526 queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 11527 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11528 LIMIT_YELLOW_CELLf, (pval + 7)/8); 11529 11530 } else { 11531 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11532 LIMIT_YELLOW_CELLf, queue_grp->yellow_limit); 11533 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11534 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 11535 } 11536 SOC_IF_ERROR_RETURN 11537 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 11538 11539 soc_mem_field32_set(unit, mem1, 11540 &offset_qgrp, RESET_OFFSET_CELLf, queue_grp->pool_resume / 8); 11541 soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_YELLOW_CELLf, 11542 queue_grp->yellow_resume / 8); 11543 soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_RED_CELLf, 11544 queue_grp->red_resume / 8); 11545 11546 SOC_IF_ERROR_RETURN 11547 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp)); 11548 } 11549 } 11550 11551 /* Input port per port settings */ 11552 PBMP_ALL_ITER(unit, port) { 11553 if ((input_port != port) && 11554 (input_port != -1)) { 11555 continue; 11556 } 11557 11558 buf_port = &buf->ports[port]; 11559 11560 rval = 0; 11561 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 11562 soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval, 11563 prigroup_spid_field[idx], 11564 buf_port->prigroups[idx].pool_idx); 11565 } 11566 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval)); 11567 11568 mem = THDI_PORT_SP_CONFIG_Xm; 11569 /* Per port per pool settings */ 11570 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11571 buf_port_pool = &buf_port->pools[idx]; 11572 midx = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 11573 sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config)); 11574 soc_mem_field32_set(unit, mem, &thdi_sp_config, 11575 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee); 11576 soc_mem_field32_set(unit, mem, &thdi_sp_config, 11577 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume); 11578 soc_mem_field32_set(unit, mem, &thdi_sp_config, 11579 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit); 11580 SOC_IF_ERROR_RETURN 11581 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, &thdi_sp_config)); 11582 } 11583 11584 fval = 0; 11585 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 11586 if (buf_port->prigroups[idx].flow_control_enable != 0) { 11587 for (pri=0; pri < 16; pri++) { 11588 if (buf_port->pri_to_prigroup[pri] == idx) { 11589 fval |= 1 << pri; 11590 } 11591 } 11592 } 11593 } 11594 11595 rval = 0; 11596 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 11597 INPUT_PORT_RX_ENABLEf, 1); 11598 /* For CPU and MACSEC port we don't configure pause enable */ 11599 if (IS_CPU_PORT(unit, port) || IS_MACSEC_PORT(unit, port)) { 11600 fval = 0; 11601 } 11602 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 11603 PORT_PRI_XON_ENABLEf, fval); 11604 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 11605 PORT_PAUSE_ENABLEf, fval ? 1 : 0); 11606 SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, port, rval)); 11607 11608 rval = 0; 11609 soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 11610 PORT_MAX_PKT_SIZEf, buf_port->pkt_size); 11611 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval)); 11612 11613 /* Input port per port per priority group settings */ 11614 mem = THDI_PORT_PG_CONFIG_Xm; 11615 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 11616 buf_prigroup = &buf->ports[port].prigroups[idx]; 11617 11618 midx = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 11619 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 11620 soc_mem_field32_set(unit, mem, &pg_config_mem, 11621 PG_MIN_LIMITf, buf_prigroup->guarantee); 11622 11623 if (buf_prigroup->pool_scale != -1) { 11624 soc_mem_field32_set(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf, 1); 11625 soc_mem_field32_set(unit, mem, &pg_config_mem, 11626 PG_SHARED_LIMITf, buf_prigroup->pool_scale); 11627 } else { 11628 soc_mem_field32_set(unit, mem, &pg_config_mem, 11629 PG_SHARED_LIMITf, buf_prigroup->pool_limit); 11630 } 11631 11632 soc_mem_field32_set(unit, mem, &pg_config_mem, 11633 PG_GBL_HDRM_ENf, buf_prigroup->device_headroom_enable); 11634 soc_mem_field32_set(unit, mem, &pg_config_mem, 11635 PG_HDRM_LIMITf, buf_prigroup->headroom); 11636 11637 soc_mem_field32_set(unit, mem, &pg_config_mem, 11638 PG_RESET_OFFSETf, buf_prigroup->pool_resume); 11639 11640 soc_mem_field32_set(unit, mem, &pg_config_mem, 11641 PG_RESET_FLOORf, buf_prigroup->pool_floor); 11642 11643 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 11644 MEM_BLOCK_ALL, midx, &pg_config_mem)); 11645 } 11646 } 11647 11648 /*********************************** 11649 * THDO 11650 */ 11651 /* Output port per port per queue setting for regular multicast queue */ 11652 PBMP_ALL_ITER(unit, port) { 11653 if ((input_port != port) && 11654 (input_port != -1)) { 11655 continue; 11656 } 11657 11658 numq = si->port_num_cosq[port]; 11659 qbase = si->port_cosq_base[port]; 11660 if (numq == 0) { 11661 continue; 11662 } 11663 11664 mem = MMU_THDM_DB_QUEUE_CONFIG_0m; 11665 11666 base = soc_monterey_l2_hw_index(unit, qbase, 0) - _MONTEREY_MC_QUEUE_BASE; 11667 11668 mem1 = MMU_THDM_DB_QUEUE_OFFSET_0m; 11669 mem2 = MMU_THDM_MCQE_QUEUE_OFFSET_0m; 11670 11671 for (idx = 0; idx < numq; idx++) { 11672 buf_queue = &buf->ports[port].queues[idx]; 11673 11674 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 11675 11676 soc_mem_field32_set(unit, mem, entry0, 11677 Q_MIN_LIMITf, buf_queue->guarantee); 11678 if (buf_queue->discard_enable) { 11679 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1); 11680 } 11681 if (buf_queue->color_discard_enable) { 11682 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 11683 } 11684 if (buf_queue->pool_scale != -1) { 11685 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1); 11686 soc_mem_field32_set(unit, mem, entry0, 11687 Q_SHARED_ALPHAf, buf_queue->pool_scale); 11688 } else { 11689 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 11690 soc_mem_field32_set(unit, mem, entry0, 11691 Q_SHARED_LIMITf, buf_queue->pool_limit); 11692 } 11693 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 11694 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 11695 soc_mem_field32_set(unit, mem, entry0, 11696 Q_COLOR_LIMIT_DYNAMICf, 1); 11697 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 11698 buf_queue->yellow_limit 11699 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 11700 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 11701 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 11702 buf_queue->red_limit 11703 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 11704 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 11705 } else { 11706 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 11707 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 11708 (buf_queue->pool_limit + 7) / 8); 11709 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 11710 (buf_queue->pool_limit + 7) / 8); 11711 } 11712 11713 soc_mem_field32_set(unit, mem, entry0, 11714 Q_SPIDf, buf_queue->pool_idx); 11715 11716 SOC_IF_ERROR_RETURN 11717 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 11718 entry0)); 11719 11720 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t)); 11721 11722 soc_mem_field32_set(unit, mem1, entry0, 11723 RESUME_OFFSETf, (default_mtu_cells * 2)/8); 11724 soc_mem_field32_set(unit, mem1, entry0, 11725 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 11726 soc_mem_field32_set(unit, mem1, entry0, 11727 RED_RESUME_OFFSET_PROFILE_SELf, 0); 11728 SOC_IF_ERROR_RETURN 11729 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, 11730 entry0)); 11731 11732 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_0_entry_t)); 11733 soc_mem_field32_set(unit, mem1, entry0, 11734 RESUME_OFFSETf, 1); 11735 SOC_IF_ERROR_RETURN 11736 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, 11737 entry0)); 11738 11739 SOC_IF_ERROR_RETURN 11740 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0, 11741 YELLOW_RESUME_OFFSETf, 11742 2)); 11743 11744 SOC_IF_ERROR_RETURN 11745 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0, 11746 RED_RESUME_OFFSETf, 11747 2)); 11748 } 11749 11750 mem = MMU_THDM_MCQE_QUEUE_CONFIG_0m; 11751 for (idx = 0; idx < numq; idx++) { 11752 buf_queue = &buf->ports[port].queues[idx]; 11753 11754 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_0_entry_t)); 11755 11756 soc_mem_field32_set(unit, mem, entry0, 11757 Q_MIN_LIMITf, buf_queue->mcq_entry_guarantee/4); 11758 if (buf_queue->discard_enable) { 11759 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1); 11760 } 11761 if (buf_queue->color_discard_enable) { 11762 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 11763 } 11764 if (buf_queue->pool_scale != -1) { 11765 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1); 11766 soc_mem_field32_set(unit, mem, entry0, 11767 Q_SHARED_ALPHAf, buf_queue->pool_scale); 11768 } else { 11769 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 11770 soc_mem_field32_set(unit, mem, entry0, 11771 Q_SHARED_LIMITf, buf_queue->mcqe_limit/4); 11772 } 11773 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 11774 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 11775 soc_mem_field32_set(unit, mem, entry0, 11776 Q_COLOR_LIMIT_DYNAMICf, 1); 11777 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 11778 buf_queue->yellow_limit 11779 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 11780 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 11781 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 11782 buf_queue->red_limit 11783 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 11784 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 11785 } else { 11786 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 11787 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 11788 (buf_queue->yellow_limit + 7) / 8); 11789 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 11790 (buf_queue->red_limit + 7)/ 8); 11791 } 11792 11793 soc_mem_field32_set(unit, mem, entry0, 11794 Q_SPIDf, buf_queue->pool_idx); 11795 11796 SOC_IF_ERROR_RETURN 11797 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 11798 entry0)); 11799 11800 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t)); 11801 11802 soc_mem_field32_set(unit, mem1, entry0, 11803 RESUME_OFFSETf, (default_mtu_cells * 2)/8); 11804 soc_mem_field32_set(unit, mem1, entry0, 11805 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 11806 soc_mem_field32_set(unit, mem1, entry0, 11807 RED_RESUME_OFFSET_PROFILE_SELf, 0); 11808 SOC_IF_ERROR_RETURN 11809 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, 11810 entry0)); 11811 11812 SOC_IF_ERROR_RETURN 11813 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0, 11814 YELLOW_RESUME_OFFSETf, 11815 1)); 11816 11817 SOC_IF_ERROR_RETURN 11818 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0, 11819 RED_RESUME_OFFSETf, 11820 1)); 11821 } 11822 11823 /* Per port per pool */ 11824 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11825 buf_pool = &buf->pools[idx]; 11826 if (buf_pool->total == 0 || idx > 0 ) { 11827 continue; 11828 } 11829 11830 if (IS_ROE_ENABLED(unit)) { 11831 limit = _MONTEREY_MMU_TOTAL_CELLS - 16 ; 11832 } else { 11833 limit = buf_pool->total - buf_pool->queue_guarantee ; 11834 } 11835 if ((limit - 2 * default_mtu_cells) > 0) { 11836 rlimit = ((limit - 2 * default_mtu_cells) < min_resume_limit) ? 11837 min_resume_limit : limit - 2 * default_mtu_cells; 11838 } else { 11839 rlimit = min_resume_limit; 11840 } 11841 mem2 = MMU_THDM_DB_PORTSP_CONFIG_0m; 11842 index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx); 11843 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t)); 11844 11845 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit); 11846 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8); 11847 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8); 11848 11849 soc_mem_field32_set(unit, mem2, entry0, 11850 SHARED_LIMIT_ENABLEf, !lossless); 11851 11852 soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, (rlimit + 7)/8); 11853 soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, (rlimit + 7)/8); 11854 soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, (rlimit + 7)/8); 11855 11856 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 11857 index1, entry0)); 11858 11859 mem2 = MMU_THDM_MCQE_PORTSP_CONFIG_0m; 11860 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_0_entry_t)); 11861 11862 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 11863 rlimit = (limit < min_resume_limit) ? min_resume_limit : limit; 11864 11865 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, (limit + 3)/4); 11866 soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, 11867 ((rlimit/8) - 1)); 11868 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMIT_ENABLEf, !lossless); 11869 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8); 11870 soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, 11871 ((rlimit + 7)/8 - 1)); 11872 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8); 11873 soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, 11874 ((rlimit + 7)/8 -1)); 11875 11876 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 11877 index1, entry0)); 11878 } 11879 } 11880 11881 /* Output port per port per queue setting for regular unicast queue */ 11882 PBMP_PORT_ITER(unit, port) { 11883 if ((input_port != port) && 11884 (input_port != -1)) { 11885 continue; 11886 } 11887 11888 if(IS_RDB_PORT(unit, port)) { 11889 continue; 11890 } 11891 /* per port regular unicast queue */ 11892 numq = si->port_num_uc_cosq[port]; 11893 qbase = si->port_uc_cosq_base[port]; 11894 if (numq == 0) { 11895 continue; 11896 } 11897 base = soc_monterey_l2_hw_index(unit, qbase, 1); 11898 mem = MMU_THDU_XPIPE_CONFIG_QUEUEm; 11899 mem1 = MMU_THDU_XPIPE_OFFSET_QUEUEm; 11900 mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm; 11901 for (idx = 0; idx < numq; idx++) { 11902 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx]; 11903 11904 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t)); 11905 sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_offset_queue_entry_t)); 11906 11907 soc_mem_field32_set(unit, mem, entry0, 11908 Q_MIN_LIMIT_CELLf, buf_queue->guarantee); 11909 if (buf_queue->pool_scale != -1) { 11910 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf, 1); 11911 soc_mem_field32_set(unit, mem, entry0, 11912 Q_SHARED_ALPHA_CELLf, buf_queue->pool_scale); 11913 } else { 11914 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 11915 soc_mem_field32_set(unit, mem, entry0, 11916 Q_SHARED_LIMIT_CELLf, buf_queue->pool_limit); 11917 } 11918 soc_mem_field32_set(unit, mem1, 11919 entry1, RESET_OFFSET_CELLf, buf_queue->pool_resume / 8); 11920 11921 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 11922 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 11923 soc_mem_field32_set(unit, mem, entry0, 11924 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 11925 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf, 11926 buf_queue->yellow_limit 11927 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 11928 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 11929 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf, 11930 buf_queue->red_limit 11931 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 11932 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 11933 } else { 11934 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 11935 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf, 11936 (buf_queue->yellow_limit + 7) / 8); 11937 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf, 11938 (buf_queue->red_limit + 7) / 8); 11939 } 11940 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf, 11941 buf_queue->yellow_resume / 8); 11942 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf, 11943 buf_queue->red_resume / 8); 11944 SOC_IF_ERROR_RETURN 11945 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 11946 11947 SOC_IF_ERROR_RETURN 11948 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1)); 11949 11950 sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t)); 11951 soc_mem_field32_set(unit, mem2, 11952 entry0, Q_SPIDf, buf_queue->pool_idx); 11953 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, lossless ? 0 : 1); 11954 if (IS_ROE_ENABLED(unit) && (idx ==5 || idx ==7)) { 11955 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 0 ) ; 11956 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1); 11957 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf,0); 11958 } else { 11959 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, lossless ? 0 : 1); 11960 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, lossless ? 0 : 1); 11961 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf,lossless ? 0 :1); 11962 } 11963 soc_mem_field32_set(unit, mem2, entry0, QGROUPf, 11964 (buf_queue->qgroup_id == -1) ? 0 : buf_queue->qgroup_id); 11965 11966 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 11967 base + idx, entry0)); 11968 } 11969 11970 /* Per port per pool unicast */ 11971 for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) { 11972 buf_pool = &buf->pools[idx]; 11973 11974 if (buf_pool->total == 0) { 11975 continue; 11976 } 11977 if (IS_ROE_ENABLED(unit)) { 11978 limit = _MONTEREY_MMU_TOTAL_CELLS - 16 ; 11979 } else { 11980 limit = buf_pool->total - buf_pool->queue_guarantee ; 11981 } 11982 mem2 = MMU_THDU_XPIPE_CONFIG_PORTm; 11983 index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx); 11984 mem3 = MMU_THDU_XPIPE_RESUME_PORTm; 11985 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t)); 11986 sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_resume_port_entry_t)); 11987 11988 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit); 11989 soc_mem_field32_set(unit, mem3, entry1, 11990 SHARED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8); 11991 11992 soc_mem_field32_set(unit, mem2, entry0, YELLOW_LIMITf, (limit + 7)/8); 11993 soc_mem_field32_set(unit, mem3, entry1, 11994 YELLOW_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8); 11995 11996 soc_mem_field32_set(unit, mem2, entry0, RED_LIMITf, (limit + 7)/8); 11997 soc_mem_field32_set(unit, mem3, entry1, 11998 RED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8); 11999 12000 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 12001 index1, entry0)); 12002 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem3, MEM_BLOCK_ALL, 12003 index1, entry1)); 12004 } 12005 } 12006 12007 12008 12009 if (input_port == -1) { 12010 /* RQE */ 12011 for (idx = 0; idx < 11; idx++) { 12012 buf_rqe_queue = &buf->rqe_queues[idx]; 12013 12014 rval = 0; 12015 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 12016 &rval, MIN_LIMITf, buf_rqe_queue->guarantee); 12017 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval)); 12018 12019 rval = 0; 12020 rval2 = 0; 12021 rval3 = 0; 12022 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 12023 &rval, SPIDf, buf_rqe_queue->pool_idx); 12024 12025 if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 12026 (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 12027 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 12028 &rval, COLOR_LIMIT_DYNAMICf, 1); 12029 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12030 SHARED_RED_LIMITf, buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 12031 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12032 SHARED_YELLOW_LIMITf, buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 12033 } else { 12034 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12035 SHARED_RED_LIMITf, (buf_rqe_queue->red_limit + 7)/ 8); 12036 12037 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12038 SHARED_YELLOW_LIMITf, (buf_rqe_queue->yellow_limit + 7) / 8); 12039 } 12040 12041 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 12042 (buf_rqe_queue->discard_enable ? 1 : 0)); 12043 12044 if (buf_rqe_queue->pool_scale != -1) { 12045 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 12046 &rval, DYNAMIC_ENABLEf, 1); 12047 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 12048 SHARED_ALPHAf, buf_rqe_queue->pool_scale); 12049 } else { 12050 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 12051 SHARED_LIMITf, buf_rqe_queue->pool_limit); 12052 } 12053 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 2); 12054 12055 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval)); 12056 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr_REG32(unit, idx, rval2)); 12057 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 12058 12059 rval = 0; 12060 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 12061 &rval, RESET_OFFSET_REDf, (default_mtu_cells * 2)/8); 12062 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 12063 &rval, RESET_OFFSET_YELLOWf, (default_mtu_cells * 2)/8); 12064 SOC_IF_ERROR_RETURN( 12065 WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 12066 12067 /* queue entry */ 12068 buf_pool = &buf->pools[buf_rqe_queue->pool_idx]; 12069 fval = ((buf_pool->total_rqe_entry + 7) / 8); 12070 rval = 0; 12071 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 12072 &rval, MIN_LIMITf, buf_rqe_queue->guarantee/8); 12073 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval)); 12074 12075 rval = 0; 12076 rval2 = 0; 12077 rval3 = 0; 12078 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 12079 &rval, SPIDf, buf_rqe_queue->pool_idx); 12080 12081 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 12082 &rval, COLOR_LIMIT_DYNAMICf, lossless ? 0 : 1); 12083 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 12084 &rval3, SHARED_RED_LIMITf, lossless ? fval : 0); 12085 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 12086 &rval3, SHARED_YELLOW_LIMITf, lossless ? fval : 0); 12087 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, DYNAMIC_ENABLEf, 12088 lossless ? 0 :1); 12089 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 12090 lossless ? 0 :1); 12091 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 12092 SHARED_LIMITf, lossless ? fval : 8); 12093 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 1); 12094 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval)); 12095 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2)); 12096 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 12097 12098 rval = 0; 12099 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 12100 &rval, RESET_OFFSET_REDf, default_mtu_cells/8); 12101 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 12102 &rval, RESET_OFFSET_YELLOWf, default_mtu_cells/8); 12103 SOC_IF_ERROR_RETURN( 12104 WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 12105 12106 } 12107 12108 /* per pool RQE settings */ 12109 total_rsvd = 0; 12110 for (idx = 0; idx < 4; idx++) { 12111 if (idx > 0 && IS_ROE_ENABLED(unit)) { 12112 continue; 12113 } 12114 buf_pool = &buf->pools[idx]; 12115 if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) || 12116 (buf_pool->total == 0)) { 12117 continue; 12118 } 12119 total_rsvd = buf_pool->queue_guarantee; 12120 if (idx == 0) { 12121 limit = buf_pool->total - total_rsvd - asf_rsvd - 16; 12122 } else { 12123 limit = buf_pool->total ; 12124 } 12125 12126 12127 rval = 0; 12128 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, 12129 &rval, SHARED_LIMITf, limit); 12130 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval, RESUME_LIMITf, 12131 (limit - (default_mtu_cells * 2) + 7)/8); 12132 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr_REG32(unit, idx, rval)); 12133 12134 rval = 0; 12135 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 12136 SHARED_RED_LIMITf, (limit + 7)/8); 12137 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 12138 SHARED_YELLOW_LIMITf, (limit + 7)/8); 12139 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval)); 12140 12141 rval = 0; 12142 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 12143 RESUME_RED_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8); 12144 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 12145 RESUME_YELLOW_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8); 12146 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit, 12147 idx, rval)); 12148 if (lossless) { 12149 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) - 1 ; 12150 } else { 12151 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) ; 12152 } 12153 if (rqlen == 0) { 12154 continue; 12155 } 12156 12157 rval = 0; 12158 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, SHARED_LIMITf, rqlen); 12159 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, RESUME_LIMITf, rqlen - 1); 12160 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval)); 12161 12162 rval = 0; 12163 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 12164 SHARED_RED_LIMITf, rqlen); 12165 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 12166 SHARED_YELLOW_LIMITf, rqlen); 12167 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, idx, rval)); 12168 12169 rval = 0; 12170 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 12171 RESUME_RED_LIMITf, rqlen - 1); 12172 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 12173 RESUME_YELLOW_LIMITf, rqlen - 1); 12174 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 12175 idx, rval)); 12176 } 12177 12178 /* Device level config setting */ 12179 if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) { 12180 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 12181 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 12182 UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1); 12183 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 12184 } 12185 } 12186 return SOC_E_NONE; 12187 } 12188 12189 STATIC int 12190 _soc_monterey_mmu_config_shared_update_check(int unit, int val1, int val2, int flags) 12191 { 12192 int rv = 0; 12193 if (flags == 1) { 12194 if (val1 > val2) { 12195 rv = 1; 12196 } 12197 } else { 12198 if (val1 < val2) { 12199 rv = 1; 12200 } 12201 } 12202 return rv; 12203 } 12204 12205 int 12206 soc_monterey_mmu_config_shared_buf_recalc(int unit, uint32 spid, int shared_size, int flags) 12207 { 12208 soc_info_t *si; 12209 soc_mem_t mem, mem2; 12210 soc_reg_t reg = INVALIDr; 12211 soc_field_t field = INVALIDf; 12212 uint32 rval, rval2; 12213 uint32 entry0[SOC_MAX_MEM_WORDS]; 12214 thdi_port_pg_config_entry_t pg_config_mem; 12215 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 12216 int port, base, qbase, numq, idx; 12217 int cur_limit, midx, index1; 12218 int granularity; 12219 uint16 dev_id; 12220 uint8 rev_id; 12221 12222 static const soc_field_t pg_spid_field[] = { 12223 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 12224 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 12225 }; 12226 12227 if (spid >= _MONTEREY_MMU_NUM_POOL) { 12228 return SOC_E_PARAM; 12229 } 12230 12231 soc_cm_get_id(unit, &dev_id, &rev_id); 12232 12233 si = &SOC_INFO(unit); 12234 12235 /* per service pool settings */ 12236 idx = spid; 12237 rval = 0; 12238 reg = MMU_THDM_DB_POOL_SHARED_LIMITr; 12239 field = SHARED_LIMITf; 12240 granularity = 1; 12241 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12242 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12243 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12244 soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 12245 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12246 } 12247 12248 rval = 0; 12249 reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr; 12250 field = YELLOW_SHARED_LIMITf; 12251 granularity = 8; 12252 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12253 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12254 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12255 soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 12256 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12257 } 12258 12259 rval = 0; 12260 reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr; 12261 field = RED_SHARED_LIMITf; 12262 granularity = 8; 12263 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12264 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12265 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12266 soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 12267 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12268 } 12269 12270 /* configure Q-groups */ 12271 mem = MMU_THDU_XPIPE_CONFIG_QGROUPm; 12272 for (idx = 0; idx < SOC_MONTEREY_MMU_CFG_QGROUP_MAX; idx++) { 12273 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 12274 12275 SOC_IF_ERROR_RETURN 12276 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12277 12278 field = Q_SHARED_LIMIT_CELLf; 12279 granularity = 1; 12280 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) { 12281 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12282 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12283 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12284 field, shared_size/granularity); 12285 } 12286 } 12287 12288 granularity = 8; 12289 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, 12290 Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 12291 field = LIMIT_RED_CELLf; 12292 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12293 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12294 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12295 field, shared_size/granularity); 12296 } 12297 12298 field = LIMIT_YELLOW_CELLf; 12299 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12300 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12301 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12302 field, shared_size/granularity); 12303 } 12304 } 12305 12306 SOC_IF_ERROR_RETURN 12307 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12308 12309 } 12310 12311 /* Input port per port settings */ 12312 PBMP_ALL_ITER(unit, port) { 12313 rval = 0; 12314 /* Input port per port per priority group settings */ 12315 mem = THDI_PORT_PG_CONFIG_Xm; 12316 field = PG_SHARED_LIMITf; 12317 granularity = 1; 12318 for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) { 12319 SOC_IF_ERROR_RETURN(READ_THDI_PORT_PG_SPIDr(unit, port, &rval)); 12320 if (spid != soc_reg_field_get(unit, THDI_PORT_PG_SPIDr, rval, 12321 pg_spid_field[idx])){ 12322 continue; 12323 } 12324 midx = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12325 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 12326 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 12327 MEM_BLOCK_ALL, midx, &pg_config_mem)); 12328 if (!soc_mem_field32_get(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf)) { 12329 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, field); 12330 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12331 soc_mem_field32_set(unit, mem, &pg_config_mem, 12332 field, shared_size/granularity); 12333 } 12334 } 12335 12336 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 12337 MEM_BLOCK_ALL, midx, &pg_config_mem)); 12338 } 12339 } 12340 12341 /*********************************** 12342 * THDO 12343 */ 12344 /* Output port per port per queue setting for regular multicast queue */ 12345 PBMP_PORT_ITER(unit, port) { 12346 12347 numq = si->port_num_cosq[port]; 12348 qbase = si->port_cosq_base[port]; 12349 if (numq == 0) { 12350 continue; 12351 } 12352 12353 mem = MMU_THDM_DB_QUEUE_CONFIG_0m; 12354 base = soc_monterey_l2_hw_index(unit, qbase, 0) - _MONTEREY_MC_QUEUE_BASE; 12355 12356 for (idx = 0; idx < numq; idx++) { 12357 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 12358 12359 SOC_IF_ERROR_RETURN 12360 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12361 12362 if (spid != soc_mem_field32_get(unit, mem, entry0, Q_SPIDf)){ 12363 continue; 12364 } 12365 field = Q_SHARED_LIMITf; 12366 granularity = 1; 12367 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 12368 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12369 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12370 soc_mem_field32_set(unit, mem, entry0, 12371 field, shared_size/granularity); 12372 } 12373 } 12374 12375 granularity = 8; 12376 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 12377 field = YELLOW_SHARED_LIMITf; 12378 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12379 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12380 soc_mem_field32_set(unit, mem, entry0, 12381 field, shared_size/granularity); 12382 } 12383 field = RED_SHARED_LIMITf; 12384 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12385 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12386 soc_mem_field32_set(unit, mem, entry0, 12387 field, shared_size/granularity); 12388 } 12389 } 12390 SOC_IF_ERROR_RETURN 12391 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 12392 entry0)); 12393 } 12394 12395 /* Per port per pool */ 12396 idx = spid; 12397 mem = MMU_THDM_DB_PORTSP_CONFIG_0m; 12398 index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12399 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t)); 12400 12401 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 12402 index1, entry0)); 12403 12404 field = SHARED_LIMITf; 12405 granularity = 1; 12406 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12407 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12408 soc_mem_field32_set(unit, mem, entry0, 12409 field, shared_size/granularity); 12410 } 12411 12412 field = RED_SHARED_LIMITf; 12413 granularity = 8; 12414 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12415 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12416 soc_mem_field32_set(unit, mem, entry0, 12417 field, shared_size/granularity); 12418 } 12419 12420 field = YELLOW_SHARED_LIMITf; 12421 granularity = 8; 12422 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12423 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12424 soc_mem_field32_set(unit, mem, entry0, 12425 field, shared_size/granularity); 12426 } 12427 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 12428 index1, entry0)); 12429 } 12430 12431 /* Output port per port per queue setting for regular unicast queue */ 12432 PBMP_PORT_ITER(unit, port) { 12433 /* per port regular unicast queue */ 12434 numq = si->port_num_uc_cosq[port]; 12435 qbase = si->port_uc_cosq_base[port]; 12436 12437 if (numq == 0) { 12438 continue; 12439 } 12440 base = soc_monterey_l2_hw_index(unit, qbase, 1); 12441 mem = MMU_THDU_XPIPE_CONFIG_QUEUEm; 12442 mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm; 12443 for (idx = 0; idx < numq; idx++) { 12444 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_q_to_qgrp_map_entry_t)); 12445 SOC_IF_ERROR_RETURN 12446 (soc_mem_read(unit, mem2, MEM_BLOCK_ALL, base+idx, entry0)); 12447 if (spid != soc_mem_field32_get(unit, mem2, entry0, Q_SPIDf)){ 12448 continue; 12449 } 12450 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t)); 12451 12452 SOC_IF_ERROR_RETURN 12453 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12454 12455 field = Q_SHARED_LIMIT_CELLf; 12456 granularity = 1; 12457 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) { 12458 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12459 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12460 soc_mem_field32_set(unit, mem, entry0, 12461 field, shared_size/granularity); 12462 } 12463 } 12464 12465 granularity = 8; 12466 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 12467 field = LIMIT_YELLOW_CELLf; 12468 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12469 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12470 soc_mem_field32_set(unit, mem, entry0, 12471 field, shared_size/granularity); 12472 } 12473 field = LIMIT_RED_CELLf; 12474 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12475 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12476 soc_mem_field32_set(unit, mem, entry0, 12477 field, shared_size/granularity); 12478 } 12479 } 12480 SOC_IF_ERROR_RETURN 12481 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12482 } 12483 12484 /* Per port per pool unicast */ 12485 idx = spid; 12486 mem = MMU_THDU_XPIPE_CONFIG_PORTm; 12487 index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12488 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t)); 12489 12490 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 12491 index1, entry0)); 12492 12493 field = SHARED_LIMITf; 12494 granularity = 1; 12495 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12496 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12497 soc_mem_field32_set(unit, mem, entry0, 12498 field, shared_size/granularity); 12499 } 12500 12501 granularity = 8; 12502 field = YELLOW_LIMITf; 12503 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12504 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12505 soc_mem_field32_set(unit, mem, entry0, 12506 field, shared_size/granularity); 12507 } 12508 field = RED_LIMITf; 12509 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12510 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12511 soc_mem_field32_set(unit, mem, entry0, 12512 field, shared_size/granularity); 12513 } 12514 12515 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 12516 index1, entry0)); 12517 } 12518 12519 /* RQE */ 12520 for (idx = 0; idx < 11; idx++) { 12521 rval = 0; 12522 rval2 = 0; 12523 12524 SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval)); 12525 if (spid != soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, SPIDf)){ 12526 continue; 12527 } 12528 12529 reg = MMU_THDR_DB_CONFIG_PRIQr; 12530 field = SHARED_LIMITf; 12531 granularity = 1; 12532 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 12533 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 12534 DYNAMIC_ENABLEf)) { 12535 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 12536 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12537 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 12538 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 12539 } 12540 } 12541 12542 rval2 = 0; 12543 reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr; 12544 granularity = 8; 12545 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 12546 12547 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 12548 COLOR_LIMIT_DYNAMICf)) { 12549 field = SHARED_RED_LIMITf; 12550 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 12551 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12552 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 12553 } 12554 12555 field = SHARED_YELLOW_LIMITf; 12556 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 12557 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12558 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 12559 } 12560 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 12561 } 12562 12563 } 12564 12565 /* per pool RQE settings */ 12566 idx = spid; 12567 reg = MMU_THDR_DB_CONFIG_SPr; 12568 field = SHARED_LIMITf; 12569 granularity = 1; 12570 12571 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 12572 12573 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12574 12575 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12576 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 12577 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 12578 } 12579 12580 reg = MMU_THDR_DB_SP_SHARED_LIMITr; 12581 granularity = 8; 12582 12583 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 12584 12585 field =SHARED_YELLOW_LIMITf; 12586 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12587 12588 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){ 12589 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 12590 } 12591 12592 field = SHARED_RED_LIMITf; 12593 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12594 12595 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){ 12596 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 12597 } 12598 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 12599 return SOC_E_NONE; 12600 } 12601 12602 int 12603 soc_monterey_mmu_config_init(int unit, int test_only, soc_port_t port) 12604 { 12605 int rv, tport; 12606 int lossless; 12607 _soc_mmu_cfg_buf_t *buf; 12608 _soc_mmu_device_info_t devcfg; 12609 soc_info_t *si; 12610 12611 buf = soc_mmu_cfg_alloc(unit); 12612 if (!buf) { 12613 return SOC_E_MEMORY; 12614 } 12615 si = &SOC_INFO(unit); 12616 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 12617 12618 _soc_monterey_mmu_init_dev_config(unit, &devcfg, lossless); 12619 _soc_monterey_mmu_config_buf_default(unit, buf, &devcfg, lossless); 12620 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 12621 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 12622 } 12623 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 12624 if (!test_only) { 12625 if (SOC_FAILURE(rv)) { 12626 LOG_VERBOSE(BSL_LS_SOC_COMMON, 12627 (BSL_META_U(unit, 12628 "MMU config: Use default setting\n"))); 12629 _soc_monterey_mmu_config_buf_default(unit, buf, &devcfg, lossless); 12630 _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg); 12631 PBMP_ALL_ITER(unit, tport) { 12632 buf->pools[0].mcq_entry_reserved += (si->port_num_cosq[tport] * 12633 _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD); 12634 } 12635 } 12636 PBMP_ALL_ITER(unit, tport) { 12637 buf->pools[0].mcq_entry_reserved += (si->port_num_cosq[tport] * 12638 _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD); 12639 } 12640 rv = _soc_monterey_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, port); 12641 } 12642 12643 soc_mmu_cfg_free(unit, buf); 12644 12645 LOG_VERBOSE(BSL_LS_SOC_COMMON, 12646 (BSL_META_U(unit, 12647 "MMU THDI/THDO init done\n"))); 12648 return rv; 12649 } 12650 12651 STATIC int 12652 _soc_monterey_mmu_init(int unit) 12653 { 12654 uint32 rval; 12655 uint64 rval64; 12656 soc_info_t *si; 12657 int total_entries, clock_period, refresh_time_val; 12658 int cpu_slots; 12659 int msbus_idle_enable; 12660 int alloc_size; 12661 int port = 0; 12662 12663 12664 /*Monterey has fixed 12Mb can not override through OTP */ 12665 _soc_mn_skew_index = 0; 12666 12667 /* MMU Settings Configuration */ 12668 12669 SOC_IF_ERROR_RETURN(soc_monterey_mmu_config_init(unit, 0 /* for testing SAL_BOOT_BCMSIM */, -1)); 12670 /* Enable IP to CMICM credit transfer */ 12671 rval = 0; 12672 soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval, 12673 TRANSFER_ENABLEf, 1); 12674 soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval, 12675 NUM_OF_CREDITSf, 32); 12676 SOC_IF_ERROR_RETURN(WRITE_IP_TO_CMICM_CREDIT_TRANSFERr(unit, rval)); 12677 COMPILER_64_ZERO(rval64); 12678 rval = 0; 12679 SOC_IF_ERROR_RETURN( 12680 READ_VBS_FC_CONFIGr(unit, &rval)); 12681 soc_reg_field_set(unit, VBS_FC_CONFIGr, &rval, 12682 FORCE_COSMASK_51_48f , 3); 12683 SOC_IF_ERROR_RETURN(WRITE_VBS_FC_CONFIGr(unit, rval)); 12684 12685 rval = 0; 12686 SOC_IF_ERROR_RETURN( 12687 READ_TOQ_STATUSr(unit, &rval)); 12688 soc_reg_field_set(unit, TOQ_STATUSr, &rval, 12689 FORCE_INIT_DONEf, 1); 12690 SOC_IF_ERROR_RETURN(WRITE_TOQ_STATUSr(unit, rval)); 12691 12692 if (_fwd_ctrl_lock[unit] == NULL) { 12693 _fwd_ctrl_lock[unit] = sal_mutex_create("_fwd_ctrl_lock"); 12694 } 12695 12696 if (_fwd_ctrl_lock[unit] == NULL) { 12697 return SOC_E_MEMORY; 12698 } 12699 12700 /*mmu traffic control*/ 12701 alloc_size = sizeof(_soc_monterey_mmu_traffic_ctrl_t); 12702 if (_soc_monterey_mmu_traffic_ctrl[unit] == NULL) { 12703 _soc_monterey_mmu_traffic_ctrl[unit] = 12704 sal_alloc(alloc_size,"_soc_monterey_mmu_traffic_ctrl"); 12705 if (_soc_monterey_mmu_traffic_ctrl[unit] == NULL) { 12706 return SOC_E_MEMORY; 12707 } 12708 } 12709 sal_memset(_soc_monterey_mmu_traffic_ctrl[unit], 0, alloc_size); 12710 12711 12712 /* Enable all ports */ 12713 PBMP_ALL_ITER(unit, port) 12714 { 12715 if (IS_CPU_PORT(unit, port) || 12716 IS_MN_HSP_PORT(unit,port) || 12717 IS_MACSEC_PORT(unit,port) || 12718 IS_LB_PORT(unit, port)) 12719 { _soc_monterey_thdo_hw_set(unit, port, 1); 12720 12721 } 12722 } 12723 si = &SOC_INFO(unit); 12724 12725 /* 12726 * Refresh Value = 12727 * ((total no of entities to be refreshed) X Core clk period in ns)/Wred tick period 50 ns 12728 */ 12729 12730 total_entries = 4096 + 1024; 12731 cpu_slots = (total_entries * 2) / 16; /* 2 slots for every 16 entries refreshed */ 12732 clock_period = (1 * 1000 * 1000) / si->frequency; /*clock period in microseconds */ 12733 12734 SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval)); 12735 msbus_idle_enable = soc_reg_field_get(unit, WRED_REFRESH_CONTROLr, 12736 rval, MSBUS_IDLE_ENABLEf); 12737 12738 if (msbus_idle_enable) { 12739 refresh_time_val = ((total_entries + cpu_slots) * clock_period) / 50; 12740 } else { 12741 refresh_time_val = (total_entries * clock_period) / 50; 12742 } 12743 refresh_time_val = refresh_time_val / 1000; /* micro to nano seconds */ 12744 12745 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 12746 REFRESH_TIME_VALf, refresh_time_val); 12747 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 12748 REFRESH_DISABLEf, 0); 12749 SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval)); 12750 12751 PBMP_ALL_ITER(unit, port) { 12752 if (IS_CPU_PORT(unit, port) || 12753 IS_LB_PORT(unit, port)) 12754 { 12755 continue; 12756 } 12757 COMPILER_64_ZERO(rval64); 12758 soc_reg64_field32_set(unit, INTFO_CONGST_STr, &rval64, ENf, 1); 12759 SOC_IF_ERROR_RETURN(WRITE_INTFO_CONGST_STr(unit, port, rval64)); 12760 rval = 0; 12761 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12762 COS0_E2E_DS_ENf , 1); 12763 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12764 COS1_E2E_DS_ENf , 1); 12765 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12766 COS2_E2E_DS_ENf , 1); 12767 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12768 COS3_E2E_DS_ENf , 1); 12769 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12770 COS4_E2E_DS_ENf , 1); 12771 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12772 COS5_E2E_DS_ENf , 1); 12773 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12774 COS6_E2E_DS_ENf , 1); 12775 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 12776 COS7_E2E_DS_ENf , 1); 12777 WRITE_THDU_PORT_E2ECC_COS_SPIDr(unit , port , rval); 12778 } 12779 12780 /* update port_init_speed array for all ports */ 12781 SOC_IF_ERROR_RETURN(_soc_mn_ports_speed_init_update(unit)); 12782 12783 return SOC_E_NONE; 12784 } 12785 12786 12787 STATIC int 12788 _soc_monterey_age_timer_get(int unit, int *age_seconds, int *enabled) 12789 { 12790 soc_control_t *soc = SOC_CONTROL(unit); 12791 uint32 rval; 12792 12793 if (!soc->l2x_sw_aging) { 12794 SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval)); 12795 *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf); 12796 *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf); 12797 } else { 12798 *enabled = soc->l2x_age_pid != SAL_THREAD_ERROR && 12799 soc->l2x_age_enable ? 12800 1 : 0; 12801 *age_seconds = soc->l2x_age_pid != SAL_THREAD_ERROR && 12802 soc->l2x_age_enable ? 12803 soc->l2x_age_interval : 0; 12804 } 12805 12806 return SOC_E_NONE; 12807 } 12808 12809 STATIC int 12810 _soc_monterey_age_timer_max_get(int unit, int *max_seconds) 12811 { 12812 soc_control_t *soc = SOC_CONTROL(unit); 12813 12814 if (!soc->l2x_sw_aging) { 12815 *max_seconds = 12816 soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf); 12817 } else { 12818 *max_seconds = 0x7fffffff; 12819 } 12820 12821 return SOC_E_NONE; 12822 } 12823 12824 STATIC int 12825 _soc_monterey_age_timer_set(int unit, int age_seconds, int enable) 12826 { 12827 soc_control_t *soc = SOC_CONTROL(unit); 12828 sal_usecs_t interval = soc->l2x_age_interval; 12829 uint32 rval = 0; 12830 12831 if (!soc->l2x_sw_aging) { 12832 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable); 12833 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds); 12834 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval)); 12835 } else if (soc->l2x_age_interval) { 12836 if (!enable) { 12837 soc->l2x_age_enable = 0; 12838 } else { 12839 if (age_seconds) { 12840 SOC_CONTROL_LOCK(unit); 12841 soc->l2x_age_interval = age_seconds; 12842 SOC_CONTROL_UNLOCK(unit); 12843 } 12844 soc->l2x_age_enable = 1; 12845 if (interval != age_seconds) { 12846 sal_sem_give(soc->l2x_age_notify); 12847 } 12848 } 12849 } else { 12850 if (enable) { 12851 SOC_IF_ERROR_RETURN 12852 (soc_td2_l2_bulk_age_start(unit, age_seconds)); 12853 } 12854 } 12855 12856 return SOC_E_NONE; 12857 } 12858 12859 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 12860 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 12861 12862 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 12863 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 12864 12865 STATIC int 12866 _soc_monterey_mdio_addr_to_port(uint32 phy_addr) 12867 { 12868 int bus, offset = 0; 12869 int mdio_addr = (phy_addr & 0x1f); 12870 12871 /* Must be internal MDIO address */ 12872 if ((phy_addr & 0x80) == 0) { 12873 return 0; 12874 } 12875 12876 bus = PHY_ID_BUS_NUM(phy_addr); 12877 if (bus > 2) { 12878 return 0; 12879 } 12880 12881 switch (bus) { 12882 case 0: offset = (mdio_addr < 0xd)? 0 : 40; break; 12883 case 1: offset = (mdio_addr < 0x9)? 12 : 36; break; 12884 case 2: offset = 20; break; 12885 } 12886 12887 return (mdio_addr + offset); 12888 } 12889 12890 STATIC int 12891 _soc_monterey_mdio_reg_read(int unit, uint32 phy_addr, 12892 uint32 phy_reg, uint32 *phy_data) 12893 { 12894 int port, phy_port, blk; 12895 soc_mem_t ucmem_data; 12896 soc_reg_t ucmem_ctrl; 12897 12898 /* Physical port based on MDIO address */ 12899 phy_port = _soc_monterey_mdio_addr_to_port(phy_addr); 12900 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 12901 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,0); 12902 if ((((phy_port > 0) && (phy_port < 13)) || 12903 ((phy_port > 52) && (phy_port < 65))) 12904 && !(IS_CPRI_PORT(unit, port))) { 12905 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1); 12906 } 12907 12908 if (soc_monterey_port_is_falcon(unit, phy_port)) { 12909 if ((((phy_port > 0) && (phy_port < 13)) || 12910 ((phy_port > 52) && (phy_port < 65))) 12911 && (IS_CPRI_PORT(unit, port))) { 12912 ucmem_data = CPMPORT_WC_UCMEM_DATAm; 12913 ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr; 12914 } else { 12915 ucmem_data = CLPORT_WC_UCMEM_DATAm; 12916 ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr; 12917 } 12918 } else { 12919 ucmem_data = XLPORT_WC_UCMEM_DATAm; 12920 ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr; 12921 } 12922 12923 LOG_INFO(BSL_LS_SOC_MII, 12924 (BSL_META_U(unit, 12925 "soc_monterey_mdio_reg_read[%d]: %d/%d/%d\n"), 12926 unit, phy_addr, phy_port, port)); 12927 12928 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 12929 12930 /* Call common S-bus MDIO read function */ 12931 return soc_sbus_mdio_reg_read(unit, port, blk, 0, 12932 phy_addr, phy_reg, phy_data, 12933 ucmem_data, ucmem_ctrl); 12934 12935 } 12936 12937 STATIC int 12938 _soc_monterey_mdio_reg_write(int unit, uint32 phy_addr, 12939 uint32 phy_reg, uint32 phy_data) 12940 { 12941 int port, phy_port, blk; 12942 soc_mem_t ucmem_data; 12943 soc_reg_t ucmem_ctrl; 12944 12945 /* Physical port based on MDIO address */ 12946 phy_port = _soc_monterey_mdio_addr_to_port(phy_addr); 12947 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 12948 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,0); 12949 if ((((phy_port > 0) && (phy_port < 13)) || 12950 ((phy_port > 52) && (phy_port < 65))) 12951 && !(IS_CPRI_PORT(unit, port))) { 12952 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1); 12953 } 12954 12955 if (soc_monterey_port_is_falcon(unit, phy_port)) { 12956 if ((((phy_port > 0) && (phy_port < 13)) || 12957 ((phy_port > 52) && (phy_port < 65))) 12958 && (IS_CPRI_PORT(unit, port))) { 12959 ucmem_data = CPMPORT_WC_UCMEM_DATAm; 12960 ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr; 12961 } else { 12962 ucmem_data = CLPORT_WC_UCMEM_DATAm; 12963 ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr; 12964 } 12965 } else { 12966 ucmem_data = XLPORT_WC_UCMEM_DATAm; 12967 ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr; 12968 } 12969 12970 LOG_INFO(BSL_LS_SOC_MII, 12971 (BSL_META_U(unit, 12972 "soc_monterey_mdio_reg_read[%d]: %d/%d/%d\n"), 12973 unit, phy_addr, phy_port, port)); 12974 12975 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 12976 12977 12978 /* Call common S-bus MDIO read function */ 12979 return soc_sbus_mdio_reg_write(unit, port, blk, 0, 12980 phy_addr, phy_reg, phy_data, 12981 ucmem_data, ucmem_ctrl); 12982 } 12983 12984 static const soc_reg_t pvtmon_result_reg[] = { 12985 TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r, 12986 TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r, 12987 TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r, 12988 TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r, 12989 }; 12990 12991 12992 STATIC void 12993 soc_monterey_temperature_intr(int unit) 12994 { 12995 uint32 rval, trval; 12996 int i, rv; 12997 soc_port_t port; 12998 soc_block_t blk; 12999 soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLOCK_TYPE_INVALID}; 13000 soc_block_t clport_blocks[] = {SOC_BLK_CLPORT, SOC_BLOCK_TYPE_INVALID}; 13001 13002 /* Raise event to app for it to take further graceful actions */ 13003 for (i = 0; i < COUNTOF(pvtmon_result_reg); i++) { 13004 if ((0x1 << i) & _soc_mn_temp_mon_mask[unit]) { 13005 if ((rv = soc_reg32_get(unit, pvtmon_result_reg[i], REG_PORT_ANY, 0, 13006 &trval)) != SOC_E_NONE) { 13007 LOG_ERROR(BSL_LS_SOC_COMMON, 13008 (BSL_META_U(unit, 13009 "MN Top Intr, Reg access error.\n"))); 13010 } 13011 trval = soc_reg_field_get(unit, pvtmon_result_reg[i], trval, 13012 PVT_DATAf); 13013 /* Convert data to temperature. 13014 * temp = 410.04-(data*0.48705) = (410040-(data*487))/1000 13015 * Note: Since this is a high temp interrupt we can safely assume 13016 * that this will end up being a +ive value. 13017 */ 13018 trval = (410040-(trval*487))/1000; 13019 LOG_ERROR(BSL_LS_SOC_COMMON, 13020 (BSL_META_U(unit, 13021 "TempMon %d: %d deg C.\n"), i, trval)); 13022 (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM, 13023 SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval); 13024 } 13025 } 13026 13027 /* Optionally hold system in reset. 13028 * Note: The main intention is to stop the chip from getting fried and halt 13029 * all schan accesses as the h/w will not respond anymore. 13030 * We are not implementing a gracefull recovery, the unit needs to be 13031 * rebooted after this. 13032 */ 13033 if (soc_property_get(unit, "temp_monitor_shutdown", 1)) { 13034 if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) { 13035 LOG_ERROR(BSL_LS_SOC_COMMON, 13036 (BSL_META_U(unit, 13037 "MN Temp Intr, Reg access error.\n"))); 13038 } 13039 13040 /* Stop all schan transactions on this unit */ 13041 #ifdef INCLUDE_I2C 13042 if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) { 13043 LOG_ERROR(BSL_LS_SOC_COMMON, 13044 (BSL_META_U(unit, 13045 "MN Temp Intr, i2c detach error.\n"))); 13046 } 13047 #endif 13048 if (!SOC_IS_RCPU_ONLY(unit)) { 13049 /* Free up DMA memory */ 13050 if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) { 13051 LOG_ERROR(BSL_LS_SOC_COMMON, 13052 (BSL_META_U(unit, 13053 "MN Temp Intr, dma detach error.\n"))); 13054 } 13055 } 13056 #ifdef INCLUDE_MEM_SCAN 13057 if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) { 13058 LOG_ERROR(BSL_LS_SOC_COMMON, 13059 (BSL_META_U(unit, 13060 "MN Temp Intr, mem scan stop error.\n"))); 13061 } 13062 #endif /* INCLUDE_MEM_SCAN */ 13063 /* Terminate counter module */ 13064 if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) { 13065 LOG_ERROR(BSL_LS_SOC_COMMON, 13066 (BSL_META_U(unit, 13067 "MN Temp Intr, counter stop error.\n"))); 13068 } 13069 if (SOC_SBUSDMA_DM_INFO(unit)) { 13070 if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) { 13071 LOG_ERROR(BSL_LS_SOC_COMMON, 13072 (BSL_META_U(unit, 13073 "MN Temp Intr, sbusdma stop error.\n"))); 13074 } 13075 } 13076 if (soc_feature(unit, soc_feature_arl_hashed)) { 13077 /* Stop L2X thread */ 13078 if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) { 13079 LOG_ERROR(BSL_LS_SOC_COMMON, 13080 (BSL_META_U(unit, 13081 "MN Temp Intr, L2x stop error.\n"))); 13082 } 13083 13084 } 13085 13086 rv = READ_TOP_SOFT_RESET_REGr(unit, &rval); 13087 if (SOC_E_NONE != rv) { 13088 LOG_ERROR(BSL_LS_SOC_COMMON, 13089 (BSL_META_U(unit, 13090 "MN Temp Intr, Reg access error.\n"))); 13091 } 13092 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 0); 13093 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0); 13094 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 0); 13095 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 0); 13096 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_RDB_RST_Lf, 0); 13097 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 0); 13098 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 0); 13099 rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval); 13100 if (SOC_E_NONE != rv) { 13101 LOG_ERROR(BSL_LS_SOC_COMMON, 13102 (BSL_META_U(unit, 13103 "MN Temp Intr, Reg access error.\n"))); 13104 } 13105 13106 if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) { 13107 LOG_ERROR(BSL_LS_SOC_COMMON, 13108 (BSL_META_U(unit, 13109 "MN Temp Intr, Reg access error.\n"))); 13110 } 13111 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf, 13112 0); 13113 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf, 13114 0); 13115 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL2_RST_Lf, 13116 0); 13117 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL3_RST_Lf, 13118 0); 13119 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 13120 1); 13121 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf, 13122 0); 13123 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf, 13124 0); 13125 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 13126 if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) { 13127 LOG_ERROR(BSL_LS_SOC_COMMON, 13128 (BSL_META_U(unit, 13129 "MN Temp Intr, Reg access error.\n"))); 13130 } 13131 /* Powerdown Falcon analog cores */ 13132 SOC_BLOCKS_ITER(unit, blk, clport_blocks) { 13133 port = SOC_BLOCK_PORT(unit, blk); 13134 rv = READ_CLPORT_XGXS0_CTRL_REGr(unit, port, &rval); 13135 if (SOC_E_NONE != rv) { 13136 LOG_ERROR(BSL_LS_SOC_COMMON, 13137 (BSL_META_U(unit, 13138 "MN Temp Intr, Reg access error.\n"))); 13139 } 13140 soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1); 13141 soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1); 13142 soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0); 13143 rv = WRITE_CLPORT_XGXS0_CTRL_REGr(unit, port, rval); 13144 if (SOC_E_NONE != rv) { 13145 LOG_ERROR(BSL_LS_SOC_COMMON, 13146 (BSL_META_U(unit, 13147 "MN Temp Intr, Reg access error.\n"))); 13148 } 13149 } 13150 /* Powerdown Eagle analog cores */ 13151 SOC_BLOCKS_ITER(unit, blk, xlport_blocks) { 13152 port = SOC_BLOCK_PORT(unit, blk); 13153 rv = READ_XLPORT_XGXS0_CTRL_REGr(unit, port, &rval); 13154 if (SOC_E_NONE != rv) { 13155 LOG_ERROR(BSL_LS_SOC_COMMON, 13156 (BSL_META_U(unit, 13157 "MN Temp Intr, Reg access error.\n"))); 13158 } 13159 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1); 13160 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1); 13161 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0); 13162 rv = WRITE_XLPORT_XGXS0_CTRL_REGr(unit, port, rval); 13163 if (SOC_E_NONE != rv) { 13164 LOG_ERROR(BSL_LS_SOC_COMMON, 13165 (BSL_META_U(unit, 13166 "MN Temp Intr, Reg access error.\n"))); 13167 } 13168 } 13169 13170 /* Disable all interrupts */ 13171 soc_cmicm_intr0_disable(unit, ~0); 13172 soc_cmicm_intr1_disable(unit, ~0); 13173 soc_cmicm_intr2_disable(unit, ~0); 13174 soc_cmicm_intr3_disable(unit, ~0); 13175 soc_cmicm_intr4_disable(unit, ~0); 13176 soc_cmicm_intr5_disable(unit, ~0); 13177 13178 /* Power down core PLL, once this is done all SCHAN accesses 13179 * will fail. 13180 */ 13181 rv = READ_TOP_CORE_PLL_CTRL_1r(unit, &rval); 13182 if (SOC_E_NONE != rv) { 13183 LOG_ERROR(BSL_LS_SOC_COMMON, 13184 (BSL_META_U(unit, 13185 "MN Temp Intr, Reg access error.\n"))); 13186 } 13187 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, ISO_INf, 1); 13188 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRONf, 0); 13189 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRON_LDOf, 0); 13190 WRITE_TOP_CORE_PLL_CTRL_1r(unit, rval); 13191 SCHAN_LOCK(unit); 13192 13193 /* Clear all outstanding DPCs owned by this unit */ 13194 sal_dpc_cancel(INT_TO_PTR(unit)); 13195 LOG_ERROR(BSL_LS_SOC_COMMON, 13196 (BSL_META_U(unit, 13197 "\nReboot the system.."))); 13198 } 13199 } 13200 13201 13202 void 13203 soc_monterey_top_intr(void *unit_vp, void *d1, void *d2, 13204 void *d3, void *d4) 13205 { 13206 uint32 rval, pvtrval; 13207 int rv, unit = PTR_TO_INT(unit_vp); 13208 13209 if ((rv = READ_TOP_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) { 13210 LOG_ERROR(BSL_LS_SOC_COMMON, 13211 (BSL_META_U(unit, 13212 "MN TOP Intr, Reg access error.\n"))); 13213 } 13214 13215 /* Bits 0-17 for PVTMON and rest for AVS */ 13216 pvtrval = rval & ((1 << 18) - 1); 13217 if (pvtrval) { 13218 LOG_ERROR(BSL_LS_SOC_COMMON, 13219 (BSL_META_U(unit, 13220 "High temp interrupt: 0x%08x\n"), rval)); 13221 13222 soc_monterey_temperature_intr(unit); 13223 return; 13224 } 13225 13226 13227 13228 return; 13229 } 13230 13231 int 13232 soc_monterey_temperature_monitor_get(int unit, 13233 int temperature_max, 13234 soc_switch_temperature_monitor_t *temperature_array, 13235 int *temperature_count) 13236 { 13237 soc_reg_t reg; 13238 int index; 13239 uint32 rval; 13240 int fval, cur, peak,valid = 0 ,done = 0; 13241 int num_entries_out; 13242 soc_timeout_t to; 13243 13244 if (temperature_count) { 13245 *temperature_count = 0; 13246 } 13247 if (COUNTOF(pvtmon_result_reg) > temperature_max) { 13248 num_entries_out = temperature_max; 13249 } else { 13250 num_entries_out = COUNTOF(pvtmon_result_reg); 13251 } 13252 13253 13254 SOC_IF_ERROR_RETURN 13255 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13256 PVTMON_SELECTf, 0)); 13257 /* Sequence for AVS PVTMON measurements starts here 13258 * Needed before reading Monitor #8: TOP_PVTMON_RESULT_8 13259 */ 13260 /* Stop on going measurements */ 13261 SOC_IF_ERROR_RETURN 13262 (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_SEQUENCER_INITr, REG_PORT_ANY, 13263 SEQUENCER_INITf, 1)); 13264 /* Clear all measurements */ 13265 SOC_IF_ERROR_RETURN 13266 (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, REG_PORT_ANY, 13267 M_INIT_PVT_MNTRf, 0xff)); 13268 SOC_IF_ERROR_RETURN 13269 (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, REG_PORT_ANY, 13270 M_INIT_PVT_MNTRf, 0x0)); 13271 13272 /* Restart measurements */ 13273 SOC_IF_ERROR_RETURN 13274 (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_SEQUENCER_INITr, REG_PORT_ANY, 13275 SEQUENCER_INITf, 0)); 13276 13277 soc_timeout_init(&to, 1500, 1); 13278 /* Poll until valid bit is set */ 13279 for (;;) { 13280 SOC_IF_ERROR_RETURN(READ_AVS_REG_RO_REGISTERS_0_PVT_TEMPERATURE_MNTR_STATUSr(unit, 13281 &rval)); 13282 valid = soc_reg_field_get(unit, AVS_REG_RO_REGISTERS_0_PVT_TEMPERATURE_MNTR_STATUSr, 13283 rval, VALID_DATAf); 13284 done = soc_reg_field_get(unit, AVS_REG_RO_REGISTERS_0_PVT_TEMPERATURE_MNTR_STATUSr, 13285 rval, DONEf); 13286 if (valid && done) { 13287 break; 13288 } 13289 if (soc_timeout_check(&to)) { 13290 LOG_ERROR(BSL_LS_SOC_DIAG, 13291 (BSL_META_U(unit, "AVS Temperature Monitor: Timeout\n"))); 13292 return SOC_E_INTERNAL; 13293 } 13294 } 13295 13296 /* Sequence for AVS PVTMON measurements end here */ 13297 SOC_IF_ERROR_RETURN 13298 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13299 PVTMON_ADC_RESETBf, 1)); 13300 SOC_IF_ERROR_RETURN 13301 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13302 PVTMON_ADC_RESETBf, 0)); 13303 SOC_IF_ERROR_RETURN 13304 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13305 PVTMON_ADC_RESETBf, 1)); 13306 13307 13308 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 13309 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13310 TOP_PVT_MON_MAX_RST_Lf, 1); 13311 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13312 TOP_PVT_MON_MIN_RST_Lf, 1); 13313 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13314 13315 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13316 TOP_PVT_MON_MAX_RST_Lf, 0); 13317 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13318 TOP_PVT_MON_MIN_RST_Lf, 0); 13319 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13320 13321 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13322 TOP_PVT_MON_MAX_RST_Lf, 1); 13323 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13324 TOP_PVT_MON_MIN_RST_Lf, 1); 13325 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13326 sal_usleep(1000); 13327 13328 for (index = 0; index < num_entries_out; index++) { 13329 reg = pvtmon_result_reg[index]; 13330 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13331 13332 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13333 cur = (4100400 - (4870 * fval)) / 1000; 13334 fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf); 13335 peak = (4100400 - (4870 * fval)) / 1000; 13336 (temperature_array + index)->curr = cur; 13337 (temperature_array + index)->peak = peak; 13338 } 13339 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 13340 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13341 TOP_PVT_MON_MAX_RST_Lf, 0); 13342 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13343 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13344 TOP_PVT_MON_MAX_RST_Lf, 1); 13345 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13346 13347 if (temperature_count) { 13348 *temperature_count=num_entries_out; 13349 } 13350 13351 return SOC_E_NONE; 13352 } 13353 13354 int 13355 soc_monterey_show_material_process(int unit) 13356 { 13357 soc_reg_t reg; 13358 int index; 13359 uint32 rval, fval, nmos[COUNTOF(pvtmon_result_reg)], n_avg, p_avg; 13360 13361 READ_TOP_PVTMON_CTRL_1r(unit, &rval); 13362 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 0); 13363 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 13364 sal_usleep(1000); 13365 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 1); 13366 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 13367 sal_usleep(1000); 13368 13369 SOC_IF_ERROR_RETURN 13370 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13371 PVTMON_SELECTf, 1)); 13372 sal_usleep(1000); 13373 13374 p_avg = 0; 13375 13376 /* Read NMOS information */ 13377 SOC_IF_ERROR_RETURN 13378 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY, 13379 MEASUREMENT_CALLIBRATIONf, 5)); 13380 13381 sal_usleep(1000); 13382 13383 n_avg = 0; 13384 for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) { 13385 reg = pvtmon_result_reg[index]; 13386 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13387 nmos[index] = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13388 n_avg += nmos[index]; 13389 } 13390 13391 /* Read PMOS information and print both NMOS and PMOS value */ 13392 SOC_IF_ERROR_RETURN 13393 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY, 13394 MEASUREMENT_CALLIBRATIONf, 7)); 13395 13396 sal_usleep(1000); 13397 13398 p_avg = 0; 13399 for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) { 13400 reg = pvtmon_result_reg[index]; 13401 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13402 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13403 p_avg += fval; 13404 13405 LOG_CLI((BSL_META_U(unit, 13406 "Material process location %d: NMOS = %3d PMOS = %3d\n"), 13407 index, nmos[index], fval)); 13408 } 13409 13410 LOG_CLI((BSL_META_U(unit, 13411 "Average: NMOS = %3d PMOS = %3d\n"), 13412 n_avg / COUNTOF(pvtmon_result_reg), 13413 p_avg / COUNTOF(pvtmon_result_reg))); 13414 13415 return SOC_E_NONE; 13416 } 13417 13418 int 13419 soc_monterey_show_ring_osc(int unit) 13420 { 13421 static const struct { 13422 int osc_sel; 13423 soc_field_t field0; 13424 int value0; 13425 soc_field_t field1; 13426 int value1; 13427 char *name; 13428 } osc_tbl[] = { 13429 { 2, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" }, 13430 { 2, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" }, 13431 { 3, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" }, 13432 { 3, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" }, 13433 { 4, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" }, 13434 { 5, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" }, 13435 { 6, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" }, 13436 { 7, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" }, 13437 { 8, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" }, 13438 { 9, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" }, 13439 { 10, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" }, 13440 { 11, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" } 13441 }; 13442 soc_reg_t ctrl_reg, stat_reg; 13443 uint32 rval, fval; 13444 int index, core_clk, quo, rem, frac, retry; 13445 13446 core_clk = SOC_INFO(unit).frequency * 1024; 13447 ctrl_reg = TOP_RING_OSC_CTRLr; 13448 stat_reg = TOP_OSC_COUNT_STATr; 13449 13450 for (index = 0; index < COUNTOF(osc_tbl); index++) { 13451 rval = 0; 13452 /* 13453 * set OSC_CNT_RSTBf to 0 to do softreset 13454 * set OSC_CNT_START to 0 to hold the counter until it selects 13455 * the input signal 13456 */ 13457 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 13458 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_ENABLEf, 1); 13459 soc_reg_field_set(unit, ctrl_reg, &rval, IROSC_ENf, 1); 13460 soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field0, 13461 osc_tbl[index].value0); 13462 if (osc_tbl[index].field1 != INVALIDf) { 13463 soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field1, 13464 osc_tbl[index].value1); 13465 } 13466 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_SELf, 13467 osc_tbl[index].osc_sel); 13468 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 13469 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_RSTBf, 1); 13470 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 13471 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_STARTf, 1); 13472 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 13473 13474 for (retry = 0; retry < 10; retry++) { 13475 sal_usleep(1000); 13476 SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval)); 13477 if (!soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_DONEf)) { 13478 continue; 13479 } 13480 13481 fval = soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_VALUEf); 13482 quo = core_clk / fval; 13483 rem = core_clk - quo * fval; 13484 frac = (rem * 10000) / fval; 13485 LOG_CLI((BSL_META_U(unit, "%s: %d.%04d Mhz\n"), 13486 osc_tbl[index].name, quo, frac)); 13487 break; 13488 } 13489 } 13490 13491 return SOC_E_NONE; 13492 } 13493 13494 int 13495 soc_monterey_show_voltage(int unit) 13496 { 13497 soc_reg_t reg; 13498 int index; 13499 uint32 rval, fval, avg; 13500 13501 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval)); 13502 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0); 13503 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 13504 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1); 13505 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_SELECTf, 4); 13506 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 13507 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 13508 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 0); 13509 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13510 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1); 13511 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13512 13513 sal_sleep(1); 13514 avg = 0; 13515 13516 /* Read Voltages. Ignores result of PVTMON8 */ 13517 for (index = 0; index < COUNTOF(pvtmon_result_reg) ; index++) { 13518 reg = pvtmon_result_reg[index]; 13519 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13520 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13521 /* (PVT_DATA * 880) / 1024 * 0.7 */ 13522 fval = (fval * 880 * 10) / (1024 * 7); 13523 avg += fval; 13524 LOG_CLI((BSL_META_U(unit, 13525 "Voltage monitor %d: voltage = %d.%03dV\n"), 13526 index, (fval/1000), (fval %1000))); 13527 } 13528 13529 avg /= (COUNTOF(pvtmon_result_reg) ); 13530 LOG_CLI((BSL_META_U(unit, 13531 "Average voltage is = %d.%03dV\n"), 13532 (avg/1000), (avg %1000))); 13533 13534 return SOC_E_NONE; 13535 } 13536 13537 /* 13538 * Function: 13539 * soc_monterey_process_func_intr 13540 * Description: 13541 * Chip specific DPC function to service interrupts 13542 * Parameters: 13543 * unit_vp - Device number 13544 * d1 - IRQ3 mask 13545 * d2 - IRQ3 number (to distinguish between 13546 * different types of interrupts). 13547 */ 13548 void 13549 soc_monterey_process_func_intr(void *unit_vp, void *d1, void *d2, void *d3, void *d4) 13550 { 13551 int unit = PTR_TO_INT(unit_vp); 13552 int irq3_num = PTR_TO_INT(d2); 13553 uint32 rval; 13554 13555 if ((irq3_num == 13) /* L2LU INTR */ && 13556 soc_feature(unit, soc_feature_l2_overflow)) { 13557 if (READ_IL2LU_INTR_STATUSr(unit, &rval)) { 13558 LOG_ERROR(BSL_LS_SOC_COMMON, 13559 (BSL_META_U(unit, 13560 "unit %d: Error reading %s reg !!\n"), 13561 unit, SOC_REG_NAME(unit, IL2LU_INTR_STATUSr))); 13562 return; 13563 } 13564 if (soc_reg_field_get(unit, IL2LU_INTR_STATUSr, rval, 13565 L2_LEARN_INSERT_FAILUREf)) { 13566 soc_td2_l2_overflow_interrupt_handler(unit); 13567 } 13568 } 13569 13570 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */ 13571 if (d1 != NULL) { 13572 (void)soc_cmicm_intr3_enable(unit, 13573 PTR_TO_INT(d1)); 13574 } 13575 13576 return; 13577 } 13578 13579 int 13580 soc_monterey_port_asf_speed_set(int unit, soc_port_t port, int speed) 13581 { 13582 soc_monterey_port_ct_speed_t asf_speed_mode; 13583 uint32 rval; 13584 13585 SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval)); 13586 13587 switch (speed) { 13588 case 10: 13589 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_10M_FULL; 13590 break; 13591 case 100: 13592 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_100M_FULL; 13593 break; 13594 case 1000: 13595 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_1000M_FULL; 13596 break; 13597 case 2500: 13598 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_2500M_FULL; 13599 break; 13600 case 5000: 13601 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_5000M_FULL; 13602 break; 13603 case 10000: 13604 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_10000M_FULL; 13605 break; 13606 case 11000: 13607 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_11000M_FULL; 13608 break; 13609 case 20000: 13610 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_20000M_FULL; 13611 break; 13612 case 21000: 13613 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_21000M_FULL; 13614 break; 13615 case 25000: 13616 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_25000M_FULL; 13617 break; 13618 case 27000: 13619 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_27000M_FULL; 13620 break; 13621 case 40000: 13622 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_40000M_FULL; 13623 break; 13624 case 42000: 13625 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_42000M_FULL; 13626 break; 13627 case 50000: 13628 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_50000M_FULL; 13629 break; 13630 case 53000: 13631 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_53000M_FULL; 13632 break; 13633 case 100000: 13634 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_100000M_FULL; 13635 break; 13636 case 106000: 13637 asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_106000M_FULL; 13638 break; 13639 case 0: 13640 return SOC_E_NONE; 13641 default: 13642 return SOC_E_PARAM; 13643 } 13644 13645 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, 13646 ASF_PORT_SPEEDf, asf_speed_mode); 13647 13648 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 13649 return SOC_E_NONE; 13650 } 13651 13652 13653 int 13654 soc_monterey_port_asf_set(int unit, soc_port_t port, int speed) 13655 { 13656 uint32 rval; 13657 soc_reg_t reg; 13658 int mmu_port, phy_port; 13659 int asf_credit_thresh_lo, asf_credit_thresh_hi; 13660 int ep_credit_size = 0, pfc_watermark = 0; 13661 egr_pfc_control_entry_t pfc_control; 13662 egr_mmu_credit_limit_entry_t egr_mmu_credit_entry; 13663 13664 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 13665 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 13666 if (SOC_IS_MONTEREY(unit)) { 13667 return SOC_E_NONE; 13668 13669 } 13670 13671 if (!soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) { 13672 if (speed <= 11000) { 13673 asf_credit_thresh_lo = 4; 13674 asf_credit_thresh_hi = 9; 13675 } else if (speed <= 21000) { 13676 asf_credit_thresh_lo = 8; 13677 asf_credit_thresh_hi = 18; 13678 } else if (speed <= 42000) { 13679 asf_credit_thresh_lo = 18; 13680 asf_credit_thresh_hi = 36; 13681 } else { 13682 asf_credit_thresh_lo = 30; 13683 asf_credit_thresh_hi = 72; 13684 } 13685 } else { 13686 if (speed <= 11000) { 13687 asf_credit_thresh_lo = 3; 13688 asf_credit_thresh_hi = 7; 13689 ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 7 : 11; 13690 pfc_watermark = IS_OVERSUB_PORT(unit,port) ? 13 : 19; 13691 } else if (speed <= 27000) { 13692 asf_credit_thresh_lo = 4; 13693 asf_credit_thresh_hi = 12; 13694 ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 11 : 16; 13695 pfc_watermark = IS_OVERSUB_PORT(unit,port) ? 25 : 19; 13696 } else if (speed <= 42000) { 13697 asf_credit_thresh_lo = 5; 13698 asf_credit_thresh_hi = 16; 13699 ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 23 : 20; 13700 pfc_watermark = 31; 13701 } else if (speed <= 53000) { 13702 asf_credit_thresh_lo = 5; 13703 asf_credit_thresh_hi = 17; 13704 ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 17 : 23; 13705 pfc_watermark = IS_OVERSUB_PORT(unit,port) ? 37 : 31; 13706 } else { 13707 asf_credit_thresh_lo = 7; 13708 asf_credit_thresh_hi = 30; 13709 ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 30 : 39; 13710 pfc_watermark = 61; 13711 } 13712 } 13713 13714 ep_credit_size = ep_credit_size - 1; 13715 rval = 0; 13716 reg = ES_PIPE0_ASF_CREDIT_THRESH_LOr; 13717 soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_lo); 13718 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 13719 13720 rval = 0; 13721 reg = ES_PIPE0_ASF_CREDIT_THRESH_HIr; 13722 soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_hi); 13723 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 13724 SOC_IF_ERROR_RETURN(soc_monterey_port_asf_speed_set(unit, port, speed)); 13725 13726 13727 13728 if (soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) { 13729 13730 /* EGR_PFC_CONTROL */ 13731 sal_memset(&pfc_control, 0, sizeof(egr_pfc_control_entry_t)); 13732 13733 soc_mem_field32_set(unit, EGR_PFC_CONTROLm, &pfc_control, ENABLEf, 1); 13734 soc_mem_field32_set(unit, EGR_PFC_CONTROLm, &pfc_control, WATERMARKf, pfc_watermark); 13735 13736 SOC_IF_ERROR_RETURN(WRITE_EGR_PFC_CONTROLm(unit, MEM_BLOCK_ALL, phy_port, &pfc_control)); 13737 13738 /* EGR_MMU_CREDIT_LIMIT */ 13739 sal_memset(&egr_mmu_credit_entry, 0, sizeof(egr_mmu_credit_limit_entry_t)); 13740 13741 soc_mem_field32_set(unit, EGR_MMU_CREDIT_LIMITm, &egr_mmu_credit_entry, ENABLEf, 1); 13742 soc_mem_field32_set(unit, EGR_MMU_CREDIT_LIMITm, &egr_mmu_credit_entry, CELL_COUNTSf, ep_credit_size); 13743 13744 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CREDIT_LIMITm(unit, MEM_BLOCK_ALL, phy_port, &egr_mmu_credit_entry)); 13745 } 13746 13747 return SOC_E_NONE; 13748 } 13749 13750 int 13751 soc_monterey_port_speed_update(int unit, soc_port_t port, int speed) 13752 { 13753 soc_pbmp_t pbm; 13754 int lossless; 13755 13756 /* Update Edatabuf transmit start count */ 13757 SOC_PBMP_CLEAR(pbm); 13758 SOC_PBMP_PORT_ADD(pbm, port); 13759 SOC_IF_ERROR_RETURN(soc_monterey_ports_edb_config(unit, 0, pbm)); 13760 13761 SOC_IF_ERROR_RETURN(soc_monterey_port_asf_set(unit, port, speed)); 13762 13763 /* Update oversubscription buffer manager (OBM) threshold */ 13764 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 13765 SOC_IF_ERROR_RETURN(_soc_monterey_idb_port_init(unit, FALSE, lossless, port)); 13766 13767 SOC_IF_ERROR_RETURN(soc_mn_mmu_delay_insertion_set(unit, port)); 13768 13769 return SOC_E_NONE; 13770 } 13771 13772 13773 13774 STATIC int 13775 _soc_monterey_thdo_hw_set(int unit, soc_port_t port, int enable) 13776 { 13777 uint64 rval64, rval64_tmp; 13778 int mmu_port, phy_port, i,mmu_port_tmp; 13779 soc_info_t *si; 13780 soc_reg_t reg_tmp; 13781 soc_reg_t reg[3][2] = { 13782 { 13783 THDU_OUTPUT_PORT_RX_ENABLE0_64r, 13784 THDU_OUTPUT_PORT_RX_ENABLE1_64r 13785 }, 13786 { 13787 MMU_THDM_DB_PORTSP_RX_ENABLE0_64r, 13788 MMU_THDM_DB_PORTSP_RX_ENABLE1_64r 13789 }, 13790 { 13791 MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r, 13792 MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r 13793 } 13794 }; 13795 13796 si = &SOC_INFO(unit); 13797 13798 phy_port = si->port_l2p_mapping[port]; 13799 mmu_port = si->port_p2m_mapping[phy_port]; 13800 if (mmu_port > 67) { 13801 return SOC_E_PARAM; 13802 } 13803 13804 for (i = 0; i < 3; i++) { 13805 COMPILER_64_ZERO(rval64); 13806 COMPILER_64_ZERO(rval64_tmp); 13807 if (mmu_port < 64) { 13808 reg_tmp = reg[i][0]; 13809 mmu_port_tmp = mmu_port; 13810 } else { 13811 if (i == 0) { 13812 continue; 13813 } 13814 reg_tmp = reg[i][1]; 13815 mmu_port_tmp = mmu_port - 64; 13816 } 13817 13818 SOC_IF_ERROR_RETURN( 13819 soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64)); 13820 13821 if (mmu_port_tmp < 32) { 13822 COMPILER_64_SET(rval64_tmp, 0, 1 << mmu_port_tmp); 13823 } else { 13824 COMPILER_64_SET(rval64_tmp, 1 << (mmu_port_tmp - 32), 0); 13825 } 13826 13827 if (enable) { 13828 COMPILER_64_OR(rval64, rval64_tmp); 13829 } else { 13830 COMPILER_64_NOT(rval64_tmp); 13831 COMPILER_64_AND(rval64, rval64_tmp); 13832 } 13833 13834 SOC_IF_ERROR_RETURN( 13835 soc_reg_set(unit, reg_tmp, REG_PORT_ANY, 0, rval64)); 13836 } 13837 13838 return SOC_E_NONE; 13839 } 13840 STATIC int 13841 _soc_monterey_thdo_hw_get(int unit, soc_port_t port, int *enable) 13842 { 13843 uint64 rval64; 13844 int mmu_port, phy_port, i, reg_grp = 0; 13845 int rv = SOC_E_NONE; 13846 soc_info_t *si; 13847 soc_reg_t reg_tmp; 13848 soc_reg_t reg[3][2] = { 13849 { 13850 THDU_OUTPUT_PORT_RX_ENABLE0_64r, 13851 THDU_OUTPUT_PORT_RX_ENABLE1_64r 13852 }, 13853 { 13854 MMU_THDM_DB_PORTSP_RX_ENABLE0_64r, 13855 MMU_THDM_DB_PORTSP_RX_ENABLE1_64r 13856 }, 13857 { 13858 MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r, 13859 MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r 13860 } 13861 }; 13862 int max_reg = 3; 13863 13864 si = &SOC_INFO(unit); 13865 13866 phy_port = si->port_l2p_mapping[port]; 13867 mmu_port = si->port_p2m_mapping[phy_port]; 13868 13869 COMPILER_64_ZERO(rval64); 13870 if (mmu_port < 64 ) { 13871 mmu_port &= 0x3f; 13872 } else { 13873 mmu_port &= 0x7; 13874 reg_grp = 1; 13875 } 13876 13877 for (i = 0; i < max_reg; i++) { 13878 reg_tmp = reg[i][reg_grp]; 13879 13880 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64)); 13881 13882 if (COMPILER_64_BITTEST(rval64 , mmu_port)) { 13883 *enable = TRUE; 13884 } else { 13885 *enable = FALSE; 13886 } 13887 } 13888 return rv; 13889 } 13890 13891 /* 13892 * Function: 13893 * _soc_monterey_port_thdo_rx_enable_set 13894 * Purpose: 13895 * enable/disable the traffic to the port according to 13896 * different callers. 13897 * the traffic to the port can be enabled only if all of the callers 13898 * are to enable it. 13899 * Parameters: 13900 * unit - (IN) unit number 13901 * port - (IN) local port 13902 * enable - (IN) enable/disable the traffic to the port. 13903 * flag - (IN) different callers. 13904 * Returns: 13905 * BCM_E_XXX 13906 */ 13907 STATIC int 13908 _soc_monterey_port_thdo_rx_enable_set(int unit, soc_port_t port, 13909 int enable, uint8 flag) 13910 { 13911 int rv = SOC_E_NONE; 13912 uint8 *thdo_drop_bmp; 13913 _soc_monterey_mmu_traffic_ctrl_t *mmu_traffic_ctrl; 13914 int cur_enable =0 ; 13915 FWD_CTRL_LOCK(unit); 13916 13917 mmu_traffic_ctrl = _soc_monterey_mmu_traffic_ctrl[unit]; 13918 if (mmu_traffic_ctrl == NULL) { 13919 FWD_CTRL_UNLOCK(unit); 13920 return SOC_E_INIT; 13921 } 13922 thdo_drop_bmp = 13923 &(mmu_traffic_ctrl->thdo_drop_bmp[port]); 13924 13925 if (!enable) { 13926 if (*thdo_drop_bmp & flag) { 13927 FWD_CTRL_UNLOCK(unit); 13928 return rv; 13929 } 13930 13931 if (*thdo_drop_bmp == 0) { 13932 rv = _soc_monterey_thdo_hw_set(unit, port, enable); 13933 if (SOC_FAILURE(rv)) { 13934 LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Clearing the registers failed.\n"))); 13935 FWD_CTRL_UNLOCK(unit); 13936 return rv; 13937 } 13938 } 13939 13940 *thdo_drop_bmp |= flag; 13941 13942 FWD_CTRL_UNLOCK(unit); 13943 return rv; 13944 } else { 13945 if (0 == *thdo_drop_bmp) { 13946 rv = _soc_monterey_thdo_hw_get(unit, port, &cur_enable); 13947 if (SOC_FAILURE(rv)) { 13948 LOG_ERROR(BSL_LS_SOC_COMMON, 13949 (BSL_META_U(unit, 13950 "Get the registers fail.\n"))); 13951 FWD_CTRL_UNLOCK(unit); 13952 return rv; 13953 } 13954 /* Warmboot: latest value of *thdo_drop_bmp is not sync to WB cache. 13955 * We execute "sc controlsync=1" when one port is link up. But when we exit SDK, 13956 * the port is link down, so the conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r 13957 * of the port is zero. After WarmBoot SDK, 13958 * we can't set conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r 13959 * for the port when it is link up, because, the value of thdo_drop_bmp is zero. 13960 */ 13961 if(cur_enable == FALSE) { 13962 LOG_INFO(BSL_LS_SOC_COMMON, 13963 (BSL_META_U(unit, 13964 "Latest thdo_drop_bmp was not updated to WB cache!!!\n"))); 13965 *thdo_drop_bmp |= flag; 13966 } 13967 } 13968 13969 if (*thdo_drop_bmp != flag) { 13970 /*other callers are in thdo drop*/ 13971 *thdo_drop_bmp &= ~flag; 13972 FWD_CTRL_UNLOCK(unit); 13973 return rv; 13974 } 13975 13976 /*Ok, only self is in thdo drop, enbable it*/ 13977 rv = _soc_monterey_thdo_hw_set(unit, port, enable); 13978 if (SOC_FAILURE(rv)) { 13979 LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Setting the registers failed.\n"))); 13980 FWD_CTRL_UNLOCK(unit); 13981 return rv; 13982 } 13983 13984 *thdo_drop_bmp &= ~flag; 13985 13986 FWD_CTRL_UNLOCK(unit); 13987 return rv; 13988 } 13989 13990 FWD_CTRL_UNLOCK(unit); 13991 return rv; 13992 } 13993 13994 13995 int 13996 soc_monterey_port_traffic_egr_enable_set(int unit, soc_port_t port, 13997 int enable) 13998 { 13999 return _soc_monterey_port_thdo_rx_enable_set(unit, port, enable, 14000 COSQ_SCHED_SET_CTRL); 14001 } 14002 14003 int 14004 soc_monterey_port_mmu_tx_enable_set(int unit, soc_port_t port, 14005 int enable) 14006 { 14007 return _soc_monterey_port_thdo_rx_enable_set(unit, port, enable, 14008 MMU_TRAFFIC_EN_CTRL); 14009 } 14010 14011 int 14012 soc_monterey_port_edb_reset(int unit, soc_port_t port) 14013 { 14014 soc_info_t *si = &SOC_INFO(unit); 14015 uint32 entry[SOC_MAX_MEM_WORDS]; 14016 int phy_port ; 14017 /* Get physical port */ 14018 phy_port = si->port_l2p_mapping[port]; 14019 if (phy_port == -1) { 14020 return SOC_E_INTERNAL; 14021 } 14022 SOC_IF_ERROR_RETURN 14023 (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 14024 phy_port, entry)); 14025 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 14026 entry, ENABLEf, 1); 14027 SOC_IF_ERROR_RETURN 14028 (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 14029 phy_port, entry)); 14030 /* Initialize EP credits in MMU */ 14031 SOC_IF_ERROR_RETURN(_soc_monterey_mmu_ep_credit_reset(unit, port)); 14032 14033 SOC_IF_ERROR_RETURN 14034 (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 14035 phy_port, entry)); 14036 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 14037 entry, ENABLEf, 0); 14038 SOC_IF_ERROR_RETURN 14039 (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 14040 phy_port, entry)); 14041 return SOC_E_NONE; 14042 } 14043 int 14044 soc_monterey_port_thdo_rx_enable_set(int unit, soc_port_t port, 14045 int enable) 14046 { 14047 return _soc_monterey_port_thdo_rx_enable_set(unit, port, enable, 14048 MAC_ENABLE_SET_CTRL); 14049 } 14050 14051 14052 STATIC int 14053 _soc_mn_resource_data_check(int unit, int num_res, soc_port_resource_t *res) 14054 { 14055 int i, j; 14056 /* null check for all resource data before accessing register */ 14057 for (i = 0 ; i < num_res ; ++i) { 14058 soc_port_resource_t *p = &res[i]; 14059 if (NULL == p) { 14060 /* 14061 * COVERITY 14062 * It is kept intentionally as a defensive check. 14063 */ 14064 /* coverity[dead_error_line] */ 14065 return SOC_E_PARAM; 14066 } 14067 for (j = 0; j < p->num_lanes ; ++j) { 14068 soc_port_lane_info_t *p_lane_info = p->lane_info[j]; 14069 if (NULL == p_lane_info) { 14070 return SOC_E_PARAM; 14071 } 14072 } 14073 } 14074 return SOC_E_NONE; 14075 } 14076 14077 /* 14078 * Function: 14079 * soc_mn_pgw_obm_set 14080 * Purpose: 14081 * Reconfigure PGW_OBM registers in flex port sequence 14082 * This function will do two things, 14083 * 1. clear all registers for old ports which exists in pre-Flex status 14084 * 2. initialize all registers for new ports which exists in post-Flex status 14085 * 14086 * Parameters: 14087 * unit - (IN) Unit number. 14088 * pre_num_res - (IN) Number of resource data which exist in pre-Flex status 14089 * post_num_res - (IN) Number of resource data which exist in post-Flex status 14090 * pre_res - (IN) Resource data structure pointer in pre-Flex status 14091 * post_res - (IN) Resource data structure pointer in post-Flex status 14092 * 14093 * Returns: 14094 * SOC_E_XXX 14095 */ 14096 int 14097 soc_mn_pgw_obm_set(int unit, 14098 int pre_num_res, soc_port_resource_t *pre_res, 14099 int post_num_res, soc_port_resource_t *post_res) 14100 { 14101 int i; 14102 int port, xlp; 14103 int lossless; 14104 14105 SOC_IF_ERROR_RETURN( 14106 _soc_mn_resource_data_check(unit, pre_num_res, pre_res)); 14107 SOC_IF_ERROR_RETURN( 14108 _soc_mn_resource_data_check(unit, post_num_res, post_res)); 14109 14110 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 14111 for (i = 0; i < pre_num_res; i++) { 14112 if (pre_res[i].flags & SOC_PORT_RESOURCE_I_MAP) { 14113 continue; 14114 } 14115 if (pre_res[i].physical_port == -1) { 14116 continue; 14117 } 14118 port = pre_res[i].logical_port; 14119 _soc_monterey_idb_port_init(unit, TRUE, lossless, port); 14120 xlp = (pre_res[i].physical_port % (MONTEREY_TSCS_PER_PGW * MONTEREY_PGWS_PER_DEV)); 14121 SOC_IF_ERROR_RETURN(_soc_monterey_port_blk_ca_mode_set(unit, TRUE, xlp)); 14122 } 14123 14124 for (i = 0; i < post_num_res; i++) { 14125 port = post_res[i].logical_port; 14126 _soc_monterey_idb_port_init(unit, FALSE, lossless, port); 14127 xlp = SOC_INFO(unit).port_serdes[port]; 14128 SOC_IF_ERROR_RETURN(_soc_monterey_port_blk_ca_mode_set(unit, TRUE, xlp)); 14129 } 14130 14131 14132 return SOC_E_NONE; 14133 } 14134 14135 14136 /* 14137 * Function: 14138 * soc_mn_obm_threshold_default_set 14139 * Purpose: 14140 * Reconfigure PGW Threshold in flex port sequence 14141 * In this function following registers will be initialized. 14142 * PGW_OBM[0-3]_THRESHOLD 14143 * PGW_OBM[0-3]_THRESHOLD2 14144 * If default_flag is PGW_OBM_INIT_HW_DEFAULT, 14145 * register will be intialized by HW reset value 14146 * If default_flag is PGW_OBM_INIT_SW_DEFAULT, 14147 * register will be intialized by SW reset value 14148 * 14149 * Parameters: 14150 * unit - (IN) Unit number 14151 * num_res - (IN) Number of resource 14152 * res - (IN) Resource data structure 14153 * lossless - (IN) Lossless configuration of device 14154 * default_flag - (IN) PGW_OBM_INIT_HW_DEFAULT 14155 * Use HW reset value for register value 14156 * - (IN) PGW_OBM_INIT_SW_DEFAULT 14157 * Use SW default value 14158 * 14159 * Assumption: 14160 * This function cannot access SOC_INFO data structure. 14161 * So assume followings condition should be checked 14162 * before calling this function. 14163 * 14164 * 1. pgw block is valid 14165 * si->block_valid[PGW_CL_BLOCK(unit, pgw)] is true 14166 * 2. port block is used 14167 * block = PGW_CL_BLOCK(unit, pgw); 14168 * SOC_BLOCK_PORT(unit, block) < 0 14169 * 3. num_res should be correct number of resource data structure. 14170 * all resource data structure should be accessed by using 14171 * pointer offset by res_num. If the pointer of resource data is NULL, 14172 * returns SOC_E_PARAM. 14173 * 14174 * Returns: 14175 * SOC_E_XXX 14176 */ 14177 STATIC 14178 soc_error_t soc_mn_obm_threshold_default_set(int unit, 14179 int num_res, 14180 soc_port_resource_t *res, 14181 int lossless, 14182 int reset) 14183 { 14184 int i; 14185 14186 for (i = 0 ; i < num_res ; ++i) { 14187 14188 14189 SOC_IF_ERROR_RETURN(_soc_monterey_idb_port_init(unit, reset, lossless, res->logical_port)); 14190 14191 } 14192 14193 return SOC_E_NONE; 14194 } 14195 14196 STATIC int 14197 soc_mn_obm_threshold_hw_default_set(int unit, int num_res, 14198 soc_port_resource_t *res, 14199 int lossless) 14200 { 14201 14202 SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_default_set(unit, num_res, res, 14203 lossless, 14204 TRUE)); 14205 return SOC_E_NONE; 14206 } 14207 14208 STATIC int 14209 soc_mn_obm_threshold_sw_default_set(int unit, int num_res, 14210 soc_port_resource_t *res, 14211 int lossless) 14212 { 14213 SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_default_set(unit, num_res, res, 14214 lossless, 14215 FALSE)); 14216 return SOC_E_NONE; 14217 } 14218 14219 /* 14220 * Function: 14221 * soc_mn_obm_threshold_set 14222 * Purpose: 14223 * Reconfigure PGW registers in flex port sequence 14224 * In this function PGW OBM threshold registers will be initialized. 14225 * This function will do two things, 14226 * 1. clear all registers for old ports which exists in pre-Flex status 14227 * 2. initialize all registers for new ports which exists in post-Flex status 14228 * 14229 * Parameters: 14230 * unit - (IN) Unit number. 14231 * pre_num_res - (IN) Number of resource data which exist in pre-Flex status 14232 * post_num_res - (IN) Number of resource data which exist in post-Flex status 14233 * pre_res - (IN) Resource data structure pointer in pre-Flex status 14234 * post_res - (IN) Resource data structure pointer in post-Flex status 14235 * lossless - (IN) mmu lossless information 14236 * 14237 * Returns: 14238 * SOC_E_XXX 14239 * 14240 * Note : For 100G port, this functions expects the ovsersub field to be 14241 * disabled. 14242 */ 14243 soc_error_t soc_mn_obm_threshold_set(int unit, 14244 int pre_num_res, soc_port_resource_t *pre_res, 14245 int post_num_res, soc_port_resource_t *post_res, 14246 int lossless) 14247 { 14248 14249 SOC_IF_ERROR_RETURN(_soc_mn_resource_data_check(unit, pre_num_res, 14250 pre_res)); 14251 SOC_IF_ERROR_RETURN(_soc_mn_resource_data_check(unit, post_num_res, 14252 post_res)); 14253 SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_hw_default_set(unit, 14254 pre_num_res, pre_res, lossless)); 14255 14256 SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_sw_default_set(unit, 14257 post_num_res, post_res, lossless)); 14258 14259 return SOC_E_NONE; 14260 } 14261 14262 14263 /* 14264 * This function is used to enable or disable cut through when a port is 14265 * operating in store and forward mode. 14266 * Refer TD2_Cutthrough_programming_guideline.pdf 14267 * Caller must pass the correct port_info pointer, corresponding to the port 14268 * being configured (and sent by the BCM layer) 14269 * To enable cut-through, pass enable = 1 14270 * To disable cut-through, pass enable = 0 14271 */ 14272 int 14273 soc_mn_cut_thru_enable_disable(int unit, soc_port_t port, int enable) 14274 { 14275 uint32 rval; 14276 uint32 speed; 14277 soc_pbmp_t pbm; 14278 14279 /* Cut-through not supported on non-packet-forwarding ports */ 14280 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 14281 return SOC_E_PORT; 14282 } 14283 14284 /* When in Oversub, only 40G speeds support CT */ 14285 speed = SOC_INFO(unit).port_speed_max[port]; 14286 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed); 14287 if (IS_OVERSUB_PORT(unit, port) && speed != 40000) { 14288 LOG_ERROR(BSL_LS_SOC_COMMON, 14289 (BSL_META_U(unit, 14290 "ASF supported only on 40G/42G ports " 14291 "when in Oversub\n"))); 14292 return SOC_E_PORT; 14293 } 14294 14295 14296 /* Mask unnecessary bits */ 14297 enable &= 0x1; 14298 14299 SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval)); 14300 14301 speed = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, ASF_PORT_SPEEDf); 14302 14303 /* Set port speed to 0 */ 14304 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, 0); 14305 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14306 14307 if (!enable) { 14308 /* Wait 8ms for draining all cells */ 14309 sal_usleep(8000); 14310 } 14311 14312 14313 SOC_PBMP_CLEAR(pbm); 14314 SOC_PBMP_PORT_ADD(pbm, port); 14315 SOC_IF_ERROR_RETURN(soc_monterey_ports_edb_config(unit, enable, pbm)); 14316 14317 14318 /* Set UC_ASF_ENABLE, MC_ASF_ENABLE bits to 1 */ 14319 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, UC_ASF_ENABLEf, enable); 14320 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, MC_ASF_ENABLEf, enable); 14321 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14322 14323 if (enable) { 14324 /* Wait 1 micro-sec */ 14325 sal_usleep(1); 14326 } 14327 14328 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, speed); 14329 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14330 14331 return SOC_E_NONE; 14332 } 14333 14334 14335 int soc_mn_max_speed_port_find(int phy_port, 14336 soc_port_resource_t *port_info, 14337 int port_info_arr_size) 14338 { 14339 int idx, index, speed; 14340 14341 index = 0; 14342 speed = port_info[index].speed; 14343 14344 for (idx = 1; idx < port_info_arr_size; idx++) { 14345 /* If all speeds are equal, '>' will return the 1st index, 14346 * '>=' will return the last index 14347 */ 14348 if (port_info[idx].speed > speed) { 14349 speed = port_info[idx].speed; 14350 index = idx; 14351 } 14352 } 14353 14354 return index; 14355 } 14356 14357 /* 14358 * This function checks if cut-through is enabled for a given port. 14359 * If either unicast or multicast cut-through is enabled, the function 14360 * returns TRUE else FALSE is returned 14361 */ 14362 int 14363 soc_monterey_is_cut_thru_enabled(int unit, soc_port_t port, int *enable) 14364 { 14365 uint32 rval; 14366 uint32 uc_enable, mc_enable; 14367 14368 /* Cut-through not supported on following ports */ 14369 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 14370 return SOC_E_PARAM; 14371 } 14372 14373 SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval)); 14374 14375 uc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, UC_ASF_ENABLEf); 14376 mc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, MC_ASF_ENABLEf); 14377 14378 if (uc_enable || mc_enable) { 14379 *enable = TRUE; 14380 } else { 14381 *enable = FALSE; 14382 } 14383 14384 return SOC_E_NONE; 14385 } 14386 14387 /* 14388 * This function is used to clear various counters in EP block. The 14389 * counters to clear are mentioned in 'Reconfigure EP' section of TD2+ Flexport 14390 */ 14391 STATIC int soc_mn_ep_counters_clear(int unit, soc_port_resource_t *port_info) 14392 { 14393 uint64 val64; 14394 14395 COMPILER_64_ZERO(val64); 14396 14397 SOC_IF_ERROR_RETURN(WRITE_TPCEr(unit, port_info->logical_port, val64)); 14398 14399 SOC_IF_ERROR_RETURN(WRITE_TDBGC0r(unit, port_info->logical_port, val64)); 14400 SOC_IF_ERROR_RETURN(WRITE_TDBGC1r(unit, port_info->logical_port, val64)); 14401 SOC_IF_ERROR_RETURN(WRITE_TDBGC2r(unit, port_info->logical_port, val64)); 14402 SOC_IF_ERROR_RETURN(WRITE_TDBGC3r(unit, port_info->logical_port, val64)); 14403 SOC_IF_ERROR_RETURN(WRITE_TDBGC4r(unit, port_info->logical_port, val64)); 14404 SOC_IF_ERROR_RETURN(WRITE_TDBGC5r(unit, port_info->logical_port, val64)); 14405 SOC_IF_ERROR_RETURN(WRITE_TDBGC6r(unit, port_info->logical_port, val64)); 14406 SOC_IF_ERROR_RETURN(WRITE_TDBGC7r(unit, port_info->logical_port, val64)); 14407 SOC_IF_ERROR_RETURN(WRITE_TDBGC8r(unit, port_info->logical_port, val64)); 14408 SOC_IF_ERROR_RETURN(WRITE_TDBGC9r(unit, port_info->logical_port, val64)); 14409 SOC_IF_ERROR_RETURN(WRITE_TDBGC10r(unit, port_info->logical_port, val64)); 14410 SOC_IF_ERROR_RETURN(WRITE_TDBGC11r(unit, port_info->logical_port, val64)); 14411 14412 return SOC_E_NONE; 14413 } 14414 14415 14416 STATIC int 14417 soc_mn_port_resource_tdm_calculate(int unit, soc_monterey_tdm_t *tdm) 14418 { 14419 int index; 14420 soc_info_t *si; 14421 soc_pbmp_t pbmp; 14422 int port = 0, slot = 0, phy_port = 0; 14423 int roe_speed_cpri,roe_speed_rsvd4; 14424 /* soc info has new values */ 14425 si = &SOC_INFO(unit); 14426 14427 sal_memset(tdm, 0, sizeof(soc_monterey_tdm_t)); 14428 14429 PBMP_PORT_ITER(unit, port) { 14430 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 14431 continue; 14432 } 14433 phy_port = si->port_l2p_mapping[port]; 14434 tdm->speed[phy_port] = si->port_speed_max[port]; 14435 if(IS_CPRI_PORT(unit,port) || IS_RSVD4_PORT(unit,port)) { 14436 if (si->port_speed_max[port] > 10100) { 14437 tdm->speed[phy_port] = 25000; 14438 }else { 14439 if (SOC_PBMP_MEMBER(si->roe_compression, port)) { 14440 roe_speed_cpri = soc_property_port_get(unit, port, spn_CPRI_PORT_INIT_SPEED_ID, -1); 14441 roe_speed_rsvd4 = soc_property_port_get(unit, port, spn_RSVD4_PORT_INIT_SPEED_ID, -1); 14442 if ((roe_speed_cpri > 0) && IS_CPRI_PORT(unit,port)) { 14443 if ((roe_speed_cpri > 6144)) { 14444 tdm->speed[phy_port] = 25000; 14445 } else { 14446 tdm->speed[phy_port] = 10000; 14447 } 14448 } else if ((roe_speed_rsvd4 > 0) && IS_RSVD4_PORT(unit,port)) { 14449 if ((roe_speed_cpri > 6144)) { 14450 tdm->speed[phy_port] = 25000; 14451 } else { 14452 tdm->speed[phy_port] = 10000; 14453 } 14454 } else { 14455 if (si->port_speed_max[port] > 6144) { 14456 tdm->speed[phy_port] = 25000; 14457 } else { 14458 tdm->speed[phy_port] = 10000; 14459 } 14460 } 14461 } else { 14462 tdm->speed[phy_port] = 10000; 14463 } 14464 } 14465 14466 } 14467 14468 MONTEREY_TDM_SPEED_ADJUST(unit, port, tdm->speed[phy_port]); 14469 14470 tdm->port_state[phy_port] = 14471 IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE; 14472 14473 /* 14474 * Primary port will be setup as line-rate or oversub. 14475 * Subsequent physical ports (sister-ports) will be either 14476 * DISABLED or SUBPORT/COMBINED mode. 14477 * 14478 * TDM Algo expects lanes info based on speed. 14479 */ 14480 if (soc_monterey_port_is_falcon(unit, phy_port)) { /* Falcons */ 14481 if (tdm->speed[phy_port] > 25000) { 14482 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 14483 } 14484 if (tdm->speed[phy_port] > 50000) { 14485 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 14486 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 14487 } 14488 } else { /* Eagles */ 14489 if (tdm->speed[phy_port] > 10000) { 14490 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 14491 } 14492 if (tdm->speed[phy_port] > 20000) { 14493 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 14494 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 14495 } 14496 if (tdm->speed[phy_port] > 40000) { 14497 tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT; 14498 tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT; 14499 tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT; 14500 tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT; 14501 tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT; 14502 tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT; 14503 } 14504 } 14505 } 14506 /* CPU, LB and RDB ports */ 14507 tdm->speed[0] = 1000; 14508 tdm->speed[65] = 1000; 14509 /*Macsec port is 20G in monterey*/ 14510 tdm->speed[66] = 20000; 14511 tdm->tdm_bw = si->bandwidth / 1000; 14512 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 14513 SOC_PBMP_AND(pbmp, si->xpipe_pbm); 14514 /* tell tdm code the device is oversub if any ports is oversub */ 14515 tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp); 14516 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 14517 14518 for (slot = 0; slot <= MONTEREY_MMU_TDM_LENGTH; slot++) { 14519 tdm->mmu_tdm[slot] = NUM_EXT_PORTS; 14520 } 14521 14522 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 14523 LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), tdm->tdm_bw)); 14524 LOG_CLI((BSL_META_U(unit, "port speed:"))); 14525 for (index = 0; index < NUM_EXT_PORTS; index++) { 14526 if (index % 8 == 0) { 14527 LOG_CLI((BSL_META_U(unit, "\n "))); 14528 } 14529 LOG_CLI((BSL_META_U(unit, " %06d(%03d)"), 14530 tdm->speed[index], index)); 14531 } 14532 LOG_CLI((BSL_META_U(unit, "\n"))); 14533 LOG_CLI((BSL_META_U(unit, "port state map:"))); 14534 for (index = 0; index < NUM_EXT_PORTS; index++) { 14535 if (index % 8 == 0) { 14536 LOG_CLI((BSL_META_U(unit, "\n "))); 14537 } 14538 if (index == 0 || index == (NUM_EXT_PORTS - 1)) { 14539 LOG_CLI((BSL_META_U(unit, " --------"))); 14540 } else { 14541 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"), 14542 tdm->port_state[index], index)); 14543 } 14544 } 14545 LOG_CLI((BSL_META_U(unit, "\n"))); 14546 } 14547 14548 14549 SOC_IF_ERROR_RETURN(soc_monterey_tdm_calc(unit, tdm)); 14550 14551 14552 return SOC_E_NONE; 14553 } 14554 14555 14556 14557 STATIC int 14558 soc_mn_ovr_sub_tdm_update(int unit, 14559 soc_monterey_tdm_t *tdm, 14560 int pre_count, 14561 soc_port_resource_t *pre_res, 14562 int post_count, 14563 soc_port_resource_t *post_res) 14564 { 14565 int phy_port; 14566 int group, wt_group, speed_group; 14567 int res_count, speed_class; 14568 int slot, empty_slot_cnt; 14569 uint32 speed_spacing; 14570 soc_monterey_tdm_t *cur_tdm; 14571 14572 14573 tdm = MONTEREY_TDM_STRUCT_BACKUP(unit); 14574 cur_tdm = MONTEREY_TDM_STRUCT_ACTIVE(unit); 14575 14576 /* Remove old ports from the existing egress overusb groups */ 14577 for (res_count = 0; res_count < pre_count; res_count++) { 14578 soc_port_resource_t *p = &pre_res[res_count]; 14579 14580 /* If OBM is not enabled then continue */ 14581 if (!p->oversub) { 14582 continue; 14583 } 14584 14585 if (p->flags & SOC_PORT_RESOURCE_INACTIVE) { 14586 continue; 14587 } 14588 14589 phy_port = p->physical_port; 14590 14591 for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) { 14592 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) { 14593 continue; 14594 } 14595 empty_slot_cnt = 0; 14596 for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 14597 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] == phy_port) { 14598 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = NUM_EXT_PORTS; 14599 14600 } 14601 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) { 14602 empty_slot_cnt++; 14603 } 14604 } 14605 14606 /* Mark group that has no more valid mmu ports as free */ 14607 if (empty_slot_cnt == MONTEREY_MMU_OVS_GROUP_TDM_LENGTH) { 14608 MONTEREY_TDM_WT_GRP_FREE(unit, cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group]); 14609 cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = 0; 14610 cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = MONTEREY_MMU_OVS_WT_GROUP_COUNT; 14611 break; 14612 } 14613 } 14614 } 14615 14616 /* Add 'new' ports to the egress schedulers */ 14617 for (res_count = 0; res_count < post_count; res_count++) { 14618 soc_port_resource_t *p = &post_res[res_count]; 14619 14620 /* If OBM is not enabled then continue */ 14621 if (!p->oversub) { 14622 continue; 14623 } 14624 14625 if (p->flags & SOC_PORT_RESOURCE_INACTIVE) { 14626 continue; 14627 } 14628 14629 speed_class = p->speed; 14630 phy_port = p->physical_port; 14631 14632 14633 if (SOC_FAILURE(_soc_monterey_mmu_ovs_speed_class_map_get( 14634 unit, &speed_class, &speed_group, &speed_spacing))) { 14635 14636 LOG_ERROR(BSL_LS_SOC_PORT, 14637 (BSL_META_U(unit, 14638 "Invalid Speed Class %d for port %d (physical = %d)"), 14639 speed_class, p->logical_port, phy_port)); 14640 14641 return SOC_E_INTERNAL; 14642 } 14643 14644 MONTEREY_TDM_WT_GRP_LOG(unit); 14645 14646 /* Try to fit the new port in the group with same speed ports */ 14647 for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) { 14648 /* Group with different speed ports; skip! */ 14649 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] != speed_class) { 14650 continue; 14651 } 14652 14653 for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 14654 /* break when an empty slot is found */ 14655 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) { 14656 break; 14657 } 14658 } 14659 if (slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH) { 14660 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port; 14661 phy_port = NUM_EXT_PORTS; 14662 break; 14663 } 14664 } 14665 14666 if (phy_port == NUM_EXT_PORTS) { 14667 /* Found an empty slot and filled; continue to next */ 14668 continue; 14669 } 14670 14671 /* Could not get a group with same speed ports, try a free group */ 14672 for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) { 14673 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) { 14674 break; 14675 } 14676 } 14677 14678 if (group < MONTEREY_MMU_OVS_GROUP_COUNT) { 14679 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][0] = phy_port; 14680 cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class; 14681 14682 for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 14683 if (MN_TDM_WT_GRP_SPG_GET(unit, wt_group) == speed_group) { 14684 MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 14685 break; 14686 } 14687 } 14688 14689 if (wt_group >= MONTEREY_MMU_OVS_WT_GROUP_COUNT) { 14690 for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 14691 if (MN_TDM_WT_GRP_REFCNT_GET(unit, wt_group) == 0) { 14692 MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 14693 break; 14694 } 14695 } 14696 } 14697 14698 if (wt_group >= MONTEREY_MMU_OVS_WT_GROUP_COUNT) { 14699 /* We could not find a weight group for this new port */ 14700 LOG_ERROR(BSL_LS_SOC_PORT, 14701 (BSL_META_U(unit, 14702 "Could not find a usable weight group for " 14703 "port %d (physical = %d; speed_class = %d)"), 14704 p->logical_port, phy_port, speed_class)); 14705 return SOC_E_INTERNAL; 14706 } 14707 14708 cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group; 14709 14710 continue; 14711 } 14712 14713 /* We could not find a group that can fit this new port */ 14714 LOG_ERROR(BSL_LS_SOC_PORT, 14715 (BSL_META_U(unit, 14716 "Could not find a usable oversub group for " 14717 "port %d (physical = %d; speed_class = %d)"), 14718 p->logical_port, phy_port, speed_class)); 14719 14720 return SOC_E_INTERNAL; 14721 } 14722 14723 sal_memcpy(&(tdm->egress_ovs_tdm), &(cur_tdm->egress_ovs_tdm), sizeof(tdm->egress_ovs_tdm)); 14724 14725 return SOC_E_NONE; 14726 } 14727 14728 14729 /* 14730 * Function: 14731 * soc_mn_port_resource_tdm_set 14732 * Purpose: 14733 * Reconfigure the ingress and egress schedulers for 14734 * the new port configuration. 14735 * 14736 * This includes reconfiguration of: 14737 * - OBM Thresholds 14738 * - EDB Prebuffer 14739 * - Ingress Oversub Scheduler 14740 * - Egress Oversub Scheduler 14741 * - Line-Rate Scheduler 14742 * Parameters: 14743 * unit - (IN) Unit number. 14744 * curr_port_info_size - (IN) Size of current port information array 14745 * curr_port_info - (IN) Per-port array with current flexing info 14746 * new_port_info_size - (IN) Size of new port information array 14747 * new_port_info - (IN) Per-port array with new flexing info 14748 * si_info - (IN) Contains subset of fields from 14749 * soc_info_t structure 14750 * prior to the flexing operation 14751 * lossless - (IN) MMU lossless information 14752 * Returns: 14753 * SOC_E_XXX 14754 * Note: 14755 * Assumptions 14756 * - soc info structure members have been updated to reflect the latest 14757 * flexing operation 14758 * - There is no overlapping between logical or physical ports in the 14759 * arrays passed, that is, operations like 4x10->1x40->4x10 on the same 14760 * set of ports have been rejected at bcm layer itself, and do not reach 14761 * this function 14762 * - Pre-FlexPort array 14763 * Contains current information on ports to be modified after 14764 * the FlexPort operation. This should include ports whose 14765 * mappings are either deleted or remapped. 14766 * - Post-FlexPort array 14767 * Contains information on new configuration for 14768 * ports that are active (present) after the FlexPort operation. 14769 * This should include ports whose mappings that are remapped or new. 14770 */ 14771 int soc_mn_port_resource_tdm_set(int unit, int curr_port_info_size, 14772 soc_port_resource_t *curr_port_info, 14773 int new_port_info_size, 14774 soc_port_resource_t *new_port_info, 14775 soc_mn_info_t *si_info, 14776 int lossless) 14777 { 14778 int rv; 14779 uint32 rval; 14780 soc_monterey_tdm_t *tdm; 14781 14782 /* Sec 6.6.3.2, #1 and #2 will be filled as part of oversubscription 14783 * code changes 14784 */ 14785 14786 /* Reconfigure EDB prebuffer 6.6.3.2 (#3) */ 14787 14788 SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval)); 14789 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 14790 CLPORT_CELL_COUNTSf, 0x1); 14791 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 14792 XLPORT_CELL_COUNTSf, 0x3); 14793 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 14794 ENABLEf, 0x1); 14795 SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval)); 14796 14797 /* Reconfigure EDB prebuffer back up calendar 6.6.3.2 (#4), for line rate 14798 * TDM calendar. Oversub related portion will be added later 14799 */ 14800 14801 /* Configure ingress scheduler back up calendar 6.6.3.2.2 (#1, bullet #2) */ 14802 tdm = MONTEREY_TDM_STRUCT_BACKUP(unit); 14803 SOC_IF_ERROR_RETURN(soc_mn_port_resource_tdm_calculate(unit, tdm)); 14804 14805 /* Reconfigure oversub scheduler (Sections 6.6.3.2.3, 6.6.3.2.4). 14806 * Function internally determines if oversub is enabled/disabled 14807 */ 14808 rv = soc_mn_ovr_sub_tdm_update(unit, tdm, 14809 curr_port_info_size, curr_port_info, 14810 new_port_info_size, new_port_info); 14811 SOC_IF_ERROR_RETURN(rv); 14812 14813 14814 /* toggle the active calendar */ 14815 MONTEREY_TDM_ACTIVE_CAL(unit) ^= 1; 14816 14817 /* update the tdm calendar config in the hardware */ 14818 SOC_IF_ERROR_RETURN(soc_monterey_tdm_update(unit, 0, MONTEREY_TDM_ACTIVE_CAL(unit), tdm)); 14819 14820 /* Reconfigure EDB prebuffer 6.6.3.2 (#6) */ 14821 14822 sal_usleep(1); 14823 14824 SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval)); 14825 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 14826 CLPORT_CELL_COUNTSf, 0x1); 14827 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 14828 XLPORT_CELL_COUNTSf, 0x3); 14829 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 14830 ENABLEf, 0x0); 14831 SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval)); 14832 14833 14834 return SOC_E_NONE; 14835 } 14836 14837 /* 14838 * Function: 14839 * soc_mn_port_resource_pgw_set 14840 * Purpose: 14841 * Reconfigure PGW registers in flex port sequence 14842 * In this function following registers will be initialized. 14843 * This function will do two things, 14844 * 1. clear all registers for old ports which exists in pre-Flex status 14845 * 2. initialize all registers for new ports which exists in post-Flex 14846 * status 14847 * 14848 * Parameters: 14849 * unit - (IN) Unit number. 14850 * pre_num_res - (IN) Number of resource data which exist in pre-Flex 14851 * status 14852 * post_num_res - (IN) Number of resource data which exist in post-Flex 14853 * status 14854 * pre_res - (IN) Resource data structure pointer in pre-Flex status 14855 * post_res - (IN) Resource data structure pointer in post-Flex status 14856 * lossless - (IN) MMU lossless information 14857 * 14858 * Returns: 14859 * SOC_E_XXX 14860 * Note: 14861 * - Assumes FlexPort cases are valid. 14862 * - Pre-FlexPort array 14863 * Contains current information on ports to be modified after 14864 * the FlexPort operation. This should include ports whose 14865 * mappings are either deleted or remapped. 14866 * - Post-FlexPort array 14867 * Contains information on new configuration for 14868 * ports that are active (present) after the FlexPort operation. 14869 * This should include ports whose mappings that are remapped or new. 14870 */ 14871 int 14872 soc_mn_port_resource_pgw_set(int unit, 14873 int pre_num_res, soc_port_resource_t *pre_res, 14874 int post_num_res, soc_port_resource_t *post_res, 14875 int lossless) 14876 { 14877 int i; 14878 14879 SOC_IF_ERROR_RETURN( 14880 _soc_mn_resource_data_check(unit, pre_num_res, pre_res)); 14881 SOC_IF_ERROR_RETURN( 14882 _soc_mn_resource_data_check(unit, post_num_res, post_res)); 14883 14884 for (i = 0; i < post_num_res; i++) { 14885 /* Reconfigure the Port Mode for Port Macro */ 14886 SOC_IF_ERROR_RETURN( 14887 soc_portctrl_port_mode_set(unit, post_res[i].logical_port, post_res[i].mode)); 14888 } 14889 14890 SOC_IF_ERROR_RETURN(soc_mn_pgw_obm_set(unit, 14891 pre_num_res, pre_res, 14892 post_num_res, post_res)); 14893 14894 return SOC_E_NONE; 14895 } 14896 14897 /* 14898 * Function: 14899 * soc_mn_port_resource_ip_set 14900 * Purpose: 14901 * Reconfigure IP. 14902 * Parameters: 14903 * unit - (IN) Unit number. 14904 * curr_port_info_size - (IN) Size of current port information array 14905 * curr_port_info - (IN) Per-port array with current flexing info 14906 * new_port_info_size - (IN) Size of new port information array 14907 * new_port_info - (IN) Per-port array with new flexing info 14908 * si_info - (IN) Contains subset of fields from soc_info_t structure 14909 * prior to the flexing operation 14910 * Returns: 14911 * SOC_E_XXX 14912 * Note: 14913 * Assumptions 14914 * - soc info structure members have been updated to reflect the latest 14915 * flexing operation 14916 * - There is no overlapping between logical or physical ports in the 14917 * arrays passed, example, operations like 4x10->1x40->4x10 on the same 14918 * set of ports have been rejected at bcm layer itself, and do not reach 14919 * this function 14920 * - Pre-FlexPort array 14921 * Contains current information on ports to be modified after 14922 * the FlexPort operation. This should include ports whose 14923 * mappings are either deleted or remapped. 14924 * - Post-FlexPort array 14925 * Contains information on new configuration for 14926 * ports that are active (present) after the FlexPort operation. 14927 * This should include ports whose mappings that are remapped or new. 14928 */ 14929 int soc_mn_port_resource_ip_set(int unit, int curr_port_info_size, 14930 soc_port_resource_t *curr_port_info, 14931 int new_port_info_size, 14932 soc_port_resource_t *new_port_info, 14933 soc_mn_info_t *si_info) 14934 { 14935 soc_info_t *si; 14936 soc_mem_t mem; 14937 ing_physical_to_logical_port_number_mapping_table_entry_t entry; 14938 int port, phy_port; 14939 int num_phy_port; 14940 14941 si = &SOC_INFO(unit); 14942 14943 /* Ingress physical to logical port mapping */ 14944 mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm; 14945 num_phy_port = soc_mem_index_count(unit, mem); 14946 14947 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 14948 sal_memset(&entry, 0, sizeof(entry)); 14949 14950 /* The p2l mapping has been updated before this function is called */ 14951 port = si->port_p2l_mapping[phy_port]; 14952 14953 soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf, 14954 port == -1 ? 0x7F : port); 14955 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, 14956 &entry)); 14957 } 14958 14959 return SOC_E_NONE; 14960 } 14961 14962 /* 14963 * Function: 14964 * soc_mn_port_resource_ep_set 14965 * Purpose: 14966 * Reconfigure EP. 14967 * Parameters: 14968 * unit - (IN) Unit number. 14969 * curr_port_info_size - (IN) Size of current port information array 14970 * curr_port_info - (IN) Per-port array with current flexing info 14971 * new_port_info_size - (IN) Size of new port information array 14972 * new_port_info - (IN) Per-port array with new flexing info 14973 * si_info - (IN) Contains subset of fields from soc_info_t structure 14974 * prior to the flexing operation 14975 * Returns: 14976 * SOC_E_XXX 14977 * Note: 14978 * Assumptions 14979 * - soc info structure members have been updated to reflect the latest 14980 * flexing operation 14981 * - There is no overlapping between logical or physical ports in the 14982 * arrays passed, example, operations like 4x10->1x40->4x10 on the same 14983 * set of ports have been rejected at bcm layer itself, and do not reach 14984 * this function 14985 * - Pre-FlexPort array 14986 * Contains current information on ports to be modified after 14987 * the FlexPort operation. This should include ports whose 14988 * mappings are either deleted or remapped. 14989 * - Post-FlexPort array 14990 * Contains information on new configuration for 14991 * ports that are active (present) after the FlexPort operation. 14992 * This should include ports whose mappings that are remapped or new. 14993 */ 14994 int soc_mn_port_resource_ep_set(int unit, int curr_port_info_size, 14995 soc_port_resource_t *curr_port_info, 14996 int new_port_info_size, 14997 soc_port_resource_t *new_port_info, 14998 soc_mn_info_t *si_info) 14999 { 15000 soc_info_t *si; 15001 uint32 rval; 15002 int num_port, port, idx, phy_port; 15003 15004 si = &SOC_INFO(unit); 15005 15006 /* Ingress logical to physical port mapping */ 15007 num_port = soc_mem_index_count(unit, PORT_TABm) - 1; 15008 15009 /* Egress logical to physical port mapping */ 15010 for (port = 0; port < num_port; port++) { 15011 /* 15012 * Use logical to physical number mapping from soc info structure 15013 * since it has been updated before this function is called 15014 */ 15015 phy_port = si->port_l2p_mapping[port]; 15016 15017 rval = 0; 15018 soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr, 15019 &rval, PHYSICAL_PORT_NUMBERf, 15020 phy_port == -1 ? 0x7F : phy_port); 15021 SOC_IF_ERROR_RETURN 15022 (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port, 15023 rval)); 15024 } 15025 15026 /* Clear counters for the newly added ports */ 15027 for (idx = 0; idx < new_port_info_size; idx++) { 15028 SOC_IF_ERROR_RETURN(soc_mn_ep_counters_clear(unit, 15029 &new_port_info[idx])); 15030 } 15031 15032 return SOC_E_NONE; 15033 } 15034 15035 /* 15036 * Function: 15037 * soc_mn_port_resource_mmu_mapping_set 15038 * Purpose: 15039 * Set the HW MMU Port mappings. 15040 * Parameters: 15041 * unit - (IN) Unit number. 15042 * nport - (IN) Number of elements in array resource. 15043 * resource - (IN) Port Resource FlexPort configuration. 15044 * Returns: 15045 * SOC_E_XXX 15046 * Note: 15047 * Assumes FlexPort cases are valid. 15048 * Assumes SOC INFO data structure has been updated. 15049 */ 15050 int 15051 soc_mn_port_resource_mmu_mapping_set(int unit, int nport, 15052 soc_port_resource_t *resource) 15053 { 15054 soc_info_t *si = &SOC_INFO(unit); 15055 soc_port_resource_t *pr; 15056 int i; 15057 int logic_port; 15058 int phy_port; 15059 uint32 rval; 15060 15061 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 15062 /* 15063 * Skip for legacy inactive configurations since 15064 * MMU mappings are kept the same. 15065 */ 15066 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 15067 LOG_VERBOSE(BSL_LS_SOC_PORT, 15068 (BSL_META_U(unit, 15069 " Skip port with inactive configuration, " 15070 "mappings are kept the same, " 15071 "mmu=%d logical=%d physical=%d\n"), 15072 si->port_p2m_mapping 15073 [si->port_l2p_mapping[pr->logical_port]], 15074 pr->logical_port, 15075 si->port_l2p_mapping[pr->logical_port])); 15076 continue; 15077 } 15078 15079 if (pr->physical_port == -1) { 15080 /* Remove old MMU mappings. */ 15081 logic_port = 0x7F; 15082 phy_port = 0x7F; 15083 15084 } else { 15085 logic_port = pr->logical_port; 15086 phy_port = pr->physical_port; 15087 } 15088 15089 rval = 0; 15090 soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval, 15091 PHY_PORTf, phy_port); 15092 SOC_IF_ERROR_RETURN 15093 (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, pr->logical_port, 15094 0, rval)); 15095 15096 rval = 0; 15097 soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval, 15098 LOGIC_PORTf, logic_port); 15099 SOC_IF_ERROR_RETURN 15100 (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, pr->logical_port, 15101 0, rval)); 15102 15103 LOG_VERBOSE(BSL_LS_SOC_PORT, 15104 (BSL_META_U(unit, 15105 "MMU port mappings: " 15106 "mmu=%d logical=%d physical=%d\n"), 15107 si->port_p2m_mapping 15108 [si->port_l2p_mapping[pr->logical_port]], 15109 logic_port, phy_port)); 15110 } 15111 15112 return SOC_E_NONE; 15113 } 15114 15115 15116 /* 15117 * Function: 15118 * soc_mn_port_resource_mmu_set 15119 * Purpose: 15120 * Called to reconfigure the MMU hardware. 15121 * Parameters: 15122 * unit - (IN) Device Number 15123 * nport - (IN) The number of port modifications in flexport_data 15124 * flexport_data - (IN) An array of port changes that are being done 15125 * Returns: 15126 * SOC_E_NONE if parameters are valid, an error otherwise. 15127 * Note: 15128 * Assumes FlexPort cases are valid. 15129 * Assumes SOC INFO data structure has been updated. 15130 */ 15131 int 15132 soc_mn_port_resource_mmu_set(int unit, int nport, 15133 soc_port_resource_t *flexport_data) 15134 { 15135 int i; 15136 15137 /* Update MMU Port Mappings */ 15138 SOC_IF_ERROR_RETURN 15139 (soc_mn_port_resource_mmu_mapping_set(unit, nport, 15140 flexport_data)); 15141 15142 /* Configure all MMU registers for new ports */ 15143 for (i = 0; i < nport; i++) { 15144 if (flexport_data[i].physical_port != -1) { 15145 SOC_IF_ERROR_RETURN( 15146 soc_monterey_mmu_port_resource_set(unit, flexport_data[i].logical_port, 15147 flexport_data[i].speed)); 15148 } 15149 } 15150 15151 return SOC_E_NONE; 15152 } 15153 15154 /* 15155 * Function: 15156 * soc_mn_is_port_flex_enable 15157 * Purpose: 15158 * Find out if port_flex_enable{physical port num} config 15159 * is present on the given physical port in config.bcm 15160 * Parameters: 15161 * unit - (IN) Unit number. 15162 * phy_port - (IN) physical port num 15163 * Returns: 15164 * TRUE or FALSE 15165 */ 15166 STATIC int 15167 soc_mn_is_port_flex_enable(int unit, int phy_port) 15168 { 15169 int enable = 0; 15170 15171 /* This property does not apply to cpu port & 15172 * loopback port 15173 */ 15174 15175 if (phy_port > 0 && phy_port < 129) { 15176 enable = soc_property_phys_port_get(unit, 15177 phy_port, 15178 spn_PORT_FLEX_ENABLE, 0); 15179 } 15180 15181 return enable; 15182 } 15183 15184 15185 /* Tells if a port macro (indexed by TSC4, not TSC12) is flex port enabled. 15186 * 15187 * Port macro flex on or off is determined by the first port in that macro. 15188 * For TSC12 it's the first port in the first TSC4. For a TSC4 that is NOT 15189 * part of a TSC12, it's also the first port of that port macro. For a TSC4 15190 * that is a part of a TSC12, refer to the first port of the first port macro 15191 * for that TSC12. 15192 * 15193 * Parameters: 15194 * unit - (IN) Unit number. 15195 * port_macro - (IN) port macro desired 15196 * flex_enabled - (OUT) whether the port macro is enabled or disabled 15197 * 15198 * Returns: 15199 * SOC_E_xxx 15200 */ 15201 int 15202 soc_mn_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled) 15203 { 15204 int port_num = -1; 15205 15206 if ((port_macro < 0) || (port_macro > 18)) { 15207 return SOC_E_PARAM; 15208 } 15209 15210 port_num = (MONTEREY_PORTS_PER_TSC * port_macro) + 1; 15211 15212 *flex_enabled = soc_mn_is_port_flex_enable(unit, port_num); 15213 15214 return SOC_E_NONE; 15215 } 15216 15217 15218 /* 15219 * Function: 15220 * soc_monterey_port_icc_width_set 15221 * Purpose: 15222 * Program PORT_INITIAL_COPY_COUNT_WIDTHr 15223 * Parameters: 15224 * unit - (IN) Unit number. 15225 * port - (IN) Logical SOC port number. 15226 * Returns: 15227 * SOC_E_XXX 15228 */ 15229 STATIC int 15230 soc_monterey_port_icc_width_set(int unit, soc_port_t port) 15231 { 15232 int count_width = 0; 15233 15234 if (SOC_INFO(unit).port_speed_max[port] < 25000) { 15235 count_width = 1; /* 1 ICC bit */ 15236 } else if (SOC_INFO(unit).port_speed_max[port] <= 53000) { 15237 count_width = 2; /* 2 ICC bits */ 15238 } else { 15239 count_width = 3; /* 3 ICC bits */ 15240 } 15241 15242 SOC_IF_ERROR_RETURN( 15243 soc_reg_field32_modify(unit, PORT_INITIAL_COPY_COUNT_WIDTHr, 15244 port, BIT_WIDTHf, count_width ? (count_width - 1) : 0)); 15245 15246 return SOC_E_NONE; 15247 } 15248 15249 /* 15250 * Function: 15251 * soc_monterey_repl_port_agg_map_init 15252 * Purpose: 15253 * Initialize L3MC Port Agg Map. 15254 * Parameters: 15255 * unit - (IN) Unit number. 15256 * port - (IN) Logical SOC port number. 15257 * Returns: 15258 * SOC_E_xxx 15259 */ 15260 STATIC int 15261 soc_monterey_repl_port_agg_map_init(int unit, soc_port_t port) 15262 { 15263 soc_info_t *si; 15264 int phy_port, mmu_port; 15265 uint32 regval; 15266 15267 si = &SOC_INFO(unit); 15268 phy_port = si->port_l2p_mapping[port]; 15269 mmu_port = si->port_p2m_mapping[phy_port]; 15270 15271 /* configure mmu port to repl aggregateId map */ 15272 regval = 0; 15273 soc_reg_field_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr, ®val, 15274 L3MC_PORT_AGG_IDf, mmu_port % 74); 15275 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr, 15276 port,0,regval)); 15277 15278 return SOC_E_NONE; 15279 } 15280 15281 /* 15282 * Function: 15283 * soc_monterey_ipmc_repl_init 15284 * Purpose: 15285 * Initialize IPMC Replication settings 15286 * Parameters: 15287 * unit - (IN) Unit number. 15288 * port - (IN) Logical SOC port number. 15289 * Returns: 15290 * SOC_E_XXX 15291 */ 15292 STATIC int 15293 soc_monterey_ipmc_repl_init(int unit, soc_port_t port) 15294 { 15295 /* Program MMU_TOQ_REPL_PORT_AGG_MAP 15296 */ 15297 SOC_IF_ERROR_RETURN(soc_monterey_repl_port_agg_map_init(unit, port)); 15298 15299 return SOC_E_NONE; 15300 } 15301 15302 /* 15303 * Function: 15304 * soc_monterey_mmu_port_resource_set 15305 * Purpose: 15306 * Reconfigure MMU for flexport operation 15307 * Parameters: 15308 * unit - (IN) Unit number. 15309 * port - (IN) Logical SOC port number. 15310 * reset - (IN) Reset. 15311 * Returns: 15312 * SOC_E_XXX 15313 */ 15314 int soc_monterey_mmu_port_resource_set(int unit, soc_port_t port, int speed) 15315 { 15316 15317 /* Flex port operation not allowed on CPU or loopback port 15318 */ 15319 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 15320 return SOC_E_PARAM; 15321 } 15322 15323 /* Configure all MMU registers for new ports whose setting is 15324 * based on port speed. 15325 */ 15326 SOC_IF_ERROR_RETURN(soc_monterey_port_speed_update(unit, port, speed)); 15327 15328 /* Program PORT_INITIAL_COPY_COUNT_WIDTH 15329 */ 15330 SOC_IF_ERROR_RETURN(soc_monterey_port_icc_width_set(unit, port)); 15331 15332 /* Reconfigure IPMC replication 15333 */ 15334 SOC_IF_ERROR_RETURN(soc_monterey_ipmc_repl_init(unit, port)); 15335 15336 return SOC_E_NONE; 15337 } 15338 15339 /* 15340 * Function: 15341 * soc_monterey_is_any_port_flex_enable 15342 * Purpose: 15343 * Find out if 15344 * port_flex_enable=1 OR 15345 * port_flex_enable{physical port num}=1 15346 * config is present in config.bcm 15347 * Parameters: 15348 * unit - (IN) Unit number. 15349 * Returns: 15350 * TRUE or FALSE 15351 * If such a config is present, this function 15352 * returns 1 - implying that flex is enable on 15353 * at least 1 port (port macro) in the system 15354 * This function returns 0, if flex is not enabled 15355 * on any port (port macro) in the system 15356 */ 15357 int soc_monterey_is_any_port_flex_enable(int unit) 15358 { 15359 int phy_port, num_phy_port; 15360 15361 num_phy_port = 67; 15362 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 15363 if (soc_property_phys_port_get(unit, 15364 phy_port, 15365 spn_PORT_FLEX_ENABLE, 0)) { 15366 return TRUE; 15367 } 15368 } 15369 15370 return FALSE; 15371 } 15372 15373 15374 15375 15376 #if defined(SER_TR_TEST_SUPPORT) 15377 15378 #define MAX_HW_TCAMS 32 15379 typedef struct ser_monterey_skipped_mem_s { 15380 soc_mem_t mem; 15381 soc_acc_type_t acc_type; 15382 } ser_monterey_skipped_mem_t; 15383 15384 const ser_monterey_skipped_mem_t monterey_skipped_mems[] = { 15385 /* Below memories have only one entry */ 15386 {L2_BULK_MATCH_DATAm, _SOC_ACC_TYPE_PIPE_ANY}, 15387 {L2_BULK_MATCH_MASKm, _SOC_ACC_TYPE_PIPE_ANY}, 15388 {L2_BULK_REPLACE_DATAm, _SOC_ACC_TYPE_PIPE_ANY}, 15389 {L2_BULK_REPLACE_MASKm, _SOC_ACC_TYPE_PIPE_ANY}, 15390 {L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY}, 15391 {MPLS_ENTROPY_LABEL_DATAm, _SOC_ACC_TYPE_PIPE_ANY}, 15392 {ING_SNAT_ONLYm, _SOC_ACC_TYPE_PIPE_ANY}, 15393 15394 /* FP_GLOBAL_MASK_TCAM and FP_GM_FILEDSm have special handling in memscan 15395 * since H/W space is shared between these two mems. 15396 * It is protected by SW memscan SER engine 15397 */ 15398 {FP_GLOBAL_MASK_TCAMm, _SOC_ACC_TYPE_PIPE_ANY}, 15399 /* MMU_MTRO_EGRMETERINGCONFIG_MEM will be tested below two are for debug */ 15400 {MMU_MTRO_EGRMETERINGCONFIG_MEM_Am, _SOC_ACC_TYPE_PIPE_ANY}, 15401 {MMU_MTRO_EGRMETERINGCONFIG_MEM_Bm, _SOC_ACC_TYPE_PIPE_ANY}, 15402 /*debug memory*/ 15403 {MMU_MAPPER_X_LSBm, _SOC_ACC_TYPE_PIPE_ANY}, 15404 /*ser flags not proper in regfile*/ 15405 {EGR_LPORT_PROFILEm, _SOC_ACC_TYPE_PIPE_ANY}, 15406 /*Not able to write to this table need to check*/ 15407 {L3_ENTRY_LPm, _SOC_ACC_TYPE_PIPE_ANY}, 15408 {INVALIDm} 15409 }; 15410 15411 int 15412 ser_test_monterey_mem_index_remap(int unit, ser_test_data_t *test_data, 15413 int *mem_has_ecc) 15414 { 15415 int uft_bkt_bank = 0; 15416 int num_uft_banks = 0; 15417 int uft_le_fv = 0; 15418 int uft_le_ecc = 0; 15419 int remap_status = 0; 15420 15421 *mem_has_ecc = 0; 15422 test_data->mem = test_data->mem_fv; 15423 test_data->index = test_data->index_fv; 15424 15425 num_uft_banks = 0; 15426 switch (test_data->mem_fv) { 15427 case VLAN_XLATEm: 15428 case VLAN_MACm: 15429 test_data->mem = VLAN_XLATE_ECCm; 15430 *mem_has_ecc = 1; 15431 break; 15432 case EGR_VLAN_XLATEm: 15433 test_data->mem = EGR_VLAN_XLATE_ECCm; 15434 *mem_has_ecc = 1; 15435 break; 15436 case L2Xm: 15437 case L2_ENTRY_ONLYm: 15438 test_data->mem = L2_ENTRY_ONLY_ECCm; 15439 *mem_has_ecc = 1; 15440 break; 15441 case L3_ENTRY_ONLYm: 15442 case L3_ENTRY_IPV4_UNICASTm: 15443 test_data->mem = L3_ENTRY_ONLY_ECCm; 15444 test_data->index = test_data->index_fv; 15445 *mem_has_ecc = 1; 15446 break; 15447 case L3_ENTRY_IPV4_MULTICASTm: 15448 case L3_ENTRY_IPV6_UNICASTm: 15449 test_data->mem = L3_ENTRY_ONLY_ECCm; 15450 test_data->index = test_data->index_fv*2; 15451 *mem_has_ecc = 1; 15452 break; 15453 case L3_ENTRY_IPV6_MULTICASTm: 15454 test_data->mem = L3_ENTRY_ONLY_ECCm; 15455 test_data->index = test_data->index_fv*4; 15456 *mem_has_ecc = 1; 15457 break; 15458 case L3_DEFIP_ALPM_IPV4m: /* 6:4 */ 15459 *mem_has_ecc = 1; 15460 test_data->mem = L3_DEFIP_ALPM_ECCm; 15461 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks); 15462 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks); 15463 switch (uft_le_fv) { 15464 case 0: uft_le_ecc = 0; break; 15465 case 1: uft_le_ecc = 0; break; /* or 1 */ 15466 case 2: uft_le_ecc = 1; break; 15467 case 3: uft_le_ecc = 2; break; 15468 case 4: uft_le_ecc = 2; break; /* or 3 */ 15469 case 5: uft_le_ecc = 3; break; 15470 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15471 } 15472 test_data->index = (uft_le_ecc << 15473 _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15474 break; 15475 case L3_DEFIP_ALPM_IPV4_1m: /* 4:4 */ 15476 case L3_DEFIP_ALPM_IPV6_64m: 15477 *mem_has_ecc = 1; 15478 test_data->mem = L3_DEFIP_ALPM_ECCm; 15479 test_data->index = test_data->index_fv; 15480 break; 15481 case L3_DEFIP_ALPM_IPV6_64_1m: /* 3:4 */ 15482 *mem_has_ecc = 1; 15483 test_data->mem = L3_DEFIP_ALPM_ECCm; 15484 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks); 15485 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks); 15486 switch (uft_le_fv) { 15487 case 0: uft_le_ecc = 0; break; /* or 1 */ 15488 case 1: uft_le_ecc = 1; break; /* or 2 */ 15489 case 2: uft_le_ecc = 2; break; /* or 3 */ 15490 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15491 } 15492 test_data->index = (uft_le_ecc << 15493 _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15494 break; 15495 case L3_DEFIP_ALPM_IPV6_128m: /* 2:4 */ 15496 *mem_has_ecc = 1; 15497 test_data->mem = L3_DEFIP_ALPM_ECCm; 15498 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks); 15499 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks); 15500 switch (uft_le_fv) { 15501 case 0: uft_le_ecc = 0; break; /* or 1 */ 15502 case 1: uft_le_ecc = 2; break; /* or 3 */ 15503 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15504 } 15505 test_data->index = (uft_le_ecc << 15506 _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15507 break; 15508 case L3_DEFIP_ALPM_RAWm: /* 1:4 */ 15509 *mem_has_ecc = 1; 15510 test_data->mem = L3_DEFIP_ALPM_ECCm; 15511 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks); 15512 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks); 15513 switch (uft_le_fv) { 15514 case 0: uft_le_ecc = 0; break; /* or 1,2,3 */ 15515 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15516 } 15517 test_data->index = (uft_le_ecc << 15518 _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15519 break; 15520 default: 15521 test_data->mem = test_data->mem_fv; 15522 test_data->index = test_data->index_fv; 15523 break; 15524 } 15525 if ((test_data->mem != test_data->mem_fv) || 15526 (test_data->index != test_data->index_fv)) { 15527 LOG_VERBOSE(BSL_LS_SOC_SER, 15528 (BSL_META_U(unit, 15529 "unit %d, ser_test_mem_index_remap: " 15530 "mem_fv %s, index_fv %0d, mem %s, index %0d, " 15531 "uft_bkt_bank %0d, uft_le_fv %0d, " 15532 "uft_le_ecc %0d, remap_status %0d \n"), 15533 unit, SOC_MEM_NAME(unit, test_data->mem_fv), test_data->index_fv, 15534 SOC_MEM_NAME(unit, test_data->mem), test_data->index, 15535 uft_bkt_bank, uft_le_fv, uft_le_ecc, remap_status)); 15536 } 15537 return remap_status; 15538 } 15539 15540 int 15541 soc_monterey_mem_is_eligible_for_scan(int unit, soc_mem_t mem) 15542 { 15543 switch (mem) { 15544 case L3_DEFIP_ALPM_ECCm: 15545 case L2_ENTRY_LPm: 15546 case L3_ENTRY_LPm: 15547 case VLAN_XLATE_LPm: 15548 case EGR_VLAN_XLATE_LPm: 15549 case L2_ENTRY_ISS_LPm: 15550 case L3_ENTRY_ISS_LPm: 15551 return 1; 15552 15553 default: 15554 break; 15555 } 15556 return 0; 15557 } 15558 15559 int 15560 soc_monterey_ser_test_skip_check (int unit, soc_mem_t mem) 15561 { 15562 int i; 15563 15564 if (!SOC_MEM_IS_VALID(unit, mem) || 15565 ((mem != INVALIDm) && 15566 ((SOC_MEM_INFO(unit, mem).flags & 15567 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) { 15568 return 1; 15569 } 15570 15571 if (soc_mem_index_count(unit, mem) <= 0) { 15572 return 1; 15573 } 15574 15575 for (i = 0; monterey_skipped_mems[i].mem != INVALIDm; i++) { 15576 if (monterey_skipped_mems[i].mem == mem) { 15577 return 1; 15578 } 15579 } 15580 if (!(SOC_MEM_INFO(unit, mem).flags & SOC_MEM_SER_FLAGS)) { 15581 return 1; 15582 } 15583 /* Skip the memory if the relevant feature and memory is disabled. */ 15584 if (!soc_feature(unit, soc_feature_l3) 15585 || !soc_feature(unit, soc_feature_lpm_tcam) ) { 15586 /* Skip L3_DEFIP memorys */ 15587 if ((L3_DEFIPm == mem) || (L3_DEFIP_PAIR_128m == mem)) return 1; 15588 } 15589 if (!soc_feature(unit, soc_feature_l3) || 15590 soc_feature(unit, soc_feature_no_tunnel)) { 15591 /* Skip ING L3 Tunnel memorys */ 15592 if ((L3_TUNNELm == mem) || (L3_TUNNEL_DATA_ONLYm == mem)) return 1; 15593 } 15594 if (!soc_feature(unit, soc_feature_nat)) { 15595 /* Skip NAT memorys */ 15596 if (ING_SNATm == mem) return 1; 15597 } 15598 15599 /* Skip MPLS memories */ 15600 15601 if (ING_MPLS_EXP_MAPPINGm == mem) { 15602 return 1; 15603 } 15604 15605 return 0; 15606 } 15607 15608 STATIC 15609 soc_error_t 15610 _soc_monterey_tcam_ser_mem_info_get (int unit, soc_mem_t mem, int *index_p) 15611 { 15612 int i; 15613 _soc_generic_ser_info_t *tcams = _soc_monterey_tcam_ser_info[unit]; 15614 15615 for (i = 0; tcams[i].mem != INVALIDm; i++) { 15616 if (tcams[i].mem == mem) { 15617 *index_p = i; 15618 return SOC_E_NONE; 15619 } 15620 } 15621 return SOC_E_NOT_FOUND; 15622 } 15623 15624 STATIC soc_error_t 15625 _soc_monterey_ser_mem_info_get (int unit, soc_mem_t mem, _soc_mem_ser_en_info_t** ser_mem_info) 15626 { 15627 int i, j; 15628 _soc_mem_ser_en_info_t *ser_en_info = NULL; 15629 15630 for (i = 0; _soc_monterey_ser_block_info[i].blocktype != 0; i++) { 15631 if ((_soc_monterey_ser_block_info[i].type == _SOC_MONTEREY_SER_TYPE_MEM) && 15632 ((_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_IPIPE) || 15633 (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_EPIPE) || 15634 #ifdef INCLUDE_XFLOW_MACSEC 15635 (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MACSEC) || 15636 #endif 15637 (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MMU))) { 15638 ser_en_info = _soc_monterey_ser_block_info[i].info; 15639 for (j = 0; ser_en_info[j].mem != INVALIDm; j++) { 15640 if (ser_en_info[j].mem == mem) { 15641 *ser_mem_info = &ser_en_info[j]; 15642 return SOC_E_NONE; 15643 } 15644 } 15645 } 15646 } 15647 15648 return SOC_E_NOT_FOUND; 15649 } 15650 /* 15651 * Function: 15652 * soc_monterey_ser_error_injection_support 15653 * Purpose: 15654 * Checks if a memory is supported by error injection interface 15655 * 15656 * Parameters: 15657 * unit - (IN) Device Number 15658 * memory - (IN) Test data required for SER test 15659 * pipe - (IN) How many indices to test for each memory 15660 * 15661 * Returns: 15662 * SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported 15663 */ 15664 soc_error_t 15665 soc_monterey_ser_error_injection_support (int unit, soc_mem_t mem, 15666 int pipe) 15667 { 15668 int rv = SOC_E_UNAVAIL; 15669 _soc_mem_ser_en_info_t *ser_mem_info = NULL; 15670 int tcam_idx = 0; 15671 15672 if (soc_monterey_ser_test_skip_check (unit,mem)) { 15673 return rv; 15674 } 15675 15676 rv = _soc_monterey_ser_mem_info_get(unit, mem, &ser_mem_info); 15677 if (rv == SOC_E_NONE) { 15678 return rv; 15679 } 15680 15681 rv = _soc_monterey_tcam_ser_mem_info_get(unit, mem, &tcam_idx); 15682 if (rv == SOC_E_NONE) { 15683 return rv; 15684 } 15685 15686 return rv; 15687 } 15688 15689 /* 15690 * Function: 15691 * _soc_monterey_perform_ser_test 15692 * Purpose: 15693 * Performs test operations common to TCAM and FIFO memory tests before 15694 * invoking common SER test. 15695 * Parameters: 15696 * unit - (IN) Device Number 15697 * test_data - (IN) Test data required for SER test 15698 * test_type - (IN) How many indices to test for each memory 15699 * mem_failed - (OUT) Incremented when memories fail the test. 15700 * Returns: 15701 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors are 15702 * possible.) 15703 */ 15704 soc_error_t 15705 _soc_monterey_perform_ser_test (int unit, ser_test_data_t *test_data, 15706 _soc_ser_test_t test_type, 15707 int *mem_skipped, int *mem_failed) 15708 { 15709 int skip_mem = FALSE; 15710 soc_error_t rv = SOC_E_NONE; 15711 uint32 flags = 0; 15712 15713 if (soc_monterey_ser_test_skip_check (unit,test_data->mem)) { 15714 skip_mem = TRUE; 15715 } 15716 #ifdef INCLUDE_XFLOW_MACSEC 15717 if(soc_feature(unit, soc_feature_xflow_macsec) && 15718 ((ISEC_SP_TCAMm == test_data->mem) || 15719 (ISEC_SC_TCAMm == test_data->mem))) { 15720 skip_mem = TRUE; 15721 } 15722 #endif 15723 if (!skip_mem) { 15724 if (test_data->mem == ING_VLAN_VFI_MEMBERSHIPm || 15725 test_data->mem == MMU_MTRI_BKPMETERINGCONFIG_MEM_0m || 15726 test_data->mem == MMU_MTRO_EGRMETERINGCONFIG_MEMm) { 15727 flags |= SOC_INJECT_ERROR_2BIT_ECC; 15728 } 15729 rv = ser_test_mem(unit, flags, test_data, test_type, mem_failed); 15730 } else { 15731 LOG_VERBOSE(BSL_LS_SOC_COMMON, 15732 (BSL_META_U(unit, 15733 "Memory %s skipped due to known issues.\n"), 15734 SOC_MEM_NAME(unit,test_data->mem))); 15735 (*mem_skipped)++; 15736 } 15737 15738 return rv; 15739 } 15740 15741 /* 15742 * Function: 15743 * soc_monterey_ser_tcam_test 15744 * Purpose: 15745 * Tests that SER is working for fifo and SRAM memories 15746 * Parameters: 15747 * unit - (IN) Device Number 15748 * test_type - (IN) How many indices to test for each memory 15749 * Returns: 15750 * the number of tests which are failed 15751 */ 15752 int 15753 soc_monterey_ser_tcam_test (int unit, _soc_ser_test_t test_type) { 15754 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 15755 ser_test_data_t test_data; 15756 int mem_failed = 0, mem_tests = 0, mem_skipped = 0; 15757 _soc_generic_ser_info_t *tcams = _soc_monterey_tcam_ser_info[unit]; 15758 int i,rv=0; 15759 soc_acc_type_t acc_type; 15760 soc_field_t test_field = VALIDf; 15761 15762 for (i = 0; tcams[i].mem != INVALIDm; i++) { 15763 mem_tests++; 15764 if ( i >= MAX_HW_TCAMS) { 15765 mem_skipped++; 15766 LOG_VERBOSE(BSL_LS_SOC_COMMON, 15767 (BSL_META_U(unit, 15768 "Memory %s skipped due to lack of test mechanism \ 15769 for Software-protected TCAMS.\n"), 15770 SOC_MEM_NAME(unit,test_data.mem))); 15771 continue; 15772 } 15773 15774 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 15775 15776 if (tcams[i].mem == L3_DEFIPm) { 15777 test_field = VALID0f; 15778 } else if (tcams[i].mem == L3_DEFIP_PAIR_128m) { 15779 test_field = VALID0_LWRf; 15780 } else 15781 #ifdef INCLUDE_XFLOW_MACSEC 15782 if (soc_feature(unit, soc_feature_xflow_macsec) && 15783 (tcams[i].mem == ISEC_SP_TCAMm)) { 15784 test_field = MASKf; 15785 } else 15786 #endif 15787 { 15788 test_field = VALIDf; 15789 } 15790 15791 soc_ser_create_test_data(unit, tmp_entry, fieldData, SER_RANGE_ENABLEr, 15792 i, INVALIDf, tcams[i].mem, test_field, 15793 MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0, 15794 &test_data); 15795 15796 rv = _soc_monterey_perform_ser_test(unit, &test_data, test_type, 15797 &mem_skipped, &mem_failed); 15798 if (SOC_FAILURE(rv)) { 15799 LOG_CLI((BSL_META_U(unit, 15800 "TCAM SER test fail for mem: \t %s\n\n"), 15801 SOC_MEM_NAME(unit,test_data.mem))); 15802 } 15803 } 15804 15805 LOG_CLI((BSL_META_U(unit, 15806 "\nTCAM memories tested on unit %d: %d\n"), unit, mem_tests)); 15807 LOG_CLI((BSL_META_U(unit, 15808 "TCAM tests passed:\t%d\n"), 15809 mem_tests - mem_failed - mem_skipped)); 15810 LOG_CLI((BSL_META_U(unit, 15811 "TCAM tests skipped:\t%d (use verbose option to see " 15812 "skipped memories)\n"), 15813 mem_skipped)); 15814 LOG_CLI((BSL_META_U(unit, 15815 "TCAM tests failed:\t%d\n\n"), mem_failed)); 15816 15817 return mem_failed; 15818 } 15819 15820 /* 15821 * Function: 15822 * soc_monterey_ser_hardware_test 15823 * Purpose: 15824 * Tests that SER is working for fifo and SRAM memories 15825 * Parameters: 15826 * unit - (IN) Device Number 15827 * test_type - (IN) How many indices to test for each memory 15828 * Returns: 15829 * the number of tests which are failed 15830 */ 15831 int 15832 soc_monterey_ser_hardware_test (int unit, _soc_ser_test_t test_type) { 15833 ser_test_data_t test_data; 15834 int mem_failed = 0, mem_tests = 0, mem_skipped = 0; 15835 int i,j,rv; 15836 soc_acc_type_t acc_type; 15837 _soc_mem_ser_en_info_t *ser_en_info = NULL; 15838 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 15839 15840 for (i = 0; _soc_monterey_ser_block_info[i].blocktype != 0; i++) { 15841 if ((_soc_monterey_ser_block_info[i].type == _SOC_MONTEREY_SER_TYPE_MEM) && 15842 ((_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_IPIPE) || 15843 (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_EPIPE) || 15844 #ifdef INCLUDE_XFLOW_MACSEC 15845 (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MACSEC) || 15846 #endif 15847 (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MMU))) { 15848 ser_en_info = _soc_monterey_ser_block_info[i].info; 15849 for (j = 0; ser_en_info[j].mem != INVALIDm; j++) { 15850 mem_tests += 1; 15851 test_data.test_field = EVEN_PARITYf; 15852 acc_type = -1; 15853 soc_ser_create_test_data(unit, tmp_entry, fieldData, 15854 ser_en_info[j].en_ctrl.ctrl_type.en_reg, 15855 SOC_INVALID_TCAM_PARITY_BIT, 15856 ser_en_info[j].en_ctrl.en_fld, 15857 ser_en_info[j].mem, 15858 test_data.test_field, 15859 MEM_BLOCK_ANY, 15860 REG_PORT_ANY, acc_type, 0, 15861 &test_data); 15862 if ((test_data.mem_info == NULL) || 15863 (!(soc_mem_index_count(unit, ser_en_info[j].mem) > 0))) { 15864 mem_skipped++; 15865 LOG_VERBOSE(BSL_LS_SOC_COMMON, 15866 (BSL_META_U(unit, 15867 "Memory %s skipped due to lack of" 15868 " mem_info structure or being disabled.\n"), 15869 SOC_MEM_NAME(unit,test_data.mem))); 15870 continue; 15871 } 15872 rv = _soc_monterey_perform_ser_test(unit, &test_data, 15873 test_type, &mem_skipped, 15874 &mem_failed); 15875 if (SOC_FAILURE(rv)) { 15876 LOG_CLI((BSL_META_U(unit, 15877 " H/W SER test fail for mem: \t %s\n\n"), 15878 SOC_MEM_NAME(unit,test_data.mem))); 15879 } 15880 } 15881 } 15882 } 15883 15884 LOG_CLI((BSL_META_U(unit, 15885 "\nH/W memories tested on unit %d: %d\n"), unit, mem_tests)); 15886 LOG_CLI((BSL_META_U(unit, 15887 "H/W tests passed:\t%d\n"), 15888 mem_tests - mem_failed - mem_skipped)); 15889 LOG_CLI((BSL_META_U(unit, 15890 "H/W tests skipped:\t%d (use verbose option to see " 15891 "skipped memories)\n"), 15892 mem_skipped)); 15893 LOG_CLI((BSL_META_U(unit, 15894 "H/W tests failed:\t%d\n\n"), mem_failed)); 15895 return mem_failed; 15896 } 15897 15898 15899 /* 15900 * Function: 15901 * soc_monterey_ser_test 15902 * Purpose: 15903 * Tests that SER is working for all supported memories. 15904 * Parameters: 15905 * unit - (IN) Device Number 15906 * test_type - (IN) How many indices to test for each memory 15907 * Returns: 15908 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors are 15909 * possible.) 15910 */ 15911 soc_error_t 15912 soc_monterey_ser_test (int unit, _soc_ser_test_t test_type) { 15913 int errors = 0; 15914 15915 /*Test TCAM memories*/ 15916 errors += soc_monterey_ser_tcam_test(unit, test_type); 15917 15918 /*Test for FIFO memories*/ 15919 errors += soc_monterey_ser_hardware_test(unit, test_type); 15920 15921 if (errors == 0) { 15922 return SOC_E_NONE; 15923 } else { 15924 return SOC_E_FAIL; 15925 } 15926 } 15927 15928 #define TR_MEM_NAME_SIZE_MAX 100 15929 15930 #ifdef SOC_MEM_NAME 15931 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) do { \ 15932 const char *_mem_name = SOC_MEM_NAME(_unit_, _mem); \ 15933 if (sal_strlen(_mem_name) < TR_MEM_NAME_SIZE_MAX) { \ 15934 sal_strcpy(_msg, _mem_name); \ 15935 } \ 15936 } while (0) 15937 #else 15938 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) 15939 #endif 15940 15941 #define TR_TEST_MEM_PRINT(_unit, _msg, _mem) do { \ 15942 sal_sprintf(_msg, "Mem ID: %d", _mem); \ 15943 TR_TEST_MEM_NAME_GET(_unit, _msg, _mem); \ 15944 LOG_CLI((BSL_META_U(_unit, \ 15945 "Memory %s is valid, but not currently testable.\n"), \ 15946 _msg)); \ 15947 } while (0) 15948 15949 /* 15950 * Function: 15951 * soc_monterey_ser_inject_or_test_mem 15952 * Purpose: 15953 * Provide a common function for injecting errors and testing single 15954 * single memories 15955 * Parameters: 15956 * unit - (IN) Device Number 15957 * mem - (IN) The memory into which an error will be injected 15958 * pipeTarget - (IN) The pipe (x/y) to use when injecting the error 15959 * index - (IN) The index into which the error will be injected. 15960 * test_type - (IN) How many indices to test in the passes memory 15961 * cmd - (IN) TRUE if a command-line test is desired. 15962 * Returns: 15963 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors 15964 * are possible.) 15965 */ 15966 soc_error_t 15967 soc_monterey_ser_inject_or_test_mem (int unit, soc_mem_t mem, int pipe_target, 15968 int block, int index, 15969 _soc_ser_test_t test_type, 15970 int inject_only, int cmd, uint32 flags) 15971 { 15972 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 15973 ser_test_data_t tcam_test_data, hw_test_data, *test_data; 15974 int tcam_idx = 0; 15975 _soc_generic_ser_info_t *tcams = _soc_monterey_tcam_ser_info[unit]; 15976 int error_count = 0, skip_count = 0, found_mem = FALSE; 15977 char fail_message[400]; 15978 soc_error_t rv = SOC_E_NONE; 15979 soc_field_t test_field = INVALIDf; 15980 soc_acc_type_t soc_acc_type_target = _SOC_ACC_TYPE_PIPE_ANY; 15981 _soc_mem_ser_en_info_t * ser_mem_info = NULL; 15982 int mem_has_ecc = 0, is_tcam = 0, is_fifo_mem = 0; 15983 15984 15985 rv = _soc_monterey_tcam_ser_mem_info_get(unit, mem, &tcam_idx); 15986 if (rv == SOC_E_NONE) { 15987 if (tcams[tcam_idx].mem == L3_DEFIPm) { 15988 test_field = VALID0f; 15989 } else if (tcams[tcam_idx].mem == L3_DEFIP_PAIR_128m) { 15990 test_field = VALID0_LWRf; 15991 } else 15992 #ifdef INCLUDE_XFLOW_MACSEC 15993 if (soc_feature(unit, soc_feature_xflow_macsec) && 15994 (tcams[tcam_idx].mem == ISEC_SP_TCAMm)) { 15995 test_field = MASKf; 15996 } else 15997 #endif 15998 { 15999 test_field = VALIDf; 16000 } 16001 soc_ser_create_test_data(unit, tmp_entry, fieldData, 16002 SER_RANGE_ENABLEr, tcam_idx, INVALIDf, mem, 16003 test_field, block, REG_PORT_ANY, 16004 soc_acc_type_target, index, &tcam_test_data); 16005 found_mem = TRUE; 16006 is_tcam = 1; 16007 } 16008 16009 rv = _soc_monterey_ser_mem_info_get (unit, mem, &ser_mem_info); 16010 if (rv == SOC_E_NONE) { 16011 if (mem == ING_L3_NEXT_HOPm) { 16012 test_field= ECC_1f; 16013 } else { 16014 test_field = EVEN_PARITYf; 16015 } 16016 #ifdef INCLUDE_XFLOW_MACSEC 16017 /* ESEC_SA_TABLEm has 4 banks of memory with individyal SER control and status */ 16018 if (soc_feature(unit, soc_feature_xflow_macsec) && 16019 mem == ESEC_SA_TABLEm) { 16020 switch (index % 4) { 16021 case 0: 16022 ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL0r; 16023 ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL0r; 16024 break; 16025 case 1: 16026 ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL1r; 16027 ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL1r; 16028 break; 16029 case 2: 16030 ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL2r; 16031 ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL2r; 16032 break; 16033 case 3: 16034 ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL3r; 16035 ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL3r; 16036 break; 16037 default: 16038 break; 16039 } 16040 } 16041 #endif 16042 soc_ser_create_test_data(unit, tmp_entry, fieldData, 16043 ser_mem_info->en_ctrl.ctrl_type.en_reg, 16044 SOC_INVALID_TCAM_PARITY_BIT, 16045 ser_mem_info->en_ctrl.en_fld, 16046 mem, test_field, block, 16047 REG_PORT_ANY, soc_acc_type_target, 16048 index, &hw_test_data); 16049 if (SOC_REG_IS_VALID(unit, ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg) && 16050 (INVALIDf != ser_mem_info->ecc1b_ctrl.en_fld)) { 16051 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16052 } 16053 SOC_IF_ERROR_RETURN 16054 (ser_test_mem_index_remap(unit, &hw_test_data, &mem_has_ecc)); 16055 if (mem_has_ecc) { 16056 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16057 } 16058 /* ING_VLAN_VFI_MEMBERSHIP is ECC protected, however 16059 * there is no 1bit error reporting control register for it. 16060 */ 16061 if (mem == ING_VLAN_VFI_MEMBERSHIPm) { 16062 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16063 } 16064 found_mem = TRUE; 16065 is_fifo_mem = 1; 16066 } 16067 if (found_mem) { 16068 test_data = is_tcam ? &tcam_test_data : &hw_test_data; 16069 test_data->acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16070 if (inject_only) { 16071 /* Check if the memory is to be skipped */ 16072 if (soc_monterey_ser_test_skip_check(unit,mem)) { 16073 TR_TEST_MEM_PRINT(unit, fail_message, mem); 16074 return SOC_E_UNAVAIL; 16075 } 16076 16077 /*Disable parity*/ 16078 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, test_data, 0)); 16079 /*Read the memory (required for successful injection)*/ 16080 SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, test_data)); 16081 /*Inject error*/ 16082 SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags, 16083 test_data)); 16084 /*Enable parity*/ 16085 rv = _ser_test_parity_control(unit, test_data, 1); 16086 } else { 16087 if (cmd) { 16088 tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16089 ser_test_cmd_generate(unit, &tcam_test_data); 16090 hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16091 ser_test_cmd_generate(unit, &hw_test_data); 16092 } else { 16093 if (is_tcam) { 16094 tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16095 rv = _soc_monterey_perform_ser_test(unit, &tcam_test_data, test_type, 16096 &skip_count, &error_count); 16097 if (SOC_SUCCESS(rv)) { 16098 LOG_CLI((BSL_META_U(unit, 16099 "TCAM SER test PASSED for memory %s\n\n"), 16100 tcam_test_data.mem_name)); 16101 } else { 16102 LOG_CLI((BSL_META_U(unit, 16103 "TCAM SER test FAILED for memory %s\n\n"), 16104 tcam_test_data.mem_name)); 16105 } 16106 } 16107 16108 if (is_fifo_mem) { 16109 hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16110 rv = _soc_monterey_perform_ser_test(unit, &hw_test_data, test_type, 16111 &skip_count, &error_count); 16112 if (SOC_SUCCESS(rv)) { 16113 LOG_CLI((BSL_META_U(unit, 16114 "H/W SER test PASSED for memory %s\n\n"), 16115 hw_test_data.mem_name)); 16116 } else { 16117 LOG_CLI((BSL_META_U(unit, 16118 "H/W SER test FAILED for memory %s\n\n"), 16119 hw_test_data.mem_name)); 16120 } 16121 } 16122 16123 if (skip_count != 0 ) { 16124 LOG_CLI((BSL_META_U(unit, 16125 "Test skipped due to known issues with " 16126 "this memory.\n"))); 16127 } 16128 } 16129 } 16130 } else { 16131 TR_TEST_MEM_PRINT(unit, fail_message, mem); 16132 rv = SOC_E_UNAVAIL; 16133 } 16134 return rv; 16135 } 16136 #undef TR_TEST_MEM_PRINT 16137 16138 /* 16139 * Function: 16140 * soc_monterey_ser_inject_error 16141 * Purpose: 16142 * Injects an error into a single monterey memory 16143 * Parameters: 16144 * unit - (IN) Device Number 16145 * mem - (IN) The memory into which an error will be injected 16146 * pipeTarget - (IN) The pipe (x/y) to use when injecting the error 16147 * index - (IN) The index into which the error will be injected. 16148 */ 16149 soc_error_t 16150 soc_monterey_ser_inject_error (int unit, uint32 flags, soc_mem_t mem, 16151 int pipe_target, int block, int index) 16152 { 16153 /* Check if memory needs to be skipped */ 16154 if (ser_monterey_test_fun.injection_support) { 16155 SOC_IF_ERROR_RETURN( 16156 soc_monterey_ser_error_injection_support(unit, mem, pipe_target)); 16157 } 16158 16159 return soc_monterey_ser_inject_or_test_mem(unit, mem, pipe_target, block, 16160 index, SER_SINGLE_INDEX, TRUE, 16161 FALSE, flags); 16162 } 16163 16164 /* 16165 * Function: 16166 * soc_monterey_ser_test_mem 16167 * Purpose: 16168 * Perform SER test on a single memory, or generate a test the user can 16169 * enter by the command line. 16170 * Parameters: 16171 * unit - (IN) Device Number 16172 * mem - (IN) The memory into which an error will be injected 16173 * test_type - (IN) How many indices to test in the passes memory 16174 * cmd - (IN) TRUE if a command-line test is desired. 16175 * Returns: 16176 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors 16177 * are possible.) 16178 */ 16179 soc_error_t 16180 soc_monterey_ser_test_mem (int unit, soc_mem_t mem, _soc_ser_test_t test_type, 16181 int cmd) 16182 { 16183 return soc_monterey_ser_inject_or_test_mem (unit, mem, _SOC_ACC_TYPE_PIPE_ANY, 16184 MEM_BLOCK_ANY, 0, 16185 test_type, FALSE, cmd, FALSE); 16186 } 16187 #endif /*defined(SER_TR_TEST_SUPPORT)*/ 16188 16189 soc_error_t 16190 soc_monterey_gatingconfig_init(int unit) { 16191 16192 16193 uint32 rval = 0; 16194 16195 soc_reg_field_set(unit, IP_SER_CLK_GATE_CTRLr , &rval, DISABLE_CLK_GATEf, 1); 16196 SOC_IF_ERROR_RETURN(WRITE_IP_SER_CLK_GATE_CTRLr(unit ,rval)); 16197 rval = 0; 16198 soc_reg_field_set(unit, ICFG_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16199 soc_reg_field_set(unit, ICFG_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16200 soc_reg_field_set(unit, ICFG_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_IPRC_DATAf,1); 16201 SOC_IF_ERROR_RETURN(WRITE_ICFG_CLK_GATING_CONTROLr(unit ,rval)); 16202 rval = 0; 16203 soc_reg_field_set(unit, EGR_EFPPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16204 soc_reg_field_set(unit, EGR_EFPPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16205 soc_reg_field_set(unit, EGR_EFPPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1); 16206 SOC_IF_ERROR_RETURN(WRITE_EGR_EFPPARS_CLK_GATING_CONTROLr(unit ,rval)); 16207 rval = 0; 16208 16209 soc_reg_field_set(unit, EGR_EHCPM_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16210 soc_reg_field_set(unit, EGR_EHCPM_CLK_GATING_CONTROLr, &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16211 soc_reg_field_set(unit, EGR_EHCPM_CLK_GATING_CONTROLr, &rval, DISABLE_CLK_GATING_ARRAYSf,1); 16212 SOC_IF_ERROR_RETURN(WRITE_EGR_EHCPM_CLK_GATING_CONTROLr(unit ,rval)); 16213 rval = 0; 16214 16215 soc_reg_field_set(unit, IPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16216 soc_reg_field_set(unit, IPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16217 soc_reg_field_set(unit, IPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_IPRC_DATAf,1); 16218 SOC_IF_ERROR_RETURN(WRITE_IPARS_CLK_GATING_CONTROLr(unit ,rval)); 16219 rval = 0; 16220 16221 16222 soc_reg_field_set(unit, EGR_EIPT_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16223 soc_reg_field_set(unit, EGR_EIPT_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1); 16224 SOC_IF_ERROR_RETURN(WRITE_EGR_EIPT_CLK_GATING_CONTROLr(unit ,rval)); 16225 rval = 0; 16226 16227 soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16228 soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16229 soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_SER_STATUS_BUSf,1); 16230 soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1); 16231 SOC_IF_ERROR_RETURN(WRITE_EGR_EL3_CLK_GATING_CONTROLr(unit ,rval)); 16232 rval = 0; 16233 16234 soc_reg_field_set(unit,IVXLT_CONTROLr, &rval, DISABLE_CLK_GATINGf, 1); 16235 soc_reg_field_set(unit, IVXLT_CONTROLr , &rval, VLAN_XLATE_DISABLE_CLK_GATINGf, 1); 16236 SOC_IF_ERROR_RETURN(WRITE_IVXLT_CONTROLr(unit ,rval)); 16237 rval = 0; 16238 16239 soc_reg_field_set(unit, EGR_EPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16240 soc_reg_field_set(unit, EGR_EPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16241 soc_reg_field_set(unit, EGR_EPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1); 16242 SOC_IF_ERROR_RETURN(WRITE_EGR_EPMOD_CLK_GATING_CONTROLr(unit ,rval)); 16243 rval = 0; 16244 16245 soc_reg_field_set(unit, EGR_ESW_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16246 soc_reg_field_set(unit, EGR_ESW_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1); 16247 SOC_IF_ERROR_RETURN(WRITE_EGR_ESW_CLK_GATING_CONTROLr(unit ,rval)); 16248 rval = 0; 16249 16250 soc_reg_field_set(unit, EGR_ESW_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16251 SOC_IF_ERROR_RETURN(WRITE_EGR_ESW_CLK_GATING_CONTROLr(unit ,rval)); 16252 rval = 0; 16253 soc_reg_field_set(unit, IVP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16254 SOC_IF_ERROR_RETURN(WRITE_IVP_CLK_GATING_CONTROLr(unit ,rval)); 16255 rval = 0; 16256 soc_reg_field_set(unit, EGR_EVLAN_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16257 soc_reg_field_set(unit, EGR_EVLAN_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_IN_HASH_TABLESf, 1); 16258 soc_reg_field_set(unit, EGR_EVLAN_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1); 16259 SOC_IF_ERROR_RETURN(WRITE_EGR_EVLAN_CLK_GATING_CONTROLr(unit ,rval)); 16260 rval = 0; 16261 16262 soc_reg_field_set(unit, IMPLS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16263 SOC_IF_ERROR_RETURN(WRITE_IMPLS_CLK_GATING_CONTROLr(unit ,rval)); 16264 rval = 0; 16265 16266 soc_reg_field_set(unit,EGR_EFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16267 soc_reg_field_set(unit, EGR_EFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16268 soc_reg_field_set(unit, EGR_EFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1); 16269 WRITE_EGR_EFP_CLK_GATING_CONTROLr(unit ,rval); 16270 rval = 0; 16271 16272 soc_reg_field_set(unit,EGR_EFPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16273 soc_reg_field_set(unit, EGR_EFPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1); 16274 soc_reg_field_set(unit, EGR_EFPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1); 16275 WRITE_EGR_EFPMOD_CLK_GATING_CONTROLr(unit ,rval); 16276 16277 soc_reg_field_set(unit, IDISC_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16278 WRITE_IDISC_CLK_GATING_CONTROLr(unit ,rval); 16279 rval = 0; 16280 16281 soc_reg_field_set(unit, IL2LU_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16282 soc_reg_field_set(unit, IL2LU_CONTROLr , &rval, L2_ISS_DISABLE_CLK_GATINGf, 1); 16283 soc_reg_field_set(unit, IL2LU_CONTROLr , &rval, L2_IPRC_DATA_DISABLE_CLK_GATINGf, 1); 16284 SOC_IF_ERROR_RETURN(WRITE_IL2LU_CONTROLr(unit ,rval)); 16285 rval = 0; 16286 16287 soc_reg_field_set(unit, IL3LU_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16288 soc_reg_field_set(unit, IL3LU_CONTROLr , &rval, L3_ISS_DISABLE_CLK_GATINGf, 1); 16289 soc_reg_field_set(unit, IL3LU_CONTROLr , &rval, L3_IPRC_DATA_DISABLE_CLK_GATINGf, 1); 16290 SOC_IF_ERROR_RETURN(WRITE_IL3LU_CONTROLr(unit ,rval)); 16291 rval = 0; 16292 soc_reg_field_set(unit, ILPM_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16293 soc_reg_field_set(unit, ILPM_CONTROLr , &rval, LPM_IPRC_DATA_DISABLE_CLK_GATINGf, 1); 16294 SOC_IF_ERROR_RETURN(WRITE_ILPM_CONTROLr(unit ,rval)); 16295 rval = 0; 16296 16297 soc_reg_field_set(unit, IRSEL1_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16298 SOC_IF_ERROR_RETURN(WRITE_IRSEL1_CLK_GATING_CONTROLr(unit ,rval)); 16299 rval = 0; 16300 16301 soc_reg_field_set(unit, ISW1_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16302 SOC_IF_ERROR_RETURN(WRITE_ISW1_CLK_GATING_CONTROLr(unit ,rval)); 16303 rval = 0; 16304 16305 soc_reg_field_set(unit, IFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16306 SOC_IF_ERROR_RETURN(WRITE_IFP_CLK_GATING_CONTROLr(unit ,rval)); 16307 rval = 0; 16308 16309 soc_reg_field_set(unit, IRSEL2_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1); 16310 soc_reg_field_set(unit, IRSEL2_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1); 16311 SOC_IF_ERROR_RETURN(WRITE_IRSEL2_CLK_GATING_CONTROLr(unit ,rval)); 16312 rval = 0; 16313 16314 soc_reg_field_set(unit, ISW2_CLK_GATING_CTRLr , &rval, DISABLE_CLK_GATINGf, 1); 16315 soc_reg_field_set(unit, ISW2_CLK_GATING_CTRLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1); 16316 SOC_IF_ERROR_RETURN(WRITE_ISW2_CLK_GATING_CTRLr(unit ,rval)); 16317 rval = 0; 16318 return SOC_E_NONE; 16319 } 16320 16321 #ifdef INCLUDE_XFLOW_MACSEC 16322 /* 16323 * Function: 16324 * soc_monterey_process_macsec_intr 16325 * Description: 16326 * Monterey specific DPC function to service MACSEC interrupts 16327 * Parameters: 16328 * unit_vp - Device number 16329 * d1 - IRQ4 mask 16330 * d2 - IRQ4 number (to distinguish between 16331 * different types of interrupts). 16332 */ 16333 void 16334 soc_monterey_process_macsec_intr(void *unit_vp, void *d1, 16335 void *d2, void *d3, void *d4) 16336 { 16337 int unit = PTR_TO_INT(unit_vp); 16338 int irq4_num = PTR_TO_INT(d4); 16339 int mask = PTR_TO_INT(d2); 16340 uint8 rbi; 16341 const _soc_monterey_ser_route_block_t *rb; 16342 uint64 rb_rval64; 16343 16344 for (rbi = 0; ; rbi++) { 16345 rb = &_soc_monterey_macsec_ser_route_blocks_irq4[rbi]; 16346 if (rb->cmic_bit == 0) { 16347 break; 16348 } 16349 16350 if (rb->cmic_bit != (1 << irq4_num)) { 16351 continue; 16352 } 16353 /* Read per route block status register */ 16354 soc_reg_get(unit, rb->status_reg, REG_PORT_ANY, 0, &rb_rval64); 16355 if (COMPILER_64_IS_ZERO(rb_rval64)) { 16356 continue; 16357 } 16358 16359 /* Process ECC interrupts */ 16360 if(soc_reg64_field32_get(unit, rb->status_reg, rb_rval64, 16361 ECCERR_INTf)) { 16362 (void)xflow_macsec_process_ecc_intr(unit); 16363 } 16364 /* Process MACSEC functional interrupts */ 16365 (void)xflow_macsec_process_functional_intr(unit, rb_rval64); 16366 16367 } /* For loop */ 16368 16369 /* Enable the interrupts */ 16370 if (d2 != NULL) { 16371 (void)soc_cmicm_intr4_enable(unit, mask); 16372 } 16373 16374 return; 16375 } 16376 #endif 16377 /* 16378 * Function: 16379 * soc_monterey_process_pm_intr 16380 * Description: 16381 * Monterey specific DPC function to service PM interrupts 16382 * Parameters: 16383 * unit_vp - Device number 16384 * d1 - IRQ4 mask 16385 * d2 - IRQ4 number (to distinguish between 16386 * different types of interrupts). 16387 */ 16388 void 16389 soc_monterey_process_pm_intr(void *unit_vp, void *d1, 16390 void *d2, void *d3, void *d4) 16391 { 16392 int unit = PTR_TO_INT(unit_vp); 16393 int irq4_num = PTR_TO_INT(d4); 16394 int mask = PTR_TO_INT(d2); 16395 uint8 rbi; 16396 int port = -1, block_info_idx; 16397 const _soc_monterey_pm_cpri_intr_info_t *rb; 16398 portmod_cpri_ecc_intr_info_t ecc_info; 16399 _soc_monterey_pm_ecc_info_t pm_ecc_info; 16400 16401 for (rbi = 0; ; rbi++) { 16402 rb = &_soc_monterey_pm_cpri_intr_info_irq4[rbi]; 16403 if (rb->cmic_bit == 0) { 16404 break; 16405 } 16406 16407 if (rb->cmic_bit != (1 << irq4_num)) { 16408 continue; 16409 } 16410 16411 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 16412 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 16413 port = SOC_BLOCK_PORT(unit, block_info_idx); 16414 break; 16415 } 16416 } 16417 16418 if (port != -1) { 16419 16420 /* Process other CPRI interrupts */ 16421 (void)portmod_cpri_port_interrupt_process(unit, port); 16422 16423 memset(&ecc_info, 0, sizeof(ecc_info)); 16424 16425 /* Process ECC interrupts */ 16426 (void)portmod_cpri_port_ecc_interrupt_status_get(unit, port, 16427 &ecc_info); 16428 16429 /* Report ECC errors */ 16430 if (ecc_info.ecc_num_bits_err != PORTMOD_PM_CPRI_ECC_ERR_NONE) { 16431 pm_ecc_info.type = _SOC_PARITY_TYPE_ECC; 16432 pm_ecc_info.ecc_err_type = 16433 ecc_info.ecc_num_bits_err; 16434 pm_ecc_info.mem = ecc_info.err_mem_info; 16435 pm_ecc_info.mem_index = ecc_info.err_addr; 16436 pm_ecc_info.port = ecc_info.port; 16437 pm_ecc_info.mem_str = ecc_info.mem_str; 16438 16439 _soc_monterey_ser_process_pm_ecc(unit, 16440 ecc_info.port, &pm_ecc_info); 16441 16442 LOG_VERBOSE(BSL_LS_SOC_COMMON, 16443 (BSL_META_U(unit, "ECC interrupt info\n" 16444 "m - %s, ecc_num_bits - %d, addr %x\n"), 16445 SOC_MEM_NAME(unit, ecc_info.err_mem_info), 16446 ecc_info.ecc_num_bits_err, 16447 ecc_info.err_addr)); 16448 } 16449 } /* (port != -1) */ 16450 } /* For loop */ 16451 16452 /* Enable the interrupts */ 16453 if (d2 != NULL) { 16454 (void)soc_cmicm_intr4_enable(unit, mask); 16455 } 16456 16457 return; 16458 } 16459 16460 /* 16461 * Apache chip driver functions. 16462 */ 16463 soc_functions_t soc_monterey_drv_funs = { 16464 _soc_monterey_misc_init, 16465 _soc_monterey_mmu_init, 16466 _soc_monterey_age_timer_get, 16467 _soc_monterey_age_timer_max_get, 16468 _soc_monterey_age_timer_set, 16469 NULL, 16470 _soc_monterey_mdio_reg_read, 16471 _soc_monterey_mdio_reg_write, 16472 soc_monterey_bond_info_init, 16473 _soc_monterey_misc_deinit 16474 }; 16475 16476 16477 #endif /* BCM_MONTEREY_SUPPORT */