13859Sml29623 /* 23859Sml29623 * CDDL HEADER START 33859Sml29623 * 43859Sml29623 * The contents of this file are subject to the terms of the 53859Sml29623 * Common Development and Distribution License (the "License"). 63859Sml29623 * You may not use this file except in compliance with the License. 73859Sml29623 * 83859Sml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93859Sml29623 * or http://www.opensolaris.org/os/licensing. 103859Sml29623 * See the License for the specific language governing permissions 113859Sml29623 * and limitations under the License. 123859Sml29623 * 133859Sml29623 * When distributing Covered Code, include this CDDL HEADER in each 143859Sml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153859Sml29623 * If applicable, add the following below this CDDL HEADER, with the 163859Sml29623 * fields enclosed by brackets "[]" replaced with your own identifying 173859Sml29623 * information: Portions Copyright [yyyy] [name of copyright owner] 183859Sml29623 * 193859Sml29623 * CDDL HEADER END 203859Sml29623 */ 213859Sml29623 /* 223859Sml29623 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 233859Sml29623 * Use is subject to license terms. 243859Sml29623 */ 253859Sml29623 263859Sml29623 #pragma ident "%Z%%M% %I% %E% SMI" 273859Sml29623 283859Sml29623 #include <sys/nxge/nxge_impl.h> 293859Sml29623 #include <sys/nxge/nxge_mac.h> 303859Sml29623 314693Stm144005 #define LINK_MONITOR_PERIOD (1000 * 1000) 324693Stm144005 #define LM_WAIT_MULTIPLIER 8 334693Stm144005 343859Sml29623 extern uint32_t nxge_no_link_notify; 354732Sdavemq extern boolean_t nxge_no_msg; 363859Sml29623 extern uint32_t nxge_lb_dbg; 373859Sml29623 extern nxge_os_mutex_t nxge_mdio_lock; 383859Sml29623 extern nxge_os_mutex_t nxge_mii_lock; 393859Sml29623 extern boolean_t nxge_jumbo_enable; 403859Sml29623 414693Stm144005 typedef enum { 424693Stm144005 CHECK_LINK_RESCHEDULE, 434693Stm144005 CHECK_LINK_STOP 444693Stm144005 } check_link_state_t; 454693Stm144005 464693Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *); 474693Stm144005 483859Sml29623 /* 493859Sml29623 * Ethernet broadcast address definition. 503859Sml29623 */ 513859Sml29623 static ether_addr_st etherbroadcastaddr = 523859Sml29623 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 534732Sdavemq /* 544732Sdavemq * Ethernet zero address definition. 554732Sdavemq */ 564185Sspeer static ether_addr_st etherzeroaddr = 574185Sspeer {{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; 584732Sdavemq /* 594732Sdavemq * Supported chip types 604732Sdavemq */ 614732Sdavemq static uint32_t nxge_supported_cl45_ids[] = {BCM8704_DEV_ID}; 624732Sdavemq static uint32_t nxge_supported_cl22_ids[] = {BCM5464R_PHY_ID}; 634732Sdavemq 644732Sdavemq #define NUM_CLAUSE_45_IDS (sizeof (nxge_supported_cl45_ids) / \ 654732Sdavemq sizeof (uint32_t)) 664732Sdavemq #define NUM_CLAUSE_22_IDS (sizeof (nxge_supported_cl22_ids) / \ 674732Sdavemq sizeof (uint32_t)) 684732Sdavemq /* 694732Sdavemq * static functions 704732Sdavemq */ 714977Sraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int); 724977Sraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int); 734977Sraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int); 744732Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t); 754732Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t); 764732Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t); 774732Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t); 784732Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t); 794732Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t); 804732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t); 814732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t); 824732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t); 834732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t); 844732Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t); 854732Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t); 864732Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t); 874732Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t); 884732Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t); 894732Sdavemq 904732Sdavemq /* 914732Sdavemq * xcvr tables for supported transceivers 924732Sdavemq */ 934732Sdavemq 944977Sraghus static nxge_xcvr_table_t nxge_n2_10G_table = { 954732Sdavemq nxge_n2_serdes_init, 964732Sdavemq nxge_10G_xcvr_init, 974732Sdavemq nxge_10G_link_intr_stop, 984732Sdavemq nxge_10G_link_intr_start, 994732Sdavemq nxge_check_10g_link, 1004732Sdavemq PCS_XCVR, 1014732Sdavemq BCM8704_N2_PORT_ADDR_BASE 1024732Sdavemq }; 1034732Sdavemq 1044977Sraghus static nxge_xcvr_table_t nxge_n2_1G_table = { 1054977Sraghus nxge_n2_serdes_init, 1064977Sraghus nxge_1G_xcvr_init, 1074977Sraghus nxge_1G_fiber_link_intr_stop, 1084977Sraghus nxge_1G_fiber_link_intr_start, 1094977Sraghus nxge_check_mii_link, 1104977Sraghus PCS_XCVR, 1114977Sraghus 0 1124977Sraghus }; 1134977Sraghus 1144732Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = { 1154732Sdavemq nxge_neptune_10G_serdes_init, 1164732Sdavemq nxge_10G_xcvr_init, 1174732Sdavemq nxge_10G_link_intr_stop, 1184732Sdavemq nxge_10G_link_intr_start, 1194732Sdavemq nxge_check_10g_link, 1204732Sdavemq PCS_XCVR, 1214732Sdavemq BCM8704_NEPTUNE_PORT_ADDR_BASE 1224732Sdavemq }; 1234732Sdavemq 1244732Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = { 1254732Sdavemq NULL, 1264732Sdavemq nxge_1G_xcvr_init, 1274732Sdavemq nxge_1G_copper_link_intr_stop, 1284732Sdavemq nxge_1G_copper_link_intr_start, 1294732Sdavemq nxge_check_mii_link, 1304732Sdavemq INT_MII_XCVR, 1314732Sdavemq BCM5464_NEPTUNE_PORT_ADDR_BASE 1324732Sdavemq }; 1334732Sdavemq 1344732Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = { 1354732Sdavemq nxge_1G_serdes_init, 1364732Sdavemq nxge_1G_xcvr_init, 1374732Sdavemq nxge_1G_fiber_link_intr_stop, 1384732Sdavemq nxge_1G_fiber_link_intr_start, 1394732Sdavemq nxge_check_mii_link, 1404732Sdavemq PCS_XCVR, 1414732Sdavemq 0 1424732Sdavemq }; 1434732Sdavemq 1444732Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = { 1454732Sdavemq nxge_neptune_10G_serdes_init, 1464732Sdavemq NULL, 1474732Sdavemq NULL, 1484732Sdavemq NULL, 1494977Sraghus NULL, 1504732Sdavemq PCS_XCVR, 1514732Sdavemq 0 1524732Sdavemq }; 1533859Sml29623 1543859Sml29623 nxge_status_t nxge_mac_init(p_nxge_t); 1553859Sml29623 1565196Ssbehera #ifdef NXGE_DEBUG 1575196Ssbehera static void nxge_mii_dump(p_nxge_t); 1585196Ssbehera #endif 1595196Ssbehera static nxge_status_t nxge_mii_get_link_mode(p_nxge_t); 1605196Ssbehera 1614977Sraghus nxge_status_t 1624977Sraghus nxge_get_xcvr_type(p_nxge_t nxgep) 1634977Sraghus { 1644977Sraghus nxge_status_t status = NXGE_OK; 1654977Sraghus char *phy_type; 1664977Sraghus char *prop_val; 1674977Sraghus 1684977Sraghus nxgep->mac.portmode = 0; 1694977Sraghus 1704977Sraghus /* Get property from the driver conf. file */ 1714977Sraghus if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 1724977Sraghus DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 1734977Sraghus "phy-type", &prop_val)) == DDI_PROP_SUCCESS) { 1744977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1754977Sraghus "found conf file: phy-type %s", prop_val)); 1764977Sraghus if (strcmp("xgsd", prop_val) == 0) { 1774977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 1784977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 1794977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1804977Sraghus "found: 10G Serdes")); 1814977Sraghus } else if (strcmp("gsd", prop_val) == 0) { 1824977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 1834977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 1844977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes")); 1854977Sraghus } else if (strcmp("mif", prop_val) == 0) { 1864977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 1874977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 1884977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 1894977Sraghus } else if (strcmp("pcs", prop_val) == 0) { 1904977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 1914977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 1924977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr")); 1934977Sraghus } 1944977Sraghus 1954977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 1964977Sraghus "phy-type", prop_val); 1974977Sraghus ddi_prop_free(prop_val); 1984977Sraghus 1994977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 2004977Sraghus "Got phy type [0x%x] from conf file", 2014977Sraghus nxgep->mac.portmode)); 2024977Sraghus 2034977Sraghus return (NXGE_OK); 2044977Sraghus } 2054977Sraghus /* 2064977Sraghus * TODO add MDIO support for Monza RTM card, Glendale (also Goa) - 2074977Sraghus * only N2-NIU 2084977Sraghus */ 2094977Sraghus if (nxgep->niu_type == N2_NIU) { 2104977Sraghus if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 2114977Sraghus "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 2124977Sraghus if (strcmp("xgf", prop_val) == 0) { 2134977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = 2144977Sraghus XPCS_XCVR; 2154977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 2164977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2174977Sraghus "10G Fiber Xcvr")); 2184977Sraghus } else if (strcmp("mif", prop_val) == 0) { 2194977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = 2204977Sraghus INT_MII_XCVR; 2214977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 2224977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2234977Sraghus "1G Copper Xcvr")); 2244977Sraghus } else if (strcmp("pcs", prop_val) == 0) { 2254977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 2264977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 2274977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2284977Sraghus "1G Fiber Xcvr")); 2294977Sraghus } else if (strcmp("xgc", prop_val) == 0) { 2304977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = 2314977Sraghus XPCS_XCVR; 2324977Sraghus nxgep->mac.portmode = PORT_10G_COPPER; 2334977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2344977Sraghus "10G Copper Xcvr")); 2354977Sraghus } else if (strcmp("xgsd", prop_val) == 0) { 2364977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 2374977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 2384977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2394977Sraghus "OBP: 10G Serdes")); 2404977Sraghus } else if (strcmp("gsd", prop_val) == 0) { 2414977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 2424977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 2434977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2444977Sraghus "OBP: 1G Serdes")); 2454977Sraghus } else { 2464977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2474977Sraghus "Unknown phy-type: %s", prop_val)); 2484977Sraghus ddi_prop_free(prop_val); 2494977Sraghus return (NXGE_ERROR); 2504977Sraghus } 2514977Sraghus status = NXGE_OK; 2524977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, 2534977Sraghus nxgep->dip, "phy-type", prop_val); 2544977Sraghus ddi_prop_free(prop_val); 2554977Sraghus 2564977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 2574977Sraghus "Got phy type [0x%x] from OBP", 2584977Sraghus nxgep->mac.portmode)); 2594977Sraghus 2604977Sraghus return (status); 2614977Sraghus } else { 2624977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2634977Sraghus "Exiting...phy-type property not found")); 2644977Sraghus return (NXGE_ERROR); 2654977Sraghus } 2664977Sraghus } 2674977Sraghus 2684977Sraghus 2694977Sraghus if (!nxgep->vpd_info.present) { 2704977Sraghus return (NXGE_OK); 2714977Sraghus } 2724977Sraghus 2734977Sraghus if (!nxgep->vpd_info.ver_valid) { 2744977Sraghus goto read_seeprom; 2754977Sraghus } 2764977Sraghus 2774977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2784977Sraghus "Reading phy type from expansion ROM")); 2794977Sraghus /* 2804977Sraghus * Try to read the phy type from the vpd data read off the 2814977Sraghus * expansion ROM. 2824977Sraghus */ 2834977Sraghus phy_type = nxgep->vpd_info.phy_type; 2844977Sraghus 2855196Ssbehera if (strncmp(phy_type, "mif", 3) == 0) { 2864977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 2874977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 2885196Ssbehera } else if (strncmp(phy_type, "xgf", 3) == 0) { 2894977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 2904977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 2915196Ssbehera } else if (strncmp(phy_type, "pcs", 3) == 0) { 2924977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 2934977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 2945196Ssbehera } else if (strncmp(phy_type, "xgc", 3) == 0) { 2954977Sraghus nxgep->mac.portmode = PORT_10G_COPPER; 2964977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 2975196Ssbehera } else if (strncmp(phy_type, "xgsd", 4) == 0) { 2985196Ssbehera nxgep->mac.portmode = PORT_10G_SERDES; 2995196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3005196Ssbehera } else if (strncmp(phy_type, "gsd", 3) == 0) { 3015196Ssbehera nxgep->mac.portmode = PORT_1G_SERDES; 3025196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3034977Sraghus } else { 3045196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3054977Sraghus "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM", 3064977Sraghus phy_type[0], phy_type[1], phy_type[2])); 3074977Sraghus goto read_seeprom; 3084977Sraghus } 3094977Sraghus 3104977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 3114977Sraghus "Got phy type [0x%x] from VPD", nxgep->mac.portmode)); 3124977Sraghus 3134977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 3144977Sraghus return (status); 3154977Sraghus 3164977Sraghus read_seeprom: 3174977Sraghus /* 3184977Sraghus * read the phy type from the SEEPROM - NCR registers 3194977Sraghus */ 3204977Sraghus status = nxge_espc_phy_type_get(nxgep); 3214977Sraghus if (status != NXGE_OK) { 3224977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3234977Sraghus "Failed to get phy type")); 3244977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 3254977Sraghus "[%s] invalid...please update", nxgep->vpd_info.ver)); 3264977Sraghus } 3274977Sraghus 3284977Sraghus return (status); 3294977Sraghus 3304977Sraghus } 3314977Sraghus 3324732Sdavemq /* Set up the PHY specific values. */ 3334732Sdavemq 3344732Sdavemq nxge_status_t 3354732Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep) 3364732Sdavemq { 3374732Sdavemq nxge_status_t status = NXGE_OK; 3384732Sdavemq uint32_t port_type; 3394732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 3404977Sraghus uint32_t pcs_id = 0; 3414977Sraghus uint32_t pma_pmd_id = 0; 3424977Sraghus uint32_t phy_id = 0; 3434732Sdavemq 3444732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>", 3454732Sdavemq portn)); 3464732Sdavemq 3474977Sraghus switch (nxgep->niu_type) { 3484977Sraghus case N2_NIU: 3494977Sraghus switch (nxgep->mac.portmode) { 3504977Sraghus case PORT_1G_FIBER: 3514977Sraghus case PORT_1G_SERDES: 3524977Sraghus nxgep->xcvr = nxge_n2_1G_table; 3534977Sraghus nxgep->xcvr.xcvr_addr = portn; 3544977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr", 3554977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" : 3564977Sraghus "Serdes")); 3574977Sraghus break; 3584977Sraghus case PORT_10G_FIBER: 3594977Sraghus case PORT_10G_SERDES: 3604977Sraghus nxgep->xcvr = nxge_n2_10G_table; 3614977Sraghus nxgep->xcvr.xcvr_addr += portn; 3624977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr", 3634977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" : 3644977Sraghus "Serdes")); 3654977Sraghus break; 3664977Sraghus default: 3674977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3684977Sraghus "<== nxge_setup_xcvr_table: " 3694977Sraghus "Unable to determine NIU portmode")); 3704977Sraghus return (NXGE_ERROR); 3714977Sraghus } 3724977Sraghus break; 3734977Sraghus default: 3744977Sraghus if (nxgep->mac.portmode == 0) { 3754977Sraghus /* 3764977Sraghus * Would be the case for platforms like Maramba 3774977Sraghus * in which the phy type could not be got from conf 3784977Sraghus * file, OBP, VPD or Serial PROM. 3794977Sraghus */ 3804977Sraghus if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 3814977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3824977Sraghus "<== nxge_setup_xcvr_table:" 3834977Sraghus " Invalid Neptune type [0x%x]", 3844977Sraghus nxgep->niu_type)); 3854977Sraghus return (NXGE_ERROR); 3864977Sraghus } 3874977Sraghus 3884977Sraghus port_type = nxgep->niu_type >> 3894977Sraghus (NXGE_PORT_TYPE_SHIFT * portn); 3904977Sraghus port_type = port_type & (NXGE_PORT_TYPE_MASK); 3914977Sraghus 3924977Sraghus switch (port_type) { 3934977Sraghus 3944977Sraghus case NXGE_PORT_1G_COPPER: 3954977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 3964977Sraghus break; 3974977Sraghus case NXGE_PORT_10G_COPPER: 3984977Sraghus nxgep->mac.portmode = PORT_10G_COPPER; 3994977Sraghus break; 4004977Sraghus case NXGE_PORT_1G_FIBRE: 4014977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 4024977Sraghus break; 4034977Sraghus case NXGE_PORT_10G_FIBRE: 4044977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 4054977Sraghus break; 4064977Sraghus case NXGE_PORT_1G_SERDES: 4074977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 4084977Sraghus break; 4094977Sraghus case NXGE_PORT_10G_SERDES: 4104977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 4114977Sraghus break; 4124977Sraghus case NXGE_PORT_1G_RGMII_FIBER: 4134977Sraghus nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 4144977Sraghus break; 4154977Sraghus default: 4164977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4174977Sraghus "<== nxge_setup_xcvr_table: " 4184977Sraghus "Unknown port-type: 0x%x", port_type)); 4194977Sraghus return (NXGE_ERROR); 4204977Sraghus } 4214977Sraghus } 4224977Sraghus 4234977Sraghus switch (nxgep->mac.portmode) { 4244977Sraghus case PORT_1G_COPPER: 4254977Sraghus case PORT_1G_RGMII_FIBER: 4264732Sdavemq nxgep->xcvr = nxge_1G_copper_table; 4274977Sraghus 4284977Sraghus /* 4294977Sraghus * For Altas 4-1G copper, Xcvr port numbers are 4304977Sraghus * swapped with ethernet port number. This is 4314977Sraghus * designed for better signal integrity in 4324977Sraghus * routing. This is also the case for the 4334977Sraghus * on-board Neptune copper ports on the Maramba 4344977Sraghus * platform. 4354977Sraghus */ 4364977Sraghus switch (nxgep->platform_type) { 4374977Sraghus case P_NEPTUNE_MARAMBA_P1: 4384732Sdavemq nxgep->xcvr.xcvr_addr = 4394732Sdavemq BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 4404977Sraghus break; 4414977Sraghus case P_NEPTUNE_MARAMBA_P0: 4424732Sdavemq nxgep->xcvr.xcvr_addr = 4434732Sdavemq BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 4444977Sraghus break; 4454977Sraghus default: 4464977Sraghus break; 4474732Sdavemq } 4484732Sdavemq /* 4494732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 4504732Sdavemq * swapped with ethernet port number. This is 4514977Sraghus * designed for better signal integrity in 4524977Sraghus * routing. This is also the case for the 4534977Sraghus * on-board Neptune copper ports on the Maramba 4544977Sraghus * platform. 4554732Sdavemq */ 4564977Sraghus switch (nxgep->platform_type) { 4574977Sraghus case P_NEPTUNE_ATLAS_4PORT: 4584977Sraghus case P_NEPTUNE_MARAMBA_P0: 4594977Sraghus case P_NEPTUNE_MARAMBA_P1: 4604977Sraghus switch (portn) { 4614977Sraghus case 0: 4624977Sraghus nxgep->xcvr.xcvr_addr += 3; 4634977Sraghus break; 4644977Sraghus case 1: 4654977Sraghus nxgep->xcvr.xcvr_addr += 2; 4664977Sraghus break; 4674977Sraghus case 2: 4684977Sraghus nxgep->xcvr.xcvr_addr += 1; 4694977Sraghus break; 4704977Sraghus case 3: 4714977Sraghus break; 4724977Sraghus default: 4734977Sraghus return (NXGE_ERROR); 4744977Sraghus } 4754732Sdavemq break; 4765196Ssbehera case P_NEPTUNE_ALONSO: 4775196Ssbehera /* 4785196Ssbehera * The Alonso Neptune, xcvr port numbers for 4795196Ssbehera * ports 2 and 3 are not swapped. Port 2 has 4805196Ssbehera * the BCM5464_PORT_BASE_ADDR and port 3 has 4815196Ssbehera * next address. 4825196Ssbehera */ 4835196Ssbehera if (portn == 3) { 4845196Ssbehera nxgep->xcvr.xcvr_addr += 1; 4855196Ssbehera } 4865196Ssbehera break; 4874732Sdavemq default: 4884977Sraghus break; 4894732Sdavemq } 4905196Ssbehera 4914977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 4924977Sraghus (nxgep->mac.portmode == PORT_1G_COPPER) ? 4934977Sraghus "Copper" : "RGMII Fiber")); 4944732Sdavemq break; 4954977Sraghus case PORT_10G_COPPER: 4964732Sdavemq nxgep->xcvr = nxge_10G_copper_table; 4974732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 4984732Sdavemq break; 4994977Sraghus case PORT_1G_FIBER: 5004977Sraghus case PORT_1G_SERDES: 5014732Sdavemq nxgep->xcvr = nxge_1G_fiber_table; 5024977Sraghus nxgep->xcvr.xcvr_addr = portn; 5034977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 5044977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? 5054977Sraghus "Fiber" : "Serdes")); 5064732Sdavemq break; 5074977Sraghus case PORT_10G_FIBER: 5084977Sraghus case PORT_10G_SERDES: 5094732Sdavemq nxgep->xcvr = nxge_10G_fiber_table; 5104977Sraghus switch (nxgep->platform_type) { 5114977Sraghus case P_NEPTUNE_MARAMBA_P0: 5124977Sraghus case P_NEPTUNE_MARAMBA_P1: 5134732Sdavemq nxgep->xcvr.xcvr_addr = 5144732Sdavemq BCM8704_MARAMBA_PORT_ADDR_BASE; 5154732Sdavemq /* 5164732Sdavemq * Switch off LED for corresponding copper 5174732Sdavemq * port 5184732Sdavemq */ 5194732Sdavemq nxge_bcm5464_link_led_off(nxgep); 5204977Sraghus break; 5214977Sraghus default: 5224977Sraghus break; 5234732Sdavemq } 5244732Sdavemq nxgep->xcvr.xcvr_addr += portn; 5254977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr", 5264977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? 5274977Sraghus "Fiber" : "Serdes")); 5284732Sdavemq break; 5294732Sdavemq default: 5304732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5314732Sdavemq "Unknown port-type: 0x%x", port_type)); 5324732Sdavemq return (NXGE_ERROR); 5334732Sdavemq } 5344732Sdavemq } 5354732Sdavemq 5364732Sdavemq nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse; 5374732Sdavemq nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr.xcvr_addr; 5384977Sraghus 5394977Sraghus /* 5404977Sraghus * Get the actual device ID value returned by MDIO read. 5414977Sraghus */ 5424977Sraghus nxgep->statsp->mac_stats.xcvr_id = 0; 5434977Sraghus 5444977Sraghus pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr.xcvr_addr); 5454977Sraghus if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) { 5464977Sraghus nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id; 5474977Sraghus } else { 5484977Sraghus pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr.xcvr_addr); 5494977Sraghus if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) { 5504977Sraghus nxgep->statsp->mac_stats.xcvr_id = pcs_id; 5514977Sraghus } else { 5524977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, 5534977Sraghus nxgep->xcvr.xcvr_addr); 5544977Sraghus if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 5554977Sraghus nxgep->statsp->mac_stats.xcvr_id = phy_id; 5564977Sraghus } 5574977Sraghus } 5584977Sraghus } 5594977Sraghus 5604732Sdavemq nxgep->mac.linkchkmode = LINKCHK_TIMER; 5614732Sdavemq 5624977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type" 5634977Sraghus "[0x%x] platform type[0x%x]", nxgep->niu_type, 5644977Sraghus nxgep->platform_type)); 5654977Sraghus 5664732Sdavemq return (status); 5674732Sdavemq } 5684732Sdavemq 5693859Sml29623 /* Initialize the entire MAC and physical layer */ 5703859Sml29623 5713859Sml29623 nxge_status_t 5723859Sml29623 nxge_mac_init(p_nxge_t nxgep) 5733859Sml29623 { 5743859Sml29623 uint8_t portn; 5753859Sml29623 nxge_status_t status = NXGE_OK; 5763859Sml29623 5773859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 5783859Sml29623 5793859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 5803859Sml29623 5813859Sml29623 nxgep->mac.portnum = portn; 5823859Sml29623 nxgep->mac.porttype = PORT_TYPE_XMAC; 5833859Sml29623 5843859Sml29623 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 5853859Sml29623 nxgep->mac.porttype = PORT_TYPE_BMAC; 5863859Sml29623 5873859Sml29623 /* Initialize XIF to configure a network mode */ 5883859Sml29623 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 5893859Sml29623 goto fail; 5903859Sml29623 } 5913859Sml29623 5923859Sml29623 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 5933859Sml29623 goto fail; 5943859Sml29623 } 5953859Sml29623 5963859Sml29623 /* Initialize TX and RX MACs */ 5973859Sml29623 /* 5983859Sml29623 * Always perform XIF init first, before TX and RX MAC init 5993859Sml29623 */ 6003859Sml29623 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 6013859Sml29623 goto fail; 6023859Sml29623 6033859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 6043859Sml29623 goto fail; 6053859Sml29623 6063859Sml29623 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 6073859Sml29623 goto fail; 6083859Sml29623 6093859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 6103859Sml29623 goto fail; 6113859Sml29623 6123859Sml29623 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 6133859Sml29623 goto fail; 6143859Sml29623 6153859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 6163859Sml29623 goto fail; 6173859Sml29623 618*5553Smisaki /* Initialize MAC control configuration */ 619*5553Smisaki if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) { 620*5553Smisaki goto fail; 621*5553Smisaki } 622*5553Smisaki 6233859Sml29623 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 6243859Sml29623 6255196Ssbehera /* The Neptune Serdes needs to be reinitialized again */ 6265196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 6275196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 6285196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 6295196Ssbehera ((portn == 0) || (portn == 1))) { 6305196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6315196Ssbehera "nxge_mac_init: reinit Neptune 1G Serdes ")); 6325196Ssbehera if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) { 6335196Ssbehera goto fail; 6345196Ssbehera } 6355196Ssbehera } 6365196Ssbehera 6374977Sraghus 6383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 6393859Sml29623 6403859Sml29623 return (NXGE_OK); 6413859Sml29623 fail: 6423859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6433859Sml29623 "nxge_mac_init: failed to initialize MAC port<%d>", 6443859Sml29623 portn)); 6453859Sml29623 return (status); 6463859Sml29623 } 6473859Sml29623 6483859Sml29623 /* Initialize the Ethernet Link */ 6493859Sml29623 6503859Sml29623 nxge_status_t 6513859Sml29623 nxge_link_init(p_nxge_t nxgep) 6523859Sml29623 { 6533859Sml29623 nxge_status_t status = NXGE_OK; 6544977Sraghus nxge_port_mode_t portmode; 6553859Sml29623 #ifdef NXGE_DEBUG 6563859Sml29623 uint8_t portn; 6573859Sml29623 6583859Sml29623 portn = nxgep->mac.portnum; 6593859Sml29623 6603859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 6613859Sml29623 #endif 6623859Sml29623 6634977Sraghus portmode = nxgep->mac.portmode; 6644977Sraghus if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) && 6654977Sraghus (portmode != PORT_1G_SERDES)) { 6663859Sml29623 /* Workaround to get link up in both NIU ports */ 6674977Sraghus if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) { 6683859Sml29623 goto fail; 6694977Sraghus } 6703859Sml29623 } 6713859Sml29623 NXGE_DELAY(200000); 6723859Sml29623 /* Initialize internal serdes */ 6733859Sml29623 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 6743859Sml29623 goto fail; 6753859Sml29623 NXGE_DELAY(200000); 6763859Sml29623 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 6773859Sml29623 goto fail; 6783859Sml29623 6793859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 6803859Sml29623 6813859Sml29623 return (NXGE_OK); 6823859Sml29623 6833859Sml29623 fail: 6843859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6853859Sml29623 "nxge_link_init: ", 6863859Sml29623 "failed to initialize Ethernet link on port<%d>", 6873859Sml29623 portn)); 6883859Sml29623 6893859Sml29623 return (status); 6903859Sml29623 } 6913859Sml29623 6923859Sml29623 6933859Sml29623 /* Initialize the XIF sub-block within the MAC */ 6943859Sml29623 6953859Sml29623 nxge_status_t 6963859Sml29623 nxge_xif_init(p_nxge_t nxgep) 6973859Sml29623 { 6983859Sml29623 uint32_t xif_cfg = 0; 6993859Sml29623 npi_attr_t ap; 7003859Sml29623 uint8_t portn; 7013859Sml29623 nxge_port_t portt; 7023859Sml29623 nxge_port_mode_t portmode; 7033859Sml29623 p_nxge_stats_t statsp; 7043859Sml29623 npi_status_t rs = NPI_SUCCESS; 7053859Sml29623 npi_handle_t handle; 7063859Sml29623 7073859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 7083859Sml29623 7093859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 7103859Sml29623 7113859Sml29623 handle = nxgep->npi_handle; 7123859Sml29623 portmode = nxgep->mac.portmode; 7133859Sml29623 portt = nxgep->mac.porttype; 7143859Sml29623 statsp = nxgep->statsp; 7153859Sml29623 7165196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 7175196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 7185196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 7195196Ssbehera ((portn == 0) || (portn == 1))) { 7205196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7215196Ssbehera "nxge_xcvr_init: set ATCA mode")); 7225196Ssbehera npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE); 7235196Ssbehera } 7245196Ssbehera 7253859Sml29623 if (portt == PORT_TYPE_XMAC) { 7263859Sml29623 7273859Sml29623 /* Setup XIF Configuration for XMAC */ 7283859Sml29623 7293859Sml29623 if ((portmode == PORT_10G_FIBER) || 7304977Sraghus (portmode == PORT_10G_COPPER) || 7314977Sraghus (portmode == PORT_10G_SERDES)) 7323859Sml29623 xif_cfg |= CFG_XMAC_XIF_LFS; 7333859Sml29623 7343859Sml29623 if (portmode == PORT_1G_COPPER) { 7353859Sml29623 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 7363859Sml29623 } 7373859Sml29623 7383859Sml29623 /* Set MAC Internal Loopback if necessary */ 7393859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 7403859Sml29623 xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 7413859Sml29623 7423859Sml29623 if (statsp->mac_stats.link_speed == 100) 7433859Sml29623 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 7443859Sml29623 7453859Sml29623 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 7463859Sml29623 7474977Sraghus if ((portmode == PORT_10G_FIBER) || 7484977Sraghus (portmode == PORT_10G_SERDES)) { 7493859Sml29623 if (statsp->mac_stats.link_up) { 7503859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 7513859Sml29623 } else { 7523859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 7533859Sml29623 } 7543859Sml29623 } 7553859Sml29623 7563859Sml29623 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 7573859Sml29623 if (rs != NPI_SUCCESS) 7583859Sml29623 goto fail; 7593859Sml29623 7603859Sml29623 nxgep->mac.xif_config = xif_cfg; 7613859Sml29623 7623859Sml29623 /* Set Port Mode */ 7633859Sml29623 if ((portmode == PORT_10G_FIBER) || 7644977Sraghus (portmode == PORT_10G_COPPER) || 7654977Sraghus (portmode == PORT_10G_SERDES)) { 7663859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 7673859Sml29623 MAC_XGMII_MODE, rs); 7683859Sml29623 if (rs != NPI_SUCCESS) 7693859Sml29623 goto fail; 7703859Sml29623 if (statsp->mac_stats.link_up) { 7713859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 7723859Sml29623 goto fail; 7733859Sml29623 } else { 7743859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 7753859Sml29623 goto fail; 7763859Sml29623 } 7773859Sml29623 } else if ((portmode == PORT_1G_FIBER) || 7784977Sraghus (portmode == PORT_1G_COPPER) || 7795196Ssbehera (portmode == PORT_1G_SERDES) || 7805196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 7815196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7825196Ssbehera "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]", 7835196Ssbehera portn, portmode, statsp->mac_stats.link_speed)); 7843859Sml29623 if (statsp->mac_stats.link_speed == 1000) { 7853859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 7863859Sml29623 MAC_GMII_MODE, rs); 7873859Sml29623 } else { 7883859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 7893859Sml29623 MAC_MII_MODE, rs); 7903859Sml29623 } 7913859Sml29623 if (rs != NPI_SUCCESS) 7923859Sml29623 goto fail; 7933859Sml29623 } else { 7943859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7953859Sml29623 "nxge_xif_init: Unknown port mode (%d)" 7963859Sml29623 " for port<%d>", portmode, portn)); 7973859Sml29623 goto fail; 7983859Sml29623 } 7993859Sml29623 8005196Ssbehera /* Enable ATCA mode */ 8015196Ssbehera 8023859Sml29623 } else if (portt == PORT_TYPE_BMAC) { 8033859Sml29623 8043859Sml29623 /* Setup XIF Configuration for BMAC */ 8053859Sml29623 8065196Ssbehera if ((portmode == PORT_1G_COPPER) || 8075196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 8083859Sml29623 if (statsp->mac_stats.link_speed == 100) 8093859Sml29623 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 8103859Sml29623 } 8113859Sml29623 8123859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 8133859Sml29623 xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 8143859Sml29623 8153859Sml29623 if (statsp->mac_stats.link_speed == 1000) 8163859Sml29623 xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 8173859Sml29623 8183859Sml29623 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 8193859Sml29623 8203859Sml29623 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 8213859Sml29623 if (rs != NPI_SUCCESS) 8223859Sml29623 goto fail; 8233859Sml29623 nxgep->mac.xif_config = xif_cfg; 8243859Sml29623 } 8253859Sml29623 8263859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 8273859Sml29623 return (NXGE_OK); 8283859Sml29623 fail: 8293859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8303859Sml29623 "nxge_xif_init: Failed to initialize XIF port<%d>", 8313859Sml29623 portn)); 8323859Sml29623 return (NXGE_ERROR | rs); 8333859Sml29623 } 8343859Sml29623 8353859Sml29623 /* Initialize the PCS sub-block in the MAC */ 8363859Sml29623 8373859Sml29623 nxge_status_t 8383859Sml29623 nxge_pcs_init(p_nxge_t nxgep) 8393859Sml29623 { 8403859Sml29623 pcs_cfg_t pcs_cfg; 8413859Sml29623 uint32_t val; 8423859Sml29623 uint8_t portn; 8433859Sml29623 nxge_port_mode_t portmode; 8443859Sml29623 npi_handle_t handle; 8453859Sml29623 p_nxge_stats_t statsp; 8463859Sml29623 npi_status_t rs = NPI_SUCCESS; 8473859Sml29623 8483859Sml29623 handle = nxgep->npi_handle; 8493859Sml29623 portmode = nxgep->mac.portmode; 8503859Sml29623 portn = nxgep->mac.portnum; 8513859Sml29623 statsp = nxgep->statsp; 8523859Sml29623 8533859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 8543859Sml29623 8554977Sraghus if ((portmode == PORT_1G_FIBER) || (portmode == PORT_1G_SERDES)) { 8564977Sraghus if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) { 8574977Sraghus goto fail; 8584977Sraghus } 8594977Sraghus 8603859Sml29623 /* Initialize port's PCS */ 8613859Sml29623 pcs_cfg.value = 0; 8623859Sml29623 pcs_cfg.bits.w0.enable = 1; 8633859Sml29623 pcs_cfg.bits.w0.mask = 1; 8643859Sml29623 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 8653859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 8664977Sraghus 8674977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8684977Sraghus "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx", 8694977Sraghus portn, pcs_cfg.value)); 8703859Sml29623 } else if ((portmode == PORT_10G_FIBER) || 8714977Sraghus (portmode == PORT_10G_COPPER) || (portmode == PORT_10G_SERDES)) { 8723859Sml29623 /* Use internal XPCS, bypass 1G PCS */ 8733859Sml29623 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 8743859Sml29623 val &= ~XMAC_XIF_XPCS_BYPASS; 8753859Sml29623 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 8763859Sml29623 8773859Sml29623 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 8783859Sml29623 goto fail; 8793859Sml29623 8803859Sml29623 /* Set XPCS Internal Loopback if necessary */ 8813859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 8823859Sml29623 XPCS_REG_CONTROL1, &val)) 8833859Sml29623 != NPI_SUCCESS) 8843859Sml29623 goto fail; 8853859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 8863859Sml29623 (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 8873859Sml29623 val |= XPCS_CTRL1_LOOPBK; 8883859Sml29623 else 8893859Sml29623 val &= ~XPCS_CTRL1_LOOPBK; 8903859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 8913859Sml29623 XPCS_REG_CONTROL1, val)) 8923859Sml29623 != NPI_SUCCESS) 8933859Sml29623 goto fail; 8943859Sml29623 8953859Sml29623 /* Clear descw errors */ 8963859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 8973859Sml29623 XPCS_REG_DESCWERR_COUNTER, 0)) 8983859Sml29623 != NPI_SUCCESS) 8993859Sml29623 goto fail; 9003859Sml29623 /* Clear symbol errors */ 9013859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 9023859Sml29623 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) 9033859Sml29623 != NPI_SUCCESS) 9043859Sml29623 goto fail; 9053859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 9063859Sml29623 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) 9073859Sml29623 != NPI_SUCCESS) 9083859Sml29623 goto fail; 9093859Sml29623 9105196Ssbehera } else if ((portmode == PORT_1G_COPPER) || 9115196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 9125196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 9135196Ssbehera "==> nxge_pcs_init: (1G) copper port<%d>", portn)); 9143859Sml29623 if (portn < 4) { 9153859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 9163859Sml29623 PCS_DATAPATH_MODE_MII); 9173859Sml29623 } 9183859Sml29623 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 9193859Sml29623 goto fail; 9203859Sml29623 9213859Sml29623 } else { 9223859Sml29623 goto fail; 9233859Sml29623 } 9243859Sml29623 pass: 9253859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 9263859Sml29623 return (NXGE_OK); 9273859Sml29623 fail: 9283859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 9293859Sml29623 "nxge_pcs_init: Failed to initialize PCS port<%d>", 9303859Sml29623 portn)); 9313859Sml29623 return (NXGE_ERROR | rs); 9323859Sml29623 } 9333859Sml29623 934*5553Smisaki /* 935*5553Smisaki * Initialize the MAC CTRL sub-block within the MAC 936*5553Smisaki * Only the receive-pause-cap is supported. 937*5553Smisaki */ 938*5553Smisaki nxge_status_t 939*5553Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep) 940*5553Smisaki { 941*5553Smisaki uint8_t portn; 942*5553Smisaki nxge_port_t portt; 943*5553Smisaki p_nxge_stats_t statsp; 944*5553Smisaki npi_handle_t handle; 945*5553Smisaki uint32_t val; 946*5553Smisaki 947*5553Smisaki portn = NXGE_GET_PORT_NUM(nxgep->function_num); 948*5553Smisaki 949*5553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>", 950*5553Smisaki portn)); 951*5553Smisaki 952*5553Smisaki handle = nxgep->npi_handle; 953*5553Smisaki portt = nxgep->mac.porttype; 954*5553Smisaki statsp = nxgep->statsp; 955*5553Smisaki 956*5553Smisaki if (portt == PORT_TYPE_XMAC) { 957*5553Smisaki /* Readin the current XMAC Config Register for XMAC */ 958*5553Smisaki XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 959*5553Smisaki 960*5553Smisaki /* 961*5553Smisaki * Setup XMAC Configuration for XMAC 962*5553Smisaki * XMAC only supports receive-pause 963*5553Smisaki */ 964*5553Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 965*5553Smisaki if (!statsp->mac_stats.adv_cap_pause) { 966*5553Smisaki /* 967*5553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 968*5553Smisaki * is 0, enable receive pause. 969*5553Smisaki */ 970*5553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 971*5553Smisaki } else { 972*5553Smisaki /* 973*5553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 974*5553Smisaki * is 1, disable receive pause. Send pause is 975*5553Smisaki * not supported. 976*5553Smisaki */ 977*5553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 978*5553Smisaki } 979*5553Smisaki } else { 980*5553Smisaki if (statsp->mac_stats.adv_cap_pause) { 981*5553Smisaki /* 982*5553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 983*5553Smisaki * is 1, enable receive pause. 984*5553Smisaki */ 985*5553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 986*5553Smisaki } else { 987*5553Smisaki /* 988*5553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 989*5553Smisaki * is 0, disable receive pause. Send pause is 990*5553Smisaki * not supported 991*5553Smisaki */ 992*5553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 993*5553Smisaki } 994*5553Smisaki } 995*5553Smisaki XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 996*5553Smisaki } else if (portt == PORT_TYPE_BMAC) { 997*5553Smisaki /* Readin the current MAC CTRL Config Register for BMAC */ 998*5553Smisaki BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val); 999*5553Smisaki 1000*5553Smisaki /* Setup MAC CTRL Configuration for BMAC */ 1001*5553Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 1002*5553Smisaki if (statsp->mac_stats.adv_cap_pause) { 1003*5553Smisaki /* 1004*5553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 1005*5553Smisaki * is 1, disable receive pause. Send pause 1006*5553Smisaki * is not supported 1007*5553Smisaki */ 1008*5553Smisaki val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN; 1009*5553Smisaki } else { 1010*5553Smisaki /* 1011*5553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 1012*5553Smisaki * is 0, enable receive pause and disable 1013*5553Smisaki * send pause. 1014*5553Smisaki */ 1015*5553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 1016*5553Smisaki val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN; 1017*5553Smisaki } 1018*5553Smisaki } else { 1019*5553Smisaki if (statsp->mac_stats.adv_cap_pause) { 1020*5553Smisaki /* 1021*5553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 1022*5553Smisaki * is 1, enable receive pause. Send pause is 1023*5553Smisaki * not supported. 1024*5553Smisaki */ 1025*5553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 1026*5553Smisaki } else { 1027*5553Smisaki /* 1028*5553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 1029*5553Smisaki * is 0, pause capability is not available in 1030*5553Smisaki * either direction. 1031*5553Smisaki */ 1032*5553Smisaki val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN & 1033*5553Smisaki ~MAC_CTRL_CFG_RECV_PAUSE_EN); 1034*5553Smisaki } 1035*5553Smisaki } 1036*5553Smisaki BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val); 1037*5553Smisaki } 1038*5553Smisaki 1039*5553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>", 1040*5553Smisaki portn)); 1041*5553Smisaki 1042*5553Smisaki return (NXGE_OK); 1043*5553Smisaki } 1044*5553Smisaki 10453859Sml29623 /* Initialize the Internal Serdes */ 10463859Sml29623 10473859Sml29623 nxge_status_t 10483859Sml29623 nxge_serdes_init(p_nxge_t nxgep) 10493859Sml29623 { 10503859Sml29623 p_nxge_stats_t statsp; 10513859Sml29623 #ifdef NXGE_DEBUG 10523859Sml29623 uint8_t portn; 10533859Sml29623 #endif 10543859Sml29623 nxge_status_t status = NXGE_OK; 10553859Sml29623 10563859Sml29623 #ifdef NXGE_DEBUG 10573859Sml29623 portn = nxgep->mac.portnum; 10583859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 10594732Sdavemq "==> nxge_serdes_init port<%d>", portn)); 10603859Sml29623 #endif 10613859Sml29623 10624732Sdavemq if (nxgep->xcvr.serdes_init) { 10634732Sdavemq statsp = nxgep->statsp; 10644732Sdavemq status = nxgep->xcvr.serdes_init(nxgep); 10654732Sdavemq if (status != NXGE_OK) 10663859Sml29623 goto fail; 10674732Sdavemq statsp->mac_stats.serdes_inits++; 10683859Sml29623 } 10693859Sml29623 10703859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 10714732Sdavemq portn)); 10723859Sml29623 10733859Sml29623 return (NXGE_OK); 10743859Sml29623 10753859Sml29623 fail: 10763859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 10774732Sdavemq "nxge_serdes_init: Failed to initialize serdes for port<%d>", 10784732Sdavemq portn)); 10793859Sml29623 10803859Sml29623 return (status); 10813859Sml29623 } 10823859Sml29623 10833859Sml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 10843859Sml29623 10854732Sdavemq static nxge_status_t 10863859Sml29623 nxge_n2_serdes_init(p_nxge_t nxgep) 10873859Sml29623 { 10883859Sml29623 uint8_t portn; 10893859Sml29623 int chan; 10903859Sml29623 esr_ti_cfgpll_l_t pll_cfg_l; 10914977Sraghus esr_ti_cfgpll_l_t pll_sts_l; 10923859Sml29623 esr_ti_cfgrx_l_t rx_cfg_l; 10933859Sml29623 esr_ti_cfgrx_h_t rx_cfg_h; 10943859Sml29623 esr_ti_cfgtx_l_t tx_cfg_l; 10953859Sml29623 esr_ti_cfgtx_h_t tx_cfg_h; 10964977Sraghus #ifdef NXGE_DEBUG 10974977Sraghus esr_ti_testcfg_t cfg; 10984977Sraghus #endif 10993859Sml29623 esr_ti_testcfg_t test_cfg; 11003859Sml29623 nxge_status_t status = NXGE_OK; 11013859Sml29623 11023859Sml29623 portn = nxgep->mac.portnum; 11033859Sml29623 11043859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 11053859Sml29623 portn)); 11063859Sml29623 11073859Sml29623 tx_cfg_l.value = 0; 11083859Sml29623 tx_cfg_h.value = 0; 11093859Sml29623 rx_cfg_l.value = 0; 11103859Sml29623 rx_cfg_h.value = 0; 11113859Sml29623 pll_cfg_l.value = 0; 11124977Sraghus pll_sts_l.value = 0; 11133859Sml29623 test_cfg.value = 0; 11143859Sml29623 11154977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER) || 11164977Sraghus (nxgep->mac.portmode == PORT_10G_SERDES)) { 11173859Sml29623 /* 0x0E01 */ 11183859Sml29623 tx_cfg_l.bits.entx = 1; 11193859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 11203859Sml29623 11213859Sml29623 /* 0x9101 */ 11223859Sml29623 rx_cfg_l.bits.enrx = 1; 11233859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 11243859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 11253859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 11263859Sml29623 11273859Sml29623 /* 0x0008 */ 11283859Sml29623 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 11293859Sml29623 11303859Sml29623 /* Set loopback mode if necessary */ 11313859Sml29623 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 11323859Sml29623 tx_cfg_l.bits.entest = 1; 11333859Sml29623 rx_cfg_l.bits.entest = 1; 11343859Sml29623 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 11353859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, 11363859Sml29623 ESR_N2_DEV_ADDR, 11373859Sml29623 ESR_N2_TEST_CFG_REG, test_cfg.value)) 11383859Sml29623 != NXGE_OK) 11393859Sml29623 goto fail; 11403859Sml29623 } 11413859Sml29623 11423859Sml29623 /* Use default PLL value */ 11433859Sml29623 11444977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 11454977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 11463859Sml29623 11473859Sml29623 /* 0x0E21 */ 11483859Sml29623 tx_cfg_l.bits.entx = 1; 11493859Sml29623 tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 11503859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 11513859Sml29623 11523859Sml29623 /* 0x9121 */ 11533859Sml29623 rx_cfg_l.bits.enrx = 1; 11543859Sml29623 rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 11553859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 11563859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 11573859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 11583859Sml29623 11594977Sraghus if (portn == 0) { 11604977Sraghus /* 0x8 */ 11614977Sraghus rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 11624977Sraghus } 11633859Sml29623 11643859Sml29623 /* MPY = 0x100 */ 11653859Sml29623 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 11663859Sml29623 11673859Sml29623 /* Set PLL */ 11683859Sml29623 pll_cfg_l.bits.enpll = 1; 11694977Sraghus pll_sts_l.bits.enpll = 1; 11703859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 11713859Sml29623 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) 11723859Sml29623 != NXGE_OK) 11733859Sml29623 goto fail; 11744977Sraghus 11754977Sraghus if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 11764977Sraghus ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 11774977Sraghus goto fail; 11784977Sraghus 11794977Sraghus #ifdef NXGE_DEBUG 11804977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 11814977Sraghus ESR_N2_PLL_CFG_L_REG, &cfg.value); 11824977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11834977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 11844977Sraghus portn, pll_cfg_l.value, cfg.value)); 11854977Sraghus 11864977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 11874977Sraghus ESR_N2_PLL_STS_L_REG, &cfg.value); 11884977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11894977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 11904977Sraghus portn, pll_sts_l.value, cfg.value)); 11914977Sraghus #endif 11924977Sraghus 11934977Sraghus /* Set loopback mode if necessary */ 11944977Sraghus if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 11954977Sraghus tx_cfg_l.bits.entest = 1; 11964977Sraghus rx_cfg_l.bits.entest = 1; 11974977Sraghus test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 11984977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11994977Sraghus "==> nxge_n2_serdes_init port<%d>: loopback 0x%x", 12004977Sraghus portn, test_cfg.value)); 12014977Sraghus if ((status = nxge_mdio_write(nxgep, portn, 12024977Sraghus ESR_N2_DEV_ADDR, 12034977Sraghus ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) { 12044977Sraghus goto fail; 12054977Sraghus } 12064977Sraghus } 12073859Sml29623 } else { 12083859Sml29623 goto fail; 12093859Sml29623 } 12103859Sml29623 12113859Sml29623 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 12123859Sml29623 12133859Sml29623 NXGE_DELAY(20); 12143859Sml29623 12153859Sml29623 /* init TX channels */ 12163859Sml29623 for (chan = 0; chan < 4; chan++) { 12173859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 12183859Sml29623 ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) 12193859Sml29623 != NXGE_OK) 12203859Sml29623 goto fail; 12213859Sml29623 12223859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 12233859Sml29623 ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) 12243859Sml29623 != NXGE_OK) 12253859Sml29623 goto fail; 12264977Sraghus 12274977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12284977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x", 12294977Sraghus portn, chan, tx_cfg_l.value)); 12304977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12314977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x", 12324977Sraghus portn, chan, tx_cfg_h.value)); 12333859Sml29623 } 12343859Sml29623 12353859Sml29623 /* init RX channels */ 12363859Sml29623 for (chan = 0; chan < 4; chan++) { 12373859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 12383859Sml29623 ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) 12393859Sml29623 != NXGE_OK) 12403859Sml29623 goto fail; 12413859Sml29623 12423859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 12433859Sml29623 ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) 12443859Sml29623 != NXGE_OK) 12453859Sml29623 goto fail; 12464977Sraghus 12474977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12484977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x", 12494977Sraghus portn, chan, rx_cfg_l.value)); 12504977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12514977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x", 12524977Sraghus portn, chan, rx_cfg_h.value)); 12533859Sml29623 } 12543859Sml29623 12553859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 12563859Sml29623 portn)); 12573859Sml29623 12583859Sml29623 return (NXGE_OK); 12593859Sml29623 fail: 12603859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12613859Sml29623 "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 12623859Sml29623 portn)); 12633859Sml29623 12643859Sml29623 return (status); 12653859Sml29623 } 12663859Sml29623 12674732Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */ 12684732Sdavemq 12694732Sdavemq static nxge_status_t 12704732Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep) 12713859Sml29623 { 12723859Sml29623 npi_handle_t handle; 12733859Sml29623 uint8_t portn; 12743859Sml29623 int chan; 12753859Sml29623 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 12763859Sml29623 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 12773859Sml29623 sr_glue_ctrl0_l_t glue_ctrl0_l; 12783859Sml29623 sr_glue_ctrl0_h_t glue_ctrl0_h; 12793859Sml29623 uint64_t val; 12803859Sml29623 uint16_t val16l; 12813859Sml29623 uint16_t val16h; 12823859Sml29623 nxge_status_t status = NXGE_OK; 12833859Sml29623 12843859Sml29623 portn = nxgep->mac.portnum; 12853859Sml29623 12863859Sml29623 if ((portn != 0) && (portn != 1)) 12873859Sml29623 return (NXGE_OK); 12883859Sml29623 12894732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12904732Sdavemq "==> nxge_neptune_10G_serdes_init port<%d>", portn)); 12913859Sml29623 12923859Sml29623 handle = nxgep->npi_handle; 12934732Sdavemq switch (portn) { 12944732Sdavemq case 0: 12954732Sdavemq ESR_REG_WR(handle, ESR_0_CONTROL_REG, 12964732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 12974732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 12984732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 12994732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 13004732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 13014732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 13024732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 13034732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 13044732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 13054732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 13064732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 13074732Sdavemq 13084732Sdavemq /* Set Serdes0 Internal Loopback if necessary */ 13094732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 13104732Sdavemq ESR_REG_WR(handle, 13114732Sdavemq ESR_0_TEST_CONFIG_REG, 13124732Sdavemq ESR_PAD_LOOPBACK_CH3 | 13134732Sdavemq ESR_PAD_LOOPBACK_CH2 | 13144732Sdavemq ESR_PAD_LOOPBACK_CH1 | 13154732Sdavemq ESR_PAD_LOOPBACK_CH0); 13164732Sdavemq } else { 13174732Sdavemq ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 13183859Sml29623 } 13194732Sdavemq break; 13204732Sdavemq case 1: 13214732Sdavemq ESR_REG_WR(handle, ESR_1_CONTROL_REG, 13224732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 13234732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 13244732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 13254732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 13264732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 13274732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 13284732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 13294732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 13304732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 13314732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 13324732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 13334732Sdavemq 13344732Sdavemq /* Set Serdes1 Internal Loopback if necessary */ 13354732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 13364732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 13374732Sdavemq ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 | 13384732Sdavemq ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0); 13394732Sdavemq } else { 13404732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 13413859Sml29623 } 13424732Sdavemq break; 13434732Sdavemq default: 13444732Sdavemq /* Nothing to do here */ 13454732Sdavemq goto done; 13464732Sdavemq } 13474732Sdavemq 13484732Sdavemq /* init TX RX channels */ 13494732Sdavemq for (chan = 0; chan < 4; chan++) { 13504732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 13514732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 13524732Sdavemq &rx_tx_ctrl_l.value)) != NXGE_OK) 13533859Sml29623 goto fail; 13544732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 13554732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 13564732Sdavemq &rx_tx_ctrl_h.value)) != NXGE_OK) 13573859Sml29623 goto fail; 13583859Sml29623 if ((status = nxge_mdio_read(nxgep, portn, 13594732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 13604732Sdavemq &glue_ctrl0_l.value)) != NXGE_OK) 13613859Sml29623 goto fail; 13623859Sml29623 if ((status = nxge_mdio_read(nxgep, portn, 13634732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 13644732Sdavemq &glue_ctrl0_h.value)) != NXGE_OK) 13654732Sdavemq goto fail; 13664732Sdavemq rx_tx_ctrl_l.bits.enstretch = 1; 13674732Sdavemq rx_tx_ctrl_h.bits.vmuxlo = 2; 13684732Sdavemq rx_tx_ctrl_h.bits.vpulselo = 2; 13694732Sdavemq glue_ctrl0_l.bits.rxlosenable = 1; 13704732Sdavemq glue_ctrl0_l.bits.samplerate = 0xF; 13714732Sdavemq glue_ctrl0_l.bits.thresholdcount = 0xFF; 13724732Sdavemq glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 13734732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 13744732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 13754732Sdavemq rx_tx_ctrl_l.value)) != NXGE_OK) 13764732Sdavemq goto fail; 13774732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 13784732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 13794732Sdavemq rx_tx_ctrl_h.value)) != NXGE_OK) 13804732Sdavemq goto fail; 13814732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 13824732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 13834732Sdavemq glue_ctrl0_l.value)) != NXGE_OK) 13844732Sdavemq goto fail; 13854732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 13864732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 13874732Sdavemq glue_ctrl0_h.value)) != NXGE_OK) 13883859Sml29623 goto fail; 13893859Sml29623 } 13903859Sml29623 13914732Sdavemq /* Apply Tx core reset */ 13924732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 13934732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 13944732Sdavemq (uint16_t)0)) != NXGE_OK) 13954732Sdavemq goto fail; 13964732Sdavemq 13974732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 13984732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 13994732Sdavemq NXGE_OK) 14004732Sdavemq goto fail; 14014732Sdavemq 14024732Sdavemq NXGE_DELAY(200); 14034732Sdavemq 14044732Sdavemq /* Apply Rx core reset */ 14054732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 14064732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 14074732Sdavemq NXGE_OK) 14084732Sdavemq goto fail; 14094732Sdavemq 14104732Sdavemq NXGE_DELAY(200); 14114732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 14124732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) 14134732Sdavemq goto fail; 14144732Sdavemq 14154732Sdavemq NXGE_DELAY(200); 14164732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 14174732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 14184732Sdavemq &val16l)) != NXGE_OK) 14194732Sdavemq goto fail; 14204732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 14214732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) 14224732Sdavemq goto fail; 14234732Sdavemq if ((val16l != 0) || (val16h != 0)) { 14244732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 14255196Ssbehera "Failed to reset port<%d> XAUI Serdes " 14265196Ssbehera "(val16l 0x%x val16h 0x%x)", 14275196Ssbehera portn, val16l, val16h)); 14284732Sdavemq } 14294732Sdavemq 14304732Sdavemq ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 14314732Sdavemq 14324732Sdavemq if (portn == 0) { 14334732Sdavemq if ((val & ESR_SIG_P0_BITS_MASK) != 14343859Sml29623 (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 14353859Sml29623 ESR_SIG_XSERDES_RDY_P0 | 14363859Sml29623 ESR_SIG_XDETECT_P0_CH3 | 14373859Sml29623 ESR_SIG_XDETECT_P0_CH2 | 14383859Sml29623 ESR_SIG_XDETECT_P0_CH1 | 14393859Sml29623 ESR_SIG_XDETECT_P0_CH0)) { 14404732Sdavemq goto fail; 14414732Sdavemq } 14424732Sdavemq } else if (portn == 1) { 14434732Sdavemq if ((val & ESR_SIG_P1_BITS_MASK) != 14443859Sml29623 (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 14453859Sml29623 ESR_SIG_XSERDES_RDY_P1 | 14463859Sml29623 ESR_SIG_XDETECT_P1_CH3 | 14473859Sml29623 ESR_SIG_XDETECT_P1_CH2 | 14483859Sml29623 ESR_SIG_XDETECT_P1_CH1 | 14493859Sml29623 ESR_SIG_XDETECT_P1_CH0)) { 14503859Sml29623 goto fail; 14513859Sml29623 } 14523859Sml29623 } 14533859Sml29623 14543859Sml29623 done: 14554732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14564732Sdavemq "<== nxge_neptune_10G_serdes_init port<%d>", portn)); 14574732Sdavemq 14583859Sml29623 return (NXGE_OK); 14593859Sml29623 fail: 14604732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14614732Sdavemq "nxge_neptune_10G_serdes_init: " 14624732Sdavemq "Failed to initialize Neptune serdes for port<%d>", portn)); 14633859Sml29623 14643859Sml29623 return (status); 14653859Sml29623 } 14663859Sml29623 14674732Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */ 14684732Sdavemq 14694732Sdavemq static nxge_status_t 14704732Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep) 14713859Sml29623 { 14724732Sdavemq npi_handle_t handle; 14734732Sdavemq uint8_t portn; 14745196Ssbehera int chan; 14755196Ssbehera sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 14765196Ssbehera sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 14775196Ssbehera sr_glue_ctrl0_l_t glue_ctrl0_l; 14785196Ssbehera sr_glue_ctrl0_h_t glue_ctrl0_h; 14794732Sdavemq uint64_t val; 14805196Ssbehera uint16_t val16l; 14815196Ssbehera uint16_t val16h; 14825196Ssbehera nxge_status_t status = NXGE_OK; 14833859Sml29623 14843859Sml29623 portn = nxgep->mac.portnum; 14854732Sdavemq 14864732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14874732Sdavemq "==> nxge_1G_serdes_init port<%d>", portn)); 14884732Sdavemq 14894732Sdavemq handle = nxgep->npi_handle; 14904732Sdavemq 14914732Sdavemq switch (portn) { 14924732Sdavemq case 0: 14935196Ssbehera /* Assert the reset register */ 14945196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 14955196Ssbehera val |= ESR_RESET_0; 14965196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 14975196Ssbehera 14985196Ssbehera /* Set the PLL register to 0x79 */ 14995196Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 15005196Ssbehera ESR_PLL_CFG_1G_SERDES); 15015196Ssbehera 15025196Ssbehera /* Set the control register to 0x249249f */ 15035196Ssbehera ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES); 15045196Ssbehera 15055196Ssbehera /* Set Serdes0 Internal Loopback if necessary */ 15065196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 15075196Ssbehera /* Set pad loopback modes 0xaa */ 15085196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 15095196Ssbehera ESR_TSTCFG_LBTEST_PAD); 15105196Ssbehera } else { 15115196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 15125196Ssbehera } 15135196Ssbehera 15145196Ssbehera /* Deassert the reset register */ 15155196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 15165196Ssbehera val &= ~ESR_RESET_0; 15175196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 15184732Sdavemq break; 15195196Ssbehera 15204732Sdavemq case 1: 15215196Ssbehera /* Assert the reset register */ 15225196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 15235196Ssbehera val |= ESR_RESET_1; 15245196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 15255196Ssbehera 15265196Ssbehera /* Set PLL register to 0x79 */ 15275196Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 15285196Ssbehera ESR_PLL_CFG_1G_SERDES); 15295196Ssbehera 15305196Ssbehera /* Set the control register to 0x249249f */ 15315196Ssbehera ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES); 15325196Ssbehera 15335196Ssbehera /* Set Serdes1 Internal Loopback if necessary */ 15345196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 15355196Ssbehera /* Set pad loopback mode 0xaa */ 15365196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 15375196Ssbehera ESR_TSTCFG_LBTEST_PAD); 15385196Ssbehera } else { 15395196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 15405196Ssbehera } 15415196Ssbehera 15425196Ssbehera /* Deassert the reset register */ 15435196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 15445196Ssbehera val &= ~ESR_RESET_1; 15455196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 15464732Sdavemq break; 15475196Ssbehera 15484732Sdavemq default: 15495196Ssbehera /* Nothing to do here */ 15505196Ssbehera goto done; 15515196Ssbehera } 15525196Ssbehera 15535196Ssbehera /* init TX RX channels */ 15545196Ssbehera for (chan = 0; chan < 4; chan++) { 15555196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 15565196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 15575196Ssbehera &rx_tx_ctrl_l.value)) != NXGE_OK) { 15585196Ssbehera goto fail; 15595196Ssbehera } 15605196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 15615196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 15625196Ssbehera &rx_tx_ctrl_h.value)) != NXGE_OK) { 15635196Ssbehera goto fail; 15645196Ssbehera } 15655196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 15665196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 15675196Ssbehera &glue_ctrl0_l.value)) != NXGE_OK) { 15685196Ssbehera goto fail; 15695196Ssbehera } 15705196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 15715196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 15725196Ssbehera &glue_ctrl0_h.value)) != NXGE_OK) { 15735196Ssbehera goto fail; 15745196Ssbehera } 15755196Ssbehera 15765196Ssbehera rx_tx_ctrl_l.bits.enstretch = 1; 15775196Ssbehera rx_tx_ctrl_h.bits.vmuxlo = 2; 15785196Ssbehera rx_tx_ctrl_h.bits.vpulselo = 2; 15795196Ssbehera glue_ctrl0_l.bits.rxlosenable = 1; 15805196Ssbehera glue_ctrl0_l.bits.samplerate = 0xF; 15815196Ssbehera glue_ctrl0_l.bits.thresholdcount = 0xFF; 15825196Ssbehera glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 15835196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 15845196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 15855196Ssbehera rx_tx_ctrl_l.value)) != NXGE_OK) { 15865196Ssbehera goto fail; 15875196Ssbehera } 15885196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 15895196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 15905196Ssbehera rx_tx_ctrl_h.value)) != NXGE_OK) { 15915196Ssbehera goto fail; 15925196Ssbehera } 15935196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 15945196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 15955196Ssbehera glue_ctrl0_l.value)) != NXGE_OK) { 15965196Ssbehera goto fail; 15975196Ssbehera } 15985196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 15995196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 16005196Ssbehera glue_ctrl0_h.value)) != NXGE_OK) { 16015196Ssbehera goto fail; 16025196Ssbehera } 16035196Ssbehera } 16045196Ssbehera 16055196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16065196Ssbehera ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) { 16074732Sdavemq goto fail; 16083859Sml29623 } 16095196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16105196Ssbehera ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 16115196Ssbehera goto fail; 16125196Ssbehera } 16135196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16145196Ssbehera ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) { 16155196Ssbehera goto fail; 16165196Ssbehera } 16175196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16185196Ssbehera ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 16195196Ssbehera goto fail; 16205196Ssbehera } 16215196Ssbehera 16225196Ssbehera /* Apply Tx core reset */ 16235196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16245196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) { 16255196Ssbehera goto fail; 16265196Ssbehera } 16275196Ssbehera 16285196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16295196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 16305196Ssbehera NXGE_OK) { 16315196Ssbehera goto fail; 16325196Ssbehera } 16335196Ssbehera 16345196Ssbehera NXGE_DELAY(200); 16355196Ssbehera 16365196Ssbehera /* Apply Rx core reset */ 16375196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16385196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 16395196Ssbehera NXGE_OK) { 16405196Ssbehera goto fail; 16415196Ssbehera } 16425196Ssbehera 16435196Ssbehera NXGE_DELAY(200); 16445196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16455196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) { 16465196Ssbehera goto fail; 16475196Ssbehera } 16485196Ssbehera 16495196Ssbehera NXGE_DELAY(200); 16505196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16515196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) { 16525196Ssbehera goto fail; 16535196Ssbehera } 16545196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 16555196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) { 16565196Ssbehera goto fail; 16575196Ssbehera } 16585196Ssbehera if ((val16l != 0) || (val16h != 0)) { 16595196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16605196Ssbehera "Failed to reset port<%d> XAUI Serdes " 16615196Ssbehera "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h)); 16625196Ssbehera status = NXGE_ERROR; 16635196Ssbehera goto fail; 16645196Ssbehera } 16655196Ssbehera 16665196Ssbehera NXGE_DELAY(200); 16675196Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 16685196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16695196Ssbehera "nxge_neptune_serdes_init: read internal signal reg port<%d> " 16705196Ssbehera "val 0x%x", portn, val)); 16715196Ssbehera if (portn == 0) { 16725196Ssbehera if ((val & ESR_SIG_P0_BITS_MASK_1G) != 16735196Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) { 16745196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16755196Ssbehera "nxge_neptune_serdes_init: " 16765196Ssbehera "Failed to get Serdes up for port<%d> val 0x%x", 16775196Ssbehera portn, (val & ESR_SIG_P0_BITS_MASK))); 16785196Ssbehera status = NXGE_ERROR; 16795196Ssbehera goto fail; 16805196Ssbehera } 16815196Ssbehera } else if (portn == 1) { 16825196Ssbehera if ((val & ESR_SIG_P1_BITS_MASK_1G) != 16835196Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) { 16845196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16855196Ssbehera "nxge_neptune_serdes_init: " 16865196Ssbehera "Failed to get Serdes up for port<%d> val 0x%x", 16875196Ssbehera portn, (val & ESR_SIG_P1_BITS_MASK))); 16885196Ssbehera status = NXGE_ERROR; 16895196Ssbehera goto fail; 16905196Ssbehera } 16915196Ssbehera } 16925196Ssbehera done: 16934732Sdavemq 16944732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16954732Sdavemq "<== nxge_1G_serdes_init port<%d>", portn)); 16963859Sml29623 return (NXGE_OK); 16974732Sdavemq fail: 16985196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16994732Sdavemq "nxge_1G_serdes_init: " 17004732Sdavemq "Failed to initialize Neptune serdes for port<%d>", 17014732Sdavemq portn)); 17024732Sdavemq 17035196Ssbehera return (status); 17043859Sml29623 } 17053859Sml29623 17064732Sdavemq /* Initialize the 10G (BCM8704) Transceiver */ 17074732Sdavemq 17084732Sdavemq static nxge_status_t 17094732Sdavemq nxge_10G_xcvr_init(p_nxge_t nxgep) 17103859Sml29623 { 17113859Sml29623 p_nxge_stats_t statsp; 17123859Sml29623 uint16_t val; 17133859Sml29623 #ifdef NXGE_DEBUG 17143859Sml29623 uint8_t portn; 17153859Sml29623 uint16_t val1; 17163859Sml29623 #endif 17173859Sml29623 uint8_t phy_port_addr; 17183859Sml29623 pmd_tx_control_t tx_ctl; 17193859Sml29623 control_t ctl; 17203859Sml29623 phyxs_control_t phyxs_ctl; 17213859Sml29623 pcs_control_t pcs_ctl; 17223859Sml29623 uint32_t delay = 0; 17233859Sml29623 optics_dcntr_t op_ctr; 17243859Sml29623 nxge_status_t status = NXGE_OK; 17253859Sml29623 #ifdef NXGE_DEBUG 17263859Sml29623 portn = nxgep->mac.portnum; 17273859Sml29623 #endif 17284732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 17294732Sdavemq portn)); 17304732Sdavemq 17314732Sdavemq statsp = nxgep->statsp; 17324732Sdavemq 17334977Sraghus if (nxgep->mac.portmode == PORT_10G_SERDES) { 17344977Sraghus goto done; 17354977Sraghus } 17364977Sraghus 17374732Sdavemq phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 17384732Sdavemq 17394732Sdavemq /* Disable Link LEDs */ 17404732Sdavemq if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 17414732Sdavemq goto fail; 17424732Sdavemq 17434732Sdavemq /* Set Clause 45 */ 17444732Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 17454732Sdavemq 17464732Sdavemq /* Reset the transceiver */ 17474732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 17484732Sdavemq BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 17494732Sdavemq goto fail; 17504732Sdavemq 17514732Sdavemq phyxs_ctl.bits.reset = 1; 17524732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 17534732Sdavemq BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 17544732Sdavemq goto fail; 17554732Sdavemq 17564732Sdavemq do { 17574732Sdavemq drv_usecwait(500); 17584732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 17594732Sdavemq BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 17604732Sdavemq &phyxs_ctl.value)) != NXGE_OK) 17614732Sdavemq goto fail; 17624732Sdavemq delay++; 17634732Sdavemq } while ((phyxs_ctl.bits.reset) && (delay < 100)); 17644732Sdavemq if (delay == 100) { 17654732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 17664732Sdavemq "failed to reset Transceiver on port<%d>", portn)); 17674732Sdavemq status = NXGE_ERROR; 17684732Sdavemq goto fail; 17694732Sdavemq } 17704732Sdavemq 17714732Sdavemq /* Set to 0x7FBF */ 17724732Sdavemq ctl.value = 0; 17734732Sdavemq ctl.bits.res1 = 0x3F; 17744732Sdavemq ctl.bits.optxon_lvl = 1; 17754732Sdavemq ctl.bits.oprxflt_lvl = 1; 17764732Sdavemq ctl.bits.optrxlos_lvl = 1; 17774732Sdavemq ctl.bits.optxflt_lvl = 1; 17784732Sdavemq ctl.bits.opprflt_lvl = 1; 17794732Sdavemq ctl.bits.obtmpflt_lvl = 1; 17804732Sdavemq ctl.bits.opbiasflt_lvl = 1; 17814732Sdavemq ctl.bits.optxrst_lvl = 1; 17824732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 17834732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value)) 17844732Sdavemq != NXGE_OK) 17854732Sdavemq goto fail; 17864732Sdavemq 17874732Sdavemq /* Set to 0x164 */ 17884732Sdavemq tx_ctl.value = 0; 17894732Sdavemq tx_ctl.bits.tsck_lpwren = 1; 17904732Sdavemq tx_ctl.bits.tx_dac_txck = 0x2; 17914732Sdavemq tx_ctl.bits.tx_dac_txd = 0x1; 17924732Sdavemq tx_ctl.bits.xfp_clken = 1; 17934732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 17944732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, 17954732Sdavemq tx_ctl.value)) != NXGE_OK) 17964732Sdavemq goto fail; 17974732Sdavemq /* 17984732Sdavemq * According to Broadcom's instruction, SW needs to read 17994732Sdavemq * back these registers twice after written. 18004732Sdavemq */ 18014732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 18024732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 18034732Sdavemq != NXGE_OK) 18044732Sdavemq goto fail; 18054732Sdavemq 18064732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 18074732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 18084732Sdavemq != NXGE_OK) 18094732Sdavemq goto fail; 18104732Sdavemq 18114732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 18124732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 18134732Sdavemq != NXGE_OK) 18144732Sdavemq goto fail; 18154732Sdavemq 18164732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 18174732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 18184732Sdavemq != NXGE_OK) 18194732Sdavemq goto fail; 18204732Sdavemq 18214732Sdavemq /* Enable Tx and Rx LEDs to be driven by traffic */ 18224732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 18234732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 18244732Sdavemq &op_ctr.value)) != NXGE_OK) 18254732Sdavemq goto fail; 1826*5553Smisaki if (NXGE_IS_XAUI_PLATFORM(nxgep)) { 1827*5553Smisaki op_ctr.bits.gpio_sel = 0x1; 1828*5553Smisaki } else { 1829*5553Smisaki op_ctr.bits.gpio_sel = 0x3; 1830*5553Smisaki } 18314732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 18324732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 18334732Sdavemq op_ctr.value)) != NXGE_OK) 18344732Sdavemq goto fail; 18354732Sdavemq 18364732Sdavemq NXGE_DELAY(1000000); 18374732Sdavemq 18384732Sdavemq /* Set BCM8704 Internal Loopback mode if necessary */ 18394732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 18404732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 18414732Sdavemq != NXGE_OK) 18424732Sdavemq goto fail; 18434732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 18444732Sdavemq pcs_ctl.bits.loopback = 1; 18454732Sdavemq else 18464732Sdavemq pcs_ctl.bits.loopback = 0; 18474732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 18484732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 18494732Sdavemq != NXGE_OK) 18504732Sdavemq goto fail; 18514732Sdavemq 18524732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val); 18534732Sdavemq if (status != NXGE_OK) 18544732Sdavemq goto fail; 18554732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18564732Sdavemq "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val)); 18574732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 18584732Sdavemq if (status != NXGE_OK) 18594732Sdavemq goto fail; 18604732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18614732Sdavemq "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val)); 18624732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 18634732Sdavemq if (status != NXGE_OK) 18644732Sdavemq goto fail; 18654732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18664732Sdavemq "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val)); 18674732Sdavemq 18684732Sdavemq #ifdef NXGE_DEBUG 18694732Sdavemq /* Diagnose link issue if link is not up */ 18704732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR, 18714732Sdavemq BCM8704_USER_ANALOG_STATUS0_REG, 18724732Sdavemq &val); 18734732Sdavemq if (status != NXGE_OK) 18744732Sdavemq goto fail; 18754732Sdavemq 18764732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 18774732Sdavemq BCM8704_USER_DEV3_ADDR, 18784732Sdavemq BCM8704_USER_ANALOG_STATUS0_REG, 18794732Sdavemq &val); 18804732Sdavemq if (status != NXGE_OK) 18814732Sdavemq goto fail; 18824732Sdavemq 18834732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 18844732Sdavemq BCM8704_USER_DEV3_ADDR, 18854732Sdavemq BCM8704_USER_TX_ALARM_STATUS_REG, 18864732Sdavemq &val1); 18874732Sdavemq if (status != NXGE_OK) 18884732Sdavemq goto fail; 18894732Sdavemq 18904732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 18914732Sdavemq BCM8704_USER_DEV3_ADDR, 18924732Sdavemq BCM8704_USER_TX_ALARM_STATUS_REG, 18934732Sdavemq &val1); 18944732Sdavemq if (status != NXGE_OK) 18954732Sdavemq goto fail; 18964732Sdavemq 18974732Sdavemq if (val != 0x3FC) { 18984732Sdavemq if ((val == 0x43BC) && (val1 != 0)) { 18994732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19004732Sdavemq "Cable not connected to peer or bad" 19014732Sdavemq " cable on port<%d>\n", portn)); 19024732Sdavemq } else if (val == 0x639C) { 19034732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19044732Sdavemq "Optical module (XFP) is bad or absent" 19054732Sdavemq " on port<%d>\n", portn)); 19064732Sdavemq } 19074732Sdavemq } 19084732Sdavemq #endif 19094732Sdavemq 19104977Sraghus done: 19114732Sdavemq statsp->mac_stats.cap_10gfdx = 1; 19124732Sdavemq statsp->mac_stats.lp_cap_10gfdx = 1; 19134732Sdavemq 19144732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 19154732Sdavemq portn)); 19164732Sdavemq return (NXGE_OK); 19174732Sdavemq 19184732Sdavemq fail: 19194732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19204732Sdavemq "nxge_10G_xcvr_init: failed to initialize transceiver for " 19214732Sdavemq "port<%d>", portn)); 19224732Sdavemq return (status); 19234732Sdavemq } 19244732Sdavemq 19254732Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */ 19264732Sdavemq 19274732Sdavemq static nxge_status_t 19284732Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep) 19294732Sdavemq { 19304732Sdavemq p_nxge_param_t param_arr = nxgep->param_arr; 19314732Sdavemq p_nxge_stats_t statsp = nxgep->statsp; 19324732Sdavemq nxge_status_t status = NXGE_OK; 19334732Sdavemq 19344977Sraghus if (nxgep->mac.portmode == PORT_1G_SERDES) { 19354977Sraghus statsp->mac_stats.cap_1000fdx = 19364977Sraghus param_arr[param_anar_1000fdx].value; 19374977Sraghus goto done; 19384977Sraghus } 19394977Sraghus 19404732Sdavemq /* Set Clause 22 */ 19414732Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 19424732Sdavemq 19434732Sdavemq /* Set capability flags */ 19444732Sdavemq statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value; 19454977Sraghus if ((nxgep->mac.portmode == PORT_1G_COPPER) || 19464977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER)) { 19474977Sraghus statsp->mac_stats.cap_100fdx = 19484977Sraghus param_arr[param_anar_100fdx].value; 19494977Sraghus statsp->mac_stats.cap_10fdx = 19504977Sraghus param_arr[param_anar_10fdx].value; 19514977Sraghus } 19524732Sdavemq 19534732Sdavemq status = nxge_mii_xcvr_init(nxgep); 19544977Sraghus done: 19554732Sdavemq return (status); 19564732Sdavemq } 19574732Sdavemq 19584732Sdavemq /* Initialize transceiver */ 19594732Sdavemq 19604732Sdavemq nxge_status_t 19614732Sdavemq nxge_xcvr_init(p_nxge_t nxgep) 19624732Sdavemq { 19634732Sdavemq p_nxge_stats_t statsp; 19644732Sdavemq #ifdef NXGE_DEBUG 19654732Sdavemq uint8_t portn; 19664732Sdavemq #endif 19674732Sdavemq 19684732Sdavemq nxge_status_t status = NXGE_OK; 19694732Sdavemq #ifdef NXGE_DEBUG 19704732Sdavemq portn = nxgep->mac.portnum; 19714732Sdavemq #endif 19723859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 19733859Sml29623 statsp = nxgep->statsp; 19743859Sml29623 19753859Sml29623 /* 19763859Sml29623 * Initialize the xcvr statistics. 19773859Sml29623 */ 19783859Sml29623 statsp->mac_stats.cap_autoneg = 0; 19793859Sml29623 statsp->mac_stats.cap_100T4 = 0; 19803859Sml29623 statsp->mac_stats.cap_100fdx = 0; 19813859Sml29623 statsp->mac_stats.cap_100hdx = 0; 19823859Sml29623 statsp->mac_stats.cap_10fdx = 0; 19833859Sml29623 statsp->mac_stats.cap_10hdx = 0; 19843859Sml29623 statsp->mac_stats.cap_asmpause = 0; 19853859Sml29623 statsp->mac_stats.cap_pause = 0; 19863859Sml29623 statsp->mac_stats.cap_1000fdx = 0; 19873859Sml29623 statsp->mac_stats.cap_1000hdx = 0; 19883859Sml29623 statsp->mac_stats.cap_10gfdx = 0; 19893859Sml29623 statsp->mac_stats.cap_10ghdx = 0; 19903859Sml29623 19913859Sml29623 /* 19923859Sml29623 * Initialize the link statistics. 19933859Sml29623 */ 19943859Sml29623 statsp->mac_stats.link_T4 = 0; 19953859Sml29623 statsp->mac_stats.link_asmpause = 0; 19963859Sml29623 statsp->mac_stats.link_pause = 0; 19973859Sml29623 19984732Sdavemq if (nxgep->xcvr.xcvr_init) { 19994732Sdavemq status = nxgep->xcvr.xcvr_init(nxgep); 20003859Sml29623 if (status != NXGE_OK) 20013859Sml29623 goto fail; 20024732Sdavemq statsp->mac_stats.xcvr_inits++; 20033859Sml29623 } 20043859Sml29623 20054732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", 20064732Sdavemq portn)); 20073859Sml29623 return (NXGE_OK); 20083859Sml29623 20093859Sml29623 fail: 20103859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 20114732Sdavemq "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 20124732Sdavemq portn)); 20133859Sml29623 return (status); 20143859Sml29623 } 20153859Sml29623 20164977Sraghus /* Look for transceiver type */ 20174977Sraghus 20184977Sraghus nxge_status_t 20194977Sraghus nxge_xcvr_find(p_nxge_t nxgep) 20204977Sraghus { 20215196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", 20225196Ssbehera nxgep->mac.portnum)); 20234977Sraghus 20244977Sraghus if (nxge_get_xcvr_type(nxgep) != NXGE_OK) 20254977Sraghus return (NXGE_ERROR); 20264977Sraghus 20274977Sraghus if (nxge_setup_xcvr_table(nxgep) != NXGE_OK) 20284977Sraghus return (NXGE_ERROR); 20294977Sraghus 20304977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d", 20314977Sraghus nxgep->statsp->mac_stats.xcvr_inuse)); 20324977Sraghus return (NXGE_OK); 20334977Sraghus } 20343859Sml29623 20353859Sml29623 /* Initialize the TxMAC sub-block */ 20363859Sml29623 20373859Sml29623 nxge_status_t 20383859Sml29623 nxge_tx_mac_init(p_nxge_t nxgep) 20393859Sml29623 { 20403859Sml29623 npi_attr_t ap; 20413859Sml29623 uint8_t portn; 20423859Sml29623 nxge_port_mode_t portmode; 20433859Sml29623 nxge_port_t portt; 20443859Sml29623 npi_handle_t handle; 20453859Sml29623 npi_status_t rs = NPI_SUCCESS; 20463859Sml29623 20473859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 20483859Sml29623 portt = nxgep->mac.porttype; 20493859Sml29623 handle = nxgep->npi_handle; 20503859Sml29623 portmode = nxgep->mac.portmode; 20513859Sml29623 20523859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 20533859Sml29623 portn)); 20543859Sml29623 20553859Sml29623 /* Set Max and Min Frame Size */ 20563859Sml29623 if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) { 20573859Sml29623 SET_MAC_ATTR2(handle, ap, portn, 20583859Sml29623 MAC_PORT_FRAME_SIZE, 64, 0x2400, rs); 20593859Sml29623 } else { 20605237Ssbehera /* Do not add CRC 4 bytes to the max or the min frame size */ 20613859Sml29623 SET_MAC_ATTR2(handle, ap, portn, 20625237Ssbehera MAC_PORT_FRAME_SIZE, 64, 0x5EE, rs); 20633859Sml29623 } 20643859Sml29623 20653859Sml29623 if (rs != NPI_SUCCESS) 20663859Sml29623 goto fail; 20673859Sml29623 if (nxgep->param_arr[param_accept_jumbo].value || 20683859Sml29623 nxgep->mac.is_jumbo == B_TRUE) 20693859Sml29623 nxgep->mac.maxframesize = 0x2400; 20703859Sml29623 else 20713859Sml29623 nxgep->mac.maxframesize = 0x5EE + 4; 20723859Sml29623 nxgep->mac.minframesize = 64; 20733859Sml29623 20743859Sml29623 if (portt == PORT_TYPE_XMAC) { 20753859Sml29623 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 20763859Sml29623 0)) != NPI_SUCCESS) 20773859Sml29623 goto fail; 20783859Sml29623 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 20793859Sml29623 if ((portmode == PORT_10G_FIBER) || 20804977Sraghus (portmode == PORT_10G_COPPER) || 20814977Sraghus (portmode == PORT_10G_SERDES)) { 20823859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 20833859Sml29623 XGMII_IPG_12_15, rs); 20843859Sml29623 if (rs != NPI_SUCCESS) 20853859Sml29623 goto fail; 20863859Sml29623 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 20873859Sml29623 } else { 20883859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 20893859Sml29623 MII_GMII_IPG_12, rs); 20903859Sml29623 if (rs != NPI_SUCCESS) 20913859Sml29623 goto fail; 20923859Sml29623 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 20933859Sml29623 } 20943859Sml29623 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 20953859Sml29623 CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 20963859Sml29623 goto fail; 20973859Sml29623 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 20983859Sml29623 nxgep->mac.maxburstsize = 0; /* not programmable */ 20993859Sml29623 nxgep->mac.ctrltype = 0; /* not programmable */ 21003859Sml29623 nxgep->mac.pa_size = 0; /* not programmable */ 21013859Sml29623 21023859Sml29623 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 21033859Sml29623 != NPI_SUCCESS) 21043859Sml29623 goto fail; 21053859Sml29623 21063859Sml29623 } else { 21073859Sml29623 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 21083859Sml29623 0)) != NPI_SUCCESS) 21093859Sml29623 goto fail; 21103859Sml29623 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 21113859Sml29623 21123859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 21133859Sml29623 rs); 21143859Sml29623 if (rs != NPI_SUCCESS) 21153859Sml29623 goto fail; 21163859Sml29623 nxgep->mac.ctrltype = 0x8808; 21173859Sml29623 21183859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 21193859Sml29623 if (rs != NPI_SUCCESS) 21203859Sml29623 goto fail; 21213859Sml29623 nxgep->mac.pa_size = 0x7; 21223859Sml29623 21233859Sml29623 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 21243859Sml29623 CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 21253859Sml29623 goto fail; 21263859Sml29623 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 21273859Sml29623 } 21283859Sml29623 21293859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 21303859Sml29623 portn)); 21313859Sml29623 21323859Sml29623 return (NXGE_OK); 21333859Sml29623 fail: 21343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 21353859Sml29623 "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", 21363859Sml29623 portn)); 21373859Sml29623 21383859Sml29623 return (NXGE_ERROR | rs); 21393859Sml29623 } 21403859Sml29623 21413859Sml29623 /* Initialize the RxMAC sub-block */ 21423859Sml29623 21433859Sml29623 nxge_status_t 21443859Sml29623 nxge_rx_mac_init(p_nxge_t nxgep) 21453859Sml29623 { 21463859Sml29623 npi_attr_t ap; 21473859Sml29623 uint32_t i; 21483859Sml29623 uint16_t hashtab_e; 21493859Sml29623 p_hash_filter_t hash_filter; 21503859Sml29623 nxge_port_t portt; 21513859Sml29623 uint8_t portn; 21523859Sml29623 npi_handle_t handle; 21533859Sml29623 npi_status_t rs = NPI_SUCCESS; 21543859Sml29623 uint16_t *addr16p; 21553859Sml29623 uint16_t addr0, addr1, addr2; 21563859Sml29623 xmac_rx_config_t xconfig; 21573859Sml29623 bmac_rx_config_t bconfig; 21583859Sml29623 21593859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 21603859Sml29623 21613859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 21623859Sml29623 portn)); 21633859Sml29623 handle = nxgep->npi_handle; 21643859Sml29623 portt = nxgep->mac.porttype; 21653859Sml29623 21663859Sml29623 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 21673859Sml29623 addr0 = ntohs(addr16p[2]); 21683859Sml29623 addr1 = ntohs(addr16p[1]); 21693859Sml29623 addr2 = ntohs(addr16p[0]); 21703859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 21713859Sml29623 rs); 21723859Sml29623 21733859Sml29623 if (rs != NPI_SUCCESS) 21743859Sml29623 goto fail; 21753859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 21763859Sml29623 if (rs != NPI_SUCCESS) 21773859Sml29623 goto fail; 21783859Sml29623 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 21793859Sml29623 if (rs != NPI_SUCCESS) 21803859Sml29623 goto fail; 21813859Sml29623 21823859Sml29623 /* 21833859Sml29623 * Load the multicast hash filter bits. 21843859Sml29623 */ 21853859Sml29623 hash_filter = nxgep->hash_filter; 21863859Sml29623 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 21873859Sml29623 if (hash_filter != NULL) { 21883859Sml29623 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 21893859Sml29623 (NMCFILTER_REGS - 1) - i]; 21903859Sml29623 } else { 21913859Sml29623 hashtab_e = 0; 21923859Sml29623 } 21933859Sml29623 21943859Sml29623 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 21953859Sml29623 (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 21963859Sml29623 goto fail; 21973859Sml29623 } 21983859Sml29623 21993859Sml29623 if (portt == PORT_TYPE_XMAC) { 22003859Sml29623 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 22013859Sml29623 0)) != NPI_SUCCESS) 22023859Sml29623 goto fail; 22033859Sml29623 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 22043859Sml29623 22053859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep); 22063859Sml29623 22073859Sml29623 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 22083859Sml29623 CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 22093859Sml29623 ~CFG_XMAC_RX_STRIP_CRC; 22103859Sml29623 22113859Sml29623 if (nxgep->filter.all_phys_cnt != 0) 22123859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 22133859Sml29623 22143859Sml29623 if (nxgep->filter.all_multicast_cnt != 0) 22153859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 22163859Sml29623 22173859Sml29623 xconfig |= CFG_XMAC_RX_HASH_FILTER; 22183859Sml29623 22193859Sml29623 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 22203859Sml29623 xconfig)) != NPI_SUCCESS) 22213859Sml29623 goto fail; 22223859Sml29623 nxgep->mac.rx_config = xconfig; 22233859Sml29623 22243859Sml29623 /* Comparison of mac unique address is always enabled on XMAC */ 22253859Sml29623 22263859Sml29623 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 22273859Sml29623 != NPI_SUCCESS) 22283859Sml29623 goto fail; 22293859Sml29623 } else { 22303859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep); 22313859Sml29623 22323859Sml29623 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 22333859Sml29623 0) != NPI_SUCCESS) 22343859Sml29623 goto fail; 22353859Sml29623 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 22363859Sml29623 22373859Sml29623 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 22383859Sml29623 ~CFG_BMAC_RX_STRIP_CRC; 22393859Sml29623 22403859Sml29623 if (nxgep->filter.all_phys_cnt != 0) 22413859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 22423859Sml29623 22433859Sml29623 if (nxgep->filter.all_multicast_cnt != 0) 22443859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 22453859Sml29623 22463859Sml29623 bconfig |= CFG_BMAC_RX_HASH_FILTER; 22473859Sml29623 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 22483859Sml29623 bconfig)) != NPI_SUCCESS) 22493859Sml29623 goto fail; 22503859Sml29623 nxgep->mac.rx_config = bconfig; 22513859Sml29623 22523859Sml29623 /* Always enable comparison of mac unique address */ 22533859Sml29623 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 22543859Sml29623 != NPI_SUCCESS) 22553859Sml29623 goto fail; 22563859Sml29623 } 22573859Sml29623 22583859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 22593859Sml29623 portn)); 22603859Sml29623 22613859Sml29623 return (NXGE_OK); 22623859Sml29623 22633859Sml29623 fail: 22643859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 22653859Sml29623 "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", 22663859Sml29623 portn)); 22673859Sml29623 22683859Sml29623 return (NXGE_ERROR | rs); 22693859Sml29623 } 22703859Sml29623 22713859Sml29623 /* Enable TXMAC */ 22723859Sml29623 22733859Sml29623 nxge_status_t 22743859Sml29623 nxge_tx_mac_enable(p_nxge_t nxgep) 22753859Sml29623 { 22763859Sml29623 npi_handle_t handle; 22773859Sml29623 npi_status_t rs = NPI_SUCCESS; 22783859Sml29623 nxge_status_t status = NXGE_OK; 22793859Sml29623 22803859Sml29623 handle = nxgep->npi_handle; 22813859Sml29623 22823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 22833859Sml29623 nxgep->mac.portnum)); 22843859Sml29623 22853859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 22863859Sml29623 goto fail; 22873859Sml29623 22883859Sml29623 /* based on speed */ 22893859Sml29623 nxgep->msg_min = ETHERMIN; 22903859Sml29623 22913859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 22923859Sml29623 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 22933859Sml29623 CFG_XMAC_TX)) != NPI_SUCCESS) 22943859Sml29623 goto fail; 22953859Sml29623 } else { 22963859Sml29623 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 22973859Sml29623 CFG_BMAC_TX)) != NPI_SUCCESS) 22983859Sml29623 goto fail; 22993859Sml29623 } 23003859Sml29623 23013859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 23023859Sml29623 nxgep->mac.portnum)); 23033859Sml29623 23043859Sml29623 return (NXGE_OK); 23053859Sml29623 fail: 23063859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23073859Sml29623 "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 23083859Sml29623 nxgep->mac.portnum)); 23093859Sml29623 if (rs != NPI_SUCCESS) 23103859Sml29623 return (NXGE_ERROR | rs); 23113859Sml29623 else 23123859Sml29623 return (status); 23133859Sml29623 } 23143859Sml29623 23153859Sml29623 /* Disable TXMAC */ 23163859Sml29623 23173859Sml29623 nxge_status_t 23183859Sml29623 nxge_tx_mac_disable(p_nxge_t nxgep) 23193859Sml29623 { 23203859Sml29623 npi_handle_t handle; 23213859Sml29623 npi_status_t rs = NPI_SUCCESS; 23223859Sml29623 23233859Sml29623 handle = nxgep->npi_handle; 23243859Sml29623 23253859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 23263859Sml29623 nxgep->mac.portnum)); 23273859Sml29623 23283859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 23293859Sml29623 if ((rs = npi_xmac_tx_config(handle, DISABLE, 23303859Sml29623 nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 23313859Sml29623 goto fail; 23323859Sml29623 } else { 23333859Sml29623 if ((rs = npi_bmac_tx_config(handle, DISABLE, 23343859Sml29623 nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 23353859Sml29623 goto fail; 23363859Sml29623 } 23373859Sml29623 23383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 23393859Sml29623 nxgep->mac.portnum)); 23403859Sml29623 return (NXGE_OK); 23413859Sml29623 fail: 23423859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23433859Sml29623 "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 23443859Sml29623 nxgep->mac.portnum)); 23453859Sml29623 return (NXGE_ERROR | rs); 23463859Sml29623 } 23473859Sml29623 23483859Sml29623 /* Enable RXMAC */ 23493859Sml29623 23503859Sml29623 nxge_status_t 23513859Sml29623 nxge_rx_mac_enable(p_nxge_t nxgep) 23523859Sml29623 { 23533859Sml29623 npi_handle_t handle; 23543859Sml29623 uint8_t portn; 23553859Sml29623 npi_status_t rs = NPI_SUCCESS; 23563859Sml29623 nxge_status_t status = NXGE_OK; 23573859Sml29623 23583859Sml29623 handle = nxgep->npi_handle; 23593859Sml29623 portn = nxgep->mac.portnum; 23603859Sml29623 23613859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 23623859Sml29623 portn)); 23633859Sml29623 23643859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 23653859Sml29623 goto fail; 23663859Sml29623 23673859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 23683859Sml29623 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 23693859Sml29623 CFG_XMAC_RX)) != NPI_SUCCESS) 23703859Sml29623 goto fail; 23713859Sml29623 } else { 23723859Sml29623 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 23733859Sml29623 CFG_BMAC_RX)) != NPI_SUCCESS) 23743859Sml29623 goto fail; 23753859Sml29623 } 23763859Sml29623 23773859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>", 23783859Sml29623 portn)); 23793859Sml29623 23803859Sml29623 return (NXGE_OK); 23813859Sml29623 fail: 23823859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23833859Sml29623 "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", 23843859Sml29623 portn)); 23853859Sml29623 23863859Sml29623 if (rs != NPI_SUCCESS) 23873859Sml29623 return (NXGE_ERROR | rs); 23883859Sml29623 else 23893859Sml29623 return (status); 23903859Sml29623 } 23913859Sml29623 23923859Sml29623 /* Disable RXMAC */ 23933859Sml29623 23943859Sml29623 nxge_status_t 23953859Sml29623 nxge_rx_mac_disable(p_nxge_t nxgep) 23963859Sml29623 { 23973859Sml29623 npi_handle_t handle; 23983859Sml29623 uint8_t portn; 23993859Sml29623 npi_status_t rs = NPI_SUCCESS; 24003859Sml29623 24013859Sml29623 handle = nxgep->npi_handle; 24023859Sml29623 portn = nxgep->mac.portnum; 24033859Sml29623 24043859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 24053859Sml29623 portn)); 24063859Sml29623 24073859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 24083859Sml29623 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 24093859Sml29623 CFG_XMAC_RX)) != NPI_SUCCESS) 24103859Sml29623 goto fail; 24113859Sml29623 } else { 24123859Sml29623 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 24133859Sml29623 CFG_BMAC_RX)) != NPI_SUCCESS) 24143859Sml29623 goto fail; 24153859Sml29623 } 24163859Sml29623 24173859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 24183859Sml29623 portn)); 24193859Sml29623 return (NXGE_OK); 24203859Sml29623 fail: 24213859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 24223859Sml29623 "nxgep_rx_mac_disable: ", 24233859Sml29623 "Failed to disable port<%d> RxMAC", 24243859Sml29623 portn)); 24253859Sml29623 24263859Sml29623 return (NXGE_ERROR | rs); 24273859Sml29623 } 24283859Sml29623 24293859Sml29623 /* Reset TXMAC */ 24303859Sml29623 24313859Sml29623 nxge_status_t 24323859Sml29623 nxge_tx_mac_reset(p_nxge_t nxgep) 24333859Sml29623 { 24343859Sml29623 npi_handle_t handle; 24353859Sml29623 uint8_t portn; 24363859Sml29623 npi_status_t rs = NPI_SUCCESS; 24373859Sml29623 24383859Sml29623 handle = nxgep->npi_handle; 24393859Sml29623 portn = nxgep->mac.portnum; 24403859Sml29623 24413859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 24423859Sml29623 portn)); 24433859Sml29623 24443859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 24453859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 24463859Sml29623 != NPI_SUCCESS) 24473859Sml29623 goto fail; 24483859Sml29623 } else { 24493859Sml29623 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 24503859Sml29623 != NPI_SUCCESS) 24513859Sml29623 goto fail; 24523859Sml29623 } 24533859Sml29623 24543859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 24553859Sml29623 portn)); 24563859Sml29623 24573859Sml29623 return (NXGE_OK); 24583859Sml29623 fail: 24593859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 24603859Sml29623 "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", 24613859Sml29623 portn)); 24623859Sml29623 24633859Sml29623 return (NXGE_ERROR | rs); 24643859Sml29623 } 24653859Sml29623 24663859Sml29623 /* Reset RXMAC */ 24673859Sml29623 24683859Sml29623 nxge_status_t 24693859Sml29623 nxge_rx_mac_reset(p_nxge_t nxgep) 24703859Sml29623 { 24713859Sml29623 npi_handle_t handle; 24723859Sml29623 uint8_t portn; 24733859Sml29623 npi_status_t rs = NPI_SUCCESS; 24743859Sml29623 24753859Sml29623 handle = nxgep->npi_handle; 24763859Sml29623 portn = nxgep->mac.portnum; 24773859Sml29623 24783859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 24793859Sml29623 portn)); 24803859Sml29623 24813859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 24823859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 24833859Sml29623 != NPI_SUCCESS) 24843859Sml29623 goto fail; 24853859Sml29623 } else { 24863859Sml29623 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 24873859Sml29623 != NPI_SUCCESS) 24883859Sml29623 goto fail; 24893859Sml29623 } 24903859Sml29623 24913859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 24923859Sml29623 portn)); 24933859Sml29623 24943859Sml29623 return (NXGE_OK); 24953859Sml29623 fail: 24963859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 24973859Sml29623 "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", 24983859Sml29623 portn)); 24993859Sml29623 return (NXGE_ERROR | rs); 25003859Sml29623 } 25013859Sml29623 25024732Sdavemq /* 10G fiber link interrupt start routine */ 25034732Sdavemq 25044732Sdavemq static nxge_status_t 25054732Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep) 25064732Sdavemq { 25074732Sdavemq npi_status_t rs = NPI_SUCCESS; 25084732Sdavemq uint8_t portn = nxgep->mac.portnum; 25094732Sdavemq 25104732Sdavemq rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 25114732Sdavemq 25124732Sdavemq if (rs != NPI_SUCCESS) 25134732Sdavemq return (NXGE_ERROR | rs); 25144732Sdavemq else 25154732Sdavemq return (NXGE_OK); 25164732Sdavemq } 25174732Sdavemq 25184732Sdavemq /* 10G fiber link interrupt stop routine */ 25194732Sdavemq 25204732Sdavemq static nxge_status_t 25214732Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep) 25224732Sdavemq { 25234732Sdavemq npi_status_t rs = NPI_SUCCESS; 25244732Sdavemq uint8_t portn = nxgep->mac.portnum; 25254732Sdavemq 25264732Sdavemq rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 25274732Sdavemq 25284732Sdavemq if (rs != NPI_SUCCESS) 25294732Sdavemq return (NXGE_ERROR | rs); 25304732Sdavemq else 25314732Sdavemq return (NXGE_OK); 25324732Sdavemq } 25334732Sdavemq 25344732Sdavemq /* 1G fiber link interrupt start routine */ 25354732Sdavemq 25364732Sdavemq static nxge_status_t 25374732Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 25384732Sdavemq { 25394732Sdavemq npi_status_t rs = NPI_SUCCESS; 25404732Sdavemq uint8_t portn = nxgep->mac.portnum; 25414732Sdavemq 25424732Sdavemq rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 25434732Sdavemq if (rs != NPI_SUCCESS) 25444732Sdavemq return (NXGE_ERROR | rs); 25454732Sdavemq else 25464732Sdavemq return (NXGE_OK); 25474732Sdavemq } 25484732Sdavemq 25494732Sdavemq /* 1G fiber link interrupt stop routine */ 25504732Sdavemq 25514732Sdavemq static nxge_status_t 25524732Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 25534732Sdavemq { 25544732Sdavemq npi_status_t rs = NPI_SUCCESS; 25554732Sdavemq uint8_t portn = nxgep->mac.portnum; 25564732Sdavemq 25574732Sdavemq rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 25584732Sdavemq 25594732Sdavemq if (rs != NPI_SUCCESS) 25604732Sdavemq return (NXGE_ERROR | rs); 25614732Sdavemq else 25624732Sdavemq return (NXGE_OK); 25634732Sdavemq } 25644732Sdavemq 25654732Sdavemq /* 1G copper link interrupt start routine */ 25664732Sdavemq 25674732Sdavemq static nxge_status_t 25684732Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 25694732Sdavemq { 25704732Sdavemq npi_status_t rs = NPI_SUCCESS; 25714732Sdavemq uint8_t portn = nxgep->mac.portnum; 25724732Sdavemq 25734732Sdavemq rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 25745203Ssbehera MII_STATUS, MII_STATUS_LINKUP); 25754732Sdavemq 25764732Sdavemq if (rs != NPI_SUCCESS) 25774732Sdavemq return (NXGE_ERROR | rs); 25784732Sdavemq else 25794732Sdavemq return (NXGE_OK); 25804732Sdavemq } 25814732Sdavemq 25824732Sdavemq /* 1G copper link interrupt stop routine */ 25834732Sdavemq 25844732Sdavemq static nxge_status_t 25854732Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 25864732Sdavemq { 25874732Sdavemq npi_status_t rs = NPI_SUCCESS; 25884732Sdavemq uint8_t portn = nxgep->mac.portnum; 25894732Sdavemq 25904732Sdavemq rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 25914732Sdavemq 25924732Sdavemq if (rs != NPI_SUCCESS) 25934732Sdavemq return (NXGE_ERROR | rs); 25944732Sdavemq else 25954732Sdavemq return (NXGE_OK); 25964732Sdavemq } 25974732Sdavemq 25984732Sdavemq /* Enable/Disable Link Status change interrupt */ 25993859Sml29623 26003859Sml29623 nxge_status_t 26013859Sml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 26023859Sml29623 { 26034732Sdavemq uint8_t portn; 26044732Sdavemq nxge_status_t status = NXGE_OK; 26053859Sml29623 26063859Sml29623 portn = nxgep->mac.portnum; 26073859Sml29623 26083859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 26094732Sdavemq if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 26104732Sdavemq return (NXGE_OK); 26114732Sdavemq 26124732Sdavemq if (enable == LINK_INTR_START) 26134732Sdavemq status = nxgep->xcvr.link_intr_start(nxgep); 26144732Sdavemq else if (enable == LINK_INTR_STOP) 26154732Sdavemq status = nxgep->xcvr.link_intr_stop(nxgep); 26164732Sdavemq if (status != NXGE_OK) 26174732Sdavemq goto fail; 26183859Sml29623 26193859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 26203859Sml29623 26213859Sml29623 return (NXGE_OK); 26223859Sml29623 fail: 26233859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 26243859Sml29623 "nxge_link_intr: Failed to set port<%d> mif intr mode", 26253859Sml29623 portn)); 26263859Sml29623 26274732Sdavemq return (status); 26283859Sml29623 } 26293859Sml29623 26303859Sml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 26313859Sml29623 26323859Sml29623 nxge_status_t 26333859Sml29623 nxge_mii_xcvr_init(p_nxge_t nxgep) 26343859Sml29623 { 26353859Sml29623 p_nxge_param_t param_arr; 26363859Sml29623 p_nxge_stats_t statsp; 26373859Sml29623 uint8_t xcvr_portn; 26383859Sml29623 p_mii_regs_t mii_regs; 26393859Sml29623 mii_bmcr_t bmcr; 26403859Sml29623 mii_bmsr_t bmsr; 26413859Sml29623 mii_anar_t anar; 26423859Sml29623 mii_gcr_t gcr; 26433859Sml29623 mii_esr_t esr; 26443859Sml29623 mii_aux_ctl_t bcm5464r_aux; 26453859Sml29623 int status = NXGE_OK; 26463859Sml29623 26473859Sml29623 uint_t delay; 26483859Sml29623 26493859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 26503859Sml29623 26513859Sml29623 param_arr = nxgep->param_arr; 26523859Sml29623 statsp = nxgep->statsp; 26533859Sml29623 xcvr_portn = statsp->mac_stats.xcvr_portn; 26543859Sml29623 26553859Sml29623 mii_regs = NULL; 26563859Sml29623 26573859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 26583859Sml29623 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 26593859Sml29623 26603859Sml29623 /* 26615196Ssbehera * The mif phy mode may be connected to either a copper link 26625196Ssbehera * or fiber link. Read the mode control register to get the fiber 26635196Ssbehera * configuration if it is hard-wired to fiber link. 26645196Ssbehera */ 26655196Ssbehera (void) nxge_mii_get_link_mode(nxgep); 26665196Ssbehera if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 26675196Ssbehera return (nxge_mii_xcvr_fiber_init(nxgep)); 26685196Ssbehera } 26695196Ssbehera 26705196Ssbehera /* 26713859Sml29623 * Reset the transceiver. 26723859Sml29623 */ 26733859Sml29623 delay = 0; 26743859Sml29623 bmcr.value = 0; 26753859Sml29623 bmcr.bits.reset = 1; 26763859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 26775125Sjoycey #if defined(__i386) 26785125Sjoycey (uint8_t)(uint32_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 26795125Sjoycey #else 26803859Sml29623 (uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 26815125Sjoycey #endif 26823859Sml29623 goto fail; 26833859Sml29623 do { 26843859Sml29623 drv_usecwait(500); 26853859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 26865125Sjoycey #if defined(__i386) 26875125Sjoycey (uint8_t)(uint32_t)&mii_regs->bmcr, &bmcr.value)) 26885125Sjoycey #else 26893859Sml29623 (uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value)) 26905125Sjoycey #endif 26913859Sml29623 != NXGE_OK) 26923859Sml29623 goto fail; 26933859Sml29623 delay++; 26943859Sml29623 } while ((bmcr.bits.reset) && (delay < 1000)); 26953859Sml29623 if (delay == 1000) { 26963859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 26973859Sml29623 goto fail; 26983859Sml29623 } 26993859Sml29623 27003859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 27015125Sjoycey #if defined(__i386) 27025125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 27035125Sjoycey #else 27043859Sml29623 (uint8_t)(uint64_t)(&mii_regs->bmsr), 27055125Sjoycey #endif 27063859Sml29623 &bmsr.value)) != NXGE_OK) 27073859Sml29623 goto fail; 27083859Sml29623 27093859Sml29623 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 27103859Sml29623 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 27113859Sml29623 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 27123859Sml29623 param_arr[param_anar_100hdx].value = 0; 27133859Sml29623 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 27143859Sml29623 param_arr[param_anar_10hdx].value = 0; 27153859Sml29623 27163859Sml29623 /* 27173859Sml29623 * Initialize the xcvr statistics. 27183859Sml29623 */ 27193859Sml29623 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 27203859Sml29623 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 27213859Sml29623 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 27223859Sml29623 statsp->mac_stats.cap_100hdx = 0; 27233859Sml29623 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 27243859Sml29623 statsp->mac_stats.cap_10hdx = 0; 27253859Sml29623 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 27263859Sml29623 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 27273859Sml29623 27283859Sml29623 /* 27293859Sml29623 * Initialise the xcvr advertised capability statistics. 27303859Sml29623 */ 27313859Sml29623 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 27323859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 27333859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 27343859Sml29623 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 27353859Sml29623 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 27363859Sml29623 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 27373859Sml29623 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 27383859Sml29623 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 27393859Sml29623 statsp->mac_stats.adv_cap_asmpause = 27403859Sml29623 param_arr[param_anar_asmpause].value; 27413859Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 27423859Sml29623 27433859Sml29623 27443859Sml29623 /* 27453859Sml29623 * Check for extended status just in case we're 27463859Sml29623 * running a Gigibit phy. 27473859Sml29623 */ 27483859Sml29623 if (bmsr.bits.extend_status) { 27493859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 27505125Sjoycey #if defined(__i386) 27515125Sjoycey (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) 27525125Sjoycey #else 27533859Sml29623 (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) 27545125Sjoycey #endif 27553859Sml29623 != NXGE_OK) 27563859Sml29623 goto fail; 27573859Sml29623 param_arr[param_anar_1000fdx].value &= 27583859Sml29623 esr.bits.link_1000fdx; 27593859Sml29623 param_arr[param_anar_1000hdx].value = 0; 27603859Sml29623 27613859Sml29623 statsp->mac_stats.cap_1000fdx = 27623859Sml29623 (esr.bits.link_1000Xfdx || 27633859Sml29623 esr.bits.link_1000fdx); 27643859Sml29623 statsp->mac_stats.cap_1000hdx = 0; 27653859Sml29623 } else { 27663859Sml29623 param_arr[param_anar_1000fdx].value = 0; 27673859Sml29623 param_arr[param_anar_1000hdx].value = 0; 27683859Sml29623 } 27693859Sml29623 27703859Sml29623 /* 27713859Sml29623 * Initialize 1G Statistics once the capability is established. 27723859Sml29623 */ 27733859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 27743859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 27753859Sml29623 27763859Sml29623 /* 27773859Sml29623 * Initialise the link statistics. 27783859Sml29623 */ 27793859Sml29623 statsp->mac_stats.link_T4 = 0; 27803859Sml29623 statsp->mac_stats.link_asmpause = 0; 27813859Sml29623 statsp->mac_stats.link_pause = 0; 27823859Sml29623 statsp->mac_stats.link_speed = 0; 27833859Sml29623 statsp->mac_stats.link_duplex = 0; 27843859Sml29623 statsp->mac_stats.link_up = 0; 27853859Sml29623 27863859Sml29623 /* 27873859Sml29623 * Switch off Auto-negotiation, 100M and full duplex. 27883859Sml29623 */ 27893859Sml29623 bmcr.value = 0; 27903859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 27915125Sjoycey #if defined(__i386) 27925125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 27935125Sjoycey #else 27943859Sml29623 (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 27955125Sjoycey #endif 27963859Sml29623 goto fail; 27973859Sml29623 27983859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 27993859Sml29623 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 28003859Sml29623 bmcr.bits.loopback = 1; 28013859Sml29623 bmcr.bits.enable_autoneg = 0; 28023859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 28033859Sml29623 bmcr.bits.speed_1000_sel = 1; 28043859Sml29623 bmcr.bits.duplex_mode = 1; 28053859Sml29623 param_arr[param_autoneg].value = 0; 28063859Sml29623 } else { 28073859Sml29623 bmcr.bits.loopback = 0; 28083859Sml29623 } 28093859Sml29623 28103859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 28113859Sml29623 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 28123859Sml29623 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 28133859Sml29623 param_arr[param_autoneg].value = 0; 28143859Sml29623 bcm5464r_aux.value = 0; 28153859Sml29623 bcm5464r_aux.bits.ext_lb = 1; 28163859Sml29623 bcm5464r_aux.bits.write_1 = 1; 28173859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 28183859Sml29623 BCM5464R_AUX_CTL, bcm5464r_aux.value)) 28193859Sml29623 != NXGE_OK) 28203859Sml29623 goto fail; 28213859Sml29623 } 28223859Sml29623 28233859Sml29623 if (param_arr[param_autoneg].value) { 28243859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 28253859Sml29623 "Restarting Auto-negotiation.")); 28263859Sml29623 /* 28273859Sml29623 * Setup our Auto-negotiation advertisement register. 28283859Sml29623 */ 28293859Sml29623 anar.value = 0; 28303859Sml29623 anar.bits.selector = 1; 28313859Sml29623 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 28323859Sml29623 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 28333859Sml29623 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 28343859Sml29623 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 28353859Sml29623 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 28363859Sml29623 anar.bits.cap_asmpause = 0; 28373859Sml29623 anar.bits.cap_pause = 0; 28383859Sml29623 if (param_arr[param_anar_1000fdx].value || 28393859Sml29623 param_arr[param_anar_100fdx].value || 28403859Sml29623 param_arr[param_anar_10fdx].value) { 28413859Sml29623 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 28423859Sml29623 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 28433859Sml29623 } 28443859Sml29623 28453859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 28465125Sjoycey #if defined(__i386) 28475125Sjoycey (uint8_t)(uint32_t)(&mii_regs->anar), anar.value)) 28485125Sjoycey #else 28493859Sml29623 (uint8_t)(uint64_t)(&mii_regs->anar), anar.value)) 28505125Sjoycey #endif 28513859Sml29623 != NXGE_OK) 28523859Sml29623 goto fail; 28533859Sml29623 if (bmsr.bits.extend_status) { 28543859Sml29623 gcr.value = 0; 28553859Sml29623 gcr.bits.ms_mode_en = 28563859Sml29623 param_arr[param_master_cfg_enable].value; 28573859Sml29623 gcr.bits.master = 28583859Sml29623 param_arr[param_master_cfg_value].value; 28593859Sml29623 gcr.bits.link_1000fdx = 28603859Sml29623 param_arr[param_anar_1000fdx].value; 28613859Sml29623 gcr.bits.link_1000hdx = 28623859Sml29623 param_arr[param_anar_1000hdx].value; 28633859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 28645125Sjoycey #if defined(__i386) 28655125Sjoycey (uint8_t)(uint32_t)(&mii_regs->gcr), gcr.value)) 28665125Sjoycey #else 28673859Sml29623 (uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value)) 28685125Sjoycey #endif 28693859Sml29623 != NXGE_OK) 28703859Sml29623 goto fail; 28713859Sml29623 } 28723859Sml29623 28733859Sml29623 bmcr.bits.enable_autoneg = 1; 28743859Sml29623 bmcr.bits.restart_autoneg = 1; 28753859Sml29623 28763859Sml29623 } else { 28773859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 28783859Sml29623 bmcr.bits.speed_1000_sel = 28793859Sml29623 param_arr[param_anar_1000fdx].value | 28803859Sml29623 param_arr[param_anar_1000hdx].value; 28813859Sml29623 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 28823859Sml29623 (param_arr[param_anar_100fdx].value | 28833859Sml29623 param_arr[param_anar_100hdx].value); 28843859Sml29623 if (bmcr.bits.speed_1000_sel) { 28853859Sml29623 statsp->mac_stats.link_speed = 1000; 28863859Sml29623 gcr.value = 0; 28873859Sml29623 gcr.bits.ms_mode_en = 28883859Sml29623 param_arr[param_master_cfg_enable].value; 28893859Sml29623 gcr.bits.master = 28903859Sml29623 param_arr[param_master_cfg_value].value; 28913859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 28925125Sjoycey #if defined(__i386) 28935125Sjoycey (uint8_t)(uint32_t)(&mii_regs->gcr), 28945125Sjoycey #else 28953859Sml29623 (uint8_t)(uint64_t)(&mii_regs->gcr), 28965125Sjoycey #endif 28973859Sml29623 gcr.value)) 28983859Sml29623 != NXGE_OK) 28993859Sml29623 goto fail; 29003859Sml29623 if (param_arr[param_anar_1000fdx].value) { 29013859Sml29623 bmcr.bits.duplex_mode = 1; 29023859Sml29623 statsp->mac_stats.link_duplex = 2; 29033859Sml29623 } else 29043859Sml29623 statsp->mac_stats.link_duplex = 1; 29053859Sml29623 } else if (bmcr.bits.speed_sel) { 29063859Sml29623 statsp->mac_stats.link_speed = 100; 29073859Sml29623 if (param_arr[param_anar_100fdx].value) { 29083859Sml29623 bmcr.bits.duplex_mode = 1; 29093859Sml29623 statsp->mac_stats.link_duplex = 2; 29103859Sml29623 } else 29113859Sml29623 statsp->mac_stats.link_duplex = 1; 29123859Sml29623 } else { 29133859Sml29623 statsp->mac_stats.link_speed = 10; 29143859Sml29623 if (param_arr[param_anar_10fdx].value) { 29153859Sml29623 bmcr.bits.duplex_mode = 1; 29163859Sml29623 statsp->mac_stats.link_duplex = 2; 29173859Sml29623 } else 29183859Sml29623 statsp->mac_stats.link_duplex = 1; 29193859Sml29623 } 29203859Sml29623 if (statsp->mac_stats.link_duplex != 1) { 29213859Sml29623 statsp->mac_stats.link_asmpause = 29223859Sml29623 statsp->mac_stats.cap_asmpause; 29233859Sml29623 statsp->mac_stats.link_pause = 29243859Sml29623 statsp->mac_stats.cap_pause; 29253859Sml29623 } 29263859Sml29623 29273859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 29283859Sml29623 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 29293859Sml29623 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 29303859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 29313859Sml29623 /* BCM5464R 1000mbps external loopback mode */ 29323859Sml29623 gcr.value = 0; 29333859Sml29623 gcr.bits.ms_mode_en = 1; 29343859Sml29623 gcr.bits.master = 1; 29353859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 29365125Sjoycey #if defined(__i386) 29375125Sjoycey (uint8_t)(uint32_t)(&mii_regs->gcr), 29385125Sjoycey #else 29393859Sml29623 (uint8_t)(uint64_t)(&mii_regs->gcr), 29405125Sjoycey #endif 29413859Sml29623 gcr.value)) 29423859Sml29623 != NXGE_OK) 29433859Sml29623 goto fail; 29443859Sml29623 bmcr.value = 0; 29453859Sml29623 bmcr.bits.speed_1000_sel = 1; 29463859Sml29623 statsp->mac_stats.link_speed = 1000; 29473859Sml29623 } else if (statsp->port_stats.lb_mode 29483859Sml29623 == nxge_lb_ext100) { 29493859Sml29623 /* BCM5464R 100mbps external loopback mode */ 29503859Sml29623 bmcr.value = 0; 29513859Sml29623 bmcr.bits.speed_sel = 1; 29523859Sml29623 bmcr.bits.duplex_mode = 1; 29533859Sml29623 statsp->mac_stats.link_speed = 100; 29543859Sml29623 } else if (statsp->port_stats.lb_mode 29553859Sml29623 == nxge_lb_ext10) { 29563859Sml29623 /* BCM5464R 10mbps external loopback mode */ 29573859Sml29623 bmcr.value = 0; 29583859Sml29623 bmcr.bits.duplex_mode = 1; 29593859Sml29623 statsp->mac_stats.link_speed = 10; 29603859Sml29623 } 29613859Sml29623 } 29623859Sml29623 } 29633859Sml29623 29643859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 29655125Sjoycey #if defined(__i386) 29665125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmcr), 29675125Sjoycey #else 29683859Sml29623 (uint8_t)(uint64_t)(&mii_regs->bmcr), 29695125Sjoycey #endif 29703859Sml29623 bmcr.value)) != NXGE_OK) 29713859Sml29623 goto fail; 29723859Sml29623 29733859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 29745125Sjoycey #if defined(__i386) 29755125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 29765125Sjoycey #else 29773859Sml29623 (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 29785125Sjoycey #endif 29793859Sml29623 goto fail; 29803859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 29813859Sml29623 29823859Sml29623 /* 29833859Sml29623 * Initialize the xcvr status kept in the context structure. 29843859Sml29623 */ 29853859Sml29623 nxgep->soft_bmsr.value = 0; 29863859Sml29623 29873859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 29885125Sjoycey #if defined(__i386) 29895125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 29905125Sjoycey #else 29913859Sml29623 (uint8_t)(uint64_t)(&mii_regs->bmsr), 29925125Sjoycey #endif 29933859Sml29623 &nxgep->bmsr.value)) != NXGE_OK) 29943859Sml29623 goto fail; 29953859Sml29623 29963859Sml29623 statsp->mac_stats.xcvr_inits++; 29973859Sml29623 nxgep->bmsr.value = 0; 29983859Sml29623 29993859Sml29623 fail: 30003859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 30013859Sml29623 "<== nxge_mii_xcvr_init status 0x%x", status)); 30023859Sml29623 return (status); 30033859Sml29623 } 30043859Sml29623 30055196Ssbehera nxge_status_t 30065196Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep) 30075196Ssbehera { 30085196Ssbehera p_nxge_param_t param_arr; 30095196Ssbehera p_nxge_stats_t statsp; 30105196Ssbehera uint8_t xcvr_portn; 30115196Ssbehera p_mii_regs_t mii_regs; 30125196Ssbehera mii_bmcr_t bmcr; 30135196Ssbehera mii_bmsr_t bmsr; 30145196Ssbehera mii_gcr_t gcr; 30155196Ssbehera mii_esr_t esr; 30165196Ssbehera mii_aux_ctl_t bcm5464r_aux; 30175196Ssbehera int status = NXGE_OK; 30185196Ssbehera 30195196Ssbehera uint_t delay; 30205196Ssbehera 30215196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init")); 30225196Ssbehera 30235196Ssbehera param_arr = nxgep->param_arr; 30245196Ssbehera statsp = nxgep->statsp; 30255196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 30265196Ssbehera 30275196Ssbehera mii_regs = NULL; 30285196Ssbehera 30295196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 30305196Ssbehera "nxge_mii_xcvr_fiber_init: " 30315196Ssbehera "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 30325196Ssbehera 30335196Ssbehera /* 30345196Ssbehera * Reset the transceiver. 30355196Ssbehera */ 30365196Ssbehera delay = 0; 30375196Ssbehera bmcr.value = 0; 30385196Ssbehera bmcr.bits.reset = 1; 30395196Ssbehera 30405196Ssbehera #if defined(__i386) 30415196Ssbehera 30425196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 30435196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 30445196Ssbehera goto fail; 30455196Ssbehera #else 30465196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 30475196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 30485196Ssbehera goto fail; 30495196Ssbehera #endif 30505196Ssbehera do { 30515196Ssbehera drv_usecwait(500); 30525196Ssbehera #if defined(__i386) 30535196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 30545196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) 30555196Ssbehera != NXGE_OK) 30565196Ssbehera goto fail; 30575196Ssbehera #else 30585196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 30595196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) 30605196Ssbehera != NXGE_OK) 30615196Ssbehera goto fail; 30625196Ssbehera #endif 30635196Ssbehera delay++; 30645196Ssbehera } while ((bmcr.bits.reset) && (delay < 1000)); 30655196Ssbehera if (delay == 1000) { 30665196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 30675196Ssbehera goto fail; 30685196Ssbehera } 30695196Ssbehera 30705196Ssbehera #if defined(__i386) 30715196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 30725196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 30735196Ssbehera goto fail; 30745196Ssbehera #else 30755196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 30765196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 30775196Ssbehera goto fail; 30785196Ssbehera #endif 30795196Ssbehera 30805196Ssbehera param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 30815196Ssbehera param_arr[param_anar_100T4].value = 0; 30825196Ssbehera param_arr[param_anar_100fdx].value = 0; 30835196Ssbehera param_arr[param_anar_100hdx].value = 0; 30845196Ssbehera param_arr[param_anar_10fdx].value = 0; 30855196Ssbehera param_arr[param_anar_10hdx].value = 0; 30865196Ssbehera 30875196Ssbehera /* 30885196Ssbehera * Initialize the xcvr statistics. 30895196Ssbehera */ 30905196Ssbehera statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 30915196Ssbehera statsp->mac_stats.cap_100T4 = 0; 30925196Ssbehera statsp->mac_stats.cap_100fdx = 0; 30935196Ssbehera statsp->mac_stats.cap_100hdx = 0; 30945196Ssbehera statsp->mac_stats.cap_10fdx = 0; 30955196Ssbehera statsp->mac_stats.cap_10hdx = 0; 30965196Ssbehera statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 30975196Ssbehera statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 30985196Ssbehera 30995196Ssbehera /* 31005196Ssbehera * Initialize the xcvr advertised capability statistics. 31015196Ssbehera */ 31025196Ssbehera statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 31035196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 31045196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 31055196Ssbehera statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 31065196Ssbehera statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 31075196Ssbehera statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 31085196Ssbehera statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 31095196Ssbehera statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 31105196Ssbehera statsp->mac_stats.adv_cap_asmpause = 31115196Ssbehera param_arr[param_anar_asmpause].value; 31125196Ssbehera statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 31135196Ssbehera 31145196Ssbehera /* 31155196Ssbehera * Check for extended status just in case we're 31165196Ssbehera * running a Gigibit phy. 31175196Ssbehera */ 31185196Ssbehera if (bmsr.bits.extend_status) { 31195196Ssbehera #if defined(__i386) 31205196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 31215196Ssbehera (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) != 31225196Ssbehera NXGE_OK) 31235196Ssbehera goto fail; 31245196Ssbehera #else 31255196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 31265196Ssbehera (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) != 31275196Ssbehera NXGE_OK) 31285196Ssbehera goto fail; 31295196Ssbehera #endif 31305196Ssbehera param_arr[param_anar_1000fdx].value &= 31315196Ssbehera esr.bits.link_1000fdx; 31325196Ssbehera param_arr[param_anar_1000hdx].value = 0; 31335196Ssbehera 31345196Ssbehera statsp->mac_stats.cap_1000fdx = 31355196Ssbehera (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 31365196Ssbehera statsp->mac_stats.cap_1000hdx = 0; 31375196Ssbehera } else { 31385196Ssbehera param_arr[param_anar_1000fdx].value = 0; 31395196Ssbehera param_arr[param_anar_1000hdx].value = 0; 31405196Ssbehera } 31415196Ssbehera 31425196Ssbehera /* 31435196Ssbehera * Initialize 1G Statistics once the capability is established. 31445196Ssbehera */ 31455196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 31465196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 31475196Ssbehera 31485196Ssbehera /* 31495196Ssbehera * Initialize the link statistics. 31505196Ssbehera */ 31515196Ssbehera statsp->mac_stats.link_T4 = 0; 31525196Ssbehera statsp->mac_stats.link_asmpause = 0; 31535196Ssbehera statsp->mac_stats.link_pause = 0; 31545196Ssbehera statsp->mac_stats.link_speed = 0; 31555196Ssbehera statsp->mac_stats.link_duplex = 0; 31565196Ssbehera statsp->mac_stats.link_up = 0; 31575196Ssbehera 31585196Ssbehera /* 31595196Ssbehera * Switch off Auto-negotiation, 100M and full duplex. 31605196Ssbehera */ 31615196Ssbehera bmcr.value = 0; 31625196Ssbehera #if defined(__i386) 31635196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 31645196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 31655196Ssbehera goto fail; 31665196Ssbehera #else 31675196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 31685196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 31695196Ssbehera goto fail; 31705196Ssbehera #endif 31715196Ssbehera 31725196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 31735196Ssbehera (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 31745196Ssbehera bmcr.bits.loopback = 1; 31755196Ssbehera bmcr.bits.enable_autoneg = 0; 31765196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 31775196Ssbehera bmcr.bits.speed_1000_sel = 1; 31785196Ssbehera bmcr.bits.duplex_mode = 1; 31795196Ssbehera param_arr[param_autoneg].value = 0; 31805196Ssbehera } else { 31815196Ssbehera bmcr.bits.loopback = 0; 31825196Ssbehera } 31835196Ssbehera 31845196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 31855196Ssbehera param_arr[param_autoneg].value = 0; 31865196Ssbehera bcm5464r_aux.value = 0; 31875196Ssbehera bcm5464r_aux.bits.ext_lb = 1; 31885196Ssbehera bcm5464r_aux.bits.write_1 = 1; 31895196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 31905196Ssbehera BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 31915196Ssbehera goto fail; 31925196Ssbehera } 31935196Ssbehera 31945196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 31955196Ssbehera bmcr.bits.speed_1000_sel = 1; 31965196Ssbehera bmcr.bits.speed_sel = 0; 31975196Ssbehera bmcr.bits.duplex_mode = 1; 31985196Ssbehera statsp->mac_stats.link_speed = 1000; 31995196Ssbehera statsp->mac_stats.link_duplex = 2; 32005196Ssbehera 32015196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) { 32025196Ssbehera /* BCM5464R 1000mbps external loopback mode */ 32035196Ssbehera gcr.value = 0; 32045196Ssbehera gcr.bits.ms_mode_en = 1; 32055196Ssbehera gcr.bits.master = 1; 32065196Ssbehera #if defined(__i386) 32075196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 32085196Ssbehera (uint8_t)(uint32_t)(&mii_regs->gcr), 32095196Ssbehera gcr.value)) != NXGE_OK) 32105196Ssbehera goto fail; 32115196Ssbehera #else 32125196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 32135196Ssbehera (uint8_t)(uint64_t)(&mii_regs->gcr), 32145196Ssbehera gcr.value)) != NXGE_OK) 32155196Ssbehera goto fail; 32165196Ssbehera #endif 32175196Ssbehera bmcr.value = 0; 32185196Ssbehera bmcr.bits.speed_1000_sel = 1; 32195196Ssbehera statsp->mac_stats.link_speed = 1000; 32205196Ssbehera } 32215196Ssbehera 32225196Ssbehera #if defined(__i386) 32235196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 32245196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), 32255196Ssbehera bmcr.value)) != NXGE_OK) 32265196Ssbehera goto fail; 32275196Ssbehera #else 32285196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 32295196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), 32305196Ssbehera bmcr.value)) != NXGE_OK) 32315196Ssbehera goto fail; 32325196Ssbehera #endif 32335196Ssbehera 32345196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 32355196Ssbehera "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x", 32365196Ssbehera bmcr.value)); 32375196Ssbehera 32385196Ssbehera #if defined(__i386) 32395196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 32405196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 32415196Ssbehera goto fail; 32425196Ssbehera #else 32435196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 32445196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 32455196Ssbehera goto fail; 32465196Ssbehera #endif 32475196Ssbehera 32485196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 32495196Ssbehera "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value)); 32505196Ssbehera 32515196Ssbehera /* 32525196Ssbehera * Initialize the xcvr status kept in the context structure. 32535196Ssbehera */ 32545196Ssbehera nxgep->soft_bmsr.value = 0; 32555196Ssbehera #if defined(__i386) 32565196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 32575196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), 32585196Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 32595196Ssbehera goto fail; 32605196Ssbehera #else 32615196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 32625196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), 32635196Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 32645196Ssbehera goto fail; 32655196Ssbehera #endif 32665196Ssbehera 32675196Ssbehera statsp->mac_stats.xcvr_inits++; 32685196Ssbehera nxgep->bmsr.value = 0; 32695196Ssbehera 32705196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 32715196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 32725196Ssbehera return (status); 32735196Ssbehera 32745196Ssbehera fail: 32755196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 32765196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 32775196Ssbehera return (status); 32785196Ssbehera } 32795196Ssbehera 32803859Sml29623 /* Read from a MII compliant register */ 32813859Sml29623 32823859Sml29623 nxge_status_t 32833859Sml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 32843859Sml29623 uint16_t *value) 32853859Sml29623 { 32863859Sml29623 npi_status_t rs = NPI_SUCCESS; 32873859Sml29623 32883859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 32893859Sml29623 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 32903859Sml29623 32913859Sml29623 MUTEX_ENTER(&nxge_mii_lock); 32923859Sml29623 32935196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 32945196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 32953859Sml29623 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 32963859Sml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 32973859Sml29623 goto fail; 32984977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 32994977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 33003859Sml29623 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 33013859Sml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 33023859Sml29623 goto fail; 33033859Sml29623 } else 33043859Sml29623 goto fail; 33053859Sml29623 33063859Sml29623 MUTEX_EXIT(&nxge_mii_lock); 33073859Sml29623 33083859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 33093859Sml29623 "xcvr_reg<%d> value=0x%x", 33103859Sml29623 xcvr_portn, xcvr_reg, *value)); 33113859Sml29623 return (NXGE_OK); 33123859Sml29623 fail: 33133859Sml29623 MUTEX_EXIT(&nxge_mii_lock); 33143859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33153859Sml29623 "nxge_mii_read: Failed to read mii on xcvr %d", 33163859Sml29623 xcvr_portn)); 33173859Sml29623 33183859Sml29623 return (NXGE_ERROR | rs); 33193859Sml29623 } 33203859Sml29623 33213859Sml29623 /* Write to a MII compliant Register */ 33223859Sml29623 33233859Sml29623 nxge_status_t 33243859Sml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 33253859Sml29623 uint16_t value) 33263859Sml29623 { 33273859Sml29623 npi_status_t rs = NPI_SUCCESS; 33283859Sml29623 33293859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 33303859Sml29623 "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, 33313859Sml29623 value)); 33323859Sml29623 33333859Sml29623 MUTEX_ENTER(&nxge_mii_lock); 33343859Sml29623 33355196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 33365196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 33373859Sml29623 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 33383859Sml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 33393859Sml29623 goto fail; 33404977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 33414977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 33423859Sml29623 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 33433859Sml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 33443859Sml29623 goto fail; 33453859Sml29623 } else 33463859Sml29623 goto fail; 33473859Sml29623 33483859Sml29623 MUTEX_EXIT(&nxge_mii_lock); 33493859Sml29623 33503859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 33513859Sml29623 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 33523859Sml29623 return (NXGE_OK); 33533859Sml29623 fail: 33543859Sml29623 MUTEX_EXIT(&nxge_mii_lock); 33553859Sml29623 33563859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33573859Sml29623 "nxge_mii_write: Failed to write mii on xcvr %d", 33583859Sml29623 xcvr_portn)); 33593859Sml29623 33603859Sml29623 return (NXGE_ERROR | rs); 33613859Sml29623 } 33623859Sml29623 33633859Sml29623 /* Perform read from Clause45 serdes / transceiver device */ 33643859Sml29623 33653859Sml29623 nxge_status_t 33663859Sml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 33673859Sml29623 uint16_t xcvr_reg, uint16_t *value) 33683859Sml29623 { 33693859Sml29623 npi_status_t rs = NPI_SUCCESS; 33703859Sml29623 33713859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 33723859Sml29623 xcvr_portn)); 33733859Sml29623 33743859Sml29623 MUTEX_ENTER(&nxge_mdio_lock); 33753859Sml29623 33763859Sml29623 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 33773859Sml29623 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 33783859Sml29623 goto fail; 33793859Sml29623 33803859Sml29623 MUTEX_EXIT(&nxge_mdio_lock); 33813859Sml29623 33823859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 33833859Sml29623 xcvr_portn)); 33843859Sml29623 return (NXGE_OK); 33853859Sml29623 fail: 33863859Sml29623 MUTEX_EXIT(&nxge_mdio_lock); 33873859Sml29623 33883859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33893859Sml29623 "nxge_mdio_read: Failed to read mdio on xcvr %d", 33903859Sml29623 xcvr_portn)); 33913859Sml29623 33923859Sml29623 return (NXGE_ERROR | rs); 33933859Sml29623 } 33943859Sml29623 33953859Sml29623 /* Perform write to Clause45 serdes / transceiver device */ 33963859Sml29623 33973859Sml29623 nxge_status_t 33983859Sml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 33993859Sml29623 uint16_t xcvr_reg, uint16_t value) 34003859Sml29623 { 34013859Sml29623 npi_status_t rs = NPI_SUCCESS; 34023859Sml29623 34033859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 34043859Sml29623 xcvr_portn)); 34053859Sml29623 34063859Sml29623 MUTEX_ENTER(&nxge_mdio_lock); 34073859Sml29623 34083859Sml29623 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 34093859Sml29623 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 34103859Sml29623 goto fail; 34113859Sml29623 34123859Sml29623 MUTEX_EXIT(&nxge_mdio_lock); 34133859Sml29623 34143859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 34153859Sml29623 xcvr_portn)); 34163859Sml29623 return (NXGE_OK); 34173859Sml29623 fail: 34183859Sml29623 MUTEX_EXIT(&nxge_mdio_lock); 34193859Sml29623 34203859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 34213859Sml29623 "nxge_mdio_write: Failed to write mdio on xcvr %d", 34223859Sml29623 xcvr_portn)); 34233859Sml29623 34243859Sml29623 return (NXGE_ERROR | rs); 34253859Sml29623 } 34263859Sml29623 34273859Sml29623 34283859Sml29623 /* Check MII to see if there is any link status change */ 34293859Sml29623 34303859Sml29623 nxge_status_t 34313859Sml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 34323859Sml29623 nxge_link_state_t *link_up) 34333859Sml29623 { 34343859Sml29623 p_nxge_param_t param_arr; 34353859Sml29623 p_nxge_stats_t statsp; 34363859Sml29623 p_mii_regs_t mii_regs; 34373859Sml29623 p_mii_bmsr_t soft_bmsr; 34383859Sml29623 mii_anar_t anar; 34393859Sml29623 mii_anlpar_t anlpar; 34403859Sml29623 mii_anar_t an_common; 34413859Sml29623 mii_aner_t aner; 34423859Sml29623 mii_gsr_t gsr; 34433859Sml29623 nxge_status_t status = NXGE_OK; 34443859Sml29623 34453859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 34463859Sml29623 34473859Sml29623 mii_regs = NULL; 34483859Sml29623 param_arr = nxgep->param_arr; 34493859Sml29623 statsp = nxgep->statsp; 34503859Sml29623 soft_bmsr = &nxgep->soft_bmsr; 34513859Sml29623 *link_up = LINK_NO_CHANGE; 34523859Sml29623 34535196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 34545196Ssbehera "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x", 34555196Ssbehera bmsr.value, bmsr_ints.value)); 34565196Ssbehera 34573859Sml29623 if (bmsr_ints.bits.link_status) { 34585196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 34595196Ssbehera "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x", 34605196Ssbehera bmsr.value, bmsr_ints.value)); 34613859Sml29623 if (bmsr.bits.link_status) { 34623859Sml29623 soft_bmsr->bits.link_status = 1; 34635196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 34645196Ssbehera "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int " 34655196Ssbehera "0x%x", bmsr.value, bmsr_ints.value)); 34663859Sml29623 } else { 34673859Sml29623 statsp->mac_stats.link_up = 0; 34683859Sml29623 soft_bmsr->bits.link_status = 0; 34693859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 34703859Sml29623 "Link down cable problem")); 34713859Sml29623 *link_up = LINK_IS_DOWN; 34723859Sml29623 } 34733859Sml29623 } 34743859Sml29623 34755196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 34765196Ssbehera param_arr[param_autoneg].value) { 34773859Sml29623 if (bmsr_ints.bits.auto_neg_complete) { 34783859Sml29623 if (bmsr.bits.auto_neg_complete) 34793859Sml29623 soft_bmsr->bits.auto_neg_complete = 1; 34803859Sml29623 else 34813859Sml29623 soft_bmsr->bits.auto_neg_complete = 0; 34823859Sml29623 } 34833859Sml29623 if (soft_bmsr->bits.link_status == 0) { 34843859Sml29623 statsp->mac_stats.link_T4 = 0; 34853859Sml29623 statsp->mac_stats.link_speed = 0; 34863859Sml29623 statsp->mac_stats.link_duplex = 0; 34873859Sml29623 statsp->mac_stats.link_asmpause = 0; 34883859Sml29623 statsp->mac_stats.link_pause = 0; 34893859Sml29623 statsp->mac_stats.lp_cap_autoneg = 0; 34903859Sml29623 statsp->mac_stats.lp_cap_100T4 = 0; 34913859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 0; 34923859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 0; 34933859Sml29623 statsp->mac_stats.lp_cap_100fdx = 0; 34943859Sml29623 statsp->mac_stats.lp_cap_100hdx = 0; 34953859Sml29623 statsp->mac_stats.lp_cap_10fdx = 0; 34963859Sml29623 statsp->mac_stats.lp_cap_10hdx = 0; 34973859Sml29623 statsp->mac_stats.lp_cap_10gfdx = 0; 34983859Sml29623 statsp->mac_stats.lp_cap_10ghdx = 0; 34993859Sml29623 statsp->mac_stats.lp_cap_asmpause = 0; 35003859Sml29623 statsp->mac_stats.lp_cap_pause = 0; 35013859Sml29623 } 35023859Sml29623 } else 35033859Sml29623 soft_bmsr->bits.auto_neg_complete = 1; 35043859Sml29623 35053859Sml29623 if ((bmsr_ints.bits.link_status || 35063859Sml29623 bmsr_ints.bits.auto_neg_complete) && 35073859Sml29623 soft_bmsr->bits.link_status && 35083859Sml29623 soft_bmsr->bits.auto_neg_complete) { 35093859Sml29623 statsp->mac_stats.link_up = 1; 35105196Ssbehera 35115196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 35125196Ssbehera "==> nxge_mii_check " 35135196Ssbehera "(auto negotiation complete or link up) " 35145196Ssbehera "soft bmsr 0x%x bmsr_int 0x%x", 35155196Ssbehera bmsr.value, bmsr_ints.value)); 35165196Ssbehera 35175196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 35185196Ssbehera param_arr[param_autoneg].value) { 35193859Sml29623 if ((status = nxge_mii_read(nxgep, 35203859Sml29623 statsp->mac_stats.xcvr_portn, 35215125Sjoycey #if defined(__i386) 35225125Sjoycey (uint8_t)(uint32_t)(&mii_regs->anar), 35235125Sjoycey #else 35243859Sml29623 (uint8_t)(uint64_t)(&mii_regs->anar), 35255125Sjoycey #endif 35263859Sml29623 &anar.value)) != NXGE_OK) 35273859Sml29623 goto fail; 35283859Sml29623 if ((status = nxge_mii_read(nxgep, 35293859Sml29623 statsp->mac_stats.xcvr_portn, 35305125Sjoycey #if defined(__i386) 35315125Sjoycey (uint8_t)(uint32_t)(&mii_regs->anlpar), 35325125Sjoycey #else 35333859Sml29623 (uint8_t)(uint64_t)(&mii_regs->anlpar), 35345125Sjoycey #endif 35353859Sml29623 &anlpar.value)) != NXGE_OK) 35363859Sml29623 goto fail; 35373859Sml29623 if ((status = nxge_mii_read(nxgep, 35383859Sml29623 statsp->mac_stats.xcvr_portn, 35395125Sjoycey #if defined(__i386) 35405125Sjoycey (uint8_t)(uint32_t)(&mii_regs->aner), 35415125Sjoycey #else 35423859Sml29623 (uint8_t)(uint64_t)(&mii_regs->aner), 35435125Sjoycey #endif 35443859Sml29623 &aner.value)) != NXGE_OK) 35453859Sml29623 goto fail; 35463859Sml29623 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 35473859Sml29623 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 35483859Sml29623 statsp->mac_stats.lp_cap_100fdx = 35493859Sml29623 anlpar.bits.cap_100fdx; 35503859Sml29623 statsp->mac_stats.lp_cap_100hdx = 35513859Sml29623 anlpar.bits.cap_100hdx; 35523859Sml29623 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 35533859Sml29623 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 35543859Sml29623 statsp->mac_stats.lp_cap_asmpause = 35553859Sml29623 anlpar.bits.cap_asmpause; 35563859Sml29623 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 35573859Sml29623 an_common.value = anar.value & anlpar.value; 35583859Sml29623 if (param_arr[param_anar_1000fdx].value || 35593859Sml29623 param_arr[param_anar_1000hdx].value) { 35603859Sml29623 if ((status = nxge_mii_read(nxgep, 35613859Sml29623 statsp->mac_stats.xcvr_portn, 35625125Sjoycey #if defined(__i386) 35635125Sjoycey (uint8_t)(uint32_t)(&mii_regs->gsr), 35645125Sjoycey #else 35653859Sml29623 (uint8_t)(uint64_t)(&mii_regs->gsr), 35665125Sjoycey #endif 35673859Sml29623 &gsr.value)) 35683859Sml29623 != NXGE_OK) 35693859Sml29623 goto fail; 35703859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 35713859Sml29623 gsr.bits.link_1000fdx; 35723859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 35733859Sml29623 gsr.bits.link_1000hdx; 35743859Sml29623 if (param_arr[param_anar_1000fdx].value && 35753859Sml29623 gsr.bits.link_1000fdx) { 35763859Sml29623 statsp->mac_stats.link_speed = 1000; 35773859Sml29623 statsp->mac_stats.link_duplex = 2; 35783859Sml29623 } else if ( 35793859Sml29623 param_arr[param_anar_1000hdx].value && 35803859Sml29623 gsr.bits.link_1000hdx) { 35813859Sml29623 statsp->mac_stats.link_speed = 1000; 35823859Sml29623 statsp->mac_stats.link_duplex = 1; 35833859Sml29623 } 35843859Sml29623 } 35853859Sml29623 if ((an_common.value != 0) && 35863859Sml29623 !(statsp->mac_stats.link_speed)) { 35873859Sml29623 if (an_common.bits.cap_100T4) { 35883859Sml29623 statsp->mac_stats.link_T4 = 1; 35893859Sml29623 statsp->mac_stats.link_speed = 100; 35903859Sml29623 statsp->mac_stats.link_duplex = 1; 35913859Sml29623 } else if (an_common.bits.cap_100fdx) { 35923859Sml29623 statsp->mac_stats.link_speed = 100; 35933859Sml29623 statsp->mac_stats.link_duplex = 2; 35943859Sml29623 } else if (an_common.bits.cap_100hdx) { 35953859Sml29623 statsp->mac_stats.link_speed = 100; 35963859Sml29623 statsp->mac_stats.link_duplex = 1; 35973859Sml29623 } else if (an_common.bits.cap_10fdx) { 35983859Sml29623 statsp->mac_stats.link_speed = 10; 35993859Sml29623 statsp->mac_stats.link_duplex = 2; 36003859Sml29623 } else if (an_common.bits.cap_10hdx) { 36013859Sml29623 statsp->mac_stats.link_speed = 10; 36023859Sml29623 statsp->mac_stats.link_duplex = 1; 36033859Sml29623 } else { 36043859Sml29623 goto fail; 36053859Sml29623 } 36063859Sml29623 } 36073859Sml29623 if (statsp->mac_stats.link_duplex != 1) { 36083859Sml29623 statsp->mac_stats.link_asmpause = 36093859Sml29623 an_common.bits.cap_asmpause; 36103859Sml29623 if (statsp->mac_stats.link_asmpause) 36113859Sml29623 if ((statsp->mac_stats.cap_pause == 0) && 36123859Sml29623 (statsp->mac_stats.lp_cap_pause 36133859Sml29623 == 1)) 36143859Sml29623 statsp->mac_stats.link_pause 36153859Sml29623 = 0; 36163859Sml29623 else 36173859Sml29623 statsp->mac_stats.link_pause 36183859Sml29623 = 1; 36193859Sml29623 else 36203859Sml29623 statsp->mac_stats.link_pause = 36213859Sml29623 an_common.bits.cap_pause; 36223859Sml29623 } 36235196Ssbehera } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 36245196Ssbehera statsp->mac_stats.link_speed = 1000; 36255196Ssbehera statsp->mac_stats.link_duplex = 2; 36263859Sml29623 } 36273859Sml29623 *link_up = LINK_IS_UP; 36283859Sml29623 } 36293859Sml29623 36303859Sml29623 if (nxgep->link_notify) { 36313859Sml29623 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 36323859Sml29623 LINK_IS_DOWN); 36333859Sml29623 nxgep->link_notify = B_FALSE; 36343859Sml29623 } 36353859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 36363859Sml29623 return (NXGE_OK); 36373859Sml29623 fail: 36383859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 36393859Sml29623 "nxge_mii_check: Unable to check MII")); 36403859Sml29623 return (status); 36413859Sml29623 } 36423859Sml29623 36434977Sraghus /* Check PCS to see if there is any link status change */ 36444977Sraghus nxge_status_t 36454977Sraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up) 36464977Sraghus { 36474977Sraghus p_nxge_stats_t statsp; 36484977Sraghus nxge_status_t status = NXGE_OK; 36494977Sraghus boolean_t linkup; 36504977Sraghus 36514977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check")); 36524977Sraghus 36534977Sraghus statsp = nxgep->statsp; 36544977Sraghus *link_up = LINK_NO_CHANGE; 36554977Sraghus 36564977Sraghus (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup); 36574977Sraghus if (linkup) { 36584977Sraghus if (nxgep->link_notify || 36594977Sraghus nxgep->statsp->mac_stats.link_up == 0) { 36604977Sraghus statsp->mac_stats.link_up = 1; 36614977Sraghus statsp->mac_stats.link_speed = 1000; 36624977Sraghus statsp->mac_stats.link_duplex = 2; 36634977Sraghus *link_up = LINK_IS_UP; 36644977Sraghus nxgep->link_notify = B_FALSE; 36654977Sraghus } 36664977Sraghus } else { 36674977Sraghus if (nxgep->link_notify || 36684977Sraghus nxgep->statsp->mac_stats.link_up == 1) { 36694977Sraghus statsp->mac_stats.link_up = 0; 36704977Sraghus statsp->mac_stats.link_speed = 0; 36714977Sraghus statsp->mac_stats.link_duplex = 0; 36724977Sraghus *link_up = LINK_IS_DOWN; 36734977Sraghus nxgep->link_notify = B_FALSE; 36744977Sraghus } 36754977Sraghus } 36764977Sraghus 36774977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check")); 36784977Sraghus return (NXGE_OK); 36794977Sraghus fail: 36804977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 36814977Sraghus "nxge_pcs_check: Unable to check PCS")); 36824977Sraghus return (status); 36834977Sraghus } 36844977Sraghus 36853859Sml29623 /* Add a multicast address entry into the HW hash table */ 36863859Sml29623 36873859Sml29623 nxge_status_t 36883859Sml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 36893859Sml29623 { 36903859Sml29623 uint32_t mchash; 36913859Sml29623 p_hash_filter_t hash_filter; 36923859Sml29623 uint16_t hash_bit; 36933859Sml29623 boolean_t rx_init = B_FALSE; 36943859Sml29623 uint_t j; 36953859Sml29623 nxge_status_t status = NXGE_OK; 36963859Sml29623 36973859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 36983859Sml29623 36993859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 37003859Sml29623 mchash = crc32_mchash(addrp); 37013859Sml29623 if (nxgep->hash_filter == NULL) { 37023859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 37033859Sml29623 "Allocating hash filter storage.")); 37043859Sml29623 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 37053859Sml29623 KM_SLEEP); 37063859Sml29623 } 37073859Sml29623 hash_filter = nxgep->hash_filter; 37083859Sml29623 j = mchash / HASH_REG_WIDTH; 37093859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 37103859Sml29623 hash_filter->hash_filter_regs[j] |= hash_bit; 37113859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]++; 37123859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 37133859Sml29623 hash_filter->hash_ref_cnt++; 37143859Sml29623 rx_init = B_TRUE; 37153859Sml29623 } 37163859Sml29623 if (rx_init) { 37173859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 37183859Sml29623 goto fail; 37193859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 37203859Sml29623 goto fail; 37213859Sml29623 } 37223859Sml29623 37233859Sml29623 RW_EXIT(&nxgep->filter_lock); 37243859Sml29623 37253859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 37263859Sml29623 37273859Sml29623 return (NXGE_OK); 37283859Sml29623 fail: 37293859Sml29623 RW_EXIT(&nxgep->filter_lock); 37303859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 37313859Sml29623 "Unable to add multicast address")); 37323859Sml29623 return (status); 37333859Sml29623 } 37343859Sml29623 37353859Sml29623 /* Remove a multicast address entry from the HW hash table */ 37363859Sml29623 37373859Sml29623 nxge_status_t 37383859Sml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 37393859Sml29623 { 37403859Sml29623 uint32_t mchash; 37413859Sml29623 p_hash_filter_t hash_filter; 37423859Sml29623 uint16_t hash_bit; 37433859Sml29623 boolean_t rx_init = B_FALSE; 37443859Sml29623 uint_t j; 37453859Sml29623 nxge_status_t status = NXGE_OK; 37463859Sml29623 37473859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 37483859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 37493859Sml29623 mchash = crc32_mchash(addrp); 37503859Sml29623 if (nxgep->hash_filter == NULL) { 37513859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 37523859Sml29623 "Hash filter already de_allocated.")); 37533859Sml29623 RW_EXIT(&nxgep->filter_lock); 37543859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 37553859Sml29623 return (NXGE_OK); 37563859Sml29623 } 37573859Sml29623 hash_filter = nxgep->hash_filter; 37583859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]--; 37593859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 37603859Sml29623 j = mchash / HASH_REG_WIDTH; 37613859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 37623859Sml29623 hash_filter->hash_filter_regs[j] &= ~hash_bit; 37633859Sml29623 hash_filter->hash_ref_cnt--; 37643859Sml29623 rx_init = B_TRUE; 37653859Sml29623 } 37663859Sml29623 if (hash_filter->hash_ref_cnt == 0) { 37673859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 37683859Sml29623 "De-allocating hash filter storage.")); 37693859Sml29623 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 37703859Sml29623 nxgep->hash_filter = NULL; 37713859Sml29623 } 37723859Sml29623 37733859Sml29623 if (rx_init) { 37743859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 37753859Sml29623 goto fail; 37763859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 37773859Sml29623 goto fail; 37783859Sml29623 } 37793859Sml29623 RW_EXIT(&nxgep->filter_lock); 37803859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 37813859Sml29623 37823859Sml29623 return (NXGE_OK); 37833859Sml29623 fail: 37843859Sml29623 RW_EXIT(&nxgep->filter_lock); 37853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 37863859Sml29623 "Unable to remove multicast address")); 37873859Sml29623 37883859Sml29623 return (status); 37893859Sml29623 } 37903859Sml29623 37913859Sml29623 /* Set MAC address into MAC address HW registers */ 37923859Sml29623 37933859Sml29623 nxge_status_t 37943859Sml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 37953859Sml29623 { 37963859Sml29623 nxge_status_t status = NXGE_OK; 37973859Sml29623 37983859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 37993859Sml29623 38003859Sml29623 MUTEX_ENTER(&nxgep->ouraddr_lock); 38013859Sml29623 /* 38023859Sml29623 * Exit if the address is same as ouraddr or multicast or broadcast 38033859Sml29623 */ 38043859Sml29623 if (((addrp->ether_addr_octet[0] & 01) == 1) || 38053859Sml29623 (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 38063859Sml29623 (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 38073859Sml29623 goto nxge_set_mac_addr_exit; 38083859Sml29623 } 38093859Sml29623 nxgep->ouraddr = *addrp; 38103859Sml29623 /* 38113859Sml29623 * Set new interface local address and re-init device. 38123859Sml29623 * This is destructive to any other streams attached 38133859Sml29623 * to this device. 38143859Sml29623 */ 38153859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 38163859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 38173859Sml29623 goto fail; 38183859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 38193859Sml29623 goto fail; 38203859Sml29623 38213859Sml29623 RW_EXIT(&nxgep->filter_lock); 38223859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 38233859Sml29623 goto nxge_set_mac_addr_end; 38243859Sml29623 nxge_set_mac_addr_exit: 38253859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 38263859Sml29623 nxge_set_mac_addr_end: 38273859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 38283859Sml29623 38293859Sml29623 return (NXGE_OK); 38303859Sml29623 fail: 38313859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 38323859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 38333859Sml29623 "Unable to set mac address")); 38343859Sml29623 return (status); 38353859Sml29623 } 38363859Sml29623 38374693Stm144005 static 38384693Stm144005 check_link_state_t 38394693Stm144005 nxge_check_link_stop( 38404693Stm144005 nxge_t *nxge) 38414693Stm144005 { 38424693Stm144005 /* If the poll has been cancelled, return STOP. */ 38434693Stm144005 MUTEX_ENTER(&nxge->poll_lock); 38444693Stm144005 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 38454693Stm144005 nxge->poll_state = LINK_MONITOR_STOP; 38464693Stm144005 nxge->nxge_link_poll_timerid = 0; 38474693Stm144005 cv_broadcast(&nxge->poll_cv); 38484693Stm144005 MUTEX_EXIT(&nxge->poll_lock); 38494693Stm144005 38504693Stm144005 NXGE_DEBUG_MSG((nxge, MAC_CTL, 38514693Stm144005 "nxge_check_%s_link(port<%d>) stopped.", 38524693Stm144005 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 38534693Stm144005 nxge->mac.portnum)); 38544693Stm144005 return (CHECK_LINK_STOP); 38554693Stm144005 } 38564693Stm144005 MUTEX_EXIT(&nxge->poll_lock); 38574693Stm144005 38584693Stm144005 return (CHECK_LINK_RESCHEDULE); 38594693Stm144005 } 38604693Stm144005 38613859Sml29623 /* Check status of MII (MIF or PCS) link */ 38623859Sml29623 38634732Sdavemq static nxge_status_t 38643859Sml29623 nxge_check_mii_link(p_nxge_t nxgep) 38653859Sml29623 { 38663859Sml29623 mii_bmsr_t bmsr_ints, bmsr_data; 38673859Sml29623 mii_anlpar_t anlpar; 38683859Sml29623 mii_gsr_t gsr; 38693859Sml29623 p_mii_regs_t mii_regs; 38703859Sml29623 nxge_status_t status = NXGE_OK; 38713859Sml29623 uint8_t portn; 38723859Sml29623 nxge_link_state_t link_up; 38733859Sml29623 38744693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 38754693Stm144005 return (NXGE_ERROR); 38764693Stm144005 38774693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 38784693Stm144005 return (NXGE_OK); 38794693Stm144005 38803859Sml29623 portn = nxgep->mac.portnum; 38813859Sml29623 38823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 38834693Stm144005 portn)); 38843859Sml29623 38853859Sml29623 mii_regs = NULL; 38863859Sml29623 38873859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 38883859Sml29623 38893859Sml29623 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 38903859Sml29623 goto nxge_check_mii_link_exit; 38913859Sml29623 38924977Sraghus switch (nxgep->mac.portmode) { 38934977Sraghus default: 38945196Ssbehera bmsr_data.value = 0; 38953859Sml29623 if ((status = nxge_mii_read(nxgep, 38964977Sraghus nxgep->statsp->mac_stats.xcvr_portn, 38975125Sjoycey #if defined(__i386) 38985125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 38995125Sjoycey #else 39004977Sraghus (uint8_t)(uint64_t)(&mii_regs->bmsr), 39015125Sjoycey #endif 39024977Sraghus &bmsr_data.value)) != NXGE_OK) { 39033859Sml29623 goto fail; 39043859Sml29623 } 39054977Sraghus 39065196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39075196Ssbehera "==> nxge_check_mii_link port<0x%x> " 39085196Ssbehera "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ", 39095196Ssbehera xcvr_portn, bmsr_data.value, nxgep->bmsr.value)); 39105196Ssbehera 39114977Sraghus if (nxgep->param_arr[param_autoneg].value) { 39124977Sraghus if ((status = nxge_mii_read(nxgep, 39134977Sraghus nxgep->statsp->mac_stats.xcvr_portn, 39145125Sjoycey #if defined(__i386) 39155125Sjoycey (uint8_t)(uint32_t)(&mii_regs->gsr), 39165125Sjoycey #else 39174977Sraghus (uint8_t)(uint64_t)(&mii_regs->gsr), 39185125Sjoycey #endif 39194977Sraghus &gsr.value)) != NXGE_OK) 39204977Sraghus goto fail; 39214977Sraghus if ((status = nxge_mii_read(nxgep, 39224977Sraghus nxgep->statsp->mac_stats.xcvr_portn, 39235125Sjoycey #if defined(__i386) 39245125Sjoycey (uint8_t)(uint32_t)(&mii_regs->anlpar), 39255125Sjoycey #else 39264977Sraghus (uint8_t)(uint64_t)(&mii_regs->anlpar), 39275125Sjoycey #endif 39284977Sraghus &anlpar.value)) != NXGE_OK) 39294977Sraghus goto fail; 39305196Ssbehera if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) { 39315196Ssbehera 39325196Ssbehera if (nxgep->statsp->mac_stats.link_up && 39335196Ssbehera ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 39345196Ssbehera gsr.bits.link_1000fdx) || 39355196Ssbehera (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 39365196Ssbehera gsr.bits.link_1000hdx) || 39375196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 39385196Ssbehera anlpar.bits.cap_100T4) || 39395196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 39405196Ssbehera anlpar.bits.cap_100fdx) || 39415196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 39425196Ssbehera anlpar.bits.cap_100hdx) || 39435196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 39445196Ssbehera anlpar.bits.cap_10fdx) || 39455196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 39465196Ssbehera anlpar.bits.cap_10hdx))) { 39475196Ssbehera bmsr_data.bits.link_status = 0; 39485196Ssbehera } 39494977Sraghus } 39504977Sraghus } 39514977Sraghus 39524977Sraghus /* Workaround for link down issue */ 39534977Sraghus if (bmsr_data.value == 0) { 39544977Sraghus cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 39554977Sraghus goto nxge_check_mii_link_exit; 39564977Sraghus } 39574977Sraghus 39585196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39595196Ssbehera "==> nxge_check_mii_link port<0x%x> :" 39605196Ssbehera "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x", 39615196Ssbehera xcvr_portn, nxgep->bmsr.value, bmsr_data.value)); 39625196Ssbehera 39634977Sraghus bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 39644977Sraghus nxgep->bmsr.value = bmsr_data.value; 39655196Ssbehera 39665196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39675196Ssbehera "==> nxge_check_mii_link port<0x%x> CALLING " 39685196Ssbehera "bmsr_data 0x%x bmsr_ints.value 0x%x", 39695196Ssbehera xcvr_portn, bmsr_data.value, bmsr_ints.value)); 39705196Ssbehera 39714977Sraghus if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, 39724977Sraghus &link_up)) != NXGE_OK) { 39734977Sraghus goto fail; 39744977Sraghus } 39754977Sraghus break; 39764977Sraghus 39774977Sraghus case PORT_1G_SERDES: 39784977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39794977Sraghus "==> nxge_check_mii_link port<%d> (SERDES)", portn)); 39804977Sraghus if ((status = nxge_pcs_check(nxgep, portn, &link_up)) 39814977Sraghus != NXGE_OK) { 39824977Sraghus goto fail; 39834977Sraghus } 39844977Sraghus break; 39853859Sml29623 } 39863859Sml29623 39873859Sml29623 nxge_check_mii_link_exit: 39883859Sml29623 RW_EXIT(&nxgep->filter_lock); 39893859Sml29623 if (link_up == LINK_IS_UP) { 39903859Sml29623 nxge_link_is_up(nxgep); 39913859Sml29623 } else if (link_up == LINK_IS_DOWN) { 39923859Sml29623 nxge_link_is_down(nxgep); 39933859Sml29623 } 39943859Sml29623 39953859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 39963859Sml29623 39973859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 39984977Sraghus portn)); 39993859Sml29623 return (NXGE_OK); 40003859Sml29623 40013859Sml29623 fail: 40023859Sml29623 RW_EXIT(&nxgep->filter_lock); 40033859Sml29623 40043859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 40053859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 40064977Sraghus "nxge_check_mii_link: Failed to check link port<%d>", 40074977Sraghus portn)); 40083859Sml29623 return (status); 40093859Sml29623 } 40103859Sml29623 40113859Sml29623 40123859Sml29623 /*ARGSUSED*/ 40134732Sdavemq static nxge_status_t 40143859Sml29623 nxge_check_10g_link(p_nxge_t nxgep) 40153859Sml29623 { 40163859Sml29623 uint8_t portn; 40173859Sml29623 nxge_status_t status = NXGE_OK; 40185422Ssbehera boolean_t link_up; 40194977Sraghus uint32_t val; 40204977Sraghus npi_status_t rs; 40213859Sml29623 40224693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 40234693Stm144005 return (NXGE_ERROR); 40244693Stm144005 40254693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 40264693Stm144005 return (NXGE_OK); 40274693Stm144005 40283859Sml29623 portn = nxgep->mac.portnum; 40295196Ssbehera val = 0; 40305196Ssbehera rs = NPI_SUCCESS; 40313859Sml29623 40323859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 40334693Stm144005 portn)); 40343859Sml29623 40354977Sraghus switch (nxgep->mac.portmode) { 40364977Sraghus default: 40374977Sraghus status = nxge_check_bcm8704_link(nxgep, &link_up); 40384977Sraghus if (status != NXGE_OK) 40394977Sraghus goto fail; 40404977Sraghus break; 40414977Sraghus case PORT_10G_SERDES: 40424977Sraghus rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 40435422Ssbehera XPCS_REG_STATUS, &val); 40444977Sraghus if (rs != 0) 40454977Sraghus goto fail; 40464977Sraghus 40474977Sraghus link_up = B_FALSE; 40485422Ssbehera if (val & XPCS_STATUS_LANE_ALIGN) { 40495422Ssbehera link_up = B_TRUE; 40504977Sraghus } 40514977Sraghus 40524977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 40534977Sraghus "==> nxge_check_10g_link port<%d> " 40545422Ssbehera "XPCS_REG_STATUS2 0x%x link_up %d", 40555422Ssbehera portn, val, link_up)); 40565422Ssbehera 40574977Sraghus break; 40584977Sraghus } 40593859Sml29623 40603859Sml29623 if (link_up) { 40613859Sml29623 if (nxgep->link_notify || 40623859Sml29623 nxgep->statsp->mac_stats.link_up == 0) { 40633859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 40643859Sml29623 goto fail; 40653859Sml29623 nxgep->statsp->mac_stats.link_up = 1; 40663859Sml29623 nxgep->statsp->mac_stats.link_speed = 10000; 40673859Sml29623 nxgep->statsp->mac_stats.link_duplex = 2; 40683859Sml29623 40693859Sml29623 nxge_link_is_up(nxgep); 40703859Sml29623 nxgep->link_notify = B_FALSE; 40713859Sml29623 } 40723859Sml29623 } else { 40733859Sml29623 if (nxgep->link_notify || 40743859Sml29623 nxgep->statsp->mac_stats.link_up == 1) { 40753859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 40763859Sml29623 goto fail; 40773859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 40784977Sraghus "Link down cable problem")); 40793859Sml29623 nxgep->statsp->mac_stats.link_up = 0; 40803859Sml29623 nxgep->statsp->mac_stats.link_speed = 0; 40813859Sml29623 nxgep->statsp->mac_stats.link_duplex = 0; 40823859Sml29623 40833859Sml29623 nxge_link_is_down(nxgep); 40843859Sml29623 nxgep->link_notify = B_FALSE; 40853859Sml29623 } 40863859Sml29623 } 40873859Sml29623 40883859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 40893859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 40904693Stm144005 portn)); 40913859Sml29623 return (NXGE_OK); 40923859Sml29623 40933859Sml29623 fail: 40944693Stm144005 (void) nxge_check_link_stop(nxgep); 40954693Stm144005 40963859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 40974693Stm144005 "nxge_check_10g_link: Failed to check link port<%d>", 40984693Stm144005 portn)); 40993859Sml29623 return (status); 41003859Sml29623 } 41013859Sml29623 41023859Sml29623 41033859Sml29623 /* Declare link down */ 41043859Sml29623 41053859Sml29623 void 41063859Sml29623 nxge_link_is_down(p_nxge_t nxgep) 41073859Sml29623 { 41084732Sdavemq p_nxge_stats_t statsp; 41094732Sdavemq char link_stat_msg[64]; 41104732Sdavemq 41113859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 41123859Sml29623 41134732Sdavemq statsp = nxgep->statsp; 41144732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 41154732Sdavemq statsp->mac_stats.xcvr_portn); 41164732Sdavemq 41174732Sdavemq if (nxge_no_msg == B_FALSE) { 41184732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 41194732Sdavemq } 41204732Sdavemq 41213859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 41223859Sml29623 41233859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 41243859Sml29623 } 41253859Sml29623 41263859Sml29623 /* Declare link up */ 41273859Sml29623 41283859Sml29623 void 41293859Sml29623 nxge_link_is_up(p_nxge_t nxgep) 41303859Sml29623 { 41314732Sdavemq p_nxge_stats_t statsp; 41324732Sdavemq char link_stat_msg[64]; 41333859Sml29623 uint32_t val; 41343859Sml29623 41353859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 41363859Sml29623 41374732Sdavemq statsp = nxgep->statsp; 41384732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 41394732Sdavemq statsp->mac_stats.xcvr_portn, 41404732Sdavemq statsp->mac_stats.link_speed); 41414732Sdavemq 41424732Sdavemq if (statsp->mac_stats.link_T4) 41434732Sdavemq (void) strcat(link_stat_msg, "T4"); 41444732Sdavemq else if (statsp->mac_stats.link_duplex == 2) 41454732Sdavemq (void) strcat(link_stat_msg, "full duplex"); 41464732Sdavemq else 41474732Sdavemq (void) strcat(link_stat_msg, "half duplex"); 41484732Sdavemq 41493859Sml29623 (void) nxge_xif_init(nxgep); 41503859Sml29623 41513859Sml29623 /* Clean up symbol errors incurred during link transition */ 41524977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER) || 41534977Sraghus (nxgep->mac.portmode == PORT_10G_SERDES)) { 41543859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 41553859Sml29623 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 41563859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 41573859Sml29623 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 41583859Sml29623 } 41593859Sml29623 41604732Sdavemq if (nxge_no_msg == B_FALSE) { 41614732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 41624732Sdavemq } 41634732Sdavemq 41643859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_UP); 41653859Sml29623 41663859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 41673859Sml29623 } 41683859Sml29623 41693859Sml29623 /* 41703859Sml29623 * Calculate the bit in the multicast address filter 41713859Sml29623 * that selects the given * address. 41723859Sml29623 * Note: For GEM, the last 8-bits are used. 41733859Sml29623 */ 41743859Sml29623 uint32_t 41753859Sml29623 crc32_mchash(p_ether_addr_t addr) 41763859Sml29623 { 41773859Sml29623 uint8_t *cp; 41783859Sml29623 uint32_t crc; 41793859Sml29623 uint32_t c; 41803859Sml29623 int byte; 41813859Sml29623 int bit; 41823859Sml29623 41833859Sml29623 cp = (uint8_t *)addr; 41843859Sml29623 crc = (uint32_t)0xffffffff; 41853859Sml29623 for (byte = 0; byte < 6; byte++) { 41863859Sml29623 c = (uint32_t)cp[byte]; 41873859Sml29623 for (bit = 0; bit < 8; bit++) { 41883859Sml29623 if ((c & 0x1) ^ (crc & 0x1)) 41893859Sml29623 crc = (crc >> 1)^0xedb88320; 41903859Sml29623 else 41913859Sml29623 crc = (crc >> 1); 41923859Sml29623 c >>= 1; 41933859Sml29623 } 41943859Sml29623 } 41953859Sml29623 return ((~crc) >> (32 - HASH_BITS)); 41963859Sml29623 } 41973859Sml29623 41983859Sml29623 /* Reset serdes */ 41993859Sml29623 42003859Sml29623 nxge_status_t 42013859Sml29623 nxge_serdes_reset(p_nxge_t nxgep) 42023859Sml29623 { 42033859Sml29623 npi_handle_t handle; 42043859Sml29623 42053859Sml29623 handle = nxgep->npi_handle; 42063859Sml29623 42073859Sml29623 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 42083859Sml29623 drv_usecwait(500); 42093859Sml29623 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 42103859Sml29623 42113859Sml29623 return (NXGE_OK); 42123859Sml29623 } 42133859Sml29623 42143859Sml29623 /* Monitor link status using interrupt or polling */ 42153859Sml29623 42163859Sml29623 nxge_status_t 42173859Sml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 42183859Sml29623 { 42193859Sml29623 nxge_status_t status = NXGE_OK; 42203859Sml29623 42213859Sml29623 /* 42224693Stm144005 * Return immediately if this is an imaginary XMAC port. 42234693Stm144005 * (At least, we don't have 4-port XMAC cards yet.) 42243859Sml29623 */ 42254977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER || 42264977Sraghus nxgep->mac.portmode == PORT_10G_SERDES) && 42274977Sraghus (nxgep->mac.portnum > 1)) 42283859Sml29623 return (NXGE_OK); 42293859Sml29623 42303859Sml29623 if (nxgep->statsp == NULL) { 42313859Sml29623 /* stats has not been allocated. */ 42323859Sml29623 return (NXGE_OK); 42333859Sml29623 } 42343859Sml29623 /* Don't check link if we're not in internal loopback mode */ 42353859Sml29623 if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal) 42363859Sml29623 return (NXGE_OK); 42373859Sml29623 42383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 42394693Stm144005 "==> nxge_link_monitor port<%d> enable=%d", 42404693Stm144005 nxgep->mac.portnum, enable)); 42413859Sml29623 if (enable == LINK_MONITOR_START) { 42423859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 42433859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 42444693Stm144005 != NXGE_OK) 42453859Sml29623 goto fail; 42463859Sml29623 } else { 42474693Stm144005 timeout_id_t timerid; 42484693Stm144005 42494693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 42504693Stm144005 return (NXGE_OK); 42514693Stm144005 42524732Sdavemq if (nxgep->xcvr.check_link) { 42534732Sdavemq timerid = timeout( 42544732Sdavemq (fptrv_t)(nxgep->xcvr.check_link), 42554693Stm144005 nxgep, 42564693Stm144005 drv_usectohz(LINK_MONITOR_PERIOD)); 42574732Sdavemq MUTEX_ENTER(&nxgep->poll_lock); 42584732Sdavemq nxgep->nxge_link_poll_timerid = timerid; 42594732Sdavemq MUTEX_EXIT(&nxgep->poll_lock); 42604732Sdavemq } else { 42614693Stm144005 return (NXGE_ERROR); 42623859Sml29623 } 42633859Sml29623 } 42643859Sml29623 } else { 42653859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 42663859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 42674693Stm144005 != NXGE_OK) 42683859Sml29623 goto fail; 42693859Sml29623 } else { 42704693Stm144005 clock_t rv; 42714693Stm144005 42724693Stm144005 MUTEX_ENTER(&nxgep->poll_lock); 42734693Stm144005 42744693Stm144005 /* If <timerid> == 0, the link monitor has */ 42754693Stm144005 /* never been started, or just now stopped. */ 42764693Stm144005 if (nxgep->nxge_link_poll_timerid == 0) { 42774693Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 42784693Stm144005 return (NXGE_OK); 42794693Stm144005 } 42804693Stm144005 42814693Stm144005 nxgep->poll_state = LINK_MONITOR_STOPPING; 42824693Stm144005 rv = cv_timedwait(&nxgep->poll_cv, 42834693Stm144005 &nxgep->poll_lock, 42844693Stm144005 ddi_get_lbolt() + 42854693Stm144005 drv_usectohz(LM_WAIT_MULTIPLIER * 42864693Stm144005 LINK_MONITOR_PERIOD)); 42874693Stm144005 if (rv == -1) { 42884693Stm144005 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 42894693Stm144005 "==> stopping port %d: " 42904693Stm144005 "cv_timedwait(%d) timed out", 42914693Stm144005 nxgep->mac.portnum, nxgep->poll_state)); 42924693Stm144005 nxgep->poll_state = LINK_MONITOR_STOP; 42933859Sml29623 nxgep->nxge_link_poll_timerid = 0; 42943859Sml29623 } 42954693Stm144005 42964693Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 42973859Sml29623 } 42983859Sml29623 } 42993859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43004693Stm144005 "<== nxge_link_monitor port<%d> enable=%d", 43014693Stm144005 nxgep->mac.portnum, enable)); 43023859Sml29623 return (NXGE_OK); 43033859Sml29623 fail: 43043859Sml29623 return (status); 43053859Sml29623 } 43063859Sml29623 43073859Sml29623 /* Set promiscous mode */ 43083859Sml29623 43093859Sml29623 nxge_status_t 43103859Sml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 43113859Sml29623 { 43123859Sml29623 nxge_status_t status = NXGE_OK; 43133859Sml29623 43144732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 43153859Sml29623 43163859Sml29623 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 43173859Sml29623 43183859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 43193859Sml29623 43203859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 43213859Sml29623 goto fail; 43223859Sml29623 } 43233859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 43243859Sml29623 goto fail; 43253859Sml29623 } 43263859Sml29623 43273859Sml29623 RW_EXIT(&nxgep->filter_lock); 43283859Sml29623 43293859Sml29623 if (on) 43303859Sml29623 nxgep->statsp->mac_stats.promisc = B_TRUE; 43313859Sml29623 else 43323859Sml29623 nxgep->statsp->mac_stats.promisc = B_FALSE; 43333859Sml29623 43343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 43353859Sml29623 43363859Sml29623 return (NXGE_OK); 43373859Sml29623 fail: 43383859Sml29623 RW_EXIT(&nxgep->filter_lock); 43393859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 43404732Sdavemq "Unable to set promisc (%d)", on)); 43413859Sml29623 43423859Sml29623 return (status); 43433859Sml29623 } 43443859Sml29623 43453859Sml29623 /*ARGSUSED*/ 43463859Sml29623 uint_t 43473859Sml29623 nxge_mif_intr(void *arg1, void *arg2) 43483859Sml29623 { 43493859Sml29623 #ifdef NXGE_DEBUG 43503859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 43513859Sml29623 #endif 43523859Sml29623 #if NXGE_MIF 43533859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 43543859Sml29623 uint32_t status; 43553859Sml29623 npi_handle_t handle; 43563859Sml29623 uint8_t portn; 43573859Sml29623 p_nxge_stats_t statsp; 43583859Sml29623 #endif 43593859Sml29623 43603859Sml29623 #ifdef NXGE_MIF 43613859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 43623859Sml29623 nxgep = ldvp->nxgep; 43633859Sml29623 } 43643859Sml29623 nxgep = ldvp->nxgep; 43653859Sml29623 #endif 43663859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 43673859Sml29623 43683859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 43693859Sml29623 return (DDI_INTR_CLAIMED); 43703859Sml29623 43713859Sml29623 mif_intr_fail: 43723859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 43733859Sml29623 return (DDI_INTR_UNCLAIMED); 43743859Sml29623 } 43753859Sml29623 43763859Sml29623 /*ARGSUSED*/ 43773859Sml29623 uint_t 43783859Sml29623 nxge_mac_intr(void *arg1, void *arg2) 43793859Sml29623 { 43803859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 43813859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 43823859Sml29623 p_nxge_ldg_t ldgp; 43833859Sml29623 uint32_t status; 43843859Sml29623 npi_handle_t handle; 43853859Sml29623 uint8_t portn; 43863859Sml29623 p_nxge_stats_t statsp; 43873859Sml29623 npi_status_t rs = NPI_SUCCESS; 43883859Sml29623 43893859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 43903859Sml29623 nxgep = ldvp->nxgep; 43913859Sml29623 } 43923859Sml29623 43933859Sml29623 ldgp = ldvp->ldgp; 43943859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 43954732Sdavemq "group %d", ldgp->ldg)); 43963859Sml29623 43973859Sml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep); 43983859Sml29623 /* 43993859Sml29623 * This interrupt handler is for a specific 44003859Sml29623 * mac port. 44013859Sml29623 */ 44023859Sml29623 statsp = (p_nxge_stats_t)nxgep->statsp; 44033859Sml29623 portn = nxgep->mac.portnum; 44043859Sml29623 44053859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, 44064732Sdavemq "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 44073859Sml29623 44083859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 44093859Sml29623 rs = npi_xmac_tx_get_istatus(handle, portn, 44103859Sml29623 (xmac_tx_iconfig_t *)&status); 44113859Sml29623 if (rs != NPI_SUCCESS) 44123859Sml29623 goto npi_fail; 44133859Sml29623 if (status & ICFG_XMAC_TX_ALL) { 44143859Sml29623 if (status & ICFG_XMAC_TX_UNDERRUN) { 44153859Sml29623 statsp->xmac_stats.tx_underflow_err++; 44163859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 44173859Sml29623 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 44183859Sml29623 } 44193859Sml29623 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 44203859Sml29623 statsp->xmac_stats.tx_maxpktsize_err++; 44215523Syc148097 /* 44225523Syc148097 * Do not send FMA ereport because this 44235523Syc148097 * error does not indicate HW failure. 44245523Syc148097 */ 44253859Sml29623 } 44263859Sml29623 if (status & ICFG_XMAC_TX_OVERFLOW) { 44273859Sml29623 statsp->xmac_stats.tx_overflow_err++; 44283859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 44293859Sml29623 NXGE_FM_EREPORT_TXMAC_OVERFLOW); 44303859Sml29623 } 44313859Sml29623 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 44323859Sml29623 statsp->xmac_stats.tx_fifo_xfr_err++; 44333859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 44343859Sml29623 NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 44353859Sml29623 } 44363859Sml29623 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 44373859Sml29623 statsp->xmac_stats.tx_byte_cnt += 44383859Sml29623 XTXMAC_BYTE_CNT_MASK; 44393859Sml29623 } 44403859Sml29623 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 44413859Sml29623 statsp->xmac_stats.tx_frame_cnt += 44423859Sml29623 XTXMAC_FRM_CNT_MASK; 44433859Sml29623 } 44443859Sml29623 } 44453859Sml29623 44463859Sml29623 rs = npi_xmac_rx_get_istatus(handle, portn, 44473859Sml29623 (xmac_rx_iconfig_t *)&status); 44483859Sml29623 if (rs != NPI_SUCCESS) 44493859Sml29623 goto npi_fail; 44503859Sml29623 if (status & ICFG_XMAC_RX_ALL) { 44513859Sml29623 if (status & ICFG_XMAC_RX_OVERFLOW) 44523859Sml29623 statsp->xmac_stats.rx_overflow_err++; 44533859Sml29623 if (status & ICFG_XMAC_RX_UNDERFLOW) { 44543859Sml29623 statsp->xmac_stats.rx_underflow_err++; 44553859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 44563859Sml29623 NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 44573859Sml29623 } 44585523Syc148097 /* 44595523Syc148097 * Do not send FMA ereport for the following 3 errors 44605523Syc148097 * because they do not indicate HW failures. 44615523Syc148097 */ 44623859Sml29623 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 44633859Sml29623 statsp->xmac_stats.rx_crc_err_cnt += 44643859Sml29623 XRXMAC_CRC_ER_CNT_MASK; 44653859Sml29623 } 44663859Sml29623 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 44673859Sml29623 statsp->xmac_stats.rx_len_err_cnt += 44683859Sml29623 MAC_LEN_ER_CNT_MASK; 44693859Sml29623 } 44703859Sml29623 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 44713859Sml29623 statsp->xmac_stats.rx_viol_err_cnt += 44723859Sml29623 XRXMAC_CD_VIO_CNT_MASK; 44733859Sml29623 } 44743859Sml29623 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 44753859Sml29623 statsp->xmac_stats.rx_byte_cnt += 44763859Sml29623 XRXMAC_BT_CNT_MASK; 44773859Sml29623 } 44783859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 44793859Sml29623 statsp->xmac_stats.rx_hist1_cnt += 44803859Sml29623 XRXMAC_HIST_CNT1_MASK; 44813859Sml29623 } 44823859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 44833859Sml29623 statsp->xmac_stats.rx_hist2_cnt += 44843859Sml29623 XRXMAC_HIST_CNT2_MASK; 44853859Sml29623 } 44863859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 44873859Sml29623 statsp->xmac_stats.rx_hist3_cnt += 44883859Sml29623 XRXMAC_HIST_CNT3_MASK; 44893859Sml29623 } 44903859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 44913859Sml29623 statsp->xmac_stats.rx_hist4_cnt += 44923859Sml29623 XRXMAC_HIST_CNT4_MASK; 44933859Sml29623 } 44943859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 44953859Sml29623 statsp->xmac_stats.rx_hist5_cnt += 44963859Sml29623 XRXMAC_HIST_CNT5_MASK; 44973859Sml29623 } 44983859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 44993859Sml29623 statsp->xmac_stats.rx_hist6_cnt += 45003859Sml29623 XRXMAC_HIST_CNT6_MASK; 45013859Sml29623 } 45023859Sml29623 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 45033859Sml29623 statsp->xmac_stats.rx_broadcast_cnt += 45043859Sml29623 XRXMAC_BC_FRM_CNT_MASK; 45053859Sml29623 } 45063859Sml29623 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 45073859Sml29623 statsp->xmac_stats.rx_mult_cnt += 45083859Sml29623 XRXMAC_MC_FRM_CNT_MASK; 45093859Sml29623 } 45105523Syc148097 /* 45115523Syc148097 * Do not send FMA ereport for the following 3 errors 45125523Syc148097 * because they do not indicate HW failures. 45135523Syc148097 */ 45143859Sml29623 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 45153859Sml29623 statsp->xmac_stats.rx_frag_cnt += 45163859Sml29623 XRXMAC_FRAG_CNT_MASK; 45173859Sml29623 } 45183859Sml29623 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 45193859Sml29623 statsp->xmac_stats.rx_frame_align_err_cnt += 45203859Sml29623 XRXMAC_AL_ER_CNT_MASK; 45213859Sml29623 } 45223859Sml29623 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 45233859Sml29623 statsp->xmac_stats.rx_linkfault_err_cnt += 45243859Sml29623 XMAC_LINK_FLT_CNT_MASK; 45253859Sml29623 } 45263859Sml29623 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 45273859Sml29623 statsp->xmac_stats.rx_remotefault_err++; 45283859Sml29623 } 45293859Sml29623 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 45303859Sml29623 statsp->xmac_stats.rx_localfault_err++; 45313859Sml29623 } 45323859Sml29623 } 45333859Sml29623 45343859Sml29623 rs = npi_xmac_ctl_get_istatus(handle, portn, 45353859Sml29623 (xmac_ctl_iconfig_t *)&status); 45363859Sml29623 if (rs != NPI_SUCCESS) 45373859Sml29623 goto npi_fail; 45383859Sml29623 if (status & ICFG_XMAC_CTRL_ALL) { 45393859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 45403859Sml29623 statsp->xmac_stats.rx_pause_cnt++; 45413859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 45423859Sml29623 statsp->xmac_stats.tx_pause_state++; 45433859Sml29623 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 45443859Sml29623 statsp->xmac_stats.tx_nopause_state++; 45453859Sml29623 } 45463859Sml29623 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 45473859Sml29623 rs = npi_bmac_tx_get_istatus(handle, portn, 45483859Sml29623 (bmac_tx_iconfig_t *)&status); 45493859Sml29623 if (rs != NPI_SUCCESS) 45503859Sml29623 goto npi_fail; 45513859Sml29623 if (status & ICFG_BMAC_TX_ALL) { 45523859Sml29623 if (status & ICFG_BMAC_TX_UNDERFLOW) { 45533859Sml29623 statsp->bmac_stats.tx_underrun_err++; 45543859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 45553859Sml29623 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 45563859Sml29623 } 45573859Sml29623 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 45583859Sml29623 statsp->bmac_stats.tx_max_pkt_err++; 45593859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 45603859Sml29623 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 45613859Sml29623 } 45623859Sml29623 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 45633859Sml29623 statsp->bmac_stats.tx_byte_cnt += 45643859Sml29623 BTXMAC_BYTE_CNT_MASK; 45653859Sml29623 } 45663859Sml29623 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 45673859Sml29623 statsp->bmac_stats.tx_frame_cnt += 45683859Sml29623 BTXMAC_FRM_CNT_MASK; 45693859Sml29623 } 45703859Sml29623 } 45713859Sml29623 45723859Sml29623 rs = npi_bmac_rx_get_istatus(handle, portn, 45733859Sml29623 (bmac_rx_iconfig_t *)&status); 45743859Sml29623 if (rs != NPI_SUCCESS) 45753859Sml29623 goto npi_fail; 45763859Sml29623 if (status & ICFG_BMAC_RX_ALL) { 45773859Sml29623 if (status & ICFG_BMAC_RX_OVERFLOW) { 45783859Sml29623 statsp->bmac_stats.rx_overflow_err++; 45793859Sml29623 } 45803859Sml29623 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 45813859Sml29623 statsp->bmac_stats.rx_frame_cnt += 45823859Sml29623 RXMAC_FRM_CNT_MASK; 45833859Sml29623 } 45843859Sml29623 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 45853859Sml29623 statsp->bmac_stats.rx_crc_err_cnt += 45863859Sml29623 BMAC_CRC_ER_CNT_MASK; 45873859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 45883859Sml29623 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 45893859Sml29623 } 45903859Sml29623 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 45913859Sml29623 statsp->bmac_stats.rx_len_err_cnt += 45923859Sml29623 MAC_LEN_ER_CNT_MASK; 45933859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 45943859Sml29623 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 45953859Sml29623 } 45963859Sml29623 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 45973859Sml29623 statsp->bmac_stats.rx_viol_err_cnt += 45983859Sml29623 BMAC_CD_VIO_CNT_MASK; 45993859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 46003859Sml29623 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 46013859Sml29623 } 46023859Sml29623 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 46033859Sml29623 statsp->bmac_stats.rx_byte_cnt += 46043859Sml29623 BRXMAC_BYTE_CNT_MASK; 46053859Sml29623 } 46063859Sml29623 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 46073859Sml29623 statsp->bmac_stats.rx_align_err_cnt += 46083859Sml29623 BMAC_AL_ER_CNT_MASK; 46093859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 46103859Sml29623 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 46113859Sml29623 } 46123859Sml29623 46133859Sml29623 rs = npi_bmac_ctl_get_istatus(handle, portn, 46143859Sml29623 (bmac_ctl_iconfig_t *)&status); 46153859Sml29623 if (rs != NPI_SUCCESS) 46163859Sml29623 goto npi_fail; 46173859Sml29623 46183859Sml29623 if (status & ICFG_BMAC_CTL_ALL) { 46193859Sml29623 if (status & ICFG_BMAC_CTL_RCVPAUSE) 46203859Sml29623 statsp->bmac_stats.rx_pause_cnt++; 46213859Sml29623 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 46223859Sml29623 statsp->bmac_stats.tx_pause_state++; 46233859Sml29623 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 46243859Sml29623 statsp->bmac_stats.tx_nopause_state++; 46253859Sml29623 } 46263859Sml29623 } 46273859Sml29623 46283859Sml29623 if (ldgp->nldvs == 1) { 46293859Sml29623 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 46303859Sml29623 B_TRUE, ldgp->ldg_timer); 46313859Sml29623 } 46323859Sml29623 46333859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 46343859Sml29623 return (DDI_INTR_CLAIMED); 46353859Sml29623 46363859Sml29623 npi_fail: 46373859Sml29623 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 46383859Sml29623 return (DDI_INTR_UNCLAIMED); 46393859Sml29623 } 46403859Sml29623 46413859Sml29623 nxge_status_t 46423859Sml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 46433859Sml29623 { 46443859Sml29623 uint8_t phy_port_addr; 46453859Sml29623 nxge_status_t status = NXGE_OK; 46463859Sml29623 boolean_t rx_sig_ok; 46473859Sml29623 boolean_t pcs_blk_lock; 46483859Sml29623 boolean_t link_align; 46493859Sml29623 uint16_t val1, val2, val3; 46503859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 46513859Sml29623 uint16_t val_debug; 46523859Sml29623 uint16_t val; 46533859Sml29623 #endif 46543859Sml29623 46553859Sml29623 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 46563859Sml29623 46573859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 46583859Sml29623 /* Check Device 3 Register Device 3 0xC809 */ 46593859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 46603859Sml29623 if ((val_debug & ~0x200) != 0) { 46613859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 46623859Sml29623 nxgep->mac.portnum, val_debug); 46633859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 46643859Sml29623 &val_debug); 46653859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 46663859Sml29623 nxgep->mac.portnum, val_debug); 46673859Sml29623 } 46683859Sml29623 46693859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 46703859Sml29623 XPCS_REG_DESCWERR_COUNTER, &val); 46713859Sml29623 if (val != 0) 46723859Sml29623 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 46733859Sml29623 46743859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 46753859Sml29623 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 46763859Sml29623 if (val != 0) 46773859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 46783859Sml29623 46793859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 46803859Sml29623 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 46813859Sml29623 if (val != 0) 46823859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 46833859Sml29623 #endif 46843859Sml29623 46853859Sml29623 /* Check from BCM8704 if 10G link is up or down */ 46863859Sml29623 46873859Sml29623 /* Check Device 1 Register 0xA bit0 */ 46883859Sml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 46893859Sml29623 BCM8704_PMA_PMD_DEV_ADDR, 46903859Sml29623 BCM8704_PMD_RECEIVE_SIG_DETECT, 46913859Sml29623 &val1); 46923859Sml29623 if (status != NXGE_OK) 46933859Sml29623 goto fail; 46943859Sml29623 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 46953859Sml29623 46963859Sml29623 /* Check Device 3 Register 0x20 bit0 */ 46973859Sml29623 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 46983859Sml29623 BCM8704_PCS_DEV_ADDR, 46993859Sml29623 BCM8704_10GBASE_R_PCS_STATUS_REG, 47003859Sml29623 &val2)) != NPI_SUCCESS) 47013859Sml29623 goto fail; 47023859Sml29623 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 47033859Sml29623 47043859Sml29623 /* Check Device 4 Register 0x18 bit12 */ 47053859Sml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 47063859Sml29623 BCM8704_PHYXS_ADDR, 47073859Sml29623 BCM8704_PHYXS_XGXS_LANE_STATUS_REG, 47083859Sml29623 &val3); 47093859Sml29623 if (status != NXGE_OK) 47103859Sml29623 goto fail; 47113859Sml29623 link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 47123859Sml29623 XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 47133859Sml29623 XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 47143859Sml29623 47153859Sml29623 #ifdef NXGE_DEBUG_ALIGN_ERR 47163859Sml29623 /* Temp workaround for link down issue */ 47173859Sml29623 if (pcs_blk_lock == B_FALSE) { 47183859Sml29623 if (val2 != 0x4) { 47193859Sml29623 pcs_blk_lock = B_TRUE; 47203859Sml29623 cmn_err(CE_NOTE, 47213859Sml29623 "!LINK DEBUG: port%d PHY Dev3 " 47223859Sml29623 "Reg 0x20 = 0x%x\n", 47233859Sml29623 nxgep->mac.portnum, val2); 47243859Sml29623 } 47253859Sml29623 } 47263859Sml29623 47273859Sml29623 if (link_align == B_FALSE) { 47283859Sml29623 if (val3 != 0x140f) { 47293859Sml29623 link_align = B_TRUE; 47303859Sml29623 cmn_err(CE_NOTE, 47313859Sml29623 "!LINK DEBUG: port%d PHY Dev4 " 47323859Sml29623 "Reg 0x18 = 0x%x\n", 47333859Sml29623 nxgep->mac.portnum, val3); 47343859Sml29623 } 47353859Sml29623 } 47363859Sml29623 47373859Sml29623 if (rx_sig_ok == B_FALSE) { 47383859Sml29623 if ((val2 == 0) || (val3 == 0)) { 47393859Sml29623 rx_sig_ok = B_TRUE; 47403859Sml29623 cmn_err(CE_NOTE, 47413859Sml29623 "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 47423859Sml29623 nxgep->mac.portnum); 47433859Sml29623 } 47443859Sml29623 } 47453859Sml29623 #endif 47463859Sml29623 47473859Sml29623 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 47483859Sml29623 (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 47493859Sml29623 47503859Sml29623 return (NXGE_OK); 47513859Sml29623 fail: 47523859Sml29623 return (status); 47533859Sml29623 } 47543859Sml29623 47553859Sml29623 nxge_status_t 47563859Sml29623 nxge_10g_link_led_on(p_nxge_t nxgep) 47573859Sml29623 { 47583859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 47594732Sdavemq != NPI_SUCCESS) 47603859Sml29623 return (NXGE_ERROR); 47613859Sml29623 else 47623859Sml29623 return (NXGE_OK); 47633859Sml29623 } 47643859Sml29623 47653859Sml29623 nxge_status_t 47663859Sml29623 nxge_10g_link_led_off(p_nxge_t nxgep) 47673859Sml29623 { 47683859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 47694732Sdavemq != NPI_SUCCESS) 47703859Sml29623 return (NXGE_ERROR); 47713859Sml29623 else 47723859Sml29623 return (NXGE_OK); 47733859Sml29623 } 47744185Sspeer 47754732Sdavemq /* Check if the given id read using the given MDIO Clause is supported */ 47764732Sdavemq 47774732Sdavemq static boolean_t 47784732Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type) 47794732Sdavemq { 47804732Sdavemq int i; 47814732Sdavemq int cl45_arr_len = NUM_CLAUSE_45_IDS; 47824732Sdavemq int cl22_arr_len = NUM_CLAUSE_22_IDS; 47834732Sdavemq boolean_t found = B_FALSE; 47844732Sdavemq 47854732Sdavemq switch (type) { 47864732Sdavemq case CLAUSE_45_TYPE: 47874732Sdavemq for (i = 0; i < cl45_arr_len; i++) { 47884782Ssbehera if ((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) == 47894782Ssbehera (id & BCM_PHY_ID_MASK)) { 47904732Sdavemq found = B_TRUE; 47914732Sdavemq break; 47924732Sdavemq } 47934732Sdavemq } 47944732Sdavemq break; 47954732Sdavemq case CLAUSE_22_TYPE: 47964732Sdavemq for (i = 0; i < cl22_arr_len; i++) { 47974782Ssbehera if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) == 47984782Ssbehera (id & BCM_PHY_ID_MASK)) { 47994732Sdavemq found = B_TRUE; 48004732Sdavemq break; 48014732Sdavemq } 48024732Sdavemq } 48034732Sdavemq break; 48044732Sdavemq default: 48054732Sdavemq break; 48064732Sdavemq } 48074732Sdavemq 48084732Sdavemq return (found); 48094732Sdavemq } 48104732Sdavemq 48114977Sraghus static uint32_t 48124977Sraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port) 48134977Sraghus { 48144977Sraghus uint16_t val1 = 0; 48154977Sraghus uint16_t val2 = 0; 48164977Sraghus uint32_t pma_pmd_dev_id = 0; 48174977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 48184977Sraghus 48194977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 48204977Sraghus NXGE_DEV_ID_REG_1, &val1); 48214977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 48224977Sraghus NXGE_DEV_ID_REG_2, &val2); 48234977Sraghus 48244977Sraghus pma_pmd_dev_id = val1; 48254977Sraghus pma_pmd_dev_id = (pma_pmd_dev_id << 16); 48264977Sraghus pma_pmd_dev_id |= val2; 48274977Sraghus 48284977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 48294977Sraghus "devid[0x%llx]", phy_port, pma_pmd_dev_id)); 48304977Sraghus 48314977Sraghus return (pma_pmd_dev_id); 48324977Sraghus } 48334977Sraghus 48344977Sraghus static uint32_t 48354977Sraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port) 48364977Sraghus { 48374977Sraghus uint16_t val1 = 0; 48384977Sraghus uint16_t val2 = 0; 48394977Sraghus uint32_t pcs_dev_id = 0; 48404977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 48414977Sraghus 48424977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 48434977Sraghus NXGE_DEV_ID_REG_1, &val1); 48444977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 48454977Sraghus NXGE_DEV_ID_REG_2, &val2); 48464977Sraghus 48474977Sraghus pcs_dev_id = val1; 48484977Sraghus pcs_dev_id = (pcs_dev_id << 16); 48494977Sraghus pcs_dev_id |= val2; 48504977Sraghus 48514977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 48524977Sraghus "devid[0x%llx]", phy_port, pcs_dev_id)); 48534977Sraghus 48544977Sraghus return (pcs_dev_id); 48554977Sraghus } 48564977Sraghus 48574977Sraghus static uint32_t 48584977Sraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port) 48594977Sraghus { 48604977Sraghus uint16_t val1 = 0; 48614977Sraghus uint16_t val2 = 0; 48624977Sraghus uint32_t phy_id = 0; 48634977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 48644977Sraghus npi_status_t npi_status = NPI_SUCCESS; 48654977Sraghus 48664977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1, 48674977Sraghus &val1); 48684977Sraghus if (npi_status != NPI_SUCCESS) { 48694977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 48704977Sraghus "clause 22 read to reg 2 failed!!!")); 48714977Sraghus goto exit; 48724977Sraghus } 48734977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2, 48744977Sraghus &val2); 48754977Sraghus if (npi_status != 0) { 48764977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 48774977Sraghus "clause 22 read to reg 3 failed!!!")); 48784977Sraghus goto exit; 48794977Sraghus } 48804977Sraghus phy_id = val1; 48814977Sraghus phy_id = (phy_id << 16); 48824977Sraghus phy_id |= val2; 48834977Sraghus 48844977Sraghus exit: 48854977Sraghus 48864977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]", 48874977Sraghus phy_port, phy_id)); 48884977Sraghus 48894977Sraghus return (phy_id); 48904977Sraghus } 48914977Sraghus 48924732Sdavemq /* 48934732Sdavemq * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 48944732Sdavemq * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 48954732Sdavemq * read. Then use the values obtained to determine the phy type of each port 48964732Sdavemq * and the Neptune type. 48974732Sdavemq */ 48984732Sdavemq 48994732Sdavemq nxge_status_t 49004732Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 49014732Sdavemq { 49024732Sdavemq int i, j, k, l; 49034732Sdavemq uint32_t pma_pmd_dev_id = 0; 49044732Sdavemq uint32_t pcs_dev_id = 0; 49054732Sdavemq uint32_t phy_id = 0; 49064782Ssbehera uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE]; 49074782Ssbehera uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE]; 49084782Ssbehera uint32_t port_phy_id[NXGE_PORTS_NEPTUNE]; 49094732Sdavemq uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 49104732Sdavemq uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 49114732Sdavemq uint8_t phy_fd[NXGE_MAX_PHY_PORTS]; 49124732Sdavemq uint8_t port_fd[NXGE_MAX_PHY_PORTS]; 49134732Sdavemq uint8_t total_port_fd, total_phy_fd; 49144732Sdavemq nxge_status_t status = NXGE_OK; 49154732Sdavemq int prt_id = -1; 49164732Sdavemq 49174732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 49184732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49194732Sdavemq "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 49204732Sdavemq nxgep->niu_type)); 49214732Sdavemq 49224732Sdavemq j = k = l = 0; 49234732Sdavemq total_port_fd = total_phy_fd = 0; 49244732Sdavemq /* 49254732Sdavemq * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved 49264732Sdavemq * for on chip serdes usages. 49274732Sdavemq */ 49284732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 49294977Sraghus 49304977Sraghus pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i); 49314732Sdavemq 49324732Sdavemq if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 49334732Sdavemq pma_pmd_dev_fd[i] = 1; 49344732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 49354732Sdavemq "PMA/PMD dev found", i)); 49364782Ssbehera if (j < NXGE_PORTS_NEPTUNE) { 49374782Ssbehera port_pma_pmd_dev_id[j] = pma_pmd_dev_id & 49384782Ssbehera BCM_PHY_ID_MASK; 49394732Sdavemq j++; 49404732Sdavemq } 49414732Sdavemq } else { 49424732Sdavemq pma_pmd_dev_fd[i] = 0; 49434732Sdavemq } 49444732Sdavemq 49454977Sraghus pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i); 49464732Sdavemq 49474732Sdavemq if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 49484732Sdavemq pcs_dev_fd[i] = 1; 49494732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 49504732Sdavemq "dev found", i)); 49514782Ssbehera if (k < NXGE_PORTS_NEPTUNE) { 49524782Ssbehera port_pcs_dev_id[k] = pcs_dev_id & 49534782Ssbehera BCM_PHY_ID_MASK; 49544732Sdavemq k++; 49554732Sdavemq } 49564732Sdavemq } else { 49574732Sdavemq pcs_dev_fd[i] = 0; 49584732Sdavemq } 49594732Sdavemq 49604732Sdavemq if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) 49614732Sdavemq port_fd[i] = 1; 49624732Sdavemq else 49634732Sdavemq port_fd[i] = 0; 49644732Sdavemq total_port_fd += port_fd[i]; 49654732Sdavemq 49664977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, i); 49674732Sdavemq 49684732Sdavemq if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 49694732Sdavemq phy_fd[i] = 1; 49704732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 49714732Sdavemq "found", i)); 49724782Ssbehera if (l < NXGE_PORTS_NEPTUNE) { 49734782Ssbehera port_phy_id[l] = phy_id & BCM_PHY_ID_MASK; 49744732Sdavemq l++; 49754732Sdavemq } 49764732Sdavemq } else { 49774732Sdavemq phy_fd[i] = 0; 49784732Sdavemq } 49794732Sdavemq total_phy_fd += phy_fd[i]; 49804732Sdavemq } 49814732Sdavemq 49824732Sdavemq switch (total_port_fd) { 49834732Sdavemq case 2: 49844732Sdavemq switch (total_phy_fd) { 49854732Sdavemq case 2: 49864977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49874977Sraghus "Unsupported neptune type 1")); 49884977Sraghus goto error_exit; 49894732Sdavemq case 1: 49904732Sdavemq /* TODO - 2 10G, 1 1G */ 49914732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49924732Sdavemq "Unsupported neptune type 2 10G, 1 1G")); 49934732Sdavemq goto error_exit; 49944732Sdavemq case 0: 49954732Sdavemq /* 2 10G */ 49964782Ssbehera if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 49974782Ssbehera (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 49984782Ssbehera ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 49994782Ssbehera (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) { 50004977Sraghus 50014977Sraghus /* 50024977Sraghus * Check the first phy port address against 50034977Sraghus * the known phy start addresses to determine 50044977Sraghus * the platform type. 50054977Sraghus */ 50064977Sraghus for (i = NXGE_EXT_PHY_PORT_ST; 50074977Sraghus i < NXGE_MAX_PHY_PORTS; i++) { 50084977Sraghus if (port_fd[i] == 1) 50094977Sraghus break; 50104977Sraghus } 50114977Sraghus if (i == BCM8704_NEPTUNE_PORT_ADDR_BASE) { 50124977Sraghus hw_p->niu_type = NEPTUNE_2_10GF; 50134977Sraghus hw_p->platform_type = 50144977Sraghus P_NEPTUNE_ATLAS_2PORT; 50154977Sraghus } else { 50164977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50174977Sraghus "Unsupported neptune type 2 - 1")); 50184977Sraghus goto error_exit; 50194977Sraghus } 50204732Sdavemq hw_p->niu_type = NEPTUNE_2_10GF; 50214732Sdavemq } else { 50224732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50234732Sdavemq "Unsupported neptune type 2")); 50244732Sdavemq goto error_exit; 50254732Sdavemq } 50264732Sdavemq break; 50274732Sdavemq case 4: 50284732Sdavemq /* Maramba with 2 XAUI */ 50294782Ssbehera if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 50304782Ssbehera (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 50314782Ssbehera ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 50324782Ssbehera (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) && 50334782Ssbehera ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 50344782Ssbehera (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 50354782Ssbehera (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 50364782Ssbehera (port_phy_id[3] == PHY_BCM5464R_FAMILY))) { 50374732Sdavemq 50384732Sdavemq /* 50394732Sdavemq * Check the first phy port address against 50404732Sdavemq * the known phy start addresses to determine 50414732Sdavemq * the platform type. 50424732Sdavemq */ 50434732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 50444732Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 50454732Sdavemq if (phy_fd[i] == 1) 50464732Sdavemq break; 50474732Sdavemq } 50484732Sdavemq if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 50494732Sdavemq hw_p->platform_type = 50504732Sdavemq P_NEPTUNE_MARAMBA_P0; 50514732Sdavemq } else if (i == 50524732Sdavemq BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 50534732Sdavemq hw_p->platform_type = 50544732Sdavemq P_NEPTUNE_MARAMBA_P1; 50554732Sdavemq } else { 50564732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 50574732Sdavemq "Unknown port %d...Cannot " 50584732Sdavemq "determine platform type", i)); 50594977Sraghus goto error_exit; 50604732Sdavemq } 50614977Sraghus hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 50624977Sraghus 50634732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50644732Sdavemq "Maramba with 2 XAUI")); 50654732Sdavemq } else { 50664732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50674732Sdavemq "Unsupported neptune type 3")); 50684732Sdavemq goto error_exit; 50694732Sdavemq } 50704732Sdavemq break; 50714732Sdavemq default: 50724732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50734732Sdavemq "Unsupported neptune type 5")); 50744732Sdavemq goto error_exit; 50754732Sdavemq } 50764782Ssbehera break; 50774732Sdavemq case 1: 50784732Sdavemq switch (total_phy_fd) { 50794732Sdavemq case 3: 50804977Sraghus /* 50814977Sraghus * TODO 3 1G, 1 10G mode. 50824977Sraghus * Differentiate between 1_1G_1_10G_2_1G and 50834977Sraghus * 1_10G_3_1G 50844977Sraghus */ 50854977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50864977Sraghus "Unsupported neptune type 7")); 50874977Sraghus goto error_exit; 50884732Sdavemq case 2: 50894732Sdavemq /* 50904732Sdavemq * TODO 2 1G, 1 10G mode. 50914732Sdavemq * Differentiate between 1_1G_1_10G_1_1G and 50924732Sdavemq * 1_10G_2_1G 50934732Sdavemq */ 50944732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50954732Sdavemq "Unsupported neptune type 8")); 50964732Sdavemq goto error_exit; 50974732Sdavemq case 1: 50984732Sdavemq /* 50994732Sdavemq * TODO 1 1G, 1 10G mode. 51004732Sdavemq * Differentiate between 1_1G_1_10G and 51014732Sdavemq * 1_10G_1_1G 51024732Sdavemq */ 51034732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51044732Sdavemq "Unsupported neptune type 9")); 51054732Sdavemq goto error_exit; 51064732Sdavemq case 0: 51074732Sdavemq /* TODO 1 10G mode */ 51084732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51094732Sdavemq "Unsupported neptune type 10")); 51104732Sdavemq goto error_exit; 51114732Sdavemq case 4: 51124732Sdavemq /* Maramba with 1 XAUI */ 51134782Ssbehera if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) || 51144782Ssbehera (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY)) { 51154732Sdavemq 51164732Sdavemq /* 51174732Sdavemq * Check the first phy port address against 51184732Sdavemq * the known phy start addresses to determine 51194732Sdavemq * the platform type. 51204732Sdavemq */ 51214732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 51224732Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 51234732Sdavemq if (phy_fd[i] == 1) 51244732Sdavemq break; 51254732Sdavemq } 51264732Sdavemq 51274732Sdavemq if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 51284732Sdavemq hw_p->platform_type = 51294732Sdavemq P_NEPTUNE_MARAMBA_P0; 51304732Sdavemq } else if (i == 51314732Sdavemq BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 51324732Sdavemq hw_p->platform_type = 51334732Sdavemq P_NEPTUNE_MARAMBA_P1; 51344732Sdavemq } else { 51354732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 51364732Sdavemq "Unknown port %d...Cannot " 51374732Sdavemq "determine platform type", i)); 51384977Sraghus goto error_exit; 51394977Sraghus } 51404977Sraghus 51414977Sraghus /* The 10G port is BCM8704 */ 51424977Sraghus for (i = NXGE_EXT_PHY_PORT_ST; 51434977Sraghus i < NXGE_MAX_PHY_PORTS; i++) { 51444977Sraghus if (port_fd[i] == 1) { 51454977Sraghus prt_id = i; 51464977Sraghus break; 51474977Sraghus } 51484977Sraghus } 51494977Sraghus 51504977Sraghus prt_id %= BCM8704_MARAMBA_PORT_ADDR_BASE; 51514977Sraghus if (prt_id == 0) { 51524977Sraghus hw_p->niu_type = NEPTUNE_1_10GF_3_1GC; 51534977Sraghus } else if (prt_id == 1) { 51544977Sraghus hw_p->niu_type = 51554977Sraghus NEPTUNE_1_1GC_1_10GF_2_1GC; 51564977Sraghus } else { 51574977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51584977Sraghus "Unsupported neptune type 11")); 51594977Sraghus goto error_exit; 51604732Sdavemq } 51614732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51624732Sdavemq "Maramba with 1 XAUI")); 51634732Sdavemq } else { 51644732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51654732Sdavemq "Unsupported neptune type 12")); 51664732Sdavemq goto error_exit; 51674732Sdavemq } 51684732Sdavemq break; 51694732Sdavemq default: 51704732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51714732Sdavemq "Unsupported neptune type 13")); 51724732Sdavemq goto error_exit; 51734732Sdavemq } 51744732Sdavemq break; 51754732Sdavemq case 0: 51764732Sdavemq switch (total_phy_fd) { 51774732Sdavemq case 4: 51784782Ssbehera if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 51794782Ssbehera (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 51804782Ssbehera (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 51814782Ssbehera (port_phy_id[3] == PHY_BCM5464R_FAMILY)) { 51824732Sdavemq 51834732Sdavemq /* 51844732Sdavemq * Check the first phy port address against 51854732Sdavemq * the known phy start addresses to determine 51864732Sdavemq * the platform type. 51874732Sdavemq */ 51884732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 51894732Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 51904732Sdavemq if (phy_fd[i] == 1) 51914732Sdavemq break; 51924732Sdavemq } 51934732Sdavemq 51944732Sdavemq if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 51954732Sdavemq hw_p->platform_type = 51964732Sdavemq P_NEPTUNE_MARAMBA_P1; 51974977Sraghus } else if (i == 51984977Sraghus BCM5464_NEPTUNE_PORT_ADDR_BASE) { 51994977Sraghus hw_p->platform_type = 52004977Sraghus P_NEPTUNE_ATLAS_4PORT; 52014977Sraghus } else { 52024977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52034977Sraghus "Unknown port %d...Cannot " 52044977Sraghus "determine platform type", i)); 52054977Sraghus goto error_exit; 52064732Sdavemq } 52074977Sraghus hw_p->niu_type = NEPTUNE_4_1GC; 52084732Sdavemq } else { 52094732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 52104732Sdavemq "Unsupported neptune type 14")); 52114732Sdavemq goto error_exit; 52124732Sdavemq } 52134732Sdavemq break; 52144732Sdavemq case 3: 52154732Sdavemq /* TODO 3 1G mode */ 52164732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 52174732Sdavemq "Unsupported neptune type 15")); 52184732Sdavemq goto error_exit; 52194732Sdavemq case 2: 52204732Sdavemq /* TODO 2 1G mode */ 52214732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 52224732Sdavemq "Unsupported neptune type 16")); 52234732Sdavemq goto error_exit; 52244732Sdavemq case 1: 52254732Sdavemq /* TODO 1 1G mode */ 52264732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 52274732Sdavemq "Unsupported neptune type 17")); 52284732Sdavemq goto error_exit; 52294732Sdavemq default: 52304732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 52314732Sdavemq "Unsupported neptune type 18, total phy fd %d", 52324732Sdavemq total_phy_fd)); 52334732Sdavemq goto error_exit; 52344732Sdavemq } 52354732Sdavemq break; 52364732Sdavemq default: 52374732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 52384732Sdavemq "Unsupported neptune type 19")); 52394732Sdavemq goto error_exit; 52404732Sdavemq } 52414732Sdavemq 52424732Sdavemq scan_exit: 52434732Sdavemq 52444732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 52454732Sdavemq "niu type [0x%x]\n", hw_p->niu_type)); 52464732Sdavemq return (status); 52474732Sdavemq 52484732Sdavemq error_exit: 52494732Sdavemq return (NXGE_ERROR); 52504732Sdavemq } 52514732Sdavemq 52524185Sspeer boolean_t 52534185Sspeer nxge_is_valid_local_mac(ether_addr_st mac_addr) 52544185Sspeer { 52554185Sspeer if ((mac_addr.ether_addr_octet[0] & 0x01) || 52564185Sspeer (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 52574185Sspeer (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 52584185Sspeer return (B_FALSE); 52594185Sspeer else 52604185Sspeer return (B_TRUE); 52614185Sspeer } 52624732Sdavemq 52634732Sdavemq static void 52644732Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 52654732Sdavemq 52664732Sdavemq npi_status_t rs = NPI_SUCCESS; 52674732Sdavemq uint8_t xcvr_portn; 52684732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 52694732Sdavemq 52704732Sdavemq NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 52714732Sdavemq 52724732Sdavemq if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 52734732Sdavemq xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 52744732Sdavemq } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 52754732Sdavemq xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 52764732Sdavemq } 52774732Sdavemq /* 52784732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 52794732Sdavemq * swapped with ethernet port number. This is 52804732Sdavemq * designed for better signal integrity in routing. 52814732Sdavemq */ 52824732Sdavemq switch (portn) { 52834732Sdavemq case 0: 52844732Sdavemq xcvr_portn += 3; 52854732Sdavemq break; 52864732Sdavemq case 1: 52874732Sdavemq xcvr_portn += 2; 52884732Sdavemq break; 52894732Sdavemq case 2: 52904732Sdavemq xcvr_portn += 1; 52914732Sdavemq break; 52924732Sdavemq case 3: 52934732Sdavemq default: 52944732Sdavemq break; 52954732Sdavemq } 52964732Sdavemq 52974732Sdavemq MUTEX_ENTER(&nxge_mii_lock); 52984732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 52994732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb4ee); 53004732Sdavemq if (rs != NPI_SUCCESS) { 53014732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 53024732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 53034732Sdavemq "returned error 0x[%x]", rs)); 53044732Sdavemq MUTEX_EXIT(&nxge_mii_lock); 53054732Sdavemq return; 53064732Sdavemq } 53074732Sdavemq 53084732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 53094732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb8ee); 53104732Sdavemq if (rs != NPI_SUCCESS) { 53114732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 53124732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 53134732Sdavemq "returned error 0x[%x]", rs)); 53144732Sdavemq MUTEX_EXIT(&nxge_mii_lock); 53154732Sdavemq return; 53164732Sdavemq } 53174732Sdavemq 53184732Sdavemq MUTEX_EXIT(&nxge_mii_lock); 53194732Sdavemq } 53205196Ssbehera 53215196Ssbehera static nxge_status_t 53225196Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep) 53235196Ssbehera { 53245196Ssbehera p_nxge_stats_t statsp; 53255196Ssbehera uint8_t xcvr_portn; 53265196Ssbehera p_mii_regs_t mii_regs; 53275196Ssbehera mii_mode_control_stat_t mode; 53285196Ssbehera int status = NXGE_OK; 53295196Ssbehera 53305196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode")); 53315196Ssbehera 53325196Ssbehera statsp = nxgep->statsp; 53335196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 53345196Ssbehera mii_regs = NULL; 53355196Ssbehera mode.value = 0; 53365203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 53375196Ssbehera #if defined(__i386) 53385196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 53395196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 53405196Ssbehera mode.value)) != NXGE_OK) { 53415196Ssbehera goto fail; 53425196Ssbehera #else 53435196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 53445196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 53455196Ssbehera mode.value)) != NXGE_OK) { 53465196Ssbehera goto fail; 53475196Ssbehera #endif 53485196Ssbehera } 53495196Ssbehera #if defined(__i386) 53505196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 53515196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 53525196Ssbehera &mode.value)) != NXGE_OK) { 53535196Ssbehera goto fail; 53545196Ssbehera } 53555196Ssbehera #else 53565196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 53575196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 53585196Ssbehera &mode.value)) != NXGE_OK) { 53595196Ssbehera goto fail; 53605196Ssbehera } 53615196Ssbehera #endif 53625196Ssbehera 53635196Ssbehera if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) { 53645196Ssbehera nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 53655196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 53665196Ssbehera "nxge_mii_get_link_mode: fiber mode")); 53675196Ssbehera } 53685196Ssbehera 53695196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 53705196Ssbehera "nxge_mii_get_link_mode: " 53715196Ssbehera "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x", 53725203Ssbehera NXGE_MII_MODE_CONTROL_REG, xcvr_portn, 53735196Ssbehera mode.value, nxgep->mac.portmode)); 53745196Ssbehera 53755196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 53765196Ssbehera "<== nxge_mii_get_link_mode")); 53775196Ssbehera return (status); 53785196Ssbehera fail: 53795196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 53805196Ssbehera "<== nxge_mii_get_link_mode (failed)")); 53815196Ssbehera return (NXGE_ERROR); 53825196Ssbehera } 53835196Ssbehera 53845196Ssbehera #ifdef NXGE_DEBUG 53855196Ssbehera static void 53865196Ssbehera nxge_mii_dump(p_nxge_t nxgep) 53875196Ssbehera { 53885196Ssbehera p_nxge_stats_t statsp; 53895196Ssbehera uint8_t xcvr_portn; 53905196Ssbehera p_mii_regs_t mii_regs; 53915196Ssbehera mii_bmcr_t bmcr; 53925196Ssbehera mii_bmsr_t bmsr; 53935196Ssbehera mii_idr1_t idr1; 53945196Ssbehera mii_idr2_t idr2; 53955196Ssbehera mii_mode_control_stat_t mode; 53965196Ssbehera 53975196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump")); 53985196Ssbehera 53995196Ssbehera param_arr = nxgep->param_arr; 54005196Ssbehera statsp = nxgep->statsp; 54015196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 54025196Ssbehera 54035196Ssbehera mii_regs = NULL; 54045196Ssbehera 54055196Ssbehera #if defined(__i386) 54065196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 54075196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value); 54085196Ssbehera #else 54095196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 54105196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value); 54115196Ssbehera #endif 54125196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 54135196Ssbehera "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x", 54145196Ssbehera xcvr_portn, bmcr.value)); 54155196Ssbehera 54165196Ssbehera #if defined(__i386) 54175196Ssbehera (void) nxge_mii_read(nxgep, 54185196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 54195196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value); 54205196Ssbehera #else 54215196Ssbehera (void) nxge_mii_read(nxgep, 54225196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 54235196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value); 54245196Ssbehera #endif 54255196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 54265196Ssbehera "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x", 54275196Ssbehera xcvr_portn, bmsr.value)); 54285196Ssbehera 54295196Ssbehera #if defined(__i386) 54305196Ssbehera (void) nxge_mii_read(nxgep, 54315196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 54325196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value); 54335196Ssbehera #else 54345196Ssbehera (void) nxge_mii_read(nxgep, 54355196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 54365196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value); 54375196Ssbehera #endif 54385196Ssbehera 54395196Ssbehera 54405196Ssbehera #if defined(__i386) 54415196Ssbehera (void) nxge_mii_read(nxgep, 54425196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 54435196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value); 54445196Ssbehera #else 54455196Ssbehera (void) nxge_mii_read(nxgep, 54465196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 54475196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value); 54485196Ssbehera #endif 54495196Ssbehera 54505196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 54515196Ssbehera "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x", 54525196Ssbehera xcvr_portn, idr1.value)); 54535196Ssbehera 54545196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 54555196Ssbehera "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x", 54565196Ssbehera xcvr_portn, idr2.value)); 54575196Ssbehera 54585196Ssbehera mode.value = 0; 54595203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 54605196Ssbehera 54615196Ssbehera #if defined(__i386) 54625196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 54635196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value); 54645196Ssbehera 54655196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 54665196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value); 54675196Ssbehera #else 54685196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 54695196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value); 54705196Ssbehera 54715196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 54725196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value); 54735196Ssbehera #endif 54745196Ssbehera 54755196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 54765196Ssbehera "nxge_mii_dump: mode control xcvr 0x%x value 0x%x", 54775196Ssbehera xcvr_portn, mode.value)); 54785196Ssbehera } 54795196Ssbehera #endif 5480