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, &reg,
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(&reg, &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, &reg,
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(&reg, &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, &reg.eo_qword[0]);
741 			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
742 			EFX_AND_OWORD(reg, rsp->mask);
743 			EFSYS_BAR_WRITEO(enp->en_esbp, address, &reg, 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, &reg.eo_qword[0]);
752 			func(2 * index + 1, B_FALSE, &reg.eo_qword[1]);
753 			EFX_AND_OWORD(reg, rsp->mask);
754 			EFSYS_BAR_READO(enp->en_esbp, address, &buf, B_TRUE);
755 			if (memcmp(&reg, &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