1 /*-
2 * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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
23 * SUCH DAMAGE.
24 */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include "efsys.h"
30 #include "efx.h"
31 #include "efx_types.h"
32 #include "efx_regs.h"
33 #include "efx_impl.h"
34 #if EFSYS_OPT_FALCON
35 #include "falcon_nvram.h"
36 #endif
37
38 #if EFSYS_OPT_MAC_FALCON_XMAC
39 #include "falcon_xmac.h"
40 #endif
41
42 #if EFSYS_OPT_MAC_FALCON_GMAC
43 #include "falcon_gmac.h"
44 #endif
45
46 #if EFSYS_OPT_PHY_NULL
47 #include "nullphy.h"
48 #endif
49
50 #if EFSYS_OPT_PHY_QT2022C2
51 #include "qt2022c2.h"
52 #endif
53
54 #if EFSYS_OPT_PHY_SFX7101
55 #include "sfx7101.h"
56 #endif
57
58 #if EFSYS_OPT_PHY_TXC43128
59 #include "txc43128.h"
60 #endif
61
62 #if EFSYS_OPT_PHY_SFT9001
63 #include "sft9001.h"
64 #endif
65
66 #if EFSYS_OPT_PHY_QT2025C
67 #include "qt2025c.h"
68 #endif
69
70 #if EFSYS_OPT_PHY_NULL
71 static efx_phy_ops_t __cs __efx_phy_null_ops = {
72 NULL, /* epo_power */
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
83 #if EFSYS_OPT_NAMES
84 nullphy_prop_name, /* epo_prop_name */
85 #endif
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 */
94 };
95 #endif /* EFSYS_OPT_PHY_NULL */
96
97 #if EFSYS_OPT_PHY_QT2022C2
98 static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = {
99 NULL, /* epo_power */
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
110 #if EFSYS_OPT_NAMES
111 qt2022c2_prop_name, /* epo_prop_name */
112 #endif
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 */
121 };
122 #endif /* EFSYS_OPT_PHY_QT2022C2 */
123
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
137 #if EFSYS_OPT_NAMES
138 sfx7101_prop_name, /* epo_prop_name */
139 #endif
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 */
148 };
149 #endif /* EFSYS_OPT_PHY_SFX7101 */
150
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
164 #if EFSYS_OPT_NAMES
165 txc43128_prop_name, /* epo_prop_name */
166 #endif
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 */
175 };
176 #endif /* EFSYS_OPT_PHY_TXC43128 */
177
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
191 #if EFSYS_OPT_NAMES
192 sft9001_prop_name, /* epo_prop_name */
193 #endif
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 */
202 };
203 #endif /* EFSYS_OPT_PHY_SFT9001 */
204
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
218 #if EFSYS_OPT_NAMES
219 qt2025c_prop_name, /* epo_prop_name */
220 #endif
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 */
229 };
230 #endif /* EFSYS_OPT_PHY_QT2025C */
231
232 #if EFSYS_OPT_SIENA
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
245 #if EFSYS_OPT_NAMES
246 siena_phy_prop_name, /* epo_prop_name */
247 #endif
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 */
256 };
257 #endif /* EFSYS_OPT_SIENA */
258
259 __checkReturn int
efx_phy_probe(__in efx_nic_t * enp)260 efx_phy_probe(
261 __in efx_nic_t *enp)
262 {
263 efx_port_t *epp = &(enp->en_port);
264 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
265 efx_phy_ops_t *epop;
266 int rc;
267
268 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
269
270 epp->ep_port = encp->enc_port;
271 epp->ep_phy_type = encp->enc_phy_type;
272
273 /* Hook in operations structure */
274 switch (enp->en_family) {
275 #if EFSYS_OPT_FALCON
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;
281 break;
282 #endif
283 #if EFSYS_OPT_PHY_QT2022C2
284 case PHY_TYPE_QT2022C2_DECODE:
285 epop = (efx_phy_ops_t *)&__efx_phy_qt2022c2_ops;
286 break;
287 #endif
288 #if EFSYS_OPT_PHY_SFX7101
289 case PHY_TYPE_SFX7101_DECODE:
290 epop = (efx_phy_ops_t *)&__efx_phy_sfx7101_ops;
291 break;
292 #endif
293 #if EFSYS_OPT_PHY_TXC43128
294 case PHY_TYPE_TXC43128_DECODE:
295 epop = (efx_phy_ops_t *)&__efx_phy_txc43128_ops;
296 break;
297 #endif
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;
302 break;
303 #endif
304 #if EFSYS_OPT_PHY_QT2025C
305 case EFX_PHY_QT2025C:
306 epop = (efx_phy_ops_t *)&__efx_phy_qt2025c_ops;
307 break;
308 #endif
309 default:
310 rc = ENOTSUP;
311 goto fail1;
312 }
313 break;
314 #endif /* EFSYS_OPT_FALCON */
315 #if EFSYS_OPT_SIENA
316 case EFX_FAMILY_SIENA:
317 epop = (efx_phy_ops_t *)&__efx_phy_siena_ops;
318 break;
319 #endif /* EFSYS_OPT_SIENA */
320 default:
321 rc = ENOTSUP;
322 goto fail1;
323 }
324
325 epp->ep_epop = epop;
326
327 return (0);
328
329 fail1:
330 EFSYS_PROBE1(fail1, int, rc);
331
332 epp->ep_port = 0;
333 epp->ep_phy_type = 0;
334
335 return (rc);
336 }
337
338 __checkReturn int
efx_phy_verify(__in efx_nic_t * enp)339 efx_phy_verify(
340 __in efx_nic_t *enp)
341 {
342 efx_port_t *epp = &(enp->en_port);
343 efx_phy_ops_t *epop = epp->ep_epop;
344
345 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
346 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
347
348 return (epop->epo_verify(enp));
349 }
350
351 #if EFSYS_OPT_PHY_LED_CONTROL
352
353 __checkReturn int
efx_phy_led_set(__in efx_nic_t * enp,__in efx_phy_led_mode_t mode)354 efx_phy_led_set(
355 __in efx_nic_t *enp,
356 __in efx_phy_led_mode_t mode)
357 {
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;
361 uint32_t mask;
362 int rc;
363
364 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
365 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
366
367 if (epp->ep_phy_led_mode == mode)
368 goto done;
369
370 mask = (1 << EFX_PHY_LED_DEFAULT);
371 mask |= encp->enc_led_mask;
372
373 if (!((1 << mode) & mask)) {
374 rc = ENOTSUP;
375 goto fail1;
376 }
377
378 EFSYS_ASSERT3U(mode, <, EFX_PHY_LED_NMODES);
379 epp->ep_phy_led_mode = mode;
380
381 if ((rc = epop->epo_reconfigure(enp)) != 0)
382 goto fail2;
383
384 done:
385 return (0);
386
387 fail2:
388 EFSYS_PROBE(fail2);
389 fail1:
390 EFSYS_PROBE1(fail1, int, rc);
391
392 return (rc);
393 }
394 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
395
396 void
efx_phy_adv_cap_get(__in efx_nic_t * enp,__in uint32_t flag,__out uint32_t * maskp)397 efx_phy_adv_cap_get(
398 __in efx_nic_t *enp,
399 __in uint32_t flag,
400 __out uint32_t *maskp)
401 {
402 efx_port_t *epp = &(enp->en_port);
403
404 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
405 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
406
407 switch (flag) {
408 case EFX_PHY_CAP_CURRENT:
409 *maskp = epp->ep_adv_cap_mask;
410 break;
411 case EFX_PHY_CAP_DEFAULT:
412 *maskp = epp->ep_default_adv_cap_mask;
413 break;
414 case EFX_PHY_CAP_PERM:
415 *maskp = epp->ep_phy_cap_mask;
416 break;
417 default:
418 EFSYS_ASSERT(B_FALSE);
419 break;
420 }
421 }
422
423 __checkReturn int
efx_phy_adv_cap_set(__in efx_nic_t * enp,__in uint32_t mask)424 efx_phy_adv_cap_set(
425 __in efx_nic_t *enp,
426 __in uint32_t mask)
427 {
428 efx_port_t *epp = &(enp->en_port);
429 efx_phy_ops_t *epop = epp->ep_epop;
430 uint32_t old_mask;
431 int rc;
432
433 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
434 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
435
436 if ((mask & ~epp->ep_phy_cap_mask) != 0) {
437 rc = ENOTSUP;
438 goto fail1;
439 }
440
441 if (epp->ep_adv_cap_mask == mask)
442 goto done;
443
444 old_mask = epp->ep_adv_cap_mask;
445 epp->ep_adv_cap_mask = mask;
446
447 if ((rc = epop->epo_reconfigure(enp)) != 0)
448 goto fail2;
449
450 done:
451 return (0);
452
453 fail2:
454 EFSYS_PROBE(fail2);
455
456 epp->ep_adv_cap_mask = old_mask;
457 /* Reconfigure for robustness */
458 if (epop->epo_reconfigure(enp) != 0) {
459 /*
460 * We may have an inconsistent view of our advertised speed
461 * capabilities.
462 */
463 EFSYS_ASSERT(0);
464 }
465
466 fail1:
467 EFSYS_PROBE1(fail1, int, rc);
468
469 return (rc);
470 }
471
472 void
efx_phy_lp_cap_get(__in efx_nic_t * enp,__out uint32_t * maskp)473 efx_phy_lp_cap_get(
474 __in efx_nic_t *enp,
475 __out uint32_t *maskp)
476 {
477 efx_port_t *epp = &(enp->en_port);
478
479 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
480 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
481
482 *maskp = epp->ep_lp_cap_mask;
483 }
484
485 __checkReturn int
efx_phy_oui_get(__in efx_nic_t * enp,__out uint32_t * ouip)486 efx_phy_oui_get(
487 __in efx_nic_t *enp,
488 __out uint32_t *ouip)
489 {
490 efx_port_t *epp = &(enp->en_port);
491 efx_phy_ops_t *epop = epp->ep_epop;
492
493 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
494 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
495
496 return (epop->epo_oui_get(enp, ouip));
497 }
498
499 void
efx_phy_media_type_get(__in efx_nic_t * enp,__out efx_phy_media_type_t * typep)500 efx_phy_media_type_get(
501 __in efx_nic_t *enp,
502 __out efx_phy_media_type_t *typep)
503 {
504 efx_port_t *epp = &(enp->en_port);
505
506 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
507 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
508
509 if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
510 *typep = epp->ep_module_type;
511 else
512 *typep = epp->ep_fixed_port_type;
513 }
514
515 #if EFSYS_OPT_PHY_STATS
516
517 #if EFSYS_OPT_NAMES
518
519 /* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
520 static const char __cs * __cs __efx_phy_stat_name[] = {
521 "oui",
522 "pma_pmd_link_up",
523 "pma_pmd_rx_fault",
524 "pma_pmd_tx_fault",
525 "pma_pmd_rev_a",
526 "pma_pmd_rev_b",
527 "pma_pmd_rev_c",
528 "pma_pmd_rev_d",
529 "pcs_link_up",
530 "pcs_rx_fault",
531 "pcs_tx_fault",
532 "pcs_ber",
533 "pcs_block_errors",
534 "phy_xs_link_up",
535 "phy_xs_rx_fault",
536 "phy_xs_tx_fault",
537 "phy_xs_align",
538 "phy_xs_sync_a",
539 "phy_xs_sync_b",
540 "phy_xs_sync_c",
541 "phy_xs_sync_d",
542 "an_link_up",
543 "an_master",
544 "an_local_rx_ok",
545 "an_remote_rx_ok",
546 "cl22ext_link_up",
547 "snr_a",
548 "snr_b",
549 "snr_c",
550 "snr_d",
551 "pma_pmd_signal_a",
552 "pma_pmd_signal_b",
553 "pma_pmd_signal_c",
554 "pma_pmd_signal_d",
555 "an_complete",
556 "pma_pmd_rev_major",
557 "pma_pmd_rev_minor",
558 "pma_pmd_rev_micro",
559 "pcs_fw_version_0",
560 "pcs_fw_version_1",
561 "pcs_fw_version_2",
562 "pcs_fw_version_3",
563 "pcs_fw_build_yy",
564 "pcs_fw_build_mm",
565 "pcs_fw_build_dd",
566 "pcs_op_mode",
567 };
568
569 /* END MKCONFIG GENERATED PhyStatNamesBlock */
570
571 const char __cs *
efx_phy_stat_name(__in efx_nic_t * enp,__in efx_phy_stat_t type)572 efx_phy_stat_name(
573 __in efx_nic_t *enp,
574 __in efx_phy_stat_t type)
575 {
576 _NOTE(ARGUNUSED(enp))
577 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
578 EFSYS_ASSERT3U(type, <, EFX_PHY_NSTATS);
579
580 return (__efx_phy_stat_name[type]);
581 }
582
583 #endif /* EFSYS_OPT_NAMES */
584
585 __checkReturn int
efx_phy_stats_update(__in efx_nic_t * enp,__in efsys_mem_t * esmp,__out_ecount (EFX_PHY_NSTATS)uint32_t * stat)586 efx_phy_stats_update(
587 __in efx_nic_t *enp,
588 __in efsys_mem_t *esmp,
589 __out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
590 {
591 efx_port_t *epp = &(enp->en_port);
592 efx_phy_ops_t *epop = epp->ep_epop;
593
594 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
595 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
596
597 return (epop->epo_stats_update(enp, esmp, stat));
598 }
599
600 #endif /* EFSYS_OPT_PHY_STATS */
601
602 #if EFSYS_OPT_PHY_PROPS
603
604 #if EFSYS_OPT_NAMES
605 const char __cs *
efx_phy_prop_name(__in efx_nic_t * enp,__in unsigned int id)606 efx_phy_prop_name(
607 __in efx_nic_t *enp,
608 __in unsigned int id)
609 {
610 efx_port_t *epp = &(enp->en_port);
611 efx_phy_ops_t *epop = epp->ep_epop;
612
613 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
614 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
615
616 return (epop->epo_prop_name(enp, id));
617 }
618 #endif /* EFSYS_OPT_NAMES */
619
620 __checkReturn int
efx_phy_prop_get(__in efx_nic_t * enp,__in unsigned int id,__in uint32_t flags,__out uint32_t * valp)621 efx_phy_prop_get(
622 __in efx_nic_t *enp,
623 __in unsigned int id,
624 __in uint32_t flags,
625 __out uint32_t *valp)
626 {
627 efx_port_t *epp = &(enp->en_port);
628 efx_phy_ops_t *epop = epp->ep_epop;
629
630 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
631 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
632
633 return (epop->epo_prop_get(enp, id, flags, valp));
634 }
635
636 __checkReturn int
efx_phy_prop_set(__in efx_nic_t * enp,__in unsigned int id,__in uint32_t val)637 efx_phy_prop_set(
638 __in efx_nic_t *enp,
639 __in unsigned int id,
640 __in uint32_t val)
641 {
642 efx_port_t *epp = &(enp->en_port);
643 efx_phy_ops_t *epop = epp->ep_epop;
644
645 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
646 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
647
648 return (epop->epo_prop_set(enp, id, val));
649 }
650 #endif /* EFSYS_OPT_PHY_STATS */
651
652 #if EFSYS_OPT_PHY_BIST
653
654 __checkReturn int
efx_phy_bist_start(__in efx_nic_t * enp,__in efx_phy_bist_type_t type)655 efx_phy_bist_start(
656 __in efx_nic_t *enp,
657 __in efx_phy_bist_type_t type)
658 {
659 efx_port_t *epp = &(enp->en_port);
660 efx_phy_ops_t *epop = epp->ep_epop;
661 int rc;
662
663 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
664 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
665
666 EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
667 EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
668 EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
669
670 if (epop->epo_bist_start == NULL) {
671 rc = ENOTSUP;
672 goto fail1;
673 }
674
675 if ((rc = epop->epo_bist_start(enp, type)) != 0)
676 goto fail2;
677
678 epp->ep_current_bist = type;
679
680 return (0);
681
682 fail2:
683 EFSYS_PROBE(fail2);
684 fail1:
685 EFSYS_PROBE1(fail1, int, rc);
686
687 return (rc);
688 }
689
690 __checkReturn int
efx_phy_bist_poll(__in efx_nic_t * enp,__in efx_phy_bist_type_t type,__out efx_phy_bist_result_t * resultp,__out_opt uint32_t * value_maskp,__out_ecount_opt (count)unsigned long * valuesp,__in size_t count)691 efx_phy_bist_poll(
692 __in efx_nic_t *enp,
693 __in efx_phy_bist_type_t type,
694 __out efx_phy_bist_result_t *resultp,
695 __out_opt uint32_t *value_maskp,
696 __out_ecount_opt(count) unsigned long *valuesp,
697 __in size_t count)
698 {
699 efx_port_t *epp = &(enp->en_port);
700 efx_phy_ops_t *epop = epp->ep_epop;
701 int rc;
702
703 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
704 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
705
706 EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
707 EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
708 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
709
710 EFSYS_ASSERT(epop->epo_bist_poll != NULL);
711 if (epop->epo_bist_poll == NULL) {
712 rc = ENOTSUP;
713 goto fail1;
714 }
715
716 if ((rc = epop->epo_bist_poll(enp, type, resultp, value_maskp,
717 valuesp, count)) != 0)
718 goto fail2;
719
720 return (0);
721
722 fail2:
723 EFSYS_PROBE(fail2);
724 fail1:
725 EFSYS_PROBE1(fail1, int, rc);
726
727 return (rc);
728 }
729
730 void
efx_phy_bist_stop(__in efx_nic_t * enp,__in efx_phy_bist_type_t type)731 efx_phy_bist_stop(
732 __in efx_nic_t *enp,
733 __in efx_phy_bist_type_t type)
734 {
735 efx_port_t *epp = &(enp->en_port);
736 efx_phy_ops_t *epop = epp->ep_epop;
737
738 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
739 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
740
741 EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
742 EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
743 EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
744
745 EFSYS_ASSERT(epop->epo_bist_stop != NULL);
746
747 if (epop->epo_bist_stop != NULL)
748 epop->epo_bist_stop(enp, type);
749
750 epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
751 }
752
753 #endif /* EFSYS_OPT_PHY_BIST */
754 void
efx_phy_unprobe(__in efx_nic_t * enp)755 efx_phy_unprobe(
756 __in efx_nic_t *enp)
757 {
758 efx_port_t *epp = &(enp->en_port);
759
760 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
761
762 epp->ep_epop = NULL;
763
764 epp->ep_adv_cap_mask = 0;
765
766 epp->ep_port = 0;
767 epp->ep_phy_type = 0;
768 }
769