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: stable/12/sys/dev/sfxge/common/efx_nic.c 342350 2018-12-21 17:22:17Z arybchik $");
35 
36 #include "efx.h"
37 #include "efx_impl.h"
38 
39 	__checkReturn	efx_rc_t
efx_family(__in uint16_t venid,__in uint16_t devid,__out efx_family_t * efp)40 efx_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 
112 static 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 
131 static 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 
150 static 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
efx_nic_create(__in efx_family_t family,__in efsys_identifier_t * esip,__in efsys_bar_t * esbp,__in efsys_lock_t * eslp,__deref_out efx_nic_t ** enpp)169 efx_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 
259 fail2:
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 
267 fail1:
268 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
269 
270 	return (rc);
271 }
272 
273 	__checkReturn	efx_rc_t
efx_nic_probe(__in efx_nic_t * enp)274 efx_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 
297 fail2:
298 	EFSYS_PROBE(fail2);
299 
300 	enop->eno_unprobe(enp);
301 
302 fail1:
303 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
304 
305 	return (rc);
306 }
307 
308 	__checkReturn	efx_rc_t
efx_nic_set_drv_limits(__inout efx_nic_t * enp,__in efx_drv_limits_t * edlp)309 efx_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 
326 fail1:
327 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
328 
329 	return (rc);
330 }
331 
332 	__checkReturn	efx_rc_t
efx_nic_get_bar_region(__in efx_nic_t * enp,__in efx_nic_region_t region,__out uint32_t * offsetp,__out size_t * sizep)333 efx_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 
357 fail2:
358 	EFSYS_PROBE(fail2);
359 
360 fail1:
361 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
362 
363 	return (rc);
364 }
365 
366 
367 	__checkReturn	efx_rc_t
efx_nic_get_vi_pool(__in efx_nic_t * enp,__out uint32_t * evq_countp,__out uint32_t * rxq_countp,__out uint32_t * txq_countp)368 efx_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 
400 fail1:
401 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
402 
403 	return (rc);
404 }
405 
406 
407 	__checkReturn	efx_rc_t
efx_nic_init(__in efx_nic_t * enp)408 efx_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 
429 fail2:
430 	EFSYS_PROBE(fail2);
431 fail1:
432 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
433 
434 	return (rc);
435 }
436 
437 			void
efx_nic_fini(__in efx_nic_t * enp)438 efx_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
efx_nic_unprobe(__in efx_nic_t * enp)457 efx_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
efx_nic_destroy(__in efx_nic_t * enp)481 efx_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
efx_nic_reset(__in efx_nic_t * enp)503 efx_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 
535 fail2:
536 	EFSYS_PROBE(fail2);
537 fail1:
538 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
539 
540 	return (rc);
541 }
542 
543 			const efx_nic_cfg_t *
efx_nic_cfg_get(__in efx_nic_t * enp)544 efx_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
efx_nic_register_test(__in efx_nic_t * enp)556 efx_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 
571 fail1:
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 
581 extern			void
efx_loopback_mask(__in efx_loopback_kind_t loopback_kind,__out efx_qword_t * maskp)582 efx_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
efx_mcdi_get_loopback_modes(__in efx_nic_t * enp)684 efx_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 
756 fail2:
757 	EFSYS_PROBE(fail2);
758 fail1:
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
efx_nic_calculate_pcie_link_bandwidth(__in uint32_t pcie_link_width,__in uint32_t pcie_link_gen,__out uint32_t * bandwidth_mbpsp)767 efx_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 
805 fail2:
806 	EFSYS_PROBE(fail2);
807 fail1:
808 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
809 
810 	return (rc);
811 }
812 
813 
814 	__checkReturn	efx_rc_t
efx_nic_check_pcie_link_speed(__in efx_nic_t * enp,__in uint32_t pcie_link_width,__in uint32_t pcie_link_gen,__out efx_pcie_link_performance_t * resultp)815 efx_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 
853 out:
854 	*resultp = result;
855 
856 	return (0);
857 
858 fail1:
859 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
860 
861 	return (rc);
862 }
863