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