net/mlx5: remove redundant flag in device config
[dpdk.git] / drivers / common / sfc_efx / base / ef10_evb.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2021 Xilinx, Inc.
4  * Copyright(c) 2018-2019 Solarflare Communications Inc.
5  */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9
10 #if EFSYS_OPT_EVB
11
12 #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
13
14         __checkReturn   efx_rc_t
15 ef10_evb_init(
16         __in            efx_nic_t *enp)
17 {
18         EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
19
20         return (0);
21 }
22
23         void
24 ef10_evb_fini(
25         __in            efx_nic_t *enp)
26 {
27         EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
28 }
29
30 static  __checkReturn   efx_rc_t
31 efx_mcdi_vswitch_alloc(
32         __in            efx_nic_t *enp,
33         __in            efx_vport_id_t vport_id,
34         __in            efx_vswitch_type_t vswitch_type)
35 {
36         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_ALLOC_IN_LEN,
37                 MC_CMD_VSWITCH_ALLOC_OUT_LEN);
38         efx_mcdi_req_t req;
39         efx_rc_t rc;
40         uint8_t ntags;
41
42         /* Ensure EFX and MCDI use same values for vswitch types */
43         EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VLAN ==
44                 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN);
45         EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VEB ==
46                 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB);
47         EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_MUX ==
48                 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX);
49
50         /* First try with maximum number of VLAN tags FW supports */
51         ntags = 2;
52 retry:
53         req.emr_cmd = MC_CMD_VSWITCH_ALLOC;
54         req.emr_in_buf = payload;
55         req.emr_in_length = MC_CMD_VSWITCH_ALLOC_IN_LEN;
56         req.emr_out_buf = payload;
57         req.emr_out_length = MC_CMD_VSWITCH_ALLOC_OUT_LEN;
58
59         MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID, vport_id);
60         MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_TYPE, vswitch_type);
61         MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS, ntags);
62         MCDI_IN_POPULATE_DWORD_1(req, VSWITCH_ALLOC_IN_FLAGS,
63                 VSWITCH_ALLOC_IN_FLAG_AUTO_PORT, 0);
64
65         efx_mcdi_execute(enp, &req);
66
67         if (req.emr_rc != 0) {
68                 rc = req.emr_rc;
69                 /*
70                  * efx_rc_t error codes in libefx are translated from MCDI
71                  * error codes in efx_mcdi_request_errcode. As this conversion
72                  * is not a 1:1, here we check the specific MCDI error code.
73                  */
74                 if (req.emr_err_code == MC_CMD_ERR_VLAN_LIMIT) {
75                         /* Too many VLAN tags, retry with fewer */
76                         EFSYS_PROBE(vlan_limit);
77                         ntags--;
78                         if (ntags > 0) {
79                                 /*
80                                  * Zero the buffer before reusing it
81                                  * for another request
82                                  */
83                                 memset(payload, 0, sizeof (payload));
84                                 goto retry;
85                         }
86                         goto fail1;
87                 }
88         }
89
90         return (0);
91
92 fail1:
93         EFSYS_PROBE1(fail1, efx_rc_t, rc);
94         return (rc);
95 }
96
97 static  __checkReturn   efx_rc_t
98 efx_mcdi_vswitch_free(
99         __in            efx_nic_t *enp)
100 {
101         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_FREE_IN_LEN,
102                 MC_CMD_VSWITCH_FREE_OUT_LEN);
103         efx_mcdi_req_t req;
104         efx_rc_t rc;
105
106         req.emr_cmd = MC_CMD_VSWITCH_FREE;
107         req.emr_in_buf = payload;
108         req.emr_in_length = MC_CMD_VSWITCH_FREE_IN_LEN;
109         req.emr_out_buf = payload;
110         req.emr_out_length = MC_CMD_VSWITCH_FREE_OUT_LEN;
111
112         MCDI_IN_SET_DWORD(req, VSWITCH_FREE_IN_UPSTREAM_PORT_ID,
113                 EVB_PORT_ID_ASSIGNED);
114         efx_mcdi_execute(enp, &req);
115
116         if (req.emr_rc != 0) {
117                 rc = req.emr_rc;
118                 goto fail1;
119         }
120
121         return (0);
122
123 fail1:
124         EFSYS_PROBE1(fail1, efx_rc_t, rc);
125         return (rc);
126 }
127
128 static  __checkReturn   efx_rc_t
129 efx_mcdi_vport_alloc(
130         __in            efx_nic_t *enp,
131         __in            efx_vport_type_t vport_type,
132         __in            uint16_t vid,
133         __in            boolean_t vlan_restrict,
134         __out           efx_vport_id_t *vport_idp)
135 {
136         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ALLOC_IN_LEN,
137                 MC_CMD_VPORT_ALLOC_OUT_LEN);
138         efx_mcdi_req_t req;
139         efx_rc_t rc;
140
141         /* Ensure EFX and MCDI use same values for vport types */
142         EFX_STATIC_ASSERT(EFX_VPORT_TYPE_NORMAL ==
143                 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL);
144         EFX_STATIC_ASSERT(EFX_VPORT_TYPE_EXPANSION ==
145                 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION);
146         EFX_STATIC_ASSERT(EFX_VPORT_TYPE_TEST ==
147                 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST);
148
149         req.emr_cmd = MC_CMD_VPORT_ALLOC;
150         req.emr_in_buf = payload;
151         req.emr_in_length = MC_CMD_VPORT_ALLOC_IN_LEN;
152         req.emr_out_buf = payload;
153         req.emr_out_length = MC_CMD_VPORT_ALLOC_OUT_LEN;
154
155         MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_UPSTREAM_PORT_ID,
156                 EVB_PORT_ID_ASSIGNED);
157         MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_TYPE, vport_type);
158         MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_NUM_VLAN_TAGS,
159                 (vid != EFX_FILTER_VID_UNSPEC));
160
161         MCDI_IN_POPULATE_DWORD_2(req, VPORT_ALLOC_IN_FLAGS,
162                 VPORT_ALLOC_IN_FLAG_AUTO_PORT, 0,
163                 VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT, vlan_restrict);
164
165         if (vid != EFX_FILTER_VID_UNSPEC)
166                 MCDI_IN_POPULATE_DWORD_1(req, VPORT_ALLOC_IN_VLAN_TAGS,
167                         VPORT_ALLOC_IN_VLAN_TAG_0, vid);
168
169         efx_mcdi_execute(enp, &req);
170
171         if (req.emr_rc != 0) {
172                 rc = req.emr_rc;
173                 goto fail1;
174         }
175
176         if (req.emr_out_length_used < MC_CMD_VPORT_ALLOC_OUT_LEN) {
177                 rc = EMSGSIZE;
178                 goto fail2;
179         }
180
181         *vport_idp = *MCDI_OUT2(req, uint32_t, VPORT_ALLOC_OUT_VPORT_ID);
182         return (0);
183
184 fail2:
185         EFSYS_PROBE(fail2);
186 fail1:
187         EFSYS_PROBE1(fail1, efx_rc_t, rc);
188         return (rc);
189 }
190
191 static  __checkReturn   efx_rc_t
192 efx_mcdi_vport_free(
193         __in            efx_nic_t *enp,
194         __in            efx_vport_id_t vport_id)
195 {
196         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_FREE_IN_LEN,
197                 MC_CMD_VPORT_FREE_OUT_LEN);
198         efx_mcdi_req_t req;
199         efx_rc_t rc;
200
201         req.emr_cmd = MC_CMD_VPORT_FREE;
202         req.emr_in_buf = payload;
203         req.emr_in_length = MC_CMD_VPORT_FREE_IN_LEN;
204         req.emr_out_buf = payload;
205         req.emr_out_length = MC_CMD_VPORT_FREE_OUT_LEN;
206
207         MCDI_IN_SET_DWORD(req, VPORT_FREE_IN_VPORT_ID, vport_id);
208         efx_mcdi_execute(enp, &req);
209
210         if (req.emr_rc != 0) {
211                 rc = req.emr_rc;
212                 goto fail1;
213         }
214
215         return (0);
216
217 fail1:
218         EFSYS_PROBE1(fail1, efx_rc_t, rc);
219         return (rc);
220 }
221
222 static  __checkReturn                   efx_rc_t
223 efx_mcdi_vport_mac_addr_add(
224         __in                            efx_nic_t *enp,
225         __in                            efx_vport_id_t vport_id,
226         __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp)
227 {
228         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN,
229                 MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN);
230         efx_mcdi_req_t req;
231         efx_rc_t rc;
232
233         req.emr_cmd = MC_CMD_VPORT_ADD_MAC_ADDRESS;
234         req.emr_in_buf = payload;
235         req.emr_in_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN;
236         req.emr_out_buf = payload;
237         req.emr_out_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN;
238
239         MCDI_IN_SET_DWORD(req, VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID, vport_id);
240         EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
241                                 VPORT_ADD_MAC_ADDRESS_IN_MACADDR), addrp);
242
243         efx_mcdi_execute(enp, &req);
244
245         if (req.emr_rc != 0) {
246                 rc = req.emr_rc;
247                 goto fail1;
248         }
249
250         return (0);
251
252 fail1:
253         EFSYS_PROBE1(fail1, efx_rc_t, rc);
254         return (rc);
255 }
256
257 static  __checkReturn                   efx_rc_t
258 efx_mcdi_vport_mac_addr_del(
259         __in                            efx_nic_t *enp,
260         __in                            efx_vport_id_t vport_id,
261         __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp)
262 {
263         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN,
264                 MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN);
265         efx_mcdi_req_t req;
266         efx_rc_t rc;
267
268         req.emr_cmd = MC_CMD_VPORT_DEL_MAC_ADDRESS;
269         req.emr_in_buf = payload;
270         req.emr_in_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN;
271         req.emr_out_buf = payload;
272         req.emr_out_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN;
273
274         MCDI_IN_SET_DWORD(req, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, vport_id);
275         EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
276                                 VPORT_DEL_MAC_ADDRESS_IN_MACADDR), addrp);
277
278         efx_mcdi_execute(enp, &req);
279
280         if (req.emr_rc != 0) {
281                 rc = req.emr_rc;
282                 goto fail1;
283         }
284
285         return (0);
286
287 fail1:
288         EFSYS_PROBE1(fail1, efx_rc_t, rc);
289         return (rc);
290 }
291
292 static  __checkReturn   efx_rc_t
293 efx_mcdi_port_assign(
294         __in            efx_nic_t *enp,
295         __in            efx_vport_id_t vport_id,
296         __in            uint32_t vf_index)
297 {
298         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_EVB_PORT_ASSIGN_IN_LEN,
299                 MC_CMD_EVB_PORT_ASSIGN_OUT_LEN);
300         efx_mcdi_req_t req;
301         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
302         efx_rc_t rc;
303
304         req.emr_cmd = MC_CMD_EVB_PORT_ASSIGN;
305         req.emr_in_buf = payload;
306         req.emr_in_length = MC_CMD_EVB_PORT_ASSIGN_IN_LEN;
307         req.emr_out_buf = payload;
308         req.emr_out_length = MC_CMD_EVB_PORT_ASSIGN_OUT_LEN;
309
310         MCDI_IN_SET_DWORD(req, EVB_PORT_ASSIGN_IN_PORT_ID, vport_id);
311         MCDI_IN_POPULATE_DWORD_2(req, EVB_PORT_ASSIGN_IN_FUNCTION,
312                 EVB_PORT_ASSIGN_IN_PF, encp->enc_pf,
313                 EVB_PORT_ASSIGN_IN_VF, vf_index);
314
315         efx_mcdi_execute(enp, &req);
316
317         if (req.emr_rc != 0) {
318                 rc = req.emr_rc;
319                 goto fail1;
320         }
321
322         return (0);
323
324 fail1:
325         EFSYS_PROBE1(fail1, efx_rc_t, rc);
326         return (rc);
327 }
328
329 static  __checkReturn                           efx_rc_t
330 efx_mcdi_vport_reconfigure(
331         __in                                    efx_nic_t *enp,
332         __in                                    efx_vport_id_t vport_id,
333         __in_opt                                uint16_t *vidp,
334         __in_bcount_opt(EFX_MAC_ADDR_LEN)       uint8_t *addrp,
335         __out_opt                               boolean_t *fn_resetp)
336 {
337         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_RECONFIGURE_IN_LEN,
338                 MC_CMD_VPORT_RECONFIGURE_OUT_LEN);
339         efx_mcdi_req_t req;
340         efx_rc_t rc;
341         uint32_t reset_flag = 0;
342
343         req.emr_cmd = MC_CMD_VPORT_RECONFIGURE;
344         req.emr_in_buf = payload;
345         req.emr_in_length = MC_CMD_VPORT_RECONFIGURE_IN_LEN;
346         req.emr_out_buf = payload;
347         req.emr_out_length = MC_CMD_VPORT_RECONFIGURE_OUT_LEN;
348
349         MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_VPORT_ID, vport_id);
350
351         if (vidp != NULL) {
352                 MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
353                         VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS, 1);
354                 if (*vidp != EFX_FILTER_VID_UNSPEC) {
355                         MCDI_IN_SET_DWORD(req,
356                                 VPORT_RECONFIGURE_IN_NUM_VLAN_TAGS, 1);
357                         MCDI_IN_POPULATE_DWORD_1(req,
358                                 VPORT_RECONFIGURE_IN_VLAN_TAGS,
359                                 VPORT_RECONFIGURE_IN_VLAN_TAG_0, *vidp);
360                 }
361         }
362
363         if ((addrp != NULL) && (efx_is_zero_eth_addr(addrp) == B_FALSE)) {
364                 MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
365                          VPORT_RECONFIGURE_IN_REPLACE_MACADDRS, 1);
366                 MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_NUM_MACADDRS, 1);
367                 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
368                                         VPORT_RECONFIGURE_IN_MACADDRS), addrp);
369         }
370
371         efx_mcdi_execute(enp, &req);
372         if (req.emr_rc != 0) {
373                 rc = req.emr_rc;
374                 goto fail1;
375         }
376
377         if (req.emr_out_length_used < MC_CMD_VPORT_RECONFIGURE_OUT_LEN) {
378                 rc = EMSGSIZE;
379                 goto fail2;
380         }
381
382         reset_flag = MCDI_OUT_DWORD_FIELD(req, VPORT_RECONFIGURE_OUT_FLAGS,
383                                             VPORT_RECONFIGURE_OUT_RESET_DONE);
384
385         if (fn_resetp != NULL)
386                 *fn_resetp = (reset_flag != 0);
387
388         return (0);
389
390 fail2:
391         EFSYS_PROBE(fail2);
392 fail1:
393         EFSYS_PROBE1(fail1, efx_rc_t, rc);
394         return (rc);
395 }
396
397         __checkReturn   efx_rc_t
398 ef10_evb_vswitch_alloc(
399         __in            efx_nic_t *enp,
400         __out           efx_vswitch_id_t *vswitch_idp)
401 {
402         efx_rc_t rc;
403         if (vswitch_idp == NULL) {
404                 rc = EINVAL;
405                 goto fail1;
406         }
407
408         if ((rc = efx_mcdi_vswitch_alloc(enp, EVB_PORT_ID_ASSIGNED,
409                         EFX_VSWITCH_TYPE_VEB)) != 0) {
410                 goto fail2;
411         }
412
413         *vswitch_idp = EFX_DEFAULT_VSWITCH_ID;
414         return (0);
415
416 fail2:
417         EFSYS_PROBE(fail2);
418 fail1:
419         EFSYS_PROBE1(fail1, efx_rc_t, rc);
420         return (rc);
421 }
422
423         __checkReturn   efx_rc_t
424 ef10_evb_vswitch_free(
425         __in            efx_nic_t *enp,
426         __in            efx_vswitch_id_t vswitch_id)
427 {
428         _NOTE(ARGUNUSED(vswitch_id))
429
430         return (efx_mcdi_vswitch_free(enp));
431 }
432
433         __checkReturn   efx_rc_t
434 ef10_evb_vport_alloc(
435         __in            efx_nic_t *enp,
436         __in            efx_vswitch_id_t vswitch_id,
437         __in            efx_vport_type_t vport_type,
438         __in            uint16_t vid,
439         __in            boolean_t vlan_restrict,
440         __out           efx_vport_id_t *vport_idp)
441 {
442         _NOTE(ARGUNUSED(vswitch_id))
443
444         return (efx_mcdi_vport_alloc(enp,
445                         vport_type, vid,
446                         vlan_restrict, vport_idp));
447 }
448
449         __checkReturn   efx_rc_t
450 ef10_evb_vport_free(
451         __in            efx_nic_t *enp,
452         __in            efx_vswitch_id_t vswitch_id,
453         __in            efx_vport_id_t vport_id)
454 {
455         _NOTE(ARGUNUSED(vswitch_id))
456
457         return (efx_mcdi_vport_free(enp, vport_id));
458 }
459
460         __checkReturn                   efx_rc_t
461 ef10_evb_vport_mac_addr_add(
462         __in                            efx_nic_t *enp,
463         __in                            efx_vswitch_id_t vswitch_id,
464         __in                            efx_vport_id_t vport_id,
465         __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp)
466 {
467         _NOTE(ARGUNUSED(vswitch_id))
468         EFSYS_ASSERT(addrp != NULL);
469
470         return (efx_mcdi_vport_mac_addr_add(enp, vport_id, addrp));
471 }
472
473         __checkReturn                   efx_rc_t
474 ef10_evb_vport_mac_addr_del(
475         __in                            efx_nic_t *enp,
476         __in                            efx_vswitch_id_t vswitch_id,
477         __in                            efx_vport_id_t vport_id,
478         __in_bcount(EFX_MAC_ADDR_LEN)   uint8_t *addrp)
479 {
480         _NOTE(ARGUNUSED(vswitch_id))
481         EFSYS_ASSERT(addrp != NULL);
482
483         return (efx_mcdi_vport_mac_addr_del(enp, vport_id, addrp));
484 }
485
486         __checkReturn   efx_rc_t
487 ef10_evb_vadaptor_alloc(
488         __in            efx_nic_t *enp,
489         __in            efx_vswitch_id_t vswitch_id,
490         __in            efx_vport_id_t vport_id)
491 {
492         _NOTE(ARGUNUSED(vswitch_id))
493
494         return (efx_mcdi_vadaptor_alloc(enp, vport_id));
495 }
496
497         __checkReturn   efx_rc_t
498 ef10_evb_vadaptor_free(
499         __in            efx_nic_t *enp,
500         __in            efx_vswitch_id_t vswitch_id,
501         __in            efx_vport_id_t vport_id)
502 {
503         _NOTE(ARGUNUSED(vswitch_id))
504
505         return (efx_mcdi_vadaptor_free(enp, vport_id));
506 }
507
508         __checkReturn   efx_rc_t
509 ef10_evb_vport_assign(
510         __in            efx_nic_t *enp,
511         __in            efx_vswitch_id_t vswitch_id,
512         __in            efx_vport_id_t vport_id,
513         __in    uint32_t vf_index)
514 {
515         _NOTE(ARGUNUSED(vswitch_id))
516
517         return (efx_mcdi_port_assign(enp, vport_id, vf_index));
518 }
519
520         __checkReturn                           efx_rc_t
521 ef10_evb_vport_reconfigure(
522         __in                                    efx_nic_t *enp,
523         __in                                    efx_vswitch_id_t vswitch_id,
524         __in                                    efx_vport_id_t vport_id,
525         __in_opt                                uint16_t *vidp,
526         __in_bcount_opt(EFX_MAC_ADDR_LEN)       uint8_t *addrp,
527         __out_opt                               boolean_t *fn_resetp)
528 {
529         _NOTE(ARGUNUSED(vswitch_id))
530
531         return (efx_mcdi_vport_reconfigure(enp, vport_id, vidp,
532                         addrp, fn_resetp));
533 }
534
535         __checkReturn   efx_rc_t
536 ef10_evb_vport_stats(
537         __in            efx_nic_t *enp,
538         __in            efx_vswitch_id_t vswitch_id,
539         __in            efx_vport_id_t vport_id,
540         __in            efsys_mem_t *esmp)
541 {
542         _NOTE(ARGUNUSED(vswitch_id))
543
544         return (efx_mcdi_mac_stats(enp, vport_id, esmp,
545                         EFX_STATS_UPLOAD, 0));
546 }
547
548 #endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
549 #endif /* EFSYS_OPT_EVB */