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