LCOV - code coverage report
Current view: top level - drivers/common/sfc_efx/base - efx_intr.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 66 0.0 %
Date: 2024-04-01 19:00:53 Functions: 0 9 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 45 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) 2007-2019 Solarflare Communications Inc.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "efx.h"
       8                 :            : #include "efx_impl.h"
       9                 :            : 
      10                 :            : 
      11                 :            : #if EFSYS_OPT_SIENA
      12                 :            : 
      13                 :            : static  __checkReturn   efx_rc_t
      14                 :            : siena_intr_init(
      15                 :            :         __in            efx_nic_t *enp,
      16                 :            :         __in            efx_intr_type_t type,
      17                 :            :         __in            efsys_mem_t *esmp);
      18                 :            : 
      19                 :            : static                  void
      20                 :            : siena_intr_enable(
      21                 :            :         __in            efx_nic_t *enp);
      22                 :            : 
      23                 :            : static                  void
      24                 :            : siena_intr_disable(
      25                 :            :         __in            efx_nic_t *enp);
      26                 :            : 
      27                 :            : static                  void
      28                 :            : siena_intr_disable_unlocked(
      29                 :            :         __in            efx_nic_t *enp);
      30                 :            : 
      31                 :            : static  __checkReturn   efx_rc_t
      32                 :            : siena_intr_trigger(
      33                 :            :         __in            efx_nic_t *enp,
      34                 :            :         __in            unsigned int level);
      35                 :            : 
      36                 :            : static                  void
      37                 :            : siena_intr_fini(
      38                 :            :         __in            efx_nic_t *enp);
      39                 :            : 
      40                 :            : static                  void
      41                 :            : siena_intr_status_line(
      42                 :            :         __in            efx_nic_t *enp,
      43                 :            :         __out           boolean_t *fatalp,
      44                 :            :         __out           uint32_t *qmaskp);
      45                 :            : 
      46                 :            : static                  void
      47                 :            : siena_intr_status_message(
      48                 :            :         __in            efx_nic_t *enp,
      49                 :            :         __in            unsigned int message,
      50                 :            :         __out           boolean_t *fatalp);
      51                 :            : 
      52                 :            : static                  void
      53                 :            : siena_intr_fatal(
      54                 :            :         __in            efx_nic_t *enp);
      55                 :            : 
      56                 :            : static  __checkReturn   boolean_t
      57                 :            : siena_intr_check_fatal(
      58                 :            :         __in            efx_nic_t *enp);
      59                 :            : 
      60                 :            : 
      61                 :            : #endif /* EFSYS_OPT_SIENA */
      62                 :            : 
      63                 :            : 
      64                 :            : #if EFSYS_OPT_SIENA
      65                 :            : static const efx_intr_ops_t     __efx_intr_siena_ops = {
      66                 :            :         siena_intr_init,                /* eio_init */
      67                 :            :         siena_intr_enable,              /* eio_enable */
      68                 :            :         siena_intr_disable,             /* eio_disable */
      69                 :            :         siena_intr_disable_unlocked,    /* eio_disable_unlocked */
      70                 :            :         siena_intr_trigger,             /* eio_trigger */
      71                 :            :         siena_intr_status_line,         /* eio_status_line */
      72                 :            :         siena_intr_status_message,      /* eio_status_message */
      73                 :            :         siena_intr_fatal,               /* eio_fatal */
      74                 :            :         siena_intr_fini,                /* eio_fini */
      75                 :            : };
      76                 :            : #endif  /* EFSYS_OPT_SIENA */
      77                 :            : 
      78                 :            : #if EFX_OPTS_EF10()
      79                 :            : static const efx_intr_ops_t     __efx_intr_ef10_ops = {
      80                 :            :         ef10_intr_init,                 /* eio_init */
      81                 :            :         ef10_intr_enable,               /* eio_enable */
      82                 :            :         ef10_intr_disable,              /* eio_disable */
      83                 :            :         ef10_intr_disable_unlocked,     /* eio_disable_unlocked */
      84                 :            :         ef10_intr_trigger,              /* eio_trigger */
      85                 :            :         ef10_intr_status_line,          /* eio_status_line */
      86                 :            :         ef10_intr_status_message,       /* eio_status_message */
      87                 :            :         ef10_intr_fatal,                /* eio_fatal */
      88                 :            :         ef10_intr_fini,                 /* eio_fini */
      89                 :            : };
      90                 :            : #endif  /* EFX_OPTS_EF10() */
      91                 :            : 
      92                 :            : #if EFSYS_OPT_RIVERHEAD
      93                 :            : static const efx_intr_ops_t     __efx_intr_rhead_ops = {
      94                 :            :         rhead_intr_init,                /* eio_init */
      95                 :            :         rhead_intr_enable,              /* eio_enable */
      96                 :            :         rhead_intr_disable,             /* eio_disable */
      97                 :            :         rhead_intr_disable_unlocked,    /* eio_disable_unlocked */
      98                 :            :         rhead_intr_trigger,             /* eio_trigger */
      99                 :            :         rhead_intr_status_line,         /* eio_status_line */
     100                 :            :         rhead_intr_status_message,      /* eio_status_message */
     101                 :            :         rhead_intr_fatal,               /* eio_fatal */
     102                 :            :         rhead_intr_fini,                /* eio_fini */
     103                 :            : };
     104                 :            : #endif  /* EFSYS_OPT_RIVERHEAD */
     105                 :            : 
     106                 :            :         __checkReturn   efx_rc_t
     107                 :          0 : efx_intr_init(
     108                 :            :         __in            efx_nic_t *enp,
     109                 :            :         __in            efx_intr_type_t type,
     110                 :            :         __in_opt        efsys_mem_t *esmp)
     111                 :            : {
     112                 :            :         efx_intr_t *eip = &(enp->en_intr);
     113                 :            :         const efx_intr_ops_t *eiop;
     114                 :            :         efx_rc_t rc;
     115                 :            : 
     116         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     117         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
     118                 :            : 
     119         [ #  # ]:          0 :         if (enp->en_mod_flags & EFX_MOD_INTR) {
     120                 :            :                 rc = EINVAL;
     121                 :          0 :                 goto fail1;
     122                 :            :         }
     123                 :            : 
     124                 :          0 :         eip->ei_esmp = esmp;
     125                 :          0 :         eip->ei_type = type;
     126                 :          0 :         eip->ei_level = 0;
     127                 :            : 
     128                 :          0 :         enp->en_mod_flags |= EFX_MOD_INTR;
     129                 :            : 
     130      [ #  #  # ]:          0 :         switch (enp->en_family) {
     131                 :            : #if EFSYS_OPT_SIENA
     132                 :            :         case EFX_FAMILY_SIENA:
     133                 :            :                 eiop = &__efx_intr_siena_ops;
     134                 :            :                 break;
     135                 :            : #endif  /* EFSYS_OPT_SIENA */
     136                 :            : 
     137                 :            : #if EFSYS_OPT_HUNTINGTON
     138                 :            :         case EFX_FAMILY_HUNTINGTON:
     139                 :            :                 eiop = &__efx_intr_ef10_ops;
     140                 :            :                 break;
     141                 :            : #endif  /* EFSYS_OPT_HUNTINGTON */
     142                 :            : 
     143                 :            : #if EFSYS_OPT_MEDFORD
     144                 :            :         case EFX_FAMILY_MEDFORD:
     145                 :            :                 eiop = &__efx_intr_ef10_ops;
     146                 :            :                 break;
     147                 :            : #endif  /* EFSYS_OPT_MEDFORD */
     148                 :            : 
     149                 :            : #if EFSYS_OPT_MEDFORD2
     150                 :            :         case EFX_FAMILY_MEDFORD2:
     151                 :            :                 eiop = &__efx_intr_ef10_ops;
     152                 :            :                 break;
     153                 :            : #endif  /* EFSYS_OPT_MEDFORD2 */
     154                 :            : 
     155                 :            : #if EFSYS_OPT_RIVERHEAD
     156                 :          0 :         case EFX_FAMILY_RIVERHEAD:
     157                 :            :                 eiop = &__efx_intr_rhead_ops;
     158                 :          0 :                 break;
     159                 :            : #endif  /* EFSYS_OPT_RIVERHEAD */
     160                 :            : 
     161                 :            :         default:
     162                 :          0 :                 EFSYS_ASSERT(B_FALSE);
     163                 :            :                 rc = ENOTSUP;
     164                 :            :                 goto fail2;
     165                 :            :         }
     166                 :            : 
     167         [ #  # ]:          0 :         if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
     168                 :          0 :                 goto fail3;
     169                 :            : 
     170                 :          0 :         eip->ei_eiop = eiop;
     171                 :            : 
     172                 :          0 :         return (0);
     173                 :            : 
     174                 :            : fail3:
     175                 :            :         EFSYS_PROBE(fail3);
     176                 :            : fail2:
     177                 :            :         EFSYS_PROBE(fail2);
     178                 :            : fail1:
     179                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     180                 :            : 
     181                 :            :         return (rc);
     182                 :            : }
     183                 :            : 
     184                 :            :                 void
     185                 :          0 : efx_intr_fini(
     186                 :            :         __in    efx_nic_t *enp)
     187                 :            : {
     188                 :            :         efx_intr_t *eip = &(enp->en_intr);
     189                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     190                 :            : 
     191         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     192         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
     193         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     194                 :            : 
     195                 :          0 :         eiop->eio_fini(enp);
     196                 :            : 
     197                 :          0 :         enp->en_mod_flags &= ~EFX_MOD_INTR;
     198                 :          0 : }
     199                 :            : 
     200                 :            :                         void
     201                 :          0 : efx_intr_enable(
     202                 :            :         __in            efx_nic_t *enp)
     203                 :            : {
     204                 :            :         efx_intr_t *eip = &(enp->en_intr);
     205                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     206                 :            : 
     207         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     208         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     209                 :            : 
     210                 :          0 :         eiop->eio_enable(enp);
     211                 :          0 : }
     212                 :            : 
     213                 :            :                         void
     214                 :          0 : efx_intr_disable(
     215                 :            :         __in            efx_nic_t *enp)
     216                 :            : {
     217                 :            :         efx_intr_t *eip = &(enp->en_intr);
     218                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     219                 :            : 
     220         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     221         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     222                 :            : 
     223                 :          0 :         eiop->eio_disable(enp);
     224                 :          0 : }
     225                 :            : 
     226                 :            :                         void
     227                 :          0 : efx_intr_disable_unlocked(
     228                 :            :         __in            efx_nic_t *enp)
     229                 :            : {
     230                 :            :         efx_intr_t *eip = &(enp->en_intr);
     231                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     232                 :            : 
     233         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     234         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     235                 :            : 
     236                 :          0 :         eiop->eio_disable_unlocked(enp);
     237                 :          0 : }
     238                 :            : 
     239                 :            : 
     240                 :            :         __checkReturn   efx_rc_t
     241                 :          0 : efx_intr_trigger(
     242                 :            :         __in            efx_nic_t *enp,
     243                 :            :         __in            unsigned int level)
     244                 :            : {
     245                 :            :         efx_intr_t *eip = &(enp->en_intr);
     246                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     247                 :            : 
     248         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     249         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     250                 :            : 
     251                 :          0 :         return (eiop->eio_trigger(enp, level));
     252                 :            : }
     253                 :            : 
     254                 :            :                         void
     255                 :          0 : efx_intr_status_line(
     256                 :            :         __in            efx_nic_t *enp,
     257                 :            :         __out           boolean_t *fatalp,
     258                 :            :         __out           uint32_t *qmaskp)
     259                 :            : {
     260                 :            :         efx_intr_t *eip = &(enp->en_intr);
     261                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     262                 :            : 
     263         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     264         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     265                 :            : 
     266                 :          0 :         eiop->eio_status_line(enp, fatalp, qmaskp);
     267                 :          0 : }
     268                 :            : 
     269                 :            :                         void
     270                 :          0 : efx_intr_status_message(
     271                 :            :         __in            efx_nic_t *enp,
     272                 :            :         __in            unsigned int message,
     273                 :            :         __out           boolean_t *fatalp)
     274                 :            : {
     275                 :            :         efx_intr_t *eip = &(enp->en_intr);
     276                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     277                 :            : 
     278         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     279         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     280                 :            : 
     281                 :          0 :         eiop->eio_status_message(enp, message, fatalp);
     282                 :          0 : }
     283                 :            : 
     284                 :            :                 void
     285                 :          0 : efx_intr_fatal(
     286                 :            :         __in    efx_nic_t *enp)
     287                 :            : {
     288                 :            :         efx_intr_t *eip = &(enp->en_intr);
     289                 :          0 :         const efx_intr_ops_t *eiop = eip->ei_eiop;
     290                 :            : 
     291         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     292         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     293                 :            : 
     294                 :          0 :         eiop->eio_fatal(enp);
     295                 :          0 : }
     296                 :            : 
     297                 :            : 
     298                 :            : /* ************************************************************************* */
     299                 :            : /* ************************************************************************* */
     300                 :            : /* ************************************************************************* */
     301                 :            : 
     302                 :            : #if EFSYS_OPT_SIENA
     303                 :            : 
     304                 :            : static  __checkReturn   efx_rc_t
     305                 :            : siena_intr_init(
     306                 :            :         __in            efx_nic_t *enp,
     307                 :            :         __in            efx_intr_type_t type,
     308                 :            :         __in            efsys_mem_t *esmp)
     309                 :            : {
     310                 :            :         efx_intr_t *eip = &(enp->en_intr);
     311                 :            :         efx_oword_t oword;
     312                 :            :         efx_rc_t rc;
     313                 :            : 
     314                 :            :         if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_INTR_SIZE)) {
     315                 :            :                 rc = EINVAL;
     316                 :            :                 goto fail1;
     317                 :            :         }
     318                 :            : 
     319                 :            :         /*
     320                 :            :          * bug17213 workaround.
     321                 :            :          *
     322                 :            :          * Under legacy interrupts, don't share a level between fatal
     323                 :            :          * interrupts and event queue interrupts. Under MSI-X, they
     324                 :            :          * must share, or we won't get an interrupt.
     325                 :            :          */
     326                 :            :         if (enp->en_family == EFX_FAMILY_SIENA &&
     327                 :            :             eip->ei_type == EFX_INTR_LINE)
     328                 :            :                 eip->ei_level = 0x1f;
     329                 :            :         else
     330                 :            :                 eip->ei_level = 0;
     331                 :            : 
     332                 :            :         /* Enable all the genuinely fatal interrupts */
     333                 :            :         EFX_SET_OWORD(oword);
     334                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
     335                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
     336                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
     337                 :            :         if (enp->en_family >= EFX_FAMILY_SIENA)
     338                 :            :                 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
     339                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
     340                 :            : 
     341                 :            :         /* Set up the interrupt address register */
     342                 :            :         EFX_POPULATE_OWORD_3(oword,
     343                 :            :             FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
     344                 :            :             FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
     345                 :            :             FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
     346                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
     347                 :            : 
     348                 :            :         return (0);
     349                 :            : 
     350                 :            : fail1:
     351                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     352                 :            : 
     353                 :            :         return (rc);
     354                 :            : }
     355                 :            : 
     356                 :            : static                  void
     357                 :            : siena_intr_enable(
     358                 :            :         __in            efx_nic_t *enp)
     359                 :            : {
     360                 :            :         efx_intr_t *eip = &(enp->en_intr);
     361                 :            :         efx_oword_t oword;
     362                 :            : 
     363                 :            :         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     364                 :            : 
     365                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
     366                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
     367                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     368                 :            : }
     369                 :            : 
     370                 :            : static                  void
     371                 :            : siena_intr_disable(
     372                 :            :         __in            efx_nic_t *enp)
     373                 :            : {
     374                 :            :         efx_oword_t oword;
     375                 :            : 
     376                 :            :         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     377                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
     378                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     379                 :            : 
     380                 :            :         EFSYS_SPIN(10);
     381                 :            : }
     382                 :            : 
     383                 :            : static                  void
     384                 :            : siena_intr_disable_unlocked(
     385                 :            :         __in            efx_nic_t *enp)
     386                 :            : {
     387                 :            :         efx_oword_t oword;
     388                 :            : 
     389                 :            :         EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
     390                 :            :                         &oword, B_FALSE);
     391                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
     392                 :            :         EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
     393                 :            :             &oword, B_FALSE);
     394                 :            : }
     395                 :            : 
     396                 :            : static  __checkReturn   efx_rc_t
     397                 :            : siena_intr_trigger(
     398                 :            :         __in            efx_nic_t *enp,
     399                 :            :         __in            unsigned int level)
     400                 :            : {
     401                 :            :         efx_intr_t *eip = &(enp->en_intr);
     402                 :            :         efx_oword_t oword;
     403                 :            :         unsigned int count;
     404                 :            :         uint32_t sel;
     405                 :            :         efx_rc_t rc;
     406                 :            : 
     407                 :            :         /* bug16757: No event queues can be initialized */
     408                 :            :         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
     409                 :            : 
     410                 :            :         if (level >= EFX_NINTR_SIENA) {
     411                 :            :                 rc = EINVAL;
     412                 :            :                 goto fail1;
     413                 :            :         }
     414                 :            : 
     415                 :            :         if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
     416                 :            :                 return (ENOTSUP); /* avoid EFSYS_PROBE() */
     417                 :            : 
     418                 :            :         sel = level;
     419                 :            : 
     420                 :            :         /* Trigger a test interrupt */
     421                 :            :         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     422                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
     423                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
     424                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     425                 :            : 
     426                 :            :         /*
     427                 :            :          * Wait up to 100ms for the interrupt to be raised before restoring
     428                 :            :          * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
     429                 :            :          * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
     430                 :            :          */
     431                 :            :         count = 0;
     432                 :            :         do {
     433                 :            :                 EFSYS_SPIN(100);        /* 100us */
     434                 :            : 
     435                 :            :                 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     436                 :            :         } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
     437                 :            : 
     438                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
     439                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
     440                 :            : 
     441                 :            :         return (0);
     442                 :            : 
     443                 :            : fail1:
     444                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     445                 :            : 
     446                 :            :         return (rc);
     447                 :            : }
     448                 :            : 
     449                 :            : static  __checkReturn   boolean_t
     450                 :            : siena_intr_check_fatal(
     451                 :            :         __in            efx_nic_t *enp)
     452                 :            : {
     453                 :            :         efx_intr_t *eip = &(enp->en_intr);
     454                 :            :         efsys_mem_t *esmp = eip->ei_esmp;
     455                 :            :         efx_oword_t oword;
     456                 :            : 
     457                 :            :         /* Read the syndrome */
     458                 :            :         EFSYS_MEM_READO(esmp, 0, &oword);
     459                 :            : 
     460                 :            :         if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
     461                 :            :                 EFSYS_PROBE(fatal);
     462                 :            : 
     463                 :            :                 /* Clear the fatal interrupt condition */
     464                 :            :                 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
     465                 :            :                 EFSYS_MEM_WRITEO(esmp, 0, &oword);
     466                 :            : 
     467                 :            :                 return (B_TRUE);
     468                 :            :         }
     469                 :            : 
     470                 :            :         return (B_FALSE);
     471                 :            : }
     472                 :            : 
     473                 :            : static                  void
     474                 :            : siena_intr_status_line(
     475                 :            :         __in            efx_nic_t *enp,
     476                 :            :         __out           boolean_t *fatalp,
     477                 :            :         __out           uint32_t *qmaskp)
     478                 :            : {
     479                 :            :         efx_intr_t *eip = &(enp->en_intr);
     480                 :            :         efx_dword_t dword;
     481                 :            : 
     482                 :            :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     483                 :            :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     484                 :            : 
     485                 :            :         /*
     486                 :            :          * Read the queue mask and implicitly acknowledge the
     487                 :            :          * interrupt.
     488                 :            :          */
     489                 :            :         EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
     490                 :            :         *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
     491                 :            : 
     492                 :            :         EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
     493                 :            : 
     494                 :            :         if (*qmaskp & (1U << eip->ei_level))
     495                 :            :                 *fatalp = siena_intr_check_fatal(enp);
     496                 :            :         else
     497                 :            :                 *fatalp = B_FALSE;
     498                 :            : }
     499                 :            : 
     500                 :            : static                  void
     501                 :            : siena_intr_status_message(
     502                 :            :         __in            efx_nic_t *enp,
     503                 :            :         __in            unsigned int message,
     504                 :            :         __out           boolean_t *fatalp)
     505                 :            : {
     506                 :            :         efx_intr_t *eip = &(enp->en_intr);
     507                 :            : 
     508                 :            :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     509                 :            :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
     510                 :            : 
     511                 :            :         if (message == eip->ei_level)
     512                 :            :                 *fatalp = siena_intr_check_fatal(enp);
     513                 :            :         else
     514                 :            :                 *fatalp = B_FALSE;
     515                 :            : }
     516                 :            : 
     517                 :            : 
     518                 :            : static          void
     519                 :            : siena_intr_fatal(
     520                 :            :         __in    efx_nic_t *enp)
     521                 :            : {
     522                 :            : #if EFSYS_OPT_DECODE_INTR_FATAL
     523                 :            :         efx_oword_t fatal;
     524                 :            :         efx_oword_t mem_per;
     525                 :            : 
     526                 :            :         EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
     527                 :            :         EFX_ZERO_OWORD(mem_per);
     528                 :            : 
     529                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
     530                 :            :             EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
     531                 :            :                 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
     532                 :            : 
     533                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
     534                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
     535                 :            : 
     536                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
     537                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
     538                 :            : 
     539                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
     540                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
     541                 :            :                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
     542                 :            :                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
     543                 :            : 
     544                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
     545                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
     546                 :            : 
     547                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
     548                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
     549                 :            : 
     550                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
     551                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
     552                 :            : 
     553                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
     554                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
     555                 :            : 
     556                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
     557                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
     558                 :            : 
     559                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
     560                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
     561                 :            : 
     562                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
     563                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
     564                 :            : 
     565                 :            :         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
     566                 :            :                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
     567                 :            :                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
     568                 :            :                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
     569                 :            : #else
     570                 :            :         EFSYS_ASSERT(0);
     571                 :            : #endif
     572                 :            : }
     573                 :            : 
     574                 :            : static          void
     575                 :            : siena_intr_fini(
     576                 :            :         __in    efx_nic_t *enp)
     577                 :            : {
     578                 :            :         efx_oword_t oword;
     579                 :            : 
     580                 :            :         /* Clear the interrupt address register */
     581                 :            :         EFX_ZERO_OWORD(oword);
     582                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
     583                 :            : }
     584                 :            : 
     585                 :            : #endif /* EFSYS_OPT_SIENA */

Generated by: LCOV version 1.14