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