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 293887 2016-01-14 08:59:38Z 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 break;
386#endif /* EFSYS_OPT_HUNTINGTON */
387
388#if EFSYS_OPT_MEDFORD
389 case EFX_FAMILY_MEDFORD:
390 enp->en_enop = (efx_nic_ops_t *)&__efx_nic_medford_ops;
391 /*
392 * FW_ASSISTED_TSO ommitted as Medford only supports firmware
393 * assisted TSO version 2, not the v1 scheme used on Huntington.
394 */
395 enp->en_features =
396 EFX_FEATURE_IPV6 |
397 EFX_FEATURE_LINK_EVENTS |
398 EFX_FEATURE_PERIODIC_MAC_STATS |
399 EFX_FEATURE_MCDI |
400 EFX_FEATURE_MAC_HEADER_FILTERS |
401 EFX_FEATURE_MCDI_DMA |
402 EFX_FEATURE_PIO_BUFFERS;
403 break;
404#endif /* EFSYS_OPT_MEDFORD */
405
406 default:
407 rc = ENOTSUP;
408 goto fail2;
409 }
410
411 enp->en_family = family;
412 enp->en_esip = esip;
413 enp->en_esbp = esbp;
414 enp->en_eslp = eslp;
415
416 *enpp = enp;
417
418 return (0);
419
420fail2:
421 EFSYS_PROBE(fail2);
422
423 enp->en_magic = 0;
424
425 /* Free the NIC object */
426 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
427
428fail1:
429 EFSYS_PROBE1(fail1, efx_rc_t, rc);
430
431 return (rc);
432}
433
434 __checkReturn efx_rc_t
435efx_nic_probe(
436 __in efx_nic_t *enp)
437{
438 efx_nic_ops_t *enop;
439 efx_rc_t rc;
440
441 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
442#if EFSYS_OPT_MCDI
443 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
444#endif /* EFSYS_OPT_MCDI */
445 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
446
447 enop = enp->en_enop;
448 if ((rc = enop->eno_probe(enp)) != 0)
449 goto fail1;
450
451 if ((rc = efx_phy_probe(enp)) != 0)
452 goto fail2;
453
454 enp->en_mod_flags |= EFX_MOD_PROBE;
455
456 return (0);
457
458fail2:
459 EFSYS_PROBE(fail2);
460
461 enop->eno_unprobe(enp);
462
463fail1:
464 EFSYS_PROBE1(fail1, efx_rc_t, rc);
465
466 return (rc);
467}
468
469#if EFSYS_OPT_PCIE_TUNE
470
471 __checkReturn efx_rc_t
472efx_nic_pcie_tune(
473 __in efx_nic_t *enp,
474 unsigned int nlanes)
475{
476 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
477 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
478 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
479
480#if EFSYS_OPT_FALCON
481 if (enp->en_family == EFX_FAMILY_FALCON)
482 return (falcon_nic_pcie_tune(enp, nlanes));
483#endif
484 return (ENOTSUP);
485}
486
487 __checkReturn efx_rc_t
488efx_nic_pcie_extended_sync(
489 __in efx_nic_t *enp)
490{
491 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
492 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
493 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
494
495#if EFSYS_OPT_SIENA
496 if (enp->en_family == EFX_FAMILY_SIENA)
497 return (siena_nic_pcie_extended_sync(enp));
498#endif
499
500 return (ENOTSUP);
501}
502
503#endif /* EFSYS_OPT_PCIE_TUNE */
504
505 __checkReturn efx_rc_t
506efx_nic_set_drv_limits(
507 __inout efx_nic_t *enp,
508 __in efx_drv_limits_t *edlp)
509{
510 efx_nic_ops_t *enop = enp->en_enop;
511 efx_rc_t rc;
512
513 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
514 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
515
516 if (enop->eno_set_drv_limits != NULL) {
517 if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
518 goto fail1;
519 }
520
521 return (0);
522
523fail1:
524 EFSYS_PROBE1(fail1, efx_rc_t, rc);
525
526 return (rc);
527}
528
529 __checkReturn efx_rc_t
530efx_nic_get_bar_region(
531 __in efx_nic_t *enp,
532 __in efx_nic_region_t region,
533 __out uint32_t *offsetp,
534 __out size_t *sizep)
535{
536 efx_nic_ops_t *enop = enp->en_enop;
537 efx_rc_t rc;
538
539 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
540 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
541 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
542
543 if (enop->eno_get_bar_region == NULL) {
544 rc = ENOTSUP;
545 goto fail1;
546 }
547 if ((rc = (enop->eno_get_bar_region)(enp,
548 region, offsetp, sizep)) != 0) {
549 goto fail2;
550 }
551
552 return (0);
553
554fail2:
555 EFSYS_PROBE(fail2);
556
557fail1:
558 EFSYS_PROBE1(fail1, efx_rc_t, rc);
559
560 return (rc);
561}
562
563
564 __checkReturn efx_rc_t
565efx_nic_get_vi_pool(
566 __in efx_nic_t *enp,
567 __out uint32_t *evq_countp,
568 __out uint32_t *rxq_countp,
569 __out uint32_t *txq_countp)
570{
571 efx_nic_ops_t *enop = enp->en_enop;
572 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
573 efx_rc_t rc;
574
575 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
576 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
577 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
578
579 if (enop->eno_get_vi_pool != NULL) {
580 uint32_t vi_count = 0;
581
582 if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
583 goto fail1;
584
585 *evq_countp = vi_count;
586 *rxq_countp = vi_count;
587 *txq_countp = vi_count;
588 } else {
589 /* Use NIC limits as default value */
590 *evq_countp = encp->enc_evq_limit;
591 *rxq_countp = encp->enc_rxq_limit;
592 *txq_countp = encp->enc_txq_limit;
593 }
594
595 return (0);
596
597fail1:
598 EFSYS_PROBE1(fail1, efx_rc_t, rc);
599
600 return (rc);
601}
602
603
604 __checkReturn efx_rc_t
605efx_nic_init(
606 __in efx_nic_t *enp)
607{
608 efx_nic_ops_t *enop = enp->en_enop;
609 efx_rc_t rc;
610
611 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
612 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
613
614 if (enp->en_mod_flags & EFX_MOD_NIC) {
615 rc = EINVAL;
616 goto fail1;
617 }
618
619 if ((rc = enop->eno_init(enp)) != 0)
620 goto fail2;
621
622 enp->en_mod_flags |= EFX_MOD_NIC;
623
624 return (0);
625
626fail2:
627 EFSYS_PROBE(fail2);
628fail1:
629 EFSYS_PROBE1(fail1, efx_rc_t, rc);
630
631 return (rc);
632}
633
634 void
635efx_nic_fini(
636 __in efx_nic_t *enp)
637{
638 efx_nic_ops_t *enop = enp->en_enop;
639
640 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
641 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
642 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
643 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
644 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
645 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
646 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
647
648 enop->eno_fini(enp);
649
650 enp->en_mod_flags &= ~EFX_MOD_NIC;
651}
652
653 void
654efx_nic_unprobe(
655 __in efx_nic_t *enp)
656{
657 efx_nic_ops_t *enop = enp->en_enop;
658
659 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
660#if EFSYS_OPT_MCDI
661 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
662#endif /* EFSYS_OPT_MCDI */
663 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
664 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
665 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
666 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
667 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
668 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
669
670 efx_phy_unprobe(enp);
671
672 enop->eno_unprobe(enp);
673
674 enp->en_mod_flags &= ~EFX_MOD_PROBE;
675}
676
677 void
678efx_nic_destroy(
679 __in efx_nic_t *enp)
680{
681 efsys_identifier_t *esip = enp->en_esip;
682
683 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
684 EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
685
686 enp->en_family = 0;
687 enp->en_esip = NULL;
688 enp->en_esbp = NULL;
689 enp->en_eslp = NULL;
690
691 enp->en_enop = NULL;
692
693 enp->en_magic = 0;
694
695 /* Free the NIC object */
696 EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
697}
698
699 __checkReturn efx_rc_t
700efx_nic_reset(
701 __in efx_nic_t *enp)
702{
703 efx_nic_ops_t *enop = enp->en_enop;
704 unsigned int mod_flags;
705 efx_rc_t rc;
706
707 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
708 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
709 /*
710 * All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we
711 * do not reset here) must have been shut down or never initialized.
712 *
713 * A rule of thumb here is: If the controller or MC reboots, is *any*
714 * state lost. If it's lost and needs reapplying, then the module
715 * *must* not be initialised during the reset.
716 */
717 mod_flags = enp->en_mod_flags;
718 mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
719 EFX_MOD_VPD | EFX_MOD_MON);
720 EFSYS_ASSERT3U(mod_flags, ==, 0);
721 if (mod_flags != 0) {
722 rc = EINVAL;
723 goto fail1;
724 }
725
726 if ((rc = enop->eno_reset(enp)) != 0)
727 goto fail2;
728
729 enp->en_reset_flags |= EFX_RESET_MAC;
730
731 return (0);
732
733fail2:
734 EFSYS_PROBE(fail2);
735fail1:
736 EFSYS_PROBE1(fail1, efx_rc_t, rc);
737
738 return (rc);
739}
740
741 const efx_nic_cfg_t *
742efx_nic_cfg_get(
743 __in efx_nic_t *enp)
744{
745 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
746
747 return (&(enp->en_nic_cfg));
748}
749
750#if EFSYS_OPT_DIAG
751
752 __checkReturn efx_rc_t
753efx_nic_register_test(
754 __in efx_nic_t *enp)
755{
756 efx_nic_ops_t *enop = enp->en_enop;
757 efx_rc_t rc;
758
759 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
760 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
761 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
762
763 if ((rc = enop->eno_register_test(enp)) != 0)
764 goto fail1;
765
766 return (0);
767
768fail1:
769 EFSYS_PROBE1(fail1, efx_rc_t, rc);
770
771 return (rc);
772}
773
774 __checkReturn efx_rc_t
775efx_nic_test_registers(
776 __in efx_nic_t *enp,
777 __in efx_register_set_t *rsp,
778 __in size_t count)
779{
780 unsigned int bit;
781 efx_oword_t original;
782 efx_oword_t reg;
783 efx_oword_t buf;
784 efx_rc_t rc;
785
786 while (count > 0) {
787 /* This function is only suitable for registers */
788 EFSYS_ASSERT(rsp->rows == 1);
789
790 /* bit sweep on and off */
791 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &original,
792 B_TRUE);
793 for (bit = 0; bit < 128; bit++) {
794 /* Is this bit in the mask? */
795 if (~(rsp->mask.eo_u32[bit >> 5]) & (1 << bit))
796 continue;
797
798 /* Test this bit can be set in isolation */
799 reg = original;
800 EFX_AND_OWORD(reg, rsp->mask);
801 EFX_SET_OWORD_BIT(reg, bit);
802
803 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
804 B_TRUE);
805 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
806 B_TRUE);
807
808 EFX_AND_OWORD(buf, rsp->mask);
809 if (memcmp(&reg, &buf, sizeof (reg))) {
810 rc = EIO;
811 goto fail1;
812 }
813
814 /* Test this bit can be cleared in isolation */
815 EFX_OR_OWORD(reg, rsp->mask);
816 EFX_CLEAR_OWORD_BIT(reg, bit);
817
818 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &reg,
819 B_TRUE);
820 EFSYS_BAR_READO(enp->en_esbp, rsp->address, &buf,
821 B_TRUE);
822
823 EFX_AND_OWORD(buf, rsp->mask);
824 if (memcmp(&reg, &buf, sizeof (reg))) {
825 rc = EIO;
826 goto fail2;
827 }
828 }
829
830 /* Restore the old value */
831 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original,
832 B_TRUE);
833
834 --count;
835 ++rsp;
836 }
837
838 return (0);
839
840fail2:
841 EFSYS_PROBE(fail2);
842fail1:
843 EFSYS_PROBE1(fail1, efx_rc_t, rc);
844
845 /* Restore the old value */
846 EFSYS_BAR_WRITEO(enp->en_esbp, rsp->address, &original, B_TRUE);
847
848 return (rc);
849}
850
851 __checkReturn efx_rc_t
852efx_nic_test_tables(
853 __in efx_nic_t *enp,
854 __in efx_register_set_t *rsp,
855 __in efx_pattern_type_t pattern,
856 __in size_t count)
857{
858 efx_sram_pattern_fn_t func;
859 unsigned int index;
860 unsigned int address;
861 efx_oword_t reg;
862 efx_oword_t buf;
863 efx_rc_t rc;
864
865 EFSYS_ASSERT(pattern < EFX_PATTERN_NTYPES);
866 func = __efx_sram_pattern_fns[pattern];
867
868 while (count > 0) {
869 /* Write */
870 address = rsp->address;
871 for (index = 0; index < rsp->rows; ++index) {
872 func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
873 func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
874 EFX_AND_OWORD(reg, rsp->mask);
875 EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, B_TRUE);
876
877 address += rsp->step;
878 }
879
880 /* Read */
881 address = rsp->address;
882 for (index = 0; index < rsp->rows; ++index) {
883 func(2 * index + 0, B_FALSE, &reg.eo_qword[0]);
884 func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
885 EFX_AND_OWORD(reg, rsp->mask);
886 EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
887 if (memcmp(&reg, &buf, sizeof (reg))) {
888 rc = EIO;
889 goto fail1;
890 }
891
892 address += rsp->step;
893 }
894
895 ++rsp;
896 --count;
897 }
898
899 return (0);
900
901fail1:
902 EFSYS_PROBE1(fail1, efx_rc_t, rc);
903
904 return (rc);
905}
906
907#endif /* EFSYS_OPT_DIAG */
908
909#if EFSYS_OPT_LOOPBACK
910
911extern void
912efx_loopback_mask(
913 __in efx_loopback_kind_t loopback_kind,
914 __out efx_qword_t *maskp)
915{
916 efx_qword_t mask;
917
918 EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
919 EFSYS_ASSERT(maskp != NULL);
920
921 /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
922 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
923 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
924 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
925 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
926 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
927 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
928 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
929 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
930 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
931 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
932 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
933 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
934 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
935 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
936 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
937 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
938 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
939 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
940 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
941 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
942 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
943 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
944 EFX_LOOPBACK_XAUI_WS_FAR);
945 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
946 EFX_LOOPBACK_XAUI_WS_NEAR);
947 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
948 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
949 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
950 EFX_LOOPBACK_XFI_WS_FAR);
951 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
952 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
953 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
954 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
955 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
956 EFX_LOOPBACK_PMA_INT_WS);
957 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
958 EFX_LOOPBACK_SD_FEP2_WS);
959 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
960 EFX_LOOPBACK_SD_FEP1_5_WS);
961 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
962 EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
963
964 /* Build bitmask of possible loopback types */
965 EFX_ZERO_QWORD(mask);
966
967 if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
968 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
969 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
970 }
971
972 if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
973 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
974 /*
975 * The "MAC" grouping has historically been used by drivers to
976 * mean loopbacks supported by on-chip hardware. Keep that
977 * meaning here, and include on-chip PHY layer loopbacks.
978 */
979 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
980 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
981 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
982 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
983 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
984 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
985 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
986 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
987 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
988 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
989 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
990 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
991 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
992 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
993 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
994 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
995 }
996
997 if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
998 (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
999 /*
1000 * The "PHY" grouping has historically been used by drivers to
1001 * mean loopbacks supported by off-chip hardware. Keep that
1002 * meaning here.
1003 */
1004 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
1005 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
1006 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
1007 EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
1008 }
1009
1010 *maskp = mask;
1011}
1012
1013 __checkReturn efx_rc_t
1014efx_mcdi_get_loopback_modes(
1015 __in efx_nic_t *enp)
1016{
1017 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1018 efx_mcdi_req_t req;
1019 uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
1020 MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
1021 efx_qword_t mask;
1022 efx_qword_t modes;
1023 efx_rc_t rc;
1024
1025 (void) memset(payload, 0, sizeof (payload));
1026 req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
1027 req.emr_in_buf = payload;
1028 req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
1029 req.emr_out_buf = payload;
1030 req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
1031
1032 efx_mcdi_execute(enp, &req);
1033
1034 if (req.emr_rc != 0) {
1035 rc = req.emr_rc;
1036 goto fail1;
1037 }
1038
1039 if (req.emr_out_length_used <
1040 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
1041 MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
1042 rc = EMSGSIZE;
1043 goto fail2;
1044 }
1045
1046 /*
1047 * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
1048 * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
1049 */
1050 efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
1051
1052 EFX_AND_QWORD(mask,
1053 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
1054
1055 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
1056 EFX_AND_QWORD(modes, mask);
1057 encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
1058
1059 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
1060 EFX_AND_QWORD(modes, mask);
1061 encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
1062
1063 modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
1064 EFX_AND_QWORD(modes, mask);
1065 encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
1066
1067 if (req.emr_out_length_used >=
1068 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
1069 MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
1070 /* Response includes 40G loopback modes */
1071 modes =
1072 *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
1073 EFX_AND_QWORD(modes, mask);
1074 encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
1075 }
1076
1077 EFX_ZERO_QWORD(modes);
1078 EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
1079 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
1080 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
1081 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
1082 EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
1083 encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
1084
1085 return (0);
1086
1087fail2:
1088 EFSYS_PROBE(fail2);
1089fail1:
1090 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1091
1092 return (rc);
1093}
1094
1095#endif /* EFSYS_OPT_LOOPBACK */