xref: /dpdk/drivers/common/sfc_efx/base/efx_mac.c (revision 0d09cbc7)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2007-2019 Solarflare Communications Inc.
5  */
6 
7 #include "efx.h"
8 #include "efx_impl.h"
9 
10 #if EFSYS_OPT_SIENA
11 
12 static	__checkReturn	efx_rc_t
13 siena_mac_multicast_list_set(
14 	__in		efx_nic_t *enp);
15 
16 #endif /* EFSYS_OPT_SIENA */
17 
18 #if EFSYS_OPT_SIENA
19 static const efx_mac_ops_t	__efx_mac_siena_ops = {
20 	siena_mac_poll,				/* emo_poll */
21 	siena_mac_up,				/* emo_up */
22 	siena_mac_reconfigure,			/* emo_addr_set */
23 	siena_mac_reconfigure,			/* emo_pdu_set */
24 	siena_mac_pdu_get,			/* emo_pdu_get */
25 	siena_mac_reconfigure,			/* emo_reconfigure */
26 	siena_mac_multicast_list_set,		/* emo_multicast_list_set */
27 	NULL,					/* emo_filter_set_default_rxq */
28 	NULL,				/* emo_filter_default_rxq_clear */
29 #if EFSYS_OPT_LOOPBACK
30 	siena_mac_loopback_set,			/* emo_loopback_set */
31 #endif	/* EFSYS_OPT_LOOPBACK */
32 #if EFSYS_OPT_MAC_STATS
33 	siena_mac_stats_get_mask,		/* emo_stats_get_mask */
34 	efx_mcdi_mac_stats_clear,		/* emo_stats_clear */
35 	efx_mcdi_mac_stats_upload,		/* emo_stats_upload */
36 	efx_mcdi_mac_stats_periodic,		/* emo_stats_periodic */
37 	siena_mac_stats_update			/* emo_stats_update */
38 #endif	/* EFSYS_OPT_MAC_STATS */
39 };
40 #endif	/* EFSYS_OPT_SIENA */
41 
42 #if EFX_OPTS_EF10()
43 static const efx_mac_ops_t	__efx_mac_ef10_ops = {
44 	ef10_mac_poll,				/* emo_poll */
45 	ef10_mac_up,				/* emo_up */
46 	ef10_mac_addr_set,			/* emo_addr_set */
47 	ef10_mac_pdu_set,			/* emo_pdu_set */
48 	ef10_mac_pdu_get,			/* emo_pdu_get */
49 	ef10_mac_reconfigure,			/* emo_reconfigure */
50 	ef10_mac_multicast_list_set,		/* emo_multicast_list_set */
51 	ef10_mac_filter_default_rxq_set,	/* emo_filter_default_rxq_set */
52 	ef10_mac_filter_default_rxq_clear,
53 					/* emo_filter_default_rxq_clear */
54 #if EFSYS_OPT_LOOPBACK
55 	ef10_mac_loopback_set,			/* emo_loopback_set */
56 #endif	/* EFSYS_OPT_LOOPBACK */
57 #if EFSYS_OPT_MAC_STATS
58 	ef10_mac_stats_get_mask,		/* emo_stats_get_mask */
59 	efx_mcdi_mac_stats_clear,		/* emo_stats_clear */
60 	efx_mcdi_mac_stats_upload,		/* emo_stats_upload */
61 	efx_mcdi_mac_stats_periodic,		/* emo_stats_periodic */
62 	ef10_mac_stats_update			/* emo_stats_update */
63 #endif	/* EFSYS_OPT_MAC_STATS */
64 };
65 #endif	/* EFX_OPTS_EF10() */
66 
67 	__checkReturn			efx_rc_t
68 efx_mac_pdu_set(
69 	__in				efx_nic_t *enp,
70 	__in				size_t pdu)
71 {
72 	efx_port_t *epp = &(enp->en_port);
73 	const efx_mac_ops_t *emop = epp->ep_emop;
74 	uint32_t old_pdu;
75 	efx_rc_t rc;
76 
77 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
78 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
79 	EFSYS_ASSERT(emop != NULL);
80 
81 	if (pdu < EFX_MAC_PDU_MIN) {
82 		rc = EINVAL;
83 		goto fail1;
84 	}
85 
86 	if (pdu > EFX_MAC_PDU_MAX) {
87 		rc = EINVAL;
88 		goto fail2;
89 	}
90 
91 	old_pdu = epp->ep_mac_pdu;
92 	epp->ep_mac_pdu = (uint32_t)pdu;
93 	if ((rc = emop->emo_pdu_set(enp)) != 0)
94 		goto fail3;
95 
96 	return (0);
97 
98 fail3:
99 	EFSYS_PROBE(fail3);
100 
101 	epp->ep_mac_pdu = old_pdu;
102 
103 fail2:
104 	EFSYS_PROBE(fail2);
105 fail1:
106 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
107 
108 	return (rc);
109 }
110 
111 	__checkReturn	efx_rc_t
112 efx_mac_pdu_get(
113 	__in		efx_nic_t *enp,
114 	__out		size_t *pdu)
115 {
116 	efx_port_t *epp = &(enp->en_port);
117 	const efx_mac_ops_t *emop = epp->ep_emop;
118 	efx_rc_t rc;
119 
120 	if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
121 		goto fail1;
122 
123 	return (0);
124 
125 fail1:
126 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
127 
128 	return (rc);
129 }
130 
131 	__checkReturn			efx_rc_t
132 efx_mac_addr_set(
133 	__in				efx_nic_t *enp,
134 	__in				uint8_t *addr)
135 {
136 	efx_port_t *epp = &(enp->en_port);
137 	const efx_mac_ops_t *emop = epp->ep_emop;
138 	uint8_t old_addr[6];
139 	uint32_t oui;
140 	efx_rc_t rc;
141 
142 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
143 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
144 
145 	if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
146 		rc = EINVAL;
147 		goto fail1;
148 	}
149 
150 	oui = addr[0] << 16 | addr[1] << 8 | addr[2];
151 	if (oui == 0x000000) {
152 		rc = EINVAL;
153 		goto fail2;
154 	}
155 
156 	EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
157 	EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
158 	if ((rc = emop->emo_addr_set(enp)) != 0)
159 		goto fail3;
160 
161 	return (0);
162 
163 fail3:
164 	EFSYS_PROBE(fail3);
165 
166 	EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
167 
168 fail2:
169 	EFSYS_PROBE(fail2);
170 fail1:
171 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
172 
173 	return (rc);
174 }
175 
176 	__checkReturn			efx_rc_t
177 efx_mac_filter_set(
178 	__in				efx_nic_t *enp,
179 	__in				boolean_t all_unicst,
180 	__in				boolean_t mulcst,
181 	__in				boolean_t all_mulcst,
182 	__in				boolean_t brdcst)
183 {
184 	efx_port_t *epp = &(enp->en_port);
185 	const efx_mac_ops_t *emop = epp->ep_emop;
186 	boolean_t old_all_unicst;
187 	boolean_t old_mulcst;
188 	boolean_t old_all_mulcst;
189 	boolean_t old_brdcst;
190 	efx_rc_t rc;
191 
192 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
193 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
194 
195 	old_all_unicst = epp->ep_all_unicst;
196 	old_mulcst = epp->ep_mulcst;
197 	old_all_mulcst = epp->ep_all_mulcst;
198 	old_brdcst = epp->ep_brdcst;
199 
200 	epp->ep_all_unicst = all_unicst;
201 	epp->ep_mulcst = mulcst;
202 	epp->ep_all_mulcst = all_mulcst;
203 	epp->ep_brdcst = brdcst;
204 
205 	if ((rc = emop->emo_reconfigure(enp)) != 0)
206 		goto fail1;
207 
208 	return (0);
209 
210 fail1:
211 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
212 
213 	epp->ep_all_unicst = old_all_unicst;
214 	epp->ep_mulcst = old_mulcst;
215 	epp->ep_all_mulcst = old_all_mulcst;
216 	epp->ep_brdcst = old_brdcst;
217 
218 	return (rc);
219 }
220 
221 					void
222 efx_mac_filter_get_all_ucast_mcast(
223 	__in				efx_nic_t *enp,
224 	__out				boolean_t *all_unicst,
225 	__out				boolean_t *all_mulcst)
226 {
227 	efx_port_t *epp = &(enp->en_port);
228 
229 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
230 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
231 
232 	*all_unicst = epp->ep_all_unicst_inserted;
233 	*all_mulcst = epp->ep_all_mulcst_inserted;
234 }
235 
236 	__checkReturn			efx_rc_t
237 efx_mac_drain(
238 	__in				efx_nic_t *enp,
239 	__in				boolean_t enabled)
240 {
241 	efx_port_t *epp = &(enp->en_port);
242 	const efx_mac_ops_t *emop = epp->ep_emop;
243 	efx_rc_t rc;
244 
245 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
246 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
247 	EFSYS_ASSERT(emop != NULL);
248 
249 	if (epp->ep_mac_drain == enabled)
250 		return (0);
251 
252 	epp->ep_mac_drain = enabled;
253 
254 	if ((rc = emop->emo_reconfigure(enp)) != 0)
255 		goto fail1;
256 
257 	return (0);
258 
259 fail1:
260 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
261 
262 	return (rc);
263 }
264 
265 	__checkReturn	efx_rc_t
266 efx_mac_up(
267 	__in		efx_nic_t *enp,
268 	__out		boolean_t *mac_upp)
269 {
270 	efx_port_t *epp = &(enp->en_port);
271 	const efx_mac_ops_t *emop = epp->ep_emop;
272 	efx_rc_t rc;
273 
274 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
275 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
276 
277 	if ((rc = emop->emo_up(enp, mac_upp)) != 0)
278 		goto fail1;
279 
280 	return (0);
281 
282 fail1:
283 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
284 
285 	return (rc);
286 }
287 
288 	__checkReturn			efx_rc_t
289 efx_mac_fcntl_set(
290 	__in				efx_nic_t *enp,
291 	__in				unsigned int fcntl,
292 	__in				boolean_t autoneg)
293 {
294 	efx_port_t *epp = &(enp->en_port);
295 	const efx_mac_ops_t *emop = epp->ep_emop;
296 	const efx_phy_ops_t *epop = epp->ep_epop;
297 	unsigned int old_fcntl;
298 	boolean_t old_autoneg;
299 	unsigned int old_adv_cap;
300 	efx_rc_t rc;
301 
302 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
303 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
304 
305 	if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
306 		rc = EINVAL;
307 		goto fail1;
308 	}
309 
310 	/*
311 	 * Ignore a request to set flow control auto-negotiation
312 	 * if the PHY doesn't support it.
313 	 */
314 	if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
315 		autoneg = B_FALSE;
316 
317 	old_fcntl = epp->ep_fcntl;
318 	old_autoneg = epp->ep_fcntl_autoneg;
319 	old_adv_cap = epp->ep_adv_cap_mask;
320 
321 	epp->ep_fcntl = fcntl;
322 	epp->ep_fcntl_autoneg = autoneg;
323 
324 	/*
325 	 * Always encode the flow control settings in the advertised
326 	 * capabilities even if we are not trying to auto-negotiate
327 	 * them and reconfigure both the PHY and the MAC.
328 	 */
329 	if (fcntl & EFX_FCNTL_RESPOND)
330 		epp->ep_adv_cap_mask |=    (1 << EFX_PHY_CAP_PAUSE |
331 					    1 << EFX_PHY_CAP_ASYM);
332 	else
333 		epp->ep_adv_cap_mask &=   ~(1 << EFX_PHY_CAP_PAUSE |
334 					    1 << EFX_PHY_CAP_ASYM);
335 
336 	if (fcntl & EFX_FCNTL_GENERATE)
337 		epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
338 
339 	if ((rc = epop->epo_reconfigure(enp)) != 0)
340 		goto fail2;
341 
342 	if ((rc = emop->emo_reconfigure(enp)) != 0)
343 		goto fail3;
344 
345 	return (0);
346 
347 fail3:
348 	EFSYS_PROBE(fail3);
349 
350 fail2:
351 	EFSYS_PROBE(fail2);
352 
353 	epp->ep_fcntl = old_fcntl;
354 	epp->ep_fcntl_autoneg = old_autoneg;
355 	epp->ep_adv_cap_mask = old_adv_cap;
356 
357 fail1:
358 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
359 
360 	return (rc);
361 }
362 
363 			void
364 efx_mac_fcntl_get(
365 	__in		efx_nic_t *enp,
366 	__out		unsigned int *fcntl_wantedp,
367 	__out		unsigned int *fcntl_linkp)
368 {
369 	efx_port_t *epp = &(enp->en_port);
370 	unsigned int wanted = 0;
371 
372 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
373 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
374 
375 	/*
376 	 * Decode the requested flow control settings from the PHY
377 	 * advertised capabilities.
378 	 */
379 	if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
380 		wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
381 	if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
382 		wanted ^= EFX_FCNTL_GENERATE;
383 
384 	*fcntl_linkp = epp->ep_fcntl;
385 	*fcntl_wantedp = wanted;
386 }
387 
388 	__checkReturn	efx_rc_t
389 efx_mac_multicast_list_set(
390 	__in				efx_nic_t *enp,
391 	__in_ecount(6*count)		uint8_t const *addrs,
392 	__in				int count)
393 {
394 	efx_port_t *epp = &(enp->en_port);
395 	const efx_mac_ops_t *emop = epp->ep_emop;
396 	uint8_t	*old_mulcst_addr_list = NULL;
397 	uint32_t old_mulcst_addr_count;
398 	efx_rc_t rc;
399 
400 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
401 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
402 
403 	if (count > EFX_MAC_MULTICAST_LIST_MAX) {
404 		rc = EINVAL;
405 		goto fail1;
406 	}
407 
408 	old_mulcst_addr_count = epp->ep_mulcst_addr_count;
409 	if (old_mulcst_addr_count > 0) {
410 		/* Allocate memory to store old list (instead of using stack) */
411 		EFSYS_KMEM_ALLOC(enp->en_esip,
412 				old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
413 				old_mulcst_addr_list);
414 		if (old_mulcst_addr_list == NULL) {
415 			rc = ENOMEM;
416 			goto fail2;
417 		}
418 
419 		/* Save the old list in case we need to rollback */
420 		memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
421 			old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
422 	}
423 
424 	/* Store the new list */
425 	memcpy(epp->ep_mulcst_addr_list, addrs,
426 		count * EFX_MAC_ADDR_LEN);
427 	epp->ep_mulcst_addr_count = count;
428 
429 	if ((rc = emop->emo_multicast_list_set(enp)) != 0)
430 		goto fail3;
431 
432 	if (old_mulcst_addr_count > 0) {
433 		EFSYS_KMEM_FREE(enp->en_esip,
434 				old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
435 				old_mulcst_addr_list);
436 	}
437 
438 	return (0);
439 
440 fail3:
441 	EFSYS_PROBE(fail3);
442 
443 	/* Restore original list on failure */
444 	epp->ep_mulcst_addr_count = old_mulcst_addr_count;
445 	if (old_mulcst_addr_count > 0) {
446 		memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
447 			old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
448 
449 		EFSYS_KMEM_FREE(enp->en_esip,
450 				old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
451 				old_mulcst_addr_list);
452 	}
453 
454 fail2:
455 	EFSYS_PROBE(fail2);
456 
457 fail1:
458 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
459 
460 	return (rc);
461 
462 }
463 
464 	__checkReturn	efx_rc_t
465 efx_mac_filter_default_rxq_set(
466 	__in		efx_nic_t *enp,
467 	__in		efx_rxq_t *erp,
468 	__in		boolean_t using_rss)
469 {
470 	efx_port_t *epp = &(enp->en_port);
471 	const efx_mac_ops_t *emop = epp->ep_emop;
472 	efx_rc_t rc;
473 
474 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
475 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
476 
477 	if (emop->emo_filter_default_rxq_set != NULL) {
478 		rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
479 		if (rc != 0)
480 			goto fail1;
481 	}
482 
483 	return (0);
484 
485 fail1:
486 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
487 
488 	return (rc);
489 }
490 
491 			void
492 efx_mac_filter_default_rxq_clear(
493 	__in		efx_nic_t *enp)
494 {
495 	efx_port_t *epp = &(enp->en_port);
496 	const efx_mac_ops_t *emop = epp->ep_emop;
497 
498 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
499 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
500 
501 	if (emop->emo_filter_default_rxq_clear != NULL)
502 		emop->emo_filter_default_rxq_clear(enp);
503 }
504 
505 
506 #if EFSYS_OPT_MAC_STATS
507 
508 #if EFSYS_OPT_NAMES
509 
510 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */
511 static const char * const __efx_mac_stat_name[] = {
512 	"rx_octets",
513 	"rx_pkts",
514 	"rx_unicst_pkts",
515 	"rx_multicst_pkts",
516 	"rx_brdcst_pkts",
517 	"rx_pause_pkts",
518 	"rx_le_64_pkts",
519 	"rx_65_to_127_pkts",
520 	"rx_128_to_255_pkts",
521 	"rx_256_to_511_pkts",
522 	"rx_512_to_1023_pkts",
523 	"rx_1024_to_15xx_pkts",
524 	"rx_ge_15xx_pkts",
525 	"rx_errors",
526 	"rx_fcs_errors",
527 	"rx_drop_events",
528 	"rx_false_carrier_errors",
529 	"rx_symbol_errors",
530 	"rx_align_errors",
531 	"rx_internal_errors",
532 	"rx_jabber_pkts",
533 	"rx_lane0_char_err",
534 	"rx_lane1_char_err",
535 	"rx_lane2_char_err",
536 	"rx_lane3_char_err",
537 	"rx_lane0_disp_err",
538 	"rx_lane1_disp_err",
539 	"rx_lane2_disp_err",
540 	"rx_lane3_disp_err",
541 	"rx_match_fault",
542 	"rx_nodesc_drop_cnt",
543 	"tx_octets",
544 	"tx_pkts",
545 	"tx_unicst_pkts",
546 	"tx_multicst_pkts",
547 	"tx_brdcst_pkts",
548 	"tx_pause_pkts",
549 	"tx_le_64_pkts",
550 	"tx_65_to_127_pkts",
551 	"tx_128_to_255_pkts",
552 	"tx_256_to_511_pkts",
553 	"tx_512_to_1023_pkts",
554 	"tx_1024_to_15xx_pkts",
555 	"tx_ge_15xx_pkts",
556 	"tx_errors",
557 	"tx_sgl_col_pkts",
558 	"tx_mult_col_pkts",
559 	"tx_ex_col_pkts",
560 	"tx_late_col_pkts",
561 	"tx_def_pkts",
562 	"tx_ex_def_pkts",
563 	"pm_trunc_bb_overflow",
564 	"pm_discard_bb_overflow",
565 	"pm_trunc_vfifo_full",
566 	"pm_discard_vfifo_full",
567 	"pm_trunc_qbb",
568 	"pm_discard_qbb",
569 	"pm_discard_mapping",
570 	"rxdp_q_disabled_pkts",
571 	"rxdp_di_dropped_pkts",
572 	"rxdp_streaming_pkts",
573 	"rxdp_hlb_fetch",
574 	"rxdp_hlb_wait",
575 	"vadapter_rx_unicast_packets",
576 	"vadapter_rx_unicast_bytes",
577 	"vadapter_rx_multicast_packets",
578 	"vadapter_rx_multicast_bytes",
579 	"vadapter_rx_broadcast_packets",
580 	"vadapter_rx_broadcast_bytes",
581 	"vadapter_rx_bad_packets",
582 	"vadapter_rx_bad_bytes",
583 	"vadapter_rx_overflow",
584 	"vadapter_tx_unicast_packets",
585 	"vadapter_tx_unicast_bytes",
586 	"vadapter_tx_multicast_packets",
587 	"vadapter_tx_multicast_bytes",
588 	"vadapter_tx_broadcast_packets",
589 	"vadapter_tx_broadcast_bytes",
590 	"vadapter_tx_bad_packets",
591 	"vadapter_tx_bad_bytes",
592 	"vadapter_tx_overflow",
593 	"fec_uncorrected_errors",
594 	"fec_corrected_errors",
595 	"fec_corrected_symbols_lane0",
596 	"fec_corrected_symbols_lane1",
597 	"fec_corrected_symbols_lane2",
598 	"fec_corrected_symbols_lane3",
599 	"ctpio_vi_busy_fallback",
600 	"ctpio_long_write_success",
601 	"ctpio_missing_dbell_fail",
602 	"ctpio_overflow_fail",
603 	"ctpio_underflow_fail",
604 	"ctpio_timeout_fail",
605 	"ctpio_noncontig_wr_fail",
606 	"ctpio_frm_clobber_fail",
607 	"ctpio_invalid_wr_fail",
608 	"ctpio_vi_clobber_fallback",
609 	"ctpio_unqualified_fallback",
610 	"ctpio_runt_fallback",
611 	"ctpio_success",
612 	"ctpio_fallback",
613 	"ctpio_poison",
614 	"ctpio_erase",
615 	"rxdp_scatter_disabled_trunc",
616 	"rxdp_hlb_idle",
617 	"rxdp_hlb_timeout",
618 };
619 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
620 
621 	__checkReturn			const char *
622 efx_mac_stat_name(
623 	__in				efx_nic_t *enp,
624 	__in				unsigned int id)
625 {
626 	_NOTE(ARGUNUSED(enp))
627 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
628 
629 	EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
630 	return (__efx_mac_stat_name[id]);
631 }
632 
633 #endif	/* EFSYS_OPT_NAMES */
634 
635 static					efx_rc_t
636 efx_mac_stats_mask_add_range(
637 	__inout_bcount(mask_size)	uint32_t *maskp,
638 	__in				size_t mask_size,
639 	__in				const struct efx_mac_stats_range *rngp)
640 {
641 	unsigned int mask_npages = mask_size / sizeof (*maskp);
642 	unsigned int el;
643 	unsigned int el_min;
644 	unsigned int el_max;
645 	unsigned int low;
646 	unsigned int high;
647 	unsigned int width;
648 	efx_rc_t rc;
649 
650 	if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <=
651 	    (unsigned int)rngp->last) {
652 		rc = EINVAL;
653 		goto fail1;
654 	}
655 
656 	EFSYS_ASSERT3U(rngp->first, <=, rngp->last);
657 	EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS);
658 
659 	for (el = 0; el < mask_npages; ++el) {
660 		el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE;
661 		el_max =
662 		    el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1);
663 		if ((unsigned int)rngp->first > el_max ||
664 		    (unsigned int)rngp->last < el_min)
665 			continue;
666 		low = MAX((unsigned int)rngp->first, el_min);
667 		high = MIN((unsigned int)rngp->last, el_max);
668 		width = high - low + 1;
669 		maskp[el] |=
670 		    (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ?
671 		    (~0ULL) : (((1ULL << width) - 1) << (low - el_min));
672 	}
673 
674 	return (0);
675 
676 fail1:
677 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
678 
679 	return (rc);
680 }
681 
682 					efx_rc_t
683 efx_mac_stats_mask_add_ranges(
684 	__inout_bcount(mask_size)	uint32_t *maskp,
685 	__in				size_t mask_size,
686 	__in_ecount(rng_count)		const struct efx_mac_stats_range *rngp,
687 	__in				unsigned int rng_count)
688 {
689 	unsigned int i;
690 	efx_rc_t rc;
691 
692 	for (i = 0; i < rng_count; ++i) {
693 		if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size,
694 		    &rngp[i])) != 0)
695 			goto fail1;
696 	}
697 
698 	return (0);
699 
700 fail1:
701 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
702 
703 	return (rc);
704 }
705 
706 	__checkReturn			efx_rc_t
707 efx_mac_stats_get_mask(
708 	__in				efx_nic_t *enp,
709 	__out_bcount(mask_size)		uint32_t *maskp,
710 	__in				size_t mask_size)
711 {
712 	efx_port_t *epp = &(enp->en_port);
713 	const efx_mac_ops_t *emop = epp->ep_emop;
714 	efx_rc_t rc;
715 
716 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
717 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
718 	EFSYS_ASSERT(maskp != NULL);
719 	EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0);
720 
721 	(void) memset(maskp, 0, mask_size);
722 
723 	if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0)
724 		goto fail1;
725 
726 	return (0);
727 
728 fail1:
729 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
730 
731 	return (rc);
732 }
733 
734 	__checkReturn			efx_rc_t
735 efx_mac_stats_clear(
736 	__in				efx_nic_t *enp)
737 {
738 	efx_port_t *epp = &(enp->en_port);
739 	const efx_mac_ops_t *emop = epp->ep_emop;
740 	efx_rc_t rc;
741 
742 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
743 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
744 	EFSYS_ASSERT(emop != NULL);
745 
746 	if ((rc = emop->emo_stats_clear(enp)) != 0)
747 		goto fail1;
748 
749 	return (0);
750 
751 fail1:
752 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
753 
754 	return (rc);
755 }
756 
757 	__checkReturn			efx_rc_t
758 efx_mac_stats_upload(
759 	__in				efx_nic_t *enp,
760 	__in				efsys_mem_t *esmp)
761 {
762 	efx_port_t *epp = &(enp->en_port);
763 	const efx_mac_ops_t *emop = epp->ep_emop;
764 	efx_rc_t rc;
765 
766 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
767 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
768 	EFSYS_ASSERT(emop != NULL);
769 
770 	if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
771 		goto fail1;
772 
773 	return (0);
774 
775 fail1:
776 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
777 
778 	return (rc);
779 }
780 
781 	__checkReturn			efx_rc_t
782 efx_mac_stats_periodic(
783 	__in				efx_nic_t *enp,
784 	__in				efsys_mem_t *esmp,
785 	__in				uint16_t period_ms,
786 	__in				boolean_t events)
787 {
788 	efx_port_t *epp = &(enp->en_port);
789 	const efx_mac_ops_t *emop = epp->ep_emop;
790 	efx_rc_t rc;
791 
792 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
793 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
794 
795 	EFSYS_ASSERT(emop != NULL);
796 
797 	if (emop->emo_stats_periodic == NULL) {
798 		rc = EINVAL;
799 		goto fail1;
800 	}
801 
802 	if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
803 		goto fail2;
804 
805 	return (0);
806 
807 fail2:
808 	EFSYS_PROBE(fail2);
809 fail1:
810 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
811 
812 	return (rc);
813 }
814 
815 
816 	__checkReturn			efx_rc_t
817 efx_mac_stats_update(
818 	__in				efx_nic_t *enp,
819 	__in				efsys_mem_t *esmp,
820 	__inout_ecount(EFX_MAC_NSTATS)	efsys_stat_t *essp,
821 	__inout_opt			uint32_t *generationp)
822 {
823 	efx_port_t *epp = &(enp->en_port);
824 	const efx_mac_ops_t *emop = epp->ep_emop;
825 	efx_rc_t rc;
826 
827 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
828 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
829 	EFSYS_ASSERT(emop != NULL);
830 
831 	rc = emop->emo_stats_update(enp, esmp, essp, generationp);
832 
833 	return (rc);
834 }
835 
836 #endif	/* EFSYS_OPT_MAC_STATS */
837 
838 	__checkReturn			efx_rc_t
839 efx_mac_select(
840 	__in				efx_nic_t *enp)
841 {
842 	efx_port_t *epp = &(enp->en_port);
843 	efx_mac_type_t type = EFX_MAC_INVALID;
844 	const efx_mac_ops_t *emop;
845 	int rc = EINVAL;
846 
847 	switch (enp->en_family) {
848 #if EFSYS_OPT_SIENA
849 	case EFX_FAMILY_SIENA:
850 		emop = &__efx_mac_siena_ops;
851 		type = EFX_MAC_SIENA;
852 		break;
853 #endif /* EFSYS_OPT_SIENA */
854 
855 #if EFSYS_OPT_HUNTINGTON
856 	case EFX_FAMILY_HUNTINGTON:
857 		emop = &__efx_mac_ef10_ops;
858 		type = EFX_MAC_HUNTINGTON;
859 		break;
860 #endif /* EFSYS_OPT_HUNTINGTON */
861 
862 #if EFSYS_OPT_MEDFORD
863 	case EFX_FAMILY_MEDFORD:
864 		emop = &__efx_mac_ef10_ops;
865 		type = EFX_MAC_MEDFORD;
866 		break;
867 #endif /* EFSYS_OPT_MEDFORD */
868 
869 #if EFSYS_OPT_MEDFORD2
870 	case EFX_FAMILY_MEDFORD2:
871 		emop = &__efx_mac_ef10_ops;
872 		type = EFX_MAC_MEDFORD2;
873 		break;
874 #endif /* EFSYS_OPT_MEDFORD2 */
875 
876 	default:
877 		rc = EINVAL;
878 		goto fail1;
879 	}
880 
881 	EFSYS_ASSERT(type != EFX_MAC_INVALID);
882 	EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
883 	EFSYS_ASSERT(emop != NULL);
884 
885 	epp->ep_emop = emop;
886 	epp->ep_mac_type = type;
887 
888 	return (0);
889 
890 fail1:
891 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
892 
893 	return (rc);
894 }
895 
896 
897 #if EFSYS_OPT_SIENA
898 
899 #define	EFX_MAC_HASH_BITS	(1 << 8)
900 
901 /* Compute the multicast hash as used on Falcon and Siena. */
902 static	void
903 siena_mac_multicast_hash_compute(
904 	__in_ecount(6*count)		uint8_t const *addrs,
905 	__in				int count,
906 	__out				efx_oword_t *hash_low,
907 	__out				efx_oword_t *hash_high)
908 {
909 	uint32_t crc, index;
910 	int i;
911 
912 	EFSYS_ASSERT(hash_low != NULL);
913 	EFSYS_ASSERT(hash_high != NULL);
914 
915 	EFX_ZERO_OWORD(*hash_low);
916 	EFX_ZERO_OWORD(*hash_high);
917 
918 	for (i = 0; i < count; i++) {
919 		/* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
920 		crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
921 		index = crc % EFX_MAC_HASH_BITS;
922 		if (index < 128) {
923 			EFX_SET_OWORD_BIT(*hash_low, index);
924 		} else {
925 			EFX_SET_OWORD_BIT(*hash_high, index - 128);
926 		}
927 
928 		addrs += EFX_MAC_ADDR_LEN;
929 	}
930 }
931 
932 static	__checkReturn	efx_rc_t
933 siena_mac_multicast_list_set(
934 	__in		efx_nic_t *enp)
935 {
936 	efx_port_t *epp = &(enp->en_port);
937 	const efx_mac_ops_t *emop = epp->ep_emop;
938 	efx_oword_t old_hash[2];
939 	efx_rc_t rc;
940 
941 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
942 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
943 
944 	memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
945 
946 	siena_mac_multicast_hash_compute(
947 	    epp->ep_mulcst_addr_list,
948 	    epp->ep_mulcst_addr_count,
949 	    &epp->ep_multicst_hash[0],
950 	    &epp->ep_multicst_hash[1]);
951 
952 	if ((rc = emop->emo_reconfigure(enp)) != 0)
953 		goto fail1;
954 
955 	return (0);
956 
957 fail1:
958 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
959 
960 	memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
961 
962 	return (rc);
963 }
964 
965 #endif /* EFSYS_OPT_SIENA */
966