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
68static 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
95static 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
122static 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
149static 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
176static 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
203static 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
230static 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
257efx_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
326fail1:
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
336efx_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
351efx_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
381done:
382	return (0);
383
384fail2:
385	EFSYS_PROBE(fail2);
386fail1:
387	EFSYS_PROBE1(fail1, int, rc);
388
389	return (rc);
390}
391#endif	/* EFSYS_OPT_PHY_LED_CONTROL */
392
393			void
394efx_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
421efx_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
445done:
446	return (0);
447
448fail2:
449	EFSYS_PROBE(fail2);
450fail1:
451	EFSYS_PROBE1(fail1, int, rc);
452
453	return (rc);
454}
455
456	void
457efx_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
470efx_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
484efx_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 */
504static 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 *
556efx_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
570efx_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 *
590efx_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
605efx_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
621efx_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
639efx_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
666fail2:
667	EFSYS_PROBE(fail2);
668fail1:
669	EFSYS_PROBE1(fail1, int, rc);
670
671	return (rc);
672}
673
674	__checkReturn		int
675efx_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
706fail2:
707	EFSYS_PROBE(fail2);
708fail1:
709	EFSYS_PROBE1(fail1, int, rc);
710
711	return (rc);
712}
713
714			void
715efx_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
739efx_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