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