13859Sml29623 /*
23859Sml29623 * CDDL HEADER START
33859Sml29623 *
43859Sml29623 * The contents of this file are subject to the terms of the
53859Sml29623 * Common Development and Distribution License (the "License").
63859Sml29623 * You may not use this file except in compliance with the License.
73859Sml29623 *
83859Sml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623 * or http://www.opensolaris.org/os/licensing.
103859Sml29623 * See the License for the specific language governing permissions
113859Sml29623 * and limitations under the License.
123859Sml29623 *
133859Sml29623 * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623 * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623 * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623 * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623 *
193859Sml29623 * CDDL HEADER END
203859Sml29623 */
213859Sml29623 /*
228661SSantwona.Behera@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
233859Sml29623 * Use is subject to license terms.
243859Sml29623 */
253859Sml29623
263859Sml29623 #include <nxge_impl.h>
273859Sml29623 #include <nxge_mac.h>
283859Sml29623 #include <npi_espc.h>
293859Sml29623 #include <nxge_espc.h>
303859Sml29623
314977Sraghus static void nxge_check_vpd_version(p_nxge_t nxgep);
323859Sml29623
334185Sspeer void
nxge_espc_get_next_mac_addr(uint8_t * st_mac,uint8_t nxt_cnt,struct ether_addr * final_mac)343859Sml29623 nxge_espc_get_next_mac_addr(uint8_t *st_mac, uint8_t nxt_cnt,
353859Sml29623 struct ether_addr *final_mac)
363859Sml29623 {
373859Sml29623 uint64_t mac[ETHERADDRL];
383859Sml29623 uint64_t mac_addr = 0;
393859Sml29623 int i, j;
403859Sml29623
413859Sml29623 for (i = ETHERADDRL - 1, j = 0; j < ETHERADDRL; i--, j++) {
423859Sml29623 mac[j] = st_mac[i];
433859Sml29623 mac_addr |= (mac[j] << (j*8));
443859Sml29623 }
453859Sml29623
463859Sml29623 mac_addr += nxt_cnt;
473859Sml29623
483859Sml29623 final_mac->ether_addr_octet[0] = (mac_addr & 0xff0000000000) >> 40;
493859Sml29623 final_mac->ether_addr_octet[1] = (mac_addr & 0xff00000000) >> 32;
503859Sml29623 final_mac->ether_addr_octet[2] = (mac_addr & 0xff000000) >> 24;
513859Sml29623 final_mac->ether_addr_octet[3] = (mac_addr & 0xff0000) >> 16;
523859Sml29623 final_mac->ether_addr_octet[4] = (mac_addr & 0xff00) >> 8;
533859Sml29623 final_mac->ether_addr_octet[5] = (mac_addr & 0xff);
543859Sml29623 }
553859Sml29623
563859Sml29623 nxge_status_t
nxge_espc_mac_addrs_get(p_nxge_t nxgep)573859Sml29623 nxge_espc_mac_addrs_get(p_nxge_t nxgep)
583859Sml29623 {
593859Sml29623 nxge_status_t status = NXGE_OK;
603859Sml29623 npi_status_t npi_status = NPI_SUCCESS;
613859Sml29623 uint8_t port_num = nxgep->mac.portnum;
623859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
633859Sml29623 uint8_t mac_addr[ETHERADDRL];
643859Sml29623
653859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL,
666929Smisaki "==> nxge_espc_mac_addr_get, port[%d]", port_num));
673859Sml29623
683859Sml29623 npi_status = npi_espc_mac_addr_get(handle, mac_addr);
693859Sml29623 if (npi_status != NPI_SUCCESS) {
703859Sml29623 status = (NXGE_ERROR | npi_status);
713859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
726929Smisaki "nxge_espc_mac_addr_get, port[%d] failed", port_num));
733859Sml29623 goto exit;
743859Sml29623 }
753859Sml29623
763859Sml29623 nxge_espc_get_next_mac_addr(mac_addr, port_num, &nxgep->factaddr);
774185Sspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL,
786929Smisaki "Got MAC Addr: %2x:%2x:%2x:%2x:%2x%:%2x%c \n",
796929Smisaki mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
806929Smisaki mac_addr[4], mac_addr[5]));
813859Sml29623
823859Sml29623 exit:
833859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_mac_addr_get, "
846929Smisaki "status [0x%x]", status));
853859Sml29623
863859Sml29623 return (status);
873859Sml29623 }
883859Sml29623
893859Sml29623 nxge_status_t
nxge_espc_num_macs_get(p_nxge_t nxgep,uint8_t * nmacs)903859Sml29623 nxge_espc_num_macs_get(p_nxge_t nxgep, uint8_t *nmacs)
913859Sml29623 {
923859Sml29623 nxge_status_t status = NXGE_OK;
933859Sml29623 npi_status_t npi_status = NPI_SUCCESS;
943859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
953859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_macs_get"));
963859Sml29623
973859Sml29623 npi_status = npi_espc_num_macs_get(handle, nmacs);
983859Sml29623 if (npi_status != NPI_SUCCESS) {
993859Sml29623 status = (NXGE_ERROR | npi_status);
1003859Sml29623 }
1013859Sml29623
1023859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_macs_get, "
1036929Smisaki "status [0x%x]", status));
1043859Sml29623
1053859Sml29623 return (status);
1063859Sml29623 }
1073859Sml29623
1083859Sml29623 nxge_status_t
nxge_espc_num_ports_get(p_nxge_t nxgep)1093859Sml29623 nxge_espc_num_ports_get(p_nxge_t nxgep)
1103859Sml29623 {
1113859Sml29623 nxge_status_t status = NXGE_OK;
1123859Sml29623 npi_status_t npi_status = NPI_SUCCESS;
1133859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
1143859Sml29623 uint8_t nports = 0;
1153859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_ports_get"));
1163859Sml29623
1173859Sml29623 npi_status = npi_espc_num_ports_get(handle, &nports);
1183859Sml29623 if (npi_status != NPI_SUCCESS) {
1193859Sml29623 status = (NXGE_ERROR | npi_status);
1203859Sml29623 }
1213859Sml29623 nxgep->nports = nports;
1223859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_num_ports_get "
1236929Smisaki "ports [0x%x]", nports));
1243859Sml29623
1253859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_ports_get, "
1266929Smisaki "status [0x%x]", status));
1273859Sml29623
1283859Sml29623 return (status);
1293859Sml29623 }
1303859Sml29623
1313859Sml29623 nxge_status_t
nxge_espc_phy_type_get(p_nxge_t nxgep)1323859Sml29623 nxge_espc_phy_type_get(p_nxge_t nxgep)
1333859Sml29623 {
1343859Sml29623 nxge_status_t status = NXGE_OK;
1353859Sml29623 npi_status_t npi_status = NPI_SUCCESS;
1363859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
1373859Sml29623 uint8_t port_num = nxgep->mac.portnum;
1383859Sml29623 uint8_t phy_type;
1393859Sml29623
1403859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_phy_type_get, port[%d]",
1416929Smisaki port_num));
1423859Sml29623
1436929Smisaki npi_status = npi_espc_port_phy_type_get(handle, &phy_type, port_num);
1443859Sml29623 if (npi_status != NPI_SUCCESS) {
1453859Sml29623 status = (NXGE_ERROR | npi_status);
1463859Sml29623 goto exit;
1473859Sml29623 }
1483859Sml29623
1493859Sml29623 switch (phy_type) {
1503859Sml29623 case ESC_PHY_10G_FIBER:
1513859Sml29623 nxgep->mac.portmode = PORT_10G_FIBER;
1523859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
1533859Sml29623 break;
1543859Sml29623 case ESC_PHY_10G_COPPER:
1553859Sml29623 nxgep->mac.portmode = PORT_10G_COPPER;
1563859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
1573859Sml29623 break;
1583859Sml29623 case ESC_PHY_1G_FIBER:
1593859Sml29623 nxgep->mac.portmode = PORT_1G_FIBER;
1603859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
1613859Sml29623 break;
1623859Sml29623 case ESC_PHY_1G_COPPER:
1633859Sml29623 nxgep->mac.portmode = PORT_1G_COPPER;
1643859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
1653859Sml29623 break;
1663859Sml29623 case ESC_PHY_NONE:
1673859Sml29623 status = NXGE_ERROR;
1684185Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get:"
1696929Smisaki "No phy type set"));
1703859Sml29623 break;
1713859Sml29623 default:
1723859Sml29623 status = NXGE_ERROR;
1733859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get: "
1746929Smisaki "Unknown phy type [%d]", phy_type));
1753859Sml29623 break;
1763859Sml29623 }
1773859Sml29623
1783859Sml29623 exit:
1793859Sml29623
1803859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_phy_type_get, "
1816929Smisaki "status [0x%x]", status));
1823859Sml29623
1833859Sml29623 return (status);
1843859Sml29623 }
1853859Sml29623
1863859Sml29623 nxge_status_t
nxge_espc_max_frame_sz_get(p_nxge_t nxgep)1873859Sml29623 nxge_espc_max_frame_sz_get(p_nxge_t nxgep)
1883859Sml29623 {
1893859Sml29623 nxge_status_t status = NXGE_OK;
1903859Sml29623 npi_status_t npi_status = NPI_SUCCESS;
1913859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
1923859Sml29623
1933859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_max_frame_sz_get"));
1943859Sml29623
1953859Sml29623 npi_status = npi_espc_max_frame_get(handle, &nxgep->mac.maxframesize);
1963859Sml29623 if (npi_status != NPI_SUCCESS) {
1973859Sml29623 status = (NXGE_ERROR | npi_status);
1983859Sml29623 }
1993859Sml29623
2003859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_max_frame_sz_get, "
2016929Smisaki "status [0x%x]", status));
2023859Sml29623
2033859Sml29623 return (status);
2043859Sml29623 }
2054185Sspeer
2064977Sraghus void
nxge_vpd_info_get(p_nxge_t nxgep)2074185Sspeer nxge_vpd_info_get(p_nxge_t nxgep)
2084185Sspeer {
2094185Sspeer npi_status_t status;
2104185Sspeer npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep);
2114185Sspeer
2124977Sraghus if ((nxgep->platform_type == P_NEPTUNE_NIU) ||
2134977Sraghus (nxgep->platform_type == P_NEPTUNE_MARAMBA_P0) ||
2147801SSantwona.Behera@Sun.COM (nxgep->platform_type == P_NEPTUNE_MARAMBA_P1) ||
2157801SSantwona.Behera@Sun.COM (nxgep->platform_type == P_NEPTUNE_ROCK)) {
2164977Sraghus nxgep->vpd_info.present = B_FALSE;
2174977Sraghus return;
2184977Sraghus }
2194977Sraghus
2207801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, CFG_CTL, "nxge_vpd_info_get: "
2217801SSantwona.Behera@Sun.COM "nxgep->platform_type[%d]...reading vpd", nxgep->platform_type));
2227801SSantwona.Behera@Sun.COM
2234977Sraghus nxgep->vpd_info.present = B_TRUE;
2244977Sraghus nxgep->vpd_info.ver_valid = B_FALSE;
2254977Sraghus
2264185Sspeer MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock);
2274185Sspeer (void) npi_espc_pio_enable(handle);
2284185Sspeer status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info,
2294977Sraghus NXGE_EROM_LEN);
2304185Sspeer (void) npi_espc_pio_disable(handle);
2314185Sspeer MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock);
2324185Sspeer
2334977Sraghus if (status != NPI_SUCCESS)
2344977Sraghus return;
2354977Sraghus
2364977Sraghus nxge_check_vpd_version(nxgep);
2374977Sraghus if (!nxgep->vpd_info.ver_valid)
2384977Sraghus return;
2394977Sraghus
2404977Sraghus /* Determine the platform type */
2414977Sraghus if ((strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_LP_BM_STR,
2424977Sraghus strlen(NXGE_QGC_LP_BM_STR)) == 0) ||
2434977Sraghus (strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_PEM_BM_STR,
2444977Sraghus strlen(NXGE_QGC_PEM_BM_STR)) == 0)) {
2454977Sraghus nxgep->platform_type = P_NEPTUNE_ATLAS_4PORT;
2464977Sraghus } else if ((strncmp(nxgep->vpd_info.bd_model,
2474977Sraghus NXGE_2XGF_LP_BM_STR, strlen(NXGE_2XGF_LP_BM_STR)) == 0) ||
2484977Sraghus (strncmp(nxgep->vpd_info.bd_model, NXGE_2XGF_PEM_BM_STR,
2494977Sraghus strlen(NXGE_2XGF_PEM_BM_STR)) == 0)) {
2504977Sraghus nxgep->platform_type = P_NEPTUNE_ATLAS_2PORT;
2515196Ssbehera } else if (strncmp(nxgep->vpd_info.bd_model,
2525196Ssbehera NXGE_ALONSO_BM_STR, strlen(NXGE_ALONSO_BM_STR)) == 0) {
2535196Ssbehera nxgep->platform_type = P_NEPTUNE_ALONSO;
2546075Ssbehera } else if (strncmp(nxgep->vpd_info.bd_model,
2556075Ssbehera NXGE_RFEM_BM_STR, strlen(NXGE_RFEM_BM_STR)) == 0) {
2566075Ssbehera nxgep->hot_swappable_phy = B_TRUE;
257*10577SMichael.Speer@Sun.COM nxgep->platform_type = P_NEPTUNE_GENERIC;
258*10577SMichael.Speer@Sun.COM nxgep->niu_type = NEPTUNE_2_10GF;
2594977Sraghus }
2604977Sraghus
2615196Ssbehera /* If Alonso platform, replace "mif" for the last 2 ports phy-type */
2625196Ssbehera if ((nxgep->platform_type == P_NEPTUNE_ALONSO) &&
2635196Ssbehera ((nxgep->function_num == 2) || (nxgep->function_num == 3))) {
2645196Ssbehera (void) strcpy(nxgep->vpd_info.phy_type, "mif");
2655196Ssbehera }
2666261Sjoycey
2676261Sjoycey /* If ARTM card, replace "mif" for the last 2 ports phy-type */
2686261Sjoycey if ((strncmp(nxgep->vpd_info.bd_model,
2696261Sjoycey NXGE_ARTM_BM_STR, strlen(NXGE_ARTM_BM_STR)) == 0) &&
2706261Sjoycey ((nxgep->function_num == 2) || (nxgep->function_num == 3))) {
2716261Sjoycey NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL,
2726261Sjoycey "Replaced phy type as mif"));
2736261Sjoycey (void) strcpy(nxgep->vpd_info.phy_type, "mif");
2746261Sjoycey }
2754185Sspeer }
2764185Sspeer
2774977Sraghus static void
nxge_check_vpd_version(p_nxge_t nxgep)2784185Sspeer nxge_check_vpd_version(p_nxge_t nxgep)
2794185Sspeer {
2804185Sspeer int i, j;
2814185Sspeer const char *fcode_str = NXGE_FCODE_ID_STR;
2824185Sspeer int fcode_str_len = strlen(fcode_str);
2834185Sspeer char ver_num_str[NXGE_FCODE_VER_STR_LEN];
2844185Sspeer char *ver_num_w;
2854185Sspeer char *ver_num_f;
2864185Sspeer int ver_num_w_len = 0;
2874185Sspeer int ver_num_f_len = 0;
2884185Sspeer int ver_w = 0;
2894185Sspeer int ver_f = 0;
2904185Sspeer
2914185Sspeer nxgep->vpd_info.ver_valid = B_FALSE;
2924185Sspeer ver_num_str[0] = '\0';
2934185Sspeer
2944185Sspeer for (i = 0; i < NXGE_VPD_VER_LEN; i++) {
2954185Sspeer if (nxgep->vpd_info.ver[i] == fcode_str[0]) {
2964185Sspeer if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) >
2974185Sspeer NXGE_VPD_VER_LEN)
2984185Sspeer break;
2994185Sspeer for (j = 0; j < fcode_str_len; j++, i++) {
3004185Sspeer if (nxgep->vpd_info.ver[i] != fcode_str[j])
3014185Sspeer break;
3024185Sspeer }
3034185Sspeer if (j < fcode_str_len)
3044185Sspeer continue;
3054185Sspeer
3064185Sspeer /* found the Fcode version string */
3074185Sspeer for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) {
3084185Sspeer ver_num_str[j] = nxgep->vpd_info.ver[i];
3094185Sspeer if (ver_num_str[j] == ' ')
3104185Sspeer break;
3114185Sspeer }
3128661SSantwona.Behera@Sun.COM if (j < NXGE_FCODE_VER_STR_LEN)
3138661SSantwona.Behera@Sun.COM ver_num_str[j] = '\0';
3144185Sspeer break;
3154185Sspeer }
3164185Sspeer }
3174185Sspeer
3184185Sspeer ver_num_w = ver_num_str;
3194185Sspeer for (i = 0; i < strlen(ver_num_str); i++) {
3204185Sspeer if (ver_num_str[i] == '.') {
3214185Sspeer ver_num_f = &ver_num_str[i + 1];
3224185Sspeer ver_num_w_len = i;
3234185Sspeer ver_num_f_len = strlen(ver_num_str) - (i + 1);
3244185Sspeer break;
3254185Sspeer }
3264185Sspeer }
3274185Sspeer
3284185Sspeer for (i = 0; i < ver_num_w_len; i++) {
3294185Sspeer ver_w = (ver_w * 10) + (ver_num_w[i] - '0');
3304185Sspeer }
3314185Sspeer
3324185Sspeer for (i = 0; i < ver_num_f_len; i++) {
3334185Sspeer ver_f = (ver_f * 10) + (ver_num_f[i] - '0');
3344185Sspeer }
3354185Sspeer
3364185Sspeer if ((ver_w > NXGE_VPD_VALID_VER_W) ||
3374185Sspeer (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F))
3384185Sspeer nxgep->vpd_info.ver_valid = B_TRUE;
3394185Sspeer
3404185Sspeer }
341