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