1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2018-2019 Solarflare Communications Inc.
12 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
14 __checkReturn efx_rc_t
18 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
19 enp->en_family == EFX_FAMILY_MEDFORD ||
20 enp->en_family == EFX_FAMILY_MEDFORD2);
29 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
30 enp->en_family == EFX_FAMILY_MEDFORD ||
31 enp->en_family == EFX_FAMILY_MEDFORD2);
34 __checkReturn efx_rc_t
35 efx_mcdi_vswitch_alloc(
37 __in efx_vport_id_t vport_id,
38 __in efx_vswitch_type_t vswitch_type)
40 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_ALLOC_IN_LEN,
41 MC_CMD_VSWITCH_ALLOC_OUT_LEN);
46 /* Ensure EFX and MCDI use same values for vswitch types */
47 EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VLAN ==
48 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN);
49 EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VEB ==
50 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB);
51 EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_MUX ==
52 MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX);
54 /* First try with maximum number of VLAN tags FW supports */
57 req.emr_cmd = MC_CMD_VSWITCH_ALLOC;
58 req.emr_in_buf = payload;
59 req.emr_in_length = MC_CMD_VSWITCH_ALLOC_IN_LEN;
60 req.emr_out_buf = payload;
61 req.emr_out_length = MC_CMD_VSWITCH_ALLOC_OUT_LEN;
63 MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID, vport_id);
64 MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_TYPE, vswitch_type);
65 MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS, ntags);
66 MCDI_IN_POPULATE_DWORD_1(req, VSWITCH_ALLOC_IN_FLAGS,
67 VSWITCH_ALLOC_IN_FLAG_AUTO_PORT, 0);
69 efx_mcdi_execute(enp, &req);
71 if (req.emr_rc != 0) {
74 * efx_rc_t error codes in libefx are translated from MCDI
75 * error codes in efx_mcdi_request_errcode. As this conversion
76 * is not a 1:1, here we check the specific MCDI error code.
78 if (req.emr_err_code == MC_CMD_ERR_VLAN_LIMIT) {
79 /* Too many VLAN tags, retry with fewer */
80 EFSYS_PROBE(vlan_limit);
84 * Zero the buffer before reusing it
87 memset(payload, 0, sizeof (payload));
97 EFSYS_PROBE1(fail1, efx_rc_t, rc);
101 __checkReturn efx_rc_t
102 efx_mcdi_vswitch_free(
105 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_FREE_IN_LEN,
106 MC_CMD_VSWITCH_FREE_OUT_LEN);
110 req.emr_cmd = MC_CMD_VSWITCH_FREE;
111 req.emr_in_buf = payload;
112 req.emr_in_length = MC_CMD_VSWITCH_FREE_IN_LEN;
113 req.emr_out_buf = payload;
114 req.emr_out_length = MC_CMD_VSWITCH_FREE_OUT_LEN;
116 MCDI_IN_SET_DWORD(req, VSWITCH_FREE_IN_UPSTREAM_PORT_ID,
117 EVB_PORT_ID_ASSIGNED);
118 efx_mcdi_execute(enp, &req);
120 if (req.emr_rc != 0) {
128 EFSYS_PROBE1(fail1, efx_rc_t, rc);
132 __checkReturn efx_rc_t
133 efx_mcdi_vport_alloc(
135 __in efx_vport_type_t vport_type,
137 __in boolean_t vlan_restrict,
138 __out efx_vport_id_t *vport_idp)
140 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ALLOC_IN_LEN,
141 MC_CMD_VPORT_ALLOC_OUT_LEN);
145 /* Ensure EFX and MCDI use same values for vport types */
146 EFX_STATIC_ASSERT(EFX_VPORT_TYPE_NORMAL ==
147 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL);
148 EFX_STATIC_ASSERT(EFX_VPORT_TYPE_EXPANSION ==
149 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION);
150 EFX_STATIC_ASSERT(EFX_VPORT_TYPE_TEST ==
151 MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST);
153 req.emr_cmd = MC_CMD_VPORT_ALLOC;
154 req.emr_in_buf = payload;
155 req.emr_in_length = MC_CMD_VPORT_ALLOC_IN_LEN;
156 req.emr_out_buf = payload;
157 req.emr_out_length = MC_CMD_VPORT_ALLOC_OUT_LEN;
159 MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_UPSTREAM_PORT_ID,
160 EVB_PORT_ID_ASSIGNED);
161 MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_TYPE, vport_type);
162 MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_NUM_VLAN_TAGS,
163 (vid != EFX_FILTER_VID_UNSPEC));
165 MCDI_IN_POPULATE_DWORD_2(req, VPORT_ALLOC_IN_FLAGS,
166 VPORT_ALLOC_IN_FLAG_AUTO_PORT, 0,
167 VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT, vlan_restrict);
169 if (vid != EFX_FILTER_VID_UNSPEC)
170 MCDI_IN_POPULATE_DWORD_1(req, VPORT_ALLOC_IN_VLAN_TAGS,
171 VPORT_ALLOC_IN_VLAN_TAG_0, vid);
173 efx_mcdi_execute(enp, &req);
175 if (req.emr_rc != 0) {
180 if (req.emr_out_length_used < MC_CMD_VPORT_ALLOC_OUT_LEN) {
185 *vport_idp = *MCDI_OUT2(req, uint32_t, VPORT_ALLOC_OUT_VPORT_ID);
191 EFSYS_PROBE1(fail1, efx_rc_t, rc);
195 __checkReturn efx_rc_t
198 __in efx_vport_id_t vport_id)
200 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_FREE_IN_LEN,
201 MC_CMD_VPORT_FREE_OUT_LEN);
205 req.emr_cmd = MC_CMD_VPORT_FREE;
206 req.emr_in_buf = payload;
207 req.emr_in_length = MC_CMD_VPORT_FREE_IN_LEN;
208 req.emr_out_buf = payload;
209 req.emr_out_length = MC_CMD_VPORT_FREE_OUT_LEN;
211 MCDI_IN_SET_DWORD(req, VPORT_FREE_IN_VPORT_ID, vport_id);
212 efx_mcdi_execute(enp, &req);
214 if (req.emr_rc != 0) {
222 EFSYS_PROBE1(fail1, efx_rc_t, rc);
226 __checkReturn efx_rc_t
227 efx_mcdi_vport_mac_addr_add(
229 __in efx_vport_id_t vport_id,
230 __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
232 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN,
233 MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN);
237 req.emr_cmd = MC_CMD_VPORT_ADD_MAC_ADDRESS;
238 req.emr_in_buf = payload;
239 req.emr_in_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN;
240 req.emr_out_buf = payload;
241 req.emr_out_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN;
243 MCDI_IN_SET_DWORD(req, VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID, vport_id);
244 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
245 VPORT_ADD_MAC_ADDRESS_IN_MACADDR), addrp);
247 efx_mcdi_execute(enp, &req);
249 if (req.emr_rc != 0) {
257 EFSYS_PROBE1(fail1, efx_rc_t, rc);
261 __checkReturn efx_rc_t
262 efx_mcdi_vport_mac_addr_del(
264 __in efx_vport_id_t vport_id,
265 __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
267 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN,
268 MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN);
272 req.emr_cmd = MC_CMD_VPORT_DEL_MAC_ADDRESS;
273 req.emr_in_buf = payload;
274 req.emr_in_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN;
275 req.emr_out_buf = payload;
276 req.emr_out_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN;
278 MCDI_IN_SET_DWORD(req, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, vport_id);
279 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
280 VPORT_DEL_MAC_ADDRESS_IN_MACADDR), addrp);
282 efx_mcdi_execute(enp, &req);
284 if (req.emr_rc != 0) {
292 EFSYS_PROBE1(fail1, efx_rc_t, rc);
296 __checkReturn efx_rc_t
297 efx_mcdi_port_assign(
299 __in efx_vport_id_t vport_id,
300 __in uint32_t vf_index)
302 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_EVB_PORT_ASSIGN_IN_LEN,
303 MC_CMD_EVB_PORT_ASSIGN_OUT_LEN);
305 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
308 req.emr_cmd = MC_CMD_EVB_PORT_ASSIGN;
309 req.emr_in_buf = payload;
310 req.emr_in_length = MC_CMD_EVB_PORT_ASSIGN_IN_LEN;
311 req.emr_out_buf = payload;
312 req.emr_out_length = MC_CMD_EVB_PORT_ASSIGN_OUT_LEN;
314 MCDI_IN_SET_DWORD(req, EVB_PORT_ASSIGN_IN_PORT_ID, vport_id);
315 MCDI_IN_POPULATE_DWORD_2(req, EVB_PORT_ASSIGN_IN_FUNCTION,
316 EVB_PORT_ASSIGN_IN_PF, encp->enc_pf,
317 EVB_PORT_ASSIGN_IN_VF, vf_index);
319 efx_mcdi_execute(enp, &req);
321 if (req.emr_rc != 0) {
329 EFSYS_PROBE1(fail1, efx_rc_t, rc);
333 __checkReturn efx_rc_t
334 efx_mcdi_vport_reconfigure(
336 __in efx_vport_id_t vport_id,
337 __in_opt uint16_t *vidp,
338 __in_bcount_opt(EFX_MAC_ADDR_LEN) uint8_t *addrp,
339 __out_opt boolean_t *fn_resetp)
341 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_RECONFIGURE_IN_LEN,
342 MC_CMD_VPORT_RECONFIGURE_OUT_LEN);
345 uint32_t reset_flag = 0;
347 req.emr_cmd = MC_CMD_VPORT_RECONFIGURE;
348 req.emr_in_buf = payload;
349 req.emr_in_length = MC_CMD_VPORT_RECONFIGURE_IN_LEN;
350 req.emr_out_buf = payload;
351 req.emr_out_length = MC_CMD_VPORT_RECONFIGURE_OUT_LEN;
353 MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_VPORT_ID, vport_id);
356 MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
357 VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS, 1);
358 if (*vidp != EFX_FILTER_VID_UNSPEC) {
359 MCDI_IN_SET_DWORD(req,
360 VPORT_RECONFIGURE_IN_NUM_VLAN_TAGS, 1);
361 MCDI_IN_POPULATE_DWORD_1(req,
362 VPORT_RECONFIGURE_IN_VLAN_TAGS,
363 VPORT_RECONFIGURE_IN_VLAN_TAG_0, *vidp);
367 if ((addrp != NULL) && (efx_is_zero_eth_addr(addrp) == B_FALSE)) {
368 MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
369 VPORT_RECONFIGURE_IN_REPLACE_MACADDRS, 1);
370 MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_NUM_MACADDRS, 1);
371 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
372 VPORT_RECONFIGURE_IN_MACADDRS), addrp);
375 efx_mcdi_execute(enp, &req);
376 if (req.emr_rc != 0) {
381 if (req.emr_out_length_used < MC_CMD_VPORT_RECONFIGURE_OUT_LEN) {
386 reset_flag = MCDI_OUT_DWORD_FIELD(req, VPORT_RECONFIGURE_OUT_FLAGS,
387 VPORT_RECONFIGURE_OUT_RESET_DONE);
389 if (fn_resetp != NULL)
390 *fn_resetp = (reset_flag != 0);
397 EFSYS_PROBE1(fail1, efx_rc_t, rc);
401 __checkReturn efx_rc_t
402 ef10_evb_vswitch_alloc(
404 __out efx_vswitch_id_t *vswitch_idp)
407 if (vswitch_idp == NULL) {
412 if ((rc = efx_mcdi_vswitch_alloc(enp, EVB_PORT_ID_ASSIGNED,
413 EFX_VSWITCH_TYPE_VEB)) != 0) {
417 *vswitch_idp = EFX_DEFAULT_VSWITCH_ID;
423 EFSYS_PROBE1(fail1, efx_rc_t, rc);
427 __checkReturn efx_rc_t
428 ef10_evb_vswitch_free(
430 __in efx_vswitch_id_t vswitch_id)
432 _NOTE(ARGUNUSED(vswitch_id))
434 return (efx_mcdi_vswitch_free(enp));
437 __checkReturn efx_rc_t
438 ef10_evb_vport_alloc(
440 __in efx_vswitch_id_t vswitch_id,
441 __in efx_vport_type_t vport_type,
443 __in boolean_t vlan_restrict,
444 __out efx_vport_id_t *vport_idp)
446 _NOTE(ARGUNUSED(vswitch_id))
448 return (efx_mcdi_vport_alloc(enp,
450 vlan_restrict, vport_idp));
453 __checkReturn efx_rc_t
456 __in efx_vswitch_id_t vswitch_id,
457 __in efx_vport_id_t vport_id)
459 _NOTE(ARGUNUSED(vswitch_id))
461 return (efx_mcdi_vport_free(enp, vport_id));
464 __checkReturn efx_rc_t
465 ef10_evb_vport_mac_addr_add(
467 __in efx_vswitch_id_t vswitch_id,
468 __in efx_vport_id_t vport_id,
469 __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
471 _NOTE(ARGUNUSED(vswitch_id))
472 EFSYS_ASSERT(addrp != NULL);
474 return (efx_mcdi_vport_mac_addr_add(enp, vport_id, addrp));
477 __checkReturn efx_rc_t
478 ef10_evb_vport_mac_addr_del(
480 __in efx_vswitch_id_t vswitch_id,
481 __in efx_vport_id_t vport_id,
482 __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
484 _NOTE(ARGUNUSED(vswitch_id))
485 EFSYS_ASSERT(addrp != NULL);
487 return (efx_mcdi_vport_mac_addr_del(enp, vport_id, addrp));
490 __checkReturn efx_rc_t
491 ef10_evb_vadaptor_alloc(
493 __in efx_vswitch_id_t vswitch_id,
494 __in efx_vport_id_t vport_id)
496 _NOTE(ARGUNUSED(vswitch_id))
498 return (efx_mcdi_vadaptor_alloc(enp, vport_id));
501 __checkReturn efx_rc_t
502 ef10_evb_vadaptor_free(
504 __in efx_vswitch_id_t vswitch_id,
505 __in efx_vport_id_t vport_id)
507 _NOTE(ARGUNUSED(vswitch_id))
509 return (efx_mcdi_vadaptor_free(enp, vport_id));
512 __checkReturn efx_rc_t
513 ef10_evb_vport_assign(
515 __in efx_vswitch_id_t vswitch_id,
516 __in efx_vport_id_t vport_id,
517 __in uint32_t vf_index)
519 _NOTE(ARGUNUSED(vswitch_id))
521 return (efx_mcdi_port_assign(enp, vport_id, vf_index));
524 __checkReturn efx_rc_t
525 ef10_evb_vport_reconfigure(
527 __in efx_vswitch_id_t vswitch_id,
528 __in efx_vport_id_t vport_id,
529 __in_opt uint16_t *vidp,
530 __in_bcount_opt(EFX_MAC_ADDR_LEN) uint8_t *addrp,
531 __out_opt boolean_t *fn_resetp)
533 _NOTE(ARGUNUSED(vswitch_id))
535 return (efx_mcdi_vport_reconfigure(enp, vport_id, vidp,
539 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
540 #endif /* EFSYS_OPT_EVB */