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