common/sfc_efx/base: add API to get Rx prefix information
[dpdk.git] / drivers / common / sfc_efx / base / rhead_rx.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2018-2019 Solarflare Communications Inc.
5  */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9
10
11 #if EFSYS_OPT_RIVERHEAD
12
13 /*
14  * Default Rx prefix layout on Riverhead if FW does not support Rx
15  * prefix choice using MC_CMD_GET_RX_PREFIX_ID and query its layout
16  * using MC_CMD_QUERY_RX_PREFIX_ID.
17  *
18  * See SF-119689-TC Riverhead Host Interface section 6.4.
19  */
20 static const efx_rx_prefix_layout_t rhead_default_rx_prefix_layout = {
21         .erpl_id        = 0,
22         .erpl_length    = ESE_GZ_RX_PKT_PREFIX_LEN,
23         .erpl_fields    = {
24 #define RHEAD_RX_PREFIX_FIELD(_name, _big_endian) \
25         EFX_RX_PREFIX_FIELD(_name, ESF_GZ_RX_PREFIX_ ## _name, _big_endian)
26
27                 RHEAD_RX_PREFIX_FIELD(LENGTH, B_FALSE),
28                 RHEAD_RX_PREFIX_FIELD(RSS_HASH_VALID, B_FALSE),
29                 RHEAD_RX_PREFIX_FIELD(USER_FLAG, B_FALSE),
30                 RHEAD_RX_PREFIX_FIELD(CLASS, B_FALSE),
31                 RHEAD_RX_PREFIX_FIELD(PARTIAL_TSTAMP, B_FALSE),
32                 RHEAD_RX_PREFIX_FIELD(RSS_HASH, B_FALSE),
33                 RHEAD_RX_PREFIX_FIELD(USER_MARK, B_FALSE),
34                 RHEAD_RX_PREFIX_FIELD(INGRESS_VPORT, B_FALSE),
35                 RHEAD_RX_PREFIX_FIELD(CSUM_FRAME, B_TRUE),
36                 RHEAD_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_TRUE),
37
38 #undef  RHEAD_RX_PREFIX_FIELD
39         }
40 };
41
42         __checkReturn   efx_rc_t
43 rhead_rx_init(
44         __in            efx_nic_t *enp)
45 {
46         efx_rc_t rc;
47
48         rc = ef10_rx_init(enp);
49         if (rc != 0)
50                 goto fail1;
51
52         return (0);
53
54 fail1:
55         EFSYS_PROBE1(fail1, efx_rc_t, rc);
56         return (rc);
57 }
58
59                 void
60 rhead_rx_fini(
61         __in    efx_nic_t *enp)
62 {
63         ef10_rx_fini(enp);
64 }
65
66 #if EFSYS_OPT_RX_SCATTER
67         __checkReturn   efx_rc_t
68 rhead_rx_scatter_enable(
69         __in            efx_nic_t *enp,
70         __in            unsigned int buf_size)
71 {
72         _NOTE(ARGUNUSED(enp, buf_size))
73         /* Nothing to do here */
74         return (0);
75 }
76 #endif  /* EFSYS_OPT_RX_SCATTER */
77
78 #if EFSYS_OPT_RX_SCALE
79
80         __checkReturn   efx_rc_t
81 rhead_rx_scale_context_alloc(
82         __in            efx_nic_t *enp,
83         __in            efx_rx_scale_context_type_t type,
84         __in            uint32_t num_queues,
85         __out           uint32_t *rss_contextp)
86 {
87         efx_rc_t rc;
88
89         rc = ef10_rx_scale_context_alloc(enp, type, num_queues, rss_contextp);
90         if (rc != 0)
91                 goto fail1;
92
93         return (0);
94
95 fail1:
96         EFSYS_PROBE1(fail1, efx_rc_t, rc);
97         return (rc);
98 }
99
100         __checkReturn   efx_rc_t
101 rhead_rx_scale_context_free(
102         __in            efx_nic_t *enp,
103         __in            uint32_t rss_context)
104 {
105         efx_rc_t rc;
106
107         rc = ef10_rx_scale_context_free(enp, rss_context);
108         if (rc != 0)
109                 goto fail1;
110
111         return (0);
112
113 fail1:
114         EFSYS_PROBE1(fail1, efx_rc_t, rc);
115         return (rc);
116 }
117
118         __checkReturn   efx_rc_t
119 rhead_rx_scale_mode_set(
120         __in            efx_nic_t *enp,
121         __in            uint32_t rss_context,
122         __in            efx_rx_hash_alg_t alg,
123         __in            efx_rx_hash_type_t type,
124         __in            boolean_t insert)
125 {
126         efx_rc_t rc;
127
128         rc = ef10_rx_scale_mode_set(enp, rss_context, alg, type, insert);
129         if (rc != 0)
130                 goto fail1;
131
132         return (0);
133
134 fail1:
135         EFSYS_PROBE1(fail1, efx_rc_t, rc);
136         return (rc);
137 }
138
139         __checkReturn   efx_rc_t
140 rhead_rx_scale_key_set(
141         __in            efx_nic_t *enp,
142         __in            uint32_t rss_context,
143         __in_ecount(n)  uint8_t *key,
144         __in            size_t n)
145 {
146         efx_rc_t rc;
147
148         rc = ef10_rx_scale_key_set(enp, rss_context, key, n);
149         if (rc != 0)
150                 goto fail1;
151
152         return (0);
153
154 fail1:
155         EFSYS_PROBE1(fail1, efx_rc_t, rc);
156         return (rc);
157 }
158
159         __checkReturn   efx_rc_t
160 rhead_rx_scale_tbl_set(
161         __in            efx_nic_t *enp,
162         __in            uint32_t rss_context,
163         __in_ecount(n)  unsigned int *table,
164         __in            size_t n)
165 {
166         efx_rc_t rc;
167
168         rc = ef10_rx_scale_tbl_set(enp, rss_context, table, n);
169         if (rc != 0)
170                 goto fail1;
171
172         return (0);
173
174 fail1:
175         EFSYS_PROBE1(fail1, efx_rc_t, rc);
176         return (rc);
177 }
178
179         __checkReturn   uint32_t
180 rhead_rx_prefix_hash(
181         __in            efx_nic_t *enp,
182         __in            efx_rx_hash_alg_t func,
183         __in            uint8_t *buffer)
184 {
185         _NOTE(ARGUNUSED(enp, func, buffer))
186
187         /* FIXME implement the method for Riverhead */
188
189         return (ENOTSUP);
190 }
191
192 #endif /* EFSYS_OPT_RX_SCALE */
193
194         __checkReturn   efx_rc_t
195 rhead_rx_prefix_pktlen(
196         __in            efx_nic_t *enp,
197         __in            uint8_t *buffer,
198         __out           uint16_t *lengthp)
199 {
200         _NOTE(ARGUNUSED(enp, buffer, lengthp))
201
202         /* FIXME implement the method for Riverhead */
203
204         return (ENOTSUP);
205 }
206
207                                 void
208 rhead_rx_qpost(
209         __in                    efx_rxq_t *erp,
210         __in_ecount(ndescs)     efsys_dma_addr_t *addrp,
211         __in                    size_t size,
212         __in                    unsigned int ndescs,
213         __in                    unsigned int completed,
214         __in                    unsigned int added)
215 {
216         _NOTE(ARGUNUSED(erp, addrp, size, ndescs, completed, added))
217
218         /* FIXME implement the method for Riverhead */
219
220         EFSYS_ASSERT(B_FALSE);
221 }
222
223                         void
224 rhead_rx_qpush(
225         __in    efx_rxq_t *erp,
226         __in    unsigned int added,
227         __inout unsigned int *pushedp)
228 {
229         _NOTE(ARGUNUSED(erp, added, pushedp))
230
231         /* FIXME implement the method for Riverhead */
232
233         EFSYS_ASSERT(B_FALSE);
234 }
235
236         __checkReturn   efx_rc_t
237 rhead_rx_qflush(
238         __in    efx_rxq_t *erp)
239 {
240         efx_nic_t *enp = erp->er_enp;
241         efx_rc_t rc;
242
243         if ((rc = efx_mcdi_fini_rxq(enp, erp->er_index)) != 0)
244                 goto fail1;
245
246         return (0);
247
248 fail1:
249         /*
250          * EALREADY is not an error, but indicates that the MC has rebooted and
251          * that the RXQ has already been destroyed. Callers need to know that
252          * the RXQ flush has completed to avoid waiting until timeout for a
253          * flush done event that will not be delivered.
254          */
255         if (rc != EALREADY)
256                 EFSYS_PROBE1(fail1, efx_rc_t, rc);
257
258         return (rc);
259 }
260
261                 void
262 rhead_rx_qenable(
263         __in    efx_rxq_t *erp)
264 {
265         _NOTE(ARGUNUSED(erp))
266 }
267
268         __checkReturn   efx_rc_t
269 rhead_rx_qcreate(
270         __in            efx_nic_t *enp,
271         __in            unsigned int index,
272         __in            unsigned int label,
273         __in            efx_rxq_type_t type,
274         __in            const efx_rxq_type_data_t *type_data,
275         __in            efsys_mem_t *esmp,
276         __in            size_t ndescs,
277         __in            uint32_t id,
278         __in            unsigned int flags,
279         __in            efx_evq_t *eep,
280         __in            efx_rxq_t *erp)
281 {
282         const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
283         efx_rc_t rc;
284         boolean_t disable_scatter;
285
286         _NOTE(ARGUNUSED(id))
287
288         EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS <=
289             (1 << ESF_GZ_EV_RXPKTS_Q_LABEL_WIDTH));
290         EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
291
292         switch (type) {
293         case EFX_RXQ_TYPE_DEFAULT:
294                 if (type_data == NULL) {
295                         rc = EINVAL;
296                         goto fail1;
297                 }
298                 erp->er_buf_size = type_data->ertd_default.ed_buf_size;
299                 break;
300         default:
301                 rc = ENOTSUP;
302                 goto fail2;
303         }
304
305         /* Scatter can only be disabled if the firmware supports doing so */
306         if (flags & EFX_RXQ_FLAG_SCATTER)
307                 disable_scatter = B_FALSE;
308         else
309                 disable_scatter = encp->enc_rx_disable_scatter_supported;
310
311         /*
312          * Ignore EFX_RXQ_FLAG_INNER_CLASSES since in accordance with
313          * EF100 host interface both inner and outer classes are provided
314          * by HW if applicable.
315          */
316
317         if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep, label, index,
318                     esmp, disable_scatter, B_FALSE, erp->er_buf_size,
319                     0, 0, 0, 0, 0)) != 0)
320                 goto fail3;
321
322         erp->er_eep = eep;
323         erp->er_label = label;
324         erp->er_prefix_layout = rhead_default_rx_prefix_layout;
325
326         return (0);
327
328 fail3:
329         EFSYS_PROBE(fail3);
330 fail2:
331         EFSYS_PROBE(fail2);
332 fail1:
333         EFSYS_PROBE1(fail1, efx_rc_t, rc);
334
335         return (rc);
336 }
337
338                 void
339 rhead_rx_qdestroy(
340         __in    efx_rxq_t *erp)
341 {
342         _NOTE(ARGUNUSED(erp))
343         /* Nothing to do here */
344 }
345
346 #endif /* EFSYS_OPT_RIVERHEAD */