efx_mac.c revision 227569
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 "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
40static 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
57static 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
74static 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
90static 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
110efx_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
140fail3:
141	EFSYS_PROBE(fail3);
142
143	epp->ep_mac_pdu = old_pdu;
144
145fail2:
146	EFSYS_PROBE(fail2);
147fail1:
148	EFSYS_PROBE1(fail1, int, rc);
149
150	return (rc);
151}
152
153	__checkReturn			int
154efx_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
185fail3:
186	EFSYS_PROBE(fail3);
187
188	EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
189
190fail2:
191	EFSYS_PROBE(fail2);
192fail1:
193	EFSYS_PROBE1(fail1, int, rc);
194
195	return (rc);
196}
197
198	__checkReturn			int
199efx_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
224fail1:
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
234efx_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
264fail2:
265	EFSYS_PROBE(fail2);
266fail1:
267	EFSYS_PROBE1(fail1, int, rc);
268
269	return (rc);
270}
271
272	__checkReturn	int
273efx_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
289fail1:
290	EFSYS_PROBE1(fail1, int, rc);
291
292	return (rc);
293}
294
295	__checkReturn			int
296efx_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
357fail2:
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
364fail1:
365	EFSYS_PROBE1(fail1, int, rc);
366
367	return (rc);
368}
369
370			void
371efx_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
401efx_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
435fail1:
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 */
448static 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 *
504efx_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
518efx_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
542fail1:
543	EFSYS_PROBE1(fail1, int, rc);
544
545	return (rc);
546}
547
548	__checkReturn			int
549efx_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
574fail2:
575	EFSYS_PROBE(fail2);
576fail1:
577	EFSYS_PROBE1(fail1, int, rc);
578
579	return (rc);
580}
581
582
583	__checkReturn			int
584efx_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
608efx_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
662chosen:
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
680fail1:
681	EFSYS_PROBE1(fail1, int, rc);
682
683	return (rc);
684}
685