LCOV - code coverage report
Current view: top level - drivers/common/sfc_efx/base - efx_tx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 184 0.0 %
Date: 2024-01-22 16:26:08 Functions: 0 21 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 115 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                 :            : #if EFSYS_OPT_QSTATS
      11                 :            : #define EFX_TX_QSTAT_INCR(_etp, _stat)                                  \
      12                 :            :         do {                                                            \
      13                 :            :                 (_etp)->et_stat[_stat]++;                            \
      14                 :            :         _NOTE(CONSTANTCONDITION)                                        \
      15                 :            :         } while (B_FALSE)
      16                 :            : #else
      17                 :            : #define EFX_TX_QSTAT_INCR(_etp, _stat)
      18                 :            : #endif
      19                 :            : 
      20                 :            : #if EFSYS_OPT_SIENA
      21                 :            : 
      22                 :            : static  __checkReturn   efx_rc_t
      23                 :            : siena_tx_init(
      24                 :            :         __in            efx_nic_t *enp);
      25                 :            : 
      26                 :            : static                  void
      27                 :            : siena_tx_fini(
      28                 :            :         __in            efx_nic_t *enp);
      29                 :            : 
      30                 :            : static  __checkReturn   efx_rc_t
      31                 :            : siena_tx_qcreate(
      32                 :            :         __in            efx_nic_t *enp,
      33                 :            :         __in            unsigned int index,
      34                 :            :         __in            unsigned int label,
      35                 :            :         __in            efsys_mem_t *esmp,
      36                 :            :         __in            size_t ndescs,
      37                 :            :         __in            uint32_t id,
      38                 :            :         __in            uint16_t flags,
      39                 :            :         __in            efx_evq_t *eep,
      40                 :            :         __in            efx_txq_t *etp,
      41                 :            :         __out           unsigned int *addedp);
      42                 :            : 
      43                 :            : static          void
      44                 :            : siena_tx_qdestroy(
      45                 :            :         __in    efx_txq_t *etp);
      46                 :            : 
      47                 :            : static  __checkReturn           efx_rc_t
      48                 :            : siena_tx_qpost(
      49                 :            :         __in                    efx_txq_t *etp,
      50                 :            :         __in_ecount(ndescs)     efx_buffer_t *eb,
      51                 :            :         __in                    unsigned int ndescs,
      52                 :            :         __in                    unsigned int completed,
      53                 :            :         __inout                 unsigned int *addedp);
      54                 :            : 
      55                 :            : static                  void
      56                 :            : siena_tx_qpush(
      57                 :            :         __in    efx_txq_t *etp,
      58                 :            :         __in    unsigned int added,
      59                 :            :         __in    unsigned int pushed);
      60                 :            : 
      61                 :            : static  __checkReturn   efx_rc_t
      62                 :            : siena_tx_qpace(
      63                 :            :         __in            efx_txq_t *etp,
      64                 :            :         __in            unsigned int ns);
      65                 :            : 
      66                 :            : static  __checkReturn   efx_rc_t
      67                 :            : siena_tx_qflush(
      68                 :            :         __in            efx_txq_t *etp);
      69                 :            : 
      70                 :            : static                  void
      71                 :            : siena_tx_qenable(
      72                 :            :         __in    efx_txq_t *etp);
      73                 :            : 
      74                 :            :         __checkReturn           efx_rc_t
      75                 :            : siena_tx_qdesc_post(
      76                 :            :         __in                    efx_txq_t *etp,
      77                 :            :         __in_ecount(ndescs)     efx_desc_t *ed,
      78                 :            :         __in                    unsigned int ndescs,
      79                 :            :         __in                    unsigned int completed,
      80                 :            :         __inout                 unsigned int *addedp);
      81                 :            : 
      82                 :            :         void
      83                 :            : siena_tx_qdesc_dma_create(
      84                 :            :         __in    efx_txq_t *etp,
      85                 :            :         __in    efsys_dma_addr_t addr,
      86                 :            :         __in    size_t size,
      87                 :            :         __in    boolean_t eop,
      88                 :            :         __out   efx_desc_t *edp);
      89                 :            : 
      90                 :            : #if EFSYS_OPT_QSTATS
      91                 :            : static                  void
      92                 :            : siena_tx_qstats_update(
      93                 :            :         __in                            efx_txq_t *etp,
      94                 :            :         __inout_ecount(TX_NQSTATS)      efsys_stat_t *stat);
      95                 :            : #endif
      96                 :            : 
      97                 :            : #endif /* EFSYS_OPT_SIENA */
      98                 :            : 
      99                 :            : 
     100                 :            : #if EFSYS_OPT_SIENA
     101                 :            : static const efx_tx_ops_t       __efx_tx_siena_ops = {
     102                 :            :         siena_tx_init,                          /* etxo_init */
     103                 :            :         siena_tx_fini,                          /* etxo_fini */
     104                 :            :         siena_tx_qcreate,                       /* etxo_qcreate */
     105                 :            :         siena_tx_qdestroy,                      /* etxo_qdestroy */
     106                 :            :         siena_tx_qpost,                         /* etxo_qpost */
     107                 :            :         siena_tx_qpush,                         /* etxo_qpush */
     108                 :            :         siena_tx_qpace,                         /* etxo_qpace */
     109                 :            :         siena_tx_qflush,                        /* etxo_qflush */
     110                 :            :         siena_tx_qenable,                       /* etxo_qenable */
     111                 :            :         NULL,                                   /* etxo_qpio_enable */
     112                 :            :         NULL,                                   /* etxo_qpio_disable */
     113                 :            :         NULL,                                   /* etxo_qpio_write */
     114                 :            :         NULL,                                   /* etxo_qpio_post */
     115                 :            :         siena_tx_qdesc_post,                    /* etxo_qdesc_post */
     116                 :            :         siena_tx_qdesc_dma_create,              /* etxo_qdesc_dma_create */
     117                 :            :         NULL,                                   /* etxo_qdesc_tso_create */
     118                 :            :         NULL,                                   /* etxo_qdesc_tso2_create */
     119                 :            :         NULL,                                   /* etxo_qdesc_vlantci_create */
     120                 :            :         NULL,                                   /* etxo_qdesc_checksum_create */
     121                 :            : #if EFSYS_OPT_QSTATS
     122                 :            :         siena_tx_qstats_update,                 /* etxo_qstats_update */
     123                 :            : #endif
     124                 :            : };
     125                 :            : #endif /* EFSYS_OPT_SIENA */
     126                 :            : 
     127                 :            : #if EFSYS_OPT_HUNTINGTON
     128                 :            : static const efx_tx_ops_t       __efx_tx_hunt_ops = {
     129                 :            :         ef10_tx_init,                           /* etxo_init */
     130                 :            :         ef10_tx_fini,                           /* etxo_fini */
     131                 :            :         ef10_tx_qcreate,                        /* etxo_qcreate */
     132                 :            :         ef10_tx_qdestroy,                       /* etxo_qdestroy */
     133                 :            :         ef10_tx_qpost,                          /* etxo_qpost */
     134                 :            :         ef10_tx_qpush,                          /* etxo_qpush */
     135                 :            :         ef10_tx_qpace,                          /* etxo_qpace */
     136                 :            :         ef10_tx_qflush,                         /* etxo_qflush */
     137                 :            :         ef10_tx_qenable,                        /* etxo_qenable */
     138                 :            :         ef10_tx_qpio_enable,                    /* etxo_qpio_enable */
     139                 :            :         ef10_tx_qpio_disable,                   /* etxo_qpio_disable */
     140                 :            :         ef10_tx_qpio_write,                     /* etxo_qpio_write */
     141                 :            :         ef10_tx_qpio_post,                      /* etxo_qpio_post */
     142                 :            :         ef10_tx_qdesc_post,                     /* etxo_qdesc_post */
     143                 :            :         ef10_tx_qdesc_dma_create,               /* etxo_qdesc_dma_create */
     144                 :            :         ef10_tx_qdesc_tso_create,               /* etxo_qdesc_tso_create */
     145                 :            :         ef10_tx_qdesc_tso2_create,              /* etxo_qdesc_tso2_create */
     146                 :            :         ef10_tx_qdesc_vlantci_create,           /* etxo_qdesc_vlantci_create */
     147                 :            :         ef10_tx_qdesc_checksum_create,          /* etxo_qdesc_checksum_create */
     148                 :            : #if EFSYS_OPT_QSTATS
     149                 :            :         ef10_tx_qstats_update,                  /* etxo_qstats_update */
     150                 :            : #endif
     151                 :            : };
     152                 :            : #endif /* EFSYS_OPT_HUNTINGTON */
     153                 :            : 
     154                 :            : #if EFSYS_OPT_MEDFORD
     155                 :            : static const efx_tx_ops_t       __efx_tx_medford_ops = {
     156                 :            :         ef10_tx_init,                           /* etxo_init */
     157                 :            :         ef10_tx_fini,                           /* etxo_fini */
     158                 :            :         ef10_tx_qcreate,                        /* etxo_qcreate */
     159                 :            :         ef10_tx_qdestroy,                       /* etxo_qdestroy */
     160                 :            :         ef10_tx_qpost,                          /* etxo_qpost */
     161                 :            :         ef10_tx_qpush,                          /* etxo_qpush */
     162                 :            :         ef10_tx_qpace,                          /* etxo_qpace */
     163                 :            :         ef10_tx_qflush,                         /* etxo_qflush */
     164                 :            :         ef10_tx_qenable,                        /* etxo_qenable */
     165                 :            :         ef10_tx_qpio_enable,                    /* etxo_qpio_enable */
     166                 :            :         ef10_tx_qpio_disable,                   /* etxo_qpio_disable */
     167                 :            :         ef10_tx_qpio_write,                     /* etxo_qpio_write */
     168                 :            :         ef10_tx_qpio_post,                      /* etxo_qpio_post */
     169                 :            :         ef10_tx_qdesc_post,                     /* etxo_qdesc_post */
     170                 :            :         ef10_tx_qdesc_dma_create,               /* etxo_qdesc_dma_create */
     171                 :            :         NULL,                                   /* etxo_qdesc_tso_create */
     172                 :            :         ef10_tx_qdesc_tso2_create,              /* etxo_qdesc_tso2_create */
     173                 :            :         ef10_tx_qdesc_vlantci_create,           /* etxo_qdesc_vlantci_create */
     174                 :            :         ef10_tx_qdesc_checksum_create,          /* etxo_qdesc_checksum_create */
     175                 :            : #if EFSYS_OPT_QSTATS
     176                 :            :         ef10_tx_qstats_update,                  /* etxo_qstats_update */
     177                 :            : #endif
     178                 :            : };
     179                 :            : #endif /* EFSYS_OPT_MEDFORD */
     180                 :            : 
     181                 :            : #if EFSYS_OPT_MEDFORD2
     182                 :            : static const efx_tx_ops_t       __efx_tx_medford2_ops = {
     183                 :            :         ef10_tx_init,                           /* etxo_init */
     184                 :            :         ef10_tx_fini,                           /* etxo_fini */
     185                 :            :         ef10_tx_qcreate,                        /* etxo_qcreate */
     186                 :            :         ef10_tx_qdestroy,                       /* etxo_qdestroy */
     187                 :            :         ef10_tx_qpost,                          /* etxo_qpost */
     188                 :            :         ef10_tx_qpush,                          /* etxo_qpush */
     189                 :            :         ef10_tx_qpace,                          /* etxo_qpace */
     190                 :            :         ef10_tx_qflush,                         /* etxo_qflush */
     191                 :            :         ef10_tx_qenable,                        /* etxo_qenable */
     192                 :            :         ef10_tx_qpio_enable,                    /* etxo_qpio_enable */
     193                 :            :         ef10_tx_qpio_disable,                   /* etxo_qpio_disable */
     194                 :            :         ef10_tx_qpio_write,                     /* etxo_qpio_write */
     195                 :            :         ef10_tx_qpio_post,                      /* etxo_qpio_post */
     196                 :            :         ef10_tx_qdesc_post,                     /* etxo_qdesc_post */
     197                 :            :         ef10_tx_qdesc_dma_create,               /* etxo_qdesc_dma_create */
     198                 :            :         NULL,                                   /* etxo_qdesc_tso_create */
     199                 :            :         ef10_tx_qdesc_tso2_create,              /* etxo_qdesc_tso2_create */
     200                 :            :         ef10_tx_qdesc_vlantci_create,           /* etxo_qdesc_vlantci_create */
     201                 :            :         ef10_tx_qdesc_checksum_create,          /* etxo_qdesc_checksum_create */
     202                 :            : #if EFSYS_OPT_QSTATS
     203                 :            :         ef10_tx_qstats_update,                  /* etxo_qstats_update */
     204                 :            : #endif
     205                 :            : };
     206                 :            : #endif /* EFSYS_OPT_MEDFORD2 */
     207                 :            : 
     208                 :            : #if EFSYS_OPT_RIVERHEAD
     209                 :            : static const efx_tx_ops_t       __efx_tx_rhead_ops = {
     210                 :            :         rhead_tx_init,                          /* etxo_init */
     211                 :            :         rhead_tx_fini,                          /* etxo_fini */
     212                 :            :         rhead_tx_qcreate,                       /* etxo_qcreate */
     213                 :            :         rhead_tx_qdestroy,                      /* etxo_qdestroy */
     214                 :            :         rhead_tx_qpost,                         /* etxo_qpost */
     215                 :            :         rhead_tx_qpush,                         /* etxo_qpush */
     216                 :            :         rhead_tx_qpace,                         /* etxo_qpace */
     217                 :            :         rhead_tx_qflush,                        /* etxo_qflush */
     218                 :            :         rhead_tx_qenable,                       /* etxo_qenable */
     219                 :            :         NULL,                                   /* etxo_qpio_enable */
     220                 :            :         NULL,                                   /* etxo_qpio_disable */
     221                 :            :         NULL,                                   /* etxo_qpio_write */
     222                 :            :         NULL,                                   /* etxo_qpio_post */
     223                 :            :         rhead_tx_qdesc_post,                    /* etxo_qdesc_post */
     224                 :            :         NULL,                                   /* etxo_qdesc_dma_create */
     225                 :            :         NULL,                                   /* etxo_qdesc_tso_create */
     226                 :            :         NULL,                                   /* etxo_qdesc_tso2_create */
     227                 :            :         NULL,                                   /* etxo_qdesc_vlantci_create */
     228                 :            :         NULL,                                   /* etxo_qdesc_checksum_create */
     229                 :            : #if EFSYS_OPT_QSTATS
     230                 :            :         rhead_tx_qstats_update,                 /* etxo_qstats_update */
     231                 :            : #endif
     232                 :            : };
     233                 :            : #endif /* EFSYS_OPT_RIVERHEAD */
     234                 :            : 
     235                 :            : 
     236                 :            :         __checkReturn   efx_rc_t
     237                 :          0 : efx_tx_init(
     238                 :            :         __in            efx_nic_t *enp)
     239                 :            : {
     240                 :            :         const efx_tx_ops_t *etxop;
     241                 :            :         efx_rc_t rc;
     242                 :            : 
     243         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     244         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
     245                 :            : 
     246         [ #  # ]:          0 :         if (!(enp->en_mod_flags & EFX_MOD_EV)) {
     247                 :            :                 rc = EINVAL;
     248                 :          0 :                 goto fail1;
     249                 :            :         }
     250                 :            : 
     251         [ #  # ]:          0 :         if (enp->en_mod_flags & EFX_MOD_TX) {
     252                 :            :                 rc = EINVAL;
     253                 :          0 :                 goto fail2;
     254                 :            :         }
     255                 :            : 
     256   [ #  #  #  #  :          0 :         switch (enp->en_family) {
                      # ]
     257                 :            : #if EFSYS_OPT_SIENA
     258                 :            :         case EFX_FAMILY_SIENA:
     259                 :            :                 etxop = &__efx_tx_siena_ops;
     260                 :            :                 break;
     261                 :            : #endif /* EFSYS_OPT_SIENA */
     262                 :            : 
     263                 :            : #if EFSYS_OPT_HUNTINGTON
     264                 :            :         case EFX_FAMILY_HUNTINGTON:
     265                 :            :                 etxop = &__efx_tx_hunt_ops;
     266                 :            :                 break;
     267                 :            : #endif /* EFSYS_OPT_HUNTINGTON */
     268                 :            : 
     269                 :            : #if EFSYS_OPT_MEDFORD
     270                 :          0 :         case EFX_FAMILY_MEDFORD:
     271                 :            :                 etxop = &__efx_tx_medford_ops;
     272                 :          0 :                 break;
     273                 :            : #endif /* EFSYS_OPT_MEDFORD */
     274                 :            : 
     275                 :            : #if EFSYS_OPT_MEDFORD2
     276                 :          0 :         case EFX_FAMILY_MEDFORD2:
     277                 :            :                 etxop = &__efx_tx_medford2_ops;
     278                 :          0 :                 break;
     279                 :            : #endif /* EFSYS_OPT_MEDFORD2 */
     280                 :            : 
     281                 :            : #if EFSYS_OPT_RIVERHEAD
     282                 :          0 :         case EFX_FAMILY_RIVERHEAD:
     283                 :            :                 etxop = &__efx_tx_rhead_ops;
     284                 :          0 :                 break;
     285                 :            : #endif /* EFSYS_OPT_RIVERHEAD */
     286                 :            : 
     287                 :            :         default:
     288                 :          0 :                 EFSYS_ASSERT(0);
     289                 :            :                 rc = ENOTSUP;
     290                 :            :                 goto fail3;
     291                 :            :         }
     292                 :            : 
     293         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
     294                 :            : 
     295         [ #  # ]:          0 :         if ((rc = etxop->etxo_init(enp)) != 0)
     296                 :          0 :                 goto fail4;
     297                 :            : 
     298                 :          0 :         enp->en_etxop = etxop;
     299                 :          0 :         enp->en_mod_flags |= EFX_MOD_TX;
     300                 :          0 :         return (0);
     301                 :            : 
     302                 :            : fail4:
     303                 :            :         EFSYS_PROBE(fail4);
     304                 :          0 : fail3:
     305                 :            :         EFSYS_PROBE(fail3);
     306                 :          0 : fail2:
     307                 :            :         EFSYS_PROBE(fail2);
     308                 :          0 : fail1:
     309                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     310                 :            : 
     311                 :          0 :         enp->en_etxop = NULL;
     312                 :          0 :         enp->en_mod_flags &= ~EFX_MOD_TX;
     313                 :          0 :         return (rc);
     314                 :            : }
     315                 :            : 
     316                 :            :                         void
     317                 :          0 : efx_tx_fini(
     318                 :            :         __in    efx_nic_t *enp)
     319                 :            : {
     320                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     321                 :            : 
     322         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     323         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
     324         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
     325         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
     326                 :            : 
     327                 :          0 :         etxop->etxo_fini(enp);
     328                 :            : 
     329                 :          0 :         enp->en_etxop = NULL;
     330                 :          0 :         enp->en_mod_flags &= ~EFX_MOD_TX;
     331                 :          0 : }
     332                 :            : 
     333                 :            :         __checkReturn   size_t
     334                 :          0 : efx_txq_size(
     335                 :            :         __in    const efx_nic_t *enp,
     336                 :            :         __in    unsigned int ndescs)
     337                 :            : {
     338                 :          0 :         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
     339                 :            : 
     340                 :          0 :         return (ndescs * encp->enc_tx_desc_size);
     341                 :            : }
     342                 :            : 
     343                 :            :         __checkReturn   unsigned int
     344                 :          0 : efx_txq_nbufs(
     345                 :            :         __in    const efx_nic_t *enp,
     346                 :            :         __in    unsigned int ndescs)
     347                 :            : {
     348                 :          0 :         return (EFX_DIV_ROUND_UP(efx_txq_size(enp, ndescs), EFX_BUF_SIZE));
     349                 :            : }
     350                 :            : 
     351                 :            :         __checkReturn   efx_rc_t
     352                 :          0 : efx_tx_qcreate(
     353                 :            :         __in            efx_nic_t *enp,
     354                 :            :         __in            unsigned int index,
     355                 :            :         __in            unsigned int label,
     356                 :            :         __in            efsys_mem_t *esmp,
     357                 :            :         __in            size_t ndescs,
     358                 :            :         __in            uint32_t id,
     359                 :            :         __in            uint16_t flags,
     360                 :            :         __in            efx_evq_t *eep,
     361                 :            :         __deref_out     efx_txq_t **etpp,
     362                 :            :         __out           unsigned int *addedp)
     363                 :            : {
     364                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     365                 :            :         efx_txq_t *etp;
     366                 :          0 :         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
     367                 :            :         efx_rc_t rc;
     368                 :            : 
     369         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
     370         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
     371                 :            : 
     372         [ #  # ]:          0 :         EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <,
     373                 :            :             enp->en_nic_cfg.enc_txq_limit);
     374                 :            : 
     375   [ #  #  #  # ]:          0 :         EFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));
     376   [ #  #  #  # ]:          0 :         EFSYS_ASSERT(ISP2(encp->enc_txq_min_ndescs));
     377                 :            : 
     378         [ #  # ]:          0 :         if (!ISP2(ndescs) ||
     379         [ #  # ]:          0 :             ndescs < encp->enc_txq_min_ndescs ||
     380         [ #  # ]:          0 :             ndescs > encp->enc_txq_max_ndescs) {
     381                 :            :                 rc = EINVAL;
     382                 :          0 :                 goto fail1;
     383                 :            :         }
     384                 :            : 
     385                 :            :         /* Allocate an TXQ object */
     386                 :          0 :         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
     387                 :            : 
     388         [ #  # ]:          0 :         if (etp == NULL) {
     389                 :            :                 rc = ENOMEM;
     390                 :          0 :                 goto fail2;
     391                 :            :         }
     392                 :            : 
     393                 :          0 :         etp->et_magic = EFX_TXQ_MAGIC;
     394                 :          0 :         etp->et_enp = enp;
     395                 :          0 :         etp->et_index = index;
     396                 :          0 :         etp->et_mask = ndescs - 1;
     397                 :          0 :         etp->et_esmp = esmp;
     398                 :            : 
     399                 :            :         /* Initial descriptor index may be modified by etxo_qcreate */
     400                 :          0 :         *addedp = 0;
     401                 :            : 
     402         [ #  # ]:          0 :         if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
     403                 :            :             ndescs, id, flags, eep, etp, addedp)) != 0)
     404                 :          0 :                 goto fail3;
     405                 :            : 
     406                 :          0 :         enp->en_tx_qcount++;
     407                 :          0 :         *etpp = etp;
     408                 :            : 
     409                 :          0 :         return (0);
     410                 :            : 
     411                 :            : fail3:
     412                 :            :         EFSYS_PROBE(fail3);
     413                 :          0 :         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
     414                 :            : fail2:
     415                 :            :         EFSYS_PROBE(fail2);
     416                 :            : fail1:
     417                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     418                 :            :         return (rc);
     419                 :            : }
     420                 :            : 
     421                 :            :                 void
     422                 :          0 : efx_tx_qdestroy(
     423                 :            :         __in    efx_txq_t *etp)
     424                 :            : {
     425                 :          0 :         efx_nic_t *enp = etp->et_enp;
     426                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     427                 :            : 
     428         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     429                 :            : 
     430         [ #  # ]:          0 :         EFSYS_ASSERT(enp->en_tx_qcount != 0);
     431                 :          0 :         --enp->en_tx_qcount;
     432                 :            : 
     433                 :          0 :         etxop->etxo_qdestroy(etp);
     434                 :            : 
     435                 :            :         /* Free the TXQ object */
     436                 :          0 :         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
     437                 :          0 : }
     438                 :            : 
     439                 :            :         __checkReturn           efx_rc_t
     440                 :          0 : efx_tx_qpost(
     441                 :            :         __in                    efx_txq_t *etp,
     442                 :            :         __in_ecount(ndescs)     efx_buffer_t *eb,
     443                 :            :         __in                    unsigned int ndescs,
     444                 :            :         __in                    unsigned int completed,
     445                 :            :         __inout                 unsigned int *addedp)
     446                 :            : {
     447                 :          0 :         efx_nic_t *enp = etp->et_enp;
     448                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     449                 :            :         efx_rc_t rc;
     450                 :            : 
     451         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     452                 :            : 
     453         [ #  # ]:          0 :         if ((rc = etxop->etxo_qpost(etp, eb, ndescs, completed, addedp)) != 0)
     454                 :          0 :                 goto fail1;
     455                 :            : 
     456                 :            :         return (0);
     457                 :            : 
     458                 :            : fail1:
     459                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     460                 :          0 :         return (rc);
     461                 :            : }
     462                 :            : 
     463                 :            :                         void
     464                 :          0 : efx_tx_qpush(
     465                 :            :         __in    efx_txq_t *etp,
     466                 :            :         __in    unsigned int added,
     467                 :            :         __in    unsigned int pushed)
     468                 :            : {
     469                 :          0 :         efx_nic_t *enp = etp->et_enp;
     470                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     471                 :            : 
     472         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     473                 :            : 
     474                 :          0 :         etxop->etxo_qpush(etp, added, pushed);
     475                 :          0 : }
     476                 :            : 
     477                 :            :         __checkReturn   efx_rc_t
     478                 :          0 : efx_tx_qpace(
     479                 :            :         __in            efx_txq_t *etp,
     480                 :            :         __in            unsigned int ns)
     481                 :            : {
     482                 :          0 :         efx_nic_t *enp = etp->et_enp;
     483                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     484                 :            :         efx_rc_t rc;
     485                 :            : 
     486         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     487                 :            : 
     488         [ #  # ]:          0 :         if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
     489                 :          0 :                 goto fail1;
     490                 :            : 
     491                 :            :         return (0);
     492                 :            : 
     493                 :            : fail1:
     494                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     495                 :          0 :         return (rc);
     496                 :            : }
     497                 :            : 
     498                 :            :         __checkReturn   efx_rc_t
     499                 :          0 : efx_tx_qflush(
     500                 :            :         __in    efx_txq_t *etp)
     501                 :            : {
     502                 :          0 :         efx_nic_t *enp = etp->et_enp;
     503                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     504                 :            :         efx_rc_t rc;
     505                 :            : 
     506         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     507                 :            : 
     508         [ #  # ]:          0 :         if ((rc = etxop->etxo_qflush(etp)) != 0)
     509                 :          0 :                 goto fail1;
     510                 :            : 
     511                 :            :         return (0);
     512                 :            : 
     513                 :            : fail1:
     514                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     515                 :          0 :         return (rc);
     516                 :            : }
     517                 :            : 
     518                 :            :                         void
     519                 :          0 : efx_tx_qenable(
     520                 :            :         __in    efx_txq_t *etp)
     521                 :            : {
     522                 :          0 :         efx_nic_t *enp = etp->et_enp;
     523                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     524                 :            : 
     525         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     526                 :            : 
     527                 :          0 :         etxop->etxo_qenable(etp);
     528                 :          0 : }
     529                 :            : 
     530                 :            :         __checkReturn   efx_rc_t
     531                 :          0 : efx_tx_qpio_enable(
     532                 :            :         __in    efx_txq_t *etp)
     533                 :            : {
     534                 :          0 :         efx_nic_t *enp = etp->et_enp;
     535                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     536                 :            :         efx_rc_t rc;
     537                 :            : 
     538         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     539                 :            : 
     540         [ #  # ]:          0 :         if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
     541                 :            :                 rc = ENOTSUP;
     542                 :          0 :                 goto fail1;
     543                 :            :         }
     544         [ #  # ]:          0 :         if (etxop->etxo_qpio_enable == NULL) {
     545                 :            :                 rc = ENOTSUP;
     546                 :          0 :                 goto fail2;
     547                 :            :         }
     548         [ #  # ]:          0 :         if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
     549                 :          0 :                 goto fail3;
     550                 :            : 
     551                 :            :         return (0);
     552                 :            : 
     553                 :            : fail3:
     554                 :            :         EFSYS_PROBE(fail3);
     555                 :            : fail2:
     556                 :            :         EFSYS_PROBE(fail2);
     557                 :            : fail1:
     558                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     559                 :            :         return (rc);
     560                 :            : }
     561                 :            : 
     562                 :            :                 void
     563                 :          0 : efx_tx_qpio_disable(
     564                 :            :         __in    efx_txq_t *etp)
     565                 :            : {
     566                 :          0 :         efx_nic_t *enp = etp->et_enp;
     567                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     568                 :            : 
     569         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     570                 :            : 
     571         [ #  # ]:          0 :         if (etxop->etxo_qpio_disable != NULL)
     572                 :          0 :                 etxop->etxo_qpio_disable(etp);
     573                 :          0 : }
     574                 :            : 
     575                 :            :         __checkReturn   efx_rc_t
     576                 :          0 : efx_tx_qpio_write(
     577                 :            :         __in                    efx_txq_t *etp,
     578                 :            :         __in_ecount(buf_length) uint8_t *buffer,
     579                 :            :         __in                    size_t buf_length,
     580                 :            :         __in                    size_t pio_buf_offset)
     581                 :            : {
     582                 :          0 :         efx_nic_t *enp = etp->et_enp;
     583                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     584                 :            :         efx_rc_t rc;
     585                 :            : 
     586         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     587                 :            : 
     588         [ #  # ]:          0 :         if (etxop->etxo_qpio_write != NULL) {
     589         [ #  # ]:          0 :                 if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
     590                 :            :                                                 pio_buf_offset)) != 0)
     591                 :          0 :                         goto fail1;
     592                 :            :                 return (0);
     593                 :            :         }
     594                 :            : 
     595                 :            :         return (ENOTSUP);
     596                 :            : 
     597                 :            : fail1:
     598                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     599                 :          0 :         return (rc);
     600                 :            : }
     601                 :            : 
     602                 :            :         __checkReturn   efx_rc_t
     603                 :          0 : efx_tx_qpio_post(
     604                 :            :         __in                    efx_txq_t *etp,
     605                 :            :         __in                    size_t pkt_length,
     606                 :            :         __in                    unsigned int completed,
     607                 :            :         __inout                 unsigned int *addedp)
     608                 :            : {
     609                 :          0 :         efx_nic_t *enp = etp->et_enp;
     610                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     611                 :            :         efx_rc_t rc;
     612                 :            : 
     613         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     614                 :            : 
     615         [ #  # ]:          0 :         if (etxop->etxo_qpio_post != NULL) {
     616         [ #  # ]:          0 :                 if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
     617                 :            :                                                 addedp)) != 0)
     618                 :          0 :                         goto fail1;
     619                 :            :                 return (0);
     620                 :            :         }
     621                 :            : 
     622                 :            :         return (ENOTSUP);
     623                 :            : 
     624                 :            : fail1:
     625                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     626                 :          0 :         return (rc);
     627                 :            : }
     628                 :            : 
     629                 :            :         __checkReturn           efx_rc_t
     630                 :          0 : efx_tx_qdesc_post(
     631                 :            :         __in                    efx_txq_t *etp,
     632                 :            :         __in_ecount(ndescs)     efx_desc_t *ed,
     633                 :            :         __in                    unsigned int ndescs,
     634                 :            :         __in                    unsigned int completed,
     635                 :            :         __inout                 unsigned int *addedp)
     636                 :            : {
     637                 :          0 :         efx_nic_t *enp = etp->et_enp;
     638                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     639                 :            : 
     640         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     641                 :            : 
     642                 :          0 :         return (etxop->etxo_qdesc_post(etp, ed, ndescs, completed, addedp));
     643                 :            : }
     644                 :            : 
     645                 :            :         void
     646                 :          0 : efx_tx_qdesc_dma_create(
     647                 :            :         __in    efx_txq_t *etp,
     648                 :            :         __in    efsys_dma_addr_t addr,
     649                 :            :         __in    size_t size,
     650                 :            :         __in    boolean_t eop,
     651                 :            :         __out   efx_desc_t *edp)
     652                 :            : {
     653                 :          0 :         efx_nic_t *enp = etp->et_enp;
     654                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     655                 :            : 
     656         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     657         [ #  # ]:          0 :         EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
     658                 :            : 
     659                 :          0 :         etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
     660                 :          0 : }
     661                 :            : 
     662                 :            :         void
     663                 :          0 : efx_tx_qdesc_tso_create(
     664                 :            :         __in    efx_txq_t *etp,
     665                 :            :         __in    uint16_t ipv4_id,
     666                 :            :         __in    uint32_t tcp_seq,
     667                 :            :         __in    uint8_t  tcp_flags,
     668                 :            :         __out   efx_desc_t *edp)
     669                 :            : {
     670                 :          0 :         efx_nic_t *enp = etp->et_enp;
     671                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     672                 :            : 
     673         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     674         [ #  # ]:          0 :         EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
     675                 :            : 
     676                 :          0 :         etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
     677                 :          0 : }
     678                 :            : 
     679                 :            :         void
     680                 :          0 : efx_tx_qdesc_tso2_create(
     681                 :            :         __in                    efx_txq_t *etp,
     682                 :            :         __in                    uint16_t ipv4_id,
     683                 :            :         __in                    uint16_t outer_ipv4_id,
     684                 :            :         __in                    uint32_t tcp_seq,
     685                 :            :         __in                    uint16_t mss,
     686                 :            :         __out_ecount(count)     efx_desc_t *edp,
     687                 :            :         __in                    int count)
     688                 :            : {
     689                 :          0 :         efx_nic_t *enp = etp->et_enp;
     690                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     691                 :            : 
     692         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     693         [ #  # ]:          0 :         EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
     694                 :            : 
     695                 :          0 :         etxop->etxo_qdesc_tso2_create(etp, ipv4_id, outer_ipv4_id,
     696                 :            :             tcp_seq, mss, edp, count);
     697                 :          0 : }
     698                 :            : 
     699                 :            :         void
     700                 :          0 : efx_tx_qdesc_vlantci_create(
     701                 :            :         __in    efx_txq_t *etp,
     702                 :            :         __in    uint16_t tci,
     703                 :            :         __out   efx_desc_t *edp)
     704                 :            : {
     705                 :          0 :         efx_nic_t *enp = etp->et_enp;
     706                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     707                 :            : 
     708         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     709         [ #  # ]:          0 :         EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
     710                 :            : 
     711                 :          0 :         etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
     712                 :          0 : }
     713                 :            : 
     714                 :            :         void
     715                 :          0 : efx_tx_qdesc_checksum_create(
     716                 :            :         __in    efx_txq_t *etp,
     717                 :            :         __in    uint16_t flags,
     718                 :            :         __out   efx_desc_t *edp)
     719                 :            : {
     720                 :          0 :         efx_nic_t *enp = etp->et_enp;
     721                 :          0 :         const efx_tx_ops_t *etxop = enp->en_etxop;
     722                 :            : 
     723         [ #  # ]:          0 :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     724         [ #  # ]:          0 :         EFSYS_ASSERT(etxop->etxo_qdesc_checksum_create != NULL);
     725                 :            : 
     726                 :          0 :         etxop->etxo_qdesc_checksum_create(etp, flags, edp);
     727                 :          0 : }
     728                 :            : 
     729                 :            : 
     730                 :            : #if EFSYS_OPT_QSTATS
     731                 :            :                         void
     732                 :            : efx_tx_qstats_update(
     733                 :            :         __in                            efx_txq_t *etp,
     734                 :            :         __inout_ecount(TX_NQSTATS)      efsys_stat_t *stat)
     735                 :            : {
     736                 :            :         efx_nic_t *enp = etp->et_enp;
     737                 :            :         const efx_tx_ops_t *etxop = enp->en_etxop;
     738                 :            : 
     739                 :            :         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
     740                 :            : 
     741                 :            :         etxop->etxo_qstats_update(etp, stat);
     742                 :            : }
     743                 :            : #endif
     744                 :            : 
     745                 :            : 
     746                 :            : #if EFSYS_OPT_SIENA
     747                 :            : 
     748                 :            : static  __checkReturn   efx_rc_t
     749                 :            : siena_tx_init(
     750                 :            :         __in            efx_nic_t *enp)
     751                 :            : {
     752                 :            :         efx_oword_t oword;
     753                 :            : 
     754                 :            :         /*
     755                 :            :          * Disable the timer-based TX DMA backoff and allow TX DMA to be
     756                 :            :          * controlled by the RX FIFO fill level (although always allow a
     757                 :            :          * minimal trickle).
     758                 :            :          */
     759                 :            :         EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);
     760                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);
     761                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);
     762                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
     763                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);
     764                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);
     765                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);
     766                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
     767                 :            : 
     768                 :            :         /*
     769                 :            :          * Filter all packets less than 14 bytes to avoid parsing
     770                 :            :          * errors.
     771                 :            :          */
     772                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
     773                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);
     774                 :            : 
     775                 :            :         /*
     776                 :            :          * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
     777                 :            :          * descriptors (which is bad).
     778                 :            :          */
     779                 :            :         EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
     780                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
     781                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
     782                 :            : 
     783                 :            :         return (0);
     784                 :            : }
     785                 :            : 
     786                 :            : #define EFX_TX_DESC(_etp, _addr, _size, _eop, _added)                   \
     787                 :            :         do {                                                            \
     788                 :            :                 unsigned int id;                                        \
     789                 :            :                 size_t offset;                                          \
     790                 :            :                 efx_qword_t qword;                                      \
     791                 :            :                                                                         \
     792                 :            :                 id = (_added)++ & (_etp)->et_mask;                       \
     793                 :            :                 offset = id * sizeof (efx_qword_t);                     \
     794                 :            :                                                                         \
     795                 :            :                 EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index,        \
     796                 :            :                     unsigned int, id, efsys_dma_addr_t, (_addr),        \
     797                 :            :                     size_t, (_size), boolean_t, (_eop));                \
     798                 :            :                                                                         \
     799                 :            :                 EFX_POPULATE_QWORD_4(qword,                             \
     800                 :            :                     FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1,                 \
     801                 :            :                     FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size),        \
     802                 :            :                     FSF_AZ_TX_KER_BUF_ADDR_DW0,                         \
     803                 :            :                     (uint32_t)((_addr) & 0xffffffff),                       \
     804                 :            :                     FSF_AZ_TX_KER_BUF_ADDR_DW1,                         \
     805                 :            :                     (uint32_t)((_addr) >> 32));                           \
     806                 :            :                 EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword);       \
     807                 :            :                                                                         \
     808                 :            :                 _NOTE(CONSTANTCONDITION)                                \
     809                 :            :         } while (B_FALSE)
     810                 :            : 
     811                 :            : static  __checkReturn           efx_rc_t
     812                 :            : siena_tx_qpost(
     813                 :            :         __in                    efx_txq_t *etp,
     814                 :            :         __in_ecount(ndescs)     efx_buffer_t *eb,
     815                 :            :         __in                    unsigned int ndescs,
     816                 :            :         __in                    unsigned int completed,
     817                 :            :         __inout                 unsigned int *addedp)
     818                 :            : {
     819                 :            :         unsigned int added = *addedp;
     820                 :            :         unsigned int i;
     821                 :            : 
     822                 :            :         if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1))
     823                 :            :                 return (ENOSPC);
     824                 :            : 
     825                 :            :         for (i = 0; i < ndescs; i++) {
     826                 :            :                 efx_buffer_t *ebp = &eb[i];
     827                 :            :                 efsys_dma_addr_t start = ebp->eb_addr;
     828                 :            :                 size_t size = ebp->eb_size;
     829                 :            :                 efsys_dma_addr_t end = start + size;
     830                 :            : 
     831                 :            :                 /*
     832                 :            :                  * Fragments must not span 4k boundaries.
     833                 :            :                  * Here it is a stricter requirement than the maximum length.
     834                 :            :                  */
     835                 :            :                 EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, start + 1,
     836                 :            :                     etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= end);
     837                 :            : 
     838                 :            :                 EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
     839                 :            :         }
     840                 :            : 
     841                 :            :         EFX_TX_QSTAT_INCR(etp, TX_POST);
     842                 :            : 
     843                 :            :         *addedp = added;
     844                 :            :         return (0);
     845                 :            : }
     846                 :            : 
     847                 :            : static          void
     848                 :            : siena_tx_qpush(
     849                 :            :         __in    efx_txq_t *etp,
     850                 :            :         __in    unsigned int added,
     851                 :            :         __in    unsigned int pushed)
     852                 :            : {
     853                 :            :         efx_nic_t *enp = etp->et_enp;
     854                 :            :         uint32_t wptr;
     855                 :            :         efx_dword_t dword;
     856                 :            :         efx_oword_t oword;
     857                 :            : 
     858                 :            :         /* Push the populated descriptors out */
     859                 :            :         wptr = added & etp->et_mask;
     860                 :            : 
     861                 :            :         EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
     862                 :            : 
     863                 :            :         /* Only write the third DWORD */
     864                 :            :         EFX_POPULATE_DWORD_1(dword,
     865                 :            :             EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
     866                 :            : 
     867                 :            :         /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
     868                 :            :         EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
     869                 :            :             SIENA_TXQ_DESC_SIZE, wptr, pushed & etp->et_mask);
     870                 :            :         EFSYS_PIO_WRITE_BARRIER();
     871                 :            :         EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
     872                 :            :                             etp->et_index, &dword, B_FALSE);
     873                 :            : }
     874                 :            : 
     875                 :            : #define EFX_MAX_PACE_VALUE 20
     876                 :            : 
     877                 :            : static  __checkReturn   efx_rc_t
     878                 :            : siena_tx_qpace(
     879                 :            :         __in            efx_txq_t *etp,
     880                 :            :         __in            unsigned int ns)
     881                 :            : {
     882                 :            :         efx_nic_t *enp = etp->et_enp;
     883                 :            :         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
     884                 :            :         efx_oword_t oword;
     885                 :            :         unsigned int pace_val;
     886                 :            :         unsigned int timer_period;
     887                 :            :         efx_rc_t rc;
     888                 :            : 
     889                 :            :         if (ns == 0) {
     890                 :            :                 pace_val = 0;
     891                 :            :         } else {
     892                 :            :                 /*
     893                 :            :                  * The pace_val to write into the table is s.t
     894                 :            :                  * ns <= timer_period * (2 ^ pace_val)
     895                 :            :                  */
     896                 :            :                 timer_period = 104 / encp->enc_clk_mult;
     897                 :            :                 for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
     898                 :            :                         if ((timer_period << pace_val) >= ns)
     899                 :            :                                 break;
     900                 :            :                 }
     901                 :            :         }
     902                 :            :         if (pace_val > EFX_MAX_PACE_VALUE) {
     903                 :            :                 rc = EINVAL;
     904                 :            :                 goto fail1;
     905                 :            :         }
     906                 :            : 
     907                 :            :         /* Update the pacing table */
     908                 :            :         EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
     909                 :            :         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
     910                 :            :             &oword, B_TRUE);
     911                 :            : 
     912                 :            :         return (0);
     913                 :            : 
     914                 :            : fail1:
     915                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
     916                 :            : 
     917                 :            :         return (rc);
     918                 :            : }
     919                 :            : 
     920                 :            : static  __checkReturn   efx_rc_t
     921                 :            : siena_tx_qflush(
     922                 :            :         __in            efx_txq_t *etp)
     923                 :            : {
     924                 :            :         efx_nic_t *enp = etp->et_enp;
     925                 :            :         efx_oword_t oword;
     926                 :            :         uint32_t label;
     927                 :            : 
     928                 :            :         efx_tx_qpace(etp, 0);
     929                 :            : 
     930                 :            :         label = etp->et_index;
     931                 :            : 
     932                 :            :         /* Flush the queue */
     933                 :            :         EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
     934                 :            :             FRF_AZ_TX_FLUSH_DESCQ, label);
     935                 :            :         EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
     936                 :            : 
     937                 :            :         return (0);
     938                 :            : }
     939                 :            : 
     940                 :            : static          void
     941                 :            : siena_tx_qenable(
     942                 :            :         __in    efx_txq_t *etp)
     943                 :            : {
     944                 :            :         efx_nic_t *enp = etp->et_enp;
     945                 :            :         efx_oword_t oword;
     946                 :            : 
     947                 :            :         EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
     948                 :            :                             etp->et_index, &oword, B_TRUE);
     949                 :            : 
     950                 :            :         EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
     951                 :            :             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
     952                 :            :             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),
     953                 :            :             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),
     954                 :            :             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));
     955                 :            : 
     956                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);
     957                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);
     958                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
     959                 :            : 
     960                 :            :         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
     961                 :            :                             etp->et_index, &oword, B_TRUE);
     962                 :            : }
     963                 :            : 
     964                 :            : static  __checkReturn   efx_rc_t
     965                 :            : siena_tx_qcreate(
     966                 :            :         __in            efx_nic_t *enp,
     967                 :            :         __in            unsigned int index,
     968                 :            :         __in            unsigned int label,
     969                 :            :         __in            efsys_mem_t *esmp,
     970                 :            :         __in            size_t ndescs,
     971                 :            :         __in            uint32_t id,
     972                 :            :         __in            uint16_t flags,
     973                 :            :         __in            efx_evq_t *eep,
     974                 :            :         __in            efx_txq_t *etp,
     975                 :            :         __out           unsigned int *addedp)
     976                 :            : {
     977                 :            :         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
     978                 :            :         efx_oword_t oword;
     979                 :            :         uint32_t size;
     980                 :            :         uint16_t inner_csum;
     981                 :            :         efx_rc_t rc;
     982                 :            : 
     983                 :            :         _NOTE(ARGUNUSED(esmp))
     984                 :            : 
     985                 :            :         EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
     986                 :            :             (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
     987                 :            :         EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
     988                 :            : 
     989                 :            :         if (index >= encp->enc_txq_limit) {
     990                 :            :                 rc = EINVAL;
     991                 :            :                 goto fail1;
     992                 :            :         }
     993                 :            :         for (size = 0;
     994                 :            :             (1U << size) <= encp->enc_txq_max_ndescs / encp->enc_txq_min_ndescs;
     995                 :            :             size++)
     996                 :            :                 if ((1U << size) == (uint32_t)ndescs / encp->enc_txq_min_ndescs)
     997                 :            :                         break;
     998                 :            :         if (id + (1 << size) >= encp->enc_buftbl_limit) {
     999                 :            :                 rc = EINVAL;
    1000                 :            :                 goto fail2;
    1001                 :            :         }
    1002                 :            : 
    1003                 :            :         inner_csum = EFX_TXQ_CKSUM_INNER_IPV4 | EFX_TXQ_CKSUM_INNER_TCPUDP;
    1004                 :            :         if ((flags & inner_csum) != 0) {
    1005                 :            :                 rc = EINVAL;
    1006                 :            :                 goto fail3;
    1007                 :            :         }
    1008                 :            : 
    1009                 :            :         /* Set up the new descriptor queue */
    1010                 :            :         *addedp = 0;
    1011                 :            : 
    1012                 :            :         EFX_POPULATE_OWORD_6(oword,
    1013                 :            :             FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
    1014                 :            :             FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,
    1015                 :            :             FRF_AZ_TX_DESCQ_OWNER_ID, 0,
    1016                 :            :             FRF_AZ_TX_DESCQ_LABEL, label,
    1017                 :            :             FRF_AZ_TX_DESCQ_SIZE, size,
    1018                 :            :             FRF_AZ_TX_DESCQ_TYPE, 0);
    1019                 :            : 
    1020                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);
    1021                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,
    1022                 :            :             (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);
    1023                 :            :         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,
    1024                 :            :             (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);
    1025                 :            : 
    1026                 :            :         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
    1027                 :            :             etp->et_index, &oword, B_TRUE);
    1028                 :            : 
    1029                 :            :         return (0);
    1030                 :            : 
    1031                 :            : fail3:
    1032                 :            :         EFSYS_PROBE(fail3);
    1033                 :            : fail2:
    1034                 :            :         EFSYS_PROBE(fail2);
    1035                 :            : fail1:
    1036                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
    1037                 :            : 
    1038                 :            :         return (rc);
    1039                 :            : }
    1040                 :            : 
    1041                 :            :         __checkReturn           efx_rc_t
    1042                 :            : siena_tx_qdesc_post(
    1043                 :            :         __in                    efx_txq_t *etp,
    1044                 :            :         __in_ecount(ndescs)     efx_desc_t *ed,
    1045                 :            :         __in                    unsigned int ndescs,
    1046                 :            :         __in                    unsigned int completed,
    1047                 :            :         __inout                 unsigned int *addedp)
    1048                 :            : {
    1049                 :            :         unsigned int added = *addedp;
    1050                 :            :         unsigned int i;
    1051                 :            :         efx_rc_t rc;
    1052                 :            : 
    1053                 :            :         if (added - completed + ndescs > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
    1054                 :            :                 rc = ENOSPC;
    1055                 :            :                 goto fail1;
    1056                 :            :         }
    1057                 :            : 
    1058                 :            :         for (i = 0; i < ndescs; i++) {
    1059                 :            :                 efx_desc_t *edp = &ed[i];
    1060                 :            :                 unsigned int id;
    1061                 :            :                 size_t offset;
    1062                 :            : 
    1063                 :            :                 id = added++ & etp->et_mask;
    1064                 :            :                 offset = id * sizeof (efx_desc_t);
    1065                 :            : 
    1066                 :            :                 EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
    1067                 :            :         }
    1068                 :            : 
    1069                 :            :         EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
    1070                 :            :                     unsigned int, added, unsigned int, ndescs);
    1071                 :            : 
    1072                 :            :         EFX_TX_QSTAT_INCR(etp, TX_POST);
    1073                 :            : 
    1074                 :            :         *addedp = added;
    1075                 :            :         return (0);
    1076                 :            : 
    1077                 :            : fail1:
    1078                 :            :         EFSYS_PROBE1(fail1, efx_rc_t, rc);
    1079                 :            :         return (rc);
    1080                 :            : }
    1081                 :            : 
    1082                 :            :         void
    1083                 :            : siena_tx_qdesc_dma_create(
    1084                 :            :         __in    efx_txq_t *etp,
    1085                 :            :         __in    efsys_dma_addr_t addr,
    1086                 :            :         __in    size_t size,
    1087                 :            :         __in    boolean_t eop,
    1088                 :            :         __out   efx_desc_t *edp)
    1089                 :            : {
    1090                 :            :         /*
    1091                 :            :          * Fragments must not span 4k boundaries.
    1092                 :            :          * Here it is a stricter requirement than the maximum length.
    1093                 :            :          */
    1094                 :            :         EFSYS_ASSERT(EFX_P2ROUNDUP(efsys_dma_addr_t, addr + 1,
    1095                 :            :             etp->et_enp->en_nic_cfg.enc_tx_dma_desc_boundary) >= addr + size);
    1096                 :            : 
    1097                 :            :         EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
    1098                 :            :                     efsys_dma_addr_t, addr,
    1099                 :            :                     size_t, size, boolean_t, eop);
    1100                 :            : 
    1101                 :            :         EFX_POPULATE_QWORD_4(edp->ed_eq,
    1102                 :            :                             FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
    1103                 :            :                             FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
    1104                 :            :                             FSF_AZ_TX_KER_BUF_ADDR_DW0,
    1105                 :            :                             (uint32_t)(addr & 0xffffffff),
    1106                 :            :                             FSF_AZ_TX_KER_BUF_ADDR_DW1,
    1107                 :            :                             (uint32_t)(addr >> 32));
    1108                 :            : }
    1109                 :            : 
    1110                 :            : #endif /* EFSYS_OPT_SIENA */
    1111                 :            : 
    1112                 :            : #if EFSYS_OPT_QSTATS
    1113                 :            : #if EFSYS_OPT_NAMES
    1114                 :            : /* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 2866874ecd7a363b */
    1115                 :            : static const char * const __efx_tx_qstat_name[] = {
    1116                 :            :         "post",
    1117                 :            :         "post_pio",
    1118                 :            : };
    1119                 :            : /* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
    1120                 :            : 
    1121                 :            :                 const char *
    1122                 :            : efx_tx_qstat_name(
    1123                 :            :         __in    efx_nic_t *enp,
    1124                 :            :         __in    unsigned int id)
    1125                 :            : {
    1126                 :            :         _NOTE(ARGUNUSED(enp))
    1127                 :            :         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
    1128                 :            :         EFSYS_ASSERT3U(id, <, TX_NQSTATS);
    1129                 :            : 
    1130                 :            :         return (__efx_tx_qstat_name[id]);
    1131                 :            : }
    1132                 :            : #endif  /* EFSYS_OPT_NAMES */
    1133                 :            : #endif /* EFSYS_OPT_QSTATS */
    1134                 :            : 
    1135                 :            : #if EFSYS_OPT_SIENA
    1136                 :            : 
    1137                 :            : #if EFSYS_OPT_QSTATS
    1138                 :            : static                                  void
    1139                 :            : siena_tx_qstats_update(
    1140                 :            :         __in                            efx_txq_t *etp,
    1141                 :            :         __inout_ecount(TX_NQSTATS)      efsys_stat_t *stat)
    1142                 :            : {
    1143                 :            :         unsigned int id;
    1144                 :            : 
    1145                 :            :         for (id = 0; id < TX_NQSTATS; id++) {
    1146                 :            :                 efsys_stat_t *essp = &stat[id];
    1147                 :            : 
    1148                 :            :                 EFSYS_STAT_INCR(essp, etp->et_stat[id]);
    1149                 :            :                 etp->et_stat[id] = 0;
    1150                 :            :         }
    1151                 :            : }
    1152                 :            : #endif  /* EFSYS_OPT_QSTATS */
    1153                 :            : 
    1154                 :            : static          void
    1155                 :            : siena_tx_qdestroy(
    1156                 :            :         __in    efx_txq_t *etp)
    1157                 :            : {
    1158                 :            :         efx_nic_t *enp = etp->et_enp;
    1159                 :            :         efx_oword_t oword;
    1160                 :            : 
    1161                 :            :         /* Purge descriptor queue */
    1162                 :            :         EFX_ZERO_OWORD(oword);
    1163                 :            : 
    1164                 :            :         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
    1165                 :            :                             etp->et_index, &oword, B_TRUE);
    1166                 :            : }
    1167                 :            : 
    1168                 :            : static          void
    1169                 :            : siena_tx_fini(
    1170                 :            :         __in    efx_nic_t *enp)
    1171                 :            : {
    1172                 :            :         _NOTE(ARGUNUSED(enp))
    1173                 :            : }
    1174                 :            : 
    1175                 :            : #endif /* EFSYS_OPT_SIENA */

Generated by: LCOV version 1.14