2 * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
31 #include "efx_types.h"
35 #include "falcon_nvram.h"
38 #if EFSYS_OPT_MAC_FALCON_XMAC
39 #include "falcon_xmac.h"
42 #if EFSYS_OPT_MAC_FALCON_GMAC
43 #include "falcon_gmac.h"
46 #if EFSYS_OPT_PHY_NULL
50 #if EFSYS_OPT_PHY_QT2022C2
54 #if EFSYS_OPT_PHY_SFX7101
58 #if EFSYS_OPT_PHY_TXC43128
62 #if EFSYS_OPT_PHY_SFT9001
66 #if EFSYS_OPT_PHY_QT2025C
70 #if EFSYS_OPT_PHY_NULL
71 static efx_phy_ops_t __cs __efx_phy_null_ops = {
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
84 nullphy_prop_name, /* epo_prop_name */
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 */
95 #endif /* EFSYS_OPT_PHY_NULL */
97 #if EFSYS_OPT_PHY_QT2022C2
98 static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = {
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
111 qt2022c2_prop_name, /* epo_prop_name */
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 */
122 #endif /* EFSYS_OPT_PHY_QT2022C2 */
124 #if EFSYS_OPT_PHY_SFX7101
125 static 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
138 sfx7101_prop_name, /* epo_prop_name */
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 */
149 #endif /* EFSYS_OPT_PHY_SFX7101 */
151 #if EFSYS_OPT_PHY_TXC43128
152 static 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
165 txc43128_prop_name, /* epo_prop_name */
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 */
176 #endif /* EFSYS_OPT_PHY_TXC43128 */
178 #if EFSYS_OPT_PHY_SFT9001
179 static 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
192 sft9001_prop_name, /* epo_prop_name */
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 */
203 #endif /* EFSYS_OPT_PHY_SFT9001 */
205 #if EFSYS_OPT_PHY_QT2025C
206 static 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
219 qt2025c_prop_name, /* epo_prop_name */
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 */
230 #endif /* EFSYS_OPT_PHY_QT2025C */
233 static 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
246 siena_phy_prop_name, /* epo_prop_name */
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 */
257 #endif /* EFSYS_OPT_SIENA */
263 efx_port_t *epp = &(enp->en_port);
264 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
268 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
270 epp->ep_port = encp->enc_port;
271 epp->ep_phy_type = encp->enc_phy_type;
273 /* Hook in operations structure */
274 switch (enp->en_family) {
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;
283 #if EFSYS_OPT_PHY_QT2022C2
284 case PHY_TYPE_QT2022C2_DECODE:
285 epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops;
288 #if EFSYS_OPT_PHY_SFX7101
289 case PHY_TYPE_SFX7101_DECODE:
290 epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops;
293 #if EFSYS_OPT_PHY_TXC43128
294 case PHY_TYPE_TXC43128_DECODE:
295 epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops;
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;
304 #if EFSYS_OPT_PHY_QT2025C
305 case EFX_PHY_QT2025C:
306 epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops;
314 #endif /* EFSYS_OPT_FALCON */
316 case EFX_FAMILY_SIENA:
317 epop = (efx_phy_ops_t *)&__efx_phy_siena_ops;
319 #endif /* EFSYS_OPT_SIENA */
330 EFSYS_PROBE1(fail1, int, rc);
333 epp->ep_phy_type = 0;
342 efx_port_t *epp = &(enp->en_port);
343 efx_phy_ops_t *epop = epp->ep_epop;
345 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
346 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
348 return (epop->epo_verify(enp));
351 #if EFSYS_OPT_PHY_LED_CONTROL
356 __in efx_phy_led_mode_t mode)
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;
364 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
365 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
367 if (epp->ep_phy_led_mode == mode)
370 mask = (1 << EFX_PHY_LED_DEFAULT);
371 mask |= encp->enc_led_mask;
373 if (!((1 << mode) & mask)) {
378 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
379 epp->ep_phy_led_mode = mode;
381 if ((rc = epop->epo_reconfigure(enp)) != 0)
390 EFSYS_PROBE1(fail1, int, rc);
394 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
400 __out uint32_t *maskp)
402 efx_port_t *epp = &(enp->en_port);
404 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
405 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
408 case EFX_PHY_CAP_CURRENT:
409 *maskp = epp->ep_adv_cap_mask;
411 case EFX_PHY_CAP_DEFAULT:
412 *maskp = epp->ep_default_adv_cap_mask;
414 case EFX_PHY_CAP_PERM:
415 *maskp = epp->ep_phy_cap_mask;
418 EFSYS_ASSERT(B_FALSE);
428 efx_port_t *epp = &(enp->en_port);
429 efx_phy_ops_t *epop = epp->ep_epop;
432 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
433 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
435 if ((mask & ~epp->ep_phy_cap_mask) != 0) {
440 if (epp->ep_adv_cap_mask == mask)
443 epp->ep_adv_cap_mask = mask;
445 if ((rc = epop->epo_reconfigure(enp)) != 0)
454 EFSYS_PROBE1(fail1, int, rc);
462 __out uint32_t *maskp)
464 efx_port_t *epp = &(enp->en_port);
466 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
467 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
469 *maskp = epp->ep_lp_cap_mask;
475 __out uint32_t *ouip)
477 efx_port_t *epp = &(enp->en_port);
478 efx_phy_ops_t *epop = epp->ep_epop;
480 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
481 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
483 return (epop->epo_oui_get(enp, ouip));
487 efx_phy_media_type_get(
489 __out efx_phy_media_type_t *typep)
491 efx_port_t *epp = &(enp->en_port);
493 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
494 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
496 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
497 *typep = epp->ep_module_type;
499 *typep = epp->ep_fixed_port_type;
502 #if EFSYS_OPT_PHY_STATS
506 /* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
507 static const char __cs * __cs __efx_phy_stat_name[] = {
556 /* END MKCONFIG GENERATED PhyStatNamesBlock */
561 __in efx_phy_stat_t type)
563 _NOTE(ARGUNUSED(enp))
564 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
565 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
567 return (__efx_phy_stat_name[type]);
570 #endif /* EFSYS_OPT_NAMES */
573 efx_phy_stats_update(
575 __in efsys_mem_t *esmp,
576 __out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
578 efx_port_t *epp = &(enp->en_port);
579 efx_phy_ops_t *epop = epp->ep_epop;
581 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
582 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
584 return (epop->epo_stats_update(enp, esmp, stat));
587 #endif /* EFSYS_OPT_PHY_STATS */
589 #if EFSYS_OPT_PHY_PROPS
595 __in unsigned int id)
597 efx_port_t *epp = &(enp->en_port);
598 efx_phy_ops_t *epop = epp->ep_epop;
600 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
601 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
603 return (epop->epo_prop_name(enp, id));
605 #endif /* EFSYS_OPT_NAMES */
610 __in unsigned int id,
612 __out uint32_t *valp)
614 efx_port_t *epp = &(enp->en_port);
615 efx_phy_ops_t *epop = epp->ep_epop;
617 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
618 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
620 return (epop->epo_prop_get(enp, id, flags, valp));
626 __in unsigned int id,
629 efx_port_t *epp = &(enp->en_port);
630 efx_phy_ops_t *epop = epp->ep_epop;
632 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
633 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
635 return (epop->epo_prop_set(enp, id, val));
637 #endif /* EFSYS_OPT_PHY_STATS */
639 #if EFSYS_OPT_PHY_BIST
644 __in efx_phy_bist_type_t type)
646 efx_port_t *epp = &(enp->en_port);
647 efx_phy_ops_t *epop = epp->ep_epop;
650 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
651 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
653 EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
654 EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
655 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
657 if (epop->epo_bist_start == NULL) {
662 if ((rc = epop->epo_bist_start(enp, type)) != 0)
665 epp->ep_current_bist = type;
672 EFSYS_PROBE1(fail1, int, rc);
680 __in efx_phy_bist_type_t type,
681 __out efx_phy_bist_result_t *resultp,
682 __out_opt uint32_t *value_maskp,
683 __out_ecount_opt(count) unsigned long *valuesp,
686 efx_port_t *epp = &(enp->en_port);
687 efx_phy_ops_t *epop = epp->ep_epop;
690 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
691 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
693 EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
694 EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
695 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
697 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
698 if (epop->epo_bist_poll == NULL) {
703 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
704 valuesp, count)) != 0)
712 EFSYS_PROBE1(fail1, int, rc);
720 __in efx_phy_bist_type_t type)
722 efx_port_t *epp = &(enp->en_port);
723 efx_phy_ops_t *epop = epp->ep_epop;
725 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
726 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
728 EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
729 EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
730 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
732 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
734 if (epop->epo_bist_stop != NULL)
735 epop->epo_bist_stop(enp, type);
737 epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
740 #endif /* EFSYS_OPT_PHY_BIST */
745 efx_port_t *epp = &(enp->en_port);
747 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
751 epp->ep_adv_cap_mask = 0;
754 epp->ep_phy_type = 0;