apache.c (650242B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: apache.c 8 * Purpose: 9 * Requires: 10 */ 11 12 #include <shared/bsl.h> 13 14 #include <sal/core/boot.h> 15 #include <soc/bradley.h> 16 #include <soc/drv.h> 17 #include <soc/error.h> 18 #include <soc/debug.h> 19 #include <soc/mem.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_APACHE_SUPPORT 29 #include <soc/iproc.h> 30 31 #ifdef ALPM_ENABLE 32 #include <soc/lpm.h> 33 #include <soc/alpm.h> 34 #include <soc/esw/alpm_int.h> 35 #endif /* ALPM_ENABLE */ 36 37 #include <soc/mmu_config.h> 38 #include <soc/post.h> 39 40 #include <soc/esw/portctrl.h> 41 #include <soc/bondoptions.h> 42 43 #ifdef PORTMOD_SUPPORT 44 #include <soc/portmod/portmod.h> 45 #endif /* PORTMOD_SUPPORT */ 46 47 48 #define APACHE_PORTS_PER_TSC 4 49 #define APACHE_TSCS_PER_PGW 9 50 #define APACHE_NUM_XLP_PER_PGW 7 51 #define APACHE_NUM_CLP_PER_PGW 2 52 #define APACHE_PGWS_PER_DEV 2 53 #define APACHE_PGW0 0 54 #define APACHE_PGW1 1 55 56 #define APACHE_PORTS_PER_PGW (APACHE_PORTS_PER_TSC * APACHE_TSCS_PER_PGW) 57 #define APACHE_PORTS_PER_PIPE (APACHE_PORTS_PER_PGW * APACHE_PGWS_PER_DEV) 58 59 #define _APACHE_BYTES_PER_OBM_CELL 16 60 #define _APACHE_CELLS_PER_OBM 1020 61 62 #define _APACHE_LOG_PORTS_PER_PIPE 75 63 #define _APACHE_MMU_PORTS_PER_PIPE 75 64 #define _SOC_APACHE_MAX_PORT (_APACHE_LOG_PORTS_PER_PIPE) 65 66 #define _APACHE_MMU_PACKET_HEADER_BYTES 64 /* bytes */ 67 #define _APACHE_MMU_JUMBO_FRAME_BYTES 9216 /* bytes */ 68 #define _APACHE_MMU_DEFAULT_MTU_BYTES 1536 /* bytes */ 69 70 #define _APACHE_MMU_BYTES_PER_CELL 208 /* bytes (1664 bits) */ 71 #define _APACHE_MMU_NUM_PG 8 72 #define _APACHE_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE 50 73 #define _APACHE_MMU_PG_MIN 8 74 75 #define SOC_APACHE_MMU_CFG_QGROUP_MAX 128 76 77 #define SOC_APACHE_MMU_MCQ_ENTRY 31540 78 #define SOC_APACHE_MMU_RQE_ENTRY 3936 79 80 #define _APACHE_MMU_TOTAL_MCQ_ENTRY(unit) SOC_APACHE_MMU_MCQ_ENTRY 81 82 #define _APACHE_MMU_TOTAL_RQE_ENTRY(unit) SOC_APACHE_MMU_RQE_ENTRY 83 84 #define _SOC_APACHE_DEFIP_MAX_TCAMS 8 85 #define _SOC_APACHE_DEFIP_TCAM_DEPTH 1024 86 87 #define IS_OVERSUB_PORT(unit,port) \ 88 (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) 89 90 /* 91 * TDM algo does not support all speeds. SDK needs to adjust 92 * the speeds to what is supported in the algorithm. 93 * 94 * For FB5 LR ports: 95 * Anything < 1G will be passed as 1G. 96 * 5G needs to be passed as 10G. 97 * 2.5G is supported in the TDM. We can pass as is. 98 * 99 * For OS and MV LR ports: 100 * Anything < 10G will be passed as 10G 101 */ 102 #define APACHE_TDM_SPEED_ADJUST(unit, port, speed) \ 103 do { \ 104 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed); \ 105 if ((speed > 0) && (speed < 10000)) { \ 106 if (SOC_INFO(unit).oversub_mode != 2) { \ 107 speed = 10000; \ 108 } else if (IS_OVERSUB_PORT(unit, port)) { \ 109 speed = 10000; \ 110 } else if (speed < 1000) { \ 111 speed = 1000; \ 112 } else if (speed == 5000) { \ 113 speed = 10000; \ 114 } \ 115 } \ 116 } while (0) 117 118 #define INVALID_PORT -1 119 120 /* defines for Reserved Buffer for Flex Port Macro when new Flex Port is 121 enabled */ 122 /* lossless defines */ 123 #define _AP_RSVD_BUF_10G_FLEX_HDRM_LOSSLESS 185 124 #define _AP_RSVD_BUF_25G_FLEX_HDRM_LOSSLESS 214 125 126 #define _AP_RSVD_BUF_FLEX_QGRP 16 127 #define _AP_RSVD_BUF_10G_FLEX_ASF 4 128 #define _AP_RSVD_BUF_25G_FLEX_ASF 16 129 130 /* defines for Reserved Buffer for Ports when Flex Port for the macro is NOT 131 enabled*/ 132 #define _AP_RSVD_BUF_NON_FLEX_OB_100G_HDRM_LOSSLESS 687 133 #define _AP_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS 558 134 #define _AP_RSVD_BUF_NON_FLEX_OB_50G_HDRM_LOSSLESS 352 135 #define _AP_RSVD_BUF_NON_FLEX_50G_HDRM_LOSSLESS 298 136 #define _AP_RSVD_BUF_NON_FLEX_OB_40G_HDRM_LOSSLESS 338 137 #define _AP_RSVD_BUF_NON_FLEX_40G_HDRM_LOSSLESS 284 138 #define _AP_RSVD_BUF_NON_FLEX_OB_25G_HDRM_LOSSLESS 214 139 #define _AP_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS 191 140 #define _AP_RSVD_BUF_NON_FLEX_OB_20G_HDRM_LOSSLESS 206 141 #define _AP_RSVD_BUF_NON_FLEX_20G_HDRM_LOSSLESS 183 142 #define _AP_RSVD_BUF_NON_FLEX_OB_10G_HDRM_LOSSLESS 185 143 #define _AP_RSVD_BUF_NON_FLEX_10G_HDRM_LOSSLESS 162 144 #define _AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS 8 145 #define _AP_RSVD_BUF_NON_FLEX_PGMIN 8 146 #define _AP_RSVD_BUF_NON_FLEX_QGRP 16 147 #define _AP_RSVD_BUF_NON_FLEX_ASF 16 148 #define _AP_RSVD_BUF_NON_FLEX_10G_ASF 4 149 /* mmu_mc_egr_qentry_min in Settings sheet */ 150 #define _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD 4 151 #define _AP_RSVD_BUF_10G_FLEX_QGRP 16 152 #define _AP_MMU_NUM_MCQ_PORT_MACRO 10 153 #define _AP_MMU_RDB_PORT_MIN 90 154 155 156 int soc_apache_is_any_port_flex_enable(int unit); 157 int soc_ap_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled); 158 159 typedef enum { 160 _SOC_PARITY_TYPE_NONE, 161 _SOC_PARITY_TYPE_GENERIC, 162 _SOC_PARITY_TYPE_PARITY, 163 _SOC_PARITY_TYPE_ECC, 164 _SOC_PARITY_TYPE_CXXPORT, 165 _SOC_PARITY_TYPE_MMU_SER, 166 _SOC_PARITY_TYPE_START_ERR, 167 _SOC_PARITY_TYPE_SER, 168 _SOC_PARITY_TYPE_BST, 169 _SOC_PARITY_TYPE_MAC_RX_CDC, 170 _SOC_PARITY_TYPE_MAC_TX_CDC, 171 _SOC_PARITY_TYPE_MAC_RX_TS, 172 _SOC_PARITY_TYPE_MIB 173 } _soc_apache_ser_info_type_t; 174 175 typedef struct _soc_apache_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_apache_fifo_ser_info_t; 184 185 typedef struct _soc_apache_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_apache_ser_block_info_t; 192 193 typedef struct _soc_apache_ser_reg_s { 194 soc_reg_t reg; 195 char *mem_str; 196 } _soc_apache_ser_reg_t; 197 198 typedef struct _soc_apache_ser_info_s { 199 _soc_apache_ser_info_type_t type; 200 struct _soc_apache_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_apache_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_apache_ser_info_t; 214 215 typedef struct _soc_apache_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_apache_ser_info_t *info; 222 uint8 id; 223 } _soc_apache_ser_route_block_t; 224 225 typedef struct _soc_apache_mmu_traffic_ctrl_s { 226 uint8 thdo_drop_bmp[_SOC_APACHE_MAX_PORT]; 227 } _soc_apache_mmu_traffic_ctrl_t; 228 229 typedef struct _soc_ap_mmu_buffer_config_s { 230 int total_physical_memory; 231 int cfapfullsetpoint; 232 int total_cell_memory; 233 int num_mem_banks; 234 int num_10g_ports; 235 int num_20g_ports; 236 int num_25g_ports; 237 int num_40g_ports; 238 int num_100g_ports; 239 int num_ovsb_10g_ports; 240 int num_ovsb_20g_ports; 241 int num_ovsb_25g_ports; 242 int num_ovsb_40g_ports; 243 int num_ovsb_100g_ports; 244 } _soc_ap_mmu_buffer_config_t; 245 246 #define _AP_NUM_SKEWS 3 247 STATIC _soc_ap_mmu_buffer_config_t soc_ap_buffer_config[_AP_NUM_SKEWS] = { 248 { 65536, 61376, 60495, 16, 50, 0, 4, 0, 0, 50, 0, 0, 4, 0 }, 249 { 53248, 46016, 45372, 13, 72, 0, 0, 0, 0, 72, 0, 0, 0, 0 }, 250 { 36864, 30656, 30248, 9, 0, 0, 4, 11, 0, 0, 0, 4, 11, 0 } 251 }; 252 STATIC int _soc_ap_skew_index; 253 254 #define _APACHE_MMU_PHYSICAL_CELLS \ 255 soc_ap_buffer_config[_soc_ap_skew_index].total_physical_memory 256 257 #define _APACHE_CFAPFULLSETPOINT \ 258 soc_ap_buffer_config[_soc_ap_skew_index].cfapfullsetpoint 259 #define _APACHE_MMU_RSVD_CELLS_CFAP \ 260 soc_ap_buffer_config[_soc_ap_skew_index].num_mem_banks * \ 261 (23 + 2 + 10) 262 263 #define _APACHE_MMU_TOTAL_CELLS \ 264 soc_ap_buffer_config[_soc_ap_skew_index].total_cell_memory 265 266 #define MAC_ENABLE_SET_CTRL (1 << 0) 267 #define MMU_TRAFFIC_EN_CTRL (1 << 1) 268 #define COSQ_SCHED_SET_CTRL (1 << 2) 269 static _soc_apache_mmu_traffic_ctrl_t 270 *_soc_apache_mmu_traffic_ctrl[SOC_MAX_NUM_DEVICES]; 271 static sal_mutex_t _fwd_ctrl_lock[SOC_MAX_NUM_DEVICES]; 272 #define FWD_CTRL_LOCK(unit) \ 273 sal_mutex_take(_fwd_ctrl_lock[unit], sal_mutex_FOREVER) 274 #define FWD_CTRL_UNLOCK(unit) \ 275 sal_mutex_give(_fwd_ctrl_lock[unit]) 276 277 /* Forward declarations */ 278 STATIC int 279 _soc_apache_mdio_reg_read(int unit, uint32 phy_addr, 280 uint32 phy_reg, uint32 *phy_data); 281 STATIC int 282 _soc_apache_mdio_reg_write(int unit, uint32 phy_addr, 283 uint32 phy_reg, uint32 phy_data); 284 285 #define _SOC_APACHE_SER_TYPE_REG 0 286 #define _SOC_APACHE_SER_TYPE_MEM 1 287 #define _SOC_APACHE_SER_TYPE_BUS 2 288 #define _SOC_APACHE_SER_TYPE_BUF 3 289 290 /* These are now generated from the regsfile processing into bcm56560_a0.c 291 structures are defined in chip.h */ 292 #if defined(BCM_56560_A0) 293 extern _soc_mem_ser_en_info_t _soc_bcm56560_a0_ip_mem_ser_info[]; 294 extern _soc_reg_ser_en_info_t _soc_bcm56560_a0_ip_reg_ser_info[]; 295 extern _soc_mem_ser_en_info_t _soc_bcm56560_a0_ep_mem_ser_info[]; 296 extern _soc_reg_ser_en_info_t _soc_bcm56560_a0_ep_reg_ser_info[]; 297 extern _soc_mem_ser_en_info_t _soc_bcm56560_a0_mmu_mem_ser_info[]; 298 299 /* These can be re-used from TD2P. As naming is SOC independent 300 * and information is same we'll reuse them here 301 */ 302 extern _soc_bus_ser_en_info_t _soc_ip_bus_ser_info[]; 303 extern _soc_buffer_ser_en_info_t _soc_ip_buffer_ser_info[]; 304 extern _soc_buffer_ser_en_info_t _soc_mmu_buffer_ser_info[]; 305 306 static _soc_bus_ser_en_info_t _soc_ep_bus_ser_info [] = { 307 { "EFP", EFP_PARITY_CONTROLr, EFP_BUS_PARITY_ENf }, 308 { "EFPPARS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_BUS_PARITY_ENf }, 309 { "EHCPM", EGR_EHCPM_SER_CONTROLr, EHCPM_BUS_PARITY_ENf }, 310 { "EPMOD", EGR_EPMOD_SER_CONTROLr, EPMOD_BUS_PARITY_ENf }, 311 { "EVLAN", EGR_VLAN_SER_CONTROLr, EVLAN_BUS_PARITY_ENf }, 312 { "", INVALIDr } /* end */ 313 }; 314 315 static _soc_buffer_ser_en_info_t _soc_ep_buffer_ser_info[] = { 316 { "INITBUF", EGR_EL3_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf }, 317 { "EGR MPB", EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf }, 318 { "EDB_CM_MEM", EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf }, 319 { "XLP13_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP13_ECC_ENf }, 320 { "XLP12_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP12_ECC_ENf }, 321 { "XLP11_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP11_ECC_ENf }, 322 { "XLP10_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP10_ECC_ENf }, 323 { "XLP9_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP9_ECC_ENf }, 324 { "XLP8_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP8_ECC_ENf }, 325 { "XLP7_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP7_ECC_ENf }, 326 { "XLP6_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP6_ECC_ENf }, 327 { "XLP5_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf }, 328 { "XLP4_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf }, 329 { "XLP3_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf }, 330 { "XLP2_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf }, 331 { "XLP1_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf }, 332 { "XLP0_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf }, 333 { "CLP5_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP5_ECC_ENf }, 334 { "CLP4_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP4_ECC_ENf }, 335 { "CLP3_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP3_ECC_ENf }, 336 { "CLP2_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP2_ECC_ENf }, 337 { "CLP1_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP1_ECC_ENf }, 338 { "CLP0_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, CLP0_ECC_ENf }, 339 { "EP_XLP13_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP13_ECC_ENf }, 340 { "EP_XLP12_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP12_ECC_ENf }, 341 { "EP_XLP11_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP11_ECC_ENf }, 342 { "EP_XLP10_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP10_ECC_ENf }, 343 { "EP_XLP9__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP9_ECC_ENf }, 344 { "EP_XLP8__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP8_ECC_ENf }, 345 { "EP_XLP7__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP7_ECC_ENf }, 346 { "EP_XLP6__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP6_ECC_ENf }, 347 { "EP_XLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP5_ECC_ENf }, 348 { "EP_XLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP4_ECC_ENf }, 349 { "EP_XLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP3_ECC_ENf }, 350 { "EP_XLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP2_ECC_ENf }, 351 { "EP_XLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP1_ECC_ENf }, 352 { "EP_XLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP0_ECC_ENf }, 353 { "EP_CLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP5_ECC_ENf }, 354 { "EP_CLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP4_ECC_ENf }, 355 { "EP_CLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP3_ECC_ENf }, 356 { "EP_CLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP2_ECC_ENf }, 357 { "EP_CLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP1_ECC_ENf }, 358 { "EP_CLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP0_ECC_ENf }, 359 360 361 { "", INVALIDr } 362 }; 363 364 static const _soc_apache_ser_block_info_t _soc_apache_ser_block_info[] = { 365 { _SOC_APACHE_SER_TYPE_REG, SOC_BLK_IPIPE, "IPIPE regs", INVALIDr, _soc_bcm56560_a0_ip_reg_ser_info }, 366 { _SOC_APACHE_SER_TYPE_MEM, SOC_BLK_IPIPE, "IPIPE mems", ING_SER_FIFO_CTRLr, _soc_bcm56560_a0_ip_mem_ser_info }, 367 { _SOC_APACHE_SER_TYPE_BUS, SOC_BLK_EPIPE, "IPIPE buses",INVALIDr, _soc_ip_bus_ser_info }, 368 { _SOC_APACHE_SER_TYPE_BUF, SOC_BLK_EPIPE, "IPIPE buff" ,INVALIDr, _soc_ip_buffer_ser_info }, 369 { _SOC_APACHE_SER_TYPE_REG, SOC_BLK_EPIPE, "EPIPE regs", INVALIDr, _soc_bcm56560_a0_ep_reg_ser_info }, 370 { _SOC_APACHE_SER_TYPE_BUS, SOC_BLK_EPIPE, "EPIPE buses",INVALIDr, _soc_ep_bus_ser_info }, 371 { _SOC_APACHE_SER_TYPE_BUF, SOC_BLK_EPIPE, "EPIPE buff" ,INVALIDr, _soc_ep_buffer_ser_info }, 372 { _SOC_APACHE_SER_TYPE_MEM, SOC_BLK_EPIPE, "EPIPE mems", EGR_SER_FIFO_CTRLr, _soc_bcm56560_a0_ep_mem_ser_info }, 373 { _SOC_APACHE_SER_TYPE_MEM, SOC_BLK_MMU, "MMU mems", INVALIDr, _soc_bcm56560_a0_mmu_mem_ser_info }, 374 { _SOC_APACHE_SER_TYPE_BUF, SOC_BLK_MMU, "MMU buff", INVALIDr, _soc_mmu_buffer_ser_info }, 375 { -1, 0 } 376 }; 377 378 379 STATIC _soc_apache_ser_info_t _soc_apache_mmu_ser_info[] = { 380 { _SOC_PARITY_TYPE_GENERIC, NULL, 0, 381 DEQ_NOT_IP_ERR_ENf, 382 DEQ_NOT_IP_ERRf, 383 INVALIDm, "MMU DEQ NOT IP", 384 INVALIDr, INVALIDf, 385 INVALIDr, NULL, 386 INVALIDr, INVALIDf, NULL }, 387 { _SOC_PARITY_TYPE_START_ERR, NULL, 0, 388 START_BY_START_ERR_ENf, 389 START_BY_START_ERRf, 390 INVALIDm, "MMU START BY START", 391 INVALIDr, INVALIDf, 392 INVALIDr, NULL, 393 INVALIDr, INVALIDf, NULL }, 394 { _SOC_PARITY_TYPE_MMU_SER, NULL, 0, 395 MEM_PAR_ERR_ENf, 396 MEM_PAR_ERRf, 397 INVALIDm, "MMU MEM PAR", 398 INVALIDr, INVALIDf, 399 MEM_FAIL_INT_STATr, NULL, 400 MEM_FAIL_INT_CLEARr, MEM_PAR_ERR_CLRf, NULL }, 401 { _SOC_PARITY_TYPE_BST, NULL, 0, 402 INVALIDf, 403 BST_THDI_INTf, 404 INVALIDm, NULL, 405 INVALIDr, INVALIDf, 406 INVALIDr, NULL, 407 INVALIDr, INVALIDf, NULL }, 408 { _SOC_PARITY_TYPE_BST, NULL, 0, 409 INVALIDf, 410 BST_THDO_INTf, 411 INVALIDm, NULL, 412 INVALIDr, INVALIDf, 413 INVALIDr, NULL, 414 INVALIDr, INVALIDf, NULL }, 415 { _SOC_PARITY_TYPE_BST, NULL, 0, 416 INVALIDf, 417 BST_CFAP_INTf, 418 INVALIDm, NULL, 419 INVALIDr, INVALIDf, 420 INVALIDr, NULL, 421 INVALIDr, INVALIDf, NULL }, 422 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 423 }; 424 425 STATIC _soc_apache_ser_reg_t _soc_apache_pg_bod_status_reg[] = { 426 { PGW_BOD_XLP0_ECC_STATUSr, "PGW BOD XLP0 ECC" }, 427 { PGW_BOD_XLP1_ECC_STATUSr, "PGW BOD XLP1 ECC" }, 428 { PGW_BOD_XLP2_ECC_STATUSr, "PGW BOD XLP2 ECC" }, 429 { PGW_BOD_XLP3_ECC_STATUSr, "PGW BOD XLP3 ECC" }, 430 { PGW_BOD_XLP4_ECC_STATUSr, "PGW BOD XLP4 ECC" }, 431 { PGW_BOD_XLP5_ECC_STATUSr, "PGW BOD XLP5 ECC" }, 432 { PGW_BOD_XLP6_ECC_STATUSr, "PGW BOD XLP6 ECC" }, 433 { PGW_BOD_CLP0_ECC_STATUSr, "PGW BOD CLP0 ECC" }, 434 { PGW_BOD_CLP1_ECC_STATUSr, "PGW BOD CLP1 ECC" }, 435 { INVALIDr } 436 }; 437 438 STATIC _soc_apache_ser_info_t _soc_apache_pg_ser_info[] = { 439 { _SOC_PARITY_TYPE_ECC, NULL, 0, 440 PGW_OBM_PERR_INTRf, 441 PGW_OBM_PERR_INTRf, 442 INVALIDm, "PGW OBM0", 443 IDB_OBM0_SER_CONTROLr, DATA_ECC_ENABLEf, 444 IDB_OBM0_DATA_ECC_STATUSr, NULL, 445 INVALIDr, INVALIDf, NULL }, 446 { _SOC_PARITY_TYPE_ECC, NULL, 0, 447 PGW_OBM_PERR_INTRf, 448 PGW_OBM_PERR_INTRf, 449 INVALIDm, "PGW OBM1", 450 IDB_OBM1_SER_CONTROLr, DATA_ECC_ENABLEf, 451 IDB_OBM1_DATA_ECC_STATUSr, NULL, 452 INVALIDr, INVALIDf, NULL }, 453 { _SOC_PARITY_TYPE_ECC, NULL, 0, 454 PGW_OBM_PERR_INTRf, 455 PGW_OBM_PERR_INTRf, 456 INVALIDm, "PGW OBM2", 457 IDB_OBM2_SER_CONTROLr, DATA_ECC_ENABLEf, 458 IDB_OBM2_DATA_ECC_STATUSr, NULL, 459 INVALIDr, INVALIDf, NULL }, 460 { _SOC_PARITY_TYPE_ECC, NULL, 0, 461 PGW_OBM_PERR_INTRf, 462 PGW_OBM_PERR_INTRf, 463 INVALIDm, "PGW OBM3", 464 IDB_OBM3_SER_CONTROLr, DATA_ECC_ENABLEf, 465 IDB_OBM3_DATA_ECC_STATUSr, NULL, 466 INVALIDr, INVALIDf, NULL }, 467 { _SOC_PARITY_TYPE_ECC, NULL, 0, 468 PGW_OBM_PERR_INTRf, 469 PGW_OBM_PERR_INTRf, 470 INVALIDm, "PGW OBM4", 471 IDB_OBM4_SER_CONTROLr, DATA_ECC_ENABLEf, 472 IDB_OBM4_DATA_ECC_STATUSr, NULL, 473 INVALIDr, INVALIDf, NULL }, 474 { _SOC_PARITY_TYPE_ECC, NULL, 0, 475 PGW_OBM_PERR_INTRf, 476 PGW_OBM_PERR_INTRf, 477 INVALIDm, "PGW OBM5", 478 IDB_OBM5_SER_CONTROLr, DATA_ECC_ENABLEf, 479 IDB_OBM5_DATA_ECC_STATUSr, NULL, 480 INVALIDr, INVALIDf, NULL }, 481 { _SOC_PARITY_TYPE_ECC, NULL, 0, 482 PGW_OBM_PERR_INTRf, 483 PGW_OBM_PERR_INTRf, 484 INVALIDm, "PGW OBM6", 485 IDB_OBM6_SER_CONTROLr, DATA_ECC_ENABLEf, 486 IDB_OBM6_DATA_ECC_STATUSr, NULL, 487 INVALIDr, INVALIDf, NULL }, 488 { _SOC_PARITY_TYPE_ECC, NULL, 0, 489 PGW_OBM_PERR_INTRf, 490 PGW_OBM_PERR_INTRf, 491 INVALIDm, "PGW OBM7", 492 IDB_OBM7_SER_CONTROLr, DATA_ECC_ENABLEf, 493 IDB_OBM7_DATA_ECC_STATUSr, NULL, 494 INVALIDr, INVALIDf, NULL }, 495 { _SOC_PARITY_TYPE_ECC, NULL, 0, 496 PGW_OBM_PERR_INTRf, 497 PGW_OBM_PERR_INTRf, 498 INVALIDm, "PGW OBM8", 499 IDB_OBM8_SER_CONTROLr, DATA_ECC_ENABLEf, 500 IDB_OBM8_DATA_ECC_STATUSr, NULL, 501 INVALIDr, INVALIDf, NULL }, 502 { _SOC_PARITY_TYPE_ECC, NULL, 0, 503 PGW_BOD_PERR_INTRf, 504 PGW_BOD_PERR_INTRf, 505 INVALIDm, "PGW BOD", 506 PGW_BOD_ECC_ENABLEr, BOD_ECC_ENABLEf, 507 INVALIDr, _soc_apache_pg_bod_status_reg, 508 INVALIDr, INVALIDf, NULL }, 509 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 510 }; 511 512 static const 513 _soc_apache_ser_route_block_t _soc_apache_ser_route_blocks_irq3[] = { 514 { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */ 515 SOC_BLK_MMU, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, INVALIDf, 516 _soc_apache_mmu_ser_info, 0 }, 517 { 0x00000002, /* EP1_TO_CMIC_PERR_INTR */ 518 SOC_BLK_EPIPE, EGR_INTR_ENABLEr, EGR_INTR_STATUSr, SER_FIFO_NON_EMPTYf, NULL, 0 }, 519 { 0x00000004, /* EP2_TO_CMIC_PERR_INTR */ 520 SOC_BLK_EPIPE, EGR_INTR_ENABLEr, EGR_INTR_STATUSr, SER_FIFO_NON_EMPTYf, NULL, 0 }, 521 { 0x00000008, /* IP0_TO_CMIC_PERR_INTR */ 522 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 523 { 0x00000010, /* IP1_TO_CMIC_PERR_INTR */ 524 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 525 { 0x00000020, /* IP2_TO_CMIC_PERR_INTR */ 526 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 527 { 0x00000040, /* IP3_TO_CMIC_PERR_INTR */ 528 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 529 { 0x00000080, /* IP4_TO_CMIC_PERR_INTR */ 530 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 531 { 0x00000100, /* IP5_TO_CMIC_PERR_INTR */ 532 SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 }, 533 { 0x00000200, /* PGW_0_TO_CMIC_PERR_INTR */ 534 SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf, 535 _soc_apache_pg_ser_info, 0 }, 536 { 0x00000400, /* PGW_1_TO_CMIC_PERR_INTR */ 537 SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf, 538 _soc_apache_pg_ser_info, 1 }, 539 { 0 } /* table terminator */ 540 }; 541 542 static soc_field_t _soc_apache_pm_rx_cdc_clear_field[] = { 543 CLEAR_RX_CDC_SINGLE_BIT_ERRf, CLEAR_RX_CDC_DOUBLE_BIT_ERRf 544 }; 545 static soc_field_t _soc_apache_pm_tx_cdc_clear_field[] = { 546 CLEAR_TX_CDC_SINGLE_BIT_ERRf, CLEAR_TX_CDC_DOUBLE_BIT_ERRf 547 }; 548 static soc_field_t _soc_apache_pm_rx_ts_clear_field[] = { 549 CLEAR_RX_TS_MEM_SINGLE_BIT_ERRf, CLEAR_RX_TS_MEM_DOUBLE_BIT_ERRf 550 }; 551 static _soc_apache_ser_reg_t _soc_apache_pm_xlp_rx_status_reg[] = { 552 { XLPORT_MIB_RSC0_ECC_STATUSr, "XLP MIB RSC0 ECC" }, 553 { XLPORT_MIB_RSC1_ECC_STATUSr, "XLP MIB RSC1 ECC" }, 554 { INVALIDr } 555 }; 556 static _soc_apache_ser_reg_t _soc_apache_pm_xlp_tx_status_reg[] = { 557 { XLPORT_MIB_TSC0_ECC_STATUSr, "XLP MIB TSC0 ECC" }, 558 { XLPORT_MIB_TSC1_ECC_STATUSr, "XLP MIB TSC1 ECC" }, 559 { INVALIDr } 560 }; 561 562 static _soc_apache_ser_info_t _soc_apache_xlport_ser_info[] = { 563 /* In addition to below we have TSC_ERROR, RX_FLOWCONTROL_REQ_FULL 564 * interrupts in XLPORT. Currently not being handled. 565 */ 566 { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0, 567 MAC_RX_CDC_MEM_ERRf, MAC_RX_CDC_MEM_ERRf, 568 INVALIDm, "MAC RX CDC memory", 569 XLPORT_INTR_ENABLEr, MAC_RX_CDC_MEM_ERRf, 570 XLMAC_RX_CDC_ECC_STATUSr, NULL, 571 XLMAC_CLEAR_ECC_STATUSr, INVALIDf, 572 _soc_apache_pm_rx_cdc_clear_field 573 }, 574 { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0, 575 MAC_TX_CDC_MEM_ERRf, MAC_TX_CDC_MEM_ERRf, 576 INVALIDm, "MAC TX CDC memory", 577 XLPORT_INTR_ENABLEr, MAC_TX_CDC_MEM_ERRf, 578 XLMAC_TX_CDC_ECC_STATUSr, NULL, 579 XLMAC_CLEAR_ECC_STATUSr, INVALIDf, 580 _soc_apache_pm_tx_cdc_clear_field 581 }, 582 { _SOC_PARITY_TYPE_MIB, NULL, 0, 583 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 584 INVALIDm, "MIB RX Statistic Counter memory", 585 XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, 586 INVALIDr, _soc_apache_pm_xlp_rx_status_reg, 587 XLPORT_MIB_RESETr, INVALIDf, NULL 588 }, 589 { _SOC_PARITY_TYPE_MIB, NULL, 0, 590 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 591 INVALIDm, "MIB TX Statistic Counter memory", 592 XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, 593 INVALIDr, _soc_apache_pm_xlp_tx_status_reg, 594 XLPORT_MIB_RESETr, INVALIDf, NULL 595 }, 596 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 597 }; 598 599 static _soc_apache_ser_info_t _soc_apache_xlb0port_ser_info[] = { 600 /* In addition to below we have TSC_ERROR, RX_FLOWCONTROL_REQ_FULL 601 * interrupts in XLPORT. Currently not being handled 602 */ 603 { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0, 604 MAC_RX_CDC_MEM_ERRf, MAC_RX_CDC_MEM_ERRf, 605 INVALIDm, "MAC RX CDC memory", 606 XLPORT_INTR_ENABLEr, MAC_RX_CDC_MEM_ERRf, 607 XLMAC_B0_RX_CDC_ECC_STATUSr, NULL, 608 XLMAC_B0_CLEAR_ECC_STATUSr, INVALIDf, 609 _soc_apache_pm_rx_cdc_clear_field 610 }, 611 { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0, 612 MAC_TX_CDC_MEM_ERRf, MAC_TX_CDC_MEM_ERRf, 613 INVALIDm, "MAC TX CDC memory", 614 XLPORT_INTR_ENABLEr, MAC_TX_CDC_MEM_ERRf, 615 XLMAC_B0_TX_CDC_ECC_STATUSr, NULL, 616 XLMAC_B0_CLEAR_ECC_STATUSr, INVALIDf, 617 _soc_apache_pm_tx_cdc_clear_field 618 }, 619 { _SOC_PARITY_TYPE_MIB, NULL, 0, 620 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 621 INVALIDm, "MIB RX Statistic Counter memory", 622 XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, 623 INVALIDr, _soc_apache_pm_xlp_rx_status_reg, 624 XLPORT_MIB_RESETr, INVALIDf, NULL 625 }, 626 { _SOC_PARITY_TYPE_MIB, NULL, 0, 627 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 628 INVALIDm, "MIB TX Statistic Counter memory", 629 XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, 630 INVALIDr, _soc_apache_pm_xlp_tx_status_reg, 631 XLPORT_MIB_RESETr, INVALIDf, NULL 632 }, 633 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 634 }; 635 636 static _soc_apache_ser_reg_t _soc_apache_pm_clp_rx_status_reg[] = { 637 { CLPORT_MIB_RSC0_ECC_STATUSr, "CLP MIB RSC0 ECC" }, 638 { CLPORT_MIB_RSC1_ECC_STATUSr, "CLP MIB RSC1 ECC" }, 639 { INVALIDr } 640 }; 641 642 static _soc_apache_ser_reg_t _soc_apache_pm_clp_tx_status_reg[] = { 643 { CLPORT_MIB_TSC0_ECC_STATUSr, "CLP MIB TSC0 ECC" }, 644 { CLPORT_MIB_TSC1_ECC_STATUSr, "CLP MIB TSC1 ECC" }, 645 { INVALIDr } 646 }; 647 static _soc_apache_ser_info_t _soc_apache_clport_ser_info[] = { 648 /* In addition to below we have TSC_ERROR, PMD_ERR, RX_FLOWCONTROL_REQ_FULL 649 * interrupts in CLPORT. Currently not being handled 650 */ 651 { _SOC_PARITY_TYPE_MAC_RX_TS, NULL, 0, 652 MAC_RX_TS_CDC_MEM_ERRf, MAC_RX_TS_CDC_MEM_ERRf, 653 INVALIDm, "MAC RX TimeStamp CDC memory", 654 CLPORT_INTR_ENABLEr, MAC_RX_TS_CDC_MEM_ERRf, 655 CLMAC_RX_TS_MEM_ECC_STATUSr, NULL, 656 CLMAC_CLEAR_ECC_STATUSr, INVALIDf, 657 _soc_apache_pm_rx_ts_clear_field 658 }, 659 { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0, 660 MAC_RX_CDC_MEM_ERRf, MAC_RX_CDC_MEM_ERRf, 661 INVALIDm, "MAC RX CDC memory", 662 CLPORT_INTR_ENABLEr, MAC_RX_CDC_MEM_ERRf, 663 CLMAC_RX_CDC_ECC_STATUSr, NULL, 664 CLMAC_CLEAR_ECC_STATUSr, INVALIDf, 665 _soc_apache_pm_rx_cdc_clear_field 666 }, 667 { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0, 668 MAC_TX_CDC_MEM_ERRf, MAC_TX_CDC_MEM_ERRf, 669 INVALIDm, "MAC TX CDC memory", 670 CLPORT_INTR_ENABLEr, MAC_TX_CDC_MEM_ERRf, 671 CLMAC_TX_CDC_ECC_STATUSr, NULL, 672 CLMAC_CLEAR_ECC_STATUSr, INVALIDf, 673 _soc_apache_pm_tx_cdc_clear_field 674 }, 675 { _SOC_PARITY_TYPE_MIB, NULL, 0, 676 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 677 INVALIDm, "MIB RX Statistic Counter memory", 678 CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, 679 INVALIDr, _soc_apache_pm_clp_rx_status_reg, 680 CLPORT_MIB_RESETr, INVALIDf, NULL 681 }, 682 { _SOC_PARITY_TYPE_MIB, NULL, 0, 683 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 684 INVALIDm, "MIB TX Statistic Counter memory", 685 CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, 686 INVALIDr, _soc_apache_pm_clp_tx_status_reg, 687 CLPORT_MIB_RESETr, INVALIDf, NULL 688 }, 689 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 690 }; 691 static _soc_apache_ser_info_t _soc_apache_clg2port_ser_info[] = { 692 /* In addition to below we have TSC_ERROR, PMD_ERR, RX_FLOWCONTROL_REQ_FULL 693 * MAC_ERR and LINK_DOWN interrupts in CLG2PORT as well as many other interrupts 694 * in CLG2MAC. Currently not being handled 695 */ 696 { _SOC_PARITY_TYPE_MAC_RX_TS, NULL, 0, 697 INVALIDf, INVALIDf, 698 INVALIDm, "MAC RX TimeStamp CDC memory", 699 CLG2MAC_INTR_ENABLEr, EN_RX_TS_MEM_SINGLE_BIT_ERRf, 700 CLG2MAC_RX_TS_MEM_ECC_STATUSr, NULL, 701 CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf, 702 _soc_apache_pm_rx_ts_clear_field 703 }, 704 { _SOC_PARITY_TYPE_MAC_RX_TS, NULL, 0, 705 INVALIDf, INVALIDf, 706 INVALIDm, "MAC RX TimeStamp CDC memory", 707 CLG2MAC_INTR_ENABLEr, EN_RX_TS_MEM_DOUBLE_BIT_ERRf, 708 CLG2MAC_RX_TS_MEM_ECC_STATUSr, NULL, 709 CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf, 710 _soc_apache_pm_rx_ts_clear_field 711 }, 712 { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0, 713 INVALIDf, INVALIDf, 714 INVALIDm, "MAC RX CDC memory", 715 CLG2MAC_INTR_ENABLEr, EN_RX_CDC_SINGLE_BIT_ERRf, 716 CLG2MAC_RX_CDC_ECC_STATUSr, NULL, 717 CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf, 718 _soc_apache_pm_rx_cdc_clear_field 719 }, 720 { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0, 721 INVALIDf, INVALIDf, 722 INVALIDm, "MAC RX CDC memory", 723 CLG2MAC_INTR_ENABLEr, EN_RX_CDC_DOUBLE_BIT_ERRf, 724 CLG2MAC_RX_CDC_ECC_STATUSr, NULL, 725 CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf, 726 _soc_apache_pm_rx_cdc_clear_field 727 }, 728 { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0, 729 INVALIDf, INVALIDf, 730 INVALIDm, "MAC TX CDC memory", 731 CLG2MAC_INTR_ENABLEr, EN_TX_CDC_SINGLE_BIT_ERRf, 732 CLG2MAC_TX_CDC_ECC_STATUSr, NULL, 733 CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf, 734 _soc_apache_pm_tx_cdc_clear_field 735 }, 736 { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0, 737 INVALIDf, INVALIDf, 738 INVALIDm, "MAC TX CDC memory", 739 CLG2MAC_INTR_ENABLEr, EN_TX_CDC_DOUBLE_BIT_ERRf, 740 CLG2MAC_TX_CDC_ECC_STATUSr, NULL, 741 CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf, 742 _soc_apache_pm_tx_cdc_clear_field 743 }, 744 { _SOC_PARITY_TYPE_MIB, NULL, 0, 745 MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf, 746 INVALIDm, "MIB RX Statistic Counter memory", 747 CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf, 748 INVALIDr, _soc_apache_pm_clp_rx_status_reg, 749 CLPORT_MIB_RESETr, INVALIDf, NULL 750 }, 751 { _SOC_PARITY_TYPE_MIB, NULL, 0, 752 MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf, 753 INVALIDm, "MIB TX Statistic Counter memory", 754 CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf, 755 INVALIDr, _soc_apache_pm_clp_tx_status_reg, 756 CLPORT_MIB_RESETr, INVALIDf, NULL 757 }, 758 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 759 }; 760 761 static _soc_apache_ser_info_t _soc_apache_pgw0_cxxport_ser_info[] = { 762 /* There are six INTR fields in CXXPORT_INTR_STATUS reg. 763 * 3 for TSC and 4 for CORE. Currently not being handled 764 */ 765 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_clport_ser_info, 0, 766 CORE3_INTf, CORE3_INTf, 767 INVALIDm, "PM4x25_CORE interrupt", 768 CLPORT_INTR_ENABLEr, INVALIDf, 769 CLPORT_INTR_STATUSr, NULL, 770 INVALIDr, INVALIDf, NULL 771 }, 772 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 6, 773 CORE2_INTf, CORE2_INTf, 774 INVALIDm, "PM4x10_CORE_2 interrupt", 775 XLPORT_INTR_ENABLEr, INVALIDf, 776 XLPORT_INTR_STATUSr, NULL, 777 INVALIDr, INVALIDf, NULL 778 }, 779 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 5, 780 CORE1_INTf, CORE1_INTf, 781 INVALIDm, "PM4x10_CORE_1 interrupt", 782 XLPORT_INTR_ENABLEr, INVALIDf, 783 XLPORT_INTR_STATUSr, NULL, 784 INVALIDr, INVALIDf, NULL 785 }, 786 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 4, 787 CORE0_INTf, CORE0_INTf, 788 INVALIDm, "PM4x10_CORE_0 interrupt", 789 XLPORT_INTR_ENABLEr, INVALIDf, 790 XLPORT_INTR_STATUSr, NULL, 791 INVALIDr, INVALIDf, NULL 792 }, 793 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 794 }; 795 796 static _soc_apache_ser_info_t _soc_apache_pgw1_cxxport_ser_info[] = { 797 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_clport_ser_info, 3, 798 CORE3_INTf, CORE3_INTf, 799 INVALIDm, "PM4x25_CORE interrupt", 800 CLPORT_INTR_ENABLEr, INVALIDf, 801 CLPORT_INTR_STATUSr, NULL, 802 INVALIDr, INVALIDf, NULL 803 }, 804 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 13, 805 CORE2_INTf, CORE2_INTf, 806 INVALIDm, "PM4x10_CORE_2 interrupt", 807 XLPORT_INTR_ENABLEr, INVALIDf, 808 XLPORT_INTR_STATUSr, NULL, 809 INVALIDr, INVALIDf, NULL 810 }, 811 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 12, 812 CORE1_INTf, CORE1_INTf, 813 INVALIDm, "PM4x10_CORE_1 interrupt", 814 XLPORT_INTR_ENABLEr, INVALIDf, 815 XLPORT_INTR_STATUSr, NULL, 816 INVALIDr, INVALIDf, NULL 817 }, 818 { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 11, 819 CORE0_INTf, CORE0_INTf, 820 INVALIDm, "PM4x10_CORE_0 interrupt", 821 XLPORT_INTR_ENABLEr, INVALIDf, 822 XLPORT_INTR_STATUSr, NULL, 823 INVALIDr, INVALIDf, NULL 824 }, 825 { _SOC_PARITY_TYPE_NONE } /* table terminator */ 826 }; 827 828 static const 829 _soc_apache_ser_route_block_t _soc_apache_ser_route_blocks_irq4[] = { 830 {0x00000001, /* Port Macro0 (PM0) interrupt */ 831 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 832 _soc_apache_xlb0port_ser_info, 0}, 833 {0x00000002, /* Port Macro1 (PM1) interrupt */ 834 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 835 _soc_apache_xlb0port_ser_info, 1}, 836 {0x00000004, /* Port Macro2 (PM2) interrupt */ 837 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 838 _soc_apache_xlb0port_ser_info, 2}, 839 {0x00000008, /* Port Macro3 (PM3) interrupt */ 840 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 841 _soc_apache_xlb0port_ser_info, 3}, 842 {0x00000010, /* Port Macro4 (PM4) interrupt */ 843 SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf, 844 _soc_apache_pgw0_cxxport_ser_info, 0}, 845 {0x00000020, /* Port Macro5 (PM5) interrupt */ 846 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 847 _soc_apache_clport_ser_info, 1}, 848 {0x00000040, /* Port Macro6 (PM6) interrupt */ 849 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 850 _soc_apache_clport_ser_info, 2}, 851 {0x00000080, /* Port Macro7 (PM7) interrupt */ 852 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 853 _soc_apache_xlb0port_ser_info, 7}, 854 {0x00000100, /* Port Macro8 (PM8) interrupt */ 855 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 856 _soc_apache_xlb0port_ser_info, 8}, 857 {0x00000200, /* Port Macro9 (PM9) interrupt */ 858 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 859 _soc_apache_xlb0port_ser_info, 9}, 860 {0x00000400, /* Port Macro10 (PM10) interrupt */ 861 SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 862 _soc_apache_xlb0port_ser_info, 10}, 863 {0x00000800, /* Port Macro11 (PM11) interrupt */ 864 SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf, 865 _soc_apache_pgw1_cxxport_ser_info, 1}, 866 {0x00001000, /* Port Macro12 (PM12) interrupt */ 867 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 868 _soc_apache_clport_ser_info, 4}, 869 {0x00002000, /* Port Macro13 (PM13) interrupt */ 870 SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 871 _soc_apache_clport_ser_info, 5}, 872 /* Bits 14-31 are reserved */ 873 {0} /* table terminator */ 874 }; 875 876 static const 877 _soc_apache_ser_route_block_t _soc_apache_ser_route_b0_blocks_irq4[] = { 878 {0x00000001, /* Port Macro0 (PM0) interrupt */ 879 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 880 _soc_apache_xlport_ser_info, 0}, 881 {0x00000002, /* Port Macro1 (PM1) interrupt */ 882 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 883 _soc_apache_xlport_ser_info, 1}, 884 {0x00000004, /* Port Macro2 (PM2) interrupt */ 885 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 886 _soc_apache_xlport_ser_info, 2}, 887 {0x00000008, /* Port Macro3 (PM3) interrupt */ 888 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 889 _soc_apache_xlport_ser_info, 3}, 890 {0x00000010, /* Port Macro4 (PM4) interrupt */ 891 SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf, 892 _soc_apache_pgw0_cxxport_ser_info, 0}, 893 {0x00000020, /* Port Macro5 (PM5) interrupt */ 894 SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 895 _soc_apache_clg2port_ser_info, 1}, 896 {0x00000040, /* Port Macro6 (PM6) interrupt */ 897 SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 898 _soc_apache_clg2port_ser_info, 2}, 899 {0x00000080, /* Port Macro7 (PM7) interrupt */ 900 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 901 _soc_apache_xlport_ser_info, 7}, 902 {0x00000100, /* Port Macro8 (PM8) interrupt */ 903 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 904 _soc_apache_xlport_ser_info, 8}, 905 {0x00000200, /* Port Macro9 (PM9) interrupt */ 906 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 907 _soc_apache_xlport_ser_info, 9}, 908 {0x00000400, /* Port Macro10 (PM10) interrupt */ 909 SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf, 910 _soc_apache_xlport_ser_info, 10}, 911 {0x00000800, /* Port Macro11 (PM11) interrupt */ 912 SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf, 913 _soc_apache_pgw1_cxxport_ser_info, 1}, 914 {0x00001000, /* Port Macro12 (PM12) interrupt */ 915 SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 916 _soc_apache_clg2port_ser_info, 4}, 917 {0x00002000, /* Port Macro13 (PM13) interrupt */ 918 SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf, 919 _soc_apache_clg2port_ser_info, 5}, 920 /* Bits 14-31 are reserved */ 921 {0} /* table terminator */ 922 }; 923 924 static soc_ser_functions_t _apache_ser_functions; 925 926 extern uint8 _soc_alpm_mode[SOC_MAX_NUM_DEVICES]; 927 928 static uint32 _apache_ser_delay = 0; 929 930 #endif 931 932 /* Values map to HW encodings */ 933 enum soc_ap_port_ca_mode_e { 934 SOC_AP_PORT_CA_MODE_SINGLE = 0, 935 SOC_AP_PORT_CA_MODE_DUAL = 1, 936 SOC_AP_PORT_CA_MODE_QUAD = 2, 937 SOC_AP_PORT_CA_MODE_TRI_211 = 3, 938 SOC_AP_PORT_CA_MODE_TRI_112 = 4, 939 SOC_AP_PORT_CA_MODE_TRI_411 = 5, 940 SOC_AP_PORT_CA_MODE_TRI_114 = 6, 941 SOC_AP_PORT_CA_MODE_COUNT /* unused */ 942 }; 943 STATIC int 944 _soc_apache_thdo_hw_set(int unit, soc_port_t port, int enable); 945 /* 946 * SINGLE => {VALUE => 0, DESC => "Port 0 valid. 10G/20G/25G/40G/50G/100G."}, 947 * DUAL => {VALUE => 1, DESC => "Port 0 and 2 valid. 10G/20G/25G/40G/50G."}, 948 * QUAD => {VALUE => 2, DESC => "Port 0, 1, 2, and 3 valid. 10G/20G/25G."}, 949 * TRI211 => {VALUE => 3, DESC => "Port 0 is 20G, port 2 10G, and port 3 10G."}, 950 * TRI112 => {VALUE => 4, DESC => "Port 0 is 10G, port 1 10G, and port 2 20G."}, 951 * TRI411 => {VALUE => 5, DESC => "Port 0 is 40G, port 2 10G, and port 3 10G."}, 952 * TRI114 => {VALUE => 6, DESC => "Port 0 is 10G, port 1 10G, and port 2 40G."}, 953 */ 954 STATIC int 955 soc_apache_port_ca_mode_get(int unit, int flexport, int xlp, int *mode) 956 { 957 soc_info_t *si; 958 int port, phy_port_base, lane; 959 int num_lanes[APACHE_PORTS_PER_TSC]; 960 int speed_max[APACHE_PORTS_PER_TSC]; 961 962 si = &SOC_INFO(unit); 963 *mode = SOC_AP_PORT_CA_MODE_QUAD; 964 965 phy_port_base = 1 + (xlp * APACHE_PORTS_PER_TSC); 966 for (lane = 0; lane < APACHE_PORTS_PER_TSC; lane++) { 967 port = si->port_p2l_mapping[phy_port_base + lane]; 968 if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 969 num_lanes[lane] = -1; 970 speed_max[lane] = -1; 971 } else { 972 num_lanes[lane] = si->port_num_lanes[port]; 973 speed_max[lane] = si->port_speed_max[port]; 974 } 975 } 976 977 if (num_lanes[0] >= 4) { 978 *mode = SOC_AP_PORT_CA_MODE_SINGLE; 979 } else if ((num_lanes[0] == 2) && (num_lanes[2] == 2)) { 980 *mode = SOC_AP_PORT_CA_MODE_DUAL; 981 } else if ((num_lanes[0] == 1) && (num_lanes[1] == 1) && 982 (num_lanes[2] == 1) && (num_lanes[3] == 1)) { 983 *mode = SOC_AP_PORT_CA_MODE_QUAD; 984 } else if (num_lanes[0] == 2) { 985 *mode = (speed_max[0] >= 40000) ? 986 SOC_AP_PORT_CA_MODE_TRI_411 : SOC_AP_PORT_CA_MODE_TRI_211; 987 } else if (num_lanes[2] == 2) { 988 *mode = (speed_max[2] >= 40000) ? 989 SOC_AP_PORT_CA_MODE_TRI_114 : SOC_AP_PORT_CA_MODE_TRI_112; 990 } 991 return SOC_E_NONE; 992 } 993 994 995 int 996 _soc_apache_idb_port_init(int unit, int reset, int lossless, soc_port_t port) 997 { 998 soc_info_t *si; 999 soc_mem_t mem; 1000 soc_reg_t reg; 1001 int obm, pgw, pgw_inst, index; 1002 int port_osub, phy_port, subport; 1003 uint32 rval32; 1004 uint64 rval64; 1005 idb_obm0_pri_map_port0_entry_t entry; 1006 1007 uint32 discard_limit = 0, lossy_discard = 0, lossy_low_pri = 0; 1008 uint32 port_xon = 0, port_xoff = 0, lossless0_xon = 0 ,lossless0_xoff = 0; 1009 1010 static const soc_reg_t obm_ctrl_regs[] = { 1011 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 1012 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 1013 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 1014 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, 1015 IDB_OBM8_CONTROLr 1016 }; 1017 static const soc_reg_t obm_thresh_regs[] = { 1018 IDB_OBM0_THRESHOLDr, IDB_OBM1_THRESHOLDr, 1019 IDB_OBM2_THRESHOLDr, IDB_OBM3_THRESHOLDr, 1020 IDB_OBM4_THRESHOLDr, IDB_OBM5_THRESHOLDr, 1021 IDB_OBM6_THRESHOLDr, IDB_OBM7_THRESHOLDr, 1022 IDB_OBM8_THRESHOLDr, 1023 }; 1024 static const soc_reg_t obm_fc_thresh_regs[] = { 1025 IDB_OBM0_FC_THRESHOLDr, IDB_OBM1_FC_THRESHOLDr, 1026 IDB_OBM2_FC_THRESHOLDr, IDB_OBM3_FC_THRESHOLDr, 1027 IDB_OBM4_FC_THRESHOLDr, IDB_OBM5_FC_THRESHOLDr, 1028 IDB_OBM6_FC_THRESHOLDr, IDB_OBM7_FC_THRESHOLDr, 1029 IDB_OBM8_FC_THRESHOLDr, 1030 }; 1031 static const soc_reg_t obm_shared_regs[] = { 1032 IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr, 1033 IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr, 1034 IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr, 1035 IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr, 1036 IDB_OBM8_SHARED_CONFIGr, 1037 }; 1038 static const soc_reg_t obm_max_usage_regs[] = { 1039 IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr, 1040 IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr, 1041 IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr, 1042 IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr, 1043 IDB_OBM8_MAX_USAGE_SELECTr 1044 }; 1045 1046 static const soc_reg_t obm_port_config_regs[] = { 1047 IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr, 1048 IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr, 1049 IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr, 1050 IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr, 1051 IDB_OBM8_PORT_CONFIGr 1052 }; 1053 static const soc_reg_t obm_fc_config_regs[] = { 1054 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 1055 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 1056 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 1057 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr, 1058 IDB_OBM8_FLOW_CONTROL_CONFIGr, 1059 }; 1060 1061 static const soc_field_t obm_bypass_fields[] = { 1062 PORT0_BYPASS_ENABLEf, PORT1_BYPASS_ENABLEf, 1063 PORT2_BYPASS_ENABLEf, PORT3_BYPASS_ENABLEf 1064 }; 1065 static const soc_field_t obm_oversub_fields[] = { 1066 PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf, 1067 PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf 1068 }; 1069 1070 static const soc_mem_t obm_pri_map_port_mem[] = { 1071 IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m, 1072 IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m, 1073 IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m, 1074 IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m, 1075 IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m, 1076 IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m, 1077 IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m, 1078 IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m, 1079 IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m, 1080 IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m, 1081 IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m, 1082 IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m, 1083 IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m, 1084 IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m, 1085 IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m, 1086 IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m, 1087 IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m, 1088 IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m, 1089 }; 1090 1091 1092 static const soc_field_t offset_ob_prio[] = { 1093 OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf, 1094 OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf, 1095 OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf, 1096 OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf, 1097 OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf, 1098 OFFSET15_OB_PRIORITYf, 1099 }; 1100 static const soc_reg_t obm_ct_thresh_regs[] = { 1101 IDB_OBM0_CT_THRESHOLDr, IDB_OBM1_CT_THRESHOLDr, 1102 IDB_OBM2_CT_THRESHOLDr, IDB_OBM3_CT_THRESHOLDr, 1103 IDB_OBM4_CT_THRESHOLDr, IDB_OBM5_CT_THRESHOLDr, 1104 IDB_OBM6_CT_THRESHOLDr, IDB_OBM7_CT_THRESHOLDr, 1105 IDB_OBM8_CT_THRESHOLDr, 1106 }; 1107 1108 si = &SOC_INFO(unit); 1109 1110 /* Calculation of obm and lanes(subport) 1111 obm is 0 for phy_port 1 to 4 1112 1 for phy port 5 to 8 and so on till 8 for phy_port 33 to 36 1113 Similarly obm 0 for phy_port 37 to 40 and so on 1114 lane(subport) is 0,1,2,3 for phy_port 1,2,3,4 resp 1115 lane(subport) is 0,1,2,3 for phy_port 5,6,7,8 resp and so on 1116 Block index is PGW0 for ports 1 to 36 1117 Block index is PGW1 for ports 37 to 72 1118 */ 1119 phy_port = si->port_l2p_mapping[port]; 1120 1121 /* Deleting a port */ 1122 if (phy_port == -1) { 1123 return SOC_E_PARAM; 1124 } 1125 1126 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 1127 /* nothing to do for non-idb ports */ 1128 return SOC_E_NONE; 1129 } 1130 1131 /* OBM group (num groups = num tsc's) belongs to PGW0/PGW1 */ 1132 obm = si->port_serdes[port]; 1133 obm %= APACHE_TSCS_PER_PGW; 1134 1135 pgw = si->port_group[port]; 1136 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 1137 subport = (phy_port - 1) % APACHE_PORTS_PER_TSC; 1138 1139 if (si->port_speed_max[port] <= 11000) { 1140 discard_limit = 253; 1141 lossy_discard = lossless ? 196 : 249; 1142 lossy_low_pri = lossless ? 100 : 173; 1143 port_xon = lossless ? 116 : 1023; 1144 port_xoff = lossless ? 126 : 1023; 1145 lossless0_xon = lossless ? 36 : 1023; 1146 lossless0_xoff = lossless ? 46 : 1023; 1147 } else if (si->port_speed_max[port] <= 21000) { 1148 discard_limit = 253; 1149 lossy_discard = lossless ? 196 : 249; 1150 lossy_low_pri = lossless ? 100 : 173; 1151 port_xon = lossless ? 101 : 1023; 1152 port_xoff = lossless ? 111 : 1023; 1153 lossless0_xon = lossless ? 36 : 1023; 1154 lossless0_xoff = lossless ? 46 : 1023; 1155 } else if (si->port_speed_max[port] <= 27000) { 1156 discard_limit = 253; 1157 lossy_discard = lossless ? 176 : 249; 1158 lossy_low_pri = lossless ? 80 : 173; 1159 port_xon = lossless ? 94 : 1023; 1160 port_xoff = lossless ? 104 : 1023; 1161 lossless0_xon = lossless ? 36 : 1023; 1162 lossless0_xoff = lossless ? 46 : 1023; 1163 } else if (si->port_speed_max[port] <= 42000) { 1164 discard_limit = 506; 1165 lossy_discard = lossless ? 196 : 502; 1166 lossy_low_pri = lossless ? 100 : 426; 1167 port_xon = lossless ? 279 : 1023; 1168 port_xoff = lossless ? 289 : 1023; 1169 lossless0_xon = lossless ? 98 : 1023; 1170 lossless0_xoff = lossless ? 108 : 1023; 1171 } else if (si->port_speed_max[port] <= 53000) { 1172 discard_limit = 506; 1173 lossy_discard = lossless ? 196 : 502; 1174 lossy_low_pri = lossless ? 100 : 426; 1175 port_xon = lossless ? 259 : 1023; 1176 port_xoff = lossless ? 269 : 1023; 1177 lossless0_xon = lossless ? 98 : 1023; 1178 lossless0_xoff = lossless ? 108 : 1023; 1179 } else { /* greter than 53000 including 106000 */ 1180 discard_limit = 1012; 1181 lossy_discard = lossless ? 196 : 1008; 1182 lossy_low_pri = lossless ? 100 : 932; 1183 port_xon = lossless ? 609 : 1023; 1184 port_xoff = lossless ? 619 : 1023; 1185 lossless0_xon = lossless ? 248 : 1023; 1186 lossless0_xoff = lossless ? 258 : 1023; 1187 } 1188 1189 if (reset) { 1190 discard_limit = 0; 1191 lossy_discard = 0; 1192 lossy_low_pri = 0; 1193 port_xon = 0; 1194 port_xoff = 0; 1195 lossless0_xon = 0; 1196 lossless0_xoff = 0; 1197 } 1198 1199 1200 rval32 = 0; 1201 reg = obm_port_config_regs[obm]; 1202 1203 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32)); 1204 soc_reg_field_set(unit, reg, &rval32, PORT_PRIf, 2); 1205 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32)); 1206 1207 rval32 = 0; 1208 reg = obm_max_usage_regs[obm]; 1209 1210 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32)); 1211 soc_reg_field_set(unit, reg, &rval32, PRIORITY_SELECTf, 2); 1212 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32)); 1213 1214 COMPILER_64_ZERO(rval64); 1215 reg = obm_thresh_regs[obm]; 1216 1217 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1218 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, discard_limit); 1219 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 1023); 1220 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 1023); 1221 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, lossy_discard); 1222 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, lossy_low_pri); 1223 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_MINf, 0); 1224 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1225 1226 rval32 = 0; 1227 reg = obm_shared_regs[obm]; 1228 1229 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32)); 1230 soc_reg_field_set(unit, reg, &rval32, SOP_DISCARD_MODEf, 1); 1231 soc_reg_field_set(unit, reg, &rval32, SOP_THRESHOLDf, 1023); 1232 soc_reg_field_set(unit, reg, &rval32, DISCARD_THRESHOLDf, 1023); 1233 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32)); 1234 1235 COMPILER_64_ZERO(rval64); 1236 reg = obm_fc_thresh_regs[obm]; 1237 1238 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1239 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, port_xon); 1240 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, port_xoff); 1241 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 1023); 1242 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 1023); 1243 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, lossless0_xon); 1244 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, lossless0_xoff); 1245 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1246 1247 if (!IS_OVERSUB_PORT(unit, port) || 1248 ((IS_OVERSUB_PORT(unit, port)) && 1249 ((si->port_speed_max[port] == 40000) || 1250 (si->port_speed_max[port] == 42000)))) { 1251 COMPILER_64_ZERO(rval64); 1252 reg = obm_ct_thresh_regs[obm]; 1253 1254 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1255 soc_reg64_field32_set(unit, reg, &rval64, CUT_THROUGH_OKf, 2); 1256 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1257 } 1258 1259 COMPILER_64_ZERO(rval64); 1260 reg = obm_fc_config_regs[obm]; 1261 1262 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64)); 1263 soc_reg64_field32_set(unit, reg, &rval64, XOFF_REFRESH_TIMERf, 256); 1264 soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, lossless ? 1 : 0); 1265 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, lossless ? 1 : 0); 1266 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, 1267 lossless ? 65535 : 0); 1268 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64)); 1269 1270 rval32 = 0; 1271 reg = obm_ctrl_regs[obm]; 1272 port_osub = SOC_PBMP_MEMBER(si->oversub_pbm, port); 1273 1274 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32)); 1275 soc_reg_field_set(unit, reg, &rval32, obm_bypass_fields[subport], 1); 1276 soc_reg_field_set(unit, reg, &rval32, obm_oversub_fields[subport], port_osub); 1277 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32)); 1278 1279 if (lossless) { 1280 mem = obm_pri_map_port_mem[(phy_port - 1) % APACHE_PORTS_PER_PGW]; 1281 sal_memset(&entry, 0, sizeof(entry)); 1282 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry)); 1283 for (index = 0; index < COUNTOF(offset_ob_prio); index++) { 1284 soc_mem_field32_set(unit, mem, &entry, offset_ob_prio[index], 2); 1285 } 1286 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry)); 1287 } 1288 1289 return SOC_E_NONE; 1290 } 1291 1292 STATIC int 1293 _soc_apache_port_blk_ca_mode_set(int unit, int flexport, int xlp) 1294 { 1295 int rv; 1296 soc_reg_t reg; 1297 int ca_port_mode = 0; 1298 int pgw_inst; 1299 uint32 r32val0, r32val1; 1300 1301 static const soc_reg_t obm_ca_ctrl_regs[] = { 1302 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr, 1303 IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 1304 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, IDB_OBM8_CA_CONTROLr 1305 }; 1306 1307 /* Calculate the mode of the Cell Assembly for the port block */ 1308 rv = soc_apache_port_ca_mode_get(unit, flexport, xlp, &ca_port_mode); 1309 SOC_IF_ERROR_RETURN(rv); 1310 1311 r32val0 = 0; 1312 reg = obm_ca_ctrl_regs[xlp % APACHE_TSCS_PER_PGW]; 1313 pgw_inst = ((xlp / APACHE_TSCS_PER_PGW) | SOC_REG_ADDR_INSTANCE_MASK); 1314 /* Debug output */ 1315 LOG_VERBOSE(BSL_LS_SOC_PORT, 1316 (BSL_META_U(unit, 1317 "Port Block CellAssembly Mode: " 1318 "xlp=%d pgw=%d reg=%s ca_mode=%d \n"), 1319 xlp, (xlp / APACHE_TSCS_PER_PGW), SOC_REG_NAME(unit, reg), ca_port_mode)); 1320 1321 1322 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &r32val0)); 1323 soc_reg_field_set(unit, reg, &r32val0, PORT_MODEf, ca_port_mode); 1324 r32val1 = r32val0; 1325 if (!flexport) { 1326 soc_reg_field_set(unit, reg, &r32val0, PORT0_RESETf, 1); 1327 soc_reg_field_set(unit, reg, &r32val0, PORT1_RESETf, 1); 1328 soc_reg_field_set(unit, reg, &r32val0, PORT2_RESETf, 1); 1329 soc_reg_field_set(unit, reg, &r32val0, PORT3_RESETf, 1); 1330 1331 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val0)); 1332 } 1333 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val1)); 1334 1335 return SOC_E_NONE; 1336 } 1337 1338 int 1339 soc_apache_idb_init(int unit) 1340 { 1341 int rv; 1342 int lossless; 1343 soc_port_t port; 1344 int xlp, blk_index; 1345 soc_block_t port_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, 1346 SOC_BLK_CLPORT, SOC_BLK_CLG2PORT, 1347 SOC_BLOCK_TYPE_INVALID}; 1348 1349 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 1350 /* Per-port settings */ 1351 PBMP_ALL_ITER(unit, port) { 1352 SOC_IF_ERROR_RETURN(_soc_apache_idb_port_init(unit, FALSE, lossless, port)); 1353 } 1354 1355 SOC_BLOCKS_ITER(unit, blk_index, port_blocks) { 1356 port = SOC_BLOCK_PORT(unit, blk_index); 1357 xlp = SOC_INFO(unit).port_serdes[port]; 1358 rv = _soc_apache_port_blk_ca_mode_set(unit, FALSE, xlp); 1359 SOC_IF_ERROR_RETURN(rv); 1360 } 1361 1362 return SOC_E_NONE; 1363 } 1364 1365 1366 STATIC int 1367 soc_ap_mmu_delay_insertion_set (int unit, int port) 1368 { 1369 int phy_port, mmu_port; 1370 int val = 0; 1371 uint32 rval; 1372 soc_info_t *si; 1373 1374 si = &SOC_INFO(unit); 1375 1376 phy_port = si->port_l2p_mapping[port]; 1377 mmu_port = si->port_p2m_mapping[phy_port]; 1378 1379 1380 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, 1381 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, &rval)); 1382 1383 if (IS_OVERSUB_PORT(unit, port ) && si->port_speed_max[port] >= 20000) { 1384 val = 120 + (sal_rand() % 20); 1385 } else { 1386 /* linerate port or OS with < 20G */ 1387 } 1388 soc_reg_field_set(unit, ES_PIPE0_MMU_3DBG_Cr, &rval, FIELD_Af, val); 1389 1390 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, 1391 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, rval)); 1392 1393 return SOC_E_NONE; 1394 } 1395 1396 1397 STATIC int 1398 _soc_apache_ser_enable_info(int unit, int block_info_idx, int inst, int port, 1399 soc_reg_t group_reg, uint64 *group_rval, 1400 const _soc_apache_ser_info_t *info_list, 1401 soc_mem_t mem, int enable); 1402 STATIC int 1403 _soc_apache_ser_enable_cxxport(int unit, int inst, 1404 const _soc_apache_ser_info_t *info, 1405 soc_mem_t mem, int enable) 1406 { 1407 uint64 rval; 1408 int block_info_idx, port, blk_idx; 1409 1410 port = INVALID_PORT; 1411 1412 if ((inst == 0) || (inst == 3)) { 1413 blk_idx = SOC_BLK_CLPORT; 1414 } else { 1415 blk_idx = SOC_BLK_XLPORT; 1416 } 1417 1418 SOC_BLOCK_ITER(unit, block_info_idx, blk_idx) { 1419 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst) { 1420 port = SOC_BLOCK_PORT(unit, block_info_idx); 1421 break; 1422 } 1423 } 1424 1425 if (port == INVALID_PORT) { 1426 return SOC_E_NONE; 1427 } 1428 1429 /* Read reg val here */ 1430 SOC_IF_ERROR_RETURN 1431 (soc_reg_get(unit, info->enable_reg, port, 0, &rval)); 1432 SOC_IF_ERROR_RETURN 1433 (_soc_apache_ser_enable_info(unit, block_info_idx, inst, port, 1434 info->enable_reg, &rval, 1435 info, mem, enable)); 1436 /* Write back reg val here */ 1437 SOC_IF_ERROR_RETURN 1438 (soc_reg_set(unit, info->enable_reg, port, 0, rval)); 1439 1440 return SOC_E_NONE; 1441 } 1442 1443 STATIC int 1444 _soc_apache_ser_enable_mmu_1bit_ecc (int unit, int enable) 1445 { 1446 int i, f; 1447 uint64 rval64; 1448 uint32 rval; 1449 soc_field_info_t *fieldp; 1450 soc_reg_info_t *regp; 1451 soc_reg_t reg; 1452 1453 soc_reg_t _1b_reg_list[] = { 1454 CFAP_EN_COR_ERR_RPTr, 1455 MMU_DEQ_EN_COR_ERR_RPTr, 1456 MMU_ENQ_EN_COR_ERR_RPTr, 1457 MMU_EPRG_EN_COR_ERR_RPTr, 1458 INTFI_EN_COR_ERR_RPTr, 1459 LLS_EN_COR_ERR_RPT_PORTr, 1460 LLS_EN_COR_ERR_RPT_L0r, 1461 LLS_EN_COR_ERR_RPT_L1r, 1462 LLS_EN_COR_ERR_RPT_L2r, 1463 MMU_PQE_EN_COR_ERR_RPTr, 1464 MMU_QCN_EN_COR_ERR_RPTr, 1465 RQE_EN_COR_ERR_RPTr, 1466 MMU_TDM_EN_COR_ERR_RPTr, 1467 THDI_EN_COR_ERR_RPTr, 1468 MMU_THDM_DB_EN_COR_ERR_RPTr, 1469 MMU_THDM_MCQE_EN_COR_ERR_RPTr, 1470 MMU_THDU_EN_COR_ERR_RPTr, 1471 MMU_TOQ_EN_COR_ERR_RPTr, 1472 HSP_EN_COR_ERR_RPTr 1473 }; 1474 for (i = 0; i < COUNTOF(_1b_reg_list); i++) { 1475 reg = _1b_reg_list[i]; 1476 regp = &(SOC_REG_INFO(unit, reg)); 1477 if (SOC_REG_IS_64(unit, reg)) { 1478 SOC_IF_ERROR_RETURN 1479 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 1480 for (f = 0; f < regp->nFields; f++) { 1481 fieldp = &(regp->fields[f]); 1482 soc_reg64_field32_set(unit, reg, &rval64, fieldp->field, 1483 enable ? 1 : 0); 1484 } 1485 SOC_IF_ERROR_RETURN 1486 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 1487 } else { 1488 SOC_IF_ERROR_RETURN 1489 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 1490 for (f = 0; f < regp->nFields; f++) { 1491 fieldp = &(regp->fields[f]); 1492 soc_reg_field_set(unit, reg, &rval, fieldp->field, 1493 enable ? 1 : 0); 1494 } 1495 SOC_IF_ERROR_RETURN 1496 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 1497 } 1498 } 1499 1500 return SOC_E_NONE; 1501 } 1502 1503 1504 STATIC int 1505 _soc_apache_ser_enable_info(int unit, int block_info_idx, int inst, int port, 1506 soc_reg_t group_reg, uint64 *group_rval, 1507 const _soc_apache_ser_info_t *info_list, 1508 soc_mem_t mem, int enable) 1509 { 1510 const _soc_apache_ser_info_t *info; 1511 int info_index, rv, rv1; 1512 soc_reg_t reg; 1513 uint32 rval; 1514 uint64 rval64, mac_err_mask; 1515 1516 rv = SOC_E_NOT_FOUND; 1517 1518 /* Loop through each info entry in the list */ 1519 for (info_index = 0; ; info_index++) { 1520 info = &info_list[info_index]; 1521 if (info->type == _SOC_PARITY_TYPE_NONE) { 1522 /* End of table */ 1523 break; 1524 } 1525 1526 if (mem != INVALIDm && info->mem != mem) { 1527 continue; 1528 } 1529 1530 rv = SOC_E_NONE; 1531 1532 /* Enable the info entry in the group register */ 1533 if (info->group_reg_enable_field != INVALIDf) { 1534 soc_reg64_field32_set(unit, group_reg, group_rval, 1535 info->group_reg_enable_field, enable ? 1 : 0); 1536 } 1537 1538 /* Handle different parity error reporting style */ 1539 switch (info->type) { 1540 case _SOC_PARITY_TYPE_MAC_TX_CDC: 1541 case _SOC_PARITY_TYPE_MAC_RX_CDC: 1542 case _SOC_PARITY_TYPE_MAC_RX_TS: 1543 COMPILER_64_SET(mac_err_mask, 0, 0x7800); 1544 if (info->group_reg_enable_field == INVALIDf) { 1545 COMPILER_64_OR(*group_rval, mac_err_mask); 1546 } 1547 /* fall through */ 1548 case _SOC_PARITY_TYPE_MIB: 1549 case _SOC_PARITY_TYPE_PARITY: 1550 case _SOC_PARITY_TYPE_ECC: 1551 reg = info->enable_reg; 1552 if (!SOC_REG_IS_VALID(unit, reg)) { 1553 break; 1554 } 1555 if (SOC_REG_IS_64(unit, reg)) { 1556 SOC_IF_ERROR_RETURN 1557 (soc_reg_get(unit, reg, port, 0, &rval64)); 1558 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field, 1559 enable ? 1 : 0); 1560 SOC_IF_ERROR_RETURN 1561 (soc_reg_set(unit, reg, port, 0, rval64)); 1562 } else { 1563 SOC_IF_ERROR_RETURN 1564 (soc_reg32_get(unit, reg, port, 0, &rval)); 1565 soc_reg_field_set(unit, reg, &rval, info->enable_field, 1566 enable ? 1 : 0); 1567 SOC_IF_ERROR_RETURN 1568 (soc_reg32_set(unit, reg, port, 0, rval)); 1569 } 1570 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1571 "SER enable for: %s\n"), 1572 (info->mem == INVALIDm) ? info->mem_str : 1573 SOC_MEM_NAME(unit, info->mem))); 1574 break; 1575 case _SOC_PARITY_TYPE_CXXPORT: 1576 /* One more level of enable tree structure */ 1577 rv1 = _soc_apache_ser_enable_cxxport(unit, info->id, info->info, 1578 mem, enable); 1579 if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) { 1580 return rv; 1581 } 1582 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1583 "SER enable for: %s\n"), 1584 (info->mem == INVALIDm) ? info->mem_str : 1585 SOC_MEM_NAME(unit, info->mem))); 1586 break; 1587 case _SOC_PARITY_TYPE_MMU_SER: 1588 rv1 = _soc_apache_ser_enable_mmu_1bit_ecc(unit, enable); 1589 if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) { 1590 return rv; 1591 } 1592 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1593 "SER enable for: %s\n"), 1594 (info->mem == INVALIDm) ? info->mem_str : 1595 SOC_MEM_NAME(unit, info->mem))); 1596 break; 1597 case _SOC_PARITY_TYPE_GENERIC: 1598 case _SOC_PARITY_TYPE_START_ERR: 1599 case _SOC_PARITY_TYPE_BST: 1600 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit, 1601 "SER enable for: %s\n"), 1602 (info->mem == INVALIDm) ? info->mem_str : 1603 SOC_MEM_NAME(unit, info->mem))); 1604 default: 1605 break; 1606 } /* Handle different parity error reporting style */ 1607 if (mem != INVALIDm) { 1608 break; 1609 } 1610 1611 } /* Loop through each info entry in the route block */ 1612 1613 return rv; 1614 } 1615 1616 STATIC int 1617 _soc_apache_ser_enable_pm (int unit, int enable) 1618 { 1619 #if defined(BCM_56560_A0) 1620 uint32 cmic_rval = 0, cmic_bit = 0; 1621 uint64 rval64; 1622 int rbi, block_info_idx, port, rv = SOC_E_NONE; 1623 const _soc_apache_ser_route_block_t *rb; 1624 1625 SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval)); 1626 1627 for (rbi = 0; ; rbi++) { 1628 if (soc_feature(unit, soc_feature_clport_gen2)) { 1629 rb = &_soc_apache_ser_route_b0_blocks_irq4[rbi]; 1630 } else { 1631 rb = &_soc_apache_ser_route_blocks_irq4[rbi]; 1632 } 1633 cmic_bit = rb->cmic_bit; 1634 if (cmic_bit == 0) { 1635 /* End of table */ 1636 break; 1637 } 1638 if (rb->info == NULL) { 1639 continue; 1640 } 1641 if (enable) { 1642 cmic_rval |= cmic_bit; 1643 } 1644 port = INVALID_PORT; 1645 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 1646 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 1647 port = SOC_BLOCK_PORT(unit, block_info_idx); 1648 break; 1649 } 1650 } 1651 1652 if (port == INVALID_PORT) { 1653 continue; 1654 } 1655 1656 if (rb->enable_reg != INVALIDr) { 1657 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 1658 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 1659 /* This port block is not configured */ 1660 continue; 1661 } 1662 SOC_IF_ERROR_RETURN 1663 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64)); 1664 1665 rv = _soc_apache_ser_enable_info(unit, block_info_idx, rb->id, port, 1666 rb->enable_reg, &rval64, 1667 rb->info, INVALIDm, enable); 1668 } 1669 1670 if (rv == SOC_E_NOT_FOUND) { 1671 continue; 1672 } else if (SOC_FAILURE(rv)) { 1673 return rv; 1674 } 1675 1676 if (rb->enable_reg != INVALIDr) { 1677 /* Write per route block parity enable register */ 1678 SOC_IF_ERROR_RETURN 1679 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64)); 1680 } 1681 } /* end of rbi for */ 1682 1683 if (enable) { 1684 /* Write CMIC enable register */ 1685 (void)soc_cmicm_intr4_enable(unit, cmic_rval); 1686 } else { 1687 /* Write CMIC disable register */ 1688 (void)soc_cmicm_intr4_disable(unit, cmic_rval); 1689 } 1690 1691 return SOC_E_NONE; 1692 #else 1693 return SOC_E_NONE; 1694 #endif 1695 } 1696 1697 STATIC int 1698 _soc_apache_ser_enable_all (int unit, int enable) 1699 { 1700 #if defined(BCM_56560_A0) 1701 uint8 rbi, bcount, type; 1702 uint16 pcount; 1703 uint32 cmic_rval; 1704 uint32 rval, cmic_bit; 1705 int port = REG_PORT_ANY; 1706 int rv, block_info_idx; 1707 uint64 rval64; 1708 soc_reg_t reg, ecc1b_reg; 1709 soc_field_t field, ecc1b_field; 1710 _soc_reg_ser_en_info_t *reg_info; 1711 _soc_mem_ser_en_info_t *mem_info; 1712 _soc_bus_ser_en_info_t *bus_info; 1713 _soc_buffer_ser_en_info_t *buf_info; 1714 char *str_type; 1715 char *str_name; 1716 const _soc_apache_ser_route_block_t *rb; 1717 const _soc_apache_ser_block_info_t *ser_block_info; 1718 static char *parity_module_str[4] = {"REG", "MEM", "BUS", "BUF"}; 1719 1720 /* coverity[result_independent_of_operands] */ 1721 SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK3r(unit, &cmic_rval)); 1722 1723 /* Enable new fifo mechanism based SER stuff */ 1724 ser_block_info = _soc_apache_ser_block_info; 1725 for (bcount = 0; ser_block_info[bcount].blocktype; bcount++) { 1726 int done = 0; 1727 1728 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, 1729 (BSL_META_U(unit, 1730 "Unit %d SER enable for: %s\n"), 1731 unit, ser_block_info[bcount].name)); 1732 1733 type = ser_block_info[bcount].type; 1734 reg_info = (_soc_reg_ser_en_info_t*)ser_block_info[bcount].info; 1735 mem_info = (_soc_mem_ser_en_info_t*)ser_block_info[bcount].info; 1736 bus_info = (_soc_bus_ser_en_info_t*)ser_block_info[bcount].info; 1737 buf_info = (_soc_buffer_ser_en_info_t*)ser_block_info[bcount].info; 1738 for (pcount = 0; ; pcount++) { 1739 ecc1b_reg = INVALIDr; 1740 ecc1b_field = INVALIDf; 1741 switch (type) { 1742 case _SOC_APACHE_SER_TYPE_REG: 1743 if (reg_info[pcount].reg == INVALIDr) { 1744 done = 1; 1745 } else { 1746 reg = reg_info[pcount].en_ctrl.ctrl_type.en_reg; 1747 field = reg_info[pcount].en_ctrl.en_fld; 1748 str_name = SOC_REG_NAME(unit, reg_info[pcount].reg); 1749 } 1750 break; 1751 case _SOC_APACHE_SER_TYPE_MEM: 1752 if (mem_info[pcount].mem == INVALIDm) { 1753 done = 1; 1754 } else { 1755 if (soc_feature(unit, soc_feature_parity_injection_l2)) { 1756 if ((mem_info[pcount].mem == L2_USER_ENTRYm) || 1757 (mem_info[pcount].mem == L2_USER_ENTRY_DATA_ONLYm)){ 1758 continue; 1759 } 1760 } 1761 if (SOC_MEM_INFO(unit, mem_info[pcount].mem).flags & 1762 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP) { 1763 continue; 1764 } 1765 reg = mem_info[pcount].en_ctrl.ctrl_type.en_reg; 1766 field = mem_info[pcount].en_ctrl.en_fld; 1767 ecc1b_reg = mem_info[pcount].ecc1b_ctrl.ctrl_type.en_reg; 1768 ecc1b_field = mem_info[pcount].ecc1b_ctrl.en_fld; 1769 str_name = SOC_MEM_NAME(unit, mem_info[pcount].mem); 1770 } 1771 break; 1772 case _SOC_APACHE_SER_TYPE_BUS: 1773 if (bus_info[pcount].en_reg == INVALIDr) { 1774 done = 1; 1775 } else { 1776 reg = bus_info[pcount].en_reg; 1777 field = bus_info[pcount].en_fld; 1778 str_name = bus_info[pcount].bus_name; 1779 } 1780 break; 1781 case _SOC_APACHE_SER_TYPE_BUF: 1782 if (buf_info[pcount].en_reg == INVALIDr) { 1783 done = 1; 1784 } else { 1785 reg = buf_info[pcount].en_reg; 1786 field = buf_info[pcount].en_fld; 1787 str_name = buf_info[pcount].buffer_name; 1788 } 1789 break; 1790 default: 1791 LOG_ERROR(BSL_LS_SOC_MEM, 1792 (BSL_META_U(unit, 1793 "Unknown parity module [bcount: %d][pcount: %d].\n"), 1794 bcount, pcount)); 1795 return SOC_E_INTERNAL; 1796 } 1797 if (done) { 1798 break; 1799 } else { 1800 str_type = parity_module_str[type]; 1801 } 1802 /* NOTE: Do not use the field modify routine in the following as 1803 some regs do not return the correct value due to which the 1804 modify routine skips the write */ 1805 if (SOC_REG_IS_64(unit, reg)) { 1806 SOC_IF_ERROR_RETURN 1807 (soc_reg_get(unit, reg, port, 0, &rval64)); 1808 soc_reg64_field32_set(unit, reg, &rval64, field, enable ? 1 : 0); 1809 SOC_IF_ERROR_RETURN 1810 (soc_reg_set(unit, reg, port, 0, rval64)); 1811 } else { 1812 SOC_IF_ERROR_RETURN 1813 (soc_reg32_get(unit, reg, port, 0, &rval)); 1814 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 1815 SOC_IF_ERROR_RETURN 1816 (soc_reg32_set(unit, reg, port, 0, rval)); 1817 } 1818 if (ecc1b_reg != INVALIDr && ecc1b_field != INVALIDf) { 1819 if (SOC_REG_IS_64(unit, ecc1b_reg)) { 1820 SOC_IF_ERROR_RETURN 1821 (soc_reg_get(unit, ecc1b_reg, port, 0, &rval64)); 1822 soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, enable ? 1 : 0); 1823 SOC_IF_ERROR_RETURN 1824 (soc_reg_set(unit, ecc1b_reg, port, 0, rval64)); 1825 } else { 1826 SOC_IF_ERROR_RETURN 1827 (soc_reg32_get(unit, ecc1b_reg, port, 0, &rval)); 1828 soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, enable ? 1 : 0); 1829 if (20 == SOC_REG_ACC_TYPE(unit, ecc1b_reg)) { 1830 SOC_IF_ERROR_RETURN( 1831 soc_reg32_set(unit, ecc1b_reg, \ 1832 SOC_REG_ADDR_INSTANCE_MASK, 0, rval)); 1833 } else { 1834 SOC_IF_ERROR_RETURN 1835 (soc_reg32_set(unit, ecc1b_reg, port, 0, rval)); 1836 } 1837 } 1838 } 1839 LOG_VERBOSE(BSL_LS_SOC_SOCMEM, 1840 (BSL_META_U(unit, 1841 "SER enable for %s: %s\n"), 1842 str_type, str_name)); 1843 } 1844 1845 /* Loop through each place-and-route of block entry 1846 Handle entries with valid REG & FIELD values */ 1847 for (rbi = 0; ; rbi++) { 1848 rb = &_soc_apache_ser_route_blocks_irq3[rbi]; 1849 cmic_bit = rb->cmic_bit; 1850 if (cmic_bit == 0) { 1851 /* End of table */ 1852 break; 1853 } 1854 if (rb->blocktype == ser_block_info[bcount].blocktype) { 1855 cmic_rval |= cmic_bit; 1856 if (rb->enable_reg != INVALIDr && rb->enable_field != INVALIDf) { 1857 SOC_IF_ERROR_RETURN 1858 (soc_reg_field32_modify(unit, rb->enable_reg, 1859 REG_PORT_ANY, rb->enable_field, enable ? 1 : 0)); 1860 } 1861 } 1862 } 1863 1864 /* reset (toggle) fifo if applicable */ 1865 if (ser_block_info[bcount].fifo_reset_reg != INVALIDr) { 1866 SOC_IF_ERROR_RETURN 1867 (soc_reg_field32_modify(unit, 1868 ser_block_info[bcount].fifo_reset_reg, 1869 REG_PORT_ANY, FIFO_RESETf, 1)); 1870 SOC_IF_ERROR_RETURN 1871 (soc_reg_field32_modify(unit, 1872 ser_block_info[bcount].fifo_reset_reg, 1873 REG_PORT_ANY, FIFO_RESETf, 0)); 1874 } 1875 } 1876 1877 /* Enable 1B error reporting for some special items */ 1878 1879 /* Description of IARB_EN_COR_ERR_RPT says, supress these errors 1880 * by setting bits. So basically we are supressing error reporting 1881 * by setting bits. 1882 * Then again, following TD2P code... 1883 */ 1884 SOC_IF_ERROR_RETURN 1885 (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 1886 REG_PORT_ANY, 1887 CMIC_BUFFER_1BIT_ERROR_REPORTf,enable?1:0)); 1888 SOC_IF_ERROR_RETURN 1889 (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 1890 REG_PORT_ANY, 1891 LEARN_FIFO_1BIT_ERROR_REPORTf, enable?1:0)); 1892 1893 /* Loop through each place-and-route block 1894 Handle entries with non-null INFO */ 1895 for (rbi = 0; ; rbi++) { 1896 rb = &_soc_apache_ser_route_blocks_irq3[rbi]; 1897 cmic_bit = rb->cmic_bit; 1898 if (cmic_bit == 0) { 1899 /* End of table */ 1900 break; 1901 } 1902 if (rb->info == NULL) { 1903 continue; 1904 } 1905 if (enable) { 1906 cmic_rval |= cmic_bit; 1907 } 1908 1909 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 1910 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 1911 port = SOC_BLOCK_PORT(unit, block_info_idx); 1912 break; 1913 } 1914 } 1915 if (rb->enable_reg != INVALIDr) { 1916 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 1917 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 1918 /* This port block is not configured */ 1919 continue; 1920 } 1921 SOC_IF_ERROR_RETURN 1922 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64)); 1923 } 1924 1925 rv = _soc_apache_ser_enable_info(unit, block_info_idx, rb->id, port, 1926 rb->enable_reg, &rval64, 1927 rb->info, INVALIDm, enable); 1928 if (rv == SOC_E_NOT_FOUND) { 1929 continue; 1930 } else if (SOC_FAILURE(rv)) { 1931 return rv; 1932 } 1933 1934 if (rb->enable_reg != INVALIDr) { 1935 /* Write per route block parity enable register */ 1936 SOC_IF_ERROR_RETURN 1937 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64)); 1938 } 1939 } 1940 1941 if (enable) { 1942 uint32 rval1; 1943 /* MMU enables */ 1944 1945 SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1)); 1946 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0); 1947 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 1948 1949 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1950 1951 soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0); 1952 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1953 1954 soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1); 1955 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1956 1957 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */ 1958 1959 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1); 1960 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 1961 1962 /* Write CMIC enable register */ 1963 (void)soc_cmicm_intr3_enable(unit, cmic_rval); 1964 } else { 1965 /* MMU disables */ 1966 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1967 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0); 1968 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1969 SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0)); 1970 1971 /* Write CMIC disable register */ 1972 (void)soc_cmicm_intr3_disable(unit, cmic_rval); 1973 } 1974 1975 SOC_IF_ERROR_RETURN(_soc_apache_ser_enable_pm(unit,enable)); 1976 1977 return SOC_E_NONE; 1978 #else 1979 return SOC_E_NONE; 1980 #endif 1981 } 1982 1983 STATIC int 1984 _soc_apache_clear_mmu_memory(int unit, soc_mem_t mem) 1985 { 1986 int i, count; 1987 static soc_mem_t mmu_mems[] = { 1988 MMU_INTFI_XPIPE_FC_MAP_TBL0m, 1989 MMU_INTFI_XPIPE_FC_MAP_TBL1m, 1990 MMU_INTFI_XPIPE_FC_MAP_TBL2m 1991 }; 1992 1993 count = COUNTOF(mmu_mems); 1994 /* MMU mem clear to avoid SER issue */ 1995 for (i = 0; i < count; i++) { 1996 if (mem != INVALIDm) { 1997 if (mem == mmu_mems[i]) { 1998 SOC_IF_ERROR_RETURN 1999 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE)); 2000 break; 2001 } 2002 } else { 2003 SOC_IF_ERROR_RETURN 2004 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE)); 2005 } 2006 } 2007 return SOC_E_NONE; 2008 } 2009 2010 static int _soc_ap_num_shared_alpm_banks[SOC_MAX_NUM_DEVICES] = {0}; 2011 static soc_mem_t *_soc_apache_alpm_bkt_view_map[SOC_MAX_NUM_DEVICES]; 2012 #define _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks) ((num_uft_banks == 4) ? 0xFFFF : 0x7FFF) 2013 #define _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks) ((num_uft_banks == 4) ? 16 : 15) 2014 2015 int 2016 _soc_apache_mem_sram_info_get (int unit, soc_mem_t mem, int index, 2017 _soc_ser_sram_info_t *sram_info) 2018 { 2019 soc_mem_t view; 2020 int i, j, base, base_index, offset, base_bucket, bkt_offset; 2021 int entries_per_ram = 0, entries_per_bank, contiguous = 0; 2022 int num_uft_banks = 0; 2023 2024 switch (mem) { 2025 case L2Xm: 2026 case L2_ENTRY_ONLY_ECCm: 2027 if (mem == L2Xm) { 2028 sram_info->disable_reg = L2_ENTRY_PARITY_CONTROLr; 2029 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2030 } 2031 /* Total number of dedicated L2 entries is 16k */ 2032 if (index < SOC_APACHE_NUM_ENTRIES_L2_BANK) { 2033 /* 2034 * Total number of L2 dedicated banks : 2 (B0, B1) 2035 * Number of buckets in one bank : 2048 2036 * Number of entries in one bucket : 4 2037 * Total number of entries in 1 bank : 8192 2038 */ 2039 /* Number of entries in a bucket */ 2040 sram_info->ram_count = SOC_APACHE_NUM_EL_L2; 2041 /* Number of buckets in a bank */ 2042 entries_per_ram = SOC_APACHE_NUM_BKTS_PER_L2_BANK; 2043 /* Total number of entries in one bank */ 2044 entries_per_bank = entries_per_ram * sram_info->ram_count; 2045 /* 1st entry within L2 dedicated bank */ 2046 offset = index % entries_per_ram; 2047 /* 1st index for correction */ 2048 base = offset; 2049 if (index >= entries_per_bank) { 2050 base = offset + entries_per_bank; 2051 } 2052 } else { 2053 /* 2054 * Total number of shared banks : 4 (B2, B3, B4, B5) 2055 * Number of buckets in one bank : 16384 2056 * Number of entries in one bucket : 4 2057 * Total number of entries in 1 bank : 65536 2058 */ 2059 /* Number of entries in a bucket */ 2060 sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED; 2061 /* Number of buckets in a bank */ 2062 entries_per_ram = SOC_APACHE_NUM_BKTS_PER_SHARED_BANK; 2063 /* Total number of entries in one bank */ 2064 entries_per_bank = entries_per_ram * sram_info->ram_count; 2065 /* index in uft space */ 2066 base_index = index - SOC_APACHE_NUM_ENTRIES_L2_BANK; 2067 /* base addr of uft bank */ 2068 base = (base_index/entries_per_bank) * entries_per_bank; 2069 /* 1st entry within uft bank */ 2070 offset = base_index % entries_per_ram; 2071 /* 1st index for correction */ 2072 base += SOC_APACHE_NUM_ENTRIES_L2_BANK + offset; 2073 } 2074 break; 2075 case L3_ENTRY_ONLYm: 2076 case L3_ENTRY_IPV4_UNICASTm: 2077 case L3_ENTRY_IPV4_MULTICASTm: 2078 case L3_ENTRY_IPV6_UNICASTm: 2079 case L3_ENTRY_IPV6_MULTICASTm: 2080 case L3_ENTRY_ONLY_ECCm: 2081 /* Total number of dedicated L3 entries is 4k */ 2082 if (index < SOC_APACHE_NUM_ENTRIES_L3_BANK) { 2083 sram_info->ram_count = 1; 2084 base = index; 2085 } else { 2086 /* 2087 * Total number of shared banks : 4 (B2, B3, B4, B5) 2088 * Number of buckets in one bank : 16384 2089 * Number of entries in one bucket : 4 2090 * Total number of entries in 1 bank : 65536 2091 */ 2092 /* Number of entries in a bucket */ 2093 sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED; 2094 /* Number of buckets in a bank */ 2095 entries_per_ram = SOC_APACHE_NUM_BKTS_PER_SHARED_BANK; 2096 /* Total number of entries in one bank */ 2097 entries_per_bank = entries_per_ram * sram_info->ram_count; 2098 /* index in uft space */ 2099 base_index = index - SOC_APACHE_NUM_ENTRIES_L3_BANK; 2100 /* base addr of uft bank */ 2101 base = (base_index/entries_per_bank) * entries_per_bank; 2102 /* 1st entry within uft bank */ 2103 offset = base_index % entries_per_ram; 2104 /* 1st index for correction */ 2105 base += SOC_APACHE_NUM_ENTRIES_L3_BANK + offset; 2106 } 2107 break; 2108 case L3_DEFIP_ALPM_IPV4m: 2109 case L3_DEFIP_ALPM_IPV4_1m: 2110 case L3_DEFIP_ALPM_IPV6_64m: 2111 case L3_DEFIP_ALPM_IPV6_64_1m: 2112 case L3_DEFIP_ALPM_IPV6_128m: 2113 case L3_DEFIP_ALPM_RAWm: 2114 case L3_DEFIP_ALPM_ECCm: 2115 num_uft_banks = soc_apache_get_alpm_banks(unit); 2116 sram_info->disable_reg = ILPM_SER_CONTROLr; 2117 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2118 sram_info->force_reg = ISS_MEMORY_CONTROL_84r; 2119 sram_info->force_field = FORCE_XOR_GENERATIONf; 2120 2121 sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED; 2122 base_bucket = ((index >> ((num_uft_banks + 1) / 2)) & SOC_APACHE_ALPM_BKT_MASK); 2123 base = index & ((num_uft_banks == 4) ? 0x3 : 0x1); 2124 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2125 (BSL_META_U(unit, 2126 "reported bucket: 0x%08x, bank:%d\n"), base_bucket, base)); 2127 base_bucket = base_bucket % SOC_APACHE_ALPM_BKT_OFFFSET; 2128 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2129 (BSL_META_U(unit, 2130 "base bucket: 0x%08x\n"), base_bucket)); 2131 sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED; 2132 base_bucket = ((index >> ((num_uft_banks + 1) / 2)) & SOC_APACHE_ALPM_BKT_MASK); 2133 base = index & ((num_uft_banks == 4) ? 0x3 : 0x1); 2134 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2135 (BSL_META_U(unit, 2136 "reported bucket: 0x%08x, bank:%d\n"), base_bucket, base)); 2137 base_bucket = base_bucket % SOC_APACHE_ALPM_BKT_OFFFSET; 2138 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2139 (BSL_META_U(unit, 2140 "base bucket: 0x%08x\n"), base_bucket)); 2141 2142 for (i = 0; i < SOC_APACHE_NUM_EL_SHARED; i++) { 2143 /* Retreive views for all 8 buckets */ 2144 bkt_offset = base_bucket + SOC_APACHE_ALPM_BKT_OFFFSET * i; 2145 view = _soc_apache_alpm_bkt_view_map[unit][bkt_offset]; 2146 if (INVALIDm != view) { 2147 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2148 (BSL_META_U(unit, 2149 "\nbucket[%d]: 0x%08x view: %s\n"), i, bkt_offset, 2150 SOC_MEM_NAME(unit, view))); 2151 } 2152 /* Use RAW view to recovery those unused ALPM buckets and avoid 2153 * false alarm */ 2154 if (INVALIDm == view) { 2155 view = L3_DEFIP_ALPM_RAWm; 2156 } 2157 sram_info->view[i] = view; 2158 switch (view) { 2159 case L3_DEFIP_ALPM_RAWm: 2160 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_PER_BKT_COUNT; 2161 sram_info->mem_indexes[i][0] = (bkt_offset << 2162 ((num_uft_banks + 1) / 2)) | base; 2163 break; 2164 case L3_DEFIP_ALPM_IPV6_128m: 2165 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV6_128_PER_BKT_COUNT; 2166 sram_info->mem_indexes[i][0] = (bkt_offset << 2167 ((num_uft_banks + 1) / 2)) | base; 2168 sram_info->mem_indexes[i][1] = (1 << 2169 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) | 2170 (bkt_offset << ((num_uft_banks + 1) / 2)) | base; 2171 break; 2172 case L3_DEFIP_ALPM_IPV6_64_1m: 2173 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV6_64_1_PER_BKT_COUNT; 2174 sram_info->mem_indexes[i][0] = (bkt_offset << 2175 ((num_uft_banks + 1) / 2)) | base; 2176 sram_info->mem_indexes[i][1] = (1 << 2177 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) | 2178 (bkt_offset << ((num_uft_banks + 1) / 2)) | base; 2179 sram_info->mem_indexes[i][2] = (2 << 2180 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) | 2181 (bkt_offset << ((num_uft_banks + 1) / 2)) | base; 2182 break; 2183 case L3_DEFIP_ALPM_IPV4m: 2184 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV4_PER_BKT_COUNT; 2185 for (j = 0; j < SOC_APACHE_L3_DEFIP_ALPM_IPV4_PER_BKT_COUNT; j++) { 2186 sram_info->mem_indexes[i][j] = (j << 2187 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) | 2188 (bkt_offset << ((num_uft_banks + 1) / 2)) | 2189 base; 2190 } 2191 break; 2192 case L3_DEFIP_ALPM_IPV4_1m: 2193 case L3_DEFIP_ALPM_IPV6_64m: 2194 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV6_64_PER_BKT_COUNT; 2195 for (j = 0; j < SOC_APACHE_L3_DEFIP_ALPM_IPV6_64_PER_BKT_COUNT; j++) { 2196 sram_info->mem_indexes[i][j] = (j << 2197 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) | 2198 (bkt_offset << ((num_uft_banks + 1) / 2)) | 2199 base; 2200 } 2201 default: 2202 break; 2203 } 2204 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2205 (BSL_META_U(unit, 2206 "Entries per bkt: %d\n"), sram_info->index_count[i])); 2207 for (j = 0; j < sram_info->index_count[i]; j++) { 2208 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2209 (BSL_META_U(unit, 2210 "Index[%d]: [0x%08x]%d\n"), j, sram_info->mem_indexes[i][j], 2211 sram_info->mem_indexes[i][j])); 2212 } 2213 } 2214 return SOC_E_NONE; 2215 case VLAN_XLATEm: 2216 case VLAN_MACm: 2217 case VLAN_XLATE_ECCm: 2218 contiguous = 1; 2219 sram_info->disable_reg = VLAN_XLATE_DBGCTRL_0r; 2220 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2221 sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r; 2222 sram_info->force_field = FORCE_XOR_GENf; 2223 sram_info->ram_count = SOC_APACHE_NUM_EL_VLAN_XLATE; 2224 base = (index/4) * 4; 2225 break; 2226 case EGR_VLAN_XLATEm: 2227 case EGR_VLAN_XLATE_ECCm: 2228 contiguous = 1; 2229 sram_info->disable_reg = EGR_VLAN_XLATE_CONTROLr; 2230 sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf; 2231 sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr; 2232 sram_info->force_field = FORCE_XOR_GENf; 2233 sram_info->ram_count = SOC_APACHE_NUM_EL_EGR_VLAN_XLATE; 2234 base = (index/4) * 4; 2235 break; 2236 case ING_L3_NEXT_HOPm: 2237 sram_info->ram_count = SOC_APACHE_NUM_EL_ING_L3_NEXT_HOP(unit); 2238 entries_per_ram = SOC_APACHE_RAM_OFFSET_ING_L3_NEXT_HOP; 2239 base = index % entries_per_ram; 2240 break; 2241 case L3_IPMCm: 2242 sram_info->ram_count = SOC_APACHE_NUM_EL_L3_IPMC(unit); 2243 entries_per_ram = SOC_APACHE_RAM_OFFSET_L3_IPMC; 2244 base = index % entries_per_ram; 2245 break; 2246 case L2MCm: 2247 sram_info->ram_count = SOC_APACHE_NUM_EL_L2MC; 2248 entries_per_ram = SOC_APACHE_RAM_OFFSET_L2MC; 2249 base = index % entries_per_ram; 2250 break; 2251 default: 2252 return SOC_E_UNAVAIL; 2253 } 2254 sram_info->mem_indexes[0][0] = base; 2255 if (contiguous) { 2256 for (i = 1; i < sram_info->ram_count; i++) { 2257 sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 1; 2258 } 2259 } else { 2260 for (i = 1; i < sram_info->ram_count; i++) { 2261 sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + entries_per_ram; 2262 } 2263 } 2264 return SOC_E_NONE; 2265 } 2266 2267 STATIC int 2268 _soc_apache_lls_hw_init(int unit) 2269 { 2270 uint32 rval; 2271 int lls_init_timer; 2272 soc_timeout_t to; 2273 2274 /* Init LLS */ 2275 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, LLS_INITr, 2276 REG_PORT_ANY, INITf, 1)); 2277 2278 /* Wait longer in QT; and not at all in BCMSIM */ 2279 if (SAL_BOOT_QUICKTURN) { 2280 lls_init_timer = 5000000; 2281 } else if (SAL_BOOT_SIMULATION) { 2282 lls_init_timer = 50; 2283 } else { 2284 lls_init_timer = 50000; 2285 } 2286 2287 /* Check INIT_DONE in LLS block */ 2288 soc_timeout_init(&to, lls_init_timer, 1); 2289 do { 2290 SOC_IF_ERROR_RETURN(READ_LLS_INITr(unit, &rval)); 2291 if (soc_reg_field_get(unit, LLS_INITr, rval, INIT_DONEf)) { 2292 break; 2293 } 2294 if (soc_timeout_check(&to)) { 2295 LOG_WARN(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "LLS INIT timeout\n"))); 2296 break; 2297 } 2298 } while (TRUE); 2299 2300 return SOC_E_NONE; 2301 } 2302 2303 2304 2305 /* Place holder for mmu init time defaults */ 2306 STATIC int 2307 _soc_apache_mmu_init_default_val(int unit) 2308 { 2309 2310 /* Initialize LLS tree to reset state */ 2311 SOC_IF_ERROR_RETURN(_soc_apache_lls_hw_init(unit)); 2312 2313 return SOC_E_NONE; 2314 } 2315 2316 int 2317 _soc_apache_mem_ser_control(int unit, soc_mem_t mem, int copyno, 2318 int enable) 2319 { 2320 if (enable) { 2321 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr, 2322 REG_PORT_ANY, TOP_MMU_RST_Lf, 0)); 2323 sal_usleep(1000); 2324 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr, 2325 REG_PORT_ANY, TOP_MMU_RST_Lf, 1)); 2326 sal_usleep(1000); 2327 } 2328 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 2329 SOC_IF_ERROR_RETURN(_soc_apache_clear_mmu_memory(unit, INVALIDm)); 2330 SOC_IF_ERROR_RETURN(_soc_apache_ser_enable_all(unit, enable)); 2331 } 2332 if (enable) { 2333 SOC_IF_ERROR_RETURN 2334 (_soc_apache_mmu_init_default_val(unit)); 2335 } 2336 return SOC_E_NONE; 2337 } 2338 2339 STATIC void 2340 _soc_apache_mem_parity_info(int unit, int block_info_idx, int pipe, 2341 soc_field_t field_enum, uint32 *minfo) 2342 { 2343 *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) 2344 | ((pipe & 0xff) << SOC_ERROR_PIPE_BP) 2345 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK); 2346 } 2347 2348 STATIC int 2349 _soc_apache_mem_is_dyn(int unit, soc_mem_t mem) 2350 { 2351 if (SOC_MEM_FIELD_VALID(unit, mem, HITf) || 2352 SOC_MEM_FIELD_VALID(unit, mem, HIT0f) || 2353 SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) || 2354 SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) || 2355 SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) || 2356 SOC_MEM_FIELD_VALID(unit, mem, HITSAf) || 2357 SOC_MEM_FIELD_VALID(unit, mem, HITDAf) || 2358 SOC_MEM_FIELD_VALID(unit, mem, B0_HITf) || 2359 SOC_MEM_FIELD_VALID(unit, mem, B1_HITf)) { 2360 return 1; 2361 } 2362 if (mem == L2_ENTRY_ONLY_ECCm || 2363 mem == L3_ENTRY_ONLY_ECCm || 2364 mem == L3_DEFIP_ALPM_ECCm) { 2365 return 1; 2366 } 2367 return 0; 2368 } 2369 2370 STATIC int 2371 _soc_apache_populate_ser_log(int unit, soc_reg_t parity_enable_reg, 2372 soc_field_t parity_enable_field, 2373 soc_mem_t mem, 2374 int mem_block, 2375 soc_acc_type_t acc_type, 2376 int index, 2377 sal_usecs_t detect_time, 2378 uint32 sblk, 2379 uint32 address) 2380 { 2381 uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 2382 int log_entry_size, id, entry_dw; 2383 uint32 *cache; 2384 uint8 *vmap; 2385 soc_ser_log_tlv_memory_t log_mem; 2386 soc_ser_log_tlv_generic_t log_generic; 2387 2388 sal_memset(&log_generic, 0, sizeof(log_generic)); 2389 sal_memset(&log_mem, 0, sizeof(log_mem)); 2390 2391 /* 2392 must be large enough for at least generic and terminator, as well as the 2393 memory type since we might decode it in soc_ser_correction. 2394 */ 2395 log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 + 2396 sizeof(soc_ser_log_tlv_generic_t) + 2397 sizeof(soc_ser_log_tlv_memory_t); 2398 2399 if (mem == INVALIDm) { 2400 mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address); 2401 if (mem != INVALIDm) { 2402 if (sblk) { 2403 SOC_MEM_BLOCK_ITER(unit, mem, mem_block) { 2404 if (SOC_BLOCK2OFFSET(unit, mem_block) == sblk) { 2405 break; 2406 } 2407 } 2408 } else { 2409 mem_block = SOC_MEM_BLOCK_ANY(unit, mem); 2410 } 2411 } 2412 } 2413 /* 2414 If we have decoded the memory we can record its contents/cache 2415 */ 2416 if((mem != INVALIDm) && 2417 (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) { 2418 entry_dw = soc_mem_entry_words(unit, mem); 2419 2420 /* Check to make sure this isn't a duplicate */ 2421 /* Search for a log entry with the same mem, and index with within the last 5 seconds */ 2422 if (soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()) > 0) { 2423 return 0; 2424 } 2425 2426 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2427 2428 cache = SOC_MEM_STATE(unit, mem).cache[mem_block]; 2429 vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block]; 2430 if (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CACHABLE) { 2431 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4; 2432 } 2433 2434 /* create the entry based on determined size, save id */ 2435 id = soc_ser_log_create_entry(unit, log_entry_size); 2436 2437 /* Add the memory information to the log now so we can detect duplicate errors */ 2438 log_generic.time = detect_time; 2439 log_mem.memory = mem; 2440 log_mem.index = index; 2441 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY, 2442 sizeof(soc_ser_log_tlv_memory_t), &log_mem); 2443 soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC, 2444 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 2445 2446 if (!_soc_apache_mem_is_dyn(unit, mem) && 2447 (parity_enable_reg != INVALIDr) && 2448 (parity_enable_field != INVALIDf)) { 2449 2450 /* Disable Parity */ 2451 if (soc_reg_field32_modify(unit, parity_enable_reg, 2452 REG_PORT_ANY, parity_enable_field, 0) < 0) { 2453 return 0; 2454 } 2455 2456 /*Enable NACK on read */ 2457 soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN, 2458 mem, 0, mem_block, 2459 index, tmp_entry); 2460 2461 /* fill in the memory contents tlv */ 2462 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS, 2463 entry_dw*4, tmp_entry) < 0) { 2464 return 0; 2465 } 2466 2467 /* Enable Parity */ 2468 if (soc_reg_field32_modify(unit, parity_enable_reg, 2469 REG_PORT_ANY, parity_enable_field, 1) < 0) { 2470 return 0; 2471 } 2472 } 2473 2474 2475 if(cache != NULL && CACHE_VMAP_TST(vmap, index)) { 2476 /* fill in the memory cache tlv */ 2477 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE, 2478 entry_dw*4, (cache + index*entry_dw)) < 0) { 2479 return 0; 2480 } 2481 } 2482 } else { 2483 id = soc_ser_log_create_entry(unit, log_entry_size); 2484 } 2485 2486 return id; 2487 } 2488 2489 STATIC int 2490 _soc_apache_ser_process_parity(int unit, int block_info_idx, int pipe, 2491 int port, const _soc_apache_ser_info_t *info, 2492 int schan, char *prefix_str, char *mem_str) 2493 { 2494 int rv; 2495 _soc_apache_ser_reg_t reg_entry[2], *reg_ptr; 2496 soc_reg_t reg; 2497 uint32 rval, minfo; 2498 uint32 multiple, entry_idx, idx, has_error; 2499 char *mem_str_ptr; 2500 _soc_ser_correct_info_t spci; 2501 2502 if (schan) { 2503 /* Some table does not have NACK register */ 2504 return SOC_E_NONE; 2505 } else { 2506 if (info->intr_status_reg != INVALIDr) { 2507 reg_entry[0].reg = info->intr_status_reg; 2508 reg_entry[0].mem_str = NULL; 2509 reg_entry[1].reg = INVALIDr; 2510 reg_ptr = reg_entry; 2511 } else if (info->intr_status_reg_list != NULL) { 2512 reg_ptr = info->intr_status_reg_list; 2513 } else { 2514 return SOC_E_NONE; 2515 } 2516 } 2517 2518 has_error = FALSE; 2519 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2520 reg = reg_ptr[idx].reg; 2521 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2522 reg_ptr[idx].mem_str : mem_str; 2523 SOC_IF_ERROR_RETURN 2524 (soc_reg32_get(unit, reg, port, 0, &rval)); 2525 2526 if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) { 2527 has_error = TRUE; 2528 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2529 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2530 _soc_apache_mem_parity_info(unit, block_info_idx, pipe, 2531 info->group_reg_status_field, &minfo); 2532 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2533 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2534 entry_idx, minfo); 2535 LOG_WARN(BSL_LS_SOC_SER, 2536 (BSL_META_U(unit, 2537 "%s %s entry %d parity error\n"), 2538 prefix_str, mem_str_ptr, entry_idx)); 2539 if (multiple) { 2540 LOG_WARN(BSL_LS_SOC_SER, 2541 (BSL_META_U(unit, 2542 "%s %s has multiple parity errors\n"), 2543 prefix_str, mem_str_ptr)); 2544 } 2545 if (idx == 0 && info->mem != INVALIDm) { 2546 sal_memset(&spci, 0, sizeof(spci)); 2547 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 2548 if (multiple) { 2549 spci.flags |= SOC_SER_ERR_MULTI; 2550 } 2551 spci.reg = INVALIDr; 2552 spci.mem = info->mem; 2553 spci.blk_type = -1; 2554 spci.index = entry_idx; 2555 spci.parity_type = info->type; 2556 spci.detect_time = sal_time_usecs(); 2557 spci.log_id = _soc_apache_populate_ser_log(unit, 2558 info->enable_reg, 2559 info->enable_field, 2560 spci.mem, 2561 SOC_MEM_BLOCK_ANY(unit, spci.mem), 2562 spci.acc_type, 2563 spci.index, 2564 spci.detect_time, 2565 spci.sblk, 2566 spci.addr); 2567 rv = soc_ser_correction(unit, &spci); 2568 if (spci.log_id != 0) { 2569 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2570 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 2571 spci.log_id, 0); 2572 } 2573 if (SOC_FAILURE(rv)) { 2574 /* Add reporting failed to correct event flag to 2575 * application */ 2576 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2577 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2578 entry_idx, minfo); 2579 return rv; 2580 } 2581 } 2582 } 2583 2584 /* Clear parity status */ 2585 SOC_IF_ERROR_RETURN 2586 (soc_reg32_set(unit, reg, port, 0, 0)); 2587 } 2588 2589 if (!has_error) { 2590 LOG_ERROR(BSL_LS_SOC_SER, 2591 (BSL_META_U(unit, 2592 "%s %s parity hardware inconsistency\n"), 2593 prefix_str, mem_str)); 2594 } 2595 2596 return SOC_E_NONE; 2597 } 2598 2599 STATIC int 2600 _soc_apache_ser_process_ecc(int unit, int block_info_idx, int pipe, int port, 2601 const _soc_apache_ser_info_t *info, 2602 int schan, char *prefix_str, char *mem_str) 2603 { 2604 int rv; 2605 _soc_apache_ser_reg_t reg_entry[2], *reg_ptr; 2606 soc_reg_t reg; 2607 uint32 rval, minfo; 2608 uint64 rval64; 2609 uint32 ecc_err, multiple, double_bit, entry_idx, idx, has_error; 2610 char *mem_str_ptr; 2611 _soc_ser_correct_info_t spci; 2612 2613 if (schan) { 2614 /* Some table does not have NACK register */ 2615 return SOC_E_NONE; 2616 } else { 2617 if (info->intr_status_reg != INVALIDr) { 2618 reg_entry[0].reg = info->intr_status_reg; 2619 reg_entry[0].mem_str = NULL; 2620 reg_entry[1].reg = INVALIDr; 2621 reg_ptr = reg_entry; 2622 } else if (info->intr_status_reg_list != NULL) { 2623 reg_ptr = info->intr_status_reg_list; 2624 } else { 2625 return SOC_E_NONE; 2626 } 2627 } 2628 2629 has_error = FALSE; 2630 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2631 reg = reg_ptr[idx].reg; 2632 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2633 reg_ptr[idx].mem_str : mem_str; 2634 2635 if (SOC_REG_IS_64(unit, reg)) { 2636 SOC_IF_ERROR_RETURN 2637 (soc_reg64_get(unit, reg, port, 0, &rval64)); 2638 ecc_err = soc_reg64_field32_get(unit, reg, rval64, ECC_ERRf); 2639 multiple = soc_reg64_field32_get(unit, reg, rval64, MULTIPLE_ERRf); 2640 double_bit = soc_reg64_field32_get(unit, reg, rval64, DOUBLE_BIT_ERRf); 2641 entry_idx = soc_reg64_field32_get(unit, reg, rval64, ENTRY_IDXf); 2642 } else { 2643 SOC_IF_ERROR_RETURN 2644 (soc_reg32_get(unit, reg, port, 0, &rval)); 2645 ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf); 2646 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2647 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf); 2648 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2649 } 2650 2651 if (ecc_err) { 2652 has_error = TRUE; 2653 _soc_apache_mem_parity_info(unit, block_info_idx, pipe, 2654 info->group_reg_status_field, &minfo); 2655 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2656 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 2657 entry_idx, minfo); 2658 sal_memset(&spci, 0, sizeof(spci)); 2659 if (double_bit) { 2660 spci.double_bit = 1; 2661 LOG_WARN(BSL_LS_SOC_SER, 2662 (BSL_META_U(unit, 2663 "%s %s entry %d double-bit ECC error\n"), 2664 prefix_str, mem_str_ptr, entry_idx)); 2665 } else { 2666 LOG_WARN(BSL_LS_SOC_SER, 2667 (BSL_META_U(unit, 2668 "%s %s entry %d ECC error\n"), 2669 prefix_str, mem_str_ptr, entry_idx)); 2670 } 2671 if (multiple) { 2672 LOG_WARN(BSL_LS_SOC_SER, 2673 (BSL_META_U(unit, 2674 "%s %s has multiple ECC errors\n"), 2675 prefix_str, mem_str_ptr)); 2676 } 2677 if (idx == 0 && info->mem != INVALIDm) { 2678 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE; 2679 if (multiple) { 2680 spci.flags |= SOC_SER_ERR_MULTI; 2681 } 2682 spci.reg = INVALIDr; 2683 spci.mem = info->mem; 2684 spci.blk_type = -1; 2685 spci.index = entry_idx; 2686 spci.parity_type = info->type; 2687 spci.detect_time = sal_time_usecs(); 2688 spci.log_id = _soc_apache_populate_ser_log(unit, 2689 info->enable_reg, 2690 info->enable_field, 2691 spci.mem, 2692 SOC_MEM_BLOCK_ANY(unit, spci.mem), 2693 spci.acc_type, 2694 spci.index, 2695 spci.detect_time, 2696 spci.sblk, 2697 spci.addr); 2698 rv = soc_ser_correction(unit, &spci); 2699 if (spci.log_id != 0) { 2700 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2701 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 2702 spci.log_id, 0); 2703 } 2704 if (SOC_FAILURE(rv)) { 2705 /* Add reporting failed to correct event flag to 2706 * application */ 2707 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 2708 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 2709 entry_idx, minfo); 2710 return rv; 2711 } 2712 } 2713 } 2714 2715 /* Clear parity status */ 2716 if (SOC_REG_IS_64(unit, reg)) { 2717 COMPILER_64_ZERO(rval64); 2718 SOC_IF_ERROR_RETURN 2719 (soc_reg64_set(unit, reg, port, 0, rval64)); 2720 } else { 2721 SOC_IF_ERROR_RETURN 2722 (soc_reg32_set(unit, reg, port, 0, 0)); 2723 } 2724 } 2725 2726 if (!has_error) { 2727 LOG_ERROR(BSL_LS_SOC_SER, 2728 (BSL_META_U(unit, 2729 "%s %s ECC hardware inconsistency\n"), 2730 prefix_str, mem_str)); 2731 } 2732 2733 return SOC_E_NONE; 2734 } 2735 2736 STATIC int 2737 _soc_apache_ser_process_mac(int unit, int block_info_idx, int pipe, int port, 2738 const _soc_apache_ser_info_t *info, 2739 int schan, char *prefix_str, char *mem_str) 2740 { 2741 _soc_apache_ser_reg_t reg_entry[2], *reg_ptr; 2742 soc_reg_t reg; 2743 soc_field_t single_bit_f, double_bit_f; 2744 uint64 rval; 2745 uint32 single_bit = 0, double_bit = 0, idx; 2746 char *mem_str_ptr; 2747 2748 if (schan) { 2749 /* Some table does not have NACK register */ 2750 return SOC_E_NONE; 2751 } else { 2752 if (info->intr_status_reg != INVALIDr) { 2753 reg_entry[0].reg = info->intr_status_reg; 2754 reg_entry[0].mem_str = NULL; 2755 reg_entry[1].reg = INVALIDr; 2756 reg_ptr = reg_entry; 2757 } else if (info->intr_status_reg_list != NULL) { 2758 reg_ptr = info->intr_status_reg_list; 2759 } else { 2760 return SOC_E_NONE; 2761 } 2762 } 2763 2764 switch (info->type) { 2765 case _SOC_PARITY_TYPE_MAC_TX_CDC: 2766 single_bit_f = TX_CDC_SINGLE_BIT_ERRf; 2767 double_bit_f = TX_CDC_DOUBLE_BIT_ERRf; 2768 break; 2769 case _SOC_PARITY_TYPE_MAC_RX_CDC: 2770 single_bit_f = RX_CDC_SINGLE_BIT_ERRf; 2771 double_bit_f = RX_CDC_DOUBLE_BIT_ERRf; 2772 break; 2773 case _SOC_PARITY_TYPE_MAC_RX_TS: 2774 single_bit_f = RX_TS_MEM_SINGLE_BIT_ERRf; 2775 double_bit_f = RX_TS_MEM_DOUBLE_BIT_ERRf; 2776 break; 2777 default: 2778 return SOC_E_PARAM; 2779 } 2780 2781 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2782 reg = reg_ptr[idx].reg; 2783 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? reg_ptr[idx].mem_str : mem_str; 2784 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, reg, port, 0, &rval)); 2785 2786 single_bit = soc_reg64_field32_get(unit, reg, rval, single_bit_f); 2787 double_bit = soc_reg64_field32_get(unit, reg, rval, double_bit_f); 2788 if (single_bit || double_bit) { 2789 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2790 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0); 2791 if (double_bit) { 2792 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2793 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0); 2794 LOG_WARN(BSL_LS_SOC_SER, 2795 (BSL_META_U(unit, 2796 "%s %s double-bit ECC error on port %d\n"), 2797 prefix_str, mem_str_ptr, port)); 2798 } else { 2799 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2800 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0); 2801 LOG_WARN(BSL_LS_SOC_SER, 2802 (BSL_META_U(unit, 2803 "%s %s single-bit ECC error on port %d\n"), 2804 prefix_str, mem_str_ptr, port)); 2805 } 2806 } 2807 2808 /* Clear parity status by a rising edge on intr_clr_field in intr_clr_reg */ 2809 SOC_IF_ERROR_RETURN 2810 (soc_reg64_get(unit, info->intr_clr_reg, port, 0, &rval)); 2811 if (single_bit) { 2812 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 0); 2813 SOC_IF_ERROR_RETURN 2814 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 2815 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 1); 2816 SOC_IF_ERROR_RETURN 2817 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 2818 } 2819 if (double_bit) { 2820 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 0); 2821 SOC_IF_ERROR_RETURN 2822 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 2823 soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 1); 2824 SOC_IF_ERROR_RETURN 2825 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval)); 2826 } 2827 } 2828 2829 return SOC_E_NONE; 2830 } 2831 2832 STATIC int 2833 _soc_apache_ser_process_mib(int unit, int block_info_idx, int pipe, int port, 2834 const _soc_apache_ser_info_t *info, 2835 int schan, char *prefix_str, char *mem_str) 2836 { 2837 _soc_apache_ser_reg_t reg_entry[2], *reg_ptr; 2838 soc_reg_t reg; 2839 uint32 rval; 2840 uint32 ecc_err, multiple, double_bit, entry_idx, idx, has_error; 2841 char *mem_str_ptr; 2842 2843 if (schan) { 2844 /* Some table does not have NACK register */ 2845 return SOC_E_NONE; 2846 } else { 2847 if (info->intr_status_reg != INVALIDr) { 2848 reg_entry[0].reg = info->intr_status_reg; 2849 reg_entry[0].mem_str = NULL; 2850 reg_entry[1].reg = INVALIDr; 2851 reg_ptr = reg_entry; 2852 } else if (info->intr_status_reg_list != NULL) { 2853 reg_ptr = info->intr_status_reg_list; 2854 } else { 2855 return SOC_E_NONE; 2856 } 2857 } 2858 2859 has_error = FALSE; 2860 for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) { 2861 reg = reg_ptr[idx].reg; 2862 mem_str_ptr = reg_ptr[idx].mem_str != NULL ? 2863 reg_ptr[idx].mem_str : mem_str; 2864 2865 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 2866 ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf); 2867 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf); 2868 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf); 2869 entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf); 2870 2871 if (ecc_err) { 2872 has_error = TRUE; 2873 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2874 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0); 2875 if (double_bit) { 2876 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2877 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 2878 entry_idx, 0); 2879 LOG_WARN(BSL_LS_SOC_SER, 2880 (BSL_META_U 2881 (unit, "%s %s double-bit ECC error on port %d\n"), 2882 prefix_str, mem_str_ptr, port)); 2883 } else { 2884 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 2885 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 2886 entry_idx, 0); 2887 LOG_WARN(BSL_LS_SOC_SER, 2888 (BSL_META_U 2889 (unit, "%s %s single-bit ECC error on port %d\n"), 2890 prefix_str, mem_str_ptr, port)); 2891 } 2892 2893 if (multiple) { 2894 LOG_WARN(BSL_LS_SOC_SER, 2895 (BSL_META_U(unit, "%s %s has multiple ECC errors\n"), 2896 prefix_str, mem_str_ptr)); 2897 } 2898 if (double_bit) { 2899 /* Entry Idx: 2900 * 0-15 Port 0 2901 * 16-31 Port 1 2902 * 32-47 Port 2 2903 * 48-63 Port 3 2904 * In case of double-bit error we need to reset MIB counters 2905 * for that port to recover 2906 */ 2907 rval = 0x1 << ((entry_idx & 63) / 16); 2908 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, rval)); 2909 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, 0x0)); 2910 } 2911 } 2912 2913 /* Clear parity status */ 2914 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, 0)); 2915 } 2916 2917 if (!has_error) { 2918 LOG_ERROR(BSL_LS_SOC_SER, 2919 (BSL_META_U(unit, "%s %s ECC hardware inconsistency\n"), 2920 prefix_str, mem_str)); 2921 } 2922 2923 return SOC_E_NONE; 2924 } 2925 2926 STATIC void 2927 _soc_apache_ser_control_reg_get(int unit, 2928 void *fifo_ser_list, 2929 soc_mem_t mem, 2930 soc_reg_t *ser_control_reg, 2931 soc_field_t *ser_enable_field) 2932 { 2933 int i; 2934 _soc_mem_ser_en_info_t *ser_en_info = NULL; 2935 2936 if ((fifo_ser_list == NULL) || (ser_control_reg == NULL) || 2937 (ser_enable_field == NULL)) { 2938 return; 2939 } 2940 2941 ser_en_info = (_soc_mem_ser_en_info_t*)fifo_ser_list; 2942 for (i = 0; ser_en_info[i].mem != INVALIDm; i++) { 2943 if (ser_en_info[i].mem == mem) { 2944 *ser_control_reg = ser_en_info[i].en_ctrl.ctrl_type.en_reg; 2945 *ser_enable_field = ser_en_info[i].en_ctrl.en_fld; 2946 break; 2947 } 2948 } 2949 } 2950 2951 STATIC int 2952 _soc_apache_ser_process_mmu_err (int unit, int block_info_idx, 2953 const _soc_apache_ser_info_t *info, 2954 char *prefix_str) 2955 { 2956 #if defined(BCM_56560_A0) 2957 uint32 rval, err, addr, bidx; 2958 uint64 rval64; 2959 soc_reg_t reg = MMU_MEM_FAIL_ADDR_64r; 2960 uint8 blk_idx; 2961 uint32 sblk = 0; 2962 int rv = SOC_E_NONE; 2963 _soc_ser_correct_info_t spci; 2964 soc_reg_t parity_enable_reg = INVALIDr; 2965 soc_field_t parity_enable_field = INVALIDf; 2966 2967 SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval)); 2968 if (soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)) { 2969 LOG_ERROR(BSL_LS_SOC_SER, 2970 (BSL_META_U(unit, 2971 "MMU SER interrupt with empty fifo !!\n"))); 2972 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval)); 2973 LOG_WARN(BSL_LS_SOC_SER, 2974 (BSL_META_U(unit, 2975 "MMU ERR status: 0x%08x\n"), rval)); 2976 SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0)); 2977 return rv; 2978 } 2979 SOC_BLOCK_ITER(unit, blk_idx, SOC_BLK_MMU) { 2980 sblk = SOC_BLOCK2SCH(unit, blk_idx); 2981 break; 2982 } 2983 do { 2984 SOC_IF_ERROR_RETURN(READ_MMU_MEM_FAIL_ADDR_64r(unit, &rval64)); 2985 err = soc_reg64_field32_get(unit, reg, rval64, ERR_TYPEf); 2986 addr = soc_reg64_field32_get(unit, reg, rval64, EADDRf); 2987 bidx = soc_reg64_field32_get(unit, reg, rval64, BIDXf); 2988 2989 2990 /* Address reported in MMU_MEM_FAIL_ADDR_64 is the entry offset within 2991 * MMU sub block. The complete Sbus address is composed of MMU sub block 2992 * base address and offset within MMU sub block address space. 2993 */ 2994 addr = (bidx << 26) | addr; 2995 sal_memset(&spci, 0, sizeof(spci)); 2996 spci.flags |= SOC_SER_SRC_MEM; 2997 spci.reg = INVALIDr; 2998 spci.mem = INVALIDm; 2999 spci.acc_type = -1; 3000 spci.blk_type = SOC_BLK_MMU; 3001 spci.sblk = sblk; 3002 spci.detect_time = sal_time_usecs(); 3003 3004 /* Try to decode memory */ 3005 spci.mem = soc_addr_to_mem_extended(unit, sblk, _SOC_ACC_TYPE_PIPE_ANY, addr); 3006 if (spci.mem != INVALIDm) { 3007 spci.index = addr - soc_mem_base(unit, spci.mem); 3008 spci.flags |= SOC_SER_REG_MEM_KNOWN; 3009 _soc_apache_ser_control_reg_get(unit, 3010 _soc_bcm56560_a0_mmu_mem_ser_info, 3011 spci.mem, 3012 &parity_enable_reg, 3013 &parity_enable_field); 3014 } else { 3015 spci.flags |= SOC_SER_REG_MEM_UNKNOWN; 3016 } 3017 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3018 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 3019 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr); 3020 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 3021 spci.log_id = _soc_apache_populate_ser_log(unit, parity_enable_reg, 3022 parity_enable_field, 3023 spci.mem, blk_idx, 3024 _SOC_ACC_TYPE_PIPE_ANY, 3025 spci.index, 3026 spci.detect_time, spci.sblk, 3027 spci.addr); 3028 if ((spci.mem == INVALIDm) || 3029 (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != 0)) { 3030 LOG_WARN(BSL_LS_SOC_SER, 3031 (BSL_META_U(unit, 3032 "MMU ERR Type: %s, Addr: 0x%08x, module: %d\n"), 3033 (err == 1) ? "1B error" : "2B error", addr, bidx)); 3034 rv = soc_ser_correction(unit, &spci); 3035 if (SOC_FAILURE(rv)) { 3036 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3037 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3038 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr); 3039 } 3040 } else { 3041 rv = SOC_E_NONE; 3042 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3043 SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 3044 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr); 3045 } 3046 3047 if (spci.log_id != 0) { 3048 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3049 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3050 spci.log_id, 0); 3051 } 3052 SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval)); 3053 } while (!soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)); 3054 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_CTRr(unit, &rval)); 3055 LOG_WARN(BSL_LS_SOC_SER, 3056 (BSL_META_U(unit, 3057 "MMU ERR ctr: %d\n"), rval)); 3058 SOC_IF_ERROR_RETURN 3059 (soc_reg_field32_modify(unit, info->intr_status_reg, REG_PORT_ANY, 3060 info->group_reg_status_field, 0)); 3061 3062 SOC_IF_ERROR_RETURN 3063 (soc_reg_field32_modify(unit, info->intr_clr_reg, REG_PORT_ANY, 3064 info->intr_clr_field, 1)); 3065 SOC_IF_ERROR_RETURN 3066 (soc_reg_field32_modify(unit, info->intr_clr_reg, REG_PORT_ANY, 3067 info->intr_clr_field, 0)); 3068 return rv; 3069 #else 3070 return SOC_E_NONE; 3071 #endif 3072 } 3073 3074 STATIC int 3075 _soc_apache_ser_process_start_err(int unit, int block_info_idx, 3076 const _soc_apache_ser_info_t *info, 3077 char *prefix_str) 3078 { 3079 #if defined(BCM_56560_A0) 3080 soc_info_t *si; 3081 uint64 rval64; 3082 uint32 pbmp_31_0, pbmp_63_32, pbmp_74_64; 3083 soc_pbmp_t pbmp; 3084 uint32 rval32, minfo; 3085 int port, mmu_port, phy_port; 3086 soc_ser_log_tlv_generic_t log_generic; 3087 int log_id; 3088 3089 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 3090 3091 si = &SOC_INFO(unit); 3092 3093 /* mmu port 52-0 */ 3094 SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR_0r(unit, &rval64)); 3095 pbmp_31_0 = COMPILER_64_LO(rval64); 3096 pbmp_63_32 = COMPILER_64_HI(rval64); 3097 /* mmu port 74-64 */ 3098 SOC_IF_ERROR_RETURN 3099 (soc_reg32_get(unit, START_BY_START_ERROR_1r, REG_PORT_ANY, 0, &rval32)); 3100 pbmp_74_64 = (rval32 & 0x3ff); 3101 SOC_PBMP_CLEAR(pbmp); 3102 SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0); 3103 SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32); 3104 SOC_PBMP_WORD_SET(pbmp, 2, pbmp_74_64); 3105 3106 SOC_PBMP_ITER(pbmp, mmu_port) { 3107 phy_port = si->port_m2p_mapping[mmu_port]; 3108 port = si->port_p2l_mapping[phy_port]; 3109 _soc_apache_mem_parity_info(unit, block_info_idx, 0, 3110 info->group_reg_status_field, &minfo); 3111 /* Report uncorrectable event flag to application */ 3112 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3113 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 3114 minfo); 3115 3116 log_generic.time = sal_time_usecs(); 3117 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 3118 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 3119 log_generic.parity_type = info->type; 3120 3121 log_id = soc_ser_log_create_entry(unit, 3122 sizeof(soc_ser_log_tlv_generic_t) + 3123 sizeof(soc_ser_log_tlv_hdr_t) *2); 3124 3125 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 3126 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 3127 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3128 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 3129 3130 LOG_WARN(BSL_LS_SOC_SER, 3131 (BSL_META_U(unit, 3132 "%s port %d start error detected\n"), prefix_str, 3133 port)); 3134 } 3135 3136 /* Clear parity status */ 3137 COMPILER_64_ZERO(rval64); 3138 SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_0r(unit, rval64)); 3139 SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_1r(unit, rval64)); 3140 3141 return SOC_E_NONE; 3142 #else 3143 return SOC_E_NONE; 3144 #endif 3145 } 3146 3147 STATIC int 3148 _soc_apache_process_ser (int unit, int block_info_idx, int inst, int pipe, 3149 int port, soc_reg_t group_reg, uint64 group_rval, 3150 const _soc_apache_ser_info_t *info_list, 3151 char *prefix_str); 3152 STATIC int 3153 _soc_apache_ser_process_cxxport(int unit, int inst, int pipe, 3154 const _soc_apache_ser_info_t *info, char *prefix_str) 3155 { 3156 soc_reg_t port_reg; 3157 uint64 port_rval; 3158 int block_info_idx, port, blk_idx; 3159 3160 if (info->intr_status_reg == INVALIDr) { 3161 return SOC_E_NONE; 3162 } 3163 3164 if ((inst == 0) || (inst == 3)) { 3165 blk_idx = SOC_BLK_CLPORT; 3166 } else { 3167 blk_idx = SOC_BLK_XLPORT; 3168 } 3169 3170 port = -1; 3171 SOC_BLOCK_ITER(unit, block_info_idx, blk_idx) { 3172 if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst) { 3173 port = SOC_BLOCK_PORT(unit, block_info_idx); 3174 break; 3175 } 3176 } 3177 if (port < 0) { 3178 return SOC_E_NONE; 3179 } 3180 3181 port_reg = info->intr_status_reg; 3182 SOC_IF_ERROR_RETURN 3183 (soc_reg_get(unit, port_reg, port, 0, &port_rval)); 3184 if (COMPILER_64_IS_ZERO(port_rval)) { 3185 return SOC_E_NONE; 3186 } 3187 3188 SOC_IF_ERROR_RETURN 3189 (_soc_apache_process_ser(unit, block_info_idx, inst, pipe, port, 3190 port_reg, port_rval, info->info, prefix_str)); 3191 3192 return SOC_E_NONE; 3193 } 3194 3195 STATIC _soc_apache_bst_hw_cb apache_bst_cb; 3196 3197 STATIC int 3198 _soc_apache_process_mmu_bst(int unit) 3199 { 3200 int rv = SOC_E_NONE; 3201 if (apache_bst_cb) { 3202 rv = apache_bst_cb(unit); 3203 } 3204 return rv; 3205 } 3206 3207 int soc_apache_set_bst_callback(int unit, _soc_apache_bst_hw_cb cb) 3208 { 3209 apache_bst_cb = cb; 3210 return SOC_E_NONE; 3211 } 3212 3213 STATIC int 3214 _soc_apache_process_ser (int unit, int block_info_idx, int inst, int pipe, 3215 int port, soc_reg_t group_reg, uint64 group_rval, 3216 const _soc_apache_ser_info_t *info_list, 3217 char *prefix_str) 3218 { 3219 const _soc_apache_ser_info_t *info; 3220 int info_index; 3221 char *mem_str = "INVALIDm"; 3222 uint32 minfo; 3223 soc_ser_log_tlv_generic_t log_generic; 3224 int log_id; 3225 3226 sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t)); 3227 3228 /* Loop through each info entry in the list */ 3229 for (info_index = 0; ; info_index++) { 3230 info = &info_list[info_index]; 3231 if (info->type == _SOC_PARITY_TYPE_NONE) { 3232 /* End of table */ 3233 break; 3234 } 3235 3236 /* Check status for the info entry in the group register */ 3237 if ((info->group_reg_status_field != INVALIDf) && 3238 (!soc_reg64_field32_get(unit, group_reg, group_rval, 3239 info->group_reg_status_field))) { 3240 continue; 3241 } 3242 3243 if (info->mem_str) { 3244 mem_str = info->mem_str; 3245 } else if (info->mem != INVALIDm) { 3246 mem_str = SOC_MEM_NAME(unit, info->mem); 3247 } else if (info->group_reg_status_field != INVALIDf) { 3248 mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field); 3249 } 3250 3251 /* Handle different parity error reporting style */ 3252 switch (info->type) { 3253 case _SOC_PARITY_TYPE_GENERIC: 3254 _soc_apache_mem_parity_info(unit, block_info_idx, 0, 3255 info->group_reg_status_field, &minfo); 3256 /* Report uncorrectable event flag to application */ 3257 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3258 SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 3259 minfo); 3260 3261 log_generic.time = sal_time_usecs(); 3262 log_generic.boot_count = soc_ser_log_get_boot_count(unit); 3263 log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type; 3264 log_generic.parity_type = info->type; 3265 3266 log_id = soc_ser_log_create_entry(unit, 3267 sizeof(soc_ser_log_tlv_generic_t) + 3268 sizeof(soc_ser_log_tlv_hdr_t) *2); 3269 3270 soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 3271 sizeof(soc_ser_log_tlv_generic_t), &log_generic); 3272 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3273 SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0); 3274 3275 LOG_WARN(BSL_LS_SOC_SER, 3276 (BSL_META_U(unit, 3277 "%s %s asserted\n"), prefix_str, mem_str)); 3278 break; 3279 case _SOC_PARITY_TYPE_PARITY: 3280 /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */ 3281 SOC_IF_ERROR_RETURN 3282 (_soc_apache_ser_process_parity(unit, block_info_idx, 3283 pipe, port, info, FALSE, 3284 prefix_str, mem_str)); 3285 break; 3286 case _SOC_PARITY_TYPE_ECC: 3287 /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */ 3288 SOC_IF_ERROR_RETURN 3289 (_soc_apache_ser_process_ecc(unit, block_info_idx, pipe, 3290 port, info, FALSE, 3291 prefix_str, mem_str)); 3292 break; 3293 case _SOC_PARITY_TYPE_MIB: 3294 /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */ 3295 SOC_IF_ERROR_RETURN 3296 (_soc_apache_ser_process_mib(unit, block_info_idx, pipe, 3297 port, info, FALSE, 3298 prefix_str, mem_str)); 3299 /* MIB_RX_MEM_ERR and MIB_TX_MEM_ERR in PORT_INTR_STATUS are write 1 to clear 3300 * So we write back the status we read. 3301 */ 3302 SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval)); 3303 break; 3304 case _SOC_PARITY_TYPE_MAC_TX_CDC: 3305 case _SOC_PARITY_TYPE_MAC_RX_CDC: 3306 case _SOC_PARITY_TYPE_MAC_RX_TS: 3307 /* xxx_SINGLE_BIT_ERRf, xxx_DOUBLE_BIT_ERRf */ 3308 SOC_IF_ERROR_RETURN 3309 (_soc_apache_ser_process_mac(unit, block_info_idx, pipe, 3310 port, info, FALSE, 3311 prefix_str, mem_str)); 3312 /* MAC_RX_CDC_MEM_ERR, MAC_TX_CDC_MEM_ERR, MAC_RX_TS_CDC_MEM_ERR 3313 * in PORT_INTR_STATUS are write 1 to clear 3314 * So we write back the status we read. 3315 */ 3316 SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval)); 3317 break; 3318 case _SOC_PARITY_TYPE_CXXPORT: 3319 /* One more level of report tree structure */ 3320 SOC_IF_ERROR_RETURN 3321 (_soc_apache_ser_process_cxxport(unit, info->id, pipe, info, prefix_str)); 3322 break; 3323 case _SOC_PARITY_TYPE_START_ERR: 3324 SOC_IF_ERROR_RETURN 3325 (_soc_apache_ser_process_start_err(unit, block_info_idx, 3326 info, prefix_str)); 3327 break; 3328 case _SOC_PARITY_TYPE_MMU_SER: 3329 SOC_IF_ERROR_RETURN 3330 (_soc_apache_ser_process_mmu_err(unit, block_info_idx, 3331 info, prefix_str)); 3332 break; 3333 case _SOC_PARITY_TYPE_BST: 3334 SOC_IF_ERROR_RETURN(_soc_apache_process_mmu_bst(unit)); 3335 break; 3336 default: 3337 break; 3338 } /* Handle different parity error reporting style */ 3339 } /* Loop through each info entry in the list */ 3340 3341 return SOC_E_NONE; 3342 } 3343 3344 STATIC char *_soc_apache_ser_hwmem_base_info[] = { 3345 "CMIC PKT BUFFER - In Iarb", 3346 "CPU PKT BUFFER - In Iarb", 3347 "Invalid value", 3348 "EINITBUF_PACKET_BUFFER - In Iarb", 3349 "INGRESS PACKET BUFFER - In Ipars", 3350 "Invalid value", 3351 "Invalid value", 3352 "Invalid value", 3353 "Invalid value", 3354 "Invalid value", 3355 "Invalid value", 3356 "ISW2_EOP_BUFFER_A - In Iesmif", 3357 "ISW2_EOP_BUFFER_B - In Iesmif", 3358 "ISW2_EOP_BUFFER_C - In Iesmif", 3359 "Invalid value", 3360 "Invalid value", 3361 "EP MPB DATA - In El3", 3362 "EP INITBUF - In Ehcpm", 3363 "CM DATA BUFFER - In Edatabuf", 3364 "XLP0 DATA BUFFER - In Edatabuf", 3365 "XLP1 DATA BUFFER - In Edatabuf", 3366 "XLP2 DATA BUFFER - In Edatabuf", 3367 "XLP3 DATA BUFFER - In Edatabuf", 3368 "XLP4 DATA BUFFER - In Edatabuf", 3369 "XLP5 DATA BUFFER - In Edatabuf", 3370 "XLP6 DATA BUFFER - In Edatabuf", 3371 "CLP1 DATA BUFFER - In Edatabuf", 3372 "CLP2 DATA BUFFER - In Edatabuf", 3373 "XLP7 DATA BUFFER - In Edatabuf", 3374 "XLP8 DATA BUFFER - In Edatabuf", 3375 "XLP9 DATA BUFFER - In Edatabuf", 3376 "XLP10 DATA BUFFER - In Edatabuf", 3377 "XLP11 DATA BUFFER - In Edatabuf", 3378 "XLP12 DATA BUFFER - In Edatabuf", 3379 "XLP13 DATA BUFFER - In Edatabuf", 3380 "CLP4 DATA BUFFER - In Edatabuf", 3381 "CLP5 DATA BUFFER - In Edatabuf", 3382 "CLP0 DATA BUFFER - In Edatabuf", 3383 "CLP3 DATA BUFFER - In Edatabuf", 3384 "RESI0 DATA BUFFER - In Edatabuf", 3385 "RESI1 DATA BUFFER - In Edatabuf", 3386 "RESI2 DATA BUFFER - In Edatabuf", 3387 "RESI3 DATA BUFFER - In Edatabuf", 3388 "Invalid value", 3389 "Invalid value", 3390 "Invalid value", 3391 "Invalid value", 3392 "Invalid value", 3393 "Invalid value", 3394 "Invalid value", 3395 "Invalid value", 3396 "XLP0 EDB CTRL BUFFER - In Edatabuf", 3397 "XLP1 EDB CTRL BUFFER - In Edatabuf", 3398 "XLP2 EDB CTRL BUFFER - In Edatabuf", 3399 "XLP3 EDB CTRL BUFFER - In Edatabuf", 3400 "XLP4 EDB CTRL BUFFER - In Edatabuf", 3401 "XLP5 EDB CTRL BUFFER - In Edatabuf", 3402 "XLP6 EDB CTRL BUFFER - In Edatabuf", 3403 "CLP1 EDB CTRL BUFFER - In Edatabuf", 3404 "CLP2 EDB CTRL BUFFER - In Edatabuf", 3405 "XLP7 EDB CTRL BUFFER - In Edatabuf", 3406 "XLP8 EDB CTRL BUFFER - In Edatabuf", 3407 "XLP9 EDB CTRL BUFFER - In Edatabuf", 3408 "XLP10 EDB CTRL BUFFER - In Edatabuf", 3409 "XLP11 EDB CTRL BUFFER - In Edatabuf", 3410 "XLP12 EDB CTRL BUFFER - In Edatabuf", 3411 "XLP13 EDB CTRL BUFFER - In Edatabuf", 3412 "CLP4 EDB CTRL BUFFER - In Edatabuf", 3413 "CLP5 EDB CTRL BUFFER - In Edatabuf", 3414 "CLP0 EDB CTRL BUFFER - In Edatabuf", 3415 "CLP3 EDB CTRL BUFFER - In Edatabuf", 3416 "LEARN FIFO - In IARB", 3417 "IFP_COUNTER_MUX_DATA_STAGING - In Ifp", 3418 "Invalid value", 3419 "Invalid value", 3420 "Invalid value", 3421 "Invalid value", 3422 "Invalid value", 3423 "Invalid value", 3424 "Invalid value", 3425 "IFP_METER_MUX_DATA_STAGING_0 - In Ifp", 3426 "IFP_METER_MUX_DATA_STAGING_1 - In Ifp", 3427 "IFP_METER_MUX_DATA_STAGING_2 - In Ifp", 3428 "IFP_METER_MUX_DATA_STAGING_3 - In Ifp", 3429 "IFP_METER_MUX_DATA_STAGING_4 - In Ifp", 3430 "IFP_METER_MUX_DATA_STAGING_5 - In Ifp", 3431 "IFP_METER_MUX_DATA_STAGING_6 - In Ifp", 3432 "IFP_METER_MUX_DATA_STAGING_7 - In Ifp", 3433 "EGR VLAN BUS", 3434 "EGR HCPM BUS", 3435 "EGR PMOD BUS", 3436 "EGR FPPARS BUS", 3437 "EFP BUS", 3438 "IVP BUS", 3439 "ICFG BUS", 3440 "Invalid value", 3441 "Invalid value", 3442 "Invalid value", 3443 "Invalid value", 3444 "Invalid value", 3445 "Invalid value", 3446 "Invalid value", 3447 "Invalid value", 3448 "Invalid value", 3449 "IPARS BUS", 3450 "IVXLT BUS", 3451 "IMPLS BUS", 3452 "IL2L3 BUS", 3453 "Invalid value", 3454 "IFP BUS", 3455 "IRSEL1 BUS", 3456 "ISW1 BUS", 3457 "IRSEL2 BUS" 3458 "IFP_PASSTHRU_HIGHWAY_BUFFER" 3459 "EFPMOD_EMOP_BUFFER" 3460 }; 3461 3462 #define _SOC_APACHE_SER_REG 1 3463 #define _SOC_APACHE_SER_MEM 0 3464 3465 STATIC void 3466 _soc_apache_print_ser_fifo_details (int unit, uint8 regmem, soc_block_t blk, 3467 uint32 sblk, int pipe, uint32 address, 3468 uint32 stage, uint32 base, uint32 index, 3469 uint32 hwmbase, uint32 type, uint32 drop, 3470 uint32 non_sbus) 3471 { 3472 uint32 hwmbase_max; 3473 3474 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityError, unit)) { 3475 switch (type) { 3476 case 0: 3477 LOG_WARN(BSL_LS_SOC_SER, 3478 (BSL_META_U(unit, 3479 "Error in: SOP cell.\n"))); 3480 break; 3481 case 1: 3482 LOG_WARN(BSL_LS_SOC_SER, 3483 (BSL_META_U(unit, 3484 "Error in: MOP cell.\n"))); 3485 break; 3486 case 2: 3487 LOG_WARN(BSL_LS_SOC_SER, 3488 (BSL_META_U(unit, 3489 "Error in: EOP cell.\n"))); 3490 break; 3491 case 3: 3492 LOG_WARN(BSL_LS_SOC_SER, 3493 (BSL_META_U(unit, 3494 "Error in: SBUS transaction.\n"))); 3495 break; 3496 case 4: 3497 LOG_WARN(BSL_LS_SOC_SER, 3498 (BSL_META_U(unit, 3499 "Error in: miscellaneous transaction.\n"))); 3500 break; 3501 default: 3502 LOG_WARN(BSL_LS_SOC_SER, 3503 (BSL_META_U(unit, 3504 "Invalid error reported !!\n"))); 3505 break; 3506 } 3507 LOG_WARN(BSL_LS_SOC_SER, 3508 (BSL_META_U(unit, 3509 "Blk: %d, Pipe: %d, Address: 0x%08x, base: 0x%x, stage: %d, index: %d\n"), 3510 sblk, pipe, address, base, stage, index)); 3511 if (regmem == _SOC_APACHE_SER_MEM) { 3512 if (hwmbase >= 0x80) { 3513 hwmbase -= 0x28; /* handle the gap */ 3514 } 3515 if (non_sbus) { 3516 hwmbase_max = sizeof(_soc_apache_ser_hwmem_base_info)/sizeof(_soc_apache_ser_hwmem_base_info[0]); 3517 LOG_WARN(BSL_LS_SOC_SER, 3518 (BSL_META_U(unit, 3519 "Mem hwbase: 0x%x [%s]\n"), hwmbase, 3520 (hwmbase < hwmbase_max) ? _soc_apache_ser_hwmem_base_info[hwmbase] : "--")); 3521 } 3522 } 3523 if (drop) { 3524 LOG_WARN(BSL_LS_SOC_SER, 3525 (BSL_META_U(unit, 3526 "SER caused packet drop.\n"))); 3527 } 3528 } 3529 } 3530 3531 #define IF_IPIPE_ARBITER_LOCK(_unit_, _blk_) \ 3532 if (_blk_ == SOC_BLK_IPIPE) {\ 3533 IP_ARBITER_LOCK(_unit_);\ 3534 } 3535 3536 #define IF_IPIPE_ARBITER_UNLOCK(_unit_, _blk_) \ 3537 if (_blk_ == SOC_BLK_IPIPE) {\ 3538 IP_ARBITER_UNLOCK(_unit_);\ 3539 } 3540 3541 #if defined(BCM_56560_A0) 3542 static uint32 _apache_ser_status_bus_fmt_get (uint32 *entry, int fld) 3543 { 3544 switch(fld) { 3545 case VALIDf: /* Bit 1*/ 3546 return (entry[0] & 0x00000001); 3547 case INSTRUCTION_TYPEf: /* Bits 1-4 */ 3548 return ((entry[0] & 0x0000001E) >> 1); 3549 case HWMEMBASEf: /* Bits 23-30 */ 3550 case MEMBASEf: 3551 return ((entry[0] & 0x7F800000) >> 23); 3552 case MEMINDEXf: /* Bits 5-22 */ 3553 return ((entry[0] & 0x007FFFE0) >> 5); 3554 case REGINDEXf: /* Bits 5-12 */ 3555 return ((entry[0] & 0x00001FE0) >> 5); 3556 case REGBASEf: /* Bits 13-29 */ 3557 return ((entry[0] & 0x3FFFE000) >> 13); 3558 case PIPE_STAGEf: /* Bits 31-36 */ 3559 return (((entry[0] & 0x80000000) >> 31) | 3560 ((entry[1] & 0x0000001F) << 1)); 3561 case ADDRESSf: /* Bits 36-5 */ 3562 return ((entry[0] >> 5) | 3563 ((entry[1] & 0x0000001F) << 27)); 3564 case DROPf: /* Bit 37 */ 3565 return (entry[1] & 0x00000020); 3566 case ECC_PARITYf: /* Bits 38-39 */ 3567 return ((entry[1] & 0x000000C0) >> 6); 3568 case MEM_TYPEf:/* Bit 40 */ 3569 return (entry[1] & 0x00000100); 3570 case NON_SBUSf: /* Bit 41 */ 3571 return (entry[1] & 0x00000200); 3572 case MULTIPLEf: /* Bit 42 */ 3573 return (entry[1] & 0x00000400); 3574 default: 3575 return -1; 3576 } 3577 } 3578 3579 #endif 3580 int 3581 soc_apache_mem_index_remap(int unit, int index, soc_mem_t *mem) 3582 { 3583 int logical_index = -1; 3584 switch (*mem) { 3585 case L3_DEFIPm: 3586 case L3_DEFIP_PAIR_128m: 3587 case L3_DEFIP_ONLYm: 3588 case L3_DEFIP_PAIR_128_ONLYm: 3589 case L3_DEFIP_DATA_ONLYm: 3590 case L3_DEFIP_PAIR_128_DATA_ONLYm: 3591 logical_index = soc_apache_l3_defip_index_remap(unit, *mem, index); 3592 if (logical_index == -1) { 3593 /* This case arises when the passed index (physical) belongs 3594 * to wider view, but the passed mem is narrow view 3595 * Note that below API rewrites mem to the correct (wide) view. 3596 */ 3597 logical_index = soc_apache_l3_defip_mem_index_get(unit, index, mem); 3598 } 3599 return logical_index; 3600 default: 3601 return index; 3602 } 3603 } 3604 3605 STATIC uint32 3606 _soc_apache_flex_ctr_addr_check (int unit, uint32 address, soc_block_t blk, 3607 uint32 stage, uint32 index) 3608 { 3609 uint32 index2 = index; 3610 3611 if ((SOC_BLK_IPIPE == blk) && (21 == stage)) { 3612 switch (address & 0xfffff000) { 3613 /* ING_FLEX_CTR_OFFSET_TABLE_*m */ 3614 case 0x56800000: 3615 case 0x56801000: 3616 case 0x56802000: 3617 case 0x56803000: 3618 case 0x56840000: 3619 case 0x56841000: 3620 case 0x56842000: 3621 case 0x56843000: 3622 index2 = address & 0x3ff; break; /* 1K depth */ 3623 /* ING_FLEX_CTR_COUNTER_TABLE_*m */ 3624 case 0x56804000: 3625 case 0x56808000: 3626 case 0x5680c000: 3627 case 0x56810000: 3628 case 0x56844000: 3629 case 0x56848000: 3630 case 0x5684c000: 3631 case 0x56850000: 3632 index2 = address & 0xfff; break; /* 4K depth */ 3633 default: 3634 break; 3635 } 3636 } 3637 3638 if ((SOC_BLK_EPIPE == blk) && (10 == stage)) { 3639 switch (address & 0XFFFFF000) { 3640 case 0x2a800000: 3641 case 0x2a801000: 3642 case 0x2a802000: 3643 case 0x2a803000: 3644 index2 = address & 0x3ff; break; /* 1K depth */ 3645 case 0x2a804000: 3646 case 0x2a808000: 3647 case 0x2a80c000: 3648 case 0x2a810000: 3649 index2 = address & 0xfff; break; /* 4K depth */ 3650 default: 3651 break; 3652 } 3653 } 3654 return index2; 3655 } 3656 3657 STATIC int 3658 _soc_apache_process_ser_fifo (int unit, soc_block_t blk, char *prefix_str) 3659 { 3660 #if defined(BCM_56560_A0) 3661 int rv; 3662 uint8 bidx; 3663 soc_mem_t mem; 3664 char blk_str[10]; 3665 void *ser_info_table = NULL; 3666 uint32 entry[SOC_MAX_MEM_WORDS], address = 0; 3667 uint32 reg_val = 0, mask = 0; 3668 uint32 stage = 0, addrbase = 0, index = 0, hwmbase = 0, type = 0; 3669 uint32 sblk = 0, regmem = 0, non_sbus = 0, drop = 0, ecc_parity = 0; 3670 soc_reg_t parity_enable_reg = INVALIDr; 3671 soc_field_t parity_enable_field = INVALIDf; 3672 _soc_ser_correct_info_t spci; 3673 soc_reg_t reg = INVALIDr; 3674 3675 switch (blk) { 3676 case SOC_BLK_IPIPE: 3677 mem = ING_SER_FIFOm; 3678 ser_info_table = _soc_bcm56560_a0_ip_mem_ser_info; 3679 sal_sprintf(blk_str, "IPIPE"); 3680 break; 3681 case SOC_BLK_EPIPE: 3682 mem = EGR_SER_FIFOm; 3683 ser_info_table = _soc_bcm56560_a0_ep_mem_ser_info; 3684 mask = 0x00000001; /* SER_FIFO_NON_EMPTYf */ 3685 reg = EGR_INTR_STATUSr; 3686 sal_sprintf(blk_str, "EPIPE"); 3687 break; 3688 default: 3689 return SOC_E_PARAM; 3690 } 3691 3692 IF_IPIPE_ARBITER_LOCK(unit, blk); 3693 do { 3694 sal_memset(&spci, 0, sizeof(spci)); 3695 rv = soc_mem_pop(unit, mem, MEM_BLOCK_ANY, entry); 3696 if (rv != SOC_E_NONE) { 3697 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3698 } 3699 SOC_IF_ERROR_RETURN(rv); 3700 /* process entry */ 3701 if (_apache_ser_status_bus_fmt_get(entry,VALIDf)) { 3702 ecc_parity = _apache_ser_status_bus_fmt_get(entry, ECC_PARITYf); 3703 regmem = _apache_ser_status_bus_fmt_get(entry, MEM_TYPEf); 3704 address = _apache_ser_status_bus_fmt_get(entry, ADDRESSf); 3705 stage = _apache_ser_status_bus_fmt_get(entry, PIPE_STAGEf); 3706 type = _apache_ser_status_bus_fmt_get(entry, INSTRUCTION_TYPEf); 3707 drop = _apache_ser_status_bus_fmt_get(entry, DROPf); 3708 SOC_BLOCK_ITER(unit, bidx, blk) { 3709 sblk = SOC_BLOCK2SCH(unit, bidx); 3710 break; 3711 } 3712 LOG_WARN(BSL_LS_SOC_SER, 3713 (BSL_META_U(unit, 3714 "%s\n"), prefix_str)); 3715 if (_apache_ser_status_bus_fmt_get(entry, MULTIPLEf)) { 3716 LOG_WARN(BSL_LS_SOC_SER, 3717 (BSL_META_U(unit, 3718 "Multiple: "))); 3719 } 3720 if (regmem == _SOC_APACHE_SER_REG ) { 3721 LOG_WARN(BSL_LS_SOC_SER, 3722 (BSL_META_U(unit, 3723 "Reg: "))); 3724 } else { 3725 LOG_WARN(BSL_LS_SOC_SER, 3726 (BSL_META_U(unit, 3727 "Mem: "))); 3728 } 3729 spci.double_bit = 0; 3730 switch (ecc_parity) { 3731 case 0: 3732 LOG_WARN(BSL_LS_SOC_SER, 3733 (BSL_META_U(unit, 3734 "Parity error..\n"))); 3735 spci.parity_type = SOC_PARITY_TYPE_PARITY; 3736 break; 3737 case 1: 3738 LOG_WARN(BSL_LS_SOC_SER, 3739 (BSL_META_U(unit, 3740 "Corrected single bit ECC error..\n"))); 3741 spci.parity_type = SOC_PARITY_TYPE_ECC; 3742 break; 3743 case 2: 3744 LOG_WARN(BSL_LS_SOC_SER, 3745 (BSL_META_U(unit, 3746 "Double or Multiple bit ECC error..\n"))); 3747 spci.parity_type = SOC_PARITY_TYPE_ECC; 3748 spci.double_bit = 1; 3749 spci.flags |= SOC_SER_ERR_MULTI; 3750 break; 3751 default: 3752 LOG_ERROR(BSL_LS_SOC_SER, 3753 (BSL_META_U(unit, 3754 "Invalid SER issue !!\n"))); 3755 3756 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3757 return SOC_E_INTERNAL; 3758 } 3759 if (regmem == _SOC_APACHE_SER_MEM) { 3760 /* process mem */ 3761 non_sbus = _apache_ser_status_bus_fmt_get(entry, NON_SBUSf); 3762 addrbase = _apache_ser_status_bus_fmt_get(entry, MEMBASEf); 3763 index = _apache_ser_status_bus_fmt_get(entry, MEMINDEXf); 3764 hwmbase = _apache_ser_status_bus_fmt_get(entry, HWMEMBASEf); 3765 if (blk == SOC_BLK_IPIPE) { 3766 switch (stage) { 3767 case 7: /* IL2LU_2 */ 3768 case 8: /* IL2LU_3 */ 3769 case 9: /* IL2LU_4 */ 3770 case 11: /* IL3LU_1 */ 3771 case 12: /* IL3LU_2 */ 3772 case 13: /* IL3LU_3 */ 3773 case 15: /* ILPM_1 */ 3774 /* Mems in these stages in IPIPE have more than 256k indexes */ 3775 index |= hwmbase << 18; 3776 hwmbase = addrbase = 0; 3777 default: break; 3778 } 3779 } 3780 3781 index = _soc_apache_flex_ctr_addr_check(unit, address, blk, 3782 stage, index); 3783 if (non_sbus == 0) { 3784 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3785 ecc_parity == 0 ? 3786 SOC_SWITCH_EVENT_DATA_ERROR_PARITY : 3787 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 3788 sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, 3789 address); 3790 _soc_apache_print_ser_fifo_details(unit, 0, blk, sblk, 0, 3791 address, stage, addrbase, 3792 index, hwmbase, type, 3793 drop, non_sbus); 3794 spci.flags = SOC_SER_SRC_MEM; 3795 spci.reg = INVALIDr; 3796 spci.mem = INVALIDm; 3797 spci.blk_type = blk; 3798 spci.sblk = sblk; 3799 spci.addr = address - index; 3800 spci.index = index; 3801 spci.stage = stage; 3802 spci.detect_time = sal_time_usecs(); 3803 spci.mem = soc_addr_to_mem_extended(unit,spci.sblk, 3804 -1,spci.addr); 3805 if (spci.mem != INVALIDm) { 3806 spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 3807 spci.flags |= SOC_SER_REG_MEM_KNOWN; 3808 spci.index = soc_apache_mem_index_remap(unit, index, &(spci.mem)); 3809 } 3810 else { 3811 /* Invalid mem, use the first acc_type_ptr*/ 3812 spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 3813 spci.flags |= SOC_SER_REG_MEM_UNKNOWN; 3814 } 3815 3816 if (spci.mem != INVALIDm) { 3817 _soc_apache_ser_control_reg_get(unit, ser_info_table, 3818 spci.mem, 3819 &parity_enable_reg, 3820 &parity_enable_field); 3821 } 3822 spci.flags |= SOC_SER_LOG_WRITE_CACHE; 3823 spci.log_id = _soc_apache_populate_ser_log(unit, 3824 parity_enable_reg, 3825 parity_enable_field, 3826 spci.mem, 3827 bidx, 3828 spci.acc_type, 3829 spci.index, 3830 spci.detect_time, 3831 spci.sblk, 3832 spci.addr); 3833 3834 rv = soc_ser_correction(unit, &spci); 3835 if (SOC_FAILURE(rv)) { 3836 if (rv != SOC_E_NOT_FOUND) { 3837 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3838 /* Add reporting failed to correct event flag to 3839 * application */ 3840 soc_event_generate(unit, 3841 SOC_SWITCH_EVENT_PARITY_ERROR, 3842 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3843 sblk | 3844 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 3845 return rv; 3846 } 3847 } 3848 if (spci.log_id != 0) { 3849 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3850 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3851 spci.log_id, 0); 3852 } 3853 3854 } else { 3855 LOG_WARN(BSL_LS_SOC_SER, 3856 (BSL_META_U(unit, 3857 "%s SER mem address un-accessable !!\n"), blk_str)); 3858 _soc_apache_print_ser_fifo_details(unit, 0, blk, sblk, 0, address, 3859 stage, addrbase, index, hwmbase, 3860 type, drop, non_sbus); 3861 } 3862 } else { 3863 /* process reg */ 3864 non_sbus = _apache_ser_status_bus_fmt_get(entry, NON_SBUSf); 3865 addrbase = _apache_ser_status_bus_fmt_get(entry, REGBASEf); 3866 index = _apache_ser_status_bus_fmt_get(entry, REGINDEXf); 3867 3868 if (non_sbus == 0) { 3869 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3870 ecc_parity == 0 ? 3871 SOC_SWITCH_EVENT_DATA_ERROR_PARITY : 3872 SOC_SWITCH_EVENT_DATA_ERROR_ECC, 3873 sblk | 3874 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 3875 _soc_apache_print_ser_fifo_details(unit, 1, blk, sblk, 0, 3876 address, stage, addrbase, 3877 index, 0, type, drop, 3878 non_sbus); 3879 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_UNKNOWN; 3880 spci.reg = INVALIDr; 3881 spci.mem = INVALIDm; 3882 spci.blk_type = blk; 3883 spci.sblk = sblk; 3884 spci.addr = address; 3885 spci.index = index; 3886 spci.stage = stage; 3887 spci.detect_time = sal_time_usecs(); 3888 spci.log_id = soc_ser_log_create_entry(unit, 3889 sizeof(soc_ser_log_tlv_generic_t) + 3890 sizeof(soc_ser_log_tlv_register_t) + 3891 sizeof(soc_ser_log_tlv_hdr_t) *3); 3892 rv = soc_ser_correction(unit, &spci); 3893 if (SOC_FAILURE(rv)) { 3894 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3895 /* Add reporting failed to correct event flag to 3896 * application */ 3897 soc_event_generate(unit, 3898 SOC_SWITCH_EVENT_PARITY_ERROR, 3899 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 3900 sblk | 3901 SOC_SER_ERROR_DATA_BLK_ADDR_SET, address); 3902 return rv; 3903 } 3904 if (spci.log_id != 0) { 3905 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 3906 SOC_SWITCH_EVENT_DATA_ERROR_LOG, 3907 spci.log_id, 0); 3908 } 3909 } else { 3910 LOG_WARN(BSL_LS_SOC_SER, 3911 (BSL_META_U(unit, 3912 "%s SER reg address un-accessable !!\n"), blk_str)); 3913 _soc_apache_print_ser_fifo_details(unit, 0, blk, sblk, 0, 3914 address, stage, addrbase, 3915 index, hwmbase, type, 3916 drop, non_sbus); 3917 } 3918 } 3919 } else { 3920 LOG_ERROR(BSL_LS_SOC_SER, 3921 (BSL_META_U(unit, 3922 "unit %d Got invalid mem pop from %s !!\n"), 3923 unit, SOC_MEM_NAME(unit, mem))); 3924 } 3925 3926 if (rv != SOC_E_NONE) { 3927 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3928 } 3929 3930 /* check if any more pending */ 3931 if (reg == INVALIDr) { 3932 rv = READ_CMIC_CMC0_IRQ_STAT2r(unit, ®_val); 3933 } else { 3934 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, ®_val); 3935 } 3936 SOC_IF_ERROR_RETURN(rv); 3937 } while (reg_val & mask); 3938 IF_IPIPE_ARBITER_UNLOCK(unit, blk); 3939 3940 return SOC_E_NONE; 3941 #else 3942 return SOC_E_NONE; 3943 #endif 3944 } 3945 3946 STATIC int 3947 _soc_apache_ser_process_irq3 (int unit, int bit_pos) 3948 { 3949 #if defined(BCM_56560_A0) 3950 uint8 rbi; 3951 int port = REG_PORT_ANY; 3952 uint32 cmic_rval, cmic_bit; 3953 uint64 rb_enable64, rb_rval64, tmp64; 3954 const _soc_apache_ser_route_block_t *rb; 3955 char prefix_str[10]; 3956 int block_info_idx; 3957 soc_stat_t *stat = SOC_STAT(unit); 3958 3959 sal_sprintf(prefix_str, "Unit: %d \n", unit); 3960 3961 /* Read CMIC parity status register */ 3962 SOC_IF_ERROR_RETURN 3963 (READ_CMIC_CMC0_IRQ_STAT3r(unit, &cmic_rval)); 3964 if (cmic_rval == 0) { 3965 return SOC_E_NONE; 3966 } 3967 /* Loop through each place-and-route block entry */ 3968 for (rbi = 0; ; rbi++) { 3969 rb = &_soc_apache_ser_route_blocks_irq3[rbi]; 3970 cmic_bit = rb->cmic_bit; 3971 if (cmic_bit == 0) { 3972 /* End of table */ 3973 break; 3974 } 3975 if (cmic_bit != (1 << bit_pos)) { 3976 continue; 3977 } 3978 if (!(cmic_rval & cmic_bit)) { 3979 /* No interrupt bit asserted for the route block */ 3980 continue; 3981 } 3982 if (rb->blocktype == SOC_BLK_IPIPE || rb->blocktype == SOC_BLK_EPIPE) { 3983 /* New fifo style processing */ 3984 (void)_soc_apache_process_ser_fifo(unit, rb->blocktype, prefix_str); 3985 stat->ser_err_fifo++; 3986 } else { 3987 /* Legacy processing */ 3988 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 3989 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 3990 port = SOC_BLOCK_PORT(unit, block_info_idx); 3991 break; 3992 } 3993 } 3994 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 3995 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 3996 /* This port block is not configured */ 3997 LOG_ERROR(BSL_LS_SOC_SER, 3998 (BSL_META_U(unit, 3999 "unit %d SER error on disabled port block %d !!\n"), 4000 unit, block_info_idx)); 4001 sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */ 4002 continue; 4003 } 4004 /* Read per route block parity status register */ 4005 SOC_IF_ERROR_RETURN 4006 (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64)); 4007 if (COMPILER_64_IS_ZERO(rb_rval64)) { 4008 continue; 4009 } 4010 SOC_IF_ERROR_RETURN 4011 (_soc_apache_process_ser(unit, block_info_idx, rb->id, -1, 4012 port, rb->status_reg, rb_rval64, 4013 rb->info, prefix_str)); 4014 4015 SOC_IF_ERROR_RETURN 4016 (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64)); 4017 COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64)); 4018 COMPILER_64_NOT(tmp64); 4019 COMPILER_64_AND(rb_enable64, tmp64); 4020 SOC_IF_ERROR_RETURN 4021 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4022 COMPILER_64_OR(rb_enable64, rb_rval64); 4023 SOC_IF_ERROR_RETURN 4024 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4025 4026 stat->ser_err_int++; 4027 } 4028 } 4029 return SOC_E_NONE; 4030 #else 4031 return SOC_E_NONE; 4032 #endif 4033 } 4034 4035 STATIC int 4036 _soc_apache_ser_process_irq4 (int unit, int bit_pos) 4037 { 4038 #if defined(BCM_56560_A0) 4039 uint8 rbi; 4040 int port = REG_PORT_ANY; 4041 uint32 cmic_rval, cmic_bit; 4042 uint64 rb_enable64, rb_rval64, tmp64; 4043 char prefix_str[10]; 4044 int block_info_idx; 4045 soc_stat_t *stat = SOC_STAT(unit); 4046 4047 const _soc_apache_ser_route_block_t *rb; 4048 4049 sal_sprintf(prefix_str, "\nUnit: %d: ", unit); 4050 4051 /* Read CMIC parity status register */ 4052 SOC_IF_ERROR_RETURN 4053 (READ_CMIC_CMC0_IRQ_STAT4r(unit, &cmic_rval)); 4054 if (cmic_rval == 0) { 4055 return SOC_E_NONE; 4056 } 4057 4058 /* Loop through each place-and-route block entry */ 4059 for (rbi = 0; ; rbi++) { 4060 if (soc_feature(unit, soc_feature_clport_gen2)) { 4061 rb = &_soc_apache_ser_route_b0_blocks_irq4[rbi]; 4062 } else { 4063 rb = &_soc_apache_ser_route_blocks_irq4[rbi]; 4064 } 4065 cmic_bit = rb->cmic_bit; 4066 if (cmic_bit == 0) { 4067 /* End of table */ 4068 break; 4069 } 4070 if (cmic_bit != (1 << bit_pos)) { 4071 continue; 4072 } 4073 if (!(cmic_rval & cmic_bit)) { 4074 /* No interrupt bit asserted for the route block */ 4075 continue; 4076 } 4077 4078 SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) { 4079 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) { 4080 port = SOC_BLOCK_PORT(unit, block_info_idx); 4081 break; 4082 } 4083 } 4084 4085 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 4086 SOC_BLK_PORT) && (port == REG_PORT_ANY)) { 4087 /* This port block is not configured */ 4088 LOG_ERROR(BSL_LS_SOC_SER, 4089 (BSL_META_U(unit, 4090 "unit %d SER error on disabled port block %d !!\n"), 4091 unit, block_info_idx)); 4092 sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */ 4093 continue; 4094 } 4095 4096 /* Read per route block parity status register */ 4097 SOC_IF_ERROR_RETURN 4098 (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64)); 4099 if (COMPILER_64_IS_ZERO(rb_rval64)) { 4100 continue; 4101 } 4102 4103 SOC_IF_ERROR_RETURN 4104 (_soc_apache_process_ser(unit, block_info_idx, rb->id, -1, 4105 port, rb->status_reg, rb_rval64, 4106 rb->info, prefix_str)); 4107 4108 SOC_IF_ERROR_RETURN 4109 (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64)); 4110 COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64)); 4111 COMPILER_64_NOT(tmp64); 4112 COMPILER_64_AND(rb_enable64, tmp64); 4113 SOC_IF_ERROR_RETURN 4114 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4115 COMPILER_64_OR(rb_enable64, rb_rval64); 4116 SOC_IF_ERROR_RETURN 4117 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64)); 4118 4119 stat->ser_err_int++; 4120 } 4121 4122 return SOC_E_NONE; 4123 #else 4124 return SOC_E_NONE; 4125 #endif 4126 } 4127 4128 #define IRQ3_STATUS_REG 3 4129 #define IRQ4_STATUS_REG 4 4130 STATIC int 4131 _soc_apache_ser_process_all (int unit, int top_irq, int bit_pos) 4132 { 4133 #if defined(BCM_56560_A0) 4134 switch (top_irq) { 4135 case IRQ3_STATUS_REG: 4136 SOC_IF_ERROR_RETURN(_soc_apache_ser_process_irq3(unit,bit_pos)); 4137 break; 4138 case IRQ4_STATUS_REG: 4139 SOC_IF_ERROR_RETURN(_soc_apache_ser_process_irq4(unit,bit_pos)); 4140 break; 4141 default: 4142 return SOC_E_INTERNAL; /* Shouldn't come here */ 4143 } 4144 4145 return SOC_E_NONE; 4146 #else 4147 return SOC_E_NONE; 4148 #endif 4149 } 4150 4151 void 4152 soc_apache_ser_set_long_delay(int delay) 4153 { 4154 #if defined(BCM_56560_A0) 4155 _apache_ser_delay = delay; 4156 return; 4157 #endif 4158 } 4159 4160 STATIC void 4161 soc_apache_ser_error (void *unit_vp, void *d1, 4162 void *d2, void *d3, void *d4) 4163 { 4164 #if defined(BCM_56560_A0) 4165 int unit = PTR_TO_INT(unit_vp); 4166 int irq_reg = PTR_TO_INT(d3); 4167 int old_mask = 0; 4168 4169 (void)_soc_apache_ser_process_all(unit,irq_reg,PTR_TO_INT(d4)); 4170 4171 sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : (_apache_ser_delay != 0 ? 10000000 : 100000)); 4172 4173 if (d2 != NULL) { 4174 old_mask = PTR_TO_INT(d2); 4175 if (irq_reg == 3) { 4176 (void)soc_cmicm_intr3_enable(unit, old_mask); 4177 } else if (irq_reg == 4) { 4178 (void)soc_cmicm_intr4_enable(unit, old_mask); 4179 } 4180 } 4181 /* soc_intr_enable(unit, IRQ_MEM_FAIL); */ 4182 #endif 4183 } 4184 4185 /* SER processing for TCAMs */ 4186 static _soc_generic_ser_info_t _soc_apache_tcam_ser_info_template[] = { 4187 /* HW SER engine protection */ 4188 { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, 4189 _SOC_SER_PARITY_4BITS, 4190 _SOC_SER_INTERLEAVE_MOD2, 4191 { {0, 97}, {1, 97}, {98, 193}, {99, 193} }, 0, 0, 0, 0, 4192 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA | 4193 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY}, 4194 { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY, 4195 _SOC_SER_PARITY_8BITS, 4196 _SOC_SER_INTERLEAVE_NONE, 4197 { {0, 99}, {100, 195}, {196, 291}, {292, 387} }, 0, 0, 0, 0, 4198 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA | 4199 _SOC_SER_FLAG_REMAP_READ | _SOC_SER_FLAG_SIZE_VERIFY}, 4200 { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4201 _SOC_SER_PARITY_4BITS, 4202 _SOC_SER_INTERLEAVE_MOD2, 4203 { {0, 165}, {1, 165}, {166, 353}, {167, 353} }, 0, 0, 0, 0, 4204 _SOC_SER_FLAG_XY_READ}, 4205 { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4206 _SOC_SER_PARITY_4BITS, 4207 _SOC_SER_INTERLEAVE_MOD2, 4208 { {0, 237}, {1, 237}, {238, 473}, {239, 473} }, 0, 0, 0, 0, 4209 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA}, 4210 { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4211 _SOC_SER_PARITY_4BITS, 4212 _SOC_SER_INTERLEAVE_MOD2, 4213 { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0, 4214 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA}, 4215 { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, 4216 _SOC_SER_PARITY_4BITS, 4217 _SOC_SER_INTERLEAVE_MOD2, 4218 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4219 _SOC_SER_FLAG_XY_READ}, 4220 { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, 4221 _SOC_SER_PARITY_4BITS, 4222 _SOC_SER_INTERLEAVE_MOD2, 4223 { {0, 145}, {2, 145}, {146, 289}, {148, 289} }, 0, 0, 0, 0, 4224 _SOC_SER_FLAG_XY_READ}, 4225 { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, 4226 _SOC_SER_PARITY_4BITS, 4227 _SOC_SER_INTERLEAVE_MOD2, 4228 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4229 _SOC_SER_FLAG_XY_READ}, 4230 { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, 4231 _SOC_SER_PARITY_4BITS, 4232 _SOC_SER_INTERLEAVE_MOD2, 4233 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4234 _SOC_SER_FLAG_XY_READ}, 4235 { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4236 _SOC_SER_PARITY_4BITS, 4237 _SOC_SER_INTERLEAVE_MOD2, 4238 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4239 _SOC_SER_FLAG_XY_READ}, 4240 { FP_UDF_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4241 _SOC_SER_PARITY_4BITS, 4242 _SOC_SER_INTERLEAVE_MOD2, 4243 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4244 _SOC_SER_FLAG_XY_READ}, 4245 { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, 4246 _SOC_SER_PARITY_4BITS, 4247 _SOC_SER_INTERLEAVE_MOD2, 4248 { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0, 4249 _SOC_SER_FLAG_XY_READ}, 4250 { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4251 _SOC_SER_PARITY_4BITS, 4252 _SOC_SER_INTERLEAVE_MOD2, 4253 { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0, 4254 _SOC_SER_FLAG_XY_READ}, 4255 { UDF_CONDITIONAL_CHECK_TABLE_CAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4256 _SOC_SER_PARITY_4BITS, 4257 _SOC_SER_INTERLEAVE_MOD2, 4258 { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0, 4259 _SOC_SER_FLAG_XY_READ}, 4260 { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY, 4261 _SOC_SER_PARITY_4BITS, 4262 _SOC_SER_INTERLEAVE_MOD2, 4263 { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0, 4264 _SOC_SER_FLAG_XY_READ}, 4265 { SUBPORT_TAG_SGPP_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, 4266 _SOC_SER_PARITY_4BITS, 4267 _SOC_SER_INTERLEAVE_MOD2, 4268 { {0, 32}, {1, 32}, {33, 64}, {34, 64} }, 0, 0, 0, 0, 4269 _SOC_SER_FLAG_XY_READ}, 4270 4271 /* Below memories have SW memscan SER engine protection */ 4272 { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, 4273 -1, -1, 4274 { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0, 4275 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE | 4276 _SOC_SER_FLAG_OVERLAY}, 4277 { FP_GM_FIELDSm, INVALIDm, _SOC_SER_TYPE_PARITY, 4278 -1, -1, 4279 { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0, 4280 _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE | 4281 _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE}, 4282 { INVALIDm }, 4283 }; 4284 4285 static _soc_generic_ser_info_t *_soc_apache_tcam_ser_info[SOC_MAX_NUM_DEVICES]; 4286 4287 STATIC void 4288 _soc_apache_ser_info_flag_update(_soc_generic_ser_info_t *ser_info, 4289 soc_mem_t mem, uint32 flag, int enable) 4290 { 4291 int ser_idx = 0; 4292 4293 while (INVALIDm != ser_info[ser_idx].mem) { 4294 if (ser_info[ser_idx].mem == mem) { 4295 if (enable) { 4296 ser_info[ser_idx].ser_flags |= flag; 4297 } else { 4298 ser_info[ser_idx].ser_flags &= ~flag; 4299 } 4300 break; 4301 } 4302 ser_idx++; 4303 } 4304 } 4305 4306 STATIC int 4307 _soc_apache_tcam_ser_init (int unit) 4308 { 4309 int alloc_size; 4310 4311 /* First, make per-unit copy of the master TCAM list */ 4312 alloc_size = sizeof(_soc_apache_tcam_ser_info_template); 4313 if (NULL == _soc_apache_tcam_ser_info[unit]) { 4314 if ((_soc_apache_tcam_ser_info[unit] = 4315 sal_alloc(alloc_size, "apache tcam list")) == NULL) { 4316 return SOC_E_MEMORY; 4317 } 4318 } 4319 4320 /* Make a fresh copy of the TCAM template info */ 4321 sal_memcpy(_soc_apache_tcam_ser_info[unit], 4322 &(_soc_apache_tcam_ser_info_template), 4323 alloc_size); 4324 4325 if (soc_feature(unit, soc_feature_field_half_slice_single_tcam) && 4326 soc_feature(unit, soc_feature_field_ingress_two_slice_types)) { 4327 _soc_apache_ser_info_flag_update(_soc_apache_tcam_ser_info[unit], FP_GLOBAL_MASK_TCAMm, 4328 _SOC_SER_FLAG_NO_DMA, TRUE); 4329 _soc_apache_ser_info_flag_update(_soc_apache_tcam_ser_info[unit], FP_TCAMm, 4330 _SOC_SER_FLAG_NO_DMA, TRUE); 4331 _soc_apache_ser_info_flag_update(_soc_apache_tcam_ser_info[unit], FP_GM_FIELDSm, 4332 _SOC_SER_FLAG_NO_DMA, TRUE); 4333 } 4334 4335 4336 return soc_generic_ser_init(unit, _soc_apache_tcam_ser_info[unit]); 4337 } 4338 4339 STATIC void 4340 soc_apache_ser_fail (int unit) 4341 { 4342 soc_generic_ser_process_error(unit, _soc_apache_tcam_ser_info[unit], 4343 _SOC_PARITY_TYPE_SER); 4344 } 4345 4346 int 4347 soc_apache_mem_config(int unit) 4348 { 4349 soc_persist_t *sop; 4350 int l2_entries, cfg_l2_entries, shared_l2_banks; 4351 int l3_entries, cfg_l3_entries, shared_l3_banks; 4352 int shared_bank_size = 64; 4353 int min_l2_entries; 4354 int min_l3_entries; 4355 int max_l2_entries; 4356 int max_l3_entries; 4357 int alpm_enable; 4358 int num_ecmp_rh_flowset_entries; 4359 int num_ipv6_128b_entries = 0; 4360 int config_v6_entries = 0; 4361 int defip_config = 0; 4362 int uft_size = 256; 4363 int def_ipv6_128b_num = 2048; 4364 int def_lpm_scaling = 0; 4365 int def_lpm_ipv6_128b_reserved = 1; 4366 uint16 dev_id; 4367 uint8 rev_id; 4368 4369 sop = SOC_PERSIST(unit); 4370 soc_cm_get_id(unit, &dev_id, &rev_id); 4371 4372 if (soc_feature(unit, soc_feature_untethered_otp)) { 4373 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureUft128k)) { 4374 shared_bank_size = 32; 4375 } 4376 } 4377 4378 uft_size = shared_bank_size * 4; 4379 min_l2_entries = 16; /* 16K dedicated L2 entries */ 4380 min_l3_entries = 4; /* 4K dedicated L3 entries */ 4381 max_l2_entries = min_l2_entries + uft_size; /* Dedicated (16K) + Shared (256K/128K)*/ 4382 max_l3_entries = min_l3_entries + uft_size; /* Dedicated (16K) + Shared (256K/128K)*/; /* Dedicated (4K) + Shared (256K)*/ 4383 4384 4385 if (SAL_BOOT_SIMULATION) { 4386 /* 4387 * Smaller table lengths for BCMSIM environment. 4388 */ 4389 max_l2_entries = min_l2_entries; 4390 max_l3_entries = min_l3_entries; 4391 } 4392 4393 cfg_l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, -1); 4394 l2_entries = cfg_l2_entries == -1 ? max_l2_entries * 1024 : cfg_l2_entries; 4395 4396 if (l2_entries <= min_l2_entries * 1024) { /* Min table size */ 4397 l2_entries = min_l2_entries * 1024; 4398 shared_l2_banks = 0; 4399 } else if (l2_entries <= max_l2_entries * 1024) { 4400 l2_entries -= min_l2_entries * 1024; 4401 shared_l2_banks = (l2_entries + (shared_bank_size * 1024 - 1)) / (shared_bank_size * 1024); 4402 l2_entries = min_l2_entries * 1024 + shared_l2_banks * shared_bank_size * 1024; 4403 } else { 4404 LOG_CLI((BSL_META_U(unit, 4405 "The specified l2_mem_entries (%d) exceeds 272K\n"), 4406 cfg_l2_entries)); 4407 return SOC_E_PARAM; 4408 } 4409 4410 cfg_l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, -1); 4411 l3_entries = cfg_l3_entries == -1 ? (min_l3_entries * 1024 ) : cfg_l3_entries; 4412 if (l3_entries <= min_l3_entries * 1024) { /* 4k dedicated L3 entries */ 4413 l3_entries = min_l3_entries * 1024; 4414 shared_l3_banks = 0; 4415 } else if (l3_entries <= max_l3_entries * 1024) { 4416 l3_entries -= min_l3_entries * 1024; 4417 shared_l3_banks = (l3_entries + (shared_bank_size * 1024 - 1)) / (shared_bank_size * 1024); 4418 l3_entries = min_l3_entries * 1024 + shared_l3_banks * shared_bank_size * 1024; 4419 } else { 4420 LOG_CLI((BSL_META_U(unit, 4421 "The specified l3_mem_entries (%d) exceeds 260K\n"), 4422 cfg_l3_entries)); 4423 return SOC_E_PARAM; 4424 } 4425 4426 alpm_enable = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0); 4427 4428 if (alpm_enable && soc_feature(unit, soc_feature_alpm)) { 4429 4430 if (shared_l2_banks + shared_l3_banks > 2) { 4431 LOG_CLI((BSL_META_U(unit, 4432 "A minimum of 2 shared banks is required for ALPM " 4433 "when it is enabled\n"))); 4434 return SOC_E_PARAM; 4435 } 4436 } else if (shared_l2_banks + shared_l3_banks > 4) { 4437 if (cfg_l2_entries == -1) { 4438 LOG_CLI((BSL_META_U(unit, 4439 "Default L2 size (294912) and the specified " 4440 "l3_mem_entries (%d) require more than 4 shared " 4441 "banks\n"), 4442 cfg_l3_entries)); 4443 } else { 4444 LOG_CLI((BSL_META_U(unit, 4445 "The specified l2_mem_entries (%d) and " 4446 "l3_mem_entries (%d) require more than 4 shared " 4447 "banks\n"), 4448 cfg_l2_entries, cfg_l3_entries)); 4449 } 4450 return SOC_E_PARAM; 4451 } 4452 _soc_alpm_mode[unit] = alpm_enable; 4453 4454 /* Adjust L2 table size */ 4455 sop->memState[L2Xm].index_max = l2_entries - 1; 4456 sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1; 4457 sop->memState[L2_ENTRY_ONLY_ECCm].index_max = l2_entries - 1; 4458 sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1; 4459 sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1; 4460 sop->memState[L2_ENTRY_LPm].index_max = min_l2_entries*1024 / 4 - 1; 4461 sop->memState[L2_ENTRY_ISS_LPm].index_max = 4462 (l2_entries - min_l2_entries*1024) / 4 - 1; 4463 4464 /* Adjust L3 table size */ 4465 sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1; 4466 sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1; 4467 sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = l3_entries / 2 - 1; 4468 sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = l3_entries/ 2 - 1; 4469 sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = l3_entries / 4 - 1; 4470 sop->memState[L3_ENTRY_ONLY_ECCm].index_max = l3_entries - 1; 4471 sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1; 4472 sop->memState[L3_ENTRY_LPm].index_max = min_l3_entries*1024 / 4 - 1; 4473 sop->memState[L3_ENTRY_ISS_LPm].index_max = 4474 (l3_entries - min_l3_entries*1024) / 4 - 1; 4475 4476 /* Adjust ALPM table size */ 4477 if (alpm_enable) { 4478 /* The check below is sufficient because if ALPM mode is enabled 4479 * and number of shared banks used is > 2 we return SOC_E_PARAM 4480 * in code at the top of this function. 4481 */ 4482 if (shared_l2_banks + shared_l3_banks > 0) { 4483 sop->memState[L3_DEFIP_ALPM_RAWm].index_max = 4484 sop->memState[L3_DEFIP_ALPM_RAWm].index_max/2; 4485 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = 4486 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max/2; 4487 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = 4488 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max/2; 4489 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = 4490 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max/2; 4491 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = 4492 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max/2; 4493 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = 4494 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max/2; 4495 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = 4496 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max/2; 4497 sop->memState[L3_DEFIP_ALPM_ECCm].index_max = 4498 sop->memState[L3_DEFIP_ALPM_ECCm].index_max/2; 4499 } 4500 } else { 4501 sop->memState[L3_DEFIP_ALPM_RAWm].index_max = -1; 4502 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = -1; 4503 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = -1; 4504 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = -1; 4505 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = -1; 4506 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = -1; 4507 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = -1; 4508 sop->memState[L3_DEFIP_ALPM_ECCm].index_max = -1; 4509 } 4510 4511 /* LAG and ECMP resilient hashing features share the same flow set table. 4512 * The table can be configured in one of 3 modes: 4513 * - dedicated to LAG resilient hashing, 4514 * - dedicated to ECMP resilient hashing, 4515 * - split evenly between LAG and ECMP resilient hashing. 4516 */ 4517 num_ecmp_rh_flowset_entries = soc_property_get(unit, 4518 spn_ECMP_RESILIENT_HASH_SIZE, 32768); 4519 switch (num_ecmp_rh_flowset_entries) { 4520 case 0: 4521 sop->memState[RH_ECMP_FLOWSETm].index_max = -1; 4522 break; 4523 case 32768: 4524 sop->memState[RH_LAG_FLOWSETm].index_max /= 2; 4525 sop->memState[RH_ECMP_FLOWSETm].index_max /= 2; 4526 break; 4527 case 65536: 4528 sop->memState[RH_LAG_FLOWSETm].index_max = -1; 4529 break; 4530 default: 4531 return SOC_E_CONFIG; 4532 } 4533 4534 if (!soc_feature(unit, soc_feature_lpm_tcam)) { 4535 SOC_CONTROL(unit)->l3_defip_max_tcams = 0; 4536 } else if (soc_feature(unit, soc_feature_l3_2k_defip_table)) { 4537 SOC_CONTROL(unit)->l3_defip_max_tcams = 2; 4538 } else if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf)) { 4539 SOC_CONTROL(unit)->l3_defip_max_tcams = 2; 4540 def_ipv6_128b_num = 1024; 4541 def_lpm_scaling = 1; 4542 def_lpm_ipv6_128b_reserved = 0; 4543 } else { 4544 SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_APACHE_DEFIP_MAX_TCAMS; 4545 } 4546 SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_APACHE_DEFIP_TCAM_DEPTH; 4547 4548 if (!soc_feature(unit, soc_feature_lpm_tcam)) { 4549 /* LPM is disabled, disable all L3_DEFIP memories */ 4550 sop->memState[L3_DEFIPm].index_max = -1; 4551 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1; 4552 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1; 4553 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1; 4554 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1; 4555 sop->memState[L3_DEFIP_ONLYm].index_max = -1; 4556 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = -1; 4557 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = -1; 4558 SOC_CONTROL(unit)->l3_defip_index_remap = 0; 4559 } else if (soc_property_get(unit, "l3_defip_sizing", TRUE)) { 4560 if (!soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) { 4561 defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1); 4562 4563 num_ipv6_128b_entries = soc_property_get(unit, 4564 spn_NUM_IPV6_LPM_128B_ENTRIES, 4565 (defip_config ? def_ipv6_128b_num : 0)); 4566 4567 /* 4568 * Config property num_ipv6_lpm_128b_entries is not valid 4569 * on Ranger2+ 4570 */ 4571 if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf) && 4572 soc_property_get(unit, spn_NUM_IPV6_LPM_128B_ENTRIES, 0)) { 4573 return SOC_E_CONFIG; 4574 } 4575 4576 num_ipv6_128b_entries = num_ipv6_128b_entries + 4577 (num_ipv6_128b_entries % 2); 4578 4579 config_v6_entries = num_ipv6_128b_entries; 4580 if (soc_property_get(unit, spn_LPM_SCALING_ENABLE, 4581 def_lpm_scaling)) { 4582 4583 num_ipv6_128b_entries = 0; 4584 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED, 4585 def_lpm_ipv6_128b_reserved)) { 4586 4587 config_v6_entries = ((config_v6_entries / 4588 SOC_CONTROL(unit)->l3_defip_tcam_size) + 4589 ((config_v6_entries % 4590 SOC_CONTROL(unit)->l3_defip_tcam_size) 4591 ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size; 4592 } else { 4593 /* 4594 * Config property lpm_ipv6_128b_reserved is not valid 4595 * on Ranger2+ 4596 */ 4597 if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf)) { 4598 return SOC_E_CONFIG; 4599 } 4600 } 4601 } 4602 sop->memState[L3_DEFIP_PAIR_128m].index_max = 4603 num_ipv6_128b_entries - 1; 4604 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 4605 num_ipv6_128b_entries - 1; 4606 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 4607 num_ipv6_128b_entries - 1; 4608 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 4609 num_ipv6_128b_entries - 1; 4610 sop->memState[L3_DEFIPm].index_max = 4611 (SOC_CONTROL(unit)->l3_defip_max_tcams * 4612 SOC_CONTROL(unit)->l3_defip_tcam_size) - 4613 (num_ipv6_128b_entries * 2) - 1; 4614 4615 sop->memState[L3_DEFIP_ONLYm].index_max = 4616 sop->memState[L3_DEFIPm].index_max; 4617 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 4618 sop->memState[L3_DEFIPm].index_max; 4619 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 4620 sop->memState[L3_DEFIPm].index_max; 4621 SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries; 4622 } else { 4623 if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) { 4624 /* slightly different processing for v6-128 */ 4625 num_ipv6_128b_entries = soc_property_get(unit, 4626 spn_NUM_IPV6_LPM_128B_ENTRIES, 4627 def_ipv6_128b_num); 4628 /* 4629 * Config property num_ipv6_lpm_128b_entries is not valid 4630 * on Ranger2+ 4631 */ 4632 if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf) && 4633 soc_property_get(unit, spn_NUM_IPV6_LPM_128B_ENTRIES, 0)) { 4634 return SOC_E_CONFIG; 4635 } 4636 4637 num_ipv6_128b_entries = num_ipv6_128b_entries + 4638 (num_ipv6_128b_entries % 2); 4639 4640 if (soc_feature(unit, soc_feature_alpm)) { 4641 if ((alpm_enable == 1) || (alpm_enable == 3)) { 4642 num_ipv6_128b_entries = (num_ipv6_128b_entries + 3) / 4 * 4; 4643 } 4644 } 4645 4646 config_v6_entries = num_ipv6_128b_entries; 4647 sop->memState[L3_DEFIP_PAIR_128m].index_max = 4648 num_ipv6_128b_entries - 1; 4649 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 4650 num_ipv6_128b_entries - 1; 4651 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 4652 num_ipv6_128b_entries - 1; 4653 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 4654 num_ipv6_128b_entries - 1; 4655 sop->memState[L3_DEFIPm].index_max = 4656 (SOC_CONTROL(unit)->l3_defip_max_tcams * 4657 SOC_CONTROL(unit)->l3_defip_tcam_size) - 4658 (num_ipv6_128b_entries * 2) - 1; 4659 4660 sop->memState[L3_DEFIP_ONLYm].index_max = 4661 sop->memState[L3_DEFIPm].index_max; 4662 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 4663 sop->memState[L3_DEFIPm].index_max; 4664 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 4665 sop->memState[L3_DEFIPm].index_max; 4666 4667 SOC_CONTROL(unit)->l3_defip_index_remap = 4668 (num_ipv6_128b_entries / 2) * 2; 4669 } else { 4670 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1; 4671 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1; 4672 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1; 4673 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1; 4674 } 4675 } 4676 soc_l3_defip_indexes_init(unit, config_v6_entries); 4677 } 4678 4679 if (_soc_apache_alpm_bkt_view_map[unit] != NULL) { 4680 sal_free(_soc_apache_alpm_bkt_view_map[unit]); 4681 _soc_apache_alpm_bkt_view_map[unit] = NULL; 4682 } 4683 4684 if (NULL == _soc_apache_alpm_bkt_view_map[unit]) { 4685 if ((_soc_apache_alpm_bkt_view_map[unit] = 4686 sal_alloc(sizeof(soc_mem_t) * SOC_APACHE_ALPM_MAX_BKTS, 4687 "alpm_bkt_map")) == NULL) { 4688 return SOC_E_MEMORY; 4689 } 4690 } 4691 4692 memset(_soc_apache_alpm_bkt_view_map[unit], INVALIDm, 4693 sizeof(soc_mem_t) * SOC_APACHE_ALPM_MAX_BKTS); 4694 4695 if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) { 4696 if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) { 4697 /* IFP */ 4698 sop->memState[FP_RANGE_CHECKm].index_max = -1; 4699 sop->memState[FP_GLOBAL_MASK_TCAMm].index_max = -1; 4700 sop->memState[FP_GM_FIELDSm].index_max = -1; 4701 sop->memState[FP_TCAMm].index_max = -1; 4702 sop->memState[FP_SLICE_MAPm].index_max = -1; 4703 sop->memState[FP_POLICY_TABLEm].index_max = -1; 4704 sop->memState[FP_METER_TABLEm].index_max = -1; 4705 sop->memState[FP_COUNTER_TABLEm].index_max = -1; 4706 sop->memState[FP_STORM_CONTROL_METERSm].index_max = -1; 4707 sop->memState[FP_SLICE_KEY_CONTROLm].index_max = -1; 4708 sop->memState[FP_PORT_METER_MAPm].index_max = -1; 4709 sop->memState[FP_I2E_CLASSID_SELECTm].index_max = -1; 4710 sop->memState[FP_HG_CLASSID_SELECTm].index_max = -1; 4711 4712 sop->memState[SVM_MACROFLOW_INDEX_TABLEm].index_max = -1; 4713 sop->memState[SVM_METER_TABLEm].index_max = -1; 4714 sop->memState[SVM_OFFSET_TABLEm].index_max = -1; 4715 sop->memState[SVM_POLICY_TABLEm].index_max = -1; 4716 sop->memState[SVM_DBG_01m].index_max = -1; 4717 sop->memState[SVM_DBG_02m].index_max = -1; 4718 sop->memState[SVM_DBG_03m].index_max = -1; 4719 4720 /* EFP */ 4721 sop->memState[EFP_TCAMm].index_max = -1; 4722 sop->memState[EFP_POLICY_TABLEm].index_max = -1; 4723 sop->memState[EFP_METER_TABLEm].index_max = -1; 4724 sop->memState[EGR_PW_INIT_COUNTERSm].index_max = -1; 4725 4726 sop->memState[EGR_TRILL_PARSE_CONTROL_2m].index_max = -1; 4727 sop->memState[EGR_1588_SAm].index_max = -1; 4728 sop->memState[EGR_FC_HEADER_TYPEm].index_max = -1; 4729 sop->memState[EGR_PORT_1m].index_max = -1; 4730 } 4731 4732 /* IVXLT */ 4733 sop->memState[VLAN_PROTOCOLm].index_max = -1; 4734 sop->memState[VLAN_PROTOCOL_DATAm].index_max = -1; 4735 sop->memState[VLAN_SUBNETm].index_max = -1; 4736 sop->memState[VLAN_SUBNET_ONLYm].index_max = -1; 4737 sop->memState[VLAN_SUBNET_DATA_ONLYm].index_max = -1; 4738 sop->memState[VLAN_MACm].index_max = -1; 4739 sop->memState[VLAN_XLATEm].index_max = -1; 4740 sop->memState[VFP_TCAMm].index_max = -1; 4741 sop->memState[VFP_POLICY_TABLEm].index_max = -1; 4742 sop->memState[ING_VLAN_TAG_ACTION_PROFILEm].index_max = -1; 4743 sop->memState[MPLS_ENTRYm].index_max = -1; 4744 sop->memState[UDF_CONDITIONAL_CHECK_TABLE_CAMm].index_max = -1; 4745 sop->memState[UDF_CONDITIONAL_CHECK_TABLE_RAMm].index_max = -1; 4746 sop->memState[ING_ETAG_PCP_MAPPINGm].index_max = -1; 4747 sop->memState[VLAN_XLATE_ECCm].index_max = -1; 4748 sop->memState[MPLS_ENTROPY_LABEL_DATAm].index_max = -1; 4749 sop->memState[VLAN_XLATE_LPm].index_max = -1; 4750 4751 } 4752 4753 return SOC_E_NONE; 4754 } 4755 4756 int soc_apache_get_alpm_banks(int unit) 4757 { 4758 int rv = SOC_E_NONE; 4759 soc_reg_t reg = ISS_LOG_TO_PHY_BANK_MAP_2r; 4760 uint32 bank_mode = 0; 4761 uint32 map = 0; 4762 4763 if (_soc_ap_num_shared_alpm_banks[unit] == 0) { 4764 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &map); 4765 if (rv >= 0) { 4766 bank_mode = soc_reg_field_get(unit, reg, map, ALPM_BANK_MODEf); 4767 } 4768 4769 if (bank_mode == 1) { 4770 _soc_ap_num_shared_alpm_banks[unit] = 2; 4771 } else { 4772 _soc_ap_num_shared_alpm_banks[unit] = 4; 4773 } 4774 } 4775 4776 return _soc_ap_num_shared_alpm_banks[unit]; 4777 } 4778 4779 int 4780 soc_apache_alpm_mode_get(int unit) 4781 { 4782 return _soc_alpm_mode[unit]; 4783 } 4784 4785 #define _APACHE_INDEX_1K_ENTRIES 1024 4786 #define _APACHE_INDEX_2K_ENTRIES 2048 4787 #define _APACHE_INDEX_3K_ENTRIES 3072 4788 #define _APACHE_INDEX_4K_ENTRIES 4096 4789 #define _APACHE_INDEX_6K_ENTRIES 6144 4790 4791 /* Map logical (always starts from 0 and contiguous) index to physical index 4792 which can have a starting offset and/or holes. 4793 Input : logical index 4794 Returns: physical index */ 4795 int 4796 soc_apache_l3_defip_index_map (int unit, soc_mem_t mem, int index) 4797 { 4798 int wide = 0; 4799 int alpm_mode = _soc_alpm_mode[unit]; 4800 int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf; 4801 int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap; 4802 4803 /* don't remap for ALPM */ 4804 if (defip128_tbl_sz == 0) { 4805 return index; 4806 } 4807 4808 if (mem == L3_DEFIP_PAIR_128m || 4809 mem == L3_DEFIP_PAIR_128_ONLYm || 4810 mem == L3_DEFIP_PAIR_128_DATA_ONLYm || 4811 mem == L3_DEFIP_PAIR_128_HIT_ONLYm) { 4812 wide = 1; 4813 } 4814 4815 if (alpm_mode == 2) { 4816 if (is_urpf_mode) { 4817 if (wide == 0) { 4818 if (index >= _APACHE_INDEX_2K_ENTRIES) { 4819 return index + (defip128_tbl_sz * 2); 4820 } 4821 return index + defip128_tbl_sz; 4822 } else { 4823 if (index >= _APACHE_INDEX_1K_ENTRIES) { 4824 return index + defip128_tbl_sz / 2; 4825 } 4826 return index; 4827 } 4828 } 4829 4830 /* not uRPF */ 4831 return (wide) ? index : index + (defip128_tbl_sz * 2); 4832 } 4833 if (alpm_mode == 1) { 4834 uint32 incr = soc_mem_index_count(unit, mem)/4; 4835 uint32 entries_per_tcam = _APACHE_INDEX_1K_ENTRIES; 4836 uint32 tcam_num, tcam_idx; 4837 uint32 cnt_128; 4838 uint32 tmp; 4839 4840 if (is_urpf_mode) { 4841 if (wide) { 4842 /* Coverity issue ignored: 4843 * Since mem index count cannot be 0 4844 * hence, the scenario does not arise */ 4845 /* coverity[divide_by_zero : FALSE] */ 4846 tcam_num = index/incr; 4847 tcam_idx = index % incr; 4848 return tcam_num * entries_per_tcam + tcam_idx; 4849 } 4850 incr = incr/2; 4851 /* coverity[divide_by_zero : FALSE] */ 4852 tcam_num = index/incr; 4853 tcam_idx = index % incr; 4854 return tcam_num * entries_per_tcam + tcam_idx + 4855 defip128_tbl_sz/4; 4856 } 4857 if (wide > 0) { 4858 if (index < (soc_mem_index_count(unit, mem) / 2)) { 4859 return index; 4860 } 4861 /* make index relative to upper half */ 4862 index -= (soc_mem_index_count(unit, mem) / 2); 4863 return index + _APACHE_INDEX_2K_ENTRIES; 4864 } 4865 4866 cnt_128 = defip128_tbl_sz; 4867 4868 if (cnt_128/2 <= _APACHE_INDEX_1K_ENTRIES) { 4869 if ((cnt_128/2 + index) < _APACHE_INDEX_1K_ENTRIES) { 4870 return index + cnt_128/2; 4871 } else if ((cnt_128 + index) < _APACHE_INDEX_4K_ENTRIES) { 4872 return index + cnt_128; 4873 } else if ((cnt_128 + index + cnt_128/2) < 4874 (_APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_1K_ENTRIES)) { 4875 return index + cnt_128 + cnt_128/2; 4876 } else { 4877 return index + 2 * cnt_128; 4878 } 4879 } else if (cnt_128/2 <= _APACHE_INDEX_2K_ENTRIES) { 4880 tmp = cnt_128 - _APACHE_INDEX_2K_ENTRIES; 4881 if ((tmp/2 + index + _APACHE_INDEX_2K_ENTRIES) < _APACHE_INDEX_3K_ENTRIES) { 4882 return index + _APACHE_INDEX_2K_ENTRIES + tmp/2; 4883 } else if ((cnt_128 + index) < _APACHE_INDEX_4K_ENTRIES) { 4884 return index + cnt_128; 4885 } else if ((cnt_128 + tmp/2 + index + _APACHE_INDEX_2K_ENTRIES) < 4886 (_APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_3K_ENTRIES)) { 4887 return index + cnt_128 + tmp/2 + _APACHE_INDEX_2K_ENTRIES; 4888 } else { 4889 return index + cnt_128 * 2; 4890 } 4891 } 4892 4893 if (index < soc_mem_index_count(unit, mem)/2) { 4894 return index + defip128_tbl_sz; 4895 } else { 4896 /* make index relative to upper half */ 4897 index -= (soc_mem_index_count(unit, mem)/2); 4898 return index + 2 * _APACHE_INDEX_2K_ENTRIES + 4899 defip128_tbl_sz; 4900 } 4901 } 4902 4903 if (is_urpf_mode) { /* URPF mode */ 4904 return soc_l3_defip_urpf_index_map(unit, wide, index); 4905 } 4906 4907 return soc_l3_defip_index_map(unit, wide, index); 4908 } 4909 4910 /* Reverse map physical index to logical index. 4911 Input : physical index 4912 Returns: logical index */ 4913 int 4914 soc_apache_l3_defip_index_remap(int unit, soc_mem_t mem, int index) 4915 { 4916 int wide = 0; 4917 int alpm_mode = _soc_alpm_mode[unit]; 4918 int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf; 4919 int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap; 4920 4921 /* don't remap for ALPM */ 4922 if (defip128_tbl_sz == 0) { 4923 return index; 4924 } 4925 4926 if (mem == L3_DEFIP_PAIR_128m || 4927 mem == L3_DEFIP_PAIR_128_ONLYm || 4928 mem == L3_DEFIP_PAIR_128_DATA_ONLYm || 4929 mem == L3_DEFIP_PAIR_128_HIT_ONLYm) { 4930 wide = 1; 4931 } 4932 4933 if (alpm_mode == 2) { 4934 if (is_urpf_mode) { /* URPF mode */ 4935 if (wide == 0) { 4936 if (index >= _APACHE_INDEX_6K_ENTRIES) { 4937 return index - (defip128_tbl_sz * 2); 4938 } 4939 return index - defip128_tbl_sz; 4940 } else { 4941 if (index >= _APACHE_INDEX_1K_ENTRIES) { 4942 return index - defip128_tbl_sz / 2; 4943 } 4944 return index; 4945 } 4946 } 4947 return (wide) ? index : index - (defip128_tbl_sz * 2); 4948 } 4949 if (alpm_mode == 1) { 4950 int cnt_128; 4951 4952 if (is_urpf_mode) { 4953 uint32 num_chunks, chunk_offset; 4954 if (wide) { 4955 num_chunks = index / _APACHE_INDEX_1K_ENTRIES; 4956 chunk_offset = index % _APACHE_INDEX_1K_ENTRIES; 4957 return num_chunks * soc_mem_index_count(unit, mem)/4 4958 + chunk_offset; 4959 } 4960 num_chunks = index / _APACHE_INDEX_1K_ENTRIES; 4961 chunk_offset = index % _APACHE_INDEX_1K_ENTRIES; 4962 chunk_offset -= (defip128_tbl_sz/4); 4963 return num_chunks*soc_mem_index_count(unit, mem)/8 + chunk_offset; 4964 4965 } 4966 4967 cnt_128 = defip128_tbl_sz; 4968 4969 if (wide) { 4970 if (index < cnt_128/2) { 4971 return index; 4972 } else if ((index >= _APACHE_INDEX_2K_ENTRIES) && 4973 (index < _APACHE_INDEX_2K_ENTRIES + cnt_128/2)){ 4974 return index - _APACHE_INDEX_2K_ENTRIES + cnt_128/2; 4975 } else { 4976 return -1; 4977 } 4978 } 4979 4980 if (cnt_128/2 <= _APACHE_INDEX_1K_ENTRIES) { 4981 if ((index < _APACHE_INDEX_1K_ENTRIES) && 4982 (index >= cnt_128/2)) { 4983 return index - cnt_128/2; 4984 } else if ((index >= _APACHE_INDEX_1K_ENTRIES + cnt_128/2) && 4985 (index < _APACHE_INDEX_4K_ENTRIES)) { 4986 return index - cnt_128; 4987 } else if ((index < _APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_1K_ENTRIES) && 4988 (index >= _APACHE_INDEX_4K_ENTRIES + cnt_128/2)) { 4989 return index - cnt_128 - cnt_128/2; 4990 } else { 4991 return index - cnt_128 * 2; 4992 } 4993 } else if (cnt_128/2 <= _APACHE_INDEX_2K_ENTRIES) { 4994 if (index < _APACHE_INDEX_3K_ENTRIES) { 4995 return index - _APACHE_INDEX_2K_ENTRIES - \ 4996 (cnt_128 - _APACHE_INDEX_2K_ENTRIES)/2; 4997 } else if (index < _APACHE_INDEX_4K_ENTRIES) { 4998 return index - cnt_128; 4999 } else if (index < _APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_3K_ENTRIES) { 5000 return index - cnt_128 - _APACHE_INDEX_2K_ENTRIES - \ 5001 (cnt_128 - _APACHE_INDEX_2K_ENTRIES)/2; 5002 } else { 5003 return index - cnt_128 * 2; 5004 } 5005 } 5006 } 5007 if (is_urpf_mode) { /* URPF mode */ 5008 return soc_l3_defip_urpf_index_remap(unit, wide, index); 5009 } 5010 5011 return soc_l3_defip_index_remap(unit, wide, index); 5012 } 5013 5014 /* Given a physical index (always in terms of the narrow entry) 5015 return the logical index and memory type */ 5016 int 5017 soc_apache_l3_defip_mem_index_get(int unit, int pindex, soc_mem_t *mem) 5018 { 5019 return soc_l3_defip_index_mem_map(unit, pindex, mem); 5020 } 5021 5022 void 5023 _soc_apache_alpm_bkt_view_set(int unit, int index, soc_mem_t view) 5024 { 5025 int bkt = soc_apache_get_alpm_banks(unit) + 1; 5026 bkt = (index >> (bkt / 2)) & SOC_APACHE_ALPM_BKT_MASK; 5027 5028 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt set index:%d bkt:%d view:%s\n"), 5029 unit, index, bkt, SOC_MEM_NAME(unit, view))); 5030 _soc_apache_alpm_bkt_view_map[unit][bkt] = view; 5031 } 5032 5033 soc_mem_t 5034 _soc_apache_alpm_bkt_view_get(int unit, int index) 5035 { 5036 soc_mem_t view; 5037 int bkt = soc_apache_get_alpm_banks(unit) + 1; 5038 bkt = (index >> (bkt / 2)) & SOC_APACHE_ALPM_BKT_MASK; 5039 5040 view = _soc_apache_alpm_bkt_view_map[unit][bkt]; 5041 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt get index:%d bkt:%d view:%s\n"), 5042 unit, index, bkt, SOC_MEM_NAME(unit, view))); 5043 return view; 5044 } 5045 5046 int 5047 _soc_apache_mem_cpu_write_control(int unit, soc_mem_t mem, int copyno, 5048 int enable, int *orig_enable) 5049 { 5050 soc_reg_t reg; 5051 soc_field_t field; 5052 int blk, port; 5053 soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, SOC_BLOCK_TYPE_INVALID}; 5054 uint32 rval, fval, orig_fval, enable_fval, disable_fval; 5055 5056 enable_fval = 1; 5057 disable_fval = 0; 5058 5059 switch (mem) { 5060 case XLPORT_WC_UCMEM_DATAm: 5061 reg = XLPORT_WC_UCMEM_CTRLr; 5062 field = ACCESS_MODEf; 5063 SOC_BLOCKS_ITER(unit, blk, xlport_blocks) { 5064 port = SOC_BLOCK_PORT(unit, blk); 5065 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 5066 /* It will use the setting from the last block */ 5067 *orig_enable = soc_reg_field_get(unit, reg, rval, field); 5068 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0); 5069 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 5070 } 5071 return SOC_E_NONE; 5072 case L3_DEFIP_ALPM_RAWm: 5073 case L3_DEFIP_ALPM_IPV4m: 5074 case L3_DEFIP_ALPM_IPV4_1m: 5075 case L3_DEFIP_ALPM_IPV6_64m: 5076 case L3_DEFIP_ALPM_IPV6_64_1m: 5077 case L3_DEFIP_ALPM_IPV6_128m: 5078 reg = ISS_MEMORY_CONTROL_84r; 5079 field = BYPASS_ISS_MEMORY_LPf; 5080 enable_fval = 0xf; 5081 break; 5082 case MMU_INTFI_PFC_ST_TBLm: 5083 reg = INTFI_CFGr; 5084 field = PFC_ST_TBL_DISABLEf; 5085 break; 5086 case LINK_STATUSm: 5087 reg = SW2_HW_CONTROLr; 5088 field = LINK_STATUS_UPDATE_ENABLEf; 5089 break; 5090 case MMU_INTFO_QCN_CNM_TIMER_TBLm: 5091 case MMU_INTFI_XPIPE_FC_MAP_TBL2m: 5092 case MMU_MTRI_BKPMETERINGBUCKET_MEM_0m: 5093 case MMU_MTRO_BUCKET_L0_MEM_0m: 5094 case MMU_MTRO_BUCKET_L1_MEM_0m: 5095 case MMU_MTRO_BUCKET_L1_MEM_1m: 5096 case MMU_MTRO_BUCKET_L2_MEM_0m: 5097 case MMU_MTRO_BUCKET_L2_MEM_1m: 5098 case MMU_MTRO_BUCKET_L2_MEM_2m: 5099 case MMU_MTRO_BUCKET_L2_MEM_3m: 5100 case MMU_MTRO_BUCKET_L2_MEM_4m: 5101 case MMU_MTRO_BUCKET_L2_MEM_5m: 5102 case MMU_MTRO_BUCKET_L2_MEM_6m: 5103 case MMU_MTRO_BUCKET_L2_MEM_7m: 5104 case MMU_WRED_AVG_QSIZE_X_PIPEm: 5105 case MMU_WRED_CONFIG_X_PIPEm: 5106 case MMU_WRED_PORT_SP_DROP_THD_X_PIPEm: 5107 case MMU_WRED_QGROUP_DROP_THD_X_PIPEm: 5108 case MMU_WRED_UC_QUEUE_DROP_THD_DEQ_X_PIPE_0m: 5109 case MMU_WRED_UC_QUEUE_DROP_THD_ENQ_X_PIPE_0m: 5110 reg = MISCCONFIGr; 5111 field = REFRESH_ENf; 5112 enable_fval = 0; 5113 disable_fval = 1; 5114 break; 5115 default: 5116 return SOC_E_NONE; 5117 } 5118 5119 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 5120 orig_fval = soc_reg_field_get(unit, reg, rval, field); 5121 fval = enable ? enable_fval : disable_fval; 5122 5123 *orig_enable = orig_fval == enable_fval; 5124 if (fval != orig_fval) { 5125 soc_reg_field_set(unit, reg, &rval, field, fval); 5126 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 5127 } 5128 5129 return SOC_E_NONE; 5130 } 5131 5132 5133 /* 5134 * cpu port (mmu port 72): 48 queues (17114 -17161) 5135 * loopback port (mmu port 73): 8 queues (17104- 17111) 5136 */ 5137 #define _APACHE_CPU_QUEUE_BASE 17114 5138 #define _APACHE_LB_QUEUE_BASE 17104 5139 #define _APACHE_QCN_QUEUE_BASE 17112 5140 #define _APACHE_HSP_PORTS 16 5141 #define _APACHE_UC_QUEUE_BASE 0 5142 #define _APACHE_MC_QUEUE_BASE 16384 5143 #define _APACHE_NUMBER_OF_UC_QUEUE 16384 5144 #define _APACHE_NUMBER_OF_MC_QUEUE 720 5145 #define IS_AP_HSP_PORT(u,p) \ 5146 ((_soc_apache_port_sched_type_get((u),(p)) == SOC_APACHE_SCHED_HSP) ? 1 : 0) 5147 5148 int 5149 soc_apache_num_cosq_init(int unit) 5150 { 5151 soc_info_t *si; 5152 int mmu_port, port, phy_port; 5153 int lls_uc_cosq_base; 5154 int count; 5155 si = &SOC_INFO(unit); 5156 5157 if (soc_feature(unit, soc_feature_cmic_reserved_queues)) { 5158 si->port_num_cosq[CMIC_PORT(unit)] = 44; 5159 } else { 5160 si->port_num_cosq[CMIC_PORT(unit)] = 48; 5161 } 5162 5163 si->port_cosq_base[CMIC_PORT(unit)] = _APACHE_CPU_QUEUE_BASE - _APACHE_MC_QUEUE_BASE; 5164 si->port_num_cosq[LB_PORT(unit)] = 9; 5165 si->port_cosq_base[LB_PORT(unit)] = _APACHE_LB_QUEUE_BASE - _APACHE_MC_QUEUE_BASE ; 5166 si->port_num_cosq[RDB_PORT(unit)] = 0; 5167 #if defined(BCM_56560_A0) 5168 si->port_cosq_base[74] = 0; 5169 #endif 5170 5171 SOC_PBMP_COUNT(si->eq_pbm, count); 5172 /* Flexport op may lead to change of schedulars. 5173 * Assign LLS uc queues from 16(max HSP ports)*10 onwards 5174 * to prevent any possible overlap 5175 */ 5176 lls_uc_cosq_base = 5177 soc_reg_field_length(unit, HSP_SCHED_GLOBAL_CONFIGr, IS_HSP_PORT_IN_XPIPEf) * 10; 5178 5179 for (mmu_port = 0; mmu_port < _APACHE_MMU_PORTS_PER_PIPE; mmu_port++) { 5180 phy_port = si->port_m2p_mapping[mmu_port]; 5181 if (phy_port == -1) { 5182 continue; 5183 } 5184 5185 port = si->port_p2l_mapping[phy_port]; 5186 if (port == -1) { 5187 continue; 5188 } 5189 5190 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 5191 continue; 5192 } 5193 5194 si->port_num_cosq[port] = 10; 5195 si->port_cosq_base[port] = mmu_port * si->port_num_cosq[port]; 5196 5197 if (SOC_PBMP_MEMBER(si->eq_pbm, port)) { /* VBS (HSP) port */ 5198 /* Made port_uc_cosq_base a function of mmu_port number 5199 * rather than a running number (as calculated by 5200 * uc_cosq_base before). If it is a running number, & 5201 * the port numbers come & go dynamically (as in flex port) 5202 * uc_cosq_base overlap. With port_uc_cosq_base a function 5203 * of mmu_port, each port has a fixed offset 5204 */ 5205 si->port_num_uc_cosq[port] = 10; 5206 si->port_uc_cosq_base[port] = mmu_port * si->port_num_uc_cosq[port]; 5207 } else { 5208 si->port_num_uc_cosq[port] = 16; 5209 /* uc_cosq_base for LLS port must be: 5210 * divisible by 4 for PFC to work 5211 * divisible by 8 for E2ECC to work 5212 */ 5213 5214 lls_uc_cosq_base = (lls_uc_cosq_base + 7) & (~7); 5215 si->port_uc_cosq_base[port] = lls_uc_cosq_base; 5216 lls_uc_cosq_base += si->port_num_uc_cosq[port]; 5217 } 5218 5219 if ((si->port_uc_cosq_base[port] > _APACHE_NUMBER_OF_UC_QUEUE) || 5220 (si->port_cosq_base[port] > _APACHE_NUMBER_OF_MC_QUEUE)) { 5221 return SOC_E_INTERNAL; 5222 } 5223 5224 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 5225 "port = %d phy_port = %d mmu = %d ucq = %d mcq = %d\n"), 5226 port, phy_port, mmu_port, si->port_uc_cosq_base[port], si->port_cosq_base[port])); 5227 } 5228 5229 return SOC_E_NONE; 5230 } 5231 5232 STATIC int 5233 soc_apache_frequency_get(int unit, int *max_freq, int *def_freq) 5234 { 5235 if (soc_feature(unit, soc_feature_untethered_otp)) { 5236 *max_freq = SOC_BOND_INFO(unit)->max_core_freq; 5237 *def_freq = SOC_BOND_INFO(unit)->default_core_freq; 5238 } else { 5239 *def_freq = 793; 5240 *max_freq = 841; 5241 } 5242 5243 return SOC_E_NONE; 5244 } 5245 5246 int 5247 soc_apache_tsc_map_get(int unit, uint32 *tsc_map, uint32 *force_hg) 5248 { 5249 5250 if (soc_feature(unit, soc_feature_untethered_otp)) { 5251 *tsc_map = SOC_BOND_INFO(unit)->tsc_enable; 5252 *force_hg = SOC_BOND_INFO(unit)->tsc_force_hg; 5253 } else { 5254 *tsc_map = 0xffffffff; 5255 *force_hg = 0x0; 5256 } 5257 5258 return SOC_E_NONE; 5259 } 5260 5261 typedef struct soc_apache_valid_fallback_cores_s { 5262 soc_100g_lane_config_t lane_config; 5263 int valid_lanes[3]; 5264 }soc_apache_valid_fallback_cores_t; 5265 5266 const soc_apache_valid_fallback_cores_t soc_apache_valid_an_cores[] = { 5267 {SOC_LANE_CONFIG_100G_4_4_2, {TRUE, TRUE, TRUE} }, 5268 {SOC_LANE_CONFIG_100G_3_4_3, {TRUE, TRUE, TRUE} }, 5269 {SOC_LANE_CONFIG_100G_2_4_4, {TRUE, TRUE, TRUE} }, 5270 {SOC_INVALID_LANE_CONFIG} 5271 }; 5272 5273 5274 STATIC int 5275 soc_apache_port_is_falcon(int unit, int phy_port) 5276 { 5277 5278 if (((phy_port >= 29) && (phy_port <= 36)) || 5279 ((phy_port >= 65) && (phy_port <= 72))) { 5280 return TRUE; 5281 } 5282 5283 return FALSE; 5284 } 5285 5286 STATIC int 5287 soc_apache_port_is_2p5g_forced(int unit, int phy_port) 5288 { 5289 int tsc_id, bit_pos; 5290 if (soc_apache_port_is_falcon(unit, phy_port) || 5291 !soc_feature(unit, soc_feature_untethered_otp)) { 5292 return FALSE; 5293 } 5294 5295 tsc_id = ((phy_port - 1) / APACHE_PORTS_PER_TSC); 5296 5297 /* SOC_BOND_INFO(unit)->tsce_max_2p5g is 14bit wide representing 14 Eagle TSCs in AP 5298 * In case TSC belongs in PGW 1, subtract 2 TSC falcons of PGW 0 to get correct bit pos 5299 */ 5300 bit_pos = (tsc_id >= APACHE_TSCS_PER_PGW) ? (tsc_id - APACHE_NUM_CLP_PER_PGW) : tsc_id; 5301 5302 if (!((SOC_BOND_INFO(unit)->tsce_max_2p5g) & (1 << bit_pos))) { 5303 return FALSE; 5304 } 5305 return TRUE; 5306 } 5307 5308 #if 0 5309 STATIC int 5310 soc_apache_port_is_11g_forced(int unit, int phy_port) 5311 { 5312 int tsc_id, bit_pos; 5313 if (!soc_apache_port_is_falcon(unit, phy_port) || 5314 !soc_feature(unit, soc_feature_untethered_otp)) { 5315 return FALSE; 5316 } 5317 5318 tsc_id = ((phy_port - 1) / APACHE_PORTS_PER_TSC); 5319 5320 /* SOC_BOND_INFO(unit)->tscf_max_11g is 4bit wide representing 4 Falcon TSCs in AP 5321 * In case TSC belongs in PGW 1, subtract 7 TSC eagles of PGW 1 to get correct bit pos 5322 */ 5323 bit_pos = (tsc_id >= APACHE_TSCS_PER_PGW) ? (tsc_id - APACHE_NUM_XLP_PER_PGW) : tsc_id; 5324 5325 /* Subtract 7 TSC eagles for PGW 0 */ 5326 bit_pos -= APACHE_NUM_XLP_PER_PGW; 5327 5328 if (!((SOC_BOND_INFO(unit)->tscf_max_11g) & (1 << bit_pos))) { 5329 return FALSE; 5330 } 5331 return TRUE; 5332 } 5333 #endif 5334 5335 /* If CLPORT0/1/2/3/4/5 block is disabled 5336 * CLPORT speeds like 1x100G, 2x50G, 4x25G are disabled 5337 */ 5338 #define IS_100G_DISABLED(clp_block) \ 5339 (soc_feature(unit, soc_feature_untethered_otp) ? (!((SOC_BOND_INFO(unit)->clmac_map) & (1 << (clp_block)))) : (0)) 5340 5341 STATIC soc_error_t 5342 _soc_apache_port_lanes_set(int unit, int phy_port, int *lanes, int port_bandwidth) 5343 { 5344 if (soc_apache_port_is_falcon(unit, phy_port)) { 5345 *lanes = (port_bandwidth > 53000) ? 5346 (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1 5347 : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1 5348 : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1 5349 : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1 5350 : 4 5351 : (port_bandwidth > 42000) ? 5352 (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1 5353 : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1 5354 : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1 5355 : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1 5356 : 2 5357 : (port_bandwidth > 27000) ? 5358 (IS_100G_DISABLED(1) && (phy_port == 29)) ? 4 5359 : (IS_100G_DISABLED(2) && (phy_port == 33)) ? 4 5360 : (IS_100G_DISABLED(4) && (phy_port == 65)) ? 4 5361 : (IS_100G_DISABLED(5) && (phy_port == 69)) ? 4 5362 : 2 5363 : (port_bandwidth == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(21000)) ? 2 5364 : (port_bandwidth > 11000) ? 5365 (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1 5366 : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1 5367 : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1 5368 : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1 5369 : 1 5370 : 1; 5371 } else { 5372 *lanes = (port_bandwidth >= 100000) ? 5373 (IS_100G_DISABLED(0) && (phy_port == 17)) ? -1 5374 : (IS_100G_DISABLED(3) && (phy_port == 53)) ? -1 5375 : 10 5376 : (port_bandwidth > 21000) ? 4 5377 : (port_bandwidth > 11000) ? 2 5378 : 1; 5379 } 5380 return ((*lanes == -1) ? SOC_E_CONFIG : SOC_E_NONE); 5381 } 5382 5383 /* Function to check legal BW values per port 5384 */ 5385 STATIC int 5386 _soc_apache_port_speed_supported(int unit, int port, int phy_port, 5387 int port_lanes, int port_bandwidth) 5388 { 5389 soc_pbmp_t xe_pbmp; 5390 5391 if (port_lanes == -1) { 5392 if (SOC_FAILURE(_soc_apache_port_lanes_set(unit, phy_port, &port_lanes, port_bandwidth))) { 5393 return FALSE; 5394 } 5395 } 5396 5397 switch (port_bandwidth) { 5398 case 1000: 5399 /* Eagles or Falcons - 1 x lanes */ 5400 return (port_lanes == 1); 5401 case 2500: 5402 case 5000: 5403 /* Eagles only - 1 x lanes */ 5404 return (!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 1)); 5405 case 10000: 5406 /* Falcons - 1 x lanes and Eagles - 1, 2 or 4 lanes */ 5407 return (!soc_apache_port_is_falcon(unit, phy_port) || 5408 (soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 1))); 5409 case 20000: 5410 /* Eagles or Falcons - 2 x lanes */ 5411 return ((!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4)) || (port_lanes == 2)); 5412 case 25000: 5413 /* Falcons only - 1 x lanes */ 5414 return ((soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 1)) || 5415 (!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4))); 5416 case 30000: 5417 /* Eagles only - 4 x lanes */ 5418 return (!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4)); 5419 case 40000: 5420 /* Eagles - 4 x lanes; Falcons - 2, 4 lanes */ 5421 return ((!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4)) || 5422 (soc_apache_port_is_falcon(unit, phy_port) && ((port_lanes == 2) || (port_lanes == 4)))); 5423 case 50000: 5424 /* Falcons only - 2 lanes */ 5425 return (soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 2)); 5426 case 100000: 5427 /* Eagles - 10 x lanes; Falcons - 4 lanes */ 5428 return ((!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 10)) || 5429 (soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4))); 5430 5431 case 11000: 5432 case 21000: 5433 case 27000: 5434 case 42000: 5435 case 53000: 5436 case 106000: 5437 SOC_PBMP_CLEAR(xe_pbmp); 5438 xe_pbmp = soc_property_get_pbmp_default(unit, 5439 spn_PBMP_XPORT_XE, xe_pbmp); 5440 if (!SOC_PBMP_MEMBER(xe_pbmp, port)) { 5441 return _soc_apache_port_speed_supported(unit, port, phy_port, port_lanes, SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(port_bandwidth)); 5442 } else { 5443 LOG_CLI((BSL_META_U(unit, 5444 "Port %d: Invalid HG2 bandwidth %d Gb\n"), 5445 port, port_bandwidth / 1000)); 5446 return FALSE; 5447 } 5448 break; 5449 5450 default: 5451 LOG_CLI((BSL_META_U(unit, 5452 "Port %d: Invalid bandwidth %d Gb\n"), 5453 port, port_bandwidth / 1000)); 5454 return FALSE; 5455 break; 5456 } 5457 5458 return FALSE; 5459 } 5460 5461 int 5462 soc_apache_port_config_bandwidth_check(int unit) 5463 { 5464 int rv = SOC_E_NONE; 5465 int oversub_mode; 5466 int port_bandwidth; 5467 int *blk_port = NULL; 5468 int *blk_port_bandwidth = NULL; 5469 int index, port, phy_port, lane_count, blk, pgw; 5470 int is_fb5_device = 0; 5471 int speed_lanes_1 = 0, speed_lanes_2 = 0; 5472 int blk_linerate_bandwidth, blk_oversub_bandwidth; 5473 int pgw_port[APACHE_PORTS_PER_PGW]; 5474 int pgw_port_bandwidth[APACHE_PORTS_PER_PGW]; 5475 int pgw_linerate_bandwidth[APACHE_PGWS_PER_DEV], pgw_oversub_bandwidth[APACHE_PGWS_PER_DEV]; 5476 int max_pgw_core_bandwidth[APACHE_PGWS_PER_DEV]; 5477 int max_pgw_oversub_bandwidth[APACHE_PGWS_PER_DEV]; 5478 int os_ratio[APACHE_PGWS_PER_DEV]; 5479 /* MAX OS ratio for a few FB5 configs is > 1.5 but is limited only to a single PGW */ 5480 int max_os_ratio = 1750, def_os_ratio = 1500; 5481 uint32 blk_configured_map, blk_inactive_map, blk_oversub_map; 5482 int falcon_lr_bandwidth = 0, falcon_os_bandwidth = 0, *falcon_bw_ptr = 0; 5483 5484 for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) { 5485 max_pgw_core_bandwidth[pgw] = (SOC_INFO(unit).bandwidth) / APACHE_PGWS_PER_DEV; 5486 max_pgw_oversub_bandwidth[pgw] = (SOC_INFO(unit).io_bandwidth) / APACHE_PGWS_PER_DEV; 5487 5488 /* OVSB TDM per slot bandwidth granularity is 10G 5489 * 56068 SKU has 2x1G ports which will be passed as 2x10g to algo-TDM 5490 * We don't care even if io_bandwidth overshoots 5491 * as long as TDM calendar allocates only 1g worth of slots. 5492 */ 5493 max_pgw_oversub_bandwidth[pgw] += (SOC_INFO(unit).frequency == 841 ? 10000 : 0); 5494 } 5495 5496 oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0); 5497 5498 /* Bandwidth check for ports in each XLPORT/CLPORT block */ 5499 for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) { 5500 pgw_linerate_bandwidth[pgw] = 0; 5501 pgw_oversub_bandwidth[pgw] = 0; 5502 5503 /* Prepare per PGW local variables for ease of processing */ 5504 for (index = 0; index < APACHE_PORTS_PER_PGW; index++) { 5505 phy_port = 1 + pgw * APACHE_PORTS_PER_PGW + index; 5506 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 5507 pgw_port[index] = port; 5508 if (port == -1) { 5509 pgw_port_bandwidth[index] = 0; 5510 } else { 5511 pgw_port_bandwidth[index] = SOC_INFO(unit).port_speed_max[port]; 5512 APACHE_TDM_SPEED_ADJUST(unit, port, pgw_port_bandwidth[index]); 5513 } 5514 } 5515 5516 for (blk = 0; blk < APACHE_TSCS_PER_PGW; blk++) { 5517 5518 blk_port = &pgw_port[blk * APACHE_PORTS_PER_TSC]; 5519 blk_port_bandwidth = &pgw_port_bandwidth[blk * APACHE_PORTS_PER_TSC]; 5520 5521 blk_configured_map = 0; 5522 for (index = 0; index < APACHE_PORTS_PER_TSC; index++) { 5523 if (blk_port[index] != -1) { 5524 blk_configured_map |= 1 << index; 5525 } 5526 } 5527 if (blk_configured_map == 0) { 5528 continue; 5529 } 5530 5531 /* Normal port block handling */ 5532 blk_inactive_map = 0; 5533 blk_oversub_map = 0; 5534 blk_linerate_bandwidth = 0; 5535 blk_oversub_bandwidth = 0; 5536 for (index = 0; index < APACHE_PORTS_PER_TSC; index++) { 5537 port = blk_port[index]; 5538 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 5539 if (port == -1) { 5540 continue; 5541 } 5542 port_bandwidth = blk_port_bandwidth[index]; 5543 if (IS_OVERSUB_PORT(unit, port)) { 5544 blk_oversub_map |= 1 << index; 5545 } 5546 if (SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 5547 blk_inactive_map |= 1 << index; 5548 } else { 5549 if (blk_oversub_map & (1 << index)) { 5550 falcon_bw_ptr = &falcon_os_bandwidth; 5551 blk_oversub_bandwidth += port_bandwidth; 5552 } else { 5553 falcon_bw_ptr = &falcon_lr_bandwidth; 5554 blk_linerate_bandwidth += port_bandwidth; 5555 } 5556 } 5557 5558 /* 0-3 Blocks are PM4x10 and 4-6 are PM12x10 */ 5559 if (blk >= 0 && blk <= 6) { 5560 if ((port_bandwidth > 106000) || 5561 (port_bandwidth > 42000 && (blk != 4)) || 5562 (port_bandwidth > 21000 && (index != 0)) || 5563 (port_bandwidth > 11000 && (index & 1))) { 5564 5565 LOG_CLI((BSL_META_U(unit, 5566 "Port %d: Physical port %d can not " 5567 "be configured to %d Gb\n"), 5568 port, phy_port, (port_bandwidth / 1000))); 5569 rv = SOC_E_FAIL; 5570 } 5571 5572 speed_lanes_1 = 11000; 5573 speed_lanes_2 = 21000; 5574 } 5575 5576 /* 7-8 Blocks are PM4x25 */ 5577 if (blk >= 7 && blk <= 8) { 5578 if ((port_bandwidth > 106000) || 5579 (port_bandwidth > 53000 && (index != 0)) || 5580 (port_bandwidth > 27000 && (index & 1))) { 5581 5582 LOG_CLI((BSL_META_U(unit, 5583 "Port %d: Physical port %d can not " 5584 "be configured to %d Gb\n"), 5585 port, phy_port, (port_bandwidth / 1000))); 5586 rv = SOC_E_FAIL; 5587 } 5588 5589 speed_lanes_1 = 27000; 5590 speed_lanes_2 = 53000; 5591 5592 *falcon_bw_ptr += port_bandwidth; 5593 } 5594 } 5595 5596 /* Check if any of the lanes used by first port of block is 5597 * not used by other port */ 5598 port_bandwidth = blk_port_bandwidth[0]; 5599 if (port_bandwidth > speed_lanes_2) { 5600 lane_count = 4; 5601 } else if (port_bandwidth > speed_lanes_1) { 5602 lane_count = 2; 5603 } else { 5604 lane_count = 1; 5605 } 5606 5607 for (index = 1; index < lane_count; index++) { 5608 port = blk_port[index]; 5609 if (port == -1 || SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 5610 continue; 5611 } 5612 LOG_CLI((BSL_META_U(unit, 5613 "Port %d bandwidth %d Gb and " 5614 "port %d can not be both configured\n"), 5615 blk_port[0], port_bandwidth / 1000, port)); 5616 rv = SOC_E_FAIL; 5617 } 5618 5619 /* Check if any of the lanes used by third port of block is 5620 * not used by other port */ 5621 port_bandwidth = blk_port_bandwidth[2]; 5622 if (port_bandwidth > speed_lanes_1) { 5623 port = blk_port[3]; 5624 if (port != -1 && !SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 5625 LOG_CLI((BSL_META_U(unit, 5626 "Port %d bandwidth %d Gb and port %d " 5627 "can not be both configured\n"), 5628 blk_port[2], port_bandwidth / 1000, port)); 5629 rv = SOC_E_FAIL; 5630 } 5631 if (blk_port[0] == -1) { 5632 LOG_CLI((BSL_META_U(unit, 5633 "Physical port %d needs to be " 5634 "configured in order to work with " 5635 "port %d\n"), 5636 1 + pgw * APACHE_PORTS_PER_PGW + 5637 blk * APACHE_PORTS_PER_TSC, 5638 blk_port[2])); 5639 rv = SOC_E_FAIL; 5640 } 5641 } 5642 5643 if (blk_inactive_map == blk_configured_map) { 5644 LOG_CLI((BSL_META_U(unit, "Flex port"))); 5645 for (index = 0; index < APACHE_PORTS_PER_TSC; index++) { 5646 if (blk_port[index] != -1) { 5647 LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index])); 5648 } 5649 } 5650 LOG_CLI((BSL_META_U(unit, ": Can not be all inactive\n"))); 5651 rv = SOC_E_FAIL; 5652 continue; 5653 } 5654 5655 if (blk_inactive_map != 0) { 5656 if (blk_oversub_map != 0 && 5657 blk_oversub_map != blk_configured_map) { 5658 LOG_CLI((BSL_META_U(unit, "Flex port"))); 5659 for (index = 0; index < APACHE_PORTS_PER_TSC; 5660 index++) { 5661 if (blk_port[index] != -1) { 5662 LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index])); 5663 } 5664 } 5665 LOG_CLI((BSL_META_U(unit, 5666 ": Can not be configured to " 5667 "different oversubscription " 5668 "mode within a port block\n"))); 5669 rv = SOC_E_FAIL; 5670 continue; 5671 } 5672 } 5673 5674 if (falcon_lr_bandwidth != 0 && falcon_os_bandwidth != 0) { 5675 LOG_CLI((BSL_META_U(unit, 5676 "TDM algorith does not support mixed LR and OS ports " 5677 "modes on PM4x25 ports. LR BW = %d Gbps & OS BW = %d Gbps\n"), 5678 falcon_lr_bandwidth / 1000, falcon_os_bandwidth / 1000)); 5679 rv = SOC_E_FAIL; 5680 } 5681 5682 5683 if (blk_linerate_bandwidth != 0 && blk_oversub_map != 0) { 5684 LOG_CLI((BSL_META_U(unit, 5685 "TSC %d cannot have mixed LR and OS ports " 5686 "LR Bandwidth = %d Gbps & OS Bandwidth = %d Gbps\n"), 5687 blk, blk_linerate_bandwidth / 1000, blk_oversub_bandwidth / 1000)); 5688 rv = SOC_E_FAIL; 5689 } 5690 5691 pgw_linerate_bandwidth[pgw] += blk_linerate_bandwidth; 5692 pgw_oversub_bandwidth[pgw] += blk_oversub_bandwidth; 5693 } /* for (blk = 0; blk < APACHE_TSCS_PER_PGW; blk++) */ 5694 5695 if ((oversub_mode == 1) && (pgw_linerate_bandwidth[pgw] != 0)) { 5696 LOG_ERROR(BSL_LS_SOC_COMMON, 5697 (BSL_META_U(unit, "Oversub mode: Linerate BW for PGW %d is not 0.\n"), pgw)); 5698 rv = SOC_E_FAIL; 5699 } else if ((oversub_mode == 0) && (pgw_oversub_bandwidth[pgw] != 0)) { 5700 LOG_ERROR(BSL_LS_SOC_COMMON, 5701 (BSL_META_U(unit, "Linerate mode: Oversub BW for PGW %d is not 0.\n"), pgw)); 5702 rv = SOC_E_FAIL; 5703 } else if (oversub_mode == 2) { 5704 /* 5705 * OS ratio = (IO BW - LR BW) / (MAX LR BW - IO LR BW) 5706 */ 5707 os_ratio[pgw] = (((pgw_oversub_bandwidth[pgw]) * 1000) / (max_pgw_core_bandwidth[pgw] - pgw_linerate_bandwidth[pgw])); 5708 } 5709 5710 if (soc_feature(unit, soc_feature_untethered_otp)) { 5711 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureFamilyFirebolt5)) { 5712 is_fb5_device = 1; 5713 } 5714 } 5715 5716 /* 5717 * On some FB5 SKUs, there will be a few MGIG ports for which the estimated 5718 * effective bandwidth will be 10G for each port in theory. 5719 * This would make the bandwidth checks below to fail. 5720 * It is expected that the users do not run these ports beyond 1G or 5721 * whatever is constrained by the HW Datasheet. These checks are relaxed for FB5 configs. 5722 */ 5723 if ((oversub_mode != 2) && !is_fb5_device){ 5724 /* Linerate Bandwidth check */ 5725 if (pgw_linerate_bandwidth[pgw] > max_pgw_core_bandwidth[pgw]) { 5726 LOG_CLI((BSL_META_U(unit, 5727 "PGW_CL%d total line rate bandwidth " 5728 "(%d Gb) exceeds %d Gb\n"), 5729 pgw, (pgw_linerate_bandwidth[pgw] / 1000), 5730 (max_pgw_core_bandwidth[pgw] / 1000))); 5731 rv = SOC_E_FAIL; 5732 } 5733 5734 /* Oversub Bandwidth check */ 5735 if ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) > max_pgw_oversub_bandwidth[pgw]) { 5736 LOG_CLI((BSL_META_U(unit, 5737 "PGW_CL%d total oversub bandwidth " 5738 "(%d Gb) exceeds %d Gb\n"), 5739 pgw, ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) / 1000), 5740 (max_pgw_oversub_bandwidth[pgw] / 1000))); 5741 rv = SOC_E_FAIL; 5742 } 5743 } 5744 } 5745 5746 if (oversub_mode == 2) { 5747 /* For mixed-mode we can have asymmetrical bandwidth distribution 5748 * Check the OS ratio in this case 5749 */ 5750 if ((os_ratio[APACHE_PGW0] > def_os_ratio) && (os_ratio[APACHE_PGW0] < max_os_ratio)) { 5751 if (os_ratio[APACHE_PGW1] > def_os_ratio) { 5752 LOG_CLI((BSL_META_U(unit, 5753 "PGW_CL1 total oversub bandwidth " 5754 "(%d Gb) exceeds limit\n"), 5755 ((pgw_oversub_bandwidth[APACHE_PGW1]) / 1000))); 5756 rv = SOC_E_FAIL; 5757 } 5758 } else if ((os_ratio[APACHE_PGW1] > def_os_ratio) && (os_ratio[APACHE_PGW1] < max_os_ratio)) { 5759 if (os_ratio[APACHE_PGW0] > def_os_ratio) { 5760 LOG_CLI((BSL_META_U(unit, 5761 "PGW_CL0 total oversub bandwidth " 5762 "(%d Gb) exceeds limit\n"), 5763 ((pgw_oversub_bandwidth[APACHE_PGW0]) / 1000))); 5764 rv = SOC_E_FAIL; 5765 } 5766 } 5767 } 5768 5769 return rv; 5770 } 5771 5772 5773 int 5774 soc_apache_mmu_hsp_port_reserve(int unit, int port, int speed_max) 5775 { 5776 int def_freq, max_freq; 5777 int min_hsp_ovs_speed; 5778 5779 SOC_IF_ERROR_RETURN(soc_apache_frequency_get(unit, &max_freq, &def_freq)); 5780 def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq); 5781 5782 switch (def_freq) { 5783 case 841: 5784 case 793: 5785 min_hsp_ovs_speed = 100000; 5786 break; 5787 default: 5788 min_hsp_ovs_speed = 40000; 5789 break; 5790 5791 } 5792 5793 if (IS_OVERSUB_PORT(unit, port) && speed_max >= min_hsp_ovs_speed) { 5794 return TRUE; 5795 } 5796 5797 return FALSE; 5798 } 5799 5800 /* MMU port numbers must be in following range. 5801 * HSP ports : [0-15] 5802 * CT ports (40G OS) : [0-17] 5803 * 50G/53G LR : [0-15] 5804 */ 5805 STATIC int 5806 soc_apache_mmu_ports_assign(int unit) 5807 { 5808 int port, phy_port, mmu_port; 5809 int port_is_hsp; 5810 int num_phy_port = APACHE_PORTS_PER_PIPE; 5811 soc_info_t *si; 5812 soc_pbmp_t pbmp; 5813 5814 si = &SOC_INFO(unit); 5815 5816 /* Setup vector-based scheduler (VBS) 5817 * a.k.a high speed port scheduler (HSP) pbm */ 5818 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5819 port = si->port_p2l_mapping[phy_port]; 5820 if (port == -1) { 5821 continue; 5822 } 5823 5824 /* Usage: 5825 * port_sched_hsp_<log_port> = 1 ; Port is in HSP 5826 * port_sched_hsp_<log_port> = 0 ; Port is in LLS 5827 * port_sched_hsp_<log_port> = -1 (default) ; SDK determines sched type 5828 */ 5829 port_is_hsp = (soc_property_port_get(unit, port, spn_PORT_SCHED_HSP, -1)); 5830 if (port_is_hsp == -1) { 5831 port_is_hsp = soc_apache_mmu_hsp_port_reserve(unit, port, si->port_speed_max[port]); 5832 } 5833 5834 if (port_is_hsp) { 5835 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 5836 } else { 5837 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port); 5838 } 5839 5840 } 5841 5842 #ifdef BCM_WARM_BOOT_SUPPORT 5843 if (SOC_WARM_BOOT(unit)) { 5844 /* For WB we recover port mappings from scache */ 5845 return SOC_E_NONE; 5846 } 5847 #endif 5848 5849 mmu_port = 0; 5850 5851 /* First assign the lowest MMU port number for VBS (HSP) ports */ 5852 pbmp = si->xpipe_pbm; 5853 SOC_PBMP_AND(pbmp, si->eq_pbm); 5854 SOC_PBMP_ITER(pbmp, port) { 5855 if ( port < _APACHE_LOG_PORTS_PER_PIPE ) { 5856 phy_port = si->port_l2p_mapping[port]; 5857 if ( phy_port <= num_phy_port) { 5858 si->port_p2m_mapping[phy_port] = mmu_port; 5859 si->port_m2p_mapping[mmu_port] = phy_port; 5860 mmu_port++; 5861 } 5862 } 5863 } 5864 5865 /* Assign MMU port for all OS ports with speed >= 100G 5866 * 100G OS ports are HSP by default 5867 */ 5868 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5869 if (si->port_p2m_mapping[phy_port] != -1) { 5870 continue; 5871 } 5872 5873 port = si->port_p2l_mapping[phy_port]; 5874 if (port == -1) { 5875 continue; 5876 } 5877 5878 if ((IS_OVERSUB_PORT(unit, port)) && 5879 (si->port_speed_max[port] >= 100000)) { 5880 si->port_p2m_mapping[phy_port] = mmu_port; 5881 si->port_m2p_mapping[mmu_port] = phy_port; 5882 mmu_port++; 5883 } 5884 } 5885 5886 /* Assign MMU port for all OS ports with speed = 40G/42G 5887 * 40G OS ports support CT 5888 */ 5889 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 5890 if (si->port_p2m_mapping[phy_port] != -1) { 5891 continue; 5892 } 5893 5894 port = si->port_p2l_mapping[phy_port]; 5895 if (port == -1) { 5896 continue; 5897 } 5898 5899 if ((IS_OVERSUB_PORT(unit, port)) && 5900 (SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(si->port_speed_max[port]) == 40000 )) { 5901 si->port_p2m_mapping[phy_port] = mmu_port; 5902 si->port_m2p_mapping[mmu_port] = phy_port; 5903 mmu_port++; 5904 } 5905 } 5906 5907 /* Assign MMU port for 1st OS phy port in PM4x25 5908 * Can become 100G(HSP) or 40G(CT) after flex 5909 */ 5910 for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) { 5911 if (si->port_p2m_mapping[phy_port] != -1) { 5912 continue; 5913 } 5914 5915 port = si->port_p2l_mapping[phy_port]; 5916 if (port == -1) { 5917 continue; 5918 } 5919 5920 if (IS_OVERSUB_PORT(unit, port) && 5921 soc_apache_port_is_falcon(unit, phy_port)) { 5922 si->port_p2m_mapping[phy_port] = mmu_port; 5923 si->port_m2p_mapping[mmu_port] = phy_port; 5924 mmu_port++; 5925 } 5926 } 5927 5928 /* Assign MMU port to 1st phy port in remaining(disabled) PM4x25 5929 * Can become 100G(HSP) or 40G(CT) or 50G(LR) after flex 5930 */ 5931 for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) { 5932 if (si->port_p2m_mapping[phy_port] != -1) { 5933 continue; 5934 } 5935 5936 if (soc_apache_port_is_falcon(unit, phy_port)) { 5937 si->port_p2m_mapping[phy_port] = mmu_port; 5938 si->port_m2p_mapping[mmu_port] = phy_port; 5939 mmu_port++; 5940 } 5941 } 5942 5943 /* Assign MMU port to 3rd OS phy port in PM4x25 5944 * Can become 40G(CT) after flex 5945 */ 5946 for (phy_port = 3; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) { 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 (IS_OVERSUB_PORT(unit, port) && 5957 soc_apache_port_is_falcon(unit, phy_port)) { 5958 si->port_p2m_mapping[phy_port] = mmu_port; 5959 si->port_m2p_mapping[mmu_port] = phy_port; 5960 mmu_port++; 5961 } 5962 } 5963 5964 /* Assign MMU port to 1st OS phy port in PM4x10 5965 * Can become 40G(CT) after flex 5966 */ 5967 for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) { 5968 if (si->port_p2m_mapping[phy_port] != -1) { 5969 continue; 5970 } 5971 5972 port = si->port_p2l_mapping[phy_port]; 5973 if (port == -1) { 5974 continue; 5975 } 5976 5977 if (IS_OVERSUB_PORT(unit, port)) { 5978 si->port_p2m_mapping[phy_port] = mmu_port; 5979 si->port_m2p_mapping[mmu_port] = phy_port; 5980 mmu_port++; 5981 } 5982 } 5983 5984 /* Assign MMU port to 3rd phy port in remaining(disabled) PM4x25 5985 * Can become 40G(CT) or 50g(LR) after flex 5986 */ 5987 for (phy_port = 3; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) { 5988 if (si->port_p2m_mapping[phy_port] != -1) { 5989 continue; 5990 } 5991 5992 if (soc_apache_port_is_falcon(unit, phy_port)) { 5993 si->port_p2m_mapping[phy_port] = mmu_port; 5994 si->port_m2p_mapping[mmu_port] = phy_port; 5995 mmu_port++; 5996 } 5997 } 5998 5999 /* Assign MMU port to 1st phy port in remaining(disabled) PM4x10 6000 * Can become 40G(CT) after flex 6001 */ 6002 for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) { 6003 if (si->port_p2m_mapping[phy_port] != -1) { 6004 continue; 6005 } 6006 6007 si->port_p2m_mapping[phy_port] = mmu_port; 6008 si->port_m2p_mapping[mmu_port] = phy_port; 6009 mmu_port++; 6010 } 6011 6012 /* Assign MMU port for all remaining valid ports */ 6013 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 6014 if (si->port_p2m_mapping[phy_port] != -1) { 6015 continue; 6016 } 6017 6018 if (si->port_p2l_mapping[phy_port] == -1) { 6019 continue; 6020 } 6021 6022 si->port_p2m_mapping[phy_port] = mmu_port; 6023 si->port_m2p_mapping[mmu_port] = phy_port; 6024 mmu_port++; 6025 } 6026 6027 /* Assign MMU port for all remaining(disabled) ports */ 6028 for (phy_port = 1; phy_port <= num_phy_port; phy_port++) { 6029 if (si->port_p2m_mapping[phy_port] != -1) { 6030 continue; 6031 } 6032 6033 si->port_p2m_mapping[phy_port] = mmu_port; 6034 si->port_m2p_mapping[mmu_port] = phy_port; 6035 mmu_port++; 6036 } 6037 6038 return SOC_E_NONE; 6039 } 6040 6041 STATIC int 6042 _soc_ap_ports_speed_init_update(int unit) 6043 { 6044 int port; 6045 soc_info_t *si = &SOC_INFO(unit); 6046 6047 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 6048 /* Set init speed to max speed by default */ 6049 /* Used during port probe and portmod attach */ 6050 si->port_init_speed[port] = si->port_speed_max[port]; 6051 } 6052 6053 return SOC_E_NONE; 6054 } 6055 6056 /* 6057 * Apache port mapping 6058 * 130 physical ports: port 0-64 in X pipe, port 65-129 in Y pipe 6059 * 106 logical ports 6060 * 108 mmu ports: port 0-53 in X pipe, port 64-117 in Y pipe 6061 * cpu port number is fixed: physical 0, logical 0, mmu 52 6062 * loopback port number is fixed: physical 129, logical 105, mmu 116 6063 * mmu port 53 and mmu port 117 are purge port 6064 * mmu port can only map to physical port ID in the same pipe 6065 * XLPORT3 (physical port 13-16) can be configured as management port(s) 6066 * management port can be: 6067 * - one 10G port 6068 * - one to four ports with speed up to 2.5G each 6069 * Physical port number in eacc port group 6070 * PGW_CL0: XLPORTB0_0 TSC-E 0 port 1-4 6071 * XLPORTB0_1 TSC-E 1 port 5-8 6072 * XLPORTB0_2 TSC-E 2 port 9-12 6073 * XLPORTB0_3 TSC-E 3 port 13-16 6074 * CXXPORT0 TSC-E 4-6 port 17-28 6075 * CLPORT0 TSC-E 4-6 port 17 6076 * XLPORT4 TSC-E 4 port 17-20 6077 * XLPORT5 TSC-E 5 port 21-24 6078 * XLPORT6 TSC-E 6 port 25-28 6079 * CLPORT1 TSC-F 0 port 29-32 6080 * CLPORT2 TSC-F 1 port 33-36 6081 * 6082 * PGW_CL1: XLPORTB0_7 TSC-E 7 port 37-40 6083 * XLPORTB0_8 TSC-E 8 port 41-44 6084 * XLPORTB0_9 TSC-E 9 port 45-48 6085 * XLPORTB0_10 TSC-E 10 port 49-52 6086 * CXXPORT1 TSC-E 11-13 port 53-64 6087 * CLPORT3 TSC-E 11-13 port 53 6088 * XLPORT11 TSC-E 11 port 53-56 6089 * XLPORT12 TSC-E 12 port 57-60 6090 * XLPORT13 TSC-E 13 port 61-64 6091 * CLPORT4 TSC-F 2 port 65-68 6092 * CLPORT5 TSC-F 3 port 69-72 6093 * This routine will setup: 6094 * SOC_INFO(unit).port_p2l_mapping[] 6095 * SOC_INFO(unit).port_l2p_mapping[] 6096 * SOC_INFO(unit).port_p2m_mapping[] 6097 * SOC_INFO(unit).port_m2p_mapping[] 6098 * SOC_INFO(unit).port_speed_max[] 6099 * SOC_INFO(unit).port_group[] 6100 * SOC_INFO(unit).port_serdes[] 6101 * SOC_INFO(unit).port_num_lanes[] 6102 * SOC_INFO(unit).phy_port_base[] 6103 * SOC_INFO(unit).mmu_port_base[] 6104 * 100+G port: 6105 * - can only be @ 760MHz 6106 * - needs to be HSP 6107 * - cannot be in oversubscribe mode 6108 * 40/42G port: 6109 * - needs to be HSP except @ 760MHz 6110 * - oversubscribe mode can support both cut-through and store-and-forward 6111 * sub-40G port: 6112 * - oversubscribe mode can only support store-and-forward 6113 */ 6114 int 6115 soc_apache_port_config_init(int unit, uint16 dev_id, uint8 rev_id) 6116 { 6117 char *config_str, *sub_str, *sub_str_end; 6118 static const char str_2p5[] = "2.5"; 6119 char str_buf[8]; 6120 soc_info_t *si; 6121 int i, rv; 6122 int num_port, num_phy_port; 6123 int port, phy_port; 6124 int port_bandwidth, port_active_lanes; 6125 int def_freq, max_freq; 6126 soc_100g_lane_config_t lane_config = SOC_LANE_CONFIG_100G_DEFAULT; 6127 int fallback_core = SOC_LANE_CONFIG_100G_DEFAULT; 6128 int index, tsc_id; 6129 char option_inactive, option_lanes; 6130 int port_count; 6131 int oversub_mode = 0; 6132 soc_pbmp_t oversub_pbm; 6133 soc_pbmp_t xe_pbmp; 6134 uint32 tsc_map, force_hg; 6135 int freq_list_len; 6136 int const *freq_list; 6137 static const int apache_freq_list[] = { 841, 793, 575, 510, 435 }; 6138 int int_ports[3][3] = { 6139 /* {log, phy, mmu} */ 6140 {0, 0, 72}, /* CPU */ 6141 {73, 73, 73}, /* LB */ 6142 {74, 74, 74}, /* RDB */ 6143 }; 6144 6145 SOC_PBMP_CLEAR(xe_pbmp); 6146 SOC_PBMP_CLEAR(oversub_pbm); 6147 xe_pbmp = soc_property_get_pbmp_default(unit, 6148 spn_PBMP_XPORT_XE, xe_pbmp); 6149 si = &SOC_INFO(unit); 6150 6151 { 6152 num_port = 72; 6153 num_phy_port = 72; 6154 } 6155 6156 SOC_IF_ERROR_RETURN(soc_apache_frequency_get(unit, &max_freq, &def_freq)); 6157 def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq); 6158 if (def_freq <= max_freq) { 6159 freq_list = apache_freq_list; 6160 freq_list_len = sizeof(apache_freq_list) / sizeof(int); 6161 for (index = 0; index < freq_list_len; index++) { 6162 if (def_freq == freq_list[index]) { 6163 break; 6164 } 6165 } 6166 6167 if (index < freq_list_len) { 6168 si->frequency = def_freq; 6169 } else { 6170 LOG_CLI((BSL_META_U(unit, 6171 "*** Input core clock frequency %dMHz is not " 6172 "supported!\n"), def_freq)); 6173 } 6174 } 6175 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6176 (BSL_META_U(unit, "Running core clock frequency %dMhz\n"), def_freq)); 6177 6178 /* Setup max I/O and core bandwidth */ 6179 switch (si->frequency) { 6180 case 841: 6181 si->io_bandwidth = 880000; 6182 si->bandwidth = 567000; 6183 break; 6184 case 793: 6185 si->io_bandwidth = 720000; 6186 si->bandwidth = 480000; 6187 break; 6188 case 575: 6189 /* LR Only */ 6190 si->io_bandwidth = 340000; 6191 si->bandwidth = 340000; 6192 break; 6193 case 435: 6194 /* LR Only */ 6195 si->io_bandwidth = 260000; 6196 si->bandwidth = 260000; 6197 break; 6198 case 510: 6199 /* si->bandwidth = 260000; */ 6200 LOG_CLI((BSL_META_U(unit, 6201 "*** Input core clock frequency %dMHz is not yet " 6202 "supported!\n"), si->frequency)); 6203 return SOC_E_INTERNAL; /* unknown frequency */ 6204 default: 6205 si->io_bandwidth = 720000; 6206 si->bandwidth = 480000; 6207 break; 6208 } 6209 6210 6211 si->oversub_mode = oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0); 6212 if (oversub_mode == 2) { 6213 oversub_pbm = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0); 6214 } 6215 6216 SOC_IF_ERROR_RETURN(soc_apache_tsc_map_get(unit, &tsc_map, &force_hg)); 6217 6218 /* Initialize the soc_info params */ 6219 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 6220 si->port_l2p_mapping[port] = -1; 6221 si->port_speed_max[port] = -1; 6222 si->port_group[port] = -1; 6223 si->port_serdes[port] = -1; 6224 si->port_num_lanes[port] = -1; 6225 6226 /* Indexed by physical port */ 6227 si->port_p2l_mapping[port] = -1; 6228 si->port_p2m_mapping[port] = -1; 6229 6230 /* Indexed by mmu port */ 6231 si->port_m2p_mapping[port] = -1; 6232 } 6233 6234 6235 6236 for (index = 0; index < COUNTOF(int_ports); index++) { 6237 /* int_ports is an array of log, phy & mmu ports in that order */ 6238 si->port_p2l_mapping[int_ports[index][1]] = int_ports[index][0]; 6239 si->port_p2m_mapping[int_ports[index][1]] = int_ports[index][2]; 6240 6241 SOC_PBMP_PORT_SET(si->xpipe_pbm, int_ports[index][0]); 6242 } 6243 6244 6245 SOC_PBMP_CLEAR(si->oversub_pbm); 6246 SOC_PBMP_CLEAR(si->management_pbm); 6247 SOC_PBMP_CLEAR(si->all.disabled_bitmap); 6248 6249 si->phy_port_base[0] = 1; /* First physical port */ 6250 si->mmu_port_base[0] = 0; /* First mmu port */ 6251 port_count = 0; 6252 6253 rv = SOC_E_NONE; 6254 for (port = 0; port <= num_port; port++) { 6255 6256 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 6257 if (config_str == NULL) { 6258 continue; 6259 } 6260 6261 /* 6262 * portmap.<port>=<physical port number>:<bandwidth in Gb>:[<num_lanes>]:[i] 6263 */ 6264 sub_str = config_str; 6265 6266 /* Parse physical port number */ 6267 phy_port = sal_ctoi(sub_str, &sub_str_end); 6268 if (sub_str == sub_str_end) { 6269 LOG_CLI((BSL_META_U(unit, 6270 "Port %d: Missing physical port information \"%s\"\n"), 6271 port, config_str)); 6272 rv = SOC_E_FAIL; 6273 continue; 6274 } 6275 6276 /* phy_port valid range [1..72] */ 6277 if (phy_port < 1 || phy_port > num_phy_port) { 6278 LOG_CLI((BSL_META_U(unit, 6279 "Port %d: Invalid physical port number %d\n"), 6280 port, phy_port)); 6281 rv = SOC_E_FAIL; 6282 continue; 6283 } 6284 6285 tsc_id = (phy_port - 1) / APACHE_PORTS_PER_TSC; 6286 if (!(tsc_map & (1 << tsc_id))) { 6287 LOG_CLI((BSL_META_U(unit, 6288 "Port %d: Physical port %d is in disabled TSC %d\n"), 6289 port, phy_port, tsc_id)); 6290 rv = SOC_E_FAIL; 6291 continue; 6292 } 6293 6294 if ((force_hg & (1 << tsc_id)) && 6295 (SOC_PBMP_MEMBER(xe_pbmp, port))) { 6296 LOG_CLI((BSL_META_U(unit, 6297 "Port %d: non-hg port in TSC(%d) which is hg-only\n"), 6298 port, tsc_id)); 6299 rv = SOC_E_FAIL; 6300 continue; 6301 } 6302 6303 if (si->port_p2l_mapping[phy_port] != -1) { 6304 LOG_CLI((BSL_META_U(unit, 6305 "Port %d: Physical port %d is used by port %d\n"), 6306 port, phy_port, si->port_p2l_mapping[phy_port])); 6307 rv = SOC_E_FAIL; 6308 continue; 6309 } 6310 6311 if (port_count > num_port) { 6312 LOG_CLI((BSL_META_U(unit, 6313 "Can not configure more than %d port\n"), num_port)); 6314 rv = SOC_E_FAIL; 6315 continue; 6316 } 6317 6318 /* Skip ':' between physical port number and bandwidth */ 6319 sub_str = sub_str_end; 6320 if (*sub_str != '\0') { 6321 if (*sub_str != ':') { 6322 LOG_CLI((BSL_META_U(unit, 6323 "Port %d: Bad config string \"%s\"\n"), 6324 port, config_str)); 6325 rv = SOC_E_FAIL; 6326 continue; 6327 } 6328 sub_str++; 6329 } 6330 6331 /* Parse bandwidth - special case 2.5G */ 6332 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 6333 if (sub_str[index] == '\0') { 6334 break; 6335 } 6336 str_buf[index] = sub_str[index]; 6337 } 6338 str_buf[index] = '\0'; 6339 6340 if (!sal_strcmp(str_buf, str_2p5)) { 6341 port_bandwidth = 2500; 6342 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 6343 } else { 6344 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 6345 if (sub_str == sub_str_end) { 6346 LOG_CLI((BSL_META_U(unit, 6347 "Port %d: Missing bandwidth " 6348 "information \"%s\"\n"), 6349 port, config_str)); 6350 rv = SOC_E_FAIL; 6351 continue; 6352 } 6353 } 6354 6355 /* Check if option presents */ 6356 option_inactive = option_lanes = 0; 6357 sub_str = sub_str_end; 6358 if (*sub_str != '\0') { 6359 /* Skip ':' between bandwidth and options */ 6360 if (*sub_str != ':') { 6361 LOG_CLI((BSL_META_U(unit, 6362 "Port %d: Bad config string \"%s\"\n"), 6363 port, config_str)); 6364 rv = SOC_E_FAIL; 6365 continue; 6366 } 6367 sub_str++; 6368 6369 /* Read 100G lane configuration if present. 6370 * Skip if options are present */ 6371 if (*sub_str != '\0') { 6372 if (*sub_str == 'i') { 6373 option_inactive = *sub_str; 6374 sub_str++; 6375 } else if ((port_bandwidth >= 100000) && 6376 ((phy_port == 17) || (phy_port == 53))) { 6377 6378 for (index = 0; index < 3; index++) { 6379 if (sub_str[index] == '\0') { 6380 break; 6381 } 6382 str_buf[index] = sub_str[index]; 6383 } 6384 str_buf[index] = '\0'; 6385 if (!sal_strcmp(str_buf, "442")) { 6386 lane_config = SOC_LANE_CONFIG_100G_4_4_2; 6387 } else if (!sal_strcmp(str_buf, "244")) { 6388 lane_config = SOC_LANE_CONFIG_100G_2_4_4; 6389 } else if (!sal_strcmp(str_buf, "343")) { 6390 lane_config = SOC_LANE_CONFIG_100G_3_4_3; 6391 } else { 6392 LOG_ERROR(BSL_LS_SOC_PORT, 6393 (BSL_META_U(unit, "Port %d: " 6394 "Bad config string \"%s\"\n"), 6395 port, str_buf)); 6396 rv = SOC_E_FAIL; 6397 continue; 6398 } 6399 sub_str_end = &sub_str[3]; /*Advance */ 6400 6401 /* Skip ':' between 100G lane config and 100G fallback port */ 6402 sub_str = sub_str_end; 6403 if (*sub_str != '\0') { 6404 if (*sub_str != ':') { 6405 LOG_ERROR(BSL_LS_SOC_PORT, 6406 (BSL_META_U(unit, "Port %d: " 6407 "Bad config string \"%s\"\n"), 6408 port, config_str)); 6409 rv = SOC_E_FAIL; 6410 continue; 6411 } 6412 sub_str_end++; 6413 } 6414 6415 sub_str = sub_str_end; 6416 /* Gather the desired fallback TSC for 100G auto-negotiation */ 6417 fallback_core = SOC_LANE_CONFIG_100G_AN_CORE_DEFAULT; 6418 if (*sub_str != '\0') { 6419 fallback_core = sal_ctoi(sub_str, &sub_str_end); 6420 if (fallback_core > 2 || fallback_core < 0) { 6421 LOG_ERROR(BSL_LS_SOC_PORT, 6422 (BSL_META_U(unit, "Port %d: " 6423 "Invalid default core \"%d\"\n"), 6424 port, fallback_core)); 6425 rv = SOC_E_FAIL; 6426 continue; 6427 } else { 6428 /* Validate that for a given lane configuration 6429 * the selected fallback core is valid. */ 6430 for (i = 0; soc_apache_valid_an_cores[i].lane_config != SOC_INVALID_LANE_CONFIG; i++) { 6431 if (soc_apache_valid_an_cores[i].lane_config == lane_config) { 6432 if (!soc_apache_valid_an_cores[i].valid_lanes[fallback_core]) { 6433 fallback_core = -1; 6434 break; 6435 } 6436 } 6437 } 6438 } 6439 6440 if (fallback_core < 0) { 6441 LOG_ERROR(BSL_LS_SOC_PORT, 6442 (BSL_META_U(unit, "Port %d: " 6443 "Invalid default lane \"%d\"\n"), 6444 port, fallback_core)); 6445 rv = SOC_E_FAIL; 6446 continue; 6447 } 6448 } 6449 } else if ((*sub_str == '1') || 6450 (*sub_str == '2') || 6451 (*sub_str == '4')) { 6452 option_lanes = *sub_str; 6453 sub_str++; 6454 6455 if (*sub_str != '\0') { 6456 if (*sub_str != 'i') { 6457 LOG_CLI((BSL_META_U(unit, 6458 "Port %d: Bad config string \"%s\"\n"), 6459 port, config_str)); 6460 rv = SOC_E_FAIL; 6461 continue; 6462 } 6463 option_inactive = *sub_str; 6464 sub_str++; 6465 } 6466 } else { 6467 LOG_CLI((BSL_META_U(unit, 6468 "Port %d: Bad config string \"%s\"\n"), 6469 port, config_str)); 6470 rv = SOC_E_FAIL; 6471 continue; 6472 } 6473 } 6474 } 6475 6476 /* Check trailing string */ 6477 if (*sub_str != '\0') { 6478 LOG_CLI((BSL_META_U(unit, 6479 "Port %d: Bad config string \"%s\"\n"), 6480 port, config_str)); 6481 rv = SOC_E_FAIL; 6482 continue; 6483 } 6484 6485 /* 6486 * Use new properties for 100GE mode lane and 6487 * fallback autoneg core if these are specified. 6488 */ 6489 if ((port_bandwidth >= 100000) && ((phy_port == 17) || (phy_port == 53))) { 6490 int an_core, mode_lane, found = 0; 6491 6492 if (SOC_SUCCESS(soc_apache_port_lane_config_get(unit, 6493 phy_port, 6494 &mode_lane, 6495 &found))) { 6496 if (found) { 6497 lane_config = mode_lane; 6498 } 6499 } 6500 if (SOC_SUCCESS(soc_apache_port_autoneg_core_get(unit, 6501 phy_port, 6502 &an_core, 6503 &found))) { 6504 if (found) { 6505 fallback_core = an_core; 6506 } 6507 } 6508 6509 } 6510 switch (option_lanes) { 6511 case '1': port_active_lanes = 1; break; 6512 case '2': port_active_lanes = 2; break; 6513 case '4': port_active_lanes = 4; break; 6514 default : 6515 if (SOC_FAILURE(_soc_apache_port_lanes_set(unit, phy_port, 6516 &port_active_lanes, 6517 port_bandwidth))) { 6518 rv = SOC_E_FAIL; 6519 } 6520 break; 6521 } 6522 if (option_inactive == 'i') { 6523 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 6524 port_active_lanes = -1; 6525 } 6526 6527 /* PORT bandwidth checks */ 6528 if ((soc_apache_port_is_2p5g_forced(unit, phy_port)) && 6529 (port_bandwidth > 2500)) { 6530 rv = SOC_E_FAIL; 6531 LOG_CLI((BSL_META_U(unit, 6532 "Port %d: Invalid bandwidth %d Gb\n" 6533 "Max bandwidth supported is 2.5G\n"), 6534 port, port_bandwidth / 1000)); 6535 6536 continue; 6537 } 6538 6539 if (!_soc_apache_port_speed_supported(unit, port, phy_port, 6540 port_active_lanes, port_bandwidth)) { 6541 rv = SOC_E_FAIL; 6542 continue; 6543 } 6544 6545 6546 /* Update soc_info */ 6547 si->port_p2l_mapping[phy_port] = port; 6548 si->port_l2p_mapping[port] = phy_port; 6549 si->port_speed_max[port] = port_bandwidth; 6550 si->port_100g_lane_config[port] = lane_config; 6551 si->port_fallback_lane[port] = fallback_core; 6552 si->port_num_lanes[port] = port_active_lanes; 6553 6554 if (SOC_PBMP_MEMBER(oversub_pbm,port) || (oversub_mode == 1)) { 6555 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 6556 } 6557 6558 port_count++; 6559 } 6560 6561 /* 6562 * Earlier SDK was restricting the mixed mode (LR + OS) to only FB5 SKUs and 6563 * the Maverick/Ranger2+ are expected to run either LR-only or OS-only port configs. 6564 * With the new port configs supported by SDK, this is no longer true. 6565 * We have a few configs in FB5 which are all OS and a few configs on 6566 * Maverick which have a mix of LR and OS ports. These checks are hence removed. 6567 */ 6568 6569 /* Legacy Flex config ":i" case detected, disabled ports in config */ 6570 if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all))) { 6571 si->flex_eligible = TRUE; 6572 } 6573 6574 if (port_count == 0) { 6575 #ifdef __KERNEL__ 6576 /* config.bcm is not parsed yet at the time 1st call of soc_attach 6577 in Kernel mode SDK. Shouldn't return error code. */ 6578 return SOC_E_NONE; 6579 #else 6580 if (SOC_CONTROL(unit)->soc_flags & SOC_F_ATTACHED) { /* not for PCID */ 6581 rv = SOC_E_FAIL; 6582 } 6583 #endif 6584 } 6585 6586 /* Bandwidth check for ports in each XLPORT/CLPORT block */ 6587 if (SOC_SUCCESS(rv)) { 6588 rv = soc_apache_port_config_bandwidth_check(unit); 6589 } 6590 6591 if (SOC_FAILURE(rv)) { 6592 for (phy_port = 1; phy_port < 72; phy_port++) { 6593 si->port_p2l_mapping[phy_port] = -1; 6594 } 6595 return rv; 6596 } 6597 6598 /* Setup port_group, num_lanes, xpipe_pbm */ 6599 for (port = 0; port <= num_port; port++) { 6600 phy_port = si->port_l2p_mapping[port]; 6601 if (phy_port == -1) { /* unused port */ 6602 continue; 6603 } 6604 /* 26 ports per PGW_CL */ 6605 si->port_group[port] = (phy_port - 1) / APACHE_PORTS_PER_PGW; 6606 si->port_serdes[port] = (phy_port - 1) / APACHE_PORTS_PER_TSC; 6607 6608 SOC_PBMP_PORT_ADD(si->xpipe_pbm, port); 6609 } 6610 SOC_PBMP_ASSIGN(si->pipe_pbm[0], si->xpipe_pbm); 6611 6612 #ifdef BCM_WARM_BOOT_SUPPORT 6613 if (SOC_WARM_BOOT(unit)) { 6614 rv = soc_apache_flexport_scache_recovery(unit); 6615 if (SOC_FAILURE(rv)) { 6616 if (rv == SOC_E_NOT_FOUND) { 6617 rv = SOC_E_NONE; 6618 } else { 6619 return rv; 6620 } 6621 } 6622 } else { 6623 /* Cold boot create */ 6624 SOC_IF_ERROR_RETURN(soc_apache_flexport_scache_allocate(unit)); 6625 } 6626 #endif /* BCM_WARM_BOOT_SUPPORT */ 6627 6628 /* Assign mmu ports for all active and inactive ports */ 6629 SOC_IF_ERROR_RETURN(soc_apache_mmu_ports_assign(unit)); 6630 6631 if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) { 6632 LOG_CLI((BSL_META_U(unit, "physical to logical mapping:"))); 6633 for (index = 0; index < num_phy_port; index++) { 6634 if (index % 16 == 0) { 6635 LOG_CLI((BSL_META_U(unit, "\n "))); 6636 } 6637 LOG_CLI((BSL_META_U(unit, " %3d"), 6638 si->port_p2l_mapping[index])); 6639 } 6640 LOG_CLI((BSL_META_U(unit, "\n"))); 6641 LOG_CLI((BSL_META_U(unit, "physical port bandwidth:"))); 6642 for (index = 0; index < num_phy_port; index++) { 6643 if (index % 16 == 0) { 6644 LOG_CLI((BSL_META_U(unit, "\n "))); 6645 } 6646 port = si->port_p2l_mapping[index]; 6647 if (port == -1) { 6648 LOG_CLI((BSL_META_U(unit, " -1"))); 6649 } else if (si->port_speed_max[port] == 2500) { 6650 LOG_CLI((BSL_META_U(unit, " 2.5"))); 6651 } else { 6652 LOG_CLI((BSL_META_U(unit, " %3d"), 6653 si->port_speed_max[port] / 1000)); 6654 } 6655 } 6656 LOG_CLI((BSL_META_U(unit, "\n"))); 6657 LOG_CLI((BSL_META_U(unit, "physical to mmu mapping:"))); 6658 for (index = 0; index < num_phy_port; index++) { 6659 if (index % 16 == 0) { 6660 LOG_CLI((BSL_META_U(unit, "\n "))); 6661 } 6662 LOG_CLI((BSL_META_U(unit, " %3d"), 6663 si->port_p2m_mapping[index])); 6664 } 6665 LOG_CLI((BSL_META_U(unit, "\n"))); 6666 } 6667 6668 SOC_IF_ERROR_RETURN(soc_ap_phy_info_init(unit)); 6669 /* update port_init_speed array for all ports */ 6670 SOC_IF_ERROR_RETURN(_soc_ap_ports_speed_init_update(unit)); 6671 SOC_IF_ERROR_RETURN(soc_ap_port_ovs_speed_group_validate(unit)); 6672 SOC_IF_ERROR_RETURN(soc_ap_port_mixed_sister_speed_validate(unit)); 6673 6674 return SOC_E_NONE; 6675 } 6676 6677 soc_error_t 6678 soc_apache_port_reg_blk_index_get(int unit, int port, soc_block_type_t blktype, int *block) 6679 { 6680 uint16 dev_id; 6681 uint8 rev_id; 6682 int phy_port; 6683 6684 soc_cm_get_id(unit, &dev_id, &rev_id); 6685 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 6686 6687 switch (blktype) { 6688 case SOC_BLK_CLG2PORT: 6689 case SOC_BLK_CLPORT: 6690 if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit, port)) { 6691 if (phy_port == 17) { 6692 *block = (rev_id == BCM56560_A0_REV_ID ? 11 : 7); 6693 } else if (phy_port == 53) { 6694 *block = (rev_id == BCM56560_A0_REV_ID ? 14 : 8); 6695 } else { 6696 return SOC_E_PARAM; 6697 } 6698 } 6699 break; 6700 case SOC_BLK_CXXPORT: 6701 if ((phy_port >= 17) && (phy_port <= 28)) { 6702 *block = (rev_id == BCM56560_A0_REV_ID ? 18 : 10); 6703 } else if ((phy_port >= 53) && (phy_port <= 64)) { 6704 *block = (rev_id == BCM56560_A0_REV_ID ? 19 : 11); 6705 } else { 6706 return SOC_E_PARAM; 6707 } 6708 break; 6709 default: 6710 break; 6711 } 6712 return SOC_E_NONE; 6713 } 6714 6715 int 6716 soc_apache_lls_bmap_alloc(int unit) 6717 { 6718 soc_control_t *soc; 6719 int port; 6720 int alloc_size_s1, alloc_size_l0, alloc_size_l1, alloc_size_l2; 6721 6722 soc = SOC_CONTROL(unit); 6723 6724 alloc_size_s1 = 6725 SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_S1_PARENTm)); 6726 alloc_size_l0 = 6727 SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L0_PARENTm)); 6728 alloc_size_l1 = 6729 SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L1_PARENTm)); 6730 alloc_size_l2 = 6731 SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L2_PARENTm)); 6732 6733 for (port = 0; port < APACHE_PORTS_PER_PIPE + 2; port++) { 6734 soc->port_lls_s1_bmap[port] = sal_alloc(alloc_size_s1, "LLS_S1_BMAP"); 6735 if (soc->port_lls_s1_bmap[port] == NULL) { 6736 return SOC_E_MEMORY; 6737 } 6738 soc->port_lls_l0_bmap[port] = sal_alloc(alloc_size_l0, "LLS_L0_BMAP"); 6739 if (soc->port_lls_l0_bmap[port] == NULL) { 6740 return SOC_E_MEMORY; 6741 } 6742 6743 soc->port_lls_l1_bmap[port] = sal_alloc(alloc_size_l1, "LLS_L1_BMAP"); 6744 if (soc->port_lls_l1_bmap[port] == NULL) { 6745 return SOC_E_MEMORY; 6746 } 6747 soc->port_lls_l2_bmap[port] = sal_alloc(alloc_size_l2, "LLS_L2_BMAP"); 6748 if (soc->port_lls_l2_bmap[port] == NULL) { 6749 return SOC_E_MEMORY; 6750 } 6751 sal_memset(soc->port_lls_s1_bmap[port], 0, alloc_size_s1); 6752 sal_memset(soc->port_lls_l0_bmap[port], 0, alloc_size_l0); 6753 sal_memset(soc->port_lls_l1_bmap[port], 0, alloc_size_l1); 6754 sal_memset(soc->port_lls_l2_bmap[port], 0, alloc_size_l2); 6755 } 6756 6757 return SOC_E_NONE; 6758 } 6759 6760 #define _SOC_AP_DEF_TEMP_MAX 130 6761 6762 static uint32 _soc_ap_temp_mon_mask[SOC_MAX_NUM_DEVICES]; 6763 6764 6765 /* 6766 * Function: soc_apache_tsc_disable 6767 * 6768 * Purpose: 6769 * Function to enable/disable used/unused TSCs in the chip. 6770 */ 6771 int 6772 soc_apache_tsc_disable(int unit) 6773 { 6774 soc_info_t *si = &SOC_INFO(unit); 6775 uint32 tsc_enable = 0; 6776 int lane, phy_port, tsc, port; 6777 6778 for (phy_port = 1; 6779 phy_port <= APACHE_PORTS_PER_PIPE; 6780 phy_port = (phy_port + APACHE_PORTS_PER_TSC)) { 6781 6782 tsc = (phy_port - 1) / APACHE_PORTS_PER_TSC; 6783 for (lane = 0; lane < APACHE_PORTS_PER_TSC; lane++) { 6784 port = si->port_p2l_mapping[phy_port + lane]; 6785 if (port != -1) { 6786 tsc_enable |= (1 << tsc); 6787 if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit,port)) { 6788 tsc_enable |= (1 << (tsc + 1)); 6789 tsc_enable |= (1 << (tsc + 2)); 6790 } 6791 break; 6792 } 6793 } 6794 } 6795 6796 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, TOP_TSC_ENABLEr, 6797 REG_PORT_ANY, 0, tsc_enable)); 6798 6799 return SOC_E_NONE; 6800 } 6801 6802 6803 void 6804 soc_apache_sbus_ring_map_config(int unit) 6805 { 6806 uint16 dev_id; 6807 uint8 rev_id; 6808 6809 /* 6810 * SBUS Ring # Start Through Blocks End 6811 * 0 CMIC IP CMIC 6812 * 1 CMIC EP CMIC 6813 * 2 CMIC MMU CMIC 6814 * 3 CMIC TSC0 - TSC1 - TSC2 - TSC3 - PGW0 - TSC4_5_6 - TSC7 - TSC8 CMIC 6815 * 4 CMIC TSC9 - TSC10 - TSC11 - TSC12 - PGW1 - TSC13_14_15 - TSC16 - TSC17 CMIC 6816 * 5 CMIC TOP REGISTERS - OTPC - AVS - SER CMIC 6817 * 6 CMIC RDB CMIC 6818 * 7 CMIC Not used CMIC 6819 */ 6820 6821 WRITE_CMIC_SBUS_RING_MAP_0_7r(unit, 0x43052100); 6822 WRITE_CMIC_SBUS_RING_MAP_8_15r(unit, 0x33333333); 6823 WRITE_CMIC_SBUS_RING_MAP_16_23r(unit, 0x44444333); 6824 WRITE_CMIC_SBUS_RING_MAP_24_31r(unit, 0x50444444); 6825 WRITE_CMIC_SBUS_RING_MAP_32_39r(unit, 0x00060555); 6826 WRITE_CMIC_SBUS_RING_MAP_40_47r(unit, 0x00000000); 6827 WRITE_CMIC_SBUS_RING_MAP_48_55r(unit, 0x00000000); 6828 WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x00000000); 6829 6830 6831 soc_cm_get_id(unit, &dev_id, &rev_id); 6832 6833 if (rev_id == BCM56560_A0_REV_ID) { 6834 WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x1000); 6835 } else { 6836 WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x7d0); 6837 } 6838 6839 return; 6840 } 6841 6842 6843 /* OVST toggle data */ 6844 static uint32 ovst_write_data[] = { 6845 0x3fffff40, 0xbffffbfe, 0x31fc9e80, 0xbffffbfe, 6846 0x40000000, 0x44000000, 0x40000000, 0x40000000, 6847 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6848 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6849 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6850 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6851 0x40000000, 0x40000000, 0x40000000, 0x80000300, 6852 0x31fc9e80, 0xbffffbfe, 0x40000000, 0x44000000, 6853 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6854 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6855 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6856 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6857 0x40000000, 0x42000000, 0x40000000, 0x40000000, 6858 0x40000000, 0x80000300, 0x31fc9e80, 0xbffffbfe, 6859 0x40000000, 0x44000000, 0x40000000, 0x40000000, 6860 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6861 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6862 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6863 0x40000000, 0x40000000, 0x40000000, 0x40000000, 6864 0x40000000, 0x40000000, 0x40000000, 0x80000300 6865 }; 6866 6867 6868 /* 6869 * Function: 6870 * apache_ovstb_toggle 6871 * Purpose: 6872 * Execute the OVST sequence for Apache devces 6873 * Parameters: 6874 * unit - StrataSwitch unit # 6875 */ 6876 STATIC void 6877 apache_ovstb_toggle(int unit) 6878 { 6879 int ix; 6880 int array_length; 6881 uint32 read_data = 0; 6882 6883 /* OVST toggle sequence needs to be run only for Apache A0/B0 parts */ 6884 if (!soc_feature(unit, soc_feature_apache_ovst_toggle)) { 6885 return; 6886 } 6887 6888 array_length = sizeof(ovst_write_data) / sizeof(uint32); 6889 6890 /* Enable UC_TAP write */ 6891 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2e); 6892 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2e); 6893 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2f); 6894 READ_TOP_UC_TAP_CONTROLr(unit, &read_data); 6895 6896 /* OVST toggle write data */ 6897 for (ix = 0; ix < array_length; ix++) { 6898 WRITE_TOP_UC_TAP_WRITE_DATAr(unit, ovst_write_data[ix]); 6899 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2f); 6900 6901 READ_TOP_UC_TAP_READ_DATAr(unit, &read_data); 6902 /* 6903 * Hardware requires about 4us spacing between two SBUS writes. 6904 * A single shift instruction requires a data write of 54 bits that is 6905 * split into two sbus writes. Using uninterruptible sleep. 6906 */ 6907 sal_udelay(4); 6908 } 6909 6910 /* Disable UC_TAP write */ 6911 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2f); 6912 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2e); 6913 WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2c); 6914 6915 return; 6916 } 6917 6918 6919 6920 6921 int 6922 soc_apache_chip_reset(int unit) 6923 { 6924 soc_info_t *si; 6925 uint16 dev_id; 6926 uint8 rev_id; 6927 int max_frequency, def_freq; 6928 uint32 rval, to_usec; 6929 soc_reg_t reg; 6930 int index; 6931 int shared_bank_offset = 0; 6932 int num_shared_l2_banks, num_shared_l3_banks, num_banks; 6933 int shared_bank; 6934 uint32 config = 0, map = 0; 6935 int num_ecmp_rh_flowset_entries; 6936 int rh_table_config_encoding; 6937 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 6938 int num_overlay_ecmp_rh_flowset_entries; 6939 int rh_bank_sel = 0x0; 6940 int ecmp_levels = 1; 6941 #endif 6942 static soc_field_t l2_fields[] = { 6943 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 6944 L2_ENTRY_BANK_5f 6945 }; 6946 static soc_field_t l3_fields[] = { 6947 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 6948 L3_ENTRY_BANK_7f 6949 }; 6950 6951 int temp_mask, temp_thr; 6952 static const soc_reg_t temp_thr_reg[] = { 6953 TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr, 6954 TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr, 6955 TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr, 6956 TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr 6957 }; 6958 static const char *temp_thr_prop[] = { 6959 "temp0_threshold", "temp1_threshold", "temp2_threshold", 6960 "temp3_threshold", "temp4_threshold", "temp5_threshold", 6961 "temp6_threshold", "temp7_threshold" 6962 }; 6963 int freq_list_len, sel; 6964 int const *freq_list; 6965 static const int apache_freq_list[] = { 841, 793, 575, 510, 435 }; 6966 6967 #if 0 6968 static const soc_reg_t lcpll_ctrl1_reg[] = { 6969 TOP_XG_PLL0_CTRL_1r, TOP_XG_PLL1_CTRL_1r, 6970 TOP_XG_PLL2_CTRL_1r, TOP_XG_PLL3_CTRL_1r, 6971 }; 6972 static const soc_reg_t lcpll_ctrl3_reg[] = { 6973 TOP_XG_PLL0_CTRL_3r, TOP_XG_PLL1_CTRL_3r, 6974 TOP_XG_PLL2_CTRL_3r, TOP_XG_PLL3_CTRL_3r 6975 }; 6976 static const soc_reg_t lcpll_ctrl4_reg[] = { 6977 TOP_XG_PLL0_CTRL_4r, TOP_XG_PLL1_CTRL_4r, 6978 TOP_XG_PLL2_CTRL_4r, TOP_XG_PLL3_CTRL_4r 6979 }; 6980 #endif 6981 static const soc_reg_t lcpll_status_reg[] = { 6982 TOP_XG_PLL0_STATUSr, TOP_XG_PLL1_STATUSr, 6983 TOP_XG_PLL2_STATUSr, TOP_XG_PLL3_STATUSr 6984 }; 6985 6986 /* Settings for 500 MHz TSPLL output clock. */ 6987 unsigned ts_ref_freq = 0; 6988 unsigned ts_idx = 0; 6989 6990 static const soc_pll_param_t ts_pll[] = { 6991 /* Fref, Ndiv_int, Ndiv_frac, Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */ 6992 {12800000, 273, 0x70000, 1, 7, 0, 2, 3, 1}, /* Ndiv = 273.4375 */ 6993 {20000000, 175, 0, 1, 7, 0, 2, 3, 1}, /* Ndiv = 175.0 */ 6994 {25000000, 140, 0, 1, 7, 0, 2, 3, 1}, /* Ndiv = 140.0 */ 6995 {32000000, 109, 0x60000, 1, 7, 0, 2, 3, 1}, /* Ndiv = 109.375 */ 6996 {50000000, 70, 0, 1, 7, 0, 2, 3, 1}, /* Ndiv = 70.0 */ 6997 { 0, 140, 0, 1, 7, 0, 2, 3, 1} /* 25 MHz, from internal reference. */ 6998 }; 6999 7000 /* Settings for 20 MHz BSPLL output clock. */ 7001 unsigned bs_ref_freq = 0; 7002 unsigned bs_idx = 0; 7003 uint32 bs_ndiv_high, bs_ndiv_low; 7004 7005 static const soc_pll_param_t bs_pll[] = { 7006 /* Fref, Ndiv_int, Ndiv_frac, Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */ 7007 {12800000, 273, 0x70000000, 1, 175, 0, 2, 3, 1}, 7008 {20000000, 175, 0, 1, 175, 0, 2, 3, 1}, 7009 {25000000, 140, 0, 1, 175, 0, 2, 3, 1}, 7010 {32000000, 109, 0x60000000, 1, 175, 0, 2, 3, 1}, 7011 {50000000, 70, 0, 1, 175, 0, 2, 3, 1}, 7012 { 0, 140, 0, 1, 175, 0, 2, 3, 1} /* 25 MHz, from internal reference. */ 7013 }; 7014 7015 7016 si = &SOC_INFO(unit); 7017 7018 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 7019 (10 * MILLISECOND_USEC); 7020 7021 /* Reset all mHost processors */ 7022 SOC_IF_ERROR_RETURN(WRITE_MHOST_0_CR5_RST_CTRLr(unit, 0)); 7023 SOC_IF_ERROR_RETURN(WRITE_MHOST_1_CR5_RST_CTRLr(unit, 0)); 7024 7025 soc_apache_sbus_ring_map_config(unit); 7026 7027 /*Reset the common UARTs */ 7028 SOC_IF_ERROR_RETURN(WRITE_CHIPCOMMONG_UART0_UART_SRRr(unit, 1)); 7029 SOC_IF_ERROR_RETURN(WRITE_CHIPCOMMONG_UART1_UART_SRRr(unit, 1)); 7030 7031 /* Wait for AXI bus to clean up */ 7032 sal_usleep(50 * MILLISECOND_USEC); 7033 7034 /* Bring the mHosts out of reset but leave the ARM cores in Halt, As 7035 * some reg accesses could cause PCI bus error while mHost is in reset 7036 */ 7037 SOC_IF_ERROR_RETURN(WRITE_MHOST_0_CR5_RST_CTRLr(unit, 0xf)); 7038 SOC_IF_ERROR_RETURN(WRITE_MHOST_1_CR5_RST_CTRLr(unit, 0xf)); 7039 7040 sal_usleep(to_usec); 7041 7042 apache_ovstb_toggle(unit); 7043 7044 soc_cm_get_id(unit, &dev_id, &rev_id); 7045 7046 SOC_IF_ERROR_RETURN(soc_apache_frequency_get(unit, &max_frequency, &def_freq)); 7047 freq_list = apache_freq_list; 7048 freq_list_len = sizeof(apache_freq_list) / sizeof(int); 7049 if (si->frequency != def_freq) { 7050 for (sel = 0; sel < freq_list_len; sel++) { 7051 if (si->frequency == freq_list[sel]) { 7052 break; 7053 } 7054 } 7055 7056 LOG_CLI((BSL_META_U(unit, 7057 "*** change CORE_CLK_FREQ_SEL to %d\n"), sel)); 7058 LOG_CLI((BSL_META_U(unit, 7059 "*** change core clock frequency to %dMHz\n"), 7060 si->frequency)); 7061 7062 SOC_IF_ERROR_RETURN(READ_TOP_CORE_CLK_FREQ_SELr(unit, &rval)); 7063 soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval, 7064 SW_CORE_CLK_SEL_ENf, 1); 7065 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval)); 7066 soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval, 7067 CORE_CLK_FREQ_SELf, sel); 7068 SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval)); 7069 7070 sal_usleep(to_usec); 7071 } 7072 7073 7074 7075 /* 7076 * For TD2+ and TD+ compatible packages where there is no 1.25V supply in the package, 7077 * ams_pll_drv_hv_disable needs to be set to 1. 7078 * 7079 * ams_pll_drv_hv_disable: This is the main TX driver mode for Falcon, and is properly enabled 7080 * when TVDD1P25 = 1.25V, and tx_drv_hv_disable is set to its default value, "0". 7081 * To prevent damage to the output driver, this bit must always be "0" if TVDD1P25 = 1.25V 7082 */ 7083 if (soc_feature(unit, soc_feature_untethered_otp)) { 7084 int pkg_50mm; 7085 7086 pkg_50mm = (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureApachePkg50mmTDpCompat) || 7087 SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureApachePkg50mmTD2pCompat)); 7088 7089 pkg_50mm |= (SOC_BOND_INFO(unit)->dev_id == BCM56765_DEVICE_ID); 7090 7091 if (pkg_50mm) { 7092 7093 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_MISC_CONTROLr, 7094 REG_PORT_ANY, FALCON_TX_DRV_HV_DISABLEf, 1)); 7095 } 7096 } 7097 7098 /* Put TS, BS PLLs to reset before changing PLL control registers */ 7099 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 7100 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7101 TOP_TS_PLL_RST_Lf, 0); 7102 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7103 TOP_BS_PLL0_RST_Lf, 0); 7104 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7105 TOP_BS_PLL1_RST_Lf, 0); 7106 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7107 TOP_TS_PLL_POST_RST_Lf, 0); 7108 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7109 TOP_BS_PLL0_POST_RST_Lf, 0); 7110 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7111 TOP_BS_PLL1_POST_RST_Lf, 0); 7112 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 7113 7114 rval = 0; 7115 7116 /* Configure TS PLL */ 7117 ts_ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0); /* 0->internal reference */ 7118 7119 for (ts_idx = 0; ts_idx < sizeof(ts_pll)/sizeof(ts_pll[0]); ++ts_idx) { 7120 if (ts_pll[ts_idx].ref_freq == ts_ref_freq) { 7121 break; 7122 } 7123 } 7124 if (ts_idx == sizeof(ts_pll)/sizeof(ts_pll[0])) { 7125 /* Valid configuration lookup failed. Use internal reference. */ 7126 ts_idx = 5; 7127 ts_ref_freq = 0; 7128 } 7129 7130 /* Do not change PLL settings for internal reference */ 7131 if(ts_ref_freq) { 7132 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit, &rval)); 7133 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, FREF_SELf, (ts_ref_freq != 0)); 7134 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_1r(unit, rval)); 7135 7136 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit,&rval)); 7137 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, PDIVf, 7138 soc_property_get(unit, spn_PTP_TS_PLL_PDIV, ts_pll[ts_idx].pdiv)); 7139 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, CH0_MDIVf, 7140 soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, ts_pll[ts_idx].mdiv)); 7141 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_3r(unit, rval)); 7142 7143 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval)); 7144 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_INTf, 7145 soc_property_get(unit, spn_PTP_TS_PLL_N, ts_pll[ts_idx].ndiv_int)); 7146 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_FRACf, ts_pll[ts_idx].ndiv_frac); 7147 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_4r(unit, rval)); 7148 7149 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_5r(unit,&rval)); 7150 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KAf, 7151 soc_property_get(unit, spn_PTP_TS_KA, ts_pll[ts_idx].ka)); 7152 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KIf, 7153 soc_property_get(unit, spn_PTP_TS_KI, ts_pll[ts_idx].ki)); 7154 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KPf, 7155 soc_property_get(unit, spn_PTP_TS_KP, ts_pll[ts_idx].kp)); 7156 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_5r(unit, rval)); 7157 } 7158 7159 /* Set 250Mhz (implies 4ns resolution) default timesync clock to 7160 calculate assymentric delays */ 7161 SOC_TIMESYNC_PLL_CLOCK_NS(unit) = (1/250 * 1000); /* clock period in nanoseconds */ 7162 7163 /* Configure BroadSync PLLs. */ 7164 bs_ref_freq = soc_property_get(unit, spn_PTP_BS_FREF, 0); /* 0->internal reference */ 7165 7166 for (bs_idx = 0; bs_idx < sizeof(bs_pll)/sizeof(bs_pll[0]); ++bs_idx) { 7167 if (bs_pll[bs_idx].ref_freq == bs_ref_freq) { 7168 break; 7169 } 7170 } 7171 if (bs_idx == sizeof(bs_pll)/sizeof(bs_pll[0])) { 7172 /* Valid configuration lookup failed. Use internal reference. */ 7173 bs_idx = 5; 7174 bs_ref_freq = 0; 7175 } 7176 7177 if (bs_ref_freq) { 7178 /* PLL settings for external reference */ 7179 7180 bs_ndiv_high = ((soc_property_get(unit, spn_PTP_BS_NDIV_INT, 7181 bs_pll[bs_idx].ndiv_int) << 6) | 7182 ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC, 7183 bs_pll[bs_idx].ndiv_frac) >> 26) & 0x3f)); 7184 bs_ndiv_low = ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC, 7185 bs_pll[bs_idx].ndiv_frac) << 6) & 0xffffc000); 7186 7187 /* Configure BS PLL0 */ 7188 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_1r(unit, &rval)); 7189 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0)); 7190 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_1r(unit, rval)); 7191 7192 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval)); 7193 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, PDIVf, 7194 soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv)); 7195 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, CH0_MDIVf, 7196 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 7197 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval)); 7198 7199 /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */ 7200 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_5r(unit,&rval)); 7201 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low); 7202 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_5r(unit, rval)); 7203 7204 /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */ 7205 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_6r(unit,&rval)); 7206 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high); 7207 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_6r(unit, rval)); 7208 7209 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_4r(unit, &rval)); 7210 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KAf, 7211 soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka)); 7212 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KIf, 7213 soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki)); 7214 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KPf, 7215 soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp)); 7216 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_4r(unit, rval)); 7217 7218 /* Configure BS PLL1 */ 7219 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_1r(unit, &rval)); 7220 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0)); 7221 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_1r(unit, rval)); 7222 7223 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval)); 7224 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, PDIVf, 7225 soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv)); 7226 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, CH0_MDIVf, 7227 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 7228 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval)); 7229 7230 /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */ 7231 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_5r(unit,&rval)); 7232 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low); 7233 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_5r(unit, rval)); 7234 7235 /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */ 7236 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_6r(unit,&rval)); 7237 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high); 7238 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_6r(unit, rval)); 7239 7240 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_4r(unit, &rval)); 7241 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KAf, 7242 soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka)); 7243 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KIf, 7244 soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki)); 7245 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KPf, 7246 soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp)); 7247 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_4r(unit, rval)); 7248 } else { 7249 /* PLL settings for internal reference are retained to default except for MDIV */ 7250 7251 /* BS PLLs Fout by default is 14MHz. Adjust MDIV to make it as 20MHz */ 7252 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval)); 7253 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, CH0_MDIVf, 7254 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 7255 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval)); 7256 7257 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval)); 7258 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, CH0_MDIVf, 7259 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 7260 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval)); 7261 } 7262 7263 /* Bring LCPLL, time sync PLL, BroadSync PLL out of reset */ 7264 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 7265 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 7266 1); 7267 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf, 7268 1); 7269 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf, 7270 1); 7271 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PMB_RST_Lf, 1); 7272 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_ARS_RST_Lf, 1); 7273 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1); 7274 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 7275 7276 sal_usleep(to_usec); 7277 7278 if (!SAL_BOOT_SIMULATION) { 7279 /* Check LCPLL lock status */ 7280 for (index = 0; index < 4; index++) { 7281 reg = lcpll_status_reg[index]; 7282 SOC_IF_ERROR_RETURN 7283 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 7284 if (!soc_reg_field_get(unit, reg, rval, TOP_XGPLL_LOCKf)) { 7285 LOG_ERROR(BSL_LS_SOC_COMMON, 7286 (BSL_META_U(unit, "LCPLL %d not locked on unit %d " 7287 "status = 0x%08x\n"), index, unit, rval)); 7288 } 7289 } 7290 /* Check time sync lock status */ 7291 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_STATUSr(unit, &rval)); 7292 if (!soc_reg_field_get(unit, TOP_TS_PLL_STATUSr, rval, PLL_LOCKf)) { 7293 LOG_ERROR(BSL_LS_SOC_COMMON, 7294 (BSL_META_U(unit, "TS_PLL not locked on unit %d " 7295 "status = 0x%08x\n"), unit, rval)); 7296 } 7297 7298 /* Check BroadSync lock status */ 7299 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_STATUSr(unit, &rval)); 7300 if (!soc_reg_field_get(unit, TOP_BS_PLL0_STATUSr, rval, PLL_LOCKf)) { 7301 LOG_ERROR(BSL_LS_SOC_COMMON, 7302 (BSL_META_U(unit, "BS_PLL0 not locked on unit %d " 7303 "status = 0x%08x\n"), unit, rval)); 7304 } 7305 7306 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_STATUSr(unit, &rval)); 7307 if (!soc_reg_field_get(unit, TOP_BS_PLL1_STATUSr, rval, PLL_LOCKf)) { 7308 LOG_ERROR(BSL_LS_SOC_COMMON, 7309 (BSL_META_U(unit, "BS_PLL1 not locked on unit %d " 7310 "status = 0x%08x\n"), unit, rval)); 7311 } 7312 } 7313 7314 /* De-assert LCPLL's post reset */ 7315 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 7316 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7317 TOP_TS_PLL_POST_RST_Lf, 1); 7318 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7319 TOP_BS_PLL0_POST_RST_Lf, 1); 7320 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7321 TOP_BS_PLL1_POST_RST_Lf, 1); 7322 7323 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 7324 TOP_PVT_MON_MIN_RST_Lf, 1); 7325 7326 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 7327 7328 sal_usleep(to_usec); 7329 7330 /* Set correct value for BG_ADJ */ 7331 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_0r(unit, &rval)); 7332 soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, BG_ADJf, 0); 7333 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_0r(unit, rval)); 7334 7335 /* Enable high temperature interrupt monitoring. 7336 * Default on: pvtmon6 (close to core_plls at center of die). 7337 */ 7338 temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<6); 7339 /* The above is a 9 bit mask to indicate which temp sensor to hook up to 7340 * the interrupt. 7341 */ 7342 rval = 0; 7343 for (index = 0; index <COUNTOF(temp_thr_reg); index++) { 7344 uint32 trval; 7345 7346 /* data = 410.04-(temp/0.48705) = (410040-(temp*1000))/487 7347 * Note: Since this is a high temp value we can safely assume it to 7348 * always be a +ive number. This is in degrees celcius. 7349 */ 7350 temp_thr = soc_property_get(unit, temp_thr_prop[index], _SOC_AP_DEF_TEMP_MAX); 7351 if (temp_thr > 410) { 7352 LOG_ERROR(BSL_LS_SOC_COMMON, 7353 (BSL_META_U(unit, 7354 "Unsupported temp value %d !! Max 410. Using %d.\n"), 7355 temp_thr, _SOC_AP_DEF_TEMP_MAX)); 7356 temp_thr = _SOC_AP_DEF_TEMP_MAX; 7357 } 7358 /* Convert temperature to config data */ 7359 temp_thr = (410040-(temp_thr*1000))/487; 7360 SOC_IF_ERROR_RETURN 7361 (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval)); 7362 soc_reg_field_set(unit, temp_thr_reg[index], &trval, MAX_THRESHOLDf, 7363 temp_thr); 7364 SOC_IF_ERROR_RETURN 7365 (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval)); 7366 if (temp_mask & (1 << index)) { 7367 rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */ 7368 } 7369 } 7370 _soc_ap_temp_mon_mask[unit] = temp_mask; 7371 7372 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_MASKr(unit, rval)); 7373 /* Enable temp mon interrupt */ 7374 (void)soc_cmicm_intr3_enable(unit, 0x4); /* PVTMON_INTR bit 2 */ 7375 7376 /* Bring port blocks out of reset */ 7377 rval = 0; 7378 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 1); 7379 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 1); 7380 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1); 7381 WRITE_TOP_SOFT_RESET_REGr(unit, rval); 7382 7383 sal_usleep(to_usec); 7384 7385 /* Bring IP, EP, and MMU blocks out of reset */ 7386 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 7387 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_RDB_RST_Lf, 1); 7388 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 7389 7390 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1); 7391 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1); 7392 7393 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 7394 7395 sal_usleep(to_usec); 7396 7397 /* Bring PMs out of reset */ 7398 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_3r(unit, &rval)); 7399 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM0_RST_Lf, 1); 7400 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM1_RST_Lf, 1); 7401 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM2_RST_Lf, 1); 7402 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM3_RST_Lf, 1); 7403 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM4_RST_Lf, 1); 7404 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM5_RST_Lf, 1); 7405 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM6_RST_Lf, 1); 7406 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM7_RST_Lf, 1); 7407 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM8_RST_Lf, 1); 7408 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM9_RST_Lf, 1); 7409 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM10_RST_Lf, 1); 7410 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM11_RST_Lf, 1); 7411 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM12_RST_Lf, 1); 7412 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM13_RST_Lf, 1); 7413 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, rval)); 7414 7415 sal_usleep(to_usec); 7416 7417 SOC_IF_ERROR_RETURN 7418 (soc_apache_hash_bank_count_get(unit, L2Xm, &num_banks)); 7419 num_shared_l2_banks = num_banks - 2; /* minus 2 dedicated L2 banks */ 7420 SOC_IF_ERROR_RETURN 7421 (soc_apache_hash_bank_count_get(unit, L3_ENTRY_ONLYm, &num_banks)); 7422 num_shared_l3_banks = num_banks - 4; /* minus 4 dedicated L3 banks */ 7423 7424 if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 7425 int non_alpm = num_shared_l3_banks + num_shared_l2_banks; 7426 if ((non_alpm) && (non_alpm <= 2)) { 7427 /* If Shared banks are used between ALPM and non-ALPM memories, 7428 * then ALPM uses Shared Bank B2, B3 and non-ALPM uses B4, B5 banks 7429 */ 7430 SOC_IF_ERROR_RETURN 7431 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 7432 REG_PORT_ANY, ALPM_BANK_MODEf, 1)); 7433 SOC_IF_ERROR_RETURN 7434 (soc_reg_field32_modify(unit, LPM_LOG_TO_PHY_BANK_MAPr, 7435 REG_PORT_ANY, ALPM_BANK_MODEf, 1)); 7436 SOC_IF_ERROR_RETURN 7437 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, 7438 REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0x3)); 7439 _soc_ap_num_shared_alpm_banks[unit] = 2; 7440 shared_bank_offset = 2; 7441 } else { 7442 SOC_IF_ERROR_RETURN 7443 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 7444 REG_PORT_ANY, ALPM_BANK_MODEf, 0)); 7445 SOC_IF_ERROR_RETURN 7446 (soc_reg_field32_modify(unit, LPM_LOG_TO_PHY_BANK_MAPr, 7447 REG_PORT_ANY, ALPM_BANK_MODEf, 0)); 7448 SOC_IF_ERROR_RETURN 7449 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, 7450 REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0xf)); 7451 _soc_ap_num_shared_alpm_banks[unit] = 4; 7452 } 7453 } 7454 7455 soc_reg_field_set(unit, L2_ISS_BANK_CONFIGr, &config, L2_ENTRY_BANK_CONFIGf, 7456 ((1 << num_shared_l2_banks) - 1) << shared_bank_offset); 7457 for (index = 0; index < num_shared_l2_banks; index++) { 7458 shared_bank = index + shared_bank_offset; 7459 soc_reg_field_set(unit, L2_ISS_LOG_TO_PHY_BANK_MAPr, &map, 7460 l2_fields[index], shared_bank); 7461 } 7462 SOC_IF_ERROR_RETURN 7463 (soc_reg32_set(unit, L2_ISS_BANK_CONFIGr, REG_PORT_ANY, 0, config)); 7464 SOC_IF_ERROR_RETURN 7465 (soc_reg32_set(unit, L2_ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, map)); 7466 7467 config = map = 0; 7468 shared_bank_offset += num_shared_l2_banks; 7469 7470 soc_reg_field_set(unit, L3_ISS_BANK_CONFIGr, &config, L3_ENTRY_BANK_CONFIGf, 7471 ((1 << num_shared_l3_banks) - 1) << shared_bank_offset); 7472 for (index = 0; index < num_shared_l3_banks; index++) { 7473 shared_bank = index + shared_bank_offset;; 7474 soc_reg_field_set(unit, L3_ISS_LOG_TO_PHY_BANK_MAPr, &map, 7475 l3_fields[index], shared_bank); 7476 } 7477 SOC_IF_ERROR_RETURN 7478 (soc_reg32_set(unit, L3_ISS_BANK_CONFIGr, REG_PORT_ANY, 0, config)); 7479 SOC_IF_ERROR_RETURN 7480 (soc_reg32_set(unit, L3_ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, map)); 7481 7482 /* SHARED_TABLE_HASH_CONTROLr.UFT_BANK_ENABLEf programming is redundant in 7483 * Apache (as in TH). If the PHY banks are not enabled for any of the LOG Tables, 7484 * the low power mode is implicit - i.e., no explicit bank_disable is reqd. */ 7485 7486 num_ecmp_rh_flowset_entries = soc_property_get(unit, 7487 spn_ECMP_RESILIENT_HASH_SIZE, 32768); 7488 switch (num_ecmp_rh_flowset_entries) { 7489 case 0: 7490 rh_table_config_encoding = 2; 7491 break; 7492 case 32768: 7493 rh_table_config_encoding = 0; 7494 break; 7495 case 65536: 7496 rh_table_config_encoding = 1; 7497 break; 7498 default: 7499 return SOC_E_CONFIG; 7500 } 7501 7502 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 7503 ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1); 7504 if ((soc_feature(unit, soc_feature_riot) || 7505 soc_feature(unit, soc_feature_multi_level_ecmp)) && 7506 ecmp_levels > 1) { 7507 7508 num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit, 7509 spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0); 7510 7511 if (SOC_FIELD_RANGE_CHECK( 7512 num_overlay_ecmp_rh_flowset_entries, 0, 16384)) { 7513 7514 num_overlay_ecmp_rh_flowset_entries = 16384; 7515 } else if (SOC_FIELD_RANGE_CHECK( 7516 num_overlay_ecmp_rh_flowset_entries, 16384, 32768)) { 7517 7518 num_overlay_ecmp_rh_flowset_entries = 32768; 7519 } else if (SOC_FIELD_RANGE_CHECK( 7520 num_overlay_ecmp_rh_flowset_entries, 32768, 49152)) { 7521 7522 num_overlay_ecmp_rh_flowset_entries = 49152; 7523 } else if (SOC_FIELD_RANGE_CHECK( 7524 num_overlay_ecmp_rh_flowset_entries, 49152, 65536)) { 7525 7526 num_overlay_ecmp_rh_flowset_entries = 65536; 7527 } 7528 7529 switch (num_overlay_ecmp_rh_flowset_entries) { 7530 case 0: 7531 rh_bank_sel = 0x0; 7532 break; 7533 case 16384: 7534 if (num_ecmp_rh_flowset_entries >= 16384) { 7535 rh_bank_sel = 0x1; 7536 } else { 7537 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7538 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7539 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7540 num_overlay_ecmp_rh_flowset_entries)); 7541 return SOC_E_CONFIG; 7542 } 7543 break; 7544 case 32768: 7545 if (num_ecmp_rh_flowset_entries >= 32768) { 7546 rh_bank_sel = 0x3; 7547 } else { 7548 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7549 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7550 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7551 num_overlay_ecmp_rh_flowset_entries)); 7552 return SOC_E_CONFIG; 7553 } 7554 break; 7555 case 49152: 7556 if (num_ecmp_rh_flowset_entries >= 49152) { 7557 rh_bank_sel = 0x7; 7558 } else { 7559 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7560 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7561 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7562 num_overlay_ecmp_rh_flowset_entries)); 7563 return SOC_E_CONFIG; 7564 } 7565 break; 7566 case 65536: 7567 if (num_ecmp_rh_flowset_entries >= 65536) { 7568 rh_bank_sel = 0xf; 7569 } else { 7570 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7571 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 7572 FUNCTION_NAME(), num_ecmp_rh_flowset_entries, 7573 num_overlay_ecmp_rh_flowset_entries)); 7574 return SOC_E_CONFIG; 7575 } 7576 break; 7577 default: 7578 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 7579 "%s: Value for overlay RH entries is not correct : %d \n"), 7580 FUNCTION_NAME(), num_overlay_ecmp_rh_flowset_entries)); 7581 return SOC_E_CONFIG; 7582 } 7583 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, RH_ECMP_FLOWSET_BANK_SELr, 7584 REG_PORT_ANY, BANK_SELf, 7585 rh_bank_sel)); 7586 } 7587 #endif 7588 7589 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr, 7590 REG_PORT_ANY, RH_FLOWSET_TABLE_CONFIG_ENCODINGf, 7591 rh_table_config_encoding)); 7592 7593 READ_TOP_PVTMON_CTRL_1r(unit, &rval); 7594 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1); 7595 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 7596 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0); 7597 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 7598 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1); 7599 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 7600 7601 /* Bypass unused Port Blocks */ 7602 if (soc_property_get(unit, "disable_unused_port_blocks", TRUE)) { 7603 SOC_IF_ERROR_RETURN(soc_apache_tsc_disable(unit)); 7604 } 7605 7606 7607 /* Do not use SBUS MDIO by default */ 7608 SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = NULL; 7609 SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = NULL; 7610 7611 /* Optionally allow SBUS MDIO for debug */ 7612 if (soc_property_get(unit, "apache_sbus_mdio", 1)) { 7613 SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = _soc_apache_mdio_reg_read; 7614 SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = _soc_apache_mdio_reg_write; 7615 } 7616 7617 if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED) && 7618 soc_feature(unit, soc_feature_turbo_boot)) { 7619 SOC_HW_RESET_START(unit); 7620 } 7621 7622 return SOC_E_NONE; 7623 } 7624 7625 int 7626 soc_apache_tsc_reset(int unit) 7627 { 7628 int blk, port; 7629 uint32 rval; 7630 7631 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CXXPORT) { 7632 port = SOC_BLOCK_PORT(unit, blk); 7633 7634 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7635 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 1)); 7636 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 2)); 7637 } 7638 7639 /* Though TSC/MAC reset is controlled by PortMod internally, 7640 * this is needed in case access to MAC registers is needed 7641 * before PortMod attach for cases like: 7642 * - To enable SER MAC interrupts 7643 * - Various sanity register read/write tests 7644 */ 7645 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLG2PORT) { 7646 port = SOC_BLOCK_PORT(unit, blk); 7647 7648 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7649 SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval)); 7650 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 7651 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 7652 } 7653 7654 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 7655 port = SOC_BLOCK_PORT(unit, blk); 7656 7657 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7658 SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval)); 7659 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 7660 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval)); 7661 } 7662 7663 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 7664 port = SOC_BLOCK_PORT(unit, blk); 7665 7666 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7667 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval)); 7668 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 7669 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 7670 } 7671 7672 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORTB0) { 7673 port = SOC_BLOCK_PORT(unit, blk); 7674 7675 SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0)); 7676 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval)); 7677 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 7678 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval)); 7679 } 7680 7681 return SOC_E_NONE; 7682 } 7683 7684 STATIC int 7685 _soc_apache_clear_enabled_port_data (int unit) 7686 { 7687 uint64 rval64; 7688 int port; 7689 uint32 evc = 0; 7690 egr_vlan_control_1_entry_t entry1; 7691 egr_vlan_control_2_entry_t entry2; 7692 egr_vlan_control_3_entry_t entry3; 7693 7694 sal_memset(&entry1, 0, sizeof(entry1)); 7695 sal_memset(&entry2, 0, sizeof(entry2)); 7696 sal_memset(&entry3, 0, sizeof(entry3)); 7697 7698 /* Some registers are implemented in memory, need to clear them in order 7699 * to have correct parity value */ 7700 COMPILER_64_ZERO(rval64); 7701 PBMP_ALL_ITER(unit, port) { 7702 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry1)); 7703 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry2)); 7704 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry3)); 7705 7706 SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, 0)); 7707 SOC_IF_ERROR_RETURN(WRITE_EGR_SF_SRC_MODID_CHECKr(unit, port, rval64)); 7708 SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64)); 7709 SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_INVALID_CRC_FRAMESr(unit, port, 0)); 7710 SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_DELIMITER_ERROR_FRAMESr(unit, port, 0)); 7711 SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ALL, port, &evc)); 7712 SOC_IF_ERROR_RETURN(WRITE_ING_TRILL_ADJACENCYr(unit, port, rval64)); 7713 SOC_IF_ERROR_RETURN(WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0)); 7714 SOC_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, 0)); 7715 } 7716 7717 return SOC_E_NONE; 7718 } 7719 7720 STATIC int 7721 _soc_apache_clear_all_port_data (int unit) 7722 { 7723 int r, p; 7724 uint32 addr; 7725 7726 SOC_IF_ERROR_RETURN(_soc_apache_clear_enabled_port_data(unit)); 7727 7728 7729 7730 /* Clear TDBGCn regs for all indexes */ 7731 for (r = 0; r < 12; r++) { 7732 addr = 0x28000000 + r*0x100; 7733 for (p = 0; p < 106; p++) { 7734 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7735 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7736 } 7737 } 7738 7739 /* Clear EGR_TRILL_TX_PKTS */ 7740 addr = 0x28000c00; 7741 for (p = 0; p < 106; p++) { 7742 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7743 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7744 } 7745 /* Clear EGR_TRILL_TX_ACCESS_PORT_TRILL_PKTS_DISCARDED */ 7746 addr = 0x28000d00; 7747 for (p = 0; p < 106; p++) { 7748 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7749 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7750 } 7751 /* Clear EGR_TRILL_TX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED */ 7752 addr = 0x28000e00; 7753 for (p = 0; p < 106; p++) { 7754 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7755 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7756 } 7757 /* Clear TPCE */ 7758 addr = 0x28000f00; 7759 for (p = 0; p < 106; p++) { 7760 _soc_reg32_set(unit, 0x2, 1, addr+p, 0); 7761 _soc_reg32_set(unit, 0x2, 2, addr+p, 0); 7762 } 7763 return SOC_E_NONE; 7764 } 7765 7766 STATIC int 7767 _soc_apache_clear_all_memory(int unit, int mmu_init) 7768 { 7769 int blk; 7770 int pgw, pgw_inst, num_pgw = 0; 7771 uint32 rval, in_progress[1]; 7772 int hw_reset_to, index, count; 7773 soc_reg_t hw_reset_reg; 7774 soc_timeout_t to; 7775 static const struct { 7776 soc_mem_t mem; 7777 uint32 skip_flags; /* always skip on QUICKTURN or XGSSIM */ 7778 } cam_list[] = { 7779 { CPU_COS_MAPm, BOOT_F_PLISIM }, 7780 { EFP_TCAMm, BOOT_F_PLISIM }, 7781 { FP_GLOBAL_MASK_TCAMm, BOOT_F_PLISIM }, 7782 { FP_TCAMm, BOOT_F_PLISIM }, 7783 { VFP_TCAMm, BOOT_F_PLISIM }, 7784 { FP_UDF_TCAMm, BOOT_F_PLISIM }, 7785 { ING_SNATm, BOOT_F_PLISIM }, 7786 { IP_MULTICAST_TCAMm, BOOT_F_PLISIM }, 7787 { L2_USER_ENTRYm, BOOT_F_PLISIM }, 7788 { L3_DEFIPm, BOOT_F_PLISIM }, 7789 { L3_DEFIP_PAIR_128m, BOOT_F_PLISIM }, 7790 { L3_TUNNELm, BOOT_F_PLISIM }, 7791 { MY_STATION_TCAMm, BOOT_F_PLISIM }, 7792 { UDF_CONDITIONAL_CHECK_TABLE_CAMm, BOOT_F_PLISIM }, 7793 { MY_STATION_TCAM_2m, BOOT_F_PLISIM }, 7794 { SUBPORT_TAG_SGPP_MAPm, BOOT_F_PLISIM }, 7795 { VLAN_SUBNETm, 0 },/* VLAN API needs all 0 mask */ 7796 { MY_STATION_TCAM_2m, BOOT_F_PLISIM }, 7797 { SUBPORT_TAG_SGPP_MAPm, BOOT_F_PLISIM }, 7798 #ifdef PLISIM 7799 /* In HW, these are the same as FP_GLOBAL_MASK_TCAM. 7800 * In simulation, they are separate instances. 7801 */ 7802 { FP_GM_FIELDSm, BOOT_F_PLISIM } 7803 #endif 7804 }; 7805 7806 if (mmu_init) { 7807 uint32 rval1; 7808 /* Start MMU memory initialization */ 7809 SOC_IF_ERROR_RETURN 7810 (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 0)); 7811 7812 SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1)); 7813 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0); 7814 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 7815 SOC_IF_ERROR_RETURN 7816 (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 1)); 7817 7818 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */ 7819 soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1); 7820 SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1)); 7821 } 7822 7823 SOC_IF_ERROR_RETURN 7824 (_soc_apache_mmu_init_default_val(unit)); 7825 7826 /* 7827 * Reset the PGW, IPIPE and EPIPE block 7828 */ 7829 rval = 0; 7830 hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r; 7831 soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1); 7832 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7833 7834 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) { 7835 num_pgw += 1; 7836 pgw = SOC_BLOCK_NUMBER(unit, blk); 7837 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 7838 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, pgw_inst, 0, rval)); 7839 } 7840 7841 rval = 0; 7842 hw_reset_reg = ING_HW_RESET_CONTROL_2r; 7843 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 7844 soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1); 7845 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7846 7847 /* Set count to # entries of largest IPIPE table */ 7848 count = soc_mem_index_count(unit, RH_HGT_FLOWSETm); 7849 if (count < soc_mem_index_count(unit, L2Xm)) { 7850 count = soc_mem_index_count(unit, L2Xm); 7851 } 7852 if (count < soc_mem_index_count(unit, L3_ENTRY_ONLYm)) { 7853 count = soc_mem_index_count(unit, L3_ENTRY_ONLYm); 7854 } 7855 if (count < soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 7856 count = soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m); 7857 } 7858 soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count); 7859 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval)); 7860 7861 rval = 0; 7862 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 7863 7864 hw_reset_reg = EGR_HW_RESET_CONTROL_1r; 7865 soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1); 7866 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7867 /* Set count to # entries of largest EPIPE table 32k */ 7868 count = soc_mem_index_count(unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm); 7869 soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count); 7870 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval)); 7871 7872 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 7873 if (SAL_BOOT_QUICKTURN) { 7874 hw_reset_to = 10000000; 7875 } else { 7876 hw_reset_to = 50000; 7877 } 7878 soc_timeout_init(&to, hw_reset_to, 0); 7879 7880 /* Wait for PGW memory initialization done. */ 7881 hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r; 7882 /* in_progress = ((1 << num_pgw) - 1); */ /* 1b for each PGW */ 7883 in_progress[0] = 0; 7884 SHR_BITSET_RANGE(in_progress, 0, num_pgw); /* 1b for each PGW */ 7885 7886 do { 7887 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) { 7888 pgw = SOC_BLOCK_NUMBER(unit, blk); 7889 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 7890 if (SHR_BITGET(in_progress, pgw)) { /* PGW RESET not done yet */ 7891 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, 7892 pgw_inst, 0, &rval)); 7893 7894 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7895 SHR_BITCLR(in_progress, pgw); /* Clear bit corresponding to the PGW */ 7896 } 7897 } 7898 } 7899 7900 if (soc_timeout_check(&to)) { 7901 if (!SAL_BOOT_BCMSIM) { 7902 LOG_WARN(BSL_LS_SOC_COMMON, 7903 (BSL_META_U(unit, "PGW_ING_HW_RESET timeout\n"))); 7904 } 7905 break; 7906 } 7907 } while (in_progress[0] != 0); 7908 7909 /* Wait for EPIPE memory initialization done. */ 7910 in_progress[0] = 1; 7911 hw_reset_reg = EGR_HW_RESET_CONTROL_1r; 7912 do { 7913 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval)); 7914 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7915 in_progress[0] = 0; 7916 } 7917 if (soc_timeout_check(&to)) { 7918 if (!SAL_BOOT_BCMSIM) { 7919 LOG_WARN(BSL_LS_SOC_COMMON, 7920 (BSL_META_U(unit, "EGR_HW_RESET timeout\n"))); 7921 } 7922 break; 7923 } 7924 } while (in_progress[0] != 0); 7925 7926 rval = 0; 7927 hw_reset_reg = EGR_HW_RESET_CONTROL_0r; 7928 soc_reg_field_set(unit, hw_reset_reg, &rval, STAGE_NUMBERf, 1); 7929 soc_reg_field_set(unit, hw_reset_reg, &rval, START_ADDRESSf, 0x80000); 7930 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 7931 7932 rval = 0; 7933 in_progress[0] = 1; 7934 hw_reset_reg = EGR_HW_RESET_CONTROL_1r; 7935 soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1); 7936 soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count); 7937 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 7938 7939 do { 7940 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval)); 7941 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7942 in_progress[0] = 0; 7943 } 7944 if (soc_timeout_check(&to)) { 7945 if (!SAL_BOOT_BCMSIM) { 7946 LOG_WARN(BSL_LS_SOC_COMMON, 7947 (BSL_META_U(unit, "EGR_HW_RESET timeout\n"))); 7948 } 7949 break; 7950 } 7951 } while (in_progress[0] != 0); 7952 7953 /* Wait for IPIPE memory initialization done. */ 7954 in_progress[0] = 1; 7955 hw_reset_reg = ING_HW_RESET_CONTROL_2r; 7956 do { 7957 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval)); 7958 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) { 7959 in_progress[0] = 0; 7960 } 7961 7962 if (soc_timeout_check(&to)) { 7963 if (!SAL_BOOT_BCMSIM) { 7964 LOG_WARN(BSL_LS_SOC_COMMON, 7965 (BSL_META_U(unit, "ING_HW_RESET timeout\n"))); 7966 } 7967 break; 7968 } 7969 } while (in_progress[0] != 0); 7970 7971 /* Clear HW reset control registers */ 7972 rval = 0; 7973 hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r; 7974 SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) { 7975 pgw = SOC_BLOCK_NUMBER(unit, blk); 7976 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 7977 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, pgw_inst, 0, rval)); 7978 } 7979 7980 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 7981 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 7982 7983 /* TCAM tables are not handled by hardware reset control */ 7984 if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_XGSSIM) { 7985 for (index = 0; index < sizeof(cam_list) / sizeof(cam_list[0]); 7986 index++) { 7987 if (sal_boot_flags_get() & cam_list[index].skip_flags) { 7988 continue; 7989 } 7990 SOC_IF_ERROR_RETURN 7991 (soc_mem_clear(unit, cam_list[index].mem, COPYNO_ALL, TRUE)); 7992 } 7993 } 7994 7995 return SOC_E_NONE; 7996 } 7997 7998 7999 STATIC int 8000 _soc_apache_port_mapping_init(int unit) 8001 { 8002 soc_info_t *si; 8003 soc_mem_t mem; 8004 uint32 rval; 8005 ing_physical_to_logical_port_number_mapping_table_entry_t entry; 8006 int port, phy_port, mmu_port; 8007 int num_port, num_phy_port; 8008 8009 si = &SOC_INFO(unit); 8010 8011 /* Ingress physical to logical port mapping */ 8012 mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm; 8013 num_phy_port = soc_mem_index_count(unit, mem); 8014 sal_memset(&entry, 0, sizeof(entry)); 8015 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 8016 port = si->port_p2l_mapping[phy_port]; 8017 soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf, 8018 port == -1 ? 0x7f : port); 8019 SOC_IF_ERROR_RETURN 8020 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry)); 8021 } 8022 8023 /* Ingress logical to physical port mapping */ 8024 num_port = soc_mem_index_count(unit, PORT_TABm) - 1; 8025 8026 for (port = 0; port < num_port; port++) { 8027 phy_port = si->port_l2p_mapping[port]; 8028 rval = 0; 8029 if (phy_port != -1) { 8030 soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval, 8031 VALIDf, 1); 8032 8033 /* IFP_GM_LOGICAL_TO_PHYSICAL_MAPP?ING.PHYSICAL_PORT_NUM is 8034 * merely a unique stream ID, it's not physical port number */ 8035 soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval, 8036 PHYSICAL_PORT_NUMf, 8037 si->port_p2m_mapping[phy_port] & 0x7f); 8038 } 8039 SOC_IF_ERROR_RETURN 8040 (WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval)); 8041 } 8042 8043 /* Egress logical to physical port mapping */ 8044 for (port = 0; port < num_port; port++) { 8045 phy_port = si->port_l2p_mapping[port]; 8046 rval = 0; 8047 soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr, 8048 &rval, PHYSICAL_PORT_NUMBERf, 8049 phy_port == -1 ? 0x7f : phy_port); 8050 SOC_IF_ERROR_RETURN 8051 (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port, 8052 rval)); 8053 } 8054 8055 /* MMU to physical port mapping and MMU to logical port mapping */ 8056 for (port = 0; port < num_port; port++) { 8057 phy_port = si->port_l2p_mapping[port]; 8058 mmu_port = si->port_p2m_mapping[phy_port]; 8059 if ((phy_port == -1) || (mmu_port == -1)) { 8060 continue; 8061 } 8062 rval = 0; 8063 soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval, 8064 PHY_PORTf, phy_port); 8065 SOC_IF_ERROR_RETURN 8066 (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, port, 0, 8067 rval)); 8068 8069 rval = 0; 8070 soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval, 8071 LOGIC_PORTf, port); 8072 SOC_IF_ERROR_RETURN 8073 (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, port, 0, 8074 rval)); 8075 } 8076 8077 return SOC_E_NONE; 8078 } 8079 8080 #define APACHE_PGW_TDM_LENGTH AP_LR_LLS_LEN 8081 #define APACHE_PGW_TDM_OVS_SIZE AP_OS_LLS_GRP_LEN 8082 #define APACHE_PGW_TDM_SLOTS_PER_REG 4 8083 #define APACHE_MMU_TDM_LENGTH 512 8084 #define APACHE_MMU_OVS_GROUP_COUNT AP_OS_VBS_GRP_NUM 8085 #define APACHE_MMU_OVS_WT_GROUP_COUNT 4 8086 #define APACHE_MMU_OVS_GROUP_TDM_LENGTH AP_OS_VBS_GRP_LEN 8087 #define APACHE_IARB_TDM_LENGTH AP_LR_IARB_STATIC_LEN 8088 8089 8090 #define OVS_TOKEN AP_OVSB_TOKEN 8091 #define IDL1_TOKEN AP_IDL1_TOKEN 8092 #define IDL2_TOKEN AP_IDL2_TOKEN 8093 #define AUX_TOKEN AP_AUX_TOKEN 8094 #define SBUS_TOKEN AP_SBUS_TOKEN 8095 8096 #define NUM_EXT_PORTS AP_NUM_EXT_PORTS 8097 8098 #define PORT_STATE_UNUSED 0 /* PORT_STATE__DISABLED */ 8099 #define PORT_STATE_LINERATE 1 /* PORT_STATE__LINERATE */ 8100 #define PORT_STATE_OVERSUB 2 /* PORT_STATE__OVERSUB */ 8101 #define PORT_STATE_SUBPORT 3 /* PORT_STATE__COMBINED */ 8102 8103 enum _ap_ovs_speed_classes { 8104 ap_ovs_speed_None = 0, 8105 ap_ovs_speed_5G = 2, 8106 ap_ovs_speed_10G = 4, 8107 ap_ovs_speed_20G = 8, 8108 ap_ovs_speed_25G = 10, 8109 ap_ovs_speed_40G = 16, 8110 ap_ovs_speed_50G = 20, 8111 ap_ovs_speed_100G = 40 8112 }; 8113 8114 typedef struct soc_apache_tdm_s { 8115 int tdm_bw; 8116 int is_oversub; 8117 8118 int speed[NUM_EXT_PORTS]; 8119 int port_state[NUM_EXT_PORTS]; 8120 8121 int pgw_tdm[APACHE_PGWS_PER_DEV][APACHE_PGW_TDM_LENGTH]; 8122 int mmu_tdm[APACHE_MMU_TDM_LENGTH + 1]; 8123 8124 struct { 8125 int pgw_ovs_tdm[APACHE_PGWS_PER_DEV][APACHE_PGW_TDM_LENGTH]; 8126 int pgw_ovs_spacing[APACHE_PGWS_PER_DEV][APACHE_PGW_TDM_LENGTH]; 8127 } ingress_ovs_tdm; 8128 8129 struct { 8130 int mmu_ovs_group_tdm[APACHE_MMU_OVS_GROUP_COUNT][APACHE_MMU_OVS_GROUP_TDM_LENGTH]; 8131 int mmu_ovs_group_speed[APACHE_MMU_OVS_GROUP_COUNT]; /* Speed for each OVS grp */ 8132 int mmu_ovs_group_wt_group[APACHE_MMU_OVS_GROUP_COUNT]; /* Weighti group for each OVS grp */ 8133 } egress_ovs_tdm; 8134 8135 int iarb_tdm_wrap_ptr; 8136 int iarb_tdm[APACHE_IARB_TDM_LENGTH]; 8137 } soc_apache_tdm_t; 8138 8139 8140 8141 struct soc_apache_misc_info_s { 8142 int tdm_active_cal; 8143 uint16 tdm_wtg_used[APACHE_MMU_OVS_WT_GROUP_COUNT]; 8144 soc_apache_tdm_t tdm0; 8145 soc_apache_tdm_t tdm1; 8146 } *soc_apache_misc_info[SOC_MAX_NUM_DEVICES] = {0}; 8147 8148 #define AP_MISC(unit) (soc_apache_misc_info[unit]) 8149 8150 static const soc_field_t ap_mmu_ovs_group_wt_select_fields[] = { 8151 GRP0f, GRP1f, GRP2f, GRP3f, GRP4f, GRP5f, GRP6f, GRP7f 8152 }; 8153 8154 8155 static const soc_reg_t ap_pgw_lr_tdm_regs[2][16] = { 8156 { 8157 PGW_LR_TDM_REG_0r, PGW_LR_TDM_REG_1r, 8158 PGW_LR_TDM_REG_2r, PGW_LR_TDM_REG_3r, 8159 PGW_LR_TDM_REG_4r, PGW_LR_TDM_REG_5r, 8160 PGW_LR_TDM_REG_6r, PGW_LR_TDM_REG_7r, 8161 PGW_LR_TDM_REG_8r, PGW_LR_TDM_REG_9r, 8162 PGW_LR_TDM_REG_10r, PGW_LR_TDM_REG_11r, 8163 PGW_LR_TDM_REG_12r, PGW_LR_TDM_REG_13r, 8164 PGW_LR_TDM_REG_14r, PGW_LR_TDM_REG_15r 8165 }, 8166 { 8167 PGW_LR_TDM2_REG_0r, PGW_LR_TDM2_REG_1r, 8168 PGW_LR_TDM2_REG_2r, PGW_LR_TDM2_REG_3r, 8169 PGW_LR_TDM2_REG_4r, PGW_LR_TDM2_REG_5r, 8170 PGW_LR_TDM2_REG_6r, PGW_LR_TDM2_REG_7r, 8171 PGW_LR_TDM2_REG_8r, PGW_LR_TDM2_REG_9r, 8172 PGW_LR_TDM2_REG_10r, PGW_LR_TDM2_REG_11r, 8173 PGW_LR_TDM2_REG_12r, PGW_LR_TDM2_REG_13r, 8174 PGW_LR_TDM2_REG_14r, PGW_LR_TDM2_REG_15r 8175 } 8176 }; 8177 8178 static const soc_field_t ap_pgw_tdm_fields[] = { 8179 TDM_ENTRY0_PORT_IDf, TDM_ENTRY1_PORT_IDf, 8180 TDM_ENTRY2_PORT_IDf, TDM_ENTRY3_PORT_IDf, 8181 TDM_ENTRY4_PORT_IDf, TDM_ENTRY5_PORT_IDf, 8182 TDM_ENTRY6_PORT_IDf, TDM_ENTRY7_PORT_IDf, 8183 TDM_ENTRY8_PORT_IDf, TDM_ENTRY9_PORT_IDf, 8184 TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf, 8185 TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf, 8186 TDM_ENTRY14_PORT_IDf, TDM_ENTRY15_PORT_IDf, 8187 TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf, 8188 TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf, 8189 TDM_ENTRY20_PORT_IDf, TDM_ENTRY21_PORT_IDf, 8190 TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf, 8191 TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf, 8192 TDM_ENTRY26_PORT_IDf, TDM_ENTRY27_PORT_IDf, 8193 TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf, 8194 TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf, 8195 TDM_ENTRY32_PORT_IDf, TDM_ENTRY33_PORT_IDf, 8196 TDM_ENTRY34_PORT_IDf, TDM_ENTRY35_PORT_IDf, 8197 TDM_ENTRY36_PORT_IDf, TDM_ENTRY37_PORT_IDf, 8198 TDM_ENTRY38_PORT_IDf, TDM_ENTRY39_PORT_IDf, 8199 TDM_ENTRY40_PORT_IDf, TDM_ENTRY41_PORT_IDf, 8200 TDM_ENTRY42_PORT_IDf, TDM_ENTRY43_PORT_IDf, 8201 TDM_ENTRY44_PORT_IDf, TDM_ENTRY45_PORT_IDf, 8202 TDM_ENTRY46_PORT_IDf, TDM_ENTRY47_PORT_IDf, 8203 TDM_ENTRY48_PORT_IDf, TDM_ENTRY49_PORT_IDf, 8204 TDM_ENTRY50_PORT_IDf, TDM_ENTRY51_PORT_IDf, 8205 TDM_ENTRY52_PORT_IDf, TDM_ENTRY53_PORT_IDf, 8206 TDM_ENTRY54_PORT_IDf, TDM_ENTRY55_PORT_IDf, 8207 TDM_ENTRY56_PORT_IDf, TDM_ENTRY57_PORT_IDf, 8208 TDM_ENTRY58_PORT_IDf, TDM_ENTRY59_PORT_IDf, 8209 TDM_ENTRY60_PORT_IDf, TDM_ENTRY61_PORT_IDf, 8210 TDM_ENTRY62_PORT_IDf, TDM_ENTRY63_PORT_IDf 8211 }; 8212 8213 static const soc_reg_t ap_pgw_ovs_tdm_regs[] = { 8214 PGW_OS_TDM_REG_0r, PGW_OS_TDM_REG_1r, 8215 PGW_OS_TDM_REG_2r, PGW_OS_TDM_REG_3r, 8216 PGW_OS_TDM_REG_4r, PGW_OS_TDM_REG_5r, 8217 PGW_OS_TDM_REG_6r, PGW_OS_TDM_REG_7r, 8218 PGW_OS_TDM_REG_8r, PGW_OS_TDM_REG_9r 8219 }; 8220 static const soc_reg_t ap_pgw_ovs_spacing_regs[] = { 8221 PGW_OS_PORT_SPACING_REG_0r, PGW_OS_PORT_SPACING_REG_1r, 8222 PGW_OS_PORT_SPACING_REG_2r, PGW_OS_PORT_SPACING_REG_3r, 8223 PGW_OS_PORT_SPACING_REG_4r, PGW_OS_PORT_SPACING_REG_5r, 8224 PGW_OS_PORT_SPACING_REG_6r, PGW_OS_PORT_SPACING_REG_7r, 8225 PGW_OS_PORT_SPACING_REG_8r, PGW_OS_PORT_SPACING_REG_9r 8226 }; 8227 static const soc_field_t ap_pgw_spacing_fields[] = { 8228 SLOT0f, SLOT1f, SLOT2f, SLOT3f, SLOT4f, SLOT5f, SLOT6f, SLOT7f, 8229 SLOT8f, SLOT9f, SLOT10f, SLOT11f, SLOT12f, SLOT13f, SLOT14f, SLOT15f, 8230 SLOT16f, SLOT17f, SLOT18f, SLOT19f, SLOT20f, SLOT21f, SLOT22f, SLOT23f, 8231 SLOT24f, SLOT25f, SLOT26f, SLOT27f, SLOT28f, SLOT29f, SLOT30f, SLOT31f, 8232 SLOT32f, SLOT33f, SLOT34f, SLOT35f, SLOT36f, SLOT37f, SLOT38f, SLOT39f 8233 }; 8234 8235 /* Registers are serviced in SPRI manner. 8236 * e.g. PGW_HSP_CONFIG_0 is highest priority with PGW_HSP_CONFIG_8 the lowest. 8237 * In order to minimise bunching of slots as much as possible, the order 8238 * these should be programmed is like below 8239 */ 8240 static const soc_reg_t pgw_hsp_config_regs[APACHE_NUM_CLP_PER_PGW * APACHE_PORTS_PER_TSC] = { 8241 PGW_HSP_CONFIG_1r, PGW_HSP_CONFIG_5r, PGW_HSP_CONFIG_3r, PGW_HSP_CONFIG_7r, 8242 PGW_HSP_CONFIG_0r, PGW_HSP_CONFIG_4r, PGW_HSP_CONFIG_2r, PGW_HSP_CONFIG_6r 8243 }; 8244 8245 static const soc_reg_t pgw_hsp_config_fields[APACHE_NUM_CLP_PER_PGW * APACHE_PORTS_PER_TSC] = { 8246 PHY_PORT_NO_1f, PHY_PORT_NO_5f, PHY_PORT_NO_3f, PHY_PORT_NO_7f, 8247 PHY_PORT_NO_0f, PHY_PORT_NO_4f, PHY_PORT_NO_2f, PHY_PORT_NO_6f 8248 }; 8249 8250 static const soc_reg_t ap_tdm_pgw_ctrl = PGW_TDM_CONTROLr; 8251 static const soc_reg_t ap_tdm_mmu_ctrl = ES_PIPE0_TDM_CONFIGr; 8252 static const soc_reg_t mmu_ovs_group_regs[APACHE_MMU_OVS_GROUP_COUNT] = { 8253 ES_PIPE0_OVR_SUB_GRP0_TBLr, ES_PIPE0_OVR_SUB_GRP1_TBLr, 8254 ES_PIPE0_OVR_SUB_GRP2_TBLr, ES_PIPE0_OVR_SUB_GRP3_TBLr, 8255 ES_PIPE0_OVR_SUB_GRP4_TBLr, ES_PIPE0_OVR_SUB_GRP5_TBLr, 8256 ES_PIPE0_OVR_SUB_GRP6_TBLr, ES_PIPE0_OVR_SUB_GRP7_TBLr 8257 }; 8258 8259 static const soc_reg_t mmu_ovs_group_wt_regs[4] = { 8260 ES_PIPE0_OVR_SUB_GRP_WT0r, ES_PIPE0_OVR_SUB_GRP_WT1r, 8261 ES_PIPE0_OVR_SUB_GRP_WT2r, ES_PIPE0_OVR_SUB_GRP_WT3r 8262 }; 8263 8264 /* 8265 * MMU OVS TDM min. slot bandwidth is 5G. 8266 * For FB5 family of devices: 8267 * Anything less than 5G will be grouped together and will have provision for up to 5G. 8268 * 8269 * For MV,Rg2+, anything <=10G will be grouped together 8270 */ 8271 #define APACHE_TDM_MMU_SPEED_GET(unit, speed) \ 8272 do { \ 8273 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed); \ 8274 if ((speed <= 5000) && (speed > 0)) { \ 8275 speed = 10000; \ 8276 if (soc_feature(unit, soc_feature_untethered_otp)) { \ 8277 speed = (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureFamilyFirebolt5) ? 5000 : 10000);\ 8278 } \ 8279 } \ 8280 } while (0) 8281 8282 8283 #define AP_TDM_WT_GRP_SPG_GET(unit, _wtg) ((AP_MISC(unit)->tdm_wtg_used[_wtg] & 0xff)) 8284 #define AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) ((AP_MISC(unit)->tdm_wtg_used[_wtg] >> 8) & 0xff) 8285 8286 #define APACHE_TDM_WT_GRP_SPEED_GET(unit, _wtg) ((AP_TDM_WT_GRP_SPG_GET(unit, _wtg) * 2500)) 8287 8288 8289 #define APACHE_TDM_WT_GRP_RESERVE(unit, _wtg, _spg) \ 8290 do { \ 8291 uint16 _tmp = (AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) + 1); \ 8292 AP_MISC(unit)->tdm_wtg_used[_wtg] = ((_spg) | (_tmp << 8)); \ 8293 } while (0) 8294 8295 #define APACHE_TDM_WT_GRP_FREE(unit, _wtg) \ 8296 do { \ 8297 uint16 _tmp = (AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) - 1); \ 8298 if (AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) <= 1) { \ 8299 soc_apache_misc_info[unit]->tdm_wtg_used[_wtg] = 0; \ 8300 } else { \ 8301 soc_apache_misc_info[unit]->tdm_wtg_used[_wtg] = \ 8302 (AP_TDM_WT_GRP_SPG_GET(unit, _wtg) | (_tmp << 8)); \ 8303 } \ 8304 } while (0) 8305 8306 #define APACHE_TDM_WT_GRP_LOG(unit) \ 8307 do { \ 8308 int _wtg; \ 8309 LOG_VERBOSE(BSL_LS_SOC_TDM, \ 8310 (BSL_META_U(unit, \ 8311 "Weight groups and reference counts: \n\t"))); \ 8312 for (_wtg = 0; _wtg < 4; _wtg++) { \ 8313 LOG_VERBOSE(BSL_LS_SOC_TDM, \ 8314 (BSL_META_U(unit, \ 8315 "Grp = %d Refcnt = %d Speed Grp = %d Speed = %d;"), \ 8316 _wtg, AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg), \ 8317 AP_TDM_WT_GRP_SPG_GET(unit, _wtg), \ 8318 APACHE_TDM_WT_GRP_SPEED_GET(unit, _wtg))); \ 8319 } \ 8320 LOG_VERBOSE(BSL_LS_SOC_TDM, (BSL_META_U(unit, "\n"))); \ 8321 } while (0) 8322 8323 #define APACHE_TDM_WT_GRP_USABLE(unit, _wtg, _spg) \ 8324 ((AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) == 0) || (AP_TDM_WT_GRP_SPG_GET(unit, _wtg) == _spg)) 8325 8326 #define APACHE_TDM_ACTIVE_CAL(unit) soc_apache_misc_info[unit]->tdm_active_cal 8327 #define APACHE_TDM_STRUCT_ACTIVE(unit) (!APACHE_TDM_ACTIVE_CAL(unit)) ? \ 8328 &(soc_apache_misc_info[unit]->tdm0) : &(soc_apache_misc_info[unit]->tdm1) 8329 #define APACHE_TDM_STRUCT_BACKUP(unit) (APACHE_TDM_ACTIVE_CAL(unit)) ? \ 8330 &(soc_apache_misc_info[unit]->tdm0) : &(soc_apache_misc_info[unit]->tdm1) 8331 8332 #define APACHE_TDM_PGW_LR_REG(cur_cal, slot) ap_pgw_lr_tdm_regs[cur_cal][slot/4] 8333 8334 #define APACHE_TDM_PGW_OS_REG(slot) ap_pgw_ovs_tdm_regs[slot/4] 8335 8336 #define APACHE_TDM_PGW_OS_SPACING_REG(slot) ap_pgw_ovs_spacing_regs[slot/4] 8337 8338 #define APACHE_TDM_PGW_SLOT(slot) ap_pgw_tdm_fields[slot] 8339 #define APACHE_TDM_PGW_OS_SPACING_FIELD(slot) ap_pgw_spacing_fields[slot] 8340 8341 #define APACHE_TDM_MMU_TBL(cur_cal) \ 8342 (!cur_cal) ? ES_PIPE0_TDM_TABLE_0m : ES_PIPE0_TDM_TABLE_1m 8343 8344 #if !defined(SOC_NO_NAMES) 8345 #define APACHE_TDM_PGW_LOG(_u, _desc, _r, _f, _v) \ 8346 LOG_INFO(BSL_LS_SOC_COMMON, \ 8347 (BSL_META_U(_u, \ 8348 _desc ": %s.%s = %d\n"), \ 8349 SOC_REG_NAME(_u, _r), \ 8350 soc_fieldnames[_f], _v)) 8351 #else 8352 #define APACHE_TDM_PGW_LOG(_u, _desc, _r, _f, _v) \ 8353 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(_u, _desc ": = %d\n"), _v)) 8354 #endif 8355 8356 soc_error_t 8357 _soc_apache_mmu_ovs_speed_class_map_get(int unit, int *speed, int *spg, uint32 *sp_spacing) 8358 { 8359 APACHE_TDM_MMU_SPEED_GET(unit, *speed); 8360 switch (*speed) { 8361 case 5000: 8362 *sp_spacing = 0x14; 8363 *spg = ap_ovs_speed_5G; 8364 break; 8365 case 10000: 8366 *sp_spacing = 0x14; 8367 *spg = ap_ovs_speed_10G; 8368 break; 8369 case 20000: 8370 *sp_spacing = 0x0a; 8371 *spg = ap_ovs_speed_20G; 8372 break; 8373 case 25000: 8374 *sp_spacing = 0x0a; 8375 *spg = ap_ovs_speed_25G; 8376 break; 8377 case 40000: 8378 *sp_spacing = 0x0a; 8379 *spg = ap_ovs_speed_40G; 8380 break; 8381 case 50000: 8382 *sp_spacing = 0x0a; 8383 *spg = ap_ovs_speed_50G; 8384 break; 8385 case 100000: 8386 *sp_spacing = 0x04; 8387 *spg = ap_ovs_speed_100G; 8388 break; 8389 default: 8390 *sp_spacing = 0x0; 8391 *spg = ap_ovs_speed_None; 8392 return SOC_E_FAIL; 8393 } 8394 8395 return SOC_E_NONE; 8396 } 8397 8398 /* 8399 * soc_apache_tdm_algo_freq_get 8400 * 8401 * TDM Algorithm differentiates between various static calendars used for 8402 * FB5 with the input core clock frequency. 8403 * For all-OS, all-LR configs, TDM algo expects the actual core clock frequency 8404 * of the device and will calculate the calendars accordingly. 8405 * For mixed mode (LR + OS) ports, a unique core clock frequency is assigned for each SKU (FB5). 8406 * This function maps the input core clock and SKU id to the clock frequency the tdm algo expects. 8407 */ 8408 8409 STATIC int 8410 soc_apache_tdm_algo_freq_get(int unit, int *core_clk_freq) 8411 { 8412 int oversub_mode; 8413 uint16 dev_id; 8414 uint8 rev_id; 8415 #if defined(BCM_56560_A0) || defined(BCM_56560_B0) 8416 soc_pbmp_t pbmp; 8417 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 8418 #endif 8419 8420 oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0); 8421 soc_cm_get_id(unit, &dev_id, &rev_id); 8422 8423 8424 switch (oversub_mode) { 8425 /* fall through */ 8426 case 0: /* All Linerate */ 8427 case 1: /* All Oversub */ 8428 switch (dev_id) { 8429 case BCM56768_DEVICE_ID: 8430 case BCM56068_DEVICE_ID: 8431 *core_clk_freq = 840; 8432 break; 8433 default: 8434 *core_clk_freq = 793; 8435 break; 8436 } 8437 break; 8438 case 2: /* Mix of Linerate and Oversub */ 8439 switch (dev_id) { 8440 case BCM56565_DEVICE_ID: 8441 *core_clk_freq = 794; 8442 break; 8443 case BCM56567_DEVICE_ID: 8444 *core_clk_freq = 795; 8445 break; 8446 case BCM56568_DEVICE_ID: 8447 *core_clk_freq = 796; 8448 8449 #if defined(BCM_56560_A0) || defined(BCM_56560_B0) 8450 if (SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 16) + 1]) && 8451 !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 16) + 1]) && 8452 SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 17) + 1]) && 8453 !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 17) + 1])) { 8454 /* TSC16 and TSC 17 is in line rate */ 8455 *core_clk_freq = 797; 8456 } else if ( SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 6) + 1]) && 8457 !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 6) + 1]) && 8458 SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 9) + 1]) && 8459 !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 9) + 1])) { 8460 /*new config TSC 6 and TSC 9 are in line rate */ 8461 *core_clk_freq = 798; 8462 } 8463 #endif 8464 break; 8465 default: 8466 *core_clk_freq = 793; 8467 break; 8468 } 8469 break; 8470 default: 8471 *core_clk_freq = 793; 8472 break; 8473 } 8474 return SOC_E_NONE; 8475 } 8476 8477 STATIC int 8478 soc_apache_tdm_calc(int unit, soc_apache_tdm_t *apache_tdm) 8479 { 8480 int rv, pgw, group, index; 8481 tdm_soc_t apache_chip_pkg; 8482 tdm_mod_t *apache_tdm_pkg; 8483 8484 sal_memset(&apache_chip_pkg, 0, sizeof(tdm_soc_t)); 8485 8486 apache_chip_pkg.unit = unit; 8487 apache_chip_pkg.num_ext_ports = AP_NUM_EXT_PORTS; 8488 apache_chip_pkg.state = sal_alloc((apache_chip_pkg.num_ext_ports)*sizeof(int *), "port state list"); 8489 apache_chip_pkg.speed = sal_alloc((apache_chip_pkg.num_ext_ports)*sizeof(int *), "port speed list"); 8490 8491 for (index = 1; index < apache_chip_pkg.num_ext_ports; index++) { 8492 apache_chip_pkg.state[index] = apache_tdm->port_state[index]; 8493 } 8494 apache_chip_pkg.state[0] = 1; /* enable cpu port */ 8495 apache_chip_pkg.state[73] = 1; /* enable loopback port */ 8496 apache_chip_pkg.state[74] = 1; /* enable RDB port */ 8497 8498 for (index = 0; index < apache_chip_pkg.num_ext_ports; index++) { 8499 apache_chip_pkg.speed[index] = apache_tdm->speed[index]; 8500 } 8501 8502 8503 if (soc_property_get(unit, "tdm_check_disable", 0)) { 8504 apache_chip_pkg.soc_vars.ap.tdm_chk_en = 0; 8505 } else { 8506 apache_chip_pkg.soc_vars.ap.tdm_chk_en = 1; 8507 } 8508 8509 8510 SOC_IF_ERROR_RETURN(soc_apache_tdm_algo_freq_get(unit, &apache_chip_pkg.clk_freq)); 8511 apache_tdm_pkg = _soc_set_tdm_tbl(SOC_SEL_TDM(&apache_chip_pkg)); 8512 8513 if (!apache_tdm_pkg) { 8514 LOG_CLI((BSL_META_U(unit, 8515 "Unsupported config for TDM calendar generation\n"))); 8516 return SOC_E_FAIL; 8517 } 8518 8519 /* PGW0 LR/OS Calendars */ 8520 sal_memcpy(apache_tdm->pgw_tdm[0], 8521 apache_tdm_pkg->_chip_data.cal_0.cal_main, 8522 sizeof(int)*APACHE_PGW_TDM_LENGTH); 8523 sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[0], 8524 apache_tdm_pkg->_chip_data.cal_0.cal_grp[0], 8525 sizeof(int)*APACHE_PGW_TDM_OVS_SIZE); 8526 sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[0], 8527 apache_tdm_pkg->_chip_data.cal_0.cal_grp[1], 8528 sizeof(int)*APACHE_PGW_TDM_OVS_SIZE); 8529 8530 /* PGW1 LR/OS Calendars */ 8531 sal_memcpy(apache_tdm->pgw_tdm[1], 8532 apache_tdm_pkg->_chip_data.cal_1.cal_main, 8533 sizeof(int)*APACHE_PGW_TDM_LENGTH); 8534 sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[1], 8535 apache_tdm_pkg->_chip_data.cal_1.cal_grp[0], 8536 sizeof(int)*APACHE_PGW_TDM_OVS_SIZE); 8537 sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[1], 8538 apache_tdm_pkg->_chip_data.cal_1.cal_grp[1], 8539 sizeof(int)*APACHE_PGW_TDM_OVS_SIZE); 8540 8541 sal_memcpy(apache_tdm->mmu_tdm, 8542 apache_tdm_pkg->_chip_data.cal_2.cal_main, 8543 sizeof(int)*APACHE_MMU_TDM_LENGTH); 8544 8545 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[0], 8546 apache_tdm_pkg->_chip_data.cal_2.cal_grp[0], 8547 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8548 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[1], 8549 apache_tdm_pkg->_chip_data.cal_2.cal_grp[1], 8550 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8551 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[2], 8552 apache_tdm_pkg->_chip_data.cal_2.cal_grp[2], 8553 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8554 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[3], 8555 apache_tdm_pkg->_chip_data.cal_2.cal_grp[3], 8556 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8557 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[4], 8558 apache_tdm_pkg->_chip_data.cal_2.cal_grp[4], 8559 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8560 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[5], 8561 apache_tdm_pkg->_chip_data.cal_2.cal_grp[5], 8562 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8563 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[6], 8564 apache_tdm_pkg->_chip_data.cal_2.cal_grp[6], 8565 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8566 sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[7], 8567 apache_tdm_pkg->_chip_data.cal_2.cal_grp[7], 8568 sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH); 8569 8570 sal_free(apache_chip_pkg.state); 8571 sal_free(apache_chip_pkg.speed); 8572 8573 apache_tdm_pkg->_chip_exec[TDM_CHIP_EXEC__FREE](apache_tdm_pkg); 8574 sal_free(apache_tdm_pkg); 8575 8576 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 8577 for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) { 8578 LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_tdm:"), pgw)); 8579 for (index = 0; index < APACHE_PGW_TDM_LENGTH; index++) { 8580 if (index % 16 == 0) { 8581 LOG_CLI((BSL_META_U(unit, "\n "))); 8582 } 8583 LOG_CLI((BSL_META_U(unit, " %3d"), 8584 apache_tdm->pgw_tdm[pgw][index])); 8585 } 8586 LOG_CLI((BSL_META_U(unit, "\n"))); 8587 LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_tdm:"), pgw)); 8588 for (index = 0; index < APACHE_PGW_TDM_LENGTH; index++) { 8589 if (index % 16 == 0) { 8590 LOG_CLI((BSL_META_U(unit, "\n "))); 8591 } 8592 LOG_CLI((BSL_META_U(unit, " %3d"), 8593 apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][index])); 8594 } 8595 LOG_CLI((BSL_META_U(unit, "\n"))); 8596 LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_spacing:"), pgw)); 8597 for (index = 0; index < APACHE_PGW_TDM_LENGTH; index++) { 8598 if (index % 16 == 0) { 8599 LOG_CLI((BSL_META_U(unit, "\n "))); 8600 } 8601 LOG_CLI((BSL_META_U(unit, " %3d"), 8602 apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][index])); 8603 } 8604 LOG_CLI((BSL_META_U(unit, "\n"))); 8605 } 8606 LOG_CLI((BSL_META_U(unit, "mmu_tdm:"))); 8607 for (index = 0; index < APACHE_MMU_TDM_LENGTH; index++) { 8608 if (index % 16 == 0) { 8609 LOG_CLI((BSL_META_U(unit, "\n "))); 8610 } 8611 LOG_CLI((BSL_META_U(unit, " %3d"), 8612 apache_tdm->mmu_tdm[index])); 8613 } 8614 LOG_CLI((BSL_META_U(unit, "\n"))); 8615 for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) { 8616 LOG_CLI((BSL_META_U(unit, "group %d ovs_group_tdm"), group)); 8617 for (index = 0; index < APACHE_MMU_OVS_GROUP_TDM_LENGTH; 8618 index++) { 8619 if (index % 16 == 0) { 8620 LOG_CLI((BSL_META_U(unit, "\n "))); 8621 } 8622 LOG_CLI((BSL_META_U(unit, " %3d"), 8623 apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][index])); 8624 } 8625 LOG_CLI((BSL_META_U(unit, "\n"))); 8626 } 8627 } 8628 8629 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 8630 LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), apache_tdm->tdm_bw)); 8631 LOG_CLI((BSL_META_U(unit, "ovs state: %d\n"), 8632 apache_tdm->is_oversub)); 8633 } 8634 8635 8636 rv = tdm_ap_set_iarb_tdm(apache_tdm->tdm_bw, 8637 apache_tdm->is_oversub, 8638 &apache_tdm->iarb_tdm_wrap_ptr, 8639 apache_tdm->iarb_tdm); 8640 8641 if (rv == 0) { 8642 LOG_CLI((BSL_META_U(unit, 8643 "Unsupported config for TDM calendar generation\n"))); 8644 return SOC_E_FAIL; 8645 } 8646 8647 if ((LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO))) { 8648 LOG_CLI((BSL_META_U(unit, 8649 "iarb_tdm: (wrap_ptr %d)"), 8650 apache_tdm->iarb_tdm_wrap_ptr)); 8651 for (index = 0; index < APACHE_IARB_TDM_LENGTH; index++) { 8652 if (index > apache_tdm->iarb_tdm_wrap_ptr) { 8653 break; 8654 } 8655 if (index % 16 == 0) { 8656 LOG_CLI((BSL_META_U(unit, "\n "))); 8657 } 8658 LOG_CLI((BSL_META_U(unit, " %3d"), 8659 apache_tdm->iarb_tdm[index])); 8660 } 8661 LOG_CLI((BSL_META_U(unit, "\n"))); 8662 } 8663 8664 return SOC_E_NONE; 8665 } 8666 8667 8668 STATIC int 8669 soc_apache_tdm_update(int unit, int init_time, int cur_cal, 8670 soc_apache_tdm_t *apache_tdm) 8671 { 8672 int rv; 8673 int count, slot; 8674 int pgw, pgw_inst, length; 8675 int pgw_hsp_config_index[APACHE_PGWS_PER_DEV] = {0, 0}; 8676 int mmu_idle_port_ix = 0; 8677 int mmu_idle_ports[] = {76, 78, 79, 80}; /* IDLE MMU ports in Apache */ 8678 8679 soc_port_t port, phy_port, mmu_port; 8680 soc_port_t pgw_clp_ports[APACHE_PGWS_PER_DEV] = {29, 65}; 8681 8682 soc_mem_t mem; 8683 soc_reg_t reg, hsp_reg; 8684 soc_field_t field, cal_end_f, cal_end_single_f, lr_tdm_wrap_f, hsp_fields[2]; 8685 es_pipe0_tdm_table_0_entry_t entry; 8686 8687 uint32 rval, hsp_values[2]; 8688 uint64 rval64, ctrl_rval64; 8689 8690 soc_info_t *si; 8691 8692 int index, group, weight, wt_group; 8693 int speed_class, speed_group, speed; 8694 uint32 wt_group_select = 0; 8695 uint32 same_spacing = 0; 8696 uint32 speed_spacing = 0; 8697 8698 8699 si = &SOC_INFO(unit); 8700 8701 /* Configure PGW TDM for APACHE */ 8702 for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) { 8703 8704 /* coverity[negative_returns : FALSE] */ 8705 if (!SOC_INFO(unit).block_valid[PGW_CL_BLOCK(unit, pgw)]) { 8706 continue; 8707 } 8708 8709 pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK; 8710 8711 rv = soc_reg_get(unit, ap_tdm_pgw_ctrl, pgw_inst, 0, &ctrl_rval64); 8712 SOC_IF_ERROR_RETURN(rv); 8713 8714 /* Configure PGW line rate ports TDM */ 8715 count = 0; 8716 COMPILER_64_ZERO(rval64); 8717 8718 for (slot= 0; slot < APACHE_PGW_TDM_LENGTH; slot++) { 8719 8720 reg = APACHE_TDM_PGW_LR_REG(cur_cal, slot); 8721 field = APACHE_TDM_PGW_SLOT(slot); 8722 8723 phy_port = apache_tdm->pgw_tdm[pgw][slot]; 8724 8725 if (phy_port == NUM_EXT_PORTS) { 8726 phy_port = 0xff; 8727 if (slot % APACHE_PGW_TDM_SLOTS_PER_REG) { 8728 break; 8729 } 8730 } else { 8731 if (phy_port == OVS_TOKEN) { 8732 phy_port = 0x4b; 8733 } 8734 count++; 8735 } 8736 8737 8738 soc_reg64_field32_set(unit, reg, &rval64, field, phy_port); 8739 8740 APACHE_TDM_PGW_LOG(unit, "PGW LR TDM config", reg, field, phy_port); 8741 8742 if (((slot + 1) % APACHE_PGW_TDM_SLOTS_PER_REG) == 0) { 8743 8744 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64)); 8745 COMPILER_64_ZERO(rval64); 8746 } 8747 } 8748 8749 lr_tdm_wrap_f = (!cur_cal) ? LR_TDM_WRAP_PTRf : LR_TDM2_WRAP_PTRf; 8750 8751 if (count > 0) { 8752 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8753 lr_tdm_wrap_f, count - 1); 8754 } 8755 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8756 LR_TDM_SELf, cur_cal); 8757 /* Always set both LR_TDM_ENABLE and LR_TDM2_ENABLE. 8758 * Even when switching, we need to make sure the the current 8759 * calendar is active so that it services the slots until the 8760 * end of the calendar when it actually switches to the new one. 8761 */ 8762 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8763 LR_TDM_ENABLEf, 1); 8764 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8765 LR_TDM2_ENABLEf, 1); 8766 8767 /* Configure PGW oversubscription ports TDM */ 8768 count = 0; 8769 COMPILER_64_ZERO(rval64); 8770 8771 for (slot= 0; slot < APACHE_PGW_TDM_OVS_SIZE; slot++) { 8772 8773 reg = APACHE_TDM_PGW_OS_REG(slot); 8774 field = APACHE_TDM_PGW_SLOT(slot); 8775 8776 phy_port = apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][slot];; 8777 APACHE_TDM_PGW_LOG(unit, "PGW OS TDM config", reg, field, phy_port); 8778 8779 if (phy_port == NUM_EXT_PORTS) { 8780 phy_port = 0xff; 8781 } else { 8782 count++; 8783 } 8784 8785 soc_reg64_field32_set(unit, reg, &rval64, field, phy_port); 8786 8787 if (((slot + 1) % APACHE_PGW_TDM_SLOTS_PER_REG) == 0) { 8788 8789 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64)); 8790 COMPILER_64_ZERO(rval64); 8791 } 8792 } 8793 8794 /* Enable os_skip_cnt_arb_sel by default in Apache */ 8795 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8796 OS_SKIP_CNT_ARB_SELf, TRUE); 8797 8798 for (phy_port = pgw_clp_ports[pgw]; 8799 phy_port < pgw_clp_ports[pgw] + (APACHE_NUM_CLP_PER_PGW * APACHE_PORTS_PER_TSC); 8800 phy_port++) 8801 { 8802 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 8803 hsp_reg = pgw_hsp_config_regs[pgw_hsp_config_index[pgw]]; 8804 hsp_fields[0] = pgw_hsp_config_fields[pgw_hsp_config_index[pgw]]; 8805 hsp_fields[1] = ENTRIES_IN_CALf; 8806 8807 if ((port == -1) || !IS_OVERSUB_PORT(unit, port)) { 8808 hsp_values[0] = 0x0; 8809 hsp_values[1] = 0x0; 8810 } else { 8811 hsp_values[0] = phy_port; 8812 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(SOC_INFO(unit).port_speed_max[port]); 8813 hsp_values[1] = speed < 10000 ? 1 : ((speed + 5000) / 10000) ; 8814 } 8815 rv = soc_reg_fields32_modify(unit, hsp_reg, pgw_inst, 8816 2, hsp_fields, hsp_values); 8817 SOC_IF_ERROR_RETURN(rv); 8818 pgw_hsp_config_index[pgw] += 1; 8819 } 8820 8821 /* OS_TDM_WRAP_PTR and OS_TDM_ENABLE programming */ 8822 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8823 OS_TDM_WRAP_PTRf, (count - 1)); 8824 soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64, 8825 OS_TDM_ENABLEf, count ? 1 : 0); 8826 8827 /* Configure PGW oversubscription port spacing */ 8828 COMPILER_64_ZERO(rval64); 8829 for (slot= 0; slot < APACHE_PGW_TDM_OVS_SIZE; slot++) { 8830 8831 reg = APACHE_TDM_PGW_OS_SPACING_REG(slot); 8832 field = APACHE_TDM_PGW_OS_SPACING_FIELD(slot); 8833 8834 phy_port = apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][slot]; 8835 APACHE_TDM_PGW_LOG(unit, "PGW OS Spacing config", reg, field, phy_port); 8836 8837 soc_reg64_field32_set(unit, reg, &rval64, field, phy_port); 8838 8839 if (((slot + 1) % APACHE_PGW_TDM_SLOTS_PER_REG) == 0) { 8840 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64)); 8841 COMPILER_64_ZERO(rval64); 8842 } 8843 } 8844 8845 8846 rv = soc_reg_set(unit, ap_tdm_pgw_ctrl, pgw_inst, 0, ctrl_rval64); 8847 SOC_IF_ERROR_RETURN(rv); 8848 } 8849 8850 8851 /* Configure MMU TDM */ 8852 mem = APACHE_TDM_MMU_TBL(cur_cal); 8853 8854 length = APACHE_MMU_TDM_LENGTH; 8855 while ((apache_tdm->mmu_tdm[length] == NUM_EXT_PORTS)) { 8856 length--; 8857 } 8858 8859 rv = soc_reg32_get(unit, ap_tdm_mmu_ctrl, REG_PORT_ANY, 0, &rval); 8860 SOC_IF_ERROR_RETURN(rv); 8861 8862 sal_memset(&entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32)); 8863 8864 for (slot = 0; slot <= length; slot++) { 8865 8866 phy_port = apache_tdm->mmu_tdm[slot]; 8867 8868 /* 8869 * TDM algo inserts CMIC, LB and ANC tokens for Auxillary 8870 * bandwidth in each TDM. ANC token needs to be replaced with 8871 * internal port 77 and CMIC & LB will be mapped to their mmu ports. 8872 * 8873 * Each TDM will also have a dedicated slot for guaranteed SBUS ops. 8874 * While the ANC slots can be used for SBUS as well, there could be 8875 * cases where the PRG (being of higher priority over SBUS) hogs SBUS 8876 * operations from getting handled. MMU port 81 will be programmed for 8877 * these tokens appearing in the algorithm. 8878 * 8879 * For unclaimed bandwidth (compared to max LR BW) from each config, 8880 * TDM algo inserts IDLE tokens. The idle tokens needs to be replaced 8881 * with internal mmu ports for Purge or SBUS operations. However, since 8882 * Hardware flags 1in4 violation errors even with these internal mmu 8883 * ports, we would iterate over all available internal ports (leaving out 8884 * ANC port - 77, of course). 8885 */ 8886 8887 if ((phy_port == SBUS_TOKEN)) { 8888 mmu_port = 81; /* Dedicated token for guaranteed SBUS ops */ 8889 } else if (phy_port == AUX_TOKEN) { 8890 mmu_port = 77; /* Dedicated ANC slot */ 8891 } else if(phy_port == IDL1_TOKEN) { 8892 /* iter over all available internal ports to avoid 1:4 violation */ 8893 mmu_port = mmu_idle_ports[mmu_idle_port_ix]; 8894 mmu_idle_port_ix = (mmu_idle_port_ix + 1) % COUNTOF(mmu_idle_ports); 8895 } else if (phy_port == OVS_TOKEN) { 8896 mmu_port = 75; /* Oversub port */ 8897 } else if (phy_port >= NUM_EXT_PORTS) { 8898 mmu_port = 0x7f; /* Invalid Port */ 8899 } else { 8900 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 8901 } 8902 8903 field = (slot % 2) ? PORT_NUM_ODDf : PORT_NUM_EVENf; 8904 if (mmu_port == -1) { 8905 return SOC_E_FAIL; 8906 } 8907 soc_mem_field32_set(unit, mem, &entry, field, mmu_port); 8908 8909 /* two slots in each entry; length can be odd too */ 8910 if ((slot % 2) || (slot == length)) { 8911 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 8912 (slot / 2), &entry)); 8913 } 8914 } 8915 8916 cal_end_f = (cur_cal) ? CAL1_ENDf : CAL0_ENDf; 8917 cal_end_single_f = (cur_cal) ? CAL1_END_SINGLEf : CAL0_END_SINGLEf; 8918 8919 /* 8920 * Examples: 8921 * 1) cal length = 401; cal_end = 401/2 - 0 = 200, cal_end_single = 1 8922 * 2) cal length = 402; cal_end = 402/2 - 1 = 200, cal_end_single = 0 8923 */ 8924 soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, cal_end_f, 8925 (slot % 2) ? (slot / 2): ((slot / 2) - 1)); 8926 if (slot % 2) { 8927 soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, cal_end_single_f, 1); 8928 } 8929 8930 soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, OPP_CPULB_ENf, 1); 8931 soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, ENABLEf, 1); 8932 soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, CURR_CALf, cur_cal); 8933 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ap_tdm_mmu_ctrl, REG_PORT_ANY, 0, rval)); 8934 8935 8936 rval = 0; 8937 for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) { 8938 speed_class = apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group]; 8939 reg = mmu_ovs_group_regs[group]; 8940 for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 8941 8942 phy_port = apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot]; 8943 if (phy_port >= NUM_EXT_PORTS) { 8944 mmu_port = 0x7f; 8945 } else { 8946 mmu_port = si->port_p2m_mapping[phy_port]; 8947 if (speed_class == 0) { 8948 speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]]; 8949 } 8950 } 8951 soc_reg_field_set(unit, reg, &rval, MMU_PORTf, (mmu_port & 0x7f)); 8952 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval)); 8953 } 8954 8955 if (SOC_FAILURE(_soc_apache_mmu_ovs_speed_class_map_get( 8956 unit, &speed_class, &speed_group, &speed_spacing))) { 8957 continue; 8958 } 8959 8960 if (init_time) { 8961 8962 for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 8963 if (APACHE_TDM_WT_GRP_USABLE(unit, wt_group, speed_group)) { 8964 APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 8965 break; 8966 } 8967 } 8968 8969 APACHE_TDM_WT_GRP_LOG(unit); 8970 8971 apache_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group; 8972 apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class; 8973 8974 } else { 8975 wt_group = apache_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group]; 8976 speed_class = apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group]; 8977 } 8978 8979 if (wt_group >= APACHE_MMU_OVS_WT_GROUP_COUNT) { 8980 return SOC_E_INTERNAL; 8981 } 8982 8983 /* Apache supports 4 oversub speeds only */ 8984 soc_reg_field_set(unit, ES_PIPE0_GRP_WT_SELECTr, &wt_group_select, 8985 ap_mmu_ovs_group_wt_select_fields[group], wt_group); 8986 reg = ES_PIPE0_OVR_SUB_GRP_CFGr; 8987 soc_reg_field_set(unit, reg, &same_spacing, SAME_SPACINGf, speed_spacing); 8988 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, group, same_spacing); 8989 SOC_IF_ERROR_RETURN(rv); 8990 8991 8992 } 8993 8994 for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 8995 8996 speed_class = APACHE_TDM_WT_GRP_SPEED_GET(unit, wt_group); 8997 if (speed_class == 0) { 8998 weight = 0x0; 8999 } else { 9000 /* use 2500M as weight unit */ 9001 weight = (speed_class > 2500 ? speed_class : 2500) / 2500; 9002 } 9003 reg = mmu_ovs_group_wt_regs[wt_group]; 9004 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval); 9005 SOC_IF_ERROR_RETURN(rv); 9006 9007 /* The proportional weights are already programmed */ 9008 if (soc_reg_field_get(unit, reg, rval, WEIGHTf) == weight) { 9009 continue; 9010 } 9011 9012 for (index = 0; index < APACHE_MMU_OVS_GROUP_TDM_LENGTH; index++) { 9013 soc_reg_field_set(unit, reg, &rval, WEIGHTf, (weight * (index + 1))); 9014 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, index, rval)); 9015 } 9016 } 9017 9018 9019 reg = ES_PIPE0_GRP_WT_SELECTr; 9020 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, wt_group_select); 9021 SOC_IF_ERROR_RETURN(rv); 9022 9023 9024 return SOC_E_NONE; 9025 } 9026 9027 STATIC int soc_ap_port_resource_tdm_calculate(int unit, soc_apache_tdm_t *tdm); 9028 9029 9030 STATIC int 9031 soc_apache_tdm_reinit(int unit) 9032 { 9033 soc_reg_t reg; 9034 int phy_port, mmu_port; 9035 int slot, group, wt_group, speed_group, speed_class; 9036 uint32 rval, wt_group_select, speed_spacing; 9037 9038 soc_apache_tdm_t *apache_tdm; 9039 soc_info_t *si = &SOC_INFO(unit); 9040 9041 reg = ES_PIPE0_TDM_CONFIGr; 9042 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 9043 APACHE_TDM_ACTIVE_CAL(unit) = soc_reg_field_get(unit, reg, rval, CURR_CALf); 9044 9045 apache_tdm = APACHE_TDM_STRUCT_ACTIVE(unit); 9046 9047 SOC_IF_ERROR_RETURN(soc_ap_port_resource_tdm_calculate(unit, apache_tdm)); 9048 9049 reg = ES_PIPE0_GRP_WT_SELECTr; 9050 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &wt_group_select)); 9051 9052 9053 for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) { 9054 speed_class = 0; 9055 speed_group = 0; 9056 reg = mmu_ovs_group_regs[group]; 9057 9058 wt_group = soc_reg_field_get(unit, ES_PIPE0_GRP_WT_SELECTr, wt_group_select, 9059 ap_mmu_ovs_group_wt_select_fields[group]); 9060 9061 for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 9062 9063 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, slot, &rval)); 9064 mmu_port = soc_reg_field_get(unit, reg, rval, MMU_PORTf); 9065 9066 if (mmu_port == 0x7f) { 9067 phy_port = NUM_EXT_PORTS; 9068 } else { 9069 phy_port = SOC_INFO(unit).port_m2p_mapping[mmu_port]; 9070 if (speed_class == 0) { 9071 speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]]; 9072 9073 if (SOC_FAILURE(_soc_apache_mmu_ovs_speed_class_map_get( 9074 unit, &speed_class, &speed_group, &speed_spacing))) { 9075 continue; 9076 } 9077 APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 9078 } 9079 } 9080 apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port; 9081 } 9082 APACHE_TDM_WT_GRP_LOG(unit); 9083 9084 apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class; 9085 apache_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group; 9086 } 9087 9088 return SOC_E_NONE; 9089 } 9090 9091 9092 STATIC int 9093 soc_apache_tdm_init(int unit) 9094 { 9095 soc_info_t *si; 9096 soc_pbmp_t pbmp; 9097 9098 int rv, index, cur_cal; 9099 int slot, port, phy_port, mmu_port; 9100 soc_apache_tdm_t *apache_tdm; 9101 9102 uint32 rval; 9103 uint32 entry[SOC_MAX_MEM_WORDS]; 9104 uint32 values[4]; 9105 soc_field_t fields[4]; 9106 9107 soc_mem_t mem; 9108 static const soc_mem_t iarb_tdm_mem = IARB_MAIN_TDMm; 9109 9110 cur_cal = APACHE_TDM_ACTIVE_CAL(unit); 9111 apache_tdm = APACHE_TDM_STRUCT_ACTIVE(unit); 9112 9113 sal_memset(apache_tdm, 0, sizeof(soc_apache_tdm_t)); 9114 9115 si = &SOC_INFO(unit); 9116 9117 PBMP_PORT_ITER(unit, port) { 9118 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 9119 continue; 9120 } 9121 phy_port = si->port_l2p_mapping[port]; 9122 9123 apache_tdm->speed[phy_port] = si->port_speed_max[port]; 9124 APACHE_TDM_SPEED_ADJUST(unit, port, apache_tdm->speed[phy_port]); 9125 9126 apache_tdm->port_state[phy_port] = 9127 IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE; 9128 9129 /* 9130 * Primary port will be setup as line-rate or oversub. 9131 * Subsequent physical ports (sister-ports) will be either 9132 * DISABLED or SUBPORT/COMBINED mode. 9133 * 9134 * TDM Algo expects lanes info based on speed. 9135 */ 9136 if (soc_apache_port_is_falcon(unit, phy_port)) { /* Falcons */ 9137 if (apache_tdm->speed[phy_port] > 25000) { 9138 apache_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 9139 } 9140 if (apache_tdm->speed[phy_port] > 50000) { 9141 apache_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 9142 apache_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 9143 } 9144 } else { /* Eagles */ 9145 if (apache_tdm->speed[phy_port] > 10000) { 9146 apache_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 9147 } 9148 if (apache_tdm->speed[phy_port] > 20000) { 9149 apache_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 9150 apache_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 9151 } 9152 if (apache_tdm->speed[phy_port] > 40000) { 9153 apache_tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT; 9154 apache_tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT; 9155 apache_tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT; 9156 apache_tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT; 9157 apache_tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT; 9158 apache_tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT; 9159 } 9160 } 9161 9162 } 9163 9164 /* CPU, LB and RDB ports */ 9165 apache_tdm->speed[0] = 1000; 9166 apache_tdm->speed[73] = 1000; 9167 apache_tdm->speed[74] = 1000; 9168 9169 apache_tdm->tdm_bw = si->bandwidth / 1000; 9170 9171 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 9172 SOC_PBMP_AND(pbmp, si->xpipe_pbm); 9173 9174 /* tell tdm code the device is oversub if any ports is oversub */ 9175 apache_tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp); 9176 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 9177 9178 for (slot = 0; slot <= APACHE_MMU_TDM_LENGTH; slot++) { 9179 apache_tdm->mmu_tdm[slot] = NUM_EXT_PORTS; 9180 } 9181 9182 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 9183 LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), apache_tdm->tdm_bw)); 9184 LOG_CLI((BSL_META_U(unit, "port speed:"))); 9185 for (index = 0; index < NUM_EXT_PORTS; index++) { 9186 if (index % 8 == 0) { 9187 LOG_CLI((BSL_META_U(unit, "\n "))); 9188 } 9189 LOG_CLI((BSL_META_U(unit, " %06d(%03d)"), 9190 apache_tdm->speed[index], index)); 9191 } 9192 LOG_CLI((BSL_META_U(unit, "\n"))); 9193 LOG_CLI((BSL_META_U(unit, "port state map:"))); 9194 for (index = 0; index < NUM_EXT_PORTS; index++) { 9195 if (index % 8 == 0) { 9196 LOG_CLI((BSL_META_U(unit, "\n "))); 9197 } 9198 if (index == 0 || index == (NUM_EXT_PORTS - 1)) { 9199 LOG_CLI((BSL_META_U(unit, " --------"))); 9200 } else { 9201 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"), 9202 apache_tdm->port_state[index], index)); 9203 } 9204 } 9205 LOG_CLI((BSL_META_U(unit, "\n"))); 9206 } 9207 9208 9209 SOC_IF_ERROR_RETURN(soc_apache_tdm_calc(unit, apache_tdm)); 9210 9211 SOC_IF_ERROR_RETURN(soc_apache_tdm_update(unit, 1, cur_cal, apache_tdm)); 9212 9213 9214 /* Configure IARB TDM */ 9215 mem = iarb_tdm_mem; 9216 sal_memset(entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32)); 9217 for (slot = 0; slot < APACHE_IARB_TDM_LENGTH; slot++) { 9218 if (slot > apache_tdm->iarb_tdm_wrap_ptr) { 9219 break; 9220 } 9221 if (apache_tdm->iarb_tdm[slot] > 0x7) { 9222 LOG_ERROR(BSL_LS_SOC_COMMON, 9223 (BSL_META_U(unit, 9224 "Invalid IARB TDM slot(%d) = %d !!\n"), 9225 slot, apache_tdm->iarb_tdm[slot])); 9226 } 9227 soc_mem_field32_set(unit, mem, entry, TDM_SLOTf, 9228 apache_tdm->iarb_tdm[slot]); 9229 SOC_IF_ERROR_RETURN 9230 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, entry)); 9231 } 9232 9233 /* IARB_TDM_CONTROL */ 9234 fields[0] = TDM_WRAP_PTRf; 9235 values[0] = apache_tdm->iarb_tdm_wrap_ptr; 9236 fields[1] = DISABLEf; 9237 values[1] = 0; 9238 SOC_IF_ERROR_RETURN 9239 (soc_reg_fields32_modify(unit, IARB_TDM_CONTROLr, REG_PORT_ANY, 2, 9240 fields, values)); 9241 9242 /* IARB_OPP_SCH_CONTROL */ 9243 fields[0] = RDB_OPP_ENf; 9244 values[0] = 1; 9245 fields[1] = LB_OPP_ENf; 9246 values[1] = 1; 9247 SOC_IF_ERROR_RETURN 9248 (soc_reg_fields32_modify(unit, IARB_OPP_SCH_CONTROLr, REG_PORT_ANY, 2, 9249 fields, values)); 9250 rval = 0; 9251 soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_CFAP_FULL_DROP_ENf, 1); 9252 soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_FIFO_THRESHOLDf, 3); 9253 soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_HS_FIFO_THRESHOLDf, 13); 9254 SOC_IF_ERROR_RETURN(WRITE_ENQ_CONFIGr(unit, rval)); 9255 9256 9257 fields[0] = FIELD_Af; 9258 values[0] = 1023; 9259 fields[1] = FIELD_Bf; 9260 values[1] = 9215; 9261 fields[2] = FIELD_Cf; 9262 values[2] = 16; 9263 rv = soc_reg_fields32_modify(unit, EGR_FORCE_SAF_CONFIGr, REG_PORT_ANY, 3, fields, values); 9264 SOC_IF_ERROR_RETURN(rv); 9265 9266 fields[0] = FIELD_Af; 9267 values[0] = 1; 9268 fields[1] = DI_ACT_THRf; 9269 values[1] = 20; 9270 rv = soc_reg_fields32_modify(unit, ES_PIPE0_MMU_1DBG_Cr, REG_PORT_ANY, 2, fields, values); 9271 SOC_IF_ERROR_RETURN(rv); 9272 9273 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_DI_THRr, REG_PORT_ANY, OS_SLT_LMTf, 1000); 9274 SOC_IF_ERROR_RETURN(rv); 9275 9276 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_1r, REG_PORT_ANY, FIELD_Bf, 0); 9277 SOC_IF_ERROR_RETURN(rv); 9278 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_0r, REG_PORT_ANY, 9279 FIELD_Af, (si->frequency * 200)); 9280 SOC_IF_ERROR_RETURN(rv); 9281 9282 9283 /* values array for filling mmu_1dbg_a regs */ 9284 values[0] = values[1] = values[2] = 0; 9285 9286 PBMP_PORT_ITER(unit, port) { 9287 9288 phy_port = si->port_l2p_mapping[port]; 9289 if (phy_port == -1 ) { 9290 continue; 9291 } 9292 mmu_port = si->port_p2m_mapping[phy_port]; 9293 if (mmu_port == -1) { 9294 continue; 9295 } 9296 9297 SOC_IF_ERROR_RETURN(soc_ap_mmu_delay_insertion_set(unit, port)); 9298 9299 9300 if (IS_OVERSUB_PORT(unit, port)) { 9301 9302 rval = ((si->port_speed_max[port] / 1000) * 9303 (12148125 / (si->frequency * 100))); 9304 rv = soc_mem_field32_modify(unit, EDB_1DBG_Bm, phy_port, FIELD_Bf, rval); 9305 SOC_IF_ERROR_RETURN(rv); 9306 9307 if (mmu_port < 32) { /* mmu_port in [0, 32) */ 9308 values[0] |= (1 << mmu_port); 9309 } else if (mmu_port < 64) { /* mmu_port in [32, 64) */ 9310 values[1] |= (1 << (mmu_port - 32)); 9311 } else { /* mmu_port in [64, 74) */ 9312 values[2] |= (1 << (mmu_port - 64)); 9313 } 9314 } 9315 } 9316 9317 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_1DBG_A_LOr, REG_PORT_ANY, FIELD_Af, values[0]); 9318 SOC_IF_ERROR_RETURN(rv); 9319 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_1DBG_A_MIDr, REG_PORT_ANY, FIELD_Af, values[1]); 9320 SOC_IF_ERROR_RETURN(rv); 9321 rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_1DBG_A_HIr, REG_PORT_ANY, FIELD_Af, values[2]); 9322 SOC_IF_ERROR_RETURN(rv); 9323 9324 return SOC_E_NONE; 9325 } 9326 9327 STATIC int 9328 _soc_apache_hash_init(int unit) 9329 { 9330 soc_field_t fields[4]; 9331 uint32 values[4]; 9332 9333 /* L2 dedicated banks */ 9334 fields[0] = BANK0_HASH_OFFSETf; 9335 values[0] = 0; /* CRC32_LOWER */ 9336 fields[1] = BANK1_HASH_OFFSETf; 9337 values[1] = 16; /* CRC32_UPPER */ 9338 SOC_IF_ERROR_RETURN 9339 (soc_reg_fields32_modify(unit, L2_TABLE_HASH_CONTROLr, REG_PORT_ANY, 2, 9340 fields, values)); 9341 9342 /* L3 dedicated banks */ 9343 fields[0] = BANK6_HASH_OFFSETf; 9344 values[0] = 0; /* CRC32_LOWER */ 9345 fields[1] = BANK7_HASH_OFFSETf; 9346 values[1] = 12; /* CRC32 >> 12 */ 9347 fields[2] = BANK8_HASH_OFFSETf; 9348 values[2] = 24; /* CRC16_LOWER << 8 | CRC32 >> 24 */ 9349 fields[3] = BANK9_HASH_OFFSETf; 9350 values[3] = 36; /* CRC16 >> 4 */ 9351 SOC_IF_ERROR_RETURN 9352 (soc_reg_fields32_modify(unit, L3_TABLE_HASH_CONTROLr, REG_PORT_ANY, 4, 9353 fields, values)); 9354 9355 /* L2/L3/ALPM shared banks */ 9356 fields[0] = BANK2_HASH_OFFSETf; 9357 values[0] = 4; /* CRC32 >> 4 */ 9358 fields[1] = BANK3_HASH_OFFSETf; 9359 values[1] = 12; /* CRC32 >> 12 */ 9360 fields[2] = BANK4_HASH_OFFSETf; 9361 values[2] = 20; /* CRC32 >> 20 */ 9362 fields[3] = BANK5_HASH_OFFSETf; 9363 values[3] = 24; /* CRC32 >> 24 */ 9364 SOC_IF_ERROR_RETURN 9365 (soc_reg_fields32_modify(unit, SHARED_TABLE_HASH_CONTROLr, 9366 REG_PORT_ANY, 4, fields, values)); 9367 9368 #ifdef SOC_ROBUST_HASH 9369 /* Robust Hash initialization */ 9370 if (soc_feature(unit, soc_feature_robust_hash)) { 9371 uint32 value, seed = 0; 9372 9373 if (NULL == ROBUSTHASH(unit)) { 9374 ROBUSTHASH(unit) = sal_alloc(sizeof(soc_robust_hash_db_t), 9375 "soc_robust_hash"); 9376 if (ROBUSTHASH(unit) == NULL) { 9377 return SOC_E_MEMORY; 9378 } 9379 sal_memset(ROBUSTHASH(unit), 0, sizeof(soc_robust_hash_db_t)); 9380 } 9381 9382 /* Enable Robust hashing for ING_VP_VLAN_MEMBERSHIP table and configure 9383 * corresponding remap and action tables. 9384 */ 9385 9386 if ((soc_property_get(unit, "robust_hash_disable_ing_vp_vlan", 0)) == 1) 9387 { 9388 /* Disable robust hashing */ 9389 SOC_IF_ERROR_RETURN 9390 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value)); 9391 soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, 9392 &value, ROBUST_HASH_ENABLEf, 0x0); 9393 SOC_IF_ERROR_RETURN 9394 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value)); 9395 9396 ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 0; 9397 } else { 9398 /* Enable robust hashing */ 9399 SOC_IF_ERROR_RETURN 9400 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value)); 9401 soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, 9402 &value, ROBUST_HASH_ENABLEf, 0x1); 9403 SOC_IF_ERROR_RETURN 9404 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value)); 9405 ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 1; 9406 9407 /* Fill action and remap tables with random data */ 9408 ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[0] = 9409 ING_VP_VLAN_MEMBERSHIP_REMAP_Am; 9410 ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[1] = 9411 ING_VP_VLAN_MEMBERSHIP_REMAP_Bm; 9412 ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[0] = 9413 ING_VP_VLAN_MEMBERSHIP_ACTION_Am; 9414 ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[1] = 9415 ING_VP_VLAN_MEMBERSHIP_ACTION_Bm; 9416 9417 seed = soc_property_get(unit, 9418 spn_ROBUST_HASH_SEED_INGRESS_VP_VLAN, 9419 16777213); 9420 9421 SOC_IF_ERROR_RETURN 9422 (soc_robust_hash_table_set(unit, 9423 &(ROBUSTHASH(unit)->ing_vp_vlan_member), 9424 seed)); 9425 } 9426 9427 /* Enable Robust hashing for EGR_VP_VLAN_MEMBERSHIP table and configure 9428 * corresponding remap and action tables. 9429 */ 9430 9431 if ((soc_property_get(unit, "robust_hash_disable_egr_vp_vlan", 0)) == 1) 9432 { 9433 /* Disable robust hashing */ 9434 SOC_IF_ERROR_RETURN 9435 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value)); 9436 soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, 9437 &value, ROBUST_HASH_ENABLEf, 0x0); 9438 SOC_IF_ERROR_RETURN 9439 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value)); 9440 9441 ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 0; 9442 } else { 9443 /* Enable robust hashing */ 9444 SOC_IF_ERROR_RETURN 9445 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value)); 9446 soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, 9447 &value, ROBUST_HASH_ENABLEf, 0x1); 9448 SOC_IF_ERROR_RETURN 9449 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value)); 9450 ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 1; 9451 9452 /* Fill action and remap tables with random data */ 9453 ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[0] = 9454 EGR_VP_VLAN_MEMBERSHIP_REMAP_Am; 9455 ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[1] = 9456 EGR_VP_VLAN_MEMBERSHIP_REMAP_Bm; 9457 ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[0] = 9458 EGR_VP_VLAN_MEMBERSHIP_ACTION_Am; 9459 ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[1] = 9460 EGR_VP_VLAN_MEMBERSHIP_ACTION_Bm; 9461 9462 seed = soc_property_get(unit, 9463 spn_ROBUST_HASH_SEED_EGRESS_VP_VLAN, 9464 16777213); 9465 9466 SOC_IF_ERROR_RETURN 9467 (soc_robust_hash_table_set(unit, 9468 &(ROBUSTHASH(unit)->egr_vp_vlan_member), 9469 seed)); 9470 } 9471 } 9472 #endif /* SOC_ROBUST_HASH */ 9473 9474 return SOC_E_NONE; 9475 } 9476 9477 #define PORTS_PER_LED_CHAIN 36 9478 STATIC int 9479 soc_apache_ledup_init(int unit) 9480 { 9481 #if defined(BCM_56560_B0) 9482 uint32 rval = 0, ix; 9483 soc_info_t *si; 9484 uint8 remap_value[SOC_MAX_NUM_PORTS]; 9485 int phy_port; 9486 9487 si = &SOC_INFO(unit); 9488 /* configure the LED scan delay cycles */ 9489 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval)); 9490 soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 0xd); 9491 soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 4); 9492 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval)); 9493 9494 SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP1_CTRLr(unit, &rval)); 9495 soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 0xb); 9496 soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 4); 9497 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_CTRLr(unit, rval)); 9498 9499 for (ix = 0; ix < PORTS_PER_LED_CHAIN; ix++) { 9500 /* Chain 0: Phy Ports 1-36 9501 * LED HW Status arrives descending order to CMIC 9502 * i.e Status for Port 36 comes first and for Port 1 last 9503 */ 9504 phy_port = PORTS_PER_LED_CHAIN - ix; 9505 if (si->port_p2l_mapping[phy_port] == -1) { 9506 remap_value[ix] = 0; 9507 } else { 9508 remap_value[ix] = phy_port; 9509 } 9510 9511 /* Chain 1 Phy Ports 37-72 9512 * LED HW Status arrives descending order to CMIC 9513 * i.e Status for Port 72 comes first and for Port 37 last 9514 */ 9515 if (si->port_p2l_mapping[phy_port + PORTS_PER_LED_CHAIN] == -1) { 9516 remap_value[ix + PORTS_PER_LED_CHAIN] = 0; 9517 } else { 9518 remap_value[ix + PORTS_PER_LED_CHAIN] = phy_port; 9519 } 9520 } 9521 9522 /* Configure LED Port remap registers */ 9523 ix = 0; 9524 rval = 0; 9525 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_0f, remap_value[ix++]); 9526 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_1f, remap_value[ix++]); 9527 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_2f, remap_value[ix++]); 9528 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_3f, remap_value[ix++]); 9529 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval)); 9530 9531 rval = 0; 9532 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_4f, remap_value[ix++]); 9533 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_5f, remap_value[ix++]); 9534 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_6f, remap_value[ix++]); 9535 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_7f, remap_value[ix++]); 9536 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval)); 9537 9538 rval = 0; 9539 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_8f, remap_value[ix++]); 9540 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_9f, remap_value[ix++]); 9541 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_10f, remap_value[ix++]); 9542 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_11f, remap_value[ix++]); 9543 /* coverity[result_independent_of_operands] */ 9544 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval)); 9545 9546 rval = 0; 9547 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_12f, remap_value[ix++]); 9548 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_13f, remap_value[ix++]); 9549 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_14f, remap_value[ix++]); 9550 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_15f, remap_value[ix++]); 9551 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval)); 9552 9553 rval = 0; 9554 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_16f, remap_value[ix++]); 9555 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_17f, remap_value[ix++]); 9556 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_18f, remap_value[ix++]); 9557 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_19f, remap_value[ix++]); 9558 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval)); 9559 9560 rval = 0; 9561 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_20f, remap_value[ix++]); 9562 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_21f, remap_value[ix++]); 9563 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_22f, remap_value[ix++]); 9564 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_23f, remap_value[ix++]); 9565 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval)); 9566 9567 rval = 0; 9568 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_24f, remap_value[ix++]); 9569 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_25f, remap_value[ix++]); 9570 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_26f, remap_value[ix++]); 9571 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_27f, remap_value[ix++]); 9572 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval)); 9573 9574 rval = 0; 9575 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_28f, remap_value[ix++]); 9576 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_29f, remap_value[ix++]); 9577 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_30f, remap_value[ix++]); 9578 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_31f, remap_value[ix++]); 9579 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval)); 9580 9581 rval = 0; 9582 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_32f, remap_value[ix++]); 9583 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_33f, remap_value[ix++]); 9584 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_34f, remap_value[ix++]); 9585 soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_35f, remap_value[ix++]); 9586 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval)); 9587 9588 9589 /* Configure LED Port remap registers - LED uP1*/ 9590 rval = 0; 9591 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_0f, remap_value[ix++]); 9592 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_1f, remap_value[ix++]); 9593 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_2f, remap_value[ix++]); 9594 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_3f, remap_value[ix++]); 9595 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r(unit, rval)); 9596 9597 rval = 0; 9598 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_4f, remap_value[ix++]); 9599 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_5f, remap_value[ix++]); 9600 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_6f, remap_value[ix++]); 9601 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_7f, remap_value[ix++]); 9602 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r(unit, rval)); 9603 9604 rval = 0; 9605 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_8f, remap_value[ix++]); 9606 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_9f, remap_value[ix++]); 9607 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_10f, remap_value[ix++]); 9608 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_11f, remap_value[ix++]); 9609 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r(unit, rval)); 9610 9611 rval = 0; 9612 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_12f, remap_value[ix++]); 9613 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_13f, remap_value[ix++]); 9614 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_14f, remap_value[ix++]); 9615 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_15f, remap_value[ix++]); 9616 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r(unit, rval)); 9617 9618 rval = 0; 9619 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_16f, remap_value[ix++]); 9620 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_17f, remap_value[ix++]); 9621 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_18f, remap_value[ix++]); 9622 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_19f, remap_value[ix++]); 9623 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r(unit, rval)); 9624 9625 rval = 0; 9626 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_20f, remap_value[ix++]); 9627 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_21f, remap_value[ix++]); 9628 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_22f, remap_value[ix++]); 9629 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_23f, remap_value[ix++]); 9630 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r(unit, rval)); 9631 9632 rval = 0; 9633 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_24f, remap_value[ix++]); 9634 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_25f, remap_value[ix++]); 9635 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_26f, remap_value[ix++]); 9636 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_27f, remap_value[ix++]); 9637 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r(unit, rval)); 9638 9639 rval = 0; 9640 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_28f, remap_value[ix++]); 9641 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_29f, remap_value[ix++]); 9642 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_30f, remap_value[ix++]); 9643 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_31f, remap_value[ix++]); 9644 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r(unit, rval)); 9645 9646 rval = 0; 9647 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_32f, remap_value[ix++]); 9648 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_33f, remap_value[ix++]); 9649 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_34f, remap_value[ix++]); 9650 soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_35f, remap_value[ix++]); 9651 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r(unit, rval)); 9652 9653 9654 /* initialize the UP0, UP1 data ram */ 9655 rval = 0; 9656 for (ix = 0; ix < 256; ix++) { 9657 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval)); 9658 SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_DATA_RAMr(unit,ix, rval)); 9659 } 9660 9661 #endif 9662 return SOC_E_NONE; 9663 } 9664 9665 #if defined(SER_TR_TEST_SUPPORT) 9666 soc_ser_test_functions_t ser_apache_test_fun; 9667 #endif 9668 9669 STATIC int 9670 _soc_apache_egr_buf_reset(int unit, int port, int reset) 9671 { 9672 uint32 entry[SOC_MAX_MEM_WORDS]; 9673 9674 SOC_IF_ERROR_RETURN( 9675 READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 9676 port, entry)); 9677 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 9678 entry, ENABLEf, reset); 9679 SOC_IF_ERROR_RETURN( 9680 WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 9681 port, entry)); 9682 9683 return SOC_E_NONE; 9684 } 9685 9686 STATIC int 9687 _soc_portctrl_apache_port_init(int unit) 9688 { 9689 soc_info_t *si; 9690 int port; 9691 int blk; 9692 int pgw_inst; 9693 9694 si = &SOC_INFO(unit); 9695 9696 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CXXPORT) { 9697 port = SOC_BLOCK_PORT(unit, blk); 9698 if (port == -1) { 9699 continue; 9700 } 9701 9702 /* If this is a 100G port, reset egress port buffer */ 9703 if (si->port_speed_max[port] >= 100000) { 9704 SOC_IF_ERROR_RETURN(_soc_apache_egr_buf_reset(unit, port, 1)); 9705 9706 SOC_IF_ERROR_RETURN(soc_apache_port_speed_update(unit, port, si->port_speed_max[port])); 9707 9708 SOC_IF_ERROR_RETURN(_soc_apache_egr_buf_reset(unit, port, 0)); 9709 9710 pgw_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK; 9711 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, PGW_ETM_MODEr, pgw_inst, ETM_PORT_EN_CONFIGf, 1)); 9712 } 9713 } 9714 9715 /* Cut through settings for all ports */ 9716 PBMP_ALL_ITER(unit, port) { 9717 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 9718 continue; 9719 } 9720 9721 SOC_IF_ERROR_RETURN(soc_apache_port_asf_set(unit, port, si->port_speed_max[port])); 9722 } 9723 9724 return SOC_E_NONE; 9725 } 9726 9727 9728 /* 9729 * Function: 9730 * soc_apache_idb_buf_reset 9731 * Purpose: 9732 * Poll until Cell Assembly and OBM buffers are empty. 9733 * Parameters: 9734 * unit - (IN) Unit number. 9735 * port - (IN) Logical SOC port number. 9736 * reset - (IN) Reset. 9737 * Returns: 9738 * SOC_E_XXX 9739 */ 9740 int 9741 soc_apache_idb_buf_reset(int unit, soc_port_t port, int reset) 9742 { 9743 soc_info_t *si = &SOC_INFO(unit); 9744 soc_reg_t reg; 9745 soc_field_t field; 9746 uint64 rval64; 9747 int phy_port, port_index, xlp, pgw, obm, pgw_inst; 9748 soc_timeout_t to; 9749 int use_count, fifo_empty; 9750 int wait_time = 250000; 9751 9752 static const soc_reg_t pgw_obm_use_counter_regs[] = { 9753 IDB_OBM0_USAGEr, IDB_OBM1_USAGEr, IDB_OBM2_USAGEr, 9754 IDB_OBM3_USAGEr, IDB_OBM4_USAGEr, IDB_OBM5_USAGEr, 9755 IDB_OBM6_USAGEr, IDB_OBM7_USAGEr, IDB_OBM8_USAGEr 9756 }; 9757 static const soc_reg_t obm_ctrl_regs[] = { 9758 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, IDB_OBM2_CONTROLr, 9759 IDB_OBM3_CONTROLr, IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 9760 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, IDB_OBM8_CONTROLr 9761 }; 9762 static const soc_reg_t obm_ca_ctrl_regs[] = { 9763 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr, 9764 IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 9765 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, IDB_OBM8_CA_CONTROLr 9766 }; 9767 static const soc_field_t port_reset_fields[] = { 9768 PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf 9769 }; 9770 9771 9772 if (SAL_BOOT_QUICKTURN) { 9773 wait_time *= 20; 9774 wait_time *= 3; 9775 } 9776 9777 /* Get physical port PGW information */ 9778 phy_port = si->port_l2p_mapping[port]; 9779 pgw = si->port_group[port]; 9780 xlp = si->port_serdes[port]; 9781 port_index = (phy_port - 1) % 4; 9782 9783 obm = xlp % APACHE_TSCS_PER_PGW; 9784 pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK; 9785 9786 /* Assume values returned above are valid */ 9787 reg = pgw_obm_use_counter_regs[obm]; 9788 field = TOTAL_COUNTf; 9789 9790 if (reset && (!SAL_BOOT_BCMSIM)) { 9791 /* Poll until Cell Assembly and OBM buffers are empty */ 9792 soc_timeout_init(&to, wait_time, 0); 9793 for (;;) { 9794 /* Get PGW use counter */ 9795 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, port_index, &rval64)); 9796 use_count = soc_reg64_field32_get(unit, reg, rval64, field); 9797 9798 /* Get PGW fifo empty flag */ 9799 SOC_IF_ERROR_RETURN(READ_PGW_BOD_STATUS1r(unit, port, &rval64)); 9800 fifo_empty = soc_reg64_field32_get(unit, PGW_BOD_STATUS1r, 9801 rval64, PGW_BOD_FIFO_EMPTYf); 9802 9803 LOG_INFO(BSL_LS_SOC_PORT, 9804 (BSL_META_U(unit, 9805 "PGW/OBM buffer reset : port %d, %s (log=%d phy=%d), " 9806 "subport: %d tsc: %d obm:%d pgw: %d" 9807 "(use_count: %d) " 9808 "(pgw_bod_fifo_emty:%d)\n"), 9809 unit, SOC_PORT_NAME(unit, port), port, phy_port, 9810 port_index, xlp, obm, pgw, 9811 use_count, fifo_empty)); 9812 9813 if ((use_count == 0) && (fifo_empty == 1)) { 9814 break; 9815 } 9816 9817 if (soc_timeout_check(&to)) { 9818 LOG_ERROR(BSL_LS_SOC_PORT, 9819 (BSL_META_U(unit, 9820 "PGW/OBM buffer reset timeout: port %d, %s, " 9821 "timeout (use_count: %d) " 9822 "(pgw_bod_fifo_emty:%d)\n"), 9823 unit, SOC_PORT_NAME(unit, port), 9824 use_count, fifo_empty)); 9825 return SOC_E_INTERNAL; 9826 } 9827 } 9828 } 9829 9830 reg = obm_ctrl_regs[obm]; 9831 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst, 9832 port_reset_fields[port_index], reset)); 9833 9834 reg = obm_ca_ctrl_regs[obm]; 9835 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst, 9836 port_reset_fields[port_index], reset)); 9837 9838 return SOC_E_NONE; 9839 } 9840 9841 STATIC int 9842 _soc_apache_port_credit_size_get(int unit, soc_port_t port, int *ep_credit_size) 9843 { 9844 int speed; 9845 uint32 cl91_enabled; 9846 9847 speed = SOC_INFO(unit).port_speed_max[port]; 9848 9849 SOC_IF_ERROR_RETURN(soc_apache_port_cl91_status_get(unit, port, &cl91_enabled)); 9850 9851 if (soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) { 9852 if (speed <= 11000) { 9853 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 7 : 11; 9854 } else if (speed <= 27000) { 9855 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 11 : (cl91_enabled ? 18 : 16); 9856 } else if (speed <= 42000) { 9857 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 21 : 20; 9858 } else if (speed <= 53000) { 9859 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 17 : (cl91_enabled ? 25 : 23); 9860 } else { 9861 *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 30 : 39; 9862 } 9863 } 9864 9865 return SOC_E_NONE; 9866 } 9867 9868 /* 9869 * Function: 9870 * _soc_apache_mmu_ep_credit_set 9871 * Purpose: 9872 * Initalize EP credits in MMU so EP is in charge 9873 * of distributing the correct number of credits. 9874 * Parameters: 9875 * unit - (IN) Unit number. 9876 * port - (IN) Logical SOC port number. 9877 * Returns: 9878 * SOC_E_XXX 9879 */ 9880 STATIC int 9881 _soc_apache_mmu_ep_credit_set(int unit, soc_port_t port) 9882 { 9883 soc_info_t *si = &SOC_INFO(unit); 9884 int phy_port; 9885 int mmu_port; 9886 int ep_credit_size = 0; 9887 soc_reg_t reg; 9888 uint32 rval; 9889 9890 /* Get physical port */ 9891 phy_port = si->port_l2p_mapping[port]; 9892 if (phy_port == -1) { 9893 return SOC_E_INTERNAL; 9894 } 9895 9896 /* Get MMU port */ 9897 mmu_port = si->port_p2m_mapping[phy_port]; 9898 if (mmu_port == -1) { 9899 return SOC_E_INTERNAL; 9900 } 9901 9902 /* Wait until credits are initialised at non-optimum value 9903 * EP passes MMU 1 credit per cycle, so worse case delay is 95 cycles after EGR_ENABLE is set. 9904 * @793.75MHz, this is ~120ns. 9905 */ 9906 sal_usleep(1); 9907 9908 reg = ES_PIPE0_MMU_PORT_CREDITr; 9909 9910 SOC_IF_ERROR_RETURN(_soc_apache_port_credit_size_get(unit, port, &ep_credit_size)); 9911 SOC_IF_ERROR_RETURN 9912 (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval)); 9913 soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, ep_credit_size); 9914 SOC_IF_ERROR_RETURN 9915 (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 9916 9917 return SOC_E_NONE; 9918 } 9919 9920 /* 9921 * Function: 9922 * _soc_apache_mmu_ep_credit_reset 9923 * Purpose: 9924 * Reset EP credits in MMU 9925 * Parameters: 9926 * unit - (IN) Unit number. 9927 * port - (IN) Logical SOC port number. 9928 * Returns: 9929 * SOC_E_XXX 9930 */ 9931 STATIC int 9932 _soc_apache_mmu_ep_credit_reset(int unit, soc_port_t port) 9933 { 9934 soc_info_t *si = &SOC_INFO(unit); 9935 int phy_port; 9936 int mmu_port; 9937 soc_reg_t reg; 9938 uint32 rval; 9939 9940 /* Get physical port */ 9941 phy_port = si->port_l2p_mapping[port]; 9942 if (phy_port == -1) { 9943 return SOC_E_INTERNAL; 9944 } 9945 9946 /* Get MMU port */ 9947 mmu_port = si->port_p2m_mapping[phy_port]; 9948 if (mmu_port == -1) { 9949 return SOC_E_INTERNAL; 9950 } 9951 9952 reg = ES_PIPE0_MMU_PORT_CREDITr; 9953 9954 SOC_IF_ERROR_RETURN 9955 (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval)); 9956 soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, 0); 9957 SOC_IF_ERROR_RETURN 9958 (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 9959 9960 return SOC_E_NONE; 9961 } 9962 9963 9964 /* 9965 * Function: 9966 * soc_apache_edb_buf_reset 9967 * Purpose: 9968 * Initialize EP credits in MMU, release EDB port buffer and 9969 * enable cell request in EP. 9970 * Parameters: 9971 * unit - (IN) Unit number. 9972 * port - (IN) Logical SOC port number. 9973 * reset - (IN) Reset. 9974 * Returns: 9975 * SOC_E_XXX 9976 */ 9977 int 9978 soc_apache_edb_buf_reset(int unit, soc_port_t port, int reset) 9979 { 9980 soc_info_t *si = &SOC_INFO(unit); 9981 uint32 entry[SOC_MAX_MEM_WORDS]; 9982 int phy_port; 9983 9984 /* Get physical port */ 9985 phy_port = si->port_l2p_mapping[port]; 9986 if (phy_port == -1) { 9987 return SOC_E_INTERNAL; 9988 } 9989 9990 if (reset) { 9991 /* 9992 * Hold EDB port buffer in reset state and disable cell 9993 * request generation in EP. 9994 */ 9995 SOC_IF_ERROR_RETURN 9996 (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 9997 phy_port, entry)); 9998 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 9999 entry, ENABLEf, 1); 10000 SOC_IF_ERROR_RETURN 10001 (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 10002 phy_port, entry)); 10003 SOC_IF_ERROR_RETURN 10004 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 10005 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 0); 10006 SOC_IF_ERROR_RETURN 10007 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 10008 10009 } else { 10010 10011 /* Initialize EP credits in MMU */ 10012 SOC_IF_ERROR_RETURN(_soc_apache_mmu_ep_credit_reset(unit, port)); 10013 10014 /* 10015 * Release EDB port buffer reset and 10016 * enable cell request generation in EP. 10017 */ 10018 SOC_IF_ERROR_RETURN 10019 (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 10020 phy_port, entry)); 10021 soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm, 10022 entry, ENABLEf, 0); 10023 SOC_IF_ERROR_RETURN 10024 (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL, 10025 phy_port, entry)); 10026 10027 SOC_IF_ERROR_RETURN 10028 (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 10029 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 10030 SOC_IF_ERROR_RETURN 10031 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 10032 10033 SOC_IF_ERROR_RETURN(_soc_apache_mmu_ep_credit_set(unit, port)); 10034 } 10035 10036 return SOC_E_NONE; 10037 } 10038 10039 int 10040 soc_apache_port_edb_config(int unit, int asf, soc_port_t port) 10041 { 10042 int rv; 10043 uint32 osct_pbm; 10044 uint64 tmp, lrct_pbm; 10045 soc_info_t *si; 10046 soc_port_t phy_port, mmu_port; 10047 int pm_id, pgw_inst, linerate; 10048 uint32 cl91_enabled; 10049 10050 soc_mem_t edb_mem = EGR_EDB_XMIT_CTRLm; 10051 soc_field_t edb_fields[3] = {START_CNTf, WAIT_FOR_MOPf, WAIT_FOR_2ND_MOPf}; 10052 uint32 edb_values[3] = {0}; 10053 10054 soc_reg_t asm_ct_thresh_reg = CELL_ASM_CUT_THRU_THRESHOLD0r; 10055 soc_field_t asm_ct_fields[APACHE_NUM_XLP_PER_PGW + APACHE_NUM_CLP_PER_PGW] = { 10056 XLP0_CELL_ASM_CUT_THRU_THRESHOLDf, 10057 XLP1_CELL_ASM_CUT_THRU_THRESHOLDf, 10058 XLP2_CELL_ASM_CUT_THRU_THRESHOLDf, 10059 XLP3_CELL_ASM_CUT_THRU_THRESHOLDf, 10060 XLP4_CELL_ASM_CUT_THRU_THRESHOLDf, 10061 XLP5_CELL_ASM_CUT_THRU_THRESHOLDf, 10062 XLP6_CELL_ASM_CUT_THRU_THRESHOLDf, 10063 CLP0_CELL_ASM_CUT_THRU_THRESHOLDf, 10064 CLP1_CELL_ASM_CUT_THRU_THRESHOLDf, 10065 }; 10066 int asm_ct_thresh; 10067 10068 si = &SOC_INFO(unit); 10069 10070 /* Remove extraneous ports from the input list */ 10071 SOC_IF_ERROR_RETURN(READ_ENQ_ASF_HS_OVERSUB_ENr(unit, &osct_pbm)); 10072 SOC_IF_ERROR_RETURN(READ_ENQ_ASF_LRCT_OVERSUB_ENr(unit, &lrct_pbm)); 10073 10074 phy_port = si->port_l2p_mapping[port]; 10075 mmu_port = si->port_p2m_mapping[phy_port]; 10076 pgw_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK; 10077 linerate = (!SOC_PBMP_MEMBER(si->oversub_pbm, port)); 10078 10079 SOC_IF_ERROR_RETURN(soc_apache_port_cl91_status_get(unit, port, &cl91_enabled)); 10080 10081 pm_id = ((phy_port - 1) / APACHE_PORTS_PER_TSC) % APACHE_TSCS_PER_PGW; 10082 if (pm_id < APACHE_NUM_XLP_PER_PGW) { /* Eagle Cores */ 10083 if (si->port_speed_max[port] <= 21000) { /* 0-21G */ 10084 edb_values[0] = (linerate) ? (asf ? 9 : 0) : (asf ? 0 : 5); 10085 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10086 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10087 10088 asm_ct_thresh = 6; 10089 } else if (si->port_speed_max[port] <= 42000) { /* 21G-42G */ 10090 edb_values[0] = (linerate) ? (asf ? 9 : 0) : (asf ? 18 : 9); 10091 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10092 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10093 10094 asm_ct_thresh = 6; 10095 } else { /* 42G or more (100G) */ 10096 edb_values[0] = (linerate) ? (asf ? 14 : 0) : (asf ? 0 : 4); 10097 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10098 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10099 10100 asm_ct_thresh = 6; 10101 } 10102 } else { /* Falcon Cores */ 10103 if (si->port_speed_max[port] <= 11000) { /* 0-11G */ 10104 edb_values[0] = (linerate) ? (asf ? 4 : 0) : (asf ? 0 : 4); 10105 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10106 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10107 10108 asm_ct_thresh = 6; 10109 } else if (si->port_speed_max[port] <= 27000) { /* 11G-27G */ 10110 edb_values[0] = (linerate) ? (asf ? (cl91_enabled ? 10 : 4) : 0) : (asf ? 0 : 4); 10111 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10112 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10113 10114 asm_ct_thresh = 6; 10115 } else if (si->port_speed_max[port] <= 42000) { /* 27G-42G */ 10116 edb_values[0] = (linerate) ? (asf ? 5 : 0) : (asf ? 7 : 4); 10117 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10118 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10119 10120 asm_ct_thresh = 6; 10121 } else if (si->port_speed_max[port] <= 53000) { /* 42G-53G */ 10122 edb_values[0] = (linerate) ? (asf ? (cl91_enabled ? 11 : 5) : 0) : (asf ? 0 : 4); 10123 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10124 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10125 10126 asm_ct_thresh = 6; 10127 } else { /* 53G-106G */ 10128 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 4); 10129 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0; 10130 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */ 10131 10132 asm_ct_thresh = 6; 10133 } 10134 } 10135 10136 rv = soc_mem_fields32_modify(unit, edb_mem, phy_port, 3, edb_fields, edb_values); 10137 SOC_IF_ERROR_RETURN(rv); 10138 10139 rv = soc_reg_field32_modify(unit, asm_ct_thresh_reg, pgw_inst, 10140 asm_ct_fields[pm_id], asm_ct_thresh); 10141 SOC_IF_ERROR_RETURN(rv); 10142 10143 if (IS_OVERSUB_PORT(unit, port)) { 10144 if ((si->port_speed_max[port] == 40000) || 10145 (si->port_speed_max[port] == 42000)) { 10146 osct_pbm |= 1 << mmu_port; /* mmu ports: [0, 17] */ 10147 } 10148 } else { 10149 COMPILER_64_SET(tmp, 0, 1); 10150 COMPILER_64_SHL(tmp, (mmu_port - 18)); /* mmu ports: [18, 71] */ 10151 COMPILER_64_OR(lrct_pbm, tmp); 10152 } 10153 10154 SOC_IF_ERROR_RETURN(WRITE_ENQ_ASF_HS_OVERSUB_ENr(unit, osct_pbm)); 10155 SOC_IF_ERROR_RETURN(WRITE_ENQ_ASF_LRCT_OVERSUB_ENr(unit, lrct_pbm)); 10156 10157 return SOC_E_NONE; 10158 } 10159 10160 10161 STATIC int 10162 soc_apache_edb_init(int unit) 10163 { 10164 soc_pbmp_t pbm; 10165 soc_port_t port; 10166 10167 SOC_PBMP_ASSIGN(pbm, PBMP_PORT_ALL(unit)); 10168 SOC_PBMP_ITER(pbm, port) { 10169 SOC_IF_ERROR_RETURN(soc_apache_port_edb_config(unit, 0, port)); 10170 } 10171 10172 return SOC_E_NONE; 10173 } 10174 10175 STATIC int 10176 _soc_apache_misc_deinit (int unit) 10177 { 10178 10179 SOC_IF_ERROR_RETURN(soc_ap_phy_info_deinit(unit)); 10180 10181 if (soc_apache_misc_info[unit] != NULL) { 10182 sal_free(soc_apache_misc_info[unit]); 10183 soc_apache_misc_info[unit] = NULL; 10184 } 10185 10186 return SOC_E_NONE; 10187 } 10188 10189 STATIC int 10190 soc_apc_mem_modify_range(int unit, soc_mem_t mem, int min_idx, int max_idx, 10191 int nfields, soc_field_t *fields, uint32 *values) 10192 { 10193 uint8 *mbuf; 10194 void *entry_ptr; 10195 int e_idx, f_idx, size, rv; 10196 10197 size = SOC_MEM_TABLE_BYTES(unit, mem); 10198 mbuf = soc_cm_salloc(unit, size, "soc_mem_name[mem]"); 10199 10200 if (NULL == mbuf) { 10201 return SOC_E_MEMORY; 10202 } 10203 10204 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf); 10205 if (SOC_FAILURE(rv)) { 10206 soc_cm_sfree(unit, mbuf); 10207 return rv; 10208 } 10209 10210 for (e_idx = min_idx; e_idx <= max_idx; e_idx++) { 10211 entry_ptr = soc_mem_table_idx_to_pointer(unit, mem, void *, mbuf, e_idx); 10212 for (f_idx = 0; f_idx < nfields; f_idx++) { 10213 /* If value is -1, program entry_idx */ 10214 soc_mem_field32_set(unit, mem, entry_ptr, fields[f_idx], 10215 (values[f_idx] == -1 ? e_idx : values[f_idx])); 10216 } 10217 } 10218 10219 rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf); 10220 soc_cm_sfree(unit, mbuf); 10221 SOC_IF_ERROR_RETURN(rv); 10222 10223 return SOC_E_NONE; 10224 } 10225 10226 #ifdef ALPM_ENABLE 10227 STATIC int 10228 _soc_apache_alpm_mode_enable(int unit) 10229 { 10230 uint32 rval = 0; 10231 uint32 mode; 10232 10233 mode = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0); 10234 if (mode && soc_feature(unit, soc_feature_alpm)) { 10235 /* Set DEFIP mode to ALPM */ 10236 SOC_IF_ERROR_RETURN(READ_L3_DEFIP_RPF_CONTROLr(unit, &rval)); 10237 soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LPM_MODEf, 1); 10238 /* Parallel mode */ 10239 if (mode == SOC_ALPM_MODE_PARALLEL) { 10240 soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LOOKUP_MODEf, 1); 10241 } else { 10242 /* combined search mode */ 10243 soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LOOKUP_MODEf, 0); 10244 } 10245 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_RPF_CONTROLr(unit, rval)); 10246 } 10247 return SOC_E_NONE; 10248 } 10249 #endif /* ALPM_ENABLE */ 10250 10251 #define MIN(a,b) ((a < b) ? a : b) 10252 STATIC int 10253 _soc_apache_misc_init (int unit) 10254 { 10255 static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 }; 10256 soc_info_t *si; 10257 uint32 rval = 0; 10258 uint64 rval64; 10259 uint32 entry[SOC_MAX_MEM_WORDS]; 10260 soc_pbmp_t pbmp; 10261 int port, min_port, max_port; 10262 int block_info_idx; 10263 int index, count, sub_sel, offset, higig2; 10264 int freq, target_freq, divisor, dividend, delay; 10265 int parity_enable = 0, cache_fpgm; 10266 soc_field_t fields[2]; 10267 uint32 values[2]; 10268 int l2mc_max_group_size = 16384, ipmc_max_group_size; 10269 10270 si = &SOC_INFO(unit); 10271 10272 if (soc_apache_misc_info[unit] == NULL) { 10273 soc_apache_misc_info[unit] = sal_alloc(sizeof(*soc_apache_misc_info[unit]), 10274 "apache misc info"); 10275 if (soc_apache_misc_info[unit] == NULL) { 10276 return SOC_E_MEMORY; 10277 } 10278 } 10279 10280 sal_memset(soc_apache_misc_info[unit], 0, (sizeof(*soc_apache_misc_info[unit]))); 10281 10282 /* Stop the mem scan task before all of the parity init takes place */ 10283 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 10284 10285 if (!SOC_WARM_BOOT(unit)) { 10286 10287 /* Initialize PORT MIB counter */ 10288 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 10289 port = SOC_BLOCK_PORT(unit, block_info_idx); 10290 soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10291 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval)); 10292 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0)); 10293 } 10294 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLG2PORT) { 10295 port = SOC_BLOCK_PORT(unit, block_info_idx); 10296 soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10297 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval)); 10298 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0)); 10299 } 10300 10301 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) { 10302 port = SOC_BLOCK_PORT(unit, block_info_idx); 10303 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10304 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval)); 10305 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0)); 10306 } 10307 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORTB0) { 10308 port = SOC_BLOCK_PORT(unit, block_info_idx); 10309 soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf); 10310 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval)); 10311 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0)); 10312 } 10313 10314 } 10315 10316 /* Stop the mem scan task before all of the parity init takes place */ 10317 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 10318 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit)); 10319 10320 10321 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 10322 if (parity_enable) { 10323 if ((!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) && 10324 !SOC_WARM_BOOT(unit)) { 10325 /* Certain mems/regs need to be cleared before enabling SER */ 10326 SOC_IF_ERROR_RETURN(_soc_apache_clear_mmu_memory(unit, INVALIDm)); 10327 SOC_IF_ERROR_RETURN(_soc_apache_clear_all_port_data(unit)); 10328 } 10329 SOC_IF_ERROR_RETURN(_soc_apache_tcam_ser_init(unit)); 10330 SOC_IF_ERROR_RETURN(_soc_apache_ser_enable_all(unit, TRUE)); 10331 #ifdef INCLUDE_MEM_SCAN 10332 soc_mem_scan_ser_list_register(unit, TRUE, 10333 _soc_apache_tcam_ser_info[unit]); 10334 #endif 10335 #if defined(BCM_56560_A0) 10336 memset(&_apache_ser_functions, 0, sizeof(soc_ser_functions_t)); 10337 _apache_ser_functions._soc_ser_fail_f = &soc_apache_ser_fail; 10338 _apache_ser_functions._soc_ser_parity_error_cmicm_intr_f = 10339 &soc_apache_ser_error; 10340 soc_ser_function_register(unit, &_apache_ser_functions); 10341 soc_apache_ser_set_long_delay(FALSE); 10342 #endif 10343 #if defined(SER_TR_TEST_SUPPORT) 10344 /*Initialize chip-specific functions for SER testing*/ 10345 memset(&ser_apache_test_fun, 0, sizeof(soc_ser_test_functions_t)); 10346 ser_apache_test_fun.inject_error_f = &soc_apache_ser_inject_error; 10347 ser_apache_test_fun.test_mem = &soc_apache_ser_test_mem; 10348 ser_apache_test_fun.test = &soc_apache_ser_test; 10349 ser_apache_test_fun.parity_control = &_ser_test_parity_control_reg_set; 10350 ser_apache_test_fun.injection_support = &soc_apache_ser_error_injection_support; 10351 soc_ser_test_functions_register(unit, &ser_apache_test_fun); 10352 #endif /*defined(SER_TR_TEST_SUPPORT*/ 10353 } 10354 10355 if (!SOC_WARM_BOOT(unit)) { 10356 SOC_IF_ERROR_RETURN 10357 (_soc_apache_clear_all_memory(unit, (parity_enable ? 0 : 1))); 10358 if (!parity_enable) { 10359 /* Clear enabled port's regs if not done above */ 10360 SOC_IF_ERROR_RETURN(_soc_apache_clear_enabled_port_data(unit)); 10361 } 10362 } 10363 10364 SOC_IF_ERROR_RETURN(_soc_apache_port_mapping_init(unit)); 10365 10366 10367 if (!SAL_BOOT_BCMSIM && !soc_property_get(unit, "skip_tdm_init", 0)) { 10368 if (!SOC_WARM_BOOT(unit)) { 10369 SOC_IF_ERROR_RETURN(soc_apache_tdm_init(unit)); 10370 SOC_IF_ERROR_RETURN(soc_apache_idb_init(unit)); 10371 SOC_IF_ERROR_RETURN(soc_apache_edb_init(unit)); 10372 } else { 10373 SOC_IF_ERROR_RETURN(soc_apache_tdm_reinit(unit)); 10374 } 10375 } 10376 10377 sal_memset(entry, 0, sizeof(cpu_pbm_entry_t)); 10378 soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit)); 10379 SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry)); 10380 10381 sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t)); 10382 soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit)); 10383 SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry)); 10384 10385 sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t)); 10386 soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf, 10387 &PBMP_LB(unit)); 10388 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm, 10389 MEM_BLOCK_ALL, 0, entry)); 10390 10391 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 10392 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 10393 PBMP_HG_ITER(unit, port) { 10394 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, 10395 MEM_BLOCK_ALL, port, entry)); 10396 } 10397 higig2 = soc_property_port_get(unit, CMIC_PORT(unit), spn_HIGIG2_HDR_MODE, 10398 soc_feature(unit, 10399 soc_feature_no_higig_plus) ? 1 : 0) 10400 ? 1 : 0; 10401 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, higig2); 10402 10403 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, 10404 si->cpu_hg_index, entry)); 10405 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2); 10406 SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, 10407 LB_PORT(unit), entry)); 10408 10409 /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to 10410 * initialize the cache until now. This is the time to check for 10411 * the cache permission of this table. 10412 */ 10413 cache_fpgm = soc_feature(unit, soc_feature_mem_cache) && 10414 soc_property_get(unit, spn_MEM_CACHE_ENABLE, 10415 (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1); 10416 10417 if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) { 10418 char mem_name[100]; 10419 char *mptr; 10420 10421 sal_memset(mem_name, 0, sizeof(mem_name)); 10422 sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_")); 10423 mptr = &mem_name[sal_strlen(mem_name)]; 10424 sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm), 10425 sizeof(mem_name) - sal_strlen(mem_name) - 1); 10426 if (soc_property_get(unit, mem_name, 0)) { 10427 cache_fpgm = 0; 10428 } 10429 } 10430 10431 if (cache_fpgm && (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) { 10432 SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |= SOC_MEM_FLAG_CACHABLE; 10433 SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm, 10434 MEM_BLOCK_ALL, TRUE)); 10435 10436 SOC_MEM_INFO(unit, FP_GM_FIELDSm).flags |= SOC_MEM_FLAG_CACHABLE; 10437 SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, FP_GM_FIELDSm, 10438 MEM_BLOCK_ALL, TRUE)); 10439 } 10440 10441 SOC_IF_ERROR_RETURN(_soc_portctrl_apache_port_init(unit)); 10442 10443 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 10444 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 10445 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 10446 10447 /* Enable dual hash tables */ 10448 SOC_IF_ERROR_RETURN(_soc_apache_hash_init(unit)); 10449 10450 #ifdef ALPM_ENABLE 10451 SOC_IF_ERROR_RETURN(_soc_apache_alpm_mode_enable(unit)); 10452 #endif 10453 10454 rval = 0; 10455 soc_reg_field_set(unit, L2_AGE_DEBUGr, &rval, AGE_COUNTf, 10456 soc_mem_index_max(unit, L2Xm)); 10457 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_DEBUGr(unit, rval)); 10458 10459 /* 10460 * Egress Enable (for non-serdes ports). 10461 * For PM ports, it is set during port enable/disable sequence. 10462 */ 10463 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 10464 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 10465 10466 /* Only enable internal ports in EGR_ENABLE. 10467 * The packet processing ports are enabled via port enable sequence. 10468 */ 10469 SOC_PBMP_CLEAR(pbmp); 10470 SOC_PBMP_PORT_ADD(pbmp, CMIC_PORT(unit)); 10471 SOC_PBMP_PORT_ADD(pbmp, LB_PORT(unit)); 10472 SOC_PBMP_PORT_ADD(pbmp, RDB_PORT(unit)); 10473 10474 PBMP_ITER(pbmp, port) { 10475 SOC_IF_ERROR_RETURN 10476 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, port, entry)); 10477 } 10478 10479 SOC_PBMP_CLEAR(pbmp); 10480 SOC_PBMP_ASSIGN(pbmp, PBMP_CMIC(unit)); 10481 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, &pbmp); 10482 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry)); 10483 10484 /* Bypass control settings */ 10485 if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) { 10486 rval = 0; 10487 10488 /* AP does not support IRSEL1 and IVP bypass stage */ 10489 /*soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 10490 IRSEL1_STAGE_BYPASS_ENABLEf, 1); 10491 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 10492 IVP_STAGE_BYPASS_ENABLEf, 1);*/ 10493 10494 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 10495 IVXLT_STAGE_BYPASS_ENABLEf, 1); 10496 10497 if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) { 10498 soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, 10499 IFP_STAGE_BYPASS_ENABLEf, 1); 10500 } 10501 10502 SOC_IF_ERROR_RETURN(WRITE_ING_BYPASS_CTRLr(unit, rval)); 10503 10504 soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval, 10505 EFP_STAGE_BYPASS_ENABLEf, 1); 10506 10507 SOC_IF_ERROR_RETURN(WRITE_EGR_BYPASS_CTRLr(unit, rval)); 10508 } 10509 10510 /* 10511 * Enable all ports (except RDB port) 10512 * RDB port is an ingress-only port that should not have any packets 10513 * enqueued against it, even if the port is added to any vlan or other 10514 * forwarding table by mistake. 10515 */ 10516 #if __GNUC__ > 6 10517 #pragma GCC diagnostic push 10518 #pragma GCC diagnostic ignored "-Wmemset-elt-size" 10519 #endif 10520 /* 10521 * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for 10522 * performance reasons, because the actual soc_mem_field_set() 10523 * will only write sizeof(ing_dest_port_enable_entry_t)=20 10524 * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651 10525 * depending on which devices are compiled in. 10526 */ 10527 sal_memset(entry, 0, sizeof(ing_dest_port_enable_entry_t)); 10528 #if __GNUC__ > 6 10529 #pragma GCC diagnostic pop 10530 #endif 10531 SOC_PBMP_CLEAR(pbmp); 10532 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 10533 SOC_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit)); 10534 soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, entry, PORT_BITMAPf, &pbmp); 10535 SOC_IF_ERROR_RETURN(WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0, entry)); 10536 10537 min_port = SOC_PORT_MIN(unit, all); 10538 max_port = SOC_PORT_MAX(unit, all); 10539 10540 fields[0] = DESTf; values[0] = -1; /* -1 => port */ 10541 fields[1] = ENABLEf; values[1] = 1; 10542 SOC_IF_ERROR_RETURN(soc_apc_mem_modify_range(unit, MODPORT_MAP_SUBPORTm, 10543 min_port, max_port, 10544 2, fields, values)); 10545 10546 /* setting up my_modid */ 10547 SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64)); 10548 10549 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 10550 MODID_0_VALIDf, 1); 10551 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 10552 MODID_0f, SOC_BASE_MODID(unit)); 10553 10554 SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64)); 10555 10556 10557 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64)); 10558 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10559 L3SRC_HIT_ENABLEf, 1); 10560 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10561 L2DST_HIT_ENABLEf, 1); 10562 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10563 APPLY_EGR_MASK_ON_L2f, 1); 10564 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10565 APPLY_EGR_MASK_ON_L3f, 1); 10566 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10567 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 10568 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10569 ARP_VALIDATION_ENf, 1); 10570 10571 /* 10572 * If riot is enabled, 10573 * MY_STATION1 will be used for tunnels. 10574 * MY_STATION2 will be used for routing. 10575 * Else, 10576 * MY_STATION1 should be used for both tunnels and routing. 10577 * For this, USE_MY_STATION1_FOR_NON_TUNNELS should be set to TRUE. 10578 */ 10579 if (!soc_feature(unit, soc_feature_riot)) { 10580 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 10581 USE_MY_STATION1_FOR_NON_TUNNELSf, 1); 10582 } 10583 10584 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64)); 10585 10586 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1r, 10587 REG_PORT_ANY, RING_MODEf, 1)); 10588 10589 10590 /* T2OQ needs to be setup for all ports that require 1 in 9 spacing or less 10591 * In Apache, it is safe to program all mmu ports 0-15 in T2OQ (whether in 10592 * high speed mode or not). In TD2+, part of the MCQDB memory was re-used 10593 * for T2OQ; Apache has separate 160 deep MCQDB memory */ 10594 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOQ_MC_CFG1r, 10595 REG_PORT_ANY, IS_MC_T2OQ_PORT0f, 10596 0xffff)); 10597 10598 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 10599 * causes the outer tag to be removed from packets that don't have 10600 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 10601 */ 10602 fields[0] = VT_MISS_UNTAGf; values[0] = 0; 10603 fields[1] = REMARK_OUTER_DOT1Pf; values[1] = 1; 10604 SOC_IF_ERROR_RETURN(soc_apc_mem_modify_range(unit, EGR_VLAN_CONTROL_1m, 10605 min_port, max_port, 10606 2, fields, values)); 10607 10608 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 10609 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 10610 SOC_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit)); 10611 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 10612 MEM_BLOCK_ANY, 0, &entry)); 10613 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, &pbmp); 10614 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 10615 MEM_BLOCK_ANY, 0, &entry)); 10616 10617 if (soc_feature(unit, soc_feature_untethered_otp)) { 10618 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureL2mc4k)) { 10619 l2mc_max_group_size = 4096; 10620 } 10621 } 10622 10623 ipmc_max_group_size = soc_mem_index_count(unit, L3_IPMCm); 10624 10625 /* Multicast range initialization */ 10626 SOC_IF_ERROR_RETURN(soc_hbx_higig2_mcast_sizes_set(unit, 10627 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 10628 SOC_HBX_MULTICAST_RANGE_DEFAULT), 10629 MIN(l2mc_max_group_size, soc_property_get(unit, 10630 spn_HIGIG2_MULTICAST_L2_RANGE, l2mc_max_group_size)), 10631 MIN(ipmc_max_group_size, soc_property_get(unit, 10632 spn_HIGIG2_MULTICAST_L3_RANGE, ipmc_max_group_size)))); 10633 10634 SOC_IF_ERROR_RETURN(soc_hbx_mcast_size_set(unit, 10635 MIN(l2mc_max_group_size, soc_property_get(unit, 10636 spn_MULTICAST_L2_RANGE, l2mc_max_group_size)))); 10637 10638 SOC_IF_ERROR_RETURN(soc_hbx_ipmc_size_set(unit, 10639 MIN(ipmc_max_group_size, soc_property_get(unit, 10640 spn_MULTICAST_L3_RANGE, ipmc_max_group_size)))); 10641 10642 /* Setup SW2_FP_DST_ACTION_CONTROL */ 10643 fields[0] = HGTRUNK_RES_ENf; 10644 values[0] = 1; 10645 fields[1] = LAG_RES_ENf; 10646 values[1] = 1; 10647 SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr, 10648 REG_PORT_ANY, 2, fields, values)); 10649 10650 /* Populate and enable RTAG7 Macro flow offset table */ 10651 if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) { 10652 count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm); 10653 sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t)); 10654 for (index = 0; index < count; ) { 10655 for (sub_sel = 0; (sub_sel < 8) && (index < count); sub_sel++) { 10656 for (offset = 0; 10657 offset < rtag7_field_width[sub_sel] && index < count; 10658 offset++) { 10659 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10660 SUB_SEL_ECMPf, sub_sel); 10661 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10662 OFFSET_ECMPf, offset); 10663 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 10664 if ((soc_feature(unit, soc_feature_riot) || 10665 soc_feature(unit, soc_feature_multi_level_ecmp))) { 10666 10667 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10668 SUB_SEL_ECMP_LEVEL1f, sub_sel); 10669 soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry, 10670 OFFSET_ECMP_LEVEL1f, offset); 10671 } 10672 #endif 10673 SOC_IF_ERROR_RETURN 10674 (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm, 10675 MEM_BLOCK_ANY, index, &entry)); 10676 index++; 10677 } 10678 } 10679 } 10680 10681 rval = 0; 10682 soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, USE_FLOW_SEL_ECMPf, 1); 10683 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 10684 if ((soc_feature(unit, soc_feature_riot) || 10685 soc_feature(unit, soc_feature_multi_level_ecmp))) { 10686 10687 soc_reg_field_set(unit, RTAG7_HASH_SELr, 10688 &rval, USE_FLOW_SEL_ECMP1f, 1); 10689 } 10690 #endif 10691 soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, 10692 USE_FLOW_SEL_TRILL_ECMPf, 1); 10693 SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_SELr(unit, rval)); 10694 } 10695 10696 freq = si->frequency; 10697 10698 /* 10699 * Set external MDIO freq to around 6MHz 10700 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2 10701 */ 10702 target_freq = 6; 10703 divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2); 10704 divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, divisor); 10705 dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1); 10706 rval = 0; 10707 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor); 10708 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend); 10709 WRITE_CMIC_RATE_ADJUSTr(unit, rval); 10710 10711 /* 10712 * Set internal MDIO freq to around 12MHz 10713 * Valid range is from 2.5MHz to 20MHz 10714 * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2 10715 * or 10716 * DIVISOR = core_clock_freq * DIVIDENT / (target_freq * 2) 10717 */ 10718 target_freq = 12; 10719 divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2); 10720 divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, divisor); 10721 dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1); 10722 rval = 0; 10723 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 10724 divisor); 10725 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 10726 dividend); 10727 WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval); 10728 10729 delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1); 10730 if (delay >= 1 && delay <= 15) { 10731 /* coverity[result_independent_of_operands] */ 10732 SOC_IF_ERROR_RETURN(READ_CMIC_MIIM_CONFIGr(unit, &rval)); 10733 soc_reg_field_set(unit, CMIC_MIIM_CONFIGr, &rval, MDIO_OUT_DELAYf, 10734 delay); 10735 /* coverity[result_independent_of_operands] */ 10736 SOC_IF_ERROR_RETURN(WRITE_CMIC_MIIM_CONFIGr(unit, rval)); 10737 } 10738 10739 if (!SOC_WARM_BOOT(unit)) { 10740 SOC_IF_ERROR_RETURN(soc_apache_ledup_init(unit)); 10741 } 10742 10743 if (soc_mspi_init(unit) != SOC_E_NONE) { 10744 LOG_WARN(BSL_LS_SOC_COMMON, 10745 (BSL_META_U(unit, 10746 "unit %d : MSPI Init Failed\n"), unit)); 10747 } 10748 10749 if (parity_enable) { 10750 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 10751 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit)); 10752 } 10753 10754 soc_ser_log_init(unit, NULL, 0); 10755 10756 /* Setup config needed for EP-Redirection */ 10757 /* Enable re-direction */ 10758 rval = 0; 10759 soc_reg_field_set(unit, EP_REDIR_CONTROLr, &rval, ENABLEf, 1); 10760 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, EP_REDIR_CONTROLr, 10761 REG_PORT_ANY, 0, rval)); 10762 10763 /* Enable RX/TX */ 10764 rval = 0; 10765 soc_reg_field_set(unit, RDB_ENABLEr, &rval, RX_ENABLEf, 1); 10766 soc_reg_field_set(unit, RDB_ENABLEr, &rval, TX_ENABLEf, 1); 10767 soc_reg_field_set(unit, RDB_ENABLEr, &rval, CTRL_INITf, 1); 10768 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, RDB_ENABLEr, 10769 REG_PORT_ANY, 0, rval)); 10770 10771 /* Enable Credit */ 10772 rval = 0; 10773 soc_reg_field_set(unit, RDB_CREDIT_ENABLEr, &rval, ENABLEf, 1); 10774 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, RDB_CREDIT_ENABLEr, 10775 REG_PORT_ANY, 0, rval)); 10776 10777 return SOC_E_NONE; 10778 } 10779 10780 uint32 _soc_apache_mmu_port(int unit, int port) 10781 { 10782 soc_info_t *si = &SOC_INFO(unit); 10783 return si->port_p2m_mapping[si->port_l2p_mapping[port]]; 10784 } 10785 10786 uint32 _soc_apache_piped_mem_index(int unit, soc_port_t port, 10787 soc_mem_t mem, int arr_off) 10788 { 10789 int mmu_port; 10790 10791 mmu_port = SOC_APACHE_MMU_PORT(unit, port); 10792 10793 switch (mem) { 10794 case MMU_THDM_DB_PORTSP_CONFIG_0m: 10795 case MMU_THDM_DB_PORTSP_CONFIG_1m: 10796 case MMU_THDM_MCQE_PORTSP_CONFIG_0m: 10797 case MMU_THDM_MCQE_PORTSP_CONFIG_1m: 10798 /* RDB port does not have any THDM data so doing a minus 1 */ 10799 return (mmu_port & 0x7f) + (_APACHE_MMU_PORTS_PER_PIPE - 1) * arr_off; 10800 case THDI_PORT_SP_CONFIG_Xm: 10801 case MMU_THDU_XPIPE_CONFIG_PORTm: 10802 case MMU_THDU_XPIPE_RESUME_PORTm: 10803 return (mmu_port & 0x7f) * _APACHE_MMU_NUM_POOL + arr_off; 10804 case THDI_PORT_PG_CONFIG_Xm: 10805 return (mmu_port & 0x7f) * _APACHE_MMU_NUM_PG + arr_off; 10806 default: 10807 return 0xffffffff; 10808 } 10809 } 10810 10811 #define _APACHE_MMU_BYTES_TO_CELLS(_byte_) \ 10812 (((_byte_) + _APACHE_MMU_BYTES_PER_CELL - 1) / _APACHE_MMU_BYTES_PER_CELL) 10813 10814 STATIC void 10815 _soc_apache_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg, 10816 int lossless) 10817 { 10818 soc_info_t *si; 10819 int ct_fifo_rsvd_count; 10820 int qcn_port_count = 0; 10821 soc_pbmp_t pbmp; 10822 int port; 10823 10824 si = &SOC_INFO(unit); 10825 10826 sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t)); 10827 10828 devcfg->max_pkt_byte = si->max_mtu; 10829 devcfg->mmu_hdr_byte = _APACHE_MMU_PACKET_HEADER_BYTES; 10830 devcfg->jumbo_pkt_size = _APACHE_MMU_JUMBO_FRAME_BYTES; 10831 devcfg->default_mtu_size = _APACHE_MMU_DEFAULT_MTU_BYTES; 10832 devcfg->mmu_cell_size = _APACHE_MMU_BYTES_PER_CELL; 10833 10834 /* 10835 * Reserve 1 cell for each cut-through fifo entry 10836 * Assume each port use 1 QCN queue, reserve 1 cell for each QCN queue 10837 * Reserve 10 cells for ingress pool overshoot for lossless setting 10838 */ 10839 ct_fifo_rsvd_count = 0; 10840 SOC_PBMP_ASSIGN(pbmp, si->port.bitmap); 10841 SOC_PBMP_REMOVE(pbmp, si->all.disabled_bitmap); 10842 10843 SOC_PBMP_ITER(pbmp, port) { 10844 qcn_port_count++; 10845 10846 if (soc_feature(unit, soc_feature_asf)) { 10847 ct_fifo_rsvd_count += si->port_speed_max[port] <= 11000 ? 4 : 16; 10848 } 10849 } 10850 10851 /* 10852 * Reserve cells for CT FIFO when Flexport is not enabled 10853 * For Flexport cases, soc_apache_mmu_additional_buffer_reserve() will cover 10854 */ 10855 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 10856 ct_fifo_rsvd_count = 0; 10857 } 10858 10859 devcfg->mmu_total_cell = _APACHE_MMU_TOTAL_CELLS - 10860 ct_fifo_rsvd_count - 10861 qcn_port_count - 10862 (lossless ? 10 : 0); 10863 10864 10865 devcfg->num_pg = _APACHE_MMU_NUM_PG; 10866 devcfg->num_service_pool = _APACHE_MMU_NUM_POOL; 10867 devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN | 10868 SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY; 10869 devcfg->total_mcq_entry = _APACHE_MMU_TOTAL_MCQ_ENTRY(unit); 10870 devcfg->rqe_queue_num = 11; 10871 } 10872 10873 STATIC int 10874 _soc_apache_default_lossless_pg_headroom(int unit, soc_port_t port) 10875 { 10876 soc_info_t *si; 10877 10878 if (IS_RDB_PORT(unit, port)) { 10879 return 0; 10880 } 10881 if (IS_CPU_PORT(unit, port)) { 10882 return 50; 10883 } 10884 if (IS_LB_PORT(unit, port)) { 10885 return 162; 10886 } 10887 10888 si = &SOC_INFO(unit); 10889 if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 10890 if (si->port_speed_max[port] >= 100000) { 10891 return 687; 10892 } else if (si->port_speed_max[port] >= 50000) { 10893 return 352; 10894 } else if (si->port_speed_max[port] >= 40000) { 10895 return 338; 10896 } else if (si->port_speed_max[port] >= 25000) { 10897 return 214; 10898 } else if (si->port_speed_max[port] >= 20000) { 10899 return 206; 10900 } else { 10901 return 185; 10902 } 10903 } else { 10904 if (si->port_speed_max[port] >= 100000) { 10905 return 558; 10906 } else if (si->port_speed_max[port] >= 50000) { 10907 return 298; 10908 } else if (si->port_speed_max[port] >= 40000) { 10909 return 284; 10910 } else if (si->port_speed_max[port] >= 25000) { 10911 return 191; 10912 } else if (si->port_speed_max[port] >= 20000) { 10913 return 183; 10914 } else { 10915 return 162; 10916 } 10917 } 10918 10919 return 0; 10920 } 10921 10922 STATIC int 10923 _soc_apache_min_cell_rsvd_per_mcq(int unit, int port, int default_val) 10924 { 10925 int freq, speed, osub; 10926 soc_info_t *si; 10927 uint8 rev_id; 10928 10929 soc_cm_get_id(unit, NULL, &rev_id); 10930 10931 if (rev_id == BCM56850_A1_REV_ID) { 10932 si = &SOC_INFO(unit); 10933 speed = si->port_speed_max[port]; 10934 osub = (SOC_PBMP_MEMBER(si->oversub_pbm, port)) ? 1 : 0; 10935 10936 if (speed <= 11000) { 10937 return (osub) ? 10 : 5; 10938 } else if (speed <= 42000) { 10939 freq = si->frequency; 10940 return ((freq >= 760) && !osub) ? 9 : 16; 10941 } 10942 } 10943 10944 return default_val; 10945 } 10946 10947 10948 /* 10949 * Function: 10950 * soc_apache_mcq_entries_rsvd_port 10951 * Purpose: 10952 * For a given port, soc_ap_mcq_entries_rsvd_port calculates 10953 * the number of MC q entries (Reserved Egress Queue Entries). 10954 * This function only gives MC q entries for 10955 * for flex disabled ports. 10956 * For flex enabled port macros, this function is not used. 10957 * Parameters: 10958 * unit - (IN) Unit number. 10959 * port - (IN) logical port num 10960 * Returns: 10961 * Reserved Egress Queue Entries for a given port 10962 */ 10963 int soc_ap_mcq_entries_rsvd_port(int unit, int port) 10964 { 10965 int port_num_cosq; 10966 soc_info_t *si; 10967 int mcq_entry = 0; 10968 10969 si = &SOC_INFO(unit); 10970 port_num_cosq = si->port_num_cosq[port]; 10971 if (IS_LB_PORT(unit, port)) { 10972 /* Loopback port has 9 queues (including QCN) 10973 * For calculation of Egress queue entries, 10974 * loopback port is considered having 8 queues 10975 * (Why? :- ask Architecture) 10976 */ 10977 port_num_cosq = si->port_num_cosq[port] - 1; 10978 } 10979 10980 mcq_entry = port_num_cosq * _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD; 10981 return mcq_entry; 10982 } 10983 10984 int 10985 soc_apache_mmu_additional_buffer_reserve(int unit, int flex, 10986 _soc_mmu_rsvd_buffer_t *rsvd_buffer) 10987 { 10988 soc_info_t *si; 10989 int pg_min_cells = 0, qgrp_min_cells = 0, hdrm_cells = 0, asf_cells = 0; 10990 int total_reserve = 0; 10991 int lossless = 0; 10992 int mcq_entry = 0; 10993 int num_lanes = 4 ; 10994 int mc_num_cos = 10; 10995 int pm, j, start_port, logical_port, start_pm, end_pm; 10996 int pm_flex_enabled = 0; 10997 int cut_through; 10998 COMPILER_REFERENCE(si); 10999 si = &SOC_INFO(unit); 11000 11001 if(!rsvd_buffer) { 11002 return SOC_E_PARAM; 11003 } 11004 11005 if (flex) { 11006 return SOC_E_NONE; 11007 } 11008 11009 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 11010 cut_through = soc_feature(unit, soc_feature_asf); 11011 11012 start_pm = 0; 11013 end_pm = 18 ; 11014 11015 /* Per pipe, calculate the memory required on a per port macro (TSC4) basis */ 11016 for (pm = start_pm; pm < end_pm; pm++) { 11017 SOC_IF_ERROR_RETURN( 11018 soc_ap_port_macro_flex_enabled(unit, pm, &pm_flex_enabled)); 11019 11020 /* if this port macro is flex enabled, allocate memory for it accordingly */ 11021 if (pm_flex_enabled == 1) { 11022 /* Reserved Buffer for Flex Port Macro when Flex Port is enabled in 11023 device */ 11024 if (lossless) { 11025 /* eagle port macro*/ 11026 if( pm < 6 || (pm > 8 && pm< 16) ) { 11027 hdrm_cells = (_AP_RSVD_BUF_10G_FLEX_HDRM_LOSSLESS 11028 * num_lanes); 11029 pg_min_cells = (_AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS 11030 * num_lanes); 11031 qgrp_min_cells = 0; 11032 if (cut_through) { 11033 asf_cells = (_AP_RSVD_BUF_25G_FLEX_ASF 11034 * 2); 11035 } 11036 }else { 11037 /* falcom port macro */ 11038 hdrm_cells = (_AP_RSVD_BUF_25G_FLEX_HDRM_LOSSLESS 11039 * num_lanes); 11040 pg_min_cells = (_AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS 11041 * num_lanes); 11042 qgrp_min_cells = 0; 11043 if (cut_through) { 11044 asf_cells = (_AP_RSVD_BUF_25G_FLEX_ASF 11045 * num_lanes); 11046 } 11047 11048 } 11049 } else { 11050 if( pm < 6 || (pm > 8 && pm< 16) ) { 11051 hdrm_cells = 0; 11052 pg_min_cells = 0; 11053 qgrp_min_cells = (_AP_RSVD_BUF_10G_FLEX_QGRP 11054 * num_lanes); 11055 11056 if (cut_through) { 11057 asf_cells = (_AP_RSVD_BUF_25G_FLEX_ASF 11058 * 2); 11059 } 11060 } else { 11061 hdrm_cells = 0; 11062 pg_min_cells = 0; 11063 qgrp_min_cells = (_AP_RSVD_BUF_10G_FLEX_QGRP 11064 * num_lanes); 11065 11066 if (cut_through) { 11067 asf_cells = (_AP_RSVD_BUF_25G_FLEX_ASF 11068 * num_lanes); 11069 } 11070 11071 } 11072 } 11073 mcq_entry = mc_num_cos * 11074 _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD * 11075 num_lanes; 11076 } else { 11077 /*For port modules that are in non-flex mode, buffer is reserved 11078 per port (not port macro). 11079 11080 Here we are calculating the buffer requirements for this TSC4 on 11081 a per port basis. */ 11082 hdrm_cells = 0; 11083 pg_min_cells = 0; 11084 qgrp_min_cells = 0; 11085 asf_cells = 0; 11086 mcq_entry = 0; 11087 start_port = (APACHE_PORTS_PER_TSC * pm ) + 1 ; 11088 for (j = start_port; j < start_port + APACHE_PORTS_PER_TSC; j++) { 11089 /* figure out from the logical port what the speed of this port is */ 11090 logical_port = si->port_p2l_mapping[j]; 11091 if (logical_port == -1) { 11092 continue; 11093 } 11094 11095 if (si->port_speed_max[logical_port] >= 100000) { 11096 if (lossless) { 11097 if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 11098 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_OB_100G_HDRM_LOSSLESS; 11099 } else { 11100 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS; 11101 } 11102 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS; 11103 pg_min_cells += _AP_RSVD_BUF_NON_FLEX_PGMIN; 11104 qgrp_min_cells += 0; 11105 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11106 } else { 11107 qgrp_min_cells += _AP_RSVD_BUF_NON_FLEX_QGRP; 11108 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11109 } 11110 } else if (si->port_speed_max[logical_port] >= 50000) { 11111 if (lossless) { 11112 if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 11113 hdrm_cells +=_AP_RSVD_BUF_NON_FLEX_OB_50G_HDRM_LOSSLESS; 11114 } else { 11115 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_50G_HDRM_LOSSLESS; 11116 } 11117 pg_min_cells += _AP_RSVD_BUF_NON_FLEX_PGMIN; 11118 qgrp_min_cells += 0; 11119 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11120 } else { 11121 qgrp_min_cells += _AP_RSVD_BUF_NON_FLEX_QGRP; 11122 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11123 } 11124 } else if (si->port_speed_max[logical_port] >= 40000) { 11125 if (lossless) { 11126 if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 11127 hdrm_cells += 11128 _AP_RSVD_BUF_NON_FLEX_OB_40G_HDRM_LOSSLESS; 11129 } else { 11130 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_40G_HDRM_LOSSLESS; 11131 } 11132 pg_min_cells += _AP_RSVD_BUF_NON_FLEX_PGMIN; 11133 qgrp_min_cells += 0; 11134 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11135 } else { 11136 qgrp_min_cells += _AP_RSVD_BUF_NON_FLEX_QGRP; 11137 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11138 } 11139 } else if (si->port_speed_max[logical_port] >= 25000) { 11140 if (lossless) { 11141 if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 11142 hdrm_cells += 11143 _AP_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS; 11144 } else { 11145 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS; 11146 } 11147 pg_min_cells += _AP_RSVD_BUF_NON_FLEX_PGMIN; 11148 qgrp_min_cells += 0; 11149 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11150 } else { 11151 qgrp_min_cells += _AP_RSVD_BUF_NON_FLEX_QGRP; 11152 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11153 } 11154 } else if (si->port_speed_max[logical_port] >= 20000) { 11155 if (lossless) { 11156 if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 11157 hdrm_cells += 11158 _AP_RSVD_BUF_NON_FLEX_OB_20G_HDRM_LOSSLESS; 11159 } else { 11160 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_20G_HDRM_LOSSLESS; 11161 } 11162 pg_min_cells += _AP_RSVD_BUF_NON_FLEX_PGMIN; 11163 qgrp_min_cells += 0; 11164 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11165 } else { 11166 qgrp_min_cells += _AP_RSVD_BUF_NON_FLEX_QGRP; 11167 asf_cells += _AP_RSVD_BUF_NON_FLEX_ASF; 11168 } 11169 } else { 11170 if (lossless) { 11171 if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 11172 hdrm_cells += 11173 _AP_RSVD_BUF_NON_FLEX_OB_10G_HDRM_LOSSLESS; 11174 } else { 11175 hdrm_cells += _AP_RSVD_BUF_NON_FLEX_10G_HDRM_LOSSLESS; 11176 } 11177 pg_min_cells += _AP_RSVD_BUF_NON_FLEX_PGMIN; 11178 qgrp_min_cells += 0; 11179 asf_cells += _AP_RSVD_BUF_NON_FLEX_10G_ASF; 11180 } else { 11181 qgrp_min_cells += _AP_RSVD_BUF_NON_FLEX_QGRP; 11182 asf_cells += _AP_RSVD_BUF_NON_FLEX_10G_ASF; 11183 } 11184 } 11185 mcq_entry += soc_ap_mcq_entries_rsvd_port(unit, logical_port); 11186 } 11187 } 11188 11189 /* Add what was calculated for the port macro to the total */ 11190 rsvd_buffer->ing_rsvd_cells += (hdrm_cells + pg_min_cells); 11191 rsvd_buffer->egr_rsvd_cells += qgrp_min_cells; 11192 rsvd_buffer->asf_rsvd_cells += asf_cells; 11193 rsvd_buffer->mcq_entry_rsvd += mcq_entry; 11194 } 11195 11196 total_reserve = rsvd_buffer->ing_rsvd_cells; 11197 total_reserve += rsvd_buffer->egr_rsvd_cells; 11198 total_reserve += rsvd_buffer->asf_rsvd_cells; 11199 11200 LOG_VERBOSE(BSL_LS_SOC_MMU, 11201 (BSL_META_U(unit, 11202 "MMU config: Cells rsvd for Pipe %d," 11203 " Flex/ASF per pipe: %d, Ing: %d," 11204 " Egr: %d, ASF: %d MCQ %d\n"), 11205 0, total_reserve, rsvd_buffer->ing_rsvd_cells, 11206 rsvd_buffer->egr_rsvd_cells, 11207 rsvd_buffer->asf_rsvd_cells, 11208 rsvd_buffer->mcq_entry_rsvd)); 11209 11210 return SOC_E_NONE; 11211 } 11212 /* 11213 * Function: 11214 * soc_ap_egr_buf_rsvd_port 11215 * Purpose: 11216 * For Cpu port or loopback port, 11217 * soc_td2p_egr_buf_rsvd_port calculates 11218 * the reserved queue min/guarantee. 11219 * This function only gives cumulative (for all queues) 11220 * queue guarantee for CPU port or Loopback port. 11221 * Parameters: 11222 * unit - (IN) Unit number. 11223 * port - (IN) logical port num for CPU port or LB port 11224 * Returns: 11225 * Reserved Cumulative (total for all queues) Queue Min/Guarantee value 11226 */ 11227 int soc_ap_egr_buf_rsvd_port(int unit, int port, int default_mtu_cells) 11228 { 11229 int port_num_cosq; 11230 soc_info_t *si; 11231 int egr_rsvd = 0; 11232 int min_cell_per_mcq; 11233 11234 if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) { 11235 return 0; 11236 } 11237 11238 si = &SOC_INFO(unit); 11239 11240 port_num_cosq = si->port_num_cosq[port]; 11241 if (IS_LB_PORT(unit, port)) { 11242 /* Loopback port has 9 queues (including QCN) 11243 * For calculation of Egress queue entries, 11244 * loopback port is considered having 8 queues 11245 * (Why? :- ask Architecture) 11246 */ 11247 port_num_cosq = si->port_num_cosq[port] - 1; 11248 } 11249 11250 11251 if (soc_feature(unit, soc_feature_min_cell_per_queue)) { 11252 min_cell_per_mcq = _soc_apache_min_cell_rsvd_per_mcq 11253 (unit, port, default_mtu_cells); 11254 } else { 11255 min_cell_per_mcq = default_mtu_cells; 11256 } 11257 11258 egr_rsvd = port_num_cosq * min_cell_per_mcq; 11259 return egr_rsvd; 11260 } 11261 11262 STATIC void 11263 _soc_apache_mmu_config_buf_default(int unit, _soc_mmu_cfg_buf_t *buf, 11264 _soc_mmu_device_info_t *devcfg, int lossless) 11265 { 11266 soc_info_t *si; 11267 _soc_mmu_cfg_buf_pool_t *buf_pool; 11268 _soc_mmu_cfg_buf_port_t *buf_port; 11269 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 11270 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 11271 _soc_mmu_cfg_buf_queue_t *buf_queue; 11272 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 11273 int max_packet_cells, pg_min, default_mtu_cells; 11274 int port, idx, per_q_guarentee; 11275 int total_pool_size = 0, egr_shared_total = 0; 11276 int q_reserved = 0, in_reserved = 0; 11277 int mcq_entry_reserved = 0; 11278 int mcq_entry_shared_total; 11279 int rqe_entry_shared_total, min_cell_per_mcq; 11280 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 11281 int asf_rsvd = 0, ing_rsvd = 0, egr_rsvd = 0; 11282 si = &SOC_INFO(unit); 11283 11284 min_cell_per_mcq = soc_feature(unit, soc_feature_min_cell_per_queue) ? 1 : 0; 11285 LOG_VERBOSE(BSL_LS_SOC_COMMON, 11286 (BSL_META_U(unit, 11287 "Initializing default MMU config (u=%d)\n"), unit)); 11288 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 11289 devcfg->mmu_hdr_byte, 11290 devcfg->mmu_cell_size); 11291 pg_min = _APACHE_MMU_PG_MIN; 11292 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 11293 devcfg->mmu_hdr_byte, 11294 devcfg->mmu_cell_size); 11295 11296 total_pool_size = devcfg->mmu_total_cell; 11297 11298 buf->headroom = 2 * _APACHE_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE; 11299 11300 in_reserved += (buf->headroom/2); 11301 11302 per_q_guarentee = _AP_RSVD_BUF_FLEX_QGRP ; 11303 if (FALSE == si->flex_eligible) { 11304 /* This checks to see if the new flex port method has been specified 11305 in the config file and is being used */ 11306 if(soc_apache_is_any_port_flex_enable(unit)) { 11307 soc_apache_mmu_additional_buffer_reserve(unit, 0, 11308 &buf->rsvd_buffers[0]); 11309 } 11310 } 11311 if (asf_rsvd < buf->rsvd_buffers[0].asf_rsvd_cells) { 11312 asf_rsvd = buf->rsvd_buffers[0].asf_rsvd_cells; 11313 } 11314 if (egr_rsvd < buf->rsvd_buffers[0].egr_rsvd_cells) { 11315 egr_rsvd = buf->rsvd_buffers[0].egr_rsvd_cells; 11316 } 11317 if (ing_rsvd < buf->rsvd_buffers[0].ing_rsvd_cells) { 11318 ing_rsvd = buf->rsvd_buffers[0].ing_rsvd_cells; 11319 } 11320 11321 PBMP_ALL_ITER(unit, port) { 11322 if (!IS_LB_PORT(unit,port) && !IS_CPU_PORT(unit,port) 11323 && !IS_RDB_PORT(unit,port) & !lossless) { 11324 q_reserved += 11325 per_q_guarentee; 11326 } 11327 } 11328 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 11329 total_pool_size -= asf_rsvd; 11330 /* Legacy flex port (:i) is not enabled 11331 * Overwrite total_rsvd with flexport reservations made 11332 * Add cpu & lb port egr rsvd entries */ 11333 if (lossless) { 11334 q_reserved = egr_rsvd + 88; 11335 } else { 11336 q_reserved = egr_rsvd + 11337 soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) + 11338 soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) + 11339 88; 11340 } 11341 egr_shared_total = total_pool_size - q_reserved; 11342 } else { 11343 egr_shared_total = total_pool_size - q_reserved - 88; 11344 } 11345 11346 mcq_entry_shared_total = _APACHE_MMU_TOTAL_MCQ_ENTRY(unit) - mcq_entry_reserved; 11347 11348 rqe_entry_shared_total = _APACHE_MMU_TOTAL_RQE_ENTRY(unit) - 88; 11349 11350 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 11351 buf_pool = &buf->pools[idx]; 11352 11353 if (idx == 0) { /* 100% scale up by 100 */ 11354 buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 11355 buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 11356 buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 11357 buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 11358 buf_pool->total_rqe_entry = rqe_entry_shared_total; 11359 } else { 11360 buf_pool->size = 0; 11361 buf_pool->yellow_size = 0; 11362 buf_pool->red_size = 0; 11363 buf_pool->total_mcq_entry = 0; 11364 buf_pool->total_rqe_entry = 0; 11365 } 11366 } 11367 11368 for (idx = 0; idx < SOC_APACHE_MMU_CFG_QGROUP_MAX; idx++) { 11369 queue_grp = &buf->qgroups[idx]; 11370 queue_grp->pool_limit = egr_shared_total; 11371 if (lossless) { 11372 queue_grp->guarantee = 0; 11373 queue_grp->pool_scale = -1; 11374 queue_grp->discard_enable = 0; 11375 queue_grp->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 11376 queue_grp->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 11377 } else { 11378 queue_grp->guarantee = 16; 11379 queue_grp->discard_enable = 1; 11380 queue_grp->pool_scale = 8; 11381 } 11382 queue_grp->pool_resume = default_mtu_cells * 2; 11383 queue_grp->yellow_resume = default_mtu_cells * 2; 11384 queue_grp->red_resume = default_mtu_cells * 2; 11385 } 11386 11387 PBMP_ALL_ITER(unit, port) { 11388 buf_port = &buf->ports[port]; 11389 11390 /* internal priority to priority group mapping */ 11391 for (idx = 0; idx < 16; idx++) { 11392 buf_port->pri_to_prigroup[idx] = 7; 11393 if (lossless && IS_RDB_PORT(unit, port)) { 11394 if (idx < 5) { 11395 buf_port->pri_to_prigroup[idx] = idx + 2; 11396 } 11397 } 11398 } 11399 11400 /* priority group to pool mapping */ 11401 for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) { 11402 buf_port->prigroups[idx].pool_idx = 0; 11403 } 11404 11405 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 11406 buf_port_pool = &buf_port->pools[idx]; 11407 buf_port_pool->guarantee = 0; 11408 buf_port_pool->pool_limit = 0; 11409 buf_port_pool->pool_resume = 0; 11410 if (idx == 0) { 11411 if (lossless && IS_RDB_PORT(unit, port)) { 11412 buf_port_pool->guarantee += 90; 11413 } 11414 buf_port_pool->pool_limit = total_pool_size; 11415 buf_port_pool->pool_resume = 11416 total_pool_size - (default_mtu_cells * 2); 11417 } 11418 in_reserved += buf_port_pool->guarantee; 11419 } 11420 11421 buf_port->pkt_size = max_packet_cells; 11422 11423 /* priority group */ 11424 for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) { 11425 buf_prigroup = &buf_port->prigroups[idx]; 11426 buf_prigroup->guarantee = 0; 11427 buf_prigroup->user_delay = -1; 11428 buf_prigroup->switch_delay = -1; 11429 buf_prigroup->pkt_size = max_packet_cells; 11430 buf_prigroup->device_headroom_enable = 0; 11431 buf_prigroup->pool_limit = 0; 11432 buf_prigroup->pool_floor = 0; 11433 buf_prigroup->pool_scale = -1; 11434 buf_prigroup->headroom = 0; 11435 buf_prigroup->pool_resume = 0; 11436 buf_prigroup->flow_control_enable = 0; 11437 if (lossless && IS_RDB_PORT(unit, port) && (idx < 7)) { 11438 buf_prigroup->device_headroom_enable = 1; 11439 buf_prigroup->headroom = 11440 _soc_apache_default_lossless_pg_headroom(unit, port); 11441 buf_prigroup->pool_scale = 8; 11442 buf_prigroup->pool_resume = default_mtu_cells * 2; 11443 } 11444 if (idx == 7) { 11445 buf_prigroup->device_headroom_enable = 1; 11446 if (!IS_RDB_PORT(unit, port)) { 11447 buf_prigroup->flow_control_enable = lossless; 11448 } 11449 if (lossless) { 11450 buf_prigroup->headroom = 11451 _soc_apache_default_lossless_pg_headroom(unit, port); 11452 if (!IS_RDB_PORT(unit, port) && buf_prigroup->headroom) { 11453 buf_prigroup->guarantee = pg_min; 11454 } 11455 buf_prigroup->pool_scale = 8; 11456 buf_prigroup->pool_resume = default_mtu_cells * 2; 11457 } 11458 if (!lossless && IS_CPU_PORT(unit, port)) { 11459 buf_prigroup->headroom = 11460 _soc_apache_default_lossless_pg_headroom(unit, port); 11461 } 11462 } 11463 in_reserved += buf_prigroup->guarantee + buf_prigroup->headroom; 11464 } 11465 11466 /* multicast queue */ 11467 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 11468 buf_queue = &buf_port->queues[idx]; 11469 buf_queue->qgroup_id = -1; 11470 buf_queue->mcq_entry_guarantee = _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD; 11471 if (IS_LB_PORT(unit, port) && (idx == 8)) { 11472 buf_queue->mcq_entry_guarantee = 0; 11473 } 11474 if (lossless) { 11475 buf_queue->guarantee = min_cell_per_mcq ? 11476 _soc_apache_min_cell_rsvd_per_mcq(unit, port, 0) : 0; 11477 buf_queue->discard_enable = 0; 11478 buf_queue->pool_scale = -1; 11479 buf_queue->pool_limit = egr_shared_total; 11480 buf_queue->mcqe_limit = mcq_entry_shared_total; 11481 buf_queue->yellow_limit = mcq_entry_shared_total; 11482 buf_queue->red_limit = mcq_entry_shared_total; 11483 buf_queue->color_discard_enable = 0; 11484 buf_queue->pool_resume = 16; 11485 } else { 11486 if (IS_CPU_PORT(unit, port) || 11487 (IS_LB_PORT(unit, port) && (idx != (si->port_num_cosq[port]-1)))) { 11488 buf_queue->guarantee = min_cell_per_mcq ? 11489 _soc_apache_min_cell_rsvd_per_mcq(unit, port, default_mtu_cells) : 11490 default_mtu_cells; 11491 } else { 11492 buf_queue->guarantee = min_cell_per_mcq ? 11493 _soc_apache_min_cell_rsvd_per_mcq(unit, port, default_mtu_cells) : 0; 11494 } 11495 buf_queue->discard_enable = 1; 11496 buf_queue->pool_scale = 8; 11497 buf_queue->pool_limit = 0; 11498 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11499 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11500 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11501 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11502 buf_queue->color_discard_enable = 0; 11503 buf_queue->pool_resume = 16; 11504 if (soc_feature(unit, soc_feature_untethered_otp)) { 11505 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu6Mb)) { 11506 buf_queue->qgroup_id = 0; 11507 buf_queue->discard_enable = 0; 11508 buf_queue->qgroup_min_enable= 1; 11509 } 11510 } 11511 } 11512 } 11513 11514 /* unicast queue */ 11515 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 11516 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 11517 if (lossless) { 11518 buf_queue->qgroup_id = -1; 11519 buf_queue->guarantee = 0; 11520 buf_queue->discard_enable = 0; 11521 buf_queue->pool_scale = -1; 11522 buf_queue->pool_limit = egr_shared_total; 11523 buf_queue->yellow_limit = egr_shared_total; 11524 buf_queue->red_limit = egr_shared_total; 11525 buf_queue->color_discard_enable = 0; 11526 buf_queue->pool_resume = default_mtu_cells * 2; 11527 buf_queue->yellow_resume = default_mtu_cells * 2; 11528 buf_queue->red_resume = default_mtu_cells * 2; 11529 } else { 11530 buf_queue->qgroup_id = 0; 11531 buf_queue->guarantee = 0; 11532 buf_queue->discard_enable = 1; 11533 buf_queue->pool_scale = 8; 11534 buf_queue->pool_limit = 0; 11535 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11536 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11537 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG 11538 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 11539 buf_queue->color_discard_enable = 0; 11540 buf_queue->pool_resume = default_mtu_cells * 2; 11541 buf_queue->yellow_resume = default_mtu_cells * 2; 11542 buf_queue->red_resume = default_mtu_cells * 2; 11543 if (soc_feature(unit, soc_feature_untethered_otp)) { 11544 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu6Mb)) { 11545 buf_queue->qgroup_id = 0; 11546 buf_queue->discard_enable = 0; 11547 buf_queue->qgroup_min_enable= 1; 11548 } 11549 } 11550 } 11551 } 11552 11553 /* queue to pool mapping */ 11554 for (idx = 0; 11555 idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) { 11556 buf_port->queues[idx].pool_idx = 0; 11557 } 11558 } 11559 11560 PBMP_ALL_ITER(unit, port) { 11561 buf_port = &buf->ports[port]; 11562 buf_prigroup = &buf_port->prigroups[7]; 11563 if (!lossless) { 11564 buf_prigroup->pool_limit = total_pool_size - in_reserved; 11565 } 11566 } 11567 11568 /* RQE */ 11569 for (idx = 0; idx < 11; idx++) { 11570 buf_rqe_queue = &buf->rqe_queues[idx]; 11571 buf_rqe_queue->pool_idx = 0; 11572 buf_rqe_queue->yellow_limit = egr_shared_total; 11573 buf_rqe_queue->red_limit = egr_shared_total; 11574 if (lossless) { 11575 buf_rqe_queue->guarantee = 8; 11576 buf_rqe_queue->discard_enable = 0; 11577 buf_rqe_queue->pool_scale = -1; 11578 buf_rqe_queue->pool_limit = egr_shared_total; 11579 } else { 11580 buf_rqe_queue->guarantee = default_mtu_cells; 11581 buf_rqe_queue->discard_enable = 1; 11582 buf_rqe_queue->pool_scale = 8; 11583 buf_rqe_queue->pool_limit = 0; 11584 buf_rqe_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 11585 buf_rqe_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 11586 } 11587 } 11588 11589 } 11590 11591 STATIC int 11592 _soc_apache_pool_scale_to_limit(int size, int scale) 11593 { 11594 int factor = 1000; 11595 11596 switch (scale) { 11597 case 7: factor = 875; break; 11598 case 6: factor = 750; break; 11599 case 5: factor = 625; break; 11600 case 4: factor = 500; break; 11601 case 3: factor = 375; break; 11602 case 2: factor = 250; break; 11603 case 1: factor = 125; break; 11604 case 0: 11605 default: 11606 factor = 1000; break; 11607 } 11608 return (size * factor)/1000; 11609 } 11610 11611 STATIC int 11612 _soc_apache_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf, 11613 _soc_mmu_device_info_t *devcfg, int lossless, 11614 soc_port_t input_port) 11615 { 11616 soc_info_t *si; 11617 _soc_mmu_cfg_buf_pool_t *buf_pool; 11618 _soc_mmu_cfg_buf_port_t *buf_port; 11619 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 11620 _soc_mmu_cfg_buf_queue_t *buf_queue; 11621 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 11622 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 11623 soc_mem_t mem, mem1, mem2, mem3; 11624 uint32 rval, fval, rval2, rval3; 11625 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 11626 thdi_port_pg_config_entry_t pg_config_mem; 11627 thdi_port_sp_config_entry_t thdi_sp_config; 11628 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 11629 mmu_thdu_xpipe_offset_qgroup_entry_t offset_qgrp; 11630 int default_mtu_cells, limit, midx, pri, rlimit, min_resume_limit; 11631 int port, base, numq, idx; 11632 int jumbo_frame_cells, pval, rqlen, qbase; 11633 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 11634 int port_count = 0; 11635 soc_reg_t reg = INVALIDr; 11636 static const soc_field_t prigroup_reg[] = { 11637 THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r 11638 }; 11639 static const soc_field_t prigroup_field[] = { 11640 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 11641 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 11642 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 11643 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 11644 }; 11645 static const soc_field_t prigroup_spid_field[] = { 11646 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 11647 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 11648 }; 11649 int index1; 11650 int pool_resume = 0; 11651 uint16 dev_id; 11652 uint8 rev_id; 11653 int ing_rsvd = 0, egr_rsvd = 0, asf_rsvd = 0; 11654 int total_rsvd = 0 ; 11655 int rqe_rsvd = 0 ; 11656 int lb_hdrm = 0, cpu_hdrm = 0, rdb_hdrm = 0; 11657 int rqe =0 ; 11658 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe; 11659 int mcq_entry_rsvd = 0; 11660 int q_reserved = 0; 11661 uint32 e2ecc_ds_config; 11662 soc_cm_get_id(unit, &dev_id, &rev_id); 11663 min_resume_limit = soc_feature(unit, soc_feature_min_resume_limit_1) ? 8 : 0; 11664 11665 si = &SOC_INFO(unit); 11666 11667 jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size + 11668 devcfg->mmu_hdr_byte, 11669 devcfg->mmu_cell_size); 11670 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 11671 devcfg->mmu_hdr_byte, 11672 devcfg->mmu_cell_size); 11673 11674 PBMP_ALL_ITER(unit, port) { 11675 if (!IS_LB_PORT(unit,port) && !IS_CPU_PORT(unit,port) && 11676 !IS_RDB_PORT(unit,port) && !lossless) { 11677 q_reserved += _AP_RSVD_BUF_FLEX_QGRP; 11678 } 11679 } 11680 idx = 0 ; 11681 rval = 0; 11682 fval = _APACHE_CFAPFULLSETPOINT; 11683 if (input_port == -1) { 11684 soc_reg_field_set(unit, CFAPFULLSETPOINTr, &rval, CFAPFULLSETPOINTf, 11685 fval); 11686 SOC_IF_ERROR_RETURN(WRITE_CFAPFULLSETPOINTr(unit, rval)); 11687 rval = 0; 11688 soc_reg_field_set(unit, CFAPFULLRESETPOINTr, &rval, 11689 CFAPFULLRESETPOINTf, fval - 2 * jumbo_frame_cells); 11690 SOC_IF_ERROR_RETURN(WRITE_CFAPFULLRESETPOINTr(unit, rval)); 11691 } 11692 if (asf_rsvd < buf->rsvd_buffers[idx].asf_rsvd_cells) { 11693 asf_rsvd = buf->rsvd_buffers[idx].asf_rsvd_cells; 11694 } 11695 if (egr_rsvd < buf->rsvd_buffers[idx].egr_rsvd_cells) { 11696 egr_rsvd = buf->rsvd_buffers[idx].egr_rsvd_cells; 11697 } 11698 if (ing_rsvd < buf->rsvd_buffers[idx].ing_rsvd_cells) { 11699 ing_rsvd = buf->rsvd_buffers[idx].ing_rsvd_cells; 11700 } 11701 mcq_entry_rsvd = buf->rsvd_buffers[idx].mcq_entry_rsvd; 11702 11703 LOG_VERBOSE(BSL_LS_SOC_MMU, 11704 (BSL_META_U(unit, 11705 "MMU config set HW: Cells rsvd : %d\n"), 11706 (ing_rsvd + egr_rsvd + asf_rsvd))); 11707 11708 /* internal priority to priority group mapping */ 11709 PBMP_ALL_ITER(unit, port) { 11710 if ((input_port != port) && 11711 (input_port != -1)) { 11712 continue; 11713 } 11714 buf_port = &buf->ports[port]; 11715 11716 for (idx = 0; idx < 16; idx++) { 11717 if (idx % 8 == 0) { /* 8 fields per register */ 11718 reg = prigroup_reg[idx / 8]; 11719 rval = 0; 11720 } 11721 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 11722 buf_port->pri_to_prigroup[idx]); 11723 if (idx % 8 == 7) { /* 8 fields per register */ 11724 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 11725 } 11726 } 11727 } 11728 if (input_port == -1) { 11729 /* Input thresholds */ 11730 rval = 0; 11731 soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr, 11732 &rval, GLOBAL_HDRM_LIMITf, buf->headroom/2); 11733 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr, 11734 REG_PORT_ANY, 0, rval)); 11735 11736 11737 fval = 0; 11738 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 11739 if ((buf->pools[idx].size & ~_MMU_CFG_BUF_PERCENT_FLAG) != 0) { 11740 fval |= 1 << idx; 11741 } 11742 } 11743 11744 rval = 0; 11745 soc_reg_field_set(unit, THDI_BYPASSr, &rval, INPUT_THRESHOLD_BYPASSf, 0); 11746 SOC_IF_ERROR_RETURN(WRITE_THDI_BYPASSr(unit, rval)); 11747 11748 11749 rval = 0; 11750 soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, COLOR_AWAREf, 0); 11751 soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, PUBLIC_ENABLEf, 1); 11752 SOC_IF_ERROR_RETURN(WRITE_THDI_POOL_CONFIGr(unit, rval)); 11753 11754 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 11755 buf_pool = &buf->pools[idx]; 11756 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 11757 continue; 11758 } 11759 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 11760 /* Legacy flex port (:i) is not enabled */ 11761 /* additional per port macro buffers reserved */ 11762 /* Add cpu & lb port pg headroom */ 11763 if (lossless) { 11764 lb_hdrm = _soc_apache_default_lossless_pg_headroom( 11765 unit, 11766 LB_PORT(unit)); 11767 11768 cpu_hdrm = _soc_apache_default_lossless_pg_headroom( 11769 unit, 11770 CMIC_PORT(unit)); 11771 rdb_hdrm = _soc_apache_default_lossless_pg_headroom( 11772 unit, 11773 RDB_PORT(unit)); 11774 /* Add PG min for CPU & Loopback port and RDB port min */ 11775 } 11776 ing_rsvd = ing_rsvd + cpu_hdrm + lb_hdrm +rdb_hdrm + 11777 2 *_AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS + _AP_MMU_RDB_PORT_MIN; 11778 } else { 11779 ing_rsvd = buf_pool->prigroup_headroom + buf_pool->prigroup_guarantee; 11780 11781 } 11782 11783 if (lossless) { 11784 limit = devcfg->mmu_total_cell - (ing_rsvd+ 11785 (buf->headroom/2) + 11786 buf_pool->queue_guarantee + asf_rsvd); 11787 } else { 11788 11789 cpu_hdrm = _soc_apache_default_lossless_pg_headroom( 11790 unit, 11791 CMIC_PORT(unit)); 11792 limit = buf_pool->total - 11793 (buf->headroom/2) - cpu_hdrm - asf_rsvd ; 11794 } 11795 11796 PBMP_ALL_ITER(unit, port) { 11797 port_count++; 11798 } 11799 port_count -= 1; 11800 pool_resume = (port_count / 2) * default_mtu_cells; 11801 11802 rval = 0; 11803 soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit); 11804 SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, rval)); 11805 11806 rval = 0; 11807 soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 11808 OFFSETf, pool_resume); 11809 SOC_IF_ERROR_RETURN(WRITE_THDI_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval)); 11810 } 11811 11812 rval = 0; 11813 SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr(unit, rval)); 11814 11815 /* output thresholds */ 11816 SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval)); 11817 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_QUEUE_AND_GROUP_TICKETf, 1); 11818 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_UPDATE_COLOR_RESUMEf, 1); 11819 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 11820 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0); 11821 SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval)); 11822 11823 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 11824 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, MOP_POLICYf, 1); 11825 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 11826 11827 /* per service pool settings */ 11828 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 11829 buf_pool = &buf->pools[idx]; 11830 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 11831 continue; 11832 } 11833 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 11834 /* Legacy flex port (:i) is not enabled 11835 * Overwrite total_rsvd with flexport reservations made 11836 * Add cpu & lb port egr rsvd entries */ 11837 if (devcfg->flags & SOC_MMU_CFG_F_RQE) { 11838 for (rqe = 0; rqe < 11; rqe++) { 11839 buf_rqe = &buf->rqe_queues[rqe]; 11840 rqe_rsvd += buf_rqe->guarantee; 11841 } 11842 } 11843 if (lossless) { 11844 total_rsvd = egr_rsvd + rqe_rsvd; 11845 } else { 11846 total_rsvd = egr_rsvd + 11847 soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) + 11848 soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) + 11849 rqe_rsvd; 11850 } 11851 } else { 11852 11853 total_rsvd = buf_pool->queue_guarantee + q_reserved; 11854 11855 } 11856 11857 limit = buf_pool->total - ( total_rsvd + asf_rsvd); 11858 11859 if (limit <= 0) { 11860 limit = 0; 11861 } 11862 11863 rval = 0; 11864 soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 11865 SHARED_LIMITf, limit); 11866 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, idx, rval)); 11867 11868 rval = 0; 11869 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 11870 &rval, YELLOW_SHARED_LIMITf, (limit + 7)/8); 11871 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, idx, rval)); 11872 11873 rval = 0; 11874 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 11875 &rval, RED_SHARED_LIMITf, (limit + 7)/8); 11876 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, idx, rval)); 11877 11878 rval = 0; 11879 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 11880 &rval, RESUME_LIMITf, (limit + 7) /8); 11881 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, idx, rval)); 11882 11883 rval = 0; 11884 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 11885 &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8); 11886 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, idx, rval)); 11887 11888 rval = 0; 11889 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 11890 &rval, RED_RESUME_LIMITf, (limit + 7)/8); 11891 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, idx, rval)); 11892 11893 total_rsvd = 0 ; 11894 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 11895 /* Legacy flex port (:i) is not enabled */ 11896 /* additional per port macro mcq entries reserved */ 11897 /* Add cpu & lb port mcs entries */ 11898 total_rsvd = mcq_entry_rsvd + 11899 soc_ap_mcq_entries_rsvd_port(unit, CMIC_PORT(unit)) + 11900 soc_ap_mcq_entries_rsvd_port(unit, LB_PORT(unit)); 11901 } else { 11902 /* cpu & lb port mcq reserved entries already included 11903 * in buf_pool->mcq_entry_reserved 11904 */ 11905 total_rsvd = buf_pool->mcq_entry_reserved; 11906 } 11907 11908 /* mcq entries */ 11909 limit = buf_pool->total_mcq_entry - total_rsvd; 11910 11911 11912 rval = 0; 11913 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 11914 &rval, SHARED_LIMITf, limit/4); 11915 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit, 11916 idx, rval)); 11917 11918 rval = 0; 11919 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 11920 &rval, YELLOW_SHARED_LIMITf, (limit + 7)/ 8); 11921 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit, 11922 idx, rval)); 11923 11924 rval = 0; 11925 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 11926 &rval, RED_SHARED_LIMITf, (limit + 7)/8); 11927 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit, 11928 idx, rval)); 11929 11930 rval = 0; 11931 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 11932 &rval, RESUME_LIMITf, (limit + 7)/8); 11933 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit, 11934 idx, rval)); 11935 11936 rval = 0; 11937 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 11938 &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8); 11939 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit, 11940 idx, rval)); 11941 11942 rval = 0; 11943 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 11944 &rval, RED_RESUME_LIMITf, (limit + 7)/8); 11945 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit, 11946 idx, rval)); 11947 } 11948 11949 rval = 0; 11950 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 11951 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1); 11952 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 11953 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Af, 0); 11954 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval)); 11955 11956 rval = 0; 11957 soc_reg_field_set(unit, MMU_THDR_QE_CONFIGr, &rval, 11958 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1); 11959 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIGr(unit, rval)); 11960 11961 /* configure Q-groups */ 11962 for (idx = 0; idx < SOC_APACHE_MMU_CFG_QGROUP_MAX; idx++) { 11963 queue_grp = &buf->qgroups[idx]; 11964 11965 mem = MMU_THDU_XPIPE_CONFIG_QGROUPm; 11966 mem1 = MMU_THDU_XPIPE_OFFSET_QGROUPm; 11967 11968 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 11969 sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp)); 11970 11971 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11972 Q_MIN_LIMIT_CELLf, queue_grp->guarantee); 11973 11974 if (queue_grp->pool_scale != -1) { 11975 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11976 Q_SHARED_ALPHA_CELLf, queue_grp->pool_scale); 11977 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11978 Q_LIMIT_DYNAMIC_CELLf, 1); 11979 } else { 11980 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11981 Q_SHARED_LIMIT_CELLf, queue_grp->pool_limit); 11982 } 11983 11984 if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 11985 pval = _soc_apache_pool_scale_to_limit(queue_grp->pool_limit, 11986 queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 11987 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11988 LIMIT_RED_CELLf, (pval + 7)/8); 11989 11990 } else { 11991 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11992 LIMIT_RED_CELLf, queue_grp->red_limit); 11993 soc_mem_field32_set(unit, mem, &cfg_qgrp, 11994 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 11995 } 11996 11997 if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 11998 pval = _soc_apache_pool_scale_to_limit(queue_grp->pool_limit, 11999 queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 12000 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12001 LIMIT_YELLOW_CELLf, (pval + 7)/8); 12002 12003 } else { 12004 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12005 LIMIT_YELLOW_CELLf, queue_grp->yellow_limit); 12006 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12007 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 12008 } 12009 SOC_IF_ERROR_RETURN 12010 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12011 12012 soc_mem_field32_set(unit, mem1, 12013 &offset_qgrp, RESET_OFFSET_CELLf, queue_grp->pool_resume / 8); 12014 soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_YELLOW_CELLf, 12015 queue_grp->yellow_resume / 8); 12016 soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_RED_CELLf, 12017 queue_grp->red_resume / 8); 12018 12019 SOC_IF_ERROR_RETURN 12020 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp)); 12021 } 12022 } 12023 12024 /* Input port per port settings */ 12025 PBMP_ALL_ITER(unit, port) { 12026 if ((input_port != port) && 12027 (input_port != -1)) { 12028 continue; 12029 } 12030 12031 buf_port = &buf->ports[port]; 12032 12033 rval = 0; 12034 for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) { 12035 soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval, 12036 prigroup_spid_field[idx], 12037 buf_port->prigroups[idx].pool_idx); 12038 } 12039 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval)); 12040 12041 mem = THDI_PORT_SP_CONFIG_Xm; 12042 /* Per port per pool settings */ 12043 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 12044 buf_port_pool = &buf_port->pools[idx]; 12045 midx = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12046 sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config)); 12047 soc_mem_field32_set(unit, mem, &thdi_sp_config, 12048 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee); 12049 soc_mem_field32_set(unit, mem, &thdi_sp_config, 12050 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume); 12051 soc_mem_field32_set(unit, mem, &thdi_sp_config, 12052 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit); 12053 SOC_IF_ERROR_RETURN 12054 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, &thdi_sp_config)); 12055 } 12056 12057 fval = 0; 12058 for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) { 12059 if (buf_port->prigroups[idx].flow_control_enable != 0) { 12060 for (pri=0; pri < 16; pri++) { 12061 if (buf_port->pri_to_prigroup[pri] == idx) { 12062 fval |= 1 << pri; 12063 } 12064 } 12065 } 12066 } 12067 12068 rval = 0; 12069 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 12070 INPUT_PORT_RX_ENABLEf, 1); 12071 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 12072 PORT_PRI_XON_ENABLEf, fval); 12073 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 12074 PORT_PAUSE_ENABLEf, fval ? 1 : 0); 12075 SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, port, rval)); 12076 12077 rval = 0; 12078 soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 12079 PORT_MAX_PKT_SIZEf, buf_port->pkt_size); 12080 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval)); 12081 12082 /* Input port per port per priority group settings */ 12083 mem = THDI_PORT_PG_CONFIG_Xm; 12084 for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) { 12085 buf_prigroup = &buf->ports[port].prigroups[idx]; 12086 12087 midx = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12088 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 12089 soc_mem_field32_set(unit, mem, &pg_config_mem, 12090 PG_MIN_LIMITf, buf_prigroup->guarantee); 12091 12092 if (buf_prigroup->pool_scale != -1) { 12093 soc_mem_field32_set(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf, 1); 12094 soc_mem_field32_set(unit, mem, &pg_config_mem, 12095 PG_SHARED_LIMITf, buf_prigroup->pool_scale); 12096 } else { 12097 soc_mem_field32_set(unit, mem, &pg_config_mem, 12098 PG_SHARED_LIMITf, buf_prigroup->pool_limit); 12099 } 12100 12101 soc_mem_field32_set(unit, mem, &pg_config_mem, 12102 PG_GBL_HDRM_ENf, buf_prigroup->device_headroom_enable); 12103 soc_mem_field32_set(unit, mem, &pg_config_mem, 12104 PG_HDRM_LIMITf, buf_prigroup->headroom); 12105 12106 soc_mem_field32_set(unit, mem, &pg_config_mem, 12107 PG_RESET_OFFSETf, buf_prigroup->pool_resume); 12108 12109 soc_mem_field32_set(unit, mem, &pg_config_mem, 12110 PG_RESET_FLOORf, buf_prigroup->pool_floor); 12111 12112 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 12113 MEM_BLOCK_ALL, midx, &pg_config_mem)); 12114 } 12115 } 12116 12117 /*********************************** 12118 * THDO 12119 */ 12120 /* Output port per port per queue setting for regular multicast queue */ 12121 PBMP_ALL_ITER(unit, port) { 12122 if ((input_port != port) && 12123 (input_port != -1)) { 12124 continue; 12125 } 12126 12127 if (IS_RDB_PORT(unit, port)) { 12128 continue; 12129 } 12130 12131 numq = si->port_num_cosq[port]; 12132 qbase = si->port_cosq_base[port]; 12133 if (numq == 0) { 12134 continue; 12135 } 12136 12137 mem = MMU_THDM_DB_QUEUE_CONFIG_0m; 12138 12139 base = soc_apache_l2_hw_index(unit, qbase, 0) - _APACHE_MC_QUEUE_BASE; 12140 12141 mem1 = MMU_THDM_DB_QUEUE_OFFSET_0m; 12142 mem2 = MMU_THDM_MCQE_QUEUE_OFFSET_0m; 12143 12144 for (idx = 0; idx < numq; idx++) { 12145 buf_queue = &buf->ports[port].queues[idx]; 12146 12147 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 12148 12149 soc_mem_field32_set(unit, mem, entry0, 12150 Q_MIN_LIMITf, buf_queue->guarantee); 12151 if (buf_queue->discard_enable) { 12152 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1); 12153 } 12154 if (buf_queue->color_discard_enable) { 12155 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 12156 } 12157 if (buf_queue->pool_scale != -1) { 12158 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1); 12159 soc_mem_field32_set(unit, mem, entry0, 12160 Q_SHARED_ALPHAf, buf_queue->pool_scale); 12161 } else { 12162 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 12163 soc_mem_field32_set(unit, mem, entry0, 12164 Q_SHARED_LIMITf, buf_queue->pool_limit); 12165 } 12166 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 12167 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 12168 soc_mem_field32_set(unit, mem, entry0, 12169 Q_COLOR_LIMIT_DYNAMICf, 1); 12170 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 12171 buf_queue->yellow_limit 12172 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 12173 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 12174 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 12175 buf_queue->red_limit 12176 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 12177 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 12178 } else { 12179 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 12180 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 12181 (buf_queue->pool_limit + 7) / 8); 12182 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 12183 (buf_queue->pool_limit + 7) / 8); 12184 } 12185 12186 soc_mem_field32_set(unit, mem, entry0, 12187 Q_SPIDf, buf_queue->pool_idx); 12188 12189 SOC_IF_ERROR_RETURN 12190 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 12191 entry0)); 12192 12193 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t)); 12194 12195 soc_mem_field32_set(unit, mem1, entry0, 12196 RESUME_OFFSETf, (default_mtu_cells * 2)/8); 12197 soc_mem_field32_set(unit, mem1, entry0, 12198 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 12199 soc_mem_field32_set(unit, mem1, entry0, 12200 RED_RESUME_OFFSET_PROFILE_SELf, 0); 12201 SOC_IF_ERROR_RETURN 12202 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, 12203 entry0)); 12204 12205 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_0_entry_t)); 12206 soc_mem_field32_set(unit, mem1, entry0, 12207 RESUME_OFFSETf, 1); 12208 SOC_IF_ERROR_RETURN 12209 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, 12210 entry0)); 12211 12212 SOC_IF_ERROR_RETURN 12213 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0, 12214 YELLOW_RESUME_OFFSETf, 12215 2)); 12216 12217 SOC_IF_ERROR_RETURN 12218 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0, 12219 RED_RESUME_OFFSETf, 12220 2)); 12221 } 12222 12223 mem = MMU_THDM_MCQE_QUEUE_CONFIG_0m; 12224 for (idx = 0; idx < numq; idx++) { 12225 buf_queue = &buf->ports[port].queues[idx]; 12226 12227 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_0_entry_t)); 12228 12229 soc_mem_field32_set(unit, mem, entry0, 12230 Q_MIN_LIMITf, buf_queue->mcq_entry_guarantee/4); 12231 if (buf_queue->discard_enable) { 12232 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1); 12233 } 12234 if (buf_queue->color_discard_enable) { 12235 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 12236 } 12237 if (buf_queue->pool_scale != -1) { 12238 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1); 12239 soc_mem_field32_set(unit, mem, entry0, 12240 Q_SHARED_ALPHAf, buf_queue->pool_scale); 12241 } else { 12242 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 12243 soc_mem_field32_set(unit, mem, entry0, 12244 Q_SHARED_LIMITf, buf_queue->mcqe_limit/4); 12245 } 12246 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 12247 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 12248 soc_mem_field32_set(unit, mem, entry0, 12249 Q_COLOR_LIMIT_DYNAMICf, 1); 12250 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 12251 buf_queue->yellow_limit 12252 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 12253 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 12254 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 12255 buf_queue->red_limit 12256 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 12257 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 12258 } else { 12259 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 12260 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf, 12261 (buf_queue->yellow_limit + 7) / 8); 12262 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf, 12263 (buf_queue->red_limit + 7)/ 8); 12264 } 12265 12266 soc_mem_field32_set(unit, mem, entry0, 12267 Q_SPIDf, buf_queue->pool_idx); 12268 12269 SOC_IF_ERROR_RETURN 12270 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 12271 entry0)); 12272 12273 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t)); 12274 12275 soc_mem_field32_set(unit, mem1, entry0, 12276 RESUME_OFFSETf, (default_mtu_cells * 2)/8); 12277 soc_mem_field32_set(unit, mem1, entry0, 12278 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 12279 soc_mem_field32_set(unit, mem1, entry0, 12280 RED_RESUME_OFFSET_PROFILE_SELf, 0); 12281 SOC_IF_ERROR_RETURN 12282 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, 12283 entry0)); 12284 12285 SOC_IF_ERROR_RETURN 12286 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0, 12287 YELLOW_RESUME_OFFSETf, 12288 1)); 12289 12290 SOC_IF_ERROR_RETURN 12291 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0, 12292 RED_RESUME_OFFSETf, 12293 1)); 12294 } 12295 12296 /* Per port per pool */ 12297 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 12298 buf_pool = &buf->pools[idx]; 12299 if (buf_pool->total == 0) { 12300 continue; 12301 } 12302 total_rsvd =0; 12303 buf_rqe = 0; 12304 rqe_rsvd = 0; 12305 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 12306 /* Legacy flex port (:i) is not enabled 12307 * Overwrite total_rsvd with flexport reservations made 12308 * Add cpu & lb port egr rsvd entries */ 12309 if (devcfg->flags & SOC_MMU_CFG_F_RQE) { 12310 for (rqe = 0; rqe < 11; rqe++) { 12311 buf_rqe = &buf->rqe_queues[rqe]; 12312 rqe_rsvd += buf_rqe->guarantee; 12313 } 12314 } 12315 if (lossless) { 12316 total_rsvd = egr_rsvd + rqe_rsvd; 12317 } else { 12318 total_rsvd = egr_rsvd + 12319 soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) + 12320 soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) + 12321 rqe_rsvd; 12322 } 12323 } else { 12324 12325 total_rsvd = buf_pool->queue_guarantee + q_reserved; 12326 } 12327 limit = buf_pool->total - total_rsvd; 12328 if ((limit - 2 * default_mtu_cells) > 0) { 12329 rlimit = ((limit - 2 * default_mtu_cells) < min_resume_limit) ? 12330 min_resume_limit : limit - 2 * default_mtu_cells; 12331 } else { 12332 rlimit = min_resume_limit; 12333 } 12334 mem2 = MMU_THDM_DB_PORTSP_CONFIG_0m; 12335 index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx); 12336 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t)); 12337 12338 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit); 12339 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8); 12340 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8); 12341 12342 soc_mem_field32_set(unit, mem2, entry0, 12343 SHARED_LIMIT_ENABLEf, !lossless); 12344 12345 soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, (rlimit + 7)/8); 12346 soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, (rlimit + 7)/8); 12347 soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, (rlimit + 7)/8); 12348 12349 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 12350 index1, entry0)); 12351 12352 mem2 = MMU_THDM_MCQE_PORTSP_CONFIG_0m; 12353 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_0_entry_t)); 12354 12355 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 12356 rlimit = (limit < min_resume_limit) ? min_resume_limit : limit; 12357 12358 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, (limit + 3)/4); 12359 soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, 12360 ((rlimit/8) - 1)); 12361 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMIT_ENABLEf, !lossless); 12362 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8); 12363 soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, 12364 ((rlimit + 7)/8 - 1)); 12365 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8); 12366 soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, 12367 ((rlimit + 7)/8 -1)); 12368 12369 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 12370 index1, entry0)); 12371 } 12372 } 12373 12374 /* Output port per port per queue setting for regular unicast queue */ 12375 PBMP_PORT_ITER(unit, port) { 12376 if ((input_port != port) && 12377 (input_port != -1)) { 12378 continue; 12379 } 12380 12381 if(IS_RDB_PORT(unit, port)) { 12382 continue; 12383 } 12384 /* per port regular unicast queue */ 12385 numq = si->port_num_uc_cosq[port]; 12386 qbase = si->port_uc_cosq_base[port]; 12387 if (numq == 0) { 12388 continue; 12389 } 12390 base = soc_apache_l2_hw_index(unit, qbase, 1); 12391 mem = MMU_THDU_XPIPE_CONFIG_QUEUEm; 12392 mem1 = MMU_THDU_XPIPE_OFFSET_QUEUEm; 12393 mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm; 12394 for (idx = 0; idx < numq; idx++) { 12395 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx]; 12396 12397 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t)); 12398 sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_offset_queue_entry_t)); 12399 12400 soc_mem_field32_set(unit, mem, entry0, 12401 Q_MIN_LIMIT_CELLf, buf_queue->guarantee); 12402 if (buf_queue->pool_scale != -1) { 12403 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf, 1); 12404 soc_mem_field32_set(unit, mem, entry0, 12405 Q_SHARED_ALPHA_CELLf, buf_queue->pool_scale); 12406 } else { 12407 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 12408 soc_mem_field32_set(unit, mem, entry0, 12409 Q_SHARED_LIMIT_CELLf, buf_queue->pool_limit); 12410 } 12411 soc_mem_field32_set(unit, mem1, 12412 entry1, RESET_OFFSET_CELLf, buf_queue->pool_resume / 8); 12413 12414 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 12415 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 12416 soc_mem_field32_set(unit, mem, entry0, 12417 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 12418 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf, 12419 buf_queue->yellow_limit 12420 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 12421 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 12422 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf, 12423 buf_queue->red_limit 12424 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 12425 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 12426 } else { 12427 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 12428 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf, 12429 (buf_queue->yellow_limit + 7) / 8); 12430 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf, 12431 (buf_queue->red_limit + 7) / 8); 12432 } 12433 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf, 12434 buf_queue->yellow_resume / 8); 12435 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf, 12436 buf_queue->red_resume / 8); 12437 SOC_IF_ERROR_RETURN 12438 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12439 12440 SOC_IF_ERROR_RETURN 12441 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1)); 12442 12443 sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t)); 12444 soc_mem_field32_set(unit, mem2, 12445 entry0, Q_SPIDf, buf_queue->pool_idx); 12446 if (buf_queue->discard_enable) { 12447 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 12448 } 12449 if (buf_queue->color_discard_enable) { 12450 soc_mem_field32_set(unit, mem2, entry0, QGROUP_COLOR_ENABLE_CELLf, 1); 12451 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_ENABLE_CELLf, 1); 12452 } 12453 if (buf_queue->qgroup_id >= 0) { 12454 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1); 12455 soc_mem_field32_set(unit, mem2, entry0, QGROUPf, buf_queue->qgroup_id); 12456 if (buf_queue->qgroup_min_enable) { 12457 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1); 12458 } 12459 } 12460 if (soc_mem_field_length(unit, mem2, Q_E2ECC_DS_CONFIGf) > 2) { 12461 e2ecc_ds_config = IS_AP_HSP_PORT(unit,port) ? 4 : 1; 12462 } else { 12463 if (IS_AP_HSP_PORT(unit,port)) { 12464 if ((idx < 8) && (buf_queue->qgroup_id < 0)) { 12465 /* If HSP port does not use qgroup for its lower 8 queues */ 12466 soc_mem_field32_set(unit, mem2, entry0, QGROUPf, idx); 12467 e2ecc_ds_config = 2; 12468 } else { 12469 e2ecc_ds_config = 1; 12470 } 12471 } else { 12472 /* LLS port */ 12473 e2ecc_ds_config = 1; 12474 } 12475 } 12476 12477 soc_mem_field32_set(unit, mem2, entry0, Q_E2ECC_DS_CONFIGf, e2ecc_ds_config); 12478 12479 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 12480 base + idx, entry0)); 12481 } 12482 12483 /* Per port per pool unicast */ 12484 for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) { 12485 buf_pool = &buf->pools[idx]; 12486 12487 if (buf_pool->total == 0) { 12488 continue; 12489 } 12490 total_rsvd = 0; 12491 buf_rqe = 0; 12492 rqe_rsvd = 0; 12493 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 12494 /* Legacy flex port (:i) is not enabled 12495 * Overwrite total_rsvd with flexport reservations made 12496 * Add cpu & lb port egr rsvd entries */ 12497 if (devcfg->flags & SOC_MMU_CFG_F_RQE) { 12498 for (rqe = 0; rqe < 11; rqe++) { 12499 buf_rqe = &buf->rqe_queues[rqe]; 12500 rqe_rsvd += buf_rqe->guarantee; 12501 } 12502 } 12503 if (lossless) { 12504 total_rsvd = egr_rsvd + rqe_rsvd; 12505 } else { 12506 total_rsvd = egr_rsvd + 12507 soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) + 12508 soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) + 12509 rqe_rsvd; 12510 } 12511 } else { 12512 12513 total_rsvd = buf_pool->queue_guarantee + q_reserved; 12514 } 12515 limit = buf_pool->total - total_rsvd ; 12516 mem2 = MMU_THDU_XPIPE_CONFIG_PORTm; 12517 index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx); 12518 mem3 = MMU_THDU_XPIPE_RESUME_PORTm; 12519 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t)); 12520 sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_resume_port_entry_t)); 12521 12522 soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit); 12523 soc_mem_field32_set(unit, mem3, entry1, 12524 SHARED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8); 12525 12526 soc_mem_field32_set(unit, mem2, entry0, YELLOW_LIMITf, (limit + 7)/8); 12527 soc_mem_field32_set(unit, mem3, entry1, 12528 YELLOW_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8); 12529 12530 soc_mem_field32_set(unit, mem2, entry0, RED_LIMITf, (limit + 7)/8); 12531 soc_mem_field32_set(unit, mem3, entry1, 12532 RED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8); 12533 12534 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 12535 index1, entry0)); 12536 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem3, MEM_BLOCK_ALL, 12537 index1, entry1)); 12538 } 12539 } 12540 12541 if (input_port == -1) { 12542 /* RQE */ 12543 for (idx = 0; idx < 11; idx++) { 12544 buf_rqe_queue = &buf->rqe_queues[idx]; 12545 12546 rval = 0; 12547 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 12548 &rval, MIN_LIMITf, buf_rqe_queue->guarantee); 12549 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval)); 12550 12551 rval = 0; 12552 rval2 = 0; 12553 rval3 = 0; 12554 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 12555 &rval, SPIDf, buf_rqe_queue->pool_idx); 12556 12557 if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 12558 (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 12559 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 12560 &rval, COLOR_LIMIT_DYNAMICf, 1); 12561 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12562 SHARED_RED_LIMITf, buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 12563 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12564 SHARED_YELLOW_LIMITf, buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 12565 } else { 12566 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12567 SHARED_RED_LIMITf, (buf_rqe_queue->red_limit + 7)/ 8); 12568 12569 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 12570 SHARED_YELLOW_LIMITf, (buf_rqe_queue->yellow_limit + 7) / 8); 12571 } 12572 12573 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 12574 (buf_rqe_queue->discard_enable ? 1 : 0)); 12575 12576 if (buf_rqe_queue->pool_scale != -1) { 12577 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 12578 &rval, DYNAMIC_ENABLEf, 1); 12579 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 12580 SHARED_ALPHAf, buf_rqe_queue->pool_scale); 12581 } else { 12582 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 12583 SHARED_LIMITf, buf_rqe_queue->pool_limit); 12584 } 12585 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 2); 12586 12587 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval)); 12588 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr_REG32(unit, idx, rval2)); 12589 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 12590 12591 rval = 0; 12592 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 12593 &rval, RESET_OFFSET_REDf, (default_mtu_cells * 2)/8); 12594 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 12595 &rval, RESET_OFFSET_YELLOWf, (default_mtu_cells * 2)/8); 12596 SOC_IF_ERROR_RETURN( 12597 WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 12598 12599 /* queue entry */ 12600 buf_pool = &buf->pools[buf_rqe_queue->pool_idx]; 12601 fval = ((buf_pool->total_rqe_entry + 7) / 8); 12602 rval = 0; 12603 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 12604 &rval, MIN_LIMITf, buf_rqe_queue->guarantee/8); 12605 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval)); 12606 12607 rval = 0; 12608 rval2 = 0; 12609 rval3 = 0; 12610 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 12611 &rval, SPIDf, buf_rqe_queue->pool_idx); 12612 12613 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 12614 &rval, COLOR_LIMIT_DYNAMICf, lossless ? 0 : 1); 12615 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 12616 &rval3, SHARED_RED_LIMITf, lossless ? fval : 0); 12617 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 12618 &rval3, SHARED_YELLOW_LIMITf, lossless ? fval : 0); 12619 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, DYNAMIC_ENABLEf, 12620 lossless ? 0 :1); 12621 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 12622 lossless ? 0 :1); 12623 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 12624 SHARED_LIMITf, lossless ? fval : 8); 12625 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 1); 12626 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval)); 12627 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2)); 12628 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 12629 12630 rval = 0; 12631 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 12632 &rval, RESET_OFFSET_REDf, default_mtu_cells/8); 12633 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 12634 &rval, RESET_OFFSET_YELLOWf, default_mtu_cells/8); 12635 SOC_IF_ERROR_RETURN( 12636 WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 12637 12638 } 12639 12640 /* per pool RQE settings */ 12641 rqe_rsvd = 0; 12642 total_rsvd = 0; 12643 for (idx = 0; idx < 4; idx++) { 12644 buf_pool = &buf->pools[idx]; 12645 if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) || 12646 (buf_pool->total == 0)) { 12647 continue; 12648 } 12649 12650 if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) { 12651 /* Legacy flex port (:i) is not enabled 12652 * Overwrite total_rsvd with flexport reservations made 12653 * Add cpu & lb port egr rsvd entries */ 12654 if (devcfg->flags & SOC_MMU_CFG_F_RQE) { 12655 for (rqe = 0; rqe < 11; rqe++) { 12656 buf_rqe = &buf->rqe_queues[rqe]; 12657 rqe_rsvd += buf_rqe->guarantee; 12658 } 12659 } 12660 if (lossless) { 12661 total_rsvd = egr_rsvd + rqe_rsvd; 12662 } else { 12663 total_rsvd = egr_rsvd + 12664 soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) + 12665 soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) + 12666 rqe_rsvd; 12667 } 12668 } else { 12669 total_rsvd = buf_pool->queue_guarantee + q_reserved; 12670 } 12671 limit = buf_pool->total - total_rsvd - asf_rsvd; 12672 12673 12674 rval = 0; 12675 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, 12676 &rval, SHARED_LIMITf, limit); 12677 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval, RESUME_LIMITf, 12678 (limit - (default_mtu_cells * 2) + 7)/8); 12679 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr_REG32(unit, idx, rval)); 12680 12681 rval = 0; 12682 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 12683 SHARED_RED_LIMITf, (limit + 7)/8); 12684 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 12685 SHARED_YELLOW_LIMITf, (limit + 7)/8); 12686 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval)); 12687 12688 rval = 0; 12689 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 12690 RESUME_RED_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8); 12691 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 12692 RESUME_YELLOW_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8); 12693 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit, 12694 idx, rval)); 12695 if (lossless) { 12696 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) - 1 ; 12697 } else { 12698 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) ; 12699 } 12700 if (rqlen == 0) { 12701 continue; 12702 } 12703 12704 rval = 0; 12705 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, SHARED_LIMITf, rqlen); 12706 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, RESUME_LIMITf, rqlen - 1); 12707 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval)); 12708 12709 rval = 0; 12710 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 12711 SHARED_RED_LIMITf, rqlen); 12712 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 12713 SHARED_YELLOW_LIMITf, rqlen); 12714 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, idx, rval)); 12715 12716 rval = 0; 12717 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 12718 RESUME_RED_LIMITf, rqlen - 1); 12719 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 12720 RESUME_YELLOW_LIMITf, rqlen - 1); 12721 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 12722 idx, rval)); 12723 } 12724 12725 /* Device level config setting */ 12726 if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) { 12727 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 12728 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 12729 UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1); 12730 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 12731 } 12732 } 12733 return SOC_E_NONE; 12734 } 12735 12736 STATIC int 12737 _soc_apache_mmu_config_shared_update_check(int unit, int val1, int val2, int flags) 12738 { 12739 int rv = 0; 12740 if (flags == 1) { 12741 if (val1 > val2) { 12742 rv = 1; 12743 } 12744 } else { 12745 if (val1 < val2) { 12746 rv = 1; 12747 } 12748 } 12749 return rv; 12750 } 12751 12752 int 12753 soc_apache_mmu_config_shared_buf_recalc(int unit, uint32 spid, int shared_size, int flags) 12754 { 12755 soc_info_t *si; 12756 soc_mem_t mem, mem2; 12757 soc_reg_t reg = INVALIDr; 12758 soc_field_t field = INVALIDf; 12759 uint32 rval, rval2; 12760 uint32 entry0[SOC_MAX_MEM_WORDS]; 12761 thdi_port_pg_config_entry_t pg_config_mem; 12762 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 12763 int port, base, qbase, numq, idx; 12764 int cur_limit, midx, index1; 12765 int granularity; 12766 uint16 dev_id; 12767 uint8 rev_id; 12768 12769 static const soc_field_t pg_spid_field[] = { 12770 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 12771 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 12772 }; 12773 12774 if (spid >= _APACHE_MMU_NUM_POOL) { 12775 return SOC_E_PARAM; 12776 } 12777 12778 soc_cm_get_id(unit, &dev_id, &rev_id); 12779 12780 si = &SOC_INFO(unit); 12781 12782 /* per service pool settings */ 12783 idx = spid; 12784 rval = 0; 12785 reg = MMU_THDM_DB_POOL_SHARED_LIMITr; 12786 field = SHARED_LIMITf; 12787 granularity = 1; 12788 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12789 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12790 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12791 soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 12792 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12793 } 12794 12795 rval = 0; 12796 reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr; 12797 field = YELLOW_SHARED_LIMITf; 12798 granularity = 8; 12799 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12800 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12801 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12802 soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 12803 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12804 } 12805 12806 rval = 0; 12807 reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr; 12808 field = RED_SHARED_LIMITf; 12809 granularity = 8; 12810 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval)); 12811 cur_limit = soc_reg_field_get(unit, reg, rval, field); 12812 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12813 soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 12814 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 12815 } 12816 12817 /* configure Q-groups */ 12818 mem = MMU_THDU_XPIPE_CONFIG_QGROUPm; 12819 for (idx = 0; idx < SOC_APACHE_MMU_CFG_QGROUP_MAX; idx++) { 12820 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 12821 12822 SOC_IF_ERROR_RETURN 12823 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12824 12825 field = Q_SHARED_LIMIT_CELLf; 12826 granularity = 1; 12827 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) { 12828 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12829 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12830 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12831 field, shared_size/granularity); 12832 } 12833 } 12834 12835 granularity = 8; 12836 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, 12837 Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 12838 field = LIMIT_RED_CELLf; 12839 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12840 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12841 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12842 field, shared_size/granularity); 12843 } 12844 12845 field = LIMIT_YELLOW_CELLf; 12846 cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field); 12847 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12848 soc_mem_field32_set(unit, mem, &cfg_qgrp, 12849 field, shared_size/granularity); 12850 } 12851 } 12852 12853 SOC_IF_ERROR_RETURN 12854 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 12855 12856 } 12857 12858 /* Input port per port settings */ 12859 PBMP_ALL_ITER(unit, port) { 12860 rval = 0; 12861 /* Input port per port per priority group settings */ 12862 mem = THDI_PORT_PG_CONFIG_Xm; 12863 field = PG_SHARED_LIMITf; 12864 granularity = 1; 12865 for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) { 12866 SOC_IF_ERROR_RETURN(READ_THDI_PORT_PG_SPIDr(unit, port, &rval)); 12867 if (spid != soc_reg_field_get(unit, THDI_PORT_PG_SPIDr, rval, 12868 pg_spid_field[idx])){ 12869 continue; 12870 } 12871 midx = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12872 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 12873 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 12874 MEM_BLOCK_ALL, midx, &pg_config_mem)); 12875 if (!soc_mem_field32_get(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf)) { 12876 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, field); 12877 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12878 soc_mem_field32_set(unit, mem, &pg_config_mem, 12879 field, shared_size/granularity); 12880 } 12881 } 12882 12883 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 12884 MEM_BLOCK_ALL, midx, &pg_config_mem)); 12885 } 12886 } 12887 12888 /*********************************** 12889 * THDO 12890 */ 12891 /* Output port per port per queue setting for regular multicast queue */ 12892 PBMP_PORT_ITER(unit, port) { 12893 12894 numq = si->port_num_cosq[port]; 12895 qbase = si->port_cosq_base[port]; 12896 if (numq == 0) { 12897 continue; 12898 } 12899 12900 mem = MMU_THDM_DB_QUEUE_CONFIG_0m; 12901 base = soc_apache_l2_hw_index(unit, qbase, 0) - _APACHE_MC_QUEUE_BASE; 12902 12903 for (idx = 0; idx < numq; idx++) { 12904 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 12905 12906 SOC_IF_ERROR_RETURN 12907 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 12908 12909 if (spid != soc_mem_field32_get(unit, mem, entry0, Q_SPIDf)){ 12910 continue; 12911 } 12912 field = Q_SHARED_LIMITf; 12913 granularity = 1; 12914 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 12915 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12916 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12917 soc_mem_field32_set(unit, mem, entry0, 12918 field, shared_size/granularity); 12919 } 12920 } 12921 12922 granularity = 8; 12923 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 12924 field = YELLOW_SHARED_LIMITf; 12925 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12926 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12927 soc_mem_field32_set(unit, mem, entry0, 12928 field, shared_size/granularity); 12929 } 12930 field = RED_SHARED_LIMITf; 12931 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12932 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12933 soc_mem_field32_set(unit, mem, entry0, 12934 field, shared_size/granularity); 12935 } 12936 } 12937 SOC_IF_ERROR_RETURN 12938 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, 12939 entry0)); 12940 } 12941 12942 /* Per port per pool */ 12943 idx = spid; 12944 mem = MMU_THDM_DB_PORTSP_CONFIG_0m; 12945 index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 12946 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t)); 12947 12948 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 12949 index1, entry0)); 12950 12951 field = SHARED_LIMITf; 12952 granularity = 1; 12953 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12954 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12955 soc_mem_field32_set(unit, mem, entry0, 12956 field, shared_size/granularity); 12957 } 12958 12959 field = RED_SHARED_LIMITf; 12960 granularity = 8; 12961 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12962 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12963 soc_mem_field32_set(unit, mem, entry0, 12964 field, shared_size/granularity); 12965 } 12966 12967 field = YELLOW_SHARED_LIMITf; 12968 granularity = 8; 12969 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 12970 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 12971 soc_mem_field32_set(unit, mem, entry0, 12972 field, shared_size/granularity); 12973 } 12974 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 12975 index1, entry0)); 12976 } 12977 12978 /* Output port per port per queue setting for regular unicast queue */ 12979 PBMP_PORT_ITER(unit, port) { 12980 /* per port regular unicast queue */ 12981 numq = si->port_num_uc_cosq[port]; 12982 qbase = si->port_uc_cosq_base[port]; 12983 12984 if (numq == 0) { 12985 continue; 12986 } 12987 base = soc_apache_l2_hw_index(unit, qbase, 1); 12988 mem = MMU_THDU_XPIPE_CONFIG_QUEUEm; 12989 mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm; 12990 for (idx = 0; idx < numq; idx++) { 12991 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_q_to_qgrp_map_entry_t)); 12992 SOC_IF_ERROR_RETURN 12993 (soc_mem_read(unit, mem2, MEM_BLOCK_ALL, base+idx, entry0)); 12994 if (spid != soc_mem_field32_get(unit, mem2, entry0, Q_SPIDf)){ 12995 continue; 12996 } 12997 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t)); 12998 12999 SOC_IF_ERROR_RETURN 13000 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 13001 13002 field = Q_SHARED_LIMIT_CELLf; 13003 granularity = 1; 13004 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) { 13005 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 13006 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13007 soc_mem_field32_set(unit, mem, entry0, 13008 field, shared_size/granularity); 13009 } 13010 } 13011 13012 granularity = 8; 13013 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 13014 field = LIMIT_YELLOW_CELLf; 13015 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 13016 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13017 soc_mem_field32_set(unit, mem, entry0, 13018 field, shared_size/granularity); 13019 } 13020 field = LIMIT_RED_CELLf; 13021 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 13022 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13023 soc_mem_field32_set(unit, mem, entry0, 13024 field, shared_size/granularity); 13025 } 13026 } 13027 SOC_IF_ERROR_RETURN 13028 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 13029 } 13030 13031 /* Per port per pool unicast */ 13032 idx = spid; 13033 mem = MMU_THDU_XPIPE_CONFIG_PORTm; 13034 index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx); 13035 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t)); 13036 13037 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 13038 index1, entry0)); 13039 13040 field = SHARED_LIMITf; 13041 granularity = 1; 13042 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 13043 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13044 soc_mem_field32_set(unit, mem, entry0, 13045 field, shared_size/granularity); 13046 } 13047 13048 granularity = 8; 13049 field = YELLOW_LIMITf; 13050 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 13051 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13052 soc_mem_field32_set(unit, mem, entry0, 13053 field, shared_size/granularity); 13054 } 13055 field = RED_LIMITf; 13056 cur_limit = soc_mem_field32_get(unit, mem, entry0, field); 13057 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13058 soc_mem_field32_set(unit, mem, entry0, 13059 field, shared_size/granularity); 13060 } 13061 13062 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 13063 index1, entry0)); 13064 } 13065 13066 /* RQE */ 13067 for (idx = 0; idx < 11; idx++) { 13068 rval = 0; 13069 rval2 = 0; 13070 13071 SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval)); 13072 if (spid != soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, SPIDf)){ 13073 continue; 13074 } 13075 13076 reg = MMU_THDR_DB_CONFIG_PRIQr; 13077 field = SHARED_LIMITf; 13078 granularity = 1; 13079 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 13080 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 13081 DYNAMIC_ENABLEf)) { 13082 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 13083 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13084 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 13085 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 13086 } 13087 } 13088 13089 rval2 = 0; 13090 reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr; 13091 granularity = 8; 13092 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 13093 13094 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 13095 COLOR_LIMIT_DYNAMICf)) { 13096 field = SHARED_RED_LIMITf; 13097 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 13098 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13099 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 13100 } 13101 13102 field = SHARED_YELLOW_LIMITf; 13103 cur_limit = soc_reg_field_get(unit, reg, rval2, field); 13104 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13105 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 13106 } 13107 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 13108 } 13109 13110 } 13111 13112 /* per pool RQE settings */ 13113 idx = spid; 13114 reg = MMU_THDR_DB_CONFIG_SPr; 13115 field = SHARED_LIMITf; 13116 granularity = 1; 13117 13118 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 13119 13120 cur_limit = soc_reg_field_get(unit, reg, rval, field); 13121 13122 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) { 13123 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 13124 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 13125 } 13126 13127 reg = MMU_THDR_DB_SP_SHARED_LIMITr; 13128 granularity = 8; 13129 13130 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2)); 13131 13132 field =SHARED_YELLOW_LIMITf; 13133 cur_limit = soc_reg_field_get(unit, reg, rval, field); 13134 13135 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){ 13136 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 13137 } 13138 13139 field = SHARED_RED_LIMITf; 13140 cur_limit = soc_reg_field_get(unit, reg, rval, field); 13141 13142 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){ 13143 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 13144 } 13145 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2)); 13146 return SOC_E_NONE; 13147 } 13148 13149 int 13150 soc_apache_mmu_config_init(int unit, int test_only, soc_port_t port) 13151 { 13152 int rv; 13153 int lossless; 13154 _soc_mmu_cfg_buf_t *buf; 13155 _soc_mmu_device_info_t devcfg; 13156 13157 buf = soc_mmu_cfg_alloc(unit); 13158 if (!buf) { 13159 return SOC_E_MEMORY; 13160 } 13161 13162 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 13163 13164 _soc_apache_mmu_init_dev_config(unit, &devcfg, lossless); 13165 _soc_apache_mmu_config_buf_default(unit, buf, &devcfg, lossless); 13166 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 13167 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 13168 } 13169 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 13170 if (!test_only) { 13171 if (SOC_FAILURE(rv)) { 13172 LOG_VERBOSE(BSL_LS_SOC_COMMON, 13173 (BSL_META_U(unit, 13174 "MMU config: Use default setting\n"))); 13175 _soc_apache_mmu_config_buf_default(unit, buf, &devcfg, lossless); 13176 _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg); 13177 } 13178 rv = _soc_apache_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, port); 13179 } 13180 13181 soc_mmu_cfg_free(unit, buf); 13182 13183 LOG_VERBOSE(BSL_LS_SOC_COMMON, 13184 (BSL_META_U(unit, 13185 "MMU THDI/THDO init done\n"))); 13186 return rv; 13187 } 13188 13189 /*Clear MMU_CBPDATA for APACHE mmu_init*/ 13190 STATIC int 13191 _soc_apache_mmu_cbpdata_clear(int unit) 13192 { 13193 soc_mem_t mem; 13194 soc_mem_t cbpdata_start_m; 13195 soc_mem_t cbpdata_end_m; 13196 13197 cbpdata_start_m = MMU_CBPDATA0m; 13198 cbpdata_end_m = MMU_CBPDATA3m; 13199 13200 for (mem = cbpdata_start_m; mem <= cbpdata_end_m; mem++) { 13201 SOC_IF_ERROR_RETURN( 13202 soc_mem_clear(unit, mem, MEM_BLOCK_ALL, TRUE)); 13203 } 13204 return SOC_E_NONE; 13205 } 13206 13207 13208 STATIC int 13209 _soc_apache_mmu_init(int unit) 13210 { 13211 uint32 rval; 13212 uint64 rval64; 13213 soc_info_t *si; 13214 int total_entries, clock_period, refresh_time_val; 13215 int cpu_slots; 13216 int msbus_idle_enable; 13217 int alloc_size; 13218 int port = 0; 13219 if (soc_feature(unit, soc_feature_untethered_otp)) { 13220 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu12Mb)) { 13221 _soc_ap_skew_index = 0; 13222 } else if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu9Mb)) { 13223 _soc_ap_skew_index = 1; 13224 } else { 13225 /*socBondInfoFeatureMmu6Mb*/ 13226 _soc_ap_skew_index = 2; 13227 } 13228 } else { 13229 /*socBondInfoFeatureMmu12Mb*/ 13230 _soc_ap_skew_index = 0; 13231 } 13232 13233 /* MMU Settings Configuration */ 13234 SOC_IF_ERROR_RETURN(soc_apache_mmu_config_init(unit, SAL_BOOT_BCMSIM, -1)); 13235 13236 rval = 0; 13237 soc_reg_field_set(unit, LLS_CONFIG0r, &rval, FC_ENABLEf, 1); 13238 soc_reg_field_set(unit, LLS_CONFIG0r, &rval, ENQUEUE_ENABLEf, 1); 13239 soc_reg_field_set(unit, LLS_CONFIG0r, &rval, DEQUEUE_ENABLEf, 1); 13240 soc_reg_field_set(unit, LLS_CONFIG0r, &rval, PORT_SCHEDULER_ENABLEf, 1); 13241 SOC_IF_ERROR_RETURN(WRITE_LLS_CONFIG0r(unit, rval)); 13242 13243 rval = 0; 13244 soc_reg_field_set(unit, PRIORITY_CONTROLr, &rval, USE_SC_FOR_MH_PRIf, 1); 13245 soc_reg_field_set(unit, PRIORITY_CONTROLr, &rval, USE_QM_FOR_MH_PRIf, 1); 13246 SOC_IF_ERROR_RETURN(WRITE_PRIORITY_CONTROLr(unit, rval)); 13247 13248 /* Enable IP to CMICM credit transfer */ 13249 rval = 0; 13250 soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval, 13251 TRANSFER_ENABLEf, 1); 13252 soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval, 13253 NUM_OF_CREDITSf, 32); 13254 SOC_IF_ERROR_RETURN(WRITE_IP_TO_CMICM_CREDIT_TRANSFERr(unit, rval)); 13255 13256 if (_fwd_ctrl_lock[unit] == NULL) { 13257 _fwd_ctrl_lock[unit] = sal_mutex_create("_fwd_ctrl_lock"); 13258 } 13259 13260 if (_fwd_ctrl_lock[unit] == NULL) { 13261 return SOC_E_MEMORY; 13262 } 13263 13264 /*mmu traffic control*/ 13265 alloc_size = sizeof(_soc_apache_mmu_traffic_ctrl_t); 13266 if (_soc_apache_mmu_traffic_ctrl[unit] == NULL) { 13267 _soc_apache_mmu_traffic_ctrl[unit] = 13268 sal_alloc(alloc_size,"_soc_apache_mmu_traffic_ctrl"); 13269 if (_soc_apache_mmu_traffic_ctrl[unit] == NULL) { 13270 return SOC_E_MEMORY; 13271 } 13272 } 13273 sal_memset(_soc_apache_mmu_traffic_ctrl[unit], 0, alloc_size); 13274 13275 13276 /* Enable all ports */ 13277 COMPILER_64_ZERO(rval64); 13278 if (!soc_ap_is_skip_default_lls_creation(unit)) { 13279 COMPILER_64_SET(rval64, 0xffffffff, 0xffffffff); 13280 SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE0_64r(unit, rval64)); 13281 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE0_64r(unit, rval64)); 13282 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r(unit, rval64)); 13283 COMPILER_64_SET(rval64, 0x0, 0x3ff); 13284 SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE1_64r(unit, rval64)); 13285 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE1_64r(unit, rval64)); 13286 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r(unit, rval64)); 13287 } else { 13288 PBMP_ALL_ITER(unit, port) 13289 { 13290 if (IS_CPU_PORT(unit, port) || 13291 IS_AP_HSP_PORT(unit,port) || 13292 IS_LB_PORT(unit, port)) 13293 { _soc_apache_thdo_hw_set(unit, port, 1); 13294 13295 } 13296 } 13297 } 13298 si = &SOC_INFO(unit); 13299 13300 /* 13301 * Refresh Value = 13302 * ((total no of entities to be refreshed) X Core clk period in ns)/Wred tick period 50 ns 13303 */ 13304 13305 total_entries = 4096 + 1024; 13306 cpu_slots = (total_entries * 2) / 16; /* 2 slots for every 16 entries refreshed */ 13307 clock_period = (1 * 1000 * 1000) / si->frequency; /*clock period in microseconds */ 13308 13309 SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval)); 13310 msbus_idle_enable = soc_reg_field_get(unit, WRED_REFRESH_CONTROLr, 13311 rval, MSBUS_IDLE_ENABLEf); 13312 13313 if (msbus_idle_enable) { 13314 refresh_time_val = ((total_entries + cpu_slots) * clock_period) / 50; 13315 } else { 13316 refresh_time_val = (total_entries * clock_period) / 50; 13317 } 13318 refresh_time_val = refresh_time_val / 1000; /* micro to nano seconds */ 13319 13320 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 13321 REFRESH_TIME_VALf, refresh_time_val); 13322 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 13323 REFRESH_DISABLEf, 0); 13324 SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval)); 13325 13326 /* Clear MMU_CBPData */ 13327 SOC_IF_ERROR_RETURN(_soc_apache_mmu_cbpdata_clear(unit)); 13328 13329 SOC_IF_ERROR_RETURN(soc_apache_lls_init(unit)); 13330 13331 SOC_IF_ERROR_RETURN 13332 (soc_reg_field32_modify(unit, OOBFC_CHANNEL_BASE_64r, REG_PORT_ANY, 13333 ENG_ENf, 1)); 13334 13335 if (soc_feature(unit, soc_feature_post)) { 13336 SOC_IF_ERROR_RETURN(soc_mmu_post_init(unit)); 13337 } 13338 13339 PBMP_ALL_ITER(unit, port) { 13340 if (IS_CPU_PORT(unit, port) || 13341 IS_LB_PORT(unit, port) || 13342 IS_RDB_PORT(unit, port)) 13343 { 13344 continue; 13345 } 13346 COMPILER_64_ZERO(rval64); 13347 soc_reg64_field32_set(unit, INTFO_CONGST_STr, &rval64, ENf, 1); 13348 SOC_IF_ERROR_RETURN(WRITE_INTFO_CONGST_STr(unit, port, rval64)); 13349 rval = 0; 13350 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13351 COS0_E2E_DS_ENf , 1); 13352 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13353 COS1_E2E_DS_ENf , 1); 13354 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13355 COS2_E2E_DS_ENf , 1); 13356 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13357 COS3_E2E_DS_ENf , 1); 13358 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13359 COS4_E2E_DS_ENf , 1); 13360 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13361 COS5_E2E_DS_ENf , 1); 13362 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13363 COS6_E2E_DS_ENf , 1); 13364 soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 13365 COS7_E2E_DS_ENf , 1); 13366 WRITE_THDU_PORT_E2ECC_COS_SPIDr(unit , port , rval); 13367 } 13368 13369 return SOC_E_NONE; 13370 } 13371 13372 13373 STATIC int 13374 _soc_apache_age_timer_get(int unit, int *age_seconds, int *enabled) 13375 { 13376 soc_control_t *soc = SOC_CONTROL(unit); 13377 uint32 rval; 13378 13379 if (!soc->l2x_sw_aging) { 13380 SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval)); 13381 *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf); 13382 *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf); 13383 } else { 13384 *enabled = soc->l2x_age_pid != SAL_THREAD_ERROR && 13385 soc->l2x_age_enable ? 13386 1 : 0; 13387 *age_seconds = soc->l2x_age_pid != SAL_THREAD_ERROR && 13388 soc->l2x_age_enable ? 13389 soc->l2x_age_interval : 0; 13390 } 13391 13392 return SOC_E_NONE; 13393 } 13394 13395 STATIC int 13396 _soc_apache_age_timer_max_get(int unit, int *max_seconds) 13397 { 13398 soc_control_t *soc = SOC_CONTROL(unit); 13399 13400 if (!soc->l2x_sw_aging) { 13401 *max_seconds = 13402 soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf); 13403 } else { 13404 *max_seconds = 0x7fffffff; 13405 } 13406 13407 return SOC_E_NONE; 13408 } 13409 13410 STATIC int 13411 _soc_apache_age_timer_set(int unit, int age_seconds, int enable) 13412 { 13413 soc_control_t *soc = SOC_CONTROL(unit); 13414 sal_usecs_t interval = soc->l2x_age_interval; 13415 uint32 rval = 0; 13416 13417 if (!soc->l2x_sw_aging) { 13418 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable); 13419 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds); 13420 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval)); 13421 } else if (soc->l2x_age_interval) { 13422 if (!enable) { 13423 soc->l2x_age_enable = 0; 13424 } else { 13425 if (age_seconds) { 13426 SOC_CONTROL_LOCK(unit); 13427 soc->l2x_age_interval = age_seconds; 13428 SOC_CONTROL_UNLOCK(unit); 13429 } 13430 soc->l2x_age_enable = 1; 13431 if (interval != age_seconds) { 13432 sal_sem_give(soc->l2x_age_notify); 13433 } 13434 } 13435 } else { 13436 if (enable) { 13437 SOC_IF_ERROR_RETURN 13438 (soc_td2_l2_bulk_age_start(unit, age_seconds)); 13439 } 13440 } 13441 13442 return SOC_E_NONE; 13443 } 13444 13445 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 13446 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 13447 13448 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 13449 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 13450 13451 STATIC int 13452 _soc_apache_mdio_addr_to_port(uint32 phy_addr) 13453 { 13454 int bus, offset = 0; 13455 13456 /* Must be internal MDIO address */ 13457 if ((phy_addr & 0x80) == 0) { 13458 return 0; 13459 } 13460 13461 /* 13462 * Internal phy address: 13463 * bus 0 phy 1 to 28 are mapped to Physical port 1 to 28 13464 * bus 1 phy 1 to 20 are mapped to Physical port 29 to 48 13465 * bus 2 phy 1 to 24 are mapped to Physical port 49 to 72 13466 */ 13467 bus = PHY_ID_BUS_NUM(phy_addr); 13468 if (bus > 2) { 13469 return 0; 13470 } 13471 13472 switch (bus) { 13473 case 0: offset = 0; break; 13474 case 1: offset = 28; break; 13475 case 2: offset = 48; break; 13476 } 13477 13478 13479 return (phy_addr & 0x1f) + offset; 13480 } 13481 13482 STATIC int 13483 _soc_apache_mdio_reg_read(int unit, uint32 phy_addr, 13484 uint32 phy_reg, uint32 *phy_data) 13485 { 13486 int port, phy_port, blk; 13487 soc_mem_t ucmem_data; 13488 soc_reg_t ucmem_ctrl; 13489 13490 /* Physical port based on MDIO address */ 13491 phy_port = _soc_apache_mdio_addr_to_port(phy_addr); 13492 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 13493 blk = SOC_PORT_BLOCK(unit, phy_port); 13494 13495 if ((phy_port >= 17 && phy_port <= 28) || 13496 (phy_port >= 53 && phy_port <= 64)) { 13497 ucmem_data = CXXPORT_WC_UCMEM_DATA0m; 13498 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r; 13499 SOC_IF_ERROR_RETURN(soc_apache_port_reg_blk_index_get(unit, port, SOC_BLK_CXXPORT, &blk)); 13500 13501 } else if (IS_CL_PORT(unit, port) || IS_CLG2_PORT(unit, port)) { 13502 ucmem_data = CLPORT_WC_UCMEM_DATAm; 13503 ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr; 13504 13505 } else { 13506 ucmem_data = XLPORT_WC_UCMEM_DATAm; 13507 ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr; 13508 13509 } 13510 13511 if (phy_port >= 17 && phy_port <= 28) { 13512 if (phy_port >= 17 && phy_port <= 20) { 13513 ucmem_data = CXXPORT_WC_UCMEM_DATA0m; 13514 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r; 13515 } else if (phy_port >= 21 && phy_port <= 24) { 13516 ucmem_data = CXXPORT_WC_UCMEM_DATA1m; 13517 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r; 13518 } else { 13519 ucmem_data = CXXPORT_WC_UCMEM_DATA2m; 13520 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r; 13521 } 13522 } else if (phy_port >= 53 && phy_port <= 64) { 13523 if (phy_port >= 53 && phy_port <= 56) { 13524 ucmem_data = CXXPORT_WC_UCMEM_DATA0m; 13525 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r; 13526 } else if (phy_port >= 57 && phy_port <= 60) { 13527 ucmem_data = CXXPORT_WC_UCMEM_DATA1m; 13528 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r; 13529 } else { 13530 ucmem_data = CXXPORT_WC_UCMEM_DATA2m; 13531 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r; 13532 } 13533 } 13534 13535 LOG_INFO(BSL_LS_SOC_MII, 13536 (BSL_META_U(unit, 13537 "soc_apache_mdio_reg_read[%d]: %d/%d/%d\n"), 13538 unit, phy_addr, phy_port, port)); 13539 13540 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 13541 13542 /* Call common S-bus MDIO read function */ 13543 return soc_sbus_mdio_reg_read(unit, port, blk, 0, 13544 phy_addr, phy_reg, phy_data, 13545 ucmem_data, ucmem_ctrl); 13546 13547 } 13548 13549 STATIC int 13550 _soc_apache_mdio_reg_write(int unit, uint32 phy_addr, 13551 uint32 phy_reg, uint32 phy_data) 13552 { 13553 int port, phy_port, blk; 13554 soc_mem_t ucmem_data; 13555 soc_reg_t ucmem_ctrl; 13556 13557 /* Physical port based on MDIO address */ 13558 phy_port = _soc_apache_mdio_addr_to_port(phy_addr); 13559 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 13560 blk = SOC_PORT_BLOCK(unit, phy_port); 13561 13562 13563 if ((phy_port >= 17 && phy_port <= 28) || 13564 (phy_port >= 53 && phy_port <= 64)) { 13565 ucmem_data = CXXPORT_WC_UCMEM_DATA0m; 13566 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r; 13567 SOC_IF_ERROR_RETURN(soc_apache_port_reg_blk_index_get(unit, port, SOC_BLK_CXXPORT, &blk)); 13568 13569 } else if (IS_CL_PORT(unit, port) || IS_CLG2_PORT(unit, port)) { 13570 ucmem_data = CLPORT_WC_UCMEM_DATAm; 13571 ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr; 13572 13573 } else { 13574 ucmem_data = XLPORT_WC_UCMEM_DATAm; 13575 ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr; 13576 13577 } 13578 13579 if (phy_port >= 17 && phy_port <= 28) { 13580 if (phy_port >= 17 && phy_port <= 20) { 13581 ucmem_data = CXXPORT_WC_UCMEM_DATA0m; 13582 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r; 13583 } else if (phy_port >= 21 && phy_port <= 24) { 13584 ucmem_data = CXXPORT_WC_UCMEM_DATA1m; 13585 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r; 13586 } else { 13587 ucmem_data = CXXPORT_WC_UCMEM_DATA2m; 13588 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r; 13589 } 13590 } else if (phy_port >= 53 && phy_port <= 64) { 13591 if (phy_port >= 53 && phy_port <= 56) { 13592 ucmem_data = CXXPORT_WC_UCMEM_DATA0m; 13593 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r; 13594 } else if (phy_port >= 57 && phy_port <= 60) { 13595 ucmem_data = CXXPORT_WC_UCMEM_DATA1m; 13596 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r; 13597 } else { 13598 ucmem_data = CXXPORT_WC_UCMEM_DATA2m; 13599 ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r; 13600 } 13601 } 13602 13603 LOG_INFO(BSL_LS_SOC_MII, 13604 (BSL_META_U(unit, 13605 "soc_apache_mdio_reg_read[%d]: %d/%d/%d\n"), 13606 unit, phy_addr, phy_port, port)); 13607 13608 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 13609 13610 13611 /* Call common S-bus MDIO read function */ 13612 return soc_sbus_mdio_reg_write(unit, port, blk, 0, 13613 phy_addr, phy_reg, phy_data, 13614 ucmem_data, ucmem_ctrl); 13615 } 13616 13617 static const soc_reg_t pvtmon_result_reg[] = { 13618 TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r, 13619 TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r, 13620 TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r, 13621 TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r 13622 }; 13623 13624 13625 STATIC void 13626 soc_apache_temperature_intr(int unit) 13627 { 13628 uint32 rval, trval; 13629 int i, rv; 13630 soc_port_t port; 13631 soc_block_t blk; 13632 soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, SOC_BLOCK_TYPE_INVALID}; 13633 soc_block_t clport_blocks[] = {SOC_BLK_CLPORT, SOC_BLK_CLG2PORT, SOC_BLOCK_TYPE_INVALID}; 13634 13635 /* Raise event to app for it to take further graceful actions */ 13636 for (i = 0; i < COUNTOF(pvtmon_result_reg); i++) { 13637 if ((0x1 << i) & _soc_ap_temp_mon_mask[unit]) { 13638 if ((rv = soc_reg32_get(unit, pvtmon_result_reg[i], REG_PORT_ANY, 0, 13639 &trval)) != SOC_E_NONE) { 13640 LOG_ERROR(BSL_LS_SOC_COMMON, 13641 (BSL_META_U(unit, 13642 "AP Top Intr, Reg access error.\n"))); 13643 } 13644 trval = soc_reg_field_get(unit, pvtmon_result_reg[i], trval, 13645 PVT_DATAf); 13646 /* Convert data to temperature. 13647 * temp = 410.04-(data*0.48705) = (410040-(data*487))/1000 13648 * Note: Since this is a high temp interrupt we can safely assume 13649 * that this will end up being a +ive value. 13650 */ 13651 trval = (410040-(trval*487))/1000; 13652 LOG_ERROR(BSL_LS_SOC_COMMON, 13653 (BSL_META_U(unit, 13654 "TempMon %d: %d deg C.\n"), i, trval)); 13655 (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM, 13656 SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval); 13657 } 13658 } 13659 13660 /* Optionally hold system in reset. 13661 * Note: The main intention is to stop the chip from getting fried and halt 13662 * all schan accesses as the h/w will not respond anymore. 13663 * We are not implementing a gracefull recovery, the unit needs to be 13664 * rebooted after this. 13665 */ 13666 if (soc_property_get(unit, "temp_monitor_shutdown", 1)) { 13667 if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) { 13668 LOG_ERROR(BSL_LS_SOC_COMMON, 13669 (BSL_META_U(unit, 13670 "AP Temp Intr, Reg access error.\n"))); 13671 } 13672 13673 /* Stop all schan transactions on this unit */ 13674 #ifdef INCLUDE_I2C 13675 if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) { 13676 LOG_ERROR(BSL_LS_SOC_COMMON, 13677 (BSL_META_U(unit, 13678 "AP Temp Intr, i2c detach error.\n"))); 13679 } 13680 #endif 13681 if (!SOC_IS_RCPU_ONLY(unit)) { 13682 /* Free up DMA memory */ 13683 if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) { 13684 LOG_ERROR(BSL_LS_SOC_COMMON, 13685 (BSL_META_U(unit, 13686 "AP Temp Intr, dma detach error.\n"))); 13687 } 13688 } 13689 #ifdef INCLUDE_MEM_SCAN 13690 if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) { 13691 LOG_ERROR(BSL_LS_SOC_COMMON, 13692 (BSL_META_U(unit, 13693 "AP Temp Intr, mem scan stop error.\n"))); 13694 } 13695 #endif /* INCLUDE_MEM_SCAN */ 13696 /* Terminate counter module */ 13697 if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) { 13698 LOG_ERROR(BSL_LS_SOC_COMMON, 13699 (BSL_META_U(unit, 13700 "AP Temp Intr, counter stop error.\n"))); 13701 } 13702 if (SOC_SBUSDMA_DM_INFO(unit)) { 13703 if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) { 13704 LOG_ERROR(BSL_LS_SOC_COMMON, 13705 (BSL_META_U(unit, 13706 "AP Temp Intr, sbusdma stop error.\n"))); 13707 } 13708 } 13709 if (soc_feature(unit, soc_feature_arl_hashed)) { 13710 /* Stop L2X thread */ 13711 if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) { 13712 LOG_ERROR(BSL_LS_SOC_COMMON, 13713 (BSL_META_U(unit, 13714 "AP Temp Intr, L2x stop error.\n"))); 13715 } 13716 13717 } 13718 13719 rv = READ_TOP_SOFT_RESET_REGr(unit, &rval); 13720 if (SOC_E_NONE != rv) { 13721 LOG_ERROR(BSL_LS_SOC_COMMON, 13722 (BSL_META_U(unit, 13723 "AP Temp Intr, Reg access error.\n"))); 13724 } 13725 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 0); 13726 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0); 13727 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 0); 13728 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 0); 13729 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_RDB_RST_Lf, 0); 13730 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 0); 13731 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 0); 13732 rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval); 13733 if (SOC_E_NONE != rv) { 13734 LOG_ERROR(BSL_LS_SOC_COMMON, 13735 (BSL_META_U(unit, 13736 "AP Temp Intr, Reg access error.\n"))); 13737 } 13738 13739 if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) { 13740 LOG_ERROR(BSL_LS_SOC_COMMON, 13741 (BSL_META_U(unit, 13742 "AP Temp Intr, Reg access error.\n"))); 13743 } 13744 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf, 13745 0); 13746 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf, 13747 0); 13748 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL2_RST_Lf, 13749 0); 13750 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL3_RST_Lf, 13751 0); 13752 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 13753 1); 13754 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf, 13755 0); 13756 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf, 13757 0); 13758 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 13759 if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) { 13760 LOG_ERROR(BSL_LS_SOC_COMMON, 13761 (BSL_META_U(unit, 13762 "AP Temp Intr, Reg access error.\n"))); 13763 } 13764 /* Powerdown Falcon analog cores */ 13765 SOC_BLOCKS_ITER(unit, blk, clport_blocks) { 13766 port = SOC_BLOCK_PORT(unit, blk); 13767 rv = READ_CLPORT_XGXS0_CTRL_REGr(unit, port, &rval); 13768 if (SOC_E_NONE != rv) { 13769 LOG_ERROR(BSL_LS_SOC_COMMON, 13770 (BSL_META_U(unit, 13771 "AP Temp Intr, Reg access error.\n"))); 13772 } 13773 soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1); 13774 soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1); 13775 soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0); 13776 rv = WRITE_CLPORT_XGXS0_CTRL_REGr(unit, port, rval); 13777 if (SOC_E_NONE != rv) { 13778 LOG_ERROR(BSL_LS_SOC_COMMON, 13779 (BSL_META_U(unit, 13780 "AP Temp Intr, Reg access error.\n"))); 13781 } 13782 } 13783 /* Powerdown Eagle analog cores */ 13784 SOC_BLOCKS_ITER(unit, blk, xlport_blocks) { 13785 port = SOC_BLOCK_PORT(unit, blk); 13786 rv = READ_XLPORT_XGXS0_CTRL_REGr(unit, port, &rval); 13787 if (SOC_E_NONE != rv) { 13788 LOG_ERROR(BSL_LS_SOC_COMMON, 13789 (BSL_META_U(unit, 13790 "AP Temp Intr, Reg access error.\n"))); 13791 } 13792 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1); 13793 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1); 13794 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0); 13795 rv = WRITE_XLPORT_XGXS0_CTRL_REGr(unit, port, rval); 13796 if (SOC_E_NONE != rv) { 13797 LOG_ERROR(BSL_LS_SOC_COMMON, 13798 (BSL_META_U(unit, 13799 "AP Temp Intr, Reg access error.\n"))); 13800 } 13801 } 13802 13803 /* Disable all interrupts */ 13804 soc_cmicm_intr0_disable(unit, ~0); 13805 soc_cmicm_intr1_disable(unit, ~0); 13806 soc_cmicm_intr2_disable(unit, ~0); 13807 soc_cmicm_intr3_disable(unit, ~0); 13808 soc_cmicm_intr4_disable(unit, ~0); 13809 soc_cmicm_intr5_disable(unit, ~0); 13810 13811 /* Power down core PLL, once this is done all SCHAN accesses 13812 * will fail. 13813 */ 13814 rv = READ_TOP_CORE_PLL_CTRL_1r(unit, &rval); 13815 if (SOC_E_NONE != rv) { 13816 LOG_ERROR(BSL_LS_SOC_COMMON, 13817 (BSL_META_U(unit, 13818 "AP Temp Intr, Reg access error.\n"))); 13819 } 13820 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, ISO_INf, 1); 13821 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRONf, 0); 13822 soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRON_LDOf, 0); 13823 WRITE_TOP_CORE_PLL_CTRL_1r(unit, rval); 13824 SCHAN_LOCK(unit); 13825 13826 /* Clear all outstanding DPCs owned by this unit */ 13827 sal_dpc_cancel(INT_TO_PTR(unit)); 13828 LOG_ERROR(BSL_LS_SOC_COMMON, 13829 (BSL_META_U(unit, 13830 "\nReboot the system.."))); 13831 } 13832 } 13833 13834 13835 void 13836 soc_apache_top_intr(void *unit_vp, void *d1, void *d2, 13837 void *d3, void *d4) 13838 { 13839 uint32 rval, pvtrval; 13840 int rv, unit = PTR_TO_INT(unit_vp); 13841 13842 if ((rv = READ_TOP_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) { 13843 LOG_ERROR(BSL_LS_SOC_COMMON, 13844 (BSL_META_U(unit, 13845 "AP TOP Intr, Reg access error.\n"))); 13846 } 13847 13848 /* Bits 0-17 for PVTMON and rest for AVS */ 13849 pvtrval = rval & ((1 << 18) - 1); 13850 if (pvtrval) { 13851 LOG_ERROR(BSL_LS_SOC_COMMON, 13852 (BSL_META_U(unit, 13853 "High temp interrupt: 0x%08x\n"), rval)); 13854 13855 soc_apache_temperature_intr(unit); 13856 return; 13857 } 13858 13859 13860 13861 return; 13862 } 13863 13864 int 13865 soc_apache_temperature_monitor_get(int unit, 13866 int temperature_max, 13867 soc_switch_temperature_monitor_t *temperature_array, 13868 int *temperature_count) 13869 { 13870 soc_reg_t reg; 13871 int index; 13872 uint32 rval; 13873 int fval, cur, peak; 13874 int num_entries_out; 13875 13876 if (temperature_count) { 13877 *temperature_count = 0; 13878 } 13879 if (COUNTOF(pvtmon_result_reg) > temperature_max) { 13880 num_entries_out = temperature_max; 13881 } else { 13882 num_entries_out = COUNTOF(pvtmon_result_reg); 13883 } 13884 SOC_IF_ERROR_RETURN 13885 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, PVTMON_SELECTf, 0)); 13886 13887 SOC_IF_ERROR_RETURN 13888 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13889 PVTMON_ADC_RESETBf, 1)); 13890 SOC_IF_ERROR_RETURN 13891 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13892 PVTMON_ADC_RESETBf, 0)); 13893 SOC_IF_ERROR_RETURN 13894 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13895 PVTMON_ADC_RESETBf, 1)); 13896 13897 13898 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 13899 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13900 TOP_PVT_MON_MAX_RST_Lf, 1); 13901 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13902 TOP_PVT_MON_MIN_RST_Lf, 1); 13903 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13904 13905 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13906 TOP_PVT_MON_MAX_RST_Lf, 0); 13907 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13908 TOP_PVT_MON_MIN_RST_Lf, 0); 13909 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13910 13911 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13912 TOP_PVT_MON_MAX_RST_Lf, 1); 13913 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13914 TOP_PVT_MON_MIN_RST_Lf, 1); 13915 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13916 sal_usleep(1000); 13917 13918 for (index = 0; index < num_entries_out; index++) { 13919 reg = pvtmon_result_reg[index]; 13920 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13921 13922 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13923 cur = (4100400 - (4870 * fval)) / 1000; 13924 fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf); 13925 peak = (4100400 - (4870 * fval)) / 1000; 13926 (temperature_array + index)->curr = cur; 13927 (temperature_array + index)->peak = peak; 13928 } 13929 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 13930 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13931 TOP_PVT_MON_MAX_RST_Lf, 0); 13932 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13933 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 13934 TOP_PVT_MON_MAX_RST_Lf, 1); 13935 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 13936 13937 if (temperature_count) { 13938 *temperature_count=num_entries_out; 13939 } 13940 13941 return SOC_E_NONE; 13942 } 13943 13944 int 13945 soc_apache_show_material_process(int unit) 13946 { 13947 soc_reg_t reg; 13948 int index; 13949 uint32 rval, fval, nmos[COUNTOF(pvtmon_result_reg)], n_avg, p_avg; 13950 13951 READ_TOP_PVTMON_CTRL_1r(unit, &rval); 13952 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 0); 13953 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 13954 sal_usleep(1000); 13955 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 1); 13956 WRITE_TOP_PVTMON_CTRL_1r(unit, rval); 13957 sal_usleep(1000); 13958 13959 SOC_IF_ERROR_RETURN 13960 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, 13961 PVTMON_SELECTf, 1)); 13962 sal_usleep(1000); 13963 13964 p_avg = 0; 13965 13966 /* Read NMOS information */ 13967 SOC_IF_ERROR_RETURN 13968 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY, 13969 MEASUREMENT_CALLIBRATIONf, 5)); 13970 13971 sal_usleep(1000); 13972 13973 n_avg = 0; 13974 for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) { 13975 reg = pvtmon_result_reg[index]; 13976 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13977 nmos[index] = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13978 n_avg += nmos[index]; 13979 } 13980 13981 /* Read PMOS information and print both NMOS and PMOS value */ 13982 SOC_IF_ERROR_RETURN 13983 (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY, 13984 MEASUREMENT_CALLIBRATIONf, 7)); 13985 13986 sal_usleep(1000); 13987 13988 p_avg = 0; 13989 for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) { 13990 reg = pvtmon_result_reg[index]; 13991 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 13992 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 13993 p_avg += fval; 13994 13995 LOG_CLI((BSL_META_U(unit, 13996 "Material process location %d: NMOS = %3d PMOS = %3d\n"), 13997 index, nmos[index], fval)); 13998 } 13999 14000 LOG_CLI((BSL_META_U(unit, 14001 "Average: NMOS = %3d PMOS = %3d\n"), 14002 n_avg / COUNTOF(pvtmon_result_reg), 14003 p_avg / COUNTOF(pvtmon_result_reg))); 14004 14005 return SOC_E_NONE; 14006 } 14007 14008 int 14009 soc_apache_show_ring_osc(int unit) 14010 { 14011 static const struct { 14012 int osc_sel; 14013 soc_field_t field0; 14014 int value0; 14015 soc_field_t field1; 14016 int value1; 14017 char *name; 14018 } osc_tbl[] = { 14019 { 2, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" }, 14020 { 2, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" }, 14021 { 3, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" }, 14022 { 3, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" }, 14023 { 4, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" }, 14024 { 5, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" }, 14025 { 6, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" }, 14026 { 7, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" }, 14027 { 8, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" }, 14028 { 9, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" }, 14029 { 10, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" }, 14030 { 11, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" } 14031 }; 14032 soc_reg_t ctrl_reg, stat_reg; 14033 uint32 rval, fval; 14034 int index, core_clk, quo, rem, frac, retry; 14035 14036 core_clk = SOC_INFO(unit).frequency * 1024; 14037 ctrl_reg = TOP_RING_OSC_CTRLr; 14038 stat_reg = TOP_OSC_COUNT_STATr; 14039 14040 for (index = 0; index < COUNTOF(osc_tbl); index++) { 14041 rval = 0; 14042 /* 14043 * set OSC_CNT_RSTBf to 0 to do softreset 14044 * set OSC_CNT_START to 0 to hold the counter until it selects 14045 * the input signal 14046 */ 14047 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 14048 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_ENABLEf, 1); 14049 soc_reg_field_set(unit, ctrl_reg, &rval, IROSC_ENf, 1); 14050 soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field0, 14051 osc_tbl[index].value0); 14052 if (osc_tbl[index].field1 != INVALIDf) { 14053 soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field1, 14054 osc_tbl[index].value1); 14055 } 14056 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_SELf, 14057 osc_tbl[index].osc_sel); 14058 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 14059 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_RSTBf, 1); 14060 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 14061 soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_STARTf, 1); 14062 SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval)); 14063 14064 for (retry = 0; retry < 10; retry++) { 14065 sal_usleep(1000); 14066 SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval)); 14067 if (!soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_DONEf)) { 14068 continue; 14069 } 14070 14071 fval = soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_VALUEf); 14072 quo = core_clk / fval; 14073 rem = core_clk - quo * fval; 14074 frac = (rem * 10000) / fval; 14075 LOG_CLI((BSL_META_U(unit, "%s: %d.%04d Mhz\n"), 14076 osc_tbl[index].name, quo, frac)); 14077 break; 14078 } 14079 } 14080 14081 return SOC_E_NONE; 14082 } 14083 14084 int 14085 soc_apache_show_voltage(int unit) 14086 { 14087 soc_reg_t reg; 14088 int index; 14089 uint32 rval, fval, avg; 14090 14091 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval)); 14092 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0); 14093 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 14094 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1); 14095 soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_SELECTf, 4); 14096 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 14097 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 14098 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 0); 14099 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 14100 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1); 14101 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 14102 14103 sal_sleep(1); 14104 avg = 0; 14105 14106 /* Read Voltages. Ignores result of PVTMON8 */ 14107 for (index = 0; index < COUNTOF(pvtmon_result_reg) - 1; index++) { 14108 reg = pvtmon_result_reg[index]; 14109 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 14110 fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf); 14111 /* (PVT_DATA * 880) / 1024 * 0.7 */ 14112 fval = (fval * 880 * 10) / (1024 * 7); 14113 avg += fval; 14114 LOG_CLI((BSL_META_U(unit, 14115 "Voltage monitor %d: voltage = %d.%03dV\n"), 14116 index, (fval/1000), (fval %1000))); 14117 } 14118 14119 avg /= (COUNTOF(pvtmon_result_reg) - 1); 14120 LOG_CLI((BSL_META_U(unit, 14121 "Average voltage is = %d.%03dV\n"), 14122 (avg/1000), (avg %1000))); 14123 14124 return SOC_E_NONE; 14125 } 14126 14127 /* 14128 * Function: 14129 * soc_apache_process_func_intr 14130 * Description: 14131 * Chip specific DPC function to service interrupts 14132 * Parameters: 14133 * unit_vp - Device number 14134 * d1 - IRQ3 mask 14135 * d2 - IRQ3 number (to distinguish between 14136 * different types of interrupts). 14137 */ 14138 void 14139 soc_apache_process_func_intr(void *unit_vp, void *d1, void *d2, void *d3, void *d4) 14140 { 14141 int unit = PTR_TO_INT(unit_vp); 14142 int irq3_num = PTR_TO_INT(d2); 14143 uint32 rval; 14144 14145 if ((irq3_num == 13) /* L2LU INTR */ && 14146 soc_feature(unit, soc_feature_l2_overflow)) { 14147 if (READ_IL2LU_INTR_STATUSr(unit, &rval)) { 14148 LOG_ERROR(BSL_LS_SOC_COMMON, 14149 (BSL_META_U(unit, 14150 "unit %d: Error reading %s reg !!\n"), 14151 unit, SOC_REG_NAME(unit, IL2LU_INTR_STATUSr))); 14152 return; 14153 } 14154 if (soc_reg_field_get(unit, IL2LU_INTR_STATUSr, rval, 14155 L2_LEARN_INSERT_FAILUREf)) { 14156 soc_td2_l2_overflow_interrupt_handler(unit); 14157 } 14158 } else if ((irq3_num == 14) /* RDB INTR */) { 14159 14160 } 14161 14162 sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */ 14163 if (d1 != NULL) { 14164 (void)soc_cmicm_intr3_enable(unit, 14165 PTR_TO_INT(d1)); 14166 } 14167 14168 return; 14169 } 14170 14171 int 14172 soc_apache_port_asf_speed_set(int unit, soc_port_t port, int speed) 14173 { 14174 soc_apache_port_ct_speed_t asf_speed_mode; 14175 uint32 rval; 14176 14177 SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval)); 14178 14179 switch (speed) { 14180 case 10: 14181 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_10M_FULL; 14182 break; 14183 case 100: 14184 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_100M_FULL; 14185 break; 14186 case 1000: 14187 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_1000M_FULL; 14188 break; 14189 case 2500: 14190 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_2500M_FULL; 14191 break; 14192 case 5000: 14193 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_5000M_FULL; 14194 break; 14195 case 10000: 14196 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_10000M_FULL; 14197 break; 14198 case 11000: 14199 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_11000M_FULL; 14200 break; 14201 case 20000: 14202 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_20000M_FULL; 14203 break; 14204 case 21000: 14205 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_21000M_FULL; 14206 break; 14207 case 25000: 14208 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_25000M_FULL; 14209 break; 14210 case 27000: 14211 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_27000M_FULL; 14212 break; 14213 case 40000: 14214 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_40000M_FULL; 14215 break; 14216 case 42000: 14217 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_42000M_FULL; 14218 break; 14219 case 50000: 14220 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_50000M_FULL; 14221 break; 14222 case 53000: 14223 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_53000M_FULL; 14224 break; 14225 case 100000: 14226 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_100000M_FULL; 14227 break; 14228 case 106000: 14229 asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_106000M_FULL; 14230 break; 14231 case 0: 14232 return SOC_E_NONE; 14233 default: 14234 return SOC_E_PARAM; 14235 } 14236 14237 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, 14238 ASF_PORT_SPEEDf, asf_speed_mode); 14239 14240 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14241 return SOC_E_NONE; 14242 } 14243 14244 int 14245 soc_apache_port_asf_set(int unit, soc_port_t port, int speed) 14246 { 14247 uint32 rval; 14248 soc_reg_t reg; 14249 int mmu_port, phy_port; 14250 int asf_credit_thresh_lo, asf_credit_thresh_hi; 14251 14252 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 14253 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 14254 14255 14256 14257 if (!soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) { 14258 if (speed <= 11000) { 14259 asf_credit_thresh_lo = 4; 14260 asf_credit_thresh_hi = 9; 14261 } else if (speed <= 21000) { 14262 asf_credit_thresh_lo = 8; 14263 asf_credit_thresh_hi = 18; 14264 } else if (speed <= 42000) { 14265 asf_credit_thresh_lo = 18; 14266 asf_credit_thresh_hi = 36; 14267 } else { 14268 asf_credit_thresh_lo = 30; 14269 asf_credit_thresh_hi = 72; 14270 } 14271 } else { 14272 if (speed <= 11000) { 14273 asf_credit_thresh_lo = 3; 14274 asf_credit_thresh_hi = 3; 14275 } else if (speed <= 27000) { 14276 asf_credit_thresh_lo = 4; 14277 asf_credit_thresh_hi = 4; 14278 } else if (speed <= 42000) { 14279 asf_credit_thresh_lo = IS_OVERSUB_PORT(unit,port) ? 6 : 5; 14280 asf_credit_thresh_hi = IS_OVERSUB_PORT(unit,port) ? 6 : 5; 14281 } else if (speed <= 53000) { 14282 asf_credit_thresh_lo = 6; 14283 asf_credit_thresh_hi = 6; 14284 } else { 14285 asf_credit_thresh_lo = 10; 14286 asf_credit_thresh_hi = 10; 14287 } 14288 } 14289 14290 14291 rval = 0; 14292 reg = ES_PIPE0_ASF_CREDIT_THRESH_LOr; 14293 soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_lo); 14294 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 14295 14296 rval = 0; 14297 reg = ES_PIPE0_ASF_CREDIT_THRESH_HIr; 14298 soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_hi); 14299 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval)); 14300 SOC_IF_ERROR_RETURN(soc_apache_port_asf_speed_set(unit, port, speed)); 14301 14302 return SOC_E_NONE; 14303 } 14304 14305 int 14306 soc_apache_port_speed_update(int unit, soc_port_t port, int speed) 14307 { 14308 int lossless; 14309 14310 /* Update Edatabuf transmit start count */ 14311 SOC_IF_ERROR_RETURN(soc_apache_port_edb_config(unit, 0, port)); 14312 14313 SOC_IF_ERROR_RETURN(soc_apache_port_asf_set(unit, port, speed)); 14314 14315 /* Update oversubscription buffer manager (OBM) threshold */ 14316 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 14317 SOC_IF_ERROR_RETURN(_soc_apache_idb_port_init(unit, FALSE, lossless, port)); 14318 14319 SOC_IF_ERROR_RETURN(soc_ap_mmu_delay_insertion_set(unit, port)); 14320 14321 return SOC_E_NONE; 14322 } 14323 14324 14325 14326 STATIC int 14327 _soc_apache_thdo_hw_set(int unit, soc_port_t port, int enable) 14328 { 14329 uint64 rval64, rval64_tmp; 14330 int mmu_port, phy_port, i,mmu_port_tmp; 14331 soc_info_t *si; 14332 soc_reg_t reg_tmp; 14333 soc_reg_t reg[3][2] = { 14334 { 14335 THDU_OUTPUT_PORT_RX_ENABLE0_64r, 14336 THDU_OUTPUT_PORT_RX_ENABLE1_64r 14337 }, 14338 { 14339 MMU_THDM_DB_PORTSP_RX_ENABLE0_64r, 14340 MMU_THDM_DB_PORTSP_RX_ENABLE1_64r 14341 }, 14342 { 14343 MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r, 14344 MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r 14345 } 14346 }; 14347 14348 si = &SOC_INFO(unit); 14349 14350 phy_port = si->port_l2p_mapping[port]; 14351 mmu_port = si->port_p2m_mapping[phy_port]; 14352 if (mmu_port > 73) { 14353 return SOC_E_PARAM; 14354 } 14355 14356 for (i = 0; i < 3; i++) { 14357 COMPILER_64_ZERO(rval64); 14358 COMPILER_64_ZERO(rval64_tmp); 14359 if (mmu_port < 64) { 14360 reg_tmp = reg[i][0]; 14361 mmu_port_tmp = mmu_port; 14362 } else { 14363 reg_tmp = reg[i][1]; 14364 mmu_port_tmp = mmu_port - 64; 14365 } 14366 14367 SOC_IF_ERROR_RETURN( 14368 soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64)); 14369 14370 if (mmu_port_tmp < 32) { 14371 COMPILER_64_SET(rval64_tmp, 0, 1 << mmu_port_tmp); 14372 } else { 14373 COMPILER_64_SET(rval64_tmp, 1 << (mmu_port_tmp - 32), 0); 14374 } 14375 14376 if (enable) { 14377 COMPILER_64_OR(rval64, rval64_tmp); 14378 } else { 14379 COMPILER_64_NOT(rval64_tmp); 14380 COMPILER_64_AND(rval64, rval64_tmp); 14381 } 14382 14383 SOC_IF_ERROR_RETURN( 14384 soc_reg_set(unit, reg_tmp, REG_PORT_ANY, 0, rval64)); 14385 } 14386 14387 return SOC_E_NONE; 14388 } 14389 STATIC int 14390 _soc_apache_thdo_hw_get(int unit, soc_port_t port, int *enable) 14391 { 14392 uint64 rval64; 14393 int mmu_port, phy_port, i, reg_grp = 0; 14394 int rv = SOC_E_NONE; 14395 soc_info_t *si; 14396 soc_reg_t reg_tmp; 14397 soc_reg_t reg[3][2] = { 14398 { 14399 THDU_OUTPUT_PORT_RX_ENABLE0_64r, 14400 THDU_OUTPUT_PORT_RX_ENABLE1_64r 14401 }, 14402 { 14403 MMU_THDM_DB_PORTSP_RX_ENABLE0_64r, 14404 MMU_THDM_DB_PORTSP_RX_ENABLE1_64r 14405 }, 14406 { 14407 MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r, 14408 MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r 14409 } 14410 }; 14411 int max_reg = 3; 14412 14413 si = &SOC_INFO(unit); 14414 14415 phy_port = si->port_l2p_mapping[port]; 14416 mmu_port = si->port_p2m_mapping[phy_port]; 14417 14418 COMPILER_64_ZERO(rval64); 14419 if (mmu_port < 64 ) { 14420 mmu_port &= 0x3f; 14421 } else { 14422 mmu_port &= 0xf; 14423 reg_grp = 1; 14424 } 14425 14426 for (i = 0; i < max_reg; i++) { 14427 reg_tmp = reg[i][reg_grp]; 14428 14429 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64)); 14430 14431 if (COMPILER_64_BITTEST(rval64 , mmu_port)) { 14432 *enable = TRUE; 14433 } else { 14434 *enable = FALSE; 14435 } 14436 } 14437 return rv; 14438 } 14439 14440 /* 14441 * Function: 14442 * _soc_apache_port_thdo_rx_enable_set 14443 * Purpose: 14444 * enable/disable the traffic to the port according to 14445 * different callers. 14446 * the traffic to the port can be enabled only if all of the callers 14447 * are to enable it. 14448 * Parameters: 14449 * unit - (IN) unit number 14450 * port - (IN) local port 14451 * enable - (IN) enable/disable the traffic to the port. 14452 * flag - (IN) different callers. 14453 * Returns: 14454 * BCM_E_XXX 14455 */ 14456 STATIC int 14457 _soc_apache_port_thdo_rx_enable_set(int unit, soc_port_t port, 14458 int enable, uint8 flag) 14459 { 14460 int rv = SOC_E_NONE; 14461 uint8 *thdo_drop_bmp; 14462 _soc_apache_mmu_traffic_ctrl_t *mmu_traffic_ctrl; 14463 int cur_enable =0 ; 14464 FWD_CTRL_LOCK(unit); 14465 14466 mmu_traffic_ctrl = _soc_apache_mmu_traffic_ctrl[unit]; 14467 if (mmu_traffic_ctrl == NULL) { 14468 FWD_CTRL_UNLOCK(unit); 14469 return SOC_E_INIT; 14470 } 14471 thdo_drop_bmp = 14472 &(mmu_traffic_ctrl->thdo_drop_bmp[port]); 14473 14474 if (!enable) { 14475 if (*thdo_drop_bmp & flag) { 14476 FWD_CTRL_UNLOCK(unit); 14477 return rv; 14478 } 14479 14480 if (*thdo_drop_bmp == 0) { 14481 rv = _soc_apache_thdo_hw_set(unit, port, enable); 14482 if (SOC_FAILURE(rv)) { 14483 LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Clearing the registers failed.\n"))); 14484 FWD_CTRL_UNLOCK(unit); 14485 return rv; 14486 } 14487 } 14488 14489 *thdo_drop_bmp |= flag; 14490 14491 FWD_CTRL_UNLOCK(unit); 14492 return rv; 14493 } else { 14494 if (0 == *thdo_drop_bmp) { 14495 rv = _soc_apache_thdo_hw_get(unit, port, &cur_enable); 14496 if (SOC_FAILURE(rv)) { 14497 LOG_ERROR(BSL_LS_SOC_COMMON, 14498 (BSL_META_U(unit, 14499 "Get the registers fail.\n"))); 14500 FWD_CTRL_UNLOCK(unit); 14501 return rv; 14502 } 14503 /* Warmboot: latest value of *thdo_drop_bmp is not sync to WB cache. 14504 * We execute "sc controlsync=1" when one port is link up. But when we exit SDK, 14505 * the port is link down, so the conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r 14506 * of the port is zero. After WarmBoot SDK, 14507 * we can't set conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r 14508 * for the port when it is link up, because, the value of thdo_drop_bmp is zero. 14509 */ 14510 if(cur_enable == FALSE) { 14511 LOG_INFO(BSL_LS_SOC_COMMON, 14512 (BSL_META_U(unit, 14513 "Latest thdo_drop_bmp was not updated to WB cache!!!\n"))); 14514 *thdo_drop_bmp |= flag; 14515 } 14516 } 14517 14518 if (*thdo_drop_bmp != flag) { 14519 /*other callers are in thdo drop*/ 14520 *thdo_drop_bmp &= ~flag; 14521 FWD_CTRL_UNLOCK(unit); 14522 return rv; 14523 } 14524 14525 /*Ok, only self is in thdo drop, enbable it*/ 14526 rv = _soc_apache_thdo_hw_set(unit, port, enable); 14527 if (SOC_FAILURE(rv)) { 14528 LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Setting the registers failed.\n"))); 14529 FWD_CTRL_UNLOCK(unit); 14530 return rv; 14531 } 14532 14533 *thdo_drop_bmp &= ~flag; 14534 14535 FWD_CTRL_UNLOCK(unit); 14536 return rv; 14537 } 14538 14539 FWD_CTRL_UNLOCK(unit); 14540 return rv; 14541 } 14542 14543 14544 int 14545 soc_apache_port_traffic_egr_enable_set(int unit, soc_port_t port, 14546 int enable) 14547 { 14548 return _soc_apache_port_thdo_rx_enable_set(unit, port, enable, 14549 COSQ_SCHED_SET_CTRL); 14550 } 14551 14552 int 14553 soc_apache_port_mmu_tx_enable_set(int unit, soc_port_t port, 14554 int enable) 14555 { 14556 return _soc_apache_port_thdo_rx_enable_set(unit, port, enable, 14557 MMU_TRAFFIC_EN_CTRL); 14558 } 14559 14560 14561 int 14562 soc_apache_port_thdo_rx_enable_set(int unit, soc_port_t port, 14563 int enable) 14564 { 14565 return _soc_apache_port_thdo_rx_enable_set(unit, port, enable, 14566 MAC_ENABLE_SET_CTRL); 14567 } 14568 14569 14570 STATIC int 14571 _soc_ap_resource_data_check(int unit, int num_res, soc_port_resource_t *res) 14572 { 14573 int i, j; 14574 /* null check for all resource data before accessing register */ 14575 for (i = 0 ; i < num_res ; ++i) { 14576 soc_port_resource_t *p = &res[i]; 14577 if (NULL == p) { 14578 /* 14579 * COVERITY 14580 * It is kept intentionally as a defensive check. 14581 */ 14582 /* coverity[dead_error_line] */ 14583 return SOC_E_PARAM; 14584 } 14585 for (j = 0; j < p->num_lanes ; ++j) { 14586 soc_port_lane_info_t *p_lane_info = p->lane_info[j]; 14587 if (NULL == p_lane_info) { 14588 return SOC_E_PARAM; 14589 } 14590 } 14591 } 14592 return SOC_E_NONE; 14593 } 14594 14595 /* 14596 * Function: 14597 * soc_ap_pgw_obm_set 14598 * Purpose: 14599 * Reconfigure PGW_OBM registers in flex port sequence 14600 * This function will do two things, 14601 * 1. clear all registers for old ports which exists in pre-Flex status 14602 * 2. initialize all registers for new ports which exists in post-Flex status 14603 * 14604 * Parameters: 14605 * unit - (IN) Unit number. 14606 * pre_num_res - (IN) Number of resource data which exist in pre-Flex status 14607 * post_num_res - (IN) Number of resource data which exist in post-Flex status 14608 * pre_res - (IN) Resource data structure pointer in pre-Flex status 14609 * post_res - (IN) Resource data structure pointer in post-Flex status 14610 * 14611 * Returns: 14612 * SOC_E_XXX 14613 */ 14614 int 14615 soc_ap_pgw_obm_set(int unit, 14616 int pre_num_res, soc_port_resource_t *pre_res, 14617 int post_num_res, soc_port_resource_t *post_res) 14618 { 14619 int i; 14620 int port, xlp; 14621 int lossless; 14622 14623 SOC_IF_ERROR_RETURN( 14624 _soc_ap_resource_data_check(unit, pre_num_res, pre_res)); 14625 SOC_IF_ERROR_RETURN( 14626 _soc_ap_resource_data_check(unit, post_num_res, post_res)); 14627 14628 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 14629 for (i = 0; i < pre_num_res; i++) { 14630 if (pre_res[i].flags & SOC_PORT_RESOURCE_I_MAP) { 14631 continue; 14632 } 14633 if (pre_res[i].physical_port == -1) { 14634 continue; 14635 } 14636 port = pre_res[i].logical_port; 14637 _soc_apache_idb_port_init(unit, TRUE, lossless, port); 14638 xlp = (pre_res[i].physical_port % (APACHE_TSCS_PER_PGW * APACHE_PGWS_PER_DEV)); 14639 SOC_IF_ERROR_RETURN(_soc_apache_port_blk_ca_mode_set(unit, TRUE, xlp)); 14640 } 14641 14642 for (i = 0; i < post_num_res; i++) { 14643 port = post_res[i].logical_port; 14644 _soc_apache_idb_port_init(unit, FALSE, lossless, port); 14645 xlp = SOC_INFO(unit).port_serdes[port]; 14646 SOC_IF_ERROR_RETURN(_soc_apache_port_blk_ca_mode_set(unit, TRUE, xlp)); 14647 } 14648 14649 14650 return SOC_E_NONE; 14651 } 14652 14653 14654 /* 14655 * Function: 14656 * soc_ap_obm_threshold_default_set 14657 * Purpose: 14658 * Reconfigure PGW Threshold in flex port sequence 14659 * In this function following registers will be initialized. 14660 * PGW_OBM[0-3]_THRESHOLD 14661 * PGW_OBM[0-3]_THRESHOLD2 14662 * If default_flag is PGW_OBM_INIT_HW_DEFAULT, 14663 * register will be intialized by HW reset value 14664 * If default_flag is PGW_OBM_INIT_SW_DEFAULT, 14665 * register will be intialized by SW reset value 14666 * 14667 * Parameters: 14668 * unit - (IN) Unit number 14669 * num_res - (IN) Number of resource 14670 * res - (IN) Resource data structure 14671 * lossless - (IN) Lossless configuration of device 14672 * default_flag - (IN) PGW_OBM_INIT_HW_DEFAULT 14673 * Use HW reset value for register value 14674 * - (IN) PGW_OBM_INIT_SW_DEFAULT 14675 * Use SW default value 14676 * 14677 * Assumption: 14678 * This function cannot access SOC_INFO data structure. 14679 * So assume followings condition should be checked 14680 * before calling this function. 14681 * 14682 * 1. pgw block is valid 14683 * si->block_valid[PGW_CL_BLOCK(unit, pgw)] is true 14684 * 2. port block is used 14685 * block = PGW_CL_BLOCK(unit, pgw); 14686 * SOC_BLOCK_PORT(unit, block) < 0 14687 * 3. num_res should be correct number of resource data structure. 14688 * all resource data structure should be accessed by using 14689 * pointer offset by res_num. If the pointer of resource data is NULL, 14690 * returns SOC_E_PARAM. 14691 * 14692 * Returns: 14693 * SOC_E_XXX 14694 */ 14695 STATIC 14696 soc_error_t soc_ap_obm_threshold_default_set(int unit, 14697 int num_res, 14698 soc_port_resource_t *res, 14699 int lossless, 14700 int reset) 14701 { 14702 int i; 14703 14704 for (i = 0 ; i < num_res ; ++i) { 14705 14706 14707 SOC_IF_ERROR_RETURN(_soc_apache_idb_port_init(unit, reset, lossless, res->logical_port)); 14708 14709 } 14710 14711 return SOC_E_NONE; 14712 } 14713 14714 STATIC int 14715 soc_ap_obm_threshold_hw_default_set(int unit, int num_res, 14716 soc_port_resource_t *res, 14717 int lossless) 14718 { 14719 14720 SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_default_set(unit, num_res, res, 14721 lossless, 14722 TRUE)); 14723 return SOC_E_NONE; 14724 } 14725 14726 STATIC int 14727 soc_ap_obm_threshold_sw_default_set(int unit, int num_res, 14728 soc_port_resource_t *res, 14729 int lossless) 14730 { 14731 SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_default_set(unit, num_res, res, 14732 lossless, 14733 FALSE)); 14734 return SOC_E_NONE; 14735 } 14736 14737 /* 14738 * Function: 14739 * soc_ap_obm_threshold_set 14740 * Purpose: 14741 * Reconfigure PGW registers in flex port sequence 14742 * In this function PGW OBM threshold registers will be initialized. 14743 * This function will do two things, 14744 * 1. clear all registers for old ports which exists in pre-Flex status 14745 * 2. initialize all registers for new ports which exists in post-Flex status 14746 * 14747 * Parameters: 14748 * unit - (IN) Unit number. 14749 * pre_num_res - (IN) Number of resource data which exist in pre-Flex status 14750 * post_num_res - (IN) Number of resource data which exist in post-Flex status 14751 * pre_res - (IN) Resource data structure pointer in pre-Flex status 14752 * post_res - (IN) Resource data structure pointer in post-Flex status 14753 * lossless - (IN) mmu lossless information 14754 * 14755 * Returns: 14756 * SOC_E_XXX 14757 * 14758 * Note : For 100G port, this functions expects the ovsersub field to be 14759 * disabled. 14760 */ 14761 soc_error_t soc_ap_obm_threshold_set(int unit, 14762 int pre_num_res, soc_port_resource_t *pre_res, 14763 int post_num_res, soc_port_resource_t *post_res, 14764 int lossless) 14765 { 14766 14767 SOC_IF_ERROR_RETURN(_soc_ap_resource_data_check(unit, pre_num_res, 14768 pre_res)); 14769 SOC_IF_ERROR_RETURN(_soc_ap_resource_data_check(unit, post_num_res, 14770 post_res)); 14771 SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_hw_default_set(unit, 14772 pre_num_res, pre_res, lossless)); 14773 14774 SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_sw_default_set(unit, 14775 post_num_res, post_res, lossless)); 14776 14777 return SOC_E_NONE; 14778 } 14779 14780 14781 /* 14782 * This function is used to enable or disable cut through when a port is 14783 * operating in store and forward mode. 14784 * Refer TD2_Cutthrough_programming_guideline.pdf 14785 * Caller must pass the correct port_info pointer, corresponding to the port 14786 * being configured (and sent by the BCM layer) 14787 * To enable cut-through, pass enable = 1 14788 * To disable cut-through, pass enable = 0 14789 */ 14790 int 14791 soc_ap_cut_thru_enable_disable(int unit, soc_port_t port, int enable) 14792 { 14793 uint32 rval; 14794 uint32 speed; 14795 14796 /* Cut-through not supported on non-packet-forwarding ports */ 14797 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 14798 return SOC_E_PORT; 14799 } 14800 14801 /* When in Oversub, only 40G speeds support CT */ 14802 speed = SOC_INFO(unit).port_speed_max[port]; 14803 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed); 14804 if (IS_OVERSUB_PORT(unit, port) && speed != 40000) { 14805 LOG_ERROR(BSL_LS_SOC_COMMON, 14806 (BSL_META_U(unit, 14807 "ASF supported only on 40G/42G ports " 14808 "when in Oversub\n"))); 14809 return SOC_E_PORT; 14810 } 14811 14812 if (soc_feature(unit, soc_feature_untethered_otp)) { 14813 if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoOsubCT) && (IS_OVERSUB_PORT(unit, port))) { 14814 LOG_ERROR(BSL_LS_SOC_COMMON, 14815 (BSL_META_U(unit, 14816 "ASF not supported on Oversub ports\n"))); 14817 return SOC_E_CONFIG; 14818 } 14819 } 14820 14821 /* Mask unnecessary bits */ 14822 enable &= 0x1; 14823 14824 SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval)); 14825 14826 speed = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, ASF_PORT_SPEEDf); 14827 14828 /* Set port speed to 0 */ 14829 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, 0); 14830 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14831 14832 if (!enable) { 14833 /* Wait 8ms for draining all cells */ 14834 sal_usleep(8000); 14835 } 14836 14837 SOC_IF_ERROR_RETURN(soc_apache_port_edb_config(unit, enable, port)); 14838 14839 /* Set UC_ASF_ENABLE, MC_ASF_ENABLE bits to 1 */ 14840 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, UC_ASF_ENABLEf, enable); 14841 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, MC_ASF_ENABLEf, enable); 14842 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14843 14844 if (enable) { 14845 /* Wait 1 micro-sec */ 14846 sal_usleep(1); 14847 } 14848 14849 soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, speed); 14850 SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval)); 14851 14852 return SOC_E_NONE; 14853 } 14854 14855 14856 int soc_ap_max_speed_port_find(int phy_port, 14857 soc_port_resource_t *port_info, 14858 int port_info_arr_size) 14859 { 14860 int idx, index, speed; 14861 14862 index = 0; 14863 speed = port_info[index].speed; 14864 14865 for (idx = 1; idx < port_info_arr_size; idx++) { 14866 /* If all speeds are equal, '>' will return the 1st index, 14867 * '>=' will return the last index 14868 */ 14869 if (port_info[idx].speed > speed) { 14870 speed = port_info[idx].speed; 14871 index = idx; 14872 } 14873 } 14874 14875 return index; 14876 } 14877 14878 /* 14879 * This function checks if cut-through is enabled for a given port. 14880 * If either unicast or multicast cut-through is enabled, the function 14881 * returns TRUE else FALSE is returned 14882 */ 14883 int 14884 soc_apache_is_cut_thru_enabled(int unit, soc_port_t port, int *enable) 14885 { 14886 uint32 rval; 14887 uint32 uc_enable, mc_enable; 14888 14889 /* Cut-through not supported on following ports */ 14890 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 14891 return SOC_E_PARAM; 14892 } 14893 14894 SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval)); 14895 14896 uc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, UC_ASF_ENABLEf); 14897 mc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, MC_ASF_ENABLEf); 14898 14899 if (uc_enable || mc_enable) { 14900 *enable = TRUE; 14901 } else { 14902 *enable = FALSE; 14903 } 14904 14905 return SOC_E_NONE; 14906 } 14907 14908 /* 14909 * This function is used to clear various counters in EP block. The 14910 * counters to clear are mentioned in 'Reconfigure EP' section of TD2+ Flexport 14911 */ 14912 STATIC int soc_ap_ep_counters_clear(int unit, soc_port_resource_t *port_info) 14913 { 14914 uint64 val64; 14915 uint32 val = 0; 14916 14917 COMPILER_64_ZERO(val64); 14918 SOC_IF_ERROR_RETURN(WRITE_EGR_TRILL_TX_PKTSr(unit, port_info->logical_port, 14919 val)); 14920 SOC_IF_ERROR_RETURN(WRITE_EGR_TRILL_TX_ACCESS_PORT_TRILL_PKTS_DISCARDEDr(unit, port_info->logical_port, val)); 14921 SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_DELIMITER_ERROR_FRAMESr(unit, 14922 port_info->logical_port, val)); 14923 SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_INVALID_CRC_FRAMESr(unit, 14924 port_info->logical_port, val)); 14925 14926 SOC_IF_ERROR_RETURN(WRITE_TPCEr(unit, port_info->logical_port, val64)); 14927 14928 SOC_IF_ERROR_RETURN(WRITE_TDBGC0r(unit, port_info->logical_port, val64)); 14929 SOC_IF_ERROR_RETURN(WRITE_TDBGC1r(unit, port_info->logical_port, val64)); 14930 SOC_IF_ERROR_RETURN(WRITE_TDBGC2r(unit, port_info->logical_port, val64)); 14931 SOC_IF_ERROR_RETURN(WRITE_TDBGC3r(unit, port_info->logical_port, val64)); 14932 SOC_IF_ERROR_RETURN(WRITE_TDBGC4r(unit, port_info->logical_port, val64)); 14933 SOC_IF_ERROR_RETURN(WRITE_TDBGC5r(unit, port_info->logical_port, val64)); 14934 SOC_IF_ERROR_RETURN(WRITE_TDBGC6r(unit, port_info->logical_port, val64)); 14935 SOC_IF_ERROR_RETURN(WRITE_TDBGC7r(unit, port_info->logical_port, val64)); 14936 SOC_IF_ERROR_RETURN(WRITE_TDBGC8r(unit, port_info->logical_port, val64)); 14937 SOC_IF_ERROR_RETURN(WRITE_TDBGC9r(unit, port_info->logical_port, val64)); 14938 SOC_IF_ERROR_RETURN(WRITE_TDBGC10r(unit, port_info->logical_port, val64)); 14939 SOC_IF_ERROR_RETURN(WRITE_TDBGC11r(unit, port_info->logical_port, val64)); 14940 14941 return SOC_E_NONE; 14942 } 14943 14944 14945 STATIC int 14946 soc_ap_port_resource_tdm_calculate(int unit, soc_apache_tdm_t *tdm) 14947 { 14948 int index; 14949 soc_info_t *si; 14950 soc_pbmp_t pbmp; 14951 int port, slot, phy_port; 14952 14953 /* soc info has new values */ 14954 si = &SOC_INFO(unit); 14955 14956 sal_memset(tdm, 0, sizeof(soc_apache_tdm_t)); 14957 14958 PBMP_PORT_ITER(unit, port) { 14959 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 14960 continue; 14961 } 14962 phy_port = si->port_l2p_mapping[port]; 14963 14964 tdm->speed[phy_port] = si->port_speed_max[port]; 14965 APACHE_TDM_SPEED_ADJUST(unit, port, tdm->speed[phy_port]); 14966 14967 tdm->port_state[phy_port] = 14968 IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE; 14969 14970 /* 14971 * Primary port will be setup as line-rate or oversub. 14972 * Subsequent physical ports (sister-ports) will be either 14973 * DISABLED or SUBPORT/COMBINED mode. 14974 * 14975 * TDM Algo expects lanes info based on speed. 14976 */ 14977 if (soc_apache_port_is_falcon(unit, phy_port)) { /* Falcons */ 14978 if (tdm->speed[phy_port] > 25000) { 14979 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 14980 } 14981 if (tdm->speed[phy_port] > 50000) { 14982 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 14983 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 14984 } 14985 } else { /* Eagles */ 14986 if (tdm->speed[phy_port] > 10000) { 14987 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT; 14988 } 14989 if (tdm->speed[phy_port] > 20000) { 14990 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT; 14991 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT; 14992 } 14993 if (tdm->speed[phy_port] > 40000) { 14994 tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT; 14995 tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT; 14996 tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT; 14997 tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT; 14998 tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT; 14999 tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT; 15000 } 15001 } 15002 } 15003 15004 /* CPU, LB and RDB ports */ 15005 tdm->speed[0] = 1000; 15006 tdm->speed[73] = 1000; 15007 tdm->speed[74] = 1000; 15008 tdm->tdm_bw = si->bandwidth / 1000; 15009 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 15010 SOC_PBMP_AND(pbmp, si->xpipe_pbm); 15011 /* tell tdm code the device is oversub if any ports is oversub */ 15012 tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp); 15013 SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm); 15014 15015 for (slot = 0; slot <= APACHE_MMU_TDM_LENGTH; slot++) { 15016 tdm->mmu_tdm[slot] = NUM_EXT_PORTS; 15017 } 15018 15019 if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) { 15020 LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), tdm->tdm_bw)); 15021 LOG_CLI((BSL_META_U(unit, "port speed:"))); 15022 for (index = 0; index < NUM_EXT_PORTS; index++) { 15023 if (index % 8 == 0) { 15024 LOG_CLI((BSL_META_U(unit, "\n "))); 15025 } 15026 LOG_CLI((BSL_META_U(unit, " %06d(%03d)"), 15027 tdm->speed[index], index)); 15028 } 15029 LOG_CLI((BSL_META_U(unit, "\n"))); 15030 LOG_CLI((BSL_META_U(unit, "port state map:"))); 15031 for (index = 0; index < NUM_EXT_PORTS; index++) { 15032 if (index % 8 == 0) { 15033 LOG_CLI((BSL_META_U(unit, "\n "))); 15034 } 15035 if (index == 0 || index == (NUM_EXT_PORTS - 1)) { 15036 LOG_CLI((BSL_META_U(unit, " --------"))); 15037 } else { 15038 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"), 15039 tdm->port_state[index], index)); 15040 } 15041 } 15042 LOG_CLI((BSL_META_U(unit, "\n"))); 15043 } 15044 15045 15046 SOC_IF_ERROR_RETURN(soc_apache_tdm_calc(unit, tdm)); 15047 15048 15049 return SOC_E_NONE; 15050 } 15051 15052 15053 15054 STATIC int 15055 soc_ap_ovr_sub_tdm_update(int unit, 15056 soc_apache_tdm_t *tdm, 15057 int pre_count, 15058 soc_port_resource_t *pre_res, 15059 int post_count, 15060 soc_port_resource_t *post_res) 15061 { 15062 int phy_port; 15063 int group, wt_group, speed_group; 15064 int res_count, speed_class; 15065 int slot, empty_slot_cnt; 15066 uint32 speed_spacing; 15067 soc_apache_tdm_t *cur_tdm; 15068 15069 15070 tdm = APACHE_TDM_STRUCT_BACKUP(unit); 15071 cur_tdm = APACHE_TDM_STRUCT_ACTIVE(unit); 15072 15073 /* Remove old ports from the existing egress overusb groups */ 15074 for (res_count = 0; res_count < pre_count; res_count++) { 15075 soc_port_resource_t *p = &pre_res[res_count]; 15076 15077 /* If OBM is not enabled then continue */ 15078 if (!p->oversub) { 15079 continue; 15080 } 15081 15082 if (p->flags & SOC_PORT_RESOURCE_INACTIVE) { 15083 continue; 15084 } 15085 15086 phy_port = p->physical_port; 15087 15088 for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) { 15089 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) { 15090 continue; 15091 } 15092 empty_slot_cnt = 0; 15093 for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 15094 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] == phy_port) { 15095 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = NUM_EXT_PORTS; 15096 15097 } 15098 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) { 15099 empty_slot_cnt++; 15100 } 15101 } 15102 15103 /* Mark group that has no more valid mmu ports as free */ 15104 if (empty_slot_cnt == APACHE_MMU_OVS_GROUP_TDM_LENGTH) { 15105 APACHE_TDM_WT_GRP_FREE(unit, cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group]); 15106 cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = 0; 15107 cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = APACHE_MMU_OVS_WT_GROUP_COUNT; 15108 break; 15109 } 15110 } 15111 } 15112 15113 /* Add 'new' ports to the egress schedulers */ 15114 for (res_count = 0; res_count < post_count; res_count++) { 15115 soc_port_resource_t *p = &post_res[res_count]; 15116 15117 /* If OBM is not enabled then continue */ 15118 if (!p->oversub) { 15119 continue; 15120 } 15121 15122 if (p->flags & SOC_PORT_RESOURCE_INACTIVE) { 15123 continue; 15124 } 15125 15126 speed_class = p->speed; 15127 phy_port = p->physical_port; 15128 15129 if (SOC_FAILURE(_soc_apache_mmu_ovs_speed_class_map_get( 15130 unit, &speed_class, &speed_group, &speed_spacing))) { 15131 LOG_ERROR(BSL_LS_SOC_PORT, 15132 (BSL_META_U(unit, 15133 "Invalid Speed Class %d for port %d (physical = %d)"), 15134 speed_class, p->logical_port, phy_port)); 15135 15136 return SOC_E_INTERNAL; 15137 } 15138 15139 APACHE_TDM_WT_GRP_LOG(unit); 15140 15141 /* Try to fit the new port in the group with same speed ports */ 15142 for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) { 15143 /* Group with different speed ports; skip! */ 15144 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] != speed_class) { 15145 continue; 15146 } 15147 15148 for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) { 15149 /* break when an empty slot is found */ 15150 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) { 15151 break; 15152 } 15153 } 15154 if (slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH) { 15155 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port; 15156 phy_port = NUM_EXT_PORTS; 15157 break; 15158 } 15159 } 15160 15161 if (phy_port == NUM_EXT_PORTS) { 15162 /* Found an empty slot and filled; continue to next */ 15163 continue; 15164 } 15165 15166 /* Could not get a group with same speed ports, try a free group */ 15167 for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) { 15168 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) { 15169 break; 15170 } 15171 } 15172 15173 if (group < APACHE_MMU_OVS_GROUP_COUNT) { 15174 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][0] = phy_port; 15175 cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class; 15176 15177 for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 15178 if (AP_TDM_WT_GRP_SPG_GET(unit, wt_group) == speed_group) { 15179 APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 15180 break; 15181 } 15182 } 15183 15184 if (wt_group >= APACHE_MMU_OVS_WT_GROUP_COUNT) { 15185 for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) { 15186 if (AP_TDM_WT_GRP_REFCNT_GET(unit, wt_group) == 0) { 15187 APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group); 15188 break; 15189 } 15190 } 15191 } 15192 15193 if (wt_group >= APACHE_MMU_OVS_WT_GROUP_COUNT) { 15194 /* We could not find a weight group for this new port */ 15195 LOG_ERROR(BSL_LS_SOC_PORT, 15196 (BSL_META_U(unit, 15197 "Could not find a usable weight group for " 15198 "port %d (physical = %d; speed_class = %d)"), 15199 p->logical_port, phy_port, speed_class)); 15200 return SOC_E_INTERNAL; 15201 } 15202 15203 cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group; 15204 15205 continue; 15206 } 15207 15208 /* We could not find a group that can fit this new port */ 15209 LOG_ERROR(BSL_LS_SOC_PORT, 15210 (BSL_META_U(unit, 15211 "Could not find a usable oversub group for " 15212 "port %d (physical = %d; speed_class = %d)"), 15213 p->logical_port, phy_port, speed_class)); 15214 15215 return SOC_E_INTERNAL; 15216 } 15217 15218 sal_memcpy(&(tdm->egress_ovs_tdm), &(cur_tdm->egress_ovs_tdm), sizeof(tdm->egress_ovs_tdm)); 15219 15220 return SOC_E_NONE; 15221 } 15222 15223 15224 /* 15225 * Function: 15226 * soc_ap_port_resource_tdm_set 15227 * Purpose: 15228 * Reconfigure the ingress and egress schedulers for 15229 * the new port configuration. 15230 * 15231 * This includes reconfiguration of: 15232 * - OBM Thresholds 15233 * - EDB Prebuffer 15234 * - Ingress Oversub Scheduler 15235 * - Egress Oversub Scheduler 15236 * - Line-Rate Scheduler 15237 * Parameters: 15238 * unit - (IN) Unit number. 15239 * curr_port_info_size - (IN) Size of current port information array 15240 * curr_port_info - (IN) Per-port array with current flexing info 15241 * new_port_info_size - (IN) Size of new port information array 15242 * new_port_info - (IN) Per-port array with new flexing info 15243 * si_info - (IN) Contains subset of fields from 15244 * soc_info_t structure 15245 * prior to the flexing operation 15246 * lossless - (IN) MMU lossless information 15247 * Returns: 15248 * SOC_E_XXX 15249 * Note: 15250 * Assumptions 15251 * - soc info structure members have been updated to reflect the latest 15252 * flexing operation 15253 * - There is no overlapping between logical or physical ports in the 15254 * arrays passed, that is, operations like 4x10->1x40->4x10 on the same 15255 * set of ports have been rejected at bcm layer itself, and do not reach 15256 * this function 15257 * - Pre-FlexPort array 15258 * Contains current information on ports to be modified after 15259 * the FlexPort operation. This should include ports whose 15260 * mappings are either deleted or remapped. 15261 * - Post-FlexPort array 15262 * Contains information on new configuration for 15263 * ports that are active (present) after the FlexPort operation. 15264 * This should include ports whose mappings that are remapped or new. 15265 */ 15266 int soc_ap_port_resource_tdm_set(int unit, int curr_port_info_size, 15267 soc_port_resource_t *curr_port_info, 15268 int new_port_info_size, 15269 soc_port_resource_t *new_port_info, 15270 soc_ap_info_t *si_info, 15271 int lossless) 15272 { 15273 int rv; 15274 uint32 rval; 15275 soc_apache_tdm_t *tdm; 15276 15277 /* Reconfigure EDB prebuffer */ 15278 15279 SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval)); 15280 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 15281 CLPORT_CELL_COUNTSf, 0x1); 15282 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 15283 XLPORT_CELL_COUNTSf, 0x3); 15284 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 15285 ENABLEf, 0x1); 15286 SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval)); 15287 15288 /* Reconfigure EDB prebuffer back up calendar, for line rate 15289 * TDM calendar. Oversub related portion will be added later 15290 */ 15291 15292 /* Configure ingress scheduler back up calendar */ 15293 tdm = APACHE_TDM_STRUCT_BACKUP(unit); 15294 SOC_IF_ERROR_RETURN(soc_ap_port_resource_tdm_calculate(unit, tdm)); 15295 15296 /* Reconfigure oversub scheduler. 15297 * Function internally determines if oversub is enabled/disabled 15298 */ 15299 rv = soc_ap_ovr_sub_tdm_update(unit, tdm, 15300 curr_port_info_size, curr_port_info, 15301 new_port_info_size, new_port_info); 15302 SOC_IF_ERROR_RETURN(rv); 15303 15304 15305 /* toggle the active calendar */ 15306 APACHE_TDM_ACTIVE_CAL(unit) ^= 1; 15307 15308 /* update the tdm calendar config in the hardware */ 15309 SOC_IF_ERROR_RETURN(soc_apache_tdm_update(unit, 0, APACHE_TDM_ACTIVE_CAL(unit), tdm)); 15310 15311 15312 /* Reconfigure EDB prebuffer */ 15313 15314 sal_usleep(1); 15315 15316 SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval)); 15317 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 15318 CLPORT_CELL_COUNTSf, 0x1); 15319 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 15320 XLPORT_CELL_COUNTSf, 0x3); 15321 soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval, 15322 ENABLEf, 0x0); 15323 SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval)); 15324 15325 15326 return SOC_E_NONE; 15327 } 15328 15329 /* 15330 * Function: 15331 * soc_ap_port_resource_pgw_set 15332 * Purpose: 15333 * Reconfigure PGW registers in flex port sequence 15334 * In this function following registers will be initialized. 15335 * This function will do two things, 15336 * 1. clear all registers for old ports which exists in pre-Flex status 15337 * 2. initialize all registers for new ports which exists in post-Flex 15338 * status 15339 * 15340 * Parameters: 15341 * unit - (IN) Unit number. 15342 * pre_num_res - (IN) Number of resource data which exist in pre-Flex 15343 * status 15344 * post_num_res - (IN) Number of resource data which exist in post-Flex 15345 * status 15346 * pre_res - (IN) Resource data structure pointer in pre-Flex status 15347 * post_res - (IN) Resource data structure pointer in post-Flex status 15348 * lossless - (IN) MMU lossless information 15349 * 15350 * Returns: 15351 * SOC_E_XXX 15352 * Note: 15353 * - Assumes FlexPort cases are valid. 15354 * - Pre-FlexPort array 15355 * Contains current information on ports to be modified after 15356 * the FlexPort operation. This should include ports whose 15357 * mappings are either deleted or remapped. 15358 * - Post-FlexPort array 15359 * Contains information on new configuration for 15360 * ports that are active (present) after the FlexPort operation. 15361 * This should include ports whose mappings that are remapped or new. 15362 */ 15363 int 15364 soc_ap_port_resource_pgw_set(int unit, 15365 int pre_num_res, soc_port_resource_t *pre_res, 15366 int post_num_res, soc_port_resource_t *post_res, 15367 int lossless) 15368 { 15369 int i; 15370 15371 SOC_IF_ERROR_RETURN( 15372 _soc_ap_resource_data_check(unit, pre_num_res, pre_res)); 15373 SOC_IF_ERROR_RETURN( 15374 _soc_ap_resource_data_check(unit, post_num_res, post_res)); 15375 15376 for (i = 0; i < post_num_res; i++) { 15377 /* Reconfigure the Port Mode for Port Macro */ 15378 SOC_IF_ERROR_RETURN( 15379 soc_portctrl_port_mode_set(unit, post_res[i].logical_port, post_res[i].mode)); 15380 } 15381 15382 SOC_IF_ERROR_RETURN(soc_ap_pgw_obm_set(unit, 15383 pre_num_res, pre_res, 15384 post_num_res, post_res)); 15385 15386 return SOC_E_NONE; 15387 } 15388 15389 /* 15390 * Function: 15391 * soc_ap_port_resource_ip_set 15392 * Purpose: 15393 * Reconfigure IP. 15394 * Parameters: 15395 * unit - (IN) Unit number. 15396 * curr_port_info_size - (IN) Size of current port information array 15397 * curr_port_info - (IN) Per-port array with current flexing info 15398 * new_port_info_size - (IN) Size of new port information array 15399 * new_port_info - (IN) Per-port array with new flexing info 15400 * si_info - (IN) Contains subset of fields from soc_info_t structure 15401 * prior to the flexing operation 15402 * Returns: 15403 * SOC_E_XXX 15404 * Note: 15405 * Assumptions 15406 * - soc info structure members have been updated to reflect the latest 15407 * flexing operation 15408 * - There is no overlapping between logical or physical ports in the 15409 * arrays passed, example, operations like 4x10->1x40->4x10 on the same 15410 * set of ports have been rejected at bcm layer itself, and do not reach 15411 * this function 15412 * - Pre-FlexPort array 15413 * Contains current information on ports to be modified after 15414 * the FlexPort operation. This should include ports whose 15415 * mappings are either deleted or remapped. 15416 * - Post-FlexPort array 15417 * Contains information on new configuration for 15418 * ports that are active (present) after the FlexPort operation. 15419 * This should include ports whose mappings that are remapped or new. 15420 */ 15421 int soc_ap_port_resource_ip_set(int unit, int curr_port_info_size, 15422 soc_port_resource_t *curr_port_info, 15423 int new_port_info_size, 15424 soc_port_resource_t *new_port_info, 15425 soc_ap_info_t *si_info) 15426 { 15427 soc_info_t *si; 15428 soc_mem_t mem; 15429 ing_physical_to_logical_port_number_mapping_table_entry_t entry; 15430 int port, phy_port; 15431 int num_phy_port; 15432 15433 si = &SOC_INFO(unit); 15434 15435 /* Ingress physical to logical port mapping */ 15436 mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm; 15437 num_phy_port = soc_mem_index_count(unit, mem); 15438 15439 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 15440 sal_memset(&entry, 0, sizeof(entry)); 15441 15442 /* The p2l mapping has been updated before this function is called */ 15443 port = si->port_p2l_mapping[phy_port]; 15444 15445 soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf, 15446 port == -1 ? 0x7F : port); 15447 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, 15448 &entry)); 15449 } 15450 15451 return SOC_E_NONE; 15452 } 15453 15454 /* 15455 * Function: 15456 * soc_ap_port_resource_ep_set 15457 * Purpose: 15458 * Reconfigure EP. 15459 * Parameters: 15460 * unit - (IN) Unit number. 15461 * curr_port_info_size - (IN) Size of current port information array 15462 * curr_port_info - (IN) Per-port array with current flexing info 15463 * new_port_info_size - (IN) Size of new port information array 15464 * new_port_info - (IN) Per-port array with new flexing info 15465 * si_info - (IN) Contains subset of fields from soc_info_t structure 15466 * prior to the flexing operation 15467 * Returns: 15468 * SOC_E_XXX 15469 * Note: 15470 * Assumptions 15471 * - soc info structure members have been updated to reflect the latest 15472 * flexing operation 15473 * - There is no overlapping between logical or physical ports in the 15474 * arrays passed, example, operations like 4x10->1x40->4x10 on the same 15475 * set of ports have been rejected at bcm layer itself, and do not reach 15476 * this function 15477 * - Pre-FlexPort array 15478 * Contains current information on ports to be modified after 15479 * the FlexPort operation. This should include ports whose 15480 * mappings are either deleted or remapped. 15481 * - Post-FlexPort array 15482 * Contains information on new configuration for 15483 * ports that are active (present) after the FlexPort operation. 15484 * This should include ports whose mappings that are remapped or new. 15485 */ 15486 int soc_ap_port_resource_ep_set(int unit, int curr_port_info_size, 15487 soc_port_resource_t *curr_port_info, 15488 int new_port_info_size, 15489 soc_port_resource_t *new_port_info, 15490 soc_ap_info_t *si_info) 15491 { 15492 soc_info_t *si; 15493 uint32 rval; 15494 int num_port, port, idx, phy_port; 15495 15496 si = &SOC_INFO(unit); 15497 15498 /* Ingress logical to physical port mapping */ 15499 num_port = soc_mem_index_count(unit, PORT_TABm) - 1; 15500 15501 /* Egress logical to physical port mapping */ 15502 for (port = 0; port < num_port; port++) { 15503 /* 15504 * Use logical to physical number mapping from soc info structure 15505 * since it has been updated before this function is called 15506 */ 15507 phy_port = si->port_l2p_mapping[port]; 15508 15509 rval = 0; 15510 soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr, 15511 &rval, PHYSICAL_PORT_NUMBERf, 15512 phy_port == -1 ? 0x7F : phy_port); 15513 SOC_IF_ERROR_RETURN 15514 (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port, 15515 rval)); 15516 } 15517 15518 /* Clear counters for the newly added ports */ 15519 for (idx = 0; idx < new_port_info_size; idx++) { 15520 SOC_IF_ERROR_RETURN(soc_ap_ep_counters_clear(unit, 15521 &new_port_info[idx])); 15522 } 15523 15524 return SOC_E_NONE; 15525 } 15526 15527 /* 15528 * Function: 15529 * soc_ap_port_resource_mmu_mapping_set 15530 * Purpose: 15531 * Set the HW MMU Port mappings. 15532 * Parameters: 15533 * unit - (IN) Unit number. 15534 * nport - (IN) Number of elements in array resource. 15535 * resource - (IN) Port Resource FlexPort configuration. 15536 * Returns: 15537 * SOC_E_XXX 15538 * Note: 15539 * Assumes FlexPort cases are valid. 15540 * Assumes SOC INFO data structure has been updated. 15541 */ 15542 int 15543 soc_ap_port_resource_mmu_mapping_set(int unit, int nport, 15544 soc_port_resource_t *resource) 15545 { 15546 soc_info_t *si = &SOC_INFO(unit); 15547 soc_port_resource_t *pr; 15548 int i; 15549 int logic_port; 15550 int phy_port; 15551 uint32 rval; 15552 15553 for (i = 0, pr = &resource[0]; i < nport; i++, pr++) { 15554 /* 15555 * Skip for legacy inactive configurations since 15556 * MMU mappings are kept the same. 15557 */ 15558 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) { 15559 LOG_VERBOSE(BSL_LS_SOC_PORT, 15560 (BSL_META_U(unit, 15561 " Skip port with inactive configuration, " 15562 "mappings are kept the same, " 15563 "mmu=%d logical=%d physical=%d\n"), 15564 si->port_p2m_mapping 15565 [si->port_l2p_mapping[pr->logical_port]], 15566 pr->logical_port, 15567 si->port_l2p_mapping[pr->logical_port])); 15568 continue; 15569 } 15570 15571 if (pr->physical_port == -1) { 15572 /* Remove old MMU mappings. */ 15573 logic_port = 0x7F; 15574 phy_port = 0x7F; 15575 15576 } else { 15577 logic_port = pr->logical_port; 15578 phy_port = pr->physical_port; 15579 } 15580 15581 rval = 0; 15582 soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval, 15583 PHY_PORTf, phy_port); 15584 SOC_IF_ERROR_RETURN 15585 (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, pr->logical_port, 15586 0, rval)); 15587 15588 rval = 0; 15589 soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval, 15590 LOGIC_PORTf, logic_port); 15591 SOC_IF_ERROR_RETURN 15592 (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, pr->logical_port, 15593 0, rval)); 15594 15595 LOG_VERBOSE(BSL_LS_SOC_PORT, 15596 (BSL_META_U(unit, 15597 "MMU port mappings: " 15598 "mmu=%d logical=%d physical=%d\n"), 15599 si->port_p2m_mapping 15600 [si->port_l2p_mapping[pr->logical_port]], 15601 logic_port, phy_port)); 15602 } 15603 15604 return SOC_E_NONE; 15605 } 15606 15607 15608 /* 15609 * Function: 15610 * soc_ap_port_resource_mmu_set 15611 * Purpose: 15612 * Called to reconfigure the MMU hardware. 15613 * Parameters: 15614 * unit - (IN) Device Number 15615 * nport - (IN) The number of port modifications in flexport_data 15616 * flexport_data - (IN) An array of port changes that are being done 15617 * Returns: 15618 * SOC_E_NONE if parameters are valid, an error otherwise. 15619 * Note: 15620 * Assumes FlexPort cases are valid. 15621 * Assumes SOC INFO data structure has been updated. 15622 */ 15623 int 15624 soc_ap_port_resource_mmu_set(int unit, int nport, 15625 soc_port_resource_t *flexport_data) 15626 { 15627 int i; 15628 15629 /* Update MMU Port Mappings */ 15630 SOC_IF_ERROR_RETURN 15631 (soc_ap_port_resource_mmu_mapping_set(unit, nport, flexport_data)); 15632 15633 /* Configure all MMU registers for new ports */ 15634 for (i = 0; i < nport; i++) { 15635 if (flexport_data[i].physical_port != -1) { 15636 SOC_IF_ERROR_RETURN( 15637 soc_apache_mmu_port_resource_set(unit, flexport_data[i].logical_port, 15638 flexport_data[i].speed)); 15639 } 15640 } 15641 15642 return SOC_E_NONE; 15643 } 15644 15645 /* 15646 * Function: 15647 * soc_ap_is_port_flex_enable 15648 * Purpose: 15649 * Find out if port_flex_enable{physical port num} config 15650 * is present on the given physical port in config.bcm 15651 * Parameters: 15652 * unit - (IN) Unit number. 15653 * phy_port - (IN) physical port num 15654 * Returns: 15655 * TRUE or FALSE 15656 */ 15657 STATIC int 15658 soc_ap_is_port_flex_enable(int unit, int phy_port) 15659 { 15660 int enable = 0; 15661 15662 /* This property does not apply to cpu port & 15663 * loopback port 15664 */ 15665 15666 if (phy_port > 0 && phy_port < 129) { 15667 enable = soc_property_phys_port_get(unit, 15668 phy_port, 15669 spn_PORT_FLEX_ENABLE, 0); 15670 } 15671 15672 return enable; 15673 } 15674 15675 15676 /* Tells if a port macro (indexed by TSC4, not TSC12) is flex port enabled. 15677 * 15678 * Port macro flex on or off is determined by the first port in that macro. 15679 * For TSC12 it's the first port in the first TSC4. For a TSC4 that is NOT 15680 * part of a TSC12, it's also the first port of that port macro. For a TSC4 15681 * that is a part of a TSC12, refer to the first port of the first port macro 15682 * for that TSC12. 15683 * 15684 * Parameters: 15685 * unit - (IN) Unit number. 15686 * port_macro - (IN) port macro desired 15687 * flex_enabled - (OUT) whether the port macro is enabled or disabled 15688 * 15689 * Returns: 15690 * SOC_E_xxx 15691 */ 15692 int 15693 soc_ap_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled) 15694 { 15695 int port_num = -1; 15696 15697 if ((port_macro < 0) || (port_macro > 18)) { 15698 return SOC_E_PARAM; 15699 } 15700 15701 port_num = (APACHE_PORTS_PER_TSC * port_macro) + 1; 15702 15703 *flex_enabled = soc_ap_is_port_flex_enable(unit, port_num); 15704 15705 return SOC_E_NONE; 15706 } 15707 15708 15709 /* 15710 * Function: 15711 * soc_apache_port_icc_width_set 15712 * Purpose: 15713 * Program PORT_INITIAL_COPY_COUNT_WIDTHr 15714 * Parameters: 15715 * unit - (IN) Unit number. 15716 * port - (IN) Logical SOC port number. 15717 * Returns: 15718 * SOC_E_XXX 15719 */ 15720 STATIC int 15721 soc_apache_port_icc_width_set(int unit, soc_port_t port) 15722 { 15723 int count_width = 0; 15724 15725 if (SOC_INFO(unit).port_speed_max[port] < 25000) { 15726 count_width = 1; /* 1 ICC bit */ 15727 } else if (SOC_INFO(unit).port_speed_max[port] <= 53000) { 15728 count_width = 2; /* 2 ICC bits */ 15729 } else { 15730 count_width = 3; /* 3 ICC bits */ 15731 } 15732 15733 SOC_IF_ERROR_RETURN( 15734 soc_reg_field32_modify(unit, PORT_INITIAL_COPY_COUNT_WIDTHr, 15735 port, BIT_WIDTHf, count_width ? (count_width - 1) : 0)); 15736 15737 return SOC_E_NONE; 15738 } 15739 15740 /* 15741 * Function: 15742 * soc_apache_repl_port_agg_map_init 15743 * Purpose: 15744 * Initialize L3MC Port Agg Map. 15745 * Parameters: 15746 * unit - (IN) Unit number. 15747 * port - (IN) Logical SOC port number. 15748 * Returns: 15749 * SOC_E_xxx 15750 */ 15751 STATIC int 15752 soc_apache_repl_port_agg_map_init(int unit, soc_port_t port) 15753 { 15754 soc_info_t *si; 15755 int phy_port, mmu_port; 15756 uint32 regval; 15757 15758 si = &SOC_INFO(unit); 15759 phy_port = si->port_l2p_mapping[port]; 15760 mmu_port = si->port_p2m_mapping[phy_port]; 15761 15762 /* configure mmu port to repl aggregateId map */ 15763 regval = 0; 15764 soc_reg_field_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr, ®val, 15765 L3MC_PORT_AGG_IDf, mmu_port % 74); 15766 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr, 15767 port,0,regval)); 15768 15769 return SOC_E_NONE; 15770 } 15771 15772 /* 15773 * Function: 15774 * soc_apache_ipmc_repl_init 15775 * Purpose: 15776 * Initialize IPMC Replication settings 15777 * Parameters: 15778 * unit - (IN) Unit number. 15779 * port - (IN) Logical SOC port number. 15780 * Returns: 15781 * SOC_E_XXX 15782 */ 15783 STATIC int 15784 soc_apache_ipmc_repl_init(int unit, soc_port_t port) 15785 { 15786 /* Program MMU_TOQ_REPL_PORT_AGG_MAP 15787 */ 15788 SOC_IF_ERROR_RETURN(soc_apache_repl_port_agg_map_init(unit, port)); 15789 15790 return SOC_E_NONE; 15791 } 15792 15793 /* 15794 * Function: 15795 * soc_apache_mmu_port_resource_set 15796 * Purpose: 15797 * Reconfigure MMU for flexport operation 15798 * Parameters: 15799 * unit - (IN) Unit number. 15800 * port - (IN) Logical SOC port number. 15801 * reset - (IN) Reset. 15802 * Returns: 15803 * SOC_E_XXX 15804 */ 15805 int soc_apache_mmu_port_resource_set(int unit, soc_port_t port, int speed) 15806 { 15807 15808 /* Flex port operation not allowed on CPU or loopback port 15809 */ 15810 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) { 15811 return SOC_E_PARAM; 15812 } 15813 15814 /* Configure all MMU registers for new ports whose setting is 15815 * based on port speed. 15816 */ 15817 SOC_IF_ERROR_RETURN(soc_apache_port_speed_update(unit, port, speed)); 15818 15819 /* Program PORT_INITIAL_COPY_COUNT_WIDTH 15820 */ 15821 SOC_IF_ERROR_RETURN(soc_apache_port_icc_width_set(unit, port)); 15822 15823 /* Reconfigure IPMC replication 15824 */ 15825 SOC_IF_ERROR_RETURN(soc_apache_ipmc_repl_init(unit, port)); 15826 15827 return SOC_E_NONE; 15828 } 15829 15830 /* 15831 * Function: 15832 * soc_apache_is_any_port_flex_enable 15833 * Purpose: 15834 * Find out if 15835 * port_flex_enable=1 OR 15836 * port_flex_enable{physical port num}=1 15837 * config is present in config.bcm 15838 * Parameters: 15839 * unit - (IN) Unit number. 15840 * Returns: 15841 * TRUE or FALSE 15842 * If such a config is present, this function 15843 * returns 1 - implying that flex is enable on 15844 * at least 1 port (port macro) in the system 15845 * This function returns 0, if flex is not enabled 15846 * on any port (port macro) in the system 15847 */ 15848 int soc_apache_is_any_port_flex_enable(int unit) 15849 { 15850 int phy_port, num_phy_port; 15851 15852 num_phy_port = 72; 15853 15854 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 15855 if (soc_property_phys_port_get(unit, 15856 phy_port, 15857 spn_PORT_FLEX_ENABLE, 0)) { 15858 return TRUE; 15859 } 15860 } 15861 15862 return FALSE; 15863 } 15864 15865 #if defined(SER_TR_TEST_SUPPORT) 15866 15867 #define MAX_HW_TCAMS 32 15868 typedef struct ser_apache_skipped_mem_s { 15869 soc_mem_t mem; 15870 soc_acc_type_t acc_type; 15871 } ser_apache_skipped_mem_t; 15872 15873 const ser_apache_skipped_mem_t apache_skipped_mems[] = { 15874 /* Below memories have only one entry */ 15875 {L2_BULK_MATCH_DATAm, _SOC_ACC_TYPE_PIPE_ANY}, 15876 {L2_BULK_MATCH_MASKm, _SOC_ACC_TYPE_PIPE_ANY}, 15877 {L2_BULK_REPLACE_DATAm, _SOC_ACC_TYPE_PIPE_ANY}, 15878 {L2_BULK_REPLACE_MASKm, _SOC_ACC_TYPE_PIPE_ANY}, 15879 {L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY}, 15880 {MPLS_ENTROPY_LABEL_DATAm, _SOC_ACC_TYPE_PIPE_ANY}, 15881 15882 {OAM_LM_COUNTERSm, _SOC_ACC_TYPE_PIPE_ANY}, 15883 {LMEPm, _SOC_ACC_TYPE_PIPE_ANY}, 15884 {LMEP_DAm, _SOC_ACC_TYPE_PIPE_ANY}, 15885 {MAID_REDUCTIONm, _SOC_ACC_TYPE_PIPE_ANY}, 15886 {MA_INDEXm, _SOC_ACC_TYPE_PIPE_ANY}, 15887 {MA_STATEm, _SOC_ACC_TYPE_PIPE_ANY}, 15888 {RMEPm, _SOC_ACC_TYPE_PIPE_ANY}, 15889 {ING_SNAT_ONLYm, _SOC_ACC_TYPE_PIPE_ANY}, 15890 15891 /* FP_GLOBAL_MASK_TCAM and FP_GM_FILEDSm have special handling in memscan 15892 * since H/W space is shared between these two mems. 15893 * It is protected by SW memscan SER engine 15894 */ 15895 {FP_GLOBAL_MASK_TCAMm, _SOC_ACC_TYPE_PIPE_ANY}, 15896 {INVALIDm} 15897 }; 15898 15899 int 15900 ser_test_apache_mem_index_remap(int unit, ser_test_data_t *test_data, 15901 int *mem_has_ecc) 15902 { 15903 int uft_bkt_bank = 0; 15904 int num_uft_banks = 0; 15905 int uft_le_fv = 0; 15906 int uft_le_ecc = 0; 15907 int remap_status = 0; 15908 15909 *mem_has_ecc = 0; 15910 test_data->mem = test_data->mem_fv; 15911 test_data->index = test_data->index_fv; 15912 15913 num_uft_banks = soc_apache_get_alpm_banks(unit); 15914 switch (test_data->mem_fv) { 15915 case VLAN_XLATEm: 15916 case VLAN_MACm: 15917 test_data->mem = VLAN_XLATE_ECCm; 15918 *mem_has_ecc = 1; 15919 break; 15920 case EGR_VLAN_XLATEm: 15921 test_data->mem = EGR_VLAN_XLATE_ECCm; 15922 *mem_has_ecc = 1; 15923 break; 15924 case L2Xm: 15925 case L2_ENTRY_ONLYm: 15926 test_data->mem = L2_ENTRY_ONLY_ECCm; 15927 *mem_has_ecc = 1; 15928 break; 15929 case L3_ENTRY_ONLYm: 15930 case L3_ENTRY_IPV4_UNICASTm: 15931 test_data->mem = L3_ENTRY_ONLY_ECCm; 15932 test_data->index = test_data->index_fv; 15933 *mem_has_ecc = 1; 15934 break; 15935 case L3_ENTRY_IPV4_MULTICASTm: 15936 case L3_ENTRY_IPV6_UNICASTm: 15937 test_data->mem = L3_ENTRY_ONLY_ECCm; 15938 test_data->index = test_data->index_fv*2; 15939 *mem_has_ecc = 1; 15940 break; 15941 case L3_ENTRY_IPV6_MULTICASTm: 15942 test_data->mem = L3_ENTRY_ONLY_ECCm; 15943 test_data->index = test_data->index_fv*4; 15944 *mem_has_ecc = 1; 15945 break; 15946 case L3_DEFIP_ALPM_IPV4m: /* 6:4 */ 15947 *mem_has_ecc = 1; 15948 test_data->mem = L3_DEFIP_ALPM_ECCm; 15949 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks); 15950 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks); 15951 switch (uft_le_fv) { 15952 case 0: uft_le_ecc = 0; break; 15953 case 1: uft_le_ecc = 0; break; /* or 1 */ 15954 case 2: uft_le_ecc = 1; break; 15955 case 3: uft_le_ecc = 2; break; 15956 case 4: uft_le_ecc = 2; break; /* or 3 */ 15957 case 5: uft_le_ecc = 3; break; 15958 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15959 } 15960 test_data->index = (uft_le_ecc << 15961 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15962 break; 15963 case L3_DEFIP_ALPM_IPV4_1m: /* 4:4 */ 15964 case L3_DEFIP_ALPM_IPV6_64m: 15965 *mem_has_ecc = 1; 15966 test_data->mem = L3_DEFIP_ALPM_ECCm; 15967 test_data->index = test_data->index_fv; 15968 break; 15969 case L3_DEFIP_ALPM_IPV6_64_1m: /* 3:4 */ 15970 *mem_has_ecc = 1; 15971 test_data->mem = L3_DEFIP_ALPM_ECCm; 15972 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks); 15973 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks); 15974 switch (uft_le_fv) { 15975 case 0: uft_le_ecc = 0; break; /* or 1 */ 15976 case 1: uft_le_ecc = 1; break; /* or 2 */ 15977 case 2: uft_le_ecc = 2; break; /* or 3 */ 15978 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15979 } 15980 test_data->index = (uft_le_ecc << 15981 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15982 break; 15983 case L3_DEFIP_ALPM_IPV6_128m: /* 2:4 */ 15984 *mem_has_ecc = 1; 15985 test_data->mem = L3_DEFIP_ALPM_ECCm; 15986 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks); 15987 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks); 15988 switch (uft_le_fv) { 15989 case 0: uft_le_ecc = 0; break; /* or 1 */ 15990 case 1: uft_le_ecc = 2; break; /* or 3 */ 15991 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 15992 } 15993 test_data->index = (uft_le_ecc << 15994 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 15995 break; 15996 case L3_DEFIP_ALPM_RAWm: /* 1:4 */ 15997 *mem_has_ecc = 1; 15998 test_data->mem = L3_DEFIP_ALPM_ECCm; 15999 uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks); 16000 uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks); 16001 switch (uft_le_fv) { 16002 case 0: uft_le_ecc = 0; break; /* or 1,2,3 */ 16003 default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break; 16004 } 16005 test_data->index = (uft_le_ecc << 16006 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank; 16007 break; 16008 default: 16009 test_data->mem = test_data->mem_fv; 16010 test_data->index = test_data->index_fv; 16011 break; 16012 } 16013 if ((test_data->mem != test_data->mem_fv) || 16014 (test_data->index != test_data->index_fv)) { 16015 LOG_VERBOSE(BSL_LS_SOC_SER, 16016 (BSL_META_U(unit, 16017 "unit %d, ser_test_mem_index_remap: " 16018 "mem_fv %s, index_fv %0d, mem %s, index %0d, " 16019 "uft_bkt_bank %0d, uft_le_fv %0d, " 16020 "uft_le_ecc %0d, remap_status %0d \n"), 16021 unit, SOC_MEM_NAME(unit, test_data->mem_fv), test_data->index_fv, 16022 SOC_MEM_NAME(unit, test_data->mem), test_data->index, 16023 uft_bkt_bank, uft_le_fv, uft_le_ecc, remap_status)); 16024 } 16025 return remap_status; 16026 } 16027 16028 int 16029 soc_apache_mem_is_eligible_for_scan(int unit, soc_mem_t mem) 16030 { 16031 switch (mem) { 16032 case L3_DEFIP_ALPM_ECCm: 16033 case L2_ENTRY_LPm: 16034 case L3_ENTRY_LPm: 16035 case VLAN_XLATE_LPm: 16036 case EGR_VLAN_XLATE_LPm: 16037 case L2_ENTRY_ISS_LPm: 16038 case L3_ENTRY_ISS_LPm: 16039 return 1; 16040 16041 default: 16042 break; 16043 } 16044 return 0; 16045 } 16046 16047 int 16048 soc_apache_ser_test_skip_check (int unit, soc_mem_t mem) 16049 { 16050 int i; 16051 16052 if (!SOC_MEM_IS_VALID(unit, mem) || 16053 ((mem != INVALIDm) && 16054 ((SOC_MEM_INFO(unit, mem).flags & 16055 SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) { 16056 return 1; 16057 } 16058 16059 if (soc_mem_index_count(unit, mem) <= 0) { 16060 return 1; 16061 } 16062 16063 for (i = 0; apache_skipped_mems[i].mem != INVALIDm; i++) { 16064 if (apache_skipped_mems[i].mem == mem) { 16065 return 1; 16066 } 16067 } 16068 if (!(SOC_MEM_INFO(unit, mem).flags & SOC_MEM_SER_FLAGS)) { 16069 return 1; 16070 } 16071 /* Skip the memory if the relevant feature and memory is disabled. */ 16072 if (!soc_feature(unit, soc_feature_l3) 16073 || !soc_feature(unit, soc_feature_lpm_tcam) ) { 16074 /* Skip L3_DEFIP memorys */ 16075 if ((L3_DEFIPm == mem) || (L3_DEFIP_PAIR_128m == mem)) return 1; 16076 } 16077 if (!soc_feature(unit, soc_feature_l3) || 16078 soc_feature(unit, soc_feature_no_tunnel)) { 16079 /* Skip ING L3 Tunnel memorys */ 16080 if ((L3_TUNNELm == mem) || (L3_TUNNEL_DATA_ONLYm == mem)) return 1; 16081 } 16082 if (!soc_feature(unit, soc_feature_nat)) { 16083 /* Skip NAT memorys */ 16084 if (ING_SNATm == mem) return 1; 16085 } 16086 16087 /* Skip MPLS memories */ 16088 16089 if (ING_MPLS_EXP_MAPPINGm == mem) { 16090 return 1; 16091 } 16092 16093 return 0; 16094 } 16095 16096 STATIC 16097 soc_error_t 16098 _soc_apache_tcam_ser_mem_info_get (int unit, soc_mem_t mem, int *index_p) 16099 { 16100 int i; 16101 _soc_generic_ser_info_t *tcams = _soc_apache_tcam_ser_info[unit]; 16102 16103 for (i = 0; tcams[i].mem != INVALIDm; i++) { 16104 if (tcams[i].mem == mem) { 16105 *index_p = i; 16106 return SOC_E_NONE; 16107 } 16108 } 16109 return SOC_E_NOT_FOUND; 16110 } 16111 16112 STATIC soc_error_t 16113 _soc_apache_ser_mem_info_get (int unit, soc_mem_t mem, _soc_mem_ser_en_info_t** ser_mem_info) 16114 { 16115 #if defined(BCM_56560_A0) 16116 int i, j; 16117 _soc_mem_ser_en_info_t *ser_en_info = NULL; 16118 16119 for (i = 0; _soc_apache_ser_block_info[i].blocktype != 0; i++) { 16120 if ((_soc_apache_ser_block_info[i].type == _SOC_APACHE_SER_TYPE_MEM) && 16121 ((_soc_apache_ser_block_info[i].blocktype == SOC_BLK_IPIPE) || 16122 (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_EPIPE) || 16123 (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_MMU))) { 16124 ser_en_info = _soc_apache_ser_block_info[i].info; 16125 for (j = 0; ser_en_info[j].mem != INVALIDm; j++) { 16126 if (ser_en_info[j].mem == mem) { 16127 *ser_mem_info = &ser_en_info[j]; 16128 return SOC_E_NONE; 16129 } 16130 } 16131 } 16132 } 16133 #endif 16134 return SOC_E_NOT_FOUND; 16135 } 16136 /* 16137 * Function: 16138 * soc_apache_ser_error_injection_support 16139 * Purpose: 16140 * Checks if a memory is supported by error injection interface 16141 * 16142 * Parameters: 16143 * unit - (IN) Device Number 16144 * memory - (IN) Test data required for SER test 16145 * pipe - (IN) How many indices to test for each memory 16146 * 16147 * Returns: 16148 * SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported 16149 */ 16150 soc_error_t 16151 soc_apache_ser_error_injection_support (int unit, soc_mem_t mem, 16152 int pipe) 16153 { 16154 int rv = SOC_E_UNAVAIL; 16155 _soc_mem_ser_en_info_t *ser_mem_info = NULL; 16156 int tcam_idx = 0; 16157 16158 if (soc_apache_ser_test_skip_check (unit,mem)) { 16159 return rv; 16160 } 16161 16162 rv = _soc_apache_ser_mem_info_get(unit, mem, &ser_mem_info); 16163 if (rv == SOC_E_NONE) { 16164 return rv; 16165 } 16166 16167 rv = _soc_apache_tcam_ser_mem_info_get(unit, mem, &tcam_idx); 16168 if (rv == SOC_E_NONE) { 16169 return rv; 16170 } 16171 16172 return rv; 16173 } 16174 16175 /* 16176 * Function: 16177 * _soc_apache_perform_ser_test 16178 * Purpose: 16179 * Performs test operations common to TCAM and FIFO memory tests before 16180 * invoking common SER test. 16181 * Parameters: 16182 * unit - (IN) Device Number 16183 * test_data - (IN) Test data required for SER test 16184 * test_type - (IN) How many indices to test for each memory 16185 * mem_failed - (OUT) Incremented when memories fail the test. 16186 * Returns: 16187 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors are 16188 * possible.) 16189 */ 16190 soc_error_t 16191 _soc_apache_perform_ser_test (int unit, ser_test_data_t *test_data, 16192 _soc_ser_test_t test_type, 16193 int *mem_skipped, int *mem_failed) 16194 { 16195 int skip_mem = FALSE; 16196 soc_error_t rv = SOC_E_NONE; 16197 uint32 flags = 0; 16198 16199 if (soc_apache_ser_test_skip_check (unit,test_data->mem)) { 16200 skip_mem = TRUE; 16201 } 16202 16203 if (!skip_mem) { 16204 if (test_data->mem == ING_VLAN_VFI_MEMBERSHIPm || 16205 test_data->mem == MMU_MTRO_S1_MEM_0m || 16206 test_data->mem == MMU_MTRI_BKPMETERINGCONFIG_MEM_0m || 16207 test_data->mem == MMU_MTRO_EGRMETERINGCONFIG_MEM_0m) { 16208 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16209 } 16210 rv = ser_test_mem(unit, flags, test_data, test_type, mem_failed); 16211 } else { 16212 LOG_VERBOSE(BSL_LS_SOC_COMMON, 16213 (BSL_META_U(unit, 16214 "Memory %s skipped due to known issues.\n"), 16215 SOC_MEM_NAME(unit,test_data->mem))); 16216 (*mem_skipped)++; 16217 } 16218 16219 return rv; 16220 } 16221 16222 /* 16223 * Function: 16224 * soc_apache_ser_tcam_test 16225 * Purpose: 16226 * Tests that SER is working for fifo and SRAM memories 16227 * Parameters: 16228 * unit - (IN) Device Number 16229 * test_type - (IN) How many indices to test for each memory 16230 * Returns: 16231 * the number of tests which are failed 16232 */ 16233 int 16234 soc_apache_ser_tcam_test (int unit, _soc_ser_test_t test_type) { 16235 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 16236 ser_test_data_t test_data; 16237 int mem_failed = 0, mem_tests = 0, mem_skipped = 0; 16238 _soc_generic_ser_info_t *tcams = _soc_apache_tcam_ser_info[unit]; 16239 int i, rv; 16240 soc_acc_type_t acc_type; 16241 soc_field_t test_field = VALIDf; 16242 16243 for (i = 0; tcams[i].mem != INVALIDm; i++) { 16244 mem_tests++; 16245 if ( i >= MAX_HW_TCAMS) { 16246 mem_skipped++; 16247 LOG_VERBOSE(BSL_LS_SOC_COMMON, 16248 (BSL_META_U(unit, 16249 "Memory %s skipped due to lack of test mechanism \ 16250 for Software-protected TCAMS.\n"), 16251 SOC_MEM_NAME(unit,test_data.mem))); 16252 continue; 16253 } 16254 16255 acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16256 16257 if (tcams[i].mem == L3_DEFIPm) { 16258 test_field = VALID0f; 16259 } else if (tcams[i].mem == L3_DEFIP_PAIR_128m) { 16260 test_field = VALID0_LWRf; 16261 } else { 16262 test_field = VALIDf; 16263 } 16264 16265 soc_ser_create_test_data(unit, tmp_entry, fieldData, SER_RANGE_ENABLEr, 16266 i, INVALIDf, tcams[i].mem, test_field, 16267 MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0, 16268 &test_data); 16269 16270 rv = _soc_apache_perform_ser_test(unit, &test_data, test_type, 16271 &mem_skipped, &mem_failed); 16272 if (SOC_FAILURE(rv)) { 16273 LOG_CLI((BSL_META_U(unit, 16274 "TCAM SER test fail for mem: \t %s\n\n"), 16275 SOC_MEM_NAME(unit,test_data.mem))); 16276 } 16277 } 16278 16279 LOG_CLI((BSL_META_U(unit, 16280 "\nTCAM memories tested on unit %d: %d\n"), unit, mem_tests)); 16281 LOG_CLI((BSL_META_U(unit, 16282 "TCAM tests passed:\t%d\n"), 16283 mem_tests - mem_failed - mem_skipped)); 16284 LOG_CLI((BSL_META_U(unit, 16285 "TCAM tests skipped:\t%d (use verbose option to see " 16286 "skipped memories)\n"), 16287 mem_skipped)); 16288 LOG_CLI((BSL_META_U(unit, 16289 "TCAM tests failed:\t%d\n\n"), mem_failed)); 16290 16291 return mem_failed; 16292 } 16293 16294 /* 16295 * Function: 16296 * soc_apache_ser_hardware_test 16297 * Purpose: 16298 * Tests that SER is working for fifo and SRAM memories 16299 * Parameters: 16300 * unit - (IN) Device Number 16301 * test_type - (IN) How many indices to test for each memory 16302 * Returns: 16303 * the number of tests which are failed 16304 */ 16305 int 16306 soc_apache_ser_hardware_test (int unit, _soc_ser_test_t test_type) { 16307 #if defined(BCM_56560_A0) 16308 ser_test_data_t test_data; 16309 int mem_failed = 0, mem_tests = 0, mem_skipped = 0; 16310 int i,j,rv; 16311 soc_acc_type_t acc_type; 16312 _soc_mem_ser_en_info_t *ser_en_info = NULL; 16313 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 16314 16315 for (i = 0; _soc_apache_ser_block_info[i].blocktype != 0; i++) { 16316 if ((_soc_apache_ser_block_info[i].type == _SOC_APACHE_SER_TYPE_MEM) && 16317 ((_soc_apache_ser_block_info[i].blocktype == SOC_BLK_IPIPE) || 16318 (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_EPIPE) || 16319 (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_MMU))) { 16320 ser_en_info = _soc_apache_ser_block_info[i].info; 16321 for (j = 0; ser_en_info[j].mem != INVALIDm; j++) { 16322 mem_tests += 1; 16323 test_data.test_field = EVEN_PARITYf; 16324 acc_type = -1; 16325 soc_ser_create_test_data(unit, tmp_entry, fieldData, 16326 ser_en_info[j].en_ctrl.ctrl_type.en_reg, 16327 SOC_INVALID_TCAM_PARITY_BIT, 16328 ser_en_info[j].en_ctrl.en_fld, 16329 ser_en_info[j].mem, 16330 test_data.test_field, 16331 MEM_BLOCK_ANY, 16332 REG_PORT_ANY, acc_type, 0, 16333 &test_data); 16334 if ((test_data.mem_info == NULL) || 16335 (!(soc_mem_index_count(unit, ser_en_info[j].mem) > 0))) { 16336 mem_skipped++; 16337 LOG_VERBOSE(BSL_LS_SOC_COMMON, 16338 (BSL_META_U(unit, 16339 "Memory %s skipped due to lack of" 16340 " mem_info structure or being disabled.\n"), 16341 SOC_MEM_NAME(unit,test_data.mem))); 16342 continue; 16343 } 16344 rv = _soc_apache_perform_ser_test(unit, &test_data, 16345 test_type, &mem_skipped, 16346 &mem_failed); 16347 if (SOC_FAILURE(rv)) { 16348 LOG_CLI((BSL_META_U(unit, 16349 "H/W SER test fail for mem: \t %s\n\n"), 16350 SOC_MEM_NAME(unit,test_data.mem))); 16351 } 16352 } 16353 } 16354 } 16355 16356 LOG_CLI((BSL_META_U(unit, 16357 "\nH/W memories tested on unit %d: %d\n"), unit, mem_tests)); 16358 LOG_CLI((BSL_META_U(unit, 16359 "H/W tests passed:\t%d\n"), 16360 mem_tests - mem_failed - mem_skipped)); 16361 LOG_CLI((BSL_META_U(unit, 16362 "H/W tests skipped:\t%d (use verbose option to see " 16363 "skipped memories)\n"), 16364 mem_skipped)); 16365 LOG_CLI((BSL_META_U(unit, 16366 "H/W tests failed:\t%d\n\n"), mem_failed)); 16367 return mem_failed; 16368 #else 16369 return SOC_E_NONE; 16370 #endif 16371 16372 } 16373 16374 16375 /* 16376 * Function: 16377 * soc_apache_ser_test 16378 * Purpose: 16379 * Tests that SER is working for all supported memories. 16380 * Parameters: 16381 * unit - (IN) Device Number 16382 * test_type - (IN) How many indices to test for each memory 16383 * Returns: 16384 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors are 16385 * possible.) 16386 */ 16387 soc_error_t 16388 soc_apache_ser_test (int unit, _soc_ser_test_t test_type) { 16389 int errors = 0; 16390 16391 /*Test TCAM memories*/ 16392 errors += soc_apache_ser_tcam_test(unit, test_type); 16393 16394 /*Test for FIFO memories*/ 16395 errors += soc_apache_ser_hardware_test(unit, test_type); 16396 16397 if (errors == 0) { 16398 return SOC_E_NONE; 16399 } else { 16400 return SOC_E_FAIL; 16401 } 16402 } 16403 16404 #define TR_MEM_NAME_SIZE_MAX 100 16405 16406 #ifdef SOC_MEM_NAME 16407 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) do { \ 16408 const char *_mem_name = SOC_MEM_NAME(_unit_, _mem); \ 16409 if (sal_strlen(_mem_name) < TR_MEM_NAME_SIZE_MAX) { \ 16410 sal_strcpy(_msg, _mem_name); \ 16411 } \ 16412 } while (0) 16413 #else 16414 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) 16415 #endif 16416 16417 #define TR_TEST_MEM_PRINT(_unit, _msg, _mem) do { \ 16418 sal_sprintf(_msg, "Mem ID: %d", _mem); \ 16419 TR_TEST_MEM_NAME_GET(_unit, _msg, _mem); \ 16420 LOG_CLI((BSL_META_U(_unit, \ 16421 "Memory %s is valid, but not currently testable.\n"), \ 16422 _msg)); \ 16423 } while (0) 16424 16425 /* 16426 * Function: 16427 * soc_apache_ser_inject_or_test_mem 16428 * Purpose: 16429 * Provide a common function for injecting errors and testing single 16430 * single memories 16431 * Parameters: 16432 * unit - (IN) Device Number 16433 * mem - (IN) The memory into which an error will be injected 16434 * pipeTarget - (IN) The pipe (x/y) to use when injecting the error 16435 * index - (IN) The index into which the error will be injected. 16436 * test_type - (IN) How many indices to test in the passes memory 16437 * cmd - (IN) TRUE if a command-line test is desired. 16438 * Returns: 16439 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors 16440 * are possible.) 16441 */ 16442 soc_error_t 16443 soc_apache_ser_inject_or_test_mem (int unit, soc_mem_t mem, int pipe_target, 16444 int block, int index, 16445 _soc_ser_test_t test_type, 16446 int inject_only, int cmd, uint32 flags) 16447 { 16448 uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS]; 16449 ser_test_data_t tcam_test_data, hw_test_data, *test_data; 16450 int tcam_idx = 0; 16451 _soc_generic_ser_info_t *tcams = _soc_apache_tcam_ser_info[unit]; 16452 int error_count = 0, skip_count = 0, found_mem = FALSE; 16453 char fail_message[400]; 16454 soc_error_t rv = SOC_E_NONE; 16455 soc_field_t test_field = INVALIDf; 16456 soc_acc_type_t soc_acc_type_target = _SOC_ACC_TYPE_PIPE_ANY; 16457 _soc_mem_ser_en_info_t *ser_mem_info = NULL; 16458 int mem_has_ecc = 0, is_tcam = 0, is_fifo_mem = 0; 16459 16460 /* TCAM test */ 16461 rv = _soc_apache_tcam_ser_mem_info_get(unit, mem, &tcam_idx); 16462 if (rv == SOC_E_NONE) { 16463 if (tcams[tcam_idx].mem == L3_DEFIPm) { 16464 test_field = VALID0f; 16465 } else if (tcams[tcam_idx].mem == L3_DEFIP_PAIR_128m) { 16466 test_field = VALID0_LWRf; 16467 } else { 16468 test_field = VALIDf; 16469 } 16470 soc_ser_create_test_data(unit, tmp_entry, fieldData, 16471 SER_RANGE_ENABLEr, tcam_idx, INVALIDf, mem, 16472 test_field, block, REG_PORT_ANY, 16473 soc_acc_type_target, index, &tcam_test_data); 16474 found_mem = TRUE; 16475 is_tcam = 1; 16476 } 16477 16478 /* H/W test */ 16479 rv = _soc_apache_ser_mem_info_get (unit, mem, &ser_mem_info); 16480 if (rv == SOC_E_NONE) { 16481 if (mem == ING_L3_NEXT_HOPm) { 16482 test_field= ECC_1f; 16483 } else { 16484 test_field = EVEN_PARITYf; 16485 } 16486 soc_ser_create_test_data(unit, tmp_entry, fieldData, 16487 ser_mem_info->en_ctrl.ctrl_type.en_reg, 16488 SOC_INVALID_TCAM_PARITY_BIT, 16489 ser_mem_info->en_ctrl.en_fld, 16490 mem, test_field, block, 16491 REG_PORT_ANY, soc_acc_type_target, 16492 index, &hw_test_data); 16493 if (SOC_REG_IS_VALID(unit, ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg) && 16494 (INVALIDf != ser_mem_info->ecc1b_ctrl.en_fld)) { 16495 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16496 } 16497 SOC_IF_ERROR_RETURN 16498 (ser_test_mem_index_remap(unit, &hw_test_data, &mem_has_ecc)); 16499 if (mem_has_ecc) { 16500 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16501 } 16502 /* ING_VLAN_VFI_MEMBERSHIP is ECC protected, however 16503 * there is no 1bit error reporting control register for it. 16504 */ 16505 if (mem == ING_VLAN_VFI_MEMBERSHIPm) { 16506 flags |= SOC_INJECT_ERROR_2BIT_ECC; 16507 } 16508 found_mem = TRUE; 16509 is_fifo_mem = 1; 16510 } 16511 16512 if (found_mem) { 16513 test_data = is_tcam ? &tcam_test_data : &hw_test_data; 16514 test_data->acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16515 if (inject_only) { 16516 /* Check if the memory is to be skipped */ 16517 if (soc_apache_ser_test_skip_check(unit,mem)) { 16518 TR_TEST_MEM_PRINT(unit, fail_message, mem); 16519 return SOC_E_UNAVAIL; 16520 } 16521 16522 /*Disable parity*/ 16523 SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, test_data, 0)); 16524 /*Read the memory (required for successful injection)*/ 16525 SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, test_data)); 16526 /*Inject error*/ 16527 SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags, 16528 test_data)); 16529 /*Enable parity*/ 16530 rv = _ser_test_parity_control(unit, test_data, 1); 16531 } else { 16532 if (cmd) { 16533 tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16534 ser_test_cmd_generate(unit, &tcam_test_data); 16535 hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16536 ser_test_cmd_generate(unit, &hw_test_data); 16537 } else { 16538 if (is_tcam) { 16539 tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16540 rv = _soc_apache_perform_ser_test(unit, &tcam_test_data, test_type, 16541 &skip_count, &error_count); 16542 if (SOC_SUCCESS(rv)) { 16543 LOG_CLI((BSL_META_U(unit, 16544 "TCAM SER test PASSED for memory %s\n\n"), 16545 tcam_test_data.mem_name)); 16546 } else { 16547 LOG_CLI((BSL_META_U(unit, 16548 "TCAM SER test FAILED for memory %s\n\n"), 16549 tcam_test_data.mem_name)); 16550 } 16551 } 16552 16553 if (is_fifo_mem) { 16554 hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY; 16555 rv = _soc_apache_perform_ser_test(unit, &hw_test_data, test_type, 16556 &skip_count, &error_count); 16557 if (SOC_SUCCESS(rv)) { 16558 LOG_CLI((BSL_META_U(unit, 16559 "H/W SER test PASSED for memory %s\n\n"), 16560 hw_test_data.mem_name)); 16561 } else { 16562 LOG_CLI((BSL_META_U(unit, 16563 "H/W SER test FAILED for memory %s\n\n"), 16564 hw_test_data.mem_name)); 16565 } 16566 } 16567 16568 if (skip_count != 0 ) { 16569 LOG_CLI((BSL_META_U(unit, 16570 "Test skipped due to known issues with " 16571 "this memory.\n"))); 16572 } 16573 } 16574 } 16575 } else { 16576 TR_TEST_MEM_PRINT(unit, fail_message, mem); 16577 rv = SOC_E_UNAVAIL; 16578 } 16579 return rv; 16580 } 16581 #undef TR_TEST_MEM_PRINT 16582 16583 /* 16584 * Function: 16585 * soc_apache_ser_inject_error 16586 * Purpose: 16587 * Injects an error into a single apache memory 16588 * Parameters: 16589 * unit - (IN) Device Number 16590 * mem - (IN) The memory into which an error will be injected 16591 * pipeTarget - (IN) The pipe (x/y) to use when injecting the error 16592 * index - (IN) The index into which the error will be injected. 16593 */ 16594 soc_error_t 16595 soc_apache_ser_inject_error (int unit, uint32 flags, soc_mem_t mem, 16596 int pipe_target, int block, int index) 16597 { 16598 /* Check if memory needs to be skipped */ 16599 if (ser_apache_test_fun.injection_support) { 16600 SOC_IF_ERROR_RETURN( 16601 soc_apache_ser_error_injection_support(unit, mem, pipe_target)); 16602 } 16603 16604 return soc_apache_ser_inject_or_test_mem(unit, mem, pipe_target, block, 16605 index, SER_SINGLE_INDEX, TRUE, 16606 FALSE, flags); 16607 } 16608 16609 /* 16610 * Function: 16611 * soc_apache_ser_test_mem 16612 * Purpose: 16613 * Perform SER test on a single memory, or generate a test the user can 16614 * enter by the command line. 16615 * Parameters: 16616 * unit - (IN) Device Number 16617 * mem - (IN) The memory into which an error will be injected 16618 * test_type - (IN) How many indices to test in the passes memory 16619 * cmd - (IN) TRUE if a command-line test is desired. 16620 * Returns: 16621 * SOC_E_NONE if test passes, an error otherwise (multiple types of errors 16622 * are possible.) 16623 */ 16624 soc_error_t 16625 soc_apache_ser_test_mem (int unit, soc_mem_t mem, _soc_ser_test_t test_type, 16626 int cmd) 16627 { 16628 return soc_apache_ser_inject_or_test_mem (unit, mem, _SOC_ACC_TYPE_PIPE_ANY, 16629 MEM_BLOCK_ANY, 0, 16630 test_type, FALSE, cmd, FALSE); 16631 } 16632 #endif /*defined(SER_TR_TEST_SUPPORT)*/ 16633 16634 /* 16635 * Apache chip driver functions. 16636 */ 16637 soc_functions_t soc_apache_drv_funs = { 16638 _soc_apache_misc_init, 16639 _soc_apache_mmu_init, 16640 _soc_apache_age_timer_get, 16641 _soc_apache_age_timer_max_get, 16642 _soc_apache_age_timer_set, 16643 NULL, 16644 _soc_apache_mdio_reg_read, 16645 _soc_apache_mdio_reg_write, 16646 soc_apache_bond_info_init, 16647 _soc_apache_misc_deinit 16648 }; 16649 16650 #endif /* BCM_APACHE_SUPPORT */ 16651