1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 #include "qat_freebsd.h" 4 #include "adf_cfg.h" 5 #include "adf_common_drv.h" 6 #include "adf_accel_devices.h" 7 #include "icp_qat_uclo.h" 8 #include "icp_qat_fw.h" 9 #include "icp_qat_fw_init_admin.h" 10 #include "adf_cfg_strings.h" 11 #include "adf_transport_access_macros.h" 12 #include "adf_transport_internal.h" 13 #include <sys/firmware.h> 14 #include <dev/pci/pcivar.h> 15 #include "adf_cfg.h" 16 #include "adf_accel_devices.h" 17 #include "adf_common_drv.h" 18 #include "icp_qat_uclo.h" 19 #include "icp_qat_hw.h" 20 21 #define MMP_VERSION_LEN 4 22 23 struct adf_mmp_version_s { 24 u8 ver_val[MMP_VERSION_LEN]; 25 }; 26 27 static int 28 request_firmware(const struct firmware **firmware_p, const char *name) 29 { 30 int retval = 0; 31 if (NULL == firmware_p) { 32 return -1; 33 } 34 *firmware_p = firmware_get(name); 35 if (NULL == *firmware_p) { 36 retval = -1; 37 } 38 return retval; 39 } 40 41 int 42 adf_ae_fw_load(struct adf_accel_dev *accel_dev) 43 { 44 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 45 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 46 const void *fw_addr, *mmp_addr; 47 u32 fw_size, mmp_size; 48 s32 i = 0; 49 u32 max_objs = 1; 50 const char *obj_name = NULL; 51 struct adf_mmp_version_s mmp_ver = { { 0 } }; 52 unsigned int cfg_ae_mask = 0; 53 54 if (!hw_device->fw_name) 55 return 0; 56 57 if (request_firmware(&loader_data->uof_fw, hw_device->fw_name)) { 58 device_printf(GET_DEV(accel_dev), 59 "Failed to load UOF FW %s\n", 60 hw_device->fw_name); 61 goto out_err; 62 } 63 64 if (request_firmware(&loader_data->mmp_fw, hw_device->fw_mmp_name)) { 65 device_printf(GET_DEV(accel_dev), 66 "Failed to load MMP FW %s\n", 67 hw_device->fw_mmp_name); 68 goto out_err; 69 } 70 71 fw_size = loader_data->uof_fw->datasize; 72 fw_addr = loader_data->uof_fw->data; 73 mmp_size = loader_data->mmp_fw->datasize; 74 mmp_addr = loader_data->mmp_fw->data; 75 76 memcpy(&mmp_ver, mmp_addr, MMP_VERSION_LEN); 77 78 accel_dev->fw_versions.mmp_version_major = mmp_ver.ver_val[0]; 79 accel_dev->fw_versions.mmp_version_minor = mmp_ver.ver_val[1]; 80 accel_dev->fw_versions.mmp_version_patch = mmp_ver.ver_val[2]; 81 82 if (hw_device->accel_capabilities_mask & 83 ADF_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC) 84 if (qat_uclo_wr_mimage(loader_data->fw_loader, 85 mmp_addr, 86 mmp_size)) { 87 device_printf(GET_DEV(accel_dev), 88 "Failed to load MMP\n"); 89 goto out_err; 90 } 91 92 if (hw_device->get_objs_num) 93 max_objs = hw_device->get_objs_num(accel_dev); 94 95 for (i = max_objs - 1; i >= 0; i--) { 96 /* obj_name is used to indicate the firmware name in MOF, 97 * config unit0 must be loaded at end for authentication 98 */ 99 if (hw_device->get_obj_name && hw_device->get_obj_cfg_ae_mask) { 100 unsigned long service_mask = hw_device->service_mask; 101 enum adf_accel_unit_services service_type = 102 ADF_ACCEL_SERVICE_NULL; 103 104 if (hw_device->get_service_type) 105 service_type = 106 hw_device->get_service_type(accel_dev, i); 107 else 108 service_type = BIT(i); 109 110 if (service_mask && !(service_mask & service_type)) 111 continue; 112 113 obj_name = 114 hw_device->get_obj_name(accel_dev, service_type); 115 cfg_ae_mask = 116 hw_device->get_obj_cfg_ae_mask(accel_dev, 117 service_type); 118 119 if (!obj_name) { 120 device_printf( 121 GET_DEV(accel_dev), 122 "Invalid object (service = %lx)\n", 123 BIT(i)); 124 goto out_err; 125 } 126 if (!cfg_ae_mask) 127 continue; 128 if (qat_uclo_set_cfg_ae_mask(loader_data->fw_loader, 129 cfg_ae_mask)) { 130 device_printf(GET_DEV(accel_dev), 131 "Invalid config AE mask\n"); 132 goto out_err; 133 } 134 } 135 136 if (qat_uclo_map_obj( 137 loader_data->fw_loader, fw_addr, fw_size, obj_name)) { 138 device_printf(GET_DEV(accel_dev), 139 "Failed to map UOF firmware\n"); 140 goto out_err; 141 } 142 if (qat_uclo_wr_all_uimage(loader_data->fw_loader)) { 143 device_printf(GET_DEV(accel_dev), 144 "Failed to load UOF firmware\n"); 145 goto out_err; 146 } 147 qat_uclo_del_obj(loader_data->fw_loader); 148 obj_name = NULL; 149 } 150 151 return 0; 152 153 out_err: 154 adf_ae_fw_release(accel_dev); 155 return EFAULT; 156 } 157 158 void 159 adf_ae_fw_release(struct adf_accel_dev *accel_dev) 160 { 161 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 162 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 163 164 if (!hw_device->fw_name) 165 return; 166 if (loader_data->fw_loader) 167 qat_uclo_del_obj(loader_data->fw_loader); 168 if (loader_data->fw_loader && loader_data->fw_loader->mobj_handle) 169 qat_uclo_del_mof(loader_data->fw_loader); 170 qat_hal_deinit(loader_data->fw_loader); 171 if (loader_data->uof_fw) 172 firmware_put(loader_data->uof_fw, FIRMWARE_UNLOAD); 173 if (loader_data->mmp_fw) 174 firmware_put(loader_data->mmp_fw, FIRMWARE_UNLOAD); 175 loader_data->uof_fw = NULL; 176 loader_data->mmp_fw = NULL; 177 loader_data->fw_loader = NULL; 178 } 179 180 int 181 adf_ae_start(struct adf_accel_dev *accel_dev) 182 { 183 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 184 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 185 uint32_t ae_ctr; 186 187 if (!hw_data->fw_name) 188 return 0; 189 190 ae_ctr = qat_hal_start(loader_data->fw_loader); 191 device_printf(GET_DEV(accel_dev), 192 "qat_dev%d started %d acceleration engines\n", 193 accel_dev->accel_id, 194 ae_ctr); 195 return 0; 196 } 197 198 int 199 adf_ae_stop(struct adf_accel_dev *accel_dev) 200 { 201 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 202 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 203 uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev); 204 205 if (!hw_data->fw_name) 206 return 0; 207 208 for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) { 209 if (hw_data->ae_mask & (1 << ae)) { 210 qat_hal_stop(loader_data->fw_loader, ae, 0xFF); 211 ae_ctr++; 212 } 213 } 214 device_printf(GET_DEV(accel_dev), 215 "qat_dev%d stopped %d acceleration engines\n", 216 accel_dev->accel_id, 217 ae_ctr); 218 return 0; 219 } 220 221 static int 222 adf_ae_reset(struct adf_accel_dev *accel_dev, int ae) 223 { 224 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 225 226 qat_hal_reset(loader_data->fw_loader); 227 if (qat_hal_clr_reset(loader_data->fw_loader)) 228 return EFAULT; 229 230 return 0; 231 } 232 233 int 234 adf_ae_init(struct adf_accel_dev *accel_dev) 235 { 236 struct adf_fw_loader_data *loader_data; 237 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 238 239 if (!hw_device->fw_name) 240 return 0; 241 242 loader_data = malloc(sizeof(*loader_data), M_QAT, M_WAITOK | M_ZERO); 243 244 accel_dev->fw_loader = loader_data; 245 if (qat_hal_init(accel_dev)) { 246 device_printf(GET_DEV(accel_dev), "Failed to init the AEs\n"); 247 free(loader_data, M_QAT); 248 return EFAULT; 249 } 250 if (adf_ae_reset(accel_dev, 0)) { 251 device_printf(GET_DEV(accel_dev), "Failed to reset the AEs\n"); 252 qat_hal_deinit(loader_data->fw_loader); 253 free(loader_data, M_QAT); 254 return EFAULT; 255 } 256 return 0; 257 } 258 259 int 260 adf_ae_shutdown(struct adf_accel_dev *accel_dev) 261 { 262 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader; 263 struct adf_hw_device_data *hw_device = accel_dev->hw_device; 264 265 if (!hw_device->fw_name) 266 return 0; 267 268 qat_hal_deinit(loader_data->fw_loader); 269 free(accel_dev->fw_loader, M_QAT); 270 accel_dev->fw_loader = NULL; 271 return 0; 272 } 273