X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcommon%2Fsfc_efx%2Fbase%2Fefx_mcdi.c;h=cdf7181e0d9f7494863cf60bdd6c4c6e151b105b;hb=e8745b54126e263a07f98849cc9a390ac31fe111;hp=b68fc0503d0e798b5c484638d691f078788abcd8;hpb=3dee345ab31a8cc685c9fe5ba3f90aa322ee1d48;p=dpdk.git diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c index b68fc0503d..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, @@ -2130,6 +2203,36 @@ fail1: #if EFSYS_OPT_RIVERHEAD || EFX_OPTS_EF10() + __checkReturn efx_rc_t +efx_mcdi_intf_from_pcie( + __in uint32_t pcie_intf, + __out efx_pcie_interface_t *efx_intf) +{ + efx_rc_t rc; + + switch (pcie_intf) { + case PCIE_INTERFACE_CALLER: + *efx_intf = EFX_PCIE_INTERFACE_CALLER; + break; + case PCIE_INTERFACE_HOST_PRIMARY: + *efx_intf = EFX_PCIE_INTERFACE_HOST_PRIMARY; + break; + case PCIE_INTERFACE_NIC_EMBEDDED: + *efx_intf = EFX_PCIE_INTERFACE_NIC_EMBEDDED; + break; + default: + rc = EINVAL; + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + /* * This function returns the pf and vf number of a function. If it is a pf the * vf number is 0xffff. The vf number is the index of the vf on that @@ -2140,18 +2243,21 @@ fail1: efx_mcdi_get_function_info( __in efx_nic_t *enp, __out uint32_t *pfp, - __out_opt uint32_t *vfp) + __out_opt uint32_t *vfp, + __out_opt efx_pcie_interface_t *intfp) { + efx_pcie_interface_t intf; efx_mcdi_req_t req; EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_FUNCTION_INFO_IN_LEN, - MC_CMD_GET_FUNCTION_INFO_OUT_LEN); + MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN); + uint32_t pcie_intf; efx_rc_t rc; req.emr_cmd = MC_CMD_GET_FUNCTION_INFO; req.emr_in_buf = payload; req.emr_in_length = MC_CMD_GET_FUNCTION_INFO_IN_LEN; req.emr_out_buf = payload; - req.emr_out_length = MC_CMD_GET_FUNCTION_INFO_OUT_LEN; + req.emr_out_length = MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN; efx_mcdi_execute(enp, &req); @@ -2169,8 +2275,24 @@ efx_mcdi_get_function_info( if (vfp != NULL) *vfp = MCDI_OUT_DWORD(req, GET_FUNCTION_INFO_OUT_VF); + if (req.emr_out_length < MC_CMD_GET_FUNCTION_INFO_OUT_V2_LEN) { + intf = EFX_PCIE_INTERFACE_HOST_PRIMARY; + } else { + pcie_intf = MCDI_OUT_DWORD(req, + GET_FUNCTION_INFO_OUT_V2_INTF); + + rc = efx_mcdi_intf_from_pcie(pcie_intf, &intf); + if (rc != 0) + goto fail3; + } + + if (intfp != NULL) + *intfp = intf; + return (0); +fail3: + EFSYS_PROBE(fail3); fail2: EFSYS_PROBE(fail2); fail1: