1 /*
2 * Copyright 2007-2013 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 "efsys.h"
27 #include "efx.h"
28 #include "efx_types.h"
29 #include "efx_impl.h"
30
31 #if EFSYS_OPT_MAC_FALCON_GMAC
32 #include "falcon_gmac.h"
33 #endif
34
35 #if EFSYS_OPT_MAC_FALCON_XMAC
36 #include "falcon_xmac.h"
37 #endif
38
39 #if EFSYS_OPT_MAC_FALCON_GMAC
40 static efx_mac_ops_t __cs __efx_falcon_gmac_ops = {
41 falcon_gmac_reset, /* emo_reset */
42 falcon_mac_poll, /* emo_poll */
43 falcon_mac_up, /* emo_up */
44 falcon_gmac_reconfigure, /* emo_reconfigure */
45 #if EFSYS_OPT_LOOPBACK
46 falcon_mac_loopback_set, /* emo_loopback_set */
47 #endif /* EFSYS_OPT_LOOPBACK */
48 #if EFSYS_OPT_MAC_STATS
49 falcon_mac_stats_upload, /* emo_stats_upload */
50 NULL, /* emo_stats_periodic */
51 falcon_gmac_stats_update /* emo_stats_update */
52 #endif /* EFSYS_OPT_MAC_STATS */
53 };
54 #endif /* EFSYS_OPT_MAC_FALCON_GMAC */
55
56 #if EFSYS_OPT_MAC_FALCON_XMAC
57 static efx_mac_ops_t __cs __efx_falcon_xmac_ops = {
58 falcon_xmac_reset, /* emo_reset */
59 falcon_mac_poll, /* emo_poll */
60 falcon_mac_up, /* emo_up */
61 falcon_xmac_reconfigure, /* emo_reconfigure */
62 #if EFSYS_OPT_LOOPBACK
63 falcon_mac_loopback_set, /* emo_loopback_set */
64 #endif /* EFSYS_OPT_LOOPBACK */
65 #if EFSYS_OPT_MAC_STATS
66 falcon_mac_stats_upload, /* emo_stats_upload */
67 NULL, /* emo_stats_periodic */
68 falcon_xmac_stats_update /* emo_stats_update */
69 #endif /* EFSYS_OPT_MAC_STATS */
70 };
71 #endif /* EFSYS_OPT_MAC_FALCON_XMAC */
72
73 #if EFSYS_OPT_SIENA
74 static efx_mac_ops_t __cs __efx_siena_mac_ops = {
75 NULL, /* emo_reset */
76 siena_mac_poll, /* emo_poll */
77 siena_mac_up, /* emo_up */
78 siena_mac_reconfigure, /* emo_reconfigure */
79 #if EFSYS_OPT_LOOPBACK
80 siena_mac_loopback_set, /* emo_loopback_set */
81 #endif /* EFSYS_OPT_LOOPBACK */
82 #if EFSYS_OPT_MAC_STATS
83 siena_mac_stats_upload, /* emo_stats_upload */
84 siena_mac_stats_periodic, /* emo_stats_periodic */
85 siena_mac_stats_update /* emo_stats_update */
86 #endif /* EFSYS_OPT_MAC_STATS */
87 };
88 #endif /* EFSYS_OPT_SIENA */
89
90 static efx_mac_ops_t __cs * __cs __efx_mac_ops[] = {
91 NULL,
92 #if EFSYS_OPT_MAC_FALCON_GMAC
93 &__efx_falcon_gmac_ops,
94 #else
95 NULL,
96 #endif /* EFSYS_OPT_MAC_FALCON_GMAC */
97 #if EFSYS_OPT_MAC_FALCON_XMAC
98 &__efx_falcon_xmac_ops,
99 #else
100 NULL,
101 #endif /* EFSYS_OPT_MAC_FALCON_XMAC */
102 #if EFSYS_OPT_SIENA
103 &__efx_siena_mac_ops,
104 #else
105 NULL,
106 #endif /* EFSYS_OPT_SIENA */
107 };
108
109 __checkReturn int
110 efx_mac_pdu_set(
111 __in efx_nic_t *enp,
112 __in size_t pdu)
113 {
114 efx_port_t *epp = &(enp->en_port);
115 efx_mac_ops_t *emop = epp->ep_emop;
116 uint32_t old_pdu;
117 int rc;
118
119 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
120 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
121 EFSYS_ASSERT(emop != NULL);
122
123 if (pdu < EFX_MAC_PDU_MIN) {
124 rc = EINVAL;
125 goto fail1;
126 }
127
128 if (pdu > EFX_MAC_PDU_MAX) {
129 rc = EINVAL;
130 goto fail2;
131 }
132
133 old_pdu = epp->ep_mac_pdu;
134 epp->ep_mac_pdu = (uint32_t)pdu;
135 if ((rc = emop->emo_reconfigure(enp)) != 0)
136 goto fail3;
137
138 return (0);
139
140 fail3:
141 EFSYS_PROBE(fail3);
142
143 epp->ep_mac_pdu = old_pdu;
144
145 fail2:
146 EFSYS_PROBE(fail2);
147 fail1:
148 EFSYS_PROBE1(fail1, int, rc);
149
150 return (rc);
151 }
152
153 __checkReturn int
154 efx_mac_addr_set(
155 __in efx_nic_t *enp,
156 __in uint8_t *addr)
157 {
158 efx_port_t *epp = &(enp->en_port);
159 efx_mac_ops_t *emop = epp->ep_emop;
160 uint8_t old_addr[6];
161 uint32_t oui;
162 int rc;
163
164 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
165 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
166
167 if (addr[0] & 0x01) {
168 rc = EINVAL;
169 goto fail1;
170 }
171
172 oui = addr[0] << 16 | addr[1] << 8 | addr[2];
173 if (oui == 0x000000) {
174 rc = EINVAL;
175 goto fail2;
176 }
177
178 EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
179 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
180 if ((rc = emop->emo_reconfigure(enp)) != 0)
181 goto fail3;
182
183 return (0);
184
185 fail3:
186 EFSYS_PROBE(fail3);
187
188 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
189
190 fail2:
191 EFSYS_PROBE(fail2);
192 fail1:
193 EFSYS_PROBE1(fail1, int, rc);
194
195 return (rc);
196 }
197
198 __checkReturn int
199 efx_mac_filter_set(
200 __in efx_nic_t *enp,
201 __in boolean_t unicst,
202 __in boolean_t brdcst)
203 {
204 efx_port_t *epp = &(enp->en_port);
205 efx_mac_ops_t *emop = epp->ep_emop;
206 boolean_t old_unicst;
207 boolean_t old_brdcst;
208 int rc;
209
210 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
211 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
212
213 old_unicst = unicst;
214 old_brdcst = brdcst;
215
216 epp->ep_unicst = unicst;
217 epp->ep_brdcst = brdcst;
218
219 if ((rc = emop->emo_reconfigure(enp)) != 0)
220 goto fail1;
221
222 return (0);
223
224 fail1:
225 EFSYS_PROBE1(fail1, int, rc);
226
227 epp->ep_unicst = old_unicst;
228 epp->ep_brdcst = old_brdcst;
229
230 return (rc);
231 }
232
233 __checkReturn int
234 efx_mac_drain(
235 __in efx_nic_t *enp,
236 __in boolean_t enabled)
237 {
238 efx_port_t *epp = &(enp->en_port);
239 efx_mac_ops_t *emop = epp->ep_emop;
240 int rc;
241
242 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
243 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
244 EFSYS_ASSERT(emop != NULL);
245
246 if (epp->ep_mac_drain == enabled)
247 return (0);
248
249 epp->ep_mac_drain = enabled;
250
251 if (enabled && emop->emo_reset != NULL) {
252 if ((rc = emop->emo_reset(enp)) != 0)
253 goto fail1;
254
255 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
256 enp->en_reset_flags &= ~EFX_RESET_PHY;
257 }
258
259 if ((rc = emop->emo_reconfigure(enp)) != 0)
260 goto fail2;
261
262 return (0);
263
264 fail2:
265 EFSYS_PROBE(fail2);
266 fail1:
267 EFSYS_PROBE1(fail1, int, rc);
268
269 return (rc);
270 }
271
272 __checkReturn int
273 efx_mac_up(
274 __in efx_nic_t *enp,
275 __out boolean_t *mac_upp)
276 {
277 efx_port_t *epp = &(enp->en_port);
278 efx_mac_ops_t *emop = epp->ep_emop;
279 int rc;
280
281 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
282 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
283
284 if ((rc = emop->emo_up(enp, mac_upp)) != 0)
285 goto fail1;
286
287 return (0);
288
289 fail1:
290 EFSYS_PROBE1(fail1, int, rc);
291
292 return (rc);
293 }
294
295 __checkReturn int
296 efx_mac_fcntl_set(
297 __in efx_nic_t *enp,
298 __in unsigned int fcntl,
299 __in boolean_t autoneg)
300 {
301 efx_port_t *epp = &(enp->en_port);
302 efx_mac_ops_t *emop = epp->ep_emop;
303 efx_phy_ops_t *epop = epp->ep_epop;
304 unsigned int old_fcntl;
305 boolean_t old_autoneg;
306 unsigned int old_adv_cap;
307 int rc;
308
309 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
310 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
311
312 if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
313 rc = EINVAL;
314 goto fail1;
315 }
316
317 /*
318 * Ignore a request to set flow control autonegotiation
319 * if the PHY doesn't support it.
320 */
321 if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
322 autoneg = B_FALSE;
323
324 old_fcntl = epp->ep_fcntl;
325 old_autoneg = autoneg;
326 old_adv_cap = epp->ep_adv_cap_mask;
327
328 epp->ep_fcntl = fcntl;
329 epp->ep_fcntl_autoneg = autoneg;
330
331 /*
332 * If the PHY supports autonegotiation, then encode the flow control
333 * settings in the advertised capabilities, and restart AN. Otherwise,
334 * just push the new settings directly to the MAC.
335 */
336 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
337 if (fcntl & EFX_FCNTL_RESPOND)
338 epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
339 1 << EFX_PHY_CAP_ASYM);
340 else
341 epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
342 1 << EFX_PHY_CAP_ASYM);
343
344 if (fcntl & EFX_FCNTL_GENERATE)
345 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
346
347 if ((rc = epop->epo_reconfigure(enp)) != 0)
348 goto fail2;
349
350 } else {
351 if ((rc = emop->emo_reconfigure(enp)) != 0)
352 goto fail2;
353 }
354
355 return (0);
356
357 fail2:
358 EFSYS_PROBE(fail2);
359
360 epp->ep_fcntl = old_fcntl;
361 epp->ep_fcntl_autoneg = old_autoneg;
362 epp->ep_adv_cap_mask = old_adv_cap;
363
364 fail1:
365 EFSYS_PROBE1(fail1, int, rc);
366
367 return (rc);
368 }
369
370 void
371 efx_mac_fcntl_get(
372 __in efx_nic_t *enp,
373 __out unsigned int *fcntl_wantedp,
374 __out unsigned int *fcntl_linkp)
375 {
376 efx_port_t *epp = &(enp->en_port);
377 unsigned int wanted;
378
379 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
380 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
381
382 /*
383 * If the PHY supports auto negotiation, then the requested flow
384 * control settings are encoded in the advertised capabilities.
385 */
386 if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
387 wanted = 0;
388
389 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
390 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
391 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
392 wanted ^= EFX_FCNTL_GENERATE;
393 } else
394 wanted = epp->ep_fcntl;
395
396 *fcntl_linkp = epp->ep_fcntl;
397 *fcntl_wantedp = wanted;
398 }
399
400 __checkReturn int
401 efx_mac_hash_set(
402 __in efx_nic_t *enp,
403 __in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket)
404 {
405 efx_port_t *epp = &(enp->en_port);
406 efx_mac_ops_t *emop = epp->ep_emop;
407 efx_oword_t old_hash[2];
408 unsigned int index;
409 int rc;
410
411 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
412 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
413
414 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
415
416 /* Set the lower 128 bits of the hash */
417 EFX_ZERO_OWORD(epp->ep_multicst_hash[0]);
418 for (index = 0; index < 128; index++) {
419 if (bucket[index] != 0)
420 EFX_SET_OWORD_BIT(epp->ep_multicst_hash[0], index);
421 }
422
423 /* Set the upper 128 bits of the hash */
424 EFX_ZERO_OWORD(epp->ep_multicst_hash[1]);
425 for (index = 0; index < 128; index++) {
426 if (bucket[index + 128] != 0)
427 EFX_SET_OWORD_BIT(epp->ep_multicst_hash[1], index);
428 }
429
430 if ((rc = emop->emo_reconfigure(enp)) != 0)
431 goto fail1;
432
433 return (0);
434
435 fail1:
436 EFSYS_PROBE1(fail1, int, rc);
437
438 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
439
440 return (rc);
441 }
442
443 #if EFSYS_OPT_MAC_STATS
444
445 #if EFSYS_OPT_NAMES
446
447 /* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */
448 static const char __cs * __cs __efx_mac_stat_name[] = {
449 "rx_octets",
450 "rx_pkts",
451 "rx_unicst_pkts",
452 "rx_multicst_pkts",
453 "rx_brdcst_pkts",
454 "rx_pause_pkts",
455 "rx_le_64_pkts",
456 "rx_65_to_127_pkts",
457 "rx_128_to_255_pkts",
458 "rx_256_to_511_pkts",
459 "rx_512_to_1023_pkts",
460 "rx_1024_to_15xx_pkts",
461 "rx_ge_15xx_pkts",
462 "rx_errors",
463 "rx_fcs_errors",
464 "rx_drop_events",
465 "rx_false_carrier_errors",
466 "rx_symbol_errors",
467 "rx_align_errors",
468 "rx_internal_errors",
469 "rx_jabber_pkts",
470 "rx_lane0_char_err",
471 "rx_lane1_char_err",
472 "rx_lane2_char_err",
473 "rx_lane3_char_err",
474 "rx_lane0_disp_err",
475 "rx_lane1_disp_err",
476 "rx_lane2_disp_err",
477 "rx_lane3_disp_err",
478 "rx_match_fault",
479 "rx_nodesc_drop_cnt",
480 "tx_octets",
481 "tx_pkts",
482 "tx_unicst_pkts",
483 "tx_multicst_pkts",
484 "tx_brdcst_pkts",
485 "tx_pause_pkts",
486 "tx_le_64_pkts",
487 "tx_65_to_127_pkts",
488 "tx_128_to_255_pkts",
489 "tx_256_to_511_pkts",
490 "tx_512_to_1023_pkts",
491 "tx_1024_to_15xx_pkts",
492 "tx_ge_15xx_pkts",
493 "tx_errors",
494 "tx_sgl_col_pkts",
495 "tx_mult_col_pkts",
496 "tx_ex_col_pkts",
497 "tx_late_col_pkts",
498 "tx_def_pkts",
499 "tx_ex_def_pkts",
500 };
501 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
502
503 __checkReturn const char __cs *
504 efx_mac_stat_name(
505 __in efx_nic_t *enp,
506 __in unsigned int id)
507 {
508 _NOTE(ARGUNUSED(enp))
509 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
510
511 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
512 return (__efx_mac_stat_name[id]);
513 }
514
515 #endif /* EFSYS_OPT_STAT_NAME */
516
517 __checkReturn int
518 efx_mac_stats_upload(
519 __in efx_nic_t *enp,
520 __in efsys_mem_t *esmp)
521 {
522 efx_port_t *epp = &(enp->en_port);
523 efx_mac_ops_t *emop = epp->ep_emop;
524 int rc;
525
526 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
527 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
528 EFSYS_ASSERT(emop != NULL);
529
530 /*
531 * Don't assert !ep_mac_stats_pending, because the client might
532 * have failed to finalise statistics when previously stopping
533 * the port.
534 */
535 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
536 goto fail1;
537
538 epp->ep_mac_stats_pending = B_TRUE;
539
540 return (0);
541
542 fail1:
543 EFSYS_PROBE1(fail1, int, rc);
544
545 return (rc);
546 }
547
548 __checkReturn int
549 efx_mac_stats_periodic(
550 __in efx_nic_t *enp,
551 __in efsys_mem_t *esmp,
552 __in uint16_t period_ms,
553 __in boolean_t events)
554 {
555 efx_port_t *epp = &(enp->en_port);
556 efx_mac_ops_t *emop = epp->ep_emop;
557 int rc;
558
559 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
560 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
561
562 EFSYS_ASSERT(emop != NULL);
563
564 if (emop->emo_stats_periodic == NULL) {
565 rc = EINVAL;
566 goto fail1;
567 }
568
569 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
570 goto fail2;
571
572 return (0);
573
574 fail2:
575 EFSYS_PROBE(fail2);
576 fail1:
577 EFSYS_PROBE1(fail1, int, rc);
578
579 return (rc);
580 }
581
582
583 __checkReturn int
584 efx_mac_stats_update(
585 __in efx_nic_t *enp,
586 __in efsys_mem_t *esmp,
587 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
588 __in uint32_t *generationp)
589 {
590 efx_port_t *epp = &(enp->en_port);
591 efx_mac_ops_t *emop = epp->ep_emop;
592 int rc;
593
594 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
595 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
596 EFSYS_ASSERT(emop != NULL);
597
598 rc = emop->emo_stats_update(enp, esmp, essp, generationp);
599 if (rc == 0)
600 epp->ep_mac_stats_pending = B_FALSE;
601
602 return (rc);
603 }
604
605 #endif /* EFSYS_OPT_MAC_STATS */
606
607 __checkReturn int
608 efx_mac_select(
609 __in efx_nic_t *enp)
610 {
611 efx_port_t *epp = &(enp->en_port);
612 efx_mac_type_t type = EFX_MAC_INVALID;
613 efx_mac_ops_t *emop;
614 int rc = EINVAL;
615
616 #if EFSYS_OPT_SIENA
617 if (enp->en_family == EFX_FAMILY_SIENA) {
618 type = EFX_MAC_SIENA;
619 goto chosen;
620 }
621 #endif
622
623 #if EFSYS_OPT_FALCON
624 switch (epp->ep_link_mode) {
625 #if EFSYS_OPT_MAC_FALCON_GMAC
626 case EFX_LINK_100HDX:
627 case EFX_LINK_100FDX:
628 case EFX_LINK_1000HDX:
629 case EFX_LINK_1000FDX:
630 type = EFX_MAC_FALCON_GMAC;
631 goto chosen;
632 #endif /* EFSYS_OPT_FALCON_GMAC */
633
634 #if EFSYS_OPT_MAC_FALCON_XMAC
635 case EFX_LINK_10000FDX:
636 type = EFX_MAC_FALCON_XMAC;
637 goto chosen;
638 #endif /* EFSYS_OPT_FALCON_XMAC */
639
640 default:
641 #if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC
642 /* Only initialise a MAC supported by the PHY */
643 if (epp->ep_phy_cap_mask &
644 ((1 << EFX_PHY_CAP_1000FDX) |
645 (1 << EFX_PHY_CAP_1000HDX) |
646 (1 << EFX_PHY_CAP_100FDX) |
647 (1 << EFX_PHY_CAP_100HDX) |
648 (1 << EFX_PHY_CAP_10FDX) |
649 (1 << EFX_PHY_CAP_10FDX)))
650 type = EFX_MAC_FALCON_GMAC;
651 else
652 type = EFX_MAC_FALCON_XMAC;
653 #elif EFSYS_OPT_MAC_FALCON_GMAC
654 type = EFX_MAC_FALCON_GMAC;
655 #else
656 type = EFX_MAC_FALCON_XMAC;
657 #endif
658 goto chosen;
659 }
660 #endif /* EFSYS_OPT_FALCON */
661
662 chosen:
663 EFSYS_ASSERT(type != EFX_MAC_INVALID);
664 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
665 emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type];
666 EFSYS_ASSERT(emop != NULL);
667
668 epp->ep_mac_type = type;
669
670 if (emop->emo_reset != NULL) {
671 if ((rc = emop->emo_reset(enp)) != 0)
672 goto fail1;
673
674 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
675 enp->en_reset_flags &= ~EFX_RESET_MAC;
676 }
677
678 return (0);
679
680 fail1:
681 EFSYS_PROBE1(fail1, int, rc);
682
683 return (rc);
684 }