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_api/qat_kernel/src/qat_transport.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_transport_access_macros.h"
    5 #include "adf_transport_internal.h"
    6 
    7 #include "cpa.h"
    8 #include "icp_adf_init.h"
    9 #include "icp_adf_transport.h"
   10 #include "icp_adf_poll.h"
   11 #include "icp_adf_transport_dp.h"
   12 #include "icp_sal_poll.h"
   13 
   14 /*
   15  * adf_modulo
   16  * result = data % ( 2 ^ shift )
   17  */
   18 static inline Cpa32U
   19 adf_modulo(Cpa32U data, Cpa32U shift)
   20 {
   21         Cpa32U div = data >> shift;
   22         Cpa32U mult = div << shift;
   23 
   24         return data - mult;
   25 }
   26 
   27 /*
   28  * icp_adf_transCreateHandle
   29  * crete transport handle for a service
   30  * call adf_create_ring from adf driver directly with same parameters
   31  */
   32 CpaStatus
   33 icp_adf_transCreateHandle(icp_accel_dev_t *adf,
   34                           icp_transport_type trans_type,
   35                           const char *section,
   36                           const uint32_t accel_nr,
   37                           const uint32_t bank_nr,
   38                           const char *service_name,
   39                           const icp_adf_ringInfoService_t info,
   40                           icp_trans_callback callback,
   41                           icp_resp_deliv_method resp,
   42                           const uint32_t num_msgs,
   43                           const uint32_t msg_size,
   44                           icp_comms_trans_handle *trans_handle)
   45 {
   46         CpaStatus status;
   47         int error;
   48 
   49         ICP_CHECK_FOR_NULL_PARAM(trans_handle);
   50         ICP_CHECK_FOR_NULL_PARAM(adf);
   51 
   52         error = adf_create_ring(adf->accel_dev,
   53                                 section,
   54                                 bank_nr,
   55                                 num_msgs,
   56                                 msg_size,
   57                                 service_name,
   58                                 callback,
   59                                 ((resp == ICP_RESP_TYPE_IRQ) ? 0 : 1),
   60                                 (struct adf_etr_ring_data **)trans_handle);
   61         if (!error)
   62                 status = CPA_STATUS_SUCCESS;
   63         else
   64                 status = CPA_STATUS_FAIL;
   65 
   66         return status;
   67 }
   68 
   69 /*
   70  * icp_adf_transReinitHandle
   71  * Reinitialize transport handle for a service
   72  */
   73 CpaStatus
   74 icp_adf_transReinitHandle(icp_accel_dev_t *adf,
   75                           icp_transport_type trans_type,
   76                           const char *section,
   77                           const uint32_t accel_nr,
   78                           const uint32_t bank_nr,
   79                           const char *service_name,
   80                           const icp_adf_ringInfoService_t info,
   81                           icp_trans_callback callback,
   82                           icp_resp_deliv_method resp,
   83                           const uint32_t num_msgs,
   84                           const uint32_t msg_size,
   85                           icp_comms_trans_handle *trans_handle)
   86 {
   87         return CPA_STATUS_SUCCESS;
   88 }
   89 /*
   90  * icp_adf_transReleaseHandle
   91  * destroy a transport handle, call adf_remove_ring from adf driver directly
   92  */
   93 CpaStatus
   94 icp_adf_transReleaseHandle(icp_comms_trans_handle trans_handle)
   95 {
   96         struct adf_etr_ring_data *ring = trans_handle;
   97 
   98         ICP_CHECK_FOR_NULL_PARAM(ring);
   99         adf_remove_ring(ring);
  100 
  101         return CPA_STATUS_SUCCESS;
  102 }
  103 
  104 /*
  105  * icp_adf_transResetHandle
  106  * clean a transport handle, call adf_remove_ring from adf driver directly
  107  */
  108 CpaStatus
  109 icp_adf_transResetHandle(icp_comms_trans_handle trans_handle)
  110 {
  111         return CPA_STATUS_SUCCESS;
  112 }
  113 
  114 /*
  115  * icp_adf_transGetRingNum
  116  * get ring number from a transport handle
  117  */
  118 CpaStatus
  119 icp_adf_transGetRingNum(icp_comms_trans_handle trans_handle, uint32_t *ringNum)
  120 {
  121         struct adf_etr_ring_data *ring = trans_handle;
  122 
  123         ICP_CHECK_FOR_NULL_PARAM(ring);
  124         ICP_CHECK_FOR_NULL_PARAM(ringNum);
  125         *ringNum = (uint32_t)(ring->ring_number);
  126 
  127         return CPA_STATUS_SUCCESS;
  128 }
  129 
  130 /*
  131  * icp_adf_transPutMsg
  132  * send a request to transport handle
  133  * call adf_send_message from adf driver directly
  134  */
  135 CpaStatus
  136 icp_adf_transPutMsg(icp_comms_trans_handle trans_handle,
  137                     uint32_t *inBuf,
  138                     uint32_t bufLen)
  139 {
  140         struct adf_etr_ring_data *ring = trans_handle;
  141         CpaStatus status = CPA_STATUS_FAIL;
  142         int error = EFAULT;
  143 
  144         ICP_CHECK_FOR_NULL_PARAM(ring);
  145 
  146         error = adf_send_message(ring, inBuf);
  147         if (EAGAIN == error)
  148                 status = CPA_STATUS_RETRY;
  149         else if (0 == error)
  150                 status = CPA_STATUS_SUCCESS;
  151         else
  152                 status = CPA_STATUS_FAIL;
  153 
  154         return status;
  155 }
  156 
  157 CpaStatus
  158 icp_adf_getInflightRequests(icp_comms_trans_handle trans_handle,
  159                             Cpa32U *maxInflightRequests,
  160                             Cpa32U *numInflightRequests)
  161 {
  162         struct adf_etr_ring_data *ring = trans_handle;
  163         ICP_CHECK_FOR_NULL_PARAM(ring);
  164         ICP_CHECK_FOR_NULL_PARAM(maxInflightRequests);
  165         ICP_CHECK_FOR_NULL_PARAM(numInflightRequests);
  166         /*
  167          * XXX: The qat_direct version of this routine returns max - 1, not
  168          * the absolute max.
  169          */
  170         *numInflightRequests = (*(uint32_t *)ring->inflights);
  171         *maxInflightRequests =
  172             ADF_MAX_INFLIGHTS(ring->ring_size, ring->msg_size);
  173         return CPA_STATUS_SUCCESS;
  174 }
  175 
  176 CpaStatus
  177 icp_adf_dp_getInflightRequests(icp_comms_trans_handle trans_handle,
  178                                Cpa32U *maxInflightRequests,
  179                                Cpa32U *numInflightRequests)
  180 {
  181         ICP_CHECK_FOR_NULL_PARAM(trans_handle);
  182         ICP_CHECK_FOR_NULL_PARAM(maxInflightRequests);
  183         ICP_CHECK_FOR_NULL_PARAM(numInflightRequests);
  184 
  185         return icp_adf_getInflightRequests(trans_handle,
  186                                            maxInflightRequests,
  187                                            numInflightRequests);
  188 }
  189 
  190 /*
  191  * This function allows the user to poll the response ring. The
  192  * ring number to be polled is supplied by the user via the
  193  * trans handle for that ring. The trans_hnd is a pointer
  194  * to an array of trans handles. This ring is
  195  * only polled if it contains data.
  196  * This method is used as an alternative to the reading messages
  197  * via the ISR method.
  198  * This function will return RETRY if the ring is empty.
  199  */
  200 CpaStatus
  201 icp_adf_pollInstance(icp_comms_trans_handle *trans_hnd,
  202                      Cpa32U num_transHandles,
  203                      Cpa32U response_quota)
  204 {
  205         Cpa32U resp_total = 0;
  206         Cpa32U num_resp;
  207         struct adf_etr_ring_data *ring = NULL;
  208         struct adf_etr_bank_data *bank = NULL;
  209         Cpa32U i;
  210 
  211         ICP_CHECK_FOR_NULL_PARAM(trans_hnd);
  212 
  213         for (i = 0; i < num_transHandles; i++) {
  214                 ring = trans_hnd[i];
  215                 if (!ring)
  216                         continue;
  217                 bank = ring->bank;
  218 
  219                 /* If the ring in question is empty try the next ring.*/
  220                 if (!bank || !bank->ring_mask) {
  221                         continue;
  222                 }
  223 
  224                 num_resp = adf_handle_response(ring, response_quota);
  225                 resp_total += num_resp;
  226         }
  227 
  228         /* If any of the rings in the instance had data and was polled
  229          * return SUCCESS. */
  230         if (resp_total)
  231                 return CPA_STATUS_SUCCESS;
  232         else
  233                 return CPA_STATUS_RETRY;
  234 }
  235 
  236 /*
  237  * This function allows the user to check the response ring. The
  238  * ring number to be polled is supplied by the user via the
  239  * trans handle for that ring. The trans_hnd is a pointer
  240  * to an array of trans handles.
  241  * This function now is a empty function.
  242  */
  243 CpaStatus
  244 icp_adf_check_RespInstance(icp_comms_trans_handle *trans_hnd,
  245                            Cpa32U num_transHandles)
  246 {
  247         return CPA_STATUS_SUCCESS;
  248 }
  249 
  250 /*
  251  * icp_sal_pollBank
  252  * poll bank with id bank_number inside acceleration device with id @accelId
  253  */
  254 CpaStatus
  255 icp_sal_pollBank(Cpa32U accelId, Cpa32U bank_number, Cpa32U response_quota)
  256 {
  257         int ret;
  258 
  259         ret = adf_poll_bank(accelId, bank_number, response_quota);
  260         if (!ret)
  261                 return CPA_STATUS_SUCCESS;
  262         else if (EAGAIN == ret)
  263                 return CPA_STATUS_RETRY;
  264 
  265         return CPA_STATUS_FAIL;
  266 }
  267 
  268 /*
  269  * icp_sal_pollAllBanks
  270  * poll all banks inside acceleration device with id @accelId
  271  */
  272 CpaStatus
  273 icp_sal_pollAllBanks(Cpa32U accelId, Cpa32U response_quota)
  274 {
  275         int ret = 0;
  276 
  277         ret = adf_poll_all_banks(accelId, response_quota);
  278         if (!ret)
  279                 return CPA_STATUS_SUCCESS;
  280         else if (ret == EAGAIN)
  281                 return CPA_STATUS_RETRY;
  282 
  283         return CPA_STATUS_FAIL;
  284 }
  285 
  286 /*
  287  * icp_adf_getQueueMemory
  288  * Data plane support function - returns the pointer to next message on the ring
  289  * or NULL if there is not enough space.
  290  */
  291 void
  292 icp_adf_getQueueMemory(icp_comms_trans_handle trans_handle,
  293                        Cpa32U numberRequests,
  294                        void **pCurrentQatMsg)
  295 {
  296         struct adf_etr_ring_data *ring = trans_handle;
  297         Cpa64U flight;
  298 
  299         ICP_CHECK_FOR_NULL_PARAM_VOID(ring);
  300 
  301         /* Check if there is enough space in the ring */
  302         flight = atomic_add_return(numberRequests, ring->inflights);
  303         if (flight > ADF_MAX_INFLIGHTS(ring->ring_size, ring->msg_size)) {
  304                 atomic_sub(numberRequests, ring->inflights);
  305                 *pCurrentQatMsg = NULL;
  306                 return;
  307         }
  308 
  309         /* We have enough space - get the address of next message */
  310         *pCurrentQatMsg = (void *)((uintptr_t)ring->base_addr + ring->tail);
  311 }
  312 
  313 /*
  314  * icp_adf_getSingleQueueAddr
  315  * Data plane support function - returns the pointer to next message on the ring
  316  * or NULL if there is not enough space - it also updates the shadow tail copy.
  317  */
  318 void
  319 icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_handle,
  320                            void **pCurrentQatMsg)
  321 {
  322         struct adf_etr_ring_data *ring = trans_handle;
  323         Cpa64U flight;
  324 
  325         ICP_CHECK_FOR_NULL_PARAM_VOID(ring);
  326         ICP_CHECK_FOR_NULL_PARAM_VOID(pCurrentQatMsg);
  327 
  328         /* Check if there is enough space in the ring */
  329         flight = atomic_add_return(1, ring->inflights);
  330         if (flight > ADF_MAX_INFLIGHTS(ring->ring_size, ring->msg_size)) {
  331                 atomic_dec(ring->inflights);
  332                 *pCurrentQatMsg = NULL;
  333                 return;
  334         }
  335 
  336         /* We have enough space - get the address of next message */
  337         *pCurrentQatMsg = (void *)((uintptr_t)ring->base_addr + ring->tail);
  338 
  339         /* Update the shadow tail */
  340         ring->tail =
  341             adf_modulo(ring->tail + ADF_MSG_SIZE_TO_BYTES(ring->msg_size),
  342                        ADF_RING_SIZE_MODULO(ring->ring_size));
  343 }
  344 
  345 /*
  346  * icp_adf_getQueueNext
  347  * Data plane support function - increments the tail pointer and returns
  348  * the pointer to next message on the ring.
  349  */
  350 void
  351 icp_adf_getQueueNext(icp_comms_trans_handle trans_handle, void **pCurrentQatMsg)
  352 {
  353         struct adf_etr_ring_data *ring = trans_handle;
  354 
  355         ICP_CHECK_FOR_NULL_PARAM_VOID(ring);
  356         ICP_CHECK_FOR_NULL_PARAM_VOID(pCurrentQatMsg);
  357 
  358         /* Increment tail to next message */
  359         ring->tail =
  360             adf_modulo(ring->tail + ADF_MSG_SIZE_TO_BYTES(ring->msg_size),
  361                        ADF_RING_SIZE_MODULO(ring->ring_size));
  362 
  363         /* Get the address of next message */
  364         *pCurrentQatMsg = (void *)((uintptr_t)ring->base_addr + ring->tail);
  365 }
  366 
  367 /*
  368  * icp_adf_updateQueueTail
  369  * Data plane support function - Writes the tail shadow copy to the device.
  370  */
  371 void
  372 icp_adf_updateQueueTail(icp_comms_trans_handle trans_handle)
  373 {
  374         struct adf_etr_ring_data *ring = trans_handle;
  375         struct adf_hw_csr_ops *csr_ops;
  376 
  377         ICP_CHECK_FOR_NULL_PARAM_VOID(ring);
  378         ICP_CHECK_FOR_NULL_PARAM_VOID(ring->bank);
  379         ICP_CHECK_FOR_NULL_PARAM_VOID(ring->bank->accel_dev);
  380 
  381         csr_ops = GET_CSR_OPS(ring->bank->accel_dev);
  382 
  383         ICP_CHECK_FOR_NULL_PARAM_VOID(csr_ops);
  384 
  385         csr_ops->write_csr_ring_tail(ring->bank->csr_addr,
  386                                      ring->bank->bank_number,
  387                                      ring->ring_number,
  388                                      ring->tail);
  389         ring->csr_tail_offset = ring->tail;
  390 }
  391 
  392 /*
  393  * icp_adf_pollQueue
  394  * Data plane support function - Poll messages from the queue.
  395  */
  396 CpaStatus
  397 icp_adf_pollQueue(icp_comms_trans_handle trans_handle, Cpa32U response_quota)
  398 {
  399         Cpa32U num_resp;
  400         struct adf_etr_ring_data *ring = trans_handle;
  401 
  402         ICP_CHECK_FOR_NULL_PARAM(ring);
  403 
  404         num_resp = adf_handle_response(ring, response_quota);
  405 
  406         if (num_resp)
  407                 return CPA_STATUS_SUCCESS;
  408         else
  409                 return CPA_STATUS_RETRY;
  410 }
  411 
  412 /*
  413  * icp_adf_queueDataToSend
  414  * Data-plane support function - Indicates if there is data on the ring to be
  415  * sent. This should only be called on request rings. If the function returns
  416  * true then it is ok to call icp_adf_updateQueueTail() function on this ring.
  417  */
  418 CpaBoolean
  419 icp_adf_queueDataToSend(icp_comms_trans_handle trans_handle)
  420 {
  421         struct adf_etr_ring_data *ring = trans_handle;
  422 
  423         if (ring->tail != ring->csr_tail_offset)
  424                 return CPA_TRUE;
  425         else
  426                 return CPA_FALSE;
  427 }
  428 
  429 /*
  430  * This icp API won't be supported in kernel space currently
  431  */
  432 CpaStatus
  433 icp_adf_transGetFdForHandle(icp_comms_trans_handle trans_hnd, int *fd)
  434 {
  435         return CPA_STATUS_UNSUPPORTED;
  436 }

Cache object: 8aec99b976f061d2854f9f6e4b5b13ff


[ 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.