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 uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int); 72 static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int); 73 static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int); 74 static boolean_t nxge_is_supported_phy(uint32_t, uint8_t); 75 static nxge_status_t nxge_n2_serdes_init(p_nxge_t); 76 static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t); 77 static nxge_status_t nxge_1G_serdes_init(p_nxge_t); 78 static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t); 79 static nxge_status_t nxge_10G_link_intr_start(p_nxge_t); 80 static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t); 81 static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t); 82 static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t); 83 static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t); 84 static nxge_status_t nxge_check_mii_link(p_nxge_t); 85 static nxge_status_t nxge_check_10g_link(p_nxge_t); 86 static nxge_status_t nxge_10G_xcvr_init(p_nxge_t); 87 static nxge_status_t nxge_1G_xcvr_init(p_nxge_t); 88 static void nxge_bcm5464_link_led_off(p_nxge_t); 89 90 /* 91 * xcvr tables for supported transceivers 92 */ 93 94 static nxge_xcvr_table_t nxge_n2_10G_table = { 95 nxge_n2_serdes_init, 96 nxge_10G_xcvr_init, 97 nxge_10G_link_intr_stop, 98 nxge_10G_link_intr_start, 99 nxge_check_10g_link, 100 PCS_XCVR, 101 BCM8704_N2_PORT_ADDR_BASE 102 }; 103 104 static nxge_xcvr_table_t nxge_n2_1G_table = { 105 nxge_n2_serdes_init, 106 nxge_1G_xcvr_init, 107 nxge_1G_fiber_link_intr_stop, 108 nxge_1G_fiber_link_intr_start, 109 nxge_check_mii_link, 110 PCS_XCVR, 111 0 112 }; 113 114 static nxge_xcvr_table_t nxge_10G_fiber_table = { 115 nxge_neptune_10G_serdes_init, 116 nxge_10G_xcvr_init, 117 nxge_10G_link_intr_stop, 118 nxge_10G_link_intr_start, 119 nxge_check_10g_link, 120 PCS_XCVR, 121 BCM8704_NEPTUNE_PORT_ADDR_BASE 122 }; 123 124 static nxge_xcvr_table_t nxge_1G_copper_table = { 125 NULL, 126 nxge_1G_xcvr_init, 127 nxge_1G_copper_link_intr_stop, 128 nxge_1G_copper_link_intr_start, 129 nxge_check_mii_link, 130 INT_MII_XCVR, 131 BCM5464_NEPTUNE_PORT_ADDR_BASE 132 }; 133 134 static nxge_xcvr_table_t nxge_1G_fiber_table = { 135 nxge_1G_serdes_init, 136 nxge_1G_xcvr_init, 137 nxge_1G_fiber_link_intr_stop, 138 nxge_1G_fiber_link_intr_start, 139 nxge_check_mii_link, 140 PCS_XCVR, 141 0 142 }; 143 144 static nxge_xcvr_table_t nxge_10G_copper_table = { 145 nxge_neptune_10G_serdes_init, 146 NULL, 147 NULL, 148 NULL, 149 NULL, 150 PCS_XCVR, 151 0 152 }; 153 154 nxge_status_t nxge_mac_init(p_nxge_t); 155 156 #ifdef NXGE_DEBUG 157 static void nxge_mii_dump(p_nxge_t); 158 #endif 159 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t); 160 161 nxge_status_t 162 nxge_get_xcvr_type(p_nxge_t nxgep) 163 { 164 nxge_status_t status = NXGE_OK; 165 char *phy_type; 166 char *prop_val; 167 168 nxgep->mac.portmode = 0; 169 170 /* Get property from the driver conf. file */ 171 if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 172 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 173 "phy-type", &prop_val)) == DDI_PROP_SUCCESS) { 174 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 175 "found conf file: phy-type %s", prop_val)); 176 if (strcmp("xgsd", prop_val) == 0) { 177 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 178 nxgep->mac.portmode = PORT_10G_SERDES; 179 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 180 "found: 10G Serdes")); 181 } else if (strcmp("gsd", prop_val) == 0) { 182 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 183 nxgep->mac.portmode = PORT_1G_SERDES; 184 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes")); 185 } else if (strcmp("mif", prop_val) == 0) { 186 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 187 nxgep->mac.portmode = PORT_1G_COPPER; 188 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 189 } else if (strcmp("pcs", prop_val) == 0) { 190 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 191 nxgep->mac.portmode = PORT_1G_FIBER; 192 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr")); 193 } 194 195 (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 196 "phy-type", prop_val); 197 ddi_prop_free(prop_val); 198 199 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 200 "Got phy type [0x%x] from conf file", 201 nxgep->mac.portmode)); 202 203 return (NXGE_OK); 204 } 205 /* 206 * TODO add MDIO support for Monza RTM card, Glendale (also Goa) - 207 * only N2-NIU 208 */ 209 if (nxgep->niu_type == N2_NIU) { 210 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 211 "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 212 if (strcmp("xgf", prop_val) == 0) { 213 nxgep->statsp->mac_stats.xcvr_inuse = 214 XPCS_XCVR; 215 nxgep->mac.portmode = PORT_10G_FIBER; 216 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 217 "10G Fiber Xcvr")); 218 } else if (strcmp("mif", prop_val) == 0) { 219 nxgep->statsp->mac_stats.xcvr_inuse = 220 INT_MII_XCVR; 221 nxgep->mac.portmode = PORT_1G_COPPER; 222 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 223 "1G Copper Xcvr")); 224 } else if (strcmp("pcs", prop_val) == 0) { 225 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 226 nxgep->mac.portmode = PORT_1G_FIBER; 227 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 228 "1G Fiber Xcvr")); 229 } else if (strcmp("xgc", prop_val) == 0) { 230 nxgep->statsp->mac_stats.xcvr_inuse = 231 XPCS_XCVR; 232 nxgep->mac.portmode = PORT_10G_COPPER; 233 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 234 "10G Copper Xcvr")); 235 } else if (strcmp("xgsd", prop_val) == 0) { 236 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 237 nxgep->mac.portmode = PORT_10G_SERDES; 238 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 239 "OBP: 10G Serdes")); 240 } else if (strcmp("gsd", prop_val) == 0) { 241 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 242 nxgep->mac.portmode = PORT_1G_SERDES; 243 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 244 "OBP: 1G Serdes")); 245 } else { 246 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 247 "Unknown phy-type: %s", prop_val)); 248 ddi_prop_free(prop_val); 249 return (NXGE_ERROR); 250 } 251 status = NXGE_OK; 252 (void) ddi_prop_update_string(DDI_DEV_T_NONE, 253 nxgep->dip, "phy-type", prop_val); 254 ddi_prop_free(prop_val); 255 256 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 257 "Got phy type [0x%x] from OBP", 258 nxgep->mac.portmode)); 259 260 return (status); 261 } else { 262 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 263 "Exiting...phy-type property not found")); 264 return (NXGE_ERROR); 265 } 266 } 267 268 269 if (!nxgep->vpd_info.present) { 270 return (NXGE_OK); 271 } 272 273 if (!nxgep->vpd_info.ver_valid) { 274 goto read_seeprom; 275 } 276 277 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 278 "Reading phy type from expansion ROM")); 279 /* 280 * Try to read the phy type from the vpd data read off the 281 * expansion ROM. 282 */ 283 phy_type = nxgep->vpd_info.phy_type; 284 285 if (strncmp(phy_type, "mif", 3) == 0) { 286 nxgep->mac.portmode = PORT_1G_COPPER; 287 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 288 } else if (strncmp(phy_type, "xgf", 3) == 0) { 289 nxgep->mac.portmode = PORT_10G_FIBER; 290 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 291 } else if (strncmp(phy_type, "pcs", 3) == 0) { 292 nxgep->mac.portmode = PORT_1G_FIBER; 293 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 294 } else if (strncmp(phy_type, "xgc", 3) == 0) { 295 nxgep->mac.portmode = PORT_10G_COPPER; 296 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 297 } else if (strncmp(phy_type, "xgsd", 4) == 0) { 298 nxgep->mac.portmode = PORT_10G_SERDES; 299 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 300 } else if (strncmp(phy_type, "gsd", 3) == 0) { 301 nxgep->mac.portmode = PORT_1G_SERDES; 302 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 303 } else { 304 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 305 "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM", 306 phy_type[0], phy_type[1], phy_type[2])); 307 goto read_seeprom; 308 } 309 310 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 311 "Got phy type [0x%x] from VPD", nxgep->mac.portmode)); 312 313 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 314 return (status); 315 316 read_seeprom: 317 /* 318 * read the phy type from the SEEPROM - NCR registers 319 */ 320 status = nxge_espc_phy_type_get(nxgep); 321 if (status != NXGE_OK) { 322 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 323 "Failed to get phy type")); 324 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 325 "[%s] invalid...please update", nxgep->vpd_info.ver)); 326 } 327 328 return (status); 329 330 } 331 332 /* Set up the PHY specific values. */ 333 334 nxge_status_t 335 nxge_setup_xcvr_table(p_nxge_t nxgep) 336 { 337 nxge_status_t status = NXGE_OK; 338 uint32_t port_type; 339 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 340 uint32_t pcs_id = 0; 341 uint32_t pma_pmd_id = 0; 342 uint32_t phy_id = 0; 343 344 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>", 345 portn)); 346 347 switch (nxgep->niu_type) { 348 case N2_NIU: 349 switch (nxgep->mac.portmode) { 350 case PORT_1G_FIBER: 351 case PORT_1G_SERDES: 352 nxgep->xcvr = nxge_n2_1G_table; 353 nxgep->xcvr.xcvr_addr = portn; 354 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr", 355 (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" : 356 "Serdes")); 357 break; 358 case PORT_10G_FIBER: 359 case PORT_10G_SERDES: 360 nxgep->xcvr = nxge_n2_10G_table; 361 nxgep->xcvr.xcvr_addr += portn; 362 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr", 363 (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" : 364 "Serdes")); 365 break; 366 default: 367 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 368 "<== nxge_setup_xcvr_table: " 369 "Unable to determine NIU portmode")); 370 return (NXGE_ERROR); 371 } 372 break; 373 default: 374 if (nxgep->mac.portmode == 0) { 375 /* 376 * Would be the case for platforms like Maramba 377 * in which the phy type could not be got from conf 378 * file, OBP, VPD or Serial PROM. 379 */ 380 if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 381 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 382 "<== nxge_setup_xcvr_table:" 383 " Invalid Neptune type [0x%x]", 384 nxgep->niu_type)); 385 return (NXGE_ERROR); 386 } 387 388 port_type = nxgep->niu_type >> 389 (NXGE_PORT_TYPE_SHIFT * portn); 390 port_type = port_type & (NXGE_PORT_TYPE_MASK); 391 392 switch (port_type) { 393 394 case NXGE_PORT_1G_COPPER: 395 nxgep->mac.portmode = PORT_1G_COPPER; 396 break; 397 case NXGE_PORT_10G_COPPER: 398 nxgep->mac.portmode = PORT_10G_COPPER; 399 break; 400 case NXGE_PORT_1G_FIBRE: 401 nxgep->mac.portmode = PORT_1G_FIBER; 402 break; 403 case NXGE_PORT_10G_FIBRE: 404 nxgep->mac.portmode = PORT_10G_FIBER; 405 break; 406 case NXGE_PORT_1G_SERDES: 407 nxgep->mac.portmode = PORT_1G_SERDES; 408 break; 409 case NXGE_PORT_10G_SERDES: 410 nxgep->mac.portmode = PORT_10G_SERDES; 411 break; 412 case NXGE_PORT_1G_RGMII_FIBER: 413 nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 414 break; 415 default: 416 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 417 "<== nxge_setup_xcvr_table: " 418 "Unknown port-type: 0x%x", port_type)); 419 return (NXGE_ERROR); 420 } 421 } 422 423 switch (nxgep->mac.portmode) { 424 case PORT_1G_COPPER: 425 case PORT_1G_RGMII_FIBER: 426 nxgep->xcvr = nxge_1G_copper_table; 427 428 /* 429 * For Altas 4-1G copper, Xcvr port numbers are 430 * swapped with ethernet port number. This is 431 * designed for better signal integrity in 432 * routing. This is also the case for the 433 * on-board Neptune copper ports on the Maramba 434 * platform. 435 */ 436 switch (nxgep->platform_type) { 437 case P_NEPTUNE_MARAMBA_P1: 438 nxgep->xcvr.xcvr_addr = 439 BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 440 break; 441 case P_NEPTUNE_MARAMBA_P0: 442 nxgep->xcvr.xcvr_addr = 443 BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 444 break; 445 default: 446 break; 447 } 448 /* 449 * For Altas 4-1G copper, Xcvr port numbers are 450 * swapped with ethernet port number. This is 451 * designed for better signal integrity in 452 * routing. This is also the case for the 453 * on-board Neptune copper ports on the Maramba 454 * platform. 455 */ 456 switch (nxgep->platform_type) { 457 case P_NEPTUNE_ATLAS_4PORT: 458 case P_NEPTUNE_MARAMBA_P0: 459 case P_NEPTUNE_MARAMBA_P1: 460 switch (portn) { 461 case 0: 462 nxgep->xcvr.xcvr_addr += 3; 463 break; 464 case 1: 465 nxgep->xcvr.xcvr_addr += 2; 466 break; 467 case 2: 468 nxgep->xcvr.xcvr_addr += 1; 469 break; 470 case 3: 471 break; 472 default: 473 return (NXGE_ERROR); 474 } 475 break; 476 case P_NEPTUNE_ALONSO: 477 /* 478 * The Alonso Neptune, xcvr port numbers for 479 * ports 2 and 3 are not swapped. Port 2 has 480 * the BCM5464_PORT_BASE_ADDR and port 3 has 481 * next address. 482 */ 483 if (portn == 3) { 484 nxgep->xcvr.xcvr_addr += 1; 485 } 486 break; 487 default: 488 break; 489 } 490 491 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 492 (nxgep->mac.portmode == PORT_1G_COPPER) ? 493 "Copper" : "RGMII Fiber")); 494 break; 495 case PORT_10G_COPPER: 496 nxgep->xcvr = nxge_10G_copper_table; 497 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 498 break; 499 case PORT_1G_FIBER: 500 case PORT_1G_SERDES: 501 nxgep->xcvr = nxge_1G_fiber_table; 502 nxgep->xcvr.xcvr_addr = portn; 503 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 504 (nxgep->mac.portmode == PORT_1G_FIBER) ? 505 "Fiber" : "Serdes")); 506 break; 507 case PORT_10G_FIBER: 508 case PORT_10G_SERDES: 509 nxgep->xcvr = nxge_10G_fiber_table; 510 switch (nxgep->platform_type) { 511 case P_NEPTUNE_MARAMBA_P0: 512 case P_NEPTUNE_MARAMBA_P1: 513 nxgep->xcvr.xcvr_addr = 514 BCM8704_MARAMBA_PORT_ADDR_BASE; 515 /* 516 * Switch off LED for corresponding copper 517 * port 518 */ 519 nxge_bcm5464_link_led_off(nxgep); 520 break; 521 default: 522 break; 523 } 524 nxgep->xcvr.xcvr_addr += portn; 525 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr", 526 (nxgep->mac.portmode == PORT_10G_FIBER) ? 527 "Fiber" : "Serdes")); 528 break; 529 default: 530 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 531 "Unknown port-type: 0x%x", port_type)); 532 return (NXGE_ERROR); 533 } 534 } 535 536 nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse; 537 nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr.xcvr_addr; 538 539 /* 540 * Get the actual device ID value returned by MDIO read. 541 */ 542 nxgep->statsp->mac_stats.xcvr_id = 0; 543 544 pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr.xcvr_addr); 545 if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) { 546 nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id; 547 } else { 548 pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr.xcvr_addr); 549 if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) { 550 nxgep->statsp->mac_stats.xcvr_id = pcs_id; 551 } else { 552 phy_id = nxge_get_cl22_phy_id(nxgep, 553 nxgep->xcvr.xcvr_addr); 554 if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 555 nxgep->statsp->mac_stats.xcvr_id = phy_id; 556 } 557 } 558 } 559 560 nxgep->mac.linkchkmode = LINKCHK_TIMER; 561 562 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type" 563 "[0x%x] platform type[0x%x]", nxgep->niu_type, 564 nxgep->platform_type)); 565 566 return (status); 567 } 568 569 /* Initialize the entire MAC and physical layer */ 570 571 nxge_status_t 572 nxge_mac_init(p_nxge_t nxgep) 573 { 574 uint8_t portn; 575 nxge_status_t status = NXGE_OK; 576 577 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 578 579 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 580 581 nxgep->mac.portnum = portn; 582 nxgep->mac.porttype = PORT_TYPE_XMAC; 583 584 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 585 nxgep->mac.porttype = PORT_TYPE_BMAC; 586 587 /* Initialize XIF to configure a network mode */ 588 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 589 goto fail; 590 } 591 592 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 593 goto fail; 594 } 595 596 /* Initialize TX and RX MACs */ 597 /* 598 * Always perform XIF init first, before TX and RX MAC init 599 */ 600 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 601 goto fail; 602 603 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 604 goto fail; 605 606 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 607 goto fail; 608 609 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 610 goto fail; 611 612 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 613 goto fail; 614 615 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 616 goto fail; 617 618 /* Initialize MAC control configuration */ 619 if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) { 620 goto fail; 621 } 622 623 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 624 625 /* The Neptune Serdes needs to be reinitialized again */ 626 if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 627 ((nxgep->mac.portmode == PORT_1G_SERDES) || 628 (nxgep->mac.portmode == PORT_1G_FIBER)) && 629 ((portn == 0) || (portn == 1))) { 630 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 631 "nxge_mac_init: reinit Neptune 1G Serdes ")); 632 if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) { 633 goto fail; 634 } 635 } 636 637 638 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 639 640 return (NXGE_OK); 641 fail: 642 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 643 "nxge_mac_init: failed to initialize MAC port<%d>", 644 portn)); 645 return (status); 646 } 647 648 /* Initialize the Ethernet Link */ 649 650 nxge_status_t 651 nxge_link_init(p_nxge_t nxgep) 652 { 653 nxge_status_t status = NXGE_OK; 654 nxge_port_mode_t portmode; 655 #ifdef NXGE_DEBUG 656 uint8_t portn; 657 658 portn = nxgep->mac.portnum; 659 660 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 661 #endif 662 663 portmode = nxgep->mac.portmode; 664 if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) && 665 (portmode != PORT_1G_SERDES)) { 666 /* Workaround to get link up in both NIU ports */ 667 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) { 668 goto fail; 669 } 670 } 671 NXGE_DELAY(200000); 672 /* Initialize internal serdes */ 673 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 674 goto fail; 675 NXGE_DELAY(200000); 676 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 677 goto fail; 678 679 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 680 681 return (NXGE_OK); 682 683 fail: 684 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 685 "nxge_link_init: ", 686 "failed to initialize Ethernet link on port<%d>", 687 portn)); 688 689 return (status); 690 } 691 692 693 /* Initialize the XIF sub-block within the MAC */ 694 695 nxge_status_t 696 nxge_xif_init(p_nxge_t nxgep) 697 { 698 uint32_t xif_cfg = 0; 699 npi_attr_t ap; 700 uint8_t portn; 701 nxge_port_t portt; 702 nxge_port_mode_t portmode; 703 p_nxge_stats_t statsp; 704 npi_status_t rs = NPI_SUCCESS; 705 npi_handle_t handle; 706 707 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 708 709 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 710 711 handle = nxgep->npi_handle; 712 portmode = nxgep->mac.portmode; 713 portt = nxgep->mac.porttype; 714 statsp = nxgep->statsp; 715 716 if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 717 ((nxgep->mac.portmode == PORT_1G_SERDES) || 718 (nxgep->mac.portmode == PORT_1G_FIBER)) && 719 ((portn == 0) || (portn == 1))) { 720 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 721 "nxge_xcvr_init: set ATCA mode")); 722 npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE); 723 } 724 725 if (portt == PORT_TYPE_XMAC) { 726 727 /* Setup XIF Configuration for XMAC */ 728 729 if ((portmode == PORT_10G_FIBER) || 730 (portmode == PORT_10G_COPPER) || 731 (portmode == PORT_10G_SERDES)) 732 xif_cfg |= CFG_XMAC_XIF_LFS; 733 734 if (portmode == PORT_1G_COPPER) { 735 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 736 } 737 738 /* Set MAC Internal Loopback if necessary */ 739 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 740 xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 741 742 if (statsp->mac_stats.link_speed == 100) 743 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 744 745 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 746 747 if ((portmode == PORT_10G_FIBER) || 748 (portmode == PORT_10G_SERDES)) { 749 if (statsp->mac_stats.link_up) { 750 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 751 } else { 752 xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 753 } 754 } 755 756 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 757 if (rs != NPI_SUCCESS) 758 goto fail; 759 760 nxgep->mac.xif_config = xif_cfg; 761 762 /* Set Port Mode */ 763 if ((portmode == PORT_10G_FIBER) || 764 (portmode == PORT_10G_COPPER) || 765 (portmode == PORT_10G_SERDES)) { 766 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 767 MAC_XGMII_MODE, rs); 768 if (rs != NPI_SUCCESS) 769 goto fail; 770 if (statsp->mac_stats.link_up) { 771 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 772 goto fail; 773 } else { 774 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 775 goto fail; 776 } 777 } else if ((portmode == PORT_1G_FIBER) || 778 (portmode == PORT_1G_COPPER) || 779 (portmode == PORT_1G_SERDES) || 780 (portmode == PORT_1G_RGMII_FIBER)) { 781 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 782 "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]", 783 portn, portmode, statsp->mac_stats.link_speed)); 784 if (statsp->mac_stats.link_speed == 1000) { 785 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 786 MAC_GMII_MODE, rs); 787 } else { 788 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 789 MAC_MII_MODE, rs); 790 } 791 if (rs != NPI_SUCCESS) 792 goto fail; 793 } else { 794 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 795 "nxge_xif_init: Unknown port mode (%d)" 796 " for port<%d>", portmode, portn)); 797 goto fail; 798 } 799 800 /* Enable ATCA mode */ 801 802 } else if (portt == PORT_TYPE_BMAC) { 803 804 /* Setup XIF Configuration for BMAC */ 805 806 if ((portmode == PORT_1G_COPPER) || 807 (portmode == PORT_1G_RGMII_FIBER)) { 808 if (statsp->mac_stats.link_speed == 100) 809 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 810 } 811 812 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 813 xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 814 815 if (statsp->mac_stats.link_speed == 1000) 816 xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 817 818 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 819 820 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 821 if (rs != NPI_SUCCESS) 822 goto fail; 823 nxgep->mac.xif_config = xif_cfg; 824 } 825 826 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 827 return (NXGE_OK); 828 fail: 829 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 830 "nxge_xif_init: Failed to initialize XIF port<%d>", 831 portn)); 832 return (NXGE_ERROR | rs); 833 } 834 835 /* Initialize the PCS sub-block in the MAC */ 836 837 nxge_status_t 838 nxge_pcs_init(p_nxge_t nxgep) 839 { 840 pcs_cfg_t pcs_cfg; 841 uint32_t val; 842 uint8_t portn; 843 nxge_port_mode_t portmode; 844 npi_handle_t handle; 845 p_nxge_stats_t statsp; 846 npi_status_t rs = NPI_SUCCESS; 847 848 handle = nxgep->npi_handle; 849 portmode = nxgep->mac.portmode; 850 portn = nxgep->mac.portnum; 851 statsp = nxgep->statsp; 852 853 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 854 855 if ((portmode == PORT_1G_FIBER) || (portmode == PORT_1G_SERDES)) { 856 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) { 857 goto fail; 858 } 859 860 /* Initialize port's PCS */ 861 pcs_cfg.value = 0; 862 pcs_cfg.bits.w0.enable = 1; 863 pcs_cfg.bits.w0.mask = 1; 864 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 865 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 866 867 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 868 "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx", 869 portn, pcs_cfg.value)); 870 } else if ((portmode == PORT_10G_FIBER) || 871 (portmode == PORT_10G_COPPER) || (portmode == PORT_10G_SERDES)) { 872 /* Use internal XPCS, bypass 1G PCS */ 873 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 874 val &= ~XMAC_XIF_XPCS_BYPASS; 875 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 876 877 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 878 goto fail; 879 880 /* Set XPCS Internal Loopback if necessary */ 881 if ((rs = npi_xmac_xpcs_read(handle, portn, 882 XPCS_REG_CONTROL1, &val)) 883 != NPI_SUCCESS) 884 goto fail; 885 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 886 (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 887 val |= XPCS_CTRL1_LOOPBK; 888 else 889 val &= ~XPCS_CTRL1_LOOPBK; 890 if ((rs = npi_xmac_xpcs_write(handle, portn, 891 XPCS_REG_CONTROL1, val)) 892 != NPI_SUCCESS) 893 goto fail; 894 895 /* Clear descw errors */ 896 if ((rs = npi_xmac_xpcs_write(handle, portn, 897 XPCS_REG_DESCWERR_COUNTER, 0)) 898 != NPI_SUCCESS) 899 goto fail; 900 /* Clear symbol errors */ 901 if ((rs = npi_xmac_xpcs_read(handle, portn, 902 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) 903 != NPI_SUCCESS) 904 goto fail; 905 if ((rs = npi_xmac_xpcs_read(handle, portn, 906 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) 907 != NPI_SUCCESS) 908 goto fail; 909 910 } else if ((portmode == PORT_1G_COPPER) || 911 (portmode == PORT_1G_RGMII_FIBER)) { 912 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 913 "==> nxge_pcs_init: (1G) copper port<%d>", portn)); 914 if (portn < 4) { 915 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 916 PCS_DATAPATH_MODE_MII); 917 } 918 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 919 goto fail; 920 921 } else { 922 goto fail; 923 } 924 pass: 925 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 926 return (NXGE_OK); 927 fail: 928 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 929 "nxge_pcs_init: Failed to initialize PCS port<%d>", 930 portn)); 931 return (NXGE_ERROR | rs); 932 } 933 934 /* 935 * Initialize the MAC CTRL sub-block within the MAC 936 * Only the receive-pause-cap is supported. 937 */ 938 nxge_status_t 939 nxge_mac_ctrl_init(p_nxge_t nxgep) 940 { 941 uint8_t portn; 942 nxge_port_t portt; 943 p_nxge_stats_t statsp; 944 npi_handle_t handle; 945 uint32_t val; 946 947 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 948 949 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>", 950 portn)); 951 952 handle = nxgep->npi_handle; 953 portt = nxgep->mac.porttype; 954 statsp = nxgep->statsp; 955 956 if (portt == PORT_TYPE_XMAC) { 957 /* Readin the current XMAC Config Register for XMAC */ 958 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 959 960 /* 961 * Setup XMAC Configuration for XMAC 962 * XMAC only supports receive-pause 963 */ 964 if (statsp->mac_stats.adv_cap_asmpause) { 965 if (!statsp->mac_stats.adv_cap_pause) { 966 /* 967 * If adv_cap_asmpause is 1 and adv_cap_pause 968 * is 0, enable receive pause. 969 */ 970 val |= XMAC_RX_CFG_RX_PAUSE_EN; 971 } else { 972 /* 973 * If adv_cap_asmpause is 1 and adv_cap_pause 974 * is 1, disable receive pause. Send pause is 975 * not supported. 976 */ 977 val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 978 } 979 } else { 980 if (statsp->mac_stats.adv_cap_pause) { 981 /* 982 * If adv_cap_asmpause is 0 and adv_cap_pause 983 * is 1, enable receive pause. 984 */ 985 val |= XMAC_RX_CFG_RX_PAUSE_EN; 986 } else { 987 /* 988 * If adv_cap_asmpause is 0 and adv_cap_pause 989 * is 0, disable receive pause. Send pause is 990 * not supported 991 */ 992 val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 993 } 994 } 995 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 996 } else if (portt == PORT_TYPE_BMAC) { 997 /* Readin the current MAC CTRL Config Register for BMAC */ 998 BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val); 999 1000 /* Setup MAC CTRL Configuration for BMAC */ 1001 if (statsp->mac_stats.adv_cap_asmpause) { 1002 if (statsp->mac_stats.adv_cap_pause) { 1003 /* 1004 * If adv_cap_asmpause is 1 and adv_cap_pause 1005 * is 1, disable receive pause. Send pause 1006 * is not supported 1007 */ 1008 val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN; 1009 } else { 1010 /* 1011 * If adv_cap_asmpause is 1 and adv_cap_pause 1012 * is 0, enable receive pause and disable 1013 * send pause. 1014 */ 1015 val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 1016 val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN; 1017 } 1018 } else { 1019 if (statsp->mac_stats.adv_cap_pause) { 1020 /* 1021 * If adv_cap_asmpause is 0 and adv_cap_pause 1022 * is 1, enable receive pause. Send pause is 1023 * not supported. 1024 */ 1025 val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 1026 } else { 1027 /* 1028 * If adv_cap_asmpause is 0 and adv_cap_pause 1029 * is 0, pause capability is not available in 1030 * either direction. 1031 */ 1032 val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN & 1033 ~MAC_CTRL_CFG_RECV_PAUSE_EN); 1034 } 1035 } 1036 BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val); 1037 } 1038 1039 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>", 1040 portn)); 1041 1042 return (NXGE_OK); 1043 } 1044 1045 /* Initialize the Internal Serdes */ 1046 1047 nxge_status_t 1048 nxge_serdes_init(p_nxge_t nxgep) 1049 { 1050 p_nxge_stats_t statsp; 1051 #ifdef NXGE_DEBUG 1052 uint8_t portn; 1053 #endif 1054 nxge_status_t status = NXGE_OK; 1055 1056 #ifdef NXGE_DEBUG 1057 portn = nxgep->mac.portnum; 1058 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1059 "==> nxge_serdes_init port<%d>", portn)); 1060 #endif 1061 1062 if (nxgep->xcvr.serdes_init) { 1063 statsp = nxgep->statsp; 1064 status = nxgep->xcvr.serdes_init(nxgep); 1065 if (status != NXGE_OK) 1066 goto fail; 1067 statsp->mac_stats.serdes_inits++; 1068 } 1069 1070 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 1071 portn)); 1072 1073 return (NXGE_OK); 1074 1075 fail: 1076 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1077 "nxge_serdes_init: Failed to initialize serdes for port<%d>", 1078 portn)); 1079 1080 return (status); 1081 } 1082 1083 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 1084 1085 static nxge_status_t 1086 nxge_n2_serdes_init(p_nxge_t nxgep) 1087 { 1088 uint8_t portn; 1089 int chan; 1090 esr_ti_cfgpll_l_t pll_cfg_l; 1091 esr_ti_cfgpll_l_t pll_sts_l; 1092 esr_ti_cfgrx_l_t rx_cfg_l; 1093 esr_ti_cfgrx_h_t rx_cfg_h; 1094 esr_ti_cfgtx_l_t tx_cfg_l; 1095 esr_ti_cfgtx_h_t tx_cfg_h; 1096 #ifdef NXGE_DEBUG 1097 esr_ti_testcfg_t cfg; 1098 #endif 1099 esr_ti_testcfg_t test_cfg; 1100 nxge_status_t status = NXGE_OK; 1101 1102 portn = nxgep->mac.portnum; 1103 1104 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 1105 portn)); 1106 1107 tx_cfg_l.value = 0; 1108 tx_cfg_h.value = 0; 1109 rx_cfg_l.value = 0; 1110 rx_cfg_h.value = 0; 1111 pll_cfg_l.value = 0; 1112 pll_sts_l.value = 0; 1113 test_cfg.value = 0; 1114 1115 if ((nxgep->mac.portmode == PORT_10G_FIBER) || 1116 (nxgep->mac.portmode == PORT_10G_SERDES)) { 1117 /* 0x0E01 */ 1118 tx_cfg_l.bits.entx = 1; 1119 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 1120 1121 /* 0x9101 */ 1122 rx_cfg_l.bits.enrx = 1; 1123 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 1124 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 1125 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 1126 1127 /* 0x0008 */ 1128 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 1129 1130 /* Set loopback mode if necessary */ 1131 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 1132 tx_cfg_l.bits.entest = 1; 1133 rx_cfg_l.bits.entest = 1; 1134 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 1135 if ((status = nxge_mdio_write(nxgep, portn, 1136 ESR_N2_DEV_ADDR, 1137 ESR_N2_TEST_CFG_REG, test_cfg.value)) 1138 != NXGE_OK) 1139 goto fail; 1140 } 1141 1142 /* Use default PLL value */ 1143 1144 } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 1145 (nxgep->mac.portmode == PORT_1G_SERDES)) { 1146 1147 /* 0x0E21 */ 1148 tx_cfg_l.bits.entx = 1; 1149 tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 1150 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 1151 1152 /* 0x9121 */ 1153 rx_cfg_l.bits.enrx = 1; 1154 rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 1155 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 1156 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 1157 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 1158 1159 if (portn == 0) { 1160 /* 0x8 */ 1161 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 1162 } 1163 1164 /* MPY = 0x100 */ 1165 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 1166 1167 /* Set PLL */ 1168 pll_cfg_l.bits.enpll = 1; 1169 pll_sts_l.bits.enpll = 1; 1170 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 1171 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) 1172 != NXGE_OK) 1173 goto fail; 1174 1175 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 1176 ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 1177 goto fail; 1178 1179 #ifdef NXGE_DEBUG 1180 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 1181 ESR_N2_PLL_CFG_L_REG, &cfg.value); 1182 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1183 "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 1184 portn, pll_cfg_l.value, cfg.value)); 1185 1186 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 1187 ESR_N2_PLL_STS_L_REG, &cfg.value); 1188 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1189 "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 1190 portn, pll_sts_l.value, cfg.value)); 1191 #endif 1192 1193 /* Set loopback mode if necessary */ 1194 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 1195 tx_cfg_l.bits.entest = 1; 1196 rx_cfg_l.bits.entest = 1; 1197 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 1198 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1199 "==> nxge_n2_serdes_init port<%d>: loopback 0x%x", 1200 portn, test_cfg.value)); 1201 if ((status = nxge_mdio_write(nxgep, portn, 1202 ESR_N2_DEV_ADDR, 1203 ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) { 1204 goto fail; 1205 } 1206 } 1207 } else { 1208 goto fail; 1209 } 1210 1211 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 1212 1213 NXGE_DELAY(20); 1214 1215 /* init TX channels */ 1216 for (chan = 0; chan < 4; chan++) { 1217 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 1218 ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) 1219 != NXGE_OK) 1220 goto fail; 1221 1222 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 1223 ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) 1224 != NXGE_OK) 1225 goto fail; 1226 1227 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1228 "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x", 1229 portn, chan, tx_cfg_l.value)); 1230 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1231 "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x", 1232 portn, chan, tx_cfg_h.value)); 1233 } 1234 1235 /* init RX channels */ 1236 for (chan = 0; chan < 4; chan++) { 1237 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 1238 ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) 1239 != NXGE_OK) 1240 goto fail; 1241 1242 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 1243 ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) 1244 != NXGE_OK) 1245 goto fail; 1246 1247 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1248 "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x", 1249 portn, chan, rx_cfg_l.value)); 1250 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1251 "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x", 1252 portn, chan, rx_cfg_h.value)); 1253 } 1254 1255 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 1256 portn)); 1257 1258 return (NXGE_OK); 1259 fail: 1260 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1261 "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 1262 portn)); 1263 1264 return (status); 1265 } 1266 1267 /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */ 1268 1269 static nxge_status_t 1270 nxge_neptune_10G_serdes_init(p_nxge_t nxgep) 1271 { 1272 npi_handle_t handle; 1273 uint8_t portn; 1274 int chan; 1275 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 1276 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 1277 sr_glue_ctrl0_l_t glue_ctrl0_l; 1278 sr_glue_ctrl0_h_t glue_ctrl0_h; 1279 uint64_t val; 1280 uint16_t val16l; 1281 uint16_t val16h; 1282 nxge_status_t status = NXGE_OK; 1283 1284 portn = nxgep->mac.portnum; 1285 1286 if ((portn != 0) && (portn != 1)) 1287 return (NXGE_OK); 1288 1289 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1290 "==> nxge_neptune_10G_serdes_init port<%d>", portn)); 1291 1292 handle = nxgep->npi_handle; 1293 switch (portn) { 1294 case 0: 1295 ESR_REG_WR(handle, ESR_0_CONTROL_REG, 1296 ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 1297 ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 1298 (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 1299 (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 1300 (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 1301 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 1302 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 1303 (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 1304 (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 1305 (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 1306 (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 1307 1308 /* Set Serdes0 Internal Loopback if necessary */ 1309 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 1310 ESR_REG_WR(handle, 1311 ESR_0_TEST_CONFIG_REG, 1312 ESR_PAD_LOOPBACK_CH3 | 1313 ESR_PAD_LOOPBACK_CH2 | 1314 ESR_PAD_LOOPBACK_CH1 | 1315 ESR_PAD_LOOPBACK_CH0); 1316 } else { 1317 ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 1318 } 1319 break; 1320 case 1: 1321 ESR_REG_WR(handle, ESR_1_CONTROL_REG, 1322 ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 1323 ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 1324 (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 1325 (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 1326 (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 1327 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 1328 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 1329 (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 1330 (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 1331 (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 1332 (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 1333 1334 /* Set Serdes1 Internal Loopback if necessary */ 1335 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 1336 ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 1337 ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 | 1338 ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0); 1339 } else { 1340 ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 1341 } 1342 break; 1343 default: 1344 /* Nothing to do here */ 1345 goto done; 1346 } 1347 1348 /* init TX RX channels */ 1349 for (chan = 0; chan < 4; chan++) { 1350 if ((status = nxge_mdio_read(nxgep, portn, 1351 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 1352 &rx_tx_ctrl_l.value)) != NXGE_OK) 1353 goto fail; 1354 if ((status = nxge_mdio_read(nxgep, portn, 1355 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 1356 &rx_tx_ctrl_h.value)) != NXGE_OK) 1357 goto fail; 1358 if ((status = nxge_mdio_read(nxgep, portn, 1359 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 1360 &glue_ctrl0_l.value)) != NXGE_OK) 1361 goto fail; 1362 if ((status = nxge_mdio_read(nxgep, portn, 1363 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 1364 &glue_ctrl0_h.value)) != NXGE_OK) 1365 goto fail; 1366 rx_tx_ctrl_l.bits.enstretch = 1; 1367 rx_tx_ctrl_h.bits.vmuxlo = 2; 1368 rx_tx_ctrl_h.bits.vpulselo = 2; 1369 glue_ctrl0_l.bits.rxlosenable = 1; 1370 glue_ctrl0_l.bits.samplerate = 0xF; 1371 glue_ctrl0_l.bits.thresholdcount = 0xFF; 1372 glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 1373 if ((status = nxge_mdio_write(nxgep, portn, 1374 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 1375 rx_tx_ctrl_l.value)) != NXGE_OK) 1376 goto fail; 1377 if ((status = nxge_mdio_write(nxgep, portn, 1378 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 1379 rx_tx_ctrl_h.value)) != NXGE_OK) 1380 goto fail; 1381 if ((status = nxge_mdio_write(nxgep, portn, 1382 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 1383 glue_ctrl0_l.value)) != NXGE_OK) 1384 goto fail; 1385 if ((status = nxge_mdio_write(nxgep, portn, 1386 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 1387 glue_ctrl0_h.value)) != NXGE_OK) 1388 goto fail; 1389 } 1390 1391 /* Apply Tx core reset */ 1392 if ((status = nxge_mdio_write(nxgep, portn, 1393 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 1394 (uint16_t)0)) != NXGE_OK) 1395 goto fail; 1396 1397 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1398 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 1399 NXGE_OK) 1400 goto fail; 1401 1402 NXGE_DELAY(200); 1403 1404 /* Apply Rx core reset */ 1405 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1406 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 1407 NXGE_OK) 1408 goto fail; 1409 1410 NXGE_DELAY(200); 1411 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1412 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) 1413 goto fail; 1414 1415 NXGE_DELAY(200); 1416 if ((status = nxge_mdio_read(nxgep, portn, 1417 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 1418 &val16l)) != NXGE_OK) 1419 goto fail; 1420 if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1421 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) 1422 goto fail; 1423 if ((val16l != 0) || (val16h != 0)) { 1424 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1425 "Failed to reset port<%d> XAUI Serdes " 1426 "(val16l 0x%x val16h 0x%x)", 1427 portn, val16l, val16h)); 1428 } 1429 1430 ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 1431 1432 if (portn == 0) { 1433 if ((val & ESR_SIG_P0_BITS_MASK) != 1434 (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 1435 ESR_SIG_XSERDES_RDY_P0 | 1436 ESR_SIG_XDETECT_P0_CH3 | 1437 ESR_SIG_XDETECT_P0_CH2 | 1438 ESR_SIG_XDETECT_P0_CH1 | 1439 ESR_SIG_XDETECT_P0_CH0)) { 1440 goto fail; 1441 } 1442 } else if (portn == 1) { 1443 if ((val & ESR_SIG_P1_BITS_MASK) != 1444 (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 1445 ESR_SIG_XSERDES_RDY_P1 | 1446 ESR_SIG_XDETECT_P1_CH3 | 1447 ESR_SIG_XDETECT_P1_CH2 | 1448 ESR_SIG_XDETECT_P1_CH1 | 1449 ESR_SIG_XDETECT_P1_CH0)) { 1450 goto fail; 1451 } 1452 } 1453 1454 done: 1455 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1456 "<== nxge_neptune_10G_serdes_init port<%d>", portn)); 1457 1458 return (NXGE_OK); 1459 fail: 1460 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1461 "nxge_neptune_10G_serdes_init: " 1462 "Failed to initialize Neptune serdes for port<%d>", portn)); 1463 1464 return (status); 1465 } 1466 1467 /* Initialize Neptune Internal Serdes for 1G (Neptune only) */ 1468 1469 static nxge_status_t 1470 nxge_1G_serdes_init(p_nxge_t nxgep) 1471 { 1472 npi_handle_t handle; 1473 uint8_t portn; 1474 int chan; 1475 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 1476 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 1477 sr_glue_ctrl0_l_t glue_ctrl0_l; 1478 sr_glue_ctrl0_h_t glue_ctrl0_h; 1479 uint64_t val; 1480 uint16_t val16l; 1481 uint16_t val16h; 1482 nxge_status_t status = NXGE_OK; 1483 1484 portn = nxgep->mac.portnum; 1485 1486 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1487 "==> nxge_1G_serdes_init port<%d>", portn)); 1488 1489 handle = nxgep->npi_handle; 1490 1491 switch (portn) { 1492 case 0: 1493 /* Assert the reset register */ 1494 ESR_REG_RD(handle, ESR_RESET_REG, &val); 1495 val |= ESR_RESET_0; 1496 ESR_REG_WR(handle, ESR_RESET_REG, val); 1497 1498 /* Set the PLL register to 0x79 */ 1499 ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 1500 ESR_PLL_CFG_1G_SERDES); 1501 1502 /* Set the control register to 0x249249f */ 1503 ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES); 1504 1505 /* Set Serdes0 Internal Loopback if necessary */ 1506 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 1507 /* Set pad loopback modes 0xaa */ 1508 ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 1509 ESR_TSTCFG_LBTEST_PAD); 1510 } else { 1511 ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 1512 } 1513 1514 /* Deassert the reset register */ 1515 ESR_REG_RD(handle, ESR_RESET_REG, &val); 1516 val &= ~ESR_RESET_0; 1517 ESR_REG_WR(handle, ESR_RESET_REG, val); 1518 break; 1519 1520 case 1: 1521 /* Assert the reset register */ 1522 ESR_REG_RD(handle, ESR_RESET_REG, &val); 1523 val |= ESR_RESET_1; 1524 ESR_REG_WR(handle, ESR_RESET_REG, val); 1525 1526 /* Set PLL register to 0x79 */ 1527 ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 1528 ESR_PLL_CFG_1G_SERDES); 1529 1530 /* Set the control register to 0x249249f */ 1531 ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES); 1532 1533 /* Set Serdes1 Internal Loopback if necessary */ 1534 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 1535 /* Set pad loopback mode 0xaa */ 1536 ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 1537 ESR_TSTCFG_LBTEST_PAD); 1538 } else { 1539 ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 1540 } 1541 1542 /* Deassert the reset register */ 1543 ESR_REG_RD(handle, ESR_RESET_REG, &val); 1544 val &= ~ESR_RESET_1; 1545 ESR_REG_WR(handle, ESR_RESET_REG, val); 1546 break; 1547 1548 default: 1549 /* Nothing to do here */ 1550 goto done; 1551 } 1552 1553 /* init TX RX channels */ 1554 for (chan = 0; chan < 4; chan++) { 1555 if ((status = nxge_mdio_read(nxgep, portn, 1556 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 1557 &rx_tx_ctrl_l.value)) != NXGE_OK) { 1558 goto fail; 1559 } 1560 if ((status = nxge_mdio_read(nxgep, portn, 1561 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 1562 &rx_tx_ctrl_h.value)) != NXGE_OK) { 1563 goto fail; 1564 } 1565 if ((status = nxge_mdio_read(nxgep, portn, 1566 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 1567 &glue_ctrl0_l.value)) != NXGE_OK) { 1568 goto fail; 1569 } 1570 if ((status = nxge_mdio_read(nxgep, portn, 1571 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 1572 &glue_ctrl0_h.value)) != NXGE_OK) { 1573 goto fail; 1574 } 1575 1576 rx_tx_ctrl_l.bits.enstretch = 1; 1577 rx_tx_ctrl_h.bits.vmuxlo = 2; 1578 rx_tx_ctrl_h.bits.vpulselo = 2; 1579 glue_ctrl0_l.bits.rxlosenable = 1; 1580 glue_ctrl0_l.bits.samplerate = 0xF; 1581 glue_ctrl0_l.bits.thresholdcount = 0xFF; 1582 glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 1583 if ((status = nxge_mdio_write(nxgep, portn, 1584 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 1585 rx_tx_ctrl_l.value)) != NXGE_OK) { 1586 goto fail; 1587 } 1588 if ((status = nxge_mdio_write(nxgep, portn, 1589 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 1590 rx_tx_ctrl_h.value)) != NXGE_OK) { 1591 goto fail; 1592 } 1593 if ((status = nxge_mdio_write(nxgep, portn, 1594 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 1595 glue_ctrl0_l.value)) != NXGE_OK) { 1596 goto fail; 1597 } 1598 if ((status = nxge_mdio_write(nxgep, portn, 1599 ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 1600 glue_ctrl0_h.value)) != NXGE_OK) { 1601 goto fail; 1602 } 1603 } 1604 1605 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1606 ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) { 1607 goto fail; 1608 } 1609 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1610 ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 1611 goto fail; 1612 } 1613 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1614 ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) { 1615 goto fail; 1616 } 1617 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1618 ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 1619 goto fail; 1620 } 1621 1622 /* Apply Tx core reset */ 1623 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1624 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) { 1625 goto fail; 1626 } 1627 1628 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1629 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 1630 NXGE_OK) { 1631 goto fail; 1632 } 1633 1634 NXGE_DELAY(200); 1635 1636 /* Apply Rx core reset */ 1637 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1638 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 1639 NXGE_OK) { 1640 goto fail; 1641 } 1642 1643 NXGE_DELAY(200); 1644 if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1645 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) { 1646 goto fail; 1647 } 1648 1649 NXGE_DELAY(200); 1650 if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1651 ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) { 1652 goto fail; 1653 } 1654 if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 1655 ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) { 1656 goto fail; 1657 } 1658 if ((val16l != 0) || (val16h != 0)) { 1659 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1660 "Failed to reset port<%d> XAUI Serdes " 1661 "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h)); 1662 status = NXGE_ERROR; 1663 goto fail; 1664 } 1665 1666 NXGE_DELAY(200); 1667 ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 1668 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1669 "nxge_neptune_serdes_init: read internal signal reg port<%d> " 1670 "val 0x%x", portn, val)); 1671 if (portn == 0) { 1672 if ((val & ESR_SIG_P0_BITS_MASK_1G) != 1673 (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) { 1674 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1675 "nxge_neptune_serdes_init: " 1676 "Failed to get Serdes up for port<%d> val 0x%x", 1677 portn, (val & ESR_SIG_P0_BITS_MASK))); 1678 status = NXGE_ERROR; 1679 goto fail; 1680 } 1681 } else if (portn == 1) { 1682 if ((val & ESR_SIG_P1_BITS_MASK_1G) != 1683 (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) { 1684 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1685 "nxge_neptune_serdes_init: " 1686 "Failed to get Serdes up for port<%d> val 0x%x", 1687 portn, (val & ESR_SIG_P1_BITS_MASK))); 1688 status = NXGE_ERROR; 1689 goto fail; 1690 } 1691 } 1692 done: 1693 1694 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1695 "<== nxge_1G_serdes_init port<%d>", portn)); 1696 return (NXGE_OK); 1697 fail: 1698 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1699 "nxge_1G_serdes_init: " 1700 "Failed to initialize Neptune serdes for port<%d>", 1701 portn)); 1702 1703 return (status); 1704 } 1705 1706 /* Initialize the 10G (BCM8704) Transceiver */ 1707 1708 static nxge_status_t 1709 nxge_10G_xcvr_init(p_nxge_t nxgep) 1710 { 1711 p_nxge_stats_t statsp; 1712 uint16_t val; 1713 #ifdef NXGE_DEBUG 1714 uint8_t portn; 1715 uint16_t val1; 1716 #endif 1717 uint8_t phy_port_addr; 1718 pmd_tx_control_t tx_ctl; 1719 control_t ctl; 1720 phyxs_control_t phyxs_ctl; 1721 pcs_control_t pcs_ctl; 1722 uint32_t delay = 0; 1723 optics_dcntr_t op_ctr; 1724 nxge_status_t status = NXGE_OK; 1725 #ifdef NXGE_DEBUG 1726 portn = nxgep->mac.portnum; 1727 #endif 1728 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 1729 portn)); 1730 1731 statsp = nxgep->statsp; 1732 1733 if (nxgep->mac.portmode == PORT_10G_SERDES) { 1734 goto done; 1735 } 1736 1737 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 1738 1739 /* Disable Link LEDs */ 1740 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 1741 goto fail; 1742 1743 /* Set Clause 45 */ 1744 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 1745 1746 /* Reset the transceiver */ 1747 if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 1748 BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 1749 goto fail; 1750 1751 phyxs_ctl.bits.reset = 1; 1752 if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 1753 BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 1754 goto fail; 1755 1756 do { 1757 drv_usecwait(500); 1758 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1759 BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 1760 &phyxs_ctl.value)) != NXGE_OK) 1761 goto fail; 1762 delay++; 1763 } while ((phyxs_ctl.bits.reset) && (delay < 100)); 1764 if (delay == 100) { 1765 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 1766 "failed to reset Transceiver on port<%d>", portn)); 1767 status = NXGE_ERROR; 1768 goto fail; 1769 } 1770 1771 /* Set to 0x7FBF */ 1772 ctl.value = 0; 1773 ctl.bits.res1 = 0x3F; 1774 ctl.bits.optxon_lvl = 1; 1775 ctl.bits.oprxflt_lvl = 1; 1776 ctl.bits.optrxlos_lvl = 1; 1777 ctl.bits.optxflt_lvl = 1; 1778 ctl.bits.opprflt_lvl = 1; 1779 ctl.bits.obtmpflt_lvl = 1; 1780 ctl.bits.opbiasflt_lvl = 1; 1781 ctl.bits.optxrst_lvl = 1; 1782 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1783 BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value)) 1784 != NXGE_OK) 1785 goto fail; 1786 1787 /* Set to 0x164 */ 1788 tx_ctl.value = 0; 1789 tx_ctl.bits.tsck_lpwren = 1; 1790 tx_ctl.bits.tx_dac_txck = 0x2; 1791 tx_ctl.bits.tx_dac_txd = 0x1; 1792 tx_ctl.bits.xfp_clken = 1; 1793 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1794 BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, 1795 tx_ctl.value)) != NXGE_OK) 1796 goto fail; 1797 /* 1798 * According to Broadcom's instruction, SW needs to read 1799 * back these registers twice after written. 1800 */ 1801 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1802 BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 1803 != NXGE_OK) 1804 goto fail; 1805 1806 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1807 BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 1808 != NXGE_OK) 1809 goto fail; 1810 1811 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1812 BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 1813 != NXGE_OK) 1814 goto fail; 1815 1816 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1817 BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 1818 != NXGE_OK) 1819 goto fail; 1820 1821 /* Enable Tx and Rx LEDs to be driven by traffic */ 1822 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1823 BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1824 &op_ctr.value)) != NXGE_OK) 1825 goto fail; 1826 if (NXGE_IS_XAUI_PLATFORM(nxgep)) { 1827 op_ctr.bits.gpio_sel = 0x1; 1828 } else { 1829 op_ctr.bits.gpio_sel = 0x3; 1830 } 1831 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1832 BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1833 op_ctr.value)) != NXGE_OK) 1834 goto fail; 1835 1836 NXGE_DELAY(1000000); 1837 1838 /* Set BCM8704 Internal Loopback mode if necessary */ 1839 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1840 BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 1841 != NXGE_OK) 1842 goto fail; 1843 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 1844 pcs_ctl.bits.loopback = 1; 1845 else 1846 pcs_ctl.bits.loopback = 0; 1847 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1848 BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 1849 != NXGE_OK) 1850 goto fail; 1851 1852 status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val); 1853 if (status != NXGE_OK) 1854 goto fail; 1855 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1856 "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val)); 1857 status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 1858 if (status != NXGE_OK) 1859 goto fail; 1860 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1861 "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val)); 1862 status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 1863 if (status != NXGE_OK) 1864 goto fail; 1865 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1866 "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val)); 1867 1868 #ifdef NXGE_DEBUG 1869 /* Diagnose link issue if link is not up */ 1870 status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR, 1871 BCM8704_USER_ANALOG_STATUS0_REG, 1872 &val); 1873 if (status != NXGE_OK) 1874 goto fail; 1875 1876 status = nxge_mdio_read(nxgep, phy_port_addr, 1877 BCM8704_USER_DEV3_ADDR, 1878 BCM8704_USER_ANALOG_STATUS0_REG, 1879 &val); 1880 if (status != NXGE_OK) 1881 goto fail; 1882 1883 status = nxge_mdio_read(nxgep, phy_port_addr, 1884 BCM8704_USER_DEV3_ADDR, 1885 BCM8704_USER_TX_ALARM_STATUS_REG, 1886 &val1); 1887 if (status != NXGE_OK) 1888 goto fail; 1889 1890 status = nxge_mdio_read(nxgep, phy_port_addr, 1891 BCM8704_USER_DEV3_ADDR, 1892 BCM8704_USER_TX_ALARM_STATUS_REG, 1893 &val1); 1894 if (status != NXGE_OK) 1895 goto fail; 1896 1897 if (val != 0x3FC) { 1898 if ((val == 0x43BC) && (val1 != 0)) { 1899 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1900 "Cable not connected to peer or bad" 1901 " cable on port<%d>\n", portn)); 1902 } else if (val == 0x639C) { 1903 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1904 "Optical module (XFP) is bad or absent" 1905 " on port<%d>\n", portn)); 1906 } 1907 } 1908 #endif 1909 1910 done: 1911 statsp->mac_stats.cap_10gfdx = 1; 1912 statsp->mac_stats.lp_cap_10gfdx = 1; 1913 1914 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 1915 portn)); 1916 return (NXGE_OK); 1917 1918 fail: 1919 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1920 "nxge_10G_xcvr_init: failed to initialize transceiver for " 1921 "port<%d>", portn)); 1922 return (status); 1923 } 1924 1925 /* Initialize the 1G copper (BCM 5464) Transceiver */ 1926 1927 static nxge_status_t 1928 nxge_1G_xcvr_init(p_nxge_t nxgep) 1929 { 1930 p_nxge_param_t param_arr = nxgep->param_arr; 1931 p_nxge_stats_t statsp = nxgep->statsp; 1932 nxge_status_t status = NXGE_OK; 1933 1934 if (nxgep->mac.portmode == PORT_1G_SERDES) { 1935 statsp->mac_stats.cap_1000fdx = 1936 param_arr[param_anar_1000fdx].value; 1937 goto done; 1938 } 1939 1940 /* Set Clause 22 */ 1941 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 1942 1943 /* Set capability flags */ 1944 statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value; 1945 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 1946 (nxgep->mac.portmode == PORT_1G_FIBER)) { 1947 statsp->mac_stats.cap_100fdx = 1948 param_arr[param_anar_100fdx].value; 1949 statsp->mac_stats.cap_10fdx = 1950 param_arr[param_anar_10fdx].value; 1951 } 1952 1953 status = nxge_mii_xcvr_init(nxgep); 1954 done: 1955 return (status); 1956 } 1957 1958 /* Initialize transceiver */ 1959 1960 nxge_status_t 1961 nxge_xcvr_init(p_nxge_t nxgep) 1962 { 1963 p_nxge_stats_t statsp; 1964 #ifdef NXGE_DEBUG 1965 uint8_t portn; 1966 #endif 1967 1968 nxge_status_t status = NXGE_OK; 1969 #ifdef NXGE_DEBUG 1970 portn = nxgep->mac.portnum; 1971 #endif 1972 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 1973 statsp = nxgep->statsp; 1974 1975 /* 1976 * Initialize the xcvr statistics. 1977 */ 1978 statsp->mac_stats.cap_autoneg = 0; 1979 statsp->mac_stats.cap_100T4 = 0; 1980 statsp->mac_stats.cap_100fdx = 0; 1981 statsp->mac_stats.cap_100hdx = 0; 1982 statsp->mac_stats.cap_10fdx = 0; 1983 statsp->mac_stats.cap_10hdx = 0; 1984 statsp->mac_stats.cap_asmpause = 0; 1985 statsp->mac_stats.cap_pause = 0; 1986 statsp->mac_stats.cap_1000fdx = 0; 1987 statsp->mac_stats.cap_1000hdx = 0; 1988 statsp->mac_stats.cap_10gfdx = 0; 1989 statsp->mac_stats.cap_10ghdx = 0; 1990 1991 /* 1992 * Initialize the link statistics. 1993 */ 1994 statsp->mac_stats.link_T4 = 0; 1995 statsp->mac_stats.link_asmpause = 0; 1996 statsp->mac_stats.link_pause = 0; 1997 1998 if (nxgep->xcvr.xcvr_init) { 1999 status = nxgep->xcvr.xcvr_init(nxgep); 2000 if (status != NXGE_OK) 2001 goto fail; 2002 statsp->mac_stats.xcvr_inits++; 2003 } 2004 2005 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", 2006 portn)); 2007 return (NXGE_OK); 2008 2009 fail: 2010 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2011 "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 2012 portn)); 2013 return (status); 2014 } 2015 2016 /* Look for transceiver type */ 2017 2018 nxge_status_t 2019 nxge_xcvr_find(p_nxge_t nxgep) 2020 { 2021 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", 2022 nxgep->mac.portnum)); 2023 2024 if (nxge_get_xcvr_type(nxgep) != NXGE_OK) 2025 return (NXGE_ERROR); 2026 2027 if (nxge_setup_xcvr_table(nxgep) != NXGE_OK) 2028 return (NXGE_ERROR); 2029 2030 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d", 2031 nxgep->statsp->mac_stats.xcvr_inuse)); 2032 return (NXGE_OK); 2033 } 2034 2035 /* Initialize the TxMAC sub-block */ 2036 2037 nxge_status_t 2038 nxge_tx_mac_init(p_nxge_t nxgep) 2039 { 2040 npi_attr_t ap; 2041 uint8_t portn; 2042 nxge_port_mode_t portmode; 2043 nxge_port_t portt; 2044 npi_handle_t handle; 2045 npi_status_t rs = NPI_SUCCESS; 2046 2047 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2048 portt = nxgep->mac.porttype; 2049 handle = nxgep->npi_handle; 2050 portmode = nxgep->mac.portmode; 2051 2052 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 2053 portn)); 2054 2055 /* Set Max and Min Frame Size */ 2056 if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) { 2057 SET_MAC_ATTR2(handle, ap, portn, 2058 MAC_PORT_FRAME_SIZE, 64, 0x2400, rs); 2059 } else { 2060 /* Do not add CRC 4 bytes to the max or the min frame size */ 2061 SET_MAC_ATTR2(handle, ap, portn, 2062 MAC_PORT_FRAME_SIZE, 64, 0x5EE, rs); 2063 } 2064 2065 if (rs != NPI_SUCCESS) 2066 goto fail; 2067 if (nxgep->param_arr[param_accept_jumbo].value || 2068 nxgep->mac.is_jumbo == B_TRUE) 2069 nxgep->mac.maxframesize = 0x2400; 2070 else 2071 nxgep->mac.maxframesize = 0x5EE + 4; 2072 nxgep->mac.minframesize = 64; 2073 2074 if (portt == PORT_TYPE_XMAC) { 2075 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 2076 0)) != NPI_SUCCESS) 2077 goto fail; 2078 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 2079 if ((portmode == PORT_10G_FIBER) || 2080 (portmode == PORT_10G_COPPER) || 2081 (portmode == PORT_10G_SERDES)) { 2082 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 2083 XGMII_IPG_12_15, rs); 2084 if (rs != NPI_SUCCESS) 2085 goto fail; 2086 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 2087 } else { 2088 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 2089 MII_GMII_IPG_12, rs); 2090 if (rs != NPI_SUCCESS) 2091 goto fail; 2092 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 2093 } 2094 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 2095 CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 2096 goto fail; 2097 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 2098 nxgep->mac.maxburstsize = 0; /* not programmable */ 2099 nxgep->mac.ctrltype = 0; /* not programmable */ 2100 nxgep->mac.pa_size = 0; /* not programmable */ 2101 2102 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 2103 != NPI_SUCCESS) 2104 goto fail; 2105 2106 } else { 2107 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 2108 0)) != NPI_SUCCESS) 2109 goto fail; 2110 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 2111 2112 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 2113 rs); 2114 if (rs != NPI_SUCCESS) 2115 goto fail; 2116 nxgep->mac.ctrltype = 0x8808; 2117 2118 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 2119 if (rs != NPI_SUCCESS) 2120 goto fail; 2121 nxgep->mac.pa_size = 0x7; 2122 2123 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 2124 CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 2125 goto fail; 2126 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 2127 } 2128 2129 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 2130 portn)); 2131 2132 return (NXGE_OK); 2133 fail: 2134 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2135 "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", 2136 portn)); 2137 2138 return (NXGE_ERROR | rs); 2139 } 2140 2141 /* Initialize the RxMAC sub-block */ 2142 2143 nxge_status_t 2144 nxge_rx_mac_init(p_nxge_t nxgep) 2145 { 2146 npi_attr_t ap; 2147 uint32_t i; 2148 uint16_t hashtab_e; 2149 p_hash_filter_t hash_filter; 2150 nxge_port_t portt; 2151 uint8_t portn; 2152 npi_handle_t handle; 2153 npi_status_t rs = NPI_SUCCESS; 2154 uint16_t *addr16p; 2155 uint16_t addr0, addr1, addr2; 2156 xmac_rx_config_t xconfig; 2157 bmac_rx_config_t bconfig; 2158 2159 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2160 2161 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 2162 portn)); 2163 handle = nxgep->npi_handle; 2164 portt = nxgep->mac.porttype; 2165 2166 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 2167 addr0 = ntohs(addr16p[2]); 2168 addr1 = ntohs(addr16p[1]); 2169 addr2 = ntohs(addr16p[0]); 2170 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 2171 rs); 2172 2173 if (rs != NPI_SUCCESS) 2174 goto fail; 2175 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 2176 if (rs != NPI_SUCCESS) 2177 goto fail; 2178 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 2179 if (rs != NPI_SUCCESS) 2180 goto fail; 2181 2182 /* 2183 * Load the multicast hash filter bits. 2184 */ 2185 hash_filter = nxgep->hash_filter; 2186 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 2187 if (hash_filter != NULL) { 2188 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 2189 (NMCFILTER_REGS - 1) - i]; 2190 } else { 2191 hashtab_e = 0; 2192 } 2193 2194 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 2195 (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 2196 goto fail; 2197 } 2198 2199 if (portt == PORT_TYPE_XMAC) { 2200 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 2201 0)) != NPI_SUCCESS) 2202 goto fail; 2203 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 2204 2205 (void) nxge_fflp_init_hostinfo(nxgep); 2206 2207 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 2208 CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 2209 ~CFG_XMAC_RX_STRIP_CRC; 2210 2211 if (nxgep->filter.all_phys_cnt != 0) 2212 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 2213 2214 if (nxgep->filter.all_multicast_cnt != 0) 2215 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 2216 2217 xconfig |= CFG_XMAC_RX_HASH_FILTER; 2218 2219 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 2220 xconfig)) != NPI_SUCCESS) 2221 goto fail; 2222 nxgep->mac.rx_config = xconfig; 2223 2224 /* Comparison of mac unique address is always enabled on XMAC */ 2225 2226 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 2227 != NPI_SUCCESS) 2228 goto fail; 2229 } else { 2230 (void) nxge_fflp_init_hostinfo(nxgep); 2231 2232 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 2233 0) != NPI_SUCCESS) 2234 goto fail; 2235 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 2236 2237 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 2238 ~CFG_BMAC_RX_STRIP_CRC; 2239 2240 if (nxgep->filter.all_phys_cnt != 0) 2241 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 2242 2243 if (nxgep->filter.all_multicast_cnt != 0) 2244 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 2245 2246 bconfig |= CFG_BMAC_RX_HASH_FILTER; 2247 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 2248 bconfig)) != NPI_SUCCESS) 2249 goto fail; 2250 nxgep->mac.rx_config = bconfig; 2251 2252 /* Always enable comparison of mac unique address */ 2253 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 2254 != NPI_SUCCESS) 2255 goto fail; 2256 } 2257 2258 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 2259 portn)); 2260 2261 return (NXGE_OK); 2262 2263 fail: 2264 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2265 "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", 2266 portn)); 2267 2268 return (NXGE_ERROR | rs); 2269 } 2270 2271 /* Enable TXMAC */ 2272 2273 nxge_status_t 2274 nxge_tx_mac_enable(p_nxge_t nxgep) 2275 { 2276 npi_handle_t handle; 2277 npi_status_t rs = NPI_SUCCESS; 2278 nxge_status_t status = NXGE_OK; 2279 2280 handle = nxgep->npi_handle; 2281 2282 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 2283 nxgep->mac.portnum)); 2284 2285 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 2286 goto fail; 2287 2288 /* based on speed */ 2289 nxgep->msg_min = ETHERMIN; 2290 2291 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2292 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 2293 CFG_XMAC_TX)) != NPI_SUCCESS) 2294 goto fail; 2295 } else { 2296 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 2297 CFG_BMAC_TX)) != NPI_SUCCESS) 2298 goto fail; 2299 } 2300 2301 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 2302 nxgep->mac.portnum)); 2303 2304 return (NXGE_OK); 2305 fail: 2306 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2307 "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 2308 nxgep->mac.portnum)); 2309 if (rs != NPI_SUCCESS) 2310 return (NXGE_ERROR | rs); 2311 else 2312 return (status); 2313 } 2314 2315 /* Disable TXMAC */ 2316 2317 nxge_status_t 2318 nxge_tx_mac_disable(p_nxge_t nxgep) 2319 { 2320 npi_handle_t handle; 2321 npi_status_t rs = NPI_SUCCESS; 2322 2323 handle = nxgep->npi_handle; 2324 2325 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 2326 nxgep->mac.portnum)); 2327 2328 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2329 if ((rs = npi_xmac_tx_config(handle, DISABLE, 2330 nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 2331 goto fail; 2332 } else { 2333 if ((rs = npi_bmac_tx_config(handle, DISABLE, 2334 nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 2335 goto fail; 2336 } 2337 2338 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 2339 nxgep->mac.portnum)); 2340 return (NXGE_OK); 2341 fail: 2342 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2343 "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 2344 nxgep->mac.portnum)); 2345 return (NXGE_ERROR | rs); 2346 } 2347 2348 /* Enable RXMAC */ 2349 2350 nxge_status_t 2351 nxge_rx_mac_enable(p_nxge_t nxgep) 2352 { 2353 npi_handle_t handle; 2354 uint8_t portn; 2355 npi_status_t rs = NPI_SUCCESS; 2356 nxge_status_t status = NXGE_OK; 2357 2358 handle = nxgep->npi_handle; 2359 portn = nxgep->mac.portnum; 2360 2361 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 2362 portn)); 2363 2364 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 2365 goto fail; 2366 2367 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2368 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 2369 CFG_XMAC_RX)) != NPI_SUCCESS) 2370 goto fail; 2371 } else { 2372 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 2373 CFG_BMAC_RX)) != NPI_SUCCESS) 2374 goto fail; 2375 } 2376 2377 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>", 2378 portn)); 2379 2380 return (NXGE_OK); 2381 fail: 2382 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2383 "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", 2384 portn)); 2385 2386 if (rs != NPI_SUCCESS) 2387 return (NXGE_ERROR | rs); 2388 else 2389 return (status); 2390 } 2391 2392 /* Disable RXMAC */ 2393 2394 nxge_status_t 2395 nxge_rx_mac_disable(p_nxge_t nxgep) 2396 { 2397 npi_handle_t handle; 2398 uint8_t portn; 2399 npi_status_t rs = NPI_SUCCESS; 2400 2401 handle = nxgep->npi_handle; 2402 portn = nxgep->mac.portnum; 2403 2404 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 2405 portn)); 2406 2407 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2408 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 2409 CFG_XMAC_RX)) != NPI_SUCCESS) 2410 goto fail; 2411 } else { 2412 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 2413 CFG_BMAC_RX)) != NPI_SUCCESS) 2414 goto fail; 2415 } 2416 2417 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 2418 portn)); 2419 return (NXGE_OK); 2420 fail: 2421 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2422 "nxgep_rx_mac_disable: ", 2423 "Failed to disable port<%d> RxMAC", 2424 portn)); 2425 2426 return (NXGE_ERROR | rs); 2427 } 2428 2429 /* Reset TXMAC */ 2430 2431 nxge_status_t 2432 nxge_tx_mac_reset(p_nxge_t nxgep) 2433 { 2434 npi_handle_t handle; 2435 uint8_t portn; 2436 npi_status_t rs = NPI_SUCCESS; 2437 2438 handle = nxgep->npi_handle; 2439 portn = nxgep->mac.portnum; 2440 2441 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 2442 portn)); 2443 2444 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2445 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 2446 != NPI_SUCCESS) 2447 goto fail; 2448 } else { 2449 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 2450 != NPI_SUCCESS) 2451 goto fail; 2452 } 2453 2454 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 2455 portn)); 2456 2457 return (NXGE_OK); 2458 fail: 2459 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2460 "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", 2461 portn)); 2462 2463 return (NXGE_ERROR | rs); 2464 } 2465 2466 /* Reset RXMAC */ 2467 2468 nxge_status_t 2469 nxge_rx_mac_reset(p_nxge_t nxgep) 2470 { 2471 npi_handle_t handle; 2472 uint8_t portn; 2473 npi_status_t rs = NPI_SUCCESS; 2474 2475 handle = nxgep->npi_handle; 2476 portn = nxgep->mac.portnum; 2477 2478 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 2479 portn)); 2480 2481 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2482 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 2483 != NPI_SUCCESS) 2484 goto fail; 2485 } else { 2486 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 2487 != NPI_SUCCESS) 2488 goto fail; 2489 } 2490 2491 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 2492 portn)); 2493 2494 return (NXGE_OK); 2495 fail: 2496 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2497 "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", 2498 portn)); 2499 return (NXGE_ERROR | rs); 2500 } 2501 2502 /* 10G fiber link interrupt start routine */ 2503 2504 static nxge_status_t 2505 nxge_10G_link_intr_start(p_nxge_t nxgep) 2506 { 2507 npi_status_t rs = NPI_SUCCESS; 2508 uint8_t portn = nxgep->mac.portnum; 2509 2510 rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 2511 2512 if (rs != NPI_SUCCESS) 2513 return (NXGE_ERROR | rs); 2514 else 2515 return (NXGE_OK); 2516 } 2517 2518 /* 10G fiber link interrupt stop routine */ 2519 2520 static nxge_status_t 2521 nxge_10G_link_intr_stop(p_nxge_t nxgep) 2522 { 2523 npi_status_t rs = NPI_SUCCESS; 2524 uint8_t portn = nxgep->mac.portnum; 2525 2526 rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 2527 2528 if (rs != NPI_SUCCESS) 2529 return (NXGE_ERROR | rs); 2530 else 2531 return (NXGE_OK); 2532 } 2533 2534 /* 1G fiber link interrupt start routine */ 2535 2536 static nxge_status_t 2537 nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 2538 { 2539 npi_status_t rs = NPI_SUCCESS; 2540 uint8_t portn = nxgep->mac.portnum; 2541 2542 rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 2543 if (rs != NPI_SUCCESS) 2544 return (NXGE_ERROR | rs); 2545 else 2546 return (NXGE_OK); 2547 } 2548 2549 /* 1G fiber link interrupt stop routine */ 2550 2551 static nxge_status_t 2552 nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 2553 { 2554 npi_status_t rs = NPI_SUCCESS; 2555 uint8_t portn = nxgep->mac.portnum; 2556 2557 rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 2558 2559 if (rs != NPI_SUCCESS) 2560 return (NXGE_ERROR | rs); 2561 else 2562 return (NXGE_OK); 2563 } 2564 2565 /* 1G copper link interrupt start routine */ 2566 2567 static nxge_status_t 2568 nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 2569 { 2570 npi_status_t rs = NPI_SUCCESS; 2571 uint8_t portn = nxgep->mac.portnum; 2572 2573 rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 2574 MII_STATUS, MII_STATUS_LINKUP); 2575 2576 if (rs != NPI_SUCCESS) 2577 return (NXGE_ERROR | rs); 2578 else 2579 return (NXGE_OK); 2580 } 2581 2582 /* 1G copper link interrupt stop routine */ 2583 2584 static nxge_status_t 2585 nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 2586 { 2587 npi_status_t rs = NPI_SUCCESS; 2588 uint8_t portn = nxgep->mac.portnum; 2589 2590 rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 2591 2592 if (rs != NPI_SUCCESS) 2593 return (NXGE_ERROR | rs); 2594 else 2595 return (NXGE_OK); 2596 } 2597 2598 /* Enable/Disable Link Status change interrupt */ 2599 2600 nxge_status_t 2601 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 2602 { 2603 uint8_t portn; 2604 nxge_status_t status = NXGE_OK; 2605 2606 portn = nxgep->mac.portnum; 2607 2608 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 2609 if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 2610 return (NXGE_OK); 2611 2612 if (enable == LINK_INTR_START) 2613 status = nxgep->xcvr.link_intr_start(nxgep); 2614 else if (enable == LINK_INTR_STOP) 2615 status = nxgep->xcvr.link_intr_stop(nxgep); 2616 if (status != NXGE_OK) 2617 goto fail; 2618 2619 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 2620 2621 return (NXGE_OK); 2622 fail: 2623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2624 "nxge_link_intr: Failed to set port<%d> mif intr mode", 2625 portn)); 2626 2627 return (status); 2628 } 2629 2630 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 2631 2632 nxge_status_t 2633 nxge_mii_xcvr_init(p_nxge_t nxgep) 2634 { 2635 p_nxge_param_t param_arr; 2636 p_nxge_stats_t statsp; 2637 uint8_t xcvr_portn; 2638 p_mii_regs_t mii_regs; 2639 mii_bmcr_t bmcr; 2640 mii_bmsr_t bmsr; 2641 mii_anar_t anar; 2642 mii_gcr_t gcr; 2643 mii_esr_t esr; 2644 mii_aux_ctl_t bcm5464r_aux; 2645 int status = NXGE_OK; 2646 2647 uint_t delay; 2648 2649 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 2650 2651 param_arr = nxgep->param_arr; 2652 statsp = nxgep->statsp; 2653 xcvr_portn = statsp->mac_stats.xcvr_portn; 2654 2655 mii_regs = NULL; 2656 2657 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2658 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 2659 2660 /* 2661 * The mif phy mode may be connected to either a copper link 2662 * or fiber link. Read the mode control register to get the fiber 2663 * configuration if it is hard-wired to fiber link. 2664 */ 2665 (void) nxge_mii_get_link_mode(nxgep); 2666 if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 2667 return (nxge_mii_xcvr_fiber_init(nxgep)); 2668 } 2669 2670 /* 2671 * Reset the transceiver. 2672 */ 2673 delay = 0; 2674 bmcr.value = 0; 2675 bmcr.bits.reset = 1; 2676 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2677 #if defined(__i386) 2678 (uint8_t)(uint32_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 2679 #else 2680 (uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 2681 #endif 2682 goto fail; 2683 do { 2684 drv_usecwait(500); 2685 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2686 #if defined(__i386) 2687 (uint8_t)(uint32_t)&mii_regs->bmcr, &bmcr.value)) 2688 #else 2689 (uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value)) 2690 #endif 2691 != NXGE_OK) 2692 goto fail; 2693 delay++; 2694 } while ((bmcr.bits.reset) && (delay < 1000)); 2695 if (delay == 1000) { 2696 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 2697 goto fail; 2698 } 2699 2700 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2701 #if defined(__i386) 2702 (uint8_t)(uint32_t)(&mii_regs->bmsr), 2703 #else 2704 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2705 #endif 2706 &bmsr.value)) != NXGE_OK) 2707 goto fail; 2708 2709 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 2710 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 2711 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 2712 param_arr[param_anar_100hdx].value = 0; 2713 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 2714 param_arr[param_anar_10hdx].value = 0; 2715 2716 /* 2717 * Initialize the xcvr statistics. 2718 */ 2719 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 2720 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 2721 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 2722 statsp->mac_stats.cap_100hdx = 0; 2723 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 2724 statsp->mac_stats.cap_10hdx = 0; 2725 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 2726 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 2727 2728 /* 2729 * Initialise the xcvr advertised capability statistics. 2730 */ 2731 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 2732 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 2733 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 2734 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 2735 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 2736 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 2737 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 2738 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 2739 statsp->mac_stats.adv_cap_asmpause = 2740 param_arr[param_anar_asmpause].value; 2741 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 2742 2743 2744 /* 2745 * Check for extended status just in case we're 2746 * running a Gigibit phy. 2747 */ 2748 if (bmsr.bits.extend_status) { 2749 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2750 #if defined(__i386) 2751 (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) 2752 #else 2753 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) 2754 #endif 2755 != NXGE_OK) 2756 goto fail; 2757 param_arr[param_anar_1000fdx].value &= 2758 esr.bits.link_1000fdx; 2759 param_arr[param_anar_1000hdx].value = 0; 2760 2761 statsp->mac_stats.cap_1000fdx = 2762 (esr.bits.link_1000Xfdx || 2763 esr.bits.link_1000fdx); 2764 statsp->mac_stats.cap_1000hdx = 0; 2765 } else { 2766 param_arr[param_anar_1000fdx].value = 0; 2767 param_arr[param_anar_1000hdx].value = 0; 2768 } 2769 2770 /* 2771 * Initialize 1G Statistics once the capability is established. 2772 */ 2773 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 2774 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 2775 2776 /* 2777 * Initialise the link statistics. 2778 */ 2779 statsp->mac_stats.link_T4 = 0; 2780 statsp->mac_stats.link_asmpause = 0; 2781 statsp->mac_stats.link_pause = 0; 2782 statsp->mac_stats.link_speed = 0; 2783 statsp->mac_stats.link_duplex = 0; 2784 statsp->mac_stats.link_up = 0; 2785 2786 /* 2787 * Switch off Auto-negotiation, 100M and full duplex. 2788 */ 2789 bmcr.value = 0; 2790 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2791 #if defined(__i386) 2792 (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 2793 #else 2794 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 2795 #endif 2796 goto fail; 2797 2798 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 2799 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 2800 bmcr.bits.loopback = 1; 2801 bmcr.bits.enable_autoneg = 0; 2802 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 2803 bmcr.bits.speed_1000_sel = 1; 2804 bmcr.bits.duplex_mode = 1; 2805 param_arr[param_autoneg].value = 0; 2806 } else { 2807 bmcr.bits.loopback = 0; 2808 } 2809 2810 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 2811 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 2812 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 2813 param_arr[param_autoneg].value = 0; 2814 bcm5464r_aux.value = 0; 2815 bcm5464r_aux.bits.ext_lb = 1; 2816 bcm5464r_aux.bits.write_1 = 1; 2817 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2818 BCM5464R_AUX_CTL, bcm5464r_aux.value)) 2819 != NXGE_OK) 2820 goto fail; 2821 } 2822 2823 if (param_arr[param_autoneg].value) { 2824 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2825 "Restarting Auto-negotiation.")); 2826 /* 2827 * Setup our Auto-negotiation advertisement register. 2828 */ 2829 anar.value = 0; 2830 anar.bits.selector = 1; 2831 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 2832 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 2833 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 2834 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 2835 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 2836 anar.bits.cap_asmpause = 0; 2837 anar.bits.cap_pause = 0; 2838 if (param_arr[param_anar_1000fdx].value || 2839 param_arr[param_anar_100fdx].value || 2840 param_arr[param_anar_10fdx].value) { 2841 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 2842 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 2843 } 2844 2845 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2846 #if defined(__i386) 2847 (uint8_t)(uint32_t)(&mii_regs->anar), anar.value)) 2848 #else 2849 (uint8_t)(uint64_t)(&mii_regs->anar), anar.value)) 2850 #endif 2851 != NXGE_OK) 2852 goto fail; 2853 if (bmsr.bits.extend_status) { 2854 gcr.value = 0; 2855 gcr.bits.ms_mode_en = 2856 param_arr[param_master_cfg_enable].value; 2857 gcr.bits.master = 2858 param_arr[param_master_cfg_value].value; 2859 gcr.bits.link_1000fdx = 2860 param_arr[param_anar_1000fdx].value; 2861 gcr.bits.link_1000hdx = 2862 param_arr[param_anar_1000hdx].value; 2863 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2864 #if defined(__i386) 2865 (uint8_t)(uint32_t)(&mii_regs->gcr), gcr.value)) 2866 #else 2867 (uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value)) 2868 #endif 2869 != NXGE_OK) 2870 goto fail; 2871 } 2872 2873 bmcr.bits.enable_autoneg = 1; 2874 bmcr.bits.restart_autoneg = 1; 2875 2876 } else { 2877 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 2878 bmcr.bits.speed_1000_sel = 2879 param_arr[param_anar_1000fdx].value | 2880 param_arr[param_anar_1000hdx].value; 2881 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 2882 (param_arr[param_anar_100fdx].value | 2883 param_arr[param_anar_100hdx].value); 2884 if (bmcr.bits.speed_1000_sel) { 2885 statsp->mac_stats.link_speed = 1000; 2886 gcr.value = 0; 2887 gcr.bits.ms_mode_en = 2888 param_arr[param_master_cfg_enable].value; 2889 gcr.bits.master = 2890 param_arr[param_master_cfg_value].value; 2891 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2892 #if defined(__i386) 2893 (uint8_t)(uint32_t)(&mii_regs->gcr), 2894 #else 2895 (uint8_t)(uint64_t)(&mii_regs->gcr), 2896 #endif 2897 gcr.value)) 2898 != NXGE_OK) 2899 goto fail; 2900 if (param_arr[param_anar_1000fdx].value) { 2901 bmcr.bits.duplex_mode = 1; 2902 statsp->mac_stats.link_duplex = 2; 2903 } else 2904 statsp->mac_stats.link_duplex = 1; 2905 } else if (bmcr.bits.speed_sel) { 2906 statsp->mac_stats.link_speed = 100; 2907 if (param_arr[param_anar_100fdx].value) { 2908 bmcr.bits.duplex_mode = 1; 2909 statsp->mac_stats.link_duplex = 2; 2910 } else 2911 statsp->mac_stats.link_duplex = 1; 2912 } else { 2913 statsp->mac_stats.link_speed = 10; 2914 if (param_arr[param_anar_10fdx].value) { 2915 bmcr.bits.duplex_mode = 1; 2916 statsp->mac_stats.link_duplex = 2; 2917 } else 2918 statsp->mac_stats.link_duplex = 1; 2919 } 2920 if (statsp->mac_stats.link_duplex != 1) { 2921 statsp->mac_stats.link_asmpause = 2922 statsp->mac_stats.cap_asmpause; 2923 statsp->mac_stats.link_pause = 2924 statsp->mac_stats.cap_pause; 2925 } 2926 2927 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 2928 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 2929 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 2930 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 2931 /* BCM5464R 1000mbps external loopback mode */ 2932 gcr.value = 0; 2933 gcr.bits.ms_mode_en = 1; 2934 gcr.bits.master = 1; 2935 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2936 #if defined(__i386) 2937 (uint8_t)(uint32_t)(&mii_regs->gcr), 2938 #else 2939 (uint8_t)(uint64_t)(&mii_regs->gcr), 2940 #endif 2941 gcr.value)) 2942 != NXGE_OK) 2943 goto fail; 2944 bmcr.value = 0; 2945 bmcr.bits.speed_1000_sel = 1; 2946 statsp->mac_stats.link_speed = 1000; 2947 } else if (statsp->port_stats.lb_mode 2948 == nxge_lb_ext100) { 2949 /* BCM5464R 100mbps external loopback mode */ 2950 bmcr.value = 0; 2951 bmcr.bits.speed_sel = 1; 2952 bmcr.bits.duplex_mode = 1; 2953 statsp->mac_stats.link_speed = 100; 2954 } else if (statsp->port_stats.lb_mode 2955 == nxge_lb_ext10) { 2956 /* BCM5464R 10mbps external loopback mode */ 2957 bmcr.value = 0; 2958 bmcr.bits.duplex_mode = 1; 2959 statsp->mac_stats.link_speed = 10; 2960 } 2961 } 2962 } 2963 2964 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2965 #if defined(__i386) 2966 (uint8_t)(uint32_t)(&mii_regs->bmcr), 2967 #else 2968 (uint8_t)(uint64_t)(&mii_regs->bmcr), 2969 #endif 2970 bmcr.value)) != NXGE_OK) 2971 goto fail; 2972 2973 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2974 #if defined(__i386) 2975 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 2976 #else 2977 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 2978 #endif 2979 goto fail; 2980 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 2981 2982 /* 2983 * Initialize the xcvr status kept in the context structure. 2984 */ 2985 nxgep->soft_bmsr.value = 0; 2986 2987 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2988 #if defined(__i386) 2989 (uint8_t)(uint32_t)(&mii_regs->bmsr), 2990 #else 2991 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2992 #endif 2993 &nxgep->bmsr.value)) != NXGE_OK) 2994 goto fail; 2995 2996 statsp->mac_stats.xcvr_inits++; 2997 nxgep->bmsr.value = 0; 2998 2999 fail: 3000 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3001 "<== nxge_mii_xcvr_init status 0x%x", status)); 3002 return (status); 3003 } 3004 3005 nxge_status_t 3006 nxge_mii_xcvr_fiber_init(p_nxge_t nxgep) 3007 { 3008 p_nxge_param_t param_arr; 3009 p_nxge_stats_t statsp; 3010 uint8_t xcvr_portn; 3011 p_mii_regs_t mii_regs; 3012 mii_bmcr_t bmcr; 3013 mii_bmsr_t bmsr; 3014 mii_gcr_t gcr; 3015 mii_esr_t esr; 3016 mii_aux_ctl_t bcm5464r_aux; 3017 int status = NXGE_OK; 3018 3019 uint_t delay; 3020 3021 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init")); 3022 3023 param_arr = nxgep->param_arr; 3024 statsp = nxgep->statsp; 3025 xcvr_portn = statsp->mac_stats.xcvr_portn; 3026 3027 mii_regs = NULL; 3028 3029 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3030 "nxge_mii_xcvr_fiber_init: " 3031 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 3032 3033 /* 3034 * Reset the transceiver. 3035 */ 3036 delay = 0; 3037 bmcr.value = 0; 3038 bmcr.bits.reset = 1; 3039 3040 #if defined(__i386) 3041 3042 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3043 (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 3044 goto fail; 3045 #else 3046 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3047 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 3048 goto fail; 3049 #endif 3050 do { 3051 drv_usecwait(500); 3052 #if defined(__i386) 3053 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3054 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) 3055 != NXGE_OK) 3056 goto fail; 3057 #else 3058 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3059 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) 3060 != NXGE_OK) 3061 goto fail; 3062 #endif 3063 delay++; 3064 } while ((bmcr.bits.reset) && (delay < 1000)); 3065 if (delay == 1000) { 3066 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 3067 goto fail; 3068 } 3069 3070 #if defined(__i386) 3071 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3072 (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 3073 goto fail; 3074 #else 3075 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3076 (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 3077 goto fail; 3078 #endif 3079 3080 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 3081 param_arr[param_anar_100T4].value = 0; 3082 param_arr[param_anar_100fdx].value = 0; 3083 param_arr[param_anar_100hdx].value = 0; 3084 param_arr[param_anar_10fdx].value = 0; 3085 param_arr[param_anar_10hdx].value = 0; 3086 3087 /* 3088 * Initialize the xcvr statistics. 3089 */ 3090 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 3091 statsp->mac_stats.cap_100T4 = 0; 3092 statsp->mac_stats.cap_100fdx = 0; 3093 statsp->mac_stats.cap_100hdx = 0; 3094 statsp->mac_stats.cap_10fdx = 0; 3095 statsp->mac_stats.cap_10hdx = 0; 3096 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 3097 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 3098 3099 /* 3100 * Initialize the xcvr advertised capability statistics. 3101 */ 3102 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 3103 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 3104 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 3105 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 3106 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 3107 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 3108 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 3109 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 3110 statsp->mac_stats.adv_cap_asmpause = 3111 param_arr[param_anar_asmpause].value; 3112 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 3113 3114 /* 3115 * Check for extended status just in case we're 3116 * running a Gigibit phy. 3117 */ 3118 if (bmsr.bits.extend_status) { 3119 #if defined(__i386) 3120 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3121 (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) != 3122 NXGE_OK) 3123 goto fail; 3124 #else 3125 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3126 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) != 3127 NXGE_OK) 3128 goto fail; 3129 #endif 3130 param_arr[param_anar_1000fdx].value &= 3131 esr.bits.link_1000fdx; 3132 param_arr[param_anar_1000hdx].value = 0; 3133 3134 statsp->mac_stats.cap_1000fdx = 3135 (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 3136 statsp->mac_stats.cap_1000hdx = 0; 3137 } else { 3138 param_arr[param_anar_1000fdx].value = 0; 3139 param_arr[param_anar_1000hdx].value = 0; 3140 } 3141 3142 /* 3143 * Initialize 1G Statistics once the capability is established. 3144 */ 3145 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 3146 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 3147 3148 /* 3149 * Initialize the link statistics. 3150 */ 3151 statsp->mac_stats.link_T4 = 0; 3152 statsp->mac_stats.link_asmpause = 0; 3153 statsp->mac_stats.link_pause = 0; 3154 statsp->mac_stats.link_speed = 0; 3155 statsp->mac_stats.link_duplex = 0; 3156 statsp->mac_stats.link_up = 0; 3157 3158 /* 3159 * Switch off Auto-negotiation, 100M and full duplex. 3160 */ 3161 bmcr.value = 0; 3162 #if defined(__i386) 3163 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3164 (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 3165 goto fail; 3166 #else 3167 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3168 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 3169 goto fail; 3170 #endif 3171 3172 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 3173 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 3174 bmcr.bits.loopback = 1; 3175 bmcr.bits.enable_autoneg = 0; 3176 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 3177 bmcr.bits.speed_1000_sel = 1; 3178 bmcr.bits.duplex_mode = 1; 3179 param_arr[param_autoneg].value = 0; 3180 } else { 3181 bmcr.bits.loopback = 0; 3182 } 3183 3184 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 3185 param_arr[param_autoneg].value = 0; 3186 bcm5464r_aux.value = 0; 3187 bcm5464r_aux.bits.ext_lb = 1; 3188 bcm5464r_aux.bits.write_1 = 1; 3189 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3190 BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 3191 goto fail; 3192 } 3193 3194 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 3195 bmcr.bits.speed_1000_sel = 1; 3196 bmcr.bits.speed_sel = 0; 3197 bmcr.bits.duplex_mode = 1; 3198 statsp->mac_stats.link_speed = 1000; 3199 statsp->mac_stats.link_duplex = 2; 3200 3201 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) { 3202 /* BCM5464R 1000mbps external loopback mode */ 3203 gcr.value = 0; 3204 gcr.bits.ms_mode_en = 1; 3205 gcr.bits.master = 1; 3206 #if defined(__i386) 3207 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3208 (uint8_t)(uint32_t)(&mii_regs->gcr), 3209 gcr.value)) != NXGE_OK) 3210 goto fail; 3211 #else 3212 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3213 (uint8_t)(uint64_t)(&mii_regs->gcr), 3214 gcr.value)) != NXGE_OK) 3215 goto fail; 3216 #endif 3217 bmcr.value = 0; 3218 bmcr.bits.speed_1000_sel = 1; 3219 statsp->mac_stats.link_speed = 1000; 3220 } 3221 3222 #if defined(__i386) 3223 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3224 (uint8_t)(uint32_t)(&mii_regs->bmcr), 3225 bmcr.value)) != NXGE_OK) 3226 goto fail; 3227 #else 3228 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3229 (uint8_t)(uint64_t)(&mii_regs->bmcr), 3230 bmcr.value)) != NXGE_OK) 3231 goto fail; 3232 #endif 3233 3234 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3235 "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x", 3236 bmcr.value)); 3237 3238 #if defined(__i386) 3239 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3240 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 3241 goto fail; 3242 #else 3243 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3244 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 3245 goto fail; 3246 #endif 3247 3248 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3249 "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value)); 3250 3251 /* 3252 * Initialize the xcvr status kept in the context structure. 3253 */ 3254 nxgep->soft_bmsr.value = 0; 3255 #if defined(__i386) 3256 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3257 (uint8_t)(uint32_t)(&mii_regs->bmsr), 3258 &nxgep->bmsr.value)) != NXGE_OK) 3259 goto fail; 3260 #else 3261 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3262 (uint8_t)(uint64_t)(&mii_regs->bmsr), 3263 &nxgep->bmsr.value)) != NXGE_OK) 3264 goto fail; 3265 #endif 3266 3267 statsp->mac_stats.xcvr_inits++; 3268 nxgep->bmsr.value = 0; 3269 3270 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3271 "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 3272 return (status); 3273 3274 fail: 3275 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3276 "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 3277 return (status); 3278 } 3279 3280 /* Read from a MII compliant register */ 3281 3282 nxge_status_t 3283 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 3284 uint16_t *value) 3285 { 3286 npi_status_t rs = NPI_SUCCESS; 3287 3288 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 3289 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 3290 3291 MUTEX_ENTER(&nxge_mii_lock); 3292 3293 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 3294 (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 3295 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 3296 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3297 goto fail; 3298 } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 3299 (nxgep->mac.portmode == PORT_1G_SERDES)) { 3300 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 3301 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3302 goto fail; 3303 } else 3304 goto fail; 3305 3306 MUTEX_EXIT(&nxge_mii_lock); 3307 3308 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 3309 "xcvr_reg<%d> value=0x%x", 3310 xcvr_portn, xcvr_reg, *value)); 3311 return (NXGE_OK); 3312 fail: 3313 MUTEX_EXIT(&nxge_mii_lock); 3314 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3315 "nxge_mii_read: Failed to read mii on xcvr %d", 3316 xcvr_portn)); 3317 3318 return (NXGE_ERROR | rs); 3319 } 3320 3321 /* Write to a MII compliant Register */ 3322 3323 nxge_status_t 3324 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 3325 uint16_t value) 3326 { 3327 npi_status_t rs = NPI_SUCCESS; 3328 3329 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 3330 "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, 3331 value)); 3332 3333 MUTEX_ENTER(&nxge_mii_lock); 3334 3335 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 3336 (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 3337 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 3338 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3339 goto fail; 3340 } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 3341 (nxgep->mac.portmode == PORT_1G_SERDES)) { 3342 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 3343 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3344 goto fail; 3345 } else 3346 goto fail; 3347 3348 MUTEX_EXIT(&nxge_mii_lock); 3349 3350 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 3351 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 3352 return (NXGE_OK); 3353 fail: 3354 MUTEX_EXIT(&nxge_mii_lock); 3355 3356 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3357 "nxge_mii_write: Failed to write mii on xcvr %d", 3358 xcvr_portn)); 3359 3360 return (NXGE_ERROR | rs); 3361 } 3362 3363 /* Perform read from Clause45 serdes / transceiver device */ 3364 3365 nxge_status_t 3366 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 3367 uint16_t xcvr_reg, uint16_t *value) 3368 { 3369 npi_status_t rs = NPI_SUCCESS; 3370 3371 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 3372 xcvr_portn)); 3373 3374 MUTEX_ENTER(&nxge_mdio_lock); 3375 3376 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 3377 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 3378 goto fail; 3379 3380 MUTEX_EXIT(&nxge_mdio_lock); 3381 3382 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 3383 xcvr_portn)); 3384 return (NXGE_OK); 3385 fail: 3386 MUTEX_EXIT(&nxge_mdio_lock); 3387 3388 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3389 "nxge_mdio_read: Failed to read mdio on xcvr %d", 3390 xcvr_portn)); 3391 3392 return (NXGE_ERROR | rs); 3393 } 3394 3395 /* Perform write to Clause45 serdes / transceiver device */ 3396 3397 nxge_status_t 3398 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 3399 uint16_t xcvr_reg, uint16_t value) 3400 { 3401 npi_status_t rs = NPI_SUCCESS; 3402 3403 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 3404 xcvr_portn)); 3405 3406 MUTEX_ENTER(&nxge_mdio_lock); 3407 3408 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 3409 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 3410 goto fail; 3411 3412 MUTEX_EXIT(&nxge_mdio_lock); 3413 3414 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 3415 xcvr_portn)); 3416 return (NXGE_OK); 3417 fail: 3418 MUTEX_EXIT(&nxge_mdio_lock); 3419 3420 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3421 "nxge_mdio_write: Failed to write mdio on xcvr %d", 3422 xcvr_portn)); 3423 3424 return (NXGE_ERROR | rs); 3425 } 3426 3427 3428 /* Check MII to see if there is any link status change */ 3429 3430 nxge_status_t 3431 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 3432 nxge_link_state_t *link_up) 3433 { 3434 p_nxge_param_t param_arr; 3435 p_nxge_stats_t statsp; 3436 p_mii_regs_t mii_regs; 3437 p_mii_bmsr_t soft_bmsr; 3438 mii_anar_t anar; 3439 mii_anlpar_t anlpar; 3440 mii_anar_t an_common; 3441 mii_aner_t aner; 3442 mii_gsr_t gsr; 3443 nxge_status_t status = NXGE_OK; 3444 3445 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 3446 3447 mii_regs = NULL; 3448 param_arr = nxgep->param_arr; 3449 statsp = nxgep->statsp; 3450 soft_bmsr = &nxgep->soft_bmsr; 3451 *link_up = LINK_NO_CHANGE; 3452 3453 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3454 "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x", 3455 bmsr.value, bmsr_ints.value)); 3456 3457 if (bmsr_ints.bits.link_status) { 3458 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3459 "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x", 3460 bmsr.value, bmsr_ints.value)); 3461 if (bmsr.bits.link_status) { 3462 soft_bmsr->bits.link_status = 1; 3463 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3464 "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int " 3465 "0x%x", bmsr.value, bmsr_ints.value)); 3466 } else { 3467 statsp->mac_stats.link_up = 0; 3468 soft_bmsr->bits.link_status = 0; 3469 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3470 "Link down cable problem")); 3471 *link_up = LINK_IS_DOWN; 3472 } 3473 } 3474 3475 if (nxgep->mac.portmode == PORT_1G_COPPER && 3476 param_arr[param_autoneg].value) { 3477 if (bmsr_ints.bits.auto_neg_complete) { 3478 if (bmsr.bits.auto_neg_complete) 3479 soft_bmsr->bits.auto_neg_complete = 1; 3480 else 3481 soft_bmsr->bits.auto_neg_complete = 0; 3482 } 3483 if (soft_bmsr->bits.link_status == 0) { 3484 statsp->mac_stats.link_T4 = 0; 3485 statsp->mac_stats.link_speed = 0; 3486 statsp->mac_stats.link_duplex = 0; 3487 statsp->mac_stats.link_asmpause = 0; 3488 statsp->mac_stats.link_pause = 0; 3489 statsp->mac_stats.lp_cap_autoneg = 0; 3490 statsp->mac_stats.lp_cap_100T4 = 0; 3491 statsp->mac_stats.lp_cap_1000fdx = 0; 3492 statsp->mac_stats.lp_cap_1000hdx = 0; 3493 statsp->mac_stats.lp_cap_100fdx = 0; 3494 statsp->mac_stats.lp_cap_100hdx = 0; 3495 statsp->mac_stats.lp_cap_10fdx = 0; 3496 statsp->mac_stats.lp_cap_10hdx = 0; 3497 statsp->mac_stats.lp_cap_10gfdx = 0; 3498 statsp->mac_stats.lp_cap_10ghdx = 0; 3499 statsp->mac_stats.lp_cap_asmpause = 0; 3500 statsp->mac_stats.lp_cap_pause = 0; 3501 } 3502 } else 3503 soft_bmsr->bits.auto_neg_complete = 1; 3504 3505 if ((bmsr_ints.bits.link_status || 3506 bmsr_ints.bits.auto_neg_complete) && 3507 soft_bmsr->bits.link_status && 3508 soft_bmsr->bits.auto_neg_complete) { 3509 statsp->mac_stats.link_up = 1; 3510 3511 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3512 "==> nxge_mii_check " 3513 "(auto negotiation complete or link up) " 3514 "soft bmsr 0x%x bmsr_int 0x%x", 3515 bmsr.value, bmsr_ints.value)); 3516 3517 if (nxgep->mac.portmode == PORT_1G_COPPER && 3518 param_arr[param_autoneg].value) { 3519 if ((status = nxge_mii_read(nxgep, 3520 statsp->mac_stats.xcvr_portn, 3521 #if defined(__i386) 3522 (uint8_t)(uint32_t)(&mii_regs->anar), 3523 #else 3524 (uint8_t)(uint64_t)(&mii_regs->anar), 3525 #endif 3526 &anar.value)) != NXGE_OK) 3527 goto fail; 3528 if ((status = nxge_mii_read(nxgep, 3529 statsp->mac_stats.xcvr_portn, 3530 #if defined(__i386) 3531 (uint8_t)(uint32_t)(&mii_regs->anlpar), 3532 #else 3533 (uint8_t)(uint64_t)(&mii_regs->anlpar), 3534 #endif 3535 &anlpar.value)) != NXGE_OK) 3536 goto fail; 3537 if ((status = nxge_mii_read(nxgep, 3538 statsp->mac_stats.xcvr_portn, 3539 #if defined(__i386) 3540 (uint8_t)(uint32_t)(&mii_regs->aner), 3541 #else 3542 (uint8_t)(uint64_t)(&mii_regs->aner), 3543 #endif 3544 &aner.value)) != NXGE_OK) 3545 goto fail; 3546 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 3547 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 3548 statsp->mac_stats.lp_cap_100fdx = 3549 anlpar.bits.cap_100fdx; 3550 statsp->mac_stats.lp_cap_100hdx = 3551 anlpar.bits.cap_100hdx; 3552 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 3553 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 3554 statsp->mac_stats.lp_cap_asmpause = 3555 anlpar.bits.cap_asmpause; 3556 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 3557 an_common.value = anar.value & anlpar.value; 3558 if (param_arr[param_anar_1000fdx].value || 3559 param_arr[param_anar_1000hdx].value) { 3560 if ((status = nxge_mii_read(nxgep, 3561 statsp->mac_stats.xcvr_portn, 3562 #if defined(__i386) 3563 (uint8_t)(uint32_t)(&mii_regs->gsr), 3564 #else 3565 (uint8_t)(uint64_t)(&mii_regs->gsr), 3566 #endif 3567 &gsr.value)) 3568 != NXGE_OK) 3569 goto fail; 3570 statsp->mac_stats.lp_cap_1000fdx = 3571 gsr.bits.link_1000fdx; 3572 statsp->mac_stats.lp_cap_1000hdx = 3573 gsr.bits.link_1000hdx; 3574 if (param_arr[param_anar_1000fdx].value && 3575 gsr.bits.link_1000fdx) { 3576 statsp->mac_stats.link_speed = 1000; 3577 statsp->mac_stats.link_duplex = 2; 3578 } else if ( 3579 param_arr[param_anar_1000hdx].value && 3580 gsr.bits.link_1000hdx) { 3581 statsp->mac_stats.link_speed = 1000; 3582 statsp->mac_stats.link_duplex = 1; 3583 } 3584 } 3585 if ((an_common.value != 0) && 3586 !(statsp->mac_stats.link_speed)) { 3587 if (an_common.bits.cap_100T4) { 3588 statsp->mac_stats.link_T4 = 1; 3589 statsp->mac_stats.link_speed = 100; 3590 statsp->mac_stats.link_duplex = 1; 3591 } else if (an_common.bits.cap_100fdx) { 3592 statsp->mac_stats.link_speed = 100; 3593 statsp->mac_stats.link_duplex = 2; 3594 } else if (an_common.bits.cap_100hdx) { 3595 statsp->mac_stats.link_speed = 100; 3596 statsp->mac_stats.link_duplex = 1; 3597 } else if (an_common.bits.cap_10fdx) { 3598 statsp->mac_stats.link_speed = 10; 3599 statsp->mac_stats.link_duplex = 2; 3600 } else if (an_common.bits.cap_10hdx) { 3601 statsp->mac_stats.link_speed = 10; 3602 statsp->mac_stats.link_duplex = 1; 3603 } else { 3604 goto fail; 3605 } 3606 } 3607 if (statsp->mac_stats.link_duplex != 1) { 3608 statsp->mac_stats.link_asmpause = 3609 an_common.bits.cap_asmpause; 3610 if (statsp->mac_stats.link_asmpause) 3611 if ((statsp->mac_stats.cap_pause == 0) && 3612 (statsp->mac_stats.lp_cap_pause 3613 == 1)) 3614 statsp->mac_stats.link_pause 3615 = 0; 3616 else 3617 statsp->mac_stats.link_pause 3618 = 1; 3619 else 3620 statsp->mac_stats.link_pause = 3621 an_common.bits.cap_pause; 3622 } 3623 } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 3624 statsp->mac_stats.link_speed = 1000; 3625 statsp->mac_stats.link_duplex = 2; 3626 } 3627 *link_up = LINK_IS_UP; 3628 } 3629 3630 if (nxgep->link_notify) { 3631 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 3632 LINK_IS_DOWN); 3633 nxgep->link_notify = B_FALSE; 3634 } 3635 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 3636 return (NXGE_OK); 3637 fail: 3638 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3639 "nxge_mii_check: Unable to check MII")); 3640 return (status); 3641 } 3642 3643 /* Check PCS to see if there is any link status change */ 3644 nxge_status_t 3645 nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up) 3646 { 3647 p_nxge_stats_t statsp; 3648 nxge_status_t status = NXGE_OK; 3649 boolean_t linkup; 3650 3651 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check")); 3652 3653 statsp = nxgep->statsp; 3654 *link_up = LINK_NO_CHANGE; 3655 3656 (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup); 3657 if (linkup) { 3658 if (nxgep->link_notify || 3659 nxgep->statsp->mac_stats.link_up == 0) { 3660 statsp->mac_stats.link_up = 1; 3661 statsp->mac_stats.link_speed = 1000; 3662 statsp->mac_stats.link_duplex = 2; 3663 *link_up = LINK_IS_UP; 3664 nxgep->link_notify = B_FALSE; 3665 } 3666 } else { 3667 if (nxgep->link_notify || 3668 nxgep->statsp->mac_stats.link_up == 1) { 3669 statsp->mac_stats.link_up = 0; 3670 statsp->mac_stats.link_speed = 0; 3671 statsp->mac_stats.link_duplex = 0; 3672 *link_up = LINK_IS_DOWN; 3673 nxgep->link_notify = B_FALSE; 3674 } 3675 } 3676 3677 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check")); 3678 return (NXGE_OK); 3679 fail: 3680 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3681 "nxge_pcs_check: Unable to check PCS")); 3682 return (status); 3683 } 3684 3685 /* Add a multicast address entry into the HW hash table */ 3686 3687 nxge_status_t 3688 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 3689 { 3690 uint32_t mchash; 3691 p_hash_filter_t hash_filter; 3692 uint16_t hash_bit; 3693 boolean_t rx_init = B_FALSE; 3694 uint_t j; 3695 nxge_status_t status = NXGE_OK; 3696 3697 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 3698 3699 RW_ENTER_WRITER(&nxgep->filter_lock); 3700 mchash = crc32_mchash(addrp); 3701 if (nxgep->hash_filter == NULL) { 3702 NXGE_DEBUG_MSG((NULL, STR_CTL, 3703 "Allocating hash filter storage.")); 3704 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 3705 KM_SLEEP); 3706 } 3707 hash_filter = nxgep->hash_filter; 3708 j = mchash / HASH_REG_WIDTH; 3709 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 3710 hash_filter->hash_filter_regs[j] |= hash_bit; 3711 hash_filter->hash_bit_ref_cnt[mchash]++; 3712 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 3713 hash_filter->hash_ref_cnt++; 3714 rx_init = B_TRUE; 3715 } 3716 if (rx_init) { 3717 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 3718 goto fail; 3719 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 3720 goto fail; 3721 } 3722 3723 RW_EXIT(&nxgep->filter_lock); 3724 3725 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 3726 3727 return (NXGE_OK); 3728 fail: 3729 RW_EXIT(&nxgep->filter_lock); 3730 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 3731 "Unable to add multicast address")); 3732 return (status); 3733 } 3734 3735 /* Remove a multicast address entry from the HW hash table */ 3736 3737 nxge_status_t 3738 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 3739 { 3740 uint32_t mchash; 3741 p_hash_filter_t hash_filter; 3742 uint16_t hash_bit; 3743 boolean_t rx_init = B_FALSE; 3744 uint_t j; 3745 nxge_status_t status = NXGE_OK; 3746 3747 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 3748 RW_ENTER_WRITER(&nxgep->filter_lock); 3749 mchash = crc32_mchash(addrp); 3750 if (nxgep->hash_filter == NULL) { 3751 NXGE_DEBUG_MSG((NULL, STR_CTL, 3752 "Hash filter already de_allocated.")); 3753 RW_EXIT(&nxgep->filter_lock); 3754 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 3755 return (NXGE_OK); 3756 } 3757 hash_filter = nxgep->hash_filter; 3758 hash_filter->hash_bit_ref_cnt[mchash]--; 3759 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 3760 j = mchash / HASH_REG_WIDTH; 3761 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 3762 hash_filter->hash_filter_regs[j] &= ~hash_bit; 3763 hash_filter->hash_ref_cnt--; 3764 rx_init = B_TRUE; 3765 } 3766 if (hash_filter->hash_ref_cnt == 0) { 3767 NXGE_DEBUG_MSG((NULL, STR_CTL, 3768 "De-allocating hash filter storage.")); 3769 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 3770 nxgep->hash_filter = NULL; 3771 } 3772 3773 if (rx_init) { 3774 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 3775 goto fail; 3776 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 3777 goto fail; 3778 } 3779 RW_EXIT(&nxgep->filter_lock); 3780 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 3781 3782 return (NXGE_OK); 3783 fail: 3784 RW_EXIT(&nxgep->filter_lock); 3785 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 3786 "Unable to remove multicast address")); 3787 3788 return (status); 3789 } 3790 3791 /* Set MAC address into MAC address HW registers */ 3792 3793 nxge_status_t 3794 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 3795 { 3796 nxge_status_t status = NXGE_OK; 3797 3798 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 3799 3800 MUTEX_ENTER(&nxgep->ouraddr_lock); 3801 /* 3802 * Exit if the address is same as ouraddr or multicast or broadcast 3803 */ 3804 if (((addrp->ether_addr_octet[0] & 01) == 1) || 3805 (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 3806 (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 3807 goto nxge_set_mac_addr_exit; 3808 } 3809 nxgep->ouraddr = *addrp; 3810 /* 3811 * Set new interface local address and re-init device. 3812 * This is destructive to any other streams attached 3813 * to this device. 3814 */ 3815 RW_ENTER_WRITER(&nxgep->filter_lock); 3816 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 3817 goto fail; 3818 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 3819 goto fail; 3820 3821 RW_EXIT(&nxgep->filter_lock); 3822 MUTEX_EXIT(&nxgep->ouraddr_lock); 3823 goto nxge_set_mac_addr_end; 3824 nxge_set_mac_addr_exit: 3825 MUTEX_EXIT(&nxgep->ouraddr_lock); 3826 nxge_set_mac_addr_end: 3827 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 3828 3829 return (NXGE_OK); 3830 fail: 3831 MUTEX_EXIT(&nxgep->ouraddr_lock); 3832 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 3833 "Unable to set mac address")); 3834 return (status); 3835 } 3836 3837 static 3838 check_link_state_t 3839 nxge_check_link_stop( 3840 nxge_t *nxge) 3841 { 3842 /* If the poll has been cancelled, return STOP. */ 3843 MUTEX_ENTER(&nxge->poll_lock); 3844 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 3845 nxge->poll_state = LINK_MONITOR_STOP; 3846 nxge->nxge_link_poll_timerid = 0; 3847 cv_broadcast(&nxge->poll_cv); 3848 MUTEX_EXIT(&nxge->poll_lock); 3849 3850 NXGE_DEBUG_MSG((nxge, MAC_CTL, 3851 "nxge_check_%s_link(port<%d>) stopped.", 3852 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 3853 nxge->mac.portnum)); 3854 return (CHECK_LINK_STOP); 3855 } 3856 MUTEX_EXIT(&nxge->poll_lock); 3857 3858 return (CHECK_LINK_RESCHEDULE); 3859 } 3860 3861 /* Check status of MII (MIF or PCS) link */ 3862 3863 static nxge_status_t 3864 nxge_check_mii_link(p_nxge_t nxgep) 3865 { 3866 mii_bmsr_t bmsr_ints, bmsr_data; 3867 mii_anlpar_t anlpar; 3868 mii_gsr_t gsr; 3869 p_mii_regs_t mii_regs; 3870 nxge_status_t status = NXGE_OK; 3871 uint8_t portn; 3872 nxge_link_state_t link_up; 3873 3874 if (nxgep->nxge_magic != NXGE_MAGIC) 3875 return (NXGE_ERROR); 3876 3877 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 3878 return (NXGE_OK); 3879 3880 portn = nxgep->mac.portnum; 3881 3882 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 3883 portn)); 3884 3885 mii_regs = NULL; 3886 3887 RW_ENTER_WRITER(&nxgep->filter_lock); 3888 3889 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 3890 goto nxge_check_mii_link_exit; 3891 3892 switch (nxgep->mac.portmode) { 3893 default: 3894 bmsr_data.value = 0; 3895 if ((status = nxge_mii_read(nxgep, 3896 nxgep->statsp->mac_stats.xcvr_portn, 3897 #if defined(__i386) 3898 (uint8_t)(uint32_t)(&mii_regs->bmsr), 3899 #else 3900 (uint8_t)(uint64_t)(&mii_regs->bmsr), 3901 #endif 3902 &bmsr_data.value)) != NXGE_OK) { 3903 goto fail; 3904 } 3905 3906 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3907 "==> nxge_check_mii_link port<0x%x> " 3908 "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ", 3909 xcvr_portn, bmsr_data.value, nxgep->bmsr.value)); 3910 3911 if (nxgep->param_arr[param_autoneg].value) { 3912 if ((status = nxge_mii_read(nxgep, 3913 nxgep->statsp->mac_stats.xcvr_portn, 3914 #if defined(__i386) 3915 (uint8_t)(uint32_t)(&mii_regs->gsr), 3916 #else 3917 (uint8_t)(uint64_t)(&mii_regs->gsr), 3918 #endif 3919 &gsr.value)) != NXGE_OK) 3920 goto fail; 3921 if ((status = nxge_mii_read(nxgep, 3922 nxgep->statsp->mac_stats.xcvr_portn, 3923 #if defined(__i386) 3924 (uint8_t)(uint32_t)(&mii_regs->anlpar), 3925 #else 3926 (uint8_t)(uint64_t)(&mii_regs->anlpar), 3927 #endif 3928 &anlpar.value)) != NXGE_OK) 3929 goto fail; 3930 if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) { 3931 3932 if (nxgep->statsp->mac_stats.link_up && 3933 ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 3934 gsr.bits.link_1000fdx) || 3935 (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 3936 gsr.bits.link_1000hdx) || 3937 (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 3938 anlpar.bits.cap_100T4) || 3939 (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 3940 anlpar.bits.cap_100fdx) || 3941 (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 3942 anlpar.bits.cap_100hdx) || 3943 (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 3944 anlpar.bits.cap_10fdx) || 3945 (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 3946 anlpar.bits.cap_10hdx))) { 3947 bmsr_data.bits.link_status = 0; 3948 } 3949 } 3950 } 3951 3952 /* Workaround for link down issue */ 3953 if (bmsr_data.value == 0) { 3954 cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 3955 goto nxge_check_mii_link_exit; 3956 } 3957 3958 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3959 "==> nxge_check_mii_link port<0x%x> :" 3960 "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x", 3961 xcvr_portn, nxgep->bmsr.value, bmsr_data.value)); 3962 3963 bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 3964 nxgep->bmsr.value = bmsr_data.value; 3965 3966 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3967 "==> nxge_check_mii_link port<0x%x> CALLING " 3968 "bmsr_data 0x%x bmsr_ints.value 0x%x", 3969 xcvr_portn, bmsr_data.value, bmsr_ints.value)); 3970 3971 if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, 3972 &link_up)) != NXGE_OK) { 3973 goto fail; 3974 } 3975 break; 3976 3977 case PORT_1G_SERDES: 3978 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3979 "==> nxge_check_mii_link port<%d> (SERDES)", portn)); 3980 if ((status = nxge_pcs_check(nxgep, portn, &link_up)) 3981 != NXGE_OK) { 3982 goto fail; 3983 } 3984 break; 3985 } 3986 3987 nxge_check_mii_link_exit: 3988 RW_EXIT(&nxgep->filter_lock); 3989 if (link_up == LINK_IS_UP) { 3990 nxge_link_is_up(nxgep); 3991 } else if (link_up == LINK_IS_DOWN) { 3992 nxge_link_is_down(nxgep); 3993 } 3994 3995 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 3996 3997 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 3998 portn)); 3999 return (NXGE_OK); 4000 4001 fail: 4002 RW_EXIT(&nxgep->filter_lock); 4003 4004 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 4005 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4006 "nxge_check_mii_link: Failed to check link port<%d>", 4007 portn)); 4008 return (status); 4009 } 4010 4011 4012 /*ARGSUSED*/ 4013 static nxge_status_t 4014 nxge_check_10g_link(p_nxge_t nxgep) 4015 { 4016 uint8_t portn; 4017 nxge_status_t status = NXGE_OK; 4018 boolean_t link_up; 4019 uint32_t val; 4020 npi_status_t rs; 4021 4022 if (nxgep->nxge_magic != NXGE_MAGIC) 4023 return (NXGE_ERROR); 4024 4025 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 4026 return (NXGE_OK); 4027 4028 portn = nxgep->mac.portnum; 4029 val = 0; 4030 rs = NPI_SUCCESS; 4031 4032 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 4033 portn)); 4034 4035 switch (nxgep->mac.portmode) { 4036 default: 4037 status = nxge_check_bcm8704_link(nxgep, &link_up); 4038 if (status != NXGE_OK) 4039 goto fail; 4040 break; 4041 case PORT_10G_SERDES: 4042 rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4043 XPCS_REG_STATUS, &val); 4044 if (rs != 0) 4045 goto fail; 4046 4047 link_up = B_FALSE; 4048 if (val & XPCS_STATUS_LANE_ALIGN) { 4049 link_up = B_TRUE; 4050 } 4051 4052 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4053 "==> nxge_check_10g_link port<%d> " 4054 "XPCS_REG_STATUS2 0x%x link_up %d", 4055 portn, val, link_up)); 4056 4057 break; 4058 } 4059 4060 if (link_up) { 4061 if (nxgep->link_notify || 4062 nxgep->statsp->mac_stats.link_up == 0) { 4063 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 4064 goto fail; 4065 nxgep->statsp->mac_stats.link_up = 1; 4066 nxgep->statsp->mac_stats.link_speed = 10000; 4067 nxgep->statsp->mac_stats.link_duplex = 2; 4068 4069 nxge_link_is_up(nxgep); 4070 nxgep->link_notify = B_FALSE; 4071 } 4072 } else { 4073 if (nxgep->link_notify || 4074 nxgep->statsp->mac_stats.link_up == 1) { 4075 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 4076 goto fail; 4077 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4078 "Link down cable problem")); 4079 nxgep->statsp->mac_stats.link_up = 0; 4080 nxgep->statsp->mac_stats.link_speed = 0; 4081 nxgep->statsp->mac_stats.link_duplex = 0; 4082 4083 nxge_link_is_down(nxgep); 4084 nxgep->link_notify = B_FALSE; 4085 } 4086 } 4087 4088 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 4089 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 4090 portn)); 4091 return (NXGE_OK); 4092 4093 fail: 4094 (void) nxge_check_link_stop(nxgep); 4095 4096 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4097 "nxge_check_10g_link: Failed to check link port<%d>", 4098 portn)); 4099 return (status); 4100 } 4101 4102 4103 /* Declare link down */ 4104 4105 void 4106 nxge_link_is_down(p_nxge_t nxgep) 4107 { 4108 p_nxge_stats_t statsp; 4109 char link_stat_msg[64]; 4110 4111 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 4112 4113 statsp = nxgep->statsp; 4114 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 4115 statsp->mac_stats.xcvr_portn); 4116 4117 if (nxge_no_msg == B_FALSE) { 4118 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 4119 } 4120 4121 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 4122 4123 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 4124 } 4125 4126 /* Declare link up */ 4127 4128 void 4129 nxge_link_is_up(p_nxge_t nxgep) 4130 { 4131 p_nxge_stats_t statsp; 4132 char link_stat_msg[64]; 4133 uint32_t val; 4134 4135 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 4136 4137 statsp = nxgep->statsp; 4138 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 4139 statsp->mac_stats.xcvr_portn, 4140 statsp->mac_stats.link_speed); 4141 4142 if (statsp->mac_stats.link_T4) 4143 (void) strcat(link_stat_msg, "T4"); 4144 else if (statsp->mac_stats.link_duplex == 2) 4145 (void) strcat(link_stat_msg, "full duplex"); 4146 else 4147 (void) strcat(link_stat_msg, "half duplex"); 4148 4149 (void) nxge_xif_init(nxgep); 4150 4151 /* Clean up symbol errors incurred during link transition */ 4152 if ((nxgep->mac.portmode == PORT_10G_FIBER) || 4153 (nxgep->mac.portmode == PORT_10G_SERDES)) { 4154 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4155 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 4156 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4157 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 4158 } 4159 4160 if (nxge_no_msg == B_FALSE) { 4161 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 4162 } 4163 4164 mac_link_update(nxgep->mach, LINK_STATE_UP); 4165 4166 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 4167 } 4168 4169 /* 4170 * Calculate the bit in the multicast address filter 4171 * that selects the given * address. 4172 * Note: For GEM, the last 8-bits are used. 4173 */ 4174 uint32_t 4175 crc32_mchash(p_ether_addr_t addr) 4176 { 4177 uint8_t *cp; 4178 uint32_t crc; 4179 uint32_t c; 4180 int byte; 4181 int bit; 4182 4183 cp = (uint8_t *)addr; 4184 crc = (uint32_t)0xffffffff; 4185 for (byte = 0; byte < 6; byte++) { 4186 c = (uint32_t)cp[byte]; 4187 for (bit = 0; bit < 8; bit++) { 4188 if ((c & 0x1) ^ (crc & 0x1)) 4189 crc = (crc >> 1)^0xedb88320; 4190 else 4191 crc = (crc >> 1); 4192 c >>= 1; 4193 } 4194 } 4195 return ((~crc) >> (32 - HASH_BITS)); 4196 } 4197 4198 /* Reset serdes */ 4199 4200 nxge_status_t 4201 nxge_serdes_reset(p_nxge_t nxgep) 4202 { 4203 npi_handle_t handle; 4204 4205 handle = nxgep->npi_handle; 4206 4207 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 4208 drv_usecwait(500); 4209 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 4210 4211 return (NXGE_OK); 4212 } 4213 4214 /* Monitor link status using interrupt or polling */ 4215 4216 nxge_status_t 4217 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 4218 { 4219 nxge_status_t status = NXGE_OK; 4220 4221 /* 4222 * Return immediately if this is an imaginary XMAC port. 4223 * (At least, we don't have 4-port XMAC cards yet.) 4224 */ 4225 if ((nxgep->mac.portmode == PORT_10G_FIBER || 4226 nxgep->mac.portmode == PORT_10G_SERDES) && 4227 (nxgep->mac.portnum > 1)) 4228 return (NXGE_OK); 4229 4230 if (nxgep->statsp == NULL) { 4231 /* stats has not been allocated. */ 4232 return (NXGE_OK); 4233 } 4234 /* Don't check link if we're not in internal loopback mode */ 4235 if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal) 4236 return (NXGE_OK); 4237 4238 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4239 "==> nxge_link_monitor port<%d> enable=%d", 4240 nxgep->mac.portnum, enable)); 4241 if (enable == LINK_MONITOR_START) { 4242 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 4243 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 4244 != NXGE_OK) 4245 goto fail; 4246 } else { 4247 timeout_id_t timerid; 4248 4249 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 4250 return (NXGE_OK); 4251 4252 if (nxgep->xcvr.check_link) { 4253 timerid = timeout( 4254 (fptrv_t)(nxgep->xcvr.check_link), 4255 nxgep, 4256 drv_usectohz(LINK_MONITOR_PERIOD)); 4257 MUTEX_ENTER(&nxgep->poll_lock); 4258 nxgep->nxge_link_poll_timerid = timerid; 4259 MUTEX_EXIT(&nxgep->poll_lock); 4260 } else { 4261 return (NXGE_ERROR); 4262 } 4263 } 4264 } else { 4265 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 4266 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 4267 != NXGE_OK) 4268 goto fail; 4269 } else { 4270 clock_t rv; 4271 4272 MUTEX_ENTER(&nxgep->poll_lock); 4273 4274 /* If <timerid> == 0, the link monitor has */ 4275 /* never been started, or just now stopped. */ 4276 if (nxgep->nxge_link_poll_timerid == 0) { 4277 MUTEX_EXIT(&nxgep->poll_lock); 4278 return (NXGE_OK); 4279 } 4280 4281 nxgep->poll_state = LINK_MONITOR_STOPPING; 4282 rv = cv_timedwait(&nxgep->poll_cv, 4283 &nxgep->poll_lock, 4284 ddi_get_lbolt() + 4285 drv_usectohz(LM_WAIT_MULTIPLIER * 4286 LINK_MONITOR_PERIOD)); 4287 if (rv == -1) { 4288 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4289 "==> stopping port %d: " 4290 "cv_timedwait(%d) timed out", 4291 nxgep->mac.portnum, nxgep->poll_state)); 4292 nxgep->poll_state = LINK_MONITOR_STOP; 4293 nxgep->nxge_link_poll_timerid = 0; 4294 } 4295 4296 MUTEX_EXIT(&nxgep->poll_lock); 4297 } 4298 } 4299 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4300 "<== nxge_link_monitor port<%d> enable=%d", 4301 nxgep->mac.portnum, enable)); 4302 return (NXGE_OK); 4303 fail: 4304 return (status); 4305 } 4306 4307 /* Set promiscous mode */ 4308 4309 nxge_status_t 4310 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 4311 { 4312 nxge_status_t status = NXGE_OK; 4313 4314 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 4315 4316 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 4317 4318 RW_ENTER_WRITER(&nxgep->filter_lock); 4319 4320 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 4321 goto fail; 4322 } 4323 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 4324 goto fail; 4325 } 4326 4327 RW_EXIT(&nxgep->filter_lock); 4328 4329 if (on) 4330 nxgep->statsp->mac_stats.promisc = B_TRUE; 4331 else 4332 nxgep->statsp->mac_stats.promisc = B_FALSE; 4333 4334 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 4335 4336 return (NXGE_OK); 4337 fail: 4338 RW_EXIT(&nxgep->filter_lock); 4339 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 4340 "Unable to set promisc (%d)", on)); 4341 4342 return (status); 4343 } 4344 4345 /*ARGSUSED*/ 4346 uint_t 4347 nxge_mif_intr(void *arg1, void *arg2) 4348 { 4349 #ifdef NXGE_DEBUG 4350 p_nxge_t nxgep = (p_nxge_t)arg2; 4351 #endif 4352 #if NXGE_MIF 4353 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 4354 uint32_t status; 4355 npi_handle_t handle; 4356 uint8_t portn; 4357 p_nxge_stats_t statsp; 4358 #endif 4359 4360 #ifdef NXGE_MIF 4361 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 4362 nxgep = ldvp->nxgep; 4363 } 4364 nxgep = ldvp->nxgep; 4365 #endif 4366 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 4367 4368 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 4369 return (DDI_INTR_CLAIMED); 4370 4371 mif_intr_fail: 4372 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 4373 return (DDI_INTR_UNCLAIMED); 4374 } 4375 4376 /*ARGSUSED*/ 4377 uint_t 4378 nxge_mac_intr(void *arg1, void *arg2) 4379 { 4380 p_nxge_t nxgep = (p_nxge_t)arg2; 4381 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 4382 p_nxge_ldg_t ldgp; 4383 uint32_t status; 4384 npi_handle_t handle; 4385 uint8_t portn; 4386 p_nxge_stats_t statsp; 4387 npi_status_t rs = NPI_SUCCESS; 4388 4389 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 4390 nxgep = ldvp->nxgep; 4391 } 4392 4393 ldgp = ldvp->ldgp; 4394 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 4395 "group %d", ldgp->ldg)); 4396 4397 handle = NXGE_DEV_NPI_HANDLE(nxgep); 4398 /* 4399 * This interrupt handler is for a specific 4400 * mac port. 4401 */ 4402 statsp = (p_nxge_stats_t)nxgep->statsp; 4403 portn = nxgep->mac.portnum; 4404 4405 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4406 "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 4407 4408 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 4409 rs = npi_xmac_tx_get_istatus(handle, portn, 4410 (xmac_tx_iconfig_t *)&status); 4411 if (rs != NPI_SUCCESS) 4412 goto npi_fail; 4413 if (status & ICFG_XMAC_TX_ALL) { 4414 if (status & ICFG_XMAC_TX_UNDERRUN) { 4415 statsp->xmac_stats.tx_underflow_err++; 4416 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4417 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 4418 } 4419 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 4420 statsp->xmac_stats.tx_maxpktsize_err++; 4421 /* 4422 * Do not send FMA ereport because this 4423 * error does not indicate HW failure. 4424 */ 4425 } 4426 if (status & ICFG_XMAC_TX_OVERFLOW) { 4427 statsp->xmac_stats.tx_overflow_err++; 4428 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4429 NXGE_FM_EREPORT_TXMAC_OVERFLOW); 4430 } 4431 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 4432 statsp->xmac_stats.tx_fifo_xfr_err++; 4433 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4434 NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 4435 } 4436 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 4437 statsp->xmac_stats.tx_byte_cnt += 4438 XTXMAC_BYTE_CNT_MASK; 4439 } 4440 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 4441 statsp->xmac_stats.tx_frame_cnt += 4442 XTXMAC_FRM_CNT_MASK; 4443 } 4444 } 4445 4446 rs = npi_xmac_rx_get_istatus(handle, portn, 4447 (xmac_rx_iconfig_t *)&status); 4448 if (rs != NPI_SUCCESS) 4449 goto npi_fail; 4450 if (status & ICFG_XMAC_RX_ALL) { 4451 if (status & ICFG_XMAC_RX_OVERFLOW) 4452 statsp->xmac_stats.rx_overflow_err++; 4453 if (status & ICFG_XMAC_RX_UNDERFLOW) { 4454 statsp->xmac_stats.rx_underflow_err++; 4455 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4456 NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 4457 } 4458 /* 4459 * Do not send FMA ereport for the following 3 errors 4460 * because they do not indicate HW failures. 4461 */ 4462 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 4463 statsp->xmac_stats.rx_crc_err_cnt += 4464 XRXMAC_CRC_ER_CNT_MASK; 4465 } 4466 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 4467 statsp->xmac_stats.rx_len_err_cnt += 4468 MAC_LEN_ER_CNT_MASK; 4469 } 4470 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 4471 statsp->xmac_stats.rx_viol_err_cnt += 4472 XRXMAC_CD_VIO_CNT_MASK; 4473 } 4474 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 4475 statsp->xmac_stats.rx_byte_cnt += 4476 XRXMAC_BT_CNT_MASK; 4477 } 4478 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 4479 statsp->xmac_stats.rx_hist1_cnt += 4480 XRXMAC_HIST_CNT1_MASK; 4481 } 4482 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 4483 statsp->xmac_stats.rx_hist2_cnt += 4484 XRXMAC_HIST_CNT2_MASK; 4485 } 4486 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 4487 statsp->xmac_stats.rx_hist3_cnt += 4488 XRXMAC_HIST_CNT3_MASK; 4489 } 4490 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 4491 statsp->xmac_stats.rx_hist4_cnt += 4492 XRXMAC_HIST_CNT4_MASK; 4493 } 4494 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 4495 statsp->xmac_stats.rx_hist5_cnt += 4496 XRXMAC_HIST_CNT5_MASK; 4497 } 4498 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 4499 statsp->xmac_stats.rx_hist6_cnt += 4500 XRXMAC_HIST_CNT6_MASK; 4501 } 4502 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 4503 statsp->xmac_stats.rx_broadcast_cnt += 4504 XRXMAC_BC_FRM_CNT_MASK; 4505 } 4506 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 4507 statsp->xmac_stats.rx_mult_cnt += 4508 XRXMAC_MC_FRM_CNT_MASK; 4509 } 4510 /* 4511 * Do not send FMA ereport for the following 3 errors 4512 * because they do not indicate HW failures. 4513 */ 4514 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 4515 statsp->xmac_stats.rx_frag_cnt += 4516 XRXMAC_FRAG_CNT_MASK; 4517 } 4518 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 4519 statsp->xmac_stats.rx_frame_align_err_cnt += 4520 XRXMAC_AL_ER_CNT_MASK; 4521 } 4522 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 4523 statsp->xmac_stats.rx_linkfault_err_cnt += 4524 XMAC_LINK_FLT_CNT_MASK; 4525 } 4526 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 4527 statsp->xmac_stats.rx_remotefault_err++; 4528 } 4529 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 4530 statsp->xmac_stats.rx_localfault_err++; 4531 } 4532 } 4533 4534 rs = npi_xmac_ctl_get_istatus(handle, portn, 4535 (xmac_ctl_iconfig_t *)&status); 4536 if (rs != NPI_SUCCESS) 4537 goto npi_fail; 4538 if (status & ICFG_XMAC_CTRL_ALL) { 4539 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 4540 statsp->xmac_stats.rx_pause_cnt++; 4541 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 4542 statsp->xmac_stats.tx_pause_state++; 4543 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 4544 statsp->xmac_stats.tx_nopause_state++; 4545 } 4546 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 4547 rs = npi_bmac_tx_get_istatus(handle, portn, 4548 (bmac_tx_iconfig_t *)&status); 4549 if (rs != NPI_SUCCESS) 4550 goto npi_fail; 4551 if (status & ICFG_BMAC_TX_ALL) { 4552 if (status & ICFG_BMAC_TX_UNDERFLOW) { 4553 statsp->bmac_stats.tx_underrun_err++; 4554 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4555 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 4556 } 4557 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 4558 statsp->bmac_stats.tx_max_pkt_err++; 4559 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4560 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 4561 } 4562 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 4563 statsp->bmac_stats.tx_byte_cnt += 4564 BTXMAC_BYTE_CNT_MASK; 4565 } 4566 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 4567 statsp->bmac_stats.tx_frame_cnt += 4568 BTXMAC_FRM_CNT_MASK; 4569 } 4570 } 4571 4572 rs = npi_bmac_rx_get_istatus(handle, portn, 4573 (bmac_rx_iconfig_t *)&status); 4574 if (rs != NPI_SUCCESS) 4575 goto npi_fail; 4576 if (status & ICFG_BMAC_RX_ALL) { 4577 if (status & ICFG_BMAC_RX_OVERFLOW) { 4578 statsp->bmac_stats.rx_overflow_err++; 4579 } 4580 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 4581 statsp->bmac_stats.rx_frame_cnt += 4582 RXMAC_FRM_CNT_MASK; 4583 } 4584 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 4585 statsp->bmac_stats.rx_crc_err_cnt += 4586 BMAC_CRC_ER_CNT_MASK; 4587 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4588 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 4589 } 4590 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 4591 statsp->bmac_stats.rx_len_err_cnt += 4592 MAC_LEN_ER_CNT_MASK; 4593 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4594 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 4595 } 4596 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 4597 statsp->bmac_stats.rx_viol_err_cnt += 4598 BMAC_CD_VIO_CNT_MASK; 4599 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4600 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 4601 } 4602 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 4603 statsp->bmac_stats.rx_byte_cnt += 4604 BRXMAC_BYTE_CNT_MASK; 4605 } 4606 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 4607 statsp->bmac_stats.rx_align_err_cnt += 4608 BMAC_AL_ER_CNT_MASK; 4609 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4610 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 4611 } 4612 4613 rs = npi_bmac_ctl_get_istatus(handle, portn, 4614 (bmac_ctl_iconfig_t *)&status); 4615 if (rs != NPI_SUCCESS) 4616 goto npi_fail; 4617 4618 if (status & ICFG_BMAC_CTL_ALL) { 4619 if (status & ICFG_BMAC_CTL_RCVPAUSE) 4620 statsp->bmac_stats.rx_pause_cnt++; 4621 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 4622 statsp->bmac_stats.tx_pause_state++; 4623 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 4624 statsp->bmac_stats.tx_nopause_state++; 4625 } 4626 } 4627 4628 if (ldgp->nldvs == 1) { 4629 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 4630 B_TRUE, ldgp->ldg_timer); 4631 } 4632 4633 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 4634 return (DDI_INTR_CLAIMED); 4635 4636 npi_fail: 4637 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 4638 return (DDI_INTR_UNCLAIMED); 4639 } 4640 4641 nxge_status_t 4642 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 4643 { 4644 uint8_t phy_port_addr; 4645 nxge_status_t status = NXGE_OK; 4646 boolean_t rx_sig_ok; 4647 boolean_t pcs_blk_lock; 4648 boolean_t link_align; 4649 uint16_t val1, val2, val3; 4650 #ifdef NXGE_DEBUG_SYMBOL_ERR 4651 uint16_t val_debug; 4652 uint16_t val; 4653 #endif 4654 4655 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 4656 4657 #ifdef NXGE_DEBUG_SYMBOL_ERR 4658 /* Check Device 3 Register Device 3 0xC809 */ 4659 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 4660 if ((val_debug & ~0x200) != 0) { 4661 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 4662 nxgep->mac.portnum, val_debug); 4663 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 4664 &val_debug); 4665 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 4666 nxgep->mac.portnum, val_debug); 4667 } 4668 4669 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4670 XPCS_REG_DESCWERR_COUNTER, &val); 4671 if (val != 0) 4672 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 4673 4674 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4675 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 4676 if (val != 0) 4677 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 4678 4679 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4680 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 4681 if (val != 0) 4682 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 4683 #endif 4684 4685 /* Check from BCM8704 if 10G link is up or down */ 4686 4687 /* Check Device 1 Register 0xA bit0 */ 4688 status = nxge_mdio_read(nxgep, phy_port_addr, 4689 BCM8704_PMA_PMD_DEV_ADDR, 4690 BCM8704_PMD_RECEIVE_SIG_DETECT, 4691 &val1); 4692 if (status != NXGE_OK) 4693 goto fail; 4694 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 4695 4696 /* Check Device 3 Register 0x20 bit0 */ 4697 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 4698 BCM8704_PCS_DEV_ADDR, 4699 BCM8704_10GBASE_R_PCS_STATUS_REG, 4700 &val2)) != NPI_SUCCESS) 4701 goto fail; 4702 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 4703 4704 /* Check Device 4 Register 0x18 bit12 */ 4705 status = nxge_mdio_read(nxgep, phy_port_addr, 4706 BCM8704_PHYXS_ADDR, 4707 BCM8704_PHYXS_XGXS_LANE_STATUS_REG, 4708 &val3); 4709 if (status != NXGE_OK) 4710 goto fail; 4711 link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 4712 XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 4713 XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 4714 4715 #ifdef NXGE_DEBUG_ALIGN_ERR 4716 /* Temp workaround for link down issue */ 4717 if (pcs_blk_lock == B_FALSE) { 4718 if (val2 != 0x4) { 4719 pcs_blk_lock = B_TRUE; 4720 cmn_err(CE_NOTE, 4721 "!LINK DEBUG: port%d PHY Dev3 " 4722 "Reg 0x20 = 0x%x\n", 4723 nxgep->mac.portnum, val2); 4724 } 4725 } 4726 4727 if (link_align == B_FALSE) { 4728 if (val3 != 0x140f) { 4729 link_align = B_TRUE; 4730 cmn_err(CE_NOTE, 4731 "!LINK DEBUG: port%d PHY Dev4 " 4732 "Reg 0x18 = 0x%x\n", 4733 nxgep->mac.portnum, val3); 4734 } 4735 } 4736 4737 if (rx_sig_ok == B_FALSE) { 4738 if ((val2 == 0) || (val3 == 0)) { 4739 rx_sig_ok = B_TRUE; 4740 cmn_err(CE_NOTE, 4741 "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 4742 nxgep->mac.portnum); 4743 } 4744 } 4745 #endif 4746 4747 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 4748 (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 4749 4750 return (NXGE_OK); 4751 fail: 4752 return (status); 4753 } 4754 4755 nxge_status_t 4756 nxge_10g_link_led_on(p_nxge_t nxgep) 4757 { 4758 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 4759 != NPI_SUCCESS) 4760 return (NXGE_ERROR); 4761 else 4762 return (NXGE_OK); 4763 } 4764 4765 nxge_status_t 4766 nxge_10g_link_led_off(p_nxge_t nxgep) 4767 { 4768 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 4769 != NPI_SUCCESS) 4770 return (NXGE_ERROR); 4771 else 4772 return (NXGE_OK); 4773 } 4774 4775 /* Check if the given id read using the given MDIO Clause is supported */ 4776 4777 static boolean_t 4778 nxge_is_supported_phy(uint32_t id, uint8_t type) 4779 { 4780 int i; 4781 int cl45_arr_len = NUM_CLAUSE_45_IDS; 4782 int cl22_arr_len = NUM_CLAUSE_22_IDS; 4783 boolean_t found = B_FALSE; 4784 4785 switch (type) { 4786 case CLAUSE_45_TYPE: 4787 for (i = 0; i < cl45_arr_len; i++) { 4788 if ((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) == 4789 (id & BCM_PHY_ID_MASK)) { 4790 found = B_TRUE; 4791 break; 4792 } 4793 } 4794 break; 4795 case CLAUSE_22_TYPE: 4796 for (i = 0; i < cl22_arr_len; i++) { 4797 if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) == 4798 (id & BCM_PHY_ID_MASK)) { 4799 found = B_TRUE; 4800 break; 4801 } 4802 } 4803 break; 4804 default: 4805 break; 4806 } 4807 4808 return (found); 4809 } 4810 4811 static uint32_t 4812 nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port) 4813 { 4814 uint16_t val1 = 0; 4815 uint16_t val2 = 0; 4816 uint32_t pma_pmd_dev_id = 0; 4817 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 4818 4819 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 4820 NXGE_DEV_ID_REG_1, &val1); 4821 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 4822 NXGE_DEV_ID_REG_2, &val2); 4823 4824 pma_pmd_dev_id = val1; 4825 pma_pmd_dev_id = (pma_pmd_dev_id << 16); 4826 pma_pmd_dev_id |= val2; 4827 4828 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 4829 "devid[0x%llx]", phy_port, pma_pmd_dev_id)); 4830 4831 return (pma_pmd_dev_id); 4832 } 4833 4834 static uint32_t 4835 nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port) 4836 { 4837 uint16_t val1 = 0; 4838 uint16_t val2 = 0; 4839 uint32_t pcs_dev_id = 0; 4840 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 4841 4842 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 4843 NXGE_DEV_ID_REG_1, &val1); 4844 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 4845 NXGE_DEV_ID_REG_2, &val2); 4846 4847 pcs_dev_id = val1; 4848 pcs_dev_id = (pcs_dev_id << 16); 4849 pcs_dev_id |= val2; 4850 4851 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 4852 "devid[0x%llx]", phy_port, pcs_dev_id)); 4853 4854 return (pcs_dev_id); 4855 } 4856 4857 static uint32_t 4858 nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port) 4859 { 4860 uint16_t val1 = 0; 4861 uint16_t val2 = 0; 4862 uint32_t phy_id = 0; 4863 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 4864 npi_status_t npi_status = NPI_SUCCESS; 4865 4866 npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1, 4867 &val1); 4868 if (npi_status != NPI_SUCCESS) { 4869 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 4870 "clause 22 read to reg 2 failed!!!")); 4871 goto exit; 4872 } 4873 npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2, 4874 &val2); 4875 if (npi_status != 0) { 4876 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 4877 "clause 22 read to reg 3 failed!!!")); 4878 goto exit; 4879 } 4880 phy_id = val1; 4881 phy_id = (phy_id << 16); 4882 phy_id |= val2; 4883 4884 exit: 4885 4886 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]", 4887 phy_port, phy_id)); 4888 4889 return (phy_id); 4890 } 4891 4892 /* 4893 * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 4894 * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 4895 * read. Then use the values obtained to determine the phy type of each port 4896 * and the Neptune type. 4897 */ 4898 4899 nxge_status_t 4900 nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 4901 { 4902 int i, j, k, l; 4903 uint32_t pma_pmd_dev_id = 0; 4904 uint32_t pcs_dev_id = 0; 4905 uint32_t phy_id = 0; 4906 uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE]; 4907 uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE]; 4908 uint32_t port_phy_id[NXGE_PORTS_NEPTUNE]; 4909 uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 4910 uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 4911 uint8_t phy_fd[NXGE_MAX_PHY_PORTS]; 4912 uint8_t port_fd[NXGE_MAX_PHY_PORTS]; 4913 uint8_t total_port_fd, total_phy_fd; 4914 nxge_status_t status = NXGE_OK; 4915 int prt_id = -1; 4916 4917 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 4918 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4919 "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 4920 nxgep->niu_type)); 4921 4922 j = k = l = 0; 4923 total_port_fd = total_phy_fd = 0; 4924 /* 4925 * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved 4926 * for on chip serdes usages. 4927 */ 4928 for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 4929 4930 pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i); 4931 4932 if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 4933 pma_pmd_dev_fd[i] = 1; 4934 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 4935 "PMA/PMD dev found", i)); 4936 if (j < NXGE_PORTS_NEPTUNE) { 4937 port_pma_pmd_dev_id[j] = pma_pmd_dev_id & 4938 BCM_PHY_ID_MASK; 4939 j++; 4940 } 4941 } else { 4942 pma_pmd_dev_fd[i] = 0; 4943 } 4944 4945 pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i); 4946 4947 if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 4948 pcs_dev_fd[i] = 1; 4949 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 4950 "dev found", i)); 4951 if (k < NXGE_PORTS_NEPTUNE) { 4952 port_pcs_dev_id[k] = pcs_dev_id & 4953 BCM_PHY_ID_MASK; 4954 k++; 4955 } 4956 } else { 4957 pcs_dev_fd[i] = 0; 4958 } 4959 4960 if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) 4961 port_fd[i] = 1; 4962 else 4963 port_fd[i] = 0; 4964 total_port_fd += port_fd[i]; 4965 4966 phy_id = nxge_get_cl22_phy_id(nxgep, i); 4967 4968 if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 4969 phy_fd[i] = 1; 4970 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 4971 "found", i)); 4972 if (l < NXGE_PORTS_NEPTUNE) { 4973 port_phy_id[l] = phy_id & BCM_PHY_ID_MASK; 4974 l++; 4975 } 4976 } else { 4977 phy_fd[i] = 0; 4978 } 4979 total_phy_fd += phy_fd[i]; 4980 } 4981 4982 switch (total_port_fd) { 4983 case 2: 4984 switch (total_phy_fd) { 4985 case 2: 4986 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4987 "Unsupported neptune type 1")); 4988 goto error_exit; 4989 case 1: 4990 /* TODO - 2 10G, 1 1G */ 4991 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4992 "Unsupported neptune type 2 10G, 1 1G")); 4993 goto error_exit; 4994 case 0: 4995 /* 2 10G */ 4996 if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 4997 (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 4998 ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 4999 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) { 5000 5001 /* 5002 * Check the first phy port address against 5003 * the known phy start addresses to determine 5004 * the platform type. 5005 */ 5006 for (i = NXGE_EXT_PHY_PORT_ST; 5007 i < NXGE_MAX_PHY_PORTS; i++) { 5008 if (port_fd[i] == 1) 5009 break; 5010 } 5011 if (i == BCM8704_NEPTUNE_PORT_ADDR_BASE) { 5012 hw_p->niu_type = NEPTUNE_2_10GF; 5013 hw_p->platform_type = 5014 P_NEPTUNE_ATLAS_2PORT; 5015 } else { 5016 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5017 "Unsupported neptune type 2 - 1")); 5018 goto error_exit; 5019 } 5020 hw_p->niu_type = NEPTUNE_2_10GF; 5021 } else { 5022 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5023 "Unsupported neptune type 2")); 5024 goto error_exit; 5025 } 5026 break; 5027 case 4: 5028 /* Maramba with 2 XAUI */ 5029 if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 5030 (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 5031 ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 5032 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) && 5033 ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 5034 (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 5035 (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 5036 (port_phy_id[3] == PHY_BCM5464R_FAMILY))) { 5037 5038 /* 5039 * Check the first phy port address against 5040 * the known phy start addresses to determine 5041 * the platform type. 5042 */ 5043 for (i = NXGE_EXT_PHY_PORT_ST; 5044 i < NXGE_MAX_PHY_PORTS; i++) { 5045 if (phy_fd[i] == 1) 5046 break; 5047 } 5048 if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 5049 hw_p->platform_type = 5050 P_NEPTUNE_MARAMBA_P0; 5051 } else if (i == 5052 BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 5053 hw_p->platform_type = 5054 P_NEPTUNE_MARAMBA_P1; 5055 } else { 5056 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5057 "Unknown port %d...Cannot " 5058 "determine platform type", i)); 5059 goto error_exit; 5060 } 5061 hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 5062 5063 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5064 "Maramba with 2 XAUI")); 5065 } else { 5066 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5067 "Unsupported neptune type 3")); 5068 goto error_exit; 5069 } 5070 break; 5071 default: 5072 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5073 "Unsupported neptune type 5")); 5074 goto error_exit; 5075 } 5076 break; 5077 case 1: 5078 switch (total_phy_fd) { 5079 case 3: 5080 /* 5081 * TODO 3 1G, 1 10G mode. 5082 * Differentiate between 1_1G_1_10G_2_1G and 5083 * 1_10G_3_1G 5084 */ 5085 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5086 "Unsupported neptune type 7")); 5087 goto error_exit; 5088 case 2: 5089 /* 5090 * TODO 2 1G, 1 10G mode. 5091 * Differentiate between 1_1G_1_10G_1_1G and 5092 * 1_10G_2_1G 5093 */ 5094 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5095 "Unsupported neptune type 8")); 5096 goto error_exit; 5097 case 1: 5098 /* 5099 * TODO 1 1G, 1 10G mode. 5100 * Differentiate between 1_1G_1_10G and 5101 * 1_10G_1_1G 5102 */ 5103 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5104 "Unsupported neptune type 9")); 5105 goto error_exit; 5106 case 0: 5107 /* TODO 1 10G mode */ 5108 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5109 "Unsupported neptune type 10")); 5110 goto error_exit; 5111 case 4: 5112 /* Maramba with 1 XAUI */ 5113 if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) || 5114 (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY)) { 5115 5116 /* 5117 * Check the first phy port address against 5118 * the known phy start addresses to determine 5119 * the platform type. 5120 */ 5121 for (i = NXGE_EXT_PHY_PORT_ST; 5122 i < NXGE_MAX_PHY_PORTS; i++) { 5123 if (phy_fd[i] == 1) 5124 break; 5125 } 5126 5127 if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 5128 hw_p->platform_type = 5129 P_NEPTUNE_MARAMBA_P0; 5130 } else if (i == 5131 BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 5132 hw_p->platform_type = 5133 P_NEPTUNE_MARAMBA_P1; 5134 } else { 5135 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5136 "Unknown port %d...Cannot " 5137 "determine platform type", i)); 5138 goto error_exit; 5139 } 5140 5141 /* The 10G port is BCM8704 */ 5142 for (i = NXGE_EXT_PHY_PORT_ST; 5143 i < NXGE_MAX_PHY_PORTS; i++) { 5144 if (port_fd[i] == 1) { 5145 prt_id = i; 5146 break; 5147 } 5148 } 5149 5150 prt_id %= BCM8704_MARAMBA_PORT_ADDR_BASE; 5151 if (prt_id == 0) { 5152 hw_p->niu_type = NEPTUNE_1_10GF_3_1GC; 5153 } else if (prt_id == 1) { 5154 hw_p->niu_type = 5155 NEPTUNE_1_1GC_1_10GF_2_1GC; 5156 } else { 5157 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5158 "Unsupported neptune type 11")); 5159 goto error_exit; 5160 } 5161 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5162 "Maramba with 1 XAUI")); 5163 } else { 5164 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5165 "Unsupported neptune type 12")); 5166 goto error_exit; 5167 } 5168 break; 5169 default: 5170 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5171 "Unsupported neptune type 13")); 5172 goto error_exit; 5173 } 5174 break; 5175 case 0: 5176 switch (total_phy_fd) { 5177 case 4: 5178 if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 5179 (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 5180 (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 5181 (port_phy_id[3] == PHY_BCM5464R_FAMILY)) { 5182 5183 /* 5184 * Check the first phy port address against 5185 * the known phy start addresses to determine 5186 * the platform type. 5187 */ 5188 for (i = NXGE_EXT_PHY_PORT_ST; 5189 i < NXGE_MAX_PHY_PORTS; i++) { 5190 if (phy_fd[i] == 1) 5191 break; 5192 } 5193 5194 if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 5195 hw_p->platform_type = 5196 P_NEPTUNE_MARAMBA_P1; 5197 } else if (i == 5198 BCM5464_NEPTUNE_PORT_ADDR_BASE) { 5199 hw_p->platform_type = 5200 P_NEPTUNE_ATLAS_4PORT; 5201 } else { 5202 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5203 "Unknown port %d...Cannot " 5204 "determine platform type", i)); 5205 goto error_exit; 5206 } 5207 hw_p->niu_type = NEPTUNE_4_1GC; 5208 } else { 5209 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5210 "Unsupported neptune type 14")); 5211 goto error_exit; 5212 } 5213 break; 5214 case 3: 5215 /* TODO 3 1G mode */ 5216 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5217 "Unsupported neptune type 15")); 5218 goto error_exit; 5219 case 2: 5220 /* TODO 2 1G mode */ 5221 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5222 "Unsupported neptune type 16")); 5223 goto error_exit; 5224 case 1: 5225 /* TODO 1 1G mode */ 5226 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5227 "Unsupported neptune type 17")); 5228 goto error_exit; 5229 default: 5230 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5231 "Unsupported neptune type 18, total phy fd %d", 5232 total_phy_fd)); 5233 goto error_exit; 5234 } 5235 break; 5236 default: 5237 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5238 "Unsupported neptune type 19")); 5239 goto error_exit; 5240 } 5241 5242 scan_exit: 5243 5244 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 5245 "niu type [0x%x]\n", hw_p->niu_type)); 5246 return (status); 5247 5248 error_exit: 5249 return (NXGE_ERROR); 5250 } 5251 5252 boolean_t 5253 nxge_is_valid_local_mac(ether_addr_st mac_addr) 5254 { 5255 if ((mac_addr.ether_addr_octet[0] & 0x01) || 5256 (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 5257 (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 5258 return (B_FALSE); 5259 else 5260 return (B_TRUE); 5261 } 5262 5263 static void 5264 nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 5265 5266 npi_status_t rs = NPI_SUCCESS; 5267 uint8_t xcvr_portn; 5268 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 5269 5270 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 5271 5272 if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 5273 xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 5274 } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 5275 xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 5276 } 5277 /* 5278 * For Altas 4-1G copper, Xcvr port numbers are 5279 * swapped with ethernet port number. This is 5280 * designed for better signal integrity in routing. 5281 */ 5282 switch (portn) { 5283 case 0: 5284 xcvr_portn += 3; 5285 break; 5286 case 1: 5287 xcvr_portn += 2; 5288 break; 5289 case 2: 5290 xcvr_portn += 1; 5291 break; 5292 case 3: 5293 default: 5294 break; 5295 } 5296 5297 MUTEX_ENTER(&nxge_mii_lock); 5298 rs = npi_mac_mif_mii_write(nxgep->npi_handle, 5299 xcvr_portn, BCM5464R_MISC, 0xb4ee); 5300 if (rs != NPI_SUCCESS) { 5301 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5302 "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 5303 "returned error 0x[%x]", rs)); 5304 MUTEX_EXIT(&nxge_mii_lock); 5305 return; 5306 } 5307 5308 rs = npi_mac_mif_mii_write(nxgep->npi_handle, 5309 xcvr_portn, BCM5464R_MISC, 0xb8ee); 5310 if (rs != NPI_SUCCESS) { 5311 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5312 "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 5313 "returned error 0x[%x]", rs)); 5314 MUTEX_EXIT(&nxge_mii_lock); 5315 return; 5316 } 5317 5318 MUTEX_EXIT(&nxge_mii_lock); 5319 } 5320 5321 static nxge_status_t 5322 nxge_mii_get_link_mode(p_nxge_t nxgep) 5323 { 5324 p_nxge_stats_t statsp; 5325 uint8_t xcvr_portn; 5326 p_mii_regs_t mii_regs; 5327 mii_mode_control_stat_t mode; 5328 int status = NXGE_OK; 5329 5330 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode")); 5331 5332 statsp = nxgep->statsp; 5333 xcvr_portn = statsp->mac_stats.xcvr_portn; 5334 mii_regs = NULL; 5335 mode.value = 0; 5336 mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 5337 #if defined(__i386) 5338 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5339 (uint8_t)(uint32_t)(&mii_regs->shadow), 5340 mode.value)) != NXGE_OK) { 5341 goto fail; 5342 #else 5343 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5344 (uint8_t)(uint64_t)(&mii_regs->shadow), 5345 mode.value)) != NXGE_OK) { 5346 goto fail; 5347 #endif 5348 } 5349 #if defined(__i386) 5350 if ((status = nxge_mii_read(nxgep, xcvr_portn, 5351 (uint8_t)(uint32_t)(&mii_regs->shadow), 5352 &mode.value)) != NXGE_OK) { 5353 goto fail; 5354 } 5355 #else 5356 if ((status = nxge_mii_read(nxgep, xcvr_portn, 5357 (uint8_t)(uint64_t)(&mii_regs->shadow), 5358 &mode.value)) != NXGE_OK) { 5359 goto fail; 5360 } 5361 #endif 5362 5363 if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) { 5364 nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 5365 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5366 "nxge_mii_get_link_mode: fiber mode")); 5367 } 5368 5369 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5370 "nxge_mii_get_link_mode: " 5371 "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x", 5372 NXGE_MII_MODE_CONTROL_REG, xcvr_portn, 5373 mode.value, nxgep->mac.portmode)); 5374 5375 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5376 "<== nxge_mii_get_link_mode")); 5377 return (status); 5378 fail: 5379 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5380 "<== nxge_mii_get_link_mode (failed)")); 5381 return (NXGE_ERROR); 5382 } 5383 5384 #ifdef NXGE_DEBUG 5385 static void 5386 nxge_mii_dump(p_nxge_t nxgep) 5387 { 5388 p_nxge_stats_t statsp; 5389 uint8_t xcvr_portn; 5390 p_mii_regs_t mii_regs; 5391 mii_bmcr_t bmcr; 5392 mii_bmsr_t bmsr; 5393 mii_idr1_t idr1; 5394 mii_idr2_t idr2; 5395 mii_mode_control_stat_t mode; 5396 5397 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump")); 5398 5399 param_arr = nxgep->param_arr; 5400 statsp = nxgep->statsp; 5401 xcvr_portn = statsp->mac_stats.xcvr_portn; 5402 5403 mii_regs = NULL; 5404 5405 #if defined(__i386) 5406 (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 5407 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value); 5408 #else 5409 (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 5410 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value); 5411 #endif 5412 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5413 "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x", 5414 xcvr_portn, bmcr.value)); 5415 5416 #if defined(__i386) 5417 (void) nxge_mii_read(nxgep, 5418 nxgep->statsp->mac_stats.xcvr_portn, 5419 (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value); 5420 #else 5421 (void) nxge_mii_read(nxgep, 5422 nxgep->statsp->mac_stats.xcvr_portn, 5423 (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value); 5424 #endif 5425 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5426 "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x", 5427 xcvr_portn, bmsr.value)); 5428 5429 #if defined(__i386) 5430 (void) nxge_mii_read(nxgep, 5431 nxgep->statsp->mac_stats.xcvr_portn, 5432 (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value); 5433 #else 5434 (void) nxge_mii_read(nxgep, 5435 nxgep->statsp->mac_stats.xcvr_portn, 5436 (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value); 5437 #endif 5438 5439 5440 #if defined(__i386) 5441 (void) nxge_mii_read(nxgep, 5442 nxgep->statsp->mac_stats.xcvr_portn, 5443 (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value); 5444 #else 5445 (void) nxge_mii_read(nxgep, 5446 nxgep->statsp->mac_stats.xcvr_portn, 5447 (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value); 5448 #endif 5449 5450 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5451 "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x", 5452 xcvr_portn, idr1.value)); 5453 5454 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5455 "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x", 5456 xcvr_portn, idr2.value)); 5457 5458 mode.value = 0; 5459 mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 5460 5461 #if defined(__i386) 5462 (void) nxge_mii_write(nxgep, xcvr_portn, 5463 (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value); 5464 5465 (void) nxge_mii_read(nxgep, xcvr_portn, 5466 (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value); 5467 #else 5468 (void) nxge_mii_write(nxgep, xcvr_portn, 5469 (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value); 5470 5471 (void) nxge_mii_read(nxgep, xcvr_portn, 5472 (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value); 5473 #endif 5474 5475 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5476 "nxge_mii_dump: mode control xcvr 0x%x value 0x%x", 5477 xcvr_portn, mode.value)); 5478 } 5479 #endif 5480