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