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_ecount(6) 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_ecount(6) 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 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
334 #endif /* EFSYS_OPT_EVB */