net/sfc/base: honour packed stream RSS restriction
[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_scale_hash_flags_get(
299         __in                                    efx_nic_t *enp,
300         __in                                    efx_rx_hash_alg_t hash_alg,
301         __inout_ecount(EFX_RX_HASH_NFLAGS)      unsigned int *flags,
302         __out                                   unsigned int *nflagsp)
303 {
304         efx_nic_cfg_t *encp = &enp->en_nic_cfg;
305         boolean_t l4;
306         boolean_t additional_modes;
307         unsigned int *entryp = flags;
308         efx_rc_t rc;
309
310         if (flags == NULL || nflagsp == NULL) {
311                 rc = EINVAL;
312                 goto fail1;
313         }
314
315         l4 = encp->enc_rx_scale_l4_hash_supported;
316         additional_modes = encp->enc_rx_scale_additional_modes_supported;
317
318 #define LIST_FLAGS(_entryp, _class, _l4_hashing, _additional_modes)     \
319         do {                                                            \
320                 if (_l4_hashing) {                                      \
321                         *(_entryp++) = EFX_RX_HASH(_class, 4TUPLE);     \
322                                                                         \
323                         if (_additional_modes) {                        \
324                                 *(_entryp++) =                          \
325                                     EFX_RX_HASH(_class, 2TUPLE_DST);    \
326                                 *(_entryp++) =                          \
327                                     EFX_RX_HASH(_class, 2TUPLE_SRC);    \
328                         }                                               \
329                 }                                                       \
330                                                                         \
331                 *(_entryp++) = EFX_RX_HASH(_class, 2TUPLE);             \
332                                                                         \
333                 if (_additional_modes) {                                \
334                         *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_DST); \
335                         *(_entryp++) = EFX_RX_HASH(_class, 1TUPLE_SRC); \
336                 }                                                       \
337                                                                         \
338                 *(_entryp++) = EFX_RX_HASH(_class, DISABLE);            \
339                                                                         \
340                 _NOTE(CONSTANTCONDITION)                                \
341         } while (B_FALSE)
342
343         switch (hash_alg) {
344         case EFX_RX_HASHALG_PACKED_STREAM:
345                 if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0)
346                         break;
347                 /* FALLTHRU */
348         case EFX_RX_HASHALG_TOEPLITZ:
349                 if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0)
350                         break;
351
352                 LIST_FLAGS(entryp, IPV4_TCP, l4, additional_modes);
353                 LIST_FLAGS(entryp, IPV6_TCP, l4, additional_modes);
354
355                 if (additional_modes) {
356                         LIST_FLAGS(entryp, IPV4_UDP, l4, additional_modes);
357                         LIST_FLAGS(entryp, IPV6_UDP, l4, additional_modes);
358                 }
359
360                 LIST_FLAGS(entryp, IPV4, B_FALSE, additional_modes);
361                 LIST_FLAGS(entryp, IPV6, B_FALSE, additional_modes);
362                 break;
363
364         default:
365                 rc = EINVAL;
366                 goto fail2;
367         }
368
369 #undef LIST_FLAGS
370
371         *nflagsp = (unsigned int)(entryp - flags);
372         EFSYS_ASSERT3U(*nflagsp, <=, EFX_RX_HASH_NFLAGS);
373
374         return (0);
375
376 fail2:
377         EFSYS_PROBE(fail2);
378
379 fail1:
380         EFSYS_PROBE1(fail1, efx_rc_t, rc);
381
382         return (rc);
383 }
384
385         __checkReturn   efx_rc_t
386 efx_rx_hash_default_support_get(
387         __in            efx_nic_t *enp,
388         __out           efx_rx_hash_support_t *supportp)
389 {
390         efx_rc_t rc;
391
392         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
393         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
394
395         if (supportp == NULL) {
396                 rc = EINVAL;
397                 goto fail1;
398         }
399
400         /*
401          * Report the hashing support the client gets by default if it
402          * does not allocate an RSS context itself.
403          */
404         *supportp = enp->en_hash_support;
405
406         return (0);
407
408 fail1:
409         EFSYS_PROBE1(fail1, efx_rc_t, rc);
410
411         return (rc);
412 }
413
414         __checkReturn   efx_rc_t
415 efx_rx_scale_default_support_get(
416         __in            efx_nic_t *enp,
417         __out           efx_rx_scale_context_type_t *typep)
418 {
419         efx_rc_t rc;
420
421         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
422         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
423
424         if (typep == NULL) {
425                 rc = EINVAL;
426                 goto fail1;
427         }
428
429         /*
430          * Report the RSS support the client gets by default if it
431          * does not allocate an RSS context itself.
432          */
433         *typep = enp->en_rss_context_type;
434
435         return (0);
436
437 fail1:
438         EFSYS_PROBE1(fail1, efx_rc_t, rc);
439
440         return (rc);
441 }
442 #endif  /* EFSYS_OPT_RX_SCALE */
443
444 #if EFSYS_OPT_RX_SCALE
445         __checkReturn   efx_rc_t
446 efx_rx_scale_context_alloc(
447         __in            efx_nic_t *enp,
448         __in            efx_rx_scale_context_type_t type,
449         __in            uint32_t num_queues,
450         __out           uint32_t *rss_contextp)
451 {
452         const efx_rx_ops_t *erxop = enp->en_erxop;
453         efx_rc_t rc;
454
455         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
456         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
457
458         if (erxop->erxo_scale_context_alloc == NULL) {
459                 rc = ENOTSUP;
460                 goto fail1;
461         }
462         if ((rc = erxop->erxo_scale_context_alloc(enp, type,
463                             num_queues, rss_contextp)) != 0) {
464                 goto fail2;
465         }
466
467         return (0);
468
469 fail2:
470         EFSYS_PROBE(fail2);
471 fail1:
472         EFSYS_PROBE1(fail1, efx_rc_t, rc);
473         return (rc);
474 }
475 #endif  /* EFSYS_OPT_RX_SCALE */
476
477 #if EFSYS_OPT_RX_SCALE
478         __checkReturn   efx_rc_t
479 efx_rx_scale_context_free(
480         __in            efx_nic_t *enp,
481         __in            uint32_t rss_context)
482 {
483         const efx_rx_ops_t *erxop = enp->en_erxop;
484         efx_rc_t rc;
485
486         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
487         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
488
489         if (erxop->erxo_scale_context_free == NULL) {
490                 rc = ENOTSUP;
491                 goto fail1;
492         }
493         if ((rc = erxop->erxo_scale_context_free(enp, rss_context)) != 0)
494                 goto fail2;
495
496         return (0);
497
498 fail2:
499         EFSYS_PROBE(fail2);
500 fail1:
501         EFSYS_PROBE1(fail1, efx_rc_t, rc);
502         return (rc);
503 }
504 #endif  /* EFSYS_OPT_RX_SCALE */
505
506 #if EFSYS_OPT_RX_SCALE
507         __checkReturn   efx_rc_t
508 efx_rx_scale_mode_set(
509         __in            efx_nic_t *enp,
510         __in            uint32_t rss_context,
511         __in            efx_rx_hash_alg_t alg,
512         __in            efx_rx_hash_type_t type,
513         __in            boolean_t insert)
514 {
515         const efx_rx_ops_t *erxop = enp->en_erxop;
516         unsigned int type_flags[EFX_RX_HASH_NFLAGS];
517         unsigned int type_nflags;
518         efx_rx_hash_type_t type_check;
519         unsigned int i;
520         efx_rc_t rc;
521
522         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
523         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
524
525         /*
526          * Legacy flags and modern bits cannot be
527          * used at the same time in the hash type.
528          */
529         if ((type & EFX_RX_HASH_LEGACY_MASK) &&
530             (type & ~EFX_RX_HASH_LEGACY_MASK)) {
531                 rc = EINVAL;
532                 goto fail1;
533         }
534
535         /*
536          * Translate legacy flags to the new representation
537          * so that chip-specific handlers will consider the
538          * new flags only.
539          */
540         if (type & EFX_RX_HASH_IPV4) {
541                 type |= EFX_RX_HASH(IPV4, 2TUPLE);
542                 type |= EFX_RX_HASH(IPV4_TCP, 2TUPLE);
543                 type |= EFX_RX_HASH(IPV4_UDP, 2TUPLE);
544         }
545
546         if (type & EFX_RX_HASH_TCPIPV4)
547                 type |= EFX_RX_HASH(IPV4_TCP, 4TUPLE);
548
549         if (type & EFX_RX_HASH_IPV6) {
550                 type |= EFX_RX_HASH(IPV6, 2TUPLE);
551                 type |= EFX_RX_HASH(IPV6_TCP, 2TUPLE);
552                 type |= EFX_RX_HASH(IPV6_UDP, 2TUPLE);
553         }
554
555         if (type & EFX_RX_HASH_TCPIPV6)
556                 type |= EFX_RX_HASH(IPV6_TCP, 4TUPLE);
557
558         type &= ~EFX_RX_HASH_LEGACY_MASK;
559         type_check = type;
560
561         /*
562          * Get the list of supported hash flags and sanitise the input.
563          */
564         rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags, &type_nflags);
565         if (rc != 0)
566                 goto fail2;
567
568         for (i = 0; i < type_nflags; ++i) {
569                 if ((type_check & type_flags[i]) == type_flags[i])
570                         type_check &= ~(type_flags[i]);
571         }
572
573         if (type_check != 0) {
574                 rc = EINVAL;
575                 goto fail3;
576         }
577
578         if (erxop->erxo_scale_mode_set != NULL) {
579                 if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg,
580                             type, insert)) != 0)
581                         goto fail4;
582         }
583
584         return (0);
585
586 fail4:
587         EFSYS_PROBE(fail4);
588 fail3:
589         EFSYS_PROBE(fail3);
590 fail2:
591         EFSYS_PROBE(fail2);
592 fail1:
593         EFSYS_PROBE1(fail1, efx_rc_t, rc);
594         return (rc);
595 }
596 #endif  /* EFSYS_OPT_RX_SCALE */
597
598 #if EFSYS_OPT_RX_SCALE
599         __checkReturn   efx_rc_t
600 efx_rx_scale_key_set(
601         __in            efx_nic_t *enp,
602         __in            uint32_t rss_context,
603         __in_ecount(n)  uint8_t *key,
604         __in            size_t n)
605 {
606         const efx_rx_ops_t *erxop = enp->en_erxop;
607         efx_rc_t rc;
608
609         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
610         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
611
612         if ((rc = erxop->erxo_scale_key_set(enp, rss_context, key, n)) != 0)
613                 goto fail1;
614
615         return (0);
616
617 fail1:
618         EFSYS_PROBE1(fail1, efx_rc_t, rc);
619
620         return (rc);
621 }
622 #endif  /* EFSYS_OPT_RX_SCALE */
623
624 #if EFSYS_OPT_RX_SCALE
625         __checkReturn   efx_rc_t
626 efx_rx_scale_tbl_set(
627         __in            efx_nic_t *enp,
628         __in            uint32_t rss_context,
629         __in_ecount(n)  unsigned int *table,
630         __in            size_t n)
631 {
632         const efx_rx_ops_t *erxop = enp->en_erxop;
633         efx_rc_t rc;
634
635         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
636         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
637
638         if ((rc = erxop->erxo_scale_tbl_set(enp, rss_context, table, n)) != 0)
639                 goto fail1;
640
641         return (0);
642
643 fail1:
644         EFSYS_PROBE1(fail1, efx_rc_t, rc);
645
646         return (rc);
647 }
648 #endif  /* EFSYS_OPT_RX_SCALE */
649
650                                 void
651 efx_rx_qpost(
652         __in                    efx_rxq_t *erp,
653         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
654         __in                    size_t size,
655         __in                    unsigned int ndescs,
656         __in                    unsigned int completed,
657         __in                    unsigned int added)
658 {
659         efx_nic_t *enp = erp->er_enp;
660         const efx_rx_ops_t *erxop = enp->en_erxop;
661
662         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
663
664         erxop->erxo_qpost(erp, addrp, size, ndescs, completed, added);
665 }
666
667 #if EFSYS_OPT_RX_PACKED_STREAM
668
669                         void
670 efx_rx_qpush_ps_credits(
671         __in            efx_rxq_t *erp)
672 {
673         efx_nic_t *enp = erp->er_enp;
674         const efx_rx_ops_t *erxop = enp->en_erxop;
675
676         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
677
678         erxop->erxo_qpush_ps_credits(erp);
679 }
680
681         __checkReturn   uint8_t *
682 efx_rx_qps_packet_info(
683         __in            efx_rxq_t *erp,
684         __in            uint8_t *buffer,
685         __in            uint32_t buffer_length,
686         __in            uint32_t current_offset,
687         __out           uint16_t *lengthp,
688         __out           uint32_t *next_offsetp,
689         __out           uint32_t *timestamp)
690 {
691         efx_nic_t *enp = erp->er_enp;
692         const efx_rx_ops_t *erxop = enp->en_erxop;
693
694         return (erxop->erxo_qps_packet_info(erp, buffer,
695                 buffer_length, current_offset, lengthp,
696                 next_offsetp, timestamp));
697 }
698
699 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
700
701                         void
702 efx_rx_qpush(
703         __in            efx_rxq_t *erp,
704         __in            unsigned int added,
705         __inout         unsigned int *pushedp)
706 {
707         efx_nic_t *enp = erp->er_enp;
708         const efx_rx_ops_t *erxop = enp->en_erxop;
709
710         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
711
712         erxop->erxo_qpush(erp, added, pushedp);
713 }
714
715         __checkReturn   efx_rc_t
716 efx_rx_qflush(
717         __in            efx_rxq_t *erp)
718 {
719         efx_nic_t *enp = erp->er_enp;
720         const efx_rx_ops_t *erxop = enp->en_erxop;
721         efx_rc_t rc;
722
723         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
724
725         if ((rc = erxop->erxo_qflush(erp)) != 0)
726                 goto fail1;
727
728         return (0);
729
730 fail1:
731         EFSYS_PROBE1(fail1, efx_rc_t, rc);
732
733         return (rc);
734 }
735
736                         void
737 efx_rx_qenable(
738         __in            efx_rxq_t *erp)
739 {
740         efx_nic_t *enp = erp->er_enp;
741         const efx_rx_ops_t *erxop = enp->en_erxop;
742
743         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
744
745         erxop->erxo_qenable(erp);
746 }
747
748 static  __checkReturn   efx_rc_t
749 efx_rx_qcreate_internal(
750         __in            efx_nic_t *enp,
751         __in            unsigned int index,
752         __in            unsigned int label,
753         __in            efx_rxq_type_t type,
754         __in            uint32_t type_data,
755         __in            efsys_mem_t *esmp,
756         __in            size_t ndescs,
757         __in            uint32_t id,
758         __in            unsigned int flags,
759         __in            efx_evq_t *eep,
760         __deref_out     efx_rxq_t **erpp)
761 {
762         const efx_rx_ops_t *erxop = enp->en_erxop;
763         efx_rxq_t *erp;
764         efx_rc_t rc;
765
766         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
767         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
768
769         /* Allocate an RXQ object */
770         EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
771
772         if (erp == NULL) {
773                 rc = ENOMEM;
774                 goto fail1;
775         }
776
777         erp->er_magic = EFX_RXQ_MAGIC;
778         erp->er_enp = enp;
779         erp->er_index = index;
780         erp->er_mask = ndescs - 1;
781         erp->er_esmp = esmp;
782
783         if ((rc = erxop->erxo_qcreate(enp, index, label, type, type_data, esmp,
784             ndescs, id, flags, eep, erp)) != 0)
785                 goto fail2;
786
787         enp->en_rx_qcount++;
788         *erpp = erp;
789
790         return (0);
791
792 fail2:
793         EFSYS_PROBE(fail2);
794
795         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
796 fail1:
797         EFSYS_PROBE1(fail1, efx_rc_t, rc);
798
799         return (rc);
800 }
801
802         __checkReturn   efx_rc_t
803 efx_rx_qcreate(
804         __in            efx_nic_t *enp,
805         __in            unsigned int index,
806         __in            unsigned int label,
807         __in            efx_rxq_type_t type,
808         __in            efsys_mem_t *esmp,
809         __in            size_t ndescs,
810         __in            uint32_t id,
811         __in            unsigned int flags,
812         __in            efx_evq_t *eep,
813         __deref_out     efx_rxq_t **erpp)
814 {
815         return efx_rx_qcreate_internal(enp, index, label, type, 0, esmp, ndescs,
816             id, flags, eep, erpp);
817 }
818
819 #if EFSYS_OPT_RX_PACKED_STREAM
820
821         __checkReturn   efx_rc_t
822 efx_rx_qcreate_packed_stream(
823         __in            efx_nic_t *enp,
824         __in            unsigned int index,
825         __in            unsigned int label,
826         __in            uint32_t ps_buf_size,
827         __in            efsys_mem_t *esmp,
828         __in            size_t ndescs,
829         __in            efx_evq_t *eep,
830         __deref_out     efx_rxq_t **erpp)
831 {
832         return efx_rx_qcreate_internal(enp, index, label,
833             EFX_RXQ_TYPE_PACKED_STREAM, ps_buf_size, esmp, ndescs,
834             0 /* id unused on EF10 */, EFX_RXQ_FLAG_NONE, eep, erpp);
835 }
836
837 #endif
838
839                         void
840 efx_rx_qdestroy(
841         __in            efx_rxq_t *erp)
842 {
843         efx_nic_t *enp = erp->er_enp;
844         const efx_rx_ops_t *erxop = enp->en_erxop;
845
846         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
847
848         erxop->erxo_qdestroy(erp);
849 }
850
851         __checkReturn   efx_rc_t
852 efx_pseudo_hdr_pkt_length_get(
853         __in            efx_rxq_t *erp,
854         __in            uint8_t *buffer,
855         __out           uint16_t *lengthp)
856 {
857         efx_nic_t *enp = erp->er_enp;
858         const efx_rx_ops_t *erxop = enp->en_erxop;
859
860         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
861
862         return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
863 }
864
865 #if EFSYS_OPT_RX_SCALE
866         __checkReturn   uint32_t
867 efx_pseudo_hdr_hash_get(
868         __in            efx_rxq_t *erp,
869         __in            efx_rx_hash_alg_t func,
870         __in            uint8_t *buffer)
871 {
872         efx_nic_t *enp = erp->er_enp;
873         const efx_rx_ops_t *erxop = enp->en_erxop;
874
875         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
876
877         EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
878         return (erxop->erxo_prefix_hash(enp, func, buffer));
879 }
880 #endif  /* EFSYS_OPT_RX_SCALE */
881
882 #if EFSYS_OPT_SIENA
883
884 static  __checkReturn   efx_rc_t
885 siena_rx_init(
886         __in            efx_nic_t *enp)
887 {
888         efx_oword_t oword;
889         unsigned int index;
890
891         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
892
893         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
894         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);
895         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);
896         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);
897         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);
898         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);
899         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
900
901         /* Zero the RSS table */
902         for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;
903             index++) {
904                 EFX_ZERO_OWORD(oword);
905                 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
906                                     index, &oword, B_TRUE);
907         }
908
909 #if EFSYS_OPT_RX_SCALE
910         /* The RSS key and indirection table are writable. */
911         enp->en_rss_context_type = EFX_RX_SCALE_EXCLUSIVE;
912
913         /* Hardware can insert RX hash with/without RSS */
914         enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
915 #endif  /* EFSYS_OPT_RX_SCALE */
916
917         return (0);
918 }
919
920 #if EFSYS_OPT_RX_SCATTER
921 static  __checkReturn   efx_rc_t
922 siena_rx_scatter_enable(
923         __in            efx_nic_t *enp,
924         __in            unsigned int buf_size)
925 {
926         unsigned int nbuf32;
927         efx_oword_t oword;
928         efx_rc_t rc;
929
930         nbuf32 = buf_size / 32;
931         if ((nbuf32 == 0) ||
932             (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
933             ((buf_size % 32) != 0)) {
934                 rc = EINVAL;
935                 goto fail1;
936         }
937
938         if (enp->en_rx_qcount > 0) {
939                 rc = EBUSY;
940                 goto fail2;
941         }
942
943         /* Set scatter buffer size */
944         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
945         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32);
946         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
947
948         /* Enable scatter for packets not matching a filter */
949         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
950         EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1);
951         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
952
953         return (0);
954
955 fail2:
956         EFSYS_PROBE(fail2);
957 fail1:
958         EFSYS_PROBE1(fail1, efx_rc_t, rc);
959
960         return (rc);
961 }
962 #endif  /* EFSYS_OPT_RX_SCATTER */
963
964
965 #define EFX_RX_LFSR_HASH(_enp, _insert)                                 \
966         do {                                                            \
967                 efx_oword_t oword;                                      \
968                                                                         \
969                 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);        \
970                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);      \
971                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);       \
972                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);       \
973                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,    \
974                     (_insert) ? 1 : 0);                                 \
975                 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);       \
976                                                                         \
977                 if ((_enp)->en_family == EFX_FAMILY_SIENA) {            \
978                         EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3,   \
979                             &oword);                                    \
980                         EFX_SET_OWORD_FIELD(oword,                      \
981                             FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0);        \
982                         EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3,  \
983                             &oword);                                    \
984                 }                                                       \
985                                                                         \
986                 _NOTE(CONSTANTCONDITION)                                \
987         } while (B_FALSE)
988
989 #define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp)             \
990         do {                                                            \
991                 efx_oword_t oword;                                      \
992                                                                         \
993                 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);        \
994                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1);      \
995                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH,           \
996                     (_ip) ? 1 : 0);                                     \
997                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP,           \
998                     (_tcp) ? 0 : 1);                                    \
999                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,    \
1000                     (_insert) ? 1 : 0);                                 \
1001                 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);       \
1002                                                                         \
1003                 _NOTE(CONSTANTCONDITION)                                \
1004         } while (B_FALSE)
1005
1006 #define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc)                 \
1007         do {                                                            \
1008                 efx_oword_t oword;                                      \
1009                                                                         \
1010                 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);  \
1011                 EFX_SET_OWORD_FIELD(oword,                              \
1012                     FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1);                \
1013                 EFX_SET_OWORD_FIELD(oword,                              \
1014                     FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0); \
1015                 EFX_SET_OWORD_FIELD(oword,                              \
1016                     FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1);   \
1017                 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
1018                                                                         \
1019                 (_rc) = 0;                                              \
1020                                                                         \
1021                 _NOTE(CONSTANTCONDITION)                                \
1022         } while (B_FALSE)
1023
1024
1025 #if EFSYS_OPT_RX_SCALE
1026
1027 static  __checkReturn   efx_rc_t
1028 siena_rx_scale_mode_set(
1029         __in            efx_nic_t *enp,
1030         __in            uint32_t rss_context,
1031         __in            efx_rx_hash_alg_t alg,
1032         __in            efx_rx_hash_type_t type,
1033         __in            boolean_t insert)
1034 {
1035         efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE);
1036         efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
1037         efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE);
1038         efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
1039         efx_rc_t rc;
1040
1041         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1042                 rc = EINVAL;
1043                 goto fail1;
1044         }
1045
1046         switch (alg) {
1047         case EFX_RX_HASHALG_LFSR:
1048                 EFX_RX_LFSR_HASH(enp, insert);
1049                 break;
1050
1051         case EFX_RX_HASHALG_TOEPLITZ:
1052                 EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
1053                     (type & type_ipv4) == type_ipv4,
1054                     (type & type_ipv4_tcp) == type_ipv4_tcp);
1055
1056                 EFX_RX_TOEPLITZ_IPV6_HASH(enp,
1057                     (type & type_ipv6) == type_ipv6,
1058                     (type & type_ipv6_tcp) == type_ipv6_tcp,
1059                     rc);
1060                 if (rc != 0)
1061                         goto fail2;
1062
1063                 break;
1064
1065         default:
1066                 rc = EINVAL;
1067                 goto fail3;
1068         }
1069
1070         return (0);
1071
1072 fail3:
1073         EFSYS_PROBE(fail3);
1074 fail2:
1075         EFSYS_PROBE(fail2);
1076 fail1:
1077         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1078
1079         EFX_RX_LFSR_HASH(enp, B_FALSE);
1080
1081         return (rc);
1082 }
1083 #endif
1084
1085 #if EFSYS_OPT_RX_SCALE
1086 static  __checkReturn   efx_rc_t
1087 siena_rx_scale_key_set(
1088         __in            efx_nic_t *enp,
1089         __in            uint32_t rss_context,
1090         __in_ecount(n)  uint8_t *key,
1091         __in            size_t n)
1092 {
1093         efx_oword_t oword;
1094         unsigned int byte;
1095         unsigned int offset;
1096         efx_rc_t rc;
1097
1098         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1099                 rc = EINVAL;
1100                 goto fail1;
1101         }
1102
1103         byte = 0;
1104
1105         /* Write Toeplitz IPv4 hash key */
1106         EFX_ZERO_OWORD(oword);
1107         for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
1108             offset > 0 && byte < n;
1109             --offset)
1110                 oword.eo_u8[offset - 1] = key[byte++];
1111
1112         EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
1113
1114         byte = 0;
1115
1116         /* Verify Toeplitz IPv4 hash key */
1117         EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
1118         for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
1119             offset > 0 && byte < n;
1120             --offset) {
1121                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1122                         rc = EFAULT;
1123                         goto fail2;
1124                 }
1125         }
1126
1127         if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
1128                 goto done;
1129
1130         byte = 0;
1131
1132         /* Write Toeplitz IPv6 hash key 3 */
1133         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1134         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
1135             FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
1136             offset > 0 && byte < n;
1137             --offset)
1138                 oword.eo_u8[offset - 1] = key[byte++];
1139
1140         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1141
1142         /* Write Toeplitz IPv6 hash key 2 */
1143         EFX_ZERO_OWORD(oword);
1144         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1145             FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1146             offset > 0 && byte < n;
1147             --offset)
1148                 oword.eo_u8[offset - 1] = key[byte++];
1149
1150         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1151
1152         /* Write Toeplitz IPv6 hash key 1 */
1153         EFX_ZERO_OWORD(oword);
1154         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1155             FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1156             offset > 0 && byte < n;
1157             --offset)
1158                 oword.eo_u8[offset - 1] = key[byte++];
1159
1160         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1161
1162         byte = 0;
1163
1164         /* Verify Toeplitz IPv6 hash key 3 */
1165         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1166         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
1167             FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
1168             offset > 0 && byte < n;
1169             --offset) {
1170                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1171                         rc = EFAULT;
1172                         goto fail3;
1173                 }
1174         }
1175
1176         /* Verify Toeplitz IPv6 hash key 2 */
1177         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1178         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1179             FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1180             offset > 0 && byte < n;
1181             --offset) {
1182                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1183                         rc = EFAULT;
1184                         goto fail4;
1185                 }
1186         }
1187
1188         /* Verify Toeplitz IPv6 hash key 1 */
1189         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1190         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1191             FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1192             offset > 0 && byte < n;
1193             --offset) {
1194                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1195                         rc = EFAULT;
1196                         goto fail5;
1197                 }
1198         }
1199
1200 done:
1201         return (0);
1202
1203 fail5:
1204         EFSYS_PROBE(fail5);
1205 fail4:
1206         EFSYS_PROBE(fail4);
1207 fail3:
1208         EFSYS_PROBE(fail3);
1209 fail2:
1210         EFSYS_PROBE(fail2);
1211 fail1:
1212         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1213
1214         return (rc);
1215 }
1216 #endif
1217
1218 #if EFSYS_OPT_RX_SCALE
1219 static  __checkReturn   efx_rc_t
1220 siena_rx_scale_tbl_set(
1221         __in            efx_nic_t *enp,
1222         __in            uint32_t rss_context,
1223         __in_ecount(n)  unsigned int *table,
1224         __in            size_t n)
1225 {
1226         efx_oword_t oword;
1227         int index;
1228         efx_rc_t rc;
1229
1230         EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
1231         EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
1232
1233         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1234                 rc = EINVAL;
1235                 goto fail1;
1236         }
1237
1238         if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {
1239                 rc = EINVAL;
1240                 goto fail2;
1241         }
1242
1243         for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {
1244                 uint32_t byte;
1245
1246                 /* Calculate the entry to place in the table */
1247                 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1248
1249                 EFSYS_PROBE2(table, int, index, uint32_t, byte);
1250
1251                 EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);
1252
1253                 /* Write the table */
1254                 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
1255                                     index, &oword, B_TRUE);
1256         }
1257
1258         for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
1259                 uint32_t byte;
1260
1261                 /* Determine if we're starting a new batch */
1262                 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1263
1264                 /* Read the table */
1265                 EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
1266                                     index, &oword, B_TRUE);
1267
1268                 /* Verify the entry */
1269                 if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
1270                         rc = EFAULT;
1271                         goto fail3;
1272                 }
1273         }
1274
1275         return (0);
1276
1277 fail3:
1278         EFSYS_PROBE(fail3);
1279 fail2:
1280         EFSYS_PROBE(fail2);
1281 fail1:
1282         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1283
1284         return (rc);
1285 }
1286 #endif
1287
1288 /*
1289  * Falcon/Siena pseudo-header
1290  * --------------------------
1291  *
1292  * Receive packets are prefixed by an optional 16 byte pseudo-header.
1293  * The pseudo-header is a byte array of one of the forms:
1294  *
1295  *  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
1296  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
1297  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
1298  *
1299  * where:
1300  *   TT.TT.TT.TT   Toeplitz hash (32-bit big-endian)
1301  *   LL.LL         LFSR hash     (16-bit big-endian)
1302  */
1303
1304 #if EFSYS_OPT_RX_SCALE
1305 static  __checkReturn   uint32_t
1306 siena_rx_prefix_hash(
1307         __in            efx_nic_t *enp,
1308         __in            efx_rx_hash_alg_t func,
1309         __in            uint8_t *buffer)
1310 {
1311         _NOTE(ARGUNUSED(enp))
1312
1313         switch (func) {
1314         case EFX_RX_HASHALG_TOEPLITZ:
1315                 return ((buffer[12] << 24) |
1316                     (buffer[13] << 16) |
1317                     (buffer[14] <<  8) |
1318                     buffer[15]);
1319
1320         case EFX_RX_HASHALG_LFSR:
1321                 return ((buffer[14] << 8) | buffer[15]);
1322
1323         default:
1324                 EFSYS_ASSERT(0);
1325                 return (0);
1326         }
1327 }
1328 #endif /* EFSYS_OPT_RX_SCALE */
1329
1330 static  __checkReturn   efx_rc_t
1331 siena_rx_prefix_pktlen(
1332         __in            efx_nic_t *enp,
1333         __in            uint8_t *buffer,
1334         __out           uint16_t *lengthp)
1335 {
1336         _NOTE(ARGUNUSED(enp, buffer, lengthp))
1337
1338         /* Not supported by Falcon/Siena hardware */
1339         EFSYS_ASSERT(0);
1340         return (ENOTSUP);
1341 }
1342
1343
1344 static                          void
1345 siena_rx_qpost(
1346         __in                    efx_rxq_t *erp,
1347         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
1348         __in                    size_t size,
1349         __in                    unsigned int ndescs,
1350         __in                    unsigned int completed,
1351         __in                    unsigned int added)
1352 {
1353         efx_qword_t qword;
1354         unsigned int i;
1355         unsigned int offset;
1356         unsigned int id;
1357
1358         /* The client driver must not overfill the queue */
1359         EFSYS_ASSERT3U(added - completed + ndescs, <=,
1360             EFX_RXQ_LIMIT(erp->er_mask + 1));
1361
1362         id = added & (erp->er_mask);
1363         for (i = 0; i < ndescs; i++) {
1364                 EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
1365                     unsigned int, id, efsys_dma_addr_t, addrp[i],
1366                     size_t, size);
1367
1368                 EFX_POPULATE_QWORD_3(qword,
1369                     FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),
1370                     FSF_AZ_RX_KER_BUF_ADDR_DW0,
1371                     (uint32_t)(addrp[i] & 0xffffffff),
1372                     FSF_AZ_RX_KER_BUF_ADDR_DW1,
1373                     (uint32_t)(addrp[i] >> 32));
1374
1375                 offset = id * sizeof (efx_qword_t);
1376                 EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
1377
1378                 id = (id + 1) & (erp->er_mask);
1379         }
1380 }
1381
1382 static                  void
1383 siena_rx_qpush(
1384         __in    efx_rxq_t *erp,
1385         __in    unsigned int added,
1386         __inout unsigned int *pushedp)
1387 {
1388         efx_nic_t *enp = erp->er_enp;
1389         unsigned int pushed = *pushedp;
1390         uint32_t wptr;
1391         efx_oword_t oword;
1392         efx_dword_t dword;
1393
1394         /* All descriptors are pushed */
1395         *pushedp = added;
1396
1397         /* Push the populated descriptors out */
1398         wptr = added & erp->er_mask;
1399
1400         EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);
1401
1402         /* Only write the third DWORD */
1403         EFX_POPULATE_DWORD_1(dword,
1404             EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
1405
1406         /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
1407         EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
1408             wptr, pushed & erp->er_mask);
1409         EFSYS_PIO_WRITE_BARRIER();
1410         EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
1411                             erp->er_index, &dword, B_FALSE);
1412 }
1413
1414 #if EFSYS_OPT_RX_PACKED_STREAM
1415 static          void
1416 siena_rx_qpush_ps_credits(
1417         __in            efx_rxq_t *erp)
1418 {
1419         /* Not supported by Siena hardware */
1420         EFSYS_ASSERT(0);
1421 }
1422
1423 static          uint8_t *
1424 siena_rx_qps_packet_info(
1425         __in            efx_rxq_t *erp,
1426         __in            uint8_t *buffer,
1427         __in            uint32_t buffer_length,
1428         __in            uint32_t current_offset,
1429         __out           uint16_t *lengthp,
1430         __out           uint32_t *next_offsetp,
1431         __out           uint32_t *timestamp)
1432 {
1433         /* Not supported by Siena hardware */
1434         EFSYS_ASSERT(0);
1435
1436         return (NULL);
1437 }
1438 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
1439
1440 static  __checkReturn   efx_rc_t
1441 siena_rx_qflush(
1442         __in    efx_rxq_t *erp)
1443 {
1444         efx_nic_t *enp = erp->er_enp;
1445         efx_oword_t oword;
1446         uint32_t label;
1447
1448         label = erp->er_index;
1449
1450         /* Flush the queue */
1451         EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
1452             FRF_AZ_RX_FLUSH_DESCQ, label);
1453         EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
1454
1455         return (0);
1456 }
1457
1458 static          void
1459 siena_rx_qenable(
1460         __in    efx_rxq_t *erp)
1461 {
1462         efx_nic_t *enp = erp->er_enp;
1463         efx_oword_t oword;
1464
1465         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
1466
1467         EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
1468                             erp->er_index, &oword, B_TRUE);
1469
1470         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
1471         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
1472         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
1473
1474         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1475                             erp->er_index, &oword, B_TRUE);
1476 }
1477
1478 static  __checkReturn   efx_rc_t
1479 siena_rx_qcreate(
1480         __in            efx_nic_t *enp,
1481         __in            unsigned int index,
1482         __in            unsigned int label,
1483         __in            efx_rxq_type_t type,
1484         __in            uint32_t type_data,
1485         __in            efsys_mem_t *esmp,
1486         __in            size_t ndescs,
1487         __in            uint32_t id,
1488         __in            unsigned int flags,
1489         __in            efx_evq_t *eep,
1490         __in            efx_rxq_t *erp)
1491 {
1492         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1493         efx_oword_t oword;
1494         uint32_t size;
1495         boolean_t jumbo = B_FALSE;
1496         efx_rc_t rc;
1497
1498         _NOTE(ARGUNUSED(esmp))
1499         _NOTE(ARGUNUSED(type_data))
1500
1501         EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
1502             (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
1503         EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
1504         EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
1505
1506         EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
1507         EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
1508
1509         if (!ISP2(ndescs) ||
1510             (ndescs < EFX_RXQ_MINNDESCS) || (ndescs > EFX_RXQ_MAXNDESCS)) {
1511                 rc = EINVAL;
1512                 goto fail1;
1513         }
1514         if (index >= encp->enc_rxq_limit) {
1515                 rc = EINVAL;
1516                 goto fail2;
1517         }
1518         for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);
1519             size++)
1520                 if ((1 << size) == (int)(ndescs / EFX_RXQ_MINNDESCS))
1521                         break;
1522         if (id + (1 << size) >= encp->enc_buftbl_limit) {
1523                 rc = EINVAL;
1524                 goto fail3;
1525         }
1526
1527         switch (type) {
1528         case EFX_RXQ_TYPE_DEFAULT:
1529                 break;
1530
1531         default:
1532                 rc = EINVAL;
1533                 goto fail4;
1534         }
1535
1536         if (flags & EFX_RXQ_FLAG_SCATTER) {
1537 #if EFSYS_OPT_RX_SCATTER
1538                 jumbo = B_TRUE;
1539 #else
1540                 rc = EINVAL;
1541                 goto fail5;
1542 #endif  /* EFSYS_OPT_RX_SCATTER */
1543         }
1544
1545         /* Set up the new descriptor queue */
1546         EFX_POPULATE_OWORD_7(oword,
1547             FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
1548             FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,
1549             FRF_AZ_RX_DESCQ_OWNER_ID, 0,
1550             FRF_AZ_RX_DESCQ_LABEL, label,
1551             FRF_AZ_RX_DESCQ_SIZE, size,
1552             FRF_AZ_RX_DESCQ_TYPE, 0,
1553             FRF_AZ_RX_DESCQ_JUMBO, jumbo);
1554
1555         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1556                             erp->er_index, &oword, B_TRUE);
1557
1558         return (0);
1559
1560 #if !EFSYS_OPT_RX_SCATTER
1561 fail5:
1562         EFSYS_PROBE(fail5);
1563 #endif
1564 fail4:
1565         EFSYS_PROBE(fail4);
1566 fail3:
1567         EFSYS_PROBE(fail3);
1568 fail2:
1569         EFSYS_PROBE(fail2);
1570 fail1:
1571         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1572
1573         return (rc);
1574 }
1575
1576 static          void
1577 siena_rx_qdestroy(
1578         __in    efx_rxq_t *erp)
1579 {
1580         efx_nic_t *enp = erp->er_enp;
1581         efx_oword_t oword;
1582
1583         EFSYS_ASSERT(enp->en_rx_qcount != 0);
1584         --enp->en_rx_qcount;
1585
1586         /* Purge descriptor queue */
1587         EFX_ZERO_OWORD(oword);
1588
1589         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1590                             erp->er_index, &oword, B_TRUE);
1591
1592         /* Free the RXQ object */
1593         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
1594 }
1595
1596 static          void
1597 siena_rx_fini(
1598         __in    efx_nic_t *enp)
1599 {
1600         _NOTE(ARGUNUSED(enp))
1601 }
1602
1603 #endif /* EFSYS_OPT_SIENA */