2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2007-2016 Solarflare Communications Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
41 static const efx_phy_ops_t __efx_phy_siena_ops = {
42 siena_phy_power, /* epo_power */
44 siena_phy_reconfigure, /* epo_reconfigure */
45 siena_phy_verify, /* epo_verify */
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 */
51 NULL, /* epo_bist_enable_offline */
52 siena_phy_bist_start, /* epo_bist_start */
53 siena_phy_bist_poll, /* epo_bist_poll */
54 siena_phy_bist_stop, /* epo_bist_stop */
55 #endif /* EFSYS_OPT_BIST */
57 #endif /* EFSYS_OPT_SIENA */
59 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
60 static const efx_phy_ops_t __efx_phy_ef10_ops = {
61 ef10_phy_power, /* epo_power */
63 ef10_phy_reconfigure, /* epo_reconfigure */
64 ef10_phy_verify, /* epo_verify */
65 ef10_phy_oui_get, /* epo_oui_get */
66 #if EFSYS_OPT_PHY_STATS
67 ef10_phy_stats_update, /* epo_stats_update */
68 #endif /* EFSYS_OPT_PHY_STATS */
70 ef10_bist_enable_offline, /* epo_bist_enable_offline */
71 ef10_bist_start, /* epo_bist_start */
72 ef10_bist_poll, /* epo_bist_poll */
73 ef10_bist_stop, /* epo_bist_stop */
74 #endif /* EFSYS_OPT_BIST */
76 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
78 __checkReturn efx_rc_t
82 efx_port_t *epp = &(enp->en_port);
83 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
84 const efx_phy_ops_t *epop;
87 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
89 epp->ep_port = encp->enc_port;
90 epp->ep_phy_type = encp->enc_phy_type;
92 /* Hook in operations structure */
93 switch (enp->en_family) {
95 case EFX_FAMILY_SIENA:
96 epop = &__efx_phy_siena_ops;
98 #endif /* EFSYS_OPT_SIENA */
99 #if EFSYS_OPT_HUNTINGTON
100 case EFX_FAMILY_HUNTINGTON:
101 epop = &__efx_phy_ef10_ops;
103 #endif /* EFSYS_OPT_HUNTINGTON */
104 #if EFSYS_OPT_MEDFORD
105 case EFX_FAMILY_MEDFORD:
106 epop = &__efx_phy_ef10_ops;
108 #endif /* EFSYS_OPT_MEDFORD */
119 EFSYS_PROBE1(fail1, efx_rc_t, rc);
122 epp->ep_phy_type = 0;
127 __checkReturn efx_rc_t
131 efx_port_t *epp = &(enp->en_port);
132 const efx_phy_ops_t *epop = epp->ep_epop;
134 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
135 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
137 return (epop->epo_verify(enp));
140 #if EFSYS_OPT_PHY_LED_CONTROL
142 __checkReturn efx_rc_t
145 __in efx_phy_led_mode_t mode)
147 efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
148 efx_port_t *epp = &(enp->en_port);
149 const efx_phy_ops_t *epop = epp->ep_epop;
153 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
154 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
156 if (epp->ep_phy_led_mode == mode)
159 mask = (1 << EFX_PHY_LED_DEFAULT);
160 mask |= encp->enc_led_mask;
162 if (!((1 << mode) & mask)) {
167 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
168 epp->ep_phy_led_mode = mode;
170 if ((rc = epop->epo_reconfigure(enp)) != 0)
179 EFSYS_PROBE1(fail1, efx_rc_t, rc);
183 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
189 __out uint32_t *maskp)
191 efx_port_t *epp = &(enp->en_port);
193 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
194 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
197 case EFX_PHY_CAP_CURRENT:
198 *maskp = epp->ep_adv_cap_mask;
200 case EFX_PHY_CAP_DEFAULT:
201 *maskp = epp->ep_default_adv_cap_mask;
203 case EFX_PHY_CAP_PERM:
204 *maskp = epp->ep_phy_cap_mask;
207 EFSYS_ASSERT(B_FALSE);
212 __checkReturn efx_rc_t
217 efx_port_t *epp = &(enp->en_port);
218 const efx_phy_ops_t *epop = epp->ep_epop;
222 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
223 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
225 if ((mask & ~epp->ep_phy_cap_mask) != 0) {
230 if (epp->ep_adv_cap_mask == mask)
233 old_mask = epp->ep_adv_cap_mask;
234 epp->ep_adv_cap_mask = mask;
236 if ((rc = epop->epo_reconfigure(enp)) != 0)
245 epp->ep_adv_cap_mask = old_mask;
246 /* Reconfigure for robustness */
247 if (epop->epo_reconfigure(enp) != 0) {
249 * We may have an inconsistent view of our advertised speed
256 EFSYS_PROBE1(fail1, efx_rc_t, rc);
264 __out uint32_t *maskp)
266 efx_port_t *epp = &(enp->en_port);
268 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
269 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
271 *maskp = epp->ep_lp_cap_mask;
274 __checkReturn efx_rc_t
277 __out uint32_t *ouip)
279 efx_port_t *epp = &(enp->en_port);
280 const efx_phy_ops_t *epop = epp->ep_epop;
282 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
283 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
285 return (epop->epo_oui_get(enp, ouip));
289 efx_phy_media_type_get(
291 __out efx_phy_media_type_t *typep)
293 efx_port_t *epp = &(enp->en_port);
295 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
296 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
298 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
299 *typep = epp->ep_module_type;
301 *typep = epp->ep_fixed_port_type;
304 __checkReturn efx_rc_t
305 efx_phy_module_get_info(
307 __in uint8_t dev_addr,
310 __out_bcount(len) uint8_t *data)
314 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
315 EFSYS_ASSERT(data != NULL);
317 if ((uint32_t)offset + len > 0xff) {
322 if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
323 offset, len, data)) != 0)
331 EFSYS_PROBE1(fail1, efx_rc_t, rc);
336 #if EFSYS_OPT_PHY_STATS
340 /* START MKCONFIG GENERATED PhyStatNamesBlock af9ffa24da3bc100 */
341 static const char * const __efx_phy_stat_name[] = {
390 /* END MKCONFIG GENERATED PhyStatNamesBlock */
395 __in efx_phy_stat_t type)
397 _NOTE(ARGUNUSED(enp))
398 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
399 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
401 return (__efx_phy_stat_name[type]);
404 #endif /* EFSYS_OPT_NAMES */
406 __checkReturn efx_rc_t
407 efx_phy_stats_update(
409 __in efsys_mem_t *esmp,
410 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
412 efx_port_t *epp = &(enp->en_port);
413 const efx_phy_ops_t *epop = epp->ep_epop;
415 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
416 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
418 return (epop->epo_stats_update(enp, esmp, stat));
421 #endif /* EFSYS_OPT_PHY_STATS */
426 __checkReturn efx_rc_t
427 efx_bist_enable_offline(
430 efx_port_t *epp = &(enp->en_port);
431 const efx_phy_ops_t *epop = epp->ep_epop;
434 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
436 if (epop->epo_bist_enable_offline == NULL) {
441 if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
449 EFSYS_PROBE1(fail1, efx_rc_t, rc);
455 __checkReturn efx_rc_t
458 __in efx_bist_type_t type)
460 efx_port_t *epp = &(enp->en_port);
461 const efx_phy_ops_t *epop = epp->ep_epop;
464 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
466 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
467 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
468 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
470 if (epop->epo_bist_start == NULL) {
475 if ((rc = epop->epo_bist_start(enp, type)) != 0)
478 epp->ep_current_bist = type;
485 EFSYS_PROBE1(fail1, efx_rc_t, rc);
490 __checkReturn efx_rc_t
493 __in efx_bist_type_t type,
494 __out efx_bist_result_t *resultp,
495 __out_opt uint32_t *value_maskp,
496 __out_ecount_opt(count) unsigned long *valuesp,
499 efx_port_t *epp = &(enp->en_port);
500 const efx_phy_ops_t *epop = epp->ep_epop;
503 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
505 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
506 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
507 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
509 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
510 if (epop->epo_bist_poll == NULL) {
515 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
516 valuesp, count)) != 0)
524 EFSYS_PROBE1(fail1, efx_rc_t, rc);
532 __in efx_bist_type_t type)
534 efx_port_t *epp = &(enp->en_port);
535 const efx_phy_ops_t *epop = epp->ep_epop;
537 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
539 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
540 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
541 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
543 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
545 if (epop->epo_bist_stop != NULL)
546 epop->epo_bist_stop(enp, type);
548 epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
551 #endif /* EFSYS_OPT_BIST */
556 efx_port_t *epp = &(enp->en_port);
558 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
562 epp->ep_adv_cap_mask = 0;
565 epp->ep_phy_type = 0;