xlmac.c (102469B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <soc/portmod/portmod.h> 11 #include <soc/portmod/xlmac.h> 12 #include <soc/drv.h> 13 14 #if defined(PORTMOD_PM4X10_SUPPORT) 15 16 17 #ifdef _ERR_MSG_MODULE_NAME 18 #error "_ERR_MSG_MODULE_NAME redefined" 19 #endif 20 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT 21 22 #define JUMBO_MAXSZ 0x3fe8 /* Max legal value (per regsfile) */ 23 24 /* 25 * version device 26 * 0xA035 Apache, Jericho, QAX, QMX 27 * 0xA036 TD2P 28 * 0xA037 Jericho+, Apache 29 * 0xA041 TH2 30 */ 31 typedef enum { 32 XLMAC_VERSION_A035 = 0xA035, 33 XLMAC_VERSION_A036 = 0xA036, 34 XLMAC_VERSION_A037 = 0xA037, 35 XLMAC_VERSION_A041 = 0xA041 36 }xlmac_version_t; 37 38 #define XLMAC_AVERAGE_IPG_DEFAULT 12 39 #define XLMAC_AVERAGE_IPG_HIGIG 8 40 41 #define XLMAC_RUNT_THRESHOLD_ETH 64 42 #define XLMAC_RUNT_THRESHOLD_HIGIG 72 43 #define XLMAC_RUNT_THRESHOLD_HIGIG2 76 44 45 /* 46 * WAN mode throttling 47 * THROT_10G_TO_5G: throt_num=21 throt_denom=21 48 * THROT_10G_TO_2P5G: throt_num=63 throt_denom=21 49 */ 50 #define XLMAC_THROT_10G_TO_5G 256 51 #define XLMAC_THROT_10G_TO_2P5G 257 52 53 #ifdef BCM_APACHE_SUPPORT 54 55 int soc_apache_xlmac_b0_ports[] = { 56 0, /* PHY port 0 is invalid */ 57 1, 1, 1, 1, /* PHY ports 1-4: PM 4x10 inst 0 */ 58 1, 1, 1, 1, /* PHY ports 5-8: PM 4x10 inst 1 */ 59 1, 1, 1, 1, /* PHY ports 9-12: PM 4x10 inst 2 */ 60 1, 1, 1, 1, /* PHY ports 13-16: PM 4x10 inst 3 */ 61 0, 0, 0, 0, /* PHY ports 17-20: PM 12x10 inst 0.0 */ 62 0, 0, 0, 0, /* PHY ports 21-24: PM 12x10 inst 0.1 */ 63 0, 0, 0, 0, /* PHY ports 25-28: PM 12x10 inst 0.2 */ 64 0, 0, 0, 0, /* PHY ports 29-32: PM 4x25 inst 0 */ 65 0, 0, 0, 0, /* PHY ports 33-36: PM 4x25 inst 1 */ 66 1, 1, 1, 1, /* PHY ports 37-40: PM 4x10 inst 4 */ 67 1, 1, 1, 1, /* PHY ports 41-44: PM 4x10 inst 5 */ 68 1, 1, 1, 1, /* PHY ports 45-48: PM 4x10 inst 6 */ 69 1, 1, 1, 1, /* PHY ports 49-52: PM 4x10 inst 7 */ 70 0, 0, 0, 0, /* PHY ports 53-56: PM 12x10 inst 1.0 */ 71 0, 0, 0, 0, /* PHY ports 57-60: PM 12x10 inst 1.1 */ 72 0, 0, 0, 0, /* PHY ports 61-64: PM 12x10 inst 1.2 */ 73 0, 0, 0, 0, /* PHY ports 65-68: PM 4x25 inst 2 */ 74 0, 0, 0, 0, /* PHY ports 69-72: PM 4x25 inst 3 */ 75 }; 76 77 78 int soc_apache_port_is_xlb0_port(int unit, int port) 79 { 80 if (soc_feature(unit, soc_feature_xlportb0)) { 81 return (soc_apache_xlmac_b0_ports[SOC_INFO(unit).port_l2p_mapping[port]]); 82 } else { 83 return 0; 84 } 85 } 86 87 #define RD_XLMAC(name, unit, port, val) do { \ 88 if (soc_apache_port_is_xlb0_port(unit, port)) { \ 89 SOC_IF_ERROR_RETURN(READ_XLMAC_B0_##name(unit, port, val)); \ 90 } else { \ 91 SOC_IF_ERROR_RETURN(READ_XLMAC_##name(unit, port, val)); \ 92 } \ 93 } while(0) 94 95 #define WR_XLMAC(name, unit, port, val) do { \ 96 if (soc_apache_port_is_xlb0_port(unit, port)) { \ 97 SOC_IF_ERROR_RETURN(WRITE_XLMAC_B0_##name(unit, port, val)); \ 98 } else { \ 99 SOC_IF_ERROR_RETURN(WRITE_XLMAC_##name(unit, port, val)); \ 100 } \ 101 } while(0) 102 103 104 #else 105 106 #define RD_XLMAC(name, unit, port, val) SOC_IF_ERROR_RETURN(READ_XLMAC_##name(unit, port, val)); 107 #define WR_XLMAC(name, unit, port, val) SOC_IF_ERROR_RETURN(WRITE_XLMAC_##name(unit, port, val)); 108 109 #endif 110 /* 111 * Functions to Review for Coverage: 112 * xlmac_loopback_set 113 * xlmac_encap_set 114 * 115 * Fucntions to be added (may be) 116 * mac_xl_egress_queue_drain 117 * mac_xl_control_set 118 * mac_xl_control_get 119 * mac_xl_ability_local_get 120 */ 121 122 #define XLMAC_SPEED_10 0x0 123 #define XLMAC_SPEED_100 0x1 124 #define XLMAC_SPEED_1000 0x2 125 #define XLMAC_SPEED_2500 0x3 126 #define XLMAC_SPEED_10000 0x4 127 128 #ifdef BCM_TIMESYNC_SUPPORT 129 struct { 130 int speed; 131 uint32 clock_rate; 132 }_xlmac_clock_rate[] = { 133 { 40000, 644 }, 134 { 20000, 322 }, 135 { 10000, 161 }, 136 { 5000, 390 }, 137 { 2500, 390 }, 138 { 1000, 390 }, 139 { 0, 390 }, 140 }; 141 142 void 143 _xlmac_speed_to_clock_rate(int unit, soc_port_t port, int speed, 144 uint32 *clock_rate) 145 { 146 int idx; 147 for (idx = 0; 148 idx < sizeof(_xlmac_clock_rate) / sizeof(_xlmac_clock_rate[0]); 149 idx++) { 150 if (speed >=_xlmac_clock_rate[idx].speed) { 151 *clock_rate = _xlmac_clock_rate[idx].clock_rate; 152 return; 153 } 154 } 155 *clock_rate = 0; 156 } 157 #endif 158 159 STATIC 160 int _xlmac_version_get(int unit, soc_port_t port, int32 *version) 161 { 162 uint64 reg_val; 163 164 if (!SOC_REG_IS_VALID(unit, XLMAC_VERSION_IDr)) { 165 *version = -1; 166 } 167 else { 168 RD_XLMAC(VERSION_IDr, unit, port, ®_val); 169 *version = soc_reg64_field32_get(unit, XLMAC_VERSION_IDr, reg_val, XLMAC_VERSIONf); 170 } 171 172 return (SOC_E_NONE); 173 } 174 175 int xlmac_enable_set(int unit, soc_port_t port, int flags, int enable) 176 { 177 uint64 reg_val, orig_reg_val; 178 uint32 soft_reset; 179 180 RD_XLMAC(CTRLr, unit, port, ®_val); 181 182 orig_reg_val = reg_val; 183 184 if (flags & XLMAC_ENABLE_SET_FLAGS_TX_EN) { 185 soc_reg64_field32_set(unit, XLMAC_CTRLr, ®_val, TX_ENf, enable ? 1 : 0); 186 } 187 if (flags & XLMAC_ENABLE_SET_FLAGS_RX_EN) { 188 soc_reg64_field32_set(unit, XLMAC_CTRLr, ®_val, RX_ENf, enable ? 1 : 0); 189 } 190 if (!(flags & XLMAC_ENABLE_SET_FLAGS_RX_EN) && !(flags & XLMAC_ENABLE_SET_FLAGS_TX_EN)) { 191 soc_reg64_field32_set(unit, XLMAC_CTRLr, ®_val, TX_ENf, enable ? 1 : 0); 192 soc_reg64_field32_set(unit, XLMAC_CTRLr, ®_val, RX_ENf, enable ? 1 : 0); 193 } 194 /* write only if value changed */ 195 if(COMPILER_64_EQ(reg_val, orig_reg_val)) { 196 soft_reset = 197 soc_reg64_field32_get(unit, XLMAC_CTRLr, reg_val, SOFT_RESETf); 198 199 if (enable || (!enable && soft_reset)) { 200 return (SOC_E_NONE); 201 } 202 } 203 204 if (!(flags & XLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS)) { 205 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, SOFT_RESETf, enable ? 0 : 1); 206 } 207 WR_XLMAC(CTRLr, unit, port, reg_val); 208 209 return (SOC_E_NONE); 210 } 211 212 213 int xlmac_discard_set(int unit, soc_port_t port, int discard) 214 { 215 uint64 rval; 216 217 RD_XLMAC(TX_CTRLr, unit, port, &rval); 218 219 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &rval, DISCARDf, discard); 220 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &rval, EP_DISCARDf, discard); 221 222 WR_XLMAC(TX_CTRLr, unit, port, rval); 223 224 return (SOC_E_NONE); 225 } 226 227 int xlmac_enable_get(int unit, soc_port_t port, int flags, int *enable) 228 { 229 uint64 reg_val; 230 231 RD_XLMAC(CTRLr, unit, port, ®_val); 232 233 if (flags & XLMAC_ENABLE_SET_FLAGS_TX_EN) { 234 *enable = soc_reg64_field32_get(unit, XLMAC_CTRLr, reg_val, TX_ENf); 235 } else { 236 *enable = soc_reg64_field32_get(unit, XLMAC_CTRLr, reg_val, RX_ENf); 237 } 238 239 return (SOC_E_NONE); 240 } 241 242 243 int xlmac_soft_reset_set(int unit, soc_port_t port, int enable) 244 { 245 uint64 reg_val; 246 247 RD_XLMAC(CTRLr, unit, port, ®_val); 248 249 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, 250 SOFT_RESETf, enable? 1 : 0); 251 WR_XLMAC(CTRLr, unit, port, reg_val); 252 253 return (SOC_E_NONE); 254 } 255 256 257 int xlmac_soft_reset_get(int unit, soc_port_t port, int *enable) 258 { 259 uint64 reg_val; 260 261 RD_XLMAC(CTRLr, unit, port, ®_val); 262 263 *enable = soc_reg64_field32_get(unit, XLMAC_CTRLr, reg_val, SOFT_RESETf)?1:0; 264 return (SOC_E_NONE); 265 } 266 267 /* 268 * Function: 269 * xlmac_timestamp_byte_adjust_set 270 * Purpose: 271 * Set timestamp byte adjust values. 272 * Parameters: 273 * unit - XGS unit #. 274 * port - Port number on unit. 275 * flags - CLMAC_TIMESTAMP_BYTE_ADJUST_XX, for special operations. 276 * speed - data rate of the port. 277 * Returns: 278 * SOC_E_XXX 279 */ 280 int 281 xlmac_timestamp_byte_adjust_set(int unit, soc_port_t port, int flags, int speed) 282 { 283 uint64 ctrl; 284 uint32 byte_adjust = 0; 285 int32 version; 286 soc_reg_t byte_adjust_reg = -1; 287 288 if (100 == speed) { 289 byte_adjust = 80; 290 } else if (1000 == speed) { 291 byte_adjust = 8; 292 } else if (2500 == speed) { 293 byte_adjust = 3; 294 } else if (10000 == speed) { 295 byte_adjust = 1; 296 } 297 298 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 299 if (SOC_REG_PORT_VALID(unit, XLMAC_B0_TIMESTAMP_BYTE_ADJUSTr, port) && 300 (version == XLMAC_VERSION_A037)) { 301 byte_adjust_reg = XLMAC_B0_TIMESTAMP_BYTE_ADJUSTr; 302 } else if (SOC_REG_PORT_VALID(unit, XLMAC_TIMESTAMP_BYTE_ADJUSTr, port)) { 303 byte_adjust_reg = XLMAC_TIMESTAMP_BYTE_ADJUSTr; 304 } 305 306 if (byte_adjust_reg != -1) { 307 if ((speed > 10000) || (flags == XLMAC_TIMESTAMP_BYTE_ADJUST_CLEAR)) { 308 /* This shouldn't be enabled when speed is more than 10G */ 309 RD_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl); 310 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 311 TX_TIMER_BYTE_ADJUSTf, 0); 312 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 313 TX_TIMER_BYTE_ADJUST_ENf, 0); 314 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 315 RX_TIMER_BYTE_ADJUSTf, 0); 316 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 317 RX_TIMER_BYTE_ADJUST_ENf, 0); 318 WR_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl); 319 } else { 320 RD_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl); 321 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 322 TX_TIMER_BYTE_ADJUSTf, byte_adjust); 323 WR_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl); 324 325 RD_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl); 326 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 327 TX_TIMER_BYTE_ADJUST_ENf, 1); 328 WR_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl); 329 330 RD_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl); 331 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 332 RX_TIMER_BYTE_ADJUSTf, byte_adjust); 333 WR_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl); 334 335 RD_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl); 336 soc_reg64_field32_set(unit, byte_adjust_reg, &ctrl, 337 RX_TIMER_BYTE_ADJUST_ENf, 1); 338 WR_XLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl); 339 } 340 } 341 342 return SOC_E_NONE; 343 } 344 345 /* 346 * Function: 347 * xlmac_timestamp_delay_set 348 * Purpose: 349 * Set Timestamp delay for one-step to account for lane and pipeline delay. 350 * Parameters: 351 * unit - XGS unit #. 352 * port - Port number on unit. 353 * speed - Speed 354 * Returns: 355 * SOC_E_XXX 356 */ 357 int xlmac_timestamp_delay_set(int unit, soc_port_t port, 358 portmod_port_ts_adjust_t ts_adjust, int speed) 359 { 360 uint64 ctrl; 361 int osts_delay = 0; 362 int tsts_delay = 0; 363 364 if (SOC_REG_IS_VALID(unit, XLMAC_TIMESTAMP_ADJUSTr)) { 365 366 #ifdef BCM_TIMESYNC_SUPPORT 367 uint32 clk_rate, tx_clk_ns; 368 int divisor; 369 _xlmac_speed_to_clock_rate(unit, port, speed, &clk_rate); 370 371 /* Tx clock rate for single/dual/quad phy mode */ 372 if ((speed >= 5000) && (speed <= 40000)) { 373 divisor = speed > 20000 ? 1 : speed > 10000 ? 2 : 4; 374 /* tx clock rate in ns */ 375 tx_clk_ns = ((1000 / clk_rate) / divisor); 376 } else { 377 /* Same tx clk rate for < 10G for all phy modes*/ 378 tx_clk_ns = 1000 / clk_rate; 379 } 380 #endif 381 382 /* 383 * MAC pipeline delay for XGMII/XGMII mode is: 384 * = (6 * TX line clock period) + (Timestamp clock period) 385 */ 386 /* signed value of pipeline delay in ns */ 387 if (ts_adjust.osts_adjust > 0) { 388 osts_delay = ts_adjust.osts_adjust; 389 } 390 #ifdef BCM_TIMESYNC_SUPPORT 391 else { 392 osts_delay = SOC_TIMESYNC_PLL_CLOCK_NS(unit) + ((12 * tx_clk_ns ) / 2); 393 } 394 #endif 395 RD_XLMAC(TIMESTAMP_ADJUSTr, unit, port, &ctrl); 396 soc_reg64_field32_set(unit, XLMAC_TIMESTAMP_ADJUSTr, &ctrl, 397 TS_OSTS_ADJUSTf, osts_delay); 398 WR_XLMAC(TIMESTAMP_ADJUSTr, unit, port, ctrl); 399 400 /* (2.5 TSC_CLK period + 1 TS_CLK period */ 401 if (ts_adjust.tsts_adjust > 0) { 402 tsts_delay = ts_adjust.tsts_adjust; 403 } 404 #ifdef BCM_TIMESYNC_SUPPORT 405 else { 406 tsts_delay = SOC_TIMESYNC_PLL_CLOCK_NS(unit) + ((5 * tx_clk_ns ) / 2); 407 } 408 #endif 409 RD_XLMAC(TIMESTAMP_ADJUSTr, unit, port, &ctrl); 410 soc_reg64_field32_set(unit, XLMAC_TIMESTAMP_ADJUSTr, &ctrl, 411 TS_TSTS_ADJUSTf, tsts_delay); 412 WR_XLMAC(TIMESTAMP_ADJUSTr, unit, port, ctrl); 413 } 414 415 return SOC_E_NONE; 416 } 417 418 int xlmac_timestamp_delay_get(int unit, soc_port_t port, 419 portmod_port_ts_adjust_t *ts_adjust) 420 { 421 uint64 reg_val; 422 423 if (SOC_REG_IS_VALID(unit, XLMAC_TIMESTAMP_ADJUSTr)) { 424 RD_XLMAC(TIMESTAMP_ADJUSTr, unit, port, ®_val); 425 ts_adjust->osts_adjust = soc_reg64_field32_get (unit, XLMAC_TIMESTAMP_ADJUSTr, reg_val, 426 TS_OSTS_ADJUSTf); 427 ts_adjust->tsts_adjust = soc_reg64_field32_get (unit, XLMAC_TIMESTAMP_ADJUSTr, reg_val, 428 TS_TSTS_ADJUSTf); 429 } else { 430 return SOC_E_UNAVAIL; 431 } 432 433 return SOC_E_NONE; 434 } 435 436 437 int xlmac_speed_set(int unit, soc_port_t port, int flags, int speed) 438 { 439 uint32 spd_fld; 440 int enable, enable_flags = 0; 441 uint64 rval; 442 uint32 reg32_val = 0, fault = 0; 443 444 if (speed >= 10000) /* 10G Speed */ 445 spd_fld = 4; 446 else if (speed >= 2500) /* 2.5G Speed */ 447 spd_fld = 3; 448 else if (speed >= 1000) /* 1G Speed */ 449 spd_fld = 2; 450 else if (speed >= 100) /* 100M Speed */ 451 spd_fld = 1; 452 else 453 spd_fld = 0; /* 10M Speed */ 454 455 SOC_IF_ERROR_RETURN(xlmac_enable_get(unit, port, 0, &enable)); 456 457 /* disable before updating the speed */ 458 if (enable) { 459 if (flags & XLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS) { 460 enable_flags |= XLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS; 461 } 462 SOC_IF_ERROR_RETURN(xlmac_enable_set(unit, port, enable_flags, 0)); 463 } 464 465 /* Update the speed */ 466 RD_XLMAC(MODEr, unit ,port, &rval); 467 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval, SPEED_MODEf, spd_fld); 468 WR_XLMAC(MODEr, unit ,port, rval); 469 470 /* 471 * Set REMOTE_FAULT/LOCAL_FAULT for XL ports, 472 * else HW Linkscan interrupt would be suppressed. 473 */ 474 if (SOC_REG_IS_VALID(unit, XLPORT_FAULT_LINK_STATUSr)) { 475 fault = speed <= 1000 ? 0 : 1; 476 477 SOC_IF_ERROR_RETURN(READ_XLPORT_FAULT_LINK_STATUSr(unit, port, ®32_val)); 478 soc_reg_field_set(unit, XLPORT_FAULT_LINK_STATUSr, ®32_val, 479 REMOTE_FAULTf, fault); 480 soc_reg_field_set(unit, XLPORT_FAULT_LINK_STATUSr, ®32_val, 481 LOCAL_FAULTf, fault); 482 SOC_IF_ERROR_RETURN(WRITE_XLPORT_FAULT_LINK_STATUSr(unit, port, reg32_val)); 483 } 484 485 if (enable) { 486 if (flags & XLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS) { 487 enable_flags |= XLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS; 488 } 489 SOC_IF_ERROR_RETURN(xlmac_enable_set(unit, port, enable_flags, 1)); 490 } 491 492 return SOC_E_NONE; 493 } 494 495 496 int xlmac_loopback_set (int unit, soc_port_t port, int enable) 497 { 498 uint64 reg_val; 499 500 RD_XLMAC(CTRLr, unit, port, ®_val); 501 502 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, 503 LOCAL_LPBKf, enable ? 1: 0); 504 WR_XLMAC(CTRLr, unit, port, reg_val); 505 506 return(SOC_E_NONE); 507 } 508 509 int xlmac_loopback_get (int unit, soc_port_t port, int *enable) 510 { 511 uint64 reg_val; 512 513 RD_XLMAC(CTRLr, unit, port, ®_val); 514 515 *enable = soc_reg64_field32_get (unit, XLMAC_CTRLr, reg_val, 516 LOCAL_LPBKf); 517 return(SOC_E_NONE); 518 } 519 520 int xlmac_tx_enable_set (int unit, soc_port_t port, int enable) 521 { 522 uint64 reg_val; 523 524 RD_XLMAC(CTRLr, unit, port, ®_val); 525 526 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, 527 TX_ENf, enable ? 1: 0); 528 WR_XLMAC(CTRLr, unit, port, reg_val); 529 530 return(SOC_E_NONE); 531 } 532 533 int xlmac_tx_enable_get (int unit, soc_port_t port, int *enable) 534 { 535 uint64 reg_val; 536 537 RD_XLMAC(CTRLr, unit, port, ®_val); 538 539 *enable = soc_reg64_field32_get (unit, XLMAC_CTRLr, reg_val, 540 TX_ENf); 541 542 return(SOC_E_NONE); 543 } 544 545 int xlmac_rx_enable_set (int unit, soc_port_t port, int enable) 546 { 547 uint64 reg_val; 548 549 RD_XLMAC(CTRLr, unit, port, ®_val); 550 551 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, 552 RX_ENf, enable ? 1: 0); 553 WR_XLMAC(CTRLr, unit, port, reg_val); 554 555 return(SOC_E_NONE); 556 } 557 558 int xlmac_rx_enable_get (int unit, soc_port_t port, int *enable) 559 { 560 uint64 reg_val; 561 562 RD_XLMAC(CTRLr, unit, port, ®_val); 563 564 *enable = soc_reg64_field32_get (unit, XLMAC_CTRLr, reg_val, 565 RX_ENf); 566 567 return(SOC_E_NONE); 568 } 569 570 /* 571 * Function: 572 * _mac_xl_port_mode_update 573 * Purpose: 574 * Set the XLMAC port encapsulation mode. 575 * Parameters: 576 * unit - XGS unit #. 577 * port - XGS port # on unit. 578 * hg_mode - SOC HG encap modes. value={HG/HG2/HG2-LITE} 579 * Returns: 580 * SOC_E_XXX 581 */ 582 STATIC int 583 _xlmac_port_mode_update(int unit, soc_port_t port, int hg_mode) 584 { 585 uint64 tx_ctrl, rx_ctrl, mac_ctrl, mac_ctrl_orig; 586 587 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 588 RD_XLMAC(RX_CTRLr, unit, port, &rx_ctrl); 589 RD_XLMAC(TX_CTRLr, unit, port, &tx_ctrl); 590 591 mac_ctrl_orig = mac_ctrl; 592 593 /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */ 594 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, RX_ENf, 0); 595 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, TX_ENf, 0); 596 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 597 598 if (hg_mode != SOC_ENCAP_IEEE) { /* HiGig Mode */ 599 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl_orig, XGMII_IPG_CHECK_DISABLEf, 1); 600 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf, XLMAC_AVERAGE_IPG_HIGIG); 601 } else { 602 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl_orig, XGMII_IPG_CHECK_DISABLEf, 0); 603 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf, XLMAC_AVERAGE_IPG_DEFAULT); 604 } 605 606 WR_XLMAC(RX_CTRLr, unit, port, rx_ctrl); 607 WR_XLMAC(TX_CTRLr, unit, port, tx_ctrl); 608 WR_XLMAC(CTRLr, unit, port, mac_ctrl_orig); /* restore mac ctrl */ 609 610 return (SOC_E_NONE); 611 } 612 613 614 int xlmac_encap_set(int unit, soc_port_t port, int flags, portmod_encap_t encap) 615 { 616 uint64 reg_val; 617 uint32 encap_val= 0, no_sop_for_crc_hg = 0, ext_hi2=0; 618 int enable, enable_flags = 0; 619 620 switch(encap){ 621 case SOC_ENCAP_IEEE: 622 encap_val = 0; 623 break; 624 case SOC_ENCAP_HIGIG: 625 encap_val = 1; 626 no_sop_for_crc_hg = 627 (flags & XLMAC_ENCAP_SET_FLAGS_NO_SOP_FOR_CRC_HG)?1:0; 628 break; 629 case SOC_ENCAP_HIGIG2: 630 case SOC_ENCAP_HIGIG2_LITE: 631 encap_val = 2; 632 no_sop_for_crc_hg = 633 (flags & XLMAC_ENCAP_SET_FLAGS_NO_SOP_FOR_CRC_HG)?1:0; 634 ext_hi2 = (flags & XLMAC_ENCAP_SET_FLAGS_EXTENDED_HIGIG2_EN) ? 1 : 0; 635 break; 636 case SOC_ENCAP_SOP_ONLY: 637 encap_val = 5; 638 break; 639 default: 640 LOG_ERROR(BSL_LS_SOC_XLMAC, 641 (BSL_META_U(unit, "illegal encap mode %d"), encap)); 642 return (SOC_E_PARAM); 643 break; 644 } 645 646 SOC_IF_ERROR_RETURN(xlmac_enable_get(unit, port, 0, &enable)); 647 648 if (enable) { 649 if (flags & XLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS) { 650 enable_flags |= XLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS; 651 } 652 /* Turn off TX/RX enable */ 653 SOC_IF_ERROR_RETURN(xlmac_enable_set(unit, port, enable_flags, 0)); 654 } 655 656 #ifdef BCM_GREYHOUND_SUPPORT 657 if (SOC_IS_GREYHOUND(unit)) { 658 /* Greyhound need mode update for all encap mode change! */ 659 SOC_IF_ERROR_RETURN(_xlmac_port_mode_update(unit, port, encap)); 660 661 /* GH specific : for HG2-LITE is sepecial case in PortMacro(PM). 662 * - encap mode in PM must be IEEE (out of PM must be HG2-LITE) 663 */ 664 encap_val = (encap == SOC_ENCAP_HIGIG2_LITE) ? 0 : encap_val; 665 } else 666 #endif 667 if ((IS_E_PORT(unit, port) && encap != SOC_ENCAP_IEEE) || 668 (IS_ST_PORT(unit, port) && encap == SOC_ENCAP_IEEE)) { 669 670 SOC_IF_ERROR_RETURN(_xlmac_port_mode_update(unit, port, encap)); 671 } 672 673 RD_XLMAC(MODEr, unit, port, ®_val); 674 675 soc_reg64_field32_set (unit, XLMAC_MODEr, ®_val, HDR_MODEf, encap_val); 676 soc_reg64_field32_set (unit, XLMAC_MODEr, ®_val, NO_SOP_FOR_CRC_HGf, 677 no_sop_for_crc_hg); 678 679 WR_XLMAC(MODEr, unit, port, reg_val); 680 681 /* Enable HiGig2 Mode */ 682 if(encap == SOC_ENCAP_HIGIG2) { 683 RD_XLMAC(CTRLr, unit, port, ®_val); 684 685 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, 686 EXTENDED_HIG2_ENf, ext_hi2); 687 WR_XLMAC(CTRLr, unit, port, reg_val); 688 689 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 690 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, ®_val, RUNT_THRESHOLDf, XLMAC_RUNT_THRESHOLD_HIGIG2); 691 WR_XLMAC(RX_CTRLr, unit, port, reg_val); 692 } else if (encap == SOC_ENCAP_HIGIG) { 693 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 694 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, ®_val, RUNT_THRESHOLDf, XLMAC_RUNT_THRESHOLD_HIGIG); 695 WR_XLMAC(RX_CTRLr, unit, port, reg_val); 696 } else { 697 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 698 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, ®_val, RUNT_THRESHOLDf, XLMAC_RUNT_THRESHOLD_ETH); 699 WR_XLMAC(RX_CTRLr, unit, port, reg_val); 700 } 701 702 if (enable) { 703 if (flags & XLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS) { 704 enable_flags |= XLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS; 705 } 706 SOC_IF_ERROR_RETURN(xlmac_enable_set(unit, port, enable_flags, 1)); 707 } 708 709 return (SOC_E_NONE); 710 } 711 712 int xlmac_encap_get(int unit, soc_port_t port, int *flags, portmod_encap_t *encap) 713 { 714 uint64 reg_val; 715 uint32 fld_val; 716 717 RD_XLMAC(MODEr, unit, port, ®_val); 718 fld_val = soc_reg64_field32_get(unit, XLMAC_MODEr, reg_val, HDR_MODEf); 719 720 switch(fld_val){ 721 case 0: 722 *encap = SOC_ENCAP_IEEE; 723 break; 724 case 1: 725 *encap = SOC_ENCAP_HIGIG; 726 break; 727 case 2: 728 *encap = SOC_ENCAP_HIGIG2; 729 break; 730 case 5: 731 *encap = SOC_ENCAP_SOP_ONLY; 732 break; 733 default: 734 return(SOC_E_PARAM); 735 break; 736 } 737 738 if((*encap == SOC_ENCAP_HIGIG) || (*encap == SOC_ENCAP_HIGIG2)){ 739 fld_val = soc_reg64_field32_get(unit, XLMAC_MODEr, reg_val, 740 NO_SOP_FOR_CRC_HGf); 741 if(fld_val) { 742 (*flags) |= XLMAC_ENCAP_SET_FLAGS_NO_SOP_FOR_CRC_HG; 743 } 744 } 745 746 if(*encap == SOC_ENCAP_HIGIG2){ 747 RD_XLMAC(CTRLr, unit, port, ®_val); 748 fld_val = soc_reg64_field32_get(unit, XLMAC_CTRLr, 749 reg_val, EXTENDED_HIG2_ENf); 750 if(fld_val) { 751 (*flags) |= XLMAC_ENCAP_SET_FLAGS_EXTENDED_HIGIG2_EN; 752 } 753 } 754 755 756 return (SOC_E_NONE); 757 } 758 759 760 int xlmac_rx_max_size_set(int unit, soc_port_t port, int value) 761 { 762 uint64 reg_val; 763 764 RD_XLMAC(RX_MAX_SIZEr, unit, port, ®_val); 765 766 soc_reg64_field32_set (unit, XLMAC_RX_MAX_SIZEr, ®_val, 767 RX_MAX_SIZEf, value); 768 WR_XLMAC(RX_MAX_SIZEr, unit, port, reg_val); 769 770 return (SOC_E_NONE); 771 } 772 773 int xlmac_rx_max_size_get(int unit, soc_port_t port, int *value) 774 { 775 uint64 reg_val; 776 777 RD_XLMAC(RX_MAX_SIZEr, unit, port, ®_val); 778 *value = (int)soc_reg64_field32_get (unit, XLMAC_RX_MAX_SIZEr, 779 reg_val, RX_MAX_SIZEf); 780 return (SOC_E_NONE); 781 } 782 783 int xlmac_pad_size_set(int unit, soc_port_t port, int value) 784 { 785 uint64 reg_val; 786 787 RD_XLMAC(TX_CTRLr, unit, port, ®_val); 788 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, ®_val, PAD_ENf, value ? 1 : 0); 789 if(value){ 790 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, ®_val, PAD_THRESHOLDf, value); 791 } 792 WR_XLMAC(TX_CTRLr, unit, port, reg_val); 793 794 return (SOC_E_NONE); 795 } 796 797 int xlmac_pad_size_get(int unit, soc_port_t port, int *value) 798 { 799 uint64 reg_val; 800 int pad_en; 801 802 RD_XLMAC(TX_CTRLr, unit, port, ®_val); 803 pad_en = soc_reg64_field32_get(unit, XLMAC_TX_CTRLr, reg_val, PAD_ENf); 804 if(!pad_en){ 805 *value = 0; 806 } 807 else{ 808 *value = soc_reg64_field32_get(unit, XLMAC_TX_CTRLr, reg_val, PAD_THRESHOLDf); 809 } 810 811 return (SOC_E_NONE); 812 } 813 814 int xlmac_runt_threshold_set(int unit, soc_port_t port, int value) 815 { 816 uint64 reg_val; 817 818 if (value > 96) { 819 LOG_VERBOSE(BSL_LS_SOC_COMMON, 820 (BSL_META_U(unit, 821 "runt size should be small than 96. got %d"), value)); 822 return (SOC_E_PARAM); 823 } 824 825 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 826 827 soc_reg64_field32_set (unit, XLMAC_RX_CTRLr, ®_val, 828 RUNT_THRESHOLDf, value); 829 830 WR_XLMAC(RX_CTRLr, unit, port, reg_val); 831 return (SOC_E_NONE); 832 } 833 834 int xlmac_runt_threshold_get(int unit, soc_port_t port, int *value) 835 { 836 uint64 reg_val; 837 838 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 839 *value = (int)soc_reg64_field32_get (unit, XLMAC_RX_CTRLr, 840 reg_val, RUNT_THRESHOLDf); 841 return (SOC_E_NONE); 842 } 843 844 int xlmac_strict_preamble_set(int unit, soc_port_t port, int value) 845 { 846 uint64 reg_val; 847 848 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 849 soc_reg64_field32_set (unit, XLMAC_RX_CTRLr, ®_val, 850 STRICT_PREAMBLEf, value); 851 WR_XLMAC(RX_CTRLr, unit, port, reg_val); 852 853 return (SOC_E_NONE); 854 } 855 856 int xlmac_strict_preamble_get(int unit, soc_port_t port, int *value) 857 { 858 uint64 reg_val; 859 860 RD_XLMAC(RX_CTRLr, unit, port, ®_val); 861 *value = (int)soc_reg64_field32_get (unit, XLMAC_RX_CTRLr, 862 reg_val, STRICT_PREAMBLEf); 863 return (SOC_E_NONE); 864 } 865 866 int xlmac_rx_vlan_tag_set (int unit, soc_port_t port, 867 int outer_vlan_tag, int inner_vlan_tag) 868 { 869 uint64 reg_val; 870 871 COMPILER_64_ZERO(reg_val); 872 873 RD_XLMAC(RX_VLAN_TAGr, unit, port, ®_val); 874 875 if(inner_vlan_tag == -1) { 876 soc_reg64_field32_set (unit, XLMAC_RX_VLAN_TAGr, ®_val, 877 INNER_VLAN_TAG_ENABLEf, 0); 878 } else { 879 soc_reg64_field32_set (unit, XLMAC_RX_VLAN_TAGr, ®_val, 880 INNER_VLAN_TAGf, inner_vlan_tag); 881 soc_reg64_field32_set (unit, XLMAC_RX_VLAN_TAGr, ®_val, 882 INNER_VLAN_TAG_ENABLEf, 1); 883 } 884 885 if(outer_vlan_tag == -1) { 886 soc_reg64_field32_set (unit, XLMAC_RX_VLAN_TAGr, ®_val, 887 OUTER_VLAN_TAG_ENABLEf, 0); 888 } else { 889 soc_reg64_field32_set (unit, XLMAC_RX_VLAN_TAGr, ®_val, 890 OUTER_VLAN_TAGf, outer_vlan_tag); 891 soc_reg64_field32_set (unit, XLMAC_RX_VLAN_TAGr, ®_val, 892 OUTER_VLAN_TAG_ENABLEf, 1); 893 } 894 895 WR_XLMAC(RX_VLAN_TAGr, unit, port, reg_val); 896 return (SOC_E_NONE); 897 } 898 899 900 int xlmac_rx_vlan_tag_get (int unit, soc_port_t port, 901 int *outer_vlan_tag, int *inner_vlan_tag) 902 { 903 uint64 reg_val; 904 uint32 enable = 0; 905 906 COMPILER_64_ZERO(reg_val); 907 908 RD_XLMAC(RX_VLAN_TAGr, unit, port, ®_val); 909 910 enable = soc_reg64_field32_get (unit, XLMAC_RX_VLAN_TAGr, reg_val, 911 INNER_VLAN_TAG_ENABLEf); 912 913 *inner_vlan_tag = enable ? 914 soc_reg64_field32_get (unit, XLMAC_RX_VLAN_TAGr, 915 reg_val, INNER_VLAN_TAGf) : -1; 916 917 enable = soc_reg64_field32_get (unit, XLMAC_RX_VLAN_TAGr, reg_val, 918 OUTER_VLAN_TAG_ENABLEf); 919 920 *outer_vlan_tag = enable ? soc_reg64_field32_get(unit, XLMAC_RX_VLAN_TAGr, 921 reg_val, OUTER_VLAN_TAGf) : -1; 922 return (SOC_E_NONE); 923 } 924 925 926 int xlmac_sw_link_status_select_set(int unit, soc_port_t port, int enable) 927 { 928 uint64 reg_val; 929 930 RD_XLMAC(CTRLr, unit, port, ®_val); 931 932 soc_reg64_field32_set (unit, XLMAC_CTRLr, ®_val, 933 LINK_STATUS_SELECTf, enable); 934 935 WR_XLMAC(CTRLr, unit, port, reg_val); 936 return (SOC_E_NONE); 937 } 938 939 int xlmac_sw_link_status_select_get(int unit, soc_port_t port, int *enable) 940 { 941 uint64 reg_val; 942 943 RD_XLMAC(CTRLr, unit, port, ®_val); 944 945 *enable = (int)soc_reg64_field32_get (unit, XLMAC_CTRLr, reg_val, 946 LINK_STATUS_SELECTf); 947 return (SOC_E_NONE); 948 } 949 950 int xlmac_sw_link_status_set(int unit, soc_port_t port, int link) 951 { 952 uint64 reg_val; 953 954 RD_XLMAC(CTRLr, unit, port, ®_val); 955 956 soc_reg64_field32_set(unit, XLMAC_CTRLr, ®_val, SW_LINK_STATUSf, link); 957 WR_XLMAC(CTRLr, unit, port, reg_val); 958 959 return (SOC_E_NONE); 960 } 961 962 int xlmac_rx_mac_sa_set(int unit, soc_port_t port, sal_mac_addr_t mac) 963 { 964 uint64 mac_addr; 965 966 COMPILER_64_ZERO(mac_addr); 967 968 COMPILER_64_SET(mac_addr, _shr_uint16_read(&mac[0]), _shr_uint32_read(&mac[2])); 969 970 WR_XLMAC(RX_MAC_SAr, unit, port, mac_addr); 971 972 return (SOC_E_NONE); 973 } 974 975 int xlmac_rx_mac_sa_get(int unit, soc_port_t port, sal_mac_addr_t mac) 976 { 977 uint64 rval64, field64; 978 uint32 values[2]; 979 980 RD_XLMAC(RX_MAC_SAr, unit, port, &rval64); 981 field64 = soc_reg64_field_get(unit, XLMAC_RX_MAC_SAr, rval64, RX_SAf); 982 983 values[0] = COMPILER_64_HI(field64); 984 values[1] = COMPILER_64_LO(field64); 985 986 mac[0] = (values[0] & 0x0000ff00) >> 8; 987 mac[1] = values[0] & 0x000000ff; 988 mac[2] = (values[1] & 0xff000000) >> 24; 989 mac[3] = (values[1] & 0x00ff0000) >> 16; 990 mac[4] = (values[1] & 0x0000ff00) >> 8; 991 mac[5] = values[1] & 0x000000ff; 992 993 return SOC_E_NONE; 994 } 995 996 int xlmac_tx_mac_sa_set(int unit, soc_port_t port, sal_mac_addr_t mac) 997 { 998 uint64 mac_addr; 999 1000 COMPILER_64_ZERO(mac_addr); 1001 COMPILER_64_SET(mac_addr, _shr_uint16_read(&mac[0]), _shr_uint32_read(&mac[2])); 1002 1003 WR_XLMAC(TX_MAC_SAr, unit, port, mac_addr); 1004 1005 return (SOC_E_NONE); 1006 } 1007 1008 1009 int xlmac_tx_mac_sa_get(int unit, soc_port_t port, sal_mac_addr_t mac) 1010 { 1011 uint64 rval64; 1012 uint32 values[2]; 1013 1014 RD_XLMAC(TX_MAC_SAr, unit, port, &rval64); 1015 values[0] = soc_reg64_field32_get(unit, XLMAC_TX_MAC_SAr, rval64, SA_HIf); 1016 values[1] = soc_reg64_field32_get(unit, XLMAC_TX_MAC_SAr, rval64, SA_LOf); 1017 1018 mac[0] = (values[0] & 0x0000ff00) >> 8; 1019 mac[1] = values[0] & 0x000000ff; 1020 mac[2] = (values[1] & 0xff000000) >> 24; 1021 mac[3] = (values[1] & 0x00ff0000) >> 16; 1022 mac[4] = (values[1] & 0x0000ff00) >> 8; 1023 mac[5] = values[1] & 0x000000ff; 1024 1025 LOG_VERBOSE(BSL_LS_SOC_10G, 1026 (BSL_META_U(unit, 1027 "xlmac_tx_mac_sa_get: unit %d port %s MAC=<" 1028 "%02x:%02x:%02x:%02x:%02x:%02x>\n"), 1029 unit, SOC_PORT_NAME(unit, port), 1030 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5])); 1031 return SOC_E_NONE; 1032 } 1033 1034 int xlmac_tx_average_ipg_set(int unit, soc_port_t port, int val) 1035 { 1036 uint64 reg_val; 1037 1038 COMPILER_64_ZERO(reg_val); 1039 1040 RD_XLMAC(TX_CTRLr, unit, port, ®_val); 1041 1042 /* Silently adjust the specified ifp bits to valid value */ 1043 /* valid value: 8 to 64 bytes (i.e. multiple of 8 bits) */ 1044 val = val < 64 ? 64 : (val > 512 ? 512 : (val + 7) & (0x7f << 3)); 1045 1046 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, ®_val, AVERAGE_IPGf, val/8); 1047 1048 WR_XLMAC(TX_CTRLr, unit, port, reg_val); 1049 1050 return (SOC_E_NONE); 1051 } 1052 1053 int xlmac_tx_average_ipg_get(int unit, soc_port_t port, int *val) 1054 { 1055 uint64 reg_val; 1056 1057 COMPILER_64_ZERO(reg_val); 1058 1059 RD_XLMAC(TX_CTRLr, unit, port, ®_val); 1060 1061 *val = soc_reg64_field32_get(unit, XLMAC_TX_CTRLr, reg_val, AVERAGE_IPGf) * 8; 1062 1063 return (SOC_E_NONE); 1064 } 1065 1066 int xlmac_tx_preamble_length_set(int unit, soc_port_t port, int length) 1067 { 1068 uint64 reg_val; 1069 1070 if(length > 8){ 1071 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1072 (BSL_META_U(unit, 1073 "runt size should be small than 8. got %d"), length)); 1074 return (SOC_E_PARAM); 1075 } 1076 1077 COMPILER_64_ZERO(reg_val); 1078 1079 RD_XLMAC(TX_CTRLr, unit, port, ®_val); 1080 1081 soc_reg64_field32_set (unit, XLMAC_TX_CTRLr, ®_val, 1082 TX_PREAMBLE_LENGTHf, length); 1083 WR_XLMAC(TX_CTRLr, unit, port, reg_val); 1084 1085 return (SOC_E_NONE); 1086 } 1087 1088 /***************************************************************************** 1089 * Remote/local Fault * 1090 */ 1091 1092 int xlmac_remote_fault_control_set (int unit, soc_port_t port, 1093 const portmod_remote_fault_control_t *control) 1094 { 1095 uint64 reg_val; 1096 1097 RD_XLMAC(RX_LSS_CTRLr, unit, port, ®_val); 1098 1099 soc_reg64_field32_set (unit, XLMAC_RX_LSS_CTRLr, ®_val, 1100 REMOTE_FAULT_DISABLEf, control->enable ? 0 : 1); 1101 soc_reg64_field32_set(unit, XLMAC_RX_LSS_CTRLr, ®_val, 1102 DROP_TX_DATA_ON_REMOTE_FAULTf, control->drop_tx_on_fault ? 1: 0); 1103 1104 WR_XLMAC(RX_LSS_CTRLr, unit, port, reg_val); 1105 1106 return (SOC_E_NONE); 1107 } 1108 1109 1110 int xlmac_remote_fault_control_get(int unit, soc_port_t port, 1111 portmod_remote_fault_control_t *control) 1112 { 1113 uint64 reg_val; 1114 1115 RD_XLMAC(RX_LSS_CTRLr, unit, port, ®_val); 1116 1117 control->enable = soc_reg64_field32_get (unit, XLMAC_RX_LSS_CTRLr, 1118 reg_val, REMOTE_FAULT_DISABLEf)? 0 : 1; 1119 control->drop_tx_on_fault = soc_reg64_field32_get(unit, XLMAC_RX_LSS_CTRLr, 1120 reg_val, DROP_TX_DATA_ON_REMOTE_FAULTf)?1:0; 1121 return (SOC_E_NONE); 1122 } 1123 1124 1125 int xlmac_local_fault_control_set (int unit, soc_port_t port, 1126 const portmod_local_fault_control_t *control) 1127 { 1128 uint64 reg_val; 1129 1130 RD_XLMAC(RX_LSS_CTRLr, unit, port, ®_val); 1131 1132 soc_reg64_field32_set(unit, XLMAC_RX_LSS_CTRLr, ®_val, 1133 LOCAL_FAULT_DISABLEf, control->enable ? 0 : 1); 1134 1135 soc_reg64_field32_set(unit, XLMAC_RX_LSS_CTRLr, ®_val, 1136 DROP_TX_DATA_ON_LOCAL_FAULTf, control->drop_tx_on_fault ? 1: 0); 1137 1138 WR_XLMAC(RX_LSS_CTRLr, unit, port, reg_val); 1139 1140 return (SOC_E_NONE); 1141 } 1142 1143 1144 int xlmac_local_fault_control_get(int unit, soc_port_t port, 1145 portmod_local_fault_control_t *control) 1146 { 1147 uint64 reg_val; 1148 1149 RD_XLMAC(RX_LSS_CTRLr, unit, port, ®_val); 1150 1151 control->enable = soc_reg64_field32_get(unit, XLMAC_RX_LSS_CTRLr, 1152 reg_val, LOCAL_FAULT_DISABLEf)? 0 : 1; 1153 control->drop_tx_on_fault = soc_reg64_field32_get(unit, XLMAC_RX_LSS_CTRLr, 1154 reg_val, DROP_TX_DATA_ON_LOCAL_FAULTf)?1:0; 1155 return (SOC_E_NONE); 1156 } 1157 1158 1159 int xlmac_remote_fault_status_get(int unit, soc_port_t port, int *status) 1160 { 1161 uint64 reg_val; 1162 1163 RD_XLMAC(RX_LSS_STATUSr, unit, port, ®_val); 1164 *status = soc_reg64_field32_get (unit, XLMAC_RX_LSS_STATUSr, reg_val, 1165 REMOTE_FAULT_STATUSf)? 1 : 0; 1166 return (SOC_E_NONE); 1167 } 1168 1169 int xlmac_local_fault_status_get(int unit, soc_port_t port, int *status) 1170 { 1171 uint64 reg_val; 1172 1173 RD_XLMAC(RX_LSS_STATUSr, unit, port, ®_val); 1174 1175 *status = soc_reg64_field32_get (unit, XLMAC_RX_LSS_STATUSr, reg_val, 1176 LOCAL_FAULT_STATUSf)?1:0; 1177 1178 return (SOC_E_NONE); 1179 } 1180 1181 int xlmac_clear_rx_lss_status_set(int unit, soc_port_t port, int lcl_fault, int rmt_fault) 1182 { 1183 uint64 reg_val; 1184 1185 RD_XLMAC(CLEAR_RX_LSS_STATUSr, unit, port, ®_val); 1186 soc_reg64_field32_set(unit, XLMAC_CLEAR_RX_LSS_STATUSr, ®_val, 1187 CLEAR_REMOTE_FAULT_STATUSf, rmt_fault); 1188 soc_reg64_field32_set(unit, XLMAC_CLEAR_RX_LSS_STATUSr, ®_val, 1189 CLEAR_LOCAL_FAULT_STATUSf, lcl_fault); 1190 WR_XLMAC(CLEAR_RX_LSS_STATUSr, unit, port, reg_val); 1191 1192 return (SOC_E_NONE); 1193 } 1194 1195 int xlmac_clear_rx_lss_status_get(int unit, soc_port_t port, int *lcl_fault, int *rmt_fault) 1196 { 1197 uint64 reg_val; 1198 1199 RD_XLMAC(CLEAR_RX_LSS_STATUSr, unit, port, ®_val); 1200 *rmt_fault = soc_reg64_field32_get(unit, XLMAC_CLEAR_RX_LSS_STATUSr, reg_val, 1201 CLEAR_REMOTE_FAULT_STATUSf); 1202 *lcl_fault = soc_reg64_field32_get(unit, XLMAC_CLEAR_RX_LSS_STATUSr, reg_val, 1203 CLEAR_LOCAL_FAULT_STATUSf); 1204 1205 return (SOC_E_NONE); 1206 } 1207 1208 /**************************************************************************** 1209 Flow Control 1210 */ 1211 1212 int xlmac_pause_control_set (int unit, soc_port_t port, 1213 const portmod_pause_control_t *control) 1214 { 1215 uint64 reg_val; 1216 1217 COMPILER_64_ZERO(reg_val); 1218 1219 RD_XLMAC(PAUSE_CTRLr, unit, port , ®_val); 1220 1221 if(control->rx_enable || control->tx_enable){ 1222 if(control->refresh_timer > 0){ 1223 soc_reg64_field32_set (unit, XLMAC_PAUSE_CTRLr, ®_val, 1224 PAUSE_REFRESH_TIMERf,control->refresh_timer); 1225 soc_reg64_field32_set (unit, XLMAC_PAUSE_CTRLr, ®_val, 1226 PAUSE_REFRESH_ENf, 1); 1227 } else { 1228 soc_reg64_field32_set(unit, XLMAC_PAUSE_CTRLr, ®_val, 1229 PAUSE_REFRESH_ENf, 0); 1230 } 1231 soc_reg64_field32_set(unit, XLMAC_PAUSE_CTRLr, ®_val, 1232 PAUSE_XOFF_TIMERf, control->xoff_timer); 1233 } 1234 1235 soc_reg64_field32_set(unit, XLMAC_PAUSE_CTRLr, ®_val, 1236 TX_PAUSE_ENf, control->tx_enable); 1237 soc_reg64_field32_set(unit, XLMAC_PAUSE_CTRLr, ®_val, 1238 RX_PAUSE_ENf, control->rx_enable); 1239 1240 WR_XLMAC(PAUSE_CTRLr, unit, port , reg_val); 1241 return (SOC_E_NONE); 1242 } 1243 1244 1245 int xlmac_pfc_control_set (int unit, soc_port_t port, 1246 const portmod_pfc_control_t *control) 1247 { 1248 uint64 reg_val; 1249 1250 COMPILER_64_ZERO(reg_val); 1251 1252 RD_XLMAC(PFC_CTRLr, unit, port , ®_val); 1253 1254 if(control->refresh_timer){ 1255 soc_reg64_field32_set (unit, XLMAC_PFC_CTRLr, ®_val, 1256 PFC_REFRESH_TIMERf, control->refresh_timer); 1257 soc_reg64_field32_set (unit, XLMAC_PFC_CTRLr, ®_val, 1258 PFC_REFRESH_ENf, 1); 1259 } else { 1260 soc_reg64_field32_set (unit, XLMAC_PFC_CTRLr, ®_val, 1261 PFC_REFRESH_ENf, 0); 1262 } 1263 1264 soc_reg64_field32_set (unit, XLMAC_PFC_CTRLr, ®_val, 1265 PFC_STATS_ENf, control->stats_en); 1266 soc_reg64_field32_set (unit, XLMAC_PFC_CTRLr, ®_val, 1267 PFC_XOFF_TIMERf, control->xoff_timer); 1268 soc_reg64_field32_set (unit, XLMAC_PFC_CTRLr, ®_val, 1269 FORCE_PFC_XONf, control->force_xon); 1270 1271 soc_reg64_field32_set(unit, XLMAC_PFC_CTRLr, ®_val, 1272 TX_PFC_ENf, control->tx_enable); 1273 soc_reg64_field32_set(unit, XLMAC_PFC_CTRLr, ®_val, 1274 RX_PFC_ENf, control->rx_enable); 1275 1276 WR_XLMAC(PFC_CTRLr, unit, port , reg_val); 1277 return (SOC_E_NONE); 1278 } 1279 1280 1281 int xlmac_llfc_control_set (int unit, soc_port_t port, 1282 const portmod_llfc_control_t *control) 1283 { 1284 uint64 reg_val; 1285 1286 RD_XLMAC(LLFC_CTRLr, unit, port , ®_val); 1287 1288 if(control->rx_enable || control->tx_enable){ 1289 soc_reg64_field32_set (unit, XLMAC_LLFC_CTRLr, ®_val, 1290 LLFC_IN_IPG_ONLYf, control->in_ipg_only); 1291 soc_reg64_field32_set (unit, XLMAC_LLFC_CTRLr, ®_val, 1292 LLFC_CRC_IGNOREf, control->crc_ignore); 1293 } 1294 1295 soc_reg64_field32_set (unit, XLMAC_LLFC_CTRLr, ®_val, 1296 TX_LLFC_ENf, control->tx_enable); 1297 soc_reg64_field32_set (unit, XLMAC_LLFC_CTRLr, ®_val, 1298 RX_LLFC_ENf, control->rx_enable); 1299 1300 WR_XLMAC(LLFC_CTRLr, unit, port , reg_val); 1301 1302 return (SOC_E_NONE); 1303 } 1304 1305 1306 int xlmac_pause_control_get (int unit, soc_port_t port, 1307 portmod_pause_control_t *control) 1308 { 1309 uint64 reg_val; 1310 uint32 refresh_enable = 0; 1311 uint32 refresh_timer = 0; 1312 1313 COMPILER_64_ZERO(reg_val); 1314 RD_XLMAC(PAUSE_CTRLr, unit, port , ®_val); 1315 1316 refresh_enable = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1317 reg_val, PAUSE_REFRESH_ENf); 1318 refresh_timer = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1319 reg_val, PAUSE_REFRESH_TIMERf); 1320 1321 control->refresh_timer = (refresh_enable) ? refresh_timer : -1; 1322 1323 control->xoff_timer = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1324 reg_val, PAUSE_XOFF_TIMERf); 1325 control->rx_enable = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1326 reg_val, RX_PAUSE_ENf); 1327 control->tx_enable = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1328 reg_val, TX_PAUSE_ENf); 1329 return (SOC_E_NONE); 1330 } 1331 1332 1333 int xlmac_pfc_control_get (int unit, soc_port_t port, 1334 portmod_pfc_control_t *control) 1335 { 1336 uint64 reg_val; 1337 uint32 refresh_enable = 0; 1338 uint32 refresh_timer = 0; 1339 1340 COMPILER_64_ZERO(reg_val); 1341 1342 RD_XLMAC(PFC_CTRLr, unit, port , ®_val); 1343 1344 refresh_enable = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1345 reg_val, PFC_REFRESH_ENf); 1346 if (refresh_enable) { 1347 refresh_timer = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1348 reg_val, PFC_REFRESH_TIMERf); 1349 } 1350 control->refresh_timer = refresh_timer; 1351 1352 control->stats_en = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1353 reg_val, PFC_STATS_ENf); 1354 control->xoff_timer = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1355 reg_val, PFC_XOFF_TIMERf); 1356 control->force_xon = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1357 reg_val, FORCE_PFC_XONf); 1358 control->rx_enable = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1359 reg_val, RX_PFC_ENf); 1360 control->tx_enable = soc_reg64_field32_get (unit, XLMAC_PFC_CTRLr, 1361 reg_val, TX_PFC_ENf); 1362 return (SOC_E_NONE); 1363 } 1364 1365 1366 int xlmac_llfc_control_get (int unit, soc_port_t port, 1367 portmod_llfc_control_t *control) 1368 { 1369 uint64 reg_val; 1370 1371 RD_XLMAC(LLFC_CTRLr, unit, port , ®_val); 1372 1373 control->in_ipg_only = soc_reg64_field32_get (unit, XLMAC_LLFC_CTRLr, 1374 reg_val, LLFC_IN_IPG_ONLYf); 1375 control->crc_ignore = soc_reg64_field32_get (unit, XLMAC_LLFC_CTRLr, 1376 reg_val, LLFC_CRC_IGNOREf); 1377 control->rx_enable = soc_reg64_field32_get (unit, XLMAC_LLFC_CTRLr, 1378 reg_val, RX_LLFC_ENf); 1379 control->tx_enable = soc_reg64_field32_get (unit, XLMAC_LLFC_CTRLr, 1380 reg_val, TX_LLFC_ENf); 1381 return (SOC_E_NONE); 1382 } 1383 1384 /* 1385 * Function: 1386 * xlmac_duplex_set 1387 * Purpose: 1388 * Set XLMAC in the specified duplex mode. 1389 * Parameters: 1390 * unit - XGS unit #. 1391 * port - XGS port # on unit. 1392 * duplex - Boolean: true --> full duplex, false --> half duplex. 1393 * Returns: 1394 * SOC_E_XXX 1395 * Notes: 1396 */ 1397 int 1398 xlmac_duplex_set(int unit, soc_port_t port, int duplex) 1399 { 1400 LOG_VERBOSE(BSL_LS_SOC_10G, 1401 (BSL_META_U(unit, 1402 "mac_xl_duplex_set: unit %d port %s duplex=%s\n"), 1403 unit, SOC_PORT_NAME(unit, port), 1404 duplex ? "Full" : "Half")); 1405 return (duplex) ? (SOC_E_NONE) : (SOC_E_UNAVAIL) ; 1406 } 1407 1408 1409 /* 1410 * Function: 1411 * xlmac_duplex_get 1412 * Purpose: 1413 * Get XLMAC duplex mode. 1414 * Parameters: 1415 * unit - XGS unit #. 1416 * duplex - (OUT) Boolean: true --> full duplex, false --> half duplex. 1417 * Returns: 1418 * SOC_E_XXX 1419 */ 1420 int 1421 xlmac_duplex_get(int unit, soc_port_t port, int *duplex) 1422 { 1423 *duplex = TRUE; /* Always full duplex */ 1424 1425 LOG_VERBOSE(BSL_LS_SOC_10G, 1426 (BSL_META_U(unit, 1427 "mac_xl_duplex_get: unit %d port %s duplex=%s\n"), 1428 unit, SOC_PORT_NAME(unit, port), 1429 *duplex ? "Full" : "Half")); 1430 return SOC_E_NONE; 1431 } 1432 1433 /* 1434 * Function: 1435 * mac_xl_speed_get 1436 * Purpose: 1437 * Get XLMAC speed 1438 * Parameters: 1439 * unit - XGS unit #. 1440 * port - XGS port # on unit. 1441 * speed - (OUT) speed in Mb 1442 * Returns: 1443 * SOC_E_XXX 1444 */ 1445 1446 int 1447 xlmac_speed_get(int unit, soc_port_t port, int *speed) 1448 { 1449 uint64 rval; 1450 1451 RD_XLMAC(MODEr, unit, port, &rval); 1452 switch (soc_reg64_field32_get(unit, XLMAC_MODEr, rval, SPEED_MODEf)) { 1453 case XLMAC_SPEED_10: 1454 *speed = 10; 1455 break; 1456 case XLMAC_SPEED_100: 1457 *speed = 100; 1458 break; 1459 case XLMAC_SPEED_1000: 1460 *speed = 1000; 1461 break; 1462 case XLMAC_SPEED_2500: 1463 *speed = 2500; 1464 break; 1465 case XLMAC_SPEED_10000: 1466 default: 1467 *speed = 10000; 1468 break; 1469 } 1470 1471 LOG_VERBOSE(BSL_LS_SOC_10G, 1472 (BSL_META_U(unit, 1473 "mac_xl_speed_get: unit %d port %s speed=%dMb\n"), 1474 unit, SOC_PORT_NAME(unit, port), 1475 *speed)); 1476 return SOC_E_NONE; 1477 } 1478 1479 1480 /** 1481 * 1482 * @brief init xlmac with default configuration 1483 * @param unit 1484 * @param instance 1485 * 1486 * @return int 1487 */ 1488 int xlmac_init(int unit, soc_port_t port, uint32_t init_flags) 1489 { 1490 uint64 mac_ctrl, tx_ctrl, rx_ctrl, rval; 1491 int is_strip_crc, is_append_crc, is_replace_crc, is_higig, is_pass_through_crc; 1492 uint32 crc_mode, is_ipg_check_disable; 1493 portmod_pause_control_t control; 1494 1495 is_strip_crc = init_flags & XLMAC_INIT_F_RX_STRIP_CRC ? 1 : 0; 1496 is_append_crc = init_flags & XLMAC_INIT_F_TX_APPEND_CRC ? 1 : 0; 1497 is_replace_crc = init_flags & XLMAC_INIT_F_TX_REPLACE_CRC ? 1 : 0; 1498 is_pass_through_crc = init_flags & XLMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE ? 1 : 0; 1499 is_higig = init_flags & XLMAC_INIT_F_IS_HIGIG ? 1 : 0; 1500 is_ipg_check_disable = init_flags & XLMAC_INIT_F_IPG_CHECK_DISABLE ? 1 : 0; 1501 1502 if(is_append_crc + is_replace_crc + is_pass_through_crc > 1) { 1503 LOG_VERBOSE(BSL_LS_SOC_10G, 1504 (BSL_META_U(unit, "XLAMC_INIT_F_TX_APPEND_CRC, XLAMC_INIT_F_TX_REPLACE_CRC and XLMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE can't co-exist"))); 1505 return (SOC_E_PARAM); 1506 } 1507 1508 /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */ 1509 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 1510 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, RX_ENf, 0); 1511 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, TX_ENf, 0); 1512 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, 1513 XGMII_IPG_CHECK_DISABLEf, 1514 is_ipg_check_disable); 1515 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 1516 1517 /* XLMAC_RX_CTRL */ 1518 RD_XLMAC(RX_CTRLr, unit, port, &rx_ctrl); 1519 1520 soc_reg64_field32_set (unit, XLMAC_RX_CTRLr, &rx_ctrl, STRIP_CRCf, 1521 is_strip_crc); 1522 soc_reg64_field32_set (unit, XLMAC_RX_CTRLr, &rx_ctrl, STRICT_PREAMBLEf, 1523 is_higig ? 0 : 1); 1524 soc_reg64_field32_set (unit, XLMAC_RX_CTRLr, &rx_ctrl, RUNT_THRESHOLDf, XLMAC_RUNT_THRESHOLD_ETH); 1525 1526 WR_XLMAC(RX_CTRLr, unit, port, rx_ctrl); 1527 1528 /* XLMAC_TX_CTRL */ 1529 RD_XLMAC(TX_CTRLr, unit, port, &tx_ctrl); 1530 1531 if(is_append_crc) { 1532 crc_mode = 0; 1533 } else if(is_replace_crc) { 1534 crc_mode = 2; 1535 } else if(is_pass_through_crc) { 1536 crc_mode = 1; 1537 } else { /* CRC AUTO Mode */ 1538 crc_mode = 3; 1539 } 1540 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &tx_ctrl, CRC_MODEf, crc_mode); 1541 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf, 1542 is_higig ? XLMAC_AVERAGE_IPG_HIGIG : XLMAC_AVERAGE_IPG_DEFAULT); 1543 1544 WR_XLMAC(TX_CTRLr, unit, port, tx_ctrl); 1545 1546 /* PAUSE */ 1547 if (IS_ST_PORT(unit, port)) { 1548 control.tx_enable = FALSE; 1549 control.rx_enable = FALSE; 1550 } else { 1551 control.tx_enable = TRUE; 1552 control.rx_enable = TRUE; 1553 } 1554 1555 /* Use the existing timer values for now */ 1556 RD_XLMAC(PAUSE_CTRLr, unit, port , &rval); 1557 1558 control.refresh_timer = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1559 rval, PAUSE_REFRESH_TIMERf); 1560 control.xoff_timer = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 1561 rval, PAUSE_XOFF_TIMERf); 1562 SOC_IF_ERROR_RETURN(xlmac_pause_control_set(unit, port, &control)); 1563 1564 /* PFC */ 1565 RD_XLMAC(PFC_CTRLr, unit ,port, &rval); 1566 soc_reg64_field32_set(unit, XLMAC_PFC_CTRLr, &rval, PFC_REFRESH_ENf, 1); 1567 WR_XLMAC(PFC_CTRLr, unit ,port, rval); 1568 1569 /* Set jumbo max size (8000 byte payload) */ 1570 SOC_IF_ERROR_RETURN(xlmac_rx_max_size_set(unit, port, JUMBO_MAXSZ)); 1571 1572 /* XLMAC_RX_LSS_CTRL */ 1573 RD_XLMAC(RX_LSS_CTRLr, unit, port, &rval); 1574 1575 soc_reg64_field32_set(unit, XLMAC_RX_LSS_CTRLr, &rval, 1576 DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 1577 soc_reg64_field32_set(unit, XLMAC_RX_LSS_CTRLr, &rval, 1578 DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 1579 soc_reg64_field32_set(unit, XLMAC_RX_LSS_CTRLr, &rval, 1580 DROP_TX_DATA_ON_LINK_INTERRUPTf, 1); 1581 WR_XLMAC(RX_LSS_CTRLr, unit, port, rval); 1582 1583 /* Disable loopback and bring XLMAC out of reset */ 1584 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, LOCAL_LPBKf, 0); 1585 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, RX_ENf, 1); 1586 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, TX_ENf, 1); 1587 1588 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 1589 return (SOC_E_NONE); 1590 } 1591 1592 /*! 1593 * xlmac_frame_spacing_stretch_set 1594 * 1595 * @brief Port Mac Control Spacing Stretch 1596 * 1597 * @param [in] unit - unit id 1598 * @param [in] port - logical port 1599 * @param [in] spacing - 1600 */ 1601 int xlmac_frame_spacing_stretch_set(int unit, int port, int spacing) 1602 { 1603 uint64 mac_ctrl; 1604 1605 if (spacing < 0 || spacing > 257) { 1606 return SOC_E_PARAM; 1607 } 1608 1609 RD_XLMAC(TX_CTRLr, unit, port, &mac_ctrl); 1610 1611 if ( spacing == XLMAC_THROT_10G_TO_5G ) { 1612 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, 21); 1613 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 21); 1614 } else if (spacing == XLMAC_THROT_10G_TO_2P5G) { 1615 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, 21); 1616 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 63); 1617 } else if (spacing >= 8) { 1618 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, spacing); 1619 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 1); 1620 } else { 1621 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, 0); 1622 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 0); 1623 } 1624 1625 WR_XLMAC(TX_CTRLr, unit, port, mac_ctrl); 1626 1627 return (SOC_E_NONE); 1628 } 1629 1630 /*! 1631 * xlmac_frame_spacing_stretch_get 1632 * 1633 * @brief Port Mac Control Spacing Stretch 1634 * 1635 * @param [in] unit - unit id 1636 * @param [in] port - logical port 1637 * @param [out] spacing - 1638 */ 1639 int xlmac_frame_spacing_stretch_get(int unit, int port, int *spacing) 1640 { 1641 uint64 mac_ctrl; 1642 1643 RD_XLMAC(TX_CTRLr, unit, port, &mac_ctrl); 1644 1645 *spacing = soc_reg64_field32_get (unit, XLMAC_TX_CTRLr, 1646 mac_ctrl, THROT_DENOMf); 1647 return (SOC_E_NONE); 1648 } 1649 1650 /*! 1651 * xlmac_diag_fifo_status_get 1652 * 1653 * @brief get port timestamps in fifo 1654 * 1655 * @param [in] unit - unit id 1656 * @param [in] port - logical port 1657 * @param [in] diag_info - 1658 */ 1659 int xlmac_diag_fifo_status_get (int unit, int port, 1660 const portmod_fifo_status_t* diag_info) 1661 { 1662 uint64 rval; 1663 portmod_fifo_status_t* pinfo =(portmod_fifo_status_t*)diag_info; 1664 1665 RD_XLMAC(TX_TIMESTAMP_FIFO_STATUSr, unit, port, &rval); 1666 1667 if (soc_reg64_field32_get(unit, XLMAC_TX_TIMESTAMP_FIFO_STATUSr, rval, 1668 ENTRY_COUNTf) == 0) { 1669 return SOC_E_EMPTY; 1670 } 1671 1672 RD_XLMAC(TX_TIMESTAMP_FIFO_DATAr, unit, port, &rval); 1673 1674 pinfo->timestamps_in_fifo = soc_reg64_field32_get(unit, 1675 XLMAC_TX_TIMESTAMP_FIFO_DATAr, rval, TIME_STAMPf); 1676 1677 return (SOC_E_NONE); 1678 } 1679 1680 /*! 1681 * xlmac_pfc_config_set 1682 * 1683 * @brief set pass control frames. 1684 * 1685 * @param [in] unit - unit id 1686 * @param [in] port - logical port 1687 * @param [in] pfc_cfg - 1688 */ 1689 int xlmac_pfc_config_set (int unit, int port, 1690 const portmod_pfc_config_t* pfc_cfg) 1691 { 1692 uint32 fval; 1693 uint64 rval; 1694 1695 RD_XLMAC(PFC_TYPEr, unit ,port, &rval); 1696 soc_reg64_field32_set(unit, XLMAC_PFC_TYPEr, &rval, PFC_ETH_TYPEf, pfc_cfg->type); 1697 WR_XLMAC(PFC_TYPEr, unit ,port, rval); 1698 1699 RD_XLMAC(PFC_OPCODEr, unit ,port, &rval); 1700 soc_reg64_field32_set(unit, XLMAC_PFC_OPCODEr, &rval, PFC_OPCODEf, pfc_cfg->opcode); 1701 WR_XLMAC(PFC_OPCODEr, unit ,port, rval); 1702 1703 RD_XLMAC(PFC_DAr, unit, port, &rval); 1704 fval = soc_reg64_field32_get(unit, XLMAC_PFC_DAr, rval, PFC_MACDA_LOf); 1705 fval &= 0x00ffffff; 1706 fval |= (pfc_cfg->da_oui & 0xff) << 24; 1707 soc_reg64_field32_set(unit, XLMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval); 1708 1709 soc_reg64_field32_set(unit, XLMAC_PFC_DAr, &rval, PFC_MACDA_HIf, 1710 pfc_cfg->da_oui >> 8); 1711 WR_XLMAC(PFC_DAr, unit, port, rval); 1712 1713 RD_XLMAC(PFC_DAr, unit, port, &rval); 1714 fval = soc_reg64_field32_get(unit, XLMAC_PFC_DAr, rval, PFC_MACDA_LOf); 1715 fval &= 0xff000000; 1716 fval |= pfc_cfg->da_nonoui; 1717 soc_reg64_field32_set(unit, XLMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval); 1718 1719 WR_XLMAC(PFC_DAr, unit, port, rval); 1720 1721 return(SOC_E_NONE); 1722 } 1723 1724 1725 1726 /*! 1727 * xlmac_pfc_config_get 1728 * 1729 * @brief set pass control frames. 1730 * 1731 * @param [in] unit - unit id 1732 * @param [in] port - logical port 1733 * @param [in] pfc_cfg - 1734 */ 1735 int xlmac_pfc_config_get (int unit, int port, 1736 const portmod_pfc_config_t* pfc_cfg) 1737 { 1738 uint64 rval; 1739 uint32 fval; 1740 uint32 fval0,fval1; 1741 portmod_pfc_config_t* pcfg = (portmod_pfc_config_t*) pfc_cfg; 1742 1743 RD_XLMAC(PFC_TYPEr, unit, port, &rval); 1744 1745 pcfg->type = soc_reg64_field32_get (unit, XLMAC_PFC_TYPEr, 1746 rval, PFC_ETH_TYPEf); 1747 1748 RD_XLMAC(PFC_OPCODEr, unit, port, &rval); 1749 pcfg->opcode = soc_reg64_field32_get (unit, XLMAC_PFC_OPCODEr, 1750 rval, PFC_OPCODEf); 1751 1752 RD_XLMAC(PFC_DAr, unit, port, &rval); 1753 fval0 = soc_reg64_field32_get(unit, XLMAC_PFC_DAr, rval, 1754 PFC_MACDA_LOf); 1755 fval1 = soc_reg64_field32_get(unit, XLMAC_PFC_DAr, rval, 1756 PFC_MACDA_HIf); 1757 pcfg->da_oui = (fval0 >> 24) | (fval1 << 8); 1758 1759 RD_XLMAC(PFC_DAr, unit, port, &rval); 1760 fval = soc_reg64_field32_get(unit, XLMAC_PFC_DAr, rval, 1761 PFC_MACDA_LOf); 1762 pcfg->da_nonoui = fval & 0xFFFFFF; 1763 1764 return (SOC_E_NONE); 1765 } 1766 1767 1768 /*! 1769 * xlmac_eee_set 1770 * 1771 * @brief EEE Control and Timer set 1772 * 1773 * @param [in] unit - unit id 1774 * @param [in] port - logical port 1775 * @param [in] eee - 1776 */ 1777 int xlmac_eee_set(int unit, int port, const portmod_eee_t* eee) 1778 { 1779 uint64 rval; 1780 1781 RD_XLMAC(EEE_CTRLr, unit ,port, &rval); 1782 soc_reg64_field32_set(unit, XLMAC_EEE_CTRLr, &rval, EEE_ENf, eee->enable); 1783 WR_XLMAC(EEE_CTRLr, unit ,port, rval); 1784 1785 RD_XLMAC(EEE_TIMERSr, unit ,port, &rval); 1786 soc_reg64_field32_set(unit, XLMAC_EEE_TIMERSr, &rval, EEE_DELAY_ENTRY_TIMERf, eee->tx_idle_time); 1787 soc_reg64_field32_set(unit, XLMAC_EEE_TIMERSr, &rval, EEE_WAKE_TIMERf, eee->tx_wake_time); 1788 WR_XLMAC(EEE_TIMERSr, unit ,port, rval); 1789 1790 return SOC_E_NONE; 1791 } 1792 1793 1794 /*! 1795 * xlmac_eee_get 1796 * 1797 * @brief EEE Control and Timer get 1798 * 1799 * @param [in] unit - unit id 1800 * @param [in] port - logical port 1801 * @param [in] eee - 1802 */ 1803 int xlmac_eee_get(int unit, int port, const portmod_eee_t* eee) 1804 { 1805 uint64 rval; 1806 portmod_eee_t* pEEE = (portmod_eee_t*)eee; 1807 1808 RD_XLMAC(EEE_CTRLr, unit, port, &rval); 1809 pEEE->enable = soc_reg64_field32_get(unit, XLMAC_EEE_CTRLr, rval, EEE_ENf); 1810 1811 RD_XLMAC(EEE_TIMERSr, unit, port, &rval); 1812 1813 pEEE->tx_idle_time = soc_reg64_field32_get (unit, XLMAC_EEE_TIMERSr, rval, 1814 EEE_DELAY_ENTRY_TIMERf); 1815 pEEE->tx_wake_time = soc_reg64_field32_get (unit, XLMAC_EEE_TIMERSr, rval, 1816 EEE_WAKE_TIMERf); 1817 return(SOC_E_NONE); 1818 } 1819 1820 int xlmac_pass_control_frame_set(int unit, int port, int value) 1821 { 1822 int32 version; 1823 uint64 rval; 1824 1825 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 1826 1827 if (version < XLMAC_VERSION_A041) { 1828 return SOC_E_UNAVAIL; 1829 } 1830 1831 RD_XLMAC(RX_CTRLr, unit, port, &rval); 1832 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, &rval, RX_PASS_CTRLf, 1833 value ? 1 : 0); 1834 WR_XLMAC(RX_CTRLr, unit, port, rval); 1835 1836 return(SOC_E_NONE); 1837 } 1838 1839 int xlmac_pass_control_frame_get(int unit, int port, int *value) 1840 { 1841 int32 version; 1842 uint64 rval; 1843 1844 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 1845 1846 if (version < XLMAC_VERSION_A041) { 1847 return SOC_E_UNAVAIL; 1848 } 1849 1850 RD_XLMAC(RX_CTRLr, unit, port, &rval); 1851 *value = soc_reg64_field32_get(unit, XLMAC_RX_CTRLr, rval, RX_PASS_CTRLf); 1852 1853 return(SOC_E_NONE); 1854 } 1855 1856 /*! 1857 * xlmac_pass_pfc_frame_set 1858 * 1859 * @brief send PFC frame to system side 1860 * 1861 * @param [in] unit - unit id 1862 * @param [in] port - logical port 1863 * @param [in] value - 1 or 0 1864 */ 1865 int xlmac_pass_pfc_frame_set(int unit, int port, int value) 1866 { 1867 int32 version; 1868 uint64 rval; 1869 1870 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 1871 1872 if (version < XLMAC_VERSION_A041) { 1873 return SOC_E_UNAVAIL; 1874 } 1875 1876 RD_XLMAC(RX_CTRLr, unit, port, &rval); 1877 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, &rval, RX_PASS_PFCf, 1878 value ? 1 : 0); 1879 WR_XLMAC(RX_CTRLr, unit, port, rval); 1880 1881 return(SOC_E_NONE); 1882 } 1883 1884 int xlmac_pass_pfc_frame_get(int unit, int port, int *value) 1885 { 1886 int32 version; 1887 uint64 rval; 1888 1889 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 1890 1891 if (version < XLMAC_VERSION_A041) { 1892 return SOC_E_UNAVAIL; 1893 } 1894 1895 RD_XLMAC(RX_CTRLr, unit, port, &rval); 1896 *value = soc_reg64_field32_get(unit, XLMAC_RX_CTRLr, rval, RX_PASS_PFCf); 1897 1898 return(SOC_E_NONE); 1899 } 1900 1901 /*! 1902 * xlmac_pass_pause_frame_set 1903 * 1904 * @brief send pause frame to system side 1905 * 1906 * @param [in] unit - unit id 1907 * @param [in] port - logical port 1908 * @param [in] value - 1 or 0 1909 */ 1910 int xlmac_pass_pause_frame_set(int unit, int port, int value) 1911 { 1912 int32 version; 1913 uint64 rval; 1914 1915 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 1916 1917 if (version < XLMAC_VERSION_A041) { 1918 return SOC_E_UNAVAIL; 1919 } 1920 1921 RD_XLMAC(RX_CTRLr, unit, port, &rval); 1922 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, &rval, RX_PASS_PAUSEf, 1923 value ? 1 : 0); 1924 WR_XLMAC(RX_CTRLr, unit, port, rval); 1925 1926 return(SOC_E_NONE); 1927 } 1928 1929 int xlmac_pass_pause_frame_get(int unit, int port, int *value) 1930 { 1931 int32 version; 1932 uint64 rval; 1933 1934 SOC_IF_ERROR_RETURN(_xlmac_version_get(unit, port, &version)); 1935 1936 if (version < XLMAC_VERSION_A041) { 1937 return SOC_E_UNAVAIL; 1938 } 1939 1940 RD_XLMAC(RX_CTRLr, unit, port, &rval); 1941 *value = soc_reg64_field32_get(unit, XLMAC_RX_CTRLr, rval, RX_PASS_PAUSEf); 1942 1943 return(SOC_E_NONE); 1944 } 1945 1946 int xlmac_lag_failover_loopback_set(int unit, int port, int val) 1947 { 1948 uint64 rval; 1949 1950 /* Toggle link bit to notify IPIPE on link up */ 1951 RD_XLMAC(LAG_FAILOVER_STATUSr, unit, port, &rval); 1952 1953 soc_reg64_field32_set (unit, XLMAC_LAG_FAILOVER_STATUSr, &rval, 1954 LAG_FAILOVER_LOOPBACKf, val); 1955 WR_XLMAC(LAG_FAILOVER_STATUSr, unit, port, rval); 1956 1957 return(SOC_E_NONE); 1958 } 1959 1960 int xlmac_lag_failover_loopback_get(int unit, int port, int *val) 1961 { 1962 uint64 rval; 1963 1964 /* Toggle link bit to notify IPIPE on link up */ 1965 RD_XLMAC(LAG_FAILOVER_STATUSr, unit, port, &rval); 1966 1967 *val = soc_reg64_field32_get (unit, XLMAC_LAG_FAILOVER_STATUSr, rval, 1968 LAG_FAILOVER_LOOPBACKf); 1969 1970 return (SOC_E_NONE); 1971 } 1972 1973 /*! 1974 * xlmac_lag_failover_disable 1975 * 1976 * @brief Port Mac Control Lag Failover Disable. 1977 * 1978 * @param [in] unit - unit id 1979 * @param [in] port - logical port 1980 */ 1981 int xlmac_lag_failover_disable(int unit, int port) 1982 { 1983 uint64 mac_ctrl; 1984 1985 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 1986 1987 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, LAG_FAILOVER_ENf, 0); 1988 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, LINK_STATUS_SELECTf, 0); 1989 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, REMOVE_FAILOVER_LPBKf, 0); 1990 1991 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 1992 return (SOC_E_NONE); 1993 } 1994 1995 1996 /*! 1997 * xlmac_lag_failover_en_set 1998 * 1999 * @brief Port Mac Control Spacing Stretch 2000 * 2001 * @param [in] unit - unit id 2002 * @param [in] port - logical port 2003 * @param [in] spacing - 2004 */ 2005 int xlmac_lag_failover_en_set(int unit, int port, int val) 2006 { 2007 uint64 mac_ctrl; 2008 2009 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 2010 2011 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, LAG_FAILOVER_ENf, val); 2012 2013 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 2014 2015 return (SOC_E_NONE); 2016 } 2017 2018 /*! 2019 * xlmac_lag_failover_en_get 2020 * 2021 * @brief Port Mac Control Spacing Stretch 2022 * 2023 * @param [in] unit - unit id 2024 * @param [in] port - logical port 2025 * @param [out] val - 2026 */ 2027 int xlmac_lag_failover_en_get(int unit, int port, int *val) 2028 { 2029 uint64 mac_ctrl; 2030 2031 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 2032 2033 *val = soc_reg64_field32_get (unit, XLMAC_CTRLr, 2034 mac_ctrl, LAG_FAILOVER_ENf); 2035 return (SOC_E_NONE); 2036 } 2037 2038 2039 /*! 2040 * xlmac_lag_remove_failover_lpbk_set 2041 * 2042 * @brief Port Mac Control Spacing Stretch 2043 * 2044 * @param [in] unit - unit id 2045 * @param [in] port - logical port 2046 * @param [in] spacing - 2047 */ 2048 int xlmac_lag_remove_failover_lpbk_set(int unit, int port, int val) 2049 { 2050 uint64 mac_ctrl; 2051 2052 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 2053 2054 soc_reg64_field32_set(unit, XLMAC_CTRLr, &mac_ctrl, REMOVE_FAILOVER_LPBKf, val); 2055 2056 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 2057 2058 return (SOC_E_NONE); 2059 } 2060 2061 /*! 2062 * xlmac_lag_remove_failover_lpbk_get 2063 * 2064 * @brief Port Mac Control Spacing Stretch 2065 * 2066 * @param [in] unit - unit id 2067 * @param [in] port - logical port 2068 * @param [out] val - 2069 */ 2070 int xlmac_lag_remove_failover_lpbk_get(int unit, int port, int *val) 2071 { 2072 uint64 mac_ctrl; 2073 2074 RD_XLMAC(CTRLr, unit, port, &mac_ctrl); 2075 2076 *val = soc_reg64_field32_get (unit, XLMAC_CTRLr, 2077 mac_ctrl, REMOVE_FAILOVER_LPBKf); 2078 return (SOC_E_NONE); 2079 } 2080 2081 int xlmac_reset_fc_timers_on_link_dn_set (int unit, soc_port_t port, int val) 2082 { 2083 uint64 reg_val; 2084 2085 RD_XLMAC(RX_LSS_CTRLr, unit, port, ®_val); 2086 2087 soc_reg64_field32_set (unit, XLMAC_RX_LSS_CTRLr, ®_val, 2088 RESET_FLOW_CONTROL_TIMERS_ON_LINK_DOWNf, val); 2089 2090 WR_XLMAC(RX_LSS_CTRLr, unit, port, reg_val); 2091 return (SOC_E_NONE); 2092 } 2093 2094 2095 int xlmac_reset_fc_timers_on_link_dn_get(int unit, soc_port_t port, int *val) 2096 { 2097 uint64 reg_val; 2098 2099 RD_XLMAC(RX_LSS_CTRLr, unit, port, ®_val); 2100 2101 *val = soc_reg64_field32_get (unit, XLMAC_RX_LSS_CTRLr, reg_val, 2102 RESET_FLOW_CONTROL_TIMERS_ON_LINK_DOWNf); 2103 return (SOC_E_NONE); 2104 } 2105 2106 2107 int xlmac_drain_cell_get (int unit, int port, portmod_drain_cells_t *drain_cells) 2108 { 2109 uint64 rval; 2110 2111 RD_XLMAC(PFC_CTRLr, unit, port, &rval); 2112 drain_cells->rx_pfc_en = soc_reg64_field32_get(unit, XLMAC_PFC_CTRLr, 2113 rval, RX_PFC_ENf); 2114 2115 RD_XLMAC(LLFC_CTRLr, unit, port, &rval); 2116 drain_cells->llfc_en = soc_reg64_field32_get(unit, XLMAC_LLFC_CTRLr, 2117 rval, RX_LLFC_ENf); 2118 2119 RD_XLMAC(PAUSE_CTRLr, unit, port , &rval); 2120 drain_cells->rx_pause = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 2121 rval, RX_PAUSE_ENf); 2122 drain_cells->tx_pause = soc_reg64_field32_get (unit, XLMAC_PAUSE_CTRLr, 2123 rval, TX_PAUSE_ENf); 2124 2125 return (0); 2126 } 2127 2128 int xlmac_drain_cell_stop (int unit, int port, const portmod_drain_cells_t *drain_cells) 2129 { 2130 uint64 rval; 2131 2132 /* Clear Discard fields */ 2133 SOC_IF_ERROR_RETURN(xlmac_discard_set (unit, port, 0)); 2134 2135 /* set pause fields */ 2136 RD_XLMAC(PAUSE_CTRLr, unit, port , &rval); 2137 soc_reg64_field32_set (unit, XLMAC_PAUSE_CTRLr, 2138 &rval, RX_PAUSE_ENf, drain_cells->rx_pause); 2139 soc_reg64_field32_set (unit, XLMAC_PAUSE_CTRLr, 2140 &rval, TX_PAUSE_ENf, drain_cells->tx_pause); 2141 WR_XLMAC(PAUSE_CTRLr, unit, port , rval); 2142 2143 /* set pfc rx_en fields */ 2144 RD_XLMAC(PFC_CTRLr, unit, port, &rval); 2145 soc_reg64_field32_set(unit, XLMAC_PFC_CTRLr, 2146 &rval, RX_PFC_ENf, drain_cells->rx_pfc_en); 2147 WR_XLMAC(PFC_CTRLr, unit, port, rval); 2148 2149 /* set llfc rx_en fields */ 2150 RD_XLMAC(LLFC_CTRLr, unit, port, &rval); 2151 soc_reg64_field32_set(unit, XLMAC_LLFC_CTRLr, 2152 &rval, RX_LLFC_ENf, drain_cells->llfc_en); 2153 WR_XLMAC(LLFC_CTRLr, unit, port, rval); 2154 2155 return (0); 2156 } 2157 2158 int xlmac_drain_cell_start(int unit, int port) 2159 { 2160 uint64 rval; 2161 2162 RD_XLMAC(CTRLr, unit, port, &rval); 2163 2164 /* Don't disable TX since it stops egress and hangs if CPU sends */ 2165 soc_reg64_field32_set(unit, XLMAC_CTRLr, &rval, TX_ENf, 1); 2166 /* Disable RX */ 2167 soc_reg64_field32_set(unit, XLMAC_CTRLr, &rval, RX_ENf, 0); 2168 2169 WR_XLMAC(CTRLr, unit, port, rval); 2170 2171 RD_XLMAC(PAUSE_CTRLr, unit, port , &rval); 2172 soc_reg64_field32_set (unit, XLMAC_PAUSE_CTRLr, &rval, RX_PAUSE_ENf, 0); 2173 WR_XLMAC(PAUSE_CTRLr, unit, port, rval); 2174 2175 RD_XLMAC(PFC_CTRLr, unit, port, &rval); 2176 soc_reg64_field32_set(unit, XLMAC_PFC_CTRLr, &rval, RX_PFC_ENf, 0); 2177 WR_XLMAC(PFC_CTRLr, unit, port, rval); 2178 2179 RD_XLMAC(LLFC_CTRLr, unit, port, &rval); 2180 soc_reg64_field32_set(unit, XLMAC_LLFC_CTRLr, &rval, RX_LLFC_ENf, 0); 2181 WR_XLMAC(LLFC_CTRLr, unit, port, rval); 2182 2183 RD_XLMAC(CTRLr, unit, port, &rval); 2184 soc_reg64_field32_set(unit, XLMAC_CTRLr, &rval, SOFT_RESETf, 1); 2185 WR_XLMAC(CTRLr, unit, port, rval); 2186 2187 SOC_IF_ERROR_RETURN(xlmac_discard_set(unit, port, 1)); 2188 2189 return (0); 2190 } 2191 2192 int 2193 xlmac_mac_ctrl_set(int unit, int port, uint64 mac_ctrl) 2194 { 2195 WR_XLMAC(CTRLr, unit, port, mac_ctrl); 2196 return (0); 2197 } 2198 2199 2200 int xlmac_txfifo_cell_cnt_get (int unit, int port, uint32* fval) 2201 { 2202 uint64 rval; 2203 2204 RD_XLMAC(TXFIFO_CELL_CNTr, unit, port, &rval); 2205 *fval = soc_reg64_field32_get(unit, XLMAC_TXFIFO_CELL_CNTr, rval, 2206 CELL_CNTf); 2207 return (0); 2208 } 2209 2210 int 2211 xlmac_egress_queue_drain_get(int unit, int port, uint64 *mac_ctrl, int *rx_en) 2212 { 2213 uint64 ctrl; 2214 2215 RD_XLMAC(CTRLr, unit, port, &ctrl); 2216 *mac_ctrl = ctrl; 2217 2218 *rx_en = soc_reg64_field32_get(unit, XLMAC_CTRLr, ctrl, RX_ENf); 2219 2220 return (0); 2221 } 2222 2223 int 2224 xlmac_egress_queue_drain_rx_en(int unit, int port, int rx_en) 2225 { 2226 uint64 ctrl; 2227 /* Enable both TX and RX, de-assert SOFT_RESET */ 2228 RD_XLMAC(CTRLr, unit, port, &ctrl); 2229 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, RX_ENf, rx_en ? 1 : 0); 2230 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, SOFT_RESETf, 0); 2231 WR_XLMAC(CTRLr, unit, port, ctrl); 2232 2233 return (0); 2234 } 2235 2236 int 2237 xlmac_drain_cells_rx_enable(int unit, int port, int rx_en) 2238 { 2239 uint64 ctrl, octrl; 2240 uint32 soft_reset = 0; 2241 2242 /* Enable both TX and RX, de-assert SOFT_RESET */ 2243 RD_XLMAC(CTRLr, unit, port, &ctrl); 2244 octrl = ctrl; 2245 2246 /* Don't disable TX since it stops egress and hangs if CPU sends */ 2247 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, TX_ENf, 1); 2248 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, RX_ENf, rx_en ? 1 : 0); 2249 2250 if (COMPILER_64_EQ(ctrl, octrl)) { 2251 /* 2252 * To avoid the unexpected early return to prevent this problem. 2253 * 1. Problem occurred for disabling process only. 2254 * 2. To comply original designing senario, XLMAC_CTRLr.SOFT_RESETf is 2255 * used to early check to see if this port is at disabled state 2256 * already. 2257 */ 2258 soft_reset = soc_reg64_field32_get(unit, 2259 XLMAC_CTRLr, ctrl, SOFT_RESETf); 2260 if ((rx_en) || (!rx_en && soft_reset)){ 2261 return SOC_E_NONE; 2262 } 2263 } 2264 2265 if (rx_en) 2266 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, SOFT_RESETf, 0); 2267 2268 WR_XLMAC(CTRLr, unit, port, ctrl); 2269 2270 return (0); 2271 } 2272 2273 /* 2274 * Function: 2275 * 2276 * Purpose: 2277 * This function checks if the MAC control values are already 2278 * set. 2279 * 2280 * This function should be called before enabling/disabling the 2281 * MAC to prevent the following: 2282 * 1. Problem occurred for disabling process only. 2283 * 2. To comply original designing senario, XLMAC_CTRLr.SOFT_RESETf is 2284 * used to early check to see if this port is at disabled state 2285 * already. 2286 * Parameters: 2287 * unit - (IN) Unit number. 2288 * port - (IN) Port number. 2289 * enable - (IN) Indicates whether to check for enable or disable. 2290 * reset - (OUT) Indicates MAC control needs to be reset or not. 2291 * Returns: 2292 * SOC_E_XXX 2293 */ 2294 int xlmac_reset_check(int unit, int port, int enable, int *reset) 2295 { 2296 uint64 ctrl, octrl; 2297 2298 *reset = 1; 2299 2300 RD_XLMAC(CTRLr, unit, port, &ctrl); 2301 octrl = ctrl; 2302 2303 /* Don't disable TX since it stops egress and hangs if CPU sends */ 2304 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, TX_ENf, enable ? 1 : 0); 2305 soc_reg64_field32_set(unit, XLMAC_CTRLr, &ctrl, RX_ENf, enable ? 1 : 0); 2306 2307 if (COMPILER_64_EQ(ctrl, octrl)) { 2308 if (enable) { 2309 *reset = 0; 2310 } else { 2311 if (soc_reg64_field32_get(unit, XLMAC_CTRLr, ctrl, SOFT_RESETf)) { 2312 *reset = 0; 2313 } 2314 } 2315 } 2316 2317 return SOC_E_NONE; 2318 } 2319 2320 int xlmac_e2ecc_hdr_get (int unit, int port, uint32_t *words) 2321 { 2322 uint64 rval64; 2323 2324 RD_XLMAC(E2ECC_MODULE_HDR_0r, unit, port, &rval64); 2325 words[0] = soc_reg64_field32_get (unit, XLMAC_E2ECC_MODULE_HDR_0r, rval64, 2326 E2ECC_MODULE_HDR_0_HIf); 2327 words[1] = soc_reg64_field32_get(unit, XLMAC_E2ECC_MODULE_HDR_0r, rval64, 2328 E2ECC_MODULE_HDR_0_LOf); 2329 2330 RD_XLMAC(E2ECC_MODULE_HDR_1r, unit, port, &rval64); 2331 words[2] = soc_reg64_field32_get (unit, XLMAC_E2ECC_MODULE_HDR_1r, rval64, 2332 E2ECC_MODULE_HDR_1_HIf); 2333 words[3] = soc_reg64_field32_get(unit, XLMAC_E2ECC_MODULE_HDR_1r, rval64, 2334 E2ECC_MODULE_HDR_1_LOf); 2335 2336 RD_XLMAC(E2ECC_DATA_HDR_0r, unit, port, &rval64); 2337 words[4] = soc_reg64_field32_get (unit, XLMAC_E2ECC_DATA_HDR_0r, rval64, 2338 E2ECC_DATA_HDR_0_HIf); 2339 words[5] = soc_reg64_field32_get(unit, XLMAC_E2ECC_DATA_HDR_0r, rval64, 2340 E2ECC_DATA_HDR_0_LOf); 2341 2342 RD_XLMAC(E2ECC_DATA_HDR_1r, unit, port, &rval64); 2343 words[6] = soc_reg64_field32_get (unit, XLMAC_E2ECC_DATA_HDR_1r, rval64, 2344 E2ECC_DATA_HDR_1_HIf); 2345 words[7] = soc_reg64_field32_get(unit, XLMAC_E2ECC_DATA_HDR_1r, rval64, 2346 E2ECC_DATA_HDR_1_LOf); 2347 2348 return SOC_E_NONE; 2349 } 2350 2351 int xlmac_e2ecc_hdr_set (int unit, int port, uint32_t *words) 2352 { 2353 uint64 rval64; 2354 COMPILER_64_ZERO(rval64); 2355 2356 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64, 2357 E2ECC_MODULE_HDR_0_HIf, words[0]); 2358 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64, 2359 E2ECC_MODULE_HDR_0_LOf, words[1]); 2360 WR_XLMAC(E2ECC_MODULE_HDR_0r, unit, port, rval64); 2361 2362 2363 COMPILER_64_ZERO(rval64); 2364 soc_reg64_field32_set (unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64, 2365 E2ECC_MODULE_HDR_1_HIf, words[2]); 2366 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64, 2367 E2ECC_MODULE_HDR_1_LOf, words[3]); 2368 WR_XLMAC(E2ECC_MODULE_HDR_1r, unit, port, rval64); 2369 2370 2371 COMPILER_64_ZERO(rval64); 2372 soc_reg64_field32_set (unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64, 2373 E2ECC_DATA_HDR_0_HIf, words[4]); 2374 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64, 2375 E2ECC_DATA_HDR_0_LOf, words[5]); 2376 WR_XLMAC(E2ECC_DATA_HDR_0r, unit, port, rval64); 2377 2378 2379 COMPILER_64_ZERO(rval64); 2380 soc_reg64_field32_set (unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64, 2381 E2ECC_DATA_HDR_1_HIf, words[6]); 2382 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64, 2383 E2ECC_DATA_HDR_1_LOf, words[7]); 2384 WR_XLMAC(E2ECC_DATA_HDR_1r, unit, port, rval64); 2385 2386 2387 return SOC_E_NONE; 2388 } 2389 2390 2391 int xlmac_e2e_enable_set(int unit, int port, int enable) 2392 { 2393 uint64 rval64; 2394 2395 RD_XLMAC(E2E_CTRLr, unit, port, &rval64); 2396 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, &rval64, E2E_ENABLEf, enable); 2397 WR_XLMAC(E2E_CTRLr, unit, port, rval64); 2398 2399 return (0); 2400 } 2401 2402 int xlmac_e2e_enable_get(int unit, int port, int *enable) 2403 { 2404 uint64 rval64; 2405 2406 RD_XLMAC(E2E_CTRLr, unit, port, &rval64); 2407 *enable = soc_reg64_field32_get(unit, XLMAC_E2E_CTRLr, rval64, E2E_ENABLEf); 2408 2409 return (0); 2410 } 2411 2412 int xlmac_interrupt_enable_get(int unit, int port, int intr_type, uint32 *value) 2413 { 2414 uint64 reg_val; 2415 int32 version; 2416 SOC_INIT_FUNC_DEFS; 2417 2418 _SOC_IF_ERR_EXIT(_xlmac_version_get(unit, port, &version)); 2419 2420 if (version < XLMAC_VERSION_A041) { 2421 return SOC_E_UNAVAIL; 2422 } 2423 2424 _SOC_IF_ERR_EXIT(READ_XLMAC_INTR_ENABLEr(unit, port, ®_val)); 2425 2426 switch(intr_type) { 2427 case portmodIntrTypeTxPktUnderflow : 2428 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TX_PKT_UNDERFLOWf); 2429 break; 2430 case portmodIntrTypeTxPktOverflow : 2431 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TX_PKT_OVERFLOWf); 2432 break; 2433 case portmodIntrTypeTxLlfcMsgOverflow : 2434 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TX_LLFC_MSG_OVERFLOWf); 2435 break; 2436 case portmodIntrTypeTxTSFifoOverflow : 2437 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TX_TS_FIFO_OVERFLOWf); 2438 break; 2439 case portmodIntrTypeRxPktOverflow : 2440 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_RX_PKT_OVERFLOWf); 2441 break; 2442 case portmodIntrTypeRxMsgOverflow : 2443 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_RX_MSG_OVERFLOWf); 2444 break; 2445 case portmodIntrTypeTxCdcSingleBitErr : 2446 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TX_CDC_SINGLE_BIT_ERRf); 2447 break; 2448 case portmodIntrTypeTxCdcDoubleBitErr : 2449 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TX_CDC_DOUBLE_BIT_ERRf); 2450 break; 2451 case portmodIntrTypeRxCdcSingleBitErr : 2452 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_RX_CDC_SINGLE_BIT_ERRf); 2453 break; 2454 case portmodIntrTypeRxCdcDoubleBitErr : 2455 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_RX_CDC_DOUBLE_BIT_ERRf); 2456 break; 2457 case portmodIntrTypeLocalFaultStatus : 2458 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_LOCAL_FAULT_STATUSf); 2459 break; 2460 case portmodIntrTypeRemoteFaultStatus : 2461 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_REMOTE_FAULT_STATUSf); 2462 break; 2463 case portmodIntrTypeLinkInterruptionStatus : 2464 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_LINK_INTERRUPTION_STATUSf); 2465 break; 2466 case portmodIntrTypeTsEntryValid : 2467 *value = soc_reg64_field32_get(unit, XLMAC_INTR_ENABLEr, reg_val, EN_TS_ENTRY_VALIDf); 2468 break; 2469 default: 2470 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type"))); 2471 break; 2472 } 2473 2474 exit: 2475 SOC_FUNC_RETURN; 2476 } 2477 2478 int xlmac_interrupt_enable_set(int unit, int port, int intr_type, uint32 value) 2479 { 2480 uint64 rval; 2481 int32 version; 2482 SOC_INIT_FUNC_DEFS; 2483 2484 _SOC_IF_ERR_EXIT(_xlmac_version_get(unit, port, &version)); 2485 2486 if (version < XLMAC_VERSION_A041) { 2487 return SOC_E_UNAVAIL; 2488 } 2489 2490 _SOC_IF_ERR_EXIT(READ_XLMAC_INTR_ENABLEr(unit, port, &rval)); 2491 2492 switch(intr_type) { 2493 case portmodIntrTypeTxPktUnderflow : 2494 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TX_PKT_UNDERFLOWf, value); 2495 break; 2496 case portmodIntrTypeTxPktOverflow : 2497 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TX_PKT_OVERFLOWf, value); 2498 break; 2499 case portmodIntrTypeTxLlfcMsgOverflow : 2500 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TX_LLFC_MSG_OVERFLOWf, value); 2501 break; 2502 case portmodIntrTypeTxTSFifoOverflow : 2503 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TX_TS_FIFO_OVERFLOWf, value); 2504 break; 2505 case portmodIntrTypeRxPktOverflow : 2506 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_RX_PKT_OVERFLOWf, value); 2507 break; 2508 case portmodIntrTypeRxMsgOverflow : 2509 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_RX_MSG_OVERFLOWf, value); 2510 break; 2511 case portmodIntrTypeTxCdcSingleBitErr : 2512 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TX_CDC_SINGLE_BIT_ERRf, value); 2513 break; 2514 case portmodIntrTypeTxCdcDoubleBitErr : 2515 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TX_CDC_DOUBLE_BIT_ERRf, value); 2516 break; 2517 case portmodIntrTypeRxCdcSingleBitErr : 2518 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_RX_CDC_SINGLE_BIT_ERRf, value); 2519 break; 2520 case portmodIntrTypeRxCdcDoubleBitErr : 2521 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_RX_CDC_DOUBLE_BIT_ERRf, value); 2522 break; 2523 case portmodIntrTypeLocalFaultStatus : 2524 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_LOCAL_FAULT_STATUSf, value); 2525 break; 2526 case portmodIntrTypeRemoteFaultStatus : 2527 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_REMOTE_FAULT_STATUSf, value); 2528 break; 2529 case portmodIntrTypeLinkInterruptionStatus : 2530 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_LINK_INTERRUPTION_STATUSf, value); 2531 break; 2532 case portmodIntrTypeTsEntryValid : 2533 soc_reg64_field32_set(unit, XLMAC_INTR_ENABLEr, &rval, EN_TS_ENTRY_VALIDf, value); 2534 break; 2535 default: 2536 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type"))); 2537 break; 2538 } 2539 2540 _SOC_IF_ERR_EXIT(WRITE_XLMAC_INTR_ENABLEr(unit, port, rval)); 2541 2542 exit: 2543 SOC_FUNC_RETURN; 2544 } 2545 2546 int xlmac_interrupt_status_get(int unit, int port, int intr_type, uint32 *value) 2547 { 2548 uint64 reg_val; 2549 int32 version; 2550 SOC_INIT_FUNC_DEFS; 2551 2552 _SOC_IF_ERR_EXIT(_xlmac_version_get(unit, port, &version)); 2553 2554 if (version < XLMAC_VERSION_A041) { 2555 return SOC_E_UNAVAIL; 2556 } 2557 2558 _SOC_IF_ERR_EXIT(READ_XLMAC_INTR_STATUSr(unit, port, ®_val)); 2559 2560 switch(intr_type) { 2561 case portmodIntrTypeTxPktUnderflow : 2562 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_UNDERFLOWf); 2563 break; 2564 case portmodIntrTypeTxPktOverflow : 2565 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_OVERFLOWf); 2566 break; 2567 case portmodIntrTypeTxLlfcMsgOverflow : 2568 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_LLFC_MSG_OVERFLOWf); 2569 break; 2570 case portmodIntrTypeTxTSFifoOverflow : 2571 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_TS_FIFO_OVERFLOWf); 2572 break; 2573 case portmodIntrTypeRxPktOverflow : 2574 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_PKT_OVERFLOWf); 2575 break; 2576 case portmodIntrTypeRxMsgOverflow : 2577 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_MSG_OVERFLOWf); 2578 break; 2579 case portmodIntrTypeTxCdcSingleBitErr : 2580 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_SINGLE_BIT_ERRf); 2581 break; 2582 case portmodIntrTypeTxCdcDoubleBitErr : 2583 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_DOUBLE_BIT_ERRf); 2584 break; 2585 case portmodIntrTypeRxCdcSingleBitErr : 2586 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_SINGLE_BIT_ERRf); 2587 break; 2588 case portmodIntrTypeRxCdcDoubleBitErr : 2589 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_DOUBLE_BIT_ERRf); 2590 break; 2591 case portmodIntrTypeLocalFaultStatus : 2592 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_LOCAL_FAULT_STATUSf); 2593 break; 2594 case portmodIntrTypeRemoteFaultStatus : 2595 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_REMOTE_FAULT_STATUSf); 2596 break; 2597 case portmodIntrTypeLinkInterruptionStatus : 2598 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_LINK_INTERRUPTION_STATUSf); 2599 break; 2600 case portmodIntrTypeTsEntryValid : 2601 *value = soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TS_ENTRY_VALIDf); 2602 break; 2603 default: 2604 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type"))); 2605 break; 2606 } 2607 2608 exit: 2609 SOC_FUNC_RETURN; 2610 } 2611 2612 int xlmac_interrupts_status_get(int unit, int port, int arr_max_size, uint32* intr_arr, uint32* size) 2613 { 2614 uint32 cnt = 0; 2615 uint64 reg_val; 2616 int32 version; 2617 SOC_INIT_FUNC_DEFS; 2618 2619 _SOC_IF_ERR_EXIT(_xlmac_version_get(unit, port, &version)); 2620 2621 if (version < XLMAC_VERSION_A041) { 2622 return SOC_E_UNAVAIL; 2623 } 2624 2625 _SOC_IF_ERR_EXIT(READ_XLMAC_INTR_STATUSr(unit, port, ®_val)); 2626 2627 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_UNDERFLOWf)) { 2628 if (cnt >= arr_max_size) { 2629 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2630 } 2631 intr_arr[cnt++] = portmodIntrTypeTxPktUnderflow; 2632 } 2633 2634 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_OVERFLOWf)) { 2635 if (cnt >= arr_max_size) { 2636 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2637 } 2638 intr_arr[cnt++] = portmodIntrTypeTxPktOverflow; 2639 } 2640 2641 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_LLFC_MSG_OVERFLOWf)) { 2642 if (cnt >= arr_max_size) { 2643 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2644 } 2645 intr_arr[cnt++] = portmodIntrTypeTxLlfcMsgOverflow; 2646 } 2647 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_TS_FIFO_OVERFLOWf)) { 2648 if (cnt >= arr_max_size) { 2649 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2650 } 2651 intr_arr[cnt++] = portmodIntrTypeTxTSFifoOverflow; 2652 } 2653 2654 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_PKT_OVERFLOWf)) { 2655 if (cnt >= arr_max_size) { 2656 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2657 } 2658 intr_arr[cnt++] = portmodIntrTypeRxPktOverflow; 2659 } 2660 2661 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_MSG_OVERFLOWf)) { 2662 if (cnt >= arr_max_size) { 2663 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2664 } 2665 intr_arr[cnt++] = portmodIntrTypeRxMsgOverflow; 2666 } 2667 2668 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_SINGLE_BIT_ERRf)) { 2669 if (cnt >= arr_max_size) { 2670 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2671 } 2672 intr_arr[cnt++] = portmodIntrTypeTxCdcSingleBitErr; 2673 } 2674 2675 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_DOUBLE_BIT_ERRf)) { 2676 if (cnt >= arr_max_size) { 2677 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2678 } 2679 intr_arr[cnt++] = portmodIntrTypeTxCdcDoubleBitErr; 2680 } 2681 2682 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_SINGLE_BIT_ERRf)) { 2683 if (cnt >= arr_max_size) { 2684 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2685 } 2686 intr_arr[cnt++] = portmodIntrTypeRxCdcSingleBitErr; 2687 } 2688 2689 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_DOUBLE_BIT_ERRf)) { 2690 if (cnt >= arr_max_size) { 2691 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2692 } 2693 intr_arr[cnt++] = portmodIntrTypeRxCdcDoubleBitErr; 2694 } 2695 2696 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_LOCAL_FAULT_STATUSf)) { 2697 if (cnt >= arr_max_size) { 2698 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2699 } 2700 intr_arr[cnt++] = portmodIntrTypeLocalFaultStatus; 2701 } 2702 2703 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_REMOTE_FAULT_STATUSf)) { 2704 if (cnt >= arr_max_size) { 2705 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2706 } 2707 intr_arr[cnt++] = portmodIntrTypeRemoteFaultStatus; 2708 } 2709 2710 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_LINK_INTERRUPTION_STATUSf)) { 2711 if (cnt >= arr_max_size) { 2712 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2713 } 2714 intr_arr[cnt++] = portmodIntrTypeLinkInterruptionStatus; 2715 } 2716 2717 if (soc_reg64_field32_get(unit, XLMAC_INTR_STATUSr, reg_val, SUM_TS_ENTRY_VALIDf)) { 2718 if (cnt >= arr_max_size) { 2719 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size"))); 2720 } 2721 intr_arr[cnt++] = portmodIntrTypeTsEntryValid; 2722 } 2723 2724 *size = cnt; 2725 2726 exit: 2727 SOC_FUNC_RETURN; 2728 } 2729 2730 int xlmac_preemption_mode_set(int32 unit, soc_port_t port, uint32 enable) 2731 { 2732 uint64 reg_val; 2733 int32 value = 0; 2734 2735 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2736 value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2737 reg_val, PREEMPTION_MODEf); 2738 2739 if (value != enable) { 2740 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 2741 ®_val, PREEMPTION_MODEf, enable? 1: 0); 2742 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 2743 } 2744 2745 return (SOC_E_NONE); 2746 } 2747 2748 int xlmac_preemption_mode_get(int32 unit, soc_port_t port, uint32 *enable) 2749 { 2750 uint64 reg_val; 2751 2752 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2753 *enable = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2754 reg_val, PREEMPTION_MODEf); 2755 2756 return (SOC_E_NONE); 2757 } 2758 2759 int xlmac_preemption_tx_enable_set(int32 unit, soc_port_t port, uint32 enable) 2760 { 2761 uint64 reg_val, v_reg_val; 2762 int32 value = 0, rc = SOC_E_NONE; 2763 uint32 is_verify_set; 2764 uint32 timeout = 0, num_attempts = 0; 2765 uint32 verify_status = 0, verify_op_done = 0; 2766 uint32 wait_time, iter = 0; 2767 2768 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2769 value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2770 reg_val, PREEMPT_ENABLEf); 2771 2772 is_verify_set = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2773 reg_val, VERIFY_ENABLEf); 2774 2775 2776 /* if preemption already enabled, return */ 2777 if (value == enable) { 2778 return rc; 2779 } 2780 2781 /* Static configuration - no preemption negotaition with link partner*/ 2782 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 2783 ®_val, PREEMPT_ENABLEf, enable? 1: 0); 2784 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 2785 2786 if (is_verify_set) { 2787 /* 2788 * preemption negotiation enabled - wait for the negotiation 2789 * to complete. 2790 * Wait time >= (num verify attempts + 1) * (verify timeout + 1) 2791 */ 2792 timeout = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2793 reg_val, VERIFY_TIMEf); 2794 num_attempts = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2795 reg_val, VERIFY_ATTEMPT_LIMITf); 2796 wait_time = (num_attempts + 1) * (timeout + 1); 2797 2798 /* wait for (timeout + 1) millsecs, and check verify status */ 2799 sal_udelay((timeout + 1) * 1000); 2800 2801 /* check verification status */ 2802 SOC_IF_ERROR_RETURN( 2803 READ_XLMAC_MERGE_VERIFY_STATEr(unit, port, &v_reg_val)); 2804 verify_status = soc_reg64_field32_get(unit, 2805 XLMAC_MERGE_VERIFY_STATEr, 2806 v_reg_val, 2807 PREEMPTION_VERIFY_STATUSf); 2808 if ((verify_status == XLMAC_PREEMPT_VERIFY_SUCCEED) || 2809 (verify_status == XLMAC_PREEMPT_VERIFY_FAILED)) { 2810 verify_op_done = 1; 2811 } 2812 2813 while (!verify_op_done) { 2814 sal_udelay((timeout + 1) * 1000); 2815 2816 /* check verification status */ 2817 SOC_IF_ERROR_RETURN( 2818 READ_XLMAC_MERGE_VERIFY_STATEr(unit, port, &v_reg_val)); 2819 verify_status = soc_reg64_field32_get(unit, 2820 XLMAC_MERGE_VERIFY_STATEr, 2821 v_reg_val, 2822 PREEMPTION_VERIFY_STATUSf); 2823 2824 /* break if verify operation done or timeout */ 2825 if ((verify_status == XLMAC_PREEMPT_VERIFY_SUCCEED) || 2826 (verify_status == XLMAC_PREEMPT_VERIFY_FAILED) || 2827 (((timeout + 1) * iter++) > wait_time)) { 2828 verify_op_done = 1; 2829 break; 2830 } 2831 } 2832 } 2833 2834 if (verify_op_done) { 2835 rc = (verify_status == XLMAC_PREEMPT_VERIFY_SUCCEED)? SOC_E_NONE: 2836 SOC_E_FAIL; 2837 } 2838 return (rc); 2839 } 2840 2841 int xlmac_preemption_tx_enable_get(int32 unit, soc_port_t port, uint32 *enable) 2842 { 2843 uint64 reg_val; 2844 2845 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2846 *enable = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2847 reg_val, PREEMPT_ENABLEf); 2848 2849 return (SOC_E_NONE); 2850 } 2851 2852 int xlmac_preemption_verify_enable_set(int32 unit, soc_port_t port, 2853 uint32 enable) 2854 { 2855 uint64 reg_val; 2856 int32 value = 0; 2857 2858 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2859 value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2860 reg_val, VERIFY_ENABLEf); 2861 2862 if (value != enable) { 2863 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 2864 ®_val, VERIFY_ENABLEf, enable? 1: 0); 2865 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 2866 } 2867 2868 return (SOC_E_NONE); 2869 } 2870 2871 int xlmac_preemption_verify_enable_get(int32 unit, soc_port_t port, 2872 uint32 *enable) 2873 { 2874 uint64 reg_val; 2875 2876 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2877 *enable = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2878 reg_val, VERIFY_ENABLEf); 2879 2880 return (SOC_E_NONE); 2881 } 2882 2883 int xlmac_preemption_verify_time_set(int32 unit, soc_port_t port, 2884 uint32 time_val) 2885 { 2886 uint64 reg_val; 2887 int32 value = 0; 2888 2889 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2890 value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2891 reg_val, VERIFY_TIMEf); 2892 2893 if (value != time_val) { 2894 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 2895 ®_val, VERIFY_TIMEf, time_val); 2896 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 2897 } 2898 2899 return (SOC_E_NONE); 2900 } 2901 2902 int xlmac_preemption_verify_time_get(int32 unit, soc_port_t port, 2903 uint32 *time_val) 2904 { 2905 uint64 reg_val; 2906 2907 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2908 *time_val = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2909 reg_val, VERIFY_TIMEf); 2910 2911 return (SOC_E_NONE); 2912 } 2913 2914 int xlmac_preemption_verify_attempts_set(int32 unit, soc_port_t port, 2915 uint32 num_attempts) 2916 { 2917 uint64 reg_val; 2918 int32 value = 0; 2919 2920 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2921 value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2922 reg_val, VERIFY_ATTEMPT_LIMITf); 2923 2924 if (value != num_attempts) { 2925 SOC_IF_ERROR_RETURN(soc_reg_field_validate(unit, XLMAC_MERGE_CONFIGr, 2926 VERIFY_ATTEMPT_LIMITf, 2927 num_attempts)); 2928 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 2929 ®_val, VERIFY_ATTEMPT_LIMITf, num_attempts); 2930 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 2931 } 2932 2933 return (SOC_E_NONE); 2934 } 2935 /*! 2936 * xlmac_timesync_tx_info_get 2937 * 2938 * @brief get port timestamps and sequence id form fifo 2939 * 2940 * @param [in] unit - unit id 2941 * @param [in] port - logical port 2942 * @param [in] tx _info - timestamp and seq id form fifo 2943 */ 2944 2945 int xlmac_timesync_tx_info_get (int unit, int port, 2946 portmod_fifo_status_t* tx_info) 2947 { 2948 uint64 rval; 2949 2950 RD_XLMAC(TX_TIMESTAMP_FIFO_STATUSr, unit, port, &rval); 2951 2952 if (soc_reg64_field32_get(unit, XLMAC_TX_TIMESTAMP_FIFO_STATUSr, rval, 2953 ENTRY_COUNTf) == 0) { 2954 return SOC_E_EMPTY; 2955 } 2956 2957 RD_XLMAC(TX_TIMESTAMP_FIFO_DATAr, unit, port, &rval); 2958 2959 tx_info->timestamps_in_fifo = soc_reg64_field32_get(unit, 2960 XLMAC_TX_TIMESTAMP_FIFO_DATAr, rval, TIME_STAMPf); 2961 tx_info->timestamps_in_fifo_hi = 0; 2962 tx_info->sequence_id = soc_reg64_field32_get(unit, 2963 XLMAC_TX_TIMESTAMP_FIFO_DATAr, rval, SEQUENCE_IDf); 2964 2965 return (SOC_E_NONE); 2966 } 2967 2968 int xlmac_preemption_verify_attempts_get(int32 unit, soc_port_t port, 2969 uint32 *num_attempts) 2970 { 2971 uint64 reg_val; 2972 2973 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 2974 *num_attempts = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 2975 reg_val, VERIFY_ATTEMPT_LIMITf); 2976 2977 return (SOC_E_NONE); 2978 } 2979 2980 int xlmac_preemption_tx_status_get(int unit, soc_port_t port, 2981 int flags, uint32 *value) 2982 { 2983 uint64 reg_val; 2984 int rv = SOC_E_NONE; 2985 2986 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_VERIFY_STATEr(unit, port, ®_val)); 2987 2988 switch (flags) { 2989 case XLMAC_PREEMPTION_TX_STATUS: 2990 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr, 2991 reg_val, PREEMPTION_TX_STATUSf); 2992 break; 2993 case XLMAC_PREEMPTION_VERIFY_STATUS: 2994 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr, 2995 reg_val, PREEMPTION_VERIFY_STATUSf); 2996 break; 2997 case XLMAC_PREEMPTION_VERIFY_CNT_STATUS: 2998 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_VERIFY_STATEr, 2999 reg_val, TX_VERIFY_CNT_STATUSf); 3000 break; 3001 default: 3002 rv = SOC_E_PARAM; 3003 } 3004 return rv; 3005 } 3006 3007 int xlmac_preemption_force_rx_lost_eop_set(int unit, soc_port_t port, 3008 int flags, uint32 value) 3009 { 3010 uint64 reg_val; 3011 int rv = SOC_E_NONE; 3012 3013 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 3014 3015 switch (flags) { 3016 case XLMAC_PREEMPTION_FORCE_SW_RX_EOP: 3017 /* 3018 * for forcing sw based rx lost eop, the sequence is to 3019 * write a zero to the field SW_FORCE_RX_LOST_EOPf wait 3020 * for a delay 10usecs, write a 1 to the field 3021 * SW_FORCE_RX_LOST_EOP 3022 */ 3023 if (value) { 3024 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 3025 ®_val, SW_FORCE_RX_LOST_EOPf, 0); 3026 SOC_IF_ERROR_RETURN( 3027 WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 3028 sal_udelay(10); 3029 } 3030 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 3031 ®_val, SW_FORCE_RX_LOST_EOPf, value); 3032 SOC_IF_ERROR_RETURN( 3033 WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 3034 break; 3035 case XLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP: 3036 soc_reg64_field32_set(unit, XLMAC_MERGE_CONFIGr, 3037 ®_val, AUTO_HW_FORCE_RX_LOST_EOPf, value); 3038 SOC_IF_ERROR_RETURN( 3039 WRITE_XLMAC_MERGE_CONFIGr(unit, port, reg_val)); 3040 break; 3041 default: 3042 rv = SOC_E_PARAM; 3043 } 3044 return rv; 3045 } 3046 3047 int xlmac_preemption_force_rx_lost_eop_get(int unit, soc_port_t port, 3048 int flags, uint32 *value) 3049 { 3050 uint64 reg_val; 3051 int rv = SOC_E_NONE; 3052 3053 SOC_IF_ERROR_RETURN(READ_XLMAC_MERGE_CONFIGr(unit, port, ®_val)); 3054 3055 switch (flags) { 3056 case XLMAC_PREEMPTION_FORCE_SW_RX_EOP: 3057 /* get the sw rx lost eop setting */ 3058 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 3059 reg_val, SW_FORCE_RX_LOST_EOPf); 3060 break; 3061 case XLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP: 3062 /* get the hw rx lost eop setting */ 3063 *value = soc_reg64_field32_get(unit, XLMAC_MERGE_CONFIGr, 3064 reg_val, AUTO_HW_FORCE_RX_LOST_EOPf); 3065 break; 3066 default: 3067 rv = SOC_E_PARAM; 3068 } 3069 return rv; 3070 } 3071 3072 int xlmac_preemption_rx_timeout_info_set(int unit, soc_port_t port, 3073 uint32 enable, uint32 timeout_val) 3074 { 3075 uint64 reg_val; 3076 3077 SOC_IF_ERROR_RETURN( 3078 READ_XLMAC_MERGE_RX_TIMEOUT_CONFIGr(unit, port, ®_val)); 3079 3080 soc_reg64_field32_set(unit, XLMAC_MERGE_RX_TIMEOUT_CONFIGr, 3081 ®_val, TIMEOUT_ENABLEf, enable? 1: 0); 3082 3083 soc_reg64_field32_set(unit, XLMAC_MERGE_RX_TIMEOUT_CONFIGr, 3084 ®_val, TIMEOUT_CNTf, timeout_val); 3085 3086 SOC_IF_ERROR_RETURN( 3087 WRITE_XLMAC_MERGE_RX_TIMEOUT_CONFIGr(unit, port, reg_val)); 3088 3089 return SOC_E_NONE; 3090 } 3091 3092 int xlmac_preemption_rx_timeout_info_get(int unit, soc_port_t port, 3093 uint32 *enable, uint32 *timeout_val) 3094 { 3095 uint64 reg_val; 3096 3097 SOC_IF_ERROR_RETURN( 3098 READ_XLMAC_MERGE_RX_TIMEOUT_CONFIGr(unit, port, ®_val)); 3099 3100 *enable = soc_reg64_field32_get(unit, XLMAC_MERGE_RX_TIMEOUT_CONFIGr, 3101 reg_val, TIMEOUT_ENABLEf); 3102 3103 *timeout_val = soc_reg64_field32_get(unit, XLMAC_MERGE_RX_TIMEOUT_CONFIGr, 3104 reg_val, TIMEOUT_CNTf); 3105 3106 return SOC_E_NONE; 3107 } 3108 3109 #undef _ERR_MSG_MODULE_NAME 3110 3111 3112 #endif /* PORTMOD_PM4X10_SUPPORT */