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 i = 0; 161 u8 serv_type; 162 int num_req_rings = bundle->num_of_rings / 2; 163 int num_rings_per_srv = num_req_rings / ADF_CFG_NUM_SERVICES; 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 < ADF_CFG_NUM_SERVICES; 168 ring_pair_index++) { 169 serv_type = GET_SRV_TYPE(ring_to_svc_map, ring_pair_index); 170 for (i = 0; i < num_rings_per_srv; i++) { 171 cfg_instance = malloc(sizeof(*cfg_instance), 172 M_QAT, 173 M_WAITOK | M_ZERO); 174 175 switch (serv_type) { 176 case CRYPTO: 177 crypto_instance_init(cfg_instance, bundle); 178 break; 179 case COMP: 180 dc_instance_init(cfg_instance, bundle); 181 break; 182 case ASYM: 183 asym_instance_init(cfg_instance, bundle); 184 break; 185 case SYM: 186 sym_instance_init(cfg_instance, bundle); 187 break; 188 case NA: 189 break; 190 191 default: 192 /* Unknown service type */ 193 device_printf( 194 GET_DEV(accel_dev), 195 "Unknown service type %d of instance, mask is 0x%x\n", 196 serv_type, 197 ring_to_svc_map); 198 } 199 cfg_instance->bundle = bank_num; 200 device->instances[device->instance_index++] = 201 cfg_instance; 202 cfg_instance = NULL; 203 } 204 if (serv_type == CRYPTO) { 205 ring_pair_index++; 206 serv_type = 207 GET_SRV_TYPE(ring_to_svc_map, ring_pair_index); 208 } 209 } 210 211 return; 212 } 213 214 int 215 adf_cfg_bundle_init(struct adf_cfg_bundle *bundle, 216 struct adf_cfg_device *device, 217 int bank_num, 218 struct adf_accel_dev *accel_dev) 219 { 220 int i = 0; 221 222 /* init ring to service mapping for this bundle */ 223 adf_cfg_init_ring2serv_mapping(accel_dev, bundle); 224 225 /* init the bundle with instance information */ 226 adf_cfg_init_and_insert_inst(bundle, device, bank_num, accel_dev); 227 228 CPU_FILL(&bundle->affinity_mask); 229 bundle->type = FREE; 230 bundle->polling_mode = -1; 231 bundle->section_index = 0; 232 bundle->number = bank_num; 233 234 bundle->sections = malloc(sizeof(char *) * bundle->max_section, 235 M_QAT, 236 M_WAITOK | M_ZERO); 237 238 for (i = 0; i < bundle->max_section; i++) { 239 bundle->sections[i] = 240 malloc(ADF_CFG_MAX_STR_LEN, M_QAT, M_WAITOK | M_ZERO); 241 } 242 return 0; 243 } 244 245 void 246 adf_cfg_bundle_clear(struct adf_cfg_bundle *bundle, 247 struct adf_accel_dev *accel_dev) 248 { 249 int i = 0; 250 251 for (i = 0; i < bundle->max_section; i++) { 252 if (bundle->sections && bundle->sections[i]) { 253 free(bundle->sections[i], M_QAT); 254 bundle->sections[i] = NULL; 255 } 256 } 257 258 free(bundle->sections, M_QAT); 259 bundle->sections = NULL; 260 261 adf_cfg_rel_ring2serv_mapping(bundle); 262 } 263 264 static void 265 adf_cfg_assign_serv_to_rings(struct adf_cfg_bundle *bundle, u16 ring_to_svc_map) 266 { 267 int ring_pair_index = 0; 268 int ring_index = 0; 269 u8 serv_type = 0; 270 int num_req_rings = bundle->num_of_rings / 2; 271 int num_rings_per_srv = num_req_rings / ADF_CFG_NUM_SERVICES; 272 273 for (ring_pair_index = 0; ring_pair_index < ADF_CFG_NUM_SERVICES; 274 ring_pair_index++) { 275 serv_type = GET_SRV_TYPE(ring_to_svc_map, ring_pair_index); 276 ring_index = num_rings_per_srv * ring_pair_index; 277 switch (serv_type) { 278 case CRYPTO: 279 ASSIGN_SERV_TO_RINGS(bundle, 280 ring_index, 281 num_req_rings, 282 ADF_ACCEL_SERV_ASYM, 283 num_rings_per_srv); 284 ring_pair_index++; 285 ring_index = num_rings_per_srv * ring_pair_index; 286 if (ring_pair_index == ADF_CFG_NUM_SERVICES) 287 break; 288 ASSIGN_SERV_TO_RINGS(bundle, 289 ring_index, 290 num_req_rings, 291 ADF_ACCEL_SERV_SYM, 292 num_rings_per_srv); 293 break; 294 case COMP: 295 ASSIGN_SERV_TO_RINGS(bundle, 296 ring_index, 297 num_req_rings, 298 ADF_ACCEL_SERV_DC, 299 num_rings_per_srv); 300 break; 301 case SYM: 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 ASYM: 309 ASSIGN_SERV_TO_RINGS(bundle, 310 ring_index, 311 num_req_rings, 312 ADF_ACCEL_SERV_ASYM, 313 num_rings_per_srv); 314 break; 315 case NA: 316 ASSIGN_SERV_TO_RINGS(bundle, 317 ring_index, 318 num_req_rings, 319 ADF_ACCEL_SERV_NA, 320 num_rings_per_srv); 321 break; 322 323 default: 324 /* unknown service type */ 325 pr_err("Unknown service type %d, mask 0x%x.\n", 326 serv_type, 327 ring_to_svc_map); 328 } 329 } 330 331 return; 332 } 333 334 void 335 adf_cfg_init_ring2serv_mapping(struct adf_accel_dev *accel_dev, 336 struct adf_cfg_bundle *bundle) 337 { 338 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 339 struct adf_cfg_ring *ring_in_bundle; 340 int ring_num = 0; 341 342 bundle->num_of_rings = hw_data->num_rings_per_bank; 343 344 bundle->rings = 345 malloc(bundle->num_of_rings * sizeof(struct adf_cfg_ring *), 346 M_QAT, 347 M_WAITOK | M_ZERO); 348 349 for (ring_num = 0; ring_num < bundle->num_of_rings; ring_num++) { 350 ring_in_bundle = malloc(sizeof(struct adf_cfg_ring), 351 M_QAT, 352 M_WAITOK | M_ZERO); 353 ring_in_bundle->mode = 354 (ring_num < bundle->num_of_rings / 2) ? TX : RX; 355 ring_in_bundle->number = ring_num; 356 bundle->rings[ring_num] = ring_in_bundle; 357 } 358 359 adf_cfg_assign_serv_to_rings(bundle, hw_data->ring_to_svc_map); 360 361 return; 362 } 363 364 int 365 adf_cfg_rel_ring2serv_mapping(struct adf_cfg_bundle *bundle) 366 { 367 int i = 0; 368 369 if (bundle->rings) { 370 for (i = 0; i < bundle->num_of_rings; i++) 371 free(bundle->rings[i], M_QAT); 372 373 free(bundle->rings, M_QAT); 374 } 375 376 return 0; 377 } 378