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