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