xref: /freebsd-11-stable/sys/dev/sfxge/common/efx_nic.c (revision 02b40efdac8a89dbb6f77ef5170482e9760d7bdf)
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$");
33 
34 #include "efx.h"
35 #include "efx_impl.h"
36 
37 	__checkReturn	efx_rc_t
efx_family(__in uint16_t venid,__in uint16_t devid,__out efx_family_t * efp)38 efx_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 
110 static 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 
129 static 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 
148 static 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
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)167 efx_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 omitted 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 
257 fail2:
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 
265 fail1:
266 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
267 
268 	return (rc);
269 }
270 
271 	__checkReturn	efx_rc_t
efx_nic_probe(__in efx_nic_t * enp)272 efx_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 
295 fail2:
296 	EFSYS_PROBE(fail2);
297 
298 	enop->eno_unprobe(enp);
299 
300 fail1:
301 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
302 
303 	return (rc);
304 }
305 
306 	__checkReturn	efx_rc_t
efx_nic_set_drv_limits(__inout efx_nic_t * enp,__in efx_drv_limits_t * edlp)307 efx_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 
324 fail1:
325 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
326 
327 	return (rc);
328 }
329 
330 	__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)331 efx_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 
355 fail2:
356 	EFSYS_PROBE(fail2);
357 
358 fail1:
359 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
360 
361 	return (rc);
362 }
363 
364 
365 	__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)366 efx_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 
398 fail1:
399 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
400 
401 	return (rc);
402 }
403 
404 
405 	__checkReturn	efx_rc_t
efx_nic_init(__in efx_nic_t * enp)406 efx_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 
427 fail2:
428 	EFSYS_PROBE(fail2);
429 fail1:
430 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
431 
432 	return (rc);
433 }
434 
435 			void
efx_nic_fini(__in efx_nic_t * enp)436 efx_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
efx_nic_unprobe(__in efx_nic_t * enp)455 efx_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
efx_nic_destroy(__in efx_nic_t * enp)479 efx_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
efx_nic_reset(__in efx_nic_t * enp)501 efx_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 
533 fail2:
534 	EFSYS_PROBE(fail2);
535 fail1:
536 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
537 
538 	return (rc);
539 }
540 
541 			const efx_nic_cfg_t *
efx_nic_cfg_get(__in efx_nic_t * enp)542 efx_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
efx_nic_register_test(__in efx_nic_t * enp)554 efx_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 
569 fail1:
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 
579 extern			void
efx_loopback_mask(__in efx_loopback_kind_t loopback_kind,__out efx_qword_t * maskp)580 efx_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
efx_mcdi_get_loopback_modes(__in efx_nic_t * enp)682 efx_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 
754 fail2:
755 	EFSYS_PROBE(fail2);
756 fail1:
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
efx_nic_calculate_pcie_link_bandwidth(__in uint32_t pcie_link_width,__in uint32_t pcie_link_gen,__out uint32_t * bandwidth_mbpsp)765 efx_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 
803 fail2:
804 	EFSYS_PROBE(fail2);
805 fail1:
806 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
807 
808 	return (rc);
809 }
810 
811 
812 	__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)813 efx_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 
851 out:
852 	*resultp = result;
853 
854 	return (0);
855 
856 fail1:
857 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
858 
859 	return (rc);
860 }
861