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