1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
31 */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include "efx.h"
37 #include "efx_impl.h"
38
39 #if EFSYS_OPT_SIENA
40
41 static __checkReturn efx_rc_t
42 siena_rx_init(
43 __in efx_nic_t *enp);
44
45 static void
46 siena_rx_fini(
47 __in efx_nic_t *enp);
48
49 #if EFSYS_OPT_RX_SCATTER
50 static __checkReturn efx_rc_t
51 siena_rx_scatter_enable(
52 __in efx_nic_t *enp,
53 __in unsigned int buf_size);
54 #endif /* EFSYS_OPT_RX_SCATTER */
55
56 #if EFSYS_OPT_RX_SCALE
57 static __checkReturn efx_rc_t
58 siena_rx_scale_mode_set(
59 __in efx_nic_t *enp,
60 __in uint32_t rss_context,
61 __in efx_rx_hash_alg_t alg,
62 __in efx_rx_hash_type_t type,
63 __in boolean_t insert);
64
65 static __checkReturn efx_rc_t
66 siena_rx_scale_key_set(
67 __in efx_nic_t *enp,
68 __in uint32_t rss_context,
69 __in_ecount(n) uint8_t *key,
70 __in size_t n);
71
72 static __checkReturn efx_rc_t
73 siena_rx_scale_tbl_set(
74 __in efx_nic_t *enp,
75 __in uint32_t rss_context,
76 __in_ecount(n) unsigned int *table,
77 __in size_t n);
78
79 static __checkReturn uint32_t
80 siena_rx_prefix_hash(
81 __in efx_nic_t *enp,
82 __in efx_rx_hash_alg_t func,
83 __in uint8_t *buffer);
84
85 #endif /* EFSYS_OPT_RX_SCALE */
86
87 static __checkReturn efx_rc_t
88 siena_rx_prefix_pktlen(
89 __in efx_nic_t *enp,
90 __in uint8_t *buffer,
91 __out uint16_t *lengthp);
92
93 static void
94 siena_rx_qpost(
95 __in efx_rxq_t *erp,
96 __in_ecount(ndescs) efsys_dma_addr_t *addrp,
97 __in size_t size,
98 __in unsigned int ndescs,
99 __in unsigned int completed,
100 __in unsigned int added);
101
102 static void
103 siena_rx_qpush(
104 __in efx_rxq_t *erp,
105 __in unsigned int added,
106 __inout unsigned int *pushedp);
107
108 #if EFSYS_OPT_RX_PACKED_STREAM
109 static void
110 siena_rx_qpush_ps_credits(
111 __in efx_rxq_t *erp);
112
113 static __checkReturn uint8_t *
114 siena_rx_qps_packet_info(
115 __in efx_rxq_t *erp,
116 __in uint8_t *buffer,
117 __in uint32_t buffer_length,
118 __in uint32_t current_offset,
119 __out uint16_t *lengthp,
120 __out uint32_t *next_offsetp,
121 __out uint32_t *timestamp);
122 #endif
123
124 static __checkReturn efx_rc_t
125 siena_rx_qflush(
126 __in efx_rxq_t *erp);
127
128 static void
129 siena_rx_qenable(
130 __in efx_rxq_t *erp);
131
132 static __checkReturn efx_rc_t
133 siena_rx_qcreate(
134 __in efx_nic_t *enp,
135 __in unsigned int index,
136 __in unsigned int label,
137 __in efx_rxq_type_t type,
138 __in_opt const efx_rxq_type_data_t *type_data,
139 __in efsys_mem_t *esmp,
140 __in size_t ndescs,
141 __in uint32_t id,
142 __in unsigned int flags,
143 __in efx_evq_t *eep,
144 __in efx_rxq_t *erp);
145
146 static void
147 siena_rx_qdestroy(
148 __in efx_rxq_t *erp);
149
150 #endif /* EFSYS_OPT_SIENA */
151
152 #if EFSYS_OPT_SIENA
153 static const efx_rx_ops_t __efx_rx_siena_ops = {
154 siena_rx_init, /* erxo_init */
155 siena_rx_fini, /* erxo_fini */
156 #if EFSYS_OPT_RX_SCATTER
157 siena_rx_scatter_enable, /* erxo_scatter_enable */
158 #endif
159 #if EFSYS_OPT_RX_SCALE
160 NULL, /* erxo_scale_context_alloc */
161 NULL, /* erxo_scale_context_free */
162 siena_rx_scale_mode_set, /* erxo_scale_mode_set */
163 siena_rx_scale_key_set, /* erxo_scale_key_set */
164 siena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
165 siena_rx_prefix_hash, /* erxo_prefix_hash */
166 #endif
167 siena_rx_prefix_pktlen, /* erxo_prefix_pktlen */
168 siena_rx_qpost, /* erxo_qpost */
169 siena_rx_qpush, /* erxo_qpush */
170 #if EFSYS_OPT_RX_PACKED_STREAM
171 siena_rx_qpush_ps_credits, /* erxo_qpush_ps_credits */
172 siena_rx_qps_packet_info, /* erxo_qps_packet_info */
173 #endif
174 siena_rx_qflush, /* erxo_qflush */
175 siena_rx_qenable, /* erxo_qenable */
176 siena_rx_qcreate, /* erxo_qcreate */
177 siena_rx_qdestroy, /* erxo_qdestroy */
178 };
179 #endif /* EFSYS_OPT_SIENA */
180
181 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
182 static const efx_rx_ops_t __efx_rx_ef10_ops = {
183 ef10_rx_init, /* erxo_init */
184 ef10_rx_fini, /* erxo_fini */
185 #if EFSYS_OPT_RX_SCATTER
186 ef10_rx_scatter_enable, /* erxo_scatter_enable */
187 #endif
188 #if EFSYS_OPT_RX_SCALE
189 ef10_rx_scale_context_alloc, /* erxo_scale_context_alloc */
190 ef10_rx_scale_context_free, /* erxo_scale_context_free */
191 ef10_rx_scale_mode_set, /* erxo_scale_mode_set */
192 ef10_rx_scale_key_set, /* erxo_scale_key_set */
193 ef10_rx_scale_tbl_set, /* erxo_scale_tbl_set */
194 ef10_rx_prefix_hash, /* erxo_prefix_hash */
195 #endif
196 ef10_rx_prefix_pktlen, /* erxo_prefix_pktlen */
197 ef10_rx_qpost, /* erxo_qpost */
198 ef10_rx_qpush, /* erxo_qpush */
199 #if EFSYS_OPT_RX_PACKED_STREAM
200 ef10_rx_qpush_ps_credits, /* erxo_qpush_ps_credits */
201 ef10_rx_qps_packet_info, /* erxo_qps_packet_info */
202 #endif
203 ef10_rx_qflush, /* erxo_qflush */
204 ef10_rx_qenable, /* erxo_qenable */
205 ef10_rx_qcreate, /* erxo_qcreate */
206 ef10_rx_qdestroy, /* erxo_qdestroy */
207 };
208 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
209
210 __checkReturn efx_rc_t
211 efx_rx_init(
212 __inout efx_nic_t *enp)
213 {
214 const efx_rx_ops_t *erxop;
215 efx_rc_t rc;
216
217 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
218 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
219
220 if (!(enp->en_mod_flags & EFX_MOD_EV)) {
221 rc = EINVAL;
222 goto fail1;
223 }
224
225 if (enp->en_mod_flags & EFX_MOD_RX) {
226 rc = EINVAL;
227 goto fail2;
228 }
229
230 switch (enp->en_family) {
231 #if EFSYS_OPT_SIENA
232 case EFX_FAMILY_SIENA:
233 erxop = &__efx_rx_siena_ops;
234 break;
235 #endif /* EFSYS_OPT_SIENA */
236
237 #if EFSYS_OPT_HUNTINGTON
238 case EFX_FAMILY_HUNTINGTON:
239 erxop = &__efx_rx_ef10_ops;
240 break;
241 #endif /* EFSYS_OPT_HUNTINGTON */
242
243 #if EFSYS_OPT_MEDFORD
244 case EFX_FAMILY_MEDFORD:
245 erxop = &__efx_rx_ef10_ops;
246 break;
247 #endif /* EFSYS_OPT_MEDFORD */
248
249 #if EFSYS_OPT_MEDFORD2
250 case EFX_FAMILY_MEDFORD2:
251 erxop = &__efx_rx_ef10_ops;
252 break;
253 #endif /* EFSYS_OPT_MEDFORD2 */
254
255 default:
256 EFSYS_ASSERT(0);
257 rc = ENOTSUP;
258 goto fail3;
259 }
260
261 if ((rc = erxop->erxo_init(enp)) != 0)
262 goto fail4;
263
264 enp->en_erxop = erxop;
265 enp->en_mod_flags |= EFX_MOD_RX;
266 return (0);
267
268 fail4:
269 EFSYS_PROBE(fail4);
270 fail3:
271 EFSYS_PROBE(fail3);
272 fail2:
273 EFSYS_PROBE(fail2);
274 fail1:
275 EFSYS_PROBE1(fail1, efx_rc_t, rc);
276
277 enp->en_erxop = NULL;
278 enp->en_mod_flags &= ~EFX_MOD_RX;
279 return (rc);
280 }
281
282 void
283 efx_rx_fini(
284 __in efx_nic_t *enp)
285 {
286 const efx_rx_ops_t *erxop = enp->en_erxop;
287
288 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
289 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
290 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
291 EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
292
293 erxop->erxo_fini(enp);
294
295 enp->en_erxop = NULL;
296 enp->en_mod_flags &= ~EFX_MOD_RX;
297 }
298
299 #if EFSYS_OPT_RX_SCATTER
300 __checkReturn efx_rc_t
301 efx_rx_scatter_enable(
302 __in efx_nic_t *enp,
303 __in unsigned int buf_size)
304 {
305 const efx_rx_ops_t *erxop = enp->en_erxop;
306 efx_rc_t rc;
307
308 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
309 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
310
311 if ((rc = erxop->erxo_scatter_enable(enp, buf_size)) != 0)
312 goto fail1;
313
314 return (0);
315
316 fail1:
317 EFSYS_PROBE1(fail1, efx_rc_t, rc);
318 return (rc);
319 }
320 #endif /* EFSYS_OPT_RX_SCATTER */
321
322 #if EFSYS_OPT_RX_SCALE
323 __checkReturn efx_rc_t
324 efx_rx_scale_hash_flags_get(
325 __in efx_nic_t *enp,
326 __in efx_rx_hash_alg_t hash_alg,
327 __out_ecount_part(max_nflags, *nflagsp) unsigned int *flagsp,
328 __in unsigned int max_nflags,
329 __out unsigned int *nflagsp)
330 {
331 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
332 unsigned int nflags = 0;
333 efx_rc_t rc;
334
335 if (flagsp == NULL || nflagsp == NULL) {
336 rc = EINVAL;
337 goto fail1;
338 }
339
340 if ((encp->enc_rx_scale_hash_alg_mask & (1U << hash_alg)) == 0) {
341 nflags = 0;
342 goto done;
343 }
344
345 /* Helper to add flags word to flags array without buffer overflow */
346 #define INSERT_FLAGS(_flags) \
347 do { \
348 if (nflags >= max_nflags) { \
349 rc = E2BIG; \
350 goto fail2; \
351 } \
352 *(flagsp + nflags) = (_flags); \
353 nflags++; \
354 \
355 _NOTE(CONSTANTCONDITION) \
356 } while (B_FALSE)
357
358 if (encp->enc_rx_scale_l4_hash_supported != B_FALSE) {
359 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 4TUPLE));
360 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 4TUPLE));
361 }
362
363 if ((encp->enc_rx_scale_l4_hash_supported != B_FALSE) &&
364 (encp->enc_rx_scale_additional_modes_supported != B_FALSE)) {
365 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE_DST));
366 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE_SRC));
367
368 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE_DST));
369 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE_SRC));
370
371 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 4TUPLE));
372 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE_DST));
373 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE_SRC));
374
375 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 4TUPLE));
376 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE_DST));
377 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE_SRC));
378 }
379
380 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 2TUPLE));
381 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 2TUPLE));
382
383 INSERT_FLAGS(EFX_RX_HASH(IPV4, 2TUPLE));
384 INSERT_FLAGS(EFX_RX_HASH(IPV6, 2TUPLE));
385
386 if (encp->enc_rx_scale_additional_modes_supported != B_FALSE) {
387 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 1TUPLE_DST));
388 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, 1TUPLE_SRC));
389
390 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 1TUPLE_DST));
391 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, 1TUPLE_SRC));
392
393 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 2TUPLE));
394 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 1TUPLE_DST));
395 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, 1TUPLE_SRC));
396
397 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 2TUPLE));
398 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 1TUPLE_DST));
399 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, 1TUPLE_SRC));
400
401 INSERT_FLAGS(EFX_RX_HASH(IPV4, 1TUPLE_DST));
402 INSERT_FLAGS(EFX_RX_HASH(IPV4, 1TUPLE_SRC));
403
404 INSERT_FLAGS(EFX_RX_HASH(IPV6, 1TUPLE_DST));
405 INSERT_FLAGS(EFX_RX_HASH(IPV6, 1TUPLE_SRC));
406 }
407
408 INSERT_FLAGS(EFX_RX_HASH(IPV4_TCP, DISABLE));
409 INSERT_FLAGS(EFX_RX_HASH(IPV6_TCP, DISABLE));
410
411 INSERT_FLAGS(EFX_RX_HASH(IPV4_UDP, DISABLE));
412 INSERT_FLAGS(EFX_RX_HASH(IPV6_UDP, DISABLE));
413
414 INSERT_FLAGS(EFX_RX_HASH(IPV4, DISABLE));
415 INSERT_FLAGS(EFX_RX_HASH(IPV6, DISABLE));
416
417 #undef INSERT_FLAGS
418
419 done:
420 *nflagsp = nflags;
421 return (0);
422
423 fail2:
424 EFSYS_PROBE(fail2);
425 fail1:
426 EFSYS_PROBE1(fail1, efx_rc_t, rc);
427
428 return (rc);
429 }
430
431 __checkReturn efx_rc_t
432 efx_rx_hash_default_support_get(
433 __in efx_nic_t *enp,
434 __out efx_rx_hash_support_t *supportp)
435 {
436 efx_rc_t rc;
437
438 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
439 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
440
441 if (supportp == NULL) {
442 rc = EINVAL;
443 goto fail1;
444 }
445
446 /*
447 * Report the hashing support the client gets by default if it
448 * does not allocate an RSS context itself.
449 */
450 *supportp = enp->en_hash_support;
451
452 return (0);
453
454 fail1:
455 EFSYS_PROBE1(fail1, efx_rc_t, rc);
456
457 return (rc);
458 }
459
460 __checkReturn efx_rc_t
461 efx_rx_scale_default_support_get(
462 __in efx_nic_t *enp,
463 __out efx_rx_scale_context_type_t *typep)
464 {
465 efx_rc_t rc;
466
467 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
468 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
469
470 if (typep == NULL) {
471 rc = EINVAL;
472 goto fail1;
473 }
474
475 /*
476 * Report the RSS support the client gets by default if it
477 * does not allocate an RSS context itself.
478 */
479 *typep = enp->en_rss_context_type;
480
481 return (0);
482
483 fail1:
484 EFSYS_PROBE1(fail1, efx_rc_t, rc);
485
486 return (rc);
487 }
488 #endif /* EFSYS_OPT_RX_SCALE */
489
490 #if EFSYS_OPT_RX_SCALE
491 __checkReturn efx_rc_t
492 efx_rx_scale_context_alloc(
493 __in efx_nic_t *enp,
494 __in efx_rx_scale_context_type_t type,
495 __in uint32_t num_queues,
496 __out uint32_t *rss_contextp)
497 {
498 const efx_rx_ops_t *erxop = enp->en_erxop;
499 efx_rc_t rc;
500
501 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
502 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
503
504 if (erxop->erxo_scale_context_alloc == NULL) {
505 rc = ENOTSUP;
506 goto fail1;
507 }
508 if ((rc = erxop->erxo_scale_context_alloc(enp, type,
509 num_queues, rss_contextp)) != 0) {
510 goto fail2;
511 }
512
513 return (0);
514
515 fail2:
516 EFSYS_PROBE(fail2);
517 fail1:
518 EFSYS_PROBE1(fail1, efx_rc_t, rc);
519 return (rc);
520 }
521 #endif /* EFSYS_OPT_RX_SCALE */
522
523 #if EFSYS_OPT_RX_SCALE
524 __checkReturn efx_rc_t
525 efx_rx_scale_context_free(
526 __in efx_nic_t *enp,
527 __in uint32_t rss_context)
528 {
529 const efx_rx_ops_t *erxop = enp->en_erxop;
530 efx_rc_t rc;
531
532 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
533 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
534
535 if (erxop->erxo_scale_context_free == NULL) {
536 rc = ENOTSUP;
537 goto fail1;
538 }
539 if ((rc = erxop->erxo_scale_context_free(enp, rss_context)) != 0)
540 goto fail2;
541
542 return (0);
543
544 fail2:
545 EFSYS_PROBE(fail2);
546 fail1:
547 EFSYS_PROBE1(fail1, efx_rc_t, rc);
548 return (rc);
549 }
550 #endif /* EFSYS_OPT_RX_SCALE */
551
552 #if EFSYS_OPT_RX_SCALE
553 __checkReturn efx_rc_t
554 efx_rx_scale_mode_set(
555 __in efx_nic_t *enp,
556 __in uint32_t rss_context,
557 __in efx_rx_hash_alg_t alg,
558 __in efx_rx_hash_type_t type,
559 __in boolean_t insert)
560 {
561 efx_nic_cfg_t *encp = &enp->en_nic_cfg;
562 const efx_rx_ops_t *erxop = enp->en_erxop;
563 efx_rx_hash_type_t type_check;
564 unsigned int i;
565 efx_rc_t rc;
566
567 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
568 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
569
570 /*
571 * Legacy flags and modern bits cannot be
572 * used at the same time in the hash type.
573 */
574 if ((type & EFX_RX_HASH_LEGACY_MASK) &&
575 (type & ~EFX_RX_HASH_LEGACY_MASK)) {
576 rc = EINVAL;
577 goto fail1;
578 }
579
580 /*
581 * If RSS hash type is represented by additional bits
582 * in the value, the latter need to be verified since
583 * not all bit combinations are valid RSS modes. Also,
584 * depending on the firmware, some valid combinations
585 * may be unsupported. Discern additional bits in the
586 * type value and try to recognise valid combinations.
587 * If some bits remain unrecognised, report the error.
588 */
589 type_check = type & ~EFX_RX_HASH_LEGACY_MASK;
590 if (type_check != 0) {
591 unsigned int type_flags[EFX_RX_HASH_NFLAGS];
592 unsigned int type_nflags;
593
594 rc = efx_rx_scale_hash_flags_get(enp, alg, type_flags,
595 EFX_ARRAY_SIZE(type_flags), &type_nflags);
596 if (rc != 0)
597 goto fail2;
598
599 for (i = 0; i < type_nflags; ++i) {
600 if ((type_check & type_flags[i]) == type_flags[i])
601 type_check &= ~(type_flags[i]);
602 }
603
604 if (type_check != 0) {
605 rc = EINVAL;
606 goto fail3;
607 }
608 }
609
610 /*
611 * Translate EFX_RX_HASH() flags to their legacy counterparts
612 * provided that the FW claims no support for additional modes.
613 */
614 if (encp->enc_rx_scale_additional_modes_supported == B_FALSE) {
615 efx_rx_hash_type_t t_ipv4 = EFX_RX_HASH(IPV4, 2TUPLE) |
616 EFX_RX_HASH(IPV4_TCP, 2TUPLE);
617 efx_rx_hash_type_t t_ipv6 = EFX_RX_HASH(IPV6, 2TUPLE) |
618 EFX_RX_HASH(IPV6_TCP, 2TUPLE);
619 efx_rx_hash_type_t t_ipv4_tcp = EFX_RX_HASH(IPV4_TCP, 4TUPLE);
620 efx_rx_hash_type_t t_ipv6_tcp = EFX_RX_HASH(IPV6_TCP, 4TUPLE);
621
622 if ((type & t_ipv4) == t_ipv4)
623 type |= EFX_RX_HASH_IPV4;
624 if ((type & t_ipv6) == t_ipv6)
625 type |= EFX_RX_HASH_IPV6;
626
627 if (encp->enc_rx_scale_l4_hash_supported == B_TRUE) {
628 if ((type & t_ipv4_tcp) == t_ipv4_tcp)
629 type |= EFX_RX_HASH_TCPIPV4;
630 if ((type & t_ipv6_tcp) == t_ipv6_tcp)
631 type |= EFX_RX_HASH_TCPIPV6;
632 }
633
634 type &= EFX_RX_HASH_LEGACY_MASK;
635 }
636
637 if (erxop->erxo_scale_mode_set != NULL) {
638 if ((rc = erxop->erxo_scale_mode_set(enp, rss_context, alg,
639 type, insert)) != 0)
640 goto fail4;
641 }
642
643 return (0);
644
645 fail4:
646 EFSYS_PROBE(fail4);
647 fail3:
648 EFSYS_PROBE(fail3);
649 fail2:
650 EFSYS_PROBE(fail2);
651 fail1:
652 EFSYS_PROBE1(fail1, efx_rc_t, rc);
653 return (rc);
654 }
655 #endif /* EFSYS_OPT_RX_SCALE */
656
657 #if EFSYS_OPT_RX_SCALE
658 __checkReturn efx_rc_t
659 efx_rx_scale_key_set(
660 __in efx_nic_t *enp,
661 __in uint32_t rss_context,
662 __in_ecount(n) uint8_t *key,
663 __in size_t n)
664 {
665 const efx_rx_ops_t *erxop = enp->en_erxop;
666 efx_rc_t rc;
667
668 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
669 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
670
671 if ((rc = erxop->erxo_scale_key_set(enp, rss_context, key, n)) != 0)
672 goto fail1;
673
674 return (0);
675
676 fail1:
677 EFSYS_PROBE1(fail1, efx_rc_t, rc);
678
679 return (rc);
680 }
681 #endif /* EFSYS_OPT_RX_SCALE */
682
683 #if EFSYS_OPT_RX_SCALE
684 __checkReturn efx_rc_t
685 efx_rx_scale_tbl_set(
686 __in efx_nic_t *enp,
687 __in uint32_t rss_context,
688 __in_ecount(n) unsigned int *table,
689 __in size_t n)
690 {
691 const efx_rx_ops_t *erxop = enp->en_erxop;
692 efx_rc_t rc;
693
694 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
695 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
696
697 if ((rc = erxop->erxo_scale_tbl_set(enp, rss_context, table, n)) != 0)
698 goto fail1;
699
700 return (0);
701
702 fail1:
703 EFSYS_PROBE1(fail1, efx_rc_t, rc);
704
705 return (rc);
706 }
707 #endif /* EFSYS_OPT_RX_SCALE */
708
709 void
710 efx_rx_qpost(
711 __in efx_rxq_t *erp,
712 __in_ecount(ndescs) efsys_dma_addr_t *addrp,
713 __in size_t size,
714 __in unsigned int ndescs,
715 __in unsigned int completed,
716 __in unsigned int added)
717 {
718 efx_nic_t *enp = erp->er_enp;
719 const efx_rx_ops_t *erxop = enp->en_erxop;
720
721 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
722
723 erxop->erxo_qpost(erp, addrp, size, ndescs, completed, added);
724 }
725
726 #if EFSYS_OPT_RX_PACKED_STREAM
727
728 void
729 efx_rx_qpush_ps_credits(
730 __in efx_rxq_t *erp)
731 {
732 efx_nic_t *enp = erp->er_enp;
733 const efx_rx_ops_t *erxop = enp->en_erxop;
734
735 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
736
737 erxop->erxo_qpush_ps_credits(erp);
738 }
739
740 __checkReturn uint8_t *
741 efx_rx_qps_packet_info(
742 __in efx_rxq_t *erp,
743 __in uint8_t *buffer,
744 __in uint32_t buffer_length,
745 __in uint32_t current_offset,
746 __out uint16_t *lengthp,
747 __out uint32_t *next_offsetp,
748 __out uint32_t *timestamp)
749 {
750 efx_nic_t *enp = erp->er_enp;
751 const efx_rx_ops_t *erxop = enp->en_erxop;
752
753 return (erxop->erxo_qps_packet_info(erp, buffer,
754 buffer_length, current_offset, lengthp,
755 next_offsetp, timestamp));
756 }
757
758 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
759
760 void
761 efx_rx_qpush(
762 __in efx_rxq_t *erp,
763 __in unsigned int added,
764 __inout unsigned int *pushedp)
765 {
766 efx_nic_t *enp = erp->er_enp;
767 const efx_rx_ops_t *erxop = enp->en_erxop;
768
769 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
770
771 erxop->erxo_qpush(erp, added, pushedp);
772 }
773
774 __checkReturn efx_rc_t
775 efx_rx_qflush(
776 __in efx_rxq_t *erp)
777 {
778 efx_nic_t *enp = erp->er_enp;
779 const efx_rx_ops_t *erxop = enp->en_erxop;
780 efx_rc_t rc;
781
782 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
783
784 if ((rc = erxop->erxo_qflush(erp)) != 0)
785 goto fail1;
786
787 return (0);
788
789 fail1:
790 EFSYS_PROBE1(fail1, efx_rc_t, rc);
791
792 return (rc);
793 }
794
795 void
796 efx_rx_qenable(
797 __in efx_rxq_t *erp)
798 {
799 efx_nic_t *enp = erp->er_enp;
800 const efx_rx_ops_t *erxop = enp->en_erxop;
801
802 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
803
804 erxop->erxo_qenable(erp);
805 }
806
807 static __checkReturn efx_rc_t
808 efx_rx_qcreate_internal(
809 __in efx_nic_t *enp,
810 __in unsigned int index,
811 __in unsigned int label,
812 __in efx_rxq_type_t type,
813 __in_opt const efx_rxq_type_data_t *type_data,
814 __in efsys_mem_t *esmp,
815 __in size_t ndescs,
816 __in uint32_t id,
817 __in unsigned int flags,
818 __in efx_evq_t *eep,
819 __deref_out efx_rxq_t **erpp)
820 {
821 const efx_rx_ops_t *erxop = enp->en_erxop;
822 efx_rxq_t *erp;
823 efx_rc_t rc;
824
825 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
826 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
827
828 /* Allocate an RXQ object */
829 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
830
831 if (erp == NULL) {
832 rc = ENOMEM;
833 goto fail1;
834 }
835
836 erp->er_magic = EFX_RXQ_MAGIC;
837 erp->er_enp = enp;
838 erp->er_index = index;
839 erp->er_mask = ndescs - 1;
840 erp->er_esmp = esmp;
841
842 if ((rc = erxop->erxo_qcreate(enp, index, label, type, type_data, esmp,
843 ndescs, id, flags, eep, erp)) != 0)
844 goto fail2;
845
846 enp->en_rx_qcount++;
847 *erpp = erp;
848
849 return (0);
850
851 fail2:
852 EFSYS_PROBE(fail2);
853
854 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
855 fail1:
856 EFSYS_PROBE1(fail1, efx_rc_t, rc);
857
858 return (rc);
859 }
860
861 __checkReturn efx_rc_t
862 efx_rx_qcreate(
863 __in efx_nic_t *enp,
864 __in unsigned int index,
865 __in unsigned int label,
866 __in efx_rxq_type_t type,
867 __in efsys_mem_t *esmp,
868 __in size_t ndescs,
869 __in uint32_t id,
870 __in unsigned int flags,
871 __in efx_evq_t *eep,
872 __deref_out efx_rxq_t **erpp)
873 {
874 return efx_rx_qcreate_internal(enp, index, label, type, NULL,
875 esmp, ndescs, id, flags, eep, erpp);
876 }
877
878 #if EFSYS_OPT_RX_PACKED_STREAM
879
880 __checkReturn efx_rc_t
881 efx_rx_qcreate_packed_stream(
882 __in efx_nic_t *enp,
883 __in unsigned int index,
884 __in unsigned int label,
885 __in uint32_t ps_buf_size,
886 __in efsys_mem_t *esmp,
887 __in size_t ndescs,
888 __in efx_evq_t *eep,
889 __deref_out efx_rxq_t **erpp)
890 {
891 efx_rxq_type_data_t type_data;
892
893 memset(&type_data, 0, sizeof (type_data));
894
895 type_data.ertd_packed_stream.eps_buf_size = ps_buf_size;
896
897 return efx_rx_qcreate_internal(enp, index, label,
898 EFX_RXQ_TYPE_PACKED_STREAM, &type_data, esmp, ndescs,
899 0 /* id unused on EF10 */, EFX_RXQ_FLAG_NONE, eep, erpp);
900 }
901
902 #endif
903
904 #if EFSYS_OPT_RX_ES_SUPER_BUFFER
905
906 __checkReturn efx_rc_t
907 efx_rx_qcreate_es_super_buffer(
908 __in efx_nic_t *enp,
909 __in unsigned int index,
910 __in unsigned int label,
911 __in uint32_t n_bufs_per_desc,
912 __in uint32_t max_dma_len,
913 __in uint32_t buf_stride,
914 __in uint32_t hol_block_timeout,
915 __in efsys_mem_t *esmp,
916 __in size_t ndescs,
917 __in unsigned int flags,
918 __in efx_evq_t *eep,
919 __deref_out efx_rxq_t **erpp)
920 {
921 efx_rc_t rc;
922 efx_rxq_type_data_t type_data;
923
924 if (hol_block_timeout > EFX_RXQ_ES_SUPER_BUFFER_HOL_BLOCK_MAX) {
925 rc = EINVAL;
926 goto fail1;
927 }
928
929 memset(&type_data, 0, sizeof (type_data));
930
931 type_data.ertd_es_super_buffer.eessb_bufs_per_desc = n_bufs_per_desc;
932 type_data.ertd_es_super_buffer.eessb_max_dma_len = max_dma_len;
933 type_data.ertd_es_super_buffer.eessb_buf_stride = buf_stride;
934 type_data.ertd_es_super_buffer.eessb_hol_block_timeout =
935 hol_block_timeout;
936
937 rc = efx_rx_qcreate_internal(enp, index, label,
938 EFX_RXQ_TYPE_ES_SUPER_BUFFER, &type_data, esmp, ndescs,
939 0 /* id unused on EF10 */, flags, eep, erpp);
940 if (rc != 0)
941 goto fail2;
942
943 return (0);
944
945 fail2:
946 EFSYS_PROBE(fail2);
947 fail1:
948 EFSYS_PROBE1(fail1, efx_rc_t, rc);
949
950 return (rc);
951 }
952
953 #endif
954
955 void
956 efx_rx_qdestroy(
957 __in efx_rxq_t *erp)
958 {
959 efx_nic_t *enp = erp->er_enp;
960 const efx_rx_ops_t *erxop = enp->en_erxop;
961
962 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
963
964 erxop->erxo_qdestroy(erp);
965 }
966
967 __checkReturn efx_rc_t
968 efx_pseudo_hdr_pkt_length_get(
969 __in efx_rxq_t *erp,
970 __in uint8_t *buffer,
971 __out uint16_t *lengthp)
972 {
973 efx_nic_t *enp = erp->er_enp;
974 const efx_rx_ops_t *erxop = enp->en_erxop;
975
976 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
977
978 return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
979 }
980
981 #if EFSYS_OPT_RX_SCALE
982 __checkReturn uint32_t
983 efx_pseudo_hdr_hash_get(
984 __in efx_rxq_t *erp,
985 __in efx_rx_hash_alg_t func,
986 __in uint8_t *buffer)
987 {
988 efx_nic_t *enp = erp->er_enp;
989 const efx_rx_ops_t *erxop = enp->en_erxop;
990
991 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
992
993 EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
994 return (erxop->erxo_prefix_hash(enp, func, buffer));
995 }
996 #endif /* EFSYS_OPT_RX_SCALE */
997
998 #if EFSYS_OPT_SIENA
999
1000 static __checkReturn efx_rc_t
1001 siena_rx_init(
1002 __in efx_nic_t *enp)
1003 {
1004 efx_oword_t oword;
1005 unsigned int index;
1006
1007 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
1008
1009 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
1010 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);
1011 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);
1012 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);
1013 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);
1014 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);
1015 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
1016
1017 /* Zero the RSS table */
1018 for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;
1019 index++) {
1020 EFX_ZERO_OWORD(oword);
1021 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
1022 index, &oword, B_TRUE);
1023 }
1024
1025 #if EFSYS_OPT_RX_SCALE
1026 /* The RSS key and indirection table are writable. */
1027 enp->en_rss_context_type = EFX_RX_SCALE_EXCLUSIVE;
1028
1029 /* Hardware can insert RX hash with/without RSS */
1030 enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
1031 #endif /* EFSYS_OPT_RX_SCALE */
1032
1033 return (0);
1034 }
1035
1036 #if EFSYS_OPT_RX_SCATTER
1037 static __checkReturn efx_rc_t
1038 siena_rx_scatter_enable(
1039 __in efx_nic_t *enp,
1040 __in unsigned int buf_size)
1041 {
1042 unsigned int nbuf32;
1043 efx_oword_t oword;
1044 efx_rc_t rc;
1045
1046 nbuf32 = buf_size / 32;
1047 IF ((NBUF32 == 0) ||
1048 (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
1049 ((buf_size % 32) != 0)) {
1050 rc = EINVAL;
1051 goto fail1;
1052 }
1053
1054 if (enp->en_rx_qcount > 0) {
1055 rc = EBUSY;
1056 goto fail2;
1057 }
1058
1059 /* Set scatter buffer size */
1060 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
1061 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32);
1062 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
1063
1064 /* Enable scatter for packets not matching a filter */
1065 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
1066 EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1);
1067 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
1068
1069 return (0);
1070
1071 fail2:
1072 EFSYS_PROBE(fail2);
1073 fail1:
1074 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1075
1076 return (rc);
1077 }
1078 #endif /* EFSYS_OPT_RX_SCATTER */
1079
1080 #define EFX_RX_LFSR_HASH(_enp, _insert) \
1081 do { \
1082 efx_oword_t oword; \
1083 \
1084 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
1085 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0); \
1086 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0); \
1087 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0); \
1088 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, \
1089 (_insert) ? 1 : 0); \
1090 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword); \
1091 \
1092 if ((_enp)->en_family == EFX_FAMILY_SIENA) { \
1093 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, \
1094 &oword); \
1095 EFX_SET_OWORD_FIELD(oword, \
1096 FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0); \
1097 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, \
1098 &oword); \
1099 } \
1100 \
1101 _NOTE(CONSTANTCONDITION) \
1102 } while (B_FALSE)
1103
1104 #define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp) \
1105 do { \
1106 efx_oword_t oword; \
1107 \
1108 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
1109 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1); \
1110 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, \
1111 (_ip) ? 1 : 0); \
1112 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, \
1113 (_tcp) ? 0 : 1); \
1114 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, \
1115 (_insert) ? 1 : 0); \
1116 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword); \
1117 \
1118 _NOTE(CONSTANTCONDITION) \
1119 } while (B_FALSE)
1120
1121 #define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc) \
1122 do { \
1123 efx_oword_t oword; \
1124 \
1125 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
1126 EFX_SET_OWORD_FIELD(oword, \
1127 FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1); \
1128 EFX_SET_OWORD_FIELD(oword, \
1129 FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0); \
1130 EFX_SET_OWORD_FIELD(oword, \
1131 FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1); \
1132 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
1133 \
1134 (_rc) = 0; \
1135 \
1136 _NOTE(CONSTANTCONDITION) \
1137 } while (B_FALSE)
1138
1139 #if EFSYS_OPT_RX_SCALE
1140
1141 static __checkReturn efx_rc_t
1142 siena_rx_scale_mode_set(
1143 __in efx_nic_t *enp,
1144 __in uint32_t rss_context,
1145 __in efx_rx_hash_alg_t alg,
1146 __in efx_rx_hash_type_t type,
1147 __in boolean_t insert)
1148 {
1149 efx_rc_t rc;
1150
1151 if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1152 rc = EINVAL;
1153 goto fail1;
1154 }
1155
1156 switch (alg) {
1157 case EFX_RX_HASHALG_LFSR:
1158 EFX_RX_LFSR_HASH(enp, insert);
1159 break;
1160
1161 case EFX_RX_HASHALG_TOEPLITZ:
1162 EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
1163 (type & EFX_RX_HASH_IPV4) ? B_TRUE : B_FALSE,
1164 (type & EFX_RX_HASH_TCPIPV4) ? B_TRUE : B_FALSE);
1165
1166 EFX_RX_TOEPLITZ_IPV6_HASH(enp,
1167 (type & EFX_RX_HASH_IPV6) ? B_TRUE : B_FALSE,
1168 (type & EFX_RX_HASH_TCPIPV6) ? B_TRUE : B_FALSE,
1169 rc);
1170 if (rc != 0)
1171 goto fail2;
1172
1173 break;
1174
1175 default:
1176 rc = EINVAL;
1177 goto fail3;
1178 }
1179
1180 return (0);
1181
1182 fail3:
1183 EFSYS_PROBE(fail3);
1184 fail2:
1185 EFSYS_PROBE(fail2);
1186 fail1:
1187 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1188
1189 EFX_RX_LFSR_HASH(enp, B_FALSE);
1190
1191 return (rc);
1192 }
1193 #endif
1194
1195 #if EFSYS_OPT_RX_SCALE
1196 static __checkReturn efx_rc_t
1197 siena_rx_scale_key_set(
1198 __in efx_nic_t *enp,
1199 __in uint32_t rss_context,
1200 __in_ecount(n) uint8_t *key,
1201 __in size_t n)
1202 {
1203 efx_oword_t oword;
1204 unsigned int byte;
1205 unsigned int offset;
1206 efx_rc_t rc;
1207
1208 if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1209 rc = EINVAL;
1210 goto fail1;
1211 }
1212
1213 byte = 0;
1214
1215 /* Write Toeplitz IPv4 hash key */
1216 EFX_ZERO_OWORD(oword);
1217 for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
1218 offset > 0 && byte < n;
1219 --offset)
1220 oword.eo_u8[offset - 1] = key[byte++];
1221
1222 EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
1223
1224 byte = 0;
1225
1226 /* Verify Toeplitz IPv4 hash key */
1227 EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
1228 for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
1229 offset > 0 && byte < n;
1230 --offset) {
1231 if (oword.eo_u8[offset - 1] != key[byte++]) {
1232 rc = EFAULT;
1233 goto fail2;
1234 }
1235 }
1236
1237 if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
1238 goto done;
1239
1240 byte = 0;
1241
1242 /* Write Toeplitz IPv6 hash key 3 */
1243 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1244 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
1245 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
1246 offset > 0 && byte < n;
1247 --offset)
1248 oword.eo_u8[offset - 1] = key[byte++];
1249
1250 EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1251
1252 /* Write Toeplitz IPv6 hash key 2 */
1253 EFX_ZERO_OWORD(oword);
1254 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1255 FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1256 offset > 0 && byte < n;
1257 --offset)
1258 oword.eo_u8[offset - 1] = key[byte++];
1259
1260 EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1261
1262 /* Write Toeplitz IPv6 hash key 1 */
1263 EFX_ZERO_OWORD(oword);
1264 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1265 FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1266 offset > 0 && byte < n;
1267 --offset)
1268 oword.eo_u8[offset - 1] = key[byte++];
1269
1270 EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1271
1272 byte = 0;
1273
1274 /* Verify Toeplitz IPv6 hash key 3 */
1275 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
1276 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
1277 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
1278 offset > 0 && byte < n;
1279 --offset) {
1280 if (oword.eo_u8[offset - 1] != key[byte++]) {
1281 rc = EFAULT;
1282 goto fail3;
1283 }
1284 }
1285
1286 /* Verify Toeplitz IPv6 hash key 2 */
1287 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
1288 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
1289 FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
1290 offset > 0 && byte < n;
1291 --offset) {
1292 if (oword.eo_u8[offset - 1] != key[byte++]) {
1293 rc = EFAULT;
1294 goto fail4;
1295 }
1296 }
1297
1298 /* Verify Toeplitz IPv6 hash key 1 */
1299 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
1300 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
1301 FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
1302 offset > 0 && byte < n;
1303 --offset) {
1304 if (oword.eo_u8[offset - 1] != key[byte++]) {
1305 rc = EFAULT;
1306 goto fail5;
1307 }
1308 }
1309
1310 done:
1311 return (0);
1312
1313 fail5:
1314 EFSYS_PROBE(fail5);
1315 fail4:
1316 EFSYS_PROBE(fail4);
1317 fail3:
1318 EFSYS_PROBE(fail3);
1319 fail2:
1320 EFSYS_PROBE(fail2);
1321 fail1:
1322 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1323
1324 return (rc);
1325 }
1326 #endif
1327
1328 #if EFSYS_OPT_RX_SCALE
1329 static __checkReturn efx_rc_t
1330 siena_rx_scale_tbl_set(
1331 __in efx_nic_t *enp,
1332 __in uint32_t rss_context,
1333 __in_ecount(n) unsigned int *table,
1334 __in size_t n)
1335 {
1336 efx_oword_t oword;
1337 int index;
1338 efx_rc_t rc;
1339
1340 EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
1341 EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
1342
1343 if (rss_context != EFX_RSS_CONTEXT_DEFAULT) {
1344 rc = EINVAL;
1345 goto fail1;
1346 }
1347
1348 if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {
1349 rc = EINVAL;
1350 goto fail2;
1351 }
1352
1353 for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {
1354 uint32_t byte;
1355
1356 /* Calculate the entry to place in the table */
1357 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1358
1359 EFSYS_PROBE2(table, int, index, uint32_t, byte);
1360
1361 EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);
1362
1363 /* Write the table */
1364 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
1365 index, &oword, B_TRUE);
1366 }
1367
1368 for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
1369 uint32_t byte;
1370
1371 /* Determine if we're starting a new batch */
1372 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1373
1374 /* Read the table */
1375 EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
1376 index, &oword, B_TRUE);
1377
1378 /* Verify the entry */
1379 if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
1380 rc = EFAULT;
1381 goto fail3;
1382 }
1383 }
1384
1385 return (0);
1386
1387 fail3:
1388 EFSYS_PROBE(fail3);
1389 fail2:
1390 EFSYS_PROBE(fail2);
1391 fail1:
1392 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1393
1394 return (rc);
1395 }
1396 #endif
1397
1398 /*
1399 * Falcon/Siena pseudo-header
1400 * --------------------------
1401 *
1402 * Receive packets are prefixed by an optional 16 byte pseudo-header.
1403 * The pseudo-header is a byte array of one of the forms:
1404 *
1405 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1406 * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
1407 * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
1408 *
1409 * where:
1410 * TT.TT.TT.TT Toeplitz hash (32-bit big-endian)
1411 * LL.LL LFSR hash (16-bit big-endian)
1412 */
1413
1414 #if EFSYS_OPT_RX_SCALE
1415 static __checkReturn uint32_t
1416 siena_rx_prefix_hash(
1417 __in efx_nic_t *enp,
1418 __in efx_rx_hash_alg_t func,
1419 __in uint8_t *buffer)
1420 {
1421 _NOTE(ARGUNUSED(enp))
1422
1423 switch (func) {
1424 case EFX_RX_HASHALG_TOEPLITZ:
1425 return ((buffer[12] << 24) |
1426 (buffer[13] << 16) |
1427 (buffer[14] << 8) |
1428 buffer[15]);
1429
1430 case EFX_RX_HASHALG_LFSR:
1431 return ((buffer[14] << 8) | buffer[15]);
1432
1433 default:
1434 EFSYS_ASSERT(0);
1435 return (0);
1436 }
1437 }
1438 #endif /* EFSYS_OPT_RX_SCALE */
1439
1440 static __checkReturn efx_rc_t
1441 siena_rx_prefix_pktlen(
1442 __in efx_nic_t *enp,
1443 __in uint8_t *buffer,
1444 __out uint16_t *lengthp)
1445 {
1446 _NOTE(ARGUNUSED(enp, buffer, lengthp))
1447
1448 /* Not supported by Falcon/Siena hardware */
1449 EFSYS_ASSERT(0);
1450 return (ENOTSUP);
1451 }
1452
1453 static void
1454 siena_rx_qpost(
1455 __in efx_rxq_t *erp,
1456 __in_ecount(ndescs) efsys_dma_addr_t *addrp,
1457 __in size_t size,
1458 __in unsigned int ndescs,
1459 __in unsigned int completed,
1460 __in unsigned int added)
1461 {
1462 efx_qword_t qword;
1463 unsigned int i;
1464 unsigned int offset;
1465 unsigned int id;
1466
1467 /* The client driver must not overfill the queue */
1468 EFSYS_ASSERT3U(added - completed + ndescs, <=,
1469 EFX_RXQ_LIMIT(erp->er_mask + 1));
1470
1471 id = added & (erp->er_mask);
1472 for (i = 0; i < ndescs; i++) {
1473 EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
1474 unsigned int, id, efsys_dma_addr_t, addrp[i],
1475 size_t, size);
1476
1477 EFX_POPULATE_QWORD_3(qword,
1478 FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),
1479 FSF_AZ_RX_KER_BUF_ADDR_DW0,
1480 (uint32_t)(addrp[i] & 0xffffffff),
1481 FSF_AZ_RX_KER_BUF_ADDR_DW1,
1482 (uint32_t)(addrp[i] >> 32));
1483
1484 offset = id * sizeof (efx_qword_t);
1485 EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
1486
1487 id = (id + 1) & (erp->er_mask);
1488 }
1489 }
1490
1491 static void
1492 siena_rx_qpush(
1493 __in efx_rxq_t *erp,
1494 __in unsigned int added,
1495 __inout unsigned int *pushedp)
1496 {
1497 efx_nic_t *enp = erp->er_enp;
1498 unsigned int pushed = *pushedp;
1499 uint32_t wptr;
1500 efx_oword_t oword;
1501 efx_dword_t dword;
1502
1503 /* All descriptors are pushed */
1504 *pushedp = added;
1505
1506 /* Push the populated descriptors out */
1507 wptr = added & erp->er_mask;
1508
1509 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);
1510
1511 /* Only write the third DWORD */
1512 EFX_POPULATE_DWORD_1(dword,
1513 EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
1514
1515 /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
1516 EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
1517 wptr, pushed & erp->er_mask);
1518 EFSYS_PIO_WRITE_BARRIER();
1519 EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
1520 erp->er_index, &dword, B_FALSE);
1521 }
1522
1523 #if EFSYS_OPT_RX_PACKED_STREAM
1524 static void
1525 siena_rx_qpush_ps_credits(
1526 __in efx_rxq_t *erp)
1527 {
1528 /* Not supported by Siena hardware */
1529 EFSYS_ASSERT(0);
1530 }
1531
1532 static uint8_t *
1533 siena_rx_qps_packet_info(
1534 __in efx_rxq_t *erp,
1535 __in uint8_t *buffer,
1536 __in uint32_t buffer_length,
1537 __in uint32_t current_offset,
1538 __out uint16_t *lengthp,
1539 __out uint32_t *next_offsetp,
1540 __out uint32_t *timestamp)
1541 {
1542 /* Not supported by Siena hardware */
1543 EFSYS_ASSERT(0);
1544
1545 return (NULL);
1546 }
1547 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
1548
1549 static __checkReturn efx_rc_t
1550 siena_rx_qflush(
1551 __in efx_rxq_t *erp)
1552 {
1553 efx_nic_t *enp = erp->er_enp;
1554 efx_oword_t oword;
1555 uint32_t label;
1556
1557 label = erp->er_index;
1558
1559 /* Flush the queue */
1560 EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
1561 FRF_AZ_RX_FLUSH_DESCQ, label);
1562 EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
1563
1564 return (0);
1565 }
1566
1567 static void
1568 siena_rx_qenable(
1569 __in efx_rxq_t *erp)
1570 {
1571 efx_nic_t *enp = erp->er_enp;
1572 efx_oword_t oword;
1573
1574 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
1575
1576 EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
1577 erp->er_index, &oword, B_TRUE);
1578
1579 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
1580 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
1581 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
1582
1583 EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1584 erp->er_index, &oword, B_TRUE);
1585 }
1586
1587 static __checkReturn efx_rc_t
1588 siena_rx_qcreate(
1589 __in efx_nic_t *enp,
1590 __in unsigned int index,
1591 __in unsigned int label,
1592 __in efx_rxq_type_t type,
1593 __in_opt const efx_rxq_type_data_t *type_data,
1594 __in efsys_mem_t *esmp,
1595 __in size_t ndescs,
1596 __in uint32_t id,
1597 __in unsigned int flags,
1598 __in efx_evq_t *eep,
1599 __in efx_rxq_t *erp)
1600 {
1601 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1602 efx_oword_t oword;
1603 uint32_t size;
1604 boolean_t jumbo = B_FALSE;
1605 efx_rc_t rc;
1606
1607 _NOTE(ARGUNUSED(esmp))
1608 _NOTE(ARGUNUSED(type_data))
1609
1610 EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
1611 (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
1612 EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
1613 EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
1614
1615 EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
1616 EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
1617
1618 if (!ISP2(ndescs) ||
1619 (ndescs < EFX_RXQ_MINNDESCS) || (ndescs > EFX_RXQ_MAXNDESCS)) {
1620 rc = EINVAL;
1621 goto fail1;
1622 }
1623 if (index >= encp->enc_rxq_limit) {
1624 rc = EINVAL;
1625 goto fail2;
1626 }
1627 for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);
1628 size++)
1629 if ((1 << size) == (int)(ndescs / EFX_RXQ_MINNDESCS))
1630 break;
1631 if (id + (1 << size) >= encp->enc_buftbl_limit) {
1632 rc = EINVAL;
1633 goto fail3;
1634 }
1635
1636 switch (type) {
1637 case EFX_RXQ_TYPE_DEFAULT:
1638 break;
1639
1640 default:
1641 rc = EINVAL;
1642 goto fail4;
1643 }
1644
1645 if (flags & EFX_RXQ_FLAG_SCATTER) {
1646 #if EFSYS_OPT_RX_SCATTER
1647 jumbo = B_TRUE;
1648 #else
1649 rc = EINVAL;
1650 goto fail5;
1651 #endif /* EFSYS_OPT_RX_SCATTER */
1652 }
1653
1654 /* Set up the new descriptor queue */
1655 EFX_POPULATE_OWORD_7(oword,
1656 FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
1657 FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,
1658 FRF_AZ_RX_DESCQ_OWNER_ID, 0,
1659 FRF_AZ_RX_DESCQ_LABEL, label,
1660 FRF_AZ_RX_DESCQ_SIZE, size,
1661 FRF_AZ_RX_DESCQ_TYPE, 0,
1662 FRF_AZ_RX_DESCQ_JUMBO, jumbo);
1663
1664 EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1665 erp->er_index, &oword, B_TRUE);
1666
1667 return (0);
1668
1669 #if !EFSYS_OPT_RX_SCATTER
1670 fail5:
1671 EFSYS_PROBE(fail5);
1672 #endif
1673 fail4:
1674 EFSYS_PROBE(fail4);
1675 fail3:
1676 EFSYS_PROBE(fail3);
1677 fail2:
1678 EFSYS_PROBE(fail2);
1679 fail1:
1680 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1681
1682 return (rc);
1683 }
1684
1685 static void
1686 siena_rx_qdestroy(
1687 __in efx_rxq_t *erp)
1688 {
1689 efx_nic_t *enp = erp->er_enp;
1690 efx_oword_t oword;
1691
1692 EFSYS_ASSERT(enp->en_rx_qcount != 0);
1693 --enp->en_rx_qcount;
1694
1695 /* Purge descriptor queue */
1696 EFX_ZERO_OWORD(oword);
1697
1698 EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1699 erp->er_index, &oword, B_TRUE);
1700
1701 /* Free the RXQ object */
1702 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
1703 }
1704
1705 static void
1706 siena_rx_fini(
1707 __in efx_nic_t *enp)
1708 {
1709 _NOTE(ARGUNUSED(enp))
1710 }
1711
1712 #endif /* EFSYS_OPT_SIENA */
Cache object: 1bcd912d64bfef4ba874fe29b8181da4
|