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