The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qat/qat_common/adf_cfg_bundle.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 }

Cache object: 1d8c868a894ff83377d73683c45f784d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.