xmac.c (107083B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * XMAC driver 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <sal/core/libc.h> 13 #include <shared/alloc.h> 14 #include <sal/core/spl.h> 15 #include <sal/core/boot.h> 16 17 #include <soc/drv.h> 18 #include <soc/error.h> 19 #include <soc/cmic.h> 20 #include <soc/portmode.h> 21 #include <soc/ll.h> 22 #include <soc/counter.h> 23 #include <soc/macutil.h> 24 #include <soc/phyctrl.h> 25 #ifdef BCM_KATANA2_SUPPORT 26 #include <soc/katana2.h> 27 #endif 28 29 #ifdef BCM_XMAC_SUPPORT 30 31 #define XMAC_RUNT_THRESHOLD_GE 0x40 /* Runt threshold value for GE ports */ 32 #define XMAC_RUNT_THRESHOLD_XE 0x40 /* Runt threshold value for XE ports */ 33 #define XMAC_RUNT_THRESHOLD_HG1 0x48 /* Runt threshold value for HG1 ports */ 34 #define XMAC_RUNT_THRESHOLD_HG2 0x4c /* Runt threshold value for HG2 ports */ 35 #define IPG_BYTE(a) ((a / 8) & 0x1f) 36 37 /* 38 * XMAC Register field definitions. 39 */ 40 41 /* Transmit CRC Modes (Receive has bit field definitions in register) */ 42 #define XMAC_CRC_APPEND 0x00 /* Append CRC (Default) */ 43 #define XMAC_CRC_KEEP 0x01 /* CRC Assumed correct */ 44 #define XMAC_CRC_REGEN 0x02 /* Replace CRC with a new one */ 45 #define XMAC_CRC_RSVP 0x03 /* Reserved (does Replace) */ 46 47 #define JUMBO_MAXSZ 0x3fe8 /* Max legal value (per regsfile) */ 48 49 mac_driver_t soc_mac_x; 50 51 #ifdef BROADCOM_DEBUG 52 static char *mac_x_encap_mode[] = SOC_ENCAP_MODE_NAMES_INITIALIZER; 53 static char *mac_x_port_if_names[] = SOC_PORT_IF_NAMES_INITIALIZER; 54 #endif /* BROADCOM_DEBUG */ 55 56 #define SOC_XMAC_SPEED_10 0x0 57 #define SOC_XMAC_SPEED_100 0x1 58 #define SOC_XMAC_SPEED_1000 0x2 59 #define SOC_XMAC_SPEED_2500 0x3 60 #define SOC_XMAC_SPEED_10000 0x4 61 62 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 63 typedef struct { 64 uint64 mac_ctrl; 65 uint64 rx_ctrl; 66 uint64 tx_ctrl; 67 uint64 pfc_ctrl; 68 uint64 rx_max_size; 69 uint64 mac_mode; 70 uint64 pause_ctrl; 71 uint64 rx_mac_sa; 72 uint64 tx_mac_sa; 73 uint64 pfc_da; 74 uint64 llfc_ctrl; 75 uint64 eee_ctrl; 76 uint64 eee_timers; 77 uint64 rx_lss_ctrl; 78 uint64 rx_vlan_tag; 79 } _mac_x_cfg_t; 80 #endif 81 82 /* Forward declarations */ 83 STATIC int mac_x_loopback_set(int unit, soc_port_t port, int lb); 84 STATIC int mac_x_loopback_get(int unit, soc_port_t port, int *lb); 85 STATIC int mac_x_frame_max_set(int unit, soc_port_t port, int size); 86 STATIC int mac_x_frame_max_get(int unit, soc_port_t port, int *size); 87 STATIC int mac_x_pause_set(int unit, soc_port_t port, int pause_tx, int pause_rx); 88 STATIC int mac_x_pause_get(int unit, soc_port_t port, int *pause_tx, int *pause_rx); 89 90 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 91 /* xmac tx/rx clock rates for various speeds from xmac spec*/ 92 struct { 93 int speed; 94 uint32 xmac_clk; 95 }_mac_x_clock_rate[] = { 96 { 40000, 312 }, 97 { 20000, 156 }, 98 { 10000, 78 }, 99 { 2500, 312 }, 100 { 1000, 125 }, 101 { 100, 25 }, 102 }; 103 STATIC int 104 mac_x_speed_get(int unit, soc_port_t port, int *speed); 105 106 void 107 _mac_x_speed_to_clock_rate(int unit, soc_port_t port, int speed, uint32 *clk_rate) 108 { 109 int idx; 110 111 *clk_rate = 0; 112 if (speed == _mac_x_clock_rate[0].speed) { 113 /* Max Speed */ 114 *clk_rate = _mac_x_clock_rate[0].xmac_clk; 115 } else { 116 for (idx = 1; idx < sizeof(_mac_x_clock_rate) / 117 sizeof(_mac_x_clock_rate[0]); idx++) { 118 if ((speed >=_mac_x_clock_rate[idx].speed) && 119 (speed < _mac_x_clock_rate[idx-1].speed)) { 120 *clk_rate = _mac_x_clock_rate[idx].xmac_clk; 121 break; 122 } 123 } 124 if (*clk_rate == 0) { 125 /* Min speed */ 126 *clk_rate = _mac_x_clock_rate[idx-1].xmac_clk; 127 } 128 } 129 } 130 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) */ 131 132 #ifndef BCM_TRIUMPH3_SUPPORT 133 STATIC 134 #endif 135 int 136 _mac_x_drain_cells(int unit, soc_port_t port, int notify_phy) 137 { 138 int rv; 139 int pause_tx, pause_rx, pfc_rx, llfc_rx; 140 #ifdef BCM_KATANA_SUPPORT 141 uint32 rval = 0; 142 #endif 143 144 rv = SOC_E_NONE; 145 146 if (SOC_IS_RELOADING(unit)) { 147 return rv; 148 } 149 150 #ifdef BCM_TRIUMPH3_SUPPORT 151 /* Skipping in for Disabled Ports */ 152 if (SOC_IS_TRIUMPH3(unit)) { 153 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 154 return SOC_E_NONE; 155 } 156 } 157 #endif 158 159 #ifdef BCM_KATANA_SUPPORT 160 if (SOC_IS_KATANAX(unit)) { 161 READ_XP_TXFIFO_PKT_DROP_CTLr(unit, port, &rval); 162 soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval, 163 DROP_ENf, 1); 164 WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, port, rval); 165 } 166 #endif /* BCM_KATANA2_SUPPORT */ 167 /* Drain cells in mmu/port before cells entering TX FIFO */ 168 SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, port, TRUE)); 169 170 /* Disable pause/pfc/llfc function */ 171 SOC_IF_ERROR_RETURN 172 (soc_mac_x.md_pause_get(unit, port, &pause_tx, &pause_rx)); 173 SOC_IF_ERROR_RETURN 174 (soc_mac_x.md_pause_set(unit, port, pause_tx, 0)); 175 176 SOC_IF_ERROR_RETURN 177 (soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 178 &pfc_rx)); 179 SOC_IF_ERROR_RETURN 180 (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 181 0)); 182 183 SOC_IF_ERROR_RETURN 184 (soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 185 &llfc_rx)); 186 SOC_IF_ERROR_RETURN 187 (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 188 0)); 189 190 /* Drain data in TX FIFO without egressing */ 191 SOC_IF_ERROR_RETURN 192 (soc_reg_field32_modify(unit, XMAC_TX_CTRLr, port, DISCARDf, 1)); 193 194 if (notify_phy == 1) { 195 /* Notify PHY driver */ 196 SOC_IF_ERROR_RETURN 197 (soc_phyctrl_notify(unit, port, phyEventStop, PHY_STOP_DRAIN)); 198 } 199 /* Wait until mmu cell count is 0 */ 200 rv = soc_egress_drain_cells(unit, port, 250000); 201 if (SOC_E_NONE == rv) { 202 /* Wait until TX fifo cell count is 0 */ 203 rv = soc_txfifo_drain_cells(unit, port, 250000); 204 } 205 206 /* Notify PHY driver */ 207 if (notify_phy == 1) { 208 SOC_IF_ERROR_RETURN 209 (soc_phyctrl_notify(unit, port, phyEventResume, PHY_STOP_DRAIN)); 210 } 211 /* Stop TX FIFO drainging */ 212 SOC_IF_ERROR_RETURN 213 (soc_reg_field32_modify(unit, XMAC_TX_CTRLr, port, DISCARDf, 0)); 214 215 /* Restore original pause/pfc/llfc configuration */ 216 SOC_IF_ERROR_RETURN 217 (soc_mac_x.md_pause_set(unit, port, pause_tx, pause_rx)); 218 SOC_IF_ERROR_RETURN 219 (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 220 pfc_rx)); 221 SOC_IF_ERROR_RETURN 222 (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 223 llfc_rx)); 224 225 #ifdef BCM_KATANA_SUPPORT 226 if (SOC_IS_KATANAX(unit)) { 227 READ_XP_TXFIFO_PKT_DROP_CTLr(unit, port, &rval); 228 soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval, 229 DROP_ENf, 0); 230 WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, port, rval); 231 } else 232 #endif 233 { 234 /* Stop draining cells in mmu/port */ 235 SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, port, FALSE)); 236 } 237 238 return rv; 239 } 240 241 #if defined(BCM_SHADOW_SUPPORT) 242 /* Shadow specific initializations */ 243 244 STATIC int 245 __shadow_petrab_mac_x_init(int unit, soc_port_t port) 246 { 247 uint64 reg64; 248 249 /* add Rx+Tx CRC insert/terminate */ 250 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, ®64)); 251 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, ®64, CRC_MODEf, XMAC_CRC_APPEND); 252 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, reg64)); 253 254 /* xmac Rx ctrl */ 255 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, ®64)); 256 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, ®64, STRIP_CRCf, 1); 257 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, reg64)); 258 259 /* XMAC Pause Ctrl */ 260 SOC_IF_ERROR_RETURN (READ_XMAC_PAUSE_CTRLr(unit, port, ®64)); 261 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, ®64, 262 RX_PAUSE_ENf, 0); 263 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, ®64, 264 TX_PAUSE_ENf, 0); 265 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, ®64, 266 PAUSE_REFRESH_ENf, 0); 267 SOC_IF_ERROR_RETURN (WRITE_XMAC_PAUSE_CTRLr(unit, port, reg64)); 268 269 /* xmac pfc ctrl */ 270 SOC_IF_ERROR_RETURN (READ_XMAC_PFC_CTRLr(unit, port, ®64)); 271 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, ®64, 272 PFC_REFRESH_ENf, 1); 273 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, ®64, 274 PFC_STATS_ENf, 1); 275 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, ®64, 276 RX_PFC_ENf, 1); 277 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, ®64, 278 TX_PFC_ENf, 1); 279 SOC_IF_ERROR_RETURN (WRITE_XMAC_PFC_CTRLr(unit, port, reg64)); 280 281 /* Set Max pkt Size */ 282 SOC_IF_ERROR_RETURN 283 (soc_reg_field32_modify(unit, XMAC_RX_MAX_SIZEr, port, 284 RX_MAX_SIZEf, 16256)); 285 286 return SOC_E_NONE; 287 } 288 289 STATIC int 290 __shadow_mac_x_init(int unit, soc_port_t port) 291 { 292 uint64 tx_ctrl, rval, data; 293 294 LOG_VERBOSE(BSL_LS_SOC_10G, 295 (BSL_META_U(unit, 296 "__shadow_mac_x_init: unit %d port %s\n"), 297 unit, SOC_PORT_NAME(unit, port))); 298 299 { 300 if (IS_XE_PORT(unit, port)) { 301 SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr(unit, port, &data)); 302 soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &data, RX_MAX_SIZEf, 9600); 303 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, data)); 304 305 /* Initialize additional device mode xmac configurations */ 306 if (soc_property_get(unit, spn_BCM88732_DEVICE_MODE, 0)) { 307 SOC_IF_ERROR_RETURN(__shadow_petrab_mac_x_init(unit, port)); 308 } 309 } 310 } 311 312 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &tx_ctrl)); 313 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, PAD_ENf, 1); 314 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, tx_ctrl)); 315 316 /* Setup header mode, check for property for bcm5632 mode */ 317 COMPILER_64_ZERO(rval); 318 SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, rval)); 319 320 return SOC_E_NONE; 321 } 322 #endif /* BCM_SHADOW_SUPPORT */ 323 324 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 325 STATIC int _mac_x_register_store(int unit, soc_port_t port, _mac_x_cfg_t *port_cfg) 326 { 327 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &port_cfg->mac_ctrl)); 328 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &port_cfg->rx_ctrl)); 329 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &port_cfg->tx_ctrl)); 330 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &port_cfg->pfc_ctrl)); 331 SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr(unit, port, &port_cfg->rx_max_size)); 332 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &port_cfg->mac_mode)); 333 SOC_IF_ERROR_RETURN(READ_XMAC_PAUSE_CTRLr(unit, port, &port_cfg->pause_ctrl)); 334 SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAC_SAr(unit, port, &port_cfg->rx_mac_sa)); 335 SOC_IF_ERROR_RETURN(READ_XMAC_TX_MAC_SAr(unit, port, &port_cfg->tx_mac_sa)); 336 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &port_cfg->pfc_da)); 337 SOC_IF_ERROR_RETURN(READ_XMAC_LLFC_CTRLr(unit, port, &port_cfg->llfc_ctrl)); 338 SOC_IF_ERROR_RETURN(READ_XMAC_EEE_CTRLr(unit, port, &port_cfg->eee_ctrl)); 339 SOC_IF_ERROR_RETURN(READ_XMAC_EEE_TIMERSr(unit, port, &port_cfg->eee_timers)); 340 SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_CTRLr(unit, port, &port_cfg->rx_lss_ctrl)); 341 SOC_IF_ERROR_RETURN(READ_XMAC_RX_VLAN_TAGr(unit, port, &port_cfg->rx_vlan_tag)); 342 return SOC_E_NONE; 343 } 344 345 STATIC int _mac_x_register_restore(int unit, soc_port_t port, _mac_x_cfg_t *port_cfg) 346 { 347 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, port_cfg->mac_ctrl)); 348 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, port_cfg->rx_ctrl)); 349 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, port_cfg->tx_ctrl)); 350 SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_CTRLr(unit, port, port_cfg->pfc_ctrl)); 351 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, port_cfg->rx_max_size)); 352 SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, port_cfg->mac_mode)); 353 SOC_IF_ERROR_RETURN(WRITE_XMAC_PAUSE_CTRLr(unit, port, port_cfg->pause_ctrl)); 354 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAC_SAr(unit, port, port_cfg->rx_mac_sa)); 355 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_MAC_SAr(unit, port, port_cfg->tx_mac_sa)); 356 SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_DAr(unit, port, port_cfg->pfc_da)); 357 SOC_IF_ERROR_RETURN(WRITE_XMAC_LLFC_CTRLr(unit, port, port_cfg->llfc_ctrl)); 358 SOC_IF_ERROR_RETURN(WRITE_XMAC_EEE_CTRLr(unit, port, port_cfg->eee_ctrl)); 359 SOC_IF_ERROR_RETURN(WRITE_XMAC_EEE_TIMERSr(unit, port, port_cfg->eee_timers)); 360 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_LSS_CTRLr(unit, port, port_cfg->rx_lss_ctrl)); 361 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_VLAN_TAGr(unit, port, port_cfg->rx_vlan_tag)); 362 return SOC_E_NONE; 363 } 364 365 /* 366 * Function: 367 * _bcm_port_mac_reinit 368 * Purpose: 369 * Resets the MAC and restores the configured values. 370 */ 371 372 int 373 _mac_x_reinit(int unit, soc_port_t port) 374 { 375 _mac_x_cfg_t *pcfg; 376 static const soc_field_t mac_field[] = { 377 XMAC0_RESETf, 378 XMAC1_RESETf, 379 XMAC2_RESETf 380 }; 381 382 int blk_num = 0, phy_port, phy_port_base = 0; 383 soc_port_t l_port =0; 384 soc_info_t *si; 385 int core_index = -1, i; 386 uint32 rval; 387 #if defined(BCM_KATANA2_SUPPORT) 388 uint8 mxqblock = 0, mxqblock_port = 0; 389 #endif 390 si = &SOC_INFO(unit); 391 392 phy_port = (soc_feature(unit, soc_feature_logical_port_num)) 393 ? si->port_l2p_mapping[port] : port; 394 if (phy_port == -1) { 395 return SOC_E_INTERNAL; 396 } 397 398 core_index = SOC_PORT_BINDEX(unit, phy_port) / 4; 399 pcfg = (_mac_x_cfg_t *) sal_alloc( 400 sizeof(_mac_x_cfg_t) * 4,"MAC config"); 401 if (pcfg == NULL) { 402 return SOC_E_MEMORY; 403 } 404 /* Store MAC settings */ 405 #if defined(BCM_KATANA2_SUPPORT) 406 if (SOC_IS_KATANA2(unit)) { 407 SOC_IF_ERROR_CLEAN_RETURN(soc_katana2_get_port_mxqblock( 408 unit, port, &mxqblock), sal_free(pcfg)); 409 for (i = 0; i < KT2_MAX_MXQPORTS_PER_BLOCK; i++) { 410 mxqblock_port = (*kt2_mxqblock_ports[unit])[mxqblock][i]; 411 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 412 SOC_IF_ERROR_CLEAN_RETURN 413 (_mac_x_register_store(unit, mxqblock_port, &pcfg[i]), 414 sal_free(pcfg)); 415 } 416 } 417 } else 418 #endif 419 #if defined(BCM_TRIDENT_SUPPORT) 420 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 421 phy_port_base = ((phy_port - 1)/4)*4 + 1; 422 for (i = 0; i < 4; i++) { 423 l_port = si->port_p2l_mapping[phy_port_base+i]; 424 if(l_port == -1) { 425 continue; 426 } 427 if(0 == si->port_num_lanes[l_port]) { 428 continue; 429 } 430 SOC_IF_ERROR_CLEAN_RETURN 431 (_mac_x_register_store(unit, l_port, &pcfg[i]), sal_free(pcfg)); 432 } 433 } else 434 #endif 435 { 436 blk_num = SOC_PORT_BLOCK(unit, phy_port); 437 phy_port_base = si->blk_fpp[blk_num] + core_index*4; 438 for (i = 0; i < 4; i++) { 439 l_port = si->port_p2l_mapping[phy_port_base+i]; 440 if(l_port == -1) { 441 continue; 442 } 443 if(0 == si->port_num_lanes[l_port]) { 444 continue; 445 } 446 SOC_IF_ERROR_CLEAN_RETURN 447 (_mac_x_register_store(unit, l_port, &pcfg[i]), sal_free(pcfg)); 448 } 449 } 450 /* Hard reset */ 451 #if defined(BCM_KATANA2_SUPPORT) 452 if (SOC_IS_KATANA2(unit)) { 453 SOC_IF_ERROR_CLEAN_RETURN(READ_XPORT_XMAC_CONTROLr(unit, port, &rval), sal_free(pcfg)); 454 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 455 SOC_IF_ERROR_CLEAN_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg)); 456 sal_udelay(10); 457 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 458 SOC_IF_ERROR_CLEAN_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg)); 459 } else 460 #endif 461 #if defined(BCM_TRIDENT_SUPPORT) 462 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 463 SOC_IF_ERROR_CLEAN_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, port, &rval), sal_free(pcfg)); 464 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 465 SOC_IF_ERROR_CLEAN_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg)); 466 sal_udelay(10); 467 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 468 SOC_IF_ERROR_CLEAN_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg)); 469 } else 470 #endif 471 { 472 SOC_IF_ERROR_CLEAN_RETURN(READ_PORT_MAC_CONTROLr(unit, port, &rval),sal_free(pcfg)); 473 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 474 mac_field[core_index], 1); 475 SOC_IF_ERROR_CLEAN_RETURN(WRITE_PORT_MAC_CONTROLr(unit, port, rval),sal_free(pcfg)); 476 sal_udelay(10); 477 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 478 mac_field[core_index], 0); 479 SOC_IF_ERROR_CLEAN_RETURN(WRITE_PORT_MAC_CONTROLr(unit, port, rval),sal_free(pcfg)); 480 } 481 sal_udelay(10); 482 #if defined(BCM_KATANA2_SUPPORT) 483 if (SOC_IS_KATANA2(unit)) { 484 /* Restore MAC settings. */ 485 SOC_IF_ERROR_CLEAN_RETURN(soc_katana2_get_port_mxqblock( 486 unit, port, &mxqblock), sal_free(pcfg)); 487 for (i = 0; i < KT2_MAX_MXQPORTS_PER_BLOCK; i++) { 488 mxqblock_port = (*kt2_mxqblock_ports[unit])[mxqblock][i]; 489 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 490 SOC_IF_ERROR_CLEAN_RETURN 491 (_mac_x_register_restore(unit, mxqblock_port, &pcfg[i]), 492 sal_free(pcfg)); 493 } 494 } 495 } else 496 #endif 497 #if defined(BCM_TRIDENT_SUPPORT) 498 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 499 for (i = 0; i < 4; i++) { 500 l_port = si->port_p2l_mapping[phy_port_base+i]; 501 if(l_port == -1) { 502 continue; 503 } 504 if(0 == si->port_num_lanes[l_port]) { 505 continue; 506 } 507 /* Restore MAC settings. */ 508 SOC_IF_ERROR_CLEAN_RETURN 509 (_mac_x_register_restore(unit, l_port, &pcfg[i]), sal_free(pcfg)); 510 } 511 } else 512 #endif 513 { 514 for (i = 0; i < 4; i++) { 515 l_port = si->port_p2l_mapping[phy_port_base+i]; 516 if(l_port == -1) { 517 continue; 518 } 519 if(0 == si->port_num_lanes[l_port]) { 520 continue; 521 } 522 /* Restore MAC settings. */ 523 SOC_IF_ERROR_CLEAN_RETURN 524 (_mac_x_register_restore(unit, l_port, &pcfg[i]), sal_free(pcfg)); 525 } 526 } 527 sal_free(pcfg); 528 return SOC_E_NONE; 529 } 530 #endif 531 532 533 /* 534 * Function: 535 * mac_x_init 536 * Purpose: 537 * Initialize Xmac into a known good state. 538 * Parameters: 539 * unit - XGS unit #. 540 * port - Port number on unit. 541 * Returns: 542 * SOC_E_XXX 543 * Notes: 544 */ 545 STATIC int 546 mac_x_init(int unit, soc_port_t port) 547 { 548 soc_info_t *si; 549 uint64 mac_ctrl, rx_ctrl, tx_ctrl, rval; 550 uint32 ipg; 551 int mode; 552 553 #if defined(BCM_KATANA2_SUPPORT) 554 int sgn_det = 0; 555 uint32 sgn_crs; 556 #endif 557 558 LOG_VERBOSE(BSL_LS_SOC_10G, 559 (BSL_META_U(unit, 560 "mac_x_init: unit %d port %s\n"), 561 unit, SOC_PORT_NAME(unit, port))); 562 563 si = &SOC_INFO(unit); 564 565 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &mac_ctrl)); 566 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, SOFT_RESETf, 1); 567 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, mac_ctrl)); 568 569 /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */ 570 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &mac_ctrl)); 571 572 if (IS_HG_PORT(unit, port)) { 573 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, SOFT_RESETf, 0); 574 } 575 576 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, RX_ENf, 0); 577 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, TX_ENf, 0); 578 if ((si->port_speed_max[port] == 40000) || 579 (si->port_speed_max[port]) == 42000) { 580 int xlgmii_align = 0; 581 582 if (IS_XE_PORT(unit, port)) { 583 xlgmii_align = 1; 584 } else { /* HG port with external PHY may also use IEEE 40G mld-4 */ 585 if (PHY_EXTERNAL_MODE(unit, port) 586 && (!PHY_PASSTHRU_MODE(unit, port)) 587 && (!soc_property_port_get(unit, port, 588 spn_PORT_PHY_MODE_REVERSE, 0))) { 589 xlgmii_align = 1; 590 } 591 } 592 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, XLGMII_ALIGN_ENBf, 593 xlgmii_align); 594 } 595 if (soc_reg_field_valid(unit, XMAC_CTRLr, XGMII_IPG_CHECK_DISABLEf)) { 596 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, 597 XGMII_IPG_CHECK_DISABLEf, 598 IS_HG_PORT(unit, port) ? 1 : 0); 599 } 600 601 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, mac_ctrl)); 602 603 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rx_ctrl)); 604 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, STRIP_CRCf, 0); 605 606 #ifdef BCM_TRIUMPH3_SUPPORT 607 if (SOC_IS_TRIUMPH3(unit) && IS_HG_PORT(unit, port)) { 608 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, RUNT_THRESHOLDf, 609 XMAC_RUNT_THRESHOLD_HG1); 610 } 611 #endif /* BCM_TRIUMPH3_SUPPORT */ 612 613 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rx_ctrl)); 614 615 616 /* XMAC_TX_CTRL settings */ 617 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &tx_ctrl)); 618 if(IS_XE_PORT(unit,port) || IS_GE_PORT(unit, port)) { 619 ipg = SOC_PERSIST(unit)->ipg[port].fd_xe; 620 } else { 621 ipg = soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0) ? 622 SOC_PERSIST(unit)->ipg[port].fd_hg2 : 623 SOC_PERSIST(unit)->ipg[port].fd_hg; 624 } 625 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf, 626 IPG_BYTE(ipg)); 627 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, CRC_MODEf, 3); 628 #if defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 629 if (SOC_IS_TRIUMPH3(unit)) { 630 if ((si->port_speed_max[port] > 1000 && 631 si->port_speed_max[port] <= 3000) || 632 IS_XL_PORT(unit, port)) { 633 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, 634 TX_64BYTE_BUFFER_ENf, 1); 635 } 636 } 637 #endif /* defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) */ 638 #ifdef BCM_KATANA2_SUPPORT 639 if (SOC_IS_KATANA2(unit)) { 640 if (si->port_speed_max[port] <= 2500) { 641 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, 642 TX_64BYTE_BUFFER_ENf, 1); 643 } 644 if (SOC_PBMP_MEMBER(si->linkphy_pbm, port)) { 645 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, CRC_MODEf, 0); 646 } 647 } 648 #endif 649 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, tx_ctrl)); 650 651 if (IS_ST_PORT(unit, port)) { 652 soc_mac_x.md_pause_set(unit, port, FALSE, FALSE); 653 } else { 654 soc_mac_x.md_pause_set(unit, port, TRUE, TRUE); 655 } 656 657 SOC_IF_ERROR_RETURN 658 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, PFC_REFRESH_ENf, 659 1)); 660 661 if (soc_property_port_get(unit, port, spn_PHY_WAN_MODE, FALSE)) { 662 /* Max speed for WAN mode is 9.294Gbps. 663 * This setting gives 10Gbps * (13/14) or 9.286 Gbps */ 664 SOC_IF_ERROR_RETURN 665 (soc_mac_x.md_control_set(unit, port, 666 SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, 667 13)); 668 } 669 670 /* Set jumbo max size (8000 byte payload) */ 671 COMPILER_64_ZERO(rval); 672 #ifdef BCM_XGS_SUPPORT 673 if (SOC_IS_XGS(unit)) { 674 soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf, 675 SOC_INFO(unit).max_mtu); 676 } else 677 #endif 678 { 679 soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf, 680 JUMBO_MAXSZ); 681 } 682 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, rval)); 683 684 /* Setup header mode, check for property for higig2 mode */ 685 COMPILER_64_ZERO(rval); 686 if (!IS_XE_PORT(unit, port) && !IS_GE_PORT(unit, port)) { 687 mode = soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0) ? 688 2 : 1; 689 soc_reg64_field32_set(unit, XMAC_MODEr, &rval, HDR_MODEf, mode); 690 } 691 if (soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) { 692 switch (si->port_speed_max[port]) { 693 case 10: 694 mode = SOC_XMAC_SPEED_10; 695 break; 696 case 100: 697 mode = SOC_XMAC_SPEED_100; 698 break; 699 case 1000: 700 mode = SOC_XMAC_SPEED_1000; 701 break; 702 case 2500: 703 case 3000: 704 mode = SOC_XMAC_SPEED_2500; 705 break; 706 default: 707 mode = SOC_XMAC_SPEED_10000; 708 break; 709 } 710 soc_reg64_field32_set(unit, XMAC_MODEr, &rval, SPEED_MODEf, mode); 711 } 712 SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, rval)); 713 714 /* XMAC_RX_CTRL settings */ 715 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rx_ctrl)); 716 717 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 718 defined(BCM_KATANA_SUPPORT) 719 720 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ) { 721 if (IS_GE_PORT(unit, port)) { 722 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 723 STRICT_PREAMBLEf, 0); 724 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 725 PROCESS_VARIABLE_PREAMBLEf, 1); 726 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval, 727 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_GE); 728 729 } else if (IS_XE_PORT(unit, port)) { 730 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 731 STRICT_PREAMBLEf, 1); 732 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 733 PROCESS_VARIABLE_PREAMBLEf, 0); 734 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval, 735 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_XE); 736 737 } else if (IS_HG_PORT(unit, port)) { 738 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 739 STRICT_PREAMBLEf, 0); 740 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 741 PROCESS_VARIABLE_PREAMBLEf, 0); 742 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 743 RX_PASS_CTRLf, 1); 744 if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0)) { 745 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 746 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG2); 747 } else { 748 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 749 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG1); 750 } 751 752 } 753 } else if (SOC_IS_KATANA(unit)) { 754 if (IS_GE_PORT(unit, port) || IS_XE_PORT(unit, port)) { 755 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 756 STRICT_PREAMBLEf, 0); 757 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 758 PROCESS_VARIABLE_PREAMBLEf, 1); 759 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 760 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_XE); 761 } else if (IS_HG_PORT(unit, port)) { 762 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 763 STRICT_PREAMBLEf, 0); 764 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 765 PROCESS_VARIABLE_PREAMBLEf, 0); 766 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 767 RX_PASS_CTRLf, 1); 768 if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0)) { 769 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 770 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG2); 771 } else { 772 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 773 RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG1); 774 } 775 } 776 } 777 778 if (SOC_IS_KATANA2(unit) && SOC_PBMP_MEMBER(si->linkphy_pbm, port)) { 779 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, STRIP_CRCf, 1); 780 } 781 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT || 782 BCM_KATANA_SUPPORT */ 783 #if defined(BCM_TRIDENT_SUPPORT) 784 if ((SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) && IS_HG_PORT(unit, port)) { 785 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, RUNT_THRESHOLDf, 786 soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0)? 787 XMAC_RUNT_THRESHOLD_HG2 : XMAC_RUNT_THRESHOLD_HG1); 788 } 789 #endif /* BCM_TRIDENT_SUPPORT*/ 790 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rx_ctrl)); 791 792 793 #if defined(BCM_SHADOW_SUPPORT) 794 /* Shadow Specific Initialization */ 795 if (SOC_IS_SHADOW(unit)) { 796 SOC_IF_ERROR_RETURN(__shadow_mac_x_init(unit, port)); 797 } 798 #endif /* BCM_SHADOW_SUPPORT */ 799 800 /* Disable loopback and bring XMAC out of reset */ 801 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, CORE_REMOTE_LPBKf, 0); 802 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, LINE_REMOTE_LPBKf, 0); 803 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, CORE_LOCAL_LPBKf, 0); 804 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, LINE_LOCAL_LPBKf, 0); 805 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, RX_ENf, 1); 806 soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, TX_ENf, 1); 807 808 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, mac_ctrl)); 809 810 #if defined(BCM_KATANA2_SUPPORT) 811 if (SOC_IS_KATANA2(unit)) { 812 sgn_det = soc_property_port_get(unit, port, spn_SERDES_RX_LOS, 0); 813 SOC_IF_ERROR_RETURN(READ_X_GPORT_SGNDET_EARLYCRSr(unit, port, &sgn_crs)); 814 soc_reg_field_set(unit, X_GPORT_SGNDET_EARLYCRSr, &sgn_crs, SGN_DETf, sgn_det); 815 SOC_IF_ERROR_RETURN(WRITE_X_GPORT_SGNDET_EARLYCRSr(unit, port, sgn_crs)); 816 } 817 #endif 818 819 return SOC_E_NONE; 820 } 821 822 /* 823 * Function: 824 * mac_x_enable_set 825 * Purpose: 826 * Drain the egress queues with out bringing down the port 827 * Parameters: 828 * unit - XGS unit #. 829 * port - Port number on unit. 830 * Returns: 831 * SOC_E_XXX 832 */ 833 STATIC int 834 mac_x_egress_queue_drain(int unit, soc_port_t port) 835 { 836 uint64 ctrl; 837 pbmp_t mask; 838 int rx_enable = 0; 839 840 LOG_VERBOSE(BSL_LS_SOC_10G, 841 (BSL_META_U(unit, 842 "mac_x_egress_queue_drain_set: unit %d port %s\n"), 843 unit, SOC_PORT_NAME(unit, port))); 844 845 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 846 847 rx_enable = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, RX_ENf); 848 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0); 849 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 850 sal_udelay(10); 851 852 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 1); 853 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 854 855 soc_link_mask2_get(unit, &mask); 856 SOC_PBMP_PORT_REMOVE(mask, port); 857 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 858 SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 0)); 859 860 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 861 862 /* Remove SOFT_RESET before RX_EN */ 863 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 0); 864 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 865 866 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1); 867 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, rx_enable ? 1 : 0); 868 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 869 sal_udelay(10); 870 871 soc_link_mask2_get(unit, &mask); 872 SOC_PBMP_PORT_ADD(mask, port); 873 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 874 875 return SOC_E_NONE; 876 } 877 /* 878 * Function: 879 * mac_x_enable_set 880 * Purpose: 881 * Enable or disable MAC 882 * Parameters: 883 * unit - XGS unit #. 884 * port - Port number on unit. 885 * enable - TRUE to enable, FALSE to disable 886 * Returns: 887 * SOC_E_XXX 888 */ 889 STATIC int 890 mac_x_enable_set(int unit, soc_port_t port, int enable) 891 { 892 uint64 ctrl; 893 pbmp_t mask; 894 895 LOG_VERBOSE(BSL_LS_SOC_10G, 896 (BSL_META_U(unit, 897 "mac_x_enable_set: unit %d port %s enable=%s\n"), 898 unit, SOC_PORT_NAME(unit, port), 899 enable ? "True" : "False")); 900 901 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 902 903 if (enable) { 904 /* Remove SOFT_RESET before RX_EN */ 905 #ifdef BCM_KATANA_SUPPORT 906 if (SOC_IS_KATANAX(unit)) { 907 SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, port, FALSE)); 908 } 909 #endif 910 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 0); 911 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 912 913 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1); 914 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 1); 915 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 916 sal_udelay(10); 917 918 soc_link_mask2_get(unit, &mask); 919 SOC_PBMP_PORT_ADD(mask, port); 920 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 921 SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventResume, 922 PHY_STOP_MAC_DIS)); 923 } else { 924 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0); 925 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 926 sal_udelay(10); 927 928 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 1); 929 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 930 931 soc_link_mask2_get(unit, &mask); 932 SOC_PBMP_PORT_REMOVE(mask, port); 933 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 934 SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 1)); 935 SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventStop, 936 PHY_STOP_MAC_DIS)); 937 } 938 939 return SOC_E_NONE; 940 } 941 942 /* 943 * Function: 944 * mac_x_enable_get 945 * Purpose: 946 * Get MAC enable state 947 * Parameters: 948 * unit - XGS unit #. 949 * port - Port number on unit. 950 * enable - (OUT) TRUE if enabled, FALSE if disabled 951 * Returns: 952 * SOC_E_XXX 953 */ 954 STATIC int 955 mac_x_enable_get(int unit, soc_port_t port, int *enable) 956 { 957 uint64 ctrl; 958 959 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 960 961 *enable = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, RX_ENf); 962 963 LOG_VERBOSE(BSL_LS_SOC_10G, 964 (BSL_META_U(unit, 965 "mac_x_enable_get: unit %d port %s enable=%s\n"), 966 unit, SOC_PORT_NAME(unit, port), 967 *enable ? "True" : "False")); 968 969 return SOC_E_NONE; 970 } 971 972 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 973 /* 974 * Function: 975 * _mac_x_timestamp_delay_set 976 * Purpose: 977 * Set Timestamp delay for one-step to account for lane and pipeline delay. 978 * Parameters: 979 * unit - XGS unit #. 980 * port - Port number on unit. 981 * speed - Speed 982 * phy_mode - single/dual/quad phy mode 983 * Returns: 984 * SOC_E_XXX 985 */ 986 STATIC int 987 _mac_x_timestamp_delay_set(int unit, soc_port_t port, int speed, int phy_mode) 988 { 989 uint64 ctrl; 990 uint32 clk_rate, tx_clk_ns; 991 int osts_delay, delay; 992 uint32 field; 993 994 LOG_VERBOSE(BSL_LS_SOC_10G, 995 (BSL_META_U(unit, 996 "mac_x_timestamp_delay_set: unit %d port %s\n"), 997 unit, SOC_PORT_NAME(unit, port))); 998 999 if (SOC_REG_IS_VALID(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr)) { 1000 SOC_IF_ERROR_RETURN(READ_XMAC_OSTS_TIMESTAMP_ADJUSTr(unit, port, &ctrl)); 1001 1002 _mac_x_speed_to_clock_rate(unit, port, speed, &clk_rate); 1003 /* Tx clock rate for single/dual/quad phy mode */ 1004 if ((speed >= 10000) && (speed <= 40000)) { 1005 /* tx clock rate in ns */ 1006 tx_clk_ns = (((1000/clk_rate))/ (1 << phy_mode)); 1007 } else { 1008 tx_clk_ns = 0; 1009 } 1010 1011 1012 1013 /* 1014 * MAC pipeline delay for XGMII/XLGMII mode is : ( as in XMAC specification) 1015 * = (5.5 * TX line clock period) + (Timestamp clock period) 1016 */ 1017 /* signed value of pipeline delay in ns */ 1018 osts_delay = soc_property_port_get(unit, port, spn_TIMESTAMP_ADJUST(speed), 1019 SOC_TIMESYNC_PLL_CLOCK_NS(unit) - 1020 ((11 * tx_clk_ns ) / 2)); 1021 1022 if (SOC_E_NONE != soc_reg_signed_field_mask(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, 1023 TS_ADJUSTf, osts_delay, &field)) { 1024 LOG_WARN(BSL_LS_SOC_PORT, (BSL_META_U(unit, 1025 "%s property out of bounds (is %d)\n"), 1026 spn_TIMESTAMP_ADJUST(speed), osts_delay)); 1027 field = 0; 1028 } 1029 1030 soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl, 1031 TS_ADJUSTf, field); 1032 /* 1033 * Lane delay for xmac lanes 1034 * Lane_0(0-3) : 1 * TX line clock period 1035 * Lane_1(4-7) : 2 * TX line clock period 1036 * Lane_2(8-11) : 3 * TX line clock period 1037 * Lane_3(12-15): 4 * TX line clock period 1038 */ 1039 /* unsigned value of lane delay in ns */ 1040 delay = 1 * tx_clk_ns; 1041 soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl, 1042 TS_ADJUST_DEMUX_DELAY_0f, delay ); 1043 delay = 2 * tx_clk_ns; 1044 soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl, 1045 TS_ADJUST_DEMUX_DELAY_1f, delay ); 1046 delay = 3 * tx_clk_ns; 1047 soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl, 1048 TS_ADJUST_DEMUX_DELAY_2f, delay ); 1049 delay = 4 * tx_clk_ns; 1050 soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl, 1051 TS_ADJUST_DEMUX_DELAY_3f, delay ); 1052 1053 SOC_IF_ERROR_RETURN(WRITE_XMAC_OSTS_TIMESTAMP_ADJUSTr(unit, port, ctrl)); 1054 } 1055 1056 return SOC_E_NONE; 1057 } 1058 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) */ 1059 1060 /* 1061 * Function: 1062 * mac_x_duplex_set 1063 * Purpose: 1064 * Set XMAC in the specified duplex mode. 1065 * Parameters: 1066 * unit - XGS unit #. 1067 * port - XGS port # on unit. 1068 * duplex - Boolean: true --> full duplex, false --> half duplex. 1069 * Returns: 1070 * SOC_E_XXX 1071 * Notes: 1072 */ 1073 STATIC int 1074 mac_x_duplex_set(int unit, soc_port_t port, int duplex) 1075 { 1076 LOG_VERBOSE(BSL_LS_SOC_10G, 1077 (BSL_META_U(unit, 1078 "mac_x_duplex_set: unit %d port %s duplex=%s\n"), 1079 unit, SOC_PORT_NAME(unit, port), 1080 duplex ? "Full" : "Half")); 1081 return SOC_E_NONE; 1082 } 1083 1084 /* 1085 * Function: 1086 * mac_x_duplex_get 1087 * Purpose: 1088 * Get XMAC duplex mode. 1089 * Parameters: 1090 * unit - XGS unit #. 1091 * duplex - (OUT) Boolean: true --> full duplex, false --> half duplex. 1092 * Returns: 1093 * SOC_E_XXX 1094 */ 1095 STATIC int 1096 mac_x_duplex_get(int unit, soc_port_t port, int *duplex) 1097 { 1098 *duplex = TRUE; /* Always full duplex */ 1099 1100 LOG_VERBOSE(BSL_LS_SOC_10G, 1101 (BSL_META_U(unit, 1102 "mac_x_duplex_get: unit %d port %s duplex=%s\n"), 1103 unit, SOC_PORT_NAME(unit, port), 1104 *duplex ? "Full" : "Half")); 1105 return SOC_E_NONE; 1106 } 1107 1108 /* 1109 * Function: 1110 * mac_x_pause_set 1111 * Purpose: 1112 * Configure XMAC to transmit/receive pause frames. 1113 * Parameters: 1114 * unit - XGS unit #. 1115 * port - XGS port # on unit. 1116 * pause_tx - Boolean: transmit pause or -1 (don't change) 1117 * pause_rx - Boolean: receive pause or -1 (don't change) 1118 * Returns: 1119 * SOC_E_XXX 1120 */ 1121 STATIC int 1122 mac_x_pause_set(int unit, soc_port_t port, int pause_tx, int pause_rx) 1123 { 1124 soc_field_t fields[2] = { TX_PAUSE_ENf, RX_PAUSE_ENf }; 1125 uint32 values[2]; 1126 1127 LOG_VERBOSE(BSL_LS_SOC_10G, 1128 (BSL_META_U(unit, 1129 "mac_x_pause_set: unit %d port %s TX=%s RX=%s\n"), 1130 unit, SOC_PORT_NAME(unit, port), 1131 pause_tx != FALSE ? "on" : "off", 1132 pause_rx != FALSE ? "on" : "off")); 1133 1134 if (SOC_IS_TD_TT(unit)) { 1135 fields[1] = RX_PASS_PAUSEf; 1136 } 1137 values[0] = pause_tx != FALSE ? 1 : 0; 1138 values[1] = pause_rx != FALSE ? 1 : 0; 1139 return soc_reg_fields32_modify(unit, XMAC_PAUSE_CTRLr, port, 2, 1140 fields, values); 1141 } 1142 1143 /* 1144 * Function: 1145 * mac_x_pause_get 1146 * Purpose: 1147 * Return the pause ability of XMAC 1148 * Parameters: 1149 * unit - XGS unit #. 1150 * port - XGS port # on unit. 1151 * pause_tx - Boolean: transmit pause 1152 * pause_rx - Boolean: receive pause 1153 * pause_mac - MAC address used for pause transmission. 1154 * Returns: 1155 * SOC_E_XXX 1156 */ 1157 STATIC int 1158 mac_x_pause_get(int unit, soc_port_t port, int *pause_tx, int *pause_rx) 1159 { 1160 soc_field_t field = RX_PAUSE_ENf; 1161 uint64 rval; 1162 1163 if (SOC_IS_TD_TT(unit)) { 1164 field = RX_PASS_PAUSEf; 1165 } 1166 1167 SOC_IF_ERROR_RETURN(READ_XMAC_PAUSE_CTRLr(unit, port, &rval)); 1168 *pause_tx = 1169 soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval, TX_PAUSE_ENf); 1170 *pause_rx = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval, field); 1171 1172 LOG_VERBOSE(BSL_LS_SOC_10G, 1173 (BSL_META_U(unit, 1174 "mac_x_pause_get: unit %d port %s TX=%s RX=%s\n"), 1175 unit, SOC_PORT_NAME(unit, port), 1176 *pause_tx ? "on" : "off", 1177 *pause_rx ? "on" : "off")); 1178 return SOC_E_NONE; 1179 } 1180 1181 /* 1182 * Function: 1183 * mac_x_speed_set 1184 * Purpose: 1185 * Set XMAC in the specified speed. 1186 * Parameters: 1187 * unit - XGS unit #. 1188 * port - XGS port # on unit. 1189 * speed - 10000, 15000, 20000, 30000, 40000. 1190 * Returns: 1191 * SOC_E_XXX 1192 */ 1193 STATIC int 1194 mac_x_speed_set(int unit, soc_port_t port, int speed) 1195 { 1196 soc_port_if_t intf; 1197 #ifdef BCM_UNIPORT_SUPPORT 1198 static const soc_field_t core_mode_field[] = { 1199 XPORT0_CORE_PORT_MODEf, 1200 XPORT1_CORE_PORT_MODEf, 1201 XPORT2_CORE_PORT_MODEf 1202 }; 1203 static const soc_field_t phy_mode_field[] = { 1204 XPORT0_PHY_PORT_MODEf, 1205 XPORT1_PHY_PORT_MODEf, 1206 XPORT2_PHY_PORT_MODEf 1207 }; 1208 static const soc_field_t xpc_gmii_enable_field[] = { 1209 XPC0_GMII_MII_ENABLEf, 1210 XPC1_GMII_MII_ENABLEf, 1211 XPC2_GMII_MII_ENABLEf 1212 }; 1213 #endif /* BCM_UNIPORT_SUPPORT */ 1214 uint64 rval64; 1215 int xlgmii_align; 1216 #if defined(BCM_TRIDENT_SUPPORT) 1217 int ipg_check_disable; 1218 #endif 1219 1220 LOG_VERBOSE(BSL_LS_SOC_10G, 1221 (BSL_META_U(unit, 1222 "mac_x_speed_set: unit %d port %s speed=%dMb\n"), 1223 unit, SOC_PORT_NAME(unit, port), 1224 speed)); 1225 1226 #ifdef BCM_KATANA_SUPPORT 1227 /* We should be looking for Ver B0 in XMAC_VERSION_ID reg. But this reg 1228 is not implemented in Katana A0. So, check for SPEED_MODE field instead */ 1229 if (SOC_IS_KATANAX(unit) && 1230 soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) { 1231 int speed_select, enable; 1232 uint32 phy_mode = 0; 1233 uint32 rval, rval_orig; 1234 uint32 strict_preamble = 1; 1235 int same_mxqblock_max_port_speed = 0; 1236 #ifdef BCM_KATANA2_SUPPORT 1237 uint32 core_mode = 0; 1238 uint32 wc_10g_21g_sel = 0; 1239 uint8 mxqblock = 0; 1240 bcmMxqConnection_t connection_mode; 1241 int other_port_speed = 0; 1242 int loop; 1243 #endif 1244 1245 switch (speed) { 1246 case 10: 1247 strict_preamble = 0; 1248 speed_select = SOC_XMAC_SPEED_10; 1249 break; 1250 /* support non-standard speed in Broadreach mode */ 1251 case 20: 1252 case 25: 1253 case 33: 1254 case 50: 1255 /* fall through to case 100 */ 1256 case 100: 1257 strict_preamble = 0; 1258 speed_select = SOC_XMAC_SPEED_100; 1259 break; 1260 case 1000: 1261 strict_preamble = 0; 1262 speed_select = SOC_XMAC_SPEED_1000; 1263 break; 1264 case 2500: 1265 strict_preamble = 0; 1266 speed_select = SOC_XMAC_SPEED_2500; 1267 break; 1268 case 10000: 1269 case 12000: 1270 case 13000: 1271 case 15000: 1272 case 16000: 1273 speed_select = SOC_XMAC_SPEED_10000; 1274 break; 1275 case 0: 1276 return (SOC_E_NONE); /* Support NULL PHY */ 1277 default: 1278 #ifdef BCM_KATANA2_SUPPORT 1279 if (SOC_IS_KATANA2(unit) && ((speed == 21000) || (speed == 20000))){ 1280 speed_select = SOC_XMAC_SPEED_10000; 1281 break; 1282 } 1283 #endif 1284 return (SOC_E_CONFIG); 1285 } 1286 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval64)); 1287 if (IS_HG_PORT(unit, port)) { 1288 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1289 STRICT_PREAMBLEf, 0); 1290 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1291 PROCESS_VARIABLE_PREAMBLEf, 0); 1292 } else { 1293 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1294 STRICT_PREAMBLEf, strict_preamble ? 1 : 0); 1295 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1296 PROCESS_VARIABLE_PREAMBLEf, strict_preamble ? 0 : 1); 1297 } 1298 1299 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rval64)); 1300 SOC_IF_ERROR_RETURN(mac_x_enable_get(unit, port, &enable)); 1301 1302 if (enable) { 1303 /* Turn off TX/RX enable */ 1304 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 0)); 1305 } 1306 1307 /* Update the speed */ 1308 SOC_IF_ERROR_RETURN 1309 (soc_reg_field32_modify(unit, XMAC_MODEr, port, 1310 SPEED_MODEf, speed_select)); 1311 1312 if (IS_MXQ_PORT(unit,port)) { 1313 phy_mode = (speed >= 10000) ? 0 : 2; 1314 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval)); 1315 rval_orig = rval; 1316 #ifdef BCM_KATANA2_SUPPORT 1317 if (SOC_IS_KATANA2(unit)) { 1318 SOC_IF_ERROR_RETURN(soc_katana2_get_phy_port_mode(unit, 1319 port, speed, 1320 &phy_mode)); 1321 SOC_IF_ERROR_RETURN(soc_katana2_get_core_port_mode(unit, 1322 port, &core_mode)); 1323 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 1324 CORE_PORT_MODEf, core_mode); 1325 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( 1326 unit,port,&mxqblock)); 1327 if ((mxqblock == 8) || (mxqblock == 9)) { 1328 same_mxqblock_max_port_speed = 0; 1329 if (core_mode == (bcmMxqCorePortMode_t ) 1330 bcmMxqCorePortModeDual) { 1331 for (loop = 0; loop < 4; loop ++) { 1332 if ((*kt2_mxqblock_ports[unit])[mxqblock][loop] 1333 != port) { 1334 if (mac_x_speed_get(unit, 1335 (*kt2_mxqblock_ports[unit])[mxqblock] 1336 [loop], &other_port_speed)==SOC_E_NONE) { 1337 if (other_port_speed > 1338 same_mxqblock_max_port_speed) { 1339 same_mxqblock_max_port_speed = 1340 other_port_speed; 1341 } 1342 } 1343 } 1344 } 1345 } else { 1346 same_mxqblock_max_port_speed = 0; 1347 } 1348 if ((speed == 10000) || (speed == 21000) || 1349 (same_mxqblock_max_port_speed == 10000) || 1350 (same_mxqblock_max_port_speed == 21000)) { 1351 wc_10g_21g_sel = 1; 1352 } 1353 } 1354 if ((mxqblock == 6) || (mxqblock == 7)) { 1355 if (speed == 10000) { 1356 SOC_IF_ERROR_RETURN( 1357 soc_katana2_get_phy_connection_mode(unit,port, 1358 mxqblock,&connection_mode)); 1359 /* XFI Mode */ 1360 if (connection_mode == bcmMqxConnectionWarpCore) { 1361 wc_10g_21g_sel = 1; 1362 } 1363 } 1364 } 1365 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 1366 WC_10G_21G_SELf, wc_10g_21g_sel); 1367 } 1368 #endif 1369 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 1370 PHY_PORT_MODEf, phy_mode); 1371 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 1372 PORT_GMII_MII_ENABLEf, 1373 ((speed >= 10000) || 1374 (same_mxqblock_max_port_speed >= 10000)) 1375 ? 0 : 1); 1376 if (rval != rval_orig) { 1377 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 1378 #ifdef BCM_TRIUMPH3_SUPPORT 1379 /* On TR3/KT2 hard reset XMAC following mode change */ 1380 if (soc_feature(unit, soc_feature_xmac_reset_on_mode_change)) { 1381 SOC_IF_ERROR_RETURN(_mac_x_reinit(unit, port)); 1382 } 1383 #endif 1384 } 1385 } 1386 1387 if (enable) { 1388 /* Re-enable transmitter and receiver */ 1389 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 1)); 1390 } 1391 1392 /* Set Timestamp Mac Delays */ 1393 if (!IS_GE_PORT(unit, port)) { 1394 SOC_IF_ERROR_RETURN(_mac_x_timestamp_delay_set( 1395 unit, port, speed, phy_mode)); 1396 } 1397 } 1398 #endif /* BCM_KATANA_SUPPORT */ 1399 1400 #ifdef BCM_UNIPORT_SUPPORT 1401 if (SOC_IS_TRIUMPH3(unit)) { 1402 1403 soc_info_t *si; 1404 int phy_port; 1405 int bindex = -1; 1406 uint32 rval; 1407 uint32 core_mode, core_mode_org = -1, phy_mode, phy_mode_org = -1; 1408 uint32 xpc_enable = 0, xpc_enable_org = -1; 1409 uint32 strict_preamble = 1; 1410 uint64 rval64; 1411 1412 si = &SOC_INFO(unit); 1413 phy_port = si->port_l2p_mapping[port]; 1414 if (phy_port == -1) { 1415 return SOC_E_INTERNAL; 1416 } 1417 bindex = SOC_PORT_BINDEX(unit, phy_port) / 4; 1418 SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval)); 1419 1420 xpc_enable_org = soc_reg_field_get(unit, PORT_MODE_REGr, rval, 1421 xpc_gmii_enable_field[bindex]); 1422 1423 if ((speed < 10000) && (IS_XT_PORT(unit, port) || 1424 (port == si->management_port))) { 1425 if (!SOC_IS_HELIX4(unit)) { 1426 xpc_enable = 1; 1427 } 1428 } 1429 1430 if (xpc_enable != xpc_enable_org) { 1431 soc_reg_field_set(unit, PORT_MODE_REGr, &rval, 1432 xpc_gmii_enable_field[bindex], 1433 xpc_enable); 1434 SOC_IF_ERROR_RETURN(WRITE_PORT_MODE_REGr(unit, port, rval)); 1435 } 1436 core_mode_org = soc_reg_field_get(unit, PORT_MODE_REGr, rval, 1437 core_mode_field[bindex]); 1438 phy_mode_org = soc_reg_field_get(unit, PORT_MODE_REGr, rval, 1439 phy_mode_field[bindex]); 1440 1441 if (IS_XT_PORT(unit, port) && (speed >= 10000)) { 1442 core_mode = 0; /* XAUI */ 1443 phy_mode = 1; 1444 } else if (!IS_XT_PORT(unit, port)) { 1445 core_mode = 0; 1446 phy_mode = 0; 1447 if ((speed >= 10000) && (speed <= 11000)) { 1448 phy_mode = 2; /* XAUI */ 1449 if (si->port_num_lanes[port] == 1) { /* XFI */ 1450 core_mode = 2; 1451 } else if (si->port_num_lanes[port] == 2) { /* RXAUI */ 1452 core_mode = 1; 1453 } 1454 } else if ((speed > 11000) && (si->port_num_lanes[port] == 2)) { /* HG-Duo */ 1455 core_mode = 1; 1456 phy_mode = 1; 1457 } else if (speed <= 2500) { 1458 core_mode = 2; 1459 phy_mode = 2; 1460 } else if (speed <= 20000) { 1461 phy_mode = 1; /* HG 12/13/16/20 */ 1462 } 1463 } else { /* GE */ 1464 core_mode = 2; 1465 phy_mode = 2; 1466 } 1467 if ((core_mode_org != core_mode) || (phy_mode_org != phy_mode)) { 1468 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1469 (BSL_META_U(unit, 1470 "cmo: %d -> cm: %d, pmo: %d -> pm: %d\n"), 1471 core_mode_org, core_mode, phy_mode_org, phy_mode)); 1472 1473 soc_reg_field_set(unit, PORT_MODE_REGr, &rval, 1474 core_mode_field[bindex], core_mode); 1475 soc_reg_field_set(unit, PORT_MODE_REGr, &rval, 1476 phy_mode_field[bindex], phy_mode); 1477 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1478 (BSL_META_U(unit, 1479 "Port: %d set port mode: %d, phy mode: %d\n"), 1480 port, core_mode, phy_mode)); 1481 SOC_IF_ERROR_RETURN(WRITE_PORT_MODE_REGr(unit, port, rval)); 1482 1483 #ifdef BCM_TRIUMPH3_SUPPORT 1484 if (SOC_IS_TRIUMPH3(unit)) { 1485 SOC_IF_ERROR_RETURN(_mac_x_reinit(unit, port)); 1486 } 1487 #endif 1488 } 1489 if (soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) { 1490 int speed_select, enable; 1491 switch (speed) { 1492 case 10: 1493 strict_preamble = 0; 1494 speed_select = SOC_XMAC_SPEED_10; 1495 break; 1496 /* support non-standard speed in Broadreach mode */ 1497 case 20: 1498 case 25: 1499 case 33: 1500 case 50: 1501 /* fall through to case 100 */ 1502 case 100: 1503 strict_preamble = 0; 1504 speed_select = SOC_XMAC_SPEED_100; 1505 break; 1506 case 1000: 1507 speed_select = SOC_XMAC_SPEED_1000; 1508 strict_preamble = 0; 1509 break; 1510 case 2500: 1511 case 3000: 1512 strict_preamble = 0; 1513 speed_select = SOC_XMAC_SPEED_2500; 1514 break; 1515 case 10000: 1516 case 11000: 1517 case 12000: 1518 case 13000: 1519 case 15000: 1520 case 16000: 1521 case 20000: 1522 case 21000: 1523 case 23000: 1524 case 25000: 1525 case 30000: 1526 case 32000: 1527 case 40000: 1528 case 42000: 1529 speed_select = SOC_XMAC_SPEED_10000; 1530 break; 1531 case 0: 1532 return (SOC_E_NONE); /* Support NULL PHY */ 1533 default: 1534 return (SOC_E_CONFIG); 1535 } 1536 /* Update preamble processing */ 1537 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval64)); 1538 if (IS_HG_PORT(unit, port)) { 1539 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1540 STRICT_PREAMBLEf, 0); 1541 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1542 PROCESS_VARIABLE_PREAMBLEf, 0); 1543 } else { 1544 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1545 STRICT_PREAMBLEf, strict_preamble ? 1546 1 : 0); 1547 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1548 PROCESS_VARIABLE_PREAMBLEf, 1549 strict_preamble ? 0 : 1); 1550 } 1551 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rval64)); 1552 1553 SOC_IF_ERROR_RETURN(mac_x_enable_get(unit, port, &enable)); 1554 1555 if (enable) { 1556 /* Turn off TX/RX enable */ 1557 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 0)); 1558 } 1559 1560 /* Update the speed */ 1561 SOC_IF_ERROR_RETURN 1562 (soc_reg_field32_modify(unit, XMAC_MODEr, port, 1563 SPEED_MODEf, speed_select)); 1564 1565 1566 1567 if (enable) { 1568 /* Re-enable transmitter and receiver */ 1569 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 1)); 1570 } 1571 1572 } 1573 1574 /* Set Timestamp Mac Delays */ 1575 if (!IS_GE_PORT(unit, port)) { 1576 SOC_IF_ERROR_RETURN(_mac_x_timestamp_delay_set( 1577 unit, port, speed, phy_mode)); 1578 } 1579 } 1580 #endif /* BCM_UNIPORT_SUPPORT */ 1581 /* Enable XLGMII_ALIGN_ENB when using Multi-Lane Distribution (MLD) */ 1582 xlgmii_align = 0; 1583 1584 #if defined(BCM_TRIDENT_SUPPORT) 1585 ipg_check_disable = 0; 1586 #endif 1587 1588 SOC_IF_ERROR_RETURN(soc_phyctrl_interface_get(unit,port,&intf)); 1589 if (IS_XE_PORT(unit, port)) { 1590 /* xe port, 40G mld-4 and 20G mld-2 */ 1591 if ((speed == 40000) || (speed == 42000) || 1592 ((speed == 20000) && (intf==SOC_PORT_IF_KR))) { 1593 xlgmii_align = 1; 1594 } 1595 } else { /* HG port with external PHY may also use IEEE 40G mld-4 */ 1596 if (((speed == 40000) || (speed == 42000)) 1597 && PHY_EXTERNAL_MODE(unit, port) 1598 && (!PHY_PASSTHRU_MODE(unit, port)) 1599 && (!soc_property_port_get(unit, port, 1600 spn_PORT_PHY_MODE_REVERSE, 0))) { 1601 xlgmii_align = 1; 1602 } 1603 #if defined(BCM_TRIDENT_SUPPORT) 1604 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit)) { 1605 if (intf == SOC_PORT_IF_KR4) { 1606 xlgmii_align = 1; 1607 } 1608 else { 1609 ipg_check_disable = 1; 1610 } 1611 } 1612 #endif 1613 } 1614 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval64)); 1615 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, XLGMII_ALIGN_ENBf, 1616 xlgmii_align); 1617 #if defined(BCM_TRIDENT_SUPPORT) 1618 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit)) { 1619 if (soc_reg_field_valid(unit, XMAC_CTRLr, XGMII_IPG_CHECK_DISABLEf)) { 1620 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64,XGMII_IPG_CHECK_DISABLEf, ipg_check_disable); 1621 } 1622 } 1623 #endif 1624 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, rval64)); 1625 1626 return SOC_E_NONE; 1627 } 1628 1629 /* 1630 * Function: 1631 * mac_x_speed_get 1632 * Purpose: 1633 * Get XMAC speed 1634 * Parameters: 1635 * unit - XGS unit #. 1636 * port - XGS port # on unit. 1637 * speed - (OUT) speed in Mb 1638 * Returns: 1639 * SOC_E_XXX 1640 */ 1641 STATIC int 1642 mac_x_speed_get(int unit, soc_port_t port, int *speed) 1643 { 1644 uint64 rval; 1645 #ifdef BCM_KATANA_SUPPORT 1646 uint32 index=0; 1647 uint32 rval32=0; 1648 soc_field_t speed_fields[]={XGXS0_SPEED16000f,XGXS0_SPEED15000f, 1649 XGXS0_SPEED13000f,XGXS0_SPEED12500f, 1650 XGXS0_SPEED12000f,XGXS0_SPEED10000_CX4f, 1651 XGXS0_SPEED10000f,XGXS0_SPEED1000f}; 1652 int speed_values[]={16000,15000, 1653 13000,12500, 1654 12000,10000, 1655 10000,1000}; 1656 #endif /* BCM_KATANA_SUPPORT */ 1657 1658 *speed = 10000; 1659 1660 /* We should be looking for Ver B0 in XMAC_VERSION_ID reg. But this reg 1661 is not implemented in Katana A0. So, check for SPEED_MODE field instead */ 1662 if (soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) { 1663 1664 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval)); 1665 switch (soc_reg64_field32_get(unit, XMAC_MODEr, rval, SPEED_MODEf)) { 1666 case SOC_XMAC_SPEED_10: 1667 *speed = 10; 1668 break; 1669 case SOC_XMAC_SPEED_100: 1670 *speed = 100; 1671 break; 1672 case SOC_XMAC_SPEED_1000: 1673 *speed = 1000; 1674 break; 1675 case SOC_XMAC_SPEED_2500: 1676 *speed = 2500; 1677 break; 1678 case SOC_XMAC_SPEED_10000: 1679 default: 1680 #ifdef BCM_KATANA_SUPPORT 1681 if (SOC_IS_KATANA(unit)) { 1682 if (IS_HG_PORT(unit, port)) { 1683 SOC_IF_ERROR_RETURN 1684 (READ_XPORT_XGXS_NEWSTATUS1_REGr(unit, port, &rval32)); 1685 for(index=0; 1686 index <sizeof(speed_values)/sizeof(speed_values[0]); 1687 index++) { 1688 if (soc_reg_field_get( 1689 unit, XPORT_XGXS_NEWSTATUS1_REGr, 1690 rval32, speed_fields[index])) { 1691 *speed = speed_values[index]; 1692 break; 1693 } 1694 } 1695 if (index != sizeof(speed_values)/sizeof(speed_values[0])) { 1696 break; 1697 } 1698 } 1699 } 1700 /* No other option left*/ 1701 #endif /* BCM_KATANA_SUPPORT */ 1702 *speed = 10000; 1703 break; 1704 } 1705 } 1706 1707 LOG_VERBOSE(BSL_LS_SOC_10G, 1708 (BSL_META_U(unit, 1709 "mac_x_speed_get: unit %d port %s speed=%dMb\n"), 1710 unit, SOC_PORT_NAME(unit, port), 1711 *speed)); 1712 return SOC_E_NONE; 1713 } 1714 1715 /* 1716 * Function: 1717 * mac_x_loopback_set 1718 * Purpose: 1719 * Set a XMAC into/out-of loopback mode 1720 * Parameters: 1721 * unit - XGS unit #. 1722 * port - XGS unit # on unit. 1723 * loopback - Boolean: true -> loopback mode, false -> normal operation 1724 * Note: 1725 * On Xmac, when setting loopback, we enable the TX/RX function also. 1726 * Note that to test the PHY, we use the remote loopback facility. 1727 * Returns: 1728 * SOC_E_XXX 1729 */ 1730 STATIC int 1731 mac_x_loopback_set(int unit, soc_port_t port, int lb) 1732 { 1733 LOG_VERBOSE(BSL_LS_SOC_10G, 1734 (BSL_META_U(unit, 1735 "mac_x_loopback_set: unit %d port %s loopback=%s\n"), 1736 unit, SOC_PORT_NAME(unit, port), 1737 lb ? "local" : "no")); 1738 1739 /* need to enable clock compensation for applicable serdes device */ 1740 (void)soc_phyctrl_notify(unit, port, phyEventMacLoopback, lb? 1: 0); 1741 1742 if (lb) { 1743 SOC_IF_ERROR_RETURN(soc_mac_x_sync_fifo_reset(unit, port)); 1744 } 1745 1746 return soc_reg_field32_modify(unit, XMAC_CTRLr, port, 1747 soc_property_port_get(unit, port, 1748 "mac_line_lb", 1) ? 1749 LINE_LOCAL_LPBKf : CORE_LOCAL_LPBKf, 1750 lb ? 1 : 0); 1751 } 1752 1753 /* 1754 * Function: 1755 * mac_x_loopback_get 1756 * Purpose: 1757 * Get current XMAC loopback mode setting. 1758 * Parameters: 1759 * unit - XGS unit #. 1760 * port - XGS port # on unit. 1761 * loopback - (OUT) Boolean: true = loopback, false = normal 1762 * Returns: 1763 * SOC_E_XXX 1764 */ 1765 STATIC int 1766 mac_x_loopback_get(int unit, soc_port_t port, int *lb) 1767 { 1768 uint64 ctrl; 1769 int local, remote; 1770 1771 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 1772 1773 remote = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, CORE_REMOTE_LPBKf) | 1774 soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, LINE_REMOTE_LPBKf); 1775 local = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, CORE_LOCAL_LPBKf) | 1776 soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, LINE_LOCAL_LPBKf); 1777 *lb = local | remote; 1778 1779 LOG_VERBOSE(BSL_LS_SOC_10G, 1780 (BSL_META_U(unit, 1781 "mac_x_loopback_get: unit %d port %s loopback=%s\n"), 1782 unit, SOC_PORT_NAME(unit, port), 1783 *lb ? (remote ? "remote" : "local") : "no")); 1784 return SOC_E_NONE; 1785 } 1786 1787 /* 1788 * Function: 1789 * mac_x_pause_addr_set 1790 * Purpose: 1791 * Configure PAUSE frame source address. 1792 * Parameters: 1793 * unit - XGS unit #. 1794 * port - XGS port # on unit. 1795 * pause_mac - (OUT) MAC address used for pause transmission. 1796 * Returns: 1797 * SOC_E_XXX 1798 */ 1799 STATIC int 1800 mac_x_pause_addr_set(int unit, soc_port_t port, sal_mac_addr_t m) 1801 { 1802 uint64 r, tmp; 1803 int i; 1804 1805 LOG_VERBOSE(BSL_LS_SOC_10G, 1806 (BSL_META_U(unit, 1807 "mac_x_pause_addr_set: unit %d port %s MAC=<" 1808 "%02x:%02x:%02x:%02x:%02x:%02x>\n"), 1809 unit, SOC_PORT_NAME(unit, port), 1810 m[0], m[1], m[2], m[3], m[4], m[5])); 1811 1812 COMPILER_64_ZERO(r); 1813 for (i = 0; i< 6; i++) { 1814 COMPILER_64_SET(tmp, 0, m[i]); 1815 COMPILER_64_SHL(r, 8); 1816 COMPILER_64_OR(r, tmp); 1817 } 1818 1819 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_MAC_SAr(unit, port, r)); 1820 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAC_SAr(unit, port, r)); 1821 1822 return SOC_E_NONE; 1823 } 1824 1825 /* 1826 * Function: 1827 * mac_x_pause_addr_get 1828 * Purpose: 1829 * Retrieve PAUSE frame source address. 1830 * Parameters: 1831 * unit - XGS unit #. 1832 * port - XGS port # on unit. 1833 * pause_mac - (OUT) MAC address used for pause transmission. 1834 * Returns: 1835 * SOC_E_XXX 1836 * NOTE: We always write the same thing to TX & RX SA 1837 * so, we just return the contects on RX_MAC_SA. 1838 */ 1839 STATIC int 1840 mac_x_pause_addr_get(int unit, soc_port_t port, sal_mac_addr_t m) 1841 { 1842 uint64 reg; 1843 uint32 msw; 1844 uint32 lsw; 1845 1846 SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAC_SAr(unit, port, ®)); 1847 COMPILER_64_TO_32_HI(msw, reg); 1848 COMPILER_64_TO_32_LO(lsw, reg); 1849 1850 m[0] = (uint8) ( ( msw & 0x0000ff00 ) >> 8 ); 1851 m[1] = (uint8) ( msw & 0x000000ff ); 1852 1853 m[2] = (uint8) ( ( lsw & 0xff000000) >> 24 ); 1854 m[3] = (uint8) ( ( lsw & 0x00ff0000) >> 16 ); 1855 m[4] = (uint8) ( ( lsw & 0x0000ff00) >> 8 ); 1856 m[5] = (uint8) ( lsw & 0x000000ff ); 1857 1858 LOG_VERBOSE(BSL_LS_SOC_10G, 1859 (BSL_META_U(unit, 1860 "mac_x_pause_addr_get: unit %d port %s MAC=<" 1861 "%02x:%02x:%02x:%02x:%02x:%02x>\n"), 1862 unit, SOC_PORT_NAME(unit, port), 1863 m[0], m[1], m[2], m[3], m[4], m[5])); 1864 return SOC_E_NONE; 1865 } 1866 1867 /* 1868 * Function: 1869 * mac_x_interface_set 1870 * Purpose: 1871 * Set a XMAC interface type 1872 * Parameters: 1873 * unit - XGS unit #. 1874 * port - XGS port # on unit. 1875 * pif - one of SOC_PORT_IF_* 1876 * Returns: 1877 * SOC_E_NONE 1878 * SOC_E_UNAVAIL - requested mode not supported. 1879 * Notes: 1880 */ 1881 STATIC int 1882 mac_x_interface_set(int unit, soc_port_t port, soc_port_if_t pif) 1883 { 1884 #ifdef BROADCOM_DEBUG 1885 LOG_VERBOSE(BSL_LS_SOC_10G, 1886 (BSL_META_U(unit, 1887 "mac_x_interface_set: unit %d port %s interface=%s\n"), 1888 unit, SOC_PORT_NAME(unit, port), 1889 mac_x_port_if_names[pif])); 1890 #endif 1891 return SOC_E_NONE; 1892 } 1893 1894 /* 1895 * Function: 1896 * mac_x_interface_get 1897 * Purpose: 1898 * Retrieve XMAC interface type 1899 * Parameters: 1900 * unit - XGS unit #. 1901 * port - XGS port # on unit. 1902 * pif - (OUT) one of SOC_PORT_IF_* 1903 * Returns: 1904 * SOC_E_NONE 1905 */ 1906 STATIC int 1907 mac_x_interface_get(int unit, soc_port_t port, soc_port_if_t *pif) 1908 { 1909 COMPILER_REFERENCE(unit); 1910 COMPILER_REFERENCE(port); 1911 1912 *pif = SOC_PORT_IF_MII; 1913 1914 #ifdef BROADCOM_DEBUG 1915 LOG_VERBOSE(BSL_LS_SOC_10G, 1916 (BSL_META_U(unit, 1917 "mac_x_interface_get: unit %d port %s interface=%s\n"), 1918 unit, SOC_PORT_NAME(unit, port), 1919 mac_x_port_if_names[*pif])); 1920 #endif 1921 return SOC_E_NONE; 1922 } 1923 1924 /* 1925 * Function: 1926 * mac_x_frame_max_set 1927 * Description: 1928 * Set the maximum receive frame size for the port 1929 * Parameters: 1930 * unit - Device number 1931 * port - Port number 1932 * size - Maximum frame size in bytes 1933 * Return Value: 1934 * BCM_E_XXX 1935 */ 1936 STATIC int 1937 mac_x_frame_max_set(int unit, soc_port_t port, int size) 1938 { 1939 uint64 rval; 1940 1941 LOG_VERBOSE(BSL_LS_SOC_10G, 1942 (BSL_META_U(unit, 1943 "mac_x_frame_max_set: unit %d port %s size=%d\n"), 1944 unit, SOC_PORT_NAME(unit, port), 1945 size)); 1946 1947 if (IS_GE_PORT(unit, port) || IS_XE_PORT(unit, port)) { 1948 /* For VLAN tagged packets */ 1949 size += 4; 1950 } 1951 COMPILER_64_ZERO(rval); 1952 soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf, size); 1953 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, rval)); 1954 return SOC_E_NONE; 1955 } 1956 1957 /* 1958 * Function: 1959 * mac_x_frame_max_get 1960 * Description: 1961 * Set the maximum receive frame size for the port 1962 * Parameters: 1963 * unit - Device number 1964 * port - Port number 1965 * size - Maximum frame size in bytes 1966 * Return Value: 1967 * BCM_E_XXX 1968 */ 1969 STATIC int 1970 mac_x_frame_max_get(int unit, soc_port_t port, int *size) 1971 { 1972 uint64 rval; 1973 1974 SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr(unit, port, &rval)); 1975 *size = soc_reg64_field32_get(unit, XMAC_RX_MAX_SIZEr, rval, RX_MAX_SIZEf); 1976 if (IS_GE_PORT(unit, port) || IS_XE_PORT(unit, port)) { 1977 /* For VLAN tagged packets */ 1978 *size -= 4; 1979 } 1980 1981 LOG_VERBOSE(BSL_LS_SOC_10G, 1982 (BSL_META_U(unit, 1983 "mac_x_frame_max_get: unit %d port %s size=%d\n"), 1984 unit, SOC_PORT_NAME(unit, port), 1985 *size)); 1986 return SOC_E_NONE; 1987 } 1988 1989 /* 1990 * Function: 1991 * mac_x_ifg_set 1992 * Description: 1993 * Sets the new ifg (Inter-frame gap) value 1994 * Parameters: 1995 * unit - Device number 1996 * port - Port number 1997 * speed - the speed for which the IFG is being set 1998 * duplex - the duplex for which the IFG is being set 1999 * ifg - number of bits to use for average inter-frame gap 2000 * Return Value: 2001 * BCM_E_XXX 2002 * Notes: 2003 * The function makes sure the IFG value makes sense and updates the 2004 * IPG register in case the speed/duplex match the current settings 2005 */ 2006 STATIC int 2007 mac_x_ifg_set(int unit, soc_port_t port, int speed, 2008 soc_port_duplex_t duplex, int ifg) 2009 { 2010 int real_ifg, encap; 2011 soc_ipg_t *si = &SOC_PERSIST(unit)->ipg[port]; 2012 uint64 rval, orval; 2013 soc_port_ability_t ability; 2014 uint32 pa_flag; 2015 2016 LOG_VERBOSE(BSL_LS_SOC_10G, 2017 (BSL_META_U(unit, 2018 "mac_x_ifg_set: unit %d port %s speed=%dMb duplex=%s " 2019 "ifg=%d\n"), 2020 unit, SOC_PORT_NAME(unit, port), 2021 speed, duplex ? "True" : "False", ifg)); 2022 2023 pa_flag = SOC_PA_SPEED(speed); 2024 soc_mac_x.md_ability_local_get(unit, port, &ability); 2025 if (!(pa_flag & ability.speed_full_duplex)) { 2026 return SOC_E_PARAM; 2027 } 2028 2029 /* Silently adjust the specified ifp bits to valid value */ 2030 /* valid value: 8 to 31 bytes (i.e. multiple of 8 bits) */ 2031 real_ifg = ifg < 64 ? 64 : (ifg > 248 ? 248 : (ifg + 7) & (0x1f << 3)); 2032 2033 if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit,port)) { 2034 si->fd_xe = real_ifg; 2035 } else { 2036 SOC_IF_ERROR_RETURN 2037 (soc_mac_x.md_encap_get(unit, port, &encap)); 2038 if(encap == SOC_ENCAP_HIGIG2) { 2039 si->fd_hg2 = real_ifg; 2040 } else { 2041 si->fd_hg = real_ifg; 2042 } 2043 } 2044 2045 2046 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &rval)); 2047 orval = rval; 2048 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, AVERAGE_IPGf, 2049 IPG_BYTE(real_ifg)); 2050 if (COMPILER_64_NE(rval, orval)) { 2051 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, rval)); 2052 } 2053 2054 return SOC_E_NONE; 2055 } 2056 2057 /* 2058 * Function: 2059 * mac_x_ifg_get 2060 * Description: 2061 * Sets the new ifg (Inter-frame gap) value 2062 * Parameters: 2063 * unit - Device number 2064 * port - Port number 2065 * speed - the speed for which the IFG is being set 2066 * duplex - the duplex for which the IFG is being set 2067 * size - Maximum frame size in bytes 2068 * Return Value: 2069 * BCM_E_XXX 2070 * Notes: 2071 * The function makes sure the IFG value makes sense and updates the 2072 * IPG register in case the speed/duplex match the current settings 2073 */ 2074 STATIC int 2075 mac_x_ifg_get(int unit, soc_port_t port, int speed, 2076 soc_port_duplex_t duplex, int *ifg) 2077 { 2078 soc_ipg_t *si = &SOC_PERSIST(unit)->ipg[port]; 2079 soc_port_ability_t ability; 2080 uint32 pa_flag; 2081 int encap; 2082 2083 if (!duplex) { 2084 return SOC_E_PARAM; 2085 } 2086 2087 pa_flag = SOC_PA_SPEED(speed); 2088 soc_mac_x.md_ability_local_get(unit, port, &ability); 2089 if (!(pa_flag & ability.speed_full_duplex)) { 2090 return SOC_E_PARAM; 2091 } 2092 2093 if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port)) { 2094 *ifg = si->fd_xe; 2095 } else { 2096 SOC_IF_ERROR_RETURN 2097 (soc_mac_x.md_encap_get(unit, port, &encap)); 2098 if(encap == SOC_ENCAP_HIGIG2) { 2099 *ifg = si->fd_hg2; 2100 } else { 2101 *ifg = si->fd_hg; 2102 } 2103 } 2104 2105 LOG_VERBOSE(BSL_LS_SOC_10G, 2106 (BSL_META_U(unit, 2107 "mac_x_ifg_get: unit %d port %s speed=%dMb duplex=%s " 2108 "ifg=%d\n"), 2109 unit, SOC_PORT_NAME(unit, port), 2110 speed, duplex ? "True" : "False", *ifg)); 2111 return SOC_E_NONE; 2112 } 2113 2114 /* 2115 * Function: 2116 * mac_x_loopback_remote_set 2117 * Purpose: 2118 * Set the XMAC into remote-loopback state. 2119 * Parameters: 2120 * unit - XGS unit #. 2121 * port - XGS port # on unit. 2122 * mode - (INT) loopback enable state 2123 * Returns: 2124 * SOC_E_XXX 2125 */ 2126 int 2127 mac_x_loopback_remote_set(int unit, soc_port_t port, int lb) 2128 { 2129 LOG_VERBOSE(BSL_LS_SOC_10G, 2130 (BSL_META_U(unit, 2131 "mac_x_loopback_remote_set: unit %d port %s loopback=%s\n"), 2132 unit, SOC_PORT_NAME(unit, port), 2133 lb ? "remote" : "no")); 2134 2135 return soc_reg_field32_modify(unit, XMAC_CTRLr, port, CORE_REMOTE_LPBKf, 2136 lb ? 1 : 0); 2137 } 2138 2139 /* 2140 * Function: 2141 * _mac_x_port_mode_update 2142 * Purpose: 2143 * Set the XMAC port encapsulation mode. 2144 * Parameters: 2145 * unit - XGS unit #. 2146 * port - XGS port # on unit. 2147 * to_hg_port - (TRUE/FALSE) 2148 * Returns: 2149 * SOC_E_XXX 2150 */ 2151 STATIC int 2152 _mac_x_port_mode_update(int unit, soc_port_t port, int to_hg_port) 2153 { 2154 uint32 rval; 2155 uint64 val64; 2156 soc_pbmp_t ctr_pbmp; 2157 int rv = SOC_E_NONE; 2158 2159 /* Pause linkscan */ 2160 soc_linkscan_pause(unit); 2161 2162 /* Pause counter collection */ 2163 COUNTER_LOCK(unit); 2164 2165 soc_xport_type_update(unit, port, to_hg_port); 2166 2167 #if defined(BCM_TRIDENT_SUPPORT) || defined (BCM_TRIUMPH3_SUPPORT) || \ 2168 defined(BCM_SHADOW_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 2169 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || 2170 SOC_IS_SHADOW(unit) || SOC_IS_KATANA2(unit)) { 2171 /* no need to hard reset the Warpcore serdes device. Soft init 2172 * should be good enough. Hard reset brings 2173 * down all other ports using the same Warpcore in quad-port mode. 2174 */ 2175 } else 2176 #endif /* BCM_TRIDENT_SUPPORT || BCM_TRIUMPH3_SUPPORT || BCM_SHADOW_SUPPORT */ 2177 { 2178 rv = soc_xgxs_reset(unit, port); 2179 } 2180 2181 if (SOC_SUCCESS(rv)) { 2182 rv = soc_phyctrl_init(unit, port); 2183 } 2184 2185 if (SOC_SUCCESS(rv)) { 2186 rv = mac_x_init(unit, port); 2187 } 2188 2189 if (SOC_SUCCESS(rv)) { 2190 rv = mac_x_enable_set(unit, port, 0); 2191 } 2192 2193 if (SOC_SUCCESS(rv)) { 2194 SOC_PBMP_CLEAR(ctr_pbmp); 2195 SOC_PBMP_PORT_SET(ctr_pbmp, port); 2196 COMPILER_64_SET(val64, 0, 0); 2197 rv = soc_counter_set_by_port(unit, ctr_pbmp, val64); 2198 } 2199 2200 COUNTER_UNLOCK(unit); 2201 soc_linkscan_continue(unit); 2202 2203 if (SOC_REG_IS_VALID(unit, XLPORT_CONFIGr)) { 2204 SOC_IF_ERROR_RETURN(READ_XLPORT_CONFIGr(unit, port, &rval)); 2205 soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, HIGIG_MODEf, 2206 to_hg_port ? 1 : 0); 2207 soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, XPAUSE_RX_ENf, 2208 to_hg_port ? 1 : 0); 2209 soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, XPAUSE_TX_ENf, 2210 to_hg_port ? 1 : 0); 2211 soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, XPAUSE_ENf, 2212 to_hg_port ? 1 : 0); 2213 SOC_IF_ERROR_RETURN(WRITE_XLPORT_CONFIGr(unit, port, rval)); 2214 } 2215 if (SOC_REG_IS_VALID(unit, XPORT_CONFIGr)) { 2216 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &rval)); 2217 if (to_hg_port) { 2218 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1); 2219 } else { 2220 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0); 2221 } 2222 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 2223 } 2224 return rv; 2225 } 2226 2227 /* 2228 * Function: 2229 * mac_x_encap_set 2230 * Purpose: 2231 * Set the XMAC port encapsulation mode. 2232 * Parameters: 2233 * unit - XGS unit #. 2234 * port - XGS port # on unit. 2235 * mode - (IN) encap bits (defined above) 2236 * Returns: 2237 * SOC_E_XXX 2238 */ 2239 STATIC int 2240 mac_x_encap_set(int unit, soc_port_t port, int mode) 2241 { 2242 int enable, encap, rv; 2243 int runt, ipg; 2244 2245 #ifdef BROADCOM_DEBUG 2246 LOG_VERBOSE(BSL_LS_SOC_10G, 2247 (BSL_META_U(unit, 2248 "mac_x_encap_set: unit %d port %s encapsulation=%s\n"), 2249 unit, SOC_PORT_NAME(unit, port), 2250 mac_x_encap_mode[mode])); 2251 #endif 2252 2253 switch (mode) { 2254 case SOC_ENCAP_IEEE: 2255 case SOC_ENCAP_HIGIG2_LITE: 2256 encap = 0; 2257 break; 2258 case SOC_ENCAP_HIGIG: 2259 encap = 1; 2260 break; 2261 case SOC_ENCAP_HIGIG2: 2262 encap = 2; 2263 break; 2264 default: 2265 return SOC_E_PARAM; 2266 } 2267 2268 if (!soc_feature(unit, soc_feature_xport_convertible)) { 2269 if ((IS_E_PORT(unit, port) && mode != SOC_ENCAP_IEEE) || 2270 (IS_ST_PORT(unit, port) && mode == SOC_ENCAP_IEEE)) { 2271 return SOC_E_PARAM; 2272 } 2273 } 2274 2275 SOC_IF_ERROR_RETURN(mac_x_enable_get(unit, port, &enable)); 2276 2277 if (enable) { 2278 /* Turn off TX/RX enable */ 2279 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 0)); 2280 } 2281 2282 if (IS_E_PORT(unit, port) && mode != SOC_ENCAP_IEEE) { 2283 /* XE -> HG */ 2284 SOC_IF_ERROR_RETURN(_mac_x_port_mode_update(unit, port, TRUE)); 2285 } else if (IS_ST_PORT(unit, port) && mode == SOC_ENCAP_IEEE) { 2286 /* HG -> XE */ 2287 SOC_IF_ERROR_RETURN(_mac_x_port_mode_update(unit, port, FALSE)); 2288 } 2289 2290 /* Update the encapsulation mode */ 2291 rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, HDR_MODEf, encap); 2292 #if defined(BCM_KATANA2_SUPPORT) 2293 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 2294 if (mode == SOC_ENCAP_HIGIG2_LITE) { 2295 rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, SPEED_MODEf, 3); 2296 } 2297 } 2298 #endif 2299 2300 /* Update the RUNT */ 2301 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit) || 2302 SOC_IS_KATANAX(unit)) { 2303 runt = ((mode == SOC_ENCAP_HIGIG2) || (mode == SOC_ENCAP_HIGIG2_LITE)) ? 2304 XMAC_RUNT_THRESHOLD_HG2 : 2305 ((mode == SOC_ENCAP_HIGIG) ? 2306 XMAC_RUNT_THRESHOLD_HG1 : XMAC_RUNT_THRESHOLD_XE); 2307 SOC_IF_ERROR_RETURN 2308 (soc_reg_field32_modify(unit, XMAC_RX_CTRLr, port, RUNT_THRESHOLDf,runt)); 2309 } 2310 2311 ipg = (mode == SOC_ENCAP_HIGIG2) ? SOC_PERSIST(unit)->ipg[port].fd_hg2 : 2312 ((mode == SOC_ENCAP_HIGIG) ? SOC_PERSIST(unit)->ipg[port].fd_hg : 2313 SOC_PERSIST(unit)->ipg[port].fd_xe); 2314 SOC_IF_ERROR_RETURN 2315 (soc_reg_field32_modify(unit, XMAC_TX_CTRLr, port, AVERAGE_IPGf, 2316 IPG_BYTE(ipg))); 2317 2318 if (enable) { 2319 /* Re-enable transmitter and receiver */ 2320 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 1)); 2321 } 2322 2323 return rv; 2324 } 2325 2326 /* 2327 * Function: 2328 * mac_x_encap_get 2329 * Purpose: 2330 * Get the XMAC port encapsulation mode. 2331 * Parameters: 2332 * unit - XGS unit #. 2333 * port - XGS port # on unit. 2334 * mode - (INT) encap bits (defined above) 2335 * Returns: 2336 * SOC_E_XXX 2337 */ 2338 STATIC int 2339 mac_x_encap_get(int unit, soc_port_t port, int *mode) 2340 { 2341 uint64 rval; 2342 2343 if (!mode) { 2344 return SOC_E_PARAM; 2345 } 2346 2347 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval)); 2348 switch (soc_reg64_field32_get(unit, XMAC_MODEr, rval, HDR_MODEf)) { 2349 case 0: 2350 *mode = SOC_ENCAP_IEEE; 2351 break; 2352 case 1: 2353 *mode = SOC_ENCAP_HIGIG; 2354 break; 2355 case 2: 2356 *mode = SOC_ENCAP_HIGIG2; 2357 break; 2358 default: 2359 *mode = SOC_ENCAP_COUNT; 2360 } 2361 2362 #ifdef BROADCOM_DEBUG 2363 LOG_VERBOSE(BSL_LS_SOC_10G, 2364 (BSL_META_U(unit, 2365 "mac_x_encap_get: unit %d port %s encapsulation=%s\n"), 2366 unit, SOC_PORT_NAME(unit, port), 2367 mac_x_encap_mode[*mode])); 2368 #endif 2369 return SOC_E_NONE; 2370 } 2371 2372 /* 2373 * Function: 2374 * mac_x_expected_rx_latency_get 2375 * Purpose: 2376 * Get the XMAC port expected Rx latency 2377 * Parameters: 2378 * unit - XGS unit #. 2379 * port - XGS port # on unit. 2380 * latency - (OUT) Latency in NS 2381 * Returns: 2382 * SOC_E_XXX 2383 */ 2384 STATIC int 2385 mac_x_expected_rx_latency_get(int unit, soc_port_t port, int *latency) 2386 { 2387 int speed = 0; 2388 SOC_IF_ERROR_RETURN(mac_x_speed_get(unit, port, &speed)); 2389 2390 2391 switch (speed) { 2392 case 1000: /* GigE */ 2393 *latency = 0; 2394 break; 2395 2396 case 10000: /* 10G */ 2397 *latency = 0; 2398 break; 2399 2400 default: 2401 *latency = 0; 2402 break; 2403 } 2404 2405 return SOC_E_NONE; 2406 } 2407 2408 2409 /* 2410 * Function: 2411 * mac_x_control_set 2412 * Purpose: 2413 * To configure MAC control properties. 2414 * Parameters: 2415 * unit - XGS unit #. 2416 * port - XGS port # on unit. 2417 * type - MAC control property to set. 2418 * int - New setting for MAC control. 2419 * Returns: 2420 * SOC_E_XXX 2421 */ 2422 STATIC int 2423 mac_x_control_set(int unit, soc_port_t port, soc_mac_control_t type, 2424 int value) 2425 { 2426 uint64 rval, copy; 2427 uint32 fval; 2428 2429 LOG_VERBOSE(BSL_LS_SOC_10G, 2430 (BSL_META_U(unit, 2431 "mac_x_control_set: unit %d port %s type=%d value=%d\n"), 2432 unit, SOC_PORT_NAME(unit, port), 2433 type, value)); 2434 2435 switch (type) { 2436 case SOC_MAC_CONTROL_RX_SET: 2437 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval)); 2438 copy = rval; 2439 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval, RX_ENf, value ? 1 : 0); 2440 if (COMPILER_64_NE(rval, copy)) { 2441 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, rval)); 2442 } 2443 break; 2444 case SOC_MAC_CONTROL_FAILOVER_RX_SET: 2445 2446 break; 2447 case SOC_MAC_CONTROL_TX_SET: 2448 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval)); 2449 copy = rval; 2450 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval, TX_ENf, value ? 1 : 0); 2451 if (COMPILER_64_NE(rval, copy)) { 2452 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, rval)); 2453 } 2454 break; 2455 case SOC_MAC_CONTROL_FRAME_SPACING_STRETCH: 2456 if (value < 0 || value > 255) { 2457 return SOC_E_PARAM; 2458 } else { 2459 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &rval)); 2460 if (value >= 8) { 2461 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_DENOMf, 2462 value); 2463 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_NUMf, 2464 1); 2465 } else { 2466 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_DENOMf, 2467 0); 2468 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_NUMf, 2469 0); 2470 } 2471 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, rval)); 2472 } 2473 return SOC_E_NONE; 2474 2475 case SOC_MAC_PASS_CONTROL_FRAME: 2476 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval)); 2477 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval, RX_PASS_CTRLf, 2478 value ? 1 : 0); 2479 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rval)); 2480 break; 2481 2482 case SOC_MAC_CONTROL_PFC_TYPE: 2483 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_PFC_TYPEr, port, 2484 PFC_ETH_TYPEf, value)); 2485 break; 2486 2487 case SOC_MAC_CONTROL_PFC_OPCODE: 2488 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_PFC_OPCODEr, 2489 port, PFC_OPCODEf, value)); 2490 break; 2491 2492 case SOC_MAC_CONTROL_PFC_CLASSES: 2493 if (value != 8) { 2494 return SOC_E_PARAM; 2495 } 2496 break; 2497 2498 case SOC_MAC_CONTROL_PFC_MAC_DA_OUI: 2499 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval)); 2500 fval = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_LOf); 2501 fval &= 0x00ffffff; 2502 fval |= (value & 0xff) << 24; 2503 soc_reg64_field32_set(unit, XMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval); 2504 2505 soc_reg64_field32_set(unit, XMAC_PFC_DAr, &rval, PFC_MACDA_HIf, 2506 value >> 8); 2507 SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_DAr(unit, port, rval)); 2508 break; 2509 2510 case SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI: 2511 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval)); 2512 fval = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_LOf); 2513 fval &= 0xff000000; 2514 fval |= value; 2515 soc_reg64_field32_set(unit, XMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval); 2516 SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_DAr(unit, port, rval)); 2517 break; 2518 2519 case SOC_MAC_CONTROL_PFC_RX_PASS: 2520 SOC_IF_ERROR_RETURN 2521 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, RX_PASS_PFCf, 2522 value ? 1 : 0)); 2523 break; 2524 2525 case SOC_MAC_CONTROL_PFC_RX_ENABLE: 2526 SOC_IF_ERROR_RETURN 2527 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, RX_PFC_ENf, 2528 value ? 1 : 0)); 2529 break; 2530 2531 case SOC_MAC_CONTROL_PFC_TX_ENABLE: 2532 SOC_IF_ERROR_RETURN 2533 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, TX_PFC_ENf, 2534 value ? 1 : 0)); 2535 break; 2536 2537 case SOC_MAC_CONTROL_PFC_FORCE_XON: 2538 SOC_IF_ERROR_RETURN 2539 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, FORCE_PFC_XONf, 2540 value ? 1 : 0)); 2541 break; 2542 2543 case SOC_MAC_CONTROL_PFC_STATS_ENABLE: 2544 SOC_IF_ERROR_RETURN 2545 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, PFC_STATS_ENf, 2546 value ? 1 : 0)); 2547 break; 2548 2549 case SOC_MAC_CONTROL_PFC_REFRESH_TIME: 2550 SOC_IF_ERROR_RETURN 2551 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, 2552 PFC_REFRESH_TIMERf, value)); 2553 break; 2554 2555 case SOC_MAC_CONTROL_PFC_XOFF_TIME: 2556 SOC_IF_ERROR_RETURN 2557 (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, 2558 PFC_XOFF_TIMERf, value)); 2559 break; 2560 2561 case SOC_MAC_CONTROL_LLFC_RX_ENABLE: 2562 SOC_IF_ERROR_RETURN 2563 (soc_reg_field32_modify(unit, XMAC_LLFC_CTRLr, port, RX_LLFC_ENf, 2564 value ? 1 : 0)); 2565 break; 2566 2567 case SOC_MAC_CONTROL_LLFC_TX_ENABLE: 2568 SOC_IF_ERROR_RETURN 2569 (soc_reg_field32_modify(unit, XMAC_LLFC_CTRLr, port, TX_LLFC_ENf, 2570 value ? 1 : 0)); 2571 break; 2572 2573 case SOC_MAC_CONTROL_EEE_ENABLE: 2574 if (!soc_feature(unit, soc_feature_eee)) { 2575 return SOC_E_UNAVAIL; 2576 } 2577 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_EEE_CTRLr, 2578 port, EEE_ENf, value)); 2579 break; 2580 2581 case SOC_MAC_CONTROL_EEE_TX_IDLE_TIME: 2582 if (!soc_feature(unit, soc_feature_eee)) { 2583 return SOC_E_UNAVAIL; 2584 } 2585 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_EEE_TIMERSr, 2586 port, EEE_DELAY_ENTRY_TIMERf, value)); 2587 break; 2588 2589 case SOC_MAC_CONTROL_EEE_TX_WAKE_TIME: 2590 if (!soc_feature(unit, soc_feature_eee)) { 2591 return SOC_E_UNAVAIL; 2592 } 2593 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_EEE_TIMERSr, 2594 port, EEE_WAKE_TIMERf, value)); 2595 break; 2596 2597 case SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE: 2598 SOC_IF_ERROR_RETURN 2599 (soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr, port, 2600 LOCAL_FAULT_DISABLEf, value ? 0 : 1)); 2601 break; 2602 2603 case SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE: 2604 SOC_IF_ERROR_RETURN 2605 (soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr, port, 2606 REMOTE_FAULT_DISABLEf, value ? 0 : 1)); 2607 break; 2608 case SOC_MAC_CONTROL_EGRESS_DRAIN: 2609 SOC_IF_ERROR_RETURN(mac_x_egress_queue_drain(unit, port)); 2610 break; 2611 2612 case SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID: 2613 SOC_IF_ERROR_RETURN 2614 (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 2615 OUTER_VLAN_TAGf, value)); 2616 SOC_IF_ERROR_RETURN 2617 (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 2618 OUTER_VLAN_TAG_ENABLEf, value ? 1 : 0)); 2619 break; 2620 case SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID: 2621 SOC_IF_ERROR_RETURN 2622 (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 2623 INNER_VLAN_TAGf, value)); 2624 SOC_IF_ERROR_RETURN 2625 (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 2626 INNER_VLAN_TAG_ENABLEf, value ? 1 : 0)); 2627 break; 2628 2629 default: 2630 return SOC_E_UNAVAIL; 2631 } 2632 2633 return SOC_E_NONE; 2634 } 2635 2636 /* 2637 * Function: 2638 * mac_x_control_get 2639 * Purpose: 2640 * To get current MAC control setting. 2641 * Parameters: 2642 * unit - XGS unit #. 2643 * port - XGS port # on unit. 2644 * type - MAC control property to set. 2645 * int - New setting for MAC control. 2646 * Returns: 2647 * SOC_E_XXX 2648 */ 2649 STATIC int 2650 mac_x_control_get(int unit, soc_port_t port, soc_mac_control_t type, 2651 int *value) 2652 { 2653 int rv; 2654 uint64 rval; 2655 uint32 fval0, fval1; 2656 2657 if (value == NULL) { 2658 return SOC_E_PARAM; 2659 } 2660 2661 rv = SOC_E_NONE; 2662 switch (type) { 2663 case SOC_MAC_CONTROL_RX_SET: 2664 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval)); 2665 *value = soc_reg64_field32_get(unit, XMAC_CTRLr, rval, RX_ENf); 2666 break; 2667 case SOC_MAC_CONTROL_TX_SET: 2668 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval)); 2669 *value = soc_reg64_field32_get(unit, XMAC_CTRLr, rval, TX_ENf); 2670 break; 2671 case SOC_MAC_CONTROL_SW_RESET: 2672 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval)); 2673 *value = soc_reg64_field32_get(unit, XMAC_CTRLr, rval, SOFT_RESETf); 2674 break; 2675 case SOC_MAC_CONTROL_FRAME_SPACING_STRETCH: 2676 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &rval)); 2677 *value = soc_reg64_field32_get(unit, XMAC_TX_CTRLr, rval, 2678 THROT_DENOMf); 2679 rv = SOC_E_NONE; 2680 break; 2681 2682 case SOC_MAC_CONTROL_TIMESTAMP_TRANSMIT: 2683 { 2684 uint32 timestamp = 0; 2685 if (soc_feature(unit, soc_feature_timestamp_counter) && 2686 soc_property_get(unit, spn_SW_TIMESTAMP_FIFO_ENABLE, 1)) { 2687 if (soc_counter_timestamp_get(unit, port, ×tamp) != 2688 SOC_E_NOT_FOUND) { 2689 *value = (int)timestamp; 2690 break; 2691 } 2692 } 2693 2694 SOC_IF_ERROR_RETURN 2695 (READ_XMAC_TX_TIMESTAMP_FIFO_STATUSr(unit, port, &rval)); 2696 if (soc_reg64_field32_get(unit, XMAC_TX_TIMESTAMP_FIFO_STATUSr, rval, 2697 ENTRY_COUNTf) == 0) { 2698 return SOC_E_EMPTY; 2699 } 2700 SOC_IF_ERROR_RETURN 2701 (READ_XMAC_TX_TIMESTAMP_FIFO_DATAr(unit, port, &rval)); 2702 *value = soc_reg64_field32_get(unit, XMAC_TX_TIMESTAMP_FIFO_DATAr, 2703 rval, TIME_STAMPf); 2704 } 2705 break; 2706 2707 case SOC_MAC_PASS_CONTROL_FRAME: 2708 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval)); 2709 *value = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval, 2710 RX_PASS_CTRLf); 2711 break; 2712 2713 case SOC_MAC_CONTROL_PFC_TYPE: 2714 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_TYPEr(unit, port, &rval)); 2715 *value = soc_reg64_field32_get(unit, XMAC_PFC_TYPEr, rval, 2716 PFC_ETH_TYPEf); 2717 break; 2718 2719 case SOC_MAC_CONTROL_PFC_OPCODE: 2720 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_OPCODEr(unit, port, &rval)); 2721 *value = soc_reg64_field32_get(unit, XMAC_PFC_OPCODEr, rval, 2722 PFC_OPCODEf); 2723 break; 2724 2725 case SOC_MAC_CONTROL_PFC_CLASSES: 2726 *value = 8; 2727 break; 2728 2729 case SOC_MAC_CONTROL_PFC_MAC_DA_OUI: 2730 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval)); 2731 fval0 = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_LOf); 2732 fval1 = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_HIf); 2733 *value = (fval0 >> 24) | (fval1 << 8); 2734 break; 2735 2736 case SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI: 2737 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval)); 2738 *value = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, 2739 PFC_MACDA_LOf) & 0x00ffffff; 2740 break; 2741 2742 case SOC_MAC_CONTROL_PFC_RX_PASS: 2743 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2744 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2745 RX_PASS_PFCf); 2746 break; 2747 2748 case SOC_MAC_CONTROL_PFC_RX_ENABLE: 2749 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2750 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2751 RX_PFC_ENf); 2752 break; 2753 2754 case SOC_MAC_CONTROL_PFC_TX_ENABLE: 2755 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2756 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2757 TX_PFC_ENf); 2758 break; 2759 2760 case SOC_MAC_CONTROL_PFC_FORCE_XON: 2761 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2762 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2763 FORCE_PFC_XONf); 2764 break; 2765 2766 case SOC_MAC_CONTROL_PFC_STATS_ENABLE: 2767 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2768 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2769 PFC_STATS_ENf); 2770 break; 2771 2772 case SOC_MAC_CONTROL_PFC_REFRESH_TIME: 2773 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2774 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2775 PFC_REFRESH_TIMERf); 2776 break; 2777 2778 case SOC_MAC_CONTROL_PFC_XOFF_TIME: 2779 SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval)); 2780 *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval, 2781 PFC_XOFF_TIMERf); 2782 break; 2783 2784 case SOC_MAC_CONTROL_LLFC_RX_ENABLE: 2785 SOC_IF_ERROR_RETURN(READ_XMAC_LLFC_CTRLr(unit, port, &rval)); 2786 *value = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval, 2787 RX_LLFC_ENf); 2788 break; 2789 2790 case SOC_MAC_CONTROL_LLFC_TX_ENABLE: 2791 SOC_IF_ERROR_RETURN(READ_XMAC_LLFC_CTRLr(unit, port, &rval)); 2792 *value = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval, 2793 TX_LLFC_ENf); 2794 break; 2795 2796 case SOC_MAC_CONTROL_EEE_ENABLE: 2797 if (!soc_feature(unit, soc_feature_eee)) { 2798 return SOC_E_UNAVAIL; 2799 } 2800 if (!soc_reg_field_valid(unit, XMAC_EEE_CTRLr, EEE_ENf)) { 2801 return SOC_E_UNAVAIL; 2802 } 2803 SOC_IF_ERROR_RETURN(READ_XMAC_EEE_CTRLr(unit, port, &rval)); 2804 *value = soc_reg64_field32_get(unit, XMAC_EEE_CTRLr, rval, EEE_ENf); 2805 break; 2806 2807 case SOC_MAC_CONTROL_EEE_TX_IDLE_TIME: 2808 if (!soc_feature(unit, soc_feature_eee)) { 2809 return SOC_E_UNAVAIL; 2810 } 2811 if (!soc_reg_field_valid(unit, XMAC_EEE_TIMERSr, EEE_DELAY_ENTRY_TIMERf)) { 2812 return SOC_E_UNAVAIL; 2813 } 2814 SOC_IF_ERROR_RETURN(READ_XMAC_EEE_TIMERSr(unit, port, &rval)); 2815 *value = soc_reg64_field32_get(unit, XMAC_EEE_TIMERSr, rval, 2816 EEE_DELAY_ENTRY_TIMERf); 2817 break; 2818 2819 case SOC_MAC_CONTROL_EEE_TX_WAKE_TIME: 2820 if (!soc_feature(unit, soc_feature_eee)) { 2821 return SOC_E_UNAVAIL; 2822 } 2823 if (!soc_reg_field_valid(unit, XMAC_EEE_TIMERSr, EEE_WAKE_TIMERf)) { 2824 return SOC_E_UNAVAIL; 2825 } 2826 SOC_IF_ERROR_RETURN(READ_XMAC_EEE_TIMERSr(unit, port, &rval)); 2827 *value = soc_reg64_field32_get(unit, XMAC_EEE_TIMERSr, rval, 2828 EEE_WAKE_TIMERf); 2829 break; 2830 2831 case SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE: 2832 SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_CTRLr(unit, port, &rval)); 2833 *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval, 2834 LOCAL_FAULT_DISABLEf) ? 0 : 1; 2835 break; 2836 2837 case SOC_MAC_CONTROL_FAULT_LOCAL_STATUS: 2838 SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_STATUSr(unit, port, &rval)); 2839 *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_STATUSr, rval, 2840 LOCAL_FAULT_STATUSf); 2841 break; 2842 2843 case SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE: 2844 SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_CTRLr(unit, port, &rval)); 2845 *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval, 2846 REMOTE_FAULT_DISABLEf) ? 0 : 1; 2847 break; 2848 2849 case SOC_MAC_CONTROL_FAULT_REMOTE_STATUS: 2850 SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_STATUSr(unit, port, &rval)); 2851 *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_STATUSr, rval, 2852 REMOTE_FAULT_STATUSf); 2853 break; 2854 case SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID: 2855 SOC_IF_ERROR_RETURN(READ_XMAC_RX_VLAN_TAGr(unit, port, &rval)); 2856 *value = soc_reg64_field32_get(unit, XMAC_RX_VLAN_TAGr, 2857 rval, OUTER_VLAN_TAGf); 2858 break; 2859 case SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID: 2860 SOC_IF_ERROR_RETURN(READ_XMAC_RX_VLAN_TAGr(unit, port, &rval)); 2861 *value = soc_reg64_field32_get(unit, XMAC_RX_VLAN_TAGr, 2862 rval, INNER_VLAN_TAGf); 2863 break; 2864 case SOC_MAC_CONTROL_EXPECTED_RX_LATENCY: 2865 SOC_IF_ERROR_RETURN(mac_x_expected_rx_latency_get(unit, port, value)); 2866 break; 2867 default: 2868 return SOC_E_UNAVAIL; 2869 } 2870 2871 LOG_VERBOSE(BSL_LS_SOC_10G, 2872 (BSL_META_U(unit, 2873 "mac_x_control_get: unit %d port %s type=%d value=%d " 2874 "rv=%d\n"), 2875 unit, SOC_PORT_NAME(unit, port), 2876 type, *value, rv)); 2877 return rv; 2878 } 2879 2880 /* 2881 * Function: 2882 * mac_x_ability_local_get 2883 * Purpose: 2884 * Return the abilities of XMAC 2885 * Parameters: 2886 * unit - XGS unit #. 2887 * port - XGS port # on unit. 2888 * mode - (OUT) Supported operating modes as a mask of abilities. 2889 * Returns: 2890 * SOC_E_XXX 2891 */ 2892 STATIC int 2893 mac_x_ability_local_get(int unit, soc_port_t port, 2894 soc_port_ability_t *ability) 2895 { 2896 #ifdef BCM_KATANA2_SUPPORT 2897 uint8 mxqblock = 0; 2898 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 2899 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( 2900 unit,port,&mxqblock)); 2901 } 2902 #endif 2903 if (NULL == ability) { 2904 return SOC_E_PARAM; 2905 } 2906 2907 ability->speed_half_duplex = SOC_PA_ABILITY_NONE; 2908 ability->pause = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM; 2909 ability->interface = SOC_PA_INTF_MII | SOC_PA_INTF_XGMII; 2910 ability->medium = SOC_PA_ABILITY_NONE; 2911 ability->loopback = SOC_PA_LB_MAC; 2912 ability->flags = SOC_PA_ABILITY_NONE; 2913 ability->encap = SOC_PA_ENCAP_IEEE | SOC_PA_ENCAP_HIGIG | 2914 SOC_PA_ENCAP_HIGIG2; 2915 #ifdef BCM_KATANA2_SUPPORT 2916 if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && ((mxqblock == 6) || (mxqblock == 7))) { 2917 ability->encap |= SOC_PA_ENCAP_HIGIG2_LITE; 2918 } 2919 #endif 2920 2921 if (IS_HL_PORT(unit , port)) { 2922 if (SOC_INFO(unit).port_speed_max[port]) { 2923 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB; 2924 } 2925 } 2926 if (IS_HG_PORT(unit , port)) { 2927 switch (SOC_INFO(unit).port_speed_max[port]) { 2928 case 42000: 2929 ability->speed_full_duplex |= SOC_PA_SPEED_42GB; 2930 /* fall through */ 2931 case 40000: 2932 ability->speed_full_duplex |= SOC_PA_SPEED_40GB; 2933 if(soc_feature(unit, soc_feature_higig_misc_speed_support)) { 2934 ability->speed_full_duplex |= SOC_PA_SPEED_42GB; 2935 } 2936 /* fall through */ 2937 case 30000: 2938 ability->speed_full_duplex |= SOC_PA_SPEED_30GB; 2939 /* fall through */ 2940 case 25000: 2941 ability->speed_full_duplex |= SOC_PA_SPEED_25GB; 2942 /* fall through */ 2943 case 23000: 2944 ability->speed_full_duplex |= SOC_PA_SPEED_23GB; 2945 /* fall through */ 2946 case 21000: 2947 ability->speed_full_duplex |= SOC_PA_SPEED_21GB; 2948 /* fall through */ 2949 case 20000: 2950 ability->speed_full_duplex |= SOC_PA_SPEED_20GB; 2951 if(soc_feature(unit, soc_feature_higig_misc_speed_support)) { 2952 ability->speed_full_duplex |= SOC_PA_SPEED_21GB; 2953 } 2954 /* fall through */ 2955 case 16000: 2956 ability->speed_full_duplex |= SOC_PA_SPEED_16GB; 2957 /* fall through */ 2958 case 15000: 2959 ability->speed_full_duplex |= SOC_PA_SPEED_15GB; 2960 /* fall through */ 2961 case 13000: 2962 ability->speed_full_duplex |= SOC_PA_SPEED_13GB; 2963 /* fall through */ 2964 case 12000: 2965 ability->speed_full_duplex |= SOC_PA_SPEED_12GB; 2966 /* fall through */ 2967 case 11000: 2968 ability->speed_full_duplex |= SOC_PA_SPEED_11GB; 2969 /* fall through */ 2970 case 10000: 2971 ability->speed_full_duplex |= SOC_PA_SPEED_10GB; 2972 if (soc_feature(unit, soc_feature_higig_misc_speed_support)) { 2973 ability->speed_full_duplex |= SOC_PA_SPEED_11GB; 2974 } 2975 break; 2976 default: 2977 break; 2978 } 2979 } else { 2980 if (SOC_INFO(unit).port_speed_max[port] >= 40000) { 2981 ability->speed_full_duplex |= SOC_PA_SPEED_40GB | 2982 SOC_PA_SPEED_42GB; 2983 } 2984 2985 if (SOC_INFO(unit).port_speed_max[port] >= 20000) { 2986 ability->speed_full_duplex |= SOC_PA_SPEED_20GB; 2987 } 2988 if (SOC_INFO(unit).port_speed_max[port] >= 10000) { 2989 ability->speed_full_duplex |= SOC_PA_SPEED_10GB; 2990 } 2991 if (soc_feature(unit, soc_feature_unified_port) || IS_MXQ_PORT(unit, port)) { 2992 if (SOC_INFO(unit).port_speed_max[port] >= 2500) { 2993 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB; 2994 } 2995 if (SOC_INFO(unit).port_speed_max[port] >= 1000) { 2996 ability->speed_full_duplex |= SOC_PA_SPEED_1000MB; 2997 } 2998 if (SOC_INFO(unit).port_speed_max[port] >= 100) { 2999 ability->speed_full_duplex |= SOC_PA_SPEED_100MB; 3000 } 3001 if (SOC_INFO(unit).port_speed_max[port] >= 10) { 3002 ability->speed_full_duplex |= SOC_PA_SPEED_10MB; 3003 } 3004 } 3005 } 3006 3007 LOG_VERBOSE(BSL_LS_SOC_10G, 3008 (BSL_META_U(unit, 3009 "mac_x_ability_local_get: unit %d port %s " 3010 "speed_half=0x%x speed_full=0x%x encap=0x%x pause=0x%x " 3011 "interface=0x%x medium=0x%x loopback=0x%x flags=0x%x\n"), 3012 unit, SOC_PORT_NAME(unit, port), 3013 ability->speed_half_duplex, ability->speed_full_duplex, 3014 ability->encap, ability->pause, ability->interface, 3015 ability->medium, ability->loopback, ability->flags)); 3016 return SOC_E_NONE; 3017 } 3018 3019 /* Exported XMAC driver structure */ 3020 mac_driver_t soc_mac_x = { 3021 "XMAC Driver", /* drv_name */ 3022 mac_x_init, /* md_init */ 3023 mac_x_enable_set, /* md_enable_set */ 3024 mac_x_enable_get, /* md_enable_get */ 3025 mac_x_duplex_set, /* md_duplex_set */ 3026 mac_x_duplex_get, /* md_duplex_get */ 3027 mac_x_speed_set, /* md_speed_set */ 3028 mac_x_speed_get, /* md_speed_get */ 3029 mac_x_pause_set, /* md_pause_set */ 3030 mac_x_pause_get, /* md_pause_get */ 3031 mac_x_pause_addr_set, /* md_pause_addr_set */ 3032 mac_x_pause_addr_get, /* md_pause_addr_get */ 3033 mac_x_loopback_set, /* md_lb_set */ 3034 mac_x_loopback_get, /* md_lb_get */ 3035 mac_x_interface_set, /* md_interface_set */ 3036 mac_x_interface_get, /* md_interface_get */ 3037 NULL, /* md_ability_get - Deprecated */ 3038 mac_x_frame_max_set, /* md_frame_max_set */ 3039 mac_x_frame_max_get, /* md_frame_max_get */ 3040 mac_x_ifg_set, /* md_ifg_set */ 3041 mac_x_ifg_get, /* md_ifg_get */ 3042 mac_x_encap_set, /* md_encap_set */ 3043 mac_x_encap_get, /* md_encap_get */ 3044 mac_x_control_set, /* md_control_set */ 3045 mac_x_control_get, /* md_control_get */ 3046 mac_x_ability_local_get, /* md_ability_local_get */ 3047 NULL /* md_timesync_tx_info_get */ 3048 }; 3049 3050 #endif /* BCM_XMAC_SUPPORT */