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 2007 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 uint16_t val; 857 #ifdef NXGE_DEBUG 858 uint8_t portn; 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 #ifdef NXGE_DEBUG 870 portn = nxgep->mac.portnum; 871 #endif 872 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 873 874 param_arr = nxgep->param_arr; 875 statsp = nxgep->statsp; 876 877 /* 878 * Initialize the xcvr statistics. 879 */ 880 statsp->mac_stats.cap_autoneg = 0; 881 statsp->mac_stats.cap_100T4 = 0; 882 statsp->mac_stats.cap_100fdx = 0; 883 statsp->mac_stats.cap_100hdx = 0; 884 statsp->mac_stats.cap_10fdx = 0; 885 statsp->mac_stats.cap_10hdx = 0; 886 statsp->mac_stats.cap_asmpause = 0; 887 statsp->mac_stats.cap_pause = 0; 888 statsp->mac_stats.cap_1000fdx = 0; 889 statsp->mac_stats.cap_1000hdx = 0; 890 statsp->mac_stats.cap_10gfdx = 0; 891 statsp->mac_stats.cap_10ghdx = 0; 892 893 /* 894 * Initialize the link statistics. 895 */ 896 statsp->mac_stats.link_T4 = 0; 897 statsp->mac_stats.link_asmpause = 0; 898 statsp->mac_stats.link_pause = 0; 899 900 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 901 902 switch (nxgep->mac.portmode) { 903 case PORT_10G_FIBER: 904 /* Disable Link LEDs */ 905 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 906 goto fail; 907 908 /* Set Clause 45 */ 909 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 910 911 /* Reset the transceiver */ 912 if ((status = nxge_mdio_read(nxgep, 913 phy_port_addr, 914 BCM8704_PHYXS_ADDR, 915 BCM8704_PHYXS_CONTROL_REG, 916 &phyxs_ctl.value)) != NXGE_OK) 917 goto fail; 918 919 phyxs_ctl.bits.reset = 1; 920 if ((status = nxge_mdio_write(nxgep, 921 phy_port_addr, 922 BCM8704_PHYXS_ADDR, 923 BCM8704_PHYXS_CONTROL_REG, 924 phyxs_ctl.value)) != NXGE_OK) 925 goto fail; 926 927 do { 928 drv_usecwait(500); 929 if ((status = nxge_mdio_read(nxgep, 930 phy_port_addr, 931 BCM8704_PHYXS_ADDR, 932 BCM8704_PHYXS_CONTROL_REG, 933 &phyxs_ctl.value)) != NXGE_OK) 934 goto fail; 935 delay++; 936 } while ((phyxs_ctl.bits.reset) && (delay < 100)); 937 if (delay == 100) { 938 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 939 "nxge_xcvr_init: " 940 "failed to reset Transceiver on port<%d>", 941 portn)); 942 status = NXGE_ERROR; 943 goto fail; 944 } 945 946 /* Set to 0x7FBF */ 947 ctl.value = 0; 948 ctl.bits.res1 = 0x3F; 949 ctl.bits.optxon_lvl = 1; 950 ctl.bits.oprxflt_lvl = 1; 951 ctl.bits.optrxlos_lvl = 1; 952 ctl.bits.optxflt_lvl = 1; 953 ctl.bits.opprflt_lvl = 1; 954 ctl.bits.obtmpflt_lvl = 1; 955 ctl.bits.opbiasflt_lvl = 1; 956 ctl.bits.optxrst_lvl = 1; 957 if ((status = nxge_mdio_write(nxgep, 958 phy_port_addr, 959 BCM8704_USER_DEV3_ADDR, 960 BCM8704_USER_CONTROL_REG, ctl.value)) 961 != NXGE_OK) 962 goto fail; 963 964 /* Set to 0x164 */ 965 tx_ctl.value = 0; 966 tx_ctl.bits.tsck_lpwren = 1; 967 tx_ctl.bits.tx_dac_txck = 0x2; 968 tx_ctl.bits.tx_dac_txd = 0x1; 969 tx_ctl.bits.xfp_clken = 1; 970 if ((status = nxge_mdio_write(nxgep, 971 phy_port_addr, 972 BCM8704_USER_DEV3_ADDR, 973 BCM8704_USER_PMD_TX_CONTROL_REG, tx_ctl.value)) 974 != NXGE_OK) 975 goto fail; 976 /* 977 * According to Broadcom's instruction, SW needs to read 978 * back these registers twice after written. 979 */ 980 if ((status = nxge_mdio_read(nxgep, 981 phy_port_addr, 982 BCM8704_USER_DEV3_ADDR, 983 BCM8704_USER_CONTROL_REG, &val)) 984 != NXGE_OK) 985 goto fail; 986 987 if ((status = nxge_mdio_read(nxgep, 988 phy_port_addr, 989 BCM8704_USER_DEV3_ADDR, 990 BCM8704_USER_CONTROL_REG, &val)) 991 != NXGE_OK) 992 goto fail; 993 994 if ((status = nxge_mdio_read(nxgep, 995 phy_port_addr, 996 BCM8704_USER_DEV3_ADDR, 997 BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 998 != NXGE_OK) 999 goto fail; 1000 1001 if ((status = nxge_mdio_read(nxgep, 1002 phy_port_addr, 1003 BCM8704_USER_DEV3_ADDR, 1004 BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 1005 != NXGE_OK) 1006 goto fail; 1007 1008 1009 /* Enable Tx and Rx LEDs to be driven by traffic */ 1010 if ((status = nxge_mdio_read(nxgep, 1011 phy_port_addr, 1012 BCM8704_USER_DEV3_ADDR, 1013 BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1014 &op_ctr.value)) != NXGE_OK) 1015 goto fail; 1016 op_ctr.bits.gpio_sel = 0x3; 1017 if ((status = nxge_mdio_write(nxgep, 1018 phy_port_addr, 1019 BCM8704_USER_DEV3_ADDR, 1020 BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1021 op_ctr.value)) != NXGE_OK) 1022 goto fail; 1023 1024 NXGE_DELAY(1000000); 1025 1026 /* Set BCM8704 Internal Loopback mode if necessary */ 1027 if ((status = nxge_mdio_read(nxgep, 1028 phy_port_addr, 1029 BCM8704_PCS_DEV_ADDR, 1030 BCM8704_PCS_CONTROL_REG, 1031 &pcs_ctl.value)) != NXGE_OK) 1032 goto fail; 1033 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 1034 pcs_ctl.bits.loopback = 1; 1035 else 1036 pcs_ctl.bits.loopback = 0; 1037 if ((status = nxge_mdio_write(nxgep, 1038 phy_port_addr, 1039 BCM8704_PCS_DEV_ADDR, 1040 BCM8704_PCS_CONTROL_REG, 1041 pcs_ctl.value)) != NXGE_OK) 1042 goto fail; 1043 1044 status = nxge_mdio_read(nxgep, phy_port_addr, 1045 0x1, 0xA, &val); 1046 if (status != NXGE_OK) 1047 goto fail; 1048 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1049 "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", 1050 portn, val)); 1051 status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 1052 if (status != NXGE_OK) 1053 goto fail; 1054 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1055 "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", 1056 portn, val)); 1057 status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 1058 if (status != NXGE_OK) 1059 goto fail; 1060 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1061 "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", 1062 portn, val)); 1063 1064 #ifdef NXGE_DEBUG 1065 /* Diagnose link issue if link is not up */ 1066 status = nxge_mdio_read(nxgep, phy_port_addr, 1067 BCM8704_USER_DEV3_ADDR, 1068 BCM8704_USER_ANALOG_STATUS0_REG, 1069 &val); 1070 if (status != NXGE_OK) 1071 goto fail; 1072 1073 status = nxge_mdio_read(nxgep, phy_port_addr, 1074 BCM8704_USER_DEV3_ADDR, 1075 BCM8704_USER_ANALOG_STATUS0_REG, 1076 &val); 1077 if (status != NXGE_OK) 1078 goto fail; 1079 1080 status = nxge_mdio_read(nxgep, phy_port_addr, 1081 BCM8704_USER_DEV3_ADDR, 1082 BCM8704_USER_TX_ALARM_STATUS_REG, 1083 &val1); 1084 if (status != NXGE_OK) 1085 goto fail; 1086 1087 status = nxge_mdio_read(nxgep, phy_port_addr, 1088 BCM8704_USER_DEV3_ADDR, 1089 BCM8704_USER_TX_ALARM_STATUS_REG, 1090 &val1); 1091 if (status != NXGE_OK) 1092 goto fail; 1093 1094 if (val != 0x3FC) { 1095 if ((val == 0x43BC) && (val1 != 0)) { 1096 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1097 "Cable not connected to peer or bad" 1098 " cable on port<%d>\n", portn)); 1099 } else if (val == 0x639C) { 1100 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1101 "Optical module (XFP) is bad or absence" 1102 " on port<%d>\n", portn)); 1103 } 1104 } 1105 #endif 1106 1107 statsp->mac_stats.cap_10gfdx = 1; 1108 statsp->mac_stats.lp_cap_10gfdx = 1; 1109 break; 1110 case PORT_10G_COPPER: 1111 break; 1112 case PORT_1G_FIBER: 1113 case PORT_1G_COPPER: 1114 /* Set Clause 22 */ 1115 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 1116 1117 /* Set capability flags */ 1118 statsp->mac_stats.cap_1000fdx = 1119 param_arr[param_anar_1000fdx].value; 1120 statsp->mac_stats.cap_100fdx = 1121 param_arr[param_anar_100fdx].value; 1122 statsp->mac_stats.cap_10fdx = param_arr[param_anar_10fdx].value; 1123 1124 if ((status = nxge_mii_xcvr_init(nxgep)) != NXGE_OK) 1125 goto fail; 1126 break; 1127 default: 1128 goto fail; 1129 } 1130 1131 statsp->mac_stats.xcvr_inits++; 1132 1133 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 1134 return (NXGE_OK); 1135 1136 fail: 1137 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1138 "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 1139 portn)); 1140 return (status); 1141 } 1142 1143 1144 /* Initialize the TxMAC sub-block */ 1145 1146 nxge_status_t 1147 nxge_tx_mac_init(p_nxge_t nxgep) 1148 { 1149 npi_attr_t ap; 1150 uint8_t portn; 1151 nxge_port_mode_t portmode; 1152 nxge_port_t portt; 1153 npi_handle_t handle; 1154 npi_status_t rs = NPI_SUCCESS; 1155 1156 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 1157 portt = nxgep->mac.porttype; 1158 handle = nxgep->npi_handle; 1159 portmode = nxgep->mac.portmode; 1160 1161 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 1162 portn)); 1163 1164 /* Set Max and Min Frame Size */ 1165 if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) { 1166 SET_MAC_ATTR2(handle, ap, portn, 1167 MAC_PORT_FRAME_SIZE, 64, 0x2400, rs); 1168 } else { 1169 SET_MAC_ATTR2(handle, ap, portn, 1170 MAC_PORT_FRAME_SIZE, 64, 0x5EE + 4, rs); 1171 } 1172 1173 if (rs != NPI_SUCCESS) 1174 goto fail; 1175 if (nxgep->param_arr[param_accept_jumbo].value || 1176 nxgep->mac.is_jumbo == B_TRUE) 1177 nxgep->mac.maxframesize = 0x2400; 1178 else 1179 nxgep->mac.maxframesize = 0x5EE + 4; 1180 nxgep->mac.minframesize = 64; 1181 1182 if (portt == PORT_TYPE_XMAC) { 1183 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 1184 0)) != NPI_SUCCESS) 1185 goto fail; 1186 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 1187 if ((portmode == PORT_10G_FIBER) || 1188 (portmode == PORT_10G_COPPER)) { 1189 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 1190 XGMII_IPG_12_15, rs); 1191 if (rs != NPI_SUCCESS) 1192 goto fail; 1193 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 1194 } else { 1195 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 1196 MII_GMII_IPG_12, rs); 1197 if (rs != NPI_SUCCESS) 1198 goto fail; 1199 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 1200 } 1201 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 1202 CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 1203 goto fail; 1204 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 1205 nxgep->mac.maxburstsize = 0; /* not programmable */ 1206 nxgep->mac.ctrltype = 0; /* not programmable */ 1207 nxgep->mac.pa_size = 0; /* not programmable */ 1208 1209 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 1210 != NPI_SUCCESS) 1211 goto fail; 1212 1213 } else { 1214 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 1215 0)) != NPI_SUCCESS) 1216 goto fail; 1217 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 1218 1219 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 1220 rs); 1221 if (rs != NPI_SUCCESS) 1222 goto fail; 1223 nxgep->mac.ctrltype = 0x8808; 1224 1225 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 1226 if (rs != NPI_SUCCESS) 1227 goto fail; 1228 nxgep->mac.pa_size = 0x7; 1229 1230 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 1231 CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 1232 goto fail; 1233 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 1234 } 1235 1236 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 1237 portn)); 1238 1239 return (NXGE_OK); 1240 fail: 1241 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1242 "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", 1243 portn)); 1244 1245 return (NXGE_ERROR | rs); 1246 } 1247 1248 /* Initialize the RxMAC sub-block */ 1249 1250 nxge_status_t 1251 nxge_rx_mac_init(p_nxge_t nxgep) 1252 { 1253 npi_attr_t ap; 1254 uint32_t i; 1255 uint16_t hashtab_e; 1256 p_hash_filter_t hash_filter; 1257 nxge_port_t portt; 1258 uint8_t portn; 1259 npi_handle_t handle; 1260 npi_status_t rs = NPI_SUCCESS; 1261 uint16_t *addr16p; 1262 uint16_t addr0, addr1, addr2; 1263 xmac_rx_config_t xconfig; 1264 bmac_rx_config_t bconfig; 1265 1266 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 1267 1268 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 1269 portn)); 1270 handle = nxgep->npi_handle; 1271 portt = nxgep->mac.porttype; 1272 1273 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 1274 addr0 = ntohs(addr16p[2]); 1275 addr1 = ntohs(addr16p[1]); 1276 addr2 = ntohs(addr16p[0]); 1277 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 1278 rs); 1279 1280 if (rs != NPI_SUCCESS) 1281 goto fail; 1282 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 1283 if (rs != NPI_SUCCESS) 1284 goto fail; 1285 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 1286 if (rs != NPI_SUCCESS) 1287 goto fail; 1288 1289 /* 1290 * Load the multicast hash filter bits. 1291 */ 1292 hash_filter = nxgep->hash_filter; 1293 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 1294 if (hash_filter != NULL) { 1295 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 1296 (NMCFILTER_REGS - 1) - i]; 1297 } else { 1298 hashtab_e = 0; 1299 } 1300 1301 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 1302 (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 1303 goto fail; 1304 } 1305 1306 if (portt == PORT_TYPE_XMAC) { 1307 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 1308 0)) != NPI_SUCCESS) 1309 goto fail; 1310 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 1311 1312 (void) nxge_fflp_init_hostinfo(nxgep); 1313 1314 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 1315 CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 1316 ~CFG_XMAC_RX_STRIP_CRC; 1317 1318 if (nxgep->filter.all_phys_cnt != 0) 1319 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 1320 1321 if (nxgep->filter.all_multicast_cnt != 0) 1322 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 1323 1324 xconfig |= CFG_XMAC_RX_HASH_FILTER; 1325 1326 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 1327 xconfig)) != NPI_SUCCESS) 1328 goto fail; 1329 nxgep->mac.rx_config = xconfig; 1330 1331 /* Comparison of mac unique address is always enabled on XMAC */ 1332 1333 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 1334 != NPI_SUCCESS) 1335 goto fail; 1336 } else { 1337 (void) nxge_fflp_init_hostinfo(nxgep); 1338 1339 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 1340 0) != NPI_SUCCESS) 1341 goto fail; 1342 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 1343 1344 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 1345 ~CFG_BMAC_RX_STRIP_CRC; 1346 1347 if (nxgep->filter.all_phys_cnt != 0) 1348 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 1349 1350 if (nxgep->filter.all_multicast_cnt != 0) 1351 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 1352 1353 bconfig |= CFG_BMAC_RX_HASH_FILTER; 1354 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 1355 bconfig)) != NPI_SUCCESS) 1356 goto fail; 1357 nxgep->mac.rx_config = bconfig; 1358 1359 /* Always enable comparison of mac unique address */ 1360 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 1361 != NPI_SUCCESS) 1362 goto fail; 1363 } 1364 1365 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 1366 portn)); 1367 1368 return (NXGE_OK); 1369 1370 fail: 1371 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1372 "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", 1373 portn)); 1374 1375 return (NXGE_ERROR | rs); 1376 } 1377 1378 /* Enable TXMAC */ 1379 1380 nxge_status_t 1381 nxge_tx_mac_enable(p_nxge_t nxgep) 1382 { 1383 npi_handle_t handle; 1384 npi_status_t rs = NPI_SUCCESS; 1385 nxge_status_t status = NXGE_OK; 1386 1387 handle = nxgep->npi_handle; 1388 1389 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 1390 nxgep->mac.portnum)); 1391 1392 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 1393 goto fail; 1394 1395 /* based on speed */ 1396 nxgep->msg_min = ETHERMIN; 1397 1398 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1399 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 1400 CFG_XMAC_TX)) != NPI_SUCCESS) 1401 goto fail; 1402 } else { 1403 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 1404 CFG_BMAC_TX)) != NPI_SUCCESS) 1405 goto fail; 1406 } 1407 1408 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 1409 nxgep->mac.portnum)); 1410 1411 return (NXGE_OK); 1412 fail: 1413 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1414 "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 1415 nxgep->mac.portnum)); 1416 if (rs != NPI_SUCCESS) 1417 return (NXGE_ERROR | rs); 1418 else 1419 return (status); 1420 } 1421 1422 /* Disable TXMAC */ 1423 1424 nxge_status_t 1425 nxge_tx_mac_disable(p_nxge_t nxgep) 1426 { 1427 npi_handle_t handle; 1428 npi_status_t rs = NPI_SUCCESS; 1429 1430 handle = nxgep->npi_handle; 1431 1432 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 1433 nxgep->mac.portnum)); 1434 1435 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1436 if ((rs = npi_xmac_tx_config(handle, DISABLE, 1437 nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 1438 goto fail; 1439 } else { 1440 if ((rs = npi_bmac_tx_config(handle, DISABLE, 1441 nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 1442 goto fail; 1443 } 1444 1445 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 1446 nxgep->mac.portnum)); 1447 return (NXGE_OK); 1448 fail: 1449 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1450 "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 1451 nxgep->mac.portnum)); 1452 return (NXGE_ERROR | rs); 1453 } 1454 1455 /* Enable RXMAC */ 1456 1457 nxge_status_t 1458 nxge_rx_mac_enable(p_nxge_t nxgep) 1459 { 1460 npi_handle_t handle; 1461 uint8_t portn; 1462 npi_status_t rs = NPI_SUCCESS; 1463 nxge_status_t status = NXGE_OK; 1464 1465 handle = nxgep->npi_handle; 1466 portn = nxgep->mac.portnum; 1467 1468 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 1469 portn)); 1470 1471 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 1472 goto fail; 1473 1474 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1475 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 1476 CFG_XMAC_RX)) != NPI_SUCCESS) 1477 goto fail; 1478 } else { 1479 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 1480 CFG_BMAC_RX)) != NPI_SUCCESS) 1481 goto fail; 1482 } 1483 1484 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>", 1485 portn)); 1486 1487 return (NXGE_OK); 1488 fail: 1489 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1490 "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", 1491 portn)); 1492 1493 if (rs != NPI_SUCCESS) 1494 return (NXGE_ERROR | rs); 1495 else 1496 return (status); 1497 } 1498 1499 /* Disable RXMAC */ 1500 1501 nxge_status_t 1502 nxge_rx_mac_disable(p_nxge_t nxgep) 1503 { 1504 npi_handle_t handle; 1505 uint8_t portn; 1506 npi_status_t rs = NPI_SUCCESS; 1507 1508 handle = nxgep->npi_handle; 1509 portn = nxgep->mac.portnum; 1510 1511 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 1512 portn)); 1513 1514 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1515 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 1516 CFG_XMAC_RX)) != NPI_SUCCESS) 1517 goto fail; 1518 } else { 1519 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 1520 CFG_BMAC_RX)) != NPI_SUCCESS) 1521 goto fail; 1522 } 1523 1524 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 1525 portn)); 1526 return (NXGE_OK); 1527 fail: 1528 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1529 "nxgep_rx_mac_disable: ", 1530 "Failed to disable port<%d> RxMAC", 1531 portn)); 1532 1533 return (NXGE_ERROR | rs); 1534 } 1535 1536 /* Reset TXMAC */ 1537 1538 nxge_status_t 1539 nxge_tx_mac_reset(p_nxge_t nxgep) 1540 { 1541 npi_handle_t handle; 1542 uint8_t portn; 1543 npi_status_t rs = NPI_SUCCESS; 1544 1545 handle = nxgep->npi_handle; 1546 portn = nxgep->mac.portnum; 1547 1548 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 1549 portn)); 1550 1551 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1552 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 1553 != NPI_SUCCESS) 1554 goto fail; 1555 } else { 1556 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 1557 != NPI_SUCCESS) 1558 goto fail; 1559 } 1560 1561 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 1562 portn)); 1563 1564 return (NXGE_OK); 1565 fail: 1566 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1567 "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", 1568 portn)); 1569 1570 return (NXGE_ERROR | rs); 1571 } 1572 1573 /* Reset RXMAC */ 1574 1575 nxge_status_t 1576 nxge_rx_mac_reset(p_nxge_t nxgep) 1577 { 1578 npi_handle_t handle; 1579 uint8_t portn; 1580 npi_status_t rs = NPI_SUCCESS; 1581 1582 handle = nxgep->npi_handle; 1583 portn = nxgep->mac.portnum; 1584 1585 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 1586 portn)); 1587 1588 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 1589 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 1590 != NPI_SUCCESS) 1591 goto fail; 1592 } else { 1593 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 1594 != NPI_SUCCESS) 1595 goto fail; 1596 } 1597 1598 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 1599 portn)); 1600 1601 return (NXGE_OK); 1602 fail: 1603 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1604 "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", 1605 portn)); 1606 return (NXGE_ERROR | rs); 1607 } 1608 1609 1610 /* Enable/Disable MII Link Status change interrupt */ 1611 1612 nxge_status_t 1613 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 1614 { 1615 uint8_t portn; 1616 nxge_port_mode_t portmode; 1617 npi_status_t rs = NPI_SUCCESS; 1618 1619 portn = nxgep->mac.portnum; 1620 portmode = nxgep->mac.portmode; 1621 1622 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 1623 1624 if (enable == LINK_INTR_START) { 1625 if (portmode == PORT_10G_FIBER) { 1626 if ((rs = npi_xmac_xpcs_link_intr_enable( 1627 nxgep->npi_handle, 1628 portn)) != NPI_SUCCESS) 1629 goto fail; 1630 } else if (portmode == PORT_1G_FIBER) { 1631 if ((rs = npi_mac_pcs_link_intr_enable( 1632 nxgep->npi_handle, 1633 portn)) != NPI_SUCCESS) 1634 goto fail; 1635 } else if (portmode == PORT_1G_COPPER) { 1636 if ((rs = npi_mac_mif_link_intr_enable( 1637 nxgep->npi_handle, 1638 portn, MII_BMSR, BMSR_LSTATUS)) != NPI_SUCCESS) 1639 goto fail; 1640 } else 1641 goto fail; 1642 } else if (enable == LINK_INTR_STOP) { 1643 if (portmode == PORT_10G_FIBER) { 1644 if ((rs = npi_xmac_xpcs_link_intr_disable( 1645 nxgep->npi_handle, 1646 portn)) != NPI_SUCCESS) 1647 goto fail; 1648 } else if (portmode == PORT_1G_FIBER) { 1649 if ((rs = npi_mac_pcs_link_intr_disable( 1650 nxgep->npi_handle, 1651 portn)) != NPI_SUCCESS) 1652 goto fail; 1653 } else if (portmode == PORT_1G_COPPER) { 1654 if ((rs = npi_mac_mif_link_intr_disable( 1655 nxgep->npi_handle, 1656 portn)) != NPI_SUCCESS) 1657 goto fail; 1658 } else 1659 goto fail; 1660 } 1661 1662 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 1663 1664 return (NXGE_OK); 1665 fail: 1666 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1667 "nxge_link_intr: Failed to set port<%d> mif intr mode", 1668 portn)); 1669 1670 return (NXGE_ERROR | rs); 1671 } 1672 1673 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 1674 1675 nxge_status_t 1676 nxge_mii_xcvr_init(p_nxge_t nxgep) 1677 { 1678 p_nxge_param_t param_arr; 1679 p_nxge_stats_t statsp; 1680 uint8_t xcvr_portn; 1681 p_mii_regs_t mii_regs; 1682 mii_bmcr_t bmcr; 1683 mii_bmsr_t bmsr; 1684 mii_anar_t anar; 1685 mii_gcr_t gcr; 1686 mii_esr_t esr; 1687 mii_aux_ctl_t bcm5464r_aux; 1688 int status = NXGE_OK; 1689 1690 uint_t delay; 1691 1692 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 1693 1694 param_arr = nxgep->param_arr; 1695 statsp = nxgep->statsp; 1696 xcvr_portn = statsp->mac_stats.xcvr_portn; 1697 1698 mii_regs = NULL; 1699 1700 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1701 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 1702 1703 /* 1704 * Reset the transceiver. 1705 */ 1706 delay = 0; 1707 bmcr.value = 0; 1708 bmcr.bits.reset = 1; 1709 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1710 (uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 1711 goto fail; 1712 do { 1713 drv_usecwait(500); 1714 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1715 (uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value)) 1716 != NXGE_OK) 1717 goto fail; 1718 delay++; 1719 } while ((bmcr.bits.reset) && (delay < 1000)); 1720 if (delay == 1000) { 1721 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 1722 goto fail; 1723 } 1724 1725 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1726 (uint8_t)(uint64_t)(&mii_regs->bmsr), 1727 &bmsr.value)) != NXGE_OK) 1728 goto fail; 1729 1730 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 1731 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 1732 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 1733 param_arr[param_anar_100hdx].value = 0; 1734 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 1735 param_arr[param_anar_10hdx].value = 0; 1736 1737 /* 1738 * Initialize the xcvr statistics. 1739 */ 1740 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 1741 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 1742 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 1743 statsp->mac_stats.cap_100hdx = 0; 1744 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 1745 statsp->mac_stats.cap_10hdx = 0; 1746 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 1747 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 1748 1749 /* 1750 * Initialise the xcvr advertised capability statistics. 1751 */ 1752 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 1753 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 1754 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 1755 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 1756 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 1757 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 1758 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 1759 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 1760 statsp->mac_stats.adv_cap_asmpause = 1761 param_arr[param_anar_asmpause].value; 1762 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 1763 1764 1765 /* 1766 * Check for extended status just in case we're 1767 * running a Gigibit phy. 1768 */ 1769 if (bmsr.bits.extend_status) { 1770 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1771 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) 1772 != NXGE_OK) 1773 goto fail; 1774 param_arr[param_anar_1000fdx].value &= 1775 esr.bits.link_1000fdx; 1776 param_arr[param_anar_1000hdx].value = 0; 1777 1778 statsp->mac_stats.cap_1000fdx = 1779 (esr.bits.link_1000Xfdx || 1780 esr.bits.link_1000fdx); 1781 statsp->mac_stats.cap_1000hdx = 0; 1782 } else { 1783 param_arr[param_anar_1000fdx].value = 0; 1784 param_arr[param_anar_1000hdx].value = 0; 1785 } 1786 1787 /* 1788 * Initialize 1G Statistics once the capability is established. 1789 */ 1790 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 1791 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 1792 1793 /* 1794 * Initialise the link statistics. 1795 */ 1796 statsp->mac_stats.link_T4 = 0; 1797 statsp->mac_stats.link_asmpause = 0; 1798 statsp->mac_stats.link_pause = 0; 1799 statsp->mac_stats.link_speed = 0; 1800 statsp->mac_stats.link_duplex = 0; 1801 statsp->mac_stats.link_up = 0; 1802 1803 /* 1804 * Switch off Auto-negotiation, 100M and full duplex. 1805 */ 1806 bmcr.value = 0; 1807 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1808 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 1809 goto fail; 1810 1811 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 1812 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 1813 bmcr.bits.loopback = 1; 1814 bmcr.bits.enable_autoneg = 0; 1815 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 1816 bmcr.bits.speed_1000_sel = 1; 1817 bmcr.bits.duplex_mode = 1; 1818 param_arr[param_autoneg].value = 0; 1819 } else { 1820 bmcr.bits.loopback = 0; 1821 } 1822 1823 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 1824 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 1825 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 1826 param_arr[param_autoneg].value = 0; 1827 bcm5464r_aux.value = 0; 1828 bcm5464r_aux.bits.ext_lb = 1; 1829 bcm5464r_aux.bits.write_1 = 1; 1830 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1831 BCM5464R_AUX_CTL, bcm5464r_aux.value)) 1832 != NXGE_OK) 1833 goto fail; 1834 } 1835 1836 if (param_arr[param_autoneg].value) { 1837 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1838 "Restarting Auto-negotiation.")); 1839 /* 1840 * Setup our Auto-negotiation advertisement register. 1841 */ 1842 anar.value = 0; 1843 anar.bits.selector = 1; 1844 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 1845 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 1846 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 1847 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 1848 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 1849 anar.bits.cap_asmpause = 0; 1850 anar.bits.cap_pause = 0; 1851 if (param_arr[param_anar_1000fdx].value || 1852 param_arr[param_anar_100fdx].value || 1853 param_arr[param_anar_10fdx].value) { 1854 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 1855 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 1856 } 1857 1858 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1859 (uint8_t)(uint64_t)(&mii_regs->anar), anar.value)) 1860 != NXGE_OK) 1861 goto fail; 1862 if (bmsr.bits.extend_status) { 1863 gcr.value = 0; 1864 gcr.bits.ms_mode_en = 1865 param_arr[param_master_cfg_enable].value; 1866 gcr.bits.master = 1867 param_arr[param_master_cfg_value].value; 1868 gcr.bits.link_1000fdx = 1869 param_arr[param_anar_1000fdx].value; 1870 gcr.bits.link_1000hdx = 1871 param_arr[param_anar_1000hdx].value; 1872 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1873 (uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value)) 1874 != NXGE_OK) 1875 goto fail; 1876 } 1877 1878 bmcr.bits.enable_autoneg = 1; 1879 bmcr.bits.restart_autoneg = 1; 1880 1881 } else { 1882 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 1883 bmcr.bits.speed_1000_sel = 1884 param_arr[param_anar_1000fdx].value | 1885 param_arr[param_anar_1000hdx].value; 1886 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 1887 (param_arr[param_anar_100fdx].value | 1888 param_arr[param_anar_100hdx].value); 1889 if (bmcr.bits.speed_1000_sel) { 1890 statsp->mac_stats.link_speed = 1000; 1891 gcr.value = 0; 1892 gcr.bits.ms_mode_en = 1893 param_arr[param_master_cfg_enable].value; 1894 gcr.bits.master = 1895 param_arr[param_master_cfg_value].value; 1896 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1897 (uint8_t)(uint64_t)(&mii_regs->gcr), 1898 gcr.value)) 1899 != NXGE_OK) 1900 goto fail; 1901 if (param_arr[param_anar_1000fdx].value) { 1902 bmcr.bits.duplex_mode = 1; 1903 statsp->mac_stats.link_duplex = 2; 1904 } else 1905 statsp->mac_stats.link_duplex = 1; 1906 } else if (bmcr.bits.speed_sel) { 1907 statsp->mac_stats.link_speed = 100; 1908 if (param_arr[param_anar_100fdx].value) { 1909 bmcr.bits.duplex_mode = 1; 1910 statsp->mac_stats.link_duplex = 2; 1911 } else 1912 statsp->mac_stats.link_duplex = 1; 1913 } else { 1914 statsp->mac_stats.link_speed = 10; 1915 if (param_arr[param_anar_10fdx].value) { 1916 bmcr.bits.duplex_mode = 1; 1917 statsp->mac_stats.link_duplex = 2; 1918 } else 1919 statsp->mac_stats.link_duplex = 1; 1920 } 1921 if (statsp->mac_stats.link_duplex != 1) { 1922 statsp->mac_stats.link_asmpause = 1923 statsp->mac_stats.cap_asmpause; 1924 statsp->mac_stats.link_pause = 1925 statsp->mac_stats.cap_pause; 1926 } 1927 1928 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 1929 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 1930 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 1931 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 1932 /* BCM5464R 1000mbps external loopback mode */ 1933 gcr.value = 0; 1934 gcr.bits.ms_mode_en = 1; 1935 gcr.bits.master = 1; 1936 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1937 (uint8_t)(uint64_t)(&mii_regs->gcr), 1938 gcr.value)) 1939 != NXGE_OK) 1940 goto fail; 1941 bmcr.value = 0; 1942 bmcr.bits.speed_1000_sel = 1; 1943 statsp->mac_stats.link_speed = 1000; 1944 } else if (statsp->port_stats.lb_mode 1945 == nxge_lb_ext100) { 1946 /* BCM5464R 100mbps external loopback mode */ 1947 bmcr.value = 0; 1948 bmcr.bits.speed_sel = 1; 1949 bmcr.bits.duplex_mode = 1; 1950 statsp->mac_stats.link_speed = 100; 1951 } else if (statsp->port_stats.lb_mode 1952 == nxge_lb_ext10) { 1953 /* BCM5464R 10mbps external loopback mode */ 1954 bmcr.value = 0; 1955 bmcr.bits.duplex_mode = 1; 1956 statsp->mac_stats.link_speed = 10; 1957 } 1958 } 1959 } 1960 1961 if ((status = nxge_mii_write(nxgep, xcvr_portn, 1962 (uint8_t)(uint64_t)(&mii_regs->bmcr), 1963 bmcr.value)) != NXGE_OK) 1964 goto fail; 1965 1966 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1967 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 1968 goto fail; 1969 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 1970 1971 /* 1972 * Initialize the xcvr status kept in the context structure. 1973 */ 1974 nxgep->soft_bmsr.value = 0; 1975 1976 if ((status = nxge_mii_read(nxgep, xcvr_portn, 1977 (uint8_t)(uint64_t)(&mii_regs->bmsr), 1978 &nxgep->bmsr.value)) != NXGE_OK) 1979 goto fail; 1980 1981 statsp->mac_stats.xcvr_inits++; 1982 nxgep->bmsr.value = 0; 1983 1984 fail: 1985 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1986 "<== nxge_mii_xcvr_init status 0x%x", status)); 1987 return (status); 1988 } 1989 1990 /* Read from a MII compliant register */ 1991 1992 nxge_status_t 1993 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 1994 uint16_t *value) 1995 { 1996 npi_status_t rs = NPI_SUCCESS; 1997 1998 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 1999 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 2000 2001 MUTEX_ENTER(&nxge_mii_lock); 2002 2003 if (nxgep->mac.portmode == PORT_1G_COPPER) { 2004 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 2005 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2006 goto fail; 2007 } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 2008 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 2009 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2010 goto fail; 2011 } else 2012 goto fail; 2013 2014 MUTEX_EXIT(&nxge_mii_lock); 2015 2016 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 2017 "xcvr_reg<%d> value=0x%x", 2018 xcvr_portn, xcvr_reg, *value)); 2019 return (NXGE_OK); 2020 fail: 2021 MUTEX_EXIT(&nxge_mii_lock); 2022 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2023 "nxge_mii_read: Failed to read mii on xcvr %d", 2024 xcvr_portn)); 2025 2026 return (NXGE_ERROR | rs); 2027 } 2028 2029 /* Write to a MII compliant Register */ 2030 2031 nxge_status_t 2032 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 2033 uint16_t value) 2034 { 2035 npi_status_t rs = NPI_SUCCESS; 2036 2037 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 2038 "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, 2039 value)); 2040 2041 MUTEX_ENTER(&nxge_mii_lock); 2042 2043 if (nxgep->mac.portmode == PORT_1G_COPPER) { 2044 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 2045 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2046 goto fail; 2047 } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 2048 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 2049 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 2050 goto fail; 2051 } else 2052 goto fail; 2053 2054 MUTEX_EXIT(&nxge_mii_lock); 2055 2056 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 2057 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 2058 return (NXGE_OK); 2059 fail: 2060 MUTEX_EXIT(&nxge_mii_lock); 2061 2062 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2063 "nxge_mii_write: Failed to write mii on xcvr %d", 2064 xcvr_portn)); 2065 2066 return (NXGE_ERROR | rs); 2067 } 2068 2069 /* Perform read from Clause45 serdes / transceiver device */ 2070 2071 nxge_status_t 2072 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 2073 uint16_t xcvr_reg, uint16_t *value) 2074 { 2075 npi_status_t rs = NPI_SUCCESS; 2076 2077 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 2078 xcvr_portn)); 2079 2080 MUTEX_ENTER(&nxge_mdio_lock); 2081 2082 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 2083 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 2084 goto fail; 2085 2086 MUTEX_EXIT(&nxge_mdio_lock); 2087 2088 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 2089 xcvr_portn)); 2090 return (NXGE_OK); 2091 fail: 2092 MUTEX_EXIT(&nxge_mdio_lock); 2093 2094 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2095 "nxge_mdio_read: Failed to read mdio on xcvr %d", 2096 xcvr_portn)); 2097 2098 return (NXGE_ERROR | rs); 2099 } 2100 2101 /* Perform write to Clause45 serdes / transceiver device */ 2102 2103 nxge_status_t 2104 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 2105 uint16_t xcvr_reg, uint16_t value) 2106 { 2107 npi_status_t rs = NPI_SUCCESS; 2108 2109 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 2110 xcvr_portn)); 2111 2112 MUTEX_ENTER(&nxge_mdio_lock); 2113 2114 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 2115 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 2116 goto fail; 2117 2118 MUTEX_EXIT(&nxge_mdio_lock); 2119 2120 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 2121 xcvr_portn)); 2122 return (NXGE_OK); 2123 fail: 2124 MUTEX_EXIT(&nxge_mdio_lock); 2125 2126 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2127 "nxge_mdio_write: Failed to write mdio on xcvr %d", 2128 xcvr_portn)); 2129 2130 return (NXGE_ERROR | rs); 2131 } 2132 2133 2134 /* Check MII to see if there is any link status change */ 2135 2136 nxge_status_t 2137 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 2138 nxge_link_state_t *link_up) 2139 { 2140 p_nxge_param_t param_arr; 2141 p_nxge_stats_t statsp; 2142 p_mii_regs_t mii_regs; 2143 p_mii_bmsr_t soft_bmsr; 2144 mii_anar_t anar; 2145 mii_anlpar_t anlpar; 2146 mii_anar_t an_common; 2147 mii_aner_t aner; 2148 mii_gsr_t gsr; 2149 nxge_status_t status = NXGE_OK; 2150 2151 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 2152 2153 mii_regs = NULL; 2154 param_arr = nxgep->param_arr; 2155 statsp = nxgep->statsp; 2156 soft_bmsr = &nxgep->soft_bmsr; 2157 *link_up = LINK_NO_CHANGE; 2158 2159 if (bmsr_ints.bits.link_status) { 2160 if (bmsr.bits.link_status) { 2161 soft_bmsr->bits.link_status = 1; 2162 } else { 2163 statsp->mac_stats.link_up = 0; 2164 soft_bmsr->bits.link_status = 0; 2165 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2166 "Link down cable problem")); 2167 *link_up = LINK_IS_DOWN; 2168 } 2169 } 2170 2171 if (param_arr[param_autoneg].value) { 2172 if (bmsr_ints.bits.auto_neg_complete) { 2173 if (bmsr.bits.auto_neg_complete) 2174 soft_bmsr->bits.auto_neg_complete = 1; 2175 else 2176 soft_bmsr->bits.auto_neg_complete = 0; 2177 } 2178 if (soft_bmsr->bits.link_status == 0) { 2179 statsp->mac_stats.link_T4 = 0; 2180 statsp->mac_stats.link_speed = 0; 2181 statsp->mac_stats.link_duplex = 0; 2182 statsp->mac_stats.link_asmpause = 0; 2183 statsp->mac_stats.link_pause = 0; 2184 statsp->mac_stats.lp_cap_autoneg = 0; 2185 statsp->mac_stats.lp_cap_100T4 = 0; 2186 statsp->mac_stats.lp_cap_1000fdx = 0; 2187 statsp->mac_stats.lp_cap_1000hdx = 0; 2188 statsp->mac_stats.lp_cap_100fdx = 0; 2189 statsp->mac_stats.lp_cap_100hdx = 0; 2190 statsp->mac_stats.lp_cap_10fdx = 0; 2191 statsp->mac_stats.lp_cap_10hdx = 0; 2192 statsp->mac_stats.lp_cap_10gfdx = 0; 2193 statsp->mac_stats.lp_cap_10ghdx = 0; 2194 statsp->mac_stats.lp_cap_asmpause = 0; 2195 statsp->mac_stats.lp_cap_pause = 0; 2196 } 2197 } else 2198 soft_bmsr->bits.auto_neg_complete = 1; 2199 2200 if ((bmsr_ints.bits.link_status || 2201 bmsr_ints.bits.auto_neg_complete) && 2202 soft_bmsr->bits.link_status && 2203 soft_bmsr->bits.auto_neg_complete) { 2204 statsp->mac_stats.link_up = 1; 2205 if (param_arr[param_autoneg].value) { 2206 if ((status = nxge_mii_read(nxgep, 2207 statsp->mac_stats.xcvr_portn, 2208 (uint8_t)(uint64_t)(&mii_regs->anar), 2209 &anar.value)) != NXGE_OK) 2210 goto fail; 2211 if ((status = nxge_mii_read(nxgep, 2212 statsp->mac_stats.xcvr_portn, 2213 (uint8_t)(uint64_t)(&mii_regs->anlpar), 2214 &anlpar.value)) != NXGE_OK) 2215 goto fail; 2216 if ((status = nxge_mii_read(nxgep, 2217 statsp->mac_stats.xcvr_portn, 2218 (uint8_t)(uint64_t)(&mii_regs->aner), 2219 &aner.value)) != NXGE_OK) 2220 goto fail; 2221 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 2222 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 2223 statsp->mac_stats.lp_cap_100fdx = 2224 anlpar.bits.cap_100fdx; 2225 statsp->mac_stats.lp_cap_100hdx = 2226 anlpar.bits.cap_100hdx; 2227 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 2228 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 2229 statsp->mac_stats.lp_cap_asmpause = 2230 anlpar.bits.cap_asmpause; 2231 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 2232 an_common.value = anar.value & anlpar.value; 2233 if (param_arr[param_anar_1000fdx].value || 2234 param_arr[param_anar_1000hdx].value) { 2235 if ((status = nxge_mii_read(nxgep, 2236 statsp->mac_stats.xcvr_portn, 2237 (uint8_t)(uint64_t)(&mii_regs->gsr), 2238 &gsr.value)) 2239 != NXGE_OK) 2240 goto fail; 2241 statsp->mac_stats.lp_cap_1000fdx = 2242 gsr.bits.link_1000fdx; 2243 statsp->mac_stats.lp_cap_1000hdx = 2244 gsr.bits.link_1000hdx; 2245 if (param_arr[param_anar_1000fdx].value && 2246 gsr.bits.link_1000fdx) { 2247 statsp->mac_stats.link_speed = 1000; 2248 statsp->mac_stats.link_duplex = 2; 2249 } else if ( 2250 param_arr[param_anar_1000hdx].value && 2251 gsr.bits.link_1000hdx) { 2252 statsp->mac_stats.link_speed = 1000; 2253 statsp->mac_stats.link_duplex = 1; 2254 } 2255 } 2256 if ((an_common.value != 0) && 2257 !(statsp->mac_stats.link_speed)) { 2258 if (an_common.bits.cap_100T4) { 2259 statsp->mac_stats.link_T4 = 1; 2260 statsp->mac_stats.link_speed = 100; 2261 statsp->mac_stats.link_duplex = 1; 2262 } else if (an_common.bits.cap_100fdx) { 2263 statsp->mac_stats.link_speed = 100; 2264 statsp->mac_stats.link_duplex = 2; 2265 } else if (an_common.bits.cap_100hdx) { 2266 statsp->mac_stats.link_speed = 100; 2267 statsp->mac_stats.link_duplex = 1; 2268 } else if (an_common.bits.cap_10fdx) { 2269 statsp->mac_stats.link_speed = 10; 2270 statsp->mac_stats.link_duplex = 2; 2271 } else if (an_common.bits.cap_10hdx) { 2272 statsp->mac_stats.link_speed = 10; 2273 statsp->mac_stats.link_duplex = 1; 2274 } else { 2275 goto fail; 2276 } 2277 } 2278 if (statsp->mac_stats.link_duplex != 1) { 2279 statsp->mac_stats.link_asmpause = 2280 an_common.bits.cap_asmpause; 2281 if (statsp->mac_stats.link_asmpause) 2282 if ((statsp->mac_stats.cap_pause == 0) && 2283 (statsp->mac_stats.lp_cap_pause 2284 == 1)) 2285 statsp->mac_stats.link_pause 2286 = 0; 2287 else 2288 statsp->mac_stats.link_pause 2289 = 1; 2290 else 2291 statsp->mac_stats.link_pause = 2292 an_common.bits.cap_pause; 2293 } 2294 } 2295 *link_up = LINK_IS_UP; 2296 } 2297 2298 if (nxgep->link_notify) { 2299 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 2300 LINK_IS_DOWN); 2301 nxgep->link_notify = B_FALSE; 2302 } 2303 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 2304 return (NXGE_OK); 2305 fail: 2306 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2307 "nxge_mii_check: Unable to check MII")); 2308 return (status); 2309 } 2310 2311 /* Add a multicast address entry into the HW hash table */ 2312 2313 nxge_status_t 2314 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 2315 { 2316 uint32_t mchash; 2317 p_hash_filter_t hash_filter; 2318 uint16_t hash_bit; 2319 boolean_t rx_init = B_FALSE; 2320 uint_t j; 2321 nxge_status_t status = NXGE_OK; 2322 2323 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 2324 2325 RW_ENTER_WRITER(&nxgep->filter_lock); 2326 mchash = crc32_mchash(addrp); 2327 if (nxgep->hash_filter == NULL) { 2328 NXGE_DEBUG_MSG((NULL, STR_CTL, 2329 "Allocating hash filter storage.")); 2330 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 2331 KM_SLEEP); 2332 } 2333 hash_filter = nxgep->hash_filter; 2334 j = mchash / HASH_REG_WIDTH; 2335 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 2336 hash_filter->hash_filter_regs[j] |= hash_bit; 2337 hash_filter->hash_bit_ref_cnt[mchash]++; 2338 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 2339 hash_filter->hash_ref_cnt++; 2340 rx_init = B_TRUE; 2341 } 2342 if (rx_init) { 2343 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 2344 goto fail; 2345 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 2346 goto fail; 2347 } 2348 2349 RW_EXIT(&nxgep->filter_lock); 2350 2351 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 2352 2353 return (NXGE_OK); 2354 fail: 2355 RW_EXIT(&nxgep->filter_lock); 2356 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 2357 "Unable to add multicast address")); 2358 return (status); 2359 } 2360 2361 /* Remove a multicast address entry from the HW hash table */ 2362 2363 nxge_status_t 2364 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 2365 { 2366 uint32_t mchash; 2367 p_hash_filter_t hash_filter; 2368 uint16_t hash_bit; 2369 boolean_t rx_init = B_FALSE; 2370 uint_t j; 2371 nxge_status_t status = NXGE_OK; 2372 2373 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 2374 RW_ENTER_WRITER(&nxgep->filter_lock); 2375 mchash = crc32_mchash(addrp); 2376 if (nxgep->hash_filter == NULL) { 2377 NXGE_DEBUG_MSG((NULL, STR_CTL, 2378 "Hash filter already de_allocated.")); 2379 RW_EXIT(&nxgep->filter_lock); 2380 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 2381 return (NXGE_OK); 2382 } 2383 hash_filter = nxgep->hash_filter; 2384 hash_filter->hash_bit_ref_cnt[mchash]--; 2385 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 2386 j = mchash / HASH_REG_WIDTH; 2387 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 2388 hash_filter->hash_filter_regs[j] &= ~hash_bit; 2389 hash_filter->hash_ref_cnt--; 2390 rx_init = B_TRUE; 2391 } 2392 if (hash_filter->hash_ref_cnt == 0) { 2393 NXGE_DEBUG_MSG((NULL, STR_CTL, 2394 "De-allocating hash filter storage.")); 2395 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 2396 nxgep->hash_filter = NULL; 2397 } 2398 2399 if (rx_init) { 2400 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 2401 goto fail; 2402 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 2403 goto fail; 2404 } 2405 RW_EXIT(&nxgep->filter_lock); 2406 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 2407 2408 return (NXGE_OK); 2409 fail: 2410 RW_EXIT(&nxgep->filter_lock); 2411 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 2412 "Unable to remove multicast address")); 2413 2414 return (status); 2415 } 2416 2417 /* Set MAC address into MAC address HW registers */ 2418 2419 nxge_status_t 2420 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 2421 { 2422 nxge_status_t status = NXGE_OK; 2423 2424 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 2425 2426 MUTEX_ENTER(&nxgep->ouraddr_lock); 2427 /* 2428 * Exit if the address is same as ouraddr or multicast or broadcast 2429 */ 2430 if (((addrp->ether_addr_octet[0] & 01) == 1) || 2431 (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 2432 (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 2433 goto nxge_set_mac_addr_exit; 2434 } 2435 nxgep->ouraddr = *addrp; 2436 /* 2437 * Set new interface local address and re-init device. 2438 * This is destructive to any other streams attached 2439 * to this device. 2440 */ 2441 RW_ENTER_WRITER(&nxgep->filter_lock); 2442 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 2443 goto fail; 2444 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 2445 goto fail; 2446 2447 RW_EXIT(&nxgep->filter_lock); 2448 MUTEX_EXIT(&nxgep->ouraddr_lock); 2449 goto nxge_set_mac_addr_end; 2450 nxge_set_mac_addr_exit: 2451 MUTEX_EXIT(&nxgep->ouraddr_lock); 2452 nxge_set_mac_addr_end: 2453 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 2454 2455 return (NXGE_OK); 2456 fail: 2457 MUTEX_EXIT(&nxgep->ouraddr_lock); 2458 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 2459 "Unable to set mac address")); 2460 return (status); 2461 } 2462 2463 /* Check status of MII (MIF or PCS) link */ 2464 2465 nxge_status_t 2466 nxge_check_mii_link(p_nxge_t nxgep) 2467 { 2468 mii_bmsr_t bmsr_ints, bmsr_data; 2469 mii_anlpar_t anlpar; 2470 mii_gsr_t gsr; 2471 p_mii_regs_t mii_regs; 2472 nxge_status_t status = NXGE_OK; 2473 uint8_t portn; 2474 nxge_link_state_t link_up; 2475 2476 portn = nxgep->mac.portnum; 2477 2478 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 2479 portn)); 2480 2481 mii_regs = NULL; 2482 2483 RW_ENTER_WRITER(&nxgep->filter_lock); 2484 2485 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 2486 goto nxge_check_mii_link_exit; 2487 2488 if ((status = nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 2489 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2490 &bmsr_data.value)) != NXGE_OK) 2491 goto fail; 2492 2493 if (nxgep->param_arr[param_autoneg].value) { 2494 if ((status = nxge_mii_read(nxgep, 2495 nxgep->statsp->mac_stats.xcvr_portn, 2496 (uint8_t)(uint64_t)(&mii_regs->gsr), 2497 &gsr.value)) != NXGE_OK) 2498 goto fail; 2499 if ((status = nxge_mii_read(nxgep, 2500 nxgep->statsp->mac_stats.xcvr_portn, 2501 (uint8_t)(uint64_t)(&mii_regs->anlpar), 2502 &anlpar.value)) != NXGE_OK) 2503 goto fail; 2504 if (nxgep->statsp->mac_stats.link_up && 2505 ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 2506 gsr.bits.link_1000fdx) || 2507 (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 2508 gsr.bits.link_1000hdx) || 2509 (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 2510 anlpar.bits.cap_100T4) || 2511 (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 2512 anlpar.bits.cap_100fdx) || 2513 (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 2514 anlpar.bits.cap_100hdx) || 2515 (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 2516 anlpar.bits.cap_10fdx) || 2517 (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 2518 anlpar.bits.cap_10hdx))) { 2519 bmsr_data.bits.link_status = 0; 2520 } 2521 } 2522 2523 /* Workaround for link down issue */ 2524 if (bmsr_data.value == 0) { 2525 cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 2526 goto nxge_check_mii_link_exit; 2527 } 2528 2529 bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 2530 nxgep->bmsr.value = bmsr_data.value; 2531 if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, &link_up)) 2532 != NXGE_OK) 2533 goto fail; 2534 2535 nxge_check_mii_link_exit: 2536 RW_EXIT(&nxgep->filter_lock); 2537 if (link_up == LINK_IS_UP) { 2538 nxge_link_is_up(nxgep); 2539 } else if (link_up == LINK_IS_DOWN) { 2540 nxge_link_is_down(nxgep); 2541 } 2542 2543 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 2544 2545 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 2546 portn)); 2547 return (NXGE_OK); 2548 2549 fail: 2550 RW_EXIT(&nxgep->filter_lock); 2551 2552 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 2553 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2554 "nxge_check_mii_link: Failed to check link port<%d>", 2555 portn)); 2556 return (status); 2557 } 2558 2559 2560 /*ARGSUSED*/ 2561 nxge_status_t 2562 nxge_check_10g_link(p_nxge_t nxgep) 2563 { 2564 uint8_t portn; 2565 2566 nxge_status_t status = NXGE_OK; 2567 boolean_t link_up; 2568 2569 portn = nxgep->mac.portnum; 2570 2571 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 2572 portn)); 2573 2574 status = nxge_check_bcm8704_link(nxgep, &link_up); 2575 2576 if (status != NXGE_OK) 2577 goto fail; 2578 2579 if (link_up) { 2580 if (nxgep->link_notify || 2581 nxgep->statsp->mac_stats.link_up == 0) { 2582 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 2583 goto fail; 2584 nxgep->statsp->mac_stats.link_up = 1; 2585 nxgep->statsp->mac_stats.link_speed = 10000; 2586 nxgep->statsp->mac_stats.link_duplex = 2; 2587 2588 nxge_link_is_up(nxgep); 2589 nxgep->link_notify = B_FALSE; 2590 } 2591 } else { 2592 if (nxgep->link_notify || 2593 nxgep->statsp->mac_stats.link_up == 1) { 2594 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 2595 goto fail; 2596 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2597 "Link down cable problem")); 2598 nxgep->statsp->mac_stats.link_up = 0; 2599 nxgep->statsp->mac_stats.link_speed = 0; 2600 nxgep->statsp->mac_stats.link_duplex = 0; 2601 2602 nxge_link_is_down(nxgep); 2603 nxgep->link_notify = B_FALSE; 2604 } 2605 } 2606 2607 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 2608 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 2609 portn)); 2610 return (NXGE_OK); 2611 2612 fail: 2613 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2614 "nxge_check_10g_link: Failed to check link port<%d>", 2615 portn)); 2616 return (status); 2617 } 2618 2619 2620 /* Declare link down */ 2621 2622 void 2623 nxge_link_is_down(p_nxge_t nxgep) 2624 { 2625 p_nxge_stats_t statsp; 2626 char link_stat_msg[64]; 2627 2628 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 2629 2630 statsp = nxgep->statsp; 2631 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link down", 2632 statsp->mac_stats.xcvr_portn); 2633 2634 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 2635 2636 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 2637 } 2638 2639 /* Declare link up */ 2640 2641 void 2642 nxge_link_is_up(p_nxge_t nxgep) 2643 { 2644 p_nxge_stats_t statsp; 2645 char link_stat_msg[64]; 2646 uint32_t val; 2647 2648 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 2649 2650 statsp = nxgep->statsp; 2651 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link up %d Mbps ", 2652 statsp->mac_stats.xcvr_portn, 2653 statsp->mac_stats.link_speed); 2654 2655 if (statsp->mac_stats.link_T4) 2656 (void) strcat(link_stat_msg, "T4"); 2657 else if (statsp->mac_stats.link_duplex == 2) 2658 (void) strcat(link_stat_msg, "full duplex"); 2659 else 2660 (void) strcat(link_stat_msg, "half duplex"); 2661 2662 (void) nxge_xif_init(nxgep); 2663 2664 /* Clean up symbol errors incurred during link transition */ 2665 if (nxgep->mac.portmode == PORT_10G_FIBER) { 2666 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 2667 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 2668 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 2669 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 2670 } 2671 2672 mac_link_update(nxgep->mach, LINK_STATE_UP); 2673 2674 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 2675 } 2676 2677 /* 2678 * Calculate the bit in the multicast address filter 2679 * that selects the given * address. 2680 * Note: For GEM, the last 8-bits are used. 2681 */ 2682 uint32_t 2683 crc32_mchash(p_ether_addr_t addr) 2684 { 2685 uint8_t *cp; 2686 uint32_t crc; 2687 uint32_t c; 2688 int byte; 2689 int bit; 2690 2691 cp = (uint8_t *)addr; 2692 crc = (uint32_t)0xffffffff; 2693 for (byte = 0; byte < 6; byte++) { 2694 c = (uint32_t)cp[byte]; 2695 for (bit = 0; bit < 8; bit++) { 2696 if ((c & 0x1) ^ (crc & 0x1)) 2697 crc = (crc >> 1)^0xedb88320; 2698 else 2699 crc = (crc >> 1); 2700 c >>= 1; 2701 } 2702 } 2703 return ((~crc) >> (32 - HASH_BITS)); 2704 } 2705 2706 /* Reset serdes */ 2707 2708 nxge_status_t 2709 nxge_serdes_reset(p_nxge_t nxgep) 2710 { 2711 npi_handle_t handle; 2712 2713 handle = nxgep->npi_handle; 2714 2715 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 2716 drv_usecwait(500); 2717 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 2718 2719 return (NXGE_OK); 2720 } 2721 2722 /* Monitor link status using interrupt or polling */ 2723 2724 nxge_status_t 2725 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 2726 { 2727 nxge_status_t status = NXGE_OK; 2728 2729 /* 2730 * Make sure that we don't check the link if this happen to 2731 * be not port0 or 1 and it is not BMAC port. 2732 */ 2733 if ((nxgep->mac.portmode == PORT_10G_FIBER) && (nxgep->mac.portnum > 1)) 2734 return (NXGE_OK); 2735 2736 if (nxgep->statsp == NULL) { 2737 /* stats has not been allocated. */ 2738 return (NXGE_OK); 2739 } 2740 /* Don't check link if we're not in internal loopback mode */ 2741 if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal) 2742 return (NXGE_OK); 2743 2744 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2745 "==> nxge_link_monitor port<%d> enable=%d", 2746 nxgep->mac.portnum, enable)); 2747 if (enable == LINK_MONITOR_START) { 2748 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 2749 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 2750 != NXGE_OK) 2751 goto fail; 2752 } else { 2753 switch (nxgep->mac.portmode) { 2754 case PORT_10G_FIBER: 2755 nxgep->nxge_link_poll_timerid = timeout( 2756 (fptrv_t)nxge_check_10g_link, 2757 nxgep, 2758 drv_usectohz(1000 * 1000)); 2759 break; 2760 2761 case PORT_1G_COPPER: 2762 case PORT_1G_FIBER: 2763 nxgep->nxge_link_poll_timerid = timeout( 2764 (fptrv_t)nxge_check_mii_link, 2765 nxgep, 2766 drv_usectohz(1000 * 1000)); 2767 break; 2768 default: 2769 ; 2770 } 2771 } 2772 } else { 2773 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 2774 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 2775 != NXGE_OK) 2776 goto fail; 2777 } else { 2778 if (nxgep->nxge_link_poll_timerid != 0) { 2779 (void) untimeout(nxgep->nxge_link_poll_timerid); 2780 nxgep->nxge_link_poll_timerid = 0; 2781 } 2782 } 2783 } 2784 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2785 "<== nxge_link_monitor port<%d> enable=%d", 2786 nxgep->mac.portnum, enable)); 2787 return (NXGE_OK); 2788 fail: 2789 return (status); 2790 } 2791 2792 /* Set promiscous mode */ 2793 2794 nxge_status_t 2795 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 2796 { 2797 nxge_status_t status = NXGE_OK; 2798 2799 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2800 "==> nxge_set_promisc: on %d", on)); 2801 2802 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 2803 2804 RW_ENTER_WRITER(&nxgep->filter_lock); 2805 2806 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 2807 goto fail; 2808 } 2809 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 2810 goto fail; 2811 } 2812 2813 RW_EXIT(&nxgep->filter_lock); 2814 2815 if (on) 2816 nxgep->statsp->mac_stats.promisc = B_TRUE; 2817 else 2818 nxgep->statsp->mac_stats.promisc = B_FALSE; 2819 2820 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 2821 2822 return (NXGE_OK); 2823 fail: 2824 RW_EXIT(&nxgep->filter_lock); 2825 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 2826 "Unable to set promisc (%d)", on)); 2827 2828 return (status); 2829 } 2830 2831 /*ARGSUSED*/ 2832 uint_t 2833 nxge_mif_intr(void *arg1, void *arg2) 2834 { 2835 #ifdef NXGE_DEBUG 2836 p_nxge_t nxgep = (p_nxge_t)arg2; 2837 #endif 2838 #if NXGE_MIF 2839 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 2840 uint32_t status; 2841 npi_handle_t handle; 2842 uint8_t portn; 2843 p_nxge_stats_t statsp; 2844 #endif 2845 2846 #ifdef NXGE_MIF 2847 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 2848 nxgep = ldvp->nxgep; 2849 } 2850 nxgep = ldvp->nxgep; 2851 #endif 2852 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 2853 2854 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 2855 return (DDI_INTR_CLAIMED); 2856 2857 mif_intr_fail: 2858 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 2859 return (DDI_INTR_UNCLAIMED); 2860 } 2861 2862 /*ARGSUSED*/ 2863 uint_t 2864 nxge_mac_intr(void *arg1, void *arg2) 2865 { 2866 p_nxge_t nxgep = (p_nxge_t)arg2; 2867 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 2868 p_nxge_ldg_t ldgp; 2869 uint32_t status; 2870 npi_handle_t handle; 2871 uint8_t portn; 2872 p_nxge_stats_t statsp; 2873 npi_status_t rs = NPI_SUCCESS; 2874 2875 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 2876 nxgep = ldvp->nxgep; 2877 } 2878 2879 ldgp = ldvp->ldgp; 2880 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 2881 "group %d", ldgp->ldg)); 2882 2883 handle = NXGE_DEV_NPI_HANDLE(nxgep); 2884 /* 2885 * This interrupt handler is for a specific 2886 * mac port. 2887 */ 2888 statsp = (p_nxge_stats_t)nxgep->statsp; 2889 portn = nxgep->mac.portnum; 2890 2891 NXGE_DEBUG_MSG((nxgep, INT_CTL, 2892 "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 2893 2894 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2895 rs = npi_xmac_tx_get_istatus(handle, portn, 2896 (xmac_tx_iconfig_t *)&status); 2897 if (rs != NPI_SUCCESS) 2898 goto npi_fail; 2899 if (status & ICFG_XMAC_TX_ALL) { 2900 if (status & ICFG_XMAC_TX_UNDERRUN) { 2901 statsp->xmac_stats.tx_underflow_err++; 2902 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2903 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 2904 } 2905 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 2906 statsp->xmac_stats.tx_maxpktsize_err++; 2907 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2908 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 2909 } 2910 if (status & ICFG_XMAC_TX_OVERFLOW) { 2911 statsp->xmac_stats.tx_overflow_err++; 2912 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2913 NXGE_FM_EREPORT_TXMAC_OVERFLOW); 2914 } 2915 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 2916 statsp->xmac_stats.tx_fifo_xfr_err++; 2917 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2918 NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 2919 } 2920 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 2921 statsp->xmac_stats.tx_byte_cnt += 2922 XTXMAC_BYTE_CNT_MASK; 2923 } 2924 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 2925 statsp->xmac_stats.tx_frame_cnt += 2926 XTXMAC_FRM_CNT_MASK; 2927 } 2928 } 2929 2930 rs = npi_xmac_rx_get_istatus(handle, portn, 2931 (xmac_rx_iconfig_t *)&status); 2932 if (rs != NPI_SUCCESS) 2933 goto npi_fail; 2934 if (status & ICFG_XMAC_RX_ALL) { 2935 if (status & ICFG_XMAC_RX_OVERFLOW) 2936 statsp->xmac_stats.rx_overflow_err++; 2937 if (status & ICFG_XMAC_RX_UNDERFLOW) { 2938 statsp->xmac_stats.rx_underflow_err++; 2939 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2940 NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 2941 } 2942 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 2943 statsp->xmac_stats.rx_crc_err_cnt += 2944 XRXMAC_CRC_ER_CNT_MASK; 2945 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2946 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 2947 } 2948 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 2949 statsp->xmac_stats.rx_len_err_cnt += 2950 MAC_LEN_ER_CNT_MASK; 2951 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2952 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 2953 } 2954 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 2955 statsp->xmac_stats.rx_viol_err_cnt += 2956 XRXMAC_CD_VIO_CNT_MASK; 2957 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2958 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 2959 } 2960 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 2961 statsp->xmac_stats.rx_byte_cnt += 2962 XRXMAC_BT_CNT_MASK; 2963 } 2964 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 2965 statsp->xmac_stats.rx_hist1_cnt += 2966 XRXMAC_HIST_CNT1_MASK; 2967 } 2968 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 2969 statsp->xmac_stats.rx_hist2_cnt += 2970 XRXMAC_HIST_CNT2_MASK; 2971 } 2972 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 2973 statsp->xmac_stats.rx_hist3_cnt += 2974 XRXMAC_HIST_CNT3_MASK; 2975 } 2976 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 2977 statsp->xmac_stats.rx_hist4_cnt += 2978 XRXMAC_HIST_CNT4_MASK; 2979 } 2980 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 2981 statsp->xmac_stats.rx_hist5_cnt += 2982 XRXMAC_HIST_CNT5_MASK; 2983 } 2984 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 2985 statsp->xmac_stats.rx_hist6_cnt += 2986 XRXMAC_HIST_CNT6_MASK; 2987 } 2988 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 2989 statsp->xmac_stats.rx_broadcast_cnt += 2990 XRXMAC_BC_FRM_CNT_MASK; 2991 } 2992 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 2993 statsp->xmac_stats.rx_mult_cnt += 2994 XRXMAC_MC_FRM_CNT_MASK; 2995 } 2996 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 2997 statsp->xmac_stats.rx_frag_cnt += 2998 XRXMAC_FRAG_CNT_MASK; 2999 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3000 NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP); 3001 } 3002 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 3003 statsp->xmac_stats.rx_frame_align_err_cnt += 3004 XRXMAC_AL_ER_CNT_MASK; 3005 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3006 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 3007 } 3008 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 3009 statsp->xmac_stats.rx_linkfault_err_cnt += 3010 XMAC_LINK_FLT_CNT_MASK; 3011 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3012 NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP); 3013 } 3014 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 3015 statsp->xmac_stats.rx_remotefault_err++; 3016 } 3017 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 3018 statsp->xmac_stats.rx_localfault_err++; 3019 } 3020 } 3021 3022 rs = npi_xmac_ctl_get_istatus(handle, portn, 3023 (xmac_ctl_iconfig_t *)&status); 3024 if (rs != NPI_SUCCESS) 3025 goto npi_fail; 3026 if (status & ICFG_XMAC_CTRL_ALL) { 3027 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 3028 statsp->xmac_stats.rx_pause_cnt++; 3029 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 3030 statsp->xmac_stats.tx_pause_state++; 3031 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 3032 statsp->xmac_stats.tx_nopause_state++; 3033 } 3034 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 3035 rs = npi_bmac_tx_get_istatus(handle, portn, 3036 (bmac_tx_iconfig_t *)&status); 3037 if (rs != NPI_SUCCESS) 3038 goto npi_fail; 3039 if (status & ICFG_BMAC_TX_ALL) { 3040 if (status & ICFG_BMAC_TX_UNDERFLOW) { 3041 statsp->bmac_stats.tx_underrun_err++; 3042 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3043 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 3044 } 3045 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 3046 statsp->bmac_stats.tx_max_pkt_err++; 3047 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3048 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 3049 } 3050 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 3051 statsp->bmac_stats.tx_byte_cnt += 3052 BTXMAC_BYTE_CNT_MASK; 3053 } 3054 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 3055 statsp->bmac_stats.tx_frame_cnt += 3056 BTXMAC_FRM_CNT_MASK; 3057 } 3058 } 3059 3060 rs = npi_bmac_rx_get_istatus(handle, portn, 3061 (bmac_rx_iconfig_t *)&status); 3062 if (rs != NPI_SUCCESS) 3063 goto npi_fail; 3064 if (status & ICFG_BMAC_RX_ALL) { 3065 if (status & ICFG_BMAC_RX_OVERFLOW) { 3066 statsp->bmac_stats.rx_overflow_err++; 3067 } 3068 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 3069 statsp->bmac_stats.rx_frame_cnt += 3070 RXMAC_FRM_CNT_MASK; 3071 } 3072 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 3073 statsp->bmac_stats.rx_crc_err_cnt += 3074 BMAC_CRC_ER_CNT_MASK; 3075 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3076 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 3077 } 3078 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 3079 statsp->bmac_stats.rx_len_err_cnt += 3080 MAC_LEN_ER_CNT_MASK; 3081 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3082 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 3083 } 3084 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 3085 statsp->bmac_stats.rx_viol_err_cnt += 3086 BMAC_CD_VIO_CNT_MASK; 3087 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3088 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 3089 } 3090 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 3091 statsp->bmac_stats.rx_byte_cnt += 3092 BRXMAC_BYTE_CNT_MASK; 3093 } 3094 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 3095 statsp->bmac_stats.rx_align_err_cnt += 3096 BMAC_AL_ER_CNT_MASK; 3097 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 3098 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 3099 } 3100 3101 rs = npi_bmac_ctl_get_istatus(handle, portn, 3102 (bmac_ctl_iconfig_t *)&status); 3103 if (rs != NPI_SUCCESS) 3104 goto npi_fail; 3105 3106 if (status & ICFG_BMAC_CTL_ALL) { 3107 if (status & ICFG_BMAC_CTL_RCVPAUSE) 3108 statsp->bmac_stats.rx_pause_cnt++; 3109 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 3110 statsp->bmac_stats.tx_pause_state++; 3111 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 3112 statsp->bmac_stats.tx_nopause_state++; 3113 } 3114 } 3115 3116 if (ldgp->nldvs == 1) { 3117 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 3118 B_TRUE, ldgp->ldg_timer); 3119 } 3120 3121 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 3122 return (DDI_INTR_CLAIMED); 3123 3124 npi_fail: 3125 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 3126 return (DDI_INTR_UNCLAIMED); 3127 } 3128 3129 nxge_status_t 3130 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 3131 { 3132 uint8_t phy_port_addr; 3133 nxge_status_t status = NXGE_OK; 3134 boolean_t rx_sig_ok; 3135 boolean_t pcs_blk_lock; 3136 boolean_t link_align; 3137 uint16_t val1, val2, val3; 3138 #ifdef NXGE_DEBUG_SYMBOL_ERR 3139 uint16_t val_debug; 3140 uint16_t val; 3141 #endif 3142 3143 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 3144 3145 #ifdef NXGE_DEBUG_SYMBOL_ERR 3146 /* Check Device 3 Register Device 3 0xC809 */ 3147 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 3148 if ((val_debug & ~0x200) != 0) { 3149 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 3150 nxgep->mac.portnum, val_debug); 3151 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 3152 &val_debug); 3153 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 3154 nxgep->mac.portnum, val_debug); 3155 } 3156 3157 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3158 XPCS_REG_DESCWERR_COUNTER, &val); 3159 if (val != 0) 3160 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 3161 3162 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3163 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 3164 if (val != 0) 3165 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 3166 3167 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3168 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 3169 if (val != 0) 3170 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 3171 #endif 3172 3173 /* Check from BCM8704 if 10G link is up or down */ 3174 3175 /* Check Device 1 Register 0xA bit0 */ 3176 status = nxge_mdio_read(nxgep, phy_port_addr, 3177 BCM8704_PMA_PMD_DEV_ADDR, 3178 BCM8704_PMD_RECEIVE_SIG_DETECT, 3179 &val1); 3180 if (status != NXGE_OK) 3181 goto fail; 3182 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 3183 3184 /* Check Device 3 Register 0x20 bit0 */ 3185 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 3186 BCM8704_PCS_DEV_ADDR, 3187 BCM8704_10GBASE_R_PCS_STATUS_REG, 3188 &val2)) != NPI_SUCCESS) 3189 goto fail; 3190 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 3191 3192 /* Check Device 4 Register 0x18 bit12 */ 3193 status = nxge_mdio_read(nxgep, phy_port_addr, 3194 BCM8704_PHYXS_ADDR, 3195 BCM8704_PHYXS_XGXS_LANE_STATUS_REG, 3196 &val3); 3197 if (status != NXGE_OK) 3198 goto fail; 3199 link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 3200 XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 3201 XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 3202 3203 #ifdef NXGE_DEBUG_ALIGN_ERR 3204 /* Temp workaround for link down issue */ 3205 if (pcs_blk_lock == B_FALSE) { 3206 if (val2 != 0x4) { 3207 pcs_blk_lock = B_TRUE; 3208 cmn_err(CE_NOTE, 3209 "!LINK DEBUG: port%d PHY Dev3 " 3210 "Reg 0x20 = 0x%x\n", 3211 nxgep->mac.portnum, val2); 3212 } 3213 } 3214 3215 if (link_align == B_FALSE) { 3216 if (val3 != 0x140f) { 3217 link_align = B_TRUE; 3218 cmn_err(CE_NOTE, 3219 "!LINK DEBUG: port%d PHY Dev4 " 3220 "Reg 0x18 = 0x%x\n", 3221 nxgep->mac.portnum, val3); 3222 } 3223 } 3224 3225 if (rx_sig_ok == B_FALSE) { 3226 if ((val2 == 0) || (val3 == 0)) { 3227 rx_sig_ok = B_TRUE; 3228 cmn_err(CE_NOTE, 3229 "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 3230 nxgep->mac.portnum); 3231 } 3232 } 3233 #endif 3234 3235 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 3236 (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 3237 3238 return (NXGE_OK); 3239 fail: 3240 return (status); 3241 } 3242 3243 3244 nxge_status_t 3245 nxge_get_xcvr_type(p_nxge_t nxgep) 3246 { 3247 nxge_status_t status = NXGE_OK; 3248 3249 #if defined(_BIG_ENDIAN) 3250 char *prop_val; 3251 3252 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 3253 "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 3254 if (strcmp("xgf", prop_val) == 0) { 3255 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3256 nxgep->mac.portmode = PORT_10G_FIBER; 3257 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr")); 3258 } else if (strcmp("mif", prop_val) == 0) { 3259 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3260 nxgep->mac.portmode = PORT_1G_COPPER; 3261 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 3262 } else if (strcmp("pcs", prop_val) == 0) { 3263 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3264 nxgep->mac.portmode = PORT_1G_FIBER; 3265 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Fiber Xcvr")); 3266 } else if (strcmp("xgc", prop_val) == 0) { 3267 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3268 nxgep->mac.portmode = PORT_10G_COPPER; 3269 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 3270 } else { 3271 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3272 "Unknown phy-type: %s", 3273 prop_val)); 3274 ddi_prop_free(prop_val); 3275 return (NXGE_ERROR); 3276 } 3277 status = NXGE_OK; 3278 (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 3279 "phy-type", prop_val); 3280 ddi_prop_free(prop_val); 3281 } else { 3282 /* 3283 * This should really be an error. But for now default 3284 * this to 10G fiber. 3285 */ 3286 if (nxgep->niu_type == N2_NIU) { 3287 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3288 nxgep->mac.portmode = PORT_10G_FIBER; 3289 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3290 "Cannot find phy-type: " 3291 " Default to 10G Fiber Xcvr")); 3292 status = NXGE_OK; 3293 } else { 3294 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3295 "Cannot get phy-type")); 3296 return (NXGE_ERROR); 3297 } 3298 } 3299 #else 3300 status = nxge_espc_phy_type_get(nxgep); 3301 #endif 3302 3303 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 3304 return (status); 3305 } 3306 3307 nxge_status_t 3308 nxge_10g_link_led_on(p_nxge_t nxgep) 3309 { 3310 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 3311 != NPI_SUCCESS) 3312 return (NXGE_ERROR); 3313 else 3314 return (NXGE_OK); 3315 } 3316 3317 nxge_status_t 3318 nxge_10g_link_led_off(p_nxge_t nxgep) 3319 { 3320 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 3321 != NPI_SUCCESS) 3322 return (NXGE_ERROR); 3323 else 3324 return (NXGE_OK); 3325 } 3326