xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_espc.c (revision 4977:6ff1c7caf2c9)
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