-----Original Message----- > Date: Tue, 24 Apr 2018 18:13:27 +0530 > From: Abhinandan Gujjar <abhinandan.guj...@intel.com> > To: jerin.ja...@caviumnetworks.com, hemant.agra...@nxp.com, > akhil.go...@nxp.com, dev@dpdk.org > CC: narender.vang...@intel.com, abhinandan.guj...@intel.com, > nikhil....@intel.com, gage.e...@intel.com > Subject: [v2,6/6] doc: add event crypto adapter documentation > X-Mailer: git-send-email 1.9.1 > > Add entries in the programmer's guide, API index, maintainer's file > and release notes for the event crypto adapter. > > Signed-off-by: Abhinandan Gujjar <abhinandan.guj...@intel.com> > --- > + > +The packet flow from cryptodev to the event device can be accomplished > +using both SW and HW based transfer mechanisms. > +The Adapter queries an eventdev PMD to determine which mechanism to be used. > +The adapter uses an EAL service core function for SW based packet transfer > +and uses the eventdev PMD functions to configure HW based packet transfer > +between the cryptodev and the event device. > + > +Crypto adapter uses a new event type called ``RTE_EVENT_TYPE_CRYPTODEV`` > +to indicate the event source. > +
I think, we can add diagrams used in rte_event_crypto_adapter.h with sequence number in SVG format here to make it easier to understand for the end user. > +API Overview > +------------ > + > +This section has a brief introduction to the event crypto adapter APIs. > +The application is expected to create an adapter which is associated with > +a single eventdev, then add cryptodev and queue pair to the adapter instance. > + > +Adapter can be started in ``RTE_EVENT_CRYPTO_ADAPTER_DEQ_ONLY`` or > +``RTE_EVENT_CRYPTO_ADAPTER_ENQ_DEQ`` mode. > +In first mode, application will submit a crypto operation directly to > cryptodev. > +In the second mode, application will send a crypto ops to cryptodev adapter > +via eventdev. The cryptodev adapter then submits the crypto operation to the > +crypto device. > + > +Create an adapter instance > +-------------------------- > + > +An adapter instance is created using ``rte_event_crypto_adapter_create()``. > This > +function is called with event device to be associated with the adapter and > port > +configuration for the adapter to setup an event port(if the adapter needs to > use > +a service function). > + > +.. code-block:: c > + > + int err; > + uint8_t dev_id, id; > + struct rte_event_dev_info dev_info; > + struct rte_event_port_conf conf; > + enum rte_event_crypto_adapter_mode mode; > + > + err = rte_event_dev_info_get(id, &dev_info); > + > + conf.new_event_threshold = dev_info.max_num_events; > + conf.dequeue_depth = dev_info.max_event_port_dequeue_depth; > + conf.enqueue_depth = dev_info.max_event_port_enqueue_depth; > + mode = RTE_EVENT_CRYPTO_ADAPTER_ENQ_DEQ; > + err = rte_event_crypto_adapter_create(id, dev_id, &conf, mode); > + > +If the application desires to have finer control of eventdev port allocation > +and setup, it can use the ``rte_event_crypto_adapter_create_ext()`` function. > +The ``rte_event_crypto_adapter_create_ext()`` function is passed as a > callback > +function. The callback function is invoked if the adapter needs to use a > +service function and needs to create an event port for it. The callback is > +expected to fill the ``struct rte_event_crypto_adapter_conf`` structure > +passed to it. > + > +For ENQ-DEQ mode, the event port created by adapter can be retrived using s/retrived/retrieved ? > +``rte_event_crypto_adapter_event_port_get()`` API. > +Application can use this event port to link with event queue on which it > +enqueue events towards the crypto adapter. > + > +.. code-block:: c > + > + uint8_t id, evdev, crypto_ev_port_id, app_qid; > + struct rte_event ev; > + int ret; > + > + ret = rte_event_crypto_adapter_event_port_get(id, &crypto_ev_port_id); > + ret = rte_event_queue_setup(evdev, app_qid, NULL); > + ret = rte_event_port_link(evdev, crypto_ev_port_id, &app_qid, NULL, 1); > + > + /* Fill in event info and update event_ptr with rte_crypto_op */ > + memset(&ev, 0, sizeof(ev)); > + ev.queue_id = app_qid; > + . > + . > + ev.event_ptr = op; > + ret = rte_event_enqueue_burst(evdev, app_ev_port_id, ev, nb_events); > + > + > +Adding queue pair to the adapter instance > +----------------------------------------- > + > +Cryptodev device id and queue pair are created using cryptodev APIs. > +Refer '<http://dpdk.org/doc/guides/prog_guide/cryptodev_lib.html>`_. > + > +.. code-block:: c > + > + struct rte_cryptodev_config conf; > + struct rte_cryptodev_qp_conf qp_conf; > + uint8_t cdev_id = 0; > + uint16_t qp_id = 0; > + > + rte_cryptodev_configure(cdev_id, &conf); > + rte_cryptodev_queue_pair_setup(cdev_id, qp_id, &qp_conf); > + > +These cryptodev id and queue pair are added to the instance using the > +``rte_event_crypto_adapter_queue_pair_add()`` function. > +The same is removed using ``rte_event_crypto_adapter_queue_pair_del()``. > + > +.. code-block:: c > + > + struct rte_event_crypto_queue_pair_conf conf; > + > + rte_event_crypto_adapter_queue_pair_add(id, cdev_id, qp_id, &conf); > + > + > +Querying adapter capabilities > +----------------------------- > + > +The ``rte_event_crypto_adapter_caps_get()`` function allows > +the application to query the adapter capabilities for an eventdev and > cryptodev > +combination. This API provides whether cryptodev and eventdev are connected > using > +internal HW port or not. > + > +.. code-block:: c > + > + rte_event_crypto_adapter_caps_get(dev_id, cdev_id, &cap); > + > + > +Configure the service function > +------------------------------ > + > +If the adapter uses a service function, the application is required to assign > +a service core to the service function as show below. > + > +.. code-block:: c > + > + uint32_t service_id; > + > + if (rte_event_crypto_adapter_service_id_get(id, &service_id) == 0) > + rte_service_map_lcore_set(service_id, CORE_ID); > + > + > +Set event request/response information > +-------------------------------------- > + > +In the ENQ_DEQ mode, the application needs to specify the cryptodev ID > +and queue pair ID (request information) in addition to the event > +information (response information) needed to enqueue an event after > +the crypto operation has completed. The request and response information > +are specified in the ``struct rte_crypto_op`` private data or session's > +private data. I think, we can mention the use of rte_event_crypto_adapter_event_port_get() API here. > + > +In the DEQ mode, the application is required to provide only the > +response information. > + > +The SW adapter or HW PMD uses ``rte_crypto_op::sess_type`` to > +decide whether request/response data is located in the crypto session/ > +crypto security session or at an offset in the ``struct rte_crypto_op``. > +The ``rte_crypto_op::private_data_offset`` is used to locate the request/ > +response in the ``rte_crypto_op``. > + > +For crypto session, ``rte_cryptodev_sym_session_set_private_data()`` API > +will be used to set request/response data. The same data will be obtained > +by ``rte_cryptodev_sym_session_get_private_data()`` API. > + > +For security session, ``rte_security_session_set_private_data()`` API > +will be used to set request/response data. The same data will be obtained > +by ``rte_security_session_get_private_data()`` API. I think, we need to talk about RTE_EVENT_CRYPTO_ADAPTER_CAP_SESSION_PRIVATE_DATA capability here and have check in sample code/common code(please ignore if the check is already present in common code) > + > +For session-less it is mandatory to place the request/response data with > +the ``rte_crypto_op``. > + > +.. code-block:: c > + > + union rte_event_crypto_metadata m_data; > + struct rte_event ev; > + struct rte_crypto_op *op; > + > + /* Allocate & fill op structure */ > + op = rte_crypto_op_alloc(); > + > + memset(&m_data, 0, sizeof(m_data)); > + memset(&ev, 0, sizeof(ev)); > + /* Fill event information and update event_ptr to rte_crypto_op */ > + ev.event_ptr = op; > + > + if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION) { > + /* Copy response information */ > + rte_memcpy(&m_data.response_info, &ev, sizeof(ev)); > + /* Copy request information */ > + m_data.request_info.cdev_id = cdev_id; > + m_data.request_info.queue_pair_id = qp_id; > + /* Call set API to store private data information */ > + rte_cryptodev_sym_session_set_private_data( > + op->sym->session, > + &m_data, > + sizeof(m_data)); > + } if (op->sess_type == RTE_CRYPTO_OP_SESSIONLESS) { > + uint32_t len = IV_OFFSET + MAXIMUM_IV_LENGTH + > + (sizeof(struct rte_crypto_sym_xform) * 2); > + op->private_data_offset = len; > + /* Copy response information */ > + rte_memcpy(&m_data.response_info, &ev, sizeof(ev)); > + /* Copy request information */ > + m_data.request_info.cdev_id = cdev_id; > + m_data.request_info.queue_pair_id = qp_id; > + /* Store private data information along with rte_crypto_op */ > + rte_memcpy(op + len, &m_data, sizeof(m_data)); > + } > +