144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22a3c5bd6dSspeer * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish #include <sys/nxge/nxge_impl.h> 2944961713Sgirish #include <sys/nxge/nxge_mac.h> 3044961713Sgirish 3198ecde52Stm #define LINK_MONITOR_PERIOD (1000 * 1000) 3298ecde52Stm #define LM_WAIT_MULTIPLIER 8 3398ecde52Stm 3444961713Sgirish extern uint32_t nxge_no_link_notify; 35*59ac0c16Sdavemq extern boolean_t nxge_no_msg; 3644961713Sgirish extern uint32_t nxge_lb_dbg; 3744961713Sgirish extern nxge_os_mutex_t nxge_mdio_lock; 3844961713Sgirish extern nxge_os_mutex_t nxge_mii_lock; 3944961713Sgirish extern boolean_t nxge_jumbo_enable; 4044961713Sgirish 4198ecde52Stm typedef enum { 4298ecde52Stm CHECK_LINK_RESCHEDULE, 4398ecde52Stm CHECK_LINK_STOP 4498ecde52Stm } check_link_state_t; 4598ecde52Stm 4698ecde52Stm static check_link_state_t nxge_check_link_stop(nxge_t *); 4798ecde52Stm 4844961713Sgirish /* 4944961713Sgirish * Ethernet broadcast address definition. 5044961713Sgirish */ 5144961713Sgirish static ether_addr_st etherbroadcastaddr = 5244961713Sgirish {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; 53*59ac0c16Sdavemq /* 54*59ac0c16Sdavemq * Ethernet zero address definition. 55*59ac0c16Sdavemq */ 5656d930aeSspeer static ether_addr_st etherzeroaddr = 5756d930aeSspeer {{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; 58*59ac0c16Sdavemq /* 59*59ac0c16Sdavemq * Supported chip types 60*59ac0c16Sdavemq */ 61*59ac0c16Sdavemq static uint32_t nxge_supported_cl45_ids[] = {BCM8704_DEV_ID}; 62*59ac0c16Sdavemq static uint32_t nxge_supported_cl22_ids[] = {BCM5464R_PHY_ID}; 63*59ac0c16Sdavemq 64*59ac0c16Sdavemq #define NUM_CLAUSE_45_IDS (sizeof (nxge_supported_cl45_ids) / \ 65*59ac0c16Sdavemq sizeof (uint32_t)) 66*59ac0c16Sdavemq #define NUM_CLAUSE_22_IDS (sizeof (nxge_supported_cl22_ids) / \ 67*59ac0c16Sdavemq sizeof (uint32_t)) 68*59ac0c16Sdavemq /* 69*59ac0c16Sdavemq * static functions 70*59ac0c16Sdavemq */ 71*59ac0c16Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t); 72*59ac0c16Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t); 73*59ac0c16Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t); 74*59ac0c16Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t); 75*59ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t); 76*59ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t); 77*59ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t); 78*59ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t); 79*59ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t); 80*59ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t); 81*59ac0c16Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t); 82*59ac0c16Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t); 83*59ac0c16Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t); 84*59ac0c16Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t); 85*59ac0c16Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t); 86*59ac0c16Sdavemq 87*59ac0c16Sdavemq /* 88*59ac0c16Sdavemq * xcvr tables for supported transceivers 89*59ac0c16Sdavemq */ 90*59ac0c16Sdavemq 91*59ac0c16Sdavemq static nxge_xcvr_table_t nxge_n2_table = { 92*59ac0c16Sdavemq nxge_n2_serdes_init, 93*59ac0c16Sdavemq nxge_10G_xcvr_init, 94*59ac0c16Sdavemq nxge_10G_link_intr_stop, 95*59ac0c16Sdavemq nxge_10G_link_intr_start, 96*59ac0c16Sdavemq nxge_check_10g_link, 97*59ac0c16Sdavemq BCM8704_DEV_ID, 98*59ac0c16Sdavemq PCS_XCVR, 99*59ac0c16Sdavemq BCM8704_N2_PORT_ADDR_BASE 100*59ac0c16Sdavemq }; 101*59ac0c16Sdavemq 102*59ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = { 103*59ac0c16Sdavemq nxge_neptune_10G_serdes_init, 104*59ac0c16Sdavemq nxge_10G_xcvr_init, 105*59ac0c16Sdavemq nxge_10G_link_intr_stop, 106*59ac0c16Sdavemq nxge_10G_link_intr_start, 107*59ac0c16Sdavemq nxge_check_10g_link, 108*59ac0c16Sdavemq BCM8704_DEV_ID, 109*59ac0c16Sdavemq PCS_XCVR, 110*59ac0c16Sdavemq BCM8704_NEPTUNE_PORT_ADDR_BASE 111*59ac0c16Sdavemq }; 112*59ac0c16Sdavemq 113*59ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = { 114*59ac0c16Sdavemq NULL, 115*59ac0c16Sdavemq nxge_1G_xcvr_init, 116*59ac0c16Sdavemq nxge_1G_copper_link_intr_stop, 117*59ac0c16Sdavemq nxge_1G_copper_link_intr_start, 118*59ac0c16Sdavemq nxge_check_mii_link, 119*59ac0c16Sdavemq BCM5464R_PHY_ID, 120*59ac0c16Sdavemq INT_MII_XCVR, 121*59ac0c16Sdavemq BCM5464_NEPTUNE_PORT_ADDR_BASE 122*59ac0c16Sdavemq }; 123*59ac0c16Sdavemq 124*59ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = { 125*59ac0c16Sdavemq nxge_1G_serdes_init, 126*59ac0c16Sdavemq nxge_1G_xcvr_init, 127*59ac0c16Sdavemq nxge_1G_fiber_link_intr_stop, 128*59ac0c16Sdavemq nxge_1G_fiber_link_intr_start, 129*59ac0c16Sdavemq nxge_check_mii_link, 130*59ac0c16Sdavemq 0, 131*59ac0c16Sdavemq PCS_XCVR, 132*59ac0c16Sdavemq 0 133*59ac0c16Sdavemq }; 134*59ac0c16Sdavemq 135*59ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = { 136*59ac0c16Sdavemq nxge_neptune_10G_serdes_init, 137*59ac0c16Sdavemq NULL, 138*59ac0c16Sdavemq NULL, 139*59ac0c16Sdavemq NULL, 140*59ac0c16Sdavemq 0, 141*59ac0c16Sdavemq PCS_XCVR, 142*59ac0c16Sdavemq 0 143*59ac0c16Sdavemq }; 14444961713Sgirish 14544961713Sgirish nxge_status_t nxge_mac_init(p_nxge_t); 14644961713Sgirish 147*59ac0c16Sdavemq /* Set up the PHY specific values. */ 148*59ac0c16Sdavemq 149*59ac0c16Sdavemq nxge_status_t 150*59ac0c16Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep) 151*59ac0c16Sdavemq { 152*59ac0c16Sdavemq nxge_status_t status = NXGE_OK; 153*59ac0c16Sdavemq uint32_t port_type; 154*59ac0c16Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 155*59ac0c16Sdavemq 156*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>", 157*59ac0c16Sdavemq portn)); 158*59ac0c16Sdavemq 159*59ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 160*59ac0c16Sdavemq nxgep->mac.portmode = PORT_10G_FIBER; 161*59ac0c16Sdavemq nxgep->xcvr = nxge_n2_table; 162*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr += portn; 163*59ac0c16Sdavemq } else { 164*59ac0c16Sdavemq port_type = nxgep->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn); 165*59ac0c16Sdavemq port_type = port_type & (NXGE_PORT_TYPE_MASK); 166*59ac0c16Sdavemq switch (port_type) { 167*59ac0c16Sdavemq case NXGE_PORT_1G_COPPER: 168*59ac0c16Sdavemq nxgep->mac.portmode = PORT_1G_COPPER; 169*59ac0c16Sdavemq nxgep->xcvr = nxge_1G_copper_table; 170*59ac0c16Sdavemq if (nxgep->nxge_hw_p->platform_type == 171*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1) { 172*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr = 173*59ac0c16Sdavemq BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 174*59ac0c16Sdavemq } else if (nxgep->nxge_hw_p->platform_type == 175*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P0) { 176*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr = 177*59ac0c16Sdavemq BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 178*59ac0c16Sdavemq } 179*59ac0c16Sdavemq /* 180*59ac0c16Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 181*59ac0c16Sdavemq * swapped with ethernet port number. This is 182*59ac0c16Sdavemq * designed for better signal integrity in routing. 183*59ac0c16Sdavemq */ 184*59ac0c16Sdavemq switch (portn) { 185*59ac0c16Sdavemq case 0: 186*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr += 3; 187*59ac0c16Sdavemq break; 188*59ac0c16Sdavemq case 1: 189*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr += 2; 190*59ac0c16Sdavemq break; 191*59ac0c16Sdavemq case 2: 192*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr += 1; 193*59ac0c16Sdavemq break; 194*59ac0c16Sdavemq case 3: 195*59ac0c16Sdavemq break; 196*59ac0c16Sdavemq default: 197*59ac0c16Sdavemq return (NXGE_ERROR); 198*59ac0c16Sdavemq } 199*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr")); 200*59ac0c16Sdavemq break; 201*59ac0c16Sdavemq case NXGE_PORT_10G_COPPER: 202*59ac0c16Sdavemq nxgep->mac.portmode = PORT_10G_COPPER; 203*59ac0c16Sdavemq nxgep->xcvr = nxge_10G_copper_table; 204*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr")); 205*59ac0c16Sdavemq break; 206*59ac0c16Sdavemq case NXGE_PORT_1G_FIBRE: 207*59ac0c16Sdavemq nxgep->mac.portmode = PORT_1G_FIBER; 208*59ac0c16Sdavemq nxgep->xcvr = nxge_1G_fiber_table; 209*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Fiber Xcvr")); 210*59ac0c16Sdavemq break; 211*59ac0c16Sdavemq case NXGE_PORT_10G_FIBRE: 212*59ac0c16Sdavemq nxgep->mac.portmode = PORT_10G_FIBER; 213*59ac0c16Sdavemq nxgep->xcvr = nxge_10G_fiber_table; 214*59ac0c16Sdavemq if ((nxgep->nxge_hw_p->platform_type == 215*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P0) || 216*59ac0c16Sdavemq (nxgep->nxge_hw_p->platform_type == 217*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1)) { 218*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr = 219*59ac0c16Sdavemq BCM8704_MARAMBA_PORT_ADDR_BASE; 220*59ac0c16Sdavemq /* 221*59ac0c16Sdavemq * Switch off LED for corresponding copper 222*59ac0c16Sdavemq * port 223*59ac0c16Sdavemq */ 224*59ac0c16Sdavemq nxge_bcm5464_link_led_off(nxgep); 225*59ac0c16Sdavemq } 226*59ac0c16Sdavemq nxgep->xcvr.xcvr_addr += portn; 227*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr")); 228*59ac0c16Sdavemq break; 229*59ac0c16Sdavemq default: 230*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 231*59ac0c16Sdavemq "Unknown port-type: 0x%x", port_type)); 232*59ac0c16Sdavemq return (NXGE_ERROR); 233*59ac0c16Sdavemq } 234*59ac0c16Sdavemq } 235*59ac0c16Sdavemq 236*59ac0c16Sdavemq nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse; 237*59ac0c16Sdavemq nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr.xcvr_addr; 238*59ac0c16Sdavemq nxgep->statsp->mac_stats.xcvr_id = nxgep->xcvr.device_id; 239*59ac0c16Sdavemq nxgep->mac.linkchkmode = LINKCHK_TIMER; 240*59ac0c16Sdavemq 241*59ac0c16Sdavemq return (status); 242*59ac0c16Sdavemq } 243*59ac0c16Sdavemq 24444961713Sgirish /* Initialize the entire MAC and physical layer */ 24544961713Sgirish 24644961713Sgirish nxge_status_t 24744961713Sgirish nxge_mac_init(p_nxge_t nxgep) 24844961713Sgirish { 24944961713Sgirish uint8_t portn; 25044961713Sgirish nxge_status_t status = NXGE_OK; 25144961713Sgirish 25244961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 25344961713Sgirish 25444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn)); 25544961713Sgirish 25644961713Sgirish nxgep->mac.portnum = portn; 25744961713Sgirish nxgep->mac.porttype = PORT_TYPE_XMAC; 25844961713Sgirish 25944961713Sgirish if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1)) 26044961713Sgirish nxgep->mac.porttype = PORT_TYPE_BMAC; 26144961713Sgirish 26244961713Sgirish /* Initialize XIF to configure a network mode */ 26344961713Sgirish if ((status = nxge_xif_init(nxgep)) != NXGE_OK) { 26444961713Sgirish goto fail; 26544961713Sgirish } 26644961713Sgirish 26744961713Sgirish if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) { 26844961713Sgirish goto fail; 26944961713Sgirish } 27044961713Sgirish 27144961713Sgirish /* Initialize TX and RX MACs */ 27244961713Sgirish /* 27344961713Sgirish * Always perform XIF init first, before TX and RX MAC init 27444961713Sgirish */ 27544961713Sgirish if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK) 27644961713Sgirish goto fail; 27744961713Sgirish 27844961713Sgirish if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 27944961713Sgirish goto fail; 28044961713Sgirish 28144961713Sgirish if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK) 28244961713Sgirish goto fail; 28344961713Sgirish 28444961713Sgirish if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 28544961713Sgirish goto fail; 28644961713Sgirish 28744961713Sgirish if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK) 28844961713Sgirish goto fail; 28944961713Sgirish 29044961713Sgirish if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 29144961713Sgirish goto fail; 29244961713Sgirish 29344961713Sgirish nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize; 29444961713Sgirish 29544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn)); 29644961713Sgirish 29744961713Sgirish return (NXGE_OK); 29844961713Sgirish fail: 29944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 30044961713Sgirish "nxge_mac_init: failed to initialize MAC port<%d>", 30144961713Sgirish portn)); 30244961713Sgirish return (status); 30344961713Sgirish } 30444961713Sgirish 30544961713Sgirish /* Initialize the Ethernet Link */ 30644961713Sgirish 30744961713Sgirish nxge_status_t 30844961713Sgirish nxge_link_init(p_nxge_t nxgep) 30944961713Sgirish { 31044961713Sgirish nxge_status_t status = NXGE_OK; 31144961713Sgirish #ifdef NXGE_DEBUG 31244961713Sgirish uint8_t portn; 31344961713Sgirish 31444961713Sgirish portn = nxgep->mac.portnum; 31544961713Sgirish 31644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn)); 31744961713Sgirish #endif 31844961713Sgirish 31944961713Sgirish if (nxgep->niu_type == N2_NIU) { 32044961713Sgirish /* Workaround to get link up in both NIU ports */ 32144961713Sgirish if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 32244961713Sgirish goto fail; 32344961713Sgirish } 32444961713Sgirish NXGE_DELAY(200000); 32544961713Sgirish /* Initialize internal serdes */ 32644961713Sgirish if ((status = nxge_serdes_init(nxgep)) != NXGE_OK) 32744961713Sgirish goto fail; 32844961713Sgirish NXGE_DELAY(200000); 32944961713Sgirish if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) 33044961713Sgirish goto fail; 33144961713Sgirish 33244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn)); 33344961713Sgirish 33444961713Sgirish return (NXGE_OK); 33544961713Sgirish 33644961713Sgirish fail: 33744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 33844961713Sgirish "nxge_link_init: ", 33944961713Sgirish "failed to initialize Ethernet link on port<%d>", 34044961713Sgirish portn)); 34144961713Sgirish 34244961713Sgirish return (status); 34344961713Sgirish } 34444961713Sgirish 34544961713Sgirish 34644961713Sgirish /* Initialize the XIF sub-block within the MAC */ 34744961713Sgirish 34844961713Sgirish nxge_status_t 34944961713Sgirish nxge_xif_init(p_nxge_t nxgep) 35044961713Sgirish { 35144961713Sgirish uint32_t xif_cfg = 0; 35244961713Sgirish npi_attr_t ap; 35344961713Sgirish uint8_t portn; 35444961713Sgirish nxge_port_t portt; 35544961713Sgirish nxge_port_mode_t portmode; 35644961713Sgirish p_nxge_stats_t statsp; 35744961713Sgirish npi_status_t rs = NPI_SUCCESS; 35844961713Sgirish npi_handle_t handle; 35944961713Sgirish 36044961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 36144961713Sgirish 36244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn)); 36344961713Sgirish 36444961713Sgirish handle = nxgep->npi_handle; 36544961713Sgirish portmode = nxgep->mac.portmode; 36644961713Sgirish portt = nxgep->mac.porttype; 36744961713Sgirish statsp = nxgep->statsp; 36844961713Sgirish 36944961713Sgirish if (portt == PORT_TYPE_XMAC) { 37044961713Sgirish 37144961713Sgirish /* Setup XIF Configuration for XMAC */ 37244961713Sgirish 37344961713Sgirish if ((portmode == PORT_10G_FIBER) || 37444961713Sgirish (portmode == PORT_10G_COPPER)) 37544961713Sgirish xif_cfg |= CFG_XMAC_XIF_LFS; 37644961713Sgirish 37744961713Sgirish if (portmode == PORT_1G_COPPER) { 37844961713Sgirish xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS; 37944961713Sgirish } 38044961713Sgirish 38144961713Sgirish /* Set MAC Internal Loopback if necessary */ 38244961713Sgirish if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 38344961713Sgirish xif_cfg |= CFG_XMAC_XIF_LOOPBACK; 38444961713Sgirish 38544961713Sgirish if (statsp->mac_stats.link_speed == 100) 38644961713Sgirish xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ; 38744961713Sgirish 38844961713Sgirish xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT; 38944961713Sgirish 39044961713Sgirish if (portmode == PORT_10G_FIBER) { 39144961713Sgirish if (statsp->mac_stats.link_up) { 39244961713Sgirish xif_cfg |= CFG_XMAC_XIF_LED_POLARITY; 39344961713Sgirish } else { 39444961713Sgirish xif_cfg |= CFG_XMAC_XIF_LED_FORCE; 39544961713Sgirish } 39644961713Sgirish } 39744961713Sgirish 39844961713Sgirish rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg); 39944961713Sgirish if (rs != NPI_SUCCESS) 40044961713Sgirish goto fail; 40144961713Sgirish 40244961713Sgirish nxgep->mac.xif_config = xif_cfg; 40344961713Sgirish 40444961713Sgirish /* Set Port Mode */ 40544961713Sgirish if ((portmode == PORT_10G_FIBER) || 40644961713Sgirish (portmode == PORT_10G_COPPER)) { 40744961713Sgirish SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 40844961713Sgirish MAC_XGMII_MODE, rs); 40944961713Sgirish if (rs != NPI_SUCCESS) 41044961713Sgirish goto fail; 41144961713Sgirish if (statsp->mac_stats.link_up) { 41244961713Sgirish if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 41344961713Sgirish goto fail; 41444961713Sgirish } else { 41544961713Sgirish if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 41644961713Sgirish goto fail; 41744961713Sgirish } 41844961713Sgirish } else if ((portmode == PORT_1G_FIBER) || 41944961713Sgirish (portmode == PORT_1G_COPPER)) { 42044961713Sgirish if (statsp->mac_stats.link_speed == 1000) { 42144961713Sgirish SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 42244961713Sgirish MAC_GMII_MODE, rs); 42344961713Sgirish } else { 42444961713Sgirish SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE, 42544961713Sgirish MAC_MII_MODE, rs); 42644961713Sgirish } 42744961713Sgirish if (rs != NPI_SUCCESS) 42844961713Sgirish goto fail; 42944961713Sgirish } else { 43044961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 43144961713Sgirish "nxge_xif_init: Unknown port mode (%d)" 43244961713Sgirish " for port<%d>", portmode, portn)); 43344961713Sgirish goto fail; 43444961713Sgirish } 43544961713Sgirish 43644961713Sgirish } else if (portt == PORT_TYPE_BMAC) { 43744961713Sgirish 43844961713Sgirish /* Setup XIF Configuration for BMAC */ 43944961713Sgirish 44044961713Sgirish if (portmode == PORT_1G_COPPER) { 44144961713Sgirish if (statsp->mac_stats.link_speed == 100) 44244961713Sgirish xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ; 44344961713Sgirish } 44444961713Sgirish 44544961713Sgirish if (statsp->port_stats.lb_mode == nxge_lb_mac1000) 44644961713Sgirish xif_cfg |= CFG_BMAC_XIF_LOOPBACK; 44744961713Sgirish 44844961713Sgirish if (statsp->mac_stats.link_speed == 1000) 44944961713Sgirish xif_cfg |= CFG_BMAC_XIF_GMII_MODE; 45044961713Sgirish 45144961713Sgirish xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT; 45244961713Sgirish 45344961713Sgirish rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg); 45444961713Sgirish if (rs != NPI_SUCCESS) 45544961713Sgirish goto fail; 45644961713Sgirish nxgep->mac.xif_config = xif_cfg; 45744961713Sgirish } 45844961713Sgirish 45944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn)); 46044961713Sgirish return (NXGE_OK); 46144961713Sgirish fail: 46244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 46344961713Sgirish "nxge_xif_init: Failed to initialize XIF port<%d>", 46444961713Sgirish portn)); 46544961713Sgirish return (NXGE_ERROR | rs); 46644961713Sgirish } 46744961713Sgirish 46844961713Sgirish /* Initialize the PCS sub-block in the MAC */ 46944961713Sgirish 47044961713Sgirish nxge_status_t 47144961713Sgirish nxge_pcs_init(p_nxge_t nxgep) 47244961713Sgirish { 47344961713Sgirish pcs_cfg_t pcs_cfg; 47444961713Sgirish uint32_t val; 47544961713Sgirish uint8_t portn; 47644961713Sgirish nxge_port_mode_t portmode; 47744961713Sgirish npi_handle_t handle; 47844961713Sgirish p_nxge_stats_t statsp; 47944961713Sgirish npi_status_t rs = NPI_SUCCESS; 48044961713Sgirish 48144961713Sgirish handle = nxgep->npi_handle; 48244961713Sgirish portmode = nxgep->mac.portmode; 48344961713Sgirish portn = nxgep->mac.portnum; 48444961713Sgirish statsp = nxgep->statsp; 48544961713Sgirish 48644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn)); 48744961713Sgirish 48844961713Sgirish if (portmode == PORT_1G_FIBER) { 48944961713Sgirish /* Initialize port's PCS */ 49044961713Sgirish pcs_cfg.value = 0; 49144961713Sgirish pcs_cfg.bits.w0.enable = 1; 49244961713Sgirish pcs_cfg.bits.w0.mask = 1; 49344961713Sgirish PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value); 49444961713Sgirish PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0); 49544961713Sgirish if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 49644961713Sgirish goto fail; 49744961713Sgirish 49844961713Sgirish } else if ((portmode == PORT_10G_FIBER) || 49944961713Sgirish (portmode == PORT_10G_COPPER)) { 50044961713Sgirish /* Use internal XPCS, bypass 1G PCS */ 50144961713Sgirish XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val); 50244961713Sgirish val &= ~XMAC_XIF_XPCS_BYPASS; 50344961713Sgirish XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val); 50444961713Sgirish 50544961713Sgirish if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS) 50644961713Sgirish goto fail; 50744961713Sgirish 50844961713Sgirish /* Set XPCS Internal Loopback if necessary */ 50944961713Sgirish if ((rs = npi_xmac_xpcs_read(handle, portn, 51044961713Sgirish XPCS_REG_CONTROL1, &val)) 51144961713Sgirish != NPI_SUCCESS) 51244961713Sgirish goto fail; 51344961713Sgirish if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) || 51444961713Sgirish (statsp->port_stats.lb_mode == nxge_lb_mac1000)) 51544961713Sgirish val |= XPCS_CTRL1_LOOPBK; 51644961713Sgirish else 51744961713Sgirish val &= ~XPCS_CTRL1_LOOPBK; 51844961713Sgirish if ((rs = npi_xmac_xpcs_write(handle, portn, 51944961713Sgirish XPCS_REG_CONTROL1, val)) 52044961713Sgirish != NPI_SUCCESS) 52144961713Sgirish goto fail; 52244961713Sgirish 52344961713Sgirish /* Clear descw errors */ 52444961713Sgirish if ((rs = npi_xmac_xpcs_write(handle, portn, 52544961713Sgirish XPCS_REG_DESCWERR_COUNTER, 0)) 52644961713Sgirish != NPI_SUCCESS) 52744961713Sgirish goto fail; 52844961713Sgirish /* Clear symbol errors */ 52944961713Sgirish if ((rs = npi_xmac_xpcs_read(handle, portn, 53044961713Sgirish XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) 53144961713Sgirish != NPI_SUCCESS) 53244961713Sgirish goto fail; 53344961713Sgirish if ((rs = npi_xmac_xpcs_read(handle, portn, 53444961713Sgirish XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) 53544961713Sgirish != NPI_SUCCESS) 53644961713Sgirish goto fail; 53744961713Sgirish 53844961713Sgirish } else if (portmode == PORT_1G_COPPER) { 53944961713Sgirish if (portn < 4) { 54044961713Sgirish PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 54144961713Sgirish PCS_DATAPATH_MODE_MII); 54244961713Sgirish } 54344961713Sgirish if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) 54444961713Sgirish goto fail; 54544961713Sgirish 54644961713Sgirish } else { 54744961713Sgirish goto fail; 54844961713Sgirish } 54944961713Sgirish pass: 55044961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn)); 55144961713Sgirish return (NXGE_OK); 55244961713Sgirish fail: 55344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 55444961713Sgirish "nxge_pcs_init: Failed to initialize PCS port<%d>", 55544961713Sgirish portn)); 55644961713Sgirish return (NXGE_ERROR | rs); 55744961713Sgirish } 55844961713Sgirish 55944961713Sgirish /* Initialize the Internal Serdes */ 56044961713Sgirish 56144961713Sgirish nxge_status_t 56244961713Sgirish nxge_serdes_init(p_nxge_t nxgep) 56344961713Sgirish { 56444961713Sgirish p_nxge_stats_t statsp; 56544961713Sgirish #ifdef NXGE_DEBUG 56644961713Sgirish uint8_t portn; 56744961713Sgirish #endif 56844961713Sgirish nxge_status_t status = NXGE_OK; 56944961713Sgirish 57044961713Sgirish #ifdef NXGE_DEBUG 57144961713Sgirish portn = nxgep->mac.portnum; 57244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 573*59ac0c16Sdavemq "==> nxge_serdes_init port<%d>", portn)); 57444961713Sgirish #endif 57544961713Sgirish 576*59ac0c16Sdavemq if (nxgep->xcvr.serdes_init) { 577*59ac0c16Sdavemq statsp = nxgep->statsp; 578*59ac0c16Sdavemq status = nxgep->xcvr.serdes_init(nxgep); 579*59ac0c16Sdavemq if (status != NXGE_OK) 58044961713Sgirish goto fail; 581*59ac0c16Sdavemq statsp->mac_stats.serdes_inits++; 58244961713Sgirish } 58344961713Sgirish 58444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>", 585*59ac0c16Sdavemq portn)); 58644961713Sgirish 58744961713Sgirish return (NXGE_OK); 58844961713Sgirish 58944961713Sgirish fail: 59044961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 591*59ac0c16Sdavemq "nxge_serdes_init: Failed to initialize serdes for port<%d>", 592*59ac0c16Sdavemq portn)); 59344961713Sgirish 59444961713Sgirish return (status); 59544961713Sgirish } 59644961713Sgirish 59744961713Sgirish /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */ 59844961713Sgirish 599*59ac0c16Sdavemq static nxge_status_t 60044961713Sgirish nxge_n2_serdes_init(p_nxge_t nxgep) 60144961713Sgirish { 60244961713Sgirish uint8_t portn; 60344961713Sgirish int chan; 60444961713Sgirish esr_ti_cfgpll_l_t pll_cfg_l; 60544961713Sgirish esr_ti_cfgrx_l_t rx_cfg_l; 60644961713Sgirish esr_ti_cfgrx_h_t rx_cfg_h; 60744961713Sgirish esr_ti_cfgtx_l_t tx_cfg_l; 60844961713Sgirish esr_ti_cfgtx_h_t tx_cfg_h; 60944961713Sgirish esr_ti_testcfg_t test_cfg; 61044961713Sgirish nxge_status_t status = NXGE_OK; 61144961713Sgirish 61244961713Sgirish portn = nxgep->mac.portnum; 61344961713Sgirish 61444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>", 61544961713Sgirish portn)); 61644961713Sgirish 61744961713Sgirish tx_cfg_l.value = 0; 61844961713Sgirish tx_cfg_h.value = 0; 61944961713Sgirish rx_cfg_l.value = 0; 62044961713Sgirish rx_cfg_h.value = 0; 62144961713Sgirish pll_cfg_l.value = 0; 62244961713Sgirish test_cfg.value = 0; 62344961713Sgirish 62444961713Sgirish if (nxgep->mac.portmode == PORT_10G_FIBER) { 62544961713Sgirish /* 0x0E01 */ 62644961713Sgirish tx_cfg_l.bits.entx = 1; 62744961713Sgirish tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 62844961713Sgirish 62944961713Sgirish /* 0x9101 */ 63044961713Sgirish rx_cfg_l.bits.enrx = 1; 63144961713Sgirish rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 63244961713Sgirish rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 63344961713Sgirish rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 63444961713Sgirish 63544961713Sgirish /* 0x0008 */ 63644961713Sgirish rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 63744961713Sgirish 63844961713Sgirish /* Set loopback mode if necessary */ 63944961713Sgirish if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 64044961713Sgirish tx_cfg_l.bits.entest = 1; 64144961713Sgirish rx_cfg_l.bits.entest = 1; 64244961713Sgirish test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK; 64344961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, 64444961713Sgirish ESR_N2_DEV_ADDR, 64544961713Sgirish ESR_N2_TEST_CFG_REG, test_cfg.value)) 64644961713Sgirish != NXGE_OK) 64744961713Sgirish goto fail; 64844961713Sgirish } 64944961713Sgirish 65044961713Sgirish /* Use default PLL value */ 65144961713Sgirish 65244961713Sgirish } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 65344961713Sgirish 65444961713Sgirish /* 0x0E21 */ 65544961713Sgirish tx_cfg_l.bits.entx = 1; 65644961713Sgirish tx_cfg_l.bits.rate = CFGTX_RATE_HALF; 65744961713Sgirish tx_cfg_l.bits.swing = CFGTX_SWING_1375MV; 65844961713Sgirish 65944961713Sgirish /* 0x9121 */ 66044961713Sgirish rx_cfg_l.bits.enrx = 1; 66144961713Sgirish rx_cfg_l.bits.rate = CFGRX_RATE_HALF; 66244961713Sgirish rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT; 66344961713Sgirish rx_cfg_l.bits.align = CFGRX_ALIGN_EN; 66444961713Sgirish rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES; 66544961713Sgirish 66644961713Sgirish /* 0x8 */ 66744961713Sgirish rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF; 66844961713Sgirish 66944961713Sgirish /* MPY = 0x100 */ 67044961713Sgirish pll_cfg_l.bits.mpy = CFGPLL_MPY_8X; 67144961713Sgirish 67244961713Sgirish /* Set PLL */ 67344961713Sgirish pll_cfg_l.bits.enpll = 1; 67444961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 67544961713Sgirish ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) 67644961713Sgirish != NXGE_OK) 67744961713Sgirish goto fail; 67844961713Sgirish } else { 67944961713Sgirish goto fail; 68044961713Sgirish } 68144961713Sgirish 68244961713Sgirish /* MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */ 68344961713Sgirish 68444961713Sgirish NXGE_DELAY(20); 68544961713Sgirish 68644961713Sgirish /* init TX channels */ 68744961713Sgirish for (chan = 0; chan < 4; chan++) { 68844961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 68944961713Sgirish ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) 69044961713Sgirish != NXGE_OK) 69144961713Sgirish goto fail; 69244961713Sgirish 69344961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 69444961713Sgirish ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) 69544961713Sgirish != NXGE_OK) 69644961713Sgirish goto fail; 69744961713Sgirish } 69844961713Sgirish 69944961713Sgirish /* init RX channels */ 70044961713Sgirish for (chan = 0; chan < 4; chan++) { 70144961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 70244961713Sgirish ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) 70344961713Sgirish != NXGE_OK) 70444961713Sgirish goto fail; 70544961713Sgirish 70644961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR, 70744961713Sgirish ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) 70844961713Sgirish != NXGE_OK) 70944961713Sgirish goto fail; 71044961713Sgirish } 71144961713Sgirish 71244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>", 71344961713Sgirish portn)); 71444961713Sgirish 71544961713Sgirish return (NXGE_OK); 71644961713Sgirish fail: 71744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 71844961713Sgirish "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>", 71944961713Sgirish portn)); 72044961713Sgirish 72144961713Sgirish return (status); 72244961713Sgirish } 72344961713Sgirish 724*59ac0c16Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */ 72544961713Sgirish 726*59ac0c16Sdavemq static nxge_status_t 727*59ac0c16Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep) 72844961713Sgirish { 72944961713Sgirish npi_handle_t handle; 73044961713Sgirish uint8_t portn; 73144961713Sgirish int chan; 73244961713Sgirish sr_rx_tx_ctrl_l_t rx_tx_ctrl_l; 73344961713Sgirish sr_rx_tx_ctrl_h_t rx_tx_ctrl_h; 73444961713Sgirish sr_glue_ctrl0_l_t glue_ctrl0_l; 73544961713Sgirish sr_glue_ctrl0_h_t glue_ctrl0_h; 73644961713Sgirish uint64_t val; 73744961713Sgirish uint16_t val16l; 73844961713Sgirish uint16_t val16h; 73944961713Sgirish nxge_status_t status = NXGE_OK; 74044961713Sgirish 74144961713Sgirish portn = nxgep->mac.portnum; 74244961713Sgirish 74344961713Sgirish if ((portn != 0) && (portn != 1)) 74444961713Sgirish return (NXGE_OK); 74544961713Sgirish 746*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 747*59ac0c16Sdavemq "==> nxge_neptune_10G_serdes_init port<%d>", portn)); 74844961713Sgirish 74944961713Sgirish handle = nxgep->npi_handle; 750*59ac0c16Sdavemq switch (portn) { 751*59ac0c16Sdavemq case 0: 752*59ac0c16Sdavemq ESR_REG_WR(handle, ESR_0_CONTROL_REG, 753*59ac0c16Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 754*59ac0c16Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 755*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 756*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 757*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 758*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 759*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 760*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 761*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 762*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 763*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 764*59ac0c16Sdavemq 765*59ac0c16Sdavemq /* Set Serdes0 Internal Loopback if necessary */ 766*59ac0c16Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 767*59ac0c16Sdavemq ESR_REG_WR(handle, 768*59ac0c16Sdavemq ESR_0_TEST_CONFIG_REG, 769*59ac0c16Sdavemq ESR_PAD_LOOPBACK_CH3 | 770*59ac0c16Sdavemq ESR_PAD_LOOPBACK_CH2 | 771*59ac0c16Sdavemq ESR_PAD_LOOPBACK_CH1 | 772*59ac0c16Sdavemq ESR_PAD_LOOPBACK_CH0); 773*59ac0c16Sdavemq } else { 774*59ac0c16Sdavemq ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0); 77544961713Sgirish } 776*59ac0c16Sdavemq break; 777*59ac0c16Sdavemq case 1: 778*59ac0c16Sdavemq ESR_REG_WR(handle, ESR_1_CONTROL_REG, 779*59ac0c16Sdavemq ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 | 780*59ac0c16Sdavemq ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 | 781*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) | 782*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) | 783*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) | 784*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 785*59ac0c16Sdavemq (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) | 786*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_0_SHIFT) | 787*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_1_SHIFT) | 788*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_2_SHIFT) | 789*59ac0c16Sdavemq (0x1 << ESR_CTL_LOSADJ_3_SHIFT)); 790*59ac0c16Sdavemq 791*59ac0c16Sdavemq /* Set Serdes1 Internal Loopback if necessary */ 792*59ac0c16Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) { 793*59ac0c16Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 794*59ac0c16Sdavemq ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 | 795*59ac0c16Sdavemq ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0); 796*59ac0c16Sdavemq } else { 797*59ac0c16Sdavemq ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0); 79844961713Sgirish } 799*59ac0c16Sdavemq break; 800*59ac0c16Sdavemq default: 801*59ac0c16Sdavemq /* Nothing to do here */ 802*59ac0c16Sdavemq goto done; 803*59ac0c16Sdavemq } 80444961713Sgirish 805*59ac0c16Sdavemq /* init TX RX channels */ 806*59ac0c16Sdavemq for (chan = 0; chan < 4; chan++) { 807*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 808*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 809*59ac0c16Sdavemq &rx_tx_ctrl_l.value)) != NXGE_OK) 81044961713Sgirish goto fail; 811*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 812*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 813*59ac0c16Sdavemq &rx_tx_ctrl_h.value)) != NXGE_OK) 81444961713Sgirish goto fail; 815*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 816*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 817*59ac0c16Sdavemq &glue_ctrl0_l.value)) != NXGE_OK) 818*59ac0c16Sdavemq goto fail; 819*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 820*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 821*59ac0c16Sdavemq &glue_ctrl0_h.value)) != NXGE_OK) 822*59ac0c16Sdavemq goto fail; 823*59ac0c16Sdavemq rx_tx_ctrl_l.bits.enstretch = 1; 824*59ac0c16Sdavemq rx_tx_ctrl_h.bits.vmuxlo = 2; 825*59ac0c16Sdavemq rx_tx_ctrl_h.bits.vpulselo = 2; 826*59ac0c16Sdavemq glue_ctrl0_l.bits.rxlosenable = 1; 827*59ac0c16Sdavemq glue_ctrl0_l.bits.samplerate = 0xF; 828*59ac0c16Sdavemq glue_ctrl0_l.bits.thresholdcount = 0xFF; 829*59ac0c16Sdavemq glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES; 83044961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, 831*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan), 832*59ac0c16Sdavemq rx_tx_ctrl_l.value)) != NXGE_OK) 83344961713Sgirish goto fail; 83444961713Sgirish if ((status = nxge_mdio_write(nxgep, portn, 835*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan), 836*59ac0c16Sdavemq rx_tx_ctrl_h.value)) != NXGE_OK) 83744961713Sgirish goto fail; 838*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 839*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan), 840*59ac0c16Sdavemq glue_ctrl0_l.value)) != NXGE_OK) 84144961713Sgirish goto fail; 842*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 843*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan), 844*59ac0c16Sdavemq glue_ctrl0_h.value)) != NXGE_OK) 84544961713Sgirish goto fail; 84644961713Sgirish } 84744961713Sgirish 848*59ac0c16Sdavemq /* Apply Tx core reset */ 849*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, 850*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 851*59ac0c16Sdavemq (uint16_t)0)) != NXGE_OK) 852*59ac0c16Sdavemq goto fail; 853*59ac0c16Sdavemq 854*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 855*59ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) != 856*59ac0c16Sdavemq NXGE_OK) 857*59ac0c16Sdavemq goto fail; 858*59ac0c16Sdavemq 859*59ac0c16Sdavemq NXGE_DELAY(200); 860*59ac0c16Sdavemq 861*59ac0c16Sdavemq /* Apply Rx core reset */ 862*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 863*59ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) != 864*59ac0c16Sdavemq NXGE_OK) 865*59ac0c16Sdavemq goto fail; 866*59ac0c16Sdavemq 867*59ac0c16Sdavemq NXGE_DELAY(200); 868*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 869*59ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) 870*59ac0c16Sdavemq goto fail; 871*59ac0c16Sdavemq 872*59ac0c16Sdavemq NXGE_DELAY(200); 873*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, 874*59ac0c16Sdavemq ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), 875*59ac0c16Sdavemq &val16l)) != NXGE_OK) 876*59ac0c16Sdavemq goto fail; 877*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR, 878*59ac0c16Sdavemq ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) 879*59ac0c16Sdavemq goto fail; 880*59ac0c16Sdavemq if ((val16l != 0) || (val16h != 0)) { 881*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 882*59ac0c16Sdavemq "Failed to reset port<%d> XAUI Serdes", portn)); 883*59ac0c16Sdavemq } 884*59ac0c16Sdavemq 885*59ac0c16Sdavemq ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val); 88644961713Sgirish 887*59ac0c16Sdavemq if (portn == 0) { 888*59ac0c16Sdavemq if ((val & ESR_SIG_P0_BITS_MASK) != 88944961713Sgirish (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 | 89044961713Sgirish ESR_SIG_XSERDES_RDY_P0 | 89144961713Sgirish ESR_SIG_XDETECT_P0_CH3 | 89244961713Sgirish ESR_SIG_XDETECT_P0_CH2 | 89344961713Sgirish ESR_SIG_XDETECT_P0_CH1 | 89444961713Sgirish ESR_SIG_XDETECT_P0_CH0)) { 895*59ac0c16Sdavemq goto fail; 896*59ac0c16Sdavemq } 897*59ac0c16Sdavemq } else if (portn == 1) { 898*59ac0c16Sdavemq if ((val & ESR_SIG_P1_BITS_MASK) != 89944961713Sgirish (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 | 90044961713Sgirish ESR_SIG_XSERDES_RDY_P1 | 90144961713Sgirish ESR_SIG_XDETECT_P1_CH3 | 90244961713Sgirish ESR_SIG_XDETECT_P1_CH2 | 90344961713Sgirish ESR_SIG_XDETECT_P1_CH1 | 90444961713Sgirish ESR_SIG_XDETECT_P1_CH0)) { 90544961713Sgirish goto fail; 90644961713Sgirish } 90744961713Sgirish } 90844961713Sgirish 90944961713Sgirish done: 910*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 911*59ac0c16Sdavemq "<== nxge_neptune_10G_serdes_init port<%d>", portn)); 912*59ac0c16Sdavemq 91344961713Sgirish return (NXGE_OK); 91444961713Sgirish fail: 915*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 916*59ac0c16Sdavemq "nxge_neptune_10G_serdes_init: " 917*59ac0c16Sdavemq "Failed to initialize Neptune serdes for port<%d>", portn)); 91844961713Sgirish 91944961713Sgirish return (status); 92044961713Sgirish } 92144961713Sgirish 922*59ac0c16Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */ 92344961713Sgirish 924*59ac0c16Sdavemq static nxge_status_t 925*59ac0c16Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep) 92644961713Sgirish { 927*59ac0c16Sdavemq npi_handle_t handle; 928*59ac0c16Sdavemq uint8_t portn; 929*59ac0c16Sdavemq uint64_t val; 93044961713Sgirish 93144961713Sgirish portn = nxgep->mac.portnum; 93244961713Sgirish 933*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 934*59ac0c16Sdavemq "==> nxge_1G_serdes_init port<%d>", portn)); 93544961713Sgirish 936*59ac0c16Sdavemq handle = nxgep->npi_handle; 93744961713Sgirish 938*59ac0c16Sdavemq ESR_REG_RD(handle, ESR_1_PLL_CONFIG_REG, &val); 939*59ac0c16Sdavemq val &= ~ESR_PLL_CFG_FBDIV_2; 940*59ac0c16Sdavemq switch (portn) { 941*59ac0c16Sdavemq case 0: 942*59ac0c16Sdavemq val |= ESR_PLL_CFG_HALF_RATE_0; 943*59ac0c16Sdavemq break; 944*59ac0c16Sdavemq case 1: 945*59ac0c16Sdavemq val |= ESR_PLL_CFG_HALF_RATE_1; 946*59ac0c16Sdavemq break; 947*59ac0c16Sdavemq case 2: 948*59ac0c16Sdavemq val |= ESR_PLL_CFG_HALF_RATE_2; 949*59ac0c16Sdavemq break; 950*59ac0c16Sdavemq case 3: 951*59ac0c16Sdavemq val |= ESR_PLL_CFG_HALF_RATE_3; 952*59ac0c16Sdavemq break; 953*59ac0c16Sdavemq default: 954*59ac0c16Sdavemq goto fail; 95544961713Sgirish } 95644961713Sgirish 957*59ac0c16Sdavemq ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, val); 958*59ac0c16Sdavemq 959*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 960*59ac0c16Sdavemq "<== nxge_1G_serdes_init port<%d>", portn)); 96144961713Sgirish return (NXGE_OK); 962*59ac0c16Sdavemq fail: 963*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, TX_CTL, 964*59ac0c16Sdavemq "nxge_1G_serdes_init: " 965*59ac0c16Sdavemq "Failed to initialize Neptune serdes for port<%d>", 966*59ac0c16Sdavemq portn)); 967*59ac0c16Sdavemq 968*59ac0c16Sdavemq return (NXGE_ERROR); 96944961713Sgirish } 97044961713Sgirish 971*59ac0c16Sdavemq /* Initialize the 10G (BCM8704) Transceiver */ 97244961713Sgirish 973*59ac0c16Sdavemq static nxge_status_t 974*59ac0c16Sdavemq nxge_10G_xcvr_init(p_nxge_t nxgep) 97544961713Sgirish { 97644961713Sgirish p_nxge_stats_t statsp; 97744961713Sgirish uint16_t val; 97844961713Sgirish #ifdef NXGE_DEBUG 97914ea4bb7Ssd uint8_t portn; 98044961713Sgirish uint16_t val1; 98144961713Sgirish #endif 98244961713Sgirish uint8_t phy_port_addr; 98344961713Sgirish pmd_tx_control_t tx_ctl; 98444961713Sgirish control_t ctl; 98544961713Sgirish phyxs_control_t phyxs_ctl; 98644961713Sgirish pcs_control_t pcs_ctl; 98744961713Sgirish uint32_t delay = 0; 98844961713Sgirish optics_dcntr_t op_ctr; 98944961713Sgirish nxge_status_t status = NXGE_OK; 99014ea4bb7Ssd #ifdef NXGE_DEBUG 99144961713Sgirish portn = nxgep->mac.portnum; 99214ea4bb7Ssd #endif 993*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 994*59ac0c16Sdavemq portn)); 99544961713Sgirish 99644961713Sgirish statsp = nxgep->statsp; 99744961713Sgirish 998*59ac0c16Sdavemq phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 999*59ac0c16Sdavemq 1000*59ac0c16Sdavemq /* Disable Link LEDs */ 1001*59ac0c16Sdavemq if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 1002*59ac0c16Sdavemq goto fail; 1003*59ac0c16Sdavemq 1004*59ac0c16Sdavemq /* Set Clause 45 */ 1005*59ac0c16Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE); 1006*59ac0c16Sdavemq 1007*59ac0c16Sdavemq /* Reset the transceiver */ 1008*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 1009*59ac0c16Sdavemq BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK) 1010*59ac0c16Sdavemq goto fail; 1011*59ac0c16Sdavemq 1012*59ac0c16Sdavemq phyxs_ctl.bits.reset = 1; 1013*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR, 1014*59ac0c16Sdavemq BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK) 1015*59ac0c16Sdavemq goto fail; 1016*59ac0c16Sdavemq 1017*59ac0c16Sdavemq do { 1018*59ac0c16Sdavemq drv_usecwait(500); 1019*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1020*59ac0c16Sdavemq BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG, 1021*59ac0c16Sdavemq &phyxs_ctl.value)) != NXGE_OK) 1022*59ac0c16Sdavemq goto fail; 1023*59ac0c16Sdavemq delay++; 1024*59ac0c16Sdavemq } while ((phyxs_ctl.bits.reset) && (delay < 100)); 1025*59ac0c16Sdavemq if (delay == 100) { 1026*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: " 1027*59ac0c16Sdavemq "failed to reset Transceiver on port<%d>", portn)); 1028*59ac0c16Sdavemq status = NXGE_ERROR; 1029*59ac0c16Sdavemq goto fail; 1030*59ac0c16Sdavemq } 103144961713Sgirish 1032*59ac0c16Sdavemq /* Set to 0x7FBF */ 1033*59ac0c16Sdavemq ctl.value = 0; 1034*59ac0c16Sdavemq ctl.bits.res1 = 0x3F; 1035*59ac0c16Sdavemq ctl.bits.optxon_lvl = 1; 1036*59ac0c16Sdavemq ctl.bits.oprxflt_lvl = 1; 1037*59ac0c16Sdavemq ctl.bits.optrxlos_lvl = 1; 1038*59ac0c16Sdavemq ctl.bits.optxflt_lvl = 1; 1039*59ac0c16Sdavemq ctl.bits.opprflt_lvl = 1; 1040*59ac0c16Sdavemq ctl.bits.obtmpflt_lvl = 1; 1041*59ac0c16Sdavemq ctl.bits.opbiasflt_lvl = 1; 1042*59ac0c16Sdavemq ctl.bits.optxrst_lvl = 1; 1043*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1044*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value)) 1045*59ac0c16Sdavemq != NXGE_OK) 1046*59ac0c16Sdavemq goto fail; 1047*59ac0c16Sdavemq 1048*59ac0c16Sdavemq /* Set to 0x164 */ 1049*59ac0c16Sdavemq tx_ctl.value = 0; 1050*59ac0c16Sdavemq tx_ctl.bits.tsck_lpwren = 1; 1051*59ac0c16Sdavemq tx_ctl.bits.tx_dac_txck = 0x2; 1052*59ac0c16Sdavemq tx_ctl.bits.tx_dac_txd = 0x1; 1053*59ac0c16Sdavemq tx_ctl.bits.xfp_clken = 1; 1054*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1055*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, 1056*59ac0c16Sdavemq tx_ctl.value)) != NXGE_OK) 1057*59ac0c16Sdavemq goto fail; 105844961713Sgirish /* 1059*59ac0c16Sdavemq * According to Broadcom's instruction, SW needs to read 1060*59ac0c16Sdavemq * back these registers twice after written. 106144961713Sgirish */ 1062*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1063*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 1064*59ac0c16Sdavemq != NXGE_OK) 1065*59ac0c16Sdavemq goto fail; 106644961713Sgirish 1067*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1068*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val)) 1069*59ac0c16Sdavemq != NXGE_OK) 1070*59ac0c16Sdavemq goto fail; 107144961713Sgirish 1072*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1073*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 1074*59ac0c16Sdavemq != NXGE_OK) 1075*59ac0c16Sdavemq goto fail; 107644961713Sgirish 1077*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1078*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val)) 1079*59ac0c16Sdavemq != NXGE_OK) 1080*59ac0c16Sdavemq goto fail; 108144961713Sgirish 1082*59ac0c16Sdavemq /* Enable Tx and Rx LEDs to be driven by traffic */ 1083*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1084*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1085*59ac0c16Sdavemq &op_ctr.value)) != NXGE_OK) 1086*59ac0c16Sdavemq goto fail; 1087*59ac0c16Sdavemq op_ctr.bits.gpio_sel = 0x3; 1088*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1089*59ac0c16Sdavemq BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG, 1090*59ac0c16Sdavemq op_ctr.value)) != NXGE_OK) 1091*59ac0c16Sdavemq goto fail; 109244961713Sgirish 1093*59ac0c16Sdavemq NXGE_DELAY(1000000); 109444961713Sgirish 1095*59ac0c16Sdavemq /* Set BCM8704 Internal Loopback mode if necessary */ 1096*59ac0c16Sdavemq if ((status = nxge_mdio_read(nxgep, phy_port_addr, 1097*59ac0c16Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value)) 1098*59ac0c16Sdavemq != NXGE_OK) 1099*59ac0c16Sdavemq goto fail; 1100*59ac0c16Sdavemq if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g) 1101*59ac0c16Sdavemq pcs_ctl.bits.loopback = 1; 1102*59ac0c16Sdavemq else 1103*59ac0c16Sdavemq pcs_ctl.bits.loopback = 0; 1104*59ac0c16Sdavemq if ((status = nxge_mdio_write(nxgep, phy_port_addr, 1105*59ac0c16Sdavemq BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value)) 1106*59ac0c16Sdavemq != NXGE_OK) 1107*59ac0c16Sdavemq goto fail; 110844961713Sgirish 1109*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val); 1110*59ac0c16Sdavemq if (status != NXGE_OK) 1111*59ac0c16Sdavemq goto fail; 1112*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1113*59ac0c16Sdavemq "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val)); 1114*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val); 1115*59ac0c16Sdavemq if (status != NXGE_OK) 1116*59ac0c16Sdavemq goto fail; 1117*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1118*59ac0c16Sdavemq "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val)); 1119*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val); 1120*59ac0c16Sdavemq if (status != NXGE_OK) 1121*59ac0c16Sdavemq goto fail; 1122*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1123*59ac0c16Sdavemq "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val)); 112444961713Sgirish 1125*59ac0c16Sdavemq #ifdef NXGE_DEBUG 1126*59ac0c16Sdavemq /* Diagnose link issue if link is not up */ 1127*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR, 1128*59ac0c16Sdavemq BCM8704_USER_ANALOG_STATUS0_REG, 1129*59ac0c16Sdavemq &val); 1130*59ac0c16Sdavemq if (status != NXGE_OK) 1131*59ac0c16Sdavemq goto fail; 113244961713Sgirish 1133*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 113444961713Sgirish BCM8704_USER_DEV3_ADDR, 1135*59ac0c16Sdavemq BCM8704_USER_ANALOG_STATUS0_REG, 1136*59ac0c16Sdavemq &val); 1137*59ac0c16Sdavemq if (status != NXGE_OK) 1138*59ac0c16Sdavemq goto fail; 113944961713Sgirish 1140*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 114144961713Sgirish BCM8704_USER_DEV3_ADDR, 1142*59ac0c16Sdavemq BCM8704_USER_TX_ALARM_STATUS_REG, 1143*59ac0c16Sdavemq &val1); 1144*59ac0c16Sdavemq if (status != NXGE_OK) 1145*59ac0c16Sdavemq goto fail; 114644961713Sgirish 1147*59ac0c16Sdavemq status = nxge_mdio_read(nxgep, phy_port_addr, 114844961713Sgirish BCM8704_USER_DEV3_ADDR, 1149*59ac0c16Sdavemq BCM8704_USER_TX_ALARM_STATUS_REG, 1150*59ac0c16Sdavemq &val1); 1151*59ac0c16Sdavemq if (status != NXGE_OK) 1152*59ac0c16Sdavemq goto fail; 115344961713Sgirish 1154*59ac0c16Sdavemq if (val != 0x3FC) { 1155*59ac0c16Sdavemq if ((val == 0x43BC) && (val1 != 0)) { 1156*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1157*59ac0c16Sdavemq "Cable not connected to peer or bad" 1158*59ac0c16Sdavemq " cable on port<%d>\n", portn)); 1159*59ac0c16Sdavemq } else if (val == 0x639C) { 1160*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1161*59ac0c16Sdavemq "Optical module (XFP) is bad or absent" 1162*59ac0c16Sdavemq " on port<%d>\n", portn)); 1163*59ac0c16Sdavemq } 1164*59ac0c16Sdavemq } 1165*59ac0c16Sdavemq #endif 116644961713Sgirish 1167*59ac0c16Sdavemq statsp->mac_stats.cap_10gfdx = 1; 1168*59ac0c16Sdavemq statsp->mac_stats.lp_cap_10gfdx = 1; 116944961713Sgirish 1170*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>", 1171*59ac0c16Sdavemq portn)); 1172*59ac0c16Sdavemq return (NXGE_OK); 117344961713Sgirish 1174*59ac0c16Sdavemq fail: 1175*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1176*59ac0c16Sdavemq "nxge_10G_xcvr_init: failed to initialize transceiver for " 1177*59ac0c16Sdavemq "port<%d>", portn)); 1178*59ac0c16Sdavemq return (status); 1179*59ac0c16Sdavemq } 118044961713Sgirish 1181*59ac0c16Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */ 118244961713Sgirish 1183*59ac0c16Sdavemq static nxge_status_t 1184*59ac0c16Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep) 1185*59ac0c16Sdavemq { 1186*59ac0c16Sdavemq p_nxge_param_t param_arr = nxgep->param_arr; 1187*59ac0c16Sdavemq p_nxge_stats_t statsp = nxgep->statsp; 1188*59ac0c16Sdavemq nxge_status_t status = NXGE_OK; 118944961713Sgirish 1190*59ac0c16Sdavemq /* Set Clause 22 */ 1191*59ac0c16Sdavemq npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE); 119244961713Sgirish 1193*59ac0c16Sdavemq /* Set capability flags */ 1194*59ac0c16Sdavemq statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value; 1195*59ac0c16Sdavemq statsp->mac_stats.cap_100fdx = param_arr[param_anar_100fdx].value; 1196*59ac0c16Sdavemq statsp->mac_stats.cap_10fdx = param_arr[param_anar_10fdx].value; 119744961713Sgirish 1198*59ac0c16Sdavemq status = nxge_mii_xcvr_init(nxgep); 119944961713Sgirish 1200*59ac0c16Sdavemq return (status); 1201*59ac0c16Sdavemq } 1202*59ac0c16Sdavemq 1203*59ac0c16Sdavemq /* Initialize transceiver */ 1204*59ac0c16Sdavemq 1205*59ac0c16Sdavemq nxge_status_t 1206*59ac0c16Sdavemq nxge_xcvr_init(p_nxge_t nxgep) 1207*59ac0c16Sdavemq { 1208*59ac0c16Sdavemq p_nxge_stats_t statsp; 1209*59ac0c16Sdavemq #ifdef NXGE_DEBUG 1210*59ac0c16Sdavemq uint8_t portn; 121144961713Sgirish #endif 121244961713Sgirish 1213*59ac0c16Sdavemq nxge_status_t status = NXGE_OK; 1214*59ac0c16Sdavemq #ifdef NXGE_DEBUG 1215*59ac0c16Sdavemq portn = nxgep->mac.portnum; 1216*59ac0c16Sdavemq #endif 1217*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn)); 1218*59ac0c16Sdavemq statsp = nxgep->statsp; 121944961713Sgirish 1220*59ac0c16Sdavemq /* 1221*59ac0c16Sdavemq * Initialize the xcvr statistics. 1222*59ac0c16Sdavemq */ 1223*59ac0c16Sdavemq statsp->mac_stats.cap_autoneg = 0; 1224*59ac0c16Sdavemq statsp->mac_stats.cap_100T4 = 0; 1225*59ac0c16Sdavemq statsp->mac_stats.cap_100fdx = 0; 1226*59ac0c16Sdavemq statsp->mac_stats.cap_100hdx = 0; 1227*59ac0c16Sdavemq statsp->mac_stats.cap_10fdx = 0; 1228*59ac0c16Sdavemq statsp->mac_stats.cap_10hdx = 0; 1229*59ac0c16Sdavemq statsp->mac_stats.cap_asmpause = 0; 1230*59ac0c16Sdavemq statsp->mac_stats.cap_pause = 0; 1231*59ac0c16Sdavemq statsp->mac_stats.cap_1000fdx = 0; 1232*59ac0c16Sdavemq statsp->mac_stats.cap_1000hdx = 0; 1233*59ac0c16Sdavemq statsp->mac_stats.cap_10gfdx = 0; 1234*59ac0c16Sdavemq statsp->mac_stats.cap_10ghdx = 0; 1235*59ac0c16Sdavemq 1236*59ac0c16Sdavemq /* 1237*59ac0c16Sdavemq * Initialize the link statistics. 1238*59ac0c16Sdavemq */ 1239*59ac0c16Sdavemq statsp->mac_stats.link_T4 = 0; 1240*59ac0c16Sdavemq statsp->mac_stats.link_asmpause = 0; 1241*59ac0c16Sdavemq statsp->mac_stats.link_pause = 0; 124244961713Sgirish 1243*59ac0c16Sdavemq if (nxgep->xcvr.xcvr_init) { 1244*59ac0c16Sdavemq status = nxgep->xcvr.xcvr_init(nxgep); 1245*59ac0c16Sdavemq if (status != NXGE_OK) 124644961713Sgirish goto fail; 1247*59ac0c16Sdavemq statsp->mac_stats.xcvr_inits++; 124844961713Sgirish } 124944961713Sgirish 1250*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", 1251*59ac0c16Sdavemq portn)); 125244961713Sgirish return (NXGE_OK); 125344961713Sgirish 125444961713Sgirish fail: 125544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 1256*59ac0c16Sdavemq "nxge_xcvr_init: failed to initialize transceiver for port<%d>", 1257*59ac0c16Sdavemq portn)); 125844961713Sgirish return (status); 125944961713Sgirish } 126044961713Sgirish 126144961713Sgirish 126244961713Sgirish /* Initialize the TxMAC sub-block */ 126344961713Sgirish 126444961713Sgirish nxge_status_t 126544961713Sgirish nxge_tx_mac_init(p_nxge_t nxgep) 126644961713Sgirish { 126744961713Sgirish npi_attr_t ap; 126844961713Sgirish uint8_t portn; 126944961713Sgirish nxge_port_mode_t portmode; 127044961713Sgirish nxge_port_t portt; 127144961713Sgirish npi_handle_t handle; 127244961713Sgirish npi_status_t rs = NPI_SUCCESS; 127344961713Sgirish 127444961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 127544961713Sgirish portt = nxgep->mac.porttype; 127644961713Sgirish handle = nxgep->npi_handle; 127744961713Sgirish portmode = nxgep->mac.portmode; 127844961713Sgirish 127944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>", 128044961713Sgirish portn)); 128144961713Sgirish 128244961713Sgirish /* Set Max and Min Frame Size */ 128314ea4bb7Ssd if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) { 128444961713Sgirish SET_MAC_ATTR2(handle, ap, portn, 128544961713Sgirish MAC_PORT_FRAME_SIZE, 64, 0x2400, rs); 128644961713Sgirish } else { 128744961713Sgirish SET_MAC_ATTR2(handle, ap, portn, 128844961713Sgirish MAC_PORT_FRAME_SIZE, 64, 0x5EE + 4, rs); 128944961713Sgirish } 129044961713Sgirish 129144961713Sgirish if (rs != NPI_SUCCESS) 129244961713Sgirish goto fail; 129314ea4bb7Ssd if (nxgep->param_arr[param_accept_jumbo].value || 129414ea4bb7Ssd nxgep->mac.is_jumbo == B_TRUE) 129544961713Sgirish nxgep->mac.maxframesize = 0x2400; 129644961713Sgirish else 129744961713Sgirish nxgep->mac.maxframesize = 0x5EE + 4; 129844961713Sgirish nxgep->mac.minframesize = 64; 129944961713Sgirish 130044961713Sgirish if (portt == PORT_TYPE_XMAC) { 130144961713Sgirish if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn, 130244961713Sgirish 0)) != NPI_SUCCESS) 130344961713Sgirish goto fail; 130444961713Sgirish nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS; 130544961713Sgirish if ((portmode == PORT_10G_FIBER) || 130644961713Sgirish (portmode == PORT_10G_COPPER)) { 130744961713Sgirish SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG, 130844961713Sgirish XGMII_IPG_12_15, rs); 130944961713Sgirish if (rs != NPI_SUCCESS) 131044961713Sgirish goto fail; 131144961713Sgirish nxgep->mac.ipg[0] = XGMII_IPG_12_15; 131244961713Sgirish } else { 131344961713Sgirish SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG, 131444961713Sgirish MII_GMII_IPG_12, rs); 131544961713Sgirish if (rs != NPI_SUCCESS) 131644961713Sgirish goto fail; 131744961713Sgirish nxgep->mac.ipg[0] = MII_GMII_IPG_12; 131844961713Sgirish } 131944961713Sgirish if ((rs = npi_xmac_tx_config(handle, INIT, portn, 132044961713Sgirish CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS) 132144961713Sgirish goto fail; 132244961713Sgirish nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX; 132344961713Sgirish nxgep->mac.maxburstsize = 0; /* not programmable */ 132444961713Sgirish nxgep->mac.ctrltype = 0; /* not programmable */ 132544961713Sgirish nxgep->mac.pa_size = 0; /* not programmable */ 132644961713Sgirish 132744961713Sgirish if ((rs = npi_xmac_zap_tx_counters(handle, portn)) 132844961713Sgirish != NPI_SUCCESS) 132944961713Sgirish goto fail; 133044961713Sgirish 133144961713Sgirish } else { 133244961713Sgirish if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn, 133344961713Sgirish 0)) != NPI_SUCCESS) 133444961713Sgirish goto fail; 133544961713Sgirish nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS; 133644961713Sgirish 133744961713Sgirish SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808, 133844961713Sgirish rs); 133944961713Sgirish if (rs != NPI_SUCCESS) 134044961713Sgirish goto fail; 134144961713Sgirish nxgep->mac.ctrltype = 0x8808; 134244961713Sgirish 134344961713Sgirish SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs); 134444961713Sgirish if (rs != NPI_SUCCESS) 134544961713Sgirish goto fail; 134644961713Sgirish nxgep->mac.pa_size = 0x7; 134744961713Sgirish 134844961713Sgirish if ((rs = npi_bmac_tx_config(handle, INIT, portn, 134944961713Sgirish CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS) 135044961713Sgirish goto fail; 135144961713Sgirish nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX; 135244961713Sgirish } 135344961713Sgirish 135444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>", 135544961713Sgirish portn)); 135644961713Sgirish 135744961713Sgirish return (NXGE_OK); 135844961713Sgirish fail: 135944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 136044961713Sgirish "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", 136144961713Sgirish portn)); 136244961713Sgirish 136344961713Sgirish return (NXGE_ERROR | rs); 136444961713Sgirish } 136544961713Sgirish 136644961713Sgirish /* Initialize the RxMAC sub-block */ 136744961713Sgirish 136844961713Sgirish nxge_status_t 136944961713Sgirish nxge_rx_mac_init(p_nxge_t nxgep) 137044961713Sgirish { 137144961713Sgirish npi_attr_t ap; 137244961713Sgirish uint32_t i; 137344961713Sgirish uint16_t hashtab_e; 137444961713Sgirish p_hash_filter_t hash_filter; 137544961713Sgirish nxge_port_t portt; 137644961713Sgirish uint8_t portn; 137744961713Sgirish npi_handle_t handle; 137844961713Sgirish npi_status_t rs = NPI_SUCCESS; 137944961713Sgirish uint16_t *addr16p; 138044961713Sgirish uint16_t addr0, addr1, addr2; 138144961713Sgirish xmac_rx_config_t xconfig; 138244961713Sgirish bmac_rx_config_t bconfig; 138344961713Sgirish 138444961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 138544961713Sgirish 138644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n", 138744961713Sgirish portn)); 138844961713Sgirish handle = nxgep->npi_handle; 138944961713Sgirish portt = nxgep->mac.porttype; 139044961713Sgirish 139144961713Sgirish addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet; 139244961713Sgirish addr0 = ntohs(addr16p[2]); 139344961713Sgirish addr1 = ntohs(addr16p[1]); 139444961713Sgirish addr2 = ntohs(addr16p[0]); 139544961713Sgirish SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2, 139644961713Sgirish rs); 139744961713Sgirish 139844961713Sgirish if (rs != NPI_SUCCESS) 139944961713Sgirish goto fail; 140044961713Sgirish SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs); 140144961713Sgirish if (rs != NPI_SUCCESS) 140244961713Sgirish goto fail; 140344961713Sgirish SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs); 140444961713Sgirish if (rs != NPI_SUCCESS) 140544961713Sgirish goto fail; 140644961713Sgirish 140744961713Sgirish /* 140844961713Sgirish * Load the multicast hash filter bits. 140944961713Sgirish */ 141044961713Sgirish hash_filter = nxgep->hash_filter; 141144961713Sgirish for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) { 141244961713Sgirish if (hash_filter != NULL) { 141344961713Sgirish hashtab_e = (uint16_t)hash_filter->hash_filter_regs[ 141444961713Sgirish (NMCFILTER_REGS - 1) - i]; 141544961713Sgirish } else { 141644961713Sgirish hashtab_e = 0; 141744961713Sgirish } 141844961713Sgirish 141944961713Sgirish if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i, 142044961713Sgirish (uint16_t *)&hashtab_e)) != NPI_SUCCESS) 142144961713Sgirish goto fail; 142244961713Sgirish } 142344961713Sgirish 142444961713Sgirish if (portt == PORT_TYPE_XMAC) { 142544961713Sgirish if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn, 142644961713Sgirish 0)) != NPI_SUCCESS) 142744961713Sgirish goto fail; 142844961713Sgirish nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS; 142944961713Sgirish 143044961713Sgirish (void) nxge_fflp_init_hostinfo(nxgep); 143144961713Sgirish 143244961713Sgirish xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK | 1433a3c5bd6dSspeer CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK & 1434a3c5bd6dSspeer ~CFG_XMAC_RX_STRIP_CRC; 143544961713Sgirish 143644961713Sgirish if (nxgep->filter.all_phys_cnt != 0) 143744961713Sgirish xconfig |= CFG_XMAC_RX_PROMISCUOUS; 143844961713Sgirish 143944961713Sgirish if (nxgep->filter.all_multicast_cnt != 0) 144044961713Sgirish xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP; 144144961713Sgirish 144244961713Sgirish xconfig |= CFG_XMAC_RX_HASH_FILTER; 144344961713Sgirish 144444961713Sgirish if ((rs = npi_xmac_rx_config(handle, INIT, portn, 144544961713Sgirish xconfig)) != NPI_SUCCESS) 144644961713Sgirish goto fail; 144744961713Sgirish nxgep->mac.rx_config = xconfig; 144844961713Sgirish 144944961713Sgirish /* Comparison of mac unique address is always enabled on XMAC */ 145044961713Sgirish 145144961713Sgirish if ((rs = npi_xmac_zap_rx_counters(handle, portn)) 145244961713Sgirish != NPI_SUCCESS) 145344961713Sgirish goto fail; 145444961713Sgirish } else { 145544961713Sgirish (void) nxge_fflp_init_hostinfo(nxgep); 145644961713Sgirish 145744961713Sgirish if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn, 145844961713Sgirish 0) != NPI_SUCCESS) 145944961713Sgirish goto fail; 146044961713Sgirish nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS; 146144961713Sgirish 1462a3c5bd6dSspeer bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX & 1463a3c5bd6dSspeer ~CFG_BMAC_RX_STRIP_CRC; 146444961713Sgirish 146544961713Sgirish if (nxgep->filter.all_phys_cnt != 0) 146644961713Sgirish bconfig |= CFG_BMAC_RX_PROMISCUOUS; 146744961713Sgirish 146844961713Sgirish if (nxgep->filter.all_multicast_cnt != 0) 146944961713Sgirish bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP; 147044961713Sgirish 147144961713Sgirish bconfig |= CFG_BMAC_RX_HASH_FILTER; 147244961713Sgirish if ((rs = npi_bmac_rx_config(handle, INIT, portn, 147344961713Sgirish bconfig)) != NPI_SUCCESS) 147444961713Sgirish goto fail; 147544961713Sgirish nxgep->mac.rx_config = bconfig; 147644961713Sgirish 147744961713Sgirish /* Always enable comparison of mac unique address */ 147844961713Sgirish if ((rs = npi_mac_altaddr_enable(handle, portn, 0)) 147944961713Sgirish != NPI_SUCCESS) 148044961713Sgirish goto fail; 148144961713Sgirish } 148244961713Sgirish 148344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n", 148444961713Sgirish portn)); 148544961713Sgirish 148644961713Sgirish return (NXGE_OK); 148744961713Sgirish 148844961713Sgirish fail: 148944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 149044961713Sgirish "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", 149144961713Sgirish portn)); 149244961713Sgirish 149344961713Sgirish return (NXGE_ERROR | rs); 149444961713Sgirish } 149544961713Sgirish 149644961713Sgirish /* Enable TXMAC */ 149744961713Sgirish 149844961713Sgirish nxge_status_t 149944961713Sgirish nxge_tx_mac_enable(p_nxge_t nxgep) 150044961713Sgirish { 150144961713Sgirish npi_handle_t handle; 150244961713Sgirish npi_status_t rs = NPI_SUCCESS; 150344961713Sgirish nxge_status_t status = NXGE_OK; 150444961713Sgirish 150544961713Sgirish handle = nxgep->npi_handle; 150644961713Sgirish 150744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>", 150844961713Sgirish nxgep->mac.portnum)); 150944961713Sgirish 151044961713Sgirish if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK) 151144961713Sgirish goto fail; 151244961713Sgirish 151344961713Sgirish /* based on speed */ 151444961713Sgirish nxgep->msg_min = ETHERMIN; 151544961713Sgirish 151644961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 151744961713Sgirish if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 151844961713Sgirish CFG_XMAC_TX)) != NPI_SUCCESS) 151944961713Sgirish goto fail; 152044961713Sgirish } else { 152144961713Sgirish if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum, 152244961713Sgirish CFG_BMAC_TX)) != NPI_SUCCESS) 152344961713Sgirish goto fail; 152444961713Sgirish } 152544961713Sgirish 152644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>", 152744961713Sgirish nxgep->mac.portnum)); 152844961713Sgirish 152944961713Sgirish return (NXGE_OK); 153044961713Sgirish fail: 153144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 153244961713Sgirish "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC", 153344961713Sgirish nxgep->mac.portnum)); 153444961713Sgirish if (rs != NPI_SUCCESS) 153544961713Sgirish return (NXGE_ERROR | rs); 153644961713Sgirish else 153744961713Sgirish return (status); 153844961713Sgirish } 153944961713Sgirish 154044961713Sgirish /* Disable TXMAC */ 154144961713Sgirish 154244961713Sgirish nxge_status_t 154344961713Sgirish nxge_tx_mac_disable(p_nxge_t nxgep) 154444961713Sgirish { 154544961713Sgirish npi_handle_t handle; 154644961713Sgirish npi_status_t rs = NPI_SUCCESS; 154744961713Sgirish 154844961713Sgirish handle = nxgep->npi_handle; 154944961713Sgirish 155044961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>", 155144961713Sgirish nxgep->mac.portnum)); 155244961713Sgirish 155344961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 155444961713Sgirish if ((rs = npi_xmac_tx_config(handle, DISABLE, 155544961713Sgirish nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS) 155644961713Sgirish goto fail; 155744961713Sgirish } else { 155844961713Sgirish if ((rs = npi_bmac_tx_config(handle, DISABLE, 155944961713Sgirish nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS) 156044961713Sgirish goto fail; 156144961713Sgirish } 156244961713Sgirish 156344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>", 156444961713Sgirish nxgep->mac.portnum)); 156544961713Sgirish return (NXGE_OK); 156644961713Sgirish fail: 156744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 156844961713Sgirish "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC", 156944961713Sgirish nxgep->mac.portnum)); 157044961713Sgirish return (NXGE_ERROR | rs); 157144961713Sgirish } 157244961713Sgirish 157344961713Sgirish /* Enable RXMAC */ 157444961713Sgirish 157544961713Sgirish nxge_status_t 157644961713Sgirish nxge_rx_mac_enable(p_nxge_t nxgep) 157744961713Sgirish { 157844961713Sgirish npi_handle_t handle; 157944961713Sgirish uint8_t portn; 158044961713Sgirish npi_status_t rs = NPI_SUCCESS; 158144961713Sgirish nxge_status_t status = NXGE_OK; 158244961713Sgirish 158344961713Sgirish handle = nxgep->npi_handle; 158444961713Sgirish portn = nxgep->mac.portnum; 158544961713Sgirish 158644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>", 158744961713Sgirish portn)); 158844961713Sgirish 158944961713Sgirish if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 159044961713Sgirish goto fail; 159144961713Sgirish 159244961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 159344961713Sgirish if ((rs = npi_xmac_rx_config(handle, ENABLE, portn, 159444961713Sgirish CFG_XMAC_RX)) != NPI_SUCCESS) 159544961713Sgirish goto fail; 159644961713Sgirish } else { 159744961713Sgirish if ((rs = npi_bmac_rx_config(handle, ENABLE, portn, 159844961713Sgirish CFG_BMAC_RX)) != NPI_SUCCESS) 159944961713Sgirish goto fail; 160044961713Sgirish } 160144961713Sgirish 160244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>", 160344961713Sgirish portn)); 160444961713Sgirish 160544961713Sgirish return (NXGE_OK); 160644961713Sgirish fail: 160744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 160844961713Sgirish "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", 160944961713Sgirish portn)); 161044961713Sgirish 161144961713Sgirish if (rs != NPI_SUCCESS) 161244961713Sgirish return (NXGE_ERROR | rs); 161344961713Sgirish else 161444961713Sgirish return (status); 161544961713Sgirish } 161644961713Sgirish 161744961713Sgirish /* Disable RXMAC */ 161844961713Sgirish 161944961713Sgirish nxge_status_t 162044961713Sgirish nxge_rx_mac_disable(p_nxge_t nxgep) 162144961713Sgirish { 162244961713Sgirish npi_handle_t handle; 162344961713Sgirish uint8_t portn; 162444961713Sgirish npi_status_t rs = NPI_SUCCESS; 162544961713Sgirish 162644961713Sgirish handle = nxgep->npi_handle; 162744961713Sgirish portn = nxgep->mac.portnum; 162844961713Sgirish 162944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>", 163044961713Sgirish portn)); 163144961713Sgirish 163244961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 163344961713Sgirish if ((rs = npi_xmac_rx_config(handle, DISABLE, portn, 163444961713Sgirish CFG_XMAC_RX)) != NPI_SUCCESS) 163544961713Sgirish goto fail; 163644961713Sgirish } else { 163744961713Sgirish if ((rs = npi_bmac_rx_config(handle, DISABLE, portn, 163844961713Sgirish CFG_BMAC_RX)) != NPI_SUCCESS) 163944961713Sgirish goto fail; 164044961713Sgirish } 164144961713Sgirish 164244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>", 164344961713Sgirish portn)); 164444961713Sgirish return (NXGE_OK); 164544961713Sgirish fail: 164644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 164744961713Sgirish "nxgep_rx_mac_disable: ", 164844961713Sgirish "Failed to disable port<%d> RxMAC", 164944961713Sgirish portn)); 165044961713Sgirish 165144961713Sgirish return (NXGE_ERROR | rs); 165244961713Sgirish } 165344961713Sgirish 165444961713Sgirish /* Reset TXMAC */ 165544961713Sgirish 165644961713Sgirish nxge_status_t 165744961713Sgirish nxge_tx_mac_reset(p_nxge_t nxgep) 165844961713Sgirish { 165944961713Sgirish npi_handle_t handle; 166044961713Sgirish uint8_t portn; 166144961713Sgirish npi_status_t rs = NPI_SUCCESS; 166244961713Sgirish 166344961713Sgirish handle = nxgep->npi_handle; 166444961713Sgirish portn = nxgep->mac.portnum; 166544961713Sgirish 166644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>", 166744961713Sgirish portn)); 166844961713Sgirish 166944961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 167044961713Sgirish if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL)) 167144961713Sgirish != NPI_SUCCESS) 167244961713Sgirish goto fail; 167344961713Sgirish } else { 167444961713Sgirish if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET)) 167544961713Sgirish != NPI_SUCCESS) 167644961713Sgirish goto fail; 167744961713Sgirish } 167844961713Sgirish 167944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>", 168044961713Sgirish portn)); 168144961713Sgirish 168244961713Sgirish return (NXGE_OK); 168344961713Sgirish fail: 168444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 168544961713Sgirish "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", 168644961713Sgirish portn)); 168744961713Sgirish 168844961713Sgirish return (NXGE_ERROR | rs); 168944961713Sgirish } 169044961713Sgirish 169144961713Sgirish /* Reset RXMAC */ 169244961713Sgirish 169344961713Sgirish nxge_status_t 169444961713Sgirish nxge_rx_mac_reset(p_nxge_t nxgep) 169544961713Sgirish { 169644961713Sgirish npi_handle_t handle; 169744961713Sgirish uint8_t portn; 169844961713Sgirish npi_status_t rs = NPI_SUCCESS; 169944961713Sgirish 170044961713Sgirish handle = nxgep->npi_handle; 170144961713Sgirish portn = nxgep->mac.portnum; 170244961713Sgirish 170344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>", 170444961713Sgirish portn)); 170544961713Sgirish 170644961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 170744961713Sgirish if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL)) 170844961713Sgirish != NPI_SUCCESS) 170944961713Sgirish goto fail; 171044961713Sgirish } else { 171144961713Sgirish if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET)) 171244961713Sgirish != NPI_SUCCESS) 171344961713Sgirish goto fail; 171444961713Sgirish } 171544961713Sgirish 171644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>", 171744961713Sgirish portn)); 171844961713Sgirish 1719*59ac0c16Sdavemq return (NXGE_OK); 1720*59ac0c16Sdavemq fail: 1721*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1722*59ac0c16Sdavemq "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", 1723*59ac0c16Sdavemq portn)); 1724*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1725*59ac0c16Sdavemq } 1726*59ac0c16Sdavemq 1727*59ac0c16Sdavemq /* 10G fiber link interrupt start routine */ 1728*59ac0c16Sdavemq 1729*59ac0c16Sdavemq static nxge_status_t 1730*59ac0c16Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep) 1731*59ac0c16Sdavemq { 1732*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 1733*59ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 1734*59ac0c16Sdavemq 1735*59ac0c16Sdavemq rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn); 1736*59ac0c16Sdavemq 1737*59ac0c16Sdavemq if (rs != NPI_SUCCESS) 1738*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1739*59ac0c16Sdavemq else 1740*59ac0c16Sdavemq return (NXGE_OK); 1741*59ac0c16Sdavemq } 1742*59ac0c16Sdavemq 1743*59ac0c16Sdavemq /* 10G fiber link interrupt stop routine */ 1744*59ac0c16Sdavemq 1745*59ac0c16Sdavemq static nxge_status_t 1746*59ac0c16Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep) 1747*59ac0c16Sdavemq { 1748*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 1749*59ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 1750*59ac0c16Sdavemq 1751*59ac0c16Sdavemq rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn); 1752*59ac0c16Sdavemq 1753*59ac0c16Sdavemq if (rs != NPI_SUCCESS) 1754*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1755*59ac0c16Sdavemq else 1756*59ac0c16Sdavemq return (NXGE_OK); 1757*59ac0c16Sdavemq } 1758*59ac0c16Sdavemq 1759*59ac0c16Sdavemq /* 1G fiber link interrupt start routine */ 1760*59ac0c16Sdavemq 1761*59ac0c16Sdavemq static nxge_status_t 1762*59ac0c16Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep) 1763*59ac0c16Sdavemq { 1764*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 1765*59ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 1766*59ac0c16Sdavemq 1767*59ac0c16Sdavemq rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn); 1768*59ac0c16Sdavemq if (rs != NPI_SUCCESS) 1769*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1770*59ac0c16Sdavemq else 1771*59ac0c16Sdavemq return (NXGE_OK); 1772*59ac0c16Sdavemq } 1773*59ac0c16Sdavemq 1774*59ac0c16Sdavemq /* 1G fiber link interrupt stop routine */ 1775*59ac0c16Sdavemq 1776*59ac0c16Sdavemq static nxge_status_t 1777*59ac0c16Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep) 1778*59ac0c16Sdavemq { 1779*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 1780*59ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 1781*59ac0c16Sdavemq 1782*59ac0c16Sdavemq rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn); 1783*59ac0c16Sdavemq 1784*59ac0c16Sdavemq if (rs != NPI_SUCCESS) 1785*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1786*59ac0c16Sdavemq else 1787*59ac0c16Sdavemq return (NXGE_OK); 1788*59ac0c16Sdavemq } 1789*59ac0c16Sdavemq 1790*59ac0c16Sdavemq /* 1G copper link interrupt start routine */ 1791*59ac0c16Sdavemq 1792*59ac0c16Sdavemq static nxge_status_t 1793*59ac0c16Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep) 1794*59ac0c16Sdavemq { 1795*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 1796*59ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 1797*59ac0c16Sdavemq 1798*59ac0c16Sdavemq rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn, 1799*59ac0c16Sdavemq MII_BMSR, BMSR_LSTATUS); 1800*59ac0c16Sdavemq 1801*59ac0c16Sdavemq if (rs != NPI_SUCCESS) 1802*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1803*59ac0c16Sdavemq else 1804*59ac0c16Sdavemq return (NXGE_OK); 180544961713Sgirish } 180644961713Sgirish 1807*59ac0c16Sdavemq /* 1G copper link interrupt stop routine */ 1808*59ac0c16Sdavemq 1809*59ac0c16Sdavemq static nxge_status_t 1810*59ac0c16Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep) 1811*59ac0c16Sdavemq { 1812*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 1813*59ac0c16Sdavemq uint8_t portn = nxgep->mac.portnum; 1814*59ac0c16Sdavemq 1815*59ac0c16Sdavemq rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn); 1816*59ac0c16Sdavemq 1817*59ac0c16Sdavemq if (rs != NPI_SUCCESS) 1818*59ac0c16Sdavemq return (NXGE_ERROR | rs); 1819*59ac0c16Sdavemq else 1820*59ac0c16Sdavemq return (NXGE_OK); 1821*59ac0c16Sdavemq } 182244961713Sgirish 1823*59ac0c16Sdavemq /* Enable/Disable Link Status change interrupt */ 182444961713Sgirish 182544961713Sgirish nxge_status_t 182644961713Sgirish nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable) 182744961713Sgirish { 1828*59ac0c16Sdavemq uint8_t portn; 1829*59ac0c16Sdavemq nxge_status_t status = NXGE_OK; 183044961713Sgirish 183144961713Sgirish portn = nxgep->mac.portnum; 183244961713Sgirish 183344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn)); 1834*59ac0c16Sdavemq if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start) 1835*59ac0c16Sdavemq return (NXGE_OK); 183644961713Sgirish 1837*59ac0c16Sdavemq if (enable == LINK_INTR_START) 1838*59ac0c16Sdavemq status = nxgep->xcvr.link_intr_start(nxgep); 1839*59ac0c16Sdavemq else if (enable == LINK_INTR_STOP) 1840*59ac0c16Sdavemq status = nxgep->xcvr.link_intr_stop(nxgep); 1841*59ac0c16Sdavemq if (status != NXGE_OK) 1842*59ac0c16Sdavemq goto fail; 184344961713Sgirish 184444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn)); 184544961713Sgirish 184644961713Sgirish return (NXGE_OK); 184744961713Sgirish fail: 184844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 184944961713Sgirish "nxge_link_intr: Failed to set port<%d> mif intr mode", 185044961713Sgirish portn)); 185144961713Sgirish 1852*59ac0c16Sdavemq return (status); 185344961713Sgirish } 185444961713Sgirish 185544961713Sgirish /* Initialize 1G Fiber / Copper transceiver using Clause 22 */ 185644961713Sgirish 185744961713Sgirish nxge_status_t 185844961713Sgirish nxge_mii_xcvr_init(p_nxge_t nxgep) 185944961713Sgirish { 186044961713Sgirish p_nxge_param_t param_arr; 186144961713Sgirish p_nxge_stats_t statsp; 186244961713Sgirish uint8_t xcvr_portn; 186344961713Sgirish p_mii_regs_t mii_regs; 186444961713Sgirish mii_bmcr_t bmcr; 186544961713Sgirish mii_bmsr_t bmsr; 186644961713Sgirish mii_anar_t anar; 186744961713Sgirish mii_gcr_t gcr; 186844961713Sgirish mii_esr_t esr; 186944961713Sgirish mii_aux_ctl_t bcm5464r_aux; 187044961713Sgirish int status = NXGE_OK; 187144961713Sgirish 187244961713Sgirish uint_t delay; 187344961713Sgirish 187444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init")); 187544961713Sgirish 187644961713Sgirish param_arr = nxgep->param_arr; 187744961713Sgirish statsp = nxgep->statsp; 187844961713Sgirish xcvr_portn = statsp->mac_stats.xcvr_portn; 187944961713Sgirish 188044961713Sgirish mii_regs = NULL; 188144961713Sgirish 188244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 188344961713Sgirish "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value)); 188444961713Sgirish 188544961713Sgirish /* 188644961713Sgirish * Reset the transceiver. 188744961713Sgirish */ 188844961713Sgirish delay = 0; 188944961713Sgirish bmcr.value = 0; 189044961713Sgirish bmcr.bits.reset = 1; 189144961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 189244961713Sgirish (uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK) 189344961713Sgirish goto fail; 189444961713Sgirish do { 189544961713Sgirish drv_usecwait(500); 189644961713Sgirish if ((status = nxge_mii_read(nxgep, xcvr_portn, 189744961713Sgirish (uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value)) 189844961713Sgirish != NXGE_OK) 189944961713Sgirish goto fail; 190044961713Sgirish delay++; 190144961713Sgirish } while ((bmcr.bits.reset) && (delay < 1000)); 190244961713Sgirish if (delay == 1000) { 190344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed.")); 190444961713Sgirish goto fail; 190544961713Sgirish } 190644961713Sgirish 190744961713Sgirish if ((status = nxge_mii_read(nxgep, xcvr_portn, 190844961713Sgirish (uint8_t)(uint64_t)(&mii_regs->bmsr), 190944961713Sgirish &bmsr.value)) != NXGE_OK) 191044961713Sgirish goto fail; 191144961713Sgirish 191244961713Sgirish param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able; 191344961713Sgirish param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4; 191444961713Sgirish param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx; 191544961713Sgirish param_arr[param_anar_100hdx].value = 0; 191644961713Sgirish param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx; 191744961713Sgirish param_arr[param_anar_10hdx].value = 0; 191844961713Sgirish 191944961713Sgirish /* 192058324dfcSspeer * Initialize the xcvr statistics. 192144961713Sgirish */ 192244961713Sgirish statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able; 192344961713Sgirish statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4; 192444961713Sgirish statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx; 192544961713Sgirish statsp->mac_stats.cap_100hdx = 0; 192644961713Sgirish statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx; 192744961713Sgirish statsp->mac_stats.cap_10hdx = 0; 192844961713Sgirish statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value; 192944961713Sgirish statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value; 193044961713Sgirish 193144961713Sgirish /* 193244961713Sgirish * Initialise the xcvr advertised capability statistics. 193344961713Sgirish */ 193444961713Sgirish statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value; 193544961713Sgirish statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 193644961713Sgirish statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 193744961713Sgirish statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value; 193844961713Sgirish statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value; 193944961713Sgirish statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value; 194044961713Sgirish statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value; 194144961713Sgirish statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value; 194244961713Sgirish statsp->mac_stats.adv_cap_asmpause = 194344961713Sgirish param_arr[param_anar_asmpause].value; 194444961713Sgirish statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value; 194544961713Sgirish 194644961713Sgirish 194744961713Sgirish /* 194844961713Sgirish * Check for extended status just in case we're 194944961713Sgirish * running a Gigibit phy. 195044961713Sgirish */ 195144961713Sgirish if (bmsr.bits.extend_status) { 195244961713Sgirish if ((status = nxge_mii_read(nxgep, xcvr_portn, 195344961713Sgirish (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) 195444961713Sgirish != NXGE_OK) 195544961713Sgirish goto fail; 195644961713Sgirish param_arr[param_anar_1000fdx].value &= 195744961713Sgirish esr.bits.link_1000fdx; 195844961713Sgirish param_arr[param_anar_1000hdx].value = 0; 195944961713Sgirish 196044961713Sgirish statsp->mac_stats.cap_1000fdx = 196144961713Sgirish (esr.bits.link_1000Xfdx || 196244961713Sgirish esr.bits.link_1000fdx); 196344961713Sgirish statsp->mac_stats.cap_1000hdx = 0; 196444961713Sgirish } else { 196544961713Sgirish param_arr[param_anar_1000fdx].value = 0; 196644961713Sgirish param_arr[param_anar_1000hdx].value = 0; 196744961713Sgirish } 196844961713Sgirish 196944961713Sgirish /* 197044961713Sgirish * Initialize 1G Statistics once the capability is established. 197144961713Sgirish */ 197244961713Sgirish statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value; 197344961713Sgirish statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value; 197444961713Sgirish 197544961713Sgirish /* 197644961713Sgirish * Initialise the link statistics. 197744961713Sgirish */ 197844961713Sgirish statsp->mac_stats.link_T4 = 0; 197944961713Sgirish statsp->mac_stats.link_asmpause = 0; 198044961713Sgirish statsp->mac_stats.link_pause = 0; 198144961713Sgirish statsp->mac_stats.link_speed = 0; 198244961713Sgirish statsp->mac_stats.link_duplex = 0; 198344961713Sgirish statsp->mac_stats.link_up = 0; 198444961713Sgirish 198544961713Sgirish /* 198644961713Sgirish * Switch off Auto-negotiation, 100M and full duplex. 198744961713Sgirish */ 198844961713Sgirish bmcr.value = 0; 198944961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 199044961713Sgirish (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK) 199144961713Sgirish goto fail; 199244961713Sgirish 199344961713Sgirish if ((statsp->port_stats.lb_mode == nxge_lb_phy) || 199444961713Sgirish (statsp->port_stats.lb_mode == nxge_lb_phy1000)) { 199544961713Sgirish bmcr.bits.loopback = 1; 199644961713Sgirish bmcr.bits.enable_autoneg = 0; 199744961713Sgirish if (statsp->port_stats.lb_mode == nxge_lb_phy1000) 199844961713Sgirish bmcr.bits.speed_1000_sel = 1; 199944961713Sgirish bmcr.bits.duplex_mode = 1; 200044961713Sgirish param_arr[param_autoneg].value = 0; 200144961713Sgirish } else { 200244961713Sgirish bmcr.bits.loopback = 0; 200344961713Sgirish } 200444961713Sgirish 200544961713Sgirish if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 200644961713Sgirish (statsp->port_stats.lb_mode == nxge_lb_ext100) || 200744961713Sgirish (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 200844961713Sgirish param_arr[param_autoneg].value = 0; 200944961713Sgirish bcm5464r_aux.value = 0; 201044961713Sgirish bcm5464r_aux.bits.ext_lb = 1; 201144961713Sgirish bcm5464r_aux.bits.write_1 = 1; 201244961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 201344961713Sgirish BCM5464R_AUX_CTL, bcm5464r_aux.value)) 201444961713Sgirish != NXGE_OK) 201544961713Sgirish goto fail; 201644961713Sgirish } 201744961713Sgirish 201844961713Sgirish if (param_arr[param_autoneg].value) { 201944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 202044961713Sgirish "Restarting Auto-negotiation.")); 202144961713Sgirish /* 202244961713Sgirish * Setup our Auto-negotiation advertisement register. 202344961713Sgirish */ 202444961713Sgirish anar.value = 0; 202544961713Sgirish anar.bits.selector = 1; 202644961713Sgirish anar.bits.cap_100T4 = param_arr[param_anar_100T4].value; 202744961713Sgirish anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value; 202844961713Sgirish anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value; 202944961713Sgirish anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value; 203044961713Sgirish anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value; 203144961713Sgirish anar.bits.cap_asmpause = 0; 203244961713Sgirish anar.bits.cap_pause = 0; 203344961713Sgirish if (param_arr[param_anar_1000fdx].value || 203444961713Sgirish param_arr[param_anar_100fdx].value || 203544961713Sgirish param_arr[param_anar_10fdx].value) { 203644961713Sgirish anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause; 203744961713Sgirish anar.bits.cap_pause = statsp->mac_stats.cap_pause; 203844961713Sgirish } 203944961713Sgirish 204044961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 204144961713Sgirish (uint8_t)(uint64_t)(&mii_regs->anar), anar.value)) 204244961713Sgirish != NXGE_OK) 204344961713Sgirish goto fail; 204444961713Sgirish if (bmsr.bits.extend_status) { 204544961713Sgirish gcr.value = 0; 204644961713Sgirish gcr.bits.ms_mode_en = 204744961713Sgirish param_arr[param_master_cfg_enable].value; 204844961713Sgirish gcr.bits.master = 204944961713Sgirish param_arr[param_master_cfg_value].value; 205044961713Sgirish gcr.bits.link_1000fdx = 205144961713Sgirish param_arr[param_anar_1000fdx].value; 205244961713Sgirish gcr.bits.link_1000hdx = 205344961713Sgirish param_arr[param_anar_1000hdx].value; 205444961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 205544961713Sgirish (uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value)) 205644961713Sgirish != NXGE_OK) 205744961713Sgirish goto fail; 205844961713Sgirish } 205944961713Sgirish 206044961713Sgirish bmcr.bits.enable_autoneg = 1; 206144961713Sgirish bmcr.bits.restart_autoneg = 1; 206244961713Sgirish 206344961713Sgirish } else { 206444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode.")); 206544961713Sgirish bmcr.bits.speed_1000_sel = 206644961713Sgirish param_arr[param_anar_1000fdx].value | 206744961713Sgirish param_arr[param_anar_1000hdx].value; 206844961713Sgirish bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) & 206944961713Sgirish (param_arr[param_anar_100fdx].value | 207044961713Sgirish param_arr[param_anar_100hdx].value); 207144961713Sgirish if (bmcr.bits.speed_1000_sel) { 207244961713Sgirish statsp->mac_stats.link_speed = 1000; 207344961713Sgirish gcr.value = 0; 207444961713Sgirish gcr.bits.ms_mode_en = 207544961713Sgirish param_arr[param_master_cfg_enable].value; 207644961713Sgirish gcr.bits.master = 207744961713Sgirish param_arr[param_master_cfg_value].value; 207844961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 207944961713Sgirish (uint8_t)(uint64_t)(&mii_regs->gcr), 208044961713Sgirish gcr.value)) 208144961713Sgirish != NXGE_OK) 208244961713Sgirish goto fail; 208344961713Sgirish if (param_arr[param_anar_1000fdx].value) { 208444961713Sgirish bmcr.bits.duplex_mode = 1; 208544961713Sgirish statsp->mac_stats.link_duplex = 2; 208644961713Sgirish } else 208744961713Sgirish statsp->mac_stats.link_duplex = 1; 208844961713Sgirish } else if (bmcr.bits.speed_sel) { 208944961713Sgirish statsp->mac_stats.link_speed = 100; 209044961713Sgirish if (param_arr[param_anar_100fdx].value) { 209144961713Sgirish bmcr.bits.duplex_mode = 1; 209244961713Sgirish statsp->mac_stats.link_duplex = 2; 209344961713Sgirish } else 209444961713Sgirish statsp->mac_stats.link_duplex = 1; 209544961713Sgirish } else { 209644961713Sgirish statsp->mac_stats.link_speed = 10; 209744961713Sgirish if (param_arr[param_anar_10fdx].value) { 209844961713Sgirish bmcr.bits.duplex_mode = 1; 209944961713Sgirish statsp->mac_stats.link_duplex = 2; 210044961713Sgirish } else 210144961713Sgirish statsp->mac_stats.link_duplex = 1; 210244961713Sgirish } 210344961713Sgirish if (statsp->mac_stats.link_duplex != 1) { 210444961713Sgirish statsp->mac_stats.link_asmpause = 210544961713Sgirish statsp->mac_stats.cap_asmpause; 210644961713Sgirish statsp->mac_stats.link_pause = 210744961713Sgirish statsp->mac_stats.cap_pause; 210844961713Sgirish } 210944961713Sgirish 211044961713Sgirish if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) || 211144961713Sgirish (statsp->port_stats.lb_mode == nxge_lb_ext100) || 211244961713Sgirish (statsp->port_stats.lb_mode == nxge_lb_ext10)) { 211344961713Sgirish if (statsp->port_stats.lb_mode == nxge_lb_ext1000) { 211444961713Sgirish /* BCM5464R 1000mbps external loopback mode */ 211544961713Sgirish gcr.value = 0; 211644961713Sgirish gcr.bits.ms_mode_en = 1; 211744961713Sgirish gcr.bits.master = 1; 211844961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 211944961713Sgirish (uint8_t)(uint64_t)(&mii_regs->gcr), 212044961713Sgirish gcr.value)) 212144961713Sgirish != NXGE_OK) 212244961713Sgirish goto fail; 212344961713Sgirish bmcr.value = 0; 212444961713Sgirish bmcr.bits.speed_1000_sel = 1; 212544961713Sgirish statsp->mac_stats.link_speed = 1000; 212644961713Sgirish } else if (statsp->port_stats.lb_mode 212744961713Sgirish == nxge_lb_ext100) { 212844961713Sgirish /* BCM5464R 100mbps external loopback mode */ 212944961713Sgirish bmcr.value = 0; 213044961713Sgirish bmcr.bits.speed_sel = 1; 213144961713Sgirish bmcr.bits.duplex_mode = 1; 213244961713Sgirish statsp->mac_stats.link_speed = 100; 213344961713Sgirish } else if (statsp->port_stats.lb_mode 213444961713Sgirish == nxge_lb_ext10) { 213544961713Sgirish /* BCM5464R 10mbps external loopback mode */ 213644961713Sgirish bmcr.value = 0; 213744961713Sgirish bmcr.bits.duplex_mode = 1; 213844961713Sgirish statsp->mac_stats.link_speed = 10; 213944961713Sgirish } 214044961713Sgirish } 214144961713Sgirish } 214244961713Sgirish 214344961713Sgirish if ((status = nxge_mii_write(nxgep, xcvr_portn, 214444961713Sgirish (uint8_t)(uint64_t)(&mii_regs->bmcr), 214544961713Sgirish bmcr.value)) != NXGE_OK) 214644961713Sgirish goto fail; 214744961713Sgirish 214844961713Sgirish if ((status = nxge_mii_read(nxgep, xcvr_portn, 214944961713Sgirish (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK) 215044961713Sgirish goto fail; 215144961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value)); 215244961713Sgirish 215344961713Sgirish /* 215444961713Sgirish * Initialize the xcvr status kept in the context structure. 215544961713Sgirish */ 215644961713Sgirish nxgep->soft_bmsr.value = 0; 215744961713Sgirish 215844961713Sgirish if ((status = nxge_mii_read(nxgep, xcvr_portn, 215944961713Sgirish (uint8_t)(uint64_t)(&mii_regs->bmsr), 216044961713Sgirish &nxgep->bmsr.value)) != NXGE_OK) 216144961713Sgirish goto fail; 216244961713Sgirish 216344961713Sgirish statsp->mac_stats.xcvr_inits++; 216444961713Sgirish nxgep->bmsr.value = 0; 216544961713Sgirish 216644961713Sgirish fail: 216744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 216844961713Sgirish "<== nxge_mii_xcvr_init status 0x%x", status)); 216944961713Sgirish return (status); 217044961713Sgirish } 217144961713Sgirish 217244961713Sgirish /* Read from a MII compliant register */ 217344961713Sgirish 217444961713Sgirish nxge_status_t 217544961713Sgirish nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 217644961713Sgirish uint16_t *value) 217744961713Sgirish { 217844961713Sgirish npi_status_t rs = NPI_SUCCESS; 217944961713Sgirish 218044961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>" 218144961713Sgirish "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 218244961713Sgirish 218344961713Sgirish MUTEX_ENTER(&nxge_mii_lock); 218444961713Sgirish 218544961713Sgirish if (nxgep->mac.portmode == PORT_1G_COPPER) { 218644961713Sgirish if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle, 218744961713Sgirish xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 218844961713Sgirish goto fail; 218944961713Sgirish } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 219044961713Sgirish if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle, 219144961713Sgirish xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 219244961713Sgirish goto fail; 219344961713Sgirish } else 219444961713Sgirish goto fail; 219544961713Sgirish 219644961713Sgirish MUTEX_EXIT(&nxge_mii_lock); 219744961713Sgirish 219844961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>" 219944961713Sgirish "xcvr_reg<%d> value=0x%x", 220044961713Sgirish xcvr_portn, xcvr_reg, *value)); 220144961713Sgirish return (NXGE_OK); 220244961713Sgirish fail: 220344961713Sgirish MUTEX_EXIT(&nxge_mii_lock); 220444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 220544961713Sgirish "nxge_mii_read: Failed to read mii on xcvr %d", 220644961713Sgirish xcvr_portn)); 220744961713Sgirish 220844961713Sgirish return (NXGE_ERROR | rs); 220944961713Sgirish } 221044961713Sgirish 221144961713Sgirish /* Write to a MII compliant Register */ 221244961713Sgirish 221344961713Sgirish nxge_status_t 221444961713Sgirish nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg, 221544961713Sgirish uint16_t value) 221644961713Sgirish { 221744961713Sgirish npi_status_t rs = NPI_SUCCESS; 221844961713Sgirish 221944961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>" 222044961713Sgirish "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, 222144961713Sgirish value)); 222244961713Sgirish 222344961713Sgirish MUTEX_ENTER(&nxge_mii_lock); 222444961713Sgirish 222544961713Sgirish if (nxgep->mac.portmode == PORT_1G_COPPER) { 222644961713Sgirish if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle, 222744961713Sgirish xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 222844961713Sgirish goto fail; 222944961713Sgirish } else if (nxgep->mac.portmode == PORT_1G_FIBER) { 223044961713Sgirish if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle, 223144961713Sgirish xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS) 223244961713Sgirish goto fail; 223344961713Sgirish } else 223444961713Sgirish goto fail; 223544961713Sgirish 223644961713Sgirish MUTEX_EXIT(&nxge_mii_lock); 223744961713Sgirish 223844961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>" 223944961713Sgirish "xcvr_reg<%d>", xcvr_portn, xcvr_reg)); 224044961713Sgirish return (NXGE_OK); 224144961713Sgirish fail: 224244961713Sgirish MUTEX_EXIT(&nxge_mii_lock); 224344961713Sgirish 224444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 224544961713Sgirish "nxge_mii_write: Failed to write mii on xcvr %d", 224644961713Sgirish xcvr_portn)); 224744961713Sgirish 224844961713Sgirish return (NXGE_ERROR | rs); 224944961713Sgirish } 225044961713Sgirish 225144961713Sgirish /* Perform read from Clause45 serdes / transceiver device */ 225244961713Sgirish 225344961713Sgirish nxge_status_t 225444961713Sgirish nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 225544961713Sgirish uint16_t xcvr_reg, uint16_t *value) 225644961713Sgirish { 225744961713Sgirish npi_status_t rs = NPI_SUCCESS; 225844961713Sgirish 225944961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>", 226044961713Sgirish xcvr_portn)); 226144961713Sgirish 226244961713Sgirish MUTEX_ENTER(&nxge_mdio_lock); 226344961713Sgirish 226444961713Sgirish if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle, 226544961713Sgirish xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 226644961713Sgirish goto fail; 226744961713Sgirish 226844961713Sgirish MUTEX_EXIT(&nxge_mdio_lock); 226944961713Sgirish 227044961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>", 227144961713Sgirish xcvr_portn)); 227244961713Sgirish return (NXGE_OK); 227344961713Sgirish fail: 227444961713Sgirish MUTEX_EXIT(&nxge_mdio_lock); 227544961713Sgirish 227644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 227744961713Sgirish "nxge_mdio_read: Failed to read mdio on xcvr %d", 227844961713Sgirish xcvr_portn)); 227944961713Sgirish 228044961713Sgirish return (NXGE_ERROR | rs); 228144961713Sgirish } 228244961713Sgirish 228344961713Sgirish /* Perform write to Clause45 serdes / transceiver device */ 228444961713Sgirish 228544961713Sgirish nxge_status_t 228644961713Sgirish nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device, 228744961713Sgirish uint16_t xcvr_reg, uint16_t value) 228844961713Sgirish { 228944961713Sgirish npi_status_t rs = NPI_SUCCESS; 229044961713Sgirish 229144961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>", 229244961713Sgirish xcvr_portn)); 229344961713Sgirish 229444961713Sgirish MUTEX_ENTER(&nxge_mdio_lock); 229544961713Sgirish 229644961713Sgirish if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle, 229744961713Sgirish xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS) 229844961713Sgirish goto fail; 229944961713Sgirish 230044961713Sgirish MUTEX_EXIT(&nxge_mdio_lock); 230144961713Sgirish 230244961713Sgirish NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>", 230344961713Sgirish xcvr_portn)); 230444961713Sgirish return (NXGE_OK); 230544961713Sgirish fail: 230644961713Sgirish MUTEX_EXIT(&nxge_mdio_lock); 230744961713Sgirish 230844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 230944961713Sgirish "nxge_mdio_write: Failed to write mdio on xcvr %d", 231044961713Sgirish xcvr_portn)); 231144961713Sgirish 231244961713Sgirish return (NXGE_ERROR | rs); 231344961713Sgirish } 231444961713Sgirish 231544961713Sgirish 231644961713Sgirish /* Check MII to see if there is any link status change */ 231744961713Sgirish 231844961713Sgirish nxge_status_t 2319a3c5bd6dSspeer nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints, 2320a3c5bd6dSspeer nxge_link_state_t *link_up) 232144961713Sgirish { 232244961713Sgirish p_nxge_param_t param_arr; 232344961713Sgirish p_nxge_stats_t statsp; 232444961713Sgirish p_mii_regs_t mii_regs; 232544961713Sgirish p_mii_bmsr_t soft_bmsr; 232644961713Sgirish mii_anar_t anar; 232744961713Sgirish mii_anlpar_t anlpar; 232844961713Sgirish mii_anar_t an_common; 232944961713Sgirish mii_aner_t aner; 233044961713Sgirish mii_gsr_t gsr; 233144961713Sgirish nxge_status_t status = NXGE_OK; 233244961713Sgirish 233344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check")); 233444961713Sgirish 233544961713Sgirish mii_regs = NULL; 233644961713Sgirish param_arr = nxgep->param_arr; 233744961713Sgirish statsp = nxgep->statsp; 233844961713Sgirish soft_bmsr = &nxgep->soft_bmsr; 2339a3c5bd6dSspeer *link_up = LINK_NO_CHANGE; 234044961713Sgirish 234144961713Sgirish if (bmsr_ints.bits.link_status) { 234244961713Sgirish if (bmsr.bits.link_status) { 234344961713Sgirish soft_bmsr->bits.link_status = 1; 234444961713Sgirish } else { 234544961713Sgirish statsp->mac_stats.link_up = 0; 234644961713Sgirish soft_bmsr->bits.link_status = 0; 234744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 234844961713Sgirish "Link down cable problem")); 2349a3c5bd6dSspeer *link_up = LINK_IS_DOWN; 235044961713Sgirish } 235144961713Sgirish } 235244961713Sgirish 235344961713Sgirish if (param_arr[param_autoneg].value) { 235444961713Sgirish if (bmsr_ints.bits.auto_neg_complete) { 235544961713Sgirish if (bmsr.bits.auto_neg_complete) 235644961713Sgirish soft_bmsr->bits.auto_neg_complete = 1; 235744961713Sgirish else 235844961713Sgirish soft_bmsr->bits.auto_neg_complete = 0; 235944961713Sgirish } 236044961713Sgirish if (soft_bmsr->bits.link_status == 0) { 236144961713Sgirish statsp->mac_stats.link_T4 = 0; 236244961713Sgirish statsp->mac_stats.link_speed = 0; 236344961713Sgirish statsp->mac_stats.link_duplex = 0; 236444961713Sgirish statsp->mac_stats.link_asmpause = 0; 236544961713Sgirish statsp->mac_stats.link_pause = 0; 236644961713Sgirish statsp->mac_stats.lp_cap_autoneg = 0; 236744961713Sgirish statsp->mac_stats.lp_cap_100T4 = 0; 236844961713Sgirish statsp->mac_stats.lp_cap_1000fdx = 0; 236944961713Sgirish statsp->mac_stats.lp_cap_1000hdx = 0; 237044961713Sgirish statsp->mac_stats.lp_cap_100fdx = 0; 237144961713Sgirish statsp->mac_stats.lp_cap_100hdx = 0; 237244961713Sgirish statsp->mac_stats.lp_cap_10fdx = 0; 237344961713Sgirish statsp->mac_stats.lp_cap_10hdx = 0; 237444961713Sgirish statsp->mac_stats.lp_cap_10gfdx = 0; 237544961713Sgirish statsp->mac_stats.lp_cap_10ghdx = 0; 237644961713Sgirish statsp->mac_stats.lp_cap_asmpause = 0; 237744961713Sgirish statsp->mac_stats.lp_cap_pause = 0; 237844961713Sgirish } 237944961713Sgirish } else 238044961713Sgirish soft_bmsr->bits.auto_neg_complete = 1; 238144961713Sgirish 238244961713Sgirish if ((bmsr_ints.bits.link_status || 238344961713Sgirish bmsr_ints.bits.auto_neg_complete) && 238444961713Sgirish soft_bmsr->bits.link_status && 238544961713Sgirish soft_bmsr->bits.auto_neg_complete) { 238644961713Sgirish statsp->mac_stats.link_up = 1; 238744961713Sgirish if (param_arr[param_autoneg].value) { 238844961713Sgirish if ((status = nxge_mii_read(nxgep, 238944961713Sgirish statsp->mac_stats.xcvr_portn, 239044961713Sgirish (uint8_t)(uint64_t)(&mii_regs->anar), 239144961713Sgirish &anar.value)) != NXGE_OK) 239244961713Sgirish goto fail; 239344961713Sgirish if ((status = nxge_mii_read(nxgep, 239444961713Sgirish statsp->mac_stats.xcvr_portn, 239544961713Sgirish (uint8_t)(uint64_t)(&mii_regs->anlpar), 239644961713Sgirish &anlpar.value)) != NXGE_OK) 239744961713Sgirish goto fail; 239844961713Sgirish if ((status = nxge_mii_read(nxgep, 239944961713Sgirish statsp->mac_stats.xcvr_portn, 240044961713Sgirish (uint8_t)(uint64_t)(&mii_regs->aner), 240144961713Sgirish &aner.value)) != NXGE_OK) 240244961713Sgirish goto fail; 240344961713Sgirish statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able; 240444961713Sgirish statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4; 240544961713Sgirish statsp->mac_stats.lp_cap_100fdx = 240644961713Sgirish anlpar.bits.cap_100fdx; 240744961713Sgirish statsp->mac_stats.lp_cap_100hdx = 240844961713Sgirish anlpar.bits.cap_100hdx; 240944961713Sgirish statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx; 241044961713Sgirish statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx; 241144961713Sgirish statsp->mac_stats.lp_cap_asmpause = 241244961713Sgirish anlpar.bits.cap_asmpause; 241344961713Sgirish statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause; 241444961713Sgirish an_common.value = anar.value & anlpar.value; 241544961713Sgirish if (param_arr[param_anar_1000fdx].value || 241644961713Sgirish param_arr[param_anar_1000hdx].value) { 241744961713Sgirish if ((status = nxge_mii_read(nxgep, 241844961713Sgirish statsp->mac_stats.xcvr_portn, 241944961713Sgirish (uint8_t)(uint64_t)(&mii_regs->gsr), 242044961713Sgirish &gsr.value)) 242144961713Sgirish != NXGE_OK) 242244961713Sgirish goto fail; 242344961713Sgirish statsp->mac_stats.lp_cap_1000fdx = 242444961713Sgirish gsr.bits.link_1000fdx; 242544961713Sgirish statsp->mac_stats.lp_cap_1000hdx = 242644961713Sgirish gsr.bits.link_1000hdx; 242744961713Sgirish if (param_arr[param_anar_1000fdx].value && 242844961713Sgirish gsr.bits.link_1000fdx) { 242944961713Sgirish statsp->mac_stats.link_speed = 1000; 243044961713Sgirish statsp->mac_stats.link_duplex = 2; 243144961713Sgirish } else if ( 243244961713Sgirish param_arr[param_anar_1000hdx].value && 243344961713Sgirish gsr.bits.link_1000hdx) { 243444961713Sgirish statsp->mac_stats.link_speed = 1000; 243544961713Sgirish statsp->mac_stats.link_duplex = 1; 243644961713Sgirish } 243744961713Sgirish } 243844961713Sgirish if ((an_common.value != 0) && 243944961713Sgirish !(statsp->mac_stats.link_speed)) { 244044961713Sgirish if (an_common.bits.cap_100T4) { 244144961713Sgirish statsp->mac_stats.link_T4 = 1; 244244961713Sgirish statsp->mac_stats.link_speed = 100; 244344961713Sgirish statsp->mac_stats.link_duplex = 1; 244444961713Sgirish } else if (an_common.bits.cap_100fdx) { 244544961713Sgirish statsp->mac_stats.link_speed = 100; 244644961713Sgirish statsp->mac_stats.link_duplex = 2; 244744961713Sgirish } else if (an_common.bits.cap_100hdx) { 244844961713Sgirish statsp->mac_stats.link_speed = 100; 244944961713Sgirish statsp->mac_stats.link_duplex = 1; 245044961713Sgirish } else if (an_common.bits.cap_10fdx) { 245144961713Sgirish statsp->mac_stats.link_speed = 10; 245244961713Sgirish statsp->mac_stats.link_duplex = 2; 245344961713Sgirish } else if (an_common.bits.cap_10hdx) { 245444961713Sgirish statsp->mac_stats.link_speed = 10; 245544961713Sgirish statsp->mac_stats.link_duplex = 1; 245644961713Sgirish } else { 245744961713Sgirish goto fail; 245844961713Sgirish } 245944961713Sgirish } 246044961713Sgirish if (statsp->mac_stats.link_duplex != 1) { 246144961713Sgirish statsp->mac_stats.link_asmpause = 246244961713Sgirish an_common.bits.cap_asmpause; 246344961713Sgirish if (statsp->mac_stats.link_asmpause) 246444961713Sgirish if ((statsp->mac_stats.cap_pause == 0) && 246544961713Sgirish (statsp->mac_stats.lp_cap_pause 246644961713Sgirish == 1)) 246744961713Sgirish statsp->mac_stats.link_pause 246844961713Sgirish = 0; 246944961713Sgirish else 247044961713Sgirish statsp->mac_stats.link_pause 247144961713Sgirish = 1; 247244961713Sgirish else 247344961713Sgirish statsp->mac_stats.link_pause = 247444961713Sgirish an_common.bits.cap_pause; 247544961713Sgirish } 247644961713Sgirish } 2477a3c5bd6dSspeer *link_up = LINK_IS_UP; 2478a3c5bd6dSspeer } 2479a3c5bd6dSspeer 2480a3c5bd6dSspeer if (nxgep->link_notify) { 2481a3c5bd6dSspeer *link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP : 2482a3c5bd6dSspeer LINK_IS_DOWN); 2483a3c5bd6dSspeer nxgep->link_notify = B_FALSE; 248444961713Sgirish } 248544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check")); 248644961713Sgirish return (NXGE_OK); 248744961713Sgirish fail: 248844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 248944961713Sgirish "nxge_mii_check: Unable to check MII")); 249044961713Sgirish return (status); 249144961713Sgirish } 249244961713Sgirish 249344961713Sgirish /* Add a multicast address entry into the HW hash table */ 249444961713Sgirish 249544961713Sgirish nxge_status_t 249644961713Sgirish nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 249744961713Sgirish { 249844961713Sgirish uint32_t mchash; 249944961713Sgirish p_hash_filter_t hash_filter; 250044961713Sgirish uint16_t hash_bit; 250144961713Sgirish boolean_t rx_init = B_FALSE; 250244961713Sgirish uint_t j; 250344961713Sgirish nxge_status_t status = NXGE_OK; 250444961713Sgirish 250544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr")); 250644961713Sgirish 250744961713Sgirish RW_ENTER_WRITER(&nxgep->filter_lock); 250844961713Sgirish mchash = crc32_mchash(addrp); 250944961713Sgirish if (nxgep->hash_filter == NULL) { 251044961713Sgirish NXGE_DEBUG_MSG((NULL, STR_CTL, 251144961713Sgirish "Allocating hash filter storage.")); 251244961713Sgirish nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t), 251344961713Sgirish KM_SLEEP); 251444961713Sgirish } 251544961713Sgirish hash_filter = nxgep->hash_filter; 251644961713Sgirish j = mchash / HASH_REG_WIDTH; 251744961713Sgirish hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 251844961713Sgirish hash_filter->hash_filter_regs[j] |= hash_bit; 251944961713Sgirish hash_filter->hash_bit_ref_cnt[mchash]++; 252044961713Sgirish if (hash_filter->hash_bit_ref_cnt[mchash] == 1) { 252144961713Sgirish hash_filter->hash_ref_cnt++; 252244961713Sgirish rx_init = B_TRUE; 252344961713Sgirish } 252444961713Sgirish if (rx_init) { 252544961713Sgirish if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 252644961713Sgirish goto fail; 252744961713Sgirish if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 252844961713Sgirish goto fail; 252944961713Sgirish } 253044961713Sgirish 253144961713Sgirish RW_EXIT(&nxgep->filter_lock); 253244961713Sgirish 253344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr")); 253444961713Sgirish 253544961713Sgirish return (NXGE_OK); 253644961713Sgirish fail: 253744961713Sgirish RW_EXIT(&nxgep->filter_lock); 253844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: " 253944961713Sgirish "Unable to add multicast address")); 254044961713Sgirish return (status); 254144961713Sgirish } 254244961713Sgirish 254344961713Sgirish /* Remove a multicast address entry from the HW hash table */ 254444961713Sgirish 254544961713Sgirish nxge_status_t 254644961713Sgirish nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp) 254744961713Sgirish { 254844961713Sgirish uint32_t mchash; 254944961713Sgirish p_hash_filter_t hash_filter; 255044961713Sgirish uint16_t hash_bit; 255144961713Sgirish boolean_t rx_init = B_FALSE; 255244961713Sgirish uint_t j; 255344961713Sgirish nxge_status_t status = NXGE_OK; 255444961713Sgirish 255544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr")); 255644961713Sgirish RW_ENTER_WRITER(&nxgep->filter_lock); 255744961713Sgirish mchash = crc32_mchash(addrp); 255844961713Sgirish if (nxgep->hash_filter == NULL) { 255944961713Sgirish NXGE_DEBUG_MSG((NULL, STR_CTL, 256044961713Sgirish "Hash filter already de_allocated.")); 256144961713Sgirish RW_EXIT(&nxgep->filter_lock); 256244961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 256344961713Sgirish return (NXGE_OK); 256444961713Sgirish } 256544961713Sgirish hash_filter = nxgep->hash_filter; 256644961713Sgirish hash_filter->hash_bit_ref_cnt[mchash]--; 256744961713Sgirish if (hash_filter->hash_bit_ref_cnt[mchash] == 0) { 256844961713Sgirish j = mchash / HASH_REG_WIDTH; 256944961713Sgirish hash_bit = (1 << (mchash % HASH_REG_WIDTH)); 257044961713Sgirish hash_filter->hash_filter_regs[j] &= ~hash_bit; 257144961713Sgirish hash_filter->hash_ref_cnt--; 257244961713Sgirish rx_init = B_TRUE; 257344961713Sgirish } 257444961713Sgirish if (hash_filter->hash_ref_cnt == 0) { 257544961713Sgirish NXGE_DEBUG_MSG((NULL, STR_CTL, 257644961713Sgirish "De-allocating hash filter storage.")); 257744961713Sgirish KMEM_FREE(hash_filter, sizeof (hash_filter_t)); 257844961713Sgirish nxgep->hash_filter = NULL; 257944961713Sgirish } 258044961713Sgirish 258144961713Sgirish if (rx_init) { 258244961713Sgirish if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 258344961713Sgirish goto fail; 258444961713Sgirish if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 258544961713Sgirish goto fail; 258644961713Sgirish } 258744961713Sgirish RW_EXIT(&nxgep->filter_lock); 258844961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr")); 258944961713Sgirish 259044961713Sgirish return (NXGE_OK); 259144961713Sgirish fail: 259244961713Sgirish RW_EXIT(&nxgep->filter_lock); 259344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: " 259444961713Sgirish "Unable to remove multicast address")); 259544961713Sgirish 259644961713Sgirish return (status); 259744961713Sgirish } 259844961713Sgirish 259944961713Sgirish /* Set MAC address into MAC address HW registers */ 260044961713Sgirish 260144961713Sgirish nxge_status_t 260244961713Sgirish nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp) 260344961713Sgirish { 260444961713Sgirish nxge_status_t status = NXGE_OK; 260544961713Sgirish 260644961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr")); 260744961713Sgirish 260844961713Sgirish MUTEX_ENTER(&nxgep->ouraddr_lock); 260944961713Sgirish /* 261044961713Sgirish * Exit if the address is same as ouraddr or multicast or broadcast 261144961713Sgirish */ 261244961713Sgirish if (((addrp->ether_addr_octet[0] & 01) == 1) || 261344961713Sgirish (ether_cmp(addrp, ðerbroadcastaddr) == 0) || 261444961713Sgirish (ether_cmp(addrp, &nxgep->ouraddr) == 0)) { 261544961713Sgirish goto nxge_set_mac_addr_exit; 261644961713Sgirish } 261744961713Sgirish nxgep->ouraddr = *addrp; 261844961713Sgirish /* 261944961713Sgirish * Set new interface local address and re-init device. 262044961713Sgirish * This is destructive to any other streams attached 262144961713Sgirish * to this device. 262244961713Sgirish */ 262344961713Sgirish RW_ENTER_WRITER(&nxgep->filter_lock); 262444961713Sgirish if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) 262544961713Sgirish goto fail; 262644961713Sgirish if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) 262744961713Sgirish goto fail; 262844961713Sgirish 262944961713Sgirish RW_EXIT(&nxgep->filter_lock); 263044961713Sgirish MUTEX_EXIT(&nxgep->ouraddr_lock); 263144961713Sgirish goto nxge_set_mac_addr_end; 263244961713Sgirish nxge_set_mac_addr_exit: 263344961713Sgirish MUTEX_EXIT(&nxgep->ouraddr_lock); 263444961713Sgirish nxge_set_mac_addr_end: 263544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr")); 263644961713Sgirish 263744961713Sgirish return (NXGE_OK); 263844961713Sgirish fail: 263944961713Sgirish MUTEX_EXIT(&nxgep->ouraddr_lock); 264044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: " 264144961713Sgirish "Unable to set mac address")); 264244961713Sgirish return (status); 264344961713Sgirish } 264444961713Sgirish 264598ecde52Stm static 264698ecde52Stm check_link_state_t 264798ecde52Stm nxge_check_link_stop( 264898ecde52Stm nxge_t *nxge) 264998ecde52Stm { 265098ecde52Stm /* If the poll has been cancelled, return STOP. */ 265198ecde52Stm MUTEX_ENTER(&nxge->poll_lock); 265298ecde52Stm if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) { 265398ecde52Stm nxge->poll_state = LINK_MONITOR_STOP; 265498ecde52Stm nxge->nxge_link_poll_timerid = 0; 265598ecde52Stm cv_broadcast(&nxge->poll_cv); 265698ecde52Stm MUTEX_EXIT(&nxge->poll_lock); 265798ecde52Stm 265898ecde52Stm NXGE_DEBUG_MSG((nxge, MAC_CTL, 265998ecde52Stm "nxge_check_%s_link(port<%d>) stopped.", 266098ecde52Stm nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii", 266198ecde52Stm nxge->mac.portnum)); 266298ecde52Stm return (CHECK_LINK_STOP); 266398ecde52Stm } 266498ecde52Stm MUTEX_EXIT(&nxge->poll_lock); 266598ecde52Stm 266698ecde52Stm return (CHECK_LINK_RESCHEDULE); 266798ecde52Stm } 266898ecde52Stm 266944961713Sgirish /* Check status of MII (MIF or PCS) link */ 267044961713Sgirish 2671*59ac0c16Sdavemq static nxge_status_t 267244961713Sgirish nxge_check_mii_link(p_nxge_t nxgep) 267344961713Sgirish { 267444961713Sgirish mii_bmsr_t bmsr_ints, bmsr_data; 267544961713Sgirish mii_anlpar_t anlpar; 267644961713Sgirish mii_gsr_t gsr; 267744961713Sgirish p_mii_regs_t mii_regs; 267844961713Sgirish nxge_status_t status = NXGE_OK; 267944961713Sgirish uint8_t portn; 2680a3c5bd6dSspeer nxge_link_state_t link_up; 268144961713Sgirish 268298ecde52Stm if (nxgep->nxge_magic != NXGE_MAGIC) 268398ecde52Stm return (NXGE_ERROR); 268498ecde52Stm 268598ecde52Stm if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 268698ecde52Stm return (NXGE_OK); 268798ecde52Stm 268844961713Sgirish portn = nxgep->mac.portnum; 268944961713Sgirish 269044961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>", 269198ecde52Stm portn)); 269244961713Sgirish 269344961713Sgirish mii_regs = NULL; 269444961713Sgirish 269544961713Sgirish RW_ENTER_WRITER(&nxgep->filter_lock); 269644961713Sgirish 269744961713Sgirish if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10) 269844961713Sgirish goto nxge_check_mii_link_exit; 269944961713Sgirish 270044961713Sgirish if ((status = nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn, 270144961713Sgirish (uint8_t)(uint64_t)(&mii_regs->bmsr), 270244961713Sgirish &bmsr_data.value)) != NXGE_OK) 270344961713Sgirish goto fail; 270444961713Sgirish 270544961713Sgirish if (nxgep->param_arr[param_autoneg].value) { 270644961713Sgirish if ((status = nxge_mii_read(nxgep, 270744961713Sgirish nxgep->statsp->mac_stats.xcvr_portn, 270844961713Sgirish (uint8_t)(uint64_t)(&mii_regs->gsr), 270944961713Sgirish &gsr.value)) != NXGE_OK) 271044961713Sgirish goto fail; 271144961713Sgirish if ((status = nxge_mii_read(nxgep, 271244961713Sgirish nxgep->statsp->mac_stats.xcvr_portn, 271344961713Sgirish (uint8_t)(uint64_t)(&mii_regs->anlpar), 271444961713Sgirish &anlpar.value)) != NXGE_OK) 271544961713Sgirish goto fail; 271644961713Sgirish if (nxgep->statsp->mac_stats.link_up && 271744961713Sgirish ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^ 271844961713Sgirish gsr.bits.link_1000fdx) || 271944961713Sgirish (nxgep->statsp->mac_stats.lp_cap_1000hdx ^ 272044961713Sgirish gsr.bits.link_1000hdx) || 272144961713Sgirish (nxgep->statsp->mac_stats.lp_cap_100T4 ^ 272244961713Sgirish anlpar.bits.cap_100T4) || 272344961713Sgirish (nxgep->statsp->mac_stats.lp_cap_100fdx ^ 272444961713Sgirish anlpar.bits.cap_100fdx) || 272544961713Sgirish (nxgep->statsp->mac_stats.lp_cap_100hdx ^ 272644961713Sgirish anlpar.bits.cap_100hdx) || 272744961713Sgirish (nxgep->statsp->mac_stats.lp_cap_10fdx ^ 272844961713Sgirish anlpar.bits.cap_10fdx) || 272944961713Sgirish (nxgep->statsp->mac_stats.lp_cap_10hdx ^ 273044961713Sgirish anlpar.bits.cap_10hdx))) { 273144961713Sgirish bmsr_data.bits.link_status = 0; 273244961713Sgirish } 273344961713Sgirish } 273444961713Sgirish 273544961713Sgirish /* Workaround for link down issue */ 273644961713Sgirish if (bmsr_data.value == 0) { 2737*59ac0c16Sdavemq cmn_err(CE_NOTE, "nxge%d: !LINK DEBUG: Read zero bmsr\n", 2738*59ac0c16Sdavemq nxgep->instance); 273944961713Sgirish goto nxge_check_mii_link_exit; 274044961713Sgirish } 274144961713Sgirish 274244961713Sgirish bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value; 274344961713Sgirish nxgep->bmsr.value = bmsr_data.value; 2744a3c5bd6dSspeer if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, &link_up)) 274598ecde52Stm != NXGE_OK) 274644961713Sgirish goto fail; 274744961713Sgirish 274844961713Sgirish nxge_check_mii_link_exit: 274944961713Sgirish RW_EXIT(&nxgep->filter_lock); 2750a3c5bd6dSspeer if (link_up == LINK_IS_UP) { 2751a3c5bd6dSspeer nxge_link_is_up(nxgep); 2752a3c5bd6dSspeer } else if (link_up == LINK_IS_DOWN) { 2753a3c5bd6dSspeer nxge_link_is_down(nxgep); 2754a3c5bd6dSspeer } 275544961713Sgirish 275644961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 275744961713Sgirish 275844961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>", 275998ecde52Stm portn)); 276044961713Sgirish return (NXGE_OK); 276144961713Sgirish 276244961713Sgirish fail: 276344961713Sgirish RW_EXIT(&nxgep->filter_lock); 276444961713Sgirish 276544961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 276644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 276798ecde52Stm "nxge_check_mii_link: Failed to check link port<%d>", 276898ecde52Stm portn)); 276944961713Sgirish return (status); 277044961713Sgirish } 277144961713Sgirish 277244961713Sgirish 277344961713Sgirish /*ARGSUSED*/ 2774*59ac0c16Sdavemq static nxge_status_t 277544961713Sgirish nxge_check_10g_link(p_nxge_t nxgep) 277644961713Sgirish { 277744961713Sgirish uint8_t portn; 277814ea4bb7Ssd 277944961713Sgirish nxge_status_t status = NXGE_OK; 278044961713Sgirish boolean_t link_up; 278144961713Sgirish 278298ecde52Stm if (nxgep->nxge_magic != NXGE_MAGIC) 278398ecde52Stm return (NXGE_ERROR); 278498ecde52Stm 278598ecde52Stm if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 278698ecde52Stm return (NXGE_OK); 278798ecde52Stm 278844961713Sgirish portn = nxgep->mac.portnum; 278944961713Sgirish 279044961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>", 279198ecde52Stm portn)); 279244961713Sgirish 279344961713Sgirish status = nxge_check_bcm8704_link(nxgep, &link_up); 279444961713Sgirish 279544961713Sgirish if (status != NXGE_OK) 279644961713Sgirish goto fail; 279744961713Sgirish 279844961713Sgirish if (link_up) { 2799a3c5bd6dSspeer if (nxgep->link_notify || 2800a3c5bd6dSspeer nxgep->statsp->mac_stats.link_up == 0) { 280144961713Sgirish if (nxge_10g_link_led_on(nxgep) != NXGE_OK) 280244961713Sgirish goto fail; 280344961713Sgirish nxgep->statsp->mac_stats.link_up = 1; 280444961713Sgirish nxgep->statsp->mac_stats.link_speed = 10000; 280544961713Sgirish nxgep->statsp->mac_stats.link_duplex = 2; 280644961713Sgirish 280744961713Sgirish nxge_link_is_up(nxgep); 2808a3c5bd6dSspeer nxgep->link_notify = B_FALSE; 280944961713Sgirish } 281044961713Sgirish } else { 2811a3c5bd6dSspeer if (nxgep->link_notify || 2812a3c5bd6dSspeer nxgep->statsp->mac_stats.link_up == 1) { 281344961713Sgirish if (nxge_10g_link_led_off(nxgep) != NXGE_OK) 281444961713Sgirish goto fail; 281544961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 2816*59ac0c16Sdavemq "Link down cable problem")); 281744961713Sgirish nxgep->statsp->mac_stats.link_up = 0; 281844961713Sgirish nxgep->statsp->mac_stats.link_speed = 0; 281944961713Sgirish nxgep->statsp->mac_stats.link_duplex = 0; 282044961713Sgirish 282144961713Sgirish nxge_link_is_down(nxgep); 2822a3c5bd6dSspeer nxgep->link_notify = B_FALSE; 282344961713Sgirish } 282444961713Sgirish } 282544961713Sgirish 282644961713Sgirish (void) nxge_link_monitor(nxgep, LINK_MONITOR_START); 282744961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>", 282898ecde52Stm portn)); 282944961713Sgirish return (NXGE_OK); 283044961713Sgirish 283144961713Sgirish fail: 283298ecde52Stm (void) nxge_check_link_stop(nxgep); 283398ecde52Stm 283444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 283598ecde52Stm "nxge_check_10g_link: Failed to check link port<%d>", 283698ecde52Stm portn)); 283744961713Sgirish return (status); 283844961713Sgirish } 283944961713Sgirish 284044961713Sgirish 284144961713Sgirish /* Declare link down */ 284244961713Sgirish 284344961713Sgirish void 284444961713Sgirish nxge_link_is_down(p_nxge_t nxgep) 284544961713Sgirish { 2846*59ac0c16Sdavemq p_nxge_stats_t statsp; 2847*59ac0c16Sdavemq char link_stat_msg[64]; 2848*59ac0c16Sdavemq 284944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down")); 285044961713Sgirish 2851*59ac0c16Sdavemq statsp = nxgep->statsp; 2852*59ac0c16Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down", 2853*59ac0c16Sdavemq statsp->mac_stats.xcvr_portn); 2854*59ac0c16Sdavemq 2855*59ac0c16Sdavemq if (nxge_no_msg == B_FALSE) { 2856*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 2857*59ac0c16Sdavemq } 2858*59ac0c16Sdavemq 285944961713Sgirish mac_link_update(nxgep->mach, LINK_STATE_DOWN); 286044961713Sgirish 286144961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down")); 286244961713Sgirish } 286344961713Sgirish 286444961713Sgirish /* Declare link up */ 286544961713Sgirish 286644961713Sgirish void 286744961713Sgirish nxge_link_is_up(p_nxge_t nxgep) 286844961713Sgirish { 2869*59ac0c16Sdavemq p_nxge_stats_t statsp; 2870*59ac0c16Sdavemq char link_stat_msg[64]; 287144961713Sgirish uint32_t val; 287244961713Sgirish 287344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up")); 287444961713Sgirish 2875*59ac0c16Sdavemq statsp = nxgep->statsp; 2876*59ac0c16Sdavemq (void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ", 2877*59ac0c16Sdavemq statsp->mac_stats.xcvr_portn, 2878*59ac0c16Sdavemq statsp->mac_stats.link_speed); 2879*59ac0c16Sdavemq 2880*59ac0c16Sdavemq if (statsp->mac_stats.link_T4) 2881*59ac0c16Sdavemq (void) strcat(link_stat_msg, "T4"); 2882*59ac0c16Sdavemq else if (statsp->mac_stats.link_duplex == 2) 2883*59ac0c16Sdavemq (void) strcat(link_stat_msg, "full duplex"); 2884*59ac0c16Sdavemq else 2885*59ac0c16Sdavemq (void) strcat(link_stat_msg, "half duplex"); 2886*59ac0c16Sdavemq 288744961713Sgirish (void) nxge_xif_init(nxgep); 288844961713Sgirish 288944961713Sgirish /* Clean up symbol errors incurred during link transition */ 289044961713Sgirish if (nxgep->mac.portmode == PORT_10G_FIBER) { 289144961713Sgirish (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 289244961713Sgirish XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 289344961713Sgirish (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 289444961713Sgirish XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 289544961713Sgirish } 289644961713Sgirish 2897*59ac0c16Sdavemq if (nxge_no_msg == B_FALSE) { 2898*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg)); 2899*59ac0c16Sdavemq } 2900*59ac0c16Sdavemq 290144961713Sgirish mac_link_update(nxgep->mach, LINK_STATE_UP); 290244961713Sgirish 290344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up")); 290444961713Sgirish } 290544961713Sgirish 290644961713Sgirish /* 290744961713Sgirish * Calculate the bit in the multicast address filter 290844961713Sgirish * that selects the given * address. 290944961713Sgirish * Note: For GEM, the last 8-bits are used. 291044961713Sgirish */ 291144961713Sgirish uint32_t 291244961713Sgirish crc32_mchash(p_ether_addr_t addr) 291344961713Sgirish { 291444961713Sgirish uint8_t *cp; 291544961713Sgirish uint32_t crc; 291644961713Sgirish uint32_t c; 291744961713Sgirish int byte; 291844961713Sgirish int bit; 291944961713Sgirish 292044961713Sgirish cp = (uint8_t *)addr; 292144961713Sgirish crc = (uint32_t)0xffffffff; 292244961713Sgirish for (byte = 0; byte < 6; byte++) { 292344961713Sgirish c = (uint32_t)cp[byte]; 292444961713Sgirish for (bit = 0; bit < 8; bit++) { 292544961713Sgirish if ((c & 0x1) ^ (crc & 0x1)) 292644961713Sgirish crc = (crc >> 1)^0xedb88320; 292744961713Sgirish else 292844961713Sgirish crc = (crc >> 1); 292944961713Sgirish c >>= 1; 293044961713Sgirish } 293144961713Sgirish } 293244961713Sgirish return ((~crc) >> (32 - HASH_BITS)); 293344961713Sgirish } 293444961713Sgirish 293544961713Sgirish /* Reset serdes */ 293644961713Sgirish 293744961713Sgirish nxge_status_t 293844961713Sgirish nxge_serdes_reset(p_nxge_t nxgep) 293944961713Sgirish { 294044961713Sgirish npi_handle_t handle; 294144961713Sgirish 294244961713Sgirish handle = nxgep->npi_handle; 294344961713Sgirish 294444961713Sgirish ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1); 294544961713Sgirish drv_usecwait(500); 294644961713Sgirish ESR_REG_WR(handle, ESR_CONFIG_REG, 0); 294744961713Sgirish 294844961713Sgirish return (NXGE_OK); 294944961713Sgirish } 295044961713Sgirish 295144961713Sgirish /* Monitor link status using interrupt or polling */ 295244961713Sgirish 295344961713Sgirish nxge_status_t 295444961713Sgirish nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable) 295544961713Sgirish { 295644961713Sgirish nxge_status_t status = NXGE_OK; 295744961713Sgirish 295844961713Sgirish /* 295998ecde52Stm * Return immediately if this is an imaginary XMAC port. 296098ecde52Stm * (At least, we don't have 4-port XMAC cards yet.) 296144961713Sgirish */ 296244961713Sgirish if ((nxgep->mac.portmode == PORT_10G_FIBER) && (nxgep->mac.portnum > 1)) 296344961713Sgirish return (NXGE_OK); 296444961713Sgirish 296544961713Sgirish if (nxgep->statsp == NULL) { 296644961713Sgirish /* stats has not been allocated. */ 296744961713Sgirish return (NXGE_OK); 296844961713Sgirish } 296944961713Sgirish /* Don't check link if we're not in internal loopback mode */ 297044961713Sgirish if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal) 297144961713Sgirish return (NXGE_OK); 297244961713Sgirish 297344961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 297498ecde52Stm "==> nxge_link_monitor port<%d> enable=%d", 297598ecde52Stm nxgep->mac.portnum, enable)); 297644961713Sgirish if (enable == LINK_MONITOR_START) { 297744961713Sgirish if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 297844961713Sgirish if ((status = nxge_link_intr(nxgep, LINK_INTR_START)) 297998ecde52Stm != NXGE_OK) 298044961713Sgirish goto fail; 298144961713Sgirish } else { 298298ecde52Stm timeout_id_t timerid; 298398ecde52Stm 298498ecde52Stm if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) 298598ecde52Stm return (NXGE_OK); 298698ecde52Stm 2987*59ac0c16Sdavemq if (nxgep->xcvr.check_link) { 2988*59ac0c16Sdavemq timerid = timeout( 2989*59ac0c16Sdavemq (fptrv_t)(nxgep->xcvr.check_link), 299098ecde52Stm nxgep, 299198ecde52Stm drv_usectohz(LINK_MONITOR_PERIOD)); 2992*59ac0c16Sdavemq MUTEX_ENTER(&nxgep->poll_lock); 2993*59ac0c16Sdavemq nxgep->nxge_link_poll_timerid = timerid; 2994*59ac0c16Sdavemq MUTEX_EXIT(&nxgep->poll_lock); 2995*59ac0c16Sdavemq } else { 299698ecde52Stm return (NXGE_ERROR); 299744961713Sgirish } 299844961713Sgirish } 299944961713Sgirish } else { 300044961713Sgirish if (nxgep->mac.linkchkmode == LINKCHK_INTR) { 300144961713Sgirish if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP)) 300298ecde52Stm != NXGE_OK) 300344961713Sgirish goto fail; 300444961713Sgirish } else { 300598ecde52Stm clock_t rv; 300698ecde52Stm 300798ecde52Stm MUTEX_ENTER(&nxgep->poll_lock); 300898ecde52Stm 300998ecde52Stm /* If <timerid> == 0, the link monitor has */ 301098ecde52Stm /* never been started, or just now stopped. */ 301198ecde52Stm if (nxgep->nxge_link_poll_timerid == 0) { 301298ecde52Stm MUTEX_EXIT(&nxgep->poll_lock); 301398ecde52Stm return (NXGE_OK); 301498ecde52Stm } 301598ecde52Stm 301698ecde52Stm nxgep->poll_state = LINK_MONITOR_STOPPING; 301798ecde52Stm rv = cv_timedwait(&nxgep->poll_cv, 301898ecde52Stm &nxgep->poll_lock, 301998ecde52Stm ddi_get_lbolt() + 302098ecde52Stm drv_usectohz(LM_WAIT_MULTIPLIER * 302198ecde52Stm LINK_MONITOR_PERIOD)); 302298ecde52Stm if (rv == -1) { 302398ecde52Stm NXGE_DEBUG_MSG((nxgep, MAC_CTL, 302498ecde52Stm "==> stopping port %d: " 302598ecde52Stm "cv_timedwait(%d) timed out", 302698ecde52Stm nxgep->mac.portnum, nxgep->poll_state)); 302798ecde52Stm nxgep->poll_state = LINK_MONITOR_STOP; 302844961713Sgirish nxgep->nxge_link_poll_timerid = 0; 302944961713Sgirish } 303098ecde52Stm 303198ecde52Stm MUTEX_EXIT(&nxgep->poll_lock); 303244961713Sgirish } 303344961713Sgirish } 303444961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, 303598ecde52Stm "<== nxge_link_monitor port<%d> enable=%d", 303698ecde52Stm nxgep->mac.portnum, enable)); 303744961713Sgirish return (NXGE_OK); 303844961713Sgirish fail: 303944961713Sgirish return (status); 304044961713Sgirish } 304144961713Sgirish 304244961713Sgirish /* Set promiscous mode */ 304344961713Sgirish 304444961713Sgirish nxge_status_t 304544961713Sgirish nxge_set_promisc(p_nxge_t nxgep, boolean_t on) 304644961713Sgirish { 304744961713Sgirish nxge_status_t status = NXGE_OK; 304844961713Sgirish 3049*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on)); 305044961713Sgirish 305144961713Sgirish nxgep->filter.all_phys_cnt = ((on) ? 1 : 0); 305244961713Sgirish 305344961713Sgirish RW_ENTER_WRITER(&nxgep->filter_lock); 305444961713Sgirish 305544961713Sgirish if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) { 305644961713Sgirish goto fail; 305744961713Sgirish } 305844961713Sgirish if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) { 305944961713Sgirish goto fail; 306044961713Sgirish } 306144961713Sgirish 306244961713Sgirish RW_EXIT(&nxgep->filter_lock); 306344961713Sgirish 306444961713Sgirish if (on) 306544961713Sgirish nxgep->statsp->mac_stats.promisc = B_TRUE; 306644961713Sgirish else 306744961713Sgirish nxgep->statsp->mac_stats.promisc = B_FALSE; 306844961713Sgirish 306944961713Sgirish NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc")); 307044961713Sgirish 307144961713Sgirish return (NXGE_OK); 307244961713Sgirish fail: 307344961713Sgirish RW_EXIT(&nxgep->filter_lock); 307444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: " 3075*59ac0c16Sdavemq "Unable to set promisc (%d)", on)); 307644961713Sgirish 307744961713Sgirish return (status); 307844961713Sgirish } 307944961713Sgirish 308044961713Sgirish /*ARGSUSED*/ 308144961713Sgirish uint_t 308244961713Sgirish nxge_mif_intr(void *arg1, void *arg2) 308344961713Sgirish { 308444961713Sgirish #ifdef NXGE_DEBUG 308544961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg2; 308644961713Sgirish #endif 308744961713Sgirish #if NXGE_MIF 308844961713Sgirish p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 308944961713Sgirish uint32_t status; 309044961713Sgirish npi_handle_t handle; 309144961713Sgirish uint8_t portn; 309244961713Sgirish p_nxge_stats_t statsp; 309344961713Sgirish #endif 309444961713Sgirish 309544961713Sgirish #ifdef NXGE_MIF 309644961713Sgirish if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 309744961713Sgirish nxgep = ldvp->nxgep; 309844961713Sgirish } 309944961713Sgirish nxgep = ldvp->nxgep; 310044961713Sgirish #endif 310144961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr")); 310244961713Sgirish 310344961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 310444961713Sgirish return (DDI_INTR_CLAIMED); 310544961713Sgirish 310644961713Sgirish mif_intr_fail: 310744961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr")); 310844961713Sgirish return (DDI_INTR_UNCLAIMED); 310944961713Sgirish } 311044961713Sgirish 311144961713Sgirish /*ARGSUSED*/ 311244961713Sgirish uint_t 311344961713Sgirish nxge_mac_intr(void *arg1, void *arg2) 311444961713Sgirish { 311544961713Sgirish p_nxge_t nxgep = (p_nxge_t)arg2; 311644961713Sgirish p_nxge_ldv_t ldvp = (p_nxge_ldv_t)arg1; 311744961713Sgirish p_nxge_ldg_t ldgp; 311844961713Sgirish uint32_t status; 311944961713Sgirish npi_handle_t handle; 312044961713Sgirish uint8_t portn; 312144961713Sgirish p_nxge_stats_t statsp; 312244961713Sgirish npi_status_t rs = NPI_SUCCESS; 312344961713Sgirish 312444961713Sgirish if (arg2 == NULL || (void *)ldvp->nxgep != arg2) { 312544961713Sgirish nxgep = ldvp->nxgep; 312644961713Sgirish } 312744961713Sgirish 312844961713Sgirish ldgp = ldvp->ldgp; 312944961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: " 3130*59ac0c16Sdavemq "group %d", ldgp->ldg)); 313144961713Sgirish 313244961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 313344961713Sgirish /* 313444961713Sgirish * This interrupt handler is for a specific 313544961713Sgirish * mac port. 313644961713Sgirish */ 313744961713Sgirish statsp = (p_nxge_stats_t)nxgep->statsp; 313844961713Sgirish portn = nxgep->mac.portnum; 313944961713Sgirish 314044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, 3141*59ac0c16Sdavemq "==> nxge_mac_intr: reading mac stats: port<%d>", portn)); 314244961713Sgirish 314344961713Sgirish if (nxgep->mac.porttype == PORT_TYPE_XMAC) { 314444961713Sgirish rs = npi_xmac_tx_get_istatus(handle, portn, 314544961713Sgirish (xmac_tx_iconfig_t *)&status); 314644961713Sgirish if (rs != NPI_SUCCESS) 314744961713Sgirish goto npi_fail; 314844961713Sgirish if (status & ICFG_XMAC_TX_ALL) { 314944961713Sgirish if (status & ICFG_XMAC_TX_UNDERRUN) { 315044961713Sgirish statsp->xmac_stats.tx_underflow_err++; 315144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 315244961713Sgirish NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 315344961713Sgirish } 315444961713Sgirish if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) { 315544961713Sgirish statsp->xmac_stats.tx_maxpktsize_err++; 315644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 315744961713Sgirish NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 315844961713Sgirish } 315944961713Sgirish if (status & ICFG_XMAC_TX_OVERFLOW) { 316044961713Sgirish statsp->xmac_stats.tx_overflow_err++; 316144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 316244961713Sgirish NXGE_FM_EREPORT_TXMAC_OVERFLOW); 316344961713Sgirish } 316444961713Sgirish if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) { 316544961713Sgirish statsp->xmac_stats.tx_fifo_xfr_err++; 316644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 316744961713Sgirish NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR); 316844961713Sgirish } 316944961713Sgirish if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) { 317044961713Sgirish statsp->xmac_stats.tx_byte_cnt += 317144961713Sgirish XTXMAC_BYTE_CNT_MASK; 317244961713Sgirish } 317344961713Sgirish if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) { 317444961713Sgirish statsp->xmac_stats.tx_frame_cnt += 317544961713Sgirish XTXMAC_FRM_CNT_MASK; 317644961713Sgirish } 317744961713Sgirish } 317844961713Sgirish 317944961713Sgirish rs = npi_xmac_rx_get_istatus(handle, portn, 318044961713Sgirish (xmac_rx_iconfig_t *)&status); 318144961713Sgirish if (rs != NPI_SUCCESS) 318244961713Sgirish goto npi_fail; 318344961713Sgirish if (status & ICFG_XMAC_RX_ALL) { 318444961713Sgirish if (status & ICFG_XMAC_RX_OVERFLOW) 318544961713Sgirish statsp->xmac_stats.rx_overflow_err++; 318644961713Sgirish if (status & ICFG_XMAC_RX_UNDERFLOW) { 318744961713Sgirish statsp->xmac_stats.rx_underflow_err++; 318844961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 318944961713Sgirish NXGE_FM_EREPORT_RXMAC_UNDERFLOW); 319044961713Sgirish } 319144961713Sgirish if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) { 319244961713Sgirish statsp->xmac_stats.rx_crc_err_cnt += 319344961713Sgirish XRXMAC_CRC_ER_CNT_MASK; 319444961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 319544961713Sgirish NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 319644961713Sgirish } 319744961713Sgirish if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) { 319844961713Sgirish statsp->xmac_stats.rx_len_err_cnt += 319944961713Sgirish MAC_LEN_ER_CNT_MASK; 320044961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 320144961713Sgirish NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 320244961713Sgirish } 320344961713Sgirish if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) { 320444961713Sgirish statsp->xmac_stats.rx_viol_err_cnt += 320544961713Sgirish XRXMAC_CD_VIO_CNT_MASK; 320644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 320744961713Sgirish NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 320844961713Sgirish } 320944961713Sgirish if (status & ICFG_XMAC_RX_OCT_CNT_EXP) { 321044961713Sgirish statsp->xmac_stats.rx_byte_cnt += 321144961713Sgirish XRXMAC_BT_CNT_MASK; 321244961713Sgirish } 321344961713Sgirish if (status & ICFG_XMAC_RX_HST_CNT1_EXP) { 321444961713Sgirish statsp->xmac_stats.rx_hist1_cnt += 321544961713Sgirish XRXMAC_HIST_CNT1_MASK; 321644961713Sgirish } 321744961713Sgirish if (status & ICFG_XMAC_RX_HST_CNT2_EXP) { 321844961713Sgirish statsp->xmac_stats.rx_hist2_cnt += 321944961713Sgirish XRXMAC_HIST_CNT2_MASK; 322044961713Sgirish } 322144961713Sgirish if (status & ICFG_XMAC_RX_HST_CNT3_EXP) { 322244961713Sgirish statsp->xmac_stats.rx_hist3_cnt += 322344961713Sgirish XRXMAC_HIST_CNT3_MASK; 322444961713Sgirish } 322544961713Sgirish if (status & ICFG_XMAC_RX_HST_CNT4_EXP) { 322644961713Sgirish statsp->xmac_stats.rx_hist4_cnt += 322744961713Sgirish XRXMAC_HIST_CNT4_MASK; 322844961713Sgirish } 322944961713Sgirish if (status & ICFG_XMAC_RX_HST_CNT5_EXP) { 323044961713Sgirish statsp->xmac_stats.rx_hist5_cnt += 323144961713Sgirish XRXMAC_HIST_CNT5_MASK; 323244961713Sgirish } 323344961713Sgirish if (status & ICFG_XMAC_RX_HST_CNT6_EXP) { 323444961713Sgirish statsp->xmac_stats.rx_hist6_cnt += 323544961713Sgirish XRXMAC_HIST_CNT6_MASK; 323644961713Sgirish } 323744961713Sgirish if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) { 323844961713Sgirish statsp->xmac_stats.rx_broadcast_cnt += 323944961713Sgirish XRXMAC_BC_FRM_CNT_MASK; 324044961713Sgirish } 324144961713Sgirish if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) { 324244961713Sgirish statsp->xmac_stats.rx_mult_cnt += 324344961713Sgirish XRXMAC_MC_FRM_CNT_MASK; 324444961713Sgirish } 324544961713Sgirish if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) { 324644961713Sgirish statsp->xmac_stats.rx_frag_cnt += 324744961713Sgirish XRXMAC_FRAG_CNT_MASK; 324844961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 324944961713Sgirish NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP); 325044961713Sgirish } 325144961713Sgirish if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) { 325244961713Sgirish statsp->xmac_stats.rx_frame_align_err_cnt += 325344961713Sgirish XRXMAC_AL_ER_CNT_MASK; 325444961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 325544961713Sgirish NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 325644961713Sgirish } 325744961713Sgirish if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) { 325844961713Sgirish statsp->xmac_stats.rx_linkfault_err_cnt += 325944961713Sgirish XMAC_LINK_FLT_CNT_MASK; 326044961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 326144961713Sgirish NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP); 326244961713Sgirish } 326344961713Sgirish if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) { 326444961713Sgirish statsp->xmac_stats.rx_remotefault_err++; 326544961713Sgirish } 326644961713Sgirish if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) { 326744961713Sgirish statsp->xmac_stats.rx_localfault_err++; 326844961713Sgirish } 326944961713Sgirish } 327044961713Sgirish 327144961713Sgirish rs = npi_xmac_ctl_get_istatus(handle, portn, 327244961713Sgirish (xmac_ctl_iconfig_t *)&status); 327344961713Sgirish if (rs != NPI_SUCCESS) 327444961713Sgirish goto npi_fail; 327544961713Sgirish if (status & ICFG_XMAC_CTRL_ALL) { 327644961713Sgirish if (status & ICFG_XMAC_CTRL_PAUSE_RCVD) 327744961713Sgirish statsp->xmac_stats.rx_pause_cnt++; 327844961713Sgirish if (status & ICFG_XMAC_CTRL_PAUSE_STATE) 327944961713Sgirish statsp->xmac_stats.tx_pause_state++; 328044961713Sgirish if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE) 328144961713Sgirish statsp->xmac_stats.tx_nopause_state++; 328244961713Sgirish } 328344961713Sgirish } else if (nxgep->mac.porttype == PORT_TYPE_BMAC) { 328444961713Sgirish rs = npi_bmac_tx_get_istatus(handle, portn, 328544961713Sgirish (bmac_tx_iconfig_t *)&status); 328644961713Sgirish if (rs != NPI_SUCCESS) 328744961713Sgirish goto npi_fail; 328844961713Sgirish if (status & ICFG_BMAC_TX_ALL) { 328944961713Sgirish if (status & ICFG_BMAC_TX_UNDERFLOW) { 329044961713Sgirish statsp->bmac_stats.tx_underrun_err++; 329144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 329244961713Sgirish NXGE_FM_EREPORT_TXMAC_UNDERFLOW); 329344961713Sgirish } 329444961713Sgirish if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) { 329544961713Sgirish statsp->bmac_stats.tx_max_pkt_err++; 329644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 329744961713Sgirish NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR); 329844961713Sgirish } 329944961713Sgirish if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) { 330044961713Sgirish statsp->bmac_stats.tx_byte_cnt += 330144961713Sgirish BTXMAC_BYTE_CNT_MASK; 330244961713Sgirish } 330344961713Sgirish if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) { 330444961713Sgirish statsp->bmac_stats.tx_frame_cnt += 330544961713Sgirish BTXMAC_FRM_CNT_MASK; 330644961713Sgirish } 330744961713Sgirish } 330844961713Sgirish 330944961713Sgirish rs = npi_bmac_rx_get_istatus(handle, portn, 331044961713Sgirish (bmac_rx_iconfig_t *)&status); 331144961713Sgirish if (rs != NPI_SUCCESS) 331244961713Sgirish goto npi_fail; 331344961713Sgirish if (status & ICFG_BMAC_RX_ALL) { 331444961713Sgirish if (status & ICFG_BMAC_RX_OVERFLOW) { 331544961713Sgirish statsp->bmac_stats.rx_overflow_err++; 331644961713Sgirish } 331744961713Sgirish if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) { 331844961713Sgirish statsp->bmac_stats.rx_frame_cnt += 331944961713Sgirish RXMAC_FRM_CNT_MASK; 332044961713Sgirish } 332144961713Sgirish if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) { 332244961713Sgirish statsp->bmac_stats.rx_crc_err_cnt += 332344961713Sgirish BMAC_CRC_ER_CNT_MASK; 332444961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 332544961713Sgirish NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP); 332644961713Sgirish } 332744961713Sgirish if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) { 332844961713Sgirish statsp->bmac_stats.rx_len_err_cnt += 332944961713Sgirish MAC_LEN_ER_CNT_MASK; 333044961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 333144961713Sgirish NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP); 333244961713Sgirish } 333344961713Sgirish if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) 333444961713Sgirish statsp->bmac_stats.rx_viol_err_cnt += 333544961713Sgirish BMAC_CD_VIO_CNT_MASK; 333644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 333744961713Sgirish NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP); 333844961713Sgirish } 333944961713Sgirish if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) { 334044961713Sgirish statsp->bmac_stats.rx_byte_cnt += 334144961713Sgirish BRXMAC_BYTE_CNT_MASK; 334244961713Sgirish } 334344961713Sgirish if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) { 334444961713Sgirish statsp->bmac_stats.rx_align_err_cnt += 334544961713Sgirish BMAC_AL_ER_CNT_MASK; 334644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 334744961713Sgirish NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP); 334844961713Sgirish } 334944961713Sgirish 335044961713Sgirish rs = npi_bmac_ctl_get_istatus(handle, portn, 335144961713Sgirish (bmac_ctl_iconfig_t *)&status); 335244961713Sgirish if (rs != NPI_SUCCESS) 335344961713Sgirish goto npi_fail; 335444961713Sgirish 335544961713Sgirish if (status & ICFG_BMAC_CTL_ALL) { 335644961713Sgirish if (status & ICFG_BMAC_CTL_RCVPAUSE) 335744961713Sgirish statsp->bmac_stats.rx_pause_cnt++; 335844961713Sgirish if (status & ICFG_BMAC_CTL_INPAUSE_ST) 335944961713Sgirish statsp->bmac_stats.tx_pause_state++; 336044961713Sgirish if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST) 336144961713Sgirish statsp->bmac_stats.tx_nopause_state++; 336244961713Sgirish } 336344961713Sgirish } 336444961713Sgirish 336544961713Sgirish if (ldgp->nldvs == 1) { 336644961713Sgirish (void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg, 336744961713Sgirish B_TRUE, ldgp->ldg_timer); 336844961713Sgirish } 336944961713Sgirish 337044961713Sgirish NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 337144961713Sgirish return (DDI_INTR_CLAIMED); 337244961713Sgirish 337344961713Sgirish npi_fail: 337444961713Sgirish NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr")); 337544961713Sgirish return (DDI_INTR_UNCLAIMED); 337644961713Sgirish } 337744961713Sgirish 337844961713Sgirish nxge_status_t 337944961713Sgirish nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up) 338044961713Sgirish { 338144961713Sgirish uint8_t phy_port_addr; 338244961713Sgirish nxge_status_t status = NXGE_OK; 338344961713Sgirish boolean_t rx_sig_ok; 338444961713Sgirish boolean_t pcs_blk_lock; 338544961713Sgirish boolean_t link_align; 338644961713Sgirish uint16_t val1, val2, val3; 338744961713Sgirish #ifdef NXGE_DEBUG_SYMBOL_ERR 338844961713Sgirish uint16_t val_debug; 338944961713Sgirish uint16_t val; 339044961713Sgirish #endif 339144961713Sgirish 339244961713Sgirish phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn; 339344961713Sgirish 339444961713Sgirish #ifdef NXGE_DEBUG_SYMBOL_ERR 339544961713Sgirish /* Check Device 3 Register Device 3 0xC809 */ 339644961713Sgirish (void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug); 339744961713Sgirish if ((val_debug & ~0x200) != 0) { 339844961713Sgirish cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n", 339944961713Sgirish nxgep->mac.portnum, val_debug); 340044961713Sgirish (void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, 340144961713Sgirish &val_debug); 340244961713Sgirish cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n", 340344961713Sgirish nxgep->mac.portnum, val_debug); 340444961713Sgirish } 340544961713Sgirish 340644961713Sgirish (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 340744961713Sgirish XPCS_REG_DESCWERR_COUNTER, &val); 340844961713Sgirish if (val != 0) 340944961713Sgirish cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val); 341044961713Sgirish 341144961713Sgirish (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 341244961713Sgirish XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val); 341344961713Sgirish if (val != 0) 341444961713Sgirish cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val); 341544961713Sgirish 341644961713Sgirish (void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum, 341744961713Sgirish XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val); 341844961713Sgirish if (val != 0) 341944961713Sgirish cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val); 342044961713Sgirish #endif 342144961713Sgirish 342244961713Sgirish /* Check from BCM8704 if 10G link is up or down */ 342344961713Sgirish 342444961713Sgirish /* Check Device 1 Register 0xA bit0 */ 342544961713Sgirish status = nxge_mdio_read(nxgep, phy_port_addr, 342644961713Sgirish BCM8704_PMA_PMD_DEV_ADDR, 342744961713Sgirish BCM8704_PMD_RECEIVE_SIG_DETECT, 342844961713Sgirish &val1); 342944961713Sgirish if (status != NXGE_OK) 343044961713Sgirish goto fail; 343144961713Sgirish rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE); 343244961713Sgirish 343344961713Sgirish /* Check Device 3 Register 0x20 bit0 */ 343444961713Sgirish if ((status = nxge_mdio_read(nxgep, phy_port_addr, 343544961713Sgirish BCM8704_PCS_DEV_ADDR, 343644961713Sgirish BCM8704_10GBASE_R_PCS_STATUS_REG, 343744961713Sgirish &val2)) != NPI_SUCCESS) 343844961713Sgirish goto fail; 343944961713Sgirish pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE); 344044961713Sgirish 344144961713Sgirish /* Check Device 4 Register 0x18 bit12 */ 344244961713Sgirish status = nxge_mdio_read(nxgep, phy_port_addr, 344344961713Sgirish BCM8704_PHYXS_ADDR, 344444961713Sgirish BCM8704_PHYXS_XGXS_LANE_STATUS_REG, 344544961713Sgirish &val3); 344644961713Sgirish if (status != NXGE_OK) 344744961713Sgirish goto fail; 344844961713Sgirish link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC | 344944961713Sgirish XGXS_LANE2_SYNC | XGXS_LANE1_SYNC | 345044961713Sgirish XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE; 345144961713Sgirish 345244961713Sgirish #ifdef NXGE_DEBUG_ALIGN_ERR 345344961713Sgirish /* Temp workaround for link down issue */ 345444961713Sgirish if (pcs_blk_lock == B_FALSE) { 345544961713Sgirish if (val2 != 0x4) { 345644961713Sgirish pcs_blk_lock = B_TRUE; 345744961713Sgirish cmn_err(CE_NOTE, 345844961713Sgirish "!LINK DEBUG: port%d PHY Dev3 " 345944961713Sgirish "Reg 0x20 = 0x%x\n", 346044961713Sgirish nxgep->mac.portnum, val2); 346144961713Sgirish } 346244961713Sgirish } 346344961713Sgirish 346444961713Sgirish if (link_align == B_FALSE) { 346544961713Sgirish if (val3 != 0x140f) { 346644961713Sgirish link_align = B_TRUE; 346744961713Sgirish cmn_err(CE_NOTE, 346844961713Sgirish "!LINK DEBUG: port%d PHY Dev4 " 346944961713Sgirish "Reg 0x18 = 0x%x\n", 347044961713Sgirish nxgep->mac.portnum, val3); 347144961713Sgirish } 347244961713Sgirish } 347344961713Sgirish 347444961713Sgirish if (rx_sig_ok == B_FALSE) { 347544961713Sgirish if ((val2 == 0) || (val3 == 0)) { 347644961713Sgirish rx_sig_ok = B_TRUE; 347744961713Sgirish cmn_err(CE_NOTE, 347844961713Sgirish "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n", 347944961713Sgirish nxgep->mac.portnum); 348044961713Sgirish } 348144961713Sgirish } 348244961713Sgirish #endif 348344961713Sgirish 348444961713Sgirish *link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) && 348544961713Sgirish (link_align == B_TRUE)) ? B_TRUE : B_FALSE; 348644961713Sgirish 348744961713Sgirish return (NXGE_OK); 348844961713Sgirish fail: 348944961713Sgirish return (status); 349044961713Sgirish } 349144961713Sgirish 3492*59ac0c16Sdavemq nxge_status_t 3493*59ac0c16Sdavemq nxge_10g_link_led_on(p_nxge_t nxgep) 3494*59ac0c16Sdavemq { 3495*59ac0c16Sdavemq if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE) 3496*59ac0c16Sdavemq != NPI_SUCCESS) 3497*59ac0c16Sdavemq return (NXGE_ERROR); 3498*59ac0c16Sdavemq else 3499*59ac0c16Sdavemq return (NXGE_OK); 3500*59ac0c16Sdavemq } 350144961713Sgirish 350244961713Sgirish nxge_status_t 3503*59ac0c16Sdavemq nxge_10g_link_led_off(p_nxge_t nxgep) 350444961713Sgirish { 3505*59ac0c16Sdavemq if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE) 3506*59ac0c16Sdavemq != NPI_SUCCESS) 3507*59ac0c16Sdavemq return (NXGE_ERROR); 3508*59ac0c16Sdavemq else 3509*59ac0c16Sdavemq return (NXGE_OK); 3510*59ac0c16Sdavemq } 351144961713Sgirish 3512*59ac0c16Sdavemq /* Check if the given id read using the given MDIO Clause is supported */ 3513*59ac0c16Sdavemq 3514*59ac0c16Sdavemq static boolean_t 3515*59ac0c16Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type) 3516*59ac0c16Sdavemq { 3517*59ac0c16Sdavemq int i; 3518*59ac0c16Sdavemq int cl45_arr_len = NUM_CLAUSE_45_IDS; 3519*59ac0c16Sdavemq int cl22_arr_len = NUM_CLAUSE_22_IDS; 3520*59ac0c16Sdavemq boolean_t found = B_FALSE; 3521*59ac0c16Sdavemq 3522*59ac0c16Sdavemq switch (type) { 3523*59ac0c16Sdavemq case CLAUSE_45_TYPE: 3524*59ac0c16Sdavemq for (i = 0; i < cl45_arr_len; i++) { 3525*59ac0c16Sdavemq if ((nxge_supported_cl45_ids[i] & PHY_ID_MASK) == 3526*59ac0c16Sdavemq (id & PHY_ID_MASK)) { 3527*59ac0c16Sdavemq found = B_TRUE; 3528*59ac0c16Sdavemq break; 3529*59ac0c16Sdavemq } 3530*59ac0c16Sdavemq } 3531*59ac0c16Sdavemq break; 3532*59ac0c16Sdavemq case CLAUSE_22_TYPE: 3533*59ac0c16Sdavemq for (i = 0; i < cl22_arr_len; i++) { 3534*59ac0c16Sdavemq if ((nxge_supported_cl22_ids[i] & PHY_ID_MASK) == 3535*59ac0c16Sdavemq (id & PHY_ID_MASK)) { 3536*59ac0c16Sdavemq found = B_TRUE; 3537*59ac0c16Sdavemq break; 353856d930aeSspeer } 353944961713Sgirish } 3540*59ac0c16Sdavemq break; 3541*59ac0c16Sdavemq default: 3542*59ac0c16Sdavemq break; 354356d930aeSspeer } 354456d930aeSspeer 3545*59ac0c16Sdavemq return (found); 3546*59ac0c16Sdavemq } 3547*59ac0c16Sdavemq 3548*59ac0c16Sdavemq /* 3549*59ac0c16Sdavemq * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO 3550*59ac0c16Sdavemq * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO 3551*59ac0c16Sdavemq * read. Then use the values obtained to determine the phy type of each port 3552*59ac0c16Sdavemq * and the Neptune type. 3553*59ac0c16Sdavemq */ 3554*59ac0c16Sdavemq 3555*59ac0c16Sdavemq nxge_status_t 3556*59ac0c16Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p) 3557*59ac0c16Sdavemq { 3558*59ac0c16Sdavemq int i, j, k, l; 3559*59ac0c16Sdavemq uint16_t val1 = 0; 3560*59ac0c16Sdavemq uint16_t val2 = 0; 3561*59ac0c16Sdavemq uint32_t pma_pmd_dev_id = 0; 3562*59ac0c16Sdavemq uint32_t pcs_dev_id = 0; 3563*59ac0c16Sdavemq uint32_t phy_id = 0; 3564*59ac0c16Sdavemq uint32_t port_pma_pmd_dev_id[4]; 3565*59ac0c16Sdavemq uint32_t port_pcs_dev_id[4]; 3566*59ac0c16Sdavemq uint32_t port_phy_id[4]; 3567*59ac0c16Sdavemq uint8_t pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS]; 3568*59ac0c16Sdavemq uint8_t pcs_dev_fd[NXGE_MAX_PHY_PORTS]; 3569*59ac0c16Sdavemq uint8_t phy_fd[NXGE_MAX_PHY_PORTS]; 3570*59ac0c16Sdavemq uint8_t port_fd[NXGE_MAX_PHY_PORTS]; 3571*59ac0c16Sdavemq uint8_t total_port_fd, total_phy_fd; 3572*59ac0c16Sdavemq nxge_status_t status = NXGE_OK; 3573*59ac0c16Sdavemq npi_status_t npi_status = NPI_SUCCESS; 3574*59ac0c16Sdavemq npi_handle_t handle; 3575*59ac0c16Sdavemq int prt_id = -1; 357656d930aeSspeer 3577*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: ")); 357856d930aeSspeer NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3579*59ac0c16Sdavemq "==> nxge_scan_ports_phy: nxge niu_type[0x%x]", 3580*59ac0c16Sdavemq nxgep->niu_type)); 3581*59ac0c16Sdavemq 3582*59ac0c16Sdavemq handle = NXGE_DEV_NPI_HANDLE(nxgep); 3583*59ac0c16Sdavemq j = k = l = 0; 3584*59ac0c16Sdavemq total_port_fd = total_phy_fd = 0; 358556d930aeSspeer /* 3586*59ac0c16Sdavemq * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved 3587*59ac0c16Sdavemq * for on chip serdes usages. 358856d930aeSspeer */ 3589*59ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) { 3590*59ac0c16Sdavemq (void) npi_mac_mif_mdio_read(handle, i, NXGE_PMA_PMD_DEV_ADDR, 3591*59ac0c16Sdavemq NXGE_DEV_ID_REG_1, &val1); 3592*59ac0c16Sdavemq (void) npi_mac_mif_mdio_read(handle, i, NXGE_PMA_PMD_DEV_ADDR, 3593*59ac0c16Sdavemq NXGE_DEV_ID_REG_2, &val2); 3594*59ac0c16Sdavemq pma_pmd_dev_id = val1; 3595*59ac0c16Sdavemq pma_pmd_dev_id = (pma_pmd_dev_id << 16); 3596*59ac0c16Sdavemq pma_pmd_dev_id |= val2; 3597*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD " 3598*59ac0c16Sdavemq "devid[0x%llx]", i, pma_pmd_dev_id)); 3599*59ac0c16Sdavemq 3600*59ac0c16Sdavemq if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) { 3601*59ac0c16Sdavemq pma_pmd_dev_fd[i] = 1; 3602*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 3603*59ac0c16Sdavemq "PMA/PMD dev found", i)); 3604*59ac0c16Sdavemq if (j < 4) { 3605*59ac0c16Sdavemq port_pma_pmd_dev_id[j] = pma_pmd_dev_id; 3606*59ac0c16Sdavemq j++; 3607*59ac0c16Sdavemq } 3608*59ac0c16Sdavemq } else { 3609*59ac0c16Sdavemq pma_pmd_dev_fd[i] = 0; 3610*59ac0c16Sdavemq } 3611*59ac0c16Sdavemq 3612*59ac0c16Sdavemq (void) npi_mac_mif_mdio_read(handle, i, NXGE_PCS_DEV_ADDR, 3613*59ac0c16Sdavemq NXGE_DEV_ID_REG_1, &val1); 3614*59ac0c16Sdavemq (void) npi_mac_mif_mdio_read(handle, i, NXGE_PCS_DEV_ADDR, 3615*59ac0c16Sdavemq NXGE_DEV_ID_REG_2, &val2); 3616*59ac0c16Sdavemq pcs_dev_id = val1; 3617*59ac0c16Sdavemq pcs_dev_id = (pcs_dev_id << 16); 3618*59ac0c16Sdavemq pcs_dev_id |= val2; 3619*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 3620*59ac0c16Sdavemq "devid[0x%llx]", i, pcs_dev_id)); 3621*59ac0c16Sdavemq 3622*59ac0c16Sdavemq if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) { 3623*59ac0c16Sdavemq pcs_dev_fd[i] = 1; 3624*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS " 3625*59ac0c16Sdavemq "dev found", i)); 3626*59ac0c16Sdavemq if (k < 4) { 3627*59ac0c16Sdavemq port_pcs_dev_id[k] = pcs_dev_id; 3628*59ac0c16Sdavemq k++; 3629*59ac0c16Sdavemq } 3630*59ac0c16Sdavemq } else { 3631*59ac0c16Sdavemq pcs_dev_fd[i] = 0; 3632*59ac0c16Sdavemq } 3633*59ac0c16Sdavemq 3634*59ac0c16Sdavemq if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) 3635*59ac0c16Sdavemq port_fd[i] = 1; 3636*59ac0c16Sdavemq else 3637*59ac0c16Sdavemq port_fd[i] = 0; 3638*59ac0c16Sdavemq total_port_fd += port_fd[i]; 3639*59ac0c16Sdavemq 3640*59ac0c16Sdavemq npi_status = npi_mac_mif_mii_read(handle, i, 3641*59ac0c16Sdavemq NXGE_PHY_ID_REG_1, &val1); 3642*59ac0c16Sdavemq if (npi_status != NPI_SUCCESS) { 3643*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 3644*59ac0c16Sdavemq "clause 22 read to reg 2 failed!!!")); 3645*59ac0c16Sdavemq goto error_exit; 3646*59ac0c16Sdavemq } 3647*59ac0c16Sdavemq npi_status = npi_mac_mif_mii_read(handle, i, 3648*59ac0c16Sdavemq NXGE_PHY_ID_REG_2, &val2); 3649*59ac0c16Sdavemq if (npi_status != 0) { 3650*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] " 3651*59ac0c16Sdavemq "clause 22 read to reg 3 failed!!!")); 3652*59ac0c16Sdavemq goto error_exit; 3653*59ac0c16Sdavemq } 3654*59ac0c16Sdavemq phy_id = val1; 3655*59ac0c16Sdavemq phy_id = (phy_id << 16); 3656*59ac0c16Sdavemq phy_id |= val2; 3657*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 3658*59ac0c16Sdavemq "[0x%llx]", i, phy_id)); 3659*59ac0c16Sdavemq 3660*59ac0c16Sdavemq if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) { 3661*59ac0c16Sdavemq phy_fd[i] = 1; 3662*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID" 3663*59ac0c16Sdavemq "found", i)); 3664*59ac0c16Sdavemq if (l < 4) { 3665*59ac0c16Sdavemq port_phy_id[l] = phy_id; 3666*59ac0c16Sdavemq l++; 3667*59ac0c16Sdavemq } 3668*59ac0c16Sdavemq } else { 3669*59ac0c16Sdavemq phy_fd[i] = 0; 3670*59ac0c16Sdavemq } 3671*59ac0c16Sdavemq total_phy_fd += phy_fd[i]; 3672*59ac0c16Sdavemq } 3673*59ac0c16Sdavemq 3674*59ac0c16Sdavemq switch (total_port_fd) { 3675*59ac0c16Sdavemq case 2: 3676*59ac0c16Sdavemq switch (total_phy_fd) { 3677*59ac0c16Sdavemq case 2: 3678*59ac0c16Sdavemq /* 2 10G, 2 1G */ 3679*59ac0c16Sdavemq if (((port_pcs_dev_id[0] == PHY_10G_FIBRE && 3680*59ac0c16Sdavemq port_pcs_dev_id[1] == PHY_10G_FIBRE) || 3681*59ac0c16Sdavemq (port_pma_pmd_dev_id[0] == PHY_10G_FIBRE && 3682*59ac0c16Sdavemq port_pma_pmd_dev_id[1] == PHY_10G_FIBRE)) && 3683*59ac0c16Sdavemq (port_phy_id[0] == PHY_1G_COPPER && 3684*59ac0c16Sdavemq port_phy_id[1] == PHY_1G_COPPER)) { 3685*59ac0c16Sdavemq hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 3686*59ac0c16Sdavemq } else { 3687*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3688*59ac0c16Sdavemq "Unsupported neptune type 1")); 3689*59ac0c16Sdavemq goto error_exit; 3690*59ac0c16Sdavemq } 3691*59ac0c16Sdavemq break; 3692*59ac0c16Sdavemq case 1: 3693*59ac0c16Sdavemq /* TODO - 2 10G, 1 1G */ 3694*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3695*59ac0c16Sdavemq "Unsupported neptune type 2 10G, 1 1G")); 3696*59ac0c16Sdavemq goto error_exit; 3697*59ac0c16Sdavemq case 0: 3698*59ac0c16Sdavemq /* 2 10G */ 3699*59ac0c16Sdavemq if ((port_pcs_dev_id[0] == PHY_10G_FIBRE && 3700*59ac0c16Sdavemq port_pcs_dev_id[1] == PHY_10G_FIBRE) || 3701*59ac0c16Sdavemq (port_pma_pmd_dev_id[0] == PHY_10G_FIBRE && 3702*59ac0c16Sdavemq port_pma_pmd_dev_id[1] == PHY_10G_FIBRE)) { 3703*59ac0c16Sdavemq hw_p->niu_type = NEPTUNE_2_10GF; 3704*59ac0c16Sdavemq } else { 3705*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3706*59ac0c16Sdavemq "Unsupported neptune type 2")); 3707*59ac0c16Sdavemq goto error_exit; 3708*59ac0c16Sdavemq } 3709*59ac0c16Sdavemq break; 3710*59ac0c16Sdavemq case 4: 3711*59ac0c16Sdavemq /* Maramba with 2 XAUI */ 3712*59ac0c16Sdavemq if (((port_pcs_dev_id[0] == PHY_10G_FIBRE && 3713*59ac0c16Sdavemq port_pcs_dev_id[1] == PHY_10G_FIBRE) || 3714*59ac0c16Sdavemq (port_pma_pmd_dev_id[0] == PHY_10G_FIBRE && 3715*59ac0c16Sdavemq port_pma_pmd_dev_id[1] == PHY_10G_FIBRE)) && 3716*59ac0c16Sdavemq (port_phy_id[0] == PHY_1G_COPPER && 3717*59ac0c16Sdavemq port_phy_id[1] == PHY_1G_COPPER && 3718*59ac0c16Sdavemq port_phy_id[2] == PHY_1G_COPPER && 3719*59ac0c16Sdavemq port_phy_id[3] == PHY_1G_COPPER)) { 3720*59ac0c16Sdavemq hw_p->niu_type = NEPTUNE_2_10GF_2_1GC; 3721*59ac0c16Sdavemq 3722*59ac0c16Sdavemq /* 3723*59ac0c16Sdavemq * Check the first phy port address against 3724*59ac0c16Sdavemq * the known phy start addresses to determine 3725*59ac0c16Sdavemq * the platform type. 3726*59ac0c16Sdavemq */ 3727*59ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 3728*59ac0c16Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 3729*59ac0c16Sdavemq if (phy_fd[i] == 1) 3730*59ac0c16Sdavemq break; 3731*59ac0c16Sdavemq } 3732*59ac0c16Sdavemq if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 3733*59ac0c16Sdavemq hw_p->platform_type = 3734*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P0; 3735*59ac0c16Sdavemq } else if (i == 3736*59ac0c16Sdavemq BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 3737*59ac0c16Sdavemq hw_p->platform_type = 3738*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1; 3739*59ac0c16Sdavemq } else { 3740*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3741*59ac0c16Sdavemq "Unknown port %d...Cannot " 3742*59ac0c16Sdavemq "determine platform type", i)); 3743*59ac0c16Sdavemq } 3744*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3745*59ac0c16Sdavemq "Maramba with 2 XAUI")); 3746*59ac0c16Sdavemq } else { 3747*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3748*59ac0c16Sdavemq "Unsupported neptune type 3")); 3749*59ac0c16Sdavemq goto error_exit; 3750*59ac0c16Sdavemq } 3751*59ac0c16Sdavemq break; 3752*59ac0c16Sdavemq default: 3753*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3754*59ac0c16Sdavemq "Unsupported neptune type 5")); 3755*59ac0c16Sdavemq goto error_exit; 3756*59ac0c16Sdavemq } 3757*59ac0c16Sdavemq case 1: 3758*59ac0c16Sdavemq switch (total_phy_fd) { 3759*59ac0c16Sdavemq case 3: 3760*59ac0c16Sdavemq if (((port_pcs_dev_id[0] & PHY_ID_MASK) == 3761*59ac0c16Sdavemq (BCM8704_DEV_ID & PHY_ID_MASK)) || 3762*59ac0c16Sdavemq ((port_pma_pmd_dev_id[0] & PHY_ID_MASK) == 3763*59ac0c16Sdavemq (BCM8704_DEV_ID & PHY_ID_MASK))) { 3764*59ac0c16Sdavemq /* The 10G port is BCM8704 */ 3765*59ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 3766*59ac0c16Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 3767*59ac0c16Sdavemq if (port_fd[i] == 1) { 3768*59ac0c16Sdavemq prt_id = i; 3769*59ac0c16Sdavemq break; 3770*59ac0c16Sdavemq } 3771*59ac0c16Sdavemq } 3772*59ac0c16Sdavemq 3773*59ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) 3774*59ac0c16Sdavemq prt_id %= BCM8704_N2_PORT_ADDR_BASE; 3775*59ac0c16Sdavemq else 3776*59ac0c16Sdavemq prt_id %= 3777*59ac0c16Sdavemq BCM8704_NEPTUNE_PORT_ADDR_BASE; 3778*59ac0c16Sdavemq 3779*59ac0c16Sdavemq if (prt_id == 0) { 3780*59ac0c16Sdavemq hw_p->niu_type = NEPTUNE_1_10GF_3_1GC; 3781*59ac0c16Sdavemq } else if (prt_id == 1) { 3782*59ac0c16Sdavemq hw_p->niu_type = 3783*59ac0c16Sdavemq NEPTUNE_1_1GC_1_10GF_2_1GC; 3784*59ac0c16Sdavemq } else { 3785*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3786*59ac0c16Sdavemq "Unsupported neptune type 6")); 3787*59ac0c16Sdavemq goto error_exit; 3788*59ac0c16Sdavemq } 3789*59ac0c16Sdavemq } else { 3790*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3791*59ac0c16Sdavemq "Unsupported neptune type 7")); 3792*59ac0c16Sdavemq goto error_exit; 3793*59ac0c16Sdavemq } 3794*59ac0c16Sdavemq break; 3795*59ac0c16Sdavemq case 2: 3796*59ac0c16Sdavemq /* 3797*59ac0c16Sdavemq * TODO 2 1G, 1 10G mode. 3798*59ac0c16Sdavemq * Differentiate between 1_1G_1_10G_1_1G and 3799*59ac0c16Sdavemq * 1_10G_2_1G 3800*59ac0c16Sdavemq */ 3801*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3802*59ac0c16Sdavemq "Unsupported neptune type 8")); 3803*59ac0c16Sdavemq goto error_exit; 3804*59ac0c16Sdavemq case 1: 3805*59ac0c16Sdavemq /* 3806*59ac0c16Sdavemq * TODO 1 1G, 1 10G mode. 3807*59ac0c16Sdavemq * Differentiate between 1_1G_1_10G and 3808*59ac0c16Sdavemq * 1_10G_1_1G 3809*59ac0c16Sdavemq */ 3810*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3811*59ac0c16Sdavemq "Unsupported neptune type 9")); 3812*59ac0c16Sdavemq goto error_exit; 3813*59ac0c16Sdavemq case 0: 3814*59ac0c16Sdavemq /* TODO 1 10G mode */ 3815*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3816*59ac0c16Sdavemq "Unsupported neptune type 10")); 3817*59ac0c16Sdavemq goto error_exit; 3818*59ac0c16Sdavemq case 4: 3819*59ac0c16Sdavemq /* Maramba with 1 XAUI */ 3820*59ac0c16Sdavemq if (((port_pcs_dev_id[0] & PHY_ID_MASK) == 3821*59ac0c16Sdavemq (BCM8704_DEV_ID & PHY_ID_MASK)) || 3822*59ac0c16Sdavemq ((port_pma_pmd_dev_id[0] & PHY_ID_MASK) == 3823*59ac0c16Sdavemq (BCM8704_DEV_ID & PHY_ID_MASK))) { 3824*59ac0c16Sdavemq /* The 10G port is BCM8704 */ 3825*59ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 3826*59ac0c16Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 3827*59ac0c16Sdavemq if (port_fd[i] == 1) { 3828*59ac0c16Sdavemq prt_id = i; 3829*59ac0c16Sdavemq break; 3830*59ac0c16Sdavemq } 3831*59ac0c16Sdavemq } 3832*59ac0c16Sdavemq 3833*59ac0c16Sdavemq prt_id %= BCM8704_MARAMBA_PORT_ADDR_BASE; 3834*59ac0c16Sdavemq if (prt_id == 0) { 3835*59ac0c16Sdavemq hw_p->niu_type = NEPTUNE_1_10GF_3_1GC; 3836*59ac0c16Sdavemq } else if (prt_id == 1) { 3837*59ac0c16Sdavemq hw_p->niu_type = 3838*59ac0c16Sdavemq NEPTUNE_1_1GC_1_10GF_2_1GC; 3839*59ac0c16Sdavemq } else { 3840*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3841*59ac0c16Sdavemq "Unsupported neptune type 11")); 3842*59ac0c16Sdavemq goto error_exit; 3843*59ac0c16Sdavemq } 3844*59ac0c16Sdavemq 3845*59ac0c16Sdavemq /* 3846*59ac0c16Sdavemq * Check the first phy port address against 3847*59ac0c16Sdavemq * the known phy start addresses to determine 3848*59ac0c16Sdavemq * the platform type. 3849*59ac0c16Sdavemq */ 3850*59ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 3851*59ac0c16Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 3852*59ac0c16Sdavemq if (phy_fd[i] == 1) 3853*59ac0c16Sdavemq break; 3854*59ac0c16Sdavemq } 3855*59ac0c16Sdavemq 3856*59ac0c16Sdavemq if (i == BCM5464_MARAMBA_P0_PORT_ADDR_BASE) { 3857*59ac0c16Sdavemq hw_p->platform_type = 3858*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P0; 3859*59ac0c16Sdavemq } else if (i == 3860*59ac0c16Sdavemq BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 3861*59ac0c16Sdavemq hw_p->platform_type = 3862*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1; 3863*59ac0c16Sdavemq } else { 3864*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 3865*59ac0c16Sdavemq "Unknown port %d...Cannot " 3866*59ac0c16Sdavemq "determine platform type", i)); 3867*59ac0c16Sdavemq } 3868*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3869*59ac0c16Sdavemq "Maramba with 1 XAUI")); 3870*59ac0c16Sdavemq } else { 3871*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3872*59ac0c16Sdavemq "Unsupported neptune type 12")); 3873*59ac0c16Sdavemq goto error_exit; 3874*59ac0c16Sdavemq } 3875*59ac0c16Sdavemq break; 3876*59ac0c16Sdavemq default: 3877*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3878*59ac0c16Sdavemq "Unsupported neptune type 13")); 3879*59ac0c16Sdavemq goto error_exit; 3880*59ac0c16Sdavemq } 3881*59ac0c16Sdavemq break; 3882*59ac0c16Sdavemq case 0: 3883*59ac0c16Sdavemq switch (total_phy_fd) { 3884*59ac0c16Sdavemq case 4: 3885*59ac0c16Sdavemq if (((port_phy_id[0] & PHY_ID_MASK) == 3886*59ac0c16Sdavemq (BCM5464R_PHY_ID & PHY_ID_MASK)) && 3887*59ac0c16Sdavemq ((port_phy_id[1] & PHY_ID_MASK) == 3888*59ac0c16Sdavemq (BCM5464R_PHY_ID & PHY_ID_MASK)) && 3889*59ac0c16Sdavemq ((port_phy_id[2] & PHY_ID_MASK) == 3890*59ac0c16Sdavemq (BCM5464R_PHY_ID & PHY_ID_MASK)) && 3891*59ac0c16Sdavemq ((port_phy_id[3] & PHY_ID_MASK) == 3892*59ac0c16Sdavemq (BCM5464R_PHY_ID & PHY_ID_MASK))) { 3893*59ac0c16Sdavemq 3894*59ac0c16Sdavemq hw_p->niu_type = NEPTUNE_4_1GC; 3895*59ac0c16Sdavemq 3896*59ac0c16Sdavemq /* 3897*59ac0c16Sdavemq * Check the first phy port address against 3898*59ac0c16Sdavemq * the known phy start addresses to determine 3899*59ac0c16Sdavemq * the platform type. 3900*59ac0c16Sdavemq */ 3901*59ac0c16Sdavemq for (i = NXGE_EXT_PHY_PORT_ST; 3902*59ac0c16Sdavemq i < NXGE_MAX_PHY_PORTS; i++) { 3903*59ac0c16Sdavemq if (phy_fd[i] == 1) 3904*59ac0c16Sdavemq break; 3905*59ac0c16Sdavemq } 3906*59ac0c16Sdavemq 3907*59ac0c16Sdavemq if (i == BCM5464_MARAMBA_P1_PORT_ADDR_BASE) { 3908*59ac0c16Sdavemq hw_p->platform_type = 3909*59ac0c16Sdavemq P_NEPTUNE_MARAMBA_P1; 3910*59ac0c16Sdavemq } 3911*59ac0c16Sdavemq } else { 3912*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3913*59ac0c16Sdavemq "Unsupported neptune type 14")); 3914*59ac0c16Sdavemq goto error_exit; 3915*59ac0c16Sdavemq } 3916*59ac0c16Sdavemq break; 3917*59ac0c16Sdavemq case 3: 3918*59ac0c16Sdavemq /* TODO 3 1G mode */ 3919*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3920*59ac0c16Sdavemq "Unsupported neptune type 15")); 3921*59ac0c16Sdavemq goto error_exit; 3922*59ac0c16Sdavemq case 2: 3923*59ac0c16Sdavemq /* TODO 2 1G mode */ 3924*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3925*59ac0c16Sdavemq "Unsupported neptune type 16")); 3926*59ac0c16Sdavemq goto error_exit; 3927*59ac0c16Sdavemq case 1: 3928*59ac0c16Sdavemq /* TODO 1 1G mode */ 3929*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3930*59ac0c16Sdavemq "Unsupported neptune type 17")); 3931*59ac0c16Sdavemq goto error_exit; 3932*59ac0c16Sdavemq default: 3933*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3934*59ac0c16Sdavemq "Unsupported neptune type 18, total phy fd %d", 3935*59ac0c16Sdavemq total_phy_fd)); 3936*59ac0c16Sdavemq goto error_exit; 3937*59ac0c16Sdavemq } 3938*59ac0c16Sdavemq break; 3939*59ac0c16Sdavemq default: 394056d930aeSspeer NXGE_DEBUG_MSG((nxgep, MAC_CTL, 3941*59ac0c16Sdavemq "Unsupported neptune type 19")); 3942*59ac0c16Sdavemq goto error_exit; 394344961713Sgirish } 394444961713Sgirish 3945*59ac0c16Sdavemq scan_exit: 394644961713Sgirish 3947*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, " 3948*59ac0c16Sdavemq "niu type [0x%x]\n", hw_p->niu_type)); 3949*59ac0c16Sdavemq return (status); 395044961713Sgirish 3951*59ac0c16Sdavemq error_exit: 3952*59ac0c16Sdavemq return (NXGE_ERROR); 395344961713Sgirish } 395456d930aeSspeer 395556d930aeSspeer boolean_t 395656d930aeSspeer nxge_is_valid_local_mac(ether_addr_st mac_addr) 395756d930aeSspeer { 395856d930aeSspeer if ((mac_addr.ether_addr_octet[0] & 0x01) || 395956d930aeSspeer (ether_cmp(&mac_addr, ðerbroadcastaddr) == 0) || 396056d930aeSspeer (ether_cmp(&mac_addr, ðerzeroaddr) == 0)) 396156d930aeSspeer return (B_FALSE); 396256d930aeSspeer else 396356d930aeSspeer return (B_TRUE); 396456d930aeSspeer } 3965*59ac0c16Sdavemq 3966*59ac0c16Sdavemq static void 3967*59ac0c16Sdavemq nxge_bcm5464_link_led_off(p_nxge_t nxgep) { 3968*59ac0c16Sdavemq 3969*59ac0c16Sdavemq npi_status_t rs = NPI_SUCCESS; 3970*59ac0c16Sdavemq uint8_t xcvr_portn; 3971*59ac0c16Sdavemq uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num); 3972*59ac0c16Sdavemq 3973*59ac0c16Sdavemq NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off")); 3974*59ac0c16Sdavemq 3975*59ac0c16Sdavemq if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) { 3976*59ac0c16Sdavemq xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE; 3977*59ac0c16Sdavemq } else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) { 3978*59ac0c16Sdavemq xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE; 3979*59ac0c16Sdavemq } 3980*59ac0c16Sdavemq /* 3981*59ac0c16Sdavemq * For Altas 4-1G copper, Xcvr port numbers are 3982*59ac0c16Sdavemq * swapped with ethernet port number. This is 3983*59ac0c16Sdavemq * designed for better signal integrity in routing. 3984*59ac0c16Sdavemq */ 3985*59ac0c16Sdavemq switch (portn) { 3986*59ac0c16Sdavemq case 0: 3987*59ac0c16Sdavemq xcvr_portn += 3; 3988*59ac0c16Sdavemq break; 3989*59ac0c16Sdavemq case 1: 3990*59ac0c16Sdavemq xcvr_portn += 2; 3991*59ac0c16Sdavemq break; 3992*59ac0c16Sdavemq case 2: 3993*59ac0c16Sdavemq xcvr_portn += 1; 3994*59ac0c16Sdavemq break; 3995*59ac0c16Sdavemq case 3: 3996*59ac0c16Sdavemq default: 3997*59ac0c16Sdavemq break; 3998*59ac0c16Sdavemq } 3999*59ac0c16Sdavemq 4000*59ac0c16Sdavemq MUTEX_ENTER(&nxge_mii_lock); 4001*59ac0c16Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 4002*59ac0c16Sdavemq xcvr_portn, BCM5464R_MISC, 0xb4ee); 4003*59ac0c16Sdavemq if (rs != NPI_SUCCESS) { 4004*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4005*59ac0c16Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 4006*59ac0c16Sdavemq "returned error 0x[%x]", rs)); 4007*59ac0c16Sdavemq MUTEX_EXIT(&nxge_mii_lock); 4008*59ac0c16Sdavemq return; 4009*59ac0c16Sdavemq } 4010*59ac0c16Sdavemq 4011*59ac0c16Sdavemq rs = npi_mac_mif_mii_write(nxgep->npi_handle, 4012*59ac0c16Sdavemq xcvr_portn, BCM5464R_MISC, 0xb8ee); 4013*59ac0c16Sdavemq if (rs != NPI_SUCCESS) { 4014*59ac0c16Sdavemq NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4015*59ac0c16Sdavemq "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write " 4016*59ac0c16Sdavemq "returned error 0x[%x]", rs)); 4017*59ac0c16Sdavemq MUTEX_EXIT(&nxge_mii_lock); 4018*59ac0c16Sdavemq return; 4019*59ac0c16Sdavemq } 4020*59ac0c16Sdavemq 4021*59ac0c16Sdavemq MUTEX_EXIT(&nxge_mii_lock); 4022*59ac0c16Sdavemq } 4023