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