xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_espc.c (revision 4185:f1a68afd98ff)
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 /*
22*4185Sspeer  * 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*4185Sspeer static nxge_status_t nxge_check_vpd_version(p_nxge_t nxgep);
343859Sml29623 
35*4185Sspeer 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);
81*4185Sspeer 		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;
174*4185Sspeer 		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 }
211*4185Sspeer 
212*4185Sspeer nxge_status_t
213*4185Sspeer nxge_vpd_info_get(p_nxge_t nxgep)
214*4185Sspeer {
215*4185Sspeer 	npi_status_t	status;
216*4185Sspeer 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
217*4185Sspeer 
218*4185Sspeer 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock);
219*4185Sspeer 	(void) npi_espc_pio_enable(handle);
220*4185Sspeer 	status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info,
221*4185Sspeer 				NXGE_EROM_LEN);
222*4185Sspeer 	(void) npi_espc_pio_disable(handle);
223*4185Sspeer 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock);
224*4185Sspeer 
225*4185Sspeer 	nxgep->vpd_info.ver_valid = B_FALSE;
226*4185Sspeer 	if (status == NPI_SUCCESS) {
227*4185Sspeer 		(void) nxge_check_vpd_version(nxgep);
228*4185Sspeer 		return (NXGE_OK);
229*4185Sspeer 	} else
230*4185Sspeer 		return (NXGE_ERROR);
231*4185Sspeer }
232*4185Sspeer 
233*4185Sspeer static nxge_status_t
234*4185Sspeer nxge_check_vpd_version(p_nxge_t nxgep)
235*4185Sspeer {
236*4185Sspeer 	int		i, j;
237*4185Sspeer 	nxge_status_t	status = NXGE_OK;
238*4185Sspeer 	const char	*fcode_str = NXGE_FCODE_ID_STR;
239*4185Sspeer 	int		fcode_str_len = strlen(fcode_str);
240*4185Sspeer 	char		ver_num_str[NXGE_FCODE_VER_STR_LEN];
241*4185Sspeer 	char		*ver_num_w;
242*4185Sspeer 	char		*ver_num_f;
243*4185Sspeer 	int		ver_num_w_len = 0;
244*4185Sspeer 	int		ver_num_f_len = 0;
245*4185Sspeer 	int		ver_w = 0;
246*4185Sspeer 	int		ver_f = 0;
247*4185Sspeer 
248*4185Sspeer 	nxgep->vpd_info.ver_valid = B_FALSE;
249*4185Sspeer 	ver_num_str[0] = '\0';
250*4185Sspeer 
251*4185Sspeer 	for (i = 0; i < NXGE_VPD_VER_LEN; i++) {
252*4185Sspeer 		if (nxgep->vpd_info.ver[i] == fcode_str[0]) {
253*4185Sspeer 			if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) >
254*4185Sspeer 			    NXGE_VPD_VER_LEN)
255*4185Sspeer 				break;
256*4185Sspeer 			for (j = 0; j < fcode_str_len; j++, i++) {
257*4185Sspeer 				if (nxgep->vpd_info.ver[i] != fcode_str[j])
258*4185Sspeer 					break;
259*4185Sspeer 			}
260*4185Sspeer 			if (j < fcode_str_len)
261*4185Sspeer 				continue;
262*4185Sspeer 
263*4185Sspeer 			/* found the Fcode version string */
264*4185Sspeer 			for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) {
265*4185Sspeer 				ver_num_str[j] = nxgep->vpd_info.ver[i];
266*4185Sspeer 				if (ver_num_str[j] == ' ')
267*4185Sspeer 					break;
268*4185Sspeer 			}
269*4185Sspeer 			ver_num_str[j] = '\0';
270*4185Sspeer 			break;
271*4185Sspeer 		}
272*4185Sspeer 	}
273*4185Sspeer 
274*4185Sspeer 	ver_num_w = ver_num_str;
275*4185Sspeer 	for (i = 0; i < strlen(ver_num_str); i++) {
276*4185Sspeer 		if (ver_num_str[i] == '.') {
277*4185Sspeer 			ver_num_f = &ver_num_str[i + 1];
278*4185Sspeer 			ver_num_w_len = i;
279*4185Sspeer 			ver_num_f_len = strlen(ver_num_str) - (i + 1);
280*4185Sspeer 			break;
281*4185Sspeer 		}
282*4185Sspeer 	}
283*4185Sspeer 
284*4185Sspeer 	for (i = 0; i < ver_num_w_len; i++) {
285*4185Sspeer 		ver_w = (ver_w * 10) + (ver_num_w[i] - '0');
286*4185Sspeer 	}
287*4185Sspeer 
288*4185Sspeer 	for (i = 0; i < ver_num_f_len; i++) {
289*4185Sspeer 		ver_f = (ver_f * 10) + (ver_num_f[i] - '0');
290*4185Sspeer 	}
291*4185Sspeer 
292*4185Sspeer 	if ((ver_w > NXGE_VPD_VALID_VER_W) ||
293*4185Sspeer 	    (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F))
294*4185Sspeer 		nxgep->vpd_info.ver_valid = B_TRUE;
295*4185Sspeer 
296*4185Sspeer 	return (status);
297*4185Sspeer }
298