Deleted Added
sdiff udiff text old ( 293887 ) new ( 293891 )
full compact
1/*-
2 * Copyright (c) 2007-2015 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: head/sys/dev/sfxge/common/efx_nic.c 293891 2016-01-14 09:05:51Z arybchik $");
33
34#include "efx.h"
35#include "efx_impl.h"
36
37 __checkReturn efx_rc_t
38efx_family(
39 __in uint16_t venid,
40 __in uint16_t devid,
41 __out efx_family_t *efp)
42{
43 if (venid == EFX_PCI_VENID_SFC) {
44 switch (devid) {
45#if EFSYS_OPT_FALCON
46 case EFX_PCI_DEVID_FALCON:
47 *efp = EFX_FAMILY_FALCON;
48 return (0);
49#endif /* EFSYS_OPT_FALCON */
50
51#if EFSYS_OPT_SIENA
52 case EFX_PCI_DEVID_SIENA_F1_UNINIT:
53 /*
54 * Hardware default for PF0 of uninitialised Siena.
55 * manftest must be able to cope with this device id.
56 */
57 *efp = EFX_FAMILY_SIENA;
58 return (0);
59
60 case EFX_PCI_DEVID_BETHPAGE:
61 case EFX_PCI_DEVID_SIENA:
62 *efp = EFX_FAMILY_SIENA;
63 return (0);
64#endif /* EFSYS_OPT_SIENA */
65
66#if EFSYS_OPT_HUNTINGTON
67 case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
68 /*
69 * Hardware default for PF0 of uninitialised Huntington.
70 * manftest must be able to cope with this device id.
71 */
72 *efp = EFX_FAMILY_HUNTINGTON;
73 return (0);
74
75 case EFX_PCI_DEVID_FARMINGDALE:
76 case EFX_PCI_DEVID_GREENPORT:
77 *efp = EFX_FAMILY_HUNTINGTON;
78 return (0);
79
80 case EFX_PCI_DEVID_FARMINGDALE_VF:
81 case EFX_PCI_DEVID_GREENPORT_VF:
82 *efp = EFX_FAMILY_HUNTINGTON;
83 return (0);
84#endif /* EFSYS_OPT_HUNTINGTON */
85
86#if EFSYS_OPT_MEDFORD
87 case EFX_PCI_DEVID_MEDFORD_PF_UNINIT:
88 /*
89 * Hardware default for PF0 of uninitialised Medford.
90 * manftest must be able to cope with this device id.
91 */
92 *efp = EFX_FAMILY_MEDFORD;
93 return (0);
94
95 case EFX_PCI_DEVID_MEDFORD:
96 *efp = EFX_FAMILY_MEDFORD;
97 return (0);
98
99 case EFX_PCI_DEVID_MEDFORD_VF:
100 *efp = EFX_FAMILY_MEDFORD;
101 return (0);
102#endif /* EFSYS_OPT_MEDFORD */
103
104 default:
105 break;
106 }
107 }
108
109 *efp = EFX_FAMILY_INVALID;
110 return (ENOTSUP);
111}
112
113/*
114 * To support clients which aren't provided with any PCI context infer
115 * the hardware family by inspecting the hardware. Obviously the caller
116 * must be damn sure they're really talking to a supported device.
117 */
118 __checkReturn efx_rc_t
119efx_infer_family(
120 __in efsys_bar_t *esbp,
121 __out efx_family_t *efp)
122{
123 efx_family_t family;
124 efx_oword_t oword;
125 unsigned int portnum;
126 efx_rc_t rc;
127
128 EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE);
129 portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
130 if ((portnum == 1) || (portnum == 2)) {
131#if EFSYS_OPT_SIENA
132 family = EFX_FAMILY_SIENA;
133 goto out;
134#endif
135 } else if (portnum == 0) {
136 efx_dword_t dword;
137 uint32_t hw_rev;
138
139 EFSYS_BAR_READD(esbp, ER_DZ_BIU_HW_REV_ID_REG_OFST, &dword,
140 B_TRUE);
141 hw_rev = EFX_DWORD_FIELD(dword, ERF_DZ_HW_REV_ID);
142 if (hw_rev == ER_DZ_BIU_HW_REV_ID_REG_RESET) {
143#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
144 /*
145 * BIU_HW_REV_ID is the same for Huntington and Medford.
146 * Assume Huntington, as Medford is very similar.
147 */
148 family = EFX_FAMILY_HUNTINGTON;
149 goto out;
150#endif
151 } else {
152#if EFSYS_OPT_FALCON
153 family = EFX_FAMILY_FALCON;
154 goto out;
155#endif
156 }
157 }
158 rc = ENOTSUP;
159 goto fail1;
160
161out:
162 if (efp != NULL)
163 *efp = family;
164 return (0);
165
166fail1:
167 EFSYS_PROBE1(fail1, efx_rc_t, rc);
168
169 return (rc);
170}
171
172#define EFX_BIU_MAGIC0 0x01234567
173#define EFX_BIU_MAGIC1 0xfedcba98
174
175 __checkReturn efx_rc_t
176efx_nic_biu_test(
177 __in efx_nic_t *enp)
178{
179 efx_oword_t oword;
180 efx_rc_t rc;
181
182 /*
183 * Write magic values to scratch registers 0 and 1, then
184 * verify that the values were written correctly. Interleave
185 * the accesses to ensure that the BIU is not just reading
186 * back the cached value that was last written.
187 */
188 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
189 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
190
191 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
192 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
193
194 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
195 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
196 rc = EIO;
197 goto fail1;
198 }
199
200 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
201 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
202 rc = EIO;
203 goto fail2;
204 }
205
206 /*
207 * Perform the same test, with the values swapped. This
208 * ensures that subsequent tests don't start with the correct
209 * values already written into the scratch registers.
210 */
211 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
212 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
213
214 EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
215 EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
216
217 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
218 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
219 rc = EIO;
220 goto fail3;
221 }
222
223 EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
224 if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
225 rc = EIO;
226 goto fail4;
227 }
228
229 return (0);
230
231fail4:
232 EFSYS_PROBE(fail4);
233fail3:
234 EFSYS_PROBE(fail3);
235fail2:
236 EFSYS_PROBE(fail2);
237fail1:
238 EFSYS_PROBE1(fail1, efx_rc_t, rc);
239
240 return (rc);
241}
242
243#if EFSYS_OPT_FALCON
244
245static efx_nic_ops_t __efx_nic_falcon_ops = {
246 falcon_nic_probe, /* eno_probe */
247 NULL, /* eno_board_cfg */
248 NULL, /* eno_set_drv_limits */
249 falcon_nic_reset, /* eno_reset */
250 falcon_nic_init, /* eno_init */
251 NULL, /* eno_get_vi_pool */
252 NULL, /* eno_get_bar_region */
253#if EFSYS_OPT_DIAG
254 falcon_sram_test, /* eno_sram_test */
255 falcon_nic_register_test, /* eno_register_test */
256#endif /* EFSYS_OPT_DIAG */
257 falcon_nic_fini, /* eno_fini */
258 falcon_nic_unprobe, /* eno_unprobe */
259};
260
261#endif /* EFSYS_OPT_FALCON */
262
263#if EFSYS_OPT_SIENA
264
265static efx_nic_ops_t __efx_nic_siena_ops = {
266 siena_nic_probe, /* eno_probe */
267 NULL, /* eno_board_cfg */
268 NULL, /* eno_set_drv_limits */
269 siena_nic_reset, /* eno_reset */
270 siena_nic_init, /* eno_init */
271 NULL, /* eno_get_vi_pool */
272 NULL, /* eno_get_bar_region */
273#if EFSYS_OPT_DIAG
274 siena_sram_test, /* eno_sram_test */
275 siena_nic_register_test, /* eno_register_test */
276#endif /* EFSYS_OPT_DIAG */
277 siena_nic_fini, /* eno_fini */
278 siena_nic_unprobe, /* eno_unprobe */
279};
280
281#endif /* EFSYS_OPT_SIENA */
282
283#if EFSYS_OPT_HUNTINGTON
284
285static efx_nic_ops_t __efx_nic_hunt_ops = {
286 ef10_nic_probe, /* eno_probe */
287 hunt_board_cfg, /* eno_board_cfg */
288 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
289 ef10_nic_reset, /* eno_reset */
290 ef10_nic_init, /* eno_init */
291 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
292 ef10_nic_get_bar_region, /* eno_get_bar_region */
293#if EFSYS_OPT_DIAG
294 ef10_sram_test, /* eno_sram_test */
295 ef10_nic_register_test, /* eno_register_test */
296#endif /* EFSYS_OPT_DIAG */
297 ef10_nic_fini, /* eno_fini */
298 ef10_nic_unprobe, /* eno_unprobe */
299};
300
301#endif /* EFSYS_OPT_HUNTINGTON */
302
303#if EFSYS_OPT_MEDFORD
304
305static efx_nic_ops_t __efx_nic_medford_ops = {
306 ef10_nic_probe, /* eno_probe */
307 medford_board_cfg, /* eno_board_cfg */
308 ef10_nic_set_drv_limits, /* eno_set_drv_limits */
309 ef10_nic_reset, /* eno_reset */
310 ef10_nic_init, /* eno_init */
311 ef10_nic_get_vi_pool, /* eno_get_vi_pool */
312 ef10_nic_get_bar_region, /* eno_get_bar_region */
313#if EFSYS_OPT_DIAG
314 ef10_sram_test, /* eno_sram_test */
315 ef10_nic_register_test, /* eno_register_test */
316#endif /* EFSYS_OPT_DIAG */
317 ef10_nic_fini, /* eno_fini */
318 ef10_nic_unprobe, /* eno_unprobe */
319};
320
321#endif /* EFSYS_OPT_MEDFORD */
322
323
324 __checkReturn efx_rc_t
325efx_nic_create(
326 __in efx_family_t family,
327 __in efsys_identifier_t *esip,
328 __in efsys_bar_t *esbp,
329 __in efsys_lock_t *eslp,
330 __deref_out efx_nic_t **enpp)
331{
332 efx_nic_t *enp;
333 efx_rc_t rc;
334
335 EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
336 EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
337
338 /* Allocate a NIC object */
339 EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
340
341 if (enp == NULL) {
342 rc = ENOMEM;
343 goto fail1;
344 }
345
346 enp->en_magic = EFX_NIC_MAGIC;
347
348 switch (family) {
349#if EFSYS_OPT_FALCON
350 case EFX_FAMILY_FALCON:
351 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_falcon_ops;
352 enp->en_features = 0;
353 break;
354#endif /* EFSYS_OPT_FALCON */
355
356#if EFSYS_OPT_SIENA
357 case EFX_FAMILY_SIENA:
358 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_siena_ops;
359 enp->en_features =
360 EFX_FEATURE_IPV6 |
361 EFX_FEATURE_LFSR_HASH_INSERT |
362 EFX_FEATURE_LINK_EVENTS |
363 EFX_FEATURE_PERIODIC_MAC_STATS |
364 EFX_FEATURE_WOL |
365 EFX_FEATURE_MCDI |
366 EFX_FEATURE_LOOKAHEAD_SPLIT |
367 EFX_FEATURE_MAC_HEADER_FILTERS |
368 EFX_FEATURE_TX_SRC_FILTERS;
369 break;
370#endif /* EFSYS_OPT_SIENA */
371
372#if EFSYS_OPT_HUNTINGTON
373 case EFX_FAMILY_HUNTINGTON:
374 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_hunt_ops;
375 /* FIXME: Add WOL support */
376 enp->en_features =
377 EFX_FEATURE_IPV6 |
378 EFX_FEATURE_LINK_EVENTS |
379 EFX_FEATURE_PERIODIC_MAC_STATS |
380 EFX_FEATURE_MCDI |
381 EFX_FEATURE_MAC_HEADER_FILTERS |
382 EFX_FEATURE_MCDI_DMA |
383 EFX_FEATURE_PIO_BUFFERS |
384 EFX_FEATURE_FW_ASSISTED_TSO |
385 EFX_FEATURE_FW_ASSISTED_TSO_V2;
386 break;
387#endif /* EFSYS_OPT_HUNTINGTON */
388
389#if EFSYS_OPT_MEDFORD
390 case EFX_FAMILY_MEDFORD:
391 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_medford_ops;
392 /*
393 * FW_ASSISTED_TSO ommitted as Medford only supports firmware
394 * assisted TSO version 2, not the v1 scheme used on Huntington.
395 */
396 enp->en_features =
397 EFX_FEATURE_IPV6 |
398 EFX_FEATURE_LINK_EVENTS |
399 EFX_FEATURE_PERIODIC_MAC_STATS |
400 EFX_FEATURE_MCDI |
401 EFX_FEATURE_MAC_HEADER_FILTERS |
402 EFX_FEATURE_MCDI_DMA |
403 EFX_FEATURE_PIO_BUFFERS;
404 break;
405#endif /* EFSYS_OPT_MEDFORD */
406
407 default:
408 rc = ENOTSUP;
409 goto fail2;
410 }
411
412 enp->en_family = family;
413 enp->en_esip = esip;
414 enp->en_esbp = esbp;
415 enp->en_eslp = eslp;
416
417 *enpp = enp;
418
419 return (0);
420
421fail2:
422 EFSYS_PROBE(fail2);
423
424 enp->en_magic = 0;
425
426 /* Free the NIC object */
427 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
428
429fail1:
430 EFSYS_PROBE1(fail1, efx_rc_t, rc);
431
432 return (rc);
433}
434
435 __checkReturn efx_rc_t
436efx_nic_probe(
437 __in efx_nic_t *enp)
438{
439 efx_nic_ops_t *enop;
440 efx_rc_t rc;
441
442 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
443#if EFSYS_OPT_MCDI
444 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
445#endif /* EFSYS_OPT_MCDI */
446 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
447
448 enop = enp->en_enop;
449 if ((rc = enop->eno_probe(enp)) != 0)
450 goto fail1;
451
452 if ((rc = efx_phy_probe(enp)) != 0)
453 goto fail2;
454
455 enp->en_mod_flags |= EFX_MOD_PROBE;
456
457 return (0);
458
459fail2:
460 EFSYS_PROBE(fail2);
461
462 enop->eno_unprobe(enp);
463
464fail1:
465 EFSYS_PROBE1(fail1, efx_rc_t, rc);
466
467 return (rc);
468}
469
470#if EFSYS_OPT_PCIE_TUNE
471
472 __checkReturn efx_rc_t
473efx_nic_pcie_tune(
474 __in efx_nic_t *enp,
475 unsigned int nlanes)
476{
477 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
478 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
479 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
480
481#if EFSYS_OPT_FALCON
482 if (enp->en_family == EFX_FAMILY_FALCON)
483 return (falcon_nic_pcie_tune(enp, nlanes));
484#endif
485 return (ENOTSUP);
486}
487
488 __checkReturn efx_rc_t
489efx_nic_pcie_extended_sync(
490 __in efx_nic_t *enp)
491{
492 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
493 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
494 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
495
496#if EFSYS_OPT_SIENA
497 if (enp->en_family == EFX_FAMILY_SIENA)
498 return (siena_nic_pcie_extended_sync(enp));
499#endif
500
501 return (ENOTSUP);
502}
503
504#endif /* EFSYS_OPT_PCIE_TUNE */
505
506 __checkReturn efx_rc_t
507efx_nic_set_drv_limits(
508 __inout efx_nic_t *enp,
509 __in efx_drv_limits_t *edlp)
510{
511 efx_nic_ops_t *enop = enp->en_enop;
512 efx_rc_t rc;
513
514 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
515 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
516
517 if (enop->eno_set_drv_limits != NULL) {
518 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
519 goto fail1;
520 }
521
522 return (0);
523
524fail1:
525 EFSYS_PROBE1(fail1, efx_rc_t, rc);
526
527 return (rc);
528}
529
530 __checkReturn efx_rc_t
531efx_nic_get_bar_region(
532 __in efx_nic_t *enp,
533 __in efx_nic_region_t region,
534 __out uint32_t *offsetp,
535 __out size_t *sizep)
536{
537 efx_nic_ops_t *enop = enp->en_enop;
538 efx_rc_t rc;
539
540 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
541 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
542 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
543
544 if (enop->eno_get_bar_region == NULL) {
545 rc = ENOTSUP;
546 goto fail1;
547 }
548 if ((rc = (enop->eno_get_bar_region)(enp,
549 region, offsetp, sizep)) != 0) {
550 goto fail2;
551 }
552
553 return (0);
554
555fail2:
556 EFSYS_PROBE(fail2);
557
558fail1:
559 EFSYS_PROBE1(fail1, efx_rc_t, rc);
560
561 return (rc);
562}
563
564
565 __checkReturn efx_rc_t
566efx_nic_get_vi_pool(
567 __in efx_nic_t *enp,
568 __out uint32_t *evq_countp,
569 __out uint32_t *rxq_countp,
570 __out uint32_t *txq_countp)
571{
572 efx_nic_ops_t *enop = enp->en_enop;
573 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
574 efx_rc_t rc;
575
576 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
577 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
578 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
579
580 if (enop->eno_get_vi_pool != NULL) {
581 uint32_t vi_count = 0;
582
583 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
584 goto fail1;
585
586 *evq_countp = vi_count;
587 *rxq_countp = vi_count;
588 *txq_countp = vi_count;
589 } else {
590 /* Use NIC limits as default value */
591 *evq_countp = encp->enc_evq_limit;
592 *rxq_countp = encp->enc_rxq_limit;
593 *txq_countp = encp->enc_txq_limit;
594 }
595
596 return (0);
597
598fail1:
599 EFSYS_PROBE1(fail1, efx_rc_t, rc);
600
601 return (rc);
602}
603
604
605 __checkReturn efx_rc_t
606efx_nic_init(
607 __in efx_nic_t *enp)
608{
609 efx_nic_ops_t *enop = enp->en_enop;
610 efx_rc_t rc;
611
612 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
613 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
614
615 if (enp->en_mod_flags & EFX_MOD_NIC) {
616 rc = EINVAL;
617 goto fail1;
618 }
619
620 if ((rc = enop->eno_init(enp)) != 0)
621 goto fail2;
622
623 enp->en_mod_flags |= EFX_MOD_NIC;
624
625 return (0);
626
627fail2:
628 EFSYS_PROBE(fail2);
629fail1:
630 EFSYS_PROBE1(fail1, efx_rc_t, rc);
631
632 return (rc);
633}
634
635 void
636efx_nic_fini(
637 __in efx_nic_t *enp)
638{
639 efx_nic_ops_t *enop = enp->en_enop;
640
641 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
642 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
643 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
644 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
645 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
646 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
647 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
648
649 enop->eno_fini(enp);
650
651 enp->en_mod_flags &= ~EFX_MOD_NIC;
652}
653
654 void
655efx_nic_unprobe(
656 __in efx_nic_t *enp)
657{
658 efx_nic_ops_t *enop = enp->en_enop;
659
660 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
661#if EFSYS_OPT_MCDI
662 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
663#endif /* EFSYS_OPT_MCDI */
664 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
665 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
666 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
667 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
668 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
669 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
670
671 efx_phy_unprobe(enp);
672
673 enop->eno_unprobe(enp);
674
675 enp->en_mod_flags &= ~EFX_MOD_PROBE;
676}
677
678 void
679efx_nic_destroy(
680 __in efx_nic_t *enp)
681{
682 efsys_identifier_t *esip = enp->en_esip;
683
684 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
685 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
686
687 enp->en_family = 0;
688 enp->en_esip = NULL;
689 enp->en_esbp = NULL;
690 enp->en_eslp = NULL;
691
692 enp->en_enop = NULL;
693
694 enp->en_magic = 0;
695
696 /* Free the NIC object */
697 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
698}
699
700 __checkReturn efx_rc_t
701efx_nic_reset(
702 __in efx_nic_t *enp)
703{
704 efx_nic_ops_t *enop = enp->en_enop;
705 unsigned int mod_flags;
706 efx_rc_t rc;
707
708 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
709 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
710 /*
711 * All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we
712 * do not reset here) must have been shut down or never initialized.
713 *
714 * A rule of thumb here is: If the controller or MC reboots, is *any*
715 * state lost. If it's lost and needs reapplying, then the module
716 * *must* not be initialised during the reset.
717 */
718 mod_flags = enp->en_mod_flags;
719 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
720 EFX_MOD_VPD | EFX_MOD_MON);
721 EFSYS_ASSERT3U(mod_flags, ==, 0);
722 if (mod_flags != 0) {
723 rc = EINVAL;
724 goto fail1;
725 }
726
727 if ((rc = enop->eno_reset(enp)) != 0)
728 goto fail2;
729
730 enp->en_reset_flags |= EFX_RESET_MAC;
731
732 return (0);
733
734fail2:
735 EFSYS_PROBE(fail2);
736fail1:
737 EFSYS_PROBE1(fail1, efx_rc_t, rc);
738
739 return (rc);
740}
741
742 const efx_nic_cfg_t *
743efx_nic_cfg_get(
744 __in efx_nic_t *enp)
745{
746 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
747
748 return (&(enp->en_nic_cfg));
749}
750
751#if EFSYS_OPT_DIAG
752
753 __checkReturn efx_rc_t
754efx_nic_register_test(
755 __in efx_nic_t *enp)
756{
757 efx_nic_ops_t *enop = enp->en_enop;
758 efx_rc_t rc;
759
760 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
761 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
762 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
763
764 if ((rc = enop->eno_register_test(enp)) != 0)
765 goto fail1;
766
767 return (0);
768
769fail1:
770 EFSYS_PROBE1(fail1, efx_rc_t, rc);
771
772 return (rc);
773}
774
775 __checkReturn efx_rc_t
776efx_nic_test_registers(
777 __in efx_nic_t *enp,
778 __in efx_register_set_t *rsp,
779 __in size_t count)
780{
781 unsigned int bit;
782 efx_oword_t original;
783 efx_oword_t reg;
784 efx_oword_t buf;
785 efx_rc_t rc;
786
787 while (count > 0) {
788 /* This function is only suitable for registers */
789 EFSYS_ASSERT(rsp->rows == 1);
790
791 /* bit sweep on and off */
792 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
793 B_TRUE);
794 for (bit = 0; bit < 128; bit++) {
795 /* Is this bit in the mask? */
796 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
797 continue;
798
799 /* Test this bit can be set in isolation */
800 reg = original;
801 EFX_AND_OWORD(reg, rsp->mask);
802 EFX_SET_OWORD_BIT(reg, bit);
803
804 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
805 B_TRUE);
806 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
807 B_TRUE);
808
809 EFX_AND_OWORD(buf, rsp->mask);
810 if (memcmp(&reg, &buf, sizeof (reg))) {
811 rc = EIO;
812 goto fail1;
813 }
814
815 /* Test this bit can be cleared in isolation */
816 EFX_OR_OWORD(reg, rsp->mask);
817 EFX_CLEAR_OWORD_BIT(reg, bit);
818
819 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
820 B_TRUE);
821 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
822 B_TRUE);
823
824 EFX_AND_OWORD(buf, rsp->mask);
825 if (memcmp(&reg, &buf, sizeof (reg))) {
826 rc = EIO;
827 goto fail2;
828 }
829 }
830
831 /* Restore the old value */
832 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
833 B_TRUE);
834
835 --count;
836 ++rsp;
837 }
838
839 return (0);
840
841fail2:
842 EFSYS_PROBE(fail2);
843fail1:
844 EFSYS_PROBE1(fail1, efx_rc_t, rc);
845
846 /* Restore the old value */
847 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
848
849 return (rc);
850}
851
852 __checkReturn efx_rc_t
853efx_nic_test_tables(
854 __in efx_nic_t *enp,
855 __in efx_register_set_t *rsp,
856 __in efx_pattern_type_t pattern,
857 __in size_t count)
858{
859 efx_sram_pattern_fn_t func;
860 unsigned int index;
861 unsigned int address;
862 efx_oword_t reg;
863 efx_oword_t buf;
864 efx_rc_t rc;
865
866 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
867 func = __efx_sram_pattern_fns[pattern];
868
869 while (count > 0) {
870 /* Write */
871 address = rsp->address;
872 for (index = 0; index < rsp->rows; ++index) {
873 func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
874 func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
875 EFX_AND_OWORD(reg, rsp->mask);
876 EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
877
878 address += rsp->step;
879 }
880
881 /* Read */
882 address = rsp->address;
883 for (index = 0; index < rsp->rows; ++index) {
884 func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
885 func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
886 EFX_AND_OWORD(reg, rsp->mask);
887 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
888 if (memcmp(&reg, &buf, sizeof (reg))) {
889 rc = EIO;
890 goto fail1;
891 }
892
893 address += rsp->step;
894 }
895
896 ++rsp;
897 --count;
898 }
899
900 return (0);
901
902fail1:
903 EFSYS_PROBE1(fail1, efx_rc_t, rc);
904
905 return (rc);
906}
907
908#endif /* EFSYS_OPT_DIAG */
909
910#if EFSYS_OPT_LOOPBACK
911
912extern void
913efx_loopback_mask(
914 __in efx_loopback_kind_t loopback_kind,
915 __out efx_qword_t *maskp)
916{
917 efx_qword_t mask;
918
919 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
920 EFSYS_ASSERT(maskp != NULL);
921
922 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
923 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
924 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
925 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
926 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
927 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
928 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
929 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
930 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
931 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
932 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
933 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
934 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
935 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
936 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
937 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
938 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
939 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
940 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
941 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
942 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
943 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
944 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
945 EFX_LOOPBACK_XAUI_WS_FAR);
946 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
947 EFX_LOOPBACK_XAUI_WS_NEAR);
948 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
949 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
950 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
951 EFX_LOOPBACK_XFI_WS_FAR);
952 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
953 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
954 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
955 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
956 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
957 EFX_LOOPBACK_PMA_INT_WS);
958 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
959 EFX_LOOPBACK_SD_FEP2_WS);
960 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
961 EFX_LOOPBACK_SD_FEP1_5_WS);
962 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
963 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
964
965 /* Build bitmask of possible loopback types */
966 EFX_ZERO_QWORD(mask);
967
968 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
969 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
970 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
971 }
972
973 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
974 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
975 /*
976 * The "MAC" grouping has historically been used by drivers to
977 * mean loopbacks supported by on-chip hardware. Keep that
978 * meaning here, and include on-chip PHY layer loopbacks.
979 */
980 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
981 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
982 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
983 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
984 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
985 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
986 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
987 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
988 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
989 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
990 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
991 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
992 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
993 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
994 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
995 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
996 }
997
998 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
999 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
1000 /*
1001 * The "PHY" grouping has historically been used by drivers to
1002 * mean loopbacks supported by off-chip hardware. Keep that
1003 * meaning here.
1004 */
1005 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
1006 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
1007 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
1008 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
1009 }
1010
1011 *maskp = mask;
1012}
1013
1014 __checkReturn efx_rc_t
1015efx_mcdi_get_loopback_modes(
1016 __in efx_nic_t *enp)
1017{
1018 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1019 efx_mcdi_req_t req;
1020 uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
1021 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
1022 efx_qword_t mask;
1023 efx_qword_t modes;
1024 efx_rc_t rc;
1025
1026 (void) memset(payload, 0, sizeof (payload));
1027 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
1028 req.emr_in_buf = payload;
1029 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
1030 req.emr_out_buf = payload;
1031 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
1032
1033 efx_mcdi_execute(enp, &req);
1034
1035 if (req.emr_rc != 0) {
1036 rc = req.emr_rc;
1037 goto fail1;
1038 }
1039
1040 if (req.emr_out_length_used <
1041 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
1042 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
1043 rc = EMSGSIZE;
1044 goto fail2;
1045 }
1046
1047 /*
1048 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
1049 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
1050 */
1051 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
1052
1053 EFX_AND_QWORD(mask,
1054 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
1055
1056 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
1057 EFX_AND_QWORD(modes, mask);
1058 encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
1059
1060 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
1061 EFX_AND_QWORD(modes, mask);
1062 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
1063
1064 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
1065 EFX_AND_QWORD(modes, mask);
1066 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
1067
1068 if (req.emr_out_length_used >=
1069 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
1070 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
1071 /* Response includes 40G loopback modes */
1072 modes =
1073 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
1074 EFX_AND_QWORD(modes, mask);
1075 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
1076 }
1077
1078 EFX_ZERO_QWORD(modes);
1079 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
1080 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
1081 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
1082 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
1083 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
1084 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
1085
1086 return (0);
1087
1088fail2:
1089 EFSYS_PROBE(fail2);
1090fail1:
1091 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1092
1093 return (rc);
1094}
1095
1096#endif /* EFSYS_OPT_LOOPBACK */