1/*-
2 * Copyright (c) 2007-2016 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 342524 2018-12-26 10:37:06Z 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#if EFSYS_OPT_SIENA
109
110static const efx_nic_ops_t	__efx_nic_siena_ops = {
111	siena_nic_probe,		/* eno_probe */
112	NULL,				/* eno_board_cfg */
113	NULL,				/* eno_set_drv_limits */
114	siena_nic_reset,		/* eno_reset */
115	siena_nic_init,			/* eno_init */
116	NULL,				/* eno_get_vi_pool */
117	NULL,				/* eno_get_bar_region */
118#if EFSYS_OPT_DIAG
119	siena_nic_register_test,	/* eno_register_test */
120#endif	/* EFSYS_OPT_DIAG */
121	siena_nic_fini,			/* eno_fini */
122	siena_nic_unprobe,		/* eno_unprobe */
123};
124
125#endif	/* EFSYS_OPT_SIENA */
126
127#if EFSYS_OPT_HUNTINGTON
128
129static const efx_nic_ops_t	__efx_nic_hunt_ops = {
130	ef10_nic_probe,			/* eno_probe */
131	hunt_board_cfg,			/* eno_board_cfg */
132	ef10_nic_set_drv_limits,	/* eno_set_drv_limits */
133	ef10_nic_reset,			/* eno_reset */
134	ef10_nic_init,			/* eno_init */
135	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
136	ef10_nic_get_bar_region,	/* eno_get_bar_region */
137#if EFSYS_OPT_DIAG
138	ef10_nic_register_test,		/* eno_register_test */
139#endif	/* EFSYS_OPT_DIAG */
140	ef10_nic_fini,			/* eno_fini */
141	ef10_nic_unprobe,		/* eno_unprobe */
142};
143
144#endif	/* EFSYS_OPT_HUNTINGTON */
145
146#if EFSYS_OPT_MEDFORD
147
148static const efx_nic_ops_t	__efx_nic_medford_ops = {
149	ef10_nic_probe,			/* eno_probe */
150	medford_board_cfg,		/* eno_board_cfg */
151	ef10_nic_set_drv_limits,	/* eno_set_drv_limits */
152	ef10_nic_reset,			/* eno_reset */
153	ef10_nic_init,			/* eno_init */
154	ef10_nic_get_vi_pool,		/* eno_get_vi_pool */
155	ef10_nic_get_bar_region,	/* eno_get_bar_region */
156#if EFSYS_OPT_DIAG
157	ef10_nic_register_test,		/* eno_register_test */
158#endif	/* EFSYS_OPT_DIAG */
159	ef10_nic_fini,			/* eno_fini */
160	ef10_nic_unprobe,		/* eno_unprobe */
161};
162
163#endif	/* EFSYS_OPT_MEDFORD */
164
165
166	__checkReturn	efx_rc_t
167efx_nic_create(
168	__in		efx_family_t family,
169	__in		efsys_identifier_t *esip,
170	__in		efsys_bar_t *esbp,
171	__in		efsys_lock_t *eslp,
172	__deref_out	efx_nic_t **enpp)
173{
174	efx_nic_t *enp;
175	efx_rc_t rc;
176
177	EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
178	EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
179
180	/* Allocate a NIC object */
181	EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
182
183	if (enp == NULL) {
184		rc = ENOMEM;
185		goto fail1;
186	}
187
188	enp->en_magic = EFX_NIC_MAGIC;
189
190	switch (family) {
191#if EFSYS_OPT_SIENA
192	case EFX_FAMILY_SIENA:
193		enp->en_enop = &__efx_nic_siena_ops;
194		enp->en_features =
195		    EFX_FEATURE_IPV6 |
196		    EFX_FEATURE_LFSR_HASH_INSERT |
197		    EFX_FEATURE_LINK_EVENTS |
198		    EFX_FEATURE_PERIODIC_MAC_STATS |
199		    EFX_FEATURE_MCDI |
200		    EFX_FEATURE_LOOKAHEAD_SPLIT |
201		    EFX_FEATURE_MAC_HEADER_FILTERS |
202		    EFX_FEATURE_TX_SRC_FILTERS;
203		break;
204#endif	/* EFSYS_OPT_SIENA */
205
206#if EFSYS_OPT_HUNTINGTON
207	case EFX_FAMILY_HUNTINGTON:
208		enp->en_enop = &__efx_nic_hunt_ops;
209		enp->en_features =
210		    EFX_FEATURE_IPV6 |
211		    EFX_FEATURE_LINK_EVENTS |
212		    EFX_FEATURE_PERIODIC_MAC_STATS |
213		    EFX_FEATURE_MCDI |
214		    EFX_FEATURE_MAC_HEADER_FILTERS |
215		    EFX_FEATURE_MCDI_DMA |
216		    EFX_FEATURE_PIO_BUFFERS |
217		    EFX_FEATURE_FW_ASSISTED_TSO |
218		    EFX_FEATURE_FW_ASSISTED_TSO_V2 |
219		    EFX_FEATURE_TXQ_CKSUM_OP_DESC;
220		break;
221#endif	/* EFSYS_OPT_HUNTINGTON */
222
223#if EFSYS_OPT_MEDFORD
224	case EFX_FAMILY_MEDFORD:
225		enp->en_enop = &__efx_nic_medford_ops;
226		/*
227		 * FW_ASSISTED_TSO ommitted as Medford only supports firmware
228		 * assisted TSO version 2, not the v1 scheme used on Huntington.
229		 */
230		enp->en_features =
231		    EFX_FEATURE_IPV6 |
232		    EFX_FEATURE_LINK_EVENTS |
233		    EFX_FEATURE_PERIODIC_MAC_STATS |
234		    EFX_FEATURE_MCDI |
235		    EFX_FEATURE_MAC_HEADER_FILTERS |
236		    EFX_FEATURE_MCDI_DMA |
237		    EFX_FEATURE_PIO_BUFFERS |
238		    EFX_FEATURE_FW_ASSISTED_TSO_V2 |
239		    EFX_FEATURE_TXQ_CKSUM_OP_DESC;
240		break;
241#endif	/* EFSYS_OPT_MEDFORD */
242
243	default:
244		rc = ENOTSUP;
245		goto fail2;
246	}
247
248	enp->en_family = family;
249	enp->en_esip = esip;
250	enp->en_esbp = esbp;
251	enp->en_eslp = eslp;
252
253	*enpp = enp;
254
255	return (0);
256
257fail2:
258	EFSYS_PROBE(fail2);
259
260	enp->en_magic = 0;
261
262	/* Free the NIC object */
263	EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
264
265fail1:
266	EFSYS_PROBE1(fail1, efx_rc_t, rc);
267
268	return (rc);
269}
270
271	__checkReturn	efx_rc_t
272efx_nic_probe(
273	__in		efx_nic_t *enp)
274{
275	const efx_nic_ops_t *enop;
276	efx_rc_t rc;
277
278	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
279#if EFSYS_OPT_MCDI
280	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
281#endif	/* EFSYS_OPT_MCDI */
282	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
283
284	enop = enp->en_enop;
285	if ((rc = enop->eno_probe(enp)) != 0)
286		goto fail1;
287
288	if ((rc = efx_phy_probe(enp)) != 0)
289		goto fail2;
290
291	enp->en_mod_flags |= EFX_MOD_PROBE;
292
293	return (0);
294
295fail2:
296	EFSYS_PROBE(fail2);
297
298	enop->eno_unprobe(enp);
299
300fail1:
301	EFSYS_PROBE1(fail1, efx_rc_t, rc);
302
303	return (rc);
304}
305
306	__checkReturn	efx_rc_t
307efx_nic_set_drv_limits(
308	__inout		efx_nic_t *enp,
309	__in		efx_drv_limits_t *edlp)
310{
311	const efx_nic_ops_t *enop = enp->en_enop;
312	efx_rc_t rc;
313
314	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
315	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
316
317	if (enop->eno_set_drv_limits != NULL) {
318		if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
319			goto fail1;
320	}
321
322	return (0);
323
324fail1:
325	EFSYS_PROBE1(fail1, efx_rc_t, rc);
326
327	return (rc);
328}
329
330	__checkReturn	efx_rc_t
331efx_nic_get_bar_region(
332	__in		efx_nic_t *enp,
333	__in		efx_nic_region_t region,
334	__out		uint32_t *offsetp,
335	__out		size_t *sizep)
336{
337	const efx_nic_ops_t *enop = enp->en_enop;
338	efx_rc_t rc;
339
340	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
341	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
342	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
343
344	if (enop->eno_get_bar_region == NULL) {
345		rc = ENOTSUP;
346		goto fail1;
347	}
348	if ((rc = (enop->eno_get_bar_region)(enp,
349		    region, offsetp, sizep)) != 0) {
350		goto fail2;
351	}
352
353	return (0);
354
355fail2:
356	EFSYS_PROBE(fail2);
357
358fail1:
359	EFSYS_PROBE1(fail1, efx_rc_t, rc);
360
361	return (rc);
362}
363
364
365	__checkReturn	efx_rc_t
366efx_nic_get_vi_pool(
367	__in		efx_nic_t *enp,
368	__out		uint32_t *evq_countp,
369	__out		uint32_t *rxq_countp,
370	__out		uint32_t *txq_countp)
371{
372	const efx_nic_ops_t *enop = enp->en_enop;
373	efx_nic_cfg_t *encp = &enp->en_nic_cfg;
374	efx_rc_t rc;
375
376	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
377	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
378	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
379
380	if (enop->eno_get_vi_pool != NULL) {
381		uint32_t vi_count = 0;
382
383		if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
384			goto fail1;
385
386		*evq_countp = vi_count;
387		*rxq_countp = vi_count;
388		*txq_countp = vi_count;
389	} else {
390		/* Use NIC limits as default value */
391		*evq_countp = encp->enc_evq_limit;
392		*rxq_countp = encp->enc_rxq_limit;
393		*txq_countp = encp->enc_txq_limit;
394	}
395
396	return (0);
397
398fail1:
399	EFSYS_PROBE1(fail1, efx_rc_t, rc);
400
401	return (rc);
402}
403
404
405	__checkReturn	efx_rc_t
406efx_nic_init(
407	__in		efx_nic_t *enp)
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
415	if (enp->en_mod_flags & EFX_MOD_NIC) {
416		rc = EINVAL;
417		goto fail1;
418	}
419
420	if ((rc = enop->eno_init(enp)) != 0)
421		goto fail2;
422
423	enp->en_mod_flags |= EFX_MOD_NIC;
424
425	return (0);
426
427fail2:
428	EFSYS_PROBE(fail2);
429fail1:
430	EFSYS_PROBE1(fail1, efx_rc_t, rc);
431
432	return (rc);
433}
434
435			void
436efx_nic_fini(
437	__in		efx_nic_t *enp)
438{
439	const efx_nic_ops_t *enop = enp->en_enop;
440
441	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
442	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
443	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
444	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
445	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
446	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
447	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
448
449	enop->eno_fini(enp);
450
451	enp->en_mod_flags &= ~EFX_MOD_NIC;
452}
453
454			void
455efx_nic_unprobe(
456	__in		efx_nic_t *enp)
457{
458	const efx_nic_ops_t *enop = enp->en_enop;
459
460	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
461#if EFSYS_OPT_MCDI
462	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
463#endif	/* EFSYS_OPT_MCDI */
464	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
465	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
466	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
467	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
468	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
469	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
470
471	efx_phy_unprobe(enp);
472
473	enop->eno_unprobe(enp);
474
475	enp->en_mod_flags &= ~EFX_MOD_PROBE;
476}
477
478			void
479efx_nic_destroy(
480	__in	efx_nic_t *enp)
481{
482	efsys_identifier_t *esip = enp->en_esip;
483
484	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
485	EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
486
487	enp->en_family = EFX_FAMILY_INVALID;
488	enp->en_esip = NULL;
489	enp->en_esbp = NULL;
490	enp->en_eslp = NULL;
491
492	enp->en_enop = NULL;
493
494	enp->en_magic = 0;
495
496	/* Free the NIC object */
497	EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
498}
499
500	__checkReturn	efx_rc_t
501efx_nic_reset(
502	__in		efx_nic_t *enp)
503{
504	const efx_nic_ops_t *enop = enp->en_enop;
505	unsigned int mod_flags;
506	efx_rc_t rc;
507
508	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
509	EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
510	/*
511	 * All modules except the MCDI, PROBE, NVRAM, VPD, MON
512	 * (which we do not reset here) must have been shut down or never
513	 * initialized.
514	 *
515	 * A rule of thumb here is: If the controller or MC reboots, is *any*
516	 * state lost. If it's lost and needs reapplying, then the module
517	 * *must* not be initialised during the reset.
518	 */
519	mod_flags = enp->en_mod_flags;
520	mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
521		    EFX_MOD_VPD | EFX_MOD_MON);
522	EFSYS_ASSERT3U(mod_flags, ==, 0);
523	if (mod_flags != 0) {
524		rc = EINVAL;
525		goto fail1;
526	}
527
528	if ((rc = enop->eno_reset(enp)) != 0)
529		goto fail2;
530
531	return (0);
532
533fail2:
534	EFSYS_PROBE(fail2);
535fail1:
536	EFSYS_PROBE1(fail1, efx_rc_t, rc);
537
538	return (rc);
539}
540
541			const efx_nic_cfg_t *
542efx_nic_cfg_get(
543	__in		efx_nic_t *enp)
544{
545	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
546	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
547
548	return (&(enp->en_nic_cfg));
549}
550
551#if EFSYS_OPT_DIAG
552
553	__checkReturn	efx_rc_t
554efx_nic_register_test(
555	__in		efx_nic_t *enp)
556{
557	const efx_nic_ops_t *enop = enp->en_enop;
558	efx_rc_t rc;
559
560	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
561	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
562	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
563
564	if ((rc = enop->eno_register_test(enp)) != 0)
565		goto fail1;
566
567	return (0);
568
569fail1:
570	EFSYS_PROBE1(fail1, efx_rc_t, rc);
571
572	return (rc);
573}
574
575#endif	/* EFSYS_OPT_DIAG */
576
577#if EFSYS_OPT_LOOPBACK
578
579extern			void
580efx_loopback_mask(
581	__in	efx_loopback_kind_t loopback_kind,
582	__out	efx_qword_t *maskp)
583{
584	efx_qword_t mask;
585
586	EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
587	EFSYS_ASSERT(maskp != NULL);
588
589	/* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
590	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
591	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
592	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
593	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
594	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
595	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
596	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
597	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
598	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
599	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
600	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
601	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
602	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
603	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
604	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
605	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
606	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
607	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
608	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
609	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
610	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
611	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
612	    EFX_LOOPBACK_XAUI_WS_FAR);
613	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
614	    EFX_LOOPBACK_XAUI_WS_NEAR);
615	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
616	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
617	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
618	    EFX_LOOPBACK_XFI_WS_FAR);
619	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
620	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
621	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
622	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
623	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
624	    EFX_LOOPBACK_PMA_INT_WS);
625	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
626	    EFX_LOOPBACK_SD_FEP2_WS);
627	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
628	    EFX_LOOPBACK_SD_FEP1_5_WS);
629	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
630	EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
631
632	/* Build bitmask of possible loopback types */
633	EFX_ZERO_QWORD(mask);
634
635	if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
636	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
637		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
638	}
639
640	if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
641	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
642		/*
643		 * The "MAC" grouping has historically been used by drivers to
644		 * mean loopbacks supported by on-chip hardware. Keep that
645		 * meaning here, and include on-chip PHY layer loopbacks.
646		 */
647		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
648		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
649		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
650		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
651		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
652		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
653		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
654		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
655		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
656		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
657		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
658		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
659		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
660		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
661		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
662		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
663	}
664
665	if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
666	    (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
667		/*
668		 * The "PHY" grouping has historically been used by drivers to
669		 * mean loopbacks supported by off-chip hardware. Keep that
670		 * meaning here.
671		 */
672		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
673		EFX_SET_QWORD_BIT(mask,	EFX_LOOPBACK_PHY_XS);
674		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
675		EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
676	}
677
678	*maskp = mask;
679}
680
681	__checkReturn	efx_rc_t
682efx_mcdi_get_loopback_modes(
683	__in		efx_nic_t *enp)
684{
685	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
686	efx_mcdi_req_t req;
687	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
688		MC_CMD_GET_LOOPBACK_MODES_OUT_LEN);
689	efx_qword_t mask;
690	efx_qword_t modes;
691	efx_rc_t rc;
692
693	req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
694	req.emr_in_buf = payload;
695	req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
696	req.emr_out_buf = payload;
697	req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
698
699	efx_mcdi_execute(enp, &req);
700
701	if (req.emr_rc != 0) {
702		rc = req.emr_rc;
703		goto fail1;
704	}
705
706	if (req.emr_out_length_used <
707	    MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
708	    MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
709		rc = EMSGSIZE;
710		goto fail2;
711	}
712
713	/*
714	 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
715	 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
716	 */
717	efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
718
719	EFX_AND_QWORD(mask,
720	    *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
721
722	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
723	EFX_AND_QWORD(modes, mask);
724	encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
725
726	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
727	EFX_AND_QWORD(modes, mask);
728	encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
729
730	modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
731	EFX_AND_QWORD(modes, mask);
732	encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
733
734	if (req.emr_out_length_used >=
735	    MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
736	    MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
737		/* Response includes 40G loopback modes */
738		modes =
739		    *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
740		EFX_AND_QWORD(modes, mask);
741		encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
742	}
743
744	EFX_ZERO_QWORD(modes);
745	EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
746	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
747	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
748	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
749	EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
750	encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
751
752	return (0);
753
754fail2:
755	EFSYS_PROBE(fail2);
756fail1:
757	EFSYS_PROBE1(fail1, efx_rc_t, rc);
758
759	return (rc);
760}
761
762#endif /* EFSYS_OPT_LOOPBACK */
763
764	__checkReturn	efx_rc_t
765efx_nic_calculate_pcie_link_bandwidth(
766	__in		uint32_t pcie_link_width,
767	__in		uint32_t pcie_link_gen,
768	__out		uint32_t *bandwidth_mbpsp)
769{
770	uint32_t lane_bandwidth;
771	uint32_t total_bandwidth;
772	efx_rc_t rc;
773
774	if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
775	    !ISP2(pcie_link_width)) {
776		rc = EINVAL;
777		goto fail1;
778	}
779
780	switch (pcie_link_gen) {
781	case EFX_PCIE_LINK_SPEED_GEN1:
782		/* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
783		lane_bandwidth = 2000;
784		break;
785	case EFX_PCIE_LINK_SPEED_GEN2:
786		/* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
787		lane_bandwidth = 4000;
788		break;
789	case EFX_PCIE_LINK_SPEED_GEN3:
790		/* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
791		lane_bandwidth = 7877;
792		break;
793	default:
794		rc = EINVAL;
795		goto fail2;
796	}
797
798	total_bandwidth = lane_bandwidth * pcie_link_width;
799	*bandwidth_mbpsp = total_bandwidth;
800
801	return (0);
802
803fail2:
804	EFSYS_PROBE(fail2);
805fail1:
806	EFSYS_PROBE1(fail1, efx_rc_t, rc);
807
808	return (rc);
809}
810
811
812	__checkReturn	efx_rc_t
813efx_nic_check_pcie_link_speed(
814	__in		efx_nic_t *enp,
815	__in		uint32_t pcie_link_width,
816	__in		uint32_t pcie_link_gen,
817	__out		efx_pcie_link_performance_t *resultp)
818{
819	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
820	uint32_t bandwidth;
821	efx_pcie_link_performance_t result;
822	efx_rc_t rc;
823
824	if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
825	    (pcie_link_width == 0) || (pcie_link_width == 32) ||
826	    (pcie_link_gen == 0)) {
827		/*
828		 * No usable info on what is required and/or in use. In virtual
829		 * machines, sometimes the PCIe link width is reported as 0 or
830		 * 32, or the speed as 0.
831		 */
832		result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
833		goto out;
834	}
835
836	/* Calculate the available bandwidth in megabits per second */
837	rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
838					    pcie_link_gen, &bandwidth);
839	if (rc != 0)
840		goto fail1;
841
842	if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
843		result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
844	} else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
845		/* The link provides enough bandwidth but not optimal latency */
846		result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
847	} else {
848		result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
849	}
850
851out:
852	*resultp = result;
853
854	return (0);
855
856fail1:
857	EFSYS_PROBE1(fail1, efx_rc_t, rc);
858
859	return (rc);
860}
861