efx_phy.c revision 280560
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: stable/10/sys/dev/sfxge/common/efx_phy.c 280560 2015-03-25 11:01:03Z arybchik $");
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
71static 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
98static 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
125static 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
152static 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
179static 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
206static 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
233static 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
260efx_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
329fail1:
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
339efx_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
354efx_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
384done:
385	return (0);
386
387fail2:
388	EFSYS_PROBE(fail2);
389fail1:
390	EFSYS_PROBE1(fail1, int, rc);
391
392	return (rc);
393}
394#endif	/* EFSYS_OPT_PHY_LED_CONTROL */
395
396			void
397efx_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
424efx_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	uint32_t old_mask;
431	int rc;
432
433	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
434	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
435
436	if ((mask & ~epp->ep_phy_cap_mask) != 0) {
437		rc = ENOTSUP;
438		goto fail1;
439	}
440
441	if (epp->ep_adv_cap_mask == mask)
442		goto done;
443
444	old_mask = epp->ep_adv_cap_mask;
445	epp->ep_adv_cap_mask = mask;
446
447	if ((rc = epop->epo_reconfigure(enp)) != 0)
448		goto fail2;
449
450done:
451	return (0);
452
453fail2:
454	EFSYS_PROBE(fail2);
455
456	epp->ep_adv_cap_mask = old_mask;
457	/* Reconfigure for robustness */
458	if (epop->epo_reconfigure(enp) != 0) {
459		/*
460		 * We may have an inconsistent view of our advertised speed
461		 * capabilities.
462		 */
463		EFSYS_ASSERT(0);
464	}
465
466fail1:
467	EFSYS_PROBE1(fail1, int, rc);
468
469	return (rc);
470}
471
472	void
473efx_phy_lp_cap_get(
474	__in		efx_nic_t *enp,
475	__out		uint32_t *maskp)
476{
477	efx_port_t *epp = &(enp->en_port);
478
479	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
480	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
481
482	*maskp = epp->ep_lp_cap_mask;
483}
484
485	__checkReturn	int
486efx_phy_oui_get(
487	__in		efx_nic_t *enp,
488	__out		uint32_t *ouip)
489{
490	efx_port_t *epp = &(enp->en_port);
491	efx_phy_ops_t *epop = epp->ep_epop;
492
493	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
494	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
495
496	return (epop->epo_oui_get(enp, ouip));
497}
498
499			void
500efx_phy_media_type_get(
501	__in		efx_nic_t *enp,
502	__out		efx_phy_media_type_t *typep)
503{
504	efx_port_t *epp = &(enp->en_port);
505
506	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
507	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
508
509	if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
510		*typep = epp->ep_module_type;
511	else
512		*typep = epp->ep_fixed_port_type;
513}
514
515#if EFSYS_OPT_PHY_STATS
516
517#if EFSYS_OPT_NAMES
518
519/* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
520static const char 	__cs * __cs __efx_phy_stat_name[] = {
521	"oui",
522	"pma_pmd_link_up",
523	"pma_pmd_rx_fault",
524	"pma_pmd_tx_fault",
525	"pma_pmd_rev_a",
526	"pma_pmd_rev_b",
527	"pma_pmd_rev_c",
528	"pma_pmd_rev_d",
529	"pcs_link_up",
530	"pcs_rx_fault",
531	"pcs_tx_fault",
532	"pcs_ber",
533	"pcs_block_errors",
534	"phy_xs_link_up",
535	"phy_xs_rx_fault",
536	"phy_xs_tx_fault",
537	"phy_xs_align",
538	"phy_xs_sync_a",
539	"phy_xs_sync_b",
540	"phy_xs_sync_c",
541	"phy_xs_sync_d",
542	"an_link_up",
543	"an_master",
544	"an_local_rx_ok",
545	"an_remote_rx_ok",
546	"cl22ext_link_up",
547	"snr_a",
548	"snr_b",
549	"snr_c",
550	"snr_d",
551	"pma_pmd_signal_a",
552	"pma_pmd_signal_b",
553	"pma_pmd_signal_c",
554	"pma_pmd_signal_d",
555	"an_complete",
556	"pma_pmd_rev_major",
557	"pma_pmd_rev_minor",
558	"pma_pmd_rev_micro",
559	"pcs_fw_version_0",
560	"pcs_fw_version_1",
561	"pcs_fw_version_2",
562	"pcs_fw_version_3",
563	"pcs_fw_build_yy",
564	"pcs_fw_build_mm",
565	"pcs_fw_build_dd",
566	"pcs_op_mode",
567};
568
569/* END MKCONFIG GENERATED PhyStatNamesBlock */
570
571					const char __cs *
572efx_phy_stat_name(
573	__in				efx_nic_t *enp,
574	__in				efx_phy_stat_t type)
575{
576	_NOTE(ARGUNUSED(enp))
577	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
578	EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
579
580	return (__efx_phy_stat_name[type]);
581}
582
583#endif	/* EFSYS_OPT_NAMES */
584
585	__checkReturn			int
586efx_phy_stats_update(
587	__in				efx_nic_t *enp,
588	__in				efsys_mem_t *esmp,
589	__out_ecount(EFX_PHY_NSTATS)	uint32_t *stat)
590{
591	efx_port_t *epp = &(enp->en_port);
592	efx_phy_ops_t *epop = epp->ep_epop;
593
594	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
595	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
596
597	return (epop->epo_stats_update(enp, esmp, stat));
598}
599
600#endif	/* EFSYS_OPT_PHY_STATS */
601
602#if EFSYS_OPT_PHY_PROPS
603
604#if EFSYS_OPT_NAMES
605		const char __cs *
606efx_phy_prop_name(
607	__in	efx_nic_t *enp,
608	__in	unsigned int id)
609{
610	efx_port_t *epp = &(enp->en_port);
611	efx_phy_ops_t *epop = epp->ep_epop;
612
613	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
614	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
615
616	return (epop->epo_prop_name(enp, id));
617}
618#endif	/* EFSYS_OPT_NAMES */
619
620	__checkReturn	int
621efx_phy_prop_get(
622	__in		efx_nic_t *enp,
623	__in		unsigned int id,
624	__in		uint32_t flags,
625	__out		uint32_t *valp)
626{
627	efx_port_t *epp = &(enp->en_port);
628	efx_phy_ops_t *epop = epp->ep_epop;
629
630	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
631	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
632
633	return (epop->epo_prop_get(enp, id, flags, valp));
634}
635
636	__checkReturn	int
637efx_phy_prop_set(
638	__in		efx_nic_t *enp,
639	__in		unsigned int id,
640	__in		uint32_t val)
641{
642	efx_port_t *epp = &(enp->en_port);
643	efx_phy_ops_t *epop = epp->ep_epop;
644
645	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
646	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
647
648	return (epop->epo_prop_set(enp, id, val));
649}
650#endif	/* EFSYS_OPT_PHY_STATS */
651
652#if EFSYS_OPT_PHY_BIST
653
654	__checkReturn		int
655efx_phy_bist_start(
656	__in			efx_nic_t *enp,
657	__in			efx_phy_bist_type_t type)
658{
659	efx_port_t *epp = &(enp->en_port);
660	efx_phy_ops_t *epop = epp->ep_epop;
661	int rc;
662
663	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
664	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
665
666	EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
667	EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
668	EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
669
670	if (epop->epo_bist_start == NULL) {
671		rc = ENOTSUP;
672		goto fail1;
673	}
674
675	if ((rc = epop->epo_bist_start(enp, type)) != 0)
676		goto fail2;
677
678	epp->ep_current_bist = type;
679
680	return (0);
681
682fail2:
683	EFSYS_PROBE(fail2);
684fail1:
685	EFSYS_PROBE1(fail1, int, rc);
686
687	return (rc);
688}
689
690	__checkReturn		int
691efx_phy_bist_poll(
692	__in			efx_nic_t *enp,
693	__in			efx_phy_bist_type_t type,
694	__out			efx_phy_bist_result_t *resultp,
695	__out_opt		uint32_t *value_maskp,
696	__out_ecount_opt(count)	unsigned long *valuesp,
697	__in			size_t count)
698{
699	efx_port_t *epp = &(enp->en_port);
700	efx_phy_ops_t *epop = epp->ep_epop;
701	int rc;
702
703	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
704	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
705
706	EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
707	EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
708	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
709
710	EFSYS_ASSERT(epop->epo_bist_poll != NULL);
711	if (epop->epo_bist_poll == NULL) {
712		rc = ENOTSUP;
713		goto fail1;
714	}
715
716	if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
717	    valuesp, count)) != 0)
718		goto fail2;
719
720	return (0);
721
722fail2:
723	EFSYS_PROBE(fail2);
724fail1:
725	EFSYS_PROBE1(fail1, int, rc);
726
727	return (rc);
728}
729
730			void
731efx_phy_bist_stop(
732	__in		efx_nic_t *enp,
733	__in		efx_phy_bist_type_t type)
734{
735	efx_port_t *epp = &(enp->en_port);
736	efx_phy_ops_t *epop = epp->ep_epop;
737
738	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
739	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
740
741	EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
742	EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
743	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
744
745	EFSYS_ASSERT(epop->epo_bist_stop != NULL);
746
747	if (epop->epo_bist_stop != NULL)
748		epop->epo_bist_stop(enp, type);
749
750	epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
751}
752
753#endif	/* EFSYS_OPT_PHY_BIST */
754			void
755efx_phy_unprobe(
756	__in	efx_nic_t *enp)
757{
758	efx_port_t *epp = &(enp->en_port);
759
760	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
761
762	epp->ep_epop = NULL;
763
764	epp->ep_adv_cap_mask = 0;
765
766	epp->ep_port = 0;
767	epp->ep_phy_type = 0;
768}
769