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 /* 224185Sspeer * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 233859Sml29623 * Use is subject to license terms. 243859Sml29623 */ 253859Sml29623 263859Sml29623 #pragma ident "%Z%%M% %I% %E% SMI" 273859Sml29623 283859Sml29623 #include <nxge_impl.h> 293859Sml29623 #include <nxge_mac.h> 303859Sml29623 #include <npi_espc.h> 313859Sml29623 #include <nxge_espc.h> 323859Sml29623 33*4977Sraghus static void nxge_check_vpd_version(p_nxge_t nxgep); 343859Sml29623 354185Sspeer void 363859Sml29623 nxge_espc_get_next_mac_addr(uint8_t *st_mac, uint8_t nxt_cnt, 373859Sml29623 struct ether_addr *final_mac) 383859Sml29623 { 393859Sml29623 uint64_t mac[ETHERADDRL]; 403859Sml29623 uint64_t mac_addr = 0; 413859Sml29623 int i, j; 423859Sml29623 433859Sml29623 for (i = ETHERADDRL - 1, j = 0; j < ETHERADDRL; i--, j++) { 443859Sml29623 mac[j] = st_mac[i]; 453859Sml29623 mac_addr |= (mac[j] << (j*8)); 463859Sml29623 } 473859Sml29623 483859Sml29623 mac_addr += nxt_cnt; 493859Sml29623 503859Sml29623 final_mac->ether_addr_octet[0] = (mac_addr & 0xff0000000000) >> 40; 513859Sml29623 final_mac->ether_addr_octet[1] = (mac_addr & 0xff00000000) >> 32; 523859Sml29623 final_mac->ether_addr_octet[2] = (mac_addr & 0xff000000) >> 24; 533859Sml29623 final_mac->ether_addr_octet[3] = (mac_addr & 0xff0000) >> 16; 543859Sml29623 final_mac->ether_addr_octet[4] = (mac_addr & 0xff00) >> 8; 553859Sml29623 final_mac->ether_addr_octet[5] = (mac_addr & 0xff); 563859Sml29623 } 573859Sml29623 583859Sml29623 nxge_status_t 593859Sml29623 nxge_espc_mac_addrs_get(p_nxge_t nxgep) 603859Sml29623 { 613859Sml29623 nxge_status_t status = NXGE_OK; 623859Sml29623 npi_status_t npi_status = NPI_SUCCESS; 633859Sml29623 uint8_t port_num = nxgep->mac.portnum; 643859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 653859Sml29623 uint8_t mac_addr[ETHERADDRL]; 663859Sml29623 673859Sml29623 NXGE_DEBUG_MSG((nxgep, MAC_CTL, 683859Sml29623 "==> nxge_espc_mac_addr_get, port[%d]", 693859Sml29623 port_num)); 703859Sml29623 713859Sml29623 npi_status = npi_espc_mac_addr_get(handle, mac_addr); 723859Sml29623 if (npi_status != NPI_SUCCESS) { 733859Sml29623 status = (NXGE_ERROR | npi_status); 743859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 753859Sml29623 "nxge_espc_mac_addr_get, port[%d] failed", 763859Sml29623 port_num)); 773859Sml29623 goto exit; 783859Sml29623 } 793859Sml29623 803859Sml29623 nxge_espc_get_next_mac_addr(mac_addr, port_num, &nxgep->factaddr); 814185Sspeer NXGE_DEBUG_MSG((nxgep, CFG_CTL, 823859Sml29623 "Got MAC Addr: %2x:%2x:%2x:%2x:%2x%:%2x%c \n", 833859Sml29623 mac_addr[0], mac_addr[1], 843859Sml29623 mac_addr[2], mac_addr[3], 853859Sml29623 mac_addr[4], mac_addr[5])); 863859Sml29623 873859Sml29623 exit: 883859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_mac_addr_get, " 893859Sml29623 "status [0x%x]", status)); 903859Sml29623 913859Sml29623 return (status); 923859Sml29623 } 933859Sml29623 943859Sml29623 nxge_status_t 953859Sml29623 nxge_espc_num_macs_get(p_nxge_t nxgep, uint8_t *nmacs) 963859Sml29623 { 973859Sml29623 nxge_status_t status = NXGE_OK; 983859Sml29623 npi_status_t npi_status = NPI_SUCCESS; 993859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 1003859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_macs_get")); 1013859Sml29623 1023859Sml29623 npi_status = npi_espc_num_macs_get(handle, nmacs); 1033859Sml29623 if (npi_status != NPI_SUCCESS) { 1043859Sml29623 status = (NXGE_ERROR | npi_status); 1053859Sml29623 } 1063859Sml29623 1073859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_macs_get, " 1083859Sml29623 "status [0x%x]", status)); 1093859Sml29623 1103859Sml29623 return (status); 1113859Sml29623 } 1123859Sml29623 1133859Sml29623 nxge_status_t 1143859Sml29623 nxge_espc_num_ports_get(p_nxge_t nxgep) 1153859Sml29623 { 1163859Sml29623 nxge_status_t status = NXGE_OK; 1173859Sml29623 npi_status_t npi_status = NPI_SUCCESS; 1183859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 1193859Sml29623 uint8_t nports = 0; 1203859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_ports_get")); 1213859Sml29623 1223859Sml29623 npi_status = npi_espc_num_ports_get(handle, &nports); 1233859Sml29623 if (npi_status != NPI_SUCCESS) { 1243859Sml29623 status = (NXGE_ERROR | npi_status); 1253859Sml29623 } 1263859Sml29623 nxgep->nports = nports; 1273859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_num_ports_get " 1283859Sml29623 "ports [0x%x]", nports)); 1293859Sml29623 1303859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_ports_get, " 1313859Sml29623 "status [0x%x]", status)); 1323859Sml29623 1333859Sml29623 return (status); 1343859Sml29623 } 1353859Sml29623 1363859Sml29623 nxge_status_t 1373859Sml29623 nxge_espc_phy_type_get(p_nxge_t nxgep) 1383859Sml29623 { 1393859Sml29623 nxge_status_t status = NXGE_OK; 1403859Sml29623 npi_status_t npi_status = NPI_SUCCESS; 1413859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 1423859Sml29623 uint8_t port_num = nxgep->mac.portnum; 1433859Sml29623 uint8_t phy_type; 1443859Sml29623 1453859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_phy_type_get, port[%d]", 1463859Sml29623 port_num)); 1473859Sml29623 1483859Sml29623 npi_status = npi_espc_port_phy_type_get(handle, &phy_type, 1493859Sml29623 port_num); 1503859Sml29623 if (npi_status != NPI_SUCCESS) { 1513859Sml29623 status = (NXGE_ERROR | npi_status); 1523859Sml29623 goto exit; 1533859Sml29623 } 1543859Sml29623 1553859Sml29623 switch (phy_type) { 1563859Sml29623 case ESC_PHY_10G_FIBER: 1573859Sml29623 nxgep->mac.portmode = PORT_10G_FIBER; 1583859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 1593859Sml29623 break; 1603859Sml29623 case ESC_PHY_10G_COPPER: 1613859Sml29623 nxgep->mac.portmode = PORT_10G_COPPER; 1623859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR; 1633859Sml29623 break; 1643859Sml29623 case ESC_PHY_1G_FIBER: 1653859Sml29623 nxgep->mac.portmode = PORT_1G_FIBER; 1663859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR; 1673859Sml29623 break; 1683859Sml29623 case ESC_PHY_1G_COPPER: 1693859Sml29623 nxgep->mac.portmode = PORT_1G_COPPER; 1703859Sml29623 nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR; 1713859Sml29623 break; 1723859Sml29623 case ESC_PHY_NONE: 1733859Sml29623 status = NXGE_ERROR; 1744185Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get:" 1753859Sml29623 "No phy type set")); 1763859Sml29623 break; 1773859Sml29623 default: 1783859Sml29623 status = NXGE_ERROR; 1793859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get: " 1803859Sml29623 "Unknown phy type [%d]", phy_type)); 1813859Sml29623 break; 1823859Sml29623 } 1833859Sml29623 1843859Sml29623 exit: 1853859Sml29623 1863859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_phy_type_get, " 1873859Sml29623 "status [0x%x]", status)); 1883859Sml29623 1893859Sml29623 return (status); 1903859Sml29623 } 1913859Sml29623 1923859Sml29623 nxge_status_t 1933859Sml29623 nxge_espc_max_frame_sz_get(p_nxge_t nxgep) 1943859Sml29623 { 1953859Sml29623 nxge_status_t status = NXGE_OK; 1963859Sml29623 npi_status_t npi_status = NPI_SUCCESS; 1973859Sml29623 npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 1983859Sml29623 1993859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_max_frame_sz_get")); 2003859Sml29623 2013859Sml29623 npi_status = npi_espc_max_frame_get(handle, &nxgep->mac.maxframesize); 2023859Sml29623 if (npi_status != NPI_SUCCESS) { 2033859Sml29623 status = (NXGE_ERROR | npi_status); 2043859Sml29623 } 2053859Sml29623 2063859Sml29623 NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_max_frame_sz_get, " 2073859Sml29623 "status [0x%x]", status)); 2083859Sml29623 2093859Sml29623 return (status); 2103859Sml29623 } 2114185Sspeer 212*4977Sraghus void 2134185Sspeer nxge_vpd_info_get(p_nxge_t nxgep) 2144185Sspeer { 2154185Sspeer npi_status_t status; 2164185Sspeer npi_handle_t handle = NXGE_DEV_NPI_HANDLE(nxgep); 2174185Sspeer 218*4977Sraghus if ((nxgep->platform_type == P_NEPTUNE_NIU) || 219*4977Sraghus (nxgep->platform_type == P_NEPTUNE_MARAMBA_P0) || 220*4977Sraghus (nxgep->platform_type == P_NEPTUNE_MARAMBA_P1)) { 221*4977Sraghus nxgep->vpd_info.present = B_FALSE; 222*4977Sraghus return; 223*4977Sraghus } 224*4977Sraghus 225*4977Sraghus nxgep->vpd_info.present = B_TRUE; 226*4977Sraghus nxgep->vpd_info.ver_valid = B_FALSE; 227*4977Sraghus 2284185Sspeer MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock); 2294185Sspeer (void) npi_espc_pio_enable(handle); 2304185Sspeer status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info, 231*4977Sraghus NXGE_EROM_LEN); 2324185Sspeer (void) npi_espc_pio_disable(handle); 2334185Sspeer MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock); 2344185Sspeer 235*4977Sraghus if (status != NPI_SUCCESS) 236*4977Sraghus return; 237*4977Sraghus 238*4977Sraghus nxge_check_vpd_version(nxgep); 239*4977Sraghus if (!nxgep->vpd_info.ver_valid) 240*4977Sraghus return; 241*4977Sraghus 242*4977Sraghus /* Determine the platform type */ 243*4977Sraghus if ((strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_LP_BM_STR, 244*4977Sraghus strlen(NXGE_QGC_LP_BM_STR)) == 0) || 245*4977Sraghus (strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_PEM_BM_STR, 246*4977Sraghus strlen(NXGE_QGC_PEM_BM_STR)) == 0)) { 247*4977Sraghus nxgep->platform_type = P_NEPTUNE_ATLAS_4PORT; 248*4977Sraghus } else if ((strncmp(nxgep->vpd_info.bd_model, 249*4977Sraghus NXGE_2XGF_LP_BM_STR, strlen(NXGE_2XGF_LP_BM_STR)) == 0) || 250*4977Sraghus (strncmp(nxgep->vpd_info.bd_model, NXGE_2XGF_PEM_BM_STR, 251*4977Sraghus strlen(NXGE_2XGF_PEM_BM_STR)) == 0)) { 252*4977Sraghus nxgep->platform_type = P_NEPTUNE_ATLAS_2PORT; 253*4977Sraghus } 254*4977Sraghus 2554185Sspeer } 2564185Sspeer 257*4977Sraghus static void 2584185Sspeer nxge_check_vpd_version(p_nxge_t nxgep) 2594185Sspeer { 2604185Sspeer int i, j; 2614185Sspeer const char *fcode_str = NXGE_FCODE_ID_STR; 2624185Sspeer int fcode_str_len = strlen(fcode_str); 2634185Sspeer char ver_num_str[NXGE_FCODE_VER_STR_LEN]; 2644185Sspeer char *ver_num_w; 2654185Sspeer char *ver_num_f; 2664185Sspeer int ver_num_w_len = 0; 2674185Sspeer int ver_num_f_len = 0; 2684185Sspeer int ver_w = 0; 2694185Sspeer int ver_f = 0; 2704185Sspeer 2714185Sspeer nxgep->vpd_info.ver_valid = B_FALSE; 2724185Sspeer ver_num_str[0] = '\0'; 2734185Sspeer 2744185Sspeer for (i = 0; i < NXGE_VPD_VER_LEN; i++) { 2754185Sspeer if (nxgep->vpd_info.ver[i] == fcode_str[0]) { 2764185Sspeer if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) > 2774185Sspeer NXGE_VPD_VER_LEN) 2784185Sspeer break; 2794185Sspeer for (j = 0; j < fcode_str_len; j++, i++) { 2804185Sspeer if (nxgep->vpd_info.ver[i] != fcode_str[j]) 2814185Sspeer break; 2824185Sspeer } 2834185Sspeer if (j < fcode_str_len) 2844185Sspeer continue; 2854185Sspeer 2864185Sspeer /* found the Fcode version string */ 2874185Sspeer for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) { 2884185Sspeer ver_num_str[j] = nxgep->vpd_info.ver[i]; 2894185Sspeer if (ver_num_str[j] == ' ') 2904185Sspeer break; 2914185Sspeer } 2924185Sspeer ver_num_str[j] = '\0'; 2934185Sspeer break; 2944185Sspeer } 2954185Sspeer } 2964185Sspeer 2974185Sspeer ver_num_w = ver_num_str; 2984185Sspeer for (i = 0; i < strlen(ver_num_str); i++) { 2994185Sspeer if (ver_num_str[i] == '.') { 3004185Sspeer ver_num_f = &ver_num_str[i + 1]; 3014185Sspeer ver_num_w_len = i; 3024185Sspeer ver_num_f_len = strlen(ver_num_str) - (i + 1); 3034185Sspeer break; 3044185Sspeer } 3054185Sspeer } 3064185Sspeer 3074185Sspeer for (i = 0; i < ver_num_w_len; i++) { 3084185Sspeer ver_w = (ver_w * 10) + (ver_num_w[i] - '0'); 3094185Sspeer } 3104185Sspeer 3114185Sspeer for (i = 0; i < ver_num_f_len; i++) { 3124185Sspeer ver_f = (ver_f * 10) + (ver_num_f[i] - '0'); 3134185Sspeer } 3144185Sspeer 3154185Sspeer if ((ver_w > NXGE_VPD_VALID_VER_W) || 3164185Sspeer (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F)) 3174185Sspeer nxgep->vpd_info.ver_valid = B_TRUE; 3184185Sspeer 3194185Sspeer } 320