net/sfc/base: control RxQ scatter using flag instead of type
[dpdk.git] / drivers / net / sfc / base / efx_rx.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
35 #if EFSYS_OPT_SIENA
36
37 static  __checkReturn   efx_rc_t
38 siena_rx_init(
39         __in            efx_nic_t *enp);
40
41 static                  void
42 siena_rx_fini(
43         __in            efx_nic_t *enp);
44
45 #if EFSYS_OPT_RX_SCATTER
46 static  __checkReturn   efx_rc_t
47 siena_rx_scatter_enable(
48         __in            efx_nic_t *enp,
49         __in            unsigned int buf_size);
50 #endif /* EFSYS_OPT_RX_SCATTER */
51
52 #if EFSYS_OPT_RX_SCALE
53 static  __checkReturn   efx_rc_t
54 siena_rx_scale_mode_set(
55         __in            efx_nic_t *enp,
56         __in            uint32_t rss_context,
57         __in            efx_rx_hash_alg_t alg,
58         __in            efx_rx_hash_type_t type,
59         __in            boolean_t insert);
60
61 static  __checkReturn   efx_rc_t
62 siena_rx_scale_key_set(
63         __in            efx_nic_t *enp,
64         __in            uint32_t rss_context,
65         __in_ecount(n)  uint8_t *key,
66         __in            size_t n);
67
68 static  __checkReturn   efx_rc_t
69 siena_rx_scale_tbl_set(
70         __in            efx_nic_t *enp,
71         __in            uint32_t rss_context,
72         __in_ecount(n)  unsigned int *table,
73         __in            size_t n);
74
75 static  __checkReturn   uint32_t
76 siena_rx_prefix_hash(
77         __in            efx_nic_t *enp,
78         __in            efx_rx_hash_alg_t func,
79         __in            uint8_t *buffer);
80
81 #endif /* EFSYS_OPT_RX_SCALE */
82
83 static  __checkReturn   efx_rc_t
84 siena_rx_prefix_pktlen(
85         __in            efx_nic_t *enp,
86         __in            uint8_t *buffer,
87         __out           uint16_t *lengthp);
88
89 static                          void
90 siena_rx_qpost(
91         __in                    efx_rxq_t *erp,
92         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
93         __in                    size_t size,
94         __in                    unsigned int ndescs,
95         __in                    unsigned int completed,
96         __in                    unsigned int added);
97
98 static                  void
99 siena_rx_qpush(
100         __in            efx_rxq_t *erp,
101         __in            unsigned int added,
102         __inout         unsigned int *pushedp);
103
104 #if EFSYS_OPT_RX_PACKED_STREAM
105 static          void
106 siena_rx_qpush_ps_credits(
107         __in            efx_rxq_t *erp);
108
109 static  __checkReturn   uint8_t *
110 siena_rx_qps_packet_info(
111         __in            efx_rxq_t *erp,
112         __in            uint8_t *buffer,
113         __in            uint32_t buffer_length,
114         __in            uint32_t current_offset,
115         __out           uint16_t *lengthp,
116         __out           uint32_t *next_offsetp,
117         __out           uint32_t *timestamp);
118 #endif
119
120 static  __checkReturn   efx_rc_t
121 siena_rx_qflush(
122         __in            efx_rxq_t *erp);
123
124 static                  void
125 siena_rx_qenable(
126         __in            efx_rxq_t *erp);
127
128 static  __checkReturn   efx_rc_t
129 siena_rx_qcreate(
130         __in            efx_nic_t *enp,
131         __in            unsigned int index,
132         __in            unsigned int label,
133         __in            efx_rxq_type_t type,
134         __in            efsys_mem_t *esmp,
135         __in            size_t ndescs,
136         __in            uint32_t id,
137         __in            unsigned int flags,
138         __in            efx_evq_t *eep,
139         __in            efx_rxq_t *erp);
140
141 static                  void
142 siena_rx_qdestroy(
143         __in            efx_rxq_t *erp);
144
145 #endif /* EFSYS_OPT_SIENA */
146
147
148 #if EFSYS_OPT_SIENA
149 static const efx_rx_ops_t __efx_rx_siena_ops = {
150         siena_rx_init,                          /* erxo_init */
151         siena_rx_fini,                          /* erxo_fini */
152 #if EFSYS_OPT_RX_SCATTER
153         siena_rx_scatter_enable,                /* erxo_scatter_enable */
154 #endif
155 #if EFSYS_OPT_RX_SCALE
156         NULL,                                   /* erxo_scale_context_alloc */
157         NULL,                                   /* erxo_scale_context_free */
158         siena_rx_scale_mode_set,                /* erxo_scale_mode_set */
159         siena_rx_scale_key_set,                 /* erxo_scale_key_set */
160         siena_rx_scale_tbl_set,                 /* erxo_scale_tbl_set */
161         siena_rx_prefix_hash,                   /* erxo_prefix_hash */
162 #endif
163         siena_rx_prefix_pktlen,                 /* erxo_prefix_pktlen */
164         siena_rx_qpost,                         /* erxo_qpost */
165         siena_rx_qpush,                         /* erxo_qpush */
166 #if EFSYS_OPT_RX_PACKED_STREAM
167         siena_rx_qpush_ps_credits,              /* erxo_qpush_ps_credits */
168         siena_rx_qps_packet_info,               /* erxo_qps_packet_info */
169 #endif
170         siena_rx_qflush,                        /* erxo_qflush */
171         siena_rx_qenable,                       /* erxo_qenable */
172         siena_rx_qcreate,                       /* erxo_qcreate */
173         siena_rx_qdestroy,                      /* erxo_qdestroy */
174 };
175 #endif  /* EFSYS_OPT_SIENA */
176
177 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
178 static const efx_rx_ops_t __efx_rx_ef10_ops = {
179         ef10_rx_init,                           /* erxo_init */
180         ef10_rx_fini,                           /* erxo_fini */
181 #if EFSYS_OPT_RX_SCATTER
182         ef10_rx_scatter_enable,                 /* erxo_scatter_enable */
183 #endif
184 #if EFSYS_OPT_RX_SCALE
185         ef10_rx_scale_context_alloc,            /* erxo_scale_context_alloc */
186         ef10_rx_scale_context_free,             /* erxo_scale_context_free */
187         ef10_rx_scale_mode_set,                 /* erxo_scale_mode_set */
188         ef10_rx_scale_key_set,                  /* erxo_scale_key_set */
189         ef10_rx_scale_tbl_set,                  /* erxo_scale_tbl_set */
190         ef10_rx_prefix_hash,                    /* erxo_prefix_hash */
191 #endif
192         ef10_rx_prefix_pktlen,                  /* erxo_prefix_pktlen */
193         ef10_rx_qpost,                          /* erxo_qpost */
194         ef10_rx_qpush,                          /* erxo_qpush */
195 #if EFSYS_OPT_RX_PACKED_STREAM
196         ef10_rx_qpush_ps_credits,               /* erxo_qpush_ps_credits */
197         ef10_rx_qps_packet_info,                /* erxo_qps_packet_info */
198 #endif
199         ef10_rx_qflush,                         /* erxo_qflush */
200         ef10_rx_qenable,                        /* erxo_qenable */
201         ef10_rx_qcreate,                        /* erxo_qcreate */
202         ef10_rx_qdestroy,                       /* erxo_qdestroy */
203 };
204 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
205
206
207         __checkReturn   efx_rc_t
208 efx_rx_init(
209         __inout         efx_nic_t *enp)
210 {
211         const efx_rx_ops_t *erxop;
212         efx_rc_t rc;
213
214         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
215         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
216
217         if (!(enp->en_mod_flags & EFX_MOD_EV)) {
218                 rc = EINVAL;
219                 goto fail1;
220         }
221
222         if (enp->en_mod_flags & EFX_MOD_RX) {
223                 rc = EINVAL;
224                 goto fail2;
225         }
226
227         switch (enp->en_family) {
228 #if EFSYS_OPT_SIENA
229         case EFX_FAMILY_SIENA:
230                 erxop = &__efx_rx_siena_ops;
231                 break;
232 #endif /* EFSYS_OPT_SIENA */
233
234 #if EFSYS_OPT_HUNTINGTON
235         case EFX_FAMILY_HUNTINGTON:
236                 erxop = &__efx_rx_ef10_ops;
237                 break;
238 #endif /* EFSYS_OPT_HUNTINGTON */
239
240 #if EFSYS_OPT_MEDFORD
241         case EFX_FAMILY_MEDFORD:
242                 erxop = &__efx_rx_ef10_ops;
243                 break;
244 #endif /* EFSYS_OPT_MEDFORD */
245
246         default:
247                 EFSYS_ASSERT(0);
248                 rc = ENOTSUP;
249                 goto fail3;
250         }
251
252         if ((rc = erxop->erxo_init(enp)) != 0)
253                 goto fail4;
254
255         enp->en_erxop = erxop;
256         enp->en_mod_flags |= EFX_MOD_RX;
257         return (0);
258
259 fail4:
260         EFSYS_PROBE(fail4);
261 fail3:
262         EFSYS_PROBE(fail3);
263 fail2:
264         EFSYS_PROBE(fail2);
265 fail1:
266         EFSYS_PROBE1(fail1, efx_rc_t, rc);
267
268         enp->en_erxop = NULL;
269         enp->en_mod_flags &= ~EFX_MOD_RX;
270         return (rc);
271 }
272
273                         void
274 efx_rx_fini(
275         __in            efx_nic_t *enp)
276 {
277         const efx_rx_ops_t *erxop = enp->en_erxop;
278
279         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
280         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
281         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
282         EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
283
284         erxop->erxo_fini(enp);
285
286         enp->en_erxop = NULL;
287         enp->en_mod_flags &= ~EFX_MOD_RX;
288 }
289
290 #if EFSYS_OPT_RX_SCATTER
291         __checkReturn   efx_rc_t
292 efx_rx_scatter_enable(
293         __in            efx_nic_t *enp,
294         __in            unsigned int buf_size)
295 {
296         const efx_rx_ops_t *erxop = enp->en_erxop;
297         efx_rc_t rc;
298
299         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
300         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
301
302         if ((rc = erxop->erxo_scatter_enable(enp, buf_size)) != 0)
303                 goto fail1;
304
305         return (0);
306
307 fail1:
308         EFSYS_PROBE1(fail1, efx_rc_t, rc);
309         return (rc);
310 }
311 #endif  /* EFSYS_OPT_RX_SCATTER */
312
313 #if EFSYS_OPT_RX_SCALE
314         __checkReturn   efx_rc_t
315 efx_rx_hash_default_support_get(
316         __in            efx_nic_t *enp,
317         __out           efx_rx_hash_support_t *supportp)
318 {
319         efx_rc_t rc;
320
321         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
322         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
323
324         if (supportp == NULL) {
325                 rc = EINVAL;
326                 goto fail1;
327         }
328
329         /*
330          * Report the hashing support the client gets by default if it
331          * does not allocate an RSS context itself.
332          */
333         *supportp = enp->en_hash_support;
334
335         return (0);
336
337 fail1:
338         EFSYS_PROBE1(fail1, efx_rc_t, rc);
339
340         return (rc);
341 }
342
343         __checkReturn   efx_rc_t
344 efx_rx_scale_default_support_get(
345         __in            efx_nic_t *enp,
346         __out           efx_rx_scale_context_type_t *typep)
347 {
348         efx_rc_t rc;
349
350         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
351         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
352
353         if (typep == NULL) {
354                 rc = EINVAL;
355                 goto fail1;
356         }
357
358         /*
359          * Report the RSS support the client gets by default if it
360          * does not allocate an RSS context itself.
361          */
362         *typep = enp->en_rss_context_type;
363
364         return (0);
365
366 fail1:
367         EFSYS_PROBE1(fail1, efx_rc_t, rc);
368
369         return (rc);
370 }
371 #endif  /* EFSYS_OPT_RX_SCALE */
372
373 #if EFSYS_OPT_RX_SCALE
374         __checkReturn   efx_rc_t
375 efx_rx_scale_context_alloc(
376         __in            efx_nic_t *enp,
377         __in            efx_rx_scale_context_type_t type,
378         __in            uint32_t num_queues,
379         __out           uint32_t *rss_contextp)
380 {
381         const efx_rx_ops_t *erxop = enp->en_erxop;
382         efx_rc_t rc;
383
384         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
385         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
386
387         if (erxop->erxo_scale_context_alloc == NULL) {
388                 rc = ENOTSUP;
389                 goto fail1;
390         }
391         if ((rc = erxop->erxo_scale_context_alloc(enp, type,
392                             num_queues, rss_contextp)) != 0) {
393                 goto fail2;
394         }
395
396         return (0);
397
398 fail2:
399         EFSYS_PROBE(fail2);
400 fail1:
401         EFSYS_PROBE1(fail1, efx_rc_t, rc);
402         return (rc);
403 }
404 #endif  /* EFSYS_OPT_RX_SCALE */
405
406 #if EFSYS_OPT_RX_SCALE
407         __checkReturn   efx_rc_t
408 efx_rx_scale_context_free(
409         __in            efx_nic_t *enp,
410         __in            uint32_t rss_context)
411 {
412         const efx_rx_ops_t *erxop = enp->en_erxop;
413         efx_rc_t rc;
414
415         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
416         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
417
418         if (erxop->erxo_scale_context_free == NULL) {
419                 rc = ENOTSUP;
420                 goto fail1;
421         }
422         if ((rc = erxop->erxo_scale_context_free(enp, rss_context)) != 0)
423                 goto fail2;
424
425         return (0);
426
427 fail2:
428         EFSYS_PROBE(fail2);
429 fail1:
430         EFSYS_PROBE1(fail1, efx_rc_t, rc);
431         return (rc);
432 }
433 #endif  /* EFSYS_OPT_RX_SCALE */
434
435 #if EFSYS_OPT_RX_SCALE
436         __checkReturn   efx_rc_t
437 efx_rx_scale_mode_set(
438         __in            efx_nic_t *enp,
439         __in            uint32_t rss_context,
440         __in            efx_rx_hash_alg_t alg,
441         __in            efx_rx_hash_type_t type,
442         __in            boolean_t insert)
443 {
444         const efx_rx_ops_t *erxop = enp->en_erxop;
445         efx_rc_t rc;
446
447         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
448         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
449
450         if (erxop->erxo_scale_mode_set != NULL) {
451                 if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg,
452                             type, insert)) != 0)
453                         goto fail1;
454         }
455
456         return (0);
457
458 fail1:
459         EFSYS_PROBE1(fail1, efx_rc_t, rc);
460         return (rc);
461 }
462 #endif  /* EFSYS_OPT_RX_SCALE */
463
464 #if EFSYS_OPT_RX_SCALE
465         __checkReturn   efx_rc_t
466 efx_rx_scale_key_set(
467         __in            efx_nic_t *enp,
468         __in            uint32_t rss_context,
469         __in_ecount(n)  uint8_t *key,
470         __in            size_t n)
471 {
472         const efx_rx_ops_t *erxop = enp->en_erxop;
473         efx_rc_t rc;
474
475         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
476         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
477
478         if ((rc = erxop->erxo_scale_key_set(enp, rss_context, key, n)) != 0)
479                 goto fail1;
480
481         return (0);
482
483 fail1:
484         EFSYS_PROBE1(fail1, efx_rc_t, rc);
485
486         return (rc);
487 }
488 #endif  /* EFSYS_OPT_RX_SCALE */
489
490 #if EFSYS_OPT_RX_SCALE
491         __checkReturn   efx_rc_t
492 efx_rx_scale_tbl_set(
493         __in            efx_nic_t *enp,
494         __in            uint32_t rss_context,
495         __in_ecount(n)  unsigned int *table,
496         __in            size_t n)
497 {
498         const efx_rx_ops_t *erxop = enp->en_erxop;
499         efx_rc_t rc;
500
501         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
502         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
503
504         if ((rc = erxop->erxo_scale_tbl_set(enp, rss_context, table, n)) != 0)
505                 goto fail1;
506
507         return (0);
508
509 fail1:
510         EFSYS_PROBE1(fail1, efx_rc_t, rc);
511
512         return (rc);
513 }
514 #endif  /* EFSYS_OPT_RX_SCALE */
515
516                                 void
517 efx_rx_qpost(
518         __in                    efx_rxq_t *erp,
519         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
520         __in                    size_t size,
521         __in                    unsigned int ndescs,
522         __in                    unsigned int completed,
523         __in                    unsigned int added)
524 {
525         efx_nic_t *enp = erp->er_enp;
526         const efx_rx_ops_t *erxop = enp->en_erxop;
527
528         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
529
530         erxop->erxo_qpost(erp, addrp, size, ndescs, completed, added);
531 }
532
533 #if EFSYS_OPT_RX_PACKED_STREAM
534
535                         void
536 efx_rx_qpush_ps_credits(
537         __in            efx_rxq_t *erp)
538 {
539         efx_nic_t *enp = erp->er_enp;
540         const efx_rx_ops_t *erxop = enp->en_erxop;
541
542         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
543
544         erxop->erxo_qpush_ps_credits(erp);
545 }
546
547         __checkReturn   uint8_t *
548 efx_rx_qps_packet_info(
549         __in            efx_rxq_t *erp,
550         __in            uint8_t *buffer,
551         __in            uint32_t buffer_length,
552         __in            uint32_t current_offset,
553         __out           uint16_t *lengthp,
554         __out           uint32_t *next_offsetp,
555         __out           uint32_t *timestamp)
556 {
557         efx_nic_t *enp = erp->er_enp;
558         const efx_rx_ops_t *erxop = enp->en_erxop;
559
560         return (erxop->erxo_qps_packet_info(erp, buffer,
561                 buffer_length, current_offset, lengthp,
562                 next_offsetp, timestamp));
563 }
564
565 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
566
567                         void
568 efx_rx_qpush(
569         __in            efx_rxq_t *erp,
570         __in            unsigned int added,
571         __inout         unsigned int *pushedp)
572 {
573         efx_nic_t *enp = erp->er_enp;
574         const efx_rx_ops_t *erxop = enp->en_erxop;
575
576         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
577
578         erxop->erxo_qpush(erp, added, pushedp);
579 }
580
581         __checkReturn   efx_rc_t
582 efx_rx_qflush(
583         __in            efx_rxq_t *erp)
584 {
585         efx_nic_t *enp = erp->er_enp;
586         const efx_rx_ops_t *erxop = enp->en_erxop;
587         efx_rc_t rc;
588
589         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
590
591         if ((rc = erxop->erxo_qflush(erp)) != 0)
592                 goto fail1;
593
594         return (0);
595
596 fail1:
597         EFSYS_PROBE1(fail1, efx_rc_t, rc);
598
599         return (rc);
600 }
601
602                         void
603 efx_rx_qenable(
604         __in            efx_rxq_t *erp)
605 {
606         efx_nic_t *enp = erp->er_enp;
607         const efx_rx_ops_t *erxop = enp->en_erxop;
608
609         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
610
611         erxop->erxo_qenable(erp);
612 }
613
614         __checkReturn   efx_rc_t
615 efx_rx_qcreate(
616         __in            efx_nic_t *enp,
617         __in            unsigned int index,
618         __in            unsigned int label,
619         __in            efx_rxq_type_t type,
620         __in            efsys_mem_t *esmp,
621         __in            size_t ndescs,
622         __in            uint32_t id,
623         __in            unsigned int flags,
624         __in            efx_evq_t *eep,
625         __deref_out     efx_rxq_t **erpp)
626 {
627         const efx_rx_ops_t *erxop = enp->en_erxop;
628         efx_rxq_t *erp;
629         efx_rc_t rc;
630
631         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
632         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
633
634         /* Allocate an RXQ object */
635         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
636
637         if (erp == NULL) {
638                 rc = ENOMEM;
639                 goto fail1;
640         }
641
642         erp->er_magic = EFX_RXQ_MAGIC;
643         erp->er_enp = enp;
644         erp->er_index = index;
645         erp->er_mask = ndescs - 1;
646         erp->er_esmp = esmp;
647
648         if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, ndescs, id,
649             flags, eep, erp)) != 0)
650                 goto fail2;
651
652         enp->en_rx_qcount++;
653         *erpp = erp;
654
655         return (0);
656
657 fail2:
658         EFSYS_PROBE(fail2);
659
660         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
661 fail1:
662         EFSYS_PROBE1(fail1, efx_rc_t, rc);
663
664         return (rc);
665 }
666
667                         void
668 efx_rx_qdestroy(
669         __in            efx_rxq_t *erp)
670 {
671         efx_nic_t *enp = erp->er_enp;
672         const efx_rx_ops_t *erxop = enp->en_erxop;
673
674         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
675
676         erxop->erxo_qdestroy(erp);
677 }
678
679         __checkReturn   efx_rc_t
680 efx_pseudo_hdr_pkt_length_get(
681         __in            efx_rxq_t *erp,
682         __in            uint8_t *buffer,
683         __out           uint16_t *lengthp)
684 {
685         efx_nic_t *enp = erp->er_enp;
686         const efx_rx_ops_t *erxop = enp->en_erxop;
687
688         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
689
690         return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
691 }
692
693 #if EFSYS_OPT_RX_SCALE
694         __checkReturn   uint32_t
695 efx_pseudo_hdr_hash_get(
696         __in            efx_rxq_t *erp,
697         __in            efx_rx_hash_alg_t func,
698         __in            uint8_t *buffer)
699 {
700         efx_nic_t *enp = erp->er_enp;
701         const efx_rx_ops_t *erxop = enp->en_erxop;
702
703         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
704
705         EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
706         return (erxop->erxo_prefix_hash(enp, func, buffer));
707 }
708 #endif  /* EFSYS_OPT_RX_SCALE */
709
710 #if EFSYS_OPT_SIENA
711
712 static  __checkReturn   efx_rc_t
713 siena_rx_init(
714         __in            efx_nic_t *enp)
715 {
716         efx_oword_t oword;
717         unsigned int index;
718
719         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
720
721         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
722         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);
723         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);
724         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);
725         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);
726         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);
727         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
728
729         /* Zero the RSS table */
730         for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;
731             index++) {
732                 EFX_ZERO_OWORD(oword);
733                 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
734                                     index, &oword, B_TRUE);
735         }
736
737 #if EFSYS_OPT_RX_SCALE
738         /* The RSS key and indirection table are writable. */
739         enp->en_rss_context_type = EFX_RX_SCALE_EXCLUSIVE;
740
741         /* Hardware can insert RX hash with/without RSS */
742         enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
743 #endif  /* EFSYS_OPT_RX_SCALE */
744
745         return (0);
746 }
747
748 #if EFSYS_OPT_RX_SCATTER
749 static  __checkReturn   efx_rc_t
750 siena_rx_scatter_enable(
751         __in            efx_nic_t *enp,
752         __in            unsigned int buf_size)
753 {
754         unsigned int nbuf32;
755         efx_oword_t oword;
756         efx_rc_t rc;
757
758         nbuf32 = buf_size / 32;
759         if ((nbuf32 == 0) ||
760             (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
761             ((buf_size % 32) != 0)) {
762                 rc = EINVAL;
763                 goto fail1;
764         }
765
766         if (enp->en_rx_qcount > 0) {
767                 rc = EBUSY;
768                 goto fail2;
769         }
770
771         /* Set scatter buffer size */
772         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
773         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32);
774         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
775
776         /* Enable scatter for packets not matching a filter */
777         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
778         EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1);
779         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
780
781         return (0);
782
783 fail2:
784         EFSYS_PROBE(fail2);
785 fail1:
786         EFSYS_PROBE1(fail1, efx_rc_t, rc);
787
788         return (rc);
789 }
790 #endif  /* EFSYS_OPT_RX_SCATTER */
791
792
793 #define EFX_RX_LFSR_HASH(_enp, _insert)                                 \
794         do {                                                            \
795                 efx_oword_t oword;                                      \
796                                                                         \
797                 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);        \
798                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);      \
799                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);       \
800                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);       \
801                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,    \
802                     (_insert) ? 1 : 0);                                 \
803                 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);       \
804                                                                         \
805                 if ((_enp)->en_family == EFX_FAMILY_SIENA) {            \
806                         EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3,   \
807                             &oword);                                    \
808                         EFX_SET_OWORD_FIELD(oword,                      \
809                             FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0);        \
810                         EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3,  \
811                             &oword);                                    \
812                 }                                                       \
813                                                                         \
814                 _NOTE(CONSTANTCONDITION)                                \
815         } while (B_FALSE)
816
817 #define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp)             \
818         do {                                                            \
819                 efx_oword_t oword;                                      \
820                                                                         \
821                 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);        \
822                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1);      \
823                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH,           \
824                     (_ip) ? 1 : 0);                                     \
825                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP,           \
826                     (_tcp) ? 0 : 1);                                    \
827                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,    \
828                     (_insert) ? 1 : 0);                                 \
829                 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);       \
830                                                                         \
831                 _NOTE(CONSTANTCONDITION)                                \
832         } while (B_FALSE)
833
834 #define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc)                 \
835         do {                                                            \
836                 efx_oword_t oword;                                      \
837                                                                         \
838                 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);  \
839                 EFX_SET_OWORD_FIELD(oword,                              \
840                     FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1);                \
841                 EFX_SET_OWORD_FIELD(oword,                              \
842                     FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0); \
843                 EFX_SET_OWORD_FIELD(oword,                              \
844                     FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1);   \
845                 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
846                                                                         \
847                 (_rc) = 0;                                              \
848                                                                         \
849                 _NOTE(CONSTANTCONDITION)                                \
850         } while (B_FALSE)
851
852
853 #if EFSYS_OPT_RX_SCALE
854
855 static  __checkReturn   efx_rc_t
856 siena_rx_scale_mode_set(
857         __in            efx_nic_t *enp,
858         __in            uint32_t rss_context,
859         __in            efx_rx_hash_alg_t alg,
860         __in            efx_rx_hash_type_t type,
861         __in            boolean_t insert)
862 {
863         efx_rc_t rc;
864
865         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
866                 rc = EINVAL;
867                 goto fail1;
868         }
869
870         switch (alg) {
871         case EFX_RX_HASHALG_LFSR:
872                 EFX_RX_LFSR_HASH(enp, insert);
873                 break;
874
875         case EFX_RX_HASHALG_TOEPLITZ:
876                 EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
877                     type & EFX_RX_HASH_IPV4,
878                     type & EFX_RX_HASH_TCPIPV4);
879
880                 EFX_RX_TOEPLITZ_IPV6_HASH(enp,
881                     type & EFX_RX_HASH_IPV6,
882                     type & EFX_RX_HASH_TCPIPV6,
883                     rc);
884                 if (rc != 0)
885                         goto fail2;
886
887                 break;
888
889         default:
890                 rc = EINVAL;
891                 goto fail3;
892         }
893
894         return (0);
895
896 fail3:
897         EFSYS_PROBE(fail3);
898 fail2:
899         EFSYS_PROBE(fail2);
900 fail1:
901         EFSYS_PROBE1(fail1, efx_rc_t, rc);
902
903         EFX_RX_LFSR_HASH(enp, B_FALSE);
904
905         return (rc);
906 }
907 #endif
908
909 #if EFSYS_OPT_RX_SCALE
910 static  __checkReturn   efx_rc_t
911 siena_rx_scale_key_set(
912         __in            efx_nic_t *enp,
913         __in            uint32_t rss_context,
914         __in_ecount(n)  uint8_t *key,
915         __in            size_t n)
916 {
917         efx_oword_t oword;
918         unsigned int byte;
919         unsigned int offset;
920         efx_rc_t rc;
921
922         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
923                 rc = EINVAL;
924                 goto fail1;
925         }
926
927         byte = 0;
928
929         /* Write Toeplitz IPv4 hash key */
930         EFX_ZERO_OWORD(oword);
931         for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
932             offset > 0 && byte < n;
933             --offset)
934                 oword.eo_u8[offset - 1] = key[byte++];
935
936         EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
937
938         byte = 0;
939
940         /* Verify Toeplitz IPv4 hash key */
941         EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
942         for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
943             offset > 0 && byte < n;
944             --offset) {
945                 if (oword.eo_u8[offset - 1] != key[byte++]) {
946                         rc = EFAULT;
947                         goto fail2;
948                 }
949         }
950
951         if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
952                 goto done;
953
954         byte = 0;
955
956         /* Write Toeplitz IPv6 hash key 3 */
957         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
958         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
959             FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
960             offset > 0 && byte < n;
961             --offset)
962                 oword.eo_u8[offset - 1] = key[byte++];
963
964         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
965
966         /* Write Toeplitz IPv6 hash key 2 */
967         EFX_ZERO_OWORD(oword);
968         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
969             FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
970             offset > 0 && byte < n;
971             --offset)
972                 oword.eo_u8[offset - 1] = key[byte++];
973
974         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
975
976         /* Write Toeplitz IPv6 hash key 1 */
977         EFX_ZERO_OWORD(oword);
978         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
979             FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
980             offset > 0 && byte < n;
981             --offset)
982                 oword.eo_u8[offset - 1] = key[byte++];
983
984         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
985
986         byte = 0;
987
988         /* Verify Toeplitz IPv6 hash key 3 */
989         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
990         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
991             FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
992             offset > 0 && byte < n;
993             --offset) {
994                 if (oword.eo_u8[offset - 1] != key[byte++]) {
995                         rc = EFAULT;
996                         goto fail3;
997                 }
998         }
999
1000         /* Verify Toeplitz IPv6 hash key 2 */
1001         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1002         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1003             FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1004             offset > 0 && byte < n;
1005             --offset) {
1006                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1007                         rc = EFAULT;
1008                         goto fail4;
1009                 }
1010         }
1011
1012         /* Verify Toeplitz IPv6 hash key 1 */
1013         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1014         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1015             FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1016             offset > 0 && byte < n;
1017             --offset) {
1018                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1019                         rc = EFAULT;
1020                         goto fail5;
1021                 }
1022         }
1023
1024 done:
1025         return (0);
1026
1027 fail5:
1028         EFSYS_PROBE(fail5);
1029 fail4:
1030         EFSYS_PROBE(fail4);
1031 fail3:
1032         EFSYS_PROBE(fail3);
1033 fail2:
1034         EFSYS_PROBE(fail2);
1035 fail1:
1036         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1037
1038         return (rc);
1039 }
1040 #endif
1041
1042 #if EFSYS_OPT_RX_SCALE
1043 static  __checkReturn   efx_rc_t
1044 siena_rx_scale_tbl_set(
1045         __in            efx_nic_t *enp,
1046         __in            uint32_t rss_context,
1047         __in_ecount(n)  unsigned int *table,
1048         __in            size_t n)
1049 {
1050         efx_oword_t oword;
1051         int index;
1052         efx_rc_t rc;
1053
1054         EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
1055         EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
1056
1057         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1058                 rc = EINVAL;
1059                 goto fail1;
1060         }
1061
1062         if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {
1063                 rc = EINVAL;
1064                 goto fail2;
1065         }
1066
1067         for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {
1068                 uint32_t byte;
1069
1070                 /* Calculate the entry to place in the table */
1071                 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1072
1073                 EFSYS_PROBE2(table, int, index, uint32_t, byte);
1074
1075                 EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);
1076
1077                 /* Write the table */
1078                 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
1079                                     index, &oword, B_TRUE);
1080         }
1081
1082         for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
1083                 uint32_t byte;
1084
1085                 /* Determine if we're starting a new batch */
1086                 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1087
1088                 /* Read the table */
1089                 EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
1090                                     index, &oword, B_TRUE);
1091
1092                 /* Verify the entry */
1093                 if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
1094                         rc = EFAULT;
1095                         goto fail3;
1096                 }
1097         }
1098
1099         return (0);
1100
1101 fail3:
1102         EFSYS_PROBE(fail3);
1103 fail2:
1104         EFSYS_PROBE(fail2);
1105 fail1:
1106         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1107
1108         return (rc);
1109 }
1110 #endif
1111
1112 /*
1113  * Falcon/Siena pseudo-header
1114  * --------------------------
1115  *
1116  * Receive packets are prefixed by an optional 16 byte pseudo-header.
1117  * The pseudo-header is a byte array of one of the forms:
1118  *
1119  *  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
1120  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
1121  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
1122  *
1123  * where:
1124  *   TT.TT.TT.TT   Toeplitz hash (32-bit big-endian)
1125  *   LL.LL         LFSR hash     (16-bit big-endian)
1126  */
1127
1128 #if EFSYS_OPT_RX_SCALE
1129 static  __checkReturn   uint32_t
1130 siena_rx_prefix_hash(
1131         __in            efx_nic_t *enp,
1132         __in            efx_rx_hash_alg_t func,
1133         __in            uint8_t *buffer)
1134 {
1135         _NOTE(ARGUNUSED(enp))
1136
1137         switch (func) {
1138         case EFX_RX_HASHALG_TOEPLITZ:
1139                 return ((buffer[12] << 24) |
1140                     (buffer[13] << 16) |
1141                     (buffer[14] <<  8) |
1142                     buffer[15]);
1143
1144         case EFX_RX_HASHALG_LFSR:
1145                 return ((buffer[14] << 8) | buffer[15]);
1146
1147         default:
1148                 EFSYS_ASSERT(0);
1149                 return (0);
1150         }
1151 }
1152 #endif /* EFSYS_OPT_RX_SCALE */
1153
1154 static  __checkReturn   efx_rc_t
1155 siena_rx_prefix_pktlen(
1156         __in            efx_nic_t *enp,
1157         __in            uint8_t *buffer,
1158         __out           uint16_t *lengthp)
1159 {
1160         _NOTE(ARGUNUSED(enp, buffer, lengthp))
1161
1162         /* Not supported by Falcon/Siena hardware */
1163         EFSYS_ASSERT(0);
1164         return (ENOTSUP);
1165 }
1166
1167
1168 static                          void
1169 siena_rx_qpost(
1170         __in                    efx_rxq_t *erp,
1171         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
1172         __in                    size_t size,
1173         __in                    unsigned int ndescs,
1174         __in                    unsigned int completed,
1175         __in                    unsigned int added)
1176 {
1177         efx_qword_t qword;
1178         unsigned int i;
1179         unsigned int offset;
1180         unsigned int id;
1181
1182         /* The client driver must not overfill the queue */
1183         EFSYS_ASSERT3U(added - completed + ndescs, <=,
1184             EFX_RXQ_LIMIT(erp->er_mask + 1));
1185
1186         id = added & (erp->er_mask);
1187         for (i = 0; i < ndescs; i++) {
1188                 EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
1189                     unsigned int, id, efsys_dma_addr_t, addrp[i],
1190                     size_t, size);
1191
1192                 EFX_POPULATE_QWORD_3(qword,
1193                     FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),
1194                     FSF_AZ_RX_KER_BUF_ADDR_DW0,
1195                     (uint32_t)(addrp[i] & 0xffffffff),
1196                     FSF_AZ_RX_KER_BUF_ADDR_DW1,
1197                     (uint32_t)(addrp[i] >> 32));
1198
1199                 offset = id * sizeof (efx_qword_t);
1200                 EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
1201
1202                 id = (id + 1) & (erp->er_mask);
1203         }
1204 }
1205
1206 static                  void
1207 siena_rx_qpush(
1208         __in    efx_rxq_t *erp,
1209         __in    unsigned int added,
1210         __inout unsigned int *pushedp)
1211 {
1212         efx_nic_t *enp = erp->er_enp;
1213         unsigned int pushed = *pushedp;
1214         uint32_t wptr;
1215         efx_oword_t oword;
1216         efx_dword_t dword;
1217
1218         /* All descriptors are pushed */
1219         *pushedp = added;
1220
1221         /* Push the populated descriptors out */
1222         wptr = added & erp->er_mask;
1223
1224         EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);
1225
1226         /* Only write the third DWORD */
1227         EFX_POPULATE_DWORD_1(dword,
1228             EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
1229
1230         /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
1231         EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
1232             wptr, pushed & erp->er_mask);
1233         EFSYS_PIO_WRITE_BARRIER();
1234         EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
1235                             erp->er_index, &dword, B_FALSE);
1236 }
1237
1238 #if EFSYS_OPT_RX_PACKED_STREAM
1239 static          void
1240 siena_rx_qpush_ps_credits(
1241         __in            efx_rxq_t *erp)
1242 {
1243         /* Not supported by Siena hardware */
1244         EFSYS_ASSERT(0);
1245 }
1246
1247 static          uint8_t *
1248 siena_rx_qps_packet_info(
1249         __in            efx_rxq_t *erp,
1250         __in            uint8_t *buffer,
1251         __in            uint32_t buffer_length,
1252         __in            uint32_t current_offset,
1253         __out           uint16_t *lengthp,
1254         __out           uint32_t *next_offsetp,
1255         __out           uint32_t *timestamp)
1256 {
1257         /* Not supported by Siena hardware */
1258         EFSYS_ASSERT(0);
1259
1260         return (NULL);
1261 }
1262 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
1263
1264 static  __checkReturn   efx_rc_t
1265 siena_rx_qflush(
1266         __in    efx_rxq_t *erp)
1267 {
1268         efx_nic_t *enp = erp->er_enp;
1269         efx_oword_t oword;
1270         uint32_t label;
1271
1272         label = erp->er_index;
1273
1274         /* Flush the queue */
1275         EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
1276             FRF_AZ_RX_FLUSH_DESCQ, label);
1277         EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
1278
1279         return (0);
1280 }
1281
1282 static          void
1283 siena_rx_qenable(
1284         __in    efx_rxq_t *erp)
1285 {
1286         efx_nic_t *enp = erp->er_enp;
1287         efx_oword_t oword;
1288
1289         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
1290
1291         EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
1292                             erp->er_index, &oword, B_TRUE);
1293
1294         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
1295         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
1296         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
1297
1298         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1299                             erp->er_index, &oword, B_TRUE);
1300 }
1301
1302 static  __checkReturn   efx_rc_t
1303 siena_rx_qcreate(
1304         __in            efx_nic_t *enp,
1305         __in            unsigned int index,
1306         __in            unsigned int label,
1307         __in            efx_rxq_type_t type,
1308         __in            efsys_mem_t *esmp,
1309         __in            size_t ndescs,
1310         __in            uint32_t id,
1311         __in            unsigned int flags,
1312         __in            efx_evq_t *eep,
1313         __in            efx_rxq_t *erp)
1314 {
1315         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1316         efx_oword_t oword;
1317         uint32_t size;
1318         boolean_t jumbo = B_FALSE;
1319         efx_rc_t rc;
1320
1321         _NOTE(ARGUNUSED(esmp))
1322
1323         EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
1324             (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
1325         EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
1326         EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
1327
1328         EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
1329         EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
1330
1331         if (!ISP2(ndescs) ||
1332             (ndescs < EFX_RXQ_MINNDESCS) || (ndescs > EFX_RXQ_MAXNDESCS)) {
1333                 rc = EINVAL;
1334                 goto fail1;
1335         }
1336         if (index >= encp->enc_rxq_limit) {
1337                 rc = EINVAL;
1338                 goto fail2;
1339         }
1340         for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);
1341             size++)
1342                 if ((1 << size) == (int)(ndescs / EFX_RXQ_MINNDESCS))
1343                         break;
1344         if (id + (1 << size) >= encp->enc_buftbl_limit) {
1345                 rc = EINVAL;
1346                 goto fail3;
1347         }
1348
1349         switch (type) {
1350         case EFX_RXQ_TYPE_DEFAULT:
1351                 break;
1352
1353         default:
1354                 rc = EINVAL;
1355                 goto fail4;
1356         }
1357
1358         if (flags & EFX_RXQ_FLAG_SCATTER) {
1359 #if EFSYS_OPT_RX_SCATTER
1360                 jumbo = B_TRUE;
1361 #else
1362                 rc = EINVAL;
1363                 goto fail5;
1364 #endif  /* EFSYS_OPT_RX_SCATTER */
1365         }
1366
1367         /* Set up the new descriptor queue */
1368         EFX_POPULATE_OWORD_7(oword,
1369             FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
1370             FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,
1371             FRF_AZ_RX_DESCQ_OWNER_ID, 0,
1372             FRF_AZ_RX_DESCQ_LABEL, label,
1373             FRF_AZ_RX_DESCQ_SIZE, size,
1374             FRF_AZ_RX_DESCQ_TYPE, 0,
1375             FRF_AZ_RX_DESCQ_JUMBO, jumbo);
1376
1377         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1378                             erp->er_index, &oword, B_TRUE);
1379
1380         return (0);
1381
1382 #if !EFSYS_OPT_RX_SCATTER
1383 fail5:
1384         EFSYS_PROBE(fail5);
1385 #endif
1386 fail4:
1387         EFSYS_PROBE(fail4);
1388 fail3:
1389         EFSYS_PROBE(fail3);
1390 fail2:
1391         EFSYS_PROBE(fail2);
1392 fail1:
1393         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1394
1395         return (rc);
1396 }
1397
1398 static          void
1399 siena_rx_qdestroy(
1400         __in    efx_rxq_t *erp)
1401 {
1402         efx_nic_t *enp = erp->er_enp;
1403         efx_oword_t oword;
1404
1405         EFSYS_ASSERT(enp->en_rx_qcount != 0);
1406         --enp->en_rx_qcount;
1407
1408         /* Purge descriptor queue */
1409         EFX_ZERO_OWORD(oword);
1410
1411         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1412                             erp->er_index, &oword, B_TRUE);
1413
1414         /* Free the RXQ object */
1415         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
1416 }
1417
1418 static          void
1419 siena_rx_fini(
1420         __in    efx_nic_t *enp)
1421 {
1422         _NOTE(ARGUNUSED(enp))
1423 }
1424
1425 #endif /* EFSYS_OPT_SIENA */