examples/dpdk-qat: remove app

Remove DPDK QAT sample app, in favour of the newer applications
that use the cryptodev library: ipsec-gw and l2fwd-crypto,
which has support for Intel QuickAssist devices.

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
This commit is contained in:
Pablo de Lara 2017-03-03 16:10:49 +00:00
parent c281019bfb
commit 59c51be41c
14 changed files with 1 additions and 3065 deletions

View File

@ -733,11 +733,6 @@ F: doc/guides/tools/proc_info.rst
Other Example Applications
--------------------------
M: Bruce Richardson <bruce.richardson@intel.com>
M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
F: examples/dpdk_qat/
F: doc/guides/sample_app_ug/intel_quickassist.rst
M: Remy Horton <remy.horton@intel.com>
F: examples/ethtool/
F: doc/guides/sample_app_ug/ethtool.rst

View File

@ -140,7 +140,6 @@ The examples directory contains sample applications that show how libraries can
examples
+-- cmdline # Example of using the cmdline library
+-- dpdk_qat # Sample integration with Intel QuickAssist
+-- exception_path # Sending packets to and from Linux TAP device
+-- helloworld # Basic Hello World example
+-- ip_reassembly # Example showing IP reassembly

View File

@ -423,6 +423,7 @@ Removed Items
* KNI vhost support removed.
* dpdk_qat sample application removed.
Shared Library Versions
-----------------------

View File

@ -61,7 +61,6 @@ Sample Applications User Guides
multi_process
qos_metering
qos_scheduler
intel_quickassist
quota_watermark
timer
packet_ordering
@ -109,8 +108,6 @@ Sample Applications User Guides
:numref:`figure_qos_sched_app_arch` :ref:`figure_qos_sched_app_arch`
:numref:`figure_quickassist_block_diagram` :ref:`figure_quickassist_block_diagram`
:numref:`figure_pipeline_overview` :ref:`figure_pipeline_overview`
:numref:`figure_ring_pipeline_perf_setup` :ref:`figure_ring_pipeline_perf_setup`

View File

@ -1,221 +0,0 @@
.. BSD LICENSE
Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Intel® QuickAssist Technology Sample Application
================================================
This sample application demonstrates the use of the cryptographic operations provided
by the Intel® QuickAssist Technology from within the DPDK environment.
Therefore, building and running this application requires having both the DPDK and
the QuickAssist Technology Software Library installed, as well as at least one
Intel® QuickAssist Technology hardware device present in the system.
For this sample application, there is a dependency on either of:
* Intel® Communications Chipset 8900 to 8920 Series Software for Linux* package
* Intel® Communications Chipset 8925 to 8955 Series Software for Linux* package
Overview
--------
An overview of the application is provided in :numref:`figure_quickassist_block_diagram`.
For simplicity, only two NIC ports and one Intel® QuickAssist Technology device are shown in this diagram,
although the number of NIC ports and Intel® QuickAssist Technology devices can be different.
.. _figure_quickassist_block_diagram:
.. figure:: img/quickassist_block_diagram.*
Intel® QuickAssist Technology Application Block Diagram
The application allows the configuration of the following items:
* Number of NIC ports
* Number of logical cores (lcores)
* Mapping of NIC RX queues to logical cores
Each lcore communicates with every cryptographic acceleration engine in the system through a pair of dedicated input - output queues.
Each lcore has a dedicated NIC TX queue with every NIC port in the system.
Therefore, each lcore reads packets from its NIC RX queues and cryptographic accelerator output queues and
writes packets to its NIC TX queues and cryptographic accelerator input queues.
Each incoming packet that is read from a NIC RX queue is either directly forwarded to its destination NIC TX port (forwarding path)
or first sent to one of the Intel® QuickAssist Technology devices for either encryption or decryption
before being sent out on its destination NIC TX port (cryptographic path).
The application supports IPv4 input packets only.
For each input packet, the decision between the forwarding path and
the cryptographic path is taken at the classification stage based on the value of the IP source address field read from the input packet.
Assuming that the IP source address is A.B.C.D, then if:
* D = 0: the forwarding path is selected (the packet is forwarded out directly)
* D = 1: the cryptographic path for encryption is selected (the packet is first encrypted and then forwarded out)
* D = 2: the cryptographic path for decryption is selected (the packet is first decrypted and then forwarded out)
For the cryptographic path cases (D = 1 or D = 2), byte C specifies the cipher algorithm and
byte B the cryptographic hash algorithm to be used for the current packet.
Byte A is not used and can be any value.
The cipher and cryptographic hash algorithms supported by this application are listed in the crypto.h header file.
For each input packet, the destination NIC TX port is decided at the forwarding stage (executed after the cryptographic stage,
if enabled for the packet) by looking at the RX port index of the dst_ports[ ] array,
which was initialized at startup, being the outport the adjacent enabled port.
For example, if ports 1,3,5 and 6 are enabled, for input port 1, outport port will be 3 and vice versa,
and for input port 5, output port will be 6 and vice versa.
For the cryptographic path, it is the payload of the IPv4 packet that is encrypted or decrypted.
Setup
~~~~~
Building and running this application requires having both the DPDK package and
the QuickAssist Technology Software Library installed,
as well as at least one Intel® QuickAssist Technology hardware device present in the system.
For more details on how to build and run DPDK and Intel® QuickAssist Technology applications,
please refer to the following documents:
* *DPDK Getting Started Guide*
* Intel® Communications Chipset 8900 to 8920 Series Software for Linux* Getting Started Guide (440005)
* Intel® Communications Chipset 8925 to 8955 Series Software for Linux* Getting Started Guide (523128)
For more details on the actual platforms used to validate this application, as well as performance numbers,
please refer to the Test Report, which is accessible by contacting your Intel representative.
Building the Application
------------------------
Steps to build the application:
#. Set up the following environment variables:
.. code-block:: console
export RTE_SDK=<Absolute path to the DPDK installation folder>
export ICP_ROOT=<Absolute path to the Intel QAT installation folder>
#. Set the target (a default target is used if not specified). For example:
.. code-block:: console
export RTE_TARGET=x86_64-native-linuxapp-gcc
Refer to the *DPDK Getting Started Guide* for possible RTE_TARGET values.
#. Build the application:
.. code-block:: console
cd ${RTE_SDK}/examples/dpdk_qat
make
Running the Application
-----------------------
Intel® QuickAssist Technology Configuration Files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Intel® QuickAssist Technology configuration files used by the application are located in the config_files folder in the application folder.
There following sets of configuration files are included in the DPDK package:
* Stargo CRB (single CPU socket): located in the stargo folder
* dh89xxcc_qa_dev0.conf
* Shumway CRB (dual CPU socket): located in the shumway folder
* dh89xxcc_qa_dev0.conf
* dh89xxcc_qa_dev1.conf
* Coleto Creek: located in the coleto folder
* dh895xcc_qa_dev0.conf
The relevant configuration file(s) must be copied to the /etc/ directory.
Please note that any change to these configuration files requires restarting the Intel®
QuickAssist Technology driver using the following command:
.. code-block:: console
# service qat_service restart
Refer to the following documents for information on the Intel® QuickAssist Technology configuration files:
* Intel® Communications Chipset 8900 to 8920 Series Software Programmer's Guide
* Intel® Communications Chipset 8925 to 8955 Series Software Programmer's Guide
* Intel® Communications Chipset 8900 to 8920 Series Software for Linux* Getting Started Guide.
* Intel® Communications Chipset 8925 to 8955 Series Software for Linux* Getting Started Guide.
Traffic Generator Setup and Application Startup
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The application has a number of command line options:
dpdk_qat [EAL options] -- -p PORTMASK [--no-promisc] [--config '(port,queue,lcore)[,(port,queue,lcore)]']
where,
* -p PORTMASK: Hexadecimal bitmask of ports to configure
* --no-promisc: Disables promiscuous mode for all ports,
so that only packets with the Ethernet MAC destination address set to the Ethernet address of the port are accepted.
By default promiscuous mode is enabled so that packets are accepted regardless of the packet's Ethernet MAC destination address.
* --config'(port,queue,lcore)[,(port,queue,lcore)]': determines which queues from which ports are mapped to which cores.
Refer to the :doc:`l3_forward` for more detailed descriptions of the --config command line option.
As an example, to run the application with two ports and two cores,
which are using different Intel® QuickAssist Technology execution engines,
performing AES-CBC-128 encryption with AES-XCBC-MAC-96 hash, the following settings can be used:
* Traffic generator source IP address: 0.9.6.1
* Command line:
.. code-block:: console
./build/dpdk_qat -l 0-7 -n 2 -- -p 0x3 --config '(0,0,1),(1,0,2)'
Refer to the *DPDK Test Report* for more examples of traffic generator setup and the application startup command lines.
If no errors are generated in response to the startup commands, the application is running correctly.

View File

@ -40,9 +40,6 @@ include $(RTE_SDK)/mk/rte.vars.mk
DIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += bond
DIRS-y += cmdline
DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
ifneq ($(ICP_ROOT),)
DIRS-y += dpdk_qat
endif
DIRS-y += ethtool
DIRS-y += exception_path
DIRS-$(CONFIG_RTE_LIBRTE_EFD) += server_node_efd

View File

@ -1,93 +0,0 @@
# BSD LICENSE
#
# Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
ifeq ($(ICP_ROOT),)
$(error "Please define ICP_ROOT environment variable")
endif
# Default target, can be overriden by command line or environment
RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
$(error This application can only operate in a linuxapp environment, \
please change the definition of the RTE_TARGET environment variable)
endif
LBITS := $(shell uname -p)
ifeq ($(CROSS_COMPILE),)
ifneq ($(CONFIG_RTE_ARCH),"x86_64")
ifneq ($(LBITS),i686)
$(error The RTE_TARGET chosen is not compatible with this environment \
(x86_64), for this application. Please change the definition of the \
RTE_TARGET environment variable, or run the application on a i686 OS)
endif
endif
endif
# binary name
APP = dpdk_qat
# all source are stored in SRCS-y
SRCS-y := main.c crypto.c
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
CFLAGS += -I$(ICP_ROOT)/quickassist/include \
-I$(ICP_ROOT)/quickassist/include/lac \
-I$(ICP_ROOT)/quickassist/lookaside/access_layer/include
# From CRF 1.2 driver, library was renamed to libicp_qa_al.a
ifneq ($(wildcard $(ICP_ROOT)/build/icp_qa_al.a),)
ICP_LIBRARY_PATH = $(ICP_ROOT)/build/icp_qa_al.a
else
ICP_LIBRARY_PATH = $(ICP_ROOT)/build/libicp_qa_al.a
endif
LDLIBS += -L$(ICP_ROOT)/build
LDLIBS += $(ICP_LIBRARY_PATH) \
-lz \
-losal \
-ladf_proxy \
-lcrypto
# workaround for a gcc bug with noreturn attribute
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603
ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
CFLAGS_main.o += -Wno-return-type
endif
include $(RTE_SDK)/mk/rte.extapp.mk

View File

@ -1,65 +0,0 @@
[GENERAL]
ServicesEnabled = cy;dc
ConfigVersion = 2
cyHmacAuthMode = 1
dcTotalSRAMAvailable = 0
Firmware_MofPath = dh895xcc/mof_firmware.bin
Firmware_MmpPath = dh895xcc/mmp_firmware.bin
statsGeneral = 1
statsDc = 1
statsDh = 1
statsDrbg = 1
statsDsa = 1
statsEcc = 1
statsKeyGen = 1
statsLn = 1
statsPrime = 1
statsRsa = 1
statsSym = 1
SRIOV_Enabled = 0
ProcDebug = 1
[KERNEL]
NumberCyInstances = 0
NumberDcInstances = 0
[SSL]
NumberCyInstances = 8
NumberDcInstances = 0
NumProcesses = 1
LimitDevAccess = 0
Cy0Name = "SSL0"
Cy0IsPolled = 1
Cy0CoreAffinity = 0
Cy1Name = "SSL1"
Cy1IsPolled = 1
Cy1CoreAffinity = 1
Cy2Name = "SSL2"
Cy2IsPolled = 1
Cy2CoreAffinity = 2
Cy3Name = "SSL3"
Cy3IsPolled = 1
Cy3CoreAffinity = 3
Cy4Name = "SSL4"
Cy4IsPolled = 1
Cy4CoreAffinity = 4
Cy5Name = "SSL5"
Cy5IsPolled = 1
Cy5CoreAffinity = 5
Cy6Name = "SSL6"
Cy6IsPolled = 1
Cy6CoreAffinity = 6
Cy7Name = "SSL7"
Cy7IsPolled = 1
Cy7CoreAffinity = 7

View File

@ -1,293 +0,0 @@
#########################################################################
#
# @par
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #########################################################################
# ########################################################
#
# This file is the configuration for a single dh89xxcc_qa
# device.
#
# Each device has up to two accelerators.
# - The client may load balance between these
# accelerators.
# Each accelerator has 8 independent ring banks.
# - The interrupt for each can be directed to a
# specific core.
# Each ring bank as 16 rings (hardware assisted queues).
#
#########################################################
# General Section
##############################################
[GENERAL]
ServicesEnabled = cy0;cy1
# Use version 2 of the config file
ConfigVersion = 2
# Look Aside Cryptographic Configuration
cyHmacAuthMode = 1
# Look Aside Compression Configuration
dcTotalSRAMAvailable = 0
# Firmware Location Configuration
Firmware_MofPath = mof_firmware.bin
Firmware_MmpPath = mmp_firmware.bin
#Default values for number of concurrent requests*/
CyNumConcurrentSymRequests = 512
CyNumConcurrentAsymRequests = 64
DcNumConcurrentRequests = 512
#Statistics, valid values: 1,0
statsGeneral = 1
statsDc = 1
statsDh = 1
statsDrbg = 1
statsDsa = 1
statsEcc = 1
statsKeyGen = 1
statsLn = 1
statsPrime = 1
statsRsa = 1
statsSym = 1
# Enables or disables Single Root Complex IO Virtualization.
# If this is enabled (1) then SRIOV and VT-d need to be enabled in
# BIOS and there can be no Cy or Dc instances created in PF (Dom0).
# If this i disabled (0) then SRIOV and VT-d need to be disabled
# in BIOS and Cy and/or Dc instances can be used in PF (Dom0)
SRIOV_Enabled = 0
#Debug feature, if set to 1 it enables additional entries in /proc filesystem
ProcDebug = 1
#######################################################
#
# Logical Instances Section
# A logical instance allows each address domain
# (kernel space and individual user space processes)
# to configure rings (i.e. hardware assisted queues)
# to be used by that address domain and to define the
# behavior of that ring.
#
# The address domains are in the following format
# - For kernel address domains
# [KERNEL]
# - For user process address domains
# [xxxxx]
# Where xxxxx may be any ascii value which uniquely identifies
# the user mode process.
# To allow the driver correctly configure the
# logical instances associated with this user process,
# the process must call the icp_sal_userStartMultiProcess(...)
# passing the xxxxx string during process initialisation.
# When the user space process is finished it must call
# icp_sal_userStop(...) to free resources.
# NumProcesses will indicate the maximum number of processes
# that can call icp_sal_userStartMultiProcess on this instance.
# Warning: the resources are preallocated: if NumProcesses
# is too high, the driver will fail to load
#
# Items configurable by a logical instance are:
# - Name of the logical instance
# - The accelerator associated with this logical
# instance
# - The core the instance is affinitized to (optional)
#
# Note: Logical instances may not share the same ring, but
# may share a ring bank.
#
# The format of the logical instances are:
# - For crypto:
# Cy<n>Name = "xxxx"
# Cy<n>AcceleratorNumber = 0-3
# Cy<n>CoreAffinity = 0-7
#
# - For Data Compression
# Dc<n>Name = "xxxx"
# Dc<n>AcceleratorNumber = 0-1
# Dc<n>CoreAffinity = 0-7
#
# Where:
# - n is the number of this logical instance starting at 0.
# - xxxx may be any ascii value which identifies the logical instance.
#
# Note: for user space processes, a list of values can be specified for
# the accelerator number and the core affinity: for example
# Cy0AcceleratorNumber = 0,2
# Cy0CoreAffinity = 0,2,4
# These comma-separated lists will allow the multiple processes to use
# different accelerators and cores, and will wrap around the numbers
# in the list. In the above example, process 0 will use accelerator 0,
# and process 1 will use accelerator 2
#
########################################################
##############################################
# Kernel Instances Section
##############################################
[KERNEL]
NumberCyInstances = 0
NumberDcInstances = 0
##############################################
# User Process Instance Section
##############################################
[SSL]
NumberCyInstances = 16
NumberDcInstances = 0
NumProcesses = 1
LimitDevAccess = 0
# Crypto - User instance #0
Cy0Name = "SSL0"
Cy0IsPolled = 1
Cy0AcceleratorNumber = 0
# List of core affinities
Cy0CoreAffinity = 0
# Crypto - User instance #1
Cy1Name = "SSL1"
Cy1IsPolled = 1
Cy1AcceleratorNumber = 1
# List of core affinities
Cy1CoreAffinity = 1
# Crypto - User instance #2
Cy2Name = "SSL2"
Cy2IsPolled = 1
Cy2AcceleratorNumber = 2
# List of core affinities
Cy2CoreAffinity = 2
# Crypto - User instance #3
Cy3Name = "SSL3"
Cy3IsPolled = 1
Cy3AcceleratorNumber = 3
# List of core affinities
Cy3CoreAffinity = 3
# Crypto - User instance #4
Cy4Name = "SSL4"
Cy4IsPolled = 1
Cy4AcceleratorNumber = 0
# List of core affinities
Cy4CoreAffinity = 4
# Crypto - User instance #5
Cy5Name = "SSL5"
Cy5IsPolled = 1
Cy5AcceleratorNumber = 1
# List of core affinities
Cy5CoreAffinity = 5
# Crypto - User instance #6
Cy6Name = "SSL6"
Cy6IsPolled = 1
Cy6AcceleratorNumber = 2
# List of core affinities
Cy6CoreAffinity = 6
# Crypto - User instance #7
Cy7Name = "SSL7"
Cy7IsPolled = 1
Cy7AcceleratorNumber = 3
# List of core affinities
Cy7CoreAffinity = 7
# Crypto - User instance #8
Cy8Name = "SSL8"
Cy8IsPolled = 1
Cy8AcceleratorNumber = 0
# List of core affinities
Cy8CoreAffinity = 16
# Crypto - User instance #9
Cy9Name = "SSL9"
Cy9IsPolled = 1
Cy9AcceleratorNumber = 1
# List of core affinities
Cy9CoreAffinity = 17
# Crypto - User instance #10
Cy10Name = "SSL10"
Cy10IsPolled = 1
Cy10AcceleratorNumber = 2
# List of core affinities
Cy10CoreAffinity = 18
# Crypto - User instance #11
Cy11Name = "SSL11"
Cy11IsPolled = 1
Cy11AcceleratorNumber = 3
# List of core affinities
Cy11CoreAffinity = 19
# Crypto - User instance #12
Cy12Name = "SSL12"
Cy12IsPolled = 1
Cy12AcceleratorNumber = 0
# List of core affinities
Cy12CoreAffinity = 20
# Crypto - User instance #13
Cy13Name = "SSL13"
Cy13IsPolled = 1
Cy13AcceleratorNumber = 1
# List of core affinities
Cy13CoreAffinity = 21
# Crypto - User instance #14
Cy14Name = "SSL14"
Cy14IsPolled = 1
Cy14AcceleratorNumber = 2
# List of core affinities
Cy14CoreAffinity = 22
# Crypto - User instance #15
Cy15Name = "SSL15"
Cy15IsPolled = 1
Cy15AcceleratorNumber = 3
# List of core affinities
Cy15CoreAffinity = 23
##############################################
# Wireless Process Instance Section
##############################################
[WIRELESS]
NumberCyInstances = 0
NumberDcInstances = 0
NumProcesses = 0

View File

@ -1,292 +0,0 @@
#########################################################################
#
# @par
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #########################################################################
# ########################################################
#
# This file is the configuration for a single dh89xxcc_qa
# device.
#
# Each device has up to two accelerators.
# - The client may load balance between these
# accelerators.
# Each accelerator has 8 independent ring banks.
# - The interrupt for each can be directed to a
# specific core.
# Each ring bank as 16 rings (hardware assisted queues).
#
#########################################################
# General Section
##############################################
[GENERAL]
ServicesEnabled = cy0;cy1
# Use version 2 of the config file
ConfigVersion = 2
# Look Aside Cryptographic Configuration
cyHmacAuthMode = 1
# Look Aside Compression Configuration
dcTotalSRAMAvailable = 0
# Firmware Location Configuration
Firmware_MofPath = mof_firmware.bin
Firmware_MmpPath = mmp_firmware.bin
#Default values for number of concurrent requests*/
CyNumConcurrentSymRequests = 512
CyNumConcurrentAsymRequests = 64
DcNumConcurrentRequests = 512
#Statistics, valid values: 1,0
statsGeneral = 1
statsDc = 1
statsDh = 1
statsDrbg = 1
statsDsa = 1
statsEcc = 1
statsKeyGen = 1
statsLn = 1
statsPrime = 1
statsRsa = 1
statsSym = 1
# Enables or disables Single Root Complex IO Virtualization.
# If this is enabled (1) then SRIOV and VT-d need to be enabled in
# BIOS and there can be no Cy or Dc instances created in PF (Dom0).
# If this i disabled (0) then SRIOV and VT-d need to be disabled
# in BIOS and Cy and/or Dc instances can be used in PF (Dom0)
SRIOV_Enabled = 0
#Debug feature, if set to 1 it enables additional entries in /proc filesystem
ProcDebug = 1
#######################################################
#
# Logical Instances Section
# A logical instance allows each address domain
# (kernel space and individual user space processes)
# to configure rings (i.e. hardware assisted queues)
# to be used by that address domain and to define the
# behavior of that ring.
#
# The address domains are in the following format
# - For kernel address domains
# [KERNEL]
# - For user process address domains
# [xxxxx]
# Where xxxxx may be any ascii value which uniquely identifies
# the user mode process.
# To allow the driver correctly configure the
# logical instances associated with this user process,
# the process must call the icp_sal_userStartMultiProcess(...)
# passing the xxxxx string during process initialisation.
# When the user space process is finished it must call
# icp_sal_userStop(...) to free resources.
# NumProcesses will indicate the maximum number of processes
# that can call icp_sal_userStartMultiProcess on this instance.
# Warning: the resources are preallocated: if NumProcesses
# is too high, the driver will fail to load
#
# Items configurable by a logical instance are:
# - Name of the logical instance
# - The accelerator associated with this logical
# instance
# - The core the instance is affinitized to (optional)
#
# Note: Logical instances may not share the same ring, but
# may share a ring bank.
#
# The format of the logical instances are:
# - For crypto:
# Cy<n>Name = "xxxx"
# Cy<n>AcceleratorNumber = 0-3
# Cy<n>CoreAffinity = 0-7
#
# - For Data Compression
# Dc<n>Name = "xxxx"
# Dc<n>AcceleratorNumber = 0-1
# Dc<n>CoreAffinity = 0-7
#
# Where:
# - n is the number of this logical instance starting at 0.
# - xxxx may be any ascii value which identifies the logical instance.
#
# Note: for user space processes, a list of values can be specified for
# the accelerator number and the core affinity: for example
# Cy0AcceleratorNumber = 0,2
# Cy0CoreAffinity = 0,2,4
# These comma-separated lists will allow the multiple processes to use
# different accelerators and cores, and will wrap around the numbers
# in the list. In the above example, process 0 will use accelerator 0,
# and process 1 will use accelerator 2
#
########################################################
##############################################
# Kernel Instances Section
##############################################
[KERNEL]
NumberCyInstances = 0
NumberDcInstances = 0
##############################################
# User Process Instance Section
##############################################
[SSL]
NumberCyInstances = 16
NumberDcInstances = 0
NumProcesses = 1
LimitDevAccess = 0
# Crypto - User instance #0
Cy0Name = "SSL0"
Cy0IsPolled = 1
Cy0AcceleratorNumber = 0
# List of core affinities
Cy0CoreAffinity = 8
# Crypto - User instance #1
Cy1Name = "SSL1"
Cy1IsPolled = 1
Cy1AcceleratorNumber = 1
# List of core affinities
Cy1CoreAffinity = 9
# Crypto - User instance #2
Cy2Name = "SSL2"
Cy2IsPolled = 1
Cy2AcceleratorNumber = 2
# List of core affinities
Cy2CoreAffinity = 10
# Crypto - User instance #3
Cy3Name = "SSL3"
Cy3IsPolled = 1
Cy3AcceleratorNumber = 3
# List of core affinities
Cy3CoreAffinity = 11
# Crypto - User instance #4
Cy4Name = "SSL4"
Cy4IsPolled = 1
Cy4AcceleratorNumber = 0
# List of core affinities
Cy4CoreAffinity = 12
# Crypto - User instance #5
Cy5Name = "SSL5"
Cy5IsPolled = 1
Cy5AcceleratorNumber = 1
# List of core affinities
Cy5CoreAffinity = 13
# Crypto - User instance #6
Cy6Name = "SSL6"
Cy6IsPolled = 1
Cy6AcceleratorNumber = 2
# List of core affinities
Cy6CoreAffinity = 14
# Crypto - User instance #7
Cy7Name = "SSL7"
Cy7IsPolled = 1
Cy7AcceleratorNumber = 3
# List of core affinities
Cy7CoreAffinity = 15
# Crypto - User instance #8
Cy8Name = "SSL8"
Cy8IsPolled = 1
Cy8AcceleratorNumber = 0
# List of core affinities
Cy8CoreAffinity = 24
# Crypto - User instance #9
Cy9Name = "SSL9"
Cy9IsPolled = 1
Cy9AcceleratorNumber = 1
# List of core affinities
Cy9CoreAffinity = 25
# Crypto - User instance #10
Cy10Name = "SSL10"
Cy10IsPolled = 1
Cy10AcceleratorNumber = 2
# List of core affinities
Cy10CoreAffinity = 26
# Crypto - User instance #11
Cy11Name = "SSL11"
Cy11IsPolled = 1
Cy11AcceleratorNumber = 3
# List of core affinities
Cy11CoreAffinity = 27
# Crypto - User instance #12
Cy12Name = "SSL12"
Cy12IsPolled = 1
Cy12AcceleratorNumber = 0
# List of core affinities
Cy12CoreAffinity = 28
# Crypto - User instance #13
Cy13Name = "SSL13"
Cy13IsPolled = 1
Cy13AcceleratorNumber = 1
# List of core affinities
Cy13CoreAffinity = 29
# Crypto - User instance #14
Cy14Name = "SSL14"
Cy14IsPolled = 1
Cy14AcceleratorNumber = 2
# List of core affinities
Cy14CoreAffinity = 30
# Crypto - User instance #15
Cy15Name = "SSL15"
Cy15IsPolled = 1
Cy15AcceleratorNumber = 3
# List of core affinities
Cy15CoreAffinity = 31
##############################################
# Wireless Process Instance Section
##############################################
[WIRELESS]
NumberCyInstances = 0
NumberDcInstances = 0
NumProcesses = 0

View File

@ -1,235 +0,0 @@
#########################################################################
#
# @par
# BSD LICENSE
#
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #########################################################################
# ########################################################
#
# This file is the configuration for a single dh89xxcc_qa
# device.
#
# Each device has up to two accelerators.
# - The client may load balance between these
# accelerators.
# Each accelerator has 8 independent ring banks.
# - The interrupt for each can be directed to a
# specific core.
# Each ring bank as 16 rings (hardware assisted queues).
#
#########################################################
# General Section
##############################################
[GENERAL]
ServicesEnabled = cy0;cy1
# Use version 2 of the config file
ConfigVersion = 2
# Look Aside Cryptographic Configuration
cyHmacAuthMode = 1
# Look Aside Compression Configuration
dcTotalSRAMAvailable = 0
# Firmware Location Configuration
Firmware_MofPath = mof_firmware.bin
Firmware_MmpPath = mmp_firmware.bin
#Default values for number of concurrent requests*/
CyNumConcurrentSymRequests = 512
CyNumConcurrentAsymRequests = 64
DcNumConcurrentRequests = 512
#Statistics, valid values: 1,0
statsGeneral = 1
statsDc = 1
statsDh = 1
statsDrbg = 1
statsDsa = 1
statsEcc = 1
statsKeyGen = 1
statsLn = 1
statsPrime = 1
statsRsa = 1
statsSym = 1
# Enables or disables Single Root Complex IO Virtualization.
# If this is enabled (1) then SRIOV and VT-d need to be enabled in
# BIOS and there can be no Cy or Dc instances created in PF (Dom0).
# If this i disabled (0) then SRIOV and VT-d need to be disabled
# in BIOS and Cy and/or Dc instances can be used in PF (Dom0)
SRIOV_Enabled = 0
#Debug feature, if set to 1 it enables additional entries in /proc filesystem
ProcDebug = 1
#######################################################
#
# Logical Instances Section
# A logical instance allows each address domain
# (kernel space and individual user space processes)
# to configure rings (i.e. hardware assisted queues)
# to be used by that address domain and to define the
# behavior of that ring.
#
# The address domains are in the following format
# - For kernel address domains
# [KERNEL]
# - For user process address domains
# [xxxxx]
# Where xxxxx may be any ascii value which uniquely identifies
# the user mode process.
# To allow the driver correctly configure the
# logical instances associated with this user process,
# the process must call the icp_sal_userStartMultiProcess(...)
# passing the xxxxx string during process initialisation.
# When the user space process is finished it must call
# icp_sal_userStop(...) to free resources.
# NumProcesses will indicate the maximum number of processes
# that can call icp_sal_userStartMultiProcess on this instance.
# Warning: the resources are preallocated: if NumProcesses
# is too high, the driver will fail to load
#
# Items configurable by a logical instance are:
# - Name of the logical instance
# - The accelerator associated with this logical
# instance
# - The core the instance is affinitized to (optional)
#
# Note: Logical instances may not share the same ring, but
# may share a ring bank.
#
# The format of the logical instances are:
# - For crypto:
# Cy<n>Name = "xxxx"
# Cy<n>AcceleratorNumber = 0-3
# Cy<n>CoreAffinity = 0-7
#
# - For Data Compression
# Dc<n>Name = "xxxx"
# Dc<n>AcceleratorNumber = 0-1
# Dc<n>CoreAffinity = 0-7
#
# Where:
# - n is the number of this logical instance starting at 0.
# - xxxx may be any ascii value which identifies the logical instance.
#
# Note: for user space processes, a list of values can be specified for
# the accelerator number and the core affinity: for example
# Cy0AcceleratorNumber = 0,2
# Cy0CoreAffinity = 0,2,4
# These comma-separated lists will allow the multiple processes to use
# different accelerators and cores, and will wrap around the numbers
# in the list. In the above example, process 0 will use accelerator 0,
# and process 1 will use accelerator 2
#
########################################################
##############################################
# Kernel Instances Section
##############################################
[KERNEL]
NumberCyInstances = 0
NumberDcInstances = 0
##############################################
# User Process Instance Section
##############################################
[SSL]
NumberCyInstances = 8
NumberDcInstances = 0
NumProcesses = 1
LimitDevAccess = 0
# Crypto - User instance #0
Cy0Name = "SSL0"
Cy0IsPolled = 1
Cy0AcceleratorNumber = 0
# List of core affinities
Cy0CoreAffinity = 0
# Crypto - User instance #1
Cy1Name = "SSL1"
Cy1IsPolled = 1
Cy1AcceleratorNumber = 1
# List of core affinities
Cy1CoreAffinity = 1
# Crypto - User instance #2
Cy2Name = "SSL2"
Cy2IsPolled = 1
Cy2AcceleratorNumber = 2
# List of core affinities
Cy2CoreAffinity = 2
# Crypto - User instance #3
Cy3Name = "SSL3"
Cy3IsPolled = 1
Cy3AcceleratorNumber = 3
# List of core affinities
Cy3CoreAffinity = 3
# Crypto - User instance #4
Cy4Name = "SSL4"
Cy4IsPolled = 1
Cy4AcceleratorNumber = 0
# List of core affinities
Cy4CoreAffinity = 4
# Crypto - User instance #5
Cy5Name = "SSL5"
Cy5IsPolled = 1
Cy5AcceleratorNumber = 1
# List of core affinities
Cy5CoreAffinity = 5
# Crypto - User instance #6
Cy6Name = "SSL6"
Cy6IsPolled = 1
Cy6AcceleratorNumber = 2
# List of core affinities
Cy6CoreAffinity = 6
# Crypto - User instance #7
Cy7Name = "SSL7"
Cy7IsPolled = 1
Cy7AcceleratorNumber = 3
# List of core affinities
Cy7CoreAffinity = 7
##############################################
# Wireless Process Instance Section
##############################################
[WIRELESS]
NumberCyInstances = 0
NumberDcInstances = 0
NumProcesses = 0

View File

@ -1,943 +0,0 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/queue.h>
#include <stdarg.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_ether.h>
#include <rte_malloc.h>
#include <rte_launch.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_string_fns.h>
#define CPA_CY_SYM_DP_TMP_WORKAROUND 1
#include "cpa.h"
#include "cpa_types.h"
#include "cpa_cy_sym_dp.h"
#include "cpa_cy_common.h"
#include "cpa_cy_im.h"
#include "icp_sal_user.h"
#include "icp_sal_poll.h"
#include "crypto.h"
/* CIPHER KEY LENGTHS */
#define KEY_SIZE_64_IN_BYTES (64 / 8)
#define KEY_SIZE_56_IN_BYTES (56 / 8)
#define KEY_SIZE_128_IN_BYTES (128 / 8)
#define KEY_SIZE_168_IN_BYTES (168 / 8)
#define KEY_SIZE_192_IN_BYTES (192 / 8)
#define KEY_SIZE_256_IN_BYTES (256 / 8)
/* HMAC AUTH KEY LENGTHS */
#define AES_XCBC_AUTH_KEY_LENGTH_IN_BYTES (128 / 8)
#define SHA1_AUTH_KEY_LENGTH_IN_BYTES (160 / 8)
#define SHA224_AUTH_KEY_LENGTH_IN_BYTES (224 / 8)
#define SHA256_AUTH_KEY_LENGTH_IN_BYTES (256 / 8)
#define SHA384_AUTH_KEY_LENGTH_IN_BYTES (384 / 8)
#define SHA512_AUTH_KEY_LENGTH_IN_BYTES (512 / 8)
#define MD5_AUTH_KEY_LENGTH_IN_BYTES (128 / 8)
#define KASUMI_AUTH_KEY_LENGTH_IN_BYTES (128 / 8)
/* HASH DIGEST LENGHTS */
#define AES_XCBC_DIGEST_LENGTH_IN_BYTES (128 / 8)
#define AES_XCBC_96_DIGEST_LENGTH_IN_BYTES (96 / 8)
#define MD5_DIGEST_LENGTH_IN_BYTES (128 / 8)
#define SHA1_DIGEST_LENGTH_IN_BYTES (160 / 8)
#define SHA1_96_DIGEST_LENGTH_IN_BYTES (96 / 8)
#define SHA224_DIGEST_LENGTH_IN_BYTES (224 / 8)
#define SHA256_DIGEST_LENGTH_IN_BYTES (256 / 8)
#define SHA384_DIGEST_LENGTH_IN_BYTES (384 / 8)
#define SHA512_DIGEST_LENGTH_IN_BYTES (512 / 8)
#define KASUMI_DIGEST_LENGTH_IN_BYTES (32 / 8)
#define IV_LENGTH_16_BYTES (16)
#define IV_LENGTH_8_BYTES (8)
/*
* rte_memzone is used to allocate physically contiguous virtual memory.
* In this application we allocate a single block and divide between variables
* which require a virtual to physical mapping for use by the QAT driver.
* Virt2phys is only performed during initialisation and not on the data-path.
*/
#define LCORE_MEMZONE_SIZE (1 << 22)
struct lcore_memzone
{
const struct rte_memzone *memzone;
void *next_free_address;
};
/*
* Size the qa software response queue.
* Note: Head and Tail are 8 bit, therefore, the queue is
* fixed to 256 entries.
*/
#define CRYPTO_SOFTWARE_QUEUE_SIZE 256
struct qa_callbackQueue {
uint8_t head;
uint8_t tail;
uint16_t numEntries;
struct rte_mbuf *qaCallbackRing[CRYPTO_SOFTWARE_QUEUE_SIZE];
};
struct qa_core_conf {
CpaCySymDpSessionCtx *encryptSessionHandleTbl[NUM_CRYPTO][NUM_HMAC];
CpaCySymDpSessionCtx *decryptSessionHandleTbl[NUM_CRYPTO][NUM_HMAC];
CpaInstanceHandle instanceHandle;
struct qa_callbackQueue callbackQueue;
uint64_t qaOutstandingRequests;
uint64_t numResponseAttempts;
uint8_t kickFreq;
void *pPacketIV;
CpaPhysicalAddr packetIVPhy;
struct lcore_memzone lcoreMemzone;
} __rte_cache_aligned;
#define MAX_CORES (RTE_MAX_LCORE)
static struct qa_core_conf qaCoreConf[MAX_CORES];
/*
*Create maximum possible key size,
*One for cipher and one for hash
*/
struct glob_keys {
uint8_t cipher_key[32];
uint8_t hash_key[64];
uint8_t iv[16];
};
struct glob_keys g_crypto_hash_keys = {
.cipher_key = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20},
.hash_key = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,
0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,
0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,
0x39,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50},
.iv = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10}
};
/*
* Offsets from the start of the packet.
*
*/
#define PACKET_DATA_START_PHYS(p) \
((p)->buf_physaddr + (p)->data_off)
/*
* A fixed offset to where the crypto is to be performed, which is the first
* byte after the Ethernet(14 bytes) and IPv4 headers(20 bytes)
*/
#define CRYPTO_START_OFFSET (14+20)
#define HASH_START_OFFSET (14+20)
#define CIPHER_BLOCK_DEFAULT_SIZE (16)
#define HASH_BLOCK_DEFAULT_SIZE (16)
/*
* Offset to the opdata from the start of the data portion of packet.
* Assumption: The buffer is physically contiguous.
* +18 takes this to the next cache line.
*/
#define CRYPTO_OFFSET_TO_OPDATA (ETHER_MAX_LEN+18)
/*
* Default number of requests to place on the hardware ring before kicking the
* ring pointers.
*/
#define CRYPTO_BURST_TX (16)
/*
* Only call the qa poll function when the number responses in the software
* queue drops below this number.
*/
#define CRYPTO_QUEUED_RESP_POLL_THRESHOLD (32)
/*
* Limit the number of polls per call to get_next_response.
*/
#define GET_NEXT_RESPONSE_FREQ (32)
/*
* Max number of responses to pull from the qa in one poll.
*/
#define CRYPTO_MAX_RESPONSE_QUOTA \
(CRYPTO_SOFTWARE_QUEUE_SIZE-CRYPTO_QUEUED_RESP_POLL_THRESHOLD-1)
#if (CRYPTO_QUEUED_RESP_POLL_THRESHOLD + CRYPTO_MAX_RESPONSE_QUOTA >= \
CRYPTO_SOFTWARE_QUEUE_SIZE)
#error Its possible to overflow the qa response Q with current poll and \
response quota.
#endif
static void
crypto_callback(CpaCySymDpOpData *pOpData,
__rte_unused CpaStatus status,
__rte_unused CpaBoolean verifyResult)
{
uint32_t lcore_id;
lcore_id = rte_lcore_id();
struct qa_callbackQueue *callbackQ = &(qaCoreConf[lcore_id].callbackQueue);
/*
* Received a completion from the QA hardware.
* Place the response on the return queue.
*/
callbackQ->qaCallbackRing[callbackQ->head] = pOpData->pCallbackTag;
callbackQ->head++;
callbackQ->numEntries++;
qaCoreConf[lcore_id].qaOutstandingRequests--;
}
static void
qa_crypto_callback(CpaCySymDpOpData *pOpData, CpaStatus status,
CpaBoolean verifyResult)
{
crypto_callback(pOpData, status, verifyResult);
}
/*
* Each allocation from a particular memzone lasts for the life-time of
* the application. No freeing of previous allocations will occur.
*/
static void *
alloc_memzone_region(uint32_t length, uint32_t lcore_id)
{
char *current_free_addr_ptr = NULL;
struct lcore_memzone *lcore_memzone = &(qaCoreConf[lcore_id].lcoreMemzone);
current_free_addr_ptr = lcore_memzone->next_free_address;
if (current_free_addr_ptr + length >=
(char *)lcore_memzone->memzone->addr + lcore_memzone->memzone->len) {
printf("Crypto: No memory available in memzone\n");
return NULL;
}
lcore_memzone->next_free_address = current_free_addr_ptr + length;
return (void *)current_free_addr_ptr;
}
/*
* Virtual to Physical Address translation is only executed during initialization
* and not on the data-path.
*/
static CpaPhysicalAddr
qa_v2p(void *ptr)
{
const struct rte_memzone *memzone = NULL;
uint32_t lcore_id = 0;
RTE_LCORE_FOREACH(lcore_id) {
memzone = qaCoreConf[lcore_id].lcoreMemzone.memzone;
if ((char*) ptr >= (char *) memzone->addr &&
(char*) ptr < ((char*) memzone->addr + memzone->len)) {
return (CpaPhysicalAddr)
(memzone->phys_addr + ((char *) ptr - (char*) memzone->addr));
}
}
printf("Crypto: Corresponding physical address not found in memzone\n");
return (CpaPhysicalAddr) 0;
}
static CpaStatus
getCoreAffinity(Cpa32U *coreAffinity, const CpaInstanceHandle instanceHandle)
{
CpaInstanceInfo2 info;
Cpa16U i = 0;
CpaStatus status = CPA_STATUS_SUCCESS;
memset(&info, 0, sizeof(CpaInstanceInfo2));
status = cpaCyInstanceGetInfo2(instanceHandle, &info);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: Error getting instance info\n");
return CPA_STATUS_FAIL;
}
for (i = 0; i < MAX_CORES; i++) {
if (CPA_BITMAP_BIT_TEST(info.coreAffinity, i)) {
*coreAffinity = i;
return CPA_STATUS_SUCCESS;
}
}
return CPA_STATUS_FAIL;
}
static CpaStatus
get_crypto_instance_on_core(CpaInstanceHandle *pInstanceHandle,
uint32_t lcore_id)
{
Cpa16U numInstances = 0, i = 0;
CpaStatus status = CPA_STATUS_FAIL;
CpaInstanceHandle *pLocalInstanceHandles = NULL;
Cpa32U coreAffinity = 0;
status = cpaCyGetNumInstances(&numInstances);
if (CPA_STATUS_SUCCESS != status || numInstances == 0) {
return CPA_STATUS_FAIL;
}
pLocalInstanceHandles = rte_malloc("pLocalInstanceHandles",
sizeof(CpaInstanceHandle) * numInstances, RTE_CACHE_LINE_SIZE);
if (NULL == pLocalInstanceHandles) {
return CPA_STATUS_FAIL;
}
status = cpaCyGetInstances(numInstances, pLocalInstanceHandles);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: cpaCyGetInstances failed with status: %"PRId32"\n", status);
rte_free((void *) pLocalInstanceHandles);
return CPA_STATUS_FAIL;
}
for (i = 0; i < numInstances; i++) {
status = getCoreAffinity(&coreAffinity, pLocalInstanceHandles[i]);
if (CPA_STATUS_SUCCESS != status) {
rte_free((void *) pLocalInstanceHandles);
return CPA_STATUS_FAIL;
}
if (coreAffinity == lcore_id) {
printf("Crypto: instance found on core %d\n", i);
*pInstanceHandle = pLocalInstanceHandles[i];
return CPA_STATUS_SUCCESS;
}
}
/* core affinity not found */
rte_free((void *) pLocalInstanceHandles);
return CPA_STATUS_FAIL;
}
static CpaStatus
initCySymSession(const int pkt_cipher_alg,
const int pkt_hash_alg, const CpaCySymHashMode hashMode,
const CpaCySymCipherDirection crypto_direction,
CpaCySymSessionCtx **ppSessionCtx,
const CpaInstanceHandle cyInstanceHandle,
const uint32_t lcore_id)
{
Cpa32U sessionCtxSizeInBytes = 0;
CpaStatus status = CPA_STATUS_FAIL;
CpaBoolean isCrypto = CPA_TRUE, isHmac = CPA_TRUE;
CpaCySymSessionSetupData sessionSetupData;
memset(&sessionSetupData, 0, sizeof(CpaCySymSessionSetupData));
/* Assumption: key length is set to each algorithm's max length */
switch (pkt_cipher_alg) {
case NO_CIPHER:
isCrypto = CPA_FALSE;
break;
case CIPHER_DES:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_DES_ECB;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_64_IN_BYTES;
break;
case CIPHER_DES_CBC:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_DES_CBC;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_64_IN_BYTES;
break;
case CIPHER_DES3:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_3DES_ECB;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_192_IN_BYTES;
break;
case CIPHER_DES3_CBC:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_3DES_CBC;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_192_IN_BYTES;
break;
case CIPHER_AES:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_AES_ECB;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_128_IN_BYTES;
break;
case CIPHER_AES_CBC_128:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_AES_CBC;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_128_IN_BYTES;
break;
case CIPHER_KASUMI_F8:
sessionSetupData.cipherSetupData.cipherAlgorithm =
CPA_CY_SYM_CIPHER_KASUMI_F8;
sessionSetupData.cipherSetupData.cipherKeyLenInBytes =
KEY_SIZE_128_IN_BYTES;
break;
default:
printf("Crypto: Undefined Cipher specified\n");
break;
}
/* Set the cipher direction */
if (isCrypto) {
sessionSetupData.cipherSetupData.cipherDirection = crypto_direction;
sessionSetupData.cipherSetupData.pCipherKey =
g_crypto_hash_keys.cipher_key;
sessionSetupData.symOperation = CPA_CY_SYM_OP_CIPHER;
}
/* Setup Hash common fields */
switch (pkt_hash_alg) {
case NO_HASH:
isHmac = CPA_FALSE;
break;
case HASH_AES_XCBC:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_AES_XCBC;
sessionSetupData.hashSetupData.digestResultLenInBytes =
AES_XCBC_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_AES_XCBC_96:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_AES_XCBC;
sessionSetupData.hashSetupData.digestResultLenInBytes =
AES_XCBC_96_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_MD5:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
sessionSetupData.hashSetupData.digestResultLenInBytes =
MD5_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_SHA1:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
sessionSetupData.hashSetupData.digestResultLenInBytes =
SHA1_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_SHA1_96:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
sessionSetupData.hashSetupData.digestResultLenInBytes =
SHA1_96_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_SHA224:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA224;
sessionSetupData.hashSetupData.digestResultLenInBytes =
SHA224_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_SHA256:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA256;
sessionSetupData.hashSetupData.digestResultLenInBytes =
SHA256_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_SHA384:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA384;
sessionSetupData.hashSetupData.digestResultLenInBytes =
SHA384_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_SHA512:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA512;
sessionSetupData.hashSetupData.digestResultLenInBytes =
SHA512_DIGEST_LENGTH_IN_BYTES;
break;
case HASH_KASUMI_F9:
sessionSetupData.hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_KASUMI_F9;
sessionSetupData.hashSetupData.digestResultLenInBytes =
KASUMI_DIGEST_LENGTH_IN_BYTES;
break;
default:
printf("Crypto: Undefined Hash specified\n");
break;
}
if (isHmac) {
sessionSetupData.hashSetupData.hashMode = hashMode;
sessionSetupData.symOperation = CPA_CY_SYM_OP_HASH;
/* If using authenticated hash setup key lengths */
if (CPA_CY_SYM_HASH_MODE_AUTH == hashMode) {
/* Use a common max length key */
sessionSetupData.hashSetupData.authModeSetupData.authKey =
g_crypto_hash_keys.hash_key;
switch (pkt_hash_alg) {
case HASH_AES_XCBC:
case HASH_AES_XCBC_96:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
AES_XCBC_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_MD5:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
SHA1_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_SHA1:
case HASH_SHA1_96:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
SHA1_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_SHA224:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
SHA224_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_SHA256:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
SHA256_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_SHA384:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
SHA384_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_SHA512:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
SHA512_AUTH_KEY_LENGTH_IN_BYTES;
break;
case HASH_KASUMI_F9:
sessionSetupData.hashSetupData.authModeSetupData.authKeyLenInBytes =
KASUMI_AUTH_KEY_LENGTH_IN_BYTES;
break;
default:
printf("Crypto: Undefined Hash specified\n");
return CPA_STATUS_FAIL;
}
}
}
/* Only high priority supported */
sessionSetupData.sessionPriority = CPA_CY_PRIORITY_HIGH;
/* If chaining algorithms */
if (isCrypto && isHmac) {
sessionSetupData.symOperation = CPA_CY_SYM_OP_ALGORITHM_CHAINING;
/* @assumption Alg Chain order is cipher then hash for encrypt
* and hash then cipher then has for decrypt*/
if (CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT == crypto_direction) {
sessionSetupData.algChainOrder =
CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
} else {
sessionSetupData.algChainOrder =
CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
}
}
if (!isCrypto && !isHmac) {
*ppSessionCtx = NULL;
return CPA_STATUS_SUCCESS;
}
/* Set flags for digest operations */
sessionSetupData.digestIsAppended = CPA_FALSE;
sessionSetupData.verifyDigest = CPA_TRUE;
/* Get the session context size based on the crypto and/or hash operations*/
status = cpaCySymDpSessionCtxGetSize(cyInstanceHandle, &sessionSetupData,
&sessionCtxSizeInBytes);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: cpaCySymDpSessionCtxGetSize error, status: %"PRId32"\n",
status);
return CPA_STATUS_FAIL;
}
*ppSessionCtx = alloc_memzone_region(sessionCtxSizeInBytes, lcore_id);
if (NULL == *ppSessionCtx) {
printf("Crypto: Failed to allocate memory for Session Context\n");
return CPA_STATUS_FAIL;
}
status = cpaCySymDpInitSession(cyInstanceHandle, &sessionSetupData,
*ppSessionCtx);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: cpaCySymDpInitSession failed with status %"PRId32"\n", status);
return CPA_STATUS_FAIL;
}
return CPA_STATUS_SUCCESS;
}
static CpaStatus
initSessionDataTables(struct qa_core_conf *qaCoreConf,uint32_t lcore_id)
{
Cpa32U i = 0, j = 0;
CpaStatus status = CPA_STATUS_FAIL;
for (i = 0; i < NUM_CRYPTO; i++) {
for (j = 0; j < NUM_HMAC; j++) {
if (((i == CIPHER_KASUMI_F8) && (j != NO_HASH) && (j != HASH_KASUMI_F9)) ||
((i != NO_CIPHER) && (i != CIPHER_KASUMI_F8) && (j == HASH_KASUMI_F9)))
continue;
status = initCySymSession(i, j, CPA_CY_SYM_HASH_MODE_AUTH,
CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT,
&qaCoreConf->encryptSessionHandleTbl[i][j],
qaCoreConf->instanceHandle,
lcore_id);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: Failed to initialize Encrypt sessions\n");
return CPA_STATUS_FAIL;
}
status = initCySymSession(i, j, CPA_CY_SYM_HASH_MODE_AUTH,
CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT,
&qaCoreConf->decryptSessionHandleTbl[i][j],
qaCoreConf->instanceHandle,
lcore_id);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: Failed to initialize Decrypt sessions\n");
return CPA_STATUS_FAIL;
}
}
}
return CPA_STATUS_SUCCESS;
}
int
crypto_init(void)
{
if (CPA_STATUS_SUCCESS != icp_sal_userStartMultiProcess("SSL",CPA_FALSE)) {
printf("Crypto: Could not start sal for user space\n");
return CPA_STATUS_FAIL;
}
printf("Crypto: icp_sal_userStartMultiProcess(\"SSL\",CPA_FALSE)\n");
return 0;
}
/*
* Per core initialisation
*/
int
per_core_crypto_init(uint32_t lcore_id)
{
CpaStatus status = CPA_STATUS_FAIL;
char memzone_name[RTE_MEMZONE_NAMESIZE];
int socketID = rte_lcore_to_socket_id(lcore_id);
/* Allocate software ring for response messages. */
qaCoreConf[lcore_id].callbackQueue.head = 0;
qaCoreConf[lcore_id].callbackQueue.tail = 0;
qaCoreConf[lcore_id].callbackQueue.numEntries = 0;
qaCoreConf[lcore_id].kickFreq = 0;
qaCoreConf[lcore_id].qaOutstandingRequests = 0;
qaCoreConf[lcore_id].numResponseAttempts = 0;
/* Initialise and reserve lcore memzone for virt2phys translation */
snprintf(memzone_name,
RTE_MEMZONE_NAMESIZE,
"lcore_%u",
lcore_id);
qaCoreConf[lcore_id].lcoreMemzone.memzone = rte_memzone_reserve(
memzone_name,
LCORE_MEMZONE_SIZE,
socketID,
0);
if (NULL == qaCoreConf[lcore_id].lcoreMemzone.memzone) {
printf("Crypto: Error allocating memzone on lcore %u\n",lcore_id);
return -1;
}
qaCoreConf[lcore_id].lcoreMemzone.next_free_address =
qaCoreConf[lcore_id].lcoreMemzone.memzone->addr;
qaCoreConf[lcore_id].pPacketIV = alloc_memzone_region(IV_LENGTH_16_BYTES,
lcore_id);
if (NULL == qaCoreConf[lcore_id].pPacketIV ) {
printf("Crypto: Failed to allocate memory for Initialization Vector\n");
return -1;
}
memcpy(qaCoreConf[lcore_id].pPacketIV, &g_crypto_hash_keys.iv,
IV_LENGTH_16_BYTES);
qaCoreConf[lcore_id].packetIVPhy = qa_v2p(qaCoreConf[lcore_id].pPacketIV);
if (0 == qaCoreConf[lcore_id].packetIVPhy) {
printf("Crypto: Invalid physical address for Initialization Vector\n");
return -1;
}
/*
* Obtain the instance handle that is mapped to the current lcore.
* This can fail if an instance is not mapped to a bank which has been
* affinitized to the current lcore.
*/
status = get_crypto_instance_on_core(&(qaCoreConf[lcore_id].instanceHandle),
lcore_id);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: get_crypto_instance_on_core failed with status: %"PRId32"\n",
status);
return -1;
}
status = cpaCySymDpRegCbFunc(qaCoreConf[lcore_id].instanceHandle,
(CpaCySymDpCbFunc) qa_crypto_callback);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: cpaCySymDpRegCbFunc failed with status: %"PRId32"\n", status);
return -1;
}
/*
* Set the address translation callback for virtual to physcial address
* mapping. This will be called by the QAT driver during initialisation only.
*/
status = cpaCySetAddressTranslation(qaCoreConf[lcore_id].instanceHandle,
(CpaVirtualToPhysical) qa_v2p);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: cpaCySetAddressTranslation failed with status: %"PRId32"\n",
status);
return -1;
}
status = initSessionDataTables(&qaCoreConf[lcore_id],lcore_id);
if (CPA_STATUS_SUCCESS != status) {
printf("Crypto: Failed to allocate all session tables.");
return -1;
}
return 0;
}
static CpaStatus
enqueueOp(CpaCySymDpOpData *opData, uint32_t lcore_id)
{
CpaStatus status;
/*
* Assumption is there is no requirement to do load balancing between
* acceleration units - that is one acceleration unit is tied to a core.
*/
opData->instanceHandle = qaCoreConf[lcore_id].instanceHandle;
if ((++qaCoreConf[lcore_id].kickFreq) % CRYPTO_BURST_TX == 0) {
status = cpaCySymDpEnqueueOp(opData, CPA_TRUE);
} else {
status = cpaCySymDpEnqueueOp(opData, CPA_FALSE);
}
qaCoreConf[lcore_id].qaOutstandingRequests++;
return status;
}
void
crypto_flush_tx_queue(uint32_t lcore_id)
{
cpaCySymDpPerformOpNow(qaCoreConf[lcore_id].instanceHandle);
}
enum crypto_result
crypto_encrypt(struct rte_mbuf *rte_buff, enum cipher_alg c, enum hash_alg h)
{
CpaCySymDpOpData *opData =
rte_pktmbuf_mtod_offset(rte_buff, CpaCySymDpOpData *,
CRYPTO_OFFSET_TO_OPDATA);
uint32_t lcore_id;
if (unlikely(c >= NUM_CRYPTO || h >= NUM_HMAC))
return CRYPTO_RESULT_FAIL;
lcore_id = rte_lcore_id();
memset(opData, 0, sizeof(CpaCySymDpOpData));
opData->srcBuffer = opData->dstBuffer = PACKET_DATA_START_PHYS(rte_buff);
opData->srcBufferLen = opData->dstBufferLen = rte_buff->data_len;
opData->sessionCtx = qaCoreConf[lcore_id].encryptSessionHandleTbl[c][h];
opData->thisPhys = PACKET_DATA_START_PHYS(rte_buff)
+ CRYPTO_OFFSET_TO_OPDATA;
opData->pCallbackTag = rte_buff;
/* if no crypto or hash operations are specified return fail */
if (NO_CIPHER == c && NO_HASH == h)
return CRYPTO_RESULT_FAIL;
if (NO_CIPHER != c) {
opData->pIv = qaCoreConf[lcore_id].pPacketIV;
opData->iv = qaCoreConf[lcore_id].packetIVPhy;
if (CIPHER_AES_CBC_128 == c)
opData->ivLenInBytes = IV_LENGTH_16_BYTES;
else
opData->ivLenInBytes = IV_LENGTH_8_BYTES;
opData->cryptoStartSrcOffsetInBytes = CRYPTO_START_OFFSET;
opData->messageLenToCipherInBytes = rte_buff->data_len
- CRYPTO_START_OFFSET;
/*
* Work around for padding, message length has to be a multiple of
* block size.
*/
opData->messageLenToCipherInBytes -= opData->messageLenToCipherInBytes
% CIPHER_BLOCK_DEFAULT_SIZE;
}
if (NO_HASH != h) {
opData->hashStartSrcOffsetInBytes = HASH_START_OFFSET;
opData->messageLenToHashInBytes = rte_buff->data_len
- HASH_START_OFFSET;
/*
* Work around for padding, message length has to be a multiple of block
* size.
*/
opData->messageLenToHashInBytes -= opData->messageLenToHashInBytes
% HASH_BLOCK_DEFAULT_SIZE;
/*
* Assumption: Ok ignore the passed digest pointer and place HMAC at end
* of packet.
*/
opData->digestResult = rte_buff->buf_physaddr + rte_buff->data_len;
}
if (CPA_STATUS_SUCCESS != enqueueOp(opData, lcore_id)) {
/*
* Failed to place a packet on the hardware queue.
* Most likely because the QA hardware is busy.
*/
return CRYPTO_RESULT_FAIL;
}
return CRYPTO_RESULT_IN_PROGRESS;
}
enum crypto_result
crypto_decrypt(struct rte_mbuf *rte_buff, enum cipher_alg c, enum hash_alg h)
{
CpaCySymDpOpData *opData = rte_pktmbuf_mtod_offset(rte_buff, void *,
CRYPTO_OFFSET_TO_OPDATA);
uint32_t lcore_id;
if (unlikely(c >= NUM_CRYPTO || h >= NUM_HMAC))
return CRYPTO_RESULT_FAIL;
lcore_id = rte_lcore_id();
memset(opData, 0, sizeof(CpaCySymDpOpData));
opData->dstBuffer = opData->srcBuffer = PACKET_DATA_START_PHYS(rte_buff);
opData->dstBufferLen = opData->srcBufferLen = rte_buff->data_len;
opData->thisPhys = PACKET_DATA_START_PHYS(rte_buff)
+ CRYPTO_OFFSET_TO_OPDATA;
opData->sessionCtx = qaCoreConf[lcore_id].decryptSessionHandleTbl[c][h];
opData->pCallbackTag = rte_buff;
/* if no crypto or hmac operations are specified return fail */
if (NO_CIPHER == c && NO_HASH == h)
return CRYPTO_RESULT_FAIL;
if (NO_CIPHER != c) {
opData->pIv = qaCoreConf[lcore_id].pPacketIV;
opData->iv = qaCoreConf[lcore_id].packetIVPhy;
if (CIPHER_AES_CBC_128 == c)
opData->ivLenInBytes = IV_LENGTH_16_BYTES;
else
opData->ivLenInBytes = IV_LENGTH_8_BYTES;
opData->cryptoStartSrcOffsetInBytes = CRYPTO_START_OFFSET;
opData->messageLenToCipherInBytes = rte_buff->data_len
- CRYPTO_START_OFFSET;
/*
* Work around for padding, message length has to be a multiple of block
* size.
*/
opData->messageLenToCipherInBytes -= opData->messageLenToCipherInBytes
% CIPHER_BLOCK_DEFAULT_SIZE;
}
if (NO_HASH != h) {
opData->hashStartSrcOffsetInBytes = HASH_START_OFFSET;
opData->messageLenToHashInBytes = rte_buff->data_len
- HASH_START_OFFSET;
/*
* Work around for padding, message length has to be a multiple of block
* size.
*/
opData->messageLenToHashInBytes -= opData->messageLenToHashInBytes
% HASH_BLOCK_DEFAULT_SIZE;
opData->digestResult = rte_buff->buf_physaddr + rte_buff->data_len;
}
if (CPA_STATUS_SUCCESS != enqueueOp(opData, lcore_id)) {
/*
* Failed to place a packet on the hardware queue.
* Most likely because the QA hardware is busy.
*/
return CRYPTO_RESULT_FAIL;
}
return CRYPTO_RESULT_IN_PROGRESS;
}
void *
crypto_get_next_response(void)
{
uint32_t lcore_id;
lcore_id = rte_lcore_id();
struct qa_callbackQueue *callbackQ = &(qaCoreConf[lcore_id].callbackQueue);
void *entry = NULL;
if (callbackQ->numEntries) {
entry = callbackQ->qaCallbackRing[callbackQ->tail];
callbackQ->tail++;
callbackQ->numEntries--;
}
/* If there are no outstanding requests no need to poll, return entry */
if (qaCoreConf[lcore_id].qaOutstandingRequests == 0)
return entry;
if (callbackQ->numEntries < CRYPTO_QUEUED_RESP_POLL_THRESHOLD
&& qaCoreConf[lcore_id].numResponseAttempts++
% GET_NEXT_RESPONSE_FREQ == 0) {
/*
* Only poll the hardware when there is less than
* CRYPTO_QUEUED_RESP_POLL_THRESHOLD elements in the software queue
*/
icp_sal_CyPollDpInstance(qaCoreConf[lcore_id].instanceHandle,
CRYPTO_MAX_RESPONSE_QUOTA);
}
return entry;
}

View File

@ -1,90 +0,0 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CRYPTO_H_
#define CRYPTO_H_
/* Pass Labels/Values to crypto units */
enum cipher_alg {
/* Option to not do any cryptography */
NO_CIPHER,
CIPHER_DES,
CIPHER_DES_CBC,
CIPHER_DES3,
CIPHER_DES3_CBC,
CIPHER_AES,
CIPHER_AES_CBC_128,
CIPHER_KASUMI_F8,
NUM_CRYPTO,
};
enum hash_alg {
/* Option to not do any hash */
NO_HASH,
HASH_MD5,
HASH_SHA1,
HASH_SHA1_96,
HASH_SHA224,
HASH_SHA256,
HASH_SHA384,
HASH_SHA512,
HASH_AES_XCBC,
HASH_AES_XCBC_96,
HASH_KASUMI_F9,
NUM_HMAC,
};
/* Return value from crypto_{encrypt/decrypt} */
enum crypto_result {
/* Packet was successfully put into crypto queue */
CRYPTO_RESULT_IN_PROGRESS,
/* Cryptography has failed in some way */
CRYPTO_RESULT_FAIL,
};
extern enum crypto_result crypto_encrypt(struct rte_mbuf *pkt, enum cipher_alg c,
enum hash_alg h);
extern enum crypto_result crypto_decrypt(struct rte_mbuf *pkt, enum cipher_alg c,
enum hash_alg h);
extern int crypto_init(void);
extern int per_core_crypto_init(uint32_t lcore_id);
extern void crypto_exit(void);
extern void *crypto_get_next_response(void);
extern void crypto_flush_tx_queue(uint32_t lcore_id);
#endif /* CRYPTO_H_ */

View File

@ -1,821 +0,0 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <string.h>
#include <sys/queue.h>
#include <stdarg.h>
#include <errno.h>
#include <getopt.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_cycles.h>
#include <rte_prefetch.h>
#include <rte_lcore.h>
#include <rte_per_lcore.h>
#include <rte_branch_prediction.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_random.h>
#include <rte_debug.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_ip.h>
#include <rte_string_fns.h>
#include "crypto.h"
#define NB_MBUF (32 * 1024)
#define MAX_PKT_BURST 32
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
#define TX_QUEUE_FLUSH_MASK 0xFFFFFFFF
#define TSC_COUNT_LIMIT 1000
#define ACTION_ENCRYPT 1
#define ACTION_DECRYPT 2
/*
* Configurable number of RX/TX ring descriptors
*/
#define RTE_TEST_RX_DESC_DEFAULT 128
#define RTE_TEST_TX_DESC_DEFAULT 512
static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
/* ethernet addresses of ports */
static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];
/* mask of enabled ports */
static unsigned enabled_port_mask = 0;
static int promiscuous_on = 1; /**< Ports set in promiscuous mode on by default. */
/* list of enabled ports */
static uint32_t dst_ports[RTE_MAX_ETHPORTS];
struct mbuf_table {
uint16_t len;
struct rte_mbuf *m_table[MAX_PKT_BURST];
};
struct lcore_rx_queue {
uint8_t port_id;
uint8_t queue_id;
};
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_LCORE_PARAMS 1024
struct lcore_params {
uint8_t port_id;
uint8_t queue_id;
uint8_t lcore_id;
};
static struct lcore_params lcore_params_array[MAX_LCORE_PARAMS];
static struct lcore_params lcore_params_array_default[] = {
{0, 0, 2},
{0, 1, 2},
{0, 2, 2},
{1, 0, 2},
{1, 1, 2},
{1, 2, 2},
{2, 0, 2},
{3, 0, 3},
{3, 1, 3},
};
static struct lcore_params * lcore_params = lcore_params_array_default;
static uint16_t nb_lcore_params = sizeof(lcore_params_array_default) /
sizeof(lcore_params_array_default[0]);
static struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.split_hdr_size = 0,
.header_split = 0, /**< Header Split disabled */
.hw_ip_checksum = 1, /**< IP checksum offload enabled */
.hw_vlan_filter = 0, /**< VLAN filtering disabled */
.jumbo_frame = 0, /**< Jumbo Frame Support disabled */
.hw_strip_crc = 0, /**< CRC stripped by hardware */
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,
.rss_hf = ETH_RSS_IP,
},
},
.txmode = {
.mq_mode = ETH_MQ_TX_NONE,
},
};
static struct rte_mempool * pktmbuf_pool[RTE_MAX_NUMA_NODES];
struct lcore_conf {
uint64_t tsc;
uint64_t tsc_count;
uint32_t tx_mask;
uint16_t n_rx_queue;
uint16_t rx_queue_list_pos;
struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE];
uint16_t tx_queue_id[RTE_MAX_ETHPORTS];
struct mbuf_table rx_mbuf;
uint32_t rx_mbuf_pos;
uint32_t rx_curr_queue;
struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
} __rte_cache_aligned;
static struct lcore_conf lcore_conf[RTE_MAX_LCORE];
static inline struct rte_mbuf *
nic_rx_get_packet(struct lcore_conf *qconf)
{
struct rte_mbuf *pkt;
if (unlikely(qconf->n_rx_queue == 0))
return NULL;
/* Look for the next queue with packets; return if none */
if (unlikely(qconf->rx_mbuf_pos == qconf->rx_mbuf.len)) {
uint32_t i;
qconf->rx_mbuf_pos = 0;
for (i = 0; i < qconf->n_rx_queue; i++) {
qconf->rx_mbuf.len = rte_eth_rx_burst(
qconf->rx_queue_list[qconf->rx_curr_queue].port_id,
qconf->rx_queue_list[qconf->rx_curr_queue].queue_id,
qconf->rx_mbuf.m_table, MAX_PKT_BURST);
qconf->rx_curr_queue++;
if (unlikely(qconf->rx_curr_queue == qconf->n_rx_queue))
qconf->rx_curr_queue = 0;
if (likely(qconf->rx_mbuf.len > 0))
break;
}
if (unlikely(i == qconf->n_rx_queue))
return NULL;
}
/* Get the next packet from the current queue; if last packet, go to next queue */
pkt = qconf->rx_mbuf.m_table[qconf->rx_mbuf_pos];
qconf->rx_mbuf_pos++;
return pkt;
}
static inline void
nic_tx_flush_queues(struct lcore_conf *qconf)
{
uint8_t portid;
for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
struct rte_mbuf **m_table = NULL;
uint16_t queueid, len;
uint32_t n, i;
if (likely((qconf->tx_mask & (1 << portid)) == 0))
continue;
len = qconf->tx_mbufs[portid].len;
if (likely(len == 0))
continue;
queueid = qconf->tx_queue_id[portid];
m_table = qconf->tx_mbufs[portid].m_table;
n = rte_eth_tx_burst(portid, queueid, m_table, len);
for (i = n; i < len; i++){
rte_pktmbuf_free(m_table[i]);
}
qconf->tx_mbufs[portid].len = 0;
}
qconf->tx_mask = TX_QUEUE_FLUSH_MASK;
}
static inline void
nic_tx_send_packet(struct rte_mbuf *pkt, uint8_t port)
{
struct lcore_conf *qconf;
uint32_t lcoreid;
uint16_t len;
if (unlikely(pkt == NULL)) {
return;
}
lcoreid = rte_lcore_id();
qconf = &lcore_conf[lcoreid];
len = qconf->tx_mbufs[port].len;
qconf->tx_mbufs[port].m_table[len] = pkt;
len++;
/* enough pkts to be sent */
if (unlikely(len == MAX_PKT_BURST)) {
uint32_t n, i;
uint16_t queueid;
queueid = qconf->tx_queue_id[port];
n = rte_eth_tx_burst(port, queueid, qconf->tx_mbufs[port].m_table, MAX_PKT_BURST);
for (i = n; i < MAX_PKT_BURST; i++){
rte_pktmbuf_free(qconf->tx_mbufs[port].m_table[i]);
}
qconf->tx_mask &= ~(1 << port);
len = 0;
}
qconf->tx_mbufs[port].len = len;
}
/* main processing loop */
static __attribute__((noreturn)) int
main_loop(__attribute__((unused)) void *dummy)
{
uint32_t lcoreid;
struct lcore_conf *qconf;
const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
lcoreid = rte_lcore_id();
qconf = &lcore_conf[lcoreid];
printf("Thread %u starting...\n", lcoreid);
for (;;) {
struct rte_mbuf *pkt;
uint32_t pkt_from_nic_rx = 0;
uint8_t port;
/* Flush TX queues */
qconf->tsc_count++;
if (unlikely(qconf->tsc_count == TSC_COUNT_LIMIT)) {
uint64_t tsc, diff_tsc;
tsc = rte_rdtsc();
diff_tsc = tsc - qconf->tsc;
if (unlikely(diff_tsc > drain_tsc)) {
nic_tx_flush_queues(qconf);
crypto_flush_tx_queue(lcoreid);
qconf->tsc = tsc;
}
qconf->tsc_count = 0;
}
/*
* Check the Intel QuickAssist queues first
*
***/
pkt = (struct rte_mbuf *) crypto_get_next_response();
if (pkt == NULL) {
pkt = nic_rx_get_packet(qconf);
pkt_from_nic_rx = 1;
}
if (pkt == NULL)
continue;
/* Send packet to either QAT encrypt, QAT decrypt or NIC TX */
if (pkt_from_nic_rx) {
struct ipv4_hdr *ip = rte_pktmbuf_mtod_offset(pkt,
struct ipv4_hdr *,
sizeof(struct ether_hdr));
if (ip->src_addr & rte_cpu_to_be_32(ACTION_ENCRYPT)) {
if (CRYPTO_RESULT_FAIL == crypto_encrypt(pkt,
(enum cipher_alg)((ip->src_addr >> 16) & 0xFF),
(enum hash_alg)((ip->src_addr >> 8) & 0xFF)))
rte_pktmbuf_free(pkt);
continue;
}
if (ip->src_addr & rte_cpu_to_be_32(ACTION_DECRYPT)) {
if(CRYPTO_RESULT_FAIL == crypto_decrypt(pkt,
(enum cipher_alg)((ip->src_addr >> 16) & 0xFF),
(enum hash_alg)((ip->src_addr >> 8) & 0xFF)))
rte_pktmbuf_free(pkt);
continue;
}
}
port = dst_ports[pkt->port];
/* Transmit the packet */
nic_tx_send_packet(pkt, (uint8_t)port);
}
}
static inline unsigned
get_port_max_rx_queues(uint8_t port_id)
{
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(port_id, &dev_info);
return dev_info.max_rx_queues;
}
static inline unsigned
get_port_max_tx_queues(uint8_t port_id)
{
struct rte_eth_dev_info dev_info;
rte_eth_dev_info_get(port_id, &dev_info);
return dev_info.max_tx_queues;
}
static int
check_lcore_params(void)
{
uint16_t i;
for (i = 0; i < nb_lcore_params; ++i) {
if (lcore_params[i].queue_id >= get_port_max_rx_queues(lcore_params[i].port_id)) {
printf("invalid queue number: %hhu\n", lcore_params[i].queue_id);
return -1;
}
if (!rte_lcore_is_enabled(lcore_params[i].lcore_id)) {
printf("error: lcore %hhu is not enabled in lcore mask\n",
lcore_params[i].lcore_id);
return -1;
}
}
return 0;
}
static int
check_port_config(const unsigned nb_ports)
{
unsigned portid;
uint16_t i;
for (i = 0; i < nb_lcore_params; ++i) {
portid = lcore_params[i].port_id;
if ((enabled_port_mask & (1 << portid)) == 0) {
printf("port %u is not enabled in port mask\n", portid);
return -1;
}
if (portid >= nb_ports) {
printf("port %u is not present on the board\n", portid);
return -1;
}
}
return 0;
}
static uint8_t
get_port_n_rx_queues(const uint8_t port)
{
int queue = -1;
uint16_t i;
for (i = 0; i < nb_lcore_params; ++i) {
if (lcore_params[i].port_id == port && lcore_params[i].queue_id > queue)
queue = lcore_params[i].queue_id;
}
return (uint8_t)(++queue);
}
static int
init_lcore_rx_queues(void)
{
uint16_t i, nb_rx_queue;
uint8_t lcore;
for (i = 0; i < nb_lcore_params; ++i) {
lcore = lcore_params[i].lcore_id;
nb_rx_queue = lcore_conf[lcore].n_rx_queue;
if (nb_rx_queue >= MAX_RX_QUEUE_PER_LCORE) {
printf("error: too many queues (%u) for lcore: %u\n",
(unsigned)nb_rx_queue + 1, (unsigned)lcore);
return -1;
}
lcore_conf[lcore].rx_queue_list[nb_rx_queue].port_id =
lcore_params[i].port_id;
lcore_conf[lcore].rx_queue_list[nb_rx_queue].queue_id =
lcore_params[i].queue_id;
lcore_conf[lcore].n_rx_queue++;
}
return 0;
}
/* display usage */
static void
print_usage(const char *prgname)
{
printf ("%s [EAL options] -- -p PORTMASK [--no-promisc]"
" [--config '(port,queue,lcore)[,(port,queue,lcore)]'\n"
" -p PORTMASK: hexadecimal bitmask of ports to configure\n"
" --no-promisc: disable promiscuous mode (default is ON)\n"
" --config '(port,queue,lcore)': rx queues configuration\n",
prgname);
}
static unsigned
parse_portmask(const char *portmask)
{
char *end = NULL;
unsigned pm;
/* parse hexadecimal string */
pm = strtoul(portmask, &end, 16);
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
return 0;
return pm;
}
static int
parse_config(const char *q_arg)
{
char s[256];
const char *p, *p_end = q_arg;
char *end;
enum fieldnames {
FLD_PORT = 0,
FLD_QUEUE,
FLD_LCORE,
_NUM_FLD
};
unsigned long int_fld[_NUM_FLD];
char *str_fld[_NUM_FLD];
int i;
unsigned size;
nb_lcore_params = 0;
while ((p = strchr(p_end,'(')) != NULL) {
if (nb_lcore_params >= MAX_LCORE_PARAMS) {
printf("exceeded max number of lcore params: %hu\n",
nb_lcore_params);
return -1;
}
++p;
if((p_end = strchr(p,')')) == NULL)
return -1;
size = p_end - p;
if(size >= sizeof(s))
return -1;
snprintf(s, sizeof(s), "%.*s", size, p);
if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
return -1;
for (i = 0; i < _NUM_FLD; i++) {
errno = 0;
int_fld[i] = strtoul(str_fld[i], &end, 0);
if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
return -1;
}
lcore_params_array[nb_lcore_params].port_id = (uint8_t)int_fld[FLD_PORT];
lcore_params_array[nb_lcore_params].queue_id = (uint8_t)int_fld[FLD_QUEUE];
lcore_params_array[nb_lcore_params].lcore_id = (uint8_t)int_fld[FLD_LCORE];
++nb_lcore_params;
}
lcore_params = lcore_params_array;
return 0;
}
/* Parse the argument given in the command line of the application */
static int
parse_args(int argc, char **argv)
{
int opt, ret;
char **argvopt;
int option_index;
char *prgname = argv[0];
static struct option lgopts[] = {
{"config", 1, 0, 0},
{"no-promisc", 0, 0, 0},
{NULL, 0, 0, 0}
};
argvopt = argv;
while ((opt = getopt_long(argc, argvopt, "p:",
lgopts, &option_index)) != EOF) {
switch (opt) {
/* portmask */
case 'p':
enabled_port_mask = parse_portmask(optarg);
if (enabled_port_mask == 0) {
printf("invalid portmask\n");
print_usage(prgname);
return -1;
}
break;
/* long options */
case 0:
if (strcmp(lgopts[option_index].name, "config") == 0) {
ret = parse_config(optarg);
if (ret) {
printf("invalid config\n");
print_usage(prgname);
return -1;
}
}
if (strcmp(lgopts[option_index].name, "no-promisc") == 0) {
printf("Promiscuous mode disabled\n");
promiscuous_on = 0;
}
break;
default:
print_usage(prgname);
return -1;
}
}
if (enabled_port_mask == 0) {
printf("portmask not specified\n");
print_usage(prgname);
return -1;
}
if (optind >= 0)
argv[optind-1] = prgname;
ret = optind-1;
optind = 1; /* reset getopt lib */
return ret;
}
static void
print_ethaddr(const char *name, const struct ether_addr *eth_addr)
{
char buf[ETHER_ADDR_FMT_SIZE];
ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, eth_addr);
printf("%s%s", name, buf);
}
static int
init_mem(void)
{
int socketid;
unsigned lcoreid;
char s[64];
RTE_LCORE_FOREACH(lcoreid) {
socketid = rte_lcore_to_socket_id(lcoreid);
if (socketid >= RTE_MAX_NUMA_NODES) {
printf("Socket %d of lcore %u is out of range %d\n",
socketid, lcoreid, RTE_MAX_NUMA_NODES);
return -1;
}
if (pktmbuf_pool[socketid] == NULL) {
snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
pktmbuf_pool[socketid] =
rte_pktmbuf_pool_create(s, NB_MBUF, 32, 0,
RTE_MBUF_DEFAULT_BUF_SIZE, socketid);
if (pktmbuf_pool[socketid] == NULL) {
printf("Cannot init mbuf pool on socket %d\n", socketid);
return -1;
}
printf("Allocated mbuf pool on socket %d\n", socketid);
}
}
return 0;
}
int
main(int argc, char **argv)
{
struct lcore_conf *qconf;
struct rte_eth_link link;
int ret;
unsigned nb_ports;
uint16_t queueid;
unsigned lcoreid;
uint32_t nb_tx_queue;
uint8_t portid, nb_rx_queue, queue, socketid, last_port;
unsigned nb_ports_in_mask = 0;
/* init EAL */
ret = rte_eal_init(argc, argv);
if (ret < 0)
return -1;
argc -= ret;
argv += ret;
/* parse application arguments (after the EAL ones) */
ret = parse_args(argc, argv);
if (ret < 0)
return -1;
if (check_lcore_params() < 0)
rte_panic("check_lcore_params failed\n");
ret = init_lcore_rx_queues();
if (ret < 0)
return -1;
ret = init_mem();
if (ret < 0)
return -1;
nb_ports = rte_eth_dev_count();
if (check_port_config(nb_ports) < 0)
rte_panic("check_port_config failed\n");
/* reset dst_ports */
for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++)
dst_ports[portid] = 0;
last_port = 0;
/*
* Each logical core is assigned a dedicated TX queue on each port.
*/
for (portid = 0; portid < nb_ports; portid++) {
/* skip ports that are not enabled */
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
if (nb_ports_in_mask % 2) {
dst_ports[portid] = last_port;
dst_ports[last_port] = portid;
}
else
last_port = portid;
nb_ports_in_mask++;
}
if (nb_ports_in_mask % 2) {
printf("Notice: odd number of ports in portmask.\n");
dst_ports[last_port] = last_port;
}
/* initialize all ports */
for (portid = 0; portid < nb_ports; portid++) {
/* skip ports that are not enabled */
if ((enabled_port_mask & (1 << portid)) == 0) {
printf("\nSkipping disabled port %d\n", portid);
continue;
}
/* init port */
printf("Initializing port %d ... ", portid );
fflush(stdout);
nb_rx_queue = get_port_n_rx_queues(portid);
if (nb_rx_queue > get_port_max_rx_queues(portid))
rte_panic("Number of rx queues %d exceeds max number of rx queues %u"
" for port %d\n", nb_rx_queue, get_port_max_rx_queues(portid),
portid);
nb_tx_queue = rte_lcore_count();
if (nb_tx_queue > get_port_max_tx_queues(portid))
rte_panic("Number of lcores %u exceeds max number of tx queues %u"
" for port %d\n", nb_tx_queue, get_port_max_tx_queues(portid),
portid);
printf("Creating queues: nb_rxq=%d nb_txq=%u... ",
nb_rx_queue, (unsigned)nb_tx_queue );
ret = rte_eth_dev_configure(portid, nb_rx_queue,
(uint16_t)nb_tx_queue, &port_conf);
if (ret < 0)
rte_panic("Cannot configure device: err=%d, port=%d\n",
ret, portid);
rte_eth_macaddr_get(portid, &ports_eth_addr[portid]);
print_ethaddr(" Address:", &ports_eth_addr[portid]);
printf(", ");
/* init one TX queue per couple (lcore,port) */
queueid = 0;
RTE_LCORE_FOREACH(lcoreid) {
socketid = (uint8_t)rte_lcore_to_socket_id(lcoreid);
printf("txq=%u,%d,%d ", lcoreid, queueid, socketid);
fflush(stdout);
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
socketid,
NULL);
if (ret < 0)
rte_panic("rte_eth_tx_queue_setup: err=%d, "
"port=%d\n", ret, portid);
qconf = &lcore_conf[lcoreid];
qconf->tx_queue_id[portid] = queueid;
queueid++;
}
printf("\n");
}
RTE_LCORE_FOREACH(lcoreid) {
qconf = &lcore_conf[lcoreid];
printf("\nInitializing rx queues on lcore %u ... ", lcoreid );
fflush(stdout);
/* init RX queues */
for(queue = 0; queue < qconf->n_rx_queue; ++queue) {
portid = qconf->rx_queue_list[queue].port_id;
queueid = qconf->rx_queue_list[queue].queue_id;
socketid = (uint8_t)rte_lcore_to_socket_id(lcoreid);
printf("rxq=%d,%d,%d ", portid, queueid, socketid);
fflush(stdout);
ret = rte_eth_rx_queue_setup(portid, queueid, nb_rxd,
socketid,
NULL,
pktmbuf_pool[socketid]);
if (ret < 0)
rte_panic("rte_eth_rx_queue_setup: err=%d,"
"port=%d\n", ret, portid);
}
}
printf("\n");
/* start ports */
for (portid = 0; portid < nb_ports; portid++) {
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
/* Start device */
ret = rte_eth_dev_start(portid);
if (ret < 0)
rte_panic("rte_eth_dev_start: err=%d, port=%d\n",
ret, portid);
printf("done: Port %d ", portid);
/* get link status */
rte_eth_link_get(portid, &link);
if (link.link_status)
printf(" Link Up - speed %u Mbps - %s\n",
(unsigned) link.link_speed,
(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
("full-duplex") : ("half-duplex\n"));
else
printf(" Link Down\n");
/*
* If enabled, put device in promiscuous mode.
* This allows IO forwarding mode to forward packets
* to itself through 2 cross-connected ports of the
* target machine.
*/
if (promiscuous_on)
rte_eth_promiscuous_enable(portid);
}
printf("Crypto: Initializing Crypto...\n");
if (crypto_init() != 0)
return -1;
RTE_LCORE_FOREACH(lcoreid) {
if (per_core_crypto_init(lcoreid) != 0) {
printf("Crypto: Cannot init lcore crypto on lcore %u\n", (unsigned)lcoreid);
return -1;
}
}
printf("Crypto: Initialization complete\n");
/* launch per-lcore init on every lcore */
rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER);
RTE_LCORE_FOREACH_SLAVE(lcoreid) {
if (rte_eal_wait_lcore(lcoreid) < 0)
return -1;
}
return 0;
}