net/sfc/base: import SFN7xxx family support
[dpdk.git] / drivers / net / sfc / base / efx_tx.c
1 /*
2  * Copyright (c) 2007-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30
31 #include "efx.h"
32 #include "efx_impl.h"
33
34 #define EFX_TX_QSTAT_INCR(_etp, _stat)
35
36 #if EFSYS_OPT_SIENA
37
38 static  __checkReturn   efx_rc_t
39 siena_tx_init(
40         __in            efx_nic_t *enp);
41
42 static                  void
43 siena_tx_fini(
44         __in            efx_nic_t *enp);
45
46 static  __checkReturn   efx_rc_t
47 siena_tx_qcreate(
48         __in            efx_nic_t *enp,
49         __in            unsigned int index,
50         __in            unsigned int label,
51         __in            efsys_mem_t *esmp,
52         __in            size_t n,
53         __in            uint32_t id,
54         __in            uint16_t flags,
55         __in            efx_evq_t *eep,
56         __in            efx_txq_t *etp,
57         __out           unsigned int *addedp);
58
59 static          void
60 siena_tx_qdestroy(
61         __in    efx_txq_t *etp);
62
63 static  __checkReturn   efx_rc_t
64 siena_tx_qpost(
65         __in            efx_txq_t *etp,
66         __in_ecount(n)  efx_buffer_t *eb,
67         __in            unsigned int n,
68         __in            unsigned int completed,
69         __inout         unsigned int *addedp);
70
71 static                  void
72 siena_tx_qpush(
73         __in    efx_txq_t *etp,
74         __in    unsigned int added,
75         __in    unsigned int pushed);
76
77 static  __checkReturn   efx_rc_t
78 siena_tx_qpace(
79         __in            efx_txq_t *etp,
80         __in            unsigned int ns);
81
82 static  __checkReturn   efx_rc_t
83 siena_tx_qflush(
84         __in            efx_txq_t *etp);
85
86 static                  void
87 siena_tx_qenable(
88         __in    efx_txq_t *etp);
89
90         __checkReturn   efx_rc_t
91 siena_tx_qdesc_post(
92         __in            efx_txq_t *etp,
93         __in_ecount(n)  efx_desc_t *ed,
94         __in            unsigned int n,
95         __in            unsigned int completed,
96         __inout         unsigned int *addedp);
97
98         void
99 siena_tx_qdesc_dma_create(
100         __in    efx_txq_t *etp,
101         __in    efsys_dma_addr_t addr,
102         __in    size_t size,
103         __in    boolean_t eop,
104         __out   efx_desc_t *edp);
105
106 #endif /* EFSYS_OPT_SIENA */
107
108
109 #if EFSYS_OPT_SIENA
110 static const efx_tx_ops_t       __efx_tx_siena_ops = {
111         siena_tx_init,                          /* etxo_init */
112         siena_tx_fini,                          /* etxo_fini */
113         siena_tx_qcreate,                       /* etxo_qcreate */
114         siena_tx_qdestroy,                      /* etxo_qdestroy */
115         siena_tx_qpost,                         /* etxo_qpost */
116         siena_tx_qpush,                         /* etxo_qpush */
117         siena_tx_qpace,                         /* etxo_qpace */
118         siena_tx_qflush,                        /* etxo_qflush */
119         siena_tx_qenable,                       /* etxo_qenable */
120         NULL,                                   /* etxo_qpio_enable */
121         NULL,                                   /* etxo_qpio_disable */
122         NULL,                                   /* etxo_qpio_write */
123         NULL,                                   /* etxo_qpio_post */
124         siena_tx_qdesc_post,                    /* etxo_qdesc_post */
125         siena_tx_qdesc_dma_create,              /* etxo_qdesc_dma_create */
126         NULL,                                   /* etxo_qdesc_tso_create */
127         NULL,                                   /* etxo_qdesc_tso2_create */
128         NULL,                                   /* etxo_qdesc_vlantci_create */
129 };
130 #endif /* EFSYS_OPT_SIENA */
131
132 #if EFSYS_OPT_HUNTINGTON
133 static const efx_tx_ops_t       __efx_tx_hunt_ops = {
134         ef10_tx_init,                           /* etxo_init */
135         ef10_tx_fini,                           /* etxo_fini */
136         ef10_tx_qcreate,                        /* etxo_qcreate */
137         ef10_tx_qdestroy,                       /* etxo_qdestroy */
138         ef10_tx_qpost,                          /* etxo_qpost */
139         ef10_tx_qpush,                          /* etxo_qpush */
140         ef10_tx_qpace,                          /* etxo_qpace */
141         ef10_tx_qflush,                         /* etxo_qflush */
142         ef10_tx_qenable,                        /* etxo_qenable */
143         ef10_tx_qpio_enable,                    /* etxo_qpio_enable */
144         ef10_tx_qpio_disable,                   /* etxo_qpio_disable */
145         ef10_tx_qpio_write,                     /* etxo_qpio_write */
146         ef10_tx_qpio_post,                      /* etxo_qpio_post */
147         ef10_tx_qdesc_post,                     /* etxo_qdesc_post */
148         ef10_tx_qdesc_dma_create,               /* etxo_qdesc_dma_create */
149         ef10_tx_qdesc_tso_create,               /* etxo_qdesc_tso_create */
150         ef10_tx_qdesc_tso2_create,              /* etxo_qdesc_tso2_create */
151         ef10_tx_qdesc_vlantci_create,           /* etxo_qdesc_vlantci_create */
152 };
153 #endif /* EFSYS_OPT_HUNTINGTON */
154
155         __checkReturn   efx_rc_t
156 efx_tx_init(
157         __in            efx_nic_t *enp)
158 {
159         const efx_tx_ops_t *etxop;
160         efx_rc_t rc;
161
162         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
163         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
164
165         if (!(enp->en_mod_flags & EFX_MOD_EV)) {
166                 rc = EINVAL;
167                 goto fail1;
168         }
169
170         if (enp->en_mod_flags & EFX_MOD_TX) {
171                 rc = EINVAL;
172                 goto fail2;
173         }
174
175         switch (enp->en_family) {
176 #if EFSYS_OPT_SIENA
177         case EFX_FAMILY_SIENA:
178                 etxop = &__efx_tx_siena_ops;
179                 break;
180 #endif /* EFSYS_OPT_SIENA */
181
182 #if EFSYS_OPT_HUNTINGTON
183         case EFX_FAMILY_HUNTINGTON:
184                 etxop = &__efx_tx_hunt_ops;
185                 break;
186 #endif /* EFSYS_OPT_HUNTINGTON */
187
188         default:
189                 EFSYS_ASSERT(0);
190                 rc = ENOTSUP;
191                 goto fail3;
192         }
193
194         EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
195
196         if ((rc = etxop->etxo_init(enp)) != 0)
197                 goto fail4;
198
199         enp->en_etxop = etxop;
200         enp->en_mod_flags |= EFX_MOD_TX;
201         return (0);
202
203 fail4:
204         EFSYS_PROBE(fail4);
205 fail3:
206         EFSYS_PROBE(fail3);
207 fail2:
208         EFSYS_PROBE(fail2);
209 fail1:
210         EFSYS_PROBE1(fail1, efx_rc_t, rc);
211
212         enp->en_etxop = NULL;
213         enp->en_mod_flags &= ~EFX_MOD_TX;
214         return (rc);
215 }
216
217                         void
218 efx_tx_fini(
219         __in    efx_nic_t *enp)
220 {
221         const efx_tx_ops_t *etxop = enp->en_etxop;
222
223         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
224         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
225         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
226         EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
227
228         etxop->etxo_fini(enp);
229
230         enp->en_etxop = NULL;
231         enp->en_mod_flags &= ~EFX_MOD_TX;
232 }
233
234         __checkReturn   efx_rc_t
235 efx_tx_qcreate(
236         __in            efx_nic_t *enp,
237         __in            unsigned int index,
238         __in            unsigned int label,
239         __in            efsys_mem_t *esmp,
240         __in            size_t n,
241         __in            uint32_t id,
242         __in            uint16_t flags,
243         __in            efx_evq_t *eep,
244         __deref_out     efx_txq_t **etpp,
245         __out           unsigned int *addedp)
246 {
247         const efx_tx_ops_t *etxop = enp->en_etxop;
248         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
249         efx_txq_t *etp;
250         efx_rc_t rc;
251
252         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
253         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
254
255         EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
256
257         /* Allocate an TXQ object */
258         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
259
260         if (etp == NULL) {
261                 rc = ENOMEM;
262                 goto fail1;
263         }
264
265         etp->et_magic = EFX_TXQ_MAGIC;
266         etp->et_enp = enp;
267         etp->et_index = index;
268         etp->et_mask = n - 1;
269         etp->et_esmp = esmp;
270
271         /* Initial descriptor index may be modified by etxo_qcreate */
272         *addedp = 0;
273
274         if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
275             n, id, flags, eep, etp, addedp)) != 0)
276                 goto fail2;
277
278         enp->en_tx_qcount++;
279         *etpp = etp;
280
281         return (0);
282
283 fail2:
284         EFSYS_PROBE(fail2);
285         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
286 fail1:
287         EFSYS_PROBE1(fail1, efx_rc_t, rc);
288         return (rc);
289 }
290
291                 void
292 efx_tx_qdestroy(
293         __in    efx_txq_t *etp)
294 {
295         efx_nic_t *enp = etp->et_enp;
296         const efx_tx_ops_t *etxop = enp->en_etxop;
297
298         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
299
300         EFSYS_ASSERT(enp->en_tx_qcount != 0);
301         --enp->en_tx_qcount;
302
303         etxop->etxo_qdestroy(etp);
304
305         /* Free the TXQ object */
306         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
307 }
308
309         __checkReturn   efx_rc_t
310 efx_tx_qpost(
311         __in            efx_txq_t *etp,
312         __in_ecount(n)  efx_buffer_t *eb,
313         __in            unsigned int n,
314         __in            unsigned int completed,
315         __inout         unsigned int *addedp)
316 {
317         efx_nic_t *enp = etp->et_enp;
318         const efx_tx_ops_t *etxop = enp->en_etxop;
319         efx_rc_t rc;
320
321         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
322
323         if ((rc = etxop->etxo_qpost(etp, eb,
324             n, completed, addedp)) != 0)
325                 goto fail1;
326
327         return (0);
328
329 fail1:
330         EFSYS_PROBE1(fail1, efx_rc_t, rc);
331         return (rc);
332 }
333
334                         void
335 efx_tx_qpush(
336         __in    efx_txq_t *etp,
337         __in    unsigned int added,
338         __in    unsigned int pushed)
339 {
340         efx_nic_t *enp = etp->et_enp;
341         const efx_tx_ops_t *etxop = enp->en_etxop;
342
343         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
344
345         etxop->etxo_qpush(etp, added, pushed);
346 }
347
348         __checkReturn   efx_rc_t
349 efx_tx_qpace(
350         __in            efx_txq_t *etp,
351         __in            unsigned int ns)
352 {
353         efx_nic_t *enp = etp->et_enp;
354         const efx_tx_ops_t *etxop = enp->en_etxop;
355         efx_rc_t rc;
356
357         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
358
359         if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
360                 goto fail1;
361
362         return (0);
363
364 fail1:
365         EFSYS_PROBE1(fail1, efx_rc_t, rc);
366         return (rc);
367 }
368
369         __checkReturn   efx_rc_t
370 efx_tx_qflush(
371         __in    efx_txq_t *etp)
372 {
373         efx_nic_t *enp = etp->et_enp;
374         const efx_tx_ops_t *etxop = enp->en_etxop;
375         efx_rc_t rc;
376
377         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
378
379         if ((rc = etxop->etxo_qflush(etp)) != 0)
380                 goto fail1;
381
382         return (0);
383
384 fail1:
385         EFSYS_PROBE1(fail1, efx_rc_t, rc);
386         return (rc);
387 }
388
389                         void
390 efx_tx_qenable(
391         __in    efx_txq_t *etp)
392 {
393         efx_nic_t *enp = etp->et_enp;
394         const efx_tx_ops_t *etxop = enp->en_etxop;
395
396         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
397
398         etxop->etxo_qenable(etp);
399 }
400
401         __checkReturn   efx_rc_t
402 efx_tx_qpio_enable(
403         __in    efx_txq_t *etp)
404 {
405         efx_nic_t *enp = etp->et_enp;
406         const efx_tx_ops_t *etxop = enp->en_etxop;
407         efx_rc_t rc;
408
409         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
410
411         if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
412                 rc = ENOTSUP;
413                 goto fail1;
414         }
415         if (etxop->etxo_qpio_enable == NULL) {
416                 rc = ENOTSUP;
417                 goto fail2;
418         }
419         if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
420                 goto fail3;
421
422         return (0);
423
424 fail3:
425         EFSYS_PROBE(fail3);
426 fail2:
427         EFSYS_PROBE(fail2);
428 fail1:
429         EFSYS_PROBE1(fail1, efx_rc_t, rc);
430         return (rc);
431 }
432
433                 void
434 efx_tx_qpio_disable(
435         __in    efx_txq_t *etp)
436 {
437         efx_nic_t *enp = etp->et_enp;
438         const efx_tx_ops_t *etxop = enp->en_etxop;
439
440         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
441
442         if (etxop->etxo_qpio_disable != NULL)
443                 etxop->etxo_qpio_disable(etp);
444 }
445
446         __checkReturn   efx_rc_t
447 efx_tx_qpio_write(
448         __in                    efx_txq_t *etp,
449         __in_ecount(buf_length) uint8_t *buffer,
450         __in                    size_t buf_length,
451         __in                    size_t pio_buf_offset)
452 {
453         efx_nic_t *enp = etp->et_enp;
454         const efx_tx_ops_t *etxop = enp->en_etxop;
455         efx_rc_t rc;
456
457         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
458
459         if (etxop->etxo_qpio_write != NULL) {
460                 if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
461                                                 pio_buf_offset)) != 0)
462                         goto fail1;
463                 return (0);
464         }
465
466         return (ENOTSUP);
467
468 fail1:
469         EFSYS_PROBE1(fail1, efx_rc_t, rc);
470         return (rc);
471 }
472
473         __checkReturn   efx_rc_t
474 efx_tx_qpio_post(
475         __in                    efx_txq_t *etp,
476         __in                    size_t pkt_length,
477         __in                    unsigned int completed,
478         __inout                 unsigned int *addedp)
479 {
480         efx_nic_t *enp = etp->et_enp;
481         const efx_tx_ops_t *etxop = enp->en_etxop;
482         efx_rc_t rc;
483
484         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
485
486         if (etxop->etxo_qpio_post != NULL) {
487                 if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
488                                                 addedp)) != 0)
489                         goto fail1;
490                 return (0);
491         }
492
493         return (ENOTSUP);
494
495 fail1:
496         EFSYS_PROBE1(fail1, efx_rc_t, rc);
497         return (rc);
498 }
499
500         __checkReturn   efx_rc_t
501 efx_tx_qdesc_post(
502         __in            efx_txq_t *etp,
503         __in_ecount(n)  efx_desc_t *ed,
504         __in            unsigned int n,
505         __in            unsigned int completed,
506         __inout         unsigned int *addedp)
507 {
508         efx_nic_t *enp = etp->et_enp;
509         const efx_tx_ops_t *etxop = enp->en_etxop;
510         efx_rc_t rc;
511
512         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
513
514         if ((rc = etxop->etxo_qdesc_post(etp, ed,
515             n, completed, addedp)) != 0)
516                 goto fail1;
517
518         return (0);
519
520 fail1:
521         EFSYS_PROBE1(fail1, efx_rc_t, rc);
522         return (rc);
523 }
524
525         void
526 efx_tx_qdesc_dma_create(
527         __in    efx_txq_t *etp,
528         __in    efsys_dma_addr_t addr,
529         __in    size_t size,
530         __in    boolean_t eop,
531         __out   efx_desc_t *edp)
532 {
533         efx_nic_t *enp = etp->et_enp;
534         const efx_tx_ops_t *etxop = enp->en_etxop;
535
536         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
537         EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
538
539         etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
540 }
541
542         void
543 efx_tx_qdesc_tso_create(
544         __in    efx_txq_t *etp,
545         __in    uint16_t ipv4_id,
546         __in    uint32_t tcp_seq,
547         __in    uint8_t  tcp_flags,
548         __out   efx_desc_t *edp)
549 {
550         efx_nic_t *enp = etp->et_enp;
551         const efx_tx_ops_t *etxop = enp->en_etxop;
552
553         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
554         EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
555
556         etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
557 }
558
559         void
560 efx_tx_qdesc_tso2_create(
561         __in                    efx_txq_t *etp,
562         __in                    uint16_t ipv4_id,
563         __in                    uint32_t tcp_seq,
564         __in                    uint16_t mss,
565         __out_ecount(count)     efx_desc_t *edp,
566         __in                    int count)
567 {
568         efx_nic_t *enp = etp->et_enp;
569         const efx_tx_ops_t *etxop = enp->en_etxop;
570
571         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
572         EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
573
574         etxop->etxo_qdesc_tso2_create(etp, ipv4_id, tcp_seq, mss, edp, count);
575 }
576
577         void
578 efx_tx_qdesc_vlantci_create(
579         __in    efx_txq_t *etp,
580         __in    uint16_t tci,
581         __out   efx_desc_t *edp)
582 {
583         efx_nic_t *enp = etp->et_enp;
584         const efx_tx_ops_t *etxop = enp->en_etxop;
585
586         EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
587         EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
588
589         etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
590 }
591
592
593 #if EFSYS_OPT_SIENA
594
595 static  __checkReturn   efx_rc_t
596 siena_tx_init(
597         __in            efx_nic_t *enp)
598 {
599         efx_oword_t oword;
600
601         /*
602          * Disable the timer-based TX DMA backoff and allow TX DMA to be
603          * controlled by the RX FIFO fill level (although always allow a
604          * minimal trickle).
605          */
606         EFX_BAR_READO(enp, FR_AZ_TX_RESERVED_REG, &oword);
607         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER, 0xfe);
608         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_RX_SPACER_EN, 1);
609         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_ONE_PKT_PER_Q, 1);
610         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PUSH_EN, 0);
611         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DIS_NON_IP_EV, 1);
612         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_THRESHOLD, 2);
613         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_PREF_WD_TMR, 0x3fffff);
614
615         /*
616          * Filter all packets less than 14 bytes to avoid parsing
617          * errors.
618          */
619         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
620         EFX_BAR_WRITEO(enp, FR_AZ_TX_RESERVED_REG, &oword);
621
622         /*
623          * Do not set TX_NO_EOP_DISC_EN, since it limits packets to 16
624          * descriptors (which is bad).
625          */
626         EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
627         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
628         EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
629
630         return (0);
631 }
632
633 #define EFX_TX_DESC(_etp, _addr, _size, _eop, _added)                   \
634         do {                                                            \
635                 unsigned int id;                                        \
636                 size_t offset;                                          \
637                 efx_qword_t qword;                                      \
638                                                                         \
639                 id = (_added)++ & (_etp)->et_mask;                      \
640                 offset = id * sizeof (efx_qword_t);                     \
641                                                                         \
642                 EFSYS_PROBE5(tx_post, unsigned int, (_etp)->et_index,   \
643                     unsigned int, id, efsys_dma_addr_t, (_addr),        \
644                     size_t, (_size), boolean_t, (_eop));                \
645                                                                         \
646                 EFX_POPULATE_QWORD_4(qword,                             \
647                     FSF_AZ_TX_KER_CONT, (_eop) ? 0 : 1,                 \
648                     FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)(_size),        \
649                     FSF_AZ_TX_KER_BUF_ADDR_DW0,                         \
650                     (uint32_t)((_addr) & 0xffffffff),                   \
651                     FSF_AZ_TX_KER_BUF_ADDR_DW1,                         \
652                     (uint32_t)((_addr) >> 32));                         \
653                 EFSYS_MEM_WRITEQ((_etp)->et_esmp, offset, &qword);      \
654                                                                         \
655                 _NOTE(CONSTANTCONDITION)                                \
656         } while (B_FALSE)
657
658 static  __checkReturn   efx_rc_t
659 siena_tx_qpost(
660         __in            efx_txq_t *etp,
661         __in_ecount(n)  efx_buffer_t *eb,
662         __in            unsigned int n,
663         __in            unsigned int completed,
664         __inout         unsigned int *addedp)
665 {
666         unsigned int added = *addedp;
667         unsigned int i;
668         int rc = ENOSPC;
669
670         if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1))
671                 goto fail1;
672
673         for (i = 0; i < n; i++) {
674                 efx_buffer_t *ebp = &eb[i];
675                 efsys_dma_addr_t start = ebp->eb_addr;
676                 size_t size = ebp->eb_size;
677                 efsys_dma_addr_t end = start + size;
678
679                 /* Fragments must not span 4k boundaries. */
680                 EFSYS_ASSERT(P2ROUNDUP(start + 1, 4096) >= end);
681
682                 EFX_TX_DESC(etp, start, size, ebp->eb_eop, added);
683         }
684
685         EFX_TX_QSTAT_INCR(etp, TX_POST);
686
687         *addedp = added;
688         return (0);
689
690 fail1:
691         EFSYS_PROBE1(fail1, efx_rc_t, rc);
692
693         return (rc);
694 }
695
696 static          void
697 siena_tx_qpush(
698         __in    efx_txq_t *etp,
699         __in    unsigned int added,
700         __in    unsigned int pushed)
701 {
702         efx_nic_t *enp = etp->et_enp;
703         uint32_t wptr;
704         efx_dword_t dword;
705         efx_oword_t oword;
706
707         /* Push the populated descriptors out */
708         wptr = added & etp->et_mask;
709
710         EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_DESC_WPTR, wptr);
711
712         /* Only write the third DWORD */
713         EFX_POPULATE_DWORD_1(dword,
714             EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
715
716         /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
717         EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
718             wptr, pushed & etp->et_mask);
719         EFSYS_PIO_WRITE_BARRIER();
720         EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
721                             etp->et_index, &dword, B_FALSE);
722 }
723
724 #define EFX_MAX_PACE_VALUE 20
725
726 static  __checkReturn   efx_rc_t
727 siena_tx_qpace(
728         __in            efx_txq_t *etp,
729         __in            unsigned int ns)
730 {
731         efx_nic_t *enp = etp->et_enp;
732         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
733         efx_oword_t oword;
734         unsigned int pace_val;
735         unsigned int timer_period;
736         efx_rc_t rc;
737
738         if (ns == 0) {
739                 pace_val = 0;
740         } else {
741                 /*
742                  * The pace_val to write into the table is s.t
743                  * ns <= timer_period * (2 ^ pace_val)
744                  */
745                 timer_period = 104 / encp->enc_clk_mult;
746                 for (pace_val = 1; pace_val <= EFX_MAX_PACE_VALUE; pace_val++) {
747                         if ((timer_period << pace_val) >= ns)
748                                 break;
749                 }
750         }
751         if (pace_val > EFX_MAX_PACE_VALUE) {
752                 rc = EINVAL;
753                 goto fail1;
754         }
755
756         /* Update the pacing table */
757         EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
758         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
759             &oword, B_TRUE);
760
761         return (0);
762
763 fail1:
764         EFSYS_PROBE1(fail1, efx_rc_t, rc);
765
766         return (rc);
767 }
768
769 static  __checkReturn   efx_rc_t
770 siena_tx_qflush(
771         __in            efx_txq_t *etp)
772 {
773         efx_nic_t *enp = etp->et_enp;
774         efx_oword_t oword;
775         uint32_t label;
776
777         efx_tx_qpace(etp, 0);
778
779         label = etp->et_index;
780
781         /* Flush the queue */
782         EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
783             FRF_AZ_TX_FLUSH_DESCQ, label);
784         EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
785
786         return (0);
787 }
788
789 static          void
790 siena_tx_qenable(
791         __in    efx_txq_t *etp)
792 {
793         efx_nic_t *enp = etp->et_enp;
794         efx_oword_t oword;
795
796         EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
797                             etp->et_index, &oword, B_TRUE);
798
799         EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
800             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
801             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_2),
802             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_1),
803             uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_0));
804
805         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DC_HW_RPTR, 0);
806         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_HW_RPTR, 0);
807         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
808
809         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
810                             etp->et_index, &oword, B_TRUE);
811 }
812
813 static  __checkReturn   efx_rc_t
814 siena_tx_qcreate(
815         __in            efx_nic_t *enp,
816         __in            unsigned int index,
817         __in            unsigned int label,
818         __in            efsys_mem_t *esmp,
819         __in            size_t n,
820         __in            uint32_t id,
821         __in            uint16_t flags,
822         __in            efx_evq_t *eep,
823         __in            efx_txq_t *etp,
824         __out           unsigned int *addedp)
825 {
826         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
827         efx_oword_t oword;
828         uint32_t size;
829         efx_rc_t rc;
830
831         _NOTE(ARGUNUSED(esmp))
832
833         EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
834             (1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
835         EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
836
837         EFSYS_ASSERT(ISP2(encp->enc_txq_max_ndescs));
838         EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
839
840         if (!ISP2(n) || (n < EFX_TXQ_MINNDESCS) || (n > EFX_EVQ_MAXNEVS)) {
841                 rc = EINVAL;
842                 goto fail1;
843         }
844         if (index >= encp->enc_txq_limit) {
845                 rc = EINVAL;
846                 goto fail2;
847         }
848         for (size = 0;
849             (1 << size) <= (int)(encp->enc_txq_max_ndescs / EFX_TXQ_MINNDESCS);
850             size++)
851                 if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS))
852                         break;
853         if (id + (1 << size) >= encp->enc_buftbl_limit) {
854                 rc = EINVAL;
855                 goto fail3;
856         }
857
858         /* Set up the new descriptor queue */
859         *addedp = 0;
860
861         EFX_POPULATE_OWORD_6(oword,
862             FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
863             FRF_AZ_TX_DESCQ_EVQ_ID, eep->ee_index,
864             FRF_AZ_TX_DESCQ_OWNER_ID, 0,
865             FRF_AZ_TX_DESCQ_LABEL, label,
866             FRF_AZ_TX_DESCQ_SIZE, size,
867             FRF_AZ_TX_DESCQ_TYPE, 0);
868
869         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_NON_IP_DROP_DIS, 1);
870         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_IP_CHKSM_DIS,
871             (flags & EFX_TXQ_CKSUM_IPV4) ? 0 : 1);
872         EFX_SET_OWORD_FIELD(oword, FRF_BZ_TX_TCP_CHKSM_DIS,
873             (flags & EFX_TXQ_CKSUM_TCPUDP) ? 0 : 1);
874
875         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
876             etp->et_index, &oword, B_TRUE);
877
878         return (0);
879
880 fail3:
881         EFSYS_PROBE(fail3);
882 fail2:
883         EFSYS_PROBE(fail2);
884 fail1:
885         EFSYS_PROBE1(fail1, efx_rc_t, rc);
886
887         return (rc);
888 }
889
890         __checkReturn   efx_rc_t
891 siena_tx_qdesc_post(
892         __in            efx_txq_t *etp,
893         __in_ecount(n)  efx_desc_t *ed,
894         __in            unsigned int n,
895         __in            unsigned int completed,
896         __inout         unsigned int *addedp)
897 {
898         unsigned int added = *addedp;
899         unsigned int i;
900         efx_rc_t rc;
901
902         if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
903                 rc = ENOSPC;
904                 goto fail1;
905         }
906
907         for (i = 0; i < n; i++) {
908                 efx_desc_t *edp = &ed[i];
909                 unsigned int id;
910                 size_t offset;
911
912                 id = added++ & etp->et_mask;
913                 offset = id * sizeof (efx_desc_t);
914
915                 EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
916         }
917
918         EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
919                     unsigned int, added, unsigned int, n);
920
921         EFX_TX_QSTAT_INCR(etp, TX_POST);
922
923         *addedp = added;
924         return (0);
925
926 fail1:
927         EFSYS_PROBE1(fail1, efx_rc_t, rc);
928         return (rc);
929 }
930
931         void
932 siena_tx_qdesc_dma_create(
933         __in    efx_txq_t *etp,
934         __in    efsys_dma_addr_t addr,
935         __in    size_t size,
936         __in    boolean_t eop,
937         __out   efx_desc_t *edp)
938 {
939         /* Fragments must not span 4k boundaries. */
940         EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
941
942         EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
943                     efsys_dma_addr_t, addr,
944                     size_t, size, boolean_t, eop);
945
946         EFX_POPULATE_QWORD_4(edp->ed_eq,
947                             FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
948                             FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
949                             FSF_AZ_TX_KER_BUF_ADDR_DW0,
950                             (uint32_t)(addr & 0xffffffff),
951                             FSF_AZ_TX_KER_BUF_ADDR_DW1,
952                             (uint32_t)(addr >> 32));
953 }
954
955 #endif /* EFSYS_OPT_SIENA */
956
957 #if EFSYS_OPT_SIENA
958
959 static          void
960 siena_tx_qdestroy(
961         __in    efx_txq_t *etp)
962 {
963         efx_nic_t *enp = etp->et_enp;
964         efx_oword_t oword;
965
966         /* Purge descriptor queue */
967         EFX_ZERO_OWORD(oword);
968
969         EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
970                             etp->et_index, &oword, B_TRUE);
971 }
972
973 static          void
974 siena_tx_fini(
975         __in    efx_nic_t *enp)
976 {
977         _NOTE(ARGUNUSED(enp))
978 }
979
980 #endif /* EFSYS_OPT_SIENA */