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