efx_nic.c revision 300007
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: head/sys/dev/sfxge/common/efx_nic.c 300007 2016-05-17 06:23:50Z 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_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
113efx_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
168fail4:
169	EFSYS_PROBE(fail4);
170fail3:
171	EFSYS_PROBE(fail3);
172fail2:
173	EFSYS_PROBE(fail2);
174fail1:
175	EFSYS_PROBE1(fail1, efx_rc_t, rc);
176
177	return (rc);
178}
179
180#if EFSYS_OPT_SIENA
181
182static 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
201static 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
220static 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
239efx_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		    EFX_FEATURE_FW_ASSISTED_TSO_V2;
312		break;
313#endif	/* EFSYS_OPT_MEDFORD */
314
315	default:
316		rc = ENOTSUP;
317		goto fail2;
318	}
319
320	enp->en_family = family;
321	enp->en_esip = esip;
322	enp->en_esbp = esbp;
323	enp->en_eslp = eslp;
324
325	*enpp = enp;
326
327	return (0);
328
329fail2:
330	EFSYS_PROBE(fail2);
331
332	enp->en_magic = 0;
333
334	/* Free the NIC object */
335	EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
336
337fail1:
338	EFSYS_PROBE1(fail1, efx_rc_t, rc);
339
340	return (rc);
341}
342
343	__checkReturn	efx_rc_t
344efx_nic_probe(
345	__in		efx_nic_t *enp)
346{
347	const efx_nic_ops_t *enop;
348	efx_rc_t rc;
349
350	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
351#if EFSYS_OPT_MCDI
352	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
353#endif	/* EFSYS_OPT_MCDI */
354	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
355
356	enop = enp->en_enop;
357	if ((rc = enop->eno_probe(enp)) != 0)
358		goto fail1;
359
360	if ((rc = efx_phy_probe(enp)) != 0)
361		goto fail2;
362
363	enp->en_mod_flags |= EFX_MOD_PROBE;
364
365	return (0);
366
367fail2:
368	EFSYS_PROBE(fail2);
369
370	enop->eno_unprobe(enp);
371
372fail1:
373	EFSYS_PROBE1(fail1, efx_rc_t, rc);
374
375	return (rc);
376}
377
378	__checkReturn	efx_rc_t
379efx_nic_set_drv_limits(
380	__inout		efx_nic_t *enp,
381	__in		efx_drv_limits_t *edlp)
382{
383	const efx_nic_ops_t *enop = enp->en_enop;
384	efx_rc_t rc;
385
386	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
387	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
388
389	if (enop->eno_set_drv_limits != NULL) {
390		if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
391			goto fail1;
392	}
393
394	return (0);
395
396fail1:
397	EFSYS_PROBE1(fail1, efx_rc_t, rc);
398
399	return (rc);
400}
401
402	__checkReturn	efx_rc_t
403efx_nic_get_bar_region(
404	__in		efx_nic_t *enp,
405	__in		efx_nic_region_t region,
406	__out		uint32_t *offsetp,
407	__out		size_t *sizep)
408{
409	const efx_nic_ops_t *enop = enp->en_enop;
410	efx_rc_t rc;
411
412	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
413	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
414	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
415
416	if (enop->eno_get_bar_region == NULL) {
417		rc = ENOTSUP;
418		goto fail1;
419	}
420	if ((rc = (enop->eno_get_bar_region)(enp,
421		    region, offsetp, sizep)) != 0) {
422		goto fail2;
423	}
424
425	return (0);
426
427fail2:
428	EFSYS_PROBE(fail2);
429
430fail1:
431	EFSYS_PROBE1(fail1, efx_rc_t, rc);
432
433	return (rc);
434}
435
436
437	__checkReturn	efx_rc_t
438efx_nic_get_vi_pool(
439	__in		efx_nic_t *enp,
440	__out		uint32_t *evq_countp,
441	__out		uint32_t *rxq_countp,
442	__out		uint32_t *txq_countp)
443{
444	const efx_nic_ops_t *enop = enp->en_enop;
445	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
446	efx_rc_t rc;
447
448	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
449	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
450	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
451
452	if (enop->eno_get_vi_pool != NULL) {
453		uint32_t vi_count = 0;
454
455		if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
456			goto fail1;
457
458		*evq_countp = vi_count;
459		*rxq_countp = vi_count;
460		*txq_countp = vi_count;
461	} else {
462		/* Use NIC limits as default value */
463		*evq_countp = encp->enc_evq_limit;
464		*rxq_countp = encp->enc_rxq_limit;
465		*txq_countp = encp->enc_txq_limit;
466	}
467
468	return (0);
469
470fail1:
471	EFSYS_PROBE1(fail1, efx_rc_t, rc);
472
473	return (rc);
474}
475
476
477	__checkReturn	efx_rc_t
478efx_nic_init(
479	__in		efx_nic_t *enp)
480{
481	const efx_nic_ops_t *enop = enp->en_enop;
482	efx_rc_t rc;
483
484	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
485	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
486
487	if (enp->en_mod_flags & EFX_MOD_NIC) {
488		rc = EINVAL;
489		goto fail1;
490	}
491
492	if ((rc = enop->eno_init(enp)) != 0)
493		goto fail2;
494
495	enp->en_mod_flags |= EFX_MOD_NIC;
496
497	return (0);
498
499fail2:
500	EFSYS_PROBE(fail2);
501fail1:
502	EFSYS_PROBE1(fail1, efx_rc_t, rc);
503
504	return (rc);
505}
506
507			void
508efx_nic_fini(
509	__in		efx_nic_t *enp)
510{
511	const efx_nic_ops_t *enop = enp->en_enop;
512
513	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
514	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
515	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
516	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
517	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
518	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
519	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
520
521	enop->eno_fini(enp);
522
523	enp->en_mod_flags &= ~EFX_MOD_NIC;
524}
525
526			void
527efx_nic_unprobe(
528	__in		efx_nic_t *enp)
529{
530	const efx_nic_ops_t *enop = enp->en_enop;
531
532	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
533#if EFSYS_OPT_MCDI
534	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
535#endif	/* EFSYS_OPT_MCDI */
536	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
537	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
538	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
539	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
540	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
541	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
542
543	efx_phy_unprobe(enp);
544
545	enop->eno_unprobe(enp);
546
547	enp->en_mod_flags &= ~EFX_MOD_PROBE;
548}
549
550			void
551efx_nic_destroy(
552	__in	efx_nic_t *enp)
553{
554	efsys_identifier_t *esip = enp->en_esip;
555
556	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
557	EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
558
559	enp->en_family = 0;
560	enp->en_esip = NULL;
561	enp->en_esbp = NULL;
562	enp->en_eslp = NULL;
563
564	enp->en_enop = NULL;
565
566	enp->en_magic = 0;
567
568	/* Free the NIC object */
569	EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
570}
571
572	__checkReturn	efx_rc_t
573efx_nic_reset(
574	__in		efx_nic_t *enp)
575{
576	const efx_nic_ops_t *enop = enp->en_enop;
577	unsigned int mod_flags;
578	efx_rc_t rc;
579
580	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
581	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
582	/*
583	 * All modules except the MCDI, PROBE, NVRAM, VPD, MON
584	 * (which we do not reset here) must have been shut down or never
585	 * initialized.
586	 *
587	 * A rule of thumb here is: If the controller or MC reboots, is *any*
588	 * state lost. If it's lost and needs reapplying, then the module
589	 * *must* not be initialised during the reset.
590	 */
591	mod_flags = enp->en_mod_flags;
592	mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
593		    EFX_MOD_VPD | EFX_MOD_MON);
594	EFSYS_ASSERT3U(mod_flags, ==, 0);
595	if (mod_flags != 0) {
596		rc = EINVAL;
597		goto fail1;
598	}
599
600	if ((rc = enop->eno_reset(enp)) != 0)
601		goto fail2;
602
603	return (0);
604
605fail2:
606	EFSYS_PROBE(fail2);
607fail1:
608	EFSYS_PROBE1(fail1, efx_rc_t, rc);
609
610	return (rc);
611}
612
613			const efx_nic_cfg_t *
614efx_nic_cfg_get(
615	__in		efx_nic_t *enp)
616{
617	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
618
619	return (&(enp->en_nic_cfg));
620}
621
622#if EFSYS_OPT_DIAG
623
624	__checkReturn	efx_rc_t
625efx_nic_register_test(
626	__in		efx_nic_t *enp)
627{
628	const efx_nic_ops_t *enop = enp->en_enop;
629	efx_rc_t rc;
630
631	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
632	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
633	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
634
635	if ((rc = enop->eno_register_test(enp)) != 0)
636		goto fail1;
637
638	return (0);
639
640fail1:
641	EFSYS_PROBE1(fail1, efx_rc_t, rc);
642
643	return (rc);
644}
645
646	__checkReturn	efx_rc_t
647efx_nic_test_registers(
648	__in		efx_nic_t *enp,
649	__in		efx_register_set_t *rsp,
650	__in		size_t count)
651{
652	unsigned int bit;
653	efx_oword_t original;
654	efx_oword_t reg;
655	efx_oword_t buf;
656	efx_rc_t rc;
657
658	while (count > 0) {
659		/* This function is only suitable for registers */
660		EFSYS_ASSERT(rsp->rows == 1);
661
662		/* bit sweep on and off */
663		EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
664			    B_TRUE);
665		for (bit = 0; bit < 128; bit++) {
666			/* Is this bit in the mask? */
667			if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
668				continue;
669
670			/* Test this bit can be set in isolation */
671			reg = original;
672			EFX_AND_OWORD(reg, rsp->mask);
673			EFX_SET_OWORD_BIT(reg, bit);
674
675			EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
676				    B_TRUE);
677			EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
678				    B_TRUE);
679
680			EFX_AND_OWORD(buf, rsp->mask);
681			if (memcmp(&reg, &buf, sizeof (reg))) {
682				rc = EIO;
683				goto fail1;
684			}
685
686			/* Test this bit can be cleared in isolation */
687			EFX_OR_OWORD(reg, rsp->mask);
688			EFX_CLEAR_OWORD_BIT(reg, bit);
689
690			EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
691				    B_TRUE);
692			EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
693				    B_TRUE);
694
695			EFX_AND_OWORD(buf, rsp->mask);
696			if (memcmp(&reg, &buf, sizeof (reg))) {
697				rc = EIO;
698				goto fail2;
699			}
700		}
701
702		/* Restore the old value */
703		EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
704			    B_TRUE);
705
706		--count;
707		++rsp;
708	}
709
710	return (0);
711
712fail2:
713	EFSYS_PROBE(fail2);
714fail1:
715	EFSYS_PROBE1(fail1, efx_rc_t, rc);
716
717	/* Restore the old value */
718	EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
719
720	return (rc);
721}
722
723	__checkReturn	efx_rc_t
724efx_nic_test_tables(
725	__in		efx_nic_t *enp,
726	__in		efx_register_set_t *rsp,
727	__in		efx_pattern_type_t pattern,
728	__in		size_t count)
729{
730	efx_sram_pattern_fn_t func;
731	unsigned int index;
732	unsigned int address;
733	efx_oword_t reg;
734	efx_oword_t buf;
735	efx_rc_t rc;
736
737	EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
738	func = __efx_sram_pattern_fns[pattern];
739
740	while (count > 0) {
741		/* Write */
742		address = rsp->address;
743		for (index = 0; index < rsp->rows; ++index) {
744			func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
745			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
746			EFX_AND_OWORD(reg, rsp->mask);
747			EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
748
749			address += rsp->step;
750		}
751
752		/* Read */
753		address = rsp->address;
754		for (index = 0; index < rsp->rows; ++index) {
755			func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
756			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
757			EFX_AND_OWORD(reg, rsp->mask);
758			EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
759			if (memcmp(&reg, &buf, sizeof (reg))) {
760				rc = EIO;
761				goto fail1;
762			}
763
764			address += rsp->step;
765		}
766
767		++rsp;
768		--count;
769	}
770
771	return (0);
772
773fail1:
774	EFSYS_PROBE1(fail1, efx_rc_t, rc);
775
776	return (rc);
777}
778
779#endif	/* EFSYS_OPT_DIAG */
780
781#if EFSYS_OPT_LOOPBACK
782
783extern			void
784efx_loopback_mask(
785	__in	efx_loopback_kind_t loopback_kind,
786	__out	efx_qword_t *maskp)
787{
788	efx_qword_t mask;
789
790	EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
791	EFSYS_ASSERT(maskp != NULL);
792
793	/* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
794	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
795	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
796	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
797	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
798	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
799	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
800	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
801	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
802	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
803	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
804	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
805	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
806	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
807	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
808	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
809	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
810	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
811	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
812	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
813	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
814	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
815	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
816	    EFX_LOOPBACK_XAUI_WS_FAR);
817	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
818	    EFX_LOOPBACK_XAUI_WS_NEAR);
819	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
820	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
821	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
822	    EFX_LOOPBACK_XFI_WS_FAR);
823	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
824	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
825	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
826	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
827	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
828	    EFX_LOOPBACK_PMA_INT_WS);
829	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
830	    EFX_LOOPBACK_SD_FEP2_WS);
831	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
832	    EFX_LOOPBACK_SD_FEP1_5_WS);
833	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
834	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
835
836	/* Build bitmask of possible loopback types */
837	EFX_ZERO_QWORD(mask);
838
839	if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
840	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
841		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
842	}
843
844	if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
845	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
846		/*
847		 * The "MAC" grouping has historically been used by drivers to
848		 * mean loopbacks supported by on-chip hardware. Keep that
849		 * meaning here, and include on-chip PHY layer loopbacks.
850		 */
851		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
852		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
853		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
854		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
855		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
856		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
857		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
858		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
859		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
860		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
861		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
862		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
863		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
864		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
865		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
866		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
867	}
868
869	if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
870	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
871		/*
872		 * The "PHY" grouping has historically been used by drivers to
873		 * mean loopbacks supported by off-chip hardware. Keep that
874		 * meaning here.
875		 */
876		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
877		EFX_SET_QWORD_BIT(mask,	EFX_LOOPBACK_PHY_XS);
878		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
879		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
880	}
881
882	*maskp = mask;
883}
884
885	__checkReturn	efx_rc_t
886efx_mcdi_get_loopback_modes(
887	__in		efx_nic_t *enp)
888{
889	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
890	efx_mcdi_req_t req;
891	uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
892			    MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
893	efx_qword_t mask;
894	efx_qword_t modes;
895	efx_rc_t rc;
896
897	(void) memset(payload, 0, sizeof (payload));
898	req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
899	req.emr_in_buf = payload;
900	req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
901	req.emr_out_buf = payload;
902	req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
903
904	efx_mcdi_execute(enp, &req);
905
906	if (req.emr_rc != 0) {
907		rc = req.emr_rc;
908		goto fail1;
909	}
910
911	if (req.emr_out_length_used <
912	    MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
913	    MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
914		rc = EMSGSIZE;
915		goto fail2;
916	}
917
918	/*
919	 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
920	 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
921	 */
922	efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
923
924	EFX_AND_QWORD(mask,
925	    *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
926
927	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
928	EFX_AND_QWORD(modes, mask);
929	encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
930
931	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
932	EFX_AND_QWORD(modes, mask);
933	encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
934
935	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
936	EFX_AND_QWORD(modes, mask);
937	encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
938
939	if (req.emr_out_length_used >=
940	    MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
941	    MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
942		/* Response includes 40G loopback modes */
943		modes =
944		    *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
945		EFX_AND_QWORD(modes, mask);
946		encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
947	}
948
949	EFX_ZERO_QWORD(modes);
950	EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
951	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
952	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
953	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
954	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
955	encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
956
957	return (0);
958
959fail2:
960	EFSYS_PROBE(fail2);
961fail1:
962	EFSYS_PROBE1(fail1, efx_rc_t, rc);
963
964	return (rc);
965}
966
967#endif /* EFSYS_OPT_LOOPBACK */
968
969	__checkReturn	efx_rc_t
970efx_nic_calculate_pcie_link_bandwidth(
971	__in		uint32_t pcie_link_width,
972	__in		uint32_t pcie_link_gen,
973	__out		uint32_t *bandwidth_mbpsp)
974{
975	uint32_t lane_bandwidth;
976	uint32_t total_bandwidth;
977	efx_rc_t rc;
978
979	if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
980	    !ISP2(pcie_link_width)) {
981		rc = EINVAL;
982		goto fail1;
983	}
984
985	switch (pcie_link_gen) {
986	case EFX_PCIE_LINK_SPEED_GEN1:
987		/* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
988		lane_bandwidth = 2000;
989		break;
990	case EFX_PCIE_LINK_SPEED_GEN2:
991		/* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
992		lane_bandwidth = 4000;
993		break;
994	case EFX_PCIE_LINK_SPEED_GEN3:
995		/* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
996		lane_bandwidth = 7877;
997		break;
998	default:
999		rc = EINVAL;
1000		goto fail2;
1001	}
1002
1003	total_bandwidth = lane_bandwidth * pcie_link_width;
1004	*bandwidth_mbpsp = total_bandwidth;
1005
1006	return (0);
1007
1008fail2:
1009	EFSYS_PROBE(fail2);
1010fail1:
1011	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1012
1013	return (rc);
1014}
1015
1016
1017	__checkReturn	efx_rc_t
1018efx_nic_check_pcie_link_speed(
1019	__in		efx_nic_t *enp,
1020	__in		uint32_t pcie_link_width,
1021	__in		uint32_t pcie_link_gen,
1022	__out		efx_pcie_link_performance_t *resultp)
1023{
1024	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1025	uint32_t bandwidth;
1026	efx_pcie_link_performance_t result;
1027	efx_rc_t rc;
1028
1029	if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
1030	    (pcie_link_width == 0) || (pcie_link_width == 32) ||
1031	    (pcie_link_gen == 0)) {
1032		/*
1033		 * No usable info on what is required and/or in use. In virtual
1034		 * machines, sometimes the PCIe link width is reported as 0 or
1035		 * 32, or the speed as 0.
1036		 */
1037		result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
1038		goto out;
1039	}
1040
1041	/* Calculate the available bandwidth in megabits per second */
1042	rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
1043					    pcie_link_gen, &bandwidth);
1044	if (rc != 0)
1045		goto fail1;
1046
1047	if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
1048		result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
1049	} else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
1050		/* The link provides enough bandwidth but not optimal latency */
1051		result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
1052	} else {
1053		result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
1054	}
1055
1056out:
1057	*resultp = result;
1058
1059	return (0);
1060
1061fail1:
1062	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1063
1064	return (rc);
1065}
1066