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 /* Do not add CRC 4 bytes to the max or the min frame size */ 1941 SET_MAC_ATTR2(handle, ap, portn, 1942 MAC_PORT_FRAME_SIZE, 64, 0x5EE, rs); 1943 } 1944 1945 if (rs != NPI_SUCCESS) 1946 goto fail; 1947 if (nxgep->param_arr[param_accept_jumbo].value || 1948 nxgep->mac.is_jumbo == B_TRUE) 1949 nxgep->mac.maxframesize = 0x2400; 1950 else 1951 nxgep->mac.maxframesize = 0x5EE + 4; 1952 nxgep->mac.minframesize = 64; 1953 1954 if (portt == PORT_TYPE_XMAC) { 1955 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 1956 0)) != NPI_SUCCESS) 1957 goto fail; 1958 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 1959 if ((portmode == PORT_10G_FIBER) || 1960 (portmode == PORT_10G_COPPER) || 1961 (portmode == PORT_10G_SERDES)) { 1962 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 1963 XGMII_IPG_12_15, rs); 1964 if (rs != NPI_SUCCESS) 1965 goto fail; 1966 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 1967 } else { 1968 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 1969 MII_GMII_IPG_12, rs); 1970 if (rs != NPI_SUCCESS) 1971 goto fail; 1972 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 1973 } 1974 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 1975 CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 1976 goto fail; 1977 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 1978 nxgep->mac.maxburstsize = 0; /* not programmable */ 1979 nxgep->mac.ctrltype = 0; /* not programmable */ 1980 nxgep->mac.pa_size = 0; /* not programmable */ 1981 1982 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 1983 != NPI_SUCCESS) 1984 goto fail; 1985 1986 } else { 1987 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 1988 0)) != NPI_SUCCESS) 1989 goto fail; 1990 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 1991 1992 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 1993 rs); 1994 if (rs != NPI_SUCCESS) 1995 goto fail; 1996 nxgep->mac.ctrltype = 0x8808; 1997 1998 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 1999 if (rs != NPI_SUCCESS) 2000 goto fail; 2001 nxgep->mac.pa_size = 0x7; 2002 2003 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 2004 CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 2005 goto fail; 2006 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 2007 } 2008 2009 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 2010 portn)); 2011 2012 return (NXGE_OK); 2013 fail: 2014 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2015 "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", 2016 portn)); 2017 2018 return (NXGE_ERROR | rs); 2019 } 2020 2021 /* Initialize the RxMAC sub-block */ 2022 2023 nxge_status_t 2024 nxge_rx_mac_init(p_nxge_t nxgep) 2025 { 2026 npi_attr_t ap; 2027 uint32_t i; 2028 uint16_t hashtab_e; 2029 p_hash_filter_t hash_filter; 2030 nxge_port_t portt; 2031 uint8_t portn; 2032 npi_handle_t handle; 2033 npi_status_t rs = NPI_SUCCESS; 2034 uint16_t *addr16p; 2035 uint16_t addr0, addr1, addr2; 2036 xmac_rx_config_t xconfig; 2037 bmac_rx_config_t bconfig; 2038 2039 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2040 2041 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 2042 portn)); 2043 handle = nxgep->npi_handle; 2044 portt = nxgep->mac.porttype; 2045 2046 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 2047 addr0 = ntohs(addr16p[2]); 2048 addr1 = ntohs(addr16p[1]); 2049 addr2 = ntohs(addr16p[0]); 2050 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 2051 rs); 2052 2053 if (rs != NPI_SUCCESS) 2054 goto fail; 2055 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 2056 if (rs != NPI_SUCCESS) 2057 goto fail; 2058 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 2059 if (rs != NPI_SUCCESS) 2060 goto fail; 2061 2062 /* 2063 * Load the multicast hash filter bits. 2064 */ 2065 hash_filter = nxgep->hash_filter; 2066 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 2067 if (hash_filter != NULL) { 2068 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 2069 (NMCFILTER_REGS - 1) - i]; 2070 } else { 2071 hashtab_e = 0; 2072 } 2073 2074 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 2075 (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 2076 goto fail; 2077 } 2078 2079 if (portt == PORT_TYPE_XMAC) { 2080 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 2081 0)) != NPI_SUCCESS) 2082 goto fail; 2083 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 2084 2085 (void) nxge_fflp_init_hostinfo(nxgep); 2086 2087 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 2088 CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 2089 ~CFG_XMAC_RX_STRIP_CRC; 2090 2091 if (nxgep->filter.all_phys_cnt != 0) 2092 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 2093 2094 if (nxgep->filter.all_multicast_cnt != 0) 2095 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 2096 2097 xconfig |= CFG_XMAC_RX_HASH_FILTER; 2098 2099 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 2100 xconfig)) != NPI_SUCCESS) 2101 goto fail; 2102 nxgep->mac.rx_config = xconfig; 2103 2104 /* Comparison of mac unique address is always enabled on XMAC */ 2105 2106 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 2107 != NPI_SUCCESS) 2108 goto fail; 2109 } else { 2110 (void) nxge_fflp_init_hostinfo(nxgep); 2111 2112 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 2113 0) != NPI_SUCCESS) 2114 goto fail; 2115 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 2116 2117 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 2118 ~CFG_BMAC_RX_STRIP_CRC; 2119 2120 if (nxgep->filter.all_phys_cnt != 0) 2121 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 2122 2123 if (nxgep->filter.all_multicast_cnt != 0) 2124 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 2125 2126 bconfig |= CFG_BMAC_RX_HASH_FILTER; 2127 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 2128 bconfig)) != NPI_SUCCESS) 2129 goto fail; 2130 nxgep->mac.rx_config = bconfig; 2131 2132 /* Always enable comparison of mac unique address */ 2133 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 2134 != NPI_SUCCESS) 2135 goto fail; 2136 } 2137 2138 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 2139 portn)); 2140 2141 return (NXGE_OK); 2142 2143 fail: 2144 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2145 "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", 2146 portn)); 2147 2148 return (NXGE_ERROR | rs); 2149 } 2150 2151 /* Enable TXMAC */ 2152 2153 nxge_status_t 2154 nxge_tx_mac_enable(p_nxge_t nxgep) 2155 { 2156 npi_handle_t handle; 2157 npi_status_t rs = NPI_SUCCESS; 2158 nxge_status_t status = NXGE_OK; 2159 2160 handle = nxgep->npi_handle; 2161 2162 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 2163 nxgep->mac.portnum)); 2164 2165 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 2166 goto fail; 2167 2168 /* based on speed */ 2169 nxgep->msg_min = ETHERMIN; 2170 2171 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2172 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 2173 CFG_XMAC_TX)) != NPI_SUCCESS) 2174 goto fail; 2175 } else { 2176 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 2177 CFG_BMAC_TX)) != NPI_SUCCESS) 2178 goto fail; 2179 } 2180 2181 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 2182 nxgep->mac.portnum)); 2183 2184 return (NXGE_OK); 2185 fail: 2186 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2187 "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 2188 nxgep->mac.portnum)); 2189 if (rs != NPI_SUCCESS) 2190 return (NXGE_ERROR | rs); 2191 else 2192 return (status); 2193 } 2194 2195 /* Disable TXMAC */ 2196 2197 nxge_status_t 2198 nxge_tx_mac_disable(p_nxge_t nxgep) 2199 { 2200 npi_handle_t handle; 2201 npi_status_t rs = NPI_SUCCESS; 2202 2203 handle = nxgep->npi_handle; 2204 2205 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 2206 nxgep->mac.portnum)); 2207 2208 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2209 if ((rs = npi_xmac_tx_config(handle, DISABLE, 2210 nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 2211 goto fail; 2212 } else { 2213 if ((rs = npi_bmac_tx_config(handle, DISABLE, 2214 nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 2215 goto fail; 2216 } 2217 2218 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 2219 nxgep->mac.portnum)); 2220 return (NXGE_OK); 2221 fail: 2222 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2223 "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 2224 nxgep->mac.portnum)); 2225 return (NXGE_ERROR | rs); 2226 } 2227 2228 /* Enable RXMAC */ 2229 2230 nxge_status_t 2231 nxge_rx_mac_enable(p_nxge_t nxgep) 2232 { 2233 npi_handle_t handle; 2234 uint8_t portn; 2235 npi_status_t rs = NPI_SUCCESS; 2236 nxge_status_t status = NXGE_OK; 2237 2238 handle = nxgep->npi_handle; 2239 portn = nxgep->mac.portnum; 2240 2241 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 2242 portn)); 2243 2244 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 2245 goto fail; 2246 2247 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2248 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 2249 CFG_XMAC_RX)) != NPI_SUCCESS) 2250 goto fail; 2251 } else { 2252 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 2253 CFG_BMAC_RX)) != NPI_SUCCESS) 2254 goto fail; 2255 } 2256 2257 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>", 2258 portn)); 2259 2260 return (NXGE_OK); 2261 fail: 2262 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2263 "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", 2264 portn)); 2265 2266 if (rs != NPI_SUCCESS) 2267 return (NXGE_ERROR | rs); 2268 else 2269 return (status); 2270 } 2271 2272 /* Disable RXMAC */ 2273 2274 nxge_status_t 2275 nxge_rx_mac_disable(p_nxge_t nxgep) 2276 { 2277 npi_handle_t handle; 2278 uint8_t portn; 2279 npi_status_t rs = NPI_SUCCESS; 2280 2281 handle = nxgep->npi_handle; 2282 portn = nxgep->mac.portnum; 2283 2284 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 2285 portn)); 2286 2287 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2288 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 2289 CFG_XMAC_RX)) != NPI_SUCCESS) 2290 goto fail; 2291 } else { 2292 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 2293 CFG_BMAC_RX)) != NPI_SUCCESS) 2294 goto fail; 2295 } 2296 2297 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 2298 portn)); 2299 return (NXGE_OK); 2300 fail: 2301 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2302 "nxgep_rx_mac_disable: ", 2303 "Failed to disable port<%d> RxMAC", 2304 portn)); 2305 2306 return (NXGE_ERROR | rs); 2307 } 2308 2309 /* Reset TXMAC */ 2310 2311 nxge_status_t 2312 nxge_tx_mac_reset(p_nxge_t nxgep) 2313 { 2314 npi_handle_t handle; 2315 uint8_t portn; 2316 npi_status_t rs = NPI_SUCCESS; 2317 2318 handle = nxgep->npi_handle; 2319 portn = nxgep->mac.portnum; 2320 2321 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 2322 portn)); 2323 2324 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2325 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 2326 != NPI_SUCCESS) 2327 goto fail; 2328 } else { 2329 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 2330 != NPI_SUCCESS) 2331 goto fail; 2332 } 2333 2334 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 2335 portn)); 2336 2337 return (NXGE_OK); 2338 fail: 2339 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2340 "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", 2341 portn)); 2342 2343 return (NXGE_ERROR | rs); 2344 } 2345 2346 /* Reset RXMAC */ 2347 2348 nxge_status_t 2349 nxge_rx_mac_reset(p_nxge_t nxgep) 2350 { 2351 npi_handle_t handle; 2352 uint8_t portn; 2353 npi_status_t rs = NPI_SUCCESS; 2354 2355 handle = nxgep->npi_handle; 2356 portn = nxgep->mac.portnum; 2357 2358 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 2359 portn)); 2360 2361 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 2362 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 2363 != NPI_SUCCESS) 2364 goto fail; 2365 } else { 2366 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 2367 != NPI_SUCCESS) 2368 goto fail; 2369 } 2370 2371 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 2372 portn)); 2373 2374 return (NXGE_OK); 2375 fail: 2376 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2377 "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", 2378 portn)); 2379 return (NXGE_ERROR | rs); 2380 } 2381 2382 /* 10G fiber link interrupt start routine */ 2383 2384 static nxge_status_t 2385 nxge_10G_link_intr_start(p_nxge_t nxgep) 2386 { 2387 npi_status_t rs = NPI_SUCCESS; 2388 uint8_t portn = nxgep->mac.portnum; 2389 2390 rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 2391 2392 if (rs != NPI_SUCCESS) 2393 return (NXGE_ERROR | rs); 2394 else 2395 return (NXGE_OK); 2396 } 2397 2398 /* 10G fiber link interrupt stop routine */ 2399 2400 static nxge_status_t 2401 nxge_10G_link_intr_stop(p_nxge_t nxgep) 2402 { 2403 npi_status_t rs = NPI_SUCCESS; 2404 uint8_t portn = nxgep->mac.portnum; 2405 2406 rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 2407 2408 if (rs != NPI_SUCCESS) 2409 return (NXGE_ERROR | rs); 2410 else 2411 return (NXGE_OK); 2412 } 2413 2414 /* 1G fiber link interrupt start routine */ 2415 2416 static nxge_status_t 2417 nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 2418 { 2419 npi_status_t rs = NPI_SUCCESS; 2420 uint8_t portn = nxgep->mac.portnum; 2421 2422 rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 2423 if (rs != NPI_SUCCESS) 2424 return (NXGE_ERROR | rs); 2425 else 2426 return (NXGE_OK); 2427 } 2428 2429 /* 1G fiber link interrupt stop routine */ 2430 2431 static nxge_status_t 2432 nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 2433 { 2434 npi_status_t rs = NPI_SUCCESS; 2435 uint8_t portn = nxgep->mac.portnum; 2436 2437 rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 2438 2439 if (rs != NPI_SUCCESS) 2440 return (NXGE_ERROR | rs); 2441 else 2442 return (NXGE_OK); 2443 } 2444 2445 /* 1G copper link interrupt start routine */ 2446 2447 static nxge_status_t 2448 nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 2449 { 2450 npi_status_t rs = NPI_SUCCESS; 2451 uint8_t portn = nxgep->mac.portnum; 2452 2453 rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 2454 MII_STATUS, MII_STATUS_LINKUP); 2455 2456 if (rs != NPI_SUCCESS) 2457 return (NXGE_ERROR | rs); 2458 else 2459 return (NXGE_OK); 2460 } 2461 2462 /* 1G copper link interrupt stop routine */ 2463 2464 static nxge_status_t 2465 nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 2466 { 2467 npi_status_t rs = NPI_SUCCESS; 2468 uint8_t portn = nxgep->mac.portnum; 2469 2470 rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 2471 2472 if (rs != NPI_SUCCESS) 2473 return (NXGE_ERROR | rs); 2474 else 2475 return (NXGE_OK); 2476 } 2477 2478 /* Enable/Disable Link Status change interrupt */ 2479 2480 nxge_status_t 2481 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 2482 { 2483 uint8_t portn; 2484 nxge_status_t status = NXGE_OK; 2485 2486 portn = nxgep->mac.portnum; 2487 2488 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 2489 if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 2490 return (NXGE_OK); 2491 2492 if (enable == LINK_INTR_START) 2493 status = nxgep->xcvr.link_intr_start(nxgep); 2494 else if (enable == LINK_INTR_STOP) 2495 status = nxgep->xcvr.link_intr_stop(nxgep); 2496 if (status != NXGE_OK) 2497 goto fail; 2498 2499 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 2500 2501 return (NXGE_OK); 2502 fail: 2503 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2504 "nxge_link_intr: Failed to set port<%d> mif intr mode", 2505 portn)); 2506 2507 return (status); 2508 } 2509 2510 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 2511 2512 nxge_status_t 2513 nxge_mii_xcvr_init(p_nxge_t nxgep) 2514 { 2515 p_nxge_param_t param_arr; 2516 p_nxge_stats_t statsp; 2517 uint8_t xcvr_portn; 2518 p_mii_regs_t mii_regs; 2519 mii_bmcr_t bmcr; 2520 mii_bmsr_t bmsr; 2521 mii_anar_t anar; 2522 mii_gcr_t gcr; 2523 mii_esr_t esr; 2524 mii_aux_ctl_t bcm5464r_aux; 2525 int status = NXGE_OK; 2526 2527 uint_t delay; 2528 2529 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 2530 2531 param_arr = nxgep->param_arr; 2532 statsp = nxgep->statsp; 2533 xcvr_portn = statsp->mac_stats.xcvr_portn; 2534 2535 mii_regs = NULL; 2536 2537 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2538 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 2539 2540 /* 2541 * The mif phy mode may be connected to either a copper link 2542 * or fiber link. Read the mode control register to get the fiber 2543 * configuration if it is hard-wired to fiber link. 2544 */ 2545 (void) nxge_mii_get_link_mode(nxgep); 2546 if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 2547 return (nxge_mii_xcvr_fiber_init(nxgep)); 2548 } 2549 2550 /* 2551 * Reset the transceiver. 2552 */ 2553 delay = 0; 2554 bmcr.value = 0; 2555 bmcr.bits.reset = 1; 2556 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2557 #if defined(__i386) 2558 (uint8_t)(uint32_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 2559 #else 2560 (uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 2561 #endif 2562 goto fail; 2563 do { 2564 drv_usecwait(500); 2565 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2566 #if defined(__i386) 2567 (uint8_t)(uint32_t)&mii_regs->bmcr, &bmcr.value)) 2568 #else 2569 (uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value)) 2570 #endif 2571 != NXGE_OK) 2572 goto fail; 2573 delay++; 2574 } while ((bmcr.bits.reset) && (delay < 1000)); 2575 if (delay == 1000) { 2576 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 2577 goto fail; 2578 } 2579 2580 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2581 #if defined(__i386) 2582 (uint8_t)(uint32_t)(&mii_regs->bmsr), 2583 #else 2584 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2585 #endif 2586 &bmsr.value)) != NXGE_OK) 2587 goto fail; 2588 2589 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 2590 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 2591 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 2592 param_arr[param_anar_100hdx].value = 0; 2593 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 2594 param_arr[param_anar_10hdx].value = 0; 2595 2596 /* 2597 * Initialize the xcvr statistics. 2598 */ 2599 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 2600 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 2601 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 2602 statsp->mac_stats.cap_100hdx = 0; 2603 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 2604 statsp->mac_stats.cap_10hdx = 0; 2605 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 2606 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 2607 2608 /* 2609 * Initialise the xcvr advertised capability statistics. 2610 */ 2611 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 2612 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 2613 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 2614 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 2615 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 2616 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 2617 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 2618 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 2619 statsp->mac_stats.adv_cap_asmpause = 2620 param_arr[param_anar_asmpause].value; 2621 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 2622 2623 2624 /* 2625 * Check for extended status just in case we're 2626 * running a Gigibit phy. 2627 */ 2628 if (bmsr.bits.extend_status) { 2629 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2630 #if defined(__i386) 2631 (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) 2632 #else 2633 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) 2634 #endif 2635 != NXGE_OK) 2636 goto fail; 2637 param_arr[param_anar_1000fdx].value &= 2638 esr.bits.link_1000fdx; 2639 param_arr[param_anar_1000hdx].value = 0; 2640 2641 statsp->mac_stats.cap_1000fdx = 2642 (esr.bits.link_1000Xfdx || 2643 esr.bits.link_1000fdx); 2644 statsp->mac_stats.cap_1000hdx = 0; 2645 } else { 2646 param_arr[param_anar_1000fdx].value = 0; 2647 param_arr[param_anar_1000hdx].value = 0; 2648 } 2649 2650 /* 2651 * Initialize 1G Statistics once the capability is established. 2652 */ 2653 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 2654 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 2655 2656 /* 2657 * Initialise the link statistics. 2658 */ 2659 statsp->mac_stats.link_T4 = 0; 2660 statsp->mac_stats.link_asmpause = 0; 2661 statsp->mac_stats.link_pause = 0; 2662 statsp->mac_stats.link_speed = 0; 2663 statsp->mac_stats.link_duplex = 0; 2664 statsp->mac_stats.link_up = 0; 2665 2666 /* 2667 * Switch off Auto-negotiation, 100M and full duplex. 2668 */ 2669 bmcr.value = 0; 2670 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2671 #if defined(__i386) 2672 (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 2673 #else 2674 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 2675 #endif 2676 goto fail; 2677 2678 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 2679 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 2680 bmcr.bits.loopback = 1; 2681 bmcr.bits.enable_autoneg = 0; 2682 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 2683 bmcr.bits.speed_1000_sel = 1; 2684 bmcr.bits.duplex_mode = 1; 2685 param_arr[param_autoneg].value = 0; 2686 } else { 2687 bmcr.bits.loopback = 0; 2688 } 2689 2690 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 2691 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 2692 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 2693 param_arr[param_autoneg].value = 0; 2694 bcm5464r_aux.value = 0; 2695 bcm5464r_aux.bits.ext_lb = 1; 2696 bcm5464r_aux.bits.write_1 = 1; 2697 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2698 BCM5464R_AUX_CTL, bcm5464r_aux.value)) 2699 != NXGE_OK) 2700 goto fail; 2701 } 2702 2703 if (param_arr[param_autoneg].value) { 2704 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2705 "Restarting Auto-negotiation.")); 2706 /* 2707 * Setup our Auto-negotiation advertisement register. 2708 */ 2709 anar.value = 0; 2710 anar.bits.selector = 1; 2711 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 2712 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 2713 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 2714 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 2715 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 2716 anar.bits.cap_asmpause = 0; 2717 anar.bits.cap_pause = 0; 2718 if (param_arr[param_anar_1000fdx].value || 2719 param_arr[param_anar_100fdx].value || 2720 param_arr[param_anar_10fdx].value) { 2721 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 2722 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 2723 } 2724 2725 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2726 #if defined(__i386) 2727 (uint8_t)(uint32_t)(&mii_regs->anar), anar.value)) 2728 #else 2729 (uint8_t)(uint64_t)(&mii_regs->anar), anar.value)) 2730 #endif 2731 != NXGE_OK) 2732 goto fail; 2733 if (bmsr.bits.extend_status) { 2734 gcr.value = 0; 2735 gcr.bits.ms_mode_en = 2736 param_arr[param_master_cfg_enable].value; 2737 gcr.bits.master = 2738 param_arr[param_master_cfg_value].value; 2739 gcr.bits.link_1000fdx = 2740 param_arr[param_anar_1000fdx].value; 2741 gcr.bits.link_1000hdx = 2742 param_arr[param_anar_1000hdx].value; 2743 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2744 #if defined(__i386) 2745 (uint8_t)(uint32_t)(&mii_regs->gcr), gcr.value)) 2746 #else 2747 (uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value)) 2748 #endif 2749 != NXGE_OK) 2750 goto fail; 2751 } 2752 2753 bmcr.bits.enable_autoneg = 1; 2754 bmcr.bits.restart_autoneg = 1; 2755 2756 } else { 2757 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 2758 bmcr.bits.speed_1000_sel = 2759 param_arr[param_anar_1000fdx].value | 2760 param_arr[param_anar_1000hdx].value; 2761 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 2762 (param_arr[param_anar_100fdx].value | 2763 param_arr[param_anar_100hdx].value); 2764 if (bmcr.bits.speed_1000_sel) { 2765 statsp->mac_stats.link_speed = 1000; 2766 gcr.value = 0; 2767 gcr.bits.ms_mode_en = 2768 param_arr[param_master_cfg_enable].value; 2769 gcr.bits.master = 2770 param_arr[param_master_cfg_value].value; 2771 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2772 #if defined(__i386) 2773 (uint8_t)(uint32_t)(&mii_regs->gcr), 2774 #else 2775 (uint8_t)(uint64_t)(&mii_regs->gcr), 2776 #endif 2777 gcr.value)) 2778 != NXGE_OK) 2779 goto fail; 2780 if (param_arr[param_anar_1000fdx].value) { 2781 bmcr.bits.duplex_mode = 1; 2782 statsp->mac_stats.link_duplex = 2; 2783 } else 2784 statsp->mac_stats.link_duplex = 1; 2785 } else if (bmcr.bits.speed_sel) { 2786 statsp->mac_stats.link_speed = 100; 2787 if (param_arr[param_anar_100fdx].value) { 2788 bmcr.bits.duplex_mode = 1; 2789 statsp->mac_stats.link_duplex = 2; 2790 } else 2791 statsp->mac_stats.link_duplex = 1; 2792 } else { 2793 statsp->mac_stats.link_speed = 10; 2794 if (param_arr[param_anar_10fdx].value) { 2795 bmcr.bits.duplex_mode = 1; 2796 statsp->mac_stats.link_duplex = 2; 2797 } else 2798 statsp->mac_stats.link_duplex = 1; 2799 } 2800 if (statsp->mac_stats.link_duplex != 1) { 2801 statsp->mac_stats.link_asmpause = 2802 statsp->mac_stats.cap_asmpause; 2803 statsp->mac_stats.link_pause = 2804 statsp->mac_stats.cap_pause; 2805 } 2806 2807 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 2808 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 2809 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 2810 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 2811 /* BCM5464R 1000mbps external loopback mode */ 2812 gcr.value = 0; 2813 gcr.bits.ms_mode_en = 1; 2814 gcr.bits.master = 1; 2815 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2816 #if defined(__i386) 2817 (uint8_t)(uint32_t)(&mii_regs->gcr), 2818 #else 2819 (uint8_t)(uint64_t)(&mii_regs->gcr), 2820 #endif 2821 gcr.value)) 2822 != NXGE_OK) 2823 goto fail; 2824 bmcr.value = 0; 2825 bmcr.bits.speed_1000_sel = 1; 2826 statsp->mac_stats.link_speed = 1000; 2827 } else if (statsp->port_stats.lb_mode 2828 == nxge_lb_ext100) { 2829 /* BCM5464R 100mbps external loopback mode */ 2830 bmcr.value = 0; 2831 bmcr.bits.speed_sel = 1; 2832 bmcr.bits.duplex_mode = 1; 2833 statsp->mac_stats.link_speed = 100; 2834 } else if (statsp->port_stats.lb_mode 2835 == nxge_lb_ext10) { 2836 /* BCM5464R 10mbps external loopback mode */ 2837 bmcr.value = 0; 2838 bmcr.bits.duplex_mode = 1; 2839 statsp->mac_stats.link_speed = 10; 2840 } 2841 } 2842 } 2843 2844 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2845 #if defined(__i386) 2846 (uint8_t)(uint32_t)(&mii_regs->bmcr), 2847 #else 2848 (uint8_t)(uint64_t)(&mii_regs->bmcr), 2849 #endif 2850 bmcr.value)) != NXGE_OK) 2851 goto fail; 2852 2853 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2854 #if defined(__i386) 2855 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 2856 #else 2857 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 2858 #endif 2859 goto fail; 2860 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 2861 2862 /* 2863 * Initialize the xcvr status kept in the context structure. 2864 */ 2865 nxgep->soft_bmsr.value = 0; 2866 2867 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2868 #if defined(__i386) 2869 (uint8_t)(uint32_t)(&mii_regs->bmsr), 2870 #else 2871 (uint8_t)(uint64_t)(&mii_regs->bmsr), 2872 #endif 2873 &nxgep->bmsr.value)) != NXGE_OK) 2874 goto fail; 2875 2876 statsp->mac_stats.xcvr_inits++; 2877 nxgep->bmsr.value = 0; 2878 2879 fail: 2880 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2881 "<== nxge_mii_xcvr_init status 0x%x", status)); 2882 return (status); 2883 } 2884 2885 nxge_status_t 2886 nxge_mii_xcvr_fiber_init(p_nxge_t nxgep) 2887 { 2888 p_nxge_param_t param_arr; 2889 p_nxge_stats_t statsp; 2890 uint8_t xcvr_portn; 2891 p_mii_regs_t mii_regs; 2892 mii_bmcr_t bmcr; 2893 mii_bmsr_t bmsr; 2894 mii_gcr_t gcr; 2895 mii_esr_t esr; 2896 mii_aux_ctl_t bcm5464r_aux; 2897 int status = NXGE_OK; 2898 2899 uint_t delay; 2900 2901 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init")); 2902 2903 param_arr = nxgep->param_arr; 2904 statsp = nxgep->statsp; 2905 xcvr_portn = statsp->mac_stats.xcvr_portn; 2906 2907 mii_regs = NULL; 2908 2909 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2910 "nxge_mii_xcvr_fiber_init: " 2911 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 2912 2913 /* 2914 * Reset the transceiver. 2915 */ 2916 delay = 0; 2917 bmcr.value = 0; 2918 bmcr.bits.reset = 1; 2919 2920 #if defined(__i386) 2921 2922 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2923 (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 2924 goto fail; 2925 #else 2926 if ((status = nxge_mii_write(nxgep, xcvr_portn, 2927 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 2928 goto fail; 2929 #endif 2930 do { 2931 drv_usecwait(500); 2932 #if defined(__i386) 2933 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2934 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) 2935 != NXGE_OK) 2936 goto fail; 2937 #else 2938 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2939 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) 2940 != NXGE_OK) 2941 goto fail; 2942 #endif 2943 delay++; 2944 } while ((bmcr.bits.reset) && (delay < 1000)); 2945 if (delay == 1000) { 2946 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 2947 goto fail; 2948 } 2949 2950 #if defined(__i386) 2951 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2952 (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 2953 goto fail; 2954 #else 2955 if ((status = nxge_mii_read(nxgep, xcvr_portn, 2956 (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 2957 goto fail; 2958 #endif 2959 2960 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 2961 param_arr[param_anar_100T4].value = 0; 2962 param_arr[param_anar_100fdx].value = 0; 2963 param_arr[param_anar_100hdx].value = 0; 2964 param_arr[param_anar_10fdx].value = 0; 2965 param_arr[param_anar_10hdx].value = 0; 2966 2967 /* 2968 * Initialize the xcvr statistics. 2969 */ 2970 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 2971 statsp->mac_stats.cap_100T4 = 0; 2972 statsp->mac_stats.cap_100fdx = 0; 2973 statsp->mac_stats.cap_100hdx = 0; 2974 statsp->mac_stats.cap_10fdx = 0; 2975 statsp->mac_stats.cap_10hdx = 0; 2976 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 2977 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 2978 2979 /* 2980 * Initialize the xcvr advertised capability statistics. 2981 */ 2982 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 2983 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 2984 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 2985 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 2986 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 2987 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 2988 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 2989 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 2990 statsp->mac_stats.adv_cap_asmpause = 2991 param_arr[param_anar_asmpause].value; 2992 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 2993 2994 /* 2995 * Check for extended status just in case we're 2996 * running a Gigibit phy. 2997 */ 2998 if (bmsr.bits.extend_status) { 2999 #if defined(__i386) 3000 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3001 (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) != 3002 NXGE_OK) 3003 goto fail; 3004 #else 3005 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3006 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) != 3007 NXGE_OK) 3008 goto fail; 3009 #endif 3010 param_arr[param_anar_1000fdx].value &= 3011 esr.bits.link_1000fdx; 3012 param_arr[param_anar_1000hdx].value = 0; 3013 3014 statsp->mac_stats.cap_1000fdx = 3015 (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 3016 statsp->mac_stats.cap_1000hdx = 0; 3017 } else { 3018 param_arr[param_anar_1000fdx].value = 0; 3019 param_arr[param_anar_1000hdx].value = 0; 3020 } 3021 3022 /* 3023 * Initialize 1G Statistics once the capability is established. 3024 */ 3025 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 3026 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 3027 3028 /* 3029 * Initialize the link statistics. 3030 */ 3031 statsp->mac_stats.link_T4 = 0; 3032 statsp->mac_stats.link_asmpause = 0; 3033 statsp->mac_stats.link_pause = 0; 3034 statsp->mac_stats.link_speed = 0; 3035 statsp->mac_stats.link_duplex = 0; 3036 statsp->mac_stats.link_up = 0; 3037 3038 /* 3039 * Switch off Auto-negotiation, 100M and full duplex. 3040 */ 3041 bmcr.value = 0; 3042 #if defined(__i386) 3043 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3044 (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 3045 goto fail; 3046 #else 3047 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3048 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 3049 goto fail; 3050 #endif 3051 3052 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 3053 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 3054 bmcr.bits.loopback = 1; 3055 bmcr.bits.enable_autoneg = 0; 3056 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 3057 bmcr.bits.speed_1000_sel = 1; 3058 bmcr.bits.duplex_mode = 1; 3059 param_arr[param_autoneg].value = 0; 3060 } else { 3061 bmcr.bits.loopback = 0; 3062 } 3063 3064 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 3065 param_arr[param_autoneg].value = 0; 3066 bcm5464r_aux.value = 0; 3067 bcm5464r_aux.bits.ext_lb = 1; 3068 bcm5464r_aux.bits.write_1 = 1; 3069 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3070 BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 3071 goto fail; 3072 } 3073 3074 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 3075 bmcr.bits.speed_1000_sel = 1; 3076 bmcr.bits.speed_sel = 0; 3077 bmcr.bits.duplex_mode = 1; 3078 statsp->mac_stats.link_speed = 1000; 3079 statsp->mac_stats.link_duplex = 2; 3080 3081 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) { 3082 /* BCM5464R 1000mbps external loopback mode */ 3083 gcr.value = 0; 3084 gcr.bits.ms_mode_en = 1; 3085 gcr.bits.master = 1; 3086 #if defined(__i386) 3087 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3088 (uint8_t)(uint32_t)(&mii_regs->gcr), 3089 gcr.value)) != NXGE_OK) 3090 goto fail; 3091 #else 3092 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3093 (uint8_t)(uint64_t)(&mii_regs->gcr), 3094 gcr.value)) != NXGE_OK) 3095 goto fail; 3096 #endif 3097 bmcr.value = 0; 3098 bmcr.bits.speed_1000_sel = 1; 3099 statsp->mac_stats.link_speed = 1000; 3100 } 3101 3102 #if defined(__i386) 3103 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3104 (uint8_t)(uint32_t)(&mii_regs->bmcr), 3105 bmcr.value)) != NXGE_OK) 3106 goto fail; 3107 #else 3108 if ((status = nxge_mii_write(nxgep, xcvr_portn, 3109 (uint8_t)(uint64_t)(&mii_regs->bmcr), 3110 bmcr.value)) != NXGE_OK) 3111 goto fail; 3112 #endif 3113 3114 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3115 "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x", 3116 bmcr.value)); 3117 3118 #if defined(__i386) 3119 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3120 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 3121 goto fail; 3122 #else 3123 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3124 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 3125 goto fail; 3126 #endif 3127 3128 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3129 "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value)); 3130 3131 /* 3132 * Initialize the xcvr status kept in the context structure. 3133 */ 3134 nxgep->soft_bmsr.value = 0; 3135 #if defined(__i386) 3136 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3137 (uint8_t)(uint32_t)(&mii_regs->bmsr), 3138 &nxgep->bmsr.value)) != NXGE_OK) 3139 goto fail; 3140 #else 3141 if ((status = nxge_mii_read(nxgep, xcvr_portn, 3142 (uint8_t)(uint64_t)(&mii_regs->bmsr), 3143 &nxgep->bmsr.value)) != NXGE_OK) 3144 goto fail; 3145 #endif 3146 3147 statsp->mac_stats.xcvr_inits++; 3148 nxgep->bmsr.value = 0; 3149 3150 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3151 "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 3152 return (status); 3153 3154 fail: 3155 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3156 "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 3157 return (status); 3158 } 3159 3160 /* Read from a MII compliant register */ 3161 3162 nxge_status_t 3163 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 3164 uint16_t *value) 3165 { 3166 npi_status_t rs = NPI_SUCCESS; 3167 3168 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 3169 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 3170 3171 MUTEX_ENTER(&nxge_mii_lock); 3172 3173 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 3174 (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 3175 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 3176 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3177 goto fail; 3178 } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 3179 (nxgep->mac.portmode == PORT_1G_SERDES)) { 3180 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 3181 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3182 goto fail; 3183 } else 3184 goto fail; 3185 3186 MUTEX_EXIT(&nxge_mii_lock); 3187 3188 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 3189 "xcvr_reg<%d> value=0x%x", 3190 xcvr_portn, xcvr_reg, *value)); 3191 return (NXGE_OK); 3192 fail: 3193 MUTEX_EXIT(&nxge_mii_lock); 3194 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3195 "nxge_mii_read: Failed to read mii on xcvr %d", 3196 xcvr_portn)); 3197 3198 return (NXGE_ERROR | rs); 3199 } 3200 3201 /* Write to a MII compliant Register */ 3202 3203 nxge_status_t 3204 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 3205 uint16_t value) 3206 { 3207 npi_status_t rs = NPI_SUCCESS; 3208 3209 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 3210 "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, 3211 value)); 3212 3213 MUTEX_ENTER(&nxge_mii_lock); 3214 3215 if ((nxgep->mac.portmode == PORT_1G_COPPER) || 3216 (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 3217 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 3218 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3219 goto fail; 3220 } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 3221 (nxgep->mac.portmode == PORT_1G_SERDES)) { 3222 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 3223 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 3224 goto fail; 3225 } else 3226 goto fail; 3227 3228 MUTEX_EXIT(&nxge_mii_lock); 3229 3230 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 3231 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 3232 return (NXGE_OK); 3233 fail: 3234 MUTEX_EXIT(&nxge_mii_lock); 3235 3236 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3237 "nxge_mii_write: Failed to write mii on xcvr %d", 3238 xcvr_portn)); 3239 3240 return (NXGE_ERROR | rs); 3241 } 3242 3243 /* Perform read from Clause45 serdes / transceiver device */ 3244 3245 nxge_status_t 3246 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 3247 uint16_t xcvr_reg, uint16_t *value) 3248 { 3249 npi_status_t rs = NPI_SUCCESS; 3250 3251 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 3252 xcvr_portn)); 3253 3254 MUTEX_ENTER(&nxge_mdio_lock); 3255 3256 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 3257 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 3258 goto fail; 3259 3260 MUTEX_EXIT(&nxge_mdio_lock); 3261 3262 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 3263 xcvr_portn)); 3264 return (NXGE_OK); 3265 fail: 3266 MUTEX_EXIT(&nxge_mdio_lock); 3267 3268 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3269 "nxge_mdio_read: Failed to read mdio on xcvr %d", 3270 xcvr_portn)); 3271 3272 return (NXGE_ERROR | rs); 3273 } 3274 3275 /* Perform write to Clause45 serdes / transceiver device */ 3276 3277 nxge_status_t 3278 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 3279 uint16_t xcvr_reg, uint16_t value) 3280 { 3281 npi_status_t rs = NPI_SUCCESS; 3282 3283 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 3284 xcvr_portn)); 3285 3286 MUTEX_ENTER(&nxge_mdio_lock); 3287 3288 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 3289 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 3290 goto fail; 3291 3292 MUTEX_EXIT(&nxge_mdio_lock); 3293 3294 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 3295 xcvr_portn)); 3296 return (NXGE_OK); 3297 fail: 3298 MUTEX_EXIT(&nxge_mdio_lock); 3299 3300 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3301 "nxge_mdio_write: Failed to write mdio on xcvr %d", 3302 xcvr_portn)); 3303 3304 return (NXGE_ERROR | rs); 3305 } 3306 3307 3308 /* Check MII to see if there is any link status change */ 3309 3310 nxge_status_t 3311 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 3312 nxge_link_state_t *link_up) 3313 { 3314 p_nxge_param_t param_arr; 3315 p_nxge_stats_t statsp; 3316 p_mii_regs_t mii_regs; 3317 p_mii_bmsr_t soft_bmsr; 3318 mii_anar_t anar; 3319 mii_anlpar_t anlpar; 3320 mii_anar_t an_common; 3321 mii_aner_t aner; 3322 mii_gsr_t gsr; 3323 nxge_status_t status = NXGE_OK; 3324 3325 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 3326 3327 mii_regs = NULL; 3328 param_arr = nxgep->param_arr; 3329 statsp = nxgep->statsp; 3330 soft_bmsr = &nxgep->soft_bmsr; 3331 *link_up = LINK_NO_CHANGE; 3332 3333 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3334 "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x", 3335 bmsr.value, bmsr_ints.value)); 3336 3337 if (bmsr_ints.bits.link_status) { 3338 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3339 "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x", 3340 bmsr.value, bmsr_ints.value)); 3341 if (bmsr.bits.link_status) { 3342 soft_bmsr->bits.link_status = 1; 3343 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3344 "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int " 3345 "0x%x", bmsr.value, bmsr_ints.value)); 3346 } else { 3347 statsp->mac_stats.link_up = 0; 3348 soft_bmsr->bits.link_status = 0; 3349 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3350 "Link down cable problem")); 3351 *link_up = LINK_IS_DOWN; 3352 } 3353 } 3354 3355 if (nxgep->mac.portmode == PORT_1G_COPPER && 3356 param_arr[param_autoneg].value) { 3357 if (bmsr_ints.bits.auto_neg_complete) { 3358 if (bmsr.bits.auto_neg_complete) 3359 soft_bmsr->bits.auto_neg_complete = 1; 3360 else 3361 soft_bmsr->bits.auto_neg_complete = 0; 3362 } 3363 if (soft_bmsr->bits.link_status == 0) { 3364 statsp->mac_stats.link_T4 = 0; 3365 statsp->mac_stats.link_speed = 0; 3366 statsp->mac_stats.link_duplex = 0; 3367 statsp->mac_stats.link_asmpause = 0; 3368 statsp->mac_stats.link_pause = 0; 3369 statsp->mac_stats.lp_cap_autoneg = 0; 3370 statsp->mac_stats.lp_cap_100T4 = 0; 3371 statsp->mac_stats.lp_cap_1000fdx = 0; 3372 statsp->mac_stats.lp_cap_1000hdx = 0; 3373 statsp->mac_stats.lp_cap_100fdx = 0; 3374 statsp->mac_stats.lp_cap_100hdx = 0; 3375 statsp->mac_stats.lp_cap_10fdx = 0; 3376 statsp->mac_stats.lp_cap_10hdx = 0; 3377 statsp->mac_stats.lp_cap_10gfdx = 0; 3378 statsp->mac_stats.lp_cap_10ghdx = 0; 3379 statsp->mac_stats.lp_cap_asmpause = 0; 3380 statsp->mac_stats.lp_cap_pause = 0; 3381 } 3382 } else 3383 soft_bmsr->bits.auto_neg_complete = 1; 3384 3385 if ((bmsr_ints.bits.link_status || 3386 bmsr_ints.bits.auto_neg_complete) && 3387 soft_bmsr->bits.link_status && 3388 soft_bmsr->bits.auto_neg_complete) { 3389 statsp->mac_stats.link_up = 1; 3390 3391 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3392 "==> nxge_mii_check " 3393 "(auto negotiation complete or link up) " 3394 "soft bmsr 0x%x bmsr_int 0x%x", 3395 bmsr.value, bmsr_ints.value)); 3396 3397 if (nxgep->mac.portmode == PORT_1G_COPPER && 3398 param_arr[param_autoneg].value) { 3399 if ((status = nxge_mii_read(nxgep, 3400 statsp->mac_stats.xcvr_portn, 3401 #if defined(__i386) 3402 (uint8_t)(uint32_t)(&mii_regs->anar), 3403 #else 3404 (uint8_t)(uint64_t)(&mii_regs->anar), 3405 #endif 3406 &anar.value)) != NXGE_OK) 3407 goto fail; 3408 if ((status = nxge_mii_read(nxgep, 3409 statsp->mac_stats.xcvr_portn, 3410 #if defined(__i386) 3411 (uint8_t)(uint32_t)(&mii_regs->anlpar), 3412 #else 3413 (uint8_t)(uint64_t)(&mii_regs->anlpar), 3414 #endif 3415 &anlpar.value)) != NXGE_OK) 3416 goto fail; 3417 if ((status = nxge_mii_read(nxgep, 3418 statsp->mac_stats.xcvr_portn, 3419 #if defined(__i386) 3420 (uint8_t)(uint32_t)(&mii_regs->aner), 3421 #else 3422 (uint8_t)(uint64_t)(&mii_regs->aner), 3423 #endif 3424 &aner.value)) != NXGE_OK) 3425 goto fail; 3426 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 3427 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 3428 statsp->mac_stats.lp_cap_100fdx = 3429 anlpar.bits.cap_100fdx; 3430 statsp->mac_stats.lp_cap_100hdx = 3431 anlpar.bits.cap_100hdx; 3432 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 3433 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 3434 statsp->mac_stats.lp_cap_asmpause = 3435 anlpar.bits.cap_asmpause; 3436 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 3437 an_common.value = anar.value & anlpar.value; 3438 if (param_arr[param_anar_1000fdx].value || 3439 param_arr[param_anar_1000hdx].value) { 3440 if ((status = nxge_mii_read(nxgep, 3441 statsp->mac_stats.xcvr_portn, 3442 #if defined(__i386) 3443 (uint8_t)(uint32_t)(&mii_regs->gsr), 3444 #else 3445 (uint8_t)(uint64_t)(&mii_regs->gsr), 3446 #endif 3447 &gsr.value)) 3448 != NXGE_OK) 3449 goto fail; 3450 statsp->mac_stats.lp_cap_1000fdx = 3451 gsr.bits.link_1000fdx; 3452 statsp->mac_stats.lp_cap_1000hdx = 3453 gsr.bits.link_1000hdx; 3454 if (param_arr[param_anar_1000fdx].value && 3455 gsr.bits.link_1000fdx) { 3456 statsp->mac_stats.link_speed = 1000; 3457 statsp->mac_stats.link_duplex = 2; 3458 } else if ( 3459 param_arr[param_anar_1000hdx].value && 3460 gsr.bits.link_1000hdx) { 3461 statsp->mac_stats.link_speed = 1000; 3462 statsp->mac_stats.link_duplex = 1; 3463 } 3464 } 3465 if ((an_common.value != 0) && 3466 !(statsp->mac_stats.link_speed)) { 3467 if (an_common.bits.cap_100T4) { 3468 statsp->mac_stats.link_T4 = 1; 3469 statsp->mac_stats.link_speed = 100; 3470 statsp->mac_stats.link_duplex = 1; 3471 } else if (an_common.bits.cap_100fdx) { 3472 statsp->mac_stats.link_speed = 100; 3473 statsp->mac_stats.link_duplex = 2; 3474 } else if (an_common.bits.cap_100hdx) { 3475 statsp->mac_stats.link_speed = 100; 3476 statsp->mac_stats.link_duplex = 1; 3477 } else if (an_common.bits.cap_10fdx) { 3478 statsp->mac_stats.link_speed = 10; 3479 statsp->mac_stats.link_duplex = 2; 3480 } else if (an_common.bits.cap_10hdx) { 3481 statsp->mac_stats.link_speed = 10; 3482 statsp->mac_stats.link_duplex = 1; 3483 } else { 3484 goto fail; 3485 } 3486 } 3487 if (statsp->mac_stats.link_duplex != 1) { 3488 statsp->mac_stats.link_asmpause = 3489 an_common.bits.cap_asmpause; 3490 if (statsp->mac_stats.link_asmpause) 3491 if ((statsp->mac_stats.cap_pause == 0) && 3492 (statsp->mac_stats.lp_cap_pause 3493 == 1)) 3494 statsp->mac_stats.link_pause 3495 = 0; 3496 else 3497 statsp->mac_stats.link_pause 3498 = 1; 3499 else 3500 statsp->mac_stats.link_pause = 3501 an_common.bits.cap_pause; 3502 } 3503 } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 3504 statsp->mac_stats.link_speed = 1000; 3505 statsp->mac_stats.link_duplex = 2; 3506 } 3507 *link_up = LINK_IS_UP; 3508 } 3509 3510 if (nxgep->link_notify) { 3511 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 3512 LINK_IS_DOWN); 3513 nxgep->link_notify = B_FALSE; 3514 } 3515 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 3516 return (NXGE_OK); 3517 fail: 3518 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3519 "nxge_mii_check: Unable to check MII")); 3520 return (status); 3521 } 3522 3523 /* Check PCS to see if there is any link status change */ 3524 nxge_status_t 3525 nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up) 3526 { 3527 p_nxge_stats_t statsp; 3528 nxge_status_t status = NXGE_OK; 3529 boolean_t linkup; 3530 3531 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check")); 3532 3533 statsp = nxgep->statsp; 3534 *link_up = LINK_NO_CHANGE; 3535 3536 (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup); 3537 if (linkup) { 3538 if (nxgep->link_notify || 3539 nxgep->statsp->mac_stats.link_up == 0) { 3540 statsp->mac_stats.link_up = 1; 3541 statsp->mac_stats.link_speed = 1000; 3542 statsp->mac_stats.link_duplex = 2; 3543 *link_up = LINK_IS_UP; 3544 nxgep->link_notify = B_FALSE; 3545 } 3546 } else { 3547 if (nxgep->link_notify || 3548 nxgep->statsp->mac_stats.link_up == 1) { 3549 statsp->mac_stats.link_up = 0; 3550 statsp->mac_stats.link_speed = 0; 3551 statsp->mac_stats.link_duplex = 0; 3552 *link_up = LINK_IS_DOWN; 3553 nxgep->link_notify = B_FALSE; 3554 } 3555 } 3556 3557 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check")); 3558 return (NXGE_OK); 3559 fail: 3560 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3561 "nxge_pcs_check: Unable to check PCS")); 3562 return (status); 3563 } 3564 3565 /* Add a multicast address entry into the HW hash table */ 3566 3567 nxge_status_t 3568 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 3569 { 3570 uint32_t mchash; 3571 p_hash_filter_t hash_filter; 3572 uint16_t hash_bit; 3573 boolean_t rx_init = B_FALSE; 3574 uint_t j; 3575 nxge_status_t status = NXGE_OK; 3576 3577 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 3578 3579 RW_ENTER_WRITER(&nxgep->filter_lock); 3580 mchash = crc32_mchash(addrp); 3581 if (nxgep->hash_filter == NULL) { 3582 NXGE_DEBUG_MSG((NULL, STR_CTL, 3583 "Allocating hash filter storage.")); 3584 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 3585 KM_SLEEP); 3586 } 3587 hash_filter = nxgep->hash_filter; 3588 j = mchash / HASH_REG_WIDTH; 3589 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 3590 hash_filter->hash_filter_regs[j] |= hash_bit; 3591 hash_filter->hash_bit_ref_cnt[mchash]++; 3592 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 3593 hash_filter->hash_ref_cnt++; 3594 rx_init = B_TRUE; 3595 } 3596 if (rx_init) { 3597 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 3598 goto fail; 3599 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 3600 goto fail; 3601 } 3602 3603 RW_EXIT(&nxgep->filter_lock); 3604 3605 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 3606 3607 return (NXGE_OK); 3608 fail: 3609 RW_EXIT(&nxgep->filter_lock); 3610 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 3611 "Unable to add multicast address")); 3612 return (status); 3613 } 3614 3615 /* Remove a multicast address entry from the HW hash table */ 3616 3617 nxge_status_t 3618 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 3619 { 3620 uint32_t mchash; 3621 p_hash_filter_t hash_filter; 3622 uint16_t hash_bit; 3623 boolean_t rx_init = B_FALSE; 3624 uint_t j; 3625 nxge_status_t status = NXGE_OK; 3626 3627 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 3628 RW_ENTER_WRITER(&nxgep->filter_lock); 3629 mchash = crc32_mchash(addrp); 3630 if (nxgep->hash_filter == NULL) { 3631 NXGE_DEBUG_MSG((NULL, STR_CTL, 3632 "Hash filter already de_allocated.")); 3633 RW_EXIT(&nxgep->filter_lock); 3634 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 3635 return (NXGE_OK); 3636 } 3637 hash_filter = nxgep->hash_filter; 3638 hash_filter->hash_bit_ref_cnt[mchash]--; 3639 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 3640 j = mchash / HASH_REG_WIDTH; 3641 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 3642 hash_filter->hash_filter_regs[j] &= ~hash_bit; 3643 hash_filter->hash_ref_cnt--; 3644 rx_init = B_TRUE; 3645 } 3646 if (hash_filter->hash_ref_cnt == 0) { 3647 NXGE_DEBUG_MSG((NULL, STR_CTL, 3648 "De-allocating hash filter storage.")); 3649 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 3650 nxgep->hash_filter = NULL; 3651 } 3652 3653 if (rx_init) { 3654 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 3655 goto fail; 3656 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 3657 goto fail; 3658 } 3659 RW_EXIT(&nxgep->filter_lock); 3660 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 3661 3662 return (NXGE_OK); 3663 fail: 3664 RW_EXIT(&nxgep->filter_lock); 3665 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 3666 "Unable to remove multicast address")); 3667 3668 return (status); 3669 } 3670 3671 /* Set MAC address into MAC address HW registers */ 3672 3673 nxge_status_t 3674 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 3675 { 3676 nxge_status_t status = NXGE_OK; 3677 3678 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 3679 3680 MUTEX_ENTER(&nxgep->ouraddr_lock); 3681 /* 3682 * Exit if the address is same as ouraddr or multicast or broadcast 3683 */ 3684 if (((addrp->ether_addr_octet[0] & 01) == 1) || 3685 (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 3686 (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 3687 goto nxge_set_mac_addr_exit; 3688 } 3689 nxgep->ouraddr = *addrp; 3690 /* 3691 * Set new interface local address and re-init device. 3692 * This is destructive to any other streams attached 3693 * to this device. 3694 */ 3695 RW_ENTER_WRITER(&nxgep->filter_lock); 3696 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 3697 goto fail; 3698 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 3699 goto fail; 3700 3701 RW_EXIT(&nxgep->filter_lock); 3702 MUTEX_EXIT(&nxgep->ouraddr_lock); 3703 goto nxge_set_mac_addr_end; 3704 nxge_set_mac_addr_exit: 3705 MUTEX_EXIT(&nxgep->ouraddr_lock); 3706 nxge_set_mac_addr_end: 3707 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 3708 3709 return (NXGE_OK); 3710 fail: 3711 MUTEX_EXIT(&nxgep->ouraddr_lock); 3712 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 3713 "Unable to set mac address")); 3714 return (status); 3715 } 3716 3717 static 3718 check_link_state_t 3719 nxge_check_link_stop( 3720 nxge_t *nxge) 3721 { 3722 /* If the poll has been cancelled, return STOP. */ 3723 MUTEX_ENTER(&nxge->poll_lock); 3724 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 3725 nxge->poll_state = LINK_MONITOR_STOP; 3726 nxge->nxge_link_poll_timerid = 0; 3727 cv_broadcast(&nxge->poll_cv); 3728 MUTEX_EXIT(&nxge->poll_lock); 3729 3730 NXGE_DEBUG_MSG((nxge, MAC_CTL, 3731 "nxge_check_%s_link(port<%d>) stopped.", 3732 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 3733 nxge->mac.portnum)); 3734 return (CHECK_LINK_STOP); 3735 } 3736 MUTEX_EXIT(&nxge->poll_lock); 3737 3738 return (CHECK_LINK_RESCHEDULE); 3739 } 3740 3741 /* Check status of MII (MIF or PCS) link */ 3742 3743 static nxge_status_t 3744 nxge_check_mii_link(p_nxge_t nxgep) 3745 { 3746 mii_bmsr_t bmsr_ints, bmsr_data; 3747 mii_anlpar_t anlpar; 3748 mii_gsr_t gsr; 3749 p_mii_regs_t mii_regs; 3750 nxge_status_t status = NXGE_OK; 3751 uint8_t portn; 3752 nxge_link_state_t link_up; 3753 3754 if (nxgep->nxge_magic != NXGE_MAGIC) 3755 return (NXGE_ERROR); 3756 3757 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 3758 return (NXGE_OK); 3759 3760 portn = nxgep->mac.portnum; 3761 3762 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 3763 portn)); 3764 3765 mii_regs = NULL; 3766 3767 RW_ENTER_WRITER(&nxgep->filter_lock); 3768 3769 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 3770 goto nxge_check_mii_link_exit; 3771 3772 switch (nxgep->mac.portmode) { 3773 default: 3774 bmsr_data.value = 0; 3775 if ((status = nxge_mii_read(nxgep, 3776 nxgep->statsp->mac_stats.xcvr_portn, 3777 #if defined(__i386) 3778 (uint8_t)(uint32_t)(&mii_regs->bmsr), 3779 #else 3780 (uint8_t)(uint64_t)(&mii_regs->bmsr), 3781 #endif 3782 &bmsr_data.value)) != NXGE_OK) { 3783 goto fail; 3784 } 3785 3786 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3787 "==> nxge_check_mii_link port<0x%x> " 3788 "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ", 3789 xcvr_portn, bmsr_data.value, nxgep->bmsr.value)); 3790 3791 if (nxgep->param_arr[param_autoneg].value) { 3792 if ((status = nxge_mii_read(nxgep, 3793 nxgep->statsp->mac_stats.xcvr_portn, 3794 #if defined(__i386) 3795 (uint8_t)(uint32_t)(&mii_regs->gsr), 3796 #else 3797 (uint8_t)(uint64_t)(&mii_regs->gsr), 3798 #endif 3799 &gsr.value)) != NXGE_OK) 3800 goto fail; 3801 if ((status = nxge_mii_read(nxgep, 3802 nxgep->statsp->mac_stats.xcvr_portn, 3803 #if defined(__i386) 3804 (uint8_t)(uint32_t)(&mii_regs->anlpar), 3805 #else 3806 (uint8_t)(uint64_t)(&mii_regs->anlpar), 3807 #endif 3808 &anlpar.value)) != NXGE_OK) 3809 goto fail; 3810 if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) { 3811 3812 if (nxgep->statsp->mac_stats.link_up && 3813 ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 3814 gsr.bits.link_1000fdx) || 3815 (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 3816 gsr.bits.link_1000hdx) || 3817 (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 3818 anlpar.bits.cap_100T4) || 3819 (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 3820 anlpar.bits.cap_100fdx) || 3821 (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 3822 anlpar.bits.cap_100hdx) || 3823 (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 3824 anlpar.bits.cap_10fdx) || 3825 (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 3826 anlpar.bits.cap_10hdx))) { 3827 bmsr_data.bits.link_status = 0; 3828 } 3829 } 3830 } 3831 3832 /* Workaround for link down issue */ 3833 if (bmsr_data.value == 0) { 3834 cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 3835 goto nxge_check_mii_link_exit; 3836 } 3837 3838 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3839 "==> nxge_check_mii_link port<0x%x> :" 3840 "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x", 3841 xcvr_portn, nxgep->bmsr.value, bmsr_data.value)); 3842 3843 bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 3844 nxgep->bmsr.value = bmsr_data.value; 3845 3846 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3847 "==> nxge_check_mii_link port<0x%x> CALLING " 3848 "bmsr_data 0x%x bmsr_ints.value 0x%x", 3849 xcvr_portn, bmsr_data.value, bmsr_ints.value)); 3850 3851 if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, 3852 &link_up)) != NXGE_OK) { 3853 goto fail; 3854 } 3855 break; 3856 3857 case PORT_1G_SERDES: 3858 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3859 "==> nxge_check_mii_link port<%d> (SERDES)", portn)); 3860 if ((status = nxge_pcs_check(nxgep, portn, &link_up)) 3861 != NXGE_OK) { 3862 goto fail; 3863 } 3864 break; 3865 } 3866 3867 nxge_check_mii_link_exit: 3868 RW_EXIT(&nxgep->filter_lock); 3869 if (link_up == LINK_IS_UP) { 3870 nxge_link_is_up(nxgep); 3871 } else if (link_up == LINK_IS_DOWN) { 3872 nxge_link_is_down(nxgep); 3873 } 3874 3875 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 3876 3877 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 3878 portn)); 3879 return (NXGE_OK); 3880 3881 fail: 3882 RW_EXIT(&nxgep->filter_lock); 3883 3884 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 3885 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3886 "nxge_check_mii_link: Failed to check link port<%d>", 3887 portn)); 3888 return (status); 3889 } 3890 3891 3892 /*ARGSUSED*/ 3893 static nxge_status_t 3894 nxge_check_10g_link(p_nxge_t nxgep) 3895 { 3896 uint8_t portn; 3897 nxge_status_t status = NXGE_OK; 3898 boolean_t link_up, xpcs_up, xmac_up; 3899 uint32_t val; 3900 npi_status_t rs; 3901 3902 if (nxgep->nxge_magic != NXGE_MAGIC) 3903 return (NXGE_ERROR); 3904 3905 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 3906 return (NXGE_OK); 3907 3908 portn = nxgep->mac.portnum; 3909 val = 0; 3910 rs = NPI_SUCCESS; 3911 3912 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 3913 portn)); 3914 3915 switch (nxgep->mac.portmode) { 3916 default: 3917 status = nxge_check_bcm8704_link(nxgep, &link_up); 3918 if (status != NXGE_OK) 3919 goto fail; 3920 break; 3921 case PORT_10G_SERDES: 3922 rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3923 XPCS_REG_STATUS1, &val); 3924 if (rs != 0) 3925 goto fail; 3926 3927 link_up = B_FALSE; 3928 xmac_up = B_FALSE; 3929 xpcs_up = B_FALSE; 3930 if (val & XPCS_STATUS1_RX_LINK_STATUS_UP) { 3931 xpcs_up = B_TRUE; 3932 } 3933 3934 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3935 "==> nxge_check_10g_link port<%d> " 3936 "XPCS_REG_STATUS1 0x%x xpcs_up %d", 3937 portn, val, xpcs_up)); 3938 /* 3939 * Read the xMAC internal signal 2 register. 3940 * This register should be the superset of the XPCS when wanting 3941 * to get the link status. If this register read is proved to be 3942 * reliable, there is no need to read the XPCS register. 3943 */ 3944 xmac_up = B_TRUE; 3945 XMAC_REG_RD(nxgep->npi_handle, portn, XMAC_INTERN2_REG, &val); 3946 if (val & XMAC_IS2_LOCAL_FLT_OC_SYNC) { /* link is down */ 3947 xmac_up = B_FALSE; 3948 } 3949 3950 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3951 "==> nxge_check_10g_link port<%d> " 3952 "XMAC_INTERN2_REG 0x%x xmac_up %d", 3953 portn, val, xmac_up)); 3954 3955 if (xpcs_up && xmac_up) { 3956 link_up = B_TRUE; 3957 } 3958 break; 3959 } 3960 3961 if (link_up) { 3962 if (nxgep->link_notify || 3963 nxgep->statsp->mac_stats.link_up == 0) { 3964 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 3965 goto fail; 3966 nxgep->statsp->mac_stats.link_up = 1; 3967 nxgep->statsp->mac_stats.link_speed = 10000; 3968 nxgep->statsp->mac_stats.link_duplex = 2; 3969 3970 nxge_link_is_up(nxgep); 3971 nxgep->link_notify = B_FALSE; 3972 } 3973 } else { 3974 if (nxgep->link_notify || 3975 nxgep->statsp->mac_stats.link_up == 1) { 3976 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 3977 goto fail; 3978 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3979 "Link down cable problem")); 3980 nxgep->statsp->mac_stats.link_up = 0; 3981 nxgep->statsp->mac_stats.link_speed = 0; 3982 nxgep->statsp->mac_stats.link_duplex = 0; 3983 3984 nxge_link_is_down(nxgep); 3985 nxgep->link_notify = B_FALSE; 3986 } 3987 } 3988 3989 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 3990 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 3991 portn)); 3992 return (NXGE_OK); 3993 3994 fail: 3995 (void) nxge_check_link_stop(nxgep); 3996 3997 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3998 "nxge_check_10g_link: Failed to check link port<%d>", 3999 portn)); 4000 return (status); 4001 } 4002 4003 4004 /* Declare link down */ 4005 4006 void 4007 nxge_link_is_down(p_nxge_t nxgep) 4008 { 4009 p_nxge_stats_t statsp; 4010 char link_stat_msg[64]; 4011 4012 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 4013 4014 statsp = nxgep->statsp; 4015 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 4016 statsp->mac_stats.xcvr_portn); 4017 4018 if (nxge_no_msg == B_FALSE) { 4019 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 4020 } 4021 4022 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 4023 4024 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 4025 } 4026 4027 /* Declare link up */ 4028 4029 void 4030 nxge_link_is_up(p_nxge_t nxgep) 4031 { 4032 p_nxge_stats_t statsp; 4033 char link_stat_msg[64]; 4034 uint32_t val; 4035 4036 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 4037 4038 statsp = nxgep->statsp; 4039 (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 4040 statsp->mac_stats.xcvr_portn, 4041 statsp->mac_stats.link_speed); 4042 4043 if (statsp->mac_stats.link_T4) 4044 (void) strcat(link_stat_msg, "T4"); 4045 else if (statsp->mac_stats.link_duplex == 2) 4046 (void) strcat(link_stat_msg, "full duplex"); 4047 else 4048 (void) strcat(link_stat_msg, "half duplex"); 4049 4050 (void) nxge_xif_init(nxgep); 4051 4052 /* Clean up symbol errors incurred during link transition */ 4053 if ((nxgep->mac.portmode == PORT_10G_FIBER) || 4054 (nxgep->mac.portmode == PORT_10G_SERDES)) { 4055 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4056 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 4057 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4058 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 4059 } 4060 4061 if (nxge_no_msg == B_FALSE) { 4062 NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 4063 } 4064 4065 mac_link_update(nxgep->mach, LINK_STATE_UP); 4066 4067 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 4068 } 4069 4070 /* 4071 * Calculate the bit in the multicast address filter 4072 * that selects the given * address. 4073 * Note: For GEM, the last 8-bits are used. 4074 */ 4075 uint32_t 4076 crc32_mchash(p_ether_addr_t addr) 4077 { 4078 uint8_t *cp; 4079 uint32_t crc; 4080 uint32_t c; 4081 int byte; 4082 int bit; 4083 4084 cp = (uint8_t *)addr; 4085 crc = (uint32_t)0xffffffff; 4086 for (byte = 0; byte < 6; byte++) { 4087 c = (uint32_t)cp[byte]; 4088 for (bit = 0; bit < 8; bit++) { 4089 if ((c & 0x1) ^ (crc & 0x1)) 4090 crc = (crc >> 1)^0xedb88320; 4091 else 4092 crc = (crc >> 1); 4093 c >>= 1; 4094 } 4095 } 4096 return ((~crc) >> (32 - HASH_BITS)); 4097 } 4098 4099 /* Reset serdes */ 4100 4101 nxge_status_t 4102 nxge_serdes_reset(p_nxge_t nxgep) 4103 { 4104 npi_handle_t handle; 4105 4106 handle = nxgep->npi_handle; 4107 4108 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 4109 drv_usecwait(500); 4110 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 4111 4112 return (NXGE_OK); 4113 } 4114 4115 /* Monitor link status using interrupt or polling */ 4116 4117 nxge_status_t 4118 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 4119 { 4120 nxge_status_t status = NXGE_OK; 4121 4122 /* 4123 * Return immediately if this is an imaginary XMAC port. 4124 * (At least, we don't have 4-port XMAC cards yet.) 4125 */ 4126 if ((nxgep->mac.portmode == PORT_10G_FIBER || 4127 nxgep->mac.portmode == PORT_10G_SERDES) && 4128 (nxgep->mac.portnum > 1)) 4129 return (NXGE_OK); 4130 4131 if (nxgep->statsp == NULL) { 4132 /* stats has not been allocated. */ 4133 return (NXGE_OK); 4134 } 4135 /* Don't check link if we're not in internal loopback mode */ 4136 if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal) 4137 return (NXGE_OK); 4138 4139 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4140 "==> nxge_link_monitor port<%d> enable=%d", 4141 nxgep->mac.portnum, enable)); 4142 if (enable == LINK_MONITOR_START) { 4143 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 4144 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 4145 != NXGE_OK) 4146 goto fail; 4147 } else { 4148 timeout_id_t timerid; 4149 4150 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 4151 return (NXGE_OK); 4152 4153 if (nxgep->xcvr.check_link) { 4154 timerid = timeout( 4155 (fptrv_t)(nxgep->xcvr.check_link), 4156 nxgep, 4157 drv_usectohz(LINK_MONITOR_PERIOD)); 4158 MUTEX_ENTER(&nxgep->poll_lock); 4159 nxgep->nxge_link_poll_timerid = timerid; 4160 MUTEX_EXIT(&nxgep->poll_lock); 4161 } else { 4162 return (NXGE_ERROR); 4163 } 4164 } 4165 } else { 4166 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 4167 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 4168 != NXGE_OK) 4169 goto fail; 4170 } else { 4171 clock_t rv; 4172 4173 MUTEX_ENTER(&nxgep->poll_lock); 4174 4175 /* If <timerid> == 0, the link monitor has */ 4176 /* never been started, or just now stopped. */ 4177 if (nxgep->nxge_link_poll_timerid == 0) { 4178 MUTEX_EXIT(&nxgep->poll_lock); 4179 return (NXGE_OK); 4180 } 4181 4182 nxgep->poll_state = LINK_MONITOR_STOPPING; 4183 rv = cv_timedwait(&nxgep->poll_cv, 4184 &nxgep->poll_lock, 4185 ddi_get_lbolt() + 4186 drv_usectohz(LM_WAIT_MULTIPLIER * 4187 LINK_MONITOR_PERIOD)); 4188 if (rv == -1) { 4189 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4190 "==> stopping port %d: " 4191 "cv_timedwait(%d) timed out", 4192 nxgep->mac.portnum, nxgep->poll_state)); 4193 nxgep->poll_state = LINK_MONITOR_STOP; 4194 nxgep->nxge_link_poll_timerid = 0; 4195 } 4196 4197 MUTEX_EXIT(&nxgep->poll_lock); 4198 } 4199 } 4200 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4201 "<== nxge_link_monitor port<%d> enable=%d", 4202 nxgep->mac.portnum, enable)); 4203 return (NXGE_OK); 4204 fail: 4205 return (status); 4206 } 4207 4208 /* Set promiscous mode */ 4209 4210 nxge_status_t 4211 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 4212 { 4213 nxge_status_t status = NXGE_OK; 4214 4215 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 4216 4217 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 4218 4219 RW_ENTER_WRITER(&nxgep->filter_lock); 4220 4221 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 4222 goto fail; 4223 } 4224 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 4225 goto fail; 4226 } 4227 4228 RW_EXIT(&nxgep->filter_lock); 4229 4230 if (on) 4231 nxgep->statsp->mac_stats.promisc = B_TRUE; 4232 else 4233 nxgep->statsp->mac_stats.promisc = B_FALSE; 4234 4235 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 4236 4237 return (NXGE_OK); 4238 fail: 4239 RW_EXIT(&nxgep->filter_lock); 4240 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 4241 "Unable to set promisc (%d)", on)); 4242 4243 return (status); 4244 } 4245 4246 /*ARGSUSED*/ 4247 uint_t 4248 nxge_mif_intr(void *arg1, void *arg2) 4249 { 4250 #ifdef NXGE_DEBUG 4251 p_nxge_t nxgep = (p_nxge_t)arg2; 4252 #endif 4253 #if NXGE_MIF 4254 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 4255 uint32_t status; 4256 npi_handle_t handle; 4257 uint8_t portn; 4258 p_nxge_stats_t statsp; 4259 #endif 4260 4261 #ifdef NXGE_MIF 4262 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 4263 nxgep = ldvp->nxgep; 4264 } 4265 nxgep = ldvp->nxgep; 4266 #endif 4267 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 4268 4269 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 4270 return (DDI_INTR_CLAIMED); 4271 4272 mif_intr_fail: 4273 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 4274 return (DDI_INTR_UNCLAIMED); 4275 } 4276 4277 /*ARGSUSED*/ 4278 uint_t 4279 nxge_mac_intr(void *arg1, void *arg2) 4280 { 4281 p_nxge_t nxgep = (p_nxge_t)arg2; 4282 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 4283 p_nxge_ldg_t ldgp; 4284 uint32_t status; 4285 npi_handle_t handle; 4286 uint8_t portn; 4287 p_nxge_stats_t statsp; 4288 npi_status_t rs = NPI_SUCCESS; 4289 4290 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 4291 nxgep = ldvp->nxgep; 4292 } 4293 4294 ldgp = ldvp->ldgp; 4295 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 4296 "group %d", ldgp->ldg)); 4297 4298 handle = NXGE_DEV_NPI_HANDLE(nxgep); 4299 /* 4300 * This interrupt handler is for a specific 4301 * mac port. 4302 */ 4303 statsp = (p_nxge_stats_t)nxgep->statsp; 4304 portn = nxgep->mac.portnum; 4305 4306 NXGE_DEBUG_MSG((nxgep, INT_CTL, 4307 "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 4308 4309 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 4310 rs = npi_xmac_tx_get_istatus(handle, portn, 4311 (xmac_tx_iconfig_t *)&status); 4312 if (rs != NPI_SUCCESS) 4313 goto npi_fail; 4314 if (status & ICFG_XMAC_TX_ALL) { 4315 if (status & ICFG_XMAC_TX_UNDERRUN) { 4316 statsp->xmac_stats.tx_underflow_err++; 4317 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4318 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 4319 } 4320 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 4321 statsp->xmac_stats.tx_maxpktsize_err++; 4322 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4323 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 4324 } 4325 if (status & ICFG_XMAC_TX_OVERFLOW) { 4326 statsp->xmac_stats.tx_overflow_err++; 4327 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4328 NXGE_FM_EREPORT_TXMAC_OVERFLOW); 4329 } 4330 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 4331 statsp->xmac_stats.tx_fifo_xfr_err++; 4332 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4333 NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 4334 } 4335 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 4336 statsp->xmac_stats.tx_byte_cnt += 4337 XTXMAC_BYTE_CNT_MASK; 4338 } 4339 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 4340 statsp->xmac_stats.tx_frame_cnt += 4341 XTXMAC_FRM_CNT_MASK; 4342 } 4343 } 4344 4345 rs = npi_xmac_rx_get_istatus(handle, portn, 4346 (xmac_rx_iconfig_t *)&status); 4347 if (rs != NPI_SUCCESS) 4348 goto npi_fail; 4349 if (status & ICFG_XMAC_RX_ALL) { 4350 if (status & ICFG_XMAC_RX_OVERFLOW) 4351 statsp->xmac_stats.rx_overflow_err++; 4352 if (status & ICFG_XMAC_RX_UNDERFLOW) { 4353 statsp->xmac_stats.rx_underflow_err++; 4354 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4355 NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 4356 } 4357 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 4358 statsp->xmac_stats.rx_crc_err_cnt += 4359 XRXMAC_CRC_ER_CNT_MASK; 4360 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4361 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 4362 } 4363 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 4364 statsp->xmac_stats.rx_len_err_cnt += 4365 MAC_LEN_ER_CNT_MASK; 4366 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4367 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 4368 } 4369 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 4370 statsp->xmac_stats.rx_viol_err_cnt += 4371 XRXMAC_CD_VIO_CNT_MASK; 4372 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4373 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 4374 } 4375 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 4376 statsp->xmac_stats.rx_byte_cnt += 4377 XRXMAC_BT_CNT_MASK; 4378 } 4379 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 4380 statsp->xmac_stats.rx_hist1_cnt += 4381 XRXMAC_HIST_CNT1_MASK; 4382 } 4383 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 4384 statsp->xmac_stats.rx_hist2_cnt += 4385 XRXMAC_HIST_CNT2_MASK; 4386 } 4387 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 4388 statsp->xmac_stats.rx_hist3_cnt += 4389 XRXMAC_HIST_CNT3_MASK; 4390 } 4391 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 4392 statsp->xmac_stats.rx_hist4_cnt += 4393 XRXMAC_HIST_CNT4_MASK; 4394 } 4395 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 4396 statsp->xmac_stats.rx_hist5_cnt += 4397 XRXMAC_HIST_CNT5_MASK; 4398 } 4399 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 4400 statsp->xmac_stats.rx_hist6_cnt += 4401 XRXMAC_HIST_CNT6_MASK; 4402 } 4403 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 4404 statsp->xmac_stats.rx_broadcast_cnt += 4405 XRXMAC_BC_FRM_CNT_MASK; 4406 } 4407 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 4408 statsp->xmac_stats.rx_mult_cnt += 4409 XRXMAC_MC_FRM_CNT_MASK; 4410 } 4411 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 4412 statsp->xmac_stats.rx_frag_cnt += 4413 XRXMAC_FRAG_CNT_MASK; 4414 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4415 NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP); 4416 } 4417 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 4418 statsp->xmac_stats.rx_frame_align_err_cnt += 4419 XRXMAC_AL_ER_CNT_MASK; 4420 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4421 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 4422 } 4423 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 4424 statsp->xmac_stats.rx_linkfault_err_cnt += 4425 XMAC_LINK_FLT_CNT_MASK; 4426 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4427 NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP); 4428 } 4429 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 4430 statsp->xmac_stats.rx_remotefault_err++; 4431 } 4432 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 4433 statsp->xmac_stats.rx_localfault_err++; 4434 } 4435 } 4436 4437 rs = npi_xmac_ctl_get_istatus(handle, portn, 4438 (xmac_ctl_iconfig_t *)&status); 4439 if (rs != NPI_SUCCESS) 4440 goto npi_fail; 4441 if (status & ICFG_XMAC_CTRL_ALL) { 4442 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 4443 statsp->xmac_stats.rx_pause_cnt++; 4444 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 4445 statsp->xmac_stats.tx_pause_state++; 4446 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 4447 statsp->xmac_stats.tx_nopause_state++; 4448 } 4449 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 4450 rs = npi_bmac_tx_get_istatus(handle, portn, 4451 (bmac_tx_iconfig_t *)&status); 4452 if (rs != NPI_SUCCESS) 4453 goto npi_fail; 4454 if (status & ICFG_BMAC_TX_ALL) { 4455 if (status & ICFG_BMAC_TX_UNDERFLOW) { 4456 statsp->bmac_stats.tx_underrun_err++; 4457 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4458 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 4459 } 4460 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 4461 statsp->bmac_stats.tx_max_pkt_err++; 4462 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4463 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 4464 } 4465 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 4466 statsp->bmac_stats.tx_byte_cnt += 4467 BTXMAC_BYTE_CNT_MASK; 4468 } 4469 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 4470 statsp->bmac_stats.tx_frame_cnt += 4471 BTXMAC_FRM_CNT_MASK; 4472 } 4473 } 4474 4475 rs = npi_bmac_rx_get_istatus(handle, portn, 4476 (bmac_rx_iconfig_t *)&status); 4477 if (rs != NPI_SUCCESS) 4478 goto npi_fail; 4479 if (status & ICFG_BMAC_RX_ALL) { 4480 if (status & ICFG_BMAC_RX_OVERFLOW) { 4481 statsp->bmac_stats.rx_overflow_err++; 4482 } 4483 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 4484 statsp->bmac_stats.rx_frame_cnt += 4485 RXMAC_FRM_CNT_MASK; 4486 } 4487 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 4488 statsp->bmac_stats.rx_crc_err_cnt += 4489 BMAC_CRC_ER_CNT_MASK; 4490 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4491 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 4492 } 4493 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 4494 statsp->bmac_stats.rx_len_err_cnt += 4495 MAC_LEN_ER_CNT_MASK; 4496 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4497 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 4498 } 4499 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 4500 statsp->bmac_stats.rx_viol_err_cnt += 4501 BMAC_CD_VIO_CNT_MASK; 4502 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4503 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 4504 } 4505 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 4506 statsp->bmac_stats.rx_byte_cnt += 4507 BRXMAC_BYTE_CNT_MASK; 4508 } 4509 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 4510 statsp->bmac_stats.rx_align_err_cnt += 4511 BMAC_AL_ER_CNT_MASK; 4512 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 4513 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 4514 } 4515 4516 rs = npi_bmac_ctl_get_istatus(handle, portn, 4517 (bmac_ctl_iconfig_t *)&status); 4518 if (rs != NPI_SUCCESS) 4519 goto npi_fail; 4520 4521 if (status & ICFG_BMAC_CTL_ALL) { 4522 if (status & ICFG_BMAC_CTL_RCVPAUSE) 4523 statsp->bmac_stats.rx_pause_cnt++; 4524 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 4525 statsp->bmac_stats.tx_pause_state++; 4526 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 4527 statsp->bmac_stats.tx_nopause_state++; 4528 } 4529 } 4530 4531 if (ldgp->nldvs == 1) { 4532 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 4533 B_TRUE, ldgp->ldg_timer); 4534 } 4535 4536 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 4537 return (DDI_INTR_CLAIMED); 4538 4539 npi_fail: 4540 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 4541 return (DDI_INTR_UNCLAIMED); 4542 } 4543 4544 nxge_status_t 4545 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 4546 { 4547 uint8_t phy_port_addr; 4548 nxge_status_t status = NXGE_OK; 4549 boolean_t rx_sig_ok; 4550 boolean_t pcs_blk_lock; 4551 boolean_t link_align; 4552 uint16_t val1, val2, val3; 4553 #ifdef NXGE_DEBUG_SYMBOL_ERR 4554 uint16_t val_debug; 4555 uint16_t val; 4556 #endif 4557 4558 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 4559 4560 #ifdef NXGE_DEBUG_SYMBOL_ERR 4561 /* Check Device 3 Register Device 3 0xC809 */ 4562 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 4563 if ((val_debug & ~0x200) != 0) { 4564 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 4565 nxgep->mac.portnum, val_debug); 4566 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 4567 &val_debug); 4568 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 4569 nxgep->mac.portnum, val_debug); 4570 } 4571 4572 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4573 XPCS_REG_DESCWERR_COUNTER, &val); 4574 if (val != 0) 4575 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 4576 4577 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4578 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 4579 if (val != 0) 4580 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 4581 4582 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 4583 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 4584 if (val != 0) 4585 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 4586 #endif 4587 4588 /* Check from BCM8704 if 10G link is up or down */ 4589 4590 /* Check Device 1 Register 0xA bit0 */ 4591 status = nxge_mdio_read(nxgep, phy_port_addr, 4592 BCM8704_PMA_PMD_DEV_ADDR, 4593 BCM8704_PMD_RECEIVE_SIG_DETECT, 4594 &val1); 4595 if (status != NXGE_OK) 4596 goto fail; 4597 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 4598 4599 /* Check Device 3 Register 0x20 bit0 */ 4600 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 4601 BCM8704_PCS_DEV_ADDR, 4602 BCM8704_10GBASE_R_PCS_STATUS_REG, 4603 &val2)) != NPI_SUCCESS) 4604 goto fail; 4605 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 4606 4607 /* Check Device 4 Register 0x18 bit12 */ 4608 status = nxge_mdio_read(nxgep, phy_port_addr, 4609 BCM8704_PHYXS_ADDR, 4610 BCM8704_PHYXS_XGXS_LANE_STATUS_REG, 4611 &val3); 4612 if (status != NXGE_OK) 4613 goto fail; 4614 link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 4615 XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 4616 XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 4617 4618 #ifdef NXGE_DEBUG_ALIGN_ERR 4619 /* Temp workaround for link down issue */ 4620 if (pcs_blk_lock == B_FALSE) { 4621 if (val2 != 0x4) { 4622 pcs_blk_lock = B_TRUE; 4623 cmn_err(CE_NOTE, 4624 "!LINK DEBUG: port%d PHY Dev3 " 4625 "Reg 0x20 = 0x%x\n", 4626 nxgep->mac.portnum, val2); 4627 } 4628 } 4629 4630 if (link_align == B_FALSE) { 4631 if (val3 != 0x140f) { 4632 link_align = B_TRUE; 4633 cmn_err(CE_NOTE, 4634 "!LINK DEBUG: port%d PHY Dev4 " 4635 "Reg 0x18 = 0x%x\n", 4636 nxgep->mac.portnum, val3); 4637 } 4638 } 4639 4640 if (rx_sig_ok == B_FALSE) { 4641 if ((val2 == 0) || (val3 == 0)) { 4642 rx_sig_ok = B_TRUE; 4643 cmn_err(CE_NOTE, 4644 "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 4645 nxgep->mac.portnum); 4646 } 4647 } 4648 #endif 4649 4650 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 4651 (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 4652 4653 return (NXGE_OK); 4654 fail: 4655 return (status); 4656 } 4657 4658 nxge_status_t 4659 nxge_10g_link_led_on(p_nxge_t nxgep) 4660 { 4661 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 4662 != NPI_SUCCESS) 4663 return (NXGE_ERROR); 4664 else 4665 return (NXGE_OK); 4666 } 4667 4668 nxge_status_t 4669 nxge_10g_link_led_off(p_nxge_t nxgep) 4670 { 4671 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 4672 != NPI_SUCCESS) 4673 return (NXGE_ERROR); 4674 else 4675 return (NXGE_OK); 4676 } 4677 4678 /* Check if the given id read using the given MDIO Clause is supported */ 4679 4680 static boolean_t 4681 nxge_is_supported_phy(uint32_t id, uint8_t type) 4682 { 4683 int i; 4684 int cl45_arr_len = NUM_CLAUSE_45_IDS; 4685 int cl22_arr_len = NUM_CLAUSE_22_IDS; 4686 boolean_t found = B_FALSE; 4687 4688 switch (type) { 4689 case CLAUSE_45_TYPE: 4690 for (i = 0; i < cl45_arr_len; i++) { 4691 if ((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) == 4692 (id & BCM_PHY_ID_MASK)) { 4693 found = B_TRUE; 4694 break; 4695 } 4696 } 4697 break; 4698 case CLAUSE_22_TYPE: 4699 for (i = 0; i < cl22_arr_len; i++) { 4700 if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) == 4701 (id & BCM_PHY_ID_MASK)) { 4702 found = B_TRUE; 4703 break; 4704 } 4705 } 4706 break; 4707 default: 4708 break; 4709 } 4710 4711 return (found); 4712 } 4713 4714 static uint32_t 4715 nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port) 4716 { 4717 uint16_t val1 = 0; 4718 uint16_t val2 = 0; 4719 uint32_t pma_pmd_dev_id = 0; 4720 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 4721 4722 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 4723 NXGE_DEV_ID_REG_1, &val1); 4724 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 4725 NXGE_DEV_ID_REG_2, &val2); 4726 4727 pma_pmd_dev_id = val1; 4728 pma_pmd_dev_id = (pma_pmd_dev_id << 16); 4729 pma_pmd_dev_id |= val2; 4730 4731 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 4732 "devid[0x%llx]", phy_port, pma_pmd_dev_id)); 4733 4734 return (pma_pmd_dev_id); 4735 } 4736 4737 static uint32_t 4738 nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port) 4739 { 4740 uint16_t val1 = 0; 4741 uint16_t val2 = 0; 4742 uint32_t pcs_dev_id = 0; 4743 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 4744 4745 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 4746 NXGE_DEV_ID_REG_1, &val1); 4747 (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 4748 NXGE_DEV_ID_REG_2, &val2); 4749 4750 pcs_dev_id = val1; 4751 pcs_dev_id = (pcs_dev_id << 16); 4752 pcs_dev_id |= val2; 4753 4754 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 4755 "devid[0x%llx]", phy_port, pcs_dev_id)); 4756 4757 return (pcs_dev_id); 4758 } 4759 4760 static uint32_t 4761 nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port) 4762 { 4763 uint16_t val1 = 0; 4764 uint16_t val2 = 0; 4765 uint32_t phy_id = 0; 4766 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 4767 npi_status_t npi_status = NPI_SUCCESS; 4768 4769 npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1, 4770 &val1); 4771 if (npi_status != NPI_SUCCESS) { 4772 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 4773 "clause 22 read to reg 2 failed!!!")); 4774 goto exit; 4775 } 4776 npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2, 4777 &val2); 4778 if (npi_status != 0) { 4779 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 4780 "clause 22 read to reg 3 failed!!!")); 4781 goto exit; 4782 } 4783 phy_id = val1; 4784 phy_id = (phy_id << 16); 4785 phy_id |= val2; 4786 4787 exit: 4788 4789 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]", 4790 phy_port, phy_id)); 4791 4792 return (phy_id); 4793 } 4794 4795 /* 4796 * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 4797 * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 4798 * read. Then use the values obtained to determine the phy type of each port 4799 * and the Neptune type. 4800 */ 4801 4802 nxge_status_t 4803 nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 4804 { 4805 int i, j, k, l; 4806 uint32_t pma_pmd_dev_id = 0; 4807 uint32_t pcs_dev_id = 0; 4808 uint32_t phy_id = 0; 4809 uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE]; 4810 uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE]; 4811 uint32_t port_phy_id[NXGE_PORTS_NEPTUNE]; 4812 uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 4813 uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 4814 uint8_t phy_fd[NXGE_MAX_PHY_PORTS]; 4815 uint8_t port_fd[NXGE_MAX_PHY_PORTS]; 4816 uint8_t total_port_fd, total_phy_fd; 4817 nxge_status_t status = NXGE_OK; 4818 int prt_id = -1; 4819 4820 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 4821 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4822 "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 4823 nxgep->niu_type)); 4824 4825 j = k = l = 0; 4826 total_port_fd = total_phy_fd = 0; 4827 /* 4828 * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved 4829 * for on chip serdes usages. 4830 */ 4831 for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 4832 4833 pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i); 4834 4835 if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 4836 pma_pmd_dev_fd[i] = 1; 4837 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 4838 "PMA/PMD dev found", i)); 4839 if (j < NXGE_PORTS_NEPTUNE) { 4840 port_pma_pmd_dev_id[j] = pma_pmd_dev_id & 4841 BCM_PHY_ID_MASK; 4842 j++; 4843 } 4844 } else { 4845 pma_pmd_dev_fd[i] = 0; 4846 } 4847 4848 pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i); 4849 4850 if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 4851 pcs_dev_fd[i] = 1; 4852 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 4853 "dev found", i)); 4854 if (k < NXGE_PORTS_NEPTUNE) { 4855 port_pcs_dev_id[k] = pcs_dev_id & 4856 BCM_PHY_ID_MASK; 4857 k++; 4858 } 4859 } else { 4860 pcs_dev_fd[i] = 0; 4861 } 4862 4863 if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) 4864 port_fd[i] = 1; 4865 else 4866 port_fd[i] = 0; 4867 total_port_fd += port_fd[i]; 4868 4869 phy_id = nxge_get_cl22_phy_id(nxgep, i); 4870 4871 if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 4872 phy_fd[i] = 1; 4873 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 4874 "found", i)); 4875 if (l < NXGE_PORTS_NEPTUNE) { 4876 port_phy_id[l] = phy_id & BCM_PHY_ID_MASK; 4877 l++; 4878 } 4879 } else { 4880 phy_fd[i] = 0; 4881 } 4882 total_phy_fd += phy_fd[i]; 4883 } 4884 4885 switch (total_port_fd) { 4886 case 2: 4887 switch (total_phy_fd) { 4888 case 2: 4889 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4890 "Unsupported neptune type 1")); 4891 goto error_exit; 4892 case 1: 4893 /* TODO - 2 10G, 1 1G */ 4894 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4895 "Unsupported neptune type 2 10G, 1 1G")); 4896 goto error_exit; 4897 case 0: 4898 /* 2 10G */ 4899 if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 4900 (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 4901 ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 4902 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) { 4903 4904 /* 4905 * Check the first phy port address against 4906 * the known phy start addresses to determine 4907 * the platform type. 4908 */ 4909 for (i = NXGE_EXT_PHY_PORT_ST; 4910 i < NXGE_MAX_PHY_PORTS; i++) { 4911 if (port_fd[i] == 1) 4912 break; 4913 } 4914 if (i == BCM8704_NEPTUNE_PORT_ADDR_BASE) { 4915 hw_p->niu_type = NEPTUNE_2_10GF; 4916 hw_p->platform_type = 4917 P_NEPTUNE_ATLAS_2PORT; 4918 } else { 4919 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4920 "Unsupported neptune type 2 - 1")); 4921 goto error_exit; 4922 } 4923 hw_p->niu_type = NEPTUNE_2_10GF; 4924 } else { 4925 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4926 "Unsupported neptune type 2")); 4927 goto error_exit; 4928 } 4929 break; 4930 case 4: 4931 /* Maramba with 2 XAUI */ 4932 if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 4933 (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 4934 ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 4935 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) && 4936 ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 4937 (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 4938 (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 4939 (port_phy_id[3] == PHY_BCM5464R_FAMILY))) { 4940 4941 /* 4942 * Check the first phy port address against 4943 * the known phy start addresses to determine 4944 * the platform type. 4945 */ 4946 for (i = NXGE_EXT_PHY_PORT_ST; 4947 i < NXGE_MAX_PHY_PORTS; i++) { 4948 if (phy_fd[i] == 1) 4949 break; 4950 } 4951 if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 4952 hw_p->platform_type = 4953 P_NEPTUNE_MARAMBA_P0; 4954 } else if (i == 4955 BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 4956 hw_p->platform_type = 4957 P_NEPTUNE_MARAMBA_P1; 4958 } else { 4959 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4960 "Unknown port %d...Cannot " 4961 "determine platform type", i)); 4962 goto error_exit; 4963 } 4964 hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 4965 4966 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4967 "Maramba with 2 XAUI")); 4968 } else { 4969 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4970 "Unsupported neptune type 3")); 4971 goto error_exit; 4972 } 4973 break; 4974 default: 4975 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4976 "Unsupported neptune type 5")); 4977 goto error_exit; 4978 } 4979 break; 4980 case 1: 4981 switch (total_phy_fd) { 4982 case 3: 4983 /* 4984 * TODO 3 1G, 1 10G mode. 4985 * Differentiate between 1_1G_1_10G_2_1G and 4986 * 1_10G_3_1G 4987 */ 4988 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4989 "Unsupported neptune type 7")); 4990 goto error_exit; 4991 case 2: 4992 /* 4993 * TODO 2 1G, 1 10G mode. 4994 * Differentiate between 1_1G_1_10G_1_1G and 4995 * 1_10G_2_1G 4996 */ 4997 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4998 "Unsupported neptune type 8")); 4999 goto error_exit; 5000 case 1: 5001 /* 5002 * TODO 1 1G, 1 10G mode. 5003 * Differentiate between 1_1G_1_10G and 5004 * 1_10G_1_1G 5005 */ 5006 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5007 "Unsupported neptune type 9")); 5008 goto error_exit; 5009 case 0: 5010 /* TODO 1 10G mode */ 5011 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5012 "Unsupported neptune type 10")); 5013 goto error_exit; 5014 case 4: 5015 /* Maramba with 1 XAUI */ 5016 if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) || 5017 (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY)) { 5018 5019 /* 5020 * Check the first phy port address against 5021 * the known phy start addresses to determine 5022 * the platform type. 5023 */ 5024 for (i = NXGE_EXT_PHY_PORT_ST; 5025 i < NXGE_MAX_PHY_PORTS; i++) { 5026 if (phy_fd[i] == 1) 5027 break; 5028 } 5029 5030 if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 5031 hw_p->platform_type = 5032 P_NEPTUNE_MARAMBA_P0; 5033 } else if (i == 5034 BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 5035 hw_p->platform_type = 5036 P_NEPTUNE_MARAMBA_P1; 5037 } else { 5038 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5039 "Unknown port %d...Cannot " 5040 "determine platform type", i)); 5041 goto error_exit; 5042 } 5043 5044 /* The 10G port is BCM8704 */ 5045 for (i = NXGE_EXT_PHY_PORT_ST; 5046 i < NXGE_MAX_PHY_PORTS; i++) { 5047 if (port_fd[i] == 1) { 5048 prt_id = i; 5049 break; 5050 } 5051 } 5052 5053 prt_id %= BCM8704_MARAMBA_PORT_ADDR_BASE; 5054 if (prt_id == 0) { 5055 hw_p->niu_type = NEPTUNE_1_10GF_3_1GC; 5056 } else if (prt_id == 1) { 5057 hw_p->niu_type = 5058 NEPTUNE_1_1GC_1_10GF_2_1GC; 5059 } else { 5060 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5061 "Unsupported neptune type 11")); 5062 goto error_exit; 5063 } 5064 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5065 "Maramba with 1 XAUI")); 5066 } else { 5067 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5068 "Unsupported neptune type 12")); 5069 goto error_exit; 5070 } 5071 break; 5072 default: 5073 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5074 "Unsupported neptune type 13")); 5075 goto error_exit; 5076 } 5077 break; 5078 case 0: 5079 switch (total_phy_fd) { 5080 case 4: 5081 if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 5082 (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 5083 (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 5084 (port_phy_id[3] == PHY_BCM5464R_FAMILY)) { 5085 5086 /* 5087 * Check the first phy port address against 5088 * the known phy start addresses to determine 5089 * the platform type. 5090 */ 5091 for (i = NXGE_EXT_PHY_PORT_ST; 5092 i < NXGE_MAX_PHY_PORTS; i++) { 5093 if (phy_fd[i] == 1) 5094 break; 5095 } 5096 5097 if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 5098 hw_p->platform_type = 5099 P_NEPTUNE_MARAMBA_P1; 5100 } else if (i == 5101 BCM5464_NEPTUNE_PORT_ADDR_BASE) { 5102 hw_p->platform_type = 5103 P_NEPTUNE_ATLAS_4PORT; 5104 } else { 5105 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5106 "Unknown port %d...Cannot " 5107 "determine platform type", i)); 5108 goto error_exit; 5109 } 5110 hw_p->niu_type = NEPTUNE_4_1GC; 5111 } else { 5112 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5113 "Unsupported neptune type 14")); 5114 goto error_exit; 5115 } 5116 break; 5117 case 3: 5118 /* TODO 3 1G mode */ 5119 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5120 "Unsupported neptune type 15")); 5121 goto error_exit; 5122 case 2: 5123 /* TODO 2 1G mode */ 5124 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5125 "Unsupported neptune type 16")); 5126 goto error_exit; 5127 case 1: 5128 /* TODO 1 1G mode */ 5129 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5130 "Unsupported neptune type 17")); 5131 goto error_exit; 5132 default: 5133 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5134 "Unsupported neptune type 18, total phy fd %d", 5135 total_phy_fd)); 5136 goto error_exit; 5137 } 5138 break; 5139 default: 5140 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5141 "Unsupported neptune type 19")); 5142 goto error_exit; 5143 } 5144 5145 scan_exit: 5146 5147 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 5148 "niu type [0x%x]\n", hw_p->niu_type)); 5149 return (status); 5150 5151 error_exit: 5152 return (NXGE_ERROR); 5153 } 5154 5155 boolean_t 5156 nxge_is_valid_local_mac(ether_addr_st mac_addr) 5157 { 5158 if ((mac_addr.ether_addr_octet[0] & 0x01) || 5159 (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 5160 (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 5161 return (B_FALSE); 5162 else 5163 return (B_TRUE); 5164 } 5165 5166 static void 5167 nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 5168 5169 npi_status_t rs = NPI_SUCCESS; 5170 uint8_t xcvr_portn; 5171 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 5172 5173 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 5174 5175 if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 5176 xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 5177 } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 5178 xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 5179 } 5180 /* 5181 * For Altas 4-1G copper, Xcvr port numbers are 5182 * swapped with ethernet port number. This is 5183 * designed for better signal integrity in routing. 5184 */ 5185 switch (portn) { 5186 case 0: 5187 xcvr_portn += 3; 5188 break; 5189 case 1: 5190 xcvr_portn += 2; 5191 break; 5192 case 2: 5193 xcvr_portn += 1; 5194 break; 5195 case 3: 5196 default: 5197 break; 5198 } 5199 5200 MUTEX_ENTER(&nxge_mii_lock); 5201 rs = npi_mac_mif_mii_write(nxgep->npi_handle, 5202 xcvr_portn, BCM5464R_MISC, 0xb4ee); 5203 if (rs != NPI_SUCCESS) { 5204 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5205 "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 5206 "returned error 0x[%x]", rs)); 5207 MUTEX_EXIT(&nxge_mii_lock); 5208 return; 5209 } 5210 5211 rs = npi_mac_mif_mii_write(nxgep->npi_handle, 5212 xcvr_portn, BCM5464R_MISC, 0xb8ee); 5213 if (rs != NPI_SUCCESS) { 5214 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5215 "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 5216 "returned error 0x[%x]", rs)); 5217 MUTEX_EXIT(&nxge_mii_lock); 5218 return; 5219 } 5220 5221 MUTEX_EXIT(&nxge_mii_lock); 5222 } 5223 5224 static nxge_status_t 5225 nxge_mii_get_link_mode(p_nxge_t nxgep) 5226 { 5227 p_nxge_stats_t statsp; 5228 uint8_t xcvr_portn; 5229 p_mii_regs_t mii_regs; 5230 mii_mode_control_stat_t mode; 5231 int status = NXGE_OK; 5232 5233 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode")); 5234 5235 statsp = nxgep->statsp; 5236 xcvr_portn = statsp->mac_stats.xcvr_portn; 5237 mii_regs = NULL; 5238 mode.value = 0; 5239 mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 5240 #if defined(__i386) 5241 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5242 (uint8_t)(uint32_t)(&mii_regs->shadow), 5243 mode.value)) != NXGE_OK) { 5244 goto fail; 5245 #else 5246 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5247 (uint8_t)(uint64_t)(&mii_regs->shadow), 5248 mode.value)) != NXGE_OK) { 5249 goto fail; 5250 #endif 5251 } 5252 #if defined(__i386) 5253 if ((status = nxge_mii_read(nxgep, xcvr_portn, 5254 (uint8_t)(uint32_t)(&mii_regs->shadow), 5255 &mode.value)) != NXGE_OK) { 5256 goto fail; 5257 } 5258 #else 5259 if ((status = nxge_mii_read(nxgep, xcvr_portn, 5260 (uint8_t)(uint64_t)(&mii_regs->shadow), 5261 &mode.value)) != NXGE_OK) { 5262 goto fail; 5263 } 5264 #endif 5265 5266 if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) { 5267 nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 5268 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5269 "nxge_mii_get_link_mode: fiber mode")); 5270 } 5271 5272 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5273 "nxge_mii_get_link_mode: " 5274 "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x", 5275 NXGE_MII_MODE_CONTROL_REG, xcvr_portn, 5276 mode.value, nxgep->mac.portmode)); 5277 5278 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5279 "<== nxge_mii_get_link_mode")); 5280 return (status); 5281 fail: 5282 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5283 "<== nxge_mii_get_link_mode (failed)")); 5284 return (NXGE_ERROR); 5285 } 5286 5287 #ifdef NXGE_DEBUG 5288 static void 5289 nxge_mii_dump(p_nxge_t nxgep) 5290 { 5291 p_nxge_stats_t statsp; 5292 uint8_t xcvr_portn; 5293 p_mii_regs_t mii_regs; 5294 mii_bmcr_t bmcr; 5295 mii_bmsr_t bmsr; 5296 mii_idr1_t idr1; 5297 mii_idr2_t idr2; 5298 mii_mode_control_stat_t mode; 5299 5300 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump")); 5301 5302 param_arr = nxgep->param_arr; 5303 statsp = nxgep->statsp; 5304 xcvr_portn = statsp->mac_stats.xcvr_portn; 5305 5306 mii_regs = NULL; 5307 5308 #if defined(__i386) 5309 (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 5310 (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value); 5311 #else 5312 (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 5313 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value); 5314 #endif 5315 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5316 "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x", 5317 xcvr_portn, bmcr.value)); 5318 5319 #if defined(__i386) 5320 (void) nxge_mii_read(nxgep, 5321 nxgep->statsp->mac_stats.xcvr_portn, 5322 (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value); 5323 #else 5324 (void) nxge_mii_read(nxgep, 5325 nxgep->statsp->mac_stats.xcvr_portn, 5326 (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value); 5327 #endif 5328 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5329 "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x", 5330 xcvr_portn, bmsr.value)); 5331 5332 #if defined(__i386) 5333 (void) nxge_mii_read(nxgep, 5334 nxgep->statsp->mac_stats.xcvr_portn, 5335 (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value); 5336 #else 5337 (void) nxge_mii_read(nxgep, 5338 nxgep->statsp->mac_stats.xcvr_portn, 5339 (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value); 5340 #endif 5341 5342 5343 #if defined(__i386) 5344 (void) nxge_mii_read(nxgep, 5345 nxgep->statsp->mac_stats.xcvr_portn, 5346 (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value); 5347 #else 5348 (void) nxge_mii_read(nxgep, 5349 nxgep->statsp->mac_stats.xcvr_portn, 5350 (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value); 5351 #endif 5352 5353 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5354 "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x", 5355 xcvr_portn, idr1.value)); 5356 5357 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5358 "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x", 5359 xcvr_portn, idr2.value)); 5360 5361 mode.value = 0; 5362 mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 5363 5364 #if defined(__i386) 5365 (void) nxge_mii_write(nxgep, xcvr_portn, 5366 (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value); 5367 5368 (void) nxge_mii_read(nxgep, xcvr_portn, 5369 (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value); 5370 #else 5371 (void) nxge_mii_write(nxgep, xcvr_portn, 5372 (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value); 5373 5374 (void) nxge_mii_read(nxgep, xcvr_portn, 5375 (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value); 5376 #endif 5377 5378 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5379 "nxge_mii_dump: mode control xcvr 0x%x value 0x%x", 5380 xcvr_portn, mode.value)); 5381 } 5382 #endif 5383