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