LCOV - code coverage report
Current view: top level - drivers/common/sfc_efx/base - ef10_ev.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 275 0.0 %
Date: 2024-01-22 15:35:40 Functions: 0 17 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 177 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *
       3                 :            :  * Copyright(c) 2019-2021 Xilinx, Inc.
       4                 :            :  * Copyright(c) 2012-2019 Solarflare Communications Inc.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "efx.h"
       8                 :            : #include "efx_impl.h"
       9                 :            : #if EFSYS_OPT_MON_STATS
      10                 :            : #include "mcdi_mon.h"
      11                 :            : #endif
      12                 :            : 
      13                 :            : #if EFX_OPTS_EF10()
      14                 :            : 
      15                 :            : /*
      16                 :            :  * Non-interrupting event queue requires interrrupting event queue to
      17                 :            :  * refer to for wake-up events even if wake ups are never used.
      18                 :            :  * It could be even non-allocated event queue.
      19                 :            :  */
      20                 :            : #define EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX  (0)
      21                 :            : 
      22                 :            : static  __checkReturn   boolean_t
      23                 :            : ef10_ev_rx(
      24                 :            :         __in            efx_evq_t *eep,
      25                 :            :         __in            efx_qword_t *eqp,
      26                 :            :         __in            const efx_ev_callbacks_t *eecp,
      27                 :            :         __in_opt        void *arg);
      28                 :            : 
      29                 :            : static  __checkReturn   boolean_t
      30                 :            : ef10_ev_tx(
      31                 :            :         __in            efx_evq_t *eep,
      32                 :            :         __in            efx_qword_t *eqp,
      33                 :            :         __in            const efx_ev_callbacks_t *eecp,
      34                 :            :         __in_opt        void *arg);
      35                 :            : 
      36                 :            : static  __checkReturn   boolean_t
      37                 :            : ef10_ev_driver(
      38                 :            :         __in            efx_evq_t *eep,
      39                 :            :         __in            efx_qword_t *eqp,
      40                 :            :         __in            const efx_ev_callbacks_t *eecp,
      41                 :            :         __in_opt        void *arg);
      42                 :            : 
      43                 :            : static  __checkReturn   boolean_t
      44                 :            : ef10_ev_drv_gen(
      45                 :            :         __in            efx_evq_t *eep,
      46                 :            :         __in            efx_qword_t *eqp,
      47                 :            :         __in            const efx_ev_callbacks_t *eecp,
      48                 :            :         __in_opt        void *arg);
      49                 :            : 
      50                 :            : 
      51                 :            : static  __checkReturn   efx_rc_t
      52                 :          0 : efx_mcdi_set_evq_tmr(
      53                 :            :         __in            efx_nic_t *enp,
      54                 :            :         __in            uint32_t instance,
      55                 :            :         __in            uint32_t mode,
      56                 :            :         __in            uint32_t timer_ns)
      57                 :            : {
      58                 :            :         efx_mcdi_req_t req;
      59                 :            :         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_EVQ_TMR_IN_LEN,
      60                 :            :                 MC_CMD_SET_EVQ_TMR_OUT_LEN);
      61                 :            :         efx_rc_t rc;
      62                 :            : 
      63                 :          0 :         req.emr_cmd = MC_CMD_SET_EVQ_TMR;
      64                 :          0 :         req.emr_in_buf = payload;
      65                 :          0 :         req.emr_in_length = MC_CMD_SET_EVQ_TMR_IN_LEN;
      66                 :          0 :         req.emr_out_buf = payload;
      67                 :          0 :         req.emr_out_length = MC_CMD_SET_EVQ_TMR_OUT_LEN;
      68                 :            : 
      69                 :          0 :         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_INSTANCE, instance);
      70                 :          0 :         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_LOAD_REQ_NS, timer_ns);
      71                 :          0 :         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_RELOAD_REQ_NS, timer_ns);
      72                 :          0 :         MCDI_IN_SET_DWORD(req, SET_EVQ_TMR_IN_TMR_MODE, mode);
      73                 :            : 
      74                 :          0 :         efx_mcdi_execute(enp, &req);
      75                 :            : 
      76         [ #  # ]:          0 :         if (req.emr_rc != 0) {
      77                 :            :                 rc = req.emr_rc;
      78                 :          0 :                 goto fail1;
      79                 :            :         }
      80                 :            : 
      81         [ #  # ]:          0 :         if (req.emr_out_length_used < MC_CMD_SET_EVQ_TMR_OUT_LEN) {
      82                 :            :                 rc = EMSGSIZE;
      83                 :          0 :                 goto fail2;
      84                 :            :         }
      85                 :            : 
      86                 :            :         return (0);
      87                 :            : 
      88                 :            : fail2:
      89                 :            :         EFSYS_PROBE(fail2);
      90                 :            : fail1:
      91                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
      92                 :            : 
      93                 :            :         return (rc);
      94                 :            : }
      95                 :            : 
      96                 :            : 
      97                 :            :         __checkReturn   efx_rc_t
      98                 :          0 : ef10_ev_init(
      99                 :            :         __in            efx_nic_t *enp)
     100                 :            : {
     101                 :            :         _NOTE(ARGUNUSED(enp))
     102                 :          0 :         return (0);
     103                 :            : }
     104                 :            : 
     105                 :            :                         void
     106                 :          0 : ef10_ev_fini(
     107                 :            :         __in            efx_nic_t *enp)
     108                 :            : {
     109                 :            :         _NOTE(ARGUNUSED(enp))
     110                 :          0 : }
     111                 :            : 
     112                 :            :         __checkReturn   efx_rc_t
     113                 :          0 : ef10_ev_qcreate(
     114                 :            :         __in            efx_nic_t *enp,
     115                 :            :         __in            unsigned int index,
     116                 :            :         __in            efsys_mem_t *esmp,
     117                 :            :         __in            size_t ndescs,
     118                 :            :         __in            uint32_t id,
     119                 :            :         __in            uint32_t us,
     120                 :            :         __in            uint32_t flags,
     121                 :            :         __in            uint32_t irq,
     122                 :            :         __in            efx_evq_t *eep)
     123                 :            : {
     124                 :            :         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
     125                 :            :         uint32_t target_evq = 0;
     126                 :            :         efx_rc_t rc;
     127                 :            :         boolean_t low_latency;
     128                 :            : 
     129                 :            :         _NOTE(ARGUNUSED(id))    /* buftbl id managed by MC */
     130                 :            : 
     131         [ #  # ]:          0 :         EFSYS_ASSERT((flags & EFX_EVQ_FLAGS_EXTENDED_WIDTH) == 0);
     132                 :            : 
     133                 :            :         /*
     134                 :            :          * NO_CONT_EV mode is only requested from the firmware when creating
     135                 :            :          * receive queues, but here it needs to be specified at event queue
     136                 :            :          * creation, as the event handler needs to know which format is in use.
     137                 :            :          *
     138                 :            :          * If EFX_EVQ_FLAGS_NO_CONT_EV is specified, all receive queues for this
     139                 :            :          * event queue will be created in NO_CONT_EV mode.
     140                 :            :          *
     141                 :            :          * See SF-109306-TC 5.11 "Events for RXQs in NO_CONT_EV mode".
     142                 :            :          */
     143         [ #  # ]:          0 :         if (flags & EFX_EVQ_FLAGS_NO_CONT_EV) {
     144         [ #  # ]:          0 :                 if (enp->en_nic_cfg.enc_no_cont_ev_mode_supported == B_FALSE) {
     145                 :            :                         rc = EINVAL;
     146                 :          0 :                         goto fail1;
     147                 :            :                 }
     148                 :            :         }
     149                 :            : 
     150                 :            :         /* Set up the handler table */
     151                 :          0 :         eep->ee_rx   = ef10_ev_rx;
     152                 :          0 :         eep->ee_tx   = ef10_ev_tx;
     153                 :          0 :         eep->ee_driver       = ef10_ev_driver;
     154                 :          0 :         eep->ee_drv_gen      = ef10_ev_drv_gen;
     155                 :          0 :         eep->ee_mcdi = ef10_ev_mcdi;
     156                 :            : 
     157                 :            :         /* Set up the event queue */
     158                 :            :         /* INIT_EVQ expects function-relative vector number */
     159         [ #  # ]:          0 :         if ((flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
     160                 :            :             EFX_EVQ_FLAGS_NOTIFY_INTERRUPT) {
     161                 :            :                 /* IRQ number is specified by caller */
     162         [ #  # ]:          0 :         } else if (index == EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX) {
     163                 :            :                 /* Use the first interrupt for always interrupting EvQ */
     164                 :            :                 irq = 0;
     165                 :          0 :                 flags = (flags & ~EFX_EVQ_FLAGS_NOTIFY_MASK) |
     166                 :            :                     EFX_EVQ_FLAGS_NOTIFY_INTERRUPT;
     167                 :            :         } else {
     168                 :            :                 target_evq = EFX_EF10_ALWAYS_INTERRUPTING_EVQ_INDEX;
     169                 :            :         }
     170                 :            : 
     171                 :            :         /*
     172                 :            :          * Interrupts may be raised for events immediately after the queue is
     173                 :            :          * created. See bug58606.
     174                 :            :          */
     175                 :            : 
     176                 :            :         /*
     177                 :            :          * On Huntington we need to specify the settings to use.
     178                 :            :          * If event queue type in flags is auto, we favour throughput
     179                 :            :          * if the adapter is running virtualization supporting firmware
     180                 :            :          * (i.e. the full featured firmware variant)
     181                 :            :          * and latency otherwise. The Ethernet Virtual Bridging
     182                 :            :          * capability is used to make this decision. (Note though that
     183                 :            :          * the low latency firmware variant is also best for
     184                 :            :          * throughput and corresponding type should be specified
     185                 :            :          * to choose it.)
     186                 :            :          *
     187                 :            :          * If FW supports EvQ types (e.g. on Medford and Medford2) the
     188                 :            :          * type which is specified in flags is passed to FW to make the
     189                 :            :          * decision and low_latency hint is ignored.
     190                 :            :          */
     191                 :          0 :         low_latency = encp->enc_datapath_cap_evb ? 0 : 1;
     192                 :          0 :         rc = efx_mcdi_init_evq(enp, index, esmp, ndescs, irq, target_evq, us,
     193                 :            :             flags, low_latency);
     194         [ #  # ]:          0 :         if (rc != 0)
     195                 :          0 :                 goto fail2;
     196                 :            : 
     197                 :            :         return (0);
     198                 :            : 
     199                 :            : fail2:
     200                 :            :         EFSYS_PROBE(fail2);
     201                 :            : fail1:
     202                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     203                 :            : 
     204                 :            :         return (rc);
     205                 :            : }
     206                 :            : 
     207                 :            :                         void
     208                 :          0 : ef10_ev_qdestroy(
     209                 :            :         __in            efx_evq_t *eep)
     210                 :            : {
     211                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     212                 :            : 
     213         [ #  # ]:          0 :         EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
     214                 :            : 
     215                 :          0 :         (void) efx_mcdi_fini_evq(enp, eep->ee_index);
     216                 :          0 : }
     217                 :            : 
     218                 :            :         __checkReturn   efx_rc_t
     219                 :          0 : ef10_ev_qprime(
     220                 :            :         __in            efx_evq_t *eep,
     221                 :            :         __in            unsigned int count)
     222                 :            : {
     223                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     224                 :            :         uint32_t rptr;
     225                 :            :         efx_dword_t dword;
     226                 :            : 
     227                 :          0 :         rptr = count & eep->ee_mask;
     228                 :            : 
     229         [ #  # ]:          0 :         if (enp->en_nic_cfg.enc_bug35388_workaround) {
     230                 :            :                 EFX_STATIC_ASSERT(EF10_EVQ_MINNEVS >
     231                 :            :                     (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
     232                 :            :                 EFX_STATIC_ASSERT(EF10_EVQ_MAXNEVS <
     233                 :            :                     (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
     234                 :            : 
     235                 :          0 :                 EFX_POPULATE_DWORD_2(dword,
     236                 :            :                     ERF_DD_EVQ_IND_RPTR_FLAGS,
     237                 :            :                     EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
     238                 :            :                     ERF_DD_EVQ_IND_RPTR,
     239                 :            :                     (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
     240   [ #  #  #  #  :          0 :                 EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
             #  #  #  # ]
     241                 :            :                     &dword, B_FALSE);
     242                 :            : 
     243                 :          0 :                 EFX_POPULATE_DWORD_2(dword,
     244                 :            :                     ERF_DD_EVQ_IND_RPTR_FLAGS,
     245                 :            :                     EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
     246                 :            :                     ERF_DD_EVQ_IND_RPTR,
     247                 :            :                     rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
     248   [ #  #  #  #  :          0 :                 EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
             #  #  #  # ]
     249                 :            :                     &dword, B_FALSE);
     250                 :            :         } else {
     251                 :            :                 EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
     252   [ #  #  #  #  :          0 :                 EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
                   #  # ]
     253                 :            :                     &dword, B_FALSE);
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         return (0);
     257                 :            : }
     258                 :            : 
     259                 :            : static  __checkReturn   efx_rc_t
     260                 :          0 : efx_mcdi_driver_event(
     261                 :            :         __in            efx_nic_t *enp,
     262                 :            :         __in            uint32_t evq,
     263                 :            :         __in            efx_qword_t data)
     264                 :            : {
     265                 :            :         efx_mcdi_req_t req;
     266                 :            :         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_DRIVER_EVENT_IN_LEN,
     267                 :            :                 MC_CMD_DRIVER_EVENT_OUT_LEN);
     268                 :            :         efx_rc_t rc;
     269                 :            : 
     270                 :          0 :         req.emr_cmd = MC_CMD_DRIVER_EVENT;
     271                 :          0 :         req.emr_in_buf = payload;
     272                 :          0 :         req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
     273                 :          0 :         req.emr_out_buf = payload;
     274                 :          0 :         req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
     275                 :            : 
     276                 :          0 :         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
     277                 :            : 
     278                 :          0 :         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
     279                 :            :             EFX_QWORD_FIELD(data, EFX_DWORD_0));
     280                 :          0 :         MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
     281                 :            :             EFX_QWORD_FIELD(data, EFX_DWORD_1));
     282                 :            : 
     283                 :          0 :         efx_mcdi_execute(enp, &req);
     284                 :            : 
     285         [ #  # ]:          0 :         if (req.emr_rc != 0) {
     286                 :            :                 rc = req.emr_rc;
     287                 :          0 :                 goto fail1;
     288                 :            :         }
     289                 :            : 
     290                 :            :         return (0);
     291                 :            : 
     292                 :            : fail1:
     293                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     294                 :            : 
     295                 :          0 :         return (rc);
     296                 :            : }
     297                 :            : 
     298                 :            :                         void
     299                 :          0 : ef10_ev_qpost(
     300                 :            :         __in    efx_evq_t *eep,
     301                 :            :         __in    uint16_t data)
     302                 :            : {
     303                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     304                 :            :         efx_qword_t event;
     305                 :            : 
     306                 :          0 :         EFX_POPULATE_QWORD_3(event,
     307                 :            :             ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
     308                 :            :             ESF_DZ_DRV_SUB_CODE, 0,
     309                 :            :             ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
     310                 :            : 
     311                 :          0 :         (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
     312                 :          0 : }
     313                 :            : 
     314                 :            :         __checkReturn   efx_rc_t
     315                 :          0 : ef10_ev_qmoderate(
     316                 :            :         __in            efx_evq_t *eep,
     317                 :            :         __in            unsigned int us)
     318                 :            : {
     319                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     320                 :            :         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
     321                 :            :         efx_dword_t dword;
     322                 :            :         uint32_t mode;
     323                 :            :         efx_rc_t rc;
     324                 :            : 
     325                 :            :         /* Check that hardware and MCDI use the same timer MODE values */
     326                 :            :         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_DIS ==
     327                 :            :             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_DIS);
     328                 :            :         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_IMMED_START ==
     329                 :            :             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_IMMED_START);
     330                 :            :         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_TRIG_START ==
     331                 :            :             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_TRIG_START);
     332                 :            :         EFX_STATIC_ASSERT(FFE_CZ_TIMER_MODE_INT_HLDOFF ==
     333                 :            :             MC_CMD_SET_EVQ_TMR_IN_TIMER_MODE_INT_HLDOFF);
     334                 :            : 
     335         [ #  # ]:          0 :         if (us > encp->enc_evq_timer_max_us) {
     336                 :            :                 rc = EINVAL;
     337                 :          0 :                 goto fail1;
     338                 :            :         }
     339                 :            : 
     340                 :            :         /* If the value is zero then disable the timer */
     341         [ #  # ]:          0 :         if (us == 0) {
     342                 :            :                 mode = FFE_CZ_TIMER_MODE_DIS;
     343                 :            :         } else {
     344                 :            :                 mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
     345                 :            :         }
     346                 :            : 
     347         [ #  # ]:          0 :         if (encp->enc_bug61265_workaround) {
     348                 :          0 :                 uint32_t ns = us * 1000;
     349                 :            : 
     350                 :          0 :                 rc = efx_mcdi_set_evq_tmr(enp, eep->ee_index, mode, ns);
     351         [ #  # ]:          0 :                 if (rc != 0)
     352                 :          0 :                         goto fail2;
     353                 :            :         } else {
     354                 :            :                 unsigned int ticks;
     355                 :            : 
     356         [ #  # ]:          0 :                 if ((rc = efx_ev_usecs_to_ticks(enp, us, &ticks)) != 0)
     357                 :          0 :                         goto fail3;
     358                 :            : 
     359         [ #  # ]:          0 :                 if (encp->enc_bug35388_workaround) {
     360                 :          0 :                         EFX_POPULATE_DWORD_3(dword,
     361                 :            :                             ERF_DD_EVQ_IND_TIMER_FLAGS,
     362                 :            :                             EFE_DD_EVQ_IND_TIMER_FLAGS,
     363                 :            :                             ERF_DD_EVQ_IND_TIMER_MODE, mode,
     364                 :            :                             ERF_DD_EVQ_IND_TIMER_VAL, ticks);
     365   [ #  #  #  #  :          0 :                         EFX_BAR_VI_WRITED(enp, ER_DD_EVQ_INDIRECT,
             #  #  #  # ]
     366                 :            :                             eep->ee_index, &dword, 0);
     367                 :            :                 } else {
     368                 :            :                         /*
     369                 :            :                          * NOTE: The TMR_REL field introduced in Medford2 is
     370                 :            :                          * ignored on earlier EF10 controllers. See bug66418
     371                 :            :                          * comment 9 for details.
     372                 :            :                          */
     373                 :          0 :                         EFX_POPULATE_DWORD_3(dword,
     374                 :            :                             ERF_DZ_TC_TIMER_MODE, mode,
     375                 :            :                             ERF_DZ_TC_TIMER_VAL, ticks,
     376                 :            :                             ERF_FZ_TC_TMR_REL_VAL, ticks);
     377   [ #  #  #  #  :          0 :                         EFX_BAR_VI_WRITED(enp, ER_DZ_EVQ_TMR_REG,
                   #  # ]
     378                 :            :                             eep->ee_index, &dword, 0);
     379                 :            :                 }
     380                 :            :         }
     381                 :            : 
     382                 :            :         return (0);
     383                 :            : 
     384                 :            : fail3:
     385                 :            :         EFSYS_PROBE(fail3);
     386                 :            : fail2:
     387                 :            :         EFSYS_PROBE(fail2);
     388                 :            : fail1:
     389                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     390                 :            : 
     391                 :            :         return (rc);
     392                 :            : }
     393                 :            : 
     394                 :            : 
     395                 :            : #if EFSYS_OPT_QSTATS
     396                 :            :                         void
     397                 :            : ef10_ev_qstats_update(
     398                 :            :         __in                            efx_evq_t *eep,
     399                 :            :         __inout_ecount(EV_NQSTATS)      efsys_stat_t *stat)
     400                 :            : {
     401                 :            :         unsigned int id;
     402                 :            : 
     403                 :            :         for (id = 0; id < EV_NQSTATS; id++) {
     404                 :            :                 efsys_stat_t *essp = &stat[id];
     405                 :            : 
     406                 :            :                 EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
     407                 :            :                 eep->ee_stat[id] = 0;
     408                 :            :         }
     409                 :            : }
     410                 :            : #endif /* EFSYS_OPT_QSTATS */
     411                 :            : 
     412                 :            : #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
     413                 :            : 
     414                 :            : static  __checkReturn   boolean_t
     415                 :          0 : ef10_ev_rx_packed_stream(
     416                 :            :         __in            efx_evq_t *eep,
     417                 :            :         __in            efx_qword_t *eqp,
     418                 :            :         __in            const efx_ev_callbacks_t *eecp,
     419                 :            :         __in_opt        void *arg)
     420                 :            : {
     421                 :            :         uint32_t label;
     422                 :            :         uint32_t pkt_count_lbits;
     423                 :            :         uint16_t flags;
     424                 :            :         boolean_t should_abort;
     425                 :            :         efx_evq_rxq_state_t *eersp;
     426                 :            :         unsigned int pkt_count;
     427                 :            :         unsigned int current_id;
     428                 :            :         boolean_t new_buffer;
     429                 :            : 
     430                 :          0 :         pkt_count_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
     431                 :          0 :         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
     432                 :          0 :         new_buffer = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_ROTATE);
     433                 :            : 
     434                 :            :         flags = 0;
     435                 :            : 
     436                 :            :         eersp = &eep->ee_rxq_state[label];
     437                 :            : 
     438                 :            :         /*
     439                 :            :          * RX_DSC_PTR_LBITS has least significant bits of the global
     440                 :            :          * (not per-buffer) packet counter. It is guaranteed that
     441                 :            :          * maximum number of completed packets fits in lbits-mask.
     442                 :            :          * So, modulo lbits-mask arithmetic should be used to calculate
     443                 :            :          * packet counter increment.
     444                 :            :          */
     445                 :          0 :         pkt_count = (pkt_count_lbits - eersp->eers_rx_stream_npackets) &
     446                 :            :             EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
     447                 :          0 :         eersp->eers_rx_stream_npackets += pkt_count;
     448                 :            : 
     449         [ #  # ]:          0 :         if (new_buffer) {
     450                 :            :                 flags |= EFX_PKT_PACKED_STREAM_NEW_BUFFER;
     451                 :            : #if EFSYS_OPT_RX_PACKED_STREAM
     452                 :            :                 /*
     453                 :            :                  * If both packed stream and equal stride super-buffer
     454                 :            :                  * modes are compiled in, in theory credits should be
     455                 :            :                  * be maintained for packed stream only, but right now
     456                 :            :                  * these modes are not distinguished in the event queue
     457                 :            :                  * Rx queue state and it is OK to increment the counter
     458                 :            :                  * regardless (it might be event cheaper than branching
     459                 :            :                  * since neighbour structure member are updated as well).
     460                 :            :                  */
     461                 :            :                 eersp->eers_rx_packed_stream_credits++;
     462                 :            : #endif
     463                 :          0 :                 eersp->eers_rx_read_ptr++;
     464                 :            :         }
     465                 :          0 :         current_id = eersp->eers_rx_read_ptr & eersp->eers_rx_mask;
     466                 :            : 
     467                 :            :         /* Check for errors that invalidate checksum and L3/L4 fields */
     468         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TRUNC_ERR) != 0) {
     469                 :            :                 /* RX frame truncated */
     470                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
     471                 :          0 :                 flags |= EFX_DISCARD;
     472                 :          0 :                 goto deliver;
     473                 :            :         }
     474         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
     475                 :            :                 /* Bad Ethernet frame CRC */
     476                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
     477                 :          0 :                 flags |= EFX_DISCARD;
     478                 :          0 :                 goto deliver;
     479                 :            :         }
     480                 :            : 
     481         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {
     482                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_PARSE_INCOMPLETE);
     483                 :          0 :                 flags |= EFX_PKT_PACKED_STREAM_PARSE_INCOMPLETE;
     484                 :          0 :                 goto deliver;
     485                 :            :         }
     486                 :            : 
     487                 :            :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR))
     488                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
     489                 :            : 
     490                 :            :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR))
     491                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
     492                 :            : 
     493                 :          0 : deliver:
     494                 :            :         /* If we're not discarding the packet then it is ok */
     495                 :            :         if (~flags & EFX_DISCARD)
     496                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
     497                 :            : 
     498         [ #  # ]:          0 :         EFSYS_ASSERT(eecp->eec_rx_ps != NULL);
     499                 :          0 :         should_abort = eecp->eec_rx_ps(arg, label, current_id, pkt_count,
     500                 :            :             flags);
     501                 :            : 
     502                 :          0 :         return (should_abort);
     503                 :            : }
     504                 :            : 
     505                 :            : #endif /* EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER */
     506                 :            : 
     507                 :            : static  __checkReturn   boolean_t
     508                 :          0 : ef10_ev_rx(
     509                 :            :         __in            efx_evq_t *eep,
     510                 :            :         __in            efx_qword_t *eqp,
     511                 :            :         __in            const efx_ev_callbacks_t *eecp,
     512                 :            :         __in_opt        void *arg)
     513                 :            : {
     514                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     515                 :            :         uint32_t size;
     516                 :            :         uint32_t label;
     517                 :            :         uint32_t mac_class;
     518                 :            :         uint32_t eth_tag_class;
     519                 :            :         uint32_t l3_class;
     520                 :            :         uint32_t l4_class;
     521                 :            :         uint32_t next_read_lbits;
     522                 :            :         uint16_t flags;
     523                 :            :         boolean_t cont;
     524                 :            :         boolean_t should_abort;
     525                 :            :         efx_evq_rxq_state_t *eersp;
     526                 :            :         unsigned int desc_count;
     527                 :            :         unsigned int last_used_id;
     528                 :            : 
     529                 :            :         EFX_EV_QSTAT_INCR(eep, EV_RX);
     530                 :            : 
     531                 :            :         /* Discard events after RXQ/TXQ errors, or hardware not available */
     532         [ #  # ]:          0 :         if (enp->en_reset_flags &
     533                 :            :             (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
     534                 :            :                 return (B_FALSE);
     535                 :            : 
     536                 :            :         /* Basic packet information */
     537                 :          0 :         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
     538                 :            :         eersp = &eep->ee_rxq_state[label];
     539                 :            : 
     540                 :            : #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
     541                 :            :         /*
     542                 :            :          * Packed stream events are very different,
     543                 :            :          * so handle them separately
     544                 :            :          */
     545         [ #  # ]:          0 :         if (eersp->eers_rx_packed_stream)
     546                 :          0 :                 return (ef10_ev_rx_packed_stream(eep, eqp, eecp, arg));
     547                 :            : #endif
     548                 :            : 
     549                 :          0 :         size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
     550                 :          0 :         cont = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT);
     551                 :          0 :         next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
     552                 :          0 :         eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
     553                 :          0 :         mac_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
     554                 :          0 :         l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
     555                 :            : 
     556                 :            :         /*
     557                 :            :          * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is only
     558                 :            :          * 2 bits wide on Medford2. Check it is safe to use the Medford2 field
     559                 :            :          * and values for all EF10 controllers.
     560                 :            :          */
     561                 :            :         EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN == ESF_DE_RX_L4_CLASS_LBN);
     562                 :            :         EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
     563                 :            :         EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
     564                 :            :         EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN == ESE_DE_L4_CLASS_UNKNOWN);
     565                 :            : 
     566                 :          0 :         l4_class = EFX_QWORD_FIELD(*eqp, ESF_FZ_RX_L4_CLASS);
     567                 :            : 
     568         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
     569                 :            :                 /* Drop this event */
     570                 :            :                 return (B_FALSE);
     571                 :            :         }
     572                 :            :         flags = 0;
     573                 :            : 
     574         [ #  # ]:          0 :         if (cont != 0) {
     575                 :            :                 /*
     576                 :            :                  * This may be part of a scattered frame, or it may be a
     577                 :            :                  * truncated frame if scatter is disabled on this RXQ.
     578                 :            :                  * Overlength frames can be received if e.g. a VF is configured
     579                 :            :                  * for 1500 MTU but connected to a port set to 9000 MTU
     580                 :            :                  * (see bug56567).
     581                 :            :                  * FIXME: There is not yet any driver that supports scatter on
     582                 :            :                  * Huntington.  Scatter support is required for OSX.
     583                 :            :                  */
     584                 :            :                 flags |= EFX_PKT_CONT;
     585                 :            :         }
     586                 :            : 
     587         [ #  # ]:          0 :         if (mac_class == ESE_DZ_MAC_CLASS_UCAST)
     588                 :          0 :                 flags |= EFX_PKT_UNICAST;
     589                 :            : 
     590                 :            :         /*
     591                 :            :          * Increment the count of descriptors read.
     592                 :            :          *
     593                 :            :          * In NO_CONT_EV mode, RX_DSC_PTR_LBITS is actually a packet count, but
     594                 :            :          * when scatter is disabled, there is only one descriptor per packet and
     595                 :            :          * so it can be treated the same.
     596                 :            :          *
     597                 :            :          * TODO: Support scatter in NO_CONT_EV mode.
     598                 :            :          */
     599                 :          0 :         desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
     600                 :            :             EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
     601                 :          0 :         eersp->eers_rx_read_ptr += desc_count;
     602                 :            : 
     603                 :            :         /* Calculate the index of the last descriptor consumed */
     604                 :          0 :         last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
     605                 :            : 
     606         [ #  # ]:          0 :         if (eep->ee_flags & EFX_EVQ_FLAGS_NO_CONT_EV) {
     607                 :            :                 if (desc_count > 1)
     608                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
     609                 :            : 
     610                 :            :                 /* Always read the length from the prefix in NO_CONT_EV mode. */
     611                 :          0 :                 flags |= EFX_PKT_PREFIX_LEN;
     612                 :            : 
     613                 :            :                 /*
     614                 :            :                  * Check for an aborted scatter, signalled by the ABORT bit in
     615                 :            :                  * NO_CONT_EV mode. The ABORT bit was not used before NO_CONT_EV
     616                 :            :                  * mode was added as it was broken in Huntington silicon.
     617                 :            :                  */
     618         [ #  # ]:          0 :                 if (EFX_QWORD_FIELD(*eqp, ESF_EZ_RX_ABORT) != 0) {
     619                 :          0 :                         flags |= EFX_DISCARD;
     620                 :          0 :                         goto deliver;
     621                 :            :                 }
     622         [ #  # ]:          0 :         } else if (desc_count > 1) {
     623                 :            :                 /*
     624                 :            :                  * FIXME: add error checking to make sure this a batched event.
     625                 :            :                  * This could also be an aborted scatter, see Bug36629.
     626                 :            :                  */
     627                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
     628                 :          0 :                 flags |= EFX_PKT_PREFIX_LEN;
     629                 :            :         }
     630                 :            : 
     631                 :            :         /* Check for errors that invalidate checksum and L3/L4 fields */
     632         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TRUNC_ERR) != 0) {
     633                 :            :                 /* RX frame truncated */
     634                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC);
     635                 :          0 :                 flags |= EFX_DISCARD;
     636                 :          0 :                 goto deliver;
     637                 :            :         }
     638         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
     639                 :            :                 /* Bad Ethernet frame CRC */
     640                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR);
     641                 :          0 :                 flags |= EFX_DISCARD;
     642                 :          0 :                 goto deliver;
     643                 :            :         }
     644         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE)) {
     645                 :            :                 /*
     646                 :            :                  * Hardware parse failed, due to malformed headers
     647                 :            :                  * or headers that are too long for the parser.
     648                 :            :                  * Headers and checksums must be validated by the host.
     649                 :            :                  */
     650                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_PARSE_INCOMPLETE);
     651                 :          0 :                 goto deliver;
     652                 :            :         }
     653                 :            : 
     654         [ #  # ]:          0 :         if ((eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN1) ||
     655                 :            :             (eth_tag_class == ESE_DZ_ETH_TAG_CLASS_VLAN2)) {
     656                 :          0 :                 flags |= EFX_PKT_VLAN_TAGGED;
     657                 :            :         }
     658                 :            : 
     659      [ #  #  # ]:          0 :         switch (l3_class) {
     660                 :          0 :         case ESE_DZ_L3_CLASS_IP4:
     661                 :            :         case ESE_DZ_L3_CLASS_IP4_FRAG:
     662                 :          0 :                 flags |= EFX_PKT_IPV4;
     663         [ #  # ]:          0 :                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR)) {
     664                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR);
     665                 :            :                 } else {
     666                 :          0 :                         flags |= EFX_CKSUM_IPV4;
     667                 :            :                 }
     668                 :            : 
     669                 :            :                 /*
     670                 :            :                  * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is
     671                 :            :                  * only 2 bits wide on Medford2. Check it is safe to use the
     672                 :            :                  * Medford2 field and values for all EF10 controllers.
     673                 :            :                  */
     674                 :            :                 EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN ==
     675                 :            :                     ESF_DE_RX_L4_CLASS_LBN);
     676                 :            :                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
     677                 :            :                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
     678                 :            :                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN ==
     679                 :            :                     ESE_DE_L4_CLASS_UNKNOWN);
     680                 :            : 
     681         [ #  # ]:          0 :                 if (l4_class == ESE_FZ_L4_CLASS_TCP) {
     682                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4);
     683                 :          0 :                         flags |= EFX_PKT_TCP;
     684         [ #  # ]:          0 :                 } else if (l4_class == ESE_FZ_L4_CLASS_UDP) {
     685                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4);
     686                 :          0 :                         flags |= EFX_PKT_UDP;
     687                 :            :                 } else {
     688                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4);
     689                 :            :                 }
     690                 :            :                 break;
     691                 :            : 
     692                 :          0 :         case ESE_DZ_L3_CLASS_IP6:
     693                 :            :         case ESE_DZ_L3_CLASS_IP6_FRAG:
     694                 :          0 :                 flags |= EFX_PKT_IPV6;
     695                 :            : 
     696                 :            :                 /*
     697                 :            :                  * RX_L4_CLASS is 3 bits wide on Huntington and Medford, but is
     698                 :            :                  * only 2 bits wide on Medford2. Check it is safe to use the
     699                 :            :                  * Medford2 field and values for all EF10 controllers.
     700                 :            :                  */
     701                 :            :                 EFX_STATIC_ASSERT(ESF_FZ_RX_L4_CLASS_LBN ==
     702                 :            :                     ESF_DE_RX_L4_CLASS_LBN);
     703                 :            :                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_TCP == ESE_DE_L4_CLASS_TCP);
     704                 :            :                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UDP == ESE_DE_L4_CLASS_UDP);
     705                 :            :                 EFX_STATIC_ASSERT(ESE_FZ_L4_CLASS_UNKNOWN ==
     706                 :            :                     ESE_DE_L4_CLASS_UNKNOWN);
     707                 :            : 
     708         [ #  # ]:          0 :                 if (l4_class == ESE_FZ_L4_CLASS_TCP) {
     709                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6);
     710                 :          0 :                         flags |= EFX_PKT_TCP;
     711         [ #  # ]:          0 :                 } else if (l4_class == ESE_FZ_L4_CLASS_UDP) {
     712                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6);
     713                 :          0 :                         flags |= EFX_PKT_UDP;
     714                 :            :                 } else {
     715                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6);
     716                 :            :                 }
     717                 :            :                 break;
     718                 :            : 
     719                 :            :         default:
     720                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP);
     721                 :            :                 break;
     722                 :            :         }
     723                 :            : 
     724         [ #  # ]:          0 :         if (flags & (EFX_PKT_TCP | EFX_PKT_UDP)) {
     725         [ #  # ]:          0 :                 if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR)) {
     726                 :            :                         EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR);
     727                 :            :                 } else {
     728                 :          0 :                         flags |= EFX_CKSUM_TCPUDP;
     729                 :            :                 }
     730                 :            :         }
     731                 :            : 
     732                 :          0 : deliver:
     733                 :            :         /* If we're not discarding the packet then it is ok */
     734                 :            :         if (~flags & EFX_DISCARD)
     735                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
     736                 :            : 
     737         [ #  # ]:          0 :         EFSYS_ASSERT(eecp->eec_rx != NULL);
     738                 :          0 :         should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
     739                 :            : 
     740                 :          0 :         return (should_abort);
     741                 :            : }
     742                 :            : 
     743                 :            : static  __checkReturn   boolean_t
     744                 :          0 : ef10_ev_tx(
     745                 :            :         __in            efx_evq_t *eep,
     746                 :            :         __in            efx_qword_t *eqp,
     747                 :            :         __in            const efx_ev_callbacks_t *eecp,
     748                 :            :         __in_opt        void *arg)
     749                 :            : {
     750                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     751                 :            :         uint32_t id;
     752                 :            :         uint32_t label;
     753                 :            :         boolean_t should_abort;
     754                 :            : 
     755                 :            :         EFX_EV_QSTAT_INCR(eep, EV_TX);
     756                 :            : 
     757                 :            :         /* Discard events after RXQ/TXQ errors, or hardware not available */
     758         [ #  # ]:          0 :         if (enp->en_reset_flags &
     759                 :            :             (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR | EFX_RESET_HW_UNAVAIL))
     760                 :            :                 return (B_FALSE);
     761                 :            : 
     762         [ #  # ]:          0 :         if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
     763                 :            :                 /* Drop this event */
     764                 :            :                 return (B_FALSE);
     765                 :            :         }
     766                 :            : 
     767                 :            :         /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
     768                 :          0 :         id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
     769                 :          0 :         label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
     770                 :            : 
     771                 :            :         EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
     772                 :            : 
     773         [ #  # ]:          0 :         EFSYS_ASSERT(eecp->eec_tx != NULL);
     774                 :          0 :         should_abort = eecp->eec_tx(arg, label, id);
     775                 :            : 
     776                 :          0 :         return (should_abort);
     777                 :            : }
     778                 :            : 
     779                 :            : static  __checkReturn   boolean_t
     780                 :          0 : ef10_ev_driver(
     781                 :            :         __in            efx_evq_t *eep,
     782                 :            :         __in            efx_qword_t *eqp,
     783                 :            :         __in            const efx_ev_callbacks_t *eecp,
     784                 :            :         __in_opt        void *arg)
     785                 :            : {
     786                 :            :         unsigned int code;
     787                 :            :         boolean_t should_abort;
     788                 :            : 
     789                 :            :         EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
     790                 :            :         should_abort = B_FALSE;
     791                 :            : 
     792                 :          0 :         code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
     793   [ #  #  #  # ]:          0 :         switch (code) {
     794                 :          0 :         case ESE_DZ_DRV_TIMER_EV: {
     795                 :            :                 uint32_t id;
     796                 :            : 
     797                 :          0 :                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
     798                 :            : 
     799         [ #  # ]:          0 :                 EFSYS_ASSERT(eecp->eec_timer != NULL);
     800                 :          0 :                 should_abort = eecp->eec_timer(arg, id);
     801                 :          0 :                 break;
     802                 :            :         }
     803                 :            : 
     804                 :          0 :         case ESE_DZ_DRV_WAKE_UP_EV: {
     805                 :            :                 uint32_t id;
     806                 :            : 
     807                 :          0 :                 id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
     808                 :            : 
     809         [ #  # ]:          0 :                 EFSYS_ASSERT(eecp->eec_wake_up != NULL);
     810                 :          0 :                 should_abort = eecp->eec_wake_up(arg, id);
     811                 :          0 :                 break;
     812                 :            :         }
     813                 :            : 
     814                 :          0 :         case ESE_DZ_DRV_START_UP_EV:
     815         [ #  # ]:          0 :                 EFSYS_ASSERT(eecp->eec_initialized != NULL);
     816                 :          0 :                 should_abort = eecp->eec_initialized(arg);
     817                 :          0 :                 break;
     818                 :            : 
     819                 :            :         default:
     820                 :            :                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
     821                 :            :                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
     822                 :            :                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
     823                 :            :                 break;
     824                 :            :         }
     825                 :            : 
     826                 :          0 :         return (should_abort);
     827                 :            : }
     828                 :            : 
     829                 :            : static  __checkReturn   boolean_t
     830                 :          0 : ef10_ev_drv_gen(
     831                 :            :         __in            efx_evq_t *eep,
     832                 :            :         __in            efx_qword_t *eqp,
     833                 :            :         __in            const efx_ev_callbacks_t *eecp,
     834                 :            :         __in_opt        void *arg)
     835                 :            : {
     836                 :            :         uint32_t data;
     837                 :            :         boolean_t should_abort;
     838                 :            : 
     839                 :            :         EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
     840                 :            :         should_abort = B_FALSE;
     841                 :            : 
     842                 :          0 :         data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
     843         [ #  # ]:          0 :         if (data >= ((uint32_t)1 << 16)) {
     844                 :            :                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
     845                 :            :                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
     846                 :            :                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
     847                 :            : 
     848                 :            :                 return (B_TRUE);
     849                 :            :         }
     850                 :            : 
     851         [ #  # ]:          0 :         EFSYS_ASSERT(eecp->eec_software != NULL);
     852                 :          0 :         should_abort = eecp->eec_software(arg, (uint16_t)data);
     853                 :            : 
     854                 :          0 :         return (should_abort);
     855                 :            : }
     856                 :            : 
     857                 :            : #endif  /* EFX_OPTS_EF10() */
     858                 :            : 
     859                 :            : #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
     860                 :            : 
     861                 :            :         __checkReturn   boolean_t
     862                 :          0 : ef10_ev_mcdi(
     863                 :            :         __in            efx_evq_t *eep,
     864                 :            :         __in            efx_qword_t *eqp,
     865                 :            :         __in            const efx_ev_callbacks_t *eecp,
     866                 :            :         __in_opt        void *arg)
     867                 :            : {
     868                 :          0 :         efx_nic_t *enp = eep->ee_enp;
     869                 :            :         unsigned int code;
     870                 :            :         boolean_t should_abort = B_FALSE;
     871                 :            :         boolean_t ev_is_v2 = B_FALSE;
     872                 :            : 
     873                 :            :         EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
     874                 :            : 
     875                 :          0 :         code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
     876   [ #  #  #  #  :          0 :         switch (code) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     877                 :          0 :         case MCDI_EVENT_CODE_BADSSERT:
     878                 :          0 :                 efx_mcdi_ev_death(enp, EINTR);
     879                 :          0 :                 break;
     880                 :            : 
     881                 :          0 :         case MCDI_EVENT_CODE_CMDDONE:
     882                 :          0 :                 efx_mcdi_ev_cpl(enp,
     883                 :          0 :                     MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
     884                 :          0 :                     MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
     885                 :          0 :                     MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
     886                 :          0 :                 break;
     887                 :            : 
     888                 :            : #if EFSYS_OPT_MCDI_PROXY_AUTH
     889                 :          0 :         case MCDI_EVENT_CODE_PROXY_RESPONSE:
     890                 :            :                 /*
     891                 :            :                  * This event notifies a function that an authorization request
     892                 :            :                  * has been processed. If the request was authorized then the
     893                 :            :                  * function can now re-send the original MCDI request.
     894                 :            :                  * See SF-113652-SW "SR-IOV Proxied Network Access Control".
     895                 :            :                  */
     896                 :          0 :                 efx_mcdi_ev_proxy_response(enp,
     897                 :            :                     MCDI_EV_FIELD(eqp, PROXY_RESPONSE_HANDLE),
     898                 :          0 :                     MCDI_EV_FIELD(eqp, PROXY_RESPONSE_RC));
     899                 :          0 :                 break;
     900                 :            : #endif /* EFSYS_OPT_MCDI_PROXY_AUTH */
     901                 :            : 
     902                 :            : #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
     903                 :            :         case MCDI_EVENT_CODE_PROXY_REQUEST:
     904                 :            :                 efx_mcdi_ev_proxy_request(enp,
     905                 :            :                         MCDI_EV_FIELD(eqp, PROXY_REQUEST_BUFF_INDEX));
     906                 :            :                 break;
     907                 :            : #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
     908                 :            : 
     909                 :          0 :         case MCDI_EVENT_CODE_LINKCHANGE_V2:
     910                 :            :                 ev_is_v2 = B_TRUE;
     911                 :            :                 /* Fallthrough */
     912                 :          0 :         case MCDI_EVENT_CODE_LINKCHANGE: {
     913                 :            :                 efx_link_mode_t link_mode;
     914                 :            : 
     915                 :          0 :                 ef10_phy_link_ev(enp, eqp, ev_is_v2, &link_mode);
     916                 :          0 :                 should_abort = eecp->eec_link_change(arg, link_mode);
     917                 :            :                 break;
     918                 :            :         }
     919                 :            : 
     920                 :            :         case MCDI_EVENT_CODE_SENSOREVT: {
     921                 :            : #if EFSYS_OPT_MON_STATS
     922                 :            :                 efx_mon_stat_t id;
     923                 :            :                 efx_mon_stat_value_t value;
     924                 :            :                 efx_rc_t rc;
     925                 :            : 
     926                 :            :                 /* Decode monitor stat for MCDI sensor (if supported) */
     927                 :            :                 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
     928                 :            :                         /* Report monitor stat change */
     929                 :            :                         should_abort = eecp->eec_monitor(arg, id, value);
     930                 :            :                 } else if (rc == ENOTSUP) {
     931                 :            :                         should_abort = eecp->eec_exception(arg,
     932                 :            :                                 EFX_EXCEPTION_UNKNOWN_SENSOREVT,
     933                 :            :                                 MCDI_EV_FIELD(eqp, DATA));
     934                 :            :                 } else {
     935                 :            :                         EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
     936                 :            :                 }
     937                 :            : #endif
     938                 :            :                 break;
     939                 :            :         }
     940                 :            : 
     941                 :            :         case MCDI_EVENT_CODE_SCHEDERR:
     942                 :            :                 /* Informational only */
     943                 :            :                 break;
     944                 :            : 
     945                 :          0 :         case MCDI_EVENT_CODE_REBOOT:
     946                 :            :                 /* Falcon/Siena only (should not been seen with Huntington). */
     947                 :          0 :                 efx_mcdi_ev_death(enp, EIO);
     948                 :          0 :                 break;
     949                 :            : 
     950                 :          0 :         case MCDI_EVENT_CODE_MC_REBOOT:
     951                 :            :                 /* MC_REBOOT event is used for Huntington (EF10) and later. */
     952                 :          0 :                 efx_mcdi_ev_death(enp, EIO);
     953                 :          0 :                 break;
     954                 :            : 
     955                 :          0 :         case MCDI_EVENT_CODE_MAC_STATS_DMA:
     956                 :            : #if EFSYS_OPT_MAC_STATS
     957         [ #  # ]:          0 :                 if (eecp->eec_mac_stats != NULL) {
     958                 :          0 :                         eecp->eec_mac_stats(arg,
     959                 :            :                             MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
     960                 :            :                 }
     961                 :            : #endif
     962                 :            :                 break;
     963                 :            : 
     964                 :          0 :         case MCDI_EVENT_CODE_FWALERT: {
     965                 :          0 :                 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
     966                 :            : 
     967         [ #  # ]:          0 :                 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
     968                 :          0 :                         should_abort = eecp->eec_exception(arg,
     969                 :            :                                 EFX_EXCEPTION_FWALERT_SRAM,
     970                 :          0 :                                 MCDI_EV_FIELD(eqp, FWALERT_DATA));
     971                 :            :                 else
     972                 :          0 :                         should_abort = eecp->eec_exception(arg,
     973                 :            :                                 EFX_EXCEPTION_UNKNOWN_FWALERT,
     974                 :            :                                 MCDI_EV_FIELD(eqp, DATA));
     975                 :            :                 break;
     976                 :            :         }
     977                 :            : 
     978                 :          0 :         case MCDI_EVENT_CODE_TX_ERR: {
     979                 :            :                 /*
     980                 :            :                  * After a TXQ error is detected, firmware sends a TX_ERR event.
     981                 :            :                  * This may be followed by TX completions (which we discard),
     982                 :            :                  * and then finally by a TX_FLUSH event. Firmware destroys the
     983                 :            :                  * TXQ automatically after sending the TX_FLUSH event.
     984                 :            :                  */
     985                 :          0 :                 enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
     986                 :            : 
     987                 :            :                 EFSYS_PROBE2(tx_descq_err,
     988                 :            :                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
     989                 :            :                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
     990                 :            : 
     991                 :            :                 /* Inform the driver that a reset is required. */
     992                 :          0 :                 eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
     993                 :            :                     MCDI_EV_FIELD(eqp, TX_ERR_DATA));
     994                 :          0 :                 break;
     995                 :            :         }
     996                 :            : 
     997                 :          0 :         case MCDI_EVENT_CODE_TX_FLUSH: {
     998                 :          0 :                 uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
     999                 :            : 
    1000                 :            :                 /*
    1001                 :            :                  * EF10 firmware sends two TX_FLUSH events: one to the txq's
    1002                 :            :                  * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
    1003                 :            :                  * We want to wait for all completions, so ignore the events
    1004                 :            :                  * with TX_FLUSH_TO_DRIVER.
    1005                 :            :                  */
    1006         [ #  # ]:          0 :                 if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
    1007                 :            :                         should_abort = B_FALSE;
    1008                 :            :                         break;
    1009                 :            :                 }
    1010                 :            : 
    1011                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
    1012                 :            : 
    1013                 :            :                 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
    1014                 :            : 
    1015         [ #  # ]:          0 :                 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
    1016                 :          0 :                 should_abort = eecp->eec_txq_flush_done(arg, txq_index);
    1017                 :          0 :                 break;
    1018                 :            :         }
    1019                 :            : 
    1020                 :          0 :         case MCDI_EVENT_CODE_RX_ERR: {
    1021                 :            :                 /*
    1022                 :            :                  * After an RXQ error is detected, firmware sends an RX_ERR
    1023                 :            :                  * event. This may be followed by RX events (which we discard),
    1024                 :            :                  * and then finally by an RX_FLUSH event. Firmware destroys the
    1025                 :            :                  * RXQ automatically after sending the RX_FLUSH event.
    1026                 :            :                  */
    1027                 :          0 :                 enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
    1028                 :            : 
    1029                 :            :                 EFSYS_PROBE2(rx_descq_err,
    1030                 :            :                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
    1031                 :            :                             uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
    1032                 :            : 
    1033                 :            :                 /* Inform the driver that a reset is required. */
    1034                 :          0 :                 eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
    1035                 :            :                     MCDI_EV_FIELD(eqp, RX_ERR_DATA));
    1036                 :          0 :                 break;
    1037                 :            :         }
    1038                 :            : 
    1039                 :          0 :         case MCDI_EVENT_CODE_RX_FLUSH: {
    1040                 :          0 :                 uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
    1041                 :            : 
    1042                 :            :                 /*
    1043                 :            :                  * EF10 firmware sends two RX_FLUSH events: one to the rxq's
    1044                 :            :                  * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
    1045                 :            :                  * We want to wait for all completions, so ignore the events
    1046                 :            :                  * with RX_FLUSH_TO_DRIVER.
    1047                 :            :                  */
    1048         [ #  # ]:          0 :                 if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
    1049                 :            :                         should_abort = B_FALSE;
    1050                 :            :                         break;
    1051                 :            :                 }
    1052                 :            : 
    1053                 :            :                 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
    1054                 :            : 
    1055                 :            :                 EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
    1056                 :            : 
    1057         [ #  # ]:          0 :                 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
    1058                 :          0 :                 should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
    1059                 :          0 :                 break;
    1060                 :            :         }
    1061                 :            : 
    1062                 :            :         default:
    1063                 :            :                 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
    1064                 :            :                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
    1065                 :            :                     uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
    1066                 :            :                 break;
    1067                 :            :         }
    1068                 :            : 
    1069                 :          0 :         return (should_abort);
    1070                 :            : }
    1071                 :            : 
    1072                 :            : #endif  /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
    1073                 :            : 
    1074                 :            : #if EFX_OPTS_EF10()
    1075                 :            : 
    1076                 :            :                 void
    1077                 :          0 : ef10_ev_rxlabel_init(
    1078                 :            :         __in            efx_evq_t *eep,
    1079                 :            :         __in            efx_rxq_t *erp,
    1080                 :            :         __in            unsigned int label,
    1081                 :            :         __in            efx_rxq_type_t type)
    1082                 :            : {
    1083                 :            :         efx_evq_rxq_state_t *eersp;
    1084                 :            : #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
    1085                 :          0 :         boolean_t packed_stream = (type == EFX_RXQ_TYPE_PACKED_STREAM);
    1086                 :          0 :         boolean_t es_super_buffer = (type == EFX_RXQ_TYPE_ES_SUPER_BUFFER);
    1087                 :            : #endif
    1088                 :            : 
    1089                 :            :         _NOTE(ARGUNUSED(type))
    1090         [ #  # ]:          0 :         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
    1091                 :            :         eersp = &eep->ee_rxq_state[label];
    1092                 :            : 
    1093         [ #  # ]:          0 :         EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
    1094                 :            : 
    1095                 :            : #if EFSYS_OPT_RX_PACKED_STREAM
    1096                 :            :         /*
    1097                 :            :          * For packed stream modes, the very first event will
    1098                 :            :          * have a new buffer flag set, so it will be incremented,
    1099                 :            :          * yielding the correct pointer. That results in a simpler
    1100                 :            :          * code than trying to detect start-of-the-world condition
    1101                 :            :          * in the event handler.
    1102                 :            :          */
    1103                 :            :         eersp->eers_rx_read_ptr = packed_stream ? ~0 : 0;
    1104                 :            : #else
    1105                 :          0 :         eersp->eers_rx_read_ptr = 0;
    1106                 :            : #endif
    1107                 :          0 :         eersp->eers_rx_mask = erp->er_mask;
    1108                 :            : #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
    1109                 :          0 :         eersp->eers_rx_stream_npackets = 0;
    1110                 :          0 :         eersp->eers_rx_packed_stream = packed_stream || es_super_buffer;
    1111                 :            : #endif
    1112                 :            : #if EFSYS_OPT_RX_PACKED_STREAM
    1113                 :            :         if (packed_stream) {
    1114                 :            :                 eersp->eers_rx_packed_stream_credits = (eep->ee_mask + 1) /
    1115                 :            :                     EFX_DIV_ROUND_UP(EFX_RX_PACKED_STREAM_MEM_PER_CREDIT,
    1116                 :            :                     EFX_RX_PACKED_STREAM_MIN_PACKET_SPACE);
    1117                 :            :                 EFSYS_ASSERT3U(eersp->eers_rx_packed_stream_credits, !=, 0);
    1118                 :            :                 /*
    1119                 :            :                  * A single credit is allocated to the queue when it is started.
    1120                 :            :                  * It is immediately spent by the first packet which has NEW
    1121                 :            :                  * BUFFER flag set, though, but still we shall take into
    1122                 :            :                  * account, as to not wrap around the maximum number of credits
    1123                 :            :                  * accidentally
    1124                 :            :                  */
    1125                 :            :                 eersp->eers_rx_packed_stream_credits--;
    1126                 :            :                 EFSYS_ASSERT3U(eersp->eers_rx_packed_stream_credits, <=,
    1127                 :            :                     EFX_RX_PACKED_STREAM_MAX_CREDITS);
    1128                 :            :         }
    1129                 :            : #endif
    1130                 :          0 : }
    1131                 :            : 
    1132                 :            :                 void
    1133                 :          0 : ef10_ev_rxlabel_fini(
    1134                 :            :         __in            efx_evq_t *eep,
    1135                 :            :         __in            unsigned int label)
    1136                 :            : {
    1137                 :            :         efx_evq_rxq_state_t *eersp;
    1138                 :            : 
    1139         [ #  # ]:          0 :         EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
    1140                 :            :         eersp = &eep->ee_rxq_state[label];
    1141                 :            : 
    1142         [ #  # ]:          0 :         EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
    1143                 :            : 
    1144                 :          0 :         eersp->eers_rx_read_ptr = 0;
    1145                 :          0 :         eersp->eers_rx_mask = 0;
    1146                 :            : #if EFSYS_OPT_RX_PACKED_STREAM || EFSYS_OPT_RX_ES_SUPER_BUFFER
    1147                 :          0 :         eersp->eers_rx_stream_npackets = 0;
    1148                 :          0 :         eersp->eers_rx_packed_stream = B_FALSE;
    1149                 :            : #endif
    1150                 :            : #if EFSYS_OPT_RX_PACKED_STREAM
    1151                 :            :         eersp->eers_rx_packed_stream_credits = 0;
    1152                 :            : #endif
    1153                 :          0 : }
    1154                 :            : 
    1155                 :            : #endif  /* EFX_OPTS_EF10() */

Generated by: LCOV version 1.14