16f45ec7bSml29623 /* 26f45ec7bSml29623 * CDDL HEADER START 36f45ec7bSml29623 * 46f45ec7bSml29623 * The contents of this file are subject to the terms of the 56f45ec7bSml29623 * Common Development and Distribution License (the "License"). 66f45ec7bSml29623 * You may not use this file except in compliance with the License. 76f45ec7bSml29623 * 86f45ec7bSml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96f45ec7bSml29623 * or http://www.opensolaris.org/os/licensing. 106f45ec7bSml29623 * See the License for the specific language governing permissions 116f45ec7bSml29623 * and limitations under the License. 126f45ec7bSml29623 * 136f45ec7bSml29623 * When distributing Covered Code, include this CDDL HEADER in each 146f45ec7bSml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156f45ec7bSml29623 * If applicable, add the following below this CDDL HEADER, with the 166f45ec7bSml29623 * fields enclosed by brackets "[]" replaced with your own identifying 176f45ec7bSml29623 * information: Portions Copyright [yyyy] [name of copyright owner] 186f45ec7bSml29623 * 196f45ec7bSml29623 * CDDL HEADER END 206f45ec7bSml29623 */ 216f45ec7bSml29623 /* 2289282175SSantwona Behera * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 236f45ec7bSml29623 */ 246f45ec7bSml29623 256f45ec7bSml29623 #include <sys/nxge/nxge_impl.h> 266f45ec7bSml29623 #include <sys/nxge/nxge_mac.h> 27678453a8Sspeer #include <sys/nxge/nxge_hio.h> 286f45ec7bSml29623 2998ecde52Stm144005 #define LINK_MONITOR_PERIOD (1000 * 1000) 3098ecde52Stm144005 #define LM_WAIT_MULTIPLIER 8 3198ecde52Stm144005 32321febdeSsbehera #define SERDES_RDY_WT_INTERVAL 50 33321febdeSsbehera #define MAX_SERDES_RDY_RETRIES 10 34321febdeSsbehera 3500161856Syc148097 #define TN1010_SPEED_1G 1 3600161856Syc148097 #define TN1010_SPEED_10G 0 3700161856Syc148097 #define TN1010_AN_IN_PROG 0 /* Auto negotiation in progress */ 3800161856Syc148097 #define TN1010_AN_COMPLETE 1 3900161856Syc148097 #define TN1010_AN_RSVD 2 4000161856Syc148097 #define TN1010_AN_FAILED 3 4100161856Syc148097 426f45ec7bSml29623 extern uint32_t nxge_no_link_notify; 4359ac0c16Sdavemq extern boolean_t nxge_no_msg; 446f45ec7bSml29623 extern uint32_t nxge_lb_dbg; 454202ea4bSsbehera extern uint32_t nxge_jumbo_mtu; 466f45ec7bSml29623 4798ecde52Stm144005 typedef enum { 4898ecde52Stm144005 CHECK_LINK_RESCHEDULE, 4998ecde52Stm144005 CHECK_LINK_STOP 5098ecde52Stm144005 } check_link_state_t; 5198ecde52Stm144005 5298ecde52Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *); 5398ecde52Stm144005 546f45ec7bSml29623 /* 556f45ec7bSml29623 * Ethernet broadcast address definition. 566f45ec7bSml29623 */ 576f45ec7bSml29623 static ether_addr_st etherbroadcastaddr = 586f45ec7bSml29623 {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 5959ac0c16Sdavemq /* 6059ac0c16Sdavemq * Ethernet zero address definition. 6159ac0c16Sdavemq */ 6256d930aeSspeer static ether_addr_st etherzeroaddr = 6356d930aeSspeer {{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; 6459ac0c16Sdavemq /* 6559ac0c16Sdavemq * Supported chip types 6659ac0c16Sdavemq */ 6752cdd236Ssbehera static uint32_t nxge_supported_cl45_ids[] = { 6852cdd236Ssbehera BCM8704_DEV_ID, 6952cdd236Ssbehera MARVELL_88X_201X_DEV_ID, 7000161856Syc148097 BCM8706_DEV_ID, 7100161856Syc148097 TN1010_DEV_ID 7252cdd236Ssbehera }; 7352cdd236Ssbehera 74b1000363Sml29623 static uint32_t nxge_supported_cl22_ids[] = { 75b1000363Sml29623 BCM5464R_PHY_ID, 76b1000363Sml29623 BCM5482_PHY_ID 77b1000363Sml29623 }; 7859ac0c16Sdavemq 7959ac0c16Sdavemq #define NUM_CLAUSE_45_IDS (sizeof (nxge_supported_cl45_ids) / \ 8059ac0c16Sdavemq sizeof (uint32_t)) 8159ac0c16Sdavemq #define NUM_CLAUSE_22_IDS (sizeof (nxge_supported_cl22_ids) / \ 8259ac0c16Sdavemq sizeof (uint32_t)) 8359ac0c16Sdavemq /* 8459ac0c16Sdavemq * static functions 8559ac0c16Sdavemq */ 862e59129aSraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int); 872e59129aSraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int); 882e59129aSraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int); 8959ac0c16Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t); 9089282175SSantwona Behera static boolean_t nxge_hswap_phy_present(p_nxge_t, uint8_t); 912d17280bSsbehera static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t); 9259ac0c16Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t); 934df55fdeSJanie Lu static nxge_status_t nxge_n2_kt_serdes_init(p_nxge_t); 9459ac0c16Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t); 9559ac0c16Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t); 9659ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t); 9759ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t); 9859ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t); 9959ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t); 10059ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t); 10159ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t); 10259ac0c16Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t); 10359ac0c16Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t); 10459ac0c16Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t); 1052d17280bSsbehera static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t); 1062d17280bSsbehera static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t); 10759ac0c16Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t); 10859ac0c16Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t); 10900161856Syc148097 static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *); 11052cdd236Ssbehera static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t); 11189282175SSantwona Behera static nxge_status_t nxge_check_nlp2020_link(p_nxge_t, boolean_t *); 11289282175SSantwona Behera static nxge_status_t nxge_nlp2020_xcvr_init(p_nxge_t); 11389282175SSantwona Behera static int nxge_nlp2020_i2c_read(p_nxge_t, uint8_t, uint16_t, uint16_t, 11489282175SSantwona Behera uint8_t *); 11589282175SSantwona Behera static boolean_t nxge_is_nlp2020_phy(p_nxge_t); 11689282175SSantwona Behera static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t); 11789282175SSantwona Behera static nxge_status_t nxge_set_nlp2020_param(p_nxge_t); 11800161856Syc148097 static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id, 11900161856Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui); 12000161856Syc148097 static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed); 12100161856Syc148097 static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep); 12200161856Syc148097 static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep, 12300161856Syc148097 nxge_link_state_t *link_up); 12400161856Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep); 12500161856Syc148097 static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep); 12600161856Syc148097 12700161856Syc148097 nxge_status_t nxge_mac_init(p_nxge_t); 12800161856Syc148097 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t); 12900161856Syc148097 13000161856Syc148097 #ifdef NXGE_DEBUG 13100161856Syc148097 static void nxge_mii_dump(p_nxge_t); 13200161856Syc148097 static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep); 13300161856Syc148097 static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep); 13400161856Syc148097 #endif 13559ac0c16Sdavemq 13659ac0c16Sdavemq /* 13759ac0c16Sdavemq * xcvr tables for supported transceivers 13859ac0c16Sdavemq */ 13959ac0c16Sdavemq 14000161856Syc148097 /* 14100161856Syc148097 * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems. 14200161856Syc148097 * The Teranetics TN1010 based copper XAUI card can also be used 14300161856Syc148097 * on N2-NIU systems in 10G mode, but it uses its own table 14400161856Syc148097 * nxge_n2_10G_tn1010_table below. 14500161856Syc148097 */ 1462e59129aSraghus static nxge_xcvr_table_t nxge_n2_10G_table = { 14759ac0c16Sdavemq nxge_n2_serdes_init, 14859ac0c16Sdavemq nxge_10G_xcvr_init, 14959ac0c16Sdavemq nxge_10G_link_intr_stop, 15059ac0c16Sdavemq nxge_10G_link_intr_start, 15159ac0c16Sdavemq nxge_check_10g_link, 1522d17280bSsbehera PCS_XCVR 15359ac0c16Sdavemq }; 15459ac0c16Sdavemq 15500161856Syc148097 /* 15600161856Syc148097 * For the Teranetics TN1010 based copper XAUI card 15700161856Syc148097 */ 15800161856Syc148097 static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = { 15900161856Syc148097 nxge_n2_serdes_init, /* Handle both 1G and 10G */ 16000161856Syc148097 nxge_tn1010_xcvr_init, /* Handle both 1G and 10G */ 16100161856Syc148097 nxge_10G_link_intr_stop, 16200161856Syc148097 nxge_10G_link_intr_start, 16300161856Syc148097 nxge_check_tn1010_link, /* Will figure out speed */ 16400161856Syc148097 XPCS_XCVR 16500161856Syc148097 }; 16600161856Syc148097 1672e59129aSraghus static nxge_xcvr_table_t nxge_n2_1G_table = { 1682e59129aSraghus nxge_n2_serdes_init, 1692e59129aSraghus nxge_1G_xcvr_init, 1702e59129aSraghus nxge_1G_fiber_link_intr_stop, 1712e59129aSraghus nxge_1G_fiber_link_intr_start, 1722e59129aSraghus nxge_check_mii_link, 1732d17280bSsbehera PCS_XCVR 1742e59129aSraghus }; 1752e59129aSraghus 17600161856Syc148097 static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = { 17700161856Syc148097 nxge_n2_serdes_init, 17800161856Syc148097 nxge_tn1010_xcvr_init, 17900161856Syc148097 nxge_1G_fiber_link_intr_stop, /* TN1010 is a Cu PHY, but it uses */ 18000161856Syc148097 nxge_1G_fiber_link_intr_start, /* PCS for 1G, so call fiber func */ 18100161856Syc148097 nxge_check_tn1010_link, 18200161856Syc148097 PCS_XCVR 18300161856Syc148097 }; 18400161856Syc148097 18500161856Syc148097 static nxge_xcvr_table_t nxge_10G_tn1010_table = { 18600161856Syc148097 nxge_neptune_10G_serdes_init, 18700161856Syc148097 nxge_tn1010_xcvr_init, 18800161856Syc148097 nxge_10G_link_intr_stop, 18900161856Syc148097 nxge_10G_link_intr_start, 19000161856Syc148097 nxge_check_tn1010_link, 19100161856Syc148097 XPCS_XCVR 19200161856Syc148097 }; 19300161856Syc148097 19400161856Syc148097 static nxge_xcvr_table_t nxge_1G_tn1010_table = { 19500161856Syc148097 nxge_1G_serdes_init, 19600161856Syc148097 nxge_tn1010_xcvr_init, 19700161856Syc148097 nxge_1G_fiber_link_intr_stop, 19800161856Syc148097 nxge_1G_fiber_link_intr_start, 19900161856Syc148097 nxge_check_tn1010_link, 20000161856Syc148097 PCS_XCVR 20100161856Syc148097 }; 20200161856Syc148097 20359ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = { 20459ac0c16Sdavemq nxge_neptune_10G_serdes_init, 20559ac0c16Sdavemq nxge_10G_xcvr_init, 20659ac0c16Sdavemq nxge_10G_link_intr_stop, 20759ac0c16Sdavemq nxge_10G_link_intr_start, 20859ac0c16Sdavemq nxge_check_10g_link, 2092d17280bSsbehera PCS_XCVR 21059ac0c16Sdavemq }; 21159ac0c16Sdavemq 21259ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = { 21359ac0c16Sdavemq NULL, 21459ac0c16Sdavemq nxge_1G_xcvr_init, 21559ac0c16Sdavemq nxge_1G_copper_link_intr_stop, 21659ac0c16Sdavemq nxge_1G_copper_link_intr_start, 21759ac0c16Sdavemq nxge_check_mii_link, 2182d17280bSsbehera INT_MII_XCVR 21959ac0c16Sdavemq }; 22059ac0c16Sdavemq 22100161856Syc148097 /* This table is for Neptune portmode == PORT_1G_SERDES cases */ 22259ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = { 22359ac0c16Sdavemq nxge_1G_serdes_init, 22459ac0c16Sdavemq nxge_1G_xcvr_init, 22559ac0c16Sdavemq nxge_1G_fiber_link_intr_stop, 22659ac0c16Sdavemq nxge_1G_fiber_link_intr_start, 22759ac0c16Sdavemq nxge_check_mii_link, 2282d17280bSsbehera PCS_XCVR 22959ac0c16Sdavemq }; 23059ac0c16Sdavemq 23159ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = { 23259ac0c16Sdavemq nxge_neptune_10G_serdes_init, 23359ac0c16Sdavemq NULL, 23459ac0c16Sdavemq NULL, 23559ac0c16Sdavemq NULL, 2362e59129aSraghus NULL, 2372d17280bSsbehera PCS_XCVR 23859ac0c16Sdavemq }; 2396f45ec7bSml29623 24000161856Syc148097 /* 24100161856Syc148097 * NXGE_PORT_TN1010 is defined as, 24200161856Syc148097 * NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT) 24300161856Syc148097 * = 0 | 5 << 16 = 0x50000 24400161856Syc148097 * 24500161856Syc148097 * So NEPTUNE_2_TN1010 = 24600161856Syc148097 * (NXGE_PORT_TN1010 | 24700161856Syc148097 * (NXGE_PORT_TN1010 << 4) | 24800161856Syc148097 * (NXGE_PORT_NONE << 8) | 24900161856Syc148097 * (NXGE_PORT_NONE << 12)), 25000161856Syc148097 * = 0x50000 | (0x50000 << 4) 25100161856Syc148097 * = 0x550000 25200161856Syc148097 * 25300161856Syc148097 * This function partitions nxgep->nxge_hw_p->niu_type (which may have 25400161856Syc148097 * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010 25500161856Syc148097 * = 0x50000 25600161856Syc148097 */ 25700161856Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep) 25800161856Syc148097 { 25900161856Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2606f45ec7bSml29623 26100161856Syc148097 if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn)) 26200161856Syc148097 & NXGE_PHY_MASK) == NXGE_PORT_TN1010) { 26300161856Syc148097 return (B_TRUE); 26400161856Syc148097 } else { 26500161856Syc148097 return (B_FALSE); 26600161856Syc148097 } 26700161856Syc148097 } 268d81011f0Ssbehera 26900161856Syc148097 27000161856Syc148097 /* 27100161856Syc148097 * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties, 27200161856Syc148097 * serial EEPROM or VPD if possible. Note that not all systems could get 27300161856Syc148097 * the portmode information by calling this function. For example, the 27400161856Syc148097 * Maramba system figures out the portmode information by calling function 27500161856Syc148097 * nxge_setup_xcvr_table. 27600161856Syc148097 */ 2772e59129aSraghus nxge_status_t 2782e59129aSraghus nxge_get_xcvr_type(p_nxge_t nxgep) 2792e59129aSraghus { 2802e59129aSraghus nxge_status_t status = NXGE_OK; 2812e59129aSraghus char *phy_type; 2822e59129aSraghus char *prop_val; 28300161856Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 2841c7408c9Stc99174@train uint32_t val; 2851c7408c9Stc99174@train npi_status_t rs; 2861c7408c9Stc99174@train 2871c7408c9Stc99174@train /* For Opus NEM, skip xcvr checking if 10G Serdes link is up */ 2881c7408c9Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES && 2891c7408c9Stc99174@train nxgep->statsp->mac_stats.link_up) { 2901c7408c9Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 2911c7408c9Stc99174@train return (status); 2921c7408c9Stc99174@train } 2932e59129aSraghus 2942e59129aSraghus nxgep->mac.portmode = 0; 2952d17280bSsbehera nxgep->xcvr_addr = 0; 2962e59129aSraghus 2972d17280bSsbehera /* 2982d17280bSsbehera * First check for hot swappable phy property. 2992d17280bSsbehera */ 3002d17280bSsbehera if (nxgep->hot_swappable_phy == B_TRUE) { 3012d17280bSsbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 3022d17280bSsbehera nxgep->mac.portmode = PORT_HSP_MODE; 3032d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable")); 3042d17280bSsbehera } else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 3052d17280bSsbehera DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 3062d17280bSsbehera "hot-swappable-phy") == 1) { 3072d17280bSsbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 3082d17280bSsbehera nxgep->mac.portmode = PORT_HSP_MODE; 3092d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable")); 3102d17280bSsbehera } else if (nxgep->niu_type == N2_NIU && 3112d17280bSsbehera ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0, 3122d17280bSsbehera "hot-swappable-phy") == 1) { 3132d17280bSsbehera nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR; 3142d17280bSsbehera nxgep->mac.portmode = PORT_HSP_MODE; 3152d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable")); 3162d17280bSsbehera } 3172d17280bSsbehera 3182d17280bSsbehera /* 3192d17280bSsbehera * MDIO polling support for Monza RTM card, Goa NEM card 3202d17280bSsbehera */ 3212d17280bSsbehera if (nxgep->mac.portmode == PORT_HSP_MODE) { 3222d17280bSsbehera nxgep->hot_swappable_phy = B_TRUE; 323ef523517SMichael Speer if (portn > 1) { 324ef523517SMichael Speer return (NXGE_ERROR); 325ef523517SMichael Speer } 326ef523517SMichael Speer 32789282175SSantwona Behera if (nxge_hswap_phy_present(nxgep, portn)) 3282d17280bSsbehera goto found_phy; 3292d17280bSsbehera 3302d17280bSsbehera nxgep->phy_absent = B_TRUE; 3311c7408c9Stc99174@train 3321c7408c9Stc99174@train /* Check Serdes link to detect Opus NEM */ 3331c7408c9Stc99174@train rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 3341c7408c9Stc99174@train XPCS_REG_STATUS, &val); 3351c7408c9Stc99174@train 3361c7408c9Stc99174@train if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) { 3371c7408c9Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3381c7408c9Stc99174@train nxgep->mac.portmode = PORT_10G_SERDES; 3391c7408c9Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3401c7408c9Stc99174@train "HSP 10G Serdes FOUND!!")); 3411c7408c9Stc99174@train } 3422d17280bSsbehera goto check_phy_done; 3432d17280bSsbehera found_phy: 3442d17280bSsbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3452d17280bSsbehera nxgep->mac.portmode = PORT_10G_FIBER; 3462d17280bSsbehera nxgep->phy_absent = B_FALSE; 3472d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr " 3482d17280bSsbehera "found for hot swappable phy")); 3492d17280bSsbehera check_phy_done: 3502d17280bSsbehera return (status); 3512d17280bSsbehera } 3522d17280bSsbehera 35300161856Syc148097 /* Get phy-type property (May have been set by nxge.conf) */ 3542e59129aSraghus if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 3552e59129aSraghus DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 3562e59129aSraghus "phy-type", &prop_val)) == DDI_PROP_SUCCESS) { 3572e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3582e59129aSraghus "found conf file: phy-type %s", prop_val)); 3592e59129aSraghus if (strcmp("xgsd", prop_val) == 0) { 3602e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 3612e59129aSraghus nxgep->mac.portmode = PORT_10G_SERDES; 3622e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3632e59129aSraghus "found: 10G Serdes")); 3642e59129aSraghus } else if (strcmp("gsd", prop_val) == 0) { 3652e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3662e59129aSraghus nxgep->mac.portmode = PORT_1G_SERDES; 3672e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes")); 3682e59129aSraghus } else if (strcmp("mif", prop_val) == 0) { 3692e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 3702e59129aSraghus nxgep->mac.portmode = PORT_1G_COPPER; 3712e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 3722e59129aSraghus } else if (strcmp("pcs", prop_val) == 0) { 3732e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 3742e59129aSraghus nxgep->mac.portmode = PORT_1G_FIBER; 3752e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr")); 376321febdeSsbehera } else if (strcmp("xgf", prop_val) == 0) { 37700161856Syc148097 /* 37800161856Syc148097 * Before OBP supports new phy-type property 37900161856Syc148097 * value "xgc", the 10G copper XAUI may carry 38000161856Syc148097 * "xgf" instead of "xgc". If the OBP is 38100161856Syc148097 * upgraded to a newer version which supports 38200161856Syc148097 * "xgc", then the TN1010 related code in this 38300161856Syc148097 * "xgf" case will not be used anymore. 38400161856Syc148097 */ 38500161856Syc148097 if (nxge_is_tn1010_phy(nxgep)) { 38600161856Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) 38700161856Syc148097 != NXGE_OK) { 38800161856Syc148097 return (status); 38900161856Syc148097 } 39000161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 39100161856Syc148097 } else { /* For Fiber XAUI */ 392321febdeSsbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 393321febdeSsbehera nxgep->mac.portmode = PORT_10G_FIBER; 39400161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 39500161856Syc148097 "10G Fiber Xcvr")); 39600161856Syc148097 } 39700161856Syc148097 } else if (strcmp("xgc", prop_val) == 0) { 39800161856Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK) 39900161856Syc148097 return (status); 40000161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 4012e59129aSraghus } 4022e59129aSraghus 4032e59129aSraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip, 4042e59129aSraghus "phy-type", prop_val); 4052e59129aSraghus ddi_prop_free(prop_val); 4062e59129aSraghus 4072e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 4082e59129aSraghus "Got phy type [0x%x] from conf file", 4092e59129aSraghus nxgep->mac.portmode)); 4102e59129aSraghus 4112e59129aSraghus return (NXGE_OK); 4122e59129aSraghus } 4132d17280bSsbehera 4142d17280bSsbehera /* Get phy-type property from OBP */ 4152e59129aSraghus if (nxgep->niu_type == N2_NIU) { 4162e59129aSraghus if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0, 4172e59129aSraghus "phy-type", &prop_val) == DDI_PROP_SUCCESS) { 4182e59129aSraghus if (strcmp("xgf", prop_val) == 0) { 41900161856Syc148097 /* 42000161856Syc148097 * Before OBP supports new phy-type property 42100161856Syc148097 * value "xgc", the 10G copper XAUI may carry 42200161856Syc148097 * "xgf" instead of "xgc". If the OBP is 42300161856Syc148097 * upgraded to a newer version which supports 42400161856Syc148097 * "xgc", then the TN1010 related code in this 42500161856Syc148097 * "xgf" case will not be used anymore. 42600161856Syc148097 */ 42700161856Syc148097 if (nxge_is_tn1010_phy(nxgep)) { 42800161856Syc148097 if ((status = 42900161856Syc148097 nxge_set_tn1010_param(nxgep)) 43000161856Syc148097 != NXGE_OK) { 43100161856Syc148097 return (status); 43200161856Syc148097 } 43300161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43400161856Syc148097 "TN1010 Xcvr")); 43589282175SSantwona Behera } else if (nxge_is_nlp2020_phy(nxgep)) { 43689282175SSantwona Behera if ((status = 43789282175SSantwona Behera nxge_set_nlp2020_param(nxgep)) 43889282175SSantwona Behera != NXGE_OK) { 43989282175SSantwona Behera return (status); 44089282175SSantwona Behera } 44189282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 44289282175SSantwona Behera "NLP2020 Xcvr")); 44300161856Syc148097 } else { /* For Fiber XAUI */ 44400161856Syc148097 nxgep->statsp->mac_stats.xcvr_inuse 44500161856Syc148097 = XPCS_XCVR; 4462e59129aSraghus nxgep->mac.portmode = PORT_10G_FIBER; 4472e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4482e59129aSraghus "10G Fiber Xcvr")); 44900161856Syc148097 } 4502e59129aSraghus } else if (strcmp("mif", prop_val) == 0) { 4512e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = 4522e59129aSraghus INT_MII_XCVR; 4532e59129aSraghus nxgep->mac.portmode = PORT_1G_COPPER; 4542e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4552e59129aSraghus "1G Copper Xcvr")); 4562e59129aSraghus } else if (strcmp("pcs", prop_val) == 0) { 4572e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 4582e59129aSraghus nxgep->mac.portmode = PORT_1G_FIBER; 4592e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4602e59129aSraghus "1G Fiber Xcvr")); 4612e59129aSraghus } else if (strcmp("xgc", prop_val) == 0) { 46200161856Syc148097 status = nxge_set_tn1010_param(nxgep); 46300161856Syc148097 if (status != NXGE_OK) 46400161856Syc148097 return (status); 46500161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr")); 4662e59129aSraghus } else if (strcmp("xgsd", prop_val) == 0) { 4672e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 4682e59129aSraghus nxgep->mac.portmode = PORT_10G_SERDES; 4692e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4702e59129aSraghus "OBP: 10G Serdes")); 4712e59129aSraghus } else if (strcmp("gsd", prop_val) == 0) { 4722e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 4732e59129aSraghus nxgep->mac.portmode = PORT_1G_SERDES; 4742e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4752e59129aSraghus "OBP: 1G Serdes")); 4762e59129aSraghus } else { 4772e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4782e59129aSraghus "Unknown phy-type: %s", prop_val)); 4792e59129aSraghus ddi_prop_free(prop_val); 4802e59129aSraghus return (NXGE_ERROR); 4812e59129aSraghus } 4822e59129aSraghus status = NXGE_OK; 4832e59129aSraghus (void) ddi_prop_update_string(DDI_DEV_T_NONE, 4842e59129aSraghus nxgep->dip, "phy-type", prop_val); 4852e59129aSraghus ddi_prop_free(prop_val); 4862e59129aSraghus 4872e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 4882e59129aSraghus "Got phy type [0x%x] from OBP", 4892e59129aSraghus nxgep->mac.portmode)); 4902e59129aSraghus 4912e59129aSraghus return (status); 4922e59129aSraghus } else { 4932e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4942e59129aSraghus "Exiting...phy-type property not found")); 4952e59129aSraghus return (NXGE_ERROR); 4962e59129aSraghus } 4972e59129aSraghus } 4982e59129aSraghus 4992e59129aSraghus 5002e59129aSraghus if (!nxgep->vpd_info.present) { 5012e59129aSraghus return (NXGE_OK); 5022e59129aSraghus } 5032e59129aSraghus 5042e59129aSraghus if (!nxgep->vpd_info.ver_valid) { 5052e59129aSraghus goto read_seeprom; 5062e59129aSraghus } 5072e59129aSraghus 5082e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5092e59129aSraghus "Reading phy type from expansion ROM")); 5102e59129aSraghus /* 5112e59129aSraghus * Try to read the phy type from the vpd data read off the 5122e59129aSraghus * expansion ROM. 5132e59129aSraghus */ 5142e59129aSraghus phy_type = nxgep->vpd_info.phy_type; 5152e59129aSraghus 516d81011f0Ssbehera if (strncmp(phy_type, "mif", 3) == 0) { 5172e59129aSraghus nxgep->mac.portmode = PORT_1G_COPPER; 5182e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 519d81011f0Ssbehera } else if (strncmp(phy_type, "xgf", 3) == 0) { 5202e59129aSraghus nxgep->mac.portmode = PORT_10G_FIBER; 5212e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 522d81011f0Ssbehera } else if (strncmp(phy_type, "pcs", 3) == 0) { 5232e59129aSraghus nxgep->mac.portmode = PORT_1G_FIBER; 5242e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 525d81011f0Ssbehera } else if (strncmp(phy_type, "xgc", 3) == 0) { 52600161856Syc148097 status = nxge_set_tn1010_param(nxgep); 52700161856Syc148097 if (status != NXGE_OK) { 52800161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 52900161856Syc148097 "nxge_get_xcvr_type: Failed to set TN1010 param")); 53000161856Syc148097 goto read_seeprom; 53100161856Syc148097 } 532d81011f0Ssbehera } else if (strncmp(phy_type, "xgsd", 4) == 0) { 533d81011f0Ssbehera nxgep->mac.portmode = PORT_10G_SERDES; 534d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 535d81011f0Ssbehera } else if (strncmp(phy_type, "gsd", 3) == 0) { 536d81011f0Ssbehera nxgep->mac.portmode = PORT_1G_SERDES; 537d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 5382e59129aSraghus } else { 539d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5402e59129aSraghus "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM", 5412e59129aSraghus phy_type[0], phy_type[1], phy_type[2])); 5422e59129aSraghus goto read_seeprom; 5432e59129aSraghus } 5442e59129aSraghus 5452e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: " 5462e59129aSraghus "Got phy type [0x%x] from VPD", nxgep->mac.portmode)); 5472e59129aSraghus 5482e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type")); 5492e59129aSraghus return (status); 5502e59129aSraghus 5512e59129aSraghus read_seeprom: 5522e59129aSraghus /* 5532e59129aSraghus * read the phy type from the SEEPROM - NCR registers 5542e59129aSraghus */ 5552e59129aSraghus status = nxge_espc_phy_type_get(nxgep); 5562e59129aSraghus if (status != NXGE_OK) { 5572e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5582e59129aSraghus "Failed to get phy type")); 5592e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version " 5602e59129aSraghus "[%s] invalid...please update", nxgep->vpd_info.ver)); 5612e59129aSraghus } 5622e59129aSraghus 5632e59129aSraghus return (status); 5642e59129aSraghus 5652e59129aSraghus } 5662e59129aSraghus 56759ac0c16Sdavemq /* Set up the PHY specific values. */ 56859ac0c16Sdavemq 56959ac0c16Sdavemq nxge_status_t 57059ac0c16Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep) 57159ac0c16Sdavemq { 57259ac0c16Sdavemq nxge_status_t status = NXGE_OK; 57359ac0c16Sdavemq uint32_t port_type; 57459ac0c16Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 5752e59129aSraghus uint32_t pcs_id = 0; 5762e59129aSraghus uint32_t pma_pmd_id = 0; 5772e59129aSraghus uint32_t phy_id = 0; 5782d17280bSsbehera uint16_t chip_id = 0; 57959ac0c16Sdavemq 58059ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>", 58159ac0c16Sdavemq portn)); 58259ac0c16Sdavemq 5832e59129aSraghus switch (nxgep->niu_type) { 5842e59129aSraghus case N2_NIU: 5852e59129aSraghus switch (nxgep->mac.portmode) { 5862e59129aSraghus case PORT_1G_FIBER: 5872e59129aSraghus case PORT_1G_SERDES: 5882e59129aSraghus nxgep->xcvr = nxge_n2_1G_table; 5892d17280bSsbehera nxgep->xcvr_addr = portn; 5902e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr", 5912e59129aSraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" : 5922e59129aSraghus "Serdes")); 5932e59129aSraghus break; 5942e59129aSraghus case PORT_10G_FIBER: 59589282175SSantwona Behera case PORT_10G_COPPER: 5962e59129aSraghus case PORT_10G_SERDES: 5972e59129aSraghus nxgep->xcvr = nxge_n2_10G_table; 5982d17280bSsbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) { 5992d17280bSsbehera nxgep->xcvr_addr = 6002d17280bSsbehera nxgep->nxge_hw_p->xcvr_addr[portn]; 6012d17280bSsbehera } 6022e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr", 6032e59129aSraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" : 60489282175SSantwona Behera ((nxgep->mac.portmode == PORT_10G_COPPER) ? 60589282175SSantwona Behera "Copper" : "Serdes"))); 6062e59129aSraghus break; 60700161856Syc148097 case PORT_1G_TN1010: 60800161856Syc148097 nxgep->xcvr = nxge_n2_1G_tn1010_table; 60900161856Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 61000161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61100161856Syc148097 "TN1010 Copper Xcvr in 1G")); 61200161856Syc148097 break; 61300161856Syc148097 case PORT_10G_TN1010: 61400161856Syc148097 nxgep->xcvr = nxge_n2_10G_tn1010_table; 61500161856Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 61600161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61700161856Syc148097 "TN1010 Copper Xcvr in 10G")); 61800161856Syc148097 break; 6192d17280bSsbehera case PORT_HSP_MODE: 6202d17280bSsbehera nxgep->xcvr = nxge_n2_10G_table; 6212d17280bSsbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR; 6222d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot " 6232d17280bSsbehera "Swappable Xcvr (not present)")); 6242d17280bSsbehera break; 6252e59129aSraghus default: 6262e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6272e59129aSraghus "<== nxge_setup_xcvr_table: " 6282e59129aSraghus "Unable to determine NIU portmode")); 6292e59129aSraghus return (NXGE_ERROR); 6302e59129aSraghus } 6312e59129aSraghus break; 6322e59129aSraghus default: 6332e59129aSraghus if (nxgep->mac.portmode == 0) { 6342e59129aSraghus /* 6352e59129aSraghus * Would be the case for platforms like Maramba 6362e59129aSraghus * in which the phy type could not be got from conf 6372e59129aSraghus * file, OBP, VPD or Serial PROM. 6382e59129aSraghus */ 6392e59129aSraghus if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 6402e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6412e59129aSraghus "<== nxge_setup_xcvr_table:" 6422e59129aSraghus " Invalid Neptune type [0x%x]", 6432e59129aSraghus nxgep->niu_type)); 6442e59129aSraghus return (NXGE_ERROR); 6452e59129aSraghus } 6462e59129aSraghus 6472e59129aSraghus port_type = nxgep->niu_type >> 6482e59129aSraghus (NXGE_PORT_TYPE_SHIFT * portn); 64959ac0c16Sdavemq port_type = port_type & (NXGE_PORT_TYPE_MASK); 6502e59129aSraghus 65159ac0c16Sdavemq switch (port_type) { 6522e59129aSraghus 65359ac0c16Sdavemq case NXGE_PORT_1G_COPPER: 65459ac0c16Sdavemq nxgep->mac.portmode = PORT_1G_COPPER; 6552e59129aSraghus break; 6562e59129aSraghus case NXGE_PORT_10G_COPPER: 6572e59129aSraghus nxgep->mac.portmode = PORT_10G_COPPER; 6582e59129aSraghus break; 6592e59129aSraghus case NXGE_PORT_1G_FIBRE: 6602e59129aSraghus nxgep->mac.portmode = PORT_1G_FIBER; 6612e59129aSraghus break; 6622e59129aSraghus case NXGE_PORT_10G_FIBRE: 6632e59129aSraghus nxgep->mac.portmode = PORT_10G_FIBER; 6642e59129aSraghus break; 6652e59129aSraghus case NXGE_PORT_1G_SERDES: 6662e59129aSraghus nxgep->mac.portmode = PORT_1G_SERDES; 6672e59129aSraghus break; 6682e59129aSraghus case NXGE_PORT_10G_SERDES: 6692e59129aSraghus nxgep->mac.portmode = PORT_10G_SERDES; 6702e59129aSraghus break; 67100161856Syc148097 /* Ports 2 and 3 of Alonso or ARTM */ 6722e59129aSraghus case NXGE_PORT_1G_RGMII_FIBER: 6732e59129aSraghus nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 6742e59129aSraghus break; 67500161856Syc148097 case NXGE_PORT_TN1010: 67600161856Syc148097 /* 67700161856Syc148097 * If this port uses the TN1010 copper 67800161856Syc148097 * PHY, then its speed is not known yet 67900161856Syc148097 * because nxge_scan_ports_phy could only 68000161856Syc148097 * figure out the vendor of the PHY but 68100161856Syc148097 * not its speed. nxge_set_tn1010_param 68200161856Syc148097 * will read the PHY speed and set 68300161856Syc148097 * portmode accordingly. 68400161856Syc148097 */ 68500161856Syc148097 if ((status = nxge_set_tn1010_param(nxgep)) 68600161856Syc148097 != NXGE_OK) { 68700161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 68800161856Syc148097 "nxge_set_tn1010_param failed")); 68900161856Syc148097 return (status); 69000161856Syc148097 } 69100161856Syc148097 break; 6922e59129aSraghus default: 6932e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 6942e59129aSraghus "<== nxge_setup_xcvr_table: " 6952e59129aSraghus "Unknown port-type: 0x%x", port_type)); 6962e59129aSraghus return (NXGE_ERROR); 6972e59129aSraghus } 6982e59129aSraghus } 6992e59129aSraghus 70000161856Syc148097 /* 70100161856Syc148097 * Above switch has figured out nxge->mac.portmode, now set 70200161856Syc148097 * nxgep->xcvr (the table) and nxgep->xcvr_addr according 70300161856Syc148097 * to portmode. 70400161856Syc148097 */ 7052e59129aSraghus switch (nxgep->mac.portmode) { 7062e59129aSraghus case PORT_1G_COPPER: 7072e59129aSraghus case PORT_1G_RGMII_FIBER: 70859ac0c16Sdavemq nxgep->xcvr = nxge_1G_copper_table; 7092d17280bSsbehera nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 71059ac0c16Sdavemq /* 71159ac0c16Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 71259ac0c16Sdavemq * swapped with ethernet port number. This is 7132e59129aSraghus * designed for better signal integrity in 7142e59129aSraghus * routing. This is also the case for the 7152e59129aSraghus * on-board Neptune copper ports on the Maramba 7162e59129aSraghus * platform. 71759ac0c16Sdavemq */ 7182e59129aSraghus switch (nxgep->platform_type) { 7192e59129aSraghus case P_NEPTUNE_ATLAS_4PORT: 7202e59129aSraghus case P_NEPTUNE_MARAMBA_P0: 7212e59129aSraghus case P_NEPTUNE_MARAMBA_P1: 72259ac0c16Sdavemq switch (portn) { 72359ac0c16Sdavemq case 0: 7242d17280bSsbehera nxgep->xcvr_addr += 3; 72559ac0c16Sdavemq break; 72659ac0c16Sdavemq case 1: 7272d17280bSsbehera nxgep->xcvr_addr += 1; 72859ac0c16Sdavemq break; 72959ac0c16Sdavemq case 2: 7302d17280bSsbehera nxgep->xcvr_addr -= 1; 73159ac0c16Sdavemq break; 73259ac0c16Sdavemq case 3: 7332d17280bSsbehera nxgep->xcvr_addr -= 3; 73459ac0c16Sdavemq break; 73559ac0c16Sdavemq default: 73659ac0c16Sdavemq return (NXGE_ERROR); 73759ac0c16Sdavemq } 73859ac0c16Sdavemq break; 7392e59129aSraghus default: 7402e59129aSraghus break; 7412e59129aSraghus } 742d81011f0Ssbehera 7432e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 7442e59129aSraghus (nxgep->mac.portmode == PORT_1G_COPPER) ? 7452e59129aSraghus "Copper" : "RGMII Fiber")); 7462e59129aSraghus break; 74700161856Syc148097 7482e59129aSraghus case PORT_10G_COPPER: 74959ac0c16Sdavemq nxgep->xcvr = nxge_10G_copper_table; 75059ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 75159ac0c16Sdavemq break; 75200161856Syc148097 75300161856Syc148097 case PORT_1G_TN1010: 75400161856Syc148097 nxgep->xcvr = nxge_1G_tn1010_table; 75500161856Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 75600161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 75700161856Syc148097 "1G TN1010 copper Xcvr")); 75800161856Syc148097 break; 75900161856Syc148097 76000161856Syc148097 case PORT_10G_TN1010: 76100161856Syc148097 nxgep->xcvr = nxge_10G_tn1010_table; 76200161856Syc148097 nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 76300161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 76400161856Syc148097 "10G TN1010 copper Xcvr")); 76500161856Syc148097 break; 76600161856Syc148097 7672e59129aSraghus case PORT_1G_FIBER: 7682e59129aSraghus case PORT_1G_SERDES: 76959ac0c16Sdavemq nxgep->xcvr = nxge_1G_fiber_table; 7702d17280bSsbehera nxgep->xcvr_addr = portn; 7712e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr", 7722e59129aSraghus (nxgep->mac.portmode == PORT_1G_FIBER) ? 7732e59129aSraghus "Fiber" : "Serdes")); 77459ac0c16Sdavemq break; 7752e59129aSraghus case PORT_10G_FIBER: 7762e59129aSraghus case PORT_10G_SERDES: 77759ac0c16Sdavemq nxgep->xcvr = nxge_10G_fiber_table; 7782d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr " 7792d17280bSsbehera "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] " 7802d17280bSsbehera "nxgep->xcvr_addr = [%d]", 7812d17280bSsbehera nxgep->nxge_hw_p->xcvr_addr[portn], 7822d17280bSsbehera nxgep->xcvr_addr)); 7832d17280bSsbehera if (nxgep->nxge_hw_p->xcvr_addr[portn]) { 7842d17280bSsbehera nxgep->xcvr_addr = 7852d17280bSsbehera nxgep->nxge_hw_p->xcvr_addr[portn]; 7862d17280bSsbehera } 7872e59129aSraghus switch (nxgep->platform_type) { 7882e59129aSraghus case P_NEPTUNE_MARAMBA_P0: 7892e59129aSraghus case P_NEPTUNE_MARAMBA_P1: 79059ac0c16Sdavemq /* 79159ac0c16Sdavemq * Switch off LED for corresponding copper 79259ac0c16Sdavemq * port 79359ac0c16Sdavemq */ 79459ac0c16Sdavemq nxge_bcm5464_link_led_off(nxgep); 7952e59129aSraghus break; 7962e59129aSraghus default: 7972e59129aSraghus break; 79859ac0c16Sdavemq } 7992e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr", 8002e59129aSraghus (nxgep->mac.portmode == PORT_10G_FIBER) ? 8012e59129aSraghus "Fiber" : "Serdes")); 80259ac0c16Sdavemq break; 8032d17280bSsbehera 8042d17280bSsbehera case PORT_HSP_MODE: 8052d17280bSsbehera nxgep->xcvr = nxge_10G_fiber_table; 8062d17280bSsbehera nxgep->xcvr.xcvr_inuse = HSP_XCVR; 8072d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot " 8082d17280bSsbehera "Swappable Xcvr (not present)")); 8092d17280bSsbehera break; 81059ac0c16Sdavemq default: 81159ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 81259ac0c16Sdavemq "Unknown port-type: 0x%x", port_type)); 81359ac0c16Sdavemq return (NXGE_ERROR); 81459ac0c16Sdavemq } 81559ac0c16Sdavemq } 81659ac0c16Sdavemq 81789282175SSantwona Behera if (nxgep->mac.portmode == PORT_10G_FIBER || 81889282175SSantwona Behera nxgep->mac.portmode == PORT_10G_COPPER) { 81952cdd236Ssbehera uint32_t pma_pmd_id; 82052cdd236Ssbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, 82152cdd236Ssbehera nxgep->xcvr_addr); 82252cdd236Ssbehera if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) { 82352cdd236Ssbehera chip_id = MRVL88X201X_CHIP_ID; 82452cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 82552cdd236Ssbehera "nxge_setup_xcvr_table: " 82652cdd236Ssbehera "Chip ID MARVELL [0x%x] for 10G xcvr", chip_id)); 82789282175SSantwona Behera } else if ((pma_pmd_id & NLP2020_DEV_ID_MASK) == 82889282175SSantwona Behera NLP2020_DEV_ID) { 82989282175SSantwona Behera chip_id = NLP2020_CHIP_ID; 83089282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 83189282175SSantwona Behera "nxge_setup_xcvr_table: " 83289282175SSantwona Behera "Chip ID AEL2020 [0x%x] for 10G xcvr", chip_id)); 83352cdd236Ssbehera } else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr, 8342d17280bSsbehera BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG, 8352d17280bSsbehera &chip_id)) == NXGE_OK) { 8362d17280bSsbehera 8372d17280bSsbehera switch (chip_id) { 8382d17280bSsbehera case BCM8704_CHIP_ID: 8392d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8402d17280bSsbehera "nxge_setup_xcvr_table: " 8412d17280bSsbehera "Chip ID 8704 [0x%x] for 10G xcvr", 8422d17280bSsbehera chip_id)); 8432d17280bSsbehera break; 8442d17280bSsbehera case BCM8706_CHIP_ID: 8452d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8462d17280bSsbehera "nxge_setup_xcvr_table: " 8472d17280bSsbehera "Chip ID 8706 [0x%x] for 10G xcvr", 8482d17280bSsbehera chip_id)); 8492d17280bSsbehera break; 8502d17280bSsbehera default: 8512d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8522d17280bSsbehera "nxge_setup_xcvr_table: " 8532d17280bSsbehera "Unknown Chip ID [0x%x] for 10G xcvr", 8542d17280bSsbehera chip_id)); 8552d17280bSsbehera break; 8562d17280bSsbehera } 8572d17280bSsbehera } 8582d17280bSsbehera } 8592d17280bSsbehera 86059ac0c16Sdavemq nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse; 8612d17280bSsbehera nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr; 8622d17280bSsbehera nxgep->chip_id = chip_id; 8632e59129aSraghus 8642e59129aSraghus /* 8652e59129aSraghus * Get the actual device ID value returned by MDIO read. 8662e59129aSraghus */ 8672e59129aSraghus nxgep->statsp->mac_stats.xcvr_id = 0; 8682e59129aSraghus 8692d17280bSsbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr); 8702e59129aSraghus if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) { 8712e59129aSraghus nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id; 8722e59129aSraghus } else { 8732d17280bSsbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr); 8742e59129aSraghus if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) { 8752e59129aSraghus nxgep->statsp->mac_stats.xcvr_id = pcs_id; 8762e59129aSraghus } else { 8772e59129aSraghus phy_id = nxge_get_cl22_phy_id(nxgep, 8782d17280bSsbehera nxgep->xcvr_addr); 8792e59129aSraghus if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 8802e59129aSraghus nxgep->statsp->mac_stats.xcvr_id = phy_id; 8812e59129aSraghus } 8822e59129aSraghus } 8832e59129aSraghus } 8842e59129aSraghus 88559ac0c16Sdavemq nxgep->mac.linkchkmode = LINKCHK_TIMER; 88659ac0c16Sdavemq 8872e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type" 88823b952a3SSantwona Behera "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type, 8892d17280bSsbehera nxgep->platform_type, nxgep->xcvr_addr)); 8902e59129aSraghus 89159ac0c16Sdavemq return (status); 89259ac0c16Sdavemq } 89359ac0c16Sdavemq 8946f45ec7bSml29623 /* Initialize the entire MAC and physical layer */ 8956f45ec7bSml29623 8966f45ec7bSml29623 nxge_status_t 8976f45ec7bSml29623 nxge_mac_init(p_nxge_t nxgep) 8986f45ec7bSml29623 { 8996f45ec7bSml29623 uint8_t portn; 9006f45ec7bSml29623 nxge_status_t status = NXGE_OK; 9016f45ec7bSml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 9026f45ec7bSml29623 9036f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 9046f45ec7bSml29623 9056f45ec7bSml29623 nxgep->mac.portnum = portn; 9066f45ec7bSml29623 nxgep->mac.porttype = PORT_TYPE_XMAC; 9076f45ec7bSml29623 9086f45ec7bSml29623 if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 9096f45ec7bSml29623 nxgep->mac.porttype = PORT_TYPE_BMAC; 9106f45ec7bSml29623 91100161856Syc148097 9126f45ec7bSml29623 /* Initialize XIF to configure a network mode */ 9136f45ec7bSml29623 if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 9146f45ec7bSml29623 goto fail; 9156f45ec7bSml29623 } 9166f45ec7bSml29623 9176f45ec7bSml29623 if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 9186f45ec7bSml29623 goto fail; 9196f45ec7bSml29623 } 9206f45ec7bSml29623 9216f45ec7bSml29623 /* Initialize TX and RX MACs */ 9226f45ec7bSml29623 /* 9236f45ec7bSml29623 * Always perform XIF init first, before TX and RX MAC init 9246f45ec7bSml29623 */ 9256f45ec7bSml29623 if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 9266f45ec7bSml29623 goto fail; 9276f45ec7bSml29623 9286f45ec7bSml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 9296f45ec7bSml29623 goto fail; 9306f45ec7bSml29623 9316f45ec7bSml29623 if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 9326f45ec7bSml29623 goto fail; 9336f45ec7bSml29623 9346f45ec7bSml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 9356f45ec7bSml29623 goto fail; 9366f45ec7bSml29623 9376f45ec7bSml29623 if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 9386f45ec7bSml29623 goto fail; 9396f45ec7bSml29623 940e759c33aSMichael Speer if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) { 9416f45ec7bSml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 9426f45ec7bSml29623 goto fail; 943e759c33aSMichael Speer } 9446f45ec7bSml29623 945cb9d3ae6Smisaki /* Initialize MAC control configuration */ 946cb9d3ae6Smisaki if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) { 947cb9d3ae6Smisaki goto fail; 948cb9d3ae6Smisaki } 949cb9d3ae6Smisaki 9506f45ec7bSml29623 nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 9516f45ec7bSml29623 952d81011f0Ssbehera /* The Neptune Serdes needs to be reinitialized again */ 953d81011f0Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 954d81011f0Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 95500161856Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) || 956d81011f0Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 957d81011f0Ssbehera ((portn == 0) || (portn == 1))) { 958d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 959d81011f0Ssbehera "nxge_mac_init: reinit Neptune 1G Serdes ")); 960d81011f0Ssbehera if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) { 961d81011f0Ssbehera goto fail; 962d81011f0Ssbehera } 963d81011f0Ssbehera } 964d81011f0Ssbehera 9652e59129aSraghus 9666f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 9676f45ec7bSml29623 9686f45ec7bSml29623 return (NXGE_OK); 9696f45ec7bSml29623 fail: 9706f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 97152ccf843Smisaki "nxge_mac_init: failed to initialize MAC port<%d>", portn)); 9726f45ec7bSml29623 return (status); 9736f45ec7bSml29623 } 9746f45ec7bSml29623 9756f45ec7bSml29623 /* Initialize the Ethernet Link */ 9766f45ec7bSml29623 9776f45ec7bSml29623 nxge_status_t 9786f45ec7bSml29623 nxge_link_init(p_nxge_t nxgep) 9796f45ec7bSml29623 { 9806f45ec7bSml29623 nxge_status_t status = NXGE_OK; 9812e59129aSraghus nxge_port_mode_t portmode; 9826f45ec7bSml29623 #ifdef NXGE_DEBUG 9836f45ec7bSml29623 uint8_t portn; 9846f45ec7bSml29623 9856f45ec7bSml29623 portn = nxgep->mac.portnum; 9866f45ec7bSml29623 9876f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 9886f45ec7bSml29623 #endif 9891c7408c9Stc99174@train /* For Opus NEM, Serdes always needs to be initialized */ 9906f45ec7bSml29623 9912e59129aSraghus portmode = nxgep->mac.portmode; 9922d17280bSsbehera 99300161856Syc148097 /* 99400161856Syc148097 * Workaround to get link up in both NIU ports. Some portmodes require 99500161856Syc148097 * that the xcvr be initialized twice, the first time before calling 99600161856Syc148097 * nxge_serdes_init. 99700161856Syc148097 */ 9982e59129aSraghus if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) && 99900161856Syc148097 (portmode != PORT_10G_TN1010) && 100000161856Syc148097 (portmode != PORT_1G_TN1010) && 10012e59129aSraghus (portmode != PORT_1G_SERDES)) { 10022e59129aSraghus if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) { 10036f45ec7bSml29623 goto fail; 10046f45ec7bSml29623 } 10052e59129aSraghus } 100600161856Syc148097 10076f45ec7bSml29623 NXGE_DELAY(200000); 10086f45ec7bSml29623 /* Initialize internal serdes */ 10096f45ec7bSml29623 if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 10106f45ec7bSml29623 goto fail; 10116f45ec7bSml29623 NXGE_DELAY(200000); 10126f45ec7bSml29623 if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 10136f45ec7bSml29623 goto fail; 10146f45ec7bSml29623 10156f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 10166f45ec7bSml29623 10176f45ec7bSml29623 return (NXGE_OK); 10186f45ec7bSml29623 10196f45ec7bSml29623 fail: 102052ccf843Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ", 102152ccf843Smisaki "failed to initialize Ethernet link on port<%d>", portn)); 10226f45ec7bSml29623 10236f45ec7bSml29623 return (status); 10246f45ec7bSml29623 } 10256f45ec7bSml29623 10266f45ec7bSml29623 10276f45ec7bSml29623 /* Initialize the XIF sub-block within the MAC */ 10286f45ec7bSml29623 10296f45ec7bSml29623 nxge_status_t 10306f45ec7bSml29623 nxge_xif_init(p_nxge_t nxgep) 10316f45ec7bSml29623 { 10326f45ec7bSml29623 uint32_t xif_cfg = 0; 10336f45ec7bSml29623 npi_attr_t ap; 10346f45ec7bSml29623 uint8_t portn; 10356f45ec7bSml29623 nxge_port_t portt; 10366f45ec7bSml29623 nxge_port_mode_t portmode; 10376f45ec7bSml29623 p_nxge_stats_t statsp; 10386f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 10396f45ec7bSml29623 npi_handle_t handle; 10406f45ec7bSml29623 10416f45ec7bSml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 10426f45ec7bSml29623 10436f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 10446f45ec7bSml29623 10456f45ec7bSml29623 handle = nxgep->npi_handle; 10466f45ec7bSml29623 portmode = nxgep->mac.portmode; 10476f45ec7bSml29623 portt = nxgep->mac.porttype; 10486f45ec7bSml29623 statsp = nxgep->statsp; 10496f45ec7bSml29623 1050d81011f0Ssbehera if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) && 1051d81011f0Ssbehera ((nxgep->mac.portmode == PORT_1G_SERDES) || 105200161856Syc148097 (nxgep->mac.portmode == PORT_1G_TN1010) || 1053d81011f0Ssbehera (nxgep->mac.portmode == PORT_1G_FIBER)) && 1054d81011f0Ssbehera ((portn == 0) || (portn == 1))) { 1055d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1056d81011f0Ssbehera "nxge_xcvr_init: set ATCA mode")); 1057d81011f0Ssbehera npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE); 1058d81011f0Ssbehera } 1059d81011f0Ssbehera 10606f45ec7bSml29623 if (portt == PORT_TYPE_XMAC) { 10616f45ec7bSml29623 10626f45ec7bSml29623 /* Setup XIF Configuration for XMAC */ 10636f45ec7bSml29623 10646f45ec7bSml29623 if ((portmode == PORT_10G_FIBER) || 10652e59129aSraghus (portmode == PORT_10G_COPPER) || 106600161856Syc148097 (portmode == PORT_10G_TN1010) || 10671c7408c9Stc99174@train (portmode == PORT_HSP_MODE) || 10682e59129aSraghus (portmode == PORT_10G_SERDES)) 10696f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_LFS; 10706f45ec7bSml29623 107100161856Syc148097 /* Bypass PCS so that RGMII will be used */ 10726f45ec7bSml29623 if (portmode == PORT_1G_COPPER) { 10736f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 10746f45ec7bSml29623 } 10756f45ec7bSml29623 10766f45ec7bSml29623 /* Set MAC Internal Loopback if necessary */ 10776f45ec7bSml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 10786f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 10796f45ec7bSml29623 10806f45ec7bSml29623 if (statsp->mac_stats.link_speed == 100) 10816f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 10826f45ec7bSml29623 10836f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 10846f45ec7bSml29623 10852e59129aSraghus if ((portmode == PORT_10G_FIBER) || 108689282175SSantwona Behera (portmode == PORT_10G_COPPER) || 108700161856Syc148097 (portmode == PORT_10G_TN1010) || 108800161856Syc148097 (portmode == PORT_1G_TN1010) || 10891c7408c9Stc99174@train (portmode == PORT_HSP_MODE) || 10902e59129aSraghus (portmode == PORT_10G_SERDES)) { 109100161856Syc148097 /* Assume LED same for 1G and 10G */ 10926f45ec7bSml29623 if (statsp->mac_stats.link_up) { 10936f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 10946f45ec7bSml29623 } else { 10956f45ec7bSml29623 xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 10966f45ec7bSml29623 } 10976f45ec7bSml29623 } 10986f45ec7bSml29623 10996f45ec7bSml29623 rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 11006f45ec7bSml29623 if (rs != NPI_SUCCESS) 11016f45ec7bSml29623 goto fail; 11026f45ec7bSml29623 11036f45ec7bSml29623 nxgep->mac.xif_config = xif_cfg; 11046f45ec7bSml29623 11056f45ec7bSml29623 /* Set Port Mode */ 11066f45ec7bSml29623 if ((portmode == PORT_10G_FIBER) || 11072e59129aSraghus (portmode == PORT_10G_COPPER) || 110800161856Syc148097 (portmode == PORT_10G_TN1010) || 11091c7408c9Stc99174@train (portmode == PORT_HSP_MODE) || 11102e59129aSraghus (portmode == PORT_10G_SERDES)) { 11116f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11126f45ec7bSml29623 MAC_XGMII_MODE, rs); 11136f45ec7bSml29623 if (rs != NPI_SUCCESS) 11146f45ec7bSml29623 goto fail; 11156f45ec7bSml29623 if (statsp->mac_stats.link_up) { 11166f45ec7bSml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 11176f45ec7bSml29623 goto fail; 11186f45ec7bSml29623 } else { 11196f45ec7bSml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 11206f45ec7bSml29623 goto fail; 11216f45ec7bSml29623 } 11226f45ec7bSml29623 } else if ((portmode == PORT_1G_FIBER) || 11232e59129aSraghus (portmode == PORT_1G_COPPER) || 1124d81011f0Ssbehera (portmode == PORT_1G_SERDES) || 112500161856Syc148097 (portmode == PORT_1G_TN1010) || 1126d81011f0Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 1127d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1128d81011f0Ssbehera "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]", 1129d81011f0Ssbehera portn, portmode, statsp->mac_stats.link_speed)); 11306f45ec7bSml29623 if (statsp->mac_stats.link_speed == 1000) { 11316f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11326f45ec7bSml29623 MAC_GMII_MODE, rs); 11336f45ec7bSml29623 } else { 11346f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 11356f45ec7bSml29623 MAC_MII_MODE, rs); 11366f45ec7bSml29623 } 11376f45ec7bSml29623 if (rs != NPI_SUCCESS) 11386f45ec7bSml29623 goto fail; 11396f45ec7bSml29623 } else { 11406f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 11416f45ec7bSml29623 "nxge_xif_init: Unknown port mode (%d)" 11426f45ec7bSml29623 " for port<%d>", portmode, portn)); 11436f45ec7bSml29623 goto fail; 11446f45ec7bSml29623 } 11456f45ec7bSml29623 1146d81011f0Ssbehera /* Enable ATCA mode */ 1147d81011f0Ssbehera 11486f45ec7bSml29623 } else if (portt == PORT_TYPE_BMAC) { 11496f45ec7bSml29623 11506f45ec7bSml29623 /* Setup XIF Configuration for BMAC */ 11516f45ec7bSml29623 1152d81011f0Ssbehera if ((portmode == PORT_1G_COPPER) || 1153d81011f0Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 11546f45ec7bSml29623 if (statsp->mac_stats.link_speed == 100) 11556f45ec7bSml29623 xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 11566f45ec7bSml29623 } 11576f45ec7bSml29623 11586f45ec7bSml29623 if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 11596f45ec7bSml29623 xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 11606f45ec7bSml29623 11616f45ec7bSml29623 if (statsp->mac_stats.link_speed == 1000) 11626f45ec7bSml29623 xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 11636f45ec7bSml29623 11646f45ec7bSml29623 xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 11656f45ec7bSml29623 11666f45ec7bSml29623 rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 11676f45ec7bSml29623 if (rs != NPI_SUCCESS) 11686f45ec7bSml29623 goto fail; 11696f45ec7bSml29623 nxgep->mac.xif_config = xif_cfg; 11706f45ec7bSml29623 } 11716f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 11726f45ec7bSml29623 return (NXGE_OK); 11736f45ec7bSml29623 fail: 11746f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 117552ccf843Smisaki "nxge_xif_init: Failed to initialize XIF port<%d>", portn)); 11766f45ec7bSml29623 return (NXGE_ERROR | rs); 11776f45ec7bSml29623 } 11786f45ec7bSml29623 11796f45ec7bSml29623 118000161856Syc148097 /* 118100161856Syc148097 * Initialize the PCS sub-block in the MAC. Note that PCS does not 118200161856Syc148097 * support loopback like XPCS. 118300161856Syc148097 */ 11846f45ec7bSml29623 nxge_status_t 11856f45ec7bSml29623 nxge_pcs_init(p_nxge_t nxgep) 11866f45ec7bSml29623 { 11876f45ec7bSml29623 pcs_cfg_t pcs_cfg; 11886f45ec7bSml29623 uint32_t val; 11896f45ec7bSml29623 uint8_t portn; 11906f45ec7bSml29623 nxge_port_mode_t portmode; 11916f45ec7bSml29623 npi_handle_t handle; 11926f45ec7bSml29623 p_nxge_stats_t statsp; 119300161856Syc148097 pcs_ctrl_t pcs_ctrl; 11946f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 119500161856Syc148097 uint8_t i; 11966f45ec7bSml29623 11976f45ec7bSml29623 handle = nxgep->npi_handle; 11986f45ec7bSml29623 portmode = nxgep->mac.portmode; 11996f45ec7bSml29623 portn = nxgep->mac.portnum; 12006f45ec7bSml29623 statsp = nxgep->statsp; 12016f45ec7bSml29623 12026f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 12036f45ec7bSml29623 120400161856Syc148097 if (portmode == PORT_1G_FIBER || 120500161856Syc148097 portmode == PORT_1G_TN1010 || 120600161856Syc148097 portmode == PORT_1G_SERDES) { 120700161856Syc148097 if (portmode == PORT_1G_TN1010) { 120800161856Syc148097 /* Reset PCS multiple time in PORT_1G_TN1010 mode */ 120900161856Syc148097 for (i = 0; i < 6; i ++) { 121000161856Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn)) 121100161856Syc148097 != NPI_SUCCESS) { 121200161856Syc148097 goto fail; 121300161856Syc148097 } 121400161856Syc148097 } 121500161856Syc148097 } else { 121600161856Syc148097 if ((rs = npi_mac_pcs_reset(handle, portn)) 121700161856Syc148097 != NPI_SUCCESS) 12182e59129aSraghus goto fail; 12192e59129aSraghus } 12202e59129aSraghus 12216f45ec7bSml29623 /* Initialize port's PCS */ 12226f45ec7bSml29623 pcs_cfg.value = 0; 12236f45ec7bSml29623 pcs_cfg.bits.w0.enable = 1; 12246f45ec7bSml29623 pcs_cfg.bits.w0.mask = 1; 12256f45ec7bSml29623 PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 12266f45ec7bSml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 12276f45ec7bSml29623 12282e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 12292e59129aSraghus "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx", 12302e59129aSraghus portn, pcs_cfg.value)); 123100161856Syc148097 123200161856Syc148097 if (portmode == PORT_1G_TN1010) { 123300161856Syc148097 /* 123400161856Syc148097 * Must disable PCS auto-negotiation when the the driver 123500161856Syc148097 * is driving the TN1010 based XAUI card Otherwise the 123600161856Syc148097 * autonegotiation between the PCS and the TN1010 PCS 123700161856Syc148097 * will never complete and the Neptune/NIU will not work 123800161856Syc148097 */ 123900161856Syc148097 pcs_ctrl.value = 0; 124000161856Syc148097 PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG, 124100161856Syc148097 pcs_ctrl.value); 124200161856Syc148097 } 124300161856Syc148097 } else if (portmode == PORT_10G_FIBER || 124400161856Syc148097 portmode == PORT_10G_COPPER || 124500161856Syc148097 portmode == PORT_10G_TN1010 || 12461c7408c9Stc99174@train portmode == PORT_HSP_MODE || 124700161856Syc148097 portmode == PORT_10G_SERDES) { 12486f45ec7bSml29623 /* Use internal XPCS, bypass 1G PCS */ 12496f45ec7bSml29623 XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 12506f45ec7bSml29623 val &= ~XMAC_XIF_XPCS_BYPASS; 12516f45ec7bSml29623 XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 12526f45ec7bSml29623 12536f45ec7bSml29623 if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 12546f45ec7bSml29623 goto fail; 12556f45ec7bSml29623 12566f45ec7bSml29623 /* Set XPCS Internal Loopback if necessary */ 12576f45ec7bSml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 125852ccf843Smisaki XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS) 12596f45ec7bSml29623 goto fail; 126000161856Syc148097 12616f45ec7bSml29623 if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 12626f45ec7bSml29623 (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 12636f45ec7bSml29623 val |= XPCS_CTRL1_LOOPBK; 12646f45ec7bSml29623 else 12656f45ec7bSml29623 val &= ~XPCS_CTRL1_LOOPBK; 12666f45ec7bSml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 126752ccf843Smisaki XPCS_REG_CONTROL1, val)) != NPI_SUCCESS) 12686f45ec7bSml29623 goto fail; 12696f45ec7bSml29623 12706f45ec7bSml29623 /* Clear descw errors */ 12716f45ec7bSml29623 if ((rs = npi_xmac_xpcs_write(handle, portn, 127252ccf843Smisaki XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS) 12736f45ec7bSml29623 goto fail; 12746f45ec7bSml29623 /* Clear symbol errors */ 12756f45ec7bSml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 127652ccf843Smisaki XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS) 12776f45ec7bSml29623 goto fail; 12786f45ec7bSml29623 if ((rs = npi_xmac_xpcs_read(handle, portn, 127952ccf843Smisaki XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS) 12806f45ec7bSml29623 goto fail; 12816f45ec7bSml29623 1282d81011f0Ssbehera } else if ((portmode == PORT_1G_COPPER) || 1283d81011f0Ssbehera (portmode == PORT_1G_RGMII_FIBER)) { 1284d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1285d81011f0Ssbehera "==> nxge_pcs_init: (1G) copper port<%d>", portn)); 12866f45ec7bSml29623 if (portn < 4) { 12876f45ec7bSml29623 PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 12886f45ec7bSml29623 PCS_DATAPATH_MODE_MII); 12896f45ec7bSml29623 } 12906f45ec7bSml29623 if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 12916f45ec7bSml29623 goto fail; 12926f45ec7bSml29623 12936f45ec7bSml29623 } else { 12946f45ec7bSml29623 goto fail; 12956f45ec7bSml29623 } 12966f45ec7bSml29623 pass: 12976f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 12986f45ec7bSml29623 return (NXGE_OK); 12996f45ec7bSml29623 fail: 13006f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 130152ccf843Smisaki "nxge_pcs_init: Failed to initialize PCS port<%d>", portn)); 13026f45ec7bSml29623 return (NXGE_ERROR | rs); 13036f45ec7bSml29623 } 13046f45ec7bSml29623 1305cb9d3ae6Smisaki /* 1306cb9d3ae6Smisaki * Initialize the MAC CTRL sub-block within the MAC 1307cb9d3ae6Smisaki * Only the receive-pause-cap is supported. 1308cb9d3ae6Smisaki */ 1309cb9d3ae6Smisaki nxge_status_t 1310cb9d3ae6Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep) 1311cb9d3ae6Smisaki { 1312cb9d3ae6Smisaki uint8_t portn; 1313cb9d3ae6Smisaki nxge_port_t portt; 1314cb9d3ae6Smisaki p_nxge_stats_t statsp; 1315cb9d3ae6Smisaki npi_handle_t handle; 1316cb9d3ae6Smisaki uint32_t val; 1317cb9d3ae6Smisaki 1318cb9d3ae6Smisaki portn = NXGE_GET_PORT_NUM(nxgep->function_num); 1319cb9d3ae6Smisaki 1320cb9d3ae6Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>", 1321cb9d3ae6Smisaki portn)); 1322cb9d3ae6Smisaki 1323cb9d3ae6Smisaki handle = nxgep->npi_handle; 1324cb9d3ae6Smisaki portt = nxgep->mac.porttype; 1325cb9d3ae6Smisaki statsp = nxgep->statsp; 1326cb9d3ae6Smisaki 1327cb9d3ae6Smisaki if (portt == PORT_TYPE_XMAC) { 132800161856Syc148097 /* Reading the current XMAC Config Register for XMAC */ 1329cb9d3ae6Smisaki XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 1330cb9d3ae6Smisaki 1331cb9d3ae6Smisaki /* 1332cb9d3ae6Smisaki * Setup XMAC Configuration for XMAC 1333cb9d3ae6Smisaki * XMAC only supports receive-pause 1334cb9d3ae6Smisaki */ 1335cb9d3ae6Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 1336cb9d3ae6Smisaki if (!statsp->mac_stats.adv_cap_pause) { 1337cb9d3ae6Smisaki /* 1338cb9d3ae6Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 1339cb9d3ae6Smisaki * is 0, enable receive pause. 1340cb9d3ae6Smisaki */ 1341cb9d3ae6Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 1342cb9d3ae6Smisaki } else { 1343cb9d3ae6Smisaki /* 1344cb9d3ae6Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 1345cb9d3ae6Smisaki * is 1, disable receive pause. Send pause is 1346cb9d3ae6Smisaki * not supported. 1347cb9d3ae6Smisaki */ 1348cb9d3ae6Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 1349cb9d3ae6Smisaki } 1350cb9d3ae6Smisaki } else { 13511bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13521bd6825cSml29623 "==> nxge_mac_ctrl_init: port<%d>: pause", 13531bd6825cSml29623 portn)); 1354cb9d3ae6Smisaki if (statsp->mac_stats.adv_cap_pause) { 13551bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13561bd6825cSml29623 "==> nxge_mac_ctrl_init: port<%d>: " 13571bd6825cSml29623 "enable pause", portn)); 1358cb9d3ae6Smisaki /* 1359cb9d3ae6Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 1360cb9d3ae6Smisaki * is 1, enable receive pause. 1361cb9d3ae6Smisaki */ 1362cb9d3ae6Smisaki val |= XMAC_RX_CFG_RX_PAUSE_EN; 1363cb9d3ae6Smisaki } else { 1364cb9d3ae6Smisaki /* 1365cb9d3ae6Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 1366cb9d3ae6Smisaki * is 0, disable receive pause. Send pause is 1367cb9d3ae6Smisaki * not supported 1368cb9d3ae6Smisaki */ 13691bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 13701bd6825cSml29623 "==> nxge_mac_ctrl_init: port<%d>: " 13711bd6825cSml29623 "disable pause", portn)); 1372cb9d3ae6Smisaki val &= ~XMAC_RX_CFG_RX_PAUSE_EN; 1373cb9d3ae6Smisaki } 1374cb9d3ae6Smisaki } 1375cb9d3ae6Smisaki XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 1376cb9d3ae6Smisaki } else if (portt == PORT_TYPE_BMAC) { 137700161856Syc148097 /* Reading the current MAC CTRL Config Register for BMAC */ 1378cb9d3ae6Smisaki BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val); 1379cb9d3ae6Smisaki 1380cb9d3ae6Smisaki /* Setup MAC CTRL Configuration for BMAC */ 1381cb9d3ae6Smisaki if (statsp->mac_stats.adv_cap_asmpause) { 1382cb9d3ae6Smisaki if (statsp->mac_stats.adv_cap_pause) { 1383cb9d3ae6Smisaki /* 1384cb9d3ae6Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 1385cb9d3ae6Smisaki * is 1, disable receive pause. Send pause 1386cb9d3ae6Smisaki * is not supported 1387cb9d3ae6Smisaki */ 1388cb9d3ae6Smisaki val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN; 1389cb9d3ae6Smisaki } else { 1390cb9d3ae6Smisaki /* 1391cb9d3ae6Smisaki * If adv_cap_asmpause is 1 and adv_cap_pause 1392cb9d3ae6Smisaki * is 0, enable receive pause and disable 1393cb9d3ae6Smisaki * send pause. 1394cb9d3ae6Smisaki */ 1395cb9d3ae6Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 1396cb9d3ae6Smisaki val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN; 1397cb9d3ae6Smisaki } 1398cb9d3ae6Smisaki } else { 1399cb9d3ae6Smisaki if (statsp->mac_stats.adv_cap_pause) { 1400cb9d3ae6Smisaki /* 1401cb9d3ae6Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 1402cb9d3ae6Smisaki * is 1, enable receive pause. Send pause is 1403cb9d3ae6Smisaki * not supported. 1404cb9d3ae6Smisaki */ 1405cb9d3ae6Smisaki val |= MAC_CTRL_CFG_RECV_PAUSE_EN; 1406cb9d3ae6Smisaki } else { 1407cb9d3ae6Smisaki /* 1408cb9d3ae6Smisaki * If adv_cap_asmpause is 0 and adv_cap_pause 1409cb9d3ae6Smisaki * is 0, pause capability is not available in 1410cb9d3ae6Smisaki * either direction. 1411cb9d3ae6Smisaki */ 1412cb9d3ae6Smisaki val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN & 1413cb9d3ae6Smisaki ~MAC_CTRL_CFG_RECV_PAUSE_EN); 1414cb9d3ae6Smisaki } 1415cb9d3ae6Smisaki } 1416cb9d3ae6Smisaki BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val); 1417cb9d3ae6Smisaki } 1418cb9d3ae6Smisaki 1419cb9d3ae6Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>", 1420cb9d3ae6Smisaki portn)); 1421cb9d3ae6Smisaki 1422cb9d3ae6Smisaki return (NXGE_OK); 1423cb9d3ae6Smisaki } 1424cb9d3ae6Smisaki 14256f45ec7bSml29623 /* Initialize the Internal Serdes */ 14266f45ec7bSml29623 14276f45ec7bSml29623 nxge_status_t 14286f45ec7bSml29623 nxge_serdes_init(p_nxge_t nxgep) 14296f45ec7bSml29623 { 14306f45ec7bSml29623 p_nxge_stats_t statsp; 14316f45ec7bSml29623 #ifdef NXGE_DEBUG 14326f45ec7bSml29623 uint8_t portn; 14336f45ec7bSml29623 #endif 14346f45ec7bSml29623 nxge_status_t status = NXGE_OK; 14356f45ec7bSml29623 14366f45ec7bSml29623 #ifdef NXGE_DEBUG 14376f45ec7bSml29623 portn = nxgep->mac.portnum; 14386f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14396f45ec7bSml29623 "==> nxge_serdes_init port<%d>", portn)); 14406f45ec7bSml29623 #endif 14416f45ec7bSml29623 144259ac0c16Sdavemq if (nxgep->xcvr.serdes_init) { 14436f45ec7bSml29623 statsp = nxgep->statsp; 144459ac0c16Sdavemq status = nxgep->xcvr.serdes_init(nxgep); 144559ac0c16Sdavemq if (status != NXGE_OK) 14466f45ec7bSml29623 goto fail; 14476f45ec7bSml29623 statsp->mac_stats.serdes_inits++; 144859ac0c16Sdavemq } 14496f45ec7bSml29623 14506f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 14516f45ec7bSml29623 portn)); 14526f45ec7bSml29623 14536f45ec7bSml29623 return (NXGE_OK); 14546f45ec7bSml29623 14556f45ec7bSml29623 fail: 14566f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14576f45ec7bSml29623 "nxge_serdes_init: Failed to initialize serdes for port<%d>", 14586f45ec7bSml29623 portn)); 14596f45ec7bSml29623 14606f45ec7bSml29623 return (status); 14616f45ec7bSml29623 } 14626f45ec7bSml29623 14636f45ec7bSml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 14646f45ec7bSml29623 146559ac0c16Sdavemq static nxge_status_t 14666f45ec7bSml29623 nxge_n2_serdes_init(p_nxge_t nxgep) 14676f45ec7bSml29623 { 14686f45ec7bSml29623 uint8_t portn; 14696f45ec7bSml29623 int chan; 14706f45ec7bSml29623 esr_ti_cfgpll_l_t pll_cfg_l; 14712e59129aSraghus esr_ti_cfgpll_l_t pll_sts_l; 14726f45ec7bSml29623 esr_ti_cfgrx_l_t rx_cfg_l; 14736f45ec7bSml29623 esr_ti_cfgrx_h_t rx_cfg_h; 14746f45ec7bSml29623 esr_ti_cfgtx_l_t tx_cfg_l; 14756f45ec7bSml29623 esr_ti_cfgtx_h_t tx_cfg_h; 14762e59129aSraghus #ifdef NXGE_DEBUG 14772e59129aSraghus esr_ti_testcfg_t cfg; 14782e59129aSraghus #endif 14796f45ec7bSml29623 esr_ti_testcfg_t test_cfg; 14806f45ec7bSml29623 nxge_status_t status = NXGE_OK; 14816f45ec7bSml29623 14826f45ec7bSml29623 portn = nxgep->mac.portnum; 14836f45ec7bSml29623 14846f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 14856f45ec7bSml29623 portn)); 14864df55fdeSJanie Lu if (nxgep->niu_hw_type == NIU_HW_TYPE_RF) { 14874df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 14884df55fdeSJanie Lu "==> nxge_n2_serdes_init port<%d>: KT-NIU", portn)); 14894df55fdeSJanie Lu return (nxge_n2_kt_serdes_init(nxgep)); 14904df55fdeSJanie Lu } 14916f45ec7bSml29623 14926f45ec7bSml29623 tx_cfg_l.value = 0; 14936f45ec7bSml29623 tx_cfg_h.value = 0; 14946f45ec7bSml29623 rx_cfg_l.value = 0; 14956f45ec7bSml29623 rx_cfg_h.value = 0; 14966f45ec7bSml29623 pll_cfg_l.value = 0; 14972e59129aSraghus pll_sts_l.value = 0; 14986f45ec7bSml29623 test_cfg.value = 0; 14996f45ec7bSml29623 150000161856Syc148097 /* 150100161856Syc148097 * If the nxge driver has been plumbed without a link, then it will 150200161856Syc148097 * detect a link up when a cable connecting to an anto-negotiation 150300161856Syc148097 * partner is plugged into the port. Because the TN1010 PHY supports 150400161856Syc148097 * both 1G and 10G speeds, the driver must re-configure the 150500161856Syc148097 * Neptune/NIU according to the negotiated speed. nxge_n2_serdes_init 150600161856Syc148097 * is called at the post-link-up reconfiguration time. Here it calls 150700161856Syc148097 * nxge_set_tn1010_param to set portmode before re-initializing 150800161856Syc148097 * the serdes. 150900161856Syc148097 */ 151000161856Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 || 151100161856Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) { 151200161856Syc148097 if (nxge_set_tn1010_param(nxgep) != NXGE_OK) { 151300161856Syc148097 goto fail; 151400161856Syc148097 } 151500161856Syc148097 } 151600161856Syc148097 151700161856Syc148097 if (nxgep->mac.portmode == PORT_10G_FIBER || 151889282175SSantwona Behera nxgep->mac.portmode == PORT_10G_COPPER || 151900161856Syc148097 nxgep->mac.portmode == PORT_10G_TN1010 || 15201c7408c9Stc99174@train nxgep->mac.portmode == PORT_HSP_MODE || 152100161856Syc148097 nxgep->mac.portmode == PORT_10G_SERDES) { 15226f45ec7bSml29623 /* 0x0E01 */ 15236f45ec7bSml29623 tx_cfg_l.bits.entx = 1; 15246f45ec7bSml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 15256f45ec7bSml29623 15266f45ec7bSml29623 /* 0x9101 */ 15276f45ec7bSml29623 rx_cfg_l.bits.enrx = 1; 15286f45ec7bSml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 15296f45ec7bSml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 15306f45ec7bSml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 15316f45ec7bSml29623 15326f45ec7bSml29623 /* 0x0008 */ 15336f45ec7bSml29623 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 15346f45ec7bSml29623 15356f45ec7bSml29623 /* Set loopback mode if necessary */ 15366f45ec7bSml29623 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 15376f45ec7bSml29623 tx_cfg_l.bits.entest = 1; 15386f45ec7bSml29623 rx_cfg_l.bits.entest = 1; 15396f45ec7bSml29623 test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 15406f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, 15416f45ec7bSml29623 ESR_N2_DEV_ADDR, 154252ccf843Smisaki ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) 15436f45ec7bSml29623 goto fail; 15446f45ec7bSml29623 } 15456f45ec7bSml29623 154600161856Syc148097 /* Initialize PLL for 10G */ 154700161856Syc148097 pll_cfg_l.bits.mpy = CFGPLL_MPY_10X; 154800161856Syc148097 pll_cfg_l.bits.enpll = 1; 154900161856Syc148097 pll_sts_l.bits.enpll = 1; 155000161856Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 155100161856Syc148097 ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 155200161856Syc148097 goto fail; 15536f45ec7bSml29623 155400161856Syc148097 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 155500161856Syc148097 ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 155600161856Syc148097 goto fail; 15576f45ec7bSml29623 155800161856Syc148097 #ifdef NXGE_DEBUG 155900161856Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 156000161856Syc148097 ESR_N2_PLL_CFG_L_REG, &cfg.value); 156100161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 156200161856Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 156300161856Syc148097 portn, pll_cfg_l.value, cfg.value)); 156400161856Syc148097 156500161856Syc148097 nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 156600161856Syc148097 ESR_N2_PLL_STS_L_REG, &cfg.value); 156700161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 156800161856Syc148097 "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 156900161856Syc148097 portn, pll_sts_l.value, cfg.value)); 157000161856Syc148097 #endif 157100161856Syc148097 } else if (nxgep->mac.portmode == PORT_1G_FIBER || 157200161856Syc148097 nxgep->mac.portmode == PORT_1G_TN1010 || 157300161856Syc148097 nxgep->mac.portmode == PORT_1G_SERDES) { 15746f45ec7bSml29623 /* 0x0E21 */ 15756f45ec7bSml29623 tx_cfg_l.bits.entx = 1; 15766f45ec7bSml29623 tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 15776f45ec7bSml29623 tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 15786f45ec7bSml29623 15796f45ec7bSml29623 /* 0x9121 */ 15806f45ec7bSml29623 rx_cfg_l.bits.enrx = 1; 15816f45ec7bSml29623 rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 15826f45ec7bSml29623 rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 15836f45ec7bSml29623 rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 15846f45ec7bSml29623 rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 15856f45ec7bSml29623 15862e59129aSraghus if (portn == 0) { 15876f45ec7bSml29623 /* 0x8 */ 15886f45ec7bSml29623 rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 15892e59129aSraghus } 15906f45ec7bSml29623 159100161856Syc148097 /* Initialize PLL for 1G */ 15926f45ec7bSml29623 pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 15936f45ec7bSml29623 pll_cfg_l.bits.enpll = 1; 15942e59129aSraghus pll_sts_l.bits.enpll = 1; 15956f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 159652ccf843Smisaki ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 15976f45ec7bSml29623 goto fail; 15982e59129aSraghus 15992e59129aSraghus if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 16002e59129aSraghus ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK) 16012e59129aSraghus goto fail; 16022e59129aSraghus 16032e59129aSraghus #ifdef NXGE_DEBUG 16042e59129aSraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 16052e59129aSraghus ESR_N2_PLL_CFG_L_REG, &cfg.value); 16062e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16072e59129aSraghus "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 16082e59129aSraghus portn, pll_cfg_l.value, cfg.value)); 16092e59129aSraghus 16102e59129aSraghus nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 16112e59129aSraghus ESR_N2_PLL_STS_L_REG, &cfg.value); 16122e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16132e59129aSraghus "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)", 16142e59129aSraghus portn, pll_sts_l.value, cfg.value)); 16152e59129aSraghus #endif 16162e59129aSraghus 16172e59129aSraghus /* Set loopback mode if necessary */ 16182e59129aSraghus if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 16192e59129aSraghus tx_cfg_l.bits.entest = 1; 16202e59129aSraghus rx_cfg_l.bits.entest = 1; 16212e59129aSraghus test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 16222e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16232e59129aSraghus "==> nxge_n2_serdes_init port<%d>: loopback 0x%x", 16242e59129aSraghus portn, test_cfg.value)); 16252e59129aSraghus if ((status = nxge_mdio_write(nxgep, portn, 16262e59129aSraghus ESR_N2_DEV_ADDR, 16272e59129aSraghus ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) { 16282e59129aSraghus goto fail; 16292e59129aSraghus } 16302e59129aSraghus } 16316f45ec7bSml29623 } else { 16326f45ec7bSml29623 goto fail; 16336f45ec7bSml29623 } 16346f45ec7bSml29623 16356f45ec7bSml29623 /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 16366f45ec7bSml29623 16376f45ec7bSml29623 NXGE_DELAY(20); 16386f45ec7bSml29623 16396f45ec7bSml29623 /* init TX channels */ 16406f45ec7bSml29623 for (chan = 0; chan < 4; chan++) { 16416f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 164252ccf843Smisaki ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK) 16436f45ec7bSml29623 goto fail; 16446f45ec7bSml29623 16456f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 164652ccf843Smisaki ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK) 16476f45ec7bSml29623 goto fail; 16482e59129aSraghus 16492e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16502e59129aSraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x", 16512e59129aSraghus portn, chan, tx_cfg_l.value)); 16522e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16532e59129aSraghus "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x", 16542e59129aSraghus portn, chan, tx_cfg_h.value)); 16556f45ec7bSml29623 } 16566f45ec7bSml29623 16576f45ec7bSml29623 /* init RX channels */ 16586f45ec7bSml29623 for (chan = 0; chan < 4; chan++) { 16596f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 166052ccf843Smisaki ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK) 16616f45ec7bSml29623 goto fail; 16626f45ec7bSml29623 16636f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 166452ccf843Smisaki ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK) 16656f45ec7bSml29623 goto fail; 16662e59129aSraghus 16672e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16682e59129aSraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x", 16692e59129aSraghus portn, chan, rx_cfg_l.value)); 167000161856Syc148097 16712e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 16722e59129aSraghus "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x", 16732e59129aSraghus portn, chan, rx_cfg_h.value)); 16746f45ec7bSml29623 } 16756f45ec7bSml29623 16766f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 16776f45ec7bSml29623 portn)); 16786f45ec7bSml29623 16796f45ec7bSml29623 return (NXGE_OK); 16806f45ec7bSml29623 fail: 16812d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16826f45ec7bSml29623 "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 16836f45ec7bSml29623 portn)); 16846f45ec7bSml29623 16856f45ec7bSml29623 return (status); 16864df55fdeSJanie Lu 16874df55fdeSJanie Lu } 16884df55fdeSJanie Lu 16894df55fdeSJanie Lu /* Initialize the TI Hedwig Internal Serdes (N2-KT-NIU only) */ 16904df55fdeSJanie Lu 16914df55fdeSJanie Lu static nxge_status_t 16924df55fdeSJanie Lu nxge_n2_kt_serdes_init(p_nxge_t nxgep) 16934df55fdeSJanie Lu { 16944df55fdeSJanie Lu uint8_t portn; 169589282175SSantwona Behera int chan, i; 16964df55fdeSJanie Lu k_esr_ti_cfgpll_l_t pll_cfg_l; 16974df55fdeSJanie Lu k_esr_ti_cfgrx_l_t rx_cfg_l; 16984df55fdeSJanie Lu k_esr_ti_cfgrx_h_t rx_cfg_h; 16994df55fdeSJanie Lu k_esr_ti_cfgtx_l_t tx_cfg_l; 17004df55fdeSJanie Lu k_esr_ti_cfgtx_h_t tx_cfg_h; 17014df55fdeSJanie Lu #ifdef NXGE_DEBUG 17024df55fdeSJanie Lu k_esr_ti_testcfg_t cfg; 17034df55fdeSJanie Lu #endif 17044df55fdeSJanie Lu k_esr_ti_testcfg_t test_cfg; 17054df55fdeSJanie Lu nxge_status_t status = NXGE_OK; 17064df55fdeSJanie Lu boolean_t mode_1g = B_FALSE; 170789282175SSantwona Behera uint64_t val; 170889282175SSantwona Behera npi_handle_t handle; 17094df55fdeSJanie Lu 17104df55fdeSJanie Lu portn = nxgep->mac.portnum; 17114df55fdeSJanie Lu 17124df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 17134df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>", portn)); 171489282175SSantwona Behera handle = nxgep->npi_handle; 17154df55fdeSJanie Lu 17164df55fdeSJanie Lu tx_cfg_l.value = 0; 17174df55fdeSJanie Lu tx_cfg_h.value = 0; 17184df55fdeSJanie Lu rx_cfg_l.value = 0; 17194df55fdeSJanie Lu rx_cfg_h.value = 0; 17204df55fdeSJanie Lu pll_cfg_l.value = 0; 17214df55fdeSJanie Lu test_cfg.value = 0; 17224df55fdeSJanie Lu 17234df55fdeSJanie Lu /* 17244df55fdeSJanie Lu * The following setting assumes the reference clock frquency 17254df55fdeSJanie Lu * is 156.25 MHz. 17264df55fdeSJanie Lu */ 17274df55fdeSJanie Lu /* 17284df55fdeSJanie Lu * If the nxge driver has been plumbed without a link, then it will 17294df55fdeSJanie Lu * detect a link up when a cable connecting to an anto-negotiation 17304df55fdeSJanie Lu * partner is plugged into the port. Because the TN1010 PHY supports 17314df55fdeSJanie Lu * both 1G and 10G speeds, the driver must re-configure the 17324df55fdeSJanie Lu * Neptune/NIU according to the negotiated speed. nxge_n2_serdes_init 17334df55fdeSJanie Lu * is called at the post-link-up reconfiguration time. Here it calls 17344df55fdeSJanie Lu * nxge_set_tn1010_param to set portmode before re-initializing 17354df55fdeSJanie Lu * the serdes. 17364df55fdeSJanie Lu */ 17374df55fdeSJanie Lu if (nxgep->mac.portmode == PORT_1G_TN1010 || 17384df55fdeSJanie Lu nxgep->mac.portmode == PORT_10G_TN1010) { 17394df55fdeSJanie Lu if (nxge_set_tn1010_param(nxgep) != NXGE_OK) { 17404df55fdeSJanie Lu goto fail; 17414df55fdeSJanie Lu } 17424df55fdeSJanie Lu } 17434df55fdeSJanie Lu if (nxgep->mac.portmode == PORT_10G_FIBER || 174489282175SSantwona Behera nxgep->mac.portmode == PORT_10G_COPPER || 17454df55fdeSJanie Lu nxgep->mac.portmode == PORT_10G_TN1010 || 17464df55fdeSJanie Lu nxgep->mac.portmode == PORT_10G_SERDES) { 1747*9d587972SSantwona Behera 1748*9d587972SSantwona Behera /* Take tunables from OBP if present, otherwise use defaults */ 1749*9d587972SSantwona Behera if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGL) { 1750*9d587972SSantwona Behera tx_cfg_l.value = nxgep->srds_prop.tx_cfg_l; 1751*9d587972SSantwona Behera } else { 17524df55fdeSJanie Lu tx_cfg_l.bits.entx = K_CFGTX_ENABLE_TX; 17534df55fdeSJanie Lu /* 0x1e21 */ 17544df55fdeSJanie Lu tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV; 17554df55fdeSJanie Lu tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF; 1756*9d587972SSantwona Behera } 17574df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 17584df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x", 17594df55fdeSJanie Lu portn, tx_cfg_l.value)); 17604df55fdeSJanie Lu 1761*9d587972SSantwona Behera if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGH) { 1762*9d587972SSantwona Behera tx_cfg_h.value = nxgep->srds_prop.tx_cfg_h; 1763*9d587972SSantwona Behera } else { 17644df55fdeSJanie Lu /* channel 0: enable syn. master */ 17654df55fdeSJanie Lu /* 0x40 */ 17664df55fdeSJanie Lu tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC; 1767*9d587972SSantwona Behera } 17684df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 17694df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x", 17704df55fdeSJanie Lu portn, tx_cfg_h.value)); 1771*9d587972SSantwona Behera 1772*9d587972SSantwona Behera if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGL) { 1773*9d587972SSantwona Behera rx_cfg_l.value = nxgep->srds_prop.rx_cfg_l; 1774*9d587972SSantwona Behera } else { 17754df55fdeSJanie Lu /* 0x4821 */ 17764df55fdeSJanie Lu rx_cfg_l.bits.enrx = K_CFGRX_ENABLE_RX; 17774df55fdeSJanie Lu rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF; 17784df55fdeSJanie Lu rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN; 17794df55fdeSJanie Lu rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE; 1780*9d587972SSantwona Behera } 17814df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 17824df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x", 17834df55fdeSJanie Lu portn, rx_cfg_l.value)); 17844df55fdeSJanie Lu 1785*9d587972SSantwona Behera if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGH) { 1786*9d587972SSantwona Behera rx_cfg_h.value = nxgep->srds_prop.rx_cfg_h; 1787*9d587972SSantwona Behera } else { 17884df55fdeSJanie Lu /* 0x0008 */ 17894df55fdeSJanie Lu rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE; 1790*9d587972SSantwona Behera } 17914df55fdeSJanie Lu 17924df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 17934df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_h 0x%x", 17944df55fdeSJanie Lu portn, rx_cfg_h.value)); 17954df55fdeSJanie Lu 1796*9d587972SSantwona Behera if (nxgep->srds_prop.prop_set & NXGE_SRDS_PLLCFGL) { 1797*9d587972SSantwona Behera pll_cfg_l.value = nxgep->srds_prop.pll_cfg_l; 1798*9d587972SSantwona Behera } else { 17994df55fdeSJanie Lu /* 0xa1: Initialize PLL for 10G */ 18004df55fdeSJanie Lu pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X; 18014df55fdeSJanie Lu pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL; 1802*9d587972SSantwona Behera } 18034df55fdeSJanie Lu 18044df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18054df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x", 18064df55fdeSJanie Lu portn, pll_cfg_l.value)); 18074df55fdeSJanie Lu 18084df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 18094df55fdeSJanie Lu ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK) 18104df55fdeSJanie Lu goto fail; 18114df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18124df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x", 18134df55fdeSJanie Lu portn, pll_cfg_l.value)); 1814*9d587972SSantwona Behera 1815*9d587972SSantwona Behera /* Set loopback mode if necessary */ 1816*9d587972SSantwona Behera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 1817*9d587972SSantwona Behera tx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK; 1818*9d587972SSantwona Behera rx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK; 1819*9d587972SSantwona Behera rx_cfg_l.bits.los = 0; 1820*9d587972SSantwona Behera 1821*9d587972SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1822*9d587972SSantwona Behera "==> nxge_n2_kt_serdes_init port<%d>: " 1823*9d587972SSantwona Behera "loopback 0x%x", portn, tx_cfg_h.value)); 1824*9d587972SSantwona Behera } 18254df55fdeSJanie Lu #ifdef NXGE_DEBUG 18264df55fdeSJanie Lu nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 18274df55fdeSJanie Lu ESR_N2_PLL_CFG_L_REG, &cfg.value); 18284df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18294df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: " 18304df55fdeSJanie Lu "PLL cfg.l 0x%x (0x%x)", 18314df55fdeSJanie Lu portn, pll_cfg_l.value, cfg.value)); 18324df55fdeSJanie Lu 18334df55fdeSJanie Lu nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 18344df55fdeSJanie Lu ESR_N2_PLL_STS_L_REG, &cfg.value); 18354df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18364df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)", 18374df55fdeSJanie Lu portn, cfg.value)); 18384df55fdeSJanie Lu #endif 18394df55fdeSJanie Lu } else if (nxgep->mac.portmode == PORT_1G_FIBER || 18404df55fdeSJanie Lu nxgep->mac.portmode == PORT_1G_TN1010 || 18414df55fdeSJanie Lu nxgep->mac.portmode == PORT_1G_SERDES) { 18424df55fdeSJanie Lu mode_1g = B_TRUE; 18434df55fdeSJanie Lu /* 0x1e41 */ 18444df55fdeSJanie Lu tx_cfg_l.bits.entx = 1; 18454df55fdeSJanie Lu tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF; 18464df55fdeSJanie Lu tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV; 18474df55fdeSJanie Lu 18484df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18494df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x", 18504df55fdeSJanie Lu portn, tx_cfg_l.value)); 18514df55fdeSJanie Lu 18524df55fdeSJanie Lu 18534df55fdeSJanie Lu /* channel 0: enable syn. master */ 18544df55fdeSJanie Lu tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC; 18554df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18564df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x", 18574df55fdeSJanie Lu portn, tx_cfg_h.value)); 18584df55fdeSJanie Lu 18594df55fdeSJanie Lu 18604df55fdeSJanie Lu /* 0x4841 */ 18614df55fdeSJanie Lu rx_cfg_l.bits.enrx = 1; 18624df55fdeSJanie Lu rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF; 18634df55fdeSJanie Lu rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN; 18644df55fdeSJanie Lu rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE; 18654df55fdeSJanie Lu 18664df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18674df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x", 18684df55fdeSJanie Lu portn, rx_cfg_l.value)); 18694df55fdeSJanie Lu 18704df55fdeSJanie Lu /* 0x0008 */ 18714df55fdeSJanie Lu rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE_LF_365MHZ_ZF; 18724df55fdeSJanie Lu 18734df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18744df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x", 18754df55fdeSJanie Lu portn, rx_cfg_h.value)); 18764df55fdeSJanie Lu 18774df55fdeSJanie Lu /* 0xa1: Initialize PLL for 1G */ 18784df55fdeSJanie Lu pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X; 18794df55fdeSJanie Lu pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL; 18804df55fdeSJanie Lu 18814df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 18824df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x", 18834df55fdeSJanie Lu portn, pll_cfg_l.value)); 18844df55fdeSJanie Lu 18854df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 18864df55fdeSJanie Lu ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) 18874df55fdeSJanie Lu != NXGE_OK) 18884df55fdeSJanie Lu goto fail; 18894df55fdeSJanie Lu 18904df55fdeSJanie Lu 18914df55fdeSJanie Lu #ifdef NXGE_DEBUG 18924df55fdeSJanie Lu nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 18934df55fdeSJanie Lu ESR_N2_PLL_CFG_L_REG, &cfg.value); 18944df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18954df55fdeSJanie Lu "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)", 18964df55fdeSJanie Lu portn, pll_cfg_l.value, cfg.value)); 18974df55fdeSJanie Lu 18984df55fdeSJanie Lu nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR, 18994df55fdeSJanie Lu ESR_N2_PLL_STS_L_REG, &cfg.value); 19004df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19014df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)", 19024df55fdeSJanie Lu portn, cfg.value)); 19034df55fdeSJanie Lu #endif 19044df55fdeSJanie Lu 19054df55fdeSJanie Lu /* Set loopback mode if necessary */ 19064df55fdeSJanie Lu if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 19074df55fdeSJanie Lu tx_cfg_h.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 19084df55fdeSJanie Lu 19094df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19104df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: " 19114df55fdeSJanie Lu "loopback 0x%x", portn, test_cfg.value)); 19124df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, 19134df55fdeSJanie Lu ESR_N2_DEV_ADDR, 19144df55fdeSJanie Lu ESR_N2_TX_CFG_L_REG_ADDR(0), 19154df55fdeSJanie Lu tx_cfg_h.value)) != NXGE_OK) { 19164df55fdeSJanie Lu goto fail; 19174df55fdeSJanie Lu } 19184df55fdeSJanie Lu } 19194df55fdeSJanie Lu } else { 19204df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19214df55fdeSJanie Lu "nxge_n2_kt_serdes_init:port<%d> - " 19224df55fdeSJanie Lu "unsupported port mode %d", 19234df55fdeSJanie Lu portn, nxgep->mac.portmode)); 19244df55fdeSJanie Lu goto fail; 19254df55fdeSJanie Lu } 19264df55fdeSJanie Lu 19274df55fdeSJanie Lu NXGE_DELAY(20); 19284df55fdeSJanie Lu /* Clear the test register (offset 0x8004) */ 19294df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 19304df55fdeSJanie Lu ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) { 19314df55fdeSJanie Lu goto fail; 19324df55fdeSJanie Lu } 19334df55fdeSJanie Lu NXGE_DELAY(20); 19344df55fdeSJanie Lu 19354df55fdeSJanie Lu /* init TX channels */ 19364df55fdeSJanie Lu for (chan = 0; chan < 4; chan++) { 19374df55fdeSJanie Lu if (mode_1g) 19384df55fdeSJanie Lu tx_cfg_l.value = 0; 19394df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 19404df55fdeSJanie Lu ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK) 19414df55fdeSJanie Lu goto fail; 19424df55fdeSJanie Lu 19434df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 19444df55fdeSJanie Lu ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK) 19454df55fdeSJanie Lu goto fail; 19464df55fdeSJanie Lu 19474df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19484df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: " 19494df55fdeSJanie Lu "chan %d tx_cfg_l 0x%x", portn, chan, tx_cfg_l.value)); 19504df55fdeSJanie Lu 19514df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19524df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: " 19534df55fdeSJanie Lu "chan %d tx_cfg_h 0x%x", portn, chan, tx_cfg_h.value)); 19544df55fdeSJanie Lu } 19554df55fdeSJanie Lu 19564df55fdeSJanie Lu /* init RX channels */ 19574df55fdeSJanie Lu /* 1G mode only write to the first channel */ 19584df55fdeSJanie Lu for (chan = 0; chan < 4; chan++) { 19594df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 19604df55fdeSJanie Lu ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) 19614df55fdeSJanie Lu != NXGE_OK) 19624df55fdeSJanie Lu goto fail; 19634df55fdeSJanie Lu 19644df55fdeSJanie Lu if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 19654df55fdeSJanie Lu ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) 19664df55fdeSJanie Lu != NXGE_OK) 19674df55fdeSJanie Lu goto fail; 19684df55fdeSJanie Lu 19694df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19704df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: " 19714df55fdeSJanie Lu "chan %d rx_cfg_l 0x%x", portn, chan, rx_cfg_l.value)); 19724df55fdeSJanie Lu 19734df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 19744df55fdeSJanie Lu "==> nxge_n2_kt_serdes_init port<%d>: " 19754df55fdeSJanie Lu "chan %d rx_cfg_h 0x%x", portn, chan, rx_cfg_h.value)); 19764df55fdeSJanie Lu } 19774df55fdeSJanie Lu 197889282175SSantwona Behera if (portn == 0) { 197989282175SSantwona Behera /* Wait for serdes to be ready */ 198089282175SSantwona Behera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 198189282175SSantwona Behera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 198289282175SSantwona Behera if ((val & ESR_SIG_P0_BITS_MASK) != 198389282175SSantwona Behera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 198489282175SSantwona Behera ESR_SIG_XSERDES_RDY_P0 | 198589282175SSantwona Behera ESR_SIG_XDETECT_P0_CH3 | 198689282175SSantwona Behera ESR_SIG_XDETECT_P0_CH2 | 198789282175SSantwona Behera ESR_SIG_XDETECT_P0_CH1 | 198889282175SSantwona Behera ESR_SIG_XDETECT_P0_CH0)) 198989282175SSantwona Behera 199089282175SSantwona Behera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 199189282175SSantwona Behera else 199289282175SSantwona Behera break; 199389282175SSantwona Behera } 199489282175SSantwona Behera 199589282175SSantwona Behera if (i == MAX_SERDES_RDY_RETRIES) { 199689282175SSantwona Behera /* 199789282175SSantwona Behera * RDY signal stays low may due to the absent of the 199889282175SSantwona Behera * external PHY, it is not an error condition. 199989282175SSantwona Behera * But still print the message for the debugging 200089282175SSantwona Behera * purpose when link stays down 200189282175SSantwona Behera */ 200289282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 200389282175SSantwona Behera "nxge_n2_kt_serdes_init: " 200489282175SSantwona Behera "Serdes/signal for port<%d> not ready", portn)); 200589282175SSantwona Behera goto done; 200689282175SSantwona Behera } 200789282175SSantwona Behera } else if (portn == 1) { 200889282175SSantwona Behera /* Wait for serdes to be ready */ 200989282175SSantwona Behera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 201089282175SSantwona Behera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 201189282175SSantwona Behera if ((val & ESR_SIG_P1_BITS_MASK) != 201289282175SSantwona Behera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 201389282175SSantwona Behera ESR_SIG_XSERDES_RDY_P1 | 201489282175SSantwona Behera ESR_SIG_XDETECT_P1_CH3 | 201589282175SSantwona Behera ESR_SIG_XDETECT_P1_CH2 | 201689282175SSantwona Behera ESR_SIG_XDETECT_P1_CH1 | 201789282175SSantwona Behera ESR_SIG_XDETECT_P1_CH0)) 201889282175SSantwona Behera 201989282175SSantwona Behera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 202089282175SSantwona Behera else 202189282175SSantwona Behera break; 202289282175SSantwona Behera } 202389282175SSantwona Behera 202489282175SSantwona Behera if (i == MAX_SERDES_RDY_RETRIES) { 202589282175SSantwona Behera /* 202689282175SSantwona Behera * RDY signal stays low may due to the absent of the 202789282175SSantwona Behera * external PHY, it is not an error condition. 202889282175SSantwona Behera * But still print the message for the debugging 202989282175SSantwona Behera * purpose when link stays down 203089282175SSantwona Behera */ 203189282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 203289282175SSantwona Behera "nxge_n2_kt_serdes_init: " 203389282175SSantwona Behera "Serdes/signal for port<%d> not ready", portn)); 203489282175SSantwona Behera goto done; 203589282175SSantwona Behera } 203689282175SSantwona Behera } 203789282175SSantwona Behera done: 203889282175SSantwona Behera 20394df55fdeSJanie Lu NXGE_DEBUG_MSG((nxgep, MAC_CTL, 20404df55fdeSJanie Lu "<== nxge_n2_kt_serdes_init port<%d>", portn)); 20414df55fdeSJanie Lu 20424df55fdeSJanie Lu return (NXGE_OK); 20434df55fdeSJanie Lu fail: 20444df55fdeSJanie Lu NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 20454df55fdeSJanie Lu "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 20464df55fdeSJanie Lu portn)); 20474df55fdeSJanie Lu 20484df55fdeSJanie Lu return (status); 20496f45ec7bSml29623 } 20506f45ec7bSml29623 205159ac0c16Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */ 20526f45ec7bSml29623 205359ac0c16Sdavemq static nxge_status_t 205459ac0c16Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep) 20556f45ec7bSml29623 { 20566f45ec7bSml29623 npi_handle_t handle; 20576f45ec7bSml29623 uint8_t portn; 2058321febdeSsbehera int chan, i; 20596f45ec7bSml29623 sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 20606f45ec7bSml29623 sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 20616f45ec7bSml29623 sr_glue_ctrl0_l_t glue_ctrl0_l; 20626f45ec7bSml29623 sr_glue_ctrl0_h_t glue_ctrl0_h; 20636f45ec7bSml29623 uint64_t val; 20646f45ec7bSml29623 uint16_t val16l; 20656f45ec7bSml29623 uint16_t val16h; 20666f45ec7bSml29623 nxge_status_t status = NXGE_OK; 20676f45ec7bSml29623 20686f45ec7bSml29623 portn = nxgep->mac.portnum; 20696f45ec7bSml29623 20706f45ec7bSml29623 if ((portn != 0) && (portn != 1)) 20716f45ec7bSml29623 return (NXGE_OK); 20726f45ec7bSml29623 207359ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 207459ac0c16Sdavemq "==> nxge_neptune_10G_serdes_init port<%d>", portn)); 20756f45ec7bSml29623 handle = nxgep->npi_handle; 20766f45ec7bSml29623 switch (portn) { 20776f45ec7bSml29623 case 0: 20784202ea4bSsbehera /* Reset Serdes */ 20794202ea4bSsbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0); 20804202ea4bSsbehera NXGE_DELAY(20); 20814202ea4bSsbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0); 20824202ea4bSsbehera NXGE_DELAY(2000); 20834202ea4bSsbehera 20844202ea4bSsbehera /* Configure Serdes to 10G mode */ 20854202ea4bSsbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 20864202ea4bSsbehera ESR_PLL_CFG_10G_SERDES); 20874202ea4bSsbehera 20886f45ec7bSml29623 ESR_REG_WR(handle, ESR_0_CONTROL_REG, 20896f45ec7bSml29623 ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 20906f45ec7bSml29623 ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 20916f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 20926f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 20936f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 20946f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 20956f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 20966f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 20976f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 20986f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 20996f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 21006f45ec7bSml29623 21016f45ec7bSml29623 /* Set Serdes0 Internal Loopback if necessary */ 210259ac0c16Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 21036f45ec7bSml29623 ESR_REG_WR(handle, 21046f45ec7bSml29623 ESR_0_TEST_CONFIG_REG, 21056f45ec7bSml29623 ESR_PAD_LOOPBACK_CH3 | 21066f45ec7bSml29623 ESR_PAD_LOOPBACK_CH2 | 21076f45ec7bSml29623 ESR_PAD_LOOPBACK_CH1 | 21086f45ec7bSml29623 ESR_PAD_LOOPBACK_CH0); 21096f45ec7bSml29623 } else { 211059ac0c16Sdavemq ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 21116f45ec7bSml29623 } 21126f45ec7bSml29623 break; 21136f45ec7bSml29623 case 1: 21144202ea4bSsbehera /* Reset Serdes */ 21154202ea4bSsbehera ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1); 21164202ea4bSsbehera NXGE_DELAY(20); 21174202ea4bSsbehera ESR_REG_WR(handle, ESR_RESET_REG, 0x0); 21184202ea4bSsbehera NXGE_DELAY(2000); 21194202ea4bSsbehera 21204202ea4bSsbehera /* Configure Serdes to 10G mode */ 21214202ea4bSsbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 21224202ea4bSsbehera ESR_PLL_CFG_10G_SERDES); 21234202ea4bSsbehera 21246f45ec7bSml29623 ESR_REG_WR(handle, ESR_1_CONTROL_REG, 21256f45ec7bSml29623 ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 21266f45ec7bSml29623 ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 21276f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 21286f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 21296f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 21306f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 21316f45ec7bSml29623 (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 21326f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 21336f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 21346f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 21356f45ec7bSml29623 (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 21366f45ec7bSml29623 21376f45ec7bSml29623 /* Set Serdes1 Internal Loopback if necessary */ 213859ac0c16Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 213959ac0c16Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 214059ac0c16Sdavemq ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 | 214159ac0c16Sdavemq ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0); 21426f45ec7bSml29623 } else { 214359ac0c16Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 21446f45ec7bSml29623 } 21456f45ec7bSml29623 break; 21466f45ec7bSml29623 default: 21476f45ec7bSml29623 /* Nothing to do here */ 21486f45ec7bSml29623 goto done; 21496f45ec7bSml29623 } 21506f45ec7bSml29623 21516f45ec7bSml29623 /* init TX RX channels */ 21526f45ec7bSml29623 for (chan = 0; chan < 4; chan++) { 21536f45ec7bSml29623 if ((status = nxge_mdio_read(nxgep, portn, 215459ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 21556f45ec7bSml29623 &rx_tx_ctrl_l.value)) != NXGE_OK) 21566f45ec7bSml29623 goto fail; 21576f45ec7bSml29623 if ((status = nxge_mdio_read(nxgep, portn, 215859ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 21596f45ec7bSml29623 &rx_tx_ctrl_h.value)) != NXGE_OK) 21606f45ec7bSml29623 goto fail; 21616f45ec7bSml29623 if ((status = nxge_mdio_read(nxgep, portn, 216259ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 21636f45ec7bSml29623 &glue_ctrl0_l.value)) != NXGE_OK) 21646f45ec7bSml29623 goto fail; 21656f45ec7bSml29623 if ((status = nxge_mdio_read(nxgep, portn, 216659ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 21676f45ec7bSml29623 &glue_ctrl0_h.value)) != NXGE_OK) 21686f45ec7bSml29623 goto fail; 21696f45ec7bSml29623 rx_tx_ctrl_l.bits.enstretch = 1; 21706f45ec7bSml29623 rx_tx_ctrl_h.bits.vmuxlo = 2; 21716f45ec7bSml29623 rx_tx_ctrl_h.bits.vpulselo = 2; 21726f45ec7bSml29623 glue_ctrl0_l.bits.rxlosenable = 1; 21736f45ec7bSml29623 glue_ctrl0_l.bits.samplerate = 0xF; 21746f45ec7bSml29623 glue_ctrl0_l.bits.thresholdcount = 0xFF; 21756f45ec7bSml29623 glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 21766f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, 217759ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 21786f45ec7bSml29623 rx_tx_ctrl_l.value)) != NXGE_OK) 21796f45ec7bSml29623 goto fail; 21806f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, 218159ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 21826f45ec7bSml29623 rx_tx_ctrl_h.value)) != NXGE_OK) 21836f45ec7bSml29623 goto fail; 21846f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, 218559ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 21866f45ec7bSml29623 glue_ctrl0_l.value)) != NXGE_OK) 21876f45ec7bSml29623 goto fail; 21886f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, 218959ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 21906f45ec7bSml29623 glue_ctrl0_h.value)) != NXGE_OK) 21916f45ec7bSml29623 goto fail; 21926f45ec7bSml29623 } 21936f45ec7bSml29623 21946f45ec7bSml29623 /* Apply Tx core reset */ 21956f45ec7bSml29623 if ((status = nxge_mdio_write(nxgep, portn, 219659ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 21976f45ec7bSml29623 (uint16_t)0)) != NXGE_OK) 21986f45ec7bSml29623 goto fail; 21996f45ec7bSml29623 220059ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 220159ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 220259ac0c16Sdavemq NXGE_OK) 22036f45ec7bSml29623 goto fail; 22046f45ec7bSml29623 22056f45ec7bSml29623 NXGE_DELAY(200); 22066f45ec7bSml29623 22076f45ec7bSml29623 /* Apply Rx core reset */ 220859ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 220959ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 221059ac0c16Sdavemq NXGE_OK) 22116f45ec7bSml29623 goto fail; 22126f45ec7bSml29623 22136f45ec7bSml29623 NXGE_DELAY(200); 221459ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 221559ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) 22166f45ec7bSml29623 goto fail; 22176f45ec7bSml29623 22186f45ec7bSml29623 NXGE_DELAY(200); 22196f45ec7bSml29623 if ((status = nxge_mdio_read(nxgep, portn, 222059ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 22216f45ec7bSml29623 &val16l)) != NXGE_OK) 22226f45ec7bSml29623 goto fail; 222359ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 222459ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) 22256f45ec7bSml29623 goto fail; 22266f45ec7bSml29623 if ((val16l != 0) || (val16h != 0)) { 22276f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2228d81011f0Ssbehera "Failed to reset port<%d> XAUI Serdes " 2229d81011f0Ssbehera "(val16l 0x%x val16h 0x%x)", 2230d81011f0Ssbehera portn, val16l, val16h)); 22316f45ec7bSml29623 } 22326f45ec7bSml29623 22336f45ec7bSml29623 if (portn == 0) { 2234321febdeSsbehera /* Wait for serdes to be ready */ 2235321febdeSsbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 2236321febdeSsbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 22376f45ec7bSml29623 if ((val & ESR_SIG_P0_BITS_MASK) != 22386f45ec7bSml29623 (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 22396f45ec7bSml29623 ESR_SIG_XSERDES_RDY_P0 | 22406f45ec7bSml29623 ESR_SIG_XDETECT_P0_CH3 | 22416f45ec7bSml29623 ESR_SIG_XDETECT_P0_CH2 | 22426f45ec7bSml29623 ESR_SIG_XDETECT_P0_CH1 | 2243321febdeSsbehera ESR_SIG_XDETECT_P0_CH0)) 2244321febdeSsbehera 2245321febdeSsbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 2246321febdeSsbehera else 2247321febdeSsbehera break; 2248321febdeSsbehera } 2249321febdeSsbehera 2250321febdeSsbehera if (i == MAX_SERDES_RDY_RETRIES) { 2251ab6abb7aSjoycey /* 2252ab6abb7aSjoycey * RDY signal stays low may due to the absent of the 2253ab6abb7aSjoycey * external PHY, it is not an error condition. But still 2254ab6abb7aSjoycey * print the message for the debugging purpose when link 2255ab6abb7aSjoycey * stays down 2256ab6abb7aSjoycey */ 2257774da109Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2258321febdeSsbehera "nxge_neptune_10G_serdes_init: " 2259321febdeSsbehera "Serdes/signal for port<%d> not ready", portn)); 2260ab6abb7aSjoycey goto done; 22616f45ec7bSml29623 } 22626f45ec7bSml29623 } else if (portn == 1) { 2263321febdeSsbehera /* Wait for serdes to be ready */ 2264321febdeSsbehera for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) { 2265321febdeSsbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 22666f45ec7bSml29623 if ((val & ESR_SIG_P1_BITS_MASK) != 22676f45ec7bSml29623 (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 22686f45ec7bSml29623 ESR_SIG_XSERDES_RDY_P1 | 22696f45ec7bSml29623 ESR_SIG_XDETECT_P1_CH3 | 22706f45ec7bSml29623 ESR_SIG_XDETECT_P1_CH2 | 22716f45ec7bSml29623 ESR_SIG_XDETECT_P1_CH1 | 2272321febdeSsbehera ESR_SIG_XDETECT_P1_CH0)) 2273321febdeSsbehera 2274321febdeSsbehera NXGE_DELAY(SERDES_RDY_WT_INTERVAL); 2275321febdeSsbehera else 2276321febdeSsbehera break; 2277321febdeSsbehera } 2278321febdeSsbehera 2279321febdeSsbehera if (i == MAX_SERDES_RDY_RETRIES) { 2280ab6abb7aSjoycey /* 2281ab6abb7aSjoycey * RDY signal stays low may due to the absent of the 2282ab6abb7aSjoycey * external PHY, it is not an error condition. But still 2283ab6abb7aSjoycey * print the message for the debugging purpose when link 2284ab6abb7aSjoycey * stays down 2285ab6abb7aSjoycey */ 2286774da109Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2287321febdeSsbehera "nxge_neptune_10G_serdes_init: " 2288321febdeSsbehera "Serdes/signal for port<%d> not ready", portn)); 2289ab6abb7aSjoycey goto done; 22906f45ec7bSml29623 } 22916f45ec7bSml29623 } 22926f45ec7bSml29623 229359ac0c16Sdavemq done: 229459ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 229559ac0c16Sdavemq "<== nxge_neptune_10G_serdes_init port<%d>", portn)); 229659ac0c16Sdavemq 229759ac0c16Sdavemq return (NXGE_OK); 229859ac0c16Sdavemq fail: 22992d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 230059ac0c16Sdavemq "nxge_neptune_10G_serdes_init: " 230159ac0c16Sdavemq "Failed to initialize Neptune serdes for port<%d>", portn)); 230259ac0c16Sdavemq 230359ac0c16Sdavemq return (status); 230459ac0c16Sdavemq } 230559ac0c16Sdavemq 230659ac0c16Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */ 230759ac0c16Sdavemq 230859ac0c16Sdavemq static nxge_status_t 230959ac0c16Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep) 231059ac0c16Sdavemq { 231159ac0c16Sdavemq npi_handle_t handle; 231259ac0c16Sdavemq uint8_t portn; 2313d81011f0Ssbehera int chan; 2314d81011f0Ssbehera sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 2315d81011f0Ssbehera sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 2316d81011f0Ssbehera sr_glue_ctrl0_l_t glue_ctrl0_l; 2317d81011f0Ssbehera sr_glue_ctrl0_h_t glue_ctrl0_h; 231859ac0c16Sdavemq uint64_t val; 2319d81011f0Ssbehera uint16_t val16l; 2320d81011f0Ssbehera uint16_t val16h; 2321d81011f0Ssbehera nxge_status_t status = NXGE_OK; 232259ac0c16Sdavemq 232359ac0c16Sdavemq portn = nxgep->mac.portnum; 232459ac0c16Sdavemq 232559ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 232659ac0c16Sdavemq "==> nxge_1G_serdes_init port<%d>", portn)); 232759ac0c16Sdavemq 232859ac0c16Sdavemq handle = nxgep->npi_handle; 232959ac0c16Sdavemq 23306f45ec7bSml29623 switch (portn) { 23316f45ec7bSml29623 case 0: 2332d81011f0Ssbehera /* Assert the reset register */ 2333d81011f0Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 2334d81011f0Ssbehera val |= ESR_RESET_0; 2335d81011f0Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 2336d81011f0Ssbehera 2337d81011f0Ssbehera /* Set the PLL register to 0x79 */ 2338d81011f0Ssbehera ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG, 2339d81011f0Ssbehera ESR_PLL_CFG_1G_SERDES); 2340d81011f0Ssbehera 2341d81011f0Ssbehera /* Set the control register to 0x249249f */ 2342d81011f0Ssbehera ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES); 2343d81011f0Ssbehera 2344d81011f0Ssbehera /* Set Serdes0 Internal Loopback if necessary */ 2345d81011f0Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 2346d81011f0Ssbehera /* Set pad loopback modes 0xaa */ 2347d81011f0Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 2348d81011f0Ssbehera ESR_TSTCFG_LBTEST_PAD); 2349d81011f0Ssbehera } else { 2350d81011f0Ssbehera ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 2351d81011f0Ssbehera } 2352d81011f0Ssbehera 2353d81011f0Ssbehera /* Deassert the reset register */ 2354d81011f0Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 2355d81011f0Ssbehera val &= ~ESR_RESET_0; 2356d81011f0Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 23576f45ec7bSml29623 break; 2358d81011f0Ssbehera 23596f45ec7bSml29623 case 1: 2360d81011f0Ssbehera /* Assert the reset register */ 2361d81011f0Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 2362d81011f0Ssbehera val |= ESR_RESET_1; 2363d81011f0Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 2364d81011f0Ssbehera 2365d81011f0Ssbehera /* Set PLL register to 0x79 */ 2366d81011f0Ssbehera ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, 2367d81011f0Ssbehera ESR_PLL_CFG_1G_SERDES); 2368d81011f0Ssbehera 2369d81011f0Ssbehera /* Set the control register to 0x249249f */ 2370d81011f0Ssbehera ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES); 2371d81011f0Ssbehera 2372d81011f0Ssbehera /* Set Serdes1 Internal Loopback if necessary */ 2373d81011f0Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) { 2374d81011f0Ssbehera /* Set pad loopback mode 0xaa */ 2375d81011f0Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 2376d81011f0Ssbehera ESR_TSTCFG_LBTEST_PAD); 2377d81011f0Ssbehera } else { 2378d81011f0Ssbehera ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 2379d81011f0Ssbehera } 2380d81011f0Ssbehera 2381d81011f0Ssbehera /* Deassert the reset register */ 2382d81011f0Ssbehera ESR_REG_RD(handle, ESR_RESET_REG, &val); 2383d81011f0Ssbehera val &= ~ESR_RESET_1; 2384d81011f0Ssbehera ESR_REG_WR(handle, ESR_RESET_REG, val); 23856f45ec7bSml29623 break; 2386d81011f0Ssbehera 23876f45ec7bSml29623 default: 2388d81011f0Ssbehera /* Nothing to do here */ 2389d81011f0Ssbehera goto done; 2390d81011f0Ssbehera } 2391d81011f0Ssbehera 2392d81011f0Ssbehera /* init TX RX channels */ 2393d81011f0Ssbehera for (chan = 0; chan < 4; chan++) { 2394d81011f0Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 2395d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 2396d81011f0Ssbehera &rx_tx_ctrl_l.value)) != NXGE_OK) { 2397d81011f0Ssbehera goto fail; 2398d81011f0Ssbehera } 2399d81011f0Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 2400d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 2401d81011f0Ssbehera &rx_tx_ctrl_h.value)) != NXGE_OK) { 2402d81011f0Ssbehera goto fail; 2403d81011f0Ssbehera } 2404d81011f0Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 2405d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 2406d81011f0Ssbehera &glue_ctrl0_l.value)) != NXGE_OK) { 2407d81011f0Ssbehera goto fail; 2408d81011f0Ssbehera } 2409d81011f0Ssbehera if ((status = nxge_mdio_read(nxgep, portn, 2410d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 2411d81011f0Ssbehera &glue_ctrl0_h.value)) != NXGE_OK) { 24126f45ec7bSml29623 goto fail; 24136f45ec7bSml29623 } 24146f45ec7bSml29623 2415d81011f0Ssbehera rx_tx_ctrl_l.bits.enstretch = 1; 2416d81011f0Ssbehera rx_tx_ctrl_h.bits.vmuxlo = 2; 2417d81011f0Ssbehera rx_tx_ctrl_h.bits.vpulselo = 2; 2418d81011f0Ssbehera glue_ctrl0_l.bits.rxlosenable = 1; 2419d81011f0Ssbehera glue_ctrl0_l.bits.samplerate = 0xF; 2420d81011f0Ssbehera glue_ctrl0_l.bits.thresholdcount = 0xFF; 2421d81011f0Ssbehera glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 2422d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 2423d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 2424d81011f0Ssbehera rx_tx_ctrl_l.value)) != NXGE_OK) { 2425d81011f0Ssbehera goto fail; 2426d81011f0Ssbehera } 2427d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 2428d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 2429d81011f0Ssbehera rx_tx_ctrl_h.value)) != NXGE_OK) { 2430d81011f0Ssbehera goto fail; 2431d81011f0Ssbehera } 2432d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 2433d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 2434d81011f0Ssbehera glue_ctrl0_l.value)) != NXGE_OK) { 2435d81011f0Ssbehera goto fail; 2436d81011f0Ssbehera } 2437d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, 2438d81011f0Ssbehera ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 2439d81011f0Ssbehera glue_ctrl0_h.value)) != NXGE_OK) { 2440d81011f0Ssbehera goto fail; 2441d81011f0Ssbehera } 2442d81011f0Ssbehera } 2443d81011f0Ssbehera 2444d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2445d81011f0Ssbehera ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) { 2446d81011f0Ssbehera goto fail; 2447d81011f0Ssbehera } 2448d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2449d81011f0Ssbehera ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 2450d81011f0Ssbehera goto fail; 2451d81011f0Ssbehera } 2452d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2453d81011f0Ssbehera ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) { 2454d81011f0Ssbehera goto fail; 2455d81011f0Ssbehera } 2456d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2457d81011f0Ssbehera ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) { 2458d81011f0Ssbehera goto fail; 2459d81011f0Ssbehera } 2460d81011f0Ssbehera 2461d81011f0Ssbehera /* Apply Tx core reset */ 2462d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2463d81011f0Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) { 2464d81011f0Ssbehera goto fail; 2465d81011f0Ssbehera } 2466d81011f0Ssbehera 2467d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2468d81011f0Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 2469d81011f0Ssbehera NXGE_OK) { 2470d81011f0Ssbehera goto fail; 2471d81011f0Ssbehera } 2472d81011f0Ssbehera 2473d81011f0Ssbehera NXGE_DELAY(200); 2474d81011f0Ssbehera 2475d81011f0Ssbehera /* Apply Rx core reset */ 2476d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2477d81011f0Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 2478d81011f0Ssbehera NXGE_OK) { 2479d81011f0Ssbehera goto fail; 2480d81011f0Ssbehera } 2481d81011f0Ssbehera 2482d81011f0Ssbehera NXGE_DELAY(200); 2483d81011f0Ssbehera if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2484d81011f0Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) { 2485d81011f0Ssbehera goto fail; 2486d81011f0Ssbehera } 2487d81011f0Ssbehera 2488d81011f0Ssbehera NXGE_DELAY(200); 2489d81011f0Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2490d81011f0Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) { 2491d81011f0Ssbehera goto fail; 2492d81011f0Ssbehera } 2493d81011f0Ssbehera if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 2494d81011f0Ssbehera ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) { 2495d81011f0Ssbehera goto fail; 2496d81011f0Ssbehera } 2497d81011f0Ssbehera if ((val16l != 0) || (val16h != 0)) { 2498d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2499d81011f0Ssbehera "Failed to reset port<%d> XAUI Serdes " 2500d81011f0Ssbehera "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h)); 2501d81011f0Ssbehera status = NXGE_ERROR; 2502d81011f0Ssbehera goto fail; 2503d81011f0Ssbehera } 2504d81011f0Ssbehera 2505d81011f0Ssbehera NXGE_DELAY(200); 2506d81011f0Ssbehera ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 2507d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2508d81011f0Ssbehera "nxge_neptune_serdes_init: read internal signal reg port<%d> " 2509d81011f0Ssbehera "val 0x%x", portn, val)); 2510d81011f0Ssbehera if (portn == 0) { 2511d81011f0Ssbehera if ((val & ESR_SIG_P0_BITS_MASK_1G) != 2512d81011f0Ssbehera (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) { 2513ab6abb7aSjoycey /* 2514ab6abb7aSjoycey * RDY signal stays low may due to the absent of the 2515ab6abb7aSjoycey * external PHY, it is not an error condition. But still 2516ab6abb7aSjoycey * print the message for the debugging purpose when link 2517ab6abb7aSjoycey * stays down 2518ab6abb7aSjoycey */ 2519d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2520ab6abb7aSjoycey "nxge_neptune_1G_serdes_init: " 2521ab6abb7aSjoycey "Serdes/signal for port<%d> not ready", portn)); 2522ab6abb7aSjoycey goto done; 2523d81011f0Ssbehera } 2524d81011f0Ssbehera } else if (portn == 1) { 2525d81011f0Ssbehera if ((val & ESR_SIG_P1_BITS_MASK_1G) != 2526d81011f0Ssbehera (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) { 2527ab6abb7aSjoycey /* 2528ab6abb7aSjoycey * RDY signal stays low may due to the absent of the 2529ab6abb7aSjoycey * external PHY, it is not an error condition. But still 2530ab6abb7aSjoycey * print the message for the debugging purpose when link 2531ab6abb7aSjoycey * stays down 2532ab6abb7aSjoycey */ 2533d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2534ab6abb7aSjoycey "nxge_neptune_1G_serdes_init: " 2535ab6abb7aSjoycey "Serdes/signal for port<%d> not ready", portn)); 2536ab6abb7aSjoycey goto done; 253700161856Syc148097 2538d81011f0Ssbehera } 2539d81011f0Ssbehera } 2540d81011f0Ssbehera done: 25416f45ec7bSml29623 254259ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 254359ac0c16Sdavemq "<== nxge_1G_serdes_init port<%d>", portn)); 25446f45ec7bSml29623 return (NXGE_OK); 25456f45ec7bSml29623 fail: 2546d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 254759ac0c16Sdavemq "nxge_1G_serdes_init: " 25486f45ec7bSml29623 "Failed to initialize Neptune serdes for port<%d>", 25496f45ec7bSml29623 portn)); 25506f45ec7bSml29623 2551d81011f0Ssbehera return (status); 25526f45ec7bSml29623 } 25536f45ec7bSml29623 2554*9d587972SSantwona Behera #define NXGE_SET_PHY_TUNABLES(nxgep, phy_port, stat) \ 2555*9d587972SSantwona Behera { \ 2556*9d587972SSantwona Behera int i; \ 2557*9d587972SSantwona Behera \ 2558*9d587972SSantwona Behera if (nxgep->phy_prop.cnt > 0) { \ 2559*9d587972SSantwona Behera for (i = 0; i < nxgep->phy_prop.cnt; i++) { \ 2560*9d587972SSantwona Behera if ((stat = nxge_mdio_write(nxgep, phy_port, \ 2561*9d587972SSantwona Behera nxgep->phy_prop.arr[i].dev, \ 2562*9d587972SSantwona Behera nxgep->phy_prop.arr[i].reg, \ 2563*9d587972SSantwona Behera nxgep->phy_prop.arr[i].val)) != NXGE_OK) { \ 2564*9d587972SSantwona Behera break; \ 2565*9d587972SSantwona Behera } \ 2566*9d587972SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, \ 2567*9d587972SSantwona Behera "From OBP, write<dev.reg.val> = " \ 2568*9d587972SSantwona Behera "<0x%x.0x%x.0x%x>", \ 2569*9d587972SSantwona Behera nxgep->phy_prop.arr[i].dev, \ 2570*9d587972SSantwona Behera nxgep->phy_prop.arr[i].reg, \ 2571*9d587972SSantwona Behera nxgep->phy_prop.arr[i].val)); \ 2572*9d587972SSantwona Behera } \ 2573*9d587972SSantwona Behera } \ 2574*9d587972SSantwona Behera } 2575*9d587972SSantwona Behera 25762d17280bSsbehera /* Initialize the BCM 8704 xcvr */ 25776f45ec7bSml29623 257859ac0c16Sdavemq static nxge_status_t 25792d17280bSsbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep) 25806f45ec7bSml29623 { 25816f45ec7bSml29623 uint16_t val; 25826f45ec7bSml29623 #ifdef NXGE_DEBUG 25836f45ec7bSml29623 uint8_t portn; 25846f45ec7bSml29623 uint16_t val1; 25856f45ec7bSml29623 #endif 25866f45ec7bSml29623 uint8_t phy_port_addr; 25876f45ec7bSml29623 pmd_tx_control_t tx_ctl; 25886f45ec7bSml29623 control_t ctl; 25896f45ec7bSml29623 phyxs_control_t phyxs_ctl; 25906f45ec7bSml29623 pcs_control_t pcs_ctl; 25916f45ec7bSml29623 uint32_t delay = 0; 25926f45ec7bSml29623 optics_dcntr_t op_ctr; 25936f45ec7bSml29623 nxge_status_t status = NXGE_OK; 25946f45ec7bSml29623 #ifdef NXGE_DEBUG 25956f45ec7bSml29623 portn = nxgep->mac.portnum; 25966f45ec7bSml29623 #endif 2597*9d587972SSantwona Behera 25982d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>", 259959ac0c16Sdavemq portn)); 26006f45ec7bSml29623 26016f45ec7bSml29623 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 26026f45ec7bSml29623 26036f45ec7bSml29623 /* Reset the transceiver */ 260459ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 260559ac0c16Sdavemq BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 26066f45ec7bSml29623 goto fail; 26076f45ec7bSml29623 26086f45ec7bSml29623 phyxs_ctl.bits.reset = 1; 260959ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 261059ac0c16Sdavemq BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 26116f45ec7bSml29623 goto fail; 26126f45ec7bSml29623 26136f45ec7bSml29623 do { 26146f45ec7bSml29623 drv_usecwait(500); 261559ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 261659ac0c16Sdavemq BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 26176f45ec7bSml29623 &phyxs_ctl.value)) != NXGE_OK) 26186f45ec7bSml29623 goto fail; 26196f45ec7bSml29623 delay++; 26206f45ec7bSml29623 } while ((phyxs_ctl.bits.reset) && (delay < 100)); 26216f45ec7bSml29623 if (delay == 100) { 262259ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 262359ac0c16Sdavemq "failed to reset Transceiver on port<%d>", portn)); 26246f45ec7bSml29623 status = NXGE_ERROR; 26256f45ec7bSml29623 goto fail; 26266f45ec7bSml29623 } 26276f45ec7bSml29623 26286f45ec7bSml29623 /* Set to 0x7FBF */ 26296f45ec7bSml29623 ctl.value = 0; 26306f45ec7bSml29623 ctl.bits.res1 = 0x3F; 26316f45ec7bSml29623 ctl.bits.optxon_lvl = 1; 26326f45ec7bSml29623 ctl.bits.oprxflt_lvl = 1; 26336f45ec7bSml29623 ctl.bits.optrxlos_lvl = 1; 26346f45ec7bSml29623 ctl.bits.optxflt_lvl = 1; 26356f45ec7bSml29623 ctl.bits.opprflt_lvl = 1; 26366f45ec7bSml29623 ctl.bits.obtmpflt_lvl = 1; 26376f45ec7bSml29623 ctl.bits.opbiasflt_lvl = 1; 26386f45ec7bSml29623 ctl.bits.optxrst_lvl = 1; 263959ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 264059ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value)) 26416f45ec7bSml29623 != NXGE_OK) 26426f45ec7bSml29623 goto fail; 26436f45ec7bSml29623 26446f45ec7bSml29623 /* Set to 0x164 */ 26456f45ec7bSml29623 tx_ctl.value = 0; 26466f45ec7bSml29623 tx_ctl.bits.tsck_lpwren = 1; 26476f45ec7bSml29623 tx_ctl.bits.tx_dac_txck = 0x2; 26486f45ec7bSml29623 tx_ctl.bits.tx_dac_txd = 0x1; 26496f45ec7bSml29623 tx_ctl.bits.xfp_clken = 1; 265059ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 265159ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, 265259ac0c16Sdavemq tx_ctl.value)) != NXGE_OK) 26536f45ec7bSml29623 goto fail; 26546f45ec7bSml29623 /* 26556f45ec7bSml29623 * According to Broadcom's instruction, SW needs to read 26566f45ec7bSml29623 * back these registers twice after written. 26576f45ec7bSml29623 */ 265859ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 265959ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 26606f45ec7bSml29623 != NXGE_OK) 26616f45ec7bSml29623 goto fail; 26626f45ec7bSml29623 266359ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 266459ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 26656f45ec7bSml29623 != NXGE_OK) 26666f45ec7bSml29623 goto fail; 26676f45ec7bSml29623 266859ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 266959ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 26706f45ec7bSml29623 != NXGE_OK) 26716f45ec7bSml29623 goto fail; 26726f45ec7bSml29623 267359ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 267459ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 26756f45ec7bSml29623 != NXGE_OK) 26766f45ec7bSml29623 goto fail; 26776f45ec7bSml29623 26786f45ec7bSml29623 /* Enable Tx and Rx LEDs to be driven by traffic */ 267959ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 268059ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 26816f45ec7bSml29623 &op_ctr.value)) != NXGE_OK) 26826f45ec7bSml29623 goto fail; 2683cb9d3ae6Smisaki if (NXGE_IS_XAUI_PLATFORM(nxgep)) { 2684cb9d3ae6Smisaki op_ctr.bits.gpio_sel = 0x1; 2685cb9d3ae6Smisaki } else { 26866f45ec7bSml29623 op_ctr.bits.gpio_sel = 0x3; 2687cb9d3ae6Smisaki } 268859ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 268959ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 26906f45ec7bSml29623 op_ctr.value)) != NXGE_OK) 26916f45ec7bSml29623 goto fail; 26926f45ec7bSml29623 26936f45ec7bSml29623 NXGE_DELAY(1000000); 26946f45ec7bSml29623 2695*9d587972SSantwona Behera /* 2696*9d587972SSantwona Behera * Set XAUI link tunables from OBP if present. 2697*9d587972SSantwona Behera */ 2698*9d587972SSantwona Behera NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status); 2699*9d587972SSantwona Behera if (status != NXGE_OK) { 2700*9d587972SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2701*9d587972SSantwona Behera "nxge_BCM8704_xcvr_init: Failed setting PHY tunables")); 2702*9d587972SSantwona Behera goto fail; 2703*9d587972SSantwona Behera } 2704*9d587972SSantwona Behera 27056f45ec7bSml29623 /* Set BCM8704 Internal Loopback mode if necessary */ 270659ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 270759ac0c16Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 270859ac0c16Sdavemq != NXGE_OK) 27096f45ec7bSml29623 goto fail; 27106f45ec7bSml29623 if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 27116f45ec7bSml29623 pcs_ctl.bits.loopback = 1; 27126f45ec7bSml29623 else 27136f45ec7bSml29623 pcs_ctl.bits.loopback = 0; 271459ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 271559ac0c16Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 271659ac0c16Sdavemq != NXGE_OK) 27176f45ec7bSml29623 goto fail; 27186f45ec7bSml29623 271959ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val); 27206f45ec7bSml29623 if (status != NXGE_OK) 27216f45ec7bSml29623 goto fail; 27226f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 272359ac0c16Sdavemq "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val)); 27246f45ec7bSml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 27256f45ec7bSml29623 if (status != NXGE_OK) 27266f45ec7bSml29623 goto fail; 27276f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 272859ac0c16Sdavemq "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val)); 27296f45ec7bSml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 27306f45ec7bSml29623 if (status != NXGE_OK) 27316f45ec7bSml29623 goto fail; 27326f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 273359ac0c16Sdavemq "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val)); 27346f45ec7bSml29623 27356f45ec7bSml29623 #ifdef NXGE_DEBUG 27366f45ec7bSml29623 /* Diagnose link issue if link is not up */ 273759ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR, 27386f45ec7bSml29623 BCM8704_USER_ANALOG_STATUS0_REG, 27396f45ec7bSml29623 &val); 27406f45ec7bSml29623 if (status != NXGE_OK) 27416f45ec7bSml29623 goto fail; 27426f45ec7bSml29623 27436f45ec7bSml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 274452ccf843Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val); 27456f45ec7bSml29623 if (status != NXGE_OK) 27466f45ec7bSml29623 goto fail; 27476f45ec7bSml29623 27486f45ec7bSml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 274952ccf843Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1); 27506f45ec7bSml29623 if (status != NXGE_OK) 27516f45ec7bSml29623 goto fail; 27526f45ec7bSml29623 27536f45ec7bSml29623 status = nxge_mdio_read(nxgep, phy_port_addr, 275452ccf843Smisaki BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1); 27556f45ec7bSml29623 if (status != NXGE_OK) 27566f45ec7bSml29623 goto fail; 27576f45ec7bSml29623 27586f45ec7bSml29623 if (val != 0x3FC) { 27596f45ec7bSml29623 if ((val == 0x43BC) && (val1 != 0)) { 27606f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 27616f45ec7bSml29623 "Cable not connected to peer or bad" 27626f45ec7bSml29623 " cable on port<%d>\n", portn)); 27636f45ec7bSml29623 } else if (val == 0x639C) { 27646f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 276559ac0c16Sdavemq "Optical module (XFP) is bad or absent" 27666f45ec7bSml29623 " on port<%d>\n", portn)); 27676f45ec7bSml29623 } 27686f45ec7bSml29623 } 27696f45ec7bSml29623 #endif 27706f45ec7bSml29623 27712d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>", 27722d17280bSsbehera portn)); 27732d17280bSsbehera return (NXGE_OK); 27742d17280bSsbehera 27752d17280bSsbehera fail: 27762d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 27772d17280bSsbehera "nxge_BCM8704_xcvr_init: failed to initialize transceiver for " 27782d17280bSsbehera "port<%d>", nxgep->mac.portnum)); 27792d17280bSsbehera return (NXGE_ERROR); 27802d17280bSsbehera } 27812d17280bSsbehera 27822d17280bSsbehera /* Initialize the BCM 8706 Transceiver */ 27832d17280bSsbehera 27842d17280bSsbehera static nxge_status_t 27852d17280bSsbehera nxge_BCM8706_xcvr_init(p_nxge_t nxgep) 27862d17280bSsbehera { 27872d17280bSsbehera uint8_t phy_port_addr; 27882d17280bSsbehera phyxs_control_t phyxs_ctl; 27892d17280bSsbehera pcs_control_t pcs_ctl; 27902d17280bSsbehera uint32_t delay = 0; 27912d17280bSsbehera optics_dcntr_t op_ctr; 27922d17280bSsbehera nxge_status_t status = NXGE_OK; 27932d17280bSsbehera #ifdef NXGE_DEBUG 27942d17280bSsbehera uint8_t portn = nxgep->mac.portnum; 27952d17280bSsbehera #endif 27962d17280bSsbehera 27972d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>", 27982d17280bSsbehera portn)); 27992d17280bSsbehera 28002d17280bSsbehera phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 28012d17280bSsbehera 28022d17280bSsbehera /* Reset the transceiver */ 28032d17280bSsbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 28042d17280bSsbehera BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 28052d17280bSsbehera goto fail; 28062d17280bSsbehera 28072d17280bSsbehera phyxs_ctl.bits.reset = 1; 28082d17280bSsbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 28092d17280bSsbehera BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 28102d17280bSsbehera goto fail; 28112d17280bSsbehera do { 28122d17280bSsbehera drv_usecwait(500); 28132d17280bSsbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 28142d17280bSsbehera BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 28152d17280bSsbehera &phyxs_ctl.value)) != NXGE_OK) 28162d17280bSsbehera goto fail; 28172d17280bSsbehera delay++; 28182d17280bSsbehera } while ((phyxs_ctl.bits.reset) && (delay < 100)); 28192d17280bSsbehera 28202d17280bSsbehera if (delay == 100) { 28212d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 28222d17280bSsbehera "failed to reset Transceiver on port<%d>", portn)); 28232d17280bSsbehera status = NXGE_ERROR; 28242d17280bSsbehera goto fail; 28252d17280bSsbehera } 28262d17280bSsbehera 28272d17280bSsbehera NXGE_DELAY(1000000); 28282d17280bSsbehera 2829*9d587972SSantwona Behera /* 2830*9d587972SSantwona Behera * Set XAUI link tunables from OBP if present. 2831*9d587972SSantwona Behera */ 2832*9d587972SSantwona Behera NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status); 2833*9d587972SSantwona Behera if (status != NXGE_OK) { 2834*9d587972SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2835*9d587972SSantwona Behera "nxge_BCM8706_xcvr_init: Failed setting PHY tunables")); 2836*9d587972SSantwona Behera goto fail; 2837*9d587972SSantwona Behera } 2838*9d587972SSantwona Behera 28392d17280bSsbehera /* Set BCM8706 Internal Loopback mode if necessary */ 28402d17280bSsbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 28412d17280bSsbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 28422d17280bSsbehera != NXGE_OK) 28432d17280bSsbehera goto fail; 28442d17280bSsbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 28452d17280bSsbehera pcs_ctl.bits.loopback = 1; 28462d17280bSsbehera else 28472d17280bSsbehera pcs_ctl.bits.loopback = 0; 28482d17280bSsbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 28492d17280bSsbehera BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 28502d17280bSsbehera != NXGE_OK) 28512d17280bSsbehera goto fail; 28522d17280bSsbehera 28532d17280bSsbehera /* Enable Tx and Rx LEDs to be driven by traffic */ 28542d17280bSsbehera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 28552d17280bSsbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 28562d17280bSsbehera &op_ctr.value)) != NXGE_OK) 28572d17280bSsbehera goto fail; 28582d17280bSsbehera op_ctr.bits.gpio_sel = 0x3; 28592d17280bSsbehera op_ctr.bits.res2 = 0x1; 28602d17280bSsbehera 28612d17280bSsbehera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 28622d17280bSsbehera BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 28632d17280bSsbehera op_ctr.value)) != NXGE_OK) 28642d17280bSsbehera goto fail; 28652d17280bSsbehera 28662d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>", 28672d17280bSsbehera portn)); 28682d17280bSsbehera return (NXGE_OK); 28692d17280bSsbehera 28702d17280bSsbehera fail: 28712d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 28722d17280bSsbehera "nxge_BCM8706_xcvr_init: failed to initialize transceiver for " 28732d17280bSsbehera "port<%d>", nxgep->mac.portnum)); 28742d17280bSsbehera return (status); 28752d17280bSsbehera } 28762d17280bSsbehera 287789282175SSantwona Behera static int 287889282175SSantwona Behera nxge_nlp2020_i2c_read(p_nxge_t nxgep, uint8_t ctrl_port, uint16_t address, 287989282175SSantwona Behera uint16_t reg, uint8_t *data) 288089282175SSantwona Behera { 288189282175SSantwona Behera int phy_dev, phy_reg; 288289282175SSantwona Behera uint16_t phy_data = 0; 288389282175SSantwona Behera uint16_t stat; 288489282175SSantwona Behera uint8_t count = 100; 288589282175SSantwona Behera 288689282175SSantwona Behera /* 288789282175SSantwona Behera * NLP2020_I2C_SNOOP_ADDR_REG [15:9][1] - Address 288889282175SSantwona Behera * NLP2020_I2C_SNOOP_ADDR_REG[7:0] - register in the xcvr's i2c 288989282175SSantwona Behera */ 289089282175SSantwona Behera phy_dev = NLP2020_I2C_SNOOP_DEV_ADDR; 289189282175SSantwona Behera phy_reg = NLP2020_I2C_SNOOP_ADDR_REG; 289289282175SSantwona Behera phy_data = ((address + 1) << NLP2020_XCVR_I2C_ADDR_SH) | reg; 289389282175SSantwona Behera if (nxge_mdio_write(nxgep, ctrl_port, 289489282175SSantwona Behera phy_dev, phy_reg, phy_data) != NXGE_OK) 289589282175SSantwona Behera goto fail; 289689282175SSantwona Behera 289789282175SSantwona Behera phy_reg = NLP2020_I2C_SNOOP_STAT_REG; 289889282175SSantwona Behera (void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg, &stat); 289989282175SSantwona Behera while ((stat != 0x01) && (count-- > 0)) { 290089282175SSantwona Behera (void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg, 290189282175SSantwona Behera &stat); 290289282175SSantwona Behera } 290389282175SSantwona Behera if (count) { 290489282175SSantwona Behera phy_reg = NLP2020_I2C_SNOOP_DATA_REG; 290589282175SSantwona Behera (void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg, 290689282175SSantwona Behera &phy_data); 290789282175SSantwona Behera *data = (phy_data >> 8); 290889282175SSantwona Behera return (0); 290989282175SSantwona Behera } 291089282175SSantwona Behera fail: 291189282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 291289282175SSantwona Behera "nxge_nlp2020_i2c_read: FAILED")); 291389282175SSantwona Behera return (1); 291489282175SSantwona Behera 291589282175SSantwona Behera } 291689282175SSantwona Behera 291789282175SSantwona Behera /* Initialize the Netlogic AEL2020 Transceiver */ 291889282175SSantwona Behera 291989282175SSantwona Behera #define NLP_INI_WAIT 1 292089282175SSantwona Behera #define NLP_INI_STOP 0 292189282175SSantwona Behera 292289282175SSantwona Behera static nxge_nlp_initseq_t nlp2020_revC_fiber_init[] = { 292389282175SSantwona Behera {0x1C003, 0x3101}, 292489282175SSantwona Behera {0x1CC01, 0x488a}, 292589282175SSantwona Behera {0x1CB1B, 0x0200}, 292689282175SSantwona Behera {0x1CB1C, 0x00f0}, 292789282175SSantwona Behera {0x1CC06, 0x00e0}, 292889282175SSantwona Behera {NLP_INI_STOP, 0}, 292989282175SSantwona Behera }; 293089282175SSantwona Behera 293189282175SSantwona Behera static nxge_nlp_initseq_t nlp2020_revC_copper_init[] = { 293289282175SSantwona Behera 293389282175SSantwona Behera {0x1C003, 0x3101}, 293489282175SSantwona Behera {0x1CD40, 0x0001}, 293589282175SSantwona Behera 293689282175SSantwona Behera {0x1CA12, 0x0100}, 293789282175SSantwona Behera {0x1CA22, 0x0100}, 293889282175SSantwona Behera {0x1CA42, 0x0100}, 293989282175SSantwona Behera {0x1C20D, 0x0002}, 294089282175SSantwona Behera {NLP_INI_WAIT, 100}, 294189282175SSantwona Behera 294289282175SSantwona Behera {0x1ff28, 0x4001}, 294389282175SSantwona Behera {0x1ff2A, 0x004A}, 294489282175SSantwona Behera {NLP_INI_WAIT, 500}, 294589282175SSantwona Behera 294689282175SSantwona Behera {0x1d000, 0x5200}, 294789282175SSantwona Behera {NLP_INI_WAIT, 500}, 294889282175SSantwona Behera 294989282175SSantwona Behera {0x1d800, 0x4009}, 295089282175SSantwona Behera {0x1d801, 0x2fff}, 295189282175SSantwona Behera {0x1d802, 0x300f}, 295289282175SSantwona Behera {0x1d803, 0x40aa}, 295389282175SSantwona Behera {0x1d804, 0x401c}, 295489282175SSantwona Behera {0x1d805, 0x401e}, 295589282175SSantwona Behera {0x1d806, 0x20c5}, 295689282175SSantwona Behera {0x1d807, 0x3c05}, 295789282175SSantwona Behera {0x1d808, 0x6536}, 295889282175SSantwona Behera {0x1d809, 0x2fe4}, 295989282175SSantwona Behera {0x1d80a, 0x3dc4}, 296089282175SSantwona Behera {0x1d80b, 0x6624}, 296189282175SSantwona Behera {0x1d80c, 0x2ff4}, 296289282175SSantwona Behera {0x1d80d, 0x3dc4}, 296389282175SSantwona Behera {0x1d80e, 0x2035}, 296489282175SSantwona Behera {0x1d80f, 0x30a5}, 296589282175SSantwona Behera {0x1d810, 0x6524}, 296689282175SSantwona Behera {0x1d811, 0x2ca2}, 296789282175SSantwona Behera {0x1d812, 0x3012}, 296889282175SSantwona Behera {0x1d813, 0x1002}, 296989282175SSantwona Behera {0x1d814, 0x2882}, 297089282175SSantwona Behera {0x1d815, 0x3022}, 297189282175SSantwona Behera {0x1d816, 0x1002}, 297289282175SSantwona Behera {0x1d817, 0x2972}, 297389282175SSantwona Behera {0x1d818, 0x3022}, 297489282175SSantwona Behera {0x1d819, 0x1002}, 297589282175SSantwona Behera {0x1d81a, 0x2892}, 297689282175SSantwona Behera {0x1d81b, 0x3012}, 297789282175SSantwona Behera {0x1d81c, 0x1002}, 297889282175SSantwona Behera {0x1d81d, 0x24e2}, 297989282175SSantwona Behera {0x1d81e, 0x3022}, 298089282175SSantwona Behera {0x1d81f, 0x1002}, 298189282175SSantwona Behera {0x1d820, 0x27e2}, 298289282175SSantwona Behera {0x1d821, 0x3012}, 298389282175SSantwona Behera {0x1d822, 0x1002}, 298489282175SSantwona Behera {0x1d823, 0x2422}, 298589282175SSantwona Behera {0x1d824, 0x3022}, 298689282175SSantwona Behera {0x1d825, 0x1002}, 298789282175SSantwona Behera {0x1d826, 0x22cd}, 298889282175SSantwona Behera {0x1d827, 0x301d}, 298989282175SSantwona Behera {0x1d828, 0x2992}, 299089282175SSantwona Behera {0x1d829, 0x3022}, 299189282175SSantwona Behera {0x1d82a, 0x1002}, 299289282175SSantwona Behera {0x1d82b, 0x5553}, 299389282175SSantwona Behera {0x1d82c, 0x0307}, 299489282175SSantwona Behera {0x1d82d, 0x2572}, 299589282175SSantwona Behera {0x1d82e, 0x3022}, 299689282175SSantwona Behera {0x1d82f, 0x1002}, 299789282175SSantwona Behera {0x1d830, 0x21a2}, 299889282175SSantwona Behera {0x1d831, 0x3012}, 299989282175SSantwona Behera {0x1d832, 0x1002}, 300089282175SSantwona Behera {0x1d833, 0x4016}, 300189282175SSantwona Behera {0x1d834, 0x5e63}, 300289282175SSantwona Behera {0x1d835, 0x0344}, 300389282175SSantwona Behera {0x1d836, 0x21a2}, 300489282175SSantwona Behera {0x1d837, 0x3012}, 300589282175SSantwona Behera {0x1d838, 0x1002}, 300689282175SSantwona Behera {0x1d839, 0x400e}, 300789282175SSantwona Behera {0x1d83a, 0x2572}, 300889282175SSantwona Behera {0x1d83b, 0x3022}, 300989282175SSantwona Behera {0x1d83c, 0x1002}, 301089282175SSantwona Behera {0x1d83d, 0x2b22}, 301189282175SSantwona Behera {0x1d83e, 0x3012}, 301289282175SSantwona Behera {0x1d83f, 0x1002}, 301389282175SSantwona Behera {0x1d840, 0x28e2}, 301489282175SSantwona Behera {0x1d841, 0x3022}, 301589282175SSantwona Behera {0x1d842, 0x1002}, 301689282175SSantwona Behera {0x1d843, 0x2782}, 301789282175SSantwona Behera {0x1d844, 0x3022}, 301889282175SSantwona Behera {0x1d845, 0x1002}, 301989282175SSantwona Behera {0x1d846, 0x2fa4}, 302089282175SSantwona Behera {0x1d847, 0x3dc4}, 302189282175SSantwona Behera {0x1d848, 0x6624}, 302289282175SSantwona Behera {0x1d849, 0x2e8b}, 302389282175SSantwona Behera {0x1d84a, 0x303b}, 302489282175SSantwona Behera {0x1d84b, 0x56b3}, 302589282175SSantwona Behera {0x1d84c, 0x03c6}, 302689282175SSantwona Behera {0x1d84d, 0x866b}, 302789282175SSantwona Behera {0x1d84e, 0x400c}, 302889282175SSantwona Behera {0x1d84f, 0x2782}, 302989282175SSantwona Behera {0x1d850, 0x3012}, 303089282175SSantwona Behera {0x1d851, 0x1002}, 303189282175SSantwona Behera {0x1d852, 0x2c4b}, 303289282175SSantwona Behera {0x1d853, 0x309b}, 303389282175SSantwona Behera {0x1d854, 0x56b3}, 303489282175SSantwona Behera {0x1d855, 0x03c3}, 303589282175SSantwona Behera {0x1d856, 0x866b}, 303689282175SSantwona Behera {0x1d857, 0x400c}, 303789282175SSantwona Behera {0x1d858, 0x22a2}, 303889282175SSantwona Behera {0x1d859, 0x3022}, 303989282175SSantwona Behera {0x1d85a, 0x1002}, 304089282175SSantwona Behera {0x1d85b, 0x28e2}, 304189282175SSantwona Behera {0x1d85c, 0x3022}, 304289282175SSantwona Behera {0x1d85d, 0x1002}, 304389282175SSantwona Behera {0x1d85e, 0x2782}, 304489282175SSantwona Behera {0x1d85f, 0x3022}, 304589282175SSantwona Behera {0x1d860, 0x1002}, 304689282175SSantwona Behera {0x1d861, 0x2fb4}, 304789282175SSantwona Behera {0x1d862, 0x3dc4}, 304889282175SSantwona Behera {0x1d863, 0x6624}, 304989282175SSantwona Behera {0x1d864, 0x56b3}, 305089282175SSantwona Behera {0x1d865, 0x03c3}, 305189282175SSantwona Behera {0x1d866, 0x866b}, 305289282175SSantwona Behera {0x1d867, 0x401c}, 305389282175SSantwona Behera {0x1d868, 0x2c45}, 305489282175SSantwona Behera {0x1d869, 0x3095}, 305589282175SSantwona Behera {0x1d86a, 0x5b53}, 305689282175SSantwona Behera {0x1d86b, 0x23d2}, 305789282175SSantwona Behera {0x1d86c, 0x3012}, 305889282175SSantwona Behera {0x1d86d, 0x13c2}, 305989282175SSantwona Behera {0x1d86e, 0x5cc3}, 306089282175SSantwona Behera {0x1d86f, 0x2782}, 306189282175SSantwona Behera {0x1d870, 0x3012}, 306289282175SSantwona Behera {0x1d871, 0x1312}, 306389282175SSantwona Behera {0x1d872, 0x2b22}, 306489282175SSantwona Behera {0x1d873, 0x3012}, 306589282175SSantwona Behera {0x1d874, 0x1002}, 306689282175SSantwona Behera {0x1d875, 0x28e2}, 306789282175SSantwona Behera {0x1d876, 0x3022}, 306889282175SSantwona Behera {0x1d877, 0x1002}, 306989282175SSantwona Behera {0x1d878, 0x2672}, 307089282175SSantwona Behera {0x1d879, 0x3022}, 307189282175SSantwona Behera {0x1d87a, 0x1002}, 307289282175SSantwona Behera {0x1d87b, 0x21a2}, 307389282175SSantwona Behera {0x1d87c, 0x3012}, 307489282175SSantwona Behera {0x1d87d, 0x1002}, 307589282175SSantwona Behera {0x1d87e, 0x628f}, 307689282175SSantwona Behera {0x1d87f, 0x2985}, 307789282175SSantwona Behera {0x1d880, 0x33a5}, 307889282175SSantwona Behera {0x1d881, 0x2782}, 307989282175SSantwona Behera {0x1d882, 0x3022}, 308089282175SSantwona Behera {0x1d883, 0x1002}, 308189282175SSantwona Behera {0x1d884, 0x5653}, 308289282175SSantwona Behera {0x1d885, 0x03d2}, 308389282175SSantwona Behera {0x1d886, 0x401e}, 308489282175SSantwona Behera {0x1d887, 0x6f72}, 308589282175SSantwona Behera {0x1d888, 0x1002}, 308689282175SSantwona Behera {0x1d889, 0x628f}, 308789282175SSantwona Behera {0x1d88a, 0x2304}, 308889282175SSantwona Behera {0x1d88b, 0x3c84}, 308989282175SSantwona Behera {0x1d88c, 0x6436}, 309089282175SSantwona Behera {0x1d88d, 0xdff4}, 309189282175SSantwona Behera {0x1d88e, 0x6436}, 309289282175SSantwona Behera {0x1d88f, 0x2ff5}, 309389282175SSantwona Behera {0x1d890, 0x3005}, 309489282175SSantwona Behera {0x1d891, 0x8656}, 309589282175SSantwona Behera {0x1d892, 0xdfba}, 309689282175SSantwona Behera {0x1d893, 0x56a3}, 309789282175SSantwona Behera {0x1d894, 0xd05a}, 309889282175SSantwona Behera {0x1d895, 0x29e2}, 309989282175SSantwona Behera {0x1d896, 0x3012}, 310089282175SSantwona Behera {0x1d897, 0x1392}, 310189282175SSantwona Behera {0x1d898, 0xd05a}, 310289282175SSantwona Behera {0x1d899, 0x56a3}, 310389282175SSantwona Behera {0x1d89a, 0xdfba}, 310489282175SSantwona Behera {0x1d89b, 0x0383}, 310589282175SSantwona Behera {0x1d89c, 0x6f72}, 310689282175SSantwona Behera {0x1d89d, 0x1002}, 310789282175SSantwona Behera {0x1d89e, 0x2a64}, 310889282175SSantwona Behera {0x1d89f, 0x3014}, 310989282175SSantwona Behera {0x1d8a0, 0x2005}, 311089282175SSantwona Behera {0x1d8a1, 0x3d75}, 311189282175SSantwona Behera {0x1d8a2, 0xc451}, 311289282175SSantwona Behera {0x1d8a3, 0x2a42}, 311389282175SSantwona Behera {0x1d8a4, 0x3022}, 311489282175SSantwona Behera {0x1d8a5, 0x1002}, 311589282175SSantwona Behera {0x1d8a6, 0x178c}, 311689282175SSantwona Behera {0x1d8a7, 0x1898}, 311789282175SSantwona Behera {0x1d8a8, 0x19a4}, 311889282175SSantwona Behera {0x1d8a9, 0x1ab0}, 311989282175SSantwona Behera {0x1d8aa, 0x1bbc}, 312089282175SSantwona Behera {0x1d8ab, 0x1cc8}, 312189282175SSantwona Behera {0x1d8ac, 0x1dd3}, 312289282175SSantwona Behera {0x1d8ad, 0x1ede}, 312389282175SSantwona Behera {0x1d8ae, 0x1fe9}, 312489282175SSantwona Behera {0x1d8af, 0x20f4}, 312589282175SSantwona Behera {0x1d8b0, 0x21ff}, 312689282175SSantwona Behera {0x1d8b1, 0x0000}, 312789282175SSantwona Behera {0x1d8b2, 0x27e1}, 312889282175SSantwona Behera {0x1d8b3, 0x3021}, 312989282175SSantwona Behera {0x1d8b4, 0x1001}, 313089282175SSantwona Behera {0x1d8b5, 0xc620}, 313189282175SSantwona Behera {0x1d8b6, 0x0000}, 313289282175SSantwona Behera {0x1d8b7, 0xc621}, 313389282175SSantwona Behera {0x1d8b8, 0x0000}, 313489282175SSantwona Behera {0x1d8b9, 0xc622}, 313589282175SSantwona Behera {0x1d8ba, 0x00e2}, 313689282175SSantwona Behera {0x1d8bb, 0xc623}, 313789282175SSantwona Behera {0x1d8bc, 0x007f}, 313889282175SSantwona Behera {0x1d8bd, 0xc624}, 313989282175SSantwona Behera {0x1d8be, 0x00ce}, 314089282175SSantwona Behera {0x1d8bf, 0xc625}, 314189282175SSantwona Behera {0x1d8c0, 0x0000}, 314289282175SSantwona Behera {0x1d8c1, 0xc627}, 314389282175SSantwona Behera {0x1d8c2, 0x0000}, 314489282175SSantwona Behera {0x1d8c3, 0xc628}, 314589282175SSantwona Behera {0x1d8c4, 0x0000}, 314689282175SSantwona Behera {0x1d8c5, 0xc90a}, 314789282175SSantwona Behera {0x1d8c6, 0x3a7c}, 314889282175SSantwona Behera {0x1d8c7, 0xc62c}, 314989282175SSantwona Behera {0x1d8c8, 0x0000}, 315089282175SSantwona Behera {0x1d8c9, 0x0000}, 315189282175SSantwona Behera {0x1d8ca, 0x27e1}, 315289282175SSantwona Behera {0x1d8cb, 0x3021}, 315389282175SSantwona Behera {0x1d8cc, 0x1001}, 315489282175SSantwona Behera {0x1d8cd, 0xc502}, 315589282175SSantwona Behera {0x1d8ce, 0x53ac}, 315689282175SSantwona Behera {0x1d8cf, 0xc503}, 315789282175SSantwona Behera {0x1d8d0, 0x2cd3}, 315889282175SSantwona Behera {0x1d8d1, 0xc600}, 315989282175SSantwona Behera {0x1d8d2, 0x2a6e}, 316089282175SSantwona Behera {0x1d8d3, 0xc601}, 316189282175SSantwona Behera {0x1d8d4, 0x2a2c}, 316289282175SSantwona Behera {0x1d8d5, 0xc605}, 316389282175SSantwona Behera {0x1d8d6, 0x5557}, 316489282175SSantwona Behera {0x1d8d7, 0xc60c}, 316589282175SSantwona Behera {0x1d8d8, 0x5400}, 316689282175SSantwona Behera {0x1d8d9, 0xc710}, 316789282175SSantwona Behera {0x1d8da, 0x0700}, 316889282175SSantwona Behera {0x1d8db, 0xc711}, 316989282175SSantwona Behera {0x1d8dc, 0x0f06}, 317089282175SSantwona Behera {0x1d8dd, 0xc718}, 317189282175SSantwona Behera {0x1d8de, 0x0700}, 317289282175SSantwona Behera {0x1d8df, 0xc719}, 317389282175SSantwona Behera {0x1d8e0, 0x0f06}, 317489282175SSantwona Behera {0x1d8e1, 0xc720}, 317589282175SSantwona Behera {0x1d8e2, 0x4700}, 317689282175SSantwona Behera {0x1d8e3, 0xc721}, 317789282175SSantwona Behera {0x1d8e4, 0x0f06}, 317889282175SSantwona Behera {0x1d8e5, 0xc728}, 317989282175SSantwona Behera {0x1d8e6, 0x0700}, 318089282175SSantwona Behera {0x1d8e7, 0xc729}, 318189282175SSantwona Behera {0x1d8e8, 0x1207}, 318289282175SSantwona Behera {0x1d8e9, 0xc801}, 318389282175SSantwona Behera {0x1d8ea, 0x7f50}, 318489282175SSantwona Behera {0x1d8eb, 0xc802}, 318589282175SSantwona Behera {0x1d8ec, 0x7760}, 318689282175SSantwona Behera {0x1d8ed, 0xc803}, 318789282175SSantwona Behera {0x1d8ee, 0x7fce}, 318889282175SSantwona Behera {0x1d8ef, 0xc804}, 318989282175SSantwona Behera {0x1d8f0, 0x520e}, 319089282175SSantwona Behera {0x1d8f1, 0xc805}, 319189282175SSantwona Behera {0x1d8f2, 0x5c11}, 319289282175SSantwona Behera {0x1d8f3, 0xc806}, 319389282175SSantwona Behera {0x1d8f4, 0x3c51}, 319489282175SSantwona Behera {0x1d8f5, 0xc807}, 319589282175SSantwona Behera {0x1d8f6, 0x4061}, 319689282175SSantwona Behera {0x1d8f7, 0xc808}, 319789282175SSantwona Behera {0x1d8f8, 0x49c1}, 319889282175SSantwona Behera {0x1d8f9, 0xc809}, 319989282175SSantwona Behera {0x1d8fa, 0x3840}, 320089282175SSantwona Behera {0x1d8fb, 0xc80a}, 320189282175SSantwona Behera {0x1d8fc, 0x0000}, 320289282175SSantwona Behera {0x1d8fd, 0xc821}, 320389282175SSantwona Behera {0x1d8fe, 0x0002}, 320489282175SSantwona Behera {0x1d8ff, 0xc822}, 320589282175SSantwona Behera {0x1d900, 0x0046}, 320689282175SSantwona Behera {0x1d901, 0xc844}, 320789282175SSantwona Behera {0x1d902, 0x182f}, 320889282175SSantwona Behera {0x1d903, 0xc849}, 320989282175SSantwona Behera {0x1d904, 0x0400}, 321089282175SSantwona Behera {0x1d905, 0xc84a}, 321189282175SSantwona Behera {0x1d906, 0x0002}, 321289282175SSantwona Behera {0x1d907, 0xc013}, 321389282175SSantwona Behera {0x1d908, 0xf341}, 321489282175SSantwona Behera {0x1d909, 0xc084}, 321589282175SSantwona Behera {0x1d90a, 0x0030}, 321689282175SSantwona Behera {0x1d90b, 0xc904}, 321789282175SSantwona Behera {0x1d90c, 0x1401}, 321889282175SSantwona Behera {0x1d90d, 0xcb0c}, 321989282175SSantwona Behera {0x1d90e, 0x0004}, 322089282175SSantwona Behera {0x1d90f, 0xcb0e}, 322189282175SSantwona Behera {0x1d910, 0xa00a}, 322289282175SSantwona Behera {0x1d911, 0xcb0f}, 322389282175SSantwona Behera {0x1d912, 0xc0c0}, 322489282175SSantwona Behera {0x1d913, 0xcb10}, 322589282175SSantwona Behera {0x1d914, 0xc0c0}, 322689282175SSantwona Behera {0x1d915, 0xcb11}, 322789282175SSantwona Behera {0x1d916, 0x00a0}, 322889282175SSantwona Behera {0x1d917, 0xcb12}, 322989282175SSantwona Behera {0x1d918, 0x0007}, 323089282175SSantwona Behera {0x1d919, 0xc241}, 323189282175SSantwona Behera {0x1d91a, 0xa000}, 323289282175SSantwona Behera {0x1d91b, 0xc243}, 323389282175SSantwona Behera {0x1d91c, 0x7fe0}, 323489282175SSantwona Behera {0x1d91d, 0xc604}, 323589282175SSantwona Behera {0x1d91e, 0x000e}, 323689282175SSantwona Behera {0x1d91f, 0xc609}, 323789282175SSantwona Behera {0x1d920, 0x00f5}, 323889282175SSantwona Behera {0x1d921, 0x0c61}, 323989282175SSantwona Behera {0x1d922, 0x000e}, 324089282175SSantwona Behera {0x1d923, 0xc660}, 324189282175SSantwona Behera {0x1d924, 0x9600}, 324289282175SSantwona Behera {0x1d925, 0xc687}, 324389282175SSantwona Behera {0x1d926, 0x0004}, 324489282175SSantwona Behera {0x1d927, 0xc60a}, 324589282175SSantwona Behera {0x1d928, 0x04f5}, 324689282175SSantwona Behera {0x1d929, 0x0000}, 324789282175SSantwona Behera {0x1d92a, 0x27e1}, 324889282175SSantwona Behera {0x1d92b, 0x3021}, 324989282175SSantwona Behera {0x1d92c, 0x1001}, 325089282175SSantwona Behera {0x1d92d, 0xc620}, 325189282175SSantwona Behera {0x1d92e, 0x14e5}, 325289282175SSantwona Behera {0x1d92f, 0xc621}, 325389282175SSantwona Behera {0x1d930, 0xc53d}, 325489282175SSantwona Behera {0x1d931, 0xc622}, 325589282175SSantwona Behera {0x1d932, 0x3cbe}, 325689282175SSantwona Behera {0x1d933, 0xc623}, 325789282175SSantwona Behera {0x1d934, 0x4452}, 325889282175SSantwona Behera {0x1d935, 0xc624}, 325989282175SSantwona Behera {0x1d936, 0xc5c5}, 326089282175SSantwona Behera {0x1d937, 0xc625}, 326189282175SSantwona Behera {0x1d938, 0xe01e}, 326289282175SSantwona Behera {0x1d939, 0xc627}, 326389282175SSantwona Behera {0x1d93a, 0x0000}, 326489282175SSantwona Behera {0x1d93b, 0xc628}, 326589282175SSantwona Behera {0x1d93c, 0x0000}, 326689282175SSantwona Behera {0x1d93d, 0xc62c}, 326789282175SSantwona Behera {0x1d93e, 0x0000}, 326889282175SSantwona Behera {0x1d93f, 0xc90a}, 326989282175SSantwona Behera {0x1d940, 0x3a7c}, 327089282175SSantwona Behera {0x1d941, 0x0000}, 327189282175SSantwona Behera {0x1d942, 0x2b84}, 327289282175SSantwona Behera {0x1d943, 0x3c74}, 327389282175SSantwona Behera {0x1d944, 0x6435}, 327489282175SSantwona Behera {0x1d945, 0xdff4}, 327589282175SSantwona Behera {0x1d946, 0x6435}, 327689282175SSantwona Behera {0x1d947, 0x2806}, 327789282175SSantwona Behera {0x1d948, 0x3006}, 327889282175SSantwona Behera {0x1d949, 0x8565}, 327989282175SSantwona Behera {0x1d94a, 0x2b24}, 328089282175SSantwona Behera {0x1d94b, 0x3c24}, 328189282175SSantwona Behera {0x1d94c, 0x6436}, 328289282175SSantwona Behera {0x1d94d, 0x1002}, 328389282175SSantwona Behera {0x1d94e, 0x2b24}, 328489282175SSantwona Behera {0x1d94f, 0x3c24}, 328589282175SSantwona Behera {0x1d950, 0x6436}, 328689282175SSantwona Behera {0x1d951, 0x4045}, 328789282175SSantwona Behera {0x1d952, 0x8656}, 328889282175SSantwona Behera {0x1d953, 0x5663}, 328989282175SSantwona Behera {0x1d954, 0x0302}, 329089282175SSantwona Behera {0x1d955, 0x401e}, 329189282175SSantwona Behera {0x1d956, 0x1002}, 329289282175SSantwona Behera {0x1d957, 0x2017}, 329389282175SSantwona Behera {0x1d958, 0x3b17}, 329489282175SSantwona Behera {0x1d959, 0x2084}, 329589282175SSantwona Behera {0x1d95a, 0x3c14}, 329689282175SSantwona Behera {0x1d95b, 0x6724}, 329789282175SSantwona Behera {0x1d95c, 0x2807}, 329889282175SSantwona Behera {0x1d95d, 0x31a7}, 329989282175SSantwona Behera {0x1d95e, 0x20c4}, 330089282175SSantwona Behera {0x1d95f, 0x3c24}, 330189282175SSantwona Behera {0x1d960, 0x6724}, 330289282175SSantwona Behera {0x1d961, 0x2ff7}, 330389282175SSantwona Behera {0x1d962, 0x30f7}, 330489282175SSantwona Behera {0x1d963, 0x20c4}, 330589282175SSantwona Behera {0x1d964, 0x3c04}, 330689282175SSantwona Behera {0x1d965, 0x6724}, 330789282175SSantwona Behera {0x1d966, 0x1002}, 330889282175SSantwona Behera {0x1d967, 0x2807}, 330989282175SSantwona Behera {0x1d968, 0x3187}, 331089282175SSantwona Behera {0x1d969, 0x20c4}, 331189282175SSantwona Behera {0x1d96a, 0x3c24}, 331289282175SSantwona Behera {0x1d96b, 0x6724}, 331389282175SSantwona Behera {0x1d96c, 0x2fe4}, 331489282175SSantwona Behera {0x1d96d, 0x3dc4}, 331589282175SSantwona Behera {0x1d96e, 0x6437}, 331689282175SSantwona Behera {0x1d96f, 0x20c4}, 331789282175SSantwona Behera {0x1d970, 0x3c04}, 331889282175SSantwona Behera {0x1d971, 0x6724}, 331989282175SSantwona Behera {0x1d972, 0x2017}, 332089282175SSantwona Behera {0x1d973, 0x3d17}, 332189282175SSantwona Behera {0x1d974, 0x2084}, 332289282175SSantwona Behera {0x1d975, 0x3c14}, 332389282175SSantwona Behera {0x1d976, 0x6724}, 332489282175SSantwona Behera {0x1d977, 0x1002}, 332589282175SSantwona Behera {0x1d978, 0x24f4}, 332689282175SSantwona Behera {0x1d979, 0x3c64}, 332789282175SSantwona Behera {0x1d97a, 0x6436}, 332889282175SSantwona Behera {0x1d97b, 0xdff4}, 332989282175SSantwona Behera {0x1d97c, 0x6436}, 333089282175SSantwona Behera {0x1d97d, 0x1002}, 333189282175SSantwona Behera {0x1d97e, 0x2006}, 333289282175SSantwona Behera {0x1d97f, 0x3d76}, 333389282175SSantwona Behera {0x1d980, 0xc161}, 333489282175SSantwona Behera {0x1d981, 0x6134}, 333589282175SSantwona Behera {0x1d982, 0x6135}, 333689282175SSantwona Behera {0x1d983, 0x5443}, 333789282175SSantwona Behera {0x1d984, 0x0303}, 333889282175SSantwona Behera {0x1d985, 0x6524}, 333989282175SSantwona Behera {0x1d986, 0x00fb}, 334089282175SSantwona Behera {0x1d987, 0x1002}, 334189282175SSantwona Behera {0x1d988, 0x20d4}, 334289282175SSantwona Behera {0x1d989, 0x3c24}, 334389282175SSantwona Behera {0x1d98a, 0x2025}, 334489282175SSantwona Behera {0x1d98b, 0x3005}, 334589282175SSantwona Behera {0x1d98c, 0x6524}, 334689282175SSantwona Behera {0x1d98d, 0x1002}, 334789282175SSantwona Behera {0x1d98e, 0xd019}, 334889282175SSantwona Behera {0x1d98f, 0x2104}, 334989282175SSantwona Behera {0x1d990, 0x3c24}, 335089282175SSantwona Behera {0x1d991, 0x2105}, 335189282175SSantwona Behera {0x1d992, 0x3805}, 335289282175SSantwona Behera {0x1d993, 0x6524}, 335389282175SSantwona Behera {0x1d994, 0xdff4}, 335489282175SSantwona Behera {0x1d995, 0x4005}, 335589282175SSantwona Behera {0x1d996, 0x6524}, 335689282175SSantwona Behera {0x1d997, 0x2e8d}, 335789282175SSantwona Behera {0x1d998, 0x303d}, 335889282175SSantwona Behera {0x1d999, 0x2408}, 335989282175SSantwona Behera {0x1d99a, 0x35d8}, 336089282175SSantwona Behera {0x1d99b, 0x5dd3}, 336189282175SSantwona Behera {0x1d99c, 0x0307}, 336289282175SSantwona Behera {0x1d99d, 0x8887}, 336389282175SSantwona Behera {0x1d99e, 0x63a7}, 336489282175SSantwona Behera {0x1d99f, 0x8887}, 336589282175SSantwona Behera {0x1d9a0, 0x63a7}, 336689282175SSantwona Behera {0x1d9a1, 0xdffd}, 336789282175SSantwona Behera {0x1d9a2, 0x00f9}, 336889282175SSantwona Behera {0x1d9a3, 0x1002}, 336989282175SSantwona Behera {0x1d9a4, 0x866a}, 337089282175SSantwona Behera {0x1d9a5, 0x6138}, 337189282175SSantwona Behera {0x1d9a6, 0x5883}, 337289282175SSantwona Behera {0x1d9a7, 0x2b42}, 337389282175SSantwona Behera {0x1d9a8, 0x3022}, 337489282175SSantwona Behera {0x1d9a9, 0x1302}, 337589282175SSantwona Behera {0x1d9aa, 0x2ff7}, 337689282175SSantwona Behera {0x1d9ab, 0x3007}, 337789282175SSantwona Behera {0x1d9ac, 0x8785}, 337889282175SSantwona Behera {0x1d9ad, 0xb887}, 337989282175SSantwona Behera {0x1d9ae, 0x8786}, 338089282175SSantwona Behera {0x1d9af, 0xb8c6}, 338189282175SSantwona Behera {0x1d9b0, 0x5a53}, 338289282175SSantwona Behera {0x1d9b1, 0x2a52}, 338389282175SSantwona Behera {0x1d9b2, 0x3022}, 338489282175SSantwona Behera {0x1d9b3, 0x13c2}, 338589282175SSantwona Behera {0x1d9b4, 0x2474}, 338689282175SSantwona Behera {0x1d9b5, 0x3c84}, 338789282175SSantwona Behera {0x1d9b6, 0x64d7}, 338889282175SSantwona Behera {0x1d9b7, 0x64d7}, 338989282175SSantwona Behera {0x1d9b8, 0x2ff5}, 339089282175SSantwona Behera {0x1d9b9, 0x3c05}, 339189282175SSantwona Behera {0x1d9ba, 0x8757}, 339289282175SSantwona Behera {0x1d9bb, 0xb886}, 339389282175SSantwona Behera {0x1d9bc, 0x9767}, 339489282175SSantwona Behera {0x1d9bd, 0x67c4}, 339589282175SSantwona Behera {0x1d9be, 0x6f72}, 339689282175SSantwona Behera {0x1d9bf, 0x1002}, 339789282175SSantwona Behera {0x1d9c0, 0x0000}, 339889282175SSantwona Behera {0x1d080, 0x0100}, 339989282175SSantwona Behera {0x1d092, 0x0000}, 340089282175SSantwona Behera {NLP_INI_STOP, 0}, 340189282175SSantwona Behera }; 340289282175SSantwona Behera 340389282175SSantwona Behera static nxge_status_t 340489282175SSantwona Behera nxge_nlp2020_xcvr_init(p_nxge_t nxgep) 340589282175SSantwona Behera { 340689282175SSantwona Behera uint8_t phy_port_addr; 340789282175SSantwona Behera nxge_status_t status = NXGE_OK; 340889282175SSantwona Behera uint16_t ctrl_reg, rst_val, pmd_ctl, rx_los; 340989282175SSantwona Behera int i = 0, count = 1000; 341089282175SSantwona Behera 341189282175SSantwona Behera uint8_t connector = 0, len, lpm; 341289282175SSantwona Behera p_nxge_nlp_initseq_t initseq; 341389282175SSantwona Behera uint16_t dev, reg, val; 341489282175SSantwona Behera 341589282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_nlp2020_xcvr_init: " 341689282175SSantwona Behera "port<%d>, phyaddr[0x%x]", nxgep->mac.portnum, 341789282175SSantwona Behera nxgep->statsp->mac_stats.xcvr_portn)); 341889282175SSantwona Behera 341989282175SSantwona Behera phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 342089282175SSantwona Behera 342189282175SSantwona Behera /* Reset the transceiver */ 342289282175SSantwona Behera rst_val = ctrl_reg = NLP2020_PMA_PMD_PHY_RST; 342389282175SSantwona Behera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 342489282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, rst_val)) 342589282175SSantwona Behera != NXGE_OK) 342689282175SSantwona Behera goto fail; 342789282175SSantwona Behera while ((count--) && (ctrl_reg & rst_val)) { 342889282175SSantwona Behera drv_usecwait(1000); 342989282175SSantwona Behera (void) nxge_mdio_read(nxgep, phy_port_addr, 343089282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &ctrl_reg); 343189282175SSantwona Behera } 343289282175SSantwona Behera if (count == 0) { 343389282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_nlp2020_xcvr_init: " 343489282175SSantwona Behera "PMA_PMD reset failed")); 343589282175SSantwona Behera goto fail; 343689282175SSantwona Behera } 343789282175SSantwona Behera 343889282175SSantwona Behera /* Set loopback mode if required */ 343989282175SSantwona Behera /* Set PMA PMD system loopback */ 344089282175SSantwona Behera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 344189282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &pmd_ctl)) 344289282175SSantwona Behera != NXGE_OK) 344389282175SSantwona Behera goto fail; 344489282175SSantwona Behera 344589282175SSantwona Behera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 344689282175SSantwona Behera pmd_ctl |= 0x0001; 344789282175SSantwona Behera else 344889282175SSantwona Behera pmd_ctl &= 0xfffe; 344989282175SSantwona Behera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 345089282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, pmd_ctl)) 345189282175SSantwona Behera != NXGE_OK) 345289282175SSantwona Behera goto fail; 345389282175SSantwona Behera 345489282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_nlp2020_xcvr_init: " 345589282175SSantwona Behera "setting LB, wrote NLP2020_PMA_PMD_CTL_REG[0x%x]", pmd_ctl)); 345689282175SSantwona Behera 345789282175SSantwona Behera /* Check connector details using I2c */ 345889282175SSantwona Behera if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR, 345989282175SSantwona Behera QSFP_MSA_CONN_REG, &connector) == 1) { 346089282175SSantwona Behera goto fail; 346189282175SSantwona Behera } 346289282175SSantwona Behera 346389282175SSantwona Behera switch (connector) { 346489282175SSantwona Behera case SFPP_FIBER: 346589282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 346689282175SSantwona Behera "nxge_nlp2020_xcvr_init: SFPP_FIBER detected")); 346789282175SSantwona Behera initseq = nlp2020_revC_fiber_init; 346889282175SSantwona Behera nxgep->nlp_conn = NXGE_NLP_CONN_FIBER; 346989282175SSantwona Behera break; 347089282175SSantwona Behera case QSFP_FIBER: 347189282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 347289282175SSantwona Behera "nxge_nlp2020_xcvr_init: QSFP_FIBER detected")); 347389282175SSantwona Behera initseq = nlp2020_revC_fiber_init; 347489282175SSantwona Behera nxgep->nlp_conn = NXGE_NLP_CONN_FIBER; 347589282175SSantwona Behera break; 347689282175SSantwona Behera case QSFP_COPPER_TWINAX: 347789282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 347889282175SSantwona Behera "nxge_nlp2020_xcvr_init: QSFP_COPPER_TWINAX/" 347989282175SSantwona Behera "SFPP_COPPER_TWINAX detected")); 348089282175SSantwona Behera 348189282175SSantwona Behera initseq = nlp2020_revC_copper_init; 348289282175SSantwona Behera nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_LT_7M; 348389282175SSantwona Behera break; 348489282175SSantwona Behera default: 348589282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 348689282175SSantwona Behera "nxge_nlp2020_xcvr_init: Unknown type [0x%x] detected", 348789282175SSantwona Behera "...setting to QSFP_FIBER", 348889282175SSantwona Behera connector)); 348989282175SSantwona Behera initseq = nlp2020_revC_fiber_init; 349089282175SSantwona Behera nxgep->nlp_conn = NXGE_NLP_CONN_FIBER; 349189282175SSantwona Behera break; 349289282175SSantwona Behera } 349389282175SSantwona Behera 349489282175SSantwona Behera /* Run appropriate init sequence */ 349589282175SSantwona Behera for (i = 0; initseq[i].dev_reg != NLP_INI_STOP; i++) { 349689282175SSantwona Behera dev = initseq[i].dev_reg >> 16; 349789282175SSantwona Behera reg = initseq[i].dev_reg & 0xffff; 349889282175SSantwona Behera val = initseq[i].val; 349989282175SSantwona Behera 350089282175SSantwona Behera if (reg == NLP_INI_WAIT) { 350189282175SSantwona Behera drv_usecwait(1000 * val); 350289282175SSantwona Behera } else { 350389282175SSantwona Behera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 350489282175SSantwona Behera dev, reg, val)) != NXGE_OK) 350589282175SSantwona Behera goto fail; 350689282175SSantwona Behera } 350789282175SSantwona Behera } 350889282175SSantwona Behera 350989282175SSantwona Behera /* rx_los inversion */ 351089282175SSantwona Behera if ((status = nxge_mdio_read(nxgep, phy_port_addr, 351189282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, &rx_los)) != NXGE_OK) 351289282175SSantwona Behera goto fail; 351389282175SSantwona Behera 351489282175SSantwona Behera rx_los &= ~(NLP2020_RXLOS_ACT_H); 351589282175SSantwona Behera 351689282175SSantwona Behera if ((status = nxge_mdio_write(nxgep, phy_port_addr, 351789282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, rx_los)) != NXGE_OK) 351889282175SSantwona Behera goto fail; 351989282175SSantwona Behera 352089282175SSantwona Behera if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR, 352189282175SSantwona Behera QSFP_MSA_LEN_REG, &len) == 1) { 352289282175SSantwona Behera goto fail; 352389282175SSantwona Behera } 352489282175SSantwona Behera 352589282175SSantwona Behera if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR, 352689282175SSantwona Behera QSFP_MSA_LPM_REG, &lpm) == 1) { 352789282175SSantwona Behera goto fail; 352889282175SSantwona Behera } 352989282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 353089282175SSantwona Behera "nxge_nlp2020_xcvr_init: len[0x%x] lpm[0x%x]", len, lpm)); 353189282175SSantwona Behera 353289282175SSantwona Behera if (connector == QSFP_COPPER_TWINAX) { 353389282175SSantwona Behera if (len >= 7) { 353489282175SSantwona Behera nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_7M_ABOVE; 353589282175SSantwona Behera /* enable pre-emphasis */ 353689282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 353789282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL1_REG, 353889282175SSantwona Behera NLP2020_TX_DRV_CTL1_PREEMP_EN); 353989282175SSantwona Behera /* write emphasis value */ 354089282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 354189282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL2_REG, 354289282175SSantwona Behera NLP2020_TX_DRV_CTL2_EMP_VAL); 354389282175SSantwona Behera /* stop microcontroller */ 354489282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 354589282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG, 354689282175SSantwona Behera NLP2020_UC_CTL_STOP); 354789282175SSantwona Behera /* reset program counter */ 354889282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 354989282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_UC_PC_START_REG, 355089282175SSantwona Behera NLP2020_UC_PC_START_VAL); 355189282175SSantwona Behera /* start microcontroller */ 355289282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 355389282175SSantwona Behera NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG, 355489282175SSantwona Behera NLP2020_UC_CTL_START); 355589282175SSantwona Behera } 355689282175SSantwona Behera } 355789282175SSantwona Behera if (lpm & QSFP_MSA_LPM_HIGH) { 355889282175SSantwona Behera /* enable high power mode */ 355989282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 356089282175SSantwona Behera NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 356189282175SSantwona Behera NLP2020_GPIO_ACT); 356289282175SSantwona Behera } else { 356389282175SSantwona Behera /* revert to low power mode */ 356489282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy_port_addr, 356589282175SSantwona Behera NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 356689282175SSantwona Behera NLP2020_GPIO_INACT); 356789282175SSantwona Behera } 3568*9d587972SSantwona Behera 3569*9d587972SSantwona Behera /* 3570*9d587972SSantwona Behera * Set XAUI link tunables from OBP if present. 3571*9d587972SSantwona Behera */ 3572*9d587972SSantwona Behera NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status); 3573*9d587972SSantwona Behera if (status != NXGE_OK) { 3574*9d587972SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3575*9d587972SSantwona Behera "nxge_nlp2020_xcvr_init: Failed setting PHY tunables")); 3576*9d587972SSantwona Behera goto fail; 3577*9d587972SSantwona Behera } 3578*9d587972SSantwona Behera 357989282175SSantwona Behera /* It takes ~2s for EDC to settle */ 358089282175SSantwona Behera drv_usecwait(2000000); 358189282175SSantwona Behera 358289282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_nlp2020_xcvr_init: " 358389282175SSantwona Behera "port<%d> phyaddr[0x%x]", nxgep->mac.portnum, phy_port_addr)); 358489282175SSantwona Behera 358589282175SSantwona Behera return (NXGE_OK); 358689282175SSantwona Behera 358789282175SSantwona Behera fail: 358889282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 358989282175SSantwona Behera "nxge_nlp2020_xcvr_init: failed to initialize transceiver for " 359089282175SSantwona Behera "port<%d>", nxgep->mac.portnum)); 359189282175SSantwona Behera return (status); 359289282175SSantwona Behera } 359389282175SSantwona Behera 359489282175SSantwona Behera static boolean_t nxge_is_nlp2020_phy(p_nxge_t nxgep) 359589282175SSantwona Behera { 359689282175SSantwona Behera uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 359789282175SSantwona Behera uint32_t pcs_id = 0; 359889282175SSantwona Behera uint32_t pma_pmd_id = 0; 359989282175SSantwona Behera uint8_t xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 360089282175SSantwona Behera 360189282175SSantwona Behera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, xcvr_addr); 360289282175SSantwona Behera pcs_id = nxge_get_cl45_pcs_id(nxgep, xcvr_addr); 360389282175SSantwona Behera 360489282175SSantwona Behera if (((pma_pmd_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) || 360589282175SSantwona Behera ((pcs_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID)) { 360689282175SSantwona Behera return (B_TRUE); 360789282175SSantwona Behera } else { 360889282175SSantwona Behera return (B_FALSE); 360989282175SSantwona Behera } 361089282175SSantwona Behera } 361189282175SSantwona Behera 361289282175SSantwona Behera static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t nxgep) 361389282175SSantwona Behera { 361489282175SSantwona Behera uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 361589282175SSantwona Behera uint8_t xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 361689282175SSantwona Behera uint8_t connector = 0; 361789282175SSantwona Behera 361889282175SSantwona Behera (void) nxge_nlp2020_i2c_read(nxgep, xcvr_addr, NLP2020_XCVR_I2C_ADDR, 361989282175SSantwona Behera QSFP_MSA_CONN_REG, &connector); 362089282175SSantwona Behera 362189282175SSantwona Behera return (connector); 362289282175SSantwona Behera } 362389282175SSantwona Behera 362489282175SSantwona Behera static nxge_status_t nxge_set_nlp2020_param(p_nxge_t nxgep) 362589282175SSantwona Behera { 362689282175SSantwona Behera uint8_t connector = 0; 362789282175SSantwona Behera 362889282175SSantwona Behera connector = nxge_get_nlp2020_connector_type(nxgep); 362989282175SSantwona Behera 363089282175SSantwona Behera switch (connector) { 363189282175SSantwona Behera case SFPP_FIBER: 363289282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 363389282175SSantwona Behera "nxge_set_nlp2020_param: SFPP_FIBER detected")); 363489282175SSantwona Behera nxgep->mac.portmode = PORT_10G_FIBER; 363589282175SSantwona Behera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 363689282175SSantwona Behera break; 363789282175SSantwona Behera case QSFP_FIBER: 363889282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 363989282175SSantwona Behera "nxge_set_nlp2020_param: QSFP_FIBER detected")); 364089282175SSantwona Behera nxgep->mac.portmode = PORT_10G_FIBER; 364189282175SSantwona Behera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 364289282175SSantwona Behera break; 364389282175SSantwona Behera case QSFP_COPPER_TWINAX: 364489282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 364589282175SSantwona Behera "nxge_set_nlp2020_param: QSFP_COPPER_TWINAX/" 364689282175SSantwona Behera "SFPP_COPPER_TWINAX detected")); 364789282175SSantwona Behera nxgep->mac.portmode = PORT_10G_COPPER; 364889282175SSantwona Behera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 364989282175SSantwona Behera break; 365089282175SSantwona Behera default: 365189282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 365289282175SSantwona Behera "nxge_set_nlp2020_param: Unknown type [0x%x] detected" 365389282175SSantwona Behera "...setting to QSFP_FIBER", 365489282175SSantwona Behera connector)); 365589282175SSantwona Behera nxgep->mac.portmode = PORT_10G_FIBER; 365689282175SSantwona Behera nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 365789282175SSantwona Behera break; 365889282175SSantwona Behera } 365989282175SSantwona Behera 366089282175SSantwona Behera return (NXGE_OK); 366189282175SSantwona Behera } 366289282175SSantwona Behera 366352cdd236Ssbehera #define CHK_STAT(x) status = (x); if (status != NXGE_OK) goto fail 366452cdd236Ssbehera 366552cdd236Ssbehera #define MRVL88X2011_RD(nxgep, port, d, r, p) \ 366652cdd236Ssbehera CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p)) 366752cdd236Ssbehera 366852cdd236Ssbehera #define MRVL88X2011_WR(nxgep, port, d, r, p) \ 366952cdd236Ssbehera CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p)) 367052cdd236Ssbehera 367152cdd236Ssbehera 367252cdd236Ssbehera static void 367352cdd236Ssbehera nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate) 367452cdd236Ssbehera { 367552cdd236Ssbehera uint16_t value; 367652cdd236Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 367752cdd236Ssbehera 367852cdd236Ssbehera if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR, 367952cdd236Ssbehera MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) { 368052cdd236Ssbehera value &= ~MRVL_88X2011_LED_BLK_MASK; 368152cdd236Ssbehera value |= (rate << MRVL_88X2011_LED_BLK_SHIFT); 368252cdd236Ssbehera (void) nxge_mdio_write(nxgep, phy, 368352cdd236Ssbehera MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL, 368452cdd236Ssbehera value); 368552cdd236Ssbehera } 368652cdd236Ssbehera } 368752cdd236Ssbehera 368852cdd236Ssbehera static nxge_status_t 368952cdd236Ssbehera nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep) 369052cdd236Ssbehera { 369152cdd236Ssbehera nxge_status_t status; 369252cdd236Ssbehera pcs_control_t pcs_ctl; 369352cdd236Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 369452cdd236Ssbehera 369552cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 369652cdd236Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value); 369752cdd236Ssbehera 369852cdd236Ssbehera if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 369952cdd236Ssbehera pcs_ctl.bits.loopback = 1; 370052cdd236Ssbehera else 370152cdd236Ssbehera pcs_ctl.bits.loopback = 0; 370252cdd236Ssbehera 370352cdd236Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 370452cdd236Ssbehera MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value); 370552cdd236Ssbehera 370652cdd236Ssbehera fail: 370752cdd236Ssbehera return (status); 370852cdd236Ssbehera } 370952cdd236Ssbehera 371052cdd236Ssbehera 371152cdd236Ssbehera static void 371252cdd236Ssbehera nxge_mrvl88x2011_led(p_nxge_t nxgep, uint16_t val) 371352cdd236Ssbehera { 371452cdd236Ssbehera uint16_t val2; 371552cdd236Ssbehera uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn; 371652cdd236Ssbehera 371752cdd236Ssbehera val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val); 371852cdd236Ssbehera val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, 371952cdd236Ssbehera MRVL_88X2011_LED_CTL_MASK); 372052cdd236Ssbehera val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val); 372152cdd236Ssbehera 372252cdd236Ssbehera if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR, 372352cdd236Ssbehera MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) { 372452cdd236Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 372552cdd236Ssbehera "nxge_mrvl88x2011_led: nxge_mdio_write failed!!")); 372652cdd236Ssbehera } 372752cdd236Ssbehera } 372852cdd236Ssbehera 372952cdd236Ssbehera 373052cdd236Ssbehera static nxge_status_t 373152cdd236Ssbehera nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep) 373252cdd236Ssbehera { 373352cdd236Ssbehera uint8_t phy; 373452cdd236Ssbehera nxge_status_t status; 373552cdd236Ssbehera uint16_t clk; 373652cdd236Ssbehera 373752cdd236Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn; 373852cdd236Ssbehera 373952cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 374052cdd236Ssbehera "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>", 374152cdd236Ssbehera nxgep->mac.portnum, phy)); 374252cdd236Ssbehera 374352cdd236Ssbehera /* Set LED functions */ 374452cdd236Ssbehera nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS); 374552cdd236Ssbehera /* PCS activity */ 374652cdd236Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT); 374752cdd236Ssbehera 374852cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 374952cdd236Ssbehera MRVL_88X2011_GEN_CTL, &clk); 375052cdd236Ssbehera clk |= MRVL_88X2011_ENA_XFPREFCLK; 375152cdd236Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 375252cdd236Ssbehera MRVL_88X2011_GEN_CTL, clk); 375352cdd236Ssbehera 375452cdd236Ssbehera /* Set internal loopback mode if necessary */ 375552cdd236Ssbehera 375652cdd236Ssbehera CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep)); 375752cdd236Ssbehera 375852cdd236Ssbehera /* Enable PMD */ 375952cdd236Ssbehera MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 376052cdd236Ssbehera MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX); 376152cdd236Ssbehera 376252cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK")); 376352cdd236Ssbehera 376452cdd236Ssbehera fail: 376552cdd236Ssbehera return (status); 376652cdd236Ssbehera } 376752cdd236Ssbehera 376852cdd236Ssbehera 376952cdd236Ssbehera 37702d17280bSsbehera /* Initialize the 10G Transceiver */ 37712d17280bSsbehera 37722d17280bSsbehera static nxge_status_t 37732d17280bSsbehera nxge_10G_xcvr_init(p_nxge_t nxgep) 37742d17280bSsbehera { 37752d17280bSsbehera p_nxge_stats_t statsp; 37761bd6825cSml29623 p_nxge_param_t param_arr = nxgep->param_arr; 37772d17280bSsbehera nxge_status_t status = NXGE_OK; 37782d17280bSsbehera #ifdef NXGE_DEBUG 37792d17280bSsbehera uint8_t portn = nxgep->mac.portnum; 37802d17280bSsbehera #endif 37812d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 37822d17280bSsbehera portn)); 37832d17280bSsbehera 37842d17280bSsbehera statsp = nxgep->statsp; 37852d17280bSsbehera 37861c7408c9Stc99174@train /* Disable Link LEDs, with or without PHY */ 37871c7408c9Stc99174@train if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 37881c7408c9Stc99174@train goto done; 37891c7408c9Stc99174@train 37901c7408c9Stc99174@train /* Skip MDIO, if PHY absent */ 37911c7408c9Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) { 37922d17280bSsbehera goto done; 37932d17280bSsbehera } 37942d17280bSsbehera 37952d17280bSsbehera /* Set Clause 45 */ 37962d17280bSsbehera npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 37972d17280bSsbehera 37982d17280bSsbehera switch (nxgep->chip_id) { 37992d17280bSsbehera case BCM8704_CHIP_ID: 380000161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 38012d17280bSsbehera "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id)); 38022d17280bSsbehera status = nxge_BCM8704_xcvr_init(nxgep); 38032d17280bSsbehera break; 38042d17280bSsbehera case BCM8706_CHIP_ID: 380500161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 38062d17280bSsbehera "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id)); 38072d17280bSsbehera status = nxge_BCM8706_xcvr_init(nxgep); 38082d17280bSsbehera break; 380952cdd236Ssbehera case MRVL88X201X_CHIP_ID: 381000161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 381189282175SSantwona Behera "Chip ID MRVL [0x%x] for 10G xcvr", nxgep->chip_id)); 381252cdd236Ssbehera status = nxge_mrvl88x2011_xcvr_init(nxgep); 381352cdd236Ssbehera break; 381489282175SSantwona Behera case NLP2020_CHIP_ID: 381589282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: " 381689282175SSantwona Behera "Chip ID NL2020 [0x%x] for 10G xcvr", nxgep->chip_id)); 381789282175SSantwona Behera status = nxge_nlp2020_xcvr_init(nxgep); 381889282175SSantwona Behera break; 38192d17280bSsbehera default: 38202d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: " 38212d17280bSsbehera "Unknown chip ID 0x%x for 10G xcvr addr[%d]", 38222d17280bSsbehera nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn)); 38232d17280bSsbehera goto fail; 38242d17280bSsbehera } 38252d17280bSsbehera 38262d17280bSsbehera if (status != NXGE_OK) { 38272d17280bSsbehera goto fail; 38282d17280bSsbehera } 38292e59129aSraghus done: 38306f45ec7bSml29623 statsp->mac_stats.cap_10gfdx = 1; 38316f45ec7bSml29623 statsp->mac_stats.lp_cap_10gfdx = 1; 38321bd6825cSml29623 statsp->mac_stats.adv_cap_asmpause = 38331bd6825cSml29623 param_arr[param_anar_asmpause].value; 38341bd6825cSml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 383559ac0c16Sdavemq 383659ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 383759ac0c16Sdavemq portn)); 383859ac0c16Sdavemq return (NXGE_OK); 383959ac0c16Sdavemq 384059ac0c16Sdavemq fail: 38412d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 384259ac0c16Sdavemq "nxge_10G_xcvr_init: failed to initialize transceiver for " 38432d17280bSsbehera "port<%d>", nxgep->mac.portnum)); 38442d17280bSsbehera return (NXGE_ERROR); 384559ac0c16Sdavemq } 384659ac0c16Sdavemq 384759ac0c16Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */ 384859ac0c16Sdavemq 384959ac0c16Sdavemq static nxge_status_t 385059ac0c16Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep) 385159ac0c16Sdavemq { 385259ac0c16Sdavemq p_nxge_param_t param_arr = nxgep->param_arr; 385359ac0c16Sdavemq p_nxge_stats_t statsp = nxgep->statsp; 385459ac0c16Sdavemq nxge_status_t status = NXGE_OK; 385559ac0c16Sdavemq 38562e59129aSraghus if (nxgep->mac.portmode == PORT_1G_SERDES) { 38572e59129aSraghus statsp->mac_stats.cap_1000fdx = 38582e59129aSraghus param_arr[param_anar_1000fdx].value; 38592e59129aSraghus goto done; 38602e59129aSraghus } 38612e59129aSraghus 38626f45ec7bSml29623 /* Set Clause 22 */ 38636f45ec7bSml29623 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 38646f45ec7bSml29623 38656f45ec7bSml29623 /* Set capability flags */ 386659ac0c16Sdavemq statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value; 38672e59129aSraghus if ((nxgep->mac.portmode == PORT_1G_COPPER) || 38682e59129aSraghus (nxgep->mac.portmode == PORT_1G_FIBER)) { 38692e59129aSraghus statsp->mac_stats.cap_100fdx = 38702e59129aSraghus param_arr[param_anar_100fdx].value; 38712e59129aSraghus statsp->mac_stats.cap_10fdx = 38722e59129aSraghus param_arr[param_anar_10fdx].value; 38732e59129aSraghus } 38746f45ec7bSml29623 387559ac0c16Sdavemq status = nxge_mii_xcvr_init(nxgep); 38762e59129aSraghus done: 387759ac0c16Sdavemq return (status); 38786f45ec7bSml29623 } 38796f45ec7bSml29623 388000161856Syc148097 /* 388100161856Syc148097 * Although the Teranetics copper transceiver (TN1010) does not need 388200161856Syc148097 * to be initialized by the driver for passing packets, this funtion 388300161856Syc148097 * initializes the members of nxgep->statsp->mac_stats struct for 388400161856Syc148097 * kstat based on the value of nxgep->statsp->ports_stats.lb_mode. 388500161856Syc148097 * It also configures the TN1010 for PHY loopback to support SunVTS. 388600161856Syc148097 * 388700161856Syc148097 * TN1010 only has the option to disable advertisement for the 10G 388800161856Syc148097 * mode. So we can set it to either Dual Mode or 1G Only mode but 388900161856Syc148097 * can't set it to 10G Only mode. 389000161856Syc148097 * 389100161856Syc148097 * ndd -set command can set the following 6 speed/duplex related parameters. 389200161856Syc148097 * 389300161856Syc148097 * ---------------------------------------------------------------- 389400161856Syc148097 * ndd -set /dev/nxgeX param n kstat nxge:X | grep param 389500161856Syc148097 * ---------------------------------------------------------------- 389600161856Syc148097 * adv_autoneg_cap kstat nxge:1 | grep adv_cap_autoneg 389700161856Syc148097 * adv_10gfdx_cap 389800161856Syc148097 * adv_1000fdx_cap kstat nxge:1 | grep adv_cap_1000fdx 389900161856Syc148097 * adv_100fdx_cap kstat nxge:1 | grep adv_cap_100fdx 390000161856Syc148097 * adv_10fdx_cap kstat nxge:1 | grep adv_cap_10fdx 390100161856Syc148097 * adv_pause_cap kstat nxge:1 | grep adv_cap_pause 390200161856Syc148097 * ---------------------------------------------------------------- 390300161856Syc148097 */ 390400161856Syc148097 static nxge_status_t 390500161856Syc148097 nxge_tn1010_xcvr_init(p_nxge_t nxgep) 390600161856Syc148097 { 390700161856Syc148097 p_nxge_param_t param_arr; 390800161856Syc148097 p_nxge_stats_t statsp; 390900161856Syc148097 tn1010_pcs_ctrl_t tn1010_pcs_ctrl; 391000161856Syc148097 uint16_t speed; 391100161856Syc148097 uint8_t phy_port_addr; 391200161856Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 391300161856Syc148097 int status = NXGE_OK; 391400161856Syc148097 391500161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init")); 391600161856Syc148097 391700161856Syc148097 param_arr = nxgep->param_arr; 391800161856Syc148097 statsp = nxgep->statsp; 391900161856Syc148097 392000161856Syc148097 /* 392100161856Syc148097 * Initialize the xcvr statistics which are NOT controlled by ndd 392200161856Syc148097 */ 392300161856Syc148097 statsp->mac_stats.cap_autoneg = 1; /* TN1010 autoneg is always on */ 392400161856Syc148097 statsp->mac_stats.cap_100T4 = 0; 392500161856Syc148097 392600161856Syc148097 /* 392700161856Syc148097 * Read the TN1010 link speed and initialize capabilities kstat. Note 392800161856Syc148097 * that function nxge_check_tn1010_link repeatedly invoked by the 392900161856Syc148097 * timer will update link_speed real time. 393000161856Syc148097 */ 393100161856Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) { 393200161856Syc148097 goto fail; 393300161856Syc148097 } 393400161856Syc148097 if (speed == TN1010_SPEED_1G) { 393500161856Syc148097 statsp->mac_stats.cap_10gfdx = 0; 393600161856Syc148097 } else { 393700161856Syc148097 statsp->mac_stats.cap_10gfdx = 1; 393800161856Syc148097 } 393900161856Syc148097 394000161856Syc148097 /* Whether we are in 1G or 10G mode, we always have the 1G capability */ 394100161856Syc148097 statsp->mac_stats.cap_1000fdx = 1; 394200161856Syc148097 394300161856Syc148097 /* TN1010 is not able to operate in the following states */ 394400161856Syc148097 statsp->mac_stats.cap_1000hdx = 0; 394500161856Syc148097 statsp->mac_stats.cap_100fdx = 0; 394600161856Syc148097 statsp->mac_stats.cap_100hdx = 0; 394700161856Syc148097 statsp->mac_stats.cap_10fdx = 0; 394800161856Syc148097 statsp->mac_stats.cap_10hdx = 0; 394900161856Syc148097 395000161856Syc148097 /* param_anar_pause can be modified by ndd -set */ 395100161856Syc148097 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 395200161856Syc148097 395300161856Syc148097 /* 395400161856Syc148097 * The following 4 lines actually overwrites what ever the ndd command 395500161856Syc148097 * has set. For example, by command 395600161856Syc148097 * ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1) 395700161856Syc148097 * we could set param_arr[param_autoneg].value to n. However, because 395800161856Syc148097 * here we assign constants to these parameters, whatever we set with 395900161856Syc148097 * the "ndd -set" command will be replaced. So command 396000161856Syc148097 * kstat nxge:X | grep param 396100161856Syc148097 * will always show those constant values. In other words, the 396200161856Syc148097 * "ndd -set" command can NOT change the values of these 4 parameters 396300161856Syc148097 * even though the command appears to be successful. 396400161856Syc148097 * 396500161856Syc148097 * Note: TN1010 auto negotiation is always enabled. 396600161856Syc148097 */ 396700161856Syc148097 statsp->mac_stats.adv_cap_autoneg 396800161856Syc148097 = param_arr[param_autoneg].value = 1; 396900161856Syc148097 statsp->mac_stats.adv_cap_1000fdx 397000161856Syc148097 = param_arr[param_anar_1000fdx].value = 1; 397100161856Syc148097 statsp->mac_stats.adv_cap_100fdx 397200161856Syc148097 = param_arr[param_anar_100fdx].value = 0; 397300161856Syc148097 statsp->mac_stats.adv_cap_10fdx 397400161856Syc148097 = param_arr[param_anar_10fdx].value = 0; 397500161856Syc148097 397600161856Syc148097 /* 397700161856Syc148097 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as 397800161856Syc148097 * defined in nxge_param_arr[], therefore they are not seen by the 397900161856Syc148097 * "ndd -get" command and can not be changed by ndd. We just set 398000161856Syc148097 * them (both ndd param and kstat values) to constant 0 because TN1010 398100161856Syc148097 * does not support those speeds. 398200161856Syc148097 */ 398300161856Syc148097 statsp->mac_stats.adv_cap_100T4 398400161856Syc148097 = param_arr[param_anar_100T4].value = 0; 398500161856Syc148097 statsp->mac_stats.adv_cap_1000hdx 398600161856Syc148097 = param_arr[param_anar_1000hdx].value = 0; 398700161856Syc148097 statsp->mac_stats.adv_cap_100hdx 398800161856Syc148097 = param_arr[param_anar_100hdx].value = 0; 398900161856Syc148097 statsp->mac_stats.adv_cap_10hdx 399000161856Syc148097 = param_arr[param_anar_10hdx].value = 0; 399100161856Syc148097 399200161856Syc148097 /* 399300161856Syc148097 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified 399400161856Syc148097 * by ndd 399500161856Syc148097 */ 399600161856Syc148097 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 399700161856Syc148097 399800161856Syc148097 /* 399900161856Syc148097 * nxge_param_arr[] defines the adv_cap_asmpause with type 400000161856Syc148097 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the 400100161856Syc148097 * "ndd -get" command and can not be changed by ndd. Here we do not 400200161856Syc148097 * assign a constant to it so the default value defined in 400300161856Syc148097 * nxge_param_arr[] will be used to set the parameter and 400400161856Syc148097 * will be shown by the kstat. 400500161856Syc148097 */ 400600161856Syc148097 statsp->mac_stats.adv_cap_asmpause 400700161856Syc148097 = param_arr[param_anar_asmpause].value; 400800161856Syc148097 400900161856Syc148097 /* 401000161856Syc148097 * Initialize the link statistics. 401100161856Syc148097 */ 401200161856Syc148097 statsp->mac_stats.link_T4 = 0; 401300161856Syc148097 statsp->mac_stats.link_asmpause = 0; 401400161856Syc148097 statsp->mac_stats.link_pause = 0; 401500161856Syc148097 if (speed == TN1010_SPEED_1G) { 401600161856Syc148097 statsp->mac_stats.link_speed = 1000; 401700161856Syc148097 statsp->mac_stats.link_duplex = 2; /* Full duplex */ 401800161856Syc148097 statsp->mac_stats.link_up = 1; 401900161856Syc148097 } else { 402000161856Syc148097 statsp->mac_stats.link_speed = 10000; 402100161856Syc148097 statsp->mac_stats.link_duplex = 2; 402200161856Syc148097 statsp->mac_stats.link_up = 1; 402300161856Syc148097 } 402400161856Syc148097 402500161856Syc148097 /* 402600161856Syc148097 * Because TN1010 does not have a link partner register, to 402700161856Syc148097 * figure out the link partner's capabilities is tricky. Here we 402800161856Syc148097 * just set the kstat based on our knowledge about the partner 402900161856Syc148097 * (The partner must support auto-neg because auto-negotiation 403000161856Syc148097 * has completed, it must support 1G or 10G because that is the 403100161856Syc148097 * negotiated speed we are using.) 403200161856Syc148097 * 403300161856Syc148097 * Note: Current kstat does not show lp_cap_10gfdx and 403400161856Syc148097 * lp_cap_10ghdx. 403500161856Syc148097 */ 403600161856Syc148097 if (speed == TN1010_SPEED_1G) { 403700161856Syc148097 statsp->mac_stats.lp_cap_1000fdx = 1; 403800161856Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0; 403900161856Syc148097 } else { 404000161856Syc148097 statsp->mac_stats.lp_cap_1000fdx = 0; 404100161856Syc148097 statsp->mac_stats.lp_cap_10gfdx = 1; 404200161856Syc148097 } 404300161856Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0; 404400161856Syc148097 statsp->mac_stats.lp_cap_1000hdx = 0; 404500161856Syc148097 statsp->mac_stats.lp_cap_100fdx = 0; 404600161856Syc148097 statsp->mac_stats.lp_cap_100hdx = 0; 404700161856Syc148097 statsp->mac_stats.lp_cap_10fdx = 0; 404800161856Syc148097 statsp->mac_stats.lp_cap_10hdx = 0; 404900161856Syc148097 statsp->mac_stats.lp_cap_10gfdx = 0; 405000161856Syc148097 statsp->mac_stats.lp_cap_10ghdx = 0; 405100161856Syc148097 statsp->mac_stats.lp_cap_100T4 = 0; 405200161856Syc148097 statsp->mac_stats.lp_cap_autoneg = 1; 405300161856Syc148097 statsp->mac_stats.lp_cap_asmpause = 0; 405400161856Syc148097 statsp->mac_stats.lp_cap_pause = 0; 405500161856Syc148097 405600161856Syc148097 /* Handle PHY loopback for SunVTS loopback test */ 405700161856Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 405800161856Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 405900161856Syc148097 406000161856Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 406100161856Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG, 406200161856Syc148097 &tn1010_pcs_ctrl.value)) != NXGE_OK) { 406300161856Syc148097 goto fail; 406400161856Syc148097 } 406500161856Syc148097 if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) || 406600161856Syc148097 (statsp->port_stats.lb_mode == nxge_lb_phy10g)) { 406700161856Syc148097 tn1010_pcs_ctrl.bits.loopback = 1; 406800161856Syc148097 } else { 406900161856Syc148097 tn1010_pcs_ctrl.bits.loopback = 0; 407000161856Syc148097 } 407100161856Syc148097 if ((status = nxge_mdio_write(nxgep, phy_port_addr, 407200161856Syc148097 TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG, 407300161856Syc148097 tn1010_pcs_ctrl.value)) != NXGE_OK) { 407400161856Syc148097 goto fail; 407500161856Syc148097 } 407600161856Syc148097 407700161856Syc148097 statsp->mac_stats.xcvr_inits++; 407800161856Syc148097 407900161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 408000161856Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status)); 408100161856Syc148097 return (status); 408200161856Syc148097 fail: 408300161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 408400161856Syc148097 "<== nxge_1G_tn1010_xcvr_init status 0x%x", status)); 408500161856Syc148097 return (status); 408600161856Syc148097 } 408700161856Syc148097 408859ac0c16Sdavemq /* Initialize transceiver */ 40896f45ec7bSml29623 409059ac0c16Sdavemq nxge_status_t 409159ac0c16Sdavemq nxge_xcvr_init(p_nxge_t nxgep) 409259ac0c16Sdavemq { 409359ac0c16Sdavemq p_nxge_stats_t statsp; 409459ac0c16Sdavemq #ifdef NXGE_DEBUG 409559ac0c16Sdavemq uint8_t portn; 409659ac0c16Sdavemq #endif 409759ac0c16Sdavemq 409859ac0c16Sdavemq nxge_status_t status = NXGE_OK; 409959ac0c16Sdavemq #ifdef NXGE_DEBUG 410059ac0c16Sdavemq portn = nxgep->mac.portnum; 410159ac0c16Sdavemq #endif 41026f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 410359ac0c16Sdavemq statsp = nxgep->statsp; 410459ac0c16Sdavemq 410559ac0c16Sdavemq /* 410600161856Syc148097 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will 410700161856Syc148097 * modify mac_stats. 410859ac0c16Sdavemq */ 410959ac0c16Sdavemq statsp->mac_stats.cap_autoneg = 0; 411059ac0c16Sdavemq statsp->mac_stats.cap_100T4 = 0; 411159ac0c16Sdavemq statsp->mac_stats.cap_100fdx = 0; 411259ac0c16Sdavemq statsp->mac_stats.cap_100hdx = 0; 411359ac0c16Sdavemq statsp->mac_stats.cap_10fdx = 0; 411459ac0c16Sdavemq statsp->mac_stats.cap_10hdx = 0; 411559ac0c16Sdavemq statsp->mac_stats.cap_asmpause = 0; 411659ac0c16Sdavemq statsp->mac_stats.cap_pause = 0; 411759ac0c16Sdavemq statsp->mac_stats.cap_1000fdx = 0; 411859ac0c16Sdavemq statsp->mac_stats.cap_1000hdx = 0; 411959ac0c16Sdavemq statsp->mac_stats.cap_10gfdx = 0; 412059ac0c16Sdavemq statsp->mac_stats.cap_10ghdx = 0; 412159ac0c16Sdavemq 412259ac0c16Sdavemq /* 412359ac0c16Sdavemq * Initialize the link statistics. 412459ac0c16Sdavemq */ 412559ac0c16Sdavemq statsp->mac_stats.link_T4 = 0; 412659ac0c16Sdavemq statsp->mac_stats.link_asmpause = 0; 412759ac0c16Sdavemq statsp->mac_stats.link_pause = 0; 412859ac0c16Sdavemq 412959ac0c16Sdavemq if (nxgep->xcvr.xcvr_init) { 413059ac0c16Sdavemq status = nxgep->xcvr.xcvr_init(nxgep); 413159ac0c16Sdavemq if (status != NXGE_OK) 413259ac0c16Sdavemq goto fail; 413359ac0c16Sdavemq statsp->mac_stats.xcvr_inits++; 413459ac0c16Sdavemq } 413559ac0c16Sdavemq 413659ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", 413759ac0c16Sdavemq portn)); 41386f45ec7bSml29623 return (NXGE_OK); 41396f45ec7bSml29623 41406f45ec7bSml29623 fail: 41416f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41426f45ec7bSml29623 "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 41436f45ec7bSml29623 portn)); 41446f45ec7bSml29623 return (status); 41456f45ec7bSml29623 } 41466f45ec7bSml29623 41472e59129aSraghus /* Look for transceiver type */ 41482e59129aSraghus 41492e59129aSraghus nxge_status_t 41502e59129aSraghus nxge_xcvr_find(p_nxge_t nxgep) 41512e59129aSraghus { 4152d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", 4153d81011f0Ssbehera nxgep->mac.portnum)); 41542e59129aSraghus 41552e59129aSraghus if (nxge_get_xcvr_type(nxgep) != NXGE_OK) 41562e59129aSraghus return (NXGE_ERROR); 41572e59129aSraghus 41582e59129aSraghus if (nxge_setup_xcvr_table(nxgep) != NXGE_OK) 41592e59129aSraghus return (NXGE_ERROR); 41602e59129aSraghus 41612e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d", 41622e59129aSraghus nxgep->statsp->mac_stats.xcvr_inuse)); 41632e59129aSraghus return (NXGE_OK); 41642e59129aSraghus } 41656f45ec7bSml29623 41666f45ec7bSml29623 /* Initialize the TxMAC sub-block */ 41676f45ec7bSml29623 41686f45ec7bSml29623 nxge_status_t 41696f45ec7bSml29623 nxge_tx_mac_init(p_nxge_t nxgep) 41706f45ec7bSml29623 { 41716f45ec7bSml29623 npi_attr_t ap; 41726f45ec7bSml29623 uint8_t portn; 41736f45ec7bSml29623 nxge_port_mode_t portmode; 41746f45ec7bSml29623 nxge_port_t portt; 41756f45ec7bSml29623 npi_handle_t handle; 41766f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 41776f45ec7bSml29623 41786f45ec7bSml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 41796f45ec7bSml29623 portt = nxgep->mac.porttype; 41806f45ec7bSml29623 handle = nxgep->npi_handle; 41816f45ec7bSml29623 portmode = nxgep->mac.portmode; 41826f45ec7bSml29623 41836f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 41846f45ec7bSml29623 portn)); 41856f45ec7bSml29623 /* Set Max and Min Frame Size */ 41864202ea4bSsbehera /* 41871bd6825cSml29623 * Use maxframesize to configure the hardware maxframe size 418800161856Syc148097 * and minframesize to configure the hardware minframe size. 41894202ea4bSsbehera */ 41901bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 41911bd6825cSml29623 "==> nxge_tx_mac_init: port<%d> " 41921bd6825cSml29623 "min framesize %d max framesize %d ", 41931bd6825cSml29623 nxgep->mac.minframesize, 41941bd6825cSml29623 nxgep->mac.maxframesize, 41951bd6825cSml29623 portn)); 41966f45ec7bSml29623 41971bd6825cSml29623 SET_MAC_ATTR2(handle, ap, portn, 41981bd6825cSml29623 MAC_PORT_FRAME_SIZE, 41991bd6825cSml29623 nxgep->mac.minframesize, 42001bd6825cSml29623 nxgep->mac.maxframesize, 42011bd6825cSml29623 rs); 42026f45ec7bSml29623 if (rs != NPI_SUCCESS) 42036f45ec7bSml29623 goto fail; 42046f45ec7bSml29623 42056f45ec7bSml29623 if (portt == PORT_TYPE_XMAC) { 42066f45ec7bSml29623 if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 42076f45ec7bSml29623 0)) != NPI_SUCCESS) 42086f45ec7bSml29623 goto fail; 42096f45ec7bSml29623 nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 42106f45ec7bSml29623 if ((portmode == PORT_10G_FIBER) || 42112e59129aSraghus (portmode == PORT_10G_COPPER) || 421200161856Syc148097 (portmode == PORT_10G_TN1010) || 42131c7408c9Stc99174@train (portmode == PORT_HSP_MODE) || 42142e59129aSraghus (portmode == PORT_10G_SERDES)) { 42156f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 42166f45ec7bSml29623 XGMII_IPG_12_15, rs); 42176f45ec7bSml29623 if (rs != NPI_SUCCESS) 42186f45ec7bSml29623 goto fail; 42196f45ec7bSml29623 nxgep->mac.ipg[0] = XGMII_IPG_12_15; 42206f45ec7bSml29623 } else { 42216f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 42226f45ec7bSml29623 MII_GMII_IPG_12, rs); 42236f45ec7bSml29623 if (rs != NPI_SUCCESS) 42246f45ec7bSml29623 goto fail; 42256f45ec7bSml29623 nxgep->mac.ipg[0] = MII_GMII_IPG_12; 42266f45ec7bSml29623 } 42276f45ec7bSml29623 if ((rs = npi_xmac_tx_config(handle, INIT, portn, 42286f45ec7bSml29623 CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 42296f45ec7bSml29623 goto fail; 42306f45ec7bSml29623 nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 42316f45ec7bSml29623 nxgep->mac.maxburstsize = 0; /* not programmable */ 42326f45ec7bSml29623 nxgep->mac.ctrltype = 0; /* not programmable */ 42336f45ec7bSml29623 nxgep->mac.pa_size = 0; /* not programmable */ 42346f45ec7bSml29623 42356f45ec7bSml29623 if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 42366f45ec7bSml29623 != NPI_SUCCESS) 42376f45ec7bSml29623 goto fail; 42386f45ec7bSml29623 42396f45ec7bSml29623 } else { 42406f45ec7bSml29623 if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 42416f45ec7bSml29623 0)) != NPI_SUCCESS) 42426f45ec7bSml29623 goto fail; 42436f45ec7bSml29623 nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 42446f45ec7bSml29623 42456f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 42466f45ec7bSml29623 rs); 42476f45ec7bSml29623 if (rs != NPI_SUCCESS) 42486f45ec7bSml29623 goto fail; 42496f45ec7bSml29623 nxgep->mac.ctrltype = 0x8808; 42506f45ec7bSml29623 42516f45ec7bSml29623 SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 42526f45ec7bSml29623 if (rs != NPI_SUCCESS) 42536f45ec7bSml29623 goto fail; 42546f45ec7bSml29623 nxgep->mac.pa_size = 0x7; 42556f45ec7bSml29623 42566f45ec7bSml29623 if ((rs = npi_bmac_tx_config(handle, INIT, portn, 42576f45ec7bSml29623 CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 42586f45ec7bSml29623 goto fail; 42596f45ec7bSml29623 nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 42606f45ec7bSml29623 } 42616f45ec7bSml29623 42626f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 42636f45ec7bSml29623 portn)); 42646f45ec7bSml29623 42656f45ec7bSml29623 return (NXGE_OK); 42666f45ec7bSml29623 fail: 42676f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 426852ccf843Smisaki "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn)); 42696f45ec7bSml29623 42706f45ec7bSml29623 return (NXGE_ERROR | rs); 42716f45ec7bSml29623 } 42726f45ec7bSml29623 42730dc2366fSVenugopal Iyer static npi_status_t 42740dc2366fSVenugopal Iyer nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep) 42750dc2366fSVenugopal Iyer { 42760dc2366fSVenugopal Iyer uint32_t i; 42770dc2366fSVenugopal Iyer uint16_t hashtab_e; 42780dc2366fSVenugopal Iyer p_hash_filter_t hash_filter; 42790dc2366fSVenugopal Iyer uint8_t portn; 42800dc2366fSVenugopal Iyer npi_handle_t handle; 42810dc2366fSVenugopal Iyer npi_status_t rs = NPI_SUCCESS; 4282678453a8Sspeer 42830dc2366fSVenugopal Iyer portn = NXGE_GET_PORT_NUM(nxgep->function_num); 42840dc2366fSVenugopal Iyer handle = nxgep->npi_handle; 42856f45ec7bSml29623 42860dc2366fSVenugopal Iyer /* 42870dc2366fSVenugopal Iyer * Load the multicast hash filter bits. 42880dc2366fSVenugopal Iyer */ 42890dc2366fSVenugopal Iyer hash_filter = nxgep->hash_filter; 42900dc2366fSVenugopal Iyer for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 42910dc2366fSVenugopal Iyer if (hash_filter != NULL) { 42920dc2366fSVenugopal Iyer hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 42930dc2366fSVenugopal Iyer (NMCFILTER_REGS - 1) - i]; 42940dc2366fSVenugopal Iyer } else { 42950dc2366fSVenugopal Iyer hashtab_e = 0; 42960dc2366fSVenugopal Iyer } 42970dc2366fSVenugopal Iyer 42980dc2366fSVenugopal Iyer if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 42990dc2366fSVenugopal Iyer (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 43000dc2366fSVenugopal Iyer return (rs); 43010dc2366fSVenugopal Iyer } 43020dc2366fSVenugopal Iyer 43030dc2366fSVenugopal Iyer return (NPI_SUCCESS); 43040dc2366fSVenugopal Iyer } 43050dc2366fSVenugopal Iyer 43060dc2366fSVenugopal Iyer /* 43070dc2366fSVenugopal Iyer * Initialize the RxMAC sub-block 43080dc2366fSVenugopal Iyer */ 43096f45ec7bSml29623 nxge_status_t 43106f45ec7bSml29623 nxge_rx_mac_init(p_nxge_t nxgep) 43116f45ec7bSml29623 { 43126f45ec7bSml29623 npi_attr_t ap; 43136f45ec7bSml29623 nxge_port_t portt; 43146f45ec7bSml29623 uint8_t portn; 43156f45ec7bSml29623 npi_handle_t handle; 43166f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 43176f45ec7bSml29623 uint16_t *addr16p; 43186f45ec7bSml29623 uint16_t addr0, addr1, addr2; 43196f45ec7bSml29623 xmac_rx_config_t xconfig; 43206f45ec7bSml29623 bmac_rx_config_t bconfig; 43216f45ec7bSml29623 43226f45ec7bSml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 43236f45ec7bSml29623 43246f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 43256f45ec7bSml29623 portn)); 43266f45ec7bSml29623 handle = nxgep->npi_handle; 43276f45ec7bSml29623 portt = nxgep->mac.porttype; 43286f45ec7bSml29623 43296f45ec7bSml29623 addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 43306f45ec7bSml29623 addr0 = ntohs(addr16p[2]); 43316f45ec7bSml29623 addr1 = ntohs(addr16p[1]); 43326f45ec7bSml29623 addr2 = ntohs(addr16p[0]); 43330dc2366fSVenugopal Iyer SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, 43340dc2366fSVenugopal Iyer addr0, addr1, addr2, rs); 43356f45ec7bSml29623 if (rs != NPI_SUCCESS) 43366f45ec7bSml29623 goto fail; 43376f45ec7bSml29623 SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 43386f45ec7bSml29623 if (rs != NPI_SUCCESS) 43396f45ec7bSml29623 goto fail; 43406f45ec7bSml29623 SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 43416f45ec7bSml29623 if (rs != NPI_SUCCESS) 43426f45ec7bSml29623 goto fail; 43436f45ec7bSml29623 43440dc2366fSVenugopal Iyer rs = nxge_rx_mac_mcast_hash_table(nxgep); 43450dc2366fSVenugopal Iyer if (rs != NPI_SUCCESS) 43466f45ec7bSml29623 goto fail; 43476f45ec7bSml29623 43486f45ec7bSml29623 if (portt == PORT_TYPE_XMAC) { 43496f45ec7bSml29623 if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 43506f45ec7bSml29623 0)) != NPI_SUCCESS) 43516f45ec7bSml29623 goto fail; 43526f45ec7bSml29623 nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 43536f45ec7bSml29623 43546f45ec7bSml29623 (void) nxge_fflp_init_hostinfo(nxgep); 43556f45ec7bSml29623 43566f45ec7bSml29623 xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 43576f45ec7bSml29623 CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 43586f45ec7bSml29623 ~CFG_XMAC_RX_STRIP_CRC; 43596f45ec7bSml29623 43606f45ec7bSml29623 if (nxgep->filter.all_phys_cnt != 0) 43616f45ec7bSml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUS; 43626f45ec7bSml29623 if (nxgep->filter.all_multicast_cnt != 0) 43636f45ec7bSml29623 xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 43646f45ec7bSml29623 43656f45ec7bSml29623 xconfig |= CFG_XMAC_RX_HASH_FILTER; 43666f45ec7bSml29623 43670dc2366fSVenugopal Iyer if ((rs = npi_xmac_rx_config(handle, INIT, 43680dc2366fSVenugopal Iyer portn, xconfig)) != NPI_SUCCESS) 43696f45ec7bSml29623 goto fail; 43706f45ec7bSml29623 nxgep->mac.rx_config = xconfig; 43716f45ec7bSml29623 43720dc2366fSVenugopal Iyer /* 43730dc2366fSVenugopal Iyer * Comparison of mac unique address is always 43740dc2366fSVenugopal Iyer * enabled on XMAC 43750dc2366fSVenugopal Iyer */ 43766f45ec7bSml29623 if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 43776f45ec7bSml29623 != NPI_SUCCESS) 43786f45ec7bSml29623 goto fail; 43796f45ec7bSml29623 } else { 43806f45ec7bSml29623 if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 43816f45ec7bSml29623 0) != NPI_SUCCESS) 43826f45ec7bSml29623 goto fail; 43830dc2366fSVenugopal Iyer 43846f45ec7bSml29623 nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 43856f45ec7bSml29623 43860dc2366fSVenugopal Iyer (void) nxge_fflp_init_hostinfo(nxgep); 43870dc2366fSVenugopal Iyer 43886f45ec7bSml29623 bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 43896f45ec7bSml29623 ~CFG_BMAC_RX_STRIP_CRC; 43906f45ec7bSml29623 43916f45ec7bSml29623 if (nxgep->filter.all_phys_cnt != 0) 43926f45ec7bSml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUS; 43936f45ec7bSml29623 if (nxgep->filter.all_multicast_cnt != 0) 43946f45ec7bSml29623 bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 43956f45ec7bSml29623 43966f45ec7bSml29623 bconfig |= CFG_BMAC_RX_HASH_FILTER; 43970dc2366fSVenugopal Iyer if ((rs = npi_bmac_rx_config(handle, INIT, 43980dc2366fSVenugopal Iyer portn, bconfig)) != NPI_SUCCESS) 43996f45ec7bSml29623 goto fail; 44006f45ec7bSml29623 nxgep->mac.rx_config = bconfig; 44016f45ec7bSml29623 44020dc2366fSVenugopal Iyer /* 44030dc2366fSVenugopal Iyer * Always enable comparison of mac unique address 44040dc2366fSVenugopal Iyer */ 44050dc2366fSVenugopal Iyer if ((rs = npi_mac_altaddr_enable(handle, 44060dc2366fSVenugopal Iyer portn, 0)) != NPI_SUCCESS) 44076f45ec7bSml29623 goto fail; 44086f45ec7bSml29623 } 44096f45ec7bSml29623 44106f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 44116f45ec7bSml29623 portn)); 44126f45ec7bSml29623 44136f45ec7bSml29623 return (NXGE_OK); 44146f45ec7bSml29623 44156f45ec7bSml29623 fail: 44166f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 441752ccf843Smisaki "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn)); 44186f45ec7bSml29623 44196f45ec7bSml29623 return (NXGE_ERROR | rs); 44206f45ec7bSml29623 } 44216f45ec7bSml29623 44226f45ec7bSml29623 /* Enable TXMAC */ 44236f45ec7bSml29623 44246f45ec7bSml29623 nxge_status_t 44256f45ec7bSml29623 nxge_tx_mac_enable(p_nxge_t nxgep) 44266f45ec7bSml29623 { 44276f45ec7bSml29623 npi_handle_t handle; 44286f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 44296f45ec7bSml29623 nxge_status_t status = NXGE_OK; 44306f45ec7bSml29623 44316f45ec7bSml29623 handle = nxgep->npi_handle; 44326f45ec7bSml29623 44336f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 44346f45ec7bSml29623 nxgep->mac.portnum)); 44356f45ec7bSml29623 44366f45ec7bSml29623 if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 44376f45ec7bSml29623 goto fail; 44386f45ec7bSml29623 44396f45ec7bSml29623 /* based on speed */ 44406f45ec7bSml29623 nxgep->msg_min = ETHERMIN; 44416f45ec7bSml29623 44426f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 44436f45ec7bSml29623 if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 44446f45ec7bSml29623 CFG_XMAC_TX)) != NPI_SUCCESS) 44456f45ec7bSml29623 goto fail; 44466f45ec7bSml29623 } else { 44476f45ec7bSml29623 if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 44486f45ec7bSml29623 CFG_BMAC_TX)) != NPI_SUCCESS) 44496f45ec7bSml29623 goto fail; 44506f45ec7bSml29623 } 44516f45ec7bSml29623 44526f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 44536f45ec7bSml29623 nxgep->mac.portnum)); 44546f45ec7bSml29623 44556f45ec7bSml29623 return (NXGE_OK); 44566f45ec7bSml29623 fail: 44576f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 44586f45ec7bSml29623 "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 44596f45ec7bSml29623 nxgep->mac.portnum)); 44606f45ec7bSml29623 if (rs != NPI_SUCCESS) 44616f45ec7bSml29623 return (NXGE_ERROR | rs); 44626f45ec7bSml29623 else 44636f45ec7bSml29623 return (status); 44646f45ec7bSml29623 } 44656f45ec7bSml29623 44666f45ec7bSml29623 /* Disable TXMAC */ 44676f45ec7bSml29623 44686f45ec7bSml29623 nxge_status_t 44696f45ec7bSml29623 nxge_tx_mac_disable(p_nxge_t nxgep) 44706f45ec7bSml29623 { 44716f45ec7bSml29623 npi_handle_t handle; 44726f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 44736f45ec7bSml29623 4474678453a8Sspeer if (isLDOMguest(nxgep)) 4475678453a8Sspeer return (NXGE_OK); 4476678453a8Sspeer 44776f45ec7bSml29623 handle = nxgep->npi_handle; 44786f45ec7bSml29623 44796f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 44806f45ec7bSml29623 nxgep->mac.portnum)); 44816f45ec7bSml29623 44826f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 44836f45ec7bSml29623 if ((rs = npi_xmac_tx_config(handle, DISABLE, 44846f45ec7bSml29623 nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 44856f45ec7bSml29623 goto fail; 44866f45ec7bSml29623 } else { 44876f45ec7bSml29623 if ((rs = npi_bmac_tx_config(handle, DISABLE, 44886f45ec7bSml29623 nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 44896f45ec7bSml29623 goto fail; 44906f45ec7bSml29623 } 44916f45ec7bSml29623 44926f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 44936f45ec7bSml29623 nxgep->mac.portnum)); 44946f45ec7bSml29623 return (NXGE_OK); 44956f45ec7bSml29623 fail: 44966f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 44976f45ec7bSml29623 "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 44986f45ec7bSml29623 nxgep->mac.portnum)); 44996f45ec7bSml29623 return (NXGE_ERROR | rs); 45006f45ec7bSml29623 } 45016f45ec7bSml29623 45026f45ec7bSml29623 /* Enable RXMAC */ 45036f45ec7bSml29623 45046f45ec7bSml29623 nxge_status_t 45056f45ec7bSml29623 nxge_rx_mac_enable(p_nxge_t nxgep) 45066f45ec7bSml29623 { 45076f45ec7bSml29623 npi_handle_t handle; 45086f45ec7bSml29623 uint8_t portn; 45096f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 45106f45ec7bSml29623 nxge_status_t status = NXGE_OK; 45116f45ec7bSml29623 4512678453a8Sspeer /* This is a service-domain-only activity. */ 4513678453a8Sspeer if (isLDOMguest(nxgep)) 4514678453a8Sspeer return (status); 4515678453a8Sspeer 45166f45ec7bSml29623 handle = nxgep->npi_handle; 45176f45ec7bSml29623 portn = nxgep->mac.portnum; 45186f45ec7bSml29623 45196f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 45206f45ec7bSml29623 portn)); 45216f45ec7bSml29623 45226f45ec7bSml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 45236f45ec7bSml29623 goto fail; 45246f45ec7bSml29623 45256f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 45266f45ec7bSml29623 if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 45276f45ec7bSml29623 CFG_XMAC_RX)) != NPI_SUCCESS) 45286f45ec7bSml29623 goto fail; 45296f45ec7bSml29623 } else { 45306f45ec7bSml29623 if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 45316f45ec7bSml29623 CFG_BMAC_RX)) != NPI_SUCCESS) 45326f45ec7bSml29623 goto fail; 45336f45ec7bSml29623 } 45346f45ec7bSml29623 4535678453a8Sspeer NXGE_DEBUG_MSG((nxgep, MAC_CTL, 4536678453a8Sspeer "<== nxge_rx_mac_enable: port<%d>", portn)); 45376f45ec7bSml29623 45386f45ec7bSml29623 return (NXGE_OK); 45396f45ec7bSml29623 fail: 45406f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4541678453a8Sspeer "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn)); 45426f45ec7bSml29623 45436f45ec7bSml29623 if (rs != NPI_SUCCESS) 45446f45ec7bSml29623 return (NXGE_ERROR | rs); 45456f45ec7bSml29623 else 45466f45ec7bSml29623 return (status); 45476f45ec7bSml29623 } 45486f45ec7bSml29623 45496f45ec7bSml29623 /* Disable RXMAC */ 45506f45ec7bSml29623 45516f45ec7bSml29623 nxge_status_t 45526f45ec7bSml29623 nxge_rx_mac_disable(p_nxge_t nxgep) 45536f45ec7bSml29623 { 45546f45ec7bSml29623 npi_handle_t handle; 45556f45ec7bSml29623 uint8_t portn; 45566f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 45576f45ec7bSml29623 4558678453a8Sspeer /* If we are a guest domain driver, don't bother. */ 4559678453a8Sspeer if (isLDOMguest(nxgep)) 4560678453a8Sspeer return (NXGE_OK); 4561678453a8Sspeer 45626f45ec7bSml29623 handle = nxgep->npi_handle; 45636f45ec7bSml29623 portn = nxgep->mac.portnum; 45646f45ec7bSml29623 45656f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 45666f45ec7bSml29623 portn)); 45676f45ec7bSml29623 45686f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 45696f45ec7bSml29623 if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 45706f45ec7bSml29623 CFG_XMAC_RX)) != NPI_SUCCESS) 45716f45ec7bSml29623 goto fail; 45726f45ec7bSml29623 } else { 45736f45ec7bSml29623 if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 45746f45ec7bSml29623 CFG_BMAC_RX)) != NPI_SUCCESS) 45756f45ec7bSml29623 goto fail; 45766f45ec7bSml29623 } 45776f45ec7bSml29623 45786f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 45796f45ec7bSml29623 portn)); 45806f45ec7bSml29623 return (NXGE_OK); 45816f45ec7bSml29623 fail: 45826f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 458352ccf843Smisaki "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn)); 45846f45ec7bSml29623 45856f45ec7bSml29623 return (NXGE_ERROR | rs); 45866f45ec7bSml29623 } 45876f45ec7bSml29623 45886f45ec7bSml29623 /* Reset TXMAC */ 45896f45ec7bSml29623 45906f45ec7bSml29623 nxge_status_t 45916f45ec7bSml29623 nxge_tx_mac_reset(p_nxge_t nxgep) 45926f45ec7bSml29623 { 45936f45ec7bSml29623 npi_handle_t handle; 45946f45ec7bSml29623 uint8_t portn; 45956f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 45966f45ec7bSml29623 45976f45ec7bSml29623 handle = nxgep->npi_handle; 45986f45ec7bSml29623 portn = nxgep->mac.portnum; 45996f45ec7bSml29623 46006f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 46016f45ec7bSml29623 portn)); 46026f45ec7bSml29623 46036f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 46046f45ec7bSml29623 if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 46056f45ec7bSml29623 != NPI_SUCCESS) 46066f45ec7bSml29623 goto fail; 46076f45ec7bSml29623 } else { 46086f45ec7bSml29623 if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 46096f45ec7bSml29623 != NPI_SUCCESS) 46106f45ec7bSml29623 goto fail; 46116f45ec7bSml29623 } 46126f45ec7bSml29623 46136f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 46146f45ec7bSml29623 portn)); 46156f45ec7bSml29623 46166f45ec7bSml29623 return (NXGE_OK); 46176f45ec7bSml29623 fail: 46186f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 461952ccf843Smisaki "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn)); 46206f45ec7bSml29623 46216f45ec7bSml29623 return (NXGE_ERROR | rs); 46226f45ec7bSml29623 } 46236f45ec7bSml29623 46246f45ec7bSml29623 /* Reset RXMAC */ 46256f45ec7bSml29623 46266f45ec7bSml29623 nxge_status_t 46276f45ec7bSml29623 nxge_rx_mac_reset(p_nxge_t nxgep) 46286f45ec7bSml29623 { 46296f45ec7bSml29623 npi_handle_t handle; 46306f45ec7bSml29623 uint8_t portn; 46316f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 46326f45ec7bSml29623 46336f45ec7bSml29623 handle = nxgep->npi_handle; 46346f45ec7bSml29623 portn = nxgep->mac.portnum; 46356f45ec7bSml29623 46366f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 46376f45ec7bSml29623 portn)); 46386f45ec7bSml29623 46396f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 46406f45ec7bSml29623 if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 46416f45ec7bSml29623 != NPI_SUCCESS) 46426f45ec7bSml29623 goto fail; 46436f45ec7bSml29623 } else { 46446f45ec7bSml29623 if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 46456f45ec7bSml29623 != NPI_SUCCESS) 46466f45ec7bSml29623 goto fail; 46476f45ec7bSml29623 } 46486f45ec7bSml29623 46496f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 46506f45ec7bSml29623 portn)); 46516f45ec7bSml29623 46526f45ec7bSml29623 return (NXGE_OK); 46536f45ec7bSml29623 fail: 46546f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 465552ccf843Smisaki "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn)); 46566f45ec7bSml29623 return (NXGE_ERROR | rs); 46576f45ec7bSml29623 } 46586f45ec7bSml29623 465959ac0c16Sdavemq /* 10G fiber link interrupt start routine */ 46606f45ec7bSml29623 466159ac0c16Sdavemq static nxge_status_t 466259ac0c16Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep) 466359ac0c16Sdavemq { 466459ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 466559ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 466659ac0c16Sdavemq 466759ac0c16Sdavemq rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 466859ac0c16Sdavemq 466959ac0c16Sdavemq if (rs != NPI_SUCCESS) 467059ac0c16Sdavemq return (NXGE_ERROR | rs); 467159ac0c16Sdavemq else 467259ac0c16Sdavemq return (NXGE_OK); 467359ac0c16Sdavemq } 467459ac0c16Sdavemq 467559ac0c16Sdavemq /* 10G fiber link interrupt stop routine */ 467659ac0c16Sdavemq 467759ac0c16Sdavemq static nxge_status_t 467859ac0c16Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep) 467959ac0c16Sdavemq { 468059ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 468159ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 468259ac0c16Sdavemq 468359ac0c16Sdavemq rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 468459ac0c16Sdavemq 468559ac0c16Sdavemq if (rs != NPI_SUCCESS) 468659ac0c16Sdavemq return (NXGE_ERROR | rs); 468759ac0c16Sdavemq else 468859ac0c16Sdavemq return (NXGE_OK); 468959ac0c16Sdavemq } 469059ac0c16Sdavemq 469159ac0c16Sdavemq /* 1G fiber link interrupt start routine */ 469259ac0c16Sdavemq 469359ac0c16Sdavemq static nxge_status_t 469459ac0c16Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 469559ac0c16Sdavemq { 469659ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 469759ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 469859ac0c16Sdavemq 469959ac0c16Sdavemq rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 470059ac0c16Sdavemq if (rs != NPI_SUCCESS) 470159ac0c16Sdavemq return (NXGE_ERROR | rs); 470259ac0c16Sdavemq else 470359ac0c16Sdavemq return (NXGE_OK); 470459ac0c16Sdavemq } 470559ac0c16Sdavemq 470659ac0c16Sdavemq /* 1G fiber link interrupt stop routine */ 470759ac0c16Sdavemq 470859ac0c16Sdavemq static nxge_status_t 470959ac0c16Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 471059ac0c16Sdavemq { 471159ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 471259ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 471359ac0c16Sdavemq 471459ac0c16Sdavemq rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 471559ac0c16Sdavemq 471659ac0c16Sdavemq if (rs != NPI_SUCCESS) 471759ac0c16Sdavemq return (NXGE_ERROR | rs); 471859ac0c16Sdavemq else 471959ac0c16Sdavemq return (NXGE_OK); 472059ac0c16Sdavemq } 472159ac0c16Sdavemq 472259ac0c16Sdavemq /* 1G copper link interrupt start routine */ 472359ac0c16Sdavemq 472459ac0c16Sdavemq static nxge_status_t 472559ac0c16Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 472659ac0c16Sdavemq { 472759ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 472859ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 472959ac0c16Sdavemq 473059ac0c16Sdavemq rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 47316b438925Ssbehera MII_STATUS, MII_STATUS_LINKUP); 473259ac0c16Sdavemq 473359ac0c16Sdavemq if (rs != NPI_SUCCESS) 473459ac0c16Sdavemq return (NXGE_ERROR | rs); 473559ac0c16Sdavemq else 473659ac0c16Sdavemq return (NXGE_OK); 473759ac0c16Sdavemq } 473859ac0c16Sdavemq 473959ac0c16Sdavemq /* 1G copper link interrupt stop routine */ 474059ac0c16Sdavemq 474159ac0c16Sdavemq static nxge_status_t 474259ac0c16Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 474359ac0c16Sdavemq { 474459ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 474559ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 474659ac0c16Sdavemq 474759ac0c16Sdavemq rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 474859ac0c16Sdavemq 474959ac0c16Sdavemq if (rs != NPI_SUCCESS) 475059ac0c16Sdavemq return (NXGE_ERROR | rs); 475159ac0c16Sdavemq else 475259ac0c16Sdavemq return (NXGE_OK); 475359ac0c16Sdavemq } 475459ac0c16Sdavemq 475559ac0c16Sdavemq /* Enable/Disable Link Status change interrupt */ 47566f45ec7bSml29623 47576f45ec7bSml29623 nxge_status_t 47586f45ec7bSml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 47596f45ec7bSml29623 { 47606f45ec7bSml29623 uint8_t portn; 476159ac0c16Sdavemq nxge_status_t status = NXGE_OK; 47626f45ec7bSml29623 47636f45ec7bSml29623 portn = nxgep->mac.portnum; 47646f45ec7bSml29623 47656f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 476659ac0c16Sdavemq if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 476759ac0c16Sdavemq return (NXGE_OK); 47686f45ec7bSml29623 476959ac0c16Sdavemq if (enable == LINK_INTR_START) 477059ac0c16Sdavemq status = nxgep->xcvr.link_intr_start(nxgep); 477159ac0c16Sdavemq else if (enable == LINK_INTR_STOP) 477259ac0c16Sdavemq status = nxgep->xcvr.link_intr_stop(nxgep); 477359ac0c16Sdavemq if (status != NXGE_OK) 47746f45ec7bSml29623 goto fail; 47756f45ec7bSml29623 47766f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 47776f45ec7bSml29623 47786f45ec7bSml29623 return (NXGE_OK); 47796f45ec7bSml29623 fail: 47806f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 478152ccf843Smisaki "nxge_link_intr: Failed to set port<%d> mif intr mode", portn)); 47826f45ec7bSml29623 478359ac0c16Sdavemq return (status); 47846f45ec7bSml29623 } 47856f45ec7bSml29623 47866f45ec7bSml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 47876f45ec7bSml29623 47886f45ec7bSml29623 nxge_status_t 47896f45ec7bSml29623 nxge_mii_xcvr_init(p_nxge_t nxgep) 47906f45ec7bSml29623 { 47916f45ec7bSml29623 p_nxge_param_t param_arr; 47926f45ec7bSml29623 p_nxge_stats_t statsp; 47936f45ec7bSml29623 uint8_t xcvr_portn; 47946f45ec7bSml29623 p_mii_regs_t mii_regs; 47956f45ec7bSml29623 mii_bmcr_t bmcr; 47966f45ec7bSml29623 mii_bmsr_t bmsr; 47976f45ec7bSml29623 mii_anar_t anar; 47986f45ec7bSml29623 mii_gcr_t gcr; 47996f45ec7bSml29623 mii_esr_t esr; 48006f45ec7bSml29623 mii_aux_ctl_t bcm5464r_aux; 48016f45ec7bSml29623 int status = NXGE_OK; 48026f45ec7bSml29623 48036f45ec7bSml29623 uint_t delay; 48046f45ec7bSml29623 48056f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 48066f45ec7bSml29623 48076f45ec7bSml29623 param_arr = nxgep->param_arr; 48086f45ec7bSml29623 statsp = nxgep->statsp; 48096f45ec7bSml29623 xcvr_portn = statsp->mac_stats.xcvr_portn; 48106f45ec7bSml29623 48116f45ec7bSml29623 mii_regs = NULL; 48126f45ec7bSml29623 48136f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 48146f45ec7bSml29623 "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 48156f45ec7bSml29623 48166f45ec7bSml29623 /* 4817d81011f0Ssbehera * The mif phy mode may be connected to either a copper link 4818d81011f0Ssbehera * or fiber link. Read the mode control register to get the fiber 4819d81011f0Ssbehera * configuration if it is hard-wired to fiber link. 4820d81011f0Ssbehera */ 4821d81011f0Ssbehera (void) nxge_mii_get_link_mode(nxgep); 4822d81011f0Ssbehera if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 4823d81011f0Ssbehera return (nxge_mii_xcvr_fiber_init(nxgep)); 4824d81011f0Ssbehera } 4825d81011f0Ssbehera 4826d81011f0Ssbehera /* 48276f45ec7bSml29623 * Reset the transceiver. 48286f45ec7bSml29623 */ 48296f45ec7bSml29623 delay = 0; 48306f45ec7bSml29623 bmcr.value = 0; 48316f45ec7bSml29623 bmcr.bits.reset = 1; 48326f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 4833adfcba55Sjoycey #if defined(__i386) 483452ccf843Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr, 4835adfcba55Sjoycey #else 483652ccf843Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr, 4837adfcba55Sjoycey #endif 483852ccf843Smisaki bmcr.value)) != NXGE_OK) 48396f45ec7bSml29623 goto fail; 48406f45ec7bSml29623 do { 48416f45ec7bSml29623 drv_usecwait(500); 48426f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 4843adfcba55Sjoycey #if defined(__i386) 484452ccf843Smisaki (uint8_t)(uint32_t)&mii_regs->bmcr, 4845adfcba55Sjoycey #else 484652ccf843Smisaki (uint8_t)(uint64_t)&mii_regs->bmcr, 4847adfcba55Sjoycey #endif 484852ccf843Smisaki &bmcr.value)) != NXGE_OK) 48496f45ec7bSml29623 goto fail; 48506f45ec7bSml29623 delay++; 48516f45ec7bSml29623 } while ((bmcr.bits.reset) && (delay < 1000)); 48526f45ec7bSml29623 if (delay == 1000) { 48536f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 48546f45ec7bSml29623 goto fail; 48556f45ec7bSml29623 } 48566f45ec7bSml29623 48576f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 4858adfcba55Sjoycey #if defined(__i386) 4859adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 4860adfcba55Sjoycey #else 48616f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->bmsr), 4862adfcba55Sjoycey #endif 48636f45ec7bSml29623 &bmsr.value)) != NXGE_OK) 48646f45ec7bSml29623 goto fail; 48656f45ec7bSml29623 48666f45ec7bSml29623 param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 48676f45ec7bSml29623 param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 48686f45ec7bSml29623 param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 48696f45ec7bSml29623 param_arr[param_anar_100hdx].value = 0; 48706f45ec7bSml29623 param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 48716f45ec7bSml29623 param_arr[param_anar_10hdx].value = 0; 48726f45ec7bSml29623 48736f45ec7bSml29623 /* 48746f45ec7bSml29623 * Initialize the xcvr statistics. 48756f45ec7bSml29623 */ 48766f45ec7bSml29623 statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 48776f45ec7bSml29623 statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 48786f45ec7bSml29623 statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 48796f45ec7bSml29623 statsp->mac_stats.cap_100hdx = 0; 48806f45ec7bSml29623 statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 48816f45ec7bSml29623 statsp->mac_stats.cap_10hdx = 0; 48826f45ec7bSml29623 statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 48836f45ec7bSml29623 statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 48846f45ec7bSml29623 48856f45ec7bSml29623 /* 488600161856Syc148097 * Initialize the xcvr advertised capability statistics. 48876f45ec7bSml29623 */ 48886f45ec7bSml29623 statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 48896f45ec7bSml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 48906f45ec7bSml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 48916f45ec7bSml29623 statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 48926f45ec7bSml29623 statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 48936f45ec7bSml29623 statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 48946f45ec7bSml29623 statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 48956f45ec7bSml29623 statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 48966f45ec7bSml29623 statsp->mac_stats.adv_cap_asmpause = 48976f45ec7bSml29623 param_arr[param_anar_asmpause].value; 48986f45ec7bSml29623 statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 48996f45ec7bSml29623 49006f45ec7bSml29623 49016f45ec7bSml29623 /* 49026f45ec7bSml29623 * Check for extended status just in case we're 49036f45ec7bSml29623 * running a Gigibit phy. 49046f45ec7bSml29623 */ 49056f45ec7bSml29623 if (bmsr.bits.extend_status) { 49066f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 4907adfcba55Sjoycey #if defined(__i386) 490852ccf843Smisaki (uint8_t)(uint32_t)(&mii_regs->esr), 4909adfcba55Sjoycey #else 491052ccf843Smisaki (uint8_t)(uint64_t)(&mii_regs->esr), 4911adfcba55Sjoycey #endif 491252ccf843Smisaki &esr.value)) != NXGE_OK) 49136f45ec7bSml29623 goto fail; 491452ccf843Smisaki param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx; 49156f45ec7bSml29623 param_arr[param_anar_1000hdx].value = 0; 49166f45ec7bSml29623 49176f45ec7bSml29623 statsp->mac_stats.cap_1000fdx = 491852ccf843Smisaki (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 49196f45ec7bSml29623 statsp->mac_stats.cap_1000hdx = 0; 49206f45ec7bSml29623 } else { 49216f45ec7bSml29623 param_arr[param_anar_1000fdx].value = 0; 49226f45ec7bSml29623 param_arr[param_anar_1000hdx].value = 0; 49236f45ec7bSml29623 } 49246f45ec7bSml29623 49256f45ec7bSml29623 /* 49266f45ec7bSml29623 * Initialize 1G Statistics once the capability is established. 49276f45ec7bSml29623 */ 49286f45ec7bSml29623 statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 49296f45ec7bSml29623 statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 49306f45ec7bSml29623 49316f45ec7bSml29623 /* 493200161856Syc148097 * Initialize the link statistics. 49336f45ec7bSml29623 */ 49346f45ec7bSml29623 statsp->mac_stats.link_T4 = 0; 49356f45ec7bSml29623 statsp->mac_stats.link_asmpause = 0; 49366f45ec7bSml29623 statsp->mac_stats.link_pause = 0; 49376f45ec7bSml29623 statsp->mac_stats.link_speed = 0; 49386f45ec7bSml29623 statsp->mac_stats.link_duplex = 0; 49396f45ec7bSml29623 statsp->mac_stats.link_up = 0; 49406f45ec7bSml29623 49416f45ec7bSml29623 /* 49426f45ec7bSml29623 * Switch off Auto-negotiation, 100M and full duplex. 49436f45ec7bSml29623 */ 49446f45ec7bSml29623 bmcr.value = 0; 49456f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 4946adfcba55Sjoycey #if defined(__i386) 494752ccf843Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 4948adfcba55Sjoycey #else 494952ccf843Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 4950adfcba55Sjoycey #endif 495152ccf843Smisaki bmcr.value)) != NXGE_OK) 49526f45ec7bSml29623 goto fail; 49536f45ec7bSml29623 49546f45ec7bSml29623 if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 49556f45ec7bSml29623 (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 49566f45ec7bSml29623 bmcr.bits.loopback = 1; 49576f45ec7bSml29623 bmcr.bits.enable_autoneg = 0; 49586f45ec7bSml29623 if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 49596f45ec7bSml29623 bmcr.bits.speed_1000_sel = 1; 49606f45ec7bSml29623 bmcr.bits.duplex_mode = 1; 49616f45ec7bSml29623 param_arr[param_autoneg].value = 0; 49626f45ec7bSml29623 } else { 49636f45ec7bSml29623 bmcr.bits.loopback = 0; 49646f45ec7bSml29623 } 49656f45ec7bSml29623 49666f45ec7bSml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 49676f45ec7bSml29623 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 49686f45ec7bSml29623 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 49696f45ec7bSml29623 param_arr[param_autoneg].value = 0; 49706f45ec7bSml29623 bcm5464r_aux.value = 0; 49716f45ec7bSml29623 bcm5464r_aux.bits.ext_lb = 1; 49726f45ec7bSml29623 bcm5464r_aux.bits.write_1 = 1; 49736f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 497452ccf843Smisaki BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 49756f45ec7bSml29623 goto fail; 49766f45ec7bSml29623 } 49776f45ec7bSml29623 497800161856Syc148097 /* If auto-negotiation is desired */ 49796f45ec7bSml29623 if (param_arr[param_autoneg].value) { 49806f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 49816f45ec7bSml29623 "Restarting Auto-negotiation.")); 49826f45ec7bSml29623 /* 49836f45ec7bSml29623 * Setup our Auto-negotiation advertisement register. 49846f45ec7bSml29623 */ 49856f45ec7bSml29623 anar.value = 0; 49866f45ec7bSml29623 anar.bits.selector = 1; 49876f45ec7bSml29623 anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 49886f45ec7bSml29623 anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 49896f45ec7bSml29623 anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 49906f45ec7bSml29623 anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 49916f45ec7bSml29623 anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 49926f45ec7bSml29623 anar.bits.cap_asmpause = 0; 49936f45ec7bSml29623 anar.bits.cap_pause = 0; 49946f45ec7bSml29623 if (param_arr[param_anar_1000fdx].value || 49956f45ec7bSml29623 param_arr[param_anar_100fdx].value || 49966f45ec7bSml29623 param_arr[param_anar_10fdx].value) { 49976f45ec7bSml29623 anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 49986f45ec7bSml29623 anar.bits.cap_pause = statsp->mac_stats.cap_pause; 49996f45ec7bSml29623 } 50006f45ec7bSml29623 500100161856Syc148097 /* Write to the auto-negotiation advertisement register */ 50026f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5003adfcba55Sjoycey #if defined(__i386) 500452ccf843Smisaki (uint8_t)(uint32_t)(&mii_regs->anar), 5005adfcba55Sjoycey #else 500652ccf843Smisaki (uint8_t)(uint64_t)(&mii_regs->anar), 5007adfcba55Sjoycey #endif 500852ccf843Smisaki anar.value)) != NXGE_OK) 50096f45ec7bSml29623 goto fail; 50106f45ec7bSml29623 if (bmsr.bits.extend_status) { 50116f45ec7bSml29623 gcr.value = 0; 50126f45ec7bSml29623 gcr.bits.ms_mode_en = 50136f45ec7bSml29623 param_arr[param_master_cfg_enable].value; 50146f45ec7bSml29623 gcr.bits.master = 50156f45ec7bSml29623 param_arr[param_master_cfg_value].value; 50166f45ec7bSml29623 gcr.bits.link_1000fdx = 50176f45ec7bSml29623 param_arr[param_anar_1000fdx].value; 50186f45ec7bSml29623 gcr.bits.link_1000hdx = 50196f45ec7bSml29623 param_arr[param_anar_1000hdx].value; 50206f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5021adfcba55Sjoycey #if defined(__i386) 502252ccf843Smisaki (uint8_t)(uint32_t)(&mii_regs->gcr), 5023adfcba55Sjoycey #else 502452ccf843Smisaki (uint8_t)(uint64_t)(&mii_regs->gcr), 5025adfcba55Sjoycey #endif 502652ccf843Smisaki gcr.value)) != NXGE_OK) 50276f45ec7bSml29623 goto fail; 50286f45ec7bSml29623 } 50296f45ec7bSml29623 50306f45ec7bSml29623 bmcr.bits.enable_autoneg = 1; 50316f45ec7bSml29623 bmcr.bits.restart_autoneg = 1; 50326f45ec7bSml29623 50336f45ec7bSml29623 } else { 50346f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 50356f45ec7bSml29623 bmcr.bits.speed_1000_sel = 50366f45ec7bSml29623 param_arr[param_anar_1000fdx].value | 50376f45ec7bSml29623 param_arr[param_anar_1000hdx].value; 50386f45ec7bSml29623 bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 50396f45ec7bSml29623 (param_arr[param_anar_100fdx].value | 50406f45ec7bSml29623 param_arr[param_anar_100hdx].value); 504100161856Syc148097 504200161856Syc148097 /* Force to 1G */ 50436f45ec7bSml29623 if (bmcr.bits.speed_1000_sel) { 50446f45ec7bSml29623 statsp->mac_stats.link_speed = 1000; 50456f45ec7bSml29623 gcr.value = 0; 50466f45ec7bSml29623 gcr.bits.ms_mode_en = 50476f45ec7bSml29623 param_arr[param_master_cfg_enable].value; 50486f45ec7bSml29623 gcr.bits.master = 50496f45ec7bSml29623 param_arr[param_master_cfg_value].value; 50506f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5051adfcba55Sjoycey #if defined(__i386) 5052adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->gcr), 5053adfcba55Sjoycey #else 50546f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->gcr), 5055adfcba55Sjoycey #endif 505652ccf843Smisaki gcr.value)) != NXGE_OK) 50576f45ec7bSml29623 goto fail; 50586f45ec7bSml29623 if (param_arr[param_anar_1000fdx].value) { 50596f45ec7bSml29623 bmcr.bits.duplex_mode = 1; 50606f45ec7bSml29623 statsp->mac_stats.link_duplex = 2; 50616f45ec7bSml29623 } else 50626f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 506300161856Syc148097 506400161856Syc148097 /* Force to 100M */ 50656f45ec7bSml29623 } else if (bmcr.bits.speed_sel) { 50666f45ec7bSml29623 statsp->mac_stats.link_speed = 100; 50676f45ec7bSml29623 if (param_arr[param_anar_100fdx].value) { 50686f45ec7bSml29623 bmcr.bits.duplex_mode = 1; 50696f45ec7bSml29623 statsp->mac_stats.link_duplex = 2; 50706f45ec7bSml29623 } else 50716f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 507200161856Syc148097 507300161856Syc148097 /* Force to 10M */ 50746f45ec7bSml29623 } else { 50756f45ec7bSml29623 statsp->mac_stats.link_speed = 10; 50766f45ec7bSml29623 if (param_arr[param_anar_10fdx].value) { 50776f45ec7bSml29623 bmcr.bits.duplex_mode = 1; 50786f45ec7bSml29623 statsp->mac_stats.link_duplex = 2; 50796f45ec7bSml29623 } else 50806f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 50816f45ec7bSml29623 } 50826f45ec7bSml29623 if (statsp->mac_stats.link_duplex != 1) { 50836f45ec7bSml29623 statsp->mac_stats.link_asmpause = 50846f45ec7bSml29623 statsp->mac_stats.cap_asmpause; 50856f45ec7bSml29623 statsp->mac_stats.link_pause = 50866f45ec7bSml29623 statsp->mac_stats.cap_pause; 50876f45ec7bSml29623 } 50886f45ec7bSml29623 50896f45ec7bSml29623 if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 50906f45ec7bSml29623 (statsp->port_stats.lb_mode == nxge_lb_ext100) || 50916f45ec7bSml29623 (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 50926f45ec7bSml29623 if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 50936f45ec7bSml29623 /* BCM5464R 1000mbps external loopback mode */ 50946f45ec7bSml29623 gcr.value = 0; 50956f45ec7bSml29623 gcr.bits.ms_mode_en = 1; 50966f45ec7bSml29623 gcr.bits.master = 1; 50976f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5098adfcba55Sjoycey #if defined(__i386) 5099adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->gcr), 5100adfcba55Sjoycey #else 51016f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->gcr), 5102adfcba55Sjoycey #endif 510352ccf843Smisaki gcr.value)) != NXGE_OK) 51046f45ec7bSml29623 goto fail; 51056f45ec7bSml29623 bmcr.value = 0; 51066f45ec7bSml29623 bmcr.bits.speed_1000_sel = 1; 51076f45ec7bSml29623 statsp->mac_stats.link_speed = 1000; 51086f45ec7bSml29623 } else if (statsp->port_stats.lb_mode 51096f45ec7bSml29623 == nxge_lb_ext100) { 51106f45ec7bSml29623 /* BCM5464R 100mbps external loopback mode */ 51116f45ec7bSml29623 bmcr.value = 0; 51126f45ec7bSml29623 bmcr.bits.speed_sel = 1; 51136f45ec7bSml29623 bmcr.bits.duplex_mode = 1; 51146f45ec7bSml29623 statsp->mac_stats.link_speed = 100; 51156f45ec7bSml29623 } else if (statsp->port_stats.lb_mode 51166f45ec7bSml29623 == nxge_lb_ext10) { 51176f45ec7bSml29623 /* BCM5464R 10mbps external loopback mode */ 51186f45ec7bSml29623 bmcr.value = 0; 51196f45ec7bSml29623 bmcr.bits.duplex_mode = 1; 51206f45ec7bSml29623 statsp->mac_stats.link_speed = 10; 51216f45ec7bSml29623 } 51226f45ec7bSml29623 } 51236f45ec7bSml29623 } 51246f45ec7bSml29623 51256f45ec7bSml29623 if ((status = nxge_mii_write(nxgep, xcvr_portn, 5126adfcba55Sjoycey #if defined(__i386) 5127adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmcr), 5128adfcba55Sjoycey #else 51296f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->bmcr), 5130adfcba55Sjoycey #endif 51316f45ec7bSml29623 bmcr.value)) != NXGE_OK) 51326f45ec7bSml29623 goto fail; 51336f45ec7bSml29623 51346f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 5135adfcba55Sjoycey #if defined(__i386) 513652ccf843Smisaki (uint8_t)(uint32_t)(&mii_regs->bmcr), 5137adfcba55Sjoycey #else 513852ccf843Smisaki (uint8_t)(uint64_t)(&mii_regs->bmcr), 5139adfcba55Sjoycey #endif 514052ccf843Smisaki &bmcr.value)) != NXGE_OK) 51416f45ec7bSml29623 goto fail; 51426f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 51436f45ec7bSml29623 51446f45ec7bSml29623 /* 51456f45ec7bSml29623 * Initialize the xcvr status kept in the context structure. 51466f45ec7bSml29623 */ 51476f45ec7bSml29623 nxgep->soft_bmsr.value = 0; 51486f45ec7bSml29623 51496f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, xcvr_portn, 5150adfcba55Sjoycey #if defined(__i386) 5151adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 5152adfcba55Sjoycey #else 51536f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->bmsr), 5154adfcba55Sjoycey #endif 51556f45ec7bSml29623 &nxgep->bmsr.value)) != NXGE_OK) 51566f45ec7bSml29623 goto fail; 51576f45ec7bSml29623 51586f45ec7bSml29623 statsp->mac_stats.xcvr_inits++; 51596f45ec7bSml29623 nxgep->bmsr.value = 0; 51606f45ec7bSml29623 51616f45ec7bSml29623 fail: 51626f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 51636f45ec7bSml29623 "<== nxge_mii_xcvr_init status 0x%x", status)); 51646f45ec7bSml29623 return (status); 51656f45ec7bSml29623 } 51666f45ec7bSml29623 5167d81011f0Ssbehera nxge_status_t 5168d81011f0Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep) 5169d81011f0Ssbehera { 5170d81011f0Ssbehera p_nxge_param_t param_arr; 5171d81011f0Ssbehera p_nxge_stats_t statsp; 5172d81011f0Ssbehera uint8_t xcvr_portn; 5173d81011f0Ssbehera p_mii_regs_t mii_regs; 5174d81011f0Ssbehera mii_bmcr_t bmcr; 5175d81011f0Ssbehera mii_bmsr_t bmsr; 5176d81011f0Ssbehera mii_gcr_t gcr; 5177d81011f0Ssbehera mii_esr_t esr; 5178d81011f0Ssbehera mii_aux_ctl_t bcm5464r_aux; 5179d81011f0Ssbehera int status = NXGE_OK; 5180d81011f0Ssbehera 5181d81011f0Ssbehera uint_t delay; 5182d81011f0Ssbehera 5183d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init")); 5184d81011f0Ssbehera 5185d81011f0Ssbehera param_arr = nxgep->param_arr; 5186d81011f0Ssbehera statsp = nxgep->statsp; 5187d81011f0Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 5188d81011f0Ssbehera 5189d81011f0Ssbehera mii_regs = NULL; 5190d81011f0Ssbehera 5191d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5192d81011f0Ssbehera "nxge_mii_xcvr_fiber_init: " 5193d81011f0Ssbehera "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 5194d81011f0Ssbehera 5195d81011f0Ssbehera /* 5196d81011f0Ssbehera * Reset the transceiver. 5197d81011f0Ssbehera */ 5198d81011f0Ssbehera delay = 0; 5199d81011f0Ssbehera bmcr.value = 0; 5200d81011f0Ssbehera bmcr.bits.reset = 1; 5201d81011f0Ssbehera 5202d81011f0Ssbehera #if defined(__i386) 5203d81011f0Ssbehera 5204d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5205d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 5206d81011f0Ssbehera goto fail; 5207d81011f0Ssbehera #else 5208d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5209d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 5210d81011f0Ssbehera goto fail; 5211d81011f0Ssbehera #endif 5212d81011f0Ssbehera do { 5213d81011f0Ssbehera drv_usecwait(500); 5214d81011f0Ssbehera #if defined(__i386) 5215d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5216d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) 5217d81011f0Ssbehera != NXGE_OK) 5218d81011f0Ssbehera goto fail; 5219d81011f0Ssbehera #else 5220d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5221d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) 5222d81011f0Ssbehera != NXGE_OK) 5223d81011f0Ssbehera goto fail; 5224d81011f0Ssbehera #endif 5225d81011f0Ssbehera delay++; 5226d81011f0Ssbehera } while ((bmcr.bits.reset) && (delay < 1000)); 5227d81011f0Ssbehera if (delay == 1000) { 5228d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 5229d81011f0Ssbehera goto fail; 5230d81011f0Ssbehera } 5231d81011f0Ssbehera 5232d81011f0Ssbehera #if defined(__i386) 5233d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5234d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 5235d81011f0Ssbehera goto fail; 5236d81011f0Ssbehera #else 5237d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5238d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK) 5239d81011f0Ssbehera goto fail; 5240d81011f0Ssbehera #endif 5241d81011f0Ssbehera 5242d81011f0Ssbehera param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 5243d81011f0Ssbehera param_arr[param_anar_100T4].value = 0; 5244d81011f0Ssbehera param_arr[param_anar_100fdx].value = 0; 5245d81011f0Ssbehera param_arr[param_anar_100hdx].value = 0; 5246d81011f0Ssbehera param_arr[param_anar_10fdx].value = 0; 5247d81011f0Ssbehera param_arr[param_anar_10hdx].value = 0; 5248d81011f0Ssbehera 5249d81011f0Ssbehera /* 5250d81011f0Ssbehera * Initialize the xcvr statistics. 5251d81011f0Ssbehera */ 5252d81011f0Ssbehera statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 5253d81011f0Ssbehera statsp->mac_stats.cap_100T4 = 0; 5254d81011f0Ssbehera statsp->mac_stats.cap_100fdx = 0; 5255d81011f0Ssbehera statsp->mac_stats.cap_100hdx = 0; 5256d81011f0Ssbehera statsp->mac_stats.cap_10fdx = 0; 5257d81011f0Ssbehera statsp->mac_stats.cap_10hdx = 0; 5258d81011f0Ssbehera statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 5259d81011f0Ssbehera statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 5260d81011f0Ssbehera 5261d81011f0Ssbehera /* 5262d81011f0Ssbehera * Initialize the xcvr advertised capability statistics. 5263d81011f0Ssbehera */ 5264d81011f0Ssbehera statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 5265d81011f0Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 5266d81011f0Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 5267d81011f0Ssbehera statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 5268d81011f0Ssbehera statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 5269d81011f0Ssbehera statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 5270d81011f0Ssbehera statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 5271d81011f0Ssbehera statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 5272d81011f0Ssbehera statsp->mac_stats.adv_cap_asmpause = 5273d81011f0Ssbehera param_arr[param_anar_asmpause].value; 5274d81011f0Ssbehera statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 5275d81011f0Ssbehera 5276d81011f0Ssbehera /* 5277d81011f0Ssbehera * Check for extended status just in case we're 5278d81011f0Ssbehera * running a Gigibit phy. 5279d81011f0Ssbehera */ 5280d81011f0Ssbehera if (bmsr.bits.extend_status) { 5281d81011f0Ssbehera #if defined(__i386) 5282d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5283d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) != 5284d81011f0Ssbehera NXGE_OK) 5285d81011f0Ssbehera goto fail; 5286d81011f0Ssbehera #else 5287d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5288d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) != 5289d81011f0Ssbehera NXGE_OK) 5290d81011f0Ssbehera goto fail; 5291d81011f0Ssbehera #endif 5292d81011f0Ssbehera param_arr[param_anar_1000fdx].value &= 5293d81011f0Ssbehera esr.bits.link_1000fdx; 5294d81011f0Ssbehera param_arr[param_anar_1000hdx].value = 0; 5295d81011f0Ssbehera 5296d81011f0Ssbehera statsp->mac_stats.cap_1000fdx = 5297d81011f0Ssbehera (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx); 5298d81011f0Ssbehera statsp->mac_stats.cap_1000hdx = 0; 5299d81011f0Ssbehera } else { 5300d81011f0Ssbehera param_arr[param_anar_1000fdx].value = 0; 5301d81011f0Ssbehera param_arr[param_anar_1000hdx].value = 0; 5302d81011f0Ssbehera } 5303d81011f0Ssbehera 5304d81011f0Ssbehera /* 5305d81011f0Ssbehera * Initialize 1G Statistics once the capability is established. 5306d81011f0Ssbehera */ 5307d81011f0Ssbehera statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 5308d81011f0Ssbehera statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 5309d81011f0Ssbehera 5310d81011f0Ssbehera /* 5311d81011f0Ssbehera * Initialize the link statistics. 5312d81011f0Ssbehera */ 5313d81011f0Ssbehera statsp->mac_stats.link_T4 = 0; 5314d81011f0Ssbehera statsp->mac_stats.link_asmpause = 0; 5315d81011f0Ssbehera statsp->mac_stats.link_pause = 0; 5316d81011f0Ssbehera statsp->mac_stats.link_speed = 0; 5317d81011f0Ssbehera statsp->mac_stats.link_duplex = 0; 5318d81011f0Ssbehera statsp->mac_stats.link_up = 0; 5319d81011f0Ssbehera 5320d81011f0Ssbehera /* 5321d81011f0Ssbehera * Switch off Auto-negotiation, 100M and full duplex. 5322d81011f0Ssbehera */ 5323d81011f0Ssbehera bmcr.value = 0; 5324d81011f0Ssbehera #if defined(__i386) 5325d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5326d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 5327d81011f0Ssbehera goto fail; 5328d81011f0Ssbehera #else 5329d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5330d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 5331d81011f0Ssbehera goto fail; 5332d81011f0Ssbehera #endif 5333d81011f0Ssbehera 5334d81011f0Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 5335d81011f0Ssbehera (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 5336d81011f0Ssbehera bmcr.bits.loopback = 1; 5337d81011f0Ssbehera bmcr.bits.enable_autoneg = 0; 5338d81011f0Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 5339d81011f0Ssbehera bmcr.bits.speed_1000_sel = 1; 5340d81011f0Ssbehera bmcr.bits.duplex_mode = 1; 5341d81011f0Ssbehera param_arr[param_autoneg].value = 0; 5342d81011f0Ssbehera } else { 5343d81011f0Ssbehera bmcr.bits.loopback = 0; 5344d81011f0Ssbehera } 5345d81011f0Ssbehera 5346d81011f0Ssbehera if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 5347d81011f0Ssbehera param_arr[param_autoneg].value = 0; 5348d81011f0Ssbehera bcm5464r_aux.value = 0; 5349d81011f0Ssbehera bcm5464r_aux.bits.ext_lb = 1; 5350d81011f0Ssbehera bcm5464r_aux.bits.write_1 = 1; 5351d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5352d81011f0Ssbehera BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK) 5353d81011f0Ssbehera goto fail; 5354d81011f0Ssbehera } 5355d81011f0Ssbehera 5356d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 5357d81011f0Ssbehera bmcr.bits.speed_1000_sel = 1; 5358d81011f0Ssbehera bmcr.bits.speed_sel = 0; 5359d81011f0Ssbehera bmcr.bits.duplex_mode = 1; 5360d81011f0Ssbehera statsp->mac_stats.link_speed = 1000; 5361d81011f0Ssbehera statsp->mac_stats.link_duplex = 2; 5362d81011f0Ssbehera 5363d81011f0Ssbehera if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) { 5364d81011f0Ssbehera /* BCM5464R 1000mbps external loopback mode */ 5365d81011f0Ssbehera gcr.value = 0; 5366d81011f0Ssbehera gcr.bits.ms_mode_en = 1; 5367d81011f0Ssbehera gcr.bits.master = 1; 5368d81011f0Ssbehera #if defined(__i386) 5369d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5370d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->gcr), 5371d81011f0Ssbehera gcr.value)) != NXGE_OK) 5372d81011f0Ssbehera goto fail; 5373d81011f0Ssbehera #else 5374d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5375d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->gcr), 5376d81011f0Ssbehera gcr.value)) != NXGE_OK) 5377d81011f0Ssbehera goto fail; 5378d81011f0Ssbehera #endif 5379d81011f0Ssbehera bmcr.value = 0; 5380d81011f0Ssbehera bmcr.bits.speed_1000_sel = 1; 5381d81011f0Ssbehera statsp->mac_stats.link_speed = 1000; 5382d81011f0Ssbehera } 5383d81011f0Ssbehera 5384d81011f0Ssbehera #if defined(__i386) 5385d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5386d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), 5387d81011f0Ssbehera bmcr.value)) != NXGE_OK) 5388d81011f0Ssbehera goto fail; 5389d81011f0Ssbehera #else 5390d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 5391d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), 5392d81011f0Ssbehera bmcr.value)) != NXGE_OK) 5393d81011f0Ssbehera goto fail; 5394d81011f0Ssbehera #endif 5395d81011f0Ssbehera 5396d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5397d81011f0Ssbehera "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x", 5398d81011f0Ssbehera bmcr.value)); 5399d81011f0Ssbehera 5400d81011f0Ssbehera #if defined(__i386) 5401d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5402d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 5403d81011f0Ssbehera goto fail; 5404d81011f0Ssbehera #else 5405d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5406d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 5407d81011f0Ssbehera goto fail; 5408d81011f0Ssbehera #endif 5409d81011f0Ssbehera 5410d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5411d81011f0Ssbehera "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value)); 5412d81011f0Ssbehera 5413d81011f0Ssbehera /* 5414d81011f0Ssbehera * Initialize the xcvr status kept in the context structure. 5415d81011f0Ssbehera */ 5416d81011f0Ssbehera nxgep->soft_bmsr.value = 0; 5417d81011f0Ssbehera #if defined(__i386) 5418d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5419d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), 5420d81011f0Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 5421d81011f0Ssbehera goto fail; 5422d81011f0Ssbehera #else 5423d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 5424d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), 5425d81011f0Ssbehera &nxgep->bmsr.value)) != NXGE_OK) 5426d81011f0Ssbehera goto fail; 5427d81011f0Ssbehera #endif 5428d81011f0Ssbehera 5429d81011f0Ssbehera statsp->mac_stats.xcvr_inits++; 5430d81011f0Ssbehera nxgep->bmsr.value = 0; 5431d81011f0Ssbehera 5432d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5433d81011f0Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 5434d81011f0Ssbehera return (status); 5435d81011f0Ssbehera 5436d81011f0Ssbehera fail: 5437d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 5438d81011f0Ssbehera "<== nxge_mii_xcvr_fiber_init status 0x%x", status)); 5439d81011f0Ssbehera return (status); 5440d81011f0Ssbehera } 5441d81011f0Ssbehera 54426f45ec7bSml29623 /* Read from a MII compliant register */ 54436f45ec7bSml29623 54446f45ec7bSml29623 nxge_status_t 54456f45ec7bSml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 54466f45ec7bSml29623 uint16_t *value) 54476f45ec7bSml29623 { 54486f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 54496f45ec7bSml29623 54506f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 54516f45ec7bSml29623 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 54526f45ec7bSml29623 5453321febdeSsbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 54546f45ec7bSml29623 5455d81011f0Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 5456d81011f0Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 54576f45ec7bSml29623 if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 54586f45ec7bSml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 54596f45ec7bSml29623 goto fail; 54602e59129aSraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 54612e59129aSraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 54626f45ec7bSml29623 if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 54636f45ec7bSml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 54646f45ec7bSml29623 goto fail; 54656f45ec7bSml29623 } else 54666f45ec7bSml29623 goto fail; 54676f45ec7bSml29623 5468321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 54696f45ec7bSml29623 54706f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 547152ccf843Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value)); 54726f45ec7bSml29623 return (NXGE_OK); 54736f45ec7bSml29623 fail: 5474321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 54756f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 547652ccf843Smisaki "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn)); 54776f45ec7bSml29623 54786f45ec7bSml29623 return (NXGE_ERROR | rs); 54796f45ec7bSml29623 } 54806f45ec7bSml29623 54816f45ec7bSml29623 /* Write to a MII compliant Register */ 54826f45ec7bSml29623 54836f45ec7bSml29623 nxge_status_t 54846f45ec7bSml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 54856f45ec7bSml29623 uint16_t value) 54866f45ec7bSml29623 { 54876f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 54886f45ec7bSml29623 54896f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 549052ccf843Smisaki "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value)); 54916f45ec7bSml29623 5492321febdeSsbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 54936f45ec7bSml29623 5494d81011f0Ssbehera if ((nxgep->mac.portmode == PORT_1G_COPPER) || 5495d81011f0Ssbehera (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) { 54966f45ec7bSml29623 if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 54976f45ec7bSml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 54986f45ec7bSml29623 goto fail; 54992e59129aSraghus } else if ((nxgep->mac.portmode == PORT_1G_FIBER) || 55002e59129aSraghus (nxgep->mac.portmode == PORT_1G_SERDES)) { 55016f45ec7bSml29623 if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 55026f45ec7bSml29623 xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 55036f45ec7bSml29623 goto fail; 55046f45ec7bSml29623 } else 55056f45ec7bSml29623 goto fail; 55066f45ec7bSml29623 5507321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 55086f45ec7bSml29623 55096f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 55106f45ec7bSml29623 "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 55116f45ec7bSml29623 return (NXGE_OK); 55126f45ec7bSml29623 fail: 5513321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 55146f45ec7bSml29623 55156f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 551652ccf843Smisaki "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn)); 55176f45ec7bSml29623 55186f45ec7bSml29623 return (NXGE_ERROR | rs); 55196f45ec7bSml29623 } 55206f45ec7bSml29623 552100161856Syc148097 /* 552200161856Syc148097 * Perform write to Clause45 serdes / transceiver device 552300161856Syc148097 * Arguments: 552400161856Syc148097 * xcvr_portn: The IEEE 802.3 Clause45 PHYAD, it is the same as port 552500161856Syc148097 * number if nxge_mdio_write is used for accessing the 552600161856Syc148097 * internal LSIL serdes. Otherwise PHYAD is different 552700161856Syc148097 * for different platforms. 552800161856Syc148097 * device: With each PHYAD, the driver can use MDIO to control 552900161856Syc148097 * multiple devices inside the PHY, here "device" is an 553000161856Syc148097 * MMD (MDIO managable device). 553100161856Syc148097 * xcvr_reg: Each device has multiple registers. xcvr_reg specifies 553200161856Syc148097 * the register which the driver will write value to. 553300161856Syc148097 * value: The register value will be filled in. 553400161856Syc148097 */ 55356f45ec7bSml29623 nxge_status_t 55366f45ec7bSml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 55376f45ec7bSml29623 uint16_t xcvr_reg, uint16_t *value) 55386f45ec7bSml29623 { 55396f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 55406f45ec7bSml29623 55416f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 55426f45ec7bSml29623 xcvr_portn)); 55436f45ec7bSml29623 554453560810Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 55456f45ec7bSml29623 55466f45ec7bSml29623 if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 55476f45ec7bSml29623 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 55486f45ec7bSml29623 goto fail; 55496f45ec7bSml29623 555053560810Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 55516f45ec7bSml29623 55526f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 55536f45ec7bSml29623 xcvr_portn)); 55546f45ec7bSml29623 return (NXGE_OK); 55556f45ec7bSml29623 fail: 555653560810Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 55576f45ec7bSml29623 55586f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 555952ccf843Smisaki "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn)); 55606f45ec7bSml29623 55616f45ec7bSml29623 return (NXGE_ERROR | rs); 55626f45ec7bSml29623 } 55636f45ec7bSml29623 55646f45ec7bSml29623 /* Perform write to Clause45 serdes / transceiver device */ 55656f45ec7bSml29623 55666f45ec7bSml29623 nxge_status_t 55676f45ec7bSml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 55686f45ec7bSml29623 uint16_t xcvr_reg, uint16_t value) 55696f45ec7bSml29623 { 55706f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 55716f45ec7bSml29623 55726f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 55736f45ec7bSml29623 xcvr_portn)); 55746f45ec7bSml29623 557553560810Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 55766f45ec7bSml29623 55776f45ec7bSml29623 if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 55786f45ec7bSml29623 xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 55796f45ec7bSml29623 goto fail; 55806f45ec7bSml29623 558153560810Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 55826f45ec7bSml29623 55836f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 55846f45ec7bSml29623 xcvr_portn)); 55856f45ec7bSml29623 return (NXGE_OK); 55866f45ec7bSml29623 fail: 558753560810Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 55886f45ec7bSml29623 55896f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 559052ccf843Smisaki "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn)); 55916f45ec7bSml29623 55926f45ec7bSml29623 return (NXGE_ERROR | rs); 55936f45ec7bSml29623 } 55946f45ec7bSml29623 55956f45ec7bSml29623 55966f45ec7bSml29623 /* Check MII to see if there is any link status change */ 55976f45ec7bSml29623 55986f45ec7bSml29623 nxge_status_t 55996f45ec7bSml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 56006f45ec7bSml29623 nxge_link_state_t *link_up) 56016f45ec7bSml29623 { 56026f45ec7bSml29623 p_nxge_param_t param_arr; 56036f45ec7bSml29623 p_nxge_stats_t statsp; 56046f45ec7bSml29623 p_mii_regs_t mii_regs; 56056f45ec7bSml29623 p_mii_bmsr_t soft_bmsr; 56066f45ec7bSml29623 mii_anar_t anar; 56076f45ec7bSml29623 mii_anlpar_t anlpar; 56086f45ec7bSml29623 mii_anar_t an_common; 56096f45ec7bSml29623 mii_aner_t aner; 56106f45ec7bSml29623 mii_gsr_t gsr; 56116f45ec7bSml29623 nxge_status_t status = NXGE_OK; 56126f45ec7bSml29623 56136f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 56146f45ec7bSml29623 56156f45ec7bSml29623 mii_regs = NULL; 56166f45ec7bSml29623 param_arr = nxgep->param_arr; 56176f45ec7bSml29623 statsp = nxgep->statsp; 56186f45ec7bSml29623 soft_bmsr = &nxgep->soft_bmsr; 56196f45ec7bSml29623 *link_up = LINK_NO_CHANGE; 56206f45ec7bSml29623 5621d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5622d81011f0Ssbehera "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x", 5623d81011f0Ssbehera bmsr.value, bmsr_ints.value)); 5624d81011f0Ssbehera 56256f45ec7bSml29623 if (bmsr_ints.bits.link_status) { 5626d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5627d81011f0Ssbehera "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x", 5628d81011f0Ssbehera bmsr.value, bmsr_ints.value)); 56296f45ec7bSml29623 if (bmsr.bits.link_status) { 56306f45ec7bSml29623 soft_bmsr->bits.link_status = 1; 5631d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5632d81011f0Ssbehera "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int " 5633d81011f0Ssbehera "0x%x", bmsr.value, bmsr_ints.value)); 56346f45ec7bSml29623 } else { 5635774da109Stc99174@train /* Only status change will update *link_up */ 5636774da109Stc99174@train if (statsp->mac_stats.link_up == 1) { 5637774da109Stc99174@train *link_up = LINK_IS_DOWN; 5638774da109Stc99174@train /* Will notify, turn off further msg */ 5639774da109Stc99174@train nxgep->link_notify = B_FALSE; 5640774da109Stc99174@train } 56416f45ec7bSml29623 statsp->mac_stats.link_up = 0; 56426f45ec7bSml29623 soft_bmsr->bits.link_status = 0; 56436f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 56446f45ec7bSml29623 "Link down cable problem")); 56456f45ec7bSml29623 } 56466f45ec7bSml29623 } 56476f45ec7bSml29623 5648d81011f0Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 5649d81011f0Ssbehera param_arr[param_autoneg].value) { 56506f45ec7bSml29623 if (bmsr_ints.bits.auto_neg_complete) { 56516f45ec7bSml29623 if (bmsr.bits.auto_neg_complete) 56526f45ec7bSml29623 soft_bmsr->bits.auto_neg_complete = 1; 56536f45ec7bSml29623 else 56546f45ec7bSml29623 soft_bmsr->bits.auto_neg_complete = 0; 56556f45ec7bSml29623 } 56566f45ec7bSml29623 if (soft_bmsr->bits.link_status == 0) { 56576f45ec7bSml29623 statsp->mac_stats.link_T4 = 0; 56586f45ec7bSml29623 statsp->mac_stats.link_speed = 0; 56596f45ec7bSml29623 statsp->mac_stats.link_duplex = 0; 56606f45ec7bSml29623 statsp->mac_stats.link_asmpause = 0; 56616f45ec7bSml29623 statsp->mac_stats.link_pause = 0; 56626f45ec7bSml29623 statsp->mac_stats.lp_cap_autoneg = 0; 56636f45ec7bSml29623 statsp->mac_stats.lp_cap_100T4 = 0; 56646f45ec7bSml29623 statsp->mac_stats.lp_cap_1000fdx = 0; 56656f45ec7bSml29623 statsp->mac_stats.lp_cap_1000hdx = 0; 56666f45ec7bSml29623 statsp->mac_stats.lp_cap_100fdx = 0; 56676f45ec7bSml29623 statsp->mac_stats.lp_cap_100hdx = 0; 56686f45ec7bSml29623 statsp->mac_stats.lp_cap_10fdx = 0; 56696f45ec7bSml29623 statsp->mac_stats.lp_cap_10hdx = 0; 56706f45ec7bSml29623 statsp->mac_stats.lp_cap_10gfdx = 0; 56716f45ec7bSml29623 statsp->mac_stats.lp_cap_10ghdx = 0; 56726f45ec7bSml29623 statsp->mac_stats.lp_cap_asmpause = 0; 56736f45ec7bSml29623 statsp->mac_stats.lp_cap_pause = 0; 56746f45ec7bSml29623 } 56756f45ec7bSml29623 } else 56766f45ec7bSml29623 soft_bmsr->bits.auto_neg_complete = 1; 56776f45ec7bSml29623 56786f45ec7bSml29623 if ((bmsr_ints.bits.link_status || 56796f45ec7bSml29623 bmsr_ints.bits.auto_neg_complete) && 56806f45ec7bSml29623 soft_bmsr->bits.link_status && 56816f45ec7bSml29623 soft_bmsr->bits.auto_neg_complete) { 5682774da109Stc99174@train if (statsp->mac_stats.link_up == 0) { 5683774da109Stc99174@train *link_up = LINK_IS_UP; 5684774da109Stc99174@train nxgep->link_notify = B_FALSE; 5685774da109Stc99174@train } 56866f45ec7bSml29623 statsp->mac_stats.link_up = 1; 5687d81011f0Ssbehera 5688d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 5689d81011f0Ssbehera "==> nxge_mii_check " 5690d81011f0Ssbehera "(auto negotiation complete or link up) " 5691d81011f0Ssbehera "soft bmsr 0x%x bmsr_int 0x%x", 5692d81011f0Ssbehera bmsr.value, bmsr_ints.value)); 5693d81011f0Ssbehera 5694d81011f0Ssbehera if (nxgep->mac.portmode == PORT_1G_COPPER && 5695d81011f0Ssbehera param_arr[param_autoneg].value) { 56966f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, 56976f45ec7bSml29623 statsp->mac_stats.xcvr_portn, 5698adfcba55Sjoycey #if defined(__i386) 5699adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->anar), 5700adfcba55Sjoycey #else 57016f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->anar), 5702adfcba55Sjoycey #endif 57036f45ec7bSml29623 &anar.value)) != NXGE_OK) 57046f45ec7bSml29623 goto fail; 57056f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, 57066f45ec7bSml29623 statsp->mac_stats.xcvr_portn, 5707adfcba55Sjoycey #if defined(__i386) 5708adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->anlpar), 5709adfcba55Sjoycey #else 57106f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->anlpar), 5711adfcba55Sjoycey #endif 57126f45ec7bSml29623 &anlpar.value)) != NXGE_OK) 57136f45ec7bSml29623 goto fail; 57146f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, 57156f45ec7bSml29623 statsp->mac_stats.xcvr_portn, 5716adfcba55Sjoycey #if defined(__i386) 5717adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->aner), 5718adfcba55Sjoycey #else 57196f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->aner), 5720adfcba55Sjoycey #endif 57216f45ec7bSml29623 &aner.value)) != NXGE_OK) 57226f45ec7bSml29623 goto fail; 57236f45ec7bSml29623 statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 57246f45ec7bSml29623 statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 57256f45ec7bSml29623 statsp->mac_stats.lp_cap_100fdx = 57266f45ec7bSml29623 anlpar.bits.cap_100fdx; 57276f45ec7bSml29623 statsp->mac_stats.lp_cap_100hdx = 57286f45ec7bSml29623 anlpar.bits.cap_100hdx; 57296f45ec7bSml29623 statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 57306f45ec7bSml29623 statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 57316f45ec7bSml29623 statsp->mac_stats.lp_cap_asmpause = 57326f45ec7bSml29623 anlpar.bits.cap_asmpause; 57336f45ec7bSml29623 statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 57346f45ec7bSml29623 an_common.value = anar.value & anlpar.value; 57356f45ec7bSml29623 if (param_arr[param_anar_1000fdx].value || 57366f45ec7bSml29623 param_arr[param_anar_1000hdx].value) { 57376f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, 57386f45ec7bSml29623 statsp->mac_stats.xcvr_portn, 5739adfcba55Sjoycey #if defined(__i386) 5740adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->gsr), 5741adfcba55Sjoycey #else 57426f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->gsr), 5743adfcba55Sjoycey #endif 574452ccf843Smisaki &gsr.value)) != NXGE_OK) 57456f45ec7bSml29623 goto fail; 57466f45ec7bSml29623 statsp->mac_stats.lp_cap_1000fdx = 57476f45ec7bSml29623 gsr.bits.link_1000fdx; 57486f45ec7bSml29623 statsp->mac_stats.lp_cap_1000hdx = 57496f45ec7bSml29623 gsr.bits.link_1000hdx; 57506f45ec7bSml29623 if (param_arr[param_anar_1000fdx].value && 57516f45ec7bSml29623 gsr.bits.link_1000fdx) { 57526f45ec7bSml29623 statsp->mac_stats.link_speed = 1000; 57536f45ec7bSml29623 statsp->mac_stats.link_duplex = 2; 57546f45ec7bSml29623 } else if ( 57556f45ec7bSml29623 param_arr[param_anar_1000hdx].value && 57566f45ec7bSml29623 gsr.bits.link_1000hdx) { 57576f45ec7bSml29623 statsp->mac_stats.link_speed = 1000; 57586f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 57596f45ec7bSml29623 } 57606f45ec7bSml29623 } 57616f45ec7bSml29623 if ((an_common.value != 0) && 57626f45ec7bSml29623 !(statsp->mac_stats.link_speed)) { 57636f45ec7bSml29623 if (an_common.bits.cap_100T4) { 57646f45ec7bSml29623 statsp->mac_stats.link_T4 = 1; 57656f45ec7bSml29623 statsp->mac_stats.link_speed = 100; 57666f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 57676f45ec7bSml29623 } else if (an_common.bits.cap_100fdx) { 57686f45ec7bSml29623 statsp->mac_stats.link_speed = 100; 57696f45ec7bSml29623 statsp->mac_stats.link_duplex = 2; 57706f45ec7bSml29623 } else if (an_common.bits.cap_100hdx) { 57716f45ec7bSml29623 statsp->mac_stats.link_speed = 100; 57726f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 57736f45ec7bSml29623 } else if (an_common.bits.cap_10fdx) { 57746f45ec7bSml29623 statsp->mac_stats.link_speed = 10; 57756f45ec7bSml29623 statsp->mac_stats.link_duplex = 2; 57766f45ec7bSml29623 } else if (an_common.bits.cap_10hdx) { 57776f45ec7bSml29623 statsp->mac_stats.link_speed = 10; 57786f45ec7bSml29623 statsp->mac_stats.link_duplex = 1; 57796f45ec7bSml29623 } else { 57806f45ec7bSml29623 goto fail; 57816f45ec7bSml29623 } 57826f45ec7bSml29623 } 57836f45ec7bSml29623 if (statsp->mac_stats.link_duplex != 1) { 578452ccf843Smisaki int link_pause; 578552ccf843Smisaki int cp, lcp; 578652ccf843Smisaki 57876f45ec7bSml29623 statsp->mac_stats.link_asmpause = 57886f45ec7bSml29623 an_common.bits.cap_asmpause; 578952ccf843Smisaki cp = statsp->mac_stats.cap_pause; 579052ccf843Smisaki lcp = statsp->mac_stats.lp_cap_pause; 579152ccf843Smisaki if (statsp->mac_stats.link_asmpause) { 579252ccf843Smisaki if ((cp == 0) && (lcp == 1)) { 579352ccf843Smisaki link_pause = 0; 579452ccf843Smisaki } else { 579552ccf843Smisaki link_pause = 1; 579652ccf843Smisaki } 579752ccf843Smisaki } else { 579852ccf843Smisaki link_pause = an_common.bits.cap_pause; 579952ccf843Smisaki } 580052ccf843Smisaki statsp->mac_stats.link_pause = link_pause; 58016f45ec7bSml29623 } 5802d81011f0Ssbehera } else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) { 5803d81011f0Ssbehera statsp->mac_stats.link_speed = 1000; 5804d81011f0Ssbehera statsp->mac_stats.link_duplex = 2; 58056f45ec7bSml29623 } 58066f45ec7bSml29623 } 5807774da109Stc99174@train /* Initial link_notify, delay link down msg */ 5808774da109Stc99174@train if (nxgep->link_notify && nxgep->nxge_mac_state == NXGE_MAC_STARTED && 5809774da109Stc99174@train (statsp->mac_stats.link_up == 1 || nxgep->link_check_count > 3)) { 58106f45ec7bSml29623 *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 58116f45ec7bSml29623 LINK_IS_DOWN); 58126f45ec7bSml29623 nxgep->link_notify = B_FALSE; 58136f45ec7bSml29623 } 58146f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 58156f45ec7bSml29623 return (NXGE_OK); 58166f45ec7bSml29623 fail: 58176f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 58186f45ec7bSml29623 "nxge_mii_check: Unable to check MII")); 58196f45ec7bSml29623 return (status); 58206f45ec7bSml29623 } 58216f45ec7bSml29623 582200161856Syc148097 /* 582300161856Syc148097 * Check PCS to see if there is any link status change. 582400161856Syc148097 * This function is called by PORT_1G_SERDES only. 582500161856Syc148097 */ 582600161856Syc148097 void 58272e59129aSraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up) 58282e59129aSraghus { 58292e59129aSraghus p_nxge_stats_t statsp; 58302e59129aSraghus boolean_t linkup; 58312e59129aSraghus 58322e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check")); 58332e59129aSraghus 58342e59129aSraghus statsp = nxgep->statsp; 58352e59129aSraghus *link_up = LINK_NO_CHANGE; 58362e59129aSraghus 58372e59129aSraghus (void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup); 58382e59129aSraghus if (linkup) { 5839774da109Stc99174@train if ((nxgep->link_notify && 5840774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) || 58412e59129aSraghus nxgep->statsp->mac_stats.link_up == 0) { 58422e59129aSraghus statsp->mac_stats.link_up = 1; 58432e59129aSraghus statsp->mac_stats.link_speed = 1000; 58442e59129aSraghus statsp->mac_stats.link_duplex = 2; 58452e59129aSraghus *link_up = LINK_IS_UP; 58462e59129aSraghus nxgep->link_notify = B_FALSE; 58472e59129aSraghus } 58482e59129aSraghus } else { 5849774da109Stc99174@train if ((nxgep->link_notify && nxgep->link_check_count > 3 && 5850774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) || 58512e59129aSraghus nxgep->statsp->mac_stats.link_up == 1) { 58522e59129aSraghus statsp->mac_stats.link_up = 0; 58532e59129aSraghus statsp->mac_stats.link_speed = 0; 58542e59129aSraghus statsp->mac_stats.link_duplex = 0; 58552e59129aSraghus *link_up = LINK_IS_DOWN; 58562e59129aSraghus nxgep->link_notify = B_FALSE; 58572e59129aSraghus } 58582e59129aSraghus } 58592e59129aSraghus 58602e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check")); 58612e59129aSraghus } 58622e59129aSraghus 58636f45ec7bSml29623 /* Add a multicast address entry into the HW hash table */ 58646f45ec7bSml29623 58656f45ec7bSml29623 nxge_status_t 58666f45ec7bSml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 58676f45ec7bSml29623 { 58686f45ec7bSml29623 uint32_t mchash; 58696f45ec7bSml29623 p_hash_filter_t hash_filter; 58706f45ec7bSml29623 uint16_t hash_bit; 58716f45ec7bSml29623 uint_t j; 58726f45ec7bSml29623 nxge_status_t status = NXGE_OK; 58730dc2366fSVenugopal Iyer npi_status_t rs; 58746f45ec7bSml29623 58756f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 58766f45ec7bSml29623 58776f45ec7bSml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 58786f45ec7bSml29623 mchash = crc32_mchash(addrp); 58796f45ec7bSml29623 if (nxgep->hash_filter == NULL) { 58806f45ec7bSml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 58816f45ec7bSml29623 "Allocating hash filter storage.")); 58826f45ec7bSml29623 nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 58836f45ec7bSml29623 KM_SLEEP); 58846f45ec7bSml29623 } 58850dc2366fSVenugopal Iyer 58866f45ec7bSml29623 hash_filter = nxgep->hash_filter; 58876f45ec7bSml29623 j = mchash / HASH_REG_WIDTH; 58886f45ec7bSml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 58896f45ec7bSml29623 hash_filter->hash_filter_regs[j] |= hash_bit; 58906f45ec7bSml29623 hash_filter->hash_bit_ref_cnt[mchash]++; 58916f45ec7bSml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 58926f45ec7bSml29623 hash_filter->hash_ref_cnt++; 58936f45ec7bSml29623 } 58940dc2366fSVenugopal Iyer 58950dc2366fSVenugopal Iyer rs = nxge_rx_mac_mcast_hash_table(nxgep); 58960dc2366fSVenugopal Iyer if (rs != NPI_SUCCESS) 58976f45ec7bSml29623 goto fail; 58986f45ec7bSml29623 58996f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 59006f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 59016f45ec7bSml29623 return (NXGE_OK); 59026f45ec7bSml29623 fail: 59036f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 59046f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 59056f45ec7bSml29623 "Unable to add multicast address")); 59066f45ec7bSml29623 return (status); 59076f45ec7bSml29623 } 59086f45ec7bSml29623 59096f45ec7bSml29623 /* Remove a multicast address entry from the HW hash table */ 59106f45ec7bSml29623 59116f45ec7bSml29623 nxge_status_t 59126f45ec7bSml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 59136f45ec7bSml29623 { 59146f45ec7bSml29623 uint32_t mchash; 59156f45ec7bSml29623 p_hash_filter_t hash_filter; 59166f45ec7bSml29623 uint16_t hash_bit; 59176f45ec7bSml29623 uint_t j; 59186f45ec7bSml29623 nxge_status_t status = NXGE_OK; 59190dc2366fSVenugopal Iyer npi_status_t rs; 59206f45ec7bSml29623 59216f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 59226f45ec7bSml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 59236f45ec7bSml29623 mchash = crc32_mchash(addrp); 59246f45ec7bSml29623 if (nxgep->hash_filter == NULL) { 59256f45ec7bSml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 59266f45ec7bSml29623 "Hash filter already de_allocated.")); 59276f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 59286f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 59296f45ec7bSml29623 return (NXGE_OK); 59306f45ec7bSml29623 } 59316f45ec7bSml29623 hash_filter = nxgep->hash_filter; 59326f45ec7bSml29623 hash_filter->hash_bit_ref_cnt[mchash]--; 59336f45ec7bSml29623 if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 59346f45ec7bSml29623 j = mchash / HASH_REG_WIDTH; 59356f45ec7bSml29623 hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 59366f45ec7bSml29623 hash_filter->hash_filter_regs[j] &= ~hash_bit; 59376f45ec7bSml29623 hash_filter->hash_ref_cnt--; 59386f45ec7bSml29623 } 59390dc2366fSVenugopal Iyer 59406f45ec7bSml29623 if (hash_filter->hash_ref_cnt == 0) { 59416f45ec7bSml29623 NXGE_DEBUG_MSG((NULL, STR_CTL, 59426f45ec7bSml29623 "De-allocating hash filter storage.")); 59436f45ec7bSml29623 KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 59446f45ec7bSml29623 nxgep->hash_filter = NULL; 59456f45ec7bSml29623 } 59466f45ec7bSml29623 59470dc2366fSVenugopal Iyer rs = nxge_rx_mac_mcast_hash_table(nxgep); 59480dc2366fSVenugopal Iyer if (rs != NPI_SUCCESS) 59496f45ec7bSml29623 goto fail; 59500dc2366fSVenugopal Iyer 59516f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 59526f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 59536f45ec7bSml29623 59546f45ec7bSml29623 return (NXGE_OK); 59556f45ec7bSml29623 fail: 59566f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 59576f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 59586f45ec7bSml29623 "Unable to remove multicast address")); 59596f45ec7bSml29623 59606f45ec7bSml29623 return (status); 59616f45ec7bSml29623 } 59626f45ec7bSml29623 59636f45ec7bSml29623 /* Set MAC address into MAC address HW registers */ 59646f45ec7bSml29623 59656f45ec7bSml29623 nxge_status_t 59666f45ec7bSml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 59676f45ec7bSml29623 { 59686f45ec7bSml29623 nxge_status_t status = NXGE_OK; 59696f45ec7bSml29623 59706f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 59716f45ec7bSml29623 59726f45ec7bSml29623 MUTEX_ENTER(&nxgep->ouraddr_lock); 59736f45ec7bSml29623 /* 59746f45ec7bSml29623 * Exit if the address is same as ouraddr or multicast or broadcast 59756f45ec7bSml29623 */ 59766f45ec7bSml29623 if (((addrp->ether_addr_octet[0] & 01) == 1) || 59776f45ec7bSml29623 (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 59786f45ec7bSml29623 (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 59796f45ec7bSml29623 goto nxge_set_mac_addr_exit; 59806f45ec7bSml29623 } 59816f45ec7bSml29623 nxgep->ouraddr = *addrp; 59826f45ec7bSml29623 /* 59836f45ec7bSml29623 * Set new interface local address and re-init device. 59846f45ec7bSml29623 * This is destructive to any other streams attached 59856f45ec7bSml29623 * to this device. 59866f45ec7bSml29623 */ 59876f45ec7bSml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 59886f45ec7bSml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 59896f45ec7bSml29623 goto fail; 59906f45ec7bSml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 59916f45ec7bSml29623 goto fail; 59926f45ec7bSml29623 59936f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 59946f45ec7bSml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 59956f45ec7bSml29623 goto nxge_set_mac_addr_end; 59966f45ec7bSml29623 nxge_set_mac_addr_exit: 59976f45ec7bSml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 59986f45ec7bSml29623 nxge_set_mac_addr_end: 59996f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 60006f45ec7bSml29623 60016f45ec7bSml29623 return (NXGE_OK); 60026f45ec7bSml29623 fail: 60036f45ec7bSml29623 MUTEX_EXIT(&nxgep->ouraddr_lock); 60046f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 60056f45ec7bSml29623 "Unable to set mac address")); 60066f45ec7bSml29623 return (status); 60076f45ec7bSml29623 } 60086f45ec7bSml29623 600998ecde52Stm144005 static 601098ecde52Stm144005 check_link_state_t 601100161856Syc148097 nxge_check_link_stop(nxge_t *nxge) 601298ecde52Stm144005 { 601398ecde52Stm144005 /* If the poll has been cancelled, return STOP. */ 601498ecde52Stm144005 MUTEX_ENTER(&nxge->poll_lock); 601598ecde52Stm144005 if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 601698ecde52Stm144005 nxge->poll_state = LINK_MONITOR_STOP; 601798ecde52Stm144005 nxge->nxge_link_poll_timerid = 0; 601898ecde52Stm144005 cv_broadcast(&nxge->poll_cv); 601998ecde52Stm144005 MUTEX_EXIT(&nxge->poll_lock); 602098ecde52Stm144005 602198ecde52Stm144005 NXGE_DEBUG_MSG((nxge, MAC_CTL, 602298ecde52Stm144005 "nxge_check_%s_link(port<%d>) stopped.", 602398ecde52Stm144005 nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 602498ecde52Stm144005 nxge->mac.portnum)); 602598ecde52Stm144005 return (CHECK_LINK_STOP); 602698ecde52Stm144005 } 602798ecde52Stm144005 MUTEX_EXIT(&nxge->poll_lock); 602898ecde52Stm144005 602998ecde52Stm144005 return (CHECK_LINK_RESCHEDULE); 603098ecde52Stm144005 } 603198ecde52Stm144005 603200161856Syc148097 /* 603300161856Syc148097 * Check status of MII (MIF or PCS) link. 603400161856Syc148097 * This function is called once per second, that is because this function 603500161856Syc148097 * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to 603600161856Syc148097 * call this function recursively. 603700161856Syc148097 */ 603859ac0c16Sdavemq static nxge_status_t 60396f45ec7bSml29623 nxge_check_mii_link(p_nxge_t nxgep) 60406f45ec7bSml29623 { 60416f45ec7bSml29623 mii_bmsr_t bmsr_ints, bmsr_data; 60426f45ec7bSml29623 mii_anlpar_t anlpar; 60436f45ec7bSml29623 mii_gsr_t gsr; 60446f45ec7bSml29623 p_mii_regs_t mii_regs; 60456f45ec7bSml29623 nxge_status_t status = NXGE_OK; 60466f45ec7bSml29623 uint8_t portn; 60476f45ec7bSml29623 nxge_link_state_t link_up; 60486f45ec7bSml29623 604998ecde52Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 605098ecde52Stm144005 return (NXGE_ERROR); 605198ecde52Stm144005 605298ecde52Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 605398ecde52Stm144005 return (NXGE_OK); 605498ecde52Stm144005 60556f45ec7bSml29623 portn = nxgep->mac.portnum; 60566f45ec7bSml29623 60576f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 60586f45ec7bSml29623 portn)); 60596f45ec7bSml29623 60606f45ec7bSml29623 mii_regs = NULL; 60616f45ec7bSml29623 60626f45ec7bSml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 60636f45ec7bSml29623 60646f45ec7bSml29623 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 60656f45ec7bSml29623 goto nxge_check_mii_link_exit; 60666f45ec7bSml29623 60672e59129aSraghus switch (nxgep->mac.portmode) { 60682e59129aSraghus default: 6069d81011f0Ssbehera bmsr_data.value = 0; 60702e59129aSraghus if ((status = nxge_mii_read(nxgep, 60712e59129aSraghus nxgep->statsp->mac_stats.xcvr_portn, 6072adfcba55Sjoycey #if defined(__i386) 6073adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->bmsr), 6074adfcba55Sjoycey #else 60756f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->bmsr), 6076adfcba55Sjoycey #endif 60772e59129aSraghus &bmsr_data.value)) != NXGE_OK) { 60786f45ec7bSml29623 goto fail; 60792e59129aSraghus } 60806f45ec7bSml29623 6081d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6082d81011f0Ssbehera "==> nxge_check_mii_link port<0x%x> " 6083d81011f0Ssbehera "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ", 60842d17280bSsbehera portn, bmsr_data.value, nxgep->bmsr.value)); 6085d81011f0Ssbehera 60866f45ec7bSml29623 if (nxgep->param_arr[param_autoneg].value) { 60876f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, 60886f45ec7bSml29623 nxgep->statsp->mac_stats.xcvr_portn, 6089adfcba55Sjoycey #if defined(__i386) 6090adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->gsr), 6091adfcba55Sjoycey #else 60926f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->gsr), 6093adfcba55Sjoycey #endif 60946f45ec7bSml29623 &gsr.value)) != NXGE_OK) 60956f45ec7bSml29623 goto fail; 60966f45ec7bSml29623 if ((status = nxge_mii_read(nxgep, 60976f45ec7bSml29623 nxgep->statsp->mac_stats.xcvr_portn, 6098adfcba55Sjoycey #if defined(__i386) 6099adfcba55Sjoycey (uint8_t)(uint32_t)(&mii_regs->anlpar), 6100adfcba55Sjoycey #else 61016f45ec7bSml29623 (uint8_t)(uint64_t)(&mii_regs->anlpar), 6102adfcba55Sjoycey #endif 61036f45ec7bSml29623 &anlpar.value)) != NXGE_OK) 61046f45ec7bSml29623 goto fail; 6105d81011f0Ssbehera if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) { 6106d81011f0Ssbehera 61076f45ec7bSml29623 if (nxgep->statsp->mac_stats.link_up && 61086f45ec7bSml29623 ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 61096f45ec7bSml29623 gsr.bits.link_1000fdx) || 61106f45ec7bSml29623 (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 61116f45ec7bSml29623 gsr.bits.link_1000hdx) || 61126f45ec7bSml29623 (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 61136f45ec7bSml29623 anlpar.bits.cap_100T4) || 61146f45ec7bSml29623 (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 61156f45ec7bSml29623 anlpar.bits.cap_100fdx) || 61166f45ec7bSml29623 (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 61176f45ec7bSml29623 anlpar.bits.cap_100hdx) || 61186f45ec7bSml29623 (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 61196f45ec7bSml29623 anlpar.bits.cap_10fdx) || 61206f45ec7bSml29623 (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 61216f45ec7bSml29623 anlpar.bits.cap_10hdx))) { 61226f45ec7bSml29623 bmsr_data.bits.link_status = 0; 61236f45ec7bSml29623 } 61246f45ec7bSml29623 } 6125d81011f0Ssbehera } 61266f45ec7bSml29623 61276f45ec7bSml29623 /* Workaround for link down issue */ 61286f45ec7bSml29623 if (bmsr_data.value == 0) { 61292e59129aSraghus cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n"); 61306f45ec7bSml29623 goto nxge_check_mii_link_exit; 61316f45ec7bSml29623 } 61326f45ec7bSml29623 6133d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6134d81011f0Ssbehera "==> nxge_check_mii_link port<0x%x> :" 6135d81011f0Ssbehera "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x", 61362d17280bSsbehera portn, nxgep->bmsr.value, bmsr_data.value)); 6137d81011f0Ssbehera 61386f45ec7bSml29623 bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 61396f45ec7bSml29623 nxgep->bmsr.value = bmsr_data.value; 6140d81011f0Ssbehera 6141d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6142d81011f0Ssbehera "==> nxge_check_mii_link port<0x%x> CALLING " 6143d81011f0Ssbehera "bmsr_data 0x%x bmsr_ints.value 0x%x", 61442d17280bSsbehera portn, bmsr_data.value, bmsr_ints.value)); 6145d81011f0Ssbehera 61462e59129aSraghus if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, 61472e59129aSraghus &link_up)) != NXGE_OK) { 61486f45ec7bSml29623 goto fail; 61492e59129aSraghus } 61502e59129aSraghus break; 61512e59129aSraghus 61522e59129aSraghus case PORT_1G_SERDES: 615300161856Syc148097 /* 615400161856Syc148097 * Above default is for all cases except PORT_1G_SERDES. 615500161856Syc148097 * The default case gets information from the PHY, but a 615600161856Syc148097 * nxge whose portmode equals PORT_1G_SERDES does not 615700161856Syc148097 * have a PHY. 615800161856Syc148097 */ 61592e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 61602e59129aSraghus "==> nxge_check_mii_link port<%d> (SERDES)", portn)); 616100161856Syc148097 nxge_pcs_check(nxgep, portn, &link_up); 61622e59129aSraghus break; 61632e59129aSraghus } 61646f45ec7bSml29623 61656f45ec7bSml29623 nxge_check_mii_link_exit: 61666f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 61676f45ec7bSml29623 if (link_up == LINK_IS_UP) { 61686f45ec7bSml29623 nxge_link_is_up(nxgep); 61696f45ec7bSml29623 } else if (link_up == LINK_IS_DOWN) { 61706f45ec7bSml29623 nxge_link_is_down(nxgep); 61716f45ec7bSml29623 } 61726f45ec7bSml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 61736f45ec7bSml29623 61746f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 61756f45ec7bSml29623 portn)); 61766f45ec7bSml29623 return (NXGE_OK); 61776f45ec7bSml29623 61786f45ec7bSml29623 fail: 61796f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 61806f45ec7bSml29623 61816f45ec7bSml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 61826f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 618352ccf843Smisaki "nxge_check_mii_link: Failed to check link port<%d>", portn)); 61846f45ec7bSml29623 return (status); 61856f45ec7bSml29623 } 61866f45ec7bSml29623 61876f45ec7bSml29623 /*ARGSUSED*/ 618859ac0c16Sdavemq static nxge_status_t 61896f45ec7bSml29623 nxge_check_10g_link(p_nxge_t nxgep) 61906f45ec7bSml29623 { 61916f45ec7bSml29623 uint8_t portn; 61926f45ec7bSml29623 nxge_status_t status = NXGE_OK; 6193763fcc44Ssbehera boolean_t link_up; 61942e59129aSraghus uint32_t val; 61952e59129aSraghus npi_status_t rs; 61966f45ec7bSml29623 619798ecde52Stm144005 if (nxgep->nxge_magic != NXGE_MAGIC) 619898ecde52Stm144005 return (NXGE_ERROR); 619998ecde52Stm144005 620098ecde52Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 620198ecde52Stm144005 return (NXGE_OK); 620298ecde52Stm144005 62036f45ec7bSml29623 portn = nxgep->mac.portnum; 6204d81011f0Ssbehera val = 0; 6205d81011f0Ssbehera rs = NPI_SUCCESS; 62066f45ec7bSml29623 62076f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 62086f45ec7bSml29623 portn)); 62096f45ec7bSml29623 62102e59129aSraghus switch (nxgep->mac.portmode) { 62112e59129aSraghus default: 62122d17280bSsbehera /* 62132d17280bSsbehera * Check if the phy is present in case of hot swappable phy 62142d17280bSsbehera */ 62152d17280bSsbehera if (nxgep->hot_swappable_phy) { 62162d17280bSsbehera boolean_t phy_present_now = B_FALSE; 62172d17280bSsbehera 621889282175SSantwona Behera if (nxge_hswap_phy_present(nxgep, portn)) 62192d17280bSsbehera phy_present_now = B_TRUE; 62202d17280bSsbehera 62211c7408c9Stc99174@train /* Check back-to-back XAUI connect to detect Opus NEM */ 62221c7408c9Stc99174@train rs = npi_xmac_xpcs_read(nxgep->npi_handle, 62231c7408c9Stc99174@train nxgep->mac.portnum, XPCS_REG_STATUS, &val); 62241c7408c9Stc99174@train if (rs != 0) 62251c7408c9Stc99174@train goto fail; 62261c7408c9Stc99174@train 62271c7408c9Stc99174@train link_up = B_FALSE; 62281c7408c9Stc99174@train if (val & XPCS_STATUS_LANE_ALIGN) { 62291c7408c9Stc99174@train link_up = B_TRUE; 62301c7408c9Stc99174@train } 62311c7408c9Stc99174@train 62322d17280bSsbehera if (nxgep->phy_absent) { 62332d17280bSsbehera if (phy_present_now) { 62342d17280bSsbehera /* 62352d17280bSsbehera * Detect, Initialize phy and do link up 62362d17280bSsbehera * set xcvr vals, link_init, nxge_init 62372d17280bSsbehera */ 62382d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 62392d17280bSsbehera "Hot swappable phy DETECTED!!")); 62402d17280bSsbehera nxgep->phy_absent = B_FALSE; 62412d17280bSsbehera (void) nxge_xcvr_find(nxgep); 62422d17280bSsbehera (void) nxge_link_init(nxgep); 62432d17280bSsbehera if (!(nxgep->drv_state & 62442d17280bSsbehera STATE_HW_INITIALIZED)) { 62452d17280bSsbehera status = nxge_init(nxgep); 62462d17280bSsbehera if (status != NXGE_OK) { 62472d17280bSsbehera NXGE_ERROR_MSG((nxgep, 62482d17280bSsbehera NXGE_ERR_CTL, 62492d17280bSsbehera "Hot swappable " 62502d17280bSsbehera "phy present, but" 62512d17280bSsbehera " driver init" 62522d17280bSsbehera " failed...")); 62532d17280bSsbehera goto fail; 62542d17280bSsbehera } 62552d17280bSsbehera } 62561c7408c9Stc99174@train } else if (link_up) { /* XAUI linkup, no PHY */ 62571c7408c9Stc99174@train /* 62581c7408c9Stc99174@train * This is the back-to-back XAUI 62591c7408c9Stc99174@train * connect case for Opus NEM. 62601c7408c9Stc99174@train */ 62611c7408c9Stc99174@train nxgep->statsp->mac_stats.xcvr_inuse = 62621c7408c9Stc99174@train XPCS_XCVR; 62631c7408c9Stc99174@train nxgep->mac.portmode = PORT_10G_SERDES; 62641c7408c9Stc99174@train NXGE_DEBUG_MSG((nxgep, MAC_CTL, 62651c7408c9Stc99174@train "HSP 10G Serdes DETECTED!!")); 62661c7408c9Stc99174@train break; 62672d17280bSsbehera } 62682d17280bSsbehera 6269774da109Stc99174@train if (nxgep->link_notify && 6270774da109Stc99174@train nxgep->link_check_count > 3 && 6271774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED || 6272774da109Stc99174@train nxgep->statsp->mac_stats.link_up == 1) { 6273774da109Stc99174@train nxgep->statsp->mac_stats.link_up = 0; 6274774da109Stc99174@train nxgep->statsp->mac_stats.link_speed = 0; 6275774da109Stc99174@train nxgep->statsp->mac_stats.link_duplex = 6276774da109Stc99174@train 0; 6277774da109Stc99174@train 6278774da109Stc99174@train nxge_link_is_down(nxgep); 6279774da109Stc99174@train nxgep->link_notify = B_FALSE; 6280774da109Stc99174@train } 6281774da109Stc99174@train 62822d17280bSsbehera goto start_link_check; 62832d17280bSsbehera 62842d17280bSsbehera } else if (!phy_present_now) { 62852d17280bSsbehera /* 62862d17280bSsbehera * Phy gone, bring link down reset xcvr vals 62872d17280bSsbehera */ 62882d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 62892d17280bSsbehera "Hot swappable phy REMOVED!!")); 62902d17280bSsbehera nxgep->phy_absent = B_TRUE; 62912d17280bSsbehera nxgep->statsp->mac_stats.link_up = 0; 62922d17280bSsbehera nxgep->statsp->mac_stats.link_speed = 0; 62932d17280bSsbehera nxgep->statsp->mac_stats.link_duplex = 0; 62942d17280bSsbehera nxge_link_is_down(nxgep); 62952d17280bSsbehera nxgep->link_notify = B_FALSE; 62962d17280bSsbehera 62972d17280bSsbehera (void) nxge_xcvr_find(nxgep); 62982d17280bSsbehera 62992d17280bSsbehera goto start_link_check; 63002d17280bSsbehera 63012d17280bSsbehera } 63022d17280bSsbehera } 630389282175SSantwona Behera 630489282175SSantwona Behera switch (nxgep->chip_id) { 630589282175SSantwona Behera case MRVL88X201X_CHIP_ID: 630600161856Syc148097 status = nxge_check_mrvl88x2011_link(nxgep, &link_up); 630789282175SSantwona Behera break; 630889282175SSantwona Behera case NLP2020_CHIP_ID: 630989282175SSantwona Behera status = nxge_check_nlp2020_link(nxgep, &link_up); 631089282175SSantwona Behera break; 631189282175SSantwona Behera default: 63126f45ec7bSml29623 status = nxge_check_bcm8704_link(nxgep, &link_up); 631389282175SSantwona Behera break; 631452cdd236Ssbehera } 631589282175SSantwona Behera 63166f45ec7bSml29623 if (status != NXGE_OK) 63176f45ec7bSml29623 goto fail; 63182e59129aSraghus break; 63192e59129aSraghus case PORT_10G_SERDES: 63202e59129aSraghus rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 6321763fcc44Ssbehera XPCS_REG_STATUS, &val); 63222e59129aSraghus if (rs != 0) 63232e59129aSraghus goto fail; 63242e59129aSraghus 63252e59129aSraghus link_up = B_FALSE; 6326763fcc44Ssbehera if (val & XPCS_STATUS_LANE_ALIGN) { 63272e59129aSraghus link_up = B_TRUE; 63282e59129aSraghus } 6329763fcc44Ssbehera 6330763fcc44Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 6331763fcc44Ssbehera "==> nxge_check_10g_link port<%d> " 6332763fcc44Ssbehera "XPCS_REG_STATUS2 0x%x link_up %d", 6333763fcc44Ssbehera portn, val, link_up)); 6334763fcc44Ssbehera 63352e59129aSraghus break; 63362e59129aSraghus } 63376f45ec7bSml29623 63386f45ec7bSml29623 if (link_up) { 6339774da109Stc99174@train if ((nxgep->link_notify && 6340774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) || 63416f45ec7bSml29623 nxgep->statsp->mac_stats.link_up == 0) { 63426f45ec7bSml29623 if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 63436f45ec7bSml29623 goto fail; 63446f45ec7bSml29623 nxgep->statsp->mac_stats.link_up = 1; 63456f45ec7bSml29623 nxgep->statsp->mac_stats.link_speed = 10000; 63466f45ec7bSml29623 nxgep->statsp->mac_stats.link_duplex = 2; 63476f45ec7bSml29623 63486f45ec7bSml29623 nxge_link_is_up(nxgep); 63496f45ec7bSml29623 nxgep->link_notify = B_FALSE; 63506f45ec7bSml29623 } 63516f45ec7bSml29623 } else { 6352774da109Stc99174@train if ((nxgep->link_notify && nxgep->link_check_count > 3 && 6353774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) || 63546f45ec7bSml29623 nxgep->statsp->mac_stats.link_up == 1) { 63556f45ec7bSml29623 if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 63566f45ec7bSml29623 goto fail; 63576f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 63586f45ec7bSml29623 "Link down cable problem")); 63596f45ec7bSml29623 nxgep->statsp->mac_stats.link_up = 0; 63606f45ec7bSml29623 nxgep->statsp->mac_stats.link_speed = 0; 63616f45ec7bSml29623 nxgep->statsp->mac_stats.link_duplex = 0; 63626f45ec7bSml29623 63636f45ec7bSml29623 nxge_link_is_down(nxgep); 63646f45ec7bSml29623 nxgep->link_notify = B_FALSE; 63651c7408c9Stc99174@train 63661c7408c9Stc99174@train if (nxgep->mac.portmode == PORT_10G_SERDES) { 63671c7408c9Stc99174@train /* 63681c7408c9Stc99174@train * NEM was unplugged, set up xcvr table 63691c7408c9Stc99174@train * to find another xcvr in the future. 63701c7408c9Stc99174@train */ 63711c7408c9Stc99174@train (void) nxge_xcvr_find(nxgep); 63721c7408c9Stc99174@train } 63736f45ec7bSml29623 } 63746f45ec7bSml29623 } 63756f45ec7bSml29623 63762d17280bSsbehera start_link_check: 63776f45ec7bSml29623 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 63786f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 63796f45ec7bSml29623 portn)); 63806f45ec7bSml29623 return (NXGE_OK); 63816f45ec7bSml29623 63826f45ec7bSml29623 fail: 638398ecde52Stm144005 (void) nxge_check_link_stop(nxgep); 638498ecde52Stm144005 63856f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 63866f45ec7bSml29623 "nxge_check_10g_link: Failed to check link port<%d>", 63876f45ec7bSml29623 portn)); 63886f45ec7bSml29623 return (status); 63896f45ec7bSml29623 } 63906f45ec7bSml29623 63916f45ec7bSml29623 63926f45ec7bSml29623 /* Declare link down */ 63936f45ec7bSml29623 63946f45ec7bSml29623 void 63956f45ec7bSml29623 nxge_link_is_down(p_nxge_t nxgep) 63966f45ec7bSml29623 { 639759ac0c16Sdavemq p_nxge_stats_t statsp; 639859ac0c16Sdavemq char link_stat_msg[64]; 639959ac0c16Sdavemq 64006f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 64016f45ec7bSml29623 640259ac0c16Sdavemq statsp = nxgep->statsp; 640359ac0c16Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 640459ac0c16Sdavemq statsp->mac_stats.xcvr_portn); 640559ac0c16Sdavemq 640659ac0c16Sdavemq if (nxge_no_msg == B_FALSE) { 640759ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 640859ac0c16Sdavemq } 640959ac0c16Sdavemq 64106f45ec7bSml29623 mac_link_update(nxgep->mach, LINK_STATE_DOWN); 64116f45ec7bSml29623 64126f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 64136f45ec7bSml29623 } 64146f45ec7bSml29623 64156f45ec7bSml29623 /* Declare link up */ 64166f45ec7bSml29623 64176f45ec7bSml29623 void 64186f45ec7bSml29623 nxge_link_is_up(p_nxge_t nxgep) 64196f45ec7bSml29623 { 642059ac0c16Sdavemq p_nxge_stats_t statsp; 642159ac0c16Sdavemq char link_stat_msg[64]; 64226f45ec7bSml29623 uint32_t val; 64236f45ec7bSml29623 64246f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 64256f45ec7bSml29623 642659ac0c16Sdavemq statsp = nxgep->statsp; 642759ac0c16Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 642859ac0c16Sdavemq statsp->mac_stats.xcvr_portn, 642959ac0c16Sdavemq statsp->mac_stats.link_speed); 643059ac0c16Sdavemq 643159ac0c16Sdavemq if (statsp->mac_stats.link_T4) 643259ac0c16Sdavemq (void) strcat(link_stat_msg, "T4"); 643359ac0c16Sdavemq else if (statsp->mac_stats.link_duplex == 2) 643459ac0c16Sdavemq (void) strcat(link_stat_msg, "full duplex"); 643559ac0c16Sdavemq else 643659ac0c16Sdavemq (void) strcat(link_stat_msg, "half duplex"); 643759ac0c16Sdavemq 64386f45ec7bSml29623 64396f45ec7bSml29623 /* Clean up symbol errors incurred during link transition */ 64402e59129aSraghus if ((nxgep->mac.portmode == PORT_10G_FIBER) || 644189282175SSantwona Behera (nxgep->mac.portmode == PORT_10G_COPPER) || 64422e59129aSraghus (nxgep->mac.portmode == PORT_10G_SERDES)) { 64436f45ec7bSml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 64446f45ec7bSml29623 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 64456f45ec7bSml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 64466f45ec7bSml29623 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 64476f45ec7bSml29623 } 64486f45ec7bSml29623 644900161856Syc148097 /* 645000161856Syc148097 * If the driver was plumbed without a link (therefore auto-negotiation 645100161856Syc148097 * could not complete), the driver will detect a link up when a cable 645200161856Syc148097 * conneting to a link partner is plugged into the port. By the time 645300161856Syc148097 * link-up is detected, auto-negotiation should have completed (The 645400161856Syc148097 * TN1010 tries to contact a link partner every 8~24ms). Here we re- 645500161856Syc148097 * configure the Neptune/NIU according to the newly negotiated speed. 645600161856Syc148097 * This is necessary only for the TN1010 basad device because only the 645700161856Syc148097 * TN1010 supports dual speeds. 645800161856Syc148097 */ 645900161856Syc148097 if (nxgep->mac.portmode == PORT_1G_TN1010 || 646000161856Syc148097 nxgep->mac.portmode == PORT_10G_TN1010) { 646100161856Syc148097 646200161856Syc148097 (void) nxge_set_tn1010_param(nxgep); 646300161856Syc148097 646400161856Syc148097 /* 646500161856Syc148097 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets 646600161856Syc148097 * nxgep->portmode) and nxge_setup_xcvr_table (which sets 646700161856Syc148097 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct). 646800161856Syc148097 */ 646900161856Syc148097 if (nxge_xcvr_find(nxgep) != NXGE_OK) { 647000161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 647100161856Syc148097 "nxge_link_is_up: nxge_xcvr_find failed")); 647200161856Syc148097 } 647300161856Syc148097 647400161856Syc148097 /* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */ 647500161856Syc148097 if (nxge_link_init(nxgep) != NXGE_OK) { 647600161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 647700161856Syc148097 "nxge_link_is_up: nxge_link_init failed")); 647800161856Syc148097 } 647900161856Syc148097 648000161856Syc148097 /* 648100161856Syc148097 * nxge_mac_init calls many subroutines including 648200161856Syc148097 * nxge_xif_init which sets XGMII or GMII mode 648300161856Syc148097 */ 648400161856Syc148097 if (nxge_mac_init(nxgep) != NXGE_OK) { 648500161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 648600161856Syc148097 "nxge_link_is_up: nxge_mac_init failed")); 648700161856Syc148097 } 648800161856Syc148097 } else { 648900161856Syc148097 (void) nxge_xif_init(nxgep); 649000161856Syc148097 } 649100161856Syc148097 649259ac0c16Sdavemq if (nxge_no_msg == B_FALSE) { 649359ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 649459ac0c16Sdavemq } 649559ac0c16Sdavemq 64966f45ec7bSml29623 mac_link_update(nxgep->mach, LINK_STATE_UP); 64976f45ec7bSml29623 64986f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 64996f45ec7bSml29623 } 65006f45ec7bSml29623 650100161856Syc148097 #ifdef NXGE_DEBUG 650200161856Syc148097 /* Dump all TN1010 Status registers */ 650300161856Syc148097 static void 650400161856Syc148097 nxge_dump_tn1010_status_regs(p_nxge_t nxgep) 650500161856Syc148097 { 650600161856Syc148097 uint16_t val; 650700161856Syc148097 650800161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 650900161856Syc148097 TN1010_PMA_PMD_DEV_ADDR, 1, &val); 651000161856Syc148097 cmn_err(CE_NOTE, "PMA status1 = 0x%x", val); 651100161856Syc148097 651200161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 651300161856Syc148097 TN1010_PMA_PMD_DEV_ADDR, 8, &val); 651400161856Syc148097 cmn_err(CE_NOTE, "PMA status2 = 0x%x", val); 651500161856Syc148097 651600161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 651700161856Syc148097 TN1010_PMA_PMD_DEV_ADDR, 129, &val); 651800161856Syc148097 cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val); 651900161856Syc148097 652000161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 652100161856Syc148097 TN1010_PCS_DEV_ADDR, 1, &val); 652200161856Syc148097 cmn_err(CE_NOTE, "PCS status1 = 0x%x", val); 652300161856Syc148097 652400161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 652500161856Syc148097 TN1010_PCS_DEV_ADDR, 8, &val); 652600161856Syc148097 cmn_err(CE_NOTE, "PCS status2 = 0x%x", val); 652700161856Syc148097 652800161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 652900161856Syc148097 TN1010_PCS_DEV_ADDR, 32, &val); 653000161856Syc148097 cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val); 653100161856Syc148097 653200161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 653300161856Syc148097 TN1010_PCS_DEV_ADDR, 33, &val); 653400161856Syc148097 cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val); 653500161856Syc148097 653600161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 653700161856Syc148097 TN1010_PHYXS_DEV_ADDR, 1, &val); 653800161856Syc148097 cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val); 653900161856Syc148097 654000161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 654100161856Syc148097 TN1010_PHYXS_DEV_ADDR, 8, &val); 654200161856Syc148097 cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val); 654300161856Syc148097 654400161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 654500161856Syc148097 TN1010_PHYXS_DEV_ADDR, 24, &val); 654600161856Syc148097 cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val); 654700161856Syc148097 654800161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 654900161856Syc148097 TN1010_AUTONEG_DEV_ADDR, 1, &val); 655000161856Syc148097 cmn_err(CE_NOTE, "Autoneg status = 0x%x", val); 655100161856Syc148097 655200161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 655300161856Syc148097 TN1010_AUTONEG_DEV_ADDR, 33, &val); 655400161856Syc148097 cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val); 655500161856Syc148097 655600161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 655700161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val); 655800161856Syc148097 cmn_err(CE_NOTE, "TN1010 status = 0x%x", val); 655900161856Syc148097 656000161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 656100161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val); 656200161856Syc148097 cmn_err(CE_NOTE, "Device status = 0x%x", val); 656300161856Syc148097 656400161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 656500161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val); 656600161856Syc148097 cmn_err(CE_NOTE, "DDR status = 0x%x", val); 656700161856Syc148097 656800161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 656900161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val); 657000161856Syc148097 cmn_err(CE_NOTE, "DDR fault status = 0x%x", val); 657100161856Syc148097 657200161856Syc148097 nxge_mdio_read(nxgep, nxgep->xcvr_addr, 657300161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val); 657400161856Syc148097 cmn_err(CE_NOTE, "Firmware Revision = 0x%x Major = 0x%x Minor = 0x%x", 657500161856Syc148097 val, (val & 0xFF00) >> 8, val & 0x00FF); 657600161856Syc148097 } 657700161856Syc148097 #endif 657800161856Syc148097 65796f45ec7bSml29623 /* 65806f45ec7bSml29623 * Calculate the bit in the multicast address filter 65816f45ec7bSml29623 * that selects the given * address. 65826f45ec7bSml29623 * Note: For GEM, the last 8-bits are used. 65836f45ec7bSml29623 */ 65846f45ec7bSml29623 uint32_t 65856f45ec7bSml29623 crc32_mchash(p_ether_addr_t addr) 65866f45ec7bSml29623 { 65876f45ec7bSml29623 uint8_t *cp; 65886f45ec7bSml29623 uint32_t crc; 65896f45ec7bSml29623 uint32_t c; 65906f45ec7bSml29623 int byte; 65916f45ec7bSml29623 int bit; 65926f45ec7bSml29623 65936f45ec7bSml29623 cp = (uint8_t *)addr; 65946f45ec7bSml29623 crc = (uint32_t)0xffffffff; 65956f45ec7bSml29623 for (byte = 0; byte < 6; byte++) { 65966f45ec7bSml29623 c = (uint32_t)cp[byte]; 65976f45ec7bSml29623 for (bit = 0; bit < 8; bit++) { 65986f45ec7bSml29623 if ((c & 0x1) ^ (crc & 0x1)) 65996f45ec7bSml29623 crc = (crc >> 1)^0xedb88320; 66006f45ec7bSml29623 else 66016f45ec7bSml29623 crc = (crc >> 1); 66026f45ec7bSml29623 c >>= 1; 66036f45ec7bSml29623 } 66046f45ec7bSml29623 } 66056f45ec7bSml29623 return ((~crc) >> (32 - HASH_BITS)); 66066f45ec7bSml29623 } 66076f45ec7bSml29623 66086f45ec7bSml29623 /* Reset serdes */ 66096f45ec7bSml29623 66106f45ec7bSml29623 nxge_status_t 66116f45ec7bSml29623 nxge_serdes_reset(p_nxge_t nxgep) 66126f45ec7bSml29623 { 66136f45ec7bSml29623 npi_handle_t handle; 66146f45ec7bSml29623 66156f45ec7bSml29623 handle = nxgep->npi_handle; 66166f45ec7bSml29623 66176f45ec7bSml29623 ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 66186f45ec7bSml29623 drv_usecwait(500); 66196f45ec7bSml29623 ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 66206f45ec7bSml29623 66216f45ec7bSml29623 return (NXGE_OK); 66226f45ec7bSml29623 } 66236f45ec7bSml29623 662400161856Syc148097 /* 662500161856Syc148097 * This function monitors link status using interrupt or polling. 662600161856Syc148097 * It calls nxgep->xcvr.check_link, a member function of 662700161856Syc148097 * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this 662800161856Syc148097 * function back, that is why the check_link routine is 662900161856Syc148097 * executed periodically. 663000161856Syc148097 */ 66316f45ec7bSml29623 nxge_status_t 66326f45ec7bSml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 66336f45ec7bSml29623 { 66346f45ec7bSml29623 nxge_status_t status = NXGE_OK; 66356f45ec7bSml29623 6636678453a8Sspeer /* If we are a guest domain driver, don't bother. */ 6637678453a8Sspeer if (isLDOMguest(nxgep)) 6638678453a8Sspeer return (status); 6639678453a8Sspeer 66406f45ec7bSml29623 /* 664198ecde52Stm144005 * Return immediately if this is an imaginary XMAC port. 664298ecde52Stm144005 * (At least, we don't have 4-port XMAC cards yet.) 66436f45ec7bSml29623 */ 66442e59129aSraghus if ((nxgep->mac.portmode == PORT_10G_FIBER || 664589282175SSantwona Behera nxgep->mac.portmode == PORT_10G_COPPER || 66462e59129aSraghus nxgep->mac.portmode == PORT_10G_SERDES) && 66472e59129aSraghus (nxgep->mac.portnum > 1)) 66486f45ec7bSml29623 return (NXGE_OK); 66496f45ec7bSml29623 66506f45ec7bSml29623 if (nxgep->statsp == NULL) { 66516f45ec7bSml29623 /* stats has not been allocated. */ 66526f45ec7bSml29623 return (NXGE_OK); 66536f45ec7bSml29623 } 6654321febdeSsbehera /* Don't check link if we're in internal loopback mode */ 6655321febdeSsbehera if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g) 66566f45ec7bSml29623 return (NXGE_OK); 66576f45ec7bSml29623 66586f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 66596f45ec7bSml29623 "==> nxge_link_monitor port<%d> enable=%d", 66606f45ec7bSml29623 nxgep->mac.portnum, enable)); 66616f45ec7bSml29623 if (enable == LINK_MONITOR_START) { 66626f45ec7bSml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 66636f45ec7bSml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 66646f45ec7bSml29623 != NXGE_OK) 66656f45ec7bSml29623 goto fail; 66666f45ec7bSml29623 } else { 666798ecde52Stm144005 timeout_id_t timerid; 666800161856Syc148097 /* 666900161856Syc148097 * check_link_stop means "Stop the link check", so 667000161856Syc148097 * we return without starting the timer. 667100161856Syc148097 */ 667298ecde52Stm144005 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 667398ecde52Stm144005 return (NXGE_OK); 667498ecde52Stm144005 667500161856Syc148097 /* 667600161856Syc148097 * Otherwise fire the timer for the nxge to check 667700161856Syc148097 * the link using the check_link function 667800161856Syc148097 * of the nxge_xcvr_table and pass "nxgep" as the 667900161856Syc148097 * argument to the check_link function. 668000161856Syc148097 */ 668159ac0c16Sdavemq if (nxgep->xcvr.check_link) { 668259ac0c16Sdavemq timerid = timeout( 668359ac0c16Sdavemq (fptrv_t)(nxgep->xcvr.check_link), 66846f45ec7bSml29623 nxgep, 668598ecde52Stm144005 drv_usectohz(LINK_MONITOR_PERIOD)); 668698ecde52Stm144005 MUTEX_ENTER(&nxgep->poll_lock); 668798ecde52Stm144005 nxgep->nxge_link_poll_timerid = timerid; 668898ecde52Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 6689774da109Stc99174@train nxgep->link_check_count ++; 669059ac0c16Sdavemq } else { 669159ac0c16Sdavemq return (NXGE_ERROR); 669259ac0c16Sdavemq } 66936f45ec7bSml29623 } 66946f45ec7bSml29623 } else { 66956f45ec7bSml29623 if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 66966f45ec7bSml29623 if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 66976f45ec7bSml29623 != NXGE_OK) 66986f45ec7bSml29623 goto fail; 66996f45ec7bSml29623 } else { 670098ecde52Stm144005 clock_t rv; 670198ecde52Stm144005 670298ecde52Stm144005 MUTEX_ENTER(&nxgep->poll_lock); 670398ecde52Stm144005 670498ecde52Stm144005 /* If <timerid> == 0, the link monitor has */ 670598ecde52Stm144005 /* never been started, or just now stopped. */ 670698ecde52Stm144005 if (nxgep->nxge_link_poll_timerid == 0) { 670798ecde52Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 670898ecde52Stm144005 return (NXGE_OK); 670998ecde52Stm144005 } 671098ecde52Stm144005 671198ecde52Stm144005 nxgep->poll_state = LINK_MONITOR_STOPPING; 6712d3d50737SRafael Vanoni rv = cv_reltimedwait(&nxgep->poll_cv, &nxgep->poll_lock, 671398ecde52Stm144005 drv_usectohz(LM_WAIT_MULTIPLIER * 6714d3d50737SRafael Vanoni LINK_MONITOR_PERIOD), TR_CLOCK_TICK); 671598ecde52Stm144005 if (rv == -1) { 671698ecde52Stm144005 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 671798ecde52Stm144005 "==> stopping port %d: " 671898ecde52Stm144005 "cv_timedwait(%d) timed out", 671998ecde52Stm144005 nxgep->mac.portnum, nxgep->poll_state)); 672098ecde52Stm144005 nxgep->poll_state = LINK_MONITOR_STOP; 67216f45ec7bSml29623 nxgep->nxge_link_poll_timerid = 0; 67226f45ec7bSml29623 } 672398ecde52Stm144005 672498ecde52Stm144005 MUTEX_EXIT(&nxgep->poll_lock); 67256f45ec7bSml29623 } 67266f45ec7bSml29623 } 67276f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 67286f45ec7bSml29623 "<== nxge_link_monitor port<%d> enable=%d", 67296f45ec7bSml29623 nxgep->mac.portnum, enable)); 6730678453a8Sspeer 67316f45ec7bSml29623 return (NXGE_OK); 67326f45ec7bSml29623 fail: 67336f45ec7bSml29623 return (status); 673400161856Syc148097 67356f45ec7bSml29623 } 67366f45ec7bSml29623 673700161856Syc148097 nxge_status_t 673800161856Syc148097 nxge_check_tn1010_link(p_nxge_t nxgep) 673900161856Syc148097 { 674000161856Syc148097 nxge_status_t status = NXGE_OK; 674100161856Syc148097 nxge_link_state_t link_up; 674200161856Syc148097 674300161856Syc148097 if (nxgep->nxge_magic != NXGE_MAGIC) { 674400161856Syc148097 /* magic is 0 if driver is not attached */ 674500161856Syc148097 return (NXGE_ERROR); 674600161856Syc148097 } 674700161856Syc148097 674800161856Syc148097 /* Link has been stopped, no need to continue */ 674900161856Syc148097 if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) { 675000161856Syc148097 return (NXGE_OK); 675100161856Syc148097 } 675200161856Syc148097 675300161856Syc148097 if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 675400161856Syc148097 goto nxge_check_tn1010_link_exit; 675500161856Syc148097 675600161856Syc148097 if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK) 675700161856Syc148097 goto fail; 675800161856Syc148097 675900161856Syc148097 nxge_check_tn1010_link_exit: 676000161856Syc148097 if (link_up == LINK_IS_UP) 676100161856Syc148097 nxge_link_is_up(nxgep); 676200161856Syc148097 else if (link_up == LINK_IS_DOWN) 676300161856Syc148097 nxge_link_is_down(nxgep); 676400161856Syc148097 676500161856Syc148097 /* 676600161856Syc148097 * nxge_link_monitor will call (nxgep->xcvr.check_link) 676700161856Syc148097 * which could be THIS function. 676800161856Syc148097 */ 676900161856Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 677000161856Syc148097 677100161856Syc148097 return (NXGE_OK); 677200161856Syc148097 677300161856Syc148097 fail: 677400161856Syc148097 (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 677500161856Syc148097 677600161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 677700161856Syc148097 "nxge_check_tn1010_link: Failed to check link")); 677800161856Syc148097 return (status); 677900161856Syc148097 } 678000161856Syc148097 678100161856Syc148097 678200161856Syc148097 /* 678300161856Syc148097 * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN. 678400161856Syc148097 */ 678500161856Syc148097 static nxge_status_t 678600161856Syc148097 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up) 678700161856Syc148097 { 678800161856Syc148097 nxge_status_t status = NXGE_OK; 678900161856Syc148097 p_nxge_stats_t statsp; 679000161856Syc148097 uint8_t phy_port_addr, portn; 679100161856Syc148097 uint16_t val; 679200161856Syc148097 679300161856Syc148097 *link_up = LINK_NO_CHANGE; 679400161856Syc148097 679500161856Syc148097 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 679600161856Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 679700161856Syc148097 statsp = nxgep->statsp; 679800161856Syc148097 679900161856Syc148097 /* Check if link is up */ 680000161856Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 680100161856Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val)) 680200161856Syc148097 != NXGE_OK) { 680300161856Syc148097 goto fail; 680400161856Syc148097 } 680500161856Syc148097 /* 680600161856Syc148097 * nxge_link_is_up has called nxge_set_tn1010_param and set 680700161856Syc148097 * portmode and link_speed 680800161856Syc148097 */ 680900161856Syc148097 if (val & TN1010_AN_LINK_STAT_BIT) { 6810774da109Stc99174@train if ((nxgep->link_notify && 6811774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) || 681200161856Syc148097 nxgep->statsp->mac_stats.link_up == 0) { 681300161856Syc148097 statsp->mac_stats.link_up = 1; 681400161856Syc148097 statsp->mac_stats.link_duplex = 2; 681500161856Syc148097 *link_up = LINK_IS_UP; 681600161856Syc148097 nxgep->link_notify = B_FALSE; 681700161856Syc148097 } 681800161856Syc148097 } else { 6819774da109Stc99174@train if ((nxgep->link_notify && nxgep->link_check_count > 3 && 6820774da109Stc99174@train nxgep->nxge_mac_state == NXGE_MAC_STARTED) || 682100161856Syc148097 nxgep->statsp->mac_stats.link_up == 1) { 682200161856Syc148097 statsp->mac_stats.link_up = 0; 682300161856Syc148097 statsp->mac_stats.link_speed = 0; 682400161856Syc148097 statsp->mac_stats.link_duplex = 0; 682500161856Syc148097 *link_up = LINK_IS_DOWN; 682600161856Syc148097 nxgep->link_notify = B_FALSE; 682700161856Syc148097 } 682800161856Syc148097 } 682900161856Syc148097 return (NXGE_OK); 683000161856Syc148097 683100161856Syc148097 fail: 683200161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 683300161856Syc148097 "nxge_tn1010_check: Unable to check TN1010")); 683400161856Syc148097 return (status); 683500161856Syc148097 } 683600161856Syc148097 683700161856Syc148097 68386f45ec7bSml29623 /* Set promiscous mode */ 68396f45ec7bSml29623 68406f45ec7bSml29623 nxge_status_t 68416f45ec7bSml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 68426f45ec7bSml29623 { 68436f45ec7bSml29623 nxge_status_t status = NXGE_OK; 68446f45ec7bSml29623 684559ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 68466f45ec7bSml29623 68476f45ec7bSml29623 nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 68486f45ec7bSml29623 68496f45ec7bSml29623 RW_ENTER_WRITER(&nxgep->filter_lock); 68506f45ec7bSml29623 68516f45ec7bSml29623 if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 68526f45ec7bSml29623 goto fail; 68536f45ec7bSml29623 } 68546f45ec7bSml29623 if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 68556f45ec7bSml29623 goto fail; 68566f45ec7bSml29623 } 68576f45ec7bSml29623 68586f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 68596f45ec7bSml29623 68606f45ec7bSml29623 if (on) 68616f45ec7bSml29623 nxgep->statsp->mac_stats.promisc = B_TRUE; 68626f45ec7bSml29623 else 68636f45ec7bSml29623 nxgep->statsp->mac_stats.promisc = B_FALSE; 68646f45ec7bSml29623 68656f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 68666f45ec7bSml29623 68676f45ec7bSml29623 return (NXGE_OK); 68686f45ec7bSml29623 fail: 68696f45ec7bSml29623 RW_EXIT(&nxgep->filter_lock); 68706f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 68716f45ec7bSml29623 "Unable to set promisc (%d)", on)); 68726f45ec7bSml29623 68736f45ec7bSml29623 return (status); 68746f45ec7bSml29623 } 68756f45ec7bSml29623 68766f45ec7bSml29623 /*ARGSUSED*/ 68776f45ec7bSml29623 uint_t 68786f45ec7bSml29623 nxge_mif_intr(void *arg1, void *arg2) 68796f45ec7bSml29623 { 68806f45ec7bSml29623 #ifdef NXGE_DEBUG 68816f45ec7bSml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 68826f45ec7bSml29623 #endif 68836f45ec7bSml29623 #if NXGE_MIF 68846f45ec7bSml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 68856f45ec7bSml29623 uint32_t status; 68866f45ec7bSml29623 npi_handle_t handle; 68876f45ec7bSml29623 uint8_t portn; 68886f45ec7bSml29623 p_nxge_stats_t statsp; 68896f45ec7bSml29623 #endif 68906f45ec7bSml29623 68916f45ec7bSml29623 #ifdef NXGE_MIF 68926f45ec7bSml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 68936f45ec7bSml29623 nxgep = ldvp->nxgep; 68946f45ec7bSml29623 } 68956f45ec7bSml29623 nxgep = ldvp->nxgep; 68966f45ec7bSml29623 #endif 68976f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 68986f45ec7bSml29623 68996f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 69006f45ec7bSml29623 return (DDI_INTR_CLAIMED); 69016f45ec7bSml29623 69026f45ec7bSml29623 mif_intr_fail: 69036f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 69046f45ec7bSml29623 return (DDI_INTR_UNCLAIMED); 69056f45ec7bSml29623 } 69066f45ec7bSml29623 69076f45ec7bSml29623 /*ARGSUSED*/ 69086f45ec7bSml29623 uint_t 69096f45ec7bSml29623 nxge_mac_intr(void *arg1, void *arg2) 69106f45ec7bSml29623 { 69116f45ec7bSml29623 p_nxge_t nxgep = (p_nxge_t)arg2; 69126f45ec7bSml29623 p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 69136f45ec7bSml29623 p_nxge_ldg_t ldgp; 69146f45ec7bSml29623 uint32_t status; 69156f45ec7bSml29623 npi_handle_t handle; 69166f45ec7bSml29623 uint8_t portn; 69176f45ec7bSml29623 p_nxge_stats_t statsp; 69186f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 69196f45ec7bSml29623 69206f45ec7bSml29623 if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 69216f45ec7bSml29623 nxgep = ldvp->nxgep; 69226f45ec7bSml29623 } 69236f45ec7bSml29623 69246f45ec7bSml29623 ldgp = ldvp->ldgp; 69256f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 69266f45ec7bSml29623 "group %d", ldgp->ldg)); 69276f45ec7bSml29623 69286f45ec7bSml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep); 69296f45ec7bSml29623 /* 69306f45ec7bSml29623 * This interrupt handler is for a specific 69316f45ec7bSml29623 * mac port. 69326f45ec7bSml29623 */ 69336f45ec7bSml29623 statsp = (p_nxge_stats_t)nxgep->statsp; 69346f45ec7bSml29623 portn = nxgep->mac.portnum; 69356f45ec7bSml29623 69366f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, 69376f45ec7bSml29623 "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 69386f45ec7bSml29623 69396f45ec7bSml29623 if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 69406f45ec7bSml29623 rs = npi_xmac_tx_get_istatus(handle, portn, 69416f45ec7bSml29623 (xmac_tx_iconfig_t *)&status); 69426f45ec7bSml29623 if (rs != NPI_SUCCESS) 69436f45ec7bSml29623 goto npi_fail; 69446f45ec7bSml29623 if (status & ICFG_XMAC_TX_ALL) { 69456f45ec7bSml29623 if (status & ICFG_XMAC_TX_UNDERRUN) { 69466f45ec7bSml29623 statsp->xmac_stats.tx_underflow_err++; 69476f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 69486f45ec7bSml29623 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 69496f45ec7bSml29623 } 69506f45ec7bSml29623 if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 69516f45ec7bSml29623 statsp->xmac_stats.tx_maxpktsize_err++; 6952f6485eecSyc148097 /* 6953f6485eecSyc148097 * Do not send FMA ereport because this 6954f6485eecSyc148097 * error does not indicate HW failure. 6955f6485eecSyc148097 */ 69566f45ec7bSml29623 } 69576f45ec7bSml29623 if (status & ICFG_XMAC_TX_OVERFLOW) { 69586f45ec7bSml29623 statsp->xmac_stats.tx_overflow_err++; 69596f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 69606f45ec7bSml29623 NXGE_FM_EREPORT_TXMAC_OVERFLOW); 69616f45ec7bSml29623 } 69626f45ec7bSml29623 if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 69636f45ec7bSml29623 statsp->xmac_stats.tx_fifo_xfr_err++; 69646f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 69656f45ec7bSml29623 NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 69666f45ec7bSml29623 } 69676f45ec7bSml29623 if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 69686f45ec7bSml29623 statsp->xmac_stats.tx_byte_cnt += 69696f45ec7bSml29623 XTXMAC_BYTE_CNT_MASK; 69706f45ec7bSml29623 } 69716f45ec7bSml29623 if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 69726f45ec7bSml29623 statsp->xmac_stats.tx_frame_cnt += 69736f45ec7bSml29623 XTXMAC_FRM_CNT_MASK; 69746f45ec7bSml29623 } 69756f45ec7bSml29623 } 69766f45ec7bSml29623 69776f45ec7bSml29623 rs = npi_xmac_rx_get_istatus(handle, portn, 69786f45ec7bSml29623 (xmac_rx_iconfig_t *)&status); 69796f45ec7bSml29623 if (rs != NPI_SUCCESS) 69806f45ec7bSml29623 goto npi_fail; 69816f45ec7bSml29623 if (status & ICFG_XMAC_RX_ALL) { 69826f45ec7bSml29623 if (status & ICFG_XMAC_RX_OVERFLOW) 69836f45ec7bSml29623 statsp->xmac_stats.rx_overflow_err++; 69846f45ec7bSml29623 if (status & ICFG_XMAC_RX_UNDERFLOW) { 69856f45ec7bSml29623 statsp->xmac_stats.rx_underflow_err++; 69866f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 69876f45ec7bSml29623 NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 69886f45ec7bSml29623 } 6989f6485eecSyc148097 /* 6990f6485eecSyc148097 * Do not send FMA ereport for the following 3 errors 6991f6485eecSyc148097 * because they do not indicate HW failures. 6992f6485eecSyc148097 */ 69936f45ec7bSml29623 if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 69946f45ec7bSml29623 statsp->xmac_stats.rx_crc_err_cnt += 69956f45ec7bSml29623 XRXMAC_CRC_ER_CNT_MASK; 69966f45ec7bSml29623 } 69976f45ec7bSml29623 if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 69986f45ec7bSml29623 statsp->xmac_stats.rx_len_err_cnt += 69996f45ec7bSml29623 MAC_LEN_ER_CNT_MASK; 70006f45ec7bSml29623 } 70016f45ec7bSml29623 if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 70026f45ec7bSml29623 statsp->xmac_stats.rx_viol_err_cnt += 70036f45ec7bSml29623 XRXMAC_CD_VIO_CNT_MASK; 70046f45ec7bSml29623 } 70056f45ec7bSml29623 if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 70066f45ec7bSml29623 statsp->xmac_stats.rx_byte_cnt += 70076f45ec7bSml29623 XRXMAC_BT_CNT_MASK; 70086f45ec7bSml29623 } 70096f45ec7bSml29623 if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 70106f45ec7bSml29623 statsp->xmac_stats.rx_hist1_cnt += 70116f45ec7bSml29623 XRXMAC_HIST_CNT1_MASK; 70126f45ec7bSml29623 } 70136f45ec7bSml29623 if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 70146f45ec7bSml29623 statsp->xmac_stats.rx_hist2_cnt += 70156f45ec7bSml29623 XRXMAC_HIST_CNT2_MASK; 70166f45ec7bSml29623 } 70176f45ec7bSml29623 if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 70186f45ec7bSml29623 statsp->xmac_stats.rx_hist3_cnt += 70196f45ec7bSml29623 XRXMAC_HIST_CNT3_MASK; 70206f45ec7bSml29623 } 70216f45ec7bSml29623 if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 70226f45ec7bSml29623 statsp->xmac_stats.rx_hist4_cnt += 70236f45ec7bSml29623 XRXMAC_HIST_CNT4_MASK; 70246f45ec7bSml29623 } 70256f45ec7bSml29623 if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 70266f45ec7bSml29623 statsp->xmac_stats.rx_hist5_cnt += 70276f45ec7bSml29623 XRXMAC_HIST_CNT5_MASK; 70286f45ec7bSml29623 } 70296f45ec7bSml29623 if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 70306f45ec7bSml29623 statsp->xmac_stats.rx_hist6_cnt += 70316f45ec7bSml29623 XRXMAC_HIST_CNT6_MASK; 70326f45ec7bSml29623 } 70336f45ec7bSml29623 if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 70346f45ec7bSml29623 statsp->xmac_stats.rx_broadcast_cnt += 70356f45ec7bSml29623 XRXMAC_BC_FRM_CNT_MASK; 70366f45ec7bSml29623 } 70376f45ec7bSml29623 if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 70386f45ec7bSml29623 statsp->xmac_stats.rx_mult_cnt += 70396f45ec7bSml29623 XRXMAC_MC_FRM_CNT_MASK; 70406f45ec7bSml29623 } 7041f6485eecSyc148097 /* 7042f6485eecSyc148097 * Do not send FMA ereport for the following 3 errors 7043f6485eecSyc148097 * because they do not indicate HW failures. 7044f6485eecSyc148097 */ 70456f45ec7bSml29623 if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 70466f45ec7bSml29623 statsp->xmac_stats.rx_frag_cnt += 70476f45ec7bSml29623 XRXMAC_FRAG_CNT_MASK; 70486f45ec7bSml29623 } 70496f45ec7bSml29623 if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 70506f45ec7bSml29623 statsp->xmac_stats.rx_frame_align_err_cnt += 70516f45ec7bSml29623 XRXMAC_AL_ER_CNT_MASK; 70526f45ec7bSml29623 } 70536f45ec7bSml29623 if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 70546f45ec7bSml29623 statsp->xmac_stats.rx_linkfault_err_cnt += 70556f45ec7bSml29623 XMAC_LINK_FLT_CNT_MASK; 70566f45ec7bSml29623 } 70576f45ec7bSml29623 if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 70586f45ec7bSml29623 statsp->xmac_stats.rx_remotefault_err++; 70596f45ec7bSml29623 } 70606f45ec7bSml29623 if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 70616f45ec7bSml29623 statsp->xmac_stats.rx_localfault_err++; 70626f45ec7bSml29623 } 70636f45ec7bSml29623 } 70646f45ec7bSml29623 70656f45ec7bSml29623 rs = npi_xmac_ctl_get_istatus(handle, portn, 70666f45ec7bSml29623 (xmac_ctl_iconfig_t *)&status); 70676f45ec7bSml29623 if (rs != NPI_SUCCESS) 70686f45ec7bSml29623 goto npi_fail; 70696f45ec7bSml29623 if (status & ICFG_XMAC_CTRL_ALL) { 70706f45ec7bSml29623 if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 70716f45ec7bSml29623 statsp->xmac_stats.rx_pause_cnt++; 70726f45ec7bSml29623 if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 70736f45ec7bSml29623 statsp->xmac_stats.tx_pause_state++; 70746f45ec7bSml29623 if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 70756f45ec7bSml29623 statsp->xmac_stats.tx_nopause_state++; 70766f45ec7bSml29623 } 70776f45ec7bSml29623 } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 70786f45ec7bSml29623 rs = npi_bmac_tx_get_istatus(handle, portn, 70796f45ec7bSml29623 (bmac_tx_iconfig_t *)&status); 70806f45ec7bSml29623 if (rs != NPI_SUCCESS) 70816f45ec7bSml29623 goto npi_fail; 70826f45ec7bSml29623 if (status & ICFG_BMAC_TX_ALL) { 70836f45ec7bSml29623 if (status & ICFG_BMAC_TX_UNDERFLOW) { 70846f45ec7bSml29623 statsp->bmac_stats.tx_underrun_err++; 70856f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 70866f45ec7bSml29623 NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 70876f45ec7bSml29623 } 70886f45ec7bSml29623 if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 70896f45ec7bSml29623 statsp->bmac_stats.tx_max_pkt_err++; 70906f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 70916f45ec7bSml29623 NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 70926f45ec7bSml29623 } 70936f45ec7bSml29623 if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 70946f45ec7bSml29623 statsp->bmac_stats.tx_byte_cnt += 70956f45ec7bSml29623 BTXMAC_BYTE_CNT_MASK; 70966f45ec7bSml29623 } 70976f45ec7bSml29623 if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 70986f45ec7bSml29623 statsp->bmac_stats.tx_frame_cnt += 70996f45ec7bSml29623 BTXMAC_FRM_CNT_MASK; 71006f45ec7bSml29623 } 71016f45ec7bSml29623 } 71026f45ec7bSml29623 71036f45ec7bSml29623 rs = npi_bmac_rx_get_istatus(handle, portn, 71046f45ec7bSml29623 (bmac_rx_iconfig_t *)&status); 71056f45ec7bSml29623 if (rs != NPI_SUCCESS) 71066f45ec7bSml29623 goto npi_fail; 71076f45ec7bSml29623 if (status & ICFG_BMAC_RX_ALL) { 71086f45ec7bSml29623 if (status & ICFG_BMAC_RX_OVERFLOW) { 71096f45ec7bSml29623 statsp->bmac_stats.rx_overflow_err++; 71106f45ec7bSml29623 } 71116f45ec7bSml29623 if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 71126f45ec7bSml29623 statsp->bmac_stats.rx_frame_cnt += 71136f45ec7bSml29623 RXMAC_FRM_CNT_MASK; 71146f45ec7bSml29623 } 71156f45ec7bSml29623 if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 71166f45ec7bSml29623 statsp->bmac_stats.rx_crc_err_cnt += 71176f45ec7bSml29623 BMAC_CRC_ER_CNT_MASK; 71186f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 71196f45ec7bSml29623 NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 71206f45ec7bSml29623 } 71216f45ec7bSml29623 if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 71226f45ec7bSml29623 statsp->bmac_stats.rx_len_err_cnt += 71236f45ec7bSml29623 MAC_LEN_ER_CNT_MASK; 71246f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 71256f45ec7bSml29623 NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 71266f45ec7bSml29623 } 71276f45ec7bSml29623 if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 71286f45ec7bSml29623 statsp->bmac_stats.rx_viol_err_cnt += 71296f45ec7bSml29623 BMAC_CD_VIO_CNT_MASK; 71306f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 71316f45ec7bSml29623 NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 71326f45ec7bSml29623 } 71336f45ec7bSml29623 if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 71346f45ec7bSml29623 statsp->bmac_stats.rx_byte_cnt += 71356f45ec7bSml29623 BRXMAC_BYTE_CNT_MASK; 71366f45ec7bSml29623 } 71376f45ec7bSml29623 if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 71386f45ec7bSml29623 statsp->bmac_stats.rx_align_err_cnt += 71396f45ec7bSml29623 BMAC_AL_ER_CNT_MASK; 71406f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 71416f45ec7bSml29623 NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 71426f45ec7bSml29623 } 71436f45ec7bSml29623 71446f45ec7bSml29623 rs = npi_bmac_ctl_get_istatus(handle, portn, 71456f45ec7bSml29623 (bmac_ctl_iconfig_t *)&status); 71466f45ec7bSml29623 if (rs != NPI_SUCCESS) 71476f45ec7bSml29623 goto npi_fail; 71486f45ec7bSml29623 71496f45ec7bSml29623 if (status & ICFG_BMAC_CTL_ALL) { 71506f45ec7bSml29623 if (status & ICFG_BMAC_CTL_RCVPAUSE) 71516f45ec7bSml29623 statsp->bmac_stats.rx_pause_cnt++; 71526f45ec7bSml29623 if (status & ICFG_BMAC_CTL_INPAUSE_ST) 71536f45ec7bSml29623 statsp->bmac_stats.tx_pause_state++; 71546f45ec7bSml29623 if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 71556f45ec7bSml29623 statsp->bmac_stats.tx_nopause_state++; 71566f45ec7bSml29623 } 71576f45ec7bSml29623 } 71586f45ec7bSml29623 71596f45ec7bSml29623 if (ldgp->nldvs == 1) { 71606f45ec7bSml29623 (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 71616f45ec7bSml29623 B_TRUE, ldgp->ldg_timer); 71626f45ec7bSml29623 } 71636f45ec7bSml29623 71646f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 71656f45ec7bSml29623 return (DDI_INTR_CLAIMED); 71666f45ec7bSml29623 71676f45ec7bSml29623 npi_fail: 71686f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 71696f45ec7bSml29623 return (DDI_INTR_UNCLAIMED); 71706f45ec7bSml29623 } 71716f45ec7bSml29623 71726f45ec7bSml29623 nxge_status_t 71736f45ec7bSml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 71746f45ec7bSml29623 { 71756f45ec7bSml29623 uint8_t phy_port_addr; 71766f45ec7bSml29623 nxge_status_t status = NXGE_OK; 71776f45ec7bSml29623 boolean_t rx_sig_ok; 71786f45ec7bSml29623 boolean_t pcs_blk_lock; 71796f45ec7bSml29623 boolean_t link_align; 71806f45ec7bSml29623 uint16_t val1, val2, val3; 71816f45ec7bSml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 71826f45ec7bSml29623 uint16_t val_debug; 71834df55fdeSJanie Lu uint32_t val; 71846f45ec7bSml29623 #endif 71856f45ec7bSml29623 71866f45ec7bSml29623 phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 71876f45ec7bSml29623 71886f45ec7bSml29623 #ifdef NXGE_DEBUG_SYMBOL_ERR 71896f45ec7bSml29623 /* Check Device 3 Register Device 3 0xC809 */ 71906f45ec7bSml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 71916f45ec7bSml29623 if ((val_debug & ~0x200) != 0) { 71926f45ec7bSml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 71936f45ec7bSml29623 nxgep->mac.portnum, val_debug); 71946f45ec7bSml29623 (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 71956f45ec7bSml29623 &val_debug); 71966f45ec7bSml29623 cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 71976f45ec7bSml29623 nxgep->mac.portnum, val_debug); 71986f45ec7bSml29623 } 71996f45ec7bSml29623 72006f45ec7bSml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 72016f45ec7bSml29623 XPCS_REG_DESCWERR_COUNTER, &val); 72026f45ec7bSml29623 if (val != 0) 72036f45ec7bSml29623 cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 72046f45ec7bSml29623 72056f45ec7bSml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 72066f45ec7bSml29623 XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 72076f45ec7bSml29623 if (val != 0) 72086f45ec7bSml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 72096f45ec7bSml29623 72106f45ec7bSml29623 (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 72116f45ec7bSml29623 XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 72126f45ec7bSml29623 if (val != 0) 72136f45ec7bSml29623 cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 72146f45ec7bSml29623 #endif 72156f45ec7bSml29623 72166f45ec7bSml29623 /* Check from BCM8704 if 10G link is up or down */ 72176f45ec7bSml29623 72186f45ec7bSml29623 /* Check Device 1 Register 0xA bit0 */ 721952ccf843Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR, 722052ccf843Smisaki BCM8704_PMD_RECEIVE_SIG_DETECT, &val1); 72216f45ec7bSml29623 if (status != NXGE_OK) 72226f45ec7bSml29623 goto fail; 72236f45ec7bSml29623 rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 72246f45ec7bSml29623 72256f45ec7bSml29623 /* Check Device 3 Register 0x20 bit0 */ 722652ccf843Smisaki if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR, 722752ccf843Smisaki BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS) 72286f45ec7bSml29623 goto fail; 72296f45ec7bSml29623 pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 72306f45ec7bSml29623 72316f45ec7bSml29623 /* Check Device 4 Register 0x18 bit12 */ 723252ccf843Smisaki status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 723352ccf843Smisaki BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3); 72346f45ec7bSml29623 if (status != NXGE_OK) 72356f45ec7bSml29623 goto fail; 72362d17280bSsbehera 72372d17280bSsbehera switch (nxgep->chip_id) { 72382d17280bSsbehera case BCM8704_CHIP_ID: 72392d17280bSsbehera link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | 72402d17280bSsbehera XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 72416f45ec7bSml29623 XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 72422d17280bSsbehera break; 72432d17280bSsbehera case BCM8706_CHIP_ID: 72442d17280bSsbehera link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) && 72452d17280bSsbehera (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) && 72462d17280bSsbehera (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ? 72472d17280bSsbehera B_TRUE : B_FALSE; 72482d17280bSsbehera break; 72492d17280bSsbehera default: 72502d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:" 72512d17280bSsbehera "Unknown chip ID [0x%x]", nxgep->chip_id)); 72522d17280bSsbehera goto fail; 72532d17280bSsbehera } 72542d17280bSsbehera 72556f45ec7bSml29623 #ifdef NXGE_DEBUG_ALIGN_ERR 72566f45ec7bSml29623 /* Temp workaround for link down issue */ 72576f45ec7bSml29623 if (pcs_blk_lock == B_FALSE) { 72586f45ec7bSml29623 if (val2 != 0x4) { 72596f45ec7bSml29623 pcs_blk_lock = B_TRUE; 726052ccf843Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 " 726152ccf843Smisaki "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2); 72626f45ec7bSml29623 } 72636f45ec7bSml29623 } 72646f45ec7bSml29623 72656f45ec7bSml29623 if (link_align == B_FALSE) { 72666f45ec7bSml29623 if (val3 != 0x140f) { 72676f45ec7bSml29623 link_align = B_TRUE; 726852ccf843Smisaki cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 " 726952ccf843Smisaki "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3); 72706f45ec7bSml29623 } 72716f45ec7bSml29623 } 72726f45ec7bSml29623 72736f45ec7bSml29623 if (rx_sig_ok == B_FALSE) { 72746f45ec7bSml29623 if ((val2 == 0) || (val3 == 0)) { 72756f45ec7bSml29623 rx_sig_ok = B_TRUE; 72766f45ec7bSml29623 cmn_err(CE_NOTE, 72776f45ec7bSml29623 "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 72786f45ec7bSml29623 nxgep->mac.portnum); 72796f45ec7bSml29623 } 72806f45ec7bSml29623 } 72816f45ec7bSml29623 #endif 72826f45ec7bSml29623 72836f45ec7bSml29623 *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 72846f45ec7bSml29623 (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 72856f45ec7bSml29623 72866f45ec7bSml29623 return (NXGE_OK); 72876f45ec7bSml29623 fail: 72886f45ec7bSml29623 return (status); 72896f45ec7bSml29623 } 72906f45ec7bSml29623 729152cdd236Ssbehera static nxge_status_t 729200161856Syc148097 nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up) 729352cdd236Ssbehera { 729452cdd236Ssbehera uint8_t phy; 729552cdd236Ssbehera nxge_status_t status = NXGE_OK; 729652cdd236Ssbehera boolean_t pma_status; 729752cdd236Ssbehera boolean_t pcs_status; 729852cdd236Ssbehera boolean_t xgxs_status; 729952cdd236Ssbehera uint16_t val; 730052cdd236Ssbehera 730152cdd236Ssbehera phy = nxgep->statsp->mac_stats.xcvr_portn; 730252cdd236Ssbehera 730352cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 730452cdd236Ssbehera MRVL_88X2011_10G_PMD_STAT_2, &val); 730552cdd236Ssbehera 730652cdd236Ssbehera *link_up = B_FALSE; 730752cdd236Ssbehera 730852cdd236Ssbehera /* Check from Marvell 88X2011 if 10G link is up or down */ 730952cdd236Ssbehera 731052cdd236Ssbehera /* Check PMA/PMD Register: 1.0001.2 == 1 */ 731152cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR, 731252cdd236Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 731352cdd236Ssbehera 731452cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 731552cdd236Ssbehera "nxge_check_mrvl88x2011_link: pmd=0x%x", val)); 731652cdd236Ssbehera 731752cdd236Ssbehera pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE); 731852cdd236Ssbehera 731952cdd236Ssbehera /* Check PMC Register : 3.0001.2 == 1: read twice */ 732052cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 732152cdd236Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 732252cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR, 732352cdd236Ssbehera MRVL_88X2011_PMA_PMD_STAT_1, &val); 732452cdd236Ssbehera 732552cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 732652cdd236Ssbehera "nxge_check_mrvl88x2011_link: pcs=0x%x", val)); 732752cdd236Ssbehera 732852cdd236Ssbehera pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE); 732952cdd236Ssbehera 733052cdd236Ssbehera /* Check XGXS Register : 4.0018.[0-3,12] */ 733152cdd236Ssbehera MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR, 733252cdd236Ssbehera MRVL_88X2011_10G_XGXS_LANE_STAT, &val); 733352cdd236Ssbehera 733452cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 733552cdd236Ssbehera "nxge_check_mrvl88x2011_link: xgxs=0x%x", val)); 733652cdd236Ssbehera 733752cdd236Ssbehera xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 733852cdd236Ssbehera XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 733952cdd236Ssbehera XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY | 734052cdd236Ssbehera XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE; 734152cdd236Ssbehera 734252cdd236Ssbehera *link_up = (pma_status && pcs_status && xgxs_status) ? 734352cdd236Ssbehera B_TRUE : B_FALSE; 734452cdd236Ssbehera 734552cdd236Ssbehera fail: 734652cdd236Ssbehera 734752cdd236Ssbehera if (*link_up == B_FALSE) { 734852cdd236Ssbehera /* PCS OFF */ 734952cdd236Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF); 735052cdd236Ssbehera } else { 735152cdd236Ssbehera /* PCS Activity */ 735252cdd236Ssbehera nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT); 735352cdd236Ssbehera } 735452cdd236Ssbehera 735552cdd236Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 735652cdd236Ssbehera " <== nxge_check_mrvl88x2011_link: up=%d", *link_up)); 735752cdd236Ssbehera 735852cdd236Ssbehera return (status); 735952cdd236Ssbehera } 736052cdd236Ssbehera 736189282175SSantwona Behera static nxge_status_t 736289282175SSantwona Behera nxge_check_nlp2020_link(p_nxge_t nxgep, boolean_t *link_up) 736389282175SSantwona Behera { 736489282175SSantwona Behera uint8_t phy; 736589282175SSantwona Behera nxge_status_t status = NXGE_OK; 736689282175SSantwona Behera uint16_t pmd_rx_sig, pcs_10gbr_stat1, phy_xs_ln_stat; 736789282175SSantwona Behera uint8_t connector = 0; 736889282175SSantwona Behera 736989282175SSantwona Behera phy = nxgep->statsp->mac_stats.xcvr_portn; 737089282175SSantwona Behera *link_up = B_FALSE; 737189282175SSantwona Behera 737289282175SSantwona Behera /* Check from Netlogic AEL2020 if 10G link is up or down */ 737389282175SSantwona Behera 737489282175SSantwona Behera status = nxge_mdio_read(nxgep, phy, NLP2020_PMA_PMD_ADDR, 737589282175SSantwona Behera NLP2020_PMA_PMD_RX_SIG_DET_REG, &pmd_rx_sig); 737689282175SSantwona Behera if (status != NXGE_OK) 737789282175SSantwona Behera goto fail; 737889282175SSantwona Behera 737989282175SSantwona Behera status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_PCS_ADDR, 738089282175SSantwona Behera NLP2020_PHY_PCS_10GBR_STAT1_REG, &pcs_10gbr_stat1); 738189282175SSantwona Behera if (status != NXGE_OK) 738289282175SSantwona Behera goto fail; 738389282175SSantwona Behera 738489282175SSantwona Behera status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_XS_ADDR, 738589282175SSantwona Behera NLP2020_PHY_XS_LN_ST_REG, &phy_xs_ln_stat); 738689282175SSantwona Behera if (status != NXGE_OK) 738789282175SSantwona Behera goto fail; 738889282175SSantwona Behera 738989282175SSantwona Behera if ((pmd_rx_sig & NLP2020_PMA_PMD_RX_SIG_ON) && 739089282175SSantwona Behera (pcs_10gbr_stat1 & NLP2020_PHY_PCS_10GBR_RX_LINK_UP) && 739189282175SSantwona Behera (phy_xs_ln_stat & NLP2020_PHY_XS_LN_ALIGN_SYNC)) 739289282175SSantwona Behera *link_up = B_TRUE; 739389282175SSantwona Behera /* 739489282175SSantwona Behera * If previously link was down, check the connector type as 739589282175SSantwona Behera * it might have been changed. 739689282175SSantwona Behera */ 739789282175SSantwona Behera if (nxgep->statsp->mac_stats.link_up == 0) { 739889282175SSantwona Behera (void) nxge_nlp2020_i2c_read(nxgep, phy, 739989282175SSantwona Behera NLP2020_XCVR_I2C_ADDR, QSFP_MSA_CONN_REG, &connector); 740089282175SSantwona Behera 740189282175SSantwona Behera switch (connector) { 740289282175SSantwona Behera case SFPP_FIBER: 740389282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 740489282175SSantwona Behera "nxge_check_nlp2020_link: SFPP_FIBER")); 740589282175SSantwona Behera if (nxgep->mac.portmode != PORT_10G_FIBER) { 740689282175SSantwona Behera nxgep->mac.portmode = PORT_10G_FIBER; 740789282175SSantwona Behera (void) nxge_nlp2020_xcvr_init(nxgep); 740889282175SSantwona Behera } 740989282175SSantwona Behera break; 741089282175SSantwona Behera case QSFP_FIBER: 741189282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 741289282175SSantwona Behera "nxge_check_nlp2020_link: QSFP_FIBER")); 741389282175SSantwona Behera if (nxgep->mac.portmode != PORT_10G_FIBER) { 741489282175SSantwona Behera nxgep->mac.portmode = PORT_10G_FIBER; 741589282175SSantwona Behera (void) nxge_nlp2020_xcvr_init(nxgep); 741689282175SSantwona Behera } 741789282175SSantwona Behera break; 741889282175SSantwona Behera case QSFP_COPPER_TWINAX: 741989282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 742089282175SSantwona Behera "nxge_check_nlp2020_link: " 742189282175SSantwona Behera "QSFP_COPPER_TWINAX/" 742289282175SSantwona Behera "SFPP_COPPER_TWINAX")); 742389282175SSantwona Behera if (nxgep->mac.portmode != PORT_10G_COPPER) { 742489282175SSantwona Behera nxgep->mac.portmode = PORT_10G_COPPER; 742589282175SSantwona Behera (void) nxge_nlp2020_xcvr_init(nxgep); 742689282175SSantwona Behera } else { 742789282175SSantwona Behera uint8_t len = 0; 742889282175SSantwona Behera (void) nxge_nlp2020_i2c_read(nxgep, phy, 742989282175SSantwona Behera NLP2020_XCVR_I2C_ADDR, QSFP_MSA_LEN_REG, 743089282175SSantwona Behera &len); 743189282175SSantwona Behera if (((len < 7) && 743289282175SSantwona Behera (nxgep->nlp_conn == 743389282175SSantwona Behera NXGE_NLP_CONN_COPPER_7M_ABOVE)) || 743489282175SSantwona Behera ((len >= 7) && 743589282175SSantwona Behera (nxgep->nlp_conn == 743689282175SSantwona Behera NXGE_NLP_CONN_COPPER_LT_7M))) { 743789282175SSantwona Behera (void) nxge_nlp2020_xcvr_init(nxgep); 743889282175SSantwona Behera } 743989282175SSantwona Behera } 744089282175SSantwona Behera break; 744189282175SSantwona Behera default: 744289282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 744389282175SSantwona Behera "nxge_check_nlp2020_link: Unknown type [0x%x] " 744489282175SSantwona Behera "detected...setting to QSFP_FIBER", 744589282175SSantwona Behera connector)); 744689282175SSantwona Behera if (nxgep->mac.portmode != PORT_10G_FIBER) { 744789282175SSantwona Behera nxgep->mac.portmode = PORT_10G_FIBER; 744889282175SSantwona Behera (void) nxge_nlp2020_xcvr_init(nxgep); 744989282175SSantwona Behera } 745089282175SSantwona Behera break; 745189282175SSantwona Behera } 745289282175SSantwona Behera } 745389282175SSantwona Behera fail: 745489282175SSantwona Behera if (*link_up == B_FALSE && nxgep->statsp->mac_stats.link_up == 1) { 745589282175SSantwona Behera /* Turn link LED OFF */ 745689282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy, 745789282175SSantwona Behera NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xb000); 745889282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy, 745989282175SSantwona Behera NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0x0); 746089282175SSantwona Behera } else if (*link_up == B_TRUE && 746189282175SSantwona Behera nxgep->statsp->mac_stats.link_up == 0) { 746289282175SSantwona Behera /* Turn link LED ON */ 746389282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy, 746489282175SSantwona Behera NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xd000); 746589282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy, 746689282175SSantwona Behera NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0xfbff); 746789282175SSantwona Behera (void) nxge_mdio_write(nxgep, phy, 746889282175SSantwona Behera NLP2020_GPIO_ADDR, 0xff2a, 0x004a); 746989282175SSantwona Behera } 747089282175SSantwona Behera 747189282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 747289282175SSantwona Behera " <== nxge_check_nlp2020_link: up=%d", *link_up)); 747389282175SSantwona Behera return (status); 747489282175SSantwona Behera } 747589282175SSantwona Behera 747689282175SSantwona Behera 74776f45ec7bSml29623 nxge_status_t 74786f45ec7bSml29623 nxge_10g_link_led_on(p_nxge_t nxgep) 74796f45ec7bSml29623 { 74806f45ec7bSml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 74816f45ec7bSml29623 != NPI_SUCCESS) 74826f45ec7bSml29623 return (NXGE_ERROR); 74836f45ec7bSml29623 else 74846f45ec7bSml29623 return (NXGE_OK); 74856f45ec7bSml29623 } 74866f45ec7bSml29623 74876f45ec7bSml29623 nxge_status_t 74886f45ec7bSml29623 nxge_10g_link_led_off(p_nxge_t nxgep) 74896f45ec7bSml29623 { 74906f45ec7bSml29623 if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 74916f45ec7bSml29623 != NPI_SUCCESS) 74926f45ec7bSml29623 return (NXGE_ERROR); 74936f45ec7bSml29623 else 74946f45ec7bSml29623 return (NXGE_OK); 74956f45ec7bSml29623 } 749656d930aeSspeer 74972d17280bSsbehera static boolean_t 749889282175SSantwona Behera nxge_hswap_phy_present(p_nxge_t nxgep, uint8_t portn) 749989282175SSantwona Behera { 750089282175SSantwona Behera /* 750189282175SSantwona Behera * check for BCM PHY (GOA NEM) 750289282175SSantwona Behera */ 750389282175SSantwona Behera /* 750489282175SSantwona Behera * If this is the 2nd NIU port, then check 2 addresses 750589282175SSantwona Behera * to take care of the Goa NEM card. Port 1 can have addr 17 750689282175SSantwona Behera * (in the eval board) or 20 (in the P0 board). 750789282175SSantwona Behera */ 750889282175SSantwona Behera if (portn == 1) { 750989282175SSantwona Behera if (nxge_is_phy_present(nxgep, ALT_GOA_CLAUSE45_PORT1_ADDR, 751089282175SSantwona Behera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 751189282175SSantwona Behera nxgep->xcvr_addr = ALT_GOA_CLAUSE45_PORT1_ADDR; 751289282175SSantwona Behera goto found_phy; 751389282175SSantwona Behera } 751489282175SSantwona Behera } 751589282175SSantwona Behera if (nxge_is_phy_present(nxgep, GOA_CLAUSE45_PORT_ADDR_BASE + portn, 751689282175SSantwona Behera BCM8706_DEV_ID, BCM_PHY_ID_MASK)) { 751789282175SSantwona Behera nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE + portn; 751889282175SSantwona Behera goto found_phy; 751989282175SSantwona Behera } 752089282175SSantwona Behera 752189282175SSantwona Behera /* 752289282175SSantwona Behera * check for NLP2020 PHY on C4 NEM 752389282175SSantwona Behera */ 752489282175SSantwona Behera switch (portn) { 752589282175SSantwona Behera case 0: 752689282175SSantwona Behera if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR0, 752789282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 752889282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR0; 752989282175SSantwona Behera goto found_phy; 753089282175SSantwona Behera } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR1, 753189282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 753289282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR1; 753389282175SSantwona Behera goto found_phy; 753489282175SSantwona Behera } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR2, 753589282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 753689282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR2; 753789282175SSantwona Behera goto found_phy; 753889282175SSantwona Behera } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR3, 753989282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 754089282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR3; 754189282175SSantwona Behera goto found_phy; 754289282175SSantwona Behera } 754389282175SSantwona Behera break; 754489282175SSantwona Behera 754589282175SSantwona Behera case 1: 754689282175SSantwona Behera if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR0, 754789282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 754889282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR0; 754989282175SSantwona Behera goto found_phy; 755089282175SSantwona Behera } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR1, 755189282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 755289282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR1; 755389282175SSantwona Behera goto found_phy; 755489282175SSantwona Behera } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR2, 755589282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 755689282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR2; 755789282175SSantwona Behera goto found_phy; 755889282175SSantwona Behera } else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR3, 755989282175SSantwona Behera NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) { 756089282175SSantwona Behera nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR3; 756189282175SSantwona Behera goto found_phy; 756289282175SSantwona Behera } 756389282175SSantwona Behera break; 756489282175SSantwona Behera default: 756589282175SSantwona Behera break; 756689282175SSantwona Behera } 756789282175SSantwona Behera 756889282175SSantwona Behera return (B_FALSE); 756989282175SSantwona Behera found_phy: 757089282175SSantwona Behera return (B_TRUE); 757189282175SSantwona Behera 757289282175SSantwona Behera } 757389282175SSantwona Behera 757489282175SSantwona Behera static boolean_t 75752d17280bSsbehera nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask) 75762d17280bSsbehera { 75772d17280bSsbehera uint32_t pma_pmd_id = 0; 75782d17280bSsbehera uint32_t pcs_id = 0; 75792d17280bSsbehera uint32_t phy_id = 0; 75802d17280bSsbehera 75812d17280bSsbehera pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr); 75822d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 75832d17280bSsbehera "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id)); 75842d17280bSsbehera if ((pma_pmd_id & mask) == (id & mask)) 75852d17280bSsbehera goto found_phy; 75862d17280bSsbehera pcs_id = nxge_get_cl45_pcs_id(nxgep, addr); 75872d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 75882d17280bSsbehera "nxge_is_phy_present: pcs_id[0x%x]", pcs_id)); 75892d17280bSsbehera if ((pcs_id & mask) == (id & mask)) 75902d17280bSsbehera goto found_phy; 75912d17280bSsbehera phy_id = nxge_get_cl22_phy_id(nxgep, addr); 75922d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 75932d17280bSsbehera "nxge_is_phy_present: phy_id[0x%x]", phy_id)); 75942d17280bSsbehera if ((phy_id & mask) == (id & mask)) 75952d17280bSsbehera goto found_phy; 75962d17280bSsbehera 75972d17280bSsbehera return (B_FALSE); 75982d17280bSsbehera 75992d17280bSsbehera found_phy: 76002d17280bSsbehera return (B_TRUE); 76012d17280bSsbehera } 76022d17280bSsbehera 760359ac0c16Sdavemq /* Check if the given id read using the given MDIO Clause is supported */ 760459ac0c16Sdavemq 760559ac0c16Sdavemq static boolean_t 760659ac0c16Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type) 760759ac0c16Sdavemq { 760859ac0c16Sdavemq int i; 760959ac0c16Sdavemq boolean_t found = B_FALSE; 761059ac0c16Sdavemq 761159ac0c16Sdavemq switch (type) { 761259ac0c16Sdavemq case CLAUSE_45_TYPE: 761300161856Syc148097 for (i = 0; i < NUM_CLAUSE_45_IDS; i++) { 761400161856Syc148097 if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) == 761500161856Syc148097 (id & BCM_PHY_ID_MASK)) || 761689282175SSantwona Behera (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK)) || 761789282175SSantwona Behera (NLP2020_DEV_ID == (id & NLP2020_DEV_ID_MASK))) { 761859ac0c16Sdavemq found = B_TRUE; 761959ac0c16Sdavemq break; 762059ac0c16Sdavemq } 762159ac0c16Sdavemq } 762259ac0c16Sdavemq break; 762359ac0c16Sdavemq case CLAUSE_22_TYPE: 762400161856Syc148097 for (i = 0; i < NUM_CLAUSE_22_IDS; i++) { 762530505775Ssbehera if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) == 762630505775Ssbehera (id & BCM_PHY_ID_MASK)) { 762759ac0c16Sdavemq found = B_TRUE; 762859ac0c16Sdavemq break; 762959ac0c16Sdavemq } 763059ac0c16Sdavemq } 763159ac0c16Sdavemq break; 763259ac0c16Sdavemq default: 763359ac0c16Sdavemq break; 763459ac0c16Sdavemq } 763559ac0c16Sdavemq 763659ac0c16Sdavemq return (found); 763759ac0c16Sdavemq } 763859ac0c16Sdavemq 76392e59129aSraghus static uint32_t 76402e59129aSraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port) 76412e59129aSraghus { 76422e59129aSraghus uint16_t val1 = 0; 76432e59129aSraghus uint16_t val2 = 0; 76442e59129aSraghus uint32_t pma_pmd_dev_id = 0; 76452e59129aSraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 76462e59129aSraghus 764753560810Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 76482e59129aSraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 76492e59129aSraghus NXGE_DEV_ID_REG_1, &val1); 76502e59129aSraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR, 76512e59129aSraghus NXGE_DEV_ID_REG_2, &val2); 765253560810Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 76532e59129aSraghus 765400161856Syc148097 /* Concatenate the Device ID stored in two registers. */ 76552e59129aSraghus pma_pmd_dev_id = val1; 76562e59129aSraghus pma_pmd_dev_id = (pma_pmd_dev_id << 16); 76572e59129aSraghus pma_pmd_dev_id |= val2; 76582e59129aSraghus 76592e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 76602e59129aSraghus "devid[0x%llx]", phy_port, pma_pmd_dev_id)); 76612e59129aSraghus 76622e59129aSraghus return (pma_pmd_dev_id); 76632e59129aSraghus } 76642e59129aSraghus 76652e59129aSraghus static uint32_t 76662e59129aSraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port) 76672e59129aSraghus { 76682e59129aSraghus uint16_t val1 = 0; 76692e59129aSraghus uint16_t val2 = 0; 76702e59129aSraghus uint32_t pcs_dev_id = 0; 76712e59129aSraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 76722e59129aSraghus 767353560810Ssbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 76742e59129aSraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 76752e59129aSraghus NXGE_DEV_ID_REG_1, &val1); 76762e59129aSraghus (void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR, 76772e59129aSraghus NXGE_DEV_ID_REG_2, &val2); 767853560810Ssbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 76792e59129aSraghus 76802e59129aSraghus pcs_dev_id = val1; 76812e59129aSraghus pcs_dev_id = (pcs_dev_id << 16); 76822e59129aSraghus pcs_dev_id |= val2; 76832e59129aSraghus 76842e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 76852e59129aSraghus "devid[0x%llx]", phy_port, pcs_dev_id)); 76862e59129aSraghus 76872e59129aSraghus return (pcs_dev_id); 76882e59129aSraghus } 76892e59129aSraghus 76902e59129aSraghus static uint32_t 76912e59129aSraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port) 76922e59129aSraghus { 76932e59129aSraghus uint16_t val1 = 0; 76942e59129aSraghus uint16_t val2 = 0; 76952e59129aSraghus uint32_t phy_id = 0; 76962e59129aSraghus npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 76972e59129aSraghus npi_status_t npi_status = NPI_SUCCESS; 76982e59129aSraghus 7699321febdeSsbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 77002e59129aSraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1, 77012e59129aSraghus &val1); 77022e59129aSraghus if (npi_status != NPI_SUCCESS) { 77032e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 77042e59129aSraghus "clause 22 read to reg 2 failed!!!")); 77052e59129aSraghus goto exit; 77062e59129aSraghus } 77072e59129aSraghus npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2, 77082e59129aSraghus &val2); 77092e59129aSraghus if (npi_status != 0) { 77102e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 77112e59129aSraghus "clause 22 read to reg 3 failed!!!")); 77122e59129aSraghus goto exit; 77132e59129aSraghus } 77142e59129aSraghus phy_id = val1; 77152e59129aSraghus phy_id = (phy_id << 16); 77162e59129aSraghus phy_id |= val2; 77172e59129aSraghus 77182e59129aSraghus exit: 7719321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 77202e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]", 77212e59129aSraghus phy_port, phy_id)); 77222e59129aSraghus 77232e59129aSraghus return (phy_id); 77242e59129aSraghus } 77252e59129aSraghus 772659ac0c16Sdavemq /* 772759ac0c16Sdavemq * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 772859ac0c16Sdavemq * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 772959ac0c16Sdavemq * read. Then use the values obtained to determine the phy type of each port 773059ac0c16Sdavemq * and the Neptune type. 773100161856Syc148097 * 773200161856Syc148097 * This function sets hw_p->xcvr_addr[i] for future MDIO access and set 773300161856Syc148097 * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode 773400161856Syc148097 * in case the portmode information is not available via OBP, nxge.conf, 773500161856Syc148097 * VPD or SEEPROM. 773659ac0c16Sdavemq */ 773759ac0c16Sdavemq nxge_status_t 773859ac0c16Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 773959ac0c16Sdavemq { 774059a835ddSjoycey int i, j, l; 774159ac0c16Sdavemq uint32_t pma_pmd_dev_id = 0; 774259ac0c16Sdavemq uint32_t pcs_dev_id = 0; 774359ac0c16Sdavemq uint32_t phy_id = 0; 774430505775Ssbehera uint32_t port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE]; 774530505775Ssbehera uint32_t port_pcs_dev_id[NXGE_PORTS_NEPTUNE]; 774630505775Ssbehera uint32_t port_phy_id[NXGE_PORTS_NEPTUNE]; 774759ac0c16Sdavemq uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 774859ac0c16Sdavemq uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 77492d17280bSsbehera uint8_t phy_fd_arr[NXGE_MAX_PHY_PORTS]; 77502d17280bSsbehera uint8_t port_fd_arr[NXGE_MAX_PHY_PORTS]; 775159ac0c16Sdavemq uint8_t total_port_fd, total_phy_fd; 775200161856Syc148097 uint8_t num_xaui; 775359ac0c16Sdavemq nxge_status_t status = NXGE_OK; 775459ac0c16Sdavemq 775559ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 775659ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 775759ac0c16Sdavemq "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 775859ac0c16Sdavemq nxgep->niu_type)); 775959ac0c16Sdavemq 7760678453a8Sspeer if (isLDOMguest(nxgep)) { 7761678453a8Sspeer hw_p->niu_type = NIU_TYPE_NONE; 7762678453a8Sspeer hw_p->platform_type = P_NEPTUNE_NONE; 7763678453a8Sspeer return (NXGE_OK); 7764678453a8Sspeer } 7765678453a8Sspeer 776659a835ddSjoycey j = l = 0; 776759ac0c16Sdavemq total_port_fd = total_phy_fd = 0; 776859ac0c16Sdavemq /* 776923b952a3SSantwona Behera * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved 777023b952a3SSantwona Behera * for on chip serdes usages. "i" in the following for loop starts at 6. 777159ac0c16Sdavemq */ 777259ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 77732e59129aSraghus 77742e59129aSraghus pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i); 777559ac0c16Sdavemq 777659ac0c16Sdavemq if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 777759ac0c16Sdavemq pma_pmd_dev_fd[i] = 1; 777859ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 777952cdd236Ssbehera "PMA/PMD dev %x found", i, pma_pmd_dev_id)); 778030505775Ssbehera if (j < NXGE_PORTS_NEPTUNE) { 778100161856Syc148097 if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK) 778200161856Syc148097 == TN1010_DEV_ID) { 778300161856Syc148097 port_pma_pmd_dev_id[j] = TN1010_DEV_ID; 778489282175SSantwona Behera } else if ((pma_pmd_dev_id & 778589282175SSantwona Behera NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) { 778689282175SSantwona Behera port_pma_pmd_dev_id[j] = 778789282175SSantwona Behera NLP2020_DEV_ID; 778800161856Syc148097 } else { 778900161856Syc148097 port_pma_pmd_dev_id[j] = 779000161856Syc148097 pma_pmd_dev_id & BCM_PHY_ID_MASK; 779100161856Syc148097 } 77922d17280bSsbehera port_fd_arr[j] = (uint8_t)i; 779359ac0c16Sdavemq j++; 779459ac0c16Sdavemq } 779559ac0c16Sdavemq } else { 779659ac0c16Sdavemq pma_pmd_dev_fd[i] = 0; 779759ac0c16Sdavemq } 779859ac0c16Sdavemq 77992e59129aSraghus pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i); 780059ac0c16Sdavemq 780159ac0c16Sdavemq if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 780259ac0c16Sdavemq pcs_dev_fd[i] = 1; 780359ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 780452cdd236Ssbehera "dev %x found", i, pcs_dev_id)); 780559a835ddSjoycey if (pma_pmd_dev_fd[i] == 1) { 780600161856Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK) 780700161856Syc148097 == TN1010_DEV_ID) { 780800161856Syc148097 port_pcs_dev_id[j - 1] = 780900161856Syc148097 TN1010_DEV_ID; 781089282175SSantwona Behera } else if ((pcs_dev_id & NLP2020_DEV_ID_MASK) 781189282175SSantwona Behera == NLP2020_DEV_ID) { 781289282175SSantwona Behera port_pcs_dev_id[j - 1] = 781389282175SSantwona Behera NLP2020_DEV_ID; 781400161856Syc148097 } else { 781500161856Syc148097 port_pcs_dev_id[j - 1] = 781600161856Syc148097 pcs_dev_id & 781730505775Ssbehera BCM_PHY_ID_MASK; 781800161856Syc148097 } 781959a835ddSjoycey } else { 782059a835ddSjoycey if (j < NXGE_PORTS_NEPTUNE) { 782100161856Syc148097 if ((pcs_dev_id & TN1010_DEV_ID_MASK) 782200161856Syc148097 == TN1010_DEV_ID) { 782300161856Syc148097 port_pcs_dev_id[j] = 782400161856Syc148097 TN1010_DEV_ID; 782589282175SSantwona Behera } else if ((pcs_dev_id & 782689282175SSantwona Behera NLP2020_DEV_ID_MASK) 782789282175SSantwona Behera == NLP2020_DEV_ID) { 782889282175SSantwona Behera port_pcs_dev_id[j] = 782989282175SSantwona Behera NLP2020_DEV_ID; 783000161856Syc148097 } else { 783100161856Syc148097 port_pcs_dev_id[j] = 783200161856Syc148097 pcs_dev_id & 783359a835ddSjoycey BCM_PHY_ID_MASK; 783400161856Syc148097 } 783559a835ddSjoycey port_fd_arr[j] = (uint8_t)i; 783659a835ddSjoycey j++; 783759a835ddSjoycey } 783859ac0c16Sdavemq } 783959ac0c16Sdavemq } else { 784059ac0c16Sdavemq pcs_dev_fd[i] = 0; 784159ac0c16Sdavemq } 784259ac0c16Sdavemq 78432d17280bSsbehera if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) { 78442d17280bSsbehera total_port_fd ++; 78452d17280bSsbehera } 784659ac0c16Sdavemq 78472e59129aSraghus phy_id = nxge_get_cl22_phy_id(nxgep, i); 784859ac0c16Sdavemq if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 78492d17280bSsbehera total_phy_fd ++; 785059ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 785152cdd236Ssbehera "%x found", i, phy_id)); 785230505775Ssbehera if (l < NXGE_PORTS_NEPTUNE) { 785300161856Syc148097 if ((phy_id & TN1010_DEV_ID_MASK) 785400161856Syc148097 == TN1010_DEV_ID) { 785500161856Syc148097 port_phy_id[l] = TN1010_DEV_ID; 785600161856Syc148097 } else { 785700161856Syc148097 port_phy_id[l] 785800161856Syc148097 = phy_id & BCM_PHY_ID_MASK; 785900161856Syc148097 } 78602d17280bSsbehera phy_fd_arr[l] = (uint8_t)i; 786159ac0c16Sdavemq l++; 786259ac0c16Sdavemq } 786359ac0c16Sdavemq } 786459ac0c16Sdavemq } 786559ac0c16Sdavemq 786659ac0c16Sdavemq switch (total_port_fd) { 786759ac0c16Sdavemq case 2: 786859ac0c16Sdavemq switch (total_phy_fd) { 786959ac0c16Sdavemq case 2: 787023b952a3SSantwona Behera /* 2 10G, 2 1G RGMII Fiber / copper */ 787159a835ddSjoycey if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 787259a835ddSjoycey (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 787359a835ddSjoycey ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 787459a835ddSjoycey (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) && 787559a835ddSjoycey ((port_phy_id[0] == PHY_BCM5482_FAMILY) && 787659a835ddSjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY))) { 787759a835ddSjoycey 787823b952a3SSantwona Behera switch (hw_p->platform_type) { 787923b952a3SSantwona Behera case P_NEPTUNE_ROCK: 788023b952a3SSantwona Behera hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 788123b952a3SSantwona Behera /* 788223b952a3SSantwona Behera * ROCK platform has assigned a lower 788323b952a3SSantwona Behera * addr to port 1. (port 0 = 0x9 and 788423b952a3SSantwona Behera * port 1 = 0x8). 788523b952a3SSantwona Behera */ 788623b952a3SSantwona Behera hw_p->xcvr_addr[1] = port_fd_arr[0]; 788723b952a3SSantwona Behera hw_p->xcvr_addr[0] = port_fd_arr[1]; 788859a835ddSjoycey 788923b952a3SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 789023b952a3SSantwona Behera "Rock with 2 10G, 2 1GC")); 789123b952a3SSantwona Behera break; 789223b952a3SSantwona Behera 789323b952a3SSantwona Behera case P_NEPTUNE_NONE: 789423b952a3SSantwona Behera default: 789523b952a3SSantwona Behera hw_p->platform_type = 789623b952a3SSantwona Behera P_NEPTUNE_GENERIC; 789759a835ddSjoycey hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF; 789859a835ddSjoycey 789959a835ddSjoycey hw_p->xcvr_addr[0] = port_fd_arr[0]; 790059a835ddSjoycey hw_p->xcvr_addr[1] = port_fd_arr[1]; 790123b952a3SSantwona Behera 790223b952a3SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 790323b952a3SSantwona Behera "ARTM card with 2 10G, 2 1GF")); 790423b952a3SSantwona Behera break; 790523b952a3SSantwona Behera } 790623b952a3SSantwona Behera 790759a835ddSjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0]; 790859a835ddSjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1]; 790959a835ddSjoycey 791059a835ddSjoycey } else { 791159a835ddSjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 791259ac0c16Sdavemq "Unsupported neptune type 1")); 791359ac0c16Sdavemq goto error_exit; 791459a835ddSjoycey } 791559a835ddSjoycey break; 791659a835ddSjoycey 791759ac0c16Sdavemq case 1: 791859ac0c16Sdavemq /* TODO - 2 10G, 1 1G */ 791959ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 792059ac0c16Sdavemq "Unsupported neptune type 2 10G, 1 1G")); 792159ac0c16Sdavemq goto error_exit; 792259ac0c16Sdavemq case 0: 792300161856Syc148097 /* 792400161856Syc148097 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI 792500161856Syc148097 * cards, etc. 792600161856Syc148097 */ 792730505775Ssbehera if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) && 792830505775Ssbehera (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) || 792930505775Ssbehera ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) && 793052cdd236Ssbehera (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) || 793152cdd236Ssbehera ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) && 793252cdd236Ssbehera (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) || 793352cdd236Ssbehera ((port_pma_pmd_dev_id[0] == 793452cdd236Ssbehera MARVELL_88X201X_PHY_ID) && 793552cdd236Ssbehera (port_pma_pmd_dev_id[1] == 793652cdd236Ssbehera MARVELL_88X201X_PHY_ID))) { 79372e59129aSraghus 79382e59129aSraghus /* 79392e59129aSraghus * Check the first phy port address against 79402e59129aSraghus * the known phy start addresses to determine 79412e59129aSraghus * the platform type. 79422e59129aSraghus */ 79432d17280bSsbehera 79442d17280bSsbehera switch (port_fd_arr[0]) { 794500161856Syc148097 case NEPTUNE_CLAUSE45_PORT_ADDR_BASE: 794652cdd236Ssbehera /* 794752cdd236Ssbehera * The Marvell case also falls into 794852cdd236Ssbehera * this case as 794952cdd236Ssbehera * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE 795000161856Syc148097 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE. 795152cdd236Ssbehera * This is OK for the 2 10G case. 795252cdd236Ssbehera */ 79532e59129aSraghus hw_p->niu_type = NEPTUNE_2_10GF; 79542e59129aSraghus hw_p->platform_type = 79552e59129aSraghus P_NEPTUNE_ATLAS_2PORT; 79562d17280bSsbehera break; 795700161856Syc148097 case GOA_CLAUSE45_PORT_ADDR_BASE: 79582d17280bSsbehera if (hw_p->platform_type != 79592d17280bSsbehera P_NEPTUNE_NIU) { 79602d17280bSsbehera hw_p->platform_type = 79612d17280bSsbehera P_NEPTUNE_GENERIC; 79622d17280bSsbehera hw_p->niu_type = 79632d17280bSsbehera NEPTUNE_2_10GF; 79642d17280bSsbehera } 79652d17280bSsbehera break; 79662d17280bSsbehera default: 79672d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 79682e59129aSraghus "Unsupported neptune type 2 - 1")); 79692e59129aSraghus goto error_exit; 79702e59129aSraghus } 79712d17280bSsbehera 79722d17280bSsbehera for (i = 0; i < 2; i++) { 79732d17280bSsbehera hw_p->xcvr_addr[i] = port_fd_arr[i]; 79742d17280bSsbehera } 797500161856Syc148097 797689282175SSantwona Behera /* 2 10G optical Netlogic AEL2020 ports */ 797789282175SSantwona Behera } else if (((port_pcs_dev_id[0] == NLP2020_DEV_ID) && 797889282175SSantwona Behera (port_pcs_dev_id[1] == NLP2020_DEV_ID)) || 797989282175SSantwona Behera ((port_pma_pmd_dev_id[0] == NLP2020_DEV_ID) && 798089282175SSantwona Behera (port_pma_pmd_dev_id[1] == NLP2020_DEV_ID))) { 798189282175SSantwona Behera if (hw_p->platform_type != P_NEPTUNE_NIU) { 798289282175SSantwona Behera hw_p->platform_type = 798389282175SSantwona Behera P_NEPTUNE_GENERIC; 798489282175SSantwona Behera hw_p->niu_type = 798589282175SSantwona Behera NEPTUNE_2_10GF; 798689282175SSantwona Behera } 798789282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 798889282175SSantwona Behera "Found 2 NL PHYs at addrs 0x%x and 0x%x", 798989282175SSantwona Behera port_fd_arr[0], port_fd_arr[1])); 799089282175SSantwona Behera hw_p->xcvr_addr[0] = port_fd_arr[0]; 799189282175SSantwona Behera hw_p->xcvr_addr[1] = port_fd_arr[1]; 799289282175SSantwona Behera 799300161856Syc148097 /* Both XAUI slots have copper XAUI cards */ 799400161856Syc148097 } else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 799500161856Syc148097 == TN1010_DEV_ID) && 799600161856Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 799700161856Syc148097 == TN1010_DEV_ID)) || 799800161856Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 799900161856Syc148097 == TN1010_DEV_ID) && 800000161856Syc148097 ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) 800100161856Syc148097 == TN1010_DEV_ID))) { 800200161856Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010; 800300161856Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 800400161856Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 800500161856Syc148097 800600161856Syc148097 /* Slot0 has fiber XAUI, slot1 has copper XAUI */ 800700161856Syc148097 } else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 800800161856Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 800900161856Syc148097 == TN1010_DEV_ID) || 801000161856Syc148097 (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY && 801100161856Syc148097 (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) == 801200161856Syc148097 TN1010_DEV_ID)) { 801300161856Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010; 801400161856Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 801500161856Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 801600161856Syc148097 801700161856Syc148097 /* Slot0 has copper XAUI, slot1 has fiber XAUI */ 801800161856Syc148097 } else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY && 801900161856Syc148097 (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 802000161856Syc148097 == TN1010_DEV_ID) || 802100161856Syc148097 (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY && 802200161856Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 802300161856Syc148097 == TN1010_DEV_ID)) { 802400161856Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF; 802500161856Syc148097 hw_p->xcvr_addr[0] = port_fd_arr[0]; 802600161856Syc148097 hw_p->xcvr_addr[1] = port_fd_arr[1]; 802700161856Syc148097 802859ac0c16Sdavemq } else { 802959ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 803059ac0c16Sdavemq "Unsupported neptune type 2")); 803159ac0c16Sdavemq goto error_exit; 803259ac0c16Sdavemq } 803359ac0c16Sdavemq break; 803400161856Syc148097 803559ac0c16Sdavemq case 4: 803600161856Syc148097 if (nxge_get_num_of_xaui( 803700161856Syc148097 port_pma_pmd_dev_id, port_pcs_dev_id, 803800161856Syc148097 port_phy_id, &num_xaui) == NXGE_ERROR) { 803900161856Syc148097 goto error_exit; 804000161856Syc148097 } 804100161856Syc148097 if (num_xaui != 2) 804200161856Syc148097 goto error_exit; 804359ac0c16Sdavemq 804459ac0c16Sdavemq /* 804500161856Syc148097 * Maramba with 2 XAUIs (either fiber or copper) 804600161856Syc148097 * 804759ac0c16Sdavemq * Check the first phy port address against 804859ac0c16Sdavemq * the known phy start addresses to determine 804959ac0c16Sdavemq * the platform type. 805059ac0c16Sdavemq */ 80512d17280bSsbehera switch (phy_fd_arr[0]) { 805200161856Syc148097 case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE: 805359ac0c16Sdavemq hw_p->platform_type = 805459ac0c16Sdavemq P_NEPTUNE_MARAMBA_P0; 80552d17280bSsbehera break; 805600161856Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 805759ac0c16Sdavemq hw_p->platform_type = 805859ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1; 80592d17280bSsbehera break; 80602d17280bSsbehera default: 806159ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 806259ac0c16Sdavemq "Unknown port %d...Cannot " 806359ac0c16Sdavemq "determine platform type", i)); 80642e59129aSraghus goto error_exit; 806559ac0c16Sdavemq } 80662d17280bSsbehera 80672d17280bSsbehera hw_p->xcvr_addr[0] = port_fd_arr[0]; 80682d17280bSsbehera hw_p->xcvr_addr[1] = port_fd_arr[1]; 80692d17280bSsbehera hw_p->xcvr_addr[2] = phy_fd_arr[2]; 80702d17280bSsbehera hw_p->xcvr_addr[3] = phy_fd_arr[3]; 80712d17280bSsbehera 807200161856Syc148097 /* slot0 has fiber XAUI, slot1 has Cu XAUI */ 807300161856Syc148097 if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 807400161856Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 807500161856Syc148097 == TN1010_DEV_ID) { 807600161856Syc148097 hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC; 807700161856Syc148097 807800161856Syc148097 /* slot0 has Cu XAUI, slot1 has fiber XAUI */ 807900161856Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 808000161856Syc148097 == TN1010_DEV_ID) && 808100161856Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) { 808200161856Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC; 808300161856Syc148097 808400161856Syc148097 /* Both slots have fiber XAUI */ 808500161856Syc148097 } else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY && 808600161856Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) { 808700161856Syc148097 hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 808800161856Syc148097 808900161856Syc148097 /* Both slots have copper XAUI */ 809000161856Syc148097 } else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 809100161856Syc148097 == TN1010_DEV_ID) && 809200161856Syc148097 (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 809300161856Syc148097 == TN1010_DEV_ID) { 809400161856Syc148097 hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC; 809500161856Syc148097 809659ac0c16Sdavemq } else { 809759ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 809859ac0c16Sdavemq "Unsupported neptune type 3")); 809959ac0c16Sdavemq goto error_exit; 810059ac0c16Sdavemq } 810159ac0c16Sdavemq break; 810259ac0c16Sdavemq default: 810359ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 810459ac0c16Sdavemq "Unsupported neptune type 5")); 810559ac0c16Sdavemq goto error_exit; 810659ac0c16Sdavemq } 810730505775Ssbehera break; 810800161856Syc148097 case 1: /* Only one clause45 port */ 810900161856Syc148097 switch (total_phy_fd) { /* Number of clause22 ports */ 811059ac0c16Sdavemq case 3: 81112e59129aSraghus /* 81122e59129aSraghus * TODO 3 1G, 1 10G mode. 81132e59129aSraghus * Differentiate between 1_1G_1_10G_2_1G and 81142e59129aSraghus * 1_10G_3_1G 81152e59129aSraghus */ 811659ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 811759ac0c16Sdavemq "Unsupported neptune type 7")); 811859ac0c16Sdavemq goto error_exit; 811959ac0c16Sdavemq case 2: 812059ac0c16Sdavemq /* 812159ac0c16Sdavemq * TODO 2 1G, 1 10G mode. 812259ac0c16Sdavemq * Differentiate between 1_1G_1_10G_1_1G and 812359ac0c16Sdavemq * 1_10G_2_1G 812459ac0c16Sdavemq */ 812559ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 812659ac0c16Sdavemq "Unsupported neptune type 8")); 812759ac0c16Sdavemq goto error_exit; 812859ac0c16Sdavemq case 1: 812959ac0c16Sdavemq /* 813059ac0c16Sdavemq * TODO 1 1G, 1 10G mode. 813159ac0c16Sdavemq * Differentiate between 1_1G_1_10G and 813259ac0c16Sdavemq * 1_10G_1_1G 813359ac0c16Sdavemq */ 813459ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 813559ac0c16Sdavemq "Unsupported neptune type 9")); 813659ac0c16Sdavemq goto error_exit; 813700161856Syc148097 case 0: /* N2 with 1 XAUI (fiber or copper) */ 813800161856Syc148097 /* Fiber XAUI */ 81392d17280bSsbehera if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY || 81402d17280bSsbehera port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) { 81412d17280bSsbehera 81422d17280bSsbehera /* 81432d17280bSsbehera * Check the first phy port address against 81442d17280bSsbehera * the known phy start addresses to determine 81452d17280bSsbehera * the platform type. 81462d17280bSsbehera */ 81472d17280bSsbehera 81482d17280bSsbehera switch (port_fd_arr[0]) { 814900161856Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE: 815000161856Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1): 815100161856Syc148097 case ALT_GOA_CLAUSE45_PORT1_ADDR: 815200161856Syc148097 /* 815300161856Syc148097 * If hw_p->platform_type == 815400161856Syc148097 * P_NEPTUNE_NIU, then portmode 815500161856Syc148097 * is already known, so there is 815600161856Syc148097 * no need to figure out hw_p-> 815700161856Syc148097 * platform_type because 815800161856Syc148097 * platform_type is only for 815900161856Syc148097 * figuring out portmode. 816000161856Syc148097 */ 81612d17280bSsbehera if (hw_p->platform_type != 81622d17280bSsbehera P_NEPTUNE_NIU) { 81632d17280bSsbehera hw_p->platform_type = 81642d17280bSsbehera P_NEPTUNE_GENERIC; 81652d17280bSsbehera hw_p->niu_type = 81662d17280bSsbehera NEPTUNE_2_10GF; 81672d17280bSsbehera } 81682d17280bSsbehera break; 81692d17280bSsbehera default: 81702d17280bSsbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 817159ac0c16Sdavemq "Unsupported neptune type 10")); 817259ac0c16Sdavemq goto error_exit; 81732d17280bSsbehera } 8174321febdeSsbehera /* 8175321febdeSsbehera * For GOA, which is a hot swappable PHY, the 8176321febdeSsbehera * phy address to function number mapping 8177321febdeSsbehera * should be preserved, i.e., addr 16 is 8178321febdeSsbehera * assigned to function 0 and 20 to function 1 8179321febdeSsbehera * But for Huron XAUI, the assignment should 8180321febdeSsbehera * be by function number, i.e., whichever 8181321febdeSsbehera * function number attaches should be 8182321febdeSsbehera * assigned the available PHY (this is required 8183321febdeSsbehera * primarily to support pre-production Huron 8184321febdeSsbehera * boards where function 0 is mapped to addr 17 8185321febdeSsbehera */ 8186321febdeSsbehera if (port_fd_arr[0] == 818700161856Syc148097 ALT_GOA_CLAUSE45_PORT1_ADDR) { 8188321febdeSsbehera hw_p->xcvr_addr[1] = port_fd_arr[0]; 8189321febdeSsbehera } else { 81904202ea4bSsbehera hw_p->xcvr_addr[nxgep->function_num] = 81914202ea4bSsbehera port_fd_arr[0]; 8192321febdeSsbehera } 819389282175SSantwona Behera } else if (port_pcs_dev_id[0] == NLP2020_DEV_ID || 819489282175SSantwona Behera port_pma_pmd_dev_id[0] == NLP2020_DEV_ID) { 819589282175SSantwona Behera /* A 10G NLP2020 PHY in slot0 or slot1 */ 819689282175SSantwona Behera switch (port_fd_arr[0]) { 819789282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR0: 819889282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR1: 819989282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR2: 820089282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR3: 820189282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR0: 820289282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR1: 820389282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR2: 820489282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR3: 820589282175SSantwona Behera /* 820689282175SSantwona Behera * If hw_p->platform_type == 820789282175SSantwona Behera * P_NEPTUNE_NIU, then portmode 820889282175SSantwona Behera * is already known, so there is 820989282175SSantwona Behera * no need to figure out hw_p-> 821089282175SSantwona Behera * platform_type because 821189282175SSantwona Behera * platform_type is only for 821289282175SSantwona Behera * figuring out portmode. 821389282175SSantwona Behera */ 821489282175SSantwona Behera if (hw_p->platform_type != 821589282175SSantwona Behera P_NEPTUNE_NIU) { 821689282175SSantwona Behera hw_p->platform_type = 821789282175SSantwona Behera P_NEPTUNE_GENERIC; 821889282175SSantwona Behera hw_p->niu_type = 821989282175SSantwona Behera NEPTUNE_2_10GF; 822089282175SSantwona Behera } 822189282175SSantwona Behera break; 822289282175SSantwona Behera default: 822389282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 822489282175SSantwona Behera "Unsupported neptune type 10-1")); 822589282175SSantwona Behera goto error_exit; 822689282175SSantwona Behera } 822789282175SSantwona Behera switch (port_fd_arr[0]) { 822889282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR0: 822989282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR1: 823089282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR2: 823189282175SSantwona Behera case NLP2020_CL45_PORT0_ADDR3: 823289282175SSantwona Behera hw_p->xcvr_addr[0] = port_fd_arr[0]; 823389282175SSantwona Behera break; 823489282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR0: 823589282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR1: 823689282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR2: 823789282175SSantwona Behera case NLP2020_CL45_PORT1_ADDR3: 823889282175SSantwona Behera hw_p->xcvr_addr[1] = port_fd_arr[0]; 823989282175SSantwona Behera break; 824089282175SSantwona Behera default: 824189282175SSantwona Behera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 824289282175SSantwona Behera "Unsupported neptune type 10-11")); 824389282175SSantwona Behera goto error_exit; 824489282175SSantwona Behera } 824589282175SSantwona Behera 824689282175SSantwona Behera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 824789282175SSantwona Behera "Found 1 NL PHYs at addr 0x%x", 824889282175SSantwona Behera port_fd_arr[0])); 824900161856Syc148097 825000161856Syc148097 /* A 10G copper XAUI in either slot0 or slot1 */ 825100161856Syc148097 } else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 825200161856Syc148097 == TN1010_DEV_ID || 825300161856Syc148097 (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 825400161856Syc148097 == TN1010_DEV_ID) { 825500161856Syc148097 switch (port_fd_arr[0]) { 825600161856Syc148097 /* The XAUI is in slot0 */ 825700161856Syc148097 case N2_CLAUSE45_PORT_ADDR_BASE: 825800161856Syc148097 hw_p->niu_type = NEPTUNE_1_TN1010; 825900161856Syc148097 break; 826000161856Syc148097 826100161856Syc148097 /* The XAUI is in slot1 */ 826200161856Syc148097 case (N2_CLAUSE45_PORT_ADDR_BASE + 1): 826300161856Syc148097 hw_p->niu_type 826400161856Syc148097 = NEPTUNE_1_NONE_1_TN1010; 826500161856Syc148097 break; 826600161856Syc148097 default: 826700161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 826800161856Syc148097 "Unsupported XAUI port address")); 826900161856Syc148097 goto error_exit; 827000161856Syc148097 } 827100161856Syc148097 hw_p->xcvr_addr[nxgep->function_num] 827200161856Syc148097 = port_fd_arr[0]; 827300161856Syc148097 82742d17280bSsbehera } else { 82752d17280bSsbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 827600161856Syc148097 "Unsupported PHY type")); 82772d17280bSsbehera goto error_exit; 82782d17280bSsbehera } 82792d17280bSsbehera break; 828000161856Syc148097 case 4: /* Maramba always have 4 clause 45 ports */ 828159ac0c16Sdavemq 828200161856Syc148097 /* Maramba with 1 XAUI */ 828352ccf843Smisaki if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) && 828452ccf843Smisaki (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) && 828500161856Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 828652ccf843Smisaki != TN1010_DEV_ID) && 828700161856Syc148097 ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 828852ccf843Smisaki != TN1010_DEV_ID)) { 828952ccf843Smisaki NXGE_DEBUG_MSG((nxgep, MAC_CTL, 829052ccf843Smisaki "Unsupported neptune type 12")); 829152ccf843Smisaki goto error_exit; 829252ccf843Smisaki } 829352ccf843Smisaki 829459ac0c16Sdavemq /* 829559ac0c16Sdavemq * Check the first phy port address against 829659ac0c16Sdavemq * the known phy start addresses to determine 829759ac0c16Sdavemq * the platform type. 829859ac0c16Sdavemq */ 82992d17280bSsbehera switch (phy_fd_arr[0]) { 830000161856Syc148097 case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE: 830159ac0c16Sdavemq hw_p->platform_type = 830259ac0c16Sdavemq P_NEPTUNE_MARAMBA_P0; 83032d17280bSsbehera break; 830400161856Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 830559ac0c16Sdavemq hw_p->platform_type = 830659ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1; 83072d17280bSsbehera break; 83082d17280bSsbehera default: 830959ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 831059ac0c16Sdavemq "Unknown port %d...Cannot " 83112d17280bSsbehera "determine platform type 10 - 2", 83122d17280bSsbehera i)); 83132e59129aSraghus goto error_exit; 83142e59129aSraghus } 83152e59129aSraghus 83162d17280bSsbehera /* 831700161856Syc148097 * Check the clause45 address to determine 83182d17280bSsbehera * if XAUI is in port 0 or port 1. 83192d17280bSsbehera */ 83202d17280bSsbehera switch (port_fd_arr[0]) { 832100161856Syc148097 case MARAMBA_CLAUSE45_PORT_ADDR_BASE: 832200161856Syc148097 if (port_pcs_dev_id[0] 832300161856Syc148097 == PHY_BCM8704_FAMILY || 832400161856Syc148097 port_pma_pmd_dev_id[0] 832500161856Syc148097 == PHY_BCM8704_FAMILY) { 832600161856Syc148097 hw_p->niu_type 832700161856Syc148097 = NEPTUNE_1_10GF_3_1GC; 832800161856Syc148097 } else { 832900161856Syc148097 hw_p->niu_type 833000161856Syc148097 = NEPTUNE_1_TN1010_3_1GC; 833100161856Syc148097 } 83322d17280bSsbehera hw_p->xcvr_addr[0] = port_fd_arr[0]; 83332d17280bSsbehera for (i = 1; i < NXGE_MAX_PORTS; i++) { 83342d17280bSsbehera hw_p->xcvr_addr[i] = 83352d17280bSsbehera phy_fd_arr[i]; 83362d17280bSsbehera } 83372d17280bSsbehera break; 833800161856Syc148097 case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1): 833900161856Syc148097 if (port_pcs_dev_id[0] 834000161856Syc148097 == PHY_BCM8704_FAMILY || 834100161856Syc148097 port_pma_pmd_dev_id[0] 834200161856Syc148097 == PHY_BCM8704_FAMILY) { 83432e59129aSraghus hw_p->niu_type = 83442e59129aSraghus NEPTUNE_1_1GC_1_10GF_2_1GC; 834500161856Syc148097 } else { 834600161856Syc148097 hw_p->niu_type = 834700161856Syc148097 NEPTUNE_1_1GC_1_TN1010_2_1GC; 834800161856Syc148097 } 83492d17280bSsbehera hw_p->xcvr_addr[0] = phy_fd_arr[0]; 83502d17280bSsbehera hw_p->xcvr_addr[1] = port_fd_arr[0]; 83512d17280bSsbehera hw_p->xcvr_addr[2] = phy_fd_arr[2]; 83522d17280bSsbehera hw_p->xcvr_addr[3] = phy_fd_arr[3]; 83532d17280bSsbehera break; 83542d17280bSsbehera default: 83552e59129aSraghus NXGE_DEBUG_MSG((nxgep, MAC_CTL, 83562e59129aSraghus "Unsupported neptune type 11")); 83572e59129aSraghus goto error_exit; 835859ac0c16Sdavemq } 835959ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 836000161856Syc148097 "Maramba with 1 XAUI (fiber or copper)")); 836159ac0c16Sdavemq break; 836259ac0c16Sdavemq default: 836359ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 836459ac0c16Sdavemq "Unsupported neptune type 13")); 836559ac0c16Sdavemq goto error_exit; 836659ac0c16Sdavemq } 836759ac0c16Sdavemq break; 836800161856Syc148097 case 0: /* 4 ports Neptune based NIC */ 836959ac0c16Sdavemq switch (total_phy_fd) { 837059ac0c16Sdavemq case 4: 837130505775Ssbehera if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) && 837230505775Ssbehera (port_phy_id[1] == PHY_BCM5464R_FAMILY) && 837330505775Ssbehera (port_phy_id[2] == PHY_BCM5464R_FAMILY) && 837430505775Ssbehera (port_phy_id[3] == PHY_BCM5464R_FAMILY)) { 837559ac0c16Sdavemq 837659ac0c16Sdavemq /* 837759ac0c16Sdavemq * Check the first phy port address against 837859ac0c16Sdavemq * the known phy start addresses to determine 837959ac0c16Sdavemq * the platform type. 838059ac0c16Sdavemq */ 83812d17280bSsbehera switch (phy_fd_arr[0]) { 838200161856Syc148097 case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE: 838359ac0c16Sdavemq hw_p->platform_type = 838459ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1; 83852d17280bSsbehera break; 838600161856Syc148097 case NEPTUNE_CLAUSE22_PORT_ADDR_BASE: 83872e59129aSraghus hw_p->platform_type = 83882e59129aSraghus P_NEPTUNE_ATLAS_4PORT; 83892d17280bSsbehera break; 83902d17280bSsbehera default: 83912e59129aSraghus NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 83922e59129aSraghus "Unknown port %d...Cannot " 83932e59129aSraghus "determine platform type", i)); 83942e59129aSraghus goto error_exit; 839559ac0c16Sdavemq } 83962e59129aSraghus hw_p->niu_type = NEPTUNE_4_1GC; 83972d17280bSsbehera for (i = 0; i < NXGE_MAX_PORTS; i++) { 83982d17280bSsbehera hw_p->xcvr_addr[i] = phy_fd_arr[i]; 83992d17280bSsbehera } 840059ac0c16Sdavemq } else { 840159ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 840259ac0c16Sdavemq "Unsupported neptune type 14")); 840359ac0c16Sdavemq goto error_exit; 840459ac0c16Sdavemq } 840559ac0c16Sdavemq break; 840659ac0c16Sdavemq case 3: 840759ac0c16Sdavemq /* TODO 3 1G mode */ 840859ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 840959ac0c16Sdavemq "Unsupported neptune type 15")); 841059ac0c16Sdavemq goto error_exit; 841159ac0c16Sdavemq case 2: 841259ac0c16Sdavemq /* TODO 2 1G mode */ 841359a835ddSjoycey if ((port_phy_id[0] == PHY_BCM5482_FAMILY) && 841459a835ddSjoycey (port_phy_id[1] == PHY_BCM5482_FAMILY)) { 841559a835ddSjoycey hw_p->platform_type = P_NEPTUNE_GENERIC; 841659a835ddSjoycey hw_p->niu_type = NEPTUNE_2_1GRF; 841759a835ddSjoycey hw_p->xcvr_addr[2] = phy_fd_arr[0]; 841859a835ddSjoycey hw_p->xcvr_addr[3] = phy_fd_arr[1]; 841959a835ddSjoycey } else { 842059a835ddSjoycey NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 842159ac0c16Sdavemq "Unsupported neptune type 16")); 842259ac0c16Sdavemq goto error_exit; 842359a835ddSjoycey } 842459a835ddSjoycey NXGE_DEBUG_MSG((nxgep, MAC_CTL, 842559a835ddSjoycey "2 RGMII Fiber ports - RTM")); 842659a835ddSjoycey break; 842759a835ddSjoycey 842859ac0c16Sdavemq case 1: 842959ac0c16Sdavemq /* TODO 1 1G mode */ 843059ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 843159ac0c16Sdavemq "Unsupported neptune type 17")); 843259ac0c16Sdavemq goto error_exit; 843359ac0c16Sdavemq default: 843459ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 843559ac0c16Sdavemq "Unsupported neptune type 18, total phy fd %d", 843659ac0c16Sdavemq total_phy_fd)); 843759ac0c16Sdavemq goto error_exit; 843859ac0c16Sdavemq } 843959ac0c16Sdavemq break; 844059ac0c16Sdavemq default: 844159ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 844259ac0c16Sdavemq "Unsupported neptune type 19")); 844359ac0c16Sdavemq goto error_exit; 844459ac0c16Sdavemq } 844559ac0c16Sdavemq 844659ac0c16Sdavemq scan_exit: 844759ac0c16Sdavemq 844859ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 844959ac0c16Sdavemq "niu type [0x%x]\n", hw_p->niu_type)); 845059ac0c16Sdavemq return (status); 845159ac0c16Sdavemq 845259ac0c16Sdavemq error_exit: 845359ac0c16Sdavemq return (NXGE_ERROR); 845459ac0c16Sdavemq } 845559ac0c16Sdavemq 845656d930aeSspeer boolean_t 845756d930aeSspeer nxge_is_valid_local_mac(ether_addr_st mac_addr) 845856d930aeSspeer { 845956d930aeSspeer if ((mac_addr.ether_addr_octet[0] & 0x01) || 846056d930aeSspeer (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 846156d930aeSspeer (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 846256d930aeSspeer return (B_FALSE); 846356d930aeSspeer else 846456d930aeSspeer return (B_TRUE); 846556d930aeSspeer } 846659ac0c16Sdavemq 846759ac0c16Sdavemq static void 846859ac0c16Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 846959ac0c16Sdavemq 847059ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 847159ac0c16Sdavemq uint8_t xcvr_portn; 847259ac0c16Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 847359ac0c16Sdavemq 847459ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 847559ac0c16Sdavemq 847659ac0c16Sdavemq if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 847700161856Syc148097 xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE; 847859ac0c16Sdavemq } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 847900161856Syc148097 xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE; 848059ac0c16Sdavemq } 848159ac0c16Sdavemq /* 848259ac0c16Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 848359ac0c16Sdavemq * swapped with ethernet port number. This is 848459ac0c16Sdavemq * designed for better signal integrity in routing. 848559ac0c16Sdavemq */ 848659ac0c16Sdavemq switch (portn) { 848759ac0c16Sdavemq case 0: 848859ac0c16Sdavemq xcvr_portn += 3; 848959ac0c16Sdavemq break; 849059ac0c16Sdavemq case 1: 849159ac0c16Sdavemq xcvr_portn += 2; 849259ac0c16Sdavemq break; 849359ac0c16Sdavemq case 2: 849459ac0c16Sdavemq xcvr_portn += 1; 849559ac0c16Sdavemq break; 849659ac0c16Sdavemq case 3: 849759ac0c16Sdavemq default: 849859ac0c16Sdavemq break; 849959ac0c16Sdavemq } 850059ac0c16Sdavemq 8501321febdeSsbehera MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock); 850259ac0c16Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 850359ac0c16Sdavemq xcvr_portn, BCM5464R_MISC, 0xb4ee); 850459ac0c16Sdavemq if (rs != NPI_SUCCESS) { 850559ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 850659ac0c16Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 850759ac0c16Sdavemq "returned error 0x[%x]", rs)); 8508321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 850959ac0c16Sdavemq return; 851059ac0c16Sdavemq } 851159ac0c16Sdavemq 851259ac0c16Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 851359ac0c16Sdavemq xcvr_portn, BCM5464R_MISC, 0xb8ee); 851459ac0c16Sdavemq if (rs != NPI_SUCCESS) { 851559ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 851659ac0c16Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 851759ac0c16Sdavemq "returned error 0x[%x]", rs)); 851859ac0c16Sdavemq } 851959ac0c16Sdavemq 8520321febdeSsbehera MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock); 852159ac0c16Sdavemq } 8522d81011f0Ssbehera 8523d81011f0Ssbehera static nxge_status_t 8524d81011f0Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep) 8525d81011f0Ssbehera { 8526d81011f0Ssbehera p_nxge_stats_t statsp; 8527d81011f0Ssbehera uint8_t xcvr_portn; 8528d81011f0Ssbehera p_mii_regs_t mii_regs; 8529d81011f0Ssbehera mii_mode_control_stat_t mode; 8530d81011f0Ssbehera int status = NXGE_OK; 8531d81011f0Ssbehera 8532d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode")); 8533d81011f0Ssbehera 8534d81011f0Ssbehera statsp = nxgep->statsp; 8535d81011f0Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 8536d81011f0Ssbehera mii_regs = NULL; 8537d81011f0Ssbehera mode.value = 0; 85386b438925Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 8539d81011f0Ssbehera #if defined(__i386) 8540d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 8541d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 8542d81011f0Ssbehera mode.value)) != NXGE_OK) { 8543d81011f0Ssbehera goto fail; 8544d81011f0Ssbehera #else 8545d81011f0Ssbehera if ((status = nxge_mii_write(nxgep, xcvr_portn, 8546d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 8547d81011f0Ssbehera mode.value)) != NXGE_OK) { 8548d81011f0Ssbehera goto fail; 8549d81011f0Ssbehera #endif 8550d81011f0Ssbehera } 8551d81011f0Ssbehera #if defined(__i386) 8552d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 8553d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), 8554d81011f0Ssbehera &mode.value)) != NXGE_OK) { 8555d81011f0Ssbehera goto fail; 8556d81011f0Ssbehera } 8557d81011f0Ssbehera #else 8558d81011f0Ssbehera if ((status = nxge_mii_read(nxgep, xcvr_portn, 8559d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), 8560d81011f0Ssbehera &mode.value)) != NXGE_OK) { 8561d81011f0Ssbehera goto fail; 8562d81011f0Ssbehera } 8563d81011f0Ssbehera #endif 8564d81011f0Ssbehera 8565d81011f0Ssbehera if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) { 8566d81011f0Ssbehera nxgep->mac.portmode = PORT_1G_RGMII_FIBER; 8567d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8568d81011f0Ssbehera "nxge_mii_get_link_mode: fiber mode")); 8569d81011f0Ssbehera } 8570d81011f0Ssbehera 8571d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8572d81011f0Ssbehera "nxge_mii_get_link_mode: " 8573d81011f0Ssbehera "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x", 85746b438925Ssbehera NXGE_MII_MODE_CONTROL_REG, xcvr_portn, 8575d81011f0Ssbehera mode.value, nxgep->mac.portmode)); 8576d81011f0Ssbehera 8577d81011f0Ssbehera NXGE_DEBUG_MSG((nxgep, MAC_CTL, 8578d81011f0Ssbehera "<== nxge_mii_get_link_mode")); 8579d81011f0Ssbehera return (status); 8580d81011f0Ssbehera fail: 8581d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8582d81011f0Ssbehera "<== nxge_mii_get_link_mode (failed)")); 8583d81011f0Ssbehera return (NXGE_ERROR); 8584d81011f0Ssbehera } 8585d81011f0Ssbehera 85861bd6825cSml29623 nxge_status_t 85871bd6825cSml29623 nxge_mac_set_framesize(p_nxge_t nxgep) 85881bd6825cSml29623 { 85891bd6825cSml29623 npi_attr_t ap; 85901bd6825cSml29623 uint8_t portn; 85911bd6825cSml29623 npi_handle_t handle; 85921bd6825cSml29623 npi_status_t rs = NPI_SUCCESS; 85931bd6825cSml29623 85941bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize")); 85951bd6825cSml29623 85961bd6825cSml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 85971bd6825cSml29623 handle = nxgep->npi_handle; 85981bd6825cSml29623 85991bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 86001bd6825cSml29623 "==> nxge_mac_sec_framesize: port<%d> " 86011bd6825cSml29623 "min framesize %d max framesize %d ", 86021bd6825cSml29623 portn, 86031bd6825cSml29623 nxgep->mac.minframesize, 86041bd6825cSml29623 nxgep->mac.maxframesize)); 86051bd6825cSml29623 86061bd6825cSml29623 SET_MAC_ATTR2(handle, ap, portn, 86071bd6825cSml29623 MAC_PORT_FRAME_SIZE, 86081bd6825cSml29623 nxgep->mac.minframesize, 86091bd6825cSml29623 nxgep->mac.maxframesize, 86101bd6825cSml29623 rs); 86111bd6825cSml29623 if (rs != NPI_SUCCESS) { 86121bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 86131bd6825cSml29623 "<== nxge_mac_set_framesize: failed to configure " 86141bd6825cSml29623 "max/min frame size port %d", portn)); 86151bd6825cSml29623 86161bd6825cSml29623 return (NXGE_ERROR | rs); 86171bd6825cSml29623 } 86181bd6825cSml29623 86191bd6825cSml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 86201bd6825cSml29623 "<== nxge_mac_set_framesize: port<%d>", portn)); 86211bd6825cSml29623 86221bd6825cSml29623 return (NXGE_OK); 86231bd6825cSml29623 } 86241bd6825cSml29623 862500161856Syc148097 static nxge_status_t 862600161856Syc148097 nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id, 862700161856Syc148097 uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui) 862800161856Syc148097 { 862900161856Syc148097 uint8_t i; 863000161856Syc148097 863100161856Syc148097 for (i = 0; i < 4; i++) { 863200161856Syc148097 if (port_phy_id[i] != PHY_BCM5464R_FAMILY) 863300161856Syc148097 return (NXGE_ERROR); 863400161856Syc148097 } 863500161856Syc148097 863600161856Syc148097 *num_xaui = 0; 863700161856Syc148097 if ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY && 863800161856Syc148097 port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) || 863900161856Syc148097 (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK) 864000161856Syc148097 == TN1010_DEV_ID) && 864100161856Syc148097 ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK) 864200161856Syc148097 == TN1010_DEV_ID))) { 864300161856Syc148097 (*num_xaui) ++; 864400161856Syc148097 } 864500161856Syc148097 if ((port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY && 864600161856Syc148097 port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) || 864700161856Syc148097 (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) 864800161856Syc148097 == TN1010_DEV_ID) && 864900161856Syc148097 ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK) 865000161856Syc148097 == TN1010_DEV_ID))) { 865100161856Syc148097 (*num_xaui) ++; 865200161856Syc148097 } 865300161856Syc148097 return (NXGE_OK); 865400161856Syc148097 } 865500161856Syc148097 865600161856Syc148097 /* 865700161856Syc148097 * Instruction from Teranetics: Once you detect link is up, go 865800161856Syc148097 * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You 865900161856Syc148097 * may want to qualify it by first checking Register 30.1.7:6 and 866000161856Syc148097 * making sure it reads "01" (Auto-Neg Complete). 866100161856Syc148097 * 866200161856Syc148097 * If this function is called when the link is down or before auto- 866300161856Syc148097 * negotiation has completed, then the speed of the PHY is not certain. 866400161856Syc148097 * In such cases, this function returns 1G as the default speed with 866500161856Syc148097 * NXGE_OK status instead of NXGE_ERROR. It is OK to initialize the 866600161856Syc148097 * driver based on a default speed because this function will be called 866700161856Syc148097 * again when the link comes up. Returning NXGE_ERROR, which may 866800161856Syc148097 * cause brutal chain reaction in caller functions, is not necessary. 866900161856Syc148097 */ 867000161856Syc148097 static nxge_status_t 867100161856Syc148097 nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed) 867200161856Syc148097 { 867300161856Syc148097 uint8_t phy_port_addr, autoneg_stat, link_up; 867400161856Syc148097 nxge_status_t status = NXGE_OK; 867500161856Syc148097 uint16_t val; 867600161856Syc148097 uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 867700161856Syc148097 867800161856Syc148097 /* Set default speed to 10G */ 867900161856Syc148097 *speed = TN1010_SPEED_10G; 868000161856Syc148097 868100161856Syc148097 /* Set Clause 45 */ 868200161856Syc148097 npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 868300161856Syc148097 868400161856Syc148097 phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn]; 868500161856Syc148097 868600161856Syc148097 /* Check Device 1 Register 0xA bit0 for link up status */ 868700161856Syc148097 status = nxge_mdio_read(nxgep, phy_port_addr, 868800161856Syc148097 TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val); 868900161856Syc148097 if (status != NXGE_OK) 869000161856Syc148097 goto fail; 869100161856Syc148097 869200161856Syc148097 link_up = ((val & TN1010_AN_LINK_STAT_BIT) 869300161856Syc148097 ? B_TRUE : B_FALSE); 869400161856Syc148097 if (link_up == B_FALSE) { 869500161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 869600161856Syc148097 "nxge_get_tn1010_speed: link is down")); 869700161856Syc148097 goto nxge_get_tn1010_speed_exit; 869800161856Syc148097 } 869900161856Syc148097 870000161856Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 870100161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG, 870200161856Syc148097 &val)) != NXGE_OK) { 870300161856Syc148097 goto fail; 870400161856Syc148097 } 870500161856Syc148097 autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >> 870600161856Syc148097 TN1010_VENDOR_MMD1_AN_STAT_SHIFT; 870700161856Syc148097 870800161856Syc148097 /* 870900161856Syc148097 * Return NXGE_OK even when we can not get a settled speed. In 871000161856Syc148097 * such case, the speed reported should not be trusted but that 871100161856Syc148097 * is OK, we will call this function periodically and will get 871200161856Syc148097 * the correct speed after the link is up. 871300161856Syc148097 */ 871400161856Syc148097 switch (autoneg_stat) { 871500161856Syc148097 case TN1010_AN_IN_PROG: 871600161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 871700161856Syc148097 "nxge_get_tn1010_speed: Auto-negotiation in progress")); 871800161856Syc148097 break; 871900161856Syc148097 case TN1010_AN_COMPLETE: 872000161856Syc148097 if ((status = nxge_mdio_read(nxgep, phy_port_addr, 872100161856Syc148097 TN1010_VENDOR_MMD1_DEV_ADDR, 872200161856Syc148097 TN1010_VENDOR_MMD1_STATUS_REG, 872300161856Syc148097 &val)) != NXGE_OK) { 872400161856Syc148097 goto fail; 872500161856Syc148097 } 872600161856Syc148097 *speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >> 872700161856Syc148097 TN1010_VENDOR_MMD1_AN_SPEED_SHIFT; 872800161856Syc148097 break; 872900161856Syc148097 case TN1010_AN_RSVD: 873000161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 873100161856Syc148097 "nxge_get_tn1010_speed: Autoneg status undefined")); 873200161856Syc148097 break; 873300161856Syc148097 case TN1010_AN_FAILED: 873400161856Syc148097 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 873500161856Syc148097 "nxge_get_tn1010_speed: Auto-negotiation failed")); 873600161856Syc148097 break; 873700161856Syc148097 default: 873800161856Syc148097 break; 873900161856Syc148097 } 874000161856Syc148097 nxge_get_tn1010_speed_exit: 874100161856Syc148097 return (NXGE_OK); 874200161856Syc148097 fail: 874300161856Syc148097 return (status); 874400161856Syc148097 } 874500161856Syc148097 874600161856Syc148097 874700161856Syc148097 /* 874800161856Syc148097 * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function 874900161856Syc148097 * figures out the speed of the PHY determined by the autonegotiation 875000161856Syc148097 * process and sets the following 3 parameters, 875100161856Syc148097 * nxgep->mac.portmode 875200161856Syc148097 * nxgep->statsp->mac_stats.link_speed 875300161856Syc148097 * nxgep->statsp->mac_stats.xcvr_inuse 875400161856Syc148097 */ 875500161856Syc148097 static nxge_status_t 875600161856Syc148097 nxge_set_tn1010_param(p_nxge_t nxgep) 875700161856Syc148097 { 875800161856Syc148097 uint16_t speed; 875900161856Syc148097 876000161856Syc148097 if (nxge_get_tn1010_speed(nxgep, &speed) != NXGE_OK) { 876100161856Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 876200161856Syc148097 "nxge_set_tn1010_param: " 876300161856Syc148097 "Failed to get TN1010 speed")); 876400161856Syc148097 return (NXGE_ERROR); 876500161856Syc148097 } 876600161856Syc148097 if (speed == TN1010_SPEED_1G) { 876700161856Syc148097 nxgep->mac.portmode = PORT_1G_TN1010; 876800161856Syc148097 nxgep->statsp->mac_stats.link_speed = 1000; 876900161856Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 877000161856Syc148097 } else { 877100161856Syc148097 nxgep->mac.portmode = PORT_10G_TN1010; 877200161856Syc148097 nxgep->statsp->mac_stats.link_speed = 10000; 877300161856Syc148097 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 877400161856Syc148097 } 877500161856Syc148097 return (NXGE_OK); 877600161856Syc148097 } 877700161856Syc148097 8778d81011f0Ssbehera #ifdef NXGE_DEBUG 8779d81011f0Ssbehera static void 8780d81011f0Ssbehera nxge_mii_dump(p_nxge_t nxgep) 8781d81011f0Ssbehera { 8782d81011f0Ssbehera p_nxge_stats_t statsp; 8783d81011f0Ssbehera uint8_t xcvr_portn; 8784d81011f0Ssbehera p_mii_regs_t mii_regs; 8785d81011f0Ssbehera mii_bmcr_t bmcr; 8786d81011f0Ssbehera mii_bmsr_t bmsr; 8787d81011f0Ssbehera mii_idr1_t idr1; 8788d81011f0Ssbehera mii_idr2_t idr2; 8789d81011f0Ssbehera mii_mode_control_stat_t mode; 8790678453a8Sspeer p_nxge_param_t param_arr; 8791d81011f0Ssbehera 8792d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump")); 8793d81011f0Ssbehera 8794d81011f0Ssbehera statsp = nxgep->statsp; 8795d81011f0Ssbehera xcvr_portn = statsp->mac_stats.xcvr_portn; 8796d81011f0Ssbehera 8797d81011f0Ssbehera mii_regs = NULL; 8798d81011f0Ssbehera 8799d81011f0Ssbehera #if defined(__i386) 8800d81011f0Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 8801d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value); 8802d81011f0Ssbehera #else 8803d81011f0Ssbehera (void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 8804d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value); 8805d81011f0Ssbehera #endif 8806d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8807d81011f0Ssbehera "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x", 8808d81011f0Ssbehera xcvr_portn, bmcr.value)); 8809d81011f0Ssbehera 8810d81011f0Ssbehera #if defined(__i386) 8811d81011f0Ssbehera (void) nxge_mii_read(nxgep, 8812d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 8813d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value); 8814d81011f0Ssbehera #else 8815d81011f0Ssbehera (void) nxge_mii_read(nxgep, 8816d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 8817d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value); 8818d81011f0Ssbehera #endif 8819d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8820d81011f0Ssbehera "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x", 8821d81011f0Ssbehera xcvr_portn, bmsr.value)); 8822d81011f0Ssbehera 8823d81011f0Ssbehera #if defined(__i386) 8824d81011f0Ssbehera (void) nxge_mii_read(nxgep, 8825d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 8826d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value); 8827d81011f0Ssbehera #else 8828d81011f0Ssbehera (void) nxge_mii_read(nxgep, 8829d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 8830d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value); 8831d81011f0Ssbehera #endif 8832d81011f0Ssbehera 8833d81011f0Ssbehera 8834d81011f0Ssbehera #if defined(__i386) 8835d81011f0Ssbehera (void) nxge_mii_read(nxgep, 8836d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 8837d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value); 8838d81011f0Ssbehera #else 8839d81011f0Ssbehera (void) nxge_mii_read(nxgep, 8840d81011f0Ssbehera nxgep->statsp->mac_stats.xcvr_portn, 8841d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value); 8842d81011f0Ssbehera #endif 8843d81011f0Ssbehera 8844d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8845d81011f0Ssbehera "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x", 8846d81011f0Ssbehera xcvr_portn, idr1.value)); 8847d81011f0Ssbehera 8848d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8849d81011f0Ssbehera "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x", 8850d81011f0Ssbehera xcvr_portn, idr2.value)); 8851d81011f0Ssbehera 8852d81011f0Ssbehera mode.value = 0; 88536b438925Ssbehera mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG; 8854d81011f0Ssbehera 8855d81011f0Ssbehera #if defined(__i386) 8856d81011f0Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 8857d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value); 8858d81011f0Ssbehera 8859d81011f0Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 8860d81011f0Ssbehera (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value); 8861d81011f0Ssbehera #else 8862d81011f0Ssbehera (void) nxge_mii_write(nxgep, xcvr_portn, 8863d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value); 8864d81011f0Ssbehera 8865d81011f0Ssbehera (void) nxge_mii_read(nxgep, xcvr_portn, 8866d81011f0Ssbehera (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value); 8867d81011f0Ssbehera #endif 8868d81011f0Ssbehera 8869d81011f0Ssbehera NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 8870d81011f0Ssbehera "nxge_mii_dump: mode control xcvr 0x%x value 0x%x", 8871d81011f0Ssbehera xcvr_portn, mode.value)); 8872d81011f0Ssbehera } 8873d81011f0Ssbehera #endif 8874