Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2015 - 2021 Intel Corporation */ #include <linux/bitfield.h> #include "adf_accel_devices.h" #include "adf_common_drv.h" #include "adf_pfvf_msg.h" #include "adf_pfvf_vf_msg.h" #include "adf_pfvf_vf_proto.h" /** * adf_vf2pf_notify_init() - send init msg to PF * @accel_dev: Pointer to acceleration VF device. * * Function sends an init message from the VF to a PF * * Return: 0 on success, error code otherwise. */ int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) { struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_INIT }; if (adf_send_vf2pf_msg(accel_dev, msg)) { dev_err(&GET_DEV(accel_dev), "Failed to send Init event to PF\n"); return -EFAULT; } set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); return 0; } EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init); /** * adf_vf2pf_notify_shutdown() - send shutdown msg to PF * @accel_dev: Pointer to acceleration VF device. * * Function sends a shutdown message from the VF to a PF * * Return: void */ void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) { struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_SHUTDOWN }; if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status)) if (adf_send_vf2pf_msg(accel_dev, msg)) dev_err(&GET_DEV(accel_dev), "Failed to send Shutdown event to PF\n"); } EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown); int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev) { u8 pf_version; int compat; int ret; struct pfvf_message resp; struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ, .data = ADF_PFVF_COMPAT_THIS_VERSION, }; BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255); ret = adf_send_vf2pf_req(accel_dev, msg, &resp); if (ret) { dev_err(&GET_DEV(accel_dev), "Failed to send Compatibility Version Request.\n"); return ret; } pf_version = FIELD_GET(ADF_PF2VF_VERSION_RESP_VERS_MASK, resp.data); compat = FIELD_GET(ADF_PF2VF_VERSION_RESP_RESULT_MASK, resp.data); /* Response from PF received, check compatibility */ switch (compat) { case ADF_PF2VF_VF_COMPATIBLE: break; case ADF_PF2VF_VF_COMPAT_UNKNOWN: /* VF is newer than PF - compatible for now */ break; case ADF_PF2VF_VF_INCOMPATIBLE: dev_err(&GET_DEV(accel_dev), "PF (vers %d) and VF (vers %d) are not compatible\n", pf_version, ADF_PFVF_COMPAT_THIS_VERSION); return -EINVAL; default: dev_err(&GET_DEV(accel_dev), "Invalid response from PF; assume not compatible\n"); return -EINVAL; } accel_dev->vf.pf_compat_ver = pf_version; return 0; } int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev) { struct adf_hw_device_data *hw_data = accel_dev->hw_device; struct capabilities_v3 cap_msg = { 0 }; unsigned int len = sizeof(cap_msg); if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_CAPABILITIES) /* The PF is too old to support the extended capabilities */ return 0; if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY, (u8 *)&cap_msg, &len)) { dev_err(&GET_DEV(accel_dev), "QAT: Failed to get block message response\n"); return -EFAULT; } switch (cap_msg.hdr.version) { default: /* Newer version received, handle only the know parts */ fallthrough; case ADF_PFVF_CAPABILITIES_V3_VERSION: if (likely(len >= sizeof(struct capabilities_v3))) hw_data->clock_frequency = cap_msg.frequency; else dev_info(&GET_DEV(accel_dev), "Could not get frequency"); fallthrough; case ADF_PFVF_CAPABILITIES_V2_VERSION: if (likely(len >= sizeof(struct capabilities_v2))) hw_data->accel_capabilities_mask = cap_msg.capabilities; else dev_info(&GET_DEV(accel_dev), "Could not get capabilities"); fallthrough; case ADF_PFVF_CAPABILITIES_V1_VERSION: if (likely(len >= sizeof(struct capabilities_v1))) { hw_data->extended_dc_capabilities = cap_msg.ext_dc_caps; } else { dev_err(&GET_DEV(accel_dev), "Capabilities message truncated to %d bytes\n", len); return -EFAULT; } } return 0; } int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev) { struct ring_to_svc_map_v1 rts_map_msg = { 0 }; unsigned int len = sizeof(rts_map_msg); if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_RING_TO_SVC_MAP) /* Use already set default mappings */ return 0; if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP, (u8 *)&rts_map_msg, &len)) { dev_err(&GET_DEV(accel_dev), "QAT: Failed to get block message response\n"); return -EFAULT; } if (unlikely(len < sizeof(struct ring_to_svc_map_v1))) { dev_err(&GET_DEV(accel_dev), "RING_TO_SVC message truncated to %d bytes\n", len); return -EFAULT; } /* Only v1 at present */ accel_dev->hw_device->ring_to_svc_map = rts_map_msg.map; return 0; } |