1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2018-2019 Solarflare Communications Inc.
12 #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
14 __checkReturn efx_rc_t
18 EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
27 EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
30 static __checkReturn efx_rc_t
31 efx_mcdi_vswitch_alloc(
33 __in efx_vport_id_t vport_id,
34 __in efx_vswitch_type_t vswitch_type)
36 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_ALLOC_IN_LEN,
37 MC_CMD_VSWITCH_ALLOC_OUT_LEN);
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);
50 /* First try with maximum number of VLAN tags FW supports */
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;
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);
65 efx_mcdi_execute(enp, &req);
67 if (req.emr_rc != 0) {
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.
74 if (req.emr_err_code == MC_CMD_ERR_VLAN_LIMIT) {
75 /* Too many VLAN tags, retry with fewer */
76 EFSYS_PROBE(vlan_limit);
80 * Zero the buffer before reusing it
83 memset(payload, 0, sizeof (payload));
93 EFSYS_PROBE1(fail1, efx_rc_t, rc);
97 static __checkReturn efx_rc_t
98 efx_mcdi_vswitch_free(
101 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_FREE_IN_LEN,
102 MC_CMD_VSWITCH_FREE_OUT_LEN);
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;
112 MCDI_IN_SET_DWORD(req, VSWITCH_FREE_IN_UPSTREAM_PORT_ID,
113 EVB_PORT_ID_ASSIGNED);
114 efx_mcdi_execute(enp, &req);
116 if (req.emr_rc != 0) {
124 EFSYS_PROBE1(fail1, efx_rc_t, rc);
128 static __checkReturn efx_rc_t
129 efx_mcdi_vport_alloc(
131 __in efx_vport_type_t vport_type,
133 __in boolean_t vlan_restrict,
134 __out efx_vport_id_t *vport_idp)
136 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ALLOC_IN_LEN,
137 MC_CMD_VPORT_ALLOC_OUT_LEN);
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);
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;
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));
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);
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);
169 efx_mcdi_execute(enp, &req);
171 if (req.emr_rc != 0) {
176 if (req.emr_out_length_used < MC_CMD_VPORT_ALLOC_OUT_LEN) {
181 *vport_idp = *MCDI_OUT2(req, uint32_t, VPORT_ALLOC_OUT_VPORT_ID);
187 EFSYS_PROBE1(fail1, efx_rc_t, rc);
191 static __checkReturn efx_rc_t
194 __in efx_vport_id_t vport_id)
196 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_FREE_IN_LEN,
197 MC_CMD_VPORT_FREE_OUT_LEN);
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;
207 MCDI_IN_SET_DWORD(req, VPORT_FREE_IN_VPORT_ID, vport_id);
208 efx_mcdi_execute(enp, &req);
210 if (req.emr_rc != 0) {
218 EFSYS_PROBE1(fail1, efx_rc_t, rc);
222 static __checkReturn efx_rc_t
223 efx_mcdi_vport_mac_addr_add(
225 __in efx_vport_id_t vport_id,
226 __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
228 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN,
229 MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN);
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;
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);
243 efx_mcdi_execute(enp, &req);
245 if (req.emr_rc != 0) {
253 EFSYS_PROBE1(fail1, efx_rc_t, rc);
257 static __checkReturn efx_rc_t
258 efx_mcdi_vport_mac_addr_del(
260 __in efx_vport_id_t vport_id,
261 __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
263 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN,
264 MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN);
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;
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);
278 efx_mcdi_execute(enp, &req);
280 if (req.emr_rc != 0) {
288 EFSYS_PROBE1(fail1, efx_rc_t, rc);
292 static __checkReturn efx_rc_t
293 efx_mcdi_port_assign(
295 __in efx_vport_id_t vport_id,
296 __in uint32_t vf_index)
298 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_EVB_PORT_ASSIGN_IN_LEN,
299 MC_CMD_EVB_PORT_ASSIGN_OUT_LEN);
301 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
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;
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);
315 efx_mcdi_execute(enp, &req);
317 if (req.emr_rc != 0) {
325 EFSYS_PROBE1(fail1, efx_rc_t, rc);
329 static __checkReturn efx_rc_t
330 efx_mcdi_vport_reconfigure(
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)
337 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_RECONFIGURE_IN_LEN,
338 MC_CMD_VPORT_RECONFIGURE_OUT_LEN);
341 uint32_t reset_flag = 0;
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;
349 MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_VPORT_ID, vport_id);
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);
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);
371 efx_mcdi_execute(enp, &req);
372 if (req.emr_rc != 0) {
377 if (req.emr_out_length_used < MC_CMD_VPORT_RECONFIGURE_OUT_LEN) {
382 reset_flag = MCDI_OUT_DWORD_FIELD(req, VPORT_RECONFIGURE_OUT_FLAGS,
383 VPORT_RECONFIGURE_OUT_RESET_DONE);
385 if (fn_resetp != NULL)
386 *fn_resetp = (reset_flag != 0);
393 EFSYS_PROBE1(fail1, efx_rc_t, rc);
397 __checkReturn efx_rc_t
398 ef10_evb_vswitch_alloc(
400 __out efx_vswitch_id_t *vswitch_idp)
403 if (vswitch_idp == NULL) {
408 if ((rc = efx_mcdi_vswitch_alloc(enp, EVB_PORT_ID_ASSIGNED,
409 EFX_VSWITCH_TYPE_VEB)) != 0) {
413 *vswitch_idp = EFX_DEFAULT_VSWITCH_ID;
419 EFSYS_PROBE1(fail1, efx_rc_t, rc);
423 __checkReturn efx_rc_t
424 ef10_evb_vswitch_free(
426 __in efx_vswitch_id_t vswitch_id)
428 _NOTE(ARGUNUSED(vswitch_id))
430 return (efx_mcdi_vswitch_free(enp));
433 __checkReturn efx_rc_t
434 ef10_evb_vport_alloc(
436 __in efx_vswitch_id_t vswitch_id,
437 __in efx_vport_type_t vport_type,
439 __in boolean_t vlan_restrict,
440 __out efx_vport_id_t *vport_idp)
442 _NOTE(ARGUNUSED(vswitch_id))
444 return (efx_mcdi_vport_alloc(enp,
446 vlan_restrict, vport_idp));
449 __checkReturn efx_rc_t
452 __in efx_vswitch_id_t vswitch_id,
453 __in efx_vport_id_t vport_id)
455 _NOTE(ARGUNUSED(vswitch_id))
457 return (efx_mcdi_vport_free(enp, vport_id));
460 __checkReturn efx_rc_t
461 ef10_evb_vport_mac_addr_add(
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)
467 _NOTE(ARGUNUSED(vswitch_id))
468 EFSYS_ASSERT(addrp != NULL);
470 return (efx_mcdi_vport_mac_addr_add(enp, vport_id, addrp));
473 __checkReturn efx_rc_t
474 ef10_evb_vport_mac_addr_del(
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)
480 _NOTE(ARGUNUSED(vswitch_id))
481 EFSYS_ASSERT(addrp != NULL);
483 return (efx_mcdi_vport_mac_addr_del(enp, vport_id, addrp));
486 __checkReturn efx_rc_t
487 ef10_evb_vadaptor_alloc(
489 __in efx_vswitch_id_t vswitch_id,
490 __in efx_vport_id_t vport_id)
492 _NOTE(ARGUNUSED(vswitch_id))
494 return (efx_mcdi_vadaptor_alloc(enp, vport_id));
497 __checkReturn efx_rc_t
498 ef10_evb_vadaptor_free(
500 __in efx_vswitch_id_t vswitch_id,
501 __in efx_vport_id_t vport_id)
503 _NOTE(ARGUNUSED(vswitch_id))
505 return (efx_mcdi_vadaptor_free(enp, vport_id));
508 __checkReturn efx_rc_t
509 ef10_evb_vport_assign(
511 __in efx_vswitch_id_t vswitch_id,
512 __in efx_vport_id_t vport_id,
513 __in uint32_t vf_index)
515 _NOTE(ARGUNUSED(vswitch_id))
517 return (efx_mcdi_port_assign(enp, vport_id, vf_index));
520 __checkReturn efx_rc_t
521 ef10_evb_vport_reconfigure(
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)
529 _NOTE(ARGUNUSED(vswitch_id))
531 return (efx_mcdi_vport_reconfigure(enp, vport_id, vidp,
535 __checkReturn efx_rc_t
536 ef10_evb_vport_stats(
538 __in efx_vswitch_id_t vswitch_id,
539 __in efx_vport_id_t vport_id,
540 __in efsys_mem_t *esmp)
542 _NOTE(ARGUNUSED(vswitch_id))
544 return (efx_mcdi_mac_stats(enp, vport_id, esmp,
545 EFX_STATS_UPLOAD, 0));
548 #endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
549 #endif /* EFSYS_OPT_EVB */