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
nxge_espc_get_next_mac_addr(uint8_t * st_mac,uint8_t nxt_cnt,struct ether_addr * final_mac)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
nxge_espc_mac_addrs_get(p_nxge_t nxgep)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
nxge_espc_num_macs_get(p_nxge_t nxgep,uint8_t * nmacs)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
nxge_espc_num_ports_get(p_nxge_t nxgep)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
nxge_espc_phy_type_get(p_nxge_t nxgep)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
nxge_espc_max_frame_sz_get(p_nxge_t nxgep)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
nxge_vpd_info_get(p_nxge_t nxgep)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
nxge_check_vpd_version(p_nxge_t nxgep)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