xref: /freebsd/sys/dev/sfxge/common/efx_nic.c (revision 266900be140bd4eeb782cdb101e081eab973dda3)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2007-2016 Solarflare Communications Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  *    this list of conditions and the following disclaimer in the documentation
14  *    and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * The views and conclusions contained in the software and documentation are
29  * those of the authors and should not be interpreted as representing official
30  * policies, either expressed or implied, of the FreeBSD Project.
31  */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include "efx.h"
37 #include "efx_impl.h"
38 
39 	__checkReturn	efx_rc_t
40 efx_family(
41 	__in		uint16_t venid,
42 	__in		uint16_t devid,
43 	__out		efx_family_t *efp)
44 {
45 	if (venid == EFX_PCI_VENID_SFC) {
46 		switch (devid) {
47 #if EFSYS_OPT_SIENA
48 		case EFX_PCI_DEVID_SIENA_F1_UNINIT:
49 			/*
50 			 * Hardware default for PF0 of uninitialised Siena.
51 			 * manftest must be able to cope with this device id.
52 			 */
53 			*efp = EFX_FAMILY_SIENA;
54 			return (0);
55 
56 		case EFX_PCI_DEVID_BETHPAGE:
57 		case EFX_PCI_DEVID_SIENA:
58 			*efp = EFX_FAMILY_SIENA;
59 			return (0);
60 #endif /* EFSYS_OPT_SIENA */
61 
62 #if EFSYS_OPT_HUNTINGTON
63 		case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
64 			/*
65 			 * Hardware default for PF0 of uninitialised Huntington.
66 			 * manftest must be able to cope with this device id.
67 			 */
68 			*efp = EFX_FAMILY_HUNTINGTON;
69 			return (0);
70 
71 		case EFX_PCI_DEVID_FARMINGDALE:
72 		case EFX_PCI_DEVID_GREENPORT:
73 			*efp = EFX_FAMILY_HUNTINGTON;
74 			return (0);
75 
76 		case EFX_PCI_DEVID_FARMINGDALE_VF:
77 		case EFX_PCI_DEVID_GREENPORT_VF:
78 			*efp = EFX_FAMILY_HUNTINGTON;
79 			return (0);
80 #endif /* EFSYS_OPT_HUNTINGTON */
81 
82 #if EFSYS_OPT_MEDFORD
83 		case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
84 			/*
85 			 * Hardware default for PF0 of uninitialised Medford.
86 			 * manftest must be able to cope with this device id.
87 			 */
88 			*efp = EFX_FAMILY_MEDFORD;
89 			return (0);
90 
91 		case EFX_PCI_DEVID_MEDFORD:
92 			*efp = EFX_FAMILY_MEDFORD;
93 			return (0);
94 
95 		case EFX_PCI_DEVID_MEDFORD_VF:
96 			*efp = EFX_FAMILY_MEDFORD;
97 			return (0);
98 #endif /* EFSYS_OPT_MEDFORD */
99 
100 		case EFX_PCI_DEVID_FALCON:	/* Obsolete, not supported */
101 		default:
102 			break;
103 		}
104 	}
105 
106 	*efp = EFX_FAMILY_INVALID;
107 	return (ENOTSUP);
108 }
109 
110 #if EFSYS_OPT_SIENA
111 
112 static const efx_nic_ops_t	__efx_nic_siena_ops = {
113 	siena_nic_probe,		/* eno_probe */
114 	NULL,				/* eno_board_cfg */
115 	NULL,				/* eno_set_drv_limits */
116 	siena_nic_reset,		/* eno_reset */
117 	siena_nic_init,			/* eno_init */
118 	NULL,				/* eno_get_vi_pool */
119 	NULL,				/* eno_get_bar_region */
120 #if EFSYS_OPT_DIAG
121 	siena_nic_register_test,	/* eno_register_test */
122 #endif	/* EFSYS_OPT_DIAG */
123 	siena_nic_fini,			/* eno_fini */
124 	siena_nic_unprobe,		/* eno_unprobe */
125 };
126 
127 #endif	/* EFSYS_OPT_SIENA */
128 
129 #if EFSYS_OPT_HUNTINGTON
130 
131 static const efx_nic_ops_t	__efx_nic_hunt_ops = {
132 	ef10_nic_probe,			/* eno_probe */
133 	hunt_board_cfg,			/* eno_board_cfg */
134 	ef10_nic_set_drv_limits,	/* eno_set_drv_limits */
135 	ef10_nic_reset,			/* eno_reset */
136 	ef10_nic_init,			/* eno_init */
137 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
138 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
139 #if EFSYS_OPT_DIAG
140 	ef10_nic_register_test,		/* eno_register_test */
141 #endif	/* EFSYS_OPT_DIAG */
142 	ef10_nic_fini,			/* eno_fini */
143 	ef10_nic_unprobe,		/* eno_unprobe */
144 };
145 
146 #endif	/* EFSYS_OPT_HUNTINGTON */
147 
148 #if EFSYS_OPT_MEDFORD
149 
150 static const efx_nic_ops_t	__efx_nic_medford_ops = {
151 	ef10_nic_probe,			/* eno_probe */
152 	medford_board_cfg,		/* eno_board_cfg */
153 	ef10_nic_set_drv_limits,	/* eno_set_drv_limits */
154 	ef10_nic_reset,			/* eno_reset */
155 	ef10_nic_init,			/* eno_init */
156 	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
157 	ef10_nic_get_bar_region,	/* eno_get_bar_region */
158 #if EFSYS_OPT_DIAG
159 	ef10_nic_register_test,		/* eno_register_test */
160 #endif	/* EFSYS_OPT_DIAG */
161 	ef10_nic_fini,			/* eno_fini */
162 	ef10_nic_unprobe,		/* eno_unprobe */
163 };
164 
165 #endif	/* EFSYS_OPT_MEDFORD */
166 
167 
168 	__checkReturn	efx_rc_t
169 efx_nic_create(
170 	__in		efx_family_t family,
171 	__in		efsys_identifier_t *esip,
172 	__in		efsys_bar_t *esbp,
173 	__in		efsys_lock_t *eslp,
174 	__deref_out	efx_nic_t **enpp)
175 {
176 	efx_nic_t *enp;
177 	efx_rc_t rc;
178 
179 	EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
180 	EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
181 
182 	/* Allocate a NIC object */
183 	EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
184 
185 	if (enp == NULL) {
186 		rc = ENOMEM;
187 		goto fail1;
188 	}
189 
190 	enp->en_magic = EFX_NIC_MAGIC;
191 
192 	switch (family) {
193 #if EFSYS_OPT_SIENA
194 	case EFX_FAMILY_SIENA:
195 		enp->en_enop = &__efx_nic_siena_ops;
196 		enp->en_features =
197 		    EFX_FEATURE_IPV6 |
198 		    EFX_FEATURE_LFSR_HASH_INSERT |
199 		    EFX_FEATURE_LINK_EVENTS |
200 		    EFX_FEATURE_PERIODIC_MAC_STATS |
201 		    EFX_FEATURE_MCDI |
202 		    EFX_FEATURE_LOOKAHEAD_SPLIT |
203 		    EFX_FEATURE_MAC_HEADER_FILTERS |
204 		    EFX_FEATURE_TX_SRC_FILTERS;
205 		break;
206 #endif	/* EFSYS_OPT_SIENA */
207 
208 #if EFSYS_OPT_HUNTINGTON
209 	case EFX_FAMILY_HUNTINGTON:
210 		enp->en_enop = &__efx_nic_hunt_ops;
211 		enp->en_features =
212 		    EFX_FEATURE_IPV6 |
213 		    EFX_FEATURE_LINK_EVENTS |
214 		    EFX_FEATURE_PERIODIC_MAC_STATS |
215 		    EFX_FEATURE_MCDI |
216 		    EFX_FEATURE_MAC_HEADER_FILTERS |
217 		    EFX_FEATURE_MCDI_DMA |
218 		    EFX_FEATURE_PIO_BUFFERS |
219 		    EFX_FEATURE_FW_ASSISTED_TSO |
220 		    EFX_FEATURE_FW_ASSISTED_TSO_V2 |
221 		    EFX_FEATURE_PACKED_STREAM;
222 		break;
223 #endif	/* EFSYS_OPT_HUNTINGTON */
224 
225 #if EFSYS_OPT_MEDFORD
226 	case EFX_FAMILY_MEDFORD:
227 		enp->en_enop = &__efx_nic_medford_ops;
228 		/*
229 		 * FW_ASSISTED_TSO omitted as Medford only supports firmware
230 		 * assisted TSO version 2, not the v1 scheme used on Huntington.
231 		 */
232 		enp->en_features =
233 		    EFX_FEATURE_IPV6 |
234 		    EFX_FEATURE_LINK_EVENTS |
235 		    EFX_FEATURE_PERIODIC_MAC_STATS |
236 		    EFX_FEATURE_MCDI |
237 		    EFX_FEATURE_MAC_HEADER_FILTERS |
238 		    EFX_FEATURE_MCDI_DMA |
239 		    EFX_FEATURE_PIO_BUFFERS |
240 		    EFX_FEATURE_FW_ASSISTED_TSO_V2 |
241 		    EFX_FEATURE_PACKED_STREAM;
242 		break;
243 #endif	/* EFSYS_OPT_MEDFORD */
244 
245 	default:
246 		rc = ENOTSUP;
247 		goto fail2;
248 	}
249 
250 	enp->en_family = family;
251 	enp->en_esip = esip;
252 	enp->en_esbp = esbp;
253 	enp->en_eslp = eslp;
254 
255 	*enpp = enp;
256 
257 	return (0);
258 
259 fail2:
260 	EFSYS_PROBE(fail2);
261 
262 	enp->en_magic = 0;
263 
264 	/* Free the NIC object */
265 	EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
266 
267 fail1:
268 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
269 
270 	return (rc);
271 }
272 
273 	__checkReturn	efx_rc_t
274 efx_nic_probe(
275 	__in		efx_nic_t *enp)
276 {
277 	const efx_nic_ops_t *enop;
278 	efx_rc_t rc;
279 
280 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
281 #if EFSYS_OPT_MCDI
282 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
283 #endif	/* EFSYS_OPT_MCDI */
284 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
285 
286 	enop = enp->en_enop;
287 	if ((rc = enop->eno_probe(enp)) != 0)
288 		goto fail1;
289 
290 	if ((rc = efx_phy_probe(enp)) != 0)
291 		goto fail2;
292 
293 	enp->en_mod_flags |= EFX_MOD_PROBE;
294 
295 	return (0);
296 
297 fail2:
298 	EFSYS_PROBE(fail2);
299 
300 	enop->eno_unprobe(enp);
301 
302 fail1:
303 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
304 
305 	return (rc);
306 }
307 
308 	__checkReturn	efx_rc_t
309 efx_nic_set_drv_limits(
310 	__inout		efx_nic_t *enp,
311 	__in		efx_drv_limits_t *edlp)
312 {
313 	const efx_nic_ops_t *enop = enp->en_enop;
314 	efx_rc_t rc;
315 
316 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
317 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
318 
319 	if (enop->eno_set_drv_limits != NULL) {
320 		if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
321 			goto fail1;
322 	}
323 
324 	return (0);
325 
326 fail1:
327 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
328 
329 	return (rc);
330 }
331 
332 	__checkReturn	efx_rc_t
333 efx_nic_get_bar_region(
334 	__in		efx_nic_t *enp,
335 	__in		efx_nic_region_t region,
336 	__out		uint32_t *offsetp,
337 	__out		size_t *sizep)
338 {
339 	const efx_nic_ops_t *enop = enp->en_enop;
340 	efx_rc_t rc;
341 
342 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
343 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
344 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
345 
346 	if (enop->eno_get_bar_region == NULL) {
347 		rc = ENOTSUP;
348 		goto fail1;
349 	}
350 	if ((rc = (enop->eno_get_bar_region)(enp,
351 		    region, offsetp, sizep)) != 0) {
352 		goto fail2;
353 	}
354 
355 	return (0);
356 
357 fail2:
358 	EFSYS_PROBE(fail2);
359 
360 fail1:
361 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
362 
363 	return (rc);
364 }
365 
366 
367 	__checkReturn	efx_rc_t
368 efx_nic_get_vi_pool(
369 	__in		efx_nic_t *enp,
370 	__out		uint32_t *evq_countp,
371 	__out		uint32_t *rxq_countp,
372 	__out		uint32_t *txq_countp)
373 {
374 	const efx_nic_ops_t *enop = enp->en_enop;
375 	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
376 	efx_rc_t rc;
377 
378 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
379 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
380 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
381 
382 	if (enop->eno_get_vi_pool != NULL) {
383 		uint32_t vi_count = 0;
384 
385 		if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
386 			goto fail1;
387 
388 		*evq_countp = vi_count;
389 		*rxq_countp = vi_count;
390 		*txq_countp = vi_count;
391 	} else {
392 		/* Use NIC limits as default value */
393 		*evq_countp = encp->enc_evq_limit;
394 		*rxq_countp = encp->enc_rxq_limit;
395 		*txq_countp = encp->enc_txq_limit;
396 	}
397 
398 	return (0);
399 
400 fail1:
401 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
402 
403 	return (rc);
404 }
405 
406 
407 	__checkReturn	efx_rc_t
408 efx_nic_init(
409 	__in		efx_nic_t *enp)
410 {
411 	const efx_nic_ops_t *enop = enp->en_enop;
412 	efx_rc_t rc;
413 
414 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
415 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
416 
417 	if (enp->en_mod_flags & EFX_MOD_NIC) {
418 		rc = EINVAL;
419 		goto fail1;
420 	}
421 
422 	if ((rc = enop->eno_init(enp)) != 0)
423 		goto fail2;
424 
425 	enp->en_mod_flags |= EFX_MOD_NIC;
426 
427 	return (0);
428 
429 fail2:
430 	EFSYS_PROBE(fail2);
431 fail1:
432 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
433 
434 	return (rc);
435 }
436 
437 			void
438 efx_nic_fini(
439 	__in		efx_nic_t *enp)
440 {
441 	const efx_nic_ops_t *enop = enp->en_enop;
442 
443 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
444 	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
445 	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
446 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
447 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
448 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
449 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
450 
451 	enop->eno_fini(enp);
452 
453 	enp->en_mod_flags &= ~EFX_MOD_NIC;
454 }
455 
456 			void
457 efx_nic_unprobe(
458 	__in		efx_nic_t *enp)
459 {
460 	const efx_nic_ops_t *enop = enp->en_enop;
461 
462 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
463 #if EFSYS_OPT_MCDI
464 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
465 #endif	/* EFSYS_OPT_MCDI */
466 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
467 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
468 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
469 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
470 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
471 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
472 
473 	efx_phy_unprobe(enp);
474 
475 	enop->eno_unprobe(enp);
476 
477 	enp->en_mod_flags &= ~EFX_MOD_PROBE;
478 }
479 
480 			void
481 efx_nic_destroy(
482 	__in	efx_nic_t *enp)
483 {
484 	efsys_identifier_t *esip = enp->en_esip;
485 
486 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
487 	EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
488 
489 	enp->en_family = EFX_FAMILY_INVALID;
490 	enp->en_esip = NULL;
491 	enp->en_esbp = NULL;
492 	enp->en_eslp = NULL;
493 
494 	enp->en_enop = NULL;
495 
496 	enp->en_magic = 0;
497 
498 	/* Free the NIC object */
499 	EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
500 }
501 
502 	__checkReturn	efx_rc_t
503 efx_nic_reset(
504 	__in		efx_nic_t *enp)
505 {
506 	const efx_nic_ops_t *enop = enp->en_enop;
507 	unsigned int mod_flags;
508 	efx_rc_t rc;
509 
510 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
511 	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
512 	/*
513 	 * All modules except the MCDI, PROBE, NVRAM, VPD, MON
514 	 * (which we do not reset here) must have been shut down or never
515 	 * initialized.
516 	 *
517 	 * A rule of thumb here is: If the controller or MC reboots, is *any*
518 	 * state lost. If it's lost and needs reapplying, then the module
519 	 * *must* not be initialised during the reset.
520 	 */
521 	mod_flags = enp->en_mod_flags;
522 	mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
523 		    EFX_MOD_VPD | EFX_MOD_MON);
524 	EFSYS_ASSERT3U(mod_flags, ==, 0);
525 	if (mod_flags != 0) {
526 		rc = EINVAL;
527 		goto fail1;
528 	}
529 
530 	if ((rc = enop->eno_reset(enp)) != 0)
531 		goto fail2;
532 
533 	return (0);
534 
535 fail2:
536 	EFSYS_PROBE(fail2);
537 fail1:
538 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
539 
540 	return (rc);
541 }
542 
543 			const efx_nic_cfg_t *
544 efx_nic_cfg_get(
545 	__in		efx_nic_t *enp)
546 {
547 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
548 
549 	return (&(enp->en_nic_cfg));
550 }
551 
552 	__checkReturn		efx_rc_t
553 efx_nic_get_fw_version(
554 	__in			efx_nic_t *enp,
555 	__out			efx_nic_fw_info_t *enfip)
556 {
557 	uint16_t mc_fw_version[4];
558 	efx_rc_t rc;
559 
560 	if (enfip == NULL) {
561 		rc = EINVAL;
562 		goto fail1;
563 	}
564 
565 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
566 	EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
567 
568 	rc = efx_mcdi_version(enp, mc_fw_version, NULL, NULL);
569 	if (rc != 0)
570 		goto fail2;
571 
572 	rc = efx_mcdi_get_capabilities(enp, NULL,
573 	    &enfip->enfi_rx_dpcpu_fw_id,
574 	    &enfip->enfi_tx_dpcpu_fw_id,
575 	    NULL, NULL);
576 	if (rc == 0) {
577 		enfip->enfi_dpcpu_fw_ids_valid = B_TRUE;
578 	} else if (rc == ENOTSUP) {
579 		enfip->enfi_dpcpu_fw_ids_valid = B_FALSE;
580 		enfip->enfi_rx_dpcpu_fw_id = 0;
581 		enfip->enfi_tx_dpcpu_fw_id = 0;
582 	} else {
583 		goto fail3;
584 	}
585 
586 	memcpy(enfip->enfi_mc_fw_version, mc_fw_version,
587 	    sizeof (mc_fw_version));
588 
589 	return (0);
590 
591 fail3:
592 	EFSYS_PROBE(fail3);
593 fail2:
594 	EFSYS_PROBE(fail2);
595 fail1:
596 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
597 
598 	return (rc);
599 }
600 
601 #if EFSYS_OPT_DIAG
602 
603 	__checkReturn	efx_rc_t
604 efx_nic_register_test(
605 	__in		efx_nic_t *enp)
606 {
607 	const efx_nic_ops_t *enop = enp->en_enop;
608 	efx_rc_t rc;
609 
610 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
611 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
612 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
613 
614 	if ((rc = enop->eno_register_test(enp)) != 0)
615 		goto fail1;
616 
617 	return (0);
618 
619 fail1:
620 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
621 
622 	return (rc);
623 }
624 
625 #endif	/* EFSYS_OPT_DIAG */
626 
627 #if EFSYS_OPT_LOOPBACK
628 
629 extern			void
630 efx_loopback_mask(
631 	__in	efx_loopback_kind_t loopback_kind,
632 	__out	efx_qword_t *maskp)
633 {
634 	efx_qword_t mask;
635 
636 	EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
637 	EFSYS_ASSERT(maskp != NULL);
638 
639 	/* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
640 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
641 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
642 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
643 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
644 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
645 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
646 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
647 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
648 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
649 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
650 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
651 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
652 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
653 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
654 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
655 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
656 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
657 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
658 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
659 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
660 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
661 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
662 	    EFX_LOOPBACK_XAUI_WS_FAR);
663 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
664 	    EFX_LOOPBACK_XAUI_WS_NEAR);
665 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
666 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
667 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
668 	    EFX_LOOPBACK_XFI_WS_FAR);
669 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
670 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
671 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
672 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
673 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
674 	    EFX_LOOPBACK_PMA_INT_WS);
675 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
676 	    EFX_LOOPBACK_SD_FEP2_WS);
677 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
678 	    EFX_LOOPBACK_SD_FEP1_5_WS);
679 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
680 	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
681 
682 	/* Build bitmask of possible loopback types */
683 	EFX_ZERO_QWORD(mask);
684 
685 	if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
686 	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
687 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
688 	}
689 
690 	if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
691 	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
692 		/*
693 		 * The "MAC" grouping has historically been used by drivers to
694 		 * mean loopbacks supported by on-chip hardware. Keep that
695 		 * meaning here, and include on-chip PHY layer loopbacks.
696 		 */
697 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
698 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
699 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
700 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
701 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
702 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
703 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
704 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
705 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
706 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
707 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
708 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
709 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
710 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
711 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
712 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
713 	}
714 
715 	if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
716 	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
717 		/*
718 		 * The "PHY" grouping has historically been used by drivers to
719 		 * mean loopbacks supported by off-chip hardware. Keep that
720 		 * meaning here.
721 		 */
722 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
723 		EFX_SET_QWORD_BIT(mask,	EFX_LOOPBACK_PHY_XS);
724 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
725 		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
726 	}
727 
728 	*maskp = mask;
729 }
730 
731 	__checkReturn	efx_rc_t
732 efx_mcdi_get_loopback_modes(
733 	__in		efx_nic_t *enp)
734 {
735 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
736 	efx_mcdi_req_t req;
737 	uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
738 			    MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
739 	efx_qword_t mask;
740 	efx_qword_t modes;
741 	efx_rc_t rc;
742 
743 	(void) memset(payload, 0, sizeof (payload));
744 	req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
745 	req.emr_in_buf = payload;
746 	req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
747 	req.emr_out_buf = payload;
748 	req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
749 
750 	efx_mcdi_execute(enp, &req);
751 
752 	if (req.emr_rc != 0) {
753 		rc = req.emr_rc;
754 		goto fail1;
755 	}
756 
757 	if (req.emr_out_length_used <
758 	    MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
759 	    MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
760 		rc = EMSGSIZE;
761 		goto fail2;
762 	}
763 
764 	/*
765 	 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
766 	 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
767 	 */
768 	efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
769 
770 	EFX_AND_QWORD(mask,
771 	    *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
772 
773 	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
774 	EFX_AND_QWORD(modes, mask);
775 	encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
776 
777 	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
778 	EFX_AND_QWORD(modes, mask);
779 	encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
780 
781 	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
782 	EFX_AND_QWORD(modes, mask);
783 	encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
784 
785 	if (req.emr_out_length_used >=
786 	    MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
787 	    MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
788 		/* Response includes 40G loopback modes */
789 		modes =
790 		    *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
791 		EFX_AND_QWORD(modes, mask);
792 		encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
793 	}
794 
795 	EFX_ZERO_QWORD(modes);
796 	EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
797 	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
798 	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
799 	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
800 	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
801 	encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
802 
803 	return (0);
804 
805 fail2:
806 	EFSYS_PROBE(fail2);
807 fail1:
808 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
809 
810 	return (rc);
811 }
812 
813 #endif /* EFSYS_OPT_LOOPBACK */
814 
815 	__checkReturn	efx_rc_t
816 efx_nic_calculate_pcie_link_bandwidth(
817 	__in		uint32_t pcie_link_width,
818 	__in		uint32_t pcie_link_gen,
819 	__out		uint32_t *bandwidth_mbpsp)
820 {
821 	uint32_t lane_bandwidth;
822 	uint32_t total_bandwidth;
823 	efx_rc_t rc;
824 
825 	if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
826 	    !ISP2(pcie_link_width)) {
827 		rc = EINVAL;
828 		goto fail1;
829 	}
830 
831 	switch (pcie_link_gen) {
832 	case EFX_PCIE_LINK_SPEED_GEN1:
833 		/* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
834 		lane_bandwidth = 2000;
835 		break;
836 	case EFX_PCIE_LINK_SPEED_GEN2:
837 		/* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
838 		lane_bandwidth = 4000;
839 		break;
840 	case EFX_PCIE_LINK_SPEED_GEN3:
841 		/* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
842 		lane_bandwidth = 7877;
843 		break;
844 	default:
845 		rc = EINVAL;
846 		goto fail2;
847 	}
848 
849 	total_bandwidth = lane_bandwidth * pcie_link_width;
850 	*bandwidth_mbpsp = total_bandwidth;
851 
852 	return (0);
853 
854 fail2:
855 	EFSYS_PROBE(fail2);
856 fail1:
857 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
858 
859 	return (rc);
860 }
861 
862 
863 	__checkReturn	efx_rc_t
864 efx_nic_check_pcie_link_speed(
865 	__in		efx_nic_t *enp,
866 	__in		uint32_t pcie_link_width,
867 	__in		uint32_t pcie_link_gen,
868 	__out		efx_pcie_link_performance_t *resultp)
869 {
870 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
871 	uint32_t bandwidth;
872 	efx_pcie_link_performance_t result;
873 	efx_rc_t rc;
874 
875 	if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
876 	    (pcie_link_width == 0) || (pcie_link_width == 32) ||
877 	    (pcie_link_gen == 0)) {
878 		/*
879 		 * No usable info on what is required and/or in use. In virtual
880 		 * machines, sometimes the PCIe link width is reported as 0 or
881 		 * 32, or the speed as 0.
882 		 */
883 		result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
884 		goto out;
885 	}
886 
887 	/* Calculate the available bandwidth in megabits per second */
888 	rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
889 					    pcie_link_gen, &bandwidth);
890 	if (rc != 0)
891 		goto fail1;
892 
893 	if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
894 		result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
895 	} else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
896 		/* The link provides enough bandwidth but not optimal latency */
897 		result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
898 	} else {
899 		result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
900 	}
901 
902 out:
903 	*resultp = result;
904 
905 	return (0);
906 
907 fail1:
908 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
909 
910 	return (rc);
911 }
912