port.c (46732B)
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 8 #include <soc/drv.h> 9 #include <bcm_int/esw/port.h> 10 #include <bcm/error.h> 11 #include <bcm/types.h> 12 #include <soc/profile_mem.h> 13 #include <soc/bondoptions.h> 14 #include <shared/bsl.h> 15 #include <bcm/port.h> 16 #include <bcm_int/esw_dispatch.h> 17 18 #if defined(BCM_GREYHOUND2_SUPPORT) 19 int bcmi_gh2_port_mac_type_get(int unit, soc_port_t port, 20 bcmi_port_mac_type_t *port_type) 21 22 { 23 if (NULL == port_type) { 24 return SOC_E_PARAM; 25 } 26 if (IS_XL_PORT(unit, port)) { 27 *port_type = bcmiPortMacTypeXLmac; 28 return SOC_E_NONE; 29 } else if (IS_GE_PORT(unit, port)) { 30 *port_type = bcmiPortMacTypeUnimac; 31 return SOC_E_NONE; 32 } else if (IS_CL_PORT(unit, port)) { 33 *port_type = bcmiPortMacTypeCLmac; 34 return SOC_E_NONE; 35 } else { 36 return SOC_E_PARAM; 37 } 38 } 39 40 #define E2EFC_REMOTE_MODE_VALID(_m_) \ 41 do { \ 42 if ((_m_) != bcmPortE2efcModeTx && (_m_) != bcmPortE2efcModeRx) { \ 43 return BCM_E_UNAVAIL; \ 44 } \ 45 } while (0) 46 #define GH2_BYTE2CELL(_a_) ((_a_) / 144) 47 48 #define GH2_CELL2BYTE(_a_) ((_a_) * 144) 49 50 #define GH2_E2EFC_PBM2BINDEX(_a_) \ 51 do { \ 52 switch (_a_) \ 53 { \ 54 case 1: \ 55 (_a_) = 1; \ 56 break; \ 57 case 2: \ 58 (_a_) = 2; \ 59 break; \ 60 case 4: \ 61 (_a_) = 3; \ 62 break; \ 63 case 8: \ 64 (_a_) = 4; \ 65 break; \ 66 default: \ 67 return BCM_E_PARAM; \ 68 } \ 69 } while (0) 70 71 #define GH2_E2EFC_REMOTE_PORT_NUM 48 72 #define GH2_E2EFC_RMOD_NUM 4 73 #define GH2_E2EFC_MODULE_HDR_LEN 2 74 #define GH2_PORT_BLOCK_ENT_NUM 4 75 #define GH2_PORT_BLOCK_INIT_NUM 57 76 77 STATIC const soc_field_t e2efc_rmod_id_f[GH2_E2EFC_RMOD_NUM] = { 78 RMOD_ID0f, RMOD_ID1f, RMOD_ID2f, RMOD_ID3f}; 79 STATIC const soc_reg_t 80 e2efc_rmod_id_r[bcmPortE2efcModeCount][GH2_E2EFC_RMOD_NUM] = { 81 {E2EFC_TX_RMODID_0r, E2EFC_TX_RMODID_0r, 82 E2EFC_TX_RMODID_1r, E2EFC_TX_RMODID_1r}, 83 {E2EFC_RX_RMODID_0r, E2EFC_RX_RMODID_0r, 84 E2EFC_RX_RMODID_1r, E2EFC_RX_RMODID_1r}}; 85 STATIC const soc_field_t e2efc_rmod_enable[GH2_E2EFC_RMOD_NUM] = { 86 V0f, V1f, V2f, V3f}; 87 88 typedef enum port_e2efc_mac_type_c { 89 E2efcModuleHdrXlmac = 0, 90 E2efcModuleHdrClmac = 1, 91 E2efcModuleHdrMacCount = 2 92 } port_e2efc_mac_type_t; 93 94 /* XLMAC : 0, CLMAC:1 */ 95 STATIC const soc_reg_t 96 e2efc_module_hdr_r[E2efcModuleHdrMacCount][GH2_E2EFC_MODULE_HDR_LEN] = { 97 {XLMAC_E2EFC_MODULE_HDR_0r, XLMAC_E2EFC_MODULE_HDR_1r}, 98 {CLMAC_E2EFC_MODULE_HDR_0r, CLMAC_E2EFC_MODULE_HDR_1r}}; 99 100 /* 101 * Description: 102 * Enable and configure the remote module to apply E2EFC mechanism. 103 * Or disable it. 104 * Parameter: 105 * unit - (IN) unit number 106 * remote_module - (IN) remote module id 107 * mode - (IN) selected mode 108 * enable - (IN) enable or disable selection 109 * e2efc_rmod_cfg - (IN) structure containing the configuration. 110 * Ignored when enable = 0. 111 */ 112 int 113 bcmi_gh2_port_e2efc_remote_module_enable_set( 114 int unit, 115 bcm_module_t remote_module, 116 bcm_port_e2efc_mode_t mode, 117 int enable, 118 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 119 { 120 bcm_port_t local_port; 121 uint32 val; 122 bcm_module_t remote_module_clear = 0; 123 int modid, i, blk, bindex, blk_num, port_mode; 124 /* XLMAC Related Parameters */ 125 uint32 hdr_0_lo, hdr_0_hi, hdr_1_lo, hdr_1_hi; 126 uint32 src_mod, dest_mod, src_port; 127 uint64 val_64; 128 int time_unit_sel, time_units, value_a, value_b; 129 uint32 val_min, val_max, new_pbm = 0; 130 port_e2efc_mac_type_t mac_type; 131 int hdr_0 = 0, hdr_1 = 1; 132 133 E2EFC_REMOTE_MODE_VALID(mode); 134 /* Check the remote module id is in the valid range or not */ 135 if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) { 136 LOG_ERROR(BSL_LS_BCM_PORT, 137 (BSL_META_U(unit, 138 "Invalid remote module ID.\n"))); 139 return BCM_E_BADID; 140 } 141 142 if (e2efc_rmod_cfg == NULL) { 143 LOG_ERROR(BSL_LS_BCM_PORT, 144 (BSL_META_U(unit, 145 "Null Remote Module Configuration.\n"))); 146 return BCM_E_PARAM; 147 } 148 149 /* Check the logical port is in the right range */ 150 if (mode == bcmPortE2efcModeTx && 151 (!SOC_PORT_VALID(unit, e2efc_rmod_cfg->local_port))) { 152 LOG_ERROR(BSL_LS_BCM_PORT, 153 (BSL_META_U(unit, 154 "Invalid port range.\n"))); 155 return BCM_E_PARAM; 156 } 157 /* Checking whether remote port is HG port */ 158 if (mode == bcmPortE2efcModeTx) { 159 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate( 160 unit, e2efc_rmod_cfg->local_port, 161 &local_port)); 162 if (!IS_HG_PORT(unit, local_port)) { 163 LOG_ERROR( 164 BSL_LS_BCM_PORT, 165 (BSL_META_U(unit, 166 "Error: unit %d port %d is not a Higig port. " 167 "E2EFC messages can only be transmitted to " 168 "or received from Higig ports.\n"), 169 unit, local_port)); 170 return BCM_E_PARAM; 171 } 172 173 if (e2efc_rmod_cfg->pkt_per_second < 0) { 174 LOG_ERROR( 175 BSL_LS_BCM_PORT, 176 (BSL_META_U(unit, 177 "Frequency of sending an E2EFC message " 178 "cannot be less than zero. \n"))); 179 return BCM_E_PARAM; 180 } 181 } 182 183 if (enable == 1) { 184 /* Search whether the existing remote module ID exist */ 185 for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) { 186 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i], 187 REG_PORT_ANY, 0, &val)); 188 if ((remote_module == (soc_reg_field_get( 189 unit, e2efc_rmod_id_r[mode][i], val, 190 e2efc_rmod_id_f[i]))) && 191 (soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i], val, 192 e2efc_rmod_enable[i]) == 1)) { 193 LOG_ERROR(BSL_LS_BCM_PORT, 194 (BSL_META_U(unit, 195 "Remote Module ID already exists.\n"))); 196 return BCM_E_EXISTS; 197 } 198 } 199 /* Traverse 4 remote module id and setup the one that is not enabled */ 200 modid = -1; 201 for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) { 202 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i], 203 REG_PORT_ANY, 0, &val)); 204 if (!(soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i], val, 205 e2efc_rmod_enable[i]))) { 206 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val, 207 e2efc_rmod_id_f[i], remote_module); 208 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val, 209 e2efc_rmod_enable[i], enable); 210 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, 211 e2efc_rmod_id_r[mode][i], 212 REG_PORT_ANY, 0, val)); 213 modid = i; 214 break; 215 } 216 } 217 if (modid == -1 ) { 218 LOG_ERROR(BSL_LS_BCM_PORT, 219 (BSL_META_U(unit, 220 "E2EFC No Available Remote.Module to Setup" 221 "Maximun 4 Remote Module only.\n"))); 222 return BCM_E_FULL; 223 } 224 /* Set up Higig Port and Port Speed Information */ 225 if (mode == bcmPortE2efcModeTx) { 226 /* Register E2EFC_RMOD_CFG fill in */ 227 if (soc_feature(unit, soc_feature_logical_port_num)) { 228 blk = SOC_PORT_BLOCK( 229 unit, SOC_INFO(unit).port_l2p_mapping[local_port]); 230 bindex = SOC_PORT_BINDEX( 231 unit, SOC_INFO(unit).port_l2p_mapping[local_port]); 232 } else { 233 blk = SOC_PORT_BLOCK(unit, local_port); 234 bindex = SOC_PORT_BINDEX(unit, local_port); 235 } 236 blk_num = SOC_BLOCK_INFO(unit, blk).number; 237 if (IS_CL_PORT(unit, local_port)) { 238 /* 239 * the SOC_BLOCK_INFO will assign block 0 to CL_PORT, 240 * which should be 7 as it follow after XL_PORT block 6 241 */ 242 blk_num += 7; 243 } 244 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_RMOD_CFGr, 245 REG_PORT_ANY, modid, &val)); 246 soc_reg_field_set(unit, E2EFC_RMOD_CFGr, &val, 247 PORT_GRP_IDf, blk_num); 248 new_pbm |= (1 << bindex); 249 soc_reg_field_set(unit, E2EFC_RMOD_CFGr, &val, 250 TX_ENABLE_BMPf, new_pbm); 251 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_RMOD_CFGr, 252 REG_PORT_ANY, modid, val)); 253 /* XLMAC Module Header Set up */ 254 bcm_esw_port_encap_get(unit, local_port, &port_mode); 255 /* Higig2 Mode */ 256 bcm_esw_stk_my_modid_get(unit, (int *)&src_mod); 257 if (port_mode == BCM_PORT_ENCAP_HIGIG2) { 258 /* default setting K.SOP = 0xfb, MCST = 0(unicast)*/ 259 hdr_0_hi = 0xfb000000; 260 dest_mod = (remote_module & 0xff) << 8; 261 hdr_0_hi = hdr_0_hi | dest_mod; 262 hdr_0_lo = 0x00000000; 263 src_mod = (src_mod & 0xff) << 24; 264 src_port = (local_port & 0xff) << 16; 265 hdr_0_lo = hdr_0_lo | src_mod | src_port; 266 } else { 267 /* Higig Mode */ 268 /* default setting K.SOP = 0xfb, HGI = 8, VID = 1 */ 269 hdr_0_hi = 0xfb800001; 270 src_mod = (src_mod & 0x1f) << 27; 271 dest_mod = remote_module & 0xff; 272 /* default setting OPCODE = 1, COS = 7 */ 273 hdr_0_lo = 0x01000700 | src_mod | dest_mod; 274 } 275 276 if (IS_XL_PORT(unit, local_port)) { 277 mac_type = E2efcModuleHdrXlmac; 278 } else if (IS_CL_PORT(unit, local_port)) { 279 mac_type = E2efcModuleHdrClmac; 280 } else { 281 LOG_ERROR(BSL_LS_BCM_PORT, 282 (BSL_META_U(unit, 283 "Invalid Mac Type.\n"))); 284 return BCM_E_PARAM; 285 } 286 287 BCM_IF_ERROR_RETURN( 288 soc_reg64_get(unit, e2efc_module_hdr_r[mac_type][hdr_0], 289 local_port, 0, &val_64)); 290 soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_0], 291 &val_64, E2EFC_MODULE_HDR_0_LOf, hdr_0_lo); 292 soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_0], 293 &val_64, E2EFC_MODULE_HDR_0_HIf, hdr_0_hi); 294 BCM_IF_ERROR_RETURN( 295 soc_reg64_set(unit, e2efc_module_hdr_r[mac_type][hdr_0], 296 local_port, 0, val_64)); 297 298 if (port_mode == BCM_PORT_ENCAP_HIGIG2) { 299 /* default setting vlan = 1, opcode = 1 */ 300 hdr_1_lo = 0x00010100; 301 hdr_1_hi = 0x00000000; 302 } else { 303 hdr_1_lo = 0x00000000; 304 hdr_1_hi = 0x00000000; 305 } 306 BCM_IF_ERROR_RETURN( 307 soc_reg64_get(unit, e2efc_module_hdr_r[mac_type][hdr_1], 308 local_port, 0, &val_64)); 309 soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_1], 310 &val_64, E2EFC_MODULE_HDR_1_LOf, hdr_1_lo); 311 soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_1], 312 &val_64, E2EFC_MODULE_HDR_1_HIf, 313 hdr_1_hi); 314 BCM_IF_ERROR_RETURN( 315 soc_reg64_set(unit, e2efc_module_hdr_r[mac_type][hdr_1], 316 local_port, 0, val_64)); 317 /* In the absence of congestion, an E2EFC message is still 318 * generated to refresh congestion status when the E2EFC max 319 * timer expires. This timer is specified in units of 250ns or 320 * 25us, and up to 1023 time units can be specified. 321 * The selection of time unit and the number of time units 322 * is computed as follows: 323 * 324 * Let E2EFC message refresh rate = N messages/sec, and N != 0, 325 * A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N, 326 * B = # of 25us time units = 1 sec / N / 25us = 327 * 40000 / N = A / 100. 328 * 329 * If A < 1, configure the minimum allowed timer value: 330 * time unit = 250ns, # of time units = 1. 331 * 332 * If A is between 1 and 1023, configure the timer as: 333 * time unit = 250ns, # of time units = A. 334 * 335 * If A > 1023 and B <= 1023, configure the timer as: 336 * time unit = 25us, # of time units = B. 337 * 338 * If B > 1023, configure the maximum allowed timer value: 339 * time unit = 25us, # of time units = 1023. 340 * 341 * Note: If N = 0, # of time units will be set to 0, and E2EFC 342 * message refresh is effectively disabled. E2ECC message 343 * will be generated only when there is a change in congestion 344 * status. 345 */ 346 347 if (e2efc_rmod_cfg->pkt_per_second == 0) { 348 time_unit_sel = 0; 349 time_units = 0; 350 } else { 351 value_a = 4000000 / e2efc_rmod_cfg->pkt_per_second; 352 value_b = value_a / 100; 353 if (value_a < 1) { 354 time_unit_sel = 0; 355 time_units = 1; 356 } else if (value_a <= 1023) { 357 time_unit_sel = 0; 358 time_units = value_a; 359 } else if ((value_a > 1023) && (value_b <= 1023)) { 360 time_unit_sel = 1; 361 time_units = value_b; 362 } else { /* value_b > 1023 */ 363 time_unit_sel = 1; 364 time_units = 1023; 365 } 366 } 367 /* E2EFC meesage trasmit period setup */ 368 /* For Min TX Timer */ 369 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_HG_MIN_TX_TIMERr, 370 REG_PORT_ANY, modid, &val_min)); 371 soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val_min, 372 LGf, time_unit_sel); 373 soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val_min, 374 TIMERf, time_units); 375 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_HG_MIN_TX_TIMERr, 376 REG_PORT_ANY, modid, val_min)); 377 /* For Max TX Timer */ 378 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_HG_MAX_TX_TIMERr, 379 REG_PORT_ANY, modid, &val_max)); 380 soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val_max, 381 LGf, time_unit_sel); 382 soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val_max, 383 TIMERf, time_units); 384 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_HG_MAX_TX_TIMERr, 385 REG_PORT_ANY, modid, val_max)); 386 } else { 387 LOG_VERBOSE(BSL_LS_BCM_PORT, 388 (BSL_META_U(unit, 389 "E2EFC RX mode not allowed to configure timer" 390 " and XLMAC and HG port setup.\n"))); 391 } 392 } else { 393 /* Traverse 4 rmod id and clear the one that match rmod id */ 394 modid = -1; 395 for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) { 396 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i], 397 REG_PORT_ANY, 0, &val)); 398 if (remote_module == (soc_reg_field_get( 399 unit, e2efc_rmod_id_r[mode][i], val, 400 e2efc_rmod_id_f[i]))) { 401 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val, 402 e2efc_rmod_id_f[i], remote_module_clear); 403 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val, 404 e2efc_rmod_enable[i], 0); 405 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, 406 e2efc_rmod_id_r[mode][i], 407 REG_PORT_ANY, 0, val)); 408 modid = i; 409 break; 410 } 411 } 412 if (modid == -1 ) { 413 LOG_ERROR(BSL_LS_BCM_PORT, 414 (BSL_META_U(unit, 415 "E2EFC No Existing Remote.Module to Clear" 416 "Maximun 4 Remote Module only.\n"))); 417 return BCM_E_NOT_FOUND; 418 } 419 } 420 421 return BCM_E_NONE; 422 } 423 424 425 /* 426 * Description: 427 * Get the enable mode and configuration of the remote module that 428 * applies E2EFC mechanism. 429 * Parameter: 430 * unit - (IN) unit number 431 * remote_module - (IN) remote module id 432 * mode - (IN) selected mode 433 * enable - (OUT) enable or disable selection 434 * e2efc_rmod_cfg - (OUT) structure containing the configuration. 435 * Only valid if the remote module is enabled. 436 */ 437 int 438 bcmi_gh2_port_e2efc_remote_module_enable_get( 439 int unit, 440 bcm_module_t remote_module, 441 bcm_port_e2efc_mode_t mode, 442 int *enable, 443 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 444 { 445 uint32 val, val_p, val_t; 446 int i, time_unit_sel, time_units; 447 int blk_num, pbm, phy_port = 0, log_port = 0; 448 449 E2EFC_REMOTE_MODE_VALID(mode); 450 451 /* Check the remote module id is in the valid range or not */ 452 if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) { 453 LOG_ERROR(BSL_LS_BCM_PORT, 454 (BSL_META_U(unit, 455 "Invalid remote module ID.\n"))); 456 return BCM_E_BADID; 457 } 458 459 if (enable == NULL || e2efc_rmod_cfg == NULL) { 460 return BCM_E_PARAM; 461 } 462 463 /* Check the logical port is in the right range */ 464 if (!SOC_PORT_VALID(unit, e2efc_rmod_cfg->local_port)) { 465 LOG_ERROR(BSL_LS_BCM_PORT, 466 (BSL_META_U(unit, 467 "Invalid port range.\n"))); 468 return BCM_E_PARAM; 469 } 470 471 /* if the matched rmod id is not found then the "enable" is zero */ 472 *enable = 0; 473 /* 474 * Only Mode TX has the bcm_port_e2efc_remote_module_config_t 475 * configuration, so if mode == RX, the get API will check whether the 476 * remote_module exists and return enable value. 477 */ 478 /* Traverse 4 rmod id and search the one that match rmod id */ 479 for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) { 480 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i], 481 REG_PORT_ANY, 0, &val)); 482 if (remote_module == (soc_reg_field_get(unit, 483 e2efc_rmod_id_r[mode][i], val, 484 e2efc_rmod_id_f[i]))) { 485 if (mode == bcmPortE2efcModeTx) { 486 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_RMOD_CFGr, 487 REG_PORT_ANY, i, &val_p)); 488 blk_num = soc_reg_field_get(unit, E2EFC_RMOD_CFGr, val_p, 489 PORT_GRP_IDf); 490 pbm = soc_reg_field_get(unit, E2EFC_RMOD_CFGr, val_p, 491 TX_ENABLE_BMPf); 492 GH2_E2EFC_PBM2BINDEX(pbm); 493 phy_port = (blk_num * GH2_PORT_BLOCK_ENT_NUM) + pbm 494 + GH2_PORT_BLOCK_INIT_NUM; 495 log_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 496 e2efc_rmod_cfg->local_port = log_port; 497 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_HG_MIN_TX_TIMERr, 498 REG_PORT_ANY, i, &val_t)); 499 time_unit_sel = 500 soc_reg_field_get(unit, E2EFC_HG_MIN_TX_TIMERr, 501 val_t, LGf); 502 time_units = 503 soc_reg_field_get(unit, E2EFC_HG_MIN_TX_TIMERr, 504 val_t, TIMERf); 505 if (time_units == 0) { 506 e2efc_rmod_cfg->pkt_per_second = 0; 507 } else if (time_unit_sel == 1) { 508 /* pkt_per_second = 1 / 25us / time_units */ 509 e2efc_rmod_cfg->pkt_per_second = 40000 / time_units; 510 } else { 511 /* pkt_per_second = 1 / 250ns / time_units */ 512 e2efc_rmod_cfg->pkt_per_second = 4000000 / time_units; 513 } 514 } 515 *enable = 1; 516 break; 517 } 518 } 519 return BCM_E_NONE; 520 } 521 522 /* helper function to search the remote module pointer */ 523 int 524 bcmi_gh2_e2efc_remote_module_ptr_get( 525 int unit, 526 bcm_module_t remote_module, 527 int *module_ptr) 528 { 529 int i, ptr; 530 uint32 val; 531 bcm_port_e2efc_mode_t mode = bcmPortE2efcModeTx; 532 533 if (module_ptr == NULL) { 534 return BCM_E_PARAM; 535 } 536 /* Check the remote module id is in the valid range or not */ 537 if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) { 538 LOG_ERROR(BSL_LS_BCM_PORT, 539 (BSL_META_U(unit, 540 "Invalid remote module ID.\n"))); 541 return BCM_E_BADID; 542 } 543 544 ptr = -1; 545 for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) { 546 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i], 547 REG_PORT_ANY, 0, &val)); 548 if (remote_module == (soc_reg_field_get( 549 unit, e2efc_rmod_id_r[mode][i], val, 550 e2efc_rmod_id_f[i]))) { 551 ptr = i; 552 break; 553 } 554 } 555 if (ptr == -1) { 556 LOG_ERROR(BSL_LS_BCM_PORT, 557 (BSL_META_U(unit, 558 "Remote module ID not found.\n"))); 559 return BCM_E_NOT_FOUND; 560 } else { 561 *module_ptr = ptr; 562 } 563 return BCM_E_NONE; 564 } 565 566 /* helper function to search the remote module id */ 567 int 568 bcmi_gh2_e2efc_remote_module_id_get( 569 int unit, 570 int module_ptr, 571 bcm_module_t *remote_module) 572 { 573 uint32 val; 574 bcm_port_e2efc_mode_t mode = bcmPortE2efcModeTx; 575 576 if (remote_module == NULL) { 577 return BCM_E_PARAM; 578 } 579 580 if (module_ptr < 0 || module_ptr >= GH2_E2EFC_RMOD_NUM) { 581 LOG_ERROR(BSL_LS_BCM_PORT, 582 (BSL_META_U(unit, 583 "Invalid remote module pointer. Should be 0~3.\n"))); 584 return BCM_E_PARAM; 585 } 586 587 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][module_ptr], 588 REG_PORT_ANY, 0, &val)); 589 /* the remote moduel is enabled */ 590 if (soc_reg_field_get(unit, 591 e2efc_rmod_id_r[mode][module_ptr], val, 592 e2efc_rmod_enable[module_ptr])) { 593 *remote_module = (soc_reg_field_get( 594 unit, e2efc_rmod_id_r[mode][module_ptr], val, 595 e2efc_rmod_id_f[module_ptr])); 596 } else { 597 return BCM_E_FAIL; 598 } 599 600 return BCM_E_NONE; 601 } 602 603 /* helper function to init E2EFC remote port */ 604 int 605 bcmi_gh2_port_e2efc_remote_port_init(int unit) 606 { 607 int i; 608 uint32 val; 609 610 for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) { 611 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 612 REG_PORT_ANY, i, &val)); 613 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val, Vf, 0); 614 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, 615 REG_PORT_ANY, i, val)); 616 } 617 618 return BCM_E_NONE; 619 } 620 621 /* 622 * Description: 623 * Add remote module-port and set configuration. 624 * Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs. 625 * The API of remote module-port configuration is only for E2EFC 626 * transmission. 627 * Parameter: 628 * unit - (IN) unit number 629 * e2efc_rport_cfg - (IN) structure containing the configuration 630 * rport_handle_id - (OUT) remote port handle id, to be used for the rest 631 * of bcm_port_e2efc_remote_port_xxx APIs 632 */ 633 int 634 bcmi_gh2_port_e2efc_remote_port_add( 635 int unit, 636 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg, 637 int *rport_handle_id) 638 { 639 uint32 val_p, val_off, val_on, val_drop; 640 int i, enable, rmod_ptr; 641 642 if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) { 643 return BCM_E_PARAM; 644 } 645 646 /* Check the logical port is in the right range */ 647 if (!SOC_PORT_VALID(unit, e2efc_rport_cfg->remote_port)) { 648 LOG_ERROR(BSL_LS_BCM_PORT, 649 (BSL_META_U(unit, 650 "Invalid port range.\n"))); 651 return BCM_E_PARAM; 652 } 653 654 if ((e2efc_rport_cfg->xoff_threshold_packets < 0) || 655 (e2efc_rport_cfg->xoff_threshold_bytes < 0) || 656 (e2efc_rport_cfg->xon_threshold_packets < 0) || 657 (e2efc_rport_cfg->xon_threshold_bytes < 0) || 658 (e2efc_rport_cfg->drop_threshold_packets < 0) || 659 (e2efc_rport_cfg->drop_threshold_bytes < 0)) { 660 LOG_ERROR(BSL_LS_BCM_PORT, 661 (BSL_META_U(unit, 662 "Invalid threshhold value set, should not less than 0.\n"))); 663 return BCM_E_PARAM; 664 } 665 666 /* Checking if the duplicated Counter is being set */ 667 for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) { 668 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 669 REG_PORT_ANY, i, &val_p)); 670 if ((soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, Vf))) { 671 BCM_IF_ERROR_RETURN( 672 bcmi_gh2_e2efc_remote_module_ptr_get( 673 unit, e2efc_rport_cfg->remote_module, &rmod_ptr)); 674 if (e2efc_rport_cfg->remote_port == 675 (soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 676 val_p, RMT_SRC_PORT_IDf))&& 677 rmod_ptr == (soc_reg_field_get( 678 unit, E2EFC_CNT_ATTRr, val_p, 679 RMOD_PTRf))) { 680 LOG_ERROR(BSL_LS_BCM_PORT, 681 (BSL_META_U(unit, 682 "Each remote source port should be" 683 "mapped to only one counter.\n"))); 684 return BCM_E_FULL; 685 } 686 } 687 } 688 689 enable = 0; 690 for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) { 691 /* check whether the E2EFC_CNT_ATTRr Vf is enabled */ 692 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 693 REG_PORT_ANY, i, &val_p)); 694 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, Vf))) { 695 /* Setting remote port, module id and enable counter */ 696 enable = 1; 697 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, Vf, enable); 698 BCM_IF_ERROR_RETURN( 699 bcmi_gh2_e2efc_remote_module_ptr_get( 700 unit, e2efc_rport_cfg->remote_module, &rmod_ptr)); 701 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 702 RMOD_PTRf, rmod_ptr); 703 704 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 705 RMT_SRC_PORT_IDf, e2efc_rport_cfg->remote_port); 706 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, 707 REG_PORT_ANY, i, val_p)); 708 /* Setting xoff theshhold */ 709 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_SET_LIMITr, 710 REG_PORT_ANY, i, &val_off)); 711 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off, 712 PKT_SET_LIMITf, 713 e2efc_rport_cfg->xoff_threshold_packets); 714 soc_reg_field_set( 715 unit, E2EFC_CNT_SET_LIMITr, &val_off, CELL_SET_LIMITf, 716 GH2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes)); 717 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_SET_LIMITr, 718 REG_PORT_ANY, i, val_off)); 719 /* Setting xon theshhold */ 720 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 721 E2EFC_CNT_RESET_LIMITr, 722 REG_PORT_ANY, i, &val_on)); 723 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &val_on, 724 PKT_RESET_LIMITf, 725 e2efc_rport_cfg->xon_threshold_packets); 726 soc_reg_field_set( 727 unit, E2EFC_CNT_RESET_LIMITr, &val_on, CELL_RESET_LIMITf, 728 GH2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes)); 729 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_RESET_LIMITr, 730 REG_PORT_ANY, i, val_on)); 731 /* Setting drop theshhold */ 732 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 733 E2EFC_CNT_DISC_LIMITr, 734 REG_PORT_ANY, i, &val_drop)); 735 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &val_drop, 736 PKT_DISC_LIMITf, 737 e2efc_rport_cfg->drop_threshold_packets); 738 soc_reg_field_set( 739 unit, E2EFC_CNT_DISC_LIMITr, &val_drop, CELL_DISC_LIMITf, 740 GH2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes)); 741 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_DISC_LIMITr, 742 REG_PORT_ANY, i, val_drop)); 743 break; 744 } 745 } 746 if (enable == 0) { 747 LOG_ERROR(BSL_LS_BCM_PORT, 748 (BSL_META_U(unit, 749 "Can't Port Config Because the 48 entries is all full"))); 750 return BCM_E_FULL; 751 } 752 *rport_handle_id = i; 753 754 return BCM_E_NONE; 755 } 756 757 /* 758 * Description: 759 * Set (modify) configuration of the remote port. 760 * Parameter: 761 * unit - (IN) unit number 762 * rport_handle_id - (IN) remote port handle id 763 * e2efc_rport_cfg - (IN) structure containing the configuration 764 */ 765 int 766 bcmi_gh2_port_e2efc_remote_port_set( 767 int unit, 768 int rport_handle_id, 769 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 770 { 771 uint32 val_p, val_off, val_on, val_drop; 772 int rmod_ptr; 773 774 /* check whehter the handle id is valid */ 775 if ( rport_handle_id < 0 || rport_handle_id >= GH2_E2EFC_REMOTE_PORT_NUM) { 776 LOG_ERROR(BSL_LS_BCM_PORT, 777 (BSL_META_U(unit, 778 "Invalid Hadle ID.\n"))); 779 return BCM_E_PARAM; 780 } 781 782 if (e2efc_rport_cfg == NULL) { 783 return BCM_E_PARAM; 784 } 785 786 /* Check the logical port is in the right range */ 787 if (!SOC_PORT_VALID(unit, e2efc_rport_cfg->remote_port)) { 788 LOG_ERROR(BSL_LS_BCM_PORT, 789 (BSL_META_U(unit, 790 "Invalid port range.\n"))); 791 return BCM_E_PARAM; 792 } 793 794 if ((e2efc_rport_cfg->xoff_threshold_packets < 0) || 795 (e2efc_rport_cfg->xoff_threshold_bytes < 0) || 796 (e2efc_rport_cfg->xon_threshold_packets < 0) || 797 (e2efc_rport_cfg->xon_threshold_bytes < 0) || 798 (e2efc_rport_cfg->drop_threshold_packets < 0) || 799 (e2efc_rport_cfg->drop_threshold_bytes < 0)) { 800 LOG_ERROR(BSL_LS_BCM_PORT, 801 (BSL_META_U(unit, 802 "Invalid threshhold value set, should not less than 0.\n"))); 803 return BCM_E_PARAM; 804 } 805 /* check whether the parameter is added or not */ 806 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 807 E2EFC_CNT_ATTRr, 808 REG_PORT_ANY, rport_handle_id, &val_p)); 809 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 810 val_p, Vf))) { 811 LOG_ERROR(BSL_LS_BCM_PORT, 812 (BSL_META_U(unit, 813 "The port config is not added, thus can't set"))); 814 return BCM_E_PARAM; 815 } 816 817 /* Setting remote port and module id */ 818 BCM_IF_ERROR_RETURN( 819 bcmi_gh2_e2efc_remote_module_ptr_get( 820 unit, e2efc_rport_cfg->remote_module, &rmod_ptr)); 821 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, RMOD_PTRf, rmod_ptr); 822 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 823 RMT_SRC_PORT_IDf, e2efc_rport_cfg->remote_port); 824 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, REG_PORT_ANY, 825 rport_handle_id, val_p)); 826 /* Setting xoff theshhold */ 827 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 828 E2EFC_CNT_SET_LIMITr, REG_PORT_ANY, 829 rport_handle_id, &val_off)); 830 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off, 831 PKT_SET_LIMITf, 832 e2efc_rport_cfg->xoff_threshold_packets); 833 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off, 834 CELL_SET_LIMITf, 835 GH2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes)); 836 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_SET_LIMITr, 837 REG_PORT_ANY, rport_handle_id, val_off)); 838 /* Setting xon theshhold */ 839 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 840 E2EFC_CNT_RESET_LIMITr, 841 REG_PORT_ANY, rport_handle_id, &val_on)); 842 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, 843 &val_on, PKT_RESET_LIMITf, 844 e2efc_rport_cfg->xon_threshold_packets); 845 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, 846 &val_on, CELL_RESET_LIMITf, 847 GH2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes)); 848 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_RESET_LIMITr, 849 REG_PORT_ANY, rport_handle_id, val_on)); 850 /* Setting drop theshhold */ 851 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 852 E2EFC_CNT_DISC_LIMITr, REG_PORT_ANY, 853 rport_handle_id, &val_drop)); 854 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, 855 &val_drop, PKT_DISC_LIMITf, 856 e2efc_rport_cfg->drop_threshold_packets); 857 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, 858 &val_drop, CELL_DISC_LIMITf, 859 GH2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes)); 860 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_DISC_LIMITr, 861 REG_PORT_ANY, rport_handle_id, val_drop)); 862 863 return BCM_E_NONE; 864 } 865 866 867 /* 868 * Description: 869 * Get configuration of the remote port. 870 * Return the remote module, remote port and configuration of the 871 * handle id. 872 * Parameter: 873 * unit - (IN) unit number 874 * rport_handle_id - (IN) remote port handle id 875 * e2efc_rport_cfg - (OUT) structure containing the configuration 876 */ 877 int 878 bcmi_gh2_port_e2efc_remote_port_get( 879 int unit, 880 int rport_handle_id, 881 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 882 { 883 uint32 val_p, val_off, val_on, val_drop; 884 int rmod_ptr, rmod_id; 885 int xoff_threshold_cell, xon_threshold_cell, drop_threshold_cell; 886 887 if (e2efc_rport_cfg == NULL) { 888 return BCM_E_PARAM; 889 } 890 891 /* check whehter the handle id is valid */ 892 if ( rport_handle_id < 0 || rport_handle_id >= GH2_E2EFC_REMOTE_PORT_NUM) { 893 LOG_ERROR(BSL_LS_BCM_PORT, 894 (BSL_META_U(unit, 895 "Invalid Hadle ID.\n"))); 896 return BCM_E_PARAM; 897 } 898 /* check whether the parameter is added or not */ 899 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 900 E2EFC_CNT_ATTRr, 901 REG_PORT_ANY, rport_handle_id, &val_p)); 902 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 903 val_p, Vf))) { 904 LOG_ERROR(BSL_LS_BCM_PORT, 905 (BSL_META_U(unit, 906 "The port config is not added, thus can't get"))); 907 return BCM_E_NOT_FOUND; 908 } 909 910 /* Getting remote port and module id */ 911 rmod_ptr = soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, RMOD_PTRf); 912 BCM_IF_ERROR_RETURN( 913 bcmi_gh2_e2efc_remote_module_id_get(unit, rmod_ptr, &rmod_id)); 914 e2efc_rport_cfg->remote_module = rmod_id; 915 e2efc_rport_cfg->remote_port = 916 soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, 917 RMT_SRC_PORT_IDf); 918 /* Getting xoff theshhold */ 919 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_SET_LIMITr, 920 REG_PORT_ANY, rport_handle_id, &val_off)); 921 e2efc_rport_cfg->xoff_threshold_packets = 922 soc_reg_field_get(unit, E2EFC_CNT_SET_LIMITr, val_off, 923 PKT_SET_LIMITf); 924 xoff_threshold_cell = soc_reg_field_get(unit, E2EFC_CNT_SET_LIMITr, 925 val_off, CELL_SET_LIMITf); 926 e2efc_rport_cfg->xoff_threshold_bytes = GH2_CELL2BYTE(xoff_threshold_cell); 927 /* Getting xon theshhold */ 928 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_RESET_LIMITr, 929 REG_PORT_ANY, rport_handle_id, &val_on)); 930 e2efc_rport_cfg->xon_threshold_packets = 931 soc_reg_field_get(unit, E2EFC_CNT_RESET_LIMITr, 932 val_on, PKT_RESET_LIMITf); 933 xon_threshold_cell = soc_reg_field_get(unit, E2EFC_CNT_RESET_LIMITr, 934 val_on, CELL_RESET_LIMITf); 935 e2efc_rport_cfg->xon_threshold_bytes = GH2_CELL2BYTE(xon_threshold_cell); 936 /* Getting drop theshhold */ 937 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_DISC_LIMITr, 938 REG_PORT_ANY, 939 rport_handle_id, &val_drop)); 940 e2efc_rport_cfg->drop_threshold_packets = 941 soc_reg_field_get(unit, E2EFC_CNT_DISC_LIMITr, 942 val_drop, PKT_DISC_LIMITf); 943 drop_threshold_cell = soc_reg_field_get(unit, E2EFC_CNT_DISC_LIMITr, 944 val_drop, CELL_DISC_LIMITf); 945 e2efc_rport_cfg->drop_threshold_bytes = GH2_CELL2BYTE(drop_threshold_cell); 946 947 return BCM_E_NONE; 948 } 949 950 951 /* 952 * Description: 953 * Delete remote port. 954 * Parameter: 955 * unit - (IN) unit number 956 * rport_handle_id - (IN) remote port handle id 957 */ 958 int 959 bcmi_gh2_port_e2efc_remote_port_delete( 960 int unit, 961 int rport_handle_id) 962 { 963 uint32 val_p, val_off, val_on, val_drop; 964 uint32 clear = 0x00000000; 965 966 /* check whehter the handle id is valid */ 967 if ( rport_handle_id < 0 || rport_handle_id >= GH2_E2EFC_REMOTE_PORT_NUM) { 968 LOG_ERROR(BSL_LS_BCM_PORT, 969 (BSL_META_U(unit, 970 "Invalid Hadle ID.\n"))); 971 return BCM_E_PARAM; 972 } 973 /* check whether the parameter is added or not */ 974 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 975 REG_PORT_ANY, rport_handle_id, &val_p)); 976 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 977 val_p, Vf))) { 978 LOG_ERROR(BSL_LS_BCM_PORT, 979 (BSL_META_U(unit, 980 "The port config is not added, thus can't delete"))); 981 return BCM_E_NOT_FOUND; 982 } 983 984 /* Set to zero remote port and module id */ 985 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 986 Vf, clear); 987 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 988 RMOD_PTRf, clear); 989 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 990 RMT_SRC_PORT_IDf, clear); 991 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, 992 REG_PORT_ANY, rport_handle_id, val_p)); 993 /* Set to zero xoff theshhold */ 994 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_SET_LIMITr, 995 REG_PORT_ANY, rport_handle_id, &val_off)); 996 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off, 997 PKT_SET_LIMITf, clear); 998 soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off, 999 CELL_SET_LIMITf, clear); 1000 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_SET_LIMITr, 1001 REG_PORT_ANY, rport_handle_id, val_off)); 1002 /* Set to zero xon theshhold */ 1003 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_RESET_LIMITr, 1004 REG_PORT_ANY, rport_handle_id, &val_on)); 1005 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, 1006 &val_on, PKT_RESET_LIMITf, clear); 1007 soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, 1008 &val_on, CELL_RESET_LIMITf, clear); 1009 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_RESET_LIMITr, 1010 REG_PORT_ANY, rport_handle_id, val_on)); 1011 /* Set to zero drop theshhold */ 1012 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_DISC_LIMITr, 1013 REG_PORT_ANY, rport_handle_id, 1014 &val_drop)); 1015 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, 1016 &val_drop, PKT_DISC_LIMITf, clear); 1017 soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, 1018 &val_drop, CELL_DISC_LIMITf, clear); 1019 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_DISC_LIMITr, 1020 REG_PORT_ANY, rport_handle_id, 1021 val_drop)); 1022 1023 return BCM_E_NONE; 1024 } 1025 /* 1026 * Description: 1027 * Traverse enabled remote modules that apply E2EFC mechanism. 1028 * Parameter: 1029 * unit - (IN) unit number 1030 * cb - (IN) call back function to execute 1031 * user_data - (IN) pointer to user data 1032 */ 1033 int 1034 bcmi_gh2_port_e2efc_remote_module_traverse( 1035 int unit, 1036 bcm_port_e2efc_remote_module_traverse_cb cb, 1037 void *user_data) 1038 { 1039 int i, rv, rmod_id; 1040 bcm_port_e2efc_mode_t mode; 1041 uint32 val; 1042 1043 if (user_data == NULL) { 1044 return BCM_E_PARAM; 1045 } 1046 1047 for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) { 1048 for (mode = bcmPortE2efcModeTx; mode < bcmPortE2efcModeCount; mode++) { 1049 soc_reg32_get(unit, e2efc_rmod_id_r[mode][i], 1050 REG_PORT_ANY, 0, &val); 1051 if (soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i], 1052 val, e2efc_rmod_enable[i])) { 1053 rmod_id = soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i], 1054 val, e2efc_rmod_id_f[i]); 1055 rv = cb(unit, rmod_id, mode, user_data); 1056 if (rv != BCM_E_NONE) { 1057 return rv; 1058 } 1059 } 1060 } 1061 } 1062 return BCM_E_NONE; 1063 } 1064 1065 /* 1066 * Description: 1067 * Traverse remote ports. 1068 * Parameter: 1069 * unit - (IN) unit number 1070 * cb - (IN) call back function to execute 1071 * user_data - (IN) pointer to user data 1072 */ 1073 int 1074 bcmi_gh2_port_e2efc_remote_port_traverse( 1075 int unit, 1076 bcm_port_e2efc_remote_port_traverse_cb cb, 1077 void *user_data) 1078 { 1079 int i, rv; 1080 uint32 val; 1081 1082 if (user_data == NULL) { 1083 return BCM_E_PARAM; 1084 } 1085 1086 for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) { 1087 /* check whether the E2EFC_CNT_ATTRr Vf is enabled */ 1088 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 1089 REG_PORT_ANY, i, &val)); 1090 if (soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val, Vf)) { 1091 rv = cb(unit, i, user_data); 1092 if (rv != BCM_E_NONE) { 1093 return rv; 1094 } 1095 } 1096 } 1097 1098 return BCM_E_NONE; 1099 } 1100 1101 #define BCMI_GH2_MAX_PHY_PORTS (90) 1102 /* 1103 * Description: 1104 * Force MAC loopback for Riot loopback port. 1105 * Parameter: 1106 * unit - (IN) unit number 1107 */ 1108 int 1109 bcmi_gh2_port_force_lb_set(int unit) 1110 { 1111 soc_bond_info_t *bond_info = SOC_BOND_INFO(unit); 1112 soc_info_t *si = &SOC_INFO(unit); 1113 int pport, port, loopback; 1114 1115 if (SOC_WARM_BOOT(unit)) { 1116 return BCM_E_NONE; 1117 } 1118 1119 if (!soc_feature(unit, soc_feature_untethered_otp)) { 1120 return SOC_E_NONE; 1121 } 1122 1123 /* Check Riot lb port */ 1124 for (pport = 0; pport < BCMI_GH2_MAX_PHY_PORTS; pport++) { 1125 if (SHR_BITGET(bond_info->tsc_in_loop, pport)) { 1126 port = si->port_p2l_mapping[pport]; 1127 if (port == -1) { 1128 continue; 1129 } 1130 BCM_IF_ERROR_RETURN( 1131 bcm_esw_port_loopback_get(unit, port, &loopback)); 1132 if (loopback == BCM_PORT_LOOPBACK_NONE) { 1133 BCM_IF_ERROR_RETURN( 1134 bcm_esw_port_loopback_set( 1135 unit, port, BCM_PORT_LOOPBACK_MAC)); 1136 /* Enable MAC credit generation from TSC */ 1137 BCM_IF_ERROR_RETURN( 1138 soc_phyctrl_control_set( 1139 unit, port, SOC_PHY_CONTROL_BOND_IN_PWRDN_OVERRIDE, 1)); 1140 LOG_DEBUG(BSL_LS_BCM_PORT, 1141 (BSL_META_UP(unit, port, 1142 "Set port as RIOT LB port\n"))); 1143 } else if (loopback != BCM_PORT_LOOPBACK_MAC) { 1144 LOG_WARN(BSL_LS_BCM_PORT, 1145 (BSL_META_UP(unit, port, 1146 "port should be in LB NONE/MAC.\n"))); 1147 return BCM_E_INTERNAL; 1148 } 1149 } 1150 } 1151 return BCM_E_NONE; 1152 } 1153 1154 #endif /* BCM_GREYHOUND2_SUPPORT */