]> git.droids-corp.org - dpdk.git/commitdiff
common/sfc_efx/base: manage VNIC MAC address by MCDI handle
authorIvan Malov <ivan.malov@oktetlabs.ru>
Thu, 26 May 2022 08:45:49 +0000 (11:45 +0300)
committerAndrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Tue, 31 May 2022 16:50:00 +0000 (18:50 +0200)
The board admin may need to assign a MAC address to a guest
VNIC identified by its MCDI handle. Provide an API for that.

In the case when a libefx-based driver is used at the guest,
it will need to check its MAC address using the symmetrical
API if the admin has tweaked it by means of its representor.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
drivers/common/sfc_efx/base/ef10_nic.c
drivers/common/sfc_efx/base/efx.h
drivers/common/sfc_efx/base/efx_mcdi.c
drivers/common/sfc_efx/version.map

index aa667309ab730da5b2e461e3416e770832238cbd..b27fc64210edbaef1e34668a1382de0e7d0335ab 100644 (file)
@@ -1991,8 +1991,9 @@ efx_mcdi_nic_board_cfg(
        if ((rc = ef10_mcdi_get_pf_count(enp, &encp->enc_hw_pf_count)) != 0)
                goto fail4;
 
-       /* MAC address for this function */
-       if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+       rc = efx_mcdi_client_mac_addr_get(enp, CLIENT_HANDLE_SELF, mac_addr);
+       if ((rc != 0) && EFX_PCI_FUNCTION_IS_PF(encp)) {
+               /* Fallback for legacy MAC address get approach (PF) */
                rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
 #if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC
                /*
@@ -2011,9 +2012,11 @@ efx_mcdi_nic_board_cfg(
                        rc = EINVAL;
                }
 #endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
-       } else {
+       } else if (rc != 0) {
+               /* Fallback for legacy MAC address get approach (VF) */
                rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
        }
+
        if (rc != 0)
                goto fail5;
 
index 854527e0fd1c04cfdec50f6c4f57851bd263ce28..95f5fb6bc087ea21f7472a9884e176a9324824fd 100644 (file)
@@ -311,6 +311,8 @@ efx_nic_check_pcie_link_speed(
        __in            uint32_t pcie_link_gen,
        __out           efx_pcie_link_performance_t *resultp);
 
+#define        EFX_MAC_ADDR_LEN 6
+
 #if EFSYS_OPT_MCDI
 
 #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10()
@@ -406,6 +408,20 @@ efx_mcdi_get_own_client_handle(
        __in            efx_nic_t *enp,
        __out           uint32_t *handle);
 
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_mcdi_client_mac_addr_get(
+       __in            efx_nic_t *enp,
+       __in            uint32_t client_handle,
+       __out           uint8_t addr_bytes[EFX_MAC_ADDR_LEN]);
+
+LIBEFX_API
+extern __checkReturn   efx_rc_t
+efx_mcdi_client_mac_addr_set(
+       __in            efx_nic_t *enp,
+       __in            uint32_t client_handle,
+       __in            const uint8_t addr_bytes[EFX_MAC_ADDR_LEN]);
+
 LIBEFX_API
 extern                 void
 efx_mcdi_fini(
@@ -616,11 +632,10 @@ typedef enum efx_link_mode_e {
        EFX_LINK_NMODES
 } efx_link_mode_t;
 
-#define        EFX_MAC_ADDR_LEN 6
-
 #define        EFX_VNI_OR_VSID_LEN 3
 
-#define        EFX_MAC_ADDR_IS_MULTICAST(_address) (((uint8_t *)_address)[0] & 0x01)
+#define        EFX_MAC_ADDR_IS_MULTICAST(_address)     \
+       (((const uint8_t *)_address)[0] & 0x01)
 
 #define        EFX_MAC_MULTICAST_LIST_MAX      256
 
index 404ca23d586b184704890308dd768bd96caf2774..6274cf6bac777dca800b7c7ea5ab752a34437755 100644 (file)
@@ -727,6 +727,107 @@ fail1:
        return (rc);
 }
 
+       __checkReturn   efx_rc_t
+efx_mcdi_client_mac_addr_get(
+       __in            efx_nic_t *enp,
+       __in            uint32_t client_handle,
+       __out           uint8_t addr_bytes[EFX_MAC_ADDR_LEN])
+{
+       efx_mcdi_req_t req;
+       EFX_MCDI_DECLARE_BUF(payload,
+           MC_CMD_GET_CLIENT_MAC_ADDRESSES_IN_LEN,
+           MC_CMD_GET_CLIENT_MAC_ADDRESSES_OUT_LEN(1));
+       efx_rc_t rc;
+
+       req.emr_cmd = MC_CMD_GET_CLIENT_MAC_ADDRESSES;
+       req.emr_in_buf = payload;
+       req.emr_in_length = MC_CMD_GET_CLIENT_MAC_ADDRESSES_IN_LEN;
+       req.emr_out_buf = payload;
+       req.emr_out_length = MC_CMD_GET_CLIENT_MAC_ADDRESSES_OUT_LEN(1);
+
+       MCDI_IN_SET_DWORD(req, GET_CLIENT_MAC_ADDRESSES_IN_CLIENT_HANDLE,
+           client_handle);
+
+       efx_mcdi_execute(enp, &req);
+
+       if (req.emr_rc != 0) {
+               rc = req.emr_rc;
+               goto fail1;
+       }
+
+       if (req.emr_out_length_used <
+           MC_CMD_GET_CLIENT_MAC_ADDRESSES_OUT_LEN(1)) {
+               rc = EMSGSIZE;
+               goto fail2;
+       }
+
+       memcpy(addr_bytes,
+           MCDI_OUT2(req, uint8_t, GET_CLIENT_MAC_ADDRESSES_OUT_MAC_ADDRS),
+           EFX_MAC_ADDR_LEN);
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_mcdi_client_mac_addr_set(
+       __in            efx_nic_t *enp,
+       __in            uint32_t client_handle,
+       __in            const uint8_t addr_bytes[EFX_MAC_ADDR_LEN])
+{
+       efx_mcdi_req_t req;
+       EFX_MCDI_DECLARE_BUF(payload,
+           MC_CMD_SET_CLIENT_MAC_ADDRESSES_IN_LEN(1),
+           MC_CMD_SET_CLIENT_MAC_ADDRESSES_OUT_LEN);
+       uint32_t oui;
+       efx_rc_t rc;
+
+       if (EFX_MAC_ADDR_IS_MULTICAST(addr_bytes)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       oui = addr_bytes[0] << 16 | addr_bytes[1] << 8 | addr_bytes[2];
+       if (oui == 0x000000) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       req.emr_cmd = MC_CMD_SET_CLIENT_MAC_ADDRESSES;
+       req.emr_in_buf = payload;
+       req.emr_in_length = MC_CMD_SET_CLIENT_MAC_ADDRESSES_IN_LEN(1);
+       req.emr_out_buf = payload;
+       req.emr_out_length = MC_CMD_SET_CLIENT_MAC_ADDRESSES_OUT_LEN;
+
+       MCDI_IN_SET_DWORD(req, SET_CLIENT_MAC_ADDRESSES_IN_CLIENT_HANDLE,
+           client_handle);
+
+       memcpy(MCDI_IN2(req, uint8_t, SET_CLIENT_MAC_ADDRESSES_IN_MAC_ADDRS),
+           addr_bytes, EFX_MAC_ADDR_LEN);
+
+       efx_mcdi_execute(enp, &req);
+
+       if (req.emr_rc != 0) {
+               rc = req.emr_rc;
+               goto fail3;
+       }
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
                        void
 efx_mcdi_get_timeout(
        __in            efx_nic_t *enp,
index 9510897b83d8c0c61ff6a66df974611376bab605..a54aab0a0893ceb736ed223dd73e048bef73ca31 100644 (file)
@@ -144,6 +144,8 @@ INTERNAL {
        efx_mae_outer_rule_remove;
        efx_mae_read_mport_journal;
 
+       efx_mcdi_client_mac_addr_get;
+       efx_mcdi_client_mac_addr_set;
        efx_mcdi_fini;
        efx_mcdi_get_client_handle;
        efx_mcdi_get_own_client_handle;