1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2007-2019 Solarflare Communications Inc.
12 static const efx_phy_ops_t __efx_phy_siena_ops = {
13 siena_phy_power, /* epo_power */
15 siena_phy_reconfigure, /* epo_reconfigure */
16 siena_phy_verify, /* epo_verify */
17 siena_phy_oui_get, /* epo_oui_get */
18 NULL, /* epo_link_state_get */
19 #if EFSYS_OPT_PHY_STATS
20 siena_phy_stats_update, /* epo_stats_update */
21 #endif /* EFSYS_OPT_PHY_STATS */
23 NULL, /* epo_bist_enable_offline */
24 siena_phy_bist_start, /* epo_bist_start */
25 siena_phy_bist_poll, /* epo_bist_poll */
26 siena_phy_bist_stop, /* epo_bist_stop */
27 #endif /* EFSYS_OPT_BIST */
29 #endif /* EFSYS_OPT_SIENA */
32 static const efx_phy_ops_t __efx_phy_ef10_ops = {
33 ef10_phy_power, /* epo_power */
35 ef10_phy_reconfigure, /* epo_reconfigure */
36 ef10_phy_verify, /* epo_verify */
37 ef10_phy_oui_get, /* epo_oui_get */
38 ef10_phy_link_state_get, /* epo_link_state_get */
39 #if EFSYS_OPT_PHY_STATS
40 ef10_phy_stats_update, /* epo_stats_update */
41 #endif /* EFSYS_OPT_PHY_STATS */
43 ef10_bist_enable_offline, /* epo_bist_enable_offline */
44 ef10_bist_start, /* epo_bist_start */
45 ef10_bist_poll, /* epo_bist_poll */
46 ef10_bist_stop, /* epo_bist_stop */
47 #endif /* EFSYS_OPT_BIST */
49 #endif /* EFX_OPTS_EF10() */
51 #if EFSYS_OPT_RIVERHEAD
52 static const efx_phy_ops_t __efx_phy_rhead_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 */
58 ef10_phy_link_state_get, /* epo_link_state_get */
59 #if EFSYS_OPT_PHY_STATS
60 ef10_phy_stats_update, /* epo_stats_update */
61 #endif /* EFSYS_OPT_PHY_STATS */
63 ef10_bist_enable_offline, /* epo_bist_enable_offline */
64 ef10_bist_start, /* epo_bist_start */
65 ef10_bist_poll, /* epo_bist_poll */
66 ef10_bist_stop, /* epo_bist_stop */
67 #endif /* EFSYS_OPT_BIST */
69 #endif /* EFSYS_OPT_RIVERHEAD */
71 __checkReturn efx_rc_t
75 efx_port_t *epp = &(enp->en_port);
76 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
77 const efx_phy_ops_t *epop;
80 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
82 epp->ep_port = encp->enc_port;
83 epp->ep_phy_type = encp->enc_phy_type;
85 /* Hook in operations structure */
86 switch (enp->en_family) {
88 case EFX_FAMILY_SIENA:
89 epop = &__efx_phy_siena_ops;
91 #endif /* EFSYS_OPT_SIENA */
93 #if EFSYS_OPT_HUNTINGTON
94 case EFX_FAMILY_HUNTINGTON:
95 epop = &__efx_phy_ef10_ops;
97 #endif /* EFSYS_OPT_HUNTINGTON */
100 case EFX_FAMILY_MEDFORD:
101 epop = &__efx_phy_ef10_ops;
103 #endif /* EFSYS_OPT_MEDFORD */
105 #if EFSYS_OPT_MEDFORD2
106 case EFX_FAMILY_MEDFORD2:
107 epop = &__efx_phy_ef10_ops;
109 #endif /* EFSYS_OPT_MEDFORD2 */
111 #if EFSYS_OPT_RIVERHEAD
112 case EFX_FAMILY_RIVERHEAD:
113 epop = &__efx_phy_rhead_ops;
115 #endif /* EFSYS_OPT_MEDFORD2 */
127 EFSYS_PROBE1(fail1, efx_rc_t, rc);
130 epp->ep_phy_type = 0;
135 __checkReturn efx_rc_t
139 efx_port_t *epp = &(enp->en_port);
140 const efx_phy_ops_t *epop = epp->ep_epop;
142 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
143 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
145 return (epop->epo_verify(enp));
148 #if EFSYS_OPT_PHY_LED_CONTROL
150 __checkReturn efx_rc_t
153 __in efx_phy_led_mode_t mode)
155 efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
156 efx_port_t *epp = &(enp->en_port);
157 const efx_phy_ops_t *epop = epp->ep_epop;
161 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
162 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
164 if (epp->ep_phy_led_mode == mode)
167 mask = (1 << EFX_PHY_LED_DEFAULT);
168 mask |= encp->enc_led_mask;
170 if (!((1 << mode) & mask)) {
175 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
176 epp->ep_phy_led_mode = mode;
178 if ((rc = epop->epo_reconfigure(enp)) != 0)
187 EFSYS_PROBE1(fail1, efx_rc_t, rc);
191 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
197 __out uint32_t *maskp)
199 efx_port_t *epp = &(enp->en_port);
201 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
202 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
205 case EFX_PHY_CAP_CURRENT:
206 *maskp = epp->ep_adv_cap_mask;
208 case EFX_PHY_CAP_DEFAULT:
209 *maskp = epp->ep_default_adv_cap_mask;
211 case EFX_PHY_CAP_PERM:
212 *maskp = epp->ep_phy_cap_mask;
215 EFSYS_ASSERT(B_FALSE);
221 __checkReturn efx_rc_t
226 efx_port_t *epp = &(enp->en_port);
227 const efx_phy_ops_t *epop = epp->ep_epop;
231 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
232 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
234 if ((mask & ~epp->ep_phy_cap_mask) != 0) {
239 if (epp->ep_adv_cap_mask == mask)
242 old_mask = epp->ep_adv_cap_mask;
243 epp->ep_adv_cap_mask = mask;
245 if ((rc = epop->epo_reconfigure(enp)) != 0)
254 epp->ep_adv_cap_mask = old_mask;
255 /* Reconfigure for robustness */
256 if (epop->epo_reconfigure(enp) != 0) {
258 * We may have an inconsistent view of our advertised speed
265 EFSYS_PROBE1(fail1, efx_rc_t, rc);
273 __out uint32_t *maskp)
275 efx_port_t *epp = &(enp->en_port);
277 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
278 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
280 *maskp = epp->ep_lp_cap_mask;
283 __checkReturn efx_rc_t
286 __out uint32_t *ouip)
288 efx_port_t *epp = &(enp->en_port);
289 const efx_phy_ops_t *epop = epp->ep_epop;
291 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
292 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
294 return (epop->epo_oui_get(enp, ouip));
298 efx_phy_media_type_get(
300 __out efx_phy_media_type_t *typep)
302 efx_port_t *epp = &(enp->en_port);
304 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
305 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
307 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
308 *typep = epp->ep_module_type;
310 *typep = epp->ep_fixed_port_type;
313 __checkReturn efx_rc_t
314 efx_phy_module_get_info(
316 __in uint8_t dev_addr,
319 __out_bcount(len) uint8_t *data)
323 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
324 EFSYS_ASSERT(data != NULL);
326 if ((offset > EFX_PHY_MEDIA_INFO_MAX_OFFSET) ||
327 ((offset + len) > EFX_PHY_MEDIA_INFO_MAX_OFFSET)) {
332 if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
333 offset, len, data)) != 0)
341 EFSYS_PROBE1(fail1, efx_rc_t, rc);
346 __checkReturn efx_rc_t
347 efx_phy_fec_type_get(
349 __out efx_phy_fec_type_t *typep)
352 efx_phy_link_state_t epls;
354 if ((rc = efx_phy_link_state_get(enp, &epls)) != 0)
357 *typep = epls.epls_fec;
362 EFSYS_PROBE1(fail1, efx_rc_t, rc);
367 __checkReturn efx_rc_t
368 efx_phy_link_state_get(
370 __out efx_phy_link_state_t *eplsp)
372 efx_port_t *epp = &(enp->en_port);
373 const efx_phy_ops_t *epop = epp->ep_epop;
376 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
377 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
379 if (epop->epo_link_state_get == NULL) {
384 if ((rc = epop->epo_link_state_get(enp, eplsp)) != 0)
392 EFSYS_PROBE1(fail1, efx_rc_t, rc);
397 #if EFSYS_OPT_PHY_STATS
401 /* START MKCONFIG GENERATED PhyStatNamesBlock af9ffa24da3bc100 */
402 static const char * const __efx_phy_stat_name[] = {
451 /* END MKCONFIG GENERATED PhyStatNamesBlock */
456 __in efx_phy_stat_t type)
458 _NOTE(ARGUNUSED(enp))
459 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
460 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
462 return (__efx_phy_stat_name[type]);
465 #endif /* EFSYS_OPT_NAMES */
467 __checkReturn efx_rc_t
468 efx_phy_stats_update(
470 __in efsys_mem_t *esmp,
471 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
473 efx_port_t *epp = &(enp->en_port);
474 const efx_phy_ops_t *epop = epp->ep_epop;
476 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
477 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
479 return (epop->epo_stats_update(enp, esmp, stat));
482 #endif /* EFSYS_OPT_PHY_STATS */
487 __checkReturn efx_rc_t
488 efx_bist_enable_offline(
491 efx_port_t *epp = &(enp->en_port);
492 const efx_phy_ops_t *epop = epp->ep_epop;
495 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
497 if (epop->epo_bist_enable_offline == NULL) {
502 if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
510 EFSYS_PROBE1(fail1, efx_rc_t, rc);
516 __checkReturn efx_rc_t
519 __in efx_bist_type_t type)
521 efx_port_t *epp = &(enp->en_port);
522 const efx_phy_ops_t *epop = epp->ep_epop;
525 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
527 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
528 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
529 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
531 if (epop->epo_bist_start == NULL) {
536 if ((rc = epop->epo_bist_start(enp, type)) != 0)
539 epp->ep_current_bist = type;
546 EFSYS_PROBE1(fail1, efx_rc_t, rc);
551 __checkReturn efx_rc_t
554 __in efx_bist_type_t type,
555 __out efx_bist_result_t *resultp,
556 __out_opt uint32_t *value_maskp,
557 __out_ecount_opt(count) unsigned long *valuesp,
560 efx_port_t *epp = &(enp->en_port);
561 const efx_phy_ops_t *epop = epp->ep_epop;
564 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
566 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
567 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
568 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
570 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
571 if (epop->epo_bist_poll == NULL) {
576 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
577 valuesp, count)) != 0)
585 EFSYS_PROBE1(fail1, efx_rc_t, rc);
593 __in efx_bist_type_t type)
595 efx_port_t *epp = &(enp->en_port);
596 const efx_phy_ops_t *epop = epp->ep_epop;
598 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
600 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
601 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
602 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
604 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
606 if (epop->epo_bist_stop != NULL)
607 epop->epo_bist_stop(enp, type);
609 epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
612 #endif /* EFSYS_OPT_BIST */
617 efx_port_t *epp = &(enp->en_port);
619 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
623 epp->ep_adv_cap_mask = 0;
626 epp->ep_phy_type = 0;