2 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
37 static __checkReturn efx_rc_t
45 #if EFSYS_OPT_RX_SCATTER
46 static __checkReturn efx_rc_t
47 siena_rx_scatter_enable(
49 __in unsigned int buf_size);
50 #endif /* EFSYS_OPT_RX_SCATTER */
52 #if EFSYS_OPT_RX_SCALE
53 static __checkReturn efx_rc_t
54 siena_rx_scale_mode_set(
56 __in efx_rx_hash_alg_t alg,
57 __in efx_rx_hash_type_t type,
58 __in boolean_t insert);
60 static __checkReturn efx_rc_t
61 siena_rx_scale_key_set(
63 __in_ecount(n) uint8_t *key,
66 static __checkReturn efx_rc_t
67 siena_rx_scale_tbl_set(
69 __in_ecount(n) unsigned int *table,
72 static __checkReturn uint32_t
75 __in efx_rx_hash_alg_t func,
76 __in uint8_t *buffer);
78 #endif /* EFSYS_OPT_RX_SCALE */
80 static __checkReturn efx_rc_t
81 siena_rx_prefix_pktlen(
84 __out uint16_t *lengthp);
89 __in_ecount(n) efsys_dma_addr_t *addrp,
92 __in unsigned int completed,
93 __in unsigned int added);
98 __in unsigned int added,
99 __inout unsigned int *pushedp);
101 #if EFSYS_OPT_RX_PACKED_STREAM
103 siena_rx_qps_update_credits(
104 __in efx_rxq_t *erp);
106 static __checkReturn uint8_t *
107 siena_rx_qps_packet_info(
109 __in uint8_t *buffer,
110 __in uint32_t buffer_length,
111 __in uint32_t current_offset,
112 __out uint16_t *lengthp,
113 __out uint32_t *next_offsetp,
114 __out uint32_t *timestamp);
117 static __checkReturn efx_rc_t
119 __in efx_rxq_t *erp);
123 __in efx_rxq_t *erp);
125 static __checkReturn efx_rc_t
128 __in unsigned int index,
129 __in unsigned int label,
130 __in efx_rxq_type_t type,
131 __in efsys_mem_t *esmp,
135 __in efx_rxq_t *erp);
139 __in efx_rxq_t *erp);
141 #endif /* EFSYS_OPT_SIENA */
145 static const efx_rx_ops_t __efx_rx_siena_ops = {
146 siena_rx_init, /* erxo_init */
147 siena_rx_fini, /* erxo_fini */
148 #if EFSYS_OPT_RX_SCATTER
149 siena_rx_scatter_enable, /* erxo_scatter_enable */
151 #if EFSYS_OPT_RX_SCALE
152 NULL, /* erxo_scale_context_alloc */
153 NULL, /* erxo_scale_context_free */
154 siena_rx_scale_mode_set, /* erxo_scale_mode_set */
155 siena_rx_scale_key_set, /* erxo_scale_key_set */
156 siena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
157 siena_rx_prefix_hash, /* erxo_prefix_hash */
159 siena_rx_prefix_pktlen, /* erxo_prefix_pktlen */
160 siena_rx_qpost, /* erxo_qpost */
161 siena_rx_qpush, /* erxo_qpush */
162 #if EFSYS_OPT_RX_PACKED_STREAM
163 siena_rx_qps_update_credits, /* erxo_qps_update_credits */
164 siena_rx_qps_packet_info, /* erxo_qps_packet_info */
166 siena_rx_qflush, /* erxo_qflush */
167 siena_rx_qenable, /* erxo_qenable */
168 siena_rx_qcreate, /* erxo_qcreate */
169 siena_rx_qdestroy, /* erxo_qdestroy */
171 #endif /* EFSYS_OPT_SIENA */
173 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
174 static const efx_rx_ops_t __efx_rx_ef10_ops = {
175 ef10_rx_init, /* erxo_init */
176 ef10_rx_fini, /* erxo_fini */
177 #if EFSYS_OPT_RX_SCATTER
178 ef10_rx_scatter_enable, /* erxo_scatter_enable */
180 #if EFSYS_OPT_RX_SCALE
181 ef10_rx_scale_context_alloc, /* erxo_scale_context_alloc */
182 ef10_rx_scale_context_free, /* erxo_scale_context_free */
183 ef10_rx_scale_mode_set, /* erxo_scale_mode_set */
184 ef10_rx_scale_key_set, /* erxo_scale_key_set */
185 ef10_rx_scale_tbl_set, /* erxo_scale_tbl_set */
186 ef10_rx_prefix_hash, /* erxo_prefix_hash */
188 ef10_rx_prefix_pktlen, /* erxo_prefix_pktlen */
189 ef10_rx_qpost, /* erxo_qpost */
190 ef10_rx_qpush, /* erxo_qpush */
191 #if EFSYS_OPT_RX_PACKED_STREAM
192 ef10_rx_qps_update_credits, /* erxo_qps_update_credits */
193 ef10_rx_qps_packet_info, /* erxo_qps_packet_info */
195 ef10_rx_qflush, /* erxo_qflush */
196 ef10_rx_qenable, /* erxo_qenable */
197 ef10_rx_qcreate, /* erxo_qcreate */
198 ef10_rx_qdestroy, /* erxo_qdestroy */
200 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
203 __checkReturn efx_rc_t
205 __inout efx_nic_t *enp)
207 const efx_rx_ops_t *erxop;
210 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
211 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
213 if (!(enp->en_mod_flags & EFX_MOD_EV)) {
218 if (enp->en_mod_flags & EFX_MOD_RX) {
223 switch (enp->en_family) {
225 case EFX_FAMILY_SIENA:
226 erxop = &__efx_rx_siena_ops;
228 #endif /* EFSYS_OPT_SIENA */
230 #if EFSYS_OPT_HUNTINGTON
231 case EFX_FAMILY_HUNTINGTON:
232 erxop = &__efx_rx_ef10_ops;
234 #endif /* EFSYS_OPT_HUNTINGTON */
236 #if EFSYS_OPT_MEDFORD
237 case EFX_FAMILY_MEDFORD:
238 erxop = &__efx_rx_ef10_ops;
240 #endif /* EFSYS_OPT_MEDFORD */
248 if ((rc = erxop->erxo_init(enp)) != 0)
251 enp->en_erxop = erxop;
252 enp->en_mod_flags |= EFX_MOD_RX;
262 EFSYS_PROBE1(fail1, efx_rc_t, rc);
264 enp->en_erxop = NULL;
265 enp->en_mod_flags &= ~EFX_MOD_RX;
273 const efx_rx_ops_t *erxop = enp->en_erxop;
275 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
276 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
277 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
278 EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
280 erxop->erxo_fini(enp);
282 enp->en_erxop = NULL;
283 enp->en_mod_flags &= ~EFX_MOD_RX;
286 #if EFSYS_OPT_RX_SCATTER
287 __checkReturn efx_rc_t
288 efx_rx_scatter_enable(
290 __in unsigned int buf_size)
292 const efx_rx_ops_t *erxop = enp->en_erxop;
295 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
296 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
298 if ((rc = erxop->erxo_scatter_enable(enp, buf_size)) != 0)
304 EFSYS_PROBE1(fail1, efx_rc_t, rc);
307 #endif /* EFSYS_OPT_RX_SCATTER */
309 #if EFSYS_OPT_RX_SCALE
310 __checkReturn efx_rc_t
311 efx_rx_hash_default_support_get(
313 __out efx_rx_hash_support_t *supportp)
317 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
318 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
320 if (supportp == NULL) {
326 * Report the hashing support the client gets by default if it
327 * does not allocate an RSS context itself.
329 *supportp = enp->en_hash_support;
334 EFSYS_PROBE1(fail1, efx_rc_t, rc);
339 __checkReturn efx_rc_t
340 efx_rx_scale_default_support_get(
342 __out efx_rx_scale_context_type_t *typep)
346 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
347 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
355 * Report the RSS support the client gets by default if it
356 * does not allocate an RSS context itself.
358 *typep = enp->en_rss_context_type;
363 EFSYS_PROBE1(fail1, efx_rc_t, rc);
367 #endif /* EFSYS_OPT_RX_SCALE */
369 #if EFSYS_OPT_RX_SCALE
370 __checkReturn efx_rc_t
371 efx_rx_scale_context_alloc(
373 __in efx_rx_scale_context_type_t type,
374 __in uint32_t num_queues,
375 __out uint32_t *rss_contextp)
377 const efx_rx_ops_t *erxop = enp->en_erxop;
380 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
381 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
383 if (erxop->erxo_scale_context_alloc == NULL) {
387 if ((rc = erxop->erxo_scale_context_alloc(enp, type,
388 num_queues, rss_contextp)) != 0) {
397 EFSYS_PROBE1(fail1, efx_rc_t, rc);
400 #endif /* EFSYS_OPT_RX_SCALE */
402 #if EFSYS_OPT_RX_SCALE
403 __checkReturn efx_rc_t
404 efx_rx_scale_context_free(
406 __in uint32_t rss_context)
408 const efx_rx_ops_t *erxop = enp->en_erxop;
411 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
412 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
414 if (erxop->erxo_scale_context_free == NULL) {
418 if ((rc = erxop->erxo_scale_context_free(enp, rss_context)) != 0)
426 EFSYS_PROBE1(fail1, efx_rc_t, rc);
429 #endif /* EFSYS_OPT_RX_SCALE */
431 #if EFSYS_OPT_RX_SCALE
432 __checkReturn efx_rc_t
433 efx_rx_scale_mode_set(
435 __in efx_rx_hash_alg_t alg,
436 __in efx_rx_hash_type_t type,
437 __in boolean_t insert)
439 const efx_rx_ops_t *erxop = enp->en_erxop;
442 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
443 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
445 if (erxop->erxo_scale_mode_set != NULL) {
446 if ((rc = erxop->erxo_scale_mode_set(enp, alg,
454 EFSYS_PROBE1(fail1, efx_rc_t, rc);
457 #endif /* EFSYS_OPT_RX_SCALE */
459 #if EFSYS_OPT_RX_SCALE
460 __checkReturn efx_rc_t
461 efx_rx_scale_key_set(
463 __in_ecount(n) uint8_t *key,
466 const efx_rx_ops_t *erxop = enp->en_erxop;
469 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
470 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
472 if ((rc = erxop->erxo_scale_key_set(enp, key, n)) != 0)
478 EFSYS_PROBE1(fail1, efx_rc_t, rc);
482 #endif /* EFSYS_OPT_RX_SCALE */
484 #if EFSYS_OPT_RX_SCALE
485 __checkReturn efx_rc_t
486 efx_rx_scale_tbl_set(
488 __in_ecount(n) unsigned int *table,
491 const efx_rx_ops_t *erxop = enp->en_erxop;
494 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
495 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
497 if ((rc = erxop->erxo_scale_tbl_set(enp, table, n)) != 0)
503 EFSYS_PROBE1(fail1, efx_rc_t, rc);
507 #endif /* EFSYS_OPT_RX_SCALE */
512 __in_ecount(n) efsys_dma_addr_t *addrp,
515 __in unsigned int completed,
516 __in unsigned int added)
518 efx_nic_t *enp = erp->er_enp;
519 const efx_rx_ops_t *erxop = enp->en_erxop;
521 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
523 erxop->erxo_qpost(erp, addrp, size, n, completed, added);
526 #if EFSYS_OPT_RX_PACKED_STREAM
529 efx_rx_qps_update_credits(
532 efx_nic_t *enp = erp->er_enp;
533 const efx_rx_ops_t *erxop = enp->en_erxop;
535 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
537 erxop->erxo_qps_update_credits(erp);
540 __checkReturn uint8_t *
541 efx_rx_qps_packet_info(
543 __in uint8_t *buffer,
544 __in uint32_t buffer_length,
545 __in uint32_t current_offset,
546 __out uint16_t *lengthp,
547 __out uint32_t *next_offsetp,
548 __out uint32_t *timestamp)
550 efx_nic_t *enp = erp->er_enp;
551 const efx_rx_ops_t *erxop = enp->en_erxop;
553 return (erxop->erxo_qps_packet_info(erp, buffer,
554 buffer_length, current_offset, lengthp,
555 next_offsetp, timestamp));
558 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
563 __in unsigned int added,
564 __inout unsigned int *pushedp)
566 efx_nic_t *enp = erp->er_enp;
567 const efx_rx_ops_t *erxop = enp->en_erxop;
569 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
571 erxop->erxo_qpush(erp, added, pushedp);
574 __checkReturn efx_rc_t
578 efx_nic_t *enp = erp->er_enp;
579 const efx_rx_ops_t *erxop = enp->en_erxop;
582 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
584 if ((rc = erxop->erxo_qflush(erp)) != 0)
590 EFSYS_PROBE1(fail1, efx_rc_t, rc);
599 efx_nic_t *enp = erp->er_enp;
600 const efx_rx_ops_t *erxop = enp->en_erxop;
602 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
604 erxop->erxo_qenable(erp);
607 __checkReturn efx_rc_t
610 __in unsigned int index,
611 __in unsigned int label,
612 __in efx_rxq_type_t type,
613 __in efsys_mem_t *esmp,
617 __deref_out efx_rxq_t **erpp)
619 const efx_rx_ops_t *erxop = enp->en_erxop;
623 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
624 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
626 /* Allocate an RXQ object */
627 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
634 erp->er_magic = EFX_RXQ_MAGIC;
636 erp->er_index = index;
637 erp->er_mask = n - 1;
640 if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, n, id,
652 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
654 EFSYS_PROBE1(fail1, efx_rc_t, rc);
663 efx_nic_t *enp = erp->er_enp;
664 const efx_rx_ops_t *erxop = enp->en_erxop;
666 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
668 erxop->erxo_qdestroy(erp);
671 __checkReturn efx_rc_t
672 efx_pseudo_hdr_pkt_length_get(
674 __in uint8_t *buffer,
675 __out uint16_t *lengthp)
677 efx_nic_t *enp = erp->er_enp;
678 const efx_rx_ops_t *erxop = enp->en_erxop;
680 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
682 return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
685 #if EFSYS_OPT_RX_SCALE
686 __checkReturn uint32_t
687 efx_pseudo_hdr_hash_get(
689 __in efx_rx_hash_alg_t func,
690 __in uint8_t *buffer)
692 efx_nic_t *enp = erp->er_enp;
693 const efx_rx_ops_t *erxop = enp->en_erxop;
695 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
697 EFSYS_ASSERT3U(enp->en_hash_support, ==, EFX_RX_HASH_AVAILABLE);
698 return (erxop->erxo_prefix_hash(enp, func, buffer));
700 #endif /* EFSYS_OPT_RX_SCALE */
704 static __checkReturn efx_rc_t
711 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
713 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
714 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0);
715 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0);
716 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0);
717 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, 0);
718 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, 0x3000 / 32);
719 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
721 /* Zero the RSS table */
722 for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS;
724 EFX_ZERO_OWORD(oword);
725 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
726 index, &oword, B_TRUE);
729 #if EFSYS_OPT_RX_SCALE
730 /* The RSS key and indirection table are writable. */
731 enp->en_rss_context_type = EFX_RX_SCALE_EXCLUSIVE;
733 /* Hardware can insert RX hash with/without RSS */
734 enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
735 #endif /* EFSYS_OPT_RX_SCALE */
740 #if EFSYS_OPT_RX_SCATTER
741 static __checkReturn efx_rc_t
742 siena_rx_scatter_enable(
744 __in unsigned int buf_size)
750 nbuf32 = buf_size / 32;
752 (nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
753 ((buf_size % 32) != 0)) {
758 if (enp->en_rx_qcount > 0) {
763 /* Set scatter buffer size */
764 EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
765 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_USR_BUF_SIZE, nbuf32);
766 EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
768 /* Enable scatter for packets not matching a filter */
769 EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
770 EFX_SET_OWORD_FIELD(oword, FRF_BZ_SCATTER_ENBL_NO_MATCH_Q, 1);
771 EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
778 EFSYS_PROBE1(fail1, efx_rc_t, rc);
782 #endif /* EFSYS_OPT_RX_SCATTER */
785 #define EFX_RX_LFSR_HASH(_enp, _insert) \
789 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
790 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 0); \
791 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, 0); \
792 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, 0); \
793 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, \
794 (_insert) ? 1 : 0); \
795 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword); \
797 if ((_enp)->en_family == EFX_FAMILY_SIENA) { \
798 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, \
800 EFX_SET_OWORD_FIELD(oword, \
801 FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 0); \
802 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, \
806 _NOTE(CONSTANTCONDITION) \
809 #define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp) \
813 EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
814 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_ALG, 1); \
815 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_IP_HASH, \
817 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_TCP_SUP, \
819 EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_HASH_INSRT_HDR, \
820 (_insert) ? 1 : 0); \
821 EFX_BAR_WRITEO((_enp), FR_AZ_RX_CFG_REG, &oword); \
823 _NOTE(CONSTANTCONDITION) \
826 #define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc) \
830 EFX_BAR_READO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
831 EFX_SET_OWORD_FIELD(oword, \
832 FRF_CZ_RX_RSS_IPV6_THASH_ENABLE, 1); \
833 EFX_SET_OWORD_FIELD(oword, \
834 FRF_CZ_RX_RSS_IPV6_IP_THASH_ENABLE, (_ip) ? 1 : 0); \
835 EFX_SET_OWORD_FIELD(oword, \
836 FRF_CZ_RX_RSS_IPV6_TCP_SUPPRESS, (_tcp) ? 0 : 1); \
837 EFX_BAR_WRITEO((_enp), FR_CZ_RX_RSS_IPV6_REG3, &oword); \
841 _NOTE(CONSTANTCONDITION) \
845 #if EFSYS_OPT_RX_SCALE
847 static __checkReturn efx_rc_t
848 siena_rx_scale_mode_set(
850 __in efx_rx_hash_alg_t alg,
851 __in efx_rx_hash_type_t type,
852 __in boolean_t insert)
857 case EFX_RX_HASHALG_LFSR:
858 EFX_RX_LFSR_HASH(enp, insert);
861 case EFX_RX_HASHALG_TOEPLITZ:
862 EFX_RX_TOEPLITZ_IPV4_HASH(enp, insert,
863 type & EFX_RX_HASH_IPV4,
864 type & EFX_RX_HASH_TCPIPV4);
866 EFX_RX_TOEPLITZ_IPV6_HASH(enp,
867 type & EFX_RX_HASH_IPV6,
868 type & EFX_RX_HASH_TCPIPV6,
885 EFSYS_PROBE1(fail1, efx_rc_t, rc);
887 EFX_RX_LFSR_HASH(enp, B_FALSE);
893 #if EFSYS_OPT_RX_SCALE
894 static __checkReturn efx_rc_t
895 siena_rx_scale_key_set(
897 __in_ecount(n) uint8_t *key,
907 /* Write Toeplitz IPv4 hash key */
908 EFX_ZERO_OWORD(oword);
909 for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
910 offset > 0 && byte < n;
912 oword.eo_u8[offset - 1] = key[byte++];
914 EFX_BAR_WRITEO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
918 /* Verify Toeplitz IPv4 hash key */
919 EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
920 for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
921 offset > 0 && byte < n;
923 if (oword.eo_u8[offset - 1] != key[byte++]) {
929 if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
934 /* Write Toeplitz IPv6 hash key 3 */
935 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
936 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
937 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
938 offset > 0 && byte < n;
940 oword.eo_u8[offset - 1] = key[byte++];
942 EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
944 /* Write Toeplitz IPv6 hash key 2 */
945 EFX_ZERO_OWORD(oword);
946 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
947 FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
948 offset > 0 && byte < n;
950 oword.eo_u8[offset - 1] = key[byte++];
952 EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
954 /* Write Toeplitz IPv6 hash key 1 */
955 EFX_ZERO_OWORD(oword);
956 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
957 FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
958 offset > 0 && byte < n;
960 oword.eo_u8[offset - 1] = key[byte++];
962 EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
966 /* Verify Toeplitz IPv6 hash key 3 */
967 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
968 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
969 FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
970 offset > 0 && byte < n;
972 if (oword.eo_u8[offset - 1] != key[byte++]) {
978 /* Verify Toeplitz IPv6 hash key 2 */
979 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
980 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
981 FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
982 offset > 0 && byte < n;
984 if (oword.eo_u8[offset - 1] != key[byte++]) {
990 /* Verify Toeplitz IPv6 hash key 1 */
991 EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
992 for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
993 FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
994 offset > 0 && byte < n;
996 if (oword.eo_u8[offset - 1] != key[byte++]) {
1012 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1018 #if EFSYS_OPT_RX_SCALE
1019 static __checkReturn efx_rc_t
1020 siena_rx_scale_tbl_set(
1021 __in efx_nic_t *enp,
1022 __in_ecount(n) unsigned int *table,
1029 EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
1030 EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
1032 if (n > FR_BZ_RX_INDIRECTION_TBL_ROWS) {
1037 for (index = 0; index < FR_BZ_RX_INDIRECTION_TBL_ROWS; index++) {
1040 /* Calculate the entry to place in the table */
1041 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1043 EFSYS_PROBE2(table, int, index, uint32_t, byte);
1045 EFX_POPULATE_OWORD_1(oword, FRF_BZ_IT_QUEUE, byte);
1047 /* Write the table */
1048 EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
1049 index, &oword, B_TRUE);
1052 for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
1055 /* Determine if we're starting a new batch */
1056 byte = (n > 0) ? (uint32_t)table[index % n] : 0;
1058 /* Read the table */
1059 EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
1060 index, &oword, B_TRUE);
1062 /* Verify the entry */
1063 if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
1074 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1081 * Falcon/Siena pseudo-header
1082 * --------------------------
1084 * Receive packets are prefixed by an optional 16 byte pseudo-header.
1085 * The pseudo-header is a byte array of one of the forms:
1087 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1088 * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.TT.TT.TT.TT
1089 * xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.xx.LL.LL
1092 * TT.TT.TT.TT Toeplitz hash (32-bit big-endian)
1093 * LL.LL LFSR hash (16-bit big-endian)
1096 #if EFSYS_OPT_RX_SCALE
1097 static __checkReturn uint32_t
1098 siena_rx_prefix_hash(
1099 __in efx_nic_t *enp,
1100 __in efx_rx_hash_alg_t func,
1101 __in uint8_t *buffer)
1103 _NOTE(ARGUNUSED(enp))
1106 case EFX_RX_HASHALG_TOEPLITZ:
1107 return ((buffer[12] << 24) |
1108 (buffer[13] << 16) |
1112 case EFX_RX_HASHALG_LFSR:
1113 return ((buffer[14] << 8) | buffer[15]);
1120 #endif /* EFSYS_OPT_RX_SCALE */
1122 static __checkReturn efx_rc_t
1123 siena_rx_prefix_pktlen(
1124 __in efx_nic_t *enp,
1125 __in uint8_t *buffer,
1126 __out uint16_t *lengthp)
1128 _NOTE(ARGUNUSED(enp, buffer, lengthp))
1130 /* Not supported by Falcon/Siena hardware */
1138 __in efx_rxq_t *erp,
1139 __in_ecount(n) efsys_dma_addr_t *addrp,
1141 __in unsigned int n,
1142 __in unsigned int completed,
1143 __in unsigned int added)
1147 unsigned int offset;
1150 /* The client driver must not overfill the queue */
1151 EFSYS_ASSERT3U(added - completed + n, <=,
1152 EFX_RXQ_LIMIT(erp->er_mask + 1));
1154 id = added & (erp->er_mask);
1155 for (i = 0; i < n; i++) {
1156 EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
1157 unsigned int, id, efsys_dma_addr_t, addrp[i],
1160 EFX_POPULATE_QWORD_3(qword,
1161 FSF_AZ_RX_KER_BUF_SIZE, (uint32_t)(size),
1162 FSF_AZ_RX_KER_BUF_ADDR_DW0,
1163 (uint32_t)(addrp[i] & 0xffffffff),
1164 FSF_AZ_RX_KER_BUF_ADDR_DW1,
1165 (uint32_t)(addrp[i] >> 32));
1167 offset = id * sizeof (efx_qword_t);
1168 EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
1170 id = (id + 1) & (erp->er_mask);
1176 __in efx_rxq_t *erp,
1177 __in unsigned int added,
1178 __inout unsigned int *pushedp)
1180 efx_nic_t *enp = erp->er_enp;
1181 unsigned int pushed = *pushedp;
1186 /* All descriptors are pushed */
1189 /* Push the populated descriptors out */
1190 wptr = added & erp->er_mask;
1192 EFX_POPULATE_OWORD_1(oword, FRF_AZ_RX_DESC_WPTR, wptr);
1194 /* Only write the third DWORD */
1195 EFX_POPULATE_DWORD_1(dword,
1196 EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
1198 /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
1199 EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
1200 wptr, pushed & erp->er_mask);
1201 EFSYS_PIO_WRITE_BARRIER();
1202 EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
1203 erp->er_index, &dword, B_FALSE);
1206 #if EFSYS_OPT_RX_PACKED_STREAM
1208 siena_rx_qps_update_credits(
1209 __in efx_rxq_t *erp)
1211 /* Not supported by Siena hardware */
1216 siena_rx_qps_packet_info(
1217 __in efx_rxq_t *erp,
1218 __in uint8_t *buffer,
1219 __in uint32_t buffer_length,
1220 __in uint32_t current_offset,
1221 __out uint16_t *lengthp,
1222 __out uint32_t *next_offsetp,
1223 __out uint32_t *timestamp)
1225 /* Not supported by Siena hardware */
1230 #endif /* EFSYS_OPT_RX_PACKED_STREAM */
1232 static __checkReturn efx_rc_t
1234 __in efx_rxq_t *erp)
1236 efx_nic_t *enp = erp->er_enp;
1240 label = erp->er_index;
1242 /* Flush the queue */
1243 EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
1244 FRF_AZ_RX_FLUSH_DESCQ, label);
1245 EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
1252 __in efx_rxq_t *erp)
1254 efx_nic_t *enp = erp->er_enp;
1257 EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
1259 EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
1260 erp->er_index, &oword, B_TRUE);
1262 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
1263 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
1264 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
1266 EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1267 erp->er_index, &oword, B_TRUE);
1270 static __checkReturn efx_rc_t
1272 __in efx_nic_t *enp,
1273 __in unsigned int index,
1274 __in unsigned int label,
1275 __in efx_rxq_type_t type,
1276 __in efsys_mem_t *esmp,
1279 __in efx_evq_t *eep,
1280 __in efx_rxq_t *erp)
1282 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1288 _NOTE(ARGUNUSED(esmp))
1290 EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
1291 (1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
1292 EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
1293 EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
1295 EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
1296 EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
1298 if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
1302 if (index >= encp->enc_rxq_limit) {
1306 for (size = 0; (1 << size) <= (EFX_RXQ_MAXNDESCS / EFX_RXQ_MINNDESCS);
1308 if ((1 << size) == (int)(n / EFX_RXQ_MINNDESCS))
1310 if (id + (1 << size) >= encp->enc_buftbl_limit) {
1316 case EFX_RXQ_TYPE_DEFAULT:
1320 #if EFSYS_OPT_RX_SCATTER
1321 case EFX_RXQ_TYPE_SCATTER:
1322 if (enp->en_family < EFX_FAMILY_SIENA) {
1328 #endif /* EFSYS_OPT_RX_SCATTER */
1335 /* Set up the new descriptor queue */
1336 EFX_POPULATE_OWORD_7(oword,
1337 FRF_AZ_RX_DESCQ_BUF_BASE_ID, id,
1338 FRF_AZ_RX_DESCQ_EVQ_ID, eep->ee_index,
1339 FRF_AZ_RX_DESCQ_OWNER_ID, 0,
1340 FRF_AZ_RX_DESCQ_LABEL, label,
1341 FRF_AZ_RX_DESCQ_SIZE, size,
1342 FRF_AZ_RX_DESCQ_TYPE, 0,
1343 FRF_AZ_RX_DESCQ_JUMBO, jumbo);
1345 EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1346 erp->er_index, &oword, B_TRUE);
1357 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1364 __in efx_rxq_t *erp)
1366 efx_nic_t *enp = erp->er_enp;
1369 EFSYS_ASSERT(enp->en_rx_qcount != 0);
1370 --enp->en_rx_qcount;
1372 /* Purge descriptor queue */
1373 EFX_ZERO_OWORD(oword);
1375 EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
1376 erp->er_index, &oword, B_TRUE);
1378 /* Free the RXQ object */
1379 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
1384 __in efx_nic_t *enp)
1386 _NOTE(ARGUNUSED(enp))
1389 #endif /* EFSYS_OPT_SIENA */