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