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