Home | History | Annotate | Download | only in nxge
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <nxge_impl.h>
     27 #include <nxge_mac.h>
     28 #include <npi_espc.h>
     29 #include <nxge_espc.h>
     30 
     31 static void nxge_check_vpd_version(p_nxge_t nxgep);
     32 
     33 void
     34 nxge_espc_get_next_mac_addr(uint8_t *st_mac, uint8_t nxt_cnt,
     35 			    struct ether_addr *final_mac)
     36 {
     37 	uint64_t	mac[ETHERADDRL];
     38 	uint64_t	mac_addr = 0;
     39 	int		i, j;
     40 
     41 	for (i = ETHERADDRL - 1, j = 0; j < ETHERADDRL; i--, j++) {
     42 		mac[j] = st_mac[i];
     43 		mac_addr |= (mac[j] << (j*8));
     44 	}
     45 
     46 	mac_addr += nxt_cnt;
     47 
     48 	final_mac->ether_addr_octet[0] = (mac_addr & 0xff0000000000) >> 40;
     49 	final_mac->ether_addr_octet[1] = (mac_addr & 0xff00000000) >> 32;
     50 	final_mac->ether_addr_octet[2] = (mac_addr & 0xff000000) >> 24;
     51 	final_mac->ether_addr_octet[3] = (mac_addr & 0xff0000) >> 16;
     52 	final_mac->ether_addr_octet[4] = (mac_addr & 0xff00) >> 8;
     53 	final_mac->ether_addr_octet[5] = (mac_addr & 0xff);
     54 }
     55 
     56 nxge_status_t
     57 nxge_espc_mac_addrs_get(p_nxge_t nxgep)
     58 {
     59 	nxge_status_t	status = NXGE_OK;
     60 	npi_status_t	npi_status = NPI_SUCCESS;
     61 	uint8_t		port_num = nxgep->mac.portnum;
     62 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
     63 	uint8_t		mac_addr[ETHERADDRL];
     64 
     65 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
     66 	    "==> nxge_espc_mac_addr_get, port[%d]", port_num));
     67 
     68 	npi_status = npi_espc_mac_addr_get(handle, mac_addr);
     69 	if (npi_status != NPI_SUCCESS) {
     70 		status = (NXGE_ERROR | npi_status);
     71 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
     72 		    "nxge_espc_mac_addr_get, port[%d] failed", port_num));
     73 		goto exit;
     74 	}
     75 
     76 	nxge_espc_get_next_mac_addr(mac_addr, port_num, &nxgep->factaddr);
     77 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
     78 		    "Got MAC Addr: %2x:%2x:%2x:%2x:%2x%:%2x%c \n",
     79 		    mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
     80 		    mac_addr[4], mac_addr[5]));
     81 
     82 exit:
     83 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_mac_addr_get, "
     84 	    "status [0x%x]", status));
     85 
     86 	return (status);
     87 }
     88 
     89 nxge_status_t
     90 nxge_espc_num_macs_get(p_nxge_t nxgep, uint8_t *nmacs)
     91 {
     92 	nxge_status_t   status = NXGE_OK;
     93 	npi_status_t    npi_status = NPI_SUCCESS;
     94 	npi_handle_t    handle = NXGE_DEV_NPI_HANDLE(nxgep);
     95 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_macs_get"));
     96 
     97 	npi_status = npi_espc_num_macs_get(handle, nmacs);
     98 	if (npi_status != NPI_SUCCESS) {
     99 		status = (NXGE_ERROR | npi_status);
    100 	}
    101 
    102 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_macs_get, "
    103 	    "status [0x%x]", status));
    104 
    105 	return (status);
    106 }
    107 
    108 nxge_status_t
    109 nxge_espc_num_ports_get(p_nxge_t nxgep)
    110 {
    111 	nxge_status_t	status = NXGE_OK;
    112 	npi_status_t	npi_status = NPI_SUCCESS;
    113 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
    114 	uint8_t		nports = 0;
    115 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_ports_get"));
    116 
    117 	npi_status = npi_espc_num_ports_get(handle, &nports);
    118 	if (npi_status != NPI_SUCCESS) {
    119 		status = (NXGE_ERROR | npi_status);
    120 	}
    121 	nxgep->nports = nports;
    122 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_num_ports_get "
    123 	    "ports [0x%x]", nports));
    124 
    125 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_ports_get, "
    126 	    "status [0x%x]", status));
    127 
    128 	return (status);
    129 }
    130 
    131 nxge_status_t
    132 nxge_espc_phy_type_get(p_nxge_t nxgep)
    133 {
    134 	nxge_status_t	status = NXGE_OK;
    135 	npi_status_t	npi_status = NPI_SUCCESS;
    136 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
    137 	uint8_t		port_num = nxgep->mac.portnum;
    138 	uint8_t		phy_type;
    139 
    140 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_phy_type_get, port[%d]",
    141 	    port_num));
    142 
    143 	npi_status = npi_espc_port_phy_type_get(handle, &phy_type, port_num);
    144 	if (npi_status != NPI_SUCCESS) {
    145 		status = (NXGE_ERROR | npi_status);
    146 		goto exit;
    147 	}
    148 
    149 	switch (phy_type) {
    150 	case ESC_PHY_10G_FIBER:
    151 		nxgep->mac.portmode = PORT_10G_FIBER;
    152 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    153 		break;
    154 	case ESC_PHY_10G_COPPER:
    155 		nxgep->mac.portmode = PORT_10G_COPPER;
    156 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    157 		break;
    158 	case ESC_PHY_1G_FIBER:
    159 		nxgep->mac.portmode = PORT_1G_FIBER;
    160 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    161 		break;
    162 	case ESC_PHY_1G_COPPER:
    163 		nxgep->mac.portmode = PORT_1G_COPPER;
    164 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
    165 		break;
    166 	case ESC_PHY_NONE:
    167 		status = NXGE_ERROR;
    168 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get:"
    169 		    "No phy type set"));
    170 		break;
    171 	default:
    172 		status = NXGE_ERROR;
    173 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get: "
    174 		    "Unknown phy type [%d]", phy_type));
    175 		break;
    176 	}
    177 
    178 exit:
    179 
    180 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_phy_type_get, "
    181 	    "status [0x%x]", status));
    182 
    183 	return (status);
    184 }
    185 
    186 nxge_status_t
    187 nxge_espc_max_frame_sz_get(p_nxge_t nxgep)
    188 {
    189 	nxge_status_t	status = NXGE_OK;
    190 	npi_status_t	npi_status = NPI_SUCCESS;
    191 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
    192 
    193 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_max_frame_sz_get"));
    194 
    195 	npi_status = npi_espc_max_frame_get(handle, &nxgep->mac.maxframesize);
    196 	if (npi_status != NPI_SUCCESS) {
    197 		status = (NXGE_ERROR | npi_status);
    198 	}
    199 
    200 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_max_frame_sz_get, "
    201 	    "status [0x%x]", status));
    202 
    203 	return (status);
    204 }
    205 
    206 void
    207 nxge_vpd_info_get(p_nxge_t nxgep)
    208 {
    209 	npi_status_t	status;
    210 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
    211 
    212 	if ((nxgep->platform_type == P_NEPTUNE_NIU) ||
    213 	    (nxgep->platform_type == P_NEPTUNE_MARAMBA_P0) ||
    214 	    (nxgep->platform_type == P_NEPTUNE_MARAMBA_P1) ||
    215 	    (nxgep->platform_type == P_NEPTUNE_ROCK)) {
    216 		nxgep->vpd_info.present = B_FALSE;
    217 		return;
    218 	}
    219 
    220 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "nxge_vpd_info_get: "
    221 	    "nxgep->platform_type[%d]...reading vpd", nxgep->platform_type));
    222 
    223 	nxgep->vpd_info.present = B_TRUE;
    224 	nxgep->vpd_info.ver_valid = B_FALSE;
    225 
    226 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock);
    227 	(void) npi_espc_pio_enable(handle);
    228 	status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info,
    229 	    NXGE_EROM_LEN);
    230 	(void) npi_espc_pio_disable(handle);
    231 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock);
    232 
    233 	if (status != NPI_SUCCESS)
    234 		return;
    235 
    236 	nxge_check_vpd_version(nxgep);
    237 	if (!nxgep->vpd_info.ver_valid)
    238 		return;
    239 
    240 	/* Determine the platform type */
    241 	if ((strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_LP_BM_STR,
    242 	    strlen(NXGE_QGC_LP_BM_STR)) == 0) ||
    243 	    (strncmp(nxgep->vpd_info.bd_model, NXGE_QGC_PEM_BM_STR,
    244 	    strlen(NXGE_QGC_PEM_BM_STR)) == 0)) {
    245 		nxgep->platform_type = P_NEPTUNE_ATLAS_4PORT;
    246 	} else if ((strncmp(nxgep->vpd_info.bd_model,
    247 	    NXGE_2XGF_LP_BM_STR, strlen(NXGE_2XGF_LP_BM_STR)) == 0) ||
    248 	    (strncmp(nxgep->vpd_info.bd_model, NXGE_2XGF_PEM_BM_STR,
    249 	    strlen(NXGE_2XGF_PEM_BM_STR)) == 0)) {
    250 		nxgep->platform_type = P_NEPTUNE_ATLAS_2PORT;
    251 	} else if (strncmp(nxgep->vpd_info.bd_model,
    252 	    NXGE_ALONSO_BM_STR, strlen(NXGE_ALONSO_BM_STR)) == 0) {
    253 		nxgep->platform_type = P_NEPTUNE_ALONSO;
    254 	} else if (strncmp(nxgep->vpd_info.bd_model,
    255 	    NXGE_RFEM_BM_STR, strlen(NXGE_RFEM_BM_STR)) == 0) {
    256 		nxgep->hot_swappable_phy = B_TRUE;
    257 		nxgep->platform_type = P_NEPTUNE_GENERIC;
    258 		nxgep->niu_type = NEPTUNE_2_10GF;
    259 	}
    260 
    261 	/* If Alonso platform, replace "mif" for the last 2 ports phy-type */
    262 	if ((nxgep->platform_type == P_NEPTUNE_ALONSO) &&
    263 	    ((nxgep->function_num == 2) || (nxgep->function_num == 3))) {
    264 		(void) strcpy(nxgep->vpd_info.phy_type, "mif");
    265 	}
    266 
    267 	/* If ARTM card, replace "mif" for the last 2 ports phy-type */
    268 	if ((strncmp(nxgep->vpd_info.bd_model,
    269 	    NXGE_ARTM_BM_STR, strlen(NXGE_ARTM_BM_STR)) == 0) &&
    270 	    ((nxgep->function_num == 2) || (nxgep->function_num == 3))) {
    271 		NXGE_DEBUG_MSG((nxgep, NXGE_ERR_CTL,
    272 		    "Replaced phy type as mif"));
    273 		(void) strcpy(nxgep->vpd_info.phy_type, "mif");
    274 	}
    275 }
    276 
    277 static void
    278 nxge_check_vpd_version(p_nxge_t nxgep)
    279 {
    280 	int		i, j;
    281 	const char	*fcode_str = NXGE_FCODE_ID_STR;
    282 	int		fcode_str_len = strlen(fcode_str);
    283 	char		ver_num_str[NXGE_FCODE_VER_STR_LEN];
    284 	char		*ver_num_w;
    285 	char		*ver_num_f;
    286 	int		ver_num_w_len = 0;
    287 	int		ver_num_f_len = 0;
    288 	int		ver_w = 0;
    289 	int		ver_f = 0;
    290 
    291 	nxgep->vpd_info.ver_valid = B_FALSE;
    292 	ver_num_str[0] = '\0';
    293 
    294 	for (i = 0; i < NXGE_VPD_VER_LEN; i++) {
    295 		if (nxgep->vpd_info.ver[i] == fcode_str[0]) {
    296 			if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) >
    297 			    NXGE_VPD_VER_LEN)
    298 				break;
    299 			for (j = 0; j < fcode_str_len; j++, i++) {
    300 				if (nxgep->vpd_info.ver[i] != fcode_str[j])
    301 					break;
    302 			}
    303 			if (j < fcode_str_len)
    304 				continue;
    305 
    306 			/* found the Fcode version string */
    307 			for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) {
    308 				ver_num_str[j] = nxgep->vpd_info.ver[i];
    309 				if (ver_num_str[j] == ' ')
    310 					break;
    311 			}
    312 			if (j < NXGE_FCODE_VER_STR_LEN)
    313 				ver_num_str[j] = '\0';
    314 			break;
    315 		}
    316 	}
    317 
    318 	ver_num_w = ver_num_str;
    319 	for (i = 0; i < strlen(ver_num_str); i++) {
    320 		if (ver_num_str[i] == '.') {
    321 			ver_num_f = &ver_num_str[i + 1];
    322 			ver_num_w_len = i;
    323 			ver_num_f_len = strlen(ver_num_str) - (i + 1);
    324 			break;
    325 		}
    326 	}
    327 
    328 	for (i = 0; i < ver_num_w_len; i++) {
    329 		ver_w = (ver_w * 10) + (ver_num_w[i] - '0');
    330 	}
    331 
    332 	for (i = 0; i < ver_num_f_len; i++) {
    333 		ver_f = (ver_f * 10) + (ver_num_f[i] - '0');
    334 	}
    335 
    336 	if ((ver_w > NXGE_VPD_VALID_VER_W) ||
    337 	    (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F))
    338 		nxgep->vpd_info.ver_valid = B_TRUE;
    339 
    340 }
    341