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