From 1bf9ff57ccb3825eb1f3d48be7f459d590115e56 Mon Sep 17 00:00:00 2001 From: Viacheslav Galaktionov Date: Mon, 11 Oct 2021 17:48:50 +0300 Subject: [PATCH] common/sfc_efx/base: allow getting VNIC MCDI client handles Equality checks between VNICs should be done by comparing their client handles. This means that clients should be able to retrieve client handles for arbitrary functions and themselves. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/common/sfc_efx/base/efx.h | 15 ++++++ drivers/common/sfc_efx/base/efx_mcdi.c | 73 ++++++++++++++++++++++++++ drivers/common/sfc_efx/version.map | 2 + 3 files changed, 90 insertions(+) diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h index e77b297950..b61984a8e3 100644 --- a/drivers/common/sfc_efx/base/efx.h +++ b/drivers/common/sfc_efx/base/efx.h @@ -391,6 +391,21 @@ extern __checkReturn boolean_t efx_mcdi_request_abort( __in efx_nic_t *enp); +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mcdi_get_client_handle( + __in efx_nic_t *enp, + __in efx_pcie_interface_t intf, + __in uint16_t pf, + __in uint16_t vf, + __out uint32_t *handle); + +LIBEFX_API +extern __checkReturn efx_rc_t +efx_mcdi_get_own_client_handle( + __in efx_nic_t *enp, + __out uint32_t *handle); + LIBEFX_API extern void efx_mcdi_fini( diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index 69bf7ce70f..cdf7181e0d 100644 --- a/drivers/common/sfc_efx/base/efx_mcdi.c +++ b/drivers/common/sfc_efx/base/efx_mcdi.c @@ -647,6 +647,79 @@ efx_mcdi_request_abort( return (aborted); } + __checkReturn efx_rc_t +efx_mcdi_get_client_handle( + __in efx_nic_t *enp, + __in efx_pcie_interface_t intf, + __in uint16_t pf, + __in uint16_t vf, + __out uint32_t *handle) +{ + efx_mcdi_req_t req; + EFX_MCDI_DECLARE_BUF(payload, + MC_CMD_GET_CLIENT_HANDLE_IN_LEN, + MC_CMD_GET_CLIENT_HANDLE_OUT_LEN); + efx_rc_t rc; + + if (handle == NULL) { + rc = EINVAL; + goto fail1; + } + + req.emr_cmd = MC_CMD_GET_CLIENT_HANDLE; + req.emr_in_buf = payload; + req.emr_in_length = MC_CMD_GET_CLIENT_HANDLE_IN_LEN; + req.emr_out_buf = payload; + req.emr_out_length = MC_CMD_GET_CLIENT_HANDLE_OUT_LEN; + + MCDI_IN_SET_DWORD(req, GET_CLIENT_HANDLE_IN_TYPE, + MC_CMD_GET_CLIENT_HANDLE_IN_TYPE_FUNC); + MCDI_IN_SET_WORD(req, GET_CLIENT_HANDLE_IN_FUNC_PF, pf); + MCDI_IN_SET_WORD(req, GET_CLIENT_HANDLE_IN_FUNC_VF, vf); + MCDI_IN_SET_DWORD(req, GET_CLIENT_HANDLE_IN_FUNC_INTF, intf); + + efx_mcdi_execute(enp, &req); + + if (req.emr_rc != 0) { + rc = req.emr_rc; + goto fail2; + } + + if (req.emr_out_length_used < MC_CMD_GET_CLIENT_HANDLE_OUT_LEN) { + rc = EMSGSIZE; + goto fail3; + } + + *handle = MCDI_OUT_DWORD(req, GET_CLIENT_HANDLE_OUT_HANDLE); + + return 0; +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + + __checkReturn efx_rc_t +efx_mcdi_get_own_client_handle( + __in efx_nic_t *enp, + __out uint32_t *handle) +{ + efx_rc_t rc; + + rc = efx_mcdi_get_client_handle(enp, PCIE_INTERFACE_CALLER, + PCIE_FUNCTION_PF_NULL, PCIE_FUNCTION_VF_NULL, handle); + if (rc != 0) + goto fail1; + + return (0); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + return (rc); +} + void efx_mcdi_get_timeout( __in efx_nic_t *enp, diff --git a/drivers/common/sfc_efx/version.map b/drivers/common/sfc_efx/version.map index 10216bb37d..346deb4b12 100644 --- a/drivers/common/sfc_efx/version.map +++ b/drivers/common/sfc_efx/version.map @@ -136,6 +136,8 @@ INTERNAL { efx_mae_read_mport_journal; efx_mcdi_fini; + efx_mcdi_get_client_handle; + efx_mcdi_get_own_client_handle; efx_mcdi_get_proxy_handle; efx_mcdi_get_timeout; efx_mcdi_init; -- 2.20.1