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