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 /*
2212103SSantwona.Behera@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
233859Sml29623 */
243859Sml29623
253859Sml29623 #include <sys/nxge/nxge_impl.h>
263859Sml29623 #include <sys/nxge/nxge_mac.h>
276495Sspeer #include <sys/nxge/nxge_hio.h>
283859Sml29623
294693Stm144005 #define LINK_MONITOR_PERIOD (1000 * 1000)
304693Stm144005 #define LM_WAIT_MULTIPLIER 8
314693Stm144005
326075Ssbehera #define SERDES_RDY_WT_INTERVAL 50
336075Ssbehera #define MAX_SERDES_RDY_RETRIES 10
346075Ssbehera
356835Syc148097 #define TN1010_SPEED_1G 1
366835Syc148097 #define TN1010_SPEED_10G 0
376835Syc148097 #define TN1010_AN_IN_PROG 0 /* Auto negotiation in progress */
386835Syc148097 #define TN1010_AN_COMPLETE 1
396835Syc148097 #define TN1010_AN_RSVD 2
406835Syc148097 #define TN1010_AN_FAILED 3
416835Syc148097
423859Sml29623 extern uint32_t nxge_no_link_notify;
434732Sdavemq extern boolean_t nxge_no_msg;
443859Sml29623 extern uint32_t nxge_lb_dbg;
456028Ssbehera extern uint32_t nxge_jumbo_mtu;
463859Sml29623
474693Stm144005 typedef enum {
484693Stm144005 CHECK_LINK_RESCHEDULE,
494693Stm144005 CHECK_LINK_STOP
504693Stm144005 } check_link_state_t;
514693Stm144005
524693Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *);
534693Stm144005
543859Sml29623 /*
553859Sml29623 * Ethernet broadcast address definition.
563859Sml29623 */
573859Sml29623 static ether_addr_st etherbroadcastaddr =
583859Sml29623 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
594732Sdavemq /*
604732Sdavemq * Ethernet zero address definition.
614732Sdavemq */
624185Sspeer static ether_addr_st etherzeroaddr =
634185Sspeer {{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
644732Sdavemq /*
654732Sdavemq * Supported chip types
664732Sdavemq */
676604Ssbehera static uint32_t nxge_supported_cl45_ids[] = {
686604Ssbehera BCM8704_DEV_ID,
696604Ssbehera MARVELL_88X_201X_DEV_ID,
706835Syc148097 BCM8706_DEV_ID,
716835Syc148097 TN1010_DEV_ID
726604Ssbehera };
736604Ssbehera
746909Sml29623 static uint32_t nxge_supported_cl22_ids[] = {
756909Sml29623 BCM5464R_PHY_ID,
766909Sml29623 BCM5482_PHY_ID
776909Sml29623 };
784732Sdavemq
794732Sdavemq #define NUM_CLAUSE_45_IDS (sizeof (nxge_supported_cl45_ids) / \
804732Sdavemq sizeof (uint32_t))
814732Sdavemq #define NUM_CLAUSE_22_IDS (sizeof (nxge_supported_cl22_ids) / \
824732Sdavemq sizeof (uint32_t))
834732Sdavemq /*
844732Sdavemq * static functions
854732Sdavemq */
864977Sraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
874977Sraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
884977Sraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
894732Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
9012103SSantwona.Behera@Sun.COM static boolean_t nxge_hswap_phy_present(p_nxge_t, uint8_t);
915572Ssbehera static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t);
924732Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
9311304SJanie.Lu@Sun.COM static nxge_status_t nxge_n2_kt_serdes_init(p_nxge_t);
944732Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
954732Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
964732Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
974732Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
984732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
994732Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
1004732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
1014732Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
1024732Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t);
1034732Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t);
1044732Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
1055572Ssbehera static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t);
1065572Ssbehera static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t);
1074732Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
1084732Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t);
1096835Syc148097 static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *);
1106604Ssbehera static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t);
11112103SSantwona.Behera@Sun.COM static nxge_status_t nxge_check_nlp2020_link(p_nxge_t, boolean_t *);
11212103SSantwona.Behera@Sun.COM static nxge_status_t nxge_nlp2020_xcvr_init(p_nxge_t);
11312103SSantwona.Behera@Sun.COM static int nxge_nlp2020_i2c_read(p_nxge_t, uint8_t, uint16_t, uint16_t,
11412103SSantwona.Behera@Sun.COM uint8_t *);
11512103SSantwona.Behera@Sun.COM static boolean_t nxge_is_nlp2020_phy(p_nxge_t);
11612103SSantwona.Behera@Sun.COM static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t);
11712103SSantwona.Behera@Sun.COM static nxge_status_t nxge_set_nlp2020_param(p_nxge_t);
1186835Syc148097 static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
1196835Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui);
1206835Syc148097 static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed);
1216835Syc148097 static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep);
1226835Syc148097 static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep,
1236835Syc148097 nxge_link_state_t *link_up);
1246835Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep);
1256835Syc148097 static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep);
1266835Syc148097
1276835Syc148097 nxge_status_t nxge_mac_init(p_nxge_t);
1286835Syc148097 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
1296835Syc148097
1306835Syc148097 #ifdef NXGE_DEBUG
1316835Syc148097 static void nxge_mii_dump(p_nxge_t);
1326835Syc148097 static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep);
1336835Syc148097 static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep);
1346835Syc148097 #endif
1354732Sdavemq
1364732Sdavemq /*
1374732Sdavemq * xcvr tables for supported transceivers
1384732Sdavemq */
1394732Sdavemq
1406835Syc148097 /*
1416835Syc148097 * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems.
1426835Syc148097 * The Teranetics TN1010 based copper XAUI card can also be used
1436835Syc148097 * on N2-NIU systems in 10G mode, but it uses its own table
1446835Syc148097 * nxge_n2_10G_tn1010_table below.
1456835Syc148097 */
1464977Sraghus static nxge_xcvr_table_t nxge_n2_10G_table = {
1474732Sdavemq nxge_n2_serdes_init,
1484732Sdavemq nxge_10G_xcvr_init,
1494732Sdavemq nxge_10G_link_intr_stop,
1504732Sdavemq nxge_10G_link_intr_start,
1514732Sdavemq nxge_check_10g_link,
1525572Ssbehera PCS_XCVR
1534732Sdavemq };
1544732Sdavemq
1556835Syc148097 /*
1566835Syc148097 * For the Teranetics TN1010 based copper XAUI card
1576835Syc148097 */
1586835Syc148097 static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = {
1596835Syc148097 nxge_n2_serdes_init, /* Handle both 1G and 10G */
1606835Syc148097 nxge_tn1010_xcvr_init, /* Handle both 1G and 10G */
1616835Syc148097 nxge_10G_link_intr_stop,
1626835Syc148097 nxge_10G_link_intr_start,
1636835Syc148097 nxge_check_tn1010_link, /* Will figure out speed */
1646835Syc148097 XPCS_XCVR
1656835Syc148097 };
1666835Syc148097
1674977Sraghus static nxge_xcvr_table_t nxge_n2_1G_table = {
1684977Sraghus nxge_n2_serdes_init,
1694977Sraghus nxge_1G_xcvr_init,
1704977Sraghus nxge_1G_fiber_link_intr_stop,
1714977Sraghus nxge_1G_fiber_link_intr_start,
1724977Sraghus nxge_check_mii_link,
1735572Ssbehera PCS_XCVR
1744977Sraghus };
1754977Sraghus
1766835Syc148097 static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = {
1776835Syc148097 nxge_n2_serdes_init,
1786835Syc148097 nxge_tn1010_xcvr_init,
1796835Syc148097 nxge_1G_fiber_link_intr_stop, /* TN1010 is a Cu PHY, but it uses */
1806835Syc148097 nxge_1G_fiber_link_intr_start, /* PCS for 1G, so call fiber func */
1816835Syc148097 nxge_check_tn1010_link,
1826835Syc148097 PCS_XCVR
1836835Syc148097 };
1846835Syc148097
1856835Syc148097 static nxge_xcvr_table_t nxge_10G_tn1010_table = {
1866835Syc148097 nxge_neptune_10G_serdes_init,
1876835Syc148097 nxge_tn1010_xcvr_init,
1886835Syc148097 nxge_10G_link_intr_stop,
1896835Syc148097 nxge_10G_link_intr_start,
1906835Syc148097 nxge_check_tn1010_link,
1916835Syc148097 XPCS_XCVR
1926835Syc148097 };
1936835Syc148097
1946835Syc148097 static nxge_xcvr_table_t nxge_1G_tn1010_table = {
1956835Syc148097 nxge_1G_serdes_init,
1966835Syc148097 nxge_tn1010_xcvr_init,
1976835Syc148097 nxge_1G_fiber_link_intr_stop,
1986835Syc148097 nxge_1G_fiber_link_intr_start,
1996835Syc148097 nxge_check_tn1010_link,
2006835Syc148097 PCS_XCVR
2016835Syc148097 };
2026835Syc148097
2034732Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = {
2044732Sdavemq nxge_neptune_10G_serdes_init,
2054732Sdavemq nxge_10G_xcvr_init,
2064732Sdavemq nxge_10G_link_intr_stop,
2074732Sdavemq nxge_10G_link_intr_start,
2084732Sdavemq nxge_check_10g_link,
2095572Ssbehera PCS_XCVR
2104732Sdavemq };
2114732Sdavemq
2124732Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = {
2134732Sdavemq NULL,
2144732Sdavemq nxge_1G_xcvr_init,
2154732Sdavemq nxge_1G_copper_link_intr_stop,
2164732Sdavemq nxge_1G_copper_link_intr_start,
2174732Sdavemq nxge_check_mii_link,
2185572Ssbehera INT_MII_XCVR
2194732Sdavemq };
2204732Sdavemq
2216835Syc148097 /* This table is for Neptune portmode == PORT_1G_SERDES cases */
2224732Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = {
2234732Sdavemq nxge_1G_serdes_init,
2244732Sdavemq nxge_1G_xcvr_init,
2254732Sdavemq nxge_1G_fiber_link_intr_stop,
2264732Sdavemq nxge_1G_fiber_link_intr_start,
2274732Sdavemq nxge_check_mii_link,
2285572Ssbehera PCS_XCVR
2294732Sdavemq };
2304732Sdavemq
2314732Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = {
2324732Sdavemq nxge_neptune_10G_serdes_init,
2334732Sdavemq NULL,
2344732Sdavemq NULL,
2354732Sdavemq NULL,
2364977Sraghus NULL,
2375572Ssbehera PCS_XCVR
2384732Sdavemq };
2393859Sml29623
2406835Syc148097 /*
2416835Syc148097 * NXGE_PORT_TN1010 is defined as,
2426835Syc148097 * NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT)
2436835Syc148097 * = 0 | 5 << 16 = 0x50000
2446835Syc148097 *
2456835Syc148097 * So NEPTUNE_2_TN1010 =
2466835Syc148097 * (NXGE_PORT_TN1010 |
2476835Syc148097 * (NXGE_PORT_TN1010 << 4) |
2486835Syc148097 * (NXGE_PORT_NONE << 8) |
2496835Syc148097 * (NXGE_PORT_NONE << 12)),
2506835Syc148097 * = 0x50000 | (0x50000 << 4)
2516835Syc148097 * = 0x550000
2526835Syc148097 *
2536835Syc148097 * This function partitions nxgep->nxge_hw_p->niu_type (which may have
2546835Syc148097 * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010
2556835Syc148097 * = 0x50000
2566835Syc148097 */
nxge_is_tn1010_phy(p_nxge_t nxgep)2576835Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep)
2586835Syc148097 {
2596835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2606835Syc148097
2616835Syc148097 if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn))
2626835Syc148097 & NXGE_PHY_MASK) == NXGE_PORT_TN1010) {
2636835Syc148097 return (B_TRUE);
2646835Syc148097 } else {
2656835Syc148097 return (B_FALSE);
2666835Syc148097 }
2676835Syc148097 }
2686835Syc148097
2696835Syc148097
2706835Syc148097 /*
2716835Syc148097 * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties,
2726835Syc148097 * serial EEPROM or VPD if possible. Note that not all systems could get
2736835Syc148097 * the portmode information by calling this function. For example, the
2746835Syc148097 * Maramba system figures out the portmode information by calling function
2756835Syc148097 * nxge_setup_xcvr_table.
2766835Syc148097 */
2774977Sraghus nxge_status_t
nxge_get_xcvr_type(p_nxge_t nxgep)2784977Sraghus nxge_get_xcvr_type(p_nxge_t nxgep)
2794977Sraghus {
2804977Sraghus nxge_status_t status = NXGE_OK;
2814977Sraghus char *phy_type;
2824977Sraghus char *prop_val;
2836835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2849599Stc99174@train uint32_t val;
2859599Stc99174@train npi_status_t rs;
2869599Stc99174@train
2879599Stc99174@train /* For Opus NEM, skip xcvr checking if 10G Serdes link is up */
2889599Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES &&
2899599Stc99174@train nxgep->statsp->mac_stats.link_up) {
2909599Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2919599Stc99174@train return (status);
2929599Stc99174@train }
2934977Sraghus
2944977Sraghus nxgep->mac.portmode = 0;
2955572Ssbehera nxgep->xcvr_addr = 0;
2965572Ssbehera
2975572Ssbehera /*
2985572Ssbehera * First check for hot swappable phy property.
2995572Ssbehera */
3005572Ssbehera if (nxgep->hot_swappable_phy == B_TRUE) {
3015572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3025572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE;
3035572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable"));
3045572Ssbehera } else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip,
3055572Ssbehera DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
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, ".conf: Hot Swappable"));
3105572Ssbehera } else if (nxgep->niu_type == N2_NIU &&
3115572Ssbehera ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0,
3125572Ssbehera "hot-swappable-phy") == 1) {
3135572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3145572Ssbehera nxgep->mac.portmode = PORT_HSP_MODE;
3155572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable"));
3165572Ssbehera }
3175572Ssbehera
3185572Ssbehera /*
3195572Ssbehera * MDIO polling support for Monza RTM card, Goa NEM card
3205572Ssbehera */
3215572Ssbehera if (nxgep->mac.portmode == PORT_HSP_MODE) {
3225572Ssbehera nxgep->hot_swappable_phy = B_TRUE;
32310577SMichael.Speer@Sun.COM if (portn > 1) {
32410577SMichael.Speer@Sun.COM return (NXGE_ERROR);
32510577SMichael.Speer@Sun.COM }
32610577SMichael.Speer@Sun.COM
32712103SSantwona.Behera@Sun.COM if (nxge_hswap_phy_present(nxgep, portn))
3285572Ssbehera goto found_phy;
3295572Ssbehera
3305572Ssbehera nxgep->phy_absent = B_TRUE;
3319599Stc99174@train
3329599Stc99174@train /* Check Serdes link to detect Opus NEM */
3339599Stc99174@train rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3349599Stc99174@train XPCS_REG_STATUS, &val);
3359599Stc99174@train
3369599Stc99174@train if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) {
3379599Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3389599Stc99174@train nxgep->mac.portmode = PORT_10G_SERDES;
3399599Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3409599Stc99174@train "HSP 10G Serdes FOUND!!"));
3419599Stc99174@train }
3425572Ssbehera goto check_phy_done;
3435572Ssbehera found_phy:
3445572Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3455572Ssbehera nxgep->mac.portmode = PORT_10G_FIBER;
3465572Ssbehera nxgep->phy_absent = B_FALSE;
3475572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr "
3485572Ssbehera "found for hot swappable phy"));
3495572Ssbehera check_phy_done:
3505572Ssbehera return (status);
3515572Ssbehera }
3525572Ssbehera
3536835Syc148097 /* Get phy-type property (May have been set by nxge.conf) */
3544977Sraghus if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
3554977Sraghus DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3564977Sraghus "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
3574977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3584977Sraghus "found conf file: phy-type %s", prop_val));
3594977Sraghus if (strcmp("xgsd", prop_val) == 0) {
3604977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3614977Sraghus nxgep->mac.portmode = PORT_10G_SERDES;
3624977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3634977Sraghus "found: 10G Serdes"));
3644977Sraghus } else if (strcmp("gsd", prop_val) == 0) {
3654977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3664977Sraghus nxgep->mac.portmode = PORT_1G_SERDES;
3674977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
3684977Sraghus } else if (strcmp("mif", prop_val) == 0) {
3694977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
3704977Sraghus nxgep->mac.portmode = PORT_1G_COPPER;
3714977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
3724977Sraghus } else if (strcmp("pcs", prop_val) == 0) {
3734977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3744977Sraghus nxgep->mac.portmode = PORT_1G_FIBER;
3754977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
3766075Ssbehera } else if (strcmp("xgf", prop_val) == 0) {
3776835Syc148097 /*
3786835Syc148097 * Before OBP supports new phy-type property
3796835Syc148097 * value "xgc", the 10G copper XAUI may carry
3806835Syc148097 * "xgf" instead of "xgc". If the OBP is
3816835Syc148097 * upgraded to a newer version which supports
3826835Syc148097 * "xgc", then the TN1010 related code in this
3836835Syc148097 * "xgf" case will not be used anymore.
3846835Syc148097 */
3856835Syc148097 if (nxge_is_tn1010_phy(nxgep)) {
3866835Syc148097 if ((status = nxge_set_tn1010_param(nxgep))
3876835Syc148097 != NXGE_OK) {
3886835Syc148097 return (status);
3896835Syc148097 }
3906835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
3916835Syc148097 } else { /* For Fiber XAUI */
3926835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3936835Syc148097 nxgep->mac.portmode = PORT_10G_FIBER;
3946835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3956835Syc148097 "10G Fiber Xcvr"));
3966835Syc148097 }
3976835Syc148097 } else if (strcmp("xgc", prop_val) == 0) {
3986835Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK)
3996835Syc148097 return (status);
4006835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4014977Sraghus }
4024977Sraghus
4034977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
4044977Sraghus "phy-type", prop_val);
4054977Sraghus ddi_prop_free(prop_val);
4064977Sraghus
4074977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4084977Sraghus "Got phy type [0x%x] from conf file",
4094977Sraghus nxgep->mac.portmode));
4104977Sraghus
4114977Sraghus return (NXGE_OK);
4124977Sraghus }
4135572Ssbehera
4145572Ssbehera /* Get phy-type property from OBP */
4154977Sraghus if (nxgep->niu_type == N2_NIU) {
4164977Sraghus if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
4174977Sraghus "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
4184977Sraghus if (strcmp("xgf", prop_val) == 0) {
4196835Syc148097 /*
4206835Syc148097 * Before OBP supports new phy-type property
4216835Syc148097 * value "xgc", the 10G copper XAUI may carry
4226835Syc148097 * "xgf" instead of "xgc". If the OBP is
4236835Syc148097 * upgraded to a newer version which supports
4246835Syc148097 * "xgc", then the TN1010 related code in this
4256835Syc148097 * "xgf" case will not be used anymore.
4266835Syc148097 */
4276835Syc148097 if (nxge_is_tn1010_phy(nxgep)) {
4286835Syc148097 if ((status =
4296835Syc148097 nxge_set_tn1010_param(nxgep))
4306835Syc148097 != NXGE_OK) {
4316835Syc148097 return (status);
4326835Syc148097 }
4336835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4346835Syc148097 "TN1010 Xcvr"));
43512103SSantwona.Behera@Sun.COM } else if (nxge_is_nlp2020_phy(nxgep)) {
43612103SSantwona.Behera@Sun.COM if ((status =
43712103SSantwona.Behera@Sun.COM nxge_set_nlp2020_param(nxgep))
43812103SSantwona.Behera@Sun.COM != NXGE_OK) {
43912103SSantwona.Behera@Sun.COM return (status);
44012103SSantwona.Behera@Sun.COM }
44112103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
44212103SSantwona.Behera@Sun.COM "NLP2020 Xcvr"));
44312103SSantwona.Behera@Sun.COM } else { /* For Fiber XAUI */
4446835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse
4456835Syc148097 = XPCS_XCVR;
4466835Syc148097 nxgep->mac.portmode = PORT_10G_FIBER;
4476835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4486835Syc148097 "10G Fiber Xcvr"));
4496835Syc148097 }
4504977Sraghus } else if (strcmp("mif", prop_val) == 0) {
4514977Sraghus nxgep->statsp->mac_stats.xcvr_inuse =
4524977Sraghus INT_MII_XCVR;
4534977Sraghus nxgep->mac.portmode = PORT_1G_COPPER;
4544977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4554977Sraghus "1G Copper Xcvr"));
4564977Sraghus } else if (strcmp("pcs", prop_val) == 0) {
4574977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4584977Sraghus nxgep->mac.portmode = PORT_1G_FIBER;
4594977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4604977Sraghus "1G Fiber Xcvr"));
4614977Sraghus } else if (strcmp("xgc", prop_val) == 0) {
4626835Syc148097 status = nxge_set_tn1010_param(nxgep);
4636835Syc148097 if (status != NXGE_OK)
4646835Syc148097 return (status);
4656835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4664977Sraghus } else if (strcmp("xgsd", prop_val) == 0) {
4674977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
4684977Sraghus nxgep->mac.portmode = PORT_10G_SERDES;
4694977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4704977Sraghus "OBP: 10G Serdes"));
4714977Sraghus } else if (strcmp("gsd", prop_val) == 0) {
4724977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4734977Sraghus nxgep->mac.portmode = PORT_1G_SERDES;
4744977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4754977Sraghus "OBP: 1G Serdes"));
4764977Sraghus } else {
4774977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4784977Sraghus "Unknown phy-type: %s", prop_val));
4794977Sraghus ddi_prop_free(prop_val);
4804977Sraghus return (NXGE_ERROR);
4814977Sraghus }
4824977Sraghus status = NXGE_OK;
4834977Sraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE,
4844977Sraghus nxgep->dip, "phy-type", prop_val);
4854977Sraghus ddi_prop_free(prop_val);
4864977Sraghus
4874977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4884977Sraghus "Got phy type [0x%x] from OBP",
4894977Sraghus nxgep->mac.portmode));
4904977Sraghus
4914977Sraghus return (status);
4924977Sraghus } else {
4934977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4944977Sraghus "Exiting...phy-type property not found"));
4954977Sraghus return (NXGE_ERROR);
4964977Sraghus }
4974977Sraghus }
4984977Sraghus
4994977Sraghus
5004977Sraghus if (!nxgep->vpd_info.present) {
5014977Sraghus return (NXGE_OK);
5024977Sraghus }
5034977Sraghus
5044977Sraghus if (!nxgep->vpd_info.ver_valid) {
5054977Sraghus goto read_seeprom;
5064977Sraghus }
5074977Sraghus
5084977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5094977Sraghus "Reading phy type from expansion ROM"));
5104977Sraghus /*
5114977Sraghus * Try to read the phy type from the vpd data read off the
5124977Sraghus * expansion ROM.
5134977Sraghus */
5144977Sraghus phy_type = nxgep->vpd_info.phy_type;
5154977Sraghus
5165196Ssbehera if (strncmp(phy_type, "mif", 3) == 0) {
5174977Sraghus nxgep->mac.portmode = PORT_1G_COPPER;
5184977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
5195196Ssbehera } else if (strncmp(phy_type, "xgf", 3) == 0) {
5204977Sraghus nxgep->mac.portmode = PORT_10G_FIBER;
5214977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
5225196Ssbehera } else if (strncmp(phy_type, "pcs", 3) == 0) {
5234977Sraghus nxgep->mac.portmode = PORT_1G_FIBER;
5244977Sraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
5255196Ssbehera } else if (strncmp(phy_type, "xgc", 3) == 0) {
5266835Syc148097 status = nxge_set_tn1010_param(nxgep);
5276835Syc148097 if (status != NXGE_OK) {
5286835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5296835Syc148097 "nxge_get_xcvr_type: Failed to set TN1010 param"));
5306835Syc148097 goto read_seeprom;
5316835Syc148097 }
5325196Ssbehera } else if (strncmp(phy_type, "xgsd", 4) == 0) {
5335196Ssbehera nxgep->mac.portmode = PORT_10G_SERDES;
5345196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
5355196Ssbehera } else if (strncmp(phy_type, "gsd", 3) == 0) {
5365196Ssbehera nxgep->mac.portmode = PORT_1G_SERDES;
5375196Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
5384977Sraghus } else {
5395196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5404977Sraghus "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
5414977Sraghus phy_type[0], phy_type[1], phy_type[2]));
5424977Sraghus goto read_seeprom;
5434977Sraghus }
5444977Sraghus
5454977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
5464977Sraghus "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
5474977Sraghus
5484977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
5494977Sraghus return (status);
5504977Sraghus
5514977Sraghus read_seeprom:
5524977Sraghus /*
5534977Sraghus * read the phy type from the SEEPROM - NCR registers
5544977Sraghus */
5554977Sraghus status = nxge_espc_phy_type_get(nxgep);
5564977Sraghus if (status != NXGE_OK) {
5574977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5584977Sraghus "Failed to get phy type"));
5594977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
5604977Sraghus "[%s] invalid...please update", nxgep->vpd_info.ver));
5614977Sraghus }
5624977Sraghus
5634977Sraghus return (status);
5644977Sraghus
5654977Sraghus }
5664977Sraghus
5674732Sdavemq /* Set up the PHY specific values. */
5684732Sdavemq
5694732Sdavemq nxge_status_t
nxge_setup_xcvr_table(p_nxge_t nxgep)5704732Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep)
5714732Sdavemq {
5724732Sdavemq nxge_status_t status = NXGE_OK;
5734732Sdavemq uint32_t port_type;
5744732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
5754977Sraghus uint32_t pcs_id = 0;
5764977Sraghus uint32_t pma_pmd_id = 0;
5774977Sraghus uint32_t phy_id = 0;
5785572Ssbehera uint16_t chip_id = 0;
5794732Sdavemq
5804732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
5814732Sdavemq portn));
5824732Sdavemq
5834977Sraghus switch (nxgep->niu_type) {
5844977Sraghus case N2_NIU:
5854977Sraghus switch (nxgep->mac.portmode) {
5864977Sraghus case PORT_1G_FIBER:
5874977Sraghus case PORT_1G_SERDES:
5884977Sraghus nxgep->xcvr = nxge_n2_1G_table;
5895572Ssbehera nxgep->xcvr_addr = portn;
5904977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
5914977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
5924977Sraghus "Serdes"));
5934977Sraghus break;
5944977Sraghus case PORT_10G_FIBER:
59512103SSantwona.Behera@Sun.COM case PORT_10G_COPPER:
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" :
60412103SSantwona.Behera@Sun.COM ((nxgep->mac.portmode == PORT_10G_COPPER) ?
60512103SSantwona.Behera@Sun.COM "Copper" : "Serdes")));
6064977Sraghus break;
6076835Syc148097 case PORT_1G_TN1010:
6086835Syc148097 nxgep->xcvr = nxge_n2_1G_tn1010_table;
6096835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
6106835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6116835Syc148097 "TN1010 Copper Xcvr in 1G"));
6126835Syc148097 break;
6136835Syc148097 case PORT_10G_TN1010:
6146835Syc148097 nxgep->xcvr = nxge_n2_10G_tn1010_table;
6156835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
6166835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6176835Syc148097 "TN1010 Copper Xcvr in 10G"));
6186835Syc148097 break;
6195572Ssbehera case PORT_HSP_MODE:
6205572Ssbehera nxgep->xcvr = nxge_n2_10G_table;
6215572Ssbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR;
6225572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot "
6235572Ssbehera "Swappable Xcvr (not present)"));
6245572Ssbehera break;
6254977Sraghus default:
6264977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6274977Sraghus "<== nxge_setup_xcvr_table: "
6284977Sraghus "Unable to determine NIU portmode"));
6294977Sraghus return (NXGE_ERROR);
6304977Sraghus }
6314977Sraghus break;
6324977Sraghus default:
6334977Sraghus if (nxgep->mac.portmode == 0) {
6344977Sraghus /*
6354977Sraghus * Would be the case for platforms like Maramba
6364977Sraghus * in which the phy type could not be got from conf
6374977Sraghus * file, OBP, VPD or Serial PROM.
6384977Sraghus */
6394977Sraghus if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6404977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6414977Sraghus "<== nxge_setup_xcvr_table:"
6424977Sraghus " Invalid Neptune type [0x%x]",
6434977Sraghus nxgep->niu_type));
6444977Sraghus return (NXGE_ERROR);
6454977Sraghus }
6464977Sraghus
6474977Sraghus port_type = nxgep->niu_type >>
6484977Sraghus (NXGE_PORT_TYPE_SHIFT * portn);
6494977Sraghus port_type = port_type & (NXGE_PORT_TYPE_MASK);
6504977Sraghus
6514977Sraghus switch (port_type) {
6524977Sraghus
6534977Sraghus case NXGE_PORT_1G_COPPER:
6544977Sraghus nxgep->mac.portmode = PORT_1G_COPPER;
6554977Sraghus break;
6564977Sraghus case NXGE_PORT_10G_COPPER:
6574977Sraghus nxgep->mac.portmode = PORT_10G_COPPER;
6584977Sraghus break;
6594977Sraghus case NXGE_PORT_1G_FIBRE:
6604977Sraghus nxgep->mac.portmode = PORT_1G_FIBER;
6614977Sraghus break;
6624977Sraghus case NXGE_PORT_10G_FIBRE:
6634977Sraghus nxgep->mac.portmode = PORT_10G_FIBER;
6644977Sraghus break;
6654977Sraghus case NXGE_PORT_1G_SERDES:
6664977Sraghus nxgep->mac.portmode = PORT_1G_SERDES;
6674977Sraghus break;
6684977Sraghus case NXGE_PORT_10G_SERDES:
6694977Sraghus nxgep->mac.portmode = PORT_10G_SERDES;
6704977Sraghus break;
6716835Syc148097 /* Ports 2 and 3 of Alonso or ARTM */
6724977Sraghus case NXGE_PORT_1G_RGMII_FIBER:
6734977Sraghus nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
6744977Sraghus break;
6756835Syc148097 case NXGE_PORT_TN1010:
6766835Syc148097 /*
6776835Syc148097 * If this port uses the TN1010 copper
6786835Syc148097 * PHY, then its speed is not known yet
6796835Syc148097 * because nxge_scan_ports_phy could only
6806835Syc148097 * figure out the vendor of the PHY but
6816835Syc148097 * not its speed. nxge_set_tn1010_param
6826835Syc148097 * will read the PHY speed and set
6836835Syc148097 * portmode accordingly.
6846835Syc148097 */
6856835Syc148097 if ((status = nxge_set_tn1010_param(nxgep))
6866835Syc148097 != NXGE_OK) {
6876835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6886835Syc148097 "nxge_set_tn1010_param failed"));
6896835Syc148097 return (status);
6906835Syc148097 }
6916835Syc148097 break;
6924977Sraghus default:
6934977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6944977Sraghus "<== nxge_setup_xcvr_table: "
6954977Sraghus "Unknown port-type: 0x%x", port_type));
6964977Sraghus return (NXGE_ERROR);
6974977Sraghus }
6984977Sraghus }
6994977Sraghus
7006835Syc148097 /*
7016835Syc148097 * Above switch has figured out nxge->mac.portmode, now set
7026835Syc148097 * nxgep->xcvr (the table) and nxgep->xcvr_addr according
7036835Syc148097 * to portmode.
7046835Syc148097 */
7054977Sraghus switch (nxgep->mac.portmode) {
7064977Sraghus case PORT_1G_COPPER:
7074977Sraghus case PORT_1G_RGMII_FIBER:
7084732Sdavemq nxgep->xcvr = nxge_1G_copper_table;
7095572Ssbehera nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
7104732Sdavemq /*
7114732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are
7124732Sdavemq * swapped with ethernet port number. This is
7134977Sraghus * designed for better signal integrity in
7144977Sraghus * routing. This is also the case for the
7154977Sraghus * on-board Neptune copper ports on the Maramba
7164977Sraghus * platform.
7174732Sdavemq */
7184977Sraghus switch (nxgep->platform_type) {
7194977Sraghus case P_NEPTUNE_ATLAS_4PORT:
7204977Sraghus case P_NEPTUNE_MARAMBA_P0:
7214977Sraghus case P_NEPTUNE_MARAMBA_P1:
7224977Sraghus switch (portn) {
7234977Sraghus case 0:
7245572Ssbehera nxgep->xcvr_addr += 3;
7254977Sraghus break;
7264977Sraghus case 1:
7275572Ssbehera nxgep->xcvr_addr += 1;
7284977Sraghus break;
7294977Sraghus case 2:
7305572Ssbehera nxgep->xcvr_addr -= 1;
7314977Sraghus break;
7324977Sraghus case 3:
7335572Ssbehera nxgep->xcvr_addr -= 3;
7344977Sraghus break;
7354977Sraghus default:
7364977Sraghus return (NXGE_ERROR);
7374977Sraghus }
7384732Sdavemq break;
7394732Sdavemq default:
7404977Sraghus break;
7414732Sdavemq }
7425196Ssbehera
7434977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7444977Sraghus (nxgep->mac.portmode == PORT_1G_COPPER) ?
7454977Sraghus "Copper" : "RGMII Fiber"));
7464732Sdavemq break;
7476835Syc148097
7484977Sraghus case PORT_10G_COPPER:
7494732Sdavemq nxgep->xcvr = nxge_10G_copper_table;
7504732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
7514732Sdavemq break;
7526835Syc148097
7536835Syc148097 case PORT_1G_TN1010:
7546835Syc148097 nxgep->xcvr = nxge_1G_tn1010_table;
7556835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
7566835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7576835Syc148097 "1G TN1010 copper Xcvr"));
7586835Syc148097 break;
7596835Syc148097
7606835Syc148097 case PORT_10G_TN1010:
7616835Syc148097 nxgep->xcvr = nxge_10G_tn1010_table;
7626835Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
7636835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
7646835Syc148097 "10G TN1010 copper Xcvr"));
7656835Syc148097 break;
7666835Syc148097
7674977Sraghus case PORT_1G_FIBER:
7684977Sraghus case PORT_1G_SERDES:
7694732Sdavemq nxgep->xcvr = nxge_1G_fiber_table;
7705572Ssbehera nxgep->xcvr_addr = portn;
7714977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7724977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER) ?
7734977Sraghus "Fiber" : "Serdes"));
7744732Sdavemq break;
7754977Sraghus case PORT_10G_FIBER:
7764977Sraghus case PORT_10G_SERDES:
7774732Sdavemq nxgep->xcvr = nxge_10G_fiber_table;
7785572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr "
7795572Ssbehera "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] "
7805572Ssbehera "nxgep->xcvr_addr = [%d]",
7815572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn],
7825572Ssbehera nxgep->xcvr_addr));
7835572Ssbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
7845572Ssbehera nxgep->xcvr_addr =
7855572Ssbehera nxgep->nxge_hw_p->xcvr_addr[portn];
7865572Ssbehera }
7874977Sraghus switch (nxgep->platform_type) {
7884977Sraghus case P_NEPTUNE_MARAMBA_P0:
7894977Sraghus case P_NEPTUNE_MARAMBA_P1:
7904732Sdavemq /*
7914732Sdavemq * Switch off LED for corresponding copper
7924732Sdavemq * port
7934732Sdavemq */
7944732Sdavemq nxge_bcm5464_link_led_off(nxgep);
7954977Sraghus break;
7964977Sraghus default:
7974977Sraghus break;
7984732Sdavemq }
7994977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr",
8004977Sraghus (nxgep->mac.portmode == PORT_10G_FIBER) ?
8014977Sraghus "Fiber" : "Serdes"));
8024732Sdavemq break;
8035572Ssbehera
8045572Ssbehera case PORT_HSP_MODE:
8055572Ssbehera nxgep->xcvr = nxge_10G_fiber_table;
8065572Ssbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR;
8075572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot "
8085572Ssbehera "Swappable Xcvr (not present)"));
8095572Ssbehera break;
8104732Sdavemq default:
8114732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8124732Sdavemq "Unknown port-type: 0x%x", port_type));
8134732Sdavemq return (NXGE_ERROR);
8144732Sdavemq }
8154732Sdavemq }
8164732Sdavemq
81712103SSantwona.Behera@Sun.COM if (nxgep->mac.portmode == PORT_10G_FIBER ||
81812103SSantwona.Behera@Sun.COM nxgep->mac.portmode == PORT_10G_COPPER) {
8196604Ssbehera uint32_t pma_pmd_id;
8206604Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep,
8216604Ssbehera nxgep->xcvr_addr);
8226604Ssbehera if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) {
8236604Ssbehera chip_id = MRVL88X201X_CHIP_ID;
8246604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8256604Ssbehera "nxge_setup_xcvr_table: "
8266604Ssbehera "Chip ID MARVELL [0x%x] for 10G xcvr", chip_id));
82712103SSantwona.Behera@Sun.COM } else if ((pma_pmd_id & NLP2020_DEV_ID_MASK) ==
82812103SSantwona.Behera@Sun.COM NLP2020_DEV_ID) {
82912103SSantwona.Behera@Sun.COM chip_id = NLP2020_CHIP_ID;
83012103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83112103SSantwona.Behera@Sun.COM "nxge_setup_xcvr_table: "
83212103SSantwona.Behera@Sun.COM "Chip ID AEL2020 [0x%x] for 10G xcvr", chip_id));
8336604Ssbehera } else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr,
8345572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG,
8355572Ssbehera &chip_id)) == NXGE_OK) {
8365572Ssbehera
8375572Ssbehera switch (chip_id) {
8385572Ssbehera case BCM8704_CHIP_ID:
8395572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8405572Ssbehera "nxge_setup_xcvr_table: "
8415572Ssbehera "Chip ID 8704 [0x%x] for 10G xcvr",
8425572Ssbehera chip_id));
8435572Ssbehera break;
8445572Ssbehera case BCM8706_CHIP_ID:
8455572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8465572Ssbehera "nxge_setup_xcvr_table: "
8475572Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr",
8485572Ssbehera chip_id));
8495572Ssbehera break;
8505572Ssbehera default:
8515572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8525572Ssbehera "nxge_setup_xcvr_table: "
8535572Ssbehera "Unknown Chip ID [0x%x] for 10G xcvr",
8545572Ssbehera chip_id));
8555572Ssbehera break;
8565572Ssbehera }
8575572Ssbehera }
8585572Ssbehera }
8595572Ssbehera
8604732Sdavemq nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
8615572Ssbehera nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr;
8625572Ssbehera nxgep->chip_id = chip_id;
8634977Sraghus
8644977Sraghus /*
8654977Sraghus * Get the actual device ID value returned by MDIO read.
8664977Sraghus */
8674977Sraghus nxgep->statsp->mac_stats.xcvr_id = 0;
8684977Sraghus
8695572Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr);
8704977Sraghus if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) {
8714977Sraghus nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id;
8724977Sraghus } else {
8735572Ssbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr);
8744977Sraghus if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) {
8754977Sraghus nxgep->statsp->mac_stats.xcvr_id = pcs_id;
8764977Sraghus } else {
8774977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep,
8785572Ssbehera nxgep->xcvr_addr);
8794977Sraghus if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
8804977Sraghus nxgep->statsp->mac_stats.xcvr_id = phy_id;
8814977Sraghus }
8824977Sraghus }
8834977Sraghus }
8844977Sraghus
8854732Sdavemq nxgep->mac.linkchkmode = LINKCHK_TIMER;
8864732Sdavemq
8874977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type"
8887801SSantwona.Behera@Sun.COM "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type,
8895572Ssbehera nxgep->platform_type, nxgep->xcvr_addr));
8904977Sraghus
8914732Sdavemq return (status);
8924732Sdavemq }
8934732Sdavemq
8943859Sml29623 /* Initialize the entire MAC and physical layer */
8953859Sml29623
8963859Sml29623 nxge_status_t
nxge_mac_init(p_nxge_t nxgep)8973859Sml29623 nxge_mac_init(p_nxge_t nxgep)
8983859Sml29623 {
8993859Sml29623 uint8_t portn;
9003859Sml29623 nxge_status_t status = NXGE_OK;
9013859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
9023859Sml29623
9033859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
9043859Sml29623
9053859Sml29623 nxgep->mac.portnum = portn;
9063859Sml29623 nxgep->mac.porttype = PORT_TYPE_XMAC;
9073859Sml29623
9083859Sml29623 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
9093859Sml29623 nxgep->mac.porttype = PORT_TYPE_BMAC;
9103859Sml29623
9116835Syc148097
9123859Sml29623 /* Initialize XIF to configure a network mode */
9133859Sml29623 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
9143859Sml29623 goto fail;
9153859Sml29623 }
9163859Sml29623
9173859Sml29623 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
9183859Sml29623 goto fail;
9193859Sml29623 }
9203859Sml29623
9213859Sml29623 /* Initialize TX and RX MACs */
9223859Sml29623 /*
9233859Sml29623 * Always perform XIF init first, before TX and RX MAC init
9243859Sml29623 */
9253859Sml29623 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
9263859Sml29623 goto fail;
9273859Sml29623
9283859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
9293859Sml29623 goto fail;
9303859Sml29623
9313859Sml29623 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
9323859Sml29623 goto fail;
9333859Sml29623
9343859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
9353859Sml29623 goto fail;
9363859Sml29623
9373859Sml29623 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
9383859Sml29623 goto fail;
9393859Sml29623
9409232SMichael.Speer@Sun.COM if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) {
9419232SMichael.Speer@Sun.COM if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
9429232SMichael.Speer@Sun.COM goto fail;
9439232SMichael.Speer@Sun.COM }
9443859Sml29623
9455553Smisaki /* Initialize MAC control configuration */
9465553Smisaki if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
9475553Smisaki goto fail;
9485553Smisaki }
9495553Smisaki
9503859Sml29623 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
9513859Sml29623
9525196Ssbehera /* The Neptune Serdes needs to be reinitialized again */
9535196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
9545196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) ||
9556835Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) ||
9565196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) &&
9575196Ssbehera ((portn == 0) || (portn == 1))) {
9585196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
9595196Ssbehera "nxge_mac_init: reinit Neptune 1G Serdes "));
9605196Ssbehera if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) {
9615196Ssbehera goto fail;
9625196Ssbehera }
9635196Ssbehera }
9645196Ssbehera
9654977Sraghus
9663859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
9673859Sml29623
9683859Sml29623 return (NXGE_OK);
9693859Sml29623 fail:
9703859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
9716929Smisaki "nxge_mac_init: failed to initialize MAC port<%d>", portn));
9723859Sml29623 return (status);
9733859Sml29623 }
9743859Sml29623
9753859Sml29623 /* Initialize the Ethernet Link */
9763859Sml29623
9773859Sml29623 nxge_status_t
nxge_link_init(p_nxge_t nxgep)9783859Sml29623 nxge_link_init(p_nxge_t nxgep)
9793859Sml29623 {
9803859Sml29623 nxge_status_t status = NXGE_OK;
9814977Sraghus nxge_port_mode_t portmode;
9823859Sml29623 #ifdef NXGE_DEBUG
9833859Sml29623 uint8_t portn;
9843859Sml29623
9853859Sml29623 portn = nxgep->mac.portnum;
9863859Sml29623
9873859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
9883859Sml29623 #endif
9899599Stc99174@train /* For Opus NEM, Serdes always needs to be initialized */
9903859Sml29623
9914977Sraghus portmode = nxgep->mac.portmode;
9925572Ssbehera
9936835Syc148097 /*
9946835Syc148097 * Workaround to get link up in both NIU ports. Some portmodes require
9956835Syc148097 * that the xcvr be initialized twice, the first time before calling
9966835Syc148097 * nxge_serdes_init.
9976835Syc148097 */
9984977Sraghus if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
9996835Syc148097 (portmode != PORT_10G_TN1010) &&
10006835Syc148097 (portmode != PORT_1G_TN1010) &&
10014977Sraghus (portmode != PORT_1G_SERDES)) {
10024977Sraghus if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
10033859Sml29623 goto fail;
10044977Sraghus }
10053859Sml29623 }
10066835Syc148097
10073859Sml29623 NXGE_DELAY(200000);
10083859Sml29623 /* Initialize internal serdes */
10093859Sml29623 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
10103859Sml29623 goto fail;
10113859Sml29623 NXGE_DELAY(200000);
10123859Sml29623 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
10133859Sml29623 goto fail;
10143859Sml29623
10153859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
10163859Sml29623
10173859Sml29623 return (NXGE_OK);
10183859Sml29623
10193859Sml29623 fail:
10206929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ",
10216929Smisaki "failed to initialize Ethernet link on port<%d>", portn));
10223859Sml29623
10233859Sml29623 return (status);
10243859Sml29623 }
10253859Sml29623
10263859Sml29623
10273859Sml29623 /* Initialize the XIF sub-block within the MAC */
10283859Sml29623
10293859Sml29623 nxge_status_t
nxge_xif_init(p_nxge_t nxgep)10303859Sml29623 nxge_xif_init(p_nxge_t nxgep)
10313859Sml29623 {
10323859Sml29623 uint32_t xif_cfg = 0;
10333859Sml29623 npi_attr_t ap;
10343859Sml29623 uint8_t portn;
10353859Sml29623 nxge_port_t portt;
10363859Sml29623 nxge_port_mode_t portmode;
10373859Sml29623 p_nxge_stats_t statsp;
10383859Sml29623 npi_status_t rs = NPI_SUCCESS;
10393859Sml29623 npi_handle_t handle;
10403859Sml29623
10413859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
10423859Sml29623
10433859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
10443859Sml29623
10453859Sml29623 handle = nxgep->npi_handle;
10463859Sml29623 portmode = nxgep->mac.portmode;
10473859Sml29623 portt = nxgep->mac.porttype;
10483859Sml29623 statsp = nxgep->statsp;
10493859Sml29623
10505196Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
10515196Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) ||
10526835Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) ||
10535196Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) &&
10545196Ssbehera ((portn == 0) || (portn == 1))) {
10555196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
10565196Ssbehera "nxge_xcvr_init: set ATCA mode"));
10575196Ssbehera npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE);
10585196Ssbehera }
10595196Ssbehera
10603859Sml29623 if (portt == PORT_TYPE_XMAC) {
10613859Sml29623
10623859Sml29623 /* Setup XIF Configuration for XMAC */
10633859Sml29623
10643859Sml29623 if ((portmode == PORT_10G_FIBER) ||
10654977Sraghus (portmode == PORT_10G_COPPER) ||
10666835Syc148097 (portmode == PORT_10G_TN1010) ||
10679599Stc99174@train (portmode == PORT_HSP_MODE) ||
10684977Sraghus (portmode == PORT_10G_SERDES))
10693859Sml29623 xif_cfg |= CFG_XMAC_XIF_LFS;
10703859Sml29623
10716835Syc148097 /* Bypass PCS so that RGMII will be used */
10723859Sml29623 if (portmode == PORT_1G_COPPER) {
10733859Sml29623 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
10743859Sml29623 }
10753859Sml29623
10763859Sml29623 /* Set MAC Internal Loopback if necessary */
10773859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
10783859Sml29623 xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
10793859Sml29623
10803859Sml29623 if (statsp->mac_stats.link_speed == 100)
10813859Sml29623 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
10823859Sml29623
10833859Sml29623 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
10843859Sml29623
10854977Sraghus if ((portmode == PORT_10G_FIBER) ||
108612103SSantwona.Behera@Sun.COM (portmode == PORT_10G_COPPER) ||
10876835Syc148097 (portmode == PORT_10G_TN1010) ||
10886835Syc148097 (portmode == PORT_1G_TN1010) ||
10899599Stc99174@train (portmode == PORT_HSP_MODE) ||
10904977Sraghus (portmode == PORT_10G_SERDES)) {
10916835Syc148097 /* Assume LED same for 1G and 10G */
10923859Sml29623 if (statsp->mac_stats.link_up) {
10933859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
10943859Sml29623 } else {
10953859Sml29623 xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
10963859Sml29623 }
10973859Sml29623 }
10983859Sml29623
10993859Sml29623 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
11003859Sml29623 if (rs != NPI_SUCCESS)
11013859Sml29623 goto fail;
11023859Sml29623
11033859Sml29623 nxgep->mac.xif_config = xif_cfg;
11043859Sml29623
11053859Sml29623 /* Set Port Mode */
11063859Sml29623 if ((portmode == PORT_10G_FIBER) ||
11074977Sraghus (portmode == PORT_10G_COPPER) ||
11086835Syc148097 (portmode == PORT_10G_TN1010) ||
11099599Stc99174@train (portmode == PORT_HSP_MODE) ||
11104977Sraghus (portmode == PORT_10G_SERDES)) {
11113859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11126929Smisaki MAC_XGMII_MODE, rs);
11133859Sml29623 if (rs != NPI_SUCCESS)
11143859Sml29623 goto fail;
11153859Sml29623 if (statsp->mac_stats.link_up) {
11163859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
11173859Sml29623 goto fail;
11183859Sml29623 } else {
11193859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
11203859Sml29623 goto fail;
11213859Sml29623 }
11223859Sml29623 } else if ((portmode == PORT_1G_FIBER) ||
11234977Sraghus (portmode == PORT_1G_COPPER) ||
11245196Ssbehera (portmode == PORT_1G_SERDES) ||
11256835Syc148097 (portmode == PORT_1G_TN1010) ||
11265196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) {
11275196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11285196Ssbehera "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
11295196Ssbehera portn, portmode, statsp->mac_stats.link_speed));
11303859Sml29623 if (statsp->mac_stats.link_speed == 1000) {
11313859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11326929Smisaki MAC_GMII_MODE, rs);
11333859Sml29623 } else {
11343859Sml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11356929Smisaki MAC_MII_MODE, rs);
11363859Sml29623 }
11373859Sml29623 if (rs != NPI_SUCCESS)
11383859Sml29623 goto fail;
11393859Sml29623 } else {
11403859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11416929Smisaki "nxge_xif_init: Unknown port mode (%d)"
11426929Smisaki " for port<%d>", portmode, portn));
11433859Sml29623 goto fail;
11443859Sml29623 }
11453859Sml29623
11465196Ssbehera /* Enable ATCA mode */
11475196Ssbehera
11483859Sml29623 } else if (portt == PORT_TYPE_BMAC) {
11493859Sml29623
11503859Sml29623 /* Setup XIF Configuration for BMAC */
11513859Sml29623
11525196Ssbehera if ((portmode == PORT_1G_COPPER) ||
11535196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) {
11543859Sml29623 if (statsp->mac_stats.link_speed == 100)
11553859Sml29623 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
11563859Sml29623 }
11573859Sml29623
11583859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
11593859Sml29623 xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
11603859Sml29623
11613859Sml29623 if (statsp->mac_stats.link_speed == 1000)
11623859Sml29623 xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
11633859Sml29623
11643859Sml29623 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
11653859Sml29623
11663859Sml29623 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
11673859Sml29623 if (rs != NPI_SUCCESS)
11683859Sml29623 goto fail;
11693859Sml29623 nxgep->mac.xif_config = xif_cfg;
11703859Sml29623 }
11713859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
11723859Sml29623 return (NXGE_OK);
11733859Sml29623 fail:
11743859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11756929Smisaki "nxge_xif_init: Failed to initialize XIF port<%d>", portn));
11763859Sml29623 return (NXGE_ERROR | rs);
11773859Sml29623 }
11783859Sml29623
11796835Syc148097
11806835Syc148097 /*
11816835Syc148097 * Initialize the PCS sub-block in the MAC. Note that PCS does not
11826835Syc148097 * support loopback like XPCS.
11836835Syc148097 */
11843859Sml29623 nxge_status_t
nxge_pcs_init(p_nxge_t nxgep)11853859Sml29623 nxge_pcs_init(p_nxge_t nxgep)
11863859Sml29623 {
11873859Sml29623 pcs_cfg_t pcs_cfg;
11883859Sml29623 uint32_t val;
11893859Sml29623 uint8_t portn;
11903859Sml29623 nxge_port_mode_t portmode;
11913859Sml29623 npi_handle_t handle;
11923859Sml29623 p_nxge_stats_t statsp;
11936835Syc148097 pcs_ctrl_t pcs_ctrl;
11943859Sml29623 npi_status_t rs = NPI_SUCCESS;
11956835Syc148097 uint8_t i;
11963859Sml29623
11973859Sml29623 handle = nxgep->npi_handle;
11983859Sml29623 portmode = nxgep->mac.portmode;
11993859Sml29623 portn = nxgep->mac.portnum;
12003859Sml29623 statsp = nxgep->statsp;
12013859Sml29623
12023859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
12033859Sml29623
12046835Syc148097 if (portmode == PORT_1G_FIBER ||
12056835Syc148097 portmode == PORT_1G_TN1010 ||
12066835Syc148097 portmode == PORT_1G_SERDES) {
12076835Syc148097 if (portmode == PORT_1G_TN1010) {
12086835Syc148097 /* Reset PCS multiple time in PORT_1G_TN1010 mode */
12096835Syc148097 for (i = 0; i < 6; i ++) {
12106835Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn))
12116835Syc148097 != NPI_SUCCESS) {
12126835Syc148097 goto fail;
12136835Syc148097 }
12146835Syc148097 }
12156835Syc148097 } else {
12166835Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn))
12176835Syc148097 != NPI_SUCCESS)
12186835Syc148097 goto fail;
12194977Sraghus }
12204977Sraghus
12213859Sml29623 /* Initialize port's PCS */
12223859Sml29623 pcs_cfg.value = 0;
12233859Sml29623 pcs_cfg.bits.w0.enable = 1;
12243859Sml29623 pcs_cfg.bits.w0.mask = 1;
12253859Sml29623 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
12263859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
12274977Sraghus
12284977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12294977Sraghus "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
12304977Sraghus portn, pcs_cfg.value));
12316835Syc148097
12326835Syc148097 if (portmode == PORT_1G_TN1010) {
12336835Syc148097 /*
12346835Syc148097 * Must disable PCS auto-negotiation when the the driver
12356835Syc148097 * is driving the TN1010 based XAUI card Otherwise the
12366835Syc148097 * autonegotiation between the PCS and the TN1010 PCS
12376835Syc148097 * will never complete and the Neptune/NIU will not work
12386835Syc148097 */
12396835Syc148097 pcs_ctrl.value = 0;
12406835Syc148097 PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG,
12416835Syc148097 pcs_ctrl.value);
12426835Syc148097 }
12436835Syc148097 } else if (portmode == PORT_10G_FIBER ||
12446835Syc148097 portmode == PORT_10G_COPPER ||
12456835Syc148097 portmode == PORT_10G_TN1010 ||
12469599Stc99174@train portmode == PORT_HSP_MODE ||
12476835Syc148097 portmode == PORT_10G_SERDES) {
12483859Sml29623 /* Use internal XPCS, bypass 1G PCS */
12493859Sml29623 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
12503859Sml29623 val &= ~XMAC_XIF_XPCS_BYPASS;
12513859Sml29623 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
12523859Sml29623
12533859Sml29623 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
12543859Sml29623 goto fail;
12553859Sml29623
12563859Sml29623 /* Set XPCS Internal Loopback if necessary */
12573859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn,
12586929Smisaki XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS)
12593859Sml29623 goto fail;
12606835Syc148097
12613859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
12626929Smisaki (statsp->port_stats.lb_mode == nxge_lb_mac1000))
12633859Sml29623 val |= XPCS_CTRL1_LOOPBK;
12643859Sml29623 else
12653859Sml29623 val &= ~XPCS_CTRL1_LOOPBK;
12663859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn,
12676929Smisaki XPCS_REG_CONTROL1, val)) != NPI_SUCCESS)
12683859Sml29623 goto fail;
12693859Sml29623
12703859Sml29623 /* Clear descw errors */
12713859Sml29623 if ((rs = npi_xmac_xpcs_write(handle, portn,
12726929Smisaki XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS)
12733859Sml29623 goto fail;
12743859Sml29623 /* Clear symbol errors */
12753859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn,
12766929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS)
12773859Sml29623 goto fail;
12783859Sml29623 if ((rs = npi_xmac_xpcs_read(handle, portn,
12796929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS)
12803859Sml29623 goto fail;
12813859Sml29623
12825196Ssbehera } else if ((portmode == PORT_1G_COPPER) ||
12835196Ssbehera (portmode == PORT_1G_RGMII_FIBER)) {
12845196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12855196Ssbehera "==> nxge_pcs_init: (1G) copper port<%d>", portn));
12863859Sml29623 if (portn < 4) {
12873859Sml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
12886929Smisaki PCS_DATAPATH_MODE_MII);
12893859Sml29623 }
12903859Sml29623 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
12913859Sml29623 goto fail;
12923859Sml29623
12933859Sml29623 } else {
12943859Sml29623 goto fail;
12953859Sml29623 }
12963859Sml29623 pass:
12973859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
12983859Sml29623 return (NXGE_OK);
12993859Sml29623 fail:
13003859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13016929Smisaki "nxge_pcs_init: Failed to initialize PCS port<%d>", portn));
13023859Sml29623 return (NXGE_ERROR | rs);
13033859Sml29623 }
13043859Sml29623
13055553Smisaki /*
13065553Smisaki * Initialize the MAC CTRL sub-block within the MAC
13075553Smisaki * Only the receive-pause-cap is supported.
13085553Smisaki */
13095553Smisaki nxge_status_t
nxge_mac_ctrl_init(p_nxge_t nxgep)13105553Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep)
13115553Smisaki {
13125553Smisaki uint8_t portn;
13135553Smisaki nxge_port_t portt;
13145553Smisaki p_nxge_stats_t statsp;
13155553Smisaki npi_handle_t handle;
13165553Smisaki uint32_t val;
13175553Smisaki
13185553Smisaki portn = NXGE_GET_PORT_NUM(nxgep->function_num);
13195553Smisaki
13205553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>",
13215553Smisaki portn));
13225553Smisaki
13235553Smisaki handle = nxgep->npi_handle;
13245553Smisaki portt = nxgep->mac.porttype;
13255553Smisaki statsp = nxgep->statsp;
13265553Smisaki
13275553Smisaki if (portt == PORT_TYPE_XMAC) {
13286835Syc148097 /* Reading the current XMAC Config Register for XMAC */
13295553Smisaki XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
13305553Smisaki
13315553Smisaki /*
13325553Smisaki * Setup XMAC Configuration for XMAC
13335553Smisaki * XMAC only supports receive-pause
13345553Smisaki */
13355553Smisaki if (statsp->mac_stats.adv_cap_asmpause) {
13365553Smisaki if (!statsp->mac_stats.adv_cap_pause) {
13375553Smisaki /*
13385553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause
13395553Smisaki * is 0, enable receive pause.
13405553Smisaki */
13415553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN;
13425553Smisaki } else {
13435553Smisaki /*
13445553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause
13455553Smisaki * is 1, disable receive pause. Send pause is
13465553Smisaki * not supported.
13475553Smisaki */
13485553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
13495553Smisaki }
13505553Smisaki } else {
13516439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13526439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: pause",
13536439Sml29623 portn));
13545553Smisaki if (statsp->mac_stats.adv_cap_pause) {
13556439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13566439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: "
13576439Sml29623 "enable pause", portn));
13585553Smisaki /*
13595553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause
13605553Smisaki * is 1, enable receive pause.
13615553Smisaki */
13625553Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN;
13635553Smisaki } else {
13645553Smisaki /*
13655553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause
13665553Smisaki * is 0, disable receive pause. Send pause is
13675553Smisaki * not supported
13685553Smisaki */
13696439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13706439Sml29623 "==> nxge_mac_ctrl_init: port<%d>: "
13716439Sml29623 "disable pause", portn));
13725553Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
13735553Smisaki }
13745553Smisaki }
13755553Smisaki XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
13765553Smisaki } else if (portt == PORT_TYPE_BMAC) {
13776835Syc148097 /* Reading the current MAC CTRL Config Register for BMAC */
13785553Smisaki BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val);
13795553Smisaki
13805553Smisaki /* Setup MAC CTRL Configuration for BMAC */
13815553Smisaki if (statsp->mac_stats.adv_cap_asmpause) {
13825553Smisaki if (statsp->mac_stats.adv_cap_pause) {
13835553Smisaki /*
13845553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause
13855553Smisaki * is 1, disable receive pause. Send pause
13865553Smisaki * is not supported
13875553Smisaki */
13885553Smisaki val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN;
13895553Smisaki } else {
13905553Smisaki /*
13915553Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause
13925553Smisaki * is 0, enable receive pause and disable
13935553Smisaki * send pause.
13945553Smisaki */
13955553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
13965553Smisaki val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN;
13975553Smisaki }
13985553Smisaki } else {
13995553Smisaki if (statsp->mac_stats.adv_cap_pause) {
14005553Smisaki /*
14015553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause
14025553Smisaki * is 1, enable receive pause. Send pause is
14035553Smisaki * not supported.
14045553Smisaki */
14055553Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
14065553Smisaki } else {
14075553Smisaki /*
14085553Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause
14095553Smisaki * is 0, pause capability is not available in
14105553Smisaki * either direction.
14115553Smisaki */
14125553Smisaki val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN &
14136929Smisaki ~MAC_CTRL_CFG_RECV_PAUSE_EN);
14145553Smisaki }
14155553Smisaki }
14165553Smisaki BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val);
14175553Smisaki }
14185553Smisaki
14195553Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>",
14205553Smisaki portn));
14215553Smisaki
14225553Smisaki return (NXGE_OK);
14235553Smisaki }
14245553Smisaki
14253859Sml29623 /* Initialize the Internal Serdes */
14263859Sml29623
14273859Sml29623 nxge_status_t
nxge_serdes_init(p_nxge_t nxgep)14283859Sml29623 nxge_serdes_init(p_nxge_t nxgep)
14293859Sml29623 {
14303859Sml29623 p_nxge_stats_t statsp;
14313859Sml29623 #ifdef NXGE_DEBUG
14323859Sml29623 uint8_t portn;
14333859Sml29623 #endif
14343859Sml29623 nxge_status_t status = NXGE_OK;
14353859Sml29623
14363859Sml29623 #ifdef NXGE_DEBUG
14373859Sml29623 portn = nxgep->mac.portnum;
14383859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14394732Sdavemq "==> nxge_serdes_init port<%d>", portn));
14403859Sml29623 #endif
14413859Sml29623
14424732Sdavemq if (nxgep->xcvr.serdes_init) {
14434732Sdavemq statsp = nxgep->statsp;
14444732Sdavemq status = nxgep->xcvr.serdes_init(nxgep);
14454732Sdavemq if (status != NXGE_OK)
14463859Sml29623 goto fail;
14474732Sdavemq statsp->mac_stats.serdes_inits++;
14483859Sml29623 }
14493859Sml29623
14503859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
14514732Sdavemq portn));
14523859Sml29623
14533859Sml29623 return (NXGE_OK);
14543859Sml29623
14553859Sml29623 fail:
14563859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14574732Sdavemq "nxge_serdes_init: Failed to initialize serdes for port<%d>",
14584732Sdavemq portn));
14593859Sml29623
14603859Sml29623 return (status);
14613859Sml29623 }
14623859Sml29623
14633859Sml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
14643859Sml29623
14654732Sdavemq static nxge_status_t
nxge_n2_serdes_init(p_nxge_t nxgep)14663859Sml29623 nxge_n2_serdes_init(p_nxge_t nxgep)
14673859Sml29623 {
14683859Sml29623 uint8_t portn;
14693859Sml29623 int chan;
14703859Sml29623 esr_ti_cfgpll_l_t pll_cfg_l;
14714977Sraghus esr_ti_cfgpll_l_t pll_sts_l;
14723859Sml29623 esr_ti_cfgrx_l_t rx_cfg_l;
14733859Sml29623 esr_ti_cfgrx_h_t rx_cfg_h;
14743859Sml29623 esr_ti_cfgtx_l_t tx_cfg_l;
14753859Sml29623 esr_ti_cfgtx_h_t tx_cfg_h;
14764977Sraghus #ifdef NXGE_DEBUG
14774977Sraghus esr_ti_testcfg_t cfg;
14784977Sraghus #endif
14793859Sml29623 esr_ti_testcfg_t test_cfg;
14803859Sml29623 nxge_status_t status = NXGE_OK;
14813859Sml29623
14823859Sml29623 portn = nxgep->mac.portnum;
14833859Sml29623
14843859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
14856929Smisaki portn));
148611304SJanie.Lu@Sun.COM if (nxgep->niu_hw_type == NIU_HW_TYPE_RF) {
148711304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
148811304SJanie.Lu@Sun.COM "==> nxge_n2_serdes_init port<%d>: KT-NIU", portn));
148911304SJanie.Lu@Sun.COM return (nxge_n2_kt_serdes_init(nxgep));
149011304SJanie.Lu@Sun.COM }
14913859Sml29623
14923859Sml29623 tx_cfg_l.value = 0;
14933859Sml29623 tx_cfg_h.value = 0;
14943859Sml29623 rx_cfg_l.value = 0;
14953859Sml29623 rx_cfg_h.value = 0;
14963859Sml29623 pll_cfg_l.value = 0;
14974977Sraghus pll_sts_l.value = 0;
14983859Sml29623 test_cfg.value = 0;
14993859Sml29623
15006835Syc148097 /*
15016835Syc148097 * If the nxge driver has been plumbed without a link, then it will
15026835Syc148097 * detect a link up when a cable connecting to an anto-negotiation
15036835Syc148097 * partner is plugged into the port. Because the TN1010 PHY supports
15046835Syc148097 * both 1G and 10G speeds, the driver must re-configure the
15056835Syc148097 * Neptune/NIU according to the negotiated speed. nxge_n2_serdes_init
15066835Syc148097 * is called at the post-link-up reconfiguration time. Here it calls
15076835Syc148097 * nxge_set_tn1010_param to set portmode before re-initializing
15086835Syc148097 * the serdes.
15096835Syc148097 */
15106835Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 ||
15116835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) {
15126835Syc148097 if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
15136835Syc148097 goto fail;
15146835Syc148097 }
15156835Syc148097 }
15166835Syc148097
15176835Syc148097 if (nxgep->mac.portmode == PORT_10G_FIBER ||
151812103SSantwona.Behera@Sun.COM nxgep->mac.portmode == PORT_10G_COPPER ||
15196835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010 ||
15209599Stc99174@train nxgep->mac.portmode == PORT_HSP_MODE ||
15216835Syc148097 nxgep->mac.portmode == PORT_10G_SERDES) {
15223859Sml29623 /* 0x0E01 */
15233859Sml29623 tx_cfg_l.bits.entx = 1;
15243859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
15253859Sml29623
15263859Sml29623 /* 0x9101 */
15273859Sml29623 rx_cfg_l.bits.enrx = 1;
15283859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
15293859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
15303859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
15313859Sml29623
15323859Sml29623 /* 0x0008 */
15333859Sml29623 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15343859Sml29623
15353859Sml29623 /* Set loopback mode if necessary */
15363859Sml29623 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
15373859Sml29623 tx_cfg_l.bits.entest = 1;
15383859Sml29623 rx_cfg_l.bits.entest = 1;
15393859Sml29623 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
15403859Sml29623 if ((status = nxge_mdio_write(nxgep, portn,
15416929Smisaki ESR_N2_DEV_ADDR,
15426929Smisaki ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK)
15433859Sml29623 goto fail;
15443859Sml29623 }
15453859Sml29623
15466835Syc148097 /* Initialize PLL for 10G */
15476835Syc148097 pll_cfg_l.bits.mpy = CFGPLL_MPY_10X;
15486835Syc148097 pll_cfg_l.bits.enpll = 1;
15496835Syc148097 pll_sts_l.bits.enpll = 1;
15506835Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
15516835Syc148097 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
15526835Syc148097 goto fail;
15536835Syc148097
15546835Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
15556835Syc148097 ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
15566835Syc148097 goto fail;
15576835Syc148097
15586835Syc148097 #ifdef NXGE_DEBUG
15596835Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
15606835Syc148097 ESR_N2_PLL_CFG_L_REG, &cfg.value);
15616835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
15626835Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
15636835Syc148097 portn, pll_cfg_l.value, cfg.value));
15646835Syc148097
15656835Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
15666835Syc148097 ESR_N2_PLL_STS_L_REG, &cfg.value);
15676835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
15686835Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
15696835Syc148097 portn, pll_sts_l.value, cfg.value));
15706835Syc148097 #endif
15716835Syc148097 } else if (nxgep->mac.portmode == PORT_1G_FIBER ||
15726835Syc148097 nxgep->mac.portmode == PORT_1G_TN1010 ||
15736835Syc148097 nxgep->mac.portmode == PORT_1G_SERDES) {
15743859Sml29623 /* 0x0E21 */
15753859Sml29623 tx_cfg_l.bits.entx = 1;
15763859Sml29623 tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
15773859Sml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
15783859Sml29623
15793859Sml29623 /* 0x9121 */
15803859Sml29623 rx_cfg_l.bits.enrx = 1;
15813859Sml29623 rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
15823859Sml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
15833859Sml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
15843859Sml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
15853859Sml29623
15864977Sraghus if (portn == 0) {
15874977Sraghus /* 0x8 */
15884977Sraghus rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15894977Sraghus }
15903859Sml29623
15916835Syc148097 /* Initialize PLL for 1G */
15923859Sml29623 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
15933859Sml29623 pll_cfg_l.bits.enpll = 1;
15944977Sraghus pll_sts_l.bits.enpll = 1;
15953859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
15966929Smisaki ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
15973859Sml29623 goto fail;
15984977Sraghus
15994977Sraghus if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16004977Sraghus ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
16014977Sraghus goto fail;
16024977Sraghus
16034977Sraghus #ifdef NXGE_DEBUG
16044977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
16054977Sraghus ESR_N2_PLL_CFG_L_REG, &cfg.value);
16064977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16074977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
16084977Sraghus portn, pll_cfg_l.value, cfg.value));
16094977Sraghus
16104977Sraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
16114977Sraghus ESR_N2_PLL_STS_L_REG, &cfg.value);
16124977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16134977Sraghus "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
16144977Sraghus portn, pll_sts_l.value, cfg.value));
16154977Sraghus #endif
16164977Sraghus
16174977Sraghus /* Set loopback mode if necessary */
16184977Sraghus if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
16194977Sraghus tx_cfg_l.bits.entest = 1;
16204977Sraghus rx_cfg_l.bits.entest = 1;
16214977Sraghus test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
16224977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16234977Sraghus "==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
16244977Sraghus portn, test_cfg.value));
16254977Sraghus if ((status = nxge_mdio_write(nxgep, portn,
16264977Sraghus ESR_N2_DEV_ADDR,
16274977Sraghus ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
16284977Sraghus goto fail;
16294977Sraghus }
16304977Sraghus }
16313859Sml29623 } else {
16323859Sml29623 goto fail;
16333859Sml29623 }
16343859Sml29623
16353859Sml29623 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
16363859Sml29623
16373859Sml29623 NXGE_DELAY(20);
16383859Sml29623
16393859Sml29623 /* init TX channels */
16403859Sml29623 for (chan = 0; chan < 4; chan++) {
16413859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16426929Smisaki ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
16433859Sml29623 goto fail;
16443859Sml29623
16453859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16466929Smisaki ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
16473859Sml29623 goto fail;
16484977Sraghus
16494977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16504977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
16514977Sraghus portn, chan, tx_cfg_l.value));
16524977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16534977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
16544977Sraghus portn, chan, tx_cfg_h.value));
16553859Sml29623 }
16563859Sml29623
16573859Sml29623 /* init RX channels */
16583859Sml29623 for (chan = 0; chan < 4; chan++) {
16593859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16606929Smisaki ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK)
16613859Sml29623 goto fail;
16623859Sml29623
16633859Sml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16646929Smisaki ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK)
16653859Sml29623 goto fail;
16664977Sraghus
16674977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16684977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
16694977Sraghus portn, chan, rx_cfg_l.value));
16706835Syc148097
16714977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16724977Sraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
16734977Sraghus portn, chan, rx_cfg_h.value));
16743859Sml29623 }
16753859Sml29623
16763859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
16776929Smisaki portn));
16783859Sml29623
16793859Sml29623 return (NXGE_OK);
16803859Sml29623 fail:
16815572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16825572Ssbehera "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
16835572Ssbehera portn));
16843859Sml29623
16853859Sml29623 return (status);
168611304SJanie.Lu@Sun.COM
168711304SJanie.Lu@Sun.COM }
168811304SJanie.Lu@Sun.COM
168911304SJanie.Lu@Sun.COM /* Initialize the TI Hedwig Internal Serdes (N2-KT-NIU only) */
169011304SJanie.Lu@Sun.COM
169111304SJanie.Lu@Sun.COM static nxge_status_t
nxge_n2_kt_serdes_init(p_nxge_t nxgep)169211304SJanie.Lu@Sun.COM nxge_n2_kt_serdes_init(p_nxge_t nxgep)
169311304SJanie.Lu@Sun.COM {
169411304SJanie.Lu@Sun.COM uint8_t portn;
169512103SSantwona.Behera@Sun.COM int chan, i;
169611304SJanie.Lu@Sun.COM k_esr_ti_cfgpll_l_t pll_cfg_l;
169711304SJanie.Lu@Sun.COM k_esr_ti_cfgrx_l_t rx_cfg_l;
169811304SJanie.Lu@Sun.COM k_esr_ti_cfgrx_h_t rx_cfg_h;
169911304SJanie.Lu@Sun.COM k_esr_ti_cfgtx_l_t tx_cfg_l;
170011304SJanie.Lu@Sun.COM k_esr_ti_cfgtx_h_t tx_cfg_h;
170111304SJanie.Lu@Sun.COM #ifdef NXGE_DEBUG
170211304SJanie.Lu@Sun.COM k_esr_ti_testcfg_t cfg;
170311304SJanie.Lu@Sun.COM #endif
170411304SJanie.Lu@Sun.COM k_esr_ti_testcfg_t test_cfg;
170511304SJanie.Lu@Sun.COM nxge_status_t status = NXGE_OK;
170611304SJanie.Lu@Sun.COM boolean_t mode_1g = B_FALSE;
170712103SSantwona.Behera@Sun.COM uint64_t val;
170812103SSantwona.Behera@Sun.COM npi_handle_t handle;
170911304SJanie.Lu@Sun.COM
171011304SJanie.Lu@Sun.COM portn = nxgep->mac.portnum;
171111304SJanie.Lu@Sun.COM
171211304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
171311304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>", portn));
171412103SSantwona.Behera@Sun.COM handle = nxgep->npi_handle;
171511304SJanie.Lu@Sun.COM
171611304SJanie.Lu@Sun.COM tx_cfg_l.value = 0;
171711304SJanie.Lu@Sun.COM tx_cfg_h.value = 0;
171811304SJanie.Lu@Sun.COM rx_cfg_l.value = 0;
171911304SJanie.Lu@Sun.COM rx_cfg_h.value = 0;
172011304SJanie.Lu@Sun.COM pll_cfg_l.value = 0;
172111304SJanie.Lu@Sun.COM test_cfg.value = 0;
172211304SJanie.Lu@Sun.COM
172311304SJanie.Lu@Sun.COM /*
172411304SJanie.Lu@Sun.COM * The following setting assumes the reference clock frquency
172511304SJanie.Lu@Sun.COM * is 156.25 MHz.
172611304SJanie.Lu@Sun.COM */
172711304SJanie.Lu@Sun.COM /*
172811304SJanie.Lu@Sun.COM * If the nxge driver has been plumbed without a link, then it will
172911304SJanie.Lu@Sun.COM * detect a link up when a cable connecting to an anto-negotiation
173011304SJanie.Lu@Sun.COM * partner is plugged into the port. Because the TN1010 PHY supports
173111304SJanie.Lu@Sun.COM * both 1G and 10G speeds, the driver must re-configure the
173211304SJanie.Lu@Sun.COM * Neptune/NIU according to the negotiated speed. nxge_n2_serdes_init
173311304SJanie.Lu@Sun.COM * is called at the post-link-up reconfiguration time. Here it calls
173411304SJanie.Lu@Sun.COM * nxge_set_tn1010_param to set portmode before re-initializing
173511304SJanie.Lu@Sun.COM * the serdes.
173611304SJanie.Lu@Sun.COM */
173711304SJanie.Lu@Sun.COM if (nxgep->mac.portmode == PORT_1G_TN1010 ||
173811304SJanie.Lu@Sun.COM nxgep->mac.portmode == PORT_10G_TN1010) {
173911304SJanie.Lu@Sun.COM if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
174011304SJanie.Lu@Sun.COM goto fail;
174111304SJanie.Lu@Sun.COM }
174211304SJanie.Lu@Sun.COM }
174311304SJanie.Lu@Sun.COM if (nxgep->mac.portmode == PORT_10G_FIBER ||
174412103SSantwona.Behera@Sun.COM nxgep->mac.portmode == PORT_10G_COPPER ||
174511304SJanie.Lu@Sun.COM nxgep->mac.portmode == PORT_10G_TN1010 ||
174611304SJanie.Lu@Sun.COM nxgep->mac.portmode == PORT_10G_SERDES) {
1747*12452SSantwona.Behera@oracle.COM
1748*12452SSantwona.Behera@oracle.COM /* Take tunables from OBP if present, otherwise use defaults */
1749*12452SSantwona.Behera@oracle.COM if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGL) {
1750*12452SSantwona.Behera@oracle.COM tx_cfg_l.value = nxgep->srds_prop.tx_cfg_l;
1751*12452SSantwona.Behera@oracle.COM } else {
1752*12452SSantwona.Behera@oracle.COM tx_cfg_l.bits.entx = K_CFGTX_ENABLE_TX;
1753*12452SSantwona.Behera@oracle.COM /* 0x1e21 */
1754*12452SSantwona.Behera@oracle.COM tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
1755*12452SSantwona.Behera@oracle.COM tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
1756*12452SSantwona.Behera@oracle.COM }
175711304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
175811304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
175911304SJanie.Lu@Sun.COM portn, tx_cfg_l.value));
176011304SJanie.Lu@Sun.COM
1761*12452SSantwona.Behera@oracle.COM if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGH) {
1762*12452SSantwona.Behera@oracle.COM tx_cfg_h.value = nxgep->srds_prop.tx_cfg_h;
1763*12452SSantwona.Behera@oracle.COM } else {
1764*12452SSantwona.Behera@oracle.COM /* channel 0: enable syn. master */
1765*12452SSantwona.Behera@oracle.COM /* 0x40 */
1766*12452SSantwona.Behera@oracle.COM tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
1767*12452SSantwona.Behera@oracle.COM }
176811304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
176911304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
177011304SJanie.Lu@Sun.COM portn, tx_cfg_h.value));
1771*12452SSantwona.Behera@oracle.COM
1772*12452SSantwona.Behera@oracle.COM if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGL) {
1773*12452SSantwona.Behera@oracle.COM rx_cfg_l.value = nxgep->srds_prop.rx_cfg_l;
1774*12452SSantwona.Behera@oracle.COM } else {
1775*12452SSantwona.Behera@oracle.COM /* 0x4821 */
1776*12452SSantwona.Behera@oracle.COM rx_cfg_l.bits.enrx = K_CFGRX_ENABLE_RX;
1777*12452SSantwona.Behera@oracle.COM rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
1778*12452SSantwona.Behera@oracle.COM rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
1779*12452SSantwona.Behera@oracle.COM rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
1780*12452SSantwona.Behera@oracle.COM }
178111304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
178211304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
178311304SJanie.Lu@Sun.COM portn, rx_cfg_l.value));
178411304SJanie.Lu@Sun.COM
1785*12452SSantwona.Behera@oracle.COM if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGH) {
1786*12452SSantwona.Behera@oracle.COM rx_cfg_h.value = nxgep->srds_prop.rx_cfg_h;
1787*12452SSantwona.Behera@oracle.COM } else {
1788*12452SSantwona.Behera@oracle.COM /* 0x0008 */
1789*12452SSantwona.Behera@oracle.COM rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE;
1790*12452SSantwona.Behera@oracle.COM }
179111304SJanie.Lu@Sun.COM
179211304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
179311304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_h 0x%x",
179411304SJanie.Lu@Sun.COM portn, rx_cfg_h.value));
179511304SJanie.Lu@Sun.COM
1796*12452SSantwona.Behera@oracle.COM if (nxgep->srds_prop.prop_set & NXGE_SRDS_PLLCFGL) {
1797*12452SSantwona.Behera@oracle.COM pll_cfg_l.value = nxgep->srds_prop.pll_cfg_l;
1798*12452SSantwona.Behera@oracle.COM } else {
1799*12452SSantwona.Behera@oracle.COM /* 0xa1: Initialize PLL for 10G */
1800*12452SSantwona.Behera@oracle.COM pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
1801*12452SSantwona.Behera@oracle.COM pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
1802*12452SSantwona.Behera@oracle.COM }
1803*12452SSantwona.Behera@oracle.COM
1804*12452SSantwona.Behera@oracle.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1805*12452SSantwona.Behera@oracle.COM "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
1806*12452SSantwona.Behera@oracle.COM portn, pll_cfg_l.value));
1807*12452SSantwona.Behera@oracle.COM
1808*12452SSantwona.Behera@oracle.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1809*12452SSantwona.Behera@oracle.COM ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
1810*12452SSantwona.Behera@oracle.COM goto fail;
1811*12452SSantwona.Behera@oracle.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1812*12452SSantwona.Behera@oracle.COM "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
1813*12452SSantwona.Behera@oracle.COM portn, pll_cfg_l.value));
1814*12452SSantwona.Behera@oracle.COM
181511304SJanie.Lu@Sun.COM /* Set loopback mode if necessary */
181611304SJanie.Lu@Sun.COM if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
181711304SJanie.Lu@Sun.COM tx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
181811304SJanie.Lu@Sun.COM rx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
181911304SJanie.Lu@Sun.COM rx_cfg_l.bits.los = 0;
182011304SJanie.Lu@Sun.COM
182111304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
182211304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
182311304SJanie.Lu@Sun.COM "loopback 0x%x", portn, tx_cfg_h.value));
182411304SJanie.Lu@Sun.COM }
182511304SJanie.Lu@Sun.COM #ifdef NXGE_DEBUG
182611304SJanie.Lu@Sun.COM nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
182711304SJanie.Lu@Sun.COM ESR_N2_PLL_CFG_L_REG, &cfg.value);
182811304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
182911304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
183011304SJanie.Lu@Sun.COM "PLL cfg.l 0x%x (0x%x)",
183111304SJanie.Lu@Sun.COM portn, pll_cfg_l.value, cfg.value));
183211304SJanie.Lu@Sun.COM
183311304SJanie.Lu@Sun.COM nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
183411304SJanie.Lu@Sun.COM ESR_N2_PLL_STS_L_REG, &cfg.value);
183511304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
183611304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
183711304SJanie.Lu@Sun.COM portn, cfg.value));
183811304SJanie.Lu@Sun.COM #endif
183911304SJanie.Lu@Sun.COM } else if (nxgep->mac.portmode == PORT_1G_FIBER ||
184011304SJanie.Lu@Sun.COM nxgep->mac.portmode == PORT_1G_TN1010 ||
184111304SJanie.Lu@Sun.COM nxgep->mac.portmode == PORT_1G_SERDES) {
184211304SJanie.Lu@Sun.COM mode_1g = B_TRUE;
184311304SJanie.Lu@Sun.COM /* 0x1e41 */
184411304SJanie.Lu@Sun.COM tx_cfg_l.bits.entx = 1;
184511304SJanie.Lu@Sun.COM tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
184611304SJanie.Lu@Sun.COM tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
184711304SJanie.Lu@Sun.COM
184811304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
184911304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
185011304SJanie.Lu@Sun.COM portn, tx_cfg_l.value));
185111304SJanie.Lu@Sun.COM
185211304SJanie.Lu@Sun.COM
185311304SJanie.Lu@Sun.COM /* channel 0: enable syn. master */
185411304SJanie.Lu@Sun.COM tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
185511304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
185611304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
185711304SJanie.Lu@Sun.COM portn, tx_cfg_h.value));
185811304SJanie.Lu@Sun.COM
185911304SJanie.Lu@Sun.COM
186011304SJanie.Lu@Sun.COM /* 0x4841 */
186111304SJanie.Lu@Sun.COM rx_cfg_l.bits.enrx = 1;
186211304SJanie.Lu@Sun.COM rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
186311304SJanie.Lu@Sun.COM rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
186411304SJanie.Lu@Sun.COM rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
186511304SJanie.Lu@Sun.COM
186611304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
186711304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
186811304SJanie.Lu@Sun.COM portn, rx_cfg_l.value));
186911304SJanie.Lu@Sun.COM
187011304SJanie.Lu@Sun.COM /* 0x0008 */
187111304SJanie.Lu@Sun.COM rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE_LF_365MHZ_ZF;
187211304SJanie.Lu@Sun.COM
187311304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
187411304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
187511304SJanie.Lu@Sun.COM portn, rx_cfg_h.value));
187611304SJanie.Lu@Sun.COM
187711304SJanie.Lu@Sun.COM /* 0xa1: Initialize PLL for 1G */
187811304SJanie.Lu@Sun.COM pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
187911304SJanie.Lu@Sun.COM pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
188011304SJanie.Lu@Sun.COM
188111304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
188211304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
188311304SJanie.Lu@Sun.COM portn, pll_cfg_l.value));
188411304SJanie.Lu@Sun.COM
188511304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
188611304SJanie.Lu@Sun.COM ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
188711304SJanie.Lu@Sun.COM != NXGE_OK)
188811304SJanie.Lu@Sun.COM goto fail;
188911304SJanie.Lu@Sun.COM
189011304SJanie.Lu@Sun.COM
189111304SJanie.Lu@Sun.COM #ifdef NXGE_DEBUG
189211304SJanie.Lu@Sun.COM nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
189311304SJanie.Lu@Sun.COM ESR_N2_PLL_CFG_L_REG, &cfg.value);
189411304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
189511304SJanie.Lu@Sun.COM "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
189611304SJanie.Lu@Sun.COM portn, pll_cfg_l.value, cfg.value));
189711304SJanie.Lu@Sun.COM
189811304SJanie.Lu@Sun.COM nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
189911304SJanie.Lu@Sun.COM ESR_N2_PLL_STS_L_REG, &cfg.value);
190011304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
190111304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
190211304SJanie.Lu@Sun.COM portn, cfg.value));
190311304SJanie.Lu@Sun.COM #endif
190411304SJanie.Lu@Sun.COM
190511304SJanie.Lu@Sun.COM /* Set loopback mode if necessary */
190611304SJanie.Lu@Sun.COM if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
190711304SJanie.Lu@Sun.COM tx_cfg_h.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
190811304SJanie.Lu@Sun.COM
190911304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
191011304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
191111304SJanie.Lu@Sun.COM "loopback 0x%x", portn, test_cfg.value));
191211304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn,
191311304SJanie.Lu@Sun.COM ESR_N2_DEV_ADDR,
191411304SJanie.Lu@Sun.COM ESR_N2_TX_CFG_L_REG_ADDR(0),
191511304SJanie.Lu@Sun.COM tx_cfg_h.value)) != NXGE_OK) {
191611304SJanie.Lu@Sun.COM goto fail;
191711304SJanie.Lu@Sun.COM }
191811304SJanie.Lu@Sun.COM }
191911304SJanie.Lu@Sun.COM } else {
192011304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
192111304SJanie.Lu@Sun.COM "nxge_n2_kt_serdes_init:port<%d> - "
192211304SJanie.Lu@Sun.COM "unsupported port mode %d",
192311304SJanie.Lu@Sun.COM portn, nxgep->mac.portmode));
192411304SJanie.Lu@Sun.COM goto fail;
192511304SJanie.Lu@Sun.COM }
192611304SJanie.Lu@Sun.COM
192711304SJanie.Lu@Sun.COM NXGE_DELAY(20);
192811304SJanie.Lu@Sun.COM /* Clear the test register (offset 0x8004) */
192911304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
193011304SJanie.Lu@Sun.COM ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
193111304SJanie.Lu@Sun.COM goto fail;
193211304SJanie.Lu@Sun.COM }
193311304SJanie.Lu@Sun.COM NXGE_DELAY(20);
193411304SJanie.Lu@Sun.COM
193511304SJanie.Lu@Sun.COM /* init TX channels */
193611304SJanie.Lu@Sun.COM for (chan = 0; chan < 4; chan++) {
193711304SJanie.Lu@Sun.COM if (mode_1g)
193811304SJanie.Lu@Sun.COM tx_cfg_l.value = 0;
193911304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
194011304SJanie.Lu@Sun.COM ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
194111304SJanie.Lu@Sun.COM goto fail;
194211304SJanie.Lu@Sun.COM
194311304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
194411304SJanie.Lu@Sun.COM ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
194511304SJanie.Lu@Sun.COM goto fail;
194611304SJanie.Lu@Sun.COM
194711304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
194811304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
194911304SJanie.Lu@Sun.COM "chan %d tx_cfg_l 0x%x", portn, chan, tx_cfg_l.value));
195011304SJanie.Lu@Sun.COM
195111304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
195211304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
195311304SJanie.Lu@Sun.COM "chan %d tx_cfg_h 0x%x", portn, chan, tx_cfg_h.value));
195411304SJanie.Lu@Sun.COM }
195511304SJanie.Lu@Sun.COM
195611304SJanie.Lu@Sun.COM /* init RX channels */
195711304SJanie.Lu@Sun.COM /* 1G mode only write to the first channel */
195811304SJanie.Lu@Sun.COM for (chan = 0; chan < 4; chan++) {
195911304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
196011304SJanie.Lu@Sun.COM ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
196111304SJanie.Lu@Sun.COM != NXGE_OK)
196211304SJanie.Lu@Sun.COM goto fail;
196311304SJanie.Lu@Sun.COM
196411304SJanie.Lu@Sun.COM if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
196511304SJanie.Lu@Sun.COM ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
196611304SJanie.Lu@Sun.COM != NXGE_OK)
196711304SJanie.Lu@Sun.COM goto fail;
196811304SJanie.Lu@Sun.COM
196911304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
197011304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
197111304SJanie.Lu@Sun.COM "chan %d rx_cfg_l 0x%x", portn, chan, rx_cfg_l.value));
197211304SJanie.Lu@Sun.COM
197311304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
197411304SJanie.Lu@Sun.COM "==> nxge_n2_kt_serdes_init port<%d>: "
197511304SJanie.Lu@Sun.COM "chan %d rx_cfg_h 0x%x", portn, chan, rx_cfg_h.value));
197611304SJanie.Lu@Sun.COM }
197711304SJanie.Lu@Sun.COM
197812103SSantwona.Behera@Sun.COM if (portn == 0) {
197912103SSantwona.Behera@Sun.COM /* Wait for serdes to be ready */
198012103SSantwona.Behera@Sun.COM for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
198112103SSantwona.Behera@Sun.COM ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
198212103SSantwona.Behera@Sun.COM if ((val & ESR_SIG_P0_BITS_MASK) !=
198312103SSantwona.Behera@Sun.COM (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
198412103SSantwona.Behera@Sun.COM ESR_SIG_XSERDES_RDY_P0 |
198512103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P0_CH3 |
198612103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P0_CH2 |
198712103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P0_CH1 |
198812103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P0_CH0))
198912103SSantwona.Behera@Sun.COM
199012103SSantwona.Behera@Sun.COM NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
199112103SSantwona.Behera@Sun.COM else
199212103SSantwona.Behera@Sun.COM break;
199312103SSantwona.Behera@Sun.COM }
199412103SSantwona.Behera@Sun.COM
199512103SSantwona.Behera@Sun.COM if (i == MAX_SERDES_RDY_RETRIES) {
199612103SSantwona.Behera@Sun.COM /*
199712103SSantwona.Behera@Sun.COM * RDY signal stays low may due to the absent of the
199812103SSantwona.Behera@Sun.COM * external PHY, it is not an error condition.
199912103SSantwona.Behera@Sun.COM * But still print the message for the debugging
200012103SSantwona.Behera@Sun.COM * purpose when link stays down
200112103SSantwona.Behera@Sun.COM */
200212103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
200312103SSantwona.Behera@Sun.COM "nxge_n2_kt_serdes_init: "
200412103SSantwona.Behera@Sun.COM "Serdes/signal for port<%d> not ready", portn));
200512103SSantwona.Behera@Sun.COM goto done;
200612103SSantwona.Behera@Sun.COM }
200712103SSantwona.Behera@Sun.COM } else if (portn == 1) {
200812103SSantwona.Behera@Sun.COM /* Wait for serdes to be ready */
200912103SSantwona.Behera@Sun.COM for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
201012103SSantwona.Behera@Sun.COM ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
201112103SSantwona.Behera@Sun.COM if ((val & ESR_SIG_P1_BITS_MASK) !=
201212103SSantwona.Behera@Sun.COM (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
201312103SSantwona.Behera@Sun.COM ESR_SIG_XSERDES_RDY_P1 |
201412103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P1_CH3 |
201512103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P1_CH2 |
201612103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P1_CH1 |
201712103SSantwona.Behera@Sun.COM ESR_SIG_XDETECT_P1_CH0))
201812103SSantwona.Behera@Sun.COM
201912103SSantwona.Behera@Sun.COM NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
202012103SSantwona.Behera@Sun.COM else
202112103SSantwona.Behera@Sun.COM break;
202212103SSantwona.Behera@Sun.COM }
202312103SSantwona.Behera@Sun.COM
202412103SSantwona.Behera@Sun.COM if (i == MAX_SERDES_RDY_RETRIES) {
202512103SSantwona.Behera@Sun.COM /*
202612103SSantwona.Behera@Sun.COM * RDY signal stays low may due to the absent of the
202712103SSantwona.Behera@Sun.COM * external PHY, it is not an error condition.
202812103SSantwona.Behera@Sun.COM * But still print the message for the debugging
202912103SSantwona.Behera@Sun.COM * purpose when link stays down
203012103SSantwona.Behera@Sun.COM */
203112103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
203212103SSantwona.Behera@Sun.COM "nxge_n2_kt_serdes_init: "
203312103SSantwona.Behera@Sun.COM "Serdes/signal for port<%d> not ready", portn));
203412103SSantwona.Behera@Sun.COM goto done;
203512103SSantwona.Behera@Sun.COM }
203612103SSantwona.Behera@Sun.COM }
203712103SSantwona.Behera@Sun.COM done:
203812103SSantwona.Behera@Sun.COM
203911304SJanie.Lu@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
204011304SJanie.Lu@Sun.COM "<== nxge_n2_kt_serdes_init port<%d>", portn));
204111304SJanie.Lu@Sun.COM
204211304SJanie.Lu@Sun.COM return (NXGE_OK);
204311304SJanie.Lu@Sun.COM fail:
204411304SJanie.Lu@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
204511304SJanie.Lu@Sun.COM "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
204611304SJanie.Lu@Sun.COM portn));
204711304SJanie.Lu@Sun.COM
204811304SJanie.Lu@Sun.COM return (status);
20493859Sml29623 }
20503859Sml29623
20514732Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
20524732Sdavemq
20534732Sdavemq static nxge_status_t
nxge_neptune_10G_serdes_init(p_nxge_t nxgep)20544732Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
20553859Sml29623 {
20563859Sml29623 npi_handle_t handle;
20573859Sml29623 uint8_t portn;
20586075Ssbehera int chan, i;
20593859Sml29623 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l;
20603859Sml29623 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h;
20613859Sml29623 sr_glue_ctrl0_l_t glue_ctrl0_l;
20623859Sml29623 sr_glue_ctrl0_h_t glue_ctrl0_h;
20633859Sml29623 uint64_t val;
20643859Sml29623 uint16_t val16l;
20653859Sml29623 uint16_t val16h;
20663859Sml29623 nxge_status_t status = NXGE_OK;
20673859Sml29623
20683859Sml29623 portn = nxgep->mac.portnum;
20693859Sml29623
20703859Sml29623 if ((portn != 0) && (portn != 1))
20713859Sml29623 return (NXGE_OK);
20723859Sml29623
20734732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
20744732Sdavemq "==> nxge_neptune_10G_serdes_init port<%d>", portn));
20753859Sml29623 handle = nxgep->npi_handle;
20764732Sdavemq switch (portn) {
20774732Sdavemq case 0:
20786028Ssbehera /* Reset Serdes */
20796028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0);
20806028Ssbehera NXGE_DELAY(20);
20816028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
20826028Ssbehera NXGE_DELAY(2000);
20836028Ssbehera
20846028Ssbehera /* Configure Serdes to 10G mode */
20856028Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
20866028Ssbehera ESR_PLL_CFG_10G_SERDES);
20876028Ssbehera
20884732Sdavemq ESR_REG_WR(handle, ESR_0_CONTROL_REG,
20894732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
20904732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
20914732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
20924732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
20934732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
20944732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
20954732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
20964732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
20974732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
20984732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
20994732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
21004732Sdavemq
21014732Sdavemq /* Set Serdes0 Internal Loopback if necessary */
21024732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
21034732Sdavemq ESR_REG_WR(handle,
21044732Sdavemq ESR_0_TEST_CONFIG_REG,
21054732Sdavemq ESR_PAD_LOOPBACK_CH3 |
21064732Sdavemq ESR_PAD_LOOPBACK_CH2 |
21074732Sdavemq ESR_PAD_LOOPBACK_CH1 |
21084732Sdavemq ESR_PAD_LOOPBACK_CH0);
21094732Sdavemq } else {
21104732Sdavemq ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
21113859Sml29623 }
21124732Sdavemq break;
21134732Sdavemq case 1:
21146028Ssbehera /* Reset Serdes */
21156028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1);
21166028Ssbehera NXGE_DELAY(20);
21176028Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
21186028Ssbehera NXGE_DELAY(2000);
21196028Ssbehera
21206028Ssbehera /* Configure Serdes to 10G mode */
21216028Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
21226028Ssbehera ESR_PLL_CFG_10G_SERDES);
21236028Ssbehera
21244732Sdavemq ESR_REG_WR(handle, ESR_1_CONTROL_REG,
21254732Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
21264732Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
21274732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
21284732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
21294732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
21304732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
21314732Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
21324732Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
21334732Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
21344732Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
21354732Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
21364732Sdavemq
21374732Sdavemq /* Set Serdes1 Internal Loopback if necessary */
21384732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
21394732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
21404732Sdavemq ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
21414732Sdavemq ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
21424732Sdavemq } else {
21434732Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
21443859Sml29623 }
21454732Sdavemq break;
21464732Sdavemq default:
21474732Sdavemq /* Nothing to do here */
21484732Sdavemq goto done;
21494732Sdavemq }
21504732Sdavemq
21514732Sdavemq /* init TX RX channels */
21524732Sdavemq for (chan = 0; chan < 4; chan++) {
21534732Sdavemq if ((status = nxge_mdio_read(nxgep, portn,
21544732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
21554732Sdavemq &rx_tx_ctrl_l.value)) != NXGE_OK)
21563859Sml29623 goto fail;
21574732Sdavemq if ((status = nxge_mdio_read(nxgep, portn,
21584732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
21594732Sdavemq &rx_tx_ctrl_h.value)) != NXGE_OK)
21603859Sml29623 goto fail;
21613859Sml29623 if ((status = nxge_mdio_read(nxgep, portn,
21624732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
21634732Sdavemq &glue_ctrl0_l.value)) != NXGE_OK)
21643859Sml29623 goto fail;
21653859Sml29623 if ((status = nxge_mdio_read(nxgep, portn,
21664732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
21674732Sdavemq &glue_ctrl0_h.value)) != NXGE_OK)
21684732Sdavemq goto fail;
21694732Sdavemq rx_tx_ctrl_l.bits.enstretch = 1;
21704732Sdavemq rx_tx_ctrl_h.bits.vmuxlo = 2;
21714732Sdavemq rx_tx_ctrl_h.bits.vpulselo = 2;
21724732Sdavemq glue_ctrl0_l.bits.rxlosenable = 1;
21734732Sdavemq glue_ctrl0_l.bits.samplerate = 0xF;
21744732Sdavemq glue_ctrl0_l.bits.thresholdcount = 0xFF;
21754732Sdavemq glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
21764732Sdavemq if ((status = nxge_mdio_write(nxgep, portn,
21774732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
21784732Sdavemq rx_tx_ctrl_l.value)) != NXGE_OK)
21794732Sdavemq goto fail;
21804732Sdavemq if ((status = nxge_mdio_write(nxgep, portn,
21814732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
21824732Sdavemq rx_tx_ctrl_h.value)) != NXGE_OK)
21834732Sdavemq goto fail;
21844732Sdavemq if ((status = nxge_mdio_write(nxgep, portn,
21854732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
21864732Sdavemq glue_ctrl0_l.value)) != NXGE_OK)
21874732Sdavemq goto fail;
21884732Sdavemq if ((status = nxge_mdio_write(nxgep, portn,
21894732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
21904732Sdavemq glue_ctrl0_h.value)) != NXGE_OK)
21913859Sml29623 goto fail;
21923859Sml29623 }
21933859Sml29623
21944732Sdavemq /* Apply Tx core reset */
21954732Sdavemq if ((status = nxge_mdio_write(nxgep, portn,
21964732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
21974732Sdavemq (uint16_t)0)) != NXGE_OK)
21984732Sdavemq goto fail;
21994732Sdavemq
22004732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22014732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
22024732Sdavemq NXGE_OK)
22034732Sdavemq goto fail;
22044732Sdavemq
22054732Sdavemq NXGE_DELAY(200);
22064732Sdavemq
22074732Sdavemq /* Apply Rx core reset */
22084732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22094732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
22104732Sdavemq NXGE_OK)
22114732Sdavemq goto fail;
22124732Sdavemq
22134732Sdavemq NXGE_DELAY(200);
22144732Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22154732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
22164732Sdavemq goto fail;
22174732Sdavemq
22184732Sdavemq NXGE_DELAY(200);
22194732Sdavemq if ((status = nxge_mdio_read(nxgep, portn,
22204732Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
22214732Sdavemq &val16l)) != NXGE_OK)
22224732Sdavemq goto fail;
22234732Sdavemq if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
22244732Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
22254732Sdavemq goto fail;
22264732Sdavemq if ((val16l != 0) || (val16h != 0)) {
22274732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
22285196Ssbehera "Failed to reset port<%d> XAUI Serdes "
22295196Ssbehera "(val16l 0x%x val16h 0x%x)",
22305196Ssbehera portn, val16l, val16h));
22314732Sdavemq }
22324732Sdavemq
22334732Sdavemq if (portn == 0) {
22346075Ssbehera /* Wait for serdes to be ready */
22356075Ssbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
22366075Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
22376075Ssbehera if ((val & ESR_SIG_P0_BITS_MASK) !=
22386075Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
22396075Ssbehera ESR_SIG_XSERDES_RDY_P0 |
22406075Ssbehera ESR_SIG_XDETECT_P0_CH3 |
22416075Ssbehera ESR_SIG_XDETECT_P0_CH2 |
22426075Ssbehera ESR_SIG_XDETECT_P0_CH1 |
22436075Ssbehera ESR_SIG_XDETECT_P0_CH0))
22446075Ssbehera
22456075Ssbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
22466075Ssbehera else
22476075Ssbehera break;
22486075Ssbehera }
22496075Ssbehera
22506075Ssbehera if (i == MAX_SERDES_RDY_RETRIES) {
22516650Sjoycey /*
22526650Sjoycey * RDY signal stays low may due to the absent of the
22536650Sjoycey * external PHY, it is not an error condition. But still
22546650Sjoycey * print the message for the debugging purpose when link
22556650Sjoycey * stays down
22566650Sjoycey */
225711409Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL,
22586075Ssbehera "nxge_neptune_10G_serdes_init: "
22596075Ssbehera "Serdes/signal for port<%d> not ready", portn));
22606835Syc148097 goto done;
22614732Sdavemq }
22624732Sdavemq } else if (portn == 1) {
22636075Ssbehera /* Wait for serdes to be ready */
22646075Ssbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
22656075Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
22666075Ssbehera if ((val & ESR_SIG_P1_BITS_MASK) !=
22676075Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
22686075Ssbehera ESR_SIG_XSERDES_RDY_P1 |
22696075Ssbehera ESR_SIG_XDETECT_P1_CH3 |
22706075Ssbehera ESR_SIG_XDETECT_P1_CH2 |
22716075Ssbehera ESR_SIG_XDETECT_P1_CH1 |
22726075Ssbehera ESR_SIG_XDETECT_P1_CH0))
22736075Ssbehera
22746075Ssbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
22756075Ssbehera else
22766075Ssbehera break;
22776075Ssbehera }
22786075Ssbehera
22796075Ssbehera if (i == MAX_SERDES_RDY_RETRIES) {
22806650Sjoycey /*
22816650Sjoycey * RDY signal stays low may due to the absent of the
22826650Sjoycey * external PHY, it is not an error condition. But still
22836650Sjoycey * print the message for the debugging purpose when link
22846650Sjoycey * stays down
22856650Sjoycey */
228611409Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL,
22876075Ssbehera "nxge_neptune_10G_serdes_init: "
22886075Ssbehera "Serdes/signal for port<%d> not ready", portn));
22896835Syc148097 goto done;
22903859Sml29623 }
22913859Sml29623 }
22923859Sml29623
22933859Sml29623 done:
22944732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
22954732Sdavemq "<== nxge_neptune_10G_serdes_init port<%d>", portn));
22964732Sdavemq
22973859Sml29623 return (NXGE_OK);
22983859Sml29623 fail:
22995572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
23004732Sdavemq "nxge_neptune_10G_serdes_init: "
23014732Sdavemq "Failed to initialize Neptune serdes for port<%d>", portn));
23023859Sml29623
23033859Sml29623 return (status);
23043859Sml29623 }
23053859Sml29623
23064732Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
23074732Sdavemq
23084732Sdavemq static nxge_status_t
nxge_1G_serdes_init(p_nxge_t nxgep)23094732Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep)
23103859Sml29623 {
23114732Sdavemq npi_handle_t handle;
23124732Sdavemq uint8_t portn;
23135196Ssbehera int chan;
23145196Ssbehera sr_rx_tx_ctrl_l_t rx_tx_ctrl_l;
23155196Ssbehera sr_rx_tx_ctrl_h_t rx_tx_ctrl_h;
23165196Ssbehera sr_glue_ctrl0_l_t glue_ctrl0_l;
23175196Ssbehera sr_glue_ctrl0_h_t glue_ctrl0_h;
23184732Sdavemq uint64_t val;
23195196Ssbehera uint16_t val16l;
23205196Ssbehera uint16_t val16h;
23215196Ssbehera nxge_status_t status = NXGE_OK;
23223859Sml29623
23233859Sml29623 portn = nxgep->mac.portnum;
23244732Sdavemq
23254732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
23264732Sdavemq "==> nxge_1G_serdes_init port<%d>", portn));
23274732Sdavemq
23284732Sdavemq handle = nxgep->npi_handle;
23294732Sdavemq
23304732Sdavemq switch (portn) {
23314732Sdavemq case 0:
23325196Ssbehera /* Assert the reset register */
23335196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val);
23345196Ssbehera val |= ESR_RESET_0;
23355196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val);
23365196Ssbehera
23375196Ssbehera /* Set the PLL register to 0x79 */
23385196Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
23395196Ssbehera ESR_PLL_CFG_1G_SERDES);
23405196Ssbehera
23415196Ssbehera /* Set the control register to 0x249249f */
23425196Ssbehera ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES);
23435196Ssbehera
23445196Ssbehera /* Set Serdes0 Internal Loopback if necessary */
23455196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
23465196Ssbehera /* Set pad loopback modes 0xaa */
23475196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG,
23485196Ssbehera ESR_TSTCFG_LBTEST_PAD);
23495196Ssbehera } else {
23505196Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
23515196Ssbehera }
23525196Ssbehera
23535196Ssbehera /* Deassert the reset register */
23545196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val);
23555196Ssbehera val &= ~ESR_RESET_0;
23565196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val);
23574732Sdavemq break;
23585196Ssbehera
23594732Sdavemq case 1:
23605196Ssbehera /* Assert the reset register */
23615196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val);
23625196Ssbehera val |= ESR_RESET_1;
23635196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val);
23645196Ssbehera
23655196Ssbehera /* Set PLL register to 0x79 */
23665196Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
23675196Ssbehera ESR_PLL_CFG_1G_SERDES);
23685196Ssbehera
23695196Ssbehera /* Set the control register to 0x249249f */
23705196Ssbehera ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES);
23715196Ssbehera
23725196Ssbehera /* Set Serdes1 Internal Loopback if necessary */
23735196Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
23745196Ssbehera /* Set pad loopback mode 0xaa */
23755196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
23765196Ssbehera ESR_TSTCFG_LBTEST_PAD);
23775196Ssbehera } else {
23785196Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
23795196Ssbehera }
23805196Ssbehera
23815196Ssbehera /* Deassert the reset register */
23825196Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val);
23835196Ssbehera val &= ~ESR_RESET_1;
23845196Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val);
23854732Sdavemq break;
23865196Ssbehera
23874732Sdavemq default:
23885196Ssbehera /* Nothing to do here */
23895196Ssbehera goto done;
23905196Ssbehera }
23915196Ssbehera
23925196Ssbehera /* init TX RX channels */
23935196Ssbehera for (chan = 0; chan < 4; chan++) {
23945196Ssbehera if ((status = nxge_mdio_read(nxgep, portn,
23955196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
23965196Ssbehera &rx_tx_ctrl_l.value)) != NXGE_OK) {
23975196Ssbehera goto fail;
23985196Ssbehera }
23995196Ssbehera if ((status = nxge_mdio_read(nxgep, portn,
24005196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
24015196Ssbehera &rx_tx_ctrl_h.value)) != NXGE_OK) {
24025196Ssbehera goto fail;
24035196Ssbehera }
24045196Ssbehera if ((status = nxge_mdio_read(nxgep, portn,
24055196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
24065196Ssbehera &glue_ctrl0_l.value)) != NXGE_OK) {
24075196Ssbehera goto fail;
24085196Ssbehera }
24095196Ssbehera if ((status = nxge_mdio_read(nxgep, portn,
24105196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
24115196Ssbehera &glue_ctrl0_h.value)) != NXGE_OK) {
24125196Ssbehera goto fail;
24135196Ssbehera }
24145196Ssbehera
24155196Ssbehera rx_tx_ctrl_l.bits.enstretch = 1;
24165196Ssbehera rx_tx_ctrl_h.bits.vmuxlo = 2;
24175196Ssbehera rx_tx_ctrl_h.bits.vpulselo = 2;
24185196Ssbehera glue_ctrl0_l.bits.rxlosenable = 1;
24195196Ssbehera glue_ctrl0_l.bits.samplerate = 0xF;
24205196Ssbehera glue_ctrl0_l.bits.thresholdcount = 0xFF;
24215196Ssbehera glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
24225196Ssbehera if ((status = nxge_mdio_write(nxgep, portn,
24235196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
24245196Ssbehera rx_tx_ctrl_l.value)) != NXGE_OK) {
24255196Ssbehera goto fail;
24265196Ssbehera }
24275196Ssbehera if ((status = nxge_mdio_write(nxgep, portn,
24285196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
24295196Ssbehera rx_tx_ctrl_h.value)) != NXGE_OK) {
24305196Ssbehera goto fail;
24315196Ssbehera }
24325196Ssbehera if ((status = nxge_mdio_write(nxgep, portn,
24335196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
24345196Ssbehera glue_ctrl0_l.value)) != NXGE_OK) {
24355196Ssbehera goto fail;
24365196Ssbehera }
24375196Ssbehera if ((status = nxge_mdio_write(nxgep, portn,
24385196Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
24395196Ssbehera glue_ctrl0_h.value)) != NXGE_OK) {
24405196Ssbehera goto fail;
24415196Ssbehera }
24425196Ssbehera }
24435196Ssbehera
24445196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24455196Ssbehera ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) {
24464732Sdavemq goto fail;
24473859Sml29623 }
24485196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24495196Ssbehera ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
24505196Ssbehera goto fail;
24515196Ssbehera }
24525196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24535196Ssbehera ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) {
24545196Ssbehera goto fail;
24555196Ssbehera }
24565196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24575196Ssbehera ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
24585196Ssbehera goto fail;
24595196Ssbehera }
24605196Ssbehera
24615196Ssbehera /* Apply Tx core reset */
24625196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24635196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) {
24645196Ssbehera goto fail;
24655196Ssbehera }
24665196Ssbehera
24675196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24685196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
24695196Ssbehera NXGE_OK) {
24705196Ssbehera goto fail;
24715196Ssbehera }
24725196Ssbehera
24735196Ssbehera NXGE_DELAY(200);
24745196Ssbehera
24755196Ssbehera /* Apply Rx core reset */
24765196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24775196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
24785196Ssbehera NXGE_OK) {
24795196Ssbehera goto fail;
24805196Ssbehera }
24815196Ssbehera
24825196Ssbehera NXGE_DELAY(200);
24835196Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24845196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) {
24855196Ssbehera goto fail;
24865196Ssbehera }
24875196Ssbehera
24885196Ssbehera NXGE_DELAY(200);
24895196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24905196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) {
24915196Ssbehera goto fail;
24925196Ssbehera }
24935196Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
24945196Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) {
24955196Ssbehera goto fail;
24965196Ssbehera }
24975196Ssbehera if ((val16l != 0) || (val16h != 0)) {
24985196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
24995196Ssbehera "Failed to reset port<%d> XAUI Serdes "
25005196Ssbehera "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h));
25015196Ssbehera status = NXGE_ERROR;
25025196Ssbehera goto fail;
25035196Ssbehera }
25045196Ssbehera
25055196Ssbehera NXGE_DELAY(200);
25065196Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
25075196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
25085196Ssbehera "nxge_neptune_serdes_init: read internal signal reg port<%d> "
25095196Ssbehera "val 0x%x", portn, val));
25105196Ssbehera if (portn == 0) {
25115196Ssbehera if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
25125196Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) {
25136650Sjoycey /*
25146650Sjoycey * RDY signal stays low may due to the absent of the
25156650Sjoycey * external PHY, it is not an error condition. But still
25166650Sjoycey * print the message for the debugging purpose when link
25176650Sjoycey * stays down
25186650Sjoycey */
25195196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25206650Sjoycey "nxge_neptune_1G_serdes_init: "
25216650Sjoycey "Serdes/signal for port<%d> not ready", portn));
25226835Syc148097 goto done;
25235196Ssbehera }
25245196Ssbehera } else if (portn == 1) {
25255196Ssbehera if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
25265196Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) {
25276650Sjoycey /*
25286650Sjoycey * RDY signal stays low may due to the absent of the
25296650Sjoycey * external PHY, it is not an error condition. But still
25306650Sjoycey * print the message for the debugging purpose when link
25316650Sjoycey * stays down
25326650Sjoycey */
25335196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25346650Sjoycey "nxge_neptune_1G_serdes_init: "
25356650Sjoycey "Serdes/signal for port<%d> not ready", portn));
25366835Syc148097 goto done;
25376835Syc148097
25385196Ssbehera }
25395196Ssbehera }
25405196Ssbehera done:
25414732Sdavemq
25424732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
25434732Sdavemq "<== nxge_1G_serdes_init port<%d>", portn));
25443859Sml29623 return (NXGE_OK);
25454732Sdavemq fail:
25465196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
25474732Sdavemq "nxge_1G_serdes_init: "
25484732Sdavemq "Failed to initialize Neptune serdes for port<%d>",
25494732Sdavemq portn));
25504732Sdavemq
25515196Ssbehera return (status);
25523859Sml29623 }
25533859Sml29623
2554*12452SSantwona.Behera@oracle.COM #define NXGE_SET_PHY_TUNABLES(nxgep, phy_port, stat) \
2555*12452SSantwona.Behera@oracle.COM { \
2556*12452SSantwona.Behera@oracle.COM int i; \
2557*12452SSantwona.Behera@oracle.COM \
2558*12452SSantwona.Behera@oracle.COM if (nxgep->phy_prop.cnt > 0) { \
2559*12452SSantwona.Behera@oracle.COM for (i = 0; i < nxgep->phy_prop.cnt; i++) { \
2560*12452SSantwona.Behera@oracle.COM if ((stat = nxge_mdio_write(nxgep, phy_port, \
2561*12452SSantwona.Behera@oracle.COM nxgep->phy_prop.arr[i].dev, \
2562*12452SSantwona.Behera@oracle.COM nxgep->phy_prop.arr[i].reg, \
2563*12452SSantwona.Behera@oracle.COM nxgep->phy_prop.arr[i].val)) != NXGE_OK) { \
2564*12452SSantwona.Behera@oracle.COM break; \
2565*12452SSantwona.Behera@oracle.COM } \
2566*12452SSantwona.Behera@oracle.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, \
2567*12452SSantwona.Behera@oracle.COM "From OBP, write<dev.reg.val> = " \
2568*12452SSantwona.Behera@oracle.COM "<0x%x.0x%x.0x%x>", \
2569*12452SSantwona.Behera@oracle.COM nxgep->phy_prop.arr[i].dev, \
2570*12452SSantwona.Behera@oracle.COM nxgep->phy_prop.arr[i].reg, \
2571*12452SSantwona.Behera@oracle.COM nxgep->phy_prop.arr[i].val)); \
2572*12452SSantwona.Behera@oracle.COM } \
2573*12452SSantwona.Behera@oracle.COM } \
2574*12452SSantwona.Behera@oracle.COM }
2575*12452SSantwona.Behera@oracle.COM
25765572Ssbehera /* Initialize the BCM 8704 xcvr */
25774732Sdavemq
25784732Sdavemq static nxge_status_t
nxge_BCM8704_xcvr_init(p_nxge_t nxgep)25795572Ssbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep)
25803859Sml29623 {
25813859Sml29623 uint16_t val;
25823859Sml29623 #ifdef NXGE_DEBUG
25833859Sml29623 uint8_t portn;
25843859Sml29623 uint16_t val1;
25853859Sml29623 #endif
25863859Sml29623 uint8_t phy_port_addr;
25873859Sml29623 pmd_tx_control_t tx_ctl;
25883859Sml29623 control_t ctl;
25893859Sml29623 phyxs_control_t phyxs_ctl;
25903859Sml29623 pcs_control_t pcs_ctl;
25913859Sml29623 uint32_t delay = 0;
25923859Sml29623 optics_dcntr_t op_ctr;
25933859Sml29623 nxge_status_t status = NXGE_OK;
25943859Sml29623 #ifdef NXGE_DEBUG
25953859Sml29623 portn = nxgep->mac.portnum;
25963859Sml29623 #endif
2597*12452SSantwona.Behera@oracle.COM
25985572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
25994732Sdavemq portn));
26004732Sdavemq
26014732Sdavemq phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
26024732Sdavemq
26034732Sdavemq /* Reset the transceiver */
26044732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
26054732Sdavemq BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
26064732Sdavemq goto fail;
26074732Sdavemq
26084732Sdavemq phyxs_ctl.bits.reset = 1;
26094732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
26104732Sdavemq BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
26114732Sdavemq goto fail;
26124732Sdavemq
26134732Sdavemq do {
26144732Sdavemq drv_usecwait(500);
26154732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26164732Sdavemq BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
26174732Sdavemq &phyxs_ctl.value)) != NXGE_OK)
26184732Sdavemq goto fail;
26194732Sdavemq delay++;
26204732Sdavemq } while ((phyxs_ctl.bits.reset) && (delay < 100));
26214732Sdavemq if (delay == 100) {
26224732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
26234732Sdavemq "failed to reset Transceiver on port<%d>", portn));
26244732Sdavemq status = NXGE_ERROR;
26254732Sdavemq goto fail;
26264732Sdavemq }
26274732Sdavemq
26284732Sdavemq /* Set to 0x7FBF */
26294732Sdavemq ctl.value = 0;
26304732Sdavemq ctl.bits.res1 = 0x3F;
26314732Sdavemq ctl.bits.optxon_lvl = 1;
26324732Sdavemq ctl.bits.oprxflt_lvl = 1;
26334732Sdavemq ctl.bits.optrxlos_lvl = 1;
26344732Sdavemq ctl.bits.optxflt_lvl = 1;
26354732Sdavemq ctl.bits.opprflt_lvl = 1;
26364732Sdavemq ctl.bits.obtmpflt_lvl = 1;
26374732Sdavemq ctl.bits.opbiasflt_lvl = 1;
26384732Sdavemq ctl.bits.optxrst_lvl = 1;
26394732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr,
26404732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
26414732Sdavemq != NXGE_OK)
26424732Sdavemq goto fail;
26434732Sdavemq
26444732Sdavemq /* Set to 0x164 */
26454732Sdavemq tx_ctl.value = 0;
26464732Sdavemq tx_ctl.bits.tsck_lpwren = 1;
26474732Sdavemq tx_ctl.bits.tx_dac_txck = 0x2;
26484732Sdavemq tx_ctl.bits.tx_dac_txd = 0x1;
26494732Sdavemq tx_ctl.bits.xfp_clken = 1;
26504732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr,
26514732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
26524732Sdavemq tx_ctl.value)) != NXGE_OK)
26534732Sdavemq goto fail;
26544732Sdavemq /*
26554732Sdavemq * According to Broadcom's instruction, SW needs to read
26564732Sdavemq * back these registers twice after written.
26574732Sdavemq */
26584732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26594732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
26604732Sdavemq != NXGE_OK)
26614732Sdavemq goto fail;
26624732Sdavemq
26634732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26644732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
26654732Sdavemq != NXGE_OK)
26664732Sdavemq goto fail;
26674732Sdavemq
26684732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26694732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
26704732Sdavemq != NXGE_OK)
26714732Sdavemq goto fail;
26724732Sdavemq
26734732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26744732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
26754732Sdavemq != NXGE_OK)
26764732Sdavemq goto fail;
26774732Sdavemq
26784732Sdavemq /* Enable Tx and Rx LEDs to be driven by traffic */
26794732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
26804732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
26814732Sdavemq &op_ctr.value)) != NXGE_OK)
26824732Sdavemq goto fail;
26835553Smisaki if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
26845553Smisaki op_ctr.bits.gpio_sel = 0x1;
26855553Smisaki } else {
26865553Smisaki op_ctr.bits.gpio_sel = 0x3;
26875553Smisaki }
26884732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr,
26894732Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
26904732Sdavemq op_ctr.value)) != NXGE_OK)
26914732Sdavemq goto fail;
26924732Sdavemq
26934732Sdavemq NXGE_DELAY(1000000);
26944732Sdavemq
2695*12452SSantwona.Behera@oracle.COM /*
2696*12452SSantwona.Behera@oracle.COM * Set XAUI link tunables from OBP if present.
2697*12452SSantwona.Behera@oracle.COM */
2698*12452SSantwona.Behera@oracle.COM NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
2699*12452SSantwona.Behera@oracle.COM if (status != NXGE_OK) {
2700*12452SSantwona.Behera@oracle.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2701*12452SSantwona.Behera@oracle.COM "nxge_BCM8704_xcvr_init: Failed setting PHY tunables"));
2702*12452SSantwona.Behera@oracle.COM goto fail;
2703*12452SSantwona.Behera@oracle.COM }
2704*12452SSantwona.Behera@oracle.COM
27054732Sdavemq /* Set BCM8704 Internal Loopback mode if necessary */
27064732Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr,
27074732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
27084732Sdavemq != NXGE_OK)
27094732Sdavemq goto fail;
27104732Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
27114732Sdavemq pcs_ctl.bits.loopback = 1;
27124732Sdavemq else
27134732Sdavemq pcs_ctl.bits.loopback = 0;
27144732Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr,
27154732Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
27164732Sdavemq != NXGE_OK)
27174732Sdavemq goto fail;
27184732Sdavemq
27194732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
27204732Sdavemq if (status != NXGE_OK)
27214732Sdavemq goto fail;
27224732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27234732Sdavemq "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
27244732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
27254732Sdavemq if (status != NXGE_OK)
27264732Sdavemq goto fail;
27274732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27284732Sdavemq "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
27294732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
27304732Sdavemq if (status != NXGE_OK)
27314732Sdavemq goto fail;
27324732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27334732Sdavemq "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
27344732Sdavemq
27354732Sdavemq #ifdef NXGE_DEBUG
27364732Sdavemq /* Diagnose link issue if link is not up */
27374732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
27384732Sdavemq BCM8704_USER_ANALOG_STATUS0_REG,
27394732Sdavemq &val);
27404732Sdavemq if (status != NXGE_OK)
27414732Sdavemq goto fail;
27424732Sdavemq
27434732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr,
27446929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val);
27454732Sdavemq if (status != NXGE_OK)
27464732Sdavemq goto fail;
27474732Sdavemq
27484732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr,
27496929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
27504732Sdavemq if (status != NXGE_OK)
27514732Sdavemq goto fail;
27524732Sdavemq
27534732Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr,
27546929Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
27554732Sdavemq if (status != NXGE_OK)
27564732Sdavemq goto fail;
27574732Sdavemq
27584732Sdavemq if (val != 0x3FC) {
27594732Sdavemq if ((val == 0x43BC) && (val1 != 0)) {
27604732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27614732Sdavemq "Cable not connected to peer or bad"
27624732Sdavemq " cable on port<%d>\n", portn));
27634732Sdavemq } else if (val == 0x639C) {
27644732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27654732Sdavemq "Optical module (XFP) is bad or absent"
27664732Sdavemq " on port<%d>\n", portn));
27674732Sdavemq }
27684732Sdavemq }
27694732Sdavemq #endif
27704732Sdavemq
27715572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
27725572Ssbehera portn));
27735572Ssbehera return (NXGE_OK);
27745572Ssbehera
27755572Ssbehera fail:
27765572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27775572Ssbehera "nxge_BCM8704_xcvr_init: failed to initialize transceiver for "
27785572Ssbehera "port<%d>", nxgep->mac.portnum));
27795572Ssbehera return (NXGE_ERROR);
27805572Ssbehera }
27815572Ssbehera
27825572Ssbehera /* Initialize the BCM 8706 Transceiver */
27835572Ssbehera
27845572Ssbehera static nxge_status_t
nxge_BCM8706_xcvr_init(p_nxge_t nxgep)27855572Ssbehera nxge_BCM8706_xcvr_init(p_nxge_t nxgep)
27865572Ssbehera {
27875572Ssbehera uint8_t phy_port_addr;
27885572Ssbehera phyxs_control_t phyxs_ctl;
27895572Ssbehera pcs_control_t pcs_ctl;
27905572Ssbehera uint32_t delay = 0;
27915572Ssbehera optics_dcntr_t op_ctr;
27925572Ssbehera nxge_status_t status = NXGE_OK;
27935572Ssbehera #ifdef NXGE_DEBUG
27945572Ssbehera uint8_t portn = nxgep->mac.portnum;
27955572Ssbehera #endif
27965572Ssbehera
27975572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
27985572Ssbehera portn));
27995572Ssbehera
28005572Ssbehera phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
28015572Ssbehera
28025572Ssbehera /* Reset the transceiver */
28035572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
28045572Ssbehera BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
28055572Ssbehera goto fail;
28065572Ssbehera
28075572Ssbehera phyxs_ctl.bits.reset = 1;
28085572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
28095572Ssbehera BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
28105572Ssbehera goto fail;
28115572Ssbehera do {
28125572Ssbehera drv_usecwait(500);
28135572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28145572Ssbehera BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
28155572Ssbehera &phyxs_ctl.value)) != NXGE_OK)
28165572Ssbehera goto fail;
28175572Ssbehera delay++;
28185572Ssbehera } while ((phyxs_ctl.bits.reset) && (delay < 100));
28195572Ssbehera
28205572Ssbehera if (delay == 100) {
28215572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
28225572Ssbehera "failed to reset Transceiver on port<%d>", portn));
28235572Ssbehera status = NXGE_ERROR;
28245572Ssbehera goto fail;
28255572Ssbehera }
28265572Ssbehera
28275572Ssbehera NXGE_DELAY(1000000);
28285572Ssbehera
2829*12452SSantwona.Behera@oracle.COM /*
2830*12452SSantwona.Behera@oracle.COM * Set XAUI link tunables from OBP if present.
2831*12452SSantwona.Behera@oracle.COM */
2832*12452SSantwona.Behera@oracle.COM NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
2833*12452SSantwona.Behera@oracle.COM if (status != NXGE_OK) {
2834*12452SSantwona.Behera@oracle.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2835*12452SSantwona.Behera@oracle.COM "nxge_BCM8706_xcvr_init: Failed setting PHY tunables"));
2836*12452SSantwona.Behera@oracle.COM goto fail;
2837*12452SSantwona.Behera@oracle.COM }
2838*12452SSantwona.Behera@oracle.COM
28395572Ssbehera /* Set BCM8706 Internal Loopback mode if necessary */
28405572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28415572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
28425572Ssbehera != NXGE_OK)
28435572Ssbehera goto fail;
28445572Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
28455572Ssbehera pcs_ctl.bits.loopback = 1;
28465572Ssbehera else
28475572Ssbehera pcs_ctl.bits.loopback = 0;
28485572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr,
28495572Ssbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
28505572Ssbehera != NXGE_OK)
28515572Ssbehera goto fail;
28525572Ssbehera
28535572Ssbehera /* Enable Tx and Rx LEDs to be driven by traffic */
28545572Ssbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28555572Ssbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
28565572Ssbehera &op_ctr.value)) != NXGE_OK)
28575572Ssbehera goto fail;
28585572Ssbehera op_ctr.bits.gpio_sel = 0x3;
28595572Ssbehera op_ctr.bits.res2 = 0x1;
28605572Ssbehera
28615572Ssbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr,
28625572Ssbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
28635572Ssbehera op_ctr.value)) != NXGE_OK)
28645572Ssbehera goto fail;
28655572Ssbehera
28665572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
28675572Ssbehera portn));
28685572Ssbehera return (NXGE_OK);
28695572Ssbehera
28705572Ssbehera fail:
28715572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
28725572Ssbehera "nxge_BCM8706_xcvr_init: failed to initialize transceiver for "
28735572Ssbehera "port<%d>", nxgep->mac.portnum));
28745572Ssbehera return (status);
28755572Ssbehera }
28765572Ssbehera
287712103SSantwona.Behera@Sun.COM static int
nxge_nlp2020_i2c_read(p_nxge_t nxgep,uint8_t ctrl_port,uint16_t address,uint16_t reg,uint8_t * data)287812103SSantwona.Behera@Sun.COM nxge_nlp2020_i2c_read(p_nxge_t nxgep, uint8_t ctrl_port, uint16_t address,
287912103SSantwona.Behera@Sun.COM uint16_t reg, uint8_t *data)
288012103SSantwona.Behera@Sun.COM {
288112103SSantwona.Behera@Sun.COM int phy_dev, phy_reg;
288212103SSantwona.Behera@Sun.COM uint16_t phy_data = 0;
288312103SSantwona.Behera@Sun.COM uint16_t stat;
288412103SSantwona.Behera@Sun.COM uint8_t count = 100;
288512103SSantwona.Behera@Sun.COM
288612103SSantwona.Behera@Sun.COM /*
288712103SSantwona.Behera@Sun.COM * NLP2020_I2C_SNOOP_ADDR_REG [15:9][1] - Address
288812103SSantwona.Behera@Sun.COM * NLP2020_I2C_SNOOP_ADDR_REG[7:0] - register in the xcvr's i2c
288912103SSantwona.Behera@Sun.COM */
289012103SSantwona.Behera@Sun.COM phy_dev = NLP2020_I2C_SNOOP_DEV_ADDR;
289112103SSantwona.Behera@Sun.COM phy_reg = NLP2020_I2C_SNOOP_ADDR_REG;
289212103SSantwona.Behera@Sun.COM phy_data = ((address + 1) << NLP2020_XCVR_I2C_ADDR_SH) | reg;
289312103SSantwona.Behera@Sun.COM if (nxge_mdio_write(nxgep, ctrl_port,
289412103SSantwona.Behera@Sun.COM phy_dev, phy_reg, phy_data) != NXGE_OK)
289512103SSantwona.Behera@Sun.COM goto fail;
289612103SSantwona.Behera@Sun.COM
289712103SSantwona.Behera@Sun.COM phy_reg = NLP2020_I2C_SNOOP_STAT_REG;
289812103SSantwona.Behera@Sun.COM (void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg, &stat);
289912103SSantwona.Behera@Sun.COM while ((stat != 0x01) && (count-- > 0)) {
290012103SSantwona.Behera@Sun.COM (void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg,
290112103SSantwona.Behera@Sun.COM &stat);
290212103SSantwona.Behera@Sun.COM }
290312103SSantwona.Behera@Sun.COM if (count) {
290412103SSantwona.Behera@Sun.COM phy_reg = NLP2020_I2C_SNOOP_DATA_REG;
290512103SSantwona.Behera@Sun.COM (void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg,
290612103SSantwona.Behera@Sun.COM &phy_data);
290712103SSantwona.Behera@Sun.COM *data = (phy_data >> 8);
290812103SSantwona.Behera@Sun.COM return (0);
290912103SSantwona.Behera@Sun.COM }
291012103SSantwona.Behera@Sun.COM fail:
291112103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
291212103SSantwona.Behera@Sun.COM "nxge_nlp2020_i2c_read: FAILED"));
291312103SSantwona.Behera@Sun.COM return (1);
291412103SSantwona.Behera@Sun.COM
291512103SSantwona.Behera@Sun.COM }
291612103SSantwona.Behera@Sun.COM
291712103SSantwona.Behera@Sun.COM /* Initialize the Netlogic AEL2020 Transceiver */
291812103SSantwona.Behera@Sun.COM
291912103SSantwona.Behera@Sun.COM #define NLP_INI_WAIT 1
292012103SSantwona.Behera@Sun.COM #define NLP_INI_STOP 0
292112103SSantwona.Behera@Sun.COM
292212103SSantwona.Behera@Sun.COM static nxge_nlp_initseq_t nlp2020_revC_fiber_init[] = {
292312103SSantwona.Behera@Sun.COM {0x1C003, 0x3101},
292412103SSantwona.Behera@Sun.COM {0x1CC01, 0x488a},
292512103SSantwona.Behera@Sun.COM {0x1CB1B, 0x0200},
292612103SSantwona.Behera@Sun.COM {0x1CB1C, 0x00f0},
292712103SSantwona.Behera@Sun.COM {0x1CC06, 0x00e0},
292812103SSantwona.Behera@Sun.COM {NLP_INI_STOP, 0},
292912103SSantwona.Behera@Sun.COM };
293012103SSantwona.Behera@Sun.COM
293112103SSantwona.Behera@Sun.COM static nxge_nlp_initseq_t nlp2020_revC_copper_init[] = {
293212103SSantwona.Behera@Sun.COM
293312103SSantwona.Behera@Sun.COM {0x1C003, 0x3101},
293412103SSantwona.Behera@Sun.COM {0x1CD40, 0x0001},
293512103SSantwona.Behera@Sun.COM
293612103SSantwona.Behera@Sun.COM {0x1CA12, 0x0100},
293712103SSantwona.Behera@Sun.COM {0x1CA22, 0x0100},
293812103SSantwona.Behera@Sun.COM {0x1CA42, 0x0100},
293912103SSantwona.Behera@Sun.COM {0x1C20D, 0x0002},
294012103SSantwona.Behera@Sun.COM {NLP_INI_WAIT, 100},
294112103SSantwona.Behera@Sun.COM
294212103SSantwona.Behera@Sun.COM {0x1ff28, 0x4001},
294312103SSantwona.Behera@Sun.COM {0x1ff2A, 0x004A},
294412103SSantwona.Behera@Sun.COM {NLP_INI_WAIT, 500},
294512103SSantwona.Behera@Sun.COM
294612103SSantwona.Behera@Sun.COM {0x1d000, 0x5200},
294712103SSantwona.Behera@Sun.COM {NLP_INI_WAIT, 500},
294812103SSantwona.Behera@Sun.COM
294912103SSantwona.Behera@Sun.COM {0x1d800, 0x4009},
295012103SSantwona.Behera@Sun.COM {0x1d801, 0x2fff},
295112103SSantwona.Behera@Sun.COM {0x1d802, 0x300f},
295212103SSantwona.Behera@Sun.COM {0x1d803, 0x40aa},
295312103SSantwona.Behera@Sun.COM {0x1d804, 0x401c},
295412103SSantwona.Behera@Sun.COM {0x1d805, 0x401e},
295512103SSantwona.Behera@Sun.COM {0x1d806, 0x20c5},
295612103SSantwona.Behera@Sun.COM {0x1d807, 0x3c05},
295712103SSantwona.Behera@Sun.COM {0x1d808, 0x6536},
295812103SSantwona.Behera@Sun.COM {0x1d809, 0x2fe4},
295912103SSantwona.Behera@Sun.COM {0x1d80a, 0x3dc4},
296012103SSantwona.Behera@Sun.COM {0x1d80b, 0x6624},
296112103SSantwona.Behera@Sun.COM {0x1d80c, 0x2ff4},
296212103SSantwona.Behera@Sun.COM {0x1d80d, 0x3dc4},
296312103SSantwona.Behera@Sun.COM {0x1d80e, 0x2035},
296412103SSantwona.Behera@Sun.COM {0x1d80f, 0x30a5},
296512103SSantwona.Behera@Sun.COM {0x1d810, 0x6524},
296612103SSantwona.Behera@Sun.COM {0x1d811, 0x2ca2},
296712103SSantwona.Behera@Sun.COM {0x1d812, 0x3012},
296812103SSantwona.Behera@Sun.COM {0x1d813, 0x1002},
296912103SSantwona.Behera@Sun.COM {0x1d814, 0x2882},
297012103SSantwona.Behera@Sun.COM {0x1d815, 0x3022},
297112103SSantwona.Behera@Sun.COM {0x1d816, 0x1002},
297212103SSantwona.Behera@Sun.COM {0x1d817, 0x2972},
297312103SSantwona.Behera@Sun.COM {0x1d818, 0x3022},
297412103SSantwona.Behera@Sun.COM {0x1d819, 0x1002},
297512103SSantwona.Behera@Sun.COM {0x1d81a, 0x2892},
297612103SSantwona.Behera@Sun.COM {0x1d81b, 0x3012},
297712103SSantwona.Behera@Sun.COM {0x1d81c, 0x1002},
297812103SSantwona.Behera@Sun.COM {0x1d81d, 0x24e2},
297912103SSantwona.Behera@Sun.COM {0x1d81e, 0x3022},
298012103SSantwona.Behera@Sun.COM {0x1d81f, 0x1002},
298112103SSantwona.Behera@Sun.COM {0x1d820, 0x27e2},
298212103SSantwona.Behera@Sun.COM {0x1d821, 0x3012},
298312103SSantwona.Behera@Sun.COM {0x1d822, 0x1002},
298412103SSantwona.Behera@Sun.COM {0x1d823, 0x2422},
298512103SSantwona.Behera@Sun.COM {0x1d824, 0x3022},
298612103SSantwona.Behera@Sun.COM {0x1d825, 0x1002},
298712103SSantwona.Behera@Sun.COM {0x1d826, 0x22cd},
298812103SSantwona.Behera@Sun.COM {0x1d827, 0x301d},
298912103SSantwona.Behera@Sun.COM {0x1d828, 0x2992},
299012103SSantwona.Behera@Sun.COM {0x1d829, 0x3022},
299112103SSantwona.Behera@Sun.COM {0x1d82a, 0x1002},
299212103SSantwona.Behera@Sun.COM {0x1d82b, 0x5553},
299312103SSantwona.Behera@Sun.COM {0x1d82c, 0x0307},
299412103SSantwona.Behera@Sun.COM {0x1d82d, 0x2572},
299512103SSantwona.Behera@Sun.COM {0x1d82e, 0x3022},
299612103SSantwona.Behera@Sun.COM {0x1d82f, 0x1002},
299712103SSantwona.Behera@Sun.COM {0x1d830, 0x21a2},
299812103SSantwona.Behera@Sun.COM {0x1d831, 0x3012},
299912103SSantwona.Behera@Sun.COM {0x1d832, 0x1002},
300012103SSantwona.Behera@Sun.COM {0x1d833, 0x4016},
300112103SSantwona.Behera@Sun.COM {0x1d834, 0x5e63},
300212103SSantwona.Behera@Sun.COM {0x1d835, 0x0344},
300312103SSantwona.Behera@Sun.COM {0x1d836, 0x21a2},
300412103SSantwona.Behera@Sun.COM {0x1d837, 0x3012},
300512103SSantwona.Behera@Sun.COM {0x1d838, 0x1002},
300612103SSantwona.Behera@Sun.COM {0x1d839, 0x400e},
300712103SSantwona.Behera@Sun.COM {0x1d83a, 0x2572},
300812103SSantwona.Behera@Sun.COM {0x1d83b, 0x3022},
300912103SSantwona.Behera@Sun.COM {0x1d83c, 0x1002},
301012103SSantwona.Behera@Sun.COM {0x1d83d, 0x2b22},
301112103SSantwona.Behera@Sun.COM {0x1d83e, 0x3012},
301212103SSantwona.Behera@Sun.COM {0x1d83f, 0x1002},
301312103SSantwona.Behera@Sun.COM {0x1d840, 0x28e2},
301412103SSantwona.Behera@Sun.COM {0x1d841, 0x3022},
301512103SSantwona.Behera@Sun.COM {0x1d842, 0x1002},
301612103SSantwona.Behera@Sun.COM {0x1d843, 0x2782},
301712103SSantwona.Behera@Sun.COM {0x1d844, 0x3022},
301812103SSantwona.Behera@Sun.COM {0x1d845, 0x1002},
301912103SSantwona.Behera@Sun.COM {0x1d846, 0x2fa4},
302012103SSantwona.Behera@Sun.COM {0x1d847, 0x3dc4},
302112103SSantwona.Behera@Sun.COM {0x1d848, 0x6624},
302212103SSantwona.Behera@Sun.COM {0x1d849, 0x2e8b},
302312103SSantwona.Behera@Sun.COM {0x1d84a, 0x303b},
302412103SSantwona.Behera@Sun.COM {0x1d84b, 0x56b3},
302512103SSantwona.Behera@Sun.COM {0x1d84c, 0x03c6},
302612103SSantwona.Behera@Sun.COM {0x1d84d, 0x866b},
302712103SSantwona.Behera@Sun.COM {0x1d84e, 0x400c},
302812103SSantwona.Behera@Sun.COM {0x1d84f, 0x2782},
302912103SSantwona.Behera@Sun.COM {0x1d850, 0x3012},
303012103SSantwona.Behera@Sun.COM {0x1d851, 0x1002},
303112103SSantwona.Behera@Sun.COM {0x1d852, 0x2c4b},
303212103SSantwona.Behera@Sun.COM {0x1d853, 0x309b},
303312103SSantwona.Behera@Sun.COM {0x1d854, 0x56b3},
303412103SSantwona.Behera@Sun.COM {0x1d855, 0x03c3},
303512103SSantwona.Behera@Sun.COM {0x1d856, 0x866b},
303612103SSantwona.Behera@Sun.COM {0x1d857, 0x400c},
303712103SSantwona.Behera@Sun.COM {0x1d858, 0x22a2},
303812103SSantwona.Behera@Sun.COM {0x1d859, 0x3022},
303912103SSantwona.Behera@Sun.COM {0x1d85a, 0x1002},
304012103SSantwona.Behera@Sun.COM {0x1d85b, 0x28e2},
304112103SSantwona.Behera@Sun.COM {0x1d85c, 0x3022},
304212103SSantwona.Behera@Sun.COM {0x1d85d, 0x1002},
304312103SSantwona.Behera@Sun.COM {0x1d85e, 0x2782},
304412103SSantwona.Behera@Sun.COM {0x1d85f, 0x3022},
304512103SSantwona.Behera@Sun.COM {0x1d860, 0x1002},
304612103SSantwona.Behera@Sun.COM {0x1d861, 0x2fb4},
304712103SSantwona.Behera@Sun.COM {0x1d862, 0x3dc4},
304812103SSantwona.Behera@Sun.COM {0x1d863, 0x6624},
304912103SSantwona.Behera@Sun.COM {0x1d864, 0x56b3},
305012103SSantwona.Behera@Sun.COM {0x1d865, 0x03c3},
305112103SSantwona.Behera@Sun.COM {0x1d866, 0x866b},
305212103SSantwona.Behera@Sun.COM {0x1d867, 0x401c},
305312103SSantwona.Behera@Sun.COM {0x1d868, 0x2c45},
305412103SSantwona.Behera@Sun.COM {0x1d869, 0x3095},
305512103SSantwona.Behera@Sun.COM {0x1d86a, 0x5b53},
305612103SSantwona.Behera@Sun.COM {0x1d86b, 0x23d2},
305712103SSantwona.Behera@Sun.COM {0x1d86c, 0x3012},
305812103SSantwona.Behera@Sun.COM {0x1d86d, 0x13c2},
305912103SSantwona.Behera@Sun.COM {0x1d86e, 0x5cc3},
306012103SSantwona.Behera@Sun.COM {0x1d86f, 0x2782},
306112103SSantwona.Behera@Sun.COM {0x1d870, 0x3012},
306212103SSantwona.Behera@Sun.COM {0x1d871, 0x1312},
306312103SSantwona.Behera@Sun.COM {0x1d872, 0x2b22},
306412103SSantwona.Behera@Sun.COM {0x1d873, 0x3012},
306512103SSantwona.Behera@Sun.COM {0x1d874, 0x1002},
306612103SSantwona.Behera@Sun.COM {0x1d875, 0x28e2},
306712103SSantwona.Behera@Sun.COM {0x1d876, 0x3022},
306812103SSantwona.Behera@Sun.COM {0x1d877, 0x1002},
306912103SSantwona.Behera@Sun.COM {0x1d878, 0x2672},
307012103SSantwona.Behera@Sun.COM {0x1d879, 0x3022},
307112103SSantwona.Behera@Sun.COM {0x1d87a, 0x1002},
307212103SSantwona.Behera@Sun.COM {0x1d87b, 0x21a2},
307312103SSantwona.Behera@Sun.COM {0x1d87c, 0x3012},
307412103SSantwona.Behera@Sun.COM {0x1d87d, 0x1002},
307512103SSantwona.Behera@Sun.COM {0x1d87e, 0x628f},
307612103SSantwona.Behera@Sun.COM {0x1d87f, 0x2985},
307712103SSantwona.Behera@Sun.COM {0x1d880, 0x33a5},
307812103SSantwona.Behera@Sun.COM {0x1d881, 0x2782},
307912103SSantwona.Behera@Sun.COM {0x1d882, 0x3022},
308012103SSantwona.Behera@Sun.COM {0x1d883, 0x1002},
308112103SSantwona.Behera@Sun.COM {0x1d884, 0x5653},
308212103SSantwona.Behera@Sun.COM {0x1d885, 0x03d2},
308312103SSantwona.Behera@Sun.COM {0x1d886, 0x401e},
308412103SSantwona.Behera@Sun.COM {0x1d887, 0x6f72},
308512103SSantwona.Behera@Sun.COM {0x1d888, 0x1002},
308612103SSantwona.Behera@Sun.COM {0x1d889, 0x628f},
308712103SSantwona.Behera@Sun.COM {0x1d88a, 0x2304},
308812103SSantwona.Behera@Sun.COM {0x1d88b, 0x3c84},
308912103SSantwona.Behera@Sun.COM {0x1d88c, 0x6436},
309012103SSantwona.Behera@Sun.COM {0x1d88d, 0xdff4},
309112103SSantwona.Behera@Sun.COM {0x1d88e, 0x6436},
309212103SSantwona.Behera@Sun.COM {0x1d88f, 0x2ff5},
309312103SSantwona.Behera@Sun.COM {0x1d890, 0x3005},
309412103SSantwona.Behera@Sun.COM {0x1d891, 0x8656},
309512103SSantwona.Behera@Sun.COM {0x1d892, 0xdfba},
309612103SSantwona.Behera@Sun.COM {0x1d893, 0x56a3},
309712103SSantwona.Behera@Sun.COM {0x1d894, 0xd05a},
309812103SSantwona.Behera@Sun.COM {0x1d895, 0x29e2},
309912103SSantwona.Behera@Sun.COM {0x1d896, 0x3012},
310012103SSantwona.Behera@Sun.COM {0x1d897, 0x1392},
310112103SSantwona.Behera@Sun.COM {0x1d898, 0xd05a},
310212103SSantwona.Behera@Sun.COM {0x1d899, 0x56a3},
310312103SSantwona.Behera@Sun.COM {0x1d89a, 0xdfba},
310412103SSantwona.Behera@Sun.COM {0x1d89b, 0x0383},
310512103SSantwona.Behera@Sun.COM {0x1d89c, 0x6f72},
310612103SSantwona.Behera@Sun.COM {0x1d89d, 0x1002},
310712103SSantwona.Behera@Sun.COM {0x1d89e, 0x2a64},
310812103SSantwona.Behera@Sun.COM {0x1d89f, 0x3014},
310912103SSantwona.Behera@Sun.COM {0x1d8a0, 0x2005},
311012103SSantwona.Behera@Sun.COM {0x1d8a1, 0x3d75},
311112103SSantwona.Behera@Sun.COM {0x1d8a2, 0xc451},
311212103SSantwona.Behera@Sun.COM {0x1d8a3, 0x2a42},
311312103SSantwona.Behera@Sun.COM {0x1d8a4, 0x3022},
311412103SSantwona.Behera@Sun.COM {0x1d8a5, 0x1002},
311512103SSantwona.Behera@Sun.COM {0x1d8a6, 0x178c},
311612103SSantwona.Behera@Sun.COM {0x1d8a7, 0x1898},
311712103SSantwona.Behera@Sun.COM {0x1d8a8, 0x19a4},
311812103SSantwona.Behera@Sun.COM {0x1d8a9, 0x1ab0},
311912103SSantwona.Behera@Sun.COM {0x1d8aa, 0x1bbc},
312012103SSantwona.Behera@Sun.COM {0x1d8ab, 0x1cc8},
312112103SSantwona.Behera@Sun.COM {0x1d8ac, 0x1dd3},
312212103SSantwona.Behera@Sun.COM {0x1d8ad, 0x1ede},
312312103SSantwona.Behera@Sun.COM {0x1d8ae, 0x1fe9},
312412103SSantwona.Behera@Sun.COM {0x1d8af, 0x20f4},
312512103SSantwona.Behera@Sun.COM {0x1d8b0, 0x21ff},
312612103SSantwona.Behera@Sun.COM {0x1d8b1, 0x0000},
312712103SSantwona.Behera@Sun.COM {0x1d8b2, 0x27e1},
312812103SSantwona.Behera@Sun.COM {0x1d8b3, 0x3021},
312912103SSantwona.Behera@Sun.COM {0x1d8b4, 0x1001},
313012103SSantwona.Behera@Sun.COM {0x1d8b5, 0xc620},
313112103SSantwona.Behera@Sun.COM {0x1d8b6, 0x0000},
313212103SSantwona.Behera@Sun.COM {0x1d8b7, 0xc621},
313312103SSantwona.Behera@Sun.COM {0x1d8b8, 0x0000},
313412103SSantwona.Behera@Sun.COM {0x1d8b9, 0xc622},
313512103SSantwona.Behera@Sun.COM {0x1d8ba, 0x00e2},
313612103SSantwona.Behera@Sun.COM {0x1d8bb, 0xc623},
313712103SSantwona.Behera@Sun.COM {0x1d8bc, 0x007f},
313812103SSantwona.Behera@Sun.COM {0x1d8bd, 0xc624},
313912103SSantwona.Behera@Sun.COM {0x1d8be, 0x00ce},
314012103SSantwona.Behera@Sun.COM {0x1d8bf, 0xc625},
314112103SSantwona.Behera@Sun.COM {0x1d8c0, 0x0000},
314212103SSantwona.Behera@Sun.COM {0x1d8c1, 0xc627},
314312103SSantwona.Behera@Sun.COM {0x1d8c2, 0x0000},
314412103SSantwona.Behera@Sun.COM {0x1d8c3, 0xc628},
314512103SSantwona.Behera@Sun.COM {0x1d8c4, 0x0000},
314612103SSantwona.Behera@Sun.COM {0x1d8c5, 0xc90a},
314712103SSantwona.Behera@Sun.COM {0x1d8c6, 0x3a7c},
314812103SSantwona.Behera@Sun.COM {0x1d8c7, 0xc62c},
314912103SSantwona.Behera@Sun.COM {0x1d8c8, 0x0000},
315012103SSantwona.Behera@Sun.COM {0x1d8c9, 0x0000},
315112103SSantwona.Behera@Sun.COM {0x1d8ca, 0x27e1},
315212103SSantwona.Behera@Sun.COM {0x1d8cb, 0x3021},
315312103SSantwona.Behera@Sun.COM {0x1d8cc, 0x1001},
315412103SSantwona.Behera@Sun.COM {0x1d8cd, 0xc502},
315512103SSantwona.Behera@Sun.COM {0x1d8ce, 0x53ac},
315612103SSantwona.Behera@Sun.COM {0x1d8cf, 0xc503},
315712103SSantwona.Behera@Sun.COM {0x1d8d0, 0x2cd3},
315812103SSantwona.Behera@Sun.COM {0x1d8d1, 0xc600},
315912103SSantwona.Behera@Sun.COM {0x1d8d2, 0x2a6e},
316012103SSantwona.Behera@Sun.COM {0x1d8d3, 0xc601},
316112103SSantwona.Behera@Sun.COM {0x1d8d4, 0x2a2c},
316212103SSantwona.Behera@Sun.COM {0x1d8d5, 0xc605},
316312103SSantwona.Behera@Sun.COM {0x1d8d6, 0x5557},
316412103SSantwona.Behera@Sun.COM {0x1d8d7, 0xc60c},
316512103SSantwona.Behera@Sun.COM {0x1d8d8, 0x5400},
316612103SSantwona.Behera@Sun.COM {0x1d8d9, 0xc710},
316712103SSantwona.Behera@Sun.COM {0x1d8da, 0x0700},
316812103SSantwona.Behera@Sun.COM {0x1d8db, 0xc711},
316912103SSantwona.Behera@Sun.COM {0x1d8dc, 0x0f06},
317012103SSantwona.Behera@Sun.COM {0x1d8dd, 0xc718},
317112103SSantwona.Behera@Sun.COM {0x1d8de, 0x0700},
317212103SSantwona.Behera@Sun.COM {0x1d8df, 0xc719},
317312103SSantwona.Behera@Sun.COM {0x1d8e0, 0x0f06},
317412103SSantwona.Behera@Sun.COM {0x1d8e1, 0xc720},
317512103SSantwona.Behera@Sun.COM {0x1d8e2, 0x4700},
317612103SSantwona.Behera@Sun.COM {0x1d8e3, 0xc721},
317712103SSantwona.Behera@Sun.COM {0x1d8e4, 0x0f06},
317812103SSantwona.Behera@Sun.COM {0x1d8e5, 0xc728},
317912103SSantwona.Behera@Sun.COM {0x1d8e6, 0x0700},
318012103SSantwona.Behera@Sun.COM {0x1d8e7, 0xc729},
318112103SSantwona.Behera@Sun.COM {0x1d8e8, 0x1207},
318212103SSantwona.Behera@Sun.COM {0x1d8e9, 0xc801},
318312103SSantwona.Behera@Sun.COM {0x1d8ea, 0x7f50},
318412103SSantwona.Behera@Sun.COM {0x1d8eb, 0xc802},
318512103SSantwona.Behera@Sun.COM {0x1d8ec, 0x7760},
318612103SSantwona.Behera@Sun.COM {0x1d8ed, 0xc803},
318712103SSantwona.Behera@Sun.COM {0x1d8ee, 0x7fce},
318812103SSantwona.Behera@Sun.COM {0x1d8ef, 0xc804},
318912103SSantwona.Behera@Sun.COM {0x1d8f0, 0x520e},
319012103SSantwona.Behera@Sun.COM {0x1d8f1, 0xc805},
319112103SSantwona.Behera@Sun.COM {0x1d8f2, 0x5c11},
319212103SSantwona.Behera@Sun.COM {0x1d8f3, 0xc806},
319312103SSantwona.Behera@Sun.COM {0x1d8f4, 0x3c51},
319412103SSantwona.Behera@Sun.COM {0x1d8f5, 0xc807},
319512103SSantwona.Behera@Sun.COM {0x1d8f6, 0x4061},
319612103SSantwona.Behera@Sun.COM {0x1d8f7, 0xc808},
319712103SSantwona.Behera@Sun.COM {0x1d8f8, 0x49c1},
319812103SSantwona.Behera@Sun.COM {0x1d8f9, 0xc809},
319912103SSantwona.Behera@Sun.COM {0x1d8fa, 0x3840},
320012103SSantwona.Behera@Sun.COM {0x1d8fb, 0xc80a},
320112103SSantwona.Behera@Sun.COM {0x1d8fc, 0x0000},
320212103SSantwona.Behera@Sun.COM {0x1d8fd, 0xc821},
320312103SSantwona.Behera@Sun.COM {0x1d8fe, 0x0002},
320412103SSantwona.Behera@Sun.COM {0x1d8ff, 0xc822},
320512103SSantwona.Behera@Sun.COM {0x1d900, 0x0046},
320612103SSantwona.Behera@Sun.COM {0x1d901, 0xc844},
320712103SSantwona.Behera@Sun.COM {0x1d902, 0x182f},
320812103SSantwona.Behera@Sun.COM {0x1d903, 0xc849},
320912103SSantwona.Behera@Sun.COM {0x1d904, 0x0400},
321012103SSantwona.Behera@Sun.COM {0x1d905, 0xc84a},
321112103SSantwona.Behera@Sun.COM {0x1d906, 0x0002},
321212103SSantwona.Behera@Sun.COM {0x1d907, 0xc013},
321312103SSantwona.Behera@Sun.COM {0x1d908, 0xf341},
321412103SSantwona.Behera@Sun.COM {0x1d909, 0xc084},
321512103SSantwona.Behera@Sun.COM {0x1d90a, 0x0030},
321612103SSantwona.Behera@Sun.COM {0x1d90b, 0xc904},
321712103SSantwona.Behera@Sun.COM {0x1d90c, 0x1401},
321812103SSantwona.Behera@Sun.COM {0x1d90d, 0xcb0c},
321912103SSantwona.Behera@Sun.COM {0x1d90e, 0x0004},
322012103SSantwona.Behera@Sun.COM {0x1d90f, 0xcb0e},
322112103SSantwona.Behera@Sun.COM {0x1d910, 0xa00a},
322212103SSantwona.Behera@Sun.COM {0x1d911, 0xcb0f},
322312103SSantwona.Behera@Sun.COM {0x1d912, 0xc0c0},
322412103SSantwona.Behera@Sun.COM {0x1d913, 0xcb10},
322512103SSantwona.Behera@Sun.COM {0x1d914, 0xc0c0},
322612103SSantwona.Behera@Sun.COM {0x1d915, 0xcb11},
322712103SSantwona.Behera@Sun.COM {0x1d916, 0x00a0},
322812103SSantwona.Behera@Sun.COM {0x1d917, 0xcb12},
322912103SSantwona.Behera@Sun.COM {0x1d918, 0x0007},
323012103SSantwona.Behera@Sun.COM {0x1d919, 0xc241},
323112103SSantwona.Behera@Sun.COM {0x1d91a, 0xa000},
323212103SSantwona.Behera@Sun.COM {0x1d91b, 0xc243},
323312103SSantwona.Behera@Sun.COM {0x1d91c, 0x7fe0},
323412103SSantwona.Behera@Sun.COM {0x1d91d, 0xc604},
323512103SSantwona.Behera@Sun.COM {0x1d91e, 0x000e},
323612103SSantwona.Behera@Sun.COM {0x1d91f, 0xc609},
323712103SSantwona.Behera@Sun.COM {0x1d920, 0x00f5},
323812103SSantwona.Behera@Sun.COM {0x1d921, 0x0c61},
323912103SSantwona.Behera@Sun.COM {0x1d922, 0x000e},
324012103SSantwona.Behera@Sun.COM {0x1d923, 0xc660},
324112103SSantwona.Behera@Sun.COM {0x1d924, 0x9600},
324212103SSantwona.Behera@Sun.COM {0x1d925, 0xc687},
324312103SSantwona.Behera@Sun.COM {0x1d926, 0x0004},
324412103SSantwona.Behera@Sun.COM {0x1d927, 0xc60a},
324512103SSantwona.Behera@Sun.COM {0x1d928, 0x04f5},
324612103SSantwona.Behera@Sun.COM {0x1d929, 0x0000},
324712103SSantwona.Behera@Sun.COM {0x1d92a, 0x27e1},
324812103SSantwona.Behera@Sun.COM {0x1d92b, 0x3021},
324912103SSantwona.Behera@Sun.COM {0x1d92c, 0x1001},
325012103SSantwona.Behera@Sun.COM {0x1d92d, 0xc620},
325112103SSantwona.Behera@Sun.COM {0x1d92e, 0x14e5},
325212103SSantwona.Behera@Sun.COM {0x1d92f, 0xc621},
325312103SSantwona.Behera@Sun.COM {0x1d930, 0xc53d},
325412103SSantwona.Behera@Sun.COM {0x1d931, 0xc622},
325512103SSantwona.Behera@Sun.COM {0x1d932, 0x3cbe},
325612103SSantwona.Behera@Sun.COM {0x1d933, 0xc623},
325712103SSantwona.Behera@Sun.COM {0x1d934, 0x4452},
325812103SSantwona.Behera@Sun.COM {0x1d935, 0xc624},
325912103SSantwona.Behera@Sun.COM {0x1d936, 0xc5c5},
326012103SSantwona.Behera@Sun.COM {0x1d937, 0xc625},
326112103SSantwona.Behera@Sun.COM {0x1d938, 0xe01e},
326212103SSantwona.Behera@Sun.COM {0x1d939, 0xc627},
326312103SSantwona.Behera@Sun.COM {0x1d93a, 0x0000},
326412103SSantwona.Behera@Sun.COM {0x1d93b, 0xc628},
326512103SSantwona.Behera@Sun.COM {0x1d93c, 0x0000},
326612103SSantwona.Behera@Sun.COM {0x1d93d, 0xc62c},
326712103SSantwona.Behera@Sun.COM {0x1d93e, 0x0000},
326812103SSantwona.Behera@Sun.COM {0x1d93f, 0xc90a},
326912103SSantwona.Behera@Sun.COM {0x1d940, 0x3a7c},
327012103SSantwona.Behera@Sun.COM {0x1d941, 0x0000},
327112103SSantwona.Behera@Sun.COM {0x1d942, 0x2b84},
327212103SSantwona.Behera@Sun.COM {0x1d943, 0x3c74},
327312103SSantwona.Behera@Sun.COM {0x1d944, 0x6435},
327412103SSantwona.Behera@Sun.COM {0x1d945, 0xdff4},
327512103SSantwona.Behera@Sun.COM {0x1d946, 0x6435},
327612103SSantwona.Behera@Sun.COM {0x1d947, 0x2806},
327712103SSantwona.Behera@Sun.COM {0x1d948, 0x3006},
327812103SSantwona.Behera@Sun.COM {0x1d949, 0x8565},
327912103SSantwona.Behera@Sun.COM {0x1d94a, 0x2b24},
328012103SSantwona.Behera@Sun.COM {0x1d94b, 0x3c24},
328112103SSantwona.Behera@Sun.COM {0x1d94c, 0x6436},
328212103SSantwona.Behera@Sun.COM {0x1d94d, 0x1002},
328312103SSantwona.Behera@Sun.COM {0x1d94e, 0x2b24},
328412103SSantwona.Behera@Sun.COM {0x1d94f, 0x3c24},
328512103SSantwona.Behera@Sun.COM {0x1d950, 0x6436},
328612103SSantwona.Behera@Sun.COM {0x1d951, 0x4045},
328712103SSantwona.Behera@Sun.COM {0x1d952, 0x8656},
328812103SSantwona.Behera@Sun.COM {0x1d953, 0x5663},
328912103SSantwona.Behera@Sun.COM {0x1d954, 0x0302},
329012103SSantwona.Behera@Sun.COM {0x1d955, 0x401e},
329112103SSantwona.Behera@Sun.COM {0x1d956, 0x1002},
329212103SSantwona.Behera@Sun.COM {0x1d957, 0x2017},
329312103SSantwona.Behera@Sun.COM {0x1d958, 0x3b17},
329412103SSantwona.Behera@Sun.COM {0x1d959, 0x2084},
329512103SSantwona.Behera@Sun.COM {0x1d95a, 0x3c14},
329612103SSantwona.Behera@Sun.COM {0x1d95b, 0x6724},
329712103SSantwona.Behera@Sun.COM {0x1d95c, 0x2807},
329812103SSantwona.Behera@Sun.COM {0x1d95d, 0x31a7},
329912103SSantwona.Behera@Sun.COM {0x1d95e, 0x20c4},
330012103SSantwona.Behera@Sun.COM {0x1d95f, 0x3c24},
330112103SSantwona.Behera@Sun.COM {0x1d960, 0x6724},
330212103SSantwona.Behera@Sun.COM {0x1d961, 0x2ff7},
330312103SSantwona.Behera@Sun.COM {0x1d962, 0x30f7},
330412103SSantwona.Behera@Sun.COM {0x1d963, 0x20c4},
330512103SSantwona.Behera@Sun.COM {0x1d964, 0x3c04},
330612103SSantwona.Behera@Sun.COM {0x1d965, 0x6724},
330712103SSantwona.Behera@Sun.COM {0x1d966, 0x1002},
330812103SSantwona.Behera@Sun.COM {0x1d967, 0x2807},
330912103SSantwona.Behera@Sun.COM {0x1d968, 0x3187},
331012103SSantwona.Behera@Sun.COM {0x1d969, 0x20c4},
331112103SSantwona.Behera@Sun.COM {0x1d96a, 0x3c24},
331212103SSantwona.Behera@Sun.COM {0x1d96b, 0x6724},
331312103SSantwona.Behera@Sun.COM {0x1d96c, 0x2fe4},
331412103SSantwona.Behera@Sun.COM {0x1d96d, 0x3dc4},
331512103SSantwona.Behera@Sun.COM {0x1d96e, 0x6437},
331612103SSantwona.Behera@Sun.COM {0x1d96f, 0x20c4},
331712103SSantwona.Behera@Sun.COM {0x1d970, 0x3c04},
331812103SSantwona.Behera@Sun.COM {0x1d971, 0x6724},
331912103SSantwona.Behera@Sun.COM {0x1d972, 0x2017},
332012103SSantwona.Behera@Sun.COM {0x1d973, 0x3d17},
332112103SSantwona.Behera@Sun.COM {0x1d974, 0x2084},
332212103SSantwona.Behera@Sun.COM {0x1d975, 0x3c14},
332312103SSantwona.Behera@Sun.COM {0x1d976, 0x6724},
332412103SSantwona.Behera@Sun.COM {0x1d977, 0x1002},
332512103SSantwona.Behera@Sun.COM {0x1d978, 0x24f4},
332612103SSantwona.Behera@Sun.COM {0x1d979, 0x3c64},
332712103SSantwona.Behera@Sun.COM {0x1d97a, 0x6436},
332812103SSantwona.Behera@Sun.COM {0x1d97b, 0xdff4},
332912103SSantwona.Behera@Sun.COM {0x1d97c, 0x6436},
333012103SSantwona.Behera@Sun.COM {0x1d97d, 0x1002},
333112103SSantwona.Behera@Sun.COM {0x1d97e, 0x2006},
333212103SSantwona.Behera@Sun.COM {0x1d97f, 0x3d76},
333312103SSantwona.Behera@Sun.COM {0x1d980, 0xc161},
333412103SSantwona.Behera@Sun.COM {0x1d981, 0x6134},
333512103SSantwona.Behera@Sun.COM {0x1d982, 0x6135},
333612103SSantwona.Behera@Sun.COM {0x1d983, 0x5443},
333712103SSantwona.Behera@Sun.COM {0x1d984, 0x0303},
333812103SSantwona.Behera@Sun.COM {0x1d985, 0x6524},
333912103SSantwona.Behera@Sun.COM {0x1d986, 0x00fb},
334012103SSantwona.Behera@Sun.COM {0x1d987, 0x1002},
334112103SSantwona.Behera@Sun.COM {0x1d988, 0x20d4},
334212103SSantwona.Behera@Sun.COM {0x1d989, 0x3c24},
334312103SSantwona.Behera@Sun.COM {0x1d98a, 0x2025},
334412103SSantwona.Behera@Sun.COM {0x1d98b, 0x3005},
334512103SSantwona.Behera@Sun.COM {0x1d98c, 0x6524},
334612103SSantwona.Behera@Sun.COM {0x1d98d, 0x1002},
334712103SSantwona.Behera@Sun.COM {0x1d98e, 0xd019},
334812103SSantwona.Behera@Sun.COM {0x1d98f, 0x2104},
334912103SSantwona.Behera@Sun.COM {0x1d990, 0x3c24},
335012103SSantwona.Behera@Sun.COM {0x1d991, 0x2105},
335112103SSantwona.Behera@Sun.COM {0x1d992, 0x3805},
335212103SSantwona.Behera@Sun.COM {0x1d993, 0x6524},
335312103SSantwona.Behera@Sun.COM {0x1d994, 0xdff4},
335412103SSantwona.Behera@Sun.COM {0x1d995, 0x4005},
335512103SSantwona.Behera@Sun.COM {0x1d996, 0x6524},
335612103SSantwona.Behera@Sun.COM {0x1d997, 0x2e8d},
335712103SSantwona.Behera@Sun.COM {0x1d998, 0x303d},
335812103SSantwona.Behera@Sun.COM {0x1d999, 0x2408},
335912103SSantwona.Behera@Sun.COM {0x1d99a, 0x35d8},
336012103SSantwona.Behera@Sun.COM {0x1d99b, 0x5dd3},
336112103SSantwona.Behera@Sun.COM {0x1d99c, 0x0307},
336212103SSantwona.Behera@Sun.COM {0x1d99d, 0x8887},
336312103SSantwona.Behera@Sun.COM {0x1d99e, 0x63a7},
336412103SSantwona.Behera@Sun.COM {0x1d99f, 0x8887},
336512103SSantwona.Behera@Sun.COM {0x1d9a0, 0x63a7},
336612103SSantwona.Behera@Sun.COM {0x1d9a1, 0xdffd},
336712103SSantwona.Behera@Sun.COM {0x1d9a2, 0x00f9},
336812103SSantwona.Behera@Sun.COM {0x1d9a3, 0x1002},
336912103SSantwona.Behera@Sun.COM {0x1d9a4, 0x866a},
337012103SSantwona.Behera@Sun.COM {0x1d9a5, 0x6138},
337112103SSantwona.Behera@Sun.COM {0x1d9a6, 0x5883},
337212103SSantwona.Behera@Sun.COM {0x1d9a7, 0x2b42},
337312103SSantwona.Behera@Sun.COM {0x1d9a8, 0x3022},
337412103SSantwona.Behera@Sun.COM {0x1d9a9, 0x1302},
337512103SSantwona.Behera@Sun.COM {0x1d9aa, 0x2ff7},
337612103SSantwona.Behera@Sun.COM {0x1d9ab, 0x3007},
337712103SSantwona.Behera@Sun.COM {0x1d9ac, 0x8785},
337812103SSantwona.Behera@Sun.COM {0x1d9ad, 0xb887},
337912103SSantwona.Behera@Sun.COM {0x1d9ae, 0x8786},
338012103SSantwona.Behera@Sun.COM {0x1d9af, 0xb8c6},
338112103SSantwona.Behera@Sun.COM {0x1d9b0, 0x5a53},
338212103SSantwona.Behera@Sun.COM {0x1d9b1, 0x2a52},
338312103SSantwona.Behera@Sun.COM {0x1d9b2, 0x3022},
338412103SSantwona.Behera@Sun.COM {0x1d9b3, 0x13c2},
338512103SSantwona.Behera@Sun.COM {0x1d9b4, 0x2474},
338612103SSantwona.Behera@Sun.COM {0x1d9b5, 0x3c84},
338712103SSantwona.Behera@Sun.COM {0x1d9b6, 0x64d7},
338812103SSantwona.Behera@Sun.COM {0x1d9b7, 0x64d7},
338912103SSantwona.Behera@Sun.COM {0x1d9b8, 0x2ff5},
339012103SSantwona.Behera@Sun.COM {0x1d9b9, 0x3c05},
339112103SSantwona.Behera@Sun.COM {0x1d9ba, 0x8757},
339212103SSantwona.Behera@Sun.COM {0x1d9bb, 0xb886},
339312103SSantwona.Behera@Sun.COM {0x1d9bc, 0x9767},
339412103SSantwona.Behera@Sun.COM {0x1d9bd, 0x67c4},
339512103SSantwona.Behera@Sun.COM {0x1d9be, 0x6f72},
339612103SSantwona.Behera@Sun.COM {0x1d9bf, 0x1002},
339712103SSantwona.Behera@Sun.COM {0x1d9c0, 0x0000},
339812103SSantwona.Behera@Sun.COM {0x1d080, 0x0100},
339912103SSantwona.Behera@Sun.COM {0x1d092, 0x0000},
340012103SSantwona.Behera@Sun.COM {NLP_INI_STOP, 0},
340112103SSantwona.Behera@Sun.COM };
340212103SSantwona.Behera@Sun.COM
340312103SSantwona.Behera@Sun.COM static nxge_status_t
nxge_nlp2020_xcvr_init(p_nxge_t nxgep)340412103SSantwona.Behera@Sun.COM nxge_nlp2020_xcvr_init(p_nxge_t nxgep)
340512103SSantwona.Behera@Sun.COM {
340612103SSantwona.Behera@Sun.COM uint8_t phy_port_addr;
340712103SSantwona.Behera@Sun.COM nxge_status_t status = NXGE_OK;
340812103SSantwona.Behera@Sun.COM uint16_t ctrl_reg, rst_val, pmd_ctl, rx_los;
340912103SSantwona.Behera@Sun.COM int i = 0, count = 1000;
341012103SSantwona.Behera@Sun.COM
341112103SSantwona.Behera@Sun.COM uint8_t connector = 0, len, lpm;
341212103SSantwona.Behera@Sun.COM p_nxge_nlp_initseq_t initseq;
341312103SSantwona.Behera@Sun.COM uint16_t dev, reg, val;
341412103SSantwona.Behera@Sun.COM
341512103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_nlp2020_xcvr_init: "
341612103SSantwona.Behera@Sun.COM "port<%d>, phyaddr[0x%x]", nxgep->mac.portnum,
341712103SSantwona.Behera@Sun.COM nxgep->statsp->mac_stats.xcvr_portn));
341812103SSantwona.Behera@Sun.COM
341912103SSantwona.Behera@Sun.COM phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
342012103SSantwona.Behera@Sun.COM
342112103SSantwona.Behera@Sun.COM /* Reset the transceiver */
342212103SSantwona.Behera@Sun.COM rst_val = ctrl_reg = NLP2020_PMA_PMD_PHY_RST;
342312103SSantwona.Behera@Sun.COM if ((status = nxge_mdio_write(nxgep, phy_port_addr,
342412103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, rst_val))
342512103SSantwona.Behera@Sun.COM != NXGE_OK)
342612103SSantwona.Behera@Sun.COM goto fail;
342712103SSantwona.Behera@Sun.COM while ((count--) && (ctrl_reg & rst_val)) {
342812103SSantwona.Behera@Sun.COM drv_usecwait(1000);
342912103SSantwona.Behera@Sun.COM (void) nxge_mdio_read(nxgep, phy_port_addr,
343012103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &ctrl_reg);
343112103SSantwona.Behera@Sun.COM }
343212103SSantwona.Behera@Sun.COM if (count == 0) {
343312103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_nlp2020_xcvr_init: "
343412103SSantwona.Behera@Sun.COM "PMA_PMD reset failed"));
343512103SSantwona.Behera@Sun.COM goto fail;
343612103SSantwona.Behera@Sun.COM }
343712103SSantwona.Behera@Sun.COM
343812103SSantwona.Behera@Sun.COM /* Set loopback mode if required */
343912103SSantwona.Behera@Sun.COM /* Set PMA PMD system loopback */
344012103SSantwona.Behera@Sun.COM if ((status = nxge_mdio_read(nxgep, phy_port_addr,
344112103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &pmd_ctl))
344212103SSantwona.Behera@Sun.COM != NXGE_OK)
344312103SSantwona.Behera@Sun.COM goto fail;
344412103SSantwona.Behera@Sun.COM
344512103SSantwona.Behera@Sun.COM if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
344612103SSantwona.Behera@Sun.COM pmd_ctl |= 0x0001;
344712103SSantwona.Behera@Sun.COM else
344812103SSantwona.Behera@Sun.COM pmd_ctl &= 0xfffe;
344912103SSantwona.Behera@Sun.COM if ((status = nxge_mdio_write(nxgep, phy_port_addr,
345012103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, pmd_ctl))
345112103SSantwona.Behera@Sun.COM != NXGE_OK)
345212103SSantwona.Behera@Sun.COM goto fail;
345312103SSantwona.Behera@Sun.COM
345412103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_nlp2020_xcvr_init: "
345512103SSantwona.Behera@Sun.COM "setting LB, wrote NLP2020_PMA_PMD_CTL_REG[0x%x]", pmd_ctl));
345612103SSantwona.Behera@Sun.COM
345712103SSantwona.Behera@Sun.COM /* Check connector details using I2c */
345812103SSantwona.Behera@Sun.COM if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
345912103SSantwona.Behera@Sun.COM QSFP_MSA_CONN_REG, &connector) == 1) {
346012103SSantwona.Behera@Sun.COM goto fail;
346112103SSantwona.Behera@Sun.COM }
346212103SSantwona.Behera@Sun.COM
346312103SSantwona.Behera@Sun.COM switch (connector) {
346412103SSantwona.Behera@Sun.COM case SFPP_FIBER:
346512103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
346612103SSantwona.Behera@Sun.COM "nxge_nlp2020_xcvr_init: SFPP_FIBER detected"));
346712103SSantwona.Behera@Sun.COM initseq = nlp2020_revC_fiber_init;
346812103SSantwona.Behera@Sun.COM nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
346912103SSantwona.Behera@Sun.COM break;
347012103SSantwona.Behera@Sun.COM case QSFP_FIBER:
347112103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
347212103SSantwona.Behera@Sun.COM "nxge_nlp2020_xcvr_init: QSFP_FIBER detected"));
347312103SSantwona.Behera@Sun.COM initseq = nlp2020_revC_fiber_init;
347412103SSantwona.Behera@Sun.COM nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
347512103SSantwona.Behera@Sun.COM break;
347612103SSantwona.Behera@Sun.COM case QSFP_COPPER_TWINAX:
347712103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
347812103SSantwona.Behera@Sun.COM "nxge_nlp2020_xcvr_init: QSFP_COPPER_TWINAX/"
347912103SSantwona.Behera@Sun.COM "SFPP_COPPER_TWINAX detected"));
348012103SSantwona.Behera@Sun.COM
348112103SSantwona.Behera@Sun.COM initseq = nlp2020_revC_copper_init;
348212103SSantwona.Behera@Sun.COM nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_LT_7M;
348312103SSantwona.Behera@Sun.COM break;
348412103SSantwona.Behera@Sun.COM default:
348512103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
348612103SSantwona.Behera@Sun.COM "nxge_nlp2020_xcvr_init: Unknown type [0x%x] detected",
348712103SSantwona.Behera@Sun.COM "...setting to QSFP_FIBER",
348812103SSantwona.Behera@Sun.COM connector));
348912103SSantwona.Behera@Sun.COM initseq = nlp2020_revC_fiber_init;
349012103SSantwona.Behera@Sun.COM nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
349112103SSantwona.Behera@Sun.COM break;
349212103SSantwona.Behera@Sun.COM }
349312103SSantwona.Behera@Sun.COM
349412103SSantwona.Behera@Sun.COM /* Run appropriate init sequence */
349512103SSantwona.Behera@Sun.COM for (i = 0; initseq[i].dev_reg != NLP_INI_STOP; i++) {
349612103SSantwona.Behera@Sun.COM dev = initseq[i].dev_reg >> 16;
349712103SSantwona.Behera@Sun.COM reg = initseq[i].dev_reg & 0xffff;
349812103SSantwona.Behera@Sun.COM val = initseq[i].val;
349912103SSantwona.Behera@Sun.COM
350012103SSantwona.Behera@Sun.COM if (reg == NLP_INI_WAIT) {
350112103SSantwona.Behera@Sun.COM drv_usecwait(1000 * val);
350212103SSantwona.Behera@Sun.COM } else {
350312103SSantwona.Behera@Sun.COM if ((status = nxge_mdio_write(nxgep, phy_port_addr,
350412103SSantwona.Behera@Sun.COM dev, reg, val)) != NXGE_OK)
350512103SSantwona.Behera@Sun.COM goto fail;
350612103SSantwona.Behera@Sun.COM }
350712103SSantwona.Behera@Sun.COM }
350812103SSantwona.Behera@Sun.COM
350912103SSantwona.Behera@Sun.COM /* rx_los inversion */
351012103SSantwona.Behera@Sun.COM if ((status = nxge_mdio_read(nxgep, phy_port_addr,
351112103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, &rx_los)) != NXGE_OK)
351212103SSantwona.Behera@Sun.COM goto fail;
351312103SSantwona.Behera@Sun.COM
351412103SSantwona.Behera@Sun.COM rx_los &= ~(NLP2020_RXLOS_ACT_H);
351512103SSantwona.Behera@Sun.COM
351612103SSantwona.Behera@Sun.COM if ((status = nxge_mdio_write(nxgep, phy_port_addr,
351712103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, rx_los)) != NXGE_OK)
351812103SSantwona.Behera@Sun.COM goto fail;
351912103SSantwona.Behera@Sun.COM
352012103SSantwona.Behera@Sun.COM if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
352112103SSantwona.Behera@Sun.COM QSFP_MSA_LEN_REG, &len) == 1) {
352212103SSantwona.Behera@Sun.COM goto fail;
352312103SSantwona.Behera@Sun.COM }
352412103SSantwona.Behera@Sun.COM
352512103SSantwona.Behera@Sun.COM if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
352612103SSantwona.Behera@Sun.COM QSFP_MSA_LPM_REG, &lpm) == 1) {
352712103SSantwona.Behera@Sun.COM goto fail;
352812103SSantwona.Behera@Sun.COM }
352912103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
353012103SSantwona.Behera@Sun.COM "nxge_nlp2020_xcvr_init: len[0x%x] lpm[0x%x]", len, lpm));
353112103SSantwona.Behera@Sun.COM
353212103SSantwona.Behera@Sun.COM if (connector == QSFP_COPPER_TWINAX) {
353312103SSantwona.Behera@Sun.COM if (len >= 7) {
353412103SSantwona.Behera@Sun.COM nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_7M_ABOVE;
353512103SSantwona.Behera@Sun.COM /* enable pre-emphasis */
353612103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
353712103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL1_REG,
353812103SSantwona.Behera@Sun.COM NLP2020_TX_DRV_CTL1_PREEMP_EN);
353912103SSantwona.Behera@Sun.COM /* write emphasis value */
354012103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
354112103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL2_REG,
354212103SSantwona.Behera@Sun.COM NLP2020_TX_DRV_CTL2_EMP_VAL);
354312103SSantwona.Behera@Sun.COM /* stop microcontroller */
354412103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
354512103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG,
354612103SSantwona.Behera@Sun.COM NLP2020_UC_CTL_STOP);
354712103SSantwona.Behera@Sun.COM /* reset program counter */
354812103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
354912103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_UC_PC_START_REG,
355012103SSantwona.Behera@Sun.COM NLP2020_UC_PC_START_VAL);
355112103SSantwona.Behera@Sun.COM /* start microcontroller */
355212103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
355312103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG,
355412103SSantwona.Behera@Sun.COM NLP2020_UC_CTL_START);
355512103SSantwona.Behera@Sun.COM }
355612103SSantwona.Behera@Sun.COM }
355712103SSantwona.Behera@Sun.COM if (lpm & QSFP_MSA_LPM_HIGH) {
355812103SSantwona.Behera@Sun.COM /* enable high power mode */
355912103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
356012103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG,
356112103SSantwona.Behera@Sun.COM NLP2020_GPIO_ACT);
356212103SSantwona.Behera@Sun.COM } else {
356312103SSantwona.Behera@Sun.COM /* revert to low power mode */
356412103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy_port_addr,
356512103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG,
356612103SSantwona.Behera@Sun.COM NLP2020_GPIO_INACT);
356712103SSantwona.Behera@Sun.COM }
3568*12452SSantwona.Behera@oracle.COM
3569*12452SSantwona.Behera@oracle.COM /*
3570*12452SSantwona.Behera@oracle.COM * Set XAUI link tunables from OBP if present.
3571*12452SSantwona.Behera@oracle.COM */
3572*12452SSantwona.Behera@oracle.COM NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
3573*12452SSantwona.Behera@oracle.COM if (status != NXGE_OK) {
3574*12452SSantwona.Behera@oracle.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3575*12452SSantwona.Behera@oracle.COM "nxge_nlp2020_xcvr_init: Failed setting PHY tunables"));
3576*12452SSantwona.Behera@oracle.COM goto fail;
3577*12452SSantwona.Behera@oracle.COM }
3578*12452SSantwona.Behera@oracle.COM
357912103SSantwona.Behera@Sun.COM /* It takes ~2s for EDC to settle */
358012103SSantwona.Behera@Sun.COM drv_usecwait(2000000);
358112103SSantwona.Behera@Sun.COM
358212103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_nlp2020_xcvr_init: "
358312103SSantwona.Behera@Sun.COM "port<%d> phyaddr[0x%x]", nxgep->mac.portnum, phy_port_addr));
358412103SSantwona.Behera@Sun.COM
358512103SSantwona.Behera@Sun.COM return (NXGE_OK);
358612103SSantwona.Behera@Sun.COM
358712103SSantwona.Behera@Sun.COM fail:
358812103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
358912103SSantwona.Behera@Sun.COM "nxge_nlp2020_xcvr_init: failed to initialize transceiver for "
359012103SSantwona.Behera@Sun.COM "port<%d>", nxgep->mac.portnum));
359112103SSantwona.Behera@Sun.COM return (status);
359212103SSantwona.Behera@Sun.COM }
359312103SSantwona.Behera@Sun.COM
nxge_is_nlp2020_phy(p_nxge_t nxgep)359412103SSantwona.Behera@Sun.COM static boolean_t nxge_is_nlp2020_phy(p_nxge_t nxgep)
359512103SSantwona.Behera@Sun.COM {
359612103SSantwona.Behera@Sun.COM uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
359712103SSantwona.Behera@Sun.COM uint32_t pcs_id = 0;
359812103SSantwona.Behera@Sun.COM uint32_t pma_pmd_id = 0;
359912103SSantwona.Behera@Sun.COM uint8_t xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
360012103SSantwona.Behera@Sun.COM
360112103SSantwona.Behera@Sun.COM pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, xcvr_addr);
360212103SSantwona.Behera@Sun.COM pcs_id = nxge_get_cl45_pcs_id(nxgep, xcvr_addr);
360312103SSantwona.Behera@Sun.COM
360412103SSantwona.Behera@Sun.COM if (((pma_pmd_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) ||
360512103SSantwona.Behera@Sun.COM ((pcs_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID)) {
360612103SSantwona.Behera@Sun.COM return (B_TRUE);
360712103SSantwona.Behera@Sun.COM } else {
360812103SSantwona.Behera@Sun.COM return (B_FALSE);
360912103SSantwona.Behera@Sun.COM }
361012103SSantwona.Behera@Sun.COM }
361112103SSantwona.Behera@Sun.COM
nxge_get_nlp2020_connector_type(p_nxge_t nxgep)361212103SSantwona.Behera@Sun.COM static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t nxgep)
361312103SSantwona.Behera@Sun.COM {
361412103SSantwona.Behera@Sun.COM uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
361512103SSantwona.Behera@Sun.COM uint8_t xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
361612103SSantwona.Behera@Sun.COM uint8_t connector = 0;
361712103SSantwona.Behera@Sun.COM
361812103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_i2c_read(nxgep, xcvr_addr, NLP2020_XCVR_I2C_ADDR,
361912103SSantwona.Behera@Sun.COM QSFP_MSA_CONN_REG, &connector);
362012103SSantwona.Behera@Sun.COM
362112103SSantwona.Behera@Sun.COM return (connector);
362212103SSantwona.Behera@Sun.COM }
362312103SSantwona.Behera@Sun.COM
nxge_set_nlp2020_param(p_nxge_t nxgep)362412103SSantwona.Behera@Sun.COM static nxge_status_t nxge_set_nlp2020_param(p_nxge_t nxgep)
362512103SSantwona.Behera@Sun.COM {
362612103SSantwona.Behera@Sun.COM uint8_t connector = 0;
362712103SSantwona.Behera@Sun.COM
362812103SSantwona.Behera@Sun.COM connector = nxge_get_nlp2020_connector_type(nxgep);
362912103SSantwona.Behera@Sun.COM
363012103SSantwona.Behera@Sun.COM switch (connector) {
363112103SSantwona.Behera@Sun.COM case SFPP_FIBER:
363212103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
363312103SSantwona.Behera@Sun.COM "nxge_set_nlp2020_param: SFPP_FIBER detected"));
363412103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_FIBER;
363512103SSantwona.Behera@Sun.COM nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
363612103SSantwona.Behera@Sun.COM break;
363712103SSantwona.Behera@Sun.COM case QSFP_FIBER:
363812103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
363912103SSantwona.Behera@Sun.COM "nxge_set_nlp2020_param: QSFP_FIBER detected"));
364012103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_FIBER;
364112103SSantwona.Behera@Sun.COM nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
364212103SSantwona.Behera@Sun.COM break;
364312103SSantwona.Behera@Sun.COM case QSFP_COPPER_TWINAX:
364412103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
364512103SSantwona.Behera@Sun.COM "nxge_set_nlp2020_param: QSFP_COPPER_TWINAX/"
364612103SSantwona.Behera@Sun.COM "SFPP_COPPER_TWINAX detected"));
364712103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_COPPER;
364812103SSantwona.Behera@Sun.COM nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
364912103SSantwona.Behera@Sun.COM break;
365012103SSantwona.Behera@Sun.COM default:
365112103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
365212103SSantwona.Behera@Sun.COM "nxge_set_nlp2020_param: Unknown type [0x%x] detected"
365312103SSantwona.Behera@Sun.COM "...setting to QSFP_FIBER",
365412103SSantwona.Behera@Sun.COM connector));
365512103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_FIBER;
365612103SSantwona.Behera@Sun.COM nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
365712103SSantwona.Behera@Sun.COM break;
365812103SSantwona.Behera@Sun.COM }
365912103SSantwona.Behera@Sun.COM
366012103SSantwona.Behera@Sun.COM return (NXGE_OK);
366112103SSantwona.Behera@Sun.COM }
366212103SSantwona.Behera@Sun.COM
36636604Ssbehera #define CHK_STAT(x) status = (x); if (status != NXGE_OK) goto fail
36646604Ssbehera
36656604Ssbehera #define MRVL88X2011_RD(nxgep, port, d, r, p) \
36666604Ssbehera CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p))
36676604Ssbehera
36686604Ssbehera #define MRVL88X2011_WR(nxgep, port, d, r, p) \
36696604Ssbehera CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p))
36706604Ssbehera
36716604Ssbehera
36726604Ssbehera static void
nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep,uint16_t rate)36736604Ssbehera nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate)
36746604Ssbehera {
36756604Ssbehera uint16_t value;
36766604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
36776604Ssbehera
36786604Ssbehera if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
36796604Ssbehera MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) {
36806604Ssbehera value &= ~MRVL_88X2011_LED_BLK_MASK;
36816604Ssbehera value |= (rate << MRVL_88X2011_LED_BLK_SHIFT);
36826604Ssbehera (void) nxge_mdio_write(nxgep, phy,
36836604Ssbehera MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL,
36846604Ssbehera value);
36856604Ssbehera }
36866604Ssbehera }
36876604Ssbehera
36886604Ssbehera static nxge_status_t
nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)36896604Ssbehera nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)
36906604Ssbehera {
36916604Ssbehera nxge_status_t status;
36926604Ssbehera pcs_control_t pcs_ctl;
36936604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
36946604Ssbehera
36956604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
36966604Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value);
36976604Ssbehera
36986604Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
36996604Ssbehera pcs_ctl.bits.loopback = 1;
37006604Ssbehera else
37016604Ssbehera pcs_ctl.bits.loopback = 0;
37026604Ssbehera
37036604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
37046604Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value);
37056604Ssbehera
37066604Ssbehera fail:
37076604Ssbehera return (status);
37086604Ssbehera }
37096604Ssbehera
37106604Ssbehera
37116604Ssbehera static void
nxge_mrvl88x2011_led(p_nxge_t nxgep,uint16_t val)37126604Ssbehera nxge_mrvl88x2011_led(p_nxge_t nxgep, uint16_t val)
37136604Ssbehera {
37146604Ssbehera uint16_t val2;
37156604Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
37166604Ssbehera
37176604Ssbehera val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
37186604Ssbehera val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT,
37196604Ssbehera MRVL_88X2011_LED_CTL_MASK);
37206604Ssbehera val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
37216604Ssbehera
37226604Ssbehera if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
37236604Ssbehera MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) {
37246604Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
37256604Ssbehera "nxge_mrvl88x2011_led: nxge_mdio_write failed!!"));
37266604Ssbehera }
37276604Ssbehera }
37286604Ssbehera
37296604Ssbehera
37306604Ssbehera static nxge_status_t
nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)37316604Ssbehera nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)
37326604Ssbehera {
37336604Ssbehera uint8_t phy;
37346604Ssbehera nxge_status_t status;
37356604Ssbehera uint16_t clk;
37366604Ssbehera
37376604Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn;
37386604Ssbehera
37396604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
37406604Ssbehera "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>",
37416604Ssbehera nxgep->mac.portnum, phy));
37426604Ssbehera
37436604Ssbehera /* Set LED functions */
37446604Ssbehera nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS);
37456604Ssbehera /* PCS activity */
37466604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT);
37476604Ssbehera
37486604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
37496604Ssbehera MRVL_88X2011_GEN_CTL, &clk);
37506604Ssbehera clk |= MRVL_88X2011_ENA_XFPREFCLK;
37516604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
37526604Ssbehera MRVL_88X2011_GEN_CTL, clk);
37536604Ssbehera
37546604Ssbehera /* Set internal loopback mode if necessary */
37556604Ssbehera
37566604Ssbehera CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep));
37576604Ssbehera
37586604Ssbehera /* Enable PMD */
37596604Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
37606604Ssbehera MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX);
37616604Ssbehera
37626604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK"));
37636604Ssbehera
37646604Ssbehera fail:
37656604Ssbehera return (status);
37666604Ssbehera }
37676604Ssbehera
37686604Ssbehera
37696604Ssbehera
37705572Ssbehera /* Initialize the 10G Transceiver */
37715572Ssbehera
37725572Ssbehera static nxge_status_t
nxge_10G_xcvr_init(p_nxge_t nxgep)37735572Ssbehera nxge_10G_xcvr_init(p_nxge_t nxgep)
37745572Ssbehera {
37755572Ssbehera p_nxge_stats_t statsp;
37766439Sml29623 p_nxge_param_t param_arr = nxgep->param_arr;
37775572Ssbehera nxge_status_t status = NXGE_OK;
37785572Ssbehera #ifdef NXGE_DEBUG
37795572Ssbehera uint8_t portn = nxgep->mac.portnum;
37805572Ssbehera #endif
37815572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
37825572Ssbehera portn));
37835572Ssbehera
37845572Ssbehera statsp = nxgep->statsp;
37855572Ssbehera
37869599Stc99174@train /* Disable Link LEDs, with or without PHY */
37879599Stc99174@train if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
37885572Ssbehera goto done;
37899599Stc99174@train
37909599Stc99174@train /* Skip MDIO, if PHY absent */
37919599Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) {
37929599Stc99174@train goto done;
37939599Stc99174@train }
37945572Ssbehera
37955572Ssbehera /* Set Clause 45 */
37965572Ssbehera npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
37975572Ssbehera
37985572Ssbehera switch (nxgep->chip_id) {
37995572Ssbehera case BCM8704_CHIP_ID:
38006835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
38015572Ssbehera "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id));
38025572Ssbehera status = nxge_BCM8704_xcvr_init(nxgep);
38035572Ssbehera break;
38045572Ssbehera case BCM8706_CHIP_ID:
38056835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
38065572Ssbehera "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id));
38075572Ssbehera status = nxge_BCM8706_xcvr_init(nxgep);
38085572Ssbehera break;
38096604Ssbehera case MRVL88X201X_CHIP_ID:
38106835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
381112103SSantwona.Behera@Sun.COM "Chip ID MRVL [0x%x] for 10G xcvr", nxgep->chip_id));
38126604Ssbehera status = nxge_mrvl88x2011_xcvr_init(nxgep);
38136604Ssbehera break;
381412103SSantwona.Behera@Sun.COM case NLP2020_CHIP_ID:
381512103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
381612103SSantwona.Behera@Sun.COM "Chip ID NL2020 [0x%x] for 10G xcvr", nxgep->chip_id));
381712103SSantwona.Behera@Sun.COM status = nxge_nlp2020_xcvr_init(nxgep);
381812103SSantwona.Behera@Sun.COM break;
38195572Ssbehera default:
38205572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: "
38215572Ssbehera "Unknown chip ID 0x%x for 10G xcvr addr[%d]",
38225572Ssbehera nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn));
38235572Ssbehera goto fail;
38245572Ssbehera }
38255572Ssbehera
38265572Ssbehera if (status != NXGE_OK) {
38275572Ssbehera goto fail;
38285572Ssbehera }
38294977Sraghus done:
38304732Sdavemq statsp->mac_stats.cap_10gfdx = 1;
38314732Sdavemq statsp->mac_stats.lp_cap_10gfdx = 1;
38326439Sml29623 statsp->mac_stats.adv_cap_asmpause =
38336439Sml29623 param_arr[param_anar_asmpause].value;
38346439Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
38354732Sdavemq
38364732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
38374732Sdavemq portn));
38384732Sdavemq return (NXGE_OK);
38394732Sdavemq
38404732Sdavemq fail:
38415572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
38424732Sdavemq "nxge_10G_xcvr_init: failed to initialize transceiver for "
38435572Ssbehera "port<%d>", nxgep->mac.portnum));
38445572Ssbehera return (NXGE_ERROR);
38454732Sdavemq }
38464732Sdavemq
38474732Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */
38484732Sdavemq
38494732Sdavemq static nxge_status_t
nxge_1G_xcvr_init(p_nxge_t nxgep)38504732Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep)
38514732Sdavemq {
38524732Sdavemq p_nxge_param_t param_arr = nxgep->param_arr;
38534732Sdavemq p_nxge_stats_t statsp = nxgep->statsp;
38544732Sdavemq nxge_status_t status = NXGE_OK;
38554732Sdavemq
38564977Sraghus if (nxgep->mac.portmode == PORT_1G_SERDES) {
38574977Sraghus statsp->mac_stats.cap_1000fdx =
38584977Sraghus param_arr[param_anar_1000fdx].value;
38594977Sraghus goto done;
38604977Sraghus }
38614977Sraghus
38624732Sdavemq /* Set Clause 22 */
38634732Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
38644732Sdavemq
38654732Sdavemq /* Set capability flags */
38664732Sdavemq statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
38674977Sraghus if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
38684977Sraghus (nxgep->mac.portmode == PORT_1G_FIBER)) {
38694977Sraghus statsp->mac_stats.cap_100fdx =
38704977Sraghus param_arr[param_anar_100fdx].value;
38714977Sraghus statsp->mac_stats.cap_10fdx =
38724977Sraghus param_arr[param_anar_10fdx].value;
38734977Sraghus }
38744732Sdavemq
38754732Sdavemq status = nxge_mii_xcvr_init(nxgep);
38764977Sraghus done:
38774732Sdavemq return (status);
38784732Sdavemq }
38794732Sdavemq
38806835Syc148097 /*
38816835Syc148097 * Although the Teranetics copper transceiver (TN1010) does not need
38826835Syc148097 * to be initialized by the driver for passing packets, this funtion
38836835Syc148097 * initializes the members of nxgep->statsp->mac_stats struct for
38846835Syc148097 * kstat based on the value of nxgep->statsp->ports_stats.lb_mode.
38856835Syc148097 * It also configures the TN1010 for PHY loopback to support SunVTS.
38866835Syc148097 *
38876835Syc148097 * TN1010 only has the option to disable advertisement for the 10G
38886835Syc148097 * mode. So we can set it to either Dual Mode or 1G Only mode but
38896835Syc148097 * can't set it to 10G Only mode.
38906835Syc148097 *
38916835Syc148097 * ndd -set command can set the following 6 speed/duplex related parameters.
38926835Syc148097 *
38936835Syc148097 * ----------------------------------------------------------------
38946835Syc148097 * ndd -set /dev/nxgeX param n kstat nxge:X | grep param
38956835Syc148097 * ----------------------------------------------------------------
38966835Syc148097 * adv_autoneg_cap kstat nxge:1 | grep adv_cap_autoneg
38976835Syc148097 * adv_10gfdx_cap
38986835Syc148097 * adv_1000fdx_cap kstat nxge:1 | grep adv_cap_1000fdx
38996835Syc148097 * adv_100fdx_cap kstat nxge:1 | grep adv_cap_100fdx
39006835Syc148097 * adv_10fdx_cap kstat nxge:1 | grep adv_cap_10fdx
39016835Syc148097 * adv_pause_cap kstat nxge:1 | grep adv_cap_pause
39026835Syc148097 * ----------------------------------------------------------------
39036835Syc148097 */
39046835Syc148097 static nxge_status_t
nxge_tn1010_xcvr_init(p_nxge_t nxgep)39056835Syc148097 nxge_tn1010_xcvr_init(p_nxge_t nxgep)
39066835Syc148097 {
39076835Syc148097 p_nxge_param_t param_arr;
39086835Syc148097 p_nxge_stats_t statsp;
39096835Syc148097 tn1010_pcs_ctrl_t tn1010_pcs_ctrl;
39106835Syc148097 uint16_t speed;
39116835Syc148097 uint8_t phy_port_addr;
39126835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
39136835Syc148097 int status = NXGE_OK;
39146835Syc148097
39156835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init"));
39166835Syc148097
39176835Syc148097 param_arr = nxgep->param_arr;
39186835Syc148097 statsp = nxgep->statsp;
39196835Syc148097
39206835Syc148097 /*
39216835Syc148097 * Initialize the xcvr statistics which are NOT controlled by ndd
39226835Syc148097 */
39236835Syc148097 statsp->mac_stats.cap_autoneg = 1; /* TN1010 autoneg is always on */
39246835Syc148097 statsp->mac_stats.cap_100T4 = 0;
39256835Syc148097
39266835Syc148097 /*
39276835Syc148097 * Read the TN1010 link speed and initialize capabilities kstat. Note
39286835Syc148097 * that function nxge_check_tn1010_link repeatedly invoked by the
39296835Syc148097 * timer will update link_speed real time.
39306835Syc148097 */
39316835Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) {
39326835Syc148097 goto fail;
39336835Syc148097 }
39346835Syc148097 if (speed == TN1010_SPEED_1G) {
39356835Syc148097 statsp->mac_stats.cap_10gfdx = 0;
39366835Syc148097 } else {
39376835Syc148097 statsp->mac_stats.cap_10gfdx = 1;
39386835Syc148097 }
39396835Syc148097
39406835Syc148097 /* Whether we are in 1G or 10G mode, we always have the 1G capability */
39416835Syc148097 statsp->mac_stats.cap_1000fdx = 1;
39426835Syc148097
39436835Syc148097 /* TN1010 is not able to operate in the following states */
39446835Syc148097 statsp->mac_stats.cap_1000hdx = 0;
39456835Syc148097 statsp->mac_stats.cap_100fdx = 0;
39466835Syc148097 statsp->mac_stats.cap_100hdx = 0;
39476835Syc148097 statsp->mac_stats.cap_10fdx = 0;
39486835Syc148097 statsp->mac_stats.cap_10hdx = 0;
39496835Syc148097
39506835Syc148097 /* param_anar_pause can be modified by ndd -set */
39516835Syc148097 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
39526835Syc148097
39536835Syc148097 /*
39546835Syc148097 * The following 4 lines actually overwrites what ever the ndd command
39556835Syc148097 * has set. For example, by command
39566835Syc148097 * ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1)
39576835Syc148097 * we could set param_arr[param_autoneg].value to n. However, because
39586835Syc148097 * here we assign constants to these parameters, whatever we set with
39596835Syc148097 * the "ndd -set" command will be replaced. So command
39606835Syc148097 * kstat nxge:X | grep param
39616835Syc148097 * will always show those constant values. In other words, the
39626835Syc148097 * "ndd -set" command can NOT change the values of these 4 parameters
39636835Syc148097 * even though the command appears to be successful.
39646835Syc148097 *
39656835Syc148097 * Note: TN1010 auto negotiation is always enabled.
39666835Syc148097 */
39676835Syc148097 statsp->mac_stats.adv_cap_autoneg
39686835Syc148097 = param_arr[param_autoneg].value = 1;
39696835Syc148097 statsp->mac_stats.adv_cap_1000fdx
39706835Syc148097 = param_arr[param_anar_1000fdx].value = 1;
39716835Syc148097 statsp->mac_stats.adv_cap_100fdx
39726835Syc148097 = param_arr[param_anar_100fdx].value = 0;
39736835Syc148097 statsp->mac_stats.adv_cap_10fdx
39746835Syc148097 = param_arr[param_anar_10fdx].value = 0;
39756835Syc148097
39766835Syc148097 /*
39776835Syc148097 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as
39786835Syc148097 * defined in nxge_param_arr[], therefore they are not seen by the
39796835Syc148097 * "ndd -get" command and can not be changed by ndd. We just set
39806835Syc148097 * them (both ndd param and kstat values) to constant 0 because TN1010
39816835Syc148097 * does not support those speeds.
39826835Syc148097 */
39836835Syc148097 statsp->mac_stats.adv_cap_100T4
39846835Syc148097 = param_arr[param_anar_100T4].value = 0;
39856835Syc148097 statsp->mac_stats.adv_cap_1000hdx
39866835Syc148097 = param_arr[param_anar_1000hdx].value = 0;
39876835Syc148097 statsp->mac_stats.adv_cap_100hdx
39886835Syc148097 = param_arr[param_anar_100hdx].value = 0;
39896835Syc148097 statsp->mac_stats.adv_cap_10hdx
39906835Syc148097 = param_arr[param_anar_10hdx].value = 0;
39916835Syc148097
39926835Syc148097 /*
39936835Syc148097 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified
39946835Syc148097 * by ndd
39956835Syc148097 */
39966835Syc148097 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
39976835Syc148097
39986835Syc148097 /*
39996835Syc148097 * nxge_param_arr[] defines the adv_cap_asmpause with type
40006835Syc148097 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the
40016835Syc148097 * "ndd -get" command and can not be changed by ndd. Here we do not
40026835Syc148097 * assign a constant to it so the default value defined in
40036835Syc148097 * nxge_param_arr[] will be used to set the parameter and
40046835Syc148097 * will be shown by the kstat.
40056835Syc148097 */
40066835Syc148097 statsp->mac_stats.adv_cap_asmpause
40076835Syc148097 = param_arr[param_anar_asmpause].value;
40086835Syc148097
40096835Syc148097 /*
40106835Syc148097 * Initialize the link statistics.
40116835Syc148097 */
40126835Syc148097 statsp->mac_stats.link_T4 = 0;
40136835Syc148097 statsp->mac_stats.link_asmpause = 0;
40146835Syc148097 statsp->mac_stats.link_pause = 0;
40156835Syc148097 if (speed == TN1010_SPEED_1G) {
40166835Syc148097 statsp->mac_stats.link_speed = 1000;
40176835Syc148097 statsp->mac_stats.link_duplex = 2; /* Full duplex */
40186835Syc148097 statsp->mac_stats.link_up = 1;
40196835Syc148097 } else {
40206835Syc148097 statsp->mac_stats.link_speed = 10000;
40216835Syc148097 statsp->mac_stats.link_duplex = 2;
40226835Syc148097 statsp->mac_stats.link_up = 1;
40236835Syc148097 }
40246835Syc148097
40256835Syc148097 /*
40266835Syc148097 * Because TN1010 does not have a link partner register, to
40276835Syc148097 * figure out the link partner's capabilities is tricky. Here we
40286835Syc148097 * just set the kstat based on our knowledge about the partner
40296835Syc148097 * (The partner must support auto-neg because auto-negotiation
40306835Syc148097 * has completed, it must support 1G or 10G because that is the
40316835Syc148097 * negotiated speed we are using.)
40326835Syc148097 *
40336835Syc148097 * Note: Current kstat does not show lp_cap_10gfdx and
40346835Syc148097 * lp_cap_10ghdx.
40356835Syc148097 */
40366835Syc148097 if (speed == TN1010_SPEED_1G) {
40376835Syc148097 statsp->mac_stats.lp_cap_1000fdx = 1;
40386835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0;
40396835Syc148097 } else {
40406835Syc148097 statsp->mac_stats.lp_cap_1000fdx = 0;
40416835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 1;
40426835Syc148097 }
40436835Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0;
40446835Syc148097 statsp->mac_stats.lp_cap_1000hdx = 0;
40456835Syc148097 statsp->mac_stats.lp_cap_100fdx = 0;
40466835Syc148097 statsp->mac_stats.lp_cap_100hdx = 0;
40476835Syc148097 statsp->mac_stats.lp_cap_10fdx = 0;
40486835Syc148097 statsp->mac_stats.lp_cap_10hdx = 0;
40496835Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0;
40506835Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0;
40516835Syc148097 statsp->mac_stats.lp_cap_100T4 = 0;
40526835Syc148097 statsp->mac_stats.lp_cap_autoneg = 1;
40536835Syc148097 statsp->mac_stats.lp_cap_asmpause = 0;
40546835Syc148097 statsp->mac_stats.lp_cap_pause = 0;
40556835Syc148097
40566835Syc148097 /* Handle PHY loopback for SunVTS loopback test */
40576835Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
40586835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
40596835Syc148097
40606835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr,
40616835Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
40626835Syc148097 &tn1010_pcs_ctrl.value)) != NXGE_OK) {
40636835Syc148097 goto fail;
40646835Syc148097 }
40656835Syc148097 if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) ||
40666835Syc148097 (statsp->port_stats.lb_mode == nxge_lb_phy10g)) {
40676835Syc148097 tn1010_pcs_ctrl.bits.loopback = 1;
40686835Syc148097 } else {
40696835Syc148097 tn1010_pcs_ctrl.bits.loopback = 0;
40706835Syc148097 }
40716835Syc148097 if ((status = nxge_mdio_write(nxgep, phy_port_addr,
40726835Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
40736835Syc148097 tn1010_pcs_ctrl.value)) != NXGE_OK) {
40746835Syc148097 goto fail;
40756835Syc148097 }
40766835Syc148097
40776835Syc148097 statsp->mac_stats.xcvr_inits++;
40786835Syc148097
40796835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
40806835Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
40816835Syc148097 return (status);
40826835Syc148097 fail:
40836835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
40846835Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
40856835Syc148097 return (status);
40866835Syc148097 }
40876835Syc148097
40884732Sdavemq /* Initialize transceiver */
40894732Sdavemq
40904732Sdavemq nxge_status_t
nxge_xcvr_init(p_nxge_t nxgep)40914732Sdavemq nxge_xcvr_init(p_nxge_t nxgep)
40924732Sdavemq {
40934732Sdavemq p_nxge_stats_t statsp;
40944732Sdavemq #ifdef NXGE_DEBUG
40954732Sdavemq uint8_t portn;
40964732Sdavemq #endif
40974732Sdavemq
40984732Sdavemq nxge_status_t status = NXGE_OK;
40994732Sdavemq #ifdef NXGE_DEBUG
41004732Sdavemq portn = nxgep->mac.portnum;
41014732Sdavemq #endif
41023859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
41033859Sml29623 statsp = nxgep->statsp;
41043859Sml29623
41053859Sml29623 /*
41066835Syc148097 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will
41076835Syc148097 * modify mac_stats.
41083859Sml29623 */
41093859Sml29623 statsp->mac_stats.cap_autoneg = 0;
41103859Sml29623 statsp->mac_stats.cap_100T4 = 0;
41113859Sml29623 statsp->mac_stats.cap_100fdx = 0;
41123859Sml29623 statsp->mac_stats.cap_100hdx = 0;
41133859Sml29623 statsp->mac_stats.cap_10fdx = 0;
41143859Sml29623 statsp->mac_stats.cap_10hdx = 0;
41153859Sml29623 statsp->mac_stats.cap_asmpause = 0;
41163859Sml29623 statsp->mac_stats.cap_pause = 0;
41173859Sml29623 statsp->mac_stats.cap_1000fdx = 0;
41183859Sml29623 statsp->mac_stats.cap_1000hdx = 0;
41193859Sml29623 statsp->mac_stats.cap_10gfdx = 0;
41203859Sml29623 statsp->mac_stats.cap_10ghdx = 0;
41213859Sml29623
41223859Sml29623 /*
41233859Sml29623 * Initialize the link statistics.
41243859Sml29623 */
41253859Sml29623 statsp->mac_stats.link_T4 = 0;
41263859Sml29623 statsp->mac_stats.link_asmpause = 0;
41273859Sml29623 statsp->mac_stats.link_pause = 0;
41283859Sml29623
41294732Sdavemq if (nxgep->xcvr.xcvr_init) {
41304732Sdavemq status = nxgep->xcvr.xcvr_init(nxgep);
41313859Sml29623 if (status != NXGE_OK)
41323859Sml29623 goto fail;
41334732Sdavemq statsp->mac_stats.xcvr_inits++;
41343859Sml29623 }
41353859Sml29623
41364732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
41374732Sdavemq portn));
41383859Sml29623 return (NXGE_OK);
41393859Sml29623
41403859Sml29623 fail:
41413859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41424732Sdavemq "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
41434732Sdavemq portn));
41443859Sml29623 return (status);
41453859Sml29623 }
41463859Sml29623
41474977Sraghus /* Look for transceiver type */
41484977Sraghus
41494977Sraghus nxge_status_t
nxge_xcvr_find(p_nxge_t nxgep)41504977Sraghus nxge_xcvr_find(p_nxge_t nxgep)
41514977Sraghus {
41525196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>",
41535196Ssbehera nxgep->mac.portnum));
41544977Sraghus
41554977Sraghus if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
41564977Sraghus return (NXGE_ERROR);
41574977Sraghus
41584977Sraghus if (nxge_setup_xcvr_table(nxgep) != NXGE_OK)
41594977Sraghus return (NXGE_ERROR);
41604977Sraghus
41614977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
41624977Sraghus nxgep->statsp->mac_stats.xcvr_inuse));
41634977Sraghus return (NXGE_OK);
41644977Sraghus }
41653859Sml29623
41663859Sml29623 /* Initialize the TxMAC sub-block */
41673859Sml29623
41683859Sml29623 nxge_status_t
nxge_tx_mac_init(p_nxge_t nxgep)41693859Sml29623 nxge_tx_mac_init(p_nxge_t nxgep)
41703859Sml29623 {
41713859Sml29623 npi_attr_t ap;
41723859Sml29623 uint8_t portn;
41733859Sml29623 nxge_port_mode_t portmode;
41743859Sml29623 nxge_port_t portt;
41753859Sml29623 npi_handle_t handle;
41763859Sml29623 npi_status_t rs = NPI_SUCCESS;
41773859Sml29623
41783859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
41793859Sml29623 portt = nxgep->mac.porttype;
41803859Sml29623 handle = nxgep->npi_handle;
41813859Sml29623 portmode = nxgep->mac.portmode;
41823859Sml29623
41833859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
41846929Smisaki portn));
41853859Sml29623 /* Set Max and Min Frame Size */
41866439Sml29623 /*
41876439Sml29623 * Use maxframesize to configure the hardware maxframe size
41886835Syc148097 * and minframesize to configure the hardware minframe size.
41896439Sml29623 */
41906439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41916439Sml29623 "==> nxge_tx_mac_init: port<%d> "
41926439Sml29623 "min framesize %d max framesize %d ",
41936439Sml29623 nxgep->mac.minframesize,
41946439Sml29623 nxgep->mac.maxframesize,
41956439Sml29623 portn));
41966439Sml29623
41976439Sml29623 SET_MAC_ATTR2(handle, ap, portn,
41986439Sml29623 MAC_PORT_FRAME_SIZE,
41996439Sml29623 nxgep->mac.minframesize,
42006439Sml29623 nxgep->mac.maxframesize,
42016439Sml29623 rs);
42023859Sml29623 if (rs != NPI_SUCCESS)
42033859Sml29623 goto fail;
42043859Sml29623
42053859Sml29623 if (portt == PORT_TYPE_XMAC) {
42063859Sml29623 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
42076929Smisaki 0)) != NPI_SUCCESS)
42083859Sml29623 goto fail;
42093859Sml29623 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
42103859Sml29623 if ((portmode == PORT_10G_FIBER) ||
42114977Sraghus (portmode == PORT_10G_COPPER) ||
42126835Syc148097 (portmode == PORT_10G_TN1010) ||
42139599Stc99174@train (portmode == PORT_HSP_MODE) ||
42144977Sraghus (portmode == PORT_10G_SERDES)) {
42153859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
42166929Smisaki XGMII_IPG_12_15, rs);
42173859Sml29623 if (rs != NPI_SUCCESS)
42183859Sml29623 goto fail;
42193859Sml29623 nxgep->mac.ipg[0] = XGMII_IPG_12_15;
42203859Sml29623 } else {
42213859Sml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
42226929Smisaki MII_GMII_IPG_12, rs);
42233859Sml29623 if (rs != NPI_SUCCESS)
42243859Sml29623 goto fail;
42253859Sml29623 nxgep->mac.ipg[0] = MII_GMII_IPG_12;
42263859Sml29623 }
42273859Sml29623 if ((rs = npi_xmac_tx_config(handle, INIT, portn,
42286929Smisaki CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
42293859Sml29623 goto fail;
42303859Sml29623 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
42313859Sml29623 nxgep->mac.maxburstsize = 0; /* not programmable */
42323859Sml29623 nxgep->mac.ctrltype = 0; /* not programmable */
42333859Sml29623 nxgep->mac.pa_size = 0; /* not programmable */
42343859Sml29623
42353859Sml29623 if ((rs = npi_xmac_zap_tx_counters(handle, portn))
42366929Smisaki != NPI_SUCCESS)
42373859Sml29623 goto fail;
42383859Sml29623
42393859Sml29623 } else {
42403859Sml29623 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
42416929Smisaki 0)) != NPI_SUCCESS)
42423859Sml29623 goto fail;
42433859Sml29623 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
42443859Sml29623
42453859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
42466929Smisaki rs);
42473859Sml29623 if (rs != NPI_SUCCESS)
42483859Sml29623 goto fail;
42493859Sml29623 nxgep->mac.ctrltype = 0x8808;
42503859Sml29623
42513859Sml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
42523859Sml29623 if (rs != NPI_SUCCESS)
42533859Sml29623 goto fail;
42543859Sml29623 nxgep->mac.pa_size = 0x7;
42553859Sml29623
42563859Sml29623 if ((rs = npi_bmac_tx_config(handle, INIT, portn,
42576929Smisaki CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
42583859Sml29623 goto fail;
42593859Sml29623 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
42603859Sml29623 }
42613859Sml29623
42623859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
42636929Smisaki portn));
42643859Sml29623
42653859Sml29623 return (NXGE_OK);
42663859Sml29623 fail:
42673859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
42686929Smisaki "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn));
42693859Sml29623
42703859Sml29623 return (NXGE_ERROR | rs);
42713859Sml29623 }
42723859Sml29623
427311878SVenu.Iyer@Sun.COM static npi_status_t
nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep)427411878SVenu.Iyer@Sun.COM nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep)
427511878SVenu.Iyer@Sun.COM {
427611878SVenu.Iyer@Sun.COM uint32_t i;
427711878SVenu.Iyer@Sun.COM uint16_t hashtab_e;
427811878SVenu.Iyer@Sun.COM p_hash_filter_t hash_filter;
427911878SVenu.Iyer@Sun.COM uint8_t portn;
428011878SVenu.Iyer@Sun.COM npi_handle_t handle;
428111878SVenu.Iyer@Sun.COM npi_status_t rs = NPI_SUCCESS;
428211878SVenu.Iyer@Sun.COM
428311878SVenu.Iyer@Sun.COM portn = NXGE_GET_PORT_NUM(nxgep->function_num);
428411878SVenu.Iyer@Sun.COM handle = nxgep->npi_handle;
428511878SVenu.Iyer@Sun.COM
428611878SVenu.Iyer@Sun.COM /*
428711878SVenu.Iyer@Sun.COM * Load the multicast hash filter bits.
428811878SVenu.Iyer@Sun.COM */
428911878SVenu.Iyer@Sun.COM hash_filter = nxgep->hash_filter;
429011878SVenu.Iyer@Sun.COM for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
429111878SVenu.Iyer@Sun.COM if (hash_filter != NULL) {
429211878SVenu.Iyer@Sun.COM hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
429311878SVenu.Iyer@Sun.COM (NMCFILTER_REGS - 1) - i];
429411878SVenu.Iyer@Sun.COM } else {
429511878SVenu.Iyer@Sun.COM hashtab_e = 0;
429611878SVenu.Iyer@Sun.COM }
429711878SVenu.Iyer@Sun.COM
429811878SVenu.Iyer@Sun.COM if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
429911878SVenu.Iyer@Sun.COM (uint16_t *)&hashtab_e)) != NPI_SUCCESS)
430011878SVenu.Iyer@Sun.COM return (rs);
430111878SVenu.Iyer@Sun.COM }
430211878SVenu.Iyer@Sun.COM
430311878SVenu.Iyer@Sun.COM return (NPI_SUCCESS);
430411878SVenu.Iyer@Sun.COM }
430511878SVenu.Iyer@Sun.COM
430611878SVenu.Iyer@Sun.COM /*
430711878SVenu.Iyer@Sun.COM * Initialize the RxMAC sub-block
430811878SVenu.Iyer@Sun.COM */
43093859Sml29623 nxge_status_t
nxge_rx_mac_init(p_nxge_t nxgep)43103859Sml29623 nxge_rx_mac_init(p_nxge_t nxgep)
43113859Sml29623 {
43123859Sml29623 npi_attr_t ap;
43133859Sml29623 nxge_port_t portt;
43143859Sml29623 uint8_t portn;
43153859Sml29623 npi_handle_t handle;
43163859Sml29623 npi_status_t rs = NPI_SUCCESS;
43173859Sml29623 uint16_t *addr16p;
43183859Sml29623 uint16_t addr0, addr1, addr2;
43193859Sml29623 xmac_rx_config_t xconfig;
43203859Sml29623 bmac_rx_config_t bconfig;
43213859Sml29623
43223859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
43233859Sml29623
43243859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
43256929Smisaki portn));
43263859Sml29623 handle = nxgep->npi_handle;
43273859Sml29623 portt = nxgep->mac.porttype;
43283859Sml29623
43293859Sml29623 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
43303859Sml29623 addr0 = ntohs(addr16p[2]);
43313859Sml29623 addr1 = ntohs(addr16p[1]);
43323859Sml29623 addr2 = ntohs(addr16p[0]);
433311878SVenu.Iyer@Sun.COM SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR,
433411878SVenu.Iyer@Sun.COM addr0, addr1, addr2, rs);
43353859Sml29623 if (rs != NPI_SUCCESS)
43363859Sml29623 goto fail;
43373859Sml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
43383859Sml29623 if (rs != NPI_SUCCESS)
43393859Sml29623 goto fail;
43403859Sml29623 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
43413859Sml29623 if (rs != NPI_SUCCESS)
43423859Sml29623 goto fail;
43433859Sml29623
434411878SVenu.Iyer@Sun.COM rs = nxge_rx_mac_mcast_hash_table(nxgep);
434511878SVenu.Iyer@Sun.COM if (rs != NPI_SUCCESS)
434611878SVenu.Iyer@Sun.COM goto fail;
43473859Sml29623
43483859Sml29623 if (portt == PORT_TYPE_XMAC) {
43493859Sml29623 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
43506929Smisaki 0)) != NPI_SUCCESS)
43513859Sml29623 goto fail;
43523859Sml29623 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
43533859Sml29623
43543859Sml29623 (void) nxge_fflp_init_hostinfo(nxgep);
43553859Sml29623
43563859Sml29623 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
43576929Smisaki CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
43586929Smisaki ~CFG_XMAC_RX_STRIP_CRC;
43593859Sml29623
43603859Sml29623 if (nxgep->filter.all_phys_cnt != 0)
43613859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUS;
43623859Sml29623 if (nxgep->filter.all_multicast_cnt != 0)
43633859Sml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
43643859Sml29623
43653859Sml29623 xconfig |= CFG_XMAC_RX_HASH_FILTER;
43663859Sml29623
436711878SVenu.Iyer@Sun.COM if ((rs = npi_xmac_rx_config(handle, INIT,
436811878SVenu.Iyer@Sun.COM portn, xconfig)) != NPI_SUCCESS)
43693859Sml29623 goto fail;
43703859Sml29623 nxgep->mac.rx_config = xconfig;
43713859Sml29623
437211878SVenu.Iyer@Sun.COM /*
437311878SVenu.Iyer@Sun.COM * Comparison of mac unique address is always
437411878SVenu.Iyer@Sun.COM * enabled on XMAC
437511878SVenu.Iyer@Sun.COM */
43763859Sml29623 if ((rs = npi_xmac_zap_rx_counters(handle, portn))
43776929Smisaki != NPI_SUCCESS)
43783859Sml29623 goto fail;
43793859Sml29623 } else {
43803859Sml29623 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
43816929Smisaki 0) != NPI_SUCCESS)
43823859Sml29623 goto fail;
438311878SVenu.Iyer@Sun.COM
43843859Sml29623 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
43853859Sml29623
438611878SVenu.Iyer@Sun.COM (void) nxge_fflp_init_hostinfo(nxgep);
438711878SVenu.Iyer@Sun.COM
43883859Sml29623 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
43896929Smisaki ~CFG_BMAC_RX_STRIP_CRC;
43903859Sml29623
43913859Sml29623 if (nxgep->filter.all_phys_cnt != 0)
43923859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUS;
43933859Sml29623 if (nxgep->filter.all_multicast_cnt != 0)
43943859Sml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
43953859Sml29623
43963859Sml29623 bconfig |= CFG_BMAC_RX_HASH_FILTER;
439711878SVenu.Iyer@Sun.COM if ((rs = npi_bmac_rx_config(handle, INIT,
439811878SVenu.Iyer@Sun.COM portn, bconfig)) != NPI_SUCCESS)
43993859Sml29623 goto fail;
44003859Sml29623 nxgep->mac.rx_config = bconfig;
44013859Sml29623
440211878SVenu.Iyer@Sun.COM /*
440311878SVenu.Iyer@Sun.COM * Always enable comparison of mac unique address
440411878SVenu.Iyer@Sun.COM */
440511878SVenu.Iyer@Sun.COM if ((rs = npi_mac_altaddr_enable(handle,
440611878SVenu.Iyer@Sun.COM portn, 0)) != NPI_SUCCESS)
44073859Sml29623 goto fail;
44083859Sml29623 }
44093859Sml29623
44103859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
44116929Smisaki portn));
44123859Sml29623
44133859Sml29623 return (NXGE_OK);
44143859Sml29623
44153859Sml29623 fail:
44163859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44176929Smisaki "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn));
44183859Sml29623
44193859Sml29623 return (NXGE_ERROR | rs);
44203859Sml29623 }
44213859Sml29623
44223859Sml29623 /* Enable TXMAC */
44233859Sml29623
44243859Sml29623 nxge_status_t
nxge_tx_mac_enable(p_nxge_t nxgep)44253859Sml29623 nxge_tx_mac_enable(p_nxge_t nxgep)
44263859Sml29623 {
44273859Sml29623 npi_handle_t handle;
44283859Sml29623 npi_status_t rs = NPI_SUCCESS;
44293859Sml29623 nxge_status_t status = NXGE_OK;
44303859Sml29623
44313859Sml29623 handle = nxgep->npi_handle;
44323859Sml29623
44333859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
44346929Smisaki nxgep->mac.portnum));
44353859Sml29623
44363859Sml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
44373859Sml29623 goto fail;
44383859Sml29623
44393859Sml29623 /* based on speed */
44403859Sml29623 nxgep->msg_min = ETHERMIN;
44413859Sml29623
44423859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44433859Sml29623 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
44446929Smisaki CFG_XMAC_TX)) != NPI_SUCCESS)
44453859Sml29623 goto fail;
44463859Sml29623 } else {
44473859Sml29623 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
44486929Smisaki CFG_BMAC_TX)) != NPI_SUCCESS)
44493859Sml29623 goto fail;
44503859Sml29623 }
44513859Sml29623
44523859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
44536929Smisaki nxgep->mac.portnum));
44543859Sml29623
44553859Sml29623 return (NXGE_OK);
44563859Sml29623 fail:
44573859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44586929Smisaki "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
44596929Smisaki nxgep->mac.portnum));
44603859Sml29623 if (rs != NPI_SUCCESS)
44613859Sml29623 return (NXGE_ERROR | rs);
44623859Sml29623 else
44633859Sml29623 return (status);
44643859Sml29623 }
44653859Sml29623
44663859Sml29623 /* Disable TXMAC */
44673859Sml29623
44683859Sml29623 nxge_status_t
nxge_tx_mac_disable(p_nxge_t nxgep)44693859Sml29623 nxge_tx_mac_disable(p_nxge_t nxgep)
44703859Sml29623 {
44713859Sml29623 npi_handle_t handle;
44723859Sml29623 npi_status_t rs = NPI_SUCCESS;
44733859Sml29623
44746495Sspeer if (isLDOMguest(nxgep))
44756495Sspeer return (NXGE_OK);
44766495Sspeer
44773859Sml29623 handle = nxgep->npi_handle;
44783859Sml29623
44793859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
44806929Smisaki nxgep->mac.portnum));
44813859Sml29623
44823859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44833859Sml29623 if ((rs = npi_xmac_tx_config(handle, DISABLE,
44846929Smisaki nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
44853859Sml29623 goto fail;
44863859Sml29623 } else {
44873859Sml29623 if ((rs = npi_bmac_tx_config(handle, DISABLE,
44886929Smisaki nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
44893859Sml29623 goto fail;
44903859Sml29623 }
44913859Sml29623
44923859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
44936929Smisaki nxgep->mac.portnum));
44943859Sml29623 return (NXGE_OK);
44953859Sml29623 fail:
44963859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44976929Smisaki "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
44986929Smisaki nxgep->mac.portnum));
44993859Sml29623 return (NXGE_ERROR | rs);
45003859Sml29623 }
45013859Sml29623
45023859Sml29623 /* Enable RXMAC */
45033859Sml29623
45043859Sml29623 nxge_status_t
nxge_rx_mac_enable(p_nxge_t nxgep)45053859Sml29623 nxge_rx_mac_enable(p_nxge_t nxgep)
45063859Sml29623 {
45073859Sml29623 npi_handle_t handle;
45083859Sml29623 uint8_t portn;
45093859Sml29623 npi_status_t rs = NPI_SUCCESS;
45103859Sml29623 nxge_status_t status = NXGE_OK;
45113859Sml29623
45126495Sspeer /* This is a service-domain-only activity. */
45136495Sspeer if (isLDOMguest(nxgep))
45146495Sspeer return (status);
45156495Sspeer
45163859Sml29623 handle = nxgep->npi_handle;
45173859Sml29623 portn = nxgep->mac.portnum;
45183859Sml29623
45193859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
45206929Smisaki portn));
45213859Sml29623
45223859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
45233859Sml29623 goto fail;
45243859Sml29623
45253859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
45263859Sml29623 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
45276495Sspeer CFG_XMAC_RX)) != NPI_SUCCESS)
45283859Sml29623 goto fail;
45293859Sml29623 } else {
45303859Sml29623 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
45316495Sspeer CFG_BMAC_RX)) != NPI_SUCCESS)
45323859Sml29623 goto fail;
45333859Sml29623 }
45343859Sml29623
45356495Sspeer NXGE_DEBUG_MSG((nxgep, MAC_CTL,
45366495Sspeer "<== nxge_rx_mac_enable: port<%d>", portn));
45373859Sml29623
45383859Sml29623 return (NXGE_OK);
45393859Sml29623 fail:
45403859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
45416495Sspeer "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn));
45423859Sml29623
45433859Sml29623 if (rs != NPI_SUCCESS)
45443859Sml29623 return (NXGE_ERROR | rs);
45453859Sml29623 else
45463859Sml29623 return (status);
45473859Sml29623 }
45483859Sml29623
45493859Sml29623 /* Disable RXMAC */
45503859Sml29623
45513859Sml29623 nxge_status_t
nxge_rx_mac_disable(p_nxge_t nxgep)45523859Sml29623 nxge_rx_mac_disable(p_nxge_t nxgep)
45533859Sml29623 {
45543859Sml29623 npi_handle_t handle;
45553859Sml29623 uint8_t portn;
45563859Sml29623 npi_status_t rs = NPI_SUCCESS;
45573859Sml29623
45586495Sspeer /* If we are a guest domain driver, don't bother. */
45596495Sspeer if (isLDOMguest(nxgep))
45606495Sspeer return (NXGE_OK);
45616495Sspeer
45623859Sml29623 handle = nxgep->npi_handle;
45633859Sml29623 portn = nxgep->mac.portnum;
45643859Sml29623
45653859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
45666929Smisaki portn));
45673859Sml29623
45683859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
45693859Sml29623 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
45706929Smisaki CFG_XMAC_RX)) != NPI_SUCCESS)
45713859Sml29623 goto fail;
45723859Sml29623 } else {
45733859Sml29623 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
45746929Smisaki CFG_BMAC_RX)) != NPI_SUCCESS)
45753859Sml29623 goto fail;
45763859Sml29623 }
45773859Sml29623
45783859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
45796929Smisaki portn));
45803859Sml29623 return (NXGE_OK);
45813859Sml29623 fail:
45823859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
45836929Smisaki "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn));
45843859Sml29623
45853859Sml29623 return (NXGE_ERROR | rs);
45863859Sml29623 }
45873859Sml29623
45883859Sml29623 /* Reset TXMAC */
45893859Sml29623
45903859Sml29623 nxge_status_t
nxge_tx_mac_reset(p_nxge_t nxgep)45913859Sml29623 nxge_tx_mac_reset(p_nxge_t nxgep)
45923859Sml29623 {
45933859Sml29623 npi_handle_t handle;
45943859Sml29623 uint8_t portn;
45953859Sml29623 npi_status_t rs = NPI_SUCCESS;
45963859Sml29623
45973859Sml29623 handle = nxgep->npi_handle;
45983859Sml29623 portn = nxgep->mac.portnum;
45993859Sml29623
46003859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
46016929Smisaki portn));
46023859Sml29623
46033859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
46043859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
46053859Sml29623 != NPI_SUCCESS)
46063859Sml29623 goto fail;
46073859Sml29623 } else {
46083859Sml29623 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
46096929Smisaki != NPI_SUCCESS)
46103859Sml29623 goto fail;
46113859Sml29623 }
46123859Sml29623
46133859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
46146929Smisaki portn));
46153859Sml29623
46163859Sml29623 return (NXGE_OK);
46173859Sml29623 fail:
46183859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46196929Smisaki "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn));
46203859Sml29623
46213859Sml29623 return (NXGE_ERROR | rs);
46223859Sml29623 }
46233859Sml29623
46243859Sml29623 /* Reset RXMAC */
46253859Sml29623
46263859Sml29623 nxge_status_t
nxge_rx_mac_reset(p_nxge_t nxgep)46273859Sml29623 nxge_rx_mac_reset(p_nxge_t nxgep)
46283859Sml29623 {
46293859Sml29623 npi_handle_t handle;
46303859Sml29623 uint8_t portn;
46313859Sml29623 npi_status_t rs = NPI_SUCCESS;
46323859Sml29623
46333859Sml29623 handle = nxgep->npi_handle;
46343859Sml29623 portn = nxgep->mac.portnum;
46353859Sml29623
46363859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
46376929Smisaki portn));
46383859Sml29623
46393859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
46403859Sml29623 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
46413859Sml29623 != NPI_SUCCESS)
46423859Sml29623 goto fail;
46433859Sml29623 } else {
46443859Sml29623 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
46456929Smisaki != NPI_SUCCESS)
46463859Sml29623 goto fail;
46473859Sml29623 }
46483859Sml29623
46493859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
46506929Smisaki portn));
46513859Sml29623
46523859Sml29623 return (NXGE_OK);
46533859Sml29623 fail:
46543859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46556929Smisaki "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn));
46563859Sml29623 return (NXGE_ERROR | rs);
46573859Sml29623 }
46583859Sml29623
46594732Sdavemq /* 10G fiber link interrupt start routine */
46604732Sdavemq
46614732Sdavemq static nxge_status_t
nxge_10G_link_intr_start(p_nxge_t nxgep)46624732Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep)
46634732Sdavemq {
46644732Sdavemq npi_status_t rs = NPI_SUCCESS;
46654732Sdavemq uint8_t portn = nxgep->mac.portnum;
46664732Sdavemq
46674732Sdavemq rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
46684732Sdavemq
46694732Sdavemq if (rs != NPI_SUCCESS)
46704732Sdavemq return (NXGE_ERROR | rs);
46714732Sdavemq else
46724732Sdavemq return (NXGE_OK);
46734732Sdavemq }
46744732Sdavemq
46754732Sdavemq /* 10G fiber link interrupt stop routine */
46764732Sdavemq
46774732Sdavemq static nxge_status_t
nxge_10G_link_intr_stop(p_nxge_t nxgep)46784732Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep)
46794732Sdavemq {
46804732Sdavemq npi_status_t rs = NPI_SUCCESS;
46814732Sdavemq uint8_t portn = nxgep->mac.portnum;
46824732Sdavemq
46834732Sdavemq rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
46844732Sdavemq
46854732Sdavemq if (rs != NPI_SUCCESS)
46864732Sdavemq return (NXGE_ERROR | rs);
46874732Sdavemq else
46884732Sdavemq return (NXGE_OK);
46894732Sdavemq }
46904732Sdavemq
46914732Sdavemq /* 1G fiber link interrupt start routine */
46924732Sdavemq
46934732Sdavemq static nxge_status_t
nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)46944732Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
46954732Sdavemq {
46964732Sdavemq npi_status_t rs = NPI_SUCCESS;
46974732Sdavemq uint8_t portn = nxgep->mac.portnum;
46984732Sdavemq
46994732Sdavemq rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
47004732Sdavemq if (rs != NPI_SUCCESS)
47014732Sdavemq return (NXGE_ERROR | rs);
47024732Sdavemq else
47034732Sdavemq return (NXGE_OK);
47044732Sdavemq }
47054732Sdavemq
47064732Sdavemq /* 1G fiber link interrupt stop routine */
47074732Sdavemq
47084732Sdavemq static nxge_status_t
nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)47094732Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
47104732Sdavemq {
47114732Sdavemq npi_status_t rs = NPI_SUCCESS;
47124732Sdavemq uint8_t portn = nxgep->mac.portnum;
47134732Sdavemq
47144732Sdavemq rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
47154732Sdavemq
47164732Sdavemq if (rs != NPI_SUCCESS)
47174732Sdavemq return (NXGE_ERROR | rs);
47184732Sdavemq else
47194732Sdavemq return (NXGE_OK);
47204732Sdavemq }
47214732Sdavemq
47224732Sdavemq /* 1G copper link interrupt start routine */
47234732Sdavemq
47244732Sdavemq static nxge_status_t
nxge_1G_copper_link_intr_start(p_nxge_t nxgep)47254732Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
47264732Sdavemq {
47274732Sdavemq npi_status_t rs = NPI_SUCCESS;
47284732Sdavemq uint8_t portn = nxgep->mac.portnum;
47294732Sdavemq
47304732Sdavemq rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
47315203Ssbehera MII_STATUS, MII_STATUS_LINKUP);
47324732Sdavemq
47334732Sdavemq if (rs != NPI_SUCCESS)
47344732Sdavemq return (NXGE_ERROR | rs);
47354732Sdavemq else
47364732Sdavemq return (NXGE_OK);
47374732Sdavemq }
47384732Sdavemq
47394732Sdavemq /* 1G copper link interrupt stop routine */
47404732Sdavemq
47414732Sdavemq static nxge_status_t
nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)47424732Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
47434732Sdavemq {
47444732Sdavemq npi_status_t rs = NPI_SUCCESS;
47454732Sdavemq uint8_t portn = nxgep->mac.portnum;
47464732Sdavemq
47474732Sdavemq rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
47484732Sdavemq
47494732Sdavemq if (rs != NPI_SUCCESS)
47504732Sdavemq return (NXGE_ERROR | rs);
47514732Sdavemq else
47524732Sdavemq return (NXGE_OK);
47534732Sdavemq }
47544732Sdavemq
47554732Sdavemq /* Enable/Disable Link Status change interrupt */
47563859Sml29623
47573859Sml29623 nxge_status_t
nxge_link_intr(p_nxge_t nxgep,link_intr_enable_t enable)47583859Sml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
47593859Sml29623 {
47604732Sdavemq uint8_t portn;
47614732Sdavemq nxge_status_t status = NXGE_OK;
47623859Sml29623
47633859Sml29623 portn = nxgep->mac.portnum;
47643859Sml29623
47653859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
47664732Sdavemq if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
47674732Sdavemq return (NXGE_OK);
47684732Sdavemq
47694732Sdavemq if (enable == LINK_INTR_START)
47704732Sdavemq status = nxgep->xcvr.link_intr_start(nxgep);
47714732Sdavemq else if (enable == LINK_INTR_STOP)
47724732Sdavemq status = nxgep->xcvr.link_intr_stop(nxgep);
47734732Sdavemq if (status != NXGE_OK)
47744732Sdavemq goto fail;
47753859Sml29623
47763859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
47773859Sml29623
47783859Sml29623 return (NXGE_OK);
47793859Sml29623 fail:
47803859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
47816929Smisaki "nxge_link_intr: Failed to set port<%d> mif intr mode", portn));
47823859Sml29623
47834732Sdavemq return (status);
47843859Sml29623 }
47853859Sml29623
47863859Sml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
47873859Sml29623
47883859Sml29623 nxge_status_t
nxge_mii_xcvr_init(p_nxge_t nxgep)47893859Sml29623 nxge_mii_xcvr_init(p_nxge_t nxgep)
47903859Sml29623 {
47913859Sml29623 p_nxge_param_t param_arr;
47923859Sml29623 p_nxge_stats_t statsp;
47933859Sml29623 uint8_t xcvr_portn;
47943859Sml29623 p_mii_regs_t mii_regs;
47953859Sml29623 mii_bmcr_t bmcr;
47963859Sml29623 mii_bmsr_t bmsr;
47973859Sml29623 mii_anar_t anar;
47983859Sml29623 mii_gcr_t gcr;
47993859Sml29623 mii_esr_t esr;
48003859Sml29623 mii_aux_ctl_t bcm5464r_aux;
48013859Sml29623 int status = NXGE_OK;
48023859Sml29623
48033859Sml29623 uint_t delay;
48043859Sml29623
48053859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
48063859Sml29623
48073859Sml29623 param_arr = nxgep->param_arr;
48083859Sml29623 statsp = nxgep->statsp;
48093859Sml29623 xcvr_portn = statsp->mac_stats.xcvr_portn;
48103859Sml29623
48113859Sml29623 mii_regs = NULL;
48123859Sml29623
48133859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
48146929Smisaki "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
48153859Sml29623
48163859Sml29623 /*
48175196Ssbehera * The mif phy mode may be connected to either a copper link
48185196Ssbehera * or fiber link. Read the mode control register to get the fiber
48195196Ssbehera * configuration if it is hard-wired to fiber link.
48205196Ssbehera */
48215196Ssbehera (void) nxge_mii_get_link_mode(nxgep);
48225196Ssbehera if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
48235196Ssbehera return (nxge_mii_xcvr_fiber_init(nxgep));
48245196Ssbehera }
48255196Ssbehera
48265196Ssbehera /*
48273859Sml29623 * Reset the transceiver.
48283859Sml29623 */
48293859Sml29623 delay = 0;
48303859Sml29623 bmcr.value = 0;
48313859Sml29623 bmcr.bits.reset = 1;
48323859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
48335125Sjoycey #if defined(__i386)
48346929Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr,
48355125Sjoycey #else
48366929Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr,
48375125Sjoycey #endif
48386929Smisaki bmcr.value)) != NXGE_OK)
48393859Sml29623 goto fail;
48403859Sml29623 do {
48413859Sml29623 drv_usecwait(500);
48423859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn,
48435125Sjoycey #if defined(__i386)
48446929Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr,
48455125Sjoycey #else
48466929Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr,
48475125Sjoycey #endif
48486929Smisaki &bmcr.value)) != NXGE_OK)
48493859Sml29623 goto fail;
48503859Sml29623 delay++;
48513859Sml29623 } while ((bmcr.bits.reset) && (delay < 1000));
48523859Sml29623 if (delay == 1000) {
48533859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
48543859Sml29623 goto fail;
48553859Sml29623 }
48563859Sml29623
48573859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn,
48585125Sjoycey #if defined(__i386)
48596929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmsr),
48605125Sjoycey #else
48616929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmsr),
48625125Sjoycey #endif
48636929Smisaki &bmsr.value)) != NXGE_OK)
48643859Sml29623 goto fail;
48653859Sml29623
48663859Sml29623 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
48673859Sml29623 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
48683859Sml29623 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
48693859Sml29623 param_arr[param_anar_100hdx].value = 0;
48703859Sml29623 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
48713859Sml29623 param_arr[param_anar_10hdx].value = 0;
48723859Sml29623
48733859Sml29623 /*
48743859Sml29623 * Initialize the xcvr statistics.
48753859Sml29623 */
48763859Sml29623 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
48773859Sml29623 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
48783859Sml29623 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
48793859Sml29623 statsp->mac_stats.cap_100hdx = 0;
48803859Sml29623 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
48813859Sml29623 statsp->mac_stats.cap_10hdx = 0;
48823859Sml29623 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
48833859Sml29623 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
48843859Sml29623
48853859Sml29623 /*
48866835Syc148097 * Initialize the xcvr advertised capability statistics.
48873859Sml29623 */
48883859Sml29623 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
48893859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
48903859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
48913859Sml29623 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
48923859Sml29623 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
48933859Sml29623 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
48943859Sml29623 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
48953859Sml29623 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
48963859Sml29623 statsp->mac_stats.adv_cap_asmpause =
48976929Smisaki param_arr[param_anar_asmpause].value;
48983859Sml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
48993859Sml29623
49003859Sml29623
49013859Sml29623 /*
49023859Sml29623 * Check for extended status just in case we're
49033859Sml29623 * running a Gigibit phy.
49043859Sml29623 */
49053859Sml29623 if (bmsr.bits.extend_status) {
49063859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn,
49075125Sjoycey #if defined(__i386)
49086929Smisaki (uint8_t)(uint32_t)(&mii_regs->esr),
49095125Sjoycey #else
49106929Smisaki (uint8_t)(uint64_t)(&mii_regs->esr),
49115125Sjoycey #endif
49126929Smisaki &esr.value)) != NXGE_OK)
49133859Sml29623 goto fail;
49146929Smisaki param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx;
49153859Sml29623 param_arr[param_anar_1000hdx].value = 0;
49163859Sml29623
49173859Sml29623 statsp->mac_stats.cap_1000fdx =
49186929Smisaki (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
49193859Sml29623 statsp->mac_stats.cap_1000hdx = 0;
49203859Sml29623 } else {
49213859Sml29623 param_arr[param_anar_1000fdx].value = 0;
49223859Sml29623 param_arr[param_anar_1000hdx].value = 0;
49233859Sml29623 }
49243859Sml29623
49253859Sml29623 /*
49263859Sml29623 * Initialize 1G Statistics once the capability is established.
49273859Sml29623 */
49283859Sml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
49293859Sml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
49303859Sml29623
49313859Sml29623 /*
49326835Syc148097 * Initialize the link statistics.
49333859Sml29623 */
49343859Sml29623 statsp->mac_stats.link_T4 = 0;
49353859Sml29623 statsp->mac_stats.link_asmpause = 0;
49363859Sml29623 statsp->mac_stats.link_pause = 0;
49373859Sml29623 statsp->mac_stats.link_speed = 0;
49383859Sml29623 statsp->mac_stats.link_duplex = 0;
49393859Sml29623 statsp->mac_stats.link_up = 0;
49403859Sml29623
49413859Sml29623 /*
49423859Sml29623 * Switch off Auto-negotiation, 100M and full duplex.
49433859Sml29623 */
49443859Sml29623 bmcr.value = 0;
49453859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
49465125Sjoycey #if defined(__i386)
49476929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr),
49485125Sjoycey #else
49496929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr),
49505125Sjoycey #endif
49516929Smisaki bmcr.value)) != NXGE_OK)
49523859Sml29623 goto fail;
49533859Sml29623
49543859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
49556929Smisaki (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
49563859Sml29623 bmcr.bits.loopback = 1;
49573859Sml29623 bmcr.bits.enable_autoneg = 0;
49583859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
49593859Sml29623 bmcr.bits.speed_1000_sel = 1;
49603859Sml29623 bmcr.bits.duplex_mode = 1;
49613859Sml29623 param_arr[param_autoneg].value = 0;
49623859Sml29623 } else {
49633859Sml29623 bmcr.bits.loopback = 0;
49643859Sml29623 }
49653859Sml29623
49663859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
49676929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
49686929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
49693859Sml29623 param_arr[param_autoneg].value = 0;
49703859Sml29623 bcm5464r_aux.value = 0;
49713859Sml29623 bcm5464r_aux.bits.ext_lb = 1;
49723859Sml29623 bcm5464r_aux.bits.write_1 = 1;
49733859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
49746929Smisaki BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
49753859Sml29623 goto fail;
49763859Sml29623 }
49773859Sml29623
49786835Syc148097 /* If auto-negotiation is desired */
49793859Sml29623 if (param_arr[param_autoneg].value) {
49803859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
49816929Smisaki "Restarting Auto-negotiation."));
49823859Sml29623 /*
49833859Sml29623 * Setup our Auto-negotiation advertisement register.
49843859Sml29623 */
49853859Sml29623 anar.value = 0;
49863859Sml29623 anar.bits.selector = 1;
49873859Sml29623 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
49883859Sml29623 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
49893859Sml29623 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
49903859Sml29623 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
49913859Sml29623 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
49923859Sml29623 anar.bits.cap_asmpause = 0;
49933859Sml29623 anar.bits.cap_pause = 0;
49943859Sml29623 if (param_arr[param_anar_1000fdx].value ||
49956929Smisaki param_arr[param_anar_100fdx].value ||
49966929Smisaki param_arr[param_anar_10fdx].value) {
49973859Sml29623 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
49983859Sml29623 anar.bits.cap_pause = statsp->mac_stats.cap_pause;
49993859Sml29623 }
50003859Sml29623
50016835Syc148097 /* Write to the auto-negotiation advertisement register */
50023859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
50035125Sjoycey #if defined(__i386)
50046929Smisaki (uint8_t)(uint32_t)(&mii_regs->anar),
50055125Sjoycey #else
50066929Smisaki (uint8_t)(uint64_t)(&mii_regs->anar),
50075125Sjoycey #endif
50086929Smisaki anar.value)) != NXGE_OK)
50093859Sml29623 goto fail;
50103859Sml29623 if (bmsr.bits.extend_status) {
50113859Sml29623 gcr.value = 0;
50123859Sml29623 gcr.bits.ms_mode_en =
50136929Smisaki param_arr[param_master_cfg_enable].value;
50143859Sml29623 gcr.bits.master =
50156929Smisaki param_arr[param_master_cfg_value].value;
50163859Sml29623 gcr.bits.link_1000fdx =
50176929Smisaki param_arr[param_anar_1000fdx].value;
50183859Sml29623 gcr.bits.link_1000hdx =
50196929Smisaki param_arr[param_anar_1000hdx].value;
50203859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
50215125Sjoycey #if defined(__i386)
50226929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr),
50235125Sjoycey #else
50246929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr),
50255125Sjoycey #endif
50266929Smisaki gcr.value)) != NXGE_OK)
50273859Sml29623 goto fail;
50283859Sml29623 }
50293859Sml29623
50303859Sml29623 bmcr.bits.enable_autoneg = 1;
50313859Sml29623 bmcr.bits.restart_autoneg = 1;
50323859Sml29623
50333859Sml29623 } else {
50343859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
50353859Sml29623 bmcr.bits.speed_1000_sel =
50366929Smisaki param_arr[param_anar_1000fdx].value |
50376929Smisaki param_arr[param_anar_1000hdx].value;
50383859Sml29623 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
50396929Smisaki (param_arr[param_anar_100fdx].value |
50406929Smisaki param_arr[param_anar_100hdx].value);
50416835Syc148097
50426835Syc148097 /* Force to 1G */
50433859Sml29623 if (bmcr.bits.speed_1000_sel) {
50443859Sml29623 statsp->mac_stats.link_speed = 1000;
50453859Sml29623 gcr.value = 0;
50463859Sml29623 gcr.bits.ms_mode_en =
50476929Smisaki param_arr[param_master_cfg_enable].value;
50483859Sml29623 gcr.bits.master =
50496929Smisaki param_arr[param_master_cfg_value].value;
50503859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
50515125Sjoycey #if defined(__i386)
50526929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr),
50535125Sjoycey #else
50546929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr),
50555125Sjoycey #endif
50566929Smisaki gcr.value)) != NXGE_OK)
50573859Sml29623 goto fail;
50583859Sml29623 if (param_arr[param_anar_1000fdx].value) {
50593859Sml29623 bmcr.bits.duplex_mode = 1;
50603859Sml29623 statsp->mac_stats.link_duplex = 2;
50613859Sml29623 } else
50623859Sml29623 statsp->mac_stats.link_duplex = 1;
50636835Syc148097
50646835Syc148097 /* Force to 100M */
50653859Sml29623 } else if (bmcr.bits.speed_sel) {
50663859Sml29623 statsp->mac_stats.link_speed = 100;
50673859Sml29623 if (param_arr[param_anar_100fdx].value) {
50683859Sml29623 bmcr.bits.duplex_mode = 1;
50693859Sml29623 statsp->mac_stats.link_duplex = 2;
50703859Sml29623 } else
50713859Sml29623 statsp->mac_stats.link_duplex = 1;
50726835Syc148097
50736835Syc148097 /* Force to 10M */
50743859Sml29623 } else {
50753859Sml29623 statsp->mac_stats.link_speed = 10;
50763859Sml29623 if (param_arr[param_anar_10fdx].value) {
50773859Sml29623 bmcr.bits.duplex_mode = 1;
50783859Sml29623 statsp->mac_stats.link_duplex = 2;
50793859Sml29623 } else
50803859Sml29623 statsp->mac_stats.link_duplex = 1;
50813859Sml29623 }
50823859Sml29623 if (statsp->mac_stats.link_duplex != 1) {
50833859Sml29623 statsp->mac_stats.link_asmpause =
50846929Smisaki statsp->mac_stats.cap_asmpause;
50853859Sml29623 statsp->mac_stats.link_pause =
50866929Smisaki statsp->mac_stats.cap_pause;
50873859Sml29623 }
50883859Sml29623
50893859Sml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
50906929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
50916929Smisaki (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
50923859Sml29623 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
50933859Sml29623 /* BCM5464R 1000mbps external loopback mode */
50943859Sml29623 gcr.value = 0;
50953859Sml29623 gcr.bits.ms_mode_en = 1;
50963859Sml29623 gcr.bits.master = 1;
50973859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
50985125Sjoycey #if defined(__i386)
50996929Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr),
51005125Sjoycey #else
51016929Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr),
51025125Sjoycey #endif
51036929Smisaki gcr.value)) != NXGE_OK)
51043859Sml29623 goto fail;
51053859Sml29623 bmcr.value = 0;
51063859Sml29623 bmcr.bits.speed_1000_sel = 1;
51073859Sml29623 statsp->mac_stats.link_speed = 1000;
51083859Sml29623 } else if (statsp->port_stats.lb_mode
51093859Sml29623 == nxge_lb_ext100) {
51103859Sml29623 /* BCM5464R 100mbps external loopback mode */
51113859Sml29623 bmcr.value = 0;
51123859Sml29623 bmcr.bits.speed_sel = 1;
51133859Sml29623 bmcr.bits.duplex_mode = 1;
51143859Sml29623 statsp->mac_stats.link_speed = 100;
51153859Sml29623 } else if (statsp->port_stats.lb_mode
51163859Sml29623 == nxge_lb_ext10) {
51173859Sml29623 /* BCM5464R 10mbps external loopback mode */
51183859Sml29623 bmcr.value = 0;
51193859Sml29623 bmcr.bits.duplex_mode = 1;
51203859Sml29623 statsp->mac_stats.link_speed = 10;
51213859Sml29623 }
51223859Sml29623 }
51233859Sml29623 }
51243859Sml29623
51253859Sml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn,
51265125Sjoycey #if defined(__i386)
51276929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr),
51285125Sjoycey #else
51296929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr),
51305125Sjoycey #endif
51316929Smisaki bmcr.value)) != NXGE_OK)
51323859Sml29623 goto fail;
51333859Sml29623
51343859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn,
51355125Sjoycey #if defined(__i386)
51366929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr),
51375125Sjoycey #else
51386929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr),
51395125Sjoycey #endif
51406929Smisaki &bmcr.value)) != NXGE_OK)
51413859Sml29623 goto fail;
51423859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
51433859Sml29623
51443859Sml29623 /*
51453859Sml29623 * Initialize the xcvr status kept in the context structure.
51463859Sml29623 */
51473859Sml29623 nxgep->soft_bmsr.value = 0;
51483859Sml29623
51493859Sml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn,
51505125Sjoycey #if defined(__i386)
51516929Smisaki (uint8_t)(uint32_t)(&mii_regs->bmsr),
51525125Sjoycey #else
51536929Smisaki (uint8_t)(uint64_t)(&mii_regs->bmsr),
51545125Sjoycey #endif
51556929Smisaki &nxgep->bmsr.value)) != NXGE_OK)
51563859Sml29623 goto fail;
51573859Sml29623
51583859Sml29623 statsp->mac_stats.xcvr_inits++;
51593859Sml29623 nxgep->bmsr.value = 0;
51603859Sml29623
51613859Sml29623 fail:
51623859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51636929Smisaki "<== nxge_mii_xcvr_init status 0x%x", status));
51643859Sml29623 return (status);
51653859Sml29623 }
51663859Sml29623
51675196Ssbehera nxge_status_t
nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)51685196Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)
51695196Ssbehera {
51705196Ssbehera p_nxge_param_t param_arr;
51715196Ssbehera p_nxge_stats_t statsp;
51725196Ssbehera uint8_t xcvr_portn;
51735196Ssbehera p_mii_regs_t mii_regs;
51745196Ssbehera mii_bmcr_t bmcr;
51755196Ssbehera mii_bmsr_t bmsr;
51765196Ssbehera mii_gcr_t gcr;
51775196Ssbehera mii_esr_t esr;
51785196Ssbehera mii_aux_ctl_t bcm5464r_aux;
51795196Ssbehera int status = NXGE_OK;
51805196Ssbehera
51815196Ssbehera uint_t delay;
51825196Ssbehera
51835196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init"));
51845196Ssbehera
51855196Ssbehera param_arr = nxgep->param_arr;
51865196Ssbehera statsp = nxgep->statsp;
51875196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn;
51885196Ssbehera
51895196Ssbehera mii_regs = NULL;
51905196Ssbehera
51915196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51925196Ssbehera "nxge_mii_xcvr_fiber_init: "
51935196Ssbehera "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
51945196Ssbehera
51955196Ssbehera /*
51965196Ssbehera * Reset the transceiver.
51975196Ssbehera */
51985196Ssbehera delay = 0;
51995196Ssbehera bmcr.value = 0;
52005196Ssbehera bmcr.bits.reset = 1;
52015196Ssbehera
52025196Ssbehera #if defined(__i386)
52035196Ssbehera
52045196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
52055196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
52065196Ssbehera goto fail;
52075196Ssbehera #else
52085196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
52095196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
52105196Ssbehera goto fail;
52115196Ssbehera #endif
52125196Ssbehera do {
52135196Ssbehera drv_usecwait(500);
52145196Ssbehera #if defined(__i386)
52155196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
52165196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value))
52175196Ssbehera != NXGE_OK)
52185196Ssbehera goto fail;
52195196Ssbehera #else
52205196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
52215196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value))
52225196Ssbehera != NXGE_OK)
52235196Ssbehera goto fail;
52245196Ssbehera #endif
52255196Ssbehera delay++;
52265196Ssbehera } while ((bmcr.bits.reset) && (delay < 1000));
52275196Ssbehera if (delay == 1000) {
52285196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
52295196Ssbehera goto fail;
52305196Ssbehera }
52315196Ssbehera
52325196Ssbehera #if defined(__i386)
52335196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
52345196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
52355196Ssbehera goto fail;
52365196Ssbehera #else
52375196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
52385196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
52395196Ssbehera goto fail;
52405196Ssbehera #endif
52415196Ssbehera
52425196Ssbehera param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
52435196Ssbehera param_arr[param_anar_100T4].value = 0;
52445196Ssbehera param_arr[param_anar_100fdx].value = 0;
52455196Ssbehera param_arr[param_anar_100hdx].value = 0;
52465196Ssbehera param_arr[param_anar_10fdx].value = 0;
52475196Ssbehera param_arr[param_anar_10hdx].value = 0;
52485196Ssbehera
52495196Ssbehera /*
52505196Ssbehera * Initialize the xcvr statistics.
52515196Ssbehera */
52525196Ssbehera statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
52535196Ssbehera statsp->mac_stats.cap_100T4 = 0;
52545196Ssbehera statsp->mac_stats.cap_100fdx = 0;
52555196Ssbehera statsp->mac_stats.cap_100hdx = 0;
52565196Ssbehera statsp->mac_stats.cap_10fdx = 0;
52575196Ssbehera statsp->mac_stats.cap_10hdx = 0;
52585196Ssbehera statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
52595196Ssbehera statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
52605196Ssbehera
52615196Ssbehera /*
52625196Ssbehera * Initialize the xcvr advertised capability statistics.
52635196Ssbehera */
52645196Ssbehera statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
52655196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
52665196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
52675196Ssbehera statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
52685196Ssbehera statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
52695196Ssbehera statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
52705196Ssbehera statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
52715196Ssbehera statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
52725196Ssbehera statsp->mac_stats.adv_cap_asmpause =
52735196Ssbehera param_arr[param_anar_asmpause].value;
52745196Ssbehera statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
52755196Ssbehera
52765196Ssbehera /*
52775196Ssbehera * Check for extended status just in case we're
52785196Ssbehera * running a Gigibit phy.
52795196Ssbehera */
52805196Ssbehera if (bmsr.bits.extend_status) {
52815196Ssbehera #if defined(__i386)
52825196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
52835196Ssbehera (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) !=
52845196Ssbehera NXGE_OK)
52855196Ssbehera goto fail;
52865196Ssbehera #else
52875196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
52885196Ssbehera (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) !=
52895196Ssbehera NXGE_OK)
52905196Ssbehera goto fail;
52915196Ssbehera #endif
52925196Ssbehera param_arr[param_anar_1000fdx].value &=
52935196Ssbehera esr.bits.link_1000fdx;
52945196Ssbehera param_arr[param_anar_1000hdx].value = 0;
52955196Ssbehera
52965196Ssbehera statsp->mac_stats.cap_1000fdx =
52975196Ssbehera (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
52985196Ssbehera statsp->mac_stats.cap_1000hdx = 0;
52995196Ssbehera } else {
53005196Ssbehera param_arr[param_anar_1000fdx].value = 0;
53015196Ssbehera param_arr[param_anar_1000hdx].value = 0;
53025196Ssbehera }
53035196Ssbehera
53045196Ssbehera /*
53055196Ssbehera * Initialize 1G Statistics once the capability is established.
53065196Ssbehera */
53075196Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
53085196Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
53095196Ssbehera
53105196Ssbehera /*
53115196Ssbehera * Initialize the link statistics.
53125196Ssbehera */
53135196Ssbehera statsp->mac_stats.link_T4 = 0;
53145196Ssbehera statsp->mac_stats.link_asmpause = 0;
53155196Ssbehera statsp->mac_stats.link_pause = 0;
53165196Ssbehera statsp->mac_stats.link_speed = 0;
53175196Ssbehera statsp->mac_stats.link_duplex = 0;
53185196Ssbehera statsp->mac_stats.link_up = 0;
53195196Ssbehera
53205196Ssbehera /*
53215196Ssbehera * Switch off Auto-negotiation, 100M and full duplex.
53225196Ssbehera */
53235196Ssbehera bmcr.value = 0;
53245196Ssbehera #if defined(__i386)
53255196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53265196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
53275196Ssbehera goto fail;
53285196Ssbehera #else
53295196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53305196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
53315196Ssbehera goto fail;
53325196Ssbehera #endif
53335196Ssbehera
53345196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
53355196Ssbehera (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
53365196Ssbehera bmcr.bits.loopback = 1;
53375196Ssbehera bmcr.bits.enable_autoneg = 0;
53385196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
53395196Ssbehera bmcr.bits.speed_1000_sel = 1;
53405196Ssbehera bmcr.bits.duplex_mode = 1;
53415196Ssbehera param_arr[param_autoneg].value = 0;
53425196Ssbehera } else {
53435196Ssbehera bmcr.bits.loopback = 0;
53445196Ssbehera }
53455196Ssbehera
53465196Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
53475196Ssbehera param_arr[param_autoneg].value = 0;
53485196Ssbehera bcm5464r_aux.value = 0;
53495196Ssbehera bcm5464r_aux.bits.ext_lb = 1;
53505196Ssbehera bcm5464r_aux.bits.write_1 = 1;
53515196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53525196Ssbehera BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
53535196Ssbehera goto fail;
53545196Ssbehera }
53555196Ssbehera
53565196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
53575196Ssbehera bmcr.bits.speed_1000_sel = 1;
53585196Ssbehera bmcr.bits.speed_sel = 0;
53595196Ssbehera bmcr.bits.duplex_mode = 1;
53605196Ssbehera statsp->mac_stats.link_speed = 1000;
53615196Ssbehera statsp->mac_stats.link_duplex = 2;
53625196Ssbehera
53635196Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) {
53645196Ssbehera /* BCM5464R 1000mbps external loopback mode */
53655196Ssbehera gcr.value = 0;
53665196Ssbehera gcr.bits.ms_mode_en = 1;
53675196Ssbehera gcr.bits.master = 1;
53685196Ssbehera #if defined(__i386)
53695196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53705196Ssbehera (uint8_t)(uint32_t)(&mii_regs->gcr),
53715196Ssbehera gcr.value)) != NXGE_OK)
53725196Ssbehera goto fail;
53735196Ssbehera #else
53745196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53755196Ssbehera (uint8_t)(uint64_t)(&mii_regs->gcr),
53765196Ssbehera gcr.value)) != NXGE_OK)
53775196Ssbehera goto fail;
53785196Ssbehera #endif
53795196Ssbehera bmcr.value = 0;
53805196Ssbehera bmcr.bits.speed_1000_sel = 1;
53815196Ssbehera statsp->mac_stats.link_speed = 1000;
53825196Ssbehera }
53835196Ssbehera
53845196Ssbehera #if defined(__i386)
53855196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53865196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr),
53875196Ssbehera bmcr.value)) != NXGE_OK)
53885196Ssbehera goto fail;
53895196Ssbehera #else
53905196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
53915196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr),
53925196Ssbehera bmcr.value)) != NXGE_OK)
53935196Ssbehera goto fail;
53945196Ssbehera #endif
53955196Ssbehera
53965196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
53975196Ssbehera "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
53985196Ssbehera bmcr.value));
53995196Ssbehera
54005196Ssbehera #if defined(__i386)
54015196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
54025196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
54035196Ssbehera goto fail;
54045196Ssbehera #else
54055196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
54065196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
54075196Ssbehera goto fail;
54085196Ssbehera #endif
54095196Ssbehera
54105196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
54115196Ssbehera "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value));
54125196Ssbehera
54135196Ssbehera /*
54145196Ssbehera * Initialize the xcvr status kept in the context structure.
54155196Ssbehera */
54165196Ssbehera nxgep->soft_bmsr.value = 0;
54175196Ssbehera #if defined(__i386)
54185196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
54195196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr),
54205196Ssbehera &nxgep->bmsr.value)) != NXGE_OK)
54215196Ssbehera goto fail;
54225196Ssbehera #else
54235196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
54245196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr),
54255196Ssbehera &nxgep->bmsr.value)) != NXGE_OK)
54265196Ssbehera goto fail;
54275196Ssbehera #endif
54285196Ssbehera
54295196Ssbehera statsp->mac_stats.xcvr_inits++;
54305196Ssbehera nxgep->bmsr.value = 0;
54315196Ssbehera
54325196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
54335196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
54345196Ssbehera return (status);
54355196Ssbehera
54365196Ssbehera fail:
54375196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54385196Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
54395196Ssbehera return (status);
54405196Ssbehera }
54415196Ssbehera
54423859Sml29623 /* Read from a MII compliant register */
54433859Sml29623
54443859Sml29623 nxge_status_t
nxge_mii_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t * value)54453859Sml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
54463859Sml29623 uint16_t *value)
54473859Sml29623 {
54483859Sml29623 npi_status_t rs = NPI_SUCCESS;
54493859Sml29623
54503859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
54516929Smisaki "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
54523859Sml29623
54536075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
54543859Sml29623
54555196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
54565196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
54573859Sml29623 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
54586929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
54593859Sml29623 goto fail;
54604977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
54614977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) {
54623859Sml29623 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
54636929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
54643859Sml29623 goto fail;
54653859Sml29623 } else
54663859Sml29623 goto fail;
54673859Sml29623
54686075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54693859Sml29623
54703859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
54716929Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value));
54723859Sml29623 return (NXGE_OK);
54733859Sml29623 fail:
54746075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54753859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54766929Smisaki "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn));
54773859Sml29623
54783859Sml29623 return (NXGE_ERROR | rs);
54793859Sml29623 }
54803859Sml29623
54813859Sml29623 /* Write to a MII compliant Register */
54823859Sml29623
54833859Sml29623 nxge_status_t
nxge_mii_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t value)54843859Sml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
54853859Sml29623 uint16_t value)
54863859Sml29623 {
54873859Sml29623 npi_status_t rs = NPI_SUCCESS;
54883859Sml29623
54893859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
54906929Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value));
54913859Sml29623
54926075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
54933859Sml29623
54945196Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
54955196Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
54963859Sml29623 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
54976929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
54983859Sml29623 goto fail;
54994977Sraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
55004977Sraghus (nxgep->mac.portmode == PORT_1G_SERDES)) {
55013859Sml29623 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
55026929Smisaki xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
55033859Sml29623 goto fail;
55043859Sml29623 } else
55053859Sml29623 goto fail;
55063859Sml29623
55076075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55083859Sml29623
55093859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
55106929Smisaki "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
55113859Sml29623 return (NXGE_OK);
55123859Sml29623 fail:
55136075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55143859Sml29623
55153859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55166929Smisaki "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn));
55173859Sml29623
55183859Sml29623 return (NXGE_ERROR | rs);
55193859Sml29623 }
55203859Sml29623
55216835Syc148097 /*
55226835Syc148097 * Perform write to Clause45 serdes / transceiver device
55236835Syc148097 * Arguments:
55246835Syc148097 * xcvr_portn: The IEEE 802.3 Clause45 PHYAD, it is the same as port
55256835Syc148097 * number if nxge_mdio_write is used for accessing the
55266835Syc148097 * internal LSIL serdes. Otherwise PHYAD is different
55276835Syc148097 * for different platforms.
55286835Syc148097 * device: With each PHYAD, the driver can use MDIO to control
55296835Syc148097 * multiple devices inside the PHY, here "device" is an
55306835Syc148097 * MMD (MDIO managable device).
55316835Syc148097 * xcvr_reg: Each device has multiple registers. xcvr_reg specifies
55326835Syc148097 * the register which the driver will write value to.
55336835Syc148097 * value: The register value will be filled in.
55346835Syc148097 */
55353859Sml29623 nxge_status_t
nxge_mdio_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t * value)55363859Sml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
55373859Sml29623 uint16_t xcvr_reg, uint16_t *value)
55383859Sml29623 {
55393859Sml29623 npi_status_t rs = NPI_SUCCESS;
55403859Sml29623
55413859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
55426929Smisaki xcvr_portn));
55433859Sml29623
55445780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
55453859Sml29623
55463859Sml29623 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
55476929Smisaki xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
55483859Sml29623 goto fail;
55493859Sml29623
55505780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55513859Sml29623
55523859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
55536929Smisaki xcvr_portn));
55543859Sml29623 return (NXGE_OK);
55553859Sml29623 fail:
55565780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55573859Sml29623
55583859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55596929Smisaki "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn));
55603859Sml29623
55613859Sml29623 return (NXGE_ERROR | rs);
55623859Sml29623 }
55633859Sml29623
55643859Sml29623 /* Perform write to Clause45 serdes / transceiver device */
55653859Sml29623
55663859Sml29623 nxge_status_t
nxge_mdio_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t value)55673859Sml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
55683859Sml29623 uint16_t xcvr_reg, uint16_t value)
55693859Sml29623 {
55703859Sml29623 npi_status_t rs = NPI_SUCCESS;
55713859Sml29623
55723859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
55736929Smisaki xcvr_portn));
55743859Sml29623
55755780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
55763859Sml29623
55773859Sml29623 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
55786929Smisaki xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
55793859Sml29623 goto fail;
55803859Sml29623
55815780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55823859Sml29623
55833859Sml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
55846929Smisaki xcvr_portn));
55853859Sml29623 return (NXGE_OK);
55863859Sml29623 fail:
55875780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
55883859Sml29623
55893859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55906929Smisaki "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn));
55913859Sml29623
55923859Sml29623 return (NXGE_ERROR | rs);
55933859Sml29623 }
55943859Sml29623
55953859Sml29623
55963859Sml29623 /* Check MII to see if there is any link status change */
55973859Sml29623
55983859Sml29623 nxge_status_t
nxge_mii_check(p_nxge_t nxgep,mii_bmsr_t bmsr,mii_bmsr_t bmsr_ints,nxge_link_state_t * link_up)55993859Sml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
56003859Sml29623 nxge_link_state_t *link_up)
56013859Sml29623 {
56023859Sml29623 p_nxge_param_t param_arr;
56033859Sml29623 p_nxge_stats_t statsp;
56043859Sml29623 p_mii_regs_t mii_regs;
56053859Sml29623 p_mii_bmsr_t soft_bmsr;
56063859Sml29623 mii_anar_t anar;
56073859Sml29623 mii_anlpar_t anlpar;
56083859Sml29623 mii_anar_t an_common;
56093859Sml29623 mii_aner_t aner;
56103859Sml29623 mii_gsr_t gsr;
56113859Sml29623 nxge_status_t status = NXGE_OK;
56123859Sml29623
56133859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
56143859Sml29623
56153859Sml29623 mii_regs = NULL;
56163859Sml29623 param_arr = nxgep->param_arr;
56173859Sml29623 statsp = nxgep->statsp;
56183859Sml29623 soft_bmsr = &nxgep->soft_bmsr;
56193859Sml29623 *link_up = LINK_NO_CHANGE;
56203859Sml29623
56215196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56225196Ssbehera "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
56235196Ssbehera bmsr.value, bmsr_ints.value));
56245196Ssbehera
56253859Sml29623 if (bmsr_ints.bits.link_status) {
56265196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56275196Ssbehera "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
56285196Ssbehera bmsr.value, bmsr_ints.value));
56293859Sml29623 if (bmsr.bits.link_status) {
56303859Sml29623 soft_bmsr->bits.link_status = 1;
56315196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56325196Ssbehera "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
56335196Ssbehera "0x%x", bmsr.value, bmsr_ints.value));
56343859Sml29623 } else {
563511409Stc99174@train /* Only status change will update *link_up */
563611409Stc99174@train if (statsp->mac_stats.link_up == 1) {
563711409Stc99174@train *link_up = LINK_IS_DOWN;
563811409Stc99174@train /* Will notify, turn off further msg */
563911409Stc99174@train nxgep->link_notify = B_FALSE;
564011409Stc99174@train }
56413859Sml29623 statsp->mac_stats.link_up = 0;
56423859Sml29623 soft_bmsr->bits.link_status = 0;
56433859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56446929Smisaki "Link down cable problem"));
56453859Sml29623 }
56463859Sml29623 }
56473859Sml29623
56485196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER &&
56495196Ssbehera param_arr[param_autoneg].value) {
56503859Sml29623 if (bmsr_ints.bits.auto_neg_complete) {
56513859Sml29623 if (bmsr.bits.auto_neg_complete)
56523859Sml29623 soft_bmsr->bits.auto_neg_complete = 1;
56533859Sml29623 else
56543859Sml29623 soft_bmsr->bits.auto_neg_complete = 0;
56553859Sml29623 }
56563859Sml29623 if (soft_bmsr->bits.link_status == 0) {
56573859Sml29623 statsp->mac_stats.link_T4 = 0;
56583859Sml29623 statsp->mac_stats.link_speed = 0;
56593859Sml29623 statsp->mac_stats.link_duplex = 0;
56603859Sml29623 statsp->mac_stats.link_asmpause = 0;
56613859Sml29623 statsp->mac_stats.link_pause = 0;
56623859Sml29623 statsp->mac_stats.lp_cap_autoneg = 0;
56633859Sml29623 statsp->mac_stats.lp_cap_100T4 = 0;
56643859Sml29623 statsp->mac_stats.lp_cap_1000fdx = 0;
56653859Sml29623 statsp->mac_stats.lp_cap_1000hdx = 0;
56663859Sml29623 statsp->mac_stats.lp_cap_100fdx = 0;
56673859Sml29623 statsp->mac_stats.lp_cap_100hdx = 0;
56683859Sml29623 statsp->mac_stats.lp_cap_10fdx = 0;
56693859Sml29623 statsp->mac_stats.lp_cap_10hdx = 0;
56703859Sml29623 statsp->mac_stats.lp_cap_10gfdx = 0;
56713859Sml29623 statsp->mac_stats.lp_cap_10ghdx = 0;
56723859Sml29623 statsp->mac_stats.lp_cap_asmpause = 0;
56733859Sml29623 statsp->mac_stats.lp_cap_pause = 0;
56743859Sml29623 }
56753859Sml29623 } else
56763859Sml29623 soft_bmsr->bits.auto_neg_complete = 1;
56773859Sml29623
56783859Sml29623 if ((bmsr_ints.bits.link_status ||
56796929Smisaki bmsr_ints.bits.auto_neg_complete) &&
56806929Smisaki soft_bmsr->bits.link_status &&
56816929Smisaki soft_bmsr->bits.auto_neg_complete) {
568211409Stc99174@train if (statsp->mac_stats.link_up == 0) {
568311409Stc99174@train *link_up = LINK_IS_UP;
568411409Stc99174@train nxgep->link_notify = B_FALSE;
568511409Stc99174@train }
56863859Sml29623 statsp->mac_stats.link_up = 1;
56875196Ssbehera
56885196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
56895196Ssbehera "==> nxge_mii_check "
56905196Ssbehera "(auto negotiation complete or link up) "
56915196Ssbehera "soft bmsr 0x%x bmsr_int 0x%x",
56925196Ssbehera bmsr.value, bmsr_ints.value));
56935196Ssbehera
56945196Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER &&
56955196Ssbehera param_arr[param_autoneg].value) {
56963859Sml29623 if ((status = nxge_mii_read(nxgep,
56976929Smisaki statsp->mac_stats.xcvr_portn,
56985125Sjoycey #if defined(__i386)
56996929Smisaki (uint8_t)(uint32_t)(&mii_regs->anar),
57005125Sjoycey #else
57016929Smisaki (uint8_t)(uint64_t)(&mii_regs->anar),
57025125Sjoycey #endif
57036929Smisaki &anar.value)) != NXGE_OK)
57043859Sml29623 goto fail;
57053859Sml29623 if ((status = nxge_mii_read(nxgep,
57066929Smisaki statsp->mac_stats.xcvr_portn,
57075125Sjoycey #if defined(__i386)
57086929Smisaki (uint8_t)(uint32_t)(&mii_regs->anlpar),
57095125Sjoycey #else
57106929Smisaki (uint8_t)(uint64_t)(&mii_regs->anlpar),
57115125Sjoycey #endif
57126929Smisaki &anlpar.value)) != NXGE_OK)
57133859Sml29623 goto fail;
57143859Sml29623 if ((status = nxge_mii_read(nxgep,
57156929Smisaki statsp->mac_stats.xcvr_portn,
57165125Sjoycey #if defined(__i386)
57176929Smisaki (uint8_t)(uint32_t)(&mii_regs->aner),
57185125Sjoycey #else
57196929Smisaki (uint8_t)(uint64_t)(&mii_regs->aner),
57205125Sjoycey #endif
57216929Smisaki &aner.value)) != NXGE_OK)
57223859Sml29623 goto fail;
57233859Sml29623 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
57243859Sml29623 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
57253859Sml29623 statsp->mac_stats.lp_cap_100fdx =
57266929Smisaki anlpar.bits.cap_100fdx;
57273859Sml29623 statsp->mac_stats.lp_cap_100hdx =
57286929Smisaki anlpar.bits.cap_100hdx;
57293859Sml29623 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
57303859Sml29623 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
57313859Sml29623 statsp->mac_stats.lp_cap_asmpause =
57326929Smisaki anlpar.bits.cap_asmpause;
57333859Sml29623 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
57343859Sml29623 an_common.value = anar.value & anlpar.value;
57353859Sml29623 if (param_arr[param_anar_1000fdx].value ||
57366929Smisaki param_arr[param_anar_1000hdx].value) {
57373859Sml29623 if ((status = nxge_mii_read(nxgep,
57386929Smisaki statsp->mac_stats.xcvr_portn,
57395125Sjoycey #if defined(__i386)
57406929Smisaki (uint8_t)(uint32_t)(&mii_regs->gsr),
57415125Sjoycey #else
57426929Smisaki (uint8_t)(uint64_t)(&mii_regs->gsr),
57435125Sjoycey #endif
57446929Smisaki &gsr.value)) != NXGE_OK)
57453859Sml29623 goto fail;
57463859Sml29623 statsp->mac_stats.lp_cap_1000fdx =
57476929Smisaki gsr.bits.link_1000fdx;
57483859Sml29623 statsp->mac_stats.lp_cap_1000hdx =
57496929Smisaki gsr.bits.link_1000hdx;
57503859Sml29623 if (param_arr[param_anar_1000fdx].value &&
57516929Smisaki gsr.bits.link_1000fdx) {
57523859Sml29623 statsp->mac_stats.link_speed = 1000;
57533859Sml29623 statsp->mac_stats.link_duplex = 2;
57543859Sml29623 } else if (
57556929Smisaki param_arr[param_anar_1000hdx].value &&
57566929Smisaki gsr.bits.link_1000hdx) {
57573859Sml29623 statsp->mac_stats.link_speed = 1000;
57583859Sml29623 statsp->mac_stats.link_duplex = 1;
57593859Sml29623 }
57603859Sml29623 }
57613859Sml29623 if ((an_common.value != 0) &&
57626929Smisaki !(statsp->mac_stats.link_speed)) {
57633859Sml29623 if (an_common.bits.cap_100T4) {
57643859Sml29623 statsp->mac_stats.link_T4 = 1;
57653859Sml29623 statsp->mac_stats.link_speed = 100;
57663859Sml29623 statsp->mac_stats.link_duplex = 1;
57673859Sml29623 } else if (an_common.bits.cap_100fdx) {
57683859Sml29623 statsp->mac_stats.link_speed = 100;
57693859Sml29623 statsp->mac_stats.link_duplex = 2;
57703859Sml29623 } else if (an_common.bits.cap_100hdx) {
57713859Sml29623 statsp->mac_stats.link_speed = 100;
57723859Sml29623 statsp->mac_stats.link_duplex = 1;
57733859Sml29623 } else if (an_common.bits.cap_10fdx) {
57743859Sml29623 statsp->mac_stats.link_speed = 10;
57753859Sml29623 statsp->mac_stats.link_duplex = 2;
57763859Sml29623 } else if (an_common.bits.cap_10hdx) {
57773859Sml29623 statsp->mac_stats.link_speed = 10;
57783859Sml29623 statsp->mac_stats.link_duplex = 1;
57793859Sml29623 } else {
57803859Sml29623 goto fail;
57813859Sml29623 }
57823859Sml29623 }
57833859Sml29623 if (statsp->mac_stats.link_duplex != 1) {
57846929Smisaki int link_pause;
57856929Smisaki int cp, lcp;
57866929Smisaki
57873859Sml29623 statsp->mac_stats.link_asmpause =
57886929Smisaki an_common.bits.cap_asmpause;
57896929Smisaki cp = statsp->mac_stats.cap_pause;
57906929Smisaki lcp = statsp->mac_stats.lp_cap_pause;
57916929Smisaki if (statsp->mac_stats.link_asmpause) {
57926929Smisaki if ((cp == 0) && (lcp == 1)) {
57936929Smisaki link_pause = 0;
57946929Smisaki } else {
57956929Smisaki link_pause = 1;
57966929Smisaki }
57976929Smisaki } else {
57986929Smisaki link_pause = an_common.bits.cap_pause;
57996929Smisaki }
58006929Smisaki statsp->mac_stats.link_pause = link_pause;
58013859Sml29623 }
58025196Ssbehera } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
58035196Ssbehera statsp->mac_stats.link_speed = 1000;
58045196Ssbehera statsp->mac_stats.link_duplex = 2;
58053859Sml29623 }
580611409Stc99174@train }
580711409Stc99174@train /* Initial link_notify, delay link down msg */
580811409Stc99174@train if (nxgep->link_notify && nxgep->nxge_mac_state == NXGE_MAC_STARTED &&
580911409Stc99174@train (statsp->mac_stats.link_up == 1 || nxgep->link_check_count > 3)) {
58103859Sml29623 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
58116929Smisaki LINK_IS_DOWN);
58123859Sml29623 nxgep->link_notify = B_FALSE;
58133859Sml29623 }
58143859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
58153859Sml29623 return (NXGE_OK);
58163859Sml29623 fail:
58173859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
58186929Smisaki "nxge_mii_check: Unable to check MII"));
58193859Sml29623 return (status);
58203859Sml29623 }
58213859Sml29623
58226835Syc148097 /*
58236835Syc148097 * Check PCS to see if there is any link status change.
58246835Syc148097 * This function is called by PORT_1G_SERDES only.
58256835Syc148097 */
58266835Syc148097 void
nxge_pcs_check(p_nxge_t nxgep,uint8_t portn,nxge_link_state_t * link_up)58274977Sraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up)
58284977Sraghus {
58294977Sraghus p_nxge_stats_t statsp;
58304977Sraghus boolean_t linkup;
58314977Sraghus
58324977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check"));
58334977Sraghus
58344977Sraghus statsp = nxgep->statsp;
58354977Sraghus *link_up = LINK_NO_CHANGE;
58364977Sraghus
58374977Sraghus (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup);
58384977Sraghus if (linkup) {
583911409Stc99174@train if ((nxgep->link_notify &&
584011409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
58414977Sraghus nxgep->statsp->mac_stats.link_up == 0) {
58424977Sraghus statsp->mac_stats.link_up = 1;
58434977Sraghus statsp->mac_stats.link_speed = 1000;
58444977Sraghus statsp->mac_stats.link_duplex = 2;
58454977Sraghus *link_up = LINK_IS_UP;
58464977Sraghus nxgep->link_notify = B_FALSE;
58474977Sraghus }
58484977Sraghus } else {
584911409Stc99174@train if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
585011409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
58514977Sraghus nxgep->statsp->mac_stats.link_up == 1) {
58524977Sraghus statsp->mac_stats.link_up = 0;
58534977Sraghus statsp->mac_stats.link_speed = 0;
58544977Sraghus statsp->mac_stats.link_duplex = 0;
58554977Sraghus *link_up = LINK_IS_DOWN;
58564977Sraghus nxgep->link_notify = B_FALSE;
58574977Sraghus }
58584977Sraghus }
58594977Sraghus
58604977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check"));
58614977Sraghus }
58624977Sraghus
58633859Sml29623 /* Add a multicast address entry into the HW hash table */
58643859Sml29623
58653859Sml29623 nxge_status_t
nxge_add_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)58663859Sml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
58673859Sml29623 {
58683859Sml29623 uint32_t mchash;
58693859Sml29623 p_hash_filter_t hash_filter;
58703859Sml29623 uint16_t hash_bit;
58713859Sml29623 uint_t j;
58723859Sml29623 nxge_status_t status = NXGE_OK;
587311878SVenu.Iyer@Sun.COM npi_status_t rs;
58743859Sml29623
58753859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
58763859Sml29623
58773859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock);
58783859Sml29623 mchash = crc32_mchash(addrp);
58793859Sml29623 if (nxgep->hash_filter == NULL) {
58803859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL,
58816929Smisaki "Allocating hash filter storage."));
58823859Sml29623 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
58836929Smisaki KM_SLEEP);
58843859Sml29623 }
588511878SVenu.Iyer@Sun.COM
58863859Sml29623 hash_filter = nxgep->hash_filter;
58873859Sml29623 j = mchash / HASH_REG_WIDTH;
58883859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH));
58893859Sml29623 hash_filter->hash_filter_regs[j] |= hash_bit;
58903859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]++;
58913859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
58923859Sml29623 hash_filter->hash_ref_cnt++;
589311878SVenu.Iyer@Sun.COM }
589411878SVenu.Iyer@Sun.COM
589511878SVenu.Iyer@Sun.COM rs = nxge_rx_mac_mcast_hash_table(nxgep);
589611878SVenu.Iyer@Sun.COM if (rs != NPI_SUCCESS)
589711878SVenu.Iyer@Sun.COM goto fail;
58983859Sml29623
58993859Sml29623 RW_EXIT(&nxgep->filter_lock);
59003859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
59013859Sml29623 return (NXGE_OK);
59023859Sml29623 fail:
59033859Sml29623 RW_EXIT(&nxgep->filter_lock);
59043859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
59056929Smisaki "Unable to add multicast address"));
59063859Sml29623 return (status);
59073859Sml29623 }
59083859Sml29623
59093859Sml29623 /* Remove a multicast address entry from the HW hash table */
59103859Sml29623
59113859Sml29623 nxge_status_t
nxge_del_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)59123859Sml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
59133859Sml29623 {
59143859Sml29623 uint32_t mchash;
59153859Sml29623 p_hash_filter_t hash_filter;
59163859Sml29623 uint16_t hash_bit;
59173859Sml29623 uint_t j;
59183859Sml29623 nxge_status_t status = NXGE_OK;
591911878SVenu.Iyer@Sun.COM npi_status_t rs;
59203859Sml29623
59213859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
59223859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock);
59233859Sml29623 mchash = crc32_mchash(addrp);
59243859Sml29623 if (nxgep->hash_filter == NULL) {
59253859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL,
59266929Smisaki "Hash filter already de_allocated."));
59273859Sml29623 RW_EXIT(&nxgep->filter_lock);
59283859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
59293859Sml29623 return (NXGE_OK);
59303859Sml29623 }
59313859Sml29623 hash_filter = nxgep->hash_filter;
59323859Sml29623 hash_filter->hash_bit_ref_cnt[mchash]--;
59333859Sml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
59343859Sml29623 j = mchash / HASH_REG_WIDTH;
59353859Sml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH));
59363859Sml29623 hash_filter->hash_filter_regs[j] &= ~hash_bit;
59373859Sml29623 hash_filter->hash_ref_cnt--;
593811878SVenu.Iyer@Sun.COM }
593911878SVenu.Iyer@Sun.COM
59403859Sml29623 if (hash_filter->hash_ref_cnt == 0) {
59413859Sml29623 NXGE_DEBUG_MSG((NULL, STR_CTL,
59426929Smisaki "De-allocating hash filter storage."));
59433859Sml29623 KMEM_FREE(hash_filter, sizeof (hash_filter_t));
59443859Sml29623 nxgep->hash_filter = NULL;
59453859Sml29623 }
59463859Sml29623
594711878SVenu.Iyer@Sun.COM rs = nxge_rx_mac_mcast_hash_table(nxgep);
594811878SVenu.Iyer@Sun.COM if (rs != NPI_SUCCESS)
594911878SVenu.Iyer@Sun.COM goto fail;
595011878SVenu.Iyer@Sun.COM
59513859Sml29623 RW_EXIT(&nxgep->filter_lock);
59523859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
59533859Sml29623
59543859Sml29623 return (NXGE_OK);
59553859Sml29623 fail:
59563859Sml29623 RW_EXIT(&nxgep->filter_lock);
59573859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
59586929Smisaki "Unable to remove multicast address"));
59593859Sml29623
59603859Sml29623 return (status);
59613859Sml29623 }
59623859Sml29623
59633859Sml29623 /* Set MAC address into MAC address HW registers */
59643859Sml29623
59653859Sml29623 nxge_status_t
nxge_set_mac_addr(p_nxge_t nxgep,struct ether_addr * addrp)59663859Sml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
59673859Sml29623 {
59683859Sml29623 nxge_status_t status = NXGE_OK;
59693859Sml29623
59703859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
59713859Sml29623
59723859Sml29623 MUTEX_ENTER(&nxgep->ouraddr_lock);
59733859Sml29623 /*
59743859Sml29623 * Exit if the address is same as ouraddr or multicast or broadcast
59753859Sml29623 */
59763859Sml29623 if (((addrp->ether_addr_octet[0] & 01) == 1) ||
59776929Smisaki (ether_cmp(addrp, ðerbroadcastaddr) == 0) ||
59786929Smisaki (ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
59793859Sml29623 goto nxge_set_mac_addr_exit;
59803859Sml29623 }
59813859Sml29623 nxgep->ouraddr = *addrp;
59823859Sml29623 /*
59833859Sml29623 * Set new interface local address and re-init device.
59843859Sml29623 * This is destructive to any other streams attached
59853859Sml29623 * to this device.
59863859Sml29623 */
59873859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock);
59883859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
59893859Sml29623 goto fail;
59903859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
59913859Sml29623 goto fail;
59923859Sml29623
59933859Sml29623 RW_EXIT(&nxgep->filter_lock);
59943859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock);
59953859Sml29623 goto nxge_set_mac_addr_end;
59963859Sml29623 nxge_set_mac_addr_exit:
59973859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock);
59983859Sml29623 nxge_set_mac_addr_end:
59993859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
60003859Sml29623
60013859Sml29623 return (NXGE_OK);
60023859Sml29623 fail:
60033859Sml29623 MUTEX_EXIT(&nxgep->ouraddr_lock);
60043859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
60056929Smisaki "Unable to set mac address"));
60063859Sml29623 return (status);
60073859Sml29623 }
60083859Sml29623
60094693Stm144005 static
60104693Stm144005 check_link_state_t
nxge_check_link_stop(nxge_t * nxge)60116835Syc148097 nxge_check_link_stop(nxge_t *nxge)
60124693Stm144005 {
60134693Stm144005 /* If the poll has been cancelled, return STOP. */
60144693Stm144005 MUTEX_ENTER(&nxge->poll_lock);
60154693Stm144005 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
60164693Stm144005 nxge->poll_state = LINK_MONITOR_STOP;
60174693Stm144005 nxge->nxge_link_poll_timerid = 0;
60184693Stm144005 cv_broadcast(&nxge->poll_cv);
60194693Stm144005 MUTEX_EXIT(&nxge->poll_lock);
60204693Stm144005
60214693Stm144005 NXGE_DEBUG_MSG((nxge, MAC_CTL,
60224693Stm144005 "nxge_check_%s_link(port<%d>) stopped.",
60234693Stm144005 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
60244693Stm144005 nxge->mac.portnum));
60254693Stm144005 return (CHECK_LINK_STOP);
60264693Stm144005 }
60274693Stm144005 MUTEX_EXIT(&nxge->poll_lock);
60284693Stm144005
60294693Stm144005 return (CHECK_LINK_RESCHEDULE);
60304693Stm144005 }
60314693Stm144005
60326835Syc148097 /*
60336835Syc148097 * Check status of MII (MIF or PCS) link.
60346835Syc148097 * This function is called once per second, that is because this function
60356835Syc148097 * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to
60366835Syc148097 * call this function recursively.
60376835Syc148097 */
60384732Sdavemq static nxge_status_t
nxge_check_mii_link(p_nxge_t nxgep)60393859Sml29623 nxge_check_mii_link(p_nxge_t nxgep)
60403859Sml29623 {
60413859Sml29623 mii_bmsr_t bmsr_ints, bmsr_data;
60423859Sml29623 mii_anlpar_t anlpar;
60433859Sml29623 mii_gsr_t gsr;
60443859Sml29623 p_mii_regs_t mii_regs;
60453859Sml29623 nxge_status_t status = NXGE_OK;
60463859Sml29623 uint8_t portn;
60473859Sml29623 nxge_link_state_t link_up;
60483859Sml29623
60494693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC)
60504693Stm144005 return (NXGE_ERROR);
60514693Stm144005
60524693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
60534693Stm144005 return (NXGE_OK);
60544693Stm144005
60553859Sml29623 portn = nxgep->mac.portnum;
60563859Sml29623
60573859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
60584693Stm144005 portn));
60593859Sml29623
60603859Sml29623 mii_regs = NULL;
60613859Sml29623
60623859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock);
60633859Sml29623
60643859Sml29623 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
60653859Sml29623 goto nxge_check_mii_link_exit;
60663859Sml29623
60674977Sraghus switch (nxgep->mac.portmode) {
60684977Sraghus default:
60695196Ssbehera bmsr_data.value = 0;
60703859Sml29623 if ((status = nxge_mii_read(nxgep,
60714977Sraghus nxgep->statsp->mac_stats.xcvr_portn,
60725125Sjoycey #if defined(__i386)
60735125Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr),
60745125Sjoycey #else
60754977Sraghus (uint8_t)(uint64_t)(&mii_regs->bmsr),
60765125Sjoycey #endif
60774977Sraghus &bmsr_data.value)) != NXGE_OK) {
60783859Sml29623 goto fail;
60793859Sml29623 }
60804977Sraghus
60815196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
60825196Ssbehera "==> nxge_check_mii_link port<0x%x> "
60835196Ssbehera "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
60845572Ssbehera portn, bmsr_data.value, nxgep->bmsr.value));
60855196Ssbehera
60864977Sraghus if (nxgep->param_arr[param_autoneg].value) {
60874977Sraghus if ((status = nxge_mii_read(nxgep,
60886929Smisaki nxgep->statsp->mac_stats.xcvr_portn,
60895125Sjoycey #if defined(__i386)
60906929Smisaki (uint8_t)(uint32_t)(&mii_regs->gsr),
60915125Sjoycey #else
60926929Smisaki (uint8_t)(uint64_t)(&mii_regs->gsr),
60935125Sjoycey #endif
60946929Smisaki &gsr.value)) != NXGE_OK)
60954977Sraghus goto fail;
60964977Sraghus if ((status = nxge_mii_read(nxgep,
60976929Smisaki nxgep->statsp->mac_stats.xcvr_portn,
60985125Sjoycey #if defined(__i386)
60996929Smisaki (uint8_t)(uint32_t)(&mii_regs->anlpar),
61005125Sjoycey #else
61016929Smisaki (uint8_t)(uint64_t)(&mii_regs->anlpar),
61025125Sjoycey #endif
61036929Smisaki &anlpar.value)) != NXGE_OK)
61044977Sraghus goto fail;
61055196Ssbehera if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
61065196Ssbehera
61075196Ssbehera if (nxgep->statsp->mac_stats.link_up &&
61085196Ssbehera ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
61095196Ssbehera gsr.bits.link_1000fdx) ||
61105196Ssbehera (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
61115196Ssbehera gsr.bits.link_1000hdx) ||
61125196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100T4 ^
61135196Ssbehera anlpar.bits.cap_100T4) ||
61145196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100fdx ^
61155196Ssbehera anlpar.bits.cap_100fdx) ||
61165196Ssbehera (nxgep->statsp->mac_stats.lp_cap_100hdx ^
61175196Ssbehera anlpar.bits.cap_100hdx) ||
61185196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10fdx ^
61195196Ssbehera anlpar.bits.cap_10fdx) ||
61205196Ssbehera (nxgep->statsp->mac_stats.lp_cap_10hdx ^
61215196Ssbehera anlpar.bits.cap_10hdx))) {
61225196Ssbehera bmsr_data.bits.link_status = 0;
61235196Ssbehera }
61244977Sraghus }
61254977Sraghus }
61264977Sraghus
61274977Sraghus /* Workaround for link down issue */
61284977Sraghus if (bmsr_data.value == 0) {
61294977Sraghus cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
61304977Sraghus goto nxge_check_mii_link_exit;
61314977Sraghus }
61324977Sraghus
61335196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61345196Ssbehera "==> nxge_check_mii_link port<0x%x> :"
61355196Ssbehera "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
61365572Ssbehera portn, nxgep->bmsr.value, bmsr_data.value));
61375196Ssbehera
61384977Sraghus bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
61394977Sraghus nxgep->bmsr.value = bmsr_data.value;
61405196Ssbehera
61415196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61425196Ssbehera "==> nxge_check_mii_link port<0x%x> CALLING "
61435196Ssbehera "bmsr_data 0x%x bmsr_ints.value 0x%x",
61445572Ssbehera portn, bmsr_data.value, bmsr_ints.value));
61455196Ssbehera
61464977Sraghus if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints,
61474977Sraghus &link_up)) != NXGE_OK) {
61484977Sraghus goto fail;
61494977Sraghus }
61504977Sraghus break;
61514977Sraghus
61524977Sraghus case PORT_1G_SERDES:
61536835Syc148097 /*
61546835Syc148097 * Above default is for all cases except PORT_1G_SERDES.
61556835Syc148097 * The default case gets information from the PHY, but a
61566835Syc148097 * nxge whose portmode equals PORT_1G_SERDES does not
61576835Syc148097 * have a PHY.
61586835Syc148097 */
61594977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61604977Sraghus "==> nxge_check_mii_link port<%d> (SERDES)", portn));
61616835Syc148097 nxge_pcs_check(nxgep, portn, &link_up);
61624977Sraghus break;
61633859Sml29623 }
61643859Sml29623
61653859Sml29623 nxge_check_mii_link_exit:
61663859Sml29623 RW_EXIT(&nxgep->filter_lock);
61673859Sml29623 if (link_up == LINK_IS_UP) {
61683859Sml29623 nxge_link_is_up(nxgep);
61693859Sml29623 } else if (link_up == LINK_IS_DOWN) {
61703859Sml29623 nxge_link_is_down(nxgep);
61713859Sml29623 }
61723859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
61733859Sml29623
61743859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
61756929Smisaki portn));
61763859Sml29623 return (NXGE_OK);
61773859Sml29623
61783859Sml29623 fail:
61793859Sml29623 RW_EXIT(&nxgep->filter_lock);
61803859Sml29623
61813859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
61823859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
61836929Smisaki "nxge_check_mii_link: Failed to check link port<%d>", portn));
61843859Sml29623 return (status);
61853859Sml29623 }
61863859Sml29623
61873859Sml29623 /*ARGSUSED*/
61884732Sdavemq static nxge_status_t
nxge_check_10g_link(p_nxge_t nxgep)61893859Sml29623 nxge_check_10g_link(p_nxge_t nxgep)
61903859Sml29623 {
61913859Sml29623 uint8_t portn;
61923859Sml29623 nxge_status_t status = NXGE_OK;
61935422Ssbehera boolean_t link_up;
61944977Sraghus uint32_t val;
61954977Sraghus npi_status_t rs;
61963859Sml29623
61974693Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC)
61984693Stm144005 return (NXGE_ERROR);
61994693Stm144005
62004693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
62014693Stm144005 return (NXGE_OK);
62024693Stm144005
62033859Sml29623 portn = nxgep->mac.portnum;
62045196Ssbehera val = 0;
62055196Ssbehera rs = NPI_SUCCESS;
62063859Sml29623
62073859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
62084693Stm144005 portn));
62093859Sml29623
62104977Sraghus switch (nxgep->mac.portmode) {
62114977Sraghus default:
62125572Ssbehera /*
62135572Ssbehera * Check if the phy is present in case of hot swappable phy
62145572Ssbehera */
62155572Ssbehera if (nxgep->hot_swappable_phy) {
62165572Ssbehera boolean_t phy_present_now = B_FALSE;
62175572Ssbehera
621812103SSantwona.Behera@Sun.COM if (nxge_hswap_phy_present(nxgep, portn))
62195572Ssbehera phy_present_now = B_TRUE;
622012103SSantwona.Behera@Sun.COM
62219599Stc99174@train /* Check back-to-back XAUI connect to detect Opus NEM */
62229599Stc99174@train rs = npi_xmac_xpcs_read(nxgep->npi_handle,
62239599Stc99174@train nxgep->mac.portnum, XPCS_REG_STATUS, &val);
62249599Stc99174@train if (rs != 0)
62259599Stc99174@train goto fail;
62269599Stc99174@train
62279599Stc99174@train link_up = B_FALSE;
62289599Stc99174@train if (val & XPCS_STATUS_LANE_ALIGN) {
62299599Stc99174@train link_up = B_TRUE;
62309599Stc99174@train }
62319599Stc99174@train
62325572Ssbehera if (nxgep->phy_absent) {
62335572Ssbehera if (phy_present_now) {
62345572Ssbehera /*
62355572Ssbehera * Detect, Initialize phy and do link up
62365572Ssbehera * set xcvr vals, link_init, nxge_init
62375572Ssbehera */
62385572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62395572Ssbehera "Hot swappable phy DETECTED!!"));
62405572Ssbehera nxgep->phy_absent = B_FALSE;
62415572Ssbehera (void) nxge_xcvr_find(nxgep);
62425572Ssbehera (void) nxge_link_init(nxgep);
62435572Ssbehera if (!(nxgep->drv_state &
62445572Ssbehera STATE_HW_INITIALIZED)) {
62455572Ssbehera status = nxge_init(nxgep);
62465572Ssbehera if (status != NXGE_OK) {
62475572Ssbehera NXGE_ERROR_MSG((nxgep,
62485572Ssbehera NXGE_ERR_CTL,
62495572Ssbehera "Hot swappable "
62505572Ssbehera "phy present, but"
62515572Ssbehera " driver init"
62525572Ssbehera " failed..."));
62535572Ssbehera goto fail;
62545572Ssbehera }
62555572Ssbehera }
62569599Stc99174@train } else if (link_up) { /* XAUI linkup, no PHY */
62579730SMichael.Speer@Sun.COM /*
62589599Stc99174@train * This is the back-to-back XAUI
62599599Stc99174@train * connect case for Opus NEM.
62609599Stc99174@train */
62619599Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse =
62629599Stc99174@train XPCS_XCVR;
62639599Stc99174@train nxgep->mac.portmode = PORT_10G_SERDES;
62649599Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62659599Stc99174@train "HSP 10G Serdes DETECTED!!"));
62669599Stc99174@train break;
62675572Ssbehera }
62685572Ssbehera
626911409Stc99174@train if (nxgep->link_notify &&
627011409Stc99174@train nxgep->link_check_count > 3 &&
627111409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED ||
627211409Stc99174@train nxgep->statsp->mac_stats.link_up == 1) {
627311409Stc99174@train nxgep->statsp->mac_stats.link_up = 0;
627411409Stc99174@train nxgep->statsp->mac_stats.link_speed = 0;
627511409Stc99174@train nxgep->statsp->mac_stats.link_duplex =
627611409Stc99174@train 0;
627711409Stc99174@train
627811409Stc99174@train nxge_link_is_down(nxgep);
627911409Stc99174@train nxgep->link_notify = B_FALSE;
628011409Stc99174@train }
628111409Stc99174@train
62825572Ssbehera goto start_link_check;
62835572Ssbehera
62845572Ssbehera } else if (!phy_present_now) {
62855572Ssbehera /*
62865572Ssbehera * Phy gone, bring link down reset xcvr vals
62875572Ssbehera */
62885572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62895572Ssbehera "Hot swappable phy REMOVED!!"));
62905572Ssbehera nxgep->phy_absent = B_TRUE;
62915572Ssbehera nxgep->statsp->mac_stats.link_up = 0;
62925572Ssbehera nxgep->statsp->mac_stats.link_speed = 0;
62935572Ssbehera nxgep->statsp->mac_stats.link_duplex = 0;
62945572Ssbehera nxge_link_is_down(nxgep);
62955572Ssbehera nxgep->link_notify = B_FALSE;
62965572Ssbehera
62975572Ssbehera (void) nxge_xcvr_find(nxgep);
62985572Ssbehera
62995572Ssbehera goto start_link_check;
63005572Ssbehera
63015572Ssbehera }
63025572Ssbehera }
630312103SSantwona.Behera@Sun.COM
630412103SSantwona.Behera@Sun.COM switch (nxgep->chip_id) {
630512103SSantwona.Behera@Sun.COM case MRVL88X201X_CHIP_ID:
63066835Syc148097 status = nxge_check_mrvl88x2011_link(nxgep, &link_up);
630712103SSantwona.Behera@Sun.COM break;
630812103SSantwona.Behera@Sun.COM case NLP2020_CHIP_ID:
630912103SSantwona.Behera@Sun.COM status = nxge_check_nlp2020_link(nxgep, &link_up);
631012103SSantwona.Behera@Sun.COM break;
631112103SSantwona.Behera@Sun.COM default:
63126604Ssbehera status = nxge_check_bcm8704_link(nxgep, &link_up);
631312103SSantwona.Behera@Sun.COM break;
63146604Ssbehera }
631512103SSantwona.Behera@Sun.COM
63164977Sraghus if (status != NXGE_OK)
63174977Sraghus goto fail;
63184977Sraghus break;
63194977Sraghus case PORT_10G_SERDES:
63204977Sraghus rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
63215422Ssbehera XPCS_REG_STATUS, &val);
63224977Sraghus if (rs != 0)
63234977Sraghus goto fail;
63244977Sraghus
63254977Sraghus link_up = B_FALSE;
63265422Ssbehera if (val & XPCS_STATUS_LANE_ALIGN) {
63275422Ssbehera link_up = B_TRUE;
63284977Sraghus }
63294977Sraghus
63304977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
63314977Sraghus "==> nxge_check_10g_link port<%d> "
63325422Ssbehera "XPCS_REG_STATUS2 0x%x link_up %d",
63335422Ssbehera portn, val, link_up));
63345422Ssbehera
63354977Sraghus break;
63364977Sraghus }
63373859Sml29623
63383859Sml29623 if (link_up) {
633911409Stc99174@train if ((nxgep->link_notify &&
634011409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
63416929Smisaki nxgep->statsp->mac_stats.link_up == 0) {
63423859Sml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
63433859Sml29623 goto fail;
63443859Sml29623 nxgep->statsp->mac_stats.link_up = 1;
63453859Sml29623 nxgep->statsp->mac_stats.link_speed = 10000;
63463859Sml29623 nxgep->statsp->mac_stats.link_duplex = 2;
63473859Sml29623
63483859Sml29623 nxge_link_is_up(nxgep);
63493859Sml29623 nxgep->link_notify = B_FALSE;
63503859Sml29623 }
63513859Sml29623 } else {
635211409Stc99174@train if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
635311409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
63546929Smisaki nxgep->statsp->mac_stats.link_up == 1) {
63553859Sml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
63563859Sml29623 goto fail;
63573859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
63586929Smisaki "Link down cable problem"));
63593859Sml29623 nxgep->statsp->mac_stats.link_up = 0;
63603859Sml29623 nxgep->statsp->mac_stats.link_speed = 0;
63613859Sml29623 nxgep->statsp->mac_stats.link_duplex = 0;
63623859Sml29623
63633859Sml29623 nxge_link_is_down(nxgep);
63643859Sml29623 nxgep->link_notify = B_FALSE;
63659599Stc99174@train
63669599Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES) {
63679599Stc99174@train /*
63689599Stc99174@train * NEM was unplugged, set up xcvr table
63699599Stc99174@train * to find another xcvr in the future.
63709599Stc99174@train */
63719599Stc99174@train (void) nxge_xcvr_find(nxgep);
63729599Stc99174@train }
63733859Sml29623 }
63743859Sml29623 }
63753859Sml29623
63765572Ssbehera start_link_check:
63773859Sml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
63783859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
63794693Stm144005 portn));
63803859Sml29623 return (NXGE_OK);
63813859Sml29623
63823859Sml29623 fail:
63834693Stm144005 (void) nxge_check_link_stop(nxgep);
63844693Stm144005
63853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
63864693Stm144005 "nxge_check_10g_link: Failed to check link port<%d>",
63874693Stm144005 portn));
63883859Sml29623 return (status);
63893859Sml29623 }
63903859Sml29623
63913859Sml29623
63923859Sml29623 /* Declare link down */
63933859Sml29623
63943859Sml29623 void
nxge_link_is_down(p_nxge_t nxgep)63953859Sml29623 nxge_link_is_down(p_nxge_t nxgep)
63963859Sml29623 {
63974732Sdavemq p_nxge_stats_t statsp;
63984732Sdavemq char link_stat_msg[64];
63994732Sdavemq
64003859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
64013859Sml29623
64024732Sdavemq statsp = nxgep->statsp;
64034732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
64044732Sdavemq statsp->mac_stats.xcvr_portn);
64054732Sdavemq
64064732Sdavemq if (nxge_no_msg == B_FALSE) {
64074732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
64084732Sdavemq }
64094732Sdavemq
64103859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_DOWN);
64113859Sml29623
64123859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
64133859Sml29623 }
64143859Sml29623
64153859Sml29623 /* Declare link up */
64163859Sml29623
64173859Sml29623 void
nxge_link_is_up(p_nxge_t nxgep)64183859Sml29623 nxge_link_is_up(p_nxge_t nxgep)
64193859Sml29623 {
64204732Sdavemq p_nxge_stats_t statsp;
64214732Sdavemq char link_stat_msg[64];
64223859Sml29623 uint32_t val;
64233859Sml29623
64243859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
64253859Sml29623
64264732Sdavemq statsp = nxgep->statsp;
64274732Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
64284732Sdavemq statsp->mac_stats.xcvr_portn,
64294732Sdavemq statsp->mac_stats.link_speed);
64304732Sdavemq
64314732Sdavemq if (statsp->mac_stats.link_T4)
64324732Sdavemq (void) strcat(link_stat_msg, "T4");
64334732Sdavemq else if (statsp->mac_stats.link_duplex == 2)
64344732Sdavemq (void) strcat(link_stat_msg, "full duplex");
64354732Sdavemq else
64364732Sdavemq (void) strcat(link_stat_msg, "half duplex");
64374732Sdavemq
64383859Sml29623
64393859Sml29623 /* Clean up symbol errors incurred during link transition */
64404977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
644112103SSantwona.Behera@Sun.COM (nxgep->mac.portmode == PORT_10G_COPPER) ||
64424977Sraghus (nxgep->mac.portmode == PORT_10G_SERDES)) {
64433859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
64446929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
64453859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
64466929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
64473859Sml29623 }
64483859Sml29623
64496835Syc148097 /*
64506835Syc148097 * If the driver was plumbed without a link (therefore auto-negotiation
64516835Syc148097 * could not complete), the driver will detect a link up when a cable
64526835Syc148097 * conneting to a link partner is plugged into the port. By the time
64536835Syc148097 * link-up is detected, auto-negotiation should have completed (The
64546835Syc148097 * TN1010 tries to contact a link partner every 8~24ms). Here we re-
64556835Syc148097 * configure the Neptune/NIU according to the newly negotiated speed.
64566835Syc148097 * This is necessary only for the TN1010 basad device because only the
64576835Syc148097 * TN1010 supports dual speeds.
64586835Syc148097 */
64596835Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 ||
64606835Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) {
64616835Syc148097
64626835Syc148097 (void) nxge_set_tn1010_param(nxgep);
64636835Syc148097
64646835Syc148097 /*
64656835Syc148097 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets
64666835Syc148097 * nxgep->portmode) and nxge_setup_xcvr_table (which sets
64676835Syc148097 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct).
64686835Syc148097 */
64696835Syc148097 if (nxge_xcvr_find(nxgep) != NXGE_OK) {
64706835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
64716835Syc148097 "nxge_link_is_up: nxge_xcvr_find failed"));
64726835Syc148097 }
64736835Syc148097
64746835Syc148097 /* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */
64756835Syc148097 if (nxge_link_init(nxgep) != NXGE_OK) {
64766835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
64776835Syc148097 "nxge_link_is_up: nxge_link_init failed"));
64786835Syc148097 }
64796835Syc148097
64806835Syc148097 /*
64816835Syc148097 * nxge_mac_init calls many subroutines including
64826835Syc148097 * nxge_xif_init which sets XGMII or GMII mode
64836835Syc148097 */
64846835Syc148097 if (nxge_mac_init(nxgep) != NXGE_OK) {
64856835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
64866835Syc148097 "nxge_link_is_up: nxge_mac_init failed"));
64876835Syc148097 }
64886835Syc148097 } else {
64896835Syc148097 (void) nxge_xif_init(nxgep);
64906835Syc148097 }
64916835Syc148097
64924732Sdavemq if (nxge_no_msg == B_FALSE) {
64934732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
64944732Sdavemq }
64954732Sdavemq
64963859Sml29623 mac_link_update(nxgep->mach, LINK_STATE_UP);
64973859Sml29623
64983859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
64993859Sml29623 }
65003859Sml29623
65016835Syc148097 #ifdef NXGE_DEBUG
65026835Syc148097 /* Dump all TN1010 Status registers */
65036835Syc148097 static void
nxge_dump_tn1010_status_regs(p_nxge_t nxgep)65046835Syc148097 nxge_dump_tn1010_status_regs(p_nxge_t nxgep)
65056835Syc148097 {
65066835Syc148097 uint16_t val;
65076835Syc148097
65086835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65096835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 1, &val);
65106835Syc148097 cmn_err(CE_NOTE, "PMA status1 = 0x%x", val);
65116835Syc148097
65126835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65136835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 8, &val);
65146835Syc148097 cmn_err(CE_NOTE, "PMA status2 = 0x%x", val);
65156835Syc148097
65166835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65176835Syc148097 TN1010_PMA_PMD_DEV_ADDR, 129, &val);
65186835Syc148097 cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val);
65196835Syc148097
65206835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65216835Syc148097 TN1010_PCS_DEV_ADDR, 1, &val);
65226835Syc148097 cmn_err(CE_NOTE, "PCS status1 = 0x%x", val);
65236835Syc148097
65246835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65256835Syc148097 TN1010_PCS_DEV_ADDR, 8, &val);
65266835Syc148097 cmn_err(CE_NOTE, "PCS status2 = 0x%x", val);
65276835Syc148097
65286835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65296835Syc148097 TN1010_PCS_DEV_ADDR, 32, &val);
65306835Syc148097 cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val);
65316835Syc148097
65326835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65336835Syc148097 TN1010_PCS_DEV_ADDR, 33, &val);
65346835Syc148097 cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val);
65356835Syc148097
65366835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65376835Syc148097 TN1010_PHYXS_DEV_ADDR, 1, &val);
65386835Syc148097 cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val);
65396835Syc148097
65406835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65416835Syc148097 TN1010_PHYXS_DEV_ADDR, 8, &val);
65426835Syc148097 cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val);
65436835Syc148097
65446835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65456835Syc148097 TN1010_PHYXS_DEV_ADDR, 24, &val);
65466835Syc148097 cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val);
65476835Syc148097
65486835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65496835Syc148097 TN1010_AUTONEG_DEV_ADDR, 1, &val);
65506835Syc148097 cmn_err(CE_NOTE, "Autoneg status = 0x%x", val);
65516835Syc148097
65526835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65536835Syc148097 TN1010_AUTONEG_DEV_ADDR, 33, &val);
65546835Syc148097 cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val);
65556835Syc148097
65566835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65576835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val);
65586835Syc148097 cmn_err(CE_NOTE, "TN1010 status = 0x%x", val);
65596835Syc148097
65606835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65616835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val);
65626835Syc148097 cmn_err(CE_NOTE, "Device status = 0x%x", val);
65636835Syc148097
65646835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65656835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val);
65666835Syc148097 cmn_err(CE_NOTE, "DDR status = 0x%x", val);
65676835Syc148097
65686835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65696835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val);
65706835Syc148097 cmn_err(CE_NOTE, "DDR fault status = 0x%x", val);
65716835Syc148097
65726835Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr,
65736835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val);
65746835Syc148097 cmn_err(CE_NOTE, "Firmware Revision = 0x%x Major = 0x%x Minor = 0x%x",
65756835Syc148097 val, (val & 0xFF00) >> 8, val & 0x00FF);
65766835Syc148097 }
65776835Syc148097 #endif
65786835Syc148097
65793859Sml29623 /*
65803859Sml29623 * Calculate the bit in the multicast address filter
65813859Sml29623 * that selects the given * address.
65823859Sml29623 * Note: For GEM, the last 8-bits are used.
65833859Sml29623 */
65843859Sml29623 uint32_t
crc32_mchash(p_ether_addr_t addr)65853859Sml29623 crc32_mchash(p_ether_addr_t addr)
65863859Sml29623 {
65873859Sml29623 uint8_t *cp;
65883859Sml29623 uint32_t crc;
65893859Sml29623 uint32_t c;
65903859Sml29623 int byte;
65913859Sml29623 int bit;
65923859Sml29623
65933859Sml29623 cp = (uint8_t *)addr;
65943859Sml29623 crc = (uint32_t)0xffffffff;
65953859Sml29623 for (byte = 0; byte < 6; byte++) {
65963859Sml29623 c = (uint32_t)cp[byte];
65973859Sml29623 for (bit = 0; bit < 8; bit++) {
65983859Sml29623 if ((c & 0x1) ^ (crc & 0x1))
65993859Sml29623 crc = (crc >> 1)^0xedb88320;
66003859Sml29623 else
66013859Sml29623 crc = (crc >> 1);
66023859Sml29623 c >>= 1;
66033859Sml29623 }
66043859Sml29623 }
66053859Sml29623 return ((~crc) >> (32 - HASH_BITS));
66063859Sml29623 }
66073859Sml29623
66083859Sml29623 /* Reset serdes */
66093859Sml29623
66103859Sml29623 nxge_status_t
nxge_serdes_reset(p_nxge_t nxgep)66113859Sml29623 nxge_serdes_reset(p_nxge_t nxgep)
66123859Sml29623 {
66133859Sml29623 npi_handle_t handle;
66143859Sml29623
66153859Sml29623 handle = nxgep->npi_handle;
66163859Sml29623
66173859Sml29623 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
66183859Sml29623 drv_usecwait(500);
66193859Sml29623 ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
66203859Sml29623
66213859Sml29623 return (NXGE_OK);
66223859Sml29623 }
66233859Sml29623
66246835Syc148097 /*
66256835Syc148097 * This function monitors link status using interrupt or polling.
66266835Syc148097 * It calls nxgep->xcvr.check_link, a member function of
66276835Syc148097 * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this
66286835Syc148097 * function back, that is why the check_link routine is
66296835Syc148097 * executed periodically.
66306835Syc148097 */
66313859Sml29623 nxge_status_t
nxge_link_monitor(p_nxge_t nxgep,link_mon_enable_t enable)66323859Sml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
66333859Sml29623 {
66343859Sml29623 nxge_status_t status = NXGE_OK;
66353859Sml29623
66366495Sspeer /* If we are a guest domain driver, don't bother. */
66376495Sspeer if (isLDOMguest(nxgep))
66386495Sspeer return (status);
66396495Sspeer
66403859Sml29623 /*
66414693Stm144005 * Return immediately if this is an imaginary XMAC port.
66424693Stm144005 * (At least, we don't have 4-port XMAC cards yet.)
66433859Sml29623 */
66444977Sraghus if ((nxgep->mac.portmode == PORT_10G_FIBER ||
664512103SSantwona.Behera@Sun.COM nxgep->mac.portmode == PORT_10G_COPPER ||
66464977Sraghus nxgep->mac.portmode == PORT_10G_SERDES) &&
66474977Sraghus (nxgep->mac.portnum > 1))
66483859Sml29623 return (NXGE_OK);
66493859Sml29623
66503859Sml29623 if (nxgep->statsp == NULL) {
66513859Sml29623 /* stats has not been allocated. */
66523859Sml29623 return (NXGE_OK);
66533859Sml29623 }
66546075Ssbehera /* Don't check link if we're in internal loopback mode */
66556075Ssbehera if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g)
66563859Sml29623 return (NXGE_OK);
66573859Sml29623
66583859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
66594693Stm144005 "==> nxge_link_monitor port<%d> enable=%d",
66604693Stm144005 nxgep->mac.portnum, enable));
66613859Sml29623 if (enable == LINK_MONITOR_START) {
66623859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
66633859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
66644693Stm144005 != NXGE_OK)
66653859Sml29623 goto fail;
66663859Sml29623 } else {
66674693Stm144005 timeout_id_t timerid;
66686835Syc148097 /*
66696835Syc148097 * check_link_stop means "Stop the link check", so
66706835Syc148097 * we return without starting the timer.
66716835Syc148097 */
66724693Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
66734693Stm144005 return (NXGE_OK);
66744693Stm144005
66756835Syc148097 /*
66766835Syc148097 * Otherwise fire the timer for the nxge to check
66776835Syc148097 * the link using the check_link function
66786835Syc148097 * of the nxge_xcvr_table and pass "nxgep" as the
66796835Syc148097 * argument to the check_link function.
66806835Syc148097 */
66814732Sdavemq if (nxgep->xcvr.check_link) {
66824732Sdavemq timerid = timeout(
66834732Sdavemq (fptrv_t)(nxgep->xcvr.check_link),
66844693Stm144005 nxgep,
66854693Stm144005 drv_usectohz(LINK_MONITOR_PERIOD));
66864732Sdavemq MUTEX_ENTER(&nxgep->poll_lock);
66874732Sdavemq nxgep->nxge_link_poll_timerid = timerid;
66884732Sdavemq MUTEX_EXIT(&nxgep->poll_lock);
668911409Stc99174@train nxgep->link_check_count ++;
66904732Sdavemq } else {
66914693Stm144005 return (NXGE_ERROR);
66923859Sml29623 }
66933859Sml29623 }
66943859Sml29623 } else {
66953859Sml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
66963859Sml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
66974693Stm144005 != NXGE_OK)
66983859Sml29623 goto fail;
66993859Sml29623 } else {
67004693Stm144005 clock_t rv;
67014693Stm144005
67024693Stm144005 MUTEX_ENTER(&nxgep->poll_lock);
67034693Stm144005
67044693Stm144005 /* If <timerid> == 0, the link monitor has */
67054693Stm144005 /* never been started, or just now stopped. */
67064693Stm144005 if (nxgep->nxge_link_poll_timerid == 0) {
67074693Stm144005 MUTEX_EXIT(&nxgep->poll_lock);
67084693Stm144005 return (NXGE_OK);
67094693Stm144005 }
67104693Stm144005
67114693Stm144005 nxgep->poll_state = LINK_MONITOR_STOPPING;
671211066Srafael.vanoni@sun.com rv = cv_reltimedwait(&nxgep->poll_cv, &nxgep->poll_lock,
67134693Stm144005 drv_usectohz(LM_WAIT_MULTIPLIER *
671411066Srafael.vanoni@sun.com LINK_MONITOR_PERIOD), TR_CLOCK_TICK);
67154693Stm144005 if (rv == -1) {
67164693Stm144005 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
67174693Stm144005 "==> stopping port %d: "
67184693Stm144005 "cv_timedwait(%d) timed out",
67194693Stm144005 nxgep->mac.portnum, nxgep->poll_state));
67204693Stm144005 nxgep->poll_state = LINK_MONITOR_STOP;
67213859Sml29623 nxgep->nxge_link_poll_timerid = 0;
67223859Sml29623 }
67234693Stm144005
67244693Stm144005 MUTEX_EXIT(&nxgep->poll_lock);
67253859Sml29623 }
67263859Sml29623 }
67273859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
67284693Stm144005 "<== nxge_link_monitor port<%d> enable=%d",
67294693Stm144005 nxgep->mac.portnum, enable));
67306495Sspeer
67313859Sml29623 return (NXGE_OK);
67323859Sml29623 fail:
67333859Sml29623 return (status);
67346835Syc148097
67353859Sml29623 }
67363859Sml29623
67376835Syc148097 nxge_status_t
nxge_check_tn1010_link(p_nxge_t nxgep)67386835Syc148097 nxge_check_tn1010_link(p_nxge_t nxgep)
67396835Syc148097 {
67406835Syc148097 nxge_status_t status = NXGE_OK;
67416835Syc148097 nxge_link_state_t link_up;
67426835Syc148097
67436835Syc148097 if (nxgep->nxge_magic != NXGE_MAGIC) {
67446835Syc148097 /* magic is 0 if driver is not attached */
67456835Syc148097 return (NXGE_ERROR);
67466835Syc148097 }
67476835Syc148097
67486835Syc148097 /* Link has been stopped, no need to continue */
67496835Syc148097 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) {
67506835Syc148097 return (NXGE_OK);
67516835Syc148097 }
67526835Syc148097
67536835Syc148097 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
67546835Syc148097 goto nxge_check_tn1010_link_exit;
67556835Syc148097
67566835Syc148097 if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK)
67576835Syc148097 goto fail;
67586835Syc148097
67596835Syc148097 nxge_check_tn1010_link_exit:
67606835Syc148097 if (link_up == LINK_IS_UP)
67616835Syc148097 nxge_link_is_up(nxgep);
67626835Syc148097 else if (link_up == LINK_IS_DOWN)
67636835Syc148097 nxge_link_is_down(nxgep);
67646835Syc148097
67656835Syc148097 /*
67666835Syc148097 * nxge_link_monitor will call (nxgep->xcvr.check_link)
67676835Syc148097 * which could be THIS function.
67686835Syc148097 */
67696835Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
67706835Syc148097
67716835Syc148097 return (NXGE_OK);
67726835Syc148097
67736835Syc148097 fail:
67746835Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
67756835Syc148097
67766835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
67776835Syc148097 "nxge_check_tn1010_link: Failed to check link"));
67786835Syc148097 return (status);
67796835Syc148097 }
67806835Syc148097
67816835Syc148097
67826835Syc148097 /*
67836835Syc148097 * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN.
67846835Syc148097 */
67856835Syc148097 static nxge_status_t
nxge_tn1010_check(p_nxge_t nxgep,nxge_link_state_t * link_up)67866835Syc148097 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up)
67876835Syc148097 {
67886835Syc148097 nxge_status_t status = NXGE_OK;
67896835Syc148097 p_nxge_stats_t statsp;
67906835Syc148097 uint8_t phy_port_addr, portn;
67916835Syc148097 uint16_t val;
67926835Syc148097
67936835Syc148097 *link_up = LINK_NO_CHANGE;
67946835Syc148097
67956835Syc148097 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
67966835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
67976835Syc148097 statsp = nxgep->statsp;
67986835Syc148097
67996835Syc148097 /* Check if link is up */
68006835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr,
68016835Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val))
68026835Syc148097 != NXGE_OK) {
68036835Syc148097 goto fail;
68046835Syc148097 }
68056835Syc148097 /*
68066835Syc148097 * nxge_link_is_up has called nxge_set_tn1010_param and set
68076835Syc148097 * portmode and link_speed
68086835Syc148097 */
68096835Syc148097 if (val & TN1010_AN_LINK_STAT_BIT) {
681011409Stc99174@train if ((nxgep->link_notify &&
681111409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
68126835Syc148097 nxgep->statsp->mac_stats.link_up == 0) {
68136835Syc148097 statsp->mac_stats.link_up = 1;
68146835Syc148097 statsp->mac_stats.link_duplex = 2;
68156835Syc148097 *link_up = LINK_IS_UP;
68166835Syc148097 nxgep->link_notify = B_FALSE;
68176835Syc148097 }
68186835Syc148097 } else {
681911409Stc99174@train if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
682011409Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
68216835Syc148097 nxgep->statsp->mac_stats.link_up == 1) {
68226835Syc148097 statsp->mac_stats.link_up = 0;
68236835Syc148097 statsp->mac_stats.link_speed = 0;
68246835Syc148097 statsp->mac_stats.link_duplex = 0;
68256835Syc148097 *link_up = LINK_IS_DOWN;
68266835Syc148097 nxgep->link_notify = B_FALSE;
68276835Syc148097 }
68286835Syc148097 }
68296835Syc148097 return (NXGE_OK);
68306835Syc148097
68316835Syc148097 fail:
68326835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
68336835Syc148097 "nxge_tn1010_check: Unable to check TN1010"));
68346835Syc148097 return (status);
68356835Syc148097 }
68366835Syc148097
68376835Syc148097
68383859Sml29623 /* Set promiscous mode */
68393859Sml29623
68403859Sml29623 nxge_status_t
nxge_set_promisc(p_nxge_t nxgep,boolean_t on)68413859Sml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
68423859Sml29623 {
68433859Sml29623 nxge_status_t status = NXGE_OK;
68443859Sml29623
68454732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
68463859Sml29623
68473859Sml29623 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
68483859Sml29623
68493859Sml29623 RW_ENTER_WRITER(&nxgep->filter_lock);
68503859Sml29623
68513859Sml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
68523859Sml29623 goto fail;
68533859Sml29623 }
68543859Sml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
68553859Sml29623 goto fail;
68563859Sml29623 }
68573859Sml29623
68583859Sml29623 RW_EXIT(&nxgep->filter_lock);
68593859Sml29623
68603859Sml29623 if (on)
68613859Sml29623 nxgep->statsp->mac_stats.promisc = B_TRUE;
68623859Sml29623 else
68633859Sml29623 nxgep->statsp->mac_stats.promisc = B_FALSE;
68643859Sml29623
68653859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
68663859Sml29623
68673859Sml29623 return (NXGE_OK);
68683859Sml29623 fail:
68693859Sml29623 RW_EXIT(&nxgep->filter_lock);
68703859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
68714732Sdavemq "Unable to set promisc (%d)", on));
68723859Sml29623
68733859Sml29623 return (status);
68743859Sml29623 }
68753859Sml29623
68763859Sml29623 /*ARGSUSED*/
68773859Sml29623 uint_t
nxge_mif_intr(void * arg1,void * arg2)68783859Sml29623 nxge_mif_intr(void *arg1, void *arg2)
68793859Sml29623 {
68803859Sml29623 #ifdef NXGE_DEBUG
68813859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2;
68823859Sml29623 #endif
68833859Sml29623 #if NXGE_MIF
68843859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1;
68853859Sml29623 uint32_t status;
68863859Sml29623 npi_handle_t handle;
68873859Sml29623 uint8_t portn;
68883859Sml29623 p_nxge_stats_t statsp;
68893859Sml29623 #endif
68903859Sml29623
68913859Sml29623 #ifdef NXGE_MIF
68923859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
68933859Sml29623 nxgep = ldvp->nxgep;
68943859Sml29623 }
68953859Sml29623 nxgep = ldvp->nxgep;
68963859Sml29623 #endif
68973859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
68983859Sml29623
68993859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
69003859Sml29623 return (DDI_INTR_CLAIMED);
69013859Sml29623
69023859Sml29623 mif_intr_fail:
69033859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
69043859Sml29623 return (DDI_INTR_UNCLAIMED);
69053859Sml29623 }
69063859Sml29623
69073859Sml29623 /*ARGSUSED*/
69083859Sml29623 uint_t
nxge_mac_intr(void * arg1,void * arg2)69093859Sml29623 nxge_mac_intr(void *arg1, void *arg2)
69103859Sml29623 {
69113859Sml29623 p_nxge_t nxgep = (p_nxge_t)arg2;
69123859Sml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1;
69133859Sml29623 p_nxge_ldg_t ldgp;
69143859Sml29623 uint32_t status;
69153859Sml29623 npi_handle_t handle;
69163859Sml29623 uint8_t portn;
69173859Sml29623 p_nxge_stats_t statsp;
69183859Sml29623 npi_status_t rs = NPI_SUCCESS;
69193859Sml29623
69203859Sml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
69213859Sml29623 nxgep = ldvp->nxgep;
69223859Sml29623 }
69233859Sml29623
69243859Sml29623 ldgp = ldvp->ldgp;
69253859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
69264732Sdavemq "group %d", ldgp->ldg));
69273859Sml29623
69283859Sml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep);
69293859Sml29623 /*
69303859Sml29623 * This interrupt handler is for a specific
69313859Sml29623 * mac port.
69323859Sml29623 */
69333859Sml29623 statsp = (p_nxge_stats_t)nxgep->statsp;
69343859Sml29623 portn = nxgep->mac.portnum;
69353859Sml29623
69363859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL,
69374732Sdavemq "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
69383859Sml29623
69393859Sml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
69403859Sml29623 rs = npi_xmac_tx_get_istatus(handle, portn,
69416929Smisaki (xmac_tx_iconfig_t *)&status);
69423859Sml29623 if (rs != NPI_SUCCESS)
69433859Sml29623 goto npi_fail;
69443859Sml29623 if (status & ICFG_XMAC_TX_ALL) {
69453859Sml29623 if (status & ICFG_XMAC_TX_UNDERRUN) {
69463859Sml29623 statsp->xmac_stats.tx_underflow_err++;
69473859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69486929Smisaki NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
69493859Sml29623 }
69503859Sml29623 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
69513859Sml29623 statsp->xmac_stats.tx_maxpktsize_err++;
69525523Syc148097 /*
69535523Syc148097 * Do not send FMA ereport because this
69545523Syc148097 * error does not indicate HW failure.
69555523Syc148097 */
69563859Sml29623 }
69573859Sml29623 if (status & ICFG_XMAC_TX_OVERFLOW) {
69583859Sml29623 statsp->xmac_stats.tx_overflow_err++;
69593859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69606929Smisaki NXGE_FM_EREPORT_TXMAC_OVERFLOW);
69613859Sml29623 }
69623859Sml29623 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
69633859Sml29623 statsp->xmac_stats.tx_fifo_xfr_err++;
69643859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69656929Smisaki NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
69663859Sml29623 }
69673859Sml29623 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
69683859Sml29623 statsp->xmac_stats.tx_byte_cnt +=
69696929Smisaki XTXMAC_BYTE_CNT_MASK;
69703859Sml29623 }
69713859Sml29623 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
69723859Sml29623 statsp->xmac_stats.tx_frame_cnt +=
69736929Smisaki XTXMAC_FRM_CNT_MASK;
69743859Sml29623 }
69753859Sml29623 }
69763859Sml29623
69773859Sml29623 rs = npi_xmac_rx_get_istatus(handle, portn,
69786929Smisaki (xmac_rx_iconfig_t *)&status);
69793859Sml29623 if (rs != NPI_SUCCESS)
69803859Sml29623 goto npi_fail;
69813859Sml29623 if (status & ICFG_XMAC_RX_ALL) {
69823859Sml29623 if (status & ICFG_XMAC_RX_OVERFLOW)
69833859Sml29623 statsp->xmac_stats.rx_overflow_err++;
69843859Sml29623 if (status & ICFG_XMAC_RX_UNDERFLOW) {
69853859Sml29623 statsp->xmac_stats.rx_underflow_err++;
69863859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
69876929Smisaki NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
69883859Sml29623 }
69895523Syc148097 /*
69905523Syc148097 * Do not send FMA ereport for the following 3 errors
69915523Syc148097 * because they do not indicate HW failures.
69925523Syc148097 */
69933859Sml29623 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
69943859Sml29623 statsp->xmac_stats.rx_crc_err_cnt +=
69956929Smisaki XRXMAC_CRC_ER_CNT_MASK;
69963859Sml29623 }
69973859Sml29623 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
69983859Sml29623 statsp->xmac_stats.rx_len_err_cnt +=
69996929Smisaki MAC_LEN_ER_CNT_MASK;
70003859Sml29623 }
70013859Sml29623 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
70023859Sml29623 statsp->xmac_stats.rx_viol_err_cnt +=
70036929Smisaki XRXMAC_CD_VIO_CNT_MASK;
70043859Sml29623 }
70053859Sml29623 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
70063859Sml29623 statsp->xmac_stats.rx_byte_cnt +=
70076929Smisaki XRXMAC_BT_CNT_MASK;
70083859Sml29623 }
70093859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
70103859Sml29623 statsp->xmac_stats.rx_hist1_cnt +=
70116929Smisaki XRXMAC_HIST_CNT1_MASK;
70123859Sml29623 }
70133859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
70143859Sml29623 statsp->xmac_stats.rx_hist2_cnt +=
70156929Smisaki XRXMAC_HIST_CNT2_MASK;
70163859Sml29623 }
70173859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
70183859Sml29623 statsp->xmac_stats.rx_hist3_cnt +=
70196929Smisaki XRXMAC_HIST_CNT3_MASK;
70203859Sml29623 }
70213859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
70223859Sml29623 statsp->xmac_stats.rx_hist4_cnt +=
70236929Smisaki XRXMAC_HIST_CNT4_MASK;
70243859Sml29623 }
70253859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
70263859Sml29623 statsp->xmac_stats.rx_hist5_cnt +=
70276929Smisaki XRXMAC_HIST_CNT5_MASK;
70283859Sml29623 }
70293859Sml29623 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
70303859Sml29623 statsp->xmac_stats.rx_hist6_cnt +=
70316929Smisaki XRXMAC_HIST_CNT6_MASK;
70323859Sml29623 }
70333859Sml29623 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
70343859Sml29623 statsp->xmac_stats.rx_broadcast_cnt +=
70356929Smisaki XRXMAC_BC_FRM_CNT_MASK;
70363859Sml29623 }
70373859Sml29623 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
70383859Sml29623 statsp->xmac_stats.rx_mult_cnt +=
70396929Smisaki XRXMAC_MC_FRM_CNT_MASK;
70403859Sml29623 }
70415523Syc148097 /*
70425523Syc148097 * Do not send FMA ereport for the following 3 errors
70435523Syc148097 * because they do not indicate HW failures.
70445523Syc148097 */
70453859Sml29623 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
70463859Sml29623 statsp->xmac_stats.rx_frag_cnt +=
70476929Smisaki XRXMAC_FRAG_CNT_MASK;
70483859Sml29623 }
70493859Sml29623 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
70503859Sml29623 statsp->xmac_stats.rx_frame_align_err_cnt +=
70516929Smisaki XRXMAC_AL_ER_CNT_MASK;
70523859Sml29623 }
70533859Sml29623 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
70543859Sml29623 statsp->xmac_stats.rx_linkfault_err_cnt +=
70556929Smisaki XMAC_LINK_FLT_CNT_MASK;
70563859Sml29623 }
70573859Sml29623 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
70583859Sml29623 statsp->xmac_stats.rx_remotefault_err++;
70593859Sml29623 }
70603859Sml29623 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
70613859Sml29623 statsp->xmac_stats.rx_localfault_err++;
70623859Sml29623 }
70633859Sml29623 }
70643859Sml29623
70653859Sml29623 rs = npi_xmac_ctl_get_istatus(handle, portn,
70666929Smisaki (xmac_ctl_iconfig_t *)&status);
70673859Sml29623 if (rs != NPI_SUCCESS)
70683859Sml29623 goto npi_fail;
70693859Sml29623 if (status & ICFG_XMAC_CTRL_ALL) {
70703859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
70713859Sml29623 statsp->xmac_stats.rx_pause_cnt++;
70723859Sml29623 if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
70733859Sml29623 statsp->xmac_stats.tx_pause_state++;
70743859Sml29623 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
70753859Sml29623 statsp->xmac_stats.tx_nopause_state++;
70763859Sml29623 }
70773859Sml29623 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
70783859Sml29623 rs = npi_bmac_tx_get_istatus(handle, portn,
70796929Smisaki (bmac_tx_iconfig_t *)&status);
70803859Sml29623 if (rs != NPI_SUCCESS)
70813859Sml29623 goto npi_fail;
70823859Sml29623 if (status & ICFG_BMAC_TX_ALL) {
70833859Sml29623 if (status & ICFG_BMAC_TX_UNDERFLOW) {
70843859Sml29623 statsp->bmac_stats.tx_underrun_err++;
70853859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
70866929Smisaki NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
70873859Sml29623 }
70883859Sml29623 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
70893859Sml29623 statsp->bmac_stats.tx_max_pkt_err++;
70903859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
70916929Smisaki NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
70923859Sml29623 }
70933859Sml29623 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
70943859Sml29623 statsp->bmac_stats.tx_byte_cnt +=
70956929Smisaki BTXMAC_BYTE_CNT_MASK;
70963859Sml29623 }
70973859Sml29623 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
70983859Sml29623 statsp->bmac_stats.tx_frame_cnt +=
70996929Smisaki BTXMAC_FRM_CNT_MASK;
71003859Sml29623 }
71013859Sml29623 }
71023859Sml29623
71033859Sml29623 rs = npi_bmac_rx_get_istatus(handle, portn,
71046929Smisaki (bmac_rx_iconfig_t *)&status);
71053859Sml29623 if (rs != NPI_SUCCESS)
71063859Sml29623 goto npi_fail;
71073859Sml29623 if (status & ICFG_BMAC_RX_ALL) {
71083859Sml29623 if (status & ICFG_BMAC_RX_OVERFLOW) {
71093859Sml29623 statsp->bmac_stats.rx_overflow_err++;
71103859Sml29623 }
71113859Sml29623 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
71123859Sml29623 statsp->bmac_stats.rx_frame_cnt +=
71136929Smisaki RXMAC_FRM_CNT_MASK;
71143859Sml29623 }
71153859Sml29623 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
71163859Sml29623 statsp->bmac_stats.rx_crc_err_cnt +=
71176929Smisaki BMAC_CRC_ER_CNT_MASK;
71183859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71196929Smisaki NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
71203859Sml29623 }
71213859Sml29623 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
71223859Sml29623 statsp->bmac_stats.rx_len_err_cnt +=
71236929Smisaki MAC_LEN_ER_CNT_MASK;
71243859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71256929Smisaki NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
71263859Sml29623 }
71273859Sml29623 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP)
71283859Sml29623 statsp->bmac_stats.rx_viol_err_cnt +=
71296929Smisaki BMAC_CD_VIO_CNT_MASK;
71303859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71316929Smisaki NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
71323859Sml29623 }
71333859Sml29623 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
71343859Sml29623 statsp->bmac_stats.rx_byte_cnt +=
71356929Smisaki BRXMAC_BYTE_CNT_MASK;
71363859Sml29623 }
71373859Sml29623 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
71383859Sml29623 statsp->bmac_stats.rx_align_err_cnt +=
71396929Smisaki BMAC_AL_ER_CNT_MASK;
71403859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
71416929Smisaki NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
71423859Sml29623 }
71433859Sml29623
71443859Sml29623 rs = npi_bmac_ctl_get_istatus(handle, portn,
71456929Smisaki (bmac_ctl_iconfig_t *)&status);
71463859Sml29623 if (rs != NPI_SUCCESS)
71473859Sml29623 goto npi_fail;
71483859Sml29623
71493859Sml29623 if (status & ICFG_BMAC_CTL_ALL) {
71503859Sml29623 if (status & ICFG_BMAC_CTL_RCVPAUSE)
71513859Sml29623 statsp->bmac_stats.rx_pause_cnt++;
71523859Sml29623 if (status & ICFG_BMAC_CTL_INPAUSE_ST)
71533859Sml29623 statsp->bmac_stats.tx_pause_state++;
71543859Sml29623 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
71553859Sml29623 statsp->bmac_stats.tx_nopause_state++;
71563859Sml29623 }
71573859Sml29623 }
71583859Sml29623
71593859Sml29623 if (ldgp->nldvs == 1) {
71603859Sml29623 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
71616929Smisaki B_TRUE, ldgp->ldg_timer);
71623859Sml29623 }
71633859Sml29623
71643859Sml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
71653859Sml29623 return (DDI_INTR_CLAIMED);
71663859Sml29623
71673859Sml29623 npi_fail:
71683859Sml29623 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
71693859Sml29623 return (DDI_INTR_UNCLAIMED);
71703859Sml29623 }
71713859Sml29623
71723859Sml29623 nxge_status_t
nxge_check_bcm8704_link(p_nxge_t nxgep,boolean_t * link_up)71733859Sml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
71743859Sml29623 {
71753859Sml29623 uint8_t phy_port_addr;
71763859Sml29623 nxge_status_t status = NXGE_OK;
71773859Sml29623 boolean_t rx_sig_ok;
71783859Sml29623 boolean_t pcs_blk_lock;
71793859Sml29623 boolean_t link_align;
71803859Sml29623 uint16_t val1, val2, val3;
71813859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR
71823859Sml29623 uint16_t val_debug;
718311304SJanie.Lu@Sun.COM uint32_t val;
71843859Sml29623 #endif
71853859Sml29623
71863859Sml29623 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
71873859Sml29623
71883859Sml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR
71893859Sml29623 /* Check Device 3 Register Device 3 0xC809 */
71903859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
71913859Sml29623 if ((val_debug & ~0x200) != 0) {
71923859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
71936929Smisaki nxgep->mac.portnum, val_debug);
71943859Sml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
71956929Smisaki &val_debug);
71963859Sml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
71976929Smisaki nxgep->mac.portnum, val_debug);
71983859Sml29623 }
71993859Sml29623
72003859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
72016929Smisaki XPCS_REG_DESCWERR_COUNTER, &val);
72023859Sml29623 if (val != 0)
72033859Sml29623 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
72043859Sml29623
72053859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
72066929Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
72073859Sml29623 if (val != 0)
72083859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
72093859Sml29623
72103859Sml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
72116929Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
72123859Sml29623 if (val != 0)
72133859Sml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
72143859Sml29623 #endif
72153859Sml29623
72163859Sml29623 /* Check from BCM8704 if 10G link is up or down */
72173859Sml29623
72183859Sml29623 /* Check Device 1 Register 0xA bit0 */
72196929Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR,
72206929Smisaki BCM8704_PMD_RECEIVE_SIG_DETECT, &val1);
72213859Sml29623 if (status != NXGE_OK)
72223859Sml29623 goto fail;
72233859Sml29623 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
72243859Sml29623
72253859Sml29623 /* Check Device 3 Register 0x20 bit0 */
72266929Smisaki if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR,
72276929Smisaki BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS)
72283859Sml29623 goto fail;
72293859Sml29623 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
72303859Sml29623
72313859Sml29623 /* Check Device 4 Register 0x18 bit12 */
72326929Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
72336929Smisaki BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3);
72343859Sml29623 if (status != NXGE_OK)
72353859Sml29623 goto fail;
72365572Ssbehera
72375572Ssbehera switch (nxgep->chip_id) {
72385572Ssbehera case BCM8704_CHIP_ID:
72395572Ssbehera link_align = (val3 == (XGXS_LANE_ALIGN_STATUS |
72405572Ssbehera XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
72415572Ssbehera XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
72425572Ssbehera break;
72435572Ssbehera case BCM8706_CHIP_ID:
72445572Ssbehera link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) &&
72455572Ssbehera (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) &&
72465572Ssbehera (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ?
72475572Ssbehera B_TRUE : B_FALSE;
72485572Ssbehera break;
72495572Ssbehera default:
72505572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:"
72515572Ssbehera "Unknown chip ID [0x%x]", nxgep->chip_id));
72525572Ssbehera goto fail;
72535572Ssbehera }
72545572Ssbehera
72553859Sml29623 #ifdef NXGE_DEBUG_ALIGN_ERR
72563859Sml29623 /* Temp workaround for link down issue */
72573859Sml29623 if (pcs_blk_lock == B_FALSE) {
72583859Sml29623 if (val2 != 0x4) {
72593859Sml29623 pcs_blk_lock = B_TRUE;
72606929Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 "
72616929Smisaki "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2);
72623859Sml29623 }
72633859Sml29623 }
72643859Sml29623
72653859Sml29623 if (link_align == B_FALSE) {
72663859Sml29623 if (val3 != 0x140f) {
72673859Sml29623 link_align = B_TRUE;
72686929Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 "
72696929Smisaki "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3);
72703859Sml29623 }
72713859Sml29623 }
72723859Sml29623
72733859Sml29623 if (rx_sig_ok == B_FALSE) {
72743859Sml29623 if ((val2 == 0) || (val3 == 0)) {
72753859Sml29623 rx_sig_ok = B_TRUE;
72763859Sml29623 cmn_err(CE_NOTE,
72776929Smisaki "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
72786929Smisaki nxgep->mac.portnum);
72793859Sml29623 }
72803859Sml29623 }
72813859Sml29623 #endif
72823859Sml29623
72833859Sml29623 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
72846929Smisaki (link_align == B_TRUE)) ? B_TRUE : B_FALSE;
72853859Sml29623
72863859Sml29623 return (NXGE_OK);
72873859Sml29623 fail:
72883859Sml29623 return (status);
72893859Sml29623 }
72903859Sml29623
72916604Ssbehera static nxge_status_t
nxge_check_mrvl88x2011_link(p_nxge_t nxgep,boolean_t * link_up)72926835Syc148097 nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up)
72936604Ssbehera {
72946604Ssbehera uint8_t phy;
72956604Ssbehera nxge_status_t status = NXGE_OK;
72966604Ssbehera boolean_t pma_status;
72976604Ssbehera boolean_t pcs_status;
72986604Ssbehera boolean_t xgxs_status;
72996604Ssbehera uint16_t val;
73006604Ssbehera
73016604Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn;
73026604Ssbehera
73036604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
73046604Ssbehera MRVL_88X2011_10G_PMD_STAT_2, &val);
73056604Ssbehera
73066604Ssbehera *link_up = B_FALSE;
73076604Ssbehera
73086604Ssbehera /* Check from Marvell 88X2011 if 10G link is up or down */
73096604Ssbehera
73106604Ssbehera /* Check PMA/PMD Register: 1.0001.2 == 1 */
73116604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
73126604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val);
73136604Ssbehera
73146604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73156604Ssbehera "nxge_check_mrvl88x2011_link: pmd=0x%x", val));
73166604Ssbehera
73176604Ssbehera pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
73186604Ssbehera
73196604Ssbehera /* Check PMC Register : 3.0001.2 == 1: read twice */
73206604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
73216604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val);
73226604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
73236604Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val);
73246604Ssbehera
73256604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73266604Ssbehera "nxge_check_mrvl88x2011_link: pcs=0x%x", val));
73276604Ssbehera
73286604Ssbehera pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
73296604Ssbehera
73306604Ssbehera /* Check XGXS Register : 4.0018.[0-3,12] */
73316604Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR,
73326604Ssbehera MRVL_88X2011_10G_XGXS_LANE_STAT, &val);
73336604Ssbehera
73346604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73356604Ssbehera "nxge_check_mrvl88x2011_link: xgxs=0x%x", val));
73366604Ssbehera
73376604Ssbehera xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC |
73386604Ssbehera XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
73396604Ssbehera XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY |
73406604Ssbehera XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE;
73416604Ssbehera
73426604Ssbehera *link_up = (pma_status && pcs_status && xgxs_status) ?
73436604Ssbehera B_TRUE : B_FALSE;
73446604Ssbehera
73456604Ssbehera fail:
73466604Ssbehera
73476604Ssbehera if (*link_up == B_FALSE) {
73486604Ssbehera /* PCS OFF */
73496604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF);
73506604Ssbehera } else {
73516604Ssbehera /* PCS Activity */
73526604Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT);
73536604Ssbehera }
73546604Ssbehera
73556604Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
73566604Ssbehera " <== nxge_check_mrvl88x2011_link: up=%d", *link_up));
73576604Ssbehera
73586604Ssbehera return (status);
73596604Ssbehera }
73606604Ssbehera
736112103SSantwona.Behera@Sun.COM static nxge_status_t
nxge_check_nlp2020_link(p_nxge_t nxgep,boolean_t * link_up)736212103SSantwona.Behera@Sun.COM nxge_check_nlp2020_link(p_nxge_t nxgep, boolean_t *link_up)
736312103SSantwona.Behera@Sun.COM {
736412103SSantwona.Behera@Sun.COM uint8_t phy;
736512103SSantwona.Behera@Sun.COM nxge_status_t status = NXGE_OK;
736612103SSantwona.Behera@Sun.COM uint16_t pmd_rx_sig, pcs_10gbr_stat1, phy_xs_ln_stat;
736712103SSantwona.Behera@Sun.COM uint8_t connector = 0;
736812103SSantwona.Behera@Sun.COM
736912103SSantwona.Behera@Sun.COM phy = nxgep->statsp->mac_stats.xcvr_portn;
737012103SSantwona.Behera@Sun.COM *link_up = B_FALSE;
737112103SSantwona.Behera@Sun.COM
737212103SSantwona.Behera@Sun.COM /* Check from Netlogic AEL2020 if 10G link is up or down */
737312103SSantwona.Behera@Sun.COM
737412103SSantwona.Behera@Sun.COM status = nxge_mdio_read(nxgep, phy, NLP2020_PMA_PMD_ADDR,
737512103SSantwona.Behera@Sun.COM NLP2020_PMA_PMD_RX_SIG_DET_REG, &pmd_rx_sig);
737612103SSantwona.Behera@Sun.COM if (status != NXGE_OK)
737712103SSantwona.Behera@Sun.COM goto fail;
737812103SSantwona.Behera@Sun.COM
737912103SSantwona.Behera@Sun.COM status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_PCS_ADDR,
738012103SSantwona.Behera@Sun.COM NLP2020_PHY_PCS_10GBR_STAT1_REG, &pcs_10gbr_stat1);
738112103SSantwona.Behera@Sun.COM if (status != NXGE_OK)
738212103SSantwona.Behera@Sun.COM goto fail;
738312103SSantwona.Behera@Sun.COM
738412103SSantwona.Behera@Sun.COM status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_XS_ADDR,
738512103SSantwona.Behera@Sun.COM NLP2020_PHY_XS_LN_ST_REG, &phy_xs_ln_stat);
738612103SSantwona.Behera@Sun.COM if (status != NXGE_OK)
738712103SSantwona.Behera@Sun.COM goto fail;
738812103SSantwona.Behera@Sun.COM
738912103SSantwona.Behera@Sun.COM if ((pmd_rx_sig & NLP2020_PMA_PMD_RX_SIG_ON) &&
739012103SSantwona.Behera@Sun.COM (pcs_10gbr_stat1 & NLP2020_PHY_PCS_10GBR_RX_LINK_UP) &&
739112103SSantwona.Behera@Sun.COM (phy_xs_ln_stat & NLP2020_PHY_XS_LN_ALIGN_SYNC))
739212103SSantwona.Behera@Sun.COM *link_up = B_TRUE;
739312103SSantwona.Behera@Sun.COM /*
739412103SSantwona.Behera@Sun.COM * If previously link was down, check the connector type as
739512103SSantwona.Behera@Sun.COM * it might have been changed.
739612103SSantwona.Behera@Sun.COM */
739712103SSantwona.Behera@Sun.COM if (nxgep->statsp->mac_stats.link_up == 0) {
739812103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_i2c_read(nxgep, phy,
739912103SSantwona.Behera@Sun.COM NLP2020_XCVR_I2C_ADDR, QSFP_MSA_CONN_REG, &connector);
740012103SSantwona.Behera@Sun.COM
740112103SSantwona.Behera@Sun.COM switch (connector) {
740212103SSantwona.Behera@Sun.COM case SFPP_FIBER:
740312103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
740412103SSantwona.Behera@Sun.COM "nxge_check_nlp2020_link: SFPP_FIBER"));
740512103SSantwona.Behera@Sun.COM if (nxgep->mac.portmode != PORT_10G_FIBER) {
740612103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_FIBER;
740712103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_xcvr_init(nxgep);
740812103SSantwona.Behera@Sun.COM }
740912103SSantwona.Behera@Sun.COM break;
741012103SSantwona.Behera@Sun.COM case QSFP_FIBER:
741112103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
741212103SSantwona.Behera@Sun.COM "nxge_check_nlp2020_link: QSFP_FIBER"));
741312103SSantwona.Behera@Sun.COM if (nxgep->mac.portmode != PORT_10G_FIBER) {
741412103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_FIBER;
741512103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_xcvr_init(nxgep);
741612103SSantwona.Behera@Sun.COM }
741712103SSantwona.Behera@Sun.COM break;
741812103SSantwona.Behera@Sun.COM case QSFP_COPPER_TWINAX:
741912103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
742012103SSantwona.Behera@Sun.COM "nxge_check_nlp2020_link: "
742112103SSantwona.Behera@Sun.COM "QSFP_COPPER_TWINAX/"
742212103SSantwona.Behera@Sun.COM "SFPP_COPPER_TWINAX"));
742312103SSantwona.Behera@Sun.COM if (nxgep->mac.portmode != PORT_10G_COPPER) {
742412103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_COPPER;
742512103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_xcvr_init(nxgep);
742612103SSantwona.Behera@Sun.COM } else {
742712103SSantwona.Behera@Sun.COM uint8_t len = 0;
742812103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_i2c_read(nxgep, phy,
742912103SSantwona.Behera@Sun.COM NLP2020_XCVR_I2C_ADDR, QSFP_MSA_LEN_REG,
743012103SSantwona.Behera@Sun.COM &len);
743112103SSantwona.Behera@Sun.COM if (((len < 7) &&
743212103SSantwona.Behera@Sun.COM (nxgep->nlp_conn ==
743312103SSantwona.Behera@Sun.COM NXGE_NLP_CONN_COPPER_7M_ABOVE)) ||
743412103SSantwona.Behera@Sun.COM ((len >= 7) &&
743512103SSantwona.Behera@Sun.COM (nxgep->nlp_conn ==
743612103SSantwona.Behera@Sun.COM NXGE_NLP_CONN_COPPER_LT_7M))) {
743712103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_xcvr_init(nxgep);
743812103SSantwona.Behera@Sun.COM }
743912103SSantwona.Behera@Sun.COM }
744012103SSantwona.Behera@Sun.COM break;
744112103SSantwona.Behera@Sun.COM default:
744212103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
744312103SSantwona.Behera@Sun.COM "nxge_check_nlp2020_link: Unknown type [0x%x] "
744412103SSantwona.Behera@Sun.COM "detected...setting to QSFP_FIBER",
744512103SSantwona.Behera@Sun.COM connector));
744612103SSantwona.Behera@Sun.COM if (nxgep->mac.portmode != PORT_10G_FIBER) {
744712103SSantwona.Behera@Sun.COM nxgep->mac.portmode = PORT_10G_FIBER;
744812103SSantwona.Behera@Sun.COM (void) nxge_nlp2020_xcvr_init(nxgep);
744912103SSantwona.Behera@Sun.COM }
745012103SSantwona.Behera@Sun.COM break;
745112103SSantwona.Behera@Sun.COM }
745212103SSantwona.Behera@Sun.COM }
745312103SSantwona.Behera@Sun.COM fail:
745412103SSantwona.Behera@Sun.COM if (*link_up == B_FALSE && nxgep->statsp->mac_stats.link_up == 1) {
745512103SSantwona.Behera@Sun.COM /* Turn link LED OFF */
745612103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy,
745712103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xb000);
745812103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy,
745912103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0x0);
746012103SSantwona.Behera@Sun.COM } else if (*link_up == B_TRUE &&
746112103SSantwona.Behera@Sun.COM nxgep->statsp->mac_stats.link_up == 0) {
746212103SSantwona.Behera@Sun.COM /* Turn link LED ON */
746312103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy,
746412103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xd000);
746512103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy,
746612103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0xfbff);
746712103SSantwona.Behera@Sun.COM (void) nxge_mdio_write(nxgep, phy,
746812103SSantwona.Behera@Sun.COM NLP2020_GPIO_ADDR, 0xff2a, 0x004a);
746912103SSantwona.Behera@Sun.COM }
747012103SSantwona.Behera@Sun.COM
747112103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
747212103SSantwona.Behera@Sun.COM " <== nxge_check_nlp2020_link: up=%d", *link_up));
747312103SSantwona.Behera@Sun.COM return (status);
747412103SSantwona.Behera@Sun.COM }
747512103SSantwona.Behera@Sun.COM
747612103SSantwona.Behera@Sun.COM
74773859Sml29623 nxge_status_t
nxge_10g_link_led_on(p_nxge_t nxgep)74783859Sml29623 nxge_10g_link_led_on(p_nxge_t nxgep)
74793859Sml29623 {
74803859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
74814732Sdavemq != NPI_SUCCESS)
74823859Sml29623 return (NXGE_ERROR);
74833859Sml29623 else
74843859Sml29623 return (NXGE_OK);
74853859Sml29623 }
74863859Sml29623
74873859Sml29623 nxge_status_t
nxge_10g_link_led_off(p_nxge_t nxgep)74883859Sml29623 nxge_10g_link_led_off(p_nxge_t nxgep)
74893859Sml29623 {
74903859Sml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
74914732Sdavemq != NPI_SUCCESS)
74923859Sml29623 return (NXGE_ERROR);
74933859Sml29623 else
74943859Sml29623 return (NXGE_OK);
74953859Sml29623 }
74964185Sspeer
74975572Ssbehera static boolean_t
nxge_hswap_phy_present(p_nxge_t nxgep,uint8_t portn)749812103SSantwona.Behera@Sun.COM nxge_hswap_phy_present(p_nxge_t nxgep, uint8_t portn)
749912103SSantwona.Behera@Sun.COM {
750012103SSantwona.Behera@Sun.COM /*
750112103SSantwona.Behera@Sun.COM * check for BCM PHY (GOA NEM)
750212103SSantwona.Behera@Sun.COM */
750312103SSantwona.Behera@Sun.COM /*
750412103SSantwona.Behera@Sun.COM * If this is the 2nd NIU port, then check 2 addresses
750512103SSantwona.Behera@Sun.COM * to take care of the Goa NEM card. Port 1 can have addr 17
750612103SSantwona.Behera@Sun.COM * (in the eval board) or 20 (in the P0 board).
750712103SSantwona.Behera@Sun.COM */
750812103SSantwona.Behera@Sun.COM if (portn == 1) {
750912103SSantwona.Behera@Sun.COM if (nxge_is_phy_present(nxgep, ALT_GOA_CLAUSE45_PORT1_ADDR,
751012103SSantwona.Behera@Sun.COM BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
751112103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = ALT_GOA_CLAUSE45_PORT1_ADDR;
751212103SSantwona.Behera@Sun.COM goto found_phy;
751312103SSantwona.Behera@Sun.COM }
751412103SSantwona.Behera@Sun.COM }
751512103SSantwona.Behera@Sun.COM if (nxge_is_phy_present(nxgep, GOA_CLAUSE45_PORT_ADDR_BASE + portn,
751612103SSantwona.Behera@Sun.COM BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
751712103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE + portn;
751812103SSantwona.Behera@Sun.COM goto found_phy;
751912103SSantwona.Behera@Sun.COM }
752012103SSantwona.Behera@Sun.COM
752112103SSantwona.Behera@Sun.COM /*
752212103SSantwona.Behera@Sun.COM * check for NLP2020 PHY on C4 NEM
752312103SSantwona.Behera@Sun.COM */
752412103SSantwona.Behera@Sun.COM switch (portn) {
752512103SSantwona.Behera@Sun.COM case 0:
752612103SSantwona.Behera@Sun.COM if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR0,
752712103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
752812103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR0;
752912103SSantwona.Behera@Sun.COM goto found_phy;
753012103SSantwona.Behera@Sun.COM } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR1,
753112103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
753212103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR1;
753312103SSantwona.Behera@Sun.COM goto found_phy;
753412103SSantwona.Behera@Sun.COM } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR2,
753512103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
753612103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR2;
753712103SSantwona.Behera@Sun.COM goto found_phy;
753812103SSantwona.Behera@Sun.COM } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR3,
753912103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
754012103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR3;
754112103SSantwona.Behera@Sun.COM goto found_phy;
754212103SSantwona.Behera@Sun.COM }
754312103SSantwona.Behera@Sun.COM break;
754412103SSantwona.Behera@Sun.COM
754512103SSantwona.Behera@Sun.COM case 1:
754612103SSantwona.Behera@Sun.COM if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR0,
754712103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
754812103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR0;
754912103SSantwona.Behera@Sun.COM goto found_phy;
755012103SSantwona.Behera@Sun.COM } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR1,
755112103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
755212103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR1;
755312103SSantwona.Behera@Sun.COM goto found_phy;
755412103SSantwona.Behera@Sun.COM } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR2,
755512103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
755612103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR2;
755712103SSantwona.Behera@Sun.COM goto found_phy;
755812103SSantwona.Behera@Sun.COM } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR3,
755912103SSantwona.Behera@Sun.COM NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
756012103SSantwona.Behera@Sun.COM nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR3;
756112103SSantwona.Behera@Sun.COM goto found_phy;
756212103SSantwona.Behera@Sun.COM }
756312103SSantwona.Behera@Sun.COM break;
756412103SSantwona.Behera@Sun.COM default:
756512103SSantwona.Behera@Sun.COM break;
756612103SSantwona.Behera@Sun.COM }
756712103SSantwona.Behera@Sun.COM
756812103SSantwona.Behera@Sun.COM return (B_FALSE);
756912103SSantwona.Behera@Sun.COM found_phy:
757012103SSantwona.Behera@Sun.COM return (B_TRUE);
757112103SSantwona.Behera@Sun.COM
757212103SSantwona.Behera@Sun.COM }
757312103SSantwona.Behera@Sun.COM
757412103SSantwona.Behera@Sun.COM static boolean_t
nxge_is_phy_present(p_nxge_t nxgep,int addr,uint32_t id,uint32_t mask)75755572Ssbehera nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask)
75765572Ssbehera {
75775572Ssbehera uint32_t pma_pmd_id = 0;
75785572Ssbehera uint32_t pcs_id = 0;
75795572Ssbehera uint32_t phy_id = 0;
75805572Ssbehera
75815572Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr);
75825572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75835572Ssbehera "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id));
75845572Ssbehera if ((pma_pmd_id & mask) == (id & mask))
75855572Ssbehera goto found_phy;
75865572Ssbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, addr);
75875572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75885572Ssbehera "nxge_is_phy_present: pcs_id[0x%x]", pcs_id));
75895572Ssbehera if ((pcs_id & mask) == (id & mask))
75905572Ssbehera goto found_phy;
75915572Ssbehera phy_id = nxge_get_cl22_phy_id(nxgep, addr);
75925572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75935572Ssbehera "nxge_is_phy_present: phy_id[0x%x]", phy_id));
75945572Ssbehera if ((phy_id & mask) == (id & mask))
75955572Ssbehera goto found_phy;
75965572Ssbehera
75975572Ssbehera return (B_FALSE);
75985572Ssbehera
75995572Ssbehera found_phy:
76005572Ssbehera return (B_TRUE);
76015572Ssbehera }
76025572Ssbehera
76034732Sdavemq /* Check if the given id read using the given MDIO Clause is supported */
76044732Sdavemq
76054732Sdavemq static boolean_t
nxge_is_supported_phy(uint32_t id,uint8_t type)76064732Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type)
76074732Sdavemq {
76084732Sdavemq int i;
76094732Sdavemq boolean_t found = B_FALSE;
76104732Sdavemq
76114732Sdavemq switch (type) {
76124732Sdavemq case CLAUSE_45_TYPE:
76136835Syc148097 for (i = 0; i < NUM_CLAUSE_45_IDS; i++) {
76146835Syc148097 if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
76156835Syc148097 (id & BCM_PHY_ID_MASK)) ||
761612103SSantwona.Behera@Sun.COM (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK)) ||
761712103SSantwona.Behera@Sun.COM (NLP2020_DEV_ID == (id & NLP2020_DEV_ID_MASK))) {
76184732Sdavemq found = B_TRUE;
76194732Sdavemq break;
76204732Sdavemq }
76214732Sdavemq }
76224732Sdavemq break;
76234732Sdavemq case CLAUSE_22_TYPE:
76246835Syc148097 for (i = 0; i < NUM_CLAUSE_22_IDS; i++) {
76254782Ssbehera if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
76264782Ssbehera (id & BCM_PHY_ID_MASK)) {
76274732Sdavemq found = B_TRUE;
76284732Sdavemq break;
76294732Sdavemq }
76304732Sdavemq }
76314732Sdavemq break;
76324732Sdavemq default:
76334732Sdavemq break;
76344732Sdavemq }
76354732Sdavemq
76364732Sdavemq return (found);
76374732Sdavemq }
76384732Sdavemq
76394977Sraghus static uint32_t
nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep,int phy_port)76404977Sraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port)
76414977Sraghus {
76424977Sraghus uint16_t val1 = 0;
76434977Sraghus uint16_t val2 = 0;
76444977Sraghus uint32_t pma_pmd_dev_id = 0;
76454977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
76464977Sraghus
76475780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
76484977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
76494977Sraghus NXGE_DEV_ID_REG_1, &val1);
76504977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
76514977Sraghus NXGE_DEV_ID_REG_2, &val2);
76525780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
76534977Sraghus
76546835Syc148097 /* Concatenate the Device ID stored in two registers. */
76554977Sraghus pma_pmd_dev_id = val1;
76564977Sraghus pma_pmd_dev_id = (pma_pmd_dev_id << 16);
76574977Sraghus pma_pmd_dev_id |= val2;
76584977Sraghus
76594977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
76604977Sraghus "devid[0x%llx]", phy_port, pma_pmd_dev_id));
76614977Sraghus
76624977Sraghus return (pma_pmd_dev_id);
76634977Sraghus }
76644977Sraghus
76654977Sraghus static uint32_t
nxge_get_cl45_pcs_id(p_nxge_t nxgep,int phy_port)76664977Sraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port)
76674977Sraghus {
76684977Sraghus uint16_t val1 = 0;
76694977Sraghus uint16_t val2 = 0;
76704977Sraghus uint32_t pcs_dev_id = 0;
76714977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
76724977Sraghus
76735780Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
76744977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
76754977Sraghus NXGE_DEV_ID_REG_1, &val1);
76764977Sraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
76774977Sraghus NXGE_DEV_ID_REG_2, &val2);
76785780Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
76794977Sraghus
76804977Sraghus pcs_dev_id = val1;
76814977Sraghus pcs_dev_id = (pcs_dev_id << 16);
76824977Sraghus pcs_dev_id |= val2;
76834977Sraghus
76844977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
76854977Sraghus "devid[0x%llx]", phy_port, pcs_dev_id));
76864977Sraghus
76874977Sraghus return (pcs_dev_id);
76884977Sraghus }
76894977Sraghus
76904977Sraghus static uint32_t
nxge_get_cl22_phy_id(p_nxge_t nxgep,int phy_port)76914977Sraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port)
76924977Sraghus {
76934977Sraghus uint16_t val1 = 0;
76944977Sraghus uint16_t val2 = 0;
76954977Sraghus uint32_t phy_id = 0;
76964977Sraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
76974977Sraghus npi_status_t npi_status = NPI_SUCCESS;
76984977Sraghus
76996075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
77004977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1,
77014977Sraghus &val1);
77024977Sraghus if (npi_status != NPI_SUCCESS) {
77034977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
77044977Sraghus "clause 22 read to reg 2 failed!!!"));
77054977Sraghus goto exit;
77064977Sraghus }
77074977Sraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2,
77084977Sraghus &val2);
77094977Sraghus if (npi_status != 0) {
77104977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
77114977Sraghus "clause 22 read to reg 3 failed!!!"));
77124977Sraghus goto exit;
77134977Sraghus }
77144977Sraghus phy_id = val1;
77154977Sraghus phy_id = (phy_id << 16);
77164977Sraghus phy_id |= val2;
77174977Sraghus
77184977Sraghus exit:
77196075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
77204977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]",
77214977Sraghus phy_port, phy_id));
77224977Sraghus
77234977Sraghus return (phy_id);
77244977Sraghus }
77254977Sraghus
77264732Sdavemq /*
77274732Sdavemq * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
77284732Sdavemq * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
77294732Sdavemq * read. Then use the values obtained to determine the phy type of each port
77304732Sdavemq * and the Neptune type.
77316835Syc148097 *
77326835Syc148097 * This function sets hw_p->xcvr_addr[i] for future MDIO access and set
77336835Syc148097 * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode
77346835Syc148097 * in case the portmode information is not available via OBP, nxge.conf,
77356835Syc148097 * VPD or SEEPROM.
77364732Sdavemq */
77374732Sdavemq nxge_status_t
nxge_scan_ports_phy(p_nxge_t nxgep,p_nxge_hw_list_t hw_p)77384732Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
77394732Sdavemq {
77406261Sjoycey int i, j, l;
77414732Sdavemq uint32_t pma_pmd_dev_id = 0;
77424732Sdavemq uint32_t pcs_dev_id = 0;
77434732Sdavemq uint32_t phy_id = 0;
77444782Ssbehera uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE];
77454782Ssbehera uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE];
77464782Ssbehera uint32_t port_phy_id[NXGE_PORTS_NEPTUNE];
77474732Sdavemq uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
77484732Sdavemq uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS];
77495572Ssbehera uint8_t phy_fd_arr[NXGE_MAX_PHY_PORTS];
77505572Ssbehera uint8_t port_fd_arr[NXGE_MAX_PHY_PORTS];
77514732Sdavemq uint8_t total_port_fd, total_phy_fd;
77526835Syc148097 uint8_t num_xaui;
77534732Sdavemq nxge_status_t status = NXGE_OK;
77544732Sdavemq
77554732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
77564732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
77574732Sdavemq "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
77584732Sdavemq nxgep->niu_type));
77594732Sdavemq
77606495Sspeer if (isLDOMguest(nxgep)) {
77616495Sspeer hw_p->niu_type = NIU_TYPE_NONE;
77626495Sspeer hw_p->platform_type = P_NEPTUNE_NONE;
77636495Sspeer return (NXGE_OK);
77646495Sspeer }
77656495Sspeer
77666261Sjoycey j = l = 0;
77674732Sdavemq total_port_fd = total_phy_fd = 0;
77684732Sdavemq /*
77697801SSantwona.Behera@Sun.COM * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved
77707801SSantwona.Behera@Sun.COM * for on chip serdes usages. "i" in the following for loop starts at 6.
77714732Sdavemq */
77724732Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
77734977Sraghus
77744977Sraghus pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i);
77754732Sdavemq
77764732Sdavemq if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
77774732Sdavemq pma_pmd_dev_fd[i] = 1;
77784732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
77796604Ssbehera "PMA/PMD dev %x found", i, pma_pmd_dev_id));
77804782Ssbehera if (j < NXGE_PORTS_NEPTUNE) {
77816835Syc148097 if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK)
77826835Syc148097 == TN1010_DEV_ID) {
77836835Syc148097 port_pma_pmd_dev_id[j] = TN1010_DEV_ID;
778412103SSantwona.Behera@Sun.COM } else if ((pma_pmd_dev_id &
778512103SSantwona.Behera@Sun.COM NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) {
778612103SSantwona.Behera@Sun.COM port_pma_pmd_dev_id[j] =
778712103SSantwona.Behera@Sun.COM NLP2020_DEV_ID;
77886835Syc148097 } else {
77896835Syc148097 port_pma_pmd_dev_id[j] =
77906929Smisaki pma_pmd_dev_id & BCM_PHY_ID_MASK;
77916835Syc148097 }
77925572Ssbehera port_fd_arr[j] = (uint8_t)i;
77934732Sdavemq j++;
77944732Sdavemq }
77954732Sdavemq } else {
77964732Sdavemq pma_pmd_dev_fd[i] = 0;
77974732Sdavemq }
77984732Sdavemq
77994977Sraghus pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i);
78004732Sdavemq
78014732Sdavemq if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
78024732Sdavemq pcs_dev_fd[i] = 1;
78034732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
78046604Ssbehera "dev %x found", i, pcs_dev_id));
78056261Sjoycey if (pma_pmd_dev_fd[i] == 1) {
78066835Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK)
78076835Syc148097 == TN1010_DEV_ID) {
78086835Syc148097 port_pcs_dev_id[j - 1] =
78096835Syc148097 TN1010_DEV_ID;
781012103SSantwona.Behera@Sun.COM } else if ((pcs_dev_id & NLP2020_DEV_ID_MASK)
781112103SSantwona.Behera@Sun.COM == NLP2020_DEV_ID) {
781212103SSantwona.Behera@Sun.COM port_pcs_dev_id[j - 1] =
781312103SSantwona.Behera@Sun.COM NLP2020_DEV_ID;
78146835Syc148097 } else {
78156835Syc148097 port_pcs_dev_id[j - 1] =
78166835Syc148097 pcs_dev_id &
78176835Syc148097 BCM_PHY_ID_MASK;
78186835Syc148097 }
78196261Sjoycey } else {
78206261Sjoycey if (j < NXGE_PORTS_NEPTUNE) {
78216835Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK)
78226929Smisaki == TN1010_DEV_ID) {
78236835Syc148097 port_pcs_dev_id[j] =
78246835Syc148097 TN1010_DEV_ID;
782512103SSantwona.Behera@Sun.COM } else if ((pcs_dev_id &
782612103SSantwona.Behera@Sun.COM NLP2020_DEV_ID_MASK)
782712103SSantwona.Behera@Sun.COM == NLP2020_DEV_ID) {
782812103SSantwona.Behera@Sun.COM port_pcs_dev_id[j] =
782912103SSantwona.Behera@Sun.COM NLP2020_DEV_ID;
78306835Syc148097 } else {
78316835Syc148097 port_pcs_dev_id[j] =
78326835Syc148097 pcs_dev_id &
78336835Syc148097 BCM_PHY_ID_MASK;
78346835Syc148097 }
78356261Sjoycey port_fd_arr[j] = (uint8_t)i;
78366261Sjoycey j++;
78376261Sjoycey }
78384732Sdavemq }
78394732Sdavemq } else {
78404732Sdavemq pcs_dev_fd[i] = 0;
78414732Sdavemq }
78424732Sdavemq
78435572Ssbehera if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) {
78445572Ssbehera total_port_fd ++;
78455572Ssbehera }
78464732Sdavemq
78474977Sraghus phy_id = nxge_get_cl22_phy_id(nxgep, i);
78484732Sdavemq if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
78495572Ssbehera total_phy_fd ++;
78504732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
78516604Ssbehera "%x found", i, phy_id));
78524782Ssbehera if (l < NXGE_PORTS_NEPTUNE) {
78536835Syc148097 if ((phy_id & TN1010_DEV_ID_MASK)
78546835Syc148097 == TN1010_DEV_ID) {
78556835Syc148097 port_phy_id[l] = TN1010_DEV_ID;
78566835Syc148097 } else {
78576835Syc148097 port_phy_id[l]
78586835Syc148097 = phy_id & BCM_PHY_ID_MASK;
78596835Syc148097 }
78605572Ssbehera phy_fd_arr[l] = (uint8_t)i;
78614732Sdavemq l++;
78624732Sdavemq }
78634732Sdavemq }
78644732Sdavemq }
78654732Sdavemq
78664732Sdavemq switch (total_port_fd) {
78674732Sdavemq case 2:
78684732Sdavemq switch (total_phy_fd) {
78694732Sdavemq case 2:
78707801SSantwona.Behera@Sun.COM /* 2 10G, 2 1G RGMII Fiber / copper */
78716261Sjoycey if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
78726261Sjoycey (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
78736261Sjoycey ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
78746261Sjoycey (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) &&
78756261Sjoycey ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
78766261Sjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY))) {
78776261Sjoycey
78787801SSantwona.Behera@Sun.COM switch (hw_p->platform_type) {
78797801SSantwona.Behera@Sun.COM case P_NEPTUNE_ROCK:
78807801SSantwona.Behera@Sun.COM hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
78817801SSantwona.Behera@Sun.COM /*
78827801SSantwona.Behera@Sun.COM * ROCK platform has assigned a lower
78837801SSantwona.Behera@Sun.COM * addr to port 1. (port 0 = 0x9 and
78847801SSantwona.Behera@Sun.COM * port 1 = 0x8).
78857801SSantwona.Behera@Sun.COM */
78867801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[0];
78877801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[1];
78887801SSantwona.Behera@Sun.COM
78897801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
78907801SSantwona.Behera@Sun.COM "Rock with 2 10G, 2 1GC"));
78917801SSantwona.Behera@Sun.COM break;
78927801SSantwona.Behera@Sun.COM
78937801SSantwona.Behera@Sun.COM case P_NEPTUNE_NONE:
78947801SSantwona.Behera@Sun.COM default:
78957801SSantwona.Behera@Sun.COM hw_p->platform_type =
78967801SSantwona.Behera@Sun.COM P_NEPTUNE_GENERIC;
78977801SSantwona.Behera@Sun.COM hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF;
78987801SSantwona.Behera@Sun.COM
78997801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[0];
79007801SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[1];
79017801SSantwona.Behera@Sun.COM
79027801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
79037801SSantwona.Behera@Sun.COM "ARTM card with 2 10G, 2 1GF"));
79047801SSantwona.Behera@Sun.COM break;
79057801SSantwona.Behera@Sun.COM }
79067801SSantwona.Behera@Sun.COM
79076261Sjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0];
79086261Sjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1];
79096261Sjoycey
79106261Sjoycey } else {
79116261Sjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79126261Sjoycey "Unsupported neptune type 1"));
79136261Sjoycey goto error_exit;
79146261Sjoycey }
79156261Sjoycey break;
79166261Sjoycey
79174732Sdavemq case 1:
79184732Sdavemq /* TODO - 2 10G, 1 1G */
79194732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
79204732Sdavemq "Unsupported neptune type 2 10G, 1 1G"));
79214732Sdavemq goto error_exit;
79224732Sdavemq case 0:
79236835Syc148097 /*
79246835Syc148097 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI
79256835Syc148097 * cards, etc.
79266835Syc148097 */
79274782Ssbehera if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
79284782Ssbehera (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
79294782Ssbehera ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
79306604Ssbehera (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) ||
79316604Ssbehera ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) &&
79326604Ssbehera (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) ||
79336604Ssbehera ((port_pma_pmd_dev_id[0] ==
79346604Ssbehera MARVELL_88X201X_PHY_ID) &&
79356604Ssbehera (port_pma_pmd_dev_id[1] ==
79366604Ssbehera MARVELL_88X201X_PHY_ID))) {
79374977Sraghus
79384977Sraghus /*
79394977Sraghus * Check the first phy port address against
79404977Sraghus * the known phy start addresses to determine
79414977Sraghus * the platform type.
79424977Sraghus */
79435572Ssbehera
79445572Ssbehera switch (port_fd_arr[0]) {
79456835Syc148097 case NEPTUNE_CLAUSE45_PORT_ADDR_BASE:
79466604Ssbehera /*
79476604Ssbehera * The Marvell case also falls into
79486604Ssbehera * this case as
79496604Ssbehera * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE
79506835Syc148097 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE.
79516604Ssbehera * This is OK for the 2 10G case.
79526604Ssbehera */
79534977Sraghus hw_p->niu_type = NEPTUNE_2_10GF;
79544977Sraghus hw_p->platform_type =
79554977Sraghus P_NEPTUNE_ATLAS_2PORT;
79565572Ssbehera break;
79576835Syc148097 case GOA_CLAUSE45_PORT_ADDR_BASE:
79585572Ssbehera if (hw_p->platform_type !=
79595572Ssbehera P_NEPTUNE_NIU) {
79605572Ssbehera hw_p->platform_type =
79615572Ssbehera P_NEPTUNE_GENERIC;
79625572Ssbehera hw_p->niu_type =
79635572Ssbehera NEPTUNE_2_10GF;
79645572Ssbehera }
79655572Ssbehera break;
79665572Ssbehera default:
79675572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
79684977Sraghus "Unsupported neptune type 2 - 1"));
79694977Sraghus goto error_exit;
79704977Sraghus }
79715572Ssbehera
79725572Ssbehera for (i = 0; i < 2; i++) {
79735572Ssbehera hw_p->xcvr_addr[i] = port_fd_arr[i];
79745572Ssbehera }
79756835Syc148097
797612103SSantwona.Behera@Sun.COM /* 2 10G optical Netlogic AEL2020 ports */
797712103SSantwona.Behera@Sun.COM } else if (((port_pcs_dev_id[0] == NLP2020_DEV_ID) &&
797812103SSantwona.Behera@Sun.COM (port_pcs_dev_id[1] == NLP2020_DEV_ID)) ||
797912103SSantwona.Behera@Sun.COM ((port_pma_pmd_dev_id[0] == NLP2020_DEV_ID) &&
798012103SSantwona.Behera@Sun.COM (port_pma_pmd_dev_id[1] == NLP2020_DEV_ID))) {
798112103SSantwona.Behera@Sun.COM if (hw_p->platform_type != P_NEPTUNE_NIU) {
798212103SSantwona.Behera@Sun.COM hw_p->platform_type =
798312103SSantwona.Behera@Sun.COM P_NEPTUNE_GENERIC;
798412103SSantwona.Behera@Sun.COM hw_p->niu_type =
798512103SSantwona.Behera@Sun.COM NEPTUNE_2_10GF;
798612103SSantwona.Behera@Sun.COM }
798712103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
798812103SSantwona.Behera@Sun.COM "Found 2 NL PHYs at addrs 0x%x and 0x%x",
798912103SSantwona.Behera@Sun.COM port_fd_arr[0], port_fd_arr[1]));
799012103SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[0];
799112103SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[1];
799212103SSantwona.Behera@Sun.COM
79936835Syc148097 /* Both XAUI slots have copper XAUI cards */
79946835Syc148097 } else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
79956835Syc148097 == TN1010_DEV_ID) &&
79966835Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
79976835Syc148097 == TN1010_DEV_ID)) ||
79986835Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
79996835Syc148097 == TN1010_DEV_ID) &&
80006835Syc148097 ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
80016835Syc148097 == TN1010_DEV_ID))) {
80026835Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010;
80036835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0];
80046835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1];
80056835Syc148097
80066835Syc148097 /* Slot0 has fiber XAUI, slot1 has copper XAUI */
80076835Syc148097 } else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
80086835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
80096835Syc148097 == TN1010_DEV_ID) ||
80106835Syc148097 (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY &&
80116835Syc148097 (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) ==
80126835Syc148097 TN1010_DEV_ID)) {
80136835Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010;
80146835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0];
80156835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1];
80166835Syc148097
80176835Syc148097 /* Slot0 has copper XAUI, slot1 has fiber XAUI */
80186835Syc148097 } else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY &&
80196835Syc148097 (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
80206835Syc148097 == TN1010_DEV_ID) ||
80216835Syc148097 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY &&
80226835Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
80236835Syc148097 == TN1010_DEV_ID)) {
80246835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF;
80256835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0];
80266835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1];
80276835Syc148097
80284732Sdavemq } else {
80294732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
80304732Sdavemq "Unsupported neptune type 2"));
80314732Sdavemq goto error_exit;
80324732Sdavemq }
80334732Sdavemq break;
80346835Syc148097
80354732Sdavemq case 4:
80366835Syc148097 if (nxge_get_num_of_xaui(
80376835Syc148097 port_pma_pmd_dev_id, port_pcs_dev_id,
80386835Syc148097 port_phy_id, &num_xaui) == NXGE_ERROR) {
80396835Syc148097 goto error_exit;
80406835Syc148097 }
80416835Syc148097 if (num_xaui != 2)
80426835Syc148097 goto error_exit;
80436835Syc148097
80446835Syc148097 /*
80456835Syc148097 * Maramba with 2 XAUIs (either fiber or copper)
80466835Syc148097 *
80476835Syc148097 * Check the first phy port address against
80486835Syc148097 * the known phy start addresses to determine
80496835Syc148097 * the platform type.
80506835Syc148097 */
80516835Syc148097 switch (phy_fd_arr[0]) {
80526835Syc148097 case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
80536835Syc148097 hw_p->platform_type =
80546835Syc148097 P_NEPTUNE_MARAMBA_P0;
80556835Syc148097 break;
80566835Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
80576835Syc148097 hw_p->platform_type =
80586835Syc148097 P_NEPTUNE_MARAMBA_P1;
80596835Syc148097 break;
80606835Syc148097 default:
80616835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
80626835Syc148097 "Unknown port %d...Cannot "
80636835Syc148097 "determine platform type", i));
80646835Syc148097 goto error_exit;
80656835Syc148097 }
80666835Syc148097
80676835Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0];
80686835Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1];
80696835Syc148097 hw_p->xcvr_addr[2] = phy_fd_arr[2];
80706835Syc148097 hw_p->xcvr_addr[3] = phy_fd_arr[3];
80716835Syc148097
80726835Syc148097 /* slot0 has fiber XAUI, slot1 has Cu XAUI */
80736835Syc148097 if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
80746835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
80756835Syc148097 == TN1010_DEV_ID) {
80766835Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC;
80776835Syc148097
80786835Syc148097 /* slot0 has Cu XAUI, slot1 has fiber XAUI */
80796835Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
80806835Syc148097 == TN1010_DEV_ID) &&
80816835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
80826835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC;
80836835Syc148097
80846835Syc148097 /* Both slots have fiber XAUI */
80856835Syc148097 } else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
80866835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
80874977Sraghus hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
80884977Sraghus
80896835Syc148097 /* Both slots have copper XAUI */
80906835Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
80916835Syc148097 == TN1010_DEV_ID) &&
80926835Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
80936835Syc148097 == TN1010_DEV_ID) {
80946835Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC;
80956835Syc148097
80964732Sdavemq } else {
80974732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
80984732Sdavemq "Unsupported neptune type 3"));
80994732Sdavemq goto error_exit;
81004732Sdavemq }
81014732Sdavemq break;
81024732Sdavemq default:
81034732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81044732Sdavemq "Unsupported neptune type 5"));
81054732Sdavemq goto error_exit;
81064732Sdavemq }
81074782Ssbehera break;
81086835Syc148097 case 1: /* Only one clause45 port */
81096835Syc148097 switch (total_phy_fd) { /* Number of clause22 ports */
81104732Sdavemq case 3:
81114977Sraghus /*
81124977Sraghus * TODO 3 1G, 1 10G mode.
81134977Sraghus * Differentiate between 1_1G_1_10G_2_1G and
81144977Sraghus * 1_10G_3_1G
81154977Sraghus */
81164977Sraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81174977Sraghus "Unsupported neptune type 7"));
81184977Sraghus goto error_exit;
81194732Sdavemq case 2:
81204732Sdavemq /*
81214732Sdavemq * TODO 2 1G, 1 10G mode.
81224732Sdavemq * Differentiate between 1_1G_1_10G_1_1G and
81234732Sdavemq * 1_10G_2_1G
81244732Sdavemq */
81254732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81264732Sdavemq "Unsupported neptune type 8"));
81274732Sdavemq goto error_exit;
81284732Sdavemq case 1:
81294732Sdavemq /*
81304732Sdavemq * TODO 1 1G, 1 10G mode.
81314732Sdavemq * Differentiate between 1_1G_1_10G and
81324732Sdavemq * 1_10G_1_1G
81334732Sdavemq */
81344732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
81354732Sdavemq "Unsupported neptune type 9"));
81364732Sdavemq goto error_exit;
81376835Syc148097 case 0: /* N2 with 1 XAUI (fiber or copper) */
81386835Syc148097 /* Fiber XAUI */
81395572Ssbehera if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY ||
81405572Ssbehera port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) {
81415572Ssbehera
81425572Ssbehera /*
81435572Ssbehera * Check the first phy port address against
81445572Ssbehera * the known phy start addresses to determine
81455572Ssbehera * the platform type.
81465572Ssbehera */
81475572Ssbehera
81485572Ssbehera switch (port_fd_arr[0]) {
81496835Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE:
81506835Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
81516835Syc148097 case ALT_GOA_CLAUSE45_PORT1_ADDR:
81526835Syc148097 /*
81536835Syc148097 * If hw_p->platform_type ==
81546835Syc148097 * P_NEPTUNE_NIU, then portmode
81556835Syc148097 * is already known, so there is
81566835Syc148097 * no need to figure out hw_p->
81576835Syc148097 * platform_type because
81586835Syc148097 * platform_type is only for
81596835Syc148097 * figuring out portmode.
81606835Syc148097 */
81615572Ssbehera if (hw_p->platform_type !=
81625572Ssbehera P_NEPTUNE_NIU) {
81635572Ssbehera hw_p->platform_type =
81645572Ssbehera P_NEPTUNE_GENERIC;
81655572Ssbehera hw_p->niu_type =
81665572Ssbehera NEPTUNE_2_10GF;
81675572Ssbehera }
81685572Ssbehera break;
81695572Ssbehera default:
81705572Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
81715572Ssbehera "Unsupported neptune type 10"));
81725572Ssbehera goto error_exit;
81735572Ssbehera }
81746075Ssbehera /*
81756075Ssbehera * For GOA, which is a hot swappable PHY, the
81766075Ssbehera * phy address to function number mapping
81776075Ssbehera * should be preserved, i.e., addr 16 is
81786075Ssbehera * assigned to function 0 and 20 to function 1
81796075Ssbehera * But for Huron XAUI, the assignment should
81806075Ssbehera * be by function number, i.e., whichever
81816075Ssbehera * function number attaches should be
81826075Ssbehera * assigned the available PHY (this is required
81836075Ssbehera * primarily to support pre-production Huron
81846075Ssbehera * boards where function 0 is mapped to addr 17
81856075Ssbehera */
81866075Ssbehera if (port_fd_arr[0] ==
81876835Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR) {
81886075Ssbehera hw_p->xcvr_addr[1] = port_fd_arr[0];
81896075Ssbehera } else {
81906075Ssbehera hw_p->xcvr_addr[nxgep->function_num] =
81916075Ssbehera port_fd_arr[0];
81926075Ssbehera }
819312103SSantwona.Behera@Sun.COM } else if (port_pcs_dev_id[0] == NLP2020_DEV_ID ||
819412103SSantwona.Behera@Sun.COM port_pma_pmd_dev_id[0] == NLP2020_DEV_ID) {
819512103SSantwona.Behera@Sun.COM /* A 10G NLP2020 PHY in slot0 or slot1 */
819612103SSantwona.Behera@Sun.COM switch (port_fd_arr[0]) {
819712103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR0:
819812103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR1:
819912103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR2:
820012103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR3:
820112103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR0:
820212103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR1:
820312103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR2:
820412103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR3:
820512103SSantwona.Behera@Sun.COM /*
820612103SSantwona.Behera@Sun.COM * If hw_p->platform_type ==
820712103SSantwona.Behera@Sun.COM * P_NEPTUNE_NIU, then portmode
820812103SSantwona.Behera@Sun.COM * is already known, so there is
820912103SSantwona.Behera@Sun.COM * no need to figure out hw_p->
821012103SSantwona.Behera@Sun.COM * platform_type because
821112103SSantwona.Behera@Sun.COM * platform_type is only for
821212103SSantwona.Behera@Sun.COM * figuring out portmode.
821312103SSantwona.Behera@Sun.COM */
821412103SSantwona.Behera@Sun.COM if (hw_p->platform_type !=
821512103SSantwona.Behera@Sun.COM P_NEPTUNE_NIU) {
821612103SSantwona.Behera@Sun.COM hw_p->platform_type =
821712103SSantwona.Behera@Sun.COM P_NEPTUNE_GENERIC;
821812103SSantwona.Behera@Sun.COM hw_p->niu_type =
821912103SSantwona.Behera@Sun.COM NEPTUNE_2_10GF;
822012103SSantwona.Behera@Sun.COM }
822112103SSantwona.Behera@Sun.COM break;
822212103SSantwona.Behera@Sun.COM default:
822312103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
822412103SSantwona.Behera@Sun.COM "Unsupported neptune type 10-1"));
822512103SSantwona.Behera@Sun.COM goto error_exit;
822612103SSantwona.Behera@Sun.COM }
822712103SSantwona.Behera@Sun.COM switch (port_fd_arr[0]) {
822812103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR0:
822912103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR1:
823012103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR2:
823112103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT0_ADDR3:
823212103SSantwona.Behera@Sun.COM hw_p->xcvr_addr[0] = port_fd_arr[0];
823312103SSantwona.Behera@Sun.COM break;
823412103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR0:
823512103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR1:
823612103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR2:
823712103SSantwona.Behera@Sun.COM case NLP2020_CL45_PORT1_ADDR3:
823812103SSantwona.Behera@Sun.COM hw_p->xcvr_addr[1] = port_fd_arr[0];
823912103SSantwona.Behera@Sun.COM break;
824012103SSantwona.Behera@Sun.COM default:
824112103SSantwona.Behera@Sun.COM NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
824212103SSantwona.Behera@Sun.COM "Unsupported neptune type 10-11"));
824312103SSantwona.Behera@Sun.COM goto error_exit;
824412103SSantwona.Behera@Sun.COM }
824512103SSantwona.Behera@Sun.COM
824612103SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, MAC_CTL,
824712103SSantwona.Behera@Sun.COM "Found 1 NL PHYs at addr 0x%x",
824812103SSantwona.Behera@Sun.COM port_fd_arr[0]));
82496835Syc148097
82506835Syc148097 /* A 10G copper XAUI in either slot0 or slot1 */
82516835Syc148097 } else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
82526835Syc148097 == TN1010_DEV_ID ||
82536835Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
82546835Syc148097 == TN1010_DEV_ID) {
82556835Syc148097 switch (port_fd_arr[0]) {
82566835Syc148097 /* The XAUI is in slot0 */
82576835Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE:
82586835Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010;
82596835Syc148097 break;
82606835Syc148097
82616835Syc148097 /* The XAUI is in slot1 */
82626835Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
82636835Syc148097 hw_p->niu_type
82646835Syc148097 = NEPTUNE_1_NONE_1_TN1010;
82656835Syc148097 break;
82666835Syc148097 default:
82676835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
82686835Syc148097 "Unsupported XAUI port address"));
82696835Syc148097 goto error_exit;
82706835Syc148097 }
82716835Syc148097 hw_p->xcvr_addr[nxgep->function_num]
82726835Syc148097 = port_fd_arr[0];
82736835Syc148097
82745572Ssbehera } else {
82755572Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
82766835Syc148097 "Unsupported PHY type"));
82775572Ssbehera goto error_exit;
82785572Ssbehera }
82795572Ssbehera break;
82806835Syc148097 case 4: /* Maramba always have 4 clause 45 ports */
82816835Syc148097
82824732Sdavemq /* Maramba with 1 XAUI */
82836929Smisaki if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) &&
82846929Smisaki (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) &&
82856835Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
82866929Smisaki != TN1010_DEV_ID) &&
82876835Syc148097 ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
82886929Smisaki != TN1010_DEV_ID)) {
82894732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
82904732Sdavemq "Unsupported neptune type 12"));
82914732Sdavemq goto error_exit;
82924732Sdavemq }
82936929Smisaki
82946929Smisaki /*
82956929Smisaki * Check the first phy port address against
82966929Smisaki * the known phy start addresses to determine
82976929Smisaki * the platform type.
82986929Smisaki */
82996929Smisaki switch (phy_fd_arr[0]) {
83006929Smisaki case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
83016929Smisaki hw_p->platform_type =
83026929Smisaki P_NEPTUNE_MARAMBA_P0;
83036929Smisaki break;
83046929Smisaki case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
83056929Smisaki hw_p->platform_type =
83066929Smisaki P_NEPTUNE_MARAMBA_P1;
83076929Smisaki break;
83086929Smisaki default:
83096929Smisaki NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
83106929Smisaki "Unknown port %d...Cannot "
83116929Smisaki "determine platform type 10 - 2",
83126929Smisaki i));
83136929Smisaki goto error_exit;
83146929Smisaki }
83156929Smisaki
83166929Smisaki /*
83176929Smisaki * Check the clause45 address to determine
83186929Smisaki * if XAUI is in port 0 or port 1.
83196929Smisaki */
83206929Smisaki switch (port_fd_arr[0]) {
83216929Smisaki case MARAMBA_CLAUSE45_PORT_ADDR_BASE:
83226929Smisaki if (port_pcs_dev_id[0]
83236929Smisaki == PHY_BCM8704_FAMILY ||
83246929Smisaki port_pma_pmd_dev_id[0]
83256929Smisaki == PHY_BCM8704_FAMILY) {
83266929Smisaki hw_p->niu_type
83276929Smisaki = NEPTUNE_1_10GF_3_1GC;
83286929Smisaki } else {
83296929Smisaki hw_p->niu_type
83306929Smisaki = NEPTUNE_1_TN1010_3_1GC;
83316929Smisaki }
83326929Smisaki hw_p->xcvr_addr[0] = port_fd_arr[0];
83336929Smisaki for (i = 1; i < NXGE_MAX_PORTS; i++) {
83346929Smisaki hw_p->xcvr_addr[i] =
83356929Smisaki phy_fd_arr[i];
83366929Smisaki }
83376929Smisaki break;
83386929Smisaki case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1):
83396929Smisaki if (port_pcs_dev_id[0]
83406929Smisaki == PHY_BCM8704_FAMILY ||
83416929Smisaki port_pma_pmd_dev_id[0]
83426929Smisaki == PHY_BCM8704_FAMILY) {
83436929Smisaki hw_p->niu_type =
83446929Smisaki NEPTUNE_1_1GC_1_10GF_2_1GC;
83456929Smisaki } else {
83466929Smisaki hw_p->niu_type =
83476929Smisaki NEPTUNE_1_1GC_1_TN1010_2_1GC;
83486929Smisaki }
83496929Smisaki hw_p->xcvr_addr[0] = phy_fd_arr[0];
83506929Smisaki hw_p->xcvr_addr[1] = port_fd_arr[0];
83516929Smisaki hw_p->xcvr_addr[2] = phy_fd_arr[2];
83526929Smisaki hw_p->xcvr_addr[3] = phy_fd_arr[3];
83536929Smisaki break;
83546929Smisaki default:
83556929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83566929Smisaki "Unsupported neptune type 11"));
83576929Smisaki goto error_exit;
83586929Smisaki }
83596929Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83606929Smisaki "Maramba with 1 XAUI (fiber or copper)"));
83614732Sdavemq break;
83624732Sdavemq default:
83634732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83644732Sdavemq "Unsupported neptune type 13"));
83654732Sdavemq goto error_exit;
83664732Sdavemq }
83674732Sdavemq break;
83686835Syc148097 case 0: /* 4 ports Neptune based NIC */
83694732Sdavemq switch (total_phy_fd) {
83704732Sdavemq case 4:
83714782Ssbehera if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
83724782Ssbehera (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
83734782Ssbehera (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
83744782Ssbehera (port_phy_id[3] == PHY_BCM5464R_FAMILY)) {
83754732Sdavemq
83764732Sdavemq /*
83774732Sdavemq * Check the first phy port address against
83784732Sdavemq * the known phy start addresses to determine
83794732Sdavemq * the platform type.
83804732Sdavemq */
83815572Ssbehera switch (phy_fd_arr[0]) {
83826835Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
83834732Sdavemq hw_p->platform_type =
83844732Sdavemq P_NEPTUNE_MARAMBA_P1;
83855572Ssbehera break;
83866835Syc148097 case NEPTUNE_CLAUSE22_PORT_ADDR_BASE:
83874977Sraghus hw_p->platform_type =
83884977Sraghus P_NEPTUNE_ATLAS_4PORT;
83895572Ssbehera break;
83905572Ssbehera default:
83914977Sraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
83924977Sraghus "Unknown port %d...Cannot "
83934977Sraghus "determine platform type", i));
83944977Sraghus goto error_exit;
83954732Sdavemq }
83964977Sraghus hw_p->niu_type = NEPTUNE_4_1GC;
83975572Ssbehera for (i = 0; i < NXGE_MAX_PORTS; i++) {
83985572Ssbehera hw_p->xcvr_addr[i] = phy_fd_arr[i];
83995572Ssbehera }
84004732Sdavemq } else {
84014732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84024732Sdavemq "Unsupported neptune type 14"));
84034732Sdavemq goto error_exit;
84044732Sdavemq }
84054732Sdavemq break;
84064732Sdavemq case 3:
84074732Sdavemq /* TODO 3 1G mode */
84084732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84094732Sdavemq "Unsupported neptune type 15"));
84104732Sdavemq goto error_exit;
84114732Sdavemq case 2:
84124732Sdavemq /* TODO 2 1G mode */
84136261Sjoycey if ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
84146261Sjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY)) {
84156261Sjoycey hw_p->platform_type = P_NEPTUNE_GENERIC;
84166261Sjoycey hw_p->niu_type = NEPTUNE_2_1GRF;
84176261Sjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0];
84186261Sjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1];
84196261Sjoycey } else {
84206261Sjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
84216261Sjoycey "Unsupported neptune type 16"));
84226261Sjoycey goto error_exit;
84236261Sjoycey }
84244732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84256261Sjoycey "2 RGMII Fiber ports - RTM"));
84266261Sjoycey break;
84276261Sjoycey
84284732Sdavemq case 1:
84294732Sdavemq /* TODO 1 1G mode */
84304732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84314732Sdavemq "Unsupported neptune type 17"));
84324732Sdavemq goto error_exit;
84334732Sdavemq default:
84344732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84354732Sdavemq "Unsupported neptune type 18, total phy fd %d",
84364732Sdavemq total_phy_fd));
84374732Sdavemq goto error_exit;
84384732Sdavemq }
84394732Sdavemq break;
84404732Sdavemq default:
84414732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84424732Sdavemq "Unsupported neptune type 19"));
84434732Sdavemq goto error_exit;
84444732Sdavemq }
84454732Sdavemq
84464732Sdavemq scan_exit:
84474732Sdavemq
84484732Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
84494732Sdavemq "niu type [0x%x]\n", hw_p->niu_type));
84504732Sdavemq return (status);
84514732Sdavemq
84524732Sdavemq error_exit:
84534732Sdavemq return (NXGE_ERROR);
84544732Sdavemq }
84554732Sdavemq
84564185Sspeer boolean_t
nxge_is_valid_local_mac(ether_addr_st mac_addr)84574185Sspeer nxge_is_valid_local_mac(ether_addr_st mac_addr)
84584185Sspeer {
84594185Sspeer if ((mac_addr.ether_addr_octet[0] & 0x01) ||
84604185Sspeer (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) ||
84614185Sspeer (ether_cmp(&mac_addr, ðerzeroaddr) == 0))
84624185Sspeer return (B_FALSE);
84634185Sspeer else
84644185Sspeer return (B_TRUE);
84654185Sspeer }
84664732Sdavemq
84674732Sdavemq static void
nxge_bcm5464_link_led_off(p_nxge_t nxgep)84684732Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) {
84694732Sdavemq
84704732Sdavemq npi_status_t rs = NPI_SUCCESS;
84714732Sdavemq uint8_t xcvr_portn;
84724732Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
84734732Sdavemq
84744732Sdavemq NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
84754732Sdavemq
84764732Sdavemq if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) {
84776835Syc148097 xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE;
84784732Sdavemq } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) {
84796835Syc148097 xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE;
84804732Sdavemq }
84814732Sdavemq /*
84824732Sdavemq * For Altas 4-1G copper, Xcvr port numbers are
84834732Sdavemq * swapped with ethernet port number. This is
84844732Sdavemq * designed for better signal integrity in routing.
84854732Sdavemq */
84864732Sdavemq switch (portn) {
84874732Sdavemq case 0:
84884732Sdavemq xcvr_portn += 3;
84894732Sdavemq break;
84904732Sdavemq case 1:
84914732Sdavemq xcvr_portn += 2;
84924732Sdavemq break;
84934732Sdavemq case 2:
84944732Sdavemq xcvr_portn += 1;
84954732Sdavemq break;
84964732Sdavemq case 3:
84974732Sdavemq default:
84984732Sdavemq break;
84994732Sdavemq }
85004732Sdavemq
85016075Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
85024732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle,
85034732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb4ee);
85044732Sdavemq if (rs != NPI_SUCCESS) {
85054732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
85064732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
85074732Sdavemq "returned error 0x[%x]", rs));
85086075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
85094732Sdavemq return;
85104732Sdavemq }
85114732Sdavemq
85124732Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle,
85134732Sdavemq xcvr_portn, BCM5464R_MISC, 0xb8ee);
85144732Sdavemq if (rs != NPI_SUCCESS) {
85154732Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
85164732Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
85174732Sdavemq "returned error 0x[%x]", rs));
85184732Sdavemq }
85194732Sdavemq
85206075Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
85214732Sdavemq }
85225196Ssbehera
85235196Ssbehera static nxge_status_t
nxge_mii_get_link_mode(p_nxge_t nxgep)85245196Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep)
85255196Ssbehera {
85265196Ssbehera p_nxge_stats_t statsp;
85275196Ssbehera uint8_t xcvr_portn;
85285196Ssbehera p_mii_regs_t mii_regs;
85295196Ssbehera mii_mode_control_stat_t mode;
85305196Ssbehera int status = NXGE_OK;
85315196Ssbehera
85325196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode"));
85335196Ssbehera
85345196Ssbehera statsp = nxgep->statsp;
85355196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn;
85365196Ssbehera mii_regs = NULL;
85375196Ssbehera mode.value = 0;
85385203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
85395196Ssbehera #if defined(__i386)
85405196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
85415196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow),
85425196Ssbehera mode.value)) != NXGE_OK) {
85435196Ssbehera goto fail;
85445196Ssbehera #else
85455196Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn,
85465196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow),
85475196Ssbehera mode.value)) != NXGE_OK) {
85485196Ssbehera goto fail;
85495196Ssbehera #endif
85505196Ssbehera }
85515196Ssbehera #if defined(__i386)
85525196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
85535196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow),
85545196Ssbehera &mode.value)) != NXGE_OK) {
85555196Ssbehera goto fail;
85565196Ssbehera }
85575196Ssbehera #else
85585196Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn,
85595196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow),
85605196Ssbehera &mode.value)) != NXGE_OK) {
85615196Ssbehera goto fail;
85625196Ssbehera }
85635196Ssbehera #endif
85645196Ssbehera
85655196Ssbehera if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) {
85665196Ssbehera nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
85675196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
85685196Ssbehera "nxge_mii_get_link_mode: fiber mode"));
85695196Ssbehera }
85705196Ssbehera
85715196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
85725196Ssbehera "nxge_mii_get_link_mode: "
85735196Ssbehera "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x",
85745203Ssbehera NXGE_MII_MODE_CONTROL_REG, xcvr_portn,
85755196Ssbehera mode.value, nxgep->mac.portmode));
85765196Ssbehera
85775196Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL,
85785196Ssbehera "<== nxge_mii_get_link_mode"));
85795196Ssbehera return (status);
85805196Ssbehera fail:
85815196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
85825196Ssbehera "<== nxge_mii_get_link_mode (failed)"));
85835196Ssbehera return (NXGE_ERROR);
85845196Ssbehera }
85855196Ssbehera
85866439Sml29623 nxge_status_t
85876439Sml29623 nxge_mac_set_framesize(p_nxge_t nxgep)
85886439Sml29623 {
85896439Sml29623 npi_attr_t ap;
85906439Sml29623 uint8_t portn;
85916439Sml29623 npi_handle_t handle;
85926439Sml29623 npi_status_t rs = NPI_SUCCESS;
85936439Sml29623
85946439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize"));
85956439Sml29623
85966439Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
85976439Sml29623 handle = nxgep->npi_handle;
85986439Sml29623
85996439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86006439Sml29623 "==> nxge_mac_sec_framesize: port<%d> "
86016439Sml29623 "min framesize %d max framesize %d ",
86026439Sml29623 portn,
86036439Sml29623 nxgep->mac.minframesize,
86046439Sml29623 nxgep->mac.maxframesize));
86056439Sml29623
86066439Sml29623 SET_MAC_ATTR2(handle, ap, portn,
86076439Sml29623 MAC_PORT_FRAME_SIZE,
86086439Sml29623 nxgep->mac.minframesize,
86096439Sml29623 nxgep->mac.maxframesize,
86106439Sml29623 rs);
86116439Sml29623 if (rs != NPI_SUCCESS) {
86126439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86136439Sml29623 "<== nxge_mac_set_framesize: failed to configure "
86146439Sml29623 "max/min frame size port %d", portn));
86156439Sml29623
86166439Sml29623 return (NXGE_ERROR | rs);
86176439Sml29623 }
86186439Sml29623
86196439Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86206439Sml29623 "<== nxge_mac_set_framesize: port<%d>", portn));
86216439Sml29623
86226439Sml29623 return (NXGE_OK);
86236439Sml29623 }
86246439Sml29623
86256835Syc148097 static nxge_status_t
86266835Syc148097 nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
86276835Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui)
86286835Syc148097 {
86296835Syc148097 uint8_t i;
86306835Syc148097
86316835Syc148097 for (i = 0; i < 4; i++) {
86326835Syc148097 if (port_phy_id[i] != PHY_BCM5464R_FAMILY)
86336835Syc148097 return (NXGE_ERROR);
86346835Syc148097 }
86356835Syc148097
86366835Syc148097 *num_xaui = 0;
86376835Syc148097 if ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY &&
86386835Syc148097 port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) ||
86396835Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
86406835Syc148097 == TN1010_DEV_ID) &&
86416835Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
86426835Syc148097 == TN1010_DEV_ID))) {
86436835Syc148097 (*num_xaui) ++;
86446835Syc148097 }
86456835Syc148097 if ((port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY &&
86466835Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) ||
86476835Syc148097 (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
86486835Syc148097 == TN1010_DEV_ID) &&
86496835Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
86506835Syc148097 == TN1010_DEV_ID))) {
86516835Syc148097 (*num_xaui) ++;
86526835Syc148097 }
86536835Syc148097 return (NXGE_OK);
86546835Syc148097 }
86556835Syc148097
86566835Syc148097 /*
86576835Syc148097 * Instruction from Teranetics: Once you detect link is up, go
86586835Syc148097 * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You
86596835Syc148097 * may want to qualify it by first checking Register 30.1.7:6 and
86606835Syc148097 * making sure it reads "01" (Auto-Neg Complete).
86616835Syc148097 *
86626835Syc148097 * If this function is called when the link is down or before auto-
86636835Syc148097 * negotiation has completed, then the speed of the PHY is not certain.
86646835Syc148097 * In such cases, this function returns 1G as the default speed with
86656835Syc148097 * NXGE_OK status instead of NXGE_ERROR. It is OK to initialize the
86666835Syc148097 * driver based on a default speed because this function will be called
86676835Syc148097 * again when the link comes up. Returning NXGE_ERROR, which may
86686835Syc148097 * cause brutal chain reaction in caller functions, is not necessary.
86696835Syc148097 */
86706835Syc148097 static nxge_status_t
86716835Syc148097 nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed)
86726835Syc148097 {
86736835Syc148097 uint8_t phy_port_addr, autoneg_stat, link_up;
86746835Syc148097 nxge_status_t status = NXGE_OK;
86756835Syc148097 uint16_t val;
86766835Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
86776835Syc148097
86786835Syc148097 /* Set default speed to 10G */
86796835Syc148097 *speed = TN1010_SPEED_10G;
86806835Syc148097
86816835Syc148097 /* Set Clause 45 */
86826835Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
86836835Syc148097
86846835Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
86856835Syc148097
86866835Syc148097 /* Check Device 1 Register 0xA bit0 for link up status */
86876835Syc148097 status = nxge_mdio_read(nxgep, phy_port_addr,
86886835Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val);
86896835Syc148097 if (status != NXGE_OK)
86906835Syc148097 goto fail;
86916835Syc148097
86926835Syc148097 link_up = ((val & TN1010_AN_LINK_STAT_BIT)
86936835Syc148097 ? B_TRUE : B_FALSE);
86946835Syc148097 if (link_up == B_FALSE) {
86956835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
86966835Syc148097 "nxge_get_tn1010_speed: link is down"));
86976835Syc148097 goto nxge_get_tn1010_speed_exit;
86986835Syc148097 }
86996835Syc148097
87006835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr,
87016835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG,
87026835Syc148097 &val)) != NXGE_OK) {
87036835Syc148097 goto fail;
87046835Syc148097 }
87056835Syc148097 autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >>
87066835Syc148097 TN1010_VENDOR_MMD1_AN_STAT_SHIFT;
87076835Syc148097
87086835Syc148097 /*
87096835Syc148097 * Return NXGE_OK even when we can not get a settled speed. In
87106835Syc148097 * such case, the speed reported should not be trusted but that
87116835Syc148097 * is OK, we will call this function periodically and will get
87126835Syc148097 * the correct speed after the link is up.
87136835Syc148097 */
87146835Syc148097 switch (autoneg_stat) {
87156835Syc148097 case TN1010_AN_IN_PROG:
87166835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
87176835Syc148097 "nxge_get_tn1010_speed: Auto-negotiation in progress"));
87186835Syc148097 break;
87196835Syc148097 case TN1010_AN_COMPLETE:
87206835Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr,
87216835Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR,
87226835Syc148097 TN1010_VENDOR_MMD1_STATUS_REG,
87236835Syc148097 &val)) != NXGE_OK) {
87246835Syc148097 goto fail;
87256835Syc148097 }
87266835Syc148097 *speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >>
87276835Syc148097 TN1010_VENDOR_MMD1_AN_SPEED_SHIFT;
87286835Syc148097 break;
87296835Syc148097 case TN1010_AN_RSVD:
87306835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
87316835Syc148097 "nxge_get_tn1010_speed: Autoneg status undefined"));
87326835Syc148097 break;
87336835Syc148097 case TN1010_AN_FAILED:
87346835Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
87356835Syc148097 "nxge_get_tn1010_speed: Auto-negotiation failed"));
87366835Syc148097 break;
87376835Syc148097 default:
87386835Syc148097 break;
87396835Syc148097 }
87406835Syc148097 nxge_get_tn1010_speed_exit:
87416835Syc148097 return (NXGE_OK);
87426835Syc148097 fail:
87436835Syc148097 return (status);
87446835Syc148097 }
87456835Syc148097
87466835Syc148097
87476835Syc148097 /*
87486835Syc148097 * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function
87496835Syc148097 * figures out the speed of the PHY determined by the autonegotiation
87506835Syc148097 * process and sets the following 3 parameters,
87516835Syc148097 * nxgep->mac.portmode
87526835Syc148097 * nxgep->statsp->mac_stats.link_speed
87536835Syc148097 * nxgep->statsp->mac_stats.xcvr_inuse
87546835Syc148097 */
87556835Syc148097 static nxge_status_t
87566835Syc148097 nxge_set_tn1010_param(p_nxge_t nxgep)
87576835Syc148097 {
87586835Syc148097 uint16_t speed;
87596835Syc148097
87606835Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) {
87616835Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
87626835Syc148097 "nxge_set_tn1010_param: "
87636835Syc148097 "Failed to get TN1010 speed"));
87646835Syc148097 return (NXGE_ERROR);
87656835Syc148097 }
87666835Syc148097 if (speed == TN1010_SPEED_1G) {
87676835Syc148097 nxgep->mac.portmode = PORT_1G_TN1010;
87686835Syc148097 nxgep->statsp->mac_stats.link_speed = 1000;
87696835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
87706835Syc148097 } else {
87716835Syc148097 nxgep->mac.portmode = PORT_10G_TN1010;
87726835Syc148097 nxgep->statsp->mac_stats.link_speed = 10000;
87736835Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
87746835Syc148097 }
87756835Syc148097 return (NXGE_OK);
87766835Syc148097 }
87776835Syc148097
87785196Ssbehera #ifdef NXGE_DEBUG
87795196Ssbehera static void
87805196Ssbehera nxge_mii_dump(p_nxge_t nxgep)
87815196Ssbehera {
87825196Ssbehera p_nxge_stats_t statsp;
87835196Ssbehera uint8_t xcvr_portn;
87845196Ssbehera p_mii_regs_t mii_regs;
87855196Ssbehera mii_bmcr_t bmcr;
87865196Ssbehera mii_bmsr_t bmsr;
87875196Ssbehera mii_idr1_t idr1;
87885196Ssbehera mii_idr2_t idr2;
87895196Ssbehera mii_mode_control_stat_t mode;
87906495Sspeer p_nxge_param_t param_arr;
87915196Ssbehera
87925196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump"));
87935196Ssbehera
87945196Ssbehera statsp = nxgep->statsp;
87955196Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn;
87965196Ssbehera
87975196Ssbehera mii_regs = NULL;
87985196Ssbehera
87995196Ssbehera #if defined(__i386)
88005196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
88015196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value);
88025196Ssbehera #else
88035196Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
88045196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value);
88055196Ssbehera #endif
88065196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88075196Ssbehera "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x",
88085196Ssbehera xcvr_portn, bmcr.value));
88095196Ssbehera
88105196Ssbehera #if defined(__i386)
88115196Ssbehera (void) nxge_mii_read(nxgep,
88125196Ssbehera nxgep->statsp->mac_stats.xcvr_portn,
88135196Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value);
88145196Ssbehera #else
88155196Ssbehera (void) nxge_mii_read(nxgep,
88165196Ssbehera nxgep->statsp->mac_stats.xcvr_portn,
88175196Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value);
88185196Ssbehera #endif
88195196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88205196Ssbehera "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x",
88215196Ssbehera xcvr_portn, bmsr.value));
88225196Ssbehera
88235196Ssbehera #if defined(__i386)
88245196Ssbehera (void) nxge_mii_read(nxgep,
88255196Ssbehera nxgep->statsp->mac_stats.xcvr_portn,
88265196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value);
88275196Ssbehera #else
88285196Ssbehera (void) nxge_mii_read(nxgep,
88295196Ssbehera nxgep->statsp->mac_stats.xcvr_portn,
88305196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value);
88315196Ssbehera #endif
88325196Ssbehera
88335196Ssbehera
88345196Ssbehera #if defined(__i386)
88355196Ssbehera (void) nxge_mii_read(nxgep,
88365196Ssbehera nxgep->statsp->mac_stats.xcvr_portn,
88375196Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value);
88385196Ssbehera #else
88395196Ssbehera (void) nxge_mii_read(nxgep,
88405196Ssbehera nxgep->statsp->mac_stats.xcvr_portn,
88415196Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value);
88425196Ssbehera #endif
88435196Ssbehera
88445196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88455196Ssbehera "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x",
88465196Ssbehera xcvr_portn, idr1.value));
88475196Ssbehera
88485196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88495196Ssbehera "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x",
88505196Ssbehera xcvr_portn, idr2.value));
88515196Ssbehera
88525196Ssbehera mode.value = 0;
88535203Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
88545196Ssbehera
88555196Ssbehera #if defined(__i386)
88565196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn,
88575196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value);
88585196Ssbehera
88595196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn,
88605196Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value);
88615196Ssbehera #else
88625196Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn,
88635196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value);
88645196Ssbehera
88655196Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn,
88665196Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value);
88675196Ssbehera #endif
88685196Ssbehera
88695196Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
88705196Ssbehera "nxge_mii_dump: mode control xcvr 0x%x value 0x%x",
88715196Ssbehera xcvr_portn, mode.value));
88725196Ssbehera }
88735196Ssbehera #endif
8874