1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2007-2018 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_fec_type_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 */
31 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
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_fec_type_get, /* epo_fec_type_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 /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
51 __checkReturn efx_rc_t
55 efx_port_t *epp = &(enp->en_port);
56 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
57 const efx_phy_ops_t *epop;
60 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
62 epp->ep_port = encp->enc_port;
63 epp->ep_phy_type = encp->enc_phy_type;
65 /* Hook in operations structure */
66 switch (enp->en_family) {
68 case EFX_FAMILY_SIENA:
69 epop = &__efx_phy_siena_ops;
71 #endif /* EFSYS_OPT_SIENA */
73 #if EFSYS_OPT_HUNTINGTON
74 case EFX_FAMILY_HUNTINGTON:
75 epop = &__efx_phy_ef10_ops;
77 #endif /* EFSYS_OPT_HUNTINGTON */
80 case EFX_FAMILY_MEDFORD:
81 epop = &__efx_phy_ef10_ops;
83 #endif /* EFSYS_OPT_MEDFORD */
85 #if EFSYS_OPT_MEDFORD2
86 case EFX_FAMILY_MEDFORD2:
87 epop = &__efx_phy_ef10_ops;
89 #endif /* EFSYS_OPT_MEDFORD2 */
101 EFSYS_PROBE1(fail1, efx_rc_t, rc);
104 epp->ep_phy_type = 0;
109 __checkReturn efx_rc_t
113 efx_port_t *epp = &(enp->en_port);
114 const efx_phy_ops_t *epop = epp->ep_epop;
116 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
117 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
119 return (epop->epo_verify(enp));
122 #if EFSYS_OPT_PHY_LED_CONTROL
124 __checkReturn efx_rc_t
127 __in efx_phy_led_mode_t mode)
129 efx_nic_cfg_t *encp = (&enp->en_nic_cfg);
130 efx_port_t *epp = &(enp->en_port);
131 const efx_phy_ops_t *epop = epp->ep_epop;
135 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
136 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
138 if (epp->ep_phy_led_mode == mode)
141 mask = (1 << EFX_PHY_LED_DEFAULT);
142 mask |= encp->enc_led_mask;
144 if (!((1 << mode) & mask)) {
149 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
150 epp->ep_phy_led_mode = mode;
152 if ((rc = epop->epo_reconfigure(enp)) != 0)
161 EFSYS_PROBE1(fail1, efx_rc_t, rc);
165 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
171 __out uint32_t *maskp)
173 efx_port_t *epp = &(enp->en_port);
175 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
176 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
179 case EFX_PHY_CAP_CURRENT:
180 *maskp = epp->ep_adv_cap_mask;
182 case EFX_PHY_CAP_DEFAULT:
183 *maskp = epp->ep_default_adv_cap_mask;
185 case EFX_PHY_CAP_PERM:
186 *maskp = epp->ep_phy_cap_mask;
189 EFSYS_ASSERT(B_FALSE);
195 #define EFX_PHY_CAP_FEC_REQ_MASK \
196 (1U << EFX_PHY_CAP_BASER_FEC_REQUESTED) | \
197 (1U << EFX_PHY_CAP_RS_FEC_REQUESTED) | \
198 (1U << EFX_PHY_CAP_25G_BASER_FEC_REQUESTED)
200 __checkReturn efx_rc_t
205 efx_port_t *epp = &(enp->en_port);
206 const efx_phy_ops_t *epop = epp->ep_epop;
210 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
211 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
213 /* Ignore don't care bits of FEC (FEC EFX_PHY_CAP_*_REQUESTED) */
214 if ((mask & ~(epp->ep_phy_cap_mask | EFX_PHY_CAP_FEC_REQ_MASK)) != 0) {
219 if (epp->ep_adv_cap_mask == mask)
222 old_mask = epp->ep_adv_cap_mask;
223 epp->ep_adv_cap_mask = mask;
225 if ((rc = epop->epo_reconfigure(enp)) != 0)
234 epp->ep_adv_cap_mask = old_mask;
235 /* Reconfigure for robustness */
236 if (epop->epo_reconfigure(enp) != 0) {
238 * We may have an inconsistent view of our advertised speed
245 EFSYS_PROBE1(fail1, efx_rc_t, rc);
253 __out uint32_t *maskp)
255 efx_port_t *epp = &(enp->en_port);
257 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
258 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
260 *maskp = epp->ep_lp_cap_mask;
263 __checkReturn efx_rc_t
266 __out uint32_t *ouip)
268 efx_port_t *epp = &(enp->en_port);
269 const efx_phy_ops_t *epop = epp->ep_epop;
271 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
272 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
274 return (epop->epo_oui_get(enp, ouip));
278 efx_phy_media_type_get(
280 __out efx_phy_media_type_t *typep)
282 efx_port_t *epp = &(enp->en_port);
284 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
285 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
287 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
288 *typep = epp->ep_module_type;
290 *typep = epp->ep_fixed_port_type;
293 __checkReturn efx_rc_t
294 efx_phy_module_get_info(
296 __in uint8_t dev_addr,
299 __out_bcount(len) uint8_t *data)
303 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
304 EFSYS_ASSERT(data != NULL);
306 if ((uint32_t)offset + len > 0xff) {
311 if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
312 offset, len, data)) != 0)
320 EFSYS_PROBE1(fail1, efx_rc_t, rc);
325 __checkReturn efx_rc_t
326 efx_phy_fec_type_get(
328 __out efx_phy_fec_type_t *typep)
330 efx_port_t *epp = &(enp->en_port);
331 const efx_phy_ops_t *epop = epp->ep_epop;
334 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
336 if (epop->epo_fec_type_get == NULL) {
341 if ((rc = epop->epo_fec_type_get(enp, typep)) != 0)
349 EFSYS_PROBE1(fail1, efx_rc_t, rc);
354 #if EFSYS_OPT_PHY_STATS
358 /* START MKCONFIG GENERATED PhyStatNamesBlock af9ffa24da3bc100 */
359 static const char * const __efx_phy_stat_name[] = {
408 /* END MKCONFIG GENERATED PhyStatNamesBlock */
413 __in efx_phy_stat_t type)
415 _NOTE(ARGUNUSED(enp))
416 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
417 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
419 return (__efx_phy_stat_name[type]);
422 #endif /* EFSYS_OPT_NAMES */
424 __checkReturn efx_rc_t
425 efx_phy_stats_update(
427 __in efsys_mem_t *esmp,
428 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
430 efx_port_t *epp = &(enp->en_port);
431 const efx_phy_ops_t *epop = epp->ep_epop;
433 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
434 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
436 return (epop->epo_stats_update(enp, esmp, stat));
439 #endif /* EFSYS_OPT_PHY_STATS */
444 __checkReturn efx_rc_t
445 efx_bist_enable_offline(
448 efx_port_t *epp = &(enp->en_port);
449 const efx_phy_ops_t *epop = epp->ep_epop;
452 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
454 if (epop->epo_bist_enable_offline == NULL) {
459 if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
467 EFSYS_PROBE1(fail1, efx_rc_t, rc);
473 __checkReturn efx_rc_t
476 __in efx_bist_type_t type)
478 efx_port_t *epp = &(enp->en_port);
479 const efx_phy_ops_t *epop = epp->ep_epop;
482 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
484 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
485 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
486 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
488 if (epop->epo_bist_start == NULL) {
493 if ((rc = epop->epo_bist_start(enp, type)) != 0)
496 epp->ep_current_bist = type;
503 EFSYS_PROBE1(fail1, efx_rc_t, rc);
508 __checkReturn efx_rc_t
511 __in efx_bist_type_t type,
512 __out efx_bist_result_t *resultp,
513 __out_opt uint32_t *value_maskp,
514 __out_ecount_opt(count) unsigned long *valuesp,
517 efx_port_t *epp = &(enp->en_port);
518 const efx_phy_ops_t *epop = epp->ep_epop;
521 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
523 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
524 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
525 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
527 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
528 if (epop->epo_bist_poll == NULL) {
533 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
534 valuesp, count)) != 0)
542 EFSYS_PROBE1(fail1, efx_rc_t, rc);
550 __in efx_bist_type_t type)
552 efx_port_t *epp = &(enp->en_port);
553 const efx_phy_ops_t *epop = epp->ep_epop;
555 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
557 EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
558 EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
559 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
561 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
563 if (epop->epo_bist_stop != NULL)
564 epop->epo_bist_stop(enp, type);
566 epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
569 #endif /* EFSYS_OPT_BIST */
574 efx_port_t *epp = &(enp->en_port);
576 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
580 epp->ep_adv_cap_mask = 0;
583 epp->ep_phy_type = 0;