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