New upstream version 18.08
[deb_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            const efx_rxq_type_data_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            const efx_rxq_type_data_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, NULL,
816             esmp, ndescs, 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         efx_rxq_type_data_t type_data;
833
834         memset(&type_data, 0, sizeof(type_data));
835
836         type_data.ertd_packed_stream.eps_buf_size = ps_buf_size;
837
838         return efx_rx_qcreate_internal(enp, index, label,
839             EFX_RXQ_TYPE_PACKED_STREAM, &type_data, esmp, ndescs,
840             0 /* id unused on EF10 */, EFX_RXQ_FLAG_NONE, eep, erpp);
841 }
842
843 #endif
844
845 #if EFSYS_OPT_RX_ES_SUPER_BUFFER
846
847         __checkReturn   efx_rc_t
848 efx_rx_qcreate_es_super_buffer(
849         __in            efx_nic_t *enp,
850         __in            unsigned int index,
851         __in            unsigned int label,
852         __in            uint32_t n_bufs_per_desc,
853         __in            uint32_t max_dma_len,
854         __in            uint32_t buf_stride,
855         __in            uint32_t hol_block_timeout,
856         __in            efsys_mem_t *esmp,
857         __in            size_t ndescs,
858         __in            unsigned int flags,
859         __in            efx_evq_t *eep,
860         __deref_out     efx_rxq_t **erpp)
861 {
862         efx_rc_t rc;
863         efx_rxq_type_data_t type_data;
864
865         if (hol_block_timeout > EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX) {
866                 rc = EINVAL;
867                 goto fail1;
868         }
869
870         memset(&type_data, 0, sizeof(type_data));
871
872         type_data.ertd_es_super_buffer.eessb_bufs_per_desc = n_bufs_per_desc;
873         type_data.ertd_es_super_buffer.eessb_max_dma_len = max_dma_len;
874         type_data.ertd_es_super_buffer.eessb_buf_stride = buf_stride;
875         type_data.ertd_es_super_buffer.eessb_hol_block_timeout =
876             hol_block_timeout;
877
878         rc = efx_rx_qcreate_internal(enp, index, label,
879             EFX_RXQ_TYPE_ES_SUPER_BUFFER, &type_data, esmp, ndescs,
880             0 /* id unused on EF10 */, flags, eep, erpp);
881         if (rc != 0)
882                 goto fail2;
883
884         return (0);
885
886 fail2:
887         EFSYS_PROBE(fail2);
888 fail1:
889         EFSYS_PROBE1(fail1, efx_rc_t, rc);
890
891         return (rc);
892 }
893
894 #endif
895
896
897                         void
898 efx_rx_qdestroy(
899         __in            efx_rxq_t *erp)
900 {
901         efx_nic_t *enp = erp->er_enp;
902         const efx_rx_ops_t *erxop = enp->en_erxop;
903
904         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
905
906         erxop->erxo_qdestroy(erp);
907 }
908
909         __checkReturn   efx_rc_t
910 efx_pseudo_hdr_pkt_length_get(
911         __in            efx_rxq_t *erp,
912         __in            uint8_t *buffer,
913         __out           uint16_t *lengthp)
914 {
915         efx_nic_t *enp = erp->er_enp;
916         const efx_rx_ops_t *erxop = enp->en_erxop;
917
918         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
919
920         return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
921 }
922
923 #if EFSYS_OPT_RX_SCALE
924         __checkReturn   uint32_t
925 efx_pseudo_hdr_hash_get(
926         __in            efx_rxq_t *erp,
927         __in            efx_rx_hash_alg_t func,
928         __in            uint8_t *buffer)
929 {
930         efx_nic_t *enp = erp->er_enp;
931         const efx_rx_ops_t *erxop = enp->en_erxop;
932
933         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
934
935         EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
936         return (erxop->erxo_prefix_hash(enp, func, buffer));
937 }
938 #endif  /* EFSYS_OPT_RX_SCALE */
939
940 #if EFSYS_OPT_SIENA
941
942 static  __checkReturn   efx_rc_t
943 siena_rx_init(
944         __in            efx_nic_t *enp)
945 {
946         efx_oword_t oword;
947         unsigned int index;
948
949         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
950
951         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
952         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);
953         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);
954         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);
955         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);
956         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);
957         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
958
959         /* Zero the RSS table */
960         for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;
961             index++) {
962                 EFX_ZERO_OWORD(oword);
963                 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
964                                     index, &oword, B_TRUE);
965         }
966
967 #if EFSYS_OPT_RX_SCALE
968         /* The RSS key and indirection table are writable. */
969         enp->en_rss_context_type = EFX_RX_SCALE_EXCLUSIVE;
970
971         /* Hardware can insert RX hash with/without RSS */
972         enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
973 #endif  /* EFSYS_OPT_RX_SCALE */
974
975         return (0);
976 }
977
978 #if EFSYS_OPT_RX_SCATTER
979 static  __checkReturn   efx_rc_t
980 siena_rx_scatter_enable(
981         __in            efx_nic_t *enp,
982         __in            unsigned int buf_size)
983 {
984         unsigned int nbuf32;
985         efx_oword_t oword;
986         efx_rc_t rc;
987
988         nbuf32 = buf_size / 32;
989         if ((nbuf32 == 0) ||
990             (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
991             ((buf_size % 32) != 0)) {
992                 rc = EINVAL;
993                 goto fail1;
994         }
995
996         if (enp->en_rx_qcount > 0) {
997                 rc = EBUSY;
998                 goto fail2;
999         }
1000
1001         /* Set scatter buffer size */
1002         EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
1003         EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32);
1004         EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
1005
1006         /* Enable scatter for packets not matching a filter */
1007         EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
1008         EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1);
1009         EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
1010
1011         return (0);
1012
1013 fail2:
1014         EFSYS_PROBE(fail2);
1015 fail1:
1016         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1017
1018         return (rc);
1019 }
1020 #endif  /* EFSYS_OPT_RX_SCATTER */
1021
1022
1023 #define EFX_RX_LFSR_HASH(_enp, _insert)                                 \
1024         do {                                                            \
1025                 efx_oword_t oword;                                      \
1026                                                                         \
1027                 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);        \
1028                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);      \
1029                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);       \
1030                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);       \
1031                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,    \
1032                     (_insert) ? 1 : 0);                                 \
1033                 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);       \
1034                                                                         \
1035                 if ((_enp)->en_family == EFX_FAMILY_SIENA) {            \
1036                         EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3,   \
1037                             &oword);                                    \
1038                         EFX_SET_OWORD_FIELD(oword,                      \
1039                             FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0);        \
1040                         EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3,  \
1041                             &oword);                                    \
1042                 }                                                       \
1043                                                                         \
1044                 _NOTE(CONSTANTCONDITION)                                \
1045         } while (B_FALSE)
1046
1047 #define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp)             \
1048         do {                                                            \
1049                 efx_oword_t oword;                                      \
1050                                                                         \
1051                 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword);        \
1052                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1);      \
1053                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH,           \
1054                     (_ip) ? 1 : 0);                                     \
1055                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP,           \
1056                     (_tcp) ? 0 : 1);                                    \
1057                 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR,    \
1058                     (_insert) ? 1 : 0);                                 \
1059                 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword);       \
1060                                                                         \
1061                 _NOTE(CONSTANTCONDITION)                                \
1062         } while (B_FALSE)
1063
1064 #define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc)                 \
1065         do {                                                            \
1066                 efx_oword_t oword;                                      \
1067                                                                         \
1068                 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword);  \
1069                 EFX_SET_OWORD_FIELD(oword,                              \
1070                     FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1);                \
1071                 EFX_SET_OWORD_FIELD(oword,                              \
1072                     FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0); \
1073                 EFX_SET_OWORD_FIELD(oword,                              \
1074                     FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1);   \
1075                 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
1076                                                                         \
1077                 (_rc) = 0;                                              \
1078                                                                         \
1079                 _NOTE(CONSTANTCONDITION)                                \
1080         } while (B_FALSE)
1081
1082
1083 #if EFSYS_OPT_RX_SCALE
1084
1085 static  __checkReturn   efx_rc_t
1086 siena_rx_scale_mode_set(
1087         __in            efx_nic_t *enp,
1088         __in            uint32_t rss_context,
1089         __in            efx_rx_hash_alg_t alg,
1090         __in            efx_rx_hash_type_t type,
1091         __in            boolean_t insert)
1092 {
1093         efx_rx_hash_type_t type_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE);
1094         efx_rx_hash_type_t type_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
1095         efx_rx_hash_type_t type_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE);
1096         efx_rx_hash_type_t type_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
1097         efx_rc_t rc;
1098
1099         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1100                 rc = EINVAL;
1101                 goto fail1;
1102         }
1103
1104         switch (alg) {
1105         case EFX_RX_HASHALG_LFSR:
1106                 EFX_RX_LFSR_HASH(enp, insert);
1107                 break;
1108
1109         case EFX_RX_HASHALG_TOEPLITZ:
1110                 EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
1111                     (type & type_ipv4) == type_ipv4,
1112                     (type & type_ipv4_tcp) == type_ipv4_tcp);
1113
1114                 EFX_RX_TOEPLITZ_IPV6_HASH(enp,
1115                     (type & type_ipv6) == type_ipv6,
1116                     (type & type_ipv6_tcp) == type_ipv6_tcp,
1117                     rc);
1118                 if (rc != 0)
1119                         goto fail2;
1120
1121                 break;
1122
1123         default:
1124                 rc = EINVAL;
1125                 goto fail3;
1126         }
1127
1128         return (0);
1129
1130 fail3:
1131         EFSYS_PROBE(fail3);
1132 fail2:
1133         EFSYS_PROBE(fail2);
1134 fail1:
1135         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1136
1137         EFX_RX_LFSR_HASH(enp, B_FALSE);
1138
1139         return (rc);
1140 }
1141 #endif
1142
1143 #if EFSYS_OPT_RX_SCALE
1144 static  __checkReturn   efx_rc_t
1145 siena_rx_scale_key_set(
1146         __in            efx_nic_t *enp,
1147         __in            uint32_t rss_context,
1148         __in_ecount(n)  uint8_t *key,
1149         __in            size_t n)
1150 {
1151         efx_oword_t oword;
1152         unsigned int byte;
1153         unsigned int offset;
1154         efx_rc_t rc;
1155
1156         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1157                 rc = EINVAL;
1158                 goto fail1;
1159         }
1160
1161         byte = 0;
1162
1163         /* Write Toeplitz IPv4 hash key */
1164         EFX_ZERO_OWORD(oword);
1165         for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
1166             offset > 0 && byte < n;
1167             --offset)
1168                 oword.eo_u8[offset - 1] = key[byte++];
1169
1170         EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
1171
1172         byte = 0;
1173
1174         /* Verify Toeplitz IPv4 hash key */
1175         EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
1176         for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
1177             offset > 0 && byte < n;
1178             --offset) {
1179                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1180                         rc = EFAULT;
1181                         goto fail2;
1182                 }
1183         }
1184
1185         if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
1186                 goto done;
1187
1188         byte = 0;
1189
1190         /* Write Toeplitz IPv6 hash key 3 */
1191         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1192         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
1193             FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
1194             offset > 0 && byte < n;
1195             --offset)
1196                 oword.eo_u8[offset - 1] = key[byte++];
1197
1198         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1199
1200         /* Write Toeplitz IPv6 hash key 2 */
1201         EFX_ZERO_OWORD(oword);
1202         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1203             FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1204             offset > 0 && byte < n;
1205             --offset)
1206                 oword.eo_u8[offset - 1] = key[byte++];
1207
1208         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1209
1210         /* Write Toeplitz IPv6 hash key 1 */
1211         EFX_ZERO_OWORD(oword);
1212         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1213             FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1214             offset > 0 && byte < n;
1215             --offset)
1216                 oword.eo_u8[offset - 1] = key[byte++];
1217
1218         EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1219
1220         byte = 0;
1221
1222         /* Verify Toeplitz IPv6 hash key 3 */
1223         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1224         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
1225             FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
1226             offset > 0 && byte < n;
1227             --offset) {
1228                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1229                         rc = EFAULT;
1230                         goto fail3;
1231                 }
1232         }
1233
1234         /* Verify Toeplitz IPv6 hash key 2 */
1235         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1236         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1237             FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1238             offset > 0 && byte < n;
1239             --offset) {
1240                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1241                         rc = EFAULT;
1242                         goto fail4;
1243                 }
1244         }
1245
1246         /* Verify Toeplitz IPv6 hash key 1 */
1247         EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1248         for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1249             FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1250             offset > 0 && byte < n;
1251             --offset) {
1252                 if (oword.eo_u8[offset - 1] != key[byte++]) {
1253                         rc = EFAULT;
1254                         goto fail5;
1255                 }
1256         }
1257
1258 done:
1259         return (0);
1260
1261 fail5:
1262         EFSYS_PROBE(fail5);
1263 fail4:
1264         EFSYS_PROBE(fail4);
1265 fail3:
1266         EFSYS_PROBE(fail3);
1267 fail2:
1268         EFSYS_PROBE(fail2);
1269 fail1:
1270         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1271
1272         return (rc);
1273 }
1274 #endif
1275
1276 #if EFSYS_OPT_RX_SCALE
1277 static  __checkReturn   efx_rc_t
1278 siena_rx_scale_tbl_set(
1279         __in            efx_nic_t *enp,
1280         __in            uint32_t rss_context,
1281         __in_ecount(n)  unsigned int *table,
1282         __in            size_t n)
1283 {
1284         efx_oword_t oword;
1285         int index;
1286         efx_rc_t rc;
1287
1288         EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
1289         EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
1290
1291         if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1292                 rc = EINVAL;
1293                 goto fail1;
1294         }
1295
1296         if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {
1297                 rc = EINVAL;
1298                 goto fail2;
1299         }
1300
1301         for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {
1302                 uint32_t byte;
1303
1304                 /* Calculate the entry to place in the table */
1305                 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1306
1307                 EFSYS_PROBE2(table, int, index, uint32_t, byte);
1308
1309                 EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);
1310
1311                 /* Write the table */
1312                 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
1313                                     index, &oword, B_TRUE);
1314         }
1315
1316         for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
1317                 uint32_t byte;
1318
1319                 /* Determine if we're starting a new batch */
1320                 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1321
1322                 /* Read the table */
1323                 EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
1324                                     index, &oword, B_TRUE);
1325
1326                 /* Verify the entry */
1327                 if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
1328                         rc = EFAULT;
1329                         goto fail3;
1330                 }
1331         }
1332
1333         return (0);
1334
1335 fail3:
1336         EFSYS_PROBE(fail3);
1337 fail2:
1338         EFSYS_PROBE(fail2);
1339 fail1:
1340         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1341
1342         return (rc);
1343 }
1344 #endif
1345
1346 /*
1347  * Falcon/Siena pseudo-header
1348  * --------------------------
1349  *
1350  * Receive packets are prefixed by an optional 16 byte pseudo-header.
1351  * The pseudo-header is a byte array of one of the forms:
1352  *
1353  *  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
1354  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
1355  * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
1356  *
1357  * where:
1358  *   TT.TT.TT.TT   Toeplitz hash (32-bit big-endian)
1359  *   LL.LL         LFSR hash     (16-bit big-endian)
1360  */
1361
1362 #if EFSYS_OPT_RX_SCALE
1363 static  __checkReturn   uint32_t
1364 siena_rx_prefix_hash(
1365         __in            efx_nic_t *enp,
1366         __in            efx_rx_hash_alg_t func,
1367         __in            uint8_t *buffer)
1368 {
1369         _NOTE(ARGUNUSED(enp))
1370
1371         switch (func) {
1372         case EFX_RX_HASHALG_TOEPLITZ:
1373                 return ((buffer[12] << 24) |
1374                     (buffer[13] << 16) |
1375                     (buffer[14] <<  8) |
1376                     buffer[15]);
1377
1378         case EFX_RX_HASHALG_LFSR:
1379                 return ((buffer[14] << 8) | buffer[15]);
1380
1381         default:
1382                 EFSYS_ASSERT(0);
1383                 return (0);
1384         }
1385 }
1386 #endif /* EFSYS_OPT_RX_SCALE */
1387
1388 static  __checkReturn   efx_rc_t
1389 siena_rx_prefix_pktlen(
1390         __in            efx_nic_t *enp,
1391         __in            uint8_t *buffer,
1392         __out           uint16_t *lengthp)
1393 {
1394         _NOTE(ARGUNUSED(enp, buffer, lengthp))
1395
1396         /* Not supported by Falcon/Siena hardware */
1397         EFSYS_ASSERT(0);
1398         return (ENOTSUP);
1399 }
1400
1401
1402 static                          void
1403 siena_rx_qpost(
1404         __in                    efx_rxq_t *erp,
1405         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
1406         __in                    size_t size,
1407         __in                    unsigned int ndescs,
1408         __in                    unsigned int completed,
1409         __in                    unsigned int added)
1410 {
1411         efx_qword_t qword;
1412         unsigned int i;
1413         unsigned int offset;
1414         unsigned int id;
1415
1416         /* The client driver must not overfill the queue */
1417         EFSYS_ASSERT3U(added - completed + ndescs, <=,
1418             EFX_RXQ_LIMIT(erp->er_mask + 1));
1419
1420         id = added & (erp->er_mask);
1421         for (i = 0; i < ndescs; i++) {
1422                 EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
1423                     unsigned int, id, efsys_dma_addr_t, addrp[i],
1424                     size_t, size);
1425
1426                 EFX_POPULATE_QWORD_3(qword,
1427                     FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),
1428                     FSF_AZ_RX_KER_BUF_ADDR_DW0,
1429                     (uint32_t)(addrp[i] & 0xffffffff),
1430                     FSF_AZ_RX_KER_BUF_ADDR_DW1,
1431                     (uint32_t)(addrp[i] >> 32));
1432
1433                 offset = id * sizeof (efx_qword_t);
1434                 EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
1435
1436                 id = (id + 1) & (erp->er_mask);
1437         }
1438 }
1439
1440 static                  void
1441 siena_rx_qpush(
1442         __in    efx_rxq_t *erp,
1443         __in    unsigned int added,
1444         __inout unsigned int *pushedp)
1445 {
1446         efx_nic_t *enp = erp->er_enp;
1447         unsigned int pushed = *pushedp;
1448         uint32_t wptr;
1449         efx_oword_t oword;
1450         efx_dword_t dword;
1451
1452         /* All descriptors are pushed */
1453         *pushedp = added;
1454
1455         /* Push the populated descriptors out */
1456         wptr = added & erp->er_mask;
1457
1458         EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);
1459
1460         /* Only write the third DWORD */
1461         EFX_POPULATE_DWORD_1(dword,
1462             EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
1463
1464         /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
1465         EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
1466             wptr, pushed & erp->er_mask);
1467         EFSYS_PIO_WRITE_BARRIER();
1468         EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
1469                             erp->er_index, &dword, B_FALSE);
1470 }
1471
1472 #if EFSYS_OPT_RX_PACKED_STREAM
1473 static          void
1474 siena_rx_qpush_ps_credits(
1475         __in            efx_rxq_t *erp)
1476 {
1477         /* Not supported by Siena hardware */
1478         EFSYS_ASSERT(0);
1479 }
1480
1481 static          uint8_t *
1482 siena_rx_qps_packet_info(
1483         __in            efx_rxq_t *erp,
1484         __in            uint8_t *buffer,
1485         __in            uint32_t buffer_length,
1486         __in            uint32_t current_offset,
1487         __out           uint16_t *lengthp,
1488         __out           uint32_t *next_offsetp,
1489         __out           uint32_t *timestamp)
1490 {
1491         /* Not supported by Siena hardware */
1492         EFSYS_ASSERT(0);
1493
1494         return (NULL);
1495 }
1496 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
1497
1498 static  __checkReturn   efx_rc_t
1499 siena_rx_qflush(
1500         __in    efx_rxq_t *erp)
1501 {
1502         efx_nic_t *enp = erp->er_enp;
1503         efx_oword_t oword;
1504         uint32_t label;
1505
1506         label = erp->er_index;
1507
1508         /* Flush the queue */
1509         EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
1510             FRF_AZ_RX_FLUSH_DESCQ, label);
1511         EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
1512
1513         return (0);
1514 }
1515
1516 static          void
1517 siena_rx_qenable(
1518         __in    efx_rxq_t *erp)
1519 {
1520         efx_nic_t *enp = erp->er_enp;
1521         efx_oword_t oword;
1522
1523         EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
1524
1525         EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
1526                             erp->er_index, &oword, B_TRUE);
1527
1528         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
1529         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
1530         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
1531
1532         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1533                             erp->er_index, &oword, B_TRUE);
1534 }
1535
1536 static  __checkReturn   efx_rc_t
1537 siena_rx_qcreate(
1538         __in            efx_nic_t *enp,
1539         __in            unsigned int index,
1540         __in            unsigned int label,
1541         __in            efx_rxq_type_t type,
1542         __in            const efx_rxq_type_data_t *type_data,
1543         __in            efsys_mem_t *esmp,
1544         __in            size_t ndescs,
1545         __in            uint32_t id,
1546         __in            unsigned int flags,
1547         __in            efx_evq_t *eep,
1548         __in            efx_rxq_t *erp)
1549 {
1550         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1551         efx_oword_t oword;
1552         uint32_t size;
1553         boolean_t jumbo = B_FALSE;
1554         efx_rc_t rc;
1555
1556         _NOTE(ARGUNUSED(esmp))
1557         _NOTE(ARGUNUSED(type_data))
1558
1559         EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
1560             (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
1561         EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
1562         EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
1563
1564         EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
1565         EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
1566
1567         if (!ISP2(ndescs) ||
1568             (ndescs < EFX_RXQ_MINNDESCS) || (ndescs > EFX_RXQ_MAXNDESCS)) {
1569                 rc = EINVAL;
1570                 goto fail1;
1571         }
1572         if (index >= encp->enc_rxq_limit) {
1573                 rc = EINVAL;
1574                 goto fail2;
1575         }
1576         for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);
1577             size++)
1578                 if ((1 << size) == (int)(ndescs / EFX_RXQ_MINNDESCS))
1579                         break;
1580         if (id + (1 << size) >= encp->enc_buftbl_limit) {
1581                 rc = EINVAL;
1582                 goto fail3;
1583         }
1584
1585         switch (type) {
1586         case EFX_RXQ_TYPE_DEFAULT:
1587                 break;
1588
1589         default:
1590                 rc = EINVAL;
1591                 goto fail4;
1592         }
1593
1594         if (flags & EFX_RXQ_FLAG_SCATTER) {
1595 #if EFSYS_OPT_RX_SCATTER
1596                 jumbo = B_TRUE;
1597 #else
1598                 rc = EINVAL;
1599                 goto fail5;
1600 #endif  /* EFSYS_OPT_RX_SCATTER */
1601         }
1602
1603         /* Set up the new descriptor queue */
1604         EFX_POPULATE_OWORD_7(oword,
1605             FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
1606             FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,
1607             FRF_AZ_RX_DESCQ_OWNER_ID, 0,
1608             FRF_AZ_RX_DESCQ_LABEL, label,
1609             FRF_AZ_RX_DESCQ_SIZE, size,
1610             FRF_AZ_RX_DESCQ_TYPE, 0,
1611             FRF_AZ_RX_DESCQ_JUMBO, jumbo);
1612
1613         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1614                             erp->er_index, &oword, B_TRUE);
1615
1616         return (0);
1617
1618 #if !EFSYS_OPT_RX_SCATTER
1619 fail5:
1620         EFSYS_PROBE(fail5);
1621 #endif
1622 fail4:
1623         EFSYS_PROBE(fail4);
1624 fail3:
1625         EFSYS_PROBE(fail3);
1626 fail2:
1627         EFSYS_PROBE(fail2);
1628 fail1:
1629         EFSYS_PROBE1(fail1, efx_rc_t, rc);
1630
1631         return (rc);
1632 }
1633
1634 static          void
1635 siena_rx_qdestroy(
1636         __in    efx_rxq_t *erp)
1637 {
1638         efx_nic_t *enp = erp->er_enp;
1639         efx_oword_t oword;
1640
1641         EFSYS_ASSERT(enp->en_rx_qcount != 0);
1642         --enp->en_rx_qcount;
1643
1644         /* Purge descriptor queue */
1645         EFX_ZERO_OWORD(oword);
1646
1647         EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1648                             erp->er_index, &oword, B_TRUE);
1649
1650         /* Free the RXQ object */
1651         EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
1652 }
1653
1654 static          void
1655 siena_rx_fini(
1656         __in    efx_nic_t *enp)
1657 {
1658         _NOTE(ARGUNUSED(enp))
1659 }
1660
1661 #endif /* EFSYS_OPT_SIENA */