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