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