1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 #include "adf_cfg_bundle.h" 4 #include "adf_cfg_strings.h" 5 #include "adf_cfg_instance.h" 6 #include <sys/cpuset.h> 7 8 static bool 9 adf_cfg_is_interrupt_mode(struct adf_cfg_bundle *bundle) 10 { 11 return (bundle->polling_mode == ADF_CFG_RESP_EPOLL) || 12 (bundle->type == KERNEL && 13 (bundle->polling_mode != ADF_CFG_RESP_POLL)); 14 } 15 16 static bool 17 adf_cfg_can_be_shared(struct adf_cfg_bundle *bundle, 18 const char *process_name, 19 int polling_mode) 20 { 21 if (adf_cfg_is_free(bundle)) 22 return true; 23 24 if (bundle->polling_mode != polling_mode) 25 return false; 26 27 return !adf_cfg_is_interrupt_mode(bundle) || 28 !strncmp(process_name, 29 bundle->sections[0], 30 ADF_CFG_MAX_SECTION_LEN_IN_BYTES); 31 } 32 33 bool 34 adf_cfg_is_free(struct adf_cfg_bundle *bundle) 35 { 36 return bundle->type == FREE; 37 } 38 39 struct adf_cfg_instance * 40 adf_cfg_get_free_instance(struct adf_cfg_device *device, 41 struct adf_cfg_bundle *bundle, 42 struct adf_cfg_instance *inst, 43 const char *process_name) 44 { 45 int i = 0; 46 struct adf_cfg_instance *ret_instance = NULL; 47 48 if (adf_cfg_can_be_shared(bundle, process_name, inst->polling_mode)) { 49 for (i = 0; i < device->instance_index; i++) { 50 /* 51 * the selected instance must match two criteria 52 * 1) instance is from the bundle 53 * 2) instance type is same 54 */ 55 if (bundle->number == device->instances[i]->bundle && 56 inst->stype == device->instances[i]->stype) { 57 ret_instance = device->instances[i]; 58 break; 59 } 60 /* 61 * no opportunity to match, 62 * quit the loop as early as possible 63 */ 64 if ((bundle->number + 1) == 65 device->instances[i]->bundle) 66 break; 67 } 68 } 69 70 return ret_instance; 71 } 72 73 int 74 adf_cfg_get_ring_pairs_from_bundle(struct adf_cfg_bundle *bundle, 75 struct adf_cfg_instance *inst, 76 const char *process_name, 77 struct adf_cfg_instance *bundle_inst) 78 { 79 if (inst->polling_mode == ADF_CFG_RESP_POLL && 80 adf_cfg_is_interrupt_mode(bundle)) { 81 pr_err("Trying to get ring pairs for a non-interrupt"); 82 pr_err(" bundle from an interrupt bundle\n"); 83 return EFAULT; 84 } 85 86 if (inst->stype != bundle_inst->stype) { 87 pr_err("Got an instance of different type (cy/dc) than the"); 88 pr_err(" one request\n"); 89 return EFAULT; 90 } 91 92 if (strcmp(ADF_KERNEL_SEC, process_name) && 93 strcmp(ADF_KERNEL_SAL_SEC, process_name) && 94 inst->polling_mode != ADF_CFG_RESP_EPOLL && 95 inst->polling_mode != ADF_CFG_RESP_POLL) { 96 pr_err("User instance %s needs to be configured", inst->name); 97 pr_err(" with IsPolled 1 or 2 for poll and epoll mode,"); 98 pr_err(" respectively\n"); 99 return EFAULT; 100 } 101 102 strlcpy(bundle->sections[bundle->section_index], 103 process_name, 104 ADF_CFG_MAX_STR_LEN); 105 bundle->section_index++; 106 107 if (adf_cfg_is_free(bundle)) { 108 bundle->polling_mode = inst->polling_mode; 109 bundle->type = (!strcmp(ADF_KERNEL_SEC, process_name) || 110 !strcmp(ADF_KERNEL_SAL_SEC, process_name)) ? 111 KERNEL : 112 USER; 113 if (adf_cfg_is_interrupt_mode(bundle)) { 114 CPU_ZERO(&bundle->affinity_mask); 115 CPU_COPY(&inst->affinity_mask, &bundle->affinity_mask); 116 } 117 } 118 119 switch (inst->stype) { 120 case CRYPTO: 121 inst->asym_tx = bundle_inst->asym_tx; 122 inst->asym_rx = bundle_inst->asym_rx; 123 inst->sym_tx = bundle_inst->sym_tx; 124 inst->sym_rx = bundle_inst->sym_rx; 125 break; 126 case COMP: 127 inst->dc_tx = bundle_inst->dc_tx; 128 inst->dc_rx = bundle_inst->dc_rx; 129 break; 130 case ASYM: 131 inst->asym_tx = bundle_inst->asym_tx; 132 inst->asym_rx = bundle_inst->asym_rx; 133 break; 134 case SYM: 135 inst->sym_tx = bundle_inst->sym_tx; 136 inst->sym_rx = bundle_inst->sym_rx; 137 break; 138 default: 139 /* unknown service type of instance */ 140 pr_err("1 Unknown service type %d of instance\n", inst->stype); 141 } 142 143 /* mark it as used */ 144 bundle_inst->stype = USED; 145 146 inst->bundle = bundle->number; 147 148 return 0; 149 } 150 151 static void 152 adf_cfg_init_and_insert_inst(struct adf_cfg_bundle *bundle, 153 struct adf_cfg_device *device, 154 int bank_num, 155 struct adf_accel_dev *accel_dev) 156 { 157 struct adf_cfg_instance *cfg_instance = NULL; 158 int ring_pair_index = 0; 159 int ring_index = 0; 160 int i = 0; 161 u8 serv_type; 162 int num_rings_per_srv = 0; 163 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 164 u16 ring_to_svc_map = GET_HW_DATA(accel_dev)->ring_to_svc_map; 165 166 /* init the bundle with instance information */ 167 for (ring_pair_index = 0; ring_pair_index < bundle->max_cfg_svc_num; 168 ring_pair_index++) { 169 adf_get_ring_svc_map_data(hw_data, 170 bundle->number, 171 ring_pair_index, 172 &serv_type, 173 &ring_index, 174 &num_rings_per_srv); 175 176 for (i = 0; i < num_rings_per_srv; i++) { 177 cfg_instance = malloc(sizeof(*cfg_instance), 178 M_QAT, 179 M_WAITOK | M_ZERO); 180 181 switch (serv_type) { 182 case CRYPTO: 183 crypto_instance_init(cfg_instance, bundle); 184 break; 185 case COMP: 186 dc_instance_init(cfg_instance, bundle); 187 break; 188 case ASYM: 189 asym_instance_init(cfg_instance, bundle); 190 break; 191 case SYM: 192 sym_instance_init(cfg_instance, bundle); 193 break; 194 case NA: 195 break; 196 197 default: 198 /* Unknown service type */ 199 device_printf( 200 GET_DEV(accel_dev), 201 "Unknown service type %d of instance, mask is 0x%x\n", 202 serv_type, 203 ring_to_svc_map); 204 } 205 cfg_instance->bundle = bank_num; 206 device->instances[device->instance_index++] = 207 cfg_instance; 208 cfg_instance = NULL; 209 } 210 if (serv_type == CRYPTO) { 211 ring_pair_index++; 212 serv_type = 213 GET_SRV_TYPE(ring_to_svc_map, ring_pair_index); 214 } 215 } 216 217 return; 218 } 219 220 int 221 adf_cfg_bundle_init(struct adf_cfg_bundle *bundle, 222 struct adf_cfg_device *device, 223 int bank_num, 224 struct adf_accel_dev *accel_dev) 225 { 226 int i = 0; 227 228 bundle->number = bank_num; 229 /* init ring to service mapping for this bundle */ 230 adf_cfg_init_ring2serv_mapping(accel_dev, bundle, device); 231 232 /* init the bundle with instance information */ 233 adf_cfg_init_and_insert_inst(bundle, device, bank_num, accel_dev); 234 235 CPU_FILL(&bundle->affinity_mask); 236 bundle->type = FREE; 237 bundle->polling_mode = -1; 238 bundle->section_index = 0; 239 240 bundle->sections = malloc(sizeof(char *) * bundle->max_section, 241 M_QAT, 242 M_WAITOK | M_ZERO); 243 244 for (i = 0; i < bundle->max_section; i++) { 245 bundle->sections[i] = 246 malloc(ADF_CFG_MAX_STR_LEN, M_QAT, M_WAITOK | M_ZERO); 247 } 248 return 0; 249 } 250 251 void 252 adf_cfg_bundle_clear(struct adf_cfg_bundle *bundle, 253 struct adf_accel_dev *accel_dev) 254 { 255 int i = 0; 256 257 for (i = 0; i < bundle->max_section; i++) { 258 if (bundle->sections && bundle->sections[i]) { 259 free(bundle->sections[i], M_QAT); 260 bundle->sections[i] = NULL; 261 } 262 } 263 264 free(bundle->sections, M_QAT); 265 bundle->sections = NULL; 266 267 adf_cfg_rel_ring2serv_mapping(bundle); 268 } 269 270 static void 271 adf_cfg_assign_serv_to_rings(struct adf_hw_device_data *hw_data, 272 struct adf_cfg_bundle *bundle, 273 struct adf_cfg_device *device) 274 { 275 int ring_pair_index = 0; 276 int ring_index = 0; 277 u8 serv_type = 0; 278 int num_req_rings = bundle->num_of_rings / 2; 279 int num_rings_per_srv = 0; 280 281 for (ring_pair_index = 0; ring_pair_index < bundle->max_cfg_svc_num; 282 ring_pair_index++) { 283 adf_get_ring_svc_map_data(hw_data, 284 bundle->number, 285 ring_pair_index, 286 &serv_type, 287 &ring_index, 288 &num_rings_per_srv); 289 290 switch (serv_type) { 291 case CRYPTO: 292 ASSIGN_SERV_TO_RINGS(bundle, 293 ring_index, 294 num_req_rings, 295 ADF_ACCEL_SERV_ASYM, 296 num_rings_per_srv); 297 ring_pair_index++; 298 ring_index = num_rings_per_srv * ring_pair_index; 299 if (ring_pair_index == bundle->max_cfg_svc_num) 300 break; 301 ASSIGN_SERV_TO_RINGS(bundle, 302 ring_index, 303 num_req_rings, 304 ADF_ACCEL_SERV_SYM, 305 num_rings_per_srv); 306 break; 307 case COMP: 308 ASSIGN_SERV_TO_RINGS(bundle, 309 ring_index, 310 num_req_rings, 311 ADF_ACCEL_SERV_DC, 312 num_rings_per_srv); 313 break; 314 case SYM: 315 ASSIGN_SERV_TO_RINGS(bundle, 316 ring_index, 317 num_req_rings, 318 ADF_ACCEL_SERV_SYM, 319 num_rings_per_srv); 320 break; 321 case ASYM: 322 ASSIGN_SERV_TO_RINGS(bundle, 323 ring_index, 324 num_req_rings, 325 ADF_ACCEL_SERV_ASYM, 326 num_rings_per_srv); 327 break; 328 case NA: 329 ASSIGN_SERV_TO_RINGS(bundle, 330 ring_index, 331 num_req_rings, 332 ADF_ACCEL_SERV_NA, 333 num_rings_per_srv); 334 break; 335 336 default: 337 /* unknown service type */ 338 pr_err("Unknown service type %d, mask 0x%x.\n", 339 serv_type, 340 hw_data->ring_to_svc_map); 341 } 342 } 343 344 return; 345 } 346 347 void 348 adf_cfg_init_ring2serv_mapping(struct adf_accel_dev *accel_dev, 349 struct adf_cfg_bundle *bundle, 350 struct adf_cfg_device *device) 351 { 352 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 353 struct adf_cfg_ring *ring_in_bundle; 354 int ring_num = 0; 355 356 bundle->num_of_rings = hw_data->num_rings_per_bank; 357 if (hw_data->num_rings_per_bank >= (2 * ADF_CFG_NUM_SERVICES)) 358 bundle->max_cfg_svc_num = ADF_CFG_NUM_SERVICES; 359 else 360 bundle->max_cfg_svc_num = 1; 361 362 bundle->rings = 363 malloc(bundle->num_of_rings * sizeof(struct adf_cfg_ring *), 364 M_QAT, 365 M_WAITOK | M_ZERO); 366 367 for (ring_num = 0; ring_num < bundle->num_of_rings; ring_num++) { 368 ring_in_bundle = malloc(sizeof(struct adf_cfg_ring), 369 M_QAT, 370 M_WAITOK | M_ZERO); 371 ring_in_bundle->mode = 372 (ring_num < bundle->num_of_rings / 2) ? TX : RX; 373 ring_in_bundle->number = ring_num; 374 bundle->rings[ring_num] = ring_in_bundle; 375 } 376 377 adf_cfg_assign_serv_to_rings(hw_data, bundle, device); 378 379 return; 380 } 381 382 int 383 adf_cfg_rel_ring2serv_mapping(struct adf_cfg_bundle *bundle) 384 { 385 int i = 0; 386 387 if (bundle->rings) { 388 for (i = 0; i < bundle->num_of_rings; i++) 389 free(bundle->rings[i], M_QAT); 390 391 free(bundle->rings, M_QAT); 392 } 393 394 return 0; 395 } 396