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