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