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 /* 226075Ssbehera * Copyright 2008 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 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 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 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 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 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 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 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) || 214*7801SSantwona.Behera@Sun.COM (nxgep->platform_type == P_NEPTUNE_MARAMBA_P1) || 215*7801SSantwona.Behera@Sun.COM (nxgep->platform_type == P_NEPTUNE_ROCK)) { 2164977Sraghus nxgep->vpd_info.present = B_FALSE; 2174977Sraghus return; 2184977Sraghus } 2194977Sraghus 220*7801SSantwona.Behera@Sun.COM NXGE_DEBUG_MSG((nxgep, CFG_CTL, "nxge_vpd_info_get: " 221*7801SSantwona.Behera@Sun.COM "nxgep->platform_type[%d]...reading vpd", nxgep->platform_type)); 222*7801SSantwona.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; 2574977Sraghus } 2584977Sraghus 2595196Ssbehera /* If Alonso platform, replace "mif" for the last 2 ports phy-type */ 2605196Ssbehera if ((nxgep->platform_type == P_NEPTUNE_ALONSO) && 2615196Ssbehera ((nxgep->function_num == 2) || (nxgep->function_num == 3))) { 2625196Ssbehera (void) strcpy(nxgep->vpd_info.phy_type, "mif"); 2635196Ssbehera } 2646261Sjoycey 2656261Sjoycey /* If ARTM card, replace "mif" for the last 2 ports phy-type */ 2666261Sjoycey if ((strncmp(nxgep->vpd_info.bd_model, 2676261Sjoycey NXGE_ARTM_BM_STR, strlen(NXGE_ARTM_BM_STR)) == 0) && 2686261Sjoycey ((nxgep->function_num == 2) || (nxgep->function_num == 3))) { 2696261Sjoycey NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL, 2706261Sjoycey "Replaced phy type as mif")); 2716261Sjoycey (void) strcpy(nxgep->vpd_info.phy_type, "mif"); 2726261Sjoycey } 2734185Sspeer } 2744185Sspeer 2754977Sraghus static void 2764185Sspeer nxge_check_vpd_version(p_nxge_t nxgep) 2774185Sspeer { 2784185Sspeer int i, j; 2794185Sspeer const char *fcode_str = NXGE_FCODE_ID_STR; 2804185Sspeer int fcode_str_len = strlen(fcode_str); 2814185Sspeer char ver_num_str[NXGE_FCODE_VER_STR_LEN]; 2824185Sspeer char *ver_num_w; 2834185Sspeer char *ver_num_f; 2844185Sspeer int ver_num_w_len = 0; 2854185Sspeer int ver_num_f_len = 0; 2864185Sspeer int ver_w = 0; 2874185Sspeer int ver_f = 0; 2884185Sspeer 2894185Sspeer nxgep->vpd_info.ver_valid = B_FALSE; 2904185Sspeer ver_num_str[0] = '\0'; 2914185Sspeer 2924185Sspeer for (i = 0; i < NXGE_VPD_VER_LEN; i++) { 2934185Sspeer if (nxgep->vpd_info.ver[i] == fcode_str[0]) { 2944185Sspeer if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) > 2954185Sspeer NXGE_VPD_VER_LEN) 2964185Sspeer break; 2974185Sspeer for (j = 0; j < fcode_str_len; j++, i++) { 2984185Sspeer if (nxgep->vpd_info.ver[i] != fcode_str[j]) 2994185Sspeer break; 3004185Sspeer } 3014185Sspeer if (j < fcode_str_len) 3024185Sspeer continue; 3034185Sspeer 3044185Sspeer /* found the Fcode version string */ 3054185Sspeer for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) { 3064185Sspeer ver_num_str[j] = nxgep->vpd_info.ver[i]; 3074185Sspeer if (ver_num_str[j] == ' ') 3084185Sspeer break; 3094185Sspeer } 3104185Sspeer ver_num_str[j] = '\0'; 3114185Sspeer break; 3124185Sspeer } 3134185Sspeer } 3144185Sspeer 3154185Sspeer ver_num_w = ver_num_str; 3164185Sspeer for (i = 0; i < strlen(ver_num_str); i++) { 3174185Sspeer if (ver_num_str[i] == '.') { 3184185Sspeer ver_num_f = &ver_num_str[i + 1]; 3194185Sspeer ver_num_w_len = i; 3204185Sspeer ver_num_f_len = strlen(ver_num_str) - (i + 1); 3214185Sspeer break; 3224185Sspeer } 3234185Sspeer } 3244185Sspeer 3254185Sspeer for (i = 0; i < ver_num_w_len; i++) { 3264185Sspeer ver_w = (ver_w * 10) + (ver_num_w[i] - '0'); 3274185Sspeer } 3284185Sspeer 3294185Sspeer for (i = 0; i < ver_num_f_len; i++) { 3304185Sspeer ver_f = (ver_f * 10) + (ver_num_f[i] - '0'); 3314185Sspeer } 3324185Sspeer 3334185Sspeer if ((ver_w > NXGE_VPD_VALID_VER_W) || 3344185Sspeer (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F)) 3354185Sspeer nxgep->vpd_info.ver_valid = B_TRUE; 3364185Sspeer 3374185Sspeer } 338