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