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