1b6b29352SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
2b6b29352SAndrew Rybchenko *
3672386c1SAndrew Rybchenko * Copyright(c) 2019-2021 Xilinx, Inc.
4b6b29352SAndrew Rybchenko * Copyright(c) 2018-2019 Solarflare Communications Inc.
5b6b29352SAndrew Rybchenko */
6b6b29352SAndrew Rybchenko
7b6b29352SAndrew Rybchenko #include "efx.h"
8b6b29352SAndrew Rybchenko #include "efx_impl.h"
9b6b29352SAndrew Rybchenko
10b6b29352SAndrew Rybchenko
11b6b29352SAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD
12b6b29352SAndrew Rybchenko
136bba823fSAndrew Rybchenko /*
14c1f02189SAndrew Rybchenko * Maximum number of Rx prefixes supported by Rx prefix choice to be
15c1f02189SAndrew Rybchenko * returned from firmware.
16c1f02189SAndrew Rybchenko */
17c1f02189SAndrew Rybchenko #define RHEAD_RX_PREFIX_IDS_MAX 16
18c1f02189SAndrew Rybchenko
19c1f02189SAndrew Rybchenko /*
206bba823fSAndrew Rybchenko * Default Rx prefix layout on Riverhead if FW does not support Rx
216bba823fSAndrew Rybchenko * prefix choice using MC_CMD_GET_RX_PREFIX_ID and query its layout
226bba823fSAndrew Rybchenko * using MC_CMD_QUERY_RX_PREFIX_ID.
236bba823fSAndrew Rybchenko *
246bba823fSAndrew Rybchenko * See SF-119689-TC Riverhead Host Interface section 6.4.
256bba823fSAndrew Rybchenko */
266bba823fSAndrew Rybchenko static const efx_rx_prefix_layout_t rhead_default_rx_prefix_layout = {
276bba823fSAndrew Rybchenko .erpl_id = 0,
286bba823fSAndrew Rybchenko .erpl_length = ESE_GZ_RX_PKT_PREFIX_LEN,
296bba823fSAndrew Rybchenko .erpl_fields = {
306bba823fSAndrew Rybchenko #define RHEAD_RX_PREFIX_FIELD(_name, _big_endian) \
316bba823fSAndrew Rybchenko EFX_RX_PREFIX_FIELD(_name, ESF_GZ_RX_PREFIX_ ## _name, _big_endian)
326bba823fSAndrew Rybchenko
336bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(LENGTH, B_FALSE),
346bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(RSS_HASH_VALID, B_FALSE),
356bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(USER_FLAG, B_FALSE),
366bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(CLASS, B_FALSE),
376bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(PARTIAL_TSTAMP, B_FALSE),
386bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(RSS_HASH, B_FALSE),
396bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(USER_MARK, B_FALSE),
40c4f4a0e6SAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(INGRESS_MPORT, B_FALSE),
416bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(CSUM_FRAME, B_TRUE),
426bba823fSAndrew Rybchenko RHEAD_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_TRUE),
436bba823fSAndrew Rybchenko
446bba823fSAndrew Rybchenko #undef RHEAD_RX_PREFIX_FIELD
456bba823fSAndrew Rybchenko }
466bba823fSAndrew Rybchenko };
476bba823fSAndrew Rybchenko
48b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_init(__in efx_nic_t * enp)49b6b29352SAndrew Rybchenko rhead_rx_init(
50b6b29352SAndrew Rybchenko __in efx_nic_t *enp)
51b6b29352SAndrew Rybchenko {
52b6b29352SAndrew Rybchenko efx_rc_t rc;
53b6b29352SAndrew Rybchenko
54b6b29352SAndrew Rybchenko rc = ef10_rx_init(enp);
55b6b29352SAndrew Rybchenko if (rc != 0)
56b6b29352SAndrew Rybchenko goto fail1;
57b6b29352SAndrew Rybchenko
58b6b29352SAndrew Rybchenko return (0);
59b6b29352SAndrew Rybchenko
60b6b29352SAndrew Rybchenko fail1:
61b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
62b6b29352SAndrew Rybchenko return (rc);
63b6b29352SAndrew Rybchenko }
64b6b29352SAndrew Rybchenko
65b6b29352SAndrew Rybchenko void
rhead_rx_fini(__in efx_nic_t * enp)66b6b29352SAndrew Rybchenko rhead_rx_fini(
67b6b29352SAndrew Rybchenko __in efx_nic_t *enp)
68b6b29352SAndrew Rybchenko {
69b6b29352SAndrew Rybchenko ef10_rx_fini(enp);
70b6b29352SAndrew Rybchenko }
71b6b29352SAndrew Rybchenko
72b6b29352SAndrew Rybchenko #if EFSYS_OPT_RX_SCATTER
73b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_scatter_enable(__in efx_nic_t * enp,__in unsigned int buf_size)74b6b29352SAndrew Rybchenko rhead_rx_scatter_enable(
75b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
76b6b29352SAndrew Rybchenko __in unsigned int buf_size)
77b6b29352SAndrew Rybchenko {
78b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(enp, buf_size))
79b6b29352SAndrew Rybchenko /* Nothing to do here */
80b6b29352SAndrew Rybchenko return (0);
81b6b29352SAndrew Rybchenko }
82b6b29352SAndrew Rybchenko #endif /* EFSYS_OPT_RX_SCATTER */
83b6b29352SAndrew Rybchenko
84b6b29352SAndrew Rybchenko #if EFSYS_OPT_RX_SCALE
85b6b29352SAndrew Rybchenko
86b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_scale_context_alloc(__in efx_nic_t * enp,__in efx_rx_scale_context_type_t type,__in uint32_t num_queues,__in uint32_t table_nentries,__out uint32_t * rss_contextp)87b6b29352SAndrew Rybchenko rhead_rx_scale_context_alloc(
88b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
89b6b29352SAndrew Rybchenko __in efx_rx_scale_context_type_t type,
90b6b29352SAndrew Rybchenko __in uint32_t num_queues,
91e7ea5f30SIvan Malov __in uint32_t table_nentries,
92b6b29352SAndrew Rybchenko __out uint32_t *rss_contextp)
93b6b29352SAndrew Rybchenko {
94b6b29352SAndrew Rybchenko efx_rc_t rc;
95b6b29352SAndrew Rybchenko
96e7ea5f30SIvan Malov rc = ef10_rx_scale_context_alloc(enp, type, num_queues, table_nentries,
97e7ea5f30SIvan Malov rss_contextp);
98b6b29352SAndrew Rybchenko if (rc != 0)
99b6b29352SAndrew Rybchenko goto fail1;
100b6b29352SAndrew Rybchenko
101b6b29352SAndrew Rybchenko return (0);
102b6b29352SAndrew Rybchenko
103b6b29352SAndrew Rybchenko fail1:
104b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
105b6b29352SAndrew Rybchenko return (rc);
106b6b29352SAndrew Rybchenko }
107b6b29352SAndrew Rybchenko
108b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_scale_context_free(__in efx_nic_t * enp,__in uint32_t rss_context)109b6b29352SAndrew Rybchenko rhead_rx_scale_context_free(
110b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
111b6b29352SAndrew Rybchenko __in uint32_t rss_context)
112b6b29352SAndrew Rybchenko {
113b6b29352SAndrew Rybchenko efx_rc_t rc;
114b6b29352SAndrew Rybchenko
115b6b29352SAndrew Rybchenko rc = ef10_rx_scale_context_free(enp, rss_context);
116b6b29352SAndrew Rybchenko if (rc != 0)
117b6b29352SAndrew Rybchenko goto fail1;
118b6b29352SAndrew Rybchenko
119b6b29352SAndrew Rybchenko return (0);
120b6b29352SAndrew Rybchenko
121b6b29352SAndrew Rybchenko fail1:
122b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
123b6b29352SAndrew Rybchenko return (rc);
124b6b29352SAndrew Rybchenko }
125b6b29352SAndrew Rybchenko
126b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_scale_mode_set(__in efx_nic_t * enp,__in uint32_t rss_context,__in efx_rx_hash_alg_t alg,__in efx_rx_hash_type_t type,__in boolean_t insert)127b6b29352SAndrew Rybchenko rhead_rx_scale_mode_set(
128b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
129b6b29352SAndrew Rybchenko __in uint32_t rss_context,
130b6b29352SAndrew Rybchenko __in efx_rx_hash_alg_t alg,
131b6b29352SAndrew Rybchenko __in efx_rx_hash_type_t type,
132b6b29352SAndrew Rybchenko __in boolean_t insert)
133b6b29352SAndrew Rybchenko {
134b6b29352SAndrew Rybchenko efx_rc_t rc;
135b6b29352SAndrew Rybchenko
136b6b29352SAndrew Rybchenko rc = ef10_rx_scale_mode_set(enp, rss_context, alg, type, insert);
137b6b29352SAndrew Rybchenko if (rc != 0)
138b6b29352SAndrew Rybchenko goto fail1;
139b6b29352SAndrew Rybchenko
140b6b29352SAndrew Rybchenko return (0);
141b6b29352SAndrew Rybchenko
142b6b29352SAndrew Rybchenko fail1:
143b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
144b6b29352SAndrew Rybchenko return (rc);
145b6b29352SAndrew Rybchenko }
146b6b29352SAndrew Rybchenko
147b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_scale_key_set(__in efx_nic_t * enp,__in uint32_t rss_context,__in_ecount (n)uint8_t * key,__in size_t n)148b6b29352SAndrew Rybchenko rhead_rx_scale_key_set(
149b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
150b6b29352SAndrew Rybchenko __in uint32_t rss_context,
151b6b29352SAndrew Rybchenko __in_ecount(n) uint8_t *key,
152b6b29352SAndrew Rybchenko __in size_t n)
153b6b29352SAndrew Rybchenko {
154b6b29352SAndrew Rybchenko efx_rc_t rc;
155b6b29352SAndrew Rybchenko
156b6b29352SAndrew Rybchenko rc = ef10_rx_scale_key_set(enp, rss_context, key, n);
157b6b29352SAndrew Rybchenko if (rc != 0)
158b6b29352SAndrew Rybchenko goto fail1;
159b6b29352SAndrew Rybchenko
160b6b29352SAndrew Rybchenko return (0);
161b6b29352SAndrew Rybchenko
162b6b29352SAndrew Rybchenko fail1:
163b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
164b6b29352SAndrew Rybchenko return (rc);
165b6b29352SAndrew Rybchenko }
166b6b29352SAndrew Rybchenko
167b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_scale_tbl_set(__in efx_nic_t * enp,__in uint32_t rss_context,__in_ecount (nentries)unsigned int * table,__in size_t nentries)168b6b29352SAndrew Rybchenko rhead_rx_scale_tbl_set(
169b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
170b6b29352SAndrew Rybchenko __in uint32_t rss_context,
1717a71c15dSIvan Malov __in_ecount(nentries) unsigned int *table,
1727a71c15dSIvan Malov __in size_t nentries)
173b6b29352SAndrew Rybchenko {
174b6b29352SAndrew Rybchenko efx_rc_t rc;
175b6b29352SAndrew Rybchenko
1767a71c15dSIvan Malov rc = ef10_rx_scale_tbl_set(enp, rss_context, table, nentries);
177b6b29352SAndrew Rybchenko if (rc != 0)
178b6b29352SAndrew Rybchenko goto fail1;
179b6b29352SAndrew Rybchenko
180b6b29352SAndrew Rybchenko return (0);
181b6b29352SAndrew Rybchenko
182b6b29352SAndrew Rybchenko fail1:
183b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
184b6b29352SAndrew Rybchenko return (rc);
185b6b29352SAndrew Rybchenko }
186b6b29352SAndrew Rybchenko
187b6b29352SAndrew Rybchenko __checkReturn uint32_t
rhead_rx_prefix_hash(__in efx_nic_t * enp,__in efx_rx_hash_alg_t func,__in uint8_t * buffer)188b6b29352SAndrew Rybchenko rhead_rx_prefix_hash(
189b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
190b6b29352SAndrew Rybchenko __in efx_rx_hash_alg_t func,
191b6b29352SAndrew Rybchenko __in uint8_t *buffer)
192b6b29352SAndrew Rybchenko {
193b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(enp, func, buffer))
194b6b29352SAndrew Rybchenko
195b6b29352SAndrew Rybchenko /* FIXME implement the method for Riverhead */
196b6b29352SAndrew Rybchenko
197b6b29352SAndrew Rybchenko return (ENOTSUP);
198b6b29352SAndrew Rybchenko }
199b6b29352SAndrew Rybchenko
200b6b29352SAndrew Rybchenko #endif /* EFSYS_OPT_RX_SCALE */
201b6b29352SAndrew Rybchenko
202b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_prefix_pktlen(__in efx_nic_t * enp,__in uint8_t * buffer,__out uint16_t * lengthp)203b6b29352SAndrew Rybchenko rhead_rx_prefix_pktlen(
204b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
205b6b29352SAndrew Rybchenko __in uint8_t *buffer,
206b6b29352SAndrew Rybchenko __out uint16_t *lengthp)
207b6b29352SAndrew Rybchenko {
208b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(enp, buffer, lengthp))
209b6b29352SAndrew Rybchenko
210b6b29352SAndrew Rybchenko /* FIXME implement the method for Riverhead */
211b6b29352SAndrew Rybchenko
212b6b29352SAndrew Rybchenko return (ENOTSUP);
213b6b29352SAndrew Rybchenko }
214b6b29352SAndrew Rybchenko
215b6b29352SAndrew Rybchenko void
rhead_rx_qpost(__in efx_rxq_t * erp,__in_ecount (ndescs)efsys_dma_addr_t * addrp,__in size_t size,__in unsigned int ndescs,__in unsigned int completed,__in unsigned int added)216b6b29352SAndrew Rybchenko rhead_rx_qpost(
217b6b29352SAndrew Rybchenko __in efx_rxq_t *erp,
218b6b29352SAndrew Rybchenko __in_ecount(ndescs) efsys_dma_addr_t *addrp,
219b6b29352SAndrew Rybchenko __in size_t size,
220b6b29352SAndrew Rybchenko __in unsigned int ndescs,
221b6b29352SAndrew Rybchenko __in unsigned int completed,
222b6b29352SAndrew Rybchenko __in unsigned int added)
223b6b29352SAndrew Rybchenko {
224b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(erp, addrp, size, ndescs, completed, added))
225b6b29352SAndrew Rybchenko
226b6b29352SAndrew Rybchenko /* FIXME implement the method for Riverhead */
227b6b29352SAndrew Rybchenko
228b6b29352SAndrew Rybchenko EFSYS_ASSERT(B_FALSE);
229b6b29352SAndrew Rybchenko }
230b6b29352SAndrew Rybchenko
231b6b29352SAndrew Rybchenko void
rhead_rx_qpush(__in efx_rxq_t * erp,__in unsigned int added,__inout unsigned int * pushedp)232b6b29352SAndrew Rybchenko rhead_rx_qpush(
233b6b29352SAndrew Rybchenko __in efx_rxq_t *erp,
234b6b29352SAndrew Rybchenko __in unsigned int added,
235b6b29352SAndrew Rybchenko __inout unsigned int *pushedp)
236b6b29352SAndrew Rybchenko {
237b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(erp, added, pushedp))
238b6b29352SAndrew Rybchenko
239b6b29352SAndrew Rybchenko /* FIXME implement the method for Riverhead */
240b6b29352SAndrew Rybchenko
241b6b29352SAndrew Rybchenko EFSYS_ASSERT(B_FALSE);
242b6b29352SAndrew Rybchenko }
243b6b29352SAndrew Rybchenko
244b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_qflush(__in efx_rxq_t * erp)245b6b29352SAndrew Rybchenko rhead_rx_qflush(
246b6b29352SAndrew Rybchenko __in efx_rxq_t *erp)
247b6b29352SAndrew Rybchenko {
248b6b29352SAndrew Rybchenko efx_nic_t *enp = erp->er_enp;
249b6b29352SAndrew Rybchenko efx_rc_t rc;
250b6b29352SAndrew Rybchenko
251b6b29352SAndrew Rybchenko if ((rc = efx_mcdi_fini_rxq(enp, erp->er_index)) != 0)
252b6b29352SAndrew Rybchenko goto fail1;
253b6b29352SAndrew Rybchenko
254b6b29352SAndrew Rybchenko return (0);
255b6b29352SAndrew Rybchenko
256b6b29352SAndrew Rybchenko fail1:
257b6b29352SAndrew Rybchenko /*
258b6b29352SAndrew Rybchenko * EALREADY is not an error, but indicates that the MC has rebooted and
259b6b29352SAndrew Rybchenko * that the RXQ has already been destroyed. Callers need to know that
260b6b29352SAndrew Rybchenko * the RXQ flush has completed to avoid waiting until timeout for a
261b6b29352SAndrew Rybchenko * flush done event that will not be delivered.
262b6b29352SAndrew Rybchenko */
263b6b29352SAndrew Rybchenko if (rc != EALREADY)
264b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
265b6b29352SAndrew Rybchenko
266b6b29352SAndrew Rybchenko return (rc);
267b6b29352SAndrew Rybchenko }
268b6b29352SAndrew Rybchenko
269b6b29352SAndrew Rybchenko void
rhead_rx_qenable(__in efx_rxq_t * erp)270b6b29352SAndrew Rybchenko rhead_rx_qenable(
271b6b29352SAndrew Rybchenko __in efx_rxq_t *erp)
272b6b29352SAndrew Rybchenko {
273b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(erp))
274b6b29352SAndrew Rybchenko }
275b6b29352SAndrew Rybchenko
276c1f02189SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_get_rx_prefix_ids(__in efx_nic_t * enp,__in uint32_t mcdi_fields_mask,__in unsigned int max_ids,__out unsigned int * nids,__out_ecount_part (max_ids,* nids)uint32_t * idsp)277c1f02189SAndrew Rybchenko efx_mcdi_get_rx_prefix_ids(
278c1f02189SAndrew Rybchenko __in efx_nic_t *enp,
279c1f02189SAndrew Rybchenko __in uint32_t mcdi_fields_mask,
280c1f02189SAndrew Rybchenko __in unsigned int max_ids,
281c1f02189SAndrew Rybchenko __out unsigned int *nids,
282c1f02189SAndrew Rybchenko __out_ecount_part(max_ids, *nids) uint32_t *idsp)
283c1f02189SAndrew Rybchenko {
284c1f02189SAndrew Rybchenko efx_mcdi_req_t req;
285c1f02189SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RX_PREFIX_ID_IN_LEN,
286c1f02189SAndrew Rybchenko MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX);
287c1f02189SAndrew Rybchenko efx_rc_t rc;
288c1f02189SAndrew Rybchenko uint32_t num;
289c1f02189SAndrew Rybchenko
290c1f02189SAndrew Rybchenko req.emr_cmd = MC_CMD_GET_RX_PREFIX_ID;
291c1f02189SAndrew Rybchenko req.emr_in_buf = payload;
292c1f02189SAndrew Rybchenko req.emr_in_length = MC_CMD_GET_RX_PREFIX_ID_IN_LEN;
293c1f02189SAndrew Rybchenko req.emr_out_buf = payload;
294c1f02189SAndrew Rybchenko req.emr_out_length = MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX;
295c1f02189SAndrew Rybchenko
296c1f02189SAndrew Rybchenko MCDI_IN_SET_DWORD(req, GET_RX_PREFIX_ID_IN_FIELDS, mcdi_fields_mask);
297c1f02189SAndrew Rybchenko
298c1f02189SAndrew Rybchenko efx_mcdi_execute(enp, &req);
299c1f02189SAndrew Rybchenko
300c1f02189SAndrew Rybchenko if (req.emr_rc != 0) {
301c1f02189SAndrew Rybchenko rc = req.emr_rc;
302c1f02189SAndrew Rybchenko goto fail1;
303c1f02189SAndrew Rybchenko }
304c1f02189SAndrew Rybchenko
305c1f02189SAndrew Rybchenko if (req.emr_out_length_used < MC_CMD_GET_RX_PREFIX_ID_OUT_LENMIN) {
306c1f02189SAndrew Rybchenko rc = EMSGSIZE;
307c1f02189SAndrew Rybchenko goto fail2;
308c1f02189SAndrew Rybchenko }
309c1f02189SAndrew Rybchenko
310c1f02189SAndrew Rybchenko num = MCDI_OUT_DWORD(req, GET_RX_PREFIX_ID_OUT_NUM_RX_PREFIX_IDS);
311c1f02189SAndrew Rybchenko
312c1f02189SAndrew Rybchenko if (req.emr_out_length_used != MC_CMD_GET_RX_PREFIX_ID_OUT_LEN(num)) {
313c1f02189SAndrew Rybchenko rc = EMSGSIZE;
314c1f02189SAndrew Rybchenko goto fail3;
315c1f02189SAndrew Rybchenko }
316c1f02189SAndrew Rybchenko
317c1f02189SAndrew Rybchenko *nids = MIN(num, max_ids);
318c1f02189SAndrew Rybchenko
319c1f02189SAndrew Rybchenko EFX_STATIC_ASSERT(sizeof (idsp[0]) ==
320c1f02189SAndrew Rybchenko MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_LEN);
321c1f02189SAndrew Rybchenko memcpy(idsp,
322c1f02189SAndrew Rybchenko MCDI_OUT2(req, uint32_t, GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID),
323c1f02189SAndrew Rybchenko *nids * sizeof (idsp[0]));
324c1f02189SAndrew Rybchenko
325c1f02189SAndrew Rybchenko return (0);
326c1f02189SAndrew Rybchenko
327c1f02189SAndrew Rybchenko fail3:
328c1f02189SAndrew Rybchenko EFSYS_PROBE(fail3);
329c1f02189SAndrew Rybchenko fail2:
330c1f02189SAndrew Rybchenko EFSYS_PROBE(fail2);
331c1f02189SAndrew Rybchenko fail1:
332c1f02189SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
333c1f02189SAndrew Rybchenko
334c1f02189SAndrew Rybchenko return (rc);
335c1f02189SAndrew Rybchenko }
336c1f02189SAndrew Rybchenko
337c1f02189SAndrew Rybchenko static __checkReturn efx_rx_prefix_field_t
efx_mcdi_rx_prefix_field_map(unsigned int mcdi_idx)338c1f02189SAndrew Rybchenko efx_mcdi_rx_prefix_field_map(unsigned int mcdi_idx)
339c1f02189SAndrew Rybchenko {
340c1f02189SAndrew Rybchenko static const efx_rx_prefix_field_t efx_mcdi_to_rx_prefix_field[] = {
341c1f02189SAndrew Rybchenko #define EFX_MCDI_TO_RX_PREFIX_FIELD(_field) \
342c1f02189SAndrew Rybchenko [RX_PREFIX_FIELD_INFO_ ## _field] = EFX_RX_PREFIX_FIELD_ ## _field
343c1f02189SAndrew Rybchenko
344c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(LENGTH),
345c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(RSS_HASH_VALID),
346c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(USER_FLAG),
347c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(CLASS),
348c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(PARTIAL_TSTAMP),
349c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(RSS_HASH),
350c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(USER_MARK),
351c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(INGRESS_VPORT),
352c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(CSUM_FRAME),
353c1f02189SAndrew Rybchenko EFX_MCDI_TO_RX_PREFIX_FIELD(VLAN_STRIP_TCI),
354c1f02189SAndrew Rybchenko
355c1f02189SAndrew Rybchenko #undef EFX_MCDI_TO_RX_PREFIX_FIELD
356c1f02189SAndrew Rybchenko };
357c1f02189SAndrew Rybchenko
358c1f02189SAndrew Rybchenko if (mcdi_idx >= EFX_ARRAY_SIZE(efx_mcdi_to_rx_prefix_field))
359c1f02189SAndrew Rybchenko return (EFX_RX_PREFIX_NFIELDS);
360c1f02189SAndrew Rybchenko
361c1f02189SAndrew Rybchenko return (efx_mcdi_to_rx_prefix_field[mcdi_idx]);
362c1f02189SAndrew Rybchenko }
363c1f02189SAndrew Rybchenko
364c1f02189SAndrew Rybchenko static __checkReturn int
efx_rx_prefix_field_map_to_mcdi(__in efx_rx_prefix_field_t field)365c1f02189SAndrew Rybchenko efx_rx_prefix_field_map_to_mcdi(
366c1f02189SAndrew Rybchenko __in efx_rx_prefix_field_t field)
367c1f02189SAndrew Rybchenko {
368c1f02189SAndrew Rybchenko static const int efx_rx_prefix_field_to_mcdi[] = {
369c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_LENGTH] =
370c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_LENGTH),
371c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_ORIG_LENGTH] = -1,
372c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_CLASS] =
373c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_CLASS),
374c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_RSS_HASH] =
375c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH),
376c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_RSS_HASH_VALID] =
377c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_VALID),
378c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_PARTIAL_TSTAMP] =
379c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_PARTIAL_TSTAMP),
380c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI] =
381c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI),
382c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_INNER_VLAN_STRIP_TCI] = -1,
383c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_USER_FLAG] =
384c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_USER_FLAG),
385c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_USER_MARK] =
386c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK),
387c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_USER_MARK_VALID] = -1,
388c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_CSUM_FRAME] =
389c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_CSUM_FRAME),
390c1f02189SAndrew Rybchenko [EFX_RX_PREFIX_FIELD_INGRESS_VPORT] =
391c1f02189SAndrew Rybchenko EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT),
392c1f02189SAndrew Rybchenko };
393c1f02189SAndrew Rybchenko
394c1f02189SAndrew Rybchenko if (field >= EFX_ARRAY_SIZE(efx_rx_prefix_field_to_mcdi))
395c1f02189SAndrew Rybchenko return (-1);
396c1f02189SAndrew Rybchenko
397c1f02189SAndrew Rybchenko return (efx_rx_prefix_field_to_mcdi[field]);
398c1f02189SAndrew Rybchenko }
399c1f02189SAndrew Rybchenko
400c1f02189SAndrew Rybchenko static __checkReturn efx_rc_t
efx_rx_prefix_fields_mask_to_mcdi(__in uint32_t fields_mask,__out uint32_t * mcdi_fields_maskp)401c1f02189SAndrew Rybchenko efx_rx_prefix_fields_mask_to_mcdi(
402c1f02189SAndrew Rybchenko __in uint32_t fields_mask,
403c1f02189SAndrew Rybchenko __out uint32_t *mcdi_fields_maskp)
404c1f02189SAndrew Rybchenko {
405c1f02189SAndrew Rybchenko uint32_t mcdi_fields_mask = 0;
406c1f02189SAndrew Rybchenko unsigned int i;
407c1f02189SAndrew Rybchenko
408c1f02189SAndrew Rybchenko for (i = 0; i < EFX_RX_PREFIX_NFIELDS; ++i) {
409c1f02189SAndrew Rybchenko if (fields_mask & (1U << i)) {
410c1f02189SAndrew Rybchenko int mcdi_field = efx_rx_prefix_field_map_to_mcdi(i);
411c1f02189SAndrew Rybchenko
412c1f02189SAndrew Rybchenko if (mcdi_field < 0)
413c1f02189SAndrew Rybchenko return (EINVAL);
414c1f02189SAndrew Rybchenko
415c1f02189SAndrew Rybchenko mcdi_fields_mask |= (1U << mcdi_field);
416c1f02189SAndrew Rybchenko }
417c1f02189SAndrew Rybchenko }
418c1f02189SAndrew Rybchenko
419c1f02189SAndrew Rybchenko *mcdi_fields_maskp = mcdi_fields_mask;
420c1f02189SAndrew Rybchenko return (0);
421c1f02189SAndrew Rybchenko }
422c1f02189SAndrew Rybchenko
423c1f02189SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_query_rx_prefix_id(__in efx_nic_t * enp,__in uint32_t prefix_id,__out efx_rx_prefix_layout_t * erplp)424c1f02189SAndrew Rybchenko efx_mcdi_query_rx_prefix_id(
425c1f02189SAndrew Rybchenko __in efx_nic_t *enp,
426c1f02189SAndrew Rybchenko __in uint32_t prefix_id,
427c1f02189SAndrew Rybchenko __out efx_rx_prefix_layout_t *erplp)
428c1f02189SAndrew Rybchenko {
429c1f02189SAndrew Rybchenko efx_mcdi_req_t req;
430c1f02189SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN,
431c1f02189SAndrew Rybchenko MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX);
432c1f02189SAndrew Rybchenko efx_rc_t rc;
433c1f02189SAndrew Rybchenko size_t response_len;
434c1f02189SAndrew Rybchenko const efx_dword_t *resp;
435c1f02189SAndrew Rybchenko const efx_dword_t *finfo;
436c1f02189SAndrew Rybchenko unsigned int num_fields;
437c1f02189SAndrew Rybchenko unsigned int mcdi_field;
438c1f02189SAndrew Rybchenko efx_rx_prefix_field_t field;
439c1f02189SAndrew Rybchenko unsigned int i;
440c1f02189SAndrew Rybchenko
441c1f02189SAndrew Rybchenko req.emr_cmd = MC_CMD_QUERY_RX_PREFIX_ID;
442c1f02189SAndrew Rybchenko req.emr_in_buf = payload;
443c1f02189SAndrew Rybchenko req.emr_in_length = MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN;
444c1f02189SAndrew Rybchenko req.emr_out_buf = payload;
445c1f02189SAndrew Rybchenko req.emr_out_length = MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX;
446c1f02189SAndrew Rybchenko
447c1f02189SAndrew Rybchenko MCDI_IN_SET_DWORD(req, QUERY_RX_PREFIX_ID_IN_RX_PREFIX_ID, prefix_id);
448c1f02189SAndrew Rybchenko
449c1f02189SAndrew Rybchenko efx_mcdi_execute(enp, &req);
450c1f02189SAndrew Rybchenko
451c1f02189SAndrew Rybchenko if (req.emr_rc != 0) {
452c1f02189SAndrew Rybchenko rc = req.emr_rc;
453c1f02189SAndrew Rybchenko goto fail1;
454c1f02189SAndrew Rybchenko }
455c1f02189SAndrew Rybchenko
456c1f02189SAndrew Rybchenko if (req.emr_out_length_used < MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN) {
457c1f02189SAndrew Rybchenko rc = EMSGSIZE;
458c1f02189SAndrew Rybchenko goto fail2;
459c1f02189SAndrew Rybchenko }
460c1f02189SAndrew Rybchenko
461c1f02189SAndrew Rybchenko if (MCDI_OUT_BYTE(req, QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE) !=
462c1f02189SAndrew Rybchenko MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE_FIXED) {
463c1f02189SAndrew Rybchenko rc = ENOTSUP;
464c1f02189SAndrew Rybchenko goto fail3;
465c1f02189SAndrew Rybchenko }
466c1f02189SAndrew Rybchenko
467c1f02189SAndrew Rybchenko EFX_STATIC_ASSERT(MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN >=
468c1f02189SAndrew Rybchenko MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST);
469c1f02189SAndrew Rybchenko response_len = req.emr_out_length_used -
470c1f02189SAndrew Rybchenko MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST;
471c1f02189SAndrew Rybchenko
472c1f02189SAndrew Rybchenko if (response_len < RX_PREFIX_FIXED_RESPONSE_LENMIN) {
473c1f02189SAndrew Rybchenko rc = EMSGSIZE;
474c1f02189SAndrew Rybchenko goto fail4;
475c1f02189SAndrew Rybchenko }
476c1f02189SAndrew Rybchenko
477c1f02189SAndrew Rybchenko resp = MCDI_OUT2(req, efx_dword_t, QUERY_RX_PREFIX_ID_OUT_RESPONSE);
478c1f02189SAndrew Rybchenko
479c1f02189SAndrew Rybchenko memset(erplp, 0, sizeof (*erplp));
480c1f02189SAndrew Rybchenko erplp->erpl_id = prefix_id;
481c1f02189SAndrew Rybchenko erplp->erpl_length =
482c1f02189SAndrew Rybchenko EFX_DWORD_FIELD(*resp, RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES);
483c1f02189SAndrew Rybchenko num_fields =
484c1f02189SAndrew Rybchenko EFX_DWORD_FIELD(*resp, RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT);
485c1f02189SAndrew Rybchenko
486c1f02189SAndrew Rybchenko if (response_len < RX_PREFIX_FIXED_RESPONSE_LEN(num_fields)) {
487c1f02189SAndrew Rybchenko rc = EMSGSIZE;
488c1f02189SAndrew Rybchenko goto fail5;
489c1f02189SAndrew Rybchenko }
490c1f02189SAndrew Rybchenko
491c1f02189SAndrew Rybchenko finfo = (const efx_dword_t *)((const uint8_t *)resp +
492c1f02189SAndrew Rybchenko RX_PREFIX_FIXED_RESPONSE_FIELDS_OFST);
493c1f02189SAndrew Rybchenko
494c1f02189SAndrew Rybchenko for (i = 0; i < num_fields; ++i, ++finfo) {
495c1f02189SAndrew Rybchenko mcdi_field = EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_TYPE);
496c1f02189SAndrew Rybchenko
497c1f02189SAndrew Rybchenko field = efx_mcdi_rx_prefix_field_map(mcdi_field);
498c1f02189SAndrew Rybchenko if (field >= EFX_RX_PREFIX_NFIELDS)
499c1f02189SAndrew Rybchenko continue;
500c1f02189SAndrew Rybchenko
501c1f02189SAndrew Rybchenko erplp->erpl_fields[field].erpfi_offset_bits =
502c1f02189SAndrew Rybchenko EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_OFFSET_BITS);
503c1f02189SAndrew Rybchenko erplp->erpl_fields[field].erpfi_width_bits =
504c1f02189SAndrew Rybchenko EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_WIDTH_BITS);
505c1f02189SAndrew Rybchenko }
506c1f02189SAndrew Rybchenko
507c1f02189SAndrew Rybchenko return (0);
508c1f02189SAndrew Rybchenko
509c1f02189SAndrew Rybchenko fail5:
510c1f02189SAndrew Rybchenko EFSYS_PROBE(fail5);
511c1f02189SAndrew Rybchenko fail4:
512c1f02189SAndrew Rybchenko EFSYS_PROBE(fail4);
513c1f02189SAndrew Rybchenko fail3:
514c1f02189SAndrew Rybchenko EFSYS_PROBE(fail3);
515c1f02189SAndrew Rybchenko fail2:
516c1f02189SAndrew Rybchenko EFSYS_PROBE(fail2);
517c1f02189SAndrew Rybchenko fail1:
518c1f02189SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
519c1f02189SAndrew Rybchenko
520c1f02189SAndrew Rybchenko return (rc);
521c1f02189SAndrew Rybchenko }
522c1f02189SAndrew Rybchenko
523c1f02189SAndrew Rybchenko static __checkReturn efx_rc_t
rhead_rx_choose_prefix_id(__in efx_nic_t * enp,__in uint32_t fields_mask,__out efx_rx_prefix_layout_t * erplp)524c1f02189SAndrew Rybchenko rhead_rx_choose_prefix_id(
525c1f02189SAndrew Rybchenko __in efx_nic_t *enp,
526c1f02189SAndrew Rybchenko __in uint32_t fields_mask,
527c1f02189SAndrew Rybchenko __out efx_rx_prefix_layout_t *erplp)
528c1f02189SAndrew Rybchenko {
529c1f02189SAndrew Rybchenko efx_rx_prefix_layout_t erpl;
530c1f02189SAndrew Rybchenko uint32_t prefix_ids[RHEAD_RX_PREFIX_IDS_MAX];
531c1f02189SAndrew Rybchenko uint32_t mcdi_fields_mask;
532c1f02189SAndrew Rybchenko unsigned int num = 0;
533c1f02189SAndrew Rybchenko unsigned int i;
534c1f02189SAndrew Rybchenko efx_rc_t rc;
535c1f02189SAndrew Rybchenko
536c1f02189SAndrew Rybchenko rc = efx_rx_prefix_fields_mask_to_mcdi(fields_mask, &mcdi_fields_mask);
537c1f02189SAndrew Rybchenko if (rc != 0)
538c1f02189SAndrew Rybchenko goto fail1;
539c1f02189SAndrew Rybchenko
540c1f02189SAndrew Rybchenko memset(erplp, 0, sizeof (*erplp));
541c1f02189SAndrew Rybchenko
542c1f02189SAndrew Rybchenko rc = efx_mcdi_get_rx_prefix_ids(enp, mcdi_fields_mask,
543c1f02189SAndrew Rybchenko EFX_ARRAY_SIZE(prefix_ids), &num, prefix_ids);
544c1f02189SAndrew Rybchenko if (rc == ENOTSUP) {
545c1f02189SAndrew Rybchenko /* Not supported MCDI, use default prefix ID */
546c1f02189SAndrew Rybchenko *erplp = rhead_default_rx_prefix_layout;
547c1f02189SAndrew Rybchenko goto done;
548c1f02189SAndrew Rybchenko }
549c1f02189SAndrew Rybchenko if (rc != 0)
550c1f02189SAndrew Rybchenko goto fail2;
551c1f02189SAndrew Rybchenko
552c1f02189SAndrew Rybchenko if (num == 0) {
553c1f02189SAndrew Rybchenko rc = ENOTSUP;
554c1f02189SAndrew Rybchenko goto fail3;
555c1f02189SAndrew Rybchenko }
556c1f02189SAndrew Rybchenko
557c1f02189SAndrew Rybchenko for (i = 0; i < num; ++i) {
558c1f02189SAndrew Rybchenko rc = efx_mcdi_query_rx_prefix_id(enp, prefix_ids[i], &erpl);
559c1f02189SAndrew Rybchenko if (rc != 0)
560c1f02189SAndrew Rybchenko goto fail4;
561c1f02189SAndrew Rybchenko
562c1f02189SAndrew Rybchenko /* Choose the smallest prefix which meets our requirements */
563c1f02189SAndrew Rybchenko if (i == 0 || erpl.erpl_length < erplp->erpl_length)
564c1f02189SAndrew Rybchenko *erplp = erpl;
565c1f02189SAndrew Rybchenko }
566c1f02189SAndrew Rybchenko
567c1f02189SAndrew Rybchenko done:
568c1f02189SAndrew Rybchenko return (0);
569c1f02189SAndrew Rybchenko
570c1f02189SAndrew Rybchenko fail4:
571c1f02189SAndrew Rybchenko EFSYS_PROBE(fail4);
572c1f02189SAndrew Rybchenko fail3:
573c1f02189SAndrew Rybchenko EFSYS_PROBE(fail3);
574c1f02189SAndrew Rybchenko fail2:
575c1f02189SAndrew Rybchenko EFSYS_PROBE(fail2);
576c1f02189SAndrew Rybchenko fail1:
577c1f02189SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
578c1f02189SAndrew Rybchenko
579c1f02189SAndrew Rybchenko return (rc);
580c1f02189SAndrew Rybchenko }
581c1f02189SAndrew Rybchenko
582b6b29352SAndrew Rybchenko __checkReturn efx_rc_t
rhead_rx_qcreate(__in efx_nic_t * enp,__in unsigned int index,__in unsigned int label,__in efx_rxq_type_t type,__in const efx_rxq_type_data_t * type_data,__in efsys_mem_t * esmp,__in size_t ndescs,__in uint32_t id,__in unsigned int flags,__in efx_evq_t * eep,__in efx_rxq_t * erp)583b6b29352SAndrew Rybchenko rhead_rx_qcreate(
584b6b29352SAndrew Rybchenko __in efx_nic_t *enp,
585b6b29352SAndrew Rybchenko __in unsigned int index,
586b6b29352SAndrew Rybchenko __in unsigned int label,
587b6b29352SAndrew Rybchenko __in efx_rxq_type_t type,
588b6b29352SAndrew Rybchenko __in const efx_rxq_type_data_t *type_data,
589b6b29352SAndrew Rybchenko __in efsys_mem_t *esmp,
590b6b29352SAndrew Rybchenko __in size_t ndescs,
591b6b29352SAndrew Rybchenko __in uint32_t id,
592b6b29352SAndrew Rybchenko __in unsigned int flags,
593b6b29352SAndrew Rybchenko __in efx_evq_t *eep,
594b6b29352SAndrew Rybchenko __in efx_rxq_t *erp)
595b6b29352SAndrew Rybchenko {
596b6b29352SAndrew Rybchenko const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
5977640543fSAndrew Rybchenko efx_mcdi_init_rxq_params_t params;
598c1f02189SAndrew Rybchenko efx_rx_prefix_layout_t erpl;
599f21c6e7fSAndrew Rybchenko uint32_t fields_mask = 0;
600b6b29352SAndrew Rybchenko efx_rc_t rc;
601b6b29352SAndrew Rybchenko
602b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(id))
603b6b29352SAndrew Rybchenko
604b6b29352SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS <=
605b6b29352SAndrew Rybchenko (1 << ESF_GZ_EV_RXPKTS_Q_LABEL_WIDTH));
606b6b29352SAndrew Rybchenko EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
607b6b29352SAndrew Rybchenko
6087640543fSAndrew Rybchenko memset(¶ms, 0, sizeof (params));
6097640543fSAndrew Rybchenko
610b6b29352SAndrew Rybchenko switch (type) {
611b6b29352SAndrew Rybchenko case EFX_RXQ_TYPE_DEFAULT:
612b6b29352SAndrew Rybchenko if (type_data == NULL) {
613b6b29352SAndrew Rybchenko rc = EINVAL;
614b6b29352SAndrew Rybchenko goto fail1;
615b6b29352SAndrew Rybchenko }
6167640543fSAndrew Rybchenko params.buf_size = type_data->ertd_default.ed_buf_size;
617b6b29352SAndrew Rybchenko break;
618b6b29352SAndrew Rybchenko default:
619b6b29352SAndrew Rybchenko rc = ENOTSUP;
620b6b29352SAndrew Rybchenko goto fail2;
621b6b29352SAndrew Rybchenko }
622b6b29352SAndrew Rybchenko
623b6b29352SAndrew Rybchenko /* Scatter can only be disabled if the firmware supports doing so */
624b6b29352SAndrew Rybchenko if (flags & EFX_RXQ_FLAG_SCATTER)
6257640543fSAndrew Rybchenko params.disable_scatter = B_FALSE;
626b6b29352SAndrew Rybchenko else
6277640543fSAndrew Rybchenko params.disable_scatter = encp->enc_rx_disable_scatter_supported;
628b6b29352SAndrew Rybchenko
629f784cdc5SAndrew Rybchenko if (flags & EFX_RXQ_FLAG_RSS_HASH) {
630f784cdc5SAndrew Rybchenko fields_mask |= 1U << EFX_RX_PREFIX_FIELD_RSS_HASH;
631f784cdc5SAndrew Rybchenko fields_mask |= 1U << EFX_RX_PREFIX_FIELD_RSS_HASH_VALID;
632f784cdc5SAndrew Rybchenko }
633f784cdc5SAndrew Rybchenko
634aa3e21f0SIgor Romanov if (flags & EFX_RXQ_FLAG_INGRESS_MPORT)
635aa3e21f0SIgor Romanov fields_mask |= 1U << EFX_RX_PREFIX_FIELD_INGRESS_MPORT;
636aa3e21f0SIgor Romanov
637c414c567SIgor Romanov if (flags & EFX_RXQ_FLAG_USER_MARK)
638c414c567SIgor Romanov fields_mask |= 1U << EFX_RX_PREFIX_FIELD_USER_MARK;
639c414c567SIgor Romanov
640cdea571bSIvan Malov if (flags & EFX_RXQ_FLAG_USER_FLAG)
641cdea571bSIvan Malov fields_mask |= 1U << EFX_RX_PREFIX_FIELD_USER_FLAG;
642cdea571bSIvan Malov
643*e5e5c127SArtemii Morozov if (flags & EFX_RXQ_FLAG_VLAN_STRIPPED_TCI)
644*e5e5c127SArtemii Morozov fields_mask |= 1U << EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI;
645*e5e5c127SArtemii Morozov
646b6b29352SAndrew Rybchenko /*
647c1f02189SAndrew Rybchenko * LENGTH is required in EF100 host interface, as receive events
648c1f02189SAndrew Rybchenko * do not include the packet length.
649c1f02189SAndrew Rybchenko */
650f21c6e7fSAndrew Rybchenko fields_mask |= 1U << EFX_RX_PREFIX_FIELD_LENGTH;
651f21c6e7fSAndrew Rybchenko if ((rc = rhead_rx_choose_prefix_id(enp, fields_mask, &erpl)) != 0)
652c1f02189SAndrew Rybchenko goto fail3;
653c1f02189SAndrew Rybchenko
654c1f02189SAndrew Rybchenko params.prefix_id = erpl.erpl_id;
655c1f02189SAndrew Rybchenko
656c1f02189SAndrew Rybchenko /*
657b6b29352SAndrew Rybchenko * Ignore EFX_RXQ_FLAG_INNER_CLASSES since in accordance with
658b6b29352SAndrew Rybchenko * EF100 host interface both inner and outer classes are provided
659b6b29352SAndrew Rybchenko * by HW if applicable.
660b6b29352SAndrew Rybchenko */
661b6b29352SAndrew Rybchenko
662b6b29352SAndrew Rybchenko if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep, label, index,
6637640543fSAndrew Rybchenko esmp, ¶ms)) != 0)
664c1f02189SAndrew Rybchenko goto fail4;
665b6b29352SAndrew Rybchenko
666b6b29352SAndrew Rybchenko erp->er_eep = eep;
667b6b29352SAndrew Rybchenko erp->er_label = label;
6687640543fSAndrew Rybchenko erp->er_buf_size = params.buf_size;
669c1f02189SAndrew Rybchenko erp->er_prefix_layout = erpl;
670b6b29352SAndrew Rybchenko
671b6b29352SAndrew Rybchenko return (0);
672b6b29352SAndrew Rybchenko
673c1f02189SAndrew Rybchenko fail4:
674c1f02189SAndrew Rybchenko EFSYS_PROBE(fail4);
675b6b29352SAndrew Rybchenko fail3:
676b6b29352SAndrew Rybchenko EFSYS_PROBE(fail3);
677b6b29352SAndrew Rybchenko fail2:
678b6b29352SAndrew Rybchenko EFSYS_PROBE(fail2);
679b6b29352SAndrew Rybchenko fail1:
680b6b29352SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
681b6b29352SAndrew Rybchenko
682b6b29352SAndrew Rybchenko return (rc);
683b6b29352SAndrew Rybchenko }
684b6b29352SAndrew Rybchenko
685b6b29352SAndrew Rybchenko void
rhead_rx_qdestroy(__in efx_rxq_t * erp)686b6b29352SAndrew Rybchenko rhead_rx_qdestroy(
687b6b29352SAndrew Rybchenko __in efx_rxq_t *erp)
688b6b29352SAndrew Rybchenko {
689b6b29352SAndrew Rybchenko _NOTE(ARGUNUSED(erp))
690b6b29352SAndrew Rybchenko /* Nothing to do here */
691b6b29352SAndrew Rybchenko }
692b6b29352SAndrew Rybchenko
693b6b29352SAndrew Rybchenko #endif /* EFSYS_OPT_RIVERHEAD */
694