2 * Copyright (c) 2012-2015 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
36 #include "efx_types.h"
39 #if EFSYS_OPT_MON_STATS
43 #if EFSYS_OPT_HUNTINGTON
46 #define EFX_EV_QSTAT_INCR(_eep, _stat) \
48 (_eep)->ee_stat[_stat]++; \
49 _NOTE(CONSTANTCONDITION) \
52 #define EFX_EV_QSTAT_INCR(_eep, _stat)
56 static __checkReturn boolean_t
59 __in efx_qword_t *eqp,
60 __in const efx_ev_callbacks_t *eecp,
63 static __checkReturn boolean_t
66 __in efx_qword_t *eqp,
67 __in const efx_ev_callbacks_t *eecp,
70 static __checkReturn boolean_t
73 __in efx_qword_t *eqp,
74 __in const efx_ev_callbacks_t *eecp,
77 static __checkReturn boolean_t
80 __in efx_qword_t *eqp,
81 __in const efx_ev_callbacks_t *eecp,
84 static __checkReturn boolean_t
87 __in efx_qword_t *eqp,
88 __in const efx_ev_callbacks_t *eecp,
92 static __checkReturn int
95 __in unsigned int instance,
96 __in efsys_mem_t *esmp,
99 __out_opt uint32_t *irqp)
103 MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
104 MC_CMD_INIT_EVQ_OUT_LEN)];
105 efx_qword_t *dma_addr;
109 int supports_rx_batching;
112 npages = EFX_EVQ_NBUFS(nevs);
113 if (MC_CMD_INIT_EVQ_IN_LEN(npages) > MC_CMD_INIT_EVQ_IN_LENMAX) {
118 (void) memset(payload, 0, sizeof (payload));
119 req.emr_cmd = MC_CMD_INIT_EVQ;
120 req.emr_in_buf = payload;
121 req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
122 req.emr_out_buf = payload;
123 req.emr_out_length = MC_CMD_INIT_EVQ_OUT_LEN;
125 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_SIZE, nevs);
126 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_INSTANCE, instance);
127 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_IRQ_NUM, irq);
130 * On Huntington RX and TX event batching can only be requested
131 * together (even if the datapath firmware doesn't actually support RX
133 * Cut through is incompatible with RX batching and so enabling cut
134 * through disables RX batching (but it does not affect TX batching).
136 * So always enable RX and TX event batching, and enable cut through
137 * if RX event batching isn't supported (i.e. on low latency firmware).
139 supports_rx_batching = enp->en_nic_cfg.enc_rx_batching_enabled ? 1 : 0;
140 MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_IN_FLAGS,
141 INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
142 INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
143 INIT_EVQ_IN_FLAG_INT_ARMD, 0,
144 INIT_EVQ_IN_FLAG_CUT_THRU, !supports_rx_batching,
145 INIT_EVQ_IN_FLAG_RX_MERGE, 1,
146 INIT_EVQ_IN_FLAG_TX_MERGE, 1);
148 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
149 MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
150 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, 0);
151 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, 0);
153 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_MODE,
154 MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
155 MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_THRSHLD, 0);
157 dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_IN_DMA_ADDR);
158 addr = EFSYS_MEM_ADDR(esmp);
160 for (i = 0; i < npages; i++) {
161 EFX_POPULATE_QWORD_2(*dma_addr,
162 EFX_DWORD_1, (uint32_t)(addr >> 32),
163 EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
166 addr += EFX_BUF_SIZE;
169 efx_mcdi_execute(enp, &req);
171 if (req.emr_rc != 0) {
176 if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) {
182 *irqp = MCDI_OUT_DWORD(req, INIT_EVQ_OUT_IRQ);
191 EFSYS_PROBE1(fail1, int, rc);
196 static __checkReturn int
199 __in uint32_t instance)
202 uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
203 MC_CMD_FINI_EVQ_OUT_LEN)];
206 (void) memset(payload, 0, sizeof (payload));
207 req.emr_cmd = MC_CMD_FINI_EVQ;
208 req.emr_in_buf = payload;
209 req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
210 req.emr_out_buf = payload;
211 req.emr_out_length = MC_CMD_FINI_EVQ_OUT_LEN;
213 MCDI_IN_SET_DWORD(req, FINI_EVQ_IN_INSTANCE, instance);
215 efx_mcdi_execute(enp, &req);
217 if (req.emr_rc != 0) {
225 EFSYS_PROBE1(fail1, int, rc);
236 _NOTE(ARGUNUSED(enp))
244 _NOTE(ARGUNUSED(enp))
250 __in unsigned int index,
251 __in efsys_mem_t *esmp,
256 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
260 _NOTE(ARGUNUSED(id)) /* buftbl id managed by MC */
261 EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
262 EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
264 if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
269 if (index >= encp->enc_evq_limit) {
274 /* Set up the handler table */
275 eep->ee_rx = hunt_ev_rx;
276 eep->ee_tx = hunt_ev_tx;
277 eep->ee_driver = hunt_ev_driver;
278 eep->ee_drv_gen = hunt_ev_drv_gen;
279 eep->ee_mcdi = hunt_ev_mcdi;
282 * Set up the event queue
283 * NOTE: ignore the returned IRQ param as firmware does not set it.
285 irq = index; /* INIT_EVQ expects function-relative vector number */
286 if ((rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, NULL)) != 0)
296 EFSYS_PROBE1(fail1, int, rc);
305 efx_nic_t *enp = eep->ee_enp;
307 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
309 (void) efx_mcdi_fini_evq(eep->ee_enp, eep->ee_index);
315 __in unsigned int count)
317 efx_nic_t *enp = eep->ee_enp;
321 rptr = count & eep->ee_mask;
323 if (enp->en_nic_cfg.enc_bug35388_workaround) {
324 EFX_STATIC_ASSERT(EFX_EVQ_MINNEVS >
325 (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
326 EFX_STATIC_ASSERT(EFX_EVQ_MAXNEVS <
327 (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
329 EFX_POPULATE_DWORD_2(dword,
330 ERF_DD_EVQ_IND_RPTR_FLAGS,
331 EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
333 (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
334 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
337 EFX_POPULATE_DWORD_2(dword,
338 ERF_DD_EVQ_IND_RPTR_FLAGS,
339 EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
341 rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
342 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
345 EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
346 EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
353 static __checkReturn int
354 efx_mcdi_driver_event(
357 __in efx_qword_t data)
360 uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
361 MC_CMD_DRIVER_EVENT_OUT_LEN)];
364 req.emr_cmd = MC_CMD_DRIVER_EVENT;
365 req.emr_in_buf = payload;
366 req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
367 req.emr_out_buf = payload;
368 req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
370 MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
372 MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
373 EFX_QWORD_FIELD(data, EFX_DWORD_0));
374 MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
375 EFX_QWORD_FIELD(data, EFX_DWORD_1));
377 efx_mcdi_execute(enp, &req);
379 if (req.emr_rc != 0) {
387 EFSYS_PROBE1(fail1, int, rc);
397 efx_nic_t *enp = eep->ee_enp;
400 EFX_POPULATE_QWORD_3(event,
401 ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
402 ESF_DZ_DRV_SUB_CODE, 0,
403 ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
405 (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
411 __in unsigned int us)
413 efx_nic_t *enp = eep->ee_enp;
414 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
416 uint32_t timer_val, mode;
419 if (us > encp->enc_evq_timer_max_us) {
424 /* If the value is zero then disable the timer */
427 mode = FFE_CZ_TIMER_MODE_DIS;
429 /* Calculate the timer value in quanta */
430 timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
432 /* Moderation value is base 0 so we need to deduct 1 */
436 mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
439 if (encp->enc_bug35388_workaround) {
440 EFX_POPULATE_DWORD_3(dword,
441 ERF_DD_EVQ_IND_TIMER_FLAGS,
442 EFE_DD_EVQ_IND_TIMER_FLAGS,
443 ERF_DD_EVQ_IND_TIMER_MODE, mode,
444 ERF_DD_EVQ_IND_TIMER_VAL, timer_val);
445 EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
446 eep->ee_index, &dword, 0);
448 EFX_POPULATE_DWORD_2(dword,
449 FRF_CZ_TC_TIMER_MODE, mode,
450 FRF_CZ_TC_TIMER_VAL, timer_val);
451 EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
452 eep->ee_index, &dword, 0);
458 EFSYS_PROBE1(fail1, int, rc);
466 hunt_ev_qstats_update(
468 __inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
471 * TBD: Consider a common Siena/Huntington function. The code is
472 * essentially identical.
476 for (id = 0; id < EV_NQSTATS; id++) {
477 efsys_stat_t *essp = &stat[id];
479 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
480 eep->ee_stat[id] = 0;
483 #endif /* EFSYS_OPT_QSTATS */
486 static __checkReturn boolean_t
489 __in efx_qword_t *eqp,
490 __in const efx_ev_callbacks_t *eecp,
493 efx_nic_t *enp = eep->ee_enp;
498 uint32_t eth_base_class;
499 uint32_t eth_tag_class;
502 uint32_t next_read_lbits;
503 boolean_t soft1, soft2;
505 boolean_t should_abort;
506 efx_evq_rxq_state_t *eersp;
507 unsigned int desc_count;
508 unsigned int last_used_id;
510 EFX_EV_QSTAT_INCR(eep, EV_RX);
512 /* Discard events after RXQ/TXQ errors */
513 if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
517 * FIXME: likely to be incomplete, incorrect and inefficient.
518 * Improvements in all three areas are required.
521 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
522 /* Drop this event */
527 size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
529 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT) != 0) {
531 * FIXME: There is not yet any driver that supports scatter on
532 * Huntington. Scatter support is required for OSX.
535 flags |= EFX_PKT_CONT;
538 parse_err = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE) != 0);
539 label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
541 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
542 /* Ethernet frame CRC bad */
543 flags |= EFX_DISCARD;
545 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC0_ERR) != 0) {
546 /* IP+TCP, bad CRC in iSCSI header */
547 flags |= EFX_DISCARD;
549 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC1_ERR) != 0) {
550 /* IP+TCP, bad CRC in iSCSI payload or FCoE or FCoIP */
551 flags |= EFX_DISCARD;
553 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
554 /* ECC memory error */
555 flags |= EFX_DISCARD;
558 /* FIXME: do we need soft bits from RXDP firmware ? */
559 soft1 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT1) != 0);
560 soft2 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT2) != 0);
562 mcast = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
563 if (mcast == ESE_DZ_MAC_CLASS_UCAST)
564 flags |= EFX_PKT_UNICAST;
566 eth_base_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_BASE_CLASS);
567 eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
568 l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
569 l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
571 /* bottom 4 bits of incremented index (not last desc consumed) */
572 next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
574 /* Increment the count of descriptors read */
575 eersp = &eep->ee_rxq_state[label];
576 desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
577 EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
578 eersp->eers_rx_read_ptr += desc_count;
581 * FIXME: add error checking to make sure this a batched event.
582 * This could also be an aborted scatter, see Bug36629.
584 if (desc_count > 1) {
585 EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
586 flags |= EFX_PKT_PREFIX_LEN;
589 /* Calculate the index of the the last descriptor consumed */
590 last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
592 /* EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_OVERRIDE_HOLDOFF); */
594 switch (eth_base_class) {
595 case ESE_DZ_ETH_BASE_CLASS_LLC_SNAP:
596 case ESE_DZ_ETH_BASE_CLASS_LLC:
597 case ESE_DZ_ETH_BASE_CLASS_ETH2:
602 switch (eth_tag_class) {
603 case ESE_DZ_ETH_TAG_CLASS_RSVD7:
604 case ESE_DZ_ETH_TAG_CLASS_RSVD6:
605 case ESE_DZ_ETH_TAG_CLASS_RSVD5:
606 case ESE_DZ_ETH_TAG_CLASS_RSVD4:
609 case ESE_DZ_ETH_TAG_CLASS_RSVD3: /* Triple tagged */
610 case ESE_DZ_ETH_TAG_CLASS_VLAN2: /* Double tagged */
611 case ESE_DZ_ETH_TAG_CLASS_VLAN1: /* VLAN tagged */
612 flags |= EFX_PKT_VLAN_TAGGED;
615 case ESE_DZ_ETH_TAG_CLASS_NONE:
621 case ESE_DZ_L3_CLASS_RSVD7: /* Used by firmware for packet overrun */
623 flags |= EFX_DISCARD;
626 case ESE_DZ_L3_CLASS_ARP:
627 case ESE_DZ_L3_CLASS_FCOE:
630 case ESE_DZ_L3_CLASS_IP6_FRAG:
631 case ESE_DZ_L3_CLASS_IP6:
632 flags |= EFX_PKT_IPV6;
635 case ESE_DZ_L3_CLASS_IP4_FRAG:
636 case ESE_DZ_L3_CLASS_IP4:
637 flags |= EFX_PKT_IPV4;
638 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR) == 0)
639 flags |= EFX_CKSUM_IPV4;
642 case ESE_DZ_L3_CLASS_UNKNOWN:
648 case ESE_DZ_L4_CLASS_RSVD7:
649 case ESE_DZ_L4_CLASS_RSVD6:
650 case ESE_DZ_L4_CLASS_RSVD5:
651 case ESE_DZ_L4_CLASS_RSVD4:
652 case ESE_DZ_L4_CLASS_RSVD3:
655 case ESE_DZ_L4_CLASS_UDP:
656 flags |= EFX_PKT_UDP;
657 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
658 flags |= EFX_CKSUM_TCPUDP;
661 case ESE_DZ_L4_CLASS_TCP:
662 flags |= EFX_PKT_TCP;
663 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
664 flags |= EFX_CKSUM_TCPUDP;
667 case ESE_DZ_L4_CLASS_UNKNOWN:
672 /* If we're not discarding the packet then it is ok */
673 if (~flags & EFX_DISCARD)
674 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
676 EFSYS_ASSERT(eecp->eec_rx != NULL);
677 should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
679 return (should_abort);
682 static __checkReturn boolean_t
685 __in efx_qword_t *eqp,
686 __in const efx_ev_callbacks_t *eecp,
689 efx_nic_t *enp = eep->ee_enp;
692 boolean_t should_abort;
694 EFX_EV_QSTAT_INCR(eep, EV_TX);
696 /* Discard events after RXQ/TXQ errors */
697 if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
700 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
701 /* Drop this event */
705 /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
706 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
707 label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
709 EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
711 EFSYS_ASSERT(eecp->eec_tx != NULL);
712 should_abort = eecp->eec_tx(arg, label, id);
714 return (should_abort);
717 static __checkReturn boolean_t
720 __in efx_qword_t *eqp,
721 __in const efx_ev_callbacks_t *eecp,
725 boolean_t should_abort;
727 EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
728 should_abort = B_FALSE;
730 code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
732 case ESE_DZ_DRV_TIMER_EV: {
735 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
737 EFSYS_ASSERT(eecp->eec_timer != NULL);
738 should_abort = eecp->eec_timer(arg, id);
742 case ESE_DZ_DRV_WAKE_UP_EV: {
745 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
747 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
748 should_abort = eecp->eec_wake_up(arg, id);
752 case ESE_DZ_DRV_START_UP_EV:
753 EFSYS_ASSERT(eecp->eec_initialized != NULL);
754 should_abort = eecp->eec_initialized(arg);
758 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
759 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
760 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
764 return (should_abort);
767 static __checkReturn boolean_t
770 __in efx_qword_t *eqp,
771 __in const efx_ev_callbacks_t *eecp,
775 boolean_t should_abort;
777 EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
778 should_abort = B_FALSE;
780 data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
781 if (data >= ((uint32_t)1 << 16)) {
782 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
783 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
784 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
789 EFSYS_ASSERT(eecp->eec_software != NULL);
790 should_abort = eecp->eec_software(arg, (uint16_t)data);
792 return (should_abort);
795 static __checkReturn boolean_t
798 __in efx_qword_t *eqp,
799 __in const efx_ev_callbacks_t *eecp,
802 efx_nic_t *enp = eep->ee_enp;
804 boolean_t should_abort = B_FALSE;
806 EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
808 code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
810 case MCDI_EVENT_CODE_BADSSERT:
811 efx_mcdi_ev_death(enp, EINTR);
814 case MCDI_EVENT_CODE_CMDDONE:
816 MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
817 MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
818 MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
821 case MCDI_EVENT_CODE_LINKCHANGE: {
822 efx_link_mode_t link_mode;
824 hunt_phy_link_ev(enp, eqp, &link_mode);
825 should_abort = eecp->eec_link_change(arg, link_mode);
829 case MCDI_EVENT_CODE_SENSOREVT: {
830 #if EFSYS_OPT_MON_STATS
832 efx_mon_stat_value_t value;
835 /* Decode monitor stat for MCDI sensor (if supported) */
836 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
837 /* Report monitor stat change */
838 should_abort = eecp->eec_monitor(arg, id, value);
839 } else if (rc == ENOTSUP) {
840 should_abort = eecp->eec_exception(arg,
841 EFX_EXCEPTION_UNKNOWN_SENSOREVT,
842 MCDI_EV_FIELD(eqp, DATA));
844 EFSYS_ASSERT(rc == ENODEV); /* Wrong port */
850 case MCDI_EVENT_CODE_SCHEDERR:
851 /* Informational only */
854 case MCDI_EVENT_CODE_REBOOT:
855 /* Falcon/Siena only (should not been seen with Huntington). */
856 efx_mcdi_ev_death(enp, EIO);
859 case MCDI_EVENT_CODE_MC_REBOOT:
860 /* MC_REBOOT event is used for Huntington (EF10) and later. */
861 efx_mcdi_ev_death(enp, EIO);
864 case MCDI_EVENT_CODE_MAC_STATS_DMA:
865 #if EFSYS_OPT_MAC_STATS
866 if (eecp->eec_mac_stats != NULL) {
867 eecp->eec_mac_stats(arg,
868 MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
873 case MCDI_EVENT_CODE_FWALERT: {
874 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
876 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
877 should_abort = eecp->eec_exception(arg,
878 EFX_EXCEPTION_FWALERT_SRAM,
879 MCDI_EV_FIELD(eqp, FWALERT_DATA));
881 should_abort = eecp->eec_exception(arg,
882 EFX_EXCEPTION_UNKNOWN_FWALERT,
883 MCDI_EV_FIELD(eqp, DATA));
887 case MCDI_EVENT_CODE_TX_ERR: {
889 * After a TXQ error is detected, firmware sends a TX_ERR event.
890 * This may be followed by TX completions (which we discard),
891 * and then finally by a TX_FLUSH event. Firmware destroys the
892 * TXQ automatically after sending the TX_FLUSH event.
894 enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
896 EFSYS_PROBE1(tx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
898 /* Inform the driver that a reset is required. */
899 eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
900 MCDI_EV_FIELD(eqp, TX_ERR_DATA));
904 case MCDI_EVENT_CODE_TX_FLUSH: {
905 uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
908 * EF10 firmware sends two TX_FLUSH events: one to the txq's
909 * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
910 * We want to wait for all completions, so ignore the events
911 * with TX_FLUSH_TO_DRIVER.
913 if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
914 should_abort = B_FALSE;
918 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
920 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
922 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
923 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
927 case MCDI_EVENT_CODE_RX_ERR: {
929 * After an RXQ error is detected, firmware sends an RX_ERR
930 * event. This may be followed by RX events (which we discard),
931 * and then finally by an RX_FLUSH event. Firmware destroys the
932 * RXQ automatically after sending the RX_FLUSH event.
934 enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
936 EFSYS_PROBE1(rx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
938 /* Inform the driver that a reset is required. */
939 eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
940 MCDI_EV_FIELD(eqp, RX_ERR_DATA));
944 case MCDI_EVENT_CODE_RX_FLUSH: {
945 uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
948 * EF10 firmware sends two RX_FLUSH events: one to the rxq's
949 * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
950 * We want to wait for all completions, so ignore the events
951 * with RX_FLUSH_TO_DRIVER.
953 if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
954 should_abort = B_FALSE;
958 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
960 EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
962 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
963 should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
968 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
969 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
970 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
974 return (should_abort);
978 hunt_ev_rxlabel_init(
981 __in unsigned int label)
983 efx_evq_rxq_state_t *eersp;
985 EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
986 eersp = &eep->ee_rxq_state[label];
988 EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
990 eersp->eers_rx_read_ptr = 0;
991 eersp->eers_rx_mask = erp->er_mask;
995 hunt_ev_rxlabel_fini(
997 __in unsigned int label)
999 efx_evq_rxq_state_t *eersp;
1001 EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
1002 eersp = &eep->ee_rxq_state[label];
1004 EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
1006 eersp->eers_rx_read_ptr = 0;
1007 eersp->eers_rx_mask = 0;
1010 #endif /* EFSYS_OPT_HUNTINGTON */