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 /* 229232SMichael.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); 278*9599Stc99174@train uint32_t val; 279*9599Stc99174@train npi_status_t rs; 280*9599Stc99174@train 281*9599Stc99174@train /* For Opus NEM, skip xcvr checking if 10G Serdes link is up */ 282*9599Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES && 283*9599Stc99174@train nxgep->statsp->mac_stats.link_up) { 284*9599Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 285*9599Stc99174@train return (status); 286*9599Stc99174@train } 2874977Sraghus 2884977Sraghus nxgep->mac.portmode = 0; 2895572Ssbehera nxgep->xcvr_addr = 0; 2905572Ssbehera 2915572Ssbehera /* 2925572Ssbehera * First check for hot swappable phy property. 2935572Ssbehera */ 2945572Ssbehera if (nxgep->hot_swappable_phy == B_TRUE) { 2955572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 2965572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE; 2975572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable")); 2985572Ssbehera } else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 2995572Ssbehera DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 3005572Ssbehera "hot-swappable-phy") == 1) { 3015572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 3025572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE; 3035572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable")); 3045572Ssbehera } else if (nxgep->niu_type == N2_NIU && 3055572Ssbehera ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0, 3065572Ssbehera "hot-swappable-phy") == 1) { 3075572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 3085572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE; 3095572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable")); 3105572Ssbehera } 3115572Ssbehera 3125572Ssbehera /* 3135572Ssbehera * MDIO polling support for Monza RTM card, Goa NEM card 3145572Ssbehera */ 3155572Ssbehera if (nxgep->mac.portmode == PORT_HSP_MODE) { 3165572Ssbehera nxgep->hot_swappable_phy = B_TRUE; 3175572Ssbehera /* 3185572Ssbehera * If this is the 2nd NIU port, then check 2 addresses 3195572Ssbehera * to take care of the Goa NEM card. Port 1 can have addr 17 3205572Ssbehera * (in the eval board) or 20 (in the P0 board). 3215572Ssbehera */ 3225572Ssbehera if (portn == 1) { 3235572Ssbehera if (nxge_is_phy_present(nxgep, 3246835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR, BCM8706_DEV_ID, 3255572Ssbehera BCM_PHY_ID_MASK)) { 3265572Ssbehera nxgep->xcvr_addr = 3276835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR; 3285572Ssbehera goto found_phy; 3295572Ssbehera } 3305572Ssbehera } 3315572Ssbehera if (nxge_is_phy_present(nxgep, 3326835Syc148097 GOA_CLAUSE45_PORT_ADDR_BASE + portn, 3335572Ssbehera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 3346835Syc148097 nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE + 3355572Ssbehera portn; 3365572Ssbehera goto found_phy; 3375572Ssbehera } 3385572Ssbehera 3395572Ssbehera nxgep->phy_absent = B_TRUE; 340*9599Stc99174@train 341*9599Stc99174@train /* Check Serdes link to detect Opus NEM */ 342*9599Stc99174@train rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 343*9599Stc99174@train XPCS_REG_STATUS, &val); 344*9599Stc99174@train 345*9599Stc99174@train if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) { 346*9599Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 347*9599Stc99174@train nxgep->mac.portmode = PORT_10G_SERDES; 348*9599Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL, 349*9599Stc99174@train "HSP 10G Serdes FOUND!!")); 350*9599Stc99174@train } 3515572Ssbehera goto check_phy_done; 3525572Ssbehera found_phy: 3535572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3545572Ssbehera nxgep->mac.portmode = PORT_10G_FIBER; 3555572Ssbehera nxgep->phy_absent = B_FALSE; 3565572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr " 3575572Ssbehera "found for hot swappable phy")); 3585572Ssbehera check_phy_done: 3595572Ssbehera return (status); 3605572Ssbehera } 3615572Ssbehera 3626835Syc148097 /* Get phy-type property (May have been set by nxge.conf) */ 3634977Sraghus if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 3644977Sraghus DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 3654977Sraghus "phy-type", &prop_val)) == DDI_PROP_SUCCESS) { 3664977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3674977Sraghus "found conf file: phy-type %s", prop_val)); 3684977Sraghus if (strcmp("xgsd", prop_val) == 0) { 3694977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3704977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 3714977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3724977Sraghus "found: 10G Serdes")); 3734977Sraghus } else if (strcmp("gsd", prop_val) == 0) { 3744977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3754977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 3764977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes")); 3774977Sraghus } else if (strcmp("mif", prop_val) == 0) { 3784977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3794977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 3804977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 3814977Sraghus } else if (strcmp("pcs", prop_val) == 0) { 3824977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3834977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 3844977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr")); 3856075Ssbehera } else if (strcmp("xgf", prop_val) == 0) { 3866835Syc148097 /* 3876835Syc148097 * Before OBP supports new phy-type property 3886835Syc148097 * value "xgc", the 10G copper XAUI may carry 3896835Syc148097 * "xgf" instead of "xgc". If the OBP is 3906835Syc148097 * upgraded to a newer version which supports 3916835Syc148097 * "xgc", then the TN1010 related code in this 3926835Syc148097 * "xgf" case will not be used anymore. 3936835Syc148097 */ 3946835Syc148097 if (nxge_is_tn1010_phy(nxgep)) { 3956835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) 3966835Syc148097 != NXGE_OK) { 3976835Syc148097 return (status); 3986835Syc148097 } 3996835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 4006835Syc148097 } else { /* For Fiber XAUI */ 4016835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 4026835Syc148097 nxgep->mac.portmode = PORT_10G_FIBER; 4036835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4046835Syc148097 "10G Fiber Xcvr")); 4056835Syc148097 } 4066835Syc148097 } else if (strcmp("xgc", prop_val) == 0) { 4076835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK) 4086835Syc148097 return (status); 4096835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 4104977Sraghus } 4114977Sraghus 4124977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 4134977Sraghus "phy-type", prop_val); 4144977Sraghus ddi_prop_free(prop_val); 4154977Sraghus 4164977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 4174977Sraghus "Got phy type [0x%x] from conf file", 4184977Sraghus nxgep->mac.portmode)); 4194977Sraghus 4204977Sraghus return (NXGE_OK); 4214977Sraghus } 4225572Ssbehera 4235572Ssbehera /* Get phy-type property from OBP */ 4244977Sraghus if (nxgep->niu_type == N2_NIU) { 4254977Sraghus if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 4264977Sraghus "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 4274977Sraghus if (strcmp("xgf", prop_val) == 0) { 4286835Syc148097 /* 4296835Syc148097 * Before OBP supports new phy-type property 4306835Syc148097 * value "xgc", the 10G copper XAUI may carry 4316835Syc148097 * "xgf" instead of "xgc". If the OBP is 4326835Syc148097 * upgraded to a newer version which supports 4336835Syc148097 * "xgc", then the TN1010 related code in this 4346835Syc148097 * "xgf" case will not be used anymore. 4356835Syc148097 */ 4366835Syc148097 if (nxge_is_tn1010_phy(nxgep)) { 4376835Syc148097 if ((status = 4386835Syc148097 nxge_set_tn1010_param(nxgep)) 4396835Syc148097 != NXGE_OK) { 4406835Syc148097 return (status); 4416835Syc148097 } 4426835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4436835Syc148097 "TN1010 Xcvr")); 4446835Syc148097 } else { /* For Fiber XAUI */ 4456835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse 4466835Syc148097 = XPCS_XCVR; 4476835Syc148097 nxgep->mac.portmode = PORT_10G_FIBER; 4486835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4496835Syc148097 "10G Fiber Xcvr")); 4506835Syc148097 } 4514977Sraghus } else if (strcmp("mif", prop_val) == 0) { 4524977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = 4534977Sraghus INT_MII_XCVR; 4544977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 4554977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4564977Sraghus "1G Copper Xcvr")); 4574977Sraghus } else if (strcmp("pcs", prop_val) == 0) { 4584977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 4594977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 4604977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4614977Sraghus "1G Fiber Xcvr")); 4624977Sraghus } else if (strcmp("xgc", prop_val) == 0) { 4636835Syc148097 status = nxge_set_tn1010_param(nxgep); 4646835Syc148097 if (status != NXGE_OK) 4656835Syc148097 return (status); 4666835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 4674977Sraghus } else if (strcmp("xgsd", prop_val) == 0) { 4684977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 4694977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 4704977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4714977Sraghus "OBP: 10G Serdes")); 4724977Sraghus } else if (strcmp("gsd", prop_val) == 0) { 4734977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 4744977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 4754977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4764977Sraghus "OBP: 1G Serdes")); 4774977Sraghus } else { 4784977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4794977Sraghus "Unknown phy-type: %s", prop_val)); 4804977Sraghus ddi_prop_free(prop_val); 4814977Sraghus return (NXGE_ERROR); 4824977Sraghus } 4834977Sraghus status = NXGE_OK; 4844977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, 4854977Sraghus nxgep->dip, "phy-type", prop_val); 4864977Sraghus ddi_prop_free(prop_val); 4874977Sraghus 4884977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 4894977Sraghus "Got phy type [0x%x] from OBP", 4904977Sraghus nxgep->mac.portmode)); 4914977Sraghus 4924977Sraghus return (status); 4934977Sraghus } else { 4944977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4954977Sraghus "Exiting...phy-type property not found")); 4964977Sraghus return (NXGE_ERROR); 4974977Sraghus } 4984977Sraghus } 4994977Sraghus 5004977Sraghus 5014977Sraghus if (!nxgep->vpd_info.present) { 5024977Sraghus return (NXGE_OK); 5034977Sraghus } 5044977Sraghus 5054977Sraghus if (!nxgep->vpd_info.ver_valid) { 5064977Sraghus goto read_seeprom; 5074977Sraghus } 5084977Sraghus 5094977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5104977Sraghus "Reading phy type from expansion ROM")); 5114977Sraghus /* 5124977Sraghus * Try to read the phy type from the vpd data read off the 5134977Sraghus * expansion ROM. 5144977Sraghus */ 5154977Sraghus phy_type = nxgep->vpd_info.phy_type; 5164977Sraghus 5175196Ssbehera if (strncmp(phy_type, "mif", 3) == 0) { 5184977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 5194977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 5205196Ssbehera } else if (strncmp(phy_type, "xgf", 3) == 0) { 5214977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 5224977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 5235196Ssbehera } else if (strncmp(phy_type, "pcs", 3) == 0) { 5244977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 5254977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 5265196Ssbehera } else if (strncmp(phy_type, "xgc", 3) == 0) { 5276835Syc148097 status = nxge_set_tn1010_param(nxgep); 5286835Syc148097 if (status != NXGE_OK) { 5296835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5306835Syc148097 "nxge_get_xcvr_type: Failed to set TN1010 param")); 5316835Syc148097 goto read_seeprom; 5326835Syc148097 } 5335196Ssbehera } else if (strncmp(phy_type, "xgsd", 4) == 0) { 5345196Ssbehera nxgep->mac.portmode = PORT_10G_SERDES; 5355196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 5365196Ssbehera } else if (strncmp(phy_type, "gsd", 3) == 0) { 5375196Ssbehera nxgep->mac.portmode = PORT_1G_SERDES; 5385196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 5394977Sraghus } else { 5405196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5414977Sraghus "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM", 5424977Sraghus phy_type[0], phy_type[1], phy_type[2])); 5434977Sraghus goto read_seeprom; 5444977Sraghus } 5454977Sraghus 5464977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 5474977Sraghus "Got phy type [0x%x] from VPD", nxgep->mac.portmode)); 5484977Sraghus 5494977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 5504977Sraghus return (status); 5514977Sraghus 5524977Sraghus read_seeprom: 5534977Sraghus /* 5544977Sraghus * read the phy type from the SEEPROM - NCR registers 5554977Sraghus */ 5564977Sraghus status = nxge_espc_phy_type_get(nxgep); 5574977Sraghus if (status != NXGE_OK) { 5584977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5594977Sraghus "Failed to get phy type")); 5604977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 5614977Sraghus "[%s] invalid...please update", nxgep->vpd_info.ver)); 5624977Sraghus } 5634977Sraghus 5644977Sraghus return (status); 5654977Sraghus 5664977Sraghus } 5674977Sraghus 5684732Sdavemq /* Set up the PHY specific values. */ 5694732Sdavemq 5704732Sdavemq nxge_status_t 5714732Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep) 5724732Sdavemq { 5734732Sdavemq nxge_status_t status = NXGE_OK; 5744732Sdavemq uint32_t port_type; 5754732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 5764977Sraghus uint32_t pcs_id = 0; 5774977Sraghus uint32_t pma_pmd_id = 0; 5784977Sraghus uint32_t phy_id = 0; 5795572Ssbehera uint16_t chip_id = 0; 5804732Sdavemq 5814732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>", 5824732Sdavemq portn)); 5834732Sdavemq 5844977Sraghus switch (nxgep->niu_type) { 5854977Sraghus case N2_NIU: 5864977Sraghus switch (nxgep->mac.portmode) { 5874977Sraghus case PORT_1G_FIBER: 5884977Sraghus case PORT_1G_SERDES: 5894977Sraghus nxgep->xcvr = nxge_n2_1G_table; 5905572Ssbehera nxgep->xcvr_addr = portn; 5914977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr", 5924977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" : 5934977Sraghus "Serdes")); 5944977Sraghus break; 5954977Sraghus case PORT_10G_FIBER: 5964977Sraghus case PORT_10G_SERDES: 5974977Sraghus nxgep->xcvr = nxge_n2_10G_table; 5985572Ssbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) { 5995572Ssbehera nxgep->xcvr_addr = 6005572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn]; 6015572Ssbehera } 6024977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr", 6034977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" : 6044977Sraghus "Serdes")); 6054977Sraghus break; 6066835Syc148097 case PORT_1G_TN1010: 6076835Syc148097 nxgep->xcvr = nxge_n2_1G_tn1010_table; 6086835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 6096835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6106835Syc148097 "TN1010 Copper Xcvr in 1G")); 6116835Syc148097 break; 6126835Syc148097 case PORT_10G_TN1010: 6136835Syc148097 nxgep->xcvr = nxge_n2_10G_tn1010_table; 6146835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 6156835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6166835Syc148097 "TN1010 Copper Xcvr in 10G")); 6176835Syc148097 break; 6185572Ssbehera case PORT_HSP_MODE: 6195572Ssbehera nxgep->xcvr = nxge_n2_10G_table; 6205572Ssbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR; 6215572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot " 6225572Ssbehera "Swappable Xcvr (not present)")); 6235572Ssbehera break; 6244977Sraghus default: 6254977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6264977Sraghus "<== nxge_setup_xcvr_table: " 6274977Sraghus "Unable to determine NIU portmode")); 6284977Sraghus return (NXGE_ERROR); 6294977Sraghus } 6304977Sraghus break; 6314977Sraghus default: 6324977Sraghus if (nxgep->mac.portmode == 0) { 6334977Sraghus /* 6344977Sraghus * Would be the case for platforms like Maramba 6354977Sraghus * in which the phy type could not be got from conf 6364977Sraghus * file, OBP, VPD or Serial PROM. 6374977Sraghus */ 6384977Sraghus if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 6394977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6404977Sraghus "<== nxge_setup_xcvr_table:" 6414977Sraghus " Invalid Neptune type [0x%x]", 6424977Sraghus nxgep->niu_type)); 6434977Sraghus return (NXGE_ERROR); 6444977Sraghus } 6454977Sraghus 6464977Sraghus port_type = nxgep->niu_type >> 6474977Sraghus (NXGE_PORT_TYPE_SHIFT * portn); 6484977Sraghus port_type = port_type & (NXGE_PORT_TYPE_MASK); 6494977Sraghus 6504977Sraghus switch (port_type) { 6514977Sraghus 6524977Sraghus case NXGE_PORT_1G_COPPER: 6534977Sraghus nxgep->mac.portmode = PORT_1G_COPPER; 6544977Sraghus break; 6554977Sraghus case NXGE_PORT_10G_COPPER: 6564977Sraghus nxgep->mac.portmode = PORT_10G_COPPER; 6574977Sraghus break; 6584977Sraghus case NXGE_PORT_1G_FIBRE: 6594977Sraghus nxgep->mac.portmode = PORT_1G_FIBER; 6604977Sraghus break; 6614977Sraghus case NXGE_PORT_10G_FIBRE: 6624977Sraghus nxgep->mac.portmode = PORT_10G_FIBER; 6634977Sraghus break; 6644977Sraghus case NXGE_PORT_1G_SERDES: 6654977Sraghus nxgep->mac.portmode = PORT_1G_SERDES; 6664977Sraghus break; 6674977Sraghus case NXGE_PORT_10G_SERDES: 6684977Sraghus nxgep->mac.portmode = PORT_10G_SERDES; 6694977Sraghus break; 6706835Syc148097 /* Ports 2 and 3 of Alonso or ARTM */ 6714977Sraghus case NXGE_PORT_1G_RGMII_FIBER: 6724977Sraghus nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 6734977Sraghus break; 6746835Syc148097 case NXGE_PORT_TN1010: 6756835Syc148097 /* 6766835Syc148097 * If this port uses the TN1010 copper 6776835Syc148097 * PHY, then its speed is not known yet 6786835Syc148097 * because nxge_scan_ports_phy could only 6796835Syc148097 * figure out the vendor of the PHY but 6806835Syc148097 * not its speed. nxge_set_tn1010_param 6816835Syc148097 * will read the PHY speed and set 6826835Syc148097 * portmode accordingly. 6836835Syc148097 */ 6846835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) 6856835Syc148097 != NXGE_OK) { 6866835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6876835Syc148097 "nxge_set_tn1010_param failed")); 6886835Syc148097 return (status); 6896835Syc148097 } 6906835Syc148097 break; 6914977Sraghus default: 6924977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6934977Sraghus "<== nxge_setup_xcvr_table: " 6944977Sraghus "Unknown port-type: 0x%x", port_type)); 6954977Sraghus return (NXGE_ERROR); 6964977Sraghus } 6974977Sraghus } 6984977Sraghus 6996835Syc148097 /* 7006835Syc148097 * Above switch has figured out nxge->mac.portmode, now set 7016835Syc148097 * nxgep->xcvr (the table) and nxgep->xcvr_addr according 7026835Syc148097 * to portmode. 7036835Syc148097 */ 7044977Sraghus switch (nxgep->mac.portmode) { 7054977Sraghus case PORT_1G_COPPER: 7064977Sraghus case PORT_1G_RGMII_FIBER: 7074732Sdavemq nxgep->xcvr = nxge_1G_copper_table; 7085572Ssbehera nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 7094732Sdavemq /* 7104732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 7114732Sdavemq * swapped with ethernet port number. This is 7124977Sraghus * designed for better signal integrity in 7134977Sraghus * routing. This is also the case for the 7144977Sraghus * on-board Neptune copper ports on the Maramba 7154977Sraghus * platform. 7164732Sdavemq */ 7174977Sraghus switch (nxgep->platform_type) { 7184977Sraghus case P_NEPTUNE_ATLAS_4PORT: 7194977Sraghus case P_NEPTUNE_MARAMBA_P0: 7204977Sraghus case P_NEPTUNE_MARAMBA_P1: 7214977Sraghus switch (portn) { 7224977Sraghus case 0: 7235572Ssbehera nxgep->xcvr_addr += 3; 7244977Sraghus break; 7254977Sraghus case 1: 7265572Ssbehera nxgep->xcvr_addr += 1; 7274977Sraghus break; 7284977Sraghus case 2: 7295572Ssbehera nxgep->xcvr_addr -= 1; 7304977Sraghus break; 7314977Sraghus case 3: 7325572Ssbehera nxgep->xcvr_addr -= 3; 7334977Sraghus break; 7344977Sraghus default: 7354977Sraghus return (NXGE_ERROR); 7364977Sraghus } 7374732Sdavemq break; 7384732Sdavemq default: 7394977Sraghus break; 7404732Sdavemq } 7415196Ssbehera 7424977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 7434977Sraghus (nxgep->mac.portmode == PORT_1G_COPPER) ? 7444977Sraghus "Copper" : "RGMII Fiber")); 7454732Sdavemq break; 7466835Syc148097 7474977Sraghus case PORT_10G_COPPER: 7484732Sdavemq nxgep->xcvr = nxge_10G_copper_table; 7494732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 7504732Sdavemq break; 7516835Syc148097 7526835Syc148097 case PORT_1G_TN1010: 7536835Syc148097 nxgep->xcvr = nxge_1G_tn1010_table; 7546835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 7556835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7566835Syc148097 "1G TN1010 copper Xcvr")); 7576835Syc148097 break; 7586835Syc148097 7596835Syc148097 case PORT_10G_TN1010: 7606835Syc148097 nxgep->xcvr = nxge_10G_tn1010_table; 7616835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 7626835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 7636835Syc148097 "10G TN1010 copper Xcvr")); 7646835Syc148097 break; 7656835Syc148097 7664977Sraghus case PORT_1G_FIBER: 7674977Sraghus case PORT_1G_SERDES: 7684732Sdavemq nxgep->xcvr = nxge_1G_fiber_table; 7695572Ssbehera nxgep->xcvr_addr = portn; 7704977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 7714977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? 7724977Sraghus "Fiber" : "Serdes")); 7734732Sdavemq break; 7744977Sraghus case PORT_10G_FIBER: 7754977Sraghus case PORT_10G_SERDES: 7764732Sdavemq nxgep->xcvr = nxge_10G_fiber_table; 7775572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr " 7785572Ssbehera "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] " 7795572Ssbehera "nxgep->xcvr_addr = [%d]", 7805572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn], 7815572Ssbehera nxgep->xcvr_addr)); 7825572Ssbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) { 7835572Ssbehera nxgep->xcvr_addr = 7845572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn]; 7855572Ssbehera } 7864977Sraghus switch (nxgep->platform_type) { 7874977Sraghus case P_NEPTUNE_MARAMBA_P0: 7884977Sraghus case P_NEPTUNE_MARAMBA_P1: 7894732Sdavemq /* 7904732Sdavemq * Switch off LED for corresponding copper 7914732Sdavemq * port 7924732Sdavemq */ 7934732Sdavemq nxge_bcm5464_link_led_off(nxgep); 7944977Sraghus break; 7954977Sraghus default: 7964977Sraghus break; 7974732Sdavemq } 7984977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr", 7994977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? 8004977Sraghus "Fiber" : "Serdes")); 8014732Sdavemq break; 8025572Ssbehera 8035572Ssbehera case PORT_HSP_MODE: 8045572Ssbehera nxgep->xcvr = nxge_10G_fiber_table; 8055572Ssbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR; 8065572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot " 8075572Ssbehera "Swappable Xcvr (not present)")); 8085572Ssbehera break; 8094732Sdavemq default: 8104732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8114732Sdavemq "Unknown port-type: 0x%x", port_type)); 8124732Sdavemq return (NXGE_ERROR); 8134732Sdavemq } 8144732Sdavemq } 8154732Sdavemq 8165572Ssbehera if (nxgep->mac.portmode == PORT_10G_FIBER) { 8176604Ssbehera uint32_t pma_pmd_id; 8186604Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, 8196604Ssbehera nxgep->xcvr_addr); 8206604Ssbehera if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) { 8216604Ssbehera chip_id = MRVL88X201X_CHIP_ID; 8226604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8236604Ssbehera "nxge_setup_xcvr_table: " 8246604Ssbehera "Chip ID MARVELL [0x%x] for 10G xcvr", chip_id)); 8256604Ssbehera } else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr, 8265572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG, 8275572Ssbehera &chip_id)) == NXGE_OK) { 8285572Ssbehera 8295572Ssbehera switch (chip_id) { 8305572Ssbehera case BCM8704_CHIP_ID: 8315572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8325572Ssbehera "nxge_setup_xcvr_table: " 8335572Ssbehera "Chip ID 8704 [0x%x] for 10G xcvr", 8345572Ssbehera chip_id)); 8355572Ssbehera break; 8365572Ssbehera case BCM8706_CHIP_ID: 8375572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8385572Ssbehera "nxge_setup_xcvr_table: " 8395572Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", 8405572Ssbehera chip_id)); 8415572Ssbehera break; 8425572Ssbehera default: 8435572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8445572Ssbehera "nxge_setup_xcvr_table: " 8455572Ssbehera "Unknown Chip ID [0x%x] for 10G xcvr", 8465572Ssbehera chip_id)); 8475572Ssbehera break; 8485572Ssbehera } 8495572Ssbehera } 8505572Ssbehera } 8515572Ssbehera 8524732Sdavemq nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse; 8535572Ssbehera nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr; 8545572Ssbehera nxgep->chip_id = chip_id; 8554977Sraghus 8564977Sraghus /* 8574977Sraghus * Get the actual device ID value returned by MDIO read. 8584977Sraghus */ 8594977Sraghus nxgep->statsp->mac_stats.xcvr_id = 0; 8604977Sraghus 8615572Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr); 8624977Sraghus if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) { 8634977Sraghus nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id; 8644977Sraghus } else { 8655572Ssbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr); 8664977Sraghus if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) { 8674977Sraghus nxgep->statsp->mac_stats.xcvr_id = pcs_id; 8684977Sraghus } else { 8694977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, 8705572Ssbehera nxgep->xcvr_addr); 8714977Sraghus if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 8724977Sraghus nxgep->statsp->mac_stats.xcvr_id = phy_id; 8734977Sraghus } 8744977Sraghus } 8754977Sraghus } 8764977Sraghus 8774732Sdavemq nxgep->mac.linkchkmode = LINKCHK_TIMER; 8784732Sdavemq 8794977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type" 8807801SSantwona.Behera@Sun.COM "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type, 8815572Ssbehera nxgep->platform_type, nxgep->xcvr_addr)); 8824977Sraghus 8834732Sdavemq return (status); 8844732Sdavemq } 8854732Sdavemq 8863859Sml29623 /* Initialize the entire MAC and physical layer */ 8873859Sml29623 8883859Sml29623 nxge_status_t 8893859Sml29623 nxge_mac_init(p_nxge_t nxgep) 8903859Sml29623 { 8913859Sml29623 uint8_t portn; 8923859Sml29623 nxge_status_t status = NXGE_OK; 8933859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 8943859Sml29623 8953859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 8963859Sml29623 8973859Sml29623 nxgep->mac.portnum = portn; 8983859Sml29623 nxgep->mac.porttype = PORT_TYPE_XMAC; 8993859Sml29623 9003859Sml29623 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 9013859Sml29623 nxgep->mac.porttype = PORT_TYPE_BMAC; 9023859Sml29623 9036835Syc148097 9043859Sml29623 /* Initialize XIF to configure a network mode */ 9053859Sml29623 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 9063859Sml29623 goto fail; 9073859Sml29623 } 9083859Sml29623 9093859Sml29623 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 9103859Sml29623 goto fail; 9113859Sml29623 } 9123859Sml29623 9133859Sml29623 /* Initialize TX and RX MACs */ 9143859Sml29623 /* 9153859Sml29623 * Always perform XIF init first, before TX and RX MAC init 9163859Sml29623 */ 9173859Sml29623 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 9183859Sml29623 goto fail; 9193859Sml29623 9203859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 9213859Sml29623 goto fail; 9223859Sml29623 9233859Sml29623 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 9243859Sml29623 goto fail; 9253859Sml29623 9263859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 9273859Sml29623 goto fail; 9283859Sml29623 9293859Sml29623 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 9303859Sml29623 goto fail; 9313859Sml29623 9329232SMichael.Speer@Sun.COM if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) { 9339232SMichael.Speer@Sun.COM if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 9349232SMichael.Speer@Sun.COM goto fail; 9359232SMichael.Speer@Sun.COM } 9363859Sml29623 9375553Smisaki /* Initialize MAC control configuration */ 9385553Smisaki if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) { 9395553Smisaki goto fail; 9405553Smisaki } 9415553Smisaki 9423859Sml29623 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 9433859Sml29623 9445196Ssbehera /* The Neptune Serdes needs to be reinitialized again */ 9455196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 9465196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 9476835Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) || 9485196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 9495196Ssbehera ((portn == 0) || (portn == 1))) { 9505196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 9515196Ssbehera "nxge_mac_init: reinit Neptune 1G Serdes ")); 9525196Ssbehera if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) { 9535196Ssbehera goto fail; 9545196Ssbehera } 9555196Ssbehera } 9565196Ssbehera 9574977Sraghus 9583859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 9593859Sml29623 9603859Sml29623 return (NXGE_OK); 9613859Sml29623 fail: 9623859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 9636929Smisaki "nxge_mac_init: failed to initialize MAC port<%d>", portn)); 9643859Sml29623 return (status); 9653859Sml29623 } 9663859Sml29623 9673859Sml29623 /* Initialize the Ethernet Link */ 9683859Sml29623 9693859Sml29623 nxge_status_t 9703859Sml29623 nxge_link_init(p_nxge_t nxgep) 9713859Sml29623 { 9723859Sml29623 nxge_status_t status = NXGE_OK; 9734977Sraghus nxge_port_mode_t portmode; 9743859Sml29623 #ifdef NXGE_DEBUG 9753859Sml29623 uint8_t portn; 9763859Sml29623 9773859Sml29623 portn = nxgep->mac.portnum; 9783859Sml29623 9793859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 9803859Sml29623 #endif 981*9599Stc99174@train /* For Opus NEM, Serdes always needs to be initialized */ 9823859Sml29623 9834977Sraghus portmode = nxgep->mac.portmode; 9845572Ssbehera 9856835Syc148097 /* 9866835Syc148097 * Workaround to get link up in both NIU ports. Some portmodes require 9876835Syc148097 * that the xcvr be initialized twice, the first time before calling 9886835Syc148097 * nxge_serdes_init. 9896835Syc148097 */ 9904977Sraghus if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) && 9916835Syc148097 (portmode != PORT_10G_TN1010) && 9926835Syc148097 (portmode != PORT_1G_TN1010) && 9934977Sraghus (portmode != PORT_1G_SERDES)) { 9944977Sraghus if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) { 9953859Sml29623 goto fail; 9964977Sraghus } 9973859Sml29623 } 9986835Syc148097 9993859Sml29623 NXGE_DELAY(200000); 10003859Sml29623 /* Initialize internal serdes */ 10013859Sml29623 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 10023859Sml29623 goto fail; 10033859Sml29623 NXGE_DELAY(200000); 10043859Sml29623 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 10053859Sml29623 goto fail; 10063859Sml29623 10073859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 10083859Sml29623 10093859Sml29623 return (NXGE_OK); 10103859Sml29623 10113859Sml29623 fail: 10126929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ", 10136929Smisaki "failed to initialize Ethernet link on port<%d>", portn)); 10143859Sml29623 10153859Sml29623 return (status); 10163859Sml29623 } 10173859Sml29623 10183859Sml29623 10193859Sml29623 /* Initialize the XIF sub-block within the MAC */ 10203859Sml29623 10213859Sml29623 nxge_status_t 10223859Sml29623 nxge_xif_init(p_nxge_t nxgep) 10233859Sml29623 { 10243859Sml29623 uint32_t xif_cfg = 0; 10253859Sml29623 npi_attr_t ap; 10263859Sml29623 uint8_t portn; 10273859Sml29623 nxge_port_t portt; 10283859Sml29623 nxge_port_mode_t portmode; 10293859Sml29623 p_nxge_stats_t statsp; 10303859Sml29623 npi_status_t rs = NPI_SUCCESS; 10313859Sml29623 npi_handle_t handle; 10323859Sml29623 10333859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 10343859Sml29623 10353859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 10363859Sml29623 10373859Sml29623 handle = nxgep->npi_handle; 10383859Sml29623 portmode = nxgep->mac.portmode; 10393859Sml29623 portt = nxgep->mac.porttype; 10403859Sml29623 statsp = nxgep->statsp; 10413859Sml29623 10425196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 10435196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 10446835Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) || 10455196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 10465196Ssbehera ((portn == 0) || (portn == 1))) { 10475196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 10485196Ssbehera "nxge_xcvr_init: set ATCA mode")); 10495196Ssbehera npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE); 10505196Ssbehera } 10515196Ssbehera 10523859Sml29623 if (portt == PORT_TYPE_XMAC) { 10533859Sml29623 10543859Sml29623 /* Setup XIF Configuration for XMAC */ 10553859Sml29623 10563859Sml29623 if ((portmode == PORT_10G_FIBER) || 10574977Sraghus (portmode == PORT_10G_COPPER) || 10586835Syc148097 (portmode == PORT_10G_TN1010) || 1059*9599Stc99174@train (portmode == PORT_HSP_MODE) || 10604977Sraghus (portmode == PORT_10G_SERDES)) 10613859Sml29623 xif_cfg |= CFG_XMAC_XIF_LFS; 10623859Sml29623 10636835Syc148097 /* Bypass PCS so that RGMII will be used */ 10643859Sml29623 if (portmode == PORT_1G_COPPER) { 10653859Sml29623 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 10663859Sml29623 } 10673859Sml29623 10683859Sml29623 /* Set MAC Internal Loopback if necessary */ 10693859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 10703859Sml29623 xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 10713859Sml29623 10723859Sml29623 if (statsp->mac_stats.link_speed == 100) 10733859Sml29623 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 10743859Sml29623 10753859Sml29623 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 10763859Sml29623 10774977Sraghus if ((portmode == PORT_10G_FIBER) || 10786835Syc148097 (portmode == PORT_10G_TN1010) || 10796835Syc148097 (portmode == PORT_1G_TN1010) || 1080*9599Stc99174@train (portmode == PORT_HSP_MODE) || 10814977Sraghus (portmode == PORT_10G_SERDES)) { 10826835Syc148097 /* Assume LED same for 1G and 10G */ 10833859Sml29623 if (statsp->mac_stats.link_up) { 10843859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 10853859Sml29623 } else { 10863859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 10873859Sml29623 } 10883859Sml29623 } 10893859Sml29623 10903859Sml29623 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 10913859Sml29623 if (rs != NPI_SUCCESS) 10923859Sml29623 goto fail; 10933859Sml29623 10943859Sml29623 nxgep->mac.xif_config = xif_cfg; 10953859Sml29623 10963859Sml29623 /* Set Port Mode */ 10973859Sml29623 if ((portmode == PORT_10G_FIBER) || 10984977Sraghus (portmode == PORT_10G_COPPER) || 10996835Syc148097 (portmode == PORT_10G_TN1010) || 1100*9599Stc99174@train (portmode == PORT_HSP_MODE) || 11014977Sraghus (portmode == PORT_10G_SERDES)) { 11023859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11036929Smisaki MAC_XGMII_MODE, rs); 11043859Sml29623 if (rs != NPI_SUCCESS) 11053859Sml29623 goto fail; 11063859Sml29623 if (statsp->mac_stats.link_up) { 11073859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 11083859Sml29623 goto fail; 11093859Sml29623 } else { 11103859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 11113859Sml29623 goto fail; 11123859Sml29623 } 11133859Sml29623 } else if ((portmode == PORT_1G_FIBER) || 11144977Sraghus (portmode == PORT_1G_COPPER) || 11155196Ssbehera (portmode == PORT_1G_SERDES) || 11166835Syc148097 (portmode == PORT_1G_TN1010) || 11175196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 11185196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11195196Ssbehera "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]", 11205196Ssbehera portn, portmode, statsp->mac_stats.link_speed)); 11213859Sml29623 if (statsp->mac_stats.link_speed == 1000) { 11223859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11236929Smisaki MAC_GMII_MODE, rs); 11243859Sml29623 } else { 11253859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11266929Smisaki MAC_MII_MODE, rs); 11273859Sml29623 } 11283859Sml29623 if (rs != NPI_SUCCESS) 11293859Sml29623 goto fail; 11303859Sml29623 } else { 11313859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11326929Smisaki "nxge_xif_init: Unknown port mode (%d)" 11336929Smisaki " for port<%d>", portmode, portn)); 11343859Sml29623 goto fail; 11353859Sml29623 } 11363859Sml29623 11375196Ssbehera /* Enable ATCA mode */ 11385196Ssbehera 11393859Sml29623 } else if (portt == PORT_TYPE_BMAC) { 11403859Sml29623 11413859Sml29623 /* Setup XIF Configuration for BMAC */ 11423859Sml29623 11435196Ssbehera if ((portmode == PORT_1G_COPPER) || 11445196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 11453859Sml29623 if (statsp->mac_stats.link_speed == 100) 11463859Sml29623 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 11473859Sml29623 } 11483859Sml29623 11493859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 11503859Sml29623 xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 11513859Sml29623 11523859Sml29623 if (statsp->mac_stats.link_speed == 1000) 11533859Sml29623 xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 11543859Sml29623 11553859Sml29623 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 11563859Sml29623 11573859Sml29623 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 11583859Sml29623 if (rs != NPI_SUCCESS) 11593859Sml29623 goto fail; 11603859Sml29623 nxgep->mac.xif_config = xif_cfg; 11613859Sml29623 } 11623859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 11633859Sml29623 return (NXGE_OK); 11643859Sml29623 fail: 11653859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11666929Smisaki "nxge_xif_init: Failed to initialize XIF port<%d>", portn)); 11673859Sml29623 return (NXGE_ERROR | rs); 11683859Sml29623 } 11693859Sml29623 11706835Syc148097 11716835Syc148097 /* 11726835Syc148097 * Initialize the PCS sub-block in the MAC. Note that PCS does not 11736835Syc148097 * support loopback like XPCS. 11746835Syc148097 */ 11753859Sml29623 nxge_status_t 11763859Sml29623 nxge_pcs_init(p_nxge_t nxgep) 11773859Sml29623 { 11783859Sml29623 pcs_cfg_t pcs_cfg; 11793859Sml29623 uint32_t val; 11803859Sml29623 uint8_t portn; 11813859Sml29623 nxge_port_mode_t portmode; 11823859Sml29623 npi_handle_t handle; 11833859Sml29623 p_nxge_stats_t statsp; 11846835Syc148097 pcs_ctrl_t pcs_ctrl; 11853859Sml29623 npi_status_t rs = NPI_SUCCESS; 11866835Syc148097 uint8_t i; 11873859Sml29623 11883859Sml29623 handle = nxgep->npi_handle; 11893859Sml29623 portmode = nxgep->mac.portmode; 11903859Sml29623 portn = nxgep->mac.portnum; 11913859Sml29623 statsp = nxgep->statsp; 11923859Sml29623 11933859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 11943859Sml29623 11956835Syc148097 if (portmode == PORT_1G_FIBER || 11966835Syc148097 portmode == PORT_1G_TN1010 || 11976835Syc148097 portmode == PORT_1G_SERDES) { 11986835Syc148097 if (portmode == PORT_1G_TN1010) { 11996835Syc148097 /* Reset PCS multiple time in PORT_1G_TN1010 mode */ 12006835Syc148097 for (i = 0; i < 6; i ++) { 12016835Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn)) 12026835Syc148097 != NPI_SUCCESS) { 12036835Syc148097 goto fail; 12046835Syc148097 } 12056835Syc148097 } 12066835Syc148097 } else { 12076835Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn)) 12086835Syc148097 != NPI_SUCCESS) 12096835Syc148097 goto fail; 12104977Sraghus } 12114977Sraghus 12123859Sml29623 /* Initialize port's PCS */ 12133859Sml29623 pcs_cfg.value = 0; 12143859Sml29623 pcs_cfg.bits.w0.enable = 1; 12153859Sml29623 pcs_cfg.bits.w0.mask = 1; 12163859Sml29623 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 12173859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 12184977Sraghus 12194977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12204977Sraghus "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx", 12214977Sraghus portn, pcs_cfg.value)); 12226835Syc148097 12236835Syc148097 if (portmode == PORT_1G_TN1010) { 12246835Syc148097 /* 12256835Syc148097 * Must disable PCS auto-negotiation when the the driver 12266835Syc148097 * is driving the TN1010 based XAUI card Otherwise the 12276835Syc148097 * autonegotiation between the PCS and the TN1010 PCS 12286835Syc148097 * will never complete and the Neptune/NIU will not work 12296835Syc148097 */ 12306835Syc148097 pcs_ctrl.value = 0; 12316835Syc148097 PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG, 12326835Syc148097 pcs_ctrl.value); 12336835Syc148097 } 12346835Syc148097 } else if (portmode == PORT_10G_FIBER || 12356835Syc148097 portmode == PORT_10G_COPPER || 12366835Syc148097 portmode == PORT_10G_TN1010 || 1237*9599Stc99174@train portmode == PORT_HSP_MODE || 12386835Syc148097 portmode == PORT_10G_SERDES) { 12393859Sml29623 /* Use internal XPCS, bypass 1G PCS */ 12403859Sml29623 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 12413859Sml29623 val &= ~XMAC_XIF_XPCS_BYPASS; 12423859Sml29623 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 12433859Sml29623 12443859Sml29623 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 12453859Sml29623 goto fail; 12463859Sml29623 12473859Sml29623 /* Set XPCS Internal Loopback if necessary */ 12483859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 12496929Smisaki XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS) 12503859Sml29623 goto fail; 12516835Syc148097 12523859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 12536929Smisaki (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 12543859Sml29623 val |= XPCS_CTRL1_LOOPBK; 12553859Sml29623 else 12563859Sml29623 val &= ~XPCS_CTRL1_LOOPBK; 12573859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 12586929Smisaki XPCS_REG_CONTROL1, val)) != NPI_SUCCESS) 12593859Sml29623 goto fail; 12603859Sml29623 12613859Sml29623 /* Clear descw errors */ 12623859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 12636929Smisaki XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS) 12643859Sml29623 goto fail; 12653859Sml29623 /* Clear symbol errors */ 12663859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 12676929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS) 12683859Sml29623 goto fail; 12693859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 12706929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS) 12713859Sml29623 goto fail; 12723859Sml29623 12735196Ssbehera } else if ((portmode == PORT_1G_COPPER) || 12745196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 12755196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12765196Ssbehera "==> nxge_pcs_init: (1G) copper port<%d>", portn)); 12773859Sml29623 if (portn < 4) { 12783859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 12796929Smisaki PCS_DATAPATH_MODE_MII); 12803859Sml29623 } 12813859Sml29623 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 12823859Sml29623 goto fail; 12833859Sml29623 12843859Sml29623 } else { 12853859Sml29623 goto fail; 12863859Sml29623 } 12873859Sml29623 pass: 12883859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 12893859Sml29623 return (NXGE_OK); 12903859Sml29623 fail: 12913859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12926929Smisaki "nxge_pcs_init: Failed to initialize PCS port<%d>", portn)); 12933859Sml29623 return (NXGE_ERROR | rs); 12943859Sml29623 } 12953859Sml29623 12965553Smisaki /* 12975553Smisaki * Initialize the MAC CTRL sub-block within the MAC 12985553Smisaki * Only the receive-pause-cap is supported. 12995553Smisaki */ 13005553Smisaki nxge_status_t 13015553Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep) 13025553Smisaki { 13035553Smisaki uint8_t portn; 13045553Smisaki nxge_port_t portt; 13055553Smisaki p_nxge_stats_t statsp; 13065553Smisaki npi_handle_t handle; 13075553Smisaki uint32_t val; 13085553Smisaki 13095553Smisaki portn = NXGE_GET_PORT_NUM(nxgep->function_num); 13105553Smisaki 13115553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>", 13125553Smisaki portn)); 13135553Smisaki 13145553Smisaki handle = nxgep->npi_handle; 13155553Smisaki portt = nxgep->mac.porttype; 13165553Smisaki statsp = nxgep->statsp; 13175553Smisaki 13185553Smisaki if (portt == PORT_TYPE_XMAC) { 13196835Syc148097 /* Reading the current XMAC Config Register for XMAC */ 13205553Smisaki XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 13215553Smisaki 13225553Smisaki /* 13235553Smisaki * Setup XMAC Configuration for XMAC 13245553Smisaki * XMAC only supports receive-pause 13255553Smisaki */ 13265553Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 13275553Smisaki if (!statsp->mac_stats.adv_cap_pause) { 13285553Smisaki /* 13295553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13305553Smisaki * is 0, enable receive pause. 13315553Smisaki */ 13325553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 13335553Smisaki } else { 13345553Smisaki /* 13355553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13365553Smisaki * is 1, disable receive pause. Send pause is 13375553Smisaki * not supported. 13385553Smisaki */ 13395553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 13405553Smisaki } 13415553Smisaki } else { 13426439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13436439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: pause", 13446439Sml29623 portn)); 13455553Smisaki if (statsp->mac_stats.adv_cap_pause) { 13466439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13476439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: " 13486439Sml29623 "enable pause", portn)); 13495553Smisaki /* 13505553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13515553Smisaki * is 1, enable receive pause. 13525553Smisaki */ 13535553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 13545553Smisaki } else { 13555553Smisaki /* 13565553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13575553Smisaki * is 0, disable receive pause. Send pause is 13585553Smisaki * not supported 13595553Smisaki */ 13606439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13616439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: " 13626439Sml29623 "disable pause", portn)); 13635553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 13645553Smisaki } 13655553Smisaki } 13665553Smisaki XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 13675553Smisaki } else if (portt == PORT_TYPE_BMAC) { 13686835Syc148097 /* Reading the current MAC CTRL Config Register for BMAC */ 13695553Smisaki BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val); 13705553Smisaki 13715553Smisaki /* Setup MAC CTRL Configuration for BMAC */ 13725553Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 13735553Smisaki if (statsp->mac_stats.adv_cap_pause) { 13745553Smisaki /* 13755553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13765553Smisaki * is 1, disable receive pause. Send pause 13775553Smisaki * is not supported 13785553Smisaki */ 13795553Smisaki val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN; 13805553Smisaki } else { 13815553Smisaki /* 13825553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 13835553Smisaki * is 0, enable receive pause and disable 13845553Smisaki * send pause. 13855553Smisaki */ 13865553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 13875553Smisaki val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN; 13885553Smisaki } 13895553Smisaki } else { 13905553Smisaki if (statsp->mac_stats.adv_cap_pause) { 13915553Smisaki /* 13925553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 13935553Smisaki * is 1, enable receive pause. Send pause is 13945553Smisaki * not supported. 13955553Smisaki */ 13965553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 13975553Smisaki } else { 13985553Smisaki /* 13995553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 14005553Smisaki * is 0, pause capability is not available in 14015553Smisaki * either direction. 14025553Smisaki */ 14035553Smisaki val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN & 14046929Smisaki ~MAC_CTRL_CFG_RECV_PAUSE_EN); 14055553Smisaki } 14065553Smisaki } 14075553Smisaki BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val); 14085553Smisaki } 14095553Smisaki 14105553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>", 14115553Smisaki portn)); 14125553Smisaki 14135553Smisaki return (NXGE_OK); 14145553Smisaki } 14155553Smisaki 14163859Sml29623 /* Initialize the Internal Serdes */ 14173859Sml29623 14183859Sml29623 nxge_status_t 14193859Sml29623 nxge_serdes_init(p_nxge_t nxgep) 14203859Sml29623 { 14213859Sml29623 p_nxge_stats_t statsp; 14223859Sml29623 #ifdef NXGE_DEBUG 14233859Sml29623 uint8_t portn; 14243859Sml29623 #endif 14253859Sml29623 nxge_status_t status = NXGE_OK; 14263859Sml29623 14273859Sml29623 #ifdef NXGE_DEBUG 14283859Sml29623 portn = nxgep->mac.portnum; 14293859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14304732Sdavemq "==> nxge_serdes_init port<%d>", portn)); 14313859Sml29623 #endif 14323859Sml29623 14334732Sdavemq if (nxgep->xcvr.serdes_init) { 14344732Sdavemq statsp = nxgep->statsp; 14354732Sdavemq status = nxgep->xcvr.serdes_init(nxgep); 14364732Sdavemq if (status != NXGE_OK) 14373859Sml29623 goto fail; 14384732Sdavemq statsp->mac_stats.serdes_inits++; 14393859Sml29623 } 14403859Sml29623 14413859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 14424732Sdavemq portn)); 14433859Sml29623 14443859Sml29623 return (NXGE_OK); 14453859Sml29623 14463859Sml29623 fail: 14473859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14484732Sdavemq "nxge_serdes_init: Failed to initialize serdes for port<%d>", 14494732Sdavemq portn)); 14503859Sml29623 14513859Sml29623 return (status); 14523859Sml29623 } 14533859Sml29623 14543859Sml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 14553859Sml29623 14564732Sdavemq static nxge_status_t 14573859Sml29623 nxge_n2_serdes_init(p_nxge_t nxgep) 14583859Sml29623 { 14593859Sml29623 uint8_t portn; 14603859Sml29623 int chan; 14613859Sml29623 esr_ti_cfgpll_l_t pll_cfg_l; 14624977Sraghus esr_ti_cfgpll_l_t pll_sts_l; 14633859Sml29623 esr_ti_cfgrx_l_t rx_cfg_l; 14643859Sml29623 esr_ti_cfgrx_h_t rx_cfg_h; 14653859Sml29623 esr_ti_cfgtx_l_t tx_cfg_l; 14663859Sml29623 esr_ti_cfgtx_h_t tx_cfg_h; 14674977Sraghus #ifdef NXGE_DEBUG 14684977Sraghus esr_ti_testcfg_t cfg; 14694977Sraghus #endif 14703859Sml29623 esr_ti_testcfg_t test_cfg; 14713859Sml29623 nxge_status_t status = NXGE_OK; 14723859Sml29623 14733859Sml29623 portn = nxgep->mac.portnum; 14743859Sml29623 14753859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 14766929Smisaki portn)); 14773859Sml29623 14783859Sml29623 tx_cfg_l.value = 0; 14793859Sml29623 tx_cfg_h.value = 0; 14803859Sml29623 rx_cfg_l.value = 0; 14813859Sml29623 rx_cfg_h.value = 0; 14823859Sml29623 pll_cfg_l.value = 0; 14834977Sraghus pll_sts_l.value = 0; 14843859Sml29623 test_cfg.value = 0; 14853859Sml29623 14866835Syc148097 /* 14876835Syc148097 * If the nxge driver has been plumbed without a link, then it will 14886835Syc148097 * detect a link up when a cable connecting to an anto-negotiation 14896835Syc148097 * partner is plugged into the port. Because the TN1010 PHY supports 14906835Syc148097 * both 1G and 10G speeds, the driver must re-configure the 14916835Syc148097 * Neptune/NIU according to the negotiated speed. nxge_n2_serdes_init 14926835Syc148097 * is called at the post-link-up reconfiguration time. Here it calls 14936835Syc148097 * nxge_set_tn1010_param to set portmode before re-initializing 14946835Syc148097 * the serdes. 14956835Syc148097 */ 14966835Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 || 14976835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) { 14986835Syc148097 if (nxge_set_tn1010_param(nxgep) != NXGE_OK) { 14996835Syc148097 goto fail; 15006835Syc148097 } 15016835Syc148097 } 15026835Syc148097 15036835Syc148097 if (nxgep->mac.portmode == PORT_10G_FIBER || 15046835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010 || 1505*9599Stc99174@train nxgep->mac.portmode == PORT_HSP_MODE || 15066835Syc148097 nxgep->mac.portmode == PORT_10G_SERDES) { 15073859Sml29623 /* 0x0E01 */ 15083859Sml29623 tx_cfg_l.bits.entx = 1; 15093859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 15103859Sml29623 15113859Sml29623 /* 0x9101 */ 15123859Sml29623 rx_cfg_l.bits.enrx = 1; 15133859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 15143859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 15153859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 15163859Sml29623 15173859Sml29623 /* 0x0008 */ 15183859Sml29623 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 15193859Sml29623 15203859Sml29623 /* Set loopback mode if necessary */ 15213859Sml29623 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 15223859Sml29623 tx_cfg_l.bits.entest = 1; 15233859Sml29623 rx_cfg_l.bits.entest = 1; 15243859Sml29623 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 15253859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, 15266929Smisaki ESR_N2_DEV_ADDR, 15276929Smisaki ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) 15283859Sml29623 goto fail; 15293859Sml29623 } 15303859Sml29623 15316835Syc148097 /* Initialize PLL for 10G */ 15326835Syc148097 pll_cfg_l.bits.mpy = CFGPLL_MPY_10X; 15336835Syc148097 pll_cfg_l.bits.enpll = 1; 15346835Syc148097 pll_sts_l.bits.enpll = 1; 15356835Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15366835Syc148097 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 15376835Syc148097 goto fail; 15386835Syc148097 15396835Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15406835Syc148097 ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 15416835Syc148097 goto fail; 15426835Syc148097 15436835Syc148097 #ifdef NXGE_DEBUG 15446835Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15456835Syc148097 ESR_N2_PLL_CFG_L_REG, &cfg.value); 15466835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15476835Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 15486835Syc148097 portn, pll_cfg_l.value, cfg.value)); 15496835Syc148097 15506835Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15516835Syc148097 ESR_N2_PLL_STS_L_REG, &cfg.value); 15526835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15536835Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 15546835Syc148097 portn, pll_sts_l.value, cfg.value)); 15556835Syc148097 #endif 15566835Syc148097 } else if (nxgep->mac.portmode == PORT_1G_FIBER || 15576835Syc148097 nxgep->mac.portmode == PORT_1G_TN1010 || 15586835Syc148097 nxgep->mac.portmode == PORT_1G_SERDES) { 15593859Sml29623 /* 0x0E21 */ 15603859Sml29623 tx_cfg_l.bits.entx = 1; 15613859Sml29623 tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 15623859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 15633859Sml29623 15643859Sml29623 /* 0x9121 */ 15653859Sml29623 rx_cfg_l.bits.enrx = 1; 15663859Sml29623 rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 15673859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 15683859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 15693859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 15703859Sml29623 15714977Sraghus if (portn == 0) { 15724977Sraghus /* 0x8 */ 15734977Sraghus rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 15744977Sraghus } 15753859Sml29623 15766835Syc148097 /* Initialize PLL for 1G */ 15773859Sml29623 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 15783859Sml29623 pll_cfg_l.bits.enpll = 1; 15794977Sraghus pll_sts_l.bits.enpll = 1; 15803859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15816929Smisaki ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 15823859Sml29623 goto fail; 15834977Sraghus 15844977Sraghus if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 15854977Sraghus ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 15864977Sraghus goto fail; 15874977Sraghus 15884977Sraghus #ifdef NXGE_DEBUG 15894977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15904977Sraghus ESR_N2_PLL_CFG_L_REG, &cfg.value); 15914977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15924977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 15934977Sraghus portn, pll_cfg_l.value, cfg.value)); 15944977Sraghus 15954977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 15964977Sraghus ESR_N2_PLL_STS_L_REG, &cfg.value); 15974977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 15984977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 15994977Sraghus portn, pll_sts_l.value, cfg.value)); 16004977Sraghus #endif 16014977Sraghus 16024977Sraghus /* Set loopback mode if necessary */ 16034977Sraghus if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 16044977Sraghus tx_cfg_l.bits.entest = 1; 16054977Sraghus rx_cfg_l.bits.entest = 1; 16064977Sraghus test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 16074977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16084977Sraghus "==> nxge_n2_serdes_init port<%d>: loopback 0x%x", 16094977Sraghus portn, test_cfg.value)); 16104977Sraghus if ((status = nxge_mdio_write(nxgep, portn, 16114977Sraghus ESR_N2_DEV_ADDR, 16124977Sraghus ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) { 16134977Sraghus goto fail; 16144977Sraghus } 16154977Sraghus } 16163859Sml29623 } else { 16173859Sml29623 goto fail; 16183859Sml29623 } 16193859Sml29623 16203859Sml29623 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 16213859Sml29623 16223859Sml29623 NXGE_DELAY(20); 16233859Sml29623 16243859Sml29623 /* init TX channels */ 16253859Sml29623 for (chan = 0; chan < 4; chan++) { 16263859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16276929Smisaki ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK) 16283859Sml29623 goto fail; 16293859Sml29623 16303859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16316929Smisaki ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK) 16323859Sml29623 goto fail; 16334977Sraghus 16344977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16354977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x", 16364977Sraghus portn, chan, tx_cfg_l.value)); 16374977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16384977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x", 16394977Sraghus portn, chan, tx_cfg_h.value)); 16403859Sml29623 } 16413859Sml29623 16423859Sml29623 /* init RX channels */ 16433859Sml29623 for (chan = 0; chan < 4; chan++) { 16443859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16456929Smisaki ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK) 16463859Sml29623 goto fail; 16473859Sml29623 16483859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16496929Smisaki ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK) 16503859Sml29623 goto fail; 16514977Sraghus 16524977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16534977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x", 16544977Sraghus portn, chan, rx_cfg_l.value)); 16556835Syc148097 16564977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16574977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x", 16584977Sraghus portn, chan, rx_cfg_h.value)); 16593859Sml29623 } 16603859Sml29623 16613859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 16626929Smisaki portn)); 16633859Sml29623 16643859Sml29623 return (NXGE_OK); 16653859Sml29623 fail: 16665572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16675572Ssbehera "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 16685572Ssbehera portn)); 16693859Sml29623 16703859Sml29623 return (status); 16713859Sml29623 } 16723859Sml29623 16734732Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */ 16744732Sdavemq 16754732Sdavemq static nxge_status_t 16764732Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep) 16773859Sml29623 { 16783859Sml29623 npi_handle_t handle; 16793859Sml29623 uint8_t portn; 16806075Ssbehera int chan, i; 16813859Sml29623 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 16823859Sml29623 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 16833859Sml29623 sr_glue_ctrl0_l_t glue_ctrl0_l; 16843859Sml29623 sr_glue_ctrl0_h_t glue_ctrl0_h; 16853859Sml29623 uint64_t val; 16863859Sml29623 uint16_t val16l; 16873859Sml29623 uint16_t val16h; 16883859Sml29623 nxge_status_t status = NXGE_OK; 16893859Sml29623 16903859Sml29623 portn = nxgep->mac.portnum; 16913859Sml29623 16923859Sml29623 if ((portn != 0) && (portn != 1)) 16933859Sml29623 return (NXGE_OK); 16943859Sml29623 16954732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16964732Sdavemq "==> nxge_neptune_10G_serdes_init port<%d>", portn)); 16973859Sml29623 handle = nxgep->npi_handle; 16984732Sdavemq switch (portn) { 16994732Sdavemq case 0: 17006028Ssbehera /* Reset Serdes */ 17016028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0); 17026028Ssbehera NXGE_DELAY(20); 17036028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0); 17046028Ssbehera NXGE_DELAY(2000); 17056028Ssbehera 17066028Ssbehera /* Configure Serdes to 10G mode */ 17076028Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 17086028Ssbehera ESR_PLL_CFG_10G_SERDES); 17096028Ssbehera 17104732Sdavemq ESR_REG_WR(handle, ESR_0_CONTROL_REG, 17114732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 17124732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 17134732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 17144732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 17154732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 17164732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 17174732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 17184732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 17194732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 17204732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 17214732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 17224732Sdavemq 17234732Sdavemq /* Set Serdes0 Internal Loopback if necessary */ 17244732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 17254732Sdavemq ESR_REG_WR(handle, 17264732Sdavemq ESR_0_TEST_CONFIG_REG, 17274732Sdavemq ESR_PAD_LOOPBACK_CH3 | 17284732Sdavemq ESR_PAD_LOOPBACK_CH2 | 17294732Sdavemq ESR_PAD_LOOPBACK_CH1 | 17304732Sdavemq ESR_PAD_LOOPBACK_CH0); 17314732Sdavemq } else { 17324732Sdavemq ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 17333859Sml29623 } 17344732Sdavemq break; 17354732Sdavemq case 1: 17366028Ssbehera /* Reset Serdes */ 17376028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1); 17386028Ssbehera NXGE_DELAY(20); 17396028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0); 17406028Ssbehera NXGE_DELAY(2000); 17416028Ssbehera 17426028Ssbehera /* Configure Serdes to 10G mode */ 17436028Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 17446028Ssbehera ESR_PLL_CFG_10G_SERDES); 17456028Ssbehera 17464732Sdavemq ESR_REG_WR(handle, ESR_1_CONTROL_REG, 17474732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 17484732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 17494732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 17504732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 17514732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 17524732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 17534732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 17544732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 17554732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 17564732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 17574732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 17584732Sdavemq 17594732Sdavemq /* Set Serdes1 Internal Loopback if necessary */ 17604732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 17614732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 17624732Sdavemq ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 | 17634732Sdavemq ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0); 17644732Sdavemq } else { 17654732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 17663859Sml29623 } 17674732Sdavemq break; 17684732Sdavemq default: 17694732Sdavemq /* Nothing to do here */ 17704732Sdavemq goto done; 17714732Sdavemq } 17724732Sdavemq 17734732Sdavemq /* init TX RX channels */ 17744732Sdavemq for (chan = 0; chan < 4; chan++) { 17754732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 17764732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 17774732Sdavemq &rx_tx_ctrl_l.value)) != NXGE_OK) 17783859Sml29623 goto fail; 17794732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 17804732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 17814732Sdavemq &rx_tx_ctrl_h.value)) != NXGE_OK) 17823859Sml29623 goto fail; 17833859Sml29623 if ((status = nxge_mdio_read(nxgep, portn, 17844732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 17854732Sdavemq &glue_ctrl0_l.value)) != NXGE_OK) 17863859Sml29623 goto fail; 17873859Sml29623 if ((status = nxge_mdio_read(nxgep, portn, 17884732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 17894732Sdavemq &glue_ctrl0_h.value)) != NXGE_OK) 17904732Sdavemq goto fail; 17914732Sdavemq rx_tx_ctrl_l.bits.enstretch = 1; 17924732Sdavemq rx_tx_ctrl_h.bits.vmuxlo = 2; 17934732Sdavemq rx_tx_ctrl_h.bits.vpulselo = 2; 17944732Sdavemq glue_ctrl0_l.bits.rxlosenable = 1; 17954732Sdavemq glue_ctrl0_l.bits.samplerate = 0xF; 17964732Sdavemq glue_ctrl0_l.bits.thresholdcount = 0xFF; 17974732Sdavemq glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 17984732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 17994732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 18004732Sdavemq rx_tx_ctrl_l.value)) != NXGE_OK) 18014732Sdavemq goto fail; 18024732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 18034732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 18044732Sdavemq rx_tx_ctrl_h.value)) != NXGE_OK) 18054732Sdavemq goto fail; 18064732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 18074732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 18084732Sdavemq glue_ctrl0_l.value)) != NXGE_OK) 18094732Sdavemq goto fail; 18104732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 18114732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 18124732Sdavemq glue_ctrl0_h.value)) != NXGE_OK) 18133859Sml29623 goto fail; 18143859Sml29623 } 18153859Sml29623 18164732Sdavemq /* Apply Tx core reset */ 18174732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 18184732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 18194732Sdavemq (uint16_t)0)) != NXGE_OK) 18204732Sdavemq goto fail; 18214732Sdavemq 18224732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18234732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 18244732Sdavemq NXGE_OK) 18254732Sdavemq goto fail; 18264732Sdavemq 18274732Sdavemq NXGE_DELAY(200); 18284732Sdavemq 18294732Sdavemq /* Apply Rx core reset */ 18304732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18314732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 18324732Sdavemq NXGE_OK) 18334732Sdavemq goto fail; 18344732Sdavemq 18354732Sdavemq NXGE_DELAY(200); 18364732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18374732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) 18384732Sdavemq goto fail; 18394732Sdavemq 18404732Sdavemq NXGE_DELAY(200); 18414732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 18424732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 18434732Sdavemq &val16l)) != NXGE_OK) 18444732Sdavemq goto fail; 18454732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 18464732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) 18474732Sdavemq goto fail; 18484732Sdavemq if ((val16l != 0) || (val16h != 0)) { 18494732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18505196Ssbehera "Failed to reset port<%d> XAUI Serdes " 18515196Ssbehera "(val16l 0x%x val16h 0x%x)", 18525196Ssbehera portn, val16l, val16h)); 18534732Sdavemq } 18544732Sdavemq 18554732Sdavemq if (portn == 0) { 18566075Ssbehera /* Wait for serdes to be ready */ 18576075Ssbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 18586075Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 18596075Ssbehera if ((val & ESR_SIG_P0_BITS_MASK) != 18606075Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 18616075Ssbehera ESR_SIG_XSERDES_RDY_P0 | 18626075Ssbehera ESR_SIG_XDETECT_P0_CH3 | 18636075Ssbehera ESR_SIG_XDETECT_P0_CH2 | 18646075Ssbehera ESR_SIG_XDETECT_P0_CH1 | 18656075Ssbehera ESR_SIG_XDETECT_P0_CH0)) 18666075Ssbehera 18676075Ssbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 18686075Ssbehera else 18696075Ssbehera break; 18706075Ssbehera } 18716075Ssbehera 18726075Ssbehera if (i == MAX_SERDES_RDY_RETRIES) { 18736650Sjoycey /* 18746650Sjoycey * RDY signal stays low may due to the absent of the 18756650Sjoycey * external PHY, it is not an error condition. But still 18766650Sjoycey * print the message for the debugging purpose when link 18776650Sjoycey * stays down 18786650Sjoycey */ 18796075Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18806075Ssbehera "nxge_neptune_10G_serdes_init: " 18816075Ssbehera "Serdes/signal for port<%d> not ready", portn)); 18826835Syc148097 goto done; 18834732Sdavemq } 18844732Sdavemq } else if (portn == 1) { 18856075Ssbehera /* Wait for serdes to be ready */ 18866075Ssbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 18876075Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 18886075Ssbehera if ((val & ESR_SIG_P1_BITS_MASK) != 18896075Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 18906075Ssbehera ESR_SIG_XSERDES_RDY_P1 | 18916075Ssbehera ESR_SIG_XDETECT_P1_CH3 | 18926075Ssbehera ESR_SIG_XDETECT_P1_CH2 | 18936075Ssbehera ESR_SIG_XDETECT_P1_CH1 | 18946075Ssbehera ESR_SIG_XDETECT_P1_CH0)) 18956075Ssbehera 18966075Ssbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 18976075Ssbehera else 18986075Ssbehera break; 18996075Ssbehera } 19006075Ssbehera 19016075Ssbehera if (i == MAX_SERDES_RDY_RETRIES) { 19026650Sjoycey /* 19036650Sjoycey * RDY signal stays low may due to the absent of the 19046650Sjoycey * external PHY, it is not an error condition. But still 19056650Sjoycey * print the message for the debugging purpose when link 19066650Sjoycey * stays down 19076650Sjoycey */ 19086075Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19096075Ssbehera "nxge_neptune_10G_serdes_init: " 19106075Ssbehera "Serdes/signal for port<%d> not ready", portn)); 19116835Syc148097 goto done; 19123859Sml29623 } 19133859Sml29623 } 19143859Sml29623 19153859Sml29623 done: 19164732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19174732Sdavemq "<== nxge_neptune_10G_serdes_init port<%d>", portn)); 19184732Sdavemq 19193859Sml29623 return (NXGE_OK); 19203859Sml29623 fail: 19215572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19224732Sdavemq "nxge_neptune_10G_serdes_init: " 19234732Sdavemq "Failed to initialize Neptune serdes for port<%d>", portn)); 19243859Sml29623 19253859Sml29623 return (status); 19263859Sml29623 } 19273859Sml29623 19284732Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */ 19294732Sdavemq 19304732Sdavemq static nxge_status_t 19314732Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep) 19323859Sml29623 { 19334732Sdavemq npi_handle_t handle; 19344732Sdavemq uint8_t portn; 19355196Ssbehera int chan; 19365196Ssbehera sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 19375196Ssbehera sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 19385196Ssbehera sr_glue_ctrl0_l_t glue_ctrl0_l; 19395196Ssbehera sr_glue_ctrl0_h_t glue_ctrl0_h; 19404732Sdavemq uint64_t val; 19415196Ssbehera uint16_t val16l; 19425196Ssbehera uint16_t val16h; 19435196Ssbehera nxge_status_t status = NXGE_OK; 19443859Sml29623 19453859Sml29623 portn = nxgep->mac.portnum; 19464732Sdavemq 19474732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19484732Sdavemq "==> nxge_1G_serdes_init port<%d>", portn)); 19494732Sdavemq 19504732Sdavemq handle = nxgep->npi_handle; 19514732Sdavemq 19524732Sdavemq switch (portn) { 19534732Sdavemq case 0: 19545196Ssbehera /* Assert 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); 19585196Ssbehera 19595196Ssbehera /* Set the PLL register to 0x79 */ 19605196Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 19615196Ssbehera ESR_PLL_CFG_1G_SERDES); 19625196Ssbehera 19635196Ssbehera /* Set the control register to 0x249249f */ 19645196Ssbehera ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES); 19655196Ssbehera 19665196Ssbehera /* Set Serdes0 Internal Loopback if necessary */ 19675196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 19685196Ssbehera /* Set pad loopback modes 0xaa */ 19695196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 19705196Ssbehera ESR_TSTCFG_LBTEST_PAD); 19715196Ssbehera } else { 19725196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 19735196Ssbehera } 19745196Ssbehera 19755196Ssbehera /* Deassert the reset register */ 19765196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 19775196Ssbehera val &= ~ESR_RESET_0; 19785196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 19794732Sdavemq break; 19805196Ssbehera 19814732Sdavemq case 1: 19825196Ssbehera /* Assert 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); 19865196Ssbehera 19875196Ssbehera /* Set PLL register to 0x79 */ 19885196Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 19895196Ssbehera ESR_PLL_CFG_1G_SERDES); 19905196Ssbehera 19915196Ssbehera /* Set the control register to 0x249249f */ 19925196Ssbehera ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES); 19935196Ssbehera 19945196Ssbehera /* Set Serdes1 Internal Loopback if necessary */ 19955196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 19965196Ssbehera /* Set pad loopback mode 0xaa */ 19975196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 19985196Ssbehera ESR_TSTCFG_LBTEST_PAD); 19995196Ssbehera } else { 20005196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 20015196Ssbehera } 20025196Ssbehera 20035196Ssbehera /* Deassert the reset register */ 20045196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 20055196Ssbehera val &= ~ESR_RESET_1; 20065196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 20074732Sdavemq break; 20085196Ssbehera 20094732Sdavemq default: 20105196Ssbehera /* Nothing to do here */ 20115196Ssbehera goto done; 20125196Ssbehera } 20135196Ssbehera 20145196Ssbehera /* init TX RX channels */ 20155196Ssbehera for (chan = 0; chan < 4; chan++) { 20165196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20175196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 20185196Ssbehera &rx_tx_ctrl_l.value)) != NXGE_OK) { 20195196Ssbehera goto fail; 20205196Ssbehera } 20215196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20225196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 20235196Ssbehera &rx_tx_ctrl_h.value)) != NXGE_OK) { 20245196Ssbehera goto fail; 20255196Ssbehera } 20265196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20275196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 20285196Ssbehera &glue_ctrl0_l.value)) != NXGE_OK) { 20295196Ssbehera goto fail; 20305196Ssbehera } 20315196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 20325196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 20335196Ssbehera &glue_ctrl0_h.value)) != NXGE_OK) { 20345196Ssbehera goto fail; 20355196Ssbehera } 20365196Ssbehera 20375196Ssbehera rx_tx_ctrl_l.bits.enstretch = 1; 20385196Ssbehera rx_tx_ctrl_h.bits.vmuxlo = 2; 20395196Ssbehera rx_tx_ctrl_h.bits.vpulselo = 2; 20405196Ssbehera glue_ctrl0_l.bits.rxlosenable = 1; 20415196Ssbehera glue_ctrl0_l.bits.samplerate = 0xF; 20425196Ssbehera glue_ctrl0_l.bits.thresholdcount = 0xFF; 20435196Ssbehera glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 20445196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20455196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 20465196Ssbehera rx_tx_ctrl_l.value)) != NXGE_OK) { 20475196Ssbehera goto fail; 20485196Ssbehera } 20495196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20505196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 20515196Ssbehera rx_tx_ctrl_h.value)) != NXGE_OK) { 20525196Ssbehera goto fail; 20535196Ssbehera } 20545196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20555196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 20565196Ssbehera glue_ctrl0_l.value)) != NXGE_OK) { 20575196Ssbehera goto fail; 20585196Ssbehera } 20595196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 20605196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 20615196Ssbehera glue_ctrl0_h.value)) != NXGE_OK) { 20625196Ssbehera goto fail; 20635196Ssbehera } 20645196Ssbehera } 20655196Ssbehera 20665196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20675196Ssbehera ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) { 20684732Sdavemq goto fail; 20693859Sml29623 } 20705196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20715196Ssbehera ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 20725196Ssbehera goto fail; 20735196Ssbehera } 20745196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20755196Ssbehera ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) { 20765196Ssbehera goto fail; 20775196Ssbehera } 20785196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20795196Ssbehera ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 20805196Ssbehera goto fail; 20815196Ssbehera } 20825196Ssbehera 20835196Ssbehera /* Apply Tx core reset */ 20845196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20855196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) { 20865196Ssbehera goto fail; 20875196Ssbehera } 20885196Ssbehera 20895196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20905196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 20915196Ssbehera NXGE_OK) { 20925196Ssbehera goto fail; 20935196Ssbehera } 20945196Ssbehera 20955196Ssbehera NXGE_DELAY(200); 20965196Ssbehera 20975196Ssbehera /* Apply Rx core reset */ 20985196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 20995196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 21005196Ssbehera NXGE_OK) { 21015196Ssbehera goto fail; 21025196Ssbehera } 21035196Ssbehera 21045196Ssbehera NXGE_DELAY(200); 21055196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 21065196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) { 21075196Ssbehera goto fail; 21085196Ssbehera } 21095196Ssbehera 21105196Ssbehera NXGE_DELAY(200); 21115196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 21125196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) { 21135196Ssbehera goto fail; 21145196Ssbehera } 21155196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 21165196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) { 21175196Ssbehera goto fail; 21185196Ssbehera } 21195196Ssbehera if ((val16l != 0) || (val16h != 0)) { 21205196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21215196Ssbehera "Failed to reset port<%d> XAUI Serdes " 21225196Ssbehera "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h)); 21235196Ssbehera status = NXGE_ERROR; 21245196Ssbehera goto fail; 21255196Ssbehera } 21265196Ssbehera 21275196Ssbehera NXGE_DELAY(200); 21285196Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 21295196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 21305196Ssbehera "nxge_neptune_serdes_init: read internal signal reg port<%d> " 21315196Ssbehera "val 0x%x", portn, val)); 21325196Ssbehera if (portn == 0) { 21335196Ssbehera if ((val & ESR_SIG_P0_BITS_MASK_1G) != 21345196Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) { 21356650Sjoycey /* 21366650Sjoycey * RDY signal stays low may due to the absent of the 21376650Sjoycey * external PHY, it is not an error condition. But still 21386650Sjoycey * print the message for the debugging purpose when link 21396650Sjoycey * stays down 21406650Sjoycey */ 21415196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21426650Sjoycey "nxge_neptune_1G_serdes_init: " 21436650Sjoycey "Serdes/signal for port<%d> not ready", portn)); 21446835Syc148097 goto done; 21455196Ssbehera } 21465196Ssbehera } else if (portn == 1) { 21475196Ssbehera if ((val & ESR_SIG_P1_BITS_MASK_1G) != 21485196Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) { 21496650Sjoycey /* 21506650Sjoycey * RDY signal stays low may due to the absent of the 21516650Sjoycey * external PHY, it is not an error condition. But still 21526650Sjoycey * print the message for the debugging purpose when link 21536650Sjoycey * stays down 21546650Sjoycey */ 21555196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21566650Sjoycey "nxge_neptune_1G_serdes_init: " 21576650Sjoycey "Serdes/signal for port<%d> not ready", portn)); 21586835Syc148097 goto done; 21596835Syc148097 21605196Ssbehera } 21615196Ssbehera } 21625196Ssbehera done: 21634732Sdavemq 21644732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 21654732Sdavemq "<== nxge_1G_serdes_init port<%d>", portn)); 21663859Sml29623 return (NXGE_OK); 21674732Sdavemq fail: 21685196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21694732Sdavemq "nxge_1G_serdes_init: " 21704732Sdavemq "Failed to initialize Neptune serdes for port<%d>", 21714732Sdavemq portn)); 21724732Sdavemq 21735196Ssbehera return (status); 21743859Sml29623 } 21753859Sml29623 21765572Ssbehera /* Initialize the BCM 8704 xcvr */ 21774732Sdavemq 21784732Sdavemq static nxge_status_t 21795572Ssbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep) 21803859Sml29623 { 21813859Sml29623 uint16_t val; 21823859Sml29623 #ifdef NXGE_DEBUG 21833859Sml29623 uint8_t portn; 21843859Sml29623 uint16_t val1; 21853859Sml29623 #endif 21863859Sml29623 uint8_t phy_port_addr; 21873859Sml29623 pmd_tx_control_t tx_ctl; 21883859Sml29623 control_t ctl; 21893859Sml29623 phyxs_control_t phyxs_ctl; 21903859Sml29623 pcs_control_t pcs_ctl; 21913859Sml29623 uint32_t delay = 0; 21923859Sml29623 optics_dcntr_t op_ctr; 21933859Sml29623 nxge_status_t status = NXGE_OK; 21943859Sml29623 #ifdef NXGE_DEBUG 21953859Sml29623 portn = nxgep->mac.portnum; 21963859Sml29623 #endif 21975572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>", 21984732Sdavemq portn)); 21994732Sdavemq 22004732Sdavemq phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 22014732Sdavemq 22024732Sdavemq /* Reset the transceiver */ 22034732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 22044732Sdavemq BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 22054732Sdavemq goto fail; 22064732Sdavemq 22074732Sdavemq phyxs_ctl.bits.reset = 1; 22084732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 22094732Sdavemq BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 22104732Sdavemq goto fail; 22114732Sdavemq 22124732Sdavemq do { 22134732Sdavemq drv_usecwait(500); 22144732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22154732Sdavemq BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 22164732Sdavemq &phyxs_ctl.value)) != NXGE_OK) 22174732Sdavemq goto fail; 22184732Sdavemq delay++; 22194732Sdavemq } while ((phyxs_ctl.bits.reset) && (delay < 100)); 22204732Sdavemq if (delay == 100) { 22214732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 22224732Sdavemq "failed to reset Transceiver on port<%d>", portn)); 22234732Sdavemq status = NXGE_ERROR; 22244732Sdavemq goto fail; 22254732Sdavemq } 22264732Sdavemq 22274732Sdavemq /* Set to 0x7FBF */ 22284732Sdavemq ctl.value = 0; 22294732Sdavemq ctl.bits.res1 = 0x3F; 22304732Sdavemq ctl.bits.optxon_lvl = 1; 22314732Sdavemq ctl.bits.oprxflt_lvl = 1; 22324732Sdavemq ctl.bits.optrxlos_lvl = 1; 22334732Sdavemq ctl.bits.optxflt_lvl = 1; 22344732Sdavemq ctl.bits.opprflt_lvl = 1; 22354732Sdavemq ctl.bits.obtmpflt_lvl = 1; 22364732Sdavemq ctl.bits.opbiasflt_lvl = 1; 22374732Sdavemq ctl.bits.optxrst_lvl = 1; 22384732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22394732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value)) 22404732Sdavemq != NXGE_OK) 22414732Sdavemq goto fail; 22424732Sdavemq 22434732Sdavemq /* Set to 0x164 */ 22444732Sdavemq tx_ctl.value = 0; 22454732Sdavemq tx_ctl.bits.tsck_lpwren = 1; 22464732Sdavemq tx_ctl.bits.tx_dac_txck = 0x2; 22474732Sdavemq tx_ctl.bits.tx_dac_txd = 0x1; 22484732Sdavemq tx_ctl.bits.xfp_clken = 1; 22494732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22504732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, 22514732Sdavemq tx_ctl.value)) != NXGE_OK) 22524732Sdavemq goto fail; 22534732Sdavemq /* 22544732Sdavemq * According to Broadcom's instruction, SW needs to read 22554732Sdavemq * back these registers twice after written. 22564732Sdavemq */ 22574732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22584732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 22594732Sdavemq != NXGE_OK) 22604732Sdavemq goto fail; 22614732Sdavemq 22624732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22634732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 22644732Sdavemq != NXGE_OK) 22654732Sdavemq goto fail; 22664732Sdavemq 22674732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22684732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 22694732Sdavemq != NXGE_OK) 22704732Sdavemq goto fail; 22714732Sdavemq 22724732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22734732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 22744732Sdavemq != NXGE_OK) 22754732Sdavemq goto fail; 22764732Sdavemq 22774732Sdavemq /* Enable Tx and Rx LEDs to be driven by traffic */ 22784732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22794732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 22804732Sdavemq &op_ctr.value)) != NXGE_OK) 22814732Sdavemq goto fail; 22825553Smisaki if (NXGE_IS_XAUI_PLATFORM(nxgep)) { 22835553Smisaki op_ctr.bits.gpio_sel = 0x1; 22845553Smisaki } else { 22855553Smisaki op_ctr.bits.gpio_sel = 0x3; 22865553Smisaki } 22874732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 22884732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 22894732Sdavemq op_ctr.value)) != NXGE_OK) 22904732Sdavemq goto fail; 22914732Sdavemq 22924732Sdavemq NXGE_DELAY(1000000); 22934732Sdavemq 22944732Sdavemq /* Set BCM8704 Internal Loopback mode if necessary */ 22954732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 22964732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 22974732Sdavemq != NXGE_OK) 22984732Sdavemq goto fail; 22994732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 23004732Sdavemq pcs_ctl.bits.loopback = 1; 23014732Sdavemq else 23024732Sdavemq pcs_ctl.bits.loopback = 0; 23034732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 23044732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 23054732Sdavemq != NXGE_OK) 23064732Sdavemq goto fail; 23074732Sdavemq 23084732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val); 23094732Sdavemq if (status != NXGE_OK) 23104732Sdavemq goto fail; 23114732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 23124732Sdavemq "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val)); 23134732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 23144732Sdavemq if (status != NXGE_OK) 23154732Sdavemq goto fail; 23164732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 23174732Sdavemq "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val)); 23184732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 23194732Sdavemq if (status != NXGE_OK) 23204732Sdavemq goto fail; 23214732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 23224732Sdavemq "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val)); 23234732Sdavemq 23244732Sdavemq #ifdef NXGE_DEBUG 23254732Sdavemq /* Diagnose link issue if link is not up */ 23264732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR, 23274732Sdavemq BCM8704_USER_ANALOG_STATUS0_REG, 23284732Sdavemq &val); 23294732Sdavemq if (status != NXGE_OK) 23304732Sdavemq goto fail; 23314732Sdavemq 23324732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 23336929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val); 23344732Sdavemq if (status != NXGE_OK) 23354732Sdavemq goto fail; 23364732Sdavemq 23374732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 23386929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1); 23394732Sdavemq if (status != NXGE_OK) 23404732Sdavemq goto fail; 23414732Sdavemq 23424732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 23436929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1); 23444732Sdavemq if (status != NXGE_OK) 23454732Sdavemq goto fail; 23464732Sdavemq 23474732Sdavemq if (val != 0x3FC) { 23484732Sdavemq if ((val == 0x43BC) && (val1 != 0)) { 23494732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 23504732Sdavemq "Cable not connected to peer or bad" 23514732Sdavemq " cable on port<%d>\n", portn)); 23524732Sdavemq } else if (val == 0x639C) { 23534732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23544732Sdavemq "Optical module (XFP) is bad or absent" 23554732Sdavemq " on port<%d>\n", portn)); 23564732Sdavemq } 23574732Sdavemq } 23584732Sdavemq #endif 23594732Sdavemq 23605572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>", 23615572Ssbehera portn)); 23625572Ssbehera return (NXGE_OK); 23635572Ssbehera 23645572Ssbehera fail: 23655572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23665572Ssbehera "nxge_BCM8704_xcvr_init: failed to initialize transceiver for " 23675572Ssbehera "port<%d>", nxgep->mac.portnum)); 23685572Ssbehera return (NXGE_ERROR); 23695572Ssbehera } 23705572Ssbehera 23715572Ssbehera /* Initialize the BCM 8706 Transceiver */ 23725572Ssbehera 23735572Ssbehera static nxge_status_t 23745572Ssbehera nxge_BCM8706_xcvr_init(p_nxge_t nxgep) 23755572Ssbehera { 23765572Ssbehera uint8_t phy_port_addr; 23775572Ssbehera phyxs_control_t phyxs_ctl; 23785572Ssbehera pcs_control_t pcs_ctl; 23795572Ssbehera uint32_t delay = 0; 23805572Ssbehera optics_dcntr_t op_ctr; 23815572Ssbehera nxge_status_t status = NXGE_OK; 23825572Ssbehera #ifdef NXGE_DEBUG 23835572Ssbehera uint8_t portn = nxgep->mac.portnum; 23845572Ssbehera #endif 23855572Ssbehera 23865572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>", 23875572Ssbehera portn)); 23885572Ssbehera 23895572Ssbehera phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 23905572Ssbehera 23915572Ssbehera /* Reset the transceiver */ 23925572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 23935572Ssbehera BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 23945572Ssbehera goto fail; 23955572Ssbehera 23965572Ssbehera phyxs_ctl.bits.reset = 1; 23975572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 23985572Ssbehera BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 23995572Ssbehera goto fail; 24005572Ssbehera do { 24015572Ssbehera drv_usecwait(500); 24025572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 24035572Ssbehera BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 24045572Ssbehera &phyxs_ctl.value)) != NXGE_OK) 24055572Ssbehera goto fail; 24065572Ssbehera delay++; 24075572Ssbehera } while ((phyxs_ctl.bits.reset) && (delay < 100)); 24085572Ssbehera 24095572Ssbehera if (delay == 100) { 24105572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 24115572Ssbehera "failed to reset Transceiver on port<%d>", portn)); 24125572Ssbehera status = NXGE_ERROR; 24135572Ssbehera goto fail; 24145572Ssbehera } 24155572Ssbehera 24165572Ssbehera NXGE_DELAY(1000000); 24175572Ssbehera 24185572Ssbehera /* Set BCM8706 Internal Loopback mode if necessary */ 24195572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 24205572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 24215572Ssbehera != NXGE_OK) 24225572Ssbehera goto fail; 24235572Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 24245572Ssbehera pcs_ctl.bits.loopback = 1; 24255572Ssbehera else 24265572Ssbehera pcs_ctl.bits.loopback = 0; 24275572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 24285572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 24295572Ssbehera != NXGE_OK) 24305572Ssbehera goto fail; 24315572Ssbehera 24325572Ssbehera /* Enable Tx and Rx LEDs to be driven by traffic */ 24335572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 24345572Ssbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 24355572Ssbehera &op_ctr.value)) != NXGE_OK) 24365572Ssbehera goto fail; 24375572Ssbehera op_ctr.bits.gpio_sel = 0x3; 24385572Ssbehera op_ctr.bits.res2 = 0x1; 24395572Ssbehera 24405572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 24415572Ssbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 24425572Ssbehera op_ctr.value)) != NXGE_OK) 24435572Ssbehera goto fail; 24445572Ssbehera 24455572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>", 24465572Ssbehera portn)); 24475572Ssbehera return (NXGE_OK); 24485572Ssbehera 24495572Ssbehera fail: 24505572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 24515572Ssbehera "nxge_BCM8706_xcvr_init: failed to initialize transceiver for " 24525572Ssbehera "port<%d>", nxgep->mac.portnum)); 24535572Ssbehera return (status); 24545572Ssbehera } 24555572Ssbehera 24566604Ssbehera #define CHK_STAT(x) status = (x); if (status != NXGE_OK) goto fail 24576604Ssbehera 24586604Ssbehera #define MRVL88X2011_RD(nxgep, port, d, r, p) \ 24596604Ssbehera CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p)) 24606604Ssbehera 24616604Ssbehera #define MRVL88X2011_WR(nxgep, port, d, r, p) \ 24626604Ssbehera CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p)) 24636604Ssbehera 24646604Ssbehera 24656604Ssbehera static void 24666604Ssbehera nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate) 24676604Ssbehera { 24686604Ssbehera uint16_t value; 24696604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 24706604Ssbehera 24716604Ssbehera if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR, 24726604Ssbehera MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) { 24736604Ssbehera value &= ~MRVL_88X2011_LED_BLK_MASK; 24746604Ssbehera value |= (rate << MRVL_88X2011_LED_BLK_SHIFT); 24756604Ssbehera (void) nxge_mdio_write(nxgep, phy, 24766604Ssbehera MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL, 24776604Ssbehera value); 24786604Ssbehera } 24796604Ssbehera } 24806604Ssbehera 24816604Ssbehera static nxge_status_t 24826604Ssbehera nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep) 24836604Ssbehera { 24846604Ssbehera nxge_status_t status; 24856604Ssbehera pcs_control_t pcs_ctl; 24866604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 24876604Ssbehera 24886604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 24896604Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value); 24906604Ssbehera 24916604Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 24926604Ssbehera pcs_ctl.bits.loopback = 1; 24936604Ssbehera else 24946604Ssbehera pcs_ctl.bits.loopback = 0; 24956604Ssbehera 24966604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 24976604Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value); 24986604Ssbehera 24996604Ssbehera fail: 25006604Ssbehera return (status); 25016604Ssbehera } 25026604Ssbehera 25036604Ssbehera 25046604Ssbehera static void 25056604Ssbehera nxge_mrvl88x2011_led(p_nxge_t nxgep, uint16_t val) 25066604Ssbehera { 25076604Ssbehera uint16_t val2; 25086604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 25096604Ssbehera 25106604Ssbehera val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val); 25116604Ssbehera val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, 25126604Ssbehera MRVL_88X2011_LED_CTL_MASK); 25136604Ssbehera val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val); 25146604Ssbehera 25156604Ssbehera if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR, 25166604Ssbehera MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) { 25176604Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 25186604Ssbehera "nxge_mrvl88x2011_led: nxge_mdio_write failed!!")); 25196604Ssbehera } 25206604Ssbehera } 25216604Ssbehera 25226604Ssbehera 25236604Ssbehera static nxge_status_t 25246604Ssbehera nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep) 25256604Ssbehera { 25266604Ssbehera uint8_t phy; 25276604Ssbehera nxge_status_t status; 25286604Ssbehera uint16_t clk; 25296604Ssbehera 25306604Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn; 25316604Ssbehera 25326604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 25336604Ssbehera "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>", 25346604Ssbehera nxgep->mac.portnum, phy)); 25356604Ssbehera 25366604Ssbehera /* Set LED functions */ 25376604Ssbehera nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS); 25386604Ssbehera /* PCS activity */ 25396604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT); 25406604Ssbehera 25416604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 25426604Ssbehera MRVL_88X2011_GEN_CTL, &clk); 25436604Ssbehera clk |= MRVL_88X2011_ENA_XFPREFCLK; 25446604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 25456604Ssbehera MRVL_88X2011_GEN_CTL, clk); 25466604Ssbehera 25476604Ssbehera /* Set internal loopback mode if necessary */ 25486604Ssbehera 25496604Ssbehera CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep)); 25506604Ssbehera 25516604Ssbehera /* Enable PMD */ 25526604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 25536604Ssbehera MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX); 25546604Ssbehera 25556604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK")); 25566604Ssbehera 25576604Ssbehera fail: 25586604Ssbehera return (status); 25596604Ssbehera } 25606604Ssbehera 25616604Ssbehera 25626604Ssbehera 25635572Ssbehera /* Initialize the 10G Transceiver */ 25645572Ssbehera 25655572Ssbehera static nxge_status_t 25665572Ssbehera nxge_10G_xcvr_init(p_nxge_t nxgep) 25675572Ssbehera { 25685572Ssbehera p_nxge_stats_t statsp; 25696439Sml29623 p_nxge_param_t param_arr = nxgep->param_arr; 25705572Ssbehera nxge_status_t status = NXGE_OK; 25715572Ssbehera #ifdef NXGE_DEBUG 25725572Ssbehera uint8_t portn = nxgep->mac.portnum; 25735572Ssbehera #endif 25745572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 25755572Ssbehera portn)); 25765572Ssbehera 25775572Ssbehera statsp = nxgep->statsp; 25785572Ssbehera 2579*9599Stc99174@train /* Disable Link LEDs, with or without PHY */ 2580*9599Stc99174@train if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 25815572Ssbehera goto done; 2582*9599Stc99174@train 2583*9599Stc99174@train /* Skip MDIO, if PHY absent */ 2584*9599Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) { 2585*9599Stc99174@train goto done; 2586*9599Stc99174@train } 25875572Ssbehera 25885572Ssbehera /* Set Clause 45 */ 25895572Ssbehera npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 25905572Ssbehera 25915572Ssbehera switch (nxgep->chip_id) { 25925572Ssbehera case BCM8704_CHIP_ID: 25936835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 25945572Ssbehera "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id)); 25955572Ssbehera status = nxge_BCM8704_xcvr_init(nxgep); 25965572Ssbehera break; 25975572Ssbehera case BCM8706_CHIP_ID: 25986835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 25995572Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id)); 26005572Ssbehera status = nxge_BCM8706_xcvr_init(nxgep); 26015572Ssbehera break; 26026604Ssbehera case MRVL88X201X_CHIP_ID: 26036835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 26046604Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id)); 26056604Ssbehera status = nxge_mrvl88x2011_xcvr_init(nxgep); 26066604Ssbehera break; 26075572Ssbehera default: 26085572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: " 26095572Ssbehera "Unknown chip ID 0x%x for 10G xcvr addr[%d]", 26105572Ssbehera nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn)); 26115572Ssbehera goto fail; 26125572Ssbehera } 26135572Ssbehera 26145572Ssbehera if (status != NXGE_OK) { 26155572Ssbehera goto fail; 26165572Ssbehera } 26174977Sraghus done: 26184732Sdavemq statsp->mac_stats.cap_10gfdx = 1; 26194732Sdavemq statsp->mac_stats.lp_cap_10gfdx = 1; 26206439Sml29623 statsp->mac_stats.adv_cap_asmpause = 26216439Sml29623 param_arr[param_anar_asmpause].value; 26226439Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 26234732Sdavemq 26244732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 26254732Sdavemq portn)); 26264732Sdavemq return (NXGE_OK); 26274732Sdavemq 26284732Sdavemq fail: 26295572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 26304732Sdavemq "nxge_10G_xcvr_init: failed to initialize transceiver for " 26315572Ssbehera "port<%d>", nxgep->mac.portnum)); 26325572Ssbehera return (NXGE_ERROR); 26334732Sdavemq } 26344732Sdavemq 26354732Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */ 26364732Sdavemq 26374732Sdavemq static nxge_status_t 26384732Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep) 26394732Sdavemq { 26404732Sdavemq p_nxge_param_t param_arr = nxgep->param_arr; 26414732Sdavemq p_nxge_stats_t statsp = nxgep->statsp; 26424732Sdavemq nxge_status_t status = NXGE_OK; 26434732Sdavemq 26444977Sraghus if (nxgep->mac.portmode == PORT_1G_SERDES) { 26454977Sraghus statsp->mac_stats.cap_1000fdx = 26464977Sraghus param_arr[param_anar_1000fdx].value; 26474977Sraghus goto done; 26484977Sraghus } 26494977Sraghus 26504732Sdavemq /* Set Clause 22 */ 26514732Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 26524732Sdavemq 26534732Sdavemq /* Set capability flags */ 26544732Sdavemq statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value; 26554977Sraghus if ((nxgep->mac.portmode == PORT_1G_COPPER) || 26564977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER)) { 26574977Sraghus statsp->mac_stats.cap_100fdx = 26584977Sraghus param_arr[param_anar_100fdx].value; 26594977Sraghus statsp->mac_stats.cap_10fdx = 26604977Sraghus param_arr[param_anar_10fdx].value; 26614977Sraghus } 26624732Sdavemq 26634732Sdavemq status = nxge_mii_xcvr_init(nxgep); 26644977Sraghus done: 26654732Sdavemq return (status); 26664732Sdavemq } 26674732Sdavemq 26686835Syc148097 /* 26696835Syc148097 * Although the Teranetics copper transceiver (TN1010) does not need 26706835Syc148097 * to be initialized by the driver for passing packets, this funtion 26716835Syc148097 * initializes the members of nxgep->statsp->mac_stats struct for 26726835Syc148097 * kstat based on the value of nxgep->statsp->ports_stats.lb_mode. 26736835Syc148097 * It also configures the TN1010 for PHY loopback to support SunVTS. 26746835Syc148097 * 26756835Syc148097 * TN1010 only has the option to disable advertisement for the 10G 26766835Syc148097 * mode. So we can set it to either Dual Mode or 1G Only mode but 26776835Syc148097 * can't set it to 10G Only mode. 26786835Syc148097 * 26796835Syc148097 * ndd -set command can set the following 6 speed/duplex related parameters. 26806835Syc148097 * 26816835Syc148097 * ---------------------------------------------------------------- 26826835Syc148097 * ndd -set /dev/nxgeX param n kstat nxge:X | grep param 26836835Syc148097 * ---------------------------------------------------------------- 26846835Syc148097 * adv_autoneg_cap kstat nxge:1 | grep adv_cap_autoneg 26856835Syc148097 * adv_10gfdx_cap 26866835Syc148097 * adv_1000fdx_cap kstat nxge:1 | grep adv_cap_1000fdx 26876835Syc148097 * adv_100fdx_cap kstat nxge:1 | grep adv_cap_100fdx 26886835Syc148097 * adv_10fdx_cap kstat nxge:1 | grep adv_cap_10fdx 26896835Syc148097 * adv_pause_cap kstat nxge:1 | grep adv_cap_pause 26906835Syc148097 * ---------------------------------------------------------------- 26916835Syc148097 */ 26926835Syc148097 static nxge_status_t 26936835Syc148097 nxge_tn1010_xcvr_init(p_nxge_t nxgep) 26946835Syc148097 { 26956835Syc148097 p_nxge_param_t param_arr; 26966835Syc148097 p_nxge_stats_t statsp; 26976835Syc148097 tn1010_pcs_ctrl_t tn1010_pcs_ctrl; 26986835Syc148097 uint16_t speed; 26996835Syc148097 uint8_t phy_port_addr; 27006835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 27016835Syc148097 int status = NXGE_OK; 27026835Syc148097 27036835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init")); 27046835Syc148097 27056835Syc148097 param_arr = nxgep->param_arr; 27066835Syc148097 statsp = nxgep->statsp; 27076835Syc148097 27086835Syc148097 /* 27096835Syc148097 * Initialize the xcvr statistics which are NOT controlled by ndd 27106835Syc148097 */ 27116835Syc148097 statsp->mac_stats.cap_autoneg = 1; /* TN1010 autoneg is always on */ 27126835Syc148097 statsp->mac_stats.cap_100T4 = 0; 27136835Syc148097 27146835Syc148097 /* 27156835Syc148097 * Read the TN1010 link speed and initialize capabilities kstat. Note 27166835Syc148097 * that function nxge_check_tn1010_link repeatedly invoked by the 27176835Syc148097 * timer will update link_speed real time. 27186835Syc148097 */ 27196835Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) { 27206835Syc148097 goto fail; 27216835Syc148097 } 27226835Syc148097 if (speed == TN1010_SPEED_1G) { 27236835Syc148097 statsp->mac_stats.cap_10gfdx = 0; 27246835Syc148097 } else { 27256835Syc148097 statsp->mac_stats.cap_10gfdx = 1; 27266835Syc148097 } 27276835Syc148097 27286835Syc148097 /* Whether we are in 1G or 10G mode, we always have the 1G capability */ 27296835Syc148097 statsp->mac_stats.cap_1000fdx = 1; 27306835Syc148097 27316835Syc148097 /* TN1010 is not able to operate in the following states */ 27326835Syc148097 statsp->mac_stats.cap_1000hdx = 0; 27336835Syc148097 statsp->mac_stats.cap_100fdx = 0; 27346835Syc148097 statsp->mac_stats.cap_100hdx = 0; 27356835Syc148097 statsp->mac_stats.cap_10fdx = 0; 27366835Syc148097 statsp->mac_stats.cap_10hdx = 0; 27376835Syc148097 27386835Syc148097 /* param_anar_pause can be modified by ndd -set */ 27396835Syc148097 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 27406835Syc148097 27416835Syc148097 /* 27426835Syc148097 * The following 4 lines actually overwrites what ever the ndd command 27436835Syc148097 * has set. For example, by command 27446835Syc148097 * ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1) 27456835Syc148097 * we could set param_arr[param_autoneg].value to n. However, because 27466835Syc148097 * here we assign constants to these parameters, whatever we set with 27476835Syc148097 * the "ndd -set" command will be replaced. So command 27486835Syc148097 * kstat nxge:X | grep param 27496835Syc148097 * will always show those constant values. In other words, the 27506835Syc148097 * "ndd -set" command can NOT change the values of these 4 parameters 27516835Syc148097 * even though the command appears to be successful. 27526835Syc148097 * 27536835Syc148097 * Note: TN1010 auto negotiation is always enabled. 27546835Syc148097 */ 27556835Syc148097 statsp->mac_stats.adv_cap_autoneg 27566835Syc148097 = param_arr[param_autoneg].value = 1; 27576835Syc148097 statsp->mac_stats.adv_cap_1000fdx 27586835Syc148097 = param_arr[param_anar_1000fdx].value = 1; 27596835Syc148097 statsp->mac_stats.adv_cap_100fdx 27606835Syc148097 = param_arr[param_anar_100fdx].value = 0; 27616835Syc148097 statsp->mac_stats.adv_cap_10fdx 27626835Syc148097 = param_arr[param_anar_10fdx].value = 0; 27636835Syc148097 27646835Syc148097 /* 27656835Syc148097 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as 27666835Syc148097 * defined in nxge_param_arr[], therefore they are not seen by the 27676835Syc148097 * "ndd -get" command and can not be changed by ndd. We just set 27686835Syc148097 * them (both ndd param and kstat values) to constant 0 because TN1010 27696835Syc148097 * does not support those speeds. 27706835Syc148097 */ 27716835Syc148097 statsp->mac_stats.adv_cap_100T4 27726835Syc148097 = param_arr[param_anar_100T4].value = 0; 27736835Syc148097 statsp->mac_stats.adv_cap_1000hdx 27746835Syc148097 = param_arr[param_anar_1000hdx].value = 0; 27756835Syc148097 statsp->mac_stats.adv_cap_100hdx 27766835Syc148097 = param_arr[param_anar_100hdx].value = 0; 27776835Syc148097 statsp->mac_stats.adv_cap_10hdx 27786835Syc148097 = param_arr[param_anar_10hdx].value = 0; 27796835Syc148097 27806835Syc148097 /* 27816835Syc148097 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified 27826835Syc148097 * by ndd 27836835Syc148097 */ 27846835Syc148097 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 27856835Syc148097 27866835Syc148097 /* 27876835Syc148097 * nxge_param_arr[] defines the adv_cap_asmpause with type 27886835Syc148097 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the 27896835Syc148097 * "ndd -get" command and can not be changed by ndd. Here we do not 27906835Syc148097 * assign a constant to it so the default value defined in 27916835Syc148097 * nxge_param_arr[] will be used to set the parameter and 27926835Syc148097 * will be shown by the kstat. 27936835Syc148097 */ 27946835Syc148097 statsp->mac_stats.adv_cap_asmpause 27956835Syc148097 = param_arr[param_anar_asmpause].value; 27966835Syc148097 27976835Syc148097 /* 27986835Syc148097 * Initialize the link statistics. 27996835Syc148097 */ 28006835Syc148097 statsp->mac_stats.link_T4 = 0; 28016835Syc148097 statsp->mac_stats.link_asmpause = 0; 28026835Syc148097 statsp->mac_stats.link_pause = 0; 28036835Syc148097 if (speed == TN1010_SPEED_1G) { 28046835Syc148097 statsp->mac_stats.link_speed = 1000; 28056835Syc148097 statsp->mac_stats.link_duplex = 2; /* Full duplex */ 28066835Syc148097 statsp->mac_stats.link_up = 1; 28076835Syc148097 } else { 28086835Syc148097 statsp->mac_stats.link_speed = 10000; 28096835Syc148097 statsp->mac_stats.link_duplex = 2; 28106835Syc148097 statsp->mac_stats.link_up = 1; 28116835Syc148097 } 28126835Syc148097 28136835Syc148097 /* 28146835Syc148097 * Because TN1010 does not have a link partner register, to 28156835Syc148097 * figure out the link partner's capabilities is tricky. Here we 28166835Syc148097 * just set the kstat based on our knowledge about the partner 28176835Syc148097 * (The partner must support auto-neg because auto-negotiation 28186835Syc148097 * has completed, it must support 1G or 10G because that is the 28196835Syc148097 * negotiated speed we are using.) 28206835Syc148097 * 28216835Syc148097 * Note: Current kstat does not show lp_cap_10gfdx and 28226835Syc148097 * lp_cap_10ghdx. 28236835Syc148097 */ 28246835Syc148097 if (speed == TN1010_SPEED_1G) { 28256835Syc148097 statsp->mac_stats.lp_cap_1000fdx = 1; 28266835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0; 28276835Syc148097 } else { 28286835Syc148097 statsp->mac_stats.lp_cap_1000fdx = 0; 28296835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 1; 28306835Syc148097 } 28316835Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0; 28326835Syc148097 statsp->mac_stats.lp_cap_1000hdx = 0; 28336835Syc148097 statsp->mac_stats.lp_cap_100fdx = 0; 28346835Syc148097 statsp->mac_stats.lp_cap_100hdx = 0; 28356835Syc148097 statsp->mac_stats.lp_cap_10fdx = 0; 28366835Syc148097 statsp->mac_stats.lp_cap_10hdx = 0; 28376835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0; 28386835Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0; 28396835Syc148097 statsp->mac_stats.lp_cap_100T4 = 0; 28406835Syc148097 statsp->mac_stats.lp_cap_autoneg = 1; 28416835Syc148097 statsp->mac_stats.lp_cap_asmpause = 0; 28426835Syc148097 statsp->mac_stats.lp_cap_pause = 0; 28436835Syc148097 28446835Syc148097 /* Handle PHY loopback for SunVTS loopback test */ 28456835Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 28466835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 28476835Syc148097 28486835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 28496835Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG, 28506835Syc148097 &tn1010_pcs_ctrl.value)) != NXGE_OK) { 28516835Syc148097 goto fail; 28526835Syc148097 } 28536835Syc148097 if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) || 28546835Syc148097 (statsp->port_stats.lb_mode == nxge_lb_phy10g)) { 28556835Syc148097 tn1010_pcs_ctrl.bits.loopback = 1; 28566835Syc148097 } else { 28576835Syc148097 tn1010_pcs_ctrl.bits.loopback = 0; 28586835Syc148097 } 28596835Syc148097 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 28606835Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG, 28616835Syc148097 tn1010_pcs_ctrl.value)) != NXGE_OK) { 28626835Syc148097 goto fail; 28636835Syc148097 } 28646835Syc148097 28656835Syc148097 statsp->mac_stats.xcvr_inits++; 28666835Syc148097 28676835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 28686835Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status)); 28696835Syc148097 return (status); 28706835Syc148097 fail: 28716835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 28726835Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status)); 28736835Syc148097 return (status); 28746835Syc148097 } 28756835Syc148097 28764732Sdavemq /* Initialize transceiver */ 28774732Sdavemq 28784732Sdavemq nxge_status_t 28794732Sdavemq nxge_xcvr_init(p_nxge_t nxgep) 28804732Sdavemq { 28814732Sdavemq p_nxge_stats_t statsp; 28824732Sdavemq #ifdef NXGE_DEBUG 28834732Sdavemq uint8_t portn; 28844732Sdavemq #endif 28854732Sdavemq 28864732Sdavemq nxge_status_t status = NXGE_OK; 28874732Sdavemq #ifdef NXGE_DEBUG 28884732Sdavemq portn = nxgep->mac.portnum; 28894732Sdavemq #endif 28903859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 28913859Sml29623 statsp = nxgep->statsp; 28923859Sml29623 28933859Sml29623 /* 28946835Syc148097 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will 28956835Syc148097 * modify mac_stats. 28963859Sml29623 */ 28973859Sml29623 statsp->mac_stats.cap_autoneg = 0; 28983859Sml29623 statsp->mac_stats.cap_100T4 = 0; 28993859Sml29623 statsp->mac_stats.cap_100fdx = 0; 29003859Sml29623 statsp->mac_stats.cap_100hdx = 0; 29013859Sml29623 statsp->mac_stats.cap_10fdx = 0; 29023859Sml29623 statsp->mac_stats.cap_10hdx = 0; 29033859Sml29623 statsp->mac_stats.cap_asmpause = 0; 29043859Sml29623 statsp->mac_stats.cap_pause = 0; 29053859Sml29623 statsp->mac_stats.cap_1000fdx = 0; 29063859Sml29623 statsp->mac_stats.cap_1000hdx = 0; 29073859Sml29623 statsp->mac_stats.cap_10gfdx = 0; 29083859Sml29623 statsp->mac_stats.cap_10ghdx = 0; 29093859Sml29623 29103859Sml29623 /* 29113859Sml29623 * Initialize the link statistics. 29123859Sml29623 */ 29133859Sml29623 statsp->mac_stats.link_T4 = 0; 29143859Sml29623 statsp->mac_stats.link_asmpause = 0; 29153859Sml29623 statsp->mac_stats.link_pause = 0; 29163859Sml29623 29174732Sdavemq if (nxgep->xcvr.xcvr_init) { 29184732Sdavemq status = nxgep->xcvr.xcvr_init(nxgep); 29193859Sml29623 if (status != NXGE_OK) 29203859Sml29623 goto fail; 29214732Sdavemq statsp->mac_stats.xcvr_inits++; 29223859Sml29623 } 29233859Sml29623 29244732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", 29254732Sdavemq portn)); 29263859Sml29623 return (NXGE_OK); 29273859Sml29623 29283859Sml29623 fail: 29293859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 29304732Sdavemq "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 29314732Sdavemq portn)); 29323859Sml29623 return (status); 29333859Sml29623 } 29343859Sml29623 29354977Sraghus /* Look for transceiver type */ 29364977Sraghus 29374977Sraghus nxge_status_t 29384977Sraghus nxge_xcvr_find(p_nxge_t nxgep) 29394977Sraghus { 29405196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", 29415196Ssbehera nxgep->mac.portnum)); 29424977Sraghus 29434977Sraghus if (nxge_get_xcvr_type(nxgep) != NXGE_OK) 29444977Sraghus return (NXGE_ERROR); 29454977Sraghus 29464977Sraghus if (nxge_setup_xcvr_table(nxgep) != NXGE_OK) 29474977Sraghus return (NXGE_ERROR); 29484977Sraghus 29494977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d", 29504977Sraghus nxgep->statsp->mac_stats.xcvr_inuse)); 29514977Sraghus return (NXGE_OK); 29524977Sraghus } 29533859Sml29623 29543859Sml29623 /* Initialize the TxMAC sub-block */ 29553859Sml29623 29563859Sml29623 nxge_status_t 29573859Sml29623 nxge_tx_mac_init(p_nxge_t nxgep) 29583859Sml29623 { 29593859Sml29623 npi_attr_t ap; 29603859Sml29623 uint8_t portn; 29613859Sml29623 nxge_port_mode_t portmode; 29623859Sml29623 nxge_port_t portt; 29633859Sml29623 npi_handle_t handle; 29643859Sml29623 npi_status_t rs = NPI_SUCCESS; 29653859Sml29623 29663859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 29673859Sml29623 portt = nxgep->mac.porttype; 29683859Sml29623 handle = nxgep->npi_handle; 29693859Sml29623 portmode = nxgep->mac.portmode; 29703859Sml29623 29713859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 29726929Smisaki portn)); 29733859Sml29623 /* Set Max and Min Frame Size */ 29746439Sml29623 /* 29756439Sml29623 * Use maxframesize to configure the hardware maxframe size 29766835Syc148097 * and minframesize to configure the hardware minframe size. 29776439Sml29623 */ 29786439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 29796439Sml29623 "==> nxge_tx_mac_init: port<%d> " 29806439Sml29623 "min framesize %d max framesize %d ", 29816439Sml29623 nxgep->mac.minframesize, 29826439Sml29623 nxgep->mac.maxframesize, 29836439Sml29623 portn)); 29846439Sml29623 29856439Sml29623 SET_MAC_ATTR2(handle, ap, portn, 29866439Sml29623 MAC_PORT_FRAME_SIZE, 29876439Sml29623 nxgep->mac.minframesize, 29886439Sml29623 nxgep->mac.maxframesize, 29896439Sml29623 rs); 29903859Sml29623 if (rs != NPI_SUCCESS) 29913859Sml29623 goto fail; 29923859Sml29623 29933859Sml29623 if (portt == PORT_TYPE_XMAC) { 29943859Sml29623 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 29956929Smisaki 0)) != NPI_SUCCESS) 29963859Sml29623 goto fail; 29973859Sml29623 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 29983859Sml29623 if ((portmode == PORT_10G_FIBER) || 29994977Sraghus (portmode == PORT_10G_COPPER) || 30006835Syc148097 (portmode == PORT_10G_TN1010) || 3001*9599Stc99174@train (portmode == PORT_HSP_MODE) || 30024977Sraghus (portmode == PORT_10G_SERDES)) { 30033859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 30046929Smisaki XGMII_IPG_12_15, rs); 30053859Sml29623 if (rs != NPI_SUCCESS) 30063859Sml29623 goto fail; 30073859Sml29623 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 30083859Sml29623 } else { 30093859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 30106929Smisaki MII_GMII_IPG_12, rs); 30113859Sml29623 if (rs != NPI_SUCCESS) 30123859Sml29623 goto fail; 30133859Sml29623 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 30143859Sml29623 } 30153859Sml29623 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 30166929Smisaki CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 30173859Sml29623 goto fail; 30183859Sml29623 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 30193859Sml29623 nxgep->mac.maxburstsize = 0; /* not programmable */ 30203859Sml29623 nxgep->mac.ctrltype = 0; /* not programmable */ 30213859Sml29623 nxgep->mac.pa_size = 0; /* not programmable */ 30223859Sml29623 30233859Sml29623 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 30246929Smisaki != NPI_SUCCESS) 30253859Sml29623 goto fail; 30263859Sml29623 30273859Sml29623 } else { 30283859Sml29623 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 30296929Smisaki 0)) != NPI_SUCCESS) 30303859Sml29623 goto fail; 30313859Sml29623 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 30323859Sml29623 30333859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 30346929Smisaki rs); 30353859Sml29623 if (rs != NPI_SUCCESS) 30363859Sml29623 goto fail; 30373859Sml29623 nxgep->mac.ctrltype = 0x8808; 30383859Sml29623 30393859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 30403859Sml29623 if (rs != NPI_SUCCESS) 30413859Sml29623 goto fail; 30423859Sml29623 nxgep->mac.pa_size = 0x7; 30433859Sml29623 30443859Sml29623 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 30456929Smisaki CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 30463859Sml29623 goto fail; 30473859Sml29623 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 30483859Sml29623 } 30493859Sml29623 30503859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 30516929Smisaki portn)); 30523859Sml29623 30533859Sml29623 return (NXGE_OK); 30543859Sml29623 fail: 30553859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 30566929Smisaki "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn)); 30573859Sml29623 30583859Sml29623 return (NXGE_ERROR | rs); 30593859Sml29623 } 30603859Sml29623 30616495Sspeer 30623859Sml29623 /* Initialize the RxMAC sub-block */ 30633859Sml29623 30643859Sml29623 nxge_status_t 30653859Sml29623 nxge_rx_mac_init(p_nxge_t nxgep) 30663859Sml29623 { 30673859Sml29623 npi_attr_t ap; 30683859Sml29623 uint32_t i; 30693859Sml29623 uint16_t hashtab_e; 30703859Sml29623 p_hash_filter_t hash_filter; 30713859Sml29623 nxge_port_t portt; 30723859Sml29623 uint8_t portn; 30733859Sml29623 npi_handle_t handle; 30743859Sml29623 npi_status_t rs = NPI_SUCCESS; 30753859Sml29623 uint16_t *addr16p; 30763859Sml29623 uint16_t addr0, addr1, addr2; 30773859Sml29623 xmac_rx_config_t xconfig; 30783859Sml29623 bmac_rx_config_t bconfig; 30793859Sml29623 30803859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 30813859Sml29623 30823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 30836929Smisaki portn)); 30843859Sml29623 handle = nxgep->npi_handle; 30853859Sml29623 portt = nxgep->mac.porttype; 30863859Sml29623 30873859Sml29623 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 30883859Sml29623 addr0 = ntohs(addr16p[2]); 30893859Sml29623 addr1 = ntohs(addr16p[1]); 30903859Sml29623 addr2 = ntohs(addr16p[0]); 30913859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 30926929Smisaki rs); 30933859Sml29623 30943859Sml29623 if (rs != NPI_SUCCESS) 30953859Sml29623 goto fail; 30963859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 30973859Sml29623 if (rs != NPI_SUCCESS) 30983859Sml29623 goto fail; 30993859Sml29623 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 31003859Sml29623 if (rs != NPI_SUCCESS) 31013859Sml29623 goto fail; 31023859Sml29623 31033859Sml29623 /* 31043859Sml29623 * Load the multicast hash filter bits. 31053859Sml29623 */ 31063859Sml29623 hash_filter = nxgep->hash_filter; 31073859Sml29623 for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 31083859Sml29623 if (hash_filter != NULL) { 31093859Sml29623 hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 31106929Smisaki (NMCFILTER_REGS - 1) - i]; 31113859Sml29623 } else { 31123859Sml29623 hashtab_e = 0; 31133859Sml29623 } 31143859Sml29623 31153859Sml29623 if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 31166929Smisaki (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 31173859Sml29623 goto fail; 31183859Sml29623 } 31193859Sml29623 31203859Sml29623 if (portt == PORT_TYPE_XMAC) { 31213859Sml29623 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 31226929Smisaki 0)) != NPI_SUCCESS) 31233859Sml29623 goto fail; 31243859Sml29623 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 31253859Sml29623 31263859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep); 31273859Sml29623 31283859Sml29623 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 31296929Smisaki CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 31306929Smisaki ~CFG_XMAC_RX_STRIP_CRC; 31313859Sml29623 31323859Sml29623 if (nxgep->filter.all_phys_cnt != 0) 31333859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 31343859Sml29623 31353859Sml29623 if (nxgep->filter.all_multicast_cnt != 0) 31363859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 31373859Sml29623 31383859Sml29623 xconfig |= CFG_XMAC_RX_HASH_FILTER; 31393859Sml29623 31403859Sml29623 if ((rs = npi_xmac_rx_config(handle, INIT, portn, 31416929Smisaki xconfig)) != NPI_SUCCESS) 31423859Sml29623 goto fail; 31433859Sml29623 nxgep->mac.rx_config = xconfig; 31443859Sml29623 31453859Sml29623 /* Comparison of mac unique address is always enabled on XMAC */ 31463859Sml29623 31473859Sml29623 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 31486929Smisaki != NPI_SUCCESS) 31493859Sml29623 goto fail; 31503859Sml29623 } else { 31513859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep); 31523859Sml29623 31533859Sml29623 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 31546929Smisaki 0) != NPI_SUCCESS) 31553859Sml29623 goto fail; 31563859Sml29623 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 31573859Sml29623 31583859Sml29623 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 31596929Smisaki ~CFG_BMAC_RX_STRIP_CRC; 31603859Sml29623 31613859Sml29623 if (nxgep->filter.all_phys_cnt != 0) 31623859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 31633859Sml29623 31643859Sml29623 if (nxgep->filter.all_multicast_cnt != 0) 31653859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 31663859Sml29623 31673859Sml29623 bconfig |= CFG_BMAC_RX_HASH_FILTER; 31683859Sml29623 if ((rs = npi_bmac_rx_config(handle, INIT, portn, 31696929Smisaki bconfig)) != NPI_SUCCESS) 31703859Sml29623 goto fail; 31713859Sml29623 nxgep->mac.rx_config = bconfig; 31723859Sml29623 31733859Sml29623 /* Always enable comparison of mac unique address */ 31743859Sml29623 if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 31756929Smisaki != NPI_SUCCESS) 31763859Sml29623 goto fail; 31773859Sml29623 } 31783859Sml29623 31793859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 31806929Smisaki portn)); 31813859Sml29623 31823859Sml29623 return (NXGE_OK); 31833859Sml29623 31843859Sml29623 fail: 31853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 31866929Smisaki "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn)); 31873859Sml29623 31883859Sml29623 return (NXGE_ERROR | rs); 31893859Sml29623 } 31903859Sml29623 31913859Sml29623 /* Enable TXMAC */ 31923859Sml29623 31933859Sml29623 nxge_status_t 31943859Sml29623 nxge_tx_mac_enable(p_nxge_t nxgep) 31953859Sml29623 { 31963859Sml29623 npi_handle_t handle; 31973859Sml29623 npi_status_t rs = NPI_SUCCESS; 31983859Sml29623 nxge_status_t status = NXGE_OK; 31993859Sml29623 32003859Sml29623 handle = nxgep->npi_handle; 32013859Sml29623 32023859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 32036929Smisaki nxgep->mac.portnum)); 32043859Sml29623 32053859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 32063859Sml29623 goto fail; 32073859Sml29623 32083859Sml29623 /* based on speed */ 32093859Sml29623 nxgep->msg_min = ETHERMIN; 32103859Sml29623 32113859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 32123859Sml29623 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 32136929Smisaki CFG_XMAC_TX)) != NPI_SUCCESS) 32143859Sml29623 goto fail; 32153859Sml29623 } else { 32163859Sml29623 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 32176929Smisaki CFG_BMAC_TX)) != NPI_SUCCESS) 32183859Sml29623 goto fail; 32193859Sml29623 } 32203859Sml29623 32213859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 32226929Smisaki nxgep->mac.portnum)); 32233859Sml29623 32243859Sml29623 return (NXGE_OK); 32253859Sml29623 fail: 32263859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 32276929Smisaki "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 32286929Smisaki nxgep->mac.portnum)); 32293859Sml29623 if (rs != NPI_SUCCESS) 32303859Sml29623 return (NXGE_ERROR | rs); 32313859Sml29623 else 32323859Sml29623 return (status); 32333859Sml29623 } 32343859Sml29623 32353859Sml29623 /* Disable TXMAC */ 32363859Sml29623 32373859Sml29623 nxge_status_t 32383859Sml29623 nxge_tx_mac_disable(p_nxge_t nxgep) 32393859Sml29623 { 32403859Sml29623 npi_handle_t handle; 32413859Sml29623 npi_status_t rs = NPI_SUCCESS; 32423859Sml29623 32436495Sspeer if (isLDOMguest(nxgep)) 32446495Sspeer return (NXGE_OK); 32456495Sspeer 32463859Sml29623 handle = nxgep->npi_handle; 32473859Sml29623 32483859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 32496929Smisaki nxgep->mac.portnum)); 32503859Sml29623 32513859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 32523859Sml29623 if ((rs = npi_xmac_tx_config(handle, DISABLE, 32536929Smisaki nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 32543859Sml29623 goto fail; 32553859Sml29623 } else { 32563859Sml29623 if ((rs = npi_bmac_tx_config(handle, DISABLE, 32576929Smisaki nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 32583859Sml29623 goto fail; 32593859Sml29623 } 32603859Sml29623 32613859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 32626929Smisaki nxgep->mac.portnum)); 32633859Sml29623 return (NXGE_OK); 32643859Sml29623 fail: 32653859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 32666929Smisaki "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 32676929Smisaki nxgep->mac.portnum)); 32683859Sml29623 return (NXGE_ERROR | rs); 32693859Sml29623 } 32703859Sml29623 32713859Sml29623 /* Enable RXMAC */ 32723859Sml29623 32733859Sml29623 nxge_status_t 32743859Sml29623 nxge_rx_mac_enable(p_nxge_t nxgep) 32753859Sml29623 { 32763859Sml29623 npi_handle_t handle; 32773859Sml29623 uint8_t portn; 32783859Sml29623 npi_status_t rs = NPI_SUCCESS; 32793859Sml29623 nxge_status_t status = NXGE_OK; 32803859Sml29623 32816495Sspeer /* This is a service-domain-only activity. */ 32826495Sspeer if (isLDOMguest(nxgep)) 32836495Sspeer return (status); 32846495Sspeer 32853859Sml29623 handle = nxgep->npi_handle; 32863859Sml29623 portn = nxgep->mac.portnum; 32873859Sml29623 32883859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 32896929Smisaki portn)); 32903859Sml29623 32913859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 32923859Sml29623 goto fail; 32933859Sml29623 32943859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 32953859Sml29623 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 32966495Sspeer CFG_XMAC_RX)) != NPI_SUCCESS) 32973859Sml29623 goto fail; 32983859Sml29623 } else { 32993859Sml29623 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 33006495Sspeer CFG_BMAC_RX)) != NPI_SUCCESS) 33013859Sml29623 goto fail; 33023859Sml29623 } 33033859Sml29623 33046495Sspeer NXGE_DEBUG_MSG((nxgep, MAC_CTL, 33056495Sspeer "<== nxge_rx_mac_enable: port<%d>", portn)); 33063859Sml29623 33073859Sml29623 return (NXGE_OK); 33083859Sml29623 fail: 33093859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33106495Sspeer "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn)); 33113859Sml29623 33123859Sml29623 if (rs != NPI_SUCCESS) 33133859Sml29623 return (NXGE_ERROR | rs); 33143859Sml29623 else 33153859Sml29623 return (status); 33163859Sml29623 } 33173859Sml29623 33183859Sml29623 /* Disable RXMAC */ 33193859Sml29623 33203859Sml29623 nxge_status_t 33213859Sml29623 nxge_rx_mac_disable(p_nxge_t nxgep) 33223859Sml29623 { 33233859Sml29623 npi_handle_t handle; 33243859Sml29623 uint8_t portn; 33253859Sml29623 npi_status_t rs = NPI_SUCCESS; 33263859Sml29623 33276495Sspeer /* If we are a guest domain driver, don't bother. */ 33286495Sspeer if (isLDOMguest(nxgep)) 33296495Sspeer return (NXGE_OK); 33306495Sspeer 33313859Sml29623 handle = nxgep->npi_handle; 33323859Sml29623 portn = nxgep->mac.portnum; 33333859Sml29623 33343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 33356929Smisaki portn)); 33363859Sml29623 33373859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 33383859Sml29623 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 33396929Smisaki CFG_XMAC_RX)) != NPI_SUCCESS) 33403859Sml29623 goto fail; 33413859Sml29623 } else { 33423859Sml29623 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 33436929Smisaki CFG_BMAC_RX)) != NPI_SUCCESS) 33443859Sml29623 goto fail; 33453859Sml29623 } 33463859Sml29623 33473859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 33486929Smisaki portn)); 33493859Sml29623 return (NXGE_OK); 33503859Sml29623 fail: 33513859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33526929Smisaki "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn)); 33533859Sml29623 33543859Sml29623 return (NXGE_ERROR | rs); 33553859Sml29623 } 33563859Sml29623 33573859Sml29623 /* Reset TXMAC */ 33583859Sml29623 33593859Sml29623 nxge_status_t 33603859Sml29623 nxge_tx_mac_reset(p_nxge_t nxgep) 33613859Sml29623 { 33623859Sml29623 npi_handle_t handle; 33633859Sml29623 uint8_t portn; 33643859Sml29623 npi_status_t rs = NPI_SUCCESS; 33653859Sml29623 33663859Sml29623 handle = nxgep->npi_handle; 33673859Sml29623 portn = nxgep->mac.portnum; 33683859Sml29623 33693859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 33706929Smisaki portn)); 33713859Sml29623 33723859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 33733859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 33743859Sml29623 != NPI_SUCCESS) 33753859Sml29623 goto fail; 33763859Sml29623 } else { 33773859Sml29623 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 33786929Smisaki != NPI_SUCCESS) 33793859Sml29623 goto fail; 33803859Sml29623 } 33813859Sml29623 33823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 33836929Smisaki portn)); 33843859Sml29623 33853859Sml29623 return (NXGE_OK); 33863859Sml29623 fail: 33873859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 33886929Smisaki "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn)); 33893859Sml29623 33903859Sml29623 return (NXGE_ERROR | rs); 33913859Sml29623 } 33923859Sml29623 33933859Sml29623 /* Reset RXMAC */ 33943859Sml29623 33953859Sml29623 nxge_status_t 33963859Sml29623 nxge_rx_mac_reset(p_nxge_t nxgep) 33973859Sml29623 { 33983859Sml29623 npi_handle_t handle; 33993859Sml29623 uint8_t portn; 34003859Sml29623 npi_status_t rs = NPI_SUCCESS; 34013859Sml29623 34023859Sml29623 handle = nxgep->npi_handle; 34033859Sml29623 portn = nxgep->mac.portnum; 34043859Sml29623 34053859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 34066929Smisaki portn)); 34073859Sml29623 34083859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 34093859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 34103859Sml29623 != NPI_SUCCESS) 34113859Sml29623 goto fail; 34123859Sml29623 } else { 34133859Sml29623 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 34146929Smisaki != NPI_SUCCESS) 34153859Sml29623 goto fail; 34163859Sml29623 } 34173859Sml29623 34183859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 34196929Smisaki portn)); 34203859Sml29623 34213859Sml29623 return (NXGE_OK); 34223859Sml29623 fail: 34233859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 34246929Smisaki "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn)); 34253859Sml29623 return (NXGE_ERROR | rs); 34263859Sml29623 } 34273859Sml29623 34284732Sdavemq /* 10G fiber link interrupt start routine */ 34294732Sdavemq 34304732Sdavemq static nxge_status_t 34314732Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep) 34324732Sdavemq { 34334732Sdavemq npi_status_t rs = NPI_SUCCESS; 34344732Sdavemq uint8_t portn = nxgep->mac.portnum; 34354732Sdavemq 34364732Sdavemq rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 34374732Sdavemq 34384732Sdavemq if (rs != NPI_SUCCESS) 34394732Sdavemq return (NXGE_ERROR | rs); 34404732Sdavemq else 34414732Sdavemq return (NXGE_OK); 34424732Sdavemq } 34434732Sdavemq 34444732Sdavemq /* 10G fiber link interrupt stop routine */ 34454732Sdavemq 34464732Sdavemq static nxge_status_t 34474732Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep) 34484732Sdavemq { 34494732Sdavemq npi_status_t rs = NPI_SUCCESS; 34504732Sdavemq uint8_t portn = nxgep->mac.portnum; 34514732Sdavemq 34524732Sdavemq rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 34534732Sdavemq 34544732Sdavemq if (rs != NPI_SUCCESS) 34554732Sdavemq return (NXGE_ERROR | rs); 34564732Sdavemq else 34574732Sdavemq return (NXGE_OK); 34584732Sdavemq } 34594732Sdavemq 34604732Sdavemq /* 1G fiber link interrupt start routine */ 34614732Sdavemq 34624732Sdavemq static nxge_status_t 34634732Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 34644732Sdavemq { 34654732Sdavemq npi_status_t rs = NPI_SUCCESS; 34664732Sdavemq uint8_t portn = nxgep->mac.portnum; 34674732Sdavemq 34684732Sdavemq rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 34694732Sdavemq if (rs != NPI_SUCCESS) 34704732Sdavemq return (NXGE_ERROR | rs); 34714732Sdavemq else 34724732Sdavemq return (NXGE_OK); 34734732Sdavemq } 34744732Sdavemq 34754732Sdavemq /* 1G fiber link interrupt stop routine */ 34764732Sdavemq 34774732Sdavemq static nxge_status_t 34784732Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 34794732Sdavemq { 34804732Sdavemq npi_status_t rs = NPI_SUCCESS; 34814732Sdavemq uint8_t portn = nxgep->mac.portnum; 34824732Sdavemq 34834732Sdavemq rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 34844732Sdavemq 34854732Sdavemq if (rs != NPI_SUCCESS) 34864732Sdavemq return (NXGE_ERROR | rs); 34874732Sdavemq else 34884732Sdavemq return (NXGE_OK); 34894732Sdavemq } 34904732Sdavemq 34914732Sdavemq /* 1G copper link interrupt start routine */ 34924732Sdavemq 34934732Sdavemq static nxge_status_t 34944732Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 34954732Sdavemq { 34964732Sdavemq npi_status_t rs = NPI_SUCCESS; 34974732Sdavemq uint8_t portn = nxgep->mac.portnum; 34984732Sdavemq 34994732Sdavemq rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 35005203Ssbehera MII_STATUS, MII_STATUS_LINKUP); 35014732Sdavemq 35024732Sdavemq if (rs != NPI_SUCCESS) 35034732Sdavemq return (NXGE_ERROR | rs); 35044732Sdavemq else 35054732Sdavemq return (NXGE_OK); 35064732Sdavemq } 35074732Sdavemq 35084732Sdavemq /* 1G copper link interrupt stop routine */ 35094732Sdavemq 35104732Sdavemq static nxge_status_t 35114732Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 35124732Sdavemq { 35134732Sdavemq npi_status_t rs = NPI_SUCCESS; 35144732Sdavemq uint8_t portn = nxgep->mac.portnum; 35154732Sdavemq 35164732Sdavemq rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 35174732Sdavemq 35184732Sdavemq if (rs != NPI_SUCCESS) 35194732Sdavemq return (NXGE_ERROR | rs); 35204732Sdavemq else 35214732Sdavemq return (NXGE_OK); 35224732Sdavemq } 35234732Sdavemq 35244732Sdavemq /* Enable/Disable Link Status change interrupt */ 35253859Sml29623 35263859Sml29623 nxge_status_t 35273859Sml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 35283859Sml29623 { 35294732Sdavemq uint8_t portn; 35304732Sdavemq nxge_status_t status = NXGE_OK; 35313859Sml29623 35323859Sml29623 portn = nxgep->mac.portnum; 35333859Sml29623 35343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 35354732Sdavemq if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 35364732Sdavemq return (NXGE_OK); 35374732Sdavemq 35384732Sdavemq if (enable == LINK_INTR_START) 35394732Sdavemq status = nxgep->xcvr.link_intr_start(nxgep); 35404732Sdavemq else if (enable == LINK_INTR_STOP) 35414732Sdavemq status = nxgep->xcvr.link_intr_stop(nxgep); 35424732Sdavemq if (status != NXGE_OK) 35434732Sdavemq goto fail; 35443859Sml29623 35453859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 35463859Sml29623 35473859Sml29623 return (NXGE_OK); 35483859Sml29623 fail: 35493859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 35506929Smisaki "nxge_link_intr: Failed to set port<%d> mif intr mode", portn)); 35513859Sml29623 35524732Sdavemq return (status); 35533859Sml29623 } 35543859Sml29623 35553859Sml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 35563859Sml29623 35573859Sml29623 nxge_status_t 35583859Sml29623 nxge_mii_xcvr_init(p_nxge_t nxgep) 35593859Sml29623 { 35603859Sml29623 p_nxge_param_t param_arr; 35613859Sml29623 p_nxge_stats_t statsp; 35623859Sml29623 uint8_t xcvr_portn; 35633859Sml29623 p_mii_regs_t mii_regs; 35643859Sml29623 mii_bmcr_t bmcr; 35653859Sml29623 mii_bmsr_t bmsr; 35663859Sml29623 mii_anar_t anar; 35673859Sml29623 mii_gcr_t gcr; 35683859Sml29623 mii_esr_t esr; 35693859Sml29623 mii_aux_ctl_t bcm5464r_aux; 35703859Sml29623 int status = NXGE_OK; 35713859Sml29623 35723859Sml29623 uint_t delay; 35733859Sml29623 35743859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 35753859Sml29623 35763859Sml29623 param_arr = nxgep->param_arr; 35773859Sml29623 statsp = nxgep->statsp; 35783859Sml29623 xcvr_portn = statsp->mac_stats.xcvr_portn; 35793859Sml29623 35803859Sml29623 mii_regs = NULL; 35813859Sml29623 35823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 35836929Smisaki "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 35843859Sml29623 35853859Sml29623 /* 35865196Ssbehera * The mif phy mode may be connected to either a copper link 35875196Ssbehera * or fiber link. Read the mode control register to get the fiber 35885196Ssbehera * configuration if it is hard-wired to fiber link. 35895196Ssbehera */ 35905196Ssbehera (void) nxge_mii_get_link_mode(nxgep); 35915196Ssbehera if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 35925196Ssbehera return (nxge_mii_xcvr_fiber_init(nxgep)); 35935196Ssbehera } 35945196Ssbehera 35955196Ssbehera /* 35963859Sml29623 * Reset the transceiver. 35973859Sml29623 */ 35983859Sml29623 delay = 0; 35993859Sml29623 bmcr.value = 0; 36003859Sml29623 bmcr.bits.reset = 1; 36013859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 36025125Sjoycey #if defined(__i386) 36036929Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr, 36045125Sjoycey #else 36056929Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr, 36065125Sjoycey #endif 36076929Smisaki bmcr.value)) != NXGE_OK) 36083859Sml29623 goto fail; 36093859Sml29623 do { 36103859Sml29623 drv_usecwait(500); 36113859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 36125125Sjoycey #if defined(__i386) 36136929Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr, 36145125Sjoycey #else 36156929Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr, 36165125Sjoycey #endif 36176929Smisaki &bmcr.value)) != NXGE_OK) 36183859Sml29623 goto fail; 36193859Sml29623 delay++; 36203859Sml29623 } while ((bmcr.bits.reset) && (delay < 1000)); 36213859Sml29623 if (delay == 1000) { 36223859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 36233859Sml29623 goto fail; 36243859Sml29623 } 36253859Sml29623 36263859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 36275125Sjoycey #if defined(__i386) 36286929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmsr), 36295125Sjoycey #else 36306929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmsr), 36315125Sjoycey #endif 36326929Smisaki &bmsr.value)) != NXGE_OK) 36333859Sml29623 goto fail; 36343859Sml29623 36353859Sml29623 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 36363859Sml29623 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 36373859Sml29623 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 36383859Sml29623 param_arr[param_anar_100hdx].value = 0; 36393859Sml29623 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 36403859Sml29623 param_arr[param_anar_10hdx].value = 0; 36413859Sml29623 36423859Sml29623 /* 36433859Sml29623 * Initialize the xcvr statistics. 36443859Sml29623 */ 36453859Sml29623 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 36463859Sml29623 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 36473859Sml29623 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 36483859Sml29623 statsp->mac_stats.cap_100hdx = 0; 36493859Sml29623 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 36503859Sml29623 statsp->mac_stats.cap_10hdx = 0; 36513859Sml29623 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 36523859Sml29623 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 36533859Sml29623 36543859Sml29623 /* 36556835Syc148097 * Initialize the xcvr advertised capability statistics. 36563859Sml29623 */ 36573859Sml29623 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 36583859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 36593859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 36603859Sml29623 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 36613859Sml29623 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 36623859Sml29623 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 36633859Sml29623 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 36643859Sml29623 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 36653859Sml29623 statsp->mac_stats.adv_cap_asmpause = 36666929Smisaki param_arr[param_anar_asmpause].value; 36673859Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 36683859Sml29623 36693859Sml29623 36703859Sml29623 /* 36713859Sml29623 * Check for extended status just in case we're 36723859Sml29623 * running a Gigibit phy. 36733859Sml29623 */ 36743859Sml29623 if (bmsr.bits.extend_status) { 36753859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 36765125Sjoycey #if defined(__i386) 36776929Smisaki (uint8_t)(uint32_t)(&mii_regs->esr), 36785125Sjoycey #else 36796929Smisaki (uint8_t)(uint64_t)(&mii_regs->esr), 36805125Sjoycey #endif 36816929Smisaki &esr.value)) != NXGE_OK) 36823859Sml29623 goto fail; 36836929Smisaki param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx; 36843859Sml29623 param_arr[param_anar_1000hdx].value = 0; 36853859Sml29623 36863859Sml29623 statsp->mac_stats.cap_1000fdx = 36876929Smisaki (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 36883859Sml29623 statsp->mac_stats.cap_1000hdx = 0; 36893859Sml29623 } else { 36903859Sml29623 param_arr[param_anar_1000fdx].value = 0; 36913859Sml29623 param_arr[param_anar_1000hdx].value = 0; 36923859Sml29623 } 36933859Sml29623 36943859Sml29623 /* 36953859Sml29623 * Initialize 1G Statistics once the capability is established. 36963859Sml29623 */ 36973859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 36983859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 36993859Sml29623 37003859Sml29623 /* 37016835Syc148097 * Initialize the link statistics. 37023859Sml29623 */ 37033859Sml29623 statsp->mac_stats.link_T4 = 0; 37043859Sml29623 statsp->mac_stats.link_asmpause = 0; 37053859Sml29623 statsp->mac_stats.link_pause = 0; 37063859Sml29623 statsp->mac_stats.link_speed = 0; 37073859Sml29623 statsp->mac_stats.link_duplex = 0; 37083859Sml29623 statsp->mac_stats.link_up = 0; 37093859Sml29623 37103859Sml29623 /* 37113859Sml29623 * Switch off Auto-negotiation, 100M and full duplex. 37123859Sml29623 */ 37133859Sml29623 bmcr.value = 0; 37143859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37155125Sjoycey #if defined(__i386) 37166929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 37175125Sjoycey #else 37186929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 37195125Sjoycey #endif 37206929Smisaki bmcr.value)) != NXGE_OK) 37213859Sml29623 goto fail; 37223859Sml29623 37233859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 37246929Smisaki (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 37253859Sml29623 bmcr.bits.loopback = 1; 37263859Sml29623 bmcr.bits.enable_autoneg = 0; 37273859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 37283859Sml29623 bmcr.bits.speed_1000_sel = 1; 37293859Sml29623 bmcr.bits.duplex_mode = 1; 37303859Sml29623 param_arr[param_autoneg].value = 0; 37313859Sml29623 } else { 37323859Sml29623 bmcr.bits.loopback = 0; 37333859Sml29623 } 37343859Sml29623 37353859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 37366929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext100) || 37376929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 37383859Sml29623 param_arr[param_autoneg].value = 0; 37393859Sml29623 bcm5464r_aux.value = 0; 37403859Sml29623 bcm5464r_aux.bits.ext_lb = 1; 37413859Sml29623 bcm5464r_aux.bits.write_1 = 1; 37423859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37436929Smisaki BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 37443859Sml29623 goto fail; 37453859Sml29623 } 37463859Sml29623 37476835Syc148097 /* If auto-negotiation is desired */ 37483859Sml29623 if (param_arr[param_autoneg].value) { 37493859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 37506929Smisaki "Restarting Auto-negotiation.")); 37513859Sml29623 /* 37523859Sml29623 * Setup our Auto-negotiation advertisement register. 37533859Sml29623 */ 37543859Sml29623 anar.value = 0; 37553859Sml29623 anar.bits.selector = 1; 37563859Sml29623 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 37573859Sml29623 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 37583859Sml29623 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 37593859Sml29623 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 37603859Sml29623 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 37613859Sml29623 anar.bits.cap_asmpause = 0; 37623859Sml29623 anar.bits.cap_pause = 0; 37633859Sml29623 if (param_arr[param_anar_1000fdx].value || 37646929Smisaki param_arr[param_anar_100fdx].value || 37656929Smisaki param_arr[param_anar_10fdx].value) { 37663859Sml29623 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 37673859Sml29623 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 37683859Sml29623 } 37693859Sml29623 37706835Syc148097 /* Write to the auto-negotiation advertisement register */ 37713859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37725125Sjoycey #if defined(__i386) 37736929Smisaki (uint8_t)(uint32_t)(&mii_regs->anar), 37745125Sjoycey #else 37756929Smisaki (uint8_t)(uint64_t)(&mii_regs->anar), 37765125Sjoycey #endif 37776929Smisaki anar.value)) != NXGE_OK) 37783859Sml29623 goto fail; 37793859Sml29623 if (bmsr.bits.extend_status) { 37803859Sml29623 gcr.value = 0; 37813859Sml29623 gcr.bits.ms_mode_en = 37826929Smisaki param_arr[param_master_cfg_enable].value; 37833859Sml29623 gcr.bits.master = 37846929Smisaki param_arr[param_master_cfg_value].value; 37853859Sml29623 gcr.bits.link_1000fdx = 37866929Smisaki param_arr[param_anar_1000fdx].value; 37873859Sml29623 gcr.bits.link_1000hdx = 37886929Smisaki param_arr[param_anar_1000hdx].value; 37893859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 37905125Sjoycey #if defined(__i386) 37916929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 37925125Sjoycey #else 37936929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 37945125Sjoycey #endif 37956929Smisaki gcr.value)) != NXGE_OK) 37963859Sml29623 goto fail; 37973859Sml29623 } 37983859Sml29623 37993859Sml29623 bmcr.bits.enable_autoneg = 1; 38003859Sml29623 bmcr.bits.restart_autoneg = 1; 38013859Sml29623 38023859Sml29623 } else { 38033859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 38043859Sml29623 bmcr.bits.speed_1000_sel = 38056929Smisaki param_arr[param_anar_1000fdx].value | 38066929Smisaki param_arr[param_anar_1000hdx].value; 38073859Sml29623 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 38086929Smisaki (param_arr[param_anar_100fdx].value | 38096929Smisaki param_arr[param_anar_100hdx].value); 38106835Syc148097 38116835Syc148097 /* Force to 1G */ 38123859Sml29623 if (bmcr.bits.speed_1000_sel) { 38133859Sml29623 statsp->mac_stats.link_speed = 1000; 38143859Sml29623 gcr.value = 0; 38153859Sml29623 gcr.bits.ms_mode_en = 38166929Smisaki param_arr[param_master_cfg_enable].value; 38173859Sml29623 gcr.bits.master = 38186929Smisaki param_arr[param_master_cfg_value].value; 38193859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 38205125Sjoycey #if defined(__i386) 38216929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 38225125Sjoycey #else 38236929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 38245125Sjoycey #endif 38256929Smisaki gcr.value)) != NXGE_OK) 38263859Sml29623 goto fail; 38273859Sml29623 if (param_arr[param_anar_1000fdx].value) { 38283859Sml29623 bmcr.bits.duplex_mode = 1; 38293859Sml29623 statsp->mac_stats.link_duplex = 2; 38303859Sml29623 } else 38313859Sml29623 statsp->mac_stats.link_duplex = 1; 38326835Syc148097 38336835Syc148097 /* Force to 100M */ 38343859Sml29623 } else if (bmcr.bits.speed_sel) { 38353859Sml29623 statsp->mac_stats.link_speed = 100; 38363859Sml29623 if (param_arr[param_anar_100fdx].value) { 38373859Sml29623 bmcr.bits.duplex_mode = 1; 38383859Sml29623 statsp->mac_stats.link_duplex = 2; 38393859Sml29623 } else 38403859Sml29623 statsp->mac_stats.link_duplex = 1; 38416835Syc148097 38426835Syc148097 /* Force to 10M */ 38433859Sml29623 } else { 38443859Sml29623 statsp->mac_stats.link_speed = 10; 38453859Sml29623 if (param_arr[param_anar_10fdx].value) { 38463859Sml29623 bmcr.bits.duplex_mode = 1; 38473859Sml29623 statsp->mac_stats.link_duplex = 2; 38483859Sml29623 } else 38493859Sml29623 statsp->mac_stats.link_duplex = 1; 38503859Sml29623 } 38513859Sml29623 if (statsp->mac_stats.link_duplex != 1) { 38523859Sml29623 statsp->mac_stats.link_asmpause = 38536929Smisaki statsp->mac_stats.cap_asmpause; 38543859Sml29623 statsp->mac_stats.link_pause = 38556929Smisaki statsp->mac_stats.cap_pause; 38563859Sml29623 } 38573859Sml29623 38583859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 38596929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext100) || 38606929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 38613859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 38623859Sml29623 /* BCM5464R 1000mbps external loopback mode */ 38633859Sml29623 gcr.value = 0; 38643859Sml29623 gcr.bits.ms_mode_en = 1; 38653859Sml29623 gcr.bits.master = 1; 38663859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 38675125Sjoycey #if defined(__i386) 38686929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 38695125Sjoycey #else 38706929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 38715125Sjoycey #endif 38726929Smisaki gcr.value)) != NXGE_OK) 38733859Sml29623 goto fail; 38743859Sml29623 bmcr.value = 0; 38753859Sml29623 bmcr.bits.speed_1000_sel = 1; 38763859Sml29623 statsp->mac_stats.link_speed = 1000; 38773859Sml29623 } else if (statsp->port_stats.lb_mode 38783859Sml29623 == nxge_lb_ext100) { 38793859Sml29623 /* BCM5464R 100mbps external loopback mode */ 38803859Sml29623 bmcr.value = 0; 38813859Sml29623 bmcr.bits.speed_sel = 1; 38823859Sml29623 bmcr.bits.duplex_mode = 1; 38833859Sml29623 statsp->mac_stats.link_speed = 100; 38843859Sml29623 } else if (statsp->port_stats.lb_mode 38853859Sml29623 == nxge_lb_ext10) { 38863859Sml29623 /* BCM5464R 10mbps external loopback mode */ 38873859Sml29623 bmcr.value = 0; 38883859Sml29623 bmcr.bits.duplex_mode = 1; 38893859Sml29623 statsp->mac_stats.link_speed = 10; 38903859Sml29623 } 38913859Sml29623 } 38923859Sml29623 } 38933859Sml29623 38943859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 38955125Sjoycey #if defined(__i386) 38966929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 38975125Sjoycey #else 38986929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 38995125Sjoycey #endif 39006929Smisaki bmcr.value)) != NXGE_OK) 39013859Sml29623 goto fail; 39023859Sml29623 39033859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 39045125Sjoycey #if defined(__i386) 39056929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 39065125Sjoycey #else 39076929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 39085125Sjoycey #endif 39096929Smisaki &bmcr.value)) != NXGE_OK) 39103859Sml29623 goto fail; 39113859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 39123859Sml29623 39133859Sml29623 /* 39143859Sml29623 * Initialize the xcvr status kept in the context structure. 39153859Sml29623 */ 39163859Sml29623 nxgep->soft_bmsr.value = 0; 39173859Sml29623 39183859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 39195125Sjoycey #if defined(__i386) 39206929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmsr), 39215125Sjoycey #else 39226929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmsr), 39235125Sjoycey #endif 39246929Smisaki &nxgep->bmsr.value)) != NXGE_OK) 39253859Sml29623 goto fail; 39263859Sml29623 39273859Sml29623 statsp->mac_stats.xcvr_inits++; 39283859Sml29623 nxgep->bmsr.value = 0; 39293859Sml29623 39303859Sml29623 fail: 39313859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39326929Smisaki "<== nxge_mii_xcvr_init status 0x%x", status)); 39333859Sml29623 return (status); 39343859Sml29623 } 39353859Sml29623 39365196Ssbehera nxge_status_t 39375196Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep) 39385196Ssbehera { 39395196Ssbehera p_nxge_param_t param_arr; 39405196Ssbehera p_nxge_stats_t statsp; 39415196Ssbehera uint8_t xcvr_portn; 39425196Ssbehera p_mii_regs_t mii_regs; 39435196Ssbehera mii_bmcr_t bmcr; 39445196Ssbehera mii_bmsr_t bmsr; 39455196Ssbehera mii_gcr_t gcr; 39465196Ssbehera mii_esr_t esr; 39475196Ssbehera mii_aux_ctl_t bcm5464r_aux; 39485196Ssbehera int status = NXGE_OK; 39495196Ssbehera 39505196Ssbehera uint_t delay; 39515196Ssbehera 39525196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init")); 39535196Ssbehera 39545196Ssbehera param_arr = nxgep->param_arr; 39555196Ssbehera statsp = nxgep->statsp; 39565196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 39575196Ssbehera 39585196Ssbehera mii_regs = NULL; 39595196Ssbehera 39605196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39615196Ssbehera "nxge_mii_xcvr_fiber_init: " 39625196Ssbehera "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 39635196Ssbehera 39645196Ssbehera /* 39655196Ssbehera * Reset the transceiver. 39665196Ssbehera */ 39675196Ssbehera delay = 0; 39685196Ssbehera bmcr.value = 0; 39695196Ssbehera bmcr.bits.reset = 1; 39705196Ssbehera 39715196Ssbehera #if defined(__i386) 39725196Ssbehera 39735196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 39745196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 39755196Ssbehera goto fail; 39765196Ssbehera #else 39775196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 39785196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 39795196Ssbehera goto fail; 39805196Ssbehera #endif 39815196Ssbehera do { 39825196Ssbehera drv_usecwait(500); 39835196Ssbehera #if defined(__i386) 39845196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 39855196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) 39865196Ssbehera != NXGE_OK) 39875196Ssbehera goto fail; 39885196Ssbehera #else 39895196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 39905196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) 39915196Ssbehera != NXGE_OK) 39925196Ssbehera goto fail; 39935196Ssbehera #endif 39945196Ssbehera delay++; 39955196Ssbehera } while ((bmcr.bits.reset) && (delay < 1000)); 39965196Ssbehera if (delay == 1000) { 39975196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 39985196Ssbehera goto fail; 39995196Ssbehera } 40005196Ssbehera 40015196Ssbehera #if defined(__i386) 40025196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 40035196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 40045196Ssbehera goto fail; 40055196Ssbehera #else 40065196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 40075196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 40085196Ssbehera goto fail; 40095196Ssbehera #endif 40105196Ssbehera 40115196Ssbehera param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 40125196Ssbehera param_arr[param_anar_100T4].value = 0; 40135196Ssbehera param_arr[param_anar_100fdx].value = 0; 40145196Ssbehera param_arr[param_anar_100hdx].value = 0; 40155196Ssbehera param_arr[param_anar_10fdx].value = 0; 40165196Ssbehera param_arr[param_anar_10hdx].value = 0; 40175196Ssbehera 40185196Ssbehera /* 40195196Ssbehera * Initialize the xcvr statistics. 40205196Ssbehera */ 40215196Ssbehera statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 40225196Ssbehera statsp->mac_stats.cap_100T4 = 0; 40235196Ssbehera statsp->mac_stats.cap_100fdx = 0; 40245196Ssbehera statsp->mac_stats.cap_100hdx = 0; 40255196Ssbehera statsp->mac_stats.cap_10fdx = 0; 40265196Ssbehera statsp->mac_stats.cap_10hdx = 0; 40275196Ssbehera statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 40285196Ssbehera statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 40295196Ssbehera 40305196Ssbehera /* 40315196Ssbehera * Initialize the xcvr advertised capability statistics. 40325196Ssbehera */ 40335196Ssbehera statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 40345196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 40355196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 40365196Ssbehera statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 40375196Ssbehera statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 40385196Ssbehera statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 40395196Ssbehera statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 40405196Ssbehera statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 40415196Ssbehera statsp->mac_stats.adv_cap_asmpause = 40425196Ssbehera param_arr[param_anar_asmpause].value; 40435196Ssbehera statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 40445196Ssbehera 40455196Ssbehera /* 40465196Ssbehera * Check for extended status just in case we're 40475196Ssbehera * running a Gigibit phy. 40485196Ssbehera */ 40495196Ssbehera if (bmsr.bits.extend_status) { 40505196Ssbehera #if defined(__i386) 40515196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 40525196Ssbehera (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) != 40535196Ssbehera NXGE_OK) 40545196Ssbehera goto fail; 40555196Ssbehera #else 40565196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 40575196Ssbehera (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) != 40585196Ssbehera NXGE_OK) 40595196Ssbehera goto fail; 40605196Ssbehera #endif 40615196Ssbehera param_arr[param_anar_1000fdx].value &= 40625196Ssbehera esr.bits.link_1000fdx; 40635196Ssbehera param_arr[param_anar_1000hdx].value = 0; 40645196Ssbehera 40655196Ssbehera statsp->mac_stats.cap_1000fdx = 40665196Ssbehera (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 40675196Ssbehera statsp->mac_stats.cap_1000hdx = 0; 40685196Ssbehera } else { 40695196Ssbehera param_arr[param_anar_1000fdx].value = 0; 40705196Ssbehera param_arr[param_anar_1000hdx].value = 0; 40715196Ssbehera } 40725196Ssbehera 40735196Ssbehera /* 40745196Ssbehera * Initialize 1G Statistics once the capability is established. 40755196Ssbehera */ 40765196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 40775196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 40785196Ssbehera 40795196Ssbehera /* 40805196Ssbehera * Initialize the link statistics. 40815196Ssbehera */ 40825196Ssbehera statsp->mac_stats.link_T4 = 0; 40835196Ssbehera statsp->mac_stats.link_asmpause = 0; 40845196Ssbehera statsp->mac_stats.link_pause = 0; 40855196Ssbehera statsp->mac_stats.link_speed = 0; 40865196Ssbehera statsp->mac_stats.link_duplex = 0; 40875196Ssbehera statsp->mac_stats.link_up = 0; 40885196Ssbehera 40895196Ssbehera /* 40905196Ssbehera * Switch off Auto-negotiation, 100M and full duplex. 40915196Ssbehera */ 40925196Ssbehera bmcr.value = 0; 40935196Ssbehera #if defined(__i386) 40945196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 40955196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 40965196Ssbehera goto fail; 40975196Ssbehera #else 40985196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 40995196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 41005196Ssbehera goto fail; 41015196Ssbehera #endif 41025196Ssbehera 41035196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 41045196Ssbehera (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 41055196Ssbehera bmcr.bits.loopback = 1; 41065196Ssbehera bmcr.bits.enable_autoneg = 0; 41075196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 41085196Ssbehera bmcr.bits.speed_1000_sel = 1; 41095196Ssbehera bmcr.bits.duplex_mode = 1; 41105196Ssbehera param_arr[param_autoneg].value = 0; 41115196Ssbehera } else { 41125196Ssbehera bmcr.bits.loopback = 0; 41135196Ssbehera } 41145196Ssbehera 41155196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 41165196Ssbehera param_arr[param_autoneg].value = 0; 41175196Ssbehera bcm5464r_aux.value = 0; 41185196Ssbehera bcm5464r_aux.bits.ext_lb = 1; 41195196Ssbehera bcm5464r_aux.bits.write_1 = 1; 41205196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41215196Ssbehera BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 41225196Ssbehera goto fail; 41235196Ssbehera } 41245196Ssbehera 41255196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 41265196Ssbehera bmcr.bits.speed_1000_sel = 1; 41275196Ssbehera bmcr.bits.speed_sel = 0; 41285196Ssbehera bmcr.bits.duplex_mode = 1; 41295196Ssbehera statsp->mac_stats.link_speed = 1000; 41305196Ssbehera statsp->mac_stats.link_duplex = 2; 41315196Ssbehera 41325196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) { 41335196Ssbehera /* BCM5464R 1000mbps external loopback mode */ 41345196Ssbehera gcr.value = 0; 41355196Ssbehera gcr.bits.ms_mode_en = 1; 41365196Ssbehera gcr.bits.master = 1; 41375196Ssbehera #if defined(__i386) 41385196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41395196Ssbehera (uint8_t)(uint32_t)(&mii_regs->gcr), 41405196Ssbehera gcr.value)) != NXGE_OK) 41415196Ssbehera goto fail; 41425196Ssbehera #else 41435196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41445196Ssbehera (uint8_t)(uint64_t)(&mii_regs->gcr), 41455196Ssbehera gcr.value)) != NXGE_OK) 41465196Ssbehera goto fail; 41475196Ssbehera #endif 41485196Ssbehera bmcr.value = 0; 41495196Ssbehera bmcr.bits.speed_1000_sel = 1; 41505196Ssbehera statsp->mac_stats.link_speed = 1000; 41515196Ssbehera } 41525196Ssbehera 41535196Ssbehera #if defined(__i386) 41545196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41555196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), 41565196Ssbehera bmcr.value)) != NXGE_OK) 41575196Ssbehera goto fail; 41585196Ssbehera #else 41595196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 41605196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), 41615196Ssbehera bmcr.value)) != NXGE_OK) 41625196Ssbehera goto fail; 41635196Ssbehera #endif 41645196Ssbehera 41655196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41665196Ssbehera "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x", 41675196Ssbehera bmcr.value)); 41685196Ssbehera 41695196Ssbehera #if defined(__i386) 41705196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41715196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 41725196Ssbehera goto fail; 41735196Ssbehera #else 41745196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41755196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 41765196Ssbehera goto fail; 41775196Ssbehera #endif 41785196Ssbehera 41795196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41805196Ssbehera "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value)); 41815196Ssbehera 41825196Ssbehera /* 41835196Ssbehera * Initialize the xcvr status kept in the context structure. 41845196Ssbehera */ 41855196Ssbehera nxgep->soft_bmsr.value = 0; 41865196Ssbehera #if defined(__i386) 41875196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41885196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), 41895196Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 41905196Ssbehera goto fail; 41915196Ssbehera #else 41925196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 41935196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), 41945196Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 41955196Ssbehera goto fail; 41965196Ssbehera #endif 41975196Ssbehera 41985196Ssbehera statsp->mac_stats.xcvr_inits++; 41995196Ssbehera nxgep->bmsr.value = 0; 42005196Ssbehera 42015196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 42025196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 42035196Ssbehera return (status); 42045196Ssbehera 42055196Ssbehera fail: 42065196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 42075196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 42085196Ssbehera return (status); 42095196Ssbehera } 42105196Ssbehera 42113859Sml29623 /* Read from a MII compliant register */ 42123859Sml29623 42133859Sml29623 nxge_status_t 42143859Sml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 42153859Sml29623 uint16_t *value) 42163859Sml29623 { 42173859Sml29623 npi_status_t rs = NPI_SUCCESS; 42183859Sml29623 42193859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 42206929Smisaki "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 42213859Sml29623 42226075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 42233859Sml29623 42245196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 42255196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 42263859Sml29623 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 42276929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42283859Sml29623 goto fail; 42294977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 42304977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 42313859Sml29623 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 42326929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42333859Sml29623 goto fail; 42343859Sml29623 } else 42353859Sml29623 goto fail; 42363859Sml29623 42376075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42383859Sml29623 42393859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 42406929Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value)); 42413859Sml29623 return (NXGE_OK); 42423859Sml29623 fail: 42436075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42443859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 42456929Smisaki "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn)); 42463859Sml29623 42473859Sml29623 return (NXGE_ERROR | rs); 42483859Sml29623 } 42493859Sml29623 42503859Sml29623 /* Write to a MII compliant Register */ 42513859Sml29623 42523859Sml29623 nxge_status_t 42533859Sml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 42543859Sml29623 uint16_t value) 42553859Sml29623 { 42563859Sml29623 npi_status_t rs = NPI_SUCCESS; 42573859Sml29623 42583859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 42596929Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value)); 42603859Sml29623 42616075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 42623859Sml29623 42635196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 42645196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 42653859Sml29623 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 42666929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42673859Sml29623 goto fail; 42684977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 42694977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 42703859Sml29623 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 42716929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 42723859Sml29623 goto fail; 42733859Sml29623 } else 42743859Sml29623 goto fail; 42753859Sml29623 42766075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42773859Sml29623 42783859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 42796929Smisaki "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 42803859Sml29623 return (NXGE_OK); 42813859Sml29623 fail: 42826075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 42833859Sml29623 42843859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 42856929Smisaki "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn)); 42863859Sml29623 42873859Sml29623 return (NXGE_ERROR | rs); 42883859Sml29623 } 42893859Sml29623 42906835Syc148097 /* 42916835Syc148097 * Perform write to Clause45 serdes / transceiver device 42926835Syc148097 * Arguments: 42936835Syc148097 * xcvr_portn: The IEEE 802.3 Clause45 PHYAD, it is the same as port 42946835Syc148097 * number if nxge_mdio_write is used for accessing the 42956835Syc148097 * internal LSIL serdes. Otherwise PHYAD is different 42966835Syc148097 * for different platforms. 42976835Syc148097 * device: With each PHYAD, the driver can use MDIO to control 42986835Syc148097 * multiple devices inside the PHY, here "device" is an 42996835Syc148097 * MMD (MDIO managable device). 43006835Syc148097 * xcvr_reg: Each device has multiple registers. xcvr_reg specifies 43016835Syc148097 * the register which the driver will write value to. 43026835Syc148097 * value: The register value will be filled in. 43036835Syc148097 */ 43043859Sml29623 nxge_status_t 43053859Sml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 43063859Sml29623 uint16_t xcvr_reg, uint16_t *value) 43073859Sml29623 { 43083859Sml29623 npi_status_t rs = NPI_SUCCESS; 43093859Sml29623 43103859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 43116929Smisaki xcvr_portn)); 43123859Sml29623 43135780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 43143859Sml29623 43153859Sml29623 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 43166929Smisaki xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 43173859Sml29623 goto fail; 43183859Sml29623 43195780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43203859Sml29623 43213859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 43226929Smisaki xcvr_portn)); 43233859Sml29623 return (NXGE_OK); 43243859Sml29623 fail: 43255780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43263859Sml29623 43273859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 43286929Smisaki "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn)); 43293859Sml29623 43303859Sml29623 return (NXGE_ERROR | rs); 43313859Sml29623 } 43323859Sml29623 43333859Sml29623 /* Perform write to Clause45 serdes / transceiver device */ 43343859Sml29623 43353859Sml29623 nxge_status_t 43363859Sml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 43373859Sml29623 uint16_t xcvr_reg, uint16_t value) 43383859Sml29623 { 43393859Sml29623 npi_status_t rs = NPI_SUCCESS; 43403859Sml29623 43413859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 43426929Smisaki xcvr_portn)); 43433859Sml29623 43445780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 43453859Sml29623 43463859Sml29623 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 43476929Smisaki xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 43483859Sml29623 goto fail; 43493859Sml29623 43505780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43513859Sml29623 43523859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 43536929Smisaki xcvr_portn)); 43543859Sml29623 return (NXGE_OK); 43553859Sml29623 fail: 43565780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 43573859Sml29623 43583859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 43596929Smisaki "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn)); 43603859Sml29623 43613859Sml29623 return (NXGE_ERROR | rs); 43623859Sml29623 } 43633859Sml29623 43643859Sml29623 43653859Sml29623 /* Check MII to see if there is any link status change */ 43663859Sml29623 43673859Sml29623 nxge_status_t 43683859Sml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 43693859Sml29623 nxge_link_state_t *link_up) 43703859Sml29623 { 43713859Sml29623 p_nxge_param_t param_arr; 43723859Sml29623 p_nxge_stats_t statsp; 43733859Sml29623 p_mii_regs_t mii_regs; 43743859Sml29623 p_mii_bmsr_t soft_bmsr; 43753859Sml29623 mii_anar_t anar; 43763859Sml29623 mii_anlpar_t anlpar; 43773859Sml29623 mii_anar_t an_common; 43783859Sml29623 mii_aner_t aner; 43793859Sml29623 mii_gsr_t gsr; 43803859Sml29623 nxge_status_t status = NXGE_OK; 43813859Sml29623 43823859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 43833859Sml29623 43843859Sml29623 mii_regs = NULL; 43853859Sml29623 param_arr = nxgep->param_arr; 43863859Sml29623 statsp = nxgep->statsp; 43873859Sml29623 soft_bmsr = &nxgep->soft_bmsr; 43883859Sml29623 *link_up = LINK_NO_CHANGE; 43893859Sml29623 43905196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43915196Ssbehera "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x", 43925196Ssbehera bmsr.value, bmsr_ints.value)); 43935196Ssbehera 43943859Sml29623 if (bmsr_ints.bits.link_status) { 43955196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43965196Ssbehera "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x", 43975196Ssbehera bmsr.value, bmsr_ints.value)); 43983859Sml29623 if (bmsr.bits.link_status) { 43993859Sml29623 soft_bmsr->bits.link_status = 1; 44005196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 44015196Ssbehera "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int " 44025196Ssbehera "0x%x", bmsr.value, bmsr_ints.value)); 44033859Sml29623 } else { 44043859Sml29623 statsp->mac_stats.link_up = 0; 44053859Sml29623 soft_bmsr->bits.link_status = 0; 44063859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 44076929Smisaki "Link down cable problem")); 44083859Sml29623 *link_up = LINK_IS_DOWN; 44093859Sml29623 } 44103859Sml29623 } 44113859Sml29623 44125196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 44135196Ssbehera param_arr[param_autoneg].value) { 44143859Sml29623 if (bmsr_ints.bits.auto_neg_complete) { 44153859Sml29623 if (bmsr.bits.auto_neg_complete) 44163859Sml29623 soft_bmsr->bits.auto_neg_complete = 1; 44173859Sml29623 else 44183859Sml29623 soft_bmsr->bits.auto_neg_complete = 0; 44193859Sml29623 } 44203859Sml29623 if (soft_bmsr->bits.link_status == 0) { 44213859Sml29623 statsp->mac_stats.link_T4 = 0; 44223859Sml29623 statsp->mac_stats.link_speed = 0; 44233859Sml29623 statsp->mac_stats.link_duplex = 0; 44243859Sml29623 statsp->mac_stats.link_asmpause = 0; 44253859Sml29623 statsp->mac_stats.link_pause = 0; 44263859Sml29623 statsp->mac_stats.lp_cap_autoneg = 0; 44273859Sml29623 statsp->mac_stats.lp_cap_100T4 = 0; 44283859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 0; 44293859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 0; 44303859Sml29623 statsp->mac_stats.lp_cap_100fdx = 0; 44313859Sml29623 statsp->mac_stats.lp_cap_100hdx = 0; 44323859Sml29623 statsp->mac_stats.lp_cap_10fdx = 0; 44333859Sml29623 statsp->mac_stats.lp_cap_10hdx = 0; 44343859Sml29623 statsp->mac_stats.lp_cap_10gfdx = 0; 44353859Sml29623 statsp->mac_stats.lp_cap_10ghdx = 0; 44363859Sml29623 statsp->mac_stats.lp_cap_asmpause = 0; 44373859Sml29623 statsp->mac_stats.lp_cap_pause = 0; 44383859Sml29623 } 44393859Sml29623 } else 44403859Sml29623 soft_bmsr->bits.auto_neg_complete = 1; 44413859Sml29623 44423859Sml29623 if ((bmsr_ints.bits.link_status || 44436929Smisaki bmsr_ints.bits.auto_neg_complete) && 44446929Smisaki soft_bmsr->bits.link_status && 44456929Smisaki soft_bmsr->bits.auto_neg_complete) { 44463859Sml29623 statsp->mac_stats.link_up = 1; 44475196Ssbehera 44485196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 44495196Ssbehera "==> nxge_mii_check " 44505196Ssbehera "(auto negotiation complete or link up) " 44515196Ssbehera "soft bmsr 0x%x bmsr_int 0x%x", 44525196Ssbehera bmsr.value, bmsr_ints.value)); 44535196Ssbehera 44545196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 44555196Ssbehera param_arr[param_autoneg].value) { 44563859Sml29623 if ((status = nxge_mii_read(nxgep, 44576929Smisaki statsp->mac_stats.xcvr_portn, 44585125Sjoycey #if defined(__i386) 44596929Smisaki (uint8_t)(uint32_t)(&mii_regs->anar), 44605125Sjoycey #else 44616929Smisaki (uint8_t)(uint64_t)(&mii_regs->anar), 44625125Sjoycey #endif 44636929Smisaki &anar.value)) != NXGE_OK) 44643859Sml29623 goto fail; 44653859Sml29623 if ((status = nxge_mii_read(nxgep, 44666929Smisaki statsp->mac_stats.xcvr_portn, 44675125Sjoycey #if defined(__i386) 44686929Smisaki (uint8_t)(uint32_t)(&mii_regs->anlpar), 44695125Sjoycey #else 44706929Smisaki (uint8_t)(uint64_t)(&mii_regs->anlpar), 44715125Sjoycey #endif 44726929Smisaki &anlpar.value)) != NXGE_OK) 44733859Sml29623 goto fail; 44743859Sml29623 if ((status = nxge_mii_read(nxgep, 44756929Smisaki statsp->mac_stats.xcvr_portn, 44765125Sjoycey #if defined(__i386) 44776929Smisaki (uint8_t)(uint32_t)(&mii_regs->aner), 44785125Sjoycey #else 44796929Smisaki (uint8_t)(uint64_t)(&mii_regs->aner), 44805125Sjoycey #endif 44816929Smisaki &aner.value)) != NXGE_OK) 44823859Sml29623 goto fail; 44833859Sml29623 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 44843859Sml29623 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 44853859Sml29623 statsp->mac_stats.lp_cap_100fdx = 44866929Smisaki anlpar.bits.cap_100fdx; 44873859Sml29623 statsp->mac_stats.lp_cap_100hdx = 44886929Smisaki anlpar.bits.cap_100hdx; 44893859Sml29623 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 44903859Sml29623 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 44913859Sml29623 statsp->mac_stats.lp_cap_asmpause = 44926929Smisaki anlpar.bits.cap_asmpause; 44933859Sml29623 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 44943859Sml29623 an_common.value = anar.value & anlpar.value; 44953859Sml29623 if (param_arr[param_anar_1000fdx].value || 44966929Smisaki param_arr[param_anar_1000hdx].value) { 44973859Sml29623 if ((status = nxge_mii_read(nxgep, 44986929Smisaki statsp->mac_stats.xcvr_portn, 44995125Sjoycey #if defined(__i386) 45006929Smisaki (uint8_t)(uint32_t)(&mii_regs->gsr), 45015125Sjoycey #else 45026929Smisaki (uint8_t)(uint64_t)(&mii_regs->gsr), 45035125Sjoycey #endif 45046929Smisaki &gsr.value)) != NXGE_OK) 45053859Sml29623 goto fail; 45063859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 45076929Smisaki gsr.bits.link_1000fdx; 45083859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 45096929Smisaki gsr.bits.link_1000hdx; 45103859Sml29623 if (param_arr[param_anar_1000fdx].value && 45116929Smisaki gsr.bits.link_1000fdx) { 45123859Sml29623 statsp->mac_stats.link_speed = 1000; 45133859Sml29623 statsp->mac_stats.link_duplex = 2; 45143859Sml29623 } else if ( 45156929Smisaki param_arr[param_anar_1000hdx].value && 45166929Smisaki gsr.bits.link_1000hdx) { 45173859Sml29623 statsp->mac_stats.link_speed = 1000; 45183859Sml29623 statsp->mac_stats.link_duplex = 1; 45193859Sml29623 } 45203859Sml29623 } 45213859Sml29623 if ((an_common.value != 0) && 45226929Smisaki !(statsp->mac_stats.link_speed)) { 45233859Sml29623 if (an_common.bits.cap_100T4) { 45243859Sml29623 statsp->mac_stats.link_T4 = 1; 45253859Sml29623 statsp->mac_stats.link_speed = 100; 45263859Sml29623 statsp->mac_stats.link_duplex = 1; 45273859Sml29623 } else if (an_common.bits.cap_100fdx) { 45283859Sml29623 statsp->mac_stats.link_speed = 100; 45293859Sml29623 statsp->mac_stats.link_duplex = 2; 45303859Sml29623 } else if (an_common.bits.cap_100hdx) { 45313859Sml29623 statsp->mac_stats.link_speed = 100; 45323859Sml29623 statsp->mac_stats.link_duplex = 1; 45333859Sml29623 } else if (an_common.bits.cap_10fdx) { 45343859Sml29623 statsp->mac_stats.link_speed = 10; 45353859Sml29623 statsp->mac_stats.link_duplex = 2; 45363859Sml29623 } else if (an_common.bits.cap_10hdx) { 45373859Sml29623 statsp->mac_stats.link_speed = 10; 45383859Sml29623 statsp->mac_stats.link_duplex = 1; 45393859Sml29623 } else { 45403859Sml29623 goto fail; 45413859Sml29623 } 45423859Sml29623 } 45433859Sml29623 if (statsp->mac_stats.link_duplex != 1) { 45446929Smisaki int link_pause; 45456929Smisaki int cp, lcp; 45466929Smisaki 45473859Sml29623 statsp->mac_stats.link_asmpause = 45486929Smisaki an_common.bits.cap_asmpause; 45496929Smisaki cp = statsp->mac_stats.cap_pause; 45506929Smisaki lcp = statsp->mac_stats.lp_cap_pause; 45516929Smisaki if (statsp->mac_stats.link_asmpause) { 45526929Smisaki if ((cp == 0) && (lcp == 1)) { 45536929Smisaki link_pause = 0; 45546929Smisaki } else { 45556929Smisaki link_pause = 1; 45566929Smisaki } 45576929Smisaki } else { 45586929Smisaki link_pause = an_common.bits.cap_pause; 45596929Smisaki } 45606929Smisaki statsp->mac_stats.link_pause = link_pause; 45613859Sml29623 } 45625196Ssbehera } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 45635196Ssbehera statsp->mac_stats.link_speed = 1000; 45645196Ssbehera statsp->mac_stats.link_duplex = 2; 45653859Sml29623 } 45663859Sml29623 *link_up = LINK_IS_UP; 45673859Sml29623 } 45683859Sml29623 45693859Sml29623 if (nxgep->link_notify) { 45703859Sml29623 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 45716929Smisaki LINK_IS_DOWN); 45723859Sml29623 nxgep->link_notify = B_FALSE; 45733859Sml29623 } 45743859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 45753859Sml29623 return (NXGE_OK); 45763859Sml29623 fail: 45773859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 45786929Smisaki "nxge_mii_check: Unable to check MII")); 45793859Sml29623 return (status); 45803859Sml29623 } 45813859Sml29623 45826835Syc148097 /* 45836835Syc148097 * Check PCS to see if there is any link status change. 45846835Syc148097 * This function is called by PORT_1G_SERDES only. 45856835Syc148097 */ 45866835Syc148097 void 45874977Sraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up) 45884977Sraghus { 45894977Sraghus p_nxge_stats_t statsp; 45904977Sraghus boolean_t linkup; 45914977Sraghus 45924977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check")); 45934977Sraghus 45944977Sraghus statsp = nxgep->statsp; 45954977Sraghus *link_up = LINK_NO_CHANGE; 45964977Sraghus 45974977Sraghus (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup); 45984977Sraghus if (linkup) { 45994977Sraghus if (nxgep->link_notify || 46004977Sraghus nxgep->statsp->mac_stats.link_up == 0) { 46014977Sraghus statsp->mac_stats.link_up = 1; 46024977Sraghus statsp->mac_stats.link_speed = 1000; 46034977Sraghus statsp->mac_stats.link_duplex = 2; 46044977Sraghus *link_up = LINK_IS_UP; 46054977Sraghus nxgep->link_notify = B_FALSE; 46064977Sraghus } 46074977Sraghus } else { 46084977Sraghus if (nxgep->link_notify || 46094977Sraghus nxgep->statsp->mac_stats.link_up == 1) { 46104977Sraghus statsp->mac_stats.link_up = 0; 46114977Sraghus statsp->mac_stats.link_speed = 0; 46124977Sraghus statsp->mac_stats.link_duplex = 0; 46134977Sraghus *link_up = LINK_IS_DOWN; 46144977Sraghus nxgep->link_notify = B_FALSE; 46154977Sraghus } 46164977Sraghus } 46174977Sraghus 46184977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check")); 46194977Sraghus } 46204977Sraghus 46213859Sml29623 /* Add a multicast address entry into the HW hash table */ 46223859Sml29623 46233859Sml29623 nxge_status_t 46243859Sml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 46253859Sml29623 { 46263859Sml29623 uint32_t mchash; 46273859Sml29623 p_hash_filter_t hash_filter; 46283859Sml29623 uint16_t hash_bit; 46293859Sml29623 boolean_t rx_init = B_FALSE; 46303859Sml29623 uint_t j; 46313859Sml29623 nxge_status_t status = NXGE_OK; 46323859Sml29623 46333859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 46343859Sml29623 46353859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 46363859Sml29623 mchash = crc32_mchash(addrp); 46373859Sml29623 if (nxgep->hash_filter == NULL) { 46383859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 46396929Smisaki "Allocating hash filter storage.")); 46403859Sml29623 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 46416929Smisaki KM_SLEEP); 46423859Sml29623 } 46433859Sml29623 hash_filter = nxgep->hash_filter; 46443859Sml29623 j = mchash / HASH_REG_WIDTH; 46453859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 46463859Sml29623 hash_filter->hash_filter_regs[j] |= hash_bit; 46473859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]++; 46483859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 46493859Sml29623 hash_filter->hash_ref_cnt++; 46503859Sml29623 rx_init = B_TRUE; 46513859Sml29623 } 46523859Sml29623 if (rx_init) { 46533859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 46543859Sml29623 goto fail; 46553859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 46563859Sml29623 goto fail; 46573859Sml29623 } 46583859Sml29623 46593859Sml29623 RW_EXIT(&nxgep->filter_lock); 46603859Sml29623 46613859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 46623859Sml29623 46633859Sml29623 return (NXGE_OK); 46643859Sml29623 fail: 46653859Sml29623 RW_EXIT(&nxgep->filter_lock); 46663859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 46676929Smisaki "Unable to add multicast address")); 46683859Sml29623 return (status); 46693859Sml29623 } 46703859Sml29623 46713859Sml29623 /* Remove a multicast address entry from the HW hash table */ 46723859Sml29623 46733859Sml29623 nxge_status_t 46743859Sml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 46753859Sml29623 { 46763859Sml29623 uint32_t mchash; 46773859Sml29623 p_hash_filter_t hash_filter; 46783859Sml29623 uint16_t hash_bit; 46793859Sml29623 boolean_t rx_init = B_FALSE; 46803859Sml29623 uint_t j; 46813859Sml29623 nxge_status_t status = NXGE_OK; 46823859Sml29623 46833859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 46843859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 46853859Sml29623 mchash = crc32_mchash(addrp); 46863859Sml29623 if (nxgep->hash_filter == NULL) { 46873859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 46886929Smisaki "Hash filter already de_allocated.")); 46893859Sml29623 RW_EXIT(&nxgep->filter_lock); 46903859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 46913859Sml29623 return (NXGE_OK); 46923859Sml29623 } 46933859Sml29623 hash_filter = nxgep->hash_filter; 46943859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]--; 46953859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 46963859Sml29623 j = mchash / HASH_REG_WIDTH; 46973859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 46983859Sml29623 hash_filter->hash_filter_regs[j] &= ~hash_bit; 46993859Sml29623 hash_filter->hash_ref_cnt--; 47003859Sml29623 rx_init = B_TRUE; 47013859Sml29623 } 47023859Sml29623 if (hash_filter->hash_ref_cnt == 0) { 47033859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 47046929Smisaki "De-allocating hash filter storage.")); 47053859Sml29623 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 47063859Sml29623 nxgep->hash_filter = NULL; 47073859Sml29623 } 47083859Sml29623 47093859Sml29623 if (rx_init) { 47103859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 47113859Sml29623 goto fail; 47123859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 47133859Sml29623 goto fail; 47143859Sml29623 } 47153859Sml29623 RW_EXIT(&nxgep->filter_lock); 47163859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 47173859Sml29623 47183859Sml29623 return (NXGE_OK); 47193859Sml29623 fail: 47203859Sml29623 RW_EXIT(&nxgep->filter_lock); 47213859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 47226929Smisaki "Unable to remove multicast address")); 47233859Sml29623 47243859Sml29623 return (status); 47253859Sml29623 } 47263859Sml29623 47273859Sml29623 /* Set MAC address into MAC address HW registers */ 47283859Sml29623 47293859Sml29623 nxge_status_t 47303859Sml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 47313859Sml29623 { 47323859Sml29623 nxge_status_t status = NXGE_OK; 47333859Sml29623 47343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 47353859Sml29623 47363859Sml29623 MUTEX_ENTER(&nxgep->ouraddr_lock); 47373859Sml29623 /* 47383859Sml29623 * Exit if the address is same as ouraddr or multicast or broadcast 47393859Sml29623 */ 47403859Sml29623 if (((addrp->ether_addr_octet[0] & 01) == 1) || 47416929Smisaki (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 47426929Smisaki (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 47433859Sml29623 goto nxge_set_mac_addr_exit; 47443859Sml29623 } 47453859Sml29623 nxgep->ouraddr = *addrp; 47463859Sml29623 /* 47473859Sml29623 * Set new interface local address and re-init device. 47483859Sml29623 * This is destructive to any other streams attached 47493859Sml29623 * to this device. 47503859Sml29623 */ 47513859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 47523859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 47533859Sml29623 goto fail; 47543859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 47553859Sml29623 goto fail; 47563859Sml29623 47573859Sml29623 RW_EXIT(&nxgep->filter_lock); 47583859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 47593859Sml29623 goto nxge_set_mac_addr_end; 47603859Sml29623 nxge_set_mac_addr_exit: 47613859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 47623859Sml29623 nxge_set_mac_addr_end: 47633859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 47643859Sml29623 47653859Sml29623 return (NXGE_OK); 47663859Sml29623 fail: 47673859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 47683859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 47696929Smisaki "Unable to set mac address")); 47703859Sml29623 return (status); 47713859Sml29623 } 47723859Sml29623 47734693Stm144005 static 47744693Stm144005 check_link_state_t 47756835Syc148097 nxge_check_link_stop(nxge_t *nxge) 47764693Stm144005 { 47774693Stm144005 /* If the poll has been cancelled, return STOP. */ 47784693Stm144005 MUTEX_ENTER(&nxge->poll_lock); 47794693Stm144005 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 47804693Stm144005 nxge->poll_state = LINK_MONITOR_STOP; 47814693Stm144005 nxge->nxge_link_poll_timerid = 0; 47824693Stm144005 cv_broadcast(&nxge->poll_cv); 47834693Stm144005 MUTEX_EXIT(&nxge->poll_lock); 47844693Stm144005 47854693Stm144005 NXGE_DEBUG_MSG((nxge, MAC_CTL, 47864693Stm144005 "nxge_check_%s_link(port<%d>) stopped.", 47874693Stm144005 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 47884693Stm144005 nxge->mac.portnum)); 47894693Stm144005 return (CHECK_LINK_STOP); 47904693Stm144005 } 47914693Stm144005 MUTEX_EXIT(&nxge->poll_lock); 47924693Stm144005 47934693Stm144005 return (CHECK_LINK_RESCHEDULE); 47944693Stm144005 } 47954693Stm144005 47966835Syc148097 /* 47976835Syc148097 * Check status of MII (MIF or PCS) link. 47986835Syc148097 * This function is called once per second, that is because this function 47996835Syc148097 * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to 48006835Syc148097 * call this function recursively. 48016835Syc148097 */ 48024732Sdavemq static nxge_status_t 48033859Sml29623 nxge_check_mii_link(p_nxge_t nxgep) 48043859Sml29623 { 48053859Sml29623 mii_bmsr_t bmsr_ints, bmsr_data; 48063859Sml29623 mii_anlpar_t anlpar; 48073859Sml29623 mii_gsr_t gsr; 48083859Sml29623 p_mii_regs_t mii_regs; 48093859Sml29623 nxge_status_t status = NXGE_OK; 48103859Sml29623 uint8_t portn; 48113859Sml29623 nxge_link_state_t link_up; 48123859Sml29623 48134693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 48144693Stm144005 return (NXGE_ERROR); 48154693Stm144005 48164693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 48174693Stm144005 return (NXGE_OK); 48184693Stm144005 48193859Sml29623 portn = nxgep->mac.portnum; 48203859Sml29623 48213859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 48224693Stm144005 portn)); 48233859Sml29623 48243859Sml29623 mii_regs = NULL; 48253859Sml29623 48263859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 48273859Sml29623 48283859Sml29623 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 48293859Sml29623 goto nxge_check_mii_link_exit; 48303859Sml29623 48314977Sraghus switch (nxgep->mac.portmode) { 48324977Sraghus default: 48335196Ssbehera bmsr_data.value = 0; 48343859Sml29623 if ((status = nxge_mii_read(nxgep, 48354977Sraghus nxgep->statsp->mac_stats.xcvr_portn, 48365125Sjoycey #if defined(__i386) 48375125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 48385125Sjoycey #else 48394977Sraghus (uint8_t)(uint64_t)(&mii_regs->bmsr), 48405125Sjoycey #endif 48414977Sraghus &bmsr_data.value)) != NXGE_OK) { 48423859Sml29623 goto fail; 48433859Sml29623 } 48444977Sraghus 48455196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 48465196Ssbehera "==> nxge_check_mii_link port<0x%x> " 48475196Ssbehera "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ", 48485572Ssbehera portn, bmsr_data.value, nxgep->bmsr.value)); 48495196Ssbehera 48504977Sraghus if (nxgep->param_arr[param_autoneg].value) { 48514977Sraghus if ((status = nxge_mii_read(nxgep, 48526929Smisaki nxgep->statsp->mac_stats.xcvr_portn, 48535125Sjoycey #if defined(__i386) 48546929Smisaki (uint8_t)(uint32_t)(&mii_regs->gsr), 48555125Sjoycey #else 48566929Smisaki (uint8_t)(uint64_t)(&mii_regs->gsr), 48575125Sjoycey #endif 48586929Smisaki &gsr.value)) != NXGE_OK) 48594977Sraghus goto fail; 48604977Sraghus if ((status = nxge_mii_read(nxgep, 48616929Smisaki nxgep->statsp->mac_stats.xcvr_portn, 48625125Sjoycey #if defined(__i386) 48636929Smisaki (uint8_t)(uint32_t)(&mii_regs->anlpar), 48645125Sjoycey #else 48656929Smisaki (uint8_t)(uint64_t)(&mii_regs->anlpar), 48665125Sjoycey #endif 48676929Smisaki &anlpar.value)) != NXGE_OK) 48684977Sraghus goto fail; 48695196Ssbehera if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) { 48705196Ssbehera 48715196Ssbehera if (nxgep->statsp->mac_stats.link_up && 48725196Ssbehera ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 48735196Ssbehera gsr.bits.link_1000fdx) || 48745196Ssbehera (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 48755196Ssbehera gsr.bits.link_1000hdx) || 48765196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 48775196Ssbehera anlpar.bits.cap_100T4) || 48785196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 48795196Ssbehera anlpar.bits.cap_100fdx) || 48805196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 48815196Ssbehera anlpar.bits.cap_100hdx) || 48825196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 48835196Ssbehera anlpar.bits.cap_10fdx) || 48845196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 48855196Ssbehera anlpar.bits.cap_10hdx))) { 48865196Ssbehera bmsr_data.bits.link_status = 0; 48875196Ssbehera } 48884977Sraghus } 48894977Sraghus } 48904977Sraghus 48914977Sraghus /* Workaround for link down issue */ 48924977Sraghus if (bmsr_data.value == 0) { 48934977Sraghus cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 48944977Sraghus goto nxge_check_mii_link_exit; 48954977Sraghus } 48964977Sraghus 48975196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 48985196Ssbehera "==> nxge_check_mii_link port<0x%x> :" 48995196Ssbehera "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x", 49005572Ssbehera portn, nxgep->bmsr.value, bmsr_data.value)); 49015196Ssbehera 49024977Sraghus bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 49034977Sraghus nxgep->bmsr.value = bmsr_data.value; 49045196Ssbehera 49055196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49065196Ssbehera "==> nxge_check_mii_link port<0x%x> CALLING " 49075196Ssbehera "bmsr_data 0x%x bmsr_ints.value 0x%x", 49085572Ssbehera portn, bmsr_data.value, bmsr_ints.value)); 49095196Ssbehera 49104977Sraghus if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, 49114977Sraghus &link_up)) != NXGE_OK) { 49124977Sraghus goto fail; 49134977Sraghus } 49144977Sraghus break; 49154977Sraghus 49164977Sraghus case PORT_1G_SERDES: 49176835Syc148097 /* 49186835Syc148097 * Above default is for all cases except PORT_1G_SERDES. 49196835Syc148097 * The default case gets information from the PHY, but a 49206835Syc148097 * nxge whose portmode equals PORT_1G_SERDES does not 49216835Syc148097 * have a PHY. 49226835Syc148097 */ 49234977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49244977Sraghus "==> nxge_check_mii_link port<%d> (SERDES)", portn)); 49256835Syc148097 nxge_pcs_check(nxgep, portn, &link_up); 49264977Sraghus break; 49273859Sml29623 } 49283859Sml29623 49293859Sml29623 nxge_check_mii_link_exit: 49303859Sml29623 RW_EXIT(&nxgep->filter_lock); 49313859Sml29623 if (link_up == LINK_IS_UP) { 49323859Sml29623 nxge_link_is_up(nxgep); 49333859Sml29623 } else if (link_up == LINK_IS_DOWN) { 49343859Sml29623 nxge_link_is_down(nxgep); 49353859Sml29623 } 49363859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 49373859Sml29623 49383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 49396929Smisaki portn)); 49403859Sml29623 return (NXGE_OK); 49413859Sml29623 49423859Sml29623 fail: 49433859Sml29623 RW_EXIT(&nxgep->filter_lock); 49443859Sml29623 49453859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 49463859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 49476929Smisaki "nxge_check_mii_link: Failed to check link port<%d>", portn)); 49483859Sml29623 return (status); 49493859Sml29623 } 49503859Sml29623 49513859Sml29623 /*ARGSUSED*/ 49524732Sdavemq static nxge_status_t 49533859Sml29623 nxge_check_10g_link(p_nxge_t nxgep) 49543859Sml29623 { 49553859Sml29623 uint8_t portn; 49563859Sml29623 nxge_status_t status = NXGE_OK; 49575422Ssbehera boolean_t link_up; 49584977Sraghus uint32_t val; 49594977Sraghus npi_status_t rs; 49603859Sml29623 49614693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 49624693Stm144005 return (NXGE_ERROR); 49634693Stm144005 49644693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 49654693Stm144005 return (NXGE_OK); 49664693Stm144005 49673859Sml29623 portn = nxgep->mac.portnum; 49685196Ssbehera val = 0; 49695196Ssbehera rs = NPI_SUCCESS; 49703859Sml29623 49713859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 49724693Stm144005 portn)); 49733859Sml29623 49744977Sraghus switch (nxgep->mac.portmode) { 49754977Sraghus default: 49765572Ssbehera /* 49775572Ssbehera * Check if the phy is present in case of hot swappable phy 49785572Ssbehera */ 49795572Ssbehera if (nxgep->hot_swappable_phy) { 49805572Ssbehera boolean_t phy_present_now = B_FALSE; 49815572Ssbehera 49825572Ssbehera /* 49835572Ssbehera * If this is the 2nd Goa port, then check 2 addresses 49845572Ssbehera * to take care of the Goa NEM card requirements. 49855572Ssbehera */ 49865572Ssbehera if (portn == 1) { 49875572Ssbehera if (nxge_is_phy_present(nxgep, 49886835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR, 49895572Ssbehera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 49905572Ssbehera phy_present_now = B_TRUE; 49915572Ssbehera nxgep->xcvr_addr = 49926835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR; 49935572Ssbehera goto phy_check_done; 49945572Ssbehera } 49955572Ssbehera } 49965572Ssbehera if (nxge_is_phy_present(nxgep, 49976835Syc148097 (GOA_CLAUSE45_PORT_ADDR_BASE) + portn, 49985572Ssbehera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 49995572Ssbehera nxgep->xcvr_addr = 50006835Syc148097 (GOA_CLAUSE45_PORT_ADDR_BASE) + portn; 50015572Ssbehera phy_present_now = B_TRUE; 50025572Ssbehera } 50035572Ssbehera 50045572Ssbehera phy_check_done: 5005*9599Stc99174@train /* Check back-to-back XAUI connect to detect Opus NEM */ 5006*9599Stc99174@train rs = npi_xmac_xpcs_read(nxgep->npi_handle, 5007*9599Stc99174@train nxgep->mac.portnum, XPCS_REG_STATUS, &val); 5008*9599Stc99174@train if (rs != 0) 5009*9599Stc99174@train goto fail; 5010*9599Stc99174@train 5011*9599Stc99174@train link_up = B_FALSE; 5012*9599Stc99174@train if (val & XPCS_STATUS_LANE_ALIGN) { 5013*9599Stc99174@train link_up = B_TRUE; 5014*9599Stc99174@train } 5015*9599Stc99174@train 50165572Ssbehera if (nxgep->phy_absent) { 50175572Ssbehera if (phy_present_now) { 50185572Ssbehera /* 50195572Ssbehera * Detect, Initialize phy and do link up 50205572Ssbehera * set xcvr vals, link_init, nxge_init 50215572Ssbehera */ 50225572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50235572Ssbehera "Hot swappable phy DETECTED!!")); 50245572Ssbehera nxgep->phy_absent = B_FALSE; 50255572Ssbehera (void) nxge_xcvr_find(nxgep); 50265572Ssbehera (void) nxge_link_init(nxgep); 50275572Ssbehera if (!(nxgep->drv_state & 50285572Ssbehera STATE_HW_INITIALIZED)) { 50295572Ssbehera status = nxge_init(nxgep); 50305572Ssbehera if (status != NXGE_OK) { 50315572Ssbehera NXGE_ERROR_MSG((nxgep, 50325572Ssbehera NXGE_ERR_CTL, 50335572Ssbehera "Hot swappable " 50345572Ssbehera "phy present, but" 50355572Ssbehera " driver init" 50365572Ssbehera " failed...")); 50375572Ssbehera goto fail; 50385572Ssbehera } 50395572Ssbehera } 5040*9599Stc99174@train } else if (link_up) { /* XAUI linkup, no PHY */ 5041*9599Stc99174@train /* 5042*9599Stc99174@train * This is the back-to-back XAUI 5043*9599Stc99174@train * connect case for Opus NEM. 5044*9599Stc99174@train */ 5045*9599Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = 5046*9599Stc99174@train XPCS_XCVR; 5047*9599Stc99174@train nxgep->mac.portmode = PORT_10G_SERDES; 5048*9599Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5049*9599Stc99174@train "HSP 10G Serdes DETECTED!!")); 5050*9599Stc99174@train break; 50515572Ssbehera } 50525572Ssbehera 50535572Ssbehera goto start_link_check; 50545572Ssbehera 50555572Ssbehera } else if (!phy_present_now) { 50565572Ssbehera /* 50575572Ssbehera * Phy gone, bring link down reset xcvr vals 50585572Ssbehera */ 50595572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50605572Ssbehera "Hot swappable phy REMOVED!!")); 50615572Ssbehera nxgep->phy_absent = B_TRUE; 50625572Ssbehera nxgep->statsp->mac_stats.link_up = 0; 50635572Ssbehera nxgep->statsp->mac_stats.link_speed = 0; 50645572Ssbehera nxgep->statsp->mac_stats.link_duplex = 0; 50655572Ssbehera nxge_link_is_down(nxgep); 50665572Ssbehera nxgep->link_notify = B_FALSE; 50675572Ssbehera 50685572Ssbehera (void) nxge_xcvr_find(nxgep); 50695572Ssbehera 50705572Ssbehera goto start_link_check; 50715572Ssbehera 50725572Ssbehera } 50735572Ssbehera } 50746604Ssbehera if (nxgep->chip_id == MRVL88X201X_CHIP_ID) { 50756835Syc148097 status = nxge_check_mrvl88x2011_link(nxgep, &link_up); 50766604Ssbehera } else { 50776604Ssbehera status = nxge_check_bcm8704_link(nxgep, &link_up); 50786604Ssbehera } 50794977Sraghus if (status != NXGE_OK) 50804977Sraghus goto fail; 50814977Sraghus break; 50824977Sraghus case PORT_10G_SERDES: 50834977Sraghus rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 50845422Ssbehera XPCS_REG_STATUS, &val); 50854977Sraghus if (rs != 0) 50864977Sraghus goto fail; 50874977Sraghus 50884977Sraghus link_up = B_FALSE; 50895422Ssbehera if (val & XPCS_STATUS_LANE_ALIGN) { 50905422Ssbehera link_up = B_TRUE; 50914977Sraghus } 50924977Sraghus 50934977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 50944977Sraghus "==> nxge_check_10g_link port<%d> " 50955422Ssbehera "XPCS_REG_STATUS2 0x%x link_up %d", 50965422Ssbehera portn, val, link_up)); 50975422Ssbehera 50984977Sraghus break; 50994977Sraghus } 51003859Sml29623 51013859Sml29623 if (link_up) { 51023859Sml29623 if (nxgep->link_notify || 51036929Smisaki nxgep->statsp->mac_stats.link_up == 0) { 51043859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 51053859Sml29623 goto fail; 51063859Sml29623 nxgep->statsp->mac_stats.link_up = 1; 51073859Sml29623 nxgep->statsp->mac_stats.link_speed = 10000; 51083859Sml29623 nxgep->statsp->mac_stats.link_duplex = 2; 51093859Sml29623 51103859Sml29623 nxge_link_is_up(nxgep); 51113859Sml29623 nxgep->link_notify = B_FALSE; 51123859Sml29623 } 51133859Sml29623 } else { 51143859Sml29623 if (nxgep->link_notify || 51156929Smisaki nxgep->statsp->mac_stats.link_up == 1) { 51163859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 51173859Sml29623 goto fail; 51183859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51196929Smisaki "Link down cable problem")); 51203859Sml29623 nxgep->statsp->mac_stats.link_up = 0; 51213859Sml29623 nxgep->statsp->mac_stats.link_speed = 0; 51223859Sml29623 nxgep->statsp->mac_stats.link_duplex = 0; 51233859Sml29623 51243859Sml29623 nxge_link_is_down(nxgep); 51253859Sml29623 nxgep->link_notify = B_FALSE; 5126*9599Stc99174@train 5127*9599Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES) { 5128*9599Stc99174@train /* 5129*9599Stc99174@train * NEM was unplugged, set up xcvr table 5130*9599Stc99174@train * to find another xcvr in the future. 5131*9599Stc99174@train */ 5132*9599Stc99174@train (void) nxge_xcvr_find(nxgep); 5133*9599Stc99174@train } 51343859Sml29623 } 51353859Sml29623 } 51363859Sml29623 51375572Ssbehera start_link_check: 51383859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 51393859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 51404693Stm144005 portn)); 51413859Sml29623 return (NXGE_OK); 51423859Sml29623 51433859Sml29623 fail: 51444693Stm144005 (void) nxge_check_link_stop(nxgep); 51454693Stm144005 51463859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 51474693Stm144005 "nxge_check_10g_link: Failed to check link port<%d>", 51484693Stm144005 portn)); 51493859Sml29623 return (status); 51503859Sml29623 } 51513859Sml29623 51523859Sml29623 51533859Sml29623 /* Declare link down */ 51543859Sml29623 51553859Sml29623 void 51563859Sml29623 nxge_link_is_down(p_nxge_t nxgep) 51573859Sml29623 { 51584732Sdavemq p_nxge_stats_t statsp; 51594732Sdavemq char link_stat_msg[64]; 51604732Sdavemq 51613859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 51623859Sml29623 51634732Sdavemq statsp = nxgep->statsp; 51644732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 51654732Sdavemq statsp->mac_stats.xcvr_portn); 51664732Sdavemq 51674732Sdavemq if (nxge_no_msg == B_FALSE) { 51684732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 51694732Sdavemq } 51704732Sdavemq 51713859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 51723859Sml29623 51733859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 51743859Sml29623 } 51753859Sml29623 51763859Sml29623 /* Declare link up */ 51773859Sml29623 51783859Sml29623 void 51793859Sml29623 nxge_link_is_up(p_nxge_t nxgep) 51803859Sml29623 { 51814732Sdavemq p_nxge_stats_t statsp; 51824732Sdavemq char link_stat_msg[64]; 51833859Sml29623 uint32_t val; 51843859Sml29623 51853859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 51863859Sml29623 51874732Sdavemq statsp = nxgep->statsp; 51884732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 51894732Sdavemq statsp->mac_stats.xcvr_portn, 51904732Sdavemq statsp->mac_stats.link_speed); 51914732Sdavemq 51924732Sdavemq if (statsp->mac_stats.link_T4) 51934732Sdavemq (void) strcat(link_stat_msg, "T4"); 51944732Sdavemq else if (statsp->mac_stats.link_duplex == 2) 51954732Sdavemq (void) strcat(link_stat_msg, "full duplex"); 51964732Sdavemq else 51974732Sdavemq (void) strcat(link_stat_msg, "half duplex"); 51984732Sdavemq 51993859Sml29623 52003859Sml29623 /* Clean up symbol errors incurred during link transition */ 52014977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER) || 52024977Sraghus (nxgep->mac.portmode == PORT_10G_SERDES)) { 52033859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 52046929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 52053859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 52066929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 52073859Sml29623 } 52083859Sml29623 52096835Syc148097 /* 52106835Syc148097 * If the driver was plumbed without a link (therefore auto-negotiation 52116835Syc148097 * could not complete), the driver will detect a link up when a cable 52126835Syc148097 * conneting to a link partner is plugged into the port. By the time 52136835Syc148097 * link-up is detected, auto-negotiation should have completed (The 52146835Syc148097 * TN1010 tries to contact a link partner every 8~24ms). Here we re- 52156835Syc148097 * configure the Neptune/NIU according to the newly negotiated speed. 52166835Syc148097 * This is necessary only for the TN1010 basad device because only the 52176835Syc148097 * TN1010 supports dual speeds. 52186835Syc148097 */ 52196835Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 || 52206835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) { 52216835Syc148097 52226835Syc148097 (void) nxge_set_tn1010_param(nxgep); 52236835Syc148097 52246835Syc148097 /* 52256835Syc148097 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets 52266835Syc148097 * nxgep->portmode) and nxge_setup_xcvr_table (which sets 52276835Syc148097 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct). 52286835Syc148097 */ 52296835Syc148097 if (nxge_xcvr_find(nxgep) != NXGE_OK) { 52306835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52316835Syc148097 "nxge_link_is_up: nxge_xcvr_find failed")); 52326835Syc148097 } 52336835Syc148097 52346835Syc148097 /* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */ 52356835Syc148097 if (nxge_link_init(nxgep) != NXGE_OK) { 52366835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52376835Syc148097 "nxge_link_is_up: nxge_link_init failed")); 52386835Syc148097 } 52396835Syc148097 52406835Syc148097 /* 52416835Syc148097 * nxge_mac_init calls many subroutines including 52426835Syc148097 * nxge_xif_init which sets XGMII or GMII mode 52436835Syc148097 */ 52446835Syc148097 if (nxge_mac_init(nxgep) != NXGE_OK) { 52456835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52466835Syc148097 "nxge_link_is_up: nxge_mac_init failed")); 52476835Syc148097 } 52486835Syc148097 } else { 52496835Syc148097 (void) nxge_xif_init(nxgep); 52506835Syc148097 } 52516835Syc148097 52524732Sdavemq if (nxge_no_msg == B_FALSE) { 52534732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 52544732Sdavemq } 52554732Sdavemq 52563859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_UP); 52573859Sml29623 52583859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 52593859Sml29623 } 52603859Sml29623 52616835Syc148097 #ifdef NXGE_DEBUG 52626835Syc148097 /* Dump all TN1010 Status registers */ 52636835Syc148097 static void 52646835Syc148097 nxge_dump_tn1010_status_regs(p_nxge_t nxgep) 52656835Syc148097 { 52666835Syc148097 uint16_t val; 52676835Syc148097 52686835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52696835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 1, &val); 52706835Syc148097 cmn_err(CE_NOTE, "PMA status1 = 0x%x", val); 52716835Syc148097 52726835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52736835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 8, &val); 52746835Syc148097 cmn_err(CE_NOTE, "PMA status2 = 0x%x", val); 52756835Syc148097 52766835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52776835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 129, &val); 52786835Syc148097 cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val); 52796835Syc148097 52806835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52816835Syc148097 TN1010_PCS_DEV_ADDR, 1, &val); 52826835Syc148097 cmn_err(CE_NOTE, "PCS status1 = 0x%x", val); 52836835Syc148097 52846835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52856835Syc148097 TN1010_PCS_DEV_ADDR, 8, &val); 52866835Syc148097 cmn_err(CE_NOTE, "PCS status2 = 0x%x", val); 52876835Syc148097 52886835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52896835Syc148097 TN1010_PCS_DEV_ADDR, 32, &val); 52906835Syc148097 cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val); 52916835Syc148097 52926835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52936835Syc148097 TN1010_PCS_DEV_ADDR, 33, &val); 52946835Syc148097 cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val); 52956835Syc148097 52966835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 52976835Syc148097 TN1010_PHYXS_DEV_ADDR, 1, &val); 52986835Syc148097 cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val); 52996835Syc148097 53006835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53016835Syc148097 TN1010_PHYXS_DEV_ADDR, 8, &val); 53026835Syc148097 cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val); 53036835Syc148097 53046835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53056835Syc148097 TN1010_PHYXS_DEV_ADDR, 24, &val); 53066835Syc148097 cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val); 53076835Syc148097 53086835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53096835Syc148097 TN1010_AUTONEG_DEV_ADDR, 1, &val); 53106835Syc148097 cmn_err(CE_NOTE, "Autoneg status = 0x%x", val); 53116835Syc148097 53126835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53136835Syc148097 TN1010_AUTONEG_DEV_ADDR, 33, &val); 53146835Syc148097 cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val); 53156835Syc148097 53166835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53176835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val); 53186835Syc148097 cmn_err(CE_NOTE, "TN1010 status = 0x%x", val); 53196835Syc148097 53206835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53216835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val); 53226835Syc148097 cmn_err(CE_NOTE, "Device status = 0x%x", val); 53236835Syc148097 53246835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53256835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val); 53266835Syc148097 cmn_err(CE_NOTE, "DDR status = 0x%x", val); 53276835Syc148097 53286835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53296835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val); 53306835Syc148097 cmn_err(CE_NOTE, "DDR fault status = 0x%x", val); 53316835Syc148097 53326835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 53336835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val); 53346835Syc148097 cmn_err(CE_NOTE, "Firmware Revision = 0x%x Major = 0x%x Minor = 0x%x", 53356835Syc148097 val, (val & 0xFF00) >> 8, val & 0x00FF); 53366835Syc148097 } 53376835Syc148097 #endif 53386835Syc148097 53393859Sml29623 /* 53403859Sml29623 * Calculate the bit in the multicast address filter 53413859Sml29623 * that selects the given * address. 53423859Sml29623 * Note: For GEM, the last 8-bits are used. 53433859Sml29623 */ 53443859Sml29623 uint32_t 53453859Sml29623 crc32_mchash(p_ether_addr_t addr) 53463859Sml29623 { 53473859Sml29623 uint8_t *cp; 53483859Sml29623 uint32_t crc; 53493859Sml29623 uint32_t c; 53503859Sml29623 int byte; 53513859Sml29623 int bit; 53523859Sml29623 53533859Sml29623 cp = (uint8_t *)addr; 53543859Sml29623 crc = (uint32_t)0xffffffff; 53553859Sml29623 for (byte = 0; byte < 6; byte++) { 53563859Sml29623 c = (uint32_t)cp[byte]; 53573859Sml29623 for (bit = 0; bit < 8; bit++) { 53583859Sml29623 if ((c & 0x1) ^ (crc & 0x1)) 53593859Sml29623 crc = (crc >> 1)^0xedb88320; 53603859Sml29623 else 53613859Sml29623 crc = (crc >> 1); 53623859Sml29623 c >>= 1; 53633859Sml29623 } 53643859Sml29623 } 53653859Sml29623 return ((~crc) >> (32 - HASH_BITS)); 53663859Sml29623 } 53673859Sml29623 53683859Sml29623 /* Reset serdes */ 53693859Sml29623 53703859Sml29623 nxge_status_t 53713859Sml29623 nxge_serdes_reset(p_nxge_t nxgep) 53723859Sml29623 { 53733859Sml29623 npi_handle_t handle; 53743859Sml29623 53753859Sml29623 handle = nxgep->npi_handle; 53763859Sml29623 53773859Sml29623 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 53783859Sml29623 drv_usecwait(500); 53793859Sml29623 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 53803859Sml29623 53813859Sml29623 return (NXGE_OK); 53823859Sml29623 } 53833859Sml29623 53846835Syc148097 /* 53856835Syc148097 * This function monitors link status using interrupt or polling. 53866835Syc148097 * It calls nxgep->xcvr.check_link, a member function of 53876835Syc148097 * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this 53886835Syc148097 * function back, that is why the check_link routine is 53896835Syc148097 * executed periodically. 53906835Syc148097 */ 53913859Sml29623 nxge_status_t 53923859Sml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 53933859Sml29623 { 53943859Sml29623 nxge_status_t status = NXGE_OK; 53953859Sml29623 53966495Sspeer /* If we are a guest domain driver, don't bother. */ 53976495Sspeer if (isLDOMguest(nxgep)) 53986495Sspeer return (status); 53996495Sspeer 54003859Sml29623 /* 54014693Stm144005 * Return immediately if this is an imaginary XMAC port. 54024693Stm144005 * (At least, we don't have 4-port XMAC cards yet.) 54033859Sml29623 */ 54044977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER || 54054977Sraghus nxgep->mac.portmode == PORT_10G_SERDES) && 54064977Sraghus (nxgep->mac.portnum > 1)) 54073859Sml29623 return (NXGE_OK); 54083859Sml29623 54093859Sml29623 if (nxgep->statsp == NULL) { 54103859Sml29623 /* stats has not been allocated. */ 54113859Sml29623 return (NXGE_OK); 54123859Sml29623 } 54136075Ssbehera /* Don't check link if we're in internal loopback mode */ 54146075Ssbehera if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g) 54153859Sml29623 return (NXGE_OK); 54163859Sml29623 54173859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 54184693Stm144005 "==> nxge_link_monitor port<%d> enable=%d", 54194693Stm144005 nxgep->mac.portnum, enable)); 54203859Sml29623 if (enable == LINK_MONITOR_START) { 54213859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 54223859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 54234693Stm144005 != NXGE_OK) 54243859Sml29623 goto fail; 54253859Sml29623 } else { 54264693Stm144005 timeout_id_t timerid; 54276835Syc148097 /* 54286835Syc148097 * check_link_stop means "Stop the link check", so 54296835Syc148097 * we return without starting the timer. 54306835Syc148097 */ 54314693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 54324693Stm144005 return (NXGE_OK); 54334693Stm144005 54346835Syc148097 /* 54356835Syc148097 * Otherwise fire the timer for the nxge to check 54366835Syc148097 * the link using the check_link function 54376835Syc148097 * of the nxge_xcvr_table and pass "nxgep" as the 54386835Syc148097 * argument to the check_link function. 54396835Syc148097 */ 54404732Sdavemq if (nxgep->xcvr.check_link) { 54414732Sdavemq timerid = timeout( 54424732Sdavemq (fptrv_t)(nxgep->xcvr.check_link), 54434693Stm144005 nxgep, 54444693Stm144005 drv_usectohz(LINK_MONITOR_PERIOD)); 54454732Sdavemq MUTEX_ENTER(&nxgep->poll_lock); 54464732Sdavemq nxgep->nxge_link_poll_timerid = timerid; 54474732Sdavemq MUTEX_EXIT(&nxgep->poll_lock); 54484732Sdavemq } else { 54494693Stm144005 return (NXGE_ERROR); 54503859Sml29623 } 54513859Sml29623 } 54523859Sml29623 } else { 54533859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 54543859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 54554693Stm144005 != NXGE_OK) 54563859Sml29623 goto fail; 54573859Sml29623 } else { 54584693Stm144005 clock_t rv; 54594693Stm144005 54604693Stm144005 MUTEX_ENTER(&nxgep->poll_lock); 54614693Stm144005 54624693Stm144005 /* If <timerid> == 0, the link monitor has */ 54634693Stm144005 /* never been started, or just now stopped. */ 54644693Stm144005 if (nxgep->nxge_link_poll_timerid == 0) { 54654693Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 54664693Stm144005 return (NXGE_OK); 54674693Stm144005 } 54684693Stm144005 54694693Stm144005 nxgep->poll_state = LINK_MONITOR_STOPPING; 54704693Stm144005 rv = cv_timedwait(&nxgep->poll_cv, 54714693Stm144005 &nxgep->poll_lock, 54724693Stm144005 ddi_get_lbolt() + 54734693Stm144005 drv_usectohz(LM_WAIT_MULTIPLIER * 54744693Stm144005 LINK_MONITOR_PERIOD)); 54754693Stm144005 if (rv == -1) { 54764693Stm144005 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 54774693Stm144005 "==> stopping port %d: " 54784693Stm144005 "cv_timedwait(%d) timed out", 54794693Stm144005 nxgep->mac.portnum, nxgep->poll_state)); 54804693Stm144005 nxgep->poll_state = LINK_MONITOR_STOP; 54813859Sml29623 nxgep->nxge_link_poll_timerid = 0; 54823859Sml29623 } 54834693Stm144005 54844693Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 54853859Sml29623 } 54863859Sml29623 } 54873859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 54884693Stm144005 "<== nxge_link_monitor port<%d> enable=%d", 54894693Stm144005 nxgep->mac.portnum, enable)); 54906495Sspeer 54913859Sml29623 return (NXGE_OK); 54923859Sml29623 fail: 54933859Sml29623 return (status); 54946835Syc148097 54953859Sml29623 } 54963859Sml29623 54976835Syc148097 nxge_status_t 54986835Syc148097 nxge_check_tn1010_link(p_nxge_t nxgep) 54996835Syc148097 { 55006835Syc148097 nxge_status_t status = NXGE_OK; 55016835Syc148097 nxge_link_state_t link_up; 55026835Syc148097 55036835Syc148097 if (nxgep->nxge_magic != NXGE_MAGIC) { 55046835Syc148097 /* magic is 0 if driver is not attached */ 55056835Syc148097 return (NXGE_ERROR); 55066835Syc148097 } 55076835Syc148097 55086835Syc148097 /* Link has been stopped, no need to continue */ 55096835Syc148097 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) { 55106835Syc148097 return (NXGE_OK); 55116835Syc148097 } 55126835Syc148097 55136835Syc148097 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 55146835Syc148097 goto nxge_check_tn1010_link_exit; 55156835Syc148097 55166835Syc148097 if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK) 55176835Syc148097 goto fail; 55186835Syc148097 55196835Syc148097 nxge_check_tn1010_link_exit: 55206835Syc148097 if (link_up == LINK_IS_UP) 55216835Syc148097 nxge_link_is_up(nxgep); 55226835Syc148097 else if (link_up == LINK_IS_DOWN) 55236835Syc148097 nxge_link_is_down(nxgep); 55246835Syc148097 55256835Syc148097 /* 55266835Syc148097 * nxge_link_monitor will call (nxgep->xcvr.check_link) 55276835Syc148097 * which could be THIS function. 55286835Syc148097 */ 55296835Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 55306835Syc148097 55316835Syc148097 return (NXGE_OK); 55326835Syc148097 55336835Syc148097 fail: 55346835Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 55356835Syc148097 55366835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 55376835Syc148097 "nxge_check_tn1010_link: Failed to check link")); 55386835Syc148097 return (status); 55396835Syc148097 } 55406835Syc148097 55416835Syc148097 55426835Syc148097 /* 55436835Syc148097 * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN. 55446835Syc148097 */ 55456835Syc148097 static nxge_status_t 55466835Syc148097 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up) 55476835Syc148097 { 55486835Syc148097 nxge_status_t status = NXGE_OK; 55496835Syc148097 p_nxge_stats_t statsp; 55506835Syc148097 uint8_t phy_port_addr, portn; 55516835Syc148097 uint16_t val; 55526835Syc148097 55536835Syc148097 *link_up = LINK_NO_CHANGE; 55546835Syc148097 55556835Syc148097 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 55566835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 55576835Syc148097 statsp = nxgep->statsp; 55586835Syc148097 55596835Syc148097 /* Check if link is up */ 55606835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 55616835Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val)) 55626835Syc148097 != NXGE_OK) { 55636835Syc148097 goto fail; 55646835Syc148097 } 55656835Syc148097 /* 55666835Syc148097 * nxge_link_is_up has called nxge_set_tn1010_param and set 55676835Syc148097 * portmode and link_speed 55686835Syc148097 */ 55696835Syc148097 if (val & TN1010_AN_LINK_STAT_BIT) { 55706835Syc148097 if (nxgep->link_notify || 55716835Syc148097 nxgep->statsp->mac_stats.link_up == 0) { 55726835Syc148097 statsp->mac_stats.link_up = 1; 55736835Syc148097 statsp->mac_stats.link_duplex = 2; 55746835Syc148097 *link_up = LINK_IS_UP; 55756835Syc148097 nxgep->link_notify = B_FALSE; 55766835Syc148097 } 55776835Syc148097 } else { 55786835Syc148097 if (nxgep->link_notify || 55796835Syc148097 nxgep->statsp->mac_stats.link_up == 1) { 55806835Syc148097 statsp->mac_stats.link_up = 0; 55816835Syc148097 statsp->mac_stats.link_speed = 0; 55826835Syc148097 statsp->mac_stats.link_duplex = 0; 55836835Syc148097 *link_up = LINK_IS_DOWN; 55846835Syc148097 nxgep->link_notify = B_FALSE; 55856835Syc148097 } 55866835Syc148097 } 55876835Syc148097 return (NXGE_OK); 55886835Syc148097 55896835Syc148097 fail: 55906835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 55916835Syc148097 "nxge_tn1010_check: Unable to check TN1010")); 55926835Syc148097 return (status); 55936835Syc148097 } 55946835Syc148097 55956835Syc148097 55963859Sml29623 /* Set promiscous mode */ 55973859Sml29623 55983859Sml29623 nxge_status_t 55993859Sml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 56003859Sml29623 { 56013859Sml29623 nxge_status_t status = NXGE_OK; 56023859Sml29623 56034732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 56043859Sml29623 56053859Sml29623 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 56063859Sml29623 56073859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 56083859Sml29623 56093859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 56103859Sml29623 goto fail; 56113859Sml29623 } 56123859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 56133859Sml29623 goto fail; 56143859Sml29623 } 56153859Sml29623 56163859Sml29623 RW_EXIT(&nxgep->filter_lock); 56173859Sml29623 56183859Sml29623 if (on) 56193859Sml29623 nxgep->statsp->mac_stats.promisc = B_TRUE; 56203859Sml29623 else 56213859Sml29623 nxgep->statsp->mac_stats.promisc = B_FALSE; 56223859Sml29623 56233859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 56243859Sml29623 56253859Sml29623 return (NXGE_OK); 56263859Sml29623 fail: 56273859Sml29623 RW_EXIT(&nxgep->filter_lock); 56283859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 56294732Sdavemq "Unable to set promisc (%d)", on)); 56303859Sml29623 56313859Sml29623 return (status); 56323859Sml29623 } 56333859Sml29623 56343859Sml29623 /*ARGSUSED*/ 56353859Sml29623 uint_t 56363859Sml29623 nxge_mif_intr(void *arg1, void *arg2) 56373859Sml29623 { 56383859Sml29623 #ifdef NXGE_DEBUG 56393859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 56403859Sml29623 #endif 56413859Sml29623 #if NXGE_MIF 56423859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 56433859Sml29623 uint32_t status; 56443859Sml29623 npi_handle_t handle; 56453859Sml29623 uint8_t portn; 56463859Sml29623 p_nxge_stats_t statsp; 56473859Sml29623 #endif 56483859Sml29623 56493859Sml29623 #ifdef NXGE_MIF 56503859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 56513859Sml29623 nxgep = ldvp->nxgep; 56523859Sml29623 } 56533859Sml29623 nxgep = ldvp->nxgep; 56543859Sml29623 #endif 56553859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 56563859Sml29623 56573859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 56583859Sml29623 return (DDI_INTR_CLAIMED); 56593859Sml29623 56603859Sml29623 mif_intr_fail: 56613859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 56623859Sml29623 return (DDI_INTR_UNCLAIMED); 56633859Sml29623 } 56643859Sml29623 56653859Sml29623 /*ARGSUSED*/ 56663859Sml29623 uint_t 56673859Sml29623 nxge_mac_intr(void *arg1, void *arg2) 56683859Sml29623 { 56693859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 56703859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 56713859Sml29623 p_nxge_ldg_t ldgp; 56723859Sml29623 uint32_t status; 56733859Sml29623 npi_handle_t handle; 56743859Sml29623 uint8_t portn; 56753859Sml29623 p_nxge_stats_t statsp; 56763859Sml29623 npi_status_t rs = NPI_SUCCESS; 56773859Sml29623 56783859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 56793859Sml29623 nxgep = ldvp->nxgep; 56803859Sml29623 } 56813859Sml29623 56823859Sml29623 ldgp = ldvp->ldgp; 56833859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 56844732Sdavemq "group %d", ldgp->ldg)); 56853859Sml29623 56863859Sml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep); 56873859Sml29623 /* 56883859Sml29623 * This interrupt handler is for a specific 56893859Sml29623 * mac port. 56903859Sml29623 */ 56913859Sml29623 statsp = (p_nxge_stats_t)nxgep->statsp; 56923859Sml29623 portn = nxgep->mac.portnum; 56933859Sml29623 56943859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, 56954732Sdavemq "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 56963859Sml29623 56973859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 56983859Sml29623 rs = npi_xmac_tx_get_istatus(handle, portn, 56996929Smisaki (xmac_tx_iconfig_t *)&status); 57003859Sml29623 if (rs != NPI_SUCCESS) 57013859Sml29623 goto npi_fail; 57023859Sml29623 if (status & ICFG_XMAC_TX_ALL) { 57033859Sml29623 if (status & ICFG_XMAC_TX_UNDERRUN) { 57043859Sml29623 statsp->xmac_stats.tx_underflow_err++; 57053859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 57066929Smisaki NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 57073859Sml29623 } 57083859Sml29623 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 57093859Sml29623 statsp->xmac_stats.tx_maxpktsize_err++; 57105523Syc148097 /* 57115523Syc148097 * Do not send FMA ereport because this 57125523Syc148097 * error does not indicate HW failure. 57135523Syc148097 */ 57143859Sml29623 } 57153859Sml29623 if (status & ICFG_XMAC_TX_OVERFLOW) { 57163859Sml29623 statsp->xmac_stats.tx_overflow_err++; 57173859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 57186929Smisaki NXGE_FM_EREPORT_TXMAC_OVERFLOW); 57193859Sml29623 } 57203859Sml29623 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 57213859Sml29623 statsp->xmac_stats.tx_fifo_xfr_err++; 57223859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 57236929Smisaki NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 57243859Sml29623 } 57253859Sml29623 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 57263859Sml29623 statsp->xmac_stats.tx_byte_cnt += 57276929Smisaki XTXMAC_BYTE_CNT_MASK; 57283859Sml29623 } 57293859Sml29623 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 57303859Sml29623 statsp->xmac_stats.tx_frame_cnt += 57316929Smisaki XTXMAC_FRM_CNT_MASK; 57323859Sml29623 } 57333859Sml29623 } 57343859Sml29623 57353859Sml29623 rs = npi_xmac_rx_get_istatus(handle, portn, 57366929Smisaki (xmac_rx_iconfig_t *)&status); 57373859Sml29623 if (rs != NPI_SUCCESS) 57383859Sml29623 goto npi_fail; 57393859Sml29623 if (status & ICFG_XMAC_RX_ALL) { 57403859Sml29623 if (status & ICFG_XMAC_RX_OVERFLOW) 57413859Sml29623 statsp->xmac_stats.rx_overflow_err++; 57423859Sml29623 if (status & ICFG_XMAC_RX_UNDERFLOW) { 57433859Sml29623 statsp->xmac_stats.rx_underflow_err++; 57443859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 57456929Smisaki NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 57463859Sml29623 } 57475523Syc148097 /* 57485523Syc148097 * Do not send FMA ereport for the following 3 errors 57495523Syc148097 * because they do not indicate HW failures. 57505523Syc148097 */ 57513859Sml29623 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 57523859Sml29623 statsp->xmac_stats.rx_crc_err_cnt += 57536929Smisaki XRXMAC_CRC_ER_CNT_MASK; 57543859Sml29623 } 57553859Sml29623 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 57563859Sml29623 statsp->xmac_stats.rx_len_err_cnt += 57576929Smisaki MAC_LEN_ER_CNT_MASK; 57583859Sml29623 } 57593859Sml29623 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 57603859Sml29623 statsp->xmac_stats.rx_viol_err_cnt += 57616929Smisaki XRXMAC_CD_VIO_CNT_MASK; 57623859Sml29623 } 57633859Sml29623 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 57643859Sml29623 statsp->xmac_stats.rx_byte_cnt += 57656929Smisaki XRXMAC_BT_CNT_MASK; 57663859Sml29623 } 57673859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 57683859Sml29623 statsp->xmac_stats.rx_hist1_cnt += 57696929Smisaki XRXMAC_HIST_CNT1_MASK; 57703859Sml29623 } 57713859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 57723859Sml29623 statsp->xmac_stats.rx_hist2_cnt += 57736929Smisaki XRXMAC_HIST_CNT2_MASK; 57743859Sml29623 } 57753859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 57763859Sml29623 statsp->xmac_stats.rx_hist3_cnt += 57776929Smisaki XRXMAC_HIST_CNT3_MASK; 57783859Sml29623 } 57793859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 57803859Sml29623 statsp->xmac_stats.rx_hist4_cnt += 57816929Smisaki XRXMAC_HIST_CNT4_MASK; 57823859Sml29623 } 57833859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 57843859Sml29623 statsp->xmac_stats.rx_hist5_cnt += 57856929Smisaki XRXMAC_HIST_CNT5_MASK; 57863859Sml29623 } 57873859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 57883859Sml29623 statsp->xmac_stats.rx_hist6_cnt += 57896929Smisaki XRXMAC_HIST_CNT6_MASK; 57903859Sml29623 } 57913859Sml29623 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 57923859Sml29623 statsp->xmac_stats.rx_broadcast_cnt += 57936929Smisaki XRXMAC_BC_FRM_CNT_MASK; 57943859Sml29623 } 57953859Sml29623 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 57963859Sml29623 statsp->xmac_stats.rx_mult_cnt += 57976929Smisaki XRXMAC_MC_FRM_CNT_MASK; 57983859Sml29623 } 57995523Syc148097 /* 58005523Syc148097 * Do not send FMA ereport for the following 3 errors 58015523Syc148097 * because they do not indicate HW failures. 58025523Syc148097 */ 58033859Sml29623 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 58043859Sml29623 statsp->xmac_stats.rx_frag_cnt += 58056929Smisaki XRXMAC_FRAG_CNT_MASK; 58063859Sml29623 } 58073859Sml29623 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 58083859Sml29623 statsp->xmac_stats.rx_frame_align_err_cnt += 58096929Smisaki XRXMAC_AL_ER_CNT_MASK; 58103859Sml29623 } 58113859Sml29623 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 58123859Sml29623 statsp->xmac_stats.rx_linkfault_err_cnt += 58136929Smisaki XMAC_LINK_FLT_CNT_MASK; 58143859Sml29623 } 58153859Sml29623 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 58163859Sml29623 statsp->xmac_stats.rx_remotefault_err++; 58173859Sml29623 } 58183859Sml29623 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 58193859Sml29623 statsp->xmac_stats.rx_localfault_err++; 58203859Sml29623 } 58213859Sml29623 } 58223859Sml29623 58233859Sml29623 rs = npi_xmac_ctl_get_istatus(handle, portn, 58246929Smisaki (xmac_ctl_iconfig_t *)&status); 58253859Sml29623 if (rs != NPI_SUCCESS) 58263859Sml29623 goto npi_fail; 58273859Sml29623 if (status & ICFG_XMAC_CTRL_ALL) { 58283859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 58293859Sml29623 statsp->xmac_stats.rx_pause_cnt++; 58303859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 58313859Sml29623 statsp->xmac_stats.tx_pause_state++; 58323859Sml29623 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 58333859Sml29623 statsp->xmac_stats.tx_nopause_state++; 58343859Sml29623 } 58353859Sml29623 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 58363859Sml29623 rs = npi_bmac_tx_get_istatus(handle, portn, 58376929Smisaki (bmac_tx_iconfig_t *)&status); 58383859Sml29623 if (rs != NPI_SUCCESS) 58393859Sml29623 goto npi_fail; 58403859Sml29623 if (status & ICFG_BMAC_TX_ALL) { 58413859Sml29623 if (status & ICFG_BMAC_TX_UNDERFLOW) { 58423859Sml29623 statsp->bmac_stats.tx_underrun_err++; 58433859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58446929Smisaki NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 58453859Sml29623 } 58463859Sml29623 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 58473859Sml29623 statsp->bmac_stats.tx_max_pkt_err++; 58483859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58496929Smisaki NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 58503859Sml29623 } 58513859Sml29623 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 58523859Sml29623 statsp->bmac_stats.tx_byte_cnt += 58536929Smisaki BTXMAC_BYTE_CNT_MASK; 58543859Sml29623 } 58553859Sml29623 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 58563859Sml29623 statsp->bmac_stats.tx_frame_cnt += 58576929Smisaki BTXMAC_FRM_CNT_MASK; 58583859Sml29623 } 58593859Sml29623 } 58603859Sml29623 58613859Sml29623 rs = npi_bmac_rx_get_istatus(handle, portn, 58626929Smisaki (bmac_rx_iconfig_t *)&status); 58633859Sml29623 if (rs != NPI_SUCCESS) 58643859Sml29623 goto npi_fail; 58653859Sml29623 if (status & ICFG_BMAC_RX_ALL) { 58663859Sml29623 if (status & ICFG_BMAC_RX_OVERFLOW) { 58673859Sml29623 statsp->bmac_stats.rx_overflow_err++; 58683859Sml29623 } 58693859Sml29623 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 58703859Sml29623 statsp->bmac_stats.rx_frame_cnt += 58716929Smisaki RXMAC_FRM_CNT_MASK; 58723859Sml29623 } 58733859Sml29623 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 58743859Sml29623 statsp->bmac_stats.rx_crc_err_cnt += 58756929Smisaki BMAC_CRC_ER_CNT_MASK; 58763859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58776929Smisaki NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 58783859Sml29623 } 58793859Sml29623 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 58803859Sml29623 statsp->bmac_stats.rx_len_err_cnt += 58816929Smisaki MAC_LEN_ER_CNT_MASK; 58823859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58836929Smisaki NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 58843859Sml29623 } 58853859Sml29623 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 58863859Sml29623 statsp->bmac_stats.rx_viol_err_cnt += 58876929Smisaki BMAC_CD_VIO_CNT_MASK; 58883859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58896929Smisaki NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 58903859Sml29623 } 58913859Sml29623 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 58923859Sml29623 statsp->bmac_stats.rx_byte_cnt += 58936929Smisaki BRXMAC_BYTE_CNT_MASK; 58943859Sml29623 } 58953859Sml29623 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 58963859Sml29623 statsp->bmac_stats.rx_align_err_cnt += 58976929Smisaki BMAC_AL_ER_CNT_MASK; 58983859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 58996929Smisaki NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 59003859Sml29623 } 59013859Sml29623 59023859Sml29623 rs = npi_bmac_ctl_get_istatus(handle, portn, 59036929Smisaki (bmac_ctl_iconfig_t *)&status); 59043859Sml29623 if (rs != NPI_SUCCESS) 59053859Sml29623 goto npi_fail; 59063859Sml29623 59073859Sml29623 if (status & ICFG_BMAC_CTL_ALL) { 59083859Sml29623 if (status & ICFG_BMAC_CTL_RCVPAUSE) 59093859Sml29623 statsp->bmac_stats.rx_pause_cnt++; 59103859Sml29623 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 59113859Sml29623 statsp->bmac_stats.tx_pause_state++; 59123859Sml29623 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 59133859Sml29623 statsp->bmac_stats.tx_nopause_state++; 59143859Sml29623 } 59153859Sml29623 } 59163859Sml29623 59173859Sml29623 if (ldgp->nldvs == 1) { 59183859Sml29623 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 59196929Smisaki B_TRUE, ldgp->ldg_timer); 59203859Sml29623 } 59213859Sml29623 59223859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 59233859Sml29623 return (DDI_INTR_CLAIMED); 59243859Sml29623 59253859Sml29623 npi_fail: 59263859Sml29623 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 59273859Sml29623 return (DDI_INTR_UNCLAIMED); 59283859Sml29623 } 59293859Sml29623 59303859Sml29623 nxge_status_t 59313859Sml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 59323859Sml29623 { 59333859Sml29623 uint8_t phy_port_addr; 59343859Sml29623 nxge_status_t status = NXGE_OK; 59353859Sml29623 boolean_t rx_sig_ok; 59363859Sml29623 boolean_t pcs_blk_lock; 59373859Sml29623 boolean_t link_align; 59383859Sml29623 uint16_t val1, val2, val3; 59393859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 59403859Sml29623 uint16_t val_debug; 59413859Sml29623 uint16_t val; 59423859Sml29623 #endif 59433859Sml29623 59443859Sml29623 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 59453859Sml29623 59463859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 59473859Sml29623 /* Check Device 3 Register Device 3 0xC809 */ 59483859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 59493859Sml29623 if ((val_debug & ~0x200) != 0) { 59503859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 59516929Smisaki nxgep->mac.portnum, val_debug); 59523859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 59536929Smisaki &val_debug); 59543859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 59556929Smisaki nxgep->mac.portnum, val_debug); 59563859Sml29623 } 59573859Sml29623 59583859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 59596929Smisaki XPCS_REG_DESCWERR_COUNTER, &val); 59603859Sml29623 if (val != 0) 59613859Sml29623 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 59623859Sml29623 59633859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 59646929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 59653859Sml29623 if (val != 0) 59663859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 59673859Sml29623 59683859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 59696929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 59703859Sml29623 if (val != 0) 59713859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 59723859Sml29623 #endif 59733859Sml29623 59743859Sml29623 /* Check from BCM8704 if 10G link is up or down */ 59753859Sml29623 59763859Sml29623 /* Check Device 1 Register 0xA bit0 */ 59776929Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR, 59786929Smisaki BCM8704_PMD_RECEIVE_SIG_DETECT, &val1); 59793859Sml29623 if (status != NXGE_OK) 59803859Sml29623 goto fail; 59813859Sml29623 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 59823859Sml29623 59833859Sml29623 /* Check Device 3 Register 0x20 bit0 */ 59846929Smisaki if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR, 59856929Smisaki BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS) 59863859Sml29623 goto fail; 59873859Sml29623 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 59883859Sml29623 59893859Sml29623 /* Check Device 4 Register 0x18 bit12 */ 59906929Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 59916929Smisaki BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3); 59923859Sml29623 if (status != NXGE_OK) 59933859Sml29623 goto fail; 59945572Ssbehera 59955572Ssbehera switch (nxgep->chip_id) { 59965572Ssbehera case BCM8704_CHIP_ID: 59975572Ssbehera link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | 59985572Ssbehera XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 59995572Ssbehera XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 60005572Ssbehera break; 60015572Ssbehera case BCM8706_CHIP_ID: 60025572Ssbehera link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) && 60035572Ssbehera (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) && 60045572Ssbehera (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ? 60055572Ssbehera B_TRUE : B_FALSE; 60065572Ssbehera break; 60075572Ssbehera default: 60085572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:" 60095572Ssbehera "Unknown chip ID [0x%x]", nxgep->chip_id)); 60105572Ssbehera goto fail; 60115572Ssbehera } 60125572Ssbehera 60133859Sml29623 60143859Sml29623 #ifdef NXGE_DEBUG_ALIGN_ERR 60153859Sml29623 /* Temp workaround for link down issue */ 60163859Sml29623 if (pcs_blk_lock == B_FALSE) { 60173859Sml29623 if (val2 != 0x4) { 60183859Sml29623 pcs_blk_lock = B_TRUE; 60196929Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 " 60206929Smisaki "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2); 60213859Sml29623 } 60223859Sml29623 } 60233859Sml29623 60243859Sml29623 if (link_align == B_FALSE) { 60253859Sml29623 if (val3 != 0x140f) { 60263859Sml29623 link_align = B_TRUE; 60276929Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 " 60286929Smisaki "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3); 60293859Sml29623 } 60303859Sml29623 } 60313859Sml29623 60323859Sml29623 if (rx_sig_ok == B_FALSE) { 60333859Sml29623 if ((val2 == 0) || (val3 == 0)) { 60343859Sml29623 rx_sig_ok = B_TRUE; 60353859Sml29623 cmn_err(CE_NOTE, 60366929Smisaki "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 60376929Smisaki nxgep->mac.portnum); 60383859Sml29623 } 60393859Sml29623 } 60403859Sml29623 #endif 60413859Sml29623 60423859Sml29623 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 60436929Smisaki (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 60443859Sml29623 60453859Sml29623 return (NXGE_OK); 60463859Sml29623 fail: 60473859Sml29623 return (status); 60483859Sml29623 } 60493859Sml29623 60506604Ssbehera static nxge_status_t 60516835Syc148097 nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up) 60526604Ssbehera { 60536604Ssbehera uint8_t phy; 60546604Ssbehera nxge_status_t status = NXGE_OK; 60556604Ssbehera boolean_t pma_status; 60566604Ssbehera boolean_t pcs_status; 60576604Ssbehera boolean_t xgxs_status; 60586604Ssbehera uint16_t val; 60596604Ssbehera 60606604Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn; 60616604Ssbehera 60626604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 60636604Ssbehera MRVL_88X2011_10G_PMD_STAT_2, &val); 60646604Ssbehera 60656604Ssbehera *link_up = B_FALSE; 60666604Ssbehera 60676604Ssbehera /* Check from Marvell 88X2011 if 10G link is up or down */ 60686604Ssbehera 60696604Ssbehera /* Check PMA/PMD Register: 1.0001.2 == 1 */ 60706604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 60716604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 60726604Ssbehera 60736604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60746604Ssbehera "nxge_check_mrvl88x2011_link: pmd=0x%x", val)); 60756604Ssbehera 60766604Ssbehera pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE); 60776604Ssbehera 60786604Ssbehera /* Check PMC Register : 3.0001.2 == 1: read twice */ 60796604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 60806604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 60816604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 60826604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 60836604Ssbehera 60846604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60856604Ssbehera "nxge_check_mrvl88x2011_link: pcs=0x%x", val)); 60866604Ssbehera 60876604Ssbehera pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE); 60886604Ssbehera 60896604Ssbehera /* Check XGXS Register : 4.0018.[0-3,12] */ 60906604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR, 60916604Ssbehera MRVL_88X2011_10G_XGXS_LANE_STAT, &val); 60926604Ssbehera 60936604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 60946604Ssbehera "nxge_check_mrvl88x2011_link: xgxs=0x%x", val)); 60956604Ssbehera 60966604Ssbehera xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 60976604Ssbehera XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 60986604Ssbehera XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY | 60996604Ssbehera XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE; 61006604Ssbehera 61016604Ssbehera *link_up = (pma_status && pcs_status && xgxs_status) ? 61026604Ssbehera B_TRUE : B_FALSE; 61036604Ssbehera 61046604Ssbehera fail: 61056604Ssbehera 61066604Ssbehera if (*link_up == B_FALSE) { 61076604Ssbehera /* PCS OFF */ 61086604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF); 61096604Ssbehera } else { 61106604Ssbehera /* PCS Activity */ 61116604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT); 61126604Ssbehera } 61136604Ssbehera 61146604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61156604Ssbehera " <== nxge_check_mrvl88x2011_link: up=%d", *link_up)); 61166604Ssbehera 61176604Ssbehera return (status); 61186604Ssbehera } 61196604Ssbehera 61203859Sml29623 nxge_status_t 61213859Sml29623 nxge_10g_link_led_on(p_nxge_t nxgep) 61223859Sml29623 { 61233859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 61244732Sdavemq != NPI_SUCCESS) 61253859Sml29623 return (NXGE_ERROR); 61263859Sml29623 else 61273859Sml29623 return (NXGE_OK); 61283859Sml29623 } 61293859Sml29623 61303859Sml29623 nxge_status_t 61313859Sml29623 nxge_10g_link_led_off(p_nxge_t nxgep) 61323859Sml29623 { 61333859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 61344732Sdavemq != NPI_SUCCESS) 61353859Sml29623 return (NXGE_ERROR); 61363859Sml29623 else 61373859Sml29623 return (NXGE_OK); 61383859Sml29623 } 61394185Sspeer 61405572Ssbehera static boolean_t 61415572Ssbehera nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask) 61425572Ssbehera { 61435572Ssbehera uint32_t pma_pmd_id = 0; 61445572Ssbehera uint32_t pcs_id = 0; 61455572Ssbehera uint32_t phy_id = 0; 61465572Ssbehera 61475572Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr); 61485572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61495572Ssbehera "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id)); 61505572Ssbehera if ((pma_pmd_id & mask) == (id & mask)) 61515572Ssbehera goto found_phy; 61525572Ssbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, addr); 61535572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61545572Ssbehera "nxge_is_phy_present: pcs_id[0x%x]", pcs_id)); 61555572Ssbehera if ((pcs_id & mask) == (id & mask)) 61565572Ssbehera goto found_phy; 61575572Ssbehera phy_id = nxge_get_cl22_phy_id(nxgep, addr); 61585572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61595572Ssbehera "nxge_is_phy_present: phy_id[0x%x]", phy_id)); 61605572Ssbehera if ((phy_id & mask) == (id & mask)) 61615572Ssbehera goto found_phy; 61625572Ssbehera 61635572Ssbehera return (B_FALSE); 61645572Ssbehera 61655572Ssbehera found_phy: 61665572Ssbehera return (B_TRUE); 61675572Ssbehera } 61685572Ssbehera 61694732Sdavemq /* Check if the given id read using the given MDIO Clause is supported */ 61704732Sdavemq 61714732Sdavemq static boolean_t 61724732Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type) 61734732Sdavemq { 61744732Sdavemq int i; 61754732Sdavemq boolean_t found = B_FALSE; 61764732Sdavemq 61774732Sdavemq switch (type) { 61784732Sdavemq case CLAUSE_45_TYPE: 61796835Syc148097 for (i = 0; i < NUM_CLAUSE_45_IDS; i++) { 61806835Syc148097 if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) == 61816835Syc148097 (id & BCM_PHY_ID_MASK)) || 61826835Syc148097 (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK))) { 61834732Sdavemq found = B_TRUE; 61844732Sdavemq break; 61854732Sdavemq } 61864732Sdavemq } 61874732Sdavemq break; 61884732Sdavemq case CLAUSE_22_TYPE: 61896835Syc148097 for (i = 0; i < NUM_CLAUSE_22_IDS; i++) { 61904782Ssbehera if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) == 61914782Ssbehera (id & BCM_PHY_ID_MASK)) { 61924732Sdavemq found = B_TRUE; 61934732Sdavemq break; 61944732Sdavemq } 61954732Sdavemq } 61964732Sdavemq break; 61974732Sdavemq default: 61984732Sdavemq break; 61994732Sdavemq } 62004732Sdavemq 62014732Sdavemq return (found); 62024732Sdavemq } 62034732Sdavemq 62044977Sraghus static uint32_t 62054977Sraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port) 62064977Sraghus { 62074977Sraghus uint16_t val1 = 0; 62084977Sraghus uint16_t val2 = 0; 62094977Sraghus uint32_t pma_pmd_dev_id = 0; 62104977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 62114977Sraghus 62125780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 62134977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 62144977Sraghus NXGE_DEV_ID_REG_1, &val1); 62154977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 62164977Sraghus NXGE_DEV_ID_REG_2, &val2); 62175780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 62184977Sraghus 62196835Syc148097 /* Concatenate the Device ID stored in two registers. */ 62204977Sraghus pma_pmd_dev_id = val1; 62214977Sraghus pma_pmd_dev_id = (pma_pmd_dev_id << 16); 62224977Sraghus pma_pmd_dev_id |= val2; 62234977Sraghus 62244977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 62254977Sraghus "devid[0x%llx]", phy_port, pma_pmd_dev_id)); 62264977Sraghus 62274977Sraghus return (pma_pmd_dev_id); 62284977Sraghus } 62294977Sraghus 62304977Sraghus static uint32_t 62314977Sraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port) 62324977Sraghus { 62334977Sraghus uint16_t val1 = 0; 62344977Sraghus uint16_t val2 = 0; 62354977Sraghus uint32_t pcs_dev_id = 0; 62364977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 62374977Sraghus 62385780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 62394977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 62404977Sraghus NXGE_DEV_ID_REG_1, &val1); 62414977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 62424977Sraghus NXGE_DEV_ID_REG_2, &val2); 62435780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 62444977Sraghus 62454977Sraghus pcs_dev_id = val1; 62464977Sraghus pcs_dev_id = (pcs_dev_id << 16); 62474977Sraghus pcs_dev_id |= val2; 62484977Sraghus 62494977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 62504977Sraghus "devid[0x%llx]", phy_port, pcs_dev_id)); 62514977Sraghus 62524977Sraghus return (pcs_dev_id); 62534977Sraghus } 62544977Sraghus 62554977Sraghus static uint32_t 62564977Sraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port) 62574977Sraghus { 62584977Sraghus uint16_t val1 = 0; 62594977Sraghus uint16_t val2 = 0; 62604977Sraghus uint32_t phy_id = 0; 62614977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 62624977Sraghus npi_status_t npi_status = NPI_SUCCESS; 62634977Sraghus 62646075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 62654977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1, 62664977Sraghus &val1); 62674977Sraghus if (npi_status != NPI_SUCCESS) { 62684977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 62694977Sraghus "clause 22 read to reg 2 failed!!!")); 62704977Sraghus goto exit; 62714977Sraghus } 62724977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2, 62734977Sraghus &val2); 62744977Sraghus if (npi_status != 0) { 62754977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 62764977Sraghus "clause 22 read to reg 3 failed!!!")); 62774977Sraghus goto exit; 62784977Sraghus } 62794977Sraghus phy_id = val1; 62804977Sraghus phy_id = (phy_id << 16); 62814977Sraghus phy_id |= val2; 62824977Sraghus 62834977Sraghus exit: 62846075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 62854977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]", 62864977Sraghus phy_port, phy_id)); 62874977Sraghus 62884977Sraghus return (phy_id); 62894977Sraghus } 62904977Sraghus 62914732Sdavemq /* 62924732Sdavemq * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 62934732Sdavemq * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 62944732Sdavemq * read. Then use the values obtained to determine the phy type of each port 62954732Sdavemq * and the Neptune type. 62966835Syc148097 * 62976835Syc148097 * This function sets hw_p->xcvr_addr[i] for future MDIO access and set 62986835Syc148097 * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode 62996835Syc148097 * in case the portmode information is not available via OBP, nxge.conf, 63006835Syc148097 * VPD or SEEPROM. 63014732Sdavemq */ 63024732Sdavemq nxge_status_t 63034732Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 63044732Sdavemq { 63056261Sjoycey int i, j, l; 63064732Sdavemq uint32_t pma_pmd_dev_id = 0; 63074732Sdavemq uint32_t pcs_dev_id = 0; 63084732Sdavemq uint32_t phy_id = 0; 63094782Ssbehera uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE]; 63104782Ssbehera uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE]; 63114782Ssbehera uint32_t port_phy_id[NXGE_PORTS_NEPTUNE]; 63124732Sdavemq uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 63134732Sdavemq uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 63145572Ssbehera uint8_t phy_fd_arr[NXGE_MAX_PHY_PORTS]; 63155572Ssbehera uint8_t port_fd_arr[NXGE_MAX_PHY_PORTS]; 63164732Sdavemq uint8_t total_port_fd, total_phy_fd; 63176835Syc148097 uint8_t num_xaui; 63184732Sdavemq nxge_status_t status = NXGE_OK; 63194732Sdavemq 63204732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 63214732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 63224732Sdavemq "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 63234732Sdavemq nxgep->niu_type)); 63244732Sdavemq 63256495Sspeer if (isLDOMguest(nxgep)) { 63266495Sspeer hw_p->niu_type = NIU_TYPE_NONE; 63276495Sspeer hw_p->platform_type = P_NEPTUNE_NONE; 63286495Sspeer return (NXGE_OK); 63296495Sspeer } 63306495Sspeer 63316261Sjoycey j = l = 0; 63324732Sdavemq total_port_fd = total_phy_fd = 0; 63334732Sdavemq /* 63347801SSantwona.Behera@Sun.COM * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved 63357801SSantwona.Behera@Sun.COM * for on chip serdes usages. "i" in the following for loop starts at 6. 63364732Sdavemq */ 63374732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 63384977Sraghus 63394977Sraghus pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i); 63404732Sdavemq 63414732Sdavemq if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 63424732Sdavemq pma_pmd_dev_fd[i] = 1; 63434732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 63446604Ssbehera "PMA/PMD dev %x found", i, pma_pmd_dev_id)); 63454782Ssbehera if (j < NXGE_PORTS_NEPTUNE) { 63466835Syc148097 if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK) 63476835Syc148097 == TN1010_DEV_ID) { 63486835Syc148097 port_pma_pmd_dev_id[j] = TN1010_DEV_ID; 63496835Syc148097 } else { 63506835Syc148097 port_pma_pmd_dev_id[j] = 63516929Smisaki pma_pmd_dev_id & BCM_PHY_ID_MASK; 63526835Syc148097 } 63535572Ssbehera port_fd_arr[j] = (uint8_t)i; 63544732Sdavemq j++; 63554732Sdavemq } 63564732Sdavemq } else { 63574732Sdavemq pma_pmd_dev_fd[i] = 0; 63584732Sdavemq } 63594732Sdavemq 63604977Sraghus pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i); 63614732Sdavemq 63624732Sdavemq if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 63634732Sdavemq pcs_dev_fd[i] = 1; 63644732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 63656604Ssbehera "dev %x found", i, pcs_dev_id)); 63666261Sjoycey if (pma_pmd_dev_fd[i] == 1) { 63676835Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK) 63686835Syc148097 == TN1010_DEV_ID) { 63696835Syc148097 port_pcs_dev_id[j - 1] = 63706835Syc148097 TN1010_DEV_ID; 63716835Syc148097 } else { 63726835Syc148097 port_pcs_dev_id[j - 1] = 63736835Syc148097 pcs_dev_id & 63746835Syc148097 BCM_PHY_ID_MASK; 63756835Syc148097 } 63766261Sjoycey } else { 63776261Sjoycey if (j < NXGE_PORTS_NEPTUNE) { 63786835Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK) 63796929Smisaki == TN1010_DEV_ID) { 63806835Syc148097 port_pcs_dev_id[j] = 63816835Syc148097 TN1010_DEV_ID; 63826835Syc148097 } else { 63836835Syc148097 port_pcs_dev_id[j] = 63846835Syc148097 pcs_dev_id & 63856835Syc148097 BCM_PHY_ID_MASK; 63866835Syc148097 } 63876261Sjoycey port_fd_arr[j] = (uint8_t)i; 63886261Sjoycey j++; 63896261Sjoycey } 63904732Sdavemq } 63914732Sdavemq } else { 63924732Sdavemq pcs_dev_fd[i] = 0; 63934732Sdavemq } 63944732Sdavemq 63955572Ssbehera if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) { 63965572Ssbehera total_port_fd ++; 63975572Ssbehera } 63984732Sdavemq 63994977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, i); 64004732Sdavemq if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 64015572Ssbehera total_phy_fd ++; 64024732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 64036604Ssbehera "%x found", i, phy_id)); 64044782Ssbehera if (l < NXGE_PORTS_NEPTUNE) { 64056835Syc148097 if ((phy_id & TN1010_DEV_ID_MASK) 64066835Syc148097 == TN1010_DEV_ID) { 64076835Syc148097 port_phy_id[l] = TN1010_DEV_ID; 64086835Syc148097 } else { 64096835Syc148097 port_phy_id[l] 64106835Syc148097 = phy_id & BCM_PHY_ID_MASK; 64116835Syc148097 } 64125572Ssbehera phy_fd_arr[l] = (uint8_t)i; 64134732Sdavemq l++; 64144732Sdavemq } 64154732Sdavemq } 64164732Sdavemq } 64174732Sdavemq 64184732Sdavemq switch (total_port_fd) { 64194732Sdavemq case 2: 64204732Sdavemq switch (total_phy_fd) { 64214732Sdavemq case 2: 64227801SSantwona.Behera@Sun.COM /* 2 10G, 2 1G RGMII Fiber / copper */ 64236261Sjoycey if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 64246261Sjoycey (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 64256261Sjoycey ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 64266261Sjoycey (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) && 64276261Sjoycey ((port_phy_id[0] == PHY_BCM5482_FAMILY) && 64286261Sjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY))) { 64296261Sjoycey 64307801SSantwona.Behera@Sun.COM switch (hw_p->platform_type) { 64317801SSantwona.Behera@Sun.COM case P_NEPTUNE_ROCK: 64327801SSantwona.Behera@Sun.COM hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 64337801SSantwona.Behera@Sun.COM /* 64347801SSantwona.Behera@Sun.COM * ROCK platform has assigned a lower 64357801SSantwona.Behera@Sun.COM * addr to port 1. (port 0 = 0x9 and 64367801SSantwona.Behera@Sun.COM * port 1 = 0x8). 64377801SSantwona.Behera@Sun.COM */ 64387801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[0]; 64397801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[1]; 64407801SSantwona.Behera@Sun.COM 64417801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, 64427801SSantwona.Behera@Sun.COM "Rock with 2 10G, 2 1GC")); 64437801SSantwona.Behera@Sun.COM break; 64447801SSantwona.Behera@Sun.COM 64457801SSantwona.Behera@Sun.COM case P_NEPTUNE_NONE: 64467801SSantwona.Behera@Sun.COM default: 64477801SSantwona.Behera@Sun.COM hw_p->platform_type = 64487801SSantwona.Behera@Sun.COM P_NEPTUNE_GENERIC; 64497801SSantwona.Behera@Sun.COM hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF; 64507801SSantwona.Behera@Sun.COM 64517801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[0]; 64527801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[1]; 64537801SSantwona.Behera@Sun.COM 64547801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, 64557801SSantwona.Behera@Sun.COM "ARTM card with 2 10G, 2 1GF")); 64567801SSantwona.Behera@Sun.COM break; 64577801SSantwona.Behera@Sun.COM } 64587801SSantwona.Behera@Sun.COM 64596261Sjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0]; 64606261Sjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1]; 64616261Sjoycey 64626261Sjoycey } else { 64636261Sjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 64646261Sjoycey "Unsupported neptune type 1")); 64656261Sjoycey goto error_exit; 64666261Sjoycey } 64676261Sjoycey break; 64686261Sjoycey 64694732Sdavemq case 1: 64704732Sdavemq /* TODO - 2 10G, 1 1G */ 64714732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 64724732Sdavemq "Unsupported neptune type 2 10G, 1 1G")); 64734732Sdavemq goto error_exit; 64744732Sdavemq case 0: 64756835Syc148097 /* 64766835Syc148097 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI 64776835Syc148097 * cards, etc. 64786835Syc148097 */ 64794782Ssbehera if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 64804782Ssbehera (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 64814782Ssbehera ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 64826604Ssbehera (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) || 64836604Ssbehera ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) && 64846604Ssbehera (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) || 64856604Ssbehera ((port_pma_pmd_dev_id[0] == 64866604Ssbehera MARVELL_88X201X_PHY_ID) && 64876604Ssbehera (port_pma_pmd_dev_id[1] == 64886604Ssbehera MARVELL_88X201X_PHY_ID))) { 64894977Sraghus 64904977Sraghus /* 64914977Sraghus * Check the first phy port address against 64924977Sraghus * the known phy start addresses to determine 64934977Sraghus * the platform type. 64944977Sraghus */ 64955572Ssbehera 64965572Ssbehera switch (port_fd_arr[0]) { 64976835Syc148097 case NEPTUNE_CLAUSE45_PORT_ADDR_BASE: 64986604Ssbehera /* 64996604Ssbehera * The Marvell case also falls into 65006604Ssbehera * this case as 65016604Ssbehera * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE 65026835Syc148097 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE. 65036604Ssbehera * This is OK for the 2 10G case. 65046604Ssbehera */ 65054977Sraghus hw_p->niu_type = NEPTUNE_2_10GF; 65064977Sraghus hw_p->platform_type = 65074977Sraghus P_NEPTUNE_ATLAS_2PORT; 65085572Ssbehera break; 65096835Syc148097 case GOA_CLAUSE45_PORT_ADDR_BASE: 65105572Ssbehera if (hw_p->platform_type != 65115572Ssbehera P_NEPTUNE_NIU) { 65125572Ssbehera hw_p->platform_type = 65135572Ssbehera P_NEPTUNE_GENERIC; 65145572Ssbehera hw_p->niu_type = 65155572Ssbehera NEPTUNE_2_10GF; 65165572Ssbehera } 65175572Ssbehera break; 65185572Ssbehera default: 65195572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 65204977Sraghus "Unsupported neptune type 2 - 1")); 65214977Sraghus goto error_exit; 65224977Sraghus } 65235572Ssbehera 65245572Ssbehera for (i = 0; i < 2; i++) { 65255572Ssbehera hw_p->xcvr_addr[i] = port_fd_arr[i]; 65265572Ssbehera } 65276835Syc148097 65286835Syc148097 /* Both XAUI slots have copper XAUI cards */ 65296835Syc148097 } else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 65306835Syc148097 == TN1010_DEV_ID) && 65316835Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 65326835Syc148097 == TN1010_DEV_ID)) || 65336835Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 65346835Syc148097 == TN1010_DEV_ID) && 65356835Syc148097 ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) 65366835Syc148097 == TN1010_DEV_ID))) { 65376835Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010; 65386835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 65396835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 65406835Syc148097 65416835Syc148097 /* Slot0 has fiber XAUI, slot1 has copper XAUI */ 65426835Syc148097 } else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 65436835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 65446835Syc148097 == TN1010_DEV_ID) || 65456835Syc148097 (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY && 65466835Syc148097 (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) == 65476835Syc148097 TN1010_DEV_ID)) { 65486835Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010; 65496835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 65506835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 65516835Syc148097 65526835Syc148097 /* Slot0 has copper XAUI, slot1 has fiber XAUI */ 65536835Syc148097 } else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY && 65546835Syc148097 (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 65556835Syc148097 == TN1010_DEV_ID) || 65566835Syc148097 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY && 65576835Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 65586835Syc148097 == TN1010_DEV_ID)) { 65596835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF; 65606835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 65616835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 65626835Syc148097 65634732Sdavemq } else { 65644732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 65654732Sdavemq "Unsupported neptune type 2")); 65664732Sdavemq goto error_exit; 65674732Sdavemq } 65684732Sdavemq break; 65696835Syc148097 65704732Sdavemq case 4: 65716835Syc148097 if (nxge_get_num_of_xaui( 65726835Syc148097 port_pma_pmd_dev_id, port_pcs_dev_id, 65736835Syc148097 port_phy_id, &num_xaui) == NXGE_ERROR) { 65746835Syc148097 goto error_exit; 65756835Syc148097 } 65766835Syc148097 if (num_xaui != 2) 65776835Syc148097 goto error_exit; 65786835Syc148097 65796835Syc148097 /* 65806835Syc148097 * Maramba with 2 XAUIs (either fiber or copper) 65816835Syc148097 * 65826835Syc148097 * Check the first phy port address against 65836835Syc148097 * the known phy start addresses to determine 65846835Syc148097 * the platform type. 65856835Syc148097 */ 65866835Syc148097 switch (phy_fd_arr[0]) { 65876835Syc148097 case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE: 65886835Syc148097 hw_p->platform_type = 65896835Syc148097 P_NEPTUNE_MARAMBA_P0; 65906835Syc148097 break; 65916835Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 65926835Syc148097 hw_p->platform_type = 65936835Syc148097 P_NEPTUNE_MARAMBA_P1; 65946835Syc148097 break; 65956835Syc148097 default: 65966835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 65976835Syc148097 "Unknown port %d...Cannot " 65986835Syc148097 "determine platform type", i)); 65996835Syc148097 goto error_exit; 66006835Syc148097 } 66016835Syc148097 66026835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 66036835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 66046835Syc148097 hw_p->xcvr_addr[2] = phy_fd_arr[2]; 66056835Syc148097 hw_p->xcvr_addr[3] = phy_fd_arr[3]; 66066835Syc148097 66076835Syc148097 /* slot0 has fiber XAUI, slot1 has Cu XAUI */ 66086835Syc148097 if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 66096835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 66106835Syc148097 == TN1010_DEV_ID) { 66116835Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC; 66126835Syc148097 66136835Syc148097 /* slot0 has Cu XAUI, slot1 has fiber XAUI */ 66146835Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 66156835Syc148097 == TN1010_DEV_ID) && 66166835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) { 66176835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC; 66186835Syc148097 66196835Syc148097 /* Both slots have fiber XAUI */ 66206835Syc148097 } else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 66216835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) { 66224977Sraghus hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 66234977Sraghus 66246835Syc148097 /* Both slots have copper XAUI */ 66256835Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 66266835Syc148097 == TN1010_DEV_ID) && 66276835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 66286835Syc148097 == TN1010_DEV_ID) { 66296835Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC; 66306835Syc148097 66314732Sdavemq } else { 66324732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66334732Sdavemq "Unsupported neptune type 3")); 66344732Sdavemq goto error_exit; 66354732Sdavemq } 66364732Sdavemq break; 66374732Sdavemq default: 66384732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66394732Sdavemq "Unsupported neptune type 5")); 66404732Sdavemq goto error_exit; 66414732Sdavemq } 66424782Ssbehera break; 66436835Syc148097 case 1: /* Only one clause45 port */ 66446835Syc148097 switch (total_phy_fd) { /* Number of clause22 ports */ 66454732Sdavemq case 3: 66464977Sraghus /* 66474977Sraghus * TODO 3 1G, 1 10G mode. 66484977Sraghus * Differentiate between 1_1G_1_10G_2_1G and 66494977Sraghus * 1_10G_3_1G 66504977Sraghus */ 66514977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66524977Sraghus "Unsupported neptune type 7")); 66534977Sraghus goto error_exit; 66544732Sdavemq case 2: 66554732Sdavemq /* 66564732Sdavemq * TODO 2 1G, 1 10G mode. 66574732Sdavemq * Differentiate between 1_1G_1_10G_1_1G and 66584732Sdavemq * 1_10G_2_1G 66594732Sdavemq */ 66604732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66614732Sdavemq "Unsupported neptune type 8")); 66624732Sdavemq goto error_exit; 66634732Sdavemq case 1: 66644732Sdavemq /* 66654732Sdavemq * TODO 1 1G, 1 10G mode. 66664732Sdavemq * Differentiate between 1_1G_1_10G and 66674732Sdavemq * 1_10G_1_1G 66684732Sdavemq */ 66694732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66704732Sdavemq "Unsupported neptune type 9")); 66714732Sdavemq goto error_exit; 66726835Syc148097 case 0: /* N2 with 1 XAUI (fiber or copper) */ 66736835Syc148097 /* Fiber XAUI */ 66745572Ssbehera if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY || 66755572Ssbehera port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) { 66765572Ssbehera 66775572Ssbehera /* 66785572Ssbehera * Check the first phy port address against 66795572Ssbehera * the known phy start addresses to determine 66805572Ssbehera * the platform type. 66815572Ssbehera */ 66825572Ssbehera 66835572Ssbehera switch (port_fd_arr[0]) { 66846835Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE: 66856835Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1): 66866835Syc148097 case ALT_GOA_CLAUSE45_PORT1_ADDR: 66876835Syc148097 /* 66886835Syc148097 * If hw_p->platform_type == 66896835Syc148097 * P_NEPTUNE_NIU, then portmode 66906835Syc148097 * is already known, so there is 66916835Syc148097 * no need to figure out hw_p-> 66926835Syc148097 * platform_type because 66936835Syc148097 * platform_type is only for 66946835Syc148097 * figuring out portmode. 66956835Syc148097 */ 66965572Ssbehera if (hw_p->platform_type != 66975572Ssbehera P_NEPTUNE_NIU) { 66985572Ssbehera hw_p->platform_type = 66995572Ssbehera P_NEPTUNE_GENERIC; 67005572Ssbehera hw_p->niu_type = 67015572Ssbehera NEPTUNE_2_10GF; 67025572Ssbehera } 67035572Ssbehera break; 67045572Ssbehera default: 67055572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 67065572Ssbehera "Unsupported neptune type 10")); 67075572Ssbehera goto error_exit; 67085572Ssbehera } 67096075Ssbehera /* 67106075Ssbehera * For GOA, which is a hot swappable PHY, the 67116075Ssbehera * phy address to function number mapping 67126075Ssbehera * should be preserved, i.e., addr 16 is 67136075Ssbehera * assigned to function 0 and 20 to function 1 67146075Ssbehera * But for Huron XAUI, the assignment should 67156075Ssbehera * be by function number, i.e., whichever 67166075Ssbehera * function number attaches should be 67176075Ssbehera * assigned the available PHY (this is required 67186075Ssbehera * primarily to support pre-production Huron 67196075Ssbehera * boards where function 0 is mapped to addr 17 67206075Ssbehera */ 67216075Ssbehera if (port_fd_arr[0] == 67226835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR) { 67236075Ssbehera hw_p->xcvr_addr[1] = port_fd_arr[0]; 67246075Ssbehera } else { 67256075Ssbehera hw_p->xcvr_addr[nxgep->function_num] = 67266075Ssbehera port_fd_arr[0]; 67276075Ssbehera } 67286835Syc148097 67296835Syc148097 /* A 10G copper XAUI in either slot0 or slot1 */ 67306835Syc148097 } else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 67316835Syc148097 == TN1010_DEV_ID || 67326835Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 67336835Syc148097 == TN1010_DEV_ID) { 67346835Syc148097 switch (port_fd_arr[0]) { 67356835Syc148097 /* The XAUI is in slot0 */ 67366835Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE: 67376835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010; 67386835Syc148097 break; 67396835Syc148097 67406835Syc148097 /* The XAUI is in slot1 */ 67416835Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1): 67426835Syc148097 hw_p->niu_type 67436835Syc148097 = NEPTUNE_1_NONE_1_TN1010; 67446835Syc148097 break; 67456835Syc148097 default: 67466835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 67476835Syc148097 "Unsupported XAUI port address")); 67486835Syc148097 goto error_exit; 67496835Syc148097 } 67506835Syc148097 hw_p->xcvr_addr[nxgep->function_num] 67516835Syc148097 = port_fd_arr[0]; 67526835Syc148097 67535572Ssbehera } else { 67545572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67556835Syc148097 "Unsupported PHY type")); 67565572Ssbehera goto error_exit; 67575572Ssbehera } 67585572Ssbehera break; 67596835Syc148097 case 4: /* Maramba always have 4 clause 45 ports */ 67606835Syc148097 67614732Sdavemq /* Maramba with 1 XAUI */ 67626929Smisaki if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) && 67636929Smisaki (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) && 67646835Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 67656929Smisaki != TN1010_DEV_ID) && 67666835Syc148097 ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 67676929Smisaki != TN1010_DEV_ID)) { 67684732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67694732Sdavemq "Unsupported neptune type 12")); 67704732Sdavemq goto error_exit; 67714732Sdavemq } 67726929Smisaki 67736929Smisaki /* 67746929Smisaki * Check the first phy port address against 67756929Smisaki * the known phy start addresses to determine 67766929Smisaki * the platform type. 67776929Smisaki */ 67786929Smisaki switch (phy_fd_arr[0]) { 67796929Smisaki case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE: 67806929Smisaki hw_p->platform_type = 67816929Smisaki P_NEPTUNE_MARAMBA_P0; 67826929Smisaki break; 67836929Smisaki case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 67846929Smisaki hw_p->platform_type = 67856929Smisaki P_NEPTUNE_MARAMBA_P1; 67866929Smisaki break; 67876929Smisaki default: 67886929Smisaki NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 67896929Smisaki "Unknown port %d...Cannot " 67906929Smisaki "determine platform type 10 - 2", 67916929Smisaki i)); 67926929Smisaki goto error_exit; 67936929Smisaki } 67946929Smisaki 67956929Smisaki /* 67966929Smisaki * Check the clause45 address to determine 67976929Smisaki * if XAUI is in port 0 or port 1. 67986929Smisaki */ 67996929Smisaki switch (port_fd_arr[0]) { 68006929Smisaki case MARAMBA_CLAUSE45_PORT_ADDR_BASE: 68016929Smisaki if (port_pcs_dev_id[0] 68026929Smisaki == PHY_BCM8704_FAMILY || 68036929Smisaki port_pma_pmd_dev_id[0] 68046929Smisaki == PHY_BCM8704_FAMILY) { 68056929Smisaki hw_p->niu_type 68066929Smisaki = NEPTUNE_1_10GF_3_1GC; 68076929Smisaki } else { 68086929Smisaki hw_p->niu_type 68096929Smisaki = NEPTUNE_1_TN1010_3_1GC; 68106929Smisaki } 68116929Smisaki hw_p->xcvr_addr[0] = port_fd_arr[0]; 68126929Smisaki for (i = 1; i < NXGE_MAX_PORTS; i++) { 68136929Smisaki hw_p->xcvr_addr[i] = 68146929Smisaki phy_fd_arr[i]; 68156929Smisaki } 68166929Smisaki break; 68176929Smisaki case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1): 68186929Smisaki if (port_pcs_dev_id[0] 68196929Smisaki == PHY_BCM8704_FAMILY || 68206929Smisaki port_pma_pmd_dev_id[0] 68216929Smisaki == PHY_BCM8704_FAMILY) { 68226929Smisaki hw_p->niu_type = 68236929Smisaki NEPTUNE_1_1GC_1_10GF_2_1GC; 68246929Smisaki } else { 68256929Smisaki hw_p->niu_type = 68266929Smisaki NEPTUNE_1_1GC_1_TN1010_2_1GC; 68276929Smisaki } 68286929Smisaki hw_p->xcvr_addr[0] = phy_fd_arr[0]; 68296929Smisaki hw_p->xcvr_addr[1] = port_fd_arr[0]; 68306929Smisaki hw_p->xcvr_addr[2] = phy_fd_arr[2]; 68316929Smisaki hw_p->xcvr_addr[3] = phy_fd_arr[3]; 68326929Smisaki break; 68336929Smisaki default: 68346929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68356929Smisaki "Unsupported neptune type 11")); 68366929Smisaki goto error_exit; 68376929Smisaki } 68386929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68396929Smisaki "Maramba with 1 XAUI (fiber or copper)")); 68404732Sdavemq break; 68414732Sdavemq default: 68424732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68434732Sdavemq "Unsupported neptune type 13")); 68444732Sdavemq goto error_exit; 68454732Sdavemq } 68464732Sdavemq break; 68476835Syc148097 case 0: /* 4 ports Neptune based NIC */ 68484732Sdavemq switch (total_phy_fd) { 68494732Sdavemq case 4: 68504782Ssbehera if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 68514782Ssbehera (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 68524782Ssbehera (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 68534782Ssbehera (port_phy_id[3] == PHY_BCM5464R_FAMILY)) { 68544732Sdavemq 68554732Sdavemq /* 68564732Sdavemq * Check the first phy port address against 68574732Sdavemq * the known phy start addresses to determine 68584732Sdavemq * the platform type. 68594732Sdavemq */ 68605572Ssbehera switch (phy_fd_arr[0]) { 68616835Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 68624732Sdavemq hw_p->platform_type = 68634732Sdavemq P_NEPTUNE_MARAMBA_P1; 68645572Ssbehera break; 68656835Syc148097 case NEPTUNE_CLAUSE22_PORT_ADDR_BASE: 68664977Sraghus hw_p->platform_type = 68674977Sraghus P_NEPTUNE_ATLAS_4PORT; 68685572Ssbehera break; 68695572Ssbehera default: 68704977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 68714977Sraghus "Unknown port %d...Cannot " 68724977Sraghus "determine platform type", i)); 68734977Sraghus goto error_exit; 68744732Sdavemq } 68754977Sraghus hw_p->niu_type = NEPTUNE_4_1GC; 68765572Ssbehera for (i = 0; i < NXGE_MAX_PORTS; i++) { 68775572Ssbehera hw_p->xcvr_addr[i] = phy_fd_arr[i]; 68785572Ssbehera } 68794732Sdavemq } else { 68804732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68814732Sdavemq "Unsupported neptune type 14")); 68824732Sdavemq goto error_exit; 68834732Sdavemq } 68844732Sdavemq break; 68854732Sdavemq case 3: 68864732Sdavemq /* TODO 3 1G mode */ 68874732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 68884732Sdavemq "Unsupported neptune type 15")); 68894732Sdavemq goto error_exit; 68904732Sdavemq case 2: 68914732Sdavemq /* TODO 2 1G mode */ 68926261Sjoycey if ((port_phy_id[0] == PHY_BCM5482_FAMILY) && 68936261Sjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY)) { 68946261Sjoycey hw_p->platform_type = P_NEPTUNE_GENERIC; 68956261Sjoycey hw_p->niu_type = NEPTUNE_2_1GRF; 68966261Sjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0]; 68976261Sjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1]; 68986261Sjoycey } else { 68996261Sjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 69006261Sjoycey "Unsupported neptune type 16")); 69016261Sjoycey goto error_exit; 69026261Sjoycey } 69034732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 69046261Sjoycey "2 RGMII Fiber ports - RTM")); 69056261Sjoycey break; 69066261Sjoycey 69074732Sdavemq case 1: 69084732Sdavemq /* TODO 1 1G mode */ 69094732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 69104732Sdavemq "Unsupported neptune type 17")); 69114732Sdavemq goto error_exit; 69124732Sdavemq default: 69134732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 69144732Sdavemq "Unsupported neptune type 18, total phy fd %d", 69154732Sdavemq total_phy_fd)); 69164732Sdavemq goto error_exit; 69174732Sdavemq } 69184732Sdavemq break; 69194732Sdavemq default: 69204732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 69214732Sdavemq "Unsupported neptune type 19")); 69224732Sdavemq goto error_exit; 69234732Sdavemq } 69244732Sdavemq 69254732Sdavemq scan_exit: 69264732Sdavemq 69274732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 69284732Sdavemq "niu type [0x%x]\n", hw_p->niu_type)); 69294732Sdavemq return (status); 69304732Sdavemq 69314732Sdavemq error_exit: 69324732Sdavemq return (NXGE_ERROR); 69334732Sdavemq } 69344732Sdavemq 69354185Sspeer boolean_t 69364185Sspeer nxge_is_valid_local_mac(ether_addr_st mac_addr) 69374185Sspeer { 69384185Sspeer if ((mac_addr.ether_addr_octet[0] & 0x01) || 69394185Sspeer (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 69404185Sspeer (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 69414185Sspeer return (B_FALSE); 69424185Sspeer else 69434185Sspeer return (B_TRUE); 69444185Sspeer } 69454732Sdavemq 69464732Sdavemq static void 69474732Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 69484732Sdavemq 69494732Sdavemq npi_status_t rs = NPI_SUCCESS; 69504732Sdavemq uint8_t xcvr_portn; 69514732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 69524732Sdavemq 69534732Sdavemq NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 69544732Sdavemq 69554732Sdavemq if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 69566835Syc148097 xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE; 69574732Sdavemq } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 69586835Syc148097 xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE; 69594732Sdavemq } 69604732Sdavemq /* 69614732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 69624732Sdavemq * swapped with ethernet port number. This is 69634732Sdavemq * designed for better signal integrity in routing. 69644732Sdavemq */ 69654732Sdavemq switch (portn) { 69664732Sdavemq case 0: 69674732Sdavemq xcvr_portn += 3; 69684732Sdavemq break; 69694732Sdavemq case 1: 69704732Sdavemq xcvr_portn += 2; 69714732Sdavemq break; 69724732Sdavemq case 2: 69734732Sdavemq xcvr_portn += 1; 69744732Sdavemq break; 69754732Sdavemq case 3: 69764732Sdavemq default: 69774732Sdavemq break; 69784732Sdavemq } 69794732Sdavemq 69806075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 69814732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 69824732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb4ee); 69834732Sdavemq if (rs != NPI_SUCCESS) { 69844732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 69854732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 69864732Sdavemq "returned error 0x[%x]", rs)); 69876075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 69884732Sdavemq return; 69894732Sdavemq } 69904732Sdavemq 69914732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 69924732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb8ee); 69934732Sdavemq if (rs != NPI_SUCCESS) { 69944732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 69954732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 69964732Sdavemq "returned error 0x[%x]", rs)); 69974732Sdavemq } 69984732Sdavemq 69996075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 70004732Sdavemq } 70015196Ssbehera 70025196Ssbehera static nxge_status_t 70035196Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep) 70045196Ssbehera { 70055196Ssbehera p_nxge_stats_t statsp; 70065196Ssbehera uint8_t xcvr_portn; 70075196Ssbehera p_mii_regs_t mii_regs; 70085196Ssbehera mii_mode_control_stat_t mode; 70095196Ssbehera int status = NXGE_OK; 70105196Ssbehera 70115196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode")); 70125196Ssbehera 70135196Ssbehera statsp = nxgep->statsp; 70145196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 70155196Ssbehera mii_regs = NULL; 70165196Ssbehera mode.value = 0; 70175203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 70185196Ssbehera #if defined(__i386) 70195196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 70205196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 70215196Ssbehera mode.value)) != NXGE_OK) { 70225196Ssbehera goto fail; 70235196Ssbehera #else 70245196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 70255196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 70265196Ssbehera mode.value)) != NXGE_OK) { 70275196Ssbehera goto fail; 70285196Ssbehera #endif 70295196Ssbehera } 70305196Ssbehera #if defined(__i386) 70315196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 70325196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 70335196Ssbehera &mode.value)) != NXGE_OK) { 70345196Ssbehera goto fail; 70355196Ssbehera } 70365196Ssbehera #else 70375196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 70385196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 70395196Ssbehera &mode.value)) != NXGE_OK) { 70405196Ssbehera goto fail; 70415196Ssbehera } 70425196Ssbehera #endif 70435196Ssbehera 70445196Ssbehera if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) { 70455196Ssbehera nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 70465196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70475196Ssbehera "nxge_mii_get_link_mode: fiber mode")); 70485196Ssbehera } 70495196Ssbehera 70505196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70515196Ssbehera "nxge_mii_get_link_mode: " 70525196Ssbehera "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x", 70535203Ssbehera NXGE_MII_MODE_CONTROL_REG, xcvr_portn, 70545196Ssbehera mode.value, nxgep->mac.portmode)); 70555196Ssbehera 70565196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70575196Ssbehera "<== nxge_mii_get_link_mode")); 70585196Ssbehera return (status); 70595196Ssbehera fail: 70605196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 70615196Ssbehera "<== nxge_mii_get_link_mode (failed)")); 70625196Ssbehera return (NXGE_ERROR); 70635196Ssbehera } 70645196Ssbehera 70656439Sml29623 nxge_status_t 70666439Sml29623 nxge_mac_set_framesize(p_nxge_t nxgep) 70676439Sml29623 { 70686439Sml29623 npi_attr_t ap; 70696439Sml29623 uint8_t portn; 70706439Sml29623 npi_handle_t handle; 70716439Sml29623 npi_status_t rs = NPI_SUCCESS; 70726439Sml29623 70736439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize")); 70746439Sml29623 70756439Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 70766439Sml29623 handle = nxgep->npi_handle; 70776439Sml29623 70786439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70796439Sml29623 "==> nxge_mac_sec_framesize: port<%d> " 70806439Sml29623 "min framesize %d max framesize %d ", 70816439Sml29623 portn, 70826439Sml29623 nxgep->mac.minframesize, 70836439Sml29623 nxgep->mac.maxframesize)); 70846439Sml29623 70856439Sml29623 SET_MAC_ATTR2(handle, ap, portn, 70866439Sml29623 MAC_PORT_FRAME_SIZE, 70876439Sml29623 nxgep->mac.minframesize, 70886439Sml29623 nxgep->mac.maxframesize, 70896439Sml29623 rs); 70906439Sml29623 if (rs != NPI_SUCCESS) { 70916439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70926439Sml29623 "<== nxge_mac_set_framesize: failed to configure " 70936439Sml29623 "max/min frame size port %d", portn)); 70946439Sml29623 70956439Sml29623 return (NXGE_ERROR | rs); 70966439Sml29623 } 70976439Sml29623 70986439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 70996439Sml29623 "<== nxge_mac_set_framesize: port<%d>", portn)); 71006439Sml29623 71016439Sml29623 return (NXGE_OK); 71026439Sml29623 } 71036439Sml29623 71046835Syc148097 static nxge_status_t 71056835Syc148097 nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id, 71066835Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui) 71076835Syc148097 { 71086835Syc148097 uint8_t i; 71096835Syc148097 71106835Syc148097 for (i = 0; i < 4; i++) { 71116835Syc148097 if (port_phy_id[i] != PHY_BCM5464R_FAMILY) 71126835Syc148097 return (NXGE_ERROR); 71136835Syc148097 } 71146835Syc148097 71156835Syc148097 *num_xaui = 0; 71166835Syc148097 if ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY && 71176835Syc148097 port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) || 71186835Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 71196835Syc148097 == TN1010_DEV_ID) && 71206835Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 71216835Syc148097 == TN1010_DEV_ID))) { 71226835Syc148097 (*num_xaui) ++; 71236835Syc148097 } 71246835Syc148097 if ((port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY && 71256835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) || 71266835Syc148097 (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) 71276835Syc148097 == TN1010_DEV_ID) && 71286835Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 71296835Syc148097 == TN1010_DEV_ID))) { 71306835Syc148097 (*num_xaui) ++; 71316835Syc148097 } 71326835Syc148097 return (NXGE_OK); 71336835Syc148097 } 71346835Syc148097 71356835Syc148097 /* 71366835Syc148097 * Instruction from Teranetics: Once you detect link is up, go 71376835Syc148097 * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You 71386835Syc148097 * may want to qualify it by first checking Register 30.1.7:6 and 71396835Syc148097 * making sure it reads "01" (Auto-Neg Complete). 71406835Syc148097 * 71416835Syc148097 * If this function is called when the link is down or before auto- 71426835Syc148097 * negotiation has completed, then the speed of the PHY is not certain. 71436835Syc148097 * In such cases, this function returns 1G as the default speed with 71446835Syc148097 * NXGE_OK status instead of NXGE_ERROR. It is OK to initialize the 71456835Syc148097 * driver based on a default speed because this function will be called 71466835Syc148097 * again when the link comes up. Returning NXGE_ERROR, which may 71476835Syc148097 * cause brutal chain reaction in caller functions, is not necessary. 71486835Syc148097 */ 71496835Syc148097 static nxge_status_t 71506835Syc148097 nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed) 71516835Syc148097 { 71526835Syc148097 uint8_t phy_port_addr, autoneg_stat, link_up; 71536835Syc148097 nxge_status_t status = NXGE_OK; 71546835Syc148097 uint16_t val; 71556835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 71566835Syc148097 71576835Syc148097 /* Set default speed to 10G */ 71586835Syc148097 *speed = TN1010_SPEED_10G; 71596835Syc148097 71606835Syc148097 /* Set Clause 45 */ 71616835Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 71626835Syc148097 71636835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 71646835Syc148097 71656835Syc148097 /* Check Device 1 Register 0xA bit0 for link up status */ 71666835Syc148097 status = nxge_mdio_read(nxgep, phy_port_addr, 71676835Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val); 71686835Syc148097 if (status != NXGE_OK) 71696835Syc148097 goto fail; 71706835Syc148097 71716835Syc148097 link_up = ((val & TN1010_AN_LINK_STAT_BIT) 71726835Syc148097 ? B_TRUE : B_FALSE); 71736835Syc148097 if (link_up == B_FALSE) { 71746835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 71756835Syc148097 "nxge_get_tn1010_speed: link is down")); 71766835Syc148097 goto nxge_get_tn1010_speed_exit; 71776835Syc148097 } 71786835Syc148097 71796835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 71806835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG, 71816835Syc148097 &val)) != NXGE_OK) { 71826835Syc148097 goto fail; 71836835Syc148097 } 71846835Syc148097 autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >> 71856835Syc148097 TN1010_VENDOR_MMD1_AN_STAT_SHIFT; 71866835Syc148097 71876835Syc148097 /* 71886835Syc148097 * Return NXGE_OK even when we can not get a settled speed. In 71896835Syc148097 * such case, the speed reported should not be trusted but that 71906835Syc148097 * is OK, we will call this function periodically and will get 71916835Syc148097 * the correct speed after the link is up. 71926835Syc148097 */ 71936835Syc148097 switch (autoneg_stat) { 71946835Syc148097 case TN1010_AN_IN_PROG: 71956835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 71966835Syc148097 "nxge_get_tn1010_speed: Auto-negotiation in progress")); 71976835Syc148097 break; 71986835Syc148097 case TN1010_AN_COMPLETE: 71996835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 72006835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 72016835Syc148097 TN1010_VENDOR_MMD1_STATUS_REG, 72026835Syc148097 &val)) != NXGE_OK) { 72036835Syc148097 goto fail; 72046835Syc148097 } 72056835Syc148097 *speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >> 72066835Syc148097 TN1010_VENDOR_MMD1_AN_SPEED_SHIFT; 72076835Syc148097 break; 72086835Syc148097 case TN1010_AN_RSVD: 72096835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72106835Syc148097 "nxge_get_tn1010_speed: Autoneg status undefined")); 72116835Syc148097 break; 72126835Syc148097 case TN1010_AN_FAILED: 72136835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 72146835Syc148097 "nxge_get_tn1010_speed: Auto-negotiation failed")); 72156835Syc148097 break; 72166835Syc148097 default: 72176835Syc148097 break; 72186835Syc148097 } 72196835Syc148097 nxge_get_tn1010_speed_exit: 72206835Syc148097 return (NXGE_OK); 72216835Syc148097 fail: 72226835Syc148097 return (status); 72236835Syc148097 } 72246835Syc148097 72256835Syc148097 72266835Syc148097 /* 72276835Syc148097 * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function 72286835Syc148097 * figures out the speed of the PHY determined by the autonegotiation 72296835Syc148097 * process and sets the following 3 parameters, 72306835Syc148097 * nxgep->mac.portmode 72316835Syc148097 * nxgep->statsp->mac_stats.link_speed 72326835Syc148097 * nxgep->statsp->mac_stats.xcvr_inuse 72336835Syc148097 */ 72346835Syc148097 static nxge_status_t 72356835Syc148097 nxge_set_tn1010_param(p_nxge_t nxgep) 72366835Syc148097 { 72376835Syc148097 uint16_t speed; 72386835Syc148097 72396835Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) { 72406835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72416835Syc148097 "nxge_set_tn1010_param: " 72426835Syc148097 "Failed to get TN1010 speed")); 72436835Syc148097 return (NXGE_ERROR); 72446835Syc148097 } 72456835Syc148097 if (speed == TN1010_SPEED_1G) { 72466835Syc148097 nxgep->mac.portmode = PORT_1G_TN1010; 72476835Syc148097 nxgep->statsp->mac_stats.link_speed = 1000; 72486835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 72496835Syc148097 } else { 72506835Syc148097 nxgep->mac.portmode = PORT_10G_TN1010; 72516835Syc148097 nxgep->statsp->mac_stats.link_speed = 10000; 72526835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 72536835Syc148097 } 72546835Syc148097 return (NXGE_OK); 72556835Syc148097 } 72566835Syc148097 72575196Ssbehera #ifdef NXGE_DEBUG 72585196Ssbehera static void 72595196Ssbehera nxge_mii_dump(p_nxge_t nxgep) 72605196Ssbehera { 72615196Ssbehera p_nxge_stats_t statsp; 72625196Ssbehera uint8_t xcvr_portn; 72635196Ssbehera p_mii_regs_t mii_regs; 72645196Ssbehera mii_bmcr_t bmcr; 72655196Ssbehera mii_bmsr_t bmsr; 72665196Ssbehera mii_idr1_t idr1; 72675196Ssbehera mii_idr2_t idr2; 72685196Ssbehera mii_mode_control_stat_t mode; 72696495Sspeer p_nxge_param_t param_arr; 72705196Ssbehera 72715196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump")); 72725196Ssbehera 72735196Ssbehera statsp = nxgep->statsp; 72745196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 72755196Ssbehera 72765196Ssbehera mii_regs = NULL; 72775196Ssbehera 72785196Ssbehera #if defined(__i386) 72795196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 72805196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value); 72815196Ssbehera #else 72825196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 72835196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value); 72845196Ssbehera #endif 72855196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72865196Ssbehera "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x", 72875196Ssbehera xcvr_portn, bmcr.value)); 72885196Ssbehera 72895196Ssbehera #if defined(__i386) 72905196Ssbehera (void) nxge_mii_read(nxgep, 72915196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72925196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value); 72935196Ssbehera #else 72945196Ssbehera (void) nxge_mii_read(nxgep, 72955196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 72965196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value); 72975196Ssbehera #endif 72985196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 72995196Ssbehera "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x", 73005196Ssbehera xcvr_portn, bmsr.value)); 73015196Ssbehera 73025196Ssbehera #if defined(__i386) 73035196Ssbehera (void) nxge_mii_read(nxgep, 73045196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 73055196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value); 73065196Ssbehera #else 73075196Ssbehera (void) nxge_mii_read(nxgep, 73085196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 73095196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value); 73105196Ssbehera #endif 73115196Ssbehera 73125196Ssbehera 73135196Ssbehera #if defined(__i386) 73145196Ssbehera (void) nxge_mii_read(nxgep, 73155196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 73165196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value); 73175196Ssbehera #else 73185196Ssbehera (void) nxge_mii_read(nxgep, 73195196Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 73205196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value); 73215196Ssbehera #endif 73225196Ssbehera 73235196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 73245196Ssbehera "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x", 73255196Ssbehera xcvr_portn, idr1.value)); 73265196Ssbehera 73275196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 73285196Ssbehera "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x", 73295196Ssbehera xcvr_portn, idr2.value)); 73305196Ssbehera 73315196Ssbehera mode.value = 0; 73325203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 73335196Ssbehera 73345196Ssbehera #if defined(__i386) 73355196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 73365196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value); 73375196Ssbehera 73385196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 73395196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value); 73405196Ssbehera #else 73415196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 73425196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value); 73435196Ssbehera 73445196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 73455196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value); 73465196Ssbehera #endif 73475196Ssbehera 73485196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 73495196Ssbehera "nxge_mii_dump: mode control xcvr 0x%x value 0x%x", 73505196Ssbehera xcvr_portn, mode.value)); 73515196Ssbehera } 73525196Ssbehera #endif 7353