1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/nxge/nxge_impl.h> 29 #include <sys/nxge/nxge_mac.h> 30 31 extern uint32_t nxge_no_link_notify; 32 extern uint32_t nxge_no_msg; 33 extern uint32_t nxge_lb_dbg; 34 extern nxge_os_mutex_t nxge_mdio_lock; 35 extern nxge_os_mutex_t nxge_mii_lock; 36 extern boolean_t nxge_jumbo_enable; 37 38 /* 39 * Ethernet broadcast address definition. 40 */ 41 static ether_addr_st etherbroadcastaddr = 42 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 43 44 nxge_status_t nxge_mac_init(p_nxge_t); 45 46 /* Initialize the entire MAC and physical layer */ 47 48 nxge_status_t 49 nxge_mac_init(p_nxge_t nxgep) 50 { 51 uint8_t portn; 52 nxge_status_t status = NXGE_OK; 53 54 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 55 56 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 57 58 nxgep->mac.portnum = portn; 59 nxgep->mac.porttype = PORT_TYPE_XMAC; 60 61 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 62 nxgep->mac.porttype = PORT_TYPE_BMAC; 63 64 /* Initialize XIF to configure a network mode */ 65 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 66 goto fail; 67 } 68 69 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 70 goto fail; 71 } 72 73 /* Initialize TX and RX MACs */ 74 /* 75 * Always perform XIF init first, before TX and RX MAC init 76 */ 77 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 78 goto fail; 79 80 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 81 goto fail; 82 83 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 84 goto fail; 85 86 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 87 goto fail; 88 89 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 90 goto fail; 91 92 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 93 goto fail; 94 95 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 96 97 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 98 99 return (NXGE_OK); 100 fail: 101 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 102 "nxge_mac_init: failed to initialize MAC port<%d>", 103 portn)); 104 return (status); 105 } 106 107 /* Initialize the Ethernet Link */ 108 109 nxge_status_t 110 nxge_link_init(p_nxge_t nxgep) 111 { 112 nxge_status_t status = NXGE_OK; 113 #ifdef NXGE_DEBUG 114 uint8_t portn; 115 116 portn = nxgep->mac.portnum; 117 118 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 119 #endif 120 121 if (nxgep->niu_type == N2_NIU) { 122 /* Workaround to get link up in both NIU ports */ 123 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 124 goto fail; 125 } 126 NXGE_DELAY(200000); 127 /* Initialize internal serdes */ 128 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 129 goto fail; 130 NXGE_DELAY(200000); 131 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 132 goto fail; 133 134 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 135 136 return (NXGE_OK); 137 138 fail: 139 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 140 "nxge_link_init: ", 141 "failed to initialize Ethernet link on port<%d>", 142 portn)); 143 144 return (status); 145 } 146 147 148 /* Initialize the XIF sub-block within the MAC */ 149 150 nxge_status_t 151 nxge_xif_init(p_nxge_t nxgep) 152 { 153 uint32_t xif_cfg = 0; 154 npi_attr_t ap; 155 uint8_t portn; 156 nxge_port_t portt; 157 nxge_port_mode_t portmode; 158 p_nxge_stats_t statsp; 159 npi_status_t rs = NPI_SUCCESS; 160 npi_handle_t handle; 161 162 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 163 164 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 165 166 handle = nxgep->npi_handle; 167 portmode = nxgep->mac.portmode; 168 portt = nxgep->mac.porttype; 169 statsp = nxgep->statsp; 170 171 if (portt == PORT_TYPE_XMAC) { 172 173 /* Setup XIF Configuration for XMAC */ 174 175 if ((portmode == PORT_10G_FIBER) || 176 (portmode == PORT_10G_COPPER)) 177 xif_cfg |= CFG_XMAC_XIF_LFS; 178 179 if (portmode == PORT_1G_COPPER) { 180 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 181 } 182 183 /* Set MAC Internal Loopback if necessary */ 184 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 185 xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 186 187 if (statsp->mac_stats.link_speed == 100) 188 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 189 190 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 191 192 if (portmode == PORT_10G_FIBER) { 193 if (statsp->mac_stats.link_up) { 194 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 195 } else { 196 xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 197 } 198 } 199 200 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 201 if (rs != NPI_SUCCESS) 202 goto fail; 203 204 nxgep->mac.xif_config = xif_cfg; 205 206 /* Set Port Mode */ 207 if ((portmode == PORT_10G_FIBER) || 208 (portmode == PORT_10G_COPPER)) { 209 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 210 MAC_XGMII_MODE, rs); 211 if (rs != NPI_SUCCESS) 212 goto fail; 213 if (statsp->mac_stats.link_up) { 214 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 215 goto fail; 216 } else { 217 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 218 goto fail; 219 } 220 } else if ((portmode == PORT_1G_FIBER) || 221 (portmode == PORT_1G_COPPER)) { 222 if (statsp->mac_stats.link_speed == 1000) { 223 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 224 MAC_GMII_MODE, rs); 225 } else { 226 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 227 MAC_MII_MODE, rs); 228 } 229 if (rs != NPI_SUCCESS) 230 goto fail; 231 } else { 232 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 233 "nxge_xif_init: Unknown port mode (%d)" 234 " for port<%d>", portmode, portn)); 235 goto fail; 236 } 237 238 } else if (portt == PORT_TYPE_BMAC) { 239 240 /* Setup XIF Configuration for BMAC */ 241 242 if (portmode == PORT_1G_COPPER) { 243 if (statsp->mac_stats.link_speed == 100) 244 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 245 } 246 247 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 248 xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 249 250 if (statsp->mac_stats.link_speed == 1000) 251 xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 252 253 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 254 255 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 256 if (rs != NPI_SUCCESS) 257 goto fail; 258 nxgep->mac.xif_config = xif_cfg; 259 } 260 261 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 262 return (NXGE_OK); 263 fail: 264 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 265 "nxge_xif_init: Failed to initialize XIF port<%d>", 266 portn)); 267 return (NXGE_ERROR | rs); 268 } 269 270 /* Initialize the PCS sub-block in the MAC */ 271 272 nxge_status_t 273 nxge_pcs_init(p_nxge_t nxgep) 274 { 275 pcs_cfg_t pcs_cfg; 276 uint32_t val; 277 uint8_t portn; 278 nxge_port_mode_t portmode; 279 npi_handle_t handle; 280 p_nxge_stats_t statsp; 281 npi_status_t rs = NPI_SUCCESS; 282 283 handle = nxgep->npi_handle; 284 portmode = nxgep->mac.portmode; 285 portn = nxgep->mac.portnum; 286 statsp = nxgep->statsp; 287 288 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 289 290 if (portmode == PORT_1G_FIBER) { 291 /* Initialize port's PCS */ 292 pcs_cfg.value = 0; 293 pcs_cfg.bits.w0.enable = 1; 294 pcs_cfg.bits.w0.mask = 1; 295 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 296 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 297 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 298 goto fail; 299 300 } else if ((portmode == PORT_10G_FIBER) || 301 (portmode == PORT_10G_COPPER)) { 302 /* Use internal XPCS, bypass 1G PCS */ 303 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 304 val &= ~XMAC_XIF_XPCS_BYPASS; 305 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 306 307 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 308 goto fail; 309 310 /* Set XPCS Internal Loopback if necessary */ 311 if ((rs = npi_xmac_xpcs_read(handle, portn, 312 XPCS_REG_CONTROL1, &val)) 313 != NPI_SUCCESS) 314 goto fail; 315 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 316 (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 317 val |= XPCS_CTRL1_LOOPBK; 318 else 319 val &= ~XPCS_CTRL1_LOOPBK; 320 if ((rs = npi_xmac_xpcs_write(handle, portn, 321 XPCS_REG_CONTROL1, val)) 322 != NPI_SUCCESS) 323 goto fail; 324 325 /* Clear descw errors */ 326 if ((rs = npi_xmac_xpcs_write(handle, portn, 327 XPCS_REG_DESCWERR_COUNTER, 0)) 328 != NPI_SUCCESS) 329 goto fail; 330 /* Clear symbol errors */ 331 if ((rs = npi_xmac_xpcs_read(handle, portn, 332 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) 333 != NPI_SUCCESS) 334 goto fail; 335 if ((rs = npi_xmac_xpcs_read(handle, portn, 336 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) 337 != NPI_SUCCESS) 338 goto fail; 339 340 } else if (portmode == PORT_1G_COPPER) { 341 if (portn < 4) { 342 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 343 PCS_DATAPATH_MODE_MII); 344 } 345 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 346 goto fail; 347 348 } else { 349 goto fail; 350 } 351 pass: 352 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 353 return (NXGE_OK); 354 fail: 355 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 356 "nxge_pcs_init: Failed to initialize PCS port<%d>", 357 portn)); 358 return (NXGE_ERROR | rs); 359 } 360 361 /* Initialize the Internal Serdes */ 362 363 nxge_status_t 364 nxge_serdes_init(p_nxge_t nxgep) 365 { 366 p_nxge_stats_t statsp; 367 #ifdef NXGE_DEBUG 368 uint8_t portn; 369 #endif 370 nxge_status_t status = NXGE_OK; 371 372 #ifdef NXGE_DEBUG 373 portn = nxgep->mac.portnum; 374 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 375 "==> nxge_serdes_init port<%d>", portn)); 376 #endif 377 378 statsp = nxgep->statsp; 379 380 if (nxgep->niu_type == N2_NIU) { 381 if (nxge_n2_serdes_init(nxgep) != NXGE_OK) 382 goto fail; 383 } else if ((nxgep->niu_type == NEPTUNE) || 384 (nxgep->niu_type == NEPTUNE_2)) { 385 if ((status = nxge_neptune_serdes_init(nxgep)) 386 != NXGE_OK) 387 goto fail; 388 } else { 389 goto fail; 390 } 391 392 statsp->mac_stats.serdes_inits++; 393 394 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 395 portn)); 396 397 return (NXGE_OK); 398 399 fail: 400 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 401 "nxge_serdes_init: Failed to initialize serdes for port<%d>", 402 portn)); 403 404 return (status); 405 } 406 407 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 408 409 nxge_status_t 410 nxge_n2_serdes_init(p_nxge_t nxgep) 411 { 412 uint8_t portn; 413 int chan; 414 esr_ti_cfgpll_l_t pll_cfg_l; 415 esr_ti_cfgrx_l_t rx_cfg_l; 416 esr_ti_cfgrx_h_t rx_cfg_h; 417 esr_ti_cfgtx_l_t tx_cfg_l; 418 esr_ti_cfgtx_h_t tx_cfg_h; 419 esr_ti_testcfg_t test_cfg; 420 nxge_status_t status = NXGE_OK; 421 422 portn = nxgep->mac.portnum; 423 424 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 425 portn)); 426 427 tx_cfg_l.value = 0; 428 tx_cfg_h.value = 0; 429 rx_cfg_l.value = 0; 430 rx_cfg_h.value = 0; 431 pll_cfg_l.value = 0; 432 test_cfg.value = 0; 433 434 if (nxgep->mac.portmode == PORT_10G_FIBER) { 435 /* 0x0E01 */ 436 tx_cfg_l.bits.entx = 1; 437 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 438 439 /* 0x9101 */ 440 rx_cfg_l.bits.enrx = 1; 441 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 442 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 443 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 444 445 /* 0x0008 */ 446 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 447 448 /* Set loopback mode if necessary */ 449 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 450 tx_cfg_l.bits.entest = 1; 451 rx_cfg_l.bits.entest = 1; 452 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 453 if ((status = nxge_mdio_write(nxgep, portn, 454 ESR_N2_DEV_ADDR, 455 ESR_N2_TEST_CFG_REG, test_cfg.value)) 456 != NXGE_OK) 457 goto fail; 458 } 459 460 /* Use default PLL value */ 461 462 } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 463 464 /* 0x0E21 */ 465 tx_cfg_l.bits.entx = 1; 466 tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 467 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 468 469 /* 0x9121 */ 470 rx_cfg_l.bits.enrx = 1; 471 rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 472 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 473 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 474 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 475 476 /* 0x8 */ 477 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 478 479 /* MPY = 0x100 */ 480 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 481 482 /* Set PLL */ 483 pll_cfg_l.bits.enpll = 1; 484 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 485 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) 486 != NXGE_OK) 487 goto fail; 488 } else { 489 goto fail; 490 } 491 492 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 493 494 NXGE_DELAY(20); 495 496 /* init TX channels */ 497 for (chan = 0; chan < 4; chan++) { 498 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 499 ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) 500 != NXGE_OK) 501 goto fail; 502 503 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 504 ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) 505 != NXGE_OK) 506 goto fail; 507 } 508 509 /* init RX channels */ 510 for (chan = 0; chan < 4; chan++) { 511 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 512 ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) 513 != NXGE_OK) 514 goto fail; 515 516 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 517 ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) 518 != NXGE_OK) 519 goto fail; 520 } 521 522 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 523 portn)); 524 525 return (NXGE_OK); 526 fail: 527 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 528 "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 529 portn)); 530 531 return (status); 532 } 533 534 /* Initialize Neptune Internal Serdes (Neptune only) */ 535 536 nxge_status_t 537 nxge_neptune_serdes_init(p_nxge_t nxgep) 538 { 539 npi_handle_t handle; 540 uint8_t portn; 541 nxge_port_mode_t portmode; 542 int chan; 543 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 544 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 545 sr_glue_ctrl0_l_t glue_ctrl0_l; 546 sr_glue_ctrl0_h_t glue_ctrl0_h; 547 uint64_t val; 548 uint16_t val16l; 549 uint16_t val16h; 550 nxge_status_t status = NXGE_OK; 551 552 portn = nxgep->mac.portnum; 553 554 if ((portn != 0) && (portn != 1)) 555 return (NXGE_OK); 556 557 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_neptune_serdes_init port<%d>", 558 portn)); 559 560 handle = nxgep->npi_handle; 561 portmode = nxgep->mac.portmode; 562 563 if ((portmode == PORT_10G_FIBER) || (portmode == PORT_10G_COPPER)) { 564 565 switch (portn) { 566 case 0: 567 ESR_REG_WR(handle, ESR_0_CONTROL_REG, 568 ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 569 ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 570 (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 571 (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 572 (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 573 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 574 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 575 (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 576 (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 577 (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 578 (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 579 580 /* Set Serdes0 Internal Loopback if necessary */ 581 if (nxgep->statsp->port_stats.lb_mode == 582 nxge_lb_serdes10g) { 583 ESR_REG_WR(handle, 584 ESR_0_TEST_CONFIG_REG, 585 ESR_PAD_LOOPBACK_CH3 | 586 ESR_PAD_LOOPBACK_CH2 | 587 ESR_PAD_LOOPBACK_CH1 | 588 ESR_PAD_LOOPBACK_CH0); 589 } else { 590 ESR_REG_WR(handle, 591 ESR_0_TEST_CONFIG_REG, 0); 592 } 593 break; 594 case 1: 595 ESR_REG_WR(handle, ESR_1_CONTROL_REG, 596 ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 597 ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 598 (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 599 (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 600 (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 601 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 602 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 603 (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 604 (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 605 (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 606 (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 607 608 /* Set Serdes1 Internal Loopback if necessary */ 609 if (nxgep->statsp->port_stats.lb_mode == 610 nxge_lb_serdes10g) { 611 ESR_REG_WR(handle, 612 ESR_1_TEST_CONFIG_REG, 613 ESR_PAD_LOOPBACK_CH3 | 614 ESR_PAD_LOOPBACK_CH2 | 615 ESR_PAD_LOOPBACK_CH1 | 616 ESR_PAD_LOOPBACK_CH0); 617 } else { 618 ESR_REG_WR(handle, 619 ESR_1_TEST_CONFIG_REG, 0); 620 } 621 break; 622 default: 623 /* Nothing to do here */ 624 goto done; 625 } 626 627 /* init TX RX channels */ 628 for (chan = 0; chan < 4; chan++) { 629 if ((status = nxge_mdio_read(nxgep, portn, 630 ESR_NEPTUNE_DEV_ADDR, 631 ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 632 &rx_tx_ctrl_l.value)) != NXGE_OK) 633 goto fail; 634 if ((status = nxge_mdio_read(nxgep, portn, 635 ESR_NEPTUNE_DEV_ADDR, 636 ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 637 &rx_tx_ctrl_h.value)) != NXGE_OK) 638 goto fail; 639 if ((status = nxge_mdio_read(nxgep, portn, 640 ESR_NEPTUNE_DEV_ADDR, 641 ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 642 &glue_ctrl0_l.value)) != NXGE_OK) 643 goto fail; 644 if ((status = nxge_mdio_read(nxgep, portn, 645 ESR_NEPTUNE_DEV_ADDR, 646 ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 647 &glue_ctrl0_h.value)) != NXGE_OK) 648 goto fail; 649 rx_tx_ctrl_l.bits.enstretch = 1; 650 rx_tx_ctrl_h.bits.vmuxlo = 2; 651 rx_tx_ctrl_h.bits.vpulselo = 2; 652 glue_ctrl0_l.bits.rxlosenable = 1; 653 glue_ctrl0_l.bits.samplerate = 0xF; 654 glue_ctrl0_l.bits.thresholdcount = 0xFF; 655 glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 656 if ((status = nxge_mdio_write(nxgep, portn, 657 ESR_NEPTUNE_DEV_ADDR, 658 ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 659 rx_tx_ctrl_l.value)) != NXGE_OK) 660 goto fail; 661 if ((status = nxge_mdio_write(nxgep, portn, 662 ESR_NEPTUNE_DEV_ADDR, 663 ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 664 rx_tx_ctrl_h.value)) != NXGE_OK) 665 goto fail; 666 if ((status = nxge_mdio_write(nxgep, portn, 667 ESR_NEPTUNE_DEV_ADDR, 668 ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 669 glue_ctrl0_l.value)) != NXGE_OK) 670 goto fail; 671 if ((status = nxge_mdio_write(nxgep, portn, 672 ESR_NEPTUNE_DEV_ADDR, 673 ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 674 glue_ctrl0_h.value)) != NXGE_OK) 675 goto fail; 676 } 677 678 /* Apply Tx core reset */ 679 if ((status = nxge_mdio_write(nxgep, portn, 680 ESR_NEPTUNE_DEV_ADDR, 681 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 682 (uint16_t)0)) != NXGE_OK) 683 goto fail; 684 685 if ((status = nxge_mdio_write(nxgep, portn, 686 ESR_NEPTUNE_DEV_ADDR, 687 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), 688 (uint16_t)0xffff)) != NXGE_OK) 689 goto fail; 690 691 NXGE_DELAY(200); 692 693 /* Apply Rx core reset */ 694 if ((status = nxge_mdio_write(nxgep, portn, 695 ESR_NEPTUNE_DEV_ADDR, 696 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 697 (uint16_t)0xffff)) != NXGE_OK) 698 goto fail; 699 700 NXGE_DELAY(200); 701 if ((status = nxge_mdio_write(nxgep, portn, 702 ESR_NEPTUNE_DEV_ADDR, 703 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), 704 (uint16_t)0)) != NXGE_OK) 705 goto fail; 706 707 NXGE_DELAY(200); 708 if ((status = nxge_mdio_read(nxgep, portn, 709 ESR_NEPTUNE_DEV_ADDR, 710 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 711 &val16l)) != NXGE_OK) 712 goto fail; 713 if ((status = nxge_mdio_read(nxgep, portn, 714 ESR_NEPTUNE_DEV_ADDR, 715 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), 716 &val16h)) != NXGE_OK) 717 goto fail; 718 if ((val16l != 0) || (val16h != 0)) { 719 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 720 "Failed to reset port<%d> XAUI Serdes", 721 portn)); 722 } 723 724 ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 725 726 if (portn == 0) { 727 if ((val & ESR_SIG_P0_BITS_MASK) != 728 (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 729 ESR_SIG_XSERDES_RDY_P0 | 730 ESR_SIG_XDETECT_P0_CH3 | 731 ESR_SIG_XDETECT_P0_CH2 | 732 ESR_SIG_XDETECT_P0_CH1 | 733 ESR_SIG_XDETECT_P0_CH0)) { 734 goto fail; 735 } 736 } else if (portn == 1) { 737 if ((val & ESR_SIG_P1_BITS_MASK) != 738 (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 739 ESR_SIG_XSERDES_RDY_P1 | 740 ESR_SIG_XDETECT_P1_CH3 | 741 ESR_SIG_XDETECT_P1_CH2 | 742 ESR_SIG_XDETECT_P1_CH1 | 743 ESR_SIG_XDETECT_P1_CH0)) { 744 goto fail; 745 } 746 } 747 748 } else if (portmode == PORT_1G_FIBER) { 749 ESR_REG_RD(handle, ESR_1_PLL_CONFIG_REG, &val) 750 val &= ~ESR_PLL_CFG_FBDIV_2; 751 switch (portn) { 752 case 0: 753 val |= ESR_PLL_CFG_HALF_RATE_0; 754 break; 755 case 1: 756 val |= ESR_PLL_CFG_HALF_RATE_1; 757 break; 758 case 2: 759 val |= ESR_PLL_CFG_HALF_RATE_2; 760 break; 761 case 3: 762 val |= ESR_PLL_CFG_HALF_RATE_3; 763 break; 764 default: 765 goto fail; 766 } 767 768 ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, val); 769 } 770 771 done: 772 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_neptune_serdes_init port<%d>", 773 portn)); 774 return (NXGE_OK); 775 fail: 776 NXGE_DEBUG_MSG((nxgep, TX_CTL, 777 "nxge_neptune_serdes_init: " 778 "Failed to initialize Neptune serdes for port<%d>", 779 portn)); 780 781 return (status); 782 } 783 784 /* Look for transceiver type */ 785 786 nxge_status_t 787 nxge_xcvr_find(p_nxge_t nxgep) 788 { 789 uint8_t portn; 790 791 portn = nxgep->mac.portnum; 792 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", portn)); 793 794 if (nxge_get_xcvr_type(nxgep) != NXGE_OK) 795 return (NXGE_ERROR); 796 797 nxgep->mac.linkchkmode = LINKCHK_TIMER; 798 if (nxgep->mac.portmode == PORT_10G_FIBER) { 799 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 800 if ((nxgep->niu_type == NEPTUNE) || 801 (nxgep->niu_type == NEPTUNE_2)) { 802 nxgep->statsp->mac_stats.xcvr_portn = 803 BCM8704_NEPTUNE_PORT_ADDR_BASE + portn; 804 } else if (nxgep->niu_type == N2_NIU) { 805 nxgep->statsp->mac_stats.xcvr_portn = 806 BCM8704_N2_PORT_ADDR_BASE + portn; 807 } else 808 return (NXGE_ERROR); 809 } else if (nxgep->mac.portmode == PORT_1G_COPPER) { 810 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 811 /* 812 * For Altas, Xcvr port numbers are swapped with ethernet 813 * port number. This is designed for better signal 814 * integrity in routing. 815 */ 816 817 switch (portn) { 818 case 0: 819 nxgep->statsp->mac_stats.xcvr_portn = 820 BCM5464_NEPTUNE_PORT_ADDR_BASE + 3; 821 break; 822 case 1: 823 nxgep->statsp->mac_stats.xcvr_portn = 824 BCM5464_NEPTUNE_PORT_ADDR_BASE + 2; 825 break; 826 case 2: 827 nxgep->statsp->mac_stats.xcvr_portn = 828 BCM5464_NEPTUNE_PORT_ADDR_BASE + 1; 829 break; 830 case 3: 831 nxgep->statsp->mac_stats.xcvr_portn = 832 BCM5464_NEPTUNE_PORT_ADDR_BASE; 833 break; 834 default: 835 return (NXGE_ERROR); 836 } 837 } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 838 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 839 nxgep->statsp->mac_stats.xcvr_portn = portn; 840 } else { 841 return (NXGE_ERROR); 842 } 843 844 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d", 845 nxgep->statsp->mac_stats.xcvr_inuse)); 846 return (NXGE_OK); 847 } 848 849 /* Initialize transceiver */ 850 851 nxge_status_t 852 nxge_xcvr_init(p_nxge_t nxgep) 853 { 854 p_nxge_param_t param_arr; 855 p_nxge_stats_t statsp; 856 uint8_t portn; 857 uint16_t val; 858 #ifdef NXGE_DEBUG 859 uint16_t val1; 860 #endif 861 uint8_t phy_port_addr; 862 pmd_tx_control_t tx_ctl; 863 control_t ctl; 864 phyxs_control_t phyxs_ctl; 865 pcs_control_t pcs_ctl; 866 uint32_t delay = 0; 867 optics_dcntr_t op_ctr; 868 nxge_status_t status = NXGE_OK; 869 870 portn = nxgep->mac.portnum; 871 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 872 873 param_arr = nxgep->param_arr; 874 statsp = nxgep->statsp; 875 876 /* 877 * Initialise the xcvr statistics. 878 */ 879 statsp->mac_stats.cap_autoneg = 0; 880 statsp->mac_stats.cap_100T4 = 0; 881 statsp->mac_stats.cap_100fdx = 0; 882 statsp->mac_stats.cap_100hdx = 0; 883 statsp->mac_stats.cap_10fdx = 0; 884 statsp->mac_stats.cap_10hdx = 0; 885 statsp->mac_stats.cap_asmpause = 0; 886 statsp->mac_stats.cap_pause = 0; 887 statsp->mac_stats.cap_1000fdx = 0; 888 statsp->mac_stats.cap_1000hdx = 0; 889 statsp->mac_stats.cap_10gfdx = 0; 890 statsp->mac_stats.cap_10ghdx = 0; 891 892 /* 893 * Initialize the link statistics. 894 */ 895 statsp->mac_stats.link_T4 = 0; 896 statsp->mac_stats.link_asmpause = 0; 897 statsp->mac_stats.link_pause = 0; 898 899 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 900 901 switch (nxgep->mac.portmode) { 902 case PORT_10G_FIBER: 903 /* Disable Link LEDs */ 904 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 905 goto fail; 906 907 /* Set Clause 45 */ 908 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 909 910 /* Reset the transceiver */ 911 if ((status = nxge_mdio_read(nxgep, 912 phy_port_addr, 913 BCM8704_PHYXS_ADDR, 914 BCM8704_PHYXS_CONTROL_REG, 915 &phyxs_ctl.value)) != NXGE_OK) 916 goto fail; 917 918 phyxs_ctl.bits.reset = 1; 919 if ((status = nxge_mdio_write(nxgep, 920 phy_port_addr, 921 BCM8704_PHYXS_ADDR, 922 BCM8704_PHYXS_CONTROL_REG, 923 phyxs_ctl.value)) != NXGE_OK) 924 goto fail; 925 926 do { 927 drv_usecwait(500); 928 if ((status = nxge_mdio_read(nxgep, 929 phy_port_addr, 930 BCM8704_PHYXS_ADDR, 931 BCM8704_PHYXS_CONTROL_REG, 932 &phyxs_ctl.value)) != NXGE_OK) 933 goto fail; 934 delay++; 935 } while ((phyxs_ctl.bits.reset) && (delay < 100)); 936 if (delay == 100) { 937 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 938 "nxge_xcvr_init: " 939 "failed to reset Transceiver on port<%d>", 940 portn)); 941 status = NXGE_ERROR; 942 goto fail; 943 } 944 945 /* Set to 0x7FBF */ 946 ctl.value = 0; 947 ctl.bits.res1 = 0x3F; 948 ctl.bits.optxon_lvl = 1; 949 ctl.bits.oprxflt_lvl = 1; 950 ctl.bits.optrxlos_lvl = 1; 951 ctl.bits.optxflt_lvl = 1; 952 ctl.bits.opprflt_lvl = 1; 953 ctl.bits.obtmpflt_lvl = 1; 954 ctl.bits.opbiasflt_lvl = 1; 955 ctl.bits.optxrst_lvl = 1; 956 if ((status = nxge_mdio_write(nxgep, 957 phy_port_addr, 958 BCM8704_USER_DEV3_ADDR, 959 BCM8704_USER_CONTROL_REG, ctl.value)) 960 != NXGE_OK) 961 goto fail; 962 963 /* Set to 0x164 */ 964 tx_ctl.value = 0; 965 tx_ctl.bits.tsck_lpwren = 1; 966 tx_ctl.bits.tx_dac_txck = 0x2; 967 tx_ctl.bits.tx_dac_txd = 0x1; 968 tx_ctl.bits.xfp_clken = 1; 969 if ((status = nxge_mdio_write(nxgep, 970 phy_port_addr, 971 BCM8704_USER_DEV3_ADDR, 972 BCM8704_USER_PMD_TX_CONTROL_REG, tx_ctl.value)) 973 != NXGE_OK) 974 goto fail; 975 /* 976 * According to Broadcom's instruction, SW needs to read 977 * back these registers twice after written. 978 */ 979 if ((status = nxge_mdio_read(nxgep, 980 phy_port_addr, 981 BCM8704_USER_DEV3_ADDR, 982 BCM8704_USER_CONTROL_REG, &val)) 983 != NXGE_OK) 984 goto fail; 985 986 if ((status = nxge_mdio_read(nxgep, 987 phy_port_addr, 988 BCM8704_USER_DEV3_ADDR, 989 BCM8704_USER_CONTROL_REG, &val)) 990 != NXGE_OK) 991 goto fail; 992 993 if ((status = nxge_mdio_read(nxgep, 994 phy_port_addr, 995 BCM8704_USER_DEV3_ADDR, 996 BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 997 != NXGE_OK) 998 goto fail; 999 1000 if ((status = nxge_mdio_read(nxgep, 1001 phy_port_addr, 1002 BCM8704_USER_DEV3_ADDR, 1003 BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 1004 != NXGE_OK) 1005 goto fail; 1006 1007 1008 if (((nxgep->board_ver < 4) && (portn == 1)) && 1009 ((nxgep->niu_type == NEPTUNE) || 1010 (nxgep->niu_type == NEPTUNE_2))) { 1011 /* 1012 * XAUI signals' polarity on Channel 0 to 2 are swapped 1013 * on port 1 due to routing. 1014 */ 1015 if ((status = nxge_mdio_write(nxgep, 1016 phy_port_addr, 1017 BCM8704_USER_DEV4_ADDR, 1018 BCM8704_USER_RX2_CONTROL1_REG, 1019 BCM8704_RXPOL_FLIP)) != NXGE_OK) 1020 goto fail; 1021 if ((status = nxge_mdio_write(nxgep, 1022 phy_port_addr, 1023 BCM8704_USER_DEV4_ADDR, 1024 BCM8704_USER_RX1_CONTROL1_REG, 1025 BCM8704_RXPOL_FLIP)) != NXGE_OK) 1026 goto fail; 1027 if ((status = nxge_mdio_write(nxgep, 1028 phy_port_addr, 1029 BCM8704_USER_DEV4_ADDR, 1030 BCM8704_USER_RX0_CONTROL1_REG, 1031 BCM8704_RXPOL_FLIP)) != NXGE_OK) 1032 goto fail; 1033 } 1034 1035 /* Enable Tx and Rx LEDs to be driven by traffic */ 1036 if ((status = nxge_mdio_read(nxgep, 1037 phy_port_addr, 1038 BCM8704_USER_DEV3_ADDR, 1039 BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1040 &op_ctr.value)) != NXGE_OK) 1041 goto fail; 1042 op_ctr.bits.gpio_sel = 0x3; 1043 if ((status = nxge_mdio_write(nxgep, 1044 phy_port_addr, 1045 BCM8704_USER_DEV3_ADDR, 1046 BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1047 op_ctr.value)) != NXGE_OK) 1048 goto fail; 1049 1050 NXGE_DELAY(1000000); 1051 1052 /* Set BCM8704 Internal Loopback mode if necessary */ 1053 if ((status = nxge_mdio_read(nxgep, 1054 phy_port_addr, 1055 BCM8704_PCS_DEV_ADDR, 1056 BCM8704_PCS_CONTROL_REG, 1057 &pcs_ctl.value)) != NXGE_OK) 1058 goto fail; 1059 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 1060 pcs_ctl.bits.loopback = 1; 1061 else 1062 pcs_ctl.bits.loopback = 0; 1063 if ((status = nxge_mdio_write(nxgep, 1064 phy_port_addr, 1065 BCM8704_PCS_DEV_ADDR, 1066 BCM8704_PCS_CONTROL_REG, 1067 pcs_ctl.value)) != NXGE_OK) 1068 goto fail; 1069 1070 status = nxge_mdio_read(nxgep, phy_port_addr, 1071 0x1, 0xA, &val); 1072 if (status != NXGE_OK) 1073 goto fail; 1074 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1075 "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", 1076 portn, val)); 1077 status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 1078 if (status != NXGE_OK) 1079 goto fail; 1080 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1081 "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", 1082 portn, val)); 1083 status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 1084 if (status != NXGE_OK) 1085 goto fail; 1086 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1087 "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", 1088 portn, val)); 1089 1090 #ifdef NXGE_DEBUG 1091 /* Diagnose link issue if link is not up */ 1092 status = nxge_mdio_read(nxgep, phy_port_addr, 1093 BCM8704_USER_DEV3_ADDR, 1094 BCM8704_USER_ANALOG_STATUS0_REG, 1095 &val); 1096 if (status != NXGE_OK) 1097 goto fail; 1098 1099 status = nxge_mdio_read(nxgep, phy_port_addr, 1100 BCM8704_USER_DEV3_ADDR, 1101 BCM8704_USER_ANALOG_STATUS0_REG, 1102 &val); 1103 if (status != NXGE_OK) 1104 goto fail; 1105 1106 status = nxge_mdio_read(nxgep, phy_port_addr, 1107 BCM8704_USER_DEV3_ADDR, 1108 BCM8704_USER_TX_ALARM_STATUS_REG, 1109 &val1); 1110 if (status != NXGE_OK) 1111 goto fail; 1112 1113 status = nxge_mdio_read(nxgep, phy_port_addr, 1114 BCM8704_USER_DEV3_ADDR, 1115 BCM8704_USER_TX_ALARM_STATUS_REG, 1116 &val1); 1117 if (status != NXGE_OK) 1118 goto fail; 1119 1120 if (val != 0x3FC) { 1121 if ((val == 0x43BC) && (val1 != 0)) { 1122 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1123 "Cable not connected to peer or bad" 1124 " cable on port<%d>\n", portn)); 1125 } else if (val == 0x639C) { 1126 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1127 "Optical module (XFP) is bad or absence" 1128 " on port<%d>\n", portn)); 1129 } 1130 } 1131 #endif 1132 1133 statsp->mac_stats.cap_10gfdx = 1; 1134 statsp->mac_stats.lp_cap_10gfdx = 1; 1135 break; 1136 case PORT_10G_COPPER: 1137 break; 1138 case PORT_1G_FIBER: 1139 case PORT_1G_COPPER: 1140 /* Set Clause 22 */ 1141 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 1142 1143 /* Set capability flags */ 1144 statsp->mac_stats.cap_1000fdx = 1145 param_arr[param_anar_1000fdx].value; 1146 statsp->mac_stats.cap_100fdx = 1147 param_arr[param_anar_100fdx].value; 1148 statsp->mac_stats.cap_10fdx = param_arr[param_anar_10fdx].value; 1149 1150 if ((status = nxge_mii_xcvr_init(nxgep)) != NXGE_OK) 1151 goto fail; 1152 break; 1153 default: 1154 goto fail; 1155 } 1156 1157 statsp->mac_stats.xcvr_inits++; 1158 1159 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 1160 return (NXGE_OK); 1161 1162 fail: 1163 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1164 "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 1165 portn)); 1166 return (status); 1167 } 1168 1169 1170 /* Initialize the TxMAC sub-block */ 1171 1172 nxge_status_t 1173 nxge_tx_mac_init(p_nxge_t nxgep) 1174 { 1175 npi_attr_t ap; 1176 uint8_t portn; 1177 nxge_port_mode_t portmode; 1178 nxge_port_t portt; 1179 npi_handle_t handle; 1180 npi_status_t rs = NPI_SUCCESS; 1181 1182 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 1183 portt = nxgep->mac.porttype; 1184 handle = nxgep->npi_handle; 1185 portmode = nxgep->mac.portmode; 1186 1187 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 1188 portn)); 1189 1190 /* Set Max and Min Frame Size */ 1191 if (nxge_jumbo_enable) { 1192 SET_MAC_ATTR2(handle, ap, portn, 1193 MAC_PORT_FRAME_SIZE, 64, 0x2400, rs); 1194 } else { 1195 SET_MAC_ATTR2(handle, ap, portn, 1196 MAC_PORT_FRAME_SIZE, 64, 0x5EE + 4, rs); 1197 } 1198 1199 if (rs != NPI_SUCCESS) 1200 goto fail; 1201 nxgep->mac.is_jumbo = B_FALSE; 1202 if (nxgep->mac.is_jumbo == B_TRUE) 1203 nxgep->mac.maxframesize = 0x2400; 1204 else 1205 nxgep->mac.maxframesize = 0x5EE + 4; 1206 nxgep->mac.minframesize = 64; 1207 1208 if (portt == PORT_TYPE_XMAC) { 1209 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 1210 0)) != NPI_SUCCESS) 1211 goto fail; 1212 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 1213 if ((portmode == PORT_10G_FIBER) || 1214 (portmode == PORT_10G_COPPER)) { 1215 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 1216 XGMII_IPG_12_15, rs); 1217 if (rs != NPI_SUCCESS) 1218 goto fail; 1219 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 1220 } else { 1221 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 1222 MII_GMII_IPG_12, rs); 1223 if (rs != NPI_SUCCESS) 1224 goto fail; 1225 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 1226 } 1227 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 1228 CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 1229 goto fail; 1230 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 1231 nxgep->mac.maxburstsize = 0; /* not programmable */ 1232 nxgep->mac.ctrltype = 0; /* not programmable */ 1233 nxgep->mac.pa_size = 0; /* not programmable */ 1234 1235 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 1236 != NPI_SUCCESS) 1237 goto fail; 1238 1239 } else { 1240 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 1241 0)) != NPI_SUCCESS) 1242 goto fail; 1243 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 1244 1245 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 1246 rs); 1247 if (rs != NPI_SUCCESS) 1248 goto fail; 1249 nxgep->mac.ctrltype = 0x8808; 1250 1251 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 1252 if (rs != NPI_SUCCESS) 1253 goto fail; 1254 nxgep->mac.pa_size = 0x7; 1255 1256 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 1257 CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 1258 goto fail; 1259 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 1260 } 1261 1262 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 1263 portn)); 1264 1265 return (NXGE_OK); 1266 fail: 1267 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1268 "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", 1269 portn)); 1270 1271 return (NXGE_ERROR | rs); 1272 } 1273 1274 /* Initialize the RxMAC sub-block */ 1275 1276 nxge_status_t 1277 nxge_rx_mac_init(p_nxge_t nxgep) 1278 { 1279 npi_attr_t ap; 1280 uint32_t i; 1281 uint16_t hashtab_e; 1282 p_hash_filter_t hash_filter; 1283 npi_mac_addr_t altmac_e; 1284 nxge_port_t portt; 1285 uint8_t portn; 1286 npi_handle_t handle; 1287 npi_status_t rs = NPI_SUCCESS; 1288 uint16_t *addr16p; 1289 uint16_t addr0, addr1, addr2; 1290 xmac_rx_config_t xconfig; 1291 bmac_rx_config_t bconfig; 1292 1293 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 1294 1295 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 1296 portn)); 1297 handle = nxgep->npi_handle; 1298 portt = nxgep->mac.porttype; 1299 1300 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 1301 addr0 = ntohs(addr16p[2]); 1302 addr1 = ntohs(addr16p[1]); 1303 addr2 = ntohs(addr16p[0]); 1304 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 1305 rs); 1306 1307 if (rs != NPI_SUCCESS) 1308 goto fail; 1309 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 1310 if (rs != NPI_SUCCESS) 1311 goto fail; 1312 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 1313 if (rs != NPI_SUCCESS) 1314 goto fail; 1315 1316 /* 1317 * Load the multicast hash filter bits. 1318 */ 1319 hash_filter = nxgep->hash_filter; 1320 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 1321 if (hash_filter != NULL) { 1322 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 1323 (NMCFILTER_REGS - 1) - i]; 1324 } else { 1325 hashtab_e = 0; 1326 } 1327 1328 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 1329 (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 1330 goto fail; 1331 } 1332 1333 if (portt == PORT_TYPE_XMAC) { 1334 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 1335 0)) != NPI_SUCCESS) 1336 goto fail; 1337 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 1338 1339 altmac_e.w0 = 0; 1340 altmac_e.w1 = 0; 1341 altmac_e.w2 = 0; 1342 for (i = 0; i < XMAC_MAX_ALT_ADDR_ENTRY; i++) { 1343 if ((rs = npi_mac_altaddr_entry(handle, OP_SET, portn, 1344 i, (npi_mac_addr_t *)&altmac_e)) != NPI_SUCCESS) 1345 goto fail; 1346 } 1347 1348 (void) nxge_fflp_init_hostinfo(nxgep); 1349 1350 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 1351 CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK | 1352 CFG_XMAC_RX_STRIP_CRC; 1353 1354 if (nxgep->filter.all_phys_cnt != 0) 1355 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 1356 1357 if (nxgep->filter.all_multicast_cnt != 0) 1358 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 1359 1360 xconfig |= CFG_XMAC_RX_HASH_FILTER; 1361 1362 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 1363 xconfig)) != NPI_SUCCESS) 1364 goto fail; 1365 nxgep->mac.rx_config = xconfig; 1366 1367 /* Comparison of mac unique address is always enabled on XMAC */ 1368 1369 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 1370 != NPI_SUCCESS) 1371 goto fail; 1372 } else { 1373 altmac_e.w0 = 0; 1374 altmac_e.w1 = 0; 1375 altmac_e.w2 = 0; 1376 for (i = 0; i < BMAC_MAX_ALT_ADDR_ENTRY; i++) { 1377 if ((rs = npi_mac_altaddr_entry(handle, OP_SET, portn, 1378 i, (npi_mac_addr_t *)&altmac_e)) != NPI_SUCCESS) 1379 goto fail; 1380 } 1381 1382 (void) nxge_fflp_init_hostinfo(nxgep); 1383 1384 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 1385 0) != NPI_SUCCESS) 1386 goto fail; 1387 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 1388 1389 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX | 1390 CFG_BMAC_RX_STRIP_CRC; 1391 1392 if (nxgep->filter.all_phys_cnt != 0) 1393 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 1394 1395 if (nxgep->filter.all_multicast_cnt != 0) 1396 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 1397 1398 bconfig |= CFG_BMAC_RX_HASH_FILTER; 1399 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 1400 bconfig)) != NPI_SUCCESS) 1401 goto fail; 1402 nxgep->mac.rx_config = bconfig; 1403 1404 /* Always enable comparison of mac unique address */ 1405 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 1406 != NPI_SUCCESS) 1407 goto fail; 1408 } 1409 1410 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 1411 portn)); 1412 1413 return (NXGE_OK); 1414 1415 fail: 1416 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1417 "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", 1418 portn)); 1419 1420 return (NXGE_ERROR | rs); 1421 } 1422 1423 /* Enable TXMAC */ 1424 1425 nxge_status_t 1426 nxge_tx_mac_enable(p_nxge_t nxgep) 1427 { 1428 npi_handle_t handle; 1429 npi_status_t rs = NPI_SUCCESS; 1430 nxge_status_t status = NXGE_OK; 1431 1432 handle = nxgep->npi_handle; 1433 1434 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 1435 nxgep->mac.portnum)); 1436 1437 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 1438 goto fail; 1439 1440 /* based on speed */ 1441 nxgep->msg_min = ETHERMIN; 1442 1443 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1444 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 1445 CFG_XMAC_TX)) != NPI_SUCCESS) 1446 goto fail; 1447 } else { 1448 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 1449 CFG_BMAC_TX)) != NPI_SUCCESS) 1450 goto fail; 1451 } 1452 1453 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 1454 nxgep->mac.portnum)); 1455 1456 return (NXGE_OK); 1457 fail: 1458 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1459 "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 1460 nxgep->mac.portnum)); 1461 if (rs != NPI_SUCCESS) 1462 return (NXGE_ERROR | rs); 1463 else 1464 return (status); 1465 } 1466 1467 /* Disable TXMAC */ 1468 1469 nxge_status_t 1470 nxge_tx_mac_disable(p_nxge_t nxgep) 1471 { 1472 npi_handle_t handle; 1473 npi_status_t rs = NPI_SUCCESS; 1474 1475 handle = nxgep->npi_handle; 1476 1477 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 1478 nxgep->mac.portnum)); 1479 1480 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1481 if ((rs = npi_xmac_tx_config(handle, DISABLE, 1482 nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 1483 goto fail; 1484 } else { 1485 if ((rs = npi_bmac_tx_config(handle, DISABLE, 1486 nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 1487 goto fail; 1488 } 1489 1490 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 1491 nxgep->mac.portnum)); 1492 return (NXGE_OK); 1493 fail: 1494 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1495 "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 1496 nxgep->mac.portnum)); 1497 return (NXGE_ERROR | rs); 1498 } 1499 1500 /* Enable RXMAC */ 1501 1502 nxge_status_t 1503 nxge_rx_mac_enable(p_nxge_t nxgep) 1504 { 1505 npi_handle_t handle; 1506 uint8_t portn; 1507 npi_status_t rs = NPI_SUCCESS; 1508 nxge_status_t status = NXGE_OK; 1509 1510 handle = nxgep->npi_handle; 1511 portn = nxgep->mac.portnum; 1512 1513 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 1514 portn)); 1515 1516 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 1517 goto fail; 1518 1519 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1520 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 1521 CFG_XMAC_RX)) != NPI_SUCCESS) 1522 goto fail; 1523 } else { 1524 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 1525 CFG_BMAC_RX)) != NPI_SUCCESS) 1526 goto fail; 1527 } 1528 1529 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>", 1530 portn)); 1531 1532 return (NXGE_OK); 1533 fail: 1534 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1535 "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", 1536 portn)); 1537 1538 if (rs != NPI_SUCCESS) 1539 return (NXGE_ERROR | rs); 1540 else 1541 return (status); 1542 } 1543 1544 /* Disable RXMAC */ 1545 1546 nxge_status_t 1547 nxge_rx_mac_disable(p_nxge_t nxgep) 1548 { 1549 npi_handle_t handle; 1550 uint8_t portn; 1551 npi_status_t rs = NPI_SUCCESS; 1552 1553 handle = nxgep->npi_handle; 1554 portn = nxgep->mac.portnum; 1555 1556 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 1557 portn)); 1558 1559 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1560 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 1561 CFG_XMAC_RX)) != NPI_SUCCESS) 1562 goto fail; 1563 } else { 1564 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 1565 CFG_BMAC_RX)) != NPI_SUCCESS) 1566 goto fail; 1567 } 1568 1569 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 1570 portn)); 1571 return (NXGE_OK); 1572 fail: 1573 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1574 "nxgep_rx_mac_disable: ", 1575 "Failed to disable port<%d> RxMAC", 1576 portn)); 1577 1578 return (NXGE_ERROR | rs); 1579 } 1580 1581 /* Reset TXMAC */ 1582 1583 nxge_status_t 1584 nxge_tx_mac_reset(p_nxge_t nxgep) 1585 { 1586 npi_handle_t handle; 1587 uint8_t portn; 1588 npi_status_t rs = NPI_SUCCESS; 1589 1590 handle = nxgep->npi_handle; 1591 portn = nxgep->mac.portnum; 1592 1593 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 1594 portn)); 1595 1596 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1597 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 1598 != NPI_SUCCESS) 1599 goto fail; 1600 } else { 1601 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 1602 != NPI_SUCCESS) 1603 goto fail; 1604 } 1605 1606 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 1607 portn)); 1608 1609 return (NXGE_OK); 1610 fail: 1611 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1612 "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", 1613 portn)); 1614 1615 return (NXGE_ERROR | rs); 1616 } 1617 1618 /* Reset RXMAC */ 1619 1620 nxge_status_t 1621 nxge_rx_mac_reset(p_nxge_t nxgep) 1622 { 1623 npi_handle_t handle; 1624 uint8_t portn; 1625 npi_status_t rs = NPI_SUCCESS; 1626 1627 handle = nxgep->npi_handle; 1628 portn = nxgep->mac.portnum; 1629 1630 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 1631 portn)); 1632 1633 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1634 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 1635 != NPI_SUCCESS) 1636 goto fail; 1637 } else { 1638 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 1639 != NPI_SUCCESS) 1640 goto fail; 1641 } 1642 1643 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 1644 portn)); 1645 1646 return (NXGE_OK); 1647 fail: 1648 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1649 "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", 1650 portn)); 1651 return (NXGE_ERROR | rs); 1652 } 1653 1654 1655 /* Enable/Disable MII Link Status change interrupt */ 1656 1657 nxge_status_t 1658 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 1659 { 1660 uint8_t portn; 1661 nxge_port_mode_t portmode; 1662 npi_status_t rs = NPI_SUCCESS; 1663 1664 portn = nxgep->mac.portnum; 1665 portmode = nxgep->mac.portmode; 1666 1667 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 1668 1669 if (enable == LINK_INTR_START) { 1670 if (portmode == PORT_10G_FIBER) { 1671 if ((rs = npi_xmac_xpcs_link_intr_enable( 1672 nxgep->npi_handle, 1673 portn)) != NPI_SUCCESS) 1674 goto fail; 1675 } else if (portmode == PORT_1G_FIBER) { 1676 if ((rs = npi_mac_pcs_link_intr_enable( 1677 nxgep->npi_handle, 1678 portn)) != NPI_SUCCESS) 1679 goto fail; 1680 } else if (portmode == PORT_1G_COPPER) { 1681 if ((rs = npi_mac_mif_link_intr_enable( 1682 nxgep->npi_handle, 1683 portn, MII_BMSR, BMSR_LSTATUS)) != NPI_SUCCESS) 1684 goto fail; 1685 } else 1686 goto fail; 1687 } else if (enable == LINK_INTR_STOP) { 1688 if (portmode == PORT_10G_FIBER) { 1689 if ((rs = npi_xmac_xpcs_link_intr_disable( 1690 nxgep->npi_handle, 1691 portn)) != NPI_SUCCESS) 1692 goto fail; 1693 } else if (portmode == PORT_1G_FIBER) { 1694 if ((rs = npi_mac_pcs_link_intr_disable( 1695 nxgep->npi_handle, 1696 portn)) != NPI_SUCCESS) 1697 goto fail; 1698 } else if (portmode == PORT_1G_COPPER) { 1699 if ((rs = npi_mac_mif_link_intr_disable( 1700 nxgep->npi_handle, 1701 portn)) != NPI_SUCCESS) 1702 goto fail; 1703 } else 1704 goto fail; 1705 } 1706 1707 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 1708 1709 return (NXGE_OK); 1710 fail: 1711 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1712 "nxge_link_intr: Failed to set port<%d> mif intr mode", 1713 portn)); 1714 1715 return (NXGE_ERROR | rs); 1716 } 1717 1718 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 1719 1720 nxge_status_t 1721 nxge_mii_xcvr_init(p_nxge_t nxgep) 1722 { 1723 p_nxge_param_t param_arr; 1724 p_nxge_stats_t statsp; 1725 uint8_t xcvr_portn; 1726 p_mii_regs_t mii_regs; 1727 mii_bmcr_t bmcr; 1728 mii_bmsr_t bmsr; 1729 mii_anar_t anar; 1730 mii_gcr_t gcr; 1731 mii_esr_t esr; 1732 mii_aux_ctl_t bcm5464r_aux; 1733 int status = NXGE_OK; 1734 1735 uint_t delay; 1736 1737 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 1738 1739 param_arr = nxgep->param_arr; 1740 statsp = nxgep->statsp; 1741 xcvr_portn = statsp->mac_stats.xcvr_portn; 1742 1743 mii_regs = NULL; 1744 1745 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1746 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 1747 1748 /* 1749 * Reset the transceiver. 1750 */ 1751 delay = 0; 1752 bmcr.value = 0; 1753 bmcr.bits.reset = 1; 1754 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1755 (uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 1756 goto fail; 1757 do { 1758 drv_usecwait(500); 1759 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1760 (uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value)) 1761 != NXGE_OK) 1762 goto fail; 1763 delay++; 1764 } while ((bmcr.bits.reset) && (delay < 1000)); 1765 if (delay == 1000) { 1766 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 1767 goto fail; 1768 } 1769 1770 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1771 (uint8_t)(uint64_t)(&mii_regs->bmsr), 1772 &bmsr.value)) != NXGE_OK) 1773 goto fail; 1774 1775 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 1776 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 1777 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 1778 param_arr[param_anar_100hdx].value = 0; 1779 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 1780 param_arr[param_anar_10hdx].value = 0; 1781 1782 /* 1783 * Initialise the xcvr statistics. 1784 */ 1785 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 1786 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 1787 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 1788 statsp->mac_stats.cap_100hdx = 0; 1789 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 1790 statsp->mac_stats.cap_10hdx = 0; 1791 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 1792 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 1793 1794 /* 1795 * Initialise the xcvr advertised capability statistics. 1796 */ 1797 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 1798 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 1799 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 1800 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 1801 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 1802 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 1803 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 1804 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 1805 statsp->mac_stats.adv_cap_asmpause = 1806 param_arr[param_anar_asmpause].value; 1807 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 1808 1809 1810 /* 1811 * Check for extended status just in case we're 1812 * running a Gigibit phy. 1813 */ 1814 if (bmsr.bits.extend_status) { 1815 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1816 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) 1817 != NXGE_OK) 1818 goto fail; 1819 param_arr[param_anar_1000fdx].value &= 1820 esr.bits.link_1000fdx; 1821 param_arr[param_anar_1000hdx].value = 0; 1822 1823 statsp->mac_stats.cap_1000fdx = 1824 (esr.bits.link_1000Xfdx || 1825 esr.bits.link_1000fdx); 1826 statsp->mac_stats.cap_1000hdx = 0; 1827 } else { 1828 param_arr[param_anar_1000fdx].value = 0; 1829 param_arr[param_anar_1000hdx].value = 0; 1830 } 1831 1832 /* 1833 * Initialize 1G Statistics once the capability is established. 1834 */ 1835 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 1836 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 1837 1838 /* 1839 * Initialise the link statistics. 1840 */ 1841 statsp->mac_stats.link_T4 = 0; 1842 statsp->mac_stats.link_asmpause = 0; 1843 statsp->mac_stats.link_pause = 0; 1844 statsp->mac_stats.link_speed = 0; 1845 statsp->mac_stats.link_duplex = 0; 1846 statsp->mac_stats.link_up = 0; 1847 1848 /* 1849 * Switch off Auto-negotiation, 100M and full duplex. 1850 */ 1851 bmcr.value = 0; 1852 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1853 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 1854 goto fail; 1855 1856 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 1857 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 1858 bmcr.bits.loopback = 1; 1859 bmcr.bits.enable_autoneg = 0; 1860 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 1861 bmcr.bits.speed_1000_sel = 1; 1862 bmcr.bits.duplex_mode = 1; 1863 param_arr[param_autoneg].value = 0; 1864 } else { 1865 bmcr.bits.loopback = 0; 1866 } 1867 1868 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 1869 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 1870 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 1871 param_arr[param_autoneg].value = 0; 1872 bcm5464r_aux.value = 0; 1873 bcm5464r_aux.bits.ext_lb = 1; 1874 bcm5464r_aux.bits.write_1 = 1; 1875 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1876 BCM5464R_AUX_CTL, bcm5464r_aux.value)) 1877 != NXGE_OK) 1878 goto fail; 1879 } 1880 1881 if (param_arr[param_autoneg].value) { 1882 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1883 "Restarting Auto-negotiation.")); 1884 /* 1885 * Setup our Auto-negotiation advertisement register. 1886 */ 1887 anar.value = 0; 1888 anar.bits.selector = 1; 1889 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 1890 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 1891 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 1892 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 1893 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 1894 anar.bits.cap_asmpause = 0; 1895 anar.bits.cap_pause = 0; 1896 if (param_arr[param_anar_1000fdx].value || 1897 param_arr[param_anar_100fdx].value || 1898 param_arr[param_anar_10fdx].value) { 1899 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 1900 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 1901 } 1902 1903 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1904 (uint8_t)(uint64_t)(&mii_regs->anar), anar.value)) 1905 != NXGE_OK) 1906 goto fail; 1907 if (bmsr.bits.extend_status) { 1908 gcr.value = 0; 1909 gcr.bits.ms_mode_en = 1910 param_arr[param_master_cfg_enable].value; 1911 gcr.bits.master = 1912 param_arr[param_master_cfg_value].value; 1913 gcr.bits.link_1000fdx = 1914 param_arr[param_anar_1000fdx].value; 1915 gcr.bits.link_1000hdx = 1916 param_arr[param_anar_1000hdx].value; 1917 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1918 (uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value)) 1919 != NXGE_OK) 1920 goto fail; 1921 } 1922 1923 bmcr.bits.enable_autoneg = 1; 1924 bmcr.bits.restart_autoneg = 1; 1925 1926 } else { 1927 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 1928 bmcr.bits.speed_1000_sel = 1929 param_arr[param_anar_1000fdx].value | 1930 param_arr[param_anar_1000hdx].value; 1931 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 1932 (param_arr[param_anar_100fdx].value | 1933 param_arr[param_anar_100hdx].value); 1934 if (bmcr.bits.speed_1000_sel) { 1935 statsp->mac_stats.link_speed = 1000; 1936 gcr.value = 0; 1937 gcr.bits.ms_mode_en = 1938 param_arr[param_master_cfg_enable].value; 1939 gcr.bits.master = 1940 param_arr[param_master_cfg_value].value; 1941 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1942 (uint8_t)(uint64_t)(&mii_regs->gcr), 1943 gcr.value)) 1944 != NXGE_OK) 1945 goto fail; 1946 if (param_arr[param_anar_1000fdx].value) { 1947 bmcr.bits.duplex_mode = 1; 1948 statsp->mac_stats.link_duplex = 2; 1949 } else 1950 statsp->mac_stats.link_duplex = 1; 1951 } else if (bmcr.bits.speed_sel) { 1952 statsp->mac_stats.link_speed = 100; 1953 if (param_arr[param_anar_100fdx].value) { 1954 bmcr.bits.duplex_mode = 1; 1955 statsp->mac_stats.link_duplex = 2; 1956 } else 1957 statsp->mac_stats.link_duplex = 1; 1958 } else { 1959 statsp->mac_stats.link_speed = 10; 1960 if (param_arr[param_anar_10fdx].value) { 1961 bmcr.bits.duplex_mode = 1; 1962 statsp->mac_stats.link_duplex = 2; 1963 } else 1964 statsp->mac_stats.link_duplex = 1; 1965 } 1966 if (statsp->mac_stats.link_duplex != 1) { 1967 statsp->mac_stats.link_asmpause = 1968 statsp->mac_stats.cap_asmpause; 1969 statsp->mac_stats.link_pause = 1970 statsp->mac_stats.cap_pause; 1971 } 1972 1973 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 1974 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 1975 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 1976 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 1977 /* BCM5464R 1000mbps external loopback mode */ 1978 gcr.value = 0; 1979 gcr.bits.ms_mode_en = 1; 1980 gcr.bits.master = 1; 1981 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1982 (uint8_t)(uint64_t)(&mii_regs->gcr), 1983 gcr.value)) 1984 != NXGE_OK) 1985 goto fail; 1986 bmcr.value = 0; 1987 bmcr.bits.speed_1000_sel = 1; 1988 statsp->mac_stats.link_speed = 1000; 1989 } else if (statsp->port_stats.lb_mode 1990 == nxge_lb_ext100) { 1991 /* BCM5464R 100mbps external loopback mode */ 1992 bmcr.value = 0; 1993 bmcr.bits.speed_sel = 1; 1994 bmcr.bits.duplex_mode = 1; 1995 statsp->mac_stats.link_speed = 100; 1996 } else if (statsp->port_stats.lb_mode 1997 == nxge_lb_ext10) { 1998 /* BCM5464R 10mbps external loopback mode */ 1999 bmcr.value = 0; 2000 bmcr.bits.duplex_mode = 1; 2001 statsp->mac_stats.link_speed = 10; 2002 } 2003 } 2004 } 2005 2006 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2007 (uint8_t)(uint64_t)(&mii_regs->bmcr), 2008 bmcr.value)) != NXGE_OK) 2009 goto fail; 2010 2011 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2012 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 2013 goto fail; 2014 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 2015 2016 /* 2017 * Initialize the xcvr status kept in the context structure. 2018 */ 2019 nxgep->soft_bmsr.value = 0; 2020 2021 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2022 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2023 &nxgep->bmsr.value)) != NXGE_OK) 2024 goto fail; 2025 2026 statsp->mac_stats.xcvr_inits++; 2027 nxgep->bmsr.value = 0; 2028 2029 fail: 2030 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2031 "<== nxge_mii_xcvr_init status 0x%x", status)); 2032 return (status); 2033 } 2034 2035 /* Read from a MII compliant register */ 2036 2037 nxge_status_t 2038 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 2039 uint16_t *value) 2040 { 2041 npi_status_t rs = NPI_SUCCESS; 2042 2043 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 2044 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 2045 2046 MUTEX_ENTER(&nxge_mii_lock); 2047 2048 if (nxgep->mac.portmode == PORT_1G_COPPER) { 2049 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 2050 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2051 goto fail; 2052 } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 2053 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 2054 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2055 goto fail; 2056 } else 2057 goto fail; 2058 2059 MUTEX_EXIT(&nxge_mii_lock); 2060 2061 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 2062 "xcvr_reg<%d> value=0x%x", 2063 xcvr_portn, xcvr_reg, *value)); 2064 return (NXGE_OK); 2065 fail: 2066 MUTEX_EXIT(&nxge_mii_lock); 2067 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2068 "nxge_mii_read: Failed to read mii on xcvr %d", 2069 xcvr_portn)); 2070 2071 return (NXGE_ERROR | rs); 2072 } 2073 2074 /* Write to a MII compliant Register */ 2075 2076 nxge_status_t 2077 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 2078 uint16_t value) 2079 { 2080 npi_status_t rs = NPI_SUCCESS; 2081 2082 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 2083 "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, 2084 value)); 2085 2086 MUTEX_ENTER(&nxge_mii_lock); 2087 2088 if (nxgep->mac.portmode == PORT_1G_COPPER) { 2089 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 2090 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2091 goto fail; 2092 } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 2093 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 2094 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2095 goto fail; 2096 } else 2097 goto fail; 2098 2099 MUTEX_EXIT(&nxge_mii_lock); 2100 2101 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 2102 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 2103 return (NXGE_OK); 2104 fail: 2105 MUTEX_EXIT(&nxge_mii_lock); 2106 2107 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2108 "nxge_mii_write: Failed to write mii on xcvr %d", 2109 xcvr_portn)); 2110 2111 return (NXGE_ERROR | rs); 2112 } 2113 2114 /* Perform read from Clause45 serdes / transceiver device */ 2115 2116 nxge_status_t 2117 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 2118 uint16_t xcvr_reg, uint16_t *value) 2119 { 2120 npi_status_t rs = NPI_SUCCESS; 2121 2122 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 2123 xcvr_portn)); 2124 2125 MUTEX_ENTER(&nxge_mdio_lock); 2126 2127 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 2128 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 2129 goto fail; 2130 2131 MUTEX_EXIT(&nxge_mdio_lock); 2132 2133 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 2134 xcvr_portn)); 2135 return (NXGE_OK); 2136 fail: 2137 MUTEX_EXIT(&nxge_mdio_lock); 2138 2139 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2140 "nxge_mdio_read: Failed to read mdio on xcvr %d", 2141 xcvr_portn)); 2142 2143 return (NXGE_ERROR | rs); 2144 } 2145 2146 /* Perform write to Clause45 serdes / transceiver device */ 2147 2148 nxge_status_t 2149 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 2150 uint16_t xcvr_reg, uint16_t value) 2151 { 2152 npi_status_t rs = NPI_SUCCESS; 2153 2154 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 2155 xcvr_portn)); 2156 2157 MUTEX_ENTER(&nxge_mdio_lock); 2158 2159 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 2160 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 2161 goto fail; 2162 2163 MUTEX_EXIT(&nxge_mdio_lock); 2164 2165 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 2166 xcvr_portn)); 2167 return (NXGE_OK); 2168 fail: 2169 MUTEX_EXIT(&nxge_mdio_lock); 2170 2171 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2172 "nxge_mdio_write: Failed to write mdio on xcvr %d", 2173 xcvr_portn)); 2174 2175 return (NXGE_ERROR | rs); 2176 } 2177 2178 2179 /* Check MII to see if there is any link status change */ 2180 2181 nxge_status_t 2182 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints) 2183 { 2184 p_nxge_param_t param_arr; 2185 p_nxge_stats_t statsp; 2186 p_mii_regs_t mii_regs; 2187 p_mii_bmsr_t soft_bmsr; 2188 mii_anar_t anar; 2189 mii_anlpar_t anlpar; 2190 mii_anar_t an_common; 2191 mii_aner_t aner; 2192 mii_gsr_t gsr; 2193 nxge_status_t status = NXGE_OK; 2194 2195 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 2196 2197 mii_regs = NULL; 2198 param_arr = nxgep->param_arr; 2199 statsp = nxgep->statsp; 2200 soft_bmsr = &nxgep->soft_bmsr; 2201 2202 if (bmsr_ints.bits.link_status) { 2203 if (bmsr.bits.link_status) { 2204 soft_bmsr->bits.link_status = 1; 2205 } else { 2206 statsp->mac_stats.link_up = 0; 2207 soft_bmsr->bits.link_status = 0; 2208 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2209 "Link down cable problem")); 2210 nxge_link_is_down(nxgep); 2211 } 2212 } 2213 2214 if (param_arr[param_autoneg].value) { 2215 if (bmsr_ints.bits.auto_neg_complete) { 2216 if (bmsr.bits.auto_neg_complete) 2217 soft_bmsr->bits.auto_neg_complete = 1; 2218 else 2219 soft_bmsr->bits.auto_neg_complete = 0; 2220 } 2221 if (soft_bmsr->bits.link_status == 0) { 2222 statsp->mac_stats.link_T4 = 0; 2223 statsp->mac_stats.link_speed = 0; 2224 statsp->mac_stats.link_duplex = 0; 2225 statsp->mac_stats.link_asmpause = 0; 2226 statsp->mac_stats.link_pause = 0; 2227 statsp->mac_stats.lp_cap_autoneg = 0; 2228 statsp->mac_stats.lp_cap_100T4 = 0; 2229 statsp->mac_stats.lp_cap_1000fdx = 0; 2230 statsp->mac_stats.lp_cap_1000hdx = 0; 2231 statsp->mac_stats.lp_cap_100fdx = 0; 2232 statsp->mac_stats.lp_cap_100hdx = 0; 2233 statsp->mac_stats.lp_cap_10fdx = 0; 2234 statsp->mac_stats.lp_cap_10hdx = 0; 2235 statsp->mac_stats.lp_cap_10gfdx = 0; 2236 statsp->mac_stats.lp_cap_10ghdx = 0; 2237 statsp->mac_stats.lp_cap_asmpause = 0; 2238 statsp->mac_stats.lp_cap_pause = 0; 2239 } 2240 } else 2241 soft_bmsr->bits.auto_neg_complete = 1; 2242 2243 if ((bmsr_ints.bits.link_status || 2244 bmsr_ints.bits.auto_neg_complete) && 2245 soft_bmsr->bits.link_status && 2246 soft_bmsr->bits.auto_neg_complete) { 2247 statsp->mac_stats.link_up = 1; 2248 if (param_arr[param_autoneg].value) { 2249 if ((status = nxge_mii_read(nxgep, 2250 statsp->mac_stats.xcvr_portn, 2251 (uint8_t)(uint64_t)(&mii_regs->anar), 2252 &anar.value)) != NXGE_OK) 2253 goto fail; 2254 if ((status = nxge_mii_read(nxgep, 2255 statsp->mac_stats.xcvr_portn, 2256 (uint8_t)(uint64_t)(&mii_regs->anlpar), 2257 &anlpar.value)) != NXGE_OK) 2258 goto fail; 2259 if ((status = nxge_mii_read(nxgep, 2260 statsp->mac_stats.xcvr_portn, 2261 (uint8_t)(uint64_t)(&mii_regs->aner), 2262 &aner.value)) != NXGE_OK) 2263 goto fail; 2264 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 2265 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 2266 statsp->mac_stats.lp_cap_100fdx = 2267 anlpar.bits.cap_100fdx; 2268 statsp->mac_stats.lp_cap_100hdx = 2269 anlpar.bits.cap_100hdx; 2270 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 2271 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 2272 statsp->mac_stats.lp_cap_asmpause = 2273 anlpar.bits.cap_asmpause; 2274 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 2275 an_common.value = anar.value & anlpar.value; 2276 if (param_arr[param_anar_1000fdx].value || 2277 param_arr[param_anar_1000hdx].value) { 2278 if ((status = nxge_mii_read(nxgep, 2279 statsp->mac_stats.xcvr_portn, 2280 (uint8_t)(uint64_t)(&mii_regs->gsr), 2281 &gsr.value)) 2282 != NXGE_OK) 2283 goto fail; 2284 statsp->mac_stats.lp_cap_1000fdx = 2285 gsr.bits.link_1000fdx; 2286 statsp->mac_stats.lp_cap_1000hdx = 2287 gsr.bits.link_1000hdx; 2288 if (param_arr[param_anar_1000fdx].value && 2289 gsr.bits.link_1000fdx) { 2290 statsp->mac_stats.link_speed = 1000; 2291 statsp->mac_stats.link_duplex = 2; 2292 } else if ( 2293 param_arr[param_anar_1000hdx].value && 2294 gsr.bits.link_1000hdx) { 2295 statsp->mac_stats.link_speed = 1000; 2296 statsp->mac_stats.link_duplex = 1; 2297 } 2298 } 2299 if ((an_common.value != 0) && 2300 !(statsp->mac_stats.link_speed)) { 2301 if (an_common.bits.cap_100T4) { 2302 statsp->mac_stats.link_T4 = 1; 2303 statsp->mac_stats.link_speed = 100; 2304 statsp->mac_stats.link_duplex = 1; 2305 } else if (an_common.bits.cap_100fdx) { 2306 statsp->mac_stats.link_speed = 100; 2307 statsp->mac_stats.link_duplex = 2; 2308 } else if (an_common.bits.cap_100hdx) { 2309 statsp->mac_stats.link_speed = 100; 2310 statsp->mac_stats.link_duplex = 1; 2311 } else if (an_common.bits.cap_10fdx) { 2312 statsp->mac_stats.link_speed = 10; 2313 statsp->mac_stats.link_duplex = 2; 2314 } else if (an_common.bits.cap_10hdx) { 2315 statsp->mac_stats.link_speed = 10; 2316 statsp->mac_stats.link_duplex = 1; 2317 } else { 2318 goto fail; 2319 } 2320 } 2321 if (statsp->mac_stats.link_duplex != 1) { 2322 statsp->mac_stats.link_asmpause = 2323 an_common.bits.cap_asmpause; 2324 if (statsp->mac_stats.link_asmpause) 2325 if ((statsp->mac_stats.cap_pause == 0) && 2326 (statsp->mac_stats.lp_cap_pause 2327 == 1)) 2328 statsp->mac_stats.link_pause 2329 = 0; 2330 else 2331 statsp->mac_stats.link_pause 2332 = 1; 2333 else 2334 statsp->mac_stats.link_pause = 2335 an_common.bits.cap_pause; 2336 } 2337 } 2338 nxge_link_is_up(nxgep); 2339 } 2340 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 2341 return (NXGE_OK); 2342 fail: 2343 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2344 "nxge_mii_check: Unable to check MII")); 2345 return (status); 2346 } 2347 2348 /* Add a multicast address entry into the HW hash table */ 2349 2350 nxge_status_t 2351 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 2352 { 2353 uint32_t mchash; 2354 p_hash_filter_t hash_filter; 2355 uint16_t hash_bit; 2356 boolean_t rx_init = B_FALSE; 2357 uint_t j; 2358 nxge_status_t status = NXGE_OK; 2359 2360 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 2361 2362 RW_ENTER_WRITER(&nxgep->filter_lock); 2363 mchash = crc32_mchash(addrp); 2364 if (nxgep->hash_filter == NULL) { 2365 NXGE_DEBUG_MSG((NULL, STR_CTL, 2366 "Allocating hash filter storage.")); 2367 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 2368 KM_SLEEP); 2369 } 2370 hash_filter = nxgep->hash_filter; 2371 j = mchash / HASH_REG_WIDTH; 2372 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 2373 hash_filter->hash_filter_regs[j] |= hash_bit; 2374 hash_filter->hash_bit_ref_cnt[mchash]++; 2375 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 2376 hash_filter->hash_ref_cnt++; 2377 rx_init = B_TRUE; 2378 } 2379 if (rx_init) { 2380 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 2381 goto fail; 2382 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 2383 goto fail; 2384 } 2385 2386 RW_EXIT(&nxgep->filter_lock); 2387 2388 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 2389 2390 return (NXGE_OK); 2391 fail: 2392 RW_EXIT(&nxgep->filter_lock); 2393 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 2394 "Unable to add multicast address")); 2395 return (status); 2396 } 2397 2398 /* Remove a multicast address entry from the HW hash table */ 2399 2400 nxge_status_t 2401 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 2402 { 2403 uint32_t mchash; 2404 p_hash_filter_t hash_filter; 2405 uint16_t hash_bit; 2406 boolean_t rx_init = B_FALSE; 2407 uint_t j; 2408 nxge_status_t status = NXGE_OK; 2409 2410 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 2411 RW_ENTER_WRITER(&nxgep->filter_lock); 2412 mchash = crc32_mchash(addrp); 2413 if (nxgep->hash_filter == NULL) { 2414 NXGE_DEBUG_MSG((NULL, STR_CTL, 2415 "Hash filter already de_allocated.")); 2416 RW_EXIT(&nxgep->filter_lock); 2417 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 2418 return (NXGE_OK); 2419 } 2420 hash_filter = nxgep->hash_filter; 2421 hash_filter->hash_bit_ref_cnt[mchash]--; 2422 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 2423 j = mchash / HASH_REG_WIDTH; 2424 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 2425 hash_filter->hash_filter_regs[j] &= ~hash_bit; 2426 hash_filter->hash_ref_cnt--; 2427 rx_init = B_TRUE; 2428 } 2429 if (hash_filter->hash_ref_cnt == 0) { 2430 NXGE_DEBUG_MSG((NULL, STR_CTL, 2431 "De-allocating hash filter storage.")); 2432 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 2433 nxgep->hash_filter = NULL; 2434 } 2435 2436 if (rx_init) { 2437 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 2438 goto fail; 2439 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 2440 goto fail; 2441 } 2442 RW_EXIT(&nxgep->filter_lock); 2443 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 2444 2445 return (NXGE_OK); 2446 fail: 2447 RW_EXIT(&nxgep->filter_lock); 2448 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 2449 "Unable to remove multicast address")); 2450 2451 return (status); 2452 } 2453 2454 /* Set MAC address into MAC address HW registers */ 2455 2456 nxge_status_t 2457 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 2458 { 2459 nxge_status_t status = NXGE_OK; 2460 2461 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 2462 2463 MUTEX_ENTER(&nxgep->ouraddr_lock); 2464 /* 2465 * Exit if the address is same as ouraddr or multicast or broadcast 2466 */ 2467 if (((addrp->ether_addr_octet[0] & 01) == 1) || 2468 (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 2469 (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 2470 goto nxge_set_mac_addr_exit; 2471 } 2472 nxgep->ouraddr = *addrp; 2473 /* 2474 * Set new interface local address and re-init device. 2475 * This is destructive to any other streams attached 2476 * to this device. 2477 */ 2478 RW_ENTER_WRITER(&nxgep->filter_lock); 2479 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 2480 goto fail; 2481 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 2482 goto fail; 2483 2484 RW_EXIT(&nxgep->filter_lock); 2485 MUTEX_EXIT(&nxgep->ouraddr_lock); 2486 goto nxge_set_mac_addr_end; 2487 nxge_set_mac_addr_exit: 2488 MUTEX_EXIT(&nxgep->ouraddr_lock); 2489 nxge_set_mac_addr_end: 2490 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 2491 2492 return (NXGE_OK); 2493 fail: 2494 MUTEX_EXIT(&nxgep->ouraddr_lock); 2495 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 2496 "Unable to set mac address")); 2497 return (status); 2498 } 2499 2500 /* Check status of MII (MIF or PCS) link */ 2501 2502 nxge_status_t 2503 nxge_check_mii_link(p_nxge_t nxgep) 2504 { 2505 mii_bmsr_t bmsr_ints, bmsr_data; 2506 mii_anlpar_t anlpar; 2507 mii_gsr_t gsr; 2508 p_mii_regs_t mii_regs; 2509 ddi_devstate_t dev_stat; 2510 nxge_status_t status = NXGE_OK; 2511 uint8_t portn; 2512 2513 portn = nxgep->mac.portnum; 2514 2515 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 2516 portn)); 2517 2518 mii_regs = NULL; 2519 2520 RW_ENTER_WRITER(&nxgep->filter_lock); 2521 2522 dev_stat = FM_GET_DEVSTATE(nxgep); 2523 2524 if (dev_stat < DDI_DEVSTATE_DEGRADED) { 2525 goto nxge_check_mii_link_exit; 2526 } 2527 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 2528 goto nxge_check_mii_link_exit; 2529 2530 if ((status = nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 2531 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2532 &bmsr_data.value)) != NXGE_OK) 2533 goto fail; 2534 2535 if (nxgep->param_arr[param_autoneg].value) { 2536 if ((status = nxge_mii_read(nxgep, 2537 nxgep->statsp->mac_stats.xcvr_portn, 2538 (uint8_t)(uint64_t)(&mii_regs->gsr), 2539 &gsr.value)) != NXGE_OK) 2540 goto fail; 2541 if ((status = nxge_mii_read(nxgep, 2542 nxgep->statsp->mac_stats.xcvr_portn, 2543 (uint8_t)(uint64_t)(&mii_regs->anlpar), 2544 &anlpar.value)) != NXGE_OK) 2545 goto fail; 2546 if (nxgep->statsp->mac_stats.link_up && 2547 ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 2548 gsr.bits.link_1000fdx) || 2549 (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 2550 gsr.bits.link_1000hdx) || 2551 (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 2552 anlpar.bits.cap_100T4) || 2553 (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 2554 anlpar.bits.cap_100fdx) || 2555 (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 2556 anlpar.bits.cap_100hdx) || 2557 (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 2558 anlpar.bits.cap_10fdx) || 2559 (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 2560 anlpar.bits.cap_10hdx))) { 2561 bmsr_data.bits.link_status = 0; 2562 } 2563 } 2564 2565 /* Workaround for link down issue */ 2566 if (bmsr_data.value == 0) { 2567 cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 2568 goto nxge_check_mii_link_exit; 2569 } 2570 2571 bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 2572 nxgep->bmsr.value = bmsr_data.value; 2573 if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints)) != NXGE_OK) 2574 goto fail; 2575 if (FM_CHECK_DEV_HANDLE(nxgep) != DDI_SUCCESS) { 2576 FM_REPORT_FAULT(nxgep, SERVICE_LOST, DEVICE_FAULT, 2577 "register access fault detected in nxge_check_mii_link"); 2578 } 2579 2580 nxge_check_mii_link_exit: 2581 RW_EXIT(&nxgep->filter_lock); 2582 2583 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 2584 2585 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 2586 portn)); 2587 return (NXGE_OK); 2588 2589 fail: 2590 RW_EXIT(&nxgep->filter_lock); 2591 2592 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 2593 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2594 "nxge_check_mii_link: Failed to check link port<%d>", 2595 portn)); 2596 return (status); 2597 } 2598 2599 2600 /*ARGSUSED*/ 2601 nxge_status_t 2602 nxge_check_10g_link(p_nxge_t nxgep) 2603 { 2604 uint8_t portn; 2605 ddi_devstate_t dev_stat; 2606 nxge_status_t status = NXGE_OK; 2607 boolean_t link_up; 2608 2609 portn = nxgep->mac.portnum; 2610 2611 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 2612 portn)); 2613 2614 dev_stat = FM_GET_DEVSTATE(nxgep); 2615 2616 if (dev_stat < DDI_DEVSTATE_DEGRADED) { 2617 goto fail; 2618 } 2619 2620 status = nxge_check_bcm8704_link(nxgep, &link_up); 2621 2622 if (status != NXGE_OK) 2623 goto fail; 2624 2625 if (link_up) { 2626 if (nxgep->statsp->mac_stats.link_up == 0) { 2627 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 2628 goto fail; 2629 nxgep->statsp->mac_stats.link_up = 1; 2630 nxgep->statsp->mac_stats.link_speed = 10000; 2631 nxgep->statsp->mac_stats.link_duplex = 2; 2632 2633 nxge_link_is_up(nxgep); 2634 } 2635 } else { 2636 if (nxgep->statsp->mac_stats.link_up == 1) { 2637 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 2638 goto fail; 2639 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2640 "Link down cable problem")); 2641 nxgep->statsp->mac_stats.link_up = 0; 2642 nxgep->statsp->mac_stats.link_speed = 0; 2643 nxgep->statsp->mac_stats.link_duplex = 0; 2644 2645 nxge_link_is_down(nxgep); 2646 2647 } 2648 } 2649 2650 if (FM_CHECK_DEV_HANDLE(nxgep) != DDI_SUCCESS) { 2651 FM_REPORT_FAULT(nxgep, SERVICE_LOST, DEVICE_FAULT, 2652 "register access fault detected in nxge_check_mii_link"); 2653 } 2654 2655 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 2656 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 2657 portn)); 2658 return (NXGE_OK); 2659 2660 fail: 2661 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2662 "nxge_check_10g_link: Failed to check link port<%d>", 2663 portn)); 2664 return (status); 2665 } 2666 2667 2668 /* Declare link down */ 2669 2670 void 2671 nxge_link_is_down(p_nxge_t nxgep) 2672 { 2673 p_nxge_stats_t statsp; 2674 char link_stat_msg[64]; 2675 2676 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 2677 2678 statsp = nxgep->statsp; 2679 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link down", 2680 statsp->mac_stats.xcvr_portn); 2681 2682 if (nxge_no_msg == 0) { 2683 FM_REPORT_FAULT(nxgep, SERVICE_DEGRADED, EXTERNAL_FAULT, 2684 link_stat_msg); 2685 } 2686 2687 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 2688 2689 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 2690 } 2691 2692 /* Declare link up */ 2693 2694 void 2695 nxge_link_is_up(p_nxge_t nxgep) 2696 { 2697 p_nxge_stats_t statsp; 2698 char link_stat_msg[64]; 2699 uint32_t val; 2700 2701 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 2702 2703 statsp = nxgep->statsp; 2704 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link up %d Mbps ", 2705 statsp->mac_stats.xcvr_portn, 2706 statsp->mac_stats.link_speed); 2707 2708 if (statsp->mac_stats.link_T4) 2709 (void) strcat(link_stat_msg, "T4"); 2710 else if (statsp->mac_stats.link_duplex == 2) 2711 (void) strcat(link_stat_msg, "full duplex"); 2712 else 2713 (void) strcat(link_stat_msg, "half duplex"); 2714 2715 (void) nxge_xif_init(nxgep); 2716 2717 if (nxge_no_msg == 0) { 2718 FM_REPORT_FAULT(nxgep, SERVICE_RESTORED, EXTERNAL_FAULT, 2719 link_stat_msg); 2720 } 2721 2722 /* Clean up symbol errors incurred during link transition */ 2723 if (nxgep->mac.portmode == PORT_10G_FIBER) { 2724 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 2725 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 2726 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 2727 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 2728 } 2729 2730 mac_link_update(nxgep->mach, LINK_STATE_UP); 2731 2732 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 2733 } 2734 2735 /* 2736 * Calculate the bit in the multicast address filter 2737 * that selects the given * address. 2738 * Note: For GEM, the last 8-bits are used. 2739 */ 2740 uint32_t 2741 crc32_mchash(p_ether_addr_t addr) 2742 { 2743 uint8_t *cp; 2744 uint32_t crc; 2745 uint32_t c; 2746 int byte; 2747 int bit; 2748 2749 cp = (uint8_t *)addr; 2750 crc = (uint32_t)0xffffffff; 2751 for (byte = 0; byte < 6; byte++) { 2752 c = (uint32_t)cp[byte]; 2753 for (bit = 0; bit < 8; bit++) { 2754 if ((c & 0x1) ^ (crc & 0x1)) 2755 crc = (crc >> 1)^0xedb88320; 2756 else 2757 crc = (crc >> 1); 2758 c >>= 1; 2759 } 2760 } 2761 return ((~crc) >> (32 - HASH_BITS)); 2762 } 2763 2764 /* Reset serdes */ 2765 2766 nxge_status_t 2767 nxge_serdes_reset(p_nxge_t nxgep) 2768 { 2769 npi_handle_t handle; 2770 2771 handle = nxgep->npi_handle; 2772 2773 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 2774 drv_usecwait(500); 2775 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 2776 2777 return (NXGE_OK); 2778 } 2779 2780 /* Monitor link status using interrupt or polling */ 2781 2782 nxge_status_t 2783 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 2784 { 2785 nxge_status_t status = NXGE_OK; 2786 2787 /* 2788 * Make sure that we don't check the link if this happen to 2789 * be not port0 or 1 and it is not BMAC port. 2790 */ 2791 if ((nxgep->mac.portmode == PORT_10G_FIBER) && (nxgep->mac.portnum > 1)) 2792 return (NXGE_OK); 2793 2794 if (nxgep->statsp == NULL) { 2795 /* stats has not been allocated. */ 2796 return (NXGE_OK); 2797 } 2798 /* Don't check link if we're not in internal loopback mode */ 2799 if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal) 2800 return (NXGE_OK); 2801 2802 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2803 "==> nxge_link_monitor port<%d> enable=%d", 2804 nxgep->mac.portnum, enable)); 2805 if (enable == LINK_MONITOR_START) { 2806 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 2807 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 2808 != NXGE_OK) 2809 goto fail; 2810 } else { 2811 switch (nxgep->mac.portmode) { 2812 case PORT_10G_FIBER: 2813 nxgep->nxge_link_poll_timerid = timeout( 2814 (fptrv_t)nxge_check_10g_link, 2815 nxgep, 2816 drv_usectohz(1000 * 1000)); 2817 break; 2818 2819 case PORT_1G_COPPER: 2820 case PORT_1G_FIBER: 2821 nxgep->nxge_link_poll_timerid = timeout( 2822 (fptrv_t)nxge_check_mii_link, 2823 nxgep, 2824 drv_usectohz(1000 * 1000)); 2825 break; 2826 default: 2827 ; 2828 } 2829 } 2830 } else { 2831 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 2832 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 2833 != NXGE_OK) 2834 goto fail; 2835 } else { 2836 if (nxgep->nxge_link_poll_timerid != 0) { 2837 (void) untimeout(nxgep->nxge_link_poll_timerid); 2838 nxgep->nxge_link_poll_timerid = 0; 2839 } 2840 } 2841 } 2842 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2843 "<== nxge_link_monitor port<%d> enable=%d", 2844 nxgep->mac.portnum, enable)); 2845 return (NXGE_OK); 2846 fail: 2847 return (status); 2848 } 2849 2850 /* Set promiscous mode */ 2851 2852 nxge_status_t 2853 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 2854 { 2855 nxge_status_t status = NXGE_OK; 2856 2857 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2858 "==> nxge_set_promisc: on %d", on)); 2859 2860 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 2861 2862 RW_ENTER_WRITER(&nxgep->filter_lock); 2863 2864 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 2865 goto fail; 2866 } 2867 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 2868 goto fail; 2869 } 2870 2871 RW_EXIT(&nxgep->filter_lock); 2872 2873 if (on) 2874 nxgep->statsp->mac_stats.promisc = B_TRUE; 2875 else 2876 nxgep->statsp->mac_stats.promisc = B_FALSE; 2877 2878 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 2879 2880 return (NXGE_OK); 2881 fail: 2882 RW_EXIT(&nxgep->filter_lock); 2883 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 2884 "Unable to set promisc (%d)", on)); 2885 2886 return (status); 2887 } 2888 2889 /*ARGSUSED*/ 2890 uint_t 2891 nxge_mif_intr(void *arg1, void *arg2) 2892 { 2893 #ifdef NXGE_DEBUG 2894 p_nxge_t nxgep = (p_nxge_t)arg2; 2895 #endif 2896 #if NXGE_MIF 2897 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 2898 uint32_t status; 2899 npi_handle_t handle; 2900 uint8_t portn; 2901 p_nxge_stats_t statsp; 2902 #endif 2903 2904 #ifdef NXGE_MIF 2905 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 2906 nxgep = ldvp->nxgep; 2907 } 2908 nxgep = ldvp->nxgep; 2909 #endif 2910 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 2911 2912 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 2913 return (DDI_INTR_CLAIMED); 2914 2915 mif_intr_fail: 2916 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 2917 return (DDI_INTR_UNCLAIMED); 2918 } 2919 2920 /*ARGSUSED*/ 2921 uint_t 2922 nxge_mac_intr(void *arg1, void *arg2) 2923 { 2924 p_nxge_t nxgep = (p_nxge_t)arg2; 2925 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 2926 p_nxge_ldg_t ldgp; 2927 uint32_t status; 2928 npi_handle_t handle; 2929 uint8_t portn; 2930 p_nxge_stats_t statsp; 2931 npi_status_t rs = NPI_SUCCESS; 2932 2933 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 2934 nxgep = ldvp->nxgep; 2935 } 2936 2937 ldgp = ldvp->ldgp; 2938 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 2939 "group %d", ldgp->ldg)); 2940 2941 handle = NXGE_DEV_NPI_HANDLE(nxgep); 2942 /* 2943 * This interrupt handler is for a specific 2944 * mac port. 2945 */ 2946 statsp = (p_nxge_stats_t)nxgep->statsp; 2947 portn = nxgep->mac.portnum; 2948 2949 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2950 "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 2951 2952 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2953 rs = npi_xmac_tx_get_istatus(handle, portn, 2954 (xmac_tx_iconfig_t *)&status); 2955 if (rs != NPI_SUCCESS) 2956 goto npi_fail; 2957 if (status & ICFG_XMAC_TX_ALL) { 2958 if (status & ICFG_XMAC_TX_UNDERRUN) { 2959 statsp->xmac_stats.tx_underflow_err++; 2960 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2961 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 2962 } 2963 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 2964 statsp->xmac_stats.tx_maxpktsize_err++; 2965 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2966 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 2967 } 2968 if (status & ICFG_XMAC_TX_OVERFLOW) { 2969 statsp->xmac_stats.tx_overflow_err++; 2970 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2971 NXGE_FM_EREPORT_TXMAC_OVERFLOW); 2972 } 2973 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 2974 statsp->xmac_stats.tx_fifo_xfr_err++; 2975 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2976 NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 2977 } 2978 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 2979 statsp->xmac_stats.tx_byte_cnt += 2980 XTXMAC_BYTE_CNT_MASK; 2981 } 2982 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 2983 statsp->xmac_stats.tx_frame_cnt += 2984 XTXMAC_FRM_CNT_MASK; 2985 } 2986 } 2987 2988 rs = npi_xmac_rx_get_istatus(handle, portn, 2989 (xmac_rx_iconfig_t *)&status); 2990 if (rs != NPI_SUCCESS) 2991 goto npi_fail; 2992 if (status & ICFG_XMAC_RX_ALL) { 2993 if (status & ICFG_XMAC_RX_OVERFLOW) 2994 statsp->xmac_stats.rx_overflow_err++; 2995 if (status & ICFG_XMAC_RX_UNDERFLOW) { 2996 statsp->xmac_stats.rx_underflow_err++; 2997 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2998 NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 2999 } 3000 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 3001 statsp->xmac_stats.rx_crc_err_cnt += 3002 XRXMAC_CRC_ER_CNT_MASK; 3003 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3004 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 3005 } 3006 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 3007 statsp->xmac_stats.rx_len_err_cnt += 3008 MAC_LEN_ER_CNT_MASK; 3009 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3010 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 3011 } 3012 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 3013 statsp->xmac_stats.rx_viol_err_cnt += 3014 XRXMAC_CD_VIO_CNT_MASK; 3015 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3016 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 3017 } 3018 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 3019 statsp->xmac_stats.rx_byte_cnt += 3020 XRXMAC_BT_CNT_MASK; 3021 } 3022 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 3023 statsp->xmac_stats.rx_hist1_cnt += 3024 XRXMAC_HIST_CNT1_MASK; 3025 } 3026 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 3027 statsp->xmac_stats.rx_hist2_cnt += 3028 XRXMAC_HIST_CNT2_MASK; 3029 } 3030 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 3031 statsp->xmac_stats.rx_hist3_cnt += 3032 XRXMAC_HIST_CNT3_MASK; 3033 } 3034 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 3035 statsp->xmac_stats.rx_hist4_cnt += 3036 XRXMAC_HIST_CNT4_MASK; 3037 } 3038 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 3039 statsp->xmac_stats.rx_hist5_cnt += 3040 XRXMAC_HIST_CNT5_MASK; 3041 } 3042 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 3043 statsp->xmac_stats.rx_hist6_cnt += 3044 XRXMAC_HIST_CNT6_MASK; 3045 } 3046 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 3047 statsp->xmac_stats.rx_broadcast_cnt += 3048 XRXMAC_BC_FRM_CNT_MASK; 3049 } 3050 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 3051 statsp->xmac_stats.rx_mult_cnt += 3052 XRXMAC_MC_FRM_CNT_MASK; 3053 } 3054 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 3055 statsp->xmac_stats.rx_frag_cnt += 3056 XRXMAC_FRAG_CNT_MASK; 3057 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3058 NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP); 3059 } 3060 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 3061 statsp->xmac_stats.rx_frame_align_err_cnt += 3062 XRXMAC_AL_ER_CNT_MASK; 3063 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3064 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 3065 } 3066 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 3067 statsp->xmac_stats.rx_linkfault_err_cnt += 3068 XMAC_LINK_FLT_CNT_MASK; 3069 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3070 NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP); 3071 } 3072 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 3073 statsp->xmac_stats.rx_remotefault_err++; 3074 } 3075 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 3076 statsp->xmac_stats.rx_localfault_err++; 3077 } 3078 } 3079 3080 rs = npi_xmac_ctl_get_istatus(handle, portn, 3081 (xmac_ctl_iconfig_t *)&status); 3082 if (rs != NPI_SUCCESS) 3083 goto npi_fail; 3084 if (status & ICFG_XMAC_CTRL_ALL) { 3085 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 3086 statsp->xmac_stats.rx_pause_cnt++; 3087 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 3088 statsp->xmac_stats.tx_pause_state++; 3089 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 3090 statsp->xmac_stats.tx_nopause_state++; 3091 } 3092 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 3093 rs = npi_bmac_tx_get_istatus(handle, portn, 3094 (bmac_tx_iconfig_t *)&status); 3095 if (rs != NPI_SUCCESS) 3096 goto npi_fail; 3097 if (status & ICFG_BMAC_TX_ALL) { 3098 if (status & ICFG_BMAC_TX_UNDERFLOW) { 3099 statsp->bmac_stats.tx_underrun_err++; 3100 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3101 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 3102 } 3103 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 3104 statsp->bmac_stats.tx_max_pkt_err++; 3105 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3106 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 3107 } 3108 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 3109 statsp->bmac_stats.tx_byte_cnt += 3110 BTXMAC_BYTE_CNT_MASK; 3111 } 3112 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 3113 statsp->bmac_stats.tx_frame_cnt += 3114 BTXMAC_FRM_CNT_MASK; 3115 } 3116 } 3117 3118 rs = npi_bmac_rx_get_istatus(handle, portn, 3119 (bmac_rx_iconfig_t *)&status); 3120 if (rs != NPI_SUCCESS) 3121 goto npi_fail; 3122 if (status & ICFG_BMAC_RX_ALL) { 3123 if (status & ICFG_BMAC_RX_OVERFLOW) { 3124 statsp->bmac_stats.rx_overflow_err++; 3125 } 3126 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 3127 statsp->bmac_stats.rx_frame_cnt += 3128 RXMAC_FRM_CNT_MASK; 3129 } 3130 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 3131 statsp->bmac_stats.rx_crc_err_cnt += 3132 BMAC_CRC_ER_CNT_MASK; 3133 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3134 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 3135 } 3136 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 3137 statsp->bmac_stats.rx_len_err_cnt += 3138 MAC_LEN_ER_CNT_MASK; 3139 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3140 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 3141 } 3142 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 3143 statsp->bmac_stats.rx_viol_err_cnt += 3144 BMAC_CD_VIO_CNT_MASK; 3145 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3146 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 3147 } 3148 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 3149 statsp->bmac_stats.rx_byte_cnt += 3150 BRXMAC_BYTE_CNT_MASK; 3151 } 3152 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 3153 statsp->bmac_stats.rx_align_err_cnt += 3154 BMAC_AL_ER_CNT_MASK; 3155 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3156 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 3157 } 3158 3159 rs = npi_bmac_ctl_get_istatus(handle, portn, 3160 (bmac_ctl_iconfig_t *)&status); 3161 if (rs != NPI_SUCCESS) 3162 goto npi_fail; 3163 3164 if (status & ICFG_BMAC_CTL_ALL) { 3165 if (status & ICFG_BMAC_CTL_RCVPAUSE) 3166 statsp->bmac_stats.rx_pause_cnt++; 3167 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 3168 statsp->bmac_stats.tx_pause_state++; 3169 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 3170 statsp->bmac_stats.tx_nopause_state++; 3171 } 3172 } 3173 3174 if (ldgp->nldvs == 1) { 3175 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3176 B_TRUE, ldgp->ldg_timer); 3177 } 3178 3179 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 3180 return (DDI_INTR_CLAIMED); 3181 3182 npi_fail: 3183 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 3184 return (DDI_INTR_UNCLAIMED); 3185 } 3186 3187 nxge_status_t 3188 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 3189 { 3190 uint8_t phy_port_addr; 3191 nxge_status_t status = NXGE_OK; 3192 boolean_t rx_sig_ok; 3193 boolean_t pcs_blk_lock; 3194 boolean_t link_align; 3195 uint16_t val1, val2, val3; 3196 #ifdef NXGE_DEBUG_SYMBOL_ERR 3197 uint16_t val_debug; 3198 uint16_t val; 3199 #endif 3200 3201 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 3202 3203 #ifdef NXGE_DEBUG_SYMBOL_ERR 3204 /* Check Device 3 Register Device 3 0xC809 */ 3205 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 3206 if ((val_debug & ~0x200) != 0) { 3207 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 3208 nxgep->mac.portnum, val_debug); 3209 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 3210 &val_debug); 3211 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 3212 nxgep->mac.portnum, val_debug); 3213 } 3214 3215 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3216 XPCS_REG_DESCWERR_COUNTER, &val); 3217 if (val != 0) 3218 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 3219 3220 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3221 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 3222 if (val != 0) 3223 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 3224 3225 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3226 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 3227 if (val != 0) 3228 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 3229 #endif 3230 3231 /* Check from BCM8704 if 10G link is up or down */ 3232 3233 /* Check Device 1 Register 0xA bit0 */ 3234 status = nxge_mdio_read(nxgep, phy_port_addr, 3235 BCM8704_PMA_PMD_DEV_ADDR, 3236 BCM8704_PMD_RECEIVE_SIG_DETECT, 3237 &val1); 3238 if (status != NXGE_OK) 3239 goto fail; 3240 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 3241 3242 /* Check Device 3 Register 0x20 bit0 */ 3243 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 3244 BCM8704_PCS_DEV_ADDR, 3245 BCM8704_10GBASE_R_PCS_STATUS_REG, 3246 &val2)) != NPI_SUCCESS) 3247 goto fail; 3248 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 3249 3250 /* Check Device 4 Register 0x18 bit12 */ 3251 status = nxge_mdio_read(nxgep, phy_port_addr, 3252 BCM8704_PHYXS_ADDR, 3253 BCM8704_PHYXS_XGXS_LANE_STATUS_REG, 3254 &val3); 3255 if (status != NXGE_OK) 3256 goto fail; 3257 link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 3258 XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 3259 XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 3260 3261 #ifdef NXGE_DEBUG_ALIGN_ERR 3262 /* Temp workaround for link down issue */ 3263 if (pcs_blk_lock == B_FALSE) { 3264 if (val2 != 0x4) { 3265 pcs_blk_lock = B_TRUE; 3266 cmn_err(CE_NOTE, 3267 "!LINK DEBUG: port%d PHY Dev3 " 3268 "Reg 0x20 = 0x%x\n", 3269 nxgep->mac.portnum, val2); 3270 } 3271 } 3272 3273 if (link_align == B_FALSE) { 3274 if (val3 != 0x140f) { 3275 link_align = B_TRUE; 3276 cmn_err(CE_NOTE, 3277 "!LINK DEBUG: port%d PHY Dev4 " 3278 "Reg 0x18 = 0x%x\n", 3279 nxgep->mac.portnum, val3); 3280 } 3281 } 3282 3283 if (rx_sig_ok == B_FALSE) { 3284 if ((val2 == 0) || (val3 == 0)) { 3285 rx_sig_ok = B_TRUE; 3286 cmn_err(CE_NOTE, 3287 "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 3288 nxgep->mac.portnum); 3289 } 3290 } 3291 #endif 3292 3293 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 3294 (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 3295 3296 return (NXGE_OK); 3297 fail: 3298 return (status); 3299 } 3300 3301 3302 nxge_status_t 3303 nxge_get_xcvr_type(p_nxge_t nxgep) 3304 { 3305 nxge_status_t status = NXGE_OK; 3306 3307 #if defined(_BIG_ENDIAN) 3308 char *prop_val; 3309 3310 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 3311 "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 3312 if (strcmp("xgf", prop_val) == 0) { 3313 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3314 nxgep->mac.portmode = PORT_10G_FIBER; 3315 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr")); 3316 } else if (strcmp("mif", prop_val) == 0) { 3317 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3318 nxgep->mac.portmode = PORT_1G_COPPER; 3319 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 3320 } else if (strcmp("pcs", prop_val) == 0) { 3321 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3322 nxgep->mac.portmode = PORT_1G_FIBER; 3323 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Fiber Xcvr")); 3324 } else if (strcmp("xgc", prop_val) == 0) { 3325 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3326 nxgep->mac.portmode = PORT_10G_COPPER; 3327 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 3328 } else { 3329 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3330 "Unknown phy-type: %s", 3331 prop_val)); 3332 ddi_prop_free(prop_val); 3333 return (NXGE_ERROR); 3334 } 3335 status = NXGE_OK; 3336 (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 3337 "phy-type", prop_val); 3338 ddi_prop_free(prop_val); 3339 } else { 3340 /* 3341 * This should really be an error. But for now default 3342 * this to 10G fiber. 3343 */ 3344 if (nxgep->niu_type == N2_NIU) { 3345 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3346 nxgep->mac.portmode = PORT_10G_FIBER; 3347 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3348 "Cannot find phy-type: " 3349 " Default to 10G Fiber Xcvr")); 3350 status = NXGE_OK; 3351 } else { 3352 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3353 "Cannot get phy-type")); 3354 return (NXGE_ERROR); 3355 } 3356 } 3357 #else 3358 status = nxge_espc_phy_type_get(nxgep); 3359 #endif 3360 3361 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 3362 return (status); 3363 } 3364 3365 nxge_status_t 3366 nxge_10g_link_led_on(p_nxge_t nxgep) 3367 { 3368 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 3369 != NPI_SUCCESS) 3370 return (NXGE_ERROR); 3371 else 3372 return (NXGE_OK); 3373 } 3374 3375 nxge_status_t 3376 nxge_10g_link_led_off(p_nxge_t nxgep) 3377 { 3378 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 3379 != NPI_SUCCESS) 3380 return (NXGE_ERROR); 3381 else 3382 return (NXGE_OK); 3383 } 3384