xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_espc.c (revision f48205be61a214698b763ff550ab9e657525104c)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <nxge_impl.h>
29 #include <nxge_mac.h>
30 #include <npi_espc.h>
31 #include <nxge_espc.h>
32 
33 static nxge_status_t nxge_check_vpd_version(p_nxge_t nxgep);
34 
35 void
36 nxge_espc_get_next_mac_addr(uint8_t *st_mac, uint8_t nxt_cnt,
37 			    struct ether_addr *final_mac)
38 {
39 	uint64_t	mac[ETHERADDRL];
40 	uint64_t	mac_addr = 0;
41 	int		i, j;
42 
43 	for (i = ETHERADDRL - 1, j = 0; j < ETHERADDRL; i--, j++) {
44 		mac[j] = st_mac[i];
45 		mac_addr |= (mac[j] << (j*8));
46 	}
47 
48 	mac_addr += nxt_cnt;
49 
50 	final_mac->ether_addr_octet[0] = (mac_addr & 0xff0000000000) >> 40;
51 	final_mac->ether_addr_octet[1] = (mac_addr & 0xff00000000) >> 32;
52 	final_mac->ether_addr_octet[2] = (mac_addr & 0xff000000) >> 24;
53 	final_mac->ether_addr_octet[3] = (mac_addr & 0xff0000) >> 16;
54 	final_mac->ether_addr_octet[4] = (mac_addr & 0xff00) >> 8;
55 	final_mac->ether_addr_octet[5] = (mac_addr & 0xff);
56 }
57 
58 nxge_status_t
59 nxge_espc_mac_addrs_get(p_nxge_t nxgep)
60 {
61 	nxge_status_t	status = NXGE_OK;
62 	npi_status_t	npi_status = NPI_SUCCESS;
63 	uint8_t		port_num = nxgep->mac.portnum;
64 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
65 	uint8_t		mac_addr[ETHERADDRL];
66 
67 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
68 			    "==> nxge_espc_mac_addr_get, port[%d]",
69 			    port_num));
70 
71 	npi_status = npi_espc_mac_addr_get(handle, mac_addr);
72 	if (npi_status != NPI_SUCCESS) {
73 		status = (NXGE_ERROR | npi_status);
74 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
75 				    "nxge_espc_mac_addr_get, port[%d] failed",
76 				    port_num));
77 		goto exit;
78 	}
79 
80 	nxge_espc_get_next_mac_addr(mac_addr, port_num, &nxgep->factaddr);
81 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
82 			"Got MAC Addr: %2x:%2x:%2x:%2x:%2x%:%2x%c \n",
83 			mac_addr[0], mac_addr[1],
84 			mac_addr[2], mac_addr[3],
85 			mac_addr[4], mac_addr[5]));
86 
87 exit:
88 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_mac_addr_get, "
89 			"status [0x%x]", status));
90 
91 	return (status);
92 }
93 
94 nxge_status_t
95 nxge_espc_num_macs_get(p_nxge_t nxgep, uint8_t *nmacs)
96 {
97 	nxge_status_t   status = NXGE_OK;
98 	npi_status_t    npi_status = NPI_SUCCESS;
99 	npi_handle_t    handle = NXGE_DEV_NPI_HANDLE(nxgep);
100 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_macs_get"));
101 
102 	npi_status = npi_espc_num_macs_get(handle, nmacs);
103 	if (npi_status != NPI_SUCCESS) {
104 		status = (NXGE_ERROR | npi_status);
105 	}
106 
107 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_macs_get, "
108 		"status [0x%x]", status));
109 
110 	return (status);
111 }
112 
113 nxge_status_t
114 nxge_espc_num_ports_get(p_nxge_t nxgep)
115 {
116 	nxge_status_t	status = NXGE_OK;
117 	npi_status_t	npi_status = NPI_SUCCESS;
118 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
119 	uint8_t		nports = 0;
120 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_num_ports_get"));
121 
122 	npi_status = npi_espc_num_ports_get(handle, &nports);
123 	if (npi_status != NPI_SUCCESS) {
124 		status = (NXGE_ERROR | npi_status);
125 	}
126 	nxgep->nports = nports;
127 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_num_ports_get "
128 			"ports [0x%x]", nports));
129 
130 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_num_ports_get, "
131 			"status [0x%x]", status));
132 
133 	return (status);
134 }
135 
136 nxge_status_t
137 nxge_espc_phy_type_get(p_nxge_t nxgep)
138 {
139 	nxge_status_t	status = NXGE_OK;
140 	npi_status_t	npi_status = NPI_SUCCESS;
141 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
142 	uint8_t		port_num = nxgep->mac.portnum;
143 	uint8_t		phy_type;
144 
145 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_phy_type_get, port[%d]",
146 			port_num));
147 
148 	npi_status = npi_espc_port_phy_type_get(handle, &phy_type,
149 						port_num);
150 	if (npi_status != NPI_SUCCESS) {
151 		status = (NXGE_ERROR | npi_status);
152 		goto exit;
153 	}
154 
155 	switch (phy_type) {
156 	case ESC_PHY_10G_FIBER:
157 		nxgep->mac.portmode = PORT_10G_FIBER;
158 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
159 		break;
160 	case ESC_PHY_10G_COPPER:
161 		nxgep->mac.portmode = PORT_10G_COPPER;
162 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
163 		break;
164 	case ESC_PHY_1G_FIBER:
165 		nxgep->mac.portmode = PORT_1G_FIBER;
166 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
167 		break;
168 	case ESC_PHY_1G_COPPER:
169 		nxgep->mac.portmode = PORT_1G_COPPER;
170 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
171 		break;
172 	case ESC_PHY_NONE:
173 		status = NXGE_ERROR;
174 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get:"
175 				"No phy type set"));
176 		break;
177 	default:
178 		status = NXGE_ERROR;
179 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_espc_phy_type_get: "
180 				"Unknown phy type [%d]", phy_type));
181 		break;
182 	}
183 
184 exit:
185 
186 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_espc_phy_type_get, "
187 			"status [0x%x]", status));
188 
189 	return (status);
190 }
191 
192 nxge_status_t
193 nxge_espc_max_frame_sz_get(p_nxge_t nxgep)
194 {
195 	nxge_status_t	status = NXGE_OK;
196 	npi_status_t	npi_status = NPI_SUCCESS;
197 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
198 
199 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_espc_max_frame_sz_get"));
200 
201 	npi_status = npi_espc_max_frame_get(handle, &nxgep->mac.maxframesize);
202 	if (npi_status != NPI_SUCCESS) {
203 		status = (NXGE_ERROR | npi_status);
204 	}
205 
206 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " nxge_espc_max_frame_sz_get, "
207 			    "status [0x%x]", status));
208 
209 	return (status);
210 }
211 
212 nxge_status_t
213 nxge_vpd_info_get(p_nxge_t nxgep)
214 {
215 	npi_status_t	status;
216 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
217 
218 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_cfg_lock);
219 	(void) npi_espc_pio_enable(handle);
220 	status = npi_espc_vpd_info_get(handle, &nxgep->vpd_info,
221 				NXGE_EROM_LEN);
222 	(void) npi_espc_pio_disable(handle);
223 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_cfg_lock);
224 
225 	nxgep->vpd_info.ver_valid = B_FALSE;
226 	if (status == NPI_SUCCESS) {
227 		(void) nxge_check_vpd_version(nxgep);
228 		return (NXGE_OK);
229 	} else
230 		return (NXGE_ERROR);
231 }
232 
233 static nxge_status_t
234 nxge_check_vpd_version(p_nxge_t nxgep)
235 {
236 	int		i, j;
237 	nxge_status_t	status = NXGE_OK;
238 	const char	*fcode_str = NXGE_FCODE_ID_STR;
239 	int		fcode_str_len = strlen(fcode_str);
240 	char		ver_num_str[NXGE_FCODE_VER_STR_LEN];
241 	char		*ver_num_w;
242 	char		*ver_num_f;
243 	int		ver_num_w_len = 0;
244 	int		ver_num_f_len = 0;
245 	int		ver_w = 0;
246 	int		ver_f = 0;
247 
248 	nxgep->vpd_info.ver_valid = B_FALSE;
249 	ver_num_str[0] = '\0';
250 
251 	for (i = 0; i < NXGE_VPD_VER_LEN; i++) {
252 		if (nxgep->vpd_info.ver[i] == fcode_str[0]) {
253 			if ((i + fcode_str_len + NXGE_FCODE_VER_STR_LEN) >
254 			    NXGE_VPD_VER_LEN)
255 				break;
256 			for (j = 0; j < fcode_str_len; j++, i++) {
257 				if (nxgep->vpd_info.ver[i] != fcode_str[j])
258 					break;
259 			}
260 			if (j < fcode_str_len)
261 				continue;
262 
263 			/* found the Fcode version string */
264 			for (j = 0; j < NXGE_FCODE_VER_STR_LEN; j++, i++) {
265 				ver_num_str[j] = nxgep->vpd_info.ver[i];
266 				if (ver_num_str[j] == ' ')
267 					break;
268 			}
269 			ver_num_str[j] = '\0';
270 			break;
271 		}
272 	}
273 
274 	ver_num_w = ver_num_str;
275 	for (i = 0; i < strlen(ver_num_str); i++) {
276 		if (ver_num_str[i] == '.') {
277 			ver_num_f = &ver_num_str[i + 1];
278 			ver_num_w_len = i;
279 			ver_num_f_len = strlen(ver_num_str) - (i + 1);
280 			break;
281 		}
282 	}
283 
284 	for (i = 0; i < ver_num_w_len; i++) {
285 		ver_w = (ver_w * 10) + (ver_num_w[i] - '0');
286 	}
287 
288 	for (i = 0; i < ver_num_f_len; i++) {
289 		ver_f = (ver_f * 10) + (ver_num_f[i] - '0');
290 	}
291 
292 	if ((ver_w > NXGE_VPD_VALID_VER_W) ||
293 	    (ver_w == NXGE_VPD_VALID_VER_W && ver_f >= NXGE_VPD_VALID_VER_F))
294 		nxgep->vpd_info.ver_valid = B_TRUE;
295 
296 	return (status);
297 }
298