2 * Copyright (c) 2012-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.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
38 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
41 static __checkReturn efx_rc_t
45 __in uint32_t target_evq,
47 __in uint32_t instance,
48 __in efsys_mem_t *esmp,
49 __in boolean_t disable_scatter)
53 MC_CMD_INIT_RXQ_IN_LEN(EFX_RXQ_NBUFS(EFX_RXQ_MAXNDESCS))];
54 int npages = EFX_RXQ_NBUFS(size);
56 efx_qword_t *dma_addr;
60 /* If this changes, then the payload size might need to change. */
61 EFSYS_ASSERT3U(MC_CMD_INIT_RXQ_OUT_LEN, ==, 0);
62 EFSYS_ASSERT3U(size, <=, EFX_RXQ_MAXNDESCS);
64 (void) memset(payload, 0, sizeof (payload));
65 req.emr_cmd = MC_CMD_INIT_RXQ;
66 req.emr_in_buf = payload;
67 req.emr_in_length = MC_CMD_INIT_RXQ_IN_LEN(npages);
68 req.emr_out_buf = payload;
69 req.emr_out_length = MC_CMD_INIT_RXQ_OUT_LEN;
71 MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_SIZE, size);
72 MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_TARGET_EVQ, target_evq);
73 MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_LABEL, label);
74 MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_INSTANCE, instance);
75 MCDI_IN_POPULATE_DWORD_6(req, INIT_RXQ_IN_FLAGS,
76 INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
77 INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
78 INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
79 INIT_RXQ_IN_CRC_MODE, 0,
80 INIT_RXQ_IN_FLAG_PREFIX, 1,
81 INIT_RXQ_IN_FLAG_DISABLE_SCATTER, disable_scatter);
82 MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_OWNER_ID, 0);
83 MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
85 dma_addr = MCDI_IN2(req, efx_qword_t, INIT_RXQ_IN_DMA_ADDR);
86 addr = EFSYS_MEM_ADDR(esmp);
88 for (i = 0; i < npages; i++) {
89 EFX_POPULATE_QWORD_2(*dma_addr,
90 EFX_DWORD_1, (uint32_t)(addr >> 32),
91 EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
97 efx_mcdi_execute(enp, &req);
99 if (req.emr_rc != 0) {
107 EFSYS_PROBE1(fail1, efx_rc_t, rc);
112 static __checkReturn efx_rc_t
115 __in uint32_t instance)
118 uint8_t payload[MAX(MC_CMD_FINI_RXQ_IN_LEN,
119 MC_CMD_FINI_RXQ_OUT_LEN)];
122 (void) memset(payload, 0, sizeof (payload));
123 req.emr_cmd = MC_CMD_FINI_RXQ;
124 req.emr_in_buf = payload;
125 req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
126 req.emr_out_buf = payload;
127 req.emr_out_length = MC_CMD_FINI_RXQ_OUT_LEN;
129 MCDI_IN_SET_DWORD(req, FINI_RXQ_IN_INSTANCE, instance);
131 efx_mcdi_execute_quiet(enp, &req);
133 if (req.emr_rc != 0) {
142 * EALREADY is not an error, but indicates that the MC has rebooted and
143 * that the RXQ has already been destroyed.
146 EFSYS_PROBE1(fail1, efx_rc_t, rc);
151 #if EFSYS_OPT_RX_SCALE
152 static __checkReturn efx_rc_t
153 efx_mcdi_rss_context_alloc(
155 __in efx_rx_scale_support_t scale_support,
156 __in uint32_t num_queues,
157 __out uint32_t *rss_contextp)
160 uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
161 MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];
162 uint32_t rss_context;
163 uint32_t context_type;
166 if (num_queues > EFX_MAXRSS) {
171 switch (scale_support) {
172 case EFX_RX_SCALE_EXCLUSIVE:
173 context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE;
175 case EFX_RX_SCALE_SHARED:
176 context_type = MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED;
183 (void) memset(payload, 0, sizeof (payload));
184 req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
185 req.emr_in_buf = payload;
186 req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
187 req.emr_out_buf = payload;
188 req.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN;
190 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
191 EVB_PORT_ID_ASSIGNED);
192 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_TYPE, context_type);
193 /* NUM_QUEUES is only used to validate indirection table offsets */
194 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, num_queues);
196 efx_mcdi_execute(enp, &req);
198 if (req.emr_rc != 0) {
203 if (req.emr_out_length_used < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) {
208 rss_context = MCDI_OUT_DWORD(req, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
209 if (rss_context == EF10_RSS_CONTEXT_INVALID) {
214 *rss_contextp = rss_context;
227 EFSYS_PROBE1(fail1, efx_rc_t, rc);
231 #endif /* EFSYS_OPT_RX_SCALE */
233 #if EFSYS_OPT_RX_SCALE
235 efx_mcdi_rss_context_free(
237 __in uint32_t rss_context)
240 uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
241 MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];
244 if (rss_context == EF10_RSS_CONTEXT_INVALID) {
249 (void) memset(payload, 0, sizeof (payload));
250 req.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;
251 req.emr_in_buf = payload;
252 req.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;
253 req.emr_out_buf = payload;
254 req.emr_out_length = MC_CMD_RSS_CONTEXT_FREE_OUT_LEN;
256 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID, rss_context);
258 efx_mcdi_execute_quiet(enp, &req);
260 if (req.emr_rc != 0) {
270 EFSYS_PROBE1(fail1, efx_rc_t, rc);
274 #endif /* EFSYS_OPT_RX_SCALE */
276 #if EFSYS_OPT_RX_SCALE
278 efx_mcdi_rss_context_set_flags(
280 __in uint32_t rss_context,
281 __in efx_rx_hash_type_t type)
284 uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
285 MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)];
288 if (rss_context == EF10_RSS_CONTEXT_INVALID) {
293 (void) memset(payload, 0, sizeof (payload));
294 req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;
295 req.emr_in_buf = payload;
296 req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;
297 req.emr_out_buf = payload;
298 req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN;
300 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
303 MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
304 RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
305 (type & EFX_RX_HASH_IPV4) ? 1 : 0,
306 RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
307 (type & EFX_RX_HASH_TCPIPV4) ? 1 : 0,
308 RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
309 (type & EFX_RX_HASH_IPV6) ? 1 : 0,
310 RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
311 (type & EFX_RX_HASH_TCPIPV6) ? 1 : 0);
313 efx_mcdi_execute(enp, &req);
315 if (req.emr_rc != 0) {
325 EFSYS_PROBE1(fail1, efx_rc_t, rc);
329 #endif /* EFSYS_OPT_RX_SCALE */
331 #if EFSYS_OPT_RX_SCALE
333 efx_mcdi_rss_context_set_key(
335 __in uint32_t rss_context,
336 __in_ecount(n) uint8_t *key,
340 uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
341 MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];
344 if (rss_context == EF10_RSS_CONTEXT_INVALID) {
349 (void) memset(payload, 0, sizeof (payload));
350 req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;
351 req.emr_in_buf = payload;
352 req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;
353 req.emr_out_buf = payload;
354 req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN;
356 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,
359 EFSYS_ASSERT3U(n, ==, MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
360 if (n != MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN) {
365 memcpy(MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY),
368 efx_mcdi_execute(enp, &req);
370 if (req.emr_rc != 0) {
382 EFSYS_PROBE1(fail1, efx_rc_t, rc);
386 #endif /* EFSYS_OPT_RX_SCALE */
388 #if EFSYS_OPT_RX_SCALE
390 efx_mcdi_rss_context_set_table(
392 __in uint32_t rss_context,
393 __in_ecount(n) unsigned int *table,
397 uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
398 MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];
402 if (rss_context == EF10_RSS_CONTEXT_INVALID) {
407 (void) memset(payload, 0, sizeof (payload));
408 req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;
409 req.emr_in_buf = payload;
410 req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;
411 req.emr_out_buf = payload;
412 req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN;
414 MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,
418 MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE);
421 i < MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN;
423 req_table[i] = (n > 0) ? (uint8_t)table[i % n] : 0;
426 efx_mcdi_execute(enp, &req);
428 if (req.emr_rc != 0) {
438 EFSYS_PROBE1(fail1, efx_rc_t, rc);
442 #endif /* EFSYS_OPT_RX_SCALE */
445 __checkReturn efx_rc_t
449 #if EFSYS_OPT_RX_SCALE
451 if (efx_mcdi_rss_context_alloc(enp, EFX_RX_SCALE_EXCLUSIVE, EFX_MAXRSS,
452 &enp->en_rss_context) == 0) {
454 * Allocated an exclusive RSS context, which allows both the
455 * indirection table and key to be modified.
457 enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
458 enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
461 * Failed to allocate an exclusive RSS context. Continue
462 * operation without support for RSS. The pseudo-header in
463 * received packets will not contain a Toeplitz hash value.
465 enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
466 enp->en_hash_support = EFX_RX_HASH_UNAVAILABLE;
469 #endif /* EFSYS_OPT_RX_SCALE */
474 #if EFSYS_OPT_RX_SCATTER
475 __checkReturn efx_rc_t
476 ef10_rx_scatter_enable(
478 __in unsigned int buf_size)
480 _NOTE(ARGUNUSED(enp, buf_size))
483 #endif /* EFSYS_OPT_RX_SCATTER */
485 #if EFSYS_OPT_RX_SCALE
486 __checkReturn efx_rc_t
487 ef10_rx_scale_mode_set(
489 __in efx_rx_hash_alg_t alg,
490 __in efx_rx_hash_type_t type,
491 __in boolean_t insert)
495 EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ);
496 EFSYS_ASSERT3U(insert, ==, B_TRUE);
498 if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) {
503 if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
508 if ((rc = efx_mcdi_rss_context_set_flags(enp,
509 enp->en_rss_context, type)) != 0)
519 EFSYS_PROBE1(fail1, efx_rc_t, rc);
523 #endif /* EFSYS_OPT_RX_SCALE */
525 #if EFSYS_OPT_RX_SCALE
526 __checkReturn efx_rc_t
527 ef10_rx_scale_key_set(
529 __in_ecount(n) uint8_t *key,
534 if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
539 if ((rc = efx_mcdi_rss_context_set_key(enp,
540 enp->en_rss_context, key, n)) != 0)
548 EFSYS_PROBE1(fail1, efx_rc_t, rc);
552 #endif /* EFSYS_OPT_RX_SCALE */
554 #if EFSYS_OPT_RX_SCALE
555 __checkReturn efx_rc_t
556 ef10_rx_scale_tbl_set(
558 __in_ecount(n) unsigned int *table,
563 if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
568 if ((rc = efx_mcdi_rss_context_set_table(enp,
569 enp->en_rss_context, table, n)) != 0)
577 EFSYS_PROBE1(fail1, efx_rc_t, rc);
581 #endif /* EFSYS_OPT_RX_SCALE */
585 * EF10 RX pseudo-header
586 * ---------------------
588 * Receive packets are prefixed by an (optional) 14 byte pseudo-header:
590 * +00: Toeplitz hash value.
591 * (32bit little-endian)
592 * +04: Outer VLAN tag. Zero if the packet did not have an outer VLAN tag.
594 * +06: Inner VLAN tag. Zero if the packet did not have an inner VLAN tag.
596 * +08: Packet Length. Zero if the RX datapath was in cut-through mode.
597 * (16bit little-endian)
598 * +10: MAC timestamp. Zero if timestamping is not enabled.
599 * (32bit little-endian)
601 * See "The RX Pseudo-header" in SF-109306-TC.
604 __checkReturn efx_rc_t
605 ef10_rx_prefix_pktlen(
607 __in uint8_t *buffer,
608 __out uint16_t *lengthp)
610 _NOTE(ARGUNUSED(enp))
613 * The RX pseudo-header contains the packet length, excluding the
614 * pseudo-header. If the hardware receive datapath was operating in
615 * cut-through mode then the length in the RX pseudo-header will be
616 * zero, and the packet length must be obtained from the DMA length
617 * reported in the RX event.
619 *lengthp = buffer[8] | (buffer[9] << 8);
623 #if EFSYS_OPT_RX_SCALE
624 __checkReturn uint32_t
627 __in efx_rx_hash_alg_t func,
628 __in uint8_t *buffer)
630 _NOTE(ARGUNUSED(enp))
633 case EFX_RX_HASHALG_TOEPLITZ:
644 #endif /* EFSYS_OPT_RX_SCALE */
649 __in_ecount(n) efsys_dma_addr_t *addrp,
652 __in unsigned int completed,
653 __in unsigned int added)
660 /* The client driver must not overfill the queue */
661 EFSYS_ASSERT3U(added - completed + n, <=,
662 EFX_RXQ_LIMIT(erp->er_mask + 1));
664 id = added & (erp->er_mask);
665 for (i = 0; i < n; i++) {
666 EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
667 unsigned int, id, efsys_dma_addr_t, addrp[i],
670 EFX_POPULATE_QWORD_3(qword,
671 ESF_DZ_RX_KER_BYTE_CNT, (uint32_t)(size),
672 ESF_DZ_RX_KER_BUF_ADDR_DW0,
673 (uint32_t)(addrp[i] & 0xffffffff),
674 ESF_DZ_RX_KER_BUF_ADDR_DW1,
675 (uint32_t)(addrp[i] >> 32));
677 offset = id * sizeof (efx_qword_t);
678 EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
680 id = (id + 1) & (erp->er_mask);
687 __in unsigned int added,
688 __inout unsigned int *pushedp)
690 efx_nic_t *enp = erp->er_enp;
691 unsigned int pushed = *pushedp;
695 /* Hardware has alignment restriction for WPTR */
696 wptr = P2ALIGN(added, EF10_RX_WPTR_ALIGN);
702 /* Push the populated descriptors out */
703 wptr &= erp->er_mask;
705 EFX_POPULATE_DWORD_1(dword, ERF_DZ_RX_DESC_WPTR, wptr);
707 /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
708 EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
709 wptr, pushed & erp->er_mask);
710 EFSYS_PIO_WRITE_BARRIER();
711 EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG,
712 erp->er_index, &dword, B_FALSE);
715 __checkReturn efx_rc_t
719 efx_nic_t *enp = erp->er_enp;
722 if ((rc = efx_mcdi_fini_rxq(enp, erp->er_index)) != 0)
729 * EALREADY is not an error, but indicates that the MC has rebooted and
730 * that the RXQ has already been destroyed. Callers need to know that
731 * the RXQ flush has completed to avoid waiting until timeout for a
732 * flush done event that will not be delivered.
735 EFSYS_PROBE1(fail1, efx_rc_t, rc);
745 _NOTE(ARGUNUSED(erp))
749 __checkReturn efx_rc_t
752 __in unsigned int index,
753 __in unsigned int label,
754 __in efx_rxq_type_t type,
755 __in efsys_mem_t *esmp,
761 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
763 boolean_t disable_scatter;
765 _NOTE(ARGUNUSED(id, erp))
767 EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << ESF_DZ_RX_QLABEL_WIDTH));
768 EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
769 EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
771 EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
772 EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
774 if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
778 if (index >= encp->enc_rxq_limit) {
783 /* Scatter can only be disabled if the firmware supports doing so */
784 if (type == EFX_RXQ_TYPE_SCATTER)
785 disable_scatter = B_FALSE;
787 disable_scatter = encp->enc_rx_disable_scatter_supported;
789 if ((rc = efx_mcdi_init_rxq(enp, n, eep->ee_index, label, index,
790 esmp, disable_scatter)) != 0)
794 erp->er_label = label;
796 ef10_ev_rxlabel_init(eep, erp, label);
805 EFSYS_PROBE1(fail1, efx_rc_t, rc);
814 efx_nic_t *enp = erp->er_enp;
815 efx_evq_t *eep = erp->er_eep;
816 unsigned int label = erp->er_label;
818 ef10_ev_rxlabel_fini(eep, label);
820 EFSYS_ASSERT(enp->en_rx_qcount != 0);
823 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
830 #if EFSYS_OPT_RX_SCALE
831 if (enp->en_rss_support != EFX_RX_SCALE_UNAVAILABLE) {
832 (void) efx_mcdi_rss_context_free(enp, enp->en_rss_context);
834 enp->en_rss_context = 0;
835 enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
837 _NOTE(ARGUNUSED(enp))
838 #endif /* EFSYS_OPT_RX_SCALE */
841 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */