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 /* 22*9232SMichael.Speer@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 233859Sml29623 * Use is subject to license terms. 243859Sml29623 */ 253859Sml29623 263859Sml29623 #include <sys/nxge/nxge_impl.h> 273859Sml29623 #include <sys/nxge/nxge_mac.h> 286495Sspeer #include <sys/nxge/nxge_hio.h> 293859Sml29623 304693Stm144005 #define LINK_MONITOR_PERIOD (1000 * 1000) 314693Stm144005 #define LM_WAIT_MULTIPLIER 8 324693Stm144005 336075Ssbehera #define SERDES_RDY_WT_INTERVAL 50 346075Ssbehera #define MAX_SERDES_RDY_RETRIES 10 356075Ssbehera 366835Syc148097 #define TN1010_SPEED_1G 1 376835Syc148097 #define TN1010_SPEED_10G 0 386835Syc148097 #define TN1010_AN_IN_PROG 0 /* Auto negotiation in progress */ 396835Syc148097 #define TN1010_AN_COMPLETE 1 406835Syc148097 #define TN1010_AN_RSVD 2 416835Syc148097 #define TN1010_AN_FAILED 3 426835Syc148097 433859Sml29623 extern uint32_t nxge_no_link_notify; 444732Sdavemq extern boolean_t nxge_no_msg; 453859Sml29623 extern uint32_t nxge_lb_dbg; 463859Sml29623 extern boolean_t nxge_jumbo_enable; 476028Ssbehera extern uint32_t nxge_jumbo_mtu; 483859Sml29623 496495Sspeer 504693Stm144005 typedef enum { 514693Stm144005 CHECK_LINK_RESCHEDULE, 524693Stm144005 CHECK_LINK_STOP 534693Stm144005 } check_link_state_t; 544693Stm144005 554693Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *); 564693Stm144005 573859Sml29623 /* 583859Sml29623 * Ethernet broadcast address definition. 593859Sml29623 */ 603859Sml29623 static ether_addr_st etherbroadcastaddr = 613859Sml29623 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 624732Sdavemq /* 634732Sdavemq * Ethernet zero address definition. 644732Sdavemq */ 654185Sspeer static ether_addr_st etherzeroaddr = 664185Sspeer {{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; 674732Sdavemq /* 684732Sdavemq * Supported chip types 694732Sdavemq */ 706604Ssbehera static uint32_t nxge_supported_cl45_ids[] = { 716604Ssbehera BCM8704_DEV_ID, 726604Ssbehera MARVELL_88X_201X_DEV_ID, 736835Syc148097 BCM8706_DEV_ID, 746835Syc148097 TN1010_DEV_ID 756604Ssbehera }; 766604Ssbehera 776909Sml29623 static uint32_t nxge_supported_cl22_ids[] = { 786909Sml29623 BCM5464R_PHY_ID, 796909Sml29623 BCM5482_PHY_ID 806909Sml29623 }; 814732Sdavemq 824732Sdavemq #define NUM_CLAUSE_45_IDS (sizeof (nxge_supported_cl45_ids) / \ 834732Sdavemq sizeof (uint32_t)) 844732Sdavemq #define NUM_CLAUSE_22_IDS (sizeof (nxge_supported_cl22_ids) / \ 854732Sdavemq sizeof (uint32_t)) 864732Sdavemq /* 874732Sdavemq * static functions 884732Sdavemq */ 894977Sraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int); 904977Sraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int); 914977Sraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int); 924732Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t); 935572Ssbehera static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t); 944732Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t); 954732Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t); 964732Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t); 974732Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t); 984732Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t); 994732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t); 1004732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t); 1014732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t); 1024732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t); 1034732Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t); 1044732Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t); 1054732Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t); 1065572Ssbehera static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t); 1075572Ssbehera static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t); 1084732Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t); 1094732Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t); 1106835Syc148097 static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *); 1116604Ssbehera static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t); 1126835Syc148097 static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id, 1136835Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui); 1146835Syc148097 static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed); 1156835Syc148097 static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep); 1166835Syc148097 static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep, 1176835Syc148097 nxge_link_state_t *link_up); 1186835Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep); 1196835Syc148097 static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep); 1206835Syc148097 1216835Syc148097 nxge_status_t nxge_mac_init(p_nxge_t); 1226835Syc148097 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t); 1236835Syc148097 1246835Syc148097 #ifdef NXGE_DEBUG 1256835Syc148097 static void nxge_mii_dump(p_nxge_t); 1266835Syc148097 static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep); 1276835Syc148097 static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep); 1286835Syc148097 #endif 1294732Sdavemq 1304732Sdavemq /* 1314732Sdavemq * xcvr tables for supported transceivers 1324732Sdavemq */ 1334732Sdavemq 1346835Syc148097 /* 1356835Syc148097 * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems. 1366835Syc148097 * The Teranetics TN1010 based copper XAUI card can also be used 1376835Syc148097 * on N2-NIU systems in 10G mode, but it uses its own table 1386835Syc148097 * nxge_n2_10G_tn1010_table below. 1396835Syc148097 */ 1404977Sraghus static nxge_xcvr_table_t nxge_n2_10G_table = { 1414732Sdavemq nxge_n2_serdes_init, 1424732Sdavemq nxge_10G_xcvr_init, 1434732Sdavemq nxge_10G_link_intr_stop, 1444732Sdavemq nxge_10G_link_intr_start, 1454732Sdavemq nxge_check_10g_link, 1465572Ssbehera PCS_XCVR 1474732Sdavemq }; 1484732Sdavemq 1496835Syc148097 /* 1506835Syc148097 * For the Teranetics TN1010 based copper XAUI card 1516835Syc148097 */ 1526835Syc148097 static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = { 1536835Syc148097 nxge_n2_serdes_init, /* Handle both 1G and 10G */ 1546835Syc148097 nxge_tn1010_xcvr_init, /* Handle both 1G and 10G */ 1556835Syc148097 nxge_10G_link_intr_stop, 1566835Syc148097 nxge_10G_link_intr_start, 1576835Syc148097 nxge_check_tn1010_link, /* Will figure out speed */ 1586835Syc148097 XPCS_XCVR 1596835Syc148097 }; 1606835Syc148097 1614977Sraghus static nxge_xcvr_table_t nxge_n2_1G_table = { 1624977Sraghus nxge_n2_serdes_init, 1634977Sraghus nxge_1G_xcvr_init, 1644977Sraghus nxge_1G_fiber_link_intr_stop, 1654977Sraghus nxge_1G_fiber_link_intr_start, 1664977Sraghus nxge_check_mii_link, 1675572Ssbehera PCS_XCVR 1684977Sraghus }; 1694977Sraghus 1706835Syc148097 static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = { 1716835Syc148097 nxge_n2_serdes_init, 1726835Syc148097 nxge_tn1010_xcvr_init, 1736835Syc148097 nxge_1G_fiber_link_intr_stop, /* TN1010 is a Cu PHY, but it uses */ 1746835Syc148097 nxge_1G_fiber_link_intr_start, /* PCS for 1G, so call fiber func */ 1756835Syc148097 nxge_check_tn1010_link, 1766835Syc148097 PCS_XCVR 1776835Syc148097 }; 1786835Syc148097 1796835Syc148097 static nxge_xcvr_table_t nxge_10G_tn1010_table = { 1806835Syc148097 nxge_neptune_10G_serdes_init, 1816835Syc148097 nxge_tn1010_xcvr_init, 1826835Syc148097 nxge_10G_link_intr_stop, 1836835Syc148097 nxge_10G_link_intr_start, 1846835Syc148097 nxge_check_tn1010_link, 1856835Syc148097 XPCS_XCVR 1866835Syc148097 }; 1876835Syc148097 1886835Syc148097 static nxge_xcvr_table_t nxge_1G_tn1010_table = { 1896835Syc148097 nxge_1G_serdes_init, 1906835Syc148097 nxge_tn1010_xcvr_init, 1916835Syc148097 nxge_1G_fiber_link_intr_stop, 1926835Syc148097 nxge_1G_fiber_link_intr_start, 1936835Syc148097 nxge_check_tn1010_link, 1946835Syc148097 PCS_XCVR 1956835Syc148097 }; 1966835Syc148097 1974732Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = { 1984732Sdavemq nxge_neptune_10G_serdes_init, 1994732Sdavemq nxge_10G_xcvr_init, 2004732Sdavemq nxge_10G_link_intr_stop, 2014732Sdavemq nxge_10G_link_intr_start, 2024732Sdavemq nxge_check_10g_link, 2035572Ssbehera PCS_XCVR 2044732Sdavemq }; 2054732Sdavemq 2064732Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = { 2074732Sdavemq NULL, 2084732Sdavemq nxge_1G_xcvr_init, 2094732Sdavemq nxge_1G_copper_link_intr_stop, 2104732Sdavemq nxge_1G_copper_link_intr_start, 2114732Sdavemq nxge_check_mii_link, 2125572Ssbehera INT_MII_XCVR 2134732Sdavemq }; 2144732Sdavemq 2156835Syc148097 /* This table is for Neptune portmode == PORT_1G_SERDES cases */ 2164732Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = { 2174732Sdavemq nxge_1G_serdes_init, 2184732Sdavemq nxge_1G_xcvr_init, 2194732Sdavemq nxge_1G_fiber_link_intr_stop, 2204732Sdavemq nxge_1G_fiber_link_intr_start, 2214732Sdavemq nxge_check_mii_link, 2225572Ssbehera PCS_XCVR 2234732Sdavemq }; 2244732Sdavemq 2254732Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = { 2264732Sdavemq nxge_neptune_10G_serdes_init, 2274732Sdavemq NULL, 2284732Sdavemq NULL, 2294732Sdavemq NULL, 2304977Sraghus NULL, 2315572Ssbehera PCS_XCVR 2324732Sdavemq }; 2333859Sml29623 2346835Syc148097 /* 2356835Syc148097 * NXGE_PORT_TN1010 is defined as, 2366835Syc148097 * NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT) 2376835Syc148097 * = 0 | 5 << 16 = 0x50000 2386835Syc148097 * 2396835Syc148097 * So NEPTUNE_2_TN1010 = 2406835Syc148097 * (NXGE_PORT_TN1010 | 2416835Syc148097 * (NXGE_PORT_TN1010 << 4) | 2426835Syc148097 * (NXGE_PORT_NONE << 8) | 2436835Syc148097 * (NXGE_PORT_NONE << 12)), 2446835Syc148097 * = 0x50000 | (0x50000 << 4) 2456835Syc148097 * = 0x550000 2466835Syc148097 * 2476835Syc148097 * This function partitions nxgep->nxge_hw_p->niu_type (which may have 2486835Syc148097 * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010 2496835Syc148097 * = 0x50000 2506835Syc148097 */ 2516835Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep) 2526835Syc148097 { 2536835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2546835Syc148097 2556835Syc148097 if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn)) 2566835Syc148097 & NXGE_PHY_MASK) == NXGE_PORT_TN1010) { 2576835Syc148097 return (B_TRUE); 2586835Syc148097 } else { 2596835Syc148097 return (B_FALSE); 2606835Syc148097 } 2616835Syc148097 } 2626835Syc148097 2636835Syc148097 2646835Syc148097 /* 2656835Syc148097 * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties, 2666835Syc148097 * serial EEPROM or VPD if possible. Note that not all systems could get 2676835Syc148097 * the portmode information by calling this function. For example, the 2686835Syc148097 * Maramba system figures out the portmode information by calling function 2696835Syc148097 * nxge_setup_xcvr_table. 2706835Syc148097 */ 2714977Sraghus nxge_status_t 2724977Sraghus nxge_get_xcvr_type(p_nxge_t nxgep) 2734977Sraghus { 2744977Sraghus nxge_status_t status = NXGE_OK; 2754977Sraghus char *phy_type; 2764977Sraghus char *prop_val; 2776835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2784977Sraghus 2794977Sraghus nxgep->mac.portmode = 0; 2805572Ssbehera nxgep->xcvr_addr = 0; 2815572Ssbehera 2825572Ssbehera /* 2835572Ssbehera * First check for hot swappable phy property. 2845572Ssbehera */ 2855572Ssbehera if (nxgep->hot_swappable_phy == B_TRUE) { 2865572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 2875572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE; 2885572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable")); 2895572Ssbehera } else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 2905572Ssbehera DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 2915572Ssbehera "hot-swappable-phy") == 1) { 2925572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 2935572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE; 2945572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable")); 2955572Ssbehera } else if (nxgep->niu_type == N2_NIU && 2965572Ssbehera ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0, 2975572Ssbehera "hot-swappable-phy") == 1) { 2985572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 2995572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE; 3005572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable")); 3015572Ssbehera } 3025572Ssbehera 3035572Ssbehera /* 3045572Ssbehera * MDIO polling support for Monza RTM card, Goa NEM card 3055572Ssbehera */ 3065572Ssbehera if (nxgep->mac.portmode == PORT_HSP_MODE) { 3075572Ssbehera nxgep->hot_swappable_phy = B_TRUE; 3085572Ssbehera /* 3095572Ssbehera * If this is the 2nd NIU port, then check 2 addresses 3105572Ssbehera * to take care of the Goa NEM card. Port 1 can have addr 17 3115572Ssbehera * (in the eval board) or 20 (in the P0 board). 3125572Ssbehera */ 3135572Ssbehera if (portn == 1) { 3145572Ssbehera if (nxge_is_phy_present(nxgep, 3156835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR, BCM8706_DEV_ID, 3165572Ssbehera BCM_PHY_ID_MASK)) { 3175572Ssbehera nxgep->xcvr_addr = 3186835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR; 3195572Ssbehera goto found_phy; 3205572Ssbehera } 3215572Ssbehera } 3225572Ssbehera if (nxge_is_phy_present(nxgep, 3236835Syc148097 GOA_CLAUSE45_PORT_ADDR_BASE + portn, 3245572Ssbehera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 3256835Syc148097 nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE + 3265572Ssbehera portn; 3275572Ssbehera goto found_phy; 3285572Ssbehera } 3295572Ssbehera 3305572Ssbehera nxgep->phy_absent = B_TRUE; 3315572Ssbehera goto check_phy_done; 3325572Ssbehera found_phy: 3335572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3345572Ssbehera nxgep->mac.portmode = PORT_10G_FIBER; 3355572Ssbehera nxgep->phy_absent = B_FALSE; 3365572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr " 3375572Ssbehera "found for hot swappable phy")); 3385572Ssbehera check_phy_done: 3395572Ssbehera return (status); 3405572Ssbehera } 3415572Ssbehera 3426835Syc148097 /* Get phy-type property (May have been set by nxge.conf) */ 3434977Sraghus if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 3444977Sraghus DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 3454977Sraghus "phy-type", &prop_val)) == DDI_PROP_SUCCESS) { 3464977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3474977Sraghus "found conf file: phy-type %s", prop_val)); 3484977Sraghus if (strcmp("xgsd", prop_val) == 0) { 3494977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3504977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 3514977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3524977Sraghus "found: 10G Serdes")); 3534977Sraghus } else if (strcmp("gsd", prop_val) == 0) { 3544977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3554977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 3564977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes")); 3574977Sraghus } else if (strcmp("mif", prop_val) == 0) { 3584977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3594977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 3604977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 3614977Sraghus } else if (strcmp("pcs", prop_val) == 0) { 3624977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3634977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 3644977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr")); 3656075Ssbehera } else if (strcmp("xgf", prop_val) == 0) { 3666835Syc148097 /* 3676835Syc148097 * Before OBP supports new phy-type property 3686835Syc148097 * value "xgc", the 10G copper XAUI may carry 3696835Syc148097 * "xgf" instead of "xgc". If the OBP is 3706835Syc148097 * upgraded to a newer version which supports 3716835Syc148097 * "xgc", then the TN1010 related code in this 3726835Syc148097 * "xgf" case will not be used anymore. 3736835Syc148097 */ 3746835Syc148097 if (nxge_is_tn1010_phy(nxgep)) { 3756835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) 3766835Syc148097 != NXGE_OK) { 3776835Syc148097 return (status); 3786835Syc148097 } 3796835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 3806835Syc148097 } else { /* For Fiber XAUI */ 3816835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3826835Syc148097 nxgep->mac.portmode = PORT_10G_FIBER; 3836835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3846835Syc148097 "10G Fiber Xcvr")); 3856835Syc148097 } 3866835Syc148097 } else if (strcmp("xgc", prop_val) == 0) { 3876835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK) 3886835Syc148097 return (status); 3896835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 3904977Sraghus } 3914977Sraghus 3924977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 3934977Sraghus "phy-type", prop_val); 3944977Sraghus ddi_prop_free(prop_val); 3954977Sraghus 3964977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 3974977Sraghus "Got phy type [0x%x] from conf file", 3984977Sraghus nxgep->mac.portmode)); 3994977Sraghus 4004977Sraghus return (NXGE_OK); 4014977Sraghus } 4025572Ssbehera 4035572Ssbehera /* Get phy-type property from OBP */ 4044977Sraghus if (nxgep->niu_type == N2_NIU) { 4054977Sraghus if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 4064977Sraghus "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 4074977Sraghus if (strcmp("xgf", prop_val) == 0) { 4086835Syc148097 /* 4096835Syc148097 * Before OBP supports new phy-type property 4106835Syc148097 * value "xgc", the 10G copper XAUI may carry 4116835Syc148097 * "xgf" instead of "xgc". If the OBP is 4126835Syc148097 * upgraded to a newer version which supports 4136835Syc148097 * "xgc", then the TN1010 related code in this 4146835Syc148097 * "xgf" case will not be used anymore. 4156835Syc148097 */ 4166835Syc148097 if (nxge_is_tn1010_phy(nxgep)) { 4176835Syc148097 if ((status = 4186835Syc148097 nxge_set_tn1010_param(nxgep)) 4196835Syc148097 != NXGE_OK) { 4206835Syc148097 return (status); 4216835Syc148097 } 4226835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4236835Syc148097 "TN1010 Xcvr")); 4246835Syc148097 } else { /* For Fiber XAUI */ 4256835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse 4266835Syc148097 = XPCS_XCVR; 4276835Syc148097 nxgep->mac.portmode = PORT_10G_FIBER; 4286835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4296835Syc148097 "10G Fiber Xcvr")); 4306835Syc148097 } 4314977Sraghus } else if (strcmp("mif", prop_val) == 0) { 4324977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = 4334977Sraghus INT_MII_XCVR; 4344977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 4354977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4364977Sraghus "1G Copper Xcvr")); 4374977Sraghus } else if (strcmp("pcs", prop_val) == 0) { 4384977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 4394977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 4404977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4414977Sraghus "1G Fiber Xcvr")); 4424977Sraghus } else if (strcmp("xgc", prop_val) == 0) { 4436835Syc148097 status = nxge_set_tn1010_param(nxgep); 4446835Syc148097 if (status != NXGE_OK) 4456835Syc148097 return (status); 4466835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 4474977Sraghus } else if (strcmp("xgsd", prop_val) == 0) { 4484977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 4494977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 4504977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4514977Sraghus "OBP: 10G Serdes")); 4524977Sraghus } else if (strcmp("gsd", prop_val) == 0) { 4534977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 4544977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 4554977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4564977Sraghus "OBP: 1G Serdes")); 4574977Sraghus } else { 4584977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4594977Sraghus "Unknown phy-type: %s", prop_val)); 4604977Sraghus ddi_prop_free(prop_val); 4614977Sraghus return (NXGE_ERROR); 4624977Sraghus } 4634977Sraghus status = NXGE_OK; 4644977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, 4654977Sraghus nxgep->dip, "phy-type", prop_val); 4664977Sraghus ddi_prop_free(prop_val); 4674977Sraghus 4684977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 4694977Sraghus "Got phy type [0x%x] from OBP", 4704977Sraghus nxgep->mac.portmode)); 4714977Sraghus 4724977Sraghus return (status); 4734977Sraghus } else { 4744977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4754977Sraghus "Exiting...phy-type property not found")); 4764977Sraghus return (NXGE_ERROR); 4774977Sraghus } 4784977Sraghus } 4794977Sraghus 4804977Sraghus 4814977Sraghus if (!nxgep->vpd_info.present) { 4824977Sraghus return (NXGE_OK); 4834977Sraghus } 4844977Sraghus 4854977Sraghus if (!nxgep->vpd_info.ver_valid) { 4864977Sraghus goto read_seeprom; 4874977Sraghus } 4884977Sraghus 4894977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4904977Sraghus "Reading phy type from expansion ROM")); 4914977Sraghus /* 4924977Sraghus * Try to read the phy type from the vpd data read off the 4934977Sraghus * expansion ROM. 4944977Sraghus */ 4954977Sraghus phy_type = nxgep->vpd_info.phy_type; 4964977Sraghus 4975196Ssbehera if (strncmp(phy_type, "mif", 3) == 0) { 4984977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 4994977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 5005196Ssbehera } else if (strncmp(phy_type, "xgf", 3) == 0) { 5014977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 5024977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 5035196Ssbehera } else if (strncmp(phy_type, "pcs", 3) == 0) { 5044977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 5054977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 5065196Ssbehera } else if (strncmp(phy_type, "xgc", 3) == 0) { 5076835Syc148097 status = nxge_set_tn1010_param(nxgep); 5086835Syc148097 if (status != NXGE_OK) { 5096835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5106835Syc148097 "nxge_get_xcvr_type: Failed to set TN1010 param")); 5116835Syc148097 goto read_seeprom; 5126835Syc148097 } 5135196Ssbehera } else if (strncmp(phy_type, "xgsd", 4) == 0) { 5145196Ssbehera nxgep->mac.portmode = PORT_10G_SERDES; 5155196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 5165196Ssbehera } else if (strncmp(phy_type, "gsd", 3) == 0) { 5175196Ssbehera nxgep->mac.portmode = PORT_1G_SERDES; 5185196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 5194977Sraghus } else { 5205196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5214977Sraghus "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM", 5224977Sraghus phy_type[0], phy_type[1], phy_type[2])); 5234977Sraghus goto read_seeprom; 5244977Sraghus } 5254977Sraghus 5264977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 5274977Sraghus "Got phy type [0x%x] from VPD", nxgep->mac.portmode)); 5284977Sraghus 5294977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 5304977Sraghus return (status); 5314977Sraghus 5324977Sraghus read_seeprom: 5334977Sraghus /* 5344977Sraghus * read the phy type from the SEEPROM - NCR registers 5354977Sraghus */ 5364977Sraghus status = nxge_espc_phy_type_get(nxgep); 5374977Sraghus if (status != NXGE_OK) { 5384977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5394977Sraghus "Failed to get phy type")); 5404977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 5414977Sraghus "[%s] invalid...please update", nxgep->vpd_info.ver)); 5424977Sraghus } 5434977Sraghus 5444977Sraghus return (status); 5454977Sraghus 5464977Sraghus } 5474977Sraghus 5484732Sdavemq /* Set up the PHY specific values. */ 5494732Sdavemq 5504732Sdavemq nxge_status_t 5514732Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep) 5524732Sdavemq { 5534732Sdavemq nxge_status_t status = NXGE_OK; 5544732Sdavemq uint32_t port_type; 5554732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 5564977Sraghus uint32_t pcs_id = 0; 5574977Sraghus uint32_t pma_pmd_id = 0; 5584977Sraghus uint32_t phy_id = 0; 5595572Ssbehera uint16_t chip_id = 0; 5604732Sdavemq 5614732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>", 5624732Sdavemq portn)); 5634732Sdavemq 5644977Sraghus switch (nxgep->niu_type) { 5654977Sraghus case N2_NIU: 5664977Sraghus switch (nxgep->mac.portmode) { 5674977Sraghus case PORT_1G_FIBER: 5684977Sraghus case PORT_1G_SERDES: 5694977Sraghus nxgep->xcvr = nxge_n2_1G_table; 5705572Ssbehera nxgep->xcvr_addr = portn; 5714977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr", 5724977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" : 5734977Sraghus "Serdes")); 5744977Sraghus break; 5754977Sraghus case PORT_10G_FIBER: 5764977Sraghus case PORT_10G_SERDES: 5774977Sraghus nxgep->xcvr = nxge_n2_10G_table; 5785572Ssbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) { 5795572Ssbehera nxgep->xcvr_addr = 5805572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn]; 5815572Ssbehera } 5824977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr", 5834977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" : 5844977Sraghus "Serdes")); 5854977Sraghus break; 5866835Syc148097 case PORT_1G_TN1010: 5876835Syc148097 nxgep->xcvr = nxge_n2_1G_tn1010_table; 5886835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 5896835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5906835Syc148097 "TN1010 Copper Xcvr in 1G")); 5916835Syc148097 break; 5926835Syc148097 case PORT_10G_TN1010: 5936835Syc148097 nxgep->xcvr = nxge_n2_10G_tn1010_table; 5946835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 5956835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5966835Syc148097 "TN1010 Copper Xcvr in 10G")); 5976835Syc148097 break; 5985572Ssbehera case PORT_HSP_MODE: 5995572Ssbehera nxgep->xcvr = nxge_n2_10G_table; 6005572Ssbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR; 6015572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot " 6025572Ssbehera "Swappable Xcvr (not present)")); 6035572Ssbehera break; 6044977Sraghus default: 6054977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6064977Sraghus "<== nxge_setup_xcvr_table: " 6074977Sraghus "Unable to determine NIU portmode")); 6084977Sraghus return (NXGE_ERROR); 6094977Sraghus } 6104977Sraghus break; 6114977Sraghus default: 6124977Sraghus if (nxgep->mac.portmode == 0) { 6134977Sraghus /* 6144977Sraghus * Would be the case for platforms like Maramba 6154977Sraghus * in which the phy type could not be got from conf 6164977Sraghus * file, OBP, VPD or Serial PROM. 6174977Sraghus */ 6184977Sraghus if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 6194977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6204977Sraghus "<== nxge_setup_xcvr_table:" 6214977Sraghus " Invalid Neptune type [0x%x]", 6224977Sraghus nxgep->niu_type)); 6234977Sraghus return (NXGE_ERROR); 6244977Sraghus } 6254977Sraghus 6264977Sraghus port_type = nxgep->niu_type >> 6274977Sraghus (NXGE_PORT_TYPE_SHIFT * portn); 6284977Sraghus port_type = port_type & (NXGE_PORT_TYPE_MASK); 6294977Sraghus 6304977Sraghus switch (port_type) { 6314977Sraghus 6324977Sraghus case NXGE_PORT_1G_COPPER: 6334977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 6344977Sraghus break; 6354977Sraghus case NXGE_PORT_10G_COPPER: 6364977Sraghus nxgep->mac.portmode = PORT_10G_COPPER; 6374977Sraghus break; 6384977Sraghus case NXGE_PORT_1G_FIBRE: 6394977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 6404977Sraghus break; 6414977Sraghus case NXGE_PORT_10G_FIBRE: 6424977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 6434977Sraghus break; 6444977Sraghus case NXGE_PORT_1G_SERDES: 6454977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 6464977Sraghus break; 6474977Sraghus case NXGE_PORT_10G_SERDES: 6484977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 6494977Sraghus break; 6506835Syc148097 /* Ports 2 and 3 of Alonso or ARTM */ 6514977Sraghus case NXGE_PORT_1G_RGMII_FIBER: 6524977Sraghus nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 6534977Sraghus break; 6546835Syc148097 case NXGE_PORT_TN1010: 6556835Syc148097 /* 6566835Syc148097 * If this port uses the TN1010 copper 6576835Syc148097 * PHY, then its speed is not known yet 6586835Syc148097 * because nxge_scan_ports_phy could only 6596835Syc148097 * figure out the vendor of the PHY but 6606835Syc148097 * not its speed. nxge_set_tn1010_param 6616835Syc148097 * will read the PHY speed and set 6626835Syc148097 * portmode accordingly. 6636835Syc148097 */ 6646835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) 6656835Syc148097 != NXGE_OK) { 6666835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6676835Syc148097 "nxge_set_tn1010_param failed")); 6686835Syc148097 return (status); 6696835Syc148097 } 6706835Syc148097 break; 6714977Sraghus default: 6724977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6734977Sraghus "<== nxge_setup_xcvr_table: " 6744977Sraghus "Unknown port-type: 0x%x", port_type)); 6754977Sraghus return (NXGE_ERROR); 6764977Sraghus } 6774977Sraghus } 6784977Sraghus 6796835Syc148097 /* 6806835Syc148097 * Above switch has figured out nxge->mac.portmode, now set 6816835Syc148097 * nxgep->xcvr (the table) and nxgep->xcvr_addr according 6826835Syc148097 * to portmode. 6836835Syc148097 */ 6844977Sraghus switch (nxgep->mac.portmode) { 6854977Sraghus case PORT_1G_COPPER: 6864977Sraghus case PORT_1G_RGMII_FIBER: 6874732Sdavemq nxgep->xcvr = nxge_1G_copper_table; 6885572Ssbehera nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 6894732Sdavemq /* 6904732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 6914732Sdavemq * swapped with ethernet port number. This is 6924977Sraghus * designed for better signal integrity in 6934977Sraghus * routing. This is also the case for the 6944977Sraghus * on-board Neptune copper ports on the Maramba 6954977Sraghus * platform. 6964732Sdavemq */ 6974977Sraghus switch (nxgep->platform_type) { 6984977Sraghus case P_NEPTUNE_ATLAS_4PORT: 6994977Sraghus case P_NEPTUNE_MARAMBA_P0: 7004977Sraghus case P_NEPTUNE_MARAMBA_P1: 7014977Sraghus switch (portn) { 7024977Sraghus case 0: 7035572Ssbehera nxgep->xcvr_addr += 3; 7044977Sraghus break; 7054977Sraghus case 1: 7065572Ssbehera nxgep->xcvr_addr += 1; 7074977Sraghus break; 7084977Sraghus case 2: 7095572Ssbehera nxgep->xcvr_addr -= 1; 7104977Sraghus break; 7114977Sraghus case 3: 7125572Ssbehera nxgep->xcvr_addr -= 3; 7134977Sraghus break; 7144977Sraghus default: 7154977Sraghus return (NXGE_ERROR); 7164977Sraghus } 7174732Sdavemq break; 7184732Sdavemq default: 7194977Sraghus break; 7204732Sdavemq } 7215196Ssbehera 7224977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 7234977Sraghus (nxgep->mac.portmode == PORT_1G_COPPER) ? 7244977Sraghus "Copper" : "RGMII Fiber")); 7254732Sdavemq break; 7266835Syc148097 7274977Sraghus case PORT_10G_COPPER: 7284732Sdavemq nxgep->xcvr = nxge_10G_copper_table; 7294732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 7304732Sdavemq break; 7316835Syc148097 7326835Syc148097 case PORT_1G_TN1010: 7336835Syc148097 nxgep->xcvr = nxge_1G_tn1010_table; 7346835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 7356835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7366835Syc148097 "1G TN1010 copper Xcvr")); 7376835Syc148097 break; 7386835Syc148097 7396835Syc148097 case PORT_10G_TN1010: 7406835Syc148097 nxgep->xcvr = nxge_10G_tn1010_table; 7416835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 7426835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7436835Syc148097 "10G TN1010 copper Xcvr")); 7446835Syc148097 break; 7456835Syc148097 7464977Sraghus case PORT_1G_FIBER: 7474977Sraghus case PORT_1G_SERDES: 7484732Sdavemq nxgep->xcvr = nxge_1G_fiber_table; 7495572Ssbehera nxgep->xcvr_addr = portn; 7504977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 7514977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? 7524977Sraghus "Fiber" : "Serdes")); 7534732Sdavemq break; 7544977Sraghus case PORT_10G_FIBER: 7554977Sraghus case PORT_10G_SERDES: 7564732Sdavemq nxgep->xcvr = nxge_10G_fiber_table; 7575572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr " 7585572Ssbehera "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] " 7595572Ssbehera "nxgep->xcvr_addr = [%d]", 7605572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn], 7615572Ssbehera nxgep->xcvr_addr)); 7625572Ssbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) { 7635572Ssbehera nxgep->xcvr_addr = 7645572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn]; 7655572Ssbehera } 7664977Sraghus switch (nxgep->platform_type) { 7674977Sraghus case P_NEPTUNE_MARAMBA_P0: 7684977Sraghus case P_NEPTUNE_MARAMBA_P1: 7694732Sdavemq /* 7704732Sdavemq * Switch off LED for corresponding copper 7714732Sdavemq * port 7724732Sdavemq */ 7734732Sdavemq nxge_bcm5464_link_led_off(nxgep); 7744977Sraghus break; 7754977Sraghus default: 7764977Sraghus break; 7774732Sdavemq } 7784977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr", 7794977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? 7804977Sraghus "Fiber" : "Serdes")); 7814732Sdavemq break; 7825572Ssbehera 7835572Ssbehera case PORT_HSP_MODE: 7845572Ssbehera nxgep->xcvr = nxge_10G_fiber_table; 7855572Ssbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR; 7865572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot " 7875572Ssbehera "Swappable Xcvr (not present)")); 7885572Ssbehera break; 7894732Sdavemq default: 7904732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 7914732Sdavemq "Unknown port-type: 0x%x", port_type)); 7924732Sdavemq return (NXGE_ERROR); 7934732Sdavemq } 7944732Sdavemq } 7954732Sdavemq 7965572Ssbehera if (nxgep->mac.portmode == PORT_10G_FIBER) { 7976604Ssbehera uint32_t pma_pmd_id; 7986604Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, 7996604Ssbehera nxgep->xcvr_addr); 8006604Ssbehera if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) { 8016604Ssbehera chip_id = MRVL88X201X_CHIP_ID; 8026604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8036604Ssbehera "nxge_setup_xcvr_table: " 8046604Ssbehera "Chip ID MARVELL [0x%x] for 10G xcvr", chip_id)); 8056604Ssbehera } else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr, 8065572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG, 8075572Ssbehera &chip_id)) == NXGE_OK) { 8085572Ssbehera 8095572Ssbehera switch (chip_id) { 8105572Ssbehera case BCM8704_CHIP_ID: 8115572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8125572Ssbehera "nxge_setup_xcvr_table: " 8135572Ssbehera "Chip ID 8704 [0x%x] for 10G xcvr", 8145572Ssbehera chip_id)); 8155572Ssbehera break; 8165572Ssbehera case BCM8706_CHIP_ID: 8175572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8185572Ssbehera "nxge_setup_xcvr_table: " 8195572Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", 8205572Ssbehera chip_id)); 8215572Ssbehera break; 8225572Ssbehera default: 8235572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8245572Ssbehera "nxge_setup_xcvr_table: " 8255572Ssbehera "Unknown Chip ID [0x%x] for 10G xcvr", 8265572Ssbehera chip_id)); 8275572Ssbehera break; 8285572Ssbehera } 8295572Ssbehera } 8305572Ssbehera } 8315572Ssbehera 8324732Sdavemq nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse; 8335572Ssbehera nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr; 8345572Ssbehera nxgep->chip_id = chip_id; 8354977Sraghus 8364977Sraghus /* 8374977Sraghus * Get the actual device ID value returned by MDIO read. 8384977Sraghus */ 8394977Sraghus nxgep->statsp->mac_stats.xcvr_id = 0; 8404977Sraghus 8415572Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr); 8424977Sraghus if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) { 8434977Sraghus nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id; 8444977Sraghus } else { 8455572Ssbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr); 8464977Sraghus if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) { 8474977Sraghus nxgep->statsp->mac_stats.xcvr_id = pcs_id; 8484977Sraghus } else { 8494977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, 8505572Ssbehera nxgep->xcvr_addr); 8514977Sraghus if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 8524977Sraghus nxgep->statsp->mac_stats.xcvr_id = phy_id; 8534977Sraghus } 8544977Sraghus } 8554977Sraghus } 8564977Sraghus 8574732Sdavemq nxgep->mac.linkchkmode = LINKCHK_TIMER; 8584732Sdavemq 8594977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type" 8607801SSantwona.Behera@Sun.COM "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type, 8615572Ssbehera nxgep->platform_type, nxgep->xcvr_addr)); 8624977Sraghus 8634732Sdavemq return (status); 8644732Sdavemq } 8654732Sdavemq 8663859Sml29623 /* Initialize the entire MAC and physical layer */ 8673859Sml29623 8683859Sml29623 nxge_status_t 8693859Sml29623 nxge_mac_init(p_nxge_t nxgep) 8703859Sml29623 { 8713859Sml29623 uint8_t portn; 8723859Sml29623 nxge_status_t status = NXGE_OK; 8733859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 8743859Sml29623 8753859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 8763859Sml29623 8773859Sml29623 nxgep->mac.portnum = portn; 8783859Sml29623 nxgep->mac.porttype = PORT_TYPE_XMAC; 8793859Sml29623 8803859Sml29623 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 8813859Sml29623 nxgep->mac.porttype = PORT_TYPE_BMAC; 8823859Sml29623 8836835Syc148097 8843859Sml29623 /* Initialize XIF to configure a network mode */ 8853859Sml29623 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 8863859Sml29623 goto fail; 8873859Sml29623 } 8883859Sml29623 8893859Sml29623 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 8903859Sml29623 goto fail; 8913859Sml29623 } 8923859Sml29623 8933859Sml29623 /* Initialize TX and RX MACs */ 8943859Sml29623 /* 8953859Sml29623 * Always perform XIF init first, before TX and RX MAC init 8963859Sml29623 */ 8973859Sml29623 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 8983859Sml29623 goto fail; 8993859Sml29623 9003859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 9013859Sml29623 goto fail; 9023859Sml29623 9033859Sml29623 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 9043859Sml29623 goto fail; 9053859Sml29623 9063859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 9073859Sml29623 goto fail; 9083859Sml29623 9093859Sml29623 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 9103859Sml29623 goto fail; 9113859Sml29623 912*9232SMichael.Speer@Sun.COM if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) { 913*9232SMichael.Speer@Sun.COM if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 914*9232SMichael.Speer@Sun.COM goto fail; 915*9232SMichael.Speer@Sun.COM } 9163859Sml29623 9175553Smisaki /* Initialize MAC control configuration */ 9185553Smisaki if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) { 9195553Smisaki goto fail; 9205553Smisaki } 9215553Smisaki 9223859Sml29623 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 9233859Sml29623 9245196Ssbehera /* The Neptune Serdes needs to be reinitialized again */ 9255196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 9265196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 9276835Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) || 9285196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 9295196Ssbehera ((portn == 0) || (portn == 1))) { 9305196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 9315196Ssbehera "nxge_mac_init: reinit Neptune 1G Serdes ")); 9325196Ssbehera if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) { 9335196Ssbehera goto fail; 9345196Ssbehera } 9355196Ssbehera } 9365196Ssbehera 9374977Sraghus 9383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 9393859Sml29623 9403859Sml29623 return (NXGE_OK); 9413859Sml29623 fail: 9423859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 9436929Smisaki "nxge_mac_init: failed to initialize MAC port<%d>", portn)); 9443859Sml29623 return (status); 9453859Sml29623 } 9463859Sml29623 9473859Sml29623 /* Initialize the Ethernet Link */ 9483859Sml29623 9493859Sml29623 nxge_status_t 9503859Sml29623 nxge_link_init(p_nxge_t nxgep) 9513859Sml29623 { 9523859Sml29623 nxge_status_t status = NXGE_OK; 9534977Sraghus nxge_port_mode_t portmode; 9543859Sml29623 #ifdef NXGE_DEBUG 9553859Sml29623 uint8_t portn; 9563859Sml29623 9573859Sml29623 portn = nxgep->mac.portnum; 9583859Sml29623 9593859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 9603859Sml29623 #endif 9615572Ssbehera if (nxgep->hot_swappable_phy && nxgep->phy_absent) { 9625572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: " 9635572Ssbehera "Phy not present, cannot initialize link")); 9645572Ssbehera return (status); 9655572Ssbehera } 9663859Sml29623 9674977Sraghus portmode = nxgep->mac.portmode; 9685572Ssbehera 9696835Syc148097 /* 9706835Syc148097 * Workaround to get link up in both NIU ports. Some portmodes require 9716835Syc148097 * that the xcvr be initialized twice, the first time before calling 9726835Syc148097 * nxge_serdes_init. 9736835Syc148097 */ 9744977Sraghus if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) && 9756835Syc148097 (portmode != PORT_10G_TN1010) && 9766835Syc148097 (portmode != PORT_1G_TN1010) && 9774977Sraghus (portmode != PORT_1G_SERDES)) { 9784977Sraghus if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) { 9793859Sml29623 goto fail; 9804977Sraghus } 9813859Sml29623 } 9826835Syc148097 9833859Sml29623 NXGE_DELAY(200000); 9843859Sml29623 /* Initialize internal serdes */ 9853859Sml29623 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 9863859Sml29623 goto fail; 9873859Sml29623 NXGE_DELAY(200000); 9883859Sml29623 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 9893859Sml29623 goto fail; 9903859Sml29623 9913859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 9923859Sml29623 9933859Sml29623 return (NXGE_OK); 9943859Sml29623 9953859Sml29623 fail: 9966929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ", 9976929Smisaki "failed to initialize Ethernet link on port<%d>", portn)); 9983859Sml29623 9993859Sml29623 return (status); 10003859Sml29623 } 10013859Sml29623 10023859Sml29623 10033859Sml29623 /* Initialize the XIF sub-block within the MAC */ 10043859Sml29623 10053859Sml29623 nxge_status_t 10063859Sml29623 nxge_xif_init(p_nxge_t nxgep) 10073859Sml29623 { 10083859Sml29623 uint32_t xif_cfg = 0; 10093859Sml29623 npi_attr_t ap; 10103859Sml29623 uint8_t portn; 10113859Sml29623 nxge_port_t portt; 10123859Sml29623 nxge_port_mode_t portmode; 10133859Sml29623 p_nxge_stats_t statsp; 10143859Sml29623 npi_status_t rs = NPI_SUCCESS; 10153859Sml29623 npi_handle_t handle; 10163859Sml29623 10173859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 10183859Sml29623 10193859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 10203859Sml29623 10213859Sml29623 handle = nxgep->npi_handle; 10223859Sml29623 portmode = nxgep->mac.portmode; 10233859Sml29623 portt = nxgep->mac.porttype; 10243859Sml29623 statsp = nxgep->statsp; 10253859Sml29623 10265196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 10275196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 10286835Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) || 10295196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 10305196Ssbehera ((portn == 0) || (portn == 1))) { 10315196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 10325196Ssbehera "nxge_xcvr_init: set ATCA mode")); 10335196Ssbehera npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE); 10345196Ssbehera } 10355196Ssbehera 10363859Sml29623 if (portt == PORT_TYPE_XMAC) { 10373859Sml29623 10383859Sml29623 /* Setup XIF Configuration for XMAC */ 10393859Sml29623 10403859Sml29623 if ((portmode == PORT_10G_FIBER) || 10414977Sraghus (portmode == PORT_10G_COPPER) || 10426835Syc148097 (portmode == PORT_10G_TN1010) || 10434977Sraghus (portmode == PORT_10G_SERDES)) 10443859Sml29623 xif_cfg |= CFG_XMAC_XIF_LFS; 10453859Sml29623 10466835Syc148097 /* Bypass PCS so that RGMII will be used */ 10473859Sml29623 if (portmode == PORT_1G_COPPER) { 10483859Sml29623 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 10493859Sml29623 } 10503859Sml29623 10513859Sml29623 /* Set MAC Internal Loopback if necessary */ 10523859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 10533859Sml29623 xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 10543859Sml29623 10553859Sml29623 if (statsp->mac_stats.link_speed == 100) 10563859Sml29623 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 10573859Sml29623 10583859Sml29623 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 10593859Sml29623 10604977Sraghus if ((portmode == PORT_10G_FIBER) || 10616835Syc148097 (portmode == PORT_10G_TN1010) || 10626835Syc148097 (portmode == PORT_1G_TN1010) || 10634977Sraghus (portmode == PORT_10G_SERDES)) { 10646835Syc148097 /* Assume LED same for 1G and 10G */ 10653859Sml29623 if (statsp->mac_stats.link_up) { 10663859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 10673859Sml29623 } else { 10683859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 10693859Sml29623 } 10703859Sml29623 } 10713859Sml29623 10723859Sml29623 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 10733859Sml29623 if (rs != NPI_SUCCESS) 10743859Sml29623 goto fail; 10753859Sml29623 10763859Sml29623 nxgep->mac.xif_config = xif_cfg; 10773859Sml29623 10783859Sml29623 /* Set Port Mode */ 10793859Sml29623 if ((portmode == PORT_10G_FIBER) || 10804977Sraghus (portmode == PORT_10G_COPPER) || 10816835Syc148097 (portmode == PORT_10G_TN1010) || 10824977Sraghus (portmode == PORT_10G_SERDES)) { 10833859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 10846929Smisaki MAC_XGMII_MODE, rs); 10853859Sml29623 if (rs != NPI_SUCCESS) 10863859Sml29623 goto fail; 10873859Sml29623 if (statsp->mac_stats.link_up) { 10883859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 10893859Sml29623 goto fail; 10903859Sml29623 } else { 10913859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 10923859Sml29623 goto fail; 10933859Sml29623 } 10943859Sml29623 } else if ((portmode == PORT_1G_FIBER) || 10954977Sraghus (portmode == PORT_1G_COPPER) || 10965196Ssbehera (portmode == PORT_1G_SERDES) || 10976835Syc148097 (portmode == PORT_1G_TN1010) || 10985196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 10995196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11005196Ssbehera "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]", 11015196Ssbehera portn, portmode, statsp->mac_stats.link_speed)); 11023859Sml29623 if (statsp->mac_stats.link_speed == 1000) { 11033859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11046929Smisaki MAC_GMII_MODE, rs); 11053859Sml29623 } else { 11063859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11076929Smisaki MAC_MII_MODE, rs); 11083859Sml29623 } 11093859Sml29623 if (rs != NPI_SUCCESS) 11103859Sml29623 goto fail; 11113859Sml29623 } else { 11123859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11136929Smisaki "nxge_xif_init: Unknown port mode (%d)" 11146929Smisaki " for port<%d>", portmode, portn)); 11153859Sml29623 goto fail; 11163859Sml29623 } 11173859Sml29623 11185196Ssbehera /* Enable ATCA mode */ 11195196Ssbehera 11203859Sml29623 } else if (portt == PORT_TYPE_BMAC) { 11213859Sml29623 11223859Sml29623 /* Setup XIF Configuration for BMAC */ 11233859Sml29623 11245196Ssbehera if ((portmode == PORT_1G_COPPER) || 11255196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 11263859Sml29623 if (statsp->mac_stats.link_speed == 100) 11273859Sml29623 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 11283859Sml29623 } 11293859Sml29623 11303859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 11313859Sml29623 xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 11323859Sml29623 11333859Sml29623 if (statsp->mac_stats.link_speed == 1000) 11343859Sml29623 xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 11353859Sml29623 11363859Sml29623 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 11373859Sml29623 11383859Sml29623 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 11393859Sml29623 if (rs != NPI_SUCCESS) 11403859Sml29623 goto fail; 11413859Sml29623 nxgep->mac.xif_config = xif_cfg; 11423859Sml29623 } 11433859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 11443859Sml29623 return (NXGE_OK); 11453859Sml29623 fail: 11463859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11476929Smisaki "nxge_xif_init: Failed to initialize XIF port<%d>", portn)); 11483859Sml29623 return (NXGE_ERROR | rs); 11493859Sml29623 } 11503859Sml29623 11516835Syc148097 11526835Syc148097 /* 11536835Syc148097 * Initialize the PCS sub-block in the MAC. Note that PCS does not 11546835Syc148097 * support loopback like XPCS. 11556835Syc148097 */ 11563859Sml29623 nxge_status_t 11573859Sml29623 nxge_pcs_init(p_nxge_t nxgep) 11583859Sml29623 { 11593859Sml29623 pcs_cfg_t pcs_cfg; 11603859Sml29623 uint32_t val; 11613859Sml29623 uint8_t portn; 11623859Sml29623 nxge_port_mode_t portmode; 11633859Sml29623 npi_handle_t handle; 11643859Sml29623 p_nxge_stats_t statsp; 11656835Syc148097 pcs_ctrl_t pcs_ctrl; 11663859Sml29623 npi_status_t rs = NPI_SUCCESS; 11676835Syc148097 uint8_t i; 11683859Sml29623 11693859Sml29623 handle = nxgep->npi_handle; 11703859Sml29623 portmode = nxgep->mac.portmode; 11713859Sml29623 portn = nxgep->mac.portnum; 11723859Sml29623 statsp = nxgep->statsp; 11733859Sml29623 11743859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 11753859Sml29623 11766835Syc148097 if (portmode == PORT_1G_FIBER || 11776835Syc148097 portmode == PORT_1G_TN1010 || 11786835Syc148097 portmode == PORT_1G_SERDES) { 11796835Syc148097 if (portmode == PORT_1G_TN1010) { 11806835Syc148097 /* Reset PCS multiple time in PORT_1G_TN1010 mode */ 11816835Syc148097 for (i = 0; i < 6; i ++) { 11826835Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn)) 11836835Syc148097 != NPI_SUCCESS) { 11846835Syc148097 goto fail; 11856835Syc148097 } 11866835Syc148097 } 11876835Syc148097 } else { 11886835Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn)) 11896835Syc148097 != NPI_SUCCESS) 11906835Syc148097 goto fail; 11914977Sraghus } 11924977Sraghus 11933859Sml29623 /* Initialize port's PCS */ 11943859Sml29623 pcs_cfg.value = 0; 11953859Sml29623 pcs_cfg.bits.w0.enable = 1; 11963859Sml29623 pcs_cfg.bits.w0.mask = 1; 11973859Sml29623 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 11983859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 11994977Sraghus 12004977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12014977Sraghus "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx", 12024977Sraghus portn, pcs_cfg.value)); 12036835Syc148097 12046835Syc148097 if (portmode == PORT_1G_TN1010) { 12056835Syc148097 /* 12066835Syc148097 * Must disable PCS auto-negotiation when the the driver 12076835Syc148097 * is driving the TN1010 based XAUI card Otherwise the 12086835Syc148097 * autonegotiation between the PCS and the TN1010 PCS 12096835Syc148097 * will never complete and the Neptune/NIU will not work 12106835Syc148097 */ 12116835Syc148097 pcs_ctrl.value = 0; 12126835Syc148097 PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG, 12136835Syc148097 pcs_ctrl.value); 12146835Syc148097 } 12156835Syc148097 } else if (portmode == PORT_10G_FIBER || 12166835Syc148097 portmode == PORT_10G_COPPER || 12176835Syc148097 portmode == PORT_10G_TN1010 || 12186835Syc148097 portmode == PORT_10G_SERDES) { 12193859Sml29623 /* Use internal XPCS, bypass 1G PCS */ 12203859Sml29623 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 12213859Sml29623 val &= ~XMAC_XIF_XPCS_BYPASS; 12223859Sml29623 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 12233859Sml29623 12243859Sml29623 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 12253859Sml29623 goto fail; 12263859Sml29623 12273859Sml29623 /* Set XPCS Internal Loopback if necessary */ 12283859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 12296929Smisaki XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS) 12303859Sml29623 goto fail; 12316835Syc148097 12323859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 12336929Smisaki (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 12343859Sml29623 val |= XPCS_CTRL1_LOOPBK; 12353859Sml29623 else 12363859Sml29623 val &= ~XPCS_CTRL1_LOOPBK; 12373859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 12386929Smisaki XPCS_REG_CONTROL1, val)) != NPI_SUCCESS) 12393859Sml29623 goto fail; 12403859Sml29623 12413859Sml29623 /* Clear descw errors */ 12423859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 12436929Smisaki XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS) 12443859Sml29623 goto fail; 12453859Sml29623 /* Clear symbol errors */ 12463859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 12476929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS) 12483859Sml29623 goto fail; 12493859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 12506929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS) 12513859Sml29623 goto fail; 12523859Sml29623 12535196Ssbehera } else if ((portmode == PORT_1G_COPPER) || 12545196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 12555196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12565196Ssbehera "==> nxge_pcs_init: (1G) copper port<%d>", portn)); 12573859Sml29623 if (portn < 4) { 12583859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 12596929Smisaki PCS_DATAPATH_MODE_MII); 12603859Sml29623 } 12613859Sml29623 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 12623859Sml29623 goto fail; 12633859Sml29623 12643859Sml29623 } else { 12653859Sml29623 goto fail; 12663859Sml29623 } 12673859Sml29623 pass: 12683859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 12693859Sml29623 return (NXGE_OK); 12703859Sml29623 fail: 12713859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12726929Smisaki "nxge_pcs_init: Failed to initialize PCS port<%d>", portn)); 12733859Sml29623 return (NXGE_ERROR | rs); 12743859Sml29623 } 12753859Sml29623 12765553Smisaki /* 12775553Smisaki * Initialize the MAC CTRL sub-block within the MAC 12785553Smisaki * Only the receive-pause-cap is supported. 12795553Smisaki */ 12805553Smisaki nxge_status_t 12815553Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep) 12825553Smisaki { 12835553Smisaki uint8_t portn; 12845553Smisaki nxge_port_t portt; 12855553Smisaki p_nxge_stats_t statsp; 12865553Smisaki npi_handle_t handle; 12875553Smisaki uint32_t val; 12885553Smisaki 12895553Smisaki portn = NXGE_GET_PORT_NUM(nxgep->function_num); 12905553Smisaki 12915553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>", 12925553Smisaki portn)); 12935553Smisaki 12945553Smisaki handle = nxgep->npi_handle; 12955553Smisaki portt = nxgep->mac.porttype; 12965553Smisaki statsp = nxgep->statsp; 12975553Smisaki 12985553Smisaki if (portt == PORT_TYPE_XMAC) { 12996835Syc148097 /* Reading the current XMAC Config Register for XMAC */ 13005553Smisaki XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 13015553Smisaki 13025553Smisaki /* 13035553Smisaki * Setup XMAC Configuration for XMAC 13045553Smisaki * XMAC only supports receive-pause 13055553Smisaki */ 13065553Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 13075553Smisaki if (!statsp->mac_stats.adv_cap_pause) { 13085553Smisaki /* 13095553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13105553Smisaki * is 0, enable receive pause. 13115553Smisaki */ 13125553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 13135553Smisaki } else { 13145553Smisaki /* 13155553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13165553Smisaki * is 1, disable receive pause. Send pause is 13175553Smisaki * not supported. 13185553Smisaki */ 13195553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 13205553Smisaki } 13215553Smisaki } else { 13226439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13236439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: pause", 13246439Sml29623 portn)); 13255553Smisaki if (statsp->mac_stats.adv_cap_pause) { 13266439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13276439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: " 13286439Sml29623 "enable pause", portn)); 13295553Smisaki /* 13305553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13315553Smisaki * is 1, enable receive pause. 13325553Smisaki */ 13335553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 13345553Smisaki } else { 13355553Smisaki /* 13365553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13375553Smisaki * is 0, disable receive pause. Send pause is 13385553Smisaki * not supported 13395553Smisaki */ 13406439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13416439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: " 13426439Sml29623 "disable pause", portn)); 13435553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 13445553Smisaki } 13455553Smisaki } 13465553Smisaki XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 13475553Smisaki } else if (portt == PORT_TYPE_BMAC) { 13486835Syc148097 /* Reading the current MAC CTRL Config Register for BMAC */ 13495553Smisaki BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val); 13505553Smisaki 13515553Smisaki /* Setup MAC CTRL Configuration for BMAC */ 13525553Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 13535553Smisaki if (statsp->mac_stats.adv_cap_pause) { 13545553Smisaki /* 13555553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13565553Smisaki * is 1, disable receive pause. Send pause 13575553Smisaki * is not supported 13585553Smisaki */ 13595553Smisaki val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN; 13605553Smisaki } else { 13615553Smisaki /* 13625553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13635553Smisaki * is 0, enable receive pause and disable 13645553Smisaki * send pause. 13655553Smisaki */ 13665553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 13675553Smisaki val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN; 13685553Smisaki } 13695553Smisaki } else { 13705553Smisaki if (statsp->mac_stats.adv_cap_pause) { 13715553Smisaki /* 13725553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13735553Smisaki * is 1, enable receive pause. Send pause is 13745553Smisaki * not supported. 13755553Smisaki */ 13765553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 13775553Smisaki } else { 13785553Smisaki /* 13795553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13805553Smisaki * is 0, pause capability is not available in 13815553Smisaki * either direction. 13825553Smisaki */ 13835553Smisaki val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN & 13846929Smisaki ~MAC_CTRL_CFG_RECV_PAUSE_EN); 13855553Smisaki } 13865553Smisaki } 13875553Smisaki BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val); 13885553Smisaki } 13895553Smisaki 13905553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>", 13915553Smisaki portn)); 13925553Smisaki 13935553Smisaki return (NXGE_OK); 13945553Smisaki } 13955553Smisaki 13963859Sml29623 /* Initialize the Internal Serdes */ 13973859Sml29623 13983859Sml29623 nxge_status_t 13993859Sml29623 nxge_serdes_init(p_nxge_t nxgep) 14003859Sml29623 { 14013859Sml29623 p_nxge_stats_t statsp; 14023859Sml29623 #ifdef NXGE_DEBUG 14033859Sml29623 uint8_t portn; 14043859Sml29623 #endif 14053859Sml29623 nxge_status_t status = NXGE_OK; 14063859Sml29623 14073859Sml29623 #ifdef NXGE_DEBUG 14083859Sml29623 portn = nxgep->mac.portnum; 14093859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14104732Sdavemq "==> nxge_serdes_init port<%d>", portn)); 14113859Sml29623 #endif 14123859Sml29623 14134732Sdavemq if (nxgep->xcvr.serdes_init) { 14144732Sdavemq statsp = nxgep->statsp; 14154732Sdavemq status = nxgep->xcvr.serdes_init(nxgep); 14164732Sdavemq if (status != NXGE_OK) 14173859Sml29623 goto fail; 14184732Sdavemq statsp->mac_stats.serdes_inits++; 14193859Sml29623 } 14203859Sml29623 14213859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 14224732Sdavemq portn)); 14233859Sml29623 14243859Sml29623 return (NXGE_OK); 14253859Sml29623 14263859Sml29623 fail: 14273859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14284732Sdavemq "nxge_serdes_init: Failed to initialize serdes for port<%d>", 14294732Sdavemq portn)); 14303859Sml29623 14313859Sml29623 return (status); 14323859Sml29623 } 14333859Sml29623 14343859Sml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 14353859Sml29623 14364732Sdavemq static nxge_status_t 14373859Sml29623 nxge_n2_serdes_init(p_nxge_t nxgep) 14383859Sml29623 { 14393859Sml29623 uint8_t portn; 14403859Sml29623 int chan; 14413859Sml29623 esr_ti_cfgpll_l_t pll_cfg_l; 14424977Sraghus esr_ti_cfgpll_l_t pll_sts_l; 14433859Sml29623 esr_ti_cfgrx_l_t rx_cfg_l; 14443859Sml29623 esr_ti_cfgrx_h_t rx_cfg_h; 14453859Sml29623 esr_ti_cfgtx_l_t tx_cfg_l; 14463859Sml29623 esr_ti_cfgtx_h_t tx_cfg_h; 14474977Sraghus #ifdef NXGE_DEBUG 14484977Sraghus esr_ti_testcfg_t cfg; 14494977Sraghus #endif 14503859Sml29623 esr_ti_testcfg_t test_cfg; 14513859Sml29623 nxge_status_t status = NXGE_OK; 14523859Sml29623 14533859Sml29623 portn = nxgep->mac.portnum; 14543859Sml29623 14553859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 14566929Smisaki portn)); 14573859Sml29623 14583859Sml29623 tx_cfg_l.value = 0; 14593859Sml29623 tx_cfg_h.value = 0; 14603859Sml29623 rx_cfg_l.value = 0; 14613859Sml29623 rx_cfg_h.value = 0; 14623859Sml29623 pll_cfg_l.value = 0; 14634977Sraghus pll_sts_l.value = 0; 14643859Sml29623 test_cfg.value = 0; 14653859Sml29623 14666835Syc148097 /* 14676835Syc148097 * If the nxge driver has been plumbed without a link, then it will 14686835Syc148097 * detect a link up when a cable connecting to an anto-negotiation 14696835Syc148097 * partner is plugged into the port. Because the TN1010 PHY supports 14706835Syc148097 * both 1G and 10G speeds, the driver must re-configure the 14716835Syc148097 * Neptune/NIU according to the negotiated speed. nxge_n2_serdes_init 14726835Syc148097 * is called at the post-link-up reconfiguration time. Here it calls 14736835Syc148097 * nxge_set_tn1010_param to set portmode before re-initializing 14746835Syc148097 * the serdes. 14756835Syc148097 */ 14766835Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 || 14776835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) { 14786835Syc148097 if (nxge_set_tn1010_param(nxgep) != NXGE_OK) { 14796835Syc148097 goto fail; 14806835Syc148097 } 14816835Syc148097 } 14826835Syc148097 14836835Syc148097 if (nxgep->mac.portmode == PORT_10G_FIBER || 14846835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010 || 14856835Syc148097 nxgep->mac.portmode == PORT_10G_SERDES) { 14863859Sml29623 /* 0x0E01 */ 14873859Sml29623 tx_cfg_l.bits.entx = 1; 14883859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 14893859Sml29623 14903859Sml29623 /* 0x9101 */ 14913859Sml29623 rx_cfg_l.bits.enrx = 1; 14923859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 14933859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 14943859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 14953859Sml29623 14963859Sml29623 /* 0x0008 */ 14973859Sml29623 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 14983859Sml29623 14993859Sml29623 /* Set loopback mode if necessary */ 15003859Sml29623 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 15013859Sml29623 tx_cfg_l.bits.entest = 1; 15023859Sml29623 rx_cfg_l.bits.entest = 1; 15033859Sml29623 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 15043859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, 15056929Smisaki ESR_N2_DEV_ADDR, 15066929Smisaki ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) 15073859Sml29623 goto fail; 15083859Sml29623 } 15093859Sml29623 15106835Syc148097 /* Initialize PLL for 10G */ 15116835Syc148097 pll_cfg_l.bits.mpy = CFGPLL_MPY_10X; 15126835Syc148097 pll_cfg_l.bits.enpll = 1; 15136835Syc148097 pll_sts_l.bits.enpll = 1; 15146835Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15156835Syc148097 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 15166835Syc148097 goto fail; 15176835Syc148097 15186835Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15196835Syc148097 ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 15206835Syc148097 goto fail; 15216835Syc148097 15226835Syc148097 #ifdef NXGE_DEBUG 15236835Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15246835Syc148097 ESR_N2_PLL_CFG_L_REG, &cfg.value); 15256835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15266835Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 15276835Syc148097 portn, pll_cfg_l.value, cfg.value)); 15286835Syc148097 15296835Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15306835Syc148097 ESR_N2_PLL_STS_L_REG, &cfg.value); 15316835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15326835Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 15336835Syc148097 portn, pll_sts_l.value, cfg.value)); 15346835Syc148097 #endif 15356835Syc148097 } else if (nxgep->mac.portmode == PORT_1G_FIBER || 15366835Syc148097 nxgep->mac.portmode == PORT_1G_TN1010 || 15376835Syc148097 nxgep->mac.portmode == PORT_1G_SERDES) { 15383859Sml29623 /* 0x0E21 */ 15393859Sml29623 tx_cfg_l.bits.entx = 1; 15403859Sml29623 tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 15413859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 15423859Sml29623 15433859Sml29623 /* 0x9121 */ 15443859Sml29623 rx_cfg_l.bits.enrx = 1; 15453859Sml29623 rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 15463859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 15473859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 15483859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 15493859Sml29623 15504977Sraghus if (portn == 0) { 15514977Sraghus /* 0x8 */ 15524977Sraghus rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 15534977Sraghus } 15543859Sml29623 15556835Syc148097 /* Initialize PLL for 1G */ 15563859Sml29623 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 15573859Sml29623 pll_cfg_l.bits.enpll = 1; 15584977Sraghus pll_sts_l.bits.enpll = 1; 15593859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15606929Smisaki ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 15613859Sml29623 goto fail; 15624977Sraghus 15634977Sraghus if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15644977Sraghus ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 15654977Sraghus goto fail; 15664977Sraghus 15674977Sraghus #ifdef NXGE_DEBUG 15684977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15694977Sraghus ESR_N2_PLL_CFG_L_REG, &cfg.value); 15704977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15714977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 15724977Sraghus portn, pll_cfg_l.value, cfg.value)); 15734977Sraghus 15744977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15754977Sraghus ESR_N2_PLL_STS_L_REG, &cfg.value); 15764977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15774977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 15784977Sraghus portn, pll_sts_l.value, cfg.value)); 15794977Sraghus #endif 15804977Sraghus 15814977Sraghus /* Set loopback mode if necessary */ 15824977Sraghus if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 15834977Sraghus tx_cfg_l.bits.entest = 1; 15844977Sraghus rx_cfg_l.bits.entest = 1; 15854977Sraghus test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 15864977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15874977Sraghus "==> nxge_n2_serdes_init port<%d>: loopback 0x%x", 15884977Sraghus portn, test_cfg.value)); 15894977Sraghus if ((status = nxge_mdio_write(nxgep, portn, 15904977Sraghus ESR_N2_DEV_ADDR, 15914977Sraghus ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) { 15924977Sraghus goto fail; 15934977Sraghus } 15944977Sraghus } 15953859Sml29623 } else { 15963859Sml29623 goto fail; 15973859Sml29623 } 15983859Sml29623 15993859Sml29623 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 16003859Sml29623 16013859Sml29623 NXGE_DELAY(20); 16023859Sml29623 16033859Sml29623 /* init TX channels */ 16043859Sml29623 for (chan = 0; chan < 4; chan++) { 16053859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16066929Smisaki ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK) 16073859Sml29623 goto fail; 16083859Sml29623 16093859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16106929Smisaki ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK) 16113859Sml29623 goto fail; 16124977Sraghus 16134977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16144977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x", 16154977Sraghus portn, chan, tx_cfg_l.value)); 16164977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16174977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x", 16184977Sraghus portn, chan, tx_cfg_h.value)); 16193859Sml29623 } 16203859Sml29623 16213859Sml29623 /* init RX channels */ 16223859Sml29623 for (chan = 0; chan < 4; chan++) { 16233859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16246929Smisaki ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK) 16253859Sml29623 goto fail; 16263859Sml29623 16273859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16286929Smisaki ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK) 16293859Sml29623 goto fail; 16304977Sraghus 16314977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16324977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x", 16334977Sraghus portn, chan, rx_cfg_l.value)); 16346835Syc148097 16354977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16364977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x", 16374977Sraghus portn, chan, rx_cfg_h.value)); 16383859Sml29623 } 16393859Sml29623 16403859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 16416929Smisaki portn)); 16423859Sml29623 16433859Sml29623 return (NXGE_OK); 16443859Sml29623 fail: 16455572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16465572Ssbehera "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 16475572Ssbehera portn)); 16483859Sml29623 16493859Sml29623 return (status); 16503859Sml29623 } 16513859Sml29623 16524732Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */ 16534732Sdavemq 16544732Sdavemq static nxge_status_t 16554732Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep) 16563859Sml29623 { 16573859Sml29623 npi_handle_t handle; 16583859Sml29623 uint8_t portn; 16596075Ssbehera int chan, i; 16603859Sml29623 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 16613859Sml29623 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 16623859Sml29623 sr_glue_ctrl0_l_t glue_ctrl0_l; 16633859Sml29623 sr_glue_ctrl0_h_t glue_ctrl0_h; 16643859Sml29623 uint64_t val; 16653859Sml29623 uint16_t val16l; 16663859Sml29623 uint16_t val16h; 16673859Sml29623 nxge_status_t status = NXGE_OK; 16683859Sml29623 16693859Sml29623 portn = nxgep->mac.portnum; 16703859Sml29623 16713859Sml29623 if ((portn != 0) && (portn != 1)) 16723859Sml29623 return (NXGE_OK); 16733859Sml29623 16744732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16754732Sdavemq "==> nxge_neptune_10G_serdes_init port<%d>", portn)); 16763859Sml29623 handle = nxgep->npi_handle; 16774732Sdavemq switch (portn) { 16784732Sdavemq case 0: 16796028Ssbehera /* Reset Serdes */ 16806028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0); 16816028Ssbehera NXGE_DELAY(20); 16826028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0); 16836028Ssbehera NXGE_DELAY(2000); 16846028Ssbehera 16856028Ssbehera /* Configure Serdes to 10G mode */ 16866028Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 16876028Ssbehera ESR_PLL_CFG_10G_SERDES); 16886028Ssbehera 16894732Sdavemq ESR_REG_WR(handle, ESR_0_CONTROL_REG, 16904732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 16914732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 16924732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 16934732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 16944732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 16954732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 16964732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 16974732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 16984732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 16994732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 17004732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 17014732Sdavemq 17024732Sdavemq /* Set Serdes0 Internal Loopback if necessary */ 17034732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 17044732Sdavemq ESR_REG_WR(handle, 17054732Sdavemq ESR_0_TEST_CONFIG_REG, 17064732Sdavemq ESR_PAD_LOOPBACK_CH3 | 17074732Sdavemq ESR_PAD_LOOPBACK_CH2 | 17084732Sdavemq ESR_PAD_LOOPBACK_CH1 | 17094732Sdavemq ESR_PAD_LOOPBACK_CH0); 17104732Sdavemq } else { 17114732Sdavemq ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 17123859Sml29623 } 17134732Sdavemq break; 17144732Sdavemq case 1: 17156028Ssbehera /* Reset Serdes */ 17166028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1); 17176028Ssbehera NXGE_DELAY(20); 17186028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0); 17196028Ssbehera NXGE_DELAY(2000); 17206028Ssbehera 17216028Ssbehera /* Configure Serdes to 10G mode */ 17226028Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 17236028Ssbehera ESR_PLL_CFG_10G_SERDES); 17246028Ssbehera 17254732Sdavemq ESR_REG_WR(handle, ESR_1_CONTROL_REG, 17264732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 17274732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 17284732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 17294732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 17304732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 17314732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 17324732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 17334732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 17344732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 17354732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 17364732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 17374732Sdavemq 17384732Sdavemq /* Set Serdes1 Internal Loopback if necessary */ 17394732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 17404732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 17414732Sdavemq ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 | 17424732Sdavemq ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0); 17434732Sdavemq } else { 17444732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 17453859Sml29623 } 17464732Sdavemq break; 17474732Sdavemq default: 17484732Sdavemq /* Nothing to do here */ 17494732Sdavemq goto done; 17504732Sdavemq } 17514732Sdavemq 17524732Sdavemq /* init TX RX channels */ 17534732Sdavemq for (chan = 0; chan < 4; chan++) { 17544732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 17554732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 17564732Sdavemq &rx_tx_ctrl_l.value)) != NXGE_OK) 17573859Sml29623 goto fail; 17584732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 17594732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 17604732Sdavemq &rx_tx_ctrl_h.value)) != NXGE_OK) 17613859Sml29623 goto fail; 17623859Sml29623 if ((status = nxge_mdio_read(nxgep, portn, 17634732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 17644732Sdavemq &glue_ctrl0_l.value)) != NXGE_OK) 17653859Sml29623 goto fail; 17663859Sml29623 if ((status = nxge_mdio_read(nxgep, portn, 17674732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 17684732Sdavemq &glue_ctrl0_h.value)) != NXGE_OK) 17694732Sdavemq goto fail; 17704732Sdavemq rx_tx_ctrl_l.bits.enstretch = 1; 17714732Sdavemq rx_tx_ctrl_h.bits.vmuxlo = 2; 17724732Sdavemq rx_tx_ctrl_h.bits.vpulselo = 2; 17734732Sdavemq glue_ctrl0_l.bits.rxlosenable = 1; 17744732Sdavemq glue_ctrl0_l.bits.samplerate = 0xF; 17754732Sdavemq glue_ctrl0_l.bits.thresholdcount = 0xFF; 17764732Sdavemq glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 17774732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 17784732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 17794732Sdavemq rx_tx_ctrl_l.value)) != NXGE_OK) 17804732Sdavemq goto fail; 17814732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 17824732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 17834732Sdavemq rx_tx_ctrl_h.value)) != NXGE_OK) 17844732Sdavemq goto fail; 17854732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 17864732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 17874732Sdavemq glue_ctrl0_l.value)) != NXGE_OK) 17884732Sdavemq goto fail; 17894732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 17904732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 17914732Sdavemq glue_ctrl0_h.value)) != NXGE_OK) 17923859Sml29623 goto fail; 17933859Sml29623 } 17943859Sml29623 17954732Sdavemq /* Apply Tx core reset */ 17964732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 17974732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 17984732Sdavemq (uint16_t)0)) != NXGE_OK) 17994732Sdavemq goto fail; 18004732Sdavemq 18014732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18024732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 18034732Sdavemq NXGE_OK) 18044732Sdavemq goto fail; 18054732Sdavemq 18064732Sdavemq NXGE_DELAY(200); 18074732Sdavemq 18084732Sdavemq /* Apply Rx core reset */ 18094732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18104732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 18114732Sdavemq NXGE_OK) 18124732Sdavemq goto fail; 18134732Sdavemq 18144732Sdavemq NXGE_DELAY(200); 18154732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18164732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) 18174732Sdavemq goto fail; 18184732Sdavemq 18194732Sdavemq NXGE_DELAY(200); 18204732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 18214732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 18224732Sdavemq &val16l)) != NXGE_OK) 18234732Sdavemq goto fail; 18244732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18254732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) 18264732Sdavemq goto fail; 18274732Sdavemq if ((val16l != 0) || (val16h != 0)) { 18284732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18295196Ssbehera "Failed to reset port<%d> XAUI Serdes " 18305196Ssbehera "(val16l 0x%x val16h 0x%x)", 18315196Ssbehera portn, val16l, val16h)); 18324732Sdavemq } 18334732Sdavemq 18344732Sdavemq if (portn == 0) { 18356075Ssbehera /* Wait for serdes to be ready */ 18366075Ssbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 18376075Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 18386075Ssbehera if ((val & ESR_SIG_P0_BITS_MASK) != 18396075Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 18406075Ssbehera ESR_SIG_XSERDES_RDY_P0 | 18416075Ssbehera ESR_SIG_XDETECT_P0_CH3 | 18426075Ssbehera ESR_SIG_XDETECT_P0_CH2 | 18436075Ssbehera ESR_SIG_XDETECT_P0_CH1 | 18446075Ssbehera ESR_SIG_XDETECT_P0_CH0)) 18456075Ssbehera 18466075Ssbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 18476075Ssbehera else 18486075Ssbehera break; 18496075Ssbehera } 18506075Ssbehera 18516075Ssbehera if (i == MAX_SERDES_RDY_RETRIES) { 18526650Sjoycey /* 18536650Sjoycey * RDY signal stays low may due to the absent of the 18546650Sjoycey * external PHY, it is not an error condition. But still 18556650Sjoycey * print the message for the debugging purpose when link 18566650Sjoycey * stays down 18576650Sjoycey */ 18586075Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18596075Ssbehera "nxge_neptune_10G_serdes_init: " 18606075Ssbehera "Serdes/signal for port<%d> not ready", portn)); 18616835Syc148097 goto done; 18624732Sdavemq } 18634732Sdavemq } else if (portn == 1) { 18646075Ssbehera /* Wait for serdes to be ready */ 18656075Ssbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 18666075Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 18676075Ssbehera if ((val & ESR_SIG_P1_BITS_MASK) != 18686075Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 18696075Ssbehera ESR_SIG_XSERDES_RDY_P1 | 18706075Ssbehera ESR_SIG_XDETECT_P1_CH3 | 18716075Ssbehera ESR_SIG_XDETECT_P1_CH2 | 18726075Ssbehera ESR_SIG_XDETECT_P1_CH1 | 18736075Ssbehera ESR_SIG_XDETECT_P1_CH0)) 18746075Ssbehera 18756075Ssbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 18766075Ssbehera else 18776075Ssbehera break; 18786075Ssbehera } 18796075Ssbehera 18806075Ssbehera if (i == MAX_SERDES_RDY_RETRIES) { 18816650Sjoycey /* 18826650Sjoycey * RDY signal stays low may due to the absent of the 18836650Sjoycey * external PHY, it is not an error condition. But still 18846650Sjoycey * print the message for the debugging purpose when link 18856650Sjoycey * stays down 18866650Sjoycey */ 18876075Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18886075Ssbehera "nxge_neptune_10G_serdes_init: " 18896075Ssbehera "Serdes/signal for port<%d> not ready", portn)); 18906835Syc148097 goto done; 18913859Sml29623 } 18923859Sml29623 } 18933859Sml29623 18943859Sml29623 done: 18954732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18964732Sdavemq "<== nxge_neptune_10G_serdes_init port<%d>", portn)); 18974732Sdavemq 18983859Sml29623 return (NXGE_OK); 18993859Sml29623 fail: 19005572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19014732Sdavemq "nxge_neptune_10G_serdes_init: " 19024732Sdavemq "Failed to initialize Neptune serdes for port<%d>", portn)); 19033859Sml29623 19043859Sml29623 return (status); 19053859Sml29623 } 19063859Sml29623 19074732Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */ 19084732Sdavemq 19094732Sdavemq static nxge_status_t 19104732Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep) 19113859Sml29623 { 19124732Sdavemq npi_handle_t handle; 19134732Sdavemq uint8_t portn; 19145196Ssbehera int chan; 19155196Ssbehera sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 19165196Ssbehera sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 19175196Ssbehera sr_glue_ctrl0_l_t glue_ctrl0_l; 19185196Ssbehera sr_glue_ctrl0_h_t glue_ctrl0_h; 19194732Sdavemq uint64_t val; 19205196Ssbehera uint16_t val16l; 19215196Ssbehera uint16_t val16h; 19225196Ssbehera nxge_status_t status = NXGE_OK; 19233859Sml29623 19243859Sml29623 portn = nxgep->mac.portnum; 19254732Sdavemq 19264732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19274732Sdavemq "==> nxge_1G_serdes_init port<%d>", portn)); 19284732Sdavemq 19294732Sdavemq handle = nxgep->npi_handle; 19304732Sdavemq 19314732Sdavemq switch (portn) { 19324732Sdavemq case 0: 19335196Ssbehera /* Assert the reset register */ 19345196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 19355196Ssbehera val |= ESR_RESET_0; 19365196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 19375196Ssbehera 19385196Ssbehera /* Set the PLL register to 0x79 */ 19395196Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 19405196Ssbehera ESR_PLL_CFG_1G_SERDES); 19415196Ssbehera 19425196Ssbehera /* Set the control register to 0x249249f */ 19435196Ssbehera ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES); 19445196Ssbehera 19455196Ssbehera /* Set Serdes0 Internal Loopback if necessary */ 19465196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 19475196Ssbehera /* Set pad loopback modes 0xaa */ 19485196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 19495196Ssbehera ESR_TSTCFG_LBTEST_PAD); 19505196Ssbehera } else { 19515196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 19525196Ssbehera } 19535196Ssbehera 19545196Ssbehera /* Deassert the reset register */ 19555196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 19565196Ssbehera val &= ~ESR_RESET_0; 19575196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 19584732Sdavemq break; 19595196Ssbehera 19604732Sdavemq case 1: 19615196Ssbehera /* Assert the reset register */ 19625196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 19635196Ssbehera val |= ESR_RESET_1; 19645196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 19655196Ssbehera 19665196Ssbehera /* Set PLL register to 0x79 */ 19675196Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 19685196Ssbehera ESR_PLL_CFG_1G_SERDES); 19695196Ssbehera 19705196Ssbehera /* Set the control register to 0x249249f */ 19715196Ssbehera ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES); 19725196Ssbehera 19735196Ssbehera /* Set Serdes1 Internal Loopback if necessary */ 19745196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 19755196Ssbehera /* Set pad loopback mode 0xaa */ 19765196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 19775196Ssbehera ESR_TSTCFG_LBTEST_PAD); 19785196Ssbehera } else { 19795196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 19805196Ssbehera } 19815196Ssbehera 19825196Ssbehera /* Deassert the reset register */ 19835196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 19845196Ssbehera val &= ~ESR_RESET_1; 19855196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 19864732Sdavemq break; 19875196Ssbehera 19884732Sdavemq default: 19895196Ssbehera /* Nothing to do here */ 19905196Ssbehera goto done; 19915196Ssbehera } 19925196Ssbehera 19935196Ssbehera /* init TX RX channels */ 19945196Ssbehera for (chan = 0; chan < 4; chan++) { 19955196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 19965196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 19975196Ssbehera &rx_tx_ctrl_l.value)) != NXGE_OK) { 19985196Ssbehera goto fail; 19995196Ssbehera } 20005196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20015196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 20025196Ssbehera &rx_tx_ctrl_h.value)) != NXGE_OK) { 20035196Ssbehera goto fail; 20045196Ssbehera } 20055196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20065196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 20075196Ssbehera &glue_ctrl0_l.value)) != NXGE_OK) { 20085196Ssbehera goto fail; 20095196Ssbehera } 20105196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20115196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 20125196Ssbehera &glue_ctrl0_h.value)) != NXGE_OK) { 20135196Ssbehera goto fail; 20145196Ssbehera } 20155196Ssbehera 20165196Ssbehera rx_tx_ctrl_l.bits.enstretch = 1; 20175196Ssbehera rx_tx_ctrl_h.bits.vmuxlo = 2; 20185196Ssbehera rx_tx_ctrl_h.bits.vpulselo = 2; 20195196Ssbehera glue_ctrl0_l.bits.rxlosenable = 1; 20205196Ssbehera glue_ctrl0_l.bits.samplerate = 0xF; 20215196Ssbehera glue_ctrl0_l.bits.thresholdcount = 0xFF; 20225196Ssbehera glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 20235196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20245196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 20255196Ssbehera rx_tx_ctrl_l.value)) != NXGE_OK) { 20265196Ssbehera goto fail; 20275196Ssbehera } 20285196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20295196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 20305196Ssbehera rx_tx_ctrl_h.value)) != NXGE_OK) { 20315196Ssbehera goto fail; 20325196Ssbehera } 20335196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20345196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 20355196Ssbehera glue_ctrl0_l.value)) != NXGE_OK) { 20365196Ssbehera goto fail; 20375196Ssbehera } 20385196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20395196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 20405196Ssbehera glue_ctrl0_h.value)) != NXGE_OK) { 20415196Ssbehera goto fail; 20425196Ssbehera } 20435196Ssbehera } 20445196Ssbehera 20455196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20465196Ssbehera ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) { 20474732Sdavemq goto fail; 20483859Sml29623 } 20495196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20505196Ssbehera ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 20515196Ssbehera goto fail; 20525196Ssbehera } 20535196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20545196Ssbehera ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) { 20555196Ssbehera goto fail; 20565196Ssbehera } 20575196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20585196Ssbehera ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 20595196Ssbehera goto fail; 20605196Ssbehera } 20615196Ssbehera 20625196Ssbehera /* Apply Tx core reset */ 20635196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20645196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) { 20655196Ssbehera goto fail; 20665196Ssbehera } 20675196Ssbehera 20685196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20695196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 20705196Ssbehera NXGE_OK) { 20715196Ssbehera goto fail; 20725196Ssbehera } 20735196Ssbehera 20745196Ssbehera NXGE_DELAY(200); 20755196Ssbehera 20765196Ssbehera /* Apply Rx core reset */ 20775196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20785196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 20795196Ssbehera NXGE_OK) { 20805196Ssbehera goto fail; 20815196Ssbehera } 20825196Ssbehera 20835196Ssbehera NXGE_DELAY(200); 20845196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20855196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) { 20865196Ssbehera goto fail; 20875196Ssbehera } 20885196Ssbehera 20895196Ssbehera NXGE_DELAY(200); 20905196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20915196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) { 20925196Ssbehera goto fail; 20935196Ssbehera } 20945196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20955196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) { 20965196Ssbehera goto fail; 20975196Ssbehera } 20985196Ssbehera if ((val16l != 0) || (val16h != 0)) { 20995196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21005196Ssbehera "Failed to reset port<%d> XAUI Serdes " 21015196Ssbehera "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h)); 21025196Ssbehera status = NXGE_ERROR; 21035196Ssbehera goto fail; 21045196Ssbehera } 21055196Ssbehera 21065196Ssbehera NXGE_DELAY(200); 21075196Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 21085196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 21095196Ssbehera "nxge_neptune_serdes_init: read internal signal reg port<%d> " 21105196Ssbehera "val 0x%x", portn, val)); 21115196Ssbehera if (portn == 0) { 21125196Ssbehera if ((val & ESR_SIG_P0_BITS_MASK_1G) != 21135196Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) { 21146650Sjoycey /* 21156650Sjoycey * RDY signal stays low may due to the absent of the 21166650Sjoycey * external PHY, it is not an error condition. But still 21176650Sjoycey * print the message for the debugging purpose when link 21186650Sjoycey * stays down 21196650Sjoycey */ 21205196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21216650Sjoycey "nxge_neptune_1G_serdes_init: " 21226650Sjoycey "Serdes/signal for port<%d> not ready", portn)); 21236835Syc148097 goto done; 21245196Ssbehera } 21255196Ssbehera } else if (portn == 1) { 21265196Ssbehera if ((val & ESR_SIG_P1_BITS_MASK_1G) != 21275196Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) { 21286650Sjoycey /* 21296650Sjoycey * RDY signal stays low may due to the absent of the 21306650Sjoycey * external PHY, it is not an error condition. But still 21316650Sjoycey * print the message for the debugging purpose when link 21326650Sjoycey * stays down 21336650Sjoycey */ 21345196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21356650Sjoycey "nxge_neptune_1G_serdes_init: " 21366650Sjoycey "Serdes/signal for port<%d> not ready", portn)); 21376835Syc148097 goto done; 21386835Syc148097 21395196Ssbehera } 21405196Ssbehera } 21415196Ssbehera done: 21424732Sdavemq 21434732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 21444732Sdavemq "<== nxge_1G_serdes_init port<%d>", portn)); 21453859Sml29623 return (NXGE_OK); 21464732Sdavemq fail: 21475196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21484732Sdavemq "nxge_1G_serdes_init: " 21494732Sdavemq "Failed to initialize Neptune serdes for port<%d>", 21504732Sdavemq portn)); 21514732Sdavemq 21525196Ssbehera return (status); 21533859Sml29623 } 21543859Sml29623 21555572Ssbehera /* Initialize the BCM 8704 xcvr */ 21564732Sdavemq 21574732Sdavemq static nxge_status_t 21585572Ssbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep) 21593859Sml29623 { 21603859Sml29623 uint16_t val; 21613859Sml29623 #ifdef NXGE_DEBUG 21623859Sml29623 uint8_t portn; 21633859Sml29623 uint16_t val1; 21643859Sml29623 #endif 21653859Sml29623 uint8_t phy_port_addr; 21663859Sml29623 pmd_tx_control_t tx_ctl; 21673859Sml29623 control_t ctl; 21683859Sml29623 phyxs_control_t phyxs_ctl; 21693859Sml29623 pcs_control_t pcs_ctl; 21703859Sml29623 uint32_t delay = 0; 21713859Sml29623 optics_dcntr_t op_ctr; 21723859Sml29623 nxge_status_t status = NXGE_OK; 21733859Sml29623 #ifdef NXGE_DEBUG 21743859Sml29623 portn = nxgep->mac.portnum; 21753859Sml29623 #endif 21765572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>", 21774732Sdavemq portn)); 21784732Sdavemq 21794732Sdavemq phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 21804732Sdavemq 21814732Sdavemq /* Reset the transceiver */ 21824732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 21834732Sdavemq BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 21844732Sdavemq goto fail; 21854732Sdavemq 21864732Sdavemq phyxs_ctl.bits.reset = 1; 21874732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 21884732Sdavemq BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 21894732Sdavemq goto fail; 21904732Sdavemq 21914732Sdavemq do { 21924732Sdavemq drv_usecwait(500); 21934732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 21944732Sdavemq BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 21954732Sdavemq &phyxs_ctl.value)) != NXGE_OK) 21964732Sdavemq goto fail; 21974732Sdavemq delay++; 21984732Sdavemq } while ((phyxs_ctl.bits.reset) && (delay < 100)); 21994732Sdavemq if (delay == 100) { 22004732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 22014732Sdavemq "failed to reset Transceiver on port<%d>", portn)); 22024732Sdavemq status = NXGE_ERROR; 22034732Sdavemq goto fail; 22044732Sdavemq } 22054732Sdavemq 22064732Sdavemq /* Set to 0x7FBF */ 22074732Sdavemq ctl.value = 0; 22084732Sdavemq ctl.bits.res1 = 0x3F; 22094732Sdavemq ctl.bits.optxon_lvl = 1; 22104732Sdavemq ctl.bits.oprxflt_lvl = 1; 22114732Sdavemq ctl.bits.optrxlos_lvl = 1; 22124732Sdavemq ctl.bits.optxflt_lvl = 1; 22134732Sdavemq ctl.bits.opprflt_lvl = 1; 22144732Sdavemq ctl.bits.obtmpflt_lvl = 1; 22154732Sdavemq ctl.bits.opbiasflt_lvl = 1; 22164732Sdavemq ctl.bits.optxrst_lvl = 1; 22174732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22184732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value)) 22194732Sdavemq != NXGE_OK) 22204732Sdavemq goto fail; 22214732Sdavemq 22224732Sdavemq /* Set to 0x164 */ 22234732Sdavemq tx_ctl.value = 0; 22244732Sdavemq tx_ctl.bits.tsck_lpwren = 1; 22254732Sdavemq tx_ctl.bits.tx_dac_txck = 0x2; 22264732Sdavemq tx_ctl.bits.tx_dac_txd = 0x1; 22274732Sdavemq tx_ctl.bits.xfp_clken = 1; 22284732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22294732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, 22304732Sdavemq tx_ctl.value)) != NXGE_OK) 22314732Sdavemq goto fail; 22324732Sdavemq /* 22334732Sdavemq * According to Broadcom's instruction, SW needs to read 22344732Sdavemq * back these registers twice after written. 22354732Sdavemq */ 22364732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22374732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 22384732Sdavemq != NXGE_OK) 22394732Sdavemq goto fail; 22404732Sdavemq 22414732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22424732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 22434732Sdavemq != NXGE_OK) 22444732Sdavemq goto fail; 22454732Sdavemq 22464732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22474732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 22484732Sdavemq != NXGE_OK) 22494732Sdavemq goto fail; 22504732Sdavemq 22514732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22524732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 22534732Sdavemq != NXGE_OK) 22544732Sdavemq goto fail; 22554732Sdavemq 22564732Sdavemq /* Enable Tx and Rx LEDs to be driven by traffic */ 22574732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22584732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 22594732Sdavemq &op_ctr.value)) != NXGE_OK) 22604732Sdavemq goto fail; 22615553Smisaki if (NXGE_IS_XAUI_PLATFORM(nxgep)) { 22625553Smisaki op_ctr.bits.gpio_sel = 0x1; 22635553Smisaki } else { 22645553Smisaki op_ctr.bits.gpio_sel = 0x3; 22655553Smisaki } 22664732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22674732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 22684732Sdavemq op_ctr.value)) != NXGE_OK) 22694732Sdavemq goto fail; 22704732Sdavemq 22714732Sdavemq NXGE_DELAY(1000000); 22724732Sdavemq 22734732Sdavemq /* Set BCM8704 Internal Loopback mode if necessary */ 22744732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22754732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 22764732Sdavemq != NXGE_OK) 22774732Sdavemq goto fail; 22784732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 22794732Sdavemq pcs_ctl.bits.loopback = 1; 22804732Sdavemq else 22814732Sdavemq pcs_ctl.bits.loopback = 0; 22824732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22834732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 22844732Sdavemq != NXGE_OK) 22854732Sdavemq goto fail; 22864732Sdavemq 22874732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val); 22884732Sdavemq if (status != NXGE_OK) 22894732Sdavemq goto fail; 22904732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 22914732Sdavemq "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val)); 22924732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 22934732Sdavemq if (status != NXGE_OK) 22944732Sdavemq goto fail; 22954732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 22964732Sdavemq "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val)); 22974732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 22984732Sdavemq if (status != NXGE_OK) 22994732Sdavemq goto fail; 23004732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 23014732Sdavemq "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val)); 23024732Sdavemq 23034732Sdavemq #ifdef NXGE_DEBUG 23044732Sdavemq /* Diagnose link issue if link is not up */ 23054732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR, 23064732Sdavemq BCM8704_USER_ANALOG_STATUS0_REG, 23074732Sdavemq &val); 23084732Sdavemq if (status != NXGE_OK) 23094732Sdavemq goto fail; 23104732Sdavemq 23114732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 23126929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val); 23134732Sdavemq if (status != NXGE_OK) 23144732Sdavemq goto fail; 23154732Sdavemq 23164732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 23176929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1); 23184732Sdavemq if (status != NXGE_OK) 23194732Sdavemq goto fail; 23204732Sdavemq 23214732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 23226929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1); 23234732Sdavemq if (status != NXGE_OK) 23244732Sdavemq goto fail; 23254732Sdavemq 23264732Sdavemq if (val != 0x3FC) { 23274732Sdavemq if ((val == 0x43BC) && (val1 != 0)) { 23284732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 23294732Sdavemq "Cable not connected to peer or bad" 23304732Sdavemq " cable on port<%d>\n", portn)); 23314732Sdavemq } else if (val == 0x639C) { 23324732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23334732Sdavemq "Optical module (XFP) is bad or absent" 23344732Sdavemq " on port<%d>\n", portn)); 23354732Sdavemq } 23364732Sdavemq } 23374732Sdavemq #endif 23384732Sdavemq 23395572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>", 23405572Ssbehera portn)); 23415572Ssbehera return (NXGE_OK); 23425572Ssbehera 23435572Ssbehera fail: 23445572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23455572Ssbehera "nxge_BCM8704_xcvr_init: failed to initialize transceiver for " 23465572Ssbehera "port<%d>", nxgep->mac.portnum)); 23475572Ssbehera return (NXGE_ERROR); 23485572Ssbehera } 23495572Ssbehera 23505572Ssbehera /* Initialize the BCM 8706 Transceiver */ 23515572Ssbehera 23525572Ssbehera static nxge_status_t 23535572Ssbehera nxge_BCM8706_xcvr_init(p_nxge_t nxgep) 23545572Ssbehera { 23555572Ssbehera uint8_t phy_port_addr; 23565572Ssbehera phyxs_control_t phyxs_ctl; 23575572Ssbehera pcs_control_t pcs_ctl; 23585572Ssbehera uint32_t delay = 0; 23595572Ssbehera optics_dcntr_t op_ctr; 23605572Ssbehera nxge_status_t status = NXGE_OK; 23615572Ssbehera #ifdef NXGE_DEBUG 23625572Ssbehera uint8_t portn = nxgep->mac.portnum; 23635572Ssbehera #endif 23645572Ssbehera 23655572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>", 23665572Ssbehera portn)); 23675572Ssbehera 23685572Ssbehera phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 23695572Ssbehera 23705572Ssbehera /* Reset the transceiver */ 23715572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 23725572Ssbehera BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 23735572Ssbehera goto fail; 23745572Ssbehera 23755572Ssbehera phyxs_ctl.bits.reset = 1; 23765572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 23775572Ssbehera BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 23785572Ssbehera goto fail; 23795572Ssbehera do { 23805572Ssbehera drv_usecwait(500); 23815572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 23825572Ssbehera BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 23835572Ssbehera &phyxs_ctl.value)) != NXGE_OK) 23845572Ssbehera goto fail; 23855572Ssbehera delay++; 23865572Ssbehera } while ((phyxs_ctl.bits.reset) && (delay < 100)); 23875572Ssbehera 23885572Ssbehera if (delay == 100) { 23895572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 23905572Ssbehera "failed to reset Transceiver on port<%d>", portn)); 23915572Ssbehera status = NXGE_ERROR; 23925572Ssbehera goto fail; 23935572Ssbehera } 23945572Ssbehera 23955572Ssbehera NXGE_DELAY(1000000); 23965572Ssbehera 23975572Ssbehera /* Set BCM8706 Internal Loopback mode if necessary */ 23985572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 23995572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 24005572Ssbehera != NXGE_OK) 24015572Ssbehera goto fail; 24025572Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 24035572Ssbehera pcs_ctl.bits.loopback = 1; 24045572Ssbehera else 24055572Ssbehera pcs_ctl.bits.loopback = 0; 24065572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 24075572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 24085572Ssbehera != NXGE_OK) 24095572Ssbehera goto fail; 24105572Ssbehera 24115572Ssbehera /* Enable Tx and Rx LEDs to be driven by traffic */ 24125572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 24135572Ssbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 24145572Ssbehera &op_ctr.value)) != NXGE_OK) 24155572Ssbehera goto fail; 24165572Ssbehera op_ctr.bits.gpio_sel = 0x3; 24175572Ssbehera op_ctr.bits.res2 = 0x1; 24185572Ssbehera 24195572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 24205572Ssbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 24215572Ssbehera op_ctr.value)) != NXGE_OK) 24225572Ssbehera goto fail; 24235572Ssbehera 24245572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>", 24255572Ssbehera portn)); 24265572Ssbehera return (NXGE_OK); 24275572Ssbehera 24285572Ssbehera fail: 24295572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 24305572Ssbehera "nxge_BCM8706_xcvr_init: failed to initialize transceiver for " 24315572Ssbehera "port<%d>", nxgep->mac.portnum)); 24325572Ssbehera return (status); 24335572Ssbehera } 24345572Ssbehera 24356604Ssbehera #define CHK_STAT(x) status = (x); if (status != NXGE_OK) goto fail 24366604Ssbehera 24376604Ssbehera #define MRVL88X2011_RD(nxgep, port, d, r, p) \ 24386604Ssbehera CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p)) 24396604Ssbehera 24406604Ssbehera #define MRVL88X2011_WR(nxgep, port, d, r, p) \ 24416604Ssbehera CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p)) 24426604Ssbehera 24436604Ssbehera 24446604Ssbehera static void 24456604Ssbehera nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate) 24466604Ssbehera { 24476604Ssbehera uint16_t value; 24486604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 24496604Ssbehera 24506604Ssbehera if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR, 24516604Ssbehera MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) { 24526604Ssbehera value &= ~MRVL_88X2011_LED_BLK_MASK; 24536604Ssbehera value |= (rate << MRVL_88X2011_LED_BLK_SHIFT); 24546604Ssbehera (void) nxge_mdio_write(nxgep, phy, 24556604Ssbehera MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL, 24566604Ssbehera value); 24576604Ssbehera } 24586604Ssbehera } 24596604Ssbehera 24606604Ssbehera static nxge_status_t 24616604Ssbehera nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep) 24626604Ssbehera { 24636604Ssbehera nxge_status_t status; 24646604Ssbehera pcs_control_t pcs_ctl; 24656604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 24666604Ssbehera 24676604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 24686604Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value); 24696604Ssbehera 24706604Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 24716604Ssbehera pcs_ctl.bits.loopback = 1; 24726604Ssbehera else 24736604Ssbehera pcs_ctl.bits.loopback = 0; 24746604Ssbehera 24756604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 24766604Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value); 24776604Ssbehera 24786604Ssbehera fail: 24796604Ssbehera return (status); 24806604Ssbehera } 24816604Ssbehera 24826604Ssbehera 24836604Ssbehera static void 24846604Ssbehera nxge_mrvl88x2011_led(p_nxge_t nxgep, uint16_t val) 24856604Ssbehera { 24866604Ssbehera uint16_t val2; 24876604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 24886604Ssbehera 24896604Ssbehera val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val); 24906604Ssbehera val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, 24916604Ssbehera MRVL_88X2011_LED_CTL_MASK); 24926604Ssbehera val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val); 24936604Ssbehera 24946604Ssbehera if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR, 24956604Ssbehera MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) { 24966604Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 24976604Ssbehera "nxge_mrvl88x2011_led: nxge_mdio_write failed!!")); 24986604Ssbehera } 24996604Ssbehera } 25006604Ssbehera 25016604Ssbehera 25026604Ssbehera static nxge_status_t 25036604Ssbehera nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep) 25046604Ssbehera { 25056604Ssbehera uint8_t phy; 25066604Ssbehera nxge_status_t status; 25076604Ssbehera uint16_t clk; 25086604Ssbehera 25096604Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn; 25106604Ssbehera 25116604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 25126604Ssbehera "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>", 25136604Ssbehera nxgep->mac.portnum, phy)); 25146604Ssbehera 25156604Ssbehera /* Set LED functions */ 25166604Ssbehera nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS); 25176604Ssbehera /* PCS activity */ 25186604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT); 25196604Ssbehera 25206604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 25216604Ssbehera MRVL_88X2011_GEN_CTL, &clk); 25226604Ssbehera clk |= MRVL_88X2011_ENA_XFPREFCLK; 25236604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 25246604Ssbehera MRVL_88X2011_GEN_CTL, clk); 25256604Ssbehera 25266604Ssbehera /* Set internal loopback mode if necessary */ 25276604Ssbehera 25286604Ssbehera CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep)); 25296604Ssbehera 25306604Ssbehera /* Enable PMD */ 25316604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 25326604Ssbehera MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX); 25336604Ssbehera 25346604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK")); 25356604Ssbehera 25366604Ssbehera fail: 25376604Ssbehera return (status); 25386604Ssbehera } 25396604Ssbehera 25406604Ssbehera 25416604Ssbehera 25425572Ssbehera /* Initialize the 10G Transceiver */ 25435572Ssbehera 25445572Ssbehera static nxge_status_t 25455572Ssbehera nxge_10G_xcvr_init(p_nxge_t nxgep) 25465572Ssbehera { 25475572Ssbehera p_nxge_stats_t statsp; 25486439Sml29623 p_nxge_param_t param_arr = nxgep->param_arr; 25495572Ssbehera nxge_status_t status = NXGE_OK; 25505572Ssbehera #ifdef NXGE_DEBUG 25515572Ssbehera uint8_t portn = nxgep->mac.portnum; 25525572Ssbehera #endif 25535572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 25545572Ssbehera portn)); 25555572Ssbehera 25565572Ssbehera statsp = nxgep->statsp; 25575572Ssbehera 25585572Ssbehera if (nxgep->mac.portmode == PORT_10G_SERDES) { 25595572Ssbehera goto done; 25605572Ssbehera } 25615572Ssbehera 25625572Ssbehera /* Disable Link LEDs */ 25635572Ssbehera if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 25645572Ssbehera goto fail; 25655572Ssbehera 25665572Ssbehera /* Set Clause 45 */ 25675572Ssbehera npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 25685572Ssbehera 25695572Ssbehera switch (nxgep->chip_id) { 25705572Ssbehera case BCM8704_CHIP_ID: 25716835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 25725572Ssbehera "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id)); 25735572Ssbehera status = nxge_BCM8704_xcvr_init(nxgep); 25745572Ssbehera break; 25755572Ssbehera case BCM8706_CHIP_ID: 25766835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 25775572Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id)); 25785572Ssbehera status = nxge_BCM8706_xcvr_init(nxgep); 25795572Ssbehera break; 25806604Ssbehera case MRVL88X201X_CHIP_ID: 25816835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 25826604Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id)); 25836604Ssbehera status = nxge_mrvl88x2011_xcvr_init(nxgep); 25846604Ssbehera break; 25855572Ssbehera default: 25865572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: " 25875572Ssbehera "Unknown chip ID 0x%x for 10G xcvr addr[%d]", 25885572Ssbehera nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn)); 25895572Ssbehera goto fail; 25905572Ssbehera } 25915572Ssbehera 25925572Ssbehera if (status != NXGE_OK) { 25935572Ssbehera goto fail; 25945572Ssbehera } 25954977Sraghus done: 25964732Sdavemq statsp->mac_stats.cap_10gfdx = 1; 25974732Sdavemq statsp->mac_stats.lp_cap_10gfdx = 1; 25986439Sml29623 statsp->mac_stats.adv_cap_asmpause = 25996439Sml29623 param_arr[param_anar_asmpause].value; 26006439Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 26014732Sdavemq 26024732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 26034732Sdavemq portn)); 26044732Sdavemq return (NXGE_OK); 26054732Sdavemq 26064732Sdavemq fail: 26075572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 26084732Sdavemq "nxge_10G_xcvr_init: failed to initialize transceiver for " 26095572Ssbehera "port<%d>", nxgep->mac.portnum)); 26105572Ssbehera return (NXGE_ERROR); 26114732Sdavemq } 26124732Sdavemq 26134732Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */ 26144732Sdavemq 26154732Sdavemq static nxge_status_t 26164732Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep) 26174732Sdavemq { 26184732Sdavemq p_nxge_param_t param_arr = nxgep->param_arr; 26194732Sdavemq p_nxge_stats_t statsp = nxgep->statsp; 26204732Sdavemq nxge_status_t status = NXGE_OK; 26214732Sdavemq 26224977Sraghus if (nxgep->mac.portmode == PORT_1G_SERDES) { 26234977Sraghus statsp->mac_stats.cap_1000fdx = 26244977Sraghus param_arr[param_anar_1000fdx].value; 26254977Sraghus goto done; 26264977Sraghus } 26274977Sraghus 26284732Sdavemq /* Set Clause 22 */ 26294732Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 26304732Sdavemq 26314732Sdavemq /* Set capability flags */ 26324732Sdavemq statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value; 26334977Sraghus if ((nxgep->mac.portmode == PORT_1G_COPPER) || 26344977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER)) { 26354977Sraghus statsp->mac_stats.cap_100fdx = 26364977Sraghus param_arr[param_anar_100fdx].value; 26374977Sraghus statsp->mac_stats.cap_10fdx = 26384977Sraghus param_arr[param_anar_10fdx].value; 26394977Sraghus } 26404732Sdavemq 26414732Sdavemq status = nxge_mii_xcvr_init(nxgep); 26424977Sraghus done: 26434732Sdavemq return (status); 26444732Sdavemq } 26454732Sdavemq 26466835Syc148097 /* 26476835Syc148097 * Although the Teranetics copper transceiver (TN1010) does not need 26486835Syc148097 * to be initialized by the driver for passing packets, this funtion 26496835Syc148097 * initializes the members of nxgep->statsp->mac_stats struct for 26506835Syc148097 * kstat based on the value of nxgep->statsp->ports_stats.lb_mode. 26516835Syc148097 * It also configures the TN1010 for PHY loopback to support SunVTS. 26526835Syc148097 * 26536835Syc148097 * TN1010 only has the option to disable advertisement for the 10G 26546835Syc148097 * mode. So we can set it to either Dual Mode or 1G Only mode but 26556835Syc148097 * can't set it to 10G Only mode. 26566835Syc148097 * 26576835Syc148097 * ndd -set command can set the following 6 speed/duplex related parameters. 26586835Syc148097 * 26596835Syc148097 * ---------------------------------------------------------------- 26606835Syc148097 * ndd -set /dev/nxgeX param n kstat nxge:X | grep param 26616835Syc148097 * ---------------------------------------------------------------- 26626835Syc148097 * adv_autoneg_cap kstat nxge:1 | grep adv_cap_autoneg 26636835Syc148097 * adv_10gfdx_cap 26646835Syc148097 * adv_1000fdx_cap kstat nxge:1 | grep adv_cap_1000fdx 26656835Syc148097 * adv_100fdx_cap kstat nxge:1 | grep adv_cap_100fdx 26666835Syc148097 * adv_10fdx_cap kstat nxge:1 | grep adv_cap_10fdx 26676835Syc148097 * adv_pause_cap kstat nxge:1 | grep adv_cap_pause 26686835Syc148097 * ---------------------------------------------------------------- 26696835Syc148097 */ 26706835Syc148097 static nxge_status_t 26716835Syc148097 nxge_tn1010_xcvr_init(p_nxge_t nxgep) 26726835Syc148097 { 26736835Syc148097 p_nxge_param_t param_arr; 26746835Syc148097 p_nxge_stats_t statsp; 26756835Syc148097 tn1010_pcs_ctrl_t tn1010_pcs_ctrl; 26766835Syc148097 uint16_t speed; 26776835Syc148097 uint8_t phy_port_addr; 26786835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 26796835Syc148097 int status = NXGE_OK; 26806835Syc148097 26816835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init")); 26826835Syc148097 26836835Syc148097 param_arr = nxgep->param_arr; 26846835Syc148097 statsp = nxgep->statsp; 26856835Syc148097 26866835Syc148097 /* 26876835Syc148097 * Initialize the xcvr statistics which are NOT controlled by ndd 26886835Syc148097 */ 26896835Syc148097 statsp->mac_stats.cap_autoneg = 1; /* TN1010 autoneg is always on */ 26906835Syc148097 statsp->mac_stats.cap_100T4 = 0; 26916835Syc148097 26926835Syc148097 /* 26936835Syc148097 * Read the TN1010 link speed and initialize capabilities kstat. Note 26946835Syc148097 * that function nxge_check_tn1010_link repeatedly invoked by the 26956835Syc148097 * timer will update link_speed real time. 26966835Syc148097 */ 26976835Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) { 26986835Syc148097 goto fail; 26996835Syc148097 } 27006835Syc148097 if (speed == TN1010_SPEED_1G) { 27016835Syc148097 statsp->mac_stats.cap_10gfdx = 0; 27026835Syc148097 } else { 27036835Syc148097 statsp->mac_stats.cap_10gfdx = 1; 27046835Syc148097 } 27056835Syc148097 27066835Syc148097 /* Whether we are in 1G or 10G mode, we always have the 1G capability */ 27076835Syc148097 statsp->mac_stats.cap_1000fdx = 1; 27086835Syc148097 27096835Syc148097 /* TN1010 is not able to operate in the following states */ 27106835Syc148097 statsp->mac_stats.cap_1000hdx = 0; 27116835Syc148097 statsp->mac_stats.cap_100fdx = 0; 27126835Syc148097 statsp->mac_stats.cap_100hdx = 0; 27136835Syc148097 statsp->mac_stats.cap_10fdx = 0; 27146835Syc148097 statsp->mac_stats.cap_10hdx = 0; 27156835Syc148097 27166835Syc148097 /* param_anar_pause can be modified by ndd -set */ 27176835Syc148097 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 27186835Syc148097 27196835Syc148097 /* 27206835Syc148097 * The following 4 lines actually overwrites what ever the ndd command 27216835Syc148097 * has set. For example, by command 27226835Syc148097 * ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1) 27236835Syc148097 * we could set param_arr[param_autoneg].value to n. However, because 27246835Syc148097 * here we assign constants to these parameters, whatever we set with 27256835Syc148097 * the "ndd -set" command will be replaced. So command 27266835Syc148097 * kstat nxge:X | grep param 27276835Syc148097 * will always show those constant values. In other words, the 27286835Syc148097 * "ndd -set" command can NOT change the values of these 4 parameters 27296835Syc148097 * even though the command appears to be successful. 27306835Syc148097 * 27316835Syc148097 * Note: TN1010 auto negotiation is always enabled. 27326835Syc148097 */ 27336835Syc148097 statsp->mac_stats.adv_cap_autoneg 27346835Syc148097 = param_arr[param_autoneg].value = 1; 27356835Syc148097 statsp->mac_stats.adv_cap_1000fdx 27366835Syc148097 = param_arr[param_anar_1000fdx].value = 1; 27376835Syc148097 statsp->mac_stats.adv_cap_100fdx 27386835Syc148097 = param_arr[param_anar_100fdx].value = 0; 27396835Syc148097 statsp->mac_stats.adv_cap_10fdx 27406835Syc148097 = param_arr[param_anar_10fdx].value = 0; 27416835Syc148097 27426835Syc148097 /* 27436835Syc148097 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as 27446835Syc148097 * defined in nxge_param_arr[], therefore they are not seen by the 27456835Syc148097 * "ndd -get" command and can not be changed by ndd. We just set 27466835Syc148097 * them (both ndd param and kstat values) to constant 0 because TN1010 27476835Syc148097 * does not support those speeds. 27486835Syc148097 */ 27496835Syc148097 statsp->mac_stats.adv_cap_100T4 27506835Syc148097 = param_arr[param_anar_100T4].value = 0; 27516835Syc148097 statsp->mac_stats.adv_cap_1000hdx 27526835Syc148097 = param_arr[param_anar_1000hdx].value = 0; 27536835Syc148097 statsp->mac_stats.adv_cap_100hdx 27546835Syc148097 = param_arr[param_anar_100hdx].value = 0; 27556835Syc148097 statsp->mac_stats.adv_cap_10hdx 27566835Syc148097 = param_arr[param_anar_10hdx].value = 0; 27576835Syc148097 27586835Syc148097 /* 27596835Syc148097 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified 27606835Syc148097 * by ndd 27616835Syc148097 */ 27626835Syc148097 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 27636835Syc148097 27646835Syc148097 /* 27656835Syc148097 * nxge_param_arr[] defines the adv_cap_asmpause with type 27666835Syc148097 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the 27676835Syc148097 * "ndd -get" command and can not be changed by ndd. Here we do not 27686835Syc148097 * assign a constant to it so the default value defined in 27696835Syc148097 * nxge_param_arr[] will be used to set the parameter and 27706835Syc148097 * will be shown by the kstat. 27716835Syc148097 */ 27726835Syc148097 statsp->mac_stats.adv_cap_asmpause 27736835Syc148097 = param_arr[param_anar_asmpause].value; 27746835Syc148097 27756835Syc148097 /* 27766835Syc148097 * Initialize the link statistics. 27776835Syc148097 */ 27786835Syc148097 statsp->mac_stats.link_T4 = 0; 27796835Syc148097 statsp->mac_stats.link_asmpause = 0; 27806835Syc148097 statsp->mac_stats.link_pause = 0; 27816835Syc148097 if (speed == TN1010_SPEED_1G) { 27826835Syc148097 statsp->mac_stats.link_speed = 1000; 27836835Syc148097 statsp->mac_stats.link_duplex = 2; /* Full duplex */ 27846835Syc148097 statsp->mac_stats.link_up = 1; 27856835Syc148097 } else { 27866835Syc148097 statsp->mac_stats.link_speed = 10000; 27876835Syc148097 statsp->mac_stats.link_duplex = 2; 27886835Syc148097 statsp->mac_stats.link_up = 1; 27896835Syc148097 } 27906835Syc148097 27916835Syc148097 /* 27926835Syc148097 * Because TN1010 does not have a link partner register, to 27936835Syc148097 * figure out the link partner's capabilities is tricky. Here we 27946835Syc148097 * just set the kstat based on our knowledge about the partner 27956835Syc148097 * (The partner must support auto-neg because auto-negotiation 27966835Syc148097 * has completed, it must support 1G or 10G because that is the 27976835Syc148097 * negotiated speed we are using.) 27986835Syc148097 * 27996835Syc148097 * Note: Current kstat does not show lp_cap_10gfdx and 28006835Syc148097 * lp_cap_10ghdx. 28016835Syc148097 */ 28026835Syc148097 if (speed == TN1010_SPEED_1G) { 28036835Syc148097 statsp->mac_stats.lp_cap_1000fdx = 1; 28046835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0; 28056835Syc148097 } else { 28066835Syc148097 statsp->mac_stats.lp_cap_1000fdx = 0; 28076835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 1; 28086835Syc148097 } 28096835Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0; 28106835Syc148097 statsp->mac_stats.lp_cap_1000hdx = 0; 28116835Syc148097 statsp->mac_stats.lp_cap_100fdx = 0; 28126835Syc148097 statsp->mac_stats.lp_cap_100hdx = 0; 28136835Syc148097 statsp->mac_stats.lp_cap_10fdx = 0; 28146835Syc148097 statsp->mac_stats.lp_cap_10hdx = 0; 28156835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0; 28166835Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0; 28176835Syc148097 statsp->mac_stats.lp_cap_100T4 = 0; 28186835Syc148097 statsp->mac_stats.lp_cap_autoneg = 1; 28196835Syc148097 statsp->mac_stats.lp_cap_asmpause = 0; 28206835Syc148097 statsp->mac_stats.lp_cap_pause = 0; 28216835Syc148097 28226835Syc148097 /* Handle PHY loopback for SunVTS loopback test */ 28236835Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 28246835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 28256835Syc148097 28266835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 28276835Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG, 28286835Syc148097 &tn1010_pcs_ctrl.value)) != NXGE_OK) { 28296835Syc148097 goto fail; 28306835Syc148097 } 28316835Syc148097 if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) || 28326835Syc148097 (statsp->port_stats.lb_mode == nxge_lb_phy10g)) { 28336835Syc148097 tn1010_pcs_ctrl.bits.loopback = 1; 28346835Syc148097 } else { 28356835Syc148097 tn1010_pcs_ctrl.bits.loopback = 0; 28366835Syc148097 } 28376835Syc148097 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 28386835Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG, 28396835Syc148097 tn1010_pcs_ctrl.value)) != NXGE_OK) { 28406835Syc148097 goto fail; 28416835Syc148097 } 28426835Syc148097 28436835Syc148097 statsp->mac_stats.xcvr_inits++; 28446835Syc148097 28456835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 28466835Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status)); 28476835Syc148097 return (status); 28486835Syc148097 fail: 28496835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 28506835Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status)); 28516835Syc148097 return (status); 28526835Syc148097 } 28536835Syc148097 28544732Sdavemq /* Initialize transceiver */ 28554732Sdavemq 28564732Sdavemq nxge_status_t 28574732Sdavemq nxge_xcvr_init(p_nxge_t nxgep) 28584732Sdavemq { 28594732Sdavemq p_nxge_stats_t statsp; 28604732Sdavemq #ifdef NXGE_DEBUG 28614732Sdavemq uint8_t portn; 28624732Sdavemq #endif 28634732Sdavemq 28644732Sdavemq nxge_status_t status = NXGE_OK; 28654732Sdavemq #ifdef NXGE_DEBUG 28664732Sdavemq portn = nxgep->mac.portnum; 28674732Sdavemq #endif 28683859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 28693859Sml29623 statsp = nxgep->statsp; 28703859Sml29623 28713859Sml29623 /* 28726835Syc148097 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will 28736835Syc148097 * modify mac_stats. 28743859Sml29623 */ 28753859Sml29623 statsp->mac_stats.cap_autoneg = 0; 28763859Sml29623 statsp->mac_stats.cap_100T4 = 0; 28773859Sml29623 statsp->mac_stats.cap_100fdx = 0; 28783859Sml29623 statsp->mac_stats.cap_100hdx = 0; 28793859Sml29623 statsp->mac_stats.cap_10fdx = 0; 28803859Sml29623 statsp->mac_stats.cap_10hdx = 0; 28813859Sml29623 statsp->mac_stats.cap_asmpause = 0; 28823859Sml29623 statsp->mac_stats.cap_pause = 0; 28833859Sml29623 statsp->mac_stats.cap_1000fdx = 0; 28843859Sml29623 statsp->mac_stats.cap_1000hdx = 0; 28853859Sml29623 statsp->mac_stats.cap_10gfdx = 0; 28863859Sml29623 statsp->mac_stats.cap_10ghdx = 0; 28873859Sml29623 28883859Sml29623 /* 28893859Sml29623 * Initialize the link statistics. 28903859Sml29623 */ 28913859Sml29623 statsp->mac_stats.link_T4 = 0; 28923859Sml29623 statsp->mac_stats.link_asmpause = 0; 28933859Sml29623 statsp->mac_stats.link_pause = 0; 28943859Sml29623 28954732Sdavemq if (nxgep->xcvr.xcvr_init) { 28964732Sdavemq status = nxgep->xcvr.xcvr_init(nxgep); 28973859Sml29623 if (status != NXGE_OK) 28983859Sml29623 goto fail; 28994732Sdavemq statsp->mac_stats.xcvr_inits++; 29003859Sml29623 } 29013859Sml29623 29024732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", 29034732Sdavemq portn)); 29043859Sml29623 return (NXGE_OK); 29053859Sml29623 29063859Sml29623 fail: 29073859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 29084732Sdavemq "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 29094732Sdavemq portn)); 29103859Sml29623 return (status); 29113859Sml29623 } 29123859Sml29623 29134977Sraghus /* Look for transceiver type */ 29144977Sraghus 29154977Sraghus nxge_status_t 29164977Sraghus nxge_xcvr_find(p_nxge_t nxgep) 29174977Sraghus { 29185196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", 29195196Ssbehera nxgep->mac.portnum)); 29204977Sraghus 29214977Sraghus if (nxge_get_xcvr_type(nxgep) != NXGE_OK) 29224977Sraghus return (NXGE_ERROR); 29234977Sraghus 29244977Sraghus if (nxge_setup_xcvr_table(nxgep) != NXGE_OK) 29254977Sraghus return (NXGE_ERROR); 29264977Sraghus 29274977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d", 29284977Sraghus nxgep->statsp->mac_stats.xcvr_inuse)); 29294977Sraghus return (NXGE_OK); 29304977Sraghus } 29313859Sml29623 29323859Sml29623 /* Initialize the TxMAC sub-block */ 29333859Sml29623 29343859Sml29623 nxge_status_t 29353859Sml29623 nxge_tx_mac_init(p_nxge_t nxgep) 29363859Sml29623 { 29373859Sml29623 npi_attr_t ap; 29383859Sml29623 uint8_t portn; 29393859Sml29623 nxge_port_mode_t portmode; 29403859Sml29623 nxge_port_t portt; 29413859Sml29623 npi_handle_t handle; 29423859Sml29623 npi_status_t rs = NPI_SUCCESS; 29433859Sml29623 29443859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 29453859Sml29623 portt = nxgep->mac.porttype; 29463859Sml29623 handle = nxgep->npi_handle; 29473859Sml29623 portmode = nxgep->mac.portmode; 29483859Sml29623 29493859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 29506929Smisaki portn)); 29513859Sml29623 /* Set Max and Min Frame Size */ 29526439Sml29623 /* 29536439Sml29623 * Use maxframesize to configure the hardware maxframe size 29546835Syc148097 * and minframesize to configure the hardware minframe size. 29556439Sml29623 */ 29566439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 29576439Sml29623 "==> nxge_tx_mac_init: port<%d> " 29586439Sml29623 "min framesize %d max framesize %d ", 29596439Sml29623 nxgep->mac.minframesize, 29606439Sml29623 nxgep->mac.maxframesize, 29616439Sml29623 portn)); 29626439Sml29623 29636439Sml29623 SET_MAC_ATTR2(handle, ap, portn, 29646439Sml29623 MAC_PORT_FRAME_SIZE, 29656439Sml29623 nxgep->mac.minframesize, 29666439Sml29623 nxgep->mac.maxframesize, 29676439Sml29623 rs); 29683859Sml29623 if (rs != NPI_SUCCESS) 29693859Sml29623 goto fail; 29703859Sml29623 29713859Sml29623 if (portt == PORT_TYPE_XMAC) { 29723859Sml29623 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 29736929Smisaki 0)) != NPI_SUCCESS) 29743859Sml29623 goto fail; 29753859Sml29623 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 29763859Sml29623 if ((portmode == PORT_10G_FIBER) || 29774977Sraghus (portmode == PORT_10G_COPPER) || 29786835Syc148097 (portmode == PORT_10G_TN1010) || 29794977Sraghus (portmode == PORT_10G_SERDES)) { 29803859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 29816929Smisaki XGMII_IPG_12_15, rs); 29823859Sml29623 if (rs != NPI_SUCCESS) 29833859Sml29623 goto fail; 29843859Sml29623 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 29853859Sml29623 } else { 29863859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 29876929Smisaki MII_GMII_IPG_12, rs); 29883859Sml29623 if (rs != NPI_SUCCESS) 29893859Sml29623 goto fail; 29903859Sml29623 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 29913859Sml29623 } 29923859Sml29623 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 29936929Smisaki CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 29943859Sml29623 goto fail; 29953859Sml29623 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 29963859Sml29623 nxgep->mac.maxburstsize = 0; /* not programmable */ 29973859Sml29623 nxgep->mac.ctrltype = 0; /* not programmable */ 29983859Sml29623 nxgep->mac.pa_size = 0; /* not programmable */ 29993859Sml29623 30003859Sml29623 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 30016929Smisaki != NPI_SUCCESS) 30023859Sml29623 goto fail; 30033859Sml29623 30043859Sml29623 } else { 30053859Sml29623 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 30066929Smisaki 0)) != NPI_SUCCESS) 30073859Sml29623 goto fail; 30083859Sml29623 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 30093859Sml29623 30103859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 30116929Smisaki rs); 30123859Sml29623 if (rs != NPI_SUCCESS) 30133859Sml29623 goto fail; 30143859Sml29623 nxgep->mac.ctrltype = 0x8808; 30153859Sml29623 30163859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 30173859Sml29623 if (rs != NPI_SUCCESS) 30183859Sml29623 goto fail; 30193859Sml29623 nxgep->mac.pa_size = 0x7; 30203859Sml29623 30213859Sml29623 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 30226929Smisaki CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 30233859Sml29623 goto fail; 30243859Sml29623 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 30253859Sml29623 } 30263859Sml29623 30273859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 30286929Smisaki portn)); 30293859Sml29623 30303859Sml29623 return (NXGE_OK); 30313859Sml29623 fail: 30323859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 30336929Smisaki "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn)); 30343859Sml29623 30353859Sml29623 return (NXGE_ERROR | rs); 30363859Sml29623 } 30373859Sml29623 30386495Sspeer 30393859Sml29623 /* Initialize the RxMAC sub-block */ 30403859Sml29623 30413859Sml29623 nxge_status_t 30423859Sml29623 nxge_rx_mac_init(p_nxge_t nxgep) 30433859Sml29623 { 30443859Sml29623 npi_attr_t ap; 30453859Sml29623 uint32_t i; 30463859Sml29623 uint16_t hashtab_e; 30473859Sml29623 p_hash_filter_t hash_filter; 30483859Sml29623 nxge_port_t portt; 30493859Sml29623 uint8_t portn; 30503859Sml29623 npi_handle_t handle; 30513859Sml29623 npi_status_t rs = NPI_SUCCESS; 30523859Sml29623 uint16_t *addr16p; 30533859Sml29623 uint16_t addr0, addr1, addr2; 30543859Sml29623 xmac_rx_config_t xconfig; 30553859Sml29623 bmac_rx_config_t bconfig; 30563859Sml29623 30573859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 30583859Sml29623 30593859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 30606929Smisaki portn)); 30613859Sml29623 handle = nxgep->npi_handle; 30623859Sml29623 portt = nxgep->mac.porttype; 30633859Sml29623 30643859Sml29623 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 30653859Sml29623 addr0 = ntohs(addr16p[2]); 30663859Sml29623 addr1 = ntohs(addr16p[1]); 30673859Sml29623 addr2 = ntohs(addr16p[0]); 30683859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 30696929Smisaki rs); 30703859Sml29623 30713859Sml29623 if (rs != NPI_SUCCESS) 30723859Sml29623 goto fail; 30733859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 30743859Sml29623 if (rs != NPI_SUCCESS) 30753859Sml29623 goto fail; 30763859Sml29623 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 30773859Sml29623 if (rs != NPI_SUCCESS) 30783859Sml29623 goto fail; 30793859Sml29623 30803859Sml29623 /* 30813859Sml29623 * Load the multicast hash filter bits. 30823859Sml29623 */ 30833859Sml29623 hash_filter = nxgep->hash_filter; 30843859Sml29623 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 30853859Sml29623 if (hash_filter != NULL) { 30863859Sml29623 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 30876929Smisaki (NMCFILTER_REGS - 1) - i]; 30883859Sml29623 } else { 30893859Sml29623 hashtab_e = 0; 30903859Sml29623 } 30913859Sml29623 30923859Sml29623 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 30936929Smisaki (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 30943859Sml29623 goto fail; 30953859Sml29623 } 30963859Sml29623 30973859Sml29623 if (portt == PORT_TYPE_XMAC) { 30983859Sml29623 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 30996929Smisaki 0)) != NPI_SUCCESS) 31003859Sml29623 goto fail; 31013859Sml29623 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 31023859Sml29623 31033859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep); 31043859Sml29623 31053859Sml29623 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 31066929Smisaki CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 31076929Smisaki ~CFG_XMAC_RX_STRIP_CRC; 31083859Sml29623 31093859Sml29623 if (nxgep->filter.all_phys_cnt != 0) 31103859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 31113859Sml29623 31123859Sml29623 if (nxgep->filter.all_multicast_cnt != 0) 31133859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 31143859Sml29623 31153859Sml29623 xconfig |= CFG_XMAC_RX_HASH_FILTER; 31163859Sml29623 31173859Sml29623 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 31186929Smisaki xconfig)) != NPI_SUCCESS) 31193859Sml29623 goto fail; 31203859Sml29623 nxgep->mac.rx_config = xconfig; 31213859Sml29623 31223859Sml29623 /* Comparison of mac unique address is always enabled on XMAC */ 31233859Sml29623 31243859Sml29623 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 31256929Smisaki != NPI_SUCCESS) 31263859Sml29623 goto fail; 31273859Sml29623 } else { 31283859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep); 31293859Sml29623 31303859Sml29623 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 31316929Smisaki 0) != NPI_SUCCESS) 31323859Sml29623 goto fail; 31333859Sml29623 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 31343859Sml29623 31353859Sml29623 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 31366929Smisaki ~CFG_BMAC_RX_STRIP_CRC; 31373859Sml29623 31383859Sml29623 if (nxgep->filter.all_phys_cnt != 0) 31393859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 31403859Sml29623 31413859Sml29623 if (nxgep->filter.all_multicast_cnt != 0) 31423859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 31433859Sml29623 31443859Sml29623 bconfig |= CFG_BMAC_RX_HASH_FILTER; 31453859Sml29623 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 31466929Smisaki bconfig)) != NPI_SUCCESS) 31473859Sml29623 goto fail; 31483859Sml29623 nxgep->mac.rx_config = bconfig; 31493859Sml29623 31503859Sml29623 /* Always enable comparison of mac unique address */ 31513859Sml29623 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 31526929Smisaki != NPI_SUCCESS) 31533859Sml29623 goto fail; 31543859Sml29623 } 31553859Sml29623 31563859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 31576929Smisaki portn)); 31583859Sml29623 31593859Sml29623 return (NXGE_OK); 31603859Sml29623 31613859Sml29623 fail: 31623859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 31636929Smisaki "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn)); 31643859Sml29623 31653859Sml29623 return (NXGE_ERROR | rs); 31663859Sml29623 } 31673859Sml29623 31683859Sml29623 /* Enable TXMAC */ 31693859Sml29623 31703859Sml29623 nxge_status_t 31713859Sml29623 nxge_tx_mac_enable(p_nxge_t nxgep) 31723859Sml29623 { 31733859Sml29623 npi_handle_t handle; 31743859Sml29623 npi_status_t rs = NPI_SUCCESS; 31753859Sml29623 nxge_status_t status = NXGE_OK; 31763859Sml29623 31773859Sml29623 handle = nxgep->npi_handle; 31783859Sml29623 31793859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 31806929Smisaki nxgep->mac.portnum)); 31813859Sml29623 31823859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 31833859Sml29623 goto fail; 31843859Sml29623 31853859Sml29623 /* based on speed */ 31863859Sml29623 nxgep->msg_min = ETHERMIN; 31873859Sml29623 31883859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 31893859Sml29623 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 31906929Smisaki CFG_XMAC_TX)) != NPI_SUCCESS) 31913859Sml29623 goto fail; 31923859Sml29623 } else { 31933859Sml29623 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 31946929Smisaki CFG_BMAC_TX)) != NPI_SUCCESS) 31953859Sml29623 goto fail; 31963859Sml29623 } 31973859Sml29623 31983859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 31996929Smisaki nxgep->mac.portnum)); 32003859Sml29623 32013859Sml29623 return (NXGE_OK); 32023859Sml29623 fail: 32033859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 32046929Smisaki "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 32056929Smisaki nxgep->mac.portnum)); 32063859Sml29623 if (rs != NPI_SUCCESS) 32073859Sml29623 return (NXGE_ERROR | rs); 32083859Sml29623 else 32093859Sml29623 return (status); 32103859Sml29623 } 32113859Sml29623 32123859Sml29623 /* Disable TXMAC */ 32133859Sml29623 32143859Sml29623 nxge_status_t 32153859Sml29623 nxge_tx_mac_disable(p_nxge_t nxgep) 32163859Sml29623 { 32173859Sml29623 npi_handle_t handle; 32183859Sml29623 npi_status_t rs = NPI_SUCCESS; 32193859Sml29623 32206495Sspeer if (isLDOMguest(nxgep)) 32216495Sspeer return (NXGE_OK); 32226495Sspeer 32233859Sml29623 handle = nxgep->npi_handle; 32243859Sml29623 32253859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 32266929Smisaki nxgep->mac.portnum)); 32273859Sml29623 32283859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 32293859Sml29623 if ((rs = npi_xmac_tx_config(handle, DISABLE, 32306929Smisaki nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 32313859Sml29623 goto fail; 32323859Sml29623 } else { 32333859Sml29623 if ((rs = npi_bmac_tx_config(handle, DISABLE, 32346929Smisaki nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 32353859Sml29623 goto fail; 32363859Sml29623 } 32373859Sml29623 32383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 32396929Smisaki nxgep->mac.portnum)); 32403859Sml29623 return (NXGE_OK); 32413859Sml29623 fail: 32423859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 32436929Smisaki "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 32446929Smisaki nxgep->mac.portnum)); 32453859Sml29623 return (NXGE_ERROR | rs); 32463859Sml29623 } 32473859Sml29623 32483859Sml29623 /* Enable RXMAC */ 32493859Sml29623 32503859Sml29623 nxge_status_t 32513859Sml29623 nxge_rx_mac_enable(p_nxge_t nxgep) 32523859Sml29623 { 32533859Sml29623 npi_handle_t handle; 32543859Sml29623 uint8_t portn; 32553859Sml29623 npi_status_t rs = NPI_SUCCESS; 32563859Sml29623 nxge_status_t status = NXGE_OK; 32573859Sml29623 32586495Sspeer /* This is a service-domain-only activity. */ 32596495Sspeer if (isLDOMguest(nxgep)) 32606495Sspeer return (status); 32616495Sspeer 32623859Sml29623 handle = nxgep->npi_handle; 32633859Sml29623 portn = nxgep->mac.portnum; 32643859Sml29623 32653859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 32666929Smisaki portn)); 32673859Sml29623 32683859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 32693859Sml29623 goto fail; 32703859Sml29623 32713859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 32723859Sml29623 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 32736495Sspeer CFG_XMAC_RX)) != NPI_SUCCESS) 32743859Sml29623 goto fail; 32753859Sml29623 } else { 32763859Sml29623 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 32776495Sspeer CFG_BMAC_RX)) != NPI_SUCCESS) 32783859Sml29623 goto fail; 32793859Sml29623 } 32803859Sml29623 32816495Sspeer NXGE_DEBUG_MSG((nxgep, MAC_CTL, 32826495Sspeer "<== nxge_rx_mac_enable: port<%d>", portn)); 32833859Sml29623 32843859Sml29623 return (NXGE_OK); 32853859Sml29623 fail: 32863859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 32876495Sspeer "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn)); 32883859Sml29623 32893859Sml29623 if (rs != NPI_SUCCESS) 32903859Sml29623 return (NXGE_ERROR | rs); 32913859Sml29623 else 32923859Sml29623 return (status); 32933859Sml29623 } 32943859Sml29623 32953859Sml29623 /* Disable RXMAC */ 32963859Sml29623 32973859Sml29623 nxge_status_t 32983859Sml29623 nxge_rx_mac_disable(p_nxge_t nxgep) 32993859Sml29623 { 33003859Sml29623 npi_handle_t handle; 33013859Sml29623 uint8_t portn; 33023859Sml29623 npi_status_t rs = NPI_SUCCESS; 33033859Sml29623 33046495Sspeer /* If we are a guest domain driver, don't bother. */ 33056495Sspeer if (isLDOMguest(nxgep)) 33066495Sspeer return (NXGE_OK); 33076495Sspeer 33083859Sml29623 handle = nxgep->npi_handle; 33093859Sml29623 portn = nxgep->mac.portnum; 33103859Sml29623 33113859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 33126929Smisaki portn)); 33133859Sml29623 33143859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 33153859Sml29623 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 33166929Smisaki CFG_XMAC_RX)) != NPI_SUCCESS) 33173859Sml29623 goto fail; 33183859Sml29623 } else { 33193859Sml29623 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 33206929Smisaki CFG_BMAC_RX)) != NPI_SUCCESS) 33213859Sml29623 goto fail; 33223859Sml29623 } 33233859Sml29623 33243859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 33256929Smisaki portn)); 33263859Sml29623 return (NXGE_OK); 33273859Sml29623 fail: 33283859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33296929Smisaki "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn)); 33303859Sml29623 33313859Sml29623 return (NXGE_ERROR | rs); 33323859Sml29623 } 33333859Sml29623 33343859Sml29623 /* Reset TXMAC */ 33353859Sml29623 33363859Sml29623 nxge_status_t 33373859Sml29623 nxge_tx_mac_reset(p_nxge_t nxgep) 33383859Sml29623 { 33393859Sml29623 npi_handle_t handle; 33403859Sml29623 uint8_t portn; 33413859Sml29623 npi_status_t rs = NPI_SUCCESS; 33423859Sml29623 33433859Sml29623 handle = nxgep->npi_handle; 33443859Sml29623 portn = nxgep->mac.portnum; 33453859Sml29623 33463859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 33476929Smisaki portn)); 33483859Sml29623 33493859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 33503859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 33513859Sml29623 != NPI_SUCCESS) 33523859Sml29623 goto fail; 33533859Sml29623 } else { 33543859Sml29623 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 33556929Smisaki != NPI_SUCCESS) 33563859Sml29623 goto fail; 33573859Sml29623 } 33583859Sml29623 33593859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 33606929Smisaki portn)); 33613859Sml29623 33623859Sml29623 return (NXGE_OK); 33633859Sml29623 fail: 33643859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33656929Smisaki "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn)); 33663859Sml29623 33673859Sml29623 return (NXGE_ERROR | rs); 33683859Sml29623 } 33693859Sml29623 33703859Sml29623 /* Reset RXMAC */ 33713859Sml29623 33723859Sml29623 nxge_status_t 33733859Sml29623 nxge_rx_mac_reset(p_nxge_t nxgep) 33743859Sml29623 { 33753859Sml29623 npi_handle_t handle; 33763859Sml29623 uint8_t portn; 33773859Sml29623 npi_status_t rs = NPI_SUCCESS; 33783859Sml29623 33793859Sml29623 handle = nxgep->npi_handle; 33803859Sml29623 portn = nxgep->mac.portnum; 33813859Sml29623 33823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 33836929Smisaki portn)); 33843859Sml29623 33853859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 33863859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 33873859Sml29623 != NPI_SUCCESS) 33883859Sml29623 goto fail; 33893859Sml29623 } else { 33903859Sml29623 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 33916929Smisaki != NPI_SUCCESS) 33923859Sml29623 goto fail; 33933859Sml29623 } 33943859Sml29623 33953859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 33966929Smisaki portn)); 33973859Sml29623 33983859Sml29623 return (NXGE_OK); 33993859Sml29623 fail: 34003859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 34016929Smisaki "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn)); 34023859Sml29623 return (NXGE_ERROR | rs); 34033859Sml29623 } 34043859Sml29623 34054732Sdavemq /* 10G fiber link interrupt start routine */ 34064732Sdavemq 34074732Sdavemq static nxge_status_t 34084732Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep) 34094732Sdavemq { 34104732Sdavemq npi_status_t rs = NPI_SUCCESS; 34114732Sdavemq uint8_t portn = nxgep->mac.portnum; 34124732Sdavemq 34134732Sdavemq rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 34144732Sdavemq 34154732Sdavemq if (rs != NPI_SUCCESS) 34164732Sdavemq return (NXGE_ERROR | rs); 34174732Sdavemq else 34184732Sdavemq return (NXGE_OK); 34194732Sdavemq } 34204732Sdavemq 34214732Sdavemq /* 10G fiber link interrupt stop routine */ 34224732Sdavemq 34234732Sdavemq static nxge_status_t 34244732Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep) 34254732Sdavemq { 34264732Sdavemq npi_status_t rs = NPI_SUCCESS; 34274732Sdavemq uint8_t portn = nxgep->mac.portnum; 34284732Sdavemq 34294732Sdavemq rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 34304732Sdavemq 34314732Sdavemq if (rs != NPI_SUCCESS) 34324732Sdavemq return (NXGE_ERROR | rs); 34334732Sdavemq else 34344732Sdavemq return (NXGE_OK); 34354732Sdavemq } 34364732Sdavemq 34374732Sdavemq /* 1G fiber link interrupt start routine */ 34384732Sdavemq 34394732Sdavemq static nxge_status_t 34404732Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 34414732Sdavemq { 34424732Sdavemq npi_status_t rs = NPI_SUCCESS; 34434732Sdavemq uint8_t portn = nxgep->mac.portnum; 34444732Sdavemq 34454732Sdavemq rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 34464732Sdavemq if (rs != NPI_SUCCESS) 34474732Sdavemq return (NXGE_ERROR | rs); 34484732Sdavemq else 34494732Sdavemq return (NXGE_OK); 34504732Sdavemq } 34514732Sdavemq 34524732Sdavemq /* 1G fiber link interrupt stop routine */ 34534732Sdavemq 34544732Sdavemq static nxge_status_t 34554732Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 34564732Sdavemq { 34574732Sdavemq npi_status_t rs = NPI_SUCCESS; 34584732Sdavemq uint8_t portn = nxgep->mac.portnum; 34594732Sdavemq 34604732Sdavemq rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 34614732Sdavemq 34624732Sdavemq if (rs != NPI_SUCCESS) 34634732Sdavemq return (NXGE_ERROR | rs); 34644732Sdavemq else 34654732Sdavemq return (NXGE_OK); 34664732Sdavemq } 34674732Sdavemq 34684732Sdavemq /* 1G copper link interrupt start routine */ 34694732Sdavemq 34704732Sdavemq static nxge_status_t 34714732Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 34724732Sdavemq { 34734732Sdavemq npi_status_t rs = NPI_SUCCESS; 34744732Sdavemq uint8_t portn = nxgep->mac.portnum; 34754732Sdavemq 34764732Sdavemq rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 34775203Ssbehera MII_STATUS, MII_STATUS_LINKUP); 34784732Sdavemq 34794732Sdavemq if (rs != NPI_SUCCESS) 34804732Sdavemq return (NXGE_ERROR | rs); 34814732Sdavemq else 34824732Sdavemq return (NXGE_OK); 34834732Sdavemq } 34844732Sdavemq 34854732Sdavemq /* 1G copper link interrupt stop routine */ 34864732Sdavemq 34874732Sdavemq static nxge_status_t 34884732Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 34894732Sdavemq { 34904732Sdavemq npi_status_t rs = NPI_SUCCESS; 34914732Sdavemq uint8_t portn = nxgep->mac.portnum; 34924732Sdavemq 34934732Sdavemq rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 34944732Sdavemq 34954732Sdavemq if (rs != NPI_SUCCESS) 34964732Sdavemq return (NXGE_ERROR | rs); 34974732Sdavemq else 34984732Sdavemq return (NXGE_OK); 34994732Sdavemq } 35004732Sdavemq 35014732Sdavemq /* Enable/Disable Link Status change interrupt */ 35023859Sml29623 35033859Sml29623 nxge_status_t 35043859Sml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 35053859Sml29623 { 35064732Sdavemq uint8_t portn; 35074732Sdavemq nxge_status_t status = NXGE_OK; 35083859Sml29623 35093859Sml29623 portn = nxgep->mac.portnum; 35103859Sml29623 35113859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 35124732Sdavemq if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 35134732Sdavemq return (NXGE_OK); 35144732Sdavemq 35154732Sdavemq if (enable == LINK_INTR_START) 35164732Sdavemq status = nxgep->xcvr.link_intr_start(nxgep); 35174732Sdavemq else if (enable == LINK_INTR_STOP) 35184732Sdavemq status = nxgep->xcvr.link_intr_stop(nxgep); 35194732Sdavemq if (status != NXGE_OK) 35204732Sdavemq goto fail; 35213859Sml29623 35223859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 35233859Sml29623 35243859Sml29623 return (NXGE_OK); 35253859Sml29623 fail: 35263859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 35276929Smisaki "nxge_link_intr: Failed to set port<%d> mif intr mode", portn)); 35283859Sml29623 35294732Sdavemq return (status); 35303859Sml29623 } 35313859Sml29623 35323859Sml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 35333859Sml29623 35343859Sml29623 nxge_status_t 35353859Sml29623 nxge_mii_xcvr_init(p_nxge_t nxgep) 35363859Sml29623 { 35373859Sml29623 p_nxge_param_t param_arr; 35383859Sml29623 p_nxge_stats_t statsp; 35393859Sml29623 uint8_t xcvr_portn; 35403859Sml29623 p_mii_regs_t mii_regs; 35413859Sml29623 mii_bmcr_t bmcr; 35423859Sml29623 mii_bmsr_t bmsr; 35433859Sml29623 mii_anar_t anar; 35443859Sml29623 mii_gcr_t gcr; 35453859Sml29623 mii_esr_t esr; 35463859Sml29623 mii_aux_ctl_t bcm5464r_aux; 35473859Sml29623 int status = NXGE_OK; 35483859Sml29623 35493859Sml29623 uint_t delay; 35503859Sml29623 35513859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 35523859Sml29623 35533859Sml29623 param_arr = nxgep->param_arr; 35543859Sml29623 statsp = nxgep->statsp; 35553859Sml29623 xcvr_portn = statsp->mac_stats.xcvr_portn; 35563859Sml29623 35573859Sml29623 mii_regs = NULL; 35583859Sml29623 35593859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 35606929Smisaki "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 35613859Sml29623 35623859Sml29623 /* 35635196Ssbehera * The mif phy mode may be connected to either a copper link 35645196Ssbehera * or fiber link. Read the mode control register to get the fiber 35655196Ssbehera * configuration if it is hard-wired to fiber link. 35665196Ssbehera */ 35675196Ssbehera (void) nxge_mii_get_link_mode(nxgep); 35685196Ssbehera if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 35695196Ssbehera return (nxge_mii_xcvr_fiber_init(nxgep)); 35705196Ssbehera } 35715196Ssbehera 35725196Ssbehera /* 35733859Sml29623 * Reset the transceiver. 35743859Sml29623 */ 35753859Sml29623 delay = 0; 35763859Sml29623 bmcr.value = 0; 35773859Sml29623 bmcr.bits.reset = 1; 35783859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 35795125Sjoycey #if defined(__i386) 35806929Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr, 35815125Sjoycey #else 35826929Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr, 35835125Sjoycey #endif 35846929Smisaki bmcr.value)) != NXGE_OK) 35853859Sml29623 goto fail; 35863859Sml29623 do { 35873859Sml29623 drv_usecwait(500); 35883859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 35895125Sjoycey #if defined(__i386) 35906929Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr, 35915125Sjoycey #else 35926929Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr, 35935125Sjoycey #endif 35946929Smisaki &bmcr.value)) != NXGE_OK) 35953859Sml29623 goto fail; 35963859Sml29623 delay++; 35973859Sml29623 } while ((bmcr.bits.reset) && (delay < 1000)); 35983859Sml29623 if (delay == 1000) { 35993859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 36003859Sml29623 goto fail; 36013859Sml29623 } 36023859Sml29623 36033859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 36045125Sjoycey #if defined(__i386) 36056929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmsr), 36065125Sjoycey #else 36076929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmsr), 36085125Sjoycey #endif 36096929Smisaki &bmsr.value)) != NXGE_OK) 36103859Sml29623 goto fail; 36113859Sml29623 36123859Sml29623 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 36133859Sml29623 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 36143859Sml29623 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 36153859Sml29623 param_arr[param_anar_100hdx].value = 0; 36163859Sml29623 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 36173859Sml29623 param_arr[param_anar_10hdx].value = 0; 36183859Sml29623 36193859Sml29623 /* 36203859Sml29623 * Initialize the xcvr statistics. 36213859Sml29623 */ 36223859Sml29623 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 36233859Sml29623 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 36243859Sml29623 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 36253859Sml29623 statsp->mac_stats.cap_100hdx = 0; 36263859Sml29623 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 36273859Sml29623 statsp->mac_stats.cap_10hdx = 0; 36283859Sml29623 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 36293859Sml29623 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 36303859Sml29623 36313859Sml29623 /* 36326835Syc148097 * Initialize the xcvr advertised capability statistics. 36333859Sml29623 */ 36343859Sml29623 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 36353859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 36363859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 36373859Sml29623 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 36383859Sml29623 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 36393859Sml29623 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 36403859Sml29623 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 36413859Sml29623 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 36423859Sml29623 statsp->mac_stats.adv_cap_asmpause = 36436929Smisaki param_arr[param_anar_asmpause].value; 36443859Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 36453859Sml29623 36463859Sml29623 36473859Sml29623 /* 36483859Sml29623 * Check for extended status just in case we're 36493859Sml29623 * running a Gigibit phy. 36503859Sml29623 */ 36513859Sml29623 if (bmsr.bits.extend_status) { 36523859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 36535125Sjoycey #if defined(__i386) 36546929Smisaki (uint8_t)(uint32_t)(&mii_regs->esr), 36555125Sjoycey #else 36566929Smisaki (uint8_t)(uint64_t)(&mii_regs->esr), 36575125Sjoycey #endif 36586929Smisaki &esr.value)) != NXGE_OK) 36593859Sml29623 goto fail; 36606929Smisaki param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx; 36613859Sml29623 param_arr[param_anar_1000hdx].value = 0; 36623859Sml29623 36633859Sml29623 statsp->mac_stats.cap_1000fdx = 36646929Smisaki (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 36653859Sml29623 statsp->mac_stats.cap_1000hdx = 0; 36663859Sml29623 } else { 36673859Sml29623 param_arr[param_anar_1000fdx].value = 0; 36683859Sml29623 param_arr[param_anar_1000hdx].value = 0; 36693859Sml29623 } 36703859Sml29623 36713859Sml29623 /* 36723859Sml29623 * Initialize 1G Statistics once the capability is established. 36733859Sml29623 */ 36743859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 36753859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 36763859Sml29623 36773859Sml29623 /* 36786835Syc148097 * Initialize the link statistics. 36793859Sml29623 */ 36803859Sml29623 statsp->mac_stats.link_T4 = 0; 36813859Sml29623 statsp->mac_stats.link_asmpause = 0; 36823859Sml29623 statsp->mac_stats.link_pause = 0; 36833859Sml29623 statsp->mac_stats.link_speed = 0; 36843859Sml29623 statsp->mac_stats.link_duplex = 0; 36853859Sml29623 statsp->mac_stats.link_up = 0; 36863859Sml29623 36873859Sml29623 /* 36883859Sml29623 * Switch off Auto-negotiation, 100M and full duplex. 36893859Sml29623 */ 36903859Sml29623 bmcr.value = 0; 36913859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 36925125Sjoycey #if defined(__i386) 36936929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 36945125Sjoycey #else 36956929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 36965125Sjoycey #endif 36976929Smisaki bmcr.value)) != NXGE_OK) 36983859Sml29623 goto fail; 36993859Sml29623 37003859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 37016929Smisaki (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 37023859Sml29623 bmcr.bits.loopback = 1; 37033859Sml29623 bmcr.bits.enable_autoneg = 0; 37043859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 37053859Sml29623 bmcr.bits.speed_1000_sel = 1; 37063859Sml29623 bmcr.bits.duplex_mode = 1; 37073859Sml29623 param_arr[param_autoneg].value = 0; 37083859Sml29623 } else { 37093859Sml29623 bmcr.bits.loopback = 0; 37103859Sml29623 } 37113859Sml29623 37123859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 37136929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext100) || 37146929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 37153859Sml29623 param_arr[param_autoneg].value = 0; 37163859Sml29623 bcm5464r_aux.value = 0; 37173859Sml29623 bcm5464r_aux.bits.ext_lb = 1; 37183859Sml29623 bcm5464r_aux.bits.write_1 = 1; 37193859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37206929Smisaki BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 37213859Sml29623 goto fail; 37223859Sml29623 } 37233859Sml29623 37246835Syc148097 /* If auto-negotiation is desired */ 37253859Sml29623 if (param_arr[param_autoneg].value) { 37263859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 37276929Smisaki "Restarting Auto-negotiation.")); 37283859Sml29623 /* 37293859Sml29623 * Setup our Auto-negotiation advertisement register. 37303859Sml29623 */ 37313859Sml29623 anar.value = 0; 37323859Sml29623 anar.bits.selector = 1; 37333859Sml29623 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 37343859Sml29623 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 37353859Sml29623 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 37363859Sml29623 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 37373859Sml29623 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 37383859Sml29623 anar.bits.cap_asmpause = 0; 37393859Sml29623 anar.bits.cap_pause = 0; 37403859Sml29623 if (param_arr[param_anar_1000fdx].value || 37416929Smisaki param_arr[param_anar_100fdx].value || 37426929Smisaki param_arr[param_anar_10fdx].value) { 37433859Sml29623 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 37443859Sml29623 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 37453859Sml29623 } 37463859Sml29623 37476835Syc148097 /* Write to the auto-negotiation advertisement register */ 37483859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37495125Sjoycey #if defined(__i386) 37506929Smisaki (uint8_t)(uint32_t)(&mii_regs->anar), 37515125Sjoycey #else 37526929Smisaki (uint8_t)(uint64_t)(&mii_regs->anar), 37535125Sjoycey #endif 37546929Smisaki anar.value)) != NXGE_OK) 37553859Sml29623 goto fail; 37563859Sml29623 if (bmsr.bits.extend_status) { 37573859Sml29623 gcr.value = 0; 37583859Sml29623 gcr.bits.ms_mode_en = 37596929Smisaki param_arr[param_master_cfg_enable].value; 37603859Sml29623 gcr.bits.master = 37616929Smisaki param_arr[param_master_cfg_value].value; 37623859Sml29623 gcr.bits.link_1000fdx = 37636929Smisaki param_arr[param_anar_1000fdx].value; 37643859Sml29623 gcr.bits.link_1000hdx = 37656929Smisaki param_arr[param_anar_1000hdx].value; 37663859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37675125Sjoycey #if defined(__i386) 37686929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 37695125Sjoycey #else 37706929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 37715125Sjoycey #endif 37726929Smisaki gcr.value)) != NXGE_OK) 37733859Sml29623 goto fail; 37743859Sml29623 } 37753859Sml29623 37763859Sml29623 bmcr.bits.enable_autoneg = 1; 37773859Sml29623 bmcr.bits.restart_autoneg = 1; 37783859Sml29623 37793859Sml29623 } else { 37803859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 37813859Sml29623 bmcr.bits.speed_1000_sel = 37826929Smisaki param_arr[param_anar_1000fdx].value | 37836929Smisaki param_arr[param_anar_1000hdx].value; 37843859Sml29623 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 37856929Smisaki (param_arr[param_anar_100fdx].value | 37866929Smisaki param_arr[param_anar_100hdx].value); 37876835Syc148097 37886835Syc148097 /* Force to 1G */ 37893859Sml29623 if (bmcr.bits.speed_1000_sel) { 37903859Sml29623 statsp->mac_stats.link_speed = 1000; 37913859Sml29623 gcr.value = 0; 37923859Sml29623 gcr.bits.ms_mode_en = 37936929Smisaki param_arr[param_master_cfg_enable].value; 37943859Sml29623 gcr.bits.master = 37956929Smisaki param_arr[param_master_cfg_value].value; 37963859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37975125Sjoycey #if defined(__i386) 37986929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 37995125Sjoycey #else 38006929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 38015125Sjoycey #endif 38026929Smisaki gcr.value)) != NXGE_OK) 38033859Sml29623 goto fail; 38043859Sml29623 if (param_arr[param_anar_1000fdx].value) { 38053859Sml29623 bmcr.bits.duplex_mode = 1; 38063859Sml29623 statsp->mac_stats.link_duplex = 2; 38073859Sml29623 } else 38083859Sml29623 statsp->mac_stats.link_duplex = 1; 38096835Syc148097 38106835Syc148097 /* Force to 100M */ 38113859Sml29623 } else if (bmcr.bits.speed_sel) { 38123859Sml29623 statsp->mac_stats.link_speed = 100; 38133859Sml29623 if (param_arr[param_anar_100fdx].value) { 38143859Sml29623 bmcr.bits.duplex_mode = 1; 38153859Sml29623 statsp->mac_stats.link_duplex = 2; 38163859Sml29623 } else 38173859Sml29623 statsp->mac_stats.link_duplex = 1; 38186835Syc148097 38196835Syc148097 /* Force to 10M */ 38203859Sml29623 } else { 38213859Sml29623 statsp->mac_stats.link_speed = 10; 38223859Sml29623 if (param_arr[param_anar_10fdx].value) { 38233859Sml29623 bmcr.bits.duplex_mode = 1; 38243859Sml29623 statsp->mac_stats.link_duplex = 2; 38253859Sml29623 } else 38263859Sml29623 statsp->mac_stats.link_duplex = 1; 38273859Sml29623 } 38283859Sml29623 if (statsp->mac_stats.link_duplex != 1) { 38293859Sml29623 statsp->mac_stats.link_asmpause = 38306929Smisaki statsp->mac_stats.cap_asmpause; 38313859Sml29623 statsp->mac_stats.link_pause = 38326929Smisaki statsp->mac_stats.cap_pause; 38333859Sml29623 } 38343859Sml29623 38353859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 38366929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext100) || 38376929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 38383859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 38393859Sml29623 /* BCM5464R 1000mbps external loopback mode */ 38403859Sml29623 gcr.value = 0; 38413859Sml29623 gcr.bits.ms_mode_en = 1; 38423859Sml29623 gcr.bits.master = 1; 38433859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 38445125Sjoycey #if defined(__i386) 38456929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 38465125Sjoycey #else 38476929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 38485125Sjoycey #endif 38496929Smisaki gcr.value)) != NXGE_OK) 38503859Sml29623 goto fail; 38513859Sml29623 bmcr.value = 0; 38523859Sml29623 bmcr.bits.speed_1000_sel = 1; 38533859Sml29623 statsp->mac_stats.link_speed = 1000; 38543859Sml29623 } else if (statsp->port_stats.lb_mode 38553859Sml29623 == nxge_lb_ext100) { 38563859Sml29623 /* BCM5464R 100mbps external loopback mode */ 38573859Sml29623 bmcr.value = 0; 38583859Sml29623 bmcr.bits.speed_sel = 1; 38593859Sml29623 bmcr.bits.duplex_mode = 1; 38603859Sml29623 statsp->mac_stats.link_speed = 100; 38613859Sml29623 } else if (statsp->port_stats.lb_mode 38623859Sml29623 == nxge_lb_ext10) { 38633859Sml29623 /* BCM5464R 10mbps external loopback mode */ 38643859Sml29623 bmcr.value = 0; 38653859Sml29623 bmcr.bits.duplex_mode = 1; 38663859Sml29623 statsp->mac_stats.link_speed = 10; 38673859Sml29623 } 38683859Sml29623 } 38693859Sml29623 } 38703859Sml29623 38713859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 38725125Sjoycey #if defined(__i386) 38736929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 38745125Sjoycey #else 38756929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 38765125Sjoycey #endif 38776929Smisaki bmcr.value)) != NXGE_OK) 38783859Sml29623 goto fail; 38793859Sml29623 38803859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 38815125Sjoycey #if defined(__i386) 38826929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 38835125Sjoycey #else 38846929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 38855125Sjoycey #endif 38866929Smisaki &bmcr.value)) != NXGE_OK) 38873859Sml29623 goto fail; 38883859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 38893859Sml29623 38903859Sml29623 /* 38913859Sml29623 * Initialize the xcvr status kept in the context structure. 38923859Sml29623 */ 38933859Sml29623 nxgep->soft_bmsr.value = 0; 38943859Sml29623 38953859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 38965125Sjoycey #if defined(__i386) 38976929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmsr), 38985125Sjoycey #else 38996929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmsr), 39005125Sjoycey #endif 39016929Smisaki &nxgep->bmsr.value)) != NXGE_OK) 39023859Sml29623 goto fail; 39033859Sml29623 39043859Sml29623 statsp->mac_stats.xcvr_inits++; 39053859Sml29623 nxgep->bmsr.value = 0; 39063859Sml29623 39073859Sml29623 fail: 39083859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39096929Smisaki "<== nxge_mii_xcvr_init status 0x%x", status)); 39103859Sml29623 return (status); 39113859Sml29623 } 39123859Sml29623 39135196Ssbehera nxge_status_t 39145196Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep) 39155196Ssbehera { 39165196Ssbehera p_nxge_param_t param_arr; 39175196Ssbehera p_nxge_stats_t statsp; 39185196Ssbehera uint8_t xcvr_portn; 39195196Ssbehera p_mii_regs_t mii_regs; 39205196Ssbehera mii_bmcr_t bmcr; 39215196Ssbehera mii_bmsr_t bmsr; 39225196Ssbehera mii_gcr_t gcr; 39235196Ssbehera mii_esr_t esr; 39245196Ssbehera mii_aux_ctl_t bcm5464r_aux; 39255196Ssbehera int status = NXGE_OK; 39265196Ssbehera 39275196Ssbehera uint_t delay; 39285196Ssbehera 39295196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init")); 39305196Ssbehera 39315196Ssbehera param_arr = nxgep->param_arr; 39325196Ssbehera statsp = nxgep->statsp; 39335196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 39345196Ssbehera 39355196Ssbehera mii_regs = NULL; 39365196Ssbehera 39375196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39385196Ssbehera "nxge_mii_xcvr_fiber_init: " 39395196Ssbehera "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 39405196Ssbehera 39415196Ssbehera /* 39425196Ssbehera * Reset the transceiver. 39435196Ssbehera */ 39445196Ssbehera delay = 0; 39455196Ssbehera bmcr.value = 0; 39465196Ssbehera bmcr.bits.reset = 1; 39475196Ssbehera 39485196Ssbehera #if defined(__i386) 39495196Ssbehera 39505196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 39515196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 39525196Ssbehera goto fail; 39535196Ssbehera #else 39545196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 39555196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 39565196Ssbehera goto fail; 39575196Ssbehera #endif 39585196Ssbehera do { 39595196Ssbehera drv_usecwait(500); 39605196Ssbehera #if defined(__i386) 39615196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 39625196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) 39635196Ssbehera != NXGE_OK) 39645196Ssbehera goto fail; 39655196Ssbehera #else 39665196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 39675196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) 39685196Ssbehera != NXGE_OK) 39695196Ssbehera goto fail; 39705196Ssbehera #endif 39715196Ssbehera delay++; 39725196Ssbehera } while ((bmcr.bits.reset) && (delay < 1000)); 39735196Ssbehera if (delay == 1000) { 39745196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 39755196Ssbehera goto fail; 39765196Ssbehera } 39775196Ssbehera 39785196Ssbehera #if defined(__i386) 39795196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 39805196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 39815196Ssbehera goto fail; 39825196Ssbehera #else 39835196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 39845196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 39855196Ssbehera goto fail; 39865196Ssbehera #endif 39875196Ssbehera 39885196Ssbehera param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 39895196Ssbehera param_arr[param_anar_100T4].value = 0; 39905196Ssbehera param_arr[param_anar_100fdx].value = 0; 39915196Ssbehera param_arr[param_anar_100hdx].value = 0; 39925196Ssbehera param_arr[param_anar_10fdx].value = 0; 39935196Ssbehera param_arr[param_anar_10hdx].value = 0; 39945196Ssbehera 39955196Ssbehera /* 39965196Ssbehera * Initialize the xcvr statistics. 39975196Ssbehera */ 39985196Ssbehera statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 39995196Ssbehera statsp->mac_stats.cap_100T4 = 0; 40005196Ssbehera statsp->mac_stats.cap_100fdx = 0; 40015196Ssbehera statsp->mac_stats.cap_100hdx = 0; 40025196Ssbehera statsp->mac_stats.cap_10fdx = 0; 40035196Ssbehera statsp->mac_stats.cap_10hdx = 0; 40045196Ssbehera statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 40055196Ssbehera statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 40065196Ssbehera 40075196Ssbehera /* 40085196Ssbehera * Initialize the xcvr advertised capability statistics. 40095196Ssbehera */ 40105196Ssbehera statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 40115196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 40125196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 40135196Ssbehera statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 40145196Ssbehera statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 40155196Ssbehera statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 40165196Ssbehera statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 40175196Ssbehera statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 40185196Ssbehera statsp->mac_stats.adv_cap_asmpause = 40195196Ssbehera param_arr[param_anar_asmpause].value; 40205196Ssbehera statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 40215196Ssbehera 40225196Ssbehera /* 40235196Ssbehera * Check for extended status just in case we're 40245196Ssbehera * running a Gigibit phy. 40255196Ssbehera */ 40265196Ssbehera if (bmsr.bits.extend_status) { 40275196Ssbehera #if defined(__i386) 40285196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 40295196Ssbehera (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) != 40305196Ssbehera NXGE_OK) 40315196Ssbehera goto fail; 40325196Ssbehera #else 40335196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 40345196Ssbehera (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) != 40355196Ssbehera NXGE_OK) 40365196Ssbehera goto fail; 40375196Ssbehera #endif 40385196Ssbehera param_arr[param_anar_1000fdx].value &= 40395196Ssbehera esr.bits.link_1000fdx; 40405196Ssbehera param_arr[param_anar_1000hdx].value = 0; 40415196Ssbehera 40425196Ssbehera statsp->mac_stats.cap_1000fdx = 40435196Ssbehera (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 40445196Ssbehera statsp->mac_stats.cap_1000hdx = 0; 40455196Ssbehera } else { 40465196Ssbehera param_arr[param_anar_1000fdx].value = 0; 40475196Ssbehera param_arr[param_anar_1000hdx].value = 0; 40485196Ssbehera } 40495196Ssbehera 40505196Ssbehera /* 40515196Ssbehera * Initialize 1G Statistics once the capability is established. 40525196Ssbehera */ 40535196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 40545196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 40555196Ssbehera 40565196Ssbehera /* 40575196Ssbehera * Initialize the link statistics. 40585196Ssbehera */ 40595196Ssbehera statsp->mac_stats.link_T4 = 0; 40605196Ssbehera statsp->mac_stats.link_asmpause = 0; 40615196Ssbehera statsp->mac_stats.link_pause = 0; 40625196Ssbehera statsp->mac_stats.link_speed = 0; 40635196Ssbehera statsp->mac_stats.link_duplex = 0; 40645196Ssbehera statsp->mac_stats.link_up = 0; 40655196Ssbehera 40665196Ssbehera /* 40675196Ssbehera * Switch off Auto-negotiation, 100M and full duplex. 40685196Ssbehera */ 40695196Ssbehera bmcr.value = 0; 40705196Ssbehera #if defined(__i386) 40715196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 40725196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 40735196Ssbehera goto fail; 40745196Ssbehera #else 40755196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 40765196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 40775196Ssbehera goto fail; 40785196Ssbehera #endif 40795196Ssbehera 40805196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 40815196Ssbehera (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 40825196Ssbehera bmcr.bits.loopback = 1; 40835196Ssbehera bmcr.bits.enable_autoneg = 0; 40845196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 40855196Ssbehera bmcr.bits.speed_1000_sel = 1; 40865196Ssbehera bmcr.bits.duplex_mode = 1; 40875196Ssbehera param_arr[param_autoneg].value = 0; 40885196Ssbehera } else { 40895196Ssbehera bmcr.bits.loopback = 0; 40905196Ssbehera } 40915196Ssbehera 40925196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 40935196Ssbehera param_arr[param_autoneg].value = 0; 40945196Ssbehera bcm5464r_aux.value = 0; 40955196Ssbehera bcm5464r_aux.bits.ext_lb = 1; 40965196Ssbehera bcm5464r_aux.bits.write_1 = 1; 40975196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 40985196Ssbehera BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 40995196Ssbehera goto fail; 41005196Ssbehera } 41015196Ssbehera 41025196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 41035196Ssbehera bmcr.bits.speed_1000_sel = 1; 41045196Ssbehera bmcr.bits.speed_sel = 0; 41055196Ssbehera bmcr.bits.duplex_mode = 1; 41065196Ssbehera statsp->mac_stats.link_speed = 1000; 41075196Ssbehera statsp->mac_stats.link_duplex = 2; 41085196Ssbehera 41095196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) { 41105196Ssbehera /* BCM5464R 1000mbps external loopback mode */ 41115196Ssbehera gcr.value = 0; 41125196Ssbehera gcr.bits.ms_mode_en = 1; 41135196Ssbehera gcr.bits.master = 1; 41145196Ssbehera #if defined(__i386) 41155196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41165196Ssbehera (uint8_t)(uint32_t)(&mii_regs->gcr), 41175196Ssbehera gcr.value)) != NXGE_OK) 41185196Ssbehera goto fail; 41195196Ssbehera #else 41205196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41215196Ssbehera (uint8_t)(uint64_t)(&mii_regs->gcr), 41225196Ssbehera gcr.value)) != NXGE_OK) 41235196Ssbehera goto fail; 41245196Ssbehera #endif 41255196Ssbehera bmcr.value = 0; 41265196Ssbehera bmcr.bits.speed_1000_sel = 1; 41275196Ssbehera statsp->mac_stats.link_speed = 1000; 41285196Ssbehera } 41295196Ssbehera 41305196Ssbehera #if defined(__i386) 41315196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41325196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), 41335196Ssbehera bmcr.value)) != NXGE_OK) 41345196Ssbehera goto fail; 41355196Ssbehera #else 41365196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41375196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), 41385196Ssbehera bmcr.value)) != NXGE_OK) 41395196Ssbehera goto fail; 41405196Ssbehera #endif 41415196Ssbehera 41425196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41435196Ssbehera "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x", 41445196Ssbehera bmcr.value)); 41455196Ssbehera 41465196Ssbehera #if defined(__i386) 41475196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41485196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 41495196Ssbehera goto fail; 41505196Ssbehera #else 41515196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41525196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 41535196Ssbehera goto fail; 41545196Ssbehera #endif 41555196Ssbehera 41565196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41575196Ssbehera "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value)); 41585196Ssbehera 41595196Ssbehera /* 41605196Ssbehera * Initialize the xcvr status kept in the context structure. 41615196Ssbehera */ 41625196Ssbehera nxgep->soft_bmsr.value = 0; 41635196Ssbehera #if defined(__i386) 41645196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41655196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), 41665196Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 41675196Ssbehera goto fail; 41685196Ssbehera #else 41695196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41705196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), 41715196Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 41725196Ssbehera goto fail; 41735196Ssbehera #endif 41745196Ssbehera 41755196Ssbehera statsp->mac_stats.xcvr_inits++; 41765196Ssbehera nxgep->bmsr.value = 0; 41775196Ssbehera 41785196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41795196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 41805196Ssbehera return (status); 41815196Ssbehera 41825196Ssbehera fail: 41835196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 41845196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 41855196Ssbehera return (status); 41865196Ssbehera } 41875196Ssbehera 41883859Sml29623 /* Read from a MII compliant register */ 41893859Sml29623 41903859Sml29623 nxge_status_t 41913859Sml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 41923859Sml29623 uint16_t *value) 41933859Sml29623 { 41943859Sml29623 npi_status_t rs = NPI_SUCCESS; 41953859Sml29623 41963859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 41976929Smisaki "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 41983859Sml29623 41996075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 42003859Sml29623 42015196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 42025196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 42033859Sml29623 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 42046929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42053859Sml29623 goto fail; 42064977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 42074977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 42083859Sml29623 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 42096929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42103859Sml29623 goto fail; 42113859Sml29623 } else 42123859Sml29623 goto fail; 42133859Sml29623 42146075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42153859Sml29623 42163859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 42176929Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value)); 42183859Sml29623 return (NXGE_OK); 42193859Sml29623 fail: 42206075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42213859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 42226929Smisaki "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn)); 42233859Sml29623 42243859Sml29623 return (NXGE_ERROR | rs); 42253859Sml29623 } 42263859Sml29623 42273859Sml29623 /* Write to a MII compliant Register */ 42283859Sml29623 42293859Sml29623 nxge_status_t 42303859Sml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 42313859Sml29623 uint16_t value) 42323859Sml29623 { 42333859Sml29623 npi_status_t rs = NPI_SUCCESS; 42343859Sml29623 42353859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 42366929Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value)); 42373859Sml29623 42386075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 42393859Sml29623 42405196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 42415196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 42423859Sml29623 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 42436929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42443859Sml29623 goto fail; 42454977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 42464977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 42473859Sml29623 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 42486929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42493859Sml29623 goto fail; 42503859Sml29623 } else 42513859Sml29623 goto fail; 42523859Sml29623 42536075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42543859Sml29623 42553859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 42566929Smisaki "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 42573859Sml29623 return (NXGE_OK); 42583859Sml29623 fail: 42596075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42603859Sml29623 42613859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 42626929Smisaki "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn)); 42633859Sml29623 42643859Sml29623 return (NXGE_ERROR | rs); 42653859Sml29623 } 42663859Sml29623 42676835Syc148097 /* 42686835Syc148097 * Perform write to Clause45 serdes / transceiver device 42696835Syc148097 * Arguments: 42706835Syc148097 * xcvr_portn: The IEEE 802.3 Clause45 PHYAD, it is the same as port 42716835Syc148097 * number if nxge_mdio_write is used for accessing the 42726835Syc148097 * internal LSIL serdes. Otherwise PHYAD is different 42736835Syc148097 * for different platforms. 42746835Syc148097 * device: With each PHYAD, the driver can use MDIO to control 42756835Syc148097 * multiple devices inside the PHY, here "device" is an 42766835Syc148097 * MMD (MDIO managable device). 42776835Syc148097 * xcvr_reg: Each device has multiple registers. xcvr_reg specifies 42786835Syc148097 * the register which the driver will write value to. 42796835Syc148097 * value: The register value will be filled in. 42806835Syc148097 */ 42813859Sml29623 nxge_status_t 42823859Sml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 42833859Sml29623 uint16_t xcvr_reg, uint16_t *value) 42843859Sml29623 { 42853859Sml29623 npi_status_t rs = NPI_SUCCESS; 42863859Sml29623 42873859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 42886929Smisaki xcvr_portn)); 42893859Sml29623 42905780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 42913859Sml29623 42923859Sml29623 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 42936929Smisaki xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 42943859Sml29623 goto fail; 42953859Sml29623 42965780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42973859Sml29623 42983859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 42996929Smisaki xcvr_portn)); 43003859Sml29623 return (NXGE_OK); 43013859Sml29623 fail: 43025780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43033859Sml29623 43043859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 43056929Smisaki "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn)); 43063859Sml29623 43073859Sml29623 return (NXGE_ERROR | rs); 43083859Sml29623 } 43093859Sml29623 43103859Sml29623 /* Perform write to Clause45 serdes / transceiver device */ 43113859Sml29623 43123859Sml29623 nxge_status_t 43133859Sml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 43143859Sml29623 uint16_t xcvr_reg, uint16_t value) 43153859Sml29623 { 43163859Sml29623 npi_status_t rs = NPI_SUCCESS; 43173859Sml29623 43183859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 43196929Smisaki xcvr_portn)); 43203859Sml29623 43215780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 43223859Sml29623 43233859Sml29623 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 43246929Smisaki xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 43253859Sml29623 goto fail; 43263859Sml29623 43275780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43283859Sml29623 43293859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 43306929Smisaki xcvr_portn)); 43313859Sml29623 return (NXGE_OK); 43323859Sml29623 fail: 43335780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43343859Sml29623 43353859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 43366929Smisaki "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn)); 43373859Sml29623 43383859Sml29623 return (NXGE_ERROR | rs); 43393859Sml29623 } 43403859Sml29623 43413859Sml29623 43423859Sml29623 /* Check MII to see if there is any link status change */ 43433859Sml29623 43443859Sml29623 nxge_status_t 43453859Sml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 43463859Sml29623 nxge_link_state_t *link_up) 43473859Sml29623 { 43483859Sml29623 p_nxge_param_t param_arr; 43493859Sml29623 p_nxge_stats_t statsp; 43503859Sml29623 p_mii_regs_t mii_regs; 43513859Sml29623 p_mii_bmsr_t soft_bmsr; 43523859Sml29623 mii_anar_t anar; 43533859Sml29623 mii_anlpar_t anlpar; 43543859Sml29623 mii_anar_t an_common; 43553859Sml29623 mii_aner_t aner; 43563859Sml29623 mii_gsr_t gsr; 43573859Sml29623 nxge_status_t status = NXGE_OK; 43583859Sml29623 43593859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 43603859Sml29623 43613859Sml29623 mii_regs = NULL; 43623859Sml29623 param_arr = nxgep->param_arr; 43633859Sml29623 statsp = nxgep->statsp; 43643859Sml29623 soft_bmsr = &nxgep->soft_bmsr; 43653859Sml29623 *link_up = LINK_NO_CHANGE; 43663859Sml29623 43675196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43685196Ssbehera "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x", 43695196Ssbehera bmsr.value, bmsr_ints.value)); 43705196Ssbehera 43713859Sml29623 if (bmsr_ints.bits.link_status) { 43725196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43735196Ssbehera "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x", 43745196Ssbehera bmsr.value, bmsr_ints.value)); 43753859Sml29623 if (bmsr.bits.link_status) { 43763859Sml29623 soft_bmsr->bits.link_status = 1; 43775196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43785196Ssbehera "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int " 43795196Ssbehera "0x%x", bmsr.value, bmsr_ints.value)); 43803859Sml29623 } else { 43813859Sml29623 statsp->mac_stats.link_up = 0; 43823859Sml29623 soft_bmsr->bits.link_status = 0; 43833859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43846929Smisaki "Link down cable problem")); 43853859Sml29623 *link_up = LINK_IS_DOWN; 43863859Sml29623 } 43873859Sml29623 } 43883859Sml29623 43895196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 43905196Ssbehera param_arr[param_autoneg].value) { 43913859Sml29623 if (bmsr_ints.bits.auto_neg_complete) { 43923859Sml29623 if (bmsr.bits.auto_neg_complete) 43933859Sml29623 soft_bmsr->bits.auto_neg_complete = 1; 43943859Sml29623 else 43953859Sml29623 soft_bmsr->bits.auto_neg_complete = 0; 43963859Sml29623 } 43973859Sml29623 if (soft_bmsr->bits.link_status == 0) { 43983859Sml29623 statsp->mac_stats.link_T4 = 0; 43993859Sml29623 statsp->mac_stats.link_speed = 0; 44003859Sml29623 statsp->mac_stats.link_duplex = 0; 44013859Sml29623 statsp->mac_stats.link_asmpause = 0; 44023859Sml29623 statsp->mac_stats.link_pause = 0; 44033859Sml29623 statsp->mac_stats.lp_cap_autoneg = 0; 44043859Sml29623 statsp->mac_stats.lp_cap_100T4 = 0; 44053859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 0; 44063859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 0; 44073859Sml29623 statsp->mac_stats.lp_cap_100fdx = 0; 44083859Sml29623 statsp->mac_stats.lp_cap_100hdx = 0; 44093859Sml29623 statsp->mac_stats.lp_cap_10fdx = 0; 44103859Sml29623 statsp->mac_stats.lp_cap_10hdx = 0; 44113859Sml29623 statsp->mac_stats.lp_cap_10gfdx = 0; 44123859Sml29623 statsp->mac_stats.lp_cap_10ghdx = 0; 44133859Sml29623 statsp->mac_stats.lp_cap_asmpause = 0; 44143859Sml29623 statsp->mac_stats.lp_cap_pause = 0; 44153859Sml29623 } 44163859Sml29623 } else 44173859Sml29623 soft_bmsr->bits.auto_neg_complete = 1; 44183859Sml29623 44193859Sml29623 if ((bmsr_ints.bits.link_status || 44206929Smisaki bmsr_ints.bits.auto_neg_complete) && 44216929Smisaki soft_bmsr->bits.link_status && 44226929Smisaki soft_bmsr->bits.auto_neg_complete) { 44233859Sml29623 statsp->mac_stats.link_up = 1; 44245196Ssbehera 44255196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 44265196Ssbehera "==> nxge_mii_check " 44275196Ssbehera "(auto negotiation complete or link up) " 44285196Ssbehera "soft bmsr 0x%x bmsr_int 0x%x", 44295196Ssbehera bmsr.value, bmsr_ints.value)); 44305196Ssbehera 44315196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 44325196Ssbehera param_arr[param_autoneg].value) { 44333859Sml29623 if ((status = nxge_mii_read(nxgep, 44346929Smisaki statsp->mac_stats.xcvr_portn, 44355125Sjoycey #if defined(__i386) 44366929Smisaki (uint8_t)(uint32_t)(&mii_regs->anar), 44375125Sjoycey #else 44386929Smisaki (uint8_t)(uint64_t)(&mii_regs->anar), 44395125Sjoycey #endif 44406929Smisaki &anar.value)) != NXGE_OK) 44413859Sml29623 goto fail; 44423859Sml29623 if ((status = nxge_mii_read(nxgep, 44436929Smisaki statsp->mac_stats.xcvr_portn, 44445125Sjoycey #if defined(__i386) 44456929Smisaki (uint8_t)(uint32_t)(&mii_regs->anlpar), 44465125Sjoycey #else 44476929Smisaki (uint8_t)(uint64_t)(&mii_regs->anlpar), 44485125Sjoycey #endif 44496929Smisaki &anlpar.value)) != NXGE_OK) 44503859Sml29623 goto fail; 44513859Sml29623 if ((status = nxge_mii_read(nxgep, 44526929Smisaki statsp->mac_stats.xcvr_portn, 44535125Sjoycey #if defined(__i386) 44546929Smisaki (uint8_t)(uint32_t)(&mii_regs->aner), 44555125Sjoycey #else 44566929Smisaki (uint8_t)(uint64_t)(&mii_regs->aner), 44575125Sjoycey #endif 44586929Smisaki &aner.value)) != NXGE_OK) 44593859Sml29623 goto fail; 44603859Sml29623 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 44613859Sml29623 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 44623859Sml29623 statsp->mac_stats.lp_cap_100fdx = 44636929Smisaki anlpar.bits.cap_100fdx; 44643859Sml29623 statsp->mac_stats.lp_cap_100hdx = 44656929Smisaki anlpar.bits.cap_100hdx; 44663859Sml29623 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 44673859Sml29623 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 44683859Sml29623 statsp->mac_stats.lp_cap_asmpause = 44696929Smisaki anlpar.bits.cap_asmpause; 44703859Sml29623 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 44713859Sml29623 an_common.value = anar.value & anlpar.value; 44723859Sml29623 if (param_arr[param_anar_1000fdx].value || 44736929Smisaki param_arr[param_anar_1000hdx].value) { 44743859Sml29623 if ((status = nxge_mii_read(nxgep, 44756929Smisaki statsp->mac_stats.xcvr_portn, 44765125Sjoycey #if defined(__i386) 44776929Smisaki (uint8_t)(uint32_t)(&mii_regs->gsr), 44785125Sjoycey #else 44796929Smisaki (uint8_t)(uint64_t)(&mii_regs->gsr), 44805125Sjoycey #endif 44816929Smisaki &gsr.value)) != NXGE_OK) 44823859Sml29623 goto fail; 44833859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 44846929Smisaki gsr.bits.link_1000fdx; 44853859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 44866929Smisaki gsr.bits.link_1000hdx; 44873859Sml29623 if (param_arr[param_anar_1000fdx].value && 44886929Smisaki gsr.bits.link_1000fdx) { 44893859Sml29623 statsp->mac_stats.link_speed = 1000; 44903859Sml29623 statsp->mac_stats.link_duplex = 2; 44913859Sml29623 } else if ( 44926929Smisaki param_arr[param_anar_1000hdx].value && 44936929Smisaki gsr.bits.link_1000hdx) { 44943859Sml29623 statsp->mac_stats.link_speed = 1000; 44953859Sml29623 statsp->mac_stats.link_duplex = 1; 44963859Sml29623 } 44973859Sml29623 } 44983859Sml29623 if ((an_common.value != 0) && 44996929Smisaki !(statsp->mac_stats.link_speed)) { 45003859Sml29623 if (an_common.bits.cap_100T4) { 45013859Sml29623 statsp->mac_stats.link_T4 = 1; 45023859Sml29623 statsp->mac_stats.link_speed = 100; 45033859Sml29623 statsp->mac_stats.link_duplex = 1; 45043859Sml29623 } else if (an_common.bits.cap_100fdx) { 45053859Sml29623 statsp->mac_stats.link_speed = 100; 45063859Sml29623 statsp->mac_stats.link_duplex = 2; 45073859Sml29623 } else if (an_common.bits.cap_100hdx) { 45083859Sml29623 statsp->mac_stats.link_speed = 100; 45093859Sml29623 statsp->mac_stats.link_duplex = 1; 45103859Sml29623 } else if (an_common.bits.cap_10fdx) { 45113859Sml29623 statsp->mac_stats.link_speed = 10; 45123859Sml29623 statsp->mac_stats.link_duplex = 2; 45133859Sml29623 } else if (an_common.bits.cap_10hdx) { 45143859Sml29623 statsp->mac_stats.link_speed = 10; 45153859Sml29623 statsp->mac_stats.link_duplex = 1; 45163859Sml29623 } else { 45173859Sml29623 goto fail; 45183859Sml29623 } 45193859Sml29623 } 45203859Sml29623 if (statsp->mac_stats.link_duplex != 1) { 45216929Smisaki int link_pause; 45226929Smisaki int cp, lcp; 45236929Smisaki 45243859Sml29623 statsp->mac_stats.link_asmpause = 45256929Smisaki an_common.bits.cap_asmpause; 45266929Smisaki cp = statsp->mac_stats.cap_pause; 45276929Smisaki lcp = statsp->mac_stats.lp_cap_pause; 45286929Smisaki if (statsp->mac_stats.link_asmpause) { 45296929Smisaki if ((cp == 0) && (lcp == 1)) { 45306929Smisaki link_pause = 0; 45316929Smisaki } else { 45326929Smisaki link_pause = 1; 45336929Smisaki } 45346929Smisaki } else { 45356929Smisaki link_pause = an_common.bits.cap_pause; 45366929Smisaki } 45376929Smisaki statsp->mac_stats.link_pause = link_pause; 45383859Sml29623 } 45395196Ssbehera } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 45405196Ssbehera statsp->mac_stats.link_speed = 1000; 45415196Ssbehera statsp->mac_stats.link_duplex = 2; 45423859Sml29623 } 45433859Sml29623 *link_up = LINK_IS_UP; 45443859Sml29623 } 45453859Sml29623 45463859Sml29623 if (nxgep->link_notify) { 45473859Sml29623 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 45486929Smisaki LINK_IS_DOWN); 45493859Sml29623 nxgep->link_notify = B_FALSE; 45503859Sml29623 } 45513859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 45523859Sml29623 return (NXGE_OK); 45533859Sml29623 fail: 45543859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 45556929Smisaki "nxge_mii_check: Unable to check MII")); 45563859Sml29623 return (status); 45573859Sml29623 } 45583859Sml29623 45596835Syc148097 /* 45606835Syc148097 * Check PCS to see if there is any link status change. 45616835Syc148097 * This function is called by PORT_1G_SERDES only. 45626835Syc148097 */ 45636835Syc148097 void 45644977Sraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up) 45654977Sraghus { 45664977Sraghus p_nxge_stats_t statsp; 45674977Sraghus boolean_t linkup; 45684977Sraghus 45694977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check")); 45704977Sraghus 45714977Sraghus statsp = nxgep->statsp; 45724977Sraghus *link_up = LINK_NO_CHANGE; 45734977Sraghus 45744977Sraghus (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup); 45754977Sraghus if (linkup) { 45764977Sraghus if (nxgep->link_notify || 45774977Sraghus nxgep->statsp->mac_stats.link_up == 0) { 45784977Sraghus statsp->mac_stats.link_up = 1; 45794977Sraghus statsp->mac_stats.link_speed = 1000; 45804977Sraghus statsp->mac_stats.link_duplex = 2; 45814977Sraghus *link_up = LINK_IS_UP; 45824977Sraghus nxgep->link_notify = B_FALSE; 45834977Sraghus } 45844977Sraghus } else { 45854977Sraghus if (nxgep->link_notify || 45864977Sraghus nxgep->statsp->mac_stats.link_up == 1) { 45874977Sraghus statsp->mac_stats.link_up = 0; 45884977Sraghus statsp->mac_stats.link_speed = 0; 45894977Sraghus statsp->mac_stats.link_duplex = 0; 45904977Sraghus *link_up = LINK_IS_DOWN; 45914977Sraghus nxgep->link_notify = B_FALSE; 45924977Sraghus } 45934977Sraghus } 45944977Sraghus 45954977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check")); 45964977Sraghus } 45974977Sraghus 45983859Sml29623 /* Add a multicast address entry into the HW hash table */ 45993859Sml29623 46003859Sml29623 nxge_status_t 46013859Sml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 46023859Sml29623 { 46033859Sml29623 uint32_t mchash; 46043859Sml29623 p_hash_filter_t hash_filter; 46053859Sml29623 uint16_t hash_bit; 46063859Sml29623 boolean_t rx_init = B_FALSE; 46073859Sml29623 uint_t j; 46083859Sml29623 nxge_status_t status = NXGE_OK; 46093859Sml29623 46103859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 46113859Sml29623 46123859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 46133859Sml29623 mchash = crc32_mchash(addrp); 46143859Sml29623 if (nxgep->hash_filter == NULL) { 46153859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 46166929Smisaki "Allocating hash filter storage.")); 46173859Sml29623 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 46186929Smisaki KM_SLEEP); 46193859Sml29623 } 46203859Sml29623 hash_filter = nxgep->hash_filter; 46213859Sml29623 j = mchash / HASH_REG_WIDTH; 46223859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 46233859Sml29623 hash_filter->hash_filter_regs[j] |= hash_bit; 46243859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]++; 46253859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 46263859Sml29623 hash_filter->hash_ref_cnt++; 46273859Sml29623 rx_init = B_TRUE; 46283859Sml29623 } 46293859Sml29623 if (rx_init) { 46303859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 46313859Sml29623 goto fail; 46323859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 46333859Sml29623 goto fail; 46343859Sml29623 } 46353859Sml29623 46363859Sml29623 RW_EXIT(&nxgep->filter_lock); 46373859Sml29623 46383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 46393859Sml29623 46403859Sml29623 return (NXGE_OK); 46413859Sml29623 fail: 46423859Sml29623 RW_EXIT(&nxgep->filter_lock); 46433859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 46446929Smisaki "Unable to add multicast address")); 46453859Sml29623 return (status); 46463859Sml29623 } 46473859Sml29623 46483859Sml29623 /* Remove a multicast address entry from the HW hash table */ 46493859Sml29623 46503859Sml29623 nxge_status_t 46513859Sml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 46523859Sml29623 { 46533859Sml29623 uint32_t mchash; 46543859Sml29623 p_hash_filter_t hash_filter; 46553859Sml29623 uint16_t hash_bit; 46563859Sml29623 boolean_t rx_init = B_FALSE; 46573859Sml29623 uint_t j; 46583859Sml29623 nxge_status_t status = NXGE_OK; 46593859Sml29623 46603859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 46613859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 46623859Sml29623 mchash = crc32_mchash(addrp); 46633859Sml29623 if (nxgep->hash_filter == NULL) { 46643859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 46656929Smisaki "Hash filter already de_allocated.")); 46663859Sml29623 RW_EXIT(&nxgep->filter_lock); 46673859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 46683859Sml29623 return (NXGE_OK); 46693859Sml29623 } 46703859Sml29623 hash_filter = nxgep->hash_filter; 46713859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]--; 46723859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 46733859Sml29623 j = mchash / HASH_REG_WIDTH; 46743859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 46753859Sml29623 hash_filter->hash_filter_regs[j] &= ~hash_bit; 46763859Sml29623 hash_filter->hash_ref_cnt--; 46773859Sml29623 rx_init = B_TRUE; 46783859Sml29623 } 46793859Sml29623 if (hash_filter->hash_ref_cnt == 0) { 46803859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 46816929Smisaki "De-allocating hash filter storage.")); 46823859Sml29623 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 46833859Sml29623 nxgep->hash_filter = NULL; 46843859Sml29623 } 46853859Sml29623 46863859Sml29623 if (rx_init) { 46873859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 46883859Sml29623 goto fail; 46893859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 46903859Sml29623 goto fail; 46913859Sml29623 } 46923859Sml29623 RW_EXIT(&nxgep->filter_lock); 46933859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 46943859Sml29623 46953859Sml29623 return (NXGE_OK); 46963859Sml29623 fail: 46973859Sml29623 RW_EXIT(&nxgep->filter_lock); 46983859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 46996929Smisaki "Unable to remove multicast address")); 47003859Sml29623 47013859Sml29623 return (status); 47023859Sml29623 } 47033859Sml29623 47043859Sml29623 /* Set MAC address into MAC address HW registers */ 47053859Sml29623 47063859Sml29623 nxge_status_t 47073859Sml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 47083859Sml29623 { 47093859Sml29623 nxge_status_t status = NXGE_OK; 47103859Sml29623 47113859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 47123859Sml29623 47133859Sml29623 MUTEX_ENTER(&nxgep->ouraddr_lock); 47143859Sml29623 /* 47153859Sml29623 * Exit if the address is same as ouraddr or multicast or broadcast 47163859Sml29623 */ 47173859Sml29623 if (((addrp->ether_addr_octet[0] & 01) == 1) || 47186929Smisaki (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 47196929Smisaki (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 47203859Sml29623 goto nxge_set_mac_addr_exit; 47213859Sml29623 } 47223859Sml29623 nxgep->ouraddr = *addrp; 47233859Sml29623 /* 47243859Sml29623 * Set new interface local address and re-init device. 47253859Sml29623 * This is destructive to any other streams attached 47263859Sml29623 * to this device. 47273859Sml29623 */ 47283859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 47293859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 47303859Sml29623 goto fail; 47313859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 47323859Sml29623 goto fail; 47333859Sml29623 47343859Sml29623 RW_EXIT(&nxgep->filter_lock); 47353859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 47363859Sml29623 goto nxge_set_mac_addr_end; 47373859Sml29623 nxge_set_mac_addr_exit: 47383859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 47393859Sml29623 nxge_set_mac_addr_end: 47403859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 47413859Sml29623 47423859Sml29623 return (NXGE_OK); 47433859Sml29623 fail: 47443859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 47453859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 47466929Smisaki "Unable to set mac address")); 47473859Sml29623 return (status); 47483859Sml29623 } 47493859Sml29623 47504693Stm144005 static 47514693Stm144005 check_link_state_t 47526835Syc148097 nxge_check_link_stop(nxge_t *nxge) 47534693Stm144005 { 47544693Stm144005 /* If the poll has been cancelled, return STOP. */ 47554693Stm144005 MUTEX_ENTER(&nxge->poll_lock); 47564693Stm144005 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 47574693Stm144005 nxge->poll_state = LINK_MONITOR_STOP; 47584693Stm144005 nxge->nxge_link_poll_timerid = 0; 47594693Stm144005 cv_broadcast(&nxge->poll_cv); 47604693Stm144005 MUTEX_EXIT(&nxge->poll_lock); 47614693Stm144005 47624693Stm144005 NXGE_DEBUG_MSG((nxge, MAC_CTL, 47634693Stm144005 "nxge_check_%s_link(port<%d>) stopped.", 47644693Stm144005 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 47654693Stm144005 nxge->mac.portnum)); 47664693Stm144005 return (CHECK_LINK_STOP); 47674693Stm144005 } 47684693Stm144005 MUTEX_EXIT(&nxge->poll_lock); 47694693Stm144005 47704693Stm144005 return (CHECK_LINK_RESCHEDULE); 47714693Stm144005 } 47724693Stm144005 47736835Syc148097 /* 47746835Syc148097 * Check status of MII (MIF or PCS) link. 47756835Syc148097 * This function is called once per second, that is because this function 47766835Syc148097 * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to 47776835Syc148097 * call this function recursively. 47786835Syc148097 */ 47794732Sdavemq static nxge_status_t 47803859Sml29623 nxge_check_mii_link(p_nxge_t nxgep) 47813859Sml29623 { 47823859Sml29623 mii_bmsr_t bmsr_ints, bmsr_data; 47833859Sml29623 mii_anlpar_t anlpar; 47843859Sml29623 mii_gsr_t gsr; 47853859Sml29623 p_mii_regs_t mii_regs; 47863859Sml29623 nxge_status_t status = NXGE_OK; 47873859Sml29623 uint8_t portn; 47883859Sml29623 nxge_link_state_t link_up; 47893859Sml29623 47904693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 47914693Stm144005 return (NXGE_ERROR); 47924693Stm144005 47934693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 47944693Stm144005 return (NXGE_OK); 47954693Stm144005 47963859Sml29623 portn = nxgep->mac.portnum; 47973859Sml29623 47983859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 47994693Stm144005 portn)); 48003859Sml29623 48013859Sml29623 mii_regs = NULL; 48023859Sml29623 48033859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 48043859Sml29623 48053859Sml29623 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 48063859Sml29623 goto nxge_check_mii_link_exit; 48073859Sml29623 48084977Sraghus switch (nxgep->mac.portmode) { 48094977Sraghus default: 48105196Ssbehera bmsr_data.value = 0; 48113859Sml29623 if ((status = nxge_mii_read(nxgep, 48124977Sraghus nxgep->statsp->mac_stats.xcvr_portn, 48135125Sjoycey #if defined(__i386) 48145125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 48155125Sjoycey #else 48164977Sraghus (uint8_t)(uint64_t)(&mii_regs->bmsr), 48175125Sjoycey #endif 48184977Sraghus &bmsr_data.value)) != NXGE_OK) { 48193859Sml29623 goto fail; 48203859Sml29623 } 48214977Sraghus 48225196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 48235196Ssbehera "==> nxge_check_mii_link port<0x%x> " 48245196Ssbehera "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ", 48255572Ssbehera portn, bmsr_data.value, nxgep->bmsr.value)); 48265196Ssbehera 48274977Sraghus if (nxgep->param_arr[param_autoneg].value) { 48284977Sraghus if ((status = nxge_mii_read(nxgep, 48296929Smisaki nxgep->statsp->mac_stats.xcvr_portn, 48305125Sjoycey #if defined(__i386) 48316929Smisaki (uint8_t)(uint32_t)(&mii_regs->gsr), 48325125Sjoycey #else 48336929Smisaki (uint8_t)(uint64_t)(&mii_regs->gsr), 48345125Sjoycey #endif 48356929Smisaki &gsr.value)) != NXGE_OK) 48364977Sraghus goto fail; 48374977Sraghus if ((status = nxge_mii_read(nxgep, 48386929Smisaki nxgep->statsp->mac_stats.xcvr_portn, 48395125Sjoycey #if defined(__i386) 48406929Smisaki (uint8_t)(uint32_t)(&mii_regs->anlpar), 48415125Sjoycey #else 48426929Smisaki (uint8_t)(uint64_t)(&mii_regs->anlpar), 48435125Sjoycey #endif 48446929Smisaki &anlpar.value)) != NXGE_OK) 48454977Sraghus goto fail; 48465196Ssbehera if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) { 48475196Ssbehera 48485196Ssbehera if (nxgep->statsp->mac_stats.link_up && 48495196Ssbehera ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 48505196Ssbehera gsr.bits.link_1000fdx) || 48515196Ssbehera (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 48525196Ssbehera gsr.bits.link_1000hdx) || 48535196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 48545196Ssbehera anlpar.bits.cap_100T4) || 48555196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 48565196Ssbehera anlpar.bits.cap_100fdx) || 48575196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 48585196Ssbehera anlpar.bits.cap_100hdx) || 48595196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 48605196Ssbehera anlpar.bits.cap_10fdx) || 48615196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 48625196Ssbehera anlpar.bits.cap_10hdx))) { 48635196Ssbehera bmsr_data.bits.link_status = 0; 48645196Ssbehera } 48654977Sraghus } 48664977Sraghus } 48674977Sraghus 48684977Sraghus /* Workaround for link down issue */ 48694977Sraghus if (bmsr_data.value == 0) { 48704977Sraghus cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 48714977Sraghus goto nxge_check_mii_link_exit; 48724977Sraghus } 48734977Sraghus 48745196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 48755196Ssbehera "==> nxge_check_mii_link port<0x%x> :" 48765196Ssbehera "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x", 48775572Ssbehera portn, nxgep->bmsr.value, bmsr_data.value)); 48785196Ssbehera 48794977Sraghus bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 48804977Sraghus nxgep->bmsr.value = bmsr_data.value; 48815196Ssbehera 48825196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 48835196Ssbehera "==> nxge_check_mii_link port<0x%x> CALLING " 48845196Ssbehera "bmsr_data 0x%x bmsr_ints.value 0x%x", 48855572Ssbehera portn, bmsr_data.value, bmsr_ints.value)); 48865196Ssbehera 48874977Sraghus if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, 48884977Sraghus &link_up)) != NXGE_OK) { 48894977Sraghus goto fail; 48904977Sraghus } 48914977Sraghus break; 48924977Sraghus 48934977Sraghus case PORT_1G_SERDES: 48946835Syc148097 /* 48956835Syc148097 * Above default is for all cases except PORT_1G_SERDES. 48966835Syc148097 * The default case gets information from the PHY, but a 48976835Syc148097 * nxge whose portmode equals PORT_1G_SERDES does not 48986835Syc148097 * have a PHY. 48996835Syc148097 */ 49004977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49014977Sraghus "==> nxge_check_mii_link port<%d> (SERDES)", portn)); 49026835Syc148097 nxge_pcs_check(nxgep, portn, &link_up); 49034977Sraghus break; 49043859Sml29623 } 49053859Sml29623 49063859Sml29623 nxge_check_mii_link_exit: 49073859Sml29623 RW_EXIT(&nxgep->filter_lock); 49083859Sml29623 if (link_up == LINK_IS_UP) { 49093859Sml29623 nxge_link_is_up(nxgep); 49103859Sml29623 } else if (link_up == LINK_IS_DOWN) { 49113859Sml29623 nxge_link_is_down(nxgep); 49123859Sml29623 } 49133859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 49143859Sml29623 49153859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 49166929Smisaki portn)); 49173859Sml29623 return (NXGE_OK); 49183859Sml29623 49193859Sml29623 fail: 49203859Sml29623 RW_EXIT(&nxgep->filter_lock); 49213859Sml29623 49223859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 49233859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 49246929Smisaki "nxge_check_mii_link: Failed to check link port<%d>", portn)); 49253859Sml29623 return (status); 49263859Sml29623 } 49273859Sml29623 49283859Sml29623 /*ARGSUSED*/ 49294732Sdavemq static nxge_status_t 49303859Sml29623 nxge_check_10g_link(p_nxge_t nxgep) 49313859Sml29623 { 49323859Sml29623 uint8_t portn; 49333859Sml29623 nxge_status_t status = NXGE_OK; 49345422Ssbehera boolean_t link_up; 49354977Sraghus uint32_t val; 49364977Sraghus npi_status_t rs; 49373859Sml29623 49384693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 49394693Stm144005 return (NXGE_ERROR); 49404693Stm144005 49414693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 49424693Stm144005 return (NXGE_OK); 49434693Stm144005 49443859Sml29623 portn = nxgep->mac.portnum; 49455196Ssbehera val = 0; 49465196Ssbehera rs = NPI_SUCCESS; 49473859Sml29623 49483859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 49494693Stm144005 portn)); 49503859Sml29623 49514977Sraghus switch (nxgep->mac.portmode) { 49524977Sraghus default: 49535572Ssbehera /* 49545572Ssbehera * Check if the phy is present in case of hot swappable phy 49555572Ssbehera */ 49565572Ssbehera if (nxgep->hot_swappable_phy) { 49575572Ssbehera boolean_t phy_present_now = B_FALSE; 49585572Ssbehera 49595572Ssbehera /* 49605572Ssbehera * If this is the 2nd Goa port, then check 2 addresses 49615572Ssbehera * to take care of the Goa NEM card requirements. 49625572Ssbehera */ 49635572Ssbehera if (portn == 1) { 49645572Ssbehera if (nxge_is_phy_present(nxgep, 49656835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR, 49665572Ssbehera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 49675572Ssbehera phy_present_now = B_TRUE; 49685572Ssbehera nxgep->xcvr_addr = 49696835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR; 49705572Ssbehera goto phy_check_done; 49715572Ssbehera } 49725572Ssbehera } 49735572Ssbehera if (nxge_is_phy_present(nxgep, 49746835Syc148097 (GOA_CLAUSE45_PORT_ADDR_BASE) + portn, 49755572Ssbehera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 49765572Ssbehera nxgep->xcvr_addr = 49776835Syc148097 (GOA_CLAUSE45_PORT_ADDR_BASE) + portn; 49785572Ssbehera phy_present_now = B_TRUE; 49795572Ssbehera } 49805572Ssbehera 49815572Ssbehera phy_check_done: 49825572Ssbehera if (nxgep->phy_absent) { 49835572Ssbehera if (phy_present_now) { 49845572Ssbehera /* 49855572Ssbehera * Detect, Initialize phy and do link up 49865572Ssbehera * set xcvr vals, link_init, nxge_init 49875572Ssbehera */ 49885572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49895572Ssbehera "Hot swappable phy DETECTED!!")); 49905572Ssbehera nxgep->phy_absent = B_FALSE; 49915572Ssbehera (void) nxge_xcvr_find(nxgep); 49925572Ssbehera (void) nxge_link_init(nxgep); 49935572Ssbehera if (!(nxgep->drv_state & 49945572Ssbehera STATE_HW_INITIALIZED)) { 49955572Ssbehera status = nxge_init(nxgep); 49965572Ssbehera if (status != NXGE_OK) { 49975572Ssbehera NXGE_ERROR_MSG((nxgep, 49985572Ssbehera NXGE_ERR_CTL, 49995572Ssbehera "Hot swappable " 50005572Ssbehera "phy present, but" 50015572Ssbehera " driver init" 50025572Ssbehera " failed...")); 50035572Ssbehera goto fail; 50045572Ssbehera } 50055572Ssbehera } 50065572Ssbehera } 50075572Ssbehera 50085572Ssbehera goto start_link_check; 50095572Ssbehera 50105572Ssbehera } else if (!phy_present_now) { 50115572Ssbehera /* 50125572Ssbehera * Phy gone, bring link down reset xcvr vals 50135572Ssbehera */ 50145572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50155572Ssbehera "Hot swappable phy REMOVED!!")); 50165572Ssbehera nxgep->phy_absent = B_TRUE; 50175572Ssbehera nxgep->statsp->mac_stats.link_up = 0; 50185572Ssbehera nxgep->statsp->mac_stats.link_speed = 0; 50195572Ssbehera nxgep->statsp->mac_stats.link_duplex = 0; 50205572Ssbehera nxge_link_is_down(nxgep); 50215572Ssbehera nxgep->link_notify = B_FALSE; 50225572Ssbehera 50235572Ssbehera (void) nxge_xcvr_find(nxgep); 50245572Ssbehera 50255572Ssbehera goto start_link_check; 50265572Ssbehera 50275572Ssbehera } 50285572Ssbehera } 50296604Ssbehera if (nxgep->chip_id == MRVL88X201X_CHIP_ID) { 50306835Syc148097 status = nxge_check_mrvl88x2011_link(nxgep, &link_up); 50316604Ssbehera } else { 50326604Ssbehera status = nxge_check_bcm8704_link(nxgep, &link_up); 50336604Ssbehera } 50344977Sraghus if (status != NXGE_OK) 50354977Sraghus goto fail; 50364977Sraghus break; 50374977Sraghus case PORT_10G_SERDES: 50384977Sraghus rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 50395422Ssbehera XPCS_REG_STATUS, &val); 50404977Sraghus if (rs != 0) 50414977Sraghus goto fail; 50424977Sraghus 50434977Sraghus link_up = B_FALSE; 50445422Ssbehera if (val & XPCS_STATUS_LANE_ALIGN) { 50455422Ssbehera link_up = B_TRUE; 50464977Sraghus } 50474977Sraghus 50484977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50494977Sraghus "==> nxge_check_10g_link port<%d> " 50505422Ssbehera "XPCS_REG_STATUS2 0x%x link_up %d", 50515422Ssbehera portn, val, link_up)); 50525422Ssbehera 50534977Sraghus break; 50544977Sraghus } 50553859Sml29623 50563859Sml29623 if (link_up) { 50573859Sml29623 if (nxgep->link_notify || 50586929Smisaki nxgep->statsp->mac_stats.link_up == 0) { 50593859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 50603859Sml29623 goto fail; 50613859Sml29623 nxgep->statsp->mac_stats.link_up = 1; 50623859Sml29623 nxgep->statsp->mac_stats.link_speed = 10000; 50633859Sml29623 nxgep->statsp->mac_stats.link_duplex = 2; 50643859Sml29623 50653859Sml29623 nxge_link_is_up(nxgep); 50663859Sml29623 nxgep->link_notify = B_FALSE; 50673859Sml29623 } 50683859Sml29623 } else { 50693859Sml29623 if (nxgep->link_notify || 50706929Smisaki nxgep->statsp->mac_stats.link_up == 1) { 50713859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 50723859Sml29623 goto fail; 50733859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50746929Smisaki "Link down cable problem")); 50753859Sml29623 nxgep->statsp->mac_stats.link_up = 0; 50763859Sml29623 nxgep->statsp->mac_stats.link_speed = 0; 50773859Sml29623 nxgep->statsp->mac_stats.link_duplex = 0; 50783859Sml29623 50793859Sml29623 nxge_link_is_down(nxgep); 50803859Sml29623 nxgep->link_notify = B_FALSE; 50813859Sml29623 } 50823859Sml29623 } 50833859Sml29623 50845572Ssbehera start_link_check: 50853859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 50863859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 50874693Stm144005 portn)); 50883859Sml29623 return (NXGE_OK); 50893859Sml29623 50903859Sml29623 fail: 50914693Stm144005 (void) nxge_check_link_stop(nxgep); 50924693Stm144005 50933859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 50944693Stm144005 "nxge_check_10g_link: Failed to check link port<%d>", 50954693Stm144005 portn)); 50963859Sml29623 return (status); 50973859Sml29623 } 50983859Sml29623 50993859Sml29623 51003859Sml29623 /* Declare link down */ 51013859Sml29623 51023859Sml29623 void 51033859Sml29623 nxge_link_is_down(p_nxge_t nxgep) 51043859Sml29623 { 51054732Sdavemq p_nxge_stats_t statsp; 51064732Sdavemq char link_stat_msg[64]; 51074732Sdavemq 51083859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 51093859Sml29623 51104732Sdavemq statsp = nxgep->statsp; 51114732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 51124732Sdavemq statsp->mac_stats.xcvr_portn); 51134732Sdavemq 51144732Sdavemq if (nxge_no_msg == B_FALSE) { 51154732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 51164732Sdavemq } 51174732Sdavemq 51183859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 51193859Sml29623 51203859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 51213859Sml29623 } 51223859Sml29623 51233859Sml29623 /* Declare link up */ 51243859Sml29623 51253859Sml29623 void 51263859Sml29623 nxge_link_is_up(p_nxge_t nxgep) 51273859Sml29623 { 51284732Sdavemq p_nxge_stats_t statsp; 51294732Sdavemq char link_stat_msg[64]; 51303859Sml29623 uint32_t val; 51313859Sml29623 51323859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 51333859Sml29623 51344732Sdavemq statsp = nxgep->statsp; 51354732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 51364732Sdavemq statsp->mac_stats.xcvr_portn, 51374732Sdavemq statsp->mac_stats.link_speed); 51384732Sdavemq 51394732Sdavemq if (statsp->mac_stats.link_T4) 51404732Sdavemq (void) strcat(link_stat_msg, "T4"); 51414732Sdavemq else if (statsp->mac_stats.link_duplex == 2) 51424732Sdavemq (void) strcat(link_stat_msg, "full duplex"); 51434732Sdavemq else 51444732Sdavemq (void) strcat(link_stat_msg, "half duplex"); 51454732Sdavemq 51463859Sml29623 51473859Sml29623 /* Clean up symbol errors incurred during link transition */ 51484977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER) || 51494977Sraghus (nxgep->mac.portmode == PORT_10G_SERDES)) { 51503859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 51516929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 51523859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 51536929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 51543859Sml29623 } 51553859Sml29623 51566835Syc148097 /* 51576835Syc148097 * If the driver was plumbed without a link (therefore auto-negotiation 51586835Syc148097 * could not complete), the driver will detect a link up when a cable 51596835Syc148097 * conneting to a link partner is plugged into the port. By the time 51606835Syc148097 * link-up is detected, auto-negotiation should have completed (The 51616835Syc148097 * TN1010 tries to contact a link partner every 8~24ms). Here we re- 51626835Syc148097 * configure the Neptune/NIU according to the newly negotiated speed. 51636835Syc148097 * This is necessary only for the TN1010 basad device because only the 51646835Syc148097 * TN1010 supports dual speeds. 51656835Syc148097 */ 51666835Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 || 51676835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) { 51686835Syc148097 51696835Syc148097 (void) nxge_set_tn1010_param(nxgep); 51706835Syc148097 51716835Syc148097 /* 51726835Syc148097 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets 51736835Syc148097 * nxgep->portmode) and nxge_setup_xcvr_table (which sets 51746835Syc148097 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct). 51756835Syc148097 */ 51766835Syc148097 if (nxge_xcvr_find(nxgep) != NXGE_OK) { 51776835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 51786835Syc148097 "nxge_link_is_up: nxge_xcvr_find failed")); 51796835Syc148097 } 51806835Syc148097 51816835Syc148097 /* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */ 51826835Syc148097 if (nxge_link_init(nxgep) != NXGE_OK) { 51836835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 51846835Syc148097 "nxge_link_is_up: nxge_link_init failed")); 51856835Syc148097 } 51866835Syc148097 51876835Syc148097 /* 51886835Syc148097 * nxge_mac_init calls many subroutines including 51896835Syc148097 * nxge_xif_init which sets XGMII or GMII mode 51906835Syc148097 */ 51916835Syc148097 if (nxge_mac_init(nxgep) != NXGE_OK) { 51926835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 51936835Syc148097 "nxge_link_is_up: nxge_mac_init failed")); 51946835Syc148097 } 51956835Syc148097 } else { 51966835Syc148097 (void) nxge_xif_init(nxgep); 51976835Syc148097 } 51986835Syc148097 51994732Sdavemq if (nxge_no_msg == B_FALSE) { 52004732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 52014732Sdavemq } 52024732Sdavemq 52033859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_UP); 52043859Sml29623 52053859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 52063859Sml29623 } 52073859Sml29623 52086835Syc148097 #ifdef NXGE_DEBUG 52096835Syc148097 /* Dump all TN1010 Status registers */ 52106835Syc148097 static void 52116835Syc148097 nxge_dump_tn1010_status_regs(p_nxge_t nxgep) 52126835Syc148097 { 52136835Syc148097 uint16_t val; 52146835Syc148097 52156835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52166835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 1, &val); 52176835Syc148097 cmn_err(CE_NOTE, "PMA status1 = 0x%x", val); 52186835Syc148097 52196835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52206835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 8, &val); 52216835Syc148097 cmn_err(CE_NOTE, "PMA status2 = 0x%x", val); 52226835Syc148097 52236835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52246835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 129, &val); 52256835Syc148097 cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val); 52266835Syc148097 52276835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52286835Syc148097 TN1010_PCS_DEV_ADDR, 1, &val); 52296835Syc148097 cmn_err(CE_NOTE, "PCS status1 = 0x%x", val); 52306835Syc148097 52316835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52326835Syc148097 TN1010_PCS_DEV_ADDR, 8, &val); 52336835Syc148097 cmn_err(CE_NOTE, "PCS status2 = 0x%x", val); 52346835Syc148097 52356835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52366835Syc148097 TN1010_PCS_DEV_ADDR, 32, &val); 52376835Syc148097 cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val); 52386835Syc148097 52396835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52406835Syc148097 TN1010_PCS_DEV_ADDR, 33, &val); 52416835Syc148097 cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val); 52426835Syc148097 52436835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52446835Syc148097 TN1010_PHYXS_DEV_ADDR, 1, &val); 52456835Syc148097 cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val); 52466835Syc148097 52476835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52486835Syc148097 TN1010_PHYXS_DEV_ADDR, 8, &val); 52496835Syc148097 cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val); 52506835Syc148097 52516835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52526835Syc148097 TN1010_PHYXS_DEV_ADDR, 24, &val); 52536835Syc148097 cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val); 52546835Syc148097 52556835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52566835Syc148097 TN1010_AUTONEG_DEV_ADDR, 1, &val); 52576835Syc148097 cmn_err(CE_NOTE, "Autoneg status = 0x%x", val); 52586835Syc148097 52596835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52606835Syc148097 TN1010_AUTONEG_DEV_ADDR, 33, &val); 52616835Syc148097 cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val); 52626835Syc148097 52636835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52646835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val); 52656835Syc148097 cmn_err(CE_NOTE, "TN1010 status = 0x%x", val); 52666835Syc148097 52676835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52686835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val); 52696835Syc148097 cmn_err(CE_NOTE, "Device status = 0x%x", val); 52706835Syc148097 52716835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52726835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val); 52736835Syc148097 cmn_err(CE_NOTE, "DDR status = 0x%x", val); 52746835Syc148097 52756835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52766835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val); 52776835Syc148097 cmn_err(CE_NOTE, "DDR fault status = 0x%x", val); 52786835Syc148097 52796835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52806835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val); 52816835Syc148097 cmn_err(CE_NOTE, "Firmware Revision = 0x%x Major = 0x%x Minor = 0x%x", 52826835Syc148097 val, (val & 0xFF00) >> 8, val & 0x00FF); 52836835Syc148097 } 52846835Syc148097 #endif 52856835Syc148097 52863859Sml29623 /* 52873859Sml29623 * Calculate the bit in the multicast address filter 52883859Sml29623 * that selects the given * address. 52893859Sml29623 * Note: For GEM, the last 8-bits are used. 52903859Sml29623 */ 52913859Sml29623 uint32_t 52923859Sml29623 crc32_mchash(p_ether_addr_t addr) 52933859Sml29623 { 52943859Sml29623 uint8_t *cp; 52953859Sml29623 uint32_t crc; 52963859Sml29623 uint32_t c; 52973859Sml29623 int byte; 52983859Sml29623 int bit; 52993859Sml29623 53003859Sml29623 cp = (uint8_t *)addr; 53013859Sml29623 crc = (uint32_t)0xffffffff; 53023859Sml29623 for (byte = 0; byte < 6; byte++) { 53033859Sml29623 c = (uint32_t)cp[byte]; 53043859Sml29623 for (bit = 0; bit < 8; bit++) { 53053859Sml29623 if ((c & 0x1) ^ (crc & 0x1)) 53063859Sml29623 crc = (crc >> 1)^0xedb88320; 53073859Sml29623 else 53083859Sml29623 crc = (crc >> 1); 53093859Sml29623 c >>= 1; 53103859Sml29623 } 53113859Sml29623 } 53123859Sml29623 return ((~crc) >> (32 - HASH_BITS)); 53133859Sml29623 } 53143859Sml29623 53153859Sml29623 /* Reset serdes */ 53163859Sml29623 53173859Sml29623 nxge_status_t 53183859Sml29623 nxge_serdes_reset(p_nxge_t nxgep) 53193859Sml29623 { 53203859Sml29623 npi_handle_t handle; 53213859Sml29623 53223859Sml29623 handle = nxgep->npi_handle; 53233859Sml29623 53243859Sml29623 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 53253859Sml29623 drv_usecwait(500); 53263859Sml29623 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 53273859Sml29623 53283859Sml29623 return (NXGE_OK); 53293859Sml29623 } 53303859Sml29623 53316835Syc148097 /* 53326835Syc148097 * This function monitors link status using interrupt or polling. 53336835Syc148097 * It calls nxgep->xcvr.check_link, a member function of 53346835Syc148097 * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this 53356835Syc148097 * function back, that is why the check_link routine is 53366835Syc148097 * executed periodically. 53376835Syc148097 */ 53383859Sml29623 nxge_status_t 53393859Sml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 53403859Sml29623 { 53413859Sml29623 nxge_status_t status = NXGE_OK; 53423859Sml29623 53436495Sspeer /* If we are a guest domain driver, don't bother. */ 53446495Sspeer if (isLDOMguest(nxgep)) 53456495Sspeer return (status); 53466495Sspeer 53473859Sml29623 /* 53484693Stm144005 * Return immediately if this is an imaginary XMAC port. 53494693Stm144005 * (At least, we don't have 4-port XMAC cards yet.) 53503859Sml29623 */ 53514977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER || 53524977Sraghus nxgep->mac.portmode == PORT_10G_SERDES) && 53534977Sraghus (nxgep->mac.portnum > 1)) 53543859Sml29623 return (NXGE_OK); 53553859Sml29623 53563859Sml29623 if (nxgep->statsp == NULL) { 53573859Sml29623 /* stats has not been allocated. */ 53583859Sml29623 return (NXGE_OK); 53593859Sml29623 } 53606075Ssbehera /* Don't check link if we're in internal loopback mode */ 53616075Ssbehera if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g) 53623859Sml29623 return (NXGE_OK); 53633859Sml29623 53643859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 53654693Stm144005 "==> nxge_link_monitor port<%d> enable=%d", 53664693Stm144005 nxgep->mac.portnum, enable)); 53673859Sml29623 if (enable == LINK_MONITOR_START) { 53683859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 53693859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 53704693Stm144005 != NXGE_OK) 53713859Sml29623 goto fail; 53723859Sml29623 } else { 53734693Stm144005 timeout_id_t timerid; 53746835Syc148097 /* 53756835Syc148097 * check_link_stop means "Stop the link check", so 53766835Syc148097 * we return without starting the timer. 53776835Syc148097 */ 53784693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 53794693Stm144005 return (NXGE_OK); 53804693Stm144005 53816835Syc148097 /* 53826835Syc148097 * Otherwise fire the timer for the nxge to check 53836835Syc148097 * the link using the check_link function 53846835Syc148097 * of the nxge_xcvr_table and pass "nxgep" as the 53856835Syc148097 * argument to the check_link function. 53866835Syc148097 */ 53874732Sdavemq if (nxgep->xcvr.check_link) { 53884732Sdavemq timerid = timeout( 53894732Sdavemq (fptrv_t)(nxgep->xcvr.check_link), 53904693Stm144005 nxgep, 53914693Stm144005 drv_usectohz(LINK_MONITOR_PERIOD)); 53924732Sdavemq MUTEX_ENTER(&nxgep->poll_lock); 53934732Sdavemq nxgep->nxge_link_poll_timerid = timerid; 53944732Sdavemq MUTEX_EXIT(&nxgep->poll_lock); 53954732Sdavemq } else { 53964693Stm144005 return (NXGE_ERROR); 53973859Sml29623 } 53983859Sml29623 } 53993859Sml29623 } else { 54003859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 54013859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 54024693Stm144005 != NXGE_OK) 54033859Sml29623 goto fail; 54043859Sml29623 } else { 54054693Stm144005 clock_t rv; 54064693Stm144005 54074693Stm144005 MUTEX_ENTER(&nxgep->poll_lock); 54084693Stm144005 54094693Stm144005 /* If <timerid> == 0, the link monitor has */ 54104693Stm144005 /* never been started, or just now stopped. */ 54114693Stm144005 if (nxgep->nxge_link_poll_timerid == 0) { 54124693Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 54134693Stm144005 return (NXGE_OK); 54144693Stm144005 } 54154693Stm144005 54164693Stm144005 nxgep->poll_state = LINK_MONITOR_STOPPING; 54174693Stm144005 rv = cv_timedwait(&nxgep->poll_cv, 54184693Stm144005 &nxgep->poll_lock, 54194693Stm144005 ddi_get_lbolt() + 54204693Stm144005 drv_usectohz(LM_WAIT_MULTIPLIER * 54214693Stm144005 LINK_MONITOR_PERIOD)); 54224693Stm144005 if (rv == -1) { 54234693Stm144005 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 54244693Stm144005 "==> stopping port %d: " 54254693Stm144005 "cv_timedwait(%d) timed out", 54264693Stm144005 nxgep->mac.portnum, nxgep->poll_state)); 54274693Stm144005 nxgep->poll_state = LINK_MONITOR_STOP; 54283859Sml29623 nxgep->nxge_link_poll_timerid = 0; 54293859Sml29623 } 54304693Stm144005 54314693Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 54323859Sml29623 } 54333859Sml29623 } 54343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 54354693Stm144005 "<== nxge_link_monitor port<%d> enable=%d", 54364693Stm144005 nxgep->mac.portnum, enable)); 54376495Sspeer 54383859Sml29623 return (NXGE_OK); 54393859Sml29623 fail: 54403859Sml29623 return (status); 54416835Syc148097 54423859Sml29623 } 54433859Sml29623 54446835Syc148097 nxge_status_t 54456835Syc148097 nxge_check_tn1010_link(p_nxge_t nxgep) 54466835Syc148097 { 54476835Syc148097 nxge_status_t status = NXGE_OK; 54486835Syc148097 nxge_link_state_t link_up; 54496835Syc148097 54506835Syc148097 if (nxgep->nxge_magic != NXGE_MAGIC) { 54516835Syc148097 /* magic is 0 if driver is not attached */ 54526835Syc148097 return (NXGE_ERROR); 54536835Syc148097 } 54546835Syc148097 54556835Syc148097 /* Link has been stopped, no need to continue */ 54566835Syc148097 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) { 54576835Syc148097 return (NXGE_OK); 54586835Syc148097 } 54596835Syc148097 54606835Syc148097 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 54616835Syc148097 goto nxge_check_tn1010_link_exit; 54626835Syc148097 54636835Syc148097 if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK) 54646835Syc148097 goto fail; 54656835Syc148097 54666835Syc148097 nxge_check_tn1010_link_exit: 54676835Syc148097 if (link_up == LINK_IS_UP) 54686835Syc148097 nxge_link_is_up(nxgep); 54696835Syc148097 else if (link_up == LINK_IS_DOWN) 54706835Syc148097 nxge_link_is_down(nxgep); 54716835Syc148097 54726835Syc148097 /* 54736835Syc148097 * nxge_link_monitor will call (nxgep->xcvr.check_link) 54746835Syc148097 * which could be THIS function. 54756835Syc148097 */ 54766835Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 54776835Syc148097 54786835Syc148097 return (NXGE_OK); 54796835Syc148097 54806835Syc148097 fail: 54816835Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 54826835Syc148097 54836835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 54846835Syc148097 "nxge_check_tn1010_link: Failed to check link")); 54856835Syc148097 return (status); 54866835Syc148097 } 54876835Syc148097 54886835Syc148097 54896835Syc148097 /* 54906835Syc148097 * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN. 54916835Syc148097 */ 54926835Syc148097 static nxge_status_t 54936835Syc148097 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up) 54946835Syc148097 { 54956835Syc148097 nxge_status_t status = NXGE_OK; 54966835Syc148097 p_nxge_stats_t statsp; 54976835Syc148097 uint8_t phy_port_addr, portn; 54986835Syc148097 uint16_t val; 54996835Syc148097 55006835Syc148097 *link_up = LINK_NO_CHANGE; 55016835Syc148097 55026835Syc148097 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 55036835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 55046835Syc148097 statsp = nxgep->statsp; 55056835Syc148097 55066835Syc148097 /* Check if link is up */ 55076835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 55086835Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val)) 55096835Syc148097 != NXGE_OK) { 55106835Syc148097 goto fail; 55116835Syc148097 } 55126835Syc148097 /* 55136835Syc148097 * nxge_link_is_up has called nxge_set_tn1010_param and set 55146835Syc148097 * portmode and link_speed 55156835Syc148097 */ 55166835Syc148097 if (val & TN1010_AN_LINK_STAT_BIT) { 55176835Syc148097 if (nxgep->link_notify || 55186835Syc148097 nxgep->statsp->mac_stats.link_up == 0) { 55196835Syc148097 statsp->mac_stats.link_up = 1; 55206835Syc148097 statsp->mac_stats.link_duplex = 2; 55216835Syc148097 *link_up = LINK_IS_UP; 55226835Syc148097 nxgep->link_notify = B_FALSE; 55236835Syc148097 } 55246835Syc148097 } else { 55256835Syc148097 if (nxgep->link_notify || 55266835Syc148097 nxgep->statsp->mac_stats.link_up == 1) { 55276835Syc148097 statsp->mac_stats.link_up = 0; 55286835Syc148097 statsp->mac_stats.link_speed = 0; 55296835Syc148097 statsp->mac_stats.link_duplex = 0; 55306835Syc148097 *link_up = LINK_IS_DOWN; 55316835Syc148097 nxgep->link_notify = B_FALSE; 55326835Syc148097 } 55336835Syc148097 } 55346835Syc148097 return (NXGE_OK); 55356835Syc148097 55366835Syc148097 fail: 55376835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 55386835Syc148097 "nxge_tn1010_check: Unable to check TN1010")); 55396835Syc148097 return (status); 55406835Syc148097 } 55416835Syc148097 55426835Syc148097 55433859Sml29623 /* Set promiscous mode */ 55443859Sml29623 55453859Sml29623 nxge_status_t 55463859Sml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 55473859Sml29623 { 55483859Sml29623 nxge_status_t status = NXGE_OK; 55493859Sml29623 55504732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 55513859Sml29623 55523859Sml29623 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 55533859Sml29623 55543859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 55553859Sml29623 55563859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 55573859Sml29623 goto fail; 55583859Sml29623 } 55593859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 55603859Sml29623 goto fail; 55613859Sml29623 } 55623859Sml29623 55633859Sml29623 RW_EXIT(&nxgep->filter_lock); 55643859Sml29623 55653859Sml29623 if (on) 55663859Sml29623 nxgep->statsp->mac_stats.promisc = B_TRUE; 55673859Sml29623 else 55683859Sml29623 nxgep->statsp->mac_stats.promisc = B_FALSE; 55693859Sml29623 55703859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 55713859Sml29623 55723859Sml29623 return (NXGE_OK); 55733859Sml29623 fail: 55743859Sml29623 RW_EXIT(&nxgep->filter_lock); 55753859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 55764732Sdavemq "Unable to set promisc (%d)", on)); 55773859Sml29623 55783859Sml29623 return (status); 55793859Sml29623 } 55803859Sml29623 55813859Sml29623 /*ARGSUSED*/ 55823859Sml29623 uint_t 55833859Sml29623 nxge_mif_intr(void *arg1, void *arg2) 55843859Sml29623 { 55853859Sml29623 #ifdef NXGE_DEBUG 55863859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 55873859Sml29623 #endif 55883859Sml29623 #if NXGE_MIF 55893859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 55903859Sml29623 uint32_t status; 55913859Sml29623 npi_handle_t handle; 55923859Sml29623 uint8_t portn; 55933859Sml29623 p_nxge_stats_t statsp; 55943859Sml29623 #endif 55953859Sml29623 55963859Sml29623 #ifdef NXGE_MIF 55973859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 55983859Sml29623 nxgep = ldvp->nxgep; 55993859Sml29623 } 56003859Sml29623 nxgep = ldvp->nxgep; 56013859Sml29623 #endif 56023859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 56033859Sml29623 56043859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 56053859Sml29623 return (DDI_INTR_CLAIMED); 56063859Sml29623 56073859Sml29623 mif_intr_fail: 56083859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 56093859Sml29623 return (DDI_INTR_UNCLAIMED); 56103859Sml29623 } 56113859Sml29623 56123859Sml29623 /*ARGSUSED*/ 56133859Sml29623 uint_t 56143859Sml29623 nxge_mac_intr(void *arg1, void *arg2) 56153859Sml29623 { 56163859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 56173859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 56183859Sml29623 p_nxge_ldg_t ldgp; 56193859Sml29623 uint32_t status; 56203859Sml29623 npi_handle_t handle; 56213859Sml29623 uint8_t portn; 56223859Sml29623 p_nxge_stats_t statsp; 56233859Sml29623 npi_status_t rs = NPI_SUCCESS; 56243859Sml29623 56253859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 56263859Sml29623 nxgep = ldvp->nxgep; 56273859Sml29623 } 56283859Sml29623 56293859Sml29623 ldgp = ldvp->ldgp; 56303859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 56314732Sdavemq "group %d", ldgp->ldg)); 56323859Sml29623 56333859Sml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep); 56343859Sml29623 /* 56353859Sml29623 * This interrupt handler is for a specific 56363859Sml29623 * mac port. 56373859Sml29623 */ 56383859Sml29623 statsp = (p_nxge_stats_t)nxgep->statsp; 56393859Sml29623 portn = nxgep->mac.portnum; 56403859Sml29623 56413859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, 56424732Sdavemq "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 56433859Sml29623 56443859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 56453859Sml29623 rs = npi_xmac_tx_get_istatus(handle, portn, 56466929Smisaki (xmac_tx_iconfig_t *)&status); 56473859Sml29623 if (rs != NPI_SUCCESS) 56483859Sml29623 goto npi_fail; 56493859Sml29623 if (status & ICFG_XMAC_TX_ALL) { 56503859Sml29623 if (status & ICFG_XMAC_TX_UNDERRUN) { 56513859Sml29623 statsp->xmac_stats.tx_underflow_err++; 56523859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 56536929Smisaki NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 56543859Sml29623 } 56553859Sml29623 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 56563859Sml29623 statsp->xmac_stats.tx_maxpktsize_err++; 56575523Syc148097 /* 56585523Syc148097 * Do not send FMA ereport because this 56595523Syc148097 * error does not indicate HW failure. 56605523Syc148097 */ 56613859Sml29623 } 56623859Sml29623 if (status & ICFG_XMAC_TX_OVERFLOW) { 56633859Sml29623 statsp->xmac_stats.tx_overflow_err++; 56643859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 56656929Smisaki NXGE_FM_EREPORT_TXMAC_OVERFLOW); 56663859Sml29623 } 56673859Sml29623 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 56683859Sml29623 statsp->xmac_stats.tx_fifo_xfr_err++; 56693859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 56706929Smisaki NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 56713859Sml29623 } 56723859Sml29623 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 56733859Sml29623 statsp->xmac_stats.tx_byte_cnt += 56746929Smisaki XTXMAC_BYTE_CNT_MASK; 56753859Sml29623 } 56763859Sml29623 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 56773859Sml29623 statsp->xmac_stats.tx_frame_cnt += 56786929Smisaki XTXMAC_FRM_CNT_MASK; 56793859Sml29623 } 56803859Sml29623 } 56813859Sml29623 56823859Sml29623 rs = npi_xmac_rx_get_istatus(handle, portn, 56836929Smisaki (xmac_rx_iconfig_t *)&status); 56843859Sml29623 if (rs != NPI_SUCCESS) 56853859Sml29623 goto npi_fail; 56863859Sml29623 if (status & ICFG_XMAC_RX_ALL) { 56873859Sml29623 if (status & ICFG_XMAC_RX_OVERFLOW) 56883859Sml29623 statsp->xmac_stats.rx_overflow_err++; 56893859Sml29623 if (status & ICFG_XMAC_RX_UNDERFLOW) { 56903859Sml29623 statsp->xmac_stats.rx_underflow_err++; 56913859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 56926929Smisaki NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 56933859Sml29623 } 56945523Syc148097 /* 56955523Syc148097 * Do not send FMA ereport for the following 3 errors 56965523Syc148097 * because they do not indicate HW failures. 56975523Syc148097 */ 56983859Sml29623 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 56993859Sml29623 statsp->xmac_stats.rx_crc_err_cnt += 57006929Smisaki XRXMAC_CRC_ER_CNT_MASK; 57013859Sml29623 } 57023859Sml29623 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 57033859Sml29623 statsp->xmac_stats.rx_len_err_cnt += 57046929Smisaki MAC_LEN_ER_CNT_MASK; 57053859Sml29623 } 57063859Sml29623 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 57073859Sml29623 statsp->xmac_stats.rx_viol_err_cnt += 57086929Smisaki XRXMAC_CD_VIO_CNT_MASK; 57093859Sml29623 } 57103859Sml29623 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 57113859Sml29623 statsp->xmac_stats.rx_byte_cnt += 57126929Smisaki XRXMAC_BT_CNT_MASK; 57133859Sml29623 } 57143859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 57153859Sml29623 statsp->xmac_stats.rx_hist1_cnt += 57166929Smisaki XRXMAC_HIST_CNT1_MASK; 57173859Sml29623 } 57183859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 57193859Sml29623 statsp->xmac_stats.rx_hist2_cnt += 57206929Smisaki XRXMAC_HIST_CNT2_MASK; 57213859Sml29623 } 57223859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 57233859Sml29623 statsp->xmac_stats.rx_hist3_cnt += 57246929Smisaki XRXMAC_HIST_CNT3_MASK; 57253859Sml29623 } 57263859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 57273859Sml29623 statsp->xmac_stats.rx_hist4_cnt += 57286929Smisaki XRXMAC_HIST_CNT4_MASK; 57293859Sml29623 } 57303859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 57313859Sml29623 statsp->xmac_stats.rx_hist5_cnt += 57326929Smisaki XRXMAC_HIST_CNT5_MASK; 57333859Sml29623 } 57343859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 57353859Sml29623 statsp->xmac_stats.rx_hist6_cnt += 57366929Smisaki XRXMAC_HIST_CNT6_MASK; 57373859Sml29623 } 57383859Sml29623 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 57393859Sml29623 statsp->xmac_stats.rx_broadcast_cnt += 57406929Smisaki XRXMAC_BC_FRM_CNT_MASK; 57413859Sml29623 } 57423859Sml29623 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 57433859Sml29623 statsp->xmac_stats.rx_mult_cnt += 57446929Smisaki XRXMAC_MC_FRM_CNT_MASK; 57453859Sml29623 } 57465523Syc148097 /* 57475523Syc148097 * Do not send FMA ereport for the following 3 errors 57485523Syc148097 * because they do not indicate HW failures. 57495523Syc148097 */ 57503859Sml29623 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 57513859Sml29623 statsp->xmac_stats.rx_frag_cnt += 57526929Smisaki XRXMAC_FRAG_CNT_MASK; 57533859Sml29623 } 57543859Sml29623 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 57553859Sml29623 statsp->xmac_stats.rx_frame_align_err_cnt += 57566929Smisaki XRXMAC_AL_ER_CNT_MASK; 57573859Sml29623 } 57583859Sml29623 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 57593859Sml29623 statsp->xmac_stats.rx_linkfault_err_cnt += 57606929Smisaki XMAC_LINK_FLT_CNT_MASK; 57613859Sml29623 } 57623859Sml29623 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 57633859Sml29623 statsp->xmac_stats.rx_remotefault_err++; 57643859Sml29623 } 57653859Sml29623 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 57663859Sml29623 statsp->xmac_stats.rx_localfault_err++; 57673859Sml29623 } 57683859Sml29623 } 57693859Sml29623 57703859Sml29623 rs = npi_xmac_ctl_get_istatus(handle, portn, 57716929Smisaki (xmac_ctl_iconfig_t *)&status); 57723859Sml29623 if (rs != NPI_SUCCESS) 57733859Sml29623 goto npi_fail; 57743859Sml29623 if (status & ICFG_XMAC_CTRL_ALL) { 57753859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 57763859Sml29623 statsp->xmac_stats.rx_pause_cnt++; 57773859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 57783859Sml29623 statsp->xmac_stats.tx_pause_state++; 57793859Sml29623 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 57803859Sml29623 statsp->xmac_stats.tx_nopause_state++; 57813859Sml29623 } 57823859Sml29623 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 57833859Sml29623 rs = npi_bmac_tx_get_istatus(handle, portn, 57846929Smisaki (bmac_tx_iconfig_t *)&status); 57853859Sml29623 if (rs != NPI_SUCCESS) 57863859Sml29623 goto npi_fail; 57873859Sml29623 if (status & ICFG_BMAC_TX_ALL) { 57883859Sml29623 if (status & ICFG_BMAC_TX_UNDERFLOW) { 57893859Sml29623 statsp->bmac_stats.tx_underrun_err++; 57903859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 57916929Smisaki NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 57923859Sml29623 } 57933859Sml29623 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 57943859Sml29623 statsp->bmac_stats.tx_max_pkt_err++; 57953859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 57966929Smisaki NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 57973859Sml29623 } 57983859Sml29623 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 57993859Sml29623 statsp->bmac_stats.tx_byte_cnt += 58006929Smisaki BTXMAC_BYTE_CNT_MASK; 58013859Sml29623 } 58023859Sml29623 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 58033859Sml29623 statsp->bmac_stats.tx_frame_cnt += 58046929Smisaki BTXMAC_FRM_CNT_MASK; 58053859Sml29623 } 58063859Sml29623 } 58073859Sml29623 58083859Sml29623 rs = npi_bmac_rx_get_istatus(handle, portn, 58096929Smisaki (bmac_rx_iconfig_t *)&status); 58103859Sml29623 if (rs != NPI_SUCCESS) 58113859Sml29623 goto npi_fail; 58123859Sml29623 if (status & ICFG_BMAC_RX_ALL) { 58133859Sml29623 if (status & ICFG_BMAC_RX_OVERFLOW) { 58143859Sml29623 statsp->bmac_stats.rx_overflow_err++; 58153859Sml29623 } 58163859Sml29623 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 58173859Sml29623 statsp->bmac_stats.rx_frame_cnt += 58186929Smisaki RXMAC_FRM_CNT_MASK; 58193859Sml29623 } 58203859Sml29623 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 58213859Sml29623 statsp->bmac_stats.rx_crc_err_cnt += 58226929Smisaki BMAC_CRC_ER_CNT_MASK; 58233859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58246929Smisaki NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 58253859Sml29623 } 58263859Sml29623 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 58273859Sml29623 statsp->bmac_stats.rx_len_err_cnt += 58286929Smisaki MAC_LEN_ER_CNT_MASK; 58293859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58306929Smisaki NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 58313859Sml29623 } 58323859Sml29623 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 58333859Sml29623 statsp->bmac_stats.rx_viol_err_cnt += 58346929Smisaki BMAC_CD_VIO_CNT_MASK; 58353859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58366929Smisaki NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 58373859Sml29623 } 58383859Sml29623 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 58393859Sml29623 statsp->bmac_stats.rx_byte_cnt += 58406929Smisaki BRXMAC_BYTE_CNT_MASK; 58413859Sml29623 } 58423859Sml29623 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 58433859Sml29623 statsp->bmac_stats.rx_align_err_cnt += 58446929Smisaki BMAC_AL_ER_CNT_MASK; 58453859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58466929Smisaki NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 58473859Sml29623 } 58483859Sml29623 58493859Sml29623 rs = npi_bmac_ctl_get_istatus(handle, portn, 58506929Smisaki (bmac_ctl_iconfig_t *)&status); 58513859Sml29623 if (rs != NPI_SUCCESS) 58523859Sml29623 goto npi_fail; 58533859Sml29623 58543859Sml29623 if (status & ICFG_BMAC_CTL_ALL) { 58553859Sml29623 if (status & ICFG_BMAC_CTL_RCVPAUSE) 58563859Sml29623 statsp->bmac_stats.rx_pause_cnt++; 58573859Sml29623 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 58583859Sml29623 statsp->bmac_stats.tx_pause_state++; 58593859Sml29623 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 58603859Sml29623 statsp->bmac_stats.tx_nopause_state++; 58613859Sml29623 } 58623859Sml29623 } 58633859Sml29623 58643859Sml29623 if (ldgp->nldvs == 1) { 58653859Sml29623 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 58666929Smisaki B_TRUE, ldgp->ldg_timer); 58673859Sml29623 } 58683859Sml29623 58693859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 58703859Sml29623 return (DDI_INTR_CLAIMED); 58713859Sml29623 58723859Sml29623 npi_fail: 58733859Sml29623 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 58743859Sml29623 return (DDI_INTR_UNCLAIMED); 58753859Sml29623 } 58763859Sml29623 58773859Sml29623 nxge_status_t 58783859Sml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 58793859Sml29623 { 58803859Sml29623 uint8_t phy_port_addr; 58813859Sml29623 nxge_status_t status = NXGE_OK; 58823859Sml29623 boolean_t rx_sig_ok; 58833859Sml29623 boolean_t pcs_blk_lock; 58843859Sml29623 boolean_t link_align; 58853859Sml29623 uint16_t val1, val2, val3; 58863859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 58873859Sml29623 uint16_t val_debug; 58883859Sml29623 uint16_t val; 58893859Sml29623 #endif 58903859Sml29623 58913859Sml29623 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 58923859Sml29623 58933859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 58943859Sml29623 /* Check Device 3 Register Device 3 0xC809 */ 58953859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 58963859Sml29623 if ((val_debug & ~0x200) != 0) { 58973859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 58986929Smisaki nxgep->mac.portnum, val_debug); 58993859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 59006929Smisaki &val_debug); 59013859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 59026929Smisaki nxgep->mac.portnum, val_debug); 59033859Sml29623 } 59043859Sml29623 59053859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 59066929Smisaki XPCS_REG_DESCWERR_COUNTER, &val); 59073859Sml29623 if (val != 0) 59083859Sml29623 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 59093859Sml29623 59103859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 59116929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 59123859Sml29623 if (val != 0) 59133859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 59143859Sml29623 59153859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 59166929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 59173859Sml29623 if (val != 0) 59183859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 59193859Sml29623 #endif 59203859Sml29623 59213859Sml29623 /* Check from BCM8704 if 10G link is up or down */ 59223859Sml29623 59233859Sml29623 /* Check Device 1 Register 0xA bit0 */ 59246929Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR, 59256929Smisaki BCM8704_PMD_RECEIVE_SIG_DETECT, &val1); 59263859Sml29623 if (status != NXGE_OK) 59273859Sml29623 goto fail; 59283859Sml29623 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 59293859Sml29623 59303859Sml29623 /* Check Device 3 Register 0x20 bit0 */ 59316929Smisaki if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR, 59326929Smisaki BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS) 59333859Sml29623 goto fail; 59343859Sml29623 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 59353859Sml29623 59363859Sml29623 /* Check Device 4 Register 0x18 bit12 */ 59376929Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 59386929Smisaki BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3); 59393859Sml29623 if (status != NXGE_OK) 59403859Sml29623 goto fail; 59415572Ssbehera 59425572Ssbehera switch (nxgep->chip_id) { 59435572Ssbehera case BCM8704_CHIP_ID: 59445572Ssbehera link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | 59455572Ssbehera XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 59465572Ssbehera XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 59475572Ssbehera break; 59485572Ssbehera case BCM8706_CHIP_ID: 59495572Ssbehera link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) && 59505572Ssbehera (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) && 59515572Ssbehera (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ? 59525572Ssbehera B_TRUE : B_FALSE; 59535572Ssbehera break; 59545572Ssbehera default: 59555572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:" 59565572Ssbehera "Unknown chip ID [0x%x]", nxgep->chip_id)); 59575572Ssbehera goto fail; 59585572Ssbehera } 59595572Ssbehera 59603859Sml29623 59613859Sml29623 #ifdef NXGE_DEBUG_ALIGN_ERR 59623859Sml29623 /* Temp workaround for link down issue */ 59633859Sml29623 if (pcs_blk_lock == B_FALSE) { 59643859Sml29623 if (val2 != 0x4) { 59653859Sml29623 pcs_blk_lock = B_TRUE; 59666929Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 " 59676929Smisaki "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2); 59683859Sml29623 } 59693859Sml29623 } 59703859Sml29623 59713859Sml29623 if (link_align == B_FALSE) { 59723859Sml29623 if (val3 != 0x140f) { 59733859Sml29623 link_align = B_TRUE; 59746929Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 " 59756929Smisaki "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3); 59763859Sml29623 } 59773859Sml29623 } 59783859Sml29623 59793859Sml29623 if (rx_sig_ok == B_FALSE) { 59803859Sml29623 if ((val2 == 0) || (val3 == 0)) { 59813859Sml29623 rx_sig_ok = B_TRUE; 59823859Sml29623 cmn_err(CE_NOTE, 59836929Smisaki "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 59846929Smisaki nxgep->mac.portnum); 59853859Sml29623 } 59863859Sml29623 } 59873859Sml29623 #endif 59883859Sml29623 59893859Sml29623 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 59906929Smisaki (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 59913859Sml29623 59923859Sml29623 return (NXGE_OK); 59933859Sml29623 fail: 59943859Sml29623 return (status); 59953859Sml29623 } 59963859Sml29623 59976604Ssbehera static nxge_status_t 59986835Syc148097 nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up) 59996604Ssbehera { 60006604Ssbehera uint8_t phy; 60016604Ssbehera nxge_status_t status = NXGE_OK; 60026604Ssbehera boolean_t pma_status; 60036604Ssbehera boolean_t pcs_status; 60046604Ssbehera boolean_t xgxs_status; 60056604Ssbehera uint16_t val; 60066604Ssbehera 60076604Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn; 60086604Ssbehera 60096604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 60106604Ssbehera MRVL_88X2011_10G_PMD_STAT_2, &val); 60116604Ssbehera 60126604Ssbehera *link_up = B_FALSE; 60136604Ssbehera 60146604Ssbehera /* Check from Marvell 88X2011 if 10G link is up or down */ 60156604Ssbehera 60166604Ssbehera /* Check PMA/PMD Register: 1.0001.2 == 1 */ 60176604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 60186604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 60196604Ssbehera 60206604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60216604Ssbehera "nxge_check_mrvl88x2011_link: pmd=0x%x", val)); 60226604Ssbehera 60236604Ssbehera pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE); 60246604Ssbehera 60256604Ssbehera /* Check PMC Register : 3.0001.2 == 1: read twice */ 60266604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 60276604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 60286604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 60296604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 60306604Ssbehera 60316604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60326604Ssbehera "nxge_check_mrvl88x2011_link: pcs=0x%x", val)); 60336604Ssbehera 60346604Ssbehera pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE); 60356604Ssbehera 60366604Ssbehera /* Check XGXS Register : 4.0018.[0-3,12] */ 60376604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR, 60386604Ssbehera MRVL_88X2011_10G_XGXS_LANE_STAT, &val); 60396604Ssbehera 60406604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60416604Ssbehera "nxge_check_mrvl88x2011_link: xgxs=0x%x", val)); 60426604Ssbehera 60436604Ssbehera xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 60446604Ssbehera XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 60456604Ssbehera XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY | 60466604Ssbehera XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE; 60476604Ssbehera 60486604Ssbehera *link_up = (pma_status && pcs_status && xgxs_status) ? 60496604Ssbehera B_TRUE : B_FALSE; 60506604Ssbehera 60516604Ssbehera fail: 60526604Ssbehera 60536604Ssbehera if (*link_up == B_FALSE) { 60546604Ssbehera /* PCS OFF */ 60556604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF); 60566604Ssbehera } else { 60576604Ssbehera /* PCS Activity */ 60586604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT); 60596604Ssbehera } 60606604Ssbehera 60616604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60626604Ssbehera " <== nxge_check_mrvl88x2011_link: up=%d", *link_up)); 60636604Ssbehera 60646604Ssbehera return (status); 60656604Ssbehera } 60666604Ssbehera 60673859Sml29623 nxge_status_t 60683859Sml29623 nxge_10g_link_led_on(p_nxge_t nxgep) 60693859Sml29623 { 60703859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 60714732Sdavemq != NPI_SUCCESS) 60723859Sml29623 return (NXGE_ERROR); 60733859Sml29623 else 60743859Sml29623 return (NXGE_OK); 60753859Sml29623 } 60763859Sml29623 60773859Sml29623 nxge_status_t 60783859Sml29623 nxge_10g_link_led_off(p_nxge_t nxgep) 60793859Sml29623 { 60803859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 60814732Sdavemq != NPI_SUCCESS) 60823859Sml29623 return (NXGE_ERROR); 60833859Sml29623 else 60843859Sml29623 return (NXGE_OK); 60853859Sml29623 } 60864185Sspeer 60875572Ssbehera static boolean_t 60885572Ssbehera nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask) 60895572Ssbehera { 60905572Ssbehera uint32_t pma_pmd_id = 0; 60915572Ssbehera uint32_t pcs_id = 0; 60925572Ssbehera uint32_t phy_id = 0; 60935572Ssbehera 60945572Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr); 60955572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60965572Ssbehera "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id)); 60975572Ssbehera if ((pma_pmd_id & mask) == (id & mask)) 60985572Ssbehera goto found_phy; 60995572Ssbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, addr); 61005572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61015572Ssbehera "nxge_is_phy_present: pcs_id[0x%x]", pcs_id)); 61025572Ssbehera if ((pcs_id & mask) == (id & mask)) 61035572Ssbehera goto found_phy; 61045572Ssbehera phy_id = nxge_get_cl22_phy_id(nxgep, addr); 61055572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61065572Ssbehera "nxge_is_phy_present: phy_id[0x%x]", phy_id)); 61075572Ssbehera if ((phy_id & mask) == (id & mask)) 61085572Ssbehera goto found_phy; 61095572Ssbehera 61105572Ssbehera return (B_FALSE); 61115572Ssbehera 61125572Ssbehera found_phy: 61135572Ssbehera return (B_TRUE); 61145572Ssbehera } 61155572Ssbehera 61164732Sdavemq /* Check if the given id read using the given MDIO Clause is supported */ 61174732Sdavemq 61184732Sdavemq static boolean_t 61194732Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type) 61204732Sdavemq { 61214732Sdavemq int i; 61224732Sdavemq boolean_t found = B_FALSE; 61234732Sdavemq 61244732Sdavemq switch (type) { 61254732Sdavemq case CLAUSE_45_TYPE: 61266835Syc148097 for (i = 0; i < NUM_CLAUSE_45_IDS; i++) { 61276835Syc148097 if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) == 61286835Syc148097 (id & BCM_PHY_ID_MASK)) || 61296835Syc148097 (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK))) { 61304732Sdavemq found = B_TRUE; 61314732Sdavemq break; 61324732Sdavemq } 61334732Sdavemq } 61344732Sdavemq break; 61354732Sdavemq case CLAUSE_22_TYPE: 61366835Syc148097 for (i = 0; i < NUM_CLAUSE_22_IDS; i++) { 61374782Ssbehera if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) == 61384782Ssbehera (id & BCM_PHY_ID_MASK)) { 61394732Sdavemq found = B_TRUE; 61404732Sdavemq break; 61414732Sdavemq } 61424732Sdavemq } 61434732Sdavemq break; 61444732Sdavemq default: 61454732Sdavemq break; 61464732Sdavemq } 61474732Sdavemq 61484732Sdavemq return (found); 61494732Sdavemq } 61504732Sdavemq 61514977Sraghus static uint32_t 61524977Sraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port) 61534977Sraghus { 61544977Sraghus uint16_t val1 = 0; 61554977Sraghus uint16_t val2 = 0; 61564977Sraghus uint32_t pma_pmd_dev_id = 0; 61574977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 61584977Sraghus 61595780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 61604977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 61614977Sraghus NXGE_DEV_ID_REG_1, &val1); 61624977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 61634977Sraghus NXGE_DEV_ID_REG_2, &val2); 61645780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 61654977Sraghus 61666835Syc148097 /* Concatenate the Device ID stored in two registers. */ 61674977Sraghus pma_pmd_dev_id = val1; 61684977Sraghus pma_pmd_dev_id = (pma_pmd_dev_id << 16); 61694977Sraghus pma_pmd_dev_id |= val2; 61704977Sraghus 61714977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 61724977Sraghus "devid[0x%llx]", phy_port, pma_pmd_dev_id)); 61734977Sraghus 61744977Sraghus return (pma_pmd_dev_id); 61754977Sraghus } 61764977Sraghus 61774977Sraghus static uint32_t 61784977Sraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port) 61794977Sraghus { 61804977Sraghus uint16_t val1 = 0; 61814977Sraghus uint16_t val2 = 0; 61824977Sraghus uint32_t pcs_dev_id = 0; 61834977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 61844977Sraghus 61855780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 61864977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 61874977Sraghus NXGE_DEV_ID_REG_1, &val1); 61884977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 61894977Sraghus NXGE_DEV_ID_REG_2, &val2); 61905780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 61914977Sraghus 61924977Sraghus pcs_dev_id = val1; 61934977Sraghus pcs_dev_id = (pcs_dev_id << 16); 61944977Sraghus pcs_dev_id |= val2; 61954977Sraghus 61964977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 61974977Sraghus "devid[0x%llx]", phy_port, pcs_dev_id)); 61984977Sraghus 61994977Sraghus return (pcs_dev_id); 62004977Sraghus } 62014977Sraghus 62024977Sraghus static uint32_t 62034977Sraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port) 62044977Sraghus { 62054977Sraghus uint16_t val1 = 0; 62064977Sraghus uint16_t val2 = 0; 62074977Sraghus uint32_t phy_id = 0; 62084977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 62094977Sraghus npi_status_t npi_status = NPI_SUCCESS; 62104977Sraghus 62116075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 62124977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1, 62134977Sraghus &val1); 62144977Sraghus if (npi_status != NPI_SUCCESS) { 62154977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 62164977Sraghus "clause 22 read to reg 2 failed!!!")); 62174977Sraghus goto exit; 62184977Sraghus } 62194977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2, 62204977Sraghus &val2); 62214977Sraghus if (npi_status != 0) { 62224977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 62234977Sraghus "clause 22 read to reg 3 failed!!!")); 62244977Sraghus goto exit; 62254977Sraghus } 62264977Sraghus phy_id = val1; 62274977Sraghus phy_id = (phy_id << 16); 62284977Sraghus phy_id |= val2; 62294977Sraghus 62304977Sraghus exit: 62316075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 62324977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]", 62334977Sraghus phy_port, phy_id)); 62344977Sraghus 62354977Sraghus return (phy_id); 62364977Sraghus } 62374977Sraghus 62384732Sdavemq /* 62394732Sdavemq * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 62404732Sdavemq * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 62414732Sdavemq * read. Then use the values obtained to determine the phy type of each port 62424732Sdavemq * and the Neptune type. 62436835Syc148097 * 62446835Syc148097 * This function sets hw_p->xcvr_addr[i] for future MDIO access and set 62456835Syc148097 * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode 62466835Syc148097 * in case the portmode information is not available via OBP, nxge.conf, 62476835Syc148097 * VPD or SEEPROM. 62484732Sdavemq */ 62494732Sdavemq nxge_status_t 62504732Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 62514732Sdavemq { 62526261Sjoycey int i, j, l; 62534732Sdavemq uint32_t pma_pmd_dev_id = 0; 62544732Sdavemq uint32_t pcs_dev_id = 0; 62554732Sdavemq uint32_t phy_id = 0; 62564782Ssbehera uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE]; 62574782Ssbehera uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE]; 62584782Ssbehera uint32_t port_phy_id[NXGE_PORTS_NEPTUNE]; 62594732Sdavemq uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 62604732Sdavemq uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 62615572Ssbehera uint8_t phy_fd_arr[NXGE_MAX_PHY_PORTS]; 62625572Ssbehera uint8_t port_fd_arr[NXGE_MAX_PHY_PORTS]; 62634732Sdavemq uint8_t total_port_fd, total_phy_fd; 62646835Syc148097 uint8_t num_xaui; 62654732Sdavemq nxge_status_t status = NXGE_OK; 62664732Sdavemq 62674732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 62684732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 62694732Sdavemq "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 62704732Sdavemq nxgep->niu_type)); 62714732Sdavemq 62726495Sspeer if (isLDOMguest(nxgep)) { 62736495Sspeer hw_p->niu_type = NIU_TYPE_NONE; 62746495Sspeer hw_p->platform_type = P_NEPTUNE_NONE; 62756495Sspeer return (NXGE_OK); 62766495Sspeer } 62776495Sspeer 62786261Sjoycey j = l = 0; 62794732Sdavemq total_port_fd = total_phy_fd = 0; 62804732Sdavemq /* 62817801SSantwona.Behera@Sun.COM * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved 62827801SSantwona.Behera@Sun.COM * for on chip serdes usages. "i" in the following for loop starts at 6. 62834732Sdavemq */ 62844732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 62854977Sraghus 62864977Sraghus pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i); 62874732Sdavemq 62884732Sdavemq if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 62894732Sdavemq pma_pmd_dev_fd[i] = 1; 62904732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 62916604Ssbehera "PMA/PMD dev %x found", i, pma_pmd_dev_id)); 62924782Ssbehera if (j < NXGE_PORTS_NEPTUNE) { 62936835Syc148097 if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK) 62946835Syc148097 == TN1010_DEV_ID) { 62956835Syc148097 port_pma_pmd_dev_id[j] = TN1010_DEV_ID; 62966835Syc148097 } else { 62976835Syc148097 port_pma_pmd_dev_id[j] = 62986929Smisaki pma_pmd_dev_id & BCM_PHY_ID_MASK; 62996835Syc148097 } 63005572Ssbehera port_fd_arr[j] = (uint8_t)i; 63014732Sdavemq j++; 63024732Sdavemq } 63034732Sdavemq } else { 63044732Sdavemq pma_pmd_dev_fd[i] = 0; 63054732Sdavemq } 63064732Sdavemq 63074977Sraghus pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i); 63084732Sdavemq 63094732Sdavemq if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 63104732Sdavemq pcs_dev_fd[i] = 1; 63114732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 63126604Ssbehera "dev %x found", i, pcs_dev_id)); 63136261Sjoycey if (pma_pmd_dev_fd[i] == 1) { 63146835Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK) 63156835Syc148097 == TN1010_DEV_ID) { 63166835Syc148097 port_pcs_dev_id[j - 1] = 63176835Syc148097 TN1010_DEV_ID; 63186835Syc148097 } else { 63196835Syc148097 port_pcs_dev_id[j - 1] = 63206835Syc148097 pcs_dev_id & 63216835Syc148097 BCM_PHY_ID_MASK; 63226835Syc148097 } 63236261Sjoycey } else { 63246261Sjoycey if (j < NXGE_PORTS_NEPTUNE) { 63256835Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK) 63266929Smisaki == TN1010_DEV_ID) { 63276835Syc148097 port_pcs_dev_id[j] = 63286835Syc148097 TN1010_DEV_ID; 63296835Syc148097 } else { 63306835Syc148097 port_pcs_dev_id[j] = 63316835Syc148097 pcs_dev_id & 63326835Syc148097 BCM_PHY_ID_MASK; 63336835Syc148097 } 63346261Sjoycey port_fd_arr[j] = (uint8_t)i; 63356261Sjoycey j++; 63366261Sjoycey } 63374732Sdavemq } 63384732Sdavemq } else { 63394732Sdavemq pcs_dev_fd[i] = 0; 63404732Sdavemq } 63414732Sdavemq 63425572Ssbehera if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) { 63435572Ssbehera total_port_fd ++; 63445572Ssbehera } 63454732Sdavemq 63464977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, i); 63474732Sdavemq if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 63485572Ssbehera total_phy_fd ++; 63494732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 63506604Ssbehera "%x found", i, phy_id)); 63514782Ssbehera if (l < NXGE_PORTS_NEPTUNE) { 63526835Syc148097 if ((phy_id & TN1010_DEV_ID_MASK) 63536835Syc148097 == TN1010_DEV_ID) { 63546835Syc148097 port_phy_id[l] = TN1010_DEV_ID; 63556835Syc148097 } else { 63566835Syc148097 port_phy_id[l] 63576835Syc148097 = phy_id & BCM_PHY_ID_MASK; 63586835Syc148097 } 63595572Ssbehera phy_fd_arr[l] = (uint8_t)i; 63604732Sdavemq l++; 63614732Sdavemq } 63624732Sdavemq } 63634732Sdavemq } 63644732Sdavemq 63654732Sdavemq switch (total_port_fd) { 63664732Sdavemq case 2: 63674732Sdavemq switch (total_phy_fd) { 63684732Sdavemq case 2: 63697801SSantwona.Behera@Sun.COM /* 2 10G, 2 1G RGMII Fiber / copper */ 63706261Sjoycey if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 63716261Sjoycey (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 63726261Sjoycey ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 63736261Sjoycey (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) && 63746261Sjoycey ((port_phy_id[0] == PHY_BCM5482_FAMILY) && 63756261Sjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY))) { 63766261Sjoycey 63777801SSantwona.Behera@Sun.COM switch (hw_p->platform_type) { 63787801SSantwona.Behera@Sun.COM case P_NEPTUNE_ROCK: 63797801SSantwona.Behera@Sun.COM hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 63807801SSantwona.Behera@Sun.COM /* 63817801SSantwona.Behera@Sun.COM * ROCK platform has assigned a lower 63827801SSantwona.Behera@Sun.COM * addr to port 1. (port 0 = 0x9 and 63837801SSantwona.Behera@Sun.COM * port 1 = 0x8). 63847801SSantwona.Behera@Sun.COM */ 63857801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[0]; 63867801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[1]; 63877801SSantwona.Behera@Sun.COM 63887801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, 63897801SSantwona.Behera@Sun.COM "Rock with 2 10G, 2 1GC")); 63907801SSantwona.Behera@Sun.COM break; 63917801SSantwona.Behera@Sun.COM 63927801SSantwona.Behera@Sun.COM case P_NEPTUNE_NONE: 63937801SSantwona.Behera@Sun.COM default: 63947801SSantwona.Behera@Sun.COM hw_p->platform_type = 63957801SSantwona.Behera@Sun.COM P_NEPTUNE_GENERIC; 63967801SSantwona.Behera@Sun.COM hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF; 63977801SSantwona.Behera@Sun.COM 63987801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[0]; 63997801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[1]; 64007801SSantwona.Behera@Sun.COM 64017801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, 64027801SSantwona.Behera@Sun.COM "ARTM card with 2 10G, 2 1GF")); 64037801SSantwona.Behera@Sun.COM break; 64047801SSantwona.Behera@Sun.COM } 64057801SSantwona.Behera@Sun.COM 64066261Sjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0]; 64076261Sjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1]; 64086261Sjoycey 64096261Sjoycey } else { 64106261Sjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 64116261Sjoycey "Unsupported neptune type 1")); 64126261Sjoycey goto error_exit; 64136261Sjoycey } 64146261Sjoycey break; 64156261Sjoycey 64164732Sdavemq case 1: 64174732Sdavemq /* TODO - 2 10G, 1 1G */ 64184732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 64194732Sdavemq "Unsupported neptune type 2 10G, 1 1G")); 64204732Sdavemq goto error_exit; 64214732Sdavemq case 0: 64226835Syc148097 /* 64236835Syc148097 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI 64246835Syc148097 * cards, etc. 64256835Syc148097 */ 64264782Ssbehera if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 64274782Ssbehera (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 64284782Ssbehera ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 64296604Ssbehera (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) || 64306604Ssbehera ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) && 64316604Ssbehera (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) || 64326604Ssbehera ((port_pma_pmd_dev_id[0] == 64336604Ssbehera MARVELL_88X201X_PHY_ID) && 64346604Ssbehera (port_pma_pmd_dev_id[1] == 64356604Ssbehera MARVELL_88X201X_PHY_ID))) { 64364977Sraghus 64374977Sraghus /* 64384977Sraghus * Check the first phy port address against 64394977Sraghus * the known phy start addresses to determine 64404977Sraghus * the platform type. 64414977Sraghus */ 64425572Ssbehera 64435572Ssbehera switch (port_fd_arr[0]) { 64446835Syc148097 case NEPTUNE_CLAUSE45_PORT_ADDR_BASE: 64456604Ssbehera /* 64466604Ssbehera * The Marvell case also falls into 64476604Ssbehera * this case as 64486604Ssbehera * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE 64496835Syc148097 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE. 64506604Ssbehera * This is OK for the 2 10G case. 64516604Ssbehera */ 64524977Sraghus hw_p->niu_type = NEPTUNE_2_10GF; 64534977Sraghus hw_p->platform_type = 64544977Sraghus P_NEPTUNE_ATLAS_2PORT; 64555572Ssbehera break; 64566835Syc148097 case GOA_CLAUSE45_PORT_ADDR_BASE: 64575572Ssbehera if (hw_p->platform_type != 64585572Ssbehera P_NEPTUNE_NIU) { 64595572Ssbehera hw_p->platform_type = 64605572Ssbehera P_NEPTUNE_GENERIC; 64615572Ssbehera hw_p->niu_type = 64625572Ssbehera NEPTUNE_2_10GF; 64635572Ssbehera } 64645572Ssbehera break; 64655572Ssbehera default: 64665572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 64674977Sraghus "Unsupported neptune type 2 - 1")); 64684977Sraghus goto error_exit; 64694977Sraghus } 64705572Ssbehera 64715572Ssbehera for (i = 0; i < 2; i++) { 64725572Ssbehera hw_p->xcvr_addr[i] = port_fd_arr[i]; 64735572Ssbehera } 64746835Syc148097 64756835Syc148097 /* Both XAUI slots have copper XAUI cards */ 64766835Syc148097 } else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 64776835Syc148097 == TN1010_DEV_ID) && 64786835Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 64796835Syc148097 == TN1010_DEV_ID)) || 64806835Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 64816835Syc148097 == TN1010_DEV_ID) && 64826835Syc148097 ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) 64836835Syc148097 == TN1010_DEV_ID))) { 64846835Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010; 64856835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 64866835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 64876835Syc148097 64886835Syc148097 /* Slot0 has fiber XAUI, slot1 has copper XAUI */ 64896835Syc148097 } else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 64906835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 64916835Syc148097 == TN1010_DEV_ID) || 64926835Syc148097 (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY && 64936835Syc148097 (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) == 64946835Syc148097 TN1010_DEV_ID)) { 64956835Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010; 64966835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 64976835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 64986835Syc148097 64996835Syc148097 /* Slot0 has copper XAUI, slot1 has fiber XAUI */ 65006835Syc148097 } else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY && 65016835Syc148097 (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 65026835Syc148097 == TN1010_DEV_ID) || 65036835Syc148097 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY && 65046835Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 65056835Syc148097 == TN1010_DEV_ID)) { 65066835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF; 65076835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 65086835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 65096835Syc148097 65104732Sdavemq } else { 65114732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 65124732Sdavemq "Unsupported neptune type 2")); 65134732Sdavemq goto error_exit; 65144732Sdavemq } 65154732Sdavemq break; 65166835Syc148097 65174732Sdavemq case 4: 65186835Syc148097 if (nxge_get_num_of_xaui( 65196835Syc148097 port_pma_pmd_dev_id, port_pcs_dev_id, 65206835Syc148097 port_phy_id, &num_xaui) == NXGE_ERROR) { 65216835Syc148097 goto error_exit; 65226835Syc148097 } 65236835Syc148097 if (num_xaui != 2) 65246835Syc148097 goto error_exit; 65256835Syc148097 65266835Syc148097 /* 65276835Syc148097 * Maramba with 2 XAUIs (either fiber or copper) 65286835Syc148097 * 65296835Syc148097 * Check the first phy port address against 65306835Syc148097 * the known phy start addresses to determine 65316835Syc148097 * the platform type. 65326835Syc148097 */ 65336835Syc148097 switch (phy_fd_arr[0]) { 65346835Syc148097 case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE: 65356835Syc148097 hw_p->platform_type = 65366835Syc148097 P_NEPTUNE_MARAMBA_P0; 65376835Syc148097 break; 65386835Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 65396835Syc148097 hw_p->platform_type = 65406835Syc148097 P_NEPTUNE_MARAMBA_P1; 65416835Syc148097 break; 65426835Syc148097 default: 65436835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 65446835Syc148097 "Unknown port %d...Cannot " 65456835Syc148097 "determine platform type", i)); 65466835Syc148097 goto error_exit; 65476835Syc148097 } 65486835Syc148097 65496835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 65506835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 65516835Syc148097 hw_p->xcvr_addr[2] = phy_fd_arr[2]; 65526835Syc148097 hw_p->xcvr_addr[3] = phy_fd_arr[3]; 65536835Syc148097 65546835Syc148097 /* slot0 has fiber XAUI, slot1 has Cu XAUI */ 65556835Syc148097 if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 65566835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 65576835Syc148097 == TN1010_DEV_ID) { 65586835Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC; 65596835Syc148097 65606835Syc148097 /* slot0 has Cu XAUI, slot1 has fiber XAUI */ 65616835Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 65626835Syc148097 == TN1010_DEV_ID) && 65636835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) { 65646835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC; 65656835Syc148097 65666835Syc148097 /* Both slots have fiber XAUI */ 65676835Syc148097 } else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 65686835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) { 65694977Sraghus hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 65704977Sraghus 65716835Syc148097 /* Both slots have copper XAUI */ 65726835Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 65736835Syc148097 == TN1010_DEV_ID) && 65746835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 65756835Syc148097 == TN1010_DEV_ID) { 65766835Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC; 65776835Syc148097 65784732Sdavemq } else { 65794732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 65804732Sdavemq "Unsupported neptune type 3")); 65814732Sdavemq goto error_exit; 65824732Sdavemq } 65834732Sdavemq break; 65844732Sdavemq default: 65854732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 65864732Sdavemq "Unsupported neptune type 5")); 65874732Sdavemq goto error_exit; 65884732Sdavemq } 65894782Ssbehera break; 65906835Syc148097 case 1: /* Only one clause45 port */ 65916835Syc148097 switch (total_phy_fd) { /* Number of clause22 ports */ 65924732Sdavemq case 3: 65934977Sraghus /* 65944977Sraghus * TODO 3 1G, 1 10G mode. 65954977Sraghus * Differentiate between 1_1G_1_10G_2_1G and 65964977Sraghus * 1_10G_3_1G 65974977Sraghus */ 65984977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 65994977Sraghus "Unsupported neptune type 7")); 66004977Sraghus goto error_exit; 66014732Sdavemq case 2: 66024732Sdavemq /* 66034732Sdavemq * TODO 2 1G, 1 10G mode. 66044732Sdavemq * Differentiate between 1_1G_1_10G_1_1G and 66054732Sdavemq * 1_10G_2_1G 66064732Sdavemq */ 66074732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66084732Sdavemq "Unsupported neptune type 8")); 66094732Sdavemq goto error_exit; 66104732Sdavemq case 1: 66114732Sdavemq /* 66124732Sdavemq * TODO 1 1G, 1 10G mode. 66134732Sdavemq * Differentiate between 1_1G_1_10G and 66144732Sdavemq * 1_10G_1_1G 66154732Sdavemq */ 66164732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66174732Sdavemq "Unsupported neptune type 9")); 66184732Sdavemq goto error_exit; 66196835Syc148097 case 0: /* N2 with 1 XAUI (fiber or copper) */ 66206835Syc148097 /* Fiber XAUI */ 66215572Ssbehera if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY || 66225572Ssbehera port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) { 66235572Ssbehera 66245572Ssbehera /* 66255572Ssbehera * Check the first phy port address against 66265572Ssbehera * the known phy start addresses to determine 66275572Ssbehera * the platform type. 66285572Ssbehera */ 66295572Ssbehera 66305572Ssbehera switch (port_fd_arr[0]) { 66316835Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE: 66326835Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1): 66336835Syc148097 case ALT_GOA_CLAUSE45_PORT1_ADDR: 66346835Syc148097 /* 66356835Syc148097 * If hw_p->platform_type == 66366835Syc148097 * P_NEPTUNE_NIU, then portmode 66376835Syc148097 * is already known, so there is 66386835Syc148097 * no need to figure out hw_p-> 66396835Syc148097 * platform_type because 66406835Syc148097 * platform_type is only for 66416835Syc148097 * figuring out portmode. 66426835Syc148097 */ 66435572Ssbehera if (hw_p->platform_type != 66445572Ssbehera P_NEPTUNE_NIU) { 66455572Ssbehera hw_p->platform_type = 66465572Ssbehera P_NEPTUNE_GENERIC; 66475572Ssbehera hw_p->niu_type = 66485572Ssbehera NEPTUNE_2_10GF; 66495572Ssbehera } 66505572Ssbehera break; 66515572Ssbehera default: 66525572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 66535572Ssbehera "Unsupported neptune type 10")); 66545572Ssbehera goto error_exit; 66555572Ssbehera } 66566075Ssbehera /* 66576075Ssbehera * For GOA, which is a hot swappable PHY, the 66586075Ssbehera * phy address to function number mapping 66596075Ssbehera * should be preserved, i.e., addr 16 is 66606075Ssbehera * assigned to function 0 and 20 to function 1 66616075Ssbehera * But for Huron XAUI, the assignment should 66626075Ssbehera * be by function number, i.e., whichever 66636075Ssbehera * function number attaches should be 66646075Ssbehera * assigned the available PHY (this is required 66656075Ssbehera * primarily to support pre-production Huron 66666075Ssbehera * boards where function 0 is mapped to addr 17 66676075Ssbehera */ 66686075Ssbehera if (port_fd_arr[0] == 66696835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR) { 66706075Ssbehera hw_p->xcvr_addr[1] = port_fd_arr[0]; 66716075Ssbehera } else { 66726075Ssbehera hw_p->xcvr_addr[nxgep->function_num] = 66736075Ssbehera port_fd_arr[0]; 66746075Ssbehera } 66756835Syc148097 66766835Syc148097 /* A 10G copper XAUI in either slot0 or slot1 */ 66776835Syc148097 } else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 66786835Syc148097 == TN1010_DEV_ID || 66796835Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 66806835Syc148097 == TN1010_DEV_ID) { 66816835Syc148097 switch (port_fd_arr[0]) { 66826835Syc148097 /* The XAUI is in slot0 */ 66836835Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE: 66846835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010; 66856835Syc148097 break; 66866835Syc148097 66876835Syc148097 /* The XAUI is in slot1 */ 66886835Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1): 66896835Syc148097 hw_p->niu_type 66906835Syc148097 = NEPTUNE_1_NONE_1_TN1010; 66916835Syc148097 break; 66926835Syc148097 default: 66936835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 66946835Syc148097 "Unsupported XAUI port address")); 66956835Syc148097 goto error_exit; 66966835Syc148097 } 66976835Syc148097 hw_p->xcvr_addr[nxgep->function_num] 66986835Syc148097 = port_fd_arr[0]; 66996835Syc148097 67005572Ssbehera } else { 67015572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67026835Syc148097 "Unsupported PHY type")); 67035572Ssbehera goto error_exit; 67045572Ssbehera } 67055572Ssbehera break; 67066835Syc148097 case 4: /* Maramba always have 4 clause 45 ports */ 67076835Syc148097 67084732Sdavemq /* Maramba with 1 XAUI */ 67096929Smisaki if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) && 67106929Smisaki (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) && 67116835Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 67126929Smisaki != TN1010_DEV_ID) && 67136835Syc148097 ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 67146929Smisaki != TN1010_DEV_ID)) { 67154732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67164732Sdavemq "Unsupported neptune type 12")); 67174732Sdavemq goto error_exit; 67184732Sdavemq } 67196929Smisaki 67206929Smisaki /* 67216929Smisaki * Check the first phy port address against 67226929Smisaki * the known phy start addresses to determine 67236929Smisaki * the platform type. 67246929Smisaki */ 67256929Smisaki switch (phy_fd_arr[0]) { 67266929Smisaki case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE: 67276929Smisaki hw_p->platform_type = 67286929Smisaki P_NEPTUNE_MARAMBA_P0; 67296929Smisaki break; 67306929Smisaki case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 67316929Smisaki hw_p->platform_type = 67326929Smisaki P_NEPTUNE_MARAMBA_P1; 67336929Smisaki break; 67346929Smisaki default: 67356929Smisaki NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 67366929Smisaki "Unknown port %d...Cannot " 67376929Smisaki "determine platform type 10 - 2", 67386929Smisaki i)); 67396929Smisaki goto error_exit; 67406929Smisaki } 67416929Smisaki 67426929Smisaki /* 67436929Smisaki * Check the clause45 address to determine 67446929Smisaki * if XAUI is in port 0 or port 1. 67456929Smisaki */ 67466929Smisaki switch (port_fd_arr[0]) { 67476929Smisaki case MARAMBA_CLAUSE45_PORT_ADDR_BASE: 67486929Smisaki if (port_pcs_dev_id[0] 67496929Smisaki == PHY_BCM8704_FAMILY || 67506929Smisaki port_pma_pmd_dev_id[0] 67516929Smisaki == PHY_BCM8704_FAMILY) { 67526929Smisaki hw_p->niu_type 67536929Smisaki = NEPTUNE_1_10GF_3_1GC; 67546929Smisaki } else { 67556929Smisaki hw_p->niu_type 67566929Smisaki = NEPTUNE_1_TN1010_3_1GC; 67576929Smisaki } 67586929Smisaki hw_p->xcvr_addr[0] = port_fd_arr[0]; 67596929Smisaki for (i = 1; i < NXGE_MAX_PORTS; i++) { 67606929Smisaki hw_p->xcvr_addr[i] = 67616929Smisaki phy_fd_arr[i]; 67626929Smisaki } 67636929Smisaki break; 67646929Smisaki case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1): 67656929Smisaki if (port_pcs_dev_id[0] 67666929Smisaki == PHY_BCM8704_FAMILY || 67676929Smisaki port_pma_pmd_dev_id[0] 67686929Smisaki == PHY_BCM8704_FAMILY) { 67696929Smisaki hw_p->niu_type = 67706929Smisaki NEPTUNE_1_1GC_1_10GF_2_1GC; 67716929Smisaki } else { 67726929Smisaki hw_p->niu_type = 67736929Smisaki NEPTUNE_1_1GC_1_TN1010_2_1GC; 67746929Smisaki } 67756929Smisaki hw_p->xcvr_addr[0] = phy_fd_arr[0]; 67766929Smisaki hw_p->xcvr_addr[1] = port_fd_arr[0]; 67776929Smisaki hw_p->xcvr_addr[2] = phy_fd_arr[2]; 67786929Smisaki hw_p->xcvr_addr[3] = phy_fd_arr[3]; 67796929Smisaki break; 67806929Smisaki default: 67816929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67826929Smisaki "Unsupported neptune type 11")); 67836929Smisaki goto error_exit; 67846929Smisaki } 67856929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67866929Smisaki "Maramba with 1 XAUI (fiber or copper)")); 67874732Sdavemq break; 67884732Sdavemq default: 67894732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67904732Sdavemq "Unsupported neptune type 13")); 67914732Sdavemq goto error_exit; 67924732Sdavemq } 67934732Sdavemq break; 67946835Syc148097 case 0: /* 4 ports Neptune based NIC */ 67954732Sdavemq switch (total_phy_fd) { 67964732Sdavemq case 4: 67974782Ssbehera if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 67984782Ssbehera (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 67994782Ssbehera (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 68004782Ssbehera (port_phy_id[3] == PHY_BCM5464R_FAMILY)) { 68014732Sdavemq 68024732Sdavemq /* 68034732Sdavemq * Check the first phy port address against 68044732Sdavemq * the known phy start addresses to determine 68054732Sdavemq * the platform type. 68064732Sdavemq */ 68075572Ssbehera switch (phy_fd_arr[0]) { 68086835Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 68094732Sdavemq hw_p->platform_type = 68104732Sdavemq P_NEPTUNE_MARAMBA_P1; 68115572Ssbehera break; 68126835Syc148097 case NEPTUNE_CLAUSE22_PORT_ADDR_BASE: 68134977Sraghus hw_p->platform_type = 68144977Sraghus P_NEPTUNE_ATLAS_4PORT; 68155572Ssbehera break; 68165572Ssbehera default: 68174977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 68184977Sraghus "Unknown port %d...Cannot " 68194977Sraghus "determine platform type", i)); 68204977Sraghus goto error_exit; 68214732Sdavemq } 68224977Sraghus hw_p->niu_type = NEPTUNE_4_1GC; 68235572Ssbehera for (i = 0; i < NXGE_MAX_PORTS; i++) { 68245572Ssbehera hw_p->xcvr_addr[i] = phy_fd_arr[i]; 68255572Ssbehera } 68264732Sdavemq } else { 68274732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68284732Sdavemq "Unsupported neptune type 14")); 68294732Sdavemq goto error_exit; 68304732Sdavemq } 68314732Sdavemq break; 68324732Sdavemq case 3: 68334732Sdavemq /* TODO 3 1G mode */ 68344732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68354732Sdavemq "Unsupported neptune type 15")); 68364732Sdavemq goto error_exit; 68374732Sdavemq case 2: 68384732Sdavemq /* TODO 2 1G mode */ 68396261Sjoycey if ((port_phy_id[0] == PHY_BCM5482_FAMILY) && 68406261Sjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY)) { 68416261Sjoycey hw_p->platform_type = P_NEPTUNE_GENERIC; 68426261Sjoycey hw_p->niu_type = NEPTUNE_2_1GRF; 68436261Sjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0]; 68446261Sjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1]; 68456261Sjoycey } else { 68466261Sjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 68476261Sjoycey "Unsupported neptune type 16")); 68486261Sjoycey goto error_exit; 68496261Sjoycey } 68504732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68516261Sjoycey "2 RGMII Fiber ports - RTM")); 68526261Sjoycey break; 68536261Sjoycey 68544732Sdavemq case 1: 68554732Sdavemq /* TODO 1 1G mode */ 68564732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68574732Sdavemq "Unsupported neptune type 17")); 68584732Sdavemq goto error_exit; 68594732Sdavemq default: 68604732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68614732Sdavemq "Unsupported neptune type 18, total phy fd %d", 68624732Sdavemq total_phy_fd)); 68634732Sdavemq goto error_exit; 68644732Sdavemq } 68654732Sdavemq break; 68664732Sdavemq default: 68674732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68684732Sdavemq "Unsupported neptune type 19")); 68694732Sdavemq goto error_exit; 68704732Sdavemq } 68714732Sdavemq 68724732Sdavemq scan_exit: 68734732Sdavemq 68744732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 68754732Sdavemq "niu type [0x%x]\n", hw_p->niu_type)); 68764732Sdavemq return (status); 68774732Sdavemq 68784732Sdavemq error_exit: 68794732Sdavemq return (NXGE_ERROR); 68804732Sdavemq } 68814732Sdavemq 68824185Sspeer boolean_t 68834185Sspeer nxge_is_valid_local_mac(ether_addr_st mac_addr) 68844185Sspeer { 68854185Sspeer if ((mac_addr.ether_addr_octet[0] & 0x01) || 68864185Sspeer (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 68874185Sspeer (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 68884185Sspeer return (B_FALSE); 68894185Sspeer else 68904185Sspeer return (B_TRUE); 68914185Sspeer } 68924732Sdavemq 68934732Sdavemq static void 68944732Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 68954732Sdavemq 68964732Sdavemq npi_status_t rs = NPI_SUCCESS; 68974732Sdavemq uint8_t xcvr_portn; 68984732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 68994732Sdavemq 69004732Sdavemq NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 69014732Sdavemq 69024732Sdavemq if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 69036835Syc148097 xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE; 69044732Sdavemq } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 69056835Syc148097 xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE; 69064732Sdavemq } 69074732Sdavemq /* 69084732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 69094732Sdavemq * swapped with ethernet port number. This is 69104732Sdavemq * designed for better signal integrity in routing. 69114732Sdavemq */ 69124732Sdavemq switch (portn) { 69134732Sdavemq case 0: 69144732Sdavemq xcvr_portn += 3; 69154732Sdavemq break; 69164732Sdavemq case 1: 69174732Sdavemq xcvr_portn += 2; 69184732Sdavemq break; 69194732Sdavemq case 2: 69204732Sdavemq xcvr_portn += 1; 69214732Sdavemq break; 69224732Sdavemq case 3: 69234732Sdavemq default: 69244732Sdavemq break; 69254732Sdavemq } 69264732Sdavemq 69276075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 69284732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 69294732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb4ee); 69304732Sdavemq if (rs != NPI_SUCCESS) { 69314732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 69324732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 69334732Sdavemq "returned error 0x[%x]", rs)); 69346075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 69354732Sdavemq return; 69364732Sdavemq } 69374732Sdavemq 69384732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 69394732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb8ee); 69404732Sdavemq if (rs != NPI_SUCCESS) { 69414732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 69424732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 69434732Sdavemq "returned error 0x[%x]", rs)); 69444732Sdavemq } 69454732Sdavemq 69466075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 69474732Sdavemq } 69485196Ssbehera 69495196Ssbehera static nxge_status_t 69505196Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep) 69515196Ssbehera { 69525196Ssbehera p_nxge_stats_t statsp; 69535196Ssbehera uint8_t xcvr_portn; 69545196Ssbehera p_mii_regs_t mii_regs; 69555196Ssbehera mii_mode_control_stat_t mode; 69565196Ssbehera int status = NXGE_OK; 69575196Ssbehera 69585196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode")); 69595196Ssbehera 69605196Ssbehera statsp = nxgep->statsp; 69615196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 69625196Ssbehera mii_regs = NULL; 69635196Ssbehera mode.value = 0; 69645203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 69655196Ssbehera #if defined(__i386) 69665196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 69675196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 69685196Ssbehera mode.value)) != NXGE_OK) { 69695196Ssbehera goto fail; 69705196Ssbehera #else 69715196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 69725196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 69735196Ssbehera mode.value)) != NXGE_OK) { 69745196Ssbehera goto fail; 69755196Ssbehera #endif 69765196Ssbehera } 69775196Ssbehera #if defined(__i386) 69785196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 69795196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 69805196Ssbehera &mode.value)) != NXGE_OK) { 69815196Ssbehera goto fail; 69825196Ssbehera } 69835196Ssbehera #else 69845196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 69855196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 69865196Ssbehera &mode.value)) != NXGE_OK) { 69875196Ssbehera goto fail; 69885196Ssbehera } 69895196Ssbehera #endif 69905196Ssbehera 69915196Ssbehera if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) { 69925196Ssbehera nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 69935196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 69945196Ssbehera "nxge_mii_get_link_mode: fiber mode")); 69955196Ssbehera } 69965196Ssbehera 69975196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 69985196Ssbehera "nxge_mii_get_link_mode: " 69995196Ssbehera "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x", 70005203Ssbehera NXGE_MII_MODE_CONTROL_REG, xcvr_portn, 70015196Ssbehera mode.value, nxgep->mac.portmode)); 70025196Ssbehera 70035196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70045196Ssbehera "<== nxge_mii_get_link_mode")); 70055196Ssbehera return (status); 70065196Ssbehera fail: 70075196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 70085196Ssbehera "<== nxge_mii_get_link_mode (failed)")); 70095196Ssbehera return (NXGE_ERROR); 70105196Ssbehera } 70115196Ssbehera 70126439Sml29623 nxge_status_t 70136439Sml29623 nxge_mac_set_framesize(p_nxge_t nxgep) 70146439Sml29623 { 70156439Sml29623 npi_attr_t ap; 70166439Sml29623 uint8_t portn; 70176439Sml29623 npi_handle_t handle; 70186439Sml29623 npi_status_t rs = NPI_SUCCESS; 70196439Sml29623 70206439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize")); 70216439Sml29623 70226439Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 70236439Sml29623 handle = nxgep->npi_handle; 70246439Sml29623 70256439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70266439Sml29623 "==> nxge_mac_sec_framesize: port<%d> " 70276439Sml29623 "min framesize %d max framesize %d ", 70286439Sml29623 portn, 70296439Sml29623 nxgep->mac.minframesize, 70306439Sml29623 nxgep->mac.maxframesize)); 70316439Sml29623 70326439Sml29623 SET_MAC_ATTR2(handle, ap, portn, 70336439Sml29623 MAC_PORT_FRAME_SIZE, 70346439Sml29623 nxgep->mac.minframesize, 70356439Sml29623 nxgep->mac.maxframesize, 70366439Sml29623 rs); 70376439Sml29623 if (rs != NPI_SUCCESS) { 70386439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70396439Sml29623 "<== nxge_mac_set_framesize: failed to configure " 70406439Sml29623 "max/min frame size port %d", portn)); 70416439Sml29623 70426439Sml29623 return (NXGE_ERROR | rs); 70436439Sml29623 } 70446439Sml29623 70456439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70466439Sml29623 "<== nxge_mac_set_framesize: port<%d>", portn)); 70476439Sml29623 70486439Sml29623 return (NXGE_OK); 70496439Sml29623 } 70506439Sml29623 70516835Syc148097 static nxge_status_t 70526835Syc148097 nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id, 70536835Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui) 70546835Syc148097 { 70556835Syc148097 uint8_t i; 70566835Syc148097 70576835Syc148097 for (i = 0; i < 4; i++) { 70586835Syc148097 if (port_phy_id[i] != PHY_BCM5464R_FAMILY) 70596835Syc148097 return (NXGE_ERROR); 70606835Syc148097 } 70616835Syc148097 70626835Syc148097 *num_xaui = 0; 70636835Syc148097 if ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY && 70646835Syc148097 port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) || 70656835Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 70666835Syc148097 == TN1010_DEV_ID) && 70676835Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 70686835Syc148097 == TN1010_DEV_ID))) { 70696835Syc148097 (*num_xaui) ++; 70706835Syc148097 } 70716835Syc148097 if ((port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY && 70726835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) || 70736835Syc148097 (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) 70746835Syc148097 == TN1010_DEV_ID) && 70756835Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 70766835Syc148097 == TN1010_DEV_ID))) { 70776835Syc148097 (*num_xaui) ++; 70786835Syc148097 } 70796835Syc148097 return (NXGE_OK); 70806835Syc148097 } 70816835Syc148097 70826835Syc148097 /* 70836835Syc148097 * Instruction from Teranetics: Once you detect link is up, go 70846835Syc148097 * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You 70856835Syc148097 * may want to qualify it by first checking Register 30.1.7:6 and 70866835Syc148097 * making sure it reads "01" (Auto-Neg Complete). 70876835Syc148097 * 70886835Syc148097 * If this function is called when the link is down or before auto- 70896835Syc148097 * negotiation has completed, then the speed of the PHY is not certain. 70906835Syc148097 * In such cases, this function returns 1G as the default speed with 70916835Syc148097 * NXGE_OK status instead of NXGE_ERROR. It is OK to initialize the 70926835Syc148097 * driver based on a default speed because this function will be called 70936835Syc148097 * again when the link comes up. Returning NXGE_ERROR, which may 70946835Syc148097 * cause brutal chain reaction in caller functions, is not necessary. 70956835Syc148097 */ 70966835Syc148097 static nxge_status_t 70976835Syc148097 nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed) 70986835Syc148097 { 70996835Syc148097 uint8_t phy_port_addr, autoneg_stat, link_up; 71006835Syc148097 nxge_status_t status = NXGE_OK; 71016835Syc148097 uint16_t val; 71026835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 71036835Syc148097 71046835Syc148097 /* Set default speed to 10G */ 71056835Syc148097 *speed = TN1010_SPEED_10G; 71066835Syc148097 71076835Syc148097 /* Set Clause 45 */ 71086835Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 71096835Syc148097 71106835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 71116835Syc148097 71126835Syc148097 /* Check Device 1 Register 0xA bit0 for link up status */ 71136835Syc148097 status = nxge_mdio_read(nxgep, phy_port_addr, 71146835Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val); 71156835Syc148097 if (status != NXGE_OK) 71166835Syc148097 goto fail; 71176835Syc148097 71186835Syc148097 link_up = ((val & TN1010_AN_LINK_STAT_BIT) 71196835Syc148097 ? B_TRUE : B_FALSE); 71206835Syc148097 if (link_up == B_FALSE) { 71216835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 71226835Syc148097 "nxge_get_tn1010_speed: link is down")); 71236835Syc148097 goto nxge_get_tn1010_speed_exit; 71246835Syc148097 } 71256835Syc148097 71266835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 71276835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG, 71286835Syc148097 &val)) != NXGE_OK) { 71296835Syc148097 goto fail; 71306835Syc148097 } 71316835Syc148097 autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >> 71326835Syc148097 TN1010_VENDOR_MMD1_AN_STAT_SHIFT; 71336835Syc148097 71346835Syc148097 /* 71356835Syc148097 * Return NXGE_OK even when we can not get a settled speed. In 71366835Syc148097 * such case, the speed reported should not be trusted but that 71376835Syc148097 * is OK, we will call this function periodically and will get 71386835Syc148097 * the correct speed after the link is up. 71396835Syc148097 */ 71406835Syc148097 switch (autoneg_stat) { 71416835Syc148097 case TN1010_AN_IN_PROG: 71426835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 71436835Syc148097 "nxge_get_tn1010_speed: Auto-negotiation in progress")); 71446835Syc148097 break; 71456835Syc148097 case TN1010_AN_COMPLETE: 71466835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 71476835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 71486835Syc148097 TN1010_VENDOR_MMD1_STATUS_REG, 71496835Syc148097 &val)) != NXGE_OK) { 71506835Syc148097 goto fail; 71516835Syc148097 } 71526835Syc148097 *speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >> 71536835Syc148097 TN1010_VENDOR_MMD1_AN_SPEED_SHIFT; 71546835Syc148097 break; 71556835Syc148097 case TN1010_AN_RSVD: 71566835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 71576835Syc148097 "nxge_get_tn1010_speed: Autoneg status undefined")); 71586835Syc148097 break; 71596835Syc148097 case TN1010_AN_FAILED: 71606835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 71616835Syc148097 "nxge_get_tn1010_speed: Auto-negotiation failed")); 71626835Syc148097 break; 71636835Syc148097 default: 71646835Syc148097 break; 71656835Syc148097 } 71666835Syc148097 nxge_get_tn1010_speed_exit: 71676835Syc148097 return (NXGE_OK); 71686835Syc148097 fail: 71696835Syc148097 return (status); 71706835Syc148097 } 71716835Syc148097 71726835Syc148097 71736835Syc148097 /* 71746835Syc148097 * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function 71756835Syc148097 * figures out the speed of the PHY determined by the autonegotiation 71766835Syc148097 * process and sets the following 3 parameters, 71776835Syc148097 * nxgep->mac.portmode 71786835Syc148097 * nxgep->statsp->mac_stats.link_speed 71796835Syc148097 * nxgep->statsp->mac_stats.xcvr_inuse 71806835Syc148097 */ 71816835Syc148097 static nxge_status_t 71826835Syc148097 nxge_set_tn1010_param(p_nxge_t nxgep) 71836835Syc148097 { 71846835Syc148097 uint16_t speed; 71856835Syc148097 71866835Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) { 71876835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 71886835Syc148097 "nxge_set_tn1010_param: " 71896835Syc148097 "Failed to get TN1010 speed")); 71906835Syc148097 return (NXGE_ERROR); 71916835Syc148097 } 71926835Syc148097 if (speed == TN1010_SPEED_1G) { 71936835Syc148097 nxgep->mac.portmode = PORT_1G_TN1010; 71946835Syc148097 nxgep->statsp->mac_stats.link_speed = 1000; 71956835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 71966835Syc148097 } else { 71976835Syc148097 nxgep->mac.portmode = PORT_10G_TN1010; 71986835Syc148097 nxgep->statsp->mac_stats.link_speed = 10000; 71996835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 72006835Syc148097 } 72016835Syc148097 return (NXGE_OK); 72026835Syc148097 } 72036835Syc148097 72045196Ssbehera #ifdef NXGE_DEBUG 72055196Ssbehera static void 72065196Ssbehera nxge_mii_dump(p_nxge_t nxgep) 72075196Ssbehera { 72085196Ssbehera p_nxge_stats_t statsp; 72095196Ssbehera uint8_t xcvr_portn; 72105196Ssbehera p_mii_regs_t mii_regs; 72115196Ssbehera mii_bmcr_t bmcr; 72125196Ssbehera mii_bmsr_t bmsr; 72135196Ssbehera mii_idr1_t idr1; 72145196Ssbehera mii_idr2_t idr2; 72155196Ssbehera mii_mode_control_stat_t mode; 72166495Sspeer p_nxge_param_t param_arr; 72175196Ssbehera 72185196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump")); 72195196Ssbehera 72205196Ssbehera statsp = nxgep->statsp; 72215196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 72225196Ssbehera 72235196Ssbehera mii_regs = NULL; 72245196Ssbehera 72255196Ssbehera #if defined(__i386) 72265196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 72275196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value); 72285196Ssbehera #else 72295196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 72305196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value); 72315196Ssbehera #endif 72325196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72335196Ssbehera "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x", 72345196Ssbehera xcvr_portn, bmcr.value)); 72355196Ssbehera 72365196Ssbehera #if defined(__i386) 72375196Ssbehera (void) nxge_mii_read(nxgep, 72385196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72395196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value); 72405196Ssbehera #else 72415196Ssbehera (void) nxge_mii_read(nxgep, 72425196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72435196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value); 72445196Ssbehera #endif 72455196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72465196Ssbehera "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x", 72475196Ssbehera xcvr_portn, bmsr.value)); 72485196Ssbehera 72495196Ssbehera #if defined(__i386) 72505196Ssbehera (void) nxge_mii_read(nxgep, 72515196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72525196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value); 72535196Ssbehera #else 72545196Ssbehera (void) nxge_mii_read(nxgep, 72555196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72565196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value); 72575196Ssbehera #endif 72585196Ssbehera 72595196Ssbehera 72605196Ssbehera #if defined(__i386) 72615196Ssbehera (void) nxge_mii_read(nxgep, 72625196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72635196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value); 72645196Ssbehera #else 72655196Ssbehera (void) nxge_mii_read(nxgep, 72665196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72675196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value); 72685196Ssbehera #endif 72695196Ssbehera 72705196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72715196Ssbehera "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x", 72725196Ssbehera xcvr_portn, idr1.value)); 72735196Ssbehera 72745196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72755196Ssbehera "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x", 72765196Ssbehera xcvr_portn, idr2.value)); 72775196Ssbehera 72785196Ssbehera mode.value = 0; 72795203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 72805196Ssbehera 72815196Ssbehera #if defined(__i386) 72825196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 72835196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value); 72845196Ssbehera 72855196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 72865196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value); 72875196Ssbehera #else 72885196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 72895196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value); 72905196Ssbehera 72915196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 72925196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value); 72935196Ssbehera #endif 72945196Ssbehera 72955196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72965196Ssbehera "nxge_mii_dump: mode control xcvr 0x%x value 0x%x", 72975196Ssbehera xcvr_portn, mode.value)); 72985196Ssbehera } 72995196Ssbehera #endif 7300