2 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
36 static const efx_phy_ops_t __efx_phy_siena_ops = {
37 siena_phy_power, /* epo_power */
39 siena_phy_reconfigure, /* epo_reconfigure */
40 siena_phy_verify, /* epo_verify */
41 siena_phy_oui_get, /* epo_oui_get */
43 NULL, /* epo_bist_enable_offline */
44 siena_phy_bist_start, /* epo_bist_start */
45 siena_phy_bist_poll, /* epo_bist_poll */
46 siena_phy_bist_stop, /* epo_bist_stop */
47 #endif /* EFSYS_OPT_BIST */
49 #endif /* EFSYS_OPT_SIENA */
51 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
52 static const efx_phy_ops_t __efx_phy_ef10_ops = {
53 ef10_phy_power, /* epo_power */
55 ef10_phy_reconfigure, /* epo_reconfigure */
56 ef10_phy_verify, /* epo_verify */
57 ef10_phy_oui_get, /* epo_oui_get */
59 ef10_bist_enable_offline, /* epo_bist_enable_offline */
60 ef10_bist_start, /* epo_bist_start */
61 ef10_bist_poll, /* epo_bist_poll */
62 ef10_bist_stop, /* epo_bist_stop */
63 #endif /* EFSYS_OPT_BIST */
65 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
67 __checkReturn efx_rc_t
71 efx_port_t *epp = &(enp->en_port);
72 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
73 const efx_phy_ops_t *epop;
76 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
78 epp->ep_port = encp->enc_port;
79 epp->ep_phy_type = encp->enc_phy_type;
81 /* Hook in operations structure */
82 switch (enp->en_family) {
84 case EFX_FAMILY_SIENA:
85 epop = &__efx_phy_siena_ops;
87 #endif /* EFSYS_OPT_SIENA */
88 #if EFSYS_OPT_HUNTINGTON
89 case EFX_FAMILY_HUNTINGTON:
90 epop = &__efx_phy_ef10_ops;
92 #endif /* EFSYS_OPT_HUNTINGTON */
94 case EFX_FAMILY_MEDFORD:
95 epop = &__efx_phy_ef10_ops;
97 #endif /* EFSYS_OPT_MEDFORD */
108 EFSYS_PROBE1(fail1, efx_rc_t, rc);
111 epp->ep_phy_type = 0;
116 __checkReturn efx_rc_t
120 efx_port_t *epp = &(enp->en_port);
121 const efx_phy_ops_t *epop = epp->ep_epop;
123 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
124 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
126 return (epop->epo_verify(enp));
133 __out uint32_t *maskp)
135 efx_port_t *epp = &(enp->en_port);
137 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
138 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
141 case EFX_PHY_CAP_CURRENT:
142 *maskp = epp->ep_adv_cap_mask;
144 case EFX_PHY_CAP_DEFAULT:
145 *maskp = epp->ep_default_adv_cap_mask;
147 case EFX_PHY_CAP_PERM:
148 *maskp = epp->ep_phy_cap_mask;
151 EFSYS_ASSERT(B_FALSE);
156 __checkReturn efx_rc_t
161 efx_port_t *epp = &(enp->en_port);
162 const efx_phy_ops_t *epop = epp->ep_epop;
166 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
167 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
169 if ((mask & ~epp->ep_phy_cap_mask) != 0) {
174 if (epp->ep_adv_cap_mask == mask)
177 old_mask = epp->ep_adv_cap_mask;
178 epp->ep_adv_cap_mask = mask;
180 if ((rc = epop->epo_reconfigure(enp)) != 0)
189 epp->ep_adv_cap_mask = old_mask;
190 /* Reconfigure for robustness */
191 if (epop->epo_reconfigure(enp) != 0) {
193 * We may have an inconsistent view of our advertised speed
200 EFSYS_PROBE1(fail1, efx_rc_t, rc);
208 __out uint32_t *maskp)
210 efx_port_t *epp = &(enp->en_port);
212 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
213 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
215 *maskp = epp->ep_lp_cap_mask;
218 __checkReturn efx_rc_t
221 __out uint32_t *ouip)
223 efx_port_t *epp = &(enp->en_port);
224 const efx_phy_ops_t *epop = epp->ep_epop;
226 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
227 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
229 return (epop->epo_oui_get(enp, ouip));
233 efx_phy_media_type_get(
235 __out efx_phy_media_type_t *typep)
237 efx_port_t *epp = &(enp->en_port);
239 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
240 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
242 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
243 *typep = epp->ep_module_type;
245 *typep = epp->ep_fixed_port_type;
248 __checkReturn efx_rc_t
249 efx_phy_module_get_info(
251 __in uint8_t dev_addr,
254 __out_bcount(len) uint8_t *data)
258 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
259 EFSYS_ASSERT(data != NULL);
261 if ((uint32_t)offset + len > 0xff) {
266 if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
267 offset, len, data)) != 0)
275 EFSYS_PROBE1(fail1, efx_rc_t, rc);
283 __checkReturn efx_rc_t
284 efx_bist_enable_offline(
287 efx_port_t *epp = &(enp->en_port);
288 const efx_phy_ops_t *epop = epp->ep_epop;
291 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
293 if (epop->epo_bist_enable_offline == NULL) {
298 if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
306 EFSYS_PROBE1(fail1, efx_rc_t, rc);
312 __checkReturn efx_rc_t
315 __in efx_bist_type_t type)
317 efx_port_t *epp = &(enp->en_port);
318 const efx_phy_ops_t *epop = epp->ep_epop;
321 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
323 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
324 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
325 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
327 if (epop->epo_bist_start == NULL) {
332 if ((rc = epop->epo_bist_start(enp, type)) != 0)
335 epp->ep_current_bist = type;
342 EFSYS_PROBE1(fail1, efx_rc_t, rc);
347 __checkReturn efx_rc_t
350 __in efx_bist_type_t type,
351 __out efx_bist_result_t *resultp,
352 __out_opt uint32_t *value_maskp,
353 __out_ecount_opt(count) unsigned long *valuesp,
356 efx_port_t *epp = &(enp->en_port);
357 const efx_phy_ops_t *epop = epp->ep_epop;
360 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
362 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
363 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
364 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
366 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
367 if (epop->epo_bist_poll == NULL) {
372 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
373 valuesp, count)) != 0)
381 EFSYS_PROBE1(fail1, efx_rc_t, rc);
389 __in efx_bist_type_t type)
391 efx_port_t *epp = &(enp->en_port);
392 const efx_phy_ops_t *epop = epp->ep_epop;
394 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
396 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
397 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
398 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
400 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
402 if (epop->epo_bist_stop != NULL)
403 epop->epo_bist_stop(enp, type);
405 epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
408 #endif /* EFSYS_OPT_BIST */
413 efx_port_t *epp = &(enp->en_port);
415 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
419 epp->ep_adv_cap_mask = 0;
422 epp->ep_phy_type = 0;