asf.c (84555B)
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: asf.c 8 * Purpose: ASF feature support for Trident3 SKUs 9 * Requires: soc/trident3.h 10 */ 11 12 #include <soc/trident3.h> 13 14 #if defined(BCM_TRIDENT3_SUPPORT) 15 16 #include <appl/diag/system.h> 17 #include <soc/drv.h> 18 #include <soc/ll.h> 19 #include <soc/property.h> 20 #include <shared/bsl.h> 21 #ifdef BCM_WARM_BOOT_SUPPORT 22 #include <soc/scache.h> 23 #endif 24 25 26 #define _SOC_TD3_ASF_CLASS_CNT 13 /* 0 for SAF, 13-15 are reserved. */ 27 #define _SOC_TD3_ASF_QUERY 0xfe 28 #define _SOC_TD3_ASF_RETRV 0xff 29 30 #define _SOC_TD3_CT_CLASS_TO_SPEED_MAP(ct_class) \ 31 _soc_td3_asf_cfg_tbl[(ct_class)].speed 32 33 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 34 35 #define _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(ct_class, floor) \ 36 do { \ 37 if (!(((ct_class) >= (floor)) && \ 38 ((ct_class) < _SOC_TD3_ASF_CLASS_CNT))) \ 39 return SOC_E_PARAM; \ 40 } while (0) 41 42 #define _SOC_TD3_ASF_PORT_VALIDATE(unit, port) \ 43 do { \ 44 if (IS_CPU_PORT(((unit)), (port)) || \ 45 IS_LB_PORT(((unit)), (port)) || \ 46 SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) \ 47 return SOC_E_UNAVAIL; \ 48 } while (0) 49 50 /* EP Credits Outstanding */ 51 typedef struct _soc_td3_ep_credit_s { 52 uint8 base_cells; /* Baseline cells */ 53 uint8 pfc_op_cells; /* PFC Optimized cells */ 54 } _soc_td3_ep_credit_t; 55 56 /* CT FIFO Threshold and Depth */ 57 typedef struct _soc_td3_ct_fifo_profile_s { 58 uint8 line_rate; /* Line-rate profile */ 59 uint8 oversub; /* General profile */ 60 } _soc_td3_ct_fifo_profile_t; 61 62 typedef struct _soc_td3_ct_fifo_s { 63 _soc_td3_ct_fifo_profile_t ss; /* Same-Speed */ 64 _soc_td3_ct_fifo_profile_t sf; /* Slow-to-Fast */ 65 _soc_td3_ct_fifo_profile_t fs; /* Fast-to-Slow */ 66 }_soc_td3_ct_fifo_t; 67 68 /* Bubble MOP */ 69 typedef struct _soc_td3_mop_s { 70 uint8 line_rate; /* Line-rate profile */ 71 uint8 oversub; /* Oversub profile */ 72 } _soc_td3_mop_t; 73 74 /* EDB Prebuffer */ 75 typedef struct _soc_td3_edb_prebuf_profile_s { 76 uint8 saf; /* prebuffer for store-and-forward. 16B granularity. */ 77 uint8 ct; /* prebuffer for cut-through. 16B granularity. */ 78 } _soc_td3_edb_prebuf_profile_t; 79 typedef struct _soc_td3_edb_prebuf_s { 80 _soc_td3_edb_prebuf_profile_t line_rate; 81 _soc_td3_edb_prebuf_profile_t oversub_161; /* 1.61 Oversub */ 82 _soc_td3_edb_prebuf_profile_t oversub_2_1; /* 2:1 Oversub */ 83 } _soc_td3_edb_prebuf_t; 84 85 /* MMU Credit Thresholds */ 86 typedef struct _soc_td3_mmu_credit_threshold_profile_s { 87 uint8 lo; /* MMU High Credit Threshold */ 88 uint8 hi; /* MMU Low Credit Threshold */ 89 } _soc_td3_mmu_credit_threshold_profile_t; 90 typedef struct _soc_td3_mmu_credit_threshold_s { 91 _soc_td3_mmu_credit_threshold_profile_t lr_os_161; /* line-rate and os ratio <= 1.61 */ 92 _soc_td3_mmu_credit_threshold_profile_t os_2_1; /* os ratio > 1.61 */ 93 } _soc_td3_mmu_credit_threshold_t; 94 95 /* IFSAF Threshold */ 96 typedef struct _soc_td3_ifsaf_threshold_s { 97 uint8 saf; 98 uint8 ct; 99 }_soc_td3_ifsaf_threshold_t; 100 101 /* ASF core config */ 102 typedef struct _soc_td3_asf_core_cfg_s { 103 int speed; 104 uint8 min_sp; /* Min. Src. Port Speed */ 105 uint8 max_sp; /* Max. Src. Port Speed */ 106 uint8 mmu_prebuffer; /* MMU prebuffer */ 107 _soc_td3_ct_fifo_t ct_fifo_threshold; /* Same-speed CT FIFO Threshold */ 108 _soc_td3_ct_fifo_t ct_fifo_depth; /* Same-speed CT FIFO Depth */ 109 uint8 fast_to_slow_acc; /* Fast to slow CT Accumulation */ 110 _soc_td3_mop_t mop_enable; /* Bubble MOP enable */ 111 _soc_td3_edb_prebuf_t edb_prebuffer; /* EDB prebuffer. xmit start cnt */ 112 _soc_td3_mmu_credit_threshold_t mmu_credit_threshold; /* MMU Credit Threshold */ 113 _soc_td3_ep_credit_t ep_credit; /* EP Credit */ 114 _soc_td3_ifsaf_threshold_t ca_thresh; /* CA_CT_CONTROL threshold0 */ 115 _soc_td3_ifsaf_threshold_t ct_ok_thresh; /* CT_THRESHOLD cut_through_ok */ 116 _soc_td3_ifsaf_threshold_t unsat_thresh; /* FORCE_SAF_CONFIG unsatisfied_threshold */ 117 /* NOTE: DON'T ALTER FIELD ORDER */ 118 } _soc_td3_asf_core_cfg_t; 119 120 /* ASF ctrl */ 121 typedef struct _soc_td3_asf_ctrl_s { 122 uint8 init; 123 pbmp_t asf_ports; 124 pbmp_t pause_restore; 125 pbmp_t asf_ss; 126 pbmp_t asf_sf; 127 pbmp_t asf_fs; 128 soc_td3_asf_mem_profile_e asf_mem_profile; 129 } _soc_td3_asf_ctrl_t; 130 131 #ifdef BCM_WARM_BOOT_SUPPORT 132 /* ASF Warmboot */ 133 typedef struct _soc_td3_asf_wb_s { 134 int unit; 135 _soc_td3_asf_ctrl_t asf_ctrl; 136 } _soc_td3_asf_wb_t; 137 #endif 138 139 /* ASF Core Config Table */ 140 static const _soc_td3_asf_core_cfg_t 141 _soc_td3_asf_cfg_tbl[_SOC_TD3_ASF_CLASS_CNT] = { 142 { -1, 0, 0, 0, {{0, 0}, { 0, 0}, {0, 0}}, {{0, 0}, { 0, 0}, { 0, 0}}, 0, {0, 0}, {{0, 0}, { 0, 0}, { 0, 0}}, {{0, 0}, {0, 0}}, { 0, 0}, {0, 0}, { 0, 0}, { 0, 0}}, /* SAF */ 143 { 10000, 1, 10, 6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 18}, {13, 24}, {38, 48}}, 31, {0, 0}, {{7, 32}, {15, 49}, {18, 56}}, {{2, 4}, {2, 6}}, {11, 11}, {4, 4}, { 0, 0}, {12, 12}}, /* 10GE */ 144 { 11000, 1, 10, 6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 18}, {13, 24}, {38, 48}}, 31, {0, 0}, {{7, 32}, {15, 49}, {18, 56}}, {{2, 4}, {2, 6}}, {11, 11}, {4, 4}, { 0, 0}, {12, 12}}, /* HG[11] */ 145 { 20000, 3, 10, 6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 25}, {14, 31}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 58}, {18, 67}}, {{2, 7}, {2, 11}}, {16, 13}, {4, 4}, { 0, 0}, {12, 12}}, /* 20GE */ 146 { 21000, 3, 10, 6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 25}, {14, 31}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 58}, {18, 67}}, {{2, 7}, {2, 11}}, {16, 13}, {4, 4}, { 0, 0}, {12, 12}}, /* HG[21] */ 147 { 25000, 5, 10, 7, {{3, 12}, {11, 20}, {3, 12}}, {{8, 32}, {16, 40}, {29, 50}}, 21, {1, 1}, {{7, 72}, {15, 91}, {18, 100}}, {{3, 7}, {3, 11}}, {20, 18}, {4, 4}, {22, 22}, {26, 26}}, /* 25GE */ 148 { 27000, 5, 10, 7, {{3, 12}, {11, 20}, {3, 12}}, {{8, 32}, {16, 40}, {29, 50}}, 21, {1, 1}, {{7, 72}, {15, 91}, {18, 100}}, {{3, 7}, {3, 11}}, {20, 18}, {4, 4}, {22, 22}, {26, 26}}, /* HG[27] */ 149 { 40000, 7, 12, 4, {{3, 10}, { 7, 14}, {3, 10}}, {{8, 30}, {12, 34}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 29}, {18, 36}}, {{4, 13}, {4, 21}}, {25, 19}, {4, 4}, { 0, 0}, {12, 12}}, /* 40GE */ 150 { 42000, 7, 12, 4, {{3, 10}, { 7, 14}, {3, 10}}, {{8, 30}, {12, 34}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 29}, {18, 36}}, {{4, 13}, {4, 21}}, {25, 19}, {4, 4}, { 0, 0}, {12, 12}}, /* HG[42] */ 151 { 50000, 9, 12, 4, {{3, 12}, { 7, 16}, {3, 12}}, {{8, 40}, {12, 44}, {29, 50}}, 21, {1, 1}, {{7, 13}, {15, 29}, {18, 36}}, {{4, 15}, {4, 21}}, {26, 22}, {6, 6}, { 0, 0}, {18, 18}}, /* 50GE */ 152 { 53000, 9, 12, 4, {{3, 12}, { 7, 16}, {3, 12}}, {{8, 40}, {12, 44}, {29, 50}}, 21, {1, 1}, {{7, 13}, {15, 29}, {18, 36}}, {{4, 15}, {4, 21}}, {26, 22}, {6, 6}, { 0, 0}, {18, 18}}, /* HG[53] */ 153 {100000, 11, 12, 4, {{3, 11}, { 7, 15}, {3, 11}}, {{8, 45}, {11, 49}, {10, 49}}, 3, {1, 1}, {{7, 13}, {15, 29}, {18, 36}}, {{8, 27}, {8, 29}}, {41, 38}, {5, 5}, { 0, 0}, {18, 18}}, /* 100GE */ 154 {106000, 11, 12, 4, {{3, 11}, { 7, 15}, {3, 11}}, {{8, 45}, {11, 49}, {10, 49}}, 3, {1, 1}, {{7, 13}, {15, 29}, {18, 36}}, {{8, 27}, {8, 29}}, {41, 38}, {5, 5}, { 0, 0}, {18, 18}} /* HG[106] */ 155 }; 156 157 /* ASF Control */ 158 static _soc_td3_asf_ctrl_t* 159 _soc_td3_asf_ctrl[SOC_MAX_NUM_DEVICES] = {NULL}; 160 161 /* ASF profile billboard */ 162 static const char *asf_profile_str[3] = 163 {"removed of cut-thru capability", 164 "capable of limited speed range cut-thru", 165 "capable of extended speed range cut-thru"}; 166 167 168 /* 169 * Cut-through class encoding: 170 * 0 - SAF 171 * 1 - 10GE 172 * 2 - HG[11] 173 * 3 - 20GE 174 * 4 - 21[HG} 175 * 5 - 25GE 176 * 6 - HG[27] 177 * 7 - 40GE 178 * 8 - HG[42] 179 * 9 - 50GE 180 * 10 - HG[53] 181 * 11 - 100GE 182 * 12 - HG[106] 183 */ 184 STATIC int 185 _soc_td3_speed_to_ct_class_map(int speed) 186 { 187 int ct_class; 188 189 if (1000 == speed) { /* 1G ports use same setting as 10G ports */ 190 speed = 10000; 191 } 192 193 for (ct_class = 0; ct_class < _SOC_TD3_ASF_CLASS_CNT; ct_class++) { 194 if (_soc_td3_asf_cfg_tbl[ct_class].speed == speed) { 195 return ct_class; 196 } 197 } 198 199 return SOC_E_PARAM; 200 } 201 202 /****************************************************************************** 203 * Name: _soc_td3_port_asf_class_get * 204 * Description: * 205 * Get Cut-through class configured for the specified port * 206 * IN params: * 207 * - Unit * 208 * - Logical Port * 209 * - Port Speed * 210 * OUT params: * 211 * - CT class * 212 * Returns: * 213 * - SOC_E_NONE on success * 214 * - SOC_E_PARAM on invalid parameter * 215 */ 216 STATIC int 217 _soc_td3_port_asf_class_get( 218 int unit, 219 soc_port_t port, 220 OUT int* const ct_class) 221 { 222 egr_ip_cut_thru_class_entry_t entry; 223 224 if (!ct_class) { 225 return SOC_E_PARAM; 226 } 227 228 sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t)); 229 SOC_IF_ERROR_RETURN 230 (READ_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry)); 231 *ct_class = soc_mem_field32_get(unit, EGR_IP_CUT_THRU_CLASSm, &entry, 232 CUT_THRU_CLASSf); 233 234 return SOC_E_NONE; 235 } 236 237 /****************************************************************************** 238 * Name: _soc_td3_port_asf_class_init * 239 * Description: * 240 * Initialize Cut-through class for the specified port * 241 * IN params: * 242 * - Unit * 243 * - Logical Port * 244 * - CT class * 245 * Returns: * 246 * - SOC_E_NONE on success * 247 * - SOC_E_PARAM on invalid parameter * 248 */ 249 STATIC int 250 _soc_td3_port_asf_class_init( 251 int unit, 252 soc_port_t port, 253 int ct_class) 254 { 255 egr_ip_cut_thru_class_entry_t entry; 256 257 sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t)); 258 soc_mem_field32_set(unit, EGR_IP_CUT_THRU_CLASSm, &entry, 259 CUT_THRU_CLASSf, ct_class); 260 SOC_IF_ERROR_RETURN 261 (WRITE_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry)); 262 263 return SOC_E_NONE; 264 } 265 266 /****************************************************************************** 267 * Name: _soc_td3_port_asf_xmit_start_count_get * 268 * Description: * 269 * Query or retrieve the XMIT Start Count for the specified source class * 270 * of the port depending on the magic number passed in xmit_cnt * 271 * IN params: * 272 * - Unit * 273 * - Logical Port * 274 * - Source Port's Class * 275 * - Destination Port's CT Class * 276 * - ASF Mode * 277 * IN/OUT params: * 278 * - xmit_cnt : IN: carries magic number for query / retrieve * 279 * - xmit_cnt : OUT: contains a valid XMIT START COUNT for the * 280 * source port class, on success * 281 * Returns: * 282 * - SOC_E_NONE on success * 283 * - SOC_E_PARAM on invalid parameter * 284 * - SOC_E_INTERNAL on init/soc errors * 285 */ 286 STATIC int 287 _soc_td3_port_asf_xmit_start_count_get( 288 int unit, 289 soc_port_t port, 290 int sc, 291 int dc, 292 soc_td3_asf_mode_e mode, 293 IN_OUT uint8* const xmit_cnt) 294 { 295 soc_info_t *si; 296 egr_xmit_start_count_entry_t entry; 297 int ovs_ratio, port_idx; 298 soc_pbmp_t td3_ports, line_rate_ports, ovs_161_ports; 299 soc_port_t td3_port; 300 int speed; 301 int ct_class; 302 int pipe; 303 soc_mem_t config_mem = INVALIDm; 304 305 if (!(si = &SOC_INFO(unit))) { 306 return SOC_E_INTERNAL; 307 } 308 309 pipe = si->port_pipe[port]; 310 config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe]; 311 312 if (_SOC_TD3_ASF_MODE_CFG_UPDATE == mode) { /* translate to valid mode */ 313 /* reverse map speed class to speed, to surmount speed deficit */ 314 SOC_IF_ERROR_RETURN(_soc_td3_port_asf_class_get(unit, port, &ct_class)); 315 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(ct_class, 0); 316 speed = _SOC_TD3_CT_CLASS_TO_SPEED_MAP(ct_class); 317 SOC_IF_ERROR_RETURN(soc_td3_port_asf_mode_get(unit, port, speed, &mode)); 318 } 319 if (!xmit_cnt || 320 !((mode >= _SOC_TD3_ASF_MODE_SAF) && 321 (mode <= _SOC_TD3_ASF_MODE_FAST_TO_SLOW))) { 322 return SOC_E_PARAM; 323 } 324 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(sc, 0); 325 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(dc, 0); 326 327 if (_SOC_TD3_ASF_RETRV == *xmit_cnt) { 328 *xmit_cnt = 0; 329 port_idx = ((port % _TD3_TDM_DEV_PORTS_PER_PIPE) * 16) + sc; 330 331 sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t)); 332 SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL, 333 port_idx, &entry)); 334 *xmit_cnt = soc_mem_field32_get(unit, config_mem, 335 &entry, THRESHOLDf); 336 } else if (_SOC_TD3_ASF_QUERY == *xmit_cnt) { 337 *xmit_cnt = 0; 338 SOC_PBMP_CLEAR(td3_ports); 339 SOC_PBMP_ASSIGN(td3_ports, PBMP_E_ALL(unit)); 340 SOC_PBMP_OR(td3_ports, PBMP_HG_ALL(unit)); 341 SOC_PBMP_REMOVE(td3_ports, PBMP_MANAGEMENT(unit)); 342 SOC_PBMP_CLEAR(line_rate_ports); 343 SOC_PBMP_CLEAR(ovs_161_ports); 344 345 PBMP_ITER(td3_ports, td3_port) { 346 if (SOC_PBMP_MEMBER(si->oversub_pbm, td3_port)) { 347 SOC_IF_ERROR_RETURN( 348 soc_td3_port_oversub_ratio_get(unit, td3_port, &ovs_ratio)); 349 if (ovs_ratio < 1620) { /* oversub ratio <= 1.61 */ 350 SOC_PBMP_PORT_ADD(ovs_161_ports, td3_port); 351 } 352 } else { /* Line-rate */ 353 SOC_PBMP_PORT_ADD(line_rate_ports, td3_port); 354 } 355 } 356 357 /* if sc < dc, use SAF setting; else, use CT setting */ 358 if (SOC_PBMP_EQ(td3_ports, line_rate_ports)) { 359 *xmit_cnt = (sc < dc) ? 360 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.line_rate.saf : 361 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.line_rate.ct; 362 } else if (SOC_PBMP_EQ(td3_ports, ovs_161_ports)) { 363 *xmit_cnt = (sc < dc) ? 364 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_161.saf : 365 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_161.ct; 366 } else { 367 *xmit_cnt = (sc < dc) ? 368 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_2_1.saf : 369 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_2_1.ct; 370 } 371 372 } 373 374 return SOC_E_NONE; 375 } 376 377 /****************************************************************************** 378 * Name: _soc_td3_port_asf_mmu_prebuf_get * 379 * Description: * 380 * Query or retrieve MMU Prebuffer (Min Source Port XMIT Count) for the * 381 * specified port depending on the magic number passed in mmu_prebuf * 382 * IN params: * 383 * - Unit * 384 * - Logical Port * 385 * - Port Speed * 386 * IN/OUT params: * 387 * - mmu_prebuf : IN: carries magic number for query / retrieve * 388 * - mmu_prebuf : OUT: contains a valid Min Source Port XMIT Count on * 389 * success * 390 * Returns: * 391 * - SOC_E_NONE on success * 392 * - SOC_E_PARAM on invalid parameter * 393 * - SOC_E_INTERNAL on init/soc errors * 394 */ 395 STATIC int 396 _soc_td3_port_asf_mmu_prebuf_get( 397 int unit, 398 soc_port_t port, 399 int port_speed, 400 IN_OUT uint8* const mmu_prebuf) 401 { 402 uint32 rval; 403 int speed_encoding; 404 405 _SOC_TD3_ASF_PORT_VALIDATE(unit, port); 406 if (!mmu_prebuf) { 407 return SOC_E_PARAM; 408 } 409 410 if (_SOC_TD3_ASF_RETRV == *mmu_prebuf) { 411 *mmu_prebuf = 0; 412 413 if (!_soc_td3_asf_ctrl[unit]->init) { 414 return SOC_E_INTERNAL; 415 } 416 417 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 418 *mmu_prebuf = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 419 MIN_SRC_PORT_XMIT_CNTf); 420 } else if (_SOC_TD3_ASF_QUERY == *mmu_prebuf) { 421 *mmu_prebuf = 0; 422 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 423 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 424 425 *mmu_prebuf = 426 _soc_td3_asf_cfg_tbl[speed_encoding].mmu_prebuffer; 427 } 428 429 return SOC_E_NONE; 430 } 431 432 /****************************************************************************** 433 * Name: _soc_td3_port_asf_fifo_threshold_get * 434 * Description: * 435 * Query or retrieve FIFO Threshold for the specified port depending on * 436 * the magic number passed in fifo_threshold * 437 * IN params: * 438 * - Unit * 439 * - Logical Port * 440 * - Port Speed * 441 * - ASF Mode * 442 * IN/OUT params: * 443 * - fifo_threshold : IN: carries magic number for query / retrieve * 444 * - fifo_threshold : OUT: contains a valid FIFO Threshold on success * 445 * Returns: * 446 * - SOC_E_NONE on success * 447 * - SOC_E_PARAM on invalid parameter * 448 * - SOC_E_INTERNAL on init/soc errors * 449 */ 450 STATIC int 451 _soc_td3_port_asf_fifo_threshold_get( 452 int unit, 453 soc_port_t port, 454 int port_speed, 455 soc_td3_asf_mode_e mode, 456 IN_OUT uint8* const fifo_threshold) 457 { 458 uint32 rval; 459 int speed_encoding; 460 uint8 oversub; 461 462 _SOC_TD3_ASF_PORT_VALIDATE(unit, port); 463 if (!fifo_threshold) { 464 return SOC_E_PARAM; 465 } 466 467 if (_SOC_TD3_ASF_RETRV == *fifo_threshold) { 468 *fifo_threshold = 0; 469 470 if (!_soc_td3_asf_ctrl[unit]->init) { 471 return SOC_E_INTERNAL; 472 } 473 474 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 475 *fifo_threshold = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 476 FIFO_THRESHOLDf); 477 } else if (_SOC_TD3_ASF_QUERY == *fifo_threshold) { 478 *fifo_threshold = 0; 479 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 480 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 481 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 482 483 switch(mode) { 484 case _SOC_TD3_ASF_MODE_SAME_SPEED: 485 *fifo_threshold = (oversub ? 486 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.ss.oversub : 487 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.ss.line_rate); 488 break; 489 490 case _SOC_TD3_ASF_MODE_SLOW_TO_FAST: 491 *fifo_threshold = (oversub ? 492 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.sf.oversub : 493 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.sf.line_rate); 494 break; 495 496 case _SOC_TD3_ASF_MODE_FAST_TO_SLOW: 497 *fifo_threshold = (oversub ? 498 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.fs.oversub : 499 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.fs.line_rate); 500 break; 501 502 default: 503 return SOC_E_PARAM; 504 } 505 } 506 507 return SOC_E_NONE; 508 } 509 510 /****************************************************************************** 511 * Name: _soc_td3_port_asf_fifo_depth_get * 512 * Description: * 513 * Query or retrieve FIFO Depth for the specified port depending on the * 514 * magic number passed in buf_sz * 515 * IN params: * 516 * - Unit * 517 * - Logical Port * 518 * - Port Speed * 519 * - ASF Mode * 520 * IN/OUT params: * 521 * - fifo_depth : IN: carries magic number for query/retrieve * 522 * - fifo_depth : OUT: contains a valid FIFO Depth on success * 523 * Returns: * 524 * - SOC_E_NONE on success * 525 * - SOC_E_PARAM on invalid parameter * 526 * - SOC_E_INTERNAL on init/soc errors * 527 */ 528 STATIC int 529 _soc_td3_port_asf_fifo_depth_get( 530 int unit, 531 soc_port_t port, 532 int port_speed, 533 soc_td3_asf_mode_e mode, 534 IN_OUT uint8* const fifo_depth) 535 { 536 uint32 rval; 537 int speed_encoding; 538 uint8 oversub; 539 540 _SOC_TD3_ASF_PORT_VALIDATE(unit, port); 541 if (!fifo_depth) { 542 return SOC_E_PARAM; 543 } 544 545 if (_SOC_TD3_ASF_RETRV == *fifo_depth) { 546 if (!_soc_td3_asf_ctrl[unit]->init) { 547 return SOC_E_INTERNAL; 548 } 549 550 *fifo_depth = 0; 551 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 552 *fifo_depth = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 553 FIFO_DEPTHf); 554 } else if (_SOC_TD3_ASF_QUERY == *fifo_depth) { 555 *fifo_depth = 0; 556 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 557 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 558 oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0); 559 560 switch(mode) { 561 case _SOC_TD3_ASF_MODE_SAME_SPEED: 562 *fifo_depth = (oversub ? 563 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.ss.oversub : 564 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.ss.line_rate); 565 break; 566 567 case _SOC_TD3_ASF_MODE_SLOW_TO_FAST: 568 *fifo_depth = (oversub ? 569 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.sf.oversub : 570 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.sf.line_rate); 571 break; 572 573 case _SOC_TD3_ASF_MODE_FAST_TO_SLOW: 574 *fifo_depth = (oversub ? 575 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.fs.oversub : 576 _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.fs.line_rate); 577 break; 578 579 default: 580 return SOC_E_PARAM; 581 } 582 } 583 584 return SOC_E_NONE; 585 } 586 587 /****************************************************************************** 588 * Name: _soc_td3_port_asf_speed_limits_get * 589 * Description: * 590 * Query or retrieve min & max source port speeds for the specified port * 591 * depending on the magic number passed in min_sp & * 592 * max_sp * 593 * IN params: * 594 * - Unit * 595 * - Logical Port * 596 * - Port Speed * 597 * - ASF Mode * 598 * IN/OUT params: * 599 * - min_sp : IN: carries magic number for query / retrieve * 600 * - min_sp : OUT: contains a valid min source port speed * 601 * on success * 602 * - max_sp : IN: carries magic number for query / retrieve * 603 * - max_sp : OUT: contains a valid max source port speed * 604 * on success * 605 * Returns: * 606 * - SOC_E_NONE on success * 607 * - SOC_E_PARAM on invalid parameter * 608 * - SOC_E_INTERNAL on init/soc errors * 609 */ 610 STATIC int 611 _soc_td3_port_asf_speed_limits_get( 612 int unit, 613 soc_port_t port, 614 int port_speed, 615 soc_td3_asf_mode_e mode, 616 IN_OUT uint8* const min_sp, 617 IN_OUT uint8* const max_sp) 618 { 619 uint32 rval; 620 int speed_encoding; 621 622 _SOC_TD3_ASF_PORT_VALIDATE(unit, port); 623 if (!min_sp || !max_sp) { 624 return SOC_E_PARAM; 625 } 626 627 if ((_SOC_TD3_ASF_RETRV == *min_sp) && 628 (_SOC_TD3_ASF_RETRV == *max_sp)) { 629 *min_sp = *max_sp = 0; 630 if (!_soc_td3_asf_ctrl[unit]->init) { 631 return SOC_E_INTERNAL; 632 } 633 634 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 635 636 /* MIN_SRC_PORT_SPEED */ 637 *min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 638 MIN_SRC_PORT_SPEEDf); 639 /* MAX_SRC_PORT_SPEED */ 640 *max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, 641 MAX_SRC_PORT_SPEEDf); 642 } else if ((_SOC_TD3_ASF_QUERY == *min_sp) && 643 (_SOC_TD3_ASF_QUERY == *max_sp)) { 644 *min_sp = *max_sp = 0; 645 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 646 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 647 648 switch(mode) { 649 case _SOC_TD3_ASF_MODE_SAF: 650 return SOC_E_NONE; 651 652 case _SOC_TD3_ASF_MODE_SAME_SPEED: 653 *min_sp = *max_sp = speed_encoding; 654 break; 655 656 case _SOC_TD3_ASF_MODE_SLOW_TO_FAST: 657 *min_sp = _soc_td3_asf_cfg_tbl[speed_encoding].min_sp; 658 *max_sp = speed_encoding; 659 break; 660 661 case _SOC_TD3_ASF_MODE_FAST_TO_SLOW: 662 if (_SOC_TD3_ASF_MEM_PROFILE_SIMILAR == 663 _soc_td3_asf_ctrl[unit]->asf_mem_profile) { 664 if (speed_encoding % 2) { /* IEEE */ 665 /* HG counterpart */ 666 *max_sp = speed_encoding + 1; 667 } else { /* HG */ 668 *max_sp = speed_encoding; 669 } 670 } else if (_SOC_TD3_ASF_MEM_PROFILE_EXTREME == 671 _soc_td3_asf_ctrl[unit]->asf_mem_profile) { 672 *max_sp = _soc_td3_asf_cfg_tbl[speed_encoding].max_sp; 673 } 674 *min_sp = speed_encoding; 675 break; 676 677 default: 678 return SOC_E_PARAM; 679 } 680 } 681 682 return SOC_E_NONE; 683 } 684 685 /****************************************************************************** 686 * Name: _soc_td3_asf_obm_ca_fifo_thresh_set * 687 * Description: * 688 * Configure Cell Assembly CT FIFO threshold for all OBM and Pipe * 689 * instances. * 690 * IN params: * 691 * - Unit * 692 * - Logical Port * 693 * - Cell Assembly CT Threshold * 694 * Returns: * 695 * - SOC_E_NONE on success * 696 * - SOC_E_* on internal errors * 697 */ 698 STATIC int 699 _soc_td3_asf_obm_ca_fifo_thresh_set( 700 int unit, 701 soc_port_t port, 702 uint8 ca_thresh) 703 { 704 int obm, pipe; 705 int lane; 706 uint32 rval; 707 soc_info_t *si = &SOC_INFO(unit); 708 uint32 thresh_field[4] = { THRESHOLD0f, THRESHOLD1f, 709 THRESHOLD2f, THRESHOLD3f }; 710 uint32 port_ct_sel_field[4] = { PORT0_CT_SELf, PORT1_CT_SELf, 711 PORT2_CT_SELf, PORT3_CT_SELf }; 712 uint32 idb_obm_ca_ct_ctrl_reg[][2] = { 713 {IDB_OBM0_CA_CT_CONTROL_PIPE0r, IDB_OBM0_CA_CT_CONTROL_PIPE1r}, 714 {IDB_OBM1_CA_CT_CONTROL_PIPE0r, IDB_OBM1_CA_CT_CONTROL_PIPE1r}, 715 {IDB_OBM2_CA_CT_CONTROL_PIPE0r, IDB_OBM2_CA_CT_CONTROL_PIPE1r}, 716 {IDB_OBM3_CA_CT_CONTROL_PIPE0r, IDB_OBM3_CA_CT_CONTROL_PIPE1r}, 717 {IDB_OBM4_CA_CT_CONTROL_PIPE0r, IDB_OBM4_CA_CT_CONTROL_PIPE1r}, 718 {IDB_OBM5_CA_CT_CONTROL_PIPE0r, IDB_OBM5_CA_CT_CONTROL_PIPE1r}, 719 {IDB_OBM6_CA_CT_CONTROL_PIPE0r, IDB_OBM6_CA_CT_CONTROL_PIPE1r}, 720 {IDB_OBM7_CA_CT_CONTROL_PIPE0r, IDB_OBM7_CA_CT_CONTROL_PIPE1r}, 721 {IDB_OBM8_CA_CT_CONTROL_PIPE0r, IDB_OBM8_CA_CT_CONTROL_PIPE1r}, 722 {IDB_OBM9_CA_CT_CONTROL_PIPE0r, IDB_OBM9_CA_CT_CONTROL_PIPE1r}, 723 {IDB_OBM10_CA_CT_CONTROL_PIPE0r, IDB_OBM10_CA_CT_CONTROL_PIPE1r}, 724 {IDB_OBM11_CA_CT_CONTROL_PIPE0r, IDB_OBM11_CA_CT_CONTROL_PIPE1r}, 725 {IDB_OBM12_CA_CT_CONTROL_PIPE0r, IDB_OBM12_CA_CT_CONTROL_PIPE1r}, 726 {IDB_OBM13_CA_CT_CONTROL_PIPE0r, IDB_OBM13_CA_CT_CONTROL_PIPE1r}, 727 {IDB_OBM14_CA_CT_CONTROL_PIPE0r, IDB_OBM14_CA_CT_CONTROL_PIPE1r}, 728 {IDB_OBM15_CA_CT_CONTROL_PIPE0r, IDB_OBM15_CA_CT_CONTROL_PIPE1r}, 729 }; 730 731 /* Get lane, pipe & obm */ 732 SOC_IF_ERROR_RETURN 733 (soc_trident3_port_obm_info_get(unit, port, &obm, &lane)); 734 pipe = si->port_pipe[port]; 735 736 SOC_IF_ERROR_RETURN( 737 soc_reg32_get(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], 738 REG_PORT_ANY, 0, &rval)); 739 740 soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval, 741 port_ct_sel_field[lane], lane); 742 soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval, 743 thresh_field[lane], ca_thresh); 744 745 SOC_IF_ERROR_RETURN( 746 soc_reg32_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], 747 REG_PORT_ANY, 0, rval)); 748 749 return SOC_E_NONE; 750 } 751 752 /****************************************************************************** 753 * Name: _soc_td3_asf_obm_bubble_mop_set * 754 * Description: * 755 * Configure Bubble MOP for all OBM and Pipe Instances * 756 * IN params: * 757 * - Unit * 758 * - Logical Port * 759 * - Bubble MOP Flag * 760 * Returns: * 761 * - SOC_E_NONE on success * 762 * - SOC_E_* on internal errors * 763 */ 764 STATIC int 765 _soc_td3_asf_obm_bubble_mop_set( 766 int unit, 767 soc_port_t port, 768 uint8 bubble_mop_disable) 769 { 770 int obm, pipe; 771 int lane; 772 uint32 rval; 773 soc_info_t *si = &SOC_INFO(unit); 774 uint32 port_field[4] = { 775 PORT0_BUBBLE_MOP_DISABLEf, PORT1_BUBBLE_MOP_DISABLEf, 776 PORT2_BUBBLE_MOP_DISABLEf, PORT3_BUBBLE_MOP_DISABLEf }; 777 uint32 idb_obm_ctrl_reg[][2] = { 778 {IDB_OBM0_CONTROL_PIPE0r, IDB_OBM0_CONTROL_PIPE1r}, 779 {IDB_OBM1_CONTROL_PIPE0r, IDB_OBM1_CONTROL_PIPE1r}, 780 {IDB_OBM2_CONTROL_PIPE0r, IDB_OBM2_CONTROL_PIPE1r}, 781 {IDB_OBM3_CONTROL_PIPE0r, IDB_OBM3_CONTROL_PIPE1r}, 782 {IDB_OBM4_CONTROL_PIPE0r, IDB_OBM4_CONTROL_PIPE1r}, 783 {IDB_OBM5_CONTROL_PIPE0r, IDB_OBM5_CONTROL_PIPE1r}, 784 {IDB_OBM6_CONTROL_PIPE0r, IDB_OBM6_CONTROL_PIPE1r}, 785 {IDB_OBM7_CONTROL_PIPE0r, IDB_OBM7_CONTROL_PIPE1r}, 786 {IDB_OBM8_CONTROL_PIPE0r, IDB_OBM8_CONTROL_PIPE1r}, 787 {IDB_OBM9_CONTROL_PIPE0r, IDB_OBM9_CONTROL_PIPE1r}, 788 {IDB_OBM10_CONTROL_PIPE0r, IDB_OBM10_CONTROL_PIPE1r}, 789 {IDB_OBM11_CONTROL_PIPE0r, IDB_OBM11_CONTROL_PIPE1r}, 790 {IDB_OBM12_CONTROL_PIPE0r, IDB_OBM12_CONTROL_PIPE1r}, 791 {IDB_OBM13_CONTROL_PIPE0r, IDB_OBM13_CONTROL_PIPE1r}, 792 {IDB_OBM14_CONTROL_PIPE0r, IDB_OBM14_CONTROL_PIPE1r}, 793 {IDB_OBM15_CONTROL_PIPE0r, IDB_OBM15_CONTROL_PIPE1r}, 794 }; 795 796 /* Get lane, pipe & obm */ 797 SOC_IF_ERROR_RETURN 798 (soc_trident3_port_obm_info_get(unit, port, &obm, &lane)); 799 pipe = si->port_pipe[port]; 800 801 /* BubbleMOP */ 802 SOC_IF_ERROR_RETURN( 803 soc_reg32_get(unit, idb_obm_ctrl_reg[obm][pipe], 804 REG_PORT_ANY, 0, &rval)); 805 806 soc_reg_field_set(unit, idb_obm_ctrl_reg[obm][pipe], &rval, 807 port_field[lane], bubble_mop_disable); 808 809 SOC_IF_ERROR_RETURN( 810 soc_reg32_set(unit, idb_obm_ctrl_reg[obm][pipe], REG_PORT_ANY, 811 0, rval)); 812 813 return SOC_E_NONE; 814 } 815 816 /****************************************************************************** 817 * Name: _soc_td3_asf_obm_ct_thresh_ok_set * 818 * Description: * 819 * Configure IDB OBM CT FIFO threshold OK for all OBM and Pipe * 820 * instances. * 821 * IN params: * 822 * - Unit * 823 * - Logical Port * 824 * - CT allowed if usage is less than or eq threshold * 825 * Returns: * 826 * - SOC_E_NONE on success * 827 * - SOC_E_* on internal errors * 828 */ 829 STATIC int 830 _soc_td3_asf_obm_ct_thresh_ok_set( 831 int unit, 832 soc_port_t port, 833 uint32 ct_ok_thresh) 834 { 835 int obm, pipe; 836 int lane; 837 uint64 rval64; 838 soc_info_t *si = &SOC_INFO(unit); 839 uint32 idb_obm_ct_thresh_reg[][2] = { 840 {IDB_OBM0_CT_THRESHOLD_PIPE0r, IDB_OBM0_CT_THRESHOLD_PIPE1r}, 841 {IDB_OBM1_CT_THRESHOLD_PIPE0r, IDB_OBM1_CT_THRESHOLD_PIPE1r}, 842 {IDB_OBM2_CT_THRESHOLD_PIPE0r, IDB_OBM2_CT_THRESHOLD_PIPE1r}, 843 {IDB_OBM3_CT_THRESHOLD_PIPE0r, IDB_OBM3_CT_THRESHOLD_PIPE1r}, 844 {IDB_OBM4_CT_THRESHOLD_PIPE0r, IDB_OBM4_CT_THRESHOLD_PIPE1r}, 845 {IDB_OBM5_CT_THRESHOLD_PIPE0r, IDB_OBM5_CT_THRESHOLD_PIPE1r}, 846 {IDB_OBM6_CT_THRESHOLD_PIPE0r, IDB_OBM6_CT_THRESHOLD_PIPE1r}, 847 {IDB_OBM7_CT_THRESHOLD_PIPE0r, IDB_OBM7_CT_THRESHOLD_PIPE1r}, 848 {IDB_OBM8_CT_THRESHOLD_PIPE0r, IDB_OBM8_CT_THRESHOLD_PIPE1r}, 849 {IDB_OBM9_CT_THRESHOLD_PIPE0r, IDB_OBM9_CT_THRESHOLD_PIPE1r}, 850 {IDB_OBM10_CT_THRESHOLD_PIPE0r, IDB_OBM10_CT_THRESHOLD_PIPE1r}, 851 {IDB_OBM11_CT_THRESHOLD_PIPE0r, IDB_OBM11_CT_THRESHOLD_PIPE1r}, 852 {IDB_OBM12_CT_THRESHOLD_PIPE0r, IDB_OBM12_CT_THRESHOLD_PIPE1r}, 853 {IDB_OBM13_CT_THRESHOLD_PIPE0r, IDB_OBM13_CT_THRESHOLD_PIPE1r}, 854 {IDB_OBM14_CT_THRESHOLD_PIPE0r, IDB_OBM14_CT_THRESHOLD_PIPE1r}, 855 {IDB_OBM15_CT_THRESHOLD_PIPE0r, IDB_OBM15_CT_THRESHOLD_PIPE1r}, 856 }; 857 858 /* Get lane, pipe & obm */ 859 SOC_IF_ERROR_RETURN 860 (soc_trident3_port_obm_info_get(unit, port, &obm, &lane)); 861 pipe = si->port_pipe[port]; 862 863 SOC_IF_ERROR_RETURN( 864 soc_reg64_get(unit, idb_obm_ct_thresh_reg[obm][pipe], 865 REG_PORT_ANY, lane, &rval64)); 866 867 soc_reg64_field32_set(unit, idb_obm_ct_thresh_reg[obm][pipe], &rval64, 868 CUT_THROUGH_OKf, ct_ok_thresh); 869 870 SOC_IF_ERROR_RETURN( 871 soc_reg64_set(unit, idb_obm_ct_thresh_reg[obm][pipe], 872 REG_PORT_ANY, lane, rval64)); 873 874 return SOC_E_NONE; 875 } 876 877 /****************************************************************************** 878 * Name: _soc_td3_asf_force_saf_config_set * 879 * Description: * 880 * Configure IDB_OBMx_FORCE_SAF_CONFIG register for all OBM and Pipe * 881 * instances. * 882 * IN params: * 883 * - Unit * 884 * - Logical Port * 885 * - Port speed * 886 * - ASF mode * 887 * Returns: * 888 * - SOC_E_NONE on success * 889 * - SOC_E_* on internal errors * 890 */ 891 STATIC int 892 _soc_td3_asf_force_saf_config_set( 893 int unit, 894 soc_port_t port, 895 int port_speed, 896 soc_td3_asf_mode_e mode) 897 { 898 int obm, pipe; 899 int lane; 900 int ct_class; 901 uint32 rval; 902 uint32 field_a; 903 uint32 field_b; 904 uint32 field_c; 905 soc_info_t *si = &SOC_INFO(unit); 906 uint32 idb_obm_force_saf_config_reg[][2] = { 907 {IDB_OBM0_DBG_A_PIPE0r, IDB_OBM0_DBG_A_PIPE1r}, 908 {IDB_OBM1_DBG_A_PIPE0r, IDB_OBM1_DBG_A_PIPE1r}, 909 {IDB_OBM2_DBG_A_PIPE0r, IDB_OBM2_DBG_A_PIPE1r}, 910 {IDB_OBM3_DBG_A_PIPE0r, IDB_OBM3_DBG_A_PIPE1r}, 911 {IDB_OBM4_DBG_A_PIPE0r, IDB_OBM4_DBG_A_PIPE1r}, 912 {IDB_OBM5_DBG_A_PIPE0r, IDB_OBM5_DBG_A_PIPE1r}, 913 {IDB_OBM6_DBG_A_PIPE0r, IDB_OBM6_DBG_A_PIPE1r}, 914 {IDB_OBM7_DBG_A_PIPE0r, IDB_OBM7_DBG_A_PIPE1r}, 915 {IDB_OBM8_DBG_A_PIPE0r, IDB_OBM8_DBG_A_PIPE1r}, 916 {IDB_OBM9_DBG_A_PIPE0r, IDB_OBM9_DBG_A_PIPE1r}, 917 {IDB_OBM10_DBG_A_PIPE0r, IDB_OBM10_DBG_A_PIPE1r}, 918 {IDB_OBM11_DBG_A_PIPE0r, IDB_OBM11_DBG_A_PIPE1r}, 919 {IDB_OBM12_DBG_A_PIPE0r, IDB_OBM12_DBG_A_PIPE1r}, 920 {IDB_OBM13_DBG_A_PIPE0r, IDB_OBM13_DBG_A_PIPE1r}, 921 {IDB_OBM14_DBG_A_PIPE0r, IDB_OBM14_DBG_A_PIPE1r}, 922 {IDB_OBM15_DBG_A_PIPE0r, IDB_OBM15_DBG_A_PIPE1r}, 923 }; 924 925 field_a = 1; 926 field_b = 1; 927 928 ct_class = _soc_td3_speed_to_ct_class_map(port_speed); 929 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(ct_class, 0); 930 field_c = (mode == _SOC_TD3_ASF_MODE_SAF) ? 931 _soc_td3_asf_cfg_tbl[ct_class].unsat_thresh.saf : 932 _soc_td3_asf_cfg_tbl[ct_class].unsat_thresh.ct; 933 934 /* Get lane, pipe & obm */ 935 SOC_IF_ERROR_RETURN 936 (soc_trident3_port_obm_info_get(unit, port, &obm, &lane)); 937 pipe = si->port_pipe[port]; 938 939 SOC_IF_ERROR_RETURN( 940 soc_reg32_get(unit, idb_obm_force_saf_config_reg[obm][pipe], 941 REG_PORT_ANY, lane, &rval)); 942 943 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 944 FIELD_Af, field_a); 945 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 946 FIELD_Bf, field_b); 947 soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval, 948 FIELD_Cf, field_c); 949 950 SOC_IF_ERROR_RETURN( 951 soc_reg32_set(unit, idb_obm_force_saf_config_reg[obm][pipe], 952 REG_PORT_ANY, lane, rval)); 953 954 return SOC_E_NONE; 955 } 956 957 int 958 soc_td3_port_asf_valid( 959 int unit, 960 soc_port_t port) 961 { 962 if (IS_CPU_PORT(((unit)), (port)) || IS_LB_PORT(((unit)), (port)) || \ 963 SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) { 964 return FALSE; 965 } else { 966 return TRUE; 967 } 968 } 969 970 /************************************* 971 * Init Start Routine * 972 * - Allocates ASF Ctrl structure * 973 * for the given unit * 974 */ 975 int 976 soc_td3_asf_init_start(int unit) 977 { 978 if (!(_soc_td3_asf_ctrl[unit] = 979 sal_alloc(sizeof(_soc_td3_asf_ctrl_t), "TD3 ASF Ctrl Area"))) { 980 return SOC_E_MEMORY; 981 } 982 sal_memset(_soc_td3_asf_ctrl[unit], 0, sizeof(_soc_td3_asf_ctrl_t)); 983 984 /* ASF_MEM_PROFILE */ 985 _soc_td3_asf_ctrl[unit]->asf_mem_profile = 986 soc_property_get(unit, spn_ASF_MEM_PROFILE, 987 _SOC_TD3_ASF_MEM_PROFILE_SIMILAR); 988 if (!((_soc_td3_asf_ctrl[unit]->asf_mem_profile >= 0) && 989 (_soc_td3_asf_ctrl[unit]->asf_mem_profile < 3))) { 990 _soc_td3_asf_ctrl[unit]->asf_mem_profile = 2; 991 } 992 993 return SOC_E_NONE; 994 } 995 996 /************************ 997 * Init Complete Marker * 998 */ 999 int 1000 soc_td3_asf_init_done(int unit) 1001 { 1002 if (_soc_td3_asf_ctrl[unit]) { 1003 _soc_td3_asf_ctrl[unit]->init = 1; 1004 LOG_CLI((BSL_META_U(unit, "*** unit %d: ports %s\n"), unit, 1005 asf_profile_str[_soc_td3_asf_ctrl[unit]->asf_mem_profile])); 1006 return SOC_E_NONE; 1007 } else { 1008 return SOC_E_INTERNAL; 1009 } 1010 } 1011 1012 /****************************************************************************** 1013 * Name: soc_td3_port_asf_init * 1014 * Description: * 1015 * Initialize ASF primitives for the specified port * 1016 * IN params: * 1017 * - Unit * 1018 * - Logical Port * 1019 * - Port Speed * 1020 * - ASF Mode * 1021 * Returns: * 1022 * - SOC_E_NONE on success * 1023 * - SOC_E_PARAM on invalid parameter * 1024 * - SOC_E_INIT on init/soc errors * 1025 */ 1026 int 1027 soc_td3_port_asf_init( 1028 int unit, 1029 soc_port_t port, 1030 int speed, 1031 soc_td3_asf_mode_e mode) 1032 { 1033 SOC_IF_ERROR_RETURN(soc_td3_port_asf_mode_set(unit, port, speed, mode)); 1034 1035 return SOC_E_NONE; 1036 } 1037 1038 /************************ 1039 * Init Start Routine * 1040 */ 1041 int 1042 soc_td3_asf_deinit(int unit) 1043 { 1044 if (_soc_td3_asf_ctrl[unit]) { 1045 sal_free(_soc_td3_asf_ctrl[unit]); 1046 _soc_td3_asf_ctrl[unit] = NULL; 1047 } 1048 1049 return SOC_E_NONE; 1050 } 1051 1052 /****************************************************************************** 1053 * Name: _soc_td3_port_asf_xmit_start_count_set * 1054 * Description: * 1055 * Initialize XMIT START COUNT memory for all the source class for the * 1056 * specified port * 1057 * Support CPU and LB ports for init setting. * 1058 * IN params: * 1059 * - Unit * 1060 * - Logical Port * 1061 * - Port Speed * 1062 * - ASF Mode * 1063 * - Extra cells (if any, to be added to xmit start count) * 1064 * Returns: * 1065 * - SOC_E_NONE on success * 1066 * - SOC_E_PARAM on invalid parameter * 1067 */ 1068 int 1069 soc_td3_port_asf_xmit_start_count_set( 1070 int unit, 1071 soc_port_t port, 1072 int port_speed, 1073 soc_td3_asf_mode_e mode, 1074 uint8 extra_cells) 1075 { 1076 egr_xmit_start_count_entry_t entry; 1077 soc_info_t *si = &SOC_INFO(unit); 1078 uint8 xmit_cnt = 0; 1079 int rv, src_class, dst_class = 0, port_idx; 1080 int pipe; 1081 soc_mem_t config_mem = INVALIDm; 1082 1083 if (!((mode >= _SOC_TD3_ASF_MODE_SAF) && 1084 (mode <= _SOC_TD3_ASF_MODE_CFG_UPDATE))) { 1085 return SOC_E_PARAM; 1086 } 1087 1088 if (IS_CPU_PORT(unit, port)) { 1089 port_speed = 20000; 1090 } 1091 if (IS_LB_PORT(unit, port)) { 1092 port_speed = 100000; 1093 } 1094 1095 if (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode) { 1096 if (SOC_E_PARAM == (dst_class = _soc_td3_speed_to_ct_class_map(port_speed))) { 1097 /* port on a speed unsupported by CT - will resort to SAF */ 1098 dst_class = 0; 1099 } 1100 } 1101 1102 sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t)); 1103 1104 pipe = si->port_pipe[port]; 1105 config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe]; 1106 1107 for (src_class = 0; src_class < _SOC_TD3_ASF_CLASS_CNT; src_class++) { 1108 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 1109 xmit_cnt = _soc_td3_asf_cfg_tbl[dst_class].edb_prebuffer.line_rate.saf; 1110 } else { 1111 if (_SOC_TD3_ASF_MODE_CFG_UPDATE == mode) { 1112 xmit_cnt = _SOC_TD3_ASF_RETRV; 1113 } else { 1114 xmit_cnt = _SOC_TD3_ASF_QUERY; 1115 } 1116 1117 rv = _soc_td3_port_asf_xmit_start_count_get(unit, port, src_class, 1118 dst_class, mode, &xmit_cnt); 1119 1120 if (SOC_FAILURE(rv)) { 1121 if (SOC_E_UNAVAIL == rv) { 1122 xmit_cnt = _soc_td3_asf_cfg_tbl[dst_class].edb_prebuffer.oversub_2_1.saf; 1123 } else { 1124 return rv; 1125 } 1126 } 1127 1128 xmit_cnt += extra_cells; 1129 } 1130 1131 port_idx = ((port % _TD3_TDM_DEV_PORTS_PER_PIPE) * 16) + src_class; 1132 1133 soc_mem_field32_set(unit, config_mem, &entry, 1134 THRESHOLDf, xmit_cnt); 1135 SOC_IF_ERROR_RETURN(soc_mem_write(unit, config_mem, MEM_BLOCK_ALL, 1136 port_idx, &entry)); 1137 } 1138 1139 return SOC_E_NONE; 1140 } 1141 1142 /****************************************************************************** 1143 * Name: soc_td3_port_asf_mode_get * 1144 * Description: * 1145 * Retrieve the ASF/SAF mode configured on the specified port * 1146 * IN params: * 1147 * - Unit * 1148 * - Logical Port * 1149 * - Port Speed * 1150 * OUT params: * 1151 * - mode : OUT: contains the ASF/SAF mode confiugred on the specified * 1152 * port on success * 1153 * Returns: * 1154 * - SOC_E_NONE on success * 1155 * - SOC_E_PARAM on invalid parameter * 1156 * - SOC_E_INTERNAL on init/soc errors * 1157 */ 1158 int 1159 soc_td3_port_asf_mode_get( 1160 int unit, 1161 soc_port_t port, 1162 int port_speed, 1163 OUT soc_td3_asf_mode_e* const mode) 1164 { 1165 uint32 rval; 1166 int speed_encoding; 1167 uint8 max_sp, min_sp, enable; 1168 1169 if (!mode) { 1170 return SOC_E_INTERNAL; 1171 } 1172 1173 if (soc_td3_port_asf_valid(unit, port)) { 1174 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1175 enable = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, ENABLEf); 1176 if (!enable) { 1177 *mode = _SOC_TD3_ASF_MODE_SAF; 1178 return SOC_E_NONE; 1179 } 1180 } else { 1181 *mode = _SOC_TD3_ASF_MODE_SAF; 1182 return SOC_E_NONE; 1183 } 1184 1185 if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->init) { 1186 return SOC_E_INTERNAL; 1187 } 1188 1189 max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MAX_SRC_PORT_SPEEDf); 1190 min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MIN_SRC_PORT_SPEEDf); 1191 1192 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 1193 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1); 1194 1195 if (max_sp && min_sp) { 1196 if (max_sp == min_sp) { 1197 if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) { 1198 *mode = _SOC_TD3_ASF_MODE_SLOW_TO_FAST; 1199 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) { 1200 *mode = _SOC_TD3_ASF_MODE_FAST_TO_SLOW; 1201 } else { 1202 *mode = _SOC_TD3_ASF_MODE_SAME_SPEED; 1203 } 1204 } else if (max_sp == speed_encoding) { 1205 *mode = _SOC_TD3_ASF_MODE_SLOW_TO_FAST; 1206 } else if (min_sp == speed_encoding) { 1207 *mode = _SOC_TD3_ASF_MODE_FAST_TO_SLOW; 1208 } else { 1209 *mode = _SOC_TD3_ASF_MODE_UNSUPPORTED; 1210 return SOC_E_UNAVAIL; 1211 } 1212 } else { 1213 *mode = _SOC_TD3_ASF_MODE_UNSUPPORTED; 1214 return SOC_E_UNAVAIL; 1215 } 1216 1217 return SOC_E_NONE; 1218 } 1219 1220 /****************************************************************************** 1221 * Name: soc_td3_port_asf_mode_set * 1222 * Description: * 1223 * Configure specified ASF/SAF modes on the specified port * 1224 * IN params: * 1225 * - Unit * 1226 * - Logical Port * 1227 * - Port Speed * 1228 * - ASF Mode * 1229 * OUT params: * 1230 * - None * 1231 * Returns: * 1232 * - SOC_E_NONE on success * 1233 * - SOC_E_PARAM on invalid parameter * 1234 * - SOC_E_INTERNAL on init/soc errors * 1235 */ 1236 int 1237 soc_td3_port_asf_mode_set( 1238 int unit, 1239 soc_port_t port, 1240 int port_speed, 1241 soc_td3_asf_mode_e mode) 1242 { 1243 int ret, speed_encoding = 0; 1244 uint8 min_sp = 0, max_sp = 0; 1245 uint8 fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0; 1246 uint8 oversub = 0; 1247 uint32 rval; 1248 soc_info_t *si = NULL; 1249 int init = 0; 1250 1251 if (_SOC_TD3_ASF_MODE_INIT == mode) { 1252 init = 1; 1253 mode = _SOC_TD3_ASF_MODE_SAF; 1254 } 1255 if ((!init) && (!_soc_td3_asf_ctrl[unit] || 1256 !_soc_td3_asf_ctrl[unit]->init || !(si = &SOC_INFO(unit)))) { 1257 return SOC_E_INTERNAL; 1258 } 1259 if (!_soc_td3_asf_ctrl[unit]->asf_mem_profile) { /* no cut-thru profile */ 1260 if ((_SOC_TD3_ASF_MODE_SAF != mode) && 1261 (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode)) { 1262 return SOC_E_UNAVAIL; 1263 } 1264 } 1265 if (!soc_td3_port_asf_valid(unit, port)) { 1266 if ((_SOC_TD3_ASF_MODE_SAF != mode) && 1267 (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode)) { 1268 return SOC_E_UNAVAIL; 1269 } 1270 SOC_IF_ERROR_RETURN( 1271 soc_td3_port_asf_xmit_start_count_set(unit, port, port_speed, 1272 mode, 0)); 1273 return SOC_E_NONE; 1274 } 1275 1276 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 1277 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 1278 1279 /* min. and max. src port speeds */ 1280 if (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode) { 1281 min_sp = max_sp = _SOC_TD3_ASF_QUERY; 1282 SOC_IF_ERROR_RETURN( 1283 _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode, 1284 &min_sp, &max_sp)); 1285 } 1286 1287 /* mode specific configurations */ 1288 switch(mode) { 1289 case _SOC_TD3_ASF_MODE_SAF: 1290 break; 1291 1292 case _SOC_TD3_ASF_MODE_SAME_SPEED: 1293 /* Cannot set cut-through mode for 1G ports */ 1294 if (1000 == port_speed) { 1295 return SOC_E_UNAVAIL; 1296 } 1297 1298 /* verify mode specific conformance */ 1299 if (min_sp != max_sp) { 1300 return SOC_E_PARAM; 1301 } 1302 break; 1303 1304 case _SOC_TD3_ASF_MODE_SLOW_TO_FAST: 1305 /* Cannot set cut-through mode for 1G ports */ 1306 if (1000 == port_speed) { 1307 return SOC_E_UNAVAIL; 1308 } 1309 1310 /* verify mode specific conformance */ 1311 if ( !((min_sp >= 1312 _soc_td3_asf_cfg_tbl[speed_encoding].min_sp) && 1313 (max_sp == speed_encoding)) ) { 1314 return SOC_E_PARAM; 1315 } 1316 break; 1317 1318 case _SOC_TD3_ASF_MODE_FAST_TO_SLOW: 1319 /* Cannot set cut-through mode for 1G ports */ 1320 if (1000 == port_speed) { 1321 return SOC_E_UNAVAIL; 1322 } 1323 1324 /* verify mode specific conformance */ 1325 if ( !((max_sp <= 1326 _soc_td3_asf_cfg_tbl[speed_encoding].max_sp) && 1327 (min_sp == speed_encoding)) ) { 1328 return SOC_E_PARAM; 1329 } 1330 break; 1331 1332 case _SOC_TD3_ASF_MODE_CFG_UPDATE: 1333 mode = _SOC_TD3_ASF_MODE_SAF; 1334 1335 /* disable CT first */ 1336 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1337 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1338 FIFO_THRESHOLDf, 0); 1339 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1340 sal_usleep(1); 1341 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0); 1342 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1343 1344 /* update new settings & re-enable */ 1345 ret = soc_td3_port_asf_mode_set(unit, port, port_speed, mode); 1346 return ret; 1347 1348 default: 1349 return SOC_E_PARAM; 1350 } 1351 1352 /* ASF_IPORT_CFG */ 1353 SOC_IF_ERROR_RETURN(READ_ASF_IPORT_CFGr(unit, port, &rval)); 1354 soc_reg_field_set(unit, ASF_IPORT_CFGr, &rval, ASF_PORT_SPEEDf, 1355 port_speed == 1000 ? 0: speed_encoding); 1356 SOC_IF_ERROR_RETURN(WRITE_ASF_IPORT_CFGr(unit, port, rval)); 1357 1358 /* init CT class */ 1359 SOC_IF_ERROR_RETURN(_soc_td3_port_asf_class_init(unit, port, speed_encoding)); 1360 1361 if (_SOC_TD3_ASF_MODE_SAF != mode) { 1362 /* Oversub */ 1363 oversub = (SOC_PBMP_MEMBER(si->oversub_pbm, port) ? 1 : 0); 1364 1365 /* FIFO threshold */ 1366 fifo_threshold = _SOC_TD3_ASF_QUERY; 1367 SOC_IF_ERROR_RETURN( 1368 _soc_td3_port_asf_fifo_threshold_get(unit, port, port_speed, mode, 1369 &fifo_threshold)); 1370 1371 /* FIFO depth */ 1372 fifo_depth = _SOC_TD3_ASF_QUERY; 1373 SOC_IF_ERROR_RETURN( 1374 _soc_td3_port_asf_fifo_depth_get(unit, port, port_speed, mode, 1375 &fifo_depth)); 1376 1377 /* MMU Prebuffer */ 1378 mmu_prebuf = _SOC_TD3_ASF_QUERY; 1379 SOC_IF_ERROR_RETURN( 1380 _soc_td3_port_asf_mmu_prebuf_get(unit, port, port_speed, 1381 &mmu_prebuf)); 1382 1383 SOC_IF_ERROR_RETURN( 1384 soc_td3_port_asf_params_set(unit, port, port_speed, mode)); 1385 1386 /* drain the port CT FIFO */ 1387 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1388 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 1); 1389 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0); 1390 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1391 1392 sal_usleep(1); 1393 1394 /* enable cut-through */ 1395 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub); 1396 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1397 MAX_SRC_PORT_SPEEDf, max_sp); 1398 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1399 MIN_SRC_PORT_SPEEDf, min_sp); 1400 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1401 MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf); 1402 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1403 FIFO_THRESHOLDf, fifo_threshold); 1404 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf, 1405 fifo_depth); 1406 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1407 1408 /* bookkeeping */ 1409 if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_ss, port)) { 1410 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ss, port); 1411 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) { 1412 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_sf, port); 1413 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) { 1414 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_fs, port); 1415 } 1416 SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_ports, port); 1417 if (_SOC_TD3_ASF_MODE_SAME_SPEED == mode) { 1418 SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_ss, port); 1419 } else if (_SOC_TD3_ASF_MODE_SLOW_TO_FAST== mode) { 1420 SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_sf, port); 1421 } else if (_SOC_TD3_ASF_MODE_FAST_TO_SLOW== mode) { 1422 SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_fs, port); 1423 } 1424 } else { /* Store and Forward */ 1425 fifo_depth = 0x40; 1426 fifo_threshold = 0x20; 1427 mmu_prebuf = 0; 1428 min_sp = 0; 1429 max_sp = 0; 1430 oversub = 0; 1431 1432 SOC_IF_ERROR_RETURN( 1433 soc_td3_port_asf_params_set(unit, port, port_speed, mode)); 1434 1435 /* ASF_EPORT_CFG */ 1436 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1437 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0); 1438 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1439 1440 sal_usleep(1); 1441 1442 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0); 1443 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1444 1445 /* update SAF configs */ 1446 SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval)); 1447 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub); 1448 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1449 MAX_SRC_PORT_SPEEDf, max_sp); 1450 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1451 MIN_SRC_PORT_SPEEDf, min_sp); 1452 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1453 MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf); 1454 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, 1455 FIFO_THRESHOLDf, fifo_threshold); 1456 soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf, 1457 fifo_depth); 1458 SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval)); 1459 1460 /* bookkeeping */ 1461 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ports, port); 1462 if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_ss, port)) { 1463 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ss, port); 1464 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) { 1465 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_sf, port); 1466 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) { 1467 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_fs, port); 1468 } 1469 } 1470 1471 return SOC_E_NONE; 1472 } 1473 1474 /****************************************************************************** 1475 * Name: soc_td3_port_asf_params_set * 1476 * Description: * 1477 * Configure ASF/SAF mode params on the specified port * 1478 * IN params: * 1479 * - Unit * 1480 * - Logical Port * 1481 * - Port Speed * 1482 * - ASF Mode * 1483 * OUT params: * 1484 * - None * 1485 * Returns: * 1486 * - SOC_E_NONE on success * 1487 * - SOC_E_PARAM on invalid parameter * 1488 * - SOC_E_INTERNAL on init/soc errors * 1489 */ 1490 int 1491 soc_td3_port_asf_params_set( 1492 int unit, 1493 soc_port_t port, 1494 int port_speed, 1495 soc_td3_asf_mode_e mode) 1496 { 1497 uint32 mmu_ep_credits_hi = 0, mmu_ep_credits_lo = 0; 1498 uint32 egr_mmu_cell_credits = 0; 1499 uint32 rval; 1500 uint32 ct_ok_thresh = 0; 1501 uint8 ca_thresh = 0; 1502 uint8 bubble_mop_disable = 0, oversub = 0; 1503 int ovs_ratio = 0; 1504 int speed_encoding = 0; 1505 soc_info_t *si = NULL; 1506 egr_mmu_cell_credit_entry_t credit_entry; 1507 1508 if (!(si = &SOC_INFO(unit))) { 1509 return SOC_E_INTERNAL; 1510 } 1511 1512 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 1513 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 1514 /* EDB Prebuffer */ 1515 SOC_IF_ERROR_RETURN( 1516 soc_td3_port_asf_xmit_start_count_set(unit, port, port_speed, 1517 mode, 0)); 1518 /* OBM Cell Assembly FIFO threshold */ 1519 ca_thresh = (mode == _SOC_TD3_ASF_MODE_SAF) ? 1520 _soc_td3_asf_cfg_tbl[speed_encoding].ca_thresh.saf : 1521 _soc_td3_asf_cfg_tbl[speed_encoding].ca_thresh.ct; 1522 SOC_IF_ERROR_RETURN( 1523 _soc_td3_asf_obm_ca_fifo_thresh_set(unit, port, ca_thresh)); 1524 /* CT threshold */ 1525 ct_ok_thresh = (mode == _SOC_TD3_ASF_MODE_SAF) ? 1526 _soc_td3_asf_cfg_tbl[speed_encoding].ct_ok_thresh.saf : 1527 _soc_td3_asf_cfg_tbl[speed_encoding].ct_ok_thresh.ct; 1528 SOC_IF_ERROR_RETURN( 1529 _soc_td3_asf_obm_ct_thresh_ok_set(unit, port, ct_ok_thresh)); 1530 /* OBM ForceSAF config */ 1531 SOC_IF_ERROR_RETURN( 1532 _soc_td3_asf_force_saf_config_set(unit, port, port_speed, mode)); 1533 1534 /* BubbleMOP */ 1535 if (_SOC_TD3_ASF_MODE_SAF != mode) { 1536 oversub = (SOC_PBMP_MEMBER(si->oversub_pbm, port) ? 1 : 0); 1537 bubble_mop_disable = oversub ? 1538 !(_soc_td3_asf_cfg_tbl[speed_encoding].mop_enable.oversub) : 1539 !(_soc_td3_asf_cfg_tbl[speed_encoding].mop_enable.line_rate); 1540 } 1541 SOC_IF_ERROR_RETURN( 1542 _soc_td3_asf_obm_bubble_mop_set(unit, port, bubble_mop_disable)); 1543 1544 /* MMU EP Credit Threshold */ 1545 SOC_IF_ERROR_RETURN( 1546 soc_td3_port_oversub_ratio_get(unit, port, &ovs_ratio)); 1547 if ((CCLK_FREQ_1525MHZ == si->frequency) && (ovs_ratio < 1620)) { 1548 mmu_ep_credits_lo = 1549 _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.lr_os_161.lo; 1550 mmu_ep_credits_hi = 1551 _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.lr_os_161.hi; 1552 } else { 1553 mmu_ep_credits_lo = 1554 _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.os_2_1.lo; 1555 mmu_ep_credits_hi = 1556 _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.os_2_1.hi; 1557 } 1558 1559 /* ASF_CREDIT_THRESH_LO */ 1560 SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_LOr(unit, port, &rval)); 1561 soc_reg_field_set(unit, ASF_CREDIT_THRESH_LOr, &rval, THRESHf, 1562 mmu_ep_credits_lo); 1563 SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_LOr(unit, port, rval)); 1564 1565 /* ASF_CREDIT_THRESH_HI */ 1566 SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval)); 1567 soc_reg_field_set(unit, ASF_CREDIT_THRESH_HIr, &rval, THRESHf, 1568 mmu_ep_credits_hi); 1569 SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_HIr(unit, port, rval)); 1570 1571 /* EP credits outstanding */ 1572 SOC_IF_ERROR_RETURN( 1573 soc_td3_port_asf_speed_to_mmu_cell_credit(unit, port, port_speed, 1574 &egr_mmu_cell_credits)); 1575 1576 /* EGR_MMU_CELL_CREDIT */ 1577 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 1578 si->port_l2p_mapping[port], &credit_entry)); 1579 soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &credit_entry, CREDITf, 1580 egr_mmu_cell_credits); 1581 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ALL, 1582 si->port_l2p_mapping[port], &credit_entry)); 1583 1584 return SOC_E_NONE; 1585 } 1586 1587 /****************************************************************************** 1588 * Name: soc_td3_port_asf_speed_to_mmu_cell_credit * 1589 * Description: * 1590 * Retrieve mmu_cell_credit based on port speed configured. * 1591 * Helper function for misc init. * 1592 * Support CPU and LB ports. * 1593 * IN params: * 1594 * - Unit * 1595 * - Logical Port * 1596 * - Port Speed * 1597 * OUT params: * 1598 * - MMU Cell credit * 1599 * Returns: * 1600 * - SOC_E_XXX on success * 1601 */ 1602 int 1603 soc_td3_port_asf_speed_to_mmu_cell_credit( 1604 int unit, 1605 soc_port_t port, 1606 int port_speed, 1607 OUT uint32 *mmu_cell_credit) 1608 { 1609 int speed_encoding = 0, ovs_ratio = 0; 1610 soc_info_t *si = NULL; 1611 1612 if (NULL == mmu_cell_credit) { 1613 return SOC_E_PARAM; 1614 } 1615 1616 if (!(si = &SOC_INFO(unit))) { 1617 return SOC_E_INTERNAL; 1618 } 1619 1620 if (IS_CPU_PORT(unit, port)) { 1621 port_speed = 20000; 1622 } 1623 if (IS_LB_PORT(unit, port)) { 1624 port_speed = 100000; 1625 } 1626 1627 speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed); 1628 _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0); 1629 1630 SOC_IF_ERROR_RETURN( 1631 soc_td3_port_oversub_ratio_get(unit, port, &ovs_ratio)); 1632 1633 if ((CCLK_FREQ_1525MHZ == si->frequency) && (ovs_ratio < 1620)) { 1634 *mmu_cell_credit = 1635 _soc_td3_asf_cfg_tbl[speed_encoding].ep_credit.pfc_op_cells; 1636 } else { 1637 *mmu_cell_credit = 1638 _soc_td3_asf_cfg_tbl[speed_encoding].ep_credit.base_cells; 1639 } 1640 1641 return SOC_E_NONE; 1642 } 1643 1644 /****************************************************************************** 1645 * Name: soc_td3_port_asf_mmu_cell_credit_to_port_speed * 1646 * Description: * 1647 * Retrieve port speed based on mmu_cell_credit configured. * 1648 * Helper function for MAC driver speed get. * 1649 * IN params: * 1650 * - Unit * 1651 * - Logical Port * 1652 * - MMU Cell credit * 1653 * OUT params: * 1654 * - Port speed * 1655 * Returns: * 1656 * - SOC_E_XXX on success * 1657 */ 1658 int 1659 soc_td3_port_asf_mmu_cell_credit_to_speed( 1660 int unit, 1661 soc_port_t port, 1662 uint8 mmu_cell_credit, 1663 OUT int *port_speed) 1664 { 1665 int i, freq; 1666 uint8 cell_credit; 1667 int speed; 1668 soc_info_t *si = NULL; 1669 1670 if (NULL == port_speed) { 1671 return SOC_E_PARAM; 1672 } 1673 1674 if (!(si = &SOC_INFO(unit))) { 1675 return SOC_E_INTERNAL; 1676 } 1677 1678 /* Special case for 1G ports since 1G ports use same setting as 10G port */ 1679 if (1000 == (speed = si->port_init_speed[port])) { /* Use cached speed instead */ 1680 *port_speed = speed; 1681 return SOC_E_NONE; 1682 } 1683 1684 freq = si->frequency; 1685 for (i = 1; i < (COUNTOF(_soc_td3_asf_cfg_tbl) - 1); i++) { 1686 int ovs_ratio = 0; 1687 SOC_IF_ERROR_RETURN( 1688 soc_td3_port_oversub_ratio_get(unit, port, &ovs_ratio)); 1689 1690 cell_credit = ((CCLK_FREQ_1525MHZ == freq) && (ovs_ratio < 1620))? 1691 _soc_td3_asf_cfg_tbl[i].ep_credit.pfc_op_cells : 1692 _soc_td3_asf_cfg_tbl[i].ep_credit.base_cells; 1693 1694 if (mmu_cell_credit == cell_credit) { 1695 if (IS_HG_PORT(unit, port)) { 1696 *port_speed = _soc_td3_asf_cfg_tbl[i + 1].speed; 1697 } else { 1698 *port_speed = _soc_td3_asf_cfg_tbl[i].speed; 1699 } 1700 /* This func is not available right now. But we can skip the check since 1701 credit data for each speed are all different. They can be distinguished. */ 1702 #if 0 1703 if (SOC_E_NONE != 1704 soc_td3_port_speed_supported(unit, port, *port_speed)) { 1705 continue; 1706 } 1707 #endif 1708 return SOC_E_NONE; 1709 } 1710 } 1711 1712 return SOC_E_NOT_FOUND; 1713 } 1714 1715 /****************************************************************************** 1716 * Name: soc_td3_port_asf_pause_bpmp_get * 1717 * Description: * 1718 * Get pointer of pause_restore bitmap for update * 1719 * IN params: * 1720 * - Unit * 1721 * OUT params: * 1722 * * 1723 * Returns: * 1724 * - Pointer of pause_restore bitmap * 1725 */ 1726 pbmp_t * 1727 soc_td3_port_asf_pause_bpmp_get(int unit) 1728 { 1729 if (_soc_td3_asf_ctrl[unit] == NULL) { 1730 return NULL; 1731 } 1732 return &_soc_td3_asf_ctrl[unit]->pause_restore; 1733 } 1734 1735 /************************ 1736 * ASF Warmboot Support * 1737 */ 1738 #ifdef BCM_WARM_BOOT_SUPPORT 1739 /* 1740 * ASF Warmboot is a part of Port module Warmboot. 1741 * Check Port module for scache_ver evolution. 1742 */ 1743 /* 1744 #define BCM_WB_VERSION_1_8 SOC_SCACHE_VERSION(1,8) 1745 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_8 1746 */ 1747 int 1748 soc_td3_asf_wb_memsz_get( 1749 int unit, 1750 OUT uint32* const mem_sz, 1751 uint16 scache_ver) 1752 { 1753 if (!mem_sz) { 1754 return SOC_E_PARAM; 1755 } 1756 *mem_sz = 0; 1757 1758 if (!SOC_WARM_BOOT(unit)) { 1759 if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->asf_mem_profile) { 1760 return SOC_E_UNAVAIL; 1761 } 1762 if (!_soc_td3_asf_ctrl[unit]->init) { 1763 return SOC_E_INTERNAL; 1764 } 1765 } 1766 1767 *mem_sz = sizeof(_soc_td3_asf_wb_t); 1768 1769 return SOC_E_NONE; 1770 } 1771 1772 int 1773 soc_td3_asf_wb_sync( 1774 int unit, 1775 IN_OUT uint8* const wb_data) 1776 { 1777 _soc_td3_asf_wb_t *wbd; 1778 1779 if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->asf_mem_profile) { 1780 return SOC_E_UNAVAIL; 1781 } 1782 if (!_soc_td3_asf_ctrl[unit]->init) { 1783 return SOC_E_INTERNAL; 1784 } 1785 if (!wb_data) { 1786 return SOC_E_PARAM; 1787 } 1788 1789 wbd = (_soc_td3_asf_wb_t *) wb_data; 1790 wbd->unit = unit; 1791 sal_memcpy(&wbd->asf_ctrl, _soc_td3_asf_ctrl[unit], 1792 sizeof(_soc_td3_asf_ctrl_t)); 1793 1794 return SOC_E_NONE; 1795 } 1796 1797 int 1798 soc_td3_asf_wb_recover( 1799 int unit, 1800 uint8* const wb_data, 1801 uint16 scache_ver) 1802 { 1803 _soc_td3_asf_wb_t *wbd; 1804 1805 if (!SOC_WARM_BOOT(unit)) { 1806 return SOC_E_INTERNAL; 1807 } 1808 if (!wb_data) { 1809 return SOC_E_PARAM; 1810 } 1811 1812 wbd = (_soc_td3_asf_wb_t *) wb_data; 1813 if (wbd->unit == unit) { 1814 if (!(_soc_td3_asf_ctrl[unit] = 1815 sal_alloc(sizeof(_soc_td3_asf_ctrl_t), "TD3 ASF Ctrl Area"))) { 1816 return SOC_E_MEMORY; 1817 } 1818 1819 sal_memcpy(_soc_td3_asf_ctrl[unit], &wbd->asf_ctrl, 1820 sizeof(_soc_td3_asf_ctrl_t)); 1821 } 1822 1823 LOG_CLI((BSL_META_U(unit, "*** unit %d: MMU-ASF subsystem warmbooted: " 1824 "ports %s\n"), unit, 1825 asf_profile_str[_soc_td3_asf_ctrl[unit]->asf_mem_profile])); 1826 1827 return SOC_E_NONE; 1828 } 1829 #endif /* BCM_WARM_BOOT_SUPPORT */ 1830 1831 /********************** 1832 * ASF Debug Support * 1833 */ 1834 int 1835 soc_td3_asf_pbmp_get(int unit) 1836 { 1837 char pfmt[SOC_PBMP_FMT_LEN]; 1838 1839 if (!_soc_td3_asf_ctrl[unit]->init) { 1840 return SOC_E_INTERNAL; 1841 } 1842 1843 LOG_CLI(("ASF PBMP: %s\n", 1844 SOC_PBMP_FMT(_soc_td3_asf_ctrl[unit]->asf_ports, pfmt))); 1845 1846 return SOC_E_NONE; 1847 } 1848 1849 int 1850 soc_td3_port_asf_show( 1851 int unit, 1852 soc_port_t port, 1853 int port_speed) 1854 { 1855 int ret; 1856 char mode_str[4][15] = {"SAF", "Same speed ", "Slow to Fast", 1857 "Fast to Slow"}; 1858 char speed_str[_SOC_TD3_ASF_CLASS_CNT][10] = {"SAF", "10G", "HG[11]", "20G", 1859 "HG[21]", "25G", "HG[27]", "40G", "HG[42]", 1860 "50G", "HG[53]", "100G", "HG[106]"}; 1861 soc_td3_asf_mode_e mode = _SOC_TD3_ASF_RETRV; 1862 uint8 min_speed, max_speed; 1863 1864 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 1865 return BCM_E_NONE; 1866 } 1867 1868 min_speed = max_speed = _SOC_TD3_ASF_RETRV; 1869 ret = soc_td3_port_asf_mode_get(unit, port, port_speed, &mode); 1870 if (SOC_E_UNAVAIL == ret) { 1871 mode = _SOC_TD3_ASF_MODE_SAF; 1872 } else if (SOC_E_NONE != ret) { 1873 return ret; 1874 } 1875 1876 LOG_CLI(("%-5s %-11s ", SOC_PORT_NAME(unit, port), mode_str[mode])); 1877 1878 if (_SOC_TD3_ASF_MODE_SAF == mode) { 1879 LOG_CLI((" .. NA ..\n")); 1880 } else if (_SOC_TD3_ASF_MODE_FAST_TO_SLOW == mode) { 1881 ret = _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode, 1882 &min_speed, &max_speed); 1883 LOG_CLI(("%s / %s\n", speed_str[max_speed], speed_str[min_speed])); 1884 } else { 1885 ret = _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode, 1886 &min_speed, &max_speed); 1887 LOG_CLI(("%s / %s\n", speed_str[min_speed], speed_str[max_speed])); 1888 } 1889 1890 return SOC_E_NONE; 1891 } 1892 1893 int soc_td3_asf_config_dump(int unit) 1894 { 1895 char asf_profile_str[3][25] = {"No cut-thru support", 1896 "Similar speed cut-thru", 1897 "Extreme speed cut-thru"}; 1898 1899 if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->init) { 1900 return SOC_E_INTERNAL; 1901 } 1902 1903 LOG_CLI(("ASF Profile: %s\n\n", 1904 asf_profile_str[_soc_td3_asf_ctrl[unit]->asf_mem_profile])); 1905 1906 return SOC_E_NONE; 1907 } 1908 1909 int 1910 soc_td3_port_asf_config_dump( 1911 int unit, 1912 soc_port_t port, 1913 int port_speed) 1914 { 1915 int txp = 0, rxp = 0, ct_class = 0; 1916 uint8 src_class = 0, dst_class = 0; 1917 uint8 min_sp = 0, max_sp = 0; 1918 uint8 fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0; 1919 uint8 xmit_start_cnt[13] = {0}; 1920 uint32 rval, mmu_ep_credits = 0, egr_mmu_cell_credits = 0; 1921 mac_driver_t *macd; 1922 soc_td3_asf_mode_e mode = _SOC_TD3_ASF_RETRV; 1923 egr_mmu_cell_credit_entry_t credit_entry; 1924 1925 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 1926 return BCM_E_NONE; 1927 } 1928 1929 if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->init) { 1930 return SOC_E_INTERNAL; 1931 } 1932 1933 SOC_IF_ERROR_RETURN( 1934 soc_td3_port_asf_mode_get(unit, port, port_speed, &mode)); 1935 1936 if (soc_td3_port_asf_valid(unit, port)) { 1937 min_sp = max_sp = fifo_threshold = _SOC_TD3_ASF_RETRV; 1938 fifo_depth = mmu_prebuf = _SOC_TD3_ASF_RETRV; 1939 1940 SOC_IF_ERROR_RETURN( 1941 _soc_td3_port_asf_class_get(unit, port, &ct_class)); 1942 SOC_IF_ERROR_RETURN( 1943 _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode, 1944 &min_sp, &max_sp)); 1945 SOC_IF_ERROR_RETURN( 1946 _soc_td3_port_asf_fifo_threshold_get(unit, port, port_speed, mode, 1947 &fifo_threshold)); 1948 1949 SOC_IF_ERROR_RETURN( 1950 _soc_td3_port_asf_fifo_depth_get(unit, port, port_speed, mode, 1951 &fifo_depth)); 1952 1953 SOC_IF_ERROR_RETURN( 1954 _soc_td3_port_asf_mmu_prebuf_get(unit, port, port_speed, 1955 &mmu_prebuf)); 1956 1957 SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval)); 1958 mmu_ep_credits = soc_reg_field_get(unit, ASF_CREDIT_THRESH_HIr, 1959 rval, THRESHf); 1960 } 1961 1962 dst_class = _soc_td3_speed_to_ct_class_map(port_speed); 1963 for (src_class = 0; src_class < _SOC_TD3_ASF_CLASS_CNT; src_class++) { 1964 xmit_start_cnt[src_class] = _SOC_TD3_ASF_RETRV; 1965 SOC_IF_ERROR_RETURN( 1966 _soc_td3_port_asf_xmit_start_count_get(unit, port, src_class, 1967 dst_class, mode, 1968 &xmit_start_cnt[src_class])); 1969 } 1970 1971 /* 1972 * COVERITY 1973 * 1974 * min_sp and max_sp will be updated in _soc_td3_port_asf_speed_limits_get. 1975 * So they won't overrun _soc_td3_asf_cfg_tbl. 1976 */ 1977 /* coverity[overrun-local : FALSE] */ 1978 LOG_CLI(("%-5s %-3d %-3d %-6d %-6d %-3d %-3d ", SOC_PORT_NAME(unit, port), 1979 mode, ct_class, _SOC_TD3_CT_CLASS_TO_SPEED_MAP(min_sp), 1980 _SOC_TD3_CT_CLASS_TO_SPEED_MAP(max_sp), fifo_threshold, 1981 fifo_depth)); 1982 for (src_class = 0; src_class < _SOC_TD3_ASF_CLASS_CNT; src_class++) { 1983 LOG_CLI(("%-3d ", xmit_start_cnt[src_class])); 1984 } 1985 1986 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 1987 SOC_INFO(unit).port_l2p_mapping[port], &credit_entry)); 1988 egr_mmu_cell_credits = soc_EGR_MMU_CELL_CREDITm_field32_get(unit, 1989 &credit_entry, CREDITf); 1990 1991 SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd)); 1992 SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp)); 1993 1994 LOG_CLI((" %-3d %-3d %-3d %-3d\n", mmu_prebuf, mmu_ep_credits, 1995 egr_mmu_cell_credits, rxp)); 1996 1997 return SOC_E_NONE; 1998 } 1999 2000 /****************************************************************************** 2001 * Name: soc_td3_port_asf_detach * 2002 * Description: * 2003 * Update ASF when port deleted during Flexport operation * 2004 * IN params: * 2005 * - Unit * 2006 * - Logical Port * 2007 * Returns: * 2008 * - SOC_E_NONE on success * 2009 * - SOC_E_PARAM on invalid parameter * 2010 */ 2011 int 2012 soc_td3_port_asf_detach(int unit, soc_port_t port) 2013 { 2014 if (_soc_td3_asf_ctrl[unit] == NULL) { 2015 return SOC_E_INIT; 2016 } 2017 2018 if (soc_td3_port_asf_valid(unit, port)) { 2019 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ports, port); 2020 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->pause_restore, port); 2021 if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_ss, port)) { 2022 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ss, port); 2023 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) { 2024 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_sf, port); 2025 } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) { 2026 SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_fs, port); 2027 } 2028 } 2029 return SOC_E_NONE; 2030 } 2031 2032 #endif /* BCM_TRIDENT3_SUPPORT */ 2033