xref: /freebsd/sys/dev/sfxge/common/efx_phy.c (revision ab0b9f6b3073e6c4d1dfbf07444d7db67a189a96)
1 /*-
2  * Copyright 2007-2009 Solarflare Communications Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28 
29 #include "efsys.h"
30 #include "efx.h"
31 #include "efx_types.h"
32 #include "efx_regs.h"
33 #include "efx_impl.h"
34 #if EFSYS_OPT_FALCON
35 #include "falcon_nvram.h"
36 #endif
37 
38 #if EFSYS_OPT_MAC_FALCON_XMAC
39 #include "falcon_xmac.h"
40 #endif
41 
42 #if EFSYS_OPT_MAC_FALCON_GMAC
43 #include "falcon_gmac.h"
44 #endif
45 
46 #if EFSYS_OPT_PHY_NULL
47 #include "nullphy.h"
48 #endif
49 
50 #if EFSYS_OPT_PHY_QT2022C2
51 #include "qt2022c2.h"
52 #endif
53 
54 #if EFSYS_OPT_PHY_SFX7101
55 #include "sfx7101.h"
56 #endif
57 
58 #if EFSYS_OPT_PHY_TXC43128
59 #include "txc43128.h"
60 #endif
61 
62 #if EFSYS_OPT_PHY_SFT9001
63 #include "sft9001.h"
64 #endif
65 
66 #if EFSYS_OPT_PHY_QT2025C
67 #include "qt2025c.h"
68 #endif
69 
70 #if EFSYS_OPT_PHY_NULL
71 static efx_phy_ops_t	__cs __efx_phy_null_ops = {
72 	NULL,				/* epo_power */
73 	nullphy_reset,			/* epo_reset */
74 	nullphy_reconfigure,		/* epo_reconfigure */
75 	nullphy_verify,			/* epo_verify */
76 	NULL,				/* epo_uplink_check */
77 	nullphy_downlink_check,		/* epo_downlink_check */
78 	nullphy_oui_get,		/* epo_oui_get */
79 #if EFSYS_OPT_PHY_STATS
80 	nullphy_stats_update,		/* epo_stats_update */
81 #endif	/* EFSYS_OPT_PHY_STATS */
82 #if EFSYS_OPT_PHY_PROPS
83 #if EFSYS_OPT_NAMES
84 	nullphy_prop_name,		/* epo_prop_name */
85 #endif
86 	nullphy_prop_get,		/* epo_prop_get */
87 	nullphy_prop_set,		/* epo_prop_set */
88 #endif	/* EFSYS_OPT_PHY_PROPS */
89 #if EFSYS_OPT_PHY_BIST
90 	NULL,				/* epo_bist_start */
91 	NULL,				/* epo_bist_poll */
92 	NULL,				/* epo_bist_stop */
93 #endif	/* EFSYS_OPT_PHY_BIST */
94 };
95 #endif	/* EFSYS_OPT_PHY_NULL */
96 
97 #if EFSYS_OPT_PHY_QT2022C2
98 static efx_phy_ops_t	__cs __efx_phy_qt2022c2_ops = {
99 	NULL,				/* epo_power */
100 	qt2022c2_reset,			/* epo_reset */
101 	qt2022c2_reconfigure,		/* epo_reconfigure */
102 	qt2022c2_verify,		/* epo_verify */
103 	qt2022c2_uplink_check,		/* epo_uplink_check */
104 	qt2022c2_downlink_check,	/* epo_downlink_check */
105 	qt2022c2_oui_get,		/* epo_oui_get */
106 #if EFSYS_OPT_PHY_STATS
107 	qt2022c2_stats_update,		/* epo_stats_update */
108 #endif	/* EFSYS_OPT_PHY_STATS */
109 #if EFSYS_OPT_PHY_PROPS
110 #if EFSYS_OPT_NAMES
111 	qt2022c2_prop_name,		/* epo_prop_name */
112 #endif
113 	qt2022c2_prop_get,		/* epo_prop_get */
114 	qt2022c2_prop_set,		/* epo_prop_set */
115 #endif	/* EFSYS_OPT_PHY_PROPS */
116 #if EFSYS_OPT_PHY_BIST
117 	NULL,				/* epo_bist_start */
118 	NULL,				/* epo_bist_poll */
119 	NULL,				/* epo_bist_stop */
120 #endif	/* EFSYS_OPT_PHY_BIST */
121 };
122 #endif	/* EFSYS_OPT_PHY_QT2022C2 */
123 
124 #if EFSYS_OPT_PHY_SFX7101
125 static efx_phy_ops_t	__cs __efx_phy_sfx7101_ops = {
126 	sfx7101_power,			/* epo_power */
127 	sfx7101_reset,			/* epo_reset */
128 	sfx7101_reconfigure,		/* epo_reconfigure */
129 	sfx7101_verify,			/* epo_verify */
130 	sfx7101_uplink_check,		/* epo_uplink_check */
131 	sfx7101_downlink_check,		/* epo_downlink_check */
132 	sfx7101_oui_get,		/* epo_oui_get */
133 #if EFSYS_OPT_PHY_STATS
134 	sfx7101_stats_update,		/* epo_stats_update */
135 #endif	/* EFSYS_OPT_PHY_STATS */
136 #if EFSYS_OPT_PHY_PROPS
137 #if EFSYS_OPT_NAMES
138 	sfx7101_prop_name,		/* epo_prop_name */
139 #endif
140 	sfx7101_prop_get,		/* epo_prop_get */
141 	sfx7101_prop_set,		/* epo_prop_set */
142 #endif	/* EFSYS_OPT_PHY_PROPS */
143 #if EFSYS_OPT_PHY_BIST
144 	NULL,				/* epo_bist_start */
145 	NULL,				/* epo_bist_poll */
146 	NULL,				/* epo_bist_stop */
147 #endif	/* EFSYS_OPT_PHY_BIST */
148 };
149 #endif	/* EFSYS_OPT_PHY_SFX7101 */
150 
151 #if EFSYS_OPT_PHY_TXC43128
152 static efx_phy_ops_t	__cs __efx_phy_txc43128_ops = {
153 	NULL,				/* epo_power */
154 	txc43128_reset,			/* epo_reset */
155 	txc43128_reconfigure,		/* epo_reconfigure */
156 	txc43128_verify,		/* epo_verify */
157 	txc43128_uplink_check,		/* epo_uplink_check */
158 	txc43128_downlink_check,	/* epo_downlink_check */
159 	txc43128_oui_get,		/* epo_oui_get */
160 #if EFSYS_OPT_PHY_STATS
161 	txc43128_stats_update,		/* epo_stats_update */
162 #endif	/* EFSYS_OPT_PHY_STATS */
163 #if EFSYS_OPT_PHY_PROPS
164 #if EFSYS_OPT_NAMES
165 	txc43128_prop_name,		/* epo_prop_name */
166 #endif
167 	txc43128_prop_get,		/* epo_prop_get */
168 	txc43128_prop_set,		/* epo_prop_set */
169 #endif	/* EFSYS_OPT_PHY_PROPS */
170 #if EFSYS_OPT_PHY_BIST
171 	NULL,				/* epo_bist_start */
172 	NULL,				/* epo_bist_poll */
173 	NULL,				/* epo_bist_stop */
174 #endif	/* EFSYS_OPT_PHY_BIST */
175 };
176 #endif	/* EFSYS_OPT_PHY_TXC43128 */
177 
178 #if EFSYS_OPT_PHY_SFT9001
179 static efx_phy_ops_t	__cs __efx_phy_sft9001_ops = {
180 	NULL,				/* epo_power */
181 	sft9001_reset,			/* epo_reset */
182 	sft9001_reconfigure,		/* epo_reconfigure */
183 	sft9001_verify,			/* epo_verify */
184 	sft9001_uplink_check,		/* epo_uplink_check */
185 	sft9001_downlink_check,		/* epo_downlink_check */
186 	sft9001_oui_get,		/* epo_oui_get */
187 #if EFSYS_OPT_PHY_STATS
188 	sft9001_stats_update,		/* epo_stats_update */
189 #endif	/* EFSYS_OPT_PHY_STATS */
190 #if EFSYS_OPT_PHY_PROPS
191 #if EFSYS_OPT_NAMES
192 	sft9001_prop_name,		/* epo_prop_name */
193 #endif
194 	sft9001_prop_get,		/* epo_prop_get */
195 	sft9001_prop_set,		/* epo_prop_set */
196 #endif	/* EFSYS_OPT_PHY_PROPS */
197 #if EFSYS_OPT_PHY_BIST
198 	sft9001_bist_start,		/* epo_bist_start */
199 	sft9001_bist_poll,		/* epo_bist_poll */
200 	sft9001_bist_stop,		/* epo_bist_stop */
201 #endif	/* EFSYS_OPT_PHY_BIST */
202 };
203 #endif	/* EFSYS_OPT_PHY_SFT9001 */
204 
205 #if EFSYS_OPT_PHY_QT2025C
206 static efx_phy_ops_t	__cs __efx_phy_qt2025c_ops = {
207 	NULL,				/* epo_power */
208 	qt2025c_reset,			/* epo_reset */
209 	qt2025c_reconfigure,		/* epo_reconfigure */
210 	qt2025c_verify,			/* epo_verify */
211 	qt2025c_uplink_check,		/* epo_uplink_check */
212 	qt2025c_downlink_check,		/* epo_downlink_check */
213 	qt2025c_oui_get,		/* epo_oui_get */
214 #if EFSYS_OPT_PHY_STATS
215 	qt2025c_stats_update,		/* epo_stats_update */
216 #endif	/* EFSYS_OPT_PHY_STATS */
217 #if EFSYS_OPT_PHY_PROPS
218 #if EFSYS_OPT_NAMES
219 	qt2025c_prop_name,		/* epo_prop_name */
220 #endif
221 	qt2025c_prop_get,		/* epo_prop_get */
222 	qt2025c_prop_set,		/* epo_prop_set */
223 #endif	/* EFSYS_OPT_PHY_PROPS */
224 #if EFSYS_OPT_PHY_BIST
225 	NULL,				/* epo_bist_start */
226 	NULL,				/* epo_bist_poll */
227 	NULL,				/* epo_bist_stop */
228 #endif	/* EFSYS_OPT_PHY_BIST */
229 };
230 #endif	/* EFSYS_OPT_PHY_QT2025C */
231 
232 #if EFSYS_OPT_SIENA
233 static efx_phy_ops_t	__cs __efx_phy_siena_ops = {
234 	siena_phy_power,		/* epo_power */
235 	NULL,				/* epo_reset */
236 	siena_phy_reconfigure,		/* epo_reconfigure */
237 	siena_phy_verify,		/* epo_verify */
238 	NULL,				/* epo_uplink_check */
239 	NULL,				/* epo_downlink_check */
240 	siena_phy_oui_get,		/* epo_oui_get */
241 #if EFSYS_OPT_PHY_STATS
242 	siena_phy_stats_update,		/* epo_stats_update */
243 #endif	/* EFSYS_OPT_PHY_STATS */
244 #if EFSYS_OPT_PHY_PROPS
245 #if EFSYS_OPT_NAMES
246 	siena_phy_prop_name,		/* epo_prop_name */
247 #endif
248 	siena_phy_prop_get,		/* epo_prop_get */
249 	siena_phy_prop_set,		/* epo_prop_set */
250 #endif	/* EFSYS_OPT_PHY_PROPS */
251 #if EFSYS_OPT_PHY_BIST
252 	siena_phy_bist_start, 		/* epo_bist_start */
253 	siena_phy_bist_poll,		/* epo_bist_poll */
254 	siena_phy_bist_stop,		/* epo_bist_stop */
255 #endif	/* EFSYS_OPT_PHY_BIST */
256 };
257 #endif	/* EFSYS_OPT_SIENA */
258 
259 	__checkReturn	int
260 efx_phy_probe(
261 	__in		efx_nic_t *enp)
262 {
263 	efx_port_t *epp = &(enp->en_port);
264 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
265 	efx_phy_ops_t *epop;
266 	int rc;
267 
268 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
269 
270 	epp->ep_port = encp->enc_port;
271 	epp->ep_phy_type = encp->enc_phy_type;
272 
273 	/* Hook in operations structure */
274 	switch (enp->en_family) {
275 #if EFSYS_OPT_FALCON
276 	case EFX_FAMILY_FALCON:
277 		switch (epp->ep_phy_type) {
278 #if EFSYS_OPT_PHY_NULL
279 		case PHY_TYPE_NONE_DECODE:
280 			epop = (efx_phy_ops_t *)&__efx_phy_null_ops;
281 			break;
282 #endif
283 #if EFSYS_OPT_PHY_QT2022C2
284 		case PHY_TYPE_QT2022C2_DECODE:
285 			epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops;
286 			break;
287 #endif
288 #if EFSYS_OPT_PHY_SFX7101
289 		case PHY_TYPE_SFX7101_DECODE:
290 			epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops;
291 			break;
292 #endif
293 #if EFSYS_OPT_PHY_TXC43128
294 		case PHY_TYPE_TXC43128_DECODE:
295 			epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops;
296 			break;
297 #endif
298 #if EFSYS_OPT_PHY_SFT9001
299 		case PHY_TYPE_SFT9001A_DECODE:
300 		case PHY_TYPE_SFT9001B_DECODE:
301 			epop = (efx_phy_ops_t *)&__efx_phy_sft9001_ops;
302 			break;
303 #endif
304 #if EFSYS_OPT_PHY_QT2025C
305 		case EFX_PHY_QT2025C:
306 			epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops;
307 			break;
308 #endif
309 		default:
310 			rc = ENOTSUP;
311 			goto fail1;
312 		}
313 		break;
314 #endif	/* EFSYS_OPT_FALCON */
315 #if EFSYS_OPT_SIENA
316 	case EFX_FAMILY_SIENA:
317 		epop = (efx_phy_ops_t *)&__efx_phy_siena_ops;
318 		break;
319 #endif	/* EFSYS_OPT_SIENA */
320 	default:
321 		rc = ENOTSUP;
322 		goto fail1;
323 	}
324 
325 	epp->ep_epop = epop;
326 
327 	return (0);
328 
329 fail1:
330 	EFSYS_PROBE1(fail1, int, rc);
331 
332 	epp->ep_port = 0;
333 	epp->ep_phy_type = 0;
334 
335 	return (rc);
336 }
337 
338 	__checkReturn	int
339 efx_phy_verify(
340 	__in		efx_nic_t *enp)
341 {
342 	efx_port_t *epp = &(enp->en_port);
343 	efx_phy_ops_t *epop = epp->ep_epop;
344 
345 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
346 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
347 
348 	return (epop->epo_verify(enp));
349 }
350 
351 #if EFSYS_OPT_PHY_LED_CONTROL
352 
353 	__checkReturn	int
354 efx_phy_led_set(
355 	__in		efx_nic_t *enp,
356 	__in		efx_phy_led_mode_t mode)
357 {
358 	efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
359 	efx_port_t *epp = &(enp->en_port);
360 	efx_phy_ops_t *epop = epp->ep_epop;
361 	uint32_t mask;
362 	int rc;
363 
364 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
365 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
366 
367 	if (epp->ep_phy_led_mode == mode)
368 		goto done;
369 
370 	mask = (1 << EFX_PHY_LED_DEFAULT);
371 	mask |= encp->enc_led_mask;
372 
373 	if (!((1 << mode) & mask)) {
374 		rc = ENOTSUP;
375 		goto fail1;
376 	}
377 
378 	EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
379 	epp->ep_phy_led_mode = mode;
380 
381 	if ((rc = epop->epo_reconfigure(enp)) != 0)
382 		goto fail2;
383 
384 done:
385 	return (0);
386 
387 fail2:
388 	EFSYS_PROBE(fail2);
389 fail1:
390 	EFSYS_PROBE1(fail1, int, rc);
391 
392 	return (rc);
393 }
394 #endif	/* EFSYS_OPT_PHY_LED_CONTROL */
395 
396 			void
397 efx_phy_adv_cap_get(
398 	__in		efx_nic_t *enp,
399 	__in		uint32_t flag,
400 	__out		uint32_t *maskp)
401 {
402 	efx_port_t *epp = &(enp->en_port);
403 
404 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
405 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
406 
407 	switch (flag) {
408 	case EFX_PHY_CAP_CURRENT:
409 		*maskp = epp->ep_adv_cap_mask;
410 		break;
411 	case EFX_PHY_CAP_DEFAULT:
412 		*maskp = epp->ep_default_adv_cap_mask;
413 		break;
414 	case EFX_PHY_CAP_PERM:
415 		*maskp = epp->ep_phy_cap_mask;
416 		break;
417 	default:
418 		EFSYS_ASSERT(B_FALSE);
419 		break;
420 	}
421 }
422 
423 	__checkReturn	int
424 efx_phy_adv_cap_set(
425 	__in		efx_nic_t *enp,
426 	__in		uint32_t mask)
427 {
428 	efx_port_t *epp = &(enp->en_port);
429 	efx_phy_ops_t *epop = epp->ep_epop;
430 	int rc;
431 
432 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
433 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
434 
435 	if ((mask & ~epp->ep_phy_cap_mask) != 0) {
436 		rc = ENOTSUP;
437 		goto fail1;
438 	}
439 
440 	if (epp->ep_adv_cap_mask == mask)
441 		goto done;
442 
443 	epp->ep_adv_cap_mask = mask;
444 
445 	if ((rc = epop->epo_reconfigure(enp)) != 0)
446 		goto fail2;
447 
448 done:
449 	return (0);
450 
451 fail2:
452 	EFSYS_PROBE(fail2);
453 fail1:
454 	EFSYS_PROBE1(fail1, int, rc);
455 
456 	return (rc);
457 }
458 
459 	void
460 efx_phy_lp_cap_get(
461 	__in		efx_nic_t *enp,
462 	__out		uint32_t *maskp)
463 {
464 	efx_port_t *epp = &(enp->en_port);
465 
466 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
467 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
468 
469 	*maskp = epp->ep_lp_cap_mask;
470 }
471 
472 	__checkReturn	int
473 efx_phy_oui_get(
474 	__in		efx_nic_t *enp,
475 	__out		uint32_t *ouip)
476 {
477 	efx_port_t *epp = &(enp->en_port);
478 	efx_phy_ops_t *epop = epp->ep_epop;
479 
480 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
481 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
482 
483 	return (epop->epo_oui_get(enp, ouip));
484 }
485 
486 			void
487 efx_phy_media_type_get(
488 	__in		efx_nic_t *enp,
489 	__out		efx_phy_media_type_t *typep)
490 {
491 	efx_port_t *epp = &(enp->en_port);
492 
493 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
494 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
495 
496 	if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
497 		*typep = epp->ep_module_type;
498 	else
499 		*typep = epp->ep_fixed_port_type;
500 }
501 
502 #if EFSYS_OPT_PHY_STATS
503 
504 #if EFSYS_OPT_NAMES
505 
506 /* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
507 static const char 	__cs * __cs __efx_phy_stat_name[] = {
508 	"oui",
509 	"pma_pmd_link_up",
510 	"pma_pmd_rx_fault",
511 	"pma_pmd_tx_fault",
512 	"pma_pmd_rev_a",
513 	"pma_pmd_rev_b",
514 	"pma_pmd_rev_c",
515 	"pma_pmd_rev_d",
516 	"pcs_link_up",
517 	"pcs_rx_fault",
518 	"pcs_tx_fault",
519 	"pcs_ber",
520 	"pcs_block_errors",
521 	"phy_xs_link_up",
522 	"phy_xs_rx_fault",
523 	"phy_xs_tx_fault",
524 	"phy_xs_align",
525 	"phy_xs_sync_a",
526 	"phy_xs_sync_b",
527 	"phy_xs_sync_c",
528 	"phy_xs_sync_d",
529 	"an_link_up",
530 	"an_master",
531 	"an_local_rx_ok",
532 	"an_remote_rx_ok",
533 	"cl22ext_link_up",
534 	"snr_a",
535 	"snr_b",
536 	"snr_c",
537 	"snr_d",
538 	"pma_pmd_signal_a",
539 	"pma_pmd_signal_b",
540 	"pma_pmd_signal_c",
541 	"pma_pmd_signal_d",
542 	"an_complete",
543 	"pma_pmd_rev_major",
544 	"pma_pmd_rev_minor",
545 	"pma_pmd_rev_micro",
546 	"pcs_fw_version_0",
547 	"pcs_fw_version_1",
548 	"pcs_fw_version_2",
549 	"pcs_fw_version_3",
550 	"pcs_fw_build_yy",
551 	"pcs_fw_build_mm",
552 	"pcs_fw_build_dd",
553 	"pcs_op_mode",
554 };
555 
556 /* END MKCONFIG GENERATED PhyStatNamesBlock */
557 
558 					const char __cs *
559 efx_phy_stat_name(
560 	__in				efx_nic_t *enp,
561 	__in				efx_phy_stat_t type)
562 {
563 	_NOTE(ARGUNUSED(enp))
564 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
565 	EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
566 
567 	return (__efx_phy_stat_name[type]);
568 }
569 
570 #endif	/* EFSYS_OPT_NAMES */
571 
572 	__checkReturn			int
573 efx_phy_stats_update(
574 	__in				efx_nic_t *enp,
575 	__in				efsys_mem_t *esmp,
576 	__out_ecount(EFX_PHY_NSTATS)	uint32_t *stat)
577 {
578 	efx_port_t *epp = &(enp->en_port);
579 	efx_phy_ops_t *epop = epp->ep_epop;
580 
581 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
582 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
583 
584 	return (epop->epo_stats_update(enp, esmp, stat));
585 }
586 
587 #endif	/* EFSYS_OPT_PHY_STATS */
588 
589 #if EFSYS_OPT_PHY_PROPS
590 
591 #if EFSYS_OPT_NAMES
592 		const char __cs *
593 efx_phy_prop_name(
594 	__in	efx_nic_t *enp,
595 	__in	unsigned int id)
596 {
597 	efx_port_t *epp = &(enp->en_port);
598 	efx_phy_ops_t *epop = epp->ep_epop;
599 
600 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
601 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
602 
603 	return (epop->epo_prop_name(enp, id));
604 }
605 #endif	/* EFSYS_OPT_NAMES */
606 
607 	__checkReturn	int
608 efx_phy_prop_get(
609 	__in		efx_nic_t *enp,
610 	__in		unsigned int id,
611 	__in		uint32_t flags,
612 	__out		uint32_t *valp)
613 {
614 	efx_port_t *epp = &(enp->en_port);
615 	efx_phy_ops_t *epop = epp->ep_epop;
616 
617 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
618 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
619 
620 	return (epop->epo_prop_get(enp, id, flags, valp));
621 }
622 
623 	__checkReturn	int
624 efx_phy_prop_set(
625 	__in		efx_nic_t *enp,
626 	__in		unsigned int id,
627 	__in		uint32_t val)
628 {
629 	efx_port_t *epp = &(enp->en_port);
630 	efx_phy_ops_t *epop = epp->ep_epop;
631 
632 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
633 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
634 
635 	return (epop->epo_prop_set(enp, id, val));
636 }
637 #endif	/* EFSYS_OPT_PHY_STATS */
638 
639 #if EFSYS_OPT_PHY_BIST
640 
641 	__checkReturn		int
642 efx_phy_bist_start(
643 	__in			efx_nic_t *enp,
644 	__in			efx_phy_bist_type_t type)
645 {
646 	efx_port_t *epp = &(enp->en_port);
647 	efx_phy_ops_t *epop = epp->ep_epop;
648 	int rc;
649 
650 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
651 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
652 
653 	EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
654 	EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
655 	EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
656 
657 	if (epop->epo_bist_start == NULL) {
658 		rc = ENOTSUP;
659 		goto fail1;
660 	}
661 
662 	if ((rc = epop->epo_bist_start(enp, type)) != 0)
663 		goto fail2;
664 
665 	epp->ep_current_bist = type;
666 
667 	return (0);
668 
669 fail2:
670 	EFSYS_PROBE(fail2);
671 fail1:
672 	EFSYS_PROBE1(fail1, int, rc);
673 
674 	return (rc);
675 }
676 
677 	__checkReturn		int
678 efx_phy_bist_poll(
679 	__in			efx_nic_t *enp,
680 	__in			efx_phy_bist_type_t type,
681 	__out			efx_phy_bist_result_t *resultp,
682 	__out_opt		uint32_t *value_maskp,
683 	__out_ecount_opt(count)	unsigned long *valuesp,
684 	__in			size_t count)
685 {
686 	efx_port_t *epp = &(enp->en_port);
687 	efx_phy_ops_t *epop = epp->ep_epop;
688 	int rc;
689 
690 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
691 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
692 
693 	EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
694 	EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
695 	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
696 
697 	EFSYS_ASSERT(epop->epo_bist_poll != NULL);
698 	if (epop->epo_bist_poll == NULL) {
699 		rc = ENOTSUP;
700 		goto fail1;
701 	}
702 
703 	if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
704 	    valuesp, count)) != 0)
705 		goto fail2;
706 
707 	return (0);
708 
709 fail2:
710 	EFSYS_PROBE(fail2);
711 fail1:
712 	EFSYS_PROBE1(fail1, int, rc);
713 
714 	return (rc);
715 }
716 
717 			void
718 efx_phy_bist_stop(
719 	__in		efx_nic_t *enp,
720 	__in		efx_phy_bist_type_t type)
721 {
722 	efx_port_t *epp = &(enp->en_port);
723 	efx_phy_ops_t *epop = epp->ep_epop;
724 
725 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
726 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
727 
728 	EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
729 	EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
730 	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
731 
732 	EFSYS_ASSERT(epop->epo_bist_stop != NULL);
733 
734 	if (epop->epo_bist_stop != NULL)
735 		epop->epo_bist_stop(enp, type);
736 
737 	epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
738 }
739 
740 #endif	/* EFSYS_OPT_PHY_BIST */
741 			void
742 efx_phy_unprobe(
743 	__in	efx_nic_t *enp)
744 {
745 	efx_port_t *epp = &(enp->en_port);
746 
747 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
748 
749 	epp->ep_epop = NULL;
750 
751 	epp->ep_adv_cap_mask = 0;
752 
753 	epp->ep_port = 0;
754 	epp->ep_phy_type = 0;
755 }
756