xref: /freebsd/sys/dev/sfxge/common/efx_phy.c (revision cdf63a700c77204252e3c2e38d7106965559f3c6)
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 
37 
38 #if EFSYS_OPT_SIENA
39 static const efx_phy_ops_t	__efx_phy_siena_ops = {
40 	siena_phy_power,		/* epo_power */
41 	NULL,				/* epo_reset */
42 	siena_phy_reconfigure,		/* epo_reconfigure */
43 	siena_phy_verify,		/* epo_verify */
44 	NULL,				/* epo_uplink_check */
45 	NULL,				/* epo_downlink_check */
46 	siena_phy_oui_get,		/* epo_oui_get */
47 #if EFSYS_OPT_PHY_STATS
48 	siena_phy_stats_update,		/* epo_stats_update */
49 #endif	/* EFSYS_OPT_PHY_STATS */
50 #if EFSYS_OPT_PHY_PROPS
51 #if EFSYS_OPT_NAMES
52 	siena_phy_prop_name,		/* epo_prop_name */
53 #endif
54 	siena_phy_prop_get,		/* epo_prop_get */
55 	siena_phy_prop_set,		/* epo_prop_set */
56 #endif	/* EFSYS_OPT_PHY_PROPS */
57 #if EFSYS_OPT_BIST
58 	NULL,				/* epo_bist_enable_offline */
59 	siena_phy_bist_start, 		/* epo_bist_start */
60 	siena_phy_bist_poll,		/* epo_bist_poll */
61 	siena_phy_bist_stop,		/* epo_bist_stop */
62 #endif	/* EFSYS_OPT_BIST */
63 };
64 #endif	/* EFSYS_OPT_SIENA */
65 
66 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
67 static const efx_phy_ops_t	__efx_phy_ef10_ops = {
68 	ef10_phy_power,			/* epo_power */
69 	NULL,				/* epo_reset */
70 	ef10_phy_reconfigure,		/* epo_reconfigure */
71 	ef10_phy_verify,		/* epo_verify */
72 	NULL,				/* epo_uplink_check */
73 	NULL,				/* epo_downlink_check */
74 	ef10_phy_oui_get,		/* epo_oui_get */
75 #if EFSYS_OPT_PHY_STATS
76 	ef10_phy_stats_update,		/* epo_stats_update */
77 #endif	/* EFSYS_OPT_PHY_STATS */
78 #if EFSYS_OPT_PHY_PROPS
79 #if EFSYS_OPT_NAMES
80 	ef10_phy_prop_name,		/* epo_prop_name */
81 #endif
82 	ef10_phy_prop_get,		/* epo_prop_get */
83 	ef10_phy_prop_set,		/* epo_prop_set */
84 #endif	/* EFSYS_OPT_PHY_PROPS */
85 #if EFSYS_OPT_BIST
86 	/* FIXME: Are these BIST methods appropriate for Medford? */
87 	hunt_bist_enable_offline,	/* epo_bist_enable_offline */
88 	hunt_bist_start,		/* epo_bist_start */
89 	hunt_bist_poll,			/* epo_bist_poll */
90 	hunt_bist_stop,			/* epo_bist_stop */
91 #endif	/* EFSYS_OPT_BIST */
92 };
93 #endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
94 
95 	__checkReturn	efx_rc_t
96 efx_phy_probe(
97 	__in		efx_nic_t *enp)
98 {
99 	efx_port_t *epp = &(enp->en_port);
100 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
101 	const efx_phy_ops_t *epop;
102 	efx_rc_t rc;
103 
104 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
105 
106 	epp->ep_port = encp->enc_port;
107 	epp->ep_phy_type = encp->enc_phy_type;
108 
109 	/* Hook in operations structure */
110 	switch (enp->en_family) {
111 #if EFSYS_OPT_SIENA
112 	case EFX_FAMILY_SIENA:
113 		epop = &__efx_phy_siena_ops;
114 		break;
115 #endif	/* EFSYS_OPT_SIENA */
116 #if EFSYS_OPT_HUNTINGTON
117 	case EFX_FAMILY_HUNTINGTON:
118 		epop = &__efx_phy_ef10_ops;
119 		break;
120 #endif	/* EFSYS_OPT_HUNTINGTON */
121 #if EFSYS_OPT_MEDFORD
122 	case EFX_FAMILY_MEDFORD:
123 		epop = &__efx_phy_ef10_ops;
124 		break;
125 #endif	/* EFSYS_OPT_MEDFORD */
126 	default:
127 		rc = ENOTSUP;
128 		goto fail1;
129 	}
130 
131 	epp->ep_epop = epop;
132 
133 	return (0);
134 
135 fail1:
136 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
137 
138 	epp->ep_port = 0;
139 	epp->ep_phy_type = 0;
140 
141 	return (rc);
142 }
143 
144 	__checkReturn	efx_rc_t
145 efx_phy_verify(
146 	__in		efx_nic_t *enp)
147 {
148 	efx_port_t *epp = &(enp->en_port);
149 	const efx_phy_ops_t *epop = epp->ep_epop;
150 
151 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
152 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
153 
154 	return (epop->epo_verify(enp));
155 }
156 
157 #if EFSYS_OPT_PHY_LED_CONTROL
158 
159 	__checkReturn	efx_rc_t
160 efx_phy_led_set(
161 	__in		efx_nic_t *enp,
162 	__in		efx_phy_led_mode_t mode)
163 {
164 	efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
165 	efx_port_t *epp = &(enp->en_port);
166 	const efx_phy_ops_t *epop = epp->ep_epop;
167 	uint32_t mask;
168 	efx_rc_t rc;
169 
170 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
171 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
172 
173 	if (epp->ep_phy_led_mode == mode)
174 		goto done;
175 
176 	mask = (1 << EFX_PHY_LED_DEFAULT);
177 	mask |= encp->enc_led_mask;
178 
179 	if (!((1 << mode) & mask)) {
180 		rc = ENOTSUP;
181 		goto fail1;
182 	}
183 
184 	EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
185 	epp->ep_phy_led_mode = mode;
186 
187 	if ((rc = epop->epo_reconfigure(enp)) != 0)
188 		goto fail2;
189 
190 done:
191 	return (0);
192 
193 fail2:
194 	EFSYS_PROBE(fail2);
195 fail1:
196 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
197 
198 	return (rc);
199 }
200 #endif	/* EFSYS_OPT_PHY_LED_CONTROL */
201 
202 			void
203 efx_phy_adv_cap_get(
204 	__in		efx_nic_t *enp,
205 	__in		uint32_t flag,
206 	__out		uint32_t *maskp)
207 {
208 	efx_port_t *epp = &(enp->en_port);
209 
210 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
211 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
212 
213 	switch (flag) {
214 	case EFX_PHY_CAP_CURRENT:
215 		*maskp = epp->ep_adv_cap_mask;
216 		break;
217 	case EFX_PHY_CAP_DEFAULT:
218 		*maskp = epp->ep_default_adv_cap_mask;
219 		break;
220 	case EFX_PHY_CAP_PERM:
221 		*maskp = epp->ep_phy_cap_mask;
222 		break;
223 	default:
224 		EFSYS_ASSERT(B_FALSE);
225 		break;
226 	}
227 }
228 
229 	__checkReturn	efx_rc_t
230 efx_phy_adv_cap_set(
231 	__in		efx_nic_t *enp,
232 	__in		uint32_t mask)
233 {
234 	efx_port_t *epp = &(enp->en_port);
235 	const efx_phy_ops_t *epop = epp->ep_epop;
236 	uint32_t old_mask;
237 	efx_rc_t rc;
238 
239 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
240 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
241 
242 	if ((mask & ~epp->ep_phy_cap_mask) != 0) {
243 		rc = ENOTSUP;
244 		goto fail1;
245 	}
246 
247 	if (epp->ep_adv_cap_mask == mask)
248 		goto done;
249 
250 	old_mask = epp->ep_adv_cap_mask;
251 	epp->ep_adv_cap_mask = mask;
252 
253 	if ((rc = epop->epo_reconfigure(enp)) != 0)
254 		goto fail2;
255 
256 done:
257 	return (0);
258 
259 fail2:
260 	EFSYS_PROBE(fail2);
261 
262 	epp->ep_adv_cap_mask = old_mask;
263 	/* Reconfigure for robustness */
264 	if (epop->epo_reconfigure(enp) != 0) {
265 		/*
266 		 * We may have an inconsistent view of our advertised speed
267 		 * capabilities.
268 		 */
269 		EFSYS_ASSERT(0);
270 	}
271 
272 fail1:
273 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
274 
275 	return (rc);
276 }
277 
278 	void
279 efx_phy_lp_cap_get(
280 	__in		efx_nic_t *enp,
281 	__out		uint32_t *maskp)
282 {
283 	efx_port_t *epp = &(enp->en_port);
284 
285 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
286 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
287 
288 	*maskp = epp->ep_lp_cap_mask;
289 }
290 
291 	__checkReturn	efx_rc_t
292 efx_phy_oui_get(
293 	__in		efx_nic_t *enp,
294 	__out		uint32_t *ouip)
295 {
296 	efx_port_t *epp = &(enp->en_port);
297 	const efx_phy_ops_t *epop = epp->ep_epop;
298 
299 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
300 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
301 
302 	return (epop->epo_oui_get(enp, ouip));
303 }
304 
305 			void
306 efx_phy_media_type_get(
307 	__in		efx_nic_t *enp,
308 	__out		efx_phy_media_type_t *typep)
309 {
310 	efx_port_t *epp = &(enp->en_port);
311 
312 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
313 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
314 
315 	if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
316 		*typep = epp->ep_module_type;
317 	else
318 		*typep = epp->ep_fixed_port_type;
319 }
320 
321 	__checkReturn	efx_rc_t
322 efx_phy_module_get_info(
323 	__in			efx_nic_t *enp,
324 	__in			uint8_t dev_addr,
325 	__in			uint8_t offset,
326 	__in			uint8_t len,
327 	__out_bcount(len)	uint8_t *data)
328 {
329 	efx_rc_t rc;
330 
331 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
332 	EFSYS_ASSERT(data != NULL);
333 
334 	if ((uint32_t)offset + len > 0xff) {
335 		rc = EINVAL;
336 		goto fail1;
337 	}
338 
339 	if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
340 	    offset, len, data)) != 0)
341 		goto fail2;
342 
343 	return (0);
344 
345 fail2:
346 	EFSYS_PROBE(fail2);
347 fail1:
348 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
349 
350 	return (rc);
351 }
352 
353 #if EFSYS_OPT_PHY_STATS
354 
355 #if EFSYS_OPT_NAMES
356 
357 /* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */
358 static const char 	*__efx_phy_stat_name[] = {
359 	"oui",
360 	"pma_pmd_link_up",
361 	"pma_pmd_rx_fault",
362 	"pma_pmd_tx_fault",
363 	"pma_pmd_rev_a",
364 	"pma_pmd_rev_b",
365 	"pma_pmd_rev_c",
366 	"pma_pmd_rev_d",
367 	"pcs_link_up",
368 	"pcs_rx_fault",
369 	"pcs_tx_fault",
370 	"pcs_ber",
371 	"pcs_block_errors",
372 	"phy_xs_link_up",
373 	"phy_xs_rx_fault",
374 	"phy_xs_tx_fault",
375 	"phy_xs_align",
376 	"phy_xs_sync_a",
377 	"phy_xs_sync_b",
378 	"phy_xs_sync_c",
379 	"phy_xs_sync_d",
380 	"an_link_up",
381 	"an_master",
382 	"an_local_rx_ok",
383 	"an_remote_rx_ok",
384 	"cl22ext_link_up",
385 	"snr_a",
386 	"snr_b",
387 	"snr_c",
388 	"snr_d",
389 	"pma_pmd_signal_a",
390 	"pma_pmd_signal_b",
391 	"pma_pmd_signal_c",
392 	"pma_pmd_signal_d",
393 	"an_complete",
394 	"pma_pmd_rev_major",
395 	"pma_pmd_rev_minor",
396 	"pma_pmd_rev_micro",
397 	"pcs_fw_version_0",
398 	"pcs_fw_version_1",
399 	"pcs_fw_version_2",
400 	"pcs_fw_version_3",
401 	"pcs_fw_build_yy",
402 	"pcs_fw_build_mm",
403 	"pcs_fw_build_dd",
404 	"pcs_op_mode",
405 };
406 
407 /* END MKCONFIG GENERATED PhyStatNamesBlock */
408 
409 					const char *
410 efx_phy_stat_name(
411 	__in				efx_nic_t *enp,
412 	__in				efx_phy_stat_t type)
413 {
414 	_NOTE(ARGUNUSED(enp))
415 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
416 	EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
417 
418 	return (__efx_phy_stat_name[type]);
419 }
420 
421 #endif	/* EFSYS_OPT_NAMES */
422 
423 	__checkReturn			efx_rc_t
424 efx_phy_stats_update(
425 	__in				efx_nic_t *enp,
426 	__in				efsys_mem_t *esmp,
427 	__inout_ecount(EFX_PHY_NSTATS)	uint32_t *stat)
428 {
429 	efx_port_t *epp = &(enp->en_port);
430 	const efx_phy_ops_t *epop = epp->ep_epop;
431 
432 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
433 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
434 
435 	return (epop->epo_stats_update(enp, esmp, stat));
436 }
437 
438 #endif	/* EFSYS_OPT_PHY_STATS */
439 
440 #if EFSYS_OPT_PHY_PROPS
441 
442 #if EFSYS_OPT_NAMES
443 		const char *
444 efx_phy_prop_name(
445 	__in	efx_nic_t *enp,
446 	__in	unsigned int id)
447 {
448 	efx_port_t *epp = &(enp->en_port);
449 	const efx_phy_ops_t *epop = epp->ep_epop;
450 
451 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
452 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
453 
454 	return (epop->epo_prop_name(enp, id));
455 }
456 #endif	/* EFSYS_OPT_NAMES */
457 
458 	__checkReturn	efx_rc_t
459 efx_phy_prop_get(
460 	__in		efx_nic_t *enp,
461 	__in		unsigned int id,
462 	__in		uint32_t flags,
463 	__out		uint32_t *valp)
464 {
465 	efx_port_t *epp = &(enp->en_port);
466 	const efx_phy_ops_t *epop = epp->ep_epop;
467 
468 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
469 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
470 
471 	return (epop->epo_prop_get(enp, id, flags, valp));
472 }
473 
474 	__checkReturn	efx_rc_t
475 efx_phy_prop_set(
476 	__in		efx_nic_t *enp,
477 	__in		unsigned int id,
478 	__in		uint32_t val)
479 {
480 	efx_port_t *epp = &(enp->en_port);
481 	const efx_phy_ops_t *epop = epp->ep_epop;
482 
483 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
484 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
485 
486 	return (epop->epo_prop_set(enp, id, val));
487 }
488 #endif	/* EFSYS_OPT_PHY_STATS */
489 
490 #if EFSYS_OPT_BIST
491 
492 	__checkReturn		efx_rc_t
493 efx_bist_enable_offline(
494 	__in			efx_nic_t *enp)
495 {
496 	efx_port_t *epp = &(enp->en_port);
497 	const efx_phy_ops_t *epop = epp->ep_epop;
498 	efx_rc_t rc;
499 
500 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
501 
502 	if (epop->epo_bist_enable_offline == NULL) {
503 		rc = ENOTSUP;
504 		goto fail1;
505 	}
506 
507 	if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
508 		goto fail2;
509 
510 	return (0);
511 
512 fail2:
513 	EFSYS_PROBE(fail2);
514 fail1:
515 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
516 
517 	return (rc);
518 
519 }
520 
521 	__checkReturn		efx_rc_t
522 efx_bist_start(
523 	__in			efx_nic_t *enp,
524 	__in			efx_bist_type_t type)
525 {
526 	efx_port_t *epp = &(enp->en_port);
527 	const efx_phy_ops_t *epop = epp->ep_epop;
528 	efx_rc_t rc;
529 
530 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
531 
532 	EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
533 	EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
534 	EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
535 
536 	if (epop->epo_bist_start == NULL) {
537 		rc = ENOTSUP;
538 		goto fail1;
539 	}
540 
541 	if ((rc = epop->epo_bist_start(enp, type)) != 0)
542 		goto fail2;
543 
544 	epp->ep_current_bist = type;
545 
546 	return (0);
547 
548 fail2:
549 	EFSYS_PROBE(fail2);
550 fail1:
551 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
552 
553 	return (rc);
554 }
555 
556 	__checkReturn		efx_rc_t
557 efx_bist_poll(
558 	__in			efx_nic_t *enp,
559 	__in			efx_bist_type_t type,
560 	__out			efx_bist_result_t *resultp,
561 	__out_opt		uint32_t *value_maskp,
562 	__out_ecount_opt(count)	unsigned long *valuesp,
563 	__in			size_t count)
564 {
565 	efx_port_t *epp = &(enp->en_port);
566 	const efx_phy_ops_t *epop = epp->ep_epop;
567 	efx_rc_t rc;
568 
569 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
570 
571 	EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
572 	EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
573 	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
574 
575 	EFSYS_ASSERT(epop->epo_bist_poll != NULL);
576 	if (epop->epo_bist_poll == NULL) {
577 		rc = ENOTSUP;
578 		goto fail1;
579 	}
580 
581 	if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
582 	    valuesp, count)) != 0)
583 		goto fail2;
584 
585 	return (0);
586 
587 fail2:
588 	EFSYS_PROBE(fail2);
589 fail1:
590 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
591 
592 	return (rc);
593 }
594 
595 			void
596 efx_bist_stop(
597 	__in		efx_nic_t *enp,
598 	__in		efx_bist_type_t type)
599 {
600 	efx_port_t *epp = &(enp->en_port);
601 	const efx_phy_ops_t *epop = epp->ep_epop;
602 
603 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
604 
605 	EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
606 	EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
607 	EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
608 
609 	EFSYS_ASSERT(epop->epo_bist_stop != NULL);
610 
611 	if (epop->epo_bist_stop != NULL)
612 		epop->epo_bist_stop(enp, type);
613 
614 	epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
615 }
616 
617 #endif	/* EFSYS_OPT_BIST */
618 			void
619 efx_phy_unprobe(
620 	__in	efx_nic_t *enp)
621 {
622 	efx_port_t *epp = &(enp->en_port);
623 
624 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
625 
626 	epp->ep_epop = NULL;
627 
628 	epp->ep_adv_cap_mask = 0;
629 
630 	epp->ep_port = 0;
631 	epp->ep_phy_type = 0;
632 }
633