1*e948693eSPhilip Paeps /*- 2*e948693eSPhilip Paeps * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved. 3*e948693eSPhilip Paeps * 4*e948693eSPhilip Paeps * Redistribution and use in source and binary forms, with or without 5*e948693eSPhilip Paeps * modification, are permitted provided that the following conditions 6*e948693eSPhilip Paeps * are met: 7*e948693eSPhilip Paeps * 1. Redistributions of source code must retain the above copyright 8*e948693eSPhilip Paeps * notice, this list of conditions and the following disclaimer. 9*e948693eSPhilip Paeps * 2. Redistributions in binary form must reproduce the above copyright 10*e948693eSPhilip Paeps * notice, this list of conditions and the following disclaimer in the 11*e948693eSPhilip Paeps * documentation and/or other materials provided with the distribution. 12*e948693eSPhilip Paeps * 13*e948693eSPhilip Paeps * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14*e948693eSPhilip Paeps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15*e948693eSPhilip Paeps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16*e948693eSPhilip Paeps * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17*e948693eSPhilip Paeps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18*e948693eSPhilip Paeps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19*e948693eSPhilip Paeps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20*e948693eSPhilip Paeps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21*e948693eSPhilip Paeps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22*e948693eSPhilip Paeps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23*e948693eSPhilip Paeps * SUCH DAMAGE. 24*e948693eSPhilip Paeps */ 25*e948693eSPhilip Paeps 26*e948693eSPhilip Paeps #include "efsys.h" 27*e948693eSPhilip Paeps #include "efx.h" 28*e948693eSPhilip Paeps #include "efx_types.h" 29*e948693eSPhilip Paeps #include "efx_regs.h" 30*e948693eSPhilip Paeps #include "efx_impl.h" 31*e948693eSPhilip Paeps 32*e948693eSPhilip Paeps #if EFSYS_OPT_QSTATS 33*e948693eSPhilip Paeps #define EFX_TX_QSTAT_INCR(_etp, _stat) \ 34*e948693eSPhilip Paeps do { \ 35*e948693eSPhilip Paeps (_etp)->et_stat[_stat]++; \ 36*e948693eSPhilip Paeps _NOTE(CONSTANTCONDITION) \ 37*e948693eSPhilip Paeps } while (B_FALSE) 38*e948693eSPhilip Paeps #else 39*e948693eSPhilip Paeps #define EFX_TX_QSTAT_INCR(_etp, _stat) 40*e948693eSPhilip Paeps #endif 41*e948693eSPhilip Paeps 42*e948693eSPhilip Paeps __checkReturn int 43*e948693eSPhilip Paeps efx_tx_init( 44*e948693eSPhilip Paeps __in efx_nic_t *enp) 45*e948693eSPhilip Paeps { 46*e948693eSPhilip Paeps efx_oword_t oword; 47*e948693eSPhilip Paeps int rc; 48*e948693eSPhilip Paeps 49*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 50*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 51*e948693eSPhilip Paeps 52*e948693eSPhilip Paeps if (!(enp->en_mod_flags & EFX_MOD_EV)) { 53*e948693eSPhilip Paeps rc = EINVAL; 54*e948693eSPhilip Paeps goto fail1; 55*e948693eSPhilip Paeps } 56*e948693eSPhilip Paeps 57*e948693eSPhilip Paeps if (enp->en_mod_flags & EFX_MOD_TX) { 58*e948693eSPhilip Paeps rc = EINVAL; 59*e948693eSPhilip Paeps goto fail2; 60*e948693eSPhilip Paeps } 61*e948693eSPhilip Paeps 62*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0); 63*e948693eSPhilip Paeps 64*e948693eSPhilip Paeps /* 65*e948693eSPhilip Paeps * Disable the timer-based TX DMA backoff and allow TX DMA to be 66*e948693eSPhilip Paeps * controlled by the RX FIFO fill level (although always allow a 67*e948693eSPhilip Paeps * minimal trickle). 68*e948693eSPhilip Paeps */ 69*e948693eSPhilip Paeps EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword); 70*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe); 71*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1); 72*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1); 73*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0); 74*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1); 75*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2); 76*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff); 77*e948693eSPhilip Paeps 78*e948693eSPhilip Paeps /* 79*e948693eSPhilip Paeps * Filter all packets less than 14 bytes to avoid parsing 80*e948693eSPhilip Paeps * errors. 81*e948693eSPhilip Paeps */ 82*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); 83*e948693eSPhilip Paeps EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword); 84*e948693eSPhilip Paeps 85*e948693eSPhilip Paeps /* 86*e948693eSPhilip Paeps * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16 87*e948693eSPhilip Paeps * descriptors (which is bad). 88*e948693eSPhilip Paeps */ 89*e948693eSPhilip Paeps EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword); 90*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0); 91*e948693eSPhilip Paeps EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword); 92*e948693eSPhilip Paeps 93*e948693eSPhilip Paeps enp->en_mod_flags |= EFX_MOD_TX; 94*e948693eSPhilip Paeps return (0); 95*e948693eSPhilip Paeps 96*e948693eSPhilip Paeps fail2: 97*e948693eSPhilip Paeps EFSYS_PROBE(fail2); 98*e948693eSPhilip Paeps fail1: 99*e948693eSPhilip Paeps EFSYS_PROBE1(fail1, int, rc); 100*e948693eSPhilip Paeps 101*e948693eSPhilip Paeps return (rc); 102*e948693eSPhilip Paeps } 103*e948693eSPhilip Paeps 104*e948693eSPhilip Paeps #if EFSYS_OPT_FILTER 105*e948693eSPhilip Paeps extern __checkReturn int 106*e948693eSPhilip Paeps efx_tx_filter_insert( 107*e948693eSPhilip Paeps __in efx_txq_t *etp, 108*e948693eSPhilip Paeps __inout efx_filter_spec_t *spec) 109*e948693eSPhilip Paeps { 110*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 111*e948693eSPhilip Paeps EFSYS_ASSERT3P(spec, !=, NULL); 112*e948693eSPhilip Paeps 113*e948693eSPhilip Paeps spec->efs_dmaq_id = (uint16_t)etp->et_index; 114*e948693eSPhilip Paeps return efx_filter_insert_filter(etp->et_enp, spec, B_FALSE); 115*e948693eSPhilip Paeps } 116*e948693eSPhilip Paeps #endif 117*e948693eSPhilip Paeps 118*e948693eSPhilip Paeps #if EFSYS_OPT_FILTER 119*e948693eSPhilip Paeps extern __checkReturn int 120*e948693eSPhilip Paeps efx_tx_filter_remove( 121*e948693eSPhilip Paeps __in efx_txq_t *etp, 122*e948693eSPhilip Paeps __inout efx_filter_spec_t *spec) 123*e948693eSPhilip Paeps { 124*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 125*e948693eSPhilip Paeps EFSYS_ASSERT3P(spec, !=, NULL); 126*e948693eSPhilip Paeps 127*e948693eSPhilip Paeps spec->efs_dmaq_id = (uint16_t)etp->et_index; 128*e948693eSPhilip Paeps return efx_filter_remove_filter(etp->et_enp, spec); 129*e948693eSPhilip Paeps } 130*e948693eSPhilip Paeps #endif 131*e948693eSPhilip Paeps 132*e948693eSPhilip Paeps #define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \ 133*e948693eSPhilip Paeps do { \ 134*e948693eSPhilip Paeps unsigned int id; \ 135*e948693eSPhilip Paeps size_t offset; \ 136*e948693eSPhilip Paeps efx_qword_t qword; \ 137*e948693eSPhilip Paeps \ 138*e948693eSPhilip Paeps id = (_added)++ & (_etp)->et_mask; \ 139*e948693eSPhilip Paeps offset = id * sizeof (efx_qword_t); \ 140*e948693eSPhilip Paeps \ 141*e948693eSPhilip Paeps EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index, \ 142*e948693eSPhilip Paeps unsigned int, id, efsys_dma_addr_t, (_addr), \ 143*e948693eSPhilip Paeps size_t, (_size), boolean_t, (_eop)); \ 144*e948693eSPhilip Paeps \ 145*e948693eSPhilip Paeps EFX_POPULATE_QWORD_4(qword, \ 146*e948693eSPhilip Paeps FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1, \ 147*e948693eSPhilip Paeps FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size), \ 148*e948693eSPhilip Paeps FSF_AZ_TX_KER_BUF_ADDR_DW0, \ 149*e948693eSPhilip Paeps (uint32_t)((_addr) & 0xffffffff), \ 150*e948693eSPhilip Paeps FSF_AZ_TX_KER_BUF_ADDR_DW1, \ 151*e948693eSPhilip Paeps (uint32_t)((_addr) >> 32)); \ 152*e948693eSPhilip Paeps EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword); \ 153*e948693eSPhilip Paeps \ 154*e948693eSPhilip Paeps _NOTE(CONSTANTCONDITION) \ 155*e948693eSPhilip Paeps } while (B_FALSE) 156*e948693eSPhilip Paeps 157*e948693eSPhilip Paeps __checkReturn int 158*e948693eSPhilip Paeps efx_tx_qpost( 159*e948693eSPhilip Paeps __in efx_txq_t *etp, 160*e948693eSPhilip Paeps __in_ecount(n) efx_buffer_t *eb, 161*e948693eSPhilip Paeps __in unsigned int n, 162*e948693eSPhilip Paeps __in unsigned int completed, 163*e948693eSPhilip Paeps __inout unsigned int *addedp) 164*e948693eSPhilip Paeps { 165*e948693eSPhilip Paeps unsigned int added = *addedp; 166*e948693eSPhilip Paeps unsigned int i; 167*e948693eSPhilip Paeps int rc = ENOSPC; 168*e948693eSPhilip Paeps 169*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 170*e948693eSPhilip Paeps 171*e948693eSPhilip Paeps if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) 172*e948693eSPhilip Paeps goto fail1; 173*e948693eSPhilip Paeps 174*e948693eSPhilip Paeps for (i = 0; i < n; i++) { 175*e948693eSPhilip Paeps efx_buffer_t *ebp = &eb[i]; 176*e948693eSPhilip Paeps efsys_dma_addr_t start = ebp->eb_addr; 177*e948693eSPhilip Paeps size_t size = ebp->eb_size; 178*e948693eSPhilip Paeps efsys_dma_addr_t end = start + size; 179*e948693eSPhilip Paeps 180*e948693eSPhilip Paeps /* Fragments must not span 4k boundaries. */ 181*e948693eSPhilip Paeps EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end); 182*e948693eSPhilip Paeps 183*e948693eSPhilip Paeps EFX_TX_DESC(etp, start, size, ebp->eb_eop, added); 184*e948693eSPhilip Paeps } 185*e948693eSPhilip Paeps 186*e948693eSPhilip Paeps EFX_TX_QSTAT_INCR(etp, TX_POST); 187*e948693eSPhilip Paeps 188*e948693eSPhilip Paeps *addedp = added; 189*e948693eSPhilip Paeps return (0); 190*e948693eSPhilip Paeps 191*e948693eSPhilip Paeps fail1: 192*e948693eSPhilip Paeps EFSYS_PROBE1(fail1, int, rc); 193*e948693eSPhilip Paeps 194*e948693eSPhilip Paeps return (rc); 195*e948693eSPhilip Paeps } 196*e948693eSPhilip Paeps 197*e948693eSPhilip Paeps void 198*e948693eSPhilip Paeps efx_tx_qpush( 199*e948693eSPhilip Paeps __in efx_txq_t *etp, 200*e948693eSPhilip Paeps __in unsigned int added) 201*e948693eSPhilip Paeps { 202*e948693eSPhilip Paeps efx_nic_t *enp = etp->et_enp; 203*e948693eSPhilip Paeps uint32_t wptr; 204*e948693eSPhilip Paeps efx_dword_t dword; 205*e948693eSPhilip Paeps efx_oword_t oword; 206*e948693eSPhilip Paeps 207*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 208*e948693eSPhilip Paeps 209*e948693eSPhilip Paeps /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */ 210*e948693eSPhilip Paeps EFSYS_PIO_WRITE_BARRIER(); 211*e948693eSPhilip Paeps 212*e948693eSPhilip Paeps /* Push the populated descriptors out */ 213*e948693eSPhilip Paeps wptr = added & etp->et_mask; 214*e948693eSPhilip Paeps 215*e948693eSPhilip Paeps EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr); 216*e948693eSPhilip Paeps 217*e948693eSPhilip Paeps /* Only write the third DWORD */ 218*e948693eSPhilip Paeps EFX_POPULATE_DWORD_1(dword, 219*e948693eSPhilip Paeps EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3)); 220*e948693eSPhilip Paeps EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0, 221*e948693eSPhilip Paeps etp->et_index, &dword, B_FALSE); 222*e948693eSPhilip Paeps } 223*e948693eSPhilip Paeps 224*e948693eSPhilip Paeps void 225*e948693eSPhilip Paeps efx_tx_qflush( 226*e948693eSPhilip Paeps __in efx_txq_t *etp) 227*e948693eSPhilip Paeps { 228*e948693eSPhilip Paeps efx_nic_t *enp = etp->et_enp; 229*e948693eSPhilip Paeps efx_oword_t oword; 230*e948693eSPhilip Paeps uint32_t label; 231*e948693eSPhilip Paeps 232*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 233*e948693eSPhilip Paeps 234*e948693eSPhilip Paeps label = etp->et_index; 235*e948693eSPhilip Paeps 236*e948693eSPhilip Paeps /* Flush the queue */ 237*e948693eSPhilip Paeps EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1, 238*e948693eSPhilip Paeps FRF_AZ_TX_FLUSH_DESCQ, label); 239*e948693eSPhilip Paeps EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword); 240*e948693eSPhilip Paeps } 241*e948693eSPhilip Paeps 242*e948693eSPhilip Paeps void 243*e948693eSPhilip Paeps efx_tx_qenable( 244*e948693eSPhilip Paeps __in efx_txq_t *etp) 245*e948693eSPhilip Paeps { 246*e948693eSPhilip Paeps efx_nic_t *enp = etp->et_enp; 247*e948693eSPhilip Paeps efx_oword_t oword; 248*e948693eSPhilip Paeps 249*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 250*e948693eSPhilip Paeps 251*e948693eSPhilip Paeps EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL, 252*e948693eSPhilip Paeps etp->et_index, &oword); 253*e948693eSPhilip Paeps 254*e948693eSPhilip Paeps EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index, 255*e948693eSPhilip Paeps uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3), 256*e948693eSPhilip Paeps uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2), 257*e948693eSPhilip Paeps uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1), 258*e948693eSPhilip Paeps uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0)); 259*e948693eSPhilip Paeps 260*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0); 261*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0); 262*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1); 263*e948693eSPhilip Paeps 264*e948693eSPhilip Paeps EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL, 265*e948693eSPhilip Paeps etp->et_index, &oword); 266*e948693eSPhilip Paeps } 267*e948693eSPhilip Paeps 268*e948693eSPhilip Paeps __checkReturn int 269*e948693eSPhilip Paeps efx_tx_qcreate( 270*e948693eSPhilip Paeps __in efx_nic_t *enp, 271*e948693eSPhilip Paeps __in unsigned int index, 272*e948693eSPhilip Paeps __in unsigned int label, 273*e948693eSPhilip Paeps __in efsys_mem_t *esmp, 274*e948693eSPhilip Paeps __in size_t n, 275*e948693eSPhilip Paeps __in uint32_t id, 276*e948693eSPhilip Paeps __in uint16_t flags, 277*e948693eSPhilip Paeps __in efx_evq_t *eep, 278*e948693eSPhilip Paeps __deref_out efx_txq_t **etpp) 279*e948693eSPhilip Paeps { 280*e948693eSPhilip Paeps efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 281*e948693eSPhilip Paeps efx_txq_t *etp; 282*e948693eSPhilip Paeps efx_oword_t oword; 283*e948693eSPhilip Paeps uint32_t size; 284*e948693eSPhilip Paeps int rc; 285*e948693eSPhilip Paeps 286*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 287*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX); 288*e948693eSPhilip Paeps 289*e948693eSPhilip Paeps EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS == (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH)); 290*e948693eSPhilip Paeps EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS); 291*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit); 292*e948693eSPhilip Paeps 293*e948693eSPhilip Paeps if (!ISP2(n) || !(n & EFX_TXQ_NDESCS_MASK)) { 294*e948693eSPhilip Paeps rc = EINVAL; 295*e948693eSPhilip Paeps goto fail1; 296*e948693eSPhilip Paeps } 297*e948693eSPhilip Paeps if (index >= encp->enc_txq_limit) { 298*e948693eSPhilip Paeps rc = EINVAL; 299*e948693eSPhilip Paeps goto fail2; 300*e948693eSPhilip Paeps } 301*e948693eSPhilip Paeps for (size = 0; (1 << size) <= (EFX_TXQ_MAXNDESCS / EFX_TXQ_MINNDESCS); 302*e948693eSPhilip Paeps size++) 303*e948693eSPhilip Paeps if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS)) 304*e948693eSPhilip Paeps break; 305*e948693eSPhilip Paeps if (id + (1 << size) >= encp->enc_buftbl_limit) { 306*e948693eSPhilip Paeps rc = EINVAL; 307*e948693eSPhilip Paeps goto fail3; 308*e948693eSPhilip Paeps } 309*e948693eSPhilip Paeps 310*e948693eSPhilip Paeps /* Allocate an TXQ object */ 311*e948693eSPhilip Paeps EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp); 312*e948693eSPhilip Paeps 313*e948693eSPhilip Paeps if (etp == NULL) { 314*e948693eSPhilip Paeps rc = ENOMEM; 315*e948693eSPhilip Paeps goto fail4; 316*e948693eSPhilip Paeps } 317*e948693eSPhilip Paeps 318*e948693eSPhilip Paeps etp->et_magic = EFX_TXQ_MAGIC; 319*e948693eSPhilip Paeps etp->et_enp = enp; 320*e948693eSPhilip Paeps etp->et_index = index; 321*e948693eSPhilip Paeps etp->et_mask = n - 1; 322*e948693eSPhilip Paeps etp->et_esmp = esmp; 323*e948693eSPhilip Paeps 324*e948693eSPhilip Paeps /* Set up the new descriptor queue */ 325*e948693eSPhilip Paeps EFX_POPULATE_OWORD_6(oword, 326*e948693eSPhilip Paeps FRF_AZ_TX_DESCQ_BUF_BASE_ID, id, 327*e948693eSPhilip Paeps FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index, 328*e948693eSPhilip Paeps FRF_AZ_TX_DESCQ_OWNER_ID, 0, 329*e948693eSPhilip Paeps FRF_AZ_TX_DESCQ_LABEL, label, 330*e948693eSPhilip Paeps FRF_AZ_TX_DESCQ_SIZE, size, 331*e948693eSPhilip Paeps FRF_AZ_TX_DESCQ_TYPE, 0); 332*e948693eSPhilip Paeps 333*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1); 334*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS, 335*e948693eSPhilip Paeps (flags & EFX_CKSUM_IPV4) ? 0 : 1); 336*e948693eSPhilip Paeps EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS, 337*e948693eSPhilip Paeps (flags & EFX_CKSUM_TCPUDP) ? 0 : 1); 338*e948693eSPhilip Paeps 339*e948693eSPhilip Paeps EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL, 340*e948693eSPhilip Paeps etp->et_index, &oword); 341*e948693eSPhilip Paeps 342*e948693eSPhilip Paeps enp->en_tx_qcount++; 343*e948693eSPhilip Paeps *etpp = etp; 344*e948693eSPhilip Paeps return (0); 345*e948693eSPhilip Paeps 346*e948693eSPhilip Paeps fail4: 347*e948693eSPhilip Paeps EFSYS_PROBE(fail4); 348*e948693eSPhilip Paeps fail3: 349*e948693eSPhilip Paeps EFSYS_PROBE(fail3); 350*e948693eSPhilip Paeps fail2: 351*e948693eSPhilip Paeps EFSYS_PROBE(fail2); 352*e948693eSPhilip Paeps fail1: 353*e948693eSPhilip Paeps EFSYS_PROBE1(fail1, int, rc); 354*e948693eSPhilip Paeps 355*e948693eSPhilip Paeps return (rc); 356*e948693eSPhilip Paeps } 357*e948693eSPhilip Paeps 358*e948693eSPhilip Paeps #if EFSYS_OPT_NAMES 359*e948693eSPhilip Paeps /* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 78ca9ab00287fffb */ 360*e948693eSPhilip Paeps static const char __cs * __cs __efx_tx_qstat_name[] = { 361*e948693eSPhilip Paeps "post", 362*e948693eSPhilip Paeps "unaligned_split", 363*e948693eSPhilip Paeps }; 364*e948693eSPhilip Paeps /* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */ 365*e948693eSPhilip Paeps 366*e948693eSPhilip Paeps const char __cs * 367*e948693eSPhilip Paeps efx_tx_qstat_name( 368*e948693eSPhilip Paeps __in efx_nic_t *enp, 369*e948693eSPhilip Paeps __in unsigned int id) 370*e948693eSPhilip Paeps { 371*e948693eSPhilip Paeps _NOTE(ARGUNUSED(enp)) 372*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 373*e948693eSPhilip Paeps EFSYS_ASSERT3U(id, <, TX_NQSTATS); 374*e948693eSPhilip Paeps 375*e948693eSPhilip Paeps return (__efx_tx_qstat_name[id]); 376*e948693eSPhilip Paeps } 377*e948693eSPhilip Paeps #endif /* EFSYS_OPT_NAMES */ 378*e948693eSPhilip Paeps 379*e948693eSPhilip Paeps #if EFSYS_OPT_QSTATS 380*e948693eSPhilip Paeps void 381*e948693eSPhilip Paeps efx_tx_qstats_update( 382*e948693eSPhilip Paeps __in efx_txq_t *etp, 383*e948693eSPhilip Paeps __inout_ecount(TX_NQSTATS) efsys_stat_t *stat) 384*e948693eSPhilip Paeps { 385*e948693eSPhilip Paeps unsigned int id; 386*e948693eSPhilip Paeps 387*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 388*e948693eSPhilip Paeps 389*e948693eSPhilip Paeps for (id = 0; id < TX_NQSTATS; id++) { 390*e948693eSPhilip Paeps efsys_stat_t *essp = &stat[id]; 391*e948693eSPhilip Paeps 392*e948693eSPhilip Paeps EFSYS_STAT_INCR(essp, etp->et_stat[id]); 393*e948693eSPhilip Paeps etp->et_stat[id] = 0; 394*e948693eSPhilip Paeps } 395*e948693eSPhilip Paeps } 396*e948693eSPhilip Paeps #endif /* EFSYS_OPT_QSTATS */ 397*e948693eSPhilip Paeps 398*e948693eSPhilip Paeps void 399*e948693eSPhilip Paeps efx_tx_qdestroy( 400*e948693eSPhilip Paeps __in efx_txq_t *etp) 401*e948693eSPhilip Paeps { 402*e948693eSPhilip Paeps efx_nic_t *enp = etp->et_enp; 403*e948693eSPhilip Paeps efx_oword_t oword; 404*e948693eSPhilip Paeps 405*e948693eSPhilip Paeps EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC); 406*e948693eSPhilip Paeps 407*e948693eSPhilip Paeps EFSYS_ASSERT(enp->en_tx_qcount != 0); 408*e948693eSPhilip Paeps --enp->en_tx_qcount; 409*e948693eSPhilip Paeps 410*e948693eSPhilip Paeps /* Purge descriptor queue */ 411*e948693eSPhilip Paeps EFX_ZERO_OWORD(oword); 412*e948693eSPhilip Paeps 413*e948693eSPhilip Paeps EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL, 414*e948693eSPhilip Paeps etp->et_index, &oword); 415*e948693eSPhilip Paeps 416*e948693eSPhilip Paeps /* Free the TXQ object */ 417*e948693eSPhilip Paeps EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp); 418*e948693eSPhilip Paeps } 419*e948693eSPhilip Paeps 420*e948693eSPhilip Paeps void 421*e948693eSPhilip Paeps efx_tx_fini( 422*e948693eSPhilip Paeps __in efx_nic_t *enp) 423*e948693eSPhilip Paeps { 424*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 425*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 426*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX); 427*e948693eSPhilip Paeps EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0); 428*e948693eSPhilip Paeps 429*e948693eSPhilip Paeps enp->en_mod_flags &= ~EFX_MOD_TX; 430*e948693eSPhilip Paeps } 431