15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko *
3*672386c1SAndrew Rybchenko * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko * Copyright(c) 2018-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko */
65e111ed8SAndrew Rybchenko
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko
105e111ed8SAndrew Rybchenko #if EFSYS_OPT_EVB
115e111ed8SAndrew Rybchenko
1262d6aaa1SAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
135e111ed8SAndrew Rybchenko
145e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_init(__in efx_nic_t * enp)155e111ed8SAndrew Rybchenko ef10_evb_init(
165e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
175e111ed8SAndrew Rybchenko {
1862d6aaa1SAndrew Rybchenko EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
195e111ed8SAndrew Rybchenko
205e111ed8SAndrew Rybchenko return (0);
215e111ed8SAndrew Rybchenko }
225e111ed8SAndrew Rybchenko
235e111ed8SAndrew Rybchenko void
ef10_evb_fini(__in efx_nic_t * enp)245e111ed8SAndrew Rybchenko ef10_evb_fini(
255e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
265e111ed8SAndrew Rybchenko {
2762d6aaa1SAndrew Rybchenko EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp) || EFX_FAMILY_IS_EF10(enp));
285e111ed8SAndrew Rybchenko }
295e111ed8SAndrew Rybchenko
305e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vswitch_alloc(__in efx_nic_t * enp,__in efx_vport_id_t vport_id,__in efx_vswitch_type_t vswitch_type)315e111ed8SAndrew Rybchenko efx_mcdi_vswitch_alloc(
325e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
335e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
345e111ed8SAndrew Rybchenko __in efx_vswitch_type_t vswitch_type)
355e111ed8SAndrew Rybchenko {
365e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_ALLOC_IN_LEN,
375e111ed8SAndrew Rybchenko MC_CMD_VSWITCH_ALLOC_OUT_LEN);
385e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
395e111ed8SAndrew Rybchenko efx_rc_t rc;
405e111ed8SAndrew Rybchenko uint8_t ntags;
415e111ed8SAndrew Rybchenko
425e111ed8SAndrew Rybchenko /* Ensure EFX and MCDI use same values for vswitch types */
435e111ed8SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VLAN ==
445e111ed8SAndrew Rybchenko MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN);
455e111ed8SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_VEB ==
465e111ed8SAndrew Rybchenko MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB);
475e111ed8SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_VSWITCH_TYPE_MUX ==
485e111ed8SAndrew Rybchenko MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX);
495e111ed8SAndrew Rybchenko
505e111ed8SAndrew Rybchenko /* First try with maximum number of VLAN tags FW supports */
515e111ed8SAndrew Rybchenko ntags = 2;
525e111ed8SAndrew Rybchenko retry:
535e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VSWITCH_ALLOC;
545e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
555e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VSWITCH_ALLOC_IN_LEN;
565e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
575e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VSWITCH_ALLOC_OUT_LEN;
585e111ed8SAndrew Rybchenko
595e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID, vport_id);
605e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_TYPE, vswitch_type);
615e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VSWITCH_ALLOC_IN_NUM_VLAN_TAGS, ntags);
625e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_1(req, VSWITCH_ALLOC_IN_FLAGS,
635e111ed8SAndrew Rybchenko VSWITCH_ALLOC_IN_FLAG_AUTO_PORT, 0);
645e111ed8SAndrew Rybchenko
655e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
665e111ed8SAndrew Rybchenko
675e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
685e111ed8SAndrew Rybchenko rc = req.emr_rc;
695e111ed8SAndrew Rybchenko /*
705e111ed8SAndrew Rybchenko * efx_rc_t error codes in libefx are translated from MCDI
715e111ed8SAndrew Rybchenko * error codes in efx_mcdi_request_errcode. As this conversion
725e111ed8SAndrew Rybchenko * is not a 1:1, here we check the specific MCDI error code.
735e111ed8SAndrew Rybchenko */
745e111ed8SAndrew Rybchenko if (req.emr_err_code == MC_CMD_ERR_VLAN_LIMIT) {
755e111ed8SAndrew Rybchenko /* Too many VLAN tags, retry with fewer */
765e111ed8SAndrew Rybchenko EFSYS_PROBE(vlan_limit);
775e111ed8SAndrew Rybchenko ntags--;
785e111ed8SAndrew Rybchenko if (ntags > 0) {
795e111ed8SAndrew Rybchenko /*
805e111ed8SAndrew Rybchenko * Zero the buffer before reusing it
815e111ed8SAndrew Rybchenko * for another request
825e111ed8SAndrew Rybchenko */
835e111ed8SAndrew Rybchenko memset(payload, 0, sizeof (payload));
845e111ed8SAndrew Rybchenko goto retry;
855e111ed8SAndrew Rybchenko }
865e111ed8SAndrew Rybchenko goto fail1;
875e111ed8SAndrew Rybchenko }
885e111ed8SAndrew Rybchenko }
895e111ed8SAndrew Rybchenko
905e111ed8SAndrew Rybchenko return (0);
915e111ed8SAndrew Rybchenko
925e111ed8SAndrew Rybchenko fail1:
935e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
945e111ed8SAndrew Rybchenko return (rc);
955e111ed8SAndrew Rybchenko }
965e111ed8SAndrew Rybchenko
975e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vswitch_free(__in efx_nic_t * enp)985e111ed8SAndrew Rybchenko efx_mcdi_vswitch_free(
995e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
1005e111ed8SAndrew Rybchenko {
1015e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VSWITCH_FREE_IN_LEN,
1025e111ed8SAndrew Rybchenko MC_CMD_VSWITCH_FREE_OUT_LEN);
1035e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
1045e111ed8SAndrew Rybchenko efx_rc_t rc;
1055e111ed8SAndrew Rybchenko
1065e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VSWITCH_FREE;
1075e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
1085e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VSWITCH_FREE_IN_LEN;
1095e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
1105e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VSWITCH_FREE_OUT_LEN;
1115e111ed8SAndrew Rybchenko
1125e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VSWITCH_FREE_IN_UPSTREAM_PORT_ID,
1135e111ed8SAndrew Rybchenko EVB_PORT_ID_ASSIGNED);
1145e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
1155e111ed8SAndrew Rybchenko
1165e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
1175e111ed8SAndrew Rybchenko rc = req.emr_rc;
1185e111ed8SAndrew Rybchenko goto fail1;
1195e111ed8SAndrew Rybchenko }
1205e111ed8SAndrew Rybchenko
1215e111ed8SAndrew Rybchenko return (0);
1225e111ed8SAndrew Rybchenko
1235e111ed8SAndrew Rybchenko fail1:
1245e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1255e111ed8SAndrew Rybchenko return (rc);
1265e111ed8SAndrew Rybchenko }
1275e111ed8SAndrew Rybchenko
1285e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vport_alloc(__in efx_nic_t * enp,__in efx_vport_type_t vport_type,__in uint16_t vid,__in boolean_t vlan_restrict,__out efx_vport_id_t * vport_idp)1295e111ed8SAndrew Rybchenko efx_mcdi_vport_alloc(
1305e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
1315e111ed8SAndrew Rybchenko __in efx_vport_type_t vport_type,
1325e111ed8SAndrew Rybchenko __in uint16_t vid,
1335e111ed8SAndrew Rybchenko __in boolean_t vlan_restrict,
1345e111ed8SAndrew Rybchenko __out efx_vport_id_t *vport_idp)
1355e111ed8SAndrew Rybchenko {
1365e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ALLOC_IN_LEN,
1375e111ed8SAndrew Rybchenko MC_CMD_VPORT_ALLOC_OUT_LEN);
1385e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
1395e111ed8SAndrew Rybchenko efx_rc_t rc;
1405e111ed8SAndrew Rybchenko
1415e111ed8SAndrew Rybchenko /* Ensure EFX and MCDI use same values for vport types */
1425e111ed8SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_VPORT_TYPE_NORMAL ==
1435e111ed8SAndrew Rybchenko MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL);
1445e111ed8SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_VPORT_TYPE_EXPANSION ==
1455e111ed8SAndrew Rybchenko MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION);
1465e111ed8SAndrew Rybchenko EFX_STATIC_ASSERT(EFX_VPORT_TYPE_TEST ==
1475e111ed8SAndrew Rybchenko MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST);
1485e111ed8SAndrew Rybchenko
1495e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VPORT_ALLOC;
1505e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
1515e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VPORT_ALLOC_IN_LEN;
1525e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
1535e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VPORT_ALLOC_OUT_LEN;
1545e111ed8SAndrew Rybchenko
1555e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_UPSTREAM_PORT_ID,
1565e111ed8SAndrew Rybchenko EVB_PORT_ID_ASSIGNED);
1575e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_TYPE, vport_type);
1585e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_ALLOC_IN_NUM_VLAN_TAGS,
1595e111ed8SAndrew Rybchenko (vid != EFX_FILTER_VID_UNSPEC));
1605e111ed8SAndrew Rybchenko
1615e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_2(req, VPORT_ALLOC_IN_FLAGS,
1625e111ed8SAndrew Rybchenko VPORT_ALLOC_IN_FLAG_AUTO_PORT, 0,
1635e111ed8SAndrew Rybchenko VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT, vlan_restrict);
1645e111ed8SAndrew Rybchenko
1655e111ed8SAndrew Rybchenko if (vid != EFX_FILTER_VID_UNSPEC)
1665e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_1(req, VPORT_ALLOC_IN_VLAN_TAGS,
1675e111ed8SAndrew Rybchenko VPORT_ALLOC_IN_VLAN_TAG_0, vid);
1685e111ed8SAndrew Rybchenko
1695e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
1705e111ed8SAndrew Rybchenko
1715e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
1725e111ed8SAndrew Rybchenko rc = req.emr_rc;
1735e111ed8SAndrew Rybchenko goto fail1;
1745e111ed8SAndrew Rybchenko }
1755e111ed8SAndrew Rybchenko
1765e111ed8SAndrew Rybchenko if (req.emr_out_length_used < MC_CMD_VPORT_ALLOC_OUT_LEN) {
1775e111ed8SAndrew Rybchenko rc = EMSGSIZE;
1785e111ed8SAndrew Rybchenko goto fail2;
1795e111ed8SAndrew Rybchenko }
1805e111ed8SAndrew Rybchenko
1815e111ed8SAndrew Rybchenko *vport_idp = *MCDI_OUT2(req, uint32_t, VPORT_ALLOC_OUT_VPORT_ID);
1825e111ed8SAndrew Rybchenko return (0);
1835e111ed8SAndrew Rybchenko
1845e111ed8SAndrew Rybchenko fail2:
1855e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
1865e111ed8SAndrew Rybchenko fail1:
1875e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1885e111ed8SAndrew Rybchenko return (rc);
1895e111ed8SAndrew Rybchenko }
1905e111ed8SAndrew Rybchenko
1915e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vport_free(__in efx_nic_t * enp,__in efx_vport_id_t vport_id)1925e111ed8SAndrew Rybchenko efx_mcdi_vport_free(
1935e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
1945e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id)
1955e111ed8SAndrew Rybchenko {
1965e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_FREE_IN_LEN,
1975e111ed8SAndrew Rybchenko MC_CMD_VPORT_FREE_OUT_LEN);
1985e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
1995e111ed8SAndrew Rybchenko efx_rc_t rc;
2005e111ed8SAndrew Rybchenko
2015e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VPORT_FREE;
2025e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
2035e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VPORT_FREE_IN_LEN;
2045e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
2055e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VPORT_FREE_OUT_LEN;
2065e111ed8SAndrew Rybchenko
2075e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_FREE_IN_VPORT_ID, vport_id);
2085e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
2095e111ed8SAndrew Rybchenko
2105e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
2115e111ed8SAndrew Rybchenko rc = req.emr_rc;
2125e111ed8SAndrew Rybchenko goto fail1;
2135e111ed8SAndrew Rybchenko }
2145e111ed8SAndrew Rybchenko
2155e111ed8SAndrew Rybchenko return (0);
2165e111ed8SAndrew Rybchenko
2175e111ed8SAndrew Rybchenko fail1:
2185e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2195e111ed8SAndrew Rybchenko return (rc);
2205e111ed8SAndrew Rybchenko }
2215e111ed8SAndrew Rybchenko
2225e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vport_mac_addr_add(__in efx_nic_t * enp,__in efx_vport_id_t vport_id,__in_bcount (EFX_MAC_ADDR_LEN)uint8_t * addrp)2235e111ed8SAndrew Rybchenko efx_mcdi_vport_mac_addr_add(
2245e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2255e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
2265e111ed8SAndrew Rybchenko __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
2275e111ed8SAndrew Rybchenko {
2285e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN,
2295e111ed8SAndrew Rybchenko MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN);
2305e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
2315e111ed8SAndrew Rybchenko efx_rc_t rc;
2325e111ed8SAndrew Rybchenko
2335e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VPORT_ADD_MAC_ADDRESS;
2345e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
2355e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN;
2365e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
2375e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN;
2385e111ed8SAndrew Rybchenko
2395e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID, vport_id);
2405e111ed8SAndrew Rybchenko EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
2415e111ed8SAndrew Rybchenko VPORT_ADD_MAC_ADDRESS_IN_MACADDR), addrp);
2425e111ed8SAndrew Rybchenko
2435e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
2445e111ed8SAndrew Rybchenko
2455e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
2465e111ed8SAndrew Rybchenko rc = req.emr_rc;
2475e111ed8SAndrew Rybchenko goto fail1;
2485e111ed8SAndrew Rybchenko }
2495e111ed8SAndrew Rybchenko
2505e111ed8SAndrew Rybchenko return (0);
2515e111ed8SAndrew Rybchenko
2525e111ed8SAndrew Rybchenko fail1:
2535e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2545e111ed8SAndrew Rybchenko return (rc);
2555e111ed8SAndrew Rybchenko }
2565e111ed8SAndrew Rybchenko
2575e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vport_mac_addr_del(__in efx_nic_t * enp,__in efx_vport_id_t vport_id,__in_bcount (EFX_MAC_ADDR_LEN)uint8_t * addrp)2585e111ed8SAndrew Rybchenko efx_mcdi_vport_mac_addr_del(
2595e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2605e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
2615e111ed8SAndrew Rybchenko __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
2625e111ed8SAndrew Rybchenko {
2635e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN,
2645e111ed8SAndrew Rybchenko MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN);
2655e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
2665e111ed8SAndrew Rybchenko efx_rc_t rc;
2675e111ed8SAndrew Rybchenko
2685e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VPORT_DEL_MAC_ADDRESS;
2695e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
2705e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN;
2715e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
2725e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN;
2735e111ed8SAndrew Rybchenko
2745e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID, vport_id);
2755e111ed8SAndrew Rybchenko EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
2765e111ed8SAndrew Rybchenko VPORT_DEL_MAC_ADDRESS_IN_MACADDR), addrp);
2775e111ed8SAndrew Rybchenko
2785e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
2795e111ed8SAndrew Rybchenko
2805e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
2815e111ed8SAndrew Rybchenko rc = req.emr_rc;
2825e111ed8SAndrew Rybchenko goto fail1;
2835e111ed8SAndrew Rybchenko }
2845e111ed8SAndrew Rybchenko
2855e111ed8SAndrew Rybchenko return (0);
2865e111ed8SAndrew Rybchenko
2875e111ed8SAndrew Rybchenko fail1:
2885e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
2895e111ed8SAndrew Rybchenko return (rc);
2905e111ed8SAndrew Rybchenko }
2915e111ed8SAndrew Rybchenko
2925e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_port_assign(__in efx_nic_t * enp,__in efx_vport_id_t vport_id,__in uint32_t vf_index)2935e111ed8SAndrew Rybchenko efx_mcdi_port_assign(
2945e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
2955e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
2965e111ed8SAndrew Rybchenko __in uint32_t vf_index)
2975e111ed8SAndrew Rybchenko {
2985e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_EVB_PORT_ASSIGN_IN_LEN,
2995e111ed8SAndrew Rybchenko MC_CMD_EVB_PORT_ASSIGN_OUT_LEN);
3005e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
3015e111ed8SAndrew Rybchenko efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
3025e111ed8SAndrew Rybchenko efx_rc_t rc;
3035e111ed8SAndrew Rybchenko
3045e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_EVB_PORT_ASSIGN;
3055e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
3065e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_EVB_PORT_ASSIGN_IN_LEN;
3075e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
3085e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_EVB_PORT_ASSIGN_OUT_LEN;
3095e111ed8SAndrew Rybchenko
3105e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, EVB_PORT_ASSIGN_IN_PORT_ID, vport_id);
3115e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_2(req, EVB_PORT_ASSIGN_IN_FUNCTION,
3125e111ed8SAndrew Rybchenko EVB_PORT_ASSIGN_IN_PF, encp->enc_pf,
3135e111ed8SAndrew Rybchenko EVB_PORT_ASSIGN_IN_VF, vf_index);
3145e111ed8SAndrew Rybchenko
3155e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
3165e111ed8SAndrew Rybchenko
3175e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
3185e111ed8SAndrew Rybchenko rc = req.emr_rc;
3195e111ed8SAndrew Rybchenko goto fail1;
3205e111ed8SAndrew Rybchenko }
3215e111ed8SAndrew Rybchenko
3225e111ed8SAndrew Rybchenko return (0);
3235e111ed8SAndrew Rybchenko
3245e111ed8SAndrew Rybchenko fail1:
3255e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
3265e111ed8SAndrew Rybchenko return (rc);
3275e111ed8SAndrew Rybchenko }
3285e111ed8SAndrew Rybchenko
3295e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_vport_reconfigure(__in efx_nic_t * enp,__in efx_vport_id_t vport_id,__in_opt uint16_t * vidp,__in_bcount_opt (EFX_MAC_ADDR_LEN)uint8_t * addrp,__out_opt boolean_t * fn_resetp)3305e111ed8SAndrew Rybchenko efx_mcdi_vport_reconfigure(
3315e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
3325e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
3335e111ed8SAndrew Rybchenko __in_opt uint16_t *vidp,
3345e111ed8SAndrew Rybchenko __in_bcount_opt(EFX_MAC_ADDR_LEN) uint8_t *addrp,
3355e111ed8SAndrew Rybchenko __out_opt boolean_t *fn_resetp)
3365e111ed8SAndrew Rybchenko {
3375e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VPORT_RECONFIGURE_IN_LEN,
3385e111ed8SAndrew Rybchenko MC_CMD_VPORT_RECONFIGURE_OUT_LEN);
3395e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
3405e111ed8SAndrew Rybchenko efx_rc_t rc;
3415e111ed8SAndrew Rybchenko uint32_t reset_flag = 0;
3425e111ed8SAndrew Rybchenko
3435e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_VPORT_RECONFIGURE;
3445e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
3455e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_VPORT_RECONFIGURE_IN_LEN;
3465e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
3475e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_VPORT_RECONFIGURE_OUT_LEN;
3485e111ed8SAndrew Rybchenko
3495e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_VPORT_ID, vport_id);
3505e111ed8SAndrew Rybchenko
3515e111ed8SAndrew Rybchenko if (vidp != NULL) {
3525e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
3535e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_IN_REPLACE_VLAN_TAGS, 1);
3545e111ed8SAndrew Rybchenko if (*vidp != EFX_FILTER_VID_UNSPEC) {
3555e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req,
3565e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_IN_NUM_VLAN_TAGS, 1);
3575e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_1(req,
3585e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_IN_VLAN_TAGS,
3595e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_IN_VLAN_TAG_0, *vidp);
3605e111ed8SAndrew Rybchenko }
3615e111ed8SAndrew Rybchenko }
3625e111ed8SAndrew Rybchenko
3635e111ed8SAndrew Rybchenko if ((addrp != NULL) && (efx_is_zero_eth_addr(addrp) == B_FALSE)) {
3645e111ed8SAndrew Rybchenko MCDI_IN_POPULATE_DWORD_1(req, VPORT_RECONFIGURE_IN_FLAGS,
3655e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_IN_REPLACE_MACADDRS, 1);
3665e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, VPORT_RECONFIGURE_IN_NUM_MACADDRS, 1);
3675e111ed8SAndrew Rybchenko EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
3685e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_IN_MACADDRS), addrp);
3695e111ed8SAndrew Rybchenko }
3705e111ed8SAndrew Rybchenko
3715e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
3725e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
3735e111ed8SAndrew Rybchenko rc = req.emr_rc;
3745e111ed8SAndrew Rybchenko goto fail1;
3755e111ed8SAndrew Rybchenko }
3765e111ed8SAndrew Rybchenko
3775e111ed8SAndrew Rybchenko if (req.emr_out_length_used < MC_CMD_VPORT_RECONFIGURE_OUT_LEN) {
3785e111ed8SAndrew Rybchenko rc = EMSGSIZE;
3795e111ed8SAndrew Rybchenko goto fail2;
3805e111ed8SAndrew Rybchenko }
3815e111ed8SAndrew Rybchenko
3825e111ed8SAndrew Rybchenko reset_flag = MCDI_OUT_DWORD_FIELD(req, VPORT_RECONFIGURE_OUT_FLAGS,
3835e111ed8SAndrew Rybchenko VPORT_RECONFIGURE_OUT_RESET_DONE);
3845e111ed8SAndrew Rybchenko
3855e111ed8SAndrew Rybchenko if (fn_resetp != NULL)
3865e111ed8SAndrew Rybchenko *fn_resetp = (reset_flag != 0);
3875e111ed8SAndrew Rybchenko
3885e111ed8SAndrew Rybchenko return (0);
3895e111ed8SAndrew Rybchenko
3905e111ed8SAndrew Rybchenko fail2:
3915e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
3925e111ed8SAndrew Rybchenko fail1:
3935e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
3945e111ed8SAndrew Rybchenko return (rc);
3955e111ed8SAndrew Rybchenko }
3965e111ed8SAndrew Rybchenko
3975e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vswitch_alloc(__in efx_nic_t * enp,__out efx_vswitch_id_t * vswitch_idp)3985e111ed8SAndrew Rybchenko ef10_evb_vswitch_alloc(
3995e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4005e111ed8SAndrew Rybchenko __out efx_vswitch_id_t *vswitch_idp)
4015e111ed8SAndrew Rybchenko {
4025e111ed8SAndrew Rybchenko efx_rc_t rc;
4035e111ed8SAndrew Rybchenko if (vswitch_idp == NULL) {
4045e111ed8SAndrew Rybchenko rc = EINVAL;
4055e111ed8SAndrew Rybchenko goto fail1;
4065e111ed8SAndrew Rybchenko }
4075e111ed8SAndrew Rybchenko
4085e111ed8SAndrew Rybchenko if ((rc = efx_mcdi_vswitch_alloc(enp, EVB_PORT_ID_ASSIGNED,
4095e111ed8SAndrew Rybchenko EFX_VSWITCH_TYPE_VEB)) != 0) {
4105e111ed8SAndrew Rybchenko goto fail2;
4115e111ed8SAndrew Rybchenko }
4125e111ed8SAndrew Rybchenko
4135e111ed8SAndrew Rybchenko *vswitch_idp = EFX_DEFAULT_VSWITCH_ID;
4145e111ed8SAndrew Rybchenko return (0);
4155e111ed8SAndrew Rybchenko
4165e111ed8SAndrew Rybchenko fail2:
4175e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
4185e111ed8SAndrew Rybchenko fail1:
4195e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
4205e111ed8SAndrew Rybchenko return (rc);
4215e111ed8SAndrew Rybchenko }
4225e111ed8SAndrew Rybchenko
4235e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vswitch_free(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id)4245e111ed8SAndrew Rybchenko ef10_evb_vswitch_free(
4255e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4265e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id)
4275e111ed8SAndrew Rybchenko {
4285e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
4295e111ed8SAndrew Rybchenko
4305e111ed8SAndrew Rybchenko return (efx_mcdi_vswitch_free(enp));
4315e111ed8SAndrew Rybchenko }
4325e111ed8SAndrew Rybchenko
4335e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_alloc(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_type_t vport_type,__in uint16_t vid,__in boolean_t vlan_restrict,__out efx_vport_id_t * vport_idp)4345e111ed8SAndrew Rybchenko ef10_evb_vport_alloc(
4355e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4365e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
4375e111ed8SAndrew Rybchenko __in efx_vport_type_t vport_type,
4385e111ed8SAndrew Rybchenko __in uint16_t vid,
4395e111ed8SAndrew Rybchenko __in boolean_t vlan_restrict,
4405e111ed8SAndrew Rybchenko __out efx_vport_id_t *vport_idp)
4415e111ed8SAndrew Rybchenko {
4425e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
4435e111ed8SAndrew Rybchenko
4445e111ed8SAndrew Rybchenko return (efx_mcdi_vport_alloc(enp,
4455e111ed8SAndrew Rybchenko vport_type, vid,
4465e111ed8SAndrew Rybchenko vlan_restrict, vport_idp));
4475e111ed8SAndrew Rybchenko }
4485e111ed8SAndrew Rybchenko
4495e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_free(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id)4505e111ed8SAndrew Rybchenko ef10_evb_vport_free(
4515e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4525e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
4535e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id)
4545e111ed8SAndrew Rybchenko {
4555e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
4565e111ed8SAndrew Rybchenko
4575e111ed8SAndrew Rybchenko return (efx_mcdi_vport_free(enp, vport_id));
4585e111ed8SAndrew Rybchenko }
4595e111ed8SAndrew Rybchenko
4605e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_mac_addr_add(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id,__in_bcount (EFX_MAC_ADDR_LEN)uint8_t * addrp)4615e111ed8SAndrew Rybchenko ef10_evb_vport_mac_addr_add(
4625e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4635e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
4645e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
4655e111ed8SAndrew Rybchenko __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
4665e111ed8SAndrew Rybchenko {
4675e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
4685e111ed8SAndrew Rybchenko EFSYS_ASSERT(addrp != NULL);
4695e111ed8SAndrew Rybchenko
4705e111ed8SAndrew Rybchenko return (efx_mcdi_vport_mac_addr_add(enp, vport_id, addrp));
4715e111ed8SAndrew Rybchenko }
4725e111ed8SAndrew Rybchenko
4735e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_mac_addr_del(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id,__in_bcount (EFX_MAC_ADDR_LEN)uint8_t * addrp)4745e111ed8SAndrew Rybchenko ef10_evb_vport_mac_addr_del(
4755e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4765e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
4775e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
4785e111ed8SAndrew Rybchenko __in_bcount(EFX_MAC_ADDR_LEN) uint8_t *addrp)
4795e111ed8SAndrew Rybchenko {
4805e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
4815e111ed8SAndrew Rybchenko EFSYS_ASSERT(addrp != NULL);
4825e111ed8SAndrew Rybchenko
4835e111ed8SAndrew Rybchenko return (efx_mcdi_vport_mac_addr_del(enp, vport_id, addrp));
4845e111ed8SAndrew Rybchenko }
4855e111ed8SAndrew Rybchenko
4865e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vadaptor_alloc(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id)4875e111ed8SAndrew Rybchenko ef10_evb_vadaptor_alloc(
4885e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
4895e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
4905e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id)
4915e111ed8SAndrew Rybchenko {
4925e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
4935e111ed8SAndrew Rybchenko
4945e111ed8SAndrew Rybchenko return (efx_mcdi_vadaptor_alloc(enp, vport_id));
4955e111ed8SAndrew Rybchenko }
4965e111ed8SAndrew Rybchenko
4975e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vadaptor_free(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id)4985e111ed8SAndrew Rybchenko ef10_evb_vadaptor_free(
4995e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
5005e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
5015e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id)
5025e111ed8SAndrew Rybchenko {
5035e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
5045e111ed8SAndrew Rybchenko
5055e111ed8SAndrew Rybchenko return (efx_mcdi_vadaptor_free(enp, vport_id));
5065e111ed8SAndrew Rybchenko }
5075e111ed8SAndrew Rybchenko
5085e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_assign(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id,__in uint32_t vf_index)5095e111ed8SAndrew Rybchenko ef10_evb_vport_assign(
5105e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
5115e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
5125e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
5135e111ed8SAndrew Rybchenko __in uint32_t vf_index)
5145e111ed8SAndrew Rybchenko {
5155e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
5165e111ed8SAndrew Rybchenko
5175e111ed8SAndrew Rybchenko return (efx_mcdi_port_assign(enp, vport_id, vf_index));
5185e111ed8SAndrew Rybchenko }
5195e111ed8SAndrew Rybchenko
5205e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_reconfigure(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id,__in_opt uint16_t * vidp,__in_bcount_opt (EFX_MAC_ADDR_LEN)uint8_t * addrp,__out_opt boolean_t * fn_resetp)5215e111ed8SAndrew Rybchenko ef10_evb_vport_reconfigure(
5225e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
5235e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
5245e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
5255e111ed8SAndrew Rybchenko __in_opt uint16_t *vidp,
5265e111ed8SAndrew Rybchenko __in_bcount_opt(EFX_MAC_ADDR_LEN) uint8_t *addrp,
5275e111ed8SAndrew Rybchenko __out_opt boolean_t *fn_resetp)
5285e111ed8SAndrew Rybchenko {
5295e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
5305e111ed8SAndrew Rybchenko
5315e111ed8SAndrew Rybchenko return (efx_mcdi_vport_reconfigure(enp, vport_id, vidp,
5325e111ed8SAndrew Rybchenko addrp, fn_resetp));
5335e111ed8SAndrew Rybchenko }
5345e111ed8SAndrew Rybchenko
5355e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_evb_vport_stats(__in efx_nic_t * enp,__in efx_vswitch_id_t vswitch_id,__in efx_vport_id_t vport_id,__in efsys_mem_t * esmp)5365e111ed8SAndrew Rybchenko ef10_evb_vport_stats(
5375e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
5385e111ed8SAndrew Rybchenko __in efx_vswitch_id_t vswitch_id,
5395e111ed8SAndrew Rybchenko __in efx_vport_id_t vport_id,
5405e111ed8SAndrew Rybchenko __in efsys_mem_t *esmp)
5415e111ed8SAndrew Rybchenko {
5425e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(vswitch_id))
5435e111ed8SAndrew Rybchenko
5445e111ed8SAndrew Rybchenko return (efx_mcdi_mac_stats(enp, vport_id, esmp,
5455e111ed8SAndrew Rybchenko EFX_STATS_UPLOAD, 0));
5465e111ed8SAndrew Rybchenko }
5475e111ed8SAndrew Rybchenko
54862d6aaa1SAndrew Rybchenko #endif /* EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() */
5495e111ed8SAndrew Rybchenko #endif /* EFSYS_OPT_EVB */
550