# Technical Documentation: DPDK/dpdk

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/DPDK/dpdk)

### Overview (`dts/README.md`)

# Description

DTS is a testing framework and set of testsuites
for end to end testing of DPDK and DPDK enabled hardware.
Unlike DPDK's dpdk-test application, which is used for running unit tests,
DTS is intended to be used to evaluate real DPDK workloads run over supported hardware.
For instance, DTS will control a traffic generator node which will send packets
to a system under test node which is running a DPDK application,
and evaluate the resulting DPDK application behavior.

# Supported Test Node Topologies

DTS is a Python application which will control a traffic generator node (TG)
and system under test node (SUT).
The nodes represent a DPDK device (usually a NIC) located on a host.
The devices/NICs can be located on two separate servers, or on the same server.
If you use the same server for both NICs,
install them on separate NUMA domains if possible
(this is ideal for performance testing.)

- 2 links topology:
  Represents a topology in which the TG node and SUT node
  both have two network interfaces which form the TG <-> SUT connection.
  An example of this would be a dual interface NIC which is the TG node
  connected to a dual interface NIC which is the SUT node.
  Interface 0 on TG <-> interface 0 on SUT, interface 1 on TG <-> interface 1 on SUT.
- 1 link topology:
  Works, but may result in skips for testsuites which are explicitly decorated
  with a 2 link requirement.
  Represents a topology in which the TG node and SUT node are connected
  over a single networking link.
  An example of this would be two single interface NICs directly connected to each other.

# Simple Linux Setup

1. On your TG and SUT nodes, add a dedicated user for DTS.
   In this example, the user is named "dts".
2. Grant passwordless sudo to the dts user, in visudo editor: \
   `dts ALL=(ALL:ALL) NOPASSWD:ALL`
3. DTS uses ssh key auth to control the nodes.
   Copy your ssh keys to the TG and SUT: \
   `ssh-copy-id dts@{your host}`

For additional detail, please refer to [dts.rst](../doc/guides/tools/dts.rst).

# DTS Configuration

DTS requires two yaml files to be filled out with information about your environment,
test_run.yaml and nodes.yaml, which follow the format illustrated in the example files.

1. Install Docker on the SUT, and Scapy on the TG.
2. Create and fill out test_run.yaml and nodes.yaml files
   within the dts directory, based on the structure from the example config files.
3. Run the bash terminal commands below in order to run the DTS container
   and start the DTS execution.

```shell
docker build --target dev -t dpdk-dts .
docker run -v $(pwd)/..:/dpdk -v /home/{name of dts user}/.ssh:/root/.ssh:ro -it dpdk-dts bash
$ poetry install
$ poetry run ./main.py
```

These commands will give you a bash shell inside a docker container
with all DTS Python dependencies installed.

# Code Coverage

To generate code coverage reports,
ensure the SUT has lcov v1.15 and gcov v8.0 or greater installed,
and that DTS is run using the `--code-coverage` argument.

## Visual Studio Code

Usage of VScode devcontainers is NOT required for developing on DTS and running DTS,
but provide some small quality of life improvements for the developer.
If you want to develop from a devcontainer, see the instructions below:

VSCode has first-class support for developing with containers.
You may need to run the non-Docker setup commands in the integrated terminal.
DTS contains a .devcontainer config,
so if you open the folder in VSCode it should prompt you to use the dev container
assuming you have the plugin installed.
Please refer to [VSCode doc](https://code.visualstudio.com/docs/remote/containers)
to set it all up.
Additionally, there is a line in `.devcontainer/devcontainer.json` that, when included,
will mount the SSH keys of the user currently running VSCode into the container for you.
The `source` on this line can be altered to mount any SSH keys
on the local machine into the container at the correct location.

---

### Doc Api Doxy Api Index (`doc/api/doxy-api-index.md`)

API
===



The public API headers are grouped by topics:

- **device**:
  [dev](@ref rte_dev.h),
  [ethdev](@ref rte_ethdev.h),
  [ethctrl](@ref rte_eth_ctrl.h),
  [rte_flow](@ref rte_flow.h),
  [rte_tm](@ref rte_tm.h),
  [rte_mtr](@ref rte_mtr.h),
  [bbdev](@ref rte_bbdev.h),
  [cryptodev](@ref rte_cryptodev.h),
  [security](@ref rte_security.h),
  [compressdev](@ref rte_compressdev.h),
  [compress](@ref rte_comp.h),
  [regexdev](@ref rte_regexdev.h),
  [mldev](@ref rte_mldev.h),
  [dmadev](@ref rte_dmadev.h),
  [gpudev](@ref rte_gpudev.h),
  [eventdev](@ref rte_eventdev.h),
  [event_eth_rx_adapter](@ref rte_event_eth_rx_adapter.h),
  [event_eth_tx_adapter](@ref rte_event_eth_tx_adapter.h),
  [event_timer_adapter](@ref rte_event_timer_adapter.h),
  [event_crypto_adapter](@ref rte_event_crypto_adapter.h),
  [event_dma_adapter](@ref rte_event_dma_adapter.h),
  [event_vector_adapter](@ref rte_event_vector_adapter.h),
  [rawdev](@ref rte_rawdev.h),
  [metrics](@ref rte_metrics.h),
  [bitrate](@ref rte_bitrate.h),
  [latency](@ref rte_latencystats.h),
  [devargs](@ref rte_devargs.h),
  [PCI](@ref rte_pci.h),
  [vdev](@ref rte_bus_vdev.h)

- **device specific**:
  [softnic](@ref rte_eth_softnic.h),
  [bond](@ref rte_eth_bond.h),
  [vhost](@ref rte_vhost.h),
  [vdpa](@ref rte_vdpa.h),
  [ixgbe](@ref rte_pmd_ixgbe.h),
  [i40e](@ref rte_pmd_i40e.h),
  [iavf](@ref rte_pmd_iavf.h),
  [bnxt](@ref rte_pmd_bnxt.h),
  [cnxk](@ref rte_pmd_cnxk.h),
  [cnxk_crypto](@ref rte_pmd_cnxk_crypto.h),
  [cnxk_eventdev](@ref rte_pmd_cnxk_eventdev.h),
  [cnxk_mempool](@ref rte_pmd_cnxk_mempool.h),
  [dpaa](@ref rte_pmd_dpaa.h),
  [dpaa2](@ref rte_pmd_dpaa2.h),
  [mlx5](@ref rte_pmd_mlx5.h),
  [dpaa2_mempool](@ref rte_dpaa2_mempool.h),
  [dpaa2_cmdif](@ref rte_pmd_dpaa2_cmdif.h),
  [dpaax_qdma](@ref rte_pmd_dpaax_qdma.h),
  [crypto_scheduler](@ref rte_cryptodev_scheduler.h),
  [dlb2](@ref rte_pmd_dlb2.h),
  [ifpga](@ref rte_pmd_ifpga.h)

- **memory**:
  [per-lcore](@ref rte_per_lcore.h),
  [lcore variables](@ref rte_lcore_var.h),
  [memseg](@ref rte_memory.h),
  [memzone](@ref rte_memzone.h),
  [mempool](@ref rte_mempool.h),
  [malloc](@ref rte_malloc.h),
  [memcpy](@ref rte_memcpy.h)

- **timers**:
  [cycles](@ref rte_cycles.h),
  [timer](@ref rte_timer.h),
  [alarm](@ref rte_alarm.h)

- **locks**:
  [atomic](@ref rte_atomic.h),
  [mcslock](@ref rte_mcslock.h),
  [pflock](@ref rte_pflock.h),
  [rwlock](@ref rte_rwlock.h),
  [seqcount](@ref rte_seqcount.h),
  [seqlock](@ref rte_seqlock.h),
  [spinlock](@ref rte_spinlock.h),
  [ticketlock](@ref rte_ticketlock.h),
  [RCU](@ref rte_rcu_qsbr.h)

- **CPU arch**:
  [branch prediction](@ref rte_branch_prediction.h),
  [cache prefetch](@ref rte_prefetch.h),
  [SIMD](@ref rte_vect.h),
  [byte order](@ref rte_byteorder.h),
  [CPU flags](@ref rte_cpuflags.h),
  [CPU pause](@ref rte_pause.h),
  [I/O access](@ref rte_io.h),
  [power management](@ref rte_power_intrinsics.h)

- **CPU multicore**:
  [interrupts](@ref rte_interrupts.h),
  [launch](@ref rte_launch.h),
  [lcore](@ref rte_lcore.h),
  [service cores](@ref rte_service.h),
  [keepalive](@ref rte_keepalive.h),
  [power/freq](@ref rte_power_cpufreq.h),
  [power/uncore](@ref rte_power_uncore.h),
  [PMD power](@ref rte_power_pmd_mgmt.h)

- **layers**:
  [ethernet](@ref rte_ether.h),
  [MACsec](@ref rte_macsec.h),
  [ARP](@ref rte_arp.h),
  [HIGIG](@ref rte_higig.h),
  [ICMP](@ref rte_icmp.h),
  [ESP](@ref rte_esp.h),
  [IPsec](@ref rte_ipsec.h),
  [IPsec group](@ref rte_ipsec_group.h),
  [IPsec SA](@ref rte_ipsec_sa.h),
  [IPsec SAD](@ref rte_ipsec_sad.h),
  [IPv4](@ref rte_ip4.h),
  [IPv6](@ref rte_ip6.h),
  [frag/reass](@ref rte_ip_frag.h),
  [UDP](@ref rte_udp.h),
  [SCTP](@ref rte_sctp.h),
  [TCP](@ref rte_tcp.h),
  [TLS](@ref rte_tls.h),
  [DTLS](@ref rte_dtls.h),
  [GTP](@ref rte_gtp.h),
  [GRO](@ref rte_gro.h),
  [GSO](@ref rte_gso.h),
  [GRE](@ref rte_gre.h),
  [MPLS](@ref rte_mpls.h),
  [VXLAN](@ref rte_vxlan.h),
  [Geneve](@ref rte_geneve.h),
  [eCPRI](@ref rte_ecpri.h),
  [PDCP hdr](@ref rte_pdcp_hdr.h),
  [PDCP](@ref rte_pdcp.h),
  [L2TPv2](@ref rte_l2tpv2.h),
  [PPP](@ref rte_ppp.h),
  [IB](@ref rte_ib.h)

- **QoS**:
  [metering](@ref rte_meter.h),
  [scheduler](@ref rte_sched.h),
  [RED congestion](@ref rte_red.h)

- **routing**:
  [LPM IPv4 route](@ref rte_lpm.h),
  [LPM IPv6 route](@ref rte_lpm6.h),
  [RIB IPv4](@ref rte_rib.h),
  [RIB IPv6](@ref rte_rib6.h),
  [FIB IPv4](@ref rte_fib.h),
  [FIB IPv6](@ref rte_fib6.h)

- **hashes**:
  [hash](@ref rte_hash.h),
  [jhash](@ref rte_jhash.h),
  [thash](@ref rte_thash.h),
  [thash_gfni](@ref rte_thash_gfni.h),
  [FBK hash](@ref rte_fbk_hash.h),
  [CRC hash](@ref rte_hash_crc.h)

- **classification**
  [reorder](@ref rte_reorder.h),
  [dispatcher](@ref rte_dispatcher.h),
  [distributor](@ref rte_distributor.h),
  [EFD](@ref rte_efd.h),
  [ACL](@ref rte_acl.h),
  [member](@ref rte_member.h),
  [BPF](@ref rte_bpf.h)

- **containers**:
  [mbuf](@ref rte_mbuf.h),
  [mbuf pool ops](@ref rte_mbuf_pool_ops.h),
  [ring](@ref rte_ring.h),
  [soring](@ref rte_soring.h),
  [stack](@ref rte_stack.h),
  [tailq](@ref rte_tailq.h),
  [bitset](@ref rte_bitset.h),
  [bitmap](@ref rte_bitmap.h)

- **packet framework**:
  * SWX pipeline:
    [control](@ref rte_swx_ctl.h),
    [extern](@ref rte_swx_extern.h),
    [pipeline](@ref rte_swx_pipeline.h)
  * SWX port:
    [port](@ref rte_swx_port.h),
    [ethdev](@ref rte_swx_port_ethdev.h),
    [fd](@ref rte_swx_port_fd.h),
    [ring](@ref rte_swx_port_ring.h),
    [src/sink](@ref rte_swx_port_source_sink.h)
  * SWX table:
    [table](@ref rte_swx_table.h),
    [table_em](@ref rte_swx_table_em.h)
    [table_wm](@ref rte_swx_table_wm.h)
  * [graph](@ref rte_graph.h):
    [graph_worker](@ref rte_graph_worker.h),
    [graph_feature_arc](@ref rte_graph_feature_arc.h),
    [graph_feature_arc_worker](@ref rte_graph_feature_arc_worker.h)
  * graph_nodes:
    [eth_node](@ref rte_node_eth_api.h),
    [ip4_node](@ref rte_node_ip4_api.h),
    [ip6_node](@ref rte_node_ip6_api.h),
    [udp4_input_node](@ref rte_node_udp4_input_api.h),
    [mbuf_dynfield](@ref rte_node_mbuf_dynfield.h)

- **basic**:
  [bitops](@ref rte_bitops.h),
  [approx fraction](@ref rte_approx.h),
  [random](@ref rte_random.h),
  [checksum](@ref rte_cksum.h),
  [config file](@ref rte_cfgfile.h),
  [key/value args](@ref rte_kvargs.h),
  [argument parsing](@ref rte_argparse.h),
  [ptr_compress](@ref rte_ptr_compress.h),
  [string](@ref rte_string_fns.h),
  [thread](@ref rte_thread.h)

- **debug**:
  [jobstats](@ref rte_jobstats.h),
  [telemetry](@ref rte_telemetry.h),
  [PMU](@ref rte_pmu.h),
  [pcapng](@ref rte_pcapng.h),
  [pdump](@ref rte_pdump.h),
  [hexdump](@ref rte_hexdump.h),
  [debug](@ref rte_debug.h),
  [log](@ref rte_log.h),
  [errno](@ref rte_errno.h),
  [trace](@ref rte_trace.h),
  [trace_point](@ref rte_trace_point.h)

- **misc**:
  [EAL config](@ref rte_eal.h),
  [common](@ref rte_common.h),
  [experimental APIs](@ref rte_compat.h),
  [version](@ref rte_version.h)

- **tests**:
  [**DTS**](@dts_api_main_page)

---

### Doc Guides Index (`doc/guides/index.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2010-2019 Intel Corporation.

DPDK documentation
==================

.. toctree::
   :maxdepth: 1

   linux_gsg/index
   freebsd_gsg/index
   windows_gsg/index
   sample_app_ug/index
   prog_guide/index
   howto/index
   tools/index
   testpmd_app_ug/index
   nics/index
   bbdevs/index
   cryptodevs/index
   compressdevs/index
   vdpadevs/index
   regexdevs/index
   mldevs/index
   dmadevs/index
   gpus/index
   eventdevs/index
   rawdevs/index
   mempool/index
   platform/index
   contributing/index
   rel_notes/index
   faq/index

---

### Doc Api Dts Api.Artifact (`doc/api/dts/api.artifact.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

artifact - File Management
==========================

.. automodule:: api.artifact
   :members:
   :show-inheritance:

---

### Doc Api Dts Api.Capabilities (`doc/api/dts/api.capabilities.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

capabilities - SUT Capabilities
===============================

.. automodule:: api.capabilities
   :members:
   :show-inheritance:

---

### Doc Api Dts Api.Packet (`doc/api/dts/api.packet.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

packet - Sending and capturing packets
======================================

.. automodule:: api.packet
   :members:
   :show-inheritance:

---

### Doc Api Dts Api (`doc/api/dts/api.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

api - DTS API
=============

.. automodule:: api
   :members:
   :show-inheritance:

.. toctree::
   :hidden:
   :maxdepth: 2

   api.testpmd

.. toctree::
   :hidden:
   :maxdepth: 1

   api.artifact
   api.capabilities
   api.packet
   api.test

---

### Doc Api Dts Api.Test (`doc/api/dts/api.test.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

test - Reporting results and logging
====================================

.. automodule:: api.test
   :members:
   :show-inheritance:

---

### Doc Api Dts Api.Testpmd.Config (`doc/api/dts/api.testpmd.config.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

config - Testpmd configuration
==============================

.. automodule:: api.testpmd.config
   :members:
   :show-inheritance:

---

### Doc Api Dts Api.Testpmd (`doc/api/dts/api.testpmd.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

testpmd - Testpmd Interactive Remote Shell
==========================================

.. automodule:: api.testpmd
   :members:
   :show-inheritance:

.. toctree::
   :hidden:
   :maxdepth: 1

   api.testpmd.types
   api.testpmd.config

---

### Doc Api Dts Api.Testpmd.Types (`doc/api/dts/api.testpmd.types.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

types - Testpmd types
=====================

.. automodule:: api.testpmd.types
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Config (`doc/api/dts/framework.config.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

config - Configuration Package
==============================

.. automodule:: framework.config
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Context (`doc/api/dts/framework.context.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

context - DTS execution context
===============================

.. automodule:: framework.context
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Exception (`doc/api/dts/framework.exception.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

exception - Exceptions
======================

.. automodule:: framework.exception
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Logger (`doc/api/dts/framework.logger.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

logger - Logging Facility
=========================

.. automodule:: framework.logger
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Params.Eal (`doc/api/dts/framework.params.eal.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

eal - EAL Parameters Modelling
==============================

.. automodule:: framework.params.eal
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Params (`doc/api/dts/framework.params.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

params - Command Line Parameters Modelling
==========================================

.. automodule:: framework.params
   :members:
   :show-inheritance:

.. toctree::
   :hidden:
   :maxdepth: 1

   framework.params.eal
   framework.params.types

---

### Doc Api Dts Framework.Params.Types (`doc/api/dts/framework.params.types.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

params.types - Parameters Modelling Types
=========================================

.. automodule:: framework.params.types
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Parser (`doc/api/dts/framework.parser.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

parser - Text Parsing Utilities
===============================

.. automodule:: framework.parser
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session.Dpdk (`doc/api/dts/framework.remote_session.dpdk.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

dpdk - DPDK Environments
========================

.. automodule:: framework.remote_session.dpdk
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session.Dpdk Shell (`doc/api/dts/framework.remote_session.dpdk_shell.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

dpdk\_shell - DPDK Interactive Remote Shell
===========================================

.. automodule:: framework.remote_session.dpdk_shell
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session.Interactive Remote Session (`doc/api/dts/framework.remote_session.interactive_remote_session.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

interactive\_remote\_session - SSH Interactive Remote Session
=============================================================

.. automodule:: framework.remote_session.interactive_remote_session
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session.Interactive Shell (`doc/api/dts/framework.remote_session.interactive_shell.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

interactive\_shell - Base Interactive Remote Shell
==================================================

.. automodule:: framework.remote_session.interactive_shell
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session.Python Shell (`doc/api/dts/framework.remote_session.python_shell.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

python\_shell - Python Interactive Remote Shell
===============================================

.. automodule:: framework.remote_session.python_shell
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session.Remote Session (`doc/api/dts/framework.remote_session.remote_session.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

remote\_session - Remote Session ABC
====================================

.. automodule:: framework.remote_session.remote_session
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Remote Session (`doc/api/dts/framework.remote_session.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

remote\_session - Node Connections Package
==========================================

.. automodule:: framework.remote_session
   :members:
   :show-inheritance:

.. toctree::
   :hidden:
   :maxdepth: 1

   framework.remote_session.remote_session
   framework.remote_session.interactive_remote_session
   framework.remote_session.interactive_shell
   framework.remote_session.shell_pool
   framework.remote_session.dpdk
   framework.remote_session.dpdk_shell
   framework.remote_session.python_shell

---

### Doc Api Dts Framework.Remote Session.Shell Pool (`doc/api/dts/framework.remote_session.shell_pool.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

shell\_pool - Shell Pooling Manager
===================================

.. automodule:: framework.remote_session.shell_pool
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Runner (`doc/api/dts/framework.runner.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

runner - Testbed Setup and Test Suite Runner
============================================

.. automodule:: framework.runner
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Settings (`doc/api/dts/framework.settings.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

settings - Command Line Arguments and Environment Variables
===========================================================

.. automodule:: framework.settings
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Test Result (`doc/api/dts/framework.test_result.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

test\_result - Test Results Records
===================================

.. automodule:: framework.test_result
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Test Run (`doc/api/dts/framework.test_run.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

test_run - Test Run Execution
=============================

.. automodule:: framework.test_run
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Test Suite (`doc/api/dts/framework.test_suite.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

test\_suite - Common Test Suite Features
========================================

.. automodule:: framework.test_suite
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Capability (`doc/api/dts/framework.testbed_model.capability.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

capability - Testbed Capabilities
=================================

.. automodule:: framework.testbed_model.capability
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Cpu (`doc/api/dts/framework.testbed_model.cpu.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

cpu - CPU Representation and Utilities
======================================

.. automodule:: framework.testbed_model.cpu
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Linux Session (`doc/api/dts/framework.testbed_model.linux_session.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

linux\_session - Linux Remote Session
=====================================

.. automodule:: framework.testbed_model.linux_session
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Node (`doc/api/dts/framework.testbed_model.node.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

node - Base Node
================

.. automodule:: framework.testbed_model.node
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Os Session (`doc/api/dts/framework.testbed_model.os_session.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

os\_session - OS-aware Remote Session ABC
=========================================

.. automodule:: framework.testbed_model.os_session
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Port (`doc/api/dts/framework.testbed_model.port.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

port - NIC Port Representation
==============================

.. automodule:: framework.testbed_model.port
   :members:
   :show-inheritance:
   :noindex:

---

### Doc Api Dts Framework.Testbed Model.Posix Session (`doc/api/dts/framework.testbed_model.posix_session.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

posix\_session - Posix Remote Session
=====================================

.. automodule:: framework.testbed_model.posix_session
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model (`doc/api/dts/framework.testbed_model.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

testbed\_model - Testbed Modelling Package
==========================================

.. automodule:: framework.testbed_model
   :members:
   :show-inheritance:

.. toctree::
   :hidden:
   :maxdepth: 2

   framework.testbed_model.traffic_generator

.. toctree::
   :hidden:
   :maxdepth: 1

   framework.testbed_model.os_session
   framework.testbed_model.linux_session
   framework.testbed_model.posix_session
   framework.testbed_model.node
   framework.testbed_model.capability
   framework.testbed_model.cpu
   framework.testbed_model.port
   framework.testbed_model.topology
   framework.testbed_model.virtual_device

---

### Doc Api Dts Framework.Testbed Model.Topology (`doc/api/dts/framework.testbed_model.topology.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

topology - Testbed Topology
===========================

.. automodule:: framework.testbed_model.topology
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Traffic Generator.Capturing Traffic Generator (`doc/api/dts/framework.testbed_model.traffic_generator.capturing_traffic_generator.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

capturing\_traffic\_generator - Base Capturing TG ABC
=====================================================

.. automodule:: framework.testbed_model.traffic_generator.capturing_traffic_generator
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Traffic Generator (`doc/api/dts/framework.testbed_model.traffic_generator.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

traffic\_generator Subpackage
=============================

.. automodule:: framework.testbed_model.traffic_generator
   :members:
   :show-inheritance:

.. toctree::
   :hidden:
   :maxdepth: 1

   framework.testbed_model.traffic_generator.traffic_generator
   framework.testbed_model.traffic_generator.capturing_traffic_generator
   framework.testbed_model.traffic_generator.scapy

---

### Doc Api Dts Framework.Testbed Model.Traffic Generator.Scapy (`doc/api/dts/framework.testbed_model.traffic_generator.scapy.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

scapy - Capturing Traffic Generator
===================================

.. automodule:: framework.testbed_model.traffic_generator.scapy
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Traffic Generator.Traffic Generator (`doc/api/dts/framework.testbed_model.traffic_generator.traffic_generator.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

traffic\_generator - Base TG ABC
================================

.. automodule:: framework.testbed_model.traffic_generator.traffic_generator
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Testbed Model.Virtual Device (`doc/api/dts/framework.testbed_model.virtual_device.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

virtual\_device - Virtual Devices
=================================

.. automodule:: framework.testbed_model.virtual_device
   :members:
   :show-inheritance:

---

### Doc Api Dts Framework.Utils (`doc/api/dts/framework.utils.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

utils - Various Utilities
=========================

.. automodule:: framework.utils
   :members:
   :show-inheritance:

---

### Doc Api Dts Index (`doc/api/dts/index.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

Welcome to DPDK Test Suite's API documentation
==============================================

.. automodule:: framework
   :members:
   :show-inheritance:

Packages
--------

.. toctree::
   :includehidden:
   :maxdepth: 1

   tests
   api
   framework.testbed_model
   framework.remote_session
   framework.params
   framework.config

Modules
-------

.. toctree::
   :maxdepth: 1

   framework.runner
   framework.test_run
   framework.test_suite
   framework.test_result
   framework.settings
   framework.context
   framework.logger
   framework.parser
   framework.utils
   framework.exception


Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

---

### Doc Api Dts Tests.TestSuite Blocklist (`doc/api/dts/tests.TestSuite_blocklist.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

blocklist Test Suite
====================

.. automodule:: tests.TestSuite_blocklist
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Buffer Scatter (`doc/api/dts/tests.TestSuite_buffer_scatter.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

buffer_scatter Test Suite
=========================

.. automodule:: tests.TestSuite_buffer_scatter
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Checksum Offload (`doc/api/dts/tests.TestSuite_checksum_offload.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

checksum_offload Test Suite
===========================

.. automodule:: tests.TestSuite_checksum_offload
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Cryptodev Latency (`doc/api/dts/tests.TestSuite_cryptodev_latency.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

cryptodev_latency Test Suite
============================

.. automodule:: tests.TestSuite_cryptodev_latency
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Cryptodev Throughput (`doc/api/dts/tests.TestSuite_cryptodev_throughput.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

cryptodev_throughput Test Suite
===============================

.. automodule:: tests.TestSuite_cryptodev_throughput
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Dual Vlan (`doc/api/dts/tests.TestSuite_dual_vlan.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

dual_vlan Test Suite
====================

.. automodule:: tests.TestSuite_dual_vlan
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Dynamic Config (`doc/api/dts/tests.TestSuite_dynamic_config.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

dynamic_config Test Suite
=========================

.. automodule:: tests.TestSuite_dynamic_config
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Dynamic Queue Conf (`doc/api/dts/tests.TestSuite_dynamic_queue_conf.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

dynamic_queue_conf Test Suite
=============================

.. automodule:: tests.TestSuite_dynamic_queue_conf
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Flow Offload (`doc/api/dts/tests.TestSuite_flow_offload.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

flow_offload Test Suite
=======================

.. automodule:: tests.TestSuite_flow_offload
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Hello World (`doc/api/dts/tests.TestSuite_hello_world.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

hello_world Test Suite
======================

.. automodule:: tests.TestSuite_hello_world
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite L2fwd (`doc/api/dts/tests.TestSuite_l2fwd.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

l2fwd Test Suite
================

.. automodule:: tests.TestSuite_l2fwd
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Mac Filter (`doc/api/dts/tests.TestSuite_mac_filter.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

mac_filter Test Suite
=====================

.. automodule:: tests.TestSuite_mac_filter
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Mtu (`doc/api/dts/tests.TestSuite_mtu.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

mtu Test Suite
==============

.. automodule:: tests.TestSuite_mtu
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Packet Capture (`doc/api/dts/tests.TestSuite_packet_capture.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

packet_capture Test Suite
=========================

.. automodule:: tests.TestSuite_packet_capture
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Port Control (`doc/api/dts/tests.TestSuite_port_control.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

port_control Test Suite
=======================

.. automodule:: tests.TestSuite_port_control
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Port Restart Config Persistency (`doc/api/dts/tests.TestSuite_port_restart_config_persistency.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

port_restart_config_persistency Test Suite
==========================================

.. automodule:: tests.TestSuite_port_restart_config_persistency
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Port Stats (`doc/api/dts/tests.TestSuite_port_stats.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

port_stats Test Suite
=====================

.. automodule:: tests.TestSuite_port_stats
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Promisc Support (`doc/api/dts/tests.TestSuite_promisc_support.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

promisc_support Test Suite
==========================

.. automodule:: tests.TestSuite_promisc_support
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Qinq (`doc/api/dts/tests.TestSuite_qinq.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

qinq Test Suite
===============

.. automodule:: tests.TestSuite_qinq
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Queue Toggle (`doc/api/dts/tests.TestSuite_queue_toggle.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

queue_toggle Test Suite
=======================

.. automodule:: tests.TestSuite_queue_toggle
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Rss (`doc/api/dts/tests.TestSuite_rss.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

rss Test Suite
==============

.. automodule:: tests.TestSuite_rss
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Rx Tx Offload (`doc/api/dts/tests.TestSuite_rx_tx_offload.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

rx_tx_offload Test Suite
========================

.. automodule:: tests.TestSuite_rx_tx_offload
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Single Core Forward Perf (`doc/api/dts/tests.TestSuite_single_core_forward_perf.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

single_core_forward_perf Test Suite
===================================

.. automodule:: tests.TestSuite_single_core_forward_perf
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Smoke Tests (`doc/api/dts/tests.TestSuite_smoke_tests.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

smoke_tests Test Suite
======================

.. automodule:: tests.TestSuite_smoke_tests
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Softnic (`doc/api/dts/tests.TestSuite_softnic.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

softnic Test Suite
==================

.. automodule:: tests.TestSuite_softnic
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Speed Capabilities (`doc/api/dts/tests.TestSuite_speed_capabilities.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

speed_capabilities Test Suite
=============================

.. automodule:: tests.TestSuite_speed_capabilities
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Unified Packet (`doc/api/dts/tests.TestSuite_unified_packet.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

unified_packet Test Suite
=========================

.. automodule:: tests.TestSuite_unified_packet
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Virtio Forward (`doc/api/dts/tests.TestSuite_virtio_forward.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

virtio_forward Test Suite
=========================

.. automodule:: tests.TestSuite_virtio_forward
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests.TestSuite Vlan (`doc/api/dts/tests.TestSuite_vlan.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

vlan Test Suite
===============

.. automodule:: tests.TestSuite_vlan
   :members:
   :show-inheritance:

---

### Doc Api Dts Tests (`doc/api/dts/tests.rst`)

.. SPDX-License-Identifier: BSD-3-Clause

Test Suites
===========

.. toctree::
   :glob:
   :hidden:
   :maxdepth: 1

   tests.*

---

### Doc Guides Bbdevs Acc100 (`doc/guides/bbdevs/acc100.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2020 Intel Corporation

Intel(R) ACC100 5G/4G FEC Poll Mode Drivers
===========================================

The BBDEV ACC100 5G/4G FEC poll mode driver (PMD) supports an
implementation of a VRAN FEC wireless acceleration function.
This device is also known as Mount Bryce.

Features
--------

ACC100 5G/4G FEC PMDs support the following features:

- LDPC Encode in the DL (5GNR)
- LDPC Decode in the UL (5GNR)
- Turbo Encode in the DL (4G)
- Turbo Decode in the UL (4G)
- Support for code block level processing
- 16 VFs per PF (physical device)
- Maximum of 128 queues per VF
- PCIe Gen-3 x16 Interface
- MSI
- SR-IOV

ACC100 5G/4G FEC PMDs support the following BBDEV capabilities:

* For the LDPC encode operation:
   - ``RTE_BBDEV_LDPC_CRC_24B_ATTACH`` :  set to attach CRC24B to CB(s)
   - ``RTE_BBDEV_LDPC_RATE_MATCH`` :  if set then do not do Rate Match bypass
   - ``RTE_BBDEV_LDPC_INTERLEAVER_BYPASS`` : if set then bypass interleaver

* For the LDPC decode operation:
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK`` :  check CRC24B from CB(s)
   - ``RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE`` :  disable early termination
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP`` :  drops CRC24B bits appended while decoding
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE`` :  provides an input for HARQ combining
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE`` :  provides an input for HARQ combining
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE`` :  HARQ memory input is internal
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE`` :  HARQ memory output is internal
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK`` :  loopback data to/from HARQ memory
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_FILLERS`` :  HARQ memory includes the fillers bits
   - ``RTE_BBDEV_LDPC_DEC_SCATTER_GATHER`` :  supports scatter-gather for input/output data
   - ``RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION`` :  supports compression of the HARQ input/output
   - ``RTE_BBDEV_LDPC_LLR_COMPRESSION`` :  supports LLR input compression

* For the turbo encode operation:
   - ``RTE_BBDEV_TURBO_CRC_24B_ATTACH`` :  set to attach CRC24B to CB(s)
   - ``RTE_BBDEV_TURBO_RATE_MATCH`` :  if set then do not do Rate Match bypass
   - ``RTE_BBDEV_TURBO_ENC_INTERRUPTS`` :  set for encoder dequeue interrupts
   - ``RTE_BBDEV_TURBO_RV_INDEX_BYPASS`` :  set to bypass RV index
   - ``RTE_BBDEV_TURBO_ENC_SCATTER_GATHER`` :  supports scatter-gather for input/output data

* For the turbo decode operation:
   - ``RTE_BBDEV_TURBO_CRC_TYPE_24B`` :  check CRC24B from CB(s)
   - ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE`` :  perform subblock de-interleave
   - ``RTE_BBDEV_TURBO_DEC_INTERRUPTS`` :  set for decoder dequeue interrupts
   - ``RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN`` :  set if negative LLR encoder i/p is supported
   - ``RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN`` :  set if positive LLR encoder i/p is supported
   - ``RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP`` :  keep CRC24B bits appended while decoding
   - ``RTE_BBDEV_TURBO_DEC_CRC_24B_DROP`` : option to drop the code block CRC after decoding
   - ``RTE_BBDEV_TURBO_EARLY_TERMINATION`` :  set early termination feature
   - ``RTE_BBDEV_TURBO_DEC_SCATTER_GATHER`` :  supports scatter-gather for input/output data
   - ``RTE_BBDEV_TURBO_HALF_ITERATION_EVEN`` :  set half iteration granularity

* PMD-specific build flags:
  The ACC100 PMD includes some optional build flags which may be used for troubleshooting.
  Recommended build configuration is for these to be kept as default.
  - ``RTE_LIBRTE_BBDEV_SKIP_VALIDATE``: option to skip API input validation.
  Recommended value is to keep the validation enabled by default
  as a protection for negative scenarios at a cost of some cycles
  spent to enforce these checks.
  - ``ACC100_EXT_MEM``: default option with memory external to CPU on the PCIe card DDR itself.
  Alternative build option will use CPU memory (not recommended).


Installation
------------

See :doc:`/linux_gsg/build_dpdk` for build instructions.

DPDK requires hugepages to be configured as described in :ref:`linux_gsg_hugepages`.
The bbdev test application has been tested with a configuration 40 x 1GB hugepages. The
hugepage configuration of a server may be examined using:

.. code-block:: console

   grep Huge* /proc/meminfo


Initialization
--------------

When the device first powers up, its PCI Physical Functions (PF) can be listed through these
commands for ACC100:

.. code-block:: console

  sudo lspci -vd8086:0d5c

The physical and virtual functions are compatible with Linux UIO drivers:
``vfio_pci`` and ``igb_uio``. However, in order to work the 5G/4G
FEC device first needs to be bound to one of these linux drivers through DPDK.

For more details on how to bind the PF device and create VF devices, see
:ref:`linux_gsg_binding_kernel`.


Configure the VFs through PF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The PCI virtual functions must be configured before working or getting assigned
to VMs/Containers. The configuration involves allocating the number of hardware
queues, priorities, load balance, bandwidth and other settings necessary for the
device to perform FEC functions.

This configuration needs to be executed at least once after reboot or PCI FLR and can
be achieved by using the functions ``rte_acc10x_configure()``,
which sets up the parameters defined in the compatible ``acc100_conf`` structure.

Test Application
----------------

BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing
the functionality of the device, depending on the device's capabilities.

For more details on how to use the test application,
see :doc:`/tools/testbbdev`.


Test Vectors
~~~~~~~~~~~~

In addition to the simple LDPC decoder and LDPC encoder tests, bbdev also provides
a range of additional tests under the test_vectors folder, which may be useful. The results
of these tests will depend on the device 5G/4G FEC capabilities which may cause some
testcases to be skipped, but no failure should be reported.


Alternate Baseband Device configuration tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On top of the embedded configuration feature supported in test-bbdev using "- -init-device"
option mentioned above, there is also a tool available to perform that device configuration
using a companion application.
The ``pf_bb_config`` application notably enables then to run bbdev-test from the VF
and not only limited to the PF as captured above.

See for more details: https://github.com/intel/pf-bb-config

Specifically for the BBDEV ACC100 PMD, the command below can be used:

.. code-block:: console

  ./pf_bb_config ACC100 -c acc100/acc100_config_vf_5g.cfg
  ./test-bbdev.py -e="-l 4-11 -a${VF_PCI_ADDR}" -c validation -n 64 -b 32 -l 1 -v ./ldpc_dec_default.data

---

### Doc Guides Bbdevs Fpga 5gnr Fec (`doc/guides/bbdevs/fpga_5gnr_fec.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2019 Intel Corporation

Intel(R) FPGA 5GNR FEC Poll Mode Driver
=======================================

The BBDEV FPGA 5GNR FEC poll mode driver (PMD) supports an FPGA implementation of a VRAN
LDPC Encode / Decode 5GNR wireless acceleration function, using Intel's PCI-e and FPGA
based Vista Creek (N3000, referred to as VC_5GNR in the code)
as well as Arrow Creek (N6000, referred to as AGX100 in the code).

Features
--------

FPGA 5GNR FEC PMD supports the following BBDEV capabilities:

- LDPC Encode in the DL
- LDPC Decode in the UL
- Support for code block level processing
- 8 VFs per PF (physical device)
- Maximum of 32 UL queues per VF
- Maximum of 32 DL queues per VF
- PCIe Gen-3 x8 Interface
- MSI-X
- SR-IOV

FPGA 5GNR FEC PMD supports the following BBDEV capabilities:

* For the LDPC encode operation:
   - ``RTE_BBDEV_LDPC_CRC_24B_ATTACH`` :  set to attach CRC24B to CB(s)
   - ``RTE_BBDEV_LDPC_RATE_MATCH`` :  if set then do not do Rate Match bypass

* For the LDPC decode operation:
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK`` :  check CRC24B from CB(s)
   - ``RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE`` :  disable early termination
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP`` :  drops CRC24B bits appended while decoding
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE`` :  provides an input for HARQ combining
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE`` :  provides an input for HARQ combining
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_IN_ENABLE`` :  HARQ memory input is internal
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_OUT_ENABLE`` :  HARQ memory output is internal
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_LOOPBACK`` :  loopback data to/from HARQ memory
   - ``RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_FILLERS`` :  HARQ memory includes the fillers bits


Limitations
-----------

FPGA 5GNR FEC does not support the following:

- Scatter-Gather function


Installation
------------

See :doc:`/linux_gsg/build_dpdk` for build instructions.

DPDK requires hugepages to be configured as described in :ref:`linux_gsg_hugepages`.
The bbdev test application has been tested with a configuration 40 x 1GB hugepages. The
hugepage configuration of a server may be examined using:

.. code-block:: console

   grep Huge* /proc/meminfo


Initialization
--------------

When the device first powers up, its PCI Physical Functions (PF) can be listed through this command:

Vista Creek (N3000)

.. code-block:: console

  sudo lspci -vd8086:0d8f

Arrow Creek (N6000)

.. code-block:: console

  sudo lspci -vd8086:5799

The physical and virtual functions are compatible with Linux UIO drivers:
``vfio_pci`` and ``igb_uio``. However, in order to work the FPGA 5GNR FEC device firstly needs
to be bound to one of these linux drivers through DPDK.

For more details on how to bind the PF device and create VF devices, see
:ref:`linux_gsg_binding_kernel`.


Configure the VFs through PF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The PCI virtual functions must be configured before working or getting assigned
to VMs/Containers. The configuration involves allocating the number of hardware
queues, priorities, load balance, bandwidth and other settings necessary for the
device to perform FEC functions.

This configuration needs to be executed at least once after reboot or PCI FLR and can
be achieved by using the function ``rte_fpga_5gnr_fec_configure()``, which sets up the
parameters defined in ``rte_fpga_5gnr_fec_conf`` structure:

.. code-block:: c

  struct rte_fpga_5gnr_fec_conf {
      bool pf_mode_en;
      uint8_t vf_ul_queues_number[FPGA_5GNR_FEC_NUM_VFS];
      uint8_t vf_dl_queues_number[FPGA_5GNR_FEC_NUM_VFS];
      uint8_t ul_bandwidth;
      uint8_t dl_bandwidth;
      uint8_t ul_load_balance;
      uint8_t dl_load_balance;
  };

- ``pf_mode_en``: identifies whether only PF is to be used, or the VFs. PF and
  VFs are mutually exclusive and cannot run simultaneously.
  Set to 1 for PF mode enabled.
  If PF mode is enabled all queues available in the device are assigned
  exclusively to PF and 0 queues given to VFs.

- ``vf_*l_queues_number``: defines the hardware queue mapping for every VF.

- ``*l_bandwidth``: Only used for the Vista Creek schedule algorithm
  in case of congestion on PCIe interface.
  The device allocates different bandwidth to UL and DL.
  The weight is configured by this setting.
  The unit of weight is 3 code blocks.
  For example, if the code block cbps (code block per second) ratio
  between UL and DL is 12:1, then the configuration value should be set to 36:3.
  The schedule algorithm is based on code block regardless the length of each block.

- ``*l_load_balance``: hardware queues are load-balanced in a round-robin
  fashion. Queues get filled first-in first-out until they reach a pre-defined
  watermark level, if exceeded, they won't get assigned new code blocks..
  This watermark is defined by this setting.

  If all hardware queues exceeds the watermark, no code blocks will be
  streamed in from UL/DL code block FIFO.


An example configuration code calling the function ``rte_fpga_5gnr_fec_configure()`` is shown
below:

.. code-block:: c

  struct rte_fpga_5gnr_fec_conf conf;
  unsigned int i;

  memset(&conf, 0, sizeof(struct rte_fpga_5gnr_fec_conf));
  conf.pf_mode_en = 1;

  for (i = 0; i < FPGA_5GNR_FEC_NUM_VFS; ++i) {
      conf.vf_ul_queues_number[i] = 4;
      conf.vf_dl_queues_number[i] = 4;
  }
  conf.ul_bandwidth = 12;
  conf.dl_bandwidth = 5;
  conf.dl_load_balance = 64;
  conf.ul_load_balance = 64;

  /* setup FPGA PF */
  ret = rte_fpga_5gnr_fec_configure(info->dev_name, &conf);
  TEST_ASSERT_SUCCESS(ret,
      "Failed to configure 5GNR FPGA PF for bbdev %s",
      info->dev_name);


Test Application
----------------

BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing
the functionality of the device, depending on the device's capabilities.

.. code-block:: console

   "-p", "--testapp-path": specifies path to the bbdev test app.
   "-e", "--eal-params"	: EAL arguments which are passed to the test app.
   "-t", "--timeout"	: Timeout in seconds (default=300).
   "-c", "--test-cases"	: Defines test cases to run. Run all if not specified.
   "-v", "--test-vector"	: Test vector path (default=dpdk_path+/app/test-bbdev/test_vectors/bbdev_null.data).
   "-n", "--num-ops"	: Number of operations to process on device (default=32).
   "-b", "--burst-size"	: Operations enqueue/dequeue burst size (default=32).
   "-l", "--num-lcores"	: Number of lcores to run (default=16).
   "-i", "--init-device" : Initialise PF device with default values.


To execute the test application tool using simple decode or encode data,
type one of the following:

.. code-block:: console

   ./test-bbdev.py -c validation -n 64 -b 1 -v ./ldpc_dec_default.data
   ./test-bbdev.py -c validation -n 64 -b 1 -v ./ldpc_enc_default.data


The test application ``test-bbdev.py`` supports the ability to configure the PF device
with a default set of values, if the "-i" or "- -init-device" option is included.
The default values are defined in ``test_bbdev_perf.c`` as:

- VF_UL_QUEUE_VALUE 4
- VF_DL_QUEUE_VALUE 4
- UL_BANDWIDTH 3
- DL_BANDWIDTH 3
- UL_LOAD_BALANCE 128
- DL_LOAD_BALANCE 128


Test Vectors
~~~~~~~~~~~~

In addition to the simple LDPC decoder and LDPC encoder tests, bbdev also provides
a range of additional tests under the test_vectors folder, which may be useful. The results
of these tests will depend on the FPGA 5GNR FEC capabilities.


Alternate Baseband Device configuration tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On top of the embedded configuration feature supported in test-bbdev using "- -init-device"
option, there is also a tool available to perform that device configuration using a companion
application.
The ``pf_bb_config`` application notably enables then to run bbdev-test from the VF
and not only limited to the PF as captured above.

See for more details: https://github.com/intel/pf-bb-config

Specifically for the BBDEV FPGA 5GNR FEC PMD, the command below can be used:

Vista Creek (N3000)

.. code-block:: console

  ./pf_bb_config FPGA_5GNR -c fpga_5gnr/fpga_5gnr_config_vf.cfg
  ./test-bbdev.py -e="-l 4-11 -a${VF_PCI_ADDR}" -c validation -n 64 -b 32 -l 1 -v ./ldpc_dec_default.data

Arrow Creek (N6000)

.. code-block:: console

  ./pf_bb_config AGX100 -c agx100/agx100_config_1vf.cfg
  ./test-bbdev.py -e="-l 4-11 -a${VF_PCI_ADDR}" -c validation -n 64 -b 32 -l 1 -v ./ldpc_dec_default.data

---

### Doc Guides Bbdevs Fpga Lte Fec (`doc/guides/bbdevs/fpga_lte_fec.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2019 Intel Corporation

Intel(R) FPGA LTE FEC Poll Mode Driver
======================================

The BBDEV FPGA LTE FEC poll mode driver (PMD) supports an FPGA implementation of a VRAN
Turbo Encode / Decode LTE wireless acceleration function, using Intel's PCI-e and FPGA
based Vista Creek device.

Features
--------

FPGA LTE FEC PMD supports the following features:

- Turbo Encode in the DL with total throughput of 4.5 Gbits/s
- Turbo Decode in the UL with total throughput of 1.5 Gbits/s assuming 8 decoder iterations
- Support for code block level processing
- 8 VFs per PF (physical device)
- Maximum of 32 UL queues per VF
- Maximum of 32 DL queues per VF
- PCIe Gen-3 x8 Interface
- MSI-X
- SR-IOV


FPGA LTE FEC PMD supports the following BBDEV capabilities:

* For the turbo encode operation:
   - ``RTE_BBDEV_TURBO_CRC_24B_ATTACH`` :  set to attach CRC24B to CB(s)
   - ``RTE_BBDEV_TURBO_RATE_MATCH`` :  if set then do not do Rate Match bypass
   - ``RTE_BBDEV_TURBO_ENC_INTERRUPTS`` :  set for encoder dequeue interrupts


* For the turbo decode operation:
   - ``RTE_BBDEV_TURBO_CRC_TYPE_24B`` :  check CRC24B from CB(s)
   - ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE`` :  perform subblock de-interleave
   - ``RTE_BBDEV_TURBO_DEC_INTERRUPTS`` :  set for decoder dequeue interrupts
   - ``RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN`` :  set if negative LLR encoder i/p is supported
   - ``RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP`` :  keep CRC24B bits appended while decoding


Limitations
-----------

FPGA LTE FEC does not support the following:

- Scatter-Gather function


Installation
------------

See :doc:`/linux_gsg/build_dpdk` for build instructions.

DPDK requires hugepages to be configured as described in :ref:`linux_gsg_hugepages`.
The bbdev test application has been tested with a configuration 40 x 1GB hugepages. The
hugepage configuration of a server may be examined using:

.. code-block:: console

   grep Huge* /proc/meminfo


Initialization
--------------

When the device first powers up, its PCI Physical Functions (PF) can be listed through this command:

.. code-block:: console

  sudo lspci -vd1172:5052

The physical and virtual functions are compatible with Linux UIO drivers:
``vfio_pci`` and ``igb_uio``. However, in order to work the FPGA LTE FEC device firstly needs
to be bound to one of these linux drivers through DPDK.

For more details on how to bind the PF device and create VF devices, see
:ref:`linux_gsg_binding_kernel`.


Configure the VFs through PF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The PCI virtual functions must be configured before working or getting assigned
to VMs/Containers. The configuration involves allocating the number of hardware
queues, priorities, load balance, bandwidth and other settings necessary for the
device to perform FEC functions.

This configuration needs to be executed at least once after reboot or PCI FLR and can
be achieved by using the function ``rte_fpga_lte_fec_configure()``, which sets up the
parameters defined in ``rte_fpga_lte_fec_conf`` structure:

.. code-block:: c

  struct rte_fpga_lte_fec_conf {
      bool pf_mode_en;
      uint8_t vf_ul_queues_number[FPGA_LTE_FEC_NUM_VFS];
      uint8_t vf_dl_queues_number[FPGA_LTE_FEC_NUM_VFS];
      uint8_t ul_bandwidth;
      uint8_t dl_bandwidth;
      uint8_t ul_load_balance;
      uint8_t dl_load_balance;
      uint16_t flr_time_out;
  };

- ``pf_mode_en``: identifies whether only PF is to be used, or the VFs. PF and
  VFs are mutually exclusive and cannot run simultaneously.
  Set to 1 for PF mode enabled.
  If PF mode is enabled all queues available in the device are assigned
  exclusively to PF and 0 queues given to VFs.

- ``vf_*l_queues_number``: defines the hardware queue mapping for every VF.

- ``*l_bandwidth``: in case of congestion on PCIe interface. The device
  allocates different bandwidth to UL and DL. The weight is configured by this
  setting. The unit of weight is 3 code blocks. For example, if the code block
  cbps (code block per second) ratio between UL and DL is 12:1, then the
  configuration value should be set to 36:3. The schedule algorithm is based
  on code block regardless the length of each block.

- ``*l_load_balance``: hardware queues are load-balanced in a round-robin
  fashion. Queues get filled first-in first-out until they reach a pre-defined
  watermark level, if exceeded, they won't get assigned new code blocks..
  This watermark is defined by this setting.

  If all hardware queues exceeds the watermark, no code blocks will be
  streamed in from UL/DL code block FIFO.

- ``flr_time_out``: specifies how many 16.384us to be FLR time out. The
  time_out = flr_time_out x 16.384us. For instance, if you want to set 10ms for
  the FLR time out then set this setting to 0x262=610.


An example configuration code calling the function ``rte_fpga_lte_fec_configure()`` is shown
below:

.. code-block:: c

  struct rte_fpga_lte_fec_conf conf;
  unsigned int i;

  memset(&conf, 0, sizeof(struct rte_fpga_lte_fec_conf));
  conf.pf_mode_en = 1;

  for (i = 0; i < FPGA_LTE_FEC_NUM_VFS; ++i) {
      conf.vf_ul_queues_number[i] = 4;
      conf.vf_dl_queues_number[i] = 4;
  }
  conf.ul_bandwidth = 12;
  conf.dl_bandwidth = 5;
  conf.dl_load_balance = 64;
  conf.ul_load_balance = 64;

  /* setup FPGA PF */
  ret = rte_fpga_lte_fec_configure(info->dev_name, &conf);
  TEST_ASSERT_SUCCESS(ret,
      "Failed to configure 4G FPGA PF for bbdev %s",
      info->dev_name);


Test Application
----------------

BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing
the functionality of the device, depending on the device's capabilities.

For more details on how to use the test application,
see :doc:`/tools/testbbdev`.

Test Vectors
~~~~~~~~~~~~

In addition to the simple turbo decoder and turbo encoder tests, bbdev also provides
a range of additional tests under the test_vectors folder, which may be useful. The results
of these tests will depend on the FPGA LTE FEC capabilities:

* turbo decoder tests:
   - ``turbo_dec_c1_k6144_r0_e10376_crc24b_sbd_negllr_high_snr.data``
   - ``turbo_dec_c1_k6144_r0_e10376_crc24b_sbd_negllr_low_snr.data``
   - ``turbo_dec_c1_k6144_r0_e34560_negllr.data``
   - ``turbo_dec_c1_k6144_r0_e34560_sbd_negllr.data``
   - ``turbo_dec_c2_k3136_r0_e4920_sbd_negllr_crc24b.data``
   - ``turbo_dec_c2_k3136_r0_e4920_sbd_negllr.data``


* turbo encoder tests:
   - ``turbo_enc_c1_k40_r0_e1190_rm.data``
   - ``turbo_enc_c1_k40_r0_e1194_rm.data``
   - ``turbo_enc_c1_k40_r0_e1196_rm.data``
   - ``turbo_enc_c1_k40_r0_e272_rm.data``
   - ``turbo_enc_c1_k6144_r0_e18444.data``
   - ``turbo_enc_c1_k6144_r0_e32256_crc24b_rm.data``
   - ``turbo_enc_c2_k5952_r0_e17868_crc24b.data``
   - ``turbo_enc_c3_k4800_r2_e14412_crc24b.data``
   - ``turbo_enc_c4_k4800_r2_e14412_crc24b.data``


Alternate Baseband Device configuration tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On top of the embedded configuration feature supported in test-bbdev using "- -init-device"
option, there is also a tool available to perform that device configuration using a companion
application.
The ``pf_bb_config`` application notably enables then to run bbdev-test from the VF
and not only limited to the PF as captured above.

See for more details: https://github.com/intel/pf-bb-config

Specifically for the BBDEV FPGA LTE FEC PMD, the command below can be used:

.. code-block:: console

  ./pf_bb_config FPGA_LTE -c fpga_lte/fpga_lte_config_vf.cfg
  ./test-bbdev.py -e="-l 4-11 -a${VF_PCI_ADDR}" -c validation -n 64 -b 32 -l 1 -v ./turbo_dec_default.data

---

### Doc Guides Bbdevs Index (`doc/guides/bbdevs/index.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2017 Intel Corporation

Baseband Device Drivers
=======================

.. toctree::
    :maxdepth: 1
    :numbered:

    overview
    null
    turbo_sw
    fpga_lte_fec
    fpga_5gnr_fec
    acc100
    vrb1
    vrb2
    la12xx

---

### Doc Guides Bbdevs La12xx (`doc/guides/bbdevs/la12xx.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2021 NXP

NXP LA12xx Poll Mode Driver
===========================

The BBDEV LA12xx poll mode driver (PMD) supports an implementation for
offloading High Phy processing functions like LDPC Encode / Decode 5GNR wireless
acceleration function, using PCI based LA12xx Software defined radio.

More information can be found at `NXP Official Website
<https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-access-la1200-programmable-baseband-processor:LA1200>`_.

Features
--------

LA12xx PMD supports the following features:

- Maximum of 8 LDPC decode (UL) queues
- Maximum of 8 LDPC encode (DL) queues
- PCIe Gen-3 x8 Interface

Installation
------------

See :doc:`/linux_gsg/build_dpdk` for build instructions.

DPDK requires hugepages to be configured as described in :ref:`linux_gsg_hugepages`.

Initialization
--------------

The device can be listed on the host console with:


Use the following lspci command to get the multiple LA12xx processor ids. The
device ID of the LA12xx baseband processor is "1c30".

.. code-block:: console

  sudo lspci -nn

...
0001:01:00.0 Power PC [0b20]: Freescale Semiconductor Inc Device [1957:1c30] (
rev 10)
...
0002:01:00.0 Power PC [0b20]: Freescale Semiconductor Inc Device [1957:1c30] (
rev 10)


Prerequisites
-------------

Currently supported by DPDK:

- NXP LA1224 BSP **1.0+**.
- NXP LA1224 PCIe Modem card connected to ARM host.

- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.

* Use dev arg option ``modem=0`` to identify the modem instance for a given
  device. This is required only if more than 1 modem cards are attached to host.
  this is optional and the default value is 0.
  e.g. ``--vdev=baseband_la12xx,modem=0``

* Use dev arg option ``max_nb_queues=x`` to specify the maximum number of queues
  to be used for communication with offload device i.e. modem. default is 16.
  e.g. ``--vdev=baseband_la12xx,max_nb_queues=4``

Enabling logs
-------------

For enabling logs, use the following EAL parameter:

.. code-block:: console

   ./your_bbdev_application <EAL args> --log-level=la12xx:<level>

Using ``bb.la12xx`` as log matching criteria, all Baseband PMD logs can be
enabled which are lower than logging ``level``.

Test Application
----------------

BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing
the functionality of the device, depending on the device's capabilities.

For more details on how to use the test application,
see :doc:`/tools/testbbdev`.


Test Vectors
~~~~~~~~~~~~

In addition to the simple LDPC decoder and LDPC encoder tests, bbdev also provides
a range of additional tests under the test_vectors folder, which may be useful. The results
of these tests will depend on the LA12xx FEC capabilities which may cause some
testcases to be skipped, but no failure should be reported.

---

### Doc Guides Bbdevs Null (`doc/guides/bbdevs/null.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2017 Intel Corporation

BBDEV null Poll Mode Driver
===========================

The (**baseband_null**) is a bbdev poll mode driver which provides a minimal
implementation of a software bbdev device. As a null device it does not modify
the data in the mbuf on which the bbdev operation is to operate and it only
works for operation type ``RTE_BBDEV_OP_NONE``.

When a burst of mbufs is submitted to a *bbdev null PMD* for processing then
each mbuf in the burst will be enqueued in an internal buffer ring to be
collected on a dequeue call.


Limitations
-----------

* In-place operations for Turbo encode and decode are not supported

Installation
------------

The *bbdev null PMD* is enabled and built by default in both the Linux and
FreeBSD builds.

Initialization
--------------

To use the PMD in an application, user must:

- Call ``rte_vdev_init("baseband_null")`` within the application.

- Use ``--vdev="baseband_null"`` in the EAL options, which will call ``rte_vdev_init()`` internally.

The following parameters (all optional) can be provided in the previous two calls:

* ``socket_id``: Specify the socket where the memory for the device is going to be allocated
  (by default, *socket_id* will be the socket where the core that is creating the PMD is running on).

* ``max_nb_queues``: Specify the maximum number of queues in the device (default is ``RTE_MAX_LCORE``).

Example:
~~~~~~~~

.. code-block:: console

    ./test-bbdev.py -e="--vdev=baseband_null,socket_id=0,max_nb_queues=8"

---

### Doc Guides Bbdevs Overview (`doc/guides/bbdevs/overview.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2020 Intel Corporation.

Baseband Device Supported Functionality Matrices
================================================

Supported Feature Flags
-----------------------

.. include:: overview_feature_table.txt

---

### Doc Guides Bbdevs Turbo Sw (`doc/guides/bbdevs/turbo_sw.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2017 Intel Corporation

SW Turbo Poll Mode Driver
=========================

The SW Turbo PMD (**baseband_turbo_sw**) provides a software only poll mode bbdev
driver that can optionally utilize Intel optimized libraries for LTE and 5GNR
Layer 1 workloads acceleration.

Note that the driver can also be built without any dependency with reduced
functionality for maintenance purpose.

To enable linking to the SDK libraries see detailed installation section below.

This PMD supports the functions: FEC, Rate Matching and CRC functions detailed
in the Features section.

Features
--------

SW Turbo PMD can support for the following capabilities when the SDK libraries
are used:

For the LTE encode operation:

* ``RTE_BBDEV_TURBO_CRC_24A_ATTACH``
* ``RTE_BBDEV_TURBO_CRC_24B_ATTACH``
* ``RTE_BBDEV_TURBO_RATE_MATCH``
* ``RTE_BBDEV_TURBO_RV_INDEX_BYPASS``

For the LTE decode operation:

* ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE``
* ``RTE_BBDEV_TURBO_CRC_TYPE_24B``
* ``RTE_BBDEV_TURBO_POS_LLR_1_BIT_IN``
* ``RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN``
* ``RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP``
* ``RTE_BBDEV_TURBO_EARLY_TERMINATION``

For the 5G NR LDPC encode operation:

* ``RTE_BBDEV_LDPC_RATE_MATCH``
* ``RTE_BBDEV_LDPC_CRC_24A_ATTACH``
* ``RTE_BBDEV_LDPC_CRC_24B_ATTACH``

For the 5G NR LDPC decode operation:

* ``RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK``
* ``RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK``
* ``RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP``
* ``RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE``
* ``RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE``
* ``RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE``

Limitations
-----------

* In-place operations for encode and decode are not supported

Installation
------------

FlexRAN SDK Download
~~~~~~~~~~~~~~~~~~~~

As an option it is possible to link this driver with FleXRAN SDK libraries
which can enable real time signal processing using AVX instructions.

These libraries are available through this `link
<https://github.com/intel/FlexRAN-FEC-SDK-Modules/tree/Branch_FEC_SDK_23.07>`_.

After download is complete, the user needs to unpack and compile on their
system before building DPDK.

To get the FlexRAN FEC SDK user manual, extract this `doxygen
<https://github.com/intel/FlexRAN-FEC-SDK-Modules/blob/Branch_FEC_SDK_23.07/doc/doxygen/html.zip>`_.

The following table maps DPDK versions with past FlexRAN SDK releases:

.. table:: DPDK and FlexRAN FEC SDK releases compliance

   =====================  ============================
   DPDK version           FlexRAN FEC SDK release
   =====================  ============================
   19.08 to 22.07         19.04
   22.11+                 22.11
   23.11+                 FEC_SDK_23.07
   =====================  ============================

FlexRAN SDK Installation
~~~~~~~~~~~~~~~~~~~~~~~~

Note that the installation of these libraries is optional.

The following are pre-requisites for building FlexRAN SDK Libraries:
 (a) An AVX512 supporting machine.
 (b) Ubuntu Linux release 22.04 operating system is advised.
 (c) Intel ICX 2023.0.0 compiler or more recent and related libraries.
     ICX is available `here <https://docs.o-ran-sc.org/projects/o-ran-sc-o-du-phy/en/latest/build_prerequisite.html#download-and-install-oneapi>`_.
 (d) `FlexRAN SDK Modules <https://github.com/intel/FlexRAN-FEC-SDK-Modules/tree/Branch_FEC_SDK_23.07>`_.
 (e) CMake 3.9.2 (Minimum 2.8.12)
 (f) Google Test 1.7.0 (Required to run the verification and compute performance tests)
 (g) Math Kernel Library 18.0 (Required by some functions in SDK)

The following instructions should be followed in this exact order:

#. Clone the SDK (folder name needs to end in 'sdk')

    .. code-block:: console

        git clone -b Branch_FEC_SDK_23.07 https://github.com/intel/FlexRAN-FEC-SDK-Modules.git flexran_sdk

#. Set the environment variables:

    .. code-block:: console

        source <path-to-workspace>/export_settings.sh -o -avx512

#. Generate makefiles based on system configuration:

    .. code-block:: console

        cd <path-to-workspace>
        ./create-makefiles-linux.sh

#. A build folder is generated in this form ``build-<ISA>-<CC>``, enter that
   folder and install:

    .. code-block:: console

        cd <path-to-workspace>/build-${WIRELESS_SDK_TARGET_ISA}-${WIRELESS_SDK_TOOLCHAIN}/
        make -j$(nproc) && make install

DPDK Initialization
~~~~~~~~~~~~~~~~~~~

In order to enable this virtual bbdev PMD, the user may:

* Build the ``FLEXRAN SDK`` libraries (explained in Installation section).

* Export the environmental variables ``FLEXRAN_SDK`` to the path where the
  FlexRAN SDK libraries were installed. And ``DIR_WIRELESS_SDK`` to the path
  where the libraries were extracted.

* Point pkgconfig towards these libraries so that they can be automatically found by meson.
  If not, DPDK will still compile but the related functionality would be stubbed out.

Example:

.. code-block:: console

    export FLEXRAN_SDK=<path-to-workspace>/build-${WIRELESS_SDK_TARGET_ISA}-${WIRELESS_SDK_TOOLCHAIN}/install
    export DIR_WIRELESS_SDK=<path-to-workspace>/build-${WIRELESS_SDK_TARGET_ISA}-${WIRELESS_SDK_TOOLCHAIN}
    export PKG_CONFIG_PATH=${DIR_WIRELESS_SDK}/pkgcfg:${PKG_CONFIG_PATH}
    cd build
    meson configure

* For AVX512 machines with SDK libraries installed then both 4G and 5G can be enabled for full real time FEC capability.
  For AVX2 machines it is possible to only enable the 4G libraries and the PMD capabilities will be limited to 4G FEC.
  If no library is present then the PMD will still build but its capabilities will be limited accordingly.

SW Turbo PMD Usage
~~~~~~~~~~~~~~~~~~

To use the PMD in an application, user must:

- Call ``rte_vdev_init("baseband_turbo_sw")`` within the application.

- Use ``--vdev="baseband_turbo_sw"`` in the EAL options, which will call ``rte_vdev_init()`` internally.

The following parameters (all optional) can be provided in the previous two calls:

* ``socket_id``: Specify the socket where the memory for the device is going to be allocated
  (by default, *socket_id* will be the socket where the core that is creating the PMD is running on).

* ``max_nb_queues``: Specify the maximum number of queues in the device (default is ``RTE_MAX_LCORE``).

Example:

.. code-block:: console

    ./test-bbdev.py -e="--vdev=baseband_turbo_sw,socket_id=0,max_nb_queues=8" \
    -c validation -v ./turbo_*_default.data

---

### Doc Guides Bbdevs Vrb1 (`doc/guides/bbdevs/vrb1.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2022 Intel Corporation

.. include:: <isonum.txt>

Intel\ |reg| vRAN Boost Poll Mode Driver (PMD)
==============================================

The Intel\ |reg| vRAN Boost integrated accelerator enables
cost-effective 4G and 5G next-generation virtualized Radio Access Network (vRAN)
solutions.
The Intel vRAN Boost v1.0 (VRB1 in the code) is specifically integrated on the
4th Gen Intel\ |reg| Xeon\ |reg| Scalable processor with Intel\ |reg| vRAN Boost,
also known as Sapphire Rapids Edge Enhanced (SPR-EE).

Features
--------

Intel vRAN Boost v1.0 includes a 5G Low Density Parity Check (LDPC) encoder/decoder,
rate match/dematch, Hybrid Automatic Repeat Request (HARQ) with access to DDR
memory for buffer management, a 4G Turbo encoder/decoder,
a Fast Fourier Transform (FFT) block providing DFT/iDFT processing offload
for the 5G Sounding Reference Signal (SRS), a Queue Manager (QMGR),
and a DMA subsystem.
There is no dedicated on-card memory for HARQ, the coherent memory on the CPU side is being used.

These hardware blocks provide the following features exposed by the PMD:

- LDPC Encode in the Downlink (5GNR)
- LDPC Decode in the Uplink (5GNR)
- Turbo Encode in the Downlink (4G)
- Turbo Decode in the Uplink (4G)
- Support for code block level processing
- FFT processing
- Single Root I/O Virtualization (SR-IOV) with 16 Virtual Functions (VFs) per Physical Function (PF)
- Maximum of 256 queues per VF

The Intel vRAN Boost v1.0 PMD supports the following bbdev capabilities:

* For the LDPC encode operation:
   - ``RTE_BBDEV_LDPC_CRC_24B_ATTACH``: set to attach CRC24B to CB(s).
   - ``RTE_BBDEV_LDPC_RATE_MATCH``: if set then do not do Rate Match bypass.
   - ``RTE_BBDEV_LDPC_INTERLEAVER_BYPASS``: if set then bypass interleaver.

* For the LDPC decode operation:
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK``: check CRC24B from CB(s).
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP``: drops CRC24B bits appended while decoding.
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK``: check CRC24A from CB(s).
   - ``RTE_BBDEV_LDPC_CRC_TYPE_16_CHECK``: check CRC16 from CB(s).
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE``: provides an input for HARQ combining.
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE``: provides an input for HARQ combining.
   - ``RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE``: disable early termination.
   - ``RTE_BBDEV_LDPC_DEC_SCATTER_GATHER``: supports scatter-gather for input/output data.
   - ``RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION``: supports compression of the HARQ input/output.
   - ``RTE_BBDEV_LDPC_LLR_COMPRESSION``: supports LLR input compression.

* For the turbo encode operation:
   - ``RTE_BBDEV_TURBO_CRC_24B_ATTACH``: set to attach CRC24B to CB(s).
   - ``RTE_BBDEV_TURBO_RATE_MATCH``: if set then do not do Rate Match bypass.
   - ``RTE_BBDEV_TURBO_RV_INDEX_BYPASS``: set to bypass RV index.
   - ``RTE_BBDEV_TURBO_ENC_SCATTER_GATHER``: supports scatter-gather for input/output data.

* For the turbo decode operation:
   - ``RTE_BBDEV_TURBO_CRC_TYPE_24B``: check CRC24B from CB(s).
   - ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE``: perform subblock de-interleave.
   - ``RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN``: set if negative LLR input is supported.
   - ``RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP``: keep CRC24B bits appended while decoding.
   - ``RTE_BBDEV_TURBO_DEC_CRC_24B_DROP``: option to drop the code block CRC after decoding.
   - ``RTE_BBDEV_TURBO_EARLY_TERMINATION``: set early termination feature.
   - ``RTE_BBDEV_TURBO_DEC_SCATTER_GATHER``: supports scatter-gather for input/output data.
   - ``RTE_BBDEV_TURBO_HALF_ITERATION_EVEN``: set half iteration granularity.
   - ``RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH``: set to run an extra odd iteration after CRC match.
   - ``RTE_BBDEV_TURBO_MAP_DEC``: supports flexible parallel MAP engine decoding.

* For the FFT operation:
   - ``RTE_BBDEV_FFT_WINDOWING``: flexible windowing capability.
   - ``RTE_BBDEV_FFT_CS_ADJUSTMENT``: flexible adjustment of Cyclic Shift time offset.
   - ``RTE_BBDEV_FFT_DFT_BYPASS``: set for bypass the DFT and get directly into iDFT input.
   - ``RTE_BBDEV_FFT_IDFT_BYPASS``: set for bypass the IDFT and get directly the DFT output.
   - ``RTE_BBDEV_FFT_WINDOWING_BYPASS``: set for bypass time domain windowing.


Installation
------------

See :doc:`/linux_gsg/build_dpdk` for build instructions.

DPDK requires hugepages to be configured as described in :ref:`linux_gsg_hugepages`.
The bbdev test application has been tested with a configuration 40 x 1GB hugepages.
The hugepage configuration of a server may be examined using:

.. code-block:: console

   grep Huge* /proc/meminfo


Initialization
--------------

When the device first powers up, its PCI Physical Functions (PF)
can be listed through these commands for Intel vRAN Boost v1:

.. code-block:: console

   sudo lspci -vd8086:57c0

The physical and virtual functions are compatible with Linux UIO drivers:
``vfio_pci`` and ``igb_uio``.
However, in order to work the 5G/4G FEC device first needs to be bound
to one of these Linux drivers through DPDK.

For more details on how to bind the PF device and create VF devices, see
:ref:`linux_gsg_binding_kernel`.


Configure the VFs through PF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The PCI virtual functions must be configured before working or getting assigned
to VMs/Containers.
The configuration involves allocating the number of hardware queues, priorities,
load balance, bandwidth and other settings necessary for the device
to perform FEC functions.

This configuration needs to be executed at least once after reboot or PCI FLR
and can be achieved by using the functions ``rte_acc200_configure()``,
which sets up the parameters defined in the compatible ``acc200_conf`` structure.


Test Application
----------------

BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing
the functionality of the device, depending on the device's capabilities.

For more details on how to use the test application,
see :doc:`/tools/testbbdev`.


Test Vectors
~~~~~~~~~~~~

In addition to the simple LDPC decoder and LDPC encoder tests,
bbdev also provides a range of additional tests under the test_vectors folder,
which may be useful.
The results of these tests will depend on the device capabilities which may
cause some test cases to be skipped, but no failure should be reported.


Alternate Baseband Device configuration tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On top of the embedded configuration feature supported in test-bbdev using
"- -init-device" option mentioned above, there is also a tool available
to perform that device configuration using a companion application.
The ``pf_bb_config`` application notably enables then to run bbdev-test
from the VF and not only limited to the PF as captured above.

See for more details: https://github.com/intel/pf-bb-config

Specifically for the bbdev Intel vRAN Boost v1 PMD, the command below can be used
(note that ACC200 was used previously to refer to VRB1):

.. code-block:: console

   pf_bb_config ACC200 -c ./acc200/acc200_config_vf_5g.cfg
   test-bbdev.py -e="-l 4-11 -a${VF_PCI_ADDR}" -c validation -n 64 -b 64 -l 1 -v ./ldpc_dec_default.data

---

### Doc Guides Bbdevs Vrb2 (`doc/guides/bbdevs/vrb2.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2023 Intel Corporation

.. include:: <isonum.txt>

Intel\ |reg| vRAN Boost v2 Poll Mode Driver (PMD)
=================================================

The Intel\ |reg| vRAN Boost integrated accelerator enables
cost-effective 4G and 5G next-generation virtualized Radio Access Network (vRAN)
solutions.
The Intel vRAN Boost v2.0 (VRB2 in the code) is specifically integrated on the
Intel\ |reg| Xeon\ |reg| Granite Rapids-D Process (GNR-D).

Features
--------

Intel vRAN Boost v2.0 includes a 5G Low Density Parity Check (LDPC) encoder/decoder,
rate match/dematch, Hybrid Automatic Repeat Request (HARQ) with access to DDR
memory for buffer management, a 4G Turbo encoder/decoder,
a Fast Fourier Transform (FFT) block providing DFT/iDFT processing offload
for the 5G Sounding Reference Signal (SRS), a MLD-TS accelerator, a Queue Manager (QMGR),
and a DMA subsystem.
There is no dedicated on-card memory for HARQ, the coherent memory on the CPU side is being used.

These hardware blocks provide the following features exposed by the PMD:

- LDPC Encode in the Downlink (5GNR)
- LDPC Decode in the Uplink (5GNR)
- Turbo Encode in the Downlink (4G)
- Turbo Decode in the Uplink (4G)
- Support for code block level processing
- Support for transport block level processing for the LDPC encode processing
  including code block concatenation.
- FFT processing
- MLD-TS processing
- Single Root I/O Virtualization (SR-IOV) with 16 Virtual Functions (VFs) per Physical Function (PF)
- Maximum of 2048 queues per VF
- Message Signaled Interrupts (MSIs)

The Intel vRAN Boost v2.0 PMD supports the following bbdev capabilities:

* For the LDPC encode operation:
   - ``RTE_BBDEV_LDPC_CRC_24B_ATTACH``: set to attach CRC24B to CB(s).
   - ``RTE_BBDEV_LDPC_RATE_MATCH``: if set then do not do Rate Match bypass.
   - ``RTE_BBDEV_LDPC_INTERLEAVER_BYPASS``: if set then bypass interleaver.
   - ``RTE_BBDEV_LDPC_ENC_SCATTER_GATHER``: supports scatter-gather for input/output data.
   - ``RTE_BBDEV_LDPC_ENC_CONCATENATION``: concatenate code blocks with bit granularity.

* For the LDPC decode operation:
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_CHECK``: check CRC24B from CB(s).
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24B_DROP``: drops CRC24B bits appended while decoding.
   - ``RTE_BBDEV_LDPC_CRC_TYPE_24A_CHECK``: check CRC24A from CB(s).
   - ``RTE_BBDEV_LDPC_CRC_TYPE_16_CHECK``: check CRC16 from CB(s).
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_IN_ENABLE``: provides an input for HARQ combining.
   - ``RTE_BBDEV_LDPC_HQ_COMBINE_OUT_ENABLE``: provides an input for HARQ combining.
   - ``RTE_BBDEV_LDPC_ITERATION_STOP_ENABLE``: disable early termination.
   - ``RTE_BBDEV_LDPC_DEC_SCATTER_GATHER``: supports scatter-gather for input/output data.
   - ``RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION``: supports compression of the HARQ input/output.
   - ``RTE_BBDEV_LDPC_LLR_COMPRESSION``: supports LLR input compression.
   - ``RTE_BBDEV_LDPC_HARQ_4BIT_COMPRESSION``: supports compression of the HARQ input/output.
   - ``RTE_BBDEV_LDPC_SOFT_OUT_ENABLE``: set the APP LLR soft output.
   - ``RTE_BBDEV_LDPC_SOFT_OUT_RM_BYPASS``: set the APP LLR soft output after rate-matching.
   - ``RTE_BBDEV_LDPC_SOFT_OUT_DEINTERLEAVER_BYPASS``: disables the de-interleaver.

* For the turbo encode operation:
   - ``RTE_BBDEV_TURBO_CRC_24B_ATTACH``: set to attach CRC24B to CB(s).
   - ``RTE_BBDEV_TURBO_RATE_MATCH``: if set then do not do Rate Match bypass.
   - ``RTE_BBDEV_TURBO_ENC_INTERRUPTS``: set for encoder dequeue interrupts.
   - ``RTE_BBDEV_TURBO_RV_INDEX_BYPASS``: set to bypass RV index.
   - ``RTE_BBDEV_TURBO_ENC_SCATTER_GATHER``: supports scatter-gather for input/output data.

* For the turbo decode operation:
   - ``RTE_BBDEV_TURBO_CRC_TYPE_24B``: check CRC24B from CB(s).
   - ``RTE_BBDEV_TURBO_SUBBLOCK_DEINTERLEAVE``: perform subblock de-interleave.
   - ``RTE_BBDEV_TURBO_DEC_INTERRUPTS``: set for decoder dequeue interrupts.
   - ``RTE_BBDEV_TURBO_NEG_LLR_1_BIT_IN``: set if negative LLR input is supported.
   - ``RTE_BBDEV_TURBO_DEC_TB_CRC_24B_KEEP``: keep CRC24B bits appended while decoding.
   - ``RTE_BBDEV_TURBO_DEC_CRC_24B_DROP``: option to drop the code block CRC after decoding.
   - ``RTE_BBDEV_TURBO_EARLY_TERMINATION``: set early termination feature.
   - ``RTE_BBDEV_TURBO_DEC_SCATTER_GATHER``: supports scatter-gather for input/output data.
   - ``RTE_BBDEV_TURBO_HALF_ITERATION_EVEN``: set half iteration granularity.
   - ``RTE_BBDEV_TURBO_SOFT_OUTPUT``: set the APP LLR soft output.
   - ``RTE_BBDEV_TURBO_EQUALIZER``: set the turbo equalizer feature.
   - ``RTE_BBDEV_TURBO_SOFT_OUT_SATURATE``: set the soft output saturation.
   - ``RTE_BBDEV_TURBO_CONTINUE_CRC_MATCH``: set to run an extra odd iteration after CRC match.
   - ``RTE_BBDEV_TURBO_NEG_LLR_1_BIT_SOFT_OUT``: set if negative APP LLR output supported.
   - ``RTE_BBDEV_TURBO_MAP_DEC``: supports flexible parallel MAP engine decoding.

* For the FFT operation:
   - ``RTE_BBDEV_FFT_WINDOWING``: flexible windowing capability.
   - ``RTE_BBDEV_FFT_CS_ADJUSTMENT``: flexible adjustment of Cyclic Shift time offset.
   - ``RTE_BBDEV_FFT_DFT_BYPASS``: set for bypass the DFT and get directly into iDFT input.
   - ``RTE_BBDEV_FFT_IDFT_BYPASS``: set for bypass the IDFT and get directly the DFT output.
   - ``RTE_BBDEV_FFT_WINDOWING_BYPASS``: set for bypass time domain windowing.

* For the MLD-TS operation:
   - ``RTE_BBDEV_MLDTS_REP``: set to repeat and reuse channel across operations.

Installation
------------

See :doc:`/linux_gsg/build_dpdk` for build instructions.

DPDK requires hugepages to be configured as described in :ref:`linux_gsg_hugepages`.
The bbdev test application has been tested with a configuration 40 x 1GB hugepages.
The hugepage configuration of a server may be examined using:

.. code-block:: console

   grep Huge* /proc/meminfo


Initialization
--------------

When the device first powers up, its PCI Physical Functions (PF)
can be listed through these commands for Intel vRAN Boost v2:

.. code-block:: console

   sudo lspci -vd8086:57c2

The physical and virtual functions are compatible with Linux UIO drivers:
``vfio`` (preferred) and ``igb_uio`` (legacy).
However, in order to work the 5G/4G FEC device first needs to be bound
to one of these Linux drivers through DPDK.


Configure the VFs through PF
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The PCI virtual functions must be configured before working or getting assigned
to VMs/Containers.
The configuration involves allocating the number of hardware queues, priorities,
load balance, bandwidth and other settings necessary for the device
to perform FEC functions.

This configuration needs to be executed at least once after reboot or PCI FLR
and can be achieved by using the functions ``rte_acc_configure()``,
which sets up the parameters defined in the compatible ``rte_acc_conf`` structure.


Test Application
----------------

BBDEV provides a test application, ``test-bbdev.py`` and range of test data for testing
the functionality of the device, depending on the device's capabilities.

For more details on how to use the test application,
see :doc:`/tools/testbbdev`.


Test Vectors
~~~~~~~~~~~~

In addition to the simple LDPC decoder and LDPC encoder tests,
bbdev also provides a range of additional tests under the test_vectors folder,
which may be useful.
The results of these tests will depend on the device capabilities which may
cause some test cases to be skipped, but no failure should be reported.


Alternate Baseband Device configuration tool
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On top of the embedded configuration feature supported in test-bbdev using
"- -init-device" option mentioned above, there is also a tool available
to perform that device configuration using a companion application.
The ``pf_bb_config`` application notably enables then to run bbdev-test
from the VF and not only limited to the PF as captured above.

See for more details: https://github.com/intel/pf-bb-config

Specifically for the bbdev Intel vRAN Boost v2 PMD, the command below can be used
(note that ACC200 was used previously to refer to VRB2):

.. code-block:: console

   pf_bb_config VRB2 -c ./vrb2/vrb2_config_vf_5g.cfg
   test-bbdev.py -e="-l 4-11 -a${VF_PCI_ADDR}" -c validation -n 64 -b 64 -l 1 -v ./ldpc_dec_default.data

---

### Doc Guides Compressdevs Index (`doc/guides/compressdevs/index.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 Intel Corporation.

Compression Device Drivers
==========================


.. toctree::
    :maxdepth: 1
    :numbered:

    overview
    isal
    mlx5
    nitrox
    octeontx
    qat_comp
    uadk
    zlib
    zsda

---

### Doc Guides Compressdevs Isal (`doc/guides/compressdevs/isal.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 Intel Corporation.

ISA-L Compression Poll Mode Driver
==================================

The ISA-L PMD (**librte_compress_isal**) provides poll mode compression &
decompression driver support for utilizing Intel ISA-L library,
which implements the deflate algorithm for both Deflate(compression) and Inflate(decompression).


Features
--------

ISA-L PMD has support for:

Compression/Decompression algorithm:

    * DEFLATE

Huffman code type:

    * FIXED
    * DYNAMIC

Window size support:

    * 32K

Checksum:

    * CRC32
    * ADLER32

To enable a checksum in the driver, the compression and/or decompression xform
structure, rte_comp_xform, must be filled with either of the CompressDev
checksum flags supported. ::

 compress_xform->compress.chksum = RTE_COMP_CHECKSUM_CRC32

 decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_CRC32

::

 compress_xform->compress.chksum = RTE_COMP_CHECKSUM_ADLER32

 decompress_xform->decompress.chksum = RTE_COMP_CHECKSUM_ADLER32

If you request a checksum for compression or decompression,
the checksum field in the operation structure,  ``op->output_chksum``,
will be filled with the checksum.

.. Note::

 For the compression case above, your output buffer will need to be large enough to hold the compressed data plus a scratchpad for the checksum at the end, the scratchpad is 8 bytes for CRC32 and 4 bytes for Adler32.

Level guide:

The ISA-L levels have been mapped to somewhat correspond to the same ZLIB level,
i.e. ZLIB L1 gives a compression ratio similar to ISA-L L1.
Compressdev level 0 enables "No Compression", which passes the uncompressed
data to the output buffer, plus deflate headers.
The ISA-L library does not support this, therefore compressdev level 0 is not supported.

The compressdev API has 10 levels, 0-9. ISA-L has 4 levels of compression, 0-3.
As a result the level mappings from the API to the PMD are shown below.

.. table:: Level mapping from Compressdev to ISA-L PMD.

   +-------------+----------------------------------------------+-----------------------------------------------+
   | Compressdev | PMD Functionality                            | Internal ISA-L                                |
   | API Level   |                                              | Level                                         |
   +=============+==============================================+===============================================+
   | 0           | No compression, Not Supported                | ---                                           |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 1           | Dynamic (Fast compression)                   | 1                                             |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 2           | Dynamic                                      | 2                                             |
   |             | (Higher compression ratio)                   |                                               |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 3           | Dynamic                                      | 3                                             |
   |             | (Best compression ratio)                     | (Level 2 if                                   |
   |             |                                              | no AVX512/AVX2)                               |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 4           | Dynamic (Best compression ratio)             | Same as above                                 |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 5           | Dynamic (Best compression ratio)             | Same as above                                 |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 6           | Dynamic (Best compression ratio)             | Same as above                                 |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 7           | Dynamic (Best compression ratio)             | Same as above                                 |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 8           | Dynamic (Best compression ratio)             | Same as above                                 |
   +-------------+----------------------------------------------+-----------------------------------------------+
   | 9           | Dynamic (Best compression ratio)             | Same as above                                 |
   +-------------+----------------------------------------------+-----------------------------------------------+

.. Note::

 The above table only shows mapping when API calls for dynamic compression.
 For fixed compression, regardless of API level, internally ISA-L level 0 is always used.


Limitations
-----------

* Compressdev level 0, no compression, is not supported.

Installation
------------

* To build DPDK with Intel's ISA-L library, the user is required to download the library from `<https://github.com/01org/isa-l>`_.

* Once downloaded, the user needs to build the library, the ISA-L autotools are usually sufficient::

    ./autogen.sh
    ./configure

* make can  be used to install the library on their system, before building DPDK::

    make
    sudo make install

* To build with meson, the **libisal.pc** file, must be copied into "pkgconfig",
  e.g. /usr/lib/pkgconfig or /usr/lib64/pkgconfig depending on your system,
  for meson to find the ISA-L library. The **libisal.pc** is located in library sources::

    cp isal/libisal.pc /usr/lib/pkgconfig/


Initialization
--------------

To use the PMD in an application, user must:

* Call ``rte_vdev_init("compress_isal")`` within the application.

* Use ``--vdev="compress_isal"`` in the EAL options, which will call ``rte_vdev_init()`` internally.

The following parameter (optional) can be provided in the previous two calls:

* ``socket_id:`` Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

---

### Doc Guides Compressdevs Mlx5 (`doc/guides/compressdevs/mlx5.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2021 Mellanox Technologies, Ltd

.. include:: <isonum.txt>

NVIDIA MLX5 Compress Driver
===========================

The mlx5 compress driver (``librte_compress_mlx5``)
provides support for NVIDIA DPU device family.

Design
------

This PMD is configuring the compress, decompress amd DMA engines.

GGAs (Generic Global Accelerators) are offload engines that can be used
to do memory to memory tasks on data.
These engines are part of the ARM complex of the BlueField chip, and as
such they do not use NIC related resources (e.g. RX/TX bandwidth).
They do share the same PCI and memory bandwidth.

So, using the BlueField device (starting from BlueField-2), the compress
class operations can be supported in parallel to the net, vDPA and
RegEx class operations.

See :doc:`/platform/mlx5` guide for more design details.

Features
--------

Compress mlx5 PMD has support for:

- Compression
- Decompression
- DMA

Algorithms
----------

NULL algorithm
~~~~~~~~~~~~~~

NULL algorithm is the way to perform DMA operations.
It works through either compress or decompress operation.

Shareable transformation.

Checksum generation:

* CRC32, Adler32 and combined checksum.

DEFLATE algorithm
~~~~~~~~~~~~~~~~~

Huffman code type:

* FIXED.
* DYNAMIC.

Window size support:

1KB, 2KB, 4KB, 8KB, 16KB and 32KB.

Shareable transformation.

Checksum generation:

* CRC32, Adler32 and combined checksum.

LZ4 algorithm
~~~~~~~~~~~~~

Support for flags:

* ``RTE_COMP_LZ4_FLAG_BLOCK_CHECKSUM``
* ``RTE_COMP_LZ4_FLAG_BLOCK_INDEPENDENCE``

Window size support:

1KB, 2KB, 4KB, 8KB, 16KB and 32KB.

Shareable transformation.

Checksum generation:

* xxHash-32 checksum.

Limitations
-----------

* Scatter-Gather, SHA and Stateful are not supported.
* Non-compressed block is not supported in compress (supported in decompress).
* Compress operation is not supported by BlueField-3.
* LZ4 algorithm is not supported by BlueField-2.

Driver options
--------------

Please refer to :ref:`mlx5 common options <mlx5_common_driver_options>`
for an additional list of options shared with other mlx5 drivers.

- ``log-block-size`` parameter [int]

  Log of the Huffman block size in the Deflate algorithm.
  Values from [4-15]; value x means block size is 2\ :sup:`x`.
  The default value is 15.


Supported Devices
-----------------

* NVIDIA\ |reg| BlueField-2 DPU
* NVIDIA\ |reg| BlueField-3 DPU/SuperNIC

Prerequisites
-------------

- NVIDIA MLNX_OFED version: **5.2**
  See :ref:`mlx5 common prerequisites <mlx5_linux_prerequisites>` for more details.

---

### Doc Guides Compressdevs Nitrox (`doc/guides/compressdevs/nitrox.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2024 Marvell.

Marvell NITROX Compression Poll Mode Driver
===========================================

The Nitrox compression poll mode driver provides support for offloading
compression and decompression operations to the NITROX V processor.
Detailed information about the NITROX V processor can be obtained here:

* https://www.marvell.com/security-solutions/nitrox-security-processors/nitrox-v/

Features
--------

NITROX V compression PMD has support for:

Compression/Decompression algorithm:

* DEFLATE

Huffman code type:

* FIXED
* DYNAMIC

Window size support:

* Min - 2 bytes
* Max - 32KB

Checksum generation:

* CRC32, Adler

Limitations
-----------

* Compressdev level 0, no compression, is not supported.

Initialization
--------------

Nitrox compression PMD depends on Nitrox kernel PF driver being installed on the platform.
Nitrox PF driver is required to create VF devices which will be used by the PMD.
Each VF device can enable one compressdev PMD.

Nitrox kernel PF driver is available as part of CNN55XX-Driver SDK.
The SDK and its installation instructions can be obtained from:
`Marvell Customer Portal <https://www.marvell.com/support/extranets.html>`_.

---

### Doc Guides Compressdevs Octeontx (`doc/guides/compressdevs/octeontx.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 Cavium Networks.

OCTEON TX ZIP Compression Poll Mode Driver
==========================================

The OCTEON TX ZIP PMD (**librte_compress_octeontx**) provides poll mode
compression & decompression driver for ZIP HW offload device, found in
**Cavium OCTEON TX** SoC family.

More information can be found at `Cavium, Inc Official Website
<http://www.cavium.com/OCTEON-TX_ARM_Processors.html>`_.

Features
--------

OCTEON TX ZIP PMD has support for:

Compression/Decompression algorithm:

* DEFLATE

Huffman code type:

* FIXED
* DYNAMIC

Window size support:

* 2 to 2^14

Limitations
-----------

* Chained mbufs are not supported.

Supported OCTEON TX SoCs
------------------------

- CN83xx

Steps To Setup Platform
-----------------------

   OCTEON TX SDK includes kernel image which provides OCTEON TX ZIP PF
   driver to manage configuration of ZIPVF device
   Required version of SDK is "OCTEONTX-SDK-6.2.0-build35" or above.

   SDK can be install by using below command.
   #rpm -ivh OCTEONTX-SDK-6.2.0-build35.x86_64.rpm --force --nodeps
   It will install OCTEONTX-SDK at following default location
   /usr/local/Cavium_Networks/OCTEONTX-SDK/

   For more information on building and booting linux kernel on OCTEON TX
   please refer /usr/local/Cavium_Networks/OCTEONTX-SDK/docs/OcteonTX-SDK-UG_6.2.0.pdf.

   SDK and related information can be obtained from: `Cavium support site <https://support.cavium.com/>`_.

Initialization
--------------

The OCTEON TX zip is exposed as pci device which consists of a set of
PCIe VF devices. On EAL initialization, ZIP PCIe VF devices will be
probed. To use the PMD in an application, user must:

* run dev_bind script to bind eight ZIP PCIe VFs to the ``vfio-pci`` driver:

   .. code-block:: console

      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.1
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.2
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.3
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.4
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.5
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.6
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:00.7
      ./usertools/dpdk-devbind.py -b vfio-pci 0001:04:01.0

* The unit test cases can be tested as below:

   .. code-block:: console

      reserve enough huge pages
      cd to <build_dir>
      meson test compressdev_autotest

---

### Doc Guides Compressdevs Overview (`doc/guides/compressdevs/overview.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 Intel Corporation.

Compression Device Supported Functionality Matrices
===================================================

Supported Feature Flags
-----------------------

.. include:: overview_feature_table.txt

.. Note::

   - "Pass-through" feature flag refers to the ability of the PMD
     to let input buffers pass-through it, copying the input to the output,
     without making any modifications to it (no compression done).

   - "OOP SGL In SGL Out" feature flag stands for
     "Out-of-place Scatter-gather list Input, Scatter-gather list Output",
     which means PMD supports different scatter-gather styled input and output buffers
     (i.e. both can consists of multiple segments).

   - "OOP SGL In LB Out" feature flag stands for
     "Out-of-place Scatter-gather list Input, Linear Buffers Output",
     which means PMD supports input from scatter-gathered styled buffers, outputting linear buffers
     (i.e. single segment).

   - "OOP LB In SGL Out" feature flag stands for
     "Out-of-place Linear Buffers Input, Scatter-gather list Output",
     which means PMD supports input from linear buffer, outputting scatter-gathered styled buffers.

---

### Doc Guides Compressdevs Qat Comp (`doc/guides/compressdevs/qat_comp.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 Intel Corporation.

Intel(R) QuickAssist (QAT) Compression Poll Mode Driver
=======================================================

The QAT compression PMD provides poll mode compression & decompression driver
support for the following hardware accelerator devices:

* ``Intel QuickAssist Technology D15xx``
* ``Intel QuickAssist Technology 200xx``
* ``Intel QuickAssist Technology C4xxx``
* ``Intel QuickAssist Technology 4xxx``
* ``Intel QuickAssist Technology C62x``
* ``Intel QuickAssist Technology C3xxx``
* ``Intel QuickAssist Technology DH895x``
* ``Intel QuickAssist Technology 300xx``


Features
--------

QAT compression PMD has support for:

Compression/Decompression algorithm:

    * DEFLATE - using Fixed and Dynamic Huffman encoding

Window size support:

    * 32K

Checksum generation:

    * CRC32, Adler and combined checksum

Stateful operation:

    * Decompression only

Limitations
-----------

* Compressdev level 0, no compression, is not supported.
* Queue-pairs are thread-safe on Intel CPUs but Queues are not (that is, within a single
  queue-pair all enqueues to the TX queue must be done from one thread and all dequeues
  from the RX queue must be done from one thread, but enqueues and dequeues may be done
  in different threads.)
* No BSD support as BSD QAT kernel driver not available.
* Stateful compression is not supported.


Installation
------------

The QAT compression PMD is built by default with a standard DPDK build.

It depends on a QAT kernel driver, see :ref:`qat_building`.

---

### Doc Guides Compressdevs Uadk (`doc/guides/compressdevs/uadk.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2024-2025 Huawei Technologies Co.,Ltd. All rights reserved.
   Copyright 2024-2025 Linaro ltd.

UADK Compression Poll Mode Driver
=================================

UADK compression PMD provides poll mode compression & decompression driver.
All compression operations are using UADK library compression API,
which is algorithm-level API, abstracting accelerators' low-level implementations.

UADK compression PMD relies on `UADK library <https://github.com/Linaro/uadk>`_.

UADK is a framework for user applications to access hardware accelerators.
UADK relies on IOMMU SVA (Shared Virtual Address) feature,
which shares the same page table between IOMMU and MMU.
As a result, the user application can directly use the virtual address for device DMA,
which enhances performance as well as easy usability.


Features
--------

UADK compression PMD has support for:

Compression/Decompression algorithm:

    * DEFLATE - using Fixed and Dynamic Huffman encoding

Window size support:

    * 32K


Test steps
----------

#. Build UADK

   .. code-block:: console

      git clone https://github.com/Linaro/uadk.git
      cd uadk
      mkdir build
      ./autogen.sh
      ./configure --prefix=$PWD/build
      make
      make install

   .. note::

      Without ``--prefix``, UADK will be installed to ``/usr/local/lib`` by default.

   .. note::

      If get error: "cannot find -lnuma", please install the libnuma-dev.

#. Run pkg-config libwd to ensure env is setup correctly

   .. code-block:: console

      export PKG_CONFIG_PATH=$PWD/build/lib/pkgconfig
      pkg-config libwd --cflags --libs -I/usr/local/include -L/usr/local/lib -lwd

   .. note::

      export ``PKG_CONFIG_PATH`` is required on demand,
      not needed if UADK is installed to ``/usr/local/lib``.

#. Build DPDK

   .. code-block:: console

      cd dpdk
      mkdir build
      meson setup build (--reconfigure)
      cd build
      ninja
      sudo ninja install

#. Prepare hugepages for DPDK (see also :doc:`/tools/hugepages`)

   .. code-block:: console

      echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
      echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
      echo 1024 > /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages
      echo 1024 > /sys/devices/system/node/node3/hugepages/hugepages-2048kB/nr_hugepages
      mkdir -p /mnt/huge_2mb
      mount -t hugetlbfs none /mnt/huge_2mb -o pagesize=2MB

#. Run test app

   .. code-block:: console

	sudo dpdk-test --vdev=compress_uadk
	RTE>>compressdev_autotest
	RTE>>quit

As a reference, the following table shows a mapping between the past DPDK versions
and the UADK library version supported by them:

.. table:: DPDK and external UADK library version compatibility

   ==============  ============================
   DPDK version    UADK library version
   ==============  ============================
   24.07 - 25.03   2.4 - 2.8
   25.07+          2.9.1
   ==============  ============================

---

### Doc Guides Compressdevs Zlib (`doc/guides/compressdevs/zlib.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 Cavium Networks.

ZLIB Compression Poll Mode Driver
=================================

The ZLIB PMD (**librte_compress_zlib**) provides poll mode compression &
decompression driver based on SW zlib library,

Features
--------

ZLIB PMD has support for:

Compression/Decompression algorithm:

* DEFLATE

Huffman code type:

* FIXED
* DYNAMIC

Window size support:

* Min - 256 bytes
* Max - 32K

Limitations
-----------

* Scatter-Gather and Stateful not supported.

Installation
------------

* To build DPDK with ZLIB library, the user is required to download the ``libz`` library.
* Use following command for installation.

* For Fedora users::
     sudo yum install zlib-devel
* For Ubuntu users::
     sudo apt-get install zlib1g-dev

* Once downloaded, the user needs to build the library.

* To build from sources
  download zlib sources from http://zlib.net/ and do following before building DPDK::

    make
    sudo make install

Initialization
--------------

To use the PMD in an application, user must:

* Call ``rte_vdev_init("compress_zlib")`` within the application.

* Use ``--vdev="compress_zlib"`` in the EAL options, which will call ``rte_vdev_init()`` internally.

The following parameter (optional) can be provided in the previous two calls:

* ``socket_id:`` Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

---

### Doc Guides Compressdevs Zsda (`doc/guides/compressdevs/zsda.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2024 ZTE Corporation.

ZTE Storage Data Accelerator (ZSDA) Poll Mode Driver
====================================================

The ZSDA compression PMD provides poll mode compression & decompression driver
support for the following hardware accelerator devices:

- Neo X510
- Neo X512


Features
--------

ZSDA compression PMD has support for:

Compression/Decompression algorithm:

   * DEFLATE - using Fixed and Dynamic Huffman encoding

Checksum generation:

   * CRC32, Adler32

Huffman code type:

   * Fixed
   * Dynamic


Limitations
-----------

* Compressdev level 0, no compression, is not supported.
* No BSD support as BSD ZSDA kernel driver not available.
* Stateful is not supported.


Installation
------------

The ZSDA compression PMD is built by default with a standard DPDK build.


Building PMDs on ZSDA
---------------------

A ZSDA device can host multiple acceleration services:

* data compression

These services are provided to DPDK applications via PMDs
which register to implement the compressdev APIs.
The PMDs use common ZSDA driver code which manages the ZSDA PCI device.


Configuring and Building the DPDK ZSDA PMDs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Further information on configuring, building and installing DPDK is described
:doc:`here </linux_gsg/build_dpdk>`.


Build Configuration
~~~~~~~~~~~~~~~~~~~

These is the build configuration options affecting ZSDA, and its default values:

.. code-block:: console

   RTE_PMD_ZSDA_MAX_PCI_DEVICES=256


Device and driver naming
------------------------

* The zsda compressdev driver name is "compress_zsda".
  The ``rte_compressdev_devices_get()`` returns the devices exposed by this driver.

* Each zsda compression device has a unique name, in format
  <PCI BDF>, e.g. "0000:cc:00.3_zsda".
  This name can be passed to ``rte_compressdev_get_dev_id()`` to get the device ID.


Enable VFs
----------

Instructions for installation are below,
but first an explanation of the relationships between the PF/VF devices
and the PMDs visible to DPDK applications.

Each ZSDA PF device exposes a number of VF devices.
Each VF device can enable one compressdev PMD.

These ZSDA PMDs share the same underlying device and pci-mgmt code,
but are enumerated independently on their respective APIs
and appear as independent devices to applications.

.. note::

   Each VF can only be used by one DPDK process.
   It is not possible to share the same VF across multiple processes,
   even if these processes are using different acceleration services.
   Conversely one DPDK process can use one or more ZSDA VFs
   and can expose compressdev instances on each of those VFs.

The examples below are based on the 1cf2 device.
If you have a different device, use the corresponding values in the above table.

In BIOS ensure that SR-IOV is enabled and either:

* Disable VT-d or
* Enable VT-d and set ``"intel_iommu=on iommu=pt"`` in the grub file.

you need to expose the Virtual Functions (VFs) using the sysfs file system.

First find the BDFs (Bus-Device-Function) of the physical functions (PFs)
of your device, e.g.::

   lspci -d:8050

You should see output similar to::

   cc:00.4 Processing accelerators: Device 1cf2:8050 (rev 01)
   ce:00.3 Processing accelerators: Device 1cf2:8050 (rev 01)
   d0:00.3 Processing accelerators: Device 1cf2:8050 (rev 01)
   d2:00.3 Processing accelerators: Device 1cf2:8050 (rev 01)

Enable the VFs for each PF by echoing the number of VFs per PF to the PCI driver::

   echo 31 > /sys/bus/pci/device/0000:cc:00.4/sriov_numvfs
   echo 31 > /sys/bus/pci/device/0000:ce:00.3/sriov_numvfs
   echo 31 > /sys/bus/pci/device/0000:d0:00.3/sriov_numvfs
   echo 31 > /sys/bus/pci/device/0000:d2:00.3/sriov_numvfs

Check that the VFs are available for use.
For example ``lspci -d:8051`` should list 124 VF devices available.

To complete the installation follow the instructions in
`Binding the available VFs to the vfio-pci driver`_.

.. note::

   If you see the following warning in ``/var/log/messages`` it can be ignored:
   ``IOMMU should be enabled for SR-IOV to work correctly``.


Binding the available VFs to the vfio-pci driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. note::

   Please note that due to security issues,
   the usage of older DPDK igb_uio driver is not recommended.
   This document shows how to use the more secure vfio-pci driver.

Unbind the VFs from the stock driver so they can be bound to the vfio-pci driver.

Bind to the vfio-pci driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Load the vfio-pci driver, bind the VF PCI device ID to it
using the ``dpdk-devbind.py`` script,
then use the ``--status`` option to confirm
the VF devices are now in use by vfio-pci kernel driver,
e.g. for the 1cf2 device::

   cd to the top-level DPDK directory
   modprobe vfio-pci
   usertools/dpdk-devbind.py -b vfio-pci 0000:cc:01.4
   usertools/dpdk-devbind.py --status

Use ``modprobe vfio-pci disable_denylist=1`` from kernel 5.9 onwards.


Testing
-------

ZSDA compression PMD can be tested by running the test application::

   cd ./<build_dir>/app/test
   ./dpdk-test -l1 -n1 -a <your zsda BDF>
   RTE>>compressdev_autotest


Debugging
---------

ZSDA logging feature can be enabled using the log-level option
(where 8 = maximum log level) on the process cmdline,
as shown in the following example::

   --log-level="gen,8"

---

### Doc Guides Contributing Abi Policy (`doc/guides/contributing/abi_policy.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2019 The DPDK contributors

ABI Policy
==========

Description
-----------

This document details the management policy for ensuring long-term stability
of the DPDK ABI and API.

General Guidelines
------------------

#. Major ABI versions are declared no more frequently than yearly. Compatibility
   with the major ABI version is mandatory in subsequent releases until a
   :ref:`new major ABI version <abi_new_version>` is declared.
#. Major ABI versions usually, but not always, align with a :doc:`LTS release <stable>`.
#. DPDK manages the ABI version at a project level,
   reflecting it in all non-experimental :ref:`library sonames <abi_what_is_soname>`.
#. Preserve the ABI and avoid changing it lightly.
   ABI changes must follow the outlined :ref:`deprecation process <abi_changes>`.
#. Adding symbols is generally not problematic.
   Manage modification of symbols with :doc:`abi_versioning`.
#. Removing symbols is considered an :ref:`ABI breakage <abi_breakages>`;
   once approved, these removals form part of the next ABI version.
#. Libraries or APIs marked as :ref:`experimental <abi_experimental_apis>`
   may be changed or removed without prior notice,
   as they are not considered part of an ABI version.
   The :ref:`experimental <abi_experimental_apis>` status of an API
   is not an indefinite state.
#. Treat updates to the :ref:`minimum hardware requirements <abi_hw_requirements>`,
   which drop support for previously supported hardware, as an ABI change.

.. note::

   This policy does not currently apply to the
   :doc:`Windows build </windows_gsg/intro>`.

What is an ABI?
~~~~~~~~~~~~~~~

An ABI (Application Binary Interface) is the set of runtime interfaces exposed
by a library. It is similar to an API (Application Programming Interface) but
is the result of compilation.
Applications effectively clone the ABI when+linking to dynamic libraries.
When an application compiles and links against dynamic libraries,
the ABI must remain constant between compile/link time and runtime.
Therefore, in the case of dynamic linking, it is critical to preserve the ABI,
or (when modifying it) to do so in a way that prevents the application
from behaving improperly or unexpectedly.

.. figure:: img/what_is_an_abi.*

	    Illustration of DPDK API and ABI.


What is an ABI version?
~~~~~~~~~~~~~~~~~~~~~~~

An ABI version is an instance of a library's ABI at a specific release. Certain
releases are considered milestone releases, the yearly LTS release for
example. The ABI of a milestone release may be declared as a 'major ABI
version', where this ABI version is then supported for some number of subsequent
releases and is annotated in the library's :ref:`soname <abi_what_is_soname>`.

ABI version support in subsequent releases facilitates application upgrades by
enabling applications built against the milestone release to upgrade to
subsequent releases of a library without a rebuild.

More details on major ABI version can be found in the :ref:`ABI versioning
<abi_major_versions>` guide.

The DPDK ABI policy
-------------------

A new major ABI version is declared no more frequently than yearly, with
declarations usually aligning with an LTS release, e.g., ABI 21 for DPDK 20.11.
Compatibility with the major ABI version is then mandatory in subsequent
releases until the next major ABI version is declared, e.g., ABI 22 for DPDK
21.11.

At the declaration of a major ABI version, major version numbers encoded in
libraries' sonames are bumped to indicate the new version, with the minor
version reset to ``0``. For example, ``librte_eal.so.21.3`` becomes
``librte_eal.so.22.0``.

The ABI may then change multiple times, without warning, between the last major
ABI version increment and the HEAD label of the git tree, with the condition
that ABI compatibility with the major ABI version is preserved and therefore
sonames do not change.

Minor versions are incremented to indicate the release of a new ABI compatible
DPDK release, typically the DPDK quarterly releases.
For example, ``librte_eal.so.21.1`` indicates the first ABI compatible DPDK release
following the declaration of the new major ABI version ``21``.

An ABI version is supported in all new releases until the next major ABI version
is declared. When changing the major ABI version, the release notes detail
all ABI changes.

.. figure:: img/abi_stability_policy.*

	    Mapping of new ABI versions and ABI version compatibility to DPDK
	    releases.

.. _abi_changes:

ABI Changes
~~~~~~~~~~~

The ABI may still change after declaring a major ABI version —
new APIs may be added or existing APIs modified.

.. Warning::

   This policy details the method by which the ABI may be changed,
   with due regard to preserving compatibility and observing deprecation notices.
   However, do not undertake this process lightly;
   as a general rule, ABI stability is extremely important for downstream consumers of DPDK.
   Change the API only for significant reasons, such as performance enhancements.
   Avoid API breakages due to changes such as reorganizing public structure fields
   for aesthetic or readability purposes.

The requirements for changing the ABI are:

#. At least 3 acknowledgments of the need to do so must be made on the
   dpdk.org mailing list.

   - The component maintainer must acknowledge the change, or if
     no maintainer is available for the component, the tree/sub-tree maintainer
     for that component must acknowledge the ABI change instead.

   - Three members of the technical board,
     as delegates of the `technical board <https://core.dpdk.org/techboard/>`_,
     must also acknowledge the need for the ABI change.

   - Seek acknowledgments from different "areas of interest" for each deprecation,
     for example: from NIC vendors, CPU vendors, end-users, etc.

#. Maintain backward compatibility with the major ABI version through
   :doc:`abi_versioning`, with :ref:`forward-only <abi_forward_only>` compatibility
   offered for any ABI changes that are indicated to be part of the next ABI
   version.

   - In situations where backward compatibility is not possible, read the
     section on :ref:`abi_breakages`.

   - No backward or forward compatibility is offered for API changes marked as
     ``experimental``, as described in the section on :ref:`Experimental APIs
     and Libraries <abi_experimental_apis>`.

   - In situations in which an ``experimental`` symbol has been stable for some
     time, when promoting the symbol to become part of the next ABI version, the
     maintainer may choose to provide an alias to the ``experimental`` tag, so
     as not to break consuming applications.

#. If a newly proposed API functionally replaces an existing one, when the new
   API becomes non-experimental, then the old one is marked with
   ``__rte_deprecated``.

    - The deprecated API should follow the notification process to be removed;
      see :ref:`abi_deprecation_notices`.

    - At the declaration of the next major ABI version, those ABI changes then
      become a formal part of the new ABI and the requirement to preserve ABI
      compatibility with the last major ABI version is dropped.

    - The original contributor of the ABI changes
      is responsible for removing redundant ABI compatibility code;
      failing that, the contributor's company, and then finally the maintainer.

.. _abi_forward_only:

.. Note::

   Forward-only compatibility is offered for changes made
   between major ABI versions. As a library's soname can only describe
   compatibility with the last major ABI version, until the next major ABI
   version is declared, these changes cannot be resolved as a runtime
   dependency through the soname. Therefore, any application wishing to use
   these ABI changes can only ensure that its runtime dependencies are met
   through Operating System package versioning.

.. _abi_hw_requirements:

.. Note::

   Treat updates to the minimum hardware requirements,
   which drop support for previously supported hardware, as an ABI change, and
   follow the relevant deprecation policy procedures as above: 3 acks, technical
   board approval, and announcement at least one release in advance.

.. _abi_breakages:

ABI Breakages
~~~~~~~~~~~~~

An amended process exists for ABI changes too significant
to reasonably maintain multiple symbol versions.
In these cases, ABIs may be updated without providing backward compatibility.
These changes must follow the same process :ref:`described above <abi_changes>`
as non-breaking changes, with the following additional requirements:

#. ABI breaking changes (including an alternative map file) can be included with
   the deprecation notice, wrapped by the ``RTE_NEXT_ABI`` option, to provide
   more details about upcoming changes. The ``RTE_NEXT_ABI`` wrapper is removed
   at the declaration of the next major ABI version.

#. Once approved, and after the deprecation notice has been observed,
   these changes form part of the next declared major ABI version.

Examples of ABI Changes
~~~~~~~~~~~~~~~~~~~~~~~

The following are examples of allowable ABI changes occurring between
declarations of major ABI versions.

* DPDK 20.11 release defines the function ``rte_foo()``; ``rte_foo()``
  is part of the major ABI version ``21``.

* DPDK 21.02 release defines a new function ``rte_foo(uint8_t bar)``.
  This is not a problem as long as the symbol ``rte_foo@DPDK_21`` is
  preserved through :doc:`abi_versioning`.

  - The new function may be marked with the ``__rte_experimental`` tag for a
    number of releases, as described in the section :ref:`abi_experimental_apis`.

  - Once ``rte_foo(uint8_t bar)`` becomes non-experimental, ``rte_foo()`` is
    declared as ``__rte_deprecated`` and a deprecation notice is provided.

* DPDK 20.11 is not re-released to include ``rte_foo(uint8_t bar)``; the new
  version of ``rte_foo`` only exists from DPDK 21.02 onwards as described in the
  :ref:`note on forward-only compatibility <abi_forward_only>`.

* DPDK 21.02 release defines the experimental function ``__rte_experimental
  rte_baz()``. This function may or may not exist in the DPDK 21.05 release.

* An application ``dPacket`` wishes to use ``rte_foo(uint8_t bar)`` before the
  declaration of the DPDK ``22`` major ABI version. The application can only
  ensure its runtime dependencies are met by specifying ``DPDK (>= 21.2)`` as
  an explicit package dependency, as the soname can only indicate the
  supported major ABI version.

* At the release of DPDK 21.11, the function ``rte_foo(uint8_t bar)`` becomes
  formally part of the new major ABI version DPDK ``22`` and ``rte_foo()`` may be
  removed.

.. _abi_deprecation_notices:

Examples of Deprecation Notices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following are some examples of ABI deprecation notices to add
to the Release Notes:

* The Macro ``#RTE_FOO`` is deprecated and will be removed with ABI version
  22, to be replaced with the inline function ``rte_foo()``.

* The function ``rte_mbuf_grok()`` has been updated to include a new parameter
  in version 21.2. Backward compatibility will be maintained for this function
  until the release of the new DPDK major ABI version 22, in DPDK version
  21.11.

* The members of ``struct rte_foo`` have been reorganized in DPDK 21.02 for
  performance reasons. Existing binary applications will have backward
  compatibility in release 21.02, while newly built binaries will need to
  reference the new structure variant ``struct rte_foo2``. Compatibility will be
  removed in release 21.11, and all applications will require updating and
  rebuilding to the new structure at that time, which will be renamed to the
  original ``struct rte_foo``.

* Significant ABI changes are planned for the ``librte_dostuff`` library. The
  upcoming release 21.02 will not contain these changes, but release 21.11 will,
  and no backward compatibility is planned due to the extensive nature of
  these changes. Binaries using this library built prior to ABI version 22 will
  require updating and recompilation.


.. _abi_new_version:

New ABI versions
----------------

A new ABI version may be declared aligned with a given release.
The requirement to preserve compatibility with the previous major ABI version
is then dropped for the duration of this release cycle.
This is commonly known as the *ABI breakage window*,
and some amended rules apply during this cycle:

 * The requirement to preserve compatibility with the previous major ABI
   version, as described in the section :ref:`abi_changes`, does not apply.
 * Contributors of compatibility preserving code in previous releases
   are now required to remove this compatibility code,
   as described in the section :ref:`abi_changes`.
 * Update symbol versioning references to the old ABI version
   to reference the new ABI version,
   as described in the section :ref:`abi_deprecating_entire_abi`.
 * Contributors of aliases to experimental in previous releases,
   as described in section :ref:`abi_aliasing_experimental_symbols`,
   are now required to remove these aliases.
 * Finally, the *ABI breakage window* is *not* permission to circumvent
   the other aspects of the procedures to make ABI changes
   described in :ref:`abi_changes`; that is, 3 ACKs of the requirement
   to break the ABI and the observance of a deprecation notice
   are still mandatory.

.. _abi_experimental_apis:

Experimental
------------

APIs
~~~~

APIs marked as ``experimental`` are not considered part of an ABI version and
may be changed or removed without prior notice. Since changes to APIs are most likely
immediately after their introduction, as users begin to take advantage of those
new APIs and start finding issues with them, new DPDK APIs are automatically
marked as ``experimental`` to allow for a period of stabilization before they
become part of a tracked ABI version.

Note that marking an API as experimental is a multi-step process.
To mark an API as experimental, annotate the symbols to be exported
with a RTE_EXPORT_EXPERIMENTAL_SYMBOL call in the corresponding libraries'
sources.
Comment experimental symbols so that it is clear in which DPDK
version they were introduced.

Secondly, mark the corresponding prototypes of those exported functions (in the
development header files) with the ``__rte_experimental`` tag
(see ``rte_compat.h``).

In addition to tagging the code with ``__rte_experimental``,
the doxygen markup must also contain the EXPERIMENTAL string,
and the MAINTAINERS file should note the EXPERIMENTAL libraries.

For removing the experimental tag associated with an API, a deprecation notice is
not required. However, an API should remain in experimental state for at least
one release. Thereafter, the normal process of posting a patch for review to the
mailing list can be followed.

After formally removing the experimental tag, a tree/sub-tree maintainer
may choose to offer an alias to the experimental tag so as not to break
applications using the symbol. The alias is then dropped at the declaration of
next major ABI version.

Libraries
~~~~~~~~~

Libraries marked as ``experimental`` are entirely not considered part of an ABI
version.
All functions in such libraries may be changed or removed without prior notice.

Promotion to stable
~~~~~~~~~~~~~~~~~~~

Review an API's ``experimental`` status annually,
by both the maintainer and/or the original contributor.
Ordinarily, promote APIs marked as ``experimental`` to the stable ABI
once a maintainer is satisfied that the API is mature
and is unlikely to change.

In exceptional circumstances, should an API still be classified
as ``experimental`` after two years
and be without any prospect of becoming part of the stable API,
the API will then become a candidate for removal,
to avoid the accumulation of abandoned symbols.

Should an ABI change, usually due to a direct change to the API's signature,
it is reasonable for the review and expiry clocks to reset.
The promotion or removal of symbols will typically form part of a conversation
between the maintainer and the original contributor.

---

### Doc Guides Contributing Abi Versioning (`doc/guides/contributing/abi_versioning.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

ABI Versioning
==============

This document details the mechanics of ABI version management in DPDK.

.. _abi_what_is_soname:

What is a library's soname?
---------------------------

System libraries usually adopt the familiar major and minor version naming
convention, where major versions (e.g. ``librte_eal 21.x, 22.x``) are presumed
to be ABI incompatible with each other and minor versions (e.g. ``librte_eal
21.1, 21.2``) are presumed to be ABI compatible. A library's `soname
<https://en.wikipedia.org/wiki/Soname>`_ is typically used to provide backward
compatibility information about a given library, describing the lowest common
denominator ABI supported by the library. The soname or logical name for the
library typically consists of the library's name and major version e.g.
``librte_eal.so.21``.

During an application's build process, a library's soname is noted as a runtime
dependency of the application. This information is then used by the `dynamic
linker <https://en.wikipedia.org/wiki/Dynamic_linker>`_ when resolving the
application's dependencies at runtime, to load a library supporting the correct
ABI version. The library loaded at runtime therefore, may be a minor revision
supporting the same major ABI version (e.g. ``librte_eal.21.2``), as the library
used to link the application (e.g. ``librte_eal.21.0``).

.. _abi_major_versions:

Major ABI versions
------------------

An ABI version change to a given library, especially in core libraries such as
``librte_mbuf``, may cause an implicit ripple effect on the ABI of its
consuming libraries, causing ABI breakages. There may however be no explicit
reason to bump a dependent library's ABI version, as there may have been no
obvious change to the dependent library's API, even though the library's ABI
compatibility will have been broken.

This interdependence of DPDK libraries, means that ABI versioning of libraries
is more manageable at a project level, with all project libraries sharing a
**single ABI version**. In addition, the need to maintain a stable ABI for some
number of releases as described in the section :doc:`abi_policy`, means
that ABI version increments need to be carefully planned and managed at a project
level.

Major ABI versions are therefore declared typically aligned with an LTS release
and are then supported for some number of subsequent releases, shared across all
libraries. This means that a single project level ABI version, reflected in all
individual library's soname, library filenames and associated version maps
persists over multiple releases.

.. code-block:: none

 $ head ./build/lib/acl_exports.map
 DPDK_21 {
        global:
 ...

 $ head ./build/lib/eal_exports.map
 DPDK_21 {
        global:
 ...

When an ABI change is made between major ABI versions to a given library, a new
section is added to that library's version map describing the impending new ABI
version, as described in the section :ref:`abi_example_macro_usage`. The
library's soname and filename however do not change, e.g. ``libacl.so.21``, as
ABI compatibility with the last major ABI version continues to be preserved for
that library.

.. code-block:: none

 $ head ./build/lib/acl_exports.map
 DPDK_21 {
        global:
 ...

 DPDK_22 {
        global:

 } DPDK_21;
 ...

 $ head ./build/lib/eal_exports.map
 DPDK_21 {
        global:
 ...

However when a new ABI version is declared, for example DPDK ``22``, old
deprecated functions may be safely removed at this point and the entire old
major ABI version removed, see the section :ref:`abi_deprecating_entire_abi` on
how this may be done.

.. code-block:: none

 $ head ./build/lib/acl_exports.map
 DPDK_22 {
        global:
 ...

 $ head ./build/lib/eal_exports.map
 DPDK_22 {
        global:
 ...

At the same time, the major ABI version is changed atomically across all
libraries by incrementing the major version in the ABI_VERSION file. This is
done globally for all libraries.

Minor ABI versions
~~~~~~~~~~~~~~~~~~

Each non-LTS release will also increment minor ABI version, to permit multiple
DPDK versions being installed alongside each other. Both stable and
experimental ABI's are versioned using the global version file that is updated
at the start of each release cycle, and are managed at the project level.

Versioning Macros
-----------------

When a symbol is exported from a library to provide an API, it also provides a
calling convention (ABI) that is embodied in its name, return type and
arguments. Occasionally that function may need to change to accommodate new
functionality or behavior. When that occurs, it may be required to allow for
backward compatibility for a time with older binaries that are dynamically
linked to the DPDK.

To support backward compatibility the ``eal_export.h``
header file provides macros to use when updating exported functions. These
macros allow multiple versions of a symbol to exist in a shared
library so that older binaries need not be immediately recompiled.

The macros are:

* ``RTE_VERSION_SYMBOL(ver, type, name, args)``: Creates a symbol version table
  entry binding symbol ``<n>@DPDK_<ver>`` to the internal function name ``<n>_v<ver>``.

* ``RTE_DEFAULT_SYMBOL(ver, type, name, args)``: Creates a symbol version entry
  instructing the linker to bind references to symbol ``<n>``
  to the internal symbol ``<n>_v<ver>``.

* ``RTE_VERSION_EXPERIMENTAL_SYMBOL(type, name, args)``:  Similar to RTE_VERSION_SYMBOL
  but for experimental API symbols. The macro is used when a symbol matures
  to become part of the stable ABI, to provide an alias to the experimental version
  until the next major ABI version.

.. _abi_example_macro_usage:

Examples of ABI Macro use
~~~~~~~~~~~~~~~~~~~~~~~~~

Updating a public API
_____________________

Assume we have a function as follows

.. code-block:: c

 /*
  * Create an acl context object for apps to
  * manipulate
  */
 RTE_EXPORT_SYMBOL(rte_acl_create)
 int
 rte_acl_create(struct rte_acl_param *param)
 {
        ...
 }


Assume that struct rte_acl_ctx is a private structure, and that a developer
wishes to enhance the acl api so that a debugging flag can be enabled on a
per-context basis.  This requires an addition to the structure (which, being
private, is safe), but it also requires modifying the code as follows

.. code-block:: c

 /*
  * Create an acl context object for apps to
  * manipulate
  */
 RTE_EXPORT_SYMBOL(rte_acl_create)
 int
 rte_acl_create(struct rte_acl_param *param, int debug)
 {
        ...
 }


Note also that, being a public function, the header file prototype must also be
changed, as must all the call sites, to reflect the new ABI footprint.  We will
maintain previous ABI versions that are accessible only to previously compiled
binaries.

The addition of a parameter to the function is ABI breaking as the function is
public, and existing application may use it in its current form. However, the
compatibility macros in DPDK allow a developer to use symbol versioning so that
multiple functions can be mapped to the same public symbol based on when an
application was linked to it.

We need to specify in the code which function maps to the rte_acl_create
symbol at which versions.  First, at the site of the initial symbol definition,
we wrap the function with ``RTE_VERSION_SYMBOL``, passing the current ABI version,
the function return type, the function name and its arguments.

.. code-block:: c

 -RTE_EXPORT_SYMBOL(rte_acl_create)
 -int
 -rte_acl_create(struct rte_acl_param *param)
 +RTE_VERSION_SYMBOL(21, int, rte_acl_create, (struct rte_acl_param *param))
 {
        size_t sz;
        struct rte_acl_ctx *ctx;
        ...

The macro instructs the linker to create a new symbol ``rte_acl_create@DPDK_21``,
which matches the symbol created in older builds,
but now points to the above newly named function ``rte_acl_create_v21``.
We have now mapped the original rte_acl_create symbol to the original function
(but with a new name).

Please see the section :ref:`abi_enabling_versioning_macros`
to enable this macro in the Meson/Ninja build.

Next, we need to create the new version of the symbol. We create a new
function name and implement it appropriately, then wrap it in a call to ``RTE_DEFAULT_SYMBOL``.

.. code-block:: c

   RTE_DEFAULT_SYMBOL(22, int, rte_acl_create, (struct rte_acl_param *param, int debug))
   {
        int ret = rte_acl_create_v21(param);

        if (debug) {
        ...
        }

        return ret;
   }

The macro instructs the linker to create the new default symbol
``rte_acl_create@DPDK_22``, which points to the function named ``rte_acl_create_v22``
(declared by the macro).

And that's it. On the next shared library rebuild, there will be two versions of rte_acl_create,
an old DPDK_21 version, used by previously built applications, and a new DPDK_22 version,
used by newly built applications.

.. note::

   **Before you leave**, please take care reviewing the sections on
   :ref:`abi_enabling_versioning_macros`,
   and :ref:`ABI deprecation <abi_deprecation>`.


.. _abi_enabling_versioning_macros:

Enabling versioning macros
__________________________

Finally, we need to indicate
to the :doc:`Meson/Ninja build system </prog_guide/build-sdk-meson>`
to enable versioning macros when building the library or driver.
In the libraries or driver where we have added symbol versioning,
in the ``meson.build`` file we add the following

.. code-block:: none

   use_function_versioning = true

at the start of the file. This will indicate to the tool-chain to
enable the function version macros when building.


.. _abi_aliasing_experimental_symbols:

Aliasing experimental symbols
_____________________________

In situations in which an ``experimental`` symbol has been stable for some time,
and it becomes a candidate for promotion to the stable ABI. At this time, when
promoting the symbol, the maintainer may choose to provide an alias to the
``experimental`` symbol version, so as not to break consuming applications.
This alias is then dropped in the next major ABI version.

The process to provide an alias to ``experimental`` is similar to that, of
:ref:`symbol versioning <abi_example_macro_usage>` described above.
Assume we have an experimental function ``rte_acl_create`` as follows:

.. code-block:: c

   #include <rte_compat.h>

   /*
    * Create an acl context object for apps to
    * manipulate
    */
   RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_acl_create)
   __rte_experimental
   int
   rte_acl_create(struct rte_acl_param *param)
   {
   ...
   }

When we promote the symbol to the stable ABI, we simply strip the
``__rte_experimental`` annotation from the function.

.. code-block:: c

   /*
    * Create an acl context object for apps to
    * manipulate
    */
   RTE_EXPORT_SYMBOL(rte_acl_create)
   int
   rte_acl_create(struct rte_acl_param *param)
   {
          ...
   }

Although there are strictly no guarantees or commitments associated with
:ref:`experimental symbols <abi_experimental_apis>`, a maintainer may wish to offer
an alias to experimental. The process to add an alias to experimental,
is similar to the symbol versioning process. Assuming we have an experimental
symbol as before, we now add the symbol to both the ``EXPERIMENTAL``
and ``DPDK_22`` version nodes.

.. code-block:: c

   #include <rte_compat.h>

   /*
    * Create an acl context object for apps to
    * manipulate
    */
   RTE_DEFAULT_SYMBOL(22, int, rte_acl_create, (struct rte_acl_param *param))
   {
   ...
   }

   RTE_VERSION_EXPERIMENTAL_SYMBOL(int, rte_acl_create, (struct rte_acl_param *param))
   {
      return rte_acl_create(param);
   }

.. _abi_deprecation:

Deprecating part of a public API
________________________________

Let's assume that you've done the above updates, and in preparation for the next
major ABI version you decide you would like to retire the old version of the
function. After having gone through the ABI deprecation announcement process,
removal is easy.

Next remove the corresponding versioned export.

.. code-block:: c

 -RTE_VERSION_SYMBOL(21, int, rte_acl_create, (struct rte_acl_param *param))


Note that the internal function definition must also be removed, but it is used
in our example by the newer version ``v22``, so we leave it in place and declare
it as static. This is a coding style choice.

.. _abi_deprecating_entire_abi:

Deprecating an entire ABI version
_________________________________

While removing a symbol from an ABI may be useful, it is more practical to
remove an entire version node at once, as is typically done at the declaration
of a major ABI version. If a version node completely specifies an API, then
removing part of it, typically makes it incomplete. In those cases it is better
to remove the entire node.

Any uses of RTE_DEFAULT_SYMBOL that pointed to the old node should be
updated to point to the new version node in any header files for all affected
symbols.

.. code-block:: c

 -RTE_DEFAULT_SYMBOL(21, int, rte_acl_create, (struct rte_acl_param *param, int debug))
 +RTE_DEFAULT_SYMBOL(22, int, rte_acl_create, (struct rte_acl_param *param, int debug))

Lastly, any RTE_VERSION_SYMBOL macros that point to the old version nodes
should be removed, taking care to preserve any code that is shared
with the new version node.


Running the ABI Validator
-------------------------

The ``devtools`` directory in the DPDK source tree contains a utility program,
``check-abi.sh``, for validating the DPDK ABI based on the libabigail
`abidiff utility <https://sourceware.org/libabigail/manual/abidiff.html>`_.

The syntax of the ``check-abi.sh`` utility is::

   devtools/check-abi.sh <refdir> <newdir>

Where <refdir> specifies the directory housing the reference build of DPDK,
and <newdir> specifies the DPDK build directory to check the ABI of.

The ABI compatibility is automatically verified when using a build script
from ``devtools``, if the variable ``DPDK_ABI_REF_VERSION`` is set with a tag,
as described in :ref:`ABI check recommendations <contrib_integrated_abi_check>`.

---

### Doc Guides Contributing Cheatsheet (`doc/guides/contributing/cheatsheet.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

Patch Cheatsheet
================

.. figure:: img/patch_cheatsheet.*

   Cheat sheet for submitting patches to dev@dpdk.org

---

### Doc Guides Contributing Coding Style (`doc/guides/contributing/coding_style.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

DPDK Coding Style
=================

Description
-----------

This document specifies the preferred style for source files in the DPDK source tree,
based on the Linux Kernel coding guidelines
and the FreeBSD 7.2 Kernel Developer's Manual (see man style(9)),
but was heavily modified for the needs of the DPDK.

General Guidelines
------------------

The rules and guidelines given in this document cannot cover every situation, so the following general guidelines should be used as a fallback:

* The code style should be consistent within each individual file.
* In the case of creating new files, the style should be consistent within each file in a given directory or module.
* The primary reason for coding standards is to increase code readability and comprehensibility, therefore always use whatever option will make the code easiest to read.

Line length is recommended to be not more than 80 characters, including comments.
[Tab stop size should be assumed to be 8-characters wide].

.. note::

	The above is recommendation, and not a hard limit.
	Generally, line lengths up to 100 characters are acceptable in the code.

C Comment Style
---------------

Usual Comments
~~~~~~~~~~~~~~

These comments should be used in normal cases.
To document a public API, a doxygen-like format must be used: refer to :ref:`style_doxygen_guidelines`.

.. code-block:: c

 /*
  * VERY important single-line comments look like this.
  */

 /* Most single-line comments look like this. */

 /*
  * Multi-line comments look like this.  Make them real sentences. Fill
  * them so they look like real paragraphs.
  */

License Header
~~~~~~~~~~~~~~

Each file must begin with a special comment containing the
`Software Package Data Exchange (SPDX) License Identifier <https://spdx.org/using-spdx-license-identifier>`_.

Generally this is the BSD License, except for code granted special exceptions.
The SPDX licences identifier is sufficient, a file should not contain
an additional text version of the license (boilerplate).

After any copyright header, a blank line should be left before any other contents, e.g. include statements in a C file.

C Preprocessor Directives
-------------------------

Header Includes
~~~~~~~~~~~~~~~

In DPDK sources, the include files should be ordered as following:

#. libc includes (system includes first)
#. DPDK EAL includes
#. DPDK misc libraries includes
#. application-specific includes

Include files from the local application directory are included using quotes, while includes from other paths are included using angle brackets: "<>".

Example:

.. code-block:: c

 #include <stdio.h>
 #include <stdlib.h>

 #include <rte_eal.h>

 #include <rte_ring.h>
 #include <rte_mempool.h>

 #include "application.h"

Header File Guards
~~~~~~~~~~~~~~~~~~

Protect headers against multiple inclusion with the usual:

.. code-block:: c

   #ifndef _FILE_H_
   #define _FILE_H_

   /* Code */

   #endif /* _FILE_H_ */


Macros
~~~~~~

Do not ``#define`` or declare names except with the standard DPDK prefix: ``RTE_``.
This is to ensure there are no collisions with definitions in the application itself.

The names of "unsafe" macros (ones that have side effects), and the names of macros for manifest constants, are all in uppercase.

The expansions of expression-like macros are either a single token or have outer parentheses.
If a macro is an inline expansion of a function, the function name is all in lowercase and the macro has the same name all in uppercase.
If the macro encapsulates a compound statement, enclose it in a do-while loop, so that it can be used safely in if statements.
Any final statement-terminating semicolon should be supplied by the macro invocation rather than the macro, to make parsing easier for pretty-printers and editors.

For example:

.. code-block:: c

 #define MACRO(x, y) do {                                        \
         variable = (x) + (y);                                   \
         (y) += 2;                                               \
 } while(0)

.. note::

 Wherever possible, enums and inline functions should be preferred to macros, since they provide additional degrees of type-safety and can allow compilers to emit extra warnings about unsafe code.

Conditional Compilation
~~~~~~~~~~~~~~~~~~~~~~~

.. note::

   Conditional compilation should be used only when absolutely necessary,
   as it increases the number of target binaries that need to be built and tested.
   See below for details of some utility macros/defines available
   to allow ifdefs/macros to be replaced by C conditional in some cases.

Some high-level guidelines on the use of conditional compilation:

* If code can compile on all platforms/systems,
  but cannot run on some due to lack of support,
  then regular C conditionals, as described in the next section,
  should be used instead of conditional compilation.
* If the code in question cannot compile on all systems,
  but constitutes only a small fragment of a file,
  then conditional compilation should be used, as described in this section.
* If the code for conditional compilation implements an interface in an OS
  or platform-specific way, then create a file for each OS or platform
  and select the appropriate file using the Meson build system.
  In most cases, these environment-specific files should be created inside the EAL library,
  rather than having each library implement its own abstraction layer.

Additional style guidance for the use of conditional compilation macros:

* When code is conditionally compiled using ``#ifdef`` or ``#if``, a comment may be added following the matching
  ``#endif`` or ``#else`` to permit the reader to easily discern where conditionally compiled code regions end.
* This comment should be used only for (subjectively) long regions, regions greater than 20 lines, or where a series of nested ``#ifdef``'s may be confusing to the reader.
  Exceptions may be made for cases where code is conditionally not compiled for the purposes of lint(1), or other tools, even though the uncompiled region may be small.
* The comment should be separated from the ``#endif`` or ``#else`` by a single space.
* For short conditionally compiled regions, a closing comment should not be used.
* The comment for ``#endif`` should match the expression used in the corresponding ``#if`` or ``#ifdef``.
* The comment for ``#else`` and ``#elif`` should match the inverse of the expression(s) used in the preceding ``#if`` and/or ``#elif`` statements.
* In the comments, the subexpression ``defined(FOO)`` is abbreviated as "FOO".
  For the purposes of comments, ``#ifndef FOO`` is treated as ``#if !defined(FOO)``.

.. code-block:: c

 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif

 #ifdef COMPAT_43
 /* A large region here, or other conditional code. */
 #else /* !COMPAT_43 */
 /* Or here. */
 #endif /* COMPAT_43 */

 #ifndef COMPAT_43
 /* Yet another large region here, or other conditional code. */
 #else /* COMPAT_43 */
 /* Or here. */
 #endif /* !COMPAT_43 */

Defines to Avoid Conditional Compilation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In many cases in DPDK, one wants to run code based on
the target platform, or runtime environment.
While this can be done using the conditional compilation directives,
e.g. ``#ifdef RTE_EXEC_ENV_LINUX``, present in DPDK for many releases,
this can also be done in many cases using regular ``if`` statements
and the following defines:

* ``RTE_ENV_FREEBSD``, ``RTE_ENV_LINUX``, ``RTE_ENV_WINDOWS`` -
  these define ids for each operating system environment.
* ``RTE_EXEC_ENV`` - this defines the id of the current environment,
  i.e. one of the items in list above.
* ``RTE_EXEC_ENV_IS_FREEBSD``, ``RTE_EXEC_ENV_IS_LINUX``, ``RTE_EXEC_ENV_IS_WINDOWS`` -
  0/1 values indicating if the current environment is that specified,
  shortcuts for checking e.g. ``RTE_EXEC_ENV == RTE_ENV_WINDOWS``

Examples of use:

.. code-block:: c

   /* report a unit tests as unsupported on Windows */
   if (RTE_EXEC_ENV_IS_WINDOWS)
       return TEST_SKIPPED;

   /* set different default values depending on OS Environment */
   switch (RTE_EXEC_ENV) {
   case RTE_ENV_FREEBSD:
       default = x;
       break;
   case RTE_ENV_LINUX:
       default = y;
       break;
   case RTE_ENV_WINDOWS:
       default = z;
       break;
   }


C Types
-------

Integers
~~~~~~~~

For fixed/minimum-size integer values, the project uses the form uintXX_t (from stdint.h) instead of older BSD-style integer identifiers of the form u_intXX_t.

Enumerations
~~~~~~~~~~~~

* Enumeration values are all uppercase.

.. code-block:: c

 enum enumtype { ONE, TWO } et;

* Enum types should be used in preference to macros #defining a set of (sequential) values.
* Enum types should be prefixed with ``rte_`` and the elements by a suitable prefix [generally starting ``RTE_<enum>_`` - where <enum> is a shortname for the enum type] to avoid namespace collisions.

Bitfields
~~~~~~~~~

The developer should group bitfields that are included in the same integer, as follows:

.. code-block:: c

 struct grehdr {
   uint16_t rec:3,
       srr:1,
       seq:1,
       key:1,
       routing:1,
       csum:1,
       version:3,
       reserved:4,
       ack:1;
 /* ... */
 }

Variable Declarations
~~~~~~~~~~~~~~~~~~~~~

In declarations, do not put any whitespace between asterisks and adjacent tokens, except for tokens that are identifiers related to types.
(These identifiers are the names of basic types, type qualifiers, and typedef-names other than the one being declared.)
Separate these identifiers from asterisks using a single space.

For example:

.. code-block:: c

   int *x;         /* no space after asterisk */
   int * const x;  /* space after asterisk when using a type qualifier */

* All externally-visible variables should have an ``rte_`` prefix in the name to avoid namespace collisions.
* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in variable names.
  Lower-case letters and underscores only.

Structure Declarations
~~~~~~~~~~~~~~~~~~~~~~

* In general, when declaring variables in new structures, declare them sorted by use, then by size (largest to smallest), and then in alphabetical order.
  Sorting by use means that commonly used variables are used together and that the structure layout makes logical sense.
  Ordering by size then ensures that as little padding is added to the structure as possible.
* For existing structures, add new members to the end for backward compatibility.
* Each structure element gets its own line.
* Try to make the structure readable by aligning the member names using spaces as shown below.
* Names following extremely long types, which therefore cannot be easily aligned with the rest, should be separated by a single space.

.. code-block:: c

 struct foo {
         struct foo      *next;          /* List of active foo. */
         struct mumble   amumble;        /* Comment for mumble. */
         int             bar;            /* Try to align the comments. */
         struct verylongtypename *baz;   /* Won't fit with other members */
 };


* Declare major structures at the top of the file where they are used,
  or in separate header files if they are used in multiple source files.
* Use of the structures should be by separate variable declarations and those declarations must be extern if they are declared in a header file.
* Externally visible structure definitions should have the structure name prefixed by ``rte_`` to avoid namespace collisions.

Queues
~~~~~~

Use queue(3) macros rather than rolling your own lists, whenever possible.
Thus, the previous example would be better written:

.. code-block:: c

 #include <sys/queue.h>

 struct foo {
         LIST_ENTRY(foo) link;      /* Use queue macros for foo lists. */
         struct mumble   amumble;   /* Comment for mumble. */
         int             bar;       /* Try to align the comments. */
         struct verylongtypename *baz;   /* Won't fit with other members */
 };
 LIST_HEAD(, foo) foohead;          /* Head of global foo list. */


DPDK also provides an optimized way to store elements in lockless rings.
This should be used in all data-path code, when there are several consumer and/or producers to avoid locking for concurrent access.

Naming
------

For symbol names and documentation, new usage of
'master / slave' (or 'slave' independent of 'master') and 'blacklist /
whitelist' is not allowed.

Recommended replacements for 'master / slave' are:
    '{primary,main} / {secondary,replica,subordinate}'
    '{initiator,requester} / {target,responder}'
    '{controller,host} / {device,worker,proxy}'
    'leader / follower'
    'director / performer'

Recommended replacements for 'blacklist/whitelist' are:
    'denylist / allowlist'
    'blocklist / passlist'

Exceptions for introducing new usage is to maintain compatibility
with an existing (as of 2020) hardware or protocol
specification that mandates those terms.


Typedefs
~~~~~~~~

Avoid using typedefs for structure types.

For example, use:

.. code-block:: c

 struct my_struct_type {
 /* ... */
 };

 struct my_struct_type my_var;


rather than:

.. code-block:: c

 typedef struct my_struct_type {
 /* ... */
 } my_struct_type;

 my_struct_type my_var


Typedefs are problematic because they do not properly hide their underlying type;
for example, you need to know if the typedef is the structure itself, as shown above, or a pointer to the structure.
In addition, they must be declared exactly once, whereas an incomplete structure type can be mentioned as many times as necessary.
Typedefs are difficult to use in stand-alone header files.
The header that defines the typedef must be included before the header that uses it, or by the header that uses it (which causes namespace pollution),
or there must be a back-door mechanism for obtaining the typedef.

Note that #defines used instead of typedefs also are problematic (since they do not propagate the pointer type correctly due to direct text replacement).
For example, ``#define pint int *`` does not work as expected, while ``typedef int *pint`` does work.
As stated when discussing macros, typedefs should be preferred to macros in cases like this.

When convention requires a typedef; make its name match the struct tag.
Avoid typedefs ending in ``_t``, except as specified in Standard C or by POSIX.

.. note::

	It is recommended to use typedefs to define function pointer types, for reasons of code readability.
	This is especially true when the function type is used as a parameter to another function.

For example:

.. code-block:: c

	/**
	 * Definition of a remote launch function.
	 */
	typedef int (lcore_function_t)(void *);

	/* launch a function of lcore_function_t type */
	int rte_eal_remote_launch(lcore_function_t *f, void *arg, unsigned worker_id);


C Indentation
-------------

General
~~~~~~~

* Indentation is a hard tab, that is, a tab character, not a sequence of spaces,

.. note::

	Global whitespace rule in DPDK, use tabs for indentation, spaces for alignment.

* Do not put any spaces before a tab for indentation.
* If you have to wrap a long statement, put the operator at the end of the line, and indent again.
* For control statements (if, while, etc.), continuation it is recommended that the next line be indented by two tabs, rather than one,
  to prevent confusion as to whether the second line of the control statement forms part of the statement body or not.
  Alternatively, the line continuation may use additional spaces to line up to an appropriately point on the preceding line, for example, to align to an opening brace.

.. note::

	As with all style guidelines, code should match style already in use in an existing file.

.. code-block:: c

 while (really_long_variable_name_1 == really_long_variable_name_2 &&
     var3 == var4){  /* confusing to read as */
     x = y + z;      /* control stmt body lines up with second line of */
     a = b + c;      /* control statement itself if single indent used */
 }

 if (really_long_variable_name_1 == really_long_variable_name_2 &&
         var3 == var4){  /* two tabs used */
     x = y + z;          /* statement body no longer lines up */
     a = b + c;
 }

 z = a + really + long + statement + that + needs +
         two + lines + gets + indented + on + the +
         second + and + subsequent + lines;


* Do not add whitespace at the end of a line.

* Do not add whitespace or a blank line at the end of a file.


Control Statements and Loops
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Include a space after keywords (if, while, for, return, switch).
* Do not use braces (``{`` and ``}``) for control statements with zero or just a single statement, unless that statement is more than a single line in which case the braces are permitted.

.. code-block:: c

 for (p = buf; *p != '\0'; ++p)
         ;       /* nothing */
 for (;;)
         stmt;
 for (;;) {
         z = a + really + long + statement + that + needs +
                 two + lines + gets + indented + on + the +
                 second + and + subsequent + lines;
 }
 for (;;) {
         if (cond)
                 stmt;
 }
 if (val != NULL)
         val = realloc(val, newsize);


* Parts of a for loop may be left empty.

.. code-block:: c

 for (; cnt < 15; cnt++) {
         stmt1;
         stmt2;
 }

* Closing and opening braces go on the same line as the else keyword.
* Braces that are not necessary should be left out.

.. code-block:: c

 if (test)
         stmt;
 else if (bar) {
         stmt;
         stmt;
 } else
         stmt;


Function Calls
~~~~~~~~~~~~~~

* Do not use spaces after function names.
* Commas should have a space after them.
* No spaces after ``(`` or ``[`` or preceding the ``]`` or ``)`` characters.

.. code-block:: c

	error = function(a1, a2);
	if (error != 0)
		exit(error);


Operators
~~~~~~~~~

* Unary operators do not require spaces, binary operators do.
* Do not use parentheses unless they are required for precedence or unless the statement is confusing without them.
  However, remember that other people may be more easily confused than you.

Exit
~~~~

Exits should be 0 on success, or 1 on failure.

.. code-block:: c

         exit(0);        /*
                          * Avoid obvious comments such as
                          * "Exit 0 on success."
                          */
 }

Local Variables
~~~~~~~~~~~~~~~

* When declaring variables in functions, multiple variables per line are OK.
  However, if multiple declarations would cause the line to exceed a reasonable line length, begin a new set of declarations on the next line rather than using a line continuation.
* Be careful to not obfuscate the code by initializing variables in the declarations, only the last variable on a line should be initialized.
  If multiple variables are to be initialized when defined, put one per line.

.. code-block:: c

 int i = 0, j = 0, k = 0;  /* bad, too many initializer */

 char a = 0;        /* OK, one variable per line with initializer */
 char b = 0;

 float x, y = 0.0;  /* OK, only last variable has initializer */


Casts and sizeof
~~~~~~~~~~~~~~~~

* Casts and sizeof statements are not followed by a space.
* Always write sizeof statements with parenthesis.
  The redundant parenthesis rules do not apply to sizeof(var) instances.

C Function Definition, Declaration and Use
------------------------------------------

Prototypes
~~~~~~~~~~

* Prototype all non-static functions (the compiler generally requires this).
* Functions local to one source module should be declared static, and should not be prototyped unless absolutely necessary.
* Functions used from other parts of code (external API) must be prototyped in the relevant include file.
* Function prototypes should be listed in a logical order, preferably alphabetical unless there is a compelling reason to use a different ordering.
* Functions that are used locally in more than one module go into a separate header file, for example, "extern.h".
* Do not use the ``__P`` macro.
* Functions that are part of an external API
  should be documented using Doxygen-like comments above declarations.
  See :ref:`style_doxygen_guidelines` for details.
* Functions that are part of the external API must have an ``rte_`` prefix on the function name.
* Do not use uppercase letters - either in the form of ALL_UPPERCASE, or CamelCase - in function names. Lower-case letters and underscores only.
* When prototyping functions, associate names with parameter types, for example:

.. code-block:: c

 void function1(int fd); /* good */
 void function2(int);    /* bad */

* Short function prototypes should be contained on a single line.
  Longer prototypes, e.g. those with many parameters, can be split across multiple lines.
  The second and subsequent lines should be further indented as for line statement continuations as described in the previous section.

.. code-block:: c

 static char *function1(int _arg, const char *_arg2,
        struct foo *_arg3,
        struct bar *_arg4,
        struct baz *_arg5);
 static void usage(void);

.. note::

	Unlike function definitions, the function prototypes do not need to place the function return type on a separate line.

Definitions
~~~~~~~~~~~

* The function type should be on a line by itself preceding the function.
* The opening brace of the function body should be on a line by itself.

.. code-block:: c

 static char *
 function(int a1, int a2, float fl, int a4)
 {


* Do not declare functions inside other functions.
  ANSI C states that such declarations have file scope regardless of the nesting of the declaration.
  Hiding file declarations in what appears to be a local scope is undesirable and will elicit complaints from a good compiler.
* Old-style (K&R) function declaration should not be used, use ANSI function declarations instead as shown below.
* Long argument lists should be wrapped as described above in the function prototypes section.

.. code-block:: c

 /*
  * All major routines should have a comment briefly describing what
  * they do. The comment before the "main" routine should describe
  * what the program does.
  */
 int
 main(int argc, char *argv[])
 {
         char *ep;
         long num;
         int ch;

C Statement Style and Conventions
---------------------------------

NULL Pointers
~~~~~~~~~~~~~

* NULL is the preferred null pointer constant.
  Use NULL instead of ``(type *)0`` or ``(type *)NULL``, except where the compiler does not know the destination type e.g. for variadic args to a function.
* Test pointers against NULL, for example, use:

.. code-block:: c

 if (p == NULL) /* Good, compare pointer to NULL */

 if (!p) /* Bad, using ! on pointer */


* Do not use ! for tests unless it is a boolean, for example, use:

.. code-block:: c

	if (*p == '\0') /* check character against (char)0 */

Return Value
~~~~~~~~~~~~

* Functions which create objects, or allocate memory, should return pointer types, and NULL on error.
  The error type should be indicated by setting the variable ``rte_errno`` appropriately.
* Functions which work on bursts of packets, such as RX-like or TX-like functions, should return the number of packets handled.
* Other functions returning int should generally behave like system calls:
  returning 0 on success and -1 on error, setting ``rte_errno`` to indicate the specific type of error.
* Where already standard in a given library, the alternative error approach may be used where the negative value is not -1 but is instead ``-errno`` if relevant, for example, ``-EINVAL``.
  Note, however, to allow consistency across functions returning integer or pointer types, the previous approach is preferred for any new libraries.
* For functions where no error is possible, the function type should be ``void`` not ``int``.
* Routines returning ``void *`` should not have their return values cast to any pointer type.
  (Typecasting can prevent the compiler from warning about missing prototypes as any implicit definition of a function returns int,
  which, unlike ``void *``, needs a typecast to assign to a pointer variable.)

.. note::

	The above rule about not typecasting ``void *`` applies to malloc, as well as to DPDK functions.

* Values in return statements should not be enclosed in parentheses.

Logging and Errors
~~~~~~~~~~~~~~~~~~

In the DPDK environment, use the logging interface provided:

.. code-block:: c

 /* register log types for this application */
 int my_logtype1 = rte_log_register("myapp.log1");
 int my_logtype2 = rte_log_register("myapp.log2");

 /* set global log level to INFO */
 rte_log_set_global_level(RTE_LOG_INFO);

 /* only display messages higher than NOTICE for log2 (default
  * is DEBUG) */
 rte_log_set_level(my_logtype2, RTE_LOG_NOTICE);

 /* enable all PMD logs (whose identifier string starts with "pmd.") */
 rte_log_set_level_pattern("pmd.*", RTE_LOG_DEBUG);

 /* log in debug level */
 rte_log_set_global_level(RTE_LOG_DEBUG);
 RTE_LOG(DEBUG, my_logtype1, "this is a debug level message\n");
 RTE_LOG(INFO, my_logtype1, "this is a info level message\n");
 RTE_LOG(WARNING, my_logtype1, "this is a warning level message\n");
 RTE_LOG(WARNING, my_logtype2, "this is a debug level message (not displayed)\n");

 /* log in info level */
 rte_log_set_global_level(RTE_LOG_INFO);
 RTE_LOG(DEBUG, my_logtype1, "debug level message (not displayed)\n");

Branch Prediction
~~~~~~~~~~~~~~~~~

* When a test is done in a critical zone (called often or in a data path) the code can use the ``likely()`` and ``unlikely()`` macros to indicate the expected, or preferred fast path.
  They are expanded as a compiler builtin and allow the developer to indicate if the branch is likely to be taken or not. Example:

.. code-block:: c

 #include <rte_branch_prediction.h>
 if (likely(x > 1))
   do_stuff();

.. note::

	The use of ``likely()`` and ``unlikely()`` should only be done in performance critical paths,
	and only when there is a clearly preferred path, or a measured performance increase gained from doing so.
	These macros should be avoided in non-performance-critical code.

Static Variables and Functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* All functions and variables that are local to a file must be declared as ``static`` because it can often help the compiler to do some optimizations (such as, inlining the code).
* Declare functions that should be inlined as ``static inline``
  and can be defined in a .c or a .h file.

.. note::
	Static functions defined in a header file must be declared as ``static inline`` in order to prevent compiler warnings about the function being unused.

Inline Functions
~~~~~~~~~~~~~~~~

The ``__rte_always_inline`` attribute forces the compiler to inline a function
regardless of its size or call-graph heuristics.
Prefer plain ``inline`` (or no annotation at all for static functions)
and let the compiler decide.
Modern compilers at ``-O2`` make good inlining decisions
for small ``static inline`` functions in headers,
and forced inlining can hurt performance by inflating function bodies,
increasing register pressure, and overriding profile-guided optimization.

``__rte_always_inline`` should only be used when one of the following applies:

* The function contains ``__rte_constant()`` checks that gate a constant-folded fast path,
  and the optimization is lost if the function is not inlined into the caller.
  Examples include byte-order helpers and length-dispatched copy/compare routines.

* The function wraps inline assembly or a compiler intrinsic
  whose correctness depends on being inlined into the caller's register context
  (for example, intrinsics requiring a compile-time constant argument).

* Measurement on a representative workload shows that
  the annotation is required to retain performance,
  and the reason is documented in the commit message that introduces it.

Each use must be justified at the point it is introduced.
Adding ``__rte_always_inline`` because nearby code uses it is not a justification;
if the constant or intrinsic that requires inlining is several call levels up the call chain,
restructure the code rather than annotating the entire chain.

The complementary attribute ``__rte_noinline`` is useful for explicitly marking cold paths
(error handling, initialization, slow-path fallbacks)
where outlining the function can reduce instruction-cache pressure on the hot path.

Const Attribute
~~~~~~~~~~~~~~~

Use the ``const`` attribute as often as possible when a variable is read-only.

Inline ASM in C code
~~~~~~~~~~~~~~~~~~~~

The ``asm`` and ``volatile`` keywords do not have underscores. The AT&T syntax should be used.
Input and output operands should be named to avoid confusion, as shown in the following example:

.. code-block:: c

	asm volatile("outb %[val], %[port]"
		: :
		[port] "dN" (port),
		[val] "a" (val));

Control Statements
~~~~~~~~~~~~~~~~~~

* Forever loops are done with for statements, not while statements.
* Elements in a switch statement that cascade should have a FALLTHROUGH comment. For example:

.. code-block:: c

         switch (ch) {         /* Indent the switch. */
         case 'a':             /* Don't indent the case. */
                 aflag = 1;    /* Indent case body one tab. */
                 /* FALLTHROUGH */
         case 'b':
                 bflag = 1;
                 break;
         case '?':
         default:
                 usage();
                 /* NOTREACHED */
         }

.. _style_dynamic_logging:

Dynamic Logging
---------------

DPDK provides infrastructure to perform logging during runtime. This is very
useful for enabling debug output without recompilation. To enable or disable
logging of a particular topic, the ``--log-level`` parameter can be provided
to EAL, which will change the log level. DPDK code can register topics,
which allows the user to adjust the log verbosity for that specific topic.

To register a library or driver for dynamic logging,
using the standardized naming scheme described below,
use ``RTE_LOG_REGISTER_DEFAULT`` macro
to define a log-type variable inside your component's main C file.
Thereafter, it is usual to define a macro or macros inside your component
to make logging more convenient.

For example, the ``rte_cfgfile`` library defines:

.. literalinclude:: ../../../lib/cfgfile/rte_cfgfile.c
   :language: c
   :start-after: Setting up dynamic logging 8<
   :end-before: >8 End of setting up dynamic logging

.. note::

   The statically-defined log types defined in ``rte_log.h`` are for legacy components,
   and they will likely be removed in a future release.
   Do not add new entries to this file.

Dynamic Logging Naming Scheme
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In general, the naming scheme is as follows: ``type.section.name``

 * Type is the type of component, where ``lib``, ``pmd``, ``bus`` and ``user``
   are the common options.
 * Section refers to a specific area, for example a poll-mode-driver for an
   ethernet device would use ``pmd.net``, while an eventdev PMD uses
   ``pmd.event``.
 * The name identifies the individual item that the log applies to.
   The name section must align with
   the directory that the PMD code resides. See examples below for clarity.

Examples:

 * The virtio network PMD in ``drivers/net/virtio`` uses ``pmd.net.virtio``
 * The eventdev software poll mode driver in ``drivers/event/sw`` uses ``pmd.event.sw``
 * The octeontx mempool driver in ``drivers/mempool/octeontx`` uses ``pmd.mempool.octeontx``
 * The DPDK hash library in ``lib/hash`` uses ``lib.hash``

Specializations
~~~~~~~~~~~~~~~

In addition to the above logging topic, any PMD or library can further split
logging output by using "specializations". A specialization could be the
difference between initialization code, and logs of events that occur at runtime.

An example could be the initialization log messages getting one
specialization, while another specialization handles mailbox command logging.
Each PMD, library or component can create as many specializations as required.

A specialization looks like this:

 * Initialization output: ``type.section.name.init``
 * PF/VF mailbox output: ``type.section.name.mbox``

These specializations are created using the ``RTE_LOG_REGISTER_SUFFIX`` macro.

A real world example is the i40e poll mode driver which exposes two
specializations, one for initialization ``pmd.net.i40e.init`` and the other for
the remaining driver logs ``pmd.net.i40e.driver``.

Note that specializations have no formatting rules, but please follow
a precedent if one exists. In order to see all current log topics and
specializations, run the ``app/test`` binary, and use the ``dump_log_types``

Python Code
-----------

All Python code should be compliant with
`PEP8 (Style Guide for Python Code) <https://www.python.org/dev/peps/pep-0008/>`_.

The ``pep8`` tool can be used for testing compliance with the guidelines.
Note that line lengths are acceptable up to 100 characters, which is in line with C recommendations.

Integrating with the Build System
---------------------------------

DPDK is built using the tools ``meson`` and ``ninja``.

.. note::

   In order to catch possible issues as soon as possible,
   it is recommended that developers build DPDK in "developer mode" to enable additional checks.
   By default, this mode is enabled if the build is being done from a git checkout,
   but the mode can be manually enabled/disabled using the
   ``developer_mode`` meson configuration option.

Therefore all new component additions should include a ``meson.build`` file,
and should be added to the component lists in the ``meson.build`` files in the
relevant top-level directory:
either ``lib`` directory or a ``driver`` subdirectory.

Meson Build File Contents - Libraries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``meson.build`` file for a new DPDK library should be of the following basic
format.

.. code-block:: python

	sources = files('file1.c', ...)
	headers = files('file1.h', ...)


This will build based on a number of conventions and assumptions within the DPDK
itself, for example, that the library name is the same as the directory name in
which the files are stored.

For a library ``meson.build`` file, there are number of variables which can be
set, some mandatory, others optional. The mandatory fields are:

sources
	**Default Value = []**.
	This variable should list out the files to be compiled up to create the
	library. Files must be specified using the meson ``files()`` function.


The optional fields are:

build
	**Default Value = true**
	Used to optionally compile a library, based on its dependencies or
	environment. When set to "false" the ``reason`` value, explained below, should
	also be set to explain to the user why the component is not being built.
	A simple example of use would be:

.. code-block:: python

	if not is_linux
	        build = false
	        reason = 'only supported on Linux'
	endif


cflags
	**Default Value = [<-march/-mcpu flags>]**.
	Used to specify any additional cflags that need to be passed to compile
	the sources in the library.

deps
	**Default Value = ['eal']**.
	Used to list the internal library dependencies of the library. It should
	be assigned to using ``+=`` rather than overwriting using ``=``.  The
	dependencies should be specified as strings, each one giving the name of
	a DPDK library, without the ``librte_`` prefix. Dependencies are handled
	recursively, so specifying e.g. ``mempool``, will automatically also
	make the library depend upon the mempool library's dependencies too -
	``ring`` and ``eal``. For libraries that only depend upon EAL, this
	variable may be omitted from the ``meson.build`` file.  For example:

.. code-block:: python

	deps += ['ethdev']


ext_deps
	**Default Value = []**.
	Used to specify external dependencies of this library. They should be
	returned as dependency objects, as returned from the meson
	``dependency()`` or ``find_library()`` functions. Before returning
	these, they should be checked to ensure the dependencies have been
	found, and, if not, the ``build`` variable should be set to ``false``.
	For example:

.. code-block:: python

	my_dep = dependency('libX', required: 'false')
	if my_dep.found()
		ext_deps += my_dep
	else
		build = false
	endif


headers
	**Default Value = []**.
	Used to return the list of header files for the library that should be
	installed to $PREFIX/include when ``meson install`` is run. As with
	source files, these should be specified using the meson ``files()``
	function.
	When ``check_includes`` build option is set to ``true``, each header file
	has additional checks performed on it, for example to ensure that it is
	not missing any include statements for dependent headers.
	For header files which are public, but only included indirectly in
	applications, these checks can be skipped by using the ``indirect_headers``
	variable rather than ``headers``.

indirect_headers
	**Default Value = []**.
	As with ``headers`` option above, except that the files are not checked
	for all needed include files as part of a DPDK build when
	``check_includes`` is set to ``true``.

includes:
	**Default Value = []**.
	Used to indicate any additional header file paths which should be
	added to the header search path for other libs depending on this
	library. EAL uses this so that other libraries building against it
	can find the headers in subdirectories of the main EAL directory. The
	base directory of each library is always given in the include path,
	it does not need to be specified here.

name
	**Default Value = library name derived from the directory name**.
	If a library's .so or .a file differs from that given in the directory
	name, the name should be specified using this variable. In practice,
	since the convention is that for a library called ``librte_xyz.so``, the
	sources are stored in a directory ``lib/xyz``, this value should
	never be needed for new libraries.

objs
	**Default Value = []**.
	This variable can be used to pass to the library build some pre-built
	objects that were compiled up as part of another target given in the
	included library ``meson.build`` file.

reason
	**Default Value = '<unknown reason>'**.
	This variable should be used when a library is not to be built i.e. when
	``build`` is set to "false", to specify the reason why a library will not be
	built. For missing dependencies this should be of the form
	``'missing dependency, "libname"'``.

use_function_versioning
	**Default Value = false**.
	Specifies if the library in question has ABI versioned functions. If it
	has, this value should be set to ensure that the C files are compiled
	twice with suitable parameters for each of shared or static library
	builds.

Meson Build File Contents - Drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For drivers, the values are largely the same as for libraries. The variables
supported are:

build
	As above.

cflags
	As above.

deps
	As above.

ext_deps
	As above.

includes
	**Default Value = <driver directory>** Some drivers include a base
	directory for additional source files and headers, so we have this
	variable to allow the headers from that base directory to be found when
	compiling driver sources. Should be appended to using ``+=`` rather than
	overwritten using ``=``.  The values appended should be meson include
	objects got using the ``include_directories()`` function. For example:

.. code-block:: python

	includes += include_directories('base')

name
	As above, though note that each driver class can define it's own naming
	scheme for the resulting ``.so`` files.

objs
	As above, generally used for the contents of the ``base`` directory.

pkgconfig_extra_libs
	**Default Value = []**
	This variable is used to pass additional library link flags through to
	the DPDK pkgconfig file generated, for example, to track any additional
	libraries that may need to be linked into the build - especially when
	using static libraries. Anything added here will be appended to the end
	of the ``pkgconfig --libs`` output.

reason
	As above.

sources [mandatory]
	As above

headers
	As above

version
	As above


Meson Coding Style
------------------

The following guidelines apply to the build system code in meson.build files in DPDK.

* Indentation should be using 4 spaces, no hard tabs.

* Line continuations should be doubly-indented to ensure visible difference from normal indentation.
  Any line continuations beyond the first may be singly indented to avoid large amounts of indentation.

* Where a line is split in the middle of a statement, e.g. a multiline `if` statement,
  brackets should be used in preference to escaping the line break.

Example::

    if (condition1 and condition2            # line breaks inside () need no escaping
            and condition3 and condition4)
        x = y
    endif

* Lists of files or components must be alphabetical unless doing so would cause errors.

* Two formats are supported for lists of files or list of components:

   * For a small number of list entries, generally 3 or fewer, all elements may be put on a single line.
     In this case, the opening and closing braces of the list must be on the same line as the list items.
     No trailing comma is put on the final list entry.
   * For lists with more than 3 items,
     it is recommended that the lists be put in the files with a *single* entry per line.
     In this case, the opening brace, or ``files`` function call must be on a line on its own,
     and the closing brace must similarly be on a line on its own at the end.
     To help with readability of nested sublists, the closing brace should be dedented to appear
     at the same level as the opening braced statement.
     The final list entry must have a trailing comma,
     so that adding a new entry to the list never modifies any other line in the list.

Examples::

    sources = files('file1.c', 'file2.c')

    subdirs = ['dir1', 'dir2']

    headers = files(
            'header1.c',
            'header2.c',
            'header3.c',   # always include trailing comma
    )                      # closing brace at indent level of opening brace

    components = [
            'comp1',
            'comp2',
            ...
            'compN',
    ]

---

### Doc Guides Contributing Design (`doc/guides/contributing/design.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

Design
======

Environment or Architecture-specific Sources
--------------------------------------------

In DPDK and DPDK applications,
some code is architecture-specific (i686, x86_64)
or environment-specific (FreeBSD or Linux, etc.).
When feasible, such instances of architecture or env-specific code
should be provided via standard APIs in the EAL.

By convention, a file is specific if the directory is indicated.
Otherwise, it is common.

For example:

A file located in a subdir of "x86_64" directory is specific to this architecture.
A file located in a subdir of "linux" is specific to this execution environment.

.. note::

   Code in DPDK libraries and applications should be generic.
   The correct location for architecture or execution environment-specific code is in the EAL.

When necessary, there are several ways to handle specific code:

* When the differences are small and they can be embedded in the same C file,
  use a ``#ifdef`` with a build definition macro in the C code.

  .. code-block:: c

     #ifdef RTE_ARCH_I686
     toto();
     #else
     titi();
     #endif

* When the differences are more significant,
  use build definition macros and conditions in the Meson build file.
  In this case, the code is split into two separate files
  that are architecture or environment specific.
  This should only apply inside the EAL library.


Per Architecture Sources
~~~~~~~~~~~~~~~~~~~~~~~~

The following macro options can be used:

* ``RTE_ARCH`` is a string that contains the name of the architecture.
* ``RTE_ARCH_I686``, ``RTE_ARCH_X86_64``, ``RTE_ARCH_X86_X32``, ``RTE_ARCH_PPC_64``,
  ``RTE_ARCH_RISCV``, ``RTE_ARCH_LOONGARCH``, ``RTE_ARCH_ARM``, ``RTE_ARCH_ARMv7``
  or ``RTE_ARCH_ARM64`` are defined when building for these architectures.


Per Execution Environment Sources
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The following macro options can be used:

* ``RTE_EXEC_ENV_NAME`` is a string that contains the name of the execution environment.
* ``RTE_EXEC_ENV_FREEBSD``, ``RTE_EXEC_ENV_LINUX`` or ``RTE_EXEC_ENV_WINDOWS`` are defined
  only if we are building for these execution environments.


Mbuf features
-------------

The ``rte_mbuf`` structure must be kept small (128 bytes).

In order to add new features without wasting buffer space for unused features,
some fields and flags can be registered dynamically in a shared area.
The "dynamic" mbuf area is the default choice for the new features.

The "dynamic" area is eating the remaining space in mbuf,
and some existing "static" fields may need to become "dynamic".

Adding a new static field or flag must be an exception matching many criteria
like (non-exhaustive): wide usage, performance, size.


Runtime Information - Logging, Tracing and Telemetry
----------------------------------------------------

It is often desirable to provide information to the end-user
as to what is happening to the application at runtime.
DPDK provides a number of built-in mechanisms to provide this introspection:

* :ref:`Logging <style_dynamic_logging>`
* :doc:`Tracing </prog_guide/trace_lib>`
* :doc:`Telemetry </prog_guide/telemetry_lib>`

Each of these has its own strengths and suitabilities for use within DPDK components.

Here are guidelines for when each mechanism should be used:

* For reporting error conditions, or other abnormal runtime issues, *logging* should be used.
  For example, depending on the severity of the issue, the appropriate log level,
  ``ERROR``, ``WARNING`` or ``NOTICE`` should be used.

.. note::

   Drivers of all classes, including both bus and device drivers,
   should not output any log information if the hardware they support is not present.
   This is to avoid any changes in output for existing users when a new driver is added to DPDK.

* For component initialization, or other cases where a path through the code
  is only likely to be taken once,
  either *logging* at ``DEBUG`` level or *tracing* may be used, or both.
  In the latter case, tracing can provide basic information as to the code path taken,
  with debug-level logging providing additional details on internal state,
  which is not possible to emit via tracing.

* For a component's data-path, where a path is to be taken multiple times within a short timeframe,
  *tracing* should be used.
  Since DPDK tracing uses `Common Trace Format <https://diamon.org/ctf/>`_ for its tracing logs,
  post-analysis can be done using a range of external tools.

* For numerical or statistical data generated by a component, such as per-packet statistics,
  *telemetry* should be used.

* For any data that may need to be gathered at any point during the execution
  to help assess the state of the application component
  (for example, core configuration, device information), *telemetry* should be used.
  Telemetry callbacks should not modify any program state, but be "read-only".

Many libraries also include a ``rte_<libname>_dump()`` function as part of their API,
writing verbose internal details to a given file-handle.
New libraries are encouraged to provide such functions where it makes sense to do so,
as they provide an additional application-controlled mechanism
to get details of the internals of a DPDK component.


Library Statistics
------------------

Description
~~~~~~~~~~~

This document describes the guidelines for DPDK library-level statistics counter
support. This includes guidelines for turning library statistics on and off and
requirements for preventing ABI changes when implementing statistics.


Mechanism to allow the application to turn library statistics on and off
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Having runtime support for enabling/disabling library statistics is recommended
as build-time options should be avoided.
However, if build-time options are used, as in the table library,
the options can be set using c_args.
When this flag is set, all the counters supported by the current library are
collected for all the instances of every object type provided by the library.
When this flag is cleared, none of the counters supported by the current library
are collected for any instance of any object type provided by the library.


Prevention of ABI changes due to library statistics support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The layout of data structures and prototype of functions that are part of the
library API should not be affected by whether the collection of statistics
counters is turned on or off for the current library. In practical terms, this
means that space should always be allocated in the API data structures for
statistics counters and the statistics related API functions are always built
into the code, regardless of whether the statistics counter collection is turned
on or off for the current library.

When the collection of statistics counters for the current library is turned
off, the counters retrieved through the statistics related API functions should
have a default value of zero.


Motivation to allow the application to turn library statistics on and off
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is highly recommended that each library provides statistics counters to allow
an application to monitor the library-level run-time events. Typical counters
are: the number of packets received/dropped/transmitted, the number of buffers
allocated/freed, the number of occurrences for specific events, etc.

However, the resources consumed for library-level statistics counter collection
have to be spent out of the application budget and the counters collected by
some libraries might not be relevant to the current application. In order to
avoid any unwanted waste of resources and/or performance impacts, the
application should decide at build time whether the collection of library-level
statistics counters should be turned on or off for each library individually.

Library-level statistics counters can be relevant or not for specific
applications:

* For Application A, counters maintained by Library X are always relevant and
  the application needs to use them to implement certain features, such as traffic
  accounting, logging, application-level statistics, etc. In this case,
  the application requires that collection of statistics counters for Library X is
  always turned on.

* For Application B, counters maintained by Library X are only useful during the
  application debug stage and are not relevant once debug phase is over. In this
  case, the application may decide to turn on the collection of Library X
  statistics counters during the debug phase and at a later stage turn them off.

* For Application C, counters maintained by Library X are not relevant at all.
  It might be that the application maintains its own set of statistics counters
  that monitor a different set of run-time events (e.g. number of connection
  requests, number of active users, etc). It might also be that the application
  uses multiple libraries (Library X, Library Y, etc) and it is interested in the
  statistics counters of Library Y, but not in those of Library X. In this case,
  the application may decide to turn the collection of statistics counters off for
  Library X and on for Library Y.

The statistics collection consumes a certain amount of CPU resources (cycles,
cache bandwidth, memory bandwidth, etc) that depends on:

* Number of libraries used by the current application that have statistics
  counters collection turned on.

* Number of statistics counters maintained by each library per object type
  instance (e.g. per port, table, pipeline, thread, etc).

* Number of instances created for each object type supported by each library.

* Complexity of the statistics logic collection for each counter: when only
  some occurrences of a specific event are valid, additional logic is typically
  needed to decide whether the current occurrence of the event should be counted
  or not. For example, in the event of packet reception, when only TCP packets
  with destination port within a certain range should be recorded, conditional
  branches are usually required. When processing a burst of packets that have been
  validated for header integrity, counting the number of bits set in a bitmask
  might be needed.


PF and VF Considerations
------------------------

The primary goal of DPDK is to provide a userspace dataplane. Managing VFs from
a PF driver is a control plane feature and developers should generally rely on
the Linux Kernel for that.

Developers should work with the Linux Kernel community to get the required
functionality upstream. PF functionality should only be added to DPDK for
testing and prototyping purposes while the kernel work is ongoing. It should
also be marked with an "EXPERIMENTAL" tag. If the functionality isn't
upstreamable, then a case can be made to maintain the PF functionality in DPDK
without the EXPERIMENTAL tag.

---

### Doc Guides Contributing Documentation (`doc/guides/contributing/documentation.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

DPDK Documentation Guidelines
=============================

This document outlines the guidelines for writing the DPDK Guides and API documentation in RST and Doxygen format.

It also explains the structure of the DPDK documentation and how to build it.


Structure of the Documentation
------------------------------

The DPDK source code repository contains input files to build the API documentation and User Guides.

The main directories that contain files related to documentation are shown below::

   lib
   |-- acl
   |-- cfgfile
   |-- cmdline
   |-- eal
   |   |-- ...
   ...
   doc
   |-- api
   +-- guides
       |-- freebsd_gsg
       |-- linux_gsg
       |-- prog_guide
       |-- sample_app_ug
       |-- guidelines
       |-- testpmd_app_ug
       |-- rel_notes
       |-- nics
       |-- ...


Doxygen comments in header files generate the API documentation.
These are built from `Doxygen <http://www.doxygen.nl>`_ comments in the header files.
These files are mainly in the ``lib/*`` directories although some of the Poll Mode Drivers in ``drivers/net``
are also documented with Doxygen.

The configuration files that are used to control the Doxygen output are in the ``doc/api`` directory.

The user guides such as *The Programmers Guide* and the *FreeBSD* and *Linux Getting Started* Guides are generated
from RST markup text files using the `Sphinx <http://sphinx-doc.org>`_ Documentation Generator.

These files are included in the ``doc/guides/`` directory.
The output is controlled by the ``doc/guides/conf.py`` file.


Role of the Documentation
-------------------------

The following items outline the roles of the different parts of the documentation and when they need to be updated or
added to by the developer.

.. _style_release_notes_guidelines:

* **Release Notes**

  The Release Notes document which features have been added in the current and previous releases of DPDK and highlight
  any known issues.
  The Releases Notes also contain notifications of features that will change ABI compatibility in the next release.

  Developers should include updates to the Release Notes with patch sets that relate to any of the following sections:

  * New Features
  * Resolved Issues (see below)
  * Known Issues
  * API Changes
  * ABI Changes
  * Shared Library Versions

  Resolved Issues should only include issues from previous releases that have been resolved in the current release.
  Issues that are introduced and then fixed within a release cycle do not have to be included here.

  Refer to the Release Notes from the previous DPDK release for the correct format of each section.


* **API documentation**

  The API documentation explains how to use the public DPDK functions.
  The `API index page <https://doc.dpdk.org/api/>`_ shows the generated API documentation with related groups of functions.

  Update API documentation via Doxygen comments when adding new functions.

* **Getting Started Guides**

  The Getting Started Guides show how to install and configure DPDK and how to run DPDK based applications on different OSes.

  A Getting Started Guide should be added when DPDK is ported to a new OS.

* **The Programmers Guide**

  The Programmers Guide explains how the API components of DPDK such as the EAL, Memzone, Rings and the Hash Library work.
  It also describes some of the higher level functionality such as Packet Distributor and Packet Framework.
  It also shows the build system and explains how to add applications.

  The Programmers Guide should be expanded when new functionality is added to DPDK.

* **App Guides**

  The app guides document the DPDK applications in the ``app`` directory such as ``testpmd``.

  The app guides should be updated if functionality is changed or added.

* **Sample App Guides**

  The sample app guides document the DPDK example applications in the examples directory.
  Generally they demonstrate a major feature such as L2 or L3 Forwarding, Multi Process or Power Management.
  They explain the purpose of the sample application, how to run it and step through some of the code to explain the
  major functionality.

  A new sample application should be accompanied by a new sample app guide.
  The guide for the Skeleton Forwarding app is a good starting reference.

* **Network Interface Controller Drivers**

  The NIC Drivers document explains the features of the individual Poll Mode Drivers, such as software requirements,
  configuration and initialization.

  New documentation should be added for new Poll Mode Drivers.

* **Guidelines**

  The guideline documents record community process, expectations and design directions.

  They can be extended, amended or discussed by submitting a patch and getting community approval.


Building the Documentation
--------------------------

Dependencies
~~~~~~~~~~~~

The following dependencies must be installed to build the documentation:

* Doxygen.
* Sphinx (also called python-sphinx).

`Doxygen`_ generates documentation from commented source code.
It can be installed as follows:

.. code-block:: console

   # Ubuntu/Debian.
   sudo apt-get -y install doxygen

   # Red Hat/Fedora.
   sudo dnf     -y install doxygen

`Sphinx`_ is a Python documentation tool for converting RST files to HTML.
For full support with figure and table captioning the latest version of Sphinx can be installed as follows:

.. code-block:: console

   # Ubuntu/Debian.
   sudo apt-get -y install python3-sphinx python3-sphinx-rtd-theme

   # Red Hat/Fedora.
   sudo dnf     -y install python3-sphinx python3-sphinx_rtd_theme

For further information on getting started with Sphinx see the
`Sphinx Getting Started <http://www.sphinx-doc.org/en/master/usage/quickstart.html>`_.

.. Note::

   To get full support for Figure and Table numbering it is best to install Sphinx 1.3.1 or later.


Build commands
~~~~~~~~~~~~~~

The documentation is built using the standard DPDK build system.

To build the documentation::

   ninja -C build doc

See :doc:`/linux_gsg/build_dpdk` for more detail on compiling DPDK with meson.

The output is generated in the directory ``build/doc/``, with:

* HTML versions of the guide docs, e.g. Getting Started Guides, Programmers Guide, in ``build/doc/guides/html``
* HTML version of the API documentation in ``build/doc/api/html``
* Man-page version of the API documentation in ``build/doc/api/man``.
  If not installing DPDK system-wise, these pages can be accessed by adding this directory to the ``MANPATH`` environment variable.
  For example:

.. code-block:: console

   export MANPATH=:/path/to/build/doc/api/man

.. Note::

   Make sure to fix any Sphinx or Doxygen warnings when adding or updating documentation.


Document Guidelines
-------------------

Here are some guidelines in relation to the style of the documentation:

* Document the obvious as well as the obscure since it won't always be obvious to the reader.
  For example an instruction like "Set up 64 2MB Hugepages" is better when followed by a sample commandline or a link to
  the appropriate section of the documentation.

* Use American English spellings throughout.
  This can be checked using the ``aspell`` utility::

       aspell --lang=en_US --check doc/guides/sample_app_ug/mydoc.rst

The documentation can be reviewed with AI help
using the script ``devtools/ai/review-doc.py``.


RST Guidelines
--------------

The RST (reStructuredText) format is a plain text markup format
that can be converted to HTML or other formats.
It is most closely associated with Python but it can be used to document any language.
It is used in DPDK to document everything apart from the API.

The Sphinx documentation contains a very useful `RST Primer <http://sphinx-doc.org/rest.html#rst-primer>`_ which is a
good place to learn the minimal set of syntax required to format a document.

The official `reStructuredText <http://docutils.sourceforge.net/rst.html>`_ website contains the specification for the
RST format and also examples of how to use it.
However, for most developers the RST Primer is a better resource.

The most common guidelines for writing RST text are detailed in the
`Documenting Python <https://docs.python.org/devguide/documenting.html>`_ guidelines.
The additional guidelines below reiterate or expand upon those guidelines.


Line Length and Wrapping
~~~~~~~~~~~~~~~~~~~~~~~~

* Documentation lines should be less than 100 characters.

* Each sentence should start on a new line.
  Multiple sentences, which are not separated by a blank line,
  are joined automatically into paragraphs.

* Wrap sentences at punctuation points, for example, at a comma.
  If no punctuation, put the newline at a logical point in the sentence,
  for example, at the end of a clause before an "and" or "but".

* Lines in literal blocks should be less than 80 characters
  since they are not wrapped by the document formatters.

  Long literal command lines can be shown wrapped with backslashes. For
  example::

     dpdk-testpmd -l 2-3 \
             --vdev=virtio_user0,path=/dev/vhost-net,queues=2,queue_size=1024 \
             -- -i --tx-offloads=0x0000002c --enable-lro --txq=2 --rxq=2 \
             --txd=1024 --rxd=1024


Whitespace
~~~~~~~~~~

* Standard RST indentation is 3 spaces.
  Code can be indented 4 spaces, especially if it is copied from source files.

* No tabs.
  Convert tabs in embedded code to 4 or 8 spaces.

* No trailing whitespace.

* Add 2 blank lines before each section header.

* Add 1 blank line after each section header.

* Add 1 blank line between each line of a list.


Section Headers
~~~~~~~~~~~~~~~

* Section headers should use the following underline formats::

   Level 1 Heading
   ===============


   Level 2 Heading
   ---------------


   Level 3 Heading
   ~~~~~~~~~~~~~~~


   Level 4 Heading
   ^^^^^^^^^^^^^^^


* Level 4 headings should be used sparingly.

* The underlines should match the length of the text.

* In general, the heading should be less than 80 characters, for conciseness.

* As noted above:

   * Add 2 blank lines before each section header.

   * Add 1 blank line after each section header.


Lists
~~~~~

* Bullet lists should be formatted with a leading ``*`` as follows::

     * Item one.

     * Item two is a long line that is wrapped and then indented to match
       the start of the previous line.

     * One space character between the bullet and the text is preferred.

* Numbered lists can be formatted with a leading number but the preference is to use ``#.`` which will give automatic numbering.
  This is more convenient when adding or removing items::

     #. Item one.

     #. Item two is a long line that is wrapped and then indented to match
        the start of the previous line.

     #. Item three.

* Definition lists can be written with or without a bullet::

     * Item one.

       Some text about item one.

     * Item two.

       Some text about item two.

* All lists, and sub-lists, must be separated from the preceding text by a blank line.
  This is a syntax requirement.

* All list items should be separated by a blank line for readability.


Code and Literal block sections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Inline text that is required to be rendered with a fixed width font should be enclosed in backquotes like this:
  \`\`text\`\`, so that it appears like this: ``text``.

* Fixed width, literal blocks of texts should be indented at least 3 spaces and prefixed with ``::`` like this::

     Here is some fixed width text::

        0x0001 0x0001 0x00FF 0x00FF

* It is also possible to specify an encoding for a literal block using the ``.. code-block::`` directive so that syntax
  highlighting can be applied.
  Examples of supported highlighting are::

     .. code-block:: console
     .. code-block:: c
     .. code-block:: python
     .. code-block:: diff
     .. code-block:: none

  That can be applied as follows::

      .. code-block:: c

         #include<stdio.h>

         int main() {

            printf("Hello World\n");

            return 0;
         }

  Which would be rendered as:

  .. code-block:: c

      #include<stdio.h>

      int main() {

         printf("Hello World\n");

         return 0;
      }

* Code snippets can also be included directly from the code using the ``literalinclude`` block.
  Using this block instead of a code block will ensure that the code snippets
  shown in the documentation are always up to date with the code.

  The following will include a snippet from the skeleton sample app::

      .. literalinclude:: ../../../examples/skeleton/basicfwd.c
         :language: c
         :start-after: Display the port MAC address.
         :end-before: Enable RX in promiscuous mode for the Ethernet device.
         :dedent: 1

  This would be rendered as:

  .. literalinclude:: ../../../examples/skeleton/basicfwd.c
     :language: c
     :start-after: Display the port MAC address.
     :end-before: Enable RX in promiscuous mode for the Ethernet device.
     :dedent: 1

  Specifying ``:language:`` will enable syntax highlighting for the specified language.
  ``:dedent:`` is used in this example to remove 1 leading tab from each line of the snippet.

* ``start-after`` and ``end-before`` can use any text within a given file,
  however it may be difficult to find unique text within your code to mark the
  start and end of your snippets. In these cases, it is recommended to include
  explicit tags in your code to denote these locations for documentation purposes.
  The accepted format for these comments is:

     * Before the code snippet, create a new comment which is a sentence explaining
       what the code snippet contains. The comment is terminated with a scissors ``8<``.
     * After the code snippet, create another new comment which starts with a
       scissors ``>8``, then ``End of`` and the first comment repeated.
     * The scissors should be orientated as shown to make it clear what code is being snipped.

  This can be done as follows:

  .. code-block:: c

    /* Example feature being documented. 8< */
    foo(bar);
    /* >8 End of example feature being documented. */

  ``foo(bar);`` could then be included in the docs using::

      .. literalinclude:: ../../../examples/sample_app/main.c
         :language: c
         :start-after: Example feature being documented. 8<
         :end-before: >8 End of example feature being documented.

  If a multiline comment is needed before the snippet,
  then the last line of the multiline comment should be in the same format as
  the first comment shown in the example.

* More information about the ``literalinclude`` block can be found within the
  `Sphinx Documentation <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html?highlight=literalinclude#directive-literalinclude>`_.

* The default encoding for a literal block using the simplified ``::``
  directive is ``none``.

* Lines in literal blocks should be less than 80 characters.
  For long literal lines, try to wrap the text at sensible locations.
  For example a long command line could be documented like this and still work if copied directly from the docs::

     ./<build_dir>/app/dpdk-testpmd -l 0-2 -n3 --vdev=net_pcap0,iface=eth0    \
                               --vdev=net_pcap1,iface=eth1     \
                               -- -i --nb-cores=2 --nb-ports=2 \
                                  --total-num-mbufs=2048

* Long lines that cannot be wrapped, such as application output, should be truncated to be less than 80 characters.


Images
~~~~~~

* All images should be in SVG scalar graphics format.
  They should be true SVG XML files and should not include binary formats embedded in a SVG wrapper.

* The DPDK documentation contains some legacy images in PNG format.
  These will be converted to SVG in time.

* `Inkscape <http://inkscape.org>`_ is the recommended graphics editor for creating the images.
  Use some of the older images in ``doc/guides/prog_guide/img/`` as a template, for example ``mbuf1.svg``
  or ``ring-enqueue1.svg``.

* The SVG images should include a copyright notice, as an XML comment.

* Images in the documentation should be formatted as follows:

   * The image should be preceded by a label
     in the format ``.. _prefix_figure_name:`` with a leading underscore,
     where ``prefix`` is the document or component name,
     and ``name`` makes it unique and descriptive.

   * Images should be included using the ``.. figure::`` directive and the file type should be set to ``*`` (not ``.svg``).
     This allows the format of the image to be changed if required, without updating the documentation.

   * Images must have a caption as part of the ``.. figure::`` directive.

* Here is an example of the previous three guidelines::

     .. _mempool_figure_cache:

     .. figure:: img/mempool.*

        A mempool in memory with its associated ring.

.. _style_mock_label:

* Images can then be linked to using the ``:numref:`` directive::

     The mempool layout is shown in :numref:`mempool_figure_cache`.

  This would be rendered as: *The mempool layout is shown in* :ref:`Fig 6.3 <style_mock_label>`.

  **Note**: The ``:numref:`` directive requires Sphinx 1.3.1 or later.
  With earlier versions it will still be rendered as a link but won't have an automatically generated number.

* The caption of the image can be generated, with a link, using the ``:ref:`` directive::

     :ref:`mempool_figure_cache`

  This would be rendered as: *A mempool in memory with its associated ring.*


Tables
~~~~~~

* RST tables should be used sparingly.
  They are hard to format and to edit, and the same information
  can usually be shown just as clearly with a definition or bullet list.

* Tables should be included using the ``.. table::`` directive and must have a caption.


.. _style_links:

Hyperlinks
~~~~~~~~~~

* Links to external websites can be plain URLs.
  The following is rendered as https://dpdk.org::

     https://dpdk.org

* They can contain alternative text.
  The following is rendered as `Check out DPDK <https://dpdk.org>`_::

     `Check out DPDK <https://dpdk.org>`_

* An internal link can be generated by placing labels in the document with the format ``.. _label_name``.

* The following links to the top of this section: :ref:`style_links`::

     .. _links:

     Hyperlinks
     ~~~~~~~~~~

     * The following links to the top of this section: :ref:`style_links`:

.. Note::

   The label must have a leading underscore but the reference to it must omit it.
   This is a frequent cause of errors and warnings.

* The use of a label is preferred since it works across files and will still work if the header text changes.


.. _style_doxygen_guidelines:

Doxygen Guidelines
------------------

The DPDK API is documented using Doxygen comment annotations in the header files.
Doxygen is a very powerful tool, it is extremely configurable and with a little effort can be used to create expressive documents.
See the `Doxygen website <http://www.doxygen.nl>`_ for full details on how to use it.

The following are some guidelines for use of Doxygen in the DPDK API documentation:

* New libraries that are documented with Doxygen should be added to the Doxygen configuration file: ``doc/api/doxy-api.conf``.
  It is only required to add the directory that contains the files.
  It isn't necessary to explicitly name each file since the configuration matches all ``rte_*.h`` files in the directory.

* Use proper capitalization and punctuation in the Doxygen comments since they will become sentences in the documentation.
  This applies particularly to single-line comments, which developers most often forget.

* Use ``@`` style Doxygen commands instead of ``\`` style commands.

* Add a general description of each library at the head of the main header files:

  .. code-block:: c

      /**
       * @file
       * RTE Mempool.
       *
       * A memory pool is an allocator of fixed-size object. It is
       * identified by its name, and uses a ring to store free objects.
       * ...
       */

* Document the purpose of a function, the parameters used and the return
  value:

  .. code-block:: c

     /**
      * Try to take the lock.
      *
      * @param sl
      *   A pointer to the spinlock.
      * @return
      *   1 if the lock is successfully taken; 0 otherwise.
      */
     int rte_spinlock_trylock(rte_spinlock_t *sl);

* Doxygen supports Markdown style syntax such as bold, italics, fixed width text and lists.
  For example the second line in the ``devargs`` parameter in the previous example will be rendered as:

     The strings should be a pci address like ``0000:01:00.0`` or **virtual** device name like ``net_pcap0``.

* Use ``-`` instead of ``*`` for lists within the Doxygen comment since the latter can get confused with the comment delimiter.

* Add an empty line between the function description, the ``@params`` and ``@return`` for readability.

* Place the ``@params`` description on separate line and indent it by 2 spaces.
  (It would be better to use no indentation since this is more common and also because checkpatch complains about leading
  whitespace in comments.
  However this is the convention used in the existing DPDK code.)

* Documented functions can be linked to simply by adding ``()`` to the function name:

  .. code-block:: c

      /**
       * The functions exported by the application Ethernet API to setup
       * a device designated by its port identifier must be invoked in
       * the following order:
       *     - rte_eth_dev_configure()
       *     - rte_eth_tx_queue_setup()
       *     - rte_eth_rx_queue_setup()
       *     - rte_eth_dev_start()
       */

  In the API documentation the functions will be rendered as links, see the
  `online section of the rte_ethdev.h docs <https://doc.dpdk.org/api/rte__ethdev_8h.html>`_ that contains the above text.

* The ``@see`` keyword can be used to create a *see also* link to another file or library.
  This directive should be placed on one line at the bottom of the documentation section.

  .. code-block:: c

     /**
      * ...
      *
      * Some text that references mempools.
      *
      * @see eal_memzone.c
      */

* Doxygen supports two types of comments for documenting variables, constants and members: prefix and postfix:

  .. code-block:: c

     /** This is a prefix comment. */
     #define RTE_FOO_ERROR  0x023.

     #define RTE_BAR_ERROR  0x024. /**< This is a postfix comment. */

* Postfix comments are preferred for struct members and constants if they can be documented in the same way:

  .. code-block:: c

     struct rte_eth_stats {
         uint64_t ipackets; /**< Total number of received packets. */
         uint64_t opackets; /**< Total number of transmitted packets.*/
         uint64_t ibytes;   /**< Total number of received bytes. */
         uint64_t obytes;   /**< Total number of transmitted bytes. */
         uint64_t imissed;  /**< Total of RX missed packets. */
         uint64_t ibadcrc;  /**< Total of RX packets with CRC error. */
         uint64_t ibadlen;  /**< Total of RX packets with bad length. */
     }

  Note: postfix comments should be aligned with spaces not tabs in accordance
  with the :doc:`coding_style`.

* If a single comment type can't be used, due to line length limitations then
  prefix comments should be preferred.
  For example this section of the code contains prefix comments, postfix comments on the same line and postfix
  comments on a separate line:

  .. code-block:: c

     /** Number of elements in the elt_pa array. */
     alignas(RTE_CACHE_LINE_SIZE) uint32_t    pg_num;
     uint32_t    pg_shift;     /**< LOG2 of the physical pages. */
     uintptr_t   pg_mask;      /**< Physical page mask value. */
     uintptr_t   elt_va_start;
     /**< Virtual address of the first mempool object. */
     uintptr_t   elt_va_end;
     /**< Virtual address of the <size + 1> mempool object. */
     phys_addr_t elt_pa[1];
     /**< Array of physical page addresses for the mempool buffer. */

  This doesn't have an effect on the rendered documentation but it is confusing for the developer reading the code.
  It this case it would be clearer to use prefix comments throughout:

  .. code-block:: c

     /** Number of elements in the elt_pa array. */
     alignas(RTE_CACHE_LINE_SIZE) uint32_t    pg_num;
     /** LOG2 of the physical pages. */
     uint32_t    pg_shift;
     /** Physical page mask value. */
     uintptr_t   pg_mask;
     /** Virtual address of the first mempool object. */
     uintptr_t   elt_va_start;
     /** Virtual address of the <size + 1> mempool object. */
     uintptr_t   elt_va_end;
     /** Array of physical page addresses for the mempool buffer. */
     phys_addr_t elt_pa[1];

* Read the rendered section of the documentation that you have added for correctness, clarity and consistency
  with the surrounding text.

---

### Doc Guides Contributing Index (`doc/guides/contributing/index.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

Contributor's Guidelines
========================

.. toctree::
    :maxdepth: 2
    :numbered:

    coding_style
    design
    abi_policy
    abi_versioning
    documentation
    unit_test
    new_library
    new_driver
    patches
    linux_uapi
    vulnerability
    stable
    cheatsheet

---

### Doc Guides Contributing Linux Uapi (`doc/guides/contributing/linux_uapi.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2024 Red Hat, Inc.

Linux uAPI header files
=======================

Rationale
---------

The build system may run a different kernel version than the deployment target.
To support features unavailable in the build system's kernel, import Linux kernel uAPI headers.

For example, if the build system runs upstream Kernel v5.19,
but you need to build a VDUSE application
that uses the VDUSE_IOTLB_GET_INFO ioctl introduced in Kernel v6.0,
importing the relevant uAPI headers enables this.

The Linux kernel's syscall license exception permits the inclusion of unmodified uAPI header files in such cases.

`Linux Kernel licence exception regarding syscalls
<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/LICENSES/exceptions/Linux-syscall-note>`_
enables importing unmodified Linux Kernel uAPI header files.

Importing or updating an uAPI header file
-----------------------------------------

To ensure that imported uAPI headers are unmodified
and sourced from an official Linux kernel release,
a helper script is provided and must be used.
This script requires the ``unifdef`` tool.

Below is an example to import ``linux/vduse.h`` file from Linux ``v6.10``:

.. code-block:: console

   devtools/linux-uapi.sh -i linux/vduse.h -u v6.10

Once imported, commit header files without any modifications.
Note that all imported headers are updated to match the specified kernel version.

Perform updates to a newer released version only when necessary,
using the same helper script.

.. code-block:: console

   devtools/linux-uapi.sh -u v6.10

The commit message should reflect why updating the headers is necessary.

Once committed, check that headers are valid using the same Linux uAPI script
with the check option:

.. code-block:: console

   devtools/linux-uapi.sh -c

Note that all the linux-uapi.sh script options can be combined. For example:

.. code-block:: console

   devtools/linux-uapi.sh -i linux/virtio_net.h -u v6.10 -c

Header inclusion into library or driver
---------------------------------------

Libraries or drivers that rely on imported uAPI headers
must explicitly include the relevant header
using the ``uapi/`` prefix in their C source files.

This inclusion must be done before any header external to DPDK is included,
to prevent inclusion of the system uAPI header in any of those external headers.

For example, to include VDUSE uAPI:

.. code-block:: c

   #include <uapi/linux/vduse.h>

   #include <stdint.h>
   ...

---

### Doc Guides Contributing New Driver (`doc/guides/contributing/new_driver.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2024 The DPDK contributors


Adding a New Driver
===================

The DPDK project continuously grows its ecosystem by adding support for new devices.
This document assists contributors in creating DPDK drivers,
also known as Poll Mode Drivers (PMD).

By having public support for a device, we ensure accessibility across various
operating systems and guarantee community maintenance in future releases.
If a new device is similar to a device already supported by an existing driver,
it is more efficient to update the existing driver.

Here are our best practice recommendations for creating a new driver.


Early Engagement with the Community
-----------------------------------

When creating a new driver, engage with the DPDK community early
rather than waiting for the work to mature.

These public discussions help align development of your driver with DPDK expectations.
You may submit a roadmap before the release to inform the community of your plans.
Additionally, sending a Request For Comments (RFC) early in the release cycle,
or even during the prior release, is advisable.

DPDK is mainly consumed via Long Term Support (LTS) releases.
It is common to target a new PMD to an LTS release.
For this, start upstreaming at least one release before an LTS release.


Progressive Work
----------------

To continually progress your work, plan
for incremental upstreaming across multiple patch series or releases.

Prioritize quality of the driver over upstreaming
in a single release or single patch series.


Finalizing
----------

Once the driver is upstreamed,
the author is responsible for maintaining it.

This includes the public test report.
Authors must send a public test report after the first upstreaming of the PMD.
The same public test procedure may be reproduced regularly per release.

After the PMD is upstreamed, send a patch to update
`the website <https://core.dpdk.org/supported/>`_
with the name of the new PMD and supported devices via the
`DPDK web mailing list <https://mails.dpdk.org/listinfo/web>`_.

For more information about the role of maintainers, see :doc:`patches`.


Splitting into Patches
----------------------

Split drivers into patches
so that each patch represents a single feature.
If the driver code is already developed, it may be challenging to split.
However, there are many benefits to doing so.

Splitting patches makes it easier to understand a feature
and clarifies the list of components/files that compose that specific feature.

It also enables the ability to track
from the source code to the feature it enables,
and helps users understand the reasoning and intention of implementation.
This kind of tracing is regularly required for defect resolution and refactoring.

Another benefit of splitting the codebase per feature is that
it highlights unnecessary or irrelevant code,
as any code not belonging to any specific feature becomes obvious.

Git bisect is also more useful if patches are split per feature.

Focus the split on logical features rather than file-based divisions.

Each patch in the series must compile without errors
and should maintain functionality.

Enable the build as early as possible within the series
to facilitate continuous integration and testing.
This approach ensures a clear and manageable development process.

Split patches following this approach:

* Organize each patch logically as a new feature.
* Run test tools per patch (See :ref:`contrib_tool_list`).
* Update relevant documentation and `<driver>.ini` file with each patch.

The following order in the patch series is as suggested below.

The first patch should have the driver's skeleton which should include:

* Maintainers file update
* Driver documentation
* Document must have links to official product documentation web page
* Add the new document to the index (`index.rst`)
* Initial `<driver>.ini` file
* Release notes announcement for the new driver

The next patches should include basic device features.
The following is a suggested sample list of such patches:

================================  ================================
Net                               Crypto
================================  ================================
Initialization                    Initialization
Configure queues                  Configure queues
Start queues                      Configure sessions
Simple Rx / Tx                    Add capabilities
Statistics                        Statistics and device info
Device info                       Simple data processing
Link interrupt
Burst mode info
Promisc all-multicast
RSS
================================  ================================

Advanced features should be in the next group of patches.
The suggestions for these, listed below, are in no specific order:

================================  ================================
Net                               Crypto
================================  ================================
Advanced Rx / Tx                  Chained operations
Vector Rx / Tx                    Scatter Gather
Scatter support                   Security protocols (IPsec, etc.)
TSO / LRO                         Asymmetric crypto
Rx / Tx descriptor status
Rx / Tx queue info
Flow offload
Traffic management / metering
Extended statistics
Secondary process support
FreeBSD / Windows support
Flow control
FEC
EEPROM access
Register dump
Time synchronization, PTP
Performance documentation
================================  ================================

After enabling all features,
if there is remaining base code that is not upstreamed,
upstream it at the end of the patch series.
However, still split these patches into logical groups.


Additional Suggestions
----------------------

Avoid doing the following:

* Using PMD specific macros when DPDK macros exist
* Including unused headers (see `process-iwyu.py`)
* Disabling compiler warnings for a driver
* #ifdef with driver-defined macros
* DPDK version checks (via ``RTE_VERSION_NUM``) in the upstream code
* Introducing public API directly from the driver

Remember to do the following:

* Runtime configuration when applicable
* Document device parameters in the driver guide
* Make device operations struct 'const'
* Dynamic logging
* SPDX license tags and copyright notice on each file
* Run the Coccinelle scripts `devtools/cocci.sh`
  which check for common cleanups
  such as useless null checks before calling free routines


Dependencies
------------

At times, drivers may have dependencies on external software.
For driver dependencies, the same DPDK rules for dependencies apply.
Dependencies should be publicly and freely available;
drivers that depend on unavailable components will not be accepted.
If the required dependency is not yet publicly available,
wait to submit the driver until the dependent library is available.


.. _contrib_tool_list:

Test Tools
----------

Build and check the driver's documentation.
Ensure there are no warnings
and the driver shows up in the relevant index page.

Run the following test tools per patch in a patch series:

* `checkpatches.sh`
* `check-git-log.sh`
* `check-meson.py`
* `check-doc-vs-code.sh`
* `check-spdx-tag.sh`
* Build documentation and validate how output looks
* Optionally run ``review-patch.py`` for AI-assisted review
  (see :ref:`contrib_ai_assisted_review` in the Contributing Guide)

---

### Doc Guides Contributing New Library (`doc/guides/contributing/new_library.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2023 Marvell.

Adding a new library
====================

Process for approval in principle
---------------------------------

Rationale
~~~~~~~~~

Adding a new library to DPDK with proper RFC and then full patch-sets requires significant effort.
To save effort, developers should seek early approval in principle,
or early feedback if the library is unsuitable for various reasons.

Process
~~~~~~~

#. When a contributor would like to add a new library to the DPDK code base,
   the contributor must send the following items to the DPDK mailing list
   for Technical Board approval-in-principle.

   * Purpose of the library.
   * Scope of work: outline the various additional tasks planned for this library,
     such as developing new test applications, adding new drivers,
     and updating existing applications.
   * Expected usage models of the library.
   * Any licensing constraints.
   * Justification for adding to DPDK.
   * Any other implementations of the same functionality in other libraries/projects
     and how this version differs.
   * Public API specification header file as RFC.

     * Optional and good to have.
     * Technical Board may additionally request this specification collateral
       if needed to get more clarity on scope and purpose.

   * Any new library dependencies to DPDK.

#. Technical Board schedules discussion on this in an upcoming Technical Board meeting
   along with the author.
   Based on the Technical Board schedule and/or author availability,
   Technical Board may need a maximum of **five** Technical Board meeting slots.

#. Based on mailing list and Technical Board meeting discussions,
   Technical Board votes and shares the decision on the mailing list.
   The decision outcome can be any of the following:

   * Approved in principle
   * Not approved
   * Further information needed

#. Once the Technical Board approves the library in principle,
   it is safe to start working on the implementation.
   However, the patches must meet the usual quality criteria
   to be effectively accepted.

---

### Doc Guides Contributing Patches (`doc/guides/contributing/patches.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

.. submitting_patches:

Contributing Code to DPDK
=========================

This document provides guidelines for submitting code to DPDK.

The DPDK development process is loosely based on the Linux Kernel development model.
Review the Linux kernel's guide:
`How to Get Your Change Into the Linux Kernel <https://www.kernel.org/doc/html/latest/process/submitting-patches.html>`_.
Many of DPDK's submission guidelines draw from the kernel process,
and the rationale behind them is often explained in greater depth there.


The DPDK Development Process
----------------------------

The DPDK development process includes the following key elements:

* The project maintains code in a public Git repository.
* Developers submit patches via a public mailing list.
* A hierarchical structure assigns maintainers to different components.
* The community reviews patches publicly on the mailing list.
* Maintainers merge reviewed patches into the repository.
* Contributors should send patches to the target repository or sub-tree (see below for details).

The mailing list for DPDK development is `dev@dpdk.org <https://mails.dpdk.org/archives/dev/>`_.
Contributors must `register for the mailing list <https://mails.dpdk.org/listinfo/dev>`_
to submit patches.
Register for DPDK `Patchwork <https://patches.dpdk.org/project/dpdk/list/>`_ as well.

If you use GitHub, pushing to a branch triggers GitHub Actions,
which builds your changes and runs unit tests and ABI checks.

Contributing to DPDK requires a basic understanding of the Git version control system.
For more information, refer to the `Pro Git Book <http://www.git-scm.com/book/>`_.

Source License
--------------

DPDK uses the Open Source BSD-3-Clause license for its core libraries and drivers.
Kernel components use the GPL-2.0 license.
To identify licenses in source files, DPDK follows the SPDX standard
developed by the Linux Foundation `SPDX project <http://spdx.org/>`_.

Use the SPDX tag on the first line of the file.
For *#!* scripts, place the SPDX tag on the second line.

For BSD-3-Clause:

``SPDX-License-Identifier: BSD-3-Clause``

For dual-licensing with BSD-3-Clause and GPL-2.0 (e.g., shared kernel/user-space code):

``SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0``

Refer to ``licenses/README`` for more details.

Maintainers and Sub-trees
-------------------------

The DPDK maintenance hierarchy divides into a main repository ``dpdk`` and sub-repositories ``dpdk-next-*``.

Maintainers exist for the trees and for components within the tree.

The ``MAINTAINERS`` file lists trees and maintainers. For example::

    Crypto Drivers
    --------------
    M: Some Name <some.name@email.com>
    T: git://dpdk.org/next/dpdk-next-crypto

    Intel AES-NI GCM PMD
    M: Some One <some.one@email.com>
    F: drivers/crypto/aesni_gcm/
    F: doc/guides/cryptodevs/aesni_gcm.rst

Where:

* ``M`` is a tree or component maintainer.
* ``T`` is a repository tree.
* ``F`` is a maintained file or directory.

The ``MAINTAINERS`` file contains additional details.

Component maintainers are responsible for:

* Reviewing patches related to their component or delegating review to others.
  Ideally, complete reviews within one week of mailing list submission.
* Acknowledging patches by adding an ``acked-by`` tag to those deemed ready for merging.
* Responding to questions regarding the component and offering guidance when needed.

Add or remove maintainers by submitting a patch to the ``MAINTAINERS`` file.
New maintainers should have demonstrated consistent contributions or reviews to the component area.
An established contributor must confirm their addition with an ``ack``.
A single component may have multiple maintainers if needed.

Tree Maintainer Responsibilities:

Tree maintainers ensure the overall quality and integrity of their tree.
Their duties include:

* Conducting additional reviews, compilation checks, or other tests as needed.
* Committing patches that component maintainers or other contributors have sufficiently reviewed.
* Ensuring timely review of submitted patches.
* Preparing the tree for integration.
* Appointing a designated backup maintainer and coordinating handovers when unavailable.

Maintainer Changes:

Add or remove tree maintainers by submitting a patch to the MAINTAINERS file.
Proposals must justify the creation of a new sub-tree
and demonstrate significant contribution to the relevant area.
An existing tree maintainer must ack the proposal.

Escalate disputes regarding trees or maintainers to the Technical Board.

Backup Maintainers:

* Choose the main tree's backup maintainer from among existing sub-tree maintainers.
* Choose a sub-tree's backup from the component maintainers within that sub-tree.


Getting the Source Code
-----------------------

Clone the source code using either of the following:

main repository::

    git clone git://dpdk.org/dpdk
    git clone https://dpdk.org/git/dpdk

sub-repositories (`list <https://git.dpdk.org/next>`_)::

    git clone git://dpdk.org/next/dpdk-next-*
    git clone https://dpdk.org/git/next/dpdk-next-*

Make Changes
------------

After cloning the DPDK repository, make your planned changes
while following these key guidelines and requirements:

* Follow the :doc:`coding_style` guidelines.

* If you are a new contributor, or if your mail address changed,
  you may update the ``.mailmap`` file.
  Otherwise a maintainer will add the new name or address.
  Keeping this file up-to-date helps when someone wants to contact you
  about the changes you contributed.

* If you add new files or directories, add your name to the ``MAINTAINERS`` file.

PMD Submissions
~~~~~~~~~~~~~~~

* Prepare initial submissions of new PMDs against the corresponding repo.

  * For example, prepare initial submission of a new network PMD
    against the dpdk-next-net repo.

  * Likewise, prepare initial submission of a new crypto or compression PMD
    against the dpdk-next-crypto repo.

  * For other PMDs and more info, refer to the ``MAINTAINERS`` file.

* Export new external functions.
  See the :doc:`abi_policy` and :doc:`abi_versioning` guides.

API and ABI Guidelines
~~~~~~~~~~~~~~~~~~~~~~

* Use any new API function in the ``/app`` test directory.

* When introducing a new device API, at least one driver should implement it.

Documentation and Release Notes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Important changes require an addition to the release notes in ``doc/guides/rel_notes/``.
  See the :ref:`release notes guidelines <style_release_notes_guidelines>`.

* Test compilation with different targets, compilers, and options;
  see :ref:`contrib_check_compilation`.

* Do not break compilation between commits with forward dependencies in a patch set.
  Each commit should compile on its own to allow ``git bisect`` and continuous integration testing.

* Add tests to the ``app/test`` unit test framework where possible.

* Add documentation, if relevant, in the form of Doxygen comments or a User Guide in RST format.
  See the :doc:`documentation`.

* Update code and related documentation atomically in the same patch.

Commit your changes to your local repo after making them.

Keep small changes that do not require specific explanations in a single patch.
Separate larger changes that require different explanations into logical patches in a patch set.
Consider whether the change could be applied without dependencies as a backport
when deciding whether to split a patch.

Run ``git log`` on similar files as a guide to how patches should be structured.


Commit Messages: Subject Line
-----------------------------

The first, summary, line of the git commit message becomes the subject line of the patch email.
Here are some guidelines for the summary line:

* The summary line must capture the area and the impact of the change.

* The summary line should be around 50 characters.

* The summary line should be lowercase apart from acronyms.

* Prefix with the component name (use git log to check existing components).
  For example::

     ixgbe: fix offload config option name

     config: increase max queues per port

* Use the imperative of the verb (like instructions to the code base).

* Do not add a period/full stop to the subject line or you will end up with two in the patch name: ``dpdk_description..patch``.

The actual email subject line should be prefixed by ``[PATCH]`` and the version, if greater than v1,
for example: ``PATCH v2``.
``git send-email`` or ``git format-patch`` generally adds this prefix; see below.

If you are submitting an RFC draft of a feature, use ``[RFC]`` instead of ``[PATCH]``.
An RFC patch does not have to be complete.
It is intended as a way of getting early feedback.


Commit Messages: Body
---------------------

Here are guidelines for the body of a commit message:

* The body of the message should describe the issue being fixed or the feature being added.
  Provide enough information to allow a reviewer to understand the purpose of the patch.

* When the change is obvious, the body can be blank apart from the signoff.

* The commit message must end with a ``Signed-off-by:`` line, added using::

      git commit --signoff # or -s

  The
  `Developer's Certificate of Origin <https://www.kernel.org/doc/html/latest/process/submitting-patches.html#developer-s-certificate-of-origin-1-1>`_
  section of the Linux kernel guidelines explains the purpose of the signoff.

  .. Note::

     All developers must read and understand the
     Developer's Certificate of Origin section of the documentation prior
     to applying the signoff and submitting a patch.

* The signoff must be a real name and not an alias or nickname.
  More than one signoff is allowed.

* Wrap the text of the commit message at 72 characters.

* When fixing a regression, reference the id of the commit
  which introduced the bug, and put the original author of that commit on CC.
  Generate the required lines using the following git alias, which prints
  the commit SHA and the author of the original code::

     git config alias.fixline "log -1 --abbrev=12 --format='Fixes: %h (\"%s\")%nCc: %ae'"

  Add the output of ``git fixline <SHA>`` to the commit message::

     doc: fix some parameter description

     Update the docs, fixing description of some parameter.

     Fixes: abcdefgh1234 ("doc: add some parameter")

     Signed-off-by: Alex Smith <alex.smith@example.com>
     ---
     Cc: author@example.com

* When fixing an error or warning, include the error message and instructions on how to reproduce it.

* Use correct capitalization, punctuation, and spelling.

In addition to the ``Signed-off-by:`` name, commit messages can also have tags
for who reported, suggested, tested, and reviewed the patch being posted.
Please refer to the `Tested, Acked and Reviewed by`_ section.

Patch Fix Related Issues
~~~~~~~~~~~~~~~~~~~~~~~~

`Coverity <https://scan.coverity.com/projects/dpdk-data-plane-development-kit>`_
is a tool for static code analysis.
It is used as a cloud-based service to scan the DPDK source code
and alert developers of any potential defects in the source code.
When fixing an issue found by Coverity, the patch must contain a Coverity issue ID
in the body of the commit message. For example::


     doc: fix some parameter description

     Update the docs, fixing description of some parameter.

     Coverity issue: 12345
     Fixes: abcdefgh1234 ("doc: add some parameter")

     Signed-off-by: Alex Smith <alex.smith@example.com>
     ---
     Cc: author@example.com


`Bugzilla <https://bugs.dpdk.org>`_
is a bug- or issue-tracking system.
Bug-tracking systems allow individual or groups of developers
to effectively track outstanding problems with their product.
When fixing an issue raised in Bugzilla, the patch must contain
a Bugzilla issue ID in the body of the commit message.
For example::

    doc: fix some parameter description

    Update the docs, fixing description of some parameter.

    Bugzilla ID: 12345
    Fixes: abcdefgh1234 ("doc: add some parameter")

    Signed-off-by: Alex Smith <alex.smith@example.com>
    ---
    Cc: author@example.com

Patch for Stable Releases
~~~~~~~~~~~~~~~~~~~~~~~~~

CC all fix patches to the main branch that are candidates for backporting
to the `stable@dpdk.org <https://mails.dpdk.org/listinfo/stable>`_
mailing list.
In the commit message body, insert ``Cc: stable@dpdk.org`` as follows::

     doc: fix some parameter description

     Update the docs, fixing description of some parameter.

     Fixes: abcdefgh1234 ("doc: add some parameter")
     Cc: stable@dpdk.org

     Signed-off-by: Alex Smith <alex.smith@example.com>

For further information on stable contribution, see
:doc:`Stable Contribution Guide <stable>`.

Patch Dependencies
~~~~~~~~~~~~~~~~~~

Sometimes a patch or patch set depends on another one.
To help the maintainers and automation tasks, document this dependency in the commit log or cover letter
with the following syntax:

``Depends-on: series-NNNNN ("Title of the series")`` or ``Depends-on: patch-NNNNN ("Title of the patch")``

Where ``NNNNN`` is the patchwork ID for the patch or series::

     doc: fix some parameter description

     Update the docs, fixing description of some parameter.

     Signed-off-by: Alex Smith <alex.smith@example.com>
     ---
     Depends-on: series-10000 ("Title of the series")

Tag order
~~~~~~~~~

A pattern indicates how certain tags should relate to each other.

Example of proper tag sequence::

     Coverity issue:
     Bugzilla ID:
     Fixes:
     Cc:

     Reported-by:
     Suggested-by:
     Signed-off-by:
     Acked-by:
     Reviewed-by:
     Tested-by:

An empty line separates the first and second tag sections.

While ``Signed-off-by:`` is obligatory and must exist in each commit,
all other tags are optional.
Any tag, as long as it is in proper location relative to other adjacent tags (if present),
may occur multiple times.

Place tags after the first occurrence of ``Signed-off-by:``
in chronological order.


Creating Patches
----------------

You can send patches directly from git,
but for new contributors it is recommended to generate the patches with ``git format-patch``
and then, when everything looks okay and the patches have been checked,
send them with ``git send-email``.

Here are some examples of using ``git format-patch`` to generate patches:

.. code-block:: console

   # Generate a patch from the last commit.
   git format-patch -1

   # Generate a patch from the last 3 commits.
   git format-patch -3

   # Generate the patches in a directory.
   git format-patch -3 -o ~/patch/

   # Add a cover letter to explain a patch set.
   git format-patch -3 -o ~/patch/ --cover-letter

   # Add a prefix with a version number.
   git format-patch -3 -o ~/patch/ -v 2


Cover letters are useful for explaining a patch set
and help generate logical threading to the patches.
Put smaller notes inline in the patch after the ``---`` separator, for example::

   Subject: [PATCH] fm10k/base: add FM10420 device ids

   Add the device ID for Boulder Rapids and Atwood Channel to enable
   drivers to support those devices.

   Signed-off-by: Alex Smith <alex.smith@example.com>
   ---

   ADD NOTES HERE.

    drivers/net/fm10k/base/fm10k_api.c  | 6 ++++++
    drivers/net/fm10k/base/fm10k_type.h | 6 ++++++
    2 files changed, 12 insertions(+)
   ...

Version 2 and later of a patch set should also include a short log of the changes
so the reviewer knows what has changed.
Add this to the cover letter or the annotations.
For example::

   ---
   v3:
   * Fixed issued with version.map.

   v2:
   * Added i40e support.
   * Renamed ethdev functions from rte_eth_ieee15888_*() to rte_eth_timesync_*()
     since 802.1AS can be supported through the same interfaces.


Checking the Patches
--------------------

Check patches for formatting and syntax issues
using the ``checkpatches.sh`` script in the ``devtools`` directory of the DPDK repo.
This uses the Linux kernel development tool ``checkpatch.pl``,
which can be obtained by cloning, and periodically updating, the Linux kernel sources.

Set the path to the original Linux script in the environment variable ``DPDK_CHECKPATCH_PATH``.

Spell checking of commonly misspelled words is enabled
by default if installed in ``/usr/share/codespell/dictionary.txt``.
Specify a different dictionary path
in the environment variable ``DPDK_CHECKPATCH_CODESPELL``.

A DPDK script builds an adjusted dictionary
from the multiple codespell dictionaries::

   git clone https://github.com/codespell-project/codespell.git
   devtools/build-dict.sh codespell/ > codespell-dpdk.txt

The development tools load environment variables
from the following files, in order of preference::

   .develconfig
   ~/.config/dpdk/devel.config
   /etc/dpdk/devel.config.

Once the environment variable is set, run the script as follows::

   devtools/checkpatches.sh ~/patch/

The script usage is::

   checkpatches.sh [-h] [-q] [-v] [-nX|-r range|patch1 [patch2] ...]

Then check the git logs using the ``check-git-log.sh`` script.

The script usage is::

   check-git-log.sh [-h] [-nX|-r range]

For both scripts, the -n option specifies a number of commits from HEAD,
and the -r option specifies a ``git log`` range.

Additionally, when contributing to the DTS tool, check patches using
the ``dts-check-format.sh`` script in the ``devtools`` directory of the DPDK repo.
Running the script requires extra :ref:`Python dependencies <dts_deps>`.


.. _contrib_ai_assisted_review:

AI-Assisted Patch Review
------------------------

Contributors may optionally use the ``review-patch.py`` script
to get an AI-assisted review of patches before submitting them to the mailing list.
The script checks patches against the DPDK coding standards
and contribution guidelines documented in ``AGENTS.md``.

The script supports multiple AI providers
(Anthropic Claude, OpenAI ChatGPT, xAI Grok, Google Gemini).
An API key for the chosen provider must be set
in the corresponding environment variable (see ``--list-providers``).

Basic usage::

   # Review a single patch (default provider: Anthropic Claude)
   devtools/ai/review-patch.py my-patch.patch

   # Use a different provider
   devtools/ai/review-patch.py -p openai my-patch.patch

   # Review for an LTS branch (enables stricter rules)
   devtools/ai/review-patch.py -r 24.11 my-patch.patch

   # List available providers and their API key variables
   devtools/ai/review-patch.py --list-providers

For a patch series in an mbox file,
the ``--split-patches`` option reviews each patch individually::

   devtools/ai/review-patch.py --split-patches series.mbox

   # Review only a range of patches
   devtools/ai/review-patch.py --split-patches --patch-range 1-5 series.mbox

When reviewing for a Long Term Stable (LTS) release,
use the ``-r`` option with the target version.
Any DPDK release with minor version ``.11`` (e.g., 23.11, 24.11)
is automatically recognized as LTS,
and the script will enforce stricter rules: bug fixes only, no new features or API.

Output can be formatted as plain text (default), Markdown, HTML, or JSON::

   devtools/ai/review-patch.py -f markdown -o review.md my-patch.patch

The review guidelines in ``AGENTS.md`` focus on correctness bug detection
and other DPDK-specific requirements.
Commit message formatting and SPDX/copyright compliance
are checked by ``checkpatches.sh`` and are not duplicated in the AI review.

.. note::

   Always verify AI suggestions before acting on them.


.. _contrib_check_compilation:

Checking Compilation
--------------------

Test compilation of patches with the ``devtools/test-meson-builds.sh`` script.

The script internally checks for dependencies, then builds for several
combinations of compilation configuration.
By default, each build goes in a subfolder of the current working directory.
However, to place the builds in a different location,
set the environment variable ``DPDK_BUILD_TEST_DIR`` to that desired location.
For example, setting ``DPDK_BUILD_TEST_DIR=__builds`` puts all builds
in a single subfolder called "__builds" created in the current directory.
Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path (e.g., ``/tmp``) is also supported.


.. _contrib_integrated_abi_check:

Checking ABI compatibility
--------------------------

By default, ABI compatibility checks are disabled.

To enable them, select a reference version via the environment
variable ``DPDK_ABI_REF_VERSION``. Contributors should ordinarily reference the
git tag of the most recent release of DPDK in ``DPDK_ABI_REF_VERSION``.

The ``devtools/test-meson-builds.sh`` script then builds this reference version
in a temporary directory and stores the results in a subfolder of the current
working directory.
Set the environment variable ``DPDK_ABI_REF_DIR`` to place the results in a different location.

Sample::

   DPDK_ABI_REF_VERSION=v19.11 DPDK_ABI_REF_DIR=/tmp ./devtools/test-meson-builds.sh


Sending Patches
---------------

Send patches to the mailing list using ``git send-email``.
Configure an external SMTP with something like the following::

   [sendemail]
       smtpuser = name@domain.com
       smtpserver = smtp.domain.com
       smtpserverport = 465
       smtpencryption = ssl

See the `Git send-email <https://git-scm.com/docs/git-send-email>`_ documentation for more details.

Send patches to ``dev@dpdk.org``.
If the patches change existing files, send them TO the maintainer(s) and CC ``dev@dpdk.org``.
Find the appropriate maintainer in the ``MAINTAINERS`` file::

   git send-email --to maintainer@some.org --cc dev@dpdk.org 000*.patch

The script ``get-maintainer.sh`` can select maintainers automatically::

  git send-email --to-cmd ./devtools/get-maintainer.sh --cc dev@dpdk.org 000*.patch

Send new additions without a maintainer::

   git send-email --to dev@dpdk.org 000*.patch

Test the emails by sending them to yourself or with the ``--dry-run`` option.

If the patch relates to a previous email thread,
add it to the same thread using the Message ID::

   git send-email --to dev@dpdk.org --in-reply-to <1234-foo@bar.com> 000*.patch

Find the Message ID in the raw text of emails or at the top of each Patchwork patch,
`for example <https://patches.dpdk.org/patch/7646/>`_.
Shallow threading (``--thread --no-chain-reply-to``) is preferred for a patch series.

Once submitted, your patches appear on the mailing list and in Patchwork.

Experienced committers may send patches directly with ``git send-email`` without the ``git format-patch`` step.
The options ``--annotate`` and ``confirm = always`` are recommended for checking patches before sending.


Backporting patches for Stable Releases
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sometimes a maintainer or contributor wishes, or can be asked, to send a patch
for a stable release rather than mainline.
In this case, send the patch(es) to ``stable@dpdk.org``,
not to ``dev@dpdk.org``.

Given that multiple stable releases are maintained simultaneously,
specify exactly which branch(es) the patch is for
using ``git send-email --subject-prefix='PATCH 16.11' ...``
and also optionally in the cover letter or in the annotation.


The Review Process
------------------

The community reviews patches, relying on the experience and
collaboration of the members to double-check each other's work. There are a
number of ways to indicate that you have checked a patch on the mailing list.


Tested, Acked and Reviewed by
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To indicate that you have interacted with a patch on the mailing list,
respond to the patch in an email with one of the following tags:

 * Reviewed-by:
 * Acked-by:
 * Tested-by:
 * Reported-by:
 * Suggested-by:

The tag should be on a separate line as follows::

   tag-here: Name Surname <email@address.com>

Each of these tags has a specific meaning. In general, the DPDK community
follows the kernel usage of the tags. A short summary of the meanings of each
tag is given here for reference:

.. _statement: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#reviewer-s-statement-of-oversight

``Reviewed-by:`` is a strong statement_ that the patch is in an appropriate state
for merging without any remaining serious technical issues. Reviews from
community members who understand the subject area
and perform thorough reviews increase the likelihood of the patch getting merged.

``Acked-by:`` records that the person named was not directly involved in preparing the patch
but wishes to signify and record their acceptance and approval of it.

``Tested-by:`` indicates that the person named has successfully tested the patch
(in some environment).

``Reported-by:`` acknowledges the person who found or reported the bug.

``Suggested-by:`` indicates that the named person suggested the patch idea.


Frequency and volume of patches
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Allow at least 24 hours between posting patch revisions.
This ensures reviewers from different geographical regions have time to provide feedback.
Additionally, do not wait too long (i.e., weeks) between revisions
as this makes it harder for reviewers and maintainers
to recall the context of the previous posting.
If you have not received any feedback within a week,
it is appropriate to send a ping to the mailing list.

Do not post new revisions without addressing all feedback.
Make sure that all outstanding items have been addressed
before posting a new revision for review
(this should involve replying to all the feedback).
Do not post a new version of a patch while there is ongoing discussion
unless a reviewer has specifically requested it.

Do not post your patches to the list in lieu of running tests.
**YOU MUST ENSURE** that your patches are ready by testing them locally
before posting to the mailing list.
Testing locally should involve, at a minimum,
running compilation with debug and release flags, and invoking the unit tests.
Your changes are expected to pass on an x86/x86-64 Linux system.
The infrastructure running the tests is a shared resource among all developers on the project,
and many frequent reposts will result in delays for all developers.
We do our best to include CI and self-test infrastructure
that developers can use individually.

For details on running the unit tests, see :doc:`unit_test`.
It is also recommended to run the :doc:`DTS </tools/dts>` comprehensive tests.
Finally, you can also push to a branch on the GitHub service
to trigger a comprehensive set of compile and unit test runs.

Keep all patch sets to a reasonable length.
Too many or too large patches and series can quickly become difficult to review reasonably.
Appropriately split patches and series into groups of digestible logical changes.


Steps to getting your patch merged
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The more work you put into the previous steps the easier it will be to get a
patch accepted. The general cycle for patch review and acceptance is:

#. Submit the patch.

#. Check the automatic test reports in the coming hours.

#. Wait for review comments. While you are waiting, review some other patches.

#. Fix the review comments and submit a ``v n+1`` patch set::

      git format-patch -3 -v 2

#. Update Patchwork to mark your previous patches as "Superseded".

#. If the relevant maintainer(s) or other developers deem the patch suitable for merging,
   they will ``ack`` the patch with an email that includes something like::

      Acked-by: Alex Smith <alex.smith@example.com>

   **Note**: When acking patches, remove as much of the text of the patch email as possible.
   It is generally best to delete everything after the ``Signed-off-by:`` line.

#. Having the patch ``Reviewed-by:`` and/or ``Tested-by:`` will also help the patch to be accepted.

#. If the patch is deemed unsuitable based on being out of scope
   or conflicting with existing functionality,
   it may receive a ``nack``.
   In this case you will need to make a more convincing technical argument in favor of your patches.

#. In addition, a patch will not be accepted
   if it does not address comments from a previous version with fixes or valid arguments.

#. Maintainers are responsible for ensuring that patches are reviewed
   and for providing an ``ack`` or ``nack`` of those patches as appropriate.

#. Once the relevant maintainer has acked a patch,
   reviewers may still comment on it for a further two weeks.
   After that time, the patch should be merged into the relevant git tree for the next release.
   Additional notes and restrictions:

   * Maintainers should ack patches at least two days before the release merge deadline,
     in order to make that release.
   * For patches acked with less than two weeks to go to the merge deadline, all additional
     comments should be made no later than two days before the merge deadline.
   * After the appropriate time for additional feedback has passed, if the patch has not yet
     been merged to the relevant tree by the committer, it should be treated as though it had,
     in that any additional changes needed to it must be addressed by a follow-on patch, rather
     than rework of the original.
   * Trivial patches may be merged sooner than described above at the tree committer's
     discretion.


Milestones definition
---------------------

Each DPDK release has milestones that help everyone converge to the release date.
The following is a list of these milestones together with
concrete definitions and expectations for a typical release cycle.
An average cycle lasts 3 months and has 4 release candidates in the last month.
Test reports are expected after each release candidate.
The number and expectations of release candidates might vary slightly.
The schedule is updated in the `roadmap <https://core.dpdk.org/roadmap/#dates>`_.

.. note::
   Sooner is always better. Deadlines are not ideal dates.

   Integration is never guaranteed but everyone can help.

Roadmap
~~~~~~~

* Announce new features in libraries, drivers, applications, and examples.
* Publish before the previous release.

Proposal Deadline
~~~~~~~~~~~~~~~~~

* Send an RFC (Request For Comments) or a complete patch of new features.
* Early RFC gives time for design review before complete implementation.
* Include at least the API changes in libraries and applications.
* Library code should be quite complete at the deadline.
* Nice to have: driver implementation, example code, and documentation.

rc1
~~~

* Priority: libraries. No library feature should be accepted after -rc1.
* Implement API changes or additions in libraries.
* The API must include Doxygen documentation
  and be part of the relevant .rst files (library-specific and release notes).
* Use the API in a test application (``/app``).
* At least one PMD should implement the API.
  It may be a draft sent in a separate series.
* Send the above to the mailing list at least 2 weeks before -rc1
  to give time for review and maintainer approval.
* If no review after 10 days, send a reminder.
* Nice to have: example code (``/examples``)

rc2
~~~

* Priority: drivers. No driver feature should be accepted after -rc2.
* A driver change must include documentation
  in the relevant .rst files (driver-specific and release notes).
* Send driver changes to the mailing list before -rc1 is released.

rc3
~~~

* Priority: applications. No application feature should be accepted after -rc3.
* New functionality that does not depend on library updates
  can be integrated as part of -rc3.
* The application change must include documentation in the relevant .rst files
  (application-specific and release notes if significant).
* Library and driver cleanup is allowed.
* Small driver reworks.

rc4
~~~

* Documentation updates.
* Critical bug fixes only.

.. note::
   Integrate bug fixes as early as possible at any stage.

---

### Doc Guides Contributing Stable (`doc/guides/contributing/stable.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 The DPDK contributors

DPDK Stable Releases and Long Term Support
==========================================

This section outlines the guidelines for DPDK Stable Releases and Long Term Support (LTS) releases.


Introduction
------------

The purpose of DPDK Stable Releases is to maintain DPDK versions
with backported fixes over an extended period.
This allows downstream users to base applications or packages on a stable,
well-maintained version of DPDK.

The primary goal of stable releases is to fix issues without introducing regressions,
while preserving backward compatibility with the original version.

LTS (Long Term Support) is a designation given to specific stable releases
to indicate extended support duration.


Stable Releases
---------------

Any DPDK release may become a Stable Release if a maintainer volunteers to support it
and major contributors commit to validating it before each release.
This designation should be made within one month of the version's initial release.

Stable Releases are typically used to backport fixes
from an ``N`` release to an ``N-1`` release, for example, from 16.11 to 16.07.

* The standard support duration is one full release cycle (4 months).
* This may extend up to one year if the maintainer continues support
  or if users provide backported fixes.
* The maintainer determines the release cadence based on the volume and criticality of fixes.
* Coordinate releases with validation engineers to ensure proper testing before tagging.


LTS Releases
------------

A Stable Release can be promoted to an LTS release through community agreement
and a maintainer's commitment.

* The current policy designates each November release (X.11) as an LTS
  and maintains it for 3 years, contingent on community validation support.
* After release, an LTS branch is created at https://git.dpdk.org/dpdk-stable
  where bugfixes are backported.
* An LTS release may align with the declaration of a new major ABI version.
  See the :doc:`abi_policy` for more information.

Release Cadence:

* At least three LTS updates per year (roughly one every four months).
* Aligned with main DPDK releases to leverage shared validation.
* Frequency may vary depending on the urgency and volume of fixes.
* Coordinate validation with test engineers.

For a list of the currently maintained stable/LTS branches,
see the `stable roadmap <https://core.dpdk.org/roadmap/#stable>`_.

At the end of the 3-year period, a final X.11.N release is made,
after which the LTS branch is no longer maintained.


What Changes Should Be Backported
---------------------------------

Limit backports to bug fixes.

All patches accepted on the main branch with a ``Fixes:`` tag
should be backported to the relevant stable/LTS branches,
unless the submitter indicates otherwise.

Fixes suitable for backport should have a ``Cc: stable@dpdk.org`` tag in the
commit message body as follows::

     doc: fix some parameter description

     Update the docs, fixing description of some parameter.

     Fixes: abcdefgh1234 ("doc: add some parameter")
     Cc: stable@dpdk.org

     Signed-off-by: Alex Smith <alex.smith@example.com>

Fixes not suitable for backport should not include the ``Cc: stable@dpdk.org`` tag.

New features should not be backported to stable releases.
In limited cases, a new feature may be acceptable if:

* It does not break API or ABI.
* It preserves backward compatibility.
* It targets the latest LTS release (to help with upgrade paths).
* The proposer commits to testing the feature and monitoring regressions.
* The proposer or their organization has a track record of validating stable releases.
* It clearly does not impact existing functionality.
* The change is minimally invasive and scoped.
* It affects vendor-specific components rather than common ones.
* There is a justifiable use case (a clear user need).
* There is community consensus about the backport.

Performance improvements are generally not considered fixes,
but may be considered in cases where:

* It is fixing a performance regression that occurred previously.
* An existing feature in LTS is not usable as intended without it.

APIs marked as ``experimental`` are not considered part of the ABI version
and can be changed without prior notice in mainline development.
However, in LTS releases, ``experimental`` APIs should not be changed,
as compatibility with previous releases of an LTS version is paramount.


The Stable Mailing List
-----------------------

Stable and LTS releases are coordinated on the stable@dpdk.org mailing list.

All fix patches to the main branch that are candidates for backporting
should also be CCed to the `stable@dpdk.org <https://mails.dpdk.org/listinfo/stable>`_
mailing list.


Releasing
---------

A Stable Release is made by:

* Tagging the release with YY.MM.n (year, month, number).
* Uploading a tarball of the release to dpdk.org.
* Sending an announcement to the `announce@dpdk.org <https://mails.dpdk.org/listinfo/announce>`_
  list.

Stable releases are available on the `dpdk.org download page <https://core.dpdk.org/download/>`_.

---

### Doc Guides Contributing Unit Test (`doc/guides/contributing/unit_test.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2021 The DPDK contributors

DPDK Unit Testing Guidelines
============================

This document outlines the guidelines for running and adding new
tests to the in-tree DPDK test suites.

The DPDK test suite model is loosely based on the xUnit model,
where tests are grouped into test suites, and suites are run by runners.
For a basic overview, see the Wikipedia article on `xUnit
<https://en.wikipedia.org/wiki/XUnit>`_.


Background
----------

The in-tree testing infrastructure for DPDK consists of
multiple applications and support tools.
The primary tools are the ``dpdk-test`` application
and the ``meson test`` infrastructure.
These two are the primary ways users interact with the DPDK testing infrastructure.

Some confusion exists regarding test suite and test case separation
between ``dpdk-test`` and ``meson test``.
Both have a concept of test suite and test case.
In both, the concept is similar.
A test suite is a group of test cases,
and a test case represents the steps needed to test a particular set of code.
Where needed, they will be disambiguated by the word Meson
to denote a Meson test suite / case.


Running a test
--------------

DPDK tests run via the main test runner, the ``dpdk-test`` app.
The ``dpdk-test`` app is a command-line interface that facilitates
running various tests or test suites.

There are three modes of operation.
The first mode is an interactive command shell
that allows launching specific test suites.
This is the default operating mode of ``dpdk-test`` and can be invoked by::

   $ ./build/app/test/dpdk-test --dpdk-options-here
   EAL: Detected 4 lcore(s)
   EAL: Detected 1 NUMA nodes
   EAL: Static memory layout is selected, amount of reserved memory...
   EAL: Multi-process socket /run/user/26934/dpdk/rte/mp_socket
   EAL: Selected IOVA mode 'VA'
   EAL: Probing VFIO support...
   EAL: PCI device 0000:00:1f.6 on NUMA socket -1
   EAL:   Invalid NUMA socket, default to 0
   EAL:   probe driver: 8086:15d7 net_e1000_em
   APP: HPET is not enabled, using TSC as default timer
   RTE>>

At the prompt, type the name of the test suite you wish to run
and it will execute.

The second form is useful for a scripting environment
and is used by the DPDK Meson build system.
Invoke this mode by
assigning a specific test suite name to the environment variable ``DPDK_TEST``
before invoking the ``dpdk-test`` command, such as::

   $ DPDK_TEST=version_autotest ./build/app/test/dpdk-test --dpdk-options-here
   EAL: Detected 4 lcore(s)
   EAL: Detected 1 NUMA nodes
   EAL: Static memory layout is selected, amount of reserved memory can be...
   EAL: Multi-process socket /run/user/26934/dpdk/rte/mp_socket
   EAL: Selected IOVA mode 'VA'
   EAL: Probing VFIO support...
   EAL: PCI device 0000:00:1f.6 on NUMA socket -1
   EAL:   Invalid NUMA socket, default to 0
   EAL:   probe driver: 8086:15d7 net_e1000_em
   APP: HPET is not enabled, using TSC as default timer
   RTE>>version_autotest
   Version string: 'DPDK 20.02.0-rc0'
   Test OK
   RTE>>$

The above shows running a specific test suite.
On success, the return code will be 0;
otherwise it will be set to some error value (such as 255).

The third form is an alternative
to providing the test suite name in an environment variable.
The unit test app can accept test suite names via command line arguments::

   $ ./build/app/test/dpdk-test --dpdk-options-here version_autotest version_autotest
   EAL: Detected 8 lcore(s)
   EAL: Detected 1 NUMA nodes
   EAL: Static memory layout is selected, amount of reserved memory can be...
   EAL: Detected static linkage of DPDK
   EAL: Multi-process socket /run/user/26934/dpdk/rte/mp_socket
   EAL: Selected IOVA mode 'VA'
   APP: HPET is not enabled, using TSC as default timer
   RTE>>version_autotest
   Version string: 'DPDK 21.08.0-rc0'
   Test OK
   RTE>>version_autotest
   Version string: 'DPDK 21.08.0-rc0'
   Test OK
   RTE>>

The primary benefit here is specifying multiple test names,
which is not possible with the ``DPDK_TEST`` environment variable.

Additionally, you can specify additional test parameters
via the ``DPDK_TEST_PARAMS`` argument,
in case some tests need additional configuration.
This is not currently used in the Meson test suites.


Running test cases via Meson
----------------------------

To allow developers to quickly execute all the standard internal tests
without needing to remember or look up each test suite name,
the build system includes a standard way of executing the Meson test suites.
After building via ``ninja``, the ``meson test`` command
with no arguments executes the Meson test suites.

There are a number of pre-configured Meson test suites.
The first is the **fast** test suite, which is the largest group of test cases.
These are the bulk of the unit tests to validate functional blocks.
The second is the **perf** tests.
These test suites can take longer to run and do performance evaluations.
The third is the **driver** test suite,
which is mostly for special hardware related testing (such as crypto devices).
The fourth, and currently the last, suite is the **debug** suite.
These tests mostly dump system information.

Select the Meson test suites by adding the ``--suite`` option
to the ``meson test`` command.
Ex: ``meson test --suite fast-tests``::

   $ meson test -C build --suite fast-tests
   ninja: Entering directory `/home/aconole/git/dpdk/build'
   [2543/2543] Linking target app/test/dpdk-test.
   1/60 DPDK:fast-tests / acl_autotest          OK       3.17 s
   2/60 DPDK:fast-tests / bitops_autotest       OK       0.22 s
   3/60 DPDK:fast-tests / byteorder_autotest    OK       0.22 s
   4/60 DPDK:fast-tests / cmdline_autotest      OK       0.28 s
   5/60 DPDK:fast-tests / common_autotest       OK       0.57 s
   6/60 DPDK:fast-tests / cpuflags_autotest     OK       0.27 s
   ...

The ``meson test`` command can also execute individual Meson test cases
via the command line by adding the test names as an argument::

   $ meson test -C build version_autotest
   ninja: Entering directory `/home/aconole/git/dpdk/build'
   [2543/2543] Linking target app/test/dpdk-test.
   1/1 DPDK:fast-tests / version_autotest OK             0.17s
   ...

Note that Meson must know these test cases
for the ``meson test`` command to run them.
Simply adding a new test to the ``dpdk-test`` application is not enough.
See the section `Adding a suite or test case to Meson`_ for more details.


Adding tests to dpdk-test application
-------------------------------------

Add unit tests to the system
whenever introducing new functionality to DPDK
or resolving a bug.
This helps the DPDK project catch regressions as they occur.

The DPDK test application supports two layers of tests:
   #. *test cases* which are individual tests
   #. *test suites* which are groups of test cases

To add a new test suite to the DPDK test application,
create a new test file for that suite
(ex: see *app/test/test_version.c* for the ``version_autotest`` test suite).
There are two important functions for interacting with the test harness:

   ``REGISTER_<MESON_SUITE>_TEST(command_name, function_to_execute)``
      Registers a test command with the name `command_name`
      and which runs the function `function_to_execute` when `command_name` is invoked.
      This macro automatically adds the test to the Meson test suite `<MESON_SUITE>`.
      Examples: ``REGISTER_DRIVER_TEST``, or ``REGISTER_PERF_TEST``.
      **NOTE:** The ``REGISTER_FAST_TEST`` macro is slightly different,
      in that it takes two additional parameters before the function name:
      the hugepage requirement (``NOHUGE_OK`` if the test can run without hugepages,
      or ``NOHUGE_SKIP`` if hugepages are required),
      and Address Sanitizer compatibility (``ASAN_OK`` if the test can run with ASan enabled,
      or ``ASAN_SKIP`` if it cannot).

   ``unit_test_suite_runner(struct unit_test_suite *)``
      Returns a runner for a full test suite object,
      which contains a test suite name, setup, tear down,
      a pointer to a list of sub-testsuites,
      and vector of unit test cases.

Each test suite has a setup and tear down function
that runs at the beginning and end of the test suite execution.
Each unit test has a similar function for test case setup and tear down.

Each test suite may use a nested list of sub-testsuites,
which the ``unit_test_suite_runner`` iterates.
This support allows for better granularity when designing test suites.
The sub-testsuites list can also be used in parallel with the vector of test cases;
in this case, the test cases run first, then each sub-testsuite executes.
To see an example of a test suite using sub-testsuites,
see *app/test/test_cryptodev.c*.

Example of a test suite with a single test case:

.. code-block:: c
   :linenos:

   #include "test.h"

   static int testsuite_setup(void) { return TEST_SUCCESS; }
   static void testsuite_teardown(void) { }

   static int ut_setup(void) { return TEST_SUCCESS; }
   static void ut_teardown(void) { }

   static int test_case_first(void) { return TEST_SUCCESS; }

   static struct unit_test_suite example_testsuite = {
          .suite_name = "EXAMPLE TEST SUITE",
          .setup = testsuite_setup,
          .teardown = testsuite_teardown,
          .unit_test_cases = {
               TEST_CASE_ST(ut_setup, ut_teardown, test_case_first),

               TEST_CASES_END(), /**< NULL terminate unit test array */
          },
   };

   static int example_tests()
   {
       return unit_test_suite_runner(&example_testsuite);
   }

   REGISTER_PERF_TEST(example_autotest, example_tests);

The above code block is a small example
that can be used to create a complete test suite with a test case.

Add sub-testsuites to the ``.unit_test_suites`` element
of the unit test suite structure, for example:

.. code-block:: c
   :linenos:

   static int testsuite_setup(void) { return TEST_SUCCESS; }
   static void testsuite_teardown(void) { }

   static int ut_setup(void) { return TEST_SUCCESS; }
   static void ut_teardown(void) { }

   static int test_case_first(void) { return TEST_SUCCESS; }

   static struct unit_test_suite example_parent_testsuite = {
          .suite_name = "EXAMPLE PARENT TEST SUITE",
          .setup = testsuite_setup,
          .teardown = testsuite_teardown,
          .unit_test_cases = {TEST_CASES_END()}
   };

   static int sub_testsuite_setup(void) { return TEST_SUCCESS; }
   static void sub_testsuite_teardown(void) { }

   static struct unit_test_suite example_sub_testsuite = {
          .suite_name = "EXAMPLE SUB TEST SUITE",
          .setup = sub_testsuite_setup,
          .teardown = sub_testsuite_teardown,
          .unit_test_cases = {
               TEST_CASE_ST(ut_setup, ut_teardown, test_case_first),

               TEST_CASES_END(), /**< NULL terminate unit test array */
          },
   };

   static struct unit_test_suite end_testsuite = {
          .suite_name = NULL,
          .setup = NULL,
          .teardown = NULL,
          .unit_test_suites = NULL
   };

   static int example_tests()
   {
       uint8_t ret, i = 0;
       struct unit_test_suite *sub_suites[] = {
              &example_sub_testsuite,
              &end_testsuite /**< NULL test suite to indicate end of list */
        };

       example_parent_testsuite.unit_test_suites =
               malloc(sizeof(struct unit_test_suite *) * RTE_DIM(sub_suites));

       for (i = 0; i < RTE_DIM(sub_suites); i++)
           example_parent_testsuite.unit_test_suites[i] = sub_suites[i];

       ret = unit_test_suite_runner(&example_parent_testsuite);
       free(example_parent_testsuite.unit_test_suites);

       return ret;
   }

   REGISTER_FAST_TEST(example_autotest, NOHUGE_OK, ASAN_OK, example_tests);


Designing a test
----------------

Test cases have multiple ways of indicating an error has occurred,
in order to reflect failure state back to the runner.
Using the various methods of indicating errors can assist
in not only validating the requisite functionality is working,
but also to help debug when a change in environment or code
has caused things to go wrong.

The first way to indicate a generic error is
by returning a test result failure, using the ``TEST_FAILED`` error code.
This is the most basic way of indicating that an error
has occurred in a test routine.
It is not very informative to the user, so use it in cases
where the test has catastrophically failed.

The preferred method of indicating an error is
via the ``RTE_TEST_ASSERT`` family of macros,
which immediately return ``TEST_FAILED`` error condition,
but also log details about the failure.
The basic form is:

.. code-block:: c

   RTE_TEST_ASSERT(cond, msg, ...)

In the above macro, *cond* is the condition to evaluate to **true**.
Any generic condition can go here.
The *msg* parameter is a message to display if *cond* evaluates to **false**.
Some specialized macros already exist.
See ``lib/librte_eal/include/rte_test.h`` for a list of defined test assertions.

Sometimes it is important to indicate that a test needs to be skipped,
either because the environment cannot support running the test,
or because some requisite functionality is unavailable.
The test suite supports returning a result of ``TEST_SKIPPED``
during test case setup, or during test case execution
to indicate that the preconditions of the test are not available.
Example::

   $ meson test -C build --suite fast-tests
   ninja: Entering directory `/home/aconole/git/dpdk/build'
   [2543/2543] Linking target app/test/dpdk-test.
   1/60 DPDK:fast-tests / acl_autotest          OK       3.17 s
   2/60 DPDK:fast-tests / bitops_autotest       OK       0.22 s
   3/60 DPDK:fast-tests / byteorder_autotest    OK       0.22 s
   ...
   46/60 DPDK:fast-tests / ipsec_autotest       SKIP     0.22 s
   ...


Checking code coverage
----------------------

The Meson build system supports generating a code coverage report
via the ``-Db_coverage=true`` option,
in conjunction with a package like **lcov**,
to generate an HTML code coverage report.
Example::

   $ meson setup build -Db_coverage=true
   $ meson test -C build --suite fast-tests
   $ ninja coverage-html -C build

The above generates an HTML report
in the ``build/meson-logs/coveragereport/`` directory
that can be explored for detailed code covered information.
Use this to assist in test development.


Adding a suite or test case to Meson
------------------------------------

Adding to one of the Meson test suites involves using the appropriate macro
to register the test in dpdk-test, as described above.
For example,
defining the test command using ``REGISTER_PERF_TEST`` automatically
adds the test to the perf-test meson suite.
Once added, the new test runs
as part of the appropriate class (fast, perf, driver, etc.).

Confirm that a test is known to Meson
by using the ``--list`` option::

   $ meson test -C build --list
   DPDK:fast-tests / acl_autotest
   DPDK:fast-tests / bitops_autotest
   ...

Some of these test suites run during continuous integration tests,
making regression checking automatic for new patches submitted to the project.

.. note::

   The old ``REGISTER_TEST_COMMAND`` macro
   to add a command without adding it to a meson test suite is deprecated.
   All new tests must be added to a test suite
   using the appropriate ``REGISTER_<SUITE>_TEST`` macro.

Running cryptodev tests
-----------------------

When running cryptodev tests, create any required virtual device
via EAL arguments, as this is not done automatically by the test::

   $ ./build/app/test/dpdk-test --vdev crypto_aesni_mb
   $ meson test -C build --suite driver-tests \
                --test-args="--vdev crypto_aesni_mb"

.. note::

   The ``cryptodev_scheduler_autotest`` is the only exception.
   This vdev is created automatically by the test app,
   as it requires a more complex setup than other vdevs.

---

### Doc Guides Contributing Vulnerability (`doc/guides/contributing/vulnerability.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2019 The DPDK contributors

DPDK Vulnerability Management Process
=====================================

Scope
-----

This security process covers only the main repositories (dpdk and dpdk-stable)
of the core project (including experimental APIs).
The team will not apply fixes to stable branches declared unmaintained (end of life).

All vulnerabilities are bugs, but not every bug is a vulnerability.
Vulnerabilities compromise one or more of:

* Confidentiality (personal or corporate confidential data).
* Integrity (trustworthiness and correctness).
* Availability (uptime and service).

If in doubt, consider the vulnerability as security sensitive.
At worst, the response will be to report the bug through the usual channels.


Finding
-------

There is no pro-active security engineering effort at the moment.

Report any security issue you find in DPDK as described below.


Reporting
---------

Do not use Bugzilla to report security vulnerabilities,
as it is not secured for such communication.
Instead, send a GPG-encrypted email
to `security@dpdk.org <https://core.dpdk.org/security#contact>`_.
This address is open to all,
but access to its inbox is intentionally limited to a small group
to minimize the risk of early disclosure.

GPG-sign any one-on-one correspondence related to the vulnerability report
as part of maintaining a secure communication process.

As with any bug report, detailed information greatly aids
in diagnosing and resolving the issue.
If you have already developed a fix,
include it in your submission to help accelerate resolution.

In your report, specify how you would like to be credited for the discovery
and mention any embargo period you wish to impose.

If the vulnerability has not yet been made public,
do not disclose patches or related information publicly.
Even if a fix has already been published,
you must still follow the proper reporting process outlined here.


Confirmation
------------

Upon receiving the report, a security team member should reply to the reporter
acknowledging receipt.

The DPDK security team reviews the security vulnerability reported.
Area experts who are not members of the security team may be involved in the process.
If the reported issue does not qualify as a security vulnerability,
the security team will request the submitter to report it
using the usual channel (Bugzilla).
If qualified, the security team assesses which DPDK versions are affected.
A bugzilla ID (allocated from a `reserved pool
<https://bugs.dpdk.org/buglist.cgi?f1=bug_group&o1=equals&v1=security>`_)
is assigned to the vulnerability, and kept empty until public disclosure.

The security team calculates the severity score with the
`CVSS calculator <https://www.first.org/cvss/calculator/3.0>`_
based on inputs from the reporter and its own assessment of the vulnerability,
and agrees on the score with the reporter.

An embargo may be put in place depending on the severity of the vulnerability.
If an embargo is decided, the security team should suggest the duration
and negotiate with the reporter.
Embargo duration between vulnerability confirmation and public disclosure
should be between **one and ten weeks**.
If an embargo is not required, the vulnerability may be fixed
using the standard patch process, once a CVE number has been assigned.

Send the confirmation mail within **3 business days**.

Include the following information in the mail:

* Confirmation
* CVSS severity and score
* Embargo duration
* Reporter credit
* Bug ID (empty and restricted for future reference)

CVE Request
-----------

The security team develops a security advisory document.
The security team may, at its discretion,
include the reporter (via "CC") in developing the security advisory document,
but in any case should accept feedback
from the reporter before finalizing the document.
When the document is final, the security team needs to
request a CVE identifier from a CNA.

Send the CVE request
to `secalert@redhat.com <mailto:secalert@redhat.com>`_
using GPG encrypted email
(see `contact details <https://access.redhat.com/security/team/contact>`_).


CVE Request Template with Embargo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

  A vulnerability was discovered in the DPDK project.
  In order to ensure full traceability, we need a CVE number assigned
  that we can attach to private and public notifications.
  Please treat the following information as confidential during the embargo
  until further public disclosure.

  [PRODUCT]:
  [VERSION]:
  [PROBLEMTYPE]:
  [SEVERITY]:
  [REFERENCES]: { bug_url }
  [DESCRIPTION]:

  Thanks
  { DPDK_security_team_member }, on behalf of the DPDK security team


CVE Request Template without Embargo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

  A vulnerability was discovered in the DPDK project.
  In order to ensure full traceability, we need a CVE number assigned
  that we can attach to private and public notifications.

  [PRODUCT]:
  [VERSION]:
  [PROBLEMTYPE]:
  [SEVERITY]:
  [REFERENCES]: { bug_url }
  [DESCRIPTION]:

  Thanks
  { DPDK_security_team_member }, on behalf of the DPDK security team


Fix Development and Review
--------------------------

If the fix is already published, skip this step,
and replace the pre-release disclosure with the private disclosure,
as described below.
This should not be considered the standard process.

This step may start in parallel with CVE creation.
The security team and elected area experts who agree to maintain confidentiality
develop and review patches fixing the vulnerability.

Reference the CVE id and the bug id in the patch if there is no embargo,
or if the embargo will be lifted when the release including the patch is published.
If the embargo will be lifted after the release,
omit the CVE and bug ids from the commit message.

Backports to the identified affected versions are done once the fix is ready.


Pre-Release Disclosure
----------------------

When the fix is ready, send the security advisory and patches
to downstream stakeholders
(`security-prerelease@dpdk.org <mailto:security-prerelease@dpdk.org>`_),
specifying the date and time of the end of the embargo.
The communicated public disclosure date should be **less than one week**.

Downstream stakeholders are expected not to deploy or disclose patches
until the embargo passes; otherwise they will be removed from the list.

Downstream stakeholders (in `security-prerelease list
<https://mails.dpdk.org/roster/security-prerelease>`_) are:

* Operating system vendors known to package DPDK
* Major DPDK users, considered trustworthy by the technical board, who
  have made the request to `techboard@dpdk.org <mailto:techboard@dpdk.org>`_

The `OSS security private mailing list <mailto:distros@vs.openwall.org>`_ will
also be contacted one week before the end of the embargo, as indicated by `the
OSS-security process <https://oss-security.openwall.org/wiki/mailing-lists/distros>`_
and using the PGP key listed on the same page, describing the details of the
vulnerability and sharing the patch[es]. Distributions and major vendors follow
this private mailing list, and it functions as a single point of contact for
embargoed advance notices for open source projects.

The security advisory will be based on the template below,
and will be sent signed with a security team member's GPG key.


Pre-Release Mail Template
~~~~~~~~~~~~~~~~~~~~~~~~~

::

  This is an advance warning of a vulnerability discovered in DPDK,
  to give you, as downstream stakeholders, a chance to coordinate
  the release of fixes and reduce the vulnerability window.
  Please treat the following information as confidential until
  the proposed public disclosure date.

  { impact_description }

  Proposed patches are attached.
  Unless a flaw is discovered in them, these patches will be merged
  to { branches } on the public disclosure date.

  CVE: { cve_id }
  Severity: { severity }
  CVSS scores: { cvss_scores }

  Proposed public disclosure date/time: { disclosure_date } at 15:00 UTC.
  Please do not make the issue public (or release public patches)
  before this coordinated embargo date.

If the issue is leaked during the embargo, follow the same procedure
with only a few days delay between the pre-release and the public disclosure.


Private Disclosure
------------------

If a vulnerability is unintentionally already fixed in the public repository,
send a security advisory to downstream stakeholders
(`security-prerelease@dpdk.org <mailto:security-prerelease@dpdk.org>`_),
giving a few days to prepare for updating before the public disclosure.


Private Disclosure Mail Template
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

  This is a warning of a vulnerability discovered in DPDK,
  to give you, as downstream stakeholders, a chance to coordinate
  the deployment of fixes before a CVE is public.

  Please treat the following information as confidential until
  the proposed public disclosure date.

  { impact_description }

  Commits: { commit_ids with branch number }

  CVE: { cve_id }
  Severity: { severity }
  CVSS scores: { cvss_scores }

  Proposed public disclosure date/time: { disclosure_date }.
  Please do not make the vulnerability information public
  before this coordinated embargo date.


Public Disclosure
-----------------

When the embargo expires, carry out the following actions simultaneously:

* A security team member files the assigned bug with all relevant details
  and makes it publicly accessible.

* Push the associated patches to the appropriate branches.

* Release updated versions for all affected stable branches, both short-term and long-term.

To ease adoption by system administrators,
preferably schedule security releases between Monday and Wednesday, avoiding weekends.

Post the security advisory
to `announce@dpdk.org <mailto:announce@dpdk.org>`_ and to `the public OSS-security
mailing list <mailto:oss-security@lists.openwall.com>`_ as soon as the patches
are pushed to the appropriate branches.

Send patches to `dev@dpdk.org <mailto:dev@dpdk.org>`_
and `stable@dpdk.org <mailto:stable@dpdk.org>`_ accordingly.


Release Mail Template
~~~~~~~~~~~~~~~~~~~~~

::

  A vulnerability was fixed in DPDK.
  Some downstream stakeholders were warned in advance
  in order to coordinate the release of fixes
  and reduce the vulnerability window.

  { impact_description }

  Commits: { commit_ids with branch number }

  CVE: { cve_id }
  Bugzilla: { bug_url }
  Severity: { severity }
  CVSS scores: { cvss_scores }


References
----------

* `A minimal security response process
  <https://access.redhat.com/blogs/766093/posts/1975833>`_
* `fd.io Vulnerability Management
  <https://wiki.fd.io/view/TSC:Vulnerability_Management>`_
* `Open Daylight Vulnerability Management
  <https://wiki.opendaylight.org/view/Security:Vulnerability_Management>`_
* `CVE Assignment Information Format
  <https://cve.mitre.org/cve/list_rules_and_guidance/cve_assignment_information_format.html>`_

---

### Doc Guides Cryptodevs Aesni Gcm (`doc/guides/cryptodevs/aesni_gcm.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2016-2020 Intel Corporation.

AES-NI GCM Crypto Poll Mode Driver
==================================


The AES-NI GCM PMD (**librte_crypto_aesni_gcm**) provides poll mode crypto driver
support for utilizing Intel multi buffer library (see AES-NI Multi-buffer PMD documentation
to learn more about it, including installation).

The AES-NI GCM PMD supports synchronous mode of operation with
``rte_cryptodev_sym_cpu_crypto_process`` function call for both AES-GCM and
GMAC, however GMAC support is limited to one segment per operation. Please
refer to ``rte_crypto`` programmer's guide for more detail.

Features
--------

AESNI GCM PMD has support for:

Authentication algorithms:

* RTE_CRYPTO_AUTH_AES_GMAC

AEAD algorithms:

* RTE_CRYPTO_AEAD_AES_GCM

Limitations
-----------

* In out-of-place operations, chained destination mbufs are not supported.
* Cipher only is not supported.


Installation
------------

To build DPDK with the AESNI_GCM_PMD the user is required to download the multi-buffer
library from `here <https://github.com/01org/intel-ipsec-mb>`_
and compile it on their user system before building DPDK.
The latest version of the library supported by this PMD is v1.5, which
can be downloaded in `<https://github.com/01org/intel-ipsec-mb/archive/v1.5.zip>`_.

For Arm system, ARM64 port of the multi-buffer library can be downloaded from
https://gitlab.arm.com/arm-reference-solutions/ipsec-mb/-/tree/main/.
The latest version of the library supported by this PMD is tagged as SECLIB-IPSEC-2026.05.30.

.. code-block:: console

    make
    make install

The library requires NASM to be built. Depending on the library version, it might
require a minimum NASM version (e.g. v0.54 requires at least NASM 2.14).

NASM is packaged for different OS. However, on some OS the version is too old,
so a manual installation is required. In that case, NASM can be downloaded from
`NASM website <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_.
Once it is downloaded, extract it and follow these steps:

.. code-block:: console

    ./configure
    make
    make install


As a reference, the following table shows a mapping between the past DPDK versions
and the external crypto libraries supported by them:

.. table:: DPDK and external crypto library version compatibility

   =============  ================================
   DPDK version   Crypto library version
   =============  ================================
   20.11 - 21.08  Multi-buffer library 0.53 - 1.3
   21.11 - 24.07  Multi-buffer library 1.0  - 1.5
   24.11+         Multi-buffer library 1.4+
   =============  ================================

Initialization
--------------

In order to enable this virtual crypto PMD, user must:

* Build the multi buffer library (explained in Installation section).

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_aesni_gcm") within the application.

* Use --vdev="crypto_aesni_gcm" in the EAL options, which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

* socket_id: Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

* max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).

* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).

Example:

.. code-block:: console

    ./dpdk-l2fwd-crypto -l 1 --vdev="crypto_aesni_gcm,socket_id=0,max_nb_sessions=128" \
    -- -p 1 --cdev SW --chain AEAD --aead_algo "aes-gcm"

---

### Doc Guides Cryptodevs Aesni Mb (`doc/guides/cryptodevs/aesni_mb.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2015-2018 Intel Corporation.

AES-NI Multi Buffer Crypto Poll Mode Driver
===========================================


The AESNI MB PMD (**librte_crypto_aesni_mb**) provides poll mode crypto driver
support for utilizing Intel multi buffer library, see the white paper
`Fast Multi-buffer IPsec Implementations on Intel® Architecture Processors
<https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-multi-buffer-ipsec-implementations-ia-processors-paper.pdf>`_.

The AES-NI MB PMD supports synchronous mode of operation with
``rte_cryptodev_sym_cpu_crypto_process`` function call.

Features
--------

AESNI MB PMD has support for:

Cipher algorithms:

* RTE_CRYPTO_CIPHER_AES128_CBC
* RTE_CRYPTO_CIPHER_AES192_CBC
* RTE_CRYPTO_CIPHER_AES256_CBC
* RTE_CRYPTO_CIPHER_AES128_CTR
* RTE_CRYPTO_CIPHER_AES192_CTR
* RTE_CRYPTO_CIPHER_AES256_CTR
* RTE_CRYPTO_CIPHER_AES_DOCSISBPI
* RTE_CRYPTO_CIPHER_DES_CBC
* RTE_CRYPTO_CIPHER_3DES_CBC
* RTE_CRYPTO_CIPHER_DES_DOCSISBPI
* RTE_CRYPTO_CIPHER_AES128_ECB
* RTE_CRYPTO_CIPHER_AES192_ECB
* RTE_CRYPTO_CIPHER_AES256_ECB
* RTE_CRYPTO_CIPHER_ZUC_EEA3
* RTE_CRYPTO_CIPHER_SNOW3G_UEA2
* RTE_CRYPTO_CIPHER_KASUMI_F8
* RTE_CRYPTO_CIPHER_SM4_CBC
* RTE_CRYPTO_CIPHER_SM4_ECB
* RTE_CRYPTO_CIPHER_SM4_CTR

Hash algorithms:

* RTE_CRYPTO_AUTH_MD5_HMAC
* RTE_CRYPTO_AUTH_SHA1_HMAC
* RTE_CRYPTO_AUTH_SHA224_HMAC
* RTE_CRYPTO_AUTH_SHA256_HMAC
* RTE_CRYPTO_AUTH_SHA384_HMAC
* RTE_CRYPTO_AUTH_SHA512_HMAC
* RTE_CRYPTO_AUTH_AES_XCBC_HMAC
* RTE_CRYPTO_AUTH_AES_CMAC
* RTE_CRYPTO_AUTH_AES_GMAC
* RTE_CRYPTO_AUTH_SHA1
* RTE_CRYPTO_AUTH_SHA224
* RTE_CRYPTO_AUTH_SHA256
* RTE_CRYPTO_AUTH_SHA384
* RTE_CRYPTO_AUTH_SHA512
* RTE_CRYPTO_AUTH_ZUC_EIA3
* RTE_CRYPTO_AUTH_SNOW3G_UIA2
* RTE_CRYPTO_AUTH_KASUMI_F9
* RTE_CRYPTO_AUTH_SM3
* RTE_CRYPTO_AUTH_SM3 HMAC

AEAD algorithms:

* RTE_CRYPTO_AEAD_AES_CCM
* RTE_CRYPTO_AEAD_AES_GCM
* RTE_CRYPTO_AEAD_CHACHA20_POLY1305
* RTE_CRYPTO_AEAD_SM4_GCM

Protocol offloads:

* RTE_SECURITY_PROTOCOL_DOCSIS

Limitations
-----------

* Out-of-place is not supported for combined Crypto-CRC DOCSIS security
  protocol.
* RTE_CRYPTO_CIPHER_DES_DOCSISBPI is not supported for combined Crypto-CRC
  DOCSIS security protocol.

AESNI MB PMD selection over SNOW3G/ZUC PMDs
-------------------------------------------

This PMD supports wireless cipher suite (SNOW3G and ZUC).
On Intel processors, it is recommended to use this PMD
instead of SNOW3G and ZUC PMDs, as it enables algorithm mixing
(e.g. cipher algorithm SNOW3G-UEA2 with authentication algorithm AES-CMAC-128)
and performance over IMIX (packet size mix) traffic is significantly higher.

Installation
------------

To build DPDK with the AESNI_MB_PMD the user is required to download the multi-buffer
library from `here <https://github.com/01org/intel-ipsec-mb>`_
and compile it on their user system before building DPDK.
The latest version of the library supported by this PMD is v1.5, which
can be downloaded from `<https://github.com/01org/intel-ipsec-mb/archive/v1.5.zip>`_.

For Arm system, ARM64 port of the multi-buffer library can be downloaded from
https://gitlab.arm.com/arm-reference-solutions/ipsec-mb/-/tree/main/.
The latest version of the library supported by this PMD is tagged as SECLIB-IPSEC-2026.05.30.

.. code-block:: console

    make
    make install

The library requires NASM to be built. Depending on the library version, it might
require a minimum NASM version (e.g. v0.54 requires at least NASM 2.14).

NASM is packaged for different OS. However, on some OS the version is too old,
so a manual installation is required. In that case, NASM can be downloaded from
`NASM website <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_.
Once it is downloaded, extract it and follow these steps:

.. code-block:: console

    ./configure
    make
    make install

As a reference, the following table shows a mapping between the past DPDK versions
and the Multi-Buffer library version supported by them:

.. table:: DPDK and Multi-Buffer library version compatibility

   ==============  ============================
   DPDK version    Multi-buffer library version
   ==============  ============================
   20.11 - 21.08   0.53 - 1.3
   21.11 - 24.07   1.0  - 1.5
   24.11+          1.4+
   ==============  ============================

Initialization
--------------

In order to enable this virtual crypto PMD, user must:

* Build the multi buffer library (explained in Installation section).

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_aesni_mb") within the application.

* Use --vdev="crypto_aesni_mb" in the EAL options, which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

* socket_id: Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

* max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).

* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).

Example:

.. code-block:: console

    ./dpdk-l2fwd-crypto -l 1 --vdev="crypto_aesni_mb,socket_id=0,max_nb_sessions=128" \
    -- -p 1 --cdev SW --chain CIPHER_HASH --cipher_algo "aes-cbc" --auth_algo "sha1-hmac"

Extra notes
-----------

For AES Counter mode (AES-CTR), the library supports two different sizes for Initialization
Vector (IV):

* 12 bytes: used mainly for IPsec, as it requires 12 bytes from the user, which internally
  are appended the counter block (4 bytes), which is set to 1 for the first block
  (no padding required from the user)

* 16 bytes: when passing 16 bytes, the library will take them and use the last 4 bytes
  as the initial counter block for the first block.

---

### Doc Guides Cryptodevs Armv8 (`doc/guides/cryptodevs/armv8.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2017 Cavium, Inc

ARMv8 Crypto Poll Mode Driver
=============================

This code provides the initial implementation of the ARMv8 crypto PMD.
The driver uses ARMv8 cryptographic extensions to process chained crypto
operations in an optimized way. The core functionality is provided by
a low-level library, written in the assembly code.

Features
--------

ARMv8 Crypto PMD has support for the following algorithm pairs:

Supported cipher algorithms:

* ``RTE_CRYPTO_CIPHER_AES_CBC``

Supported authentication algorithms:

* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``

Installation
------------

To build DPDK with this virtual crypto PMD, the user is required to:

* Download AArch64 crypto library source code from
  `here <https://github.com/ARM-software/AArch64cryptolib>`_.

* Build the ``AArch64cryptolib`` library:

.. code-block:: console

   make

* Add path to `libAArch64crypto.pc` in `PKG_CONFIG_PATH` environment variable:

.. code-block:: console

   export PKG_CONFIG_PATH=<path_to_AArch64cryptolib>/pkgconfig/:$PKG_CONFIG_PATH

* Build DPDK:

.. code-block:: console

   meson setup build
   ninja -C build

The corresponding device can be created only if the following features
are supported by the CPU:

* ``RTE_CPUFLAG_AES``
* ``RTE_CPUFLAG_SHA1``
* ``RTE_CPUFLAG_SHA2``
* ``RTE_CPUFLAG_NEON``

Initialization
--------------

Use ``--vdev "crypto_armv8"`` in the EAL options to create virtual crypto device.

User can use app/test application to check how to use this PMD and to verify
crypto processing.

Test name is cryptodev_sw_armv8_autotest.

Limitations
-----------

* Maximum number of sessions is 2048.
* Only chained operations are supported.
* AES-128-CBC is the only supported cipher variant.
* Cipher input data has to be a multiple of 16 bytes.
* Digest input data has to be a multiple of 8 bytes.

---

### Doc Guides Cryptodevs Bcmfs (`doc/guides/cryptodevs/bcmfs.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(C) 2020 Broadcom

Broadcom FlexSparc Crypto Poll Mode Driver
==========================================

The FlexSparc crypto poll mode driver (BCMFS PMD) provides support for offloading
cryptographic operations to the Broadcom SoCs having FlexSparc4 unit.
Detailed information about SoCs can be found at `Broadcom Official Website
<https://www.broadcom.com/products/ethernet-connectivity/network-adapters/smartnic>`__.

Supported Broadcom SoCs
-----------------------

* Stingray

Features
--------

The BCMFS PMD has support for below symmetric algorithms:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_3DES_CTR``
* ``RTE_CRYPTO_CIPHER_AES128_CBC``
* ``RTE_CRYPTO_CIPHER_AES192_CBC``
* ``RTE_CRYPTO_CIPHER_AES256_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CTR``
* ``RTE_CRYPTO_CIPHER_AES192_CTR``
* ``RTE_CRYPTO_CIPHER_AES256_CTR``
* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_DES_CBC``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_AES_XCBC_MAC``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_AES_GMAC``
* ``RTE_CRYPTO_AUTH_AES_CMAC``

Supported AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

Installation
------------
Information about kernel, rootfs and toolchain can be found at
`Broadcom Official Website <https://www.broadcom.com/products/ethernet-connectivity
/network-adapters/smartnic/stingray-software>`__.

The BCMFS PMD may be compiled natively on a Stingray platform or
cross-compiled on an x86 platform. For example, below commands can be executed
for cross compiling on x86 platform.

.. code-block:: console

    cd <DPDK-source-directory>
    meson setup <dest-dir> --cross-file config/arm/arm64_stingray_linux_gcc
    cd <dest-dir>
    ninja

Initialization
--------------
The supported platform devices should be present in the
*/sys/bus/platform/devices/fs<version>/<dev_name>* path on the booted kernel.
To get BCMFS PMD executing, device node must be owned by VFIO platform module only.
For example, below commands can be run to get hold of a device node by VFIO.

.. code-block:: console

    SETUP_SYSFS_DEV_NAME=67000000.crypto_mbox
    io_device_name="vfio-platform"
    echo $io_device_name > /sys/bus/platform/devices/${SETUP_SYSFS_DEV_NAME}/driver_override
    echo ${SETUP_SYSFS_DEV_NAME} > /sys/bus/platform/drivers_probe

Limitations
-----------

* The session-oriented APIs are supported but the session-less APIs are not.
* CCM is not supported.

Testing
-------

The symmetric crypto operations on BCMFS PMD may be verified by running the test
application:

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_bcmfs_autotest

---

### Doc Guides Cryptodevs Caam Jr (`doc/guides/cryptodevs/caam_jr.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018 NXP


NXP CAAM JOB RING (caam_jr)
===========================

The caam_jr PMD provides poll mode crypto driver support for NXP SEC 4.x+ (CAAM)
hardware accelerator. More information is available at:

`NXP Cryptographic Acceleration Technology  <https://www.nxp.com/applications/solutions/internet-of-things/secure-things/network-security-technology/cryptographic-acceleration-technology:NETWORK_SECURITY_CRYPTOG>`_.

Architecture
------------

SEC is the SOC's security engine, which serves as NXP's latest cryptographic
acceleration and offloading hardware. It combines functions previously
implemented in separate modules to create a modular and scalable acceleration
and assurance engine. It also implements block encryption algorithms, stream
cipher algorithms, hashing algorithms, public key algorithms, run-time
integrity checking, and a hardware random number generator. SEC performs
higher-level cryptographic operations than previous NXP cryptographic
accelerators. This provides significant improvement to system level performance.

SEC HW accelerator above 4.x+ version are also known as CAAM.

caam_jr PMD is one of DPAA drivers which uses UIO interface to interact with
Linux kernel for configure and destroy the device instance (ring).


Implementation
--------------

SEC provides platform assurance by working with SecMon, which is a companion
logic block that tracks the security state of the SOC. SEC is programmed by
means of descriptors (not to be confused with frame descriptors (FDs)) that
indicate the operations to be performed and link to the message and
associated data. SEC incorporates two DMA engines to fetch the descriptors,
read the message data, and write the results of the operations. The DMA
engine provides a scatter/gather capability so that SEC can read and write
data scattered in memory. SEC may be configured by means of software for
dynamic changes in byte ordering. The default configuration for this version
of SEC is little-endian mode.

Note that one physical Job Ring represent one caam_jr device.

Features
--------

The CAAM_JR PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CBC``
* ``RTE_CRYPTO_CIPHER_AES192_CBC``
* ``RTE_CRYPTO_CIPHER_AES256_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CTR``
* ``RTE_CRYPTO_CIPHER_AES192_CTR``
* ``RTE_CRYPTO_CIPHER_AES256_CTR``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

Supported DPAA SoCs
-------------------

* LS1046A/LS1026A
* LS1043A/LS1023A
* LS1028A
* LS1012A

Limitations
-----------

* Hash followed by Cipher mode is not supported
* Only supports the session-oriented API implementation (session-less APIs are not supported).

Prerequisites
-------------

caam_jr driver has following dependencies are not part of DPDK and must be installed separately:

* **NXP Linux SDK**

  NXP Linux software development kit (SDK) includes support for the family
  of QorIQ® ARM-Architecture-based system on chip (SoC) processors
  and corresponding boards.

  It includes the Linux board support packages (BSPs) for NXP SoCs,
  a fully operational tool chain, kernel and board specific modules.

  SDK and related information can be obtained from:  `NXP QorIQ SDK  <http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX>`_.

Currently supported by DPDK:

* NXP SDK **18.09+**.
* Supported architectures:  **arm64 LE**.

* Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.


Enabling logs
-------------

For enabling logs, use the following EAL parameter:

.. code-block:: console

   ./your_crypto_application <EAL args> --log-level=pmd.crypto.caam,<level>

---

### Doc Guides Cryptodevs Ccp (`doc/guides/cryptodevs/ccp.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.

AMD CCP Poll Mode Driver
========================

This code provides the initial implementation of the ccp poll mode driver.
The CCP poll mode driver library (**librte_crypto_ccp**) implements support for
AMD’s cryptographic co-processor (CCP). The CCP PMD is a virtual crypto
poll mode driver which schedules crypto operations to one or more available
CCP hardware engines on the platform. The CCP PMD provides poll mode crypto
driver support for the following hardware accelerator devices::

	AMD Cryptographic Co-processor (0x1456)
	AMD Cryptographic Co-processor (0x1468)

Features
--------

CCP crypto PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_ECB``
* ``RTE_CRYPTO_CIPHER_AES_CTR``
* ``RTE_CRYPTO_CIPHER_3DES_CBC``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_AES_CMAC``
* ``RTE_CRYPTO_AUTH_SHA3_224``
* ``RTE_CRYPTO_AUTH_SHA3_224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_256``
* ``RTE_CRYPTO_AUTH_SHA3_256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_384``
* ``RTE_CRYPTO_AUTH_SHA3_384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_512``
* ``RTE_CRYPTO_AUTH_SHA3_512_HMAC``

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

Installation
------------

To compile ccp PMD, openssl packages have to be installed in the build
environment.

For Ubuntu 16.04 LTS use below to install openssl in the build system:

.. code-block:: console

	sudo apt-get install openssl

This code was verified on Ubuntu 16.04.

Initialization
--------------

Bind the CCP devices to ``vfio_pci`` or ``igb_uio`` (see :ref:`linux_gsg_binding_kernel`)
before running the CCP PMD stack.

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_ccp") within the application.

* Use --vdev="crypto_ccp" in the EAL options, which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

* socket_id: Specify the socket where the memory for the device is going to be allocated.
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

* max_nb_queue_pairs: Specify the maximum number of queue pairs in the device.

* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).

* ccp_auth_opt: Specify authentication operations to perform on CPU using openssl APIs.

To validate ccp PMD, l2fwd-crypto example can be used with following command:

.. code-block:: console

        sudo ./<build_dir>/examples/dpdk-l2fwd-crypto -l 1 --vdev "crypto_ccp" -- -p 0x1
        --chain CIPHER_HASH --cipher_op ENCRYPT --cipher_algo aes-cbc
        --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f
        --cipher_iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff
        --auth_op GENERATE --auth_algo sha1-hmac
        --auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
        :11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
        :11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11

The CCP PMD also supports computing authentication over CPU with cipher offloaded to CCP.
To enable this feature, pass an additional argument as ccp_auth_opt=1 to --vdev parameters as
following:

.. code-block:: console

        sudo ./<build_dir>/examples/dpdk-l2fwd-crypto -l 1 --vdev "crypto_ccp,ccp_auth_opt=1" -- -p 0x1
        --chain CIPHER_HASH --cipher_op ENCRYPT --cipher_algo aes-cbc
        --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f
        --cipher_iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff
        --auth_op GENERATE --auth_algo sha1-hmac
        --auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
        :11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
        :11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11

Limitations
-----------

* Chained mbufs are not supported.
* MD5_HMAC is supported only for CPU based authentication.

---

### Doc Guides Cryptodevs Cnxk (`doc/guides/cryptodevs/cnxk.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2021 Marvell.

Marvell cnxk Crypto Poll Mode Driver
====================================

The cnxk crypto poll mode driver provides support for offloading
cryptographic operations to cryptographic accelerator units on the
**Marvell OCTEON cnxk** SoC family.

The cnxk crypto PMD code is organized into different sets of files.
The file names starting with cn9k, cn10k and cn20k provides support
for CN9XX, CN10XX and CN20XX respectively.
The common code between the SoCs is present in file names starting with cnxk.

More information about OCTEON cnxk SoCs may be obtained from `<https://www.marvell.com>`_

Supported OCTEON cnxk SoCs
--------------------------

- CN9XX
- CN10XX
- CN20XX

Features
--------

The OCTEON cnxk crypto PMD has support for:

Symmetric Crypto Algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_NULL``
* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_3DES_ECB``
* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_CTR``
* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_DES_CBC``
* ``RTE_CRYPTO_CIPHER_KASUMI_F8``
* ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
* ``RTE_CRYPTO_CIPHER_ZUC_EEA3``
* ``RTE_CRYPTO_CIPHER_SM4``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_NULL``
* ``RTE_CRYPTO_AUTH_AES_GMAC``
* ``RTE_CRYPTO_AUTH_KASUMI_F9``
* ``RTE_CRYPTO_AUTH_MD5``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_224``
* ``RTE_CRYPTO_AUTH_SHA3_224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_256``
* ``RTE_CRYPTO_AUTH_SHA3_256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_384``
* ``RTE_CRYPTO_AUTH_SHA3_384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_512``
* ``RTE_CRYPTO_AUTH_SHA3_512_HMAC``
* ``RTE_CRYPTO_AUTH_SHAKE_128``
* ``RTE_CRYPTO_AUTH_SHAKE_256``
* ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
* ``RTE_CRYPTO_AUTH_ZUC_EIA3``
* ``RTE_CRYPTO_AUTH_AES_CMAC``
* ``RTE_CRYPTO_AUTH_SM3``

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``
* ``RTE_CRYPTO_AEAD_AES_CCM``
* ``RTE_CRYPTO_AEAD_CHACHA20_POLY1305``

Asymmetric Crypto Algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* ``RTE_CRYPTO_ASYM_XFORM_RSA``
* ``RTE_CRYPTO_ASYM_XFORM_MODEX``

Installation
------------

The OCTEON cnxk crypto PMD may be compiled natively on an OCTEON cnxk platform
or cross-compiled on an x86 platform.

Refer to :doc:`/platform/cnxk` for instructions to build your DPDK
application.

.. note::

   The OCTEON cnxk crypto PMD uses services from the kernel mode OCTEON cnxk
   crypto PF driver in linux. This driver is included in the OCTEON TX SDK.

Initialization
--------------

``CN9K Initialization``

List the CPT PF devices available on cn9k platform:

.. code-block:: console

    lspci -d:a0fd

``a0fd`` is the CPT PF device id. You should see output similar to:

.. code-block:: console

    0002:10:00.0 Class 1080: Device 177d:a0fd

Set ``sriov_numvfs`` on the CPT PF device, to create a VF:

.. code-block:: console

    echo 1 > /sys/bus/pci/devices/0002:10:00.0/sriov_numvfs

Bind the CPT VF device to the vfio_pci driver:

.. code-block:: console

    cd <dpdk directory>
    ./usertools/dpdk-devbind.py -u 0002:10:00.1
    ./usertools/dpdk-devbind.py -b vfio-pci 0002:10.00.1

.. note::

    * For CN98xx SoC, it is recommended to use even and odd DBDF VFs to achieve
      higher performance as even VF uses one crypto engine and odd one uses
      another crypto engine.

    * Ensure that sufficient huge pages are available for your application::

         dpdk-hugepages.py --setup 4G --pagesize 512M

      Refer to :ref:`linux_gsg_hugepages` for more details.

``CN10K/CN20K Initialization``

List the CPT PF devices available on cn10k platform:

.. code-block:: console

    lspci -d:a0f2

``a0f2`` is the CPT PF device id. You should see output similar to:

.. code-block:: console

    0002:20:00.0 Class 1080: Device 177d:a0f2

Set ``sriov_numvfs`` on the CPT PF device, to create a VF:

.. code-block:: console

    echo 1 > /sys/bus/pci/devices/0002:20:00.0/sriov_numvfs

Bind the CPT VF device to the vfio_pci driver:

.. code-block:: console

    cd <dpdk directory>
    ./usertools/dpdk-devbind.py -u 0002:20:00.1
    ./usertools/dpdk-devbind.py -b vfio-pci 0002:20:00.1

Runtime Config Options
----------------------

- ``Maximum queue pairs limit`` (default ``63``)

   The number of maximum queue pairs supported by the device, can be limited
   during runtime by using ``max_qps_limit`` ``devargs`` parameter.

   For example::

      -a 0002:20:00.1,max_qps_limit=4

   With the above configuration, the number of maximum queue pairs supported
   by the device is limited to 4.

- ``QP ID for Rx injection in case of fallback mechanism`` (default ``60``)

   QP ID for Rx injection in fallback mechanism of security.
   Can be configured during runtime by using ``rx_inject_qp`` devargs parameter.

   For example::

      -a 0002:20:00.1,rx_inject_qp=20

   With the above configuration, QP 20 will be used by the device for Rx injection
   in security in fallback mechanism scenario.

- ``Context ilen value`` (default ``0``)

  Initial context fetch length value for CPT context.

  For example::

      -a 0002:20:00.1,ctx_ilen=4

  With the above configuration, CPT initial context fetch size
  will be set to ``4+1`` 128 bytes blocks.

Debugging Options
-----------------

.. table:: OCTEON cnxk crypto PMD debug options

    +---+------------+-------------------------------------------------------+
    | # | Component  | EAL log command                                       |
    +===+============+=======================================================+
    | 1 | CPT        | --log-level='pmd\.common\.cnxk\.crypto,8'             |
    +---+------------+-------------------------------------------------------+

Testing
-------

The symmetric crypto operations on OCTEON cnxk crypto PMD may be verified by
running the test application:

``CN9K``

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_cn9k_autotest

``CN10K``

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_cn10k_autotest

``CN20K``

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_cn20k_autotest

The asymmetric crypto operations on OCTEON cnxk crypto PMD may be verified by
running the test application:

``CN9K``

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_cn9k_asym_autotest

``CN10K``

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_cn10k_asym_autotest

``CN20K``

.. code-block:: console

    ./dpdk-test
    RTE>>cryptodev_cn20k_asym_autotest

Lookaside IPsec Support
-----------------------

The OCTEON cnxk SoCs can accelerate IPsec traffic in lookaside protocol mode,
with its **cryptographic accelerator (CPT)**. ``OCTEON cnxk crypto PMD`` implements
this as an ``RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL`` offload.

Refer to :doc:`/prog_guide/rte_security` for more details on protocol offloads.

This feature can be tested with ipsec-secgw sample application.

Supported OCTEON cnxk SoCs
~~~~~~~~~~~~~~~~~~~~~~~~~~

- CN9XX
- CN10XX
- CN20XX

CN9XX Features supported
~~~~~~~~~~~~~~~~~~~~~~~~

* IPv4
* IPv6
* ESP
* ESN
* Anti-replay
* Tunnel mode
* Transport mode(IPv4)
* UDP Encapsulation
* AH

AEAD algorithms
+++++++++++++++

* AES-128/192/256-GCM

Cipher algorithms
+++++++++++++++++

* NULL
* AES-128/192/256-CBC
* AES-128/192/256-CTR

Auth algorithms
+++++++++++++++

* SHA1-HMAC
* SHA256-128-HMAC
* SHA384-192-HMAC
* SHA512-256-HMAC
* AES-XCBC-96
* AES-GMAC

CN10XX/CN20XX Features supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* IPv4
* ESP
* ESN
* Anti-replay
* Tunnel mode
* Transport mode
* UDP Encapsulation
* AH

AEAD algorithms
+++++++++++++++

* AES-128/192/256-GCM

Cipher algorithms
+++++++++++++++++

* NULL
* AES-128/192/256-CBC
* AES-128/192/256-CTR

Auth algorithms
+++++++++++++++

* NULL
* SHA1-HMAC
* SHA256-128-HMAC
* SHA384-192-HMAC
* SHA512-256-HMAC
* AES-XCBC-96
* AES-GMAC

---

### Doc Guides Cryptodevs Dpaa2 Sec (`doc/guides/cryptodevs/dpaa2_sec.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2016 NXP



NXP DPAA2 CAAM (DPAA2_SEC)
==========================

The DPAA2_SEC PMD provides poll mode crypto driver support for NXP DPAA2 CAAM
hardware accelerator.

Architecture
------------

SEC is the SOC's security engine, which serves as NXP's latest cryptographic
acceleration and offloading hardware. It combines functions previously
implemented in separate modules to create a modular and scalable acceleration
and assurance engine. It also implements block encryption algorithms, stream
cipher algorithms, hashing algorithms, public key algorithms, run-time
integrity checking, and a hardware random number generator. SEC performs
higher-level cryptographic operations than previous NXP cryptographic
accelerators. This provides significant improvement to system level performance.

DPAA2_SEC is one of the hardware resource in DPAA2 Architecture. More information
on DPAA2 Architecture is described in :ref:`dpaa2_overview`.

DPAA2_SEC PMD is one of DPAA2 drivers which interacts with Management Complex (MC)
portal to access the hardware object - DPSECI. The MC provides access to create,
discover, connect, configure and destroy dpseci objects in DPAA2_SEC PMD.

DPAA2_SEC PMD also uses some of the other hardware resources like buffer pools,
queues, queue portals to store and to enqueue/dequeue data to the hardware SEC.

DPSECI objects are detected by PMD using a resource container called DPRC (like
in :ref:`dpaa2_overview`).

For example:

.. code-block:: console

    DPRC.1 (bus)
      |
      +--+--------+-------+-------+-------+---------+
         |        |       |       |       |         |
       DPMCP.1  DPIO.1  DPBP.1  DPNI.1  DPMAC.1  DPSECI.1
       DPMCP.2  DPIO.2          DPNI.2  DPMAC.2  DPSECI.2
       DPMCP.3

Implementation
--------------

SEC provides platform assurance by working with SecMon, which is a companion
logic block that tracks the security state of the SOC. SEC is programmed by
means of descriptors (not to be confused with frame descriptors (FDs)) that
indicate the operations to be performed and link to the message and
associated data. SEC incorporates two DMA engines to fetch the descriptors,
read the message data, and write the results of the operations. The DMA
engine provides a scatter/gather capability so that SEC can read and write
data scattered in memory. SEC may be configured by means of software for
dynamic changes in byte ordering. The default configuration for this version
of SEC is little-endian mode.

A block diagram similar to dpaa2 NIC is shown below to show where DPAA2_SEC
fits in the DPAA2 Bus model

.. code-block:: console


                                       +----------------+
                                       | DPDK DPAA2_SEC |
                                       |     PMD        |
                                       +----------------+       +------------+
                                       |  MC SEC object |.......|  Mempool   |
                    . . . . . . . . .  |   (DPSECI)     |       |  (DPBP)    |
                   .                   +---+---+--------+       +-----+------+
                  .                        ^   |                      .
                 .                         |   |<enqueue,             .
                .                          |   | dequeue>             .
               .                           |   |                      .
              .                        +---+---V----+                 .
             .      . . . . . . . . . .| DPIO driver|                 .
            .      .                   |  (DPIO)    |                 .
           .      .                    +-----+------+                 .
          .      .                     |  QBMAN     |                 .
         .      .                      |  Driver    |                 .
    +----+------+-------+              +-----+----- |                 .
    |   dpaa2 bus       |                    |                        .
    |   VFIO fslmc-bus  |....................|.........................
    |                   |                    |
    |     /bus/fslmc    |                    |
    +-------------------+                    |
                                             |
    ========================== HARDWARE =====|=======================
                                           DPIO
                                             |
                                           DPSECI---DPBP
    =========================================|========================



Features
--------

The DPAA2_SEC PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_NULL``
* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CBC``
* ``RTE_CRYPTO_CIPHER_AES192_CBC``
* ``RTE_CRYPTO_CIPHER_AES256_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CTR``
* ``RTE_CRYPTO_CIPHER_AES192_CTR``
* ``RTE_CRYPTO_CIPHER_AES256_CTR``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_NULL``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_AES_XCBC_MAC``
* ``RTE_CRYPTO_AUTH_AES_CMAC``

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

Supported DPAA2 SoCs
--------------------

* LS2160A
* LS2084A/LS2044A
* LS2088A/LS2048A
* LS1088A/LS1048A

Allowing & Blocking
-------------------

The DPAA2 SEC device can be blocked with the following:

 .. code-block:: console

    <dpdk app> <EAL args> -b "fslmc:dpseci.x" -- ...

Where x is the device object id as configured in resource container.

Limitations
-----------

* Hash followed by Cipher mode is not supported
* Only supports the session-oriented API implementation (session-less APIs are not supported).

Prerequisites
-------------

DPAA2_SEC driver has similar pre-requisites as described in :ref:`dpaa2_overview`.
The following dependencies are not part of DPDK and must be installed separately:

See :doc:`/platform/dpaa2` for setup information

- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.


Enabling logs
-------------

For enabling logs, use the following EAL parameter:

.. code-block:: console

   ./your_crypto_application <EAL args> --log-level=pmd.crypto.dpaa2:<level>

Using ``crypto.dpaa2`` as log matching criteria, all Crypto PMD logs can be
enabled which are lower than logging ``level``.

Enabling debug prints
---------------------

Use dev arg option ``drv_dump_mode=x`` to dump useful debug prints on HW sec
error. There are 3 dump modes available 0, 1 and 2. Mode 0 means no dump print
on error, mode 1 means dump HW error code and mode 2 means dump HW error code
along with other useful debugging information like session, queue, descriptor
data.
e.g. ``fslmc:dpseci.1,drv_dump_mode=1``

Enable strict ordering
----------------------

Use dev arg option ``drv_strict_order=1`` to enable strict ordering.
By default, loose ordering is set for ordered schedule type event.
e.g. ``fslmc:dpseci.1,drv_strict_order=1``

---

### Doc Guides Cryptodevs Dpaa Sec (`doc/guides/cryptodevs/dpaa_sec.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2017 NXP



NXP DPAA CAAM (DPAA_SEC)
========================

The DPAA_SEC PMD provides poll mode crypto driver support for NXP DPAA CAAM
hardware accelerator.

Architecture
------------

SEC is the SOC's security engine, which serves as NXP's latest cryptographic
acceleration and offloading hardware. It combines functions previously
implemented in separate modules to create a modular and scalable acceleration
and assurance engine. It also implements block encryption algorithms, stream
cipher algorithms, hashing algorithms, public key algorithms, run-time
integrity checking, and a hardware random number generator. SEC performs
higher-level cryptographic operations than previous NXP cryptographic
accelerators. This provides significant improvement to system level performance.

DPAA_SEC is one of the hardware resource in DPAA Architecture. More information
on DPAA Architecture is described in :ref:`dpaa_overview`.

DPAA_SEC PMD is one of DPAA drivers which interacts with QBMAN to create,
configure and destroy the device instance using queue pair with CAAM portal.

DPAA_SEC PMD also uses some of the other hardware resources like buffer pools,
queues, queue portals to store and to enqueue/dequeue data to the hardware SEC.

Implementation
--------------

SEC provides platform assurance by working with SecMon, which is a companion
logic block that tracks the security state of the SOC. SEC is programmed by
means of descriptors (not to be confused with frame descriptors (FDs)) that
indicate the operations to be performed and link to the message and
associated data. SEC incorporates two DMA engines to fetch the descriptors,
read the message data, and write the results of the operations. The DMA
engine provides a scatter/gather capability so that SEC can read and write
data scattered in memory. SEC may be configured by means of software for
dynamic changes in byte ordering. The default configuration for this version
of SEC is little-endian mode.

Features
--------

The DPAA PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CBC``
* ``RTE_CRYPTO_CIPHER_AES192_CBC``
* ``RTE_CRYPTO_CIPHER_AES256_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CTR``
* ``RTE_CRYPTO_CIPHER_AES192_CTR``
* ``RTE_CRYPTO_CIPHER_AES256_CTR``
* ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
* ``RTE_CRYPTO_CIPHER_ZUC_EEA3``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_ZUC_EIA3``

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

Supported DPAA SoCs
-------------------

* LS1046A/LS1026A
* LS1043A/LS1023A

Allowing & Blocking
-------------------

For blocking a DPAA device, following commands can be used.

 .. code-block:: console

    <dpdk app> <EAL args> -b "dpaa:dpaa_sec-X" -- ...
    e.g. "dpaa:dpaa_sec-1"

    or to disable all 4 SEC devices
    -b "dpaa:dpaa_sec-1"  -b "dpaa:dpaa_sec-2" -b "dpaa:dpaa_sec-3" -b "dpaa:dpaa_sec-4"

Limitations
-----------

* Hash followed by Cipher mode is not supported
* Only supports the session-oriented API implementation (session-less APIs are not supported).

Prerequisites
-------------

DPAA_SEC driver has similar pre-requisites as described in :ref:`dpaa_overview`.

See :doc:`/platform/dpaa` for setup information


- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.


Enabling logs
-------------

For enabling logs, use the following EAL parameter:

.. code-block:: console

   ./your_crypto_application <EAL args> --log-level=pmd.crypto.dpaa:<level>

Using ``pmd.crypto.dpaa`` as log matching criteria, all Crypto PMD logs can be
enabled which are lower than logging ``level``.

Enabling debug prints
---------------------

Use dev arg option ``drv_dump_mode=x`` to dump useful debug prints on HW sec
error. There are 3 dump modes available 0, 1 and 2. Mode 0 means no dump print
on error, mode 1 means dump HW error code and mode 2 means dump HW error code
along with other useful debugging information like session, queue, descriptor
data.
e.g. ``dpaa_bus:dpaa_sec-1,drv_dump_mode=1``

---

### Doc Guides Cryptodevs Index (`doc/guides/cryptodevs/index.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2015 - 2017 Intel Corporation.

Crypto Device Drivers
=====================


.. toctree::
    :maxdepth: 1
    :numbered:

    overview
    aesni_mb
    aesni_gcm
    armv8
    bcmfs
    caam_jr
    ccp
    cnxk
    dpaa2_sec
    dpaa_sec
    ionic
    octeontx
    openssl
    mlx5
    mvsam
    nitrox
    null
    scheduler
    snow3g
    qat
    uadk
    virtio
    zuc
    zsda

---

### Doc Guides Cryptodevs Ionic (`doc/guides/cryptodevs/ionic.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2021-2025 Advanced Micro Devices, Inc.

IONIC Crypto Driver
===================

The ionic crypto driver provides support for offloading cryptographic operations
to hardware cryptographic blocks on AMD Pensando server adapters.
It currently supports the below models:

- DSC-25 dual-port 25G Distributed Services Card
  `(pdf) <https://pensandoio.secure.force.com/DownloadFile?id=a0L4T000004IKurUAG>`__
- DSC-100 dual-port 100G Distributed Services Card
  `(pdf) <https://pensandoio.secure.force.com/DownloadFile?id=a0L4T000004IKuwUAG>`__
- DSC2-200 dual-port 200G Distributed Services Card
  `(pdf) <https://www.amd.com/content/dam/amd/en/documents/pensando-technical-docs/product-briefs/pensando-elba-product-brief.pdf>`__
- DSC3-400 dual-port 400G Distributed Services Card
  `(pdf) <https://www.amd.com/content/dam/amd/en/documents/pensando-technical-docs/product-briefs/pensando-dsc3-product-brief.pdf>`__
- Pollara 400 single-port 400G AI NIC
  `(pdf) <https://www.amd.com/content/dam/amd/en/documents/pensando-technical-docs/product-briefs/pollara-product-brief.pdf>`__

Please visit the
`AMD Pensando Networking
<https://www.amd.com/en/products/accelerators/pensando.html>`_
web site for more information.

Device Support
--------------

The ionic crypto driver currently supports
running directly on the device's embedded processors.
For help running the driver, please contact AMD Pensando support.

Limitations
-----------

- Host-side access via PCI is not yet supported
- Multiprocess applications are not yet supported
- Sessionless APIs are not yet supported

Runtime Configuration
---------------------

None

Features
--------

The ionic crypto PMD has support for:

Symmetric Crypto Algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

---

### Doc Guides Cryptodevs Mlx5 (`doc/guides/cryptodevs/mlx5.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright (c) 2021 NVIDIA Corporation & Affiliates

.. include:: <isonum.txt>

NVIDIA MLX5 Crypto Driver
=========================

The mlx5 crypto driver (``librte_crypto_mlx5``)
provides support for NVIDIA NIC and DPU device families.

Overview
--------

NVIDIA MLX5 crypto driver supports AES-XTS and AES-GCM cryption.

AES-XTS
~~~~~~~

The device can provide disk encryption services,
allowing data encryption and decryption towards a disk.
Having all encryption/decryption operations done in a single device
can reduce cost and overheads of the related FIPS certification,
as ConnectX-6 is FIPS 140-2 level-2 ready.
The encryption cipher is AES-XTS of 256/512 bit key size.

MKEY is a memory region object in the hardware,
that holds address translation information and attributes per memory area.
Its ID must be tied to addresses provided to the hardware.
The encryption operations are performed with MKEY read/write transactions,
when the MKEY is configured to perform crypto operations.

The encryption does not require text to be aligned to the AES block size (128b).

See :doc:`/platform/mlx5` guide for more design details.

AES-GCM
~~~~~~~

The supported AAD/digest/key size can be read from ``dev_info``.

In AES-GCM mode, the HW requires continuous input and output of
Additional Authenticated Data (AAD), payload, and digest (if needed).
However, the API only provides a single AAD input,
which means that in the out-of-place mode,
the AAD will be used in both input and output.
This reuse of AAD in the out-of-place mode breaks the continuous output,
which degrades the performance and introduces extra UMR WQE.
If digest is not continuous after payload will also lead to that extra UMR WQE.

To address this issue, the API provides ``min_mbuf_headroom_req`` and
``min_mbuf_tailroom_req`` in ``rte_cryptodev_info`` as a hint to the PMD.
It indicates the PMD can use the buffer before and after the mbuf payload
as AAD and digest space.
With this hint, the PMD will use the buffer before and after the mbuf payload
directly via copying AAD and digest.
However, the application must ensure that there is enough headroom and tailroom
reserved for the mbuf.
Or, for non-continuous operations, extra UMR WQE will be used.


Configuration
-------------

See the :ref:`mlx5 common configuration <mlx5_common_env>`.

A device comes out of NVIDIA factory with pre-defined import methods.
There are two possible import methods: wrapped or plaintext (valid for AES-XTS only).

In case the device is in wrapped mode, it needs to be moved to crypto operational mode.
In order to move the device to crypto operational mode, credential and KEK
(Key Encrypting Key) should be set as the first step.
The credential will be used by the software in order to perform crypto login, and the KEK is
the AES Key Wrap Algorithm (rfc3394) key that will be used for sensitive data
wrapping.
The credential and the AES-XTS keys should be provided to the hardware, as ciphertext
encrypted by the KEK.

A keytag (64 bits) should be appended to the AES-XTS keys (before wrapping),
and will be validated when the hardware attempts to access it.

When crypto engines are defined to work in wrapped import method, they come out
of the factory in Commissioning mode, and thus, cannot be used for crypto operations
yet. A dedicated tool is used for changing the mode from Commissioning to
Operational, while setting the first import_KEK and credential in plaintext.
The mlxreg dedicated tool should be used as follows:

- Set CRYPTO_OPERATIONAL register to set the device in crypto operational mode.

  The input to this tool is:

  - The first credential in plaintext, 40B.
  - The first import_KEK in plaintext: kek size 0 for 16B or 1 for 32B, kek data.

  Example::

     mlxreg -d /dev/mst/mt4123_pciconf0 --reg_name CRYPTO_OPERATIONAL --get

  The "wrapped_crypto_operational" value will be "0x00000000".
  The command to set the register should be executed only once, and all the
  values mentioned above should be specified in the same command.

  Example::

     mlxreg -d /dev/mst/mt4123_pciconf0 --reg_name CRYPTO_OPERATIONAL \
     --set "credential[0]=0x10000000, credential[1]=0x10000000, kek[0]=0x00000000"

  All values not specified will remain 0.
  "wrapped_crypto_going_to_commissioning" and  "wrapped_crypto_operational"
  should not be specified.

  All the device ports should set it in order to move to operational mode.
  For BlueField-2, BlueField-3 the internal ports in the ARM system should also be set.

- Query CRYPTO_OPERATIONAL register to make sure the device is in Operational
  mode.

  Example::

     mlxreg -d /dev/mst/mt4123_pciconf0 --reg_name CRYPTO_OPERATIONAL --get

  The "wrapped_crypto_operational" value will be "0x00000001" if the mode was
  successfully changed to operational mode.

On the other hand, in case of plaintext mode, there is no need for all the above,
DEK is passed in plaintext without keytag.

  The mlx5 crypto PMD can be verified by running the test application::
    Wrapped mode:
      dpdk-test -l 0 -n 1 -w <dev>,class=crypto,wcs_file=<file_path>
      RTE>>cryptodev_mlx5_autotest

    Plaintext mode:
      dpdk-test -l 0 -n 1 -w <dev>,class=crypto
      RTE>>cryptodev_mlx5_autotest


Driver options
--------------

Please refer to :ref:`mlx5 common options <mlx5_common_driver_options>`
for an additional list of options shared with other mlx5 drivers.

- ``algo`` parameter [int]

  - 0. AES-XTS crypto.

  - 1. AES-GCM crypto.

  Set to zero (AES-XTS) by default.

- ``wcs_file`` parameter [string] - mandatory in wrapped mode

  File path including only the wrapped credential in string format of hexadecimal
  numbers, represent 48 bytes (8 bytes IV added by the AES key wrap algorithm).
  This option is valid only for AES-XTS.

- ``import_kek_id`` parameter [int]

  The identifier of the KEK, default value is 0 represents the operational
  register import_kek..
  This option is valid only for AES-XTS.

- ``credential_id`` parameter [int]

  The identifier of the credential, default value is 0 represents the operational
  register credential.
  This option is valid only for AES-XTS.

- ``keytag`` parameter [int]

  The plaintext of the keytag appended to the AES-XTS keys, default value is 0.
  This option is valid only for AES-XTS.

- ``max_segs_num`` parameter [int]

  Maximum number of mbuf chain segments(src or dest), default value is 8.

- ``crypto_mode`` parameter [string]

  Only valid in AES-GCM mode. Will be ignored in AES-XTS mode.

  - ``full_capable``
    Use UMR WQE for inputs not as contiguous AAD/Payload/Digest.

  - ``ipsec_opt``
    Do software AAD shrink for inputs as contiguous AAD/IV/Payload/Digest.
    The PMD relies on the IPsec layout, expecting the memory to align
    with AAD/IV/Payload/Digest in a contiguous manner,
    all within a single mbuf for any given OP.
    The PMD extracts the ESP.IV bytes from the input memory
    and binds the AAD (ESP SPI and SN) to the payload during enqueue OP.
    It then restores the original memory layout in the decrypt OP.
    The ESP.IV size supported range is [0,16] bytes.
    For OOP case, the PMD will replace the bytes preceding the OP destination address
    to match the information found between the AAD pointer and the OP source address.
    User should prepare this headroom in this case.

  Set to ``full_capable`` by default.


Supported Devices
-----------------

* NVIDIA\ |reg| ConnectX\ |reg|-6 200G MCX654106A-HCAT (2x200G)
* NVIDIA\ |reg| ConnectX\ |reg|-6 Dx
* NVIDIA\ |reg| ConnectX\ |reg|-7
* NVIDIA\ |reg| ConnectX\ |reg|-9 SuperNIC
* NVIDIA\ |reg| BlueField\ |reg|-2 DPU
* NVIDIA\ |reg| BlueField\ |reg|-3 DPU/SuperNIC


Limitations
-----------

- AES-XTS keys provided in xform must include keytag and should be wrapped.
- The supported data-unit lengths are 512B and 4KB and 1MB. In case the `dataunit_len`
  is not provided in the cipher xform, the OP length is limited to the above
  values.
- AES-GCM is supported only on BlueField-3.
- AES-GCM supports only key import plaintext mode.
- AES-GCM ``ipsec_opt`` mode does not support non-contiguous AAD/Payload/Digest
  and multi-segment mode.


Prerequisites
-------------

FW Prerequisites
~~~~~~~~~~~~~~~~

- xx.31.0328 for ConnectX-6.
- xx.32.0108 for ConnectX-6 Dx and BlueField-2.
- xx.36.xxxx for ConnectX-7 and BlueField-3.
- 40.44.1036 for ConnectX-8.
- 82.47.xxxx for ConnectX-9.
- xx.37.3010 for BlueField-3 and newer for AES-GCM.

Linux Prerequisites
~~~~~~~~~~~~~~~~~~~

- NVIDIA MLNX_OFED version: **5.3**.
- Compilation can be done also with rdma-core v15+.

  See :ref:`mlx5 common prerequisites <mlx5_linux_prerequisites>` for more details.

Windows Prerequisites
~~~~~~~~~~~~~~~~~~~~~

- NVIDIA WINOF-2 version: **2.60** or higher.
  See :ref:`mlx5 common prerequisites <mlx5_windows_prerequisites>` for more details.

---

### Doc Guides Cryptodevs Mvsam (`doc/guides/cryptodevs/mvsam.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2017 Marvell International Ltd.
    Copyright(c) 2017 Semihalf.

MVSAM Crypto Poll Mode Driver
=============================

The MVSAM CRYPTO PMD (**librte_crypto_mvsam**) provides poll mode crypto driver
support by utilizing MUSDK library, which provides cryptographic operations
acceleration by using Security Acceleration Engine (EIP197) directly from
user-space with minimum overhead and high performance.

Detailed information about SoCs that use MVSAM crypto driver can be obtained here:

* https://www.marvell.com/embedded-processors/armada-70xx/
* https://www.marvell.com/embedded-processors/armada-80xx/
* https://www.marvell.com/embedded-processors/armada-3700/


Features
--------

MVSAM CRYPTO PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_NULL``
* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_CTR``
* ``RTE_CRYPTO_CIPHER_AES_ECB``
* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_3DES_CTR``
* ``RTE_CRYPTO_CIPHER_3DES_ECB``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_NULL``
* ``RTE_CRYPTO_AUTH_MD5``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_AES_GMAC``

AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``

For supported feature flags please consult :doc:`overview`.

Limitations
-----------

* Hardware only supports scenarios where ICV (digest buffer) is placed just
  after the authenticated data. Other placement will result in error.

Installation
------------

MVSAM CRYPTO PMD requires MUSDK built with EIP197 support thus following
extra option must be passed to the library configuration script:

.. code-block:: console

   --enable-sam [--enable-sam-statistics] [--enable-sam-debug]

For instructions how to build required kernel modules please refer
to `doc/musdk_get_started.txt`.

Initialization
--------------

After successfully building MVSAM CRYPTO PMD, the following modules need to be
loaded:

.. code-block:: console

   insmod musdk_cma.ko
   insmod crypto_safexcel.ko rings=0,0
   insmod mv_sam_uio.ko

The following parameters (all optional) are exported by the driver:

- ``max_nb_queue_pairs``: maximum number of queue pairs in the device (default: 8 - A8K, 4 - A7K/A3K).
- ``max_nb_sessions``: maximum number of sessions that can be created (default: 2048).
- ``socket_id``: socket on which to allocate the device resources on.

l2fwd-crypto example application can be used to verify MVSAM CRYPTO PMD
operation:

.. code-block:: console

   ./dpdk-l2fwd-crypto --vdev=eth_mvpp2,iface=eth0 --vdev=crypto_mvsam -- \
     --cipher_op ENCRYPT --cipher_algo aes-cbc \
     --cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f  \
     --auth_op GENERATE --auth_algo sha1-hmac \
     --auth_key 10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f

---

### Doc Guides Cryptodevs Nitrox (`doc/guides/cryptodevs/nitrox.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(C) 2019 Marvell International Ltd.

Marvell NITROX Crypto Poll Mode Driver
======================================

The Nitrox crypto poll mode driver provides support for offloading
cryptographic operations to the NITROX V security processor. Detailed
information about the NITROX V security processor can be obtained here:

* https://www.marvell.com/security-solutions/nitrox-security-processors/nitrox-v/

Features
--------

Nitrox crypto PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_3DES_CBC``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``

Supported AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``
* ``RTE_CRYPTO_AEAD_AES_CCM``

Limitations
-----------

* Session-less APIs are not supported.


Initialization
--------------

Nitrox crypto PMD depend on Nitrox kernel PF driver being installed on the
platform. Nitrox PF driver is required to create VF devices which will
be used by the PMD. Each VF device can enable one cryptodev PMD.

Nitrox kernel PF driver is available as part of CNN55XX-Driver SDK. The SDK
and it's installation instructions can be obtained from:
`Marvell Technical Documentation Portal <https://support.cavium.com/>`_.

---

### Doc Guides Cryptodevs Null (`doc/guides/cryptodevs/null.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2016 Intel Corporation.

Null Crypto Poll Mode Driver
============================

The Null Crypto PMD (**librte_crypto_null**) provides a crypto poll mode
driver which provides a minimal implementation for a software crypto device. As
a null device it does not modify the data in the mbuf on which the crypto
operation is to operate and it only has support for a single cipher and
authentication algorithm.

When a burst of mbufs is submitted to a Null Crypto PMD for processing then
each mbuf in the burst will be enqueued in an internal buffer for collection on
a dequeue call as long as the mbuf has a valid rte_mbuf_offload operation with
a valid rte_cryptodev_session or rte_crypto_xform chain of operations.

Features
--------

Modes:

* RTE_CRYPTO_XFORM_CIPHER ONLY
* RTE_CRYPTO_XFORM_AUTH ONLY
* RTE_CRYPTO_XFORM_CIPHER THEN RTE_CRYPTO_XFORM_AUTH
* RTE_CRYPTO_XFORM_AUTH THEN RTE_CRYPTO_XFORM_CIPHER

Cipher algorithms:

* RTE_CRYPTO_CIPHER_NULL

Authentication algorithms:

* RTE_CRYPTO_AUTH_NULL

Limitations
-----------

* Only in-place is currently supported (destination address is the same as
  source address).

Installation
------------

The Null Crypto PMD is enabled and built by default in both the Linux and
FreeBSD builds.

Initialization
--------------

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_null") within the application.

* Use --vdev="crypto_null" in the EAL options, which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

* socket_id: Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

* max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).

* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).

Example:

.. code-block:: console

    ./dpdk-l2fwd-crypto -l 1 --vdev="crypto_null,socket_id=0,max_nb_sessions=128" \
    -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "null"

---

### Doc Guides Cryptodevs Octeontx (`doc/guides/cryptodevs/octeontx.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2018 Cavium, Inc

Cavium OCTEON TX Crypto Poll Mode Driver
========================================

The OCTEON TX crypto poll mode driver provides support for offloading
cryptographic operations to cryptographic accelerator units on
**OCTEON TX** :sup:`®` family of processors (CN8XXX). The OCTEON TX crypto
poll mode driver enqueues the crypto request to this accelerator and dequeues
the response once the operation is completed.

Supported Symmetric Crypto Algorithms
-------------------------------------

Cipher Algorithms
~~~~~~~~~~~~~~~~~

* ``RTE_CRYPTO_CIPHER_NULL``
* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_3DES_ECB``
* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_CTR``
* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_DES_CBC``
* ``RTE_CRYPTO_CIPHER_KASUMI_F8``
* ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
* ``RTE_CRYPTO_CIPHER_ZUC_EEA3``

Hash Algorithms
~~~~~~~~~~~~~~~

* ``RTE_CRYPTO_AUTH_NULL``
* ``RTE_CRYPTO_AUTH_AES_GMAC``
* ``RTE_CRYPTO_AUTH_KASUMI_F9``
* ``RTE_CRYPTO_AUTH_MD5``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
* ``RTE_CRYPTO_AUTH_ZUC_EIA3``

AEAD Algorithms
~~~~~~~~~~~~~~~

* ``RTE_CRYPTO_AEAD_AES_GCM``

Supported Asymmetric Crypto Algorithms
--------------------------------------

* ``RTE_CRYPTO_ASYM_XFORM_RSA``
* ``RTE_CRYPTO_ASYM_XFORM_MODEX``


Compilation
-----------

The OCTEON TX crypto poll mode driver can be compiled either natively on
**OCTEON TX** :sup:`®` board or cross-compiled on an x86 based platform.

Refer :doc:`/platform/octeontx` for details about setting up the platform
and building DPDK applications.

.. note::

   OCTEON TX crypto PF driver needs microcode to be available at `/lib/firmware/` directory.
   Refer SDK documents for further information.

SDK and related information can be obtained from: `Cavium support site <https://support.cavium.com/>`_.

Execution
---------

The number of crypto VFs to be enabled can be controlled by setting sysfs entry,
`sriov_numvfs`, for the corresponding PF driver.

.. code-block:: console

        echo <num_vfs> > /sys/bus/pci/devices/<dev_bus_id>/sriov_numvfs

The device bus ID, `dev_bus_id`, to be used in the above step can be found out
by using dpdk-devbind.py script. The OCTEON TX crypto PF device need to be
identified and the corresponding device number can be used to tune various PF
properties.


Once the required VFs are enabled, dpdk-devbind.py script can be used to
identify the VFs. To be accessible from DPDK, VFs need to be bound to vfio-pci
driver:

.. code-block:: console

        cd <dpdk directory>
        ./usertools/dpdk-devbind.py -u <vf device no>
        ./usertools/dpdk-devbind.py -b vfio-pci <vf device no>

Appropriate huge page need to be setup in order to run the DPDK example
applications.

.. code-block:: console

   dpdk-hugepages.py --setup 4G --pagesize 512M

Example applications can now be executed with crypto operations offloaded to
OCTEON TX crypto PMD.

.. code-block:: console

        ./build/ipsec-secgw --log-level=8 -l 0-7 -- -P -p 0x3 -u 0x2 --config
        "(1,0,0),(0,0,0)" -f ep1.cfg

Testing
-------

The symmetric crypto operations on OCTEON TX crypto PMD may be verified by running the test
application:

.. code-block:: console

        ./dpdk-test
        RTE>>cryptodev_octeontx_autotest

The asymmetric crypto operations on OCTEON TX crypto PMD may be verified by running the test
application:

.. code-block:: console

        ./dpdk-test
        RTE>>cryptodev_octeontx_asym_autotest

---

### Doc Guides Cryptodevs Openssl (`doc/guides/cryptodevs/openssl.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2016 Intel Corporation.

OpenSSL Crypto Poll Mode Driver
===============================

This code provides the initial implementation of the openssl poll mode
driver. All cryptography operations are using Openssl library crypto API.
Each algorithm uses EVP interface from openssl API - which is recommended
by Openssl maintainers.

For more details about openssl library please visit openssl webpage:
https://www.openssl.org/

Features
--------

OpenSSL PMD has support for:

Supported cipher algorithms:

* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_CTR``
* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_3DES_CTR``
* ``RTE_CRYPTO_CIPHER_DES_DOCSISBPI``

Supported authentication algorithms:

* ``RTE_CRYPTO_AUTH_AES_GMAC``
* ``RTE_CRYPTO_AUTH_MD5``
* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA3_224``
* ``RTE_CRYPTO_AUTH_SHA3_256``
* ``RTE_CRYPTO_AUTH_SHA3_384``
* ``RTE_CRYPTO_AUTH_SHA3_512``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_512_HMAC``
* ``RTE_CRYPTO_AUTH_SHAKE_128``
* ``RTE_CRYPTO_AUTH_SHAKE_256``

Supported AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``
* ``RTE_CRYPTO_AEAD_AES_CCM``

Supported Asymmetric Crypto algorithms:

* ``RTE_CRYPTO_ASYM_XFORM_RSA``
* ``RTE_CRYPTO_ASYM_XFORM_DSA``
* ``RTE_CRYPTO_ASYM_XFORM_DH``
* ``RTE_CRYPTO_ASYM_XFORM_MODINV``
* ``RTE_CRYPTO_ASYM_XFORM_MODEX``
* ``RTE_CRYPTO_ASYM_XFORM_SM2``


Installation
------------

To compile the OpenSSL PMD the openssl library must be installed. It will
then be picked up by the Meson/Ninja build system.

To ensure that you have the latest security fixes it is recommended that you
use the latest stable version of OpenSSL 3.x.

* OpenSSL 3.0.0 or newer: https://www.openssl.org/source/

Initialization
--------------

User can use app/test application to check how to use this PMD and to verify
crypto processing.

Test name is cryptodev_openssl_autotest.
For asymmetric crypto operations testing, run cryptodev_openssl_asym_autotest.

To verify real traffic l2fwd-crypto example can be used with this command:

.. code-block:: console

	sudo ./<build_dir>/examples/dpdk-l2fwd-crypto -l 0-1 --vdev "crypto_openssl"
	--vdev "crypto_openssl"-- -p 0x3 --chain CIPHER_HASH
	--cipher_op ENCRYPT --cipher_algo AES_CBC
	--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f
	--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff
	--auth_op GENERATE --auth_algo SHA1_HMAC
	--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
	:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
	:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11

Limitations
-----------

* Maximum number of sessions is 2048.
* Chained mbufs are supported only for source mbuf (destination must be
  contiguous).
* Hash only is not supported for GCM and GMAC.
* Cipher only is not supported for GCM and GMAC.

---

### Doc Guides Cryptodevs Overview (`doc/guides/cryptodevs/overview.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2016-2017 Intel Corporation.

Crypto Device Supported Functionality Matrices
==============================================

Supported Feature Flags
-----------------------

.. include:: overview_feature_table.txt

.. Note::

   - "In Place SGL" feature flag stands for "In place Scatter-gather list",
     which means that an input buffer can consist of multiple segments,
     being the operation in-place (input address = output address).

   - "OOP SGL In SGL Out" feature flag stands for
     "Out-of-place Scatter-gather list Input, Scatter-gather list Output",
     which means PMD supports different scatter-gather styled input and output buffers
     (i.e. both can consist of multiple segments).

   - "OOP SGL In LB Out" feature flag stands for
     "Out-of-place Scatter-gather list Input, Linear Buffers Output",
     which means PMD supports input from scatter-gather styled buffers,
     outputting linear buffers (i.e. single segment).

   - "OOP LB In SGL Out" feature flag stands for
     "Out-of-place Linear Buffers Input, Scatter-gather list Output",
     which means PMD supports input from linear buffer, outputting
     scatter-gather styled buffers.

   - "OOP LB In LB Out" feature flag stands for
     "Out-of-place Linear Buffers Input, Linear Buffers Output",
     which means that Out-of-place operation is supported,
     with linear input and output buffers.

   - "RSA PRIV OP KEY EXP" feature flag means PMD support RSA private key
     operation (Sign and Decrypt) using exponent key type only.

   - "RSA PRIV OP KEY QT" feature flag means PMD support RSA private key
     operation (Sign and Decrypt) using quintuple (crt) type key only.

   - "Digest encrypted" feature flag means PMD support hash-cipher cases,
     where generated digest is appended to and encrypted with the data.

   - "CIPHER_MULTIPLE_DATA_UNITS" feature flag means PMD support operations
      on multiple data-units message.

   - "CIPHER_WRAPPED_KEY" feature flag means PMD support wrapped key in cipher
      xform.


Supported Cipher Algorithms
---------------------------

.. include:: overview_cipher_table.txt

Supported Authentication Algorithms
-----------------------------------

.. include:: overview_auth_table.txt

Supported AEAD Algorithms
-------------------------

.. include:: overview_aead_table.txt

Supported Asymmetric Algorithms
-------------------------------

.. include:: overview_asym_table.txt

Supported Operating Systems
---------------------------

.. include:: overview_os_table.txt

---

### Doc Guides Cryptodevs Qat (`doc/guides/cryptodevs/qat.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2015-2019 Intel Corporation.

Intel(R) QuickAssist (QAT) Crypto Poll Mode Driver
==================================================

QAT documentation consists of three parts:

* Details of the symmetric and asymmetric crypto services below.
* Details of the :doc:`compression service </compressdevs/qat_comp>`
  in the compressdev drivers section.
* Details of building the common QAT infrastructure and the PMDs to support the
  above services. See :ref:`qat_building` below.


Symmetric Crypto Service on QAT
-------------------------------

The QAT symmetric crypto PMD (hereafter referred to as `QAT SYM [PMD]`) provides
poll mode crypto driver support for the following hardware accelerator devices:

* ``Intel QuickAssist Technology DH895xCC``
* ``Intel QuickAssist Technology C62x``
* ``Intel QuickAssist Technology C3xxx``
* ``Intel QuickAssist Technology 200xx``
* ``Intel QuickAssist Technology D15xx``
* ``Intel QuickAssist Technology C4xxx``
* ``Intel QuickAssist Technology 4xxx``
* ``Intel QuickAssist Technology 300xx``
* ``Intel QuickAssist Technology 420xx``
* ``Intel QuickAssist Technology apfxx``


Features
~~~~~~~~

The QAT SYM PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_3DES_CBC``
* ``RTE_CRYPTO_CIPHER_3DES_CTR``
* ``RTE_CRYPTO_CIPHER_AES128_CBC``
* ``RTE_CRYPTO_CIPHER_AES192_CBC``
* ``RTE_CRYPTO_CIPHER_AES256_CBC``
* ``RTE_CRYPTO_CIPHER_AES128_CTR``
* ``RTE_CRYPTO_CIPHER_AES192_CTR``
* ``RTE_CRYPTO_CIPHER_AES256_CTR``
* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
* ``RTE_CRYPTO_CIPHER_NULL``
* ``RTE_CRYPTO_CIPHER_KASUMI_F8``
* ``RTE_CRYPTO_CIPHER_DES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_DOCSISBPI``
* ``RTE_CRYPTO_CIPHER_DES_DOCSISBPI``
* ``RTE_CRYPTO_CIPHER_ZUC_EEA3``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
* ``RTE_CRYPTO_AUTH_SHA3_224``
* ``RTE_CRYPTO_AUTH_SHA3_256``
* ``RTE_CRYPTO_AUTH_SHA3_384``
* ``RTE_CRYPTO_AUTH_SHA3_512``
* ``RTE_CRYPTO_AUTH_AES_XCBC_MAC``
* ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_NULL``
* ``RTE_CRYPTO_AUTH_KASUMI_F9``
* ``RTE_CRYPTO_AUTH_AES_GMAC``
* ``RTE_CRYPTO_AUTH_ZUC_EIA3``
* ``RTE_CRYPTO_AUTH_AES_CMAC``
* ``RTE_CRYPTO_AUTH_SM3``
* ``RTE_CRYPTO_AUTH_SM3_HMAC``

Supported AEAD algorithms:

* ``RTE_CRYPTO_AEAD_AES_GCM``
* ``RTE_CRYPTO_AEAD_AES_CCM``
* ``RTE_CRYPTO_AEAD_CHACHA20_POLY1305``

Protocol offloads:

* ``RTE_SECURITY_PROTOCOL_DOCSIS``

Supported Chains
~~~~~~~~~~~~~~~~

All the usual chains are supported and also some mixed chains:

.. table:: Supported hash-cipher chains for wireless digest-encrypted cases

   +------------------+-----------+-------------+----------+----------+
   | Cipher algorithm | NULL AUTH | SNOW3G UIA2 | ZUC EIA3 | AES CMAC |
   +==================+===========+=============+==========+==========+
   | NULL CIPHER      | Y         | 2&3         | 2&3      | Y        |
   +------------------+-----------+-------------+----------+----------+
   | SNOW3G UEA2      | 2&3       | 1&2&3       | 2&3      | 2&3      |
   +------------------+-----------+-------------+----------+----------+
   | ZUC EEA3         | 2&3       | 2&3         | 2&3      | 2&3      |
   +------------------+-----------+-------------+----------+----------+
   | AES CTR          | 1&2&3     | 2&3         | 2&3      | Y        |
   +------------------+-----------+-------------+----------+----------+

* The combinations marked as "Y" are supported on all QAT hardware versions.
* The combinations marked as "2&3" are supported on GEN2 and GEN3 QAT hardware only.
* The combinations marked as "1&2&3" are supported on GEN1, GEN2 and GEN3 QAT hardware only.


Limitations
~~~~~~~~~~~

* Only supports the session-oriented API implementation (session-less APIs are not supported).
* SNOW 3G (UEA2), KASUMI (F8) and ZUC (EEA3) supported only if cipher length and offset fields are byte-multiple.
* SNOW 3G (UIA2) and ZUC (EIA3) supported only if hash length and offset fields are byte-multiple.
* No BSD support as BSD QAT kernel driver not available.
* ZUC EEA3/EIA3 is not supported by dh895xcc devices
* Maximum additional authenticated data (AAD) for GCM is 240 bytes long and must be passed to the device in a buffer rounded up to the nearest block-size multiple (x16) and padded with zeros.
* Queue-pairs are thread-safe on Intel CPUs but Queues are not (that is, within a single
  queue-pair all enqueues to the TX queue must be done from one thread and all dequeues
  from the RX queue must be done from one thread, but enqueues and dequeues may be done
  in different threads.)
* A GCM limitation exists, but only in the case where there are multiple
  generations of QAT devices on a single platform.
  To optimise performance, the GCM crypto session should be initialised for the
  device generation to which the ops will be enqueued. Specifically if a GCM
  session is initialised on a GEN2 device, but then attached to an op enqueued
  to a GEN3 device, it will work but cannot take advantage of hardware
  optimisations in the GEN3 device. And if a GCM session is initialised on a
  GEN3 device, then attached to an op sent to a GEN1/GEN2 device, it will not be
  enqueued to the device and will be marked as failed. The simplest way to
  mitigate this is to use the PCI allowlist to avoid mixing devices of different
  generations in the same process if planning to use for GCM.
* The mixed algo feature on GEN2 is not supported by all kernel drivers. Check
  the notes under the Available Kernel Drivers table below for specific details.
* Out-of-place is not supported for combined Crypto-CRC DOCSIS security
  protocol.
* ``RTE_CRYPTO_CIPHER_DES_DOCSISBPI`` is not supported for combined Crypto-CRC
  DOCSIS security protocol.
* Multi-segment buffers are not supported for combined Crypto-CRC DOCSIS
  security protocol.

Extra notes on KASUMI F9
~~~~~~~~~~~~~~~~~~~~~~~~

When using KASUMI F9 authentication algorithm, the input buffer must be
constructed according to the
`3GPP KASUMI specification <http://cryptome.org/3gpp/35201-900.pdf>`_
(section 4.4, page 13). The input buffer has to have COUNT (4 bytes),
FRESH (4 bytes), MESSAGE and DIRECTION (1 bit) concatenated. After the DIRECTION
bit, a single '1' bit is appended, followed by between 0 and 7 '0' bits, so that
the total length of the buffer is multiple of 8 bits. Note that the actual
message can be any length, specified in bits.

Once this buffer is passed this way, when creating the crypto operation,
length of data to authenticate "op.sym.auth.data.length" must be the length
of all the items described above, including the padding at the end.
Also, offset of data to authenticate "op.sym.auth.data.offset"
must be such that points at the start of the COUNT bytes.

Asymmetric Crypto Service on QAT
--------------------------------

The QAT asymmetric crypto PMD (hereafter referred to as `QAT ASYM [PMD]`) provides
poll mode crypto driver support for the following hardware accelerator devices:

* ``Intel QuickAssist Technology DH895xCC``
* ``Intel QuickAssist Technology C62x``
* ``Intel QuickAssist Technology C3xxx``
* ``Intel QuickAssist Technology D15xx``
* ``Intel QuickAssist Technology C4xxx``
* ``Intel QuickAssist Technology 4xxx``
* ``Intel QuickAssist Technology 401xxx``
* ``Intel QuickAssist Technology 300xx``
* ``Intel QuickAssist Technology 420xx``

The QAT ASYM PMD has support for:

* ``RTE_CRYPTO_ASYM_XFORM_MODEX``
* ``RTE_CRYPTO_ASYM_XFORM_MODINV``
* ``RTE_CRYPTO_ASYM_XFORM_RSA``
* ``RTE_CRYPTO_ASYM_XFORM_ECDSA``
* ``RTE_CRYPTO_ASYM_XFORM_ECPM``
* ``RTE_CRYPTO_ASYM_XFORM_ECDH``
* ``RTE_CRYPTO_ASYM_XFORM_SM2``

Limitations
~~~~~~~~~~~

* Big integers longer than 4096 bits are not supported.
* Queue-pairs are thread-safe on Intel CPUs but Queues are not (that is, within a single
  queue-pair all enqueues to the TX queue must be done from one thread and all dequeues
  from the RX queue must be done from one thread, but enqueues and dequeues may be done
  in different threads.)
* RSA-2560, RSA-3584 are not supported

.. _qat_building:

Building PMDs on QAT
--------------------

A QAT device can host multiple acceleration services:

* symmetric cryptography
* data compression
* asymmetric cryptography

These services are provided to DPDK applications via PMDs which register to
implement the corresponding cryptodev and compressdev APIs. The PMDs use
common QAT driver code which manages the QAT PCI device. They also depend on a
QAT kernel driver being installed on the platform, see :ref:`qat_kernel` below.


Configuring and Building the DPDK QAT PMDs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Further information on configuring, building and installing DPDK is described
:doc:`here </linux_gsg/build_dpdk>`.

Build Configuration
~~~~~~~~~~~~~~~~~~~

These are the build configuration options affecting QAT, and their default values:

.. code-block:: console

	RTE_PMD_QAT_MAX_PCI_DEVICES=48
	RTE_PMD_QAT_COMP_IM_BUFFER_SIZE=65536

Both QAT SYM PMD and QAT ASYM PMD have an external dependency on libcrypto, so are not
built by default.

Ubuntu

.. code-block:: console

   apt install libssl-dev

RHEL

.. code-block:: console

   dnf install openssl-devel

The QAT compressdev PMD has no external dependencies, so is built by default.

The number of VFs per PF varies - see table below. If multiple QAT packages are
installed on a platform then RTE_PMD_QAT_MAX_PCI_DEVICES should be
adjusted to the number of VFs which the QAT common code will need to handle.

.. Note::

        There are separate config items (not QAT-specific) for max cryptodevs
        RTE_CRYPTO_MAX_DEVS and max compressdevs RTE_COMPRESS_MAX_DEVS,
        if necessary these should be adjusted to handle the total of QAT and other
        devices which the process will use. In particular for crypto, where each
        QAT VF may expose two crypto devices, sym and asym, it may happen that the
        number of devices will be bigger than MAX_DEVS and the process will show an error
        during PMD initialisation. To avoid this problem RTE_CRYPTO_MAX_DEVS may be
        increased or -a, allow domain:bus:devid:func option may be used.


QAT compression PMD needs intermediate buffers to support Deflate compression
with Dynamic Huffman encoding. RTE_PMD_QAT_COMP_IM_BUFFER_SIZE
specifies the size of a single buffer, the PMD will allocate a multiple of these,
plus some extra space for associated meta-data. For GEN2 devices, 20 buffers are
allocated while for GEN1 devices, 12 buffers are allocated, plus 1472 bytes overhead.

.. Note::

	If the compressed output of a Deflate operation using Dynamic Huffman
	Encoding is too big to fit in an intermediate buffer, then the
	operation will be split into smaller operations and their results will
	be merged afterwards.
	This is not possible if any checksum calculation was requested - in such
	case the code falls back to fixed compression.
	To avoid this less performant case, applications should configure
	the intermediate buffer size to be larger than the expected input data size
	(compressed output size is usually unknown, so the only option is to make
	larger than the input size).


Running QAT PMD with insecure crypto algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A few insecure crypto algorithms are deprecated from QAT drivers.
This needs to be reflected in DPDK QAT PMD.
DPDK QAT PMD has by default disabled all the insecure crypto algorithms from Gen 1, 2, 3 and 4.
A PMD devarg is used to enable the capability.

- qat_legacy_capa

To use this feature the user must set the devarg on process start as a device additional devarg::

  -a b1:01.2,qat_legacy_capa=1


Running QAT PMD with minimum threshold for burst size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If only a small number or packets can be enqueued. Each enqueue causes an expensive MMIO write.
These MMIO write occurrences can be optimised by setting any of the following parameters:

- qat_sym_enq_threshold
- qat_asym_enq_threshold
- qat_comp_enq_threshold

When any of these parameters is set rte_cryptodev_enqueue_burst function will
return 0 (thereby avoiding an MMIO) if the device is congested and number of packets
possible to enqueue is smaller.
To use this feature the user must set the parameter on process start as a device additional parameter::

  -a 03:01.1,qat_sym_enq_threshold=32,qat_comp_enq_threshold=16

All parameters can be used with the same device regardless of order. Parameters are separated
by comma. When the same parameter is used more than once first occurrence of the parameter
is used.
Maximum threshold that can be set is 32.


Running QAT PMD with Cipher-CRC offload feature
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Support has been added to the QAT symmetric crypto PMD for combined Cipher-CRC offload,
primarily for the Crypto-CRC DOCSIS security protocol, on GEN2/GEN3/GEN4 QAT devices.

The following devarg enables a Cipher-CRC offload capability check to determine
if the feature is supported on the QAT device.

- qat_sym_cipher_crc_enable

When enabled, a capability check for the combined Cipher-CRC offload feature is triggered
to the QAT firmware during queue pair initialization. If supported by the firmware,
any subsequent runtime Crypto-CRC DOCSIS security protocol requests handled by the QAT PMD
are offloaded to the QAT device by setting up the content descriptor and request accordingly.
If not supported, the CRC is calculated by the QAT PMD using the NET CRC API.

To use this feature the user must set the devarg on process start as a device additional devarg::

 -a 03:01.1,qat_sym_cipher_crc_enable=1


Running QAT PMD with Intel IPsec MB library
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The QAT PMD requires IPsec MB library
for HMAC partial hash calculation in symmetric precomputes function.
OpenSSL 3.0+ removed the low-level ``SHA*_Transform`` API
that were previously used for HMAC precomputes.

**On x86 platforms:**

* Intel IPsec MB library (v1.4.0+) is required for HMAC precomputes.
* OpenSSL (3.0+) is optional for DOCSIS BPI cipher fallback.

**On ARM platforms:**

* ARM IPsec MB library from ``gitlab.arm.com/arm-reference-solutions/ipsec-mb``
  is required for HMAC precomputes.
* OpenSSL (3.0+) is required for DOCSIS BPI cipher algorithms.
  ARM IPsec MB does not implement CFB-one-byte cipher modes needed for DOCSIS.
  Without OpenSSL, DOCSIS algorithms will not be available on ARM.


Device and driver naming
~~~~~~~~~~~~~~~~~~~~~~~~

* The qat cryptodev symmetric crypto driver name is "crypto_qat".
* The qat cryptodev asymmetric crypto driver name is "crypto_qat_asym".

The "rte_cryptodev_devices_get()" returns the devices exposed by either of these drivers.

* Each qat sym crypto device has a unique name, in format
  "<pci bdf>_<service>", e.g. "0000:41:01.0_qat_sym".
* Each qat asym crypto device has a unique name, in format
  "<pci bdf>_<service>", e.g. "0000:41:01.0_qat_asym".
  This name can be passed to "rte_cryptodev_get_dev_id()" to get the device_id.

.. Note::

	The cryptodev driver name is passed to the dpdk-test-crypto-perf tool in the "-devtype" parameter.

	The qat crypto device name is in the format of the worker parameter passed to the crypto scheduler.

* The qat compressdev driver name is "compress_qat".
  The rte_compressdev_devices_get() returns the devices exposed by this driver.

* Each qat compression device has a unique name, in format
  <pci bdf>_<service>, e.g. "0000:41:01.0_qat_comp".
  This name can be passed to rte_compressdev_get_dev_id() to get the device_id.


Running QAT on Aarch64 based Ampere Altra platform
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Requires Linux kernel v6.0+.
See also `this kernel patch <https://lkml.org/lkml/2022/6/17/328>`_.


.. _qat_kernel:

Dependency on the QAT kernel driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To use QAT an SRIOV-enabled QAT kernel driver is required. The VF
devices created and initialised by this driver will be used by the QAT PMDs.

Instructions for installation are below, but first an explanation of the
relationships between the PF/VF devices and the PMDs visible to
DPDK applications.

Each QuickAssist PF device exposes a number of VF devices. Each VF device can
enable one symmetric cryptodev PMD and/or one asymmetric cryptodev PMD and/or
one compressdev PMD.
These QAT PMDs share the same underlying device and pci-mgmt code, but are
enumerated independently on their respective APIs and appear as independent
devices to applications.

.. Note::

   Each VF can only be used by one DPDK process. It is not possible to share
   the same VF across multiple processes, even if these processes are using
   different acceleration services.

   Conversely one DPDK process can use one or more QAT VFs and can expose both
   cryptodev and compressdev instances on each of those VFs.


Available kernel drivers
~~~~~~~~~~~~~~~~~~~~~~~~

Kernel drivers for each device for each service are listed in the following table. (Scroll right
to see the full table)

.. table:: QAT device generations, devices and drivers

   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | S   | A   | C   | Gen | Device   | Driver/ver    | Kernel Module | Pci Driver | PF Did | #PFs | VF Did | VFs/PF |
   +=====+=====+=====+=====+==========+===============+===============+============+========+======+========+========+
   | Yes | No  | No  | 1   | DH895xCC | linux/4.4+    | qat_dh895xcc  | dh895xcc   | 435    | 1    | 443    | 32     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | No  | "   | "        | IDZ/4.12.0+   | "             | "          | "      | "    | "      | "      |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | "   | "        | IDZ/4.13.0+   | "             | "          | "      | "    | "      | "      |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 2   | C62x     | linux/4.5+    | qat_c62x      | c6xx       | 37c8   | 3    | 37c9   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | "   | "        | IDZ/4.12.0+   | "             | "          | "      | "    | "      | "      |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 2   | C3xxx    | linux/4.5+    | qat_c3xxx     | c3xxx      | 19e2   | 1    | 19e3   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | "   | "        | IDZ/4.12.0+   | "             | "          | "      | "    | "      | "      |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 2   | 200xx    | p             | qat_200xx     | 200xx      | 18ee   | 1    | 18ef   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 2   | D15xx    | p             | qat_d15xx     | d15xx      | 6f54   | 1    | 6f55   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | No  | 3   | C4xxx    | p             | qat_c4xxx     | c4xxx      | 18a0   | 1    | 18a1   | 128    |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | No  | 4   | 4xxx     | linux/5.11+   | qat_4xxx      | 4xxx       | 4940   | 4    | 4941   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | 4   | 4xxx     | linux/5.17+   | qat_4xxx      | 4xxx       | 4940   | 4    | 4941   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 4   | 4xxx     | IDZ/ N/A      | qat_4xxx      | 4xxx       | 4940   | 4    | 4941   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | 4   | 401xxx   | linux/5.19+   | qat_4xxx      | 4xxx       | 4942   | 2    | 4943   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 4   | 401xxx   | IDZ/ N/A      | qat_4xxx      | 4xxx       | 4942   | 2    | 4943   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | 4   | 402xx    | linux/6.4+    | qat_4xxx      | 4xxx       | 4944   | 2    | 4945   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | No  | No  | 4   | 402xx    | IDZ/ N/A      | qat_4xxx      | 4xxx       | 4944   | 2    | 4945   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+
   | Yes | Yes | Yes | 5   | 420xx    | linux/6.8+    | qat_420xx     | 420xx      | 4946   | 2    | 4947   | 16     |
   +-----+-----+-----+-----+----------+---------------+---------------+------------+--------+------+--------+--------+

* Note: Symmetric mixed crypto algorithms feature on Gen 2 works only with IDZ driver version 4.9.0+

The first 3 columns indicate the service:

* S = Symmetric crypto service (via cryptodev API)
* A = Asymmetric crypto service  (via cryptodev API)
* C = Compression service (via compressdev API)

The ``Driver`` column indicates either the Linux kernel version in which
support for this device was introduced or a driver available on Intel Developer Zone (IDZ).
There are both linux in-tree and IDZ kernel drivers available for some
devices. p = release pending.

If you are running on a kernel which includes a driver for your device, see
`Installation using kernel.org driver`_ below. Otherwise see
`Installation using IDZ QAT driver`_.

.. note::

   The asymmetric service is not supported by DPDK QAT PMD for the Gen 3 platform.
   The actual crypto services enabled on the system depend
   on QAT driver capabilities and hardware slice configuration.

.. note::

   With the introduction of QAT Generation 4,
   the in-tree drivers are available within the mainline Linux kernel.
   Out-of-tree (OOT) drivers for QAT Gen 4 are currently in sustaining mode,
   meaning they will only receive maintenance updates without new feature development.
   Future generations of QAT will be supported with in-tree drivers exclusively.

.. note::

   For **in-tree drivers**, when multiple QAT instances are available,
   each instance is assigned a different crypto service by default (asym;sym or dc).
   The available crypto queue pair request will return zero
   if the corresponding service is not enabled.

   To verify the device configuration, run::

      cat /sys/bus/pci/devices/<BDF>/qat/cfg_services

   For symmetric and asymmetric crypto services, ensure that `"asym;sym"` are enabled.

   For **out-of-tree drivers**, the configuration file for each instance can be found at::

      /etc/<GEN>_dev<ID>.conf


Installation using kernel.org driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The examples below are based on the C62x device, if you have a different device
use the corresponding values in the above table.

In BIOS ensure that SRIOV is enabled and either:

* Disable VT-d or
* Enable VT-d and set ``"intel_iommu=on iommu=pt"`` in the grub file.

Check that the QAT driver is loaded on your system, by executing::

    lsmod | grep qa

You should see the kernel module for your device listed, e.g.::

    qat_c62x               5626  0
    intel_qat              82336  1 qat_c62x

Next, you need to expose the Virtual Functions (VFs) using the sysfs file system.

First find the BDFs (Bus-Device-Function) of the physical functions (PFs) of
your device, e.g.::

    lspci -d:37c8

You should see output similar to::

    1a:00.0 Co-processor: Intel Corporation Device 37c8
    3d:00.0 Co-processor: Intel Corporation Device 37c8
    3f:00.0 Co-processor: Intel Corporation Device 37c8

Enable the VFs for each PF by echoing the number of VFs per PF to the pci driver::

     echo 16 > /sys/bus/pci/drivers/c6xx/0000:1a:00.0/sriov_numvfs
     echo 16 > /sys/bus/pci/drivers/c6xx/0000:3d:00.0/sriov_numvfs
     echo 16 > /sys/bus/pci/drivers/c6xx/0000:3f:00.0/sriov_numvfs

Check that the VFs are available for use. For example ``lspci -d:37c9`` should
list 48 VF devices available for a ``C62x`` device.

To complete the installation follow the instructions in
`Binding the available VFs to the vfio-pci driver`_.

.. Note::

   If the QAT kernel modules are not loaded and you see an error like ``Failed
   to load MMP firmware qat_895xcc_mmp.bin`` in kernel logs, this may be as a
   result of not using a distribution, but just updating the kernel directly.

   Download firmware from the `kernel firmware repo
   <http://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/>`_.

   Copy qat binaries to ``/lib/firmware``::

      cp qat_895xcc.bin /lib/firmware
      cp qat_895xcc_mmp.bin /lib/firmware

   Change to your linux source root directory and start the qat kernel modules::

      insmod ./drivers/crypto/qat/qat_common/intel_qat.ko
      insmod ./drivers/crypto/qat/qat_dh895xcc/qat_dh895xcc.ko

.. Note::

   If you see the following warning in ``/var/log/messages`` it can be ignored:
   ``IOMMU should be enabled for SR-IOV to work correctly``.


Installation using IDZ QAT driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Download the latest QuickAssist Technology Driver from `Intel Developer Zone
<https://developer.intel.com/quickassist>`_.
Consult the *Quick Start Guide* at the same URL for further information.

The steps below assume you are:

* Building on a platform with one ``C62x`` device.
* Using package ``qat1.7.l.4.2.0-000xx.tar.gz``.
* On Fedora26 kernel ``4.11.11-300.fc26.x86_64``.

In the BIOS ensure that SRIOV is enabled and VT-d is disabled.

Uninstall any existing QAT driver, for example by running:

* ``./installer.sh uninstall`` in the directory where originally installed.


Build and install the SRIOV-enabled QAT driver::

    mkdir /QAT
    cd /QAT

    # Copy the package to this location and unpack
    tar zxof qat1.7.l.4.2.0-000xx.tar.gz

    ./configure --enable-icp-sriov=host
    make install

You can use ``cat /sys/kernel/debug/qat<your device type and bdf>/version/fw`` to confirm the driver is correctly installed and is using firmware version 4.2.0.
You can use ``lspci -d:37c9`` to confirm the presence of the 16 VF devices available per ``C62x`` PF.

Confirm the driver is correctly installed and is using firmware version 4.2.0::

    cat /sys/kernel/debug/qat<your device type and bdf>/version/fw


Confirm the presence of 48 VF devices - 16 per PF::

    lspci -d:37c9


To complete the installation - follow instructions in
`Binding the available VFs to the vfio-pci driver`_.

.. Note::

   If using a later kernel and the build fails with an error relating to
   ``strict_stroul`` not being available apply the following patch:

   .. code-block:: diff

      /QAT/QAT1.6/quickassist/utilities/downloader/Target_CoreLibs/uclo/include/linux/uclo_platform.h
      + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,5)
      + #define STR_TO_64(str, base, num, endPtr) {endPtr=NULL; if (kstrtoul((str), (base), (num))) printk("Error strtoull convert %s\n", str); }
      + #else
      #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
      #define STR_TO_64(str, base, num, endPtr) {endPtr=NULL; if (strict_strtoull((str), (base), (num))) printk("Error strtoull convert %s\n", str); }
      #else
      #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
      #define STR_TO_64(str, base, num, endPtr) {endPtr=NULL; strict_strtoll((str), (base), (num));}
      #else
      #define STR_TO_64(str, base, num, endPtr)                                 \
           do {                                                               \
                 if (str[0] == '-')                                           \
                 {                                                            \
                      *(num) = -(simple_strtoull((str+1), &(endPtr), (base))); \
                 }else {                                                      \
                      *(num) = simple_strtoull((str), &(endPtr), (base));      \
                 }                                                            \
           } while(0)
      + #endif
      #endif
      #endif


.. Note::

   If the build fails due to missing header files you may need to do following::

      sudo yum install zlib-devel
      sudo yum install openssl-devel
      sudo yum install libudev-devel

.. Note::

   If the build or install fails due to mismatching kernel sources you may need to do the following::

      sudo yum install kernel-headers-`uname -r`
      sudo yum install kernel-src-`uname -r`
      sudo yum install kernel-devel-`uname -r`

.. Note::

   If the build fails on newer GCC versions (such as GCC 12) with an error relating to
   ``-lc`` not being found, apply the following patch:

   .. code-block:: diff

      /QAT/quickassist/lookaside/access_layer/src/Makefile
      cd $(ICP_FINAL_OUTPUT_DIR);\
      cmd="$(LINKER) $(LIB_SHARED_FLAGS) -o \
        $(LIB_SHARED) $(ADDITIONAL_OBJECTS) $(ADDITIONAL_LIBS) *.o -lpthread -ludev \
      - -Bstatic -L$(ADF_DIR)/src/build/$(ICP_OS)/$(ICP_OS_LEVEL) \
      - -ladf_user -L$(OSAL_DIR)/src/build/$(ICP_OS)/$(ICP_OS_LEVEL)/ \
      - -losal -Bdynamic -lc"; \
      + -Bstatic -L$(ADF_DIR)/src/build/$(ICP_OS)/$(ICP_OS_LEVEL) \
      + -ladf_user -L$(OSAL_DIR)/src/build/$(ICP_OS)/$(ICP_OS_LEVEL)/ \
      + -losal -Bdynamic -L/lib/x86_64-linux-gnu/ -lc"; \
      echo "$$cmd"; \
      $$cmd

   Followed by this patch:

   .. code-block:: diff

      /QAT/quickassist/build_system/build_files/OS/linux_common_user_space_rules.mk
      @echo 'Creating shared library ${LIB_SHARED}'; \
      cd $($(PROG_ACY)_FINAL_OUTPUT_DIR);\
      -  echo $(LINKER) $(LIB_SHARED_FLAGS) -o $@  $(OBJECTS) $(ADDITIONAL_OBJECTS) -lc;\
      -  $(LINKER) $(LIB_SHARED_FLAGS) -o $@  $(OBJECTS) $(ADDITIONAL_OBJECTS) -lc ;
      +  echo $(LINKER) $(LIB_SHARED_FLAGS) -o $@  $(OBJECTS) $(ADDITIONAL_OBJECTS) \
      +  -L/lib/x86_64-linux-gnu/ -lc;\
      +  $(LINKER) $(LIB_SHARED_FLAGS) -o $@  $(OBJECTS) $(ADDITIONAL_OBJECTS) \
      +  -L/lib/x86_64-linux-gnu/ -lc ;


Binding the available VFs to the vfio-pci driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note:

* Please note that due to security issues, the usage of older DPDK igb_uio
  driver is not recommended. This document shows how to use the more secure
  vfio-pci driver.
* If QAT fails to bind to vfio-pci on Linux kernel 5.9+, please see the
  QATE-39220 and QATE-7495 issues in
  `IDZ doc <https://cdrdv2.intel.com/v1/dl/getContent/710057?explicitVersion=true>`_
  which details the constraint about trusted guests and add `disable_denylist=1`
  to the vfio-pci params to use QAT. See also `this patch description <https://lkml.org/lkml/2020/7/23/1155>`_.

Unbind the VFs from the stock driver so they can be bound to the vfio-pci driver.

For an Intel(R) QuickAssist Technology DH895xCC device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The unbind command below assumes ``BDFs`` of ``03:01.00-03:04.07``, if your
VFs are different adjust the unbind command below::

    cd to the top-level DPDK directory
    for device in $(seq 1 4); do \
        for fn in $(seq 0 7); do \
            usertools/dpdk-devbind.py -u 0000:03:0${device}.${fn}; \
        done; \
    done

For an Intel(R) QuickAssist Technology C62x device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The unbind command below assumes ``BDFs`` of ``1a:01.00-1a:02.07``,
``3d:01.00-3d:02.07`` and ``3f:01.00-3f:02.07``, if your VFs are different
adjust the unbind command below::

    cd to the top-level DPDK directory
    for device in $(seq 1 2); do \
        for fn in $(seq 0 7); do \
            usertools/dpdk-devbind.py -u 0000:1a:0${device}.${fn}; \
            usertools/dpdk-devbind.py -u 0000:3d:0${device}.${fn}; \
            usertools/dpdk-devbind.py -u 0000:3f:0${device}.${fn}; \
        done; \
    done

For Intel(R) QuickAssist Technology C3xxx or 200xx or D15xx device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The unbind command below assumes ``BDFs`` of ``01:01.00-01:02.07``, if your
VFs are different adjust the unbind command below::

    cd to the top-level DPDK directory
    for device in $(seq 1 2); do \
        for fn in $(seq 0 7); do \
            usertools/dpdk-devbind.py -u 0000:01:0${device}.${fn}; \
        done; \
    done

Bind to the vfio-pci driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Load the vfio-pci driver, bind the VF PCI Device id to it using the
``dpdk-devbind.py`` script then use the ``--status`` option
to confirm the VF devices are now in use by vfio-pci kernel driver,
e.g. for the C62x device::

    cd to the top-level DPDK directory
    modprobe vfio-pci
    usertools/dpdk-devbind.py -b vfio-pci 0000:03:01.1
    usertools/dpdk-devbind.py --status

Use ``modprobe vfio-pci disable_denylist=1`` from kernel 5.9 onwards.
See note in the section `Binding the available VFs to the vfio-pci driver`_
above.

Testing
~~~~~~~

QAT SYM crypto PMD can be tested by running the test application::

    cd ./<build_dir>/app/test
    ./dpdk-test -l1 -n1 -a <your qat bdf>
    RTE>>cryptodev_qat_autotest

QAT ASYM crypto PMD can be tested by running the test application::

    cd ./<build_dir>/app/test
    ./dpdk-test -l1 -n1 -a <your qat bdf>
    RTE>>cryptodev_qat_asym_autotest

QAT compression PMD can be tested by running the test application::

    cd ./<build_dir>/app/test
    ./dpdk-test -l1 -n1 -a <your qat bdf>
    RTE>>compressdev_autotest


Debugging
~~~~~~~~~

There are 2 sets of trace available via the dynamic logging feature:

* pmd.qat.dp exposes trace on the data-path.
* pmd.qat.general exposes all other trace.

pmd.qat exposes both sets of traces.
They can be enabled using the log-level option (where 8=maximum log level) on
the process cmdline, e.g. using any of the following::

    --log-level="pmd.qat.general,8"
    --log-level="pmd.qat.dp,8"
    --log-level="pmd.qat,8"

.. Note::

    The global RTE_LOG_DP_LEVEL overrides data-path trace so must be set to
    RTE_LOG_DEBUG to see all the trace. This variable is in config/rte_config.h
    for meson build.
    Also the dynamic global log level overrides both sets of trace, so e.g. no
    QAT trace would display in this case::

	--log-level="7" --log-level="pmd.qat.general,8"

---

### Doc Guides Cryptodevs Scheduler (`doc/guides/cryptodevs/scheduler.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2017 Intel Corporation.

Cryptodev Scheduler Poll Mode Driver Library
============================================

Scheduler PMD is a software crypto PMD, which has the capabilities of
attaching hardware and/or software cryptodevs, and distributes ingress
crypto ops among them in a certain manner.

.. figure:: img/scheduler-overview.*

   Cryptodev Scheduler Overview


The Cryptodev Scheduler PMD library (**librte_crypto_scheduler**) acts as
a software crypto PMD and shares the same API provided by librte_cryptodev.
The PMD supports attaching multiple crypto PMDs, software or hardware, as
workers, and distributes the crypto workload to them with certain behavior.
The behaviors are categorizes as different "modes". Basically, a scheduling
mode defines certain actions for scheduling crypto ops to its workers.

The librte_crypto_scheduler library exports a C API which provides an API
for attaching/detaching workers, set/get scheduling modes, and enable/disable
crypto ops reordering.

Limitations
-----------

* Sessionless crypto operation is not supported
* OOP crypto operation is not supported when the crypto op reordering feature
  is enabled.


Initialization
--------------

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_scheduler") within the application.

* Use --vdev="crypto_scheduler" in the EAL options, which will call
  rte_vdev_init() internally.


The following parameters (all optional) can be provided in the previous
two calls:

* socket_id: Specify the socket where the memory for the device is going
  to be allocated (by default, socket_id will be the socket where the core
  that is creating the PMD is running on).

* max_nb_sessions: Specify the maximum number of sessions that can be
  created. This value may be overwritten internally if there are too
  many devices are attached.

* worker: If a cryptodev has been initialized with specific name, it can be
  attached to the scheduler using this parameter, simply filling the name
  here. Multiple cryptodevs can be attached initially by presenting this
  parameter multiple times.

* mode: Specify the scheduling mode of the PMD. The supported scheduling
  mode parameter values are specified in the "Cryptodev Scheduler Modes
  Overview" section.

* mode_param: Specify the mode-specific parameter. Some scheduling modes
  may be initialized with specific parameters other than the default ones,
  such as the **threshold** packet size of **packet-size-distr** mode. This
  parameter fulfills the purpose.

* ordering: Specify the status of the crypto operations ordering feature.
  The value of this parameter can be "enable" or "disable". This feature
  is disabled by default.

Example:

.. code-block:: console

    ... --vdev "crypto_aesni_mb0,name=aesni_mb_1" --vdev "crypto_aesni_mb1,name=aesni_mb_2" --vdev "crypto_scheduler,worker=aesni_mb_1,worker=aesni_mb_2" ...

.. note::

    * The scheduler cryptodev cannot be started unless the scheduling mode
      is set and at least one worker is attached. Also, to configure the
      scheduler in the run-time, like attach/detach worker(s), change
      scheduling mode, or enable/disable crypto op ordering, one should stop
      the scheduler first, otherwise an error will be returned.

    * The crypto op reordering feature requires using the userdata field of
      every mbuf to be processed to store temporary data. By the end of
      processing, the field is set to pointing to NULL, any previously
      stored value of this field will be lost.


Cryptodev Scheduler Modes Overview
----------------------------------

Currently the Crypto Scheduler PMD library supports following modes of
operation:

*   **CDEV_SCHED_MODE_ROUNDROBIN:**

   *Initialization mode parameter*: **round-robin**

   Round-robin mode, which distributes the enqueued burst of crypto ops
   among its workers in a round-robin manner. This mode may help to fill
   the throughput gap between the physical core and the existing cryptodevs
   to increase the overall performance.

*   **CDEV_SCHED_MODE_PKT_SIZE_DISTR:**

   *Initialization mode parameter*: **packet-size-distr**

   Packet-size based distribution mode, which works with 2 workers, the primary
   worker and the secondary worker, and distributes the enqueued crypto
   operations to them based on their data lengths. A crypto operation will be
   distributed to the primary worker if its data length is equal to or bigger
   than the designated threshold, otherwise it will be handled by the secondary
   worker.

   A typical use case in this mode is with the QAT cryptodev as the primary and
   a software cryptodev as the secondary worker. This may help applications to
   process additional crypto workload than what the QAT cryptodev can handle on
   its own, by making use of the available CPU cycles to deal with smaller
   crypto workloads.

   The threshold is set to 128 bytes by default. It can be updated by calling
   function **rte_cryptodev_scheduler_option_set**. The parameter of
   **option_type** must be **CDEV_SCHED_OPTION_THRESHOLD** and **option** should
   point to a rte_cryptodev_scheduler_threshold_option structure filled with
   appropriate threshold value. Please NOTE this threshold has be a power-of-2
   unsigned integer. It is possible to use **mode_param** initialization
   parameter to achieve the same purpose. For example:

   ... --vdev "crypto_scheduler,mode=packet-size-distr,mode_param=threshold:512" ...

   The above parameter will overwrite the threshold value to 512.

*   **CDEV_SCHED_MODE_FAILOVER:**

   *Initialization mode parameter*: **fail-over**

   Fail-over mode, which works with 2 workers, the primary worker and the
   secondary worker. In this mode, the scheduler will enqueue the incoming
   crypto operation burst to the primary worker. When one or more crypto
   operations fail to be enqueued, then they will be enqueued to the secondary
   worker.

*   **CDEV_SCHED_MODE_MULTICORE:**

   *Initialization mode parameter*: **multi-core**

   Multi-core mode, which distributes the workload with several (up to eight)
   worker cores. The enqueued bursts are distributed among the worker cores in a
   round-robin manner. If scheduler cannot enqueue entire burst to the same worker,
   it will enqueue the remaining operations to the next available worker.
   For pure small packet size (64 bytes) traffic however the multi-core mode is not
   an optimal solution, as it doesn't give significant per-core performance improvement.
   For mixed traffic (IMIX) the optimal number of worker cores is around 2-3.
   For large packets (1.5 kbytes) scheduler shows linear scaling in performance
   up to eight cores.
   Each worker uses its own cryptodev. Only software cryptodevs
   are supported. Only the same type of cryptodevs should be used concurrently.

   The multi-core mode uses one extra parameter:

   * corelist: Semicolon-separated list of logical cores to be used as workers.
     The number of worker cores should be equal to the number of worker cryptodevs.
     These cores should be present in EAL core list parameter and
     should not be used by the application or any other process.

   Example:
    ... --vdev "crypto_aesni_mb1,name=aesni_mb_1" --vdev "crypto_aesni_mb_pmd2,name=aesni_mb_2" \
    --vdev "crypto_scheduler,worker=aesni_mb_1,worker=aesni_mb_2,mode=multi-core,corelist=23;24" ...

---

### Doc Guides Cryptodevs Snow3g (`doc/guides/cryptodevs/snow3g.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2016-2019 Intel Corporation.

SNOW 3G Crypto Poll Mode Driver
===============================

The SNOW3G PMD (**librte_crypto_snow3g**) provides poll mode crypto driver support for
utilizing the ARM64 port of `Intel IPsec Multi-Buffer library
<https://gitlab.arm.com/arm-reference-solutions/ipsec-mb>`_
which implements F8 and F9 functions for SNOW 3G UEA2 cipher and UIA2 hash algorithms.

Features
--------

SNOW 3G PMD has support for:

Cipher algorithm:

* RTE_CRYPTO_CIPHER_SNOW3G_UEA2

Authentication algorithm:

* RTE_CRYPTO_AUTH_SNOW3G_UIA2

.. note::

   The latest v1.3 add ARM64 port of ipsec-mb library support ARM platform.

Limitations
-----------

* Chained mbufs are not supported.
* SNOW 3G (UIA2) supported only if hash offset field is byte-aligned.
* In-place bit-level operations for SNOW 3G (UEA2) are not supported
  (if length and/or offset of data to be ciphered is not byte-aligned).

SNOW3G PMD vs AESNI MB PMD
--------------------------

On Intel processors this PMD is no longer supported, please use the AESNI MB PMD.
Take a look at the PMD documentation (:doc:`aesni_mb`) for more information.

Installation
------------

To build DPDK with the SNOW3G_PMD the user is required to download the multi-buffer
library and compile it on their user system before building DPDK.

The ARM64 port of the multi-buffer library can be downloaded from
`<https://gitlab.arm.com/arm-reference-solutions/ipsec-mb/-/tree/main/>`_.
The latest version of the library supported by this PMD is tagged as SECLIB-IPSEC-2026.05.30.

After downloading the library, the user needs to unpack and compile it
on their system before building DPDK:

.. code-block:: console

    make
    make install

The library requires NASM to be built on x86. Depending on the library version,
it might require a minimum NASM version (e.g. v0.54 requires at least NASM 2.14).

NASM is packaged for different OS. However, on some OS the version is too old,
so a manual installation is required. In that case, NASM can be downloaded from
`NASM website <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_.
Once it is downloaded, extract it and follow these steps:

.. code-block:: console

    ./configure
    make
    make install

As a reference, the following table shows a mapping between the past DPDK versions
and the external crypto libraries supported by them:

.. table:: DPDK and external crypto library version compatibility

   =============  ================================
   DPDK version   Crypto library version
   =============  ================================
   20.02 - 21.08  Multi-buffer library 0.53 - 1.3
   21.11 - 24.07  Multi-buffer library 1.0  - 1.5
   24.11+         Multi-buffer library 1.4+
   =============  ================================

Initialization
--------------

In order to enable this virtual crypto PMD, user must:

* Build the multi buffer library (explained in Installation section).

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_snow3g") within the application.

* Use --vdev="crypto_snow3g" in the EAL options, which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

* socket_id: Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

* max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).

* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).

Example:

.. code-block:: console

    ./dpdk-l2fwd-crypto -l 1 --vdev="crypto_snow3g,socket_id=0,max_nb_sessions=128" \
    -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "snow3g-uea2"

---

### Doc Guides Cryptodevs Uadk (`doc/guides/cryptodevs/uadk.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2022-2023 Huawei Technologies Co.,Ltd. All rights reserved.
   Copyright 2022-2023 Linaro ltd.

UADK Crypto Poll Mode Driver
============================

This code provides the initial implementation of the UADK poll mode driver.
All cryptographic operations are using UADK library crypto API,
which is algorithm level API, abstracting accelerators' low level implementations.

UADK crypto PMD relies on `UADK library <https://github.com/Linaro/uadk>`_.

UADK is a framework for user applications to access hardware accelerators.
UADK relies on IOMMU SVA (Shared Virtual Address) feature,
which share the same page table between IOMMU and MMU.
As a result, user application can directly use virtual address for device DMA,
which enhances the performance as well as easy usability.


Features
--------

UADK crypto PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_AES_ECB``
* ``RTE_CRYPTO_CIPHER_AES_CBC``
* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_DES_CBC``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_MD5``
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SHA512_HMAC``

Test steps
----------


#. Build UADK

   .. code-block:: console

      git clone https://github.com/Linaro/uadk.git
      cd uadk
      mkdir build
      ./autogen.sh
      ./configure --prefix=$PWD/build
      make
      make install

   .. note::

      Without ``--prefix``, UADK will be installed to ``/usr/local/lib`` by default.

   .. note::

      If get error: "cannot find -lnuma", please install the libnuma-dev.

#. Run pkg-config libwd to ensure env is setup correctly

   .. code-block:: console

      export PKG_CONFIG_PATH=$PWD/build/lib/pkgconfig
      pkg-config libwd --cflags --libs -I/usr/local/include -L/usr/local/lib -lwd

   .. note::

      export ``PKG_CONFIG_PATH`` is required on demand,
      not needed if UADK is installed to ``/usr/local/lib``.

#. Build DPDK

   .. code-block:: console

      cd dpdk
      mkdir build
      meson setup build (--reconfigure)
      cd build
      ninja
      sudo meson install

#. Prepare hugepages for DPDK (see also :doc:`/tools/hugepages`)

   .. code-block:: console

      echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
      echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
      echo 1024 > /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages
      echo 1024 > /sys/devices/system/node/node3/hugepages/hugepages-2048kB/nr_hugepages
      mkdir -p /mnt/huge_2mb
      mount -t hugetlbfs none /mnt/huge_2mb -o pagesize=2MB

#. Run test app

   .. code-block:: console

      sudo dpdk-test --vdev=crypto_uadk --log-level=6
      RTE>>cryptodev_uadk_autotest
      RTE>>quit

As a reference, the following table shows a mapping between the past DPDK versions
and the UADK library version supported by them:

.. table:: DPDK and external UADK library version compatibility

   ==============  ============================
   DPDK version    UADK library version
   ==============  ============================
   22.11 - 25.03   2.4 - 2.8
   25.07+          2.9.1
   ==============  ============================


Initialization
--------------

To use the PMD in an application, the user must:

* Call ``rte_vdev_init("crypto_uadk")`` within the application.

* Use ``--vdev="crypto_uadk"`` in the EAL options,
  which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

``max_nb_queue_pairs``
  Specify the maximum number of queue pairs in the device (8 by default).
  The maximum value can be queried from the device property ``available_instances``.
  Property ``available_instances`` value may differ from the devices and platforms.
  Allocating queue pairs bigger than ``available_instances`` will fail.

Example:

.. code-block:: console

	cat /sys/class/uacce/hisi_sec2-2/available_instances
	256

	sudo dpdk-test-crypto-perf -l 0-10 --vdev crypto_uadk,max_nb_queue_pairs=10 \
		-- --devtype crypto_uadk --optype cipher-only --buffer-sz 8192

---

### Doc Guides Cryptodevs Virtio (`doc/guides/cryptodevs/virtio.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018 HUAWEI TECHNOLOGIES CO., LTD.

Virtio Crypto Poll Mode Driver
==============================

The virtio crypto PMD provides poll mode driver support for the virtio crypto
device.

Features
--------

The virtio crypto PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_AES_CBC``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1_HMAC``

Limitations
-----------

*  Only supports the session-oriented API implementation (session-less APIs are
   not supported).
*  Only supports modern mode since virtio crypto conforms to virtio-1.0.
*  Only has two types of queues: data queue and control queue. These two queues
   only support indirect buffers to communication with the virtio backend.
*  Only supports AES_CBC cipher only algorithm and AES_CBC with HMAC_SHA1
   chaining algorithm since the vhost crypto backend only these algorithms
   are supported.
*  Does not support Link State interrupt.
*  Does not support runtime configuration.

Virtio crypto PMD Rx/Tx Callbacks
---------------------------------

Rx callbacks:

* ``virtio_crypto_pkt_rx_burst``

Tx callbacks:

* ``virtio_crypto_pkt_tx_burst``

Installation
------------

Quick instructions are as follows:

Firstly run DPDK vhost crypto sample as a server side and build QEMU with
vhost crypto enabled.
QEMU can then be started using the following parameters:

.. code-block:: console

    qemu-system-x86_64 \
    [...] \
        -chardev socket,id=charcrypto0,path=/path/to/your/socket \
        -object cryptodev-vhost-user,id=cryptodev0,chardev=charcrypto0 \
        -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0
    [...]

Secondly bind the uio_pci_generic driver for the virtio-crypto device.
For example, 0000:00:04.0 is the domain, bus, device and function
number of the virtio-crypto device:

.. code-block:: console

    modprobe uio_pci_generic
    echo -n 0000:00:04.0 > /sys/bus/pci/drivers/virtio-pci/unbind
    echo "1af4 1054" > /sys/bus/pci/drivers/uio_pci_generic/new_id

Finally the front-end virtio crypto PMD can be installed.

Tests
-----

The unit test cases can be tested as below:

.. code-block:: console

    reserve enough huge pages
    cd to <build_dir>
    meson test cryptodev_virtio_autotest

The performance can be tested as below:

.. code-block:: console

    reserve enough huge pages
    cd to <build_dir>

    ./app/dpdk-test-crypto-perf -l 0,1 -- --devtype crypto_virtio \
        --ptest throughput --optype cipher-then-auth --cipher-algo aes-cbc \
        --cipher-op encrypt --cipher-key-sz 16 --auth-algo sha1-hmac \
        --auth-op generate --auth-key-sz 64 --digest-sz 12 \
        --total-ops 100000000 --burst-sz 64 --buffer-sz 2048

---

### Doc Guides Cryptodevs Zsda (`doc/guides/cryptodevs/zsda.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2025 ZTE Corporation.

ZTE Storage Data Accelerator (ZSDA) Poll Mode Driver
====================================================

The ZSDA crypto PMD provides poll mode Cipher and Hash driver
support for the following hardware accelerator devices:

- Neo X510
- Neo X512


Features
--------

The ZSDA SYM PMD has support for:

Cipher algorithms:

* ``RTE_CRYPTO_CIPHER_AES_XTS``
* ``RTE_CRYPTO_CIPHER_SM4_XTS``

Hash algorithms:

* ``RTE_CRYPTO_AUTH_SHA1``
* ``RTE_CRYPTO_AUTH_SHA224``
* ``RTE_CRYPTO_AUTH_SHA256``
* ``RTE_CRYPTO_AUTH_SHA384``
* ``RTE_CRYPTO_AUTH_SHA512``
* ``RTE_CRYPTO_AUTH_SM3``


Limitations
-----------

* Only supports the session-oriented API implementation
  (session-less API is not supported).
* No BSD and Windows support.
* Queue-pairs are thread-safe on Intel CPUs but queues are not:
  within a single queue-pair all enqueues to the Tx queue must be done from one thread
  and all dequeues from the Rx queue must be done from one thread,
  but enqueues and dequeues may be done in different threads.


Installation
------------

The ZSDA crypto service is built by default with a standard DPDK build.


Testing
-------

ZSDA SYM crypto PMD can be tested by running the test application::

   cd ./<build_dir>/app/test
   ./dpdk-test -l1 -n1 -a <your zsda bdf>
   RTE>>cryptodev_zsda_autotest

---

### Doc Guides Cryptodevs Zuc (`doc/guides/cryptodevs/zuc.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2016-2019 Intel Corporation.

ZUC Crypto Poll Mode Driver
===========================

The ZUC PMD (**librte_crypto_zuc**) provides poll mode crypto driver support for
utilizing the ARM64 port of `Intel IPsec Multi-Buffer library
<https://gitlab.arm.com/arm-reference-solutions/ipsec-mb>`_
which implements F8 and F9 functions for ZUC EEA3 cipher and EIA3 hash algorithms.

Features
--------

ZUC PMD has support for:

Cipher algorithm:

* RTE_CRYPTO_CIPHER_ZUC_EEA3

Authentication algorithm:

* RTE_CRYPTO_AUTH_ZUC_EIA3

.. note::

   The latest v1.3 add ARM64 port of ipsec-mb library support ARM platform.

Limitations
-----------

* Chained mbufs are not supported.
* ZUC (EIA3) supported only if hash offset field is byte-aligned.
* ZUC (EEA3) supported only if cipher length, cipher offset fields are byte-aligned.

ZUC PMD vs AESNI MB PMD
-----------------------

On Intel processors this PMD is no longer supported, please use the AESNI MB PMD.
Take a look at the PMD documentation (:doc:`aesni_mb`) for more information.

Installation
------------

To build DPDK with the ZUC_PMD the user is required to download the multi-buffer
library and compile it on their user system before building DPDK.

The ARM64 port of the multi-buffer library can be downloaded from
`<https://gitlab.arm.com/arm-reference-solutions/ipsec-mb/-/tree/main/>`_.
The latest version of the library supported by this PMD is tagged as SECLIB-IPSEC-2026.05.30.

After downloading the library, the user needs to unpack and compile it
on their system before building DPDK:

.. code-block:: console

    make
    make install

The library requires NASM to be built on x86. Depending on the library version,
it might require a minimum NASM version (e.g. v0.54 requires at least NASM 2.14).

NASM is packaged for different OS. However, on some OS the version is too old,
so a manual installation is required. In that case, NASM can be downloaded from
`NASM website <https://www.nasm.us/pub/nasm/releasebuilds/?C=M;O=D>`_.
Once it is downloaded, extract it and follow these steps:

.. code-block:: console

    ./configure
    make
    make install

As a reference, the following table shows a mapping between the past DPDK versions
and the external crypto libraries supported by them:

.. table:: DPDK and external crypto library version compatibility

   =============  ================================
   DPDK version   Crypto library version
   =============  ================================
   20.02 - 21.08  Multi-buffer library 0.53 - 1.3
   21.11 - 24.07  Multi-buffer library 1.0  - 1.5
   24.11+         Multi-buffer library 1.4+
   =============  ================================

Initialization
--------------

In order to enable this virtual crypto PMD, user must:

* Build the multi buffer library (explained in Installation section).

To use the PMD in an application, user must:

* Call rte_vdev_init("crypto_zuc") within the application.

* Use --vdev="crypto_zuc" in the EAL options, which will call rte_vdev_init() internally.

The following parameters (all optional) can be provided in the previous two calls:

* socket_id: Specify the socket where the memory for the device is going to be allocated
  (by default, socket_id will be the socket where the core that is creating the PMD is running on).

* max_nb_queue_pairs: Specify the maximum number of queue pairs in the device (8 by default).

* max_nb_sessions: Specify the maximum number of sessions that can be created (2048 by default).

Example:

.. code-block:: console

    ./dpdk-l2fwd-crypto -l 1 --vdev="crypto_zuc,socket_id=0,max_nb_sessions=128" \
    -- -p 1 --cdev SW --chain CIPHER_ONLY --cipher_algo "zuc-eea3"

---

### Doc Guides Dmadevs Ae4dma (`doc/guides/dmadevs/ae4dma.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2026 Advanced Micro Devices, Inc.

.. include:: <isonum.txt>

AMD AE4DMA DMA Device Driver
============================

The ``ae4dma`` dmadev driver is a poll-mode driver (PMD) for the AMD AE4DMA hardware DMA engine.
The engine exposes 16 independent hardware command queues, each with a ring of 32 descriptors.
The PMD maps each hardware command queue to a separate DPDK dmadev with a single virtual channel,
so a single PCI function appears as 16 dmadevs named ``<pci-bdf>-ch0`` through ``<pci-bdf>-ch15``.

The driver supports memory-to-memory copy operations only.

Hardware Requirements
---------------------

The ``dpdk-devbind.py`` script can be used to list AE4DMA devices on the system::

   $ dpdk-devbind.py --status-dev dma

AE4DMA devices appear with vendor ID ``0x1022`` and device ID ``0x149b``.

Compilation
-----------

The driver is built as part of the standard DPDK build on x86 platforms using ``meson``
and ``ninja``; no extra configuration is required.

Device Setup
------------

The AE4DMA device must be bound to a DPDK-compatible kernel module such as ``vfio-pci``
before it can be used::

   $ dpdk-devbind.py -b vfio-pci <pci-bdf>

Initialization
~~~~~~~~~~~~~~

On probe the PMD performs the following steps for each PCI function:

* Reads BAR0 and programs the common configuration register
  with the number of hardware queues to enable (16).
* For each hardware queue it allocates a 32-entry descriptor ring in IOVA-contiguous memory,
  programs the queue base address and ring depth into the per-queue registers,
  and enables the queue.
* Interrupts are masked; completion is polled by the application.

Usage
-----

Once a dmadev has been started, copies are submitted with ``rte_dma_copy()`` and
completions are reaped with ``rte_dma_completed()`` or ``rte_dma_completed_status()``.
See the :ref:`Enqueue / Dequeue API <dmadev_enqueue_dequeue>` section of
the dmadev library documentation for details.

Limitations
-----------

* Only memory-to-memory copies are supported. Fill, scatter-gather and
  any other operation types are not advertised in ``rte_dma_info::dev_capa``.
* The maximum number of descriptors per virtual channel is fixed by hardware at 32,
  and the engine reserves one slot to distinguish a full ring from an empty one,
  so at most 31 operations can be outstanding (``rte_dma_burst_capacity()`` returns at most 31).
  The PMD rounds the requested ring size up to a power of two and clamps it to 32.
* Only a single virtual channel per dmadev is supported;
  use the 16 per-PCI-function dmadevs to obtain channel-level parallelism.
* Interrupt-driven completion is not supported.

---

### Doc Guides Dmadevs Cnxk (`doc/guides/dmadevs/cnxk.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2021 Marvell International Ltd.

.. include:: <isonum.txt>

CNXK DMA Device Driver
======================

The ``cnxk`` dmadev driver provides a poll-mode driver (PMD) for Marvell DPI DMA
Hardware Accelerator block found in OCTEON 9 and OCTEON 10 family of SoCs.
Each DMA queue is exposed as a VF function when SRIOV is enabled.

The block supports following modes of DMA transfers:

#. Internal - DMA within SoC DRAM to DRAM
#. Inbound  - Host DRAM to SoC DRAM when SoC is in PCIe Endpoint
#. Outbound - SoC DRAM to Host DRAM when SoC is in PCIe Endpoint

Prerequisites and Compilation procedure
---------------------------------------

See :doc:`/platform/cnxk` for setup information.

Device Setup
------------

The ``dpdk-devbind.py`` script, included with DPDK,
can be used to show the presence of supported hardware.
Running ``dpdk-devbind.py --status-dev dma`` will show all the CNXK DMA devices.

Devices using VFIO drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~

The HW devices to be used will need to be bound to a user-space IO driver for use.
The ``dpdk-devbind.py`` script can be used to view the state of the devices
and to bind them to a suitable DPDK-supported driver, such as ``vfio-pci``.
For example::

     $ dpdk-devbind.py -b vfio-pci 0000:05:00.1

Device Probing and Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To use the devices from an application, the dmadev API can be used.
CNXK DMA device configuration requirements:

* Only one ``vchan`` is supported per device.
* CNXK DMA devices do not support silent mode.

Once configured, the device can then be made ready for use
by calling the ``rte_dma_start()`` API.

Performing Data Copies
~~~~~~~~~~~~~~~~~~~~~~

Refer to the :ref:`dmadev_enqueue_dequeue` section
of the dmadev library documentation
for details on operation enqueue and submission API usage.

Performance Tuning Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To achieve higher performance, DMA device needs to be tuned
using PF kernel driver module parameters.
The PF kernel driver is part of the OCTEON SDK.
Module parameters shall be configured during module insert as in below example::

    $ sudo insmod octeontx2_dpi.ko mps=128 mrrs=128 eng_fifo_buf=0x101008080808

``mps``

  Maximum payload size.
  MPS size shall not exceed the size selected by PCI config.
  Maximum size that shall be configured can be found
  on executing ``lspci`` command for the device.

``mrrs``

  Maximum read request size.
  MRRS size shall not exceed the size selected by PCI config.
  Maximum size that shall be configured can be found
  on executing ``lspci`` command for the device.

``eng_fifo_buf``

  CNXK supports 6 DMA engines and each engine has an associated FIFO.
  By default, all engine's FIFO is configured to 8 KB.
  Engine FIFO size can be tuned using this 64-bit variable,
  where each byte represents an engine.
  In the example above, engine 0-3 FIFO are configure as 8 KB
  and engine 4-5 are configured as 16 KB.

.. note::

   MPS and MRRS performance tuning parameters help achieve higher performance
   only for inbound and outbound DMA transfers.
   The parameter has no effect for internal only DMA transfer.

---

### Doc Guides Dmadevs Dpaa (`doc/guides/dmadevs/dpaa.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2021 NXP

NXP DPAA DMA Driver
===================

The DPAA DMA is an implementation of the dmadev APIs,
that provide means to initiate a DMA transaction from CPU.
The initiated DMA is performed without CPU being involved
in the actual DMA transaction.
This is achieved via using the QDMA controller of DPAA SoC.

The QDMA controller transfers blocks of data
between one source and one destination.
The blocks of data transferred can be represented in memory
as contiguous or noncontiguous using scatter/gather table(s).

More information can be found at `NXP Official Website
<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.

Supported DPAA SoCs
-------------------

- LS1046A
- LS1043A

Prerequisites
-------------

See :doc:`/platform/dpaa` for setup information

- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.

.. note::

   Some part of dpaa bus code (qbman and fman - library) routines are
   dual licensed (BSD & GPLv2), however they are used as BSD in DPDK in userspace.

Compilation
-----------

For builds using ``meson`` and ``ninja``, the driver will be built when the
target platform is dpaa-based. No additional compilation steps are necessary.

``RTE_DMA_DPAA_ERRATA_ERR050757``
  Enable software workaround for Errata-A050757
``RTE_DMA_DPAA_ERRATA_ERR050265``
  Enable software workaround for Errata-A050265

Initialization
--------------

On EAL initialization, DPAA DMA devices will be detected on DPAA bus and
will be probed and populated into their device list.

Features
--------

The DPAA DMA implements following features in the dmadev API:

- Supports 1 virtual channel.
- Supports all 4 DMA transfers: MEM_TO_MEM, MEM_TO_DEV,
  DEV_TO_MEM, DEV_TO_DEV.
- Supports DMA silent mode.
- Supports issuing DMA of data within memory without hogging CPU while
  performing DMA operation.
- Supports statistics.

Platform Requirement
--------------------

DPAA DMA driver for DPDK can only work on NXP SoCs
as listed in the `Supported DPAA SoCs`_.

Device Arguments
----------------

``dpaa_dma_err_check=1``
  Check DMA errors at driver level.
  Usage example: ``dpaa_bus:dpaa_qdma-1,dpaa_dma_err_check=1``

---

### Doc Guides Dmadevs Dpaa2 (`doc/guides/dmadevs/dpaa2.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2018-2022 NXP

NXP DPAA2 QDMA Driver
=====================

The DPAA2 QDMA is an implementation of the dmadev API, that provide means
to initiate a DMA transaction from CPU. The initiated DMA is performed
without CPU being involved in the actual DMA transaction. This is achieved
via using the DPDMAI device exposed by MC.

More information can be found at `NXP Official Website
<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.

Features
--------

The DPAA2 QDMA implements following features in the dmadev API;

- Supports issuing DMA of data within memory without hogging CPU while
  performing DMA operation.
- Supports configuring to optionally get status of the DMA translation on
  per DMA operation basis.
- Supports statistics.

Supported DPAA2 SoCs
--------------------

- LX2160A
- LS2084A/LS2044A
- LS2088A/LS2048A
- LS1088A/LS1048A

Prerequisites
-------------

See :doc:`/platform/dpaa2` for setup information

- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.

.. note::

   Some part of fslmc bus code (mc flib - object library) routines are
   dual licensed (BSD & GPLv2).


Enabling logs
-------------

For enabling logs, use the following EAL parameter:

.. code-block:: console

   ./your_qdma_application <EAL args> --log-level=pmd.dma.dpaa2.qdma,<level>

Using ``pmd.dma.dpaa2.qdma`` as log matching criteria, all Event PMD logs can be
enabled which are lower than logging ``level``.


Initialization
--------------

The DPAA2 QDMA is exposed as a dma device which consists of dpdmai devices.
On EAL initialization, dpdmai devices will be probed and populated into the
dmadevices. The dmadev ID of the device can be obtained using

* Invoking ``rte_dma_get_dev_id_by_name("dpdmai.x")`` from the application
  where x is the object ID of the DPDMAI object created by MC. Use can
  use this index for further rawdev function calls.

Platform Requirement
~~~~~~~~~~~~~~~~~~~~

DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
``Supported DPAA2 SoCs``.

Device Arguments
----------------

``fle_pre_populate=1``
  Pre-populate all DMA descriptors with pre-initialized values.
  Usage example: ``fslmc:dpdmai.1,fle_pre_populate=1``

``desc_debug=1``
  Enable descriptor debugs.
  Usage example: ``fslmc:dpdmai.1,desc_debug=1``

``short_fd=1``
  Enable short FDs.
  Usage example: ``fslmc:dpdmai.1,short_fd=1``

---

### Doc Guides Dmadevs Hisi Acc (`doc/guides/dmadevs/hisi_acc.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved.

HiSilicon Accelerator DMA Driver
================================

Kunpeng SoC Accelerator subsystem supports zip function,
the zip also supports data copy and fill.
This driver exposes this capability to DPDK applications.


Supported Kunpeng SoCs
----------------------

* Kunpeng 920


Device Setup
------------

In order to use the device in DPDK, user should
insmod `uacce.ko`, `hisi_qm.ko`
and `hisi_zip.ko` (with module parameter ``uacce_mode=1``),
then there will be several subdirectories
whose names start with ``hisi_zip`` in ``/sys/class/uacce/`` directory.

Device Probing and Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

User should use following method to probe device::

   dpdk-app -a uacce:hisi_zip-0,queues=2 ...

``hisi_zip-0`` is the directory name in the ``/sys/class/uacce/`` directory,
queues is runtime config parameter which indicates how many dmadevs are created.

If the probe is successful, two dmadevs are created,
named ``hisi_zip-0-dma0`` and ``hisi_zip-0-dma1``.

.. note::

   In the ``/sys/class/uacce/hisi_zip-x/`` directory,
   user could query API and algorithms,
   this driver can only match the device whose API is ``hisi_qm_v5``
   and algorithms contain ``udma``.

Device Configuration
~~~~~~~~~~~~~~~~~~~~

Configuration requirements:

* ``ring_size`` obtained from UACCE API and is a fixed value.
* Only one ``vchan`` is supported per ``dmadev``.
* Silent mode is not supported.
* The transfer direction must be set to ``RTE_DMA_DIR_MEM_TO_MEM``.


Device Datapath Capability and Limitation
-----------------------------------------

Support memory copy and fill operations.

.. note::

   Currently, the maximum size of the operation data is limited to 16MB-1B in the driver.
   The device actually supports operations in a larger data size,
   but the driver requires complex operations in the datapth.
   If you have such requirement, please contact the maintainers.

---

### Doc Guides Dmadevs Hisi Pciep (`doc/guides/dmadevs/hisi_pciep.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2021 HiSilicon Limited.

HISILICON PCIEP DMA Driver
==========================

Kunpeng SoC PCIe subsystem has an internal DMA unit
which can be used by application to accelerate data copies.
The DMA PF function supports multiple DMA channels.


Supported Kunpeng SoCs
----------------------

* Kunpeng 920


Device Setup
------------

This device needs to be bound to a suitable DPDK-supported user-space IO
driver such as ``vfio-pci`` in order to be used by DPDK.

Device Probing and Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Once probed successfully, the device will appear as four ``dmadev``
which can be accessed using API from the ``rte_dmadev`` library.

The name of the ``dmadev`` created is like "B:D.F-chX", e.g. DMA 0000:7b:00.0
will create four ``dmadev``,
the 1st ``dmadev`` name is "0000:7b:00.0-ch0",
and the 2nd ``dmadev`` name is "0000:7b:00.0-ch1".

Device Configuration
~~~~~~~~~~~~~~~~~~~~

Configuration requirements:

* ``ring_size`` must be a power of two, between 32 and 8192.
* Only one ``vchan`` is supported per ``dmadev``.
* Silent mode is not supported.
* The transfer direction must be set to ``RTE_DMA_DIR_MEM_TO_MEM``.

---

### Doc Guides Dmadevs Idxd (`doc/guides/dmadevs/idxd.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2021 Intel Corporation.

.. include:: <isonum.txt>

IDXD DMA Device Driver
======================

The ``idxd`` dmadev driver provides a poll-mode driver (PMD) for Intel\ |reg|
Data Streaming Accelerator `(Intel DSA)
<https://software.intel.com/content/www/us/en/develop/articles/intel-data-streaming-accelerator-architecture-specification.html>`_.
This PMD can be used in conjunction with Intel\ |reg| DSA devices to offload
data operations, such as data copies, to hardware, freeing up CPU cycles for
other tasks.

Hardware Requirements
---------------------

The ``dpdk-devbind.py`` script, included with DPDK, can be used to show the
presence of supported hardware. Running ``dpdk-devbind.py --status-dev dma``
will show all the DMA devices on the system, including IDXD supported devices.
Intel\ |reg| DSA devices, are currently (at time of writing) appearing
as devices with type “0b25”, due to the absence of pci-id database entries for
them at this point.

Compilation
-----------

For builds using ``meson`` and ``ninja``, the driver will be built when the
target platform is x86-based. No additional compilation steps are necessary.

Device Setup
------------

Intel\ |reg| DSA devices can use the IDXD kernel driver or DPDK-supported drivers,
such as ``vfio-pci``. Both are supported by the IDXD PMD.

.. note::

   To use Intel\ |reg| DSA devices in DPDK multi-process applications,
   the devices should be bound to the vfio-pci driver.
   Multi-process is not supported when using the kernel IDXD driver.

Intel\ |reg| DSA devices using IDXD kernel driver
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To use an Intel\ |reg| DSA device bound to the IDXD kernel driver, the device must first be configured.
The `accel-config <https://github.com/intel/idxd-config>`_ utility library can be used for configuration.

.. note::
        The device configuration can also be done by directly interacting with the sysfs nodes.
        An example of how this may be done can be seen in the script ``dpdk_idxd_cfg.py``
        included in the driver source directory.

There are some mandatory configuration steps before being able to use a device with an application.
The internal engines, which do the copies or other operations,
and the work-queues, which are used by applications to assign work to the device,
need to be assigned to groups, and the various other configuration options,
such as priority or queue depth, need to be set for each queue.
Furthermore, to mark a work-queue for use by DPDK,
so it will be picked up in device scans,
the queue must be assigned a name starting with either ``dpdk_``
or the DPDK application's ``file-prefix`` parameter (default ``rte_``).

To assign an engine to a group::

        $ accel-config config-engine dsa0/engine0.0 --group-id=0

To assign work queues to groups for passing descriptors to the engines a similar accel-config command can be used.
However, the work queues also need to be configured depending on the use case.
Some configuration options include:

* mode (Dedicated/Shared): Indicates whether a WQ may accept jobs from multiple queues simultaneously.
* priority: WQ priority between 1 and 15. Larger value means higher priority.
* wq-size: the size of the WQ. Sum of all WQ sizes must be less that the total-size defined by the device.
* type: WQ type (kernel/mdev/user). Determines how the device is presented.
* name: identifier given to the WQ.
  For DPDK to automatically find and use the queue as a DMA device,
  the queue must be assigned a name starting with either ``dpdk_``
  or the DPDK application's ``file-prefix`` parameter (default ``rte_``).

Example configuration for a work queue::

        $ accel-config config-wq dsa0/wq0.0 --group-id=0 \
           --mode=dedicated --priority=10 --wq-size=8 \
           --max-batch-size=512 --type=user --name=dpdk_app1

Once the devices have been configured, they need to be enabled::

        $ accel-config enable-device dsa0
        $ accel-config enable-wq dsa0/wq0.0

Check the device configuration::

        $ accel-config list

Every Intel\ |reg| DSA instance supports multiple queues and each should be similarly configured.
As a further example, the following set of commands will configure and enable 4 queues on instance 0,
giving each an equal share of resources::

        # configure 4 groups, each with one engine
        accel-config config-engine dsa0/engine0.0 --group-id=0
        accel-config config-engine dsa0/engine0.1 --group-id=1
        accel-config config-engine dsa0/engine0.2 --group-id=2
        accel-config config-engine dsa0/engine0.3 --group-id=3

        # configure 4 queues, putting each in a different group, so each
        # is backed by a single engine
        accel-config config-wq dsa0/wq0.0 --group-id=0 --type=user --wq-size=32 \
            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
        accel-config config-wq dsa0/wq0.1 --group-id=1 --type=user --wq-size=32 \
            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
        accel-config config-wq dsa0/wq0.2 --group-id=2 --type=user --wq-size=32 \
            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
        accel-config config-wq dsa0/wq0.3 --group-id=3 --type=user --wq-size=32 \
            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1

        # enable device and queues
        accel-config enable-device dsa0
        accel-config enable-wq dsa0/wq0.0 dsa0/wq0.1 dsa0/wq0.2 dsa0/wq0.3


Devices using VFIO/UIO drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The HW devices to be used will need to be bound to a user-space IO driver for use.
The ``dpdk-devbind.py`` script can be used to view the state of the devices
and to bind them to a suitable DPDK-supported driver, such as ``vfio-pci``.
For example::

	$ dpdk-devbind.py -b vfio-pci 6a:01.0

.. note::

   Since each individual queue on the HW device is its own separate dmadev instance,
   the internal DMA device name includes the HW queue ID as a suffix on the PCI address.
   The above device when used by a DPDK application will be accessible via dmadevs with names:
   ``0000:6a:01.0-q0``, ``00006a:01.0-q1``, etc.

Device Probing and Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For devices bound to a suitable DPDK-supported VFIO/UIO driver, the HW devices will
be found as part of the device scan done at application initialization time without
the need to pass parameters to the application.

For Intel\ |reg| DSA devices, DPDK will automatically configure the device with the
maximum number of workqueues available on it, partitioning all resources equally
among the queues.
If fewer workqueues are required, then the ``max_queues`` parameter may be passed to
the device driver on the EAL commandline, via the ``allowlist`` or ``-a`` flag e.g.::

	$ dpdk-test -a <b:d:f>,max_queues=4

For devices bound to the IDXD kernel driver,
the DPDK IDXD driver will automatically perform a scan for available workqueues
to use. Any workqueues found listed in ``/dev/dsa`` on the system will be checked
in ``/sys``, and any which have ``dpdk_`` prefix in their name will be automatically
probed by the driver to make them available to the application.
Alternatively, to support use by multiple DPDK processes simultaneously,
the value used as the DPDK ``--file-prefix`` parameter may be used as a workqueue
name prefix, instead of ``dpdk_``, allowing each DPDK application instance to only
use a subset of configured queues.

Additionally, the -a (allowlist) or -b (blocklist) commandline parameters
are also available to further restrict the device list that will be used.
If the -a option is used, then any device that passes the ``dpdk_``
or ``--file-prefix`` prefix condition must also be present in the allow list.
Similarly, when the block list is used,
any device that passes the prefix condition must not be in the block list.
For example, to only use ``wq0.3``, assuming the name prefix condition is met::

	$ dpdk-test -a wq0.3

Once probed successfully, irrespective of kernel driver, the device will appear as a ``dmadev``,
that is a "DMA device type" inside DPDK, and can be accessed using APIs from the
``rte_dmadev`` library.

Using IDXD DMAdev Devices
-------------------------

To use the devices from an application, the dmadev API can be used.

Device Configuration
~~~~~~~~~~~~~~~~~~~~

IDXD configuration requirements:

* ``ring_size`` must be a power of two, between 64 and 4096.
* Only one ``vchan`` is supported per device (work queue).
* IDXD devices do not support silent mode.
* The transfer direction must be set to ``RTE_DMA_DIR_MEM_TO_MEM`` to copy from memory to memory.

Once configured, the device can then be made ready for use by calling the
``rte_dma_start()`` API.

Performing Data Copies
~~~~~~~~~~~~~~~~~~~~~~

Refer to the :ref:`dmadev_enqueue_dequeue` section of the dmadev library
documentation for details on operation enqueue, submission and completion API usage.

It is expected that, for efficiency reasons, a burst of operations will be enqueued to the
device via multiple enqueue calls between calls to the ``rte_dma_submit()`` function.

When gathering completions, ``rte_dma_completed()`` should be used, up until the point an error
occurs in an operation. If an error was encountered, ``rte_dma_completed_status()`` must be used
to kick the device off to continue processing operations and also to gather the status of each
individual operations which is filled in to the ``status`` array provided as parameter by the
application.

The following status codes are supported by IDXD:

* ``RTE_DMA_STATUS_SUCCESSFUL``: The operation was successful.
* ``RTE_DMA_STATUS_INVALID_OPCODE``: The operation failed due to an invalid operation code.
* ``RTE_DMA_STATUS_INVALID_LENGTH``: The operation failed due to an invalid data length.
* ``RTE_DMA_STATUS_NOT_ATTEMPTED``: The operation was not attempted.
* ``RTE_DMA_STATUS_ERROR_UNKNOWN``: The operation failed due to an unspecified error.

The following code shows how to retrieve the number of successfully completed
copies within a burst and then using ``rte_dma_completed_status()`` to check
which operation failed and kick off the device to continue processing operations:

.. code-block:: C

   enum rte_dma_status_code status[COMP_BURST_SZ];
   uint16_t count, idx, status_count;
   bool error = 0;

   count = rte_dma_completed(dev_id, vchan, COMP_BURST_SZ, &idx, &error);

   if (error){
      status_count = rte_dma_completed_status(dev_id, vchan, COMP_BURST_SZ, &idx, status);
   }

---

### Doc Guides Dmadevs Index (`doc/guides/dmadevs/index.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2021 HiSilicon Limited

DMA Device Drivers
==================

The following are a list of DMA device drivers, which can be used from
an application through DMA API.

.. toctree::
   :maxdepth: 1
   :numbered:

   ae4dma
   cnxk
   dpaa
   dpaa2
   hisi_acc
   hisi_pciep
   idxd
   ioat
   odm

---

### Doc Guides Dmadevs Ioat (`doc/guides/dmadevs/ioat.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2021 Intel Corporation.

.. include:: <isonum.txt>

IOAT DMA Device Driver
======================

The ``ioat`` dmadev driver provides a poll-mode driver (PMD) for Intel\
|reg| QuickData Technology which is part of part of Intel\ |reg| I/O
Acceleration Technology (`Intel I/OAT
<https://www.intel.com/content/www/us/en/wireless-network/accel-technology.html>`_).
This PMD, when used on supported hardware, allows data copies, for example,
cloning packet data, to be accelerated by IOAT hardware rather than having to
be done by software, freeing up CPU cycles for other tasks.

Hardware Requirements
---------------------

The ``dpdk-devbind.py`` script, included with DPDK, can be used to show the
presence of supported hardware. Running ``dpdk-devbind.py --status-dev dma``
will show all the DMA devices on the system, IOAT devices are included in this
list. For Intel\ |reg| IOAT devices, the hardware will often be listed as
"Crystal Beach DMA", or "CBDMA" or on some newer systems '0b00' due to the
absence of pci-id database entries for them at this point.

.. note::
        Error handling is not supported by this driver on hardware prior to
        Intel Ice Lake. Unsupported systems include Broadwell, Skylake and
        Cascade Lake.

Compilation
-----------

For builds using ``meson`` and ``ninja``, the driver will be built when the
target platform is x86-based. No additional compilation steps are necessary.

Device Setup
------------

Intel\ |reg| IOAT devices will need to be bound to a suitable DPDK-supported
user-space IO driver such as ``vfio-pci`` in order to be used by DPDK.

The ``dpdk-devbind.py`` script can be used to view the state of the devices using::

   $ dpdk-devbind.py --status-dev dma

The ``dpdk-devbind.py`` script can also be used to bind devices to a suitable driver.
For example::

	$ dpdk-devbind.py -b vfio-pci 00:01.0 00:01.1

Device Probing and Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For devices bound to a suitable DPDK-supported driver (``vfio-pci``), the HW
devices will be found as part of the device scan done at application
initialization time without the need to pass parameters to the application.

If the application does not require all the devices available an allowlist can
be used in the same way that other DPDK devices use them.

For example::

	$ dpdk-test -a <b:d:f>

Once probed successfully, the device will appear as a ``dmadev``, that is a
"DMA device type" inside DPDK, and can be accessed using APIs from the
``rte_dmadev`` library.

Using IOAT DMAdev Devices
-------------------------

To use IOAT devices from an application, the ``dmadev`` API can be used.

Device Configuration
~~~~~~~~~~~~~~~~~~~~

IOAT configuration requirements:

* ``ring_size`` must be a power of two, between 64 and 4096.
* Only one ``vchan`` is supported per device.
* Silent mode is not supported.
* The transfer direction must be set to ``RTE_DMA_DIR_MEM_TO_MEM`` to copy from memory to memory.

Once configured, the device can then be made ready for use by calling the
``rte_dma_start()`` API.

Performing Data Copies
~~~~~~~~~~~~~~~~~~~~~~

Refer to the :ref:`dmadev_enqueue_dequeue` section of the dmadev library
documentation for details on operation enqueue, submission and completion API usage.

It is expected that, for efficiency reasons, a burst of operations will be enqueued to the
device via multiple enqueue calls between calls to the ``rte_dma_submit()`` function.

When gathering completions, ``rte_dma_completed()`` should be used, up until the point an error
occurs with an operation. If an error was encountered, ``rte_dma_completed_status()`` must be used
to reset the device and continue processing operations. This function will also gather the status
of each individual operation which is filled in to the ``status`` array provided as parameter
by the application.

The status codes supported by IOAT are:

* ``RTE_DMA_STATUS_SUCCESSFUL``: The operation was successful.
* ``RTE_DMA_STATUS_INVALID_SRC_ADDR``: The operation failed due to an invalid source address.
* ``RTE_DMA_STATUS_INVALID_DST_ADDR``: The operation failed due to an invalid destination address.
* ``RTE_DMA_STATUS_INVALID_LENGTH``: The operation failed due to an invalid descriptor length.
* ``RTE_DMA_STATUS_DESCRIPTOR_READ_ERROR``: The device could not read the descriptor.
* ``RTE_DMA_STATUS_ERROR_UNKNOWN``: The operation failed due to an unspecified error.

The following code shows how to retrieve the number of successfully completed
copies within a burst and then uses ``rte_dma_completed_status()`` to check
which operation failed and reset the device to continue processing operations:

.. code-block:: C

   enum rte_dma_status_code status[COMP_BURST_SZ];
   uint16_t count, idx, status_count;
   bool error = 0;

   count = rte_dma_completed(dev_id, vchan, COMP_BURST_SZ, &idx, &error);

   if (error){
      status_count = rte_dma_completed_status(dev_id, vchan, COMP_BURST_SZ, &idx, status);
   }

---

### Doc Guides Dmadevs Odm (`doc/guides/dmadevs/odm.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2024 Marvell.

Odyssey ODM DMA Device Driver
=============================

The ``odm`` DMA device driver provides a poll-mode driver (PMD)
for Marvell Odyssey DMA Hardware Accelerator block found in Odyssey SoC.
The block supports only mem to mem DMA transfers.

ODM DMA device can support up to 32 queues and 16 VFs.

Device Setup
------------

The ODM DMA device is initialized by the ODM PF driver application,
which is responsible for configuring the device and creating VFs.

The driver can be downloaded from GitHub using the following link
`<https://github.com/MarvellEmbeddedProcessors/odm_pf_driver>`_

Instructions for enabling the ODM PF driver are provided in the repository's
README file.

The ``dpdk-devbind.py`` script, included with DPDK,
can be used to show the presence of supported hardware.
Running ``dpdk-devbind.py --status-dev dma``
will show all the Odyssey ODM DMA devices.

Devices using VFIO drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~

The HW devices to be used will need to be bound to a user-space IO driver.
The ``dpdk-devbind.py`` script can be used to view the state of the devices
and to bind them to a suitable DPDK-supported driver, such as ``vfio-pci``.
For example::

   dpdk-devbind.py -b vfio-pci 0000:08:00.1

Device Probing and Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To use the devices from an application, the dmadev API can be used.

Once configured, the device can then be made ready for use
by calling the ``rte_dma_start()`` API.

Performing Data Copies
~~~~~~~~~~~~~~~~~~~~~~

Refer to the :ref:`dmadev_enqueue_dequeue` section of the dmadev library documentation
for details on operation enqueue and submission API usage.

Performance Tuning Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To achieve higher performance, the DMA device needs to be tuned
using the parameters provided by the PF driver application.

The following configuration parameters are exposed
by the ODM PF driver application:

``ENG_SEL``

  ODM DMA device has 2 engines internally. Engine to queue mapping is decided
  by a hardware register which can be configured
  by updating the configuration file::

     ENG_SEL="0xCCCCCCCC"

  Each bit in the register corresponds to one queue.
  Each queue would be associated with one engine.
  If the value of the bit corresponding to the queue is 0, then engine 0 would be picked.
  If it is 1, then engine 1 would be picked.

  In the above command, the register value is set as
  ``1100 1100 1100 1100 1100 1100 1100 1100``
  which allows for alternate engines to be used with alternate VFs
  (assuming the system has 16 VFs with 2 queues each).

---

### Doc Guides Eventdevs Cnxk (`doc/guides/eventdevs/cnxk.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright(c) 2021 Marvell.

Marvell cnxk SSO Eventdev Driver
================================

The SSO PMD (**librte_event_cnxk**) and provides poll mode
eventdev driver support for the inbuilt event device found in the
**Marvell OCTEON cnxk** SoC family.

More information about OCTEON cnxk SoC can be found at `Marvell Official Website
<https://www.marvell.com/embedded-processors/infrastructure-processors/>`_.

Supported OCTEON cnxk SoCs
--------------------------

- CN9XX
- CN10XX
- CN20XX

Features
--------

Features of the OCTEON cnxk SSO PMD are:

- 256 Event queues
- 26 (dual) and 52 (single) Event ports on CN9XX
- 52 Event ports on CN10XX
- HW event scheduler
- Supports 1M flows per event queue
- Flow based event pipelining
- Flow pinning support in flow based event pipelining
- Queue based event pipelining
- Supports ATOMIC, ORDERED, PARALLEL schedule types per flow
- Event scheduling QoS based on event queue priority
- Open system with configurable amount of outstanding events limited only by
  DRAM
- HW accelerated dequeue timeout support to enable power management
- HW managed event timers support through TIM, with high precision and
  time granularity of 2.5us on CN9K and 1us on CN10K/CN20K.
- Up to 256 TIM rings a.k.a event timer adapters.
- Up to 8 rings traversed in parallel.
- HW managed packets enqueued from ethdev to eventdev exposed through event eth
  RX adapter.
- N:1 ethernet device Rx queue to Event queue mapping.
- Lockfree Tx from event eth Tx adapter using ``RTE_ETH_TX_OFFLOAD_MT_LOCKFREE``
  capability while maintaining receive packet order.
- Full Rx/Tx offload support defined through ethdev queue configuration.
- HW managed event vectorization on CN10K/CN20K for packets enqueued from ethdev
  to eventdev configurable per each Rx queue in Rx adapter.
- Event vector transmission via Tx adapter.
- Up to 2 event link profiles.
- HW managed event vectorization on CN20K via ``rte_event_vector_adapter``
  for work originating from CPU.

Prerequisites and Compilation procedure
---------------------------------------

   See :doc:`/platform/cnxk` for setup information.


Runtime Config Options
----------------------

- ``Maximum number of in-flight events`` (default ``8192``)

  In **Marvell OCTEON cnxk** the max number of in-flight events are only limited
  by DRAM size, the ``xae_cnt`` devargs parameter is introduced to provide
  upper limit for in-flight events.

  For example::

    -a 0002:0e:00.0,xae_cnt=16384

- ``CN9K Getwork mode``

  CN9K ``single_ws`` devargs parameter is introduced to select single workslot
  mode in SSO and disable the default dual workslot mode.

  For example::

    -a 0002:0e:00.0,single_ws=1

- ``Event Group QoS support``

  SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight
  events. By default the buffers are assigned to the SSO GGRPs to
  satisfy minimum HW requirements. SSO is free to assign the remaining
  buffers to GGRPs based on a preconfigured threshold.
  We can control the QoS of SSO GGRP by modifying the above mentioned
  thresholds. GGRPs that have higher importance can be assigned higher
  thresholds than the rest. The dictionary format is as follows
  [Qx-TAQ-IAQ][Qz-TAQ-IAQ] expressed in percentages, 0 represents default.

  For example::

    -a 0002:0e:00.0,qos=[1-50-50]

- ``CN10K/CN20K WQE stashing support``

  CN10K/CN20K supports stashing the scheduled WQE carried by `rte_event` to the
  cores L2 Dcache. The number of cache lines to be stashed and the offset
  is configurable per HWGRP i.e. event queue. The dictionary format is as
  follows `[Qx|stash_offset|stash_length]` here the stash offset can be
  a negative integer.
  By default, stashing is enabled on queues which have been connected to
  Rx adapter. Both MBUF and NIX_RX_WQE_HDR + NIX_RX_PARSE_S are stashed.

  For example::

    For stashing mbuf on queue 0 and mbuf + headroom on queue 1
    -a 0002:0e:00.0,stash="[0|-1|1][1|-1|2]"

- ``Force Rx Back pressure``

   Force Rx back pressure when same mempool is used across ethernet device
   connected to event device.

   For example::

      -a 0002:0e:00.0,force_rx_bp=1

- ``TIM disable NPA``

  By default chunks are allocated from NPA then TIM can automatically free
  them when traversing the list of chunks. The ``tim_disable_npa`` devargs
  parameter disables NPA and uses software mempool to manage chunks

  For example::

    -a 0002:0e:00.0,tim_disable_npa=1

- ``TIM modify chunk slots``

  The ``tim_chnk_slots`` devargs can be used to modify number of chunk slots.
  Chunks are used to store event timers, a chunk can be visualised as an array
  where the last element points to the next chunk and rest of them are used to
  store events. TIM traverses the list of chunks and enqueues the event timers
  to SSO. The default value is 255 and the max value is 4095.

  For example::

    -a 0002:0e:00.0,tim_chnk_slots=1023

- ``TIM enable arm/cancel statistics``

  The ``tim_stats_ena`` devargs can be used to enable arm and cancel stats of
  event timer adapter.

  For example::

    -a 0002:0e:00.0,tim_stats_ena=1

- ``TIM limit max rings reserved``

  The ``tim_rings_lmt`` devargs can be used to limit the max number of TIM
  rings i.e. event timer adapter reserved on probe. Since, TIM rings are HW
  resources we can avoid starving other applications by not grabbing all the
  rings.

  For example::

    -a 0002:0e:00.0,tim_rings_lmt=5

- ``TIM ring control internal parameters``

  When using multiple TIM rings the ``tim_ring_ctl`` devargs can be used to
  control each TIM rings internal parameters uniquely. The following dict
  format is expected [ring-chnk_slots-disable_npa-stats_ena]. 0 represents
  default values.

  For Example::

    -a 0002:0e:00.0,tim_ring_ctl=[2-1023-1-0]

- ``TIM external clock frequency``

  The ``tim_eclk_freq`` devagrs can be used to pass external clock frequencies
  when external clock source is selected.

  External clock frequencies are mapped as follows::

    RTE_EVENT_TIMER_ADAPTER_EXT_CLK0 = TIM_CLK_SRC_10NS,
    RTE_EVENT_TIMER_ADAPTER_EXT_CLK1 = TIM_CLK_SRC_GPIO,
    RTE_EVENT_TIMER_ADAPTER_EXT_CLK2 = TIM_CLK_SRC_PTP,
    RTE_EVENT_TIMER_ADAPTER_EXT_CLK3 = TIM_CLK_SRC_SYNCE

  The order of frequencies supplied to device args should be GPIO-PTP-SYNCE.

  For Example::

    -a 0002:0e:00.0,tim_eclk_freq=122880000-1000000000-0

Power Saving on CN10K/CN20K
---------------------------

ARM cores can additionally use WFE when polling for transactions on SSO bus
to save power i.e., in the event dequeue call ARM core can enter WFE and exit
when either work has been scheduled or dequeue timeout has reached.
This feature can be selected by configuring meson with ``RTE_ARM_USE_WFE`` enabled.

Debugging Options
-----------------

.. table:: OCTEON cnxk event device debug options

   +---+------------+-------------------------------------------------------+
   | # | Component  | EAL log command                                       |
   +===+============+=======================================================+
   | 1 | SSO        | --log-level='pmd\.common\.cnxk\.event,8'              |
   +---+------------+-------------------------------------------------------+
   | 2 | TIM        | --log-level='pmd\.common\.cnxk\.timer,8'              |
   +---+------------+-------------------------------------------------------+

Limitations
-----------

Rx adapter support
~~~~~~~~~~~~~~~~~~

Using the same mempool for all the ethernet device ports connected to
event device would cause back pressure to be asserted only on the first
ethernet device.
Back pressure is automatically disabled when using same mempool for all the
ethernet devices connected to event device to override this applications can
use `force_rx_bp=1` device arguments.
Using unique mempool per each ethernet device is recommended when they are
connected to event device.

DMA adapter new mode support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DMA driver does not support DMA adapter configured in new mode.

---

### Doc Guides Eventdevs Dlb2 (`doc/guides/eventdevs/dlb2.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2020 Intel Corporation.

Driver for the Intel® Dynamic Load Balancer (DLB)
=================================================

The DPDK DLB poll mode driver supports the Intel® Dynamic Load Balancer,
hardware versions 2.0 and 2.5.

Please follow the links below to download the Programmer Guides.

`Intel Dynamic Load Balancer 2.0 Programmer Guide <https://cdrdv2.intel.com/v1/dl/getContent/613545>`_. (Device: 0x2710)

`Intel Dynamic Load Balancer 2.5 Programmer Guide <https://cdrdv2.intel.com/v1/dl/getContent/639481>`_. (Device: 0x2714)

Prerequisites
-------------

Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.

Configuration
-------------

The DLB PF PMD is a user-space PMD that uses VFIO to gain direct
device access. To use this operation mode, the PCIe PF device must
be bound to a DPDK-compatible VFIO driver, such as vfio-pci.

Eventdev API Notes
------------------

The DLB PMD provides the functions of a DPDK event device; specifically, it
supports atomic, ordered, and parallel scheduling events from queues to ports.
However, the DLB hardware is not a perfect match to the eventdev API. Some DLB
features are abstracted by the PMD such as directed ports.

In general the DLB PMD is designed for ease-of-use and does not require a
detailed understanding of the hardware, but these details are important when
writing high-performance code. This section describes the places where the
eventdev API and DLB misalign.

Scheduling Domain Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DLB supports 32 scheduling domains.
When one is configured, it allocates load-balanced and
directed queues, ports, credits, and other hardware resources. Some
resource allocations are user-controlled -- the number of queues, for example
-- and others, like credit pools (one directed and one load-balanced pool per
scheduling domain), are not.

The DLB is a closed system eventdev, and as such the ``nb_events_limit`` device
setup argument and the per-port ``new_event_threshold`` argument apply as
defined in the eventdev header file. The limit is applied to all enqueues,
regardless of whether it will consume a directed or load-balanced credit.

Load-Balanced Queues
~~~~~~~~~~~~~~~~~~~~

A load-balanced queue can support atomic and ordered scheduling, or atomic and
unordered scheduling, but not atomic and unordered and ordered scheduling. A
queue's scheduling types are controlled by the event queue configuration.

If the user sets the ``RTE_EVENT_QUEUE_CFG_ALL_TYPES`` flag, the
``nb_atomic_order_sequences`` determines the supported scheduling types.
With non-zero ``nb_atomic_order_sequences``, the queue is configured for atomic
and ordered scheduling. In this case, ``RTE_SCHED_TYPE_PARALLEL`` scheduling is
supported by scheduling those events as ordered events.  Note that when the
event is dequeued, its sched_type will be ``RTE_SCHED_TYPE_ORDERED``. Else if
``nb_atomic_order_sequences`` is zero, the queue is configured for atomic and
unordered scheduling. In this case, ``RTE_SCHED_TYPE_ORDERED`` is unsupported.

If the ``RTE_EVENT_QUEUE_CFG_ALL_TYPES`` flag is not set, schedule_type
dictates the queue's scheduling type.

The ``nb_atomic_order_sequences`` queue configuration field sets the ordered
queue's reorder buffer size.  DLB has 2 groups of ordered queues, where each
group is configured to contain either 1 queue with 1024 reorder entries, 2
queues with 512 reorder entries, and so on down to 32 queues with 32 entries.

When a load-balanced queue is created, the PMD will configure a new sequence
number group on-demand if num_sequence_numbers does not match a pre-existing
group with available reorder buffer entries. If all sequence number groups are
in use, no new group will be created and queue configuration will fail. (Note
that when the PMD is used with a virtual DLB device, it cannot change the
sequence number configuration.)

The queue's ``nb_atomic_flows`` parameter is ignored by the DLB PMD, because
the DLB does not limit the number of flows a queue can track. In the DLB, all
load-balanced queues can use the full 16-bit flow ID range.

Load-balanced and Directed Ports
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DLB ports come in two flavors: load-balanced and directed. The eventdev API
does not have the same concept, but it has a similar one: ports and queues that
are singly-linked (i.e. linked to a single queue or port, respectively).

The ``rte_event_dev_info_get()`` function reports the number of available
event ports and queues (among other things). For the DLB PMD, max_event_ports
and max_event_queues report the number of available load-balanced ports and
queues, and max_single_link_event_port_queue_pairs reports the number of
available directed ports and queues.

When a scheduling domain is created in ``rte_event_dev_configure()``, the user
specifies ``nb_event_ports`` and ``nb_single_link_event_port_queues``, which
control the total number of ports (load-balanced and directed) and the number
of directed ports. Hence, the number of requested load-balanced ports is
``nb_event_ports - nb_single_link_event_ports``. The ``nb_event_queues`` field
specifies the total number of queues (load-balanced and directed). The number
of directed queues comes from ``nb_single_link_event_port_queues``, since
directed ports and queues come in pairs.

When a port is setup, the ``RTE_EVENT_PORT_CFG_SINGLE_LINK`` flag determines
whether it should be configured as a directed (the flag is set) or a
load-balanced (the flag is unset) port. Similarly, the
``RTE_EVENT_QUEUE_CFG_SINGLE_LINK`` queue configuration flag controls
whether it is a directed or load-balanced queue.

Load-balanced ports can only be linked to load-balanced queues, and directed
ports can only be linked to directed queues. Furthermore, directed ports can
only be linked to a single directed queue (and vice versa), and that link
cannot change after the eventdev is started.

The eventdev API does not have a directed scheduling type. To support directed
traffic, the DLB PMD detects when an event is being sent to a directed queue
and overrides its scheduling type. Note that the originally selected scheduling
type (atomic, ordered, or parallel) is not preserved, and an event's sched_type
will be set to ``RTE_SCHED_TYPE_ATOMIC`` when it is dequeued from a directed
port.

Finally, even though all 3 event types are supported on the same QID by
converting unordered events to ordered, such use should be discouraged as much
as possible, since mixing types on the same queue uses valuable reorder
resources, and orders events which do not require ordering.

Flow ID
~~~~~~~

The flow ID field is preserved in the event when it is scheduled in the
DLB.

Hardware Credits
~~~~~~~~~~~~~~~~

DLB uses a hardware credit scheme to prevent software from overflowing hardware
event storage, with each unit of storage represented by a credit. A port spends
a credit to enqueue an event, and hardware refills the ports with credits as the
events are scheduled to ports. Refills come from credit pools.

For DLB v2.5, there is a single credit pool used for both load balanced and
directed traffic.

For DLB v2.0, each port is a member of both a load-balanced credit pool and a
directed credit pool. The load-balanced credits are used to enqueue to
load-balanced queues, and directed credits are used for directed queues.
These pools' sizes are controlled by the nb_events_limit field in struct
rte_event_dev_config. The load-balanced pool is sized to contain
nb_events_limit credits, and the directed pool is sized to contain
nb_events_limit/2 credits. The directed pool size can be overridden with the
num_dir_credits devargs argument, like so:

    .. code-block:: console

       --allow ea:00.0,num_dir_credits=<value>

This can be used if the default allocation is too low or too high for the
specific application needs. The PMD also supports a devarg that limits the
max_num_events reported by rte_event_dev_info_get():

    .. code-block:: console

       --allow ea:00.0,max_num_events=<value>

By default, max_num_events is reported as the total available load-balanced
credits. If multiple DLB-based applications are being used, it may be desirable
to control how many load-balanced credits each application uses, particularly
when application(s) are written to configure nb_events_limit equal to the
reported max_num_events.

Each port is a member of both credit pools. A port's credit allocation is
defined by its low watermark, high watermark, and refill quanta. These three
parameters are calculated by the DLB PMD like so:

- The load-balanced high watermark is set to the port's enqueue_depth.
  The directed high watermark is set to the minimum of the enqueue_depth and
  the directed pool size divided by the total number of ports.
- The refill quanta is set to half the high watermark.
- The low watermark is set to the minimum of 16 and the refill quanta.

When the eventdev is started, each port is pre-allocated a high watermark's
worth of credits. For example, if an eventdev contains four ports with enqueue
depths of 32 and a load-balanced credit pool size of 4096, each port will start
with 32 load-balanced credits, and there will be 3968 credits available to
replenish the ports. Thus, a single port is not capable of enqueueing up to the
nb_events_limit (without any events being dequeued), since the other ports are
retaining their initial credit allocation; in short, all ports must enqueue in
order to reach the limit.

If a port attempts to enqueue and has no credits available, the enqueue
operation will fail and the application must retry the enqueue. Credits are
replenished asynchronously by the DLB hardware.

Software Credits
~~~~~~~~~~~~~~~~

The DLB is a "closed system" event dev, and the DLB PMD layers a software
credit scheme on top of the hardware credit scheme in order to comply with
the per-port backpressure described in the eventdev API.

The DLB's hardware scheme is local to a queue/pipeline stage: a port spends a
credit when it enqueues to a queue, and credits are later replenished after the
events are dequeued and released.

In the software credit scheme, a credit is consumed when a new (.op =
RTE_EVENT_OP_NEW) event is injected into the system, and the credit is
replenished when the event is released from the system (either explicitly with
RTE_EVENT_OP_RELEASE or implicitly in dequeue_burst()).

In this model, an event is "in the system" from its first enqueue into eventdev
until it is last dequeued. If the event goes through multiple event queues, it
is still considered "in the system" while a worker thread is processing it.

A port will fail to enqueue if the number of events in the system exceeds its
``new_event_threshold`` (specified at port setup time). A port will also fail
to enqueue if it lacks enough hardware credits to enqueue; load-balanced
credits are used to enqueue to a load-balanced queue, and directed credits are
used to enqueue to a directed queue.

The out-of-credit situations are typically transient, and an eventdev
application using the DLB ought to retry its enqueues if they fail.
If enqueue fails, DLB PMD sets rte_errno as follows:

- -ENOSPC: Credit exhaustion (either hardware or software)
- -EINVAL: Invalid argument, such as port ID, queue ID, or sched_type.

Depending on the pipeline the application has constructed, it's possible to
enter a credit deadlock scenario wherein the worker thread lacks the credit
to enqueue an event, and it must dequeue an event before it can recover the
credit. If the worker thread retries its enqueue indefinitely, it will not
make forward progress. Such deadlock is possible if the application has event
"loops", in which an event in dequeued from queue A and later enqueued back to
queue A.

Due to this, workers should stop retrying after a time, release the events it
is attempting to enqueue, and dequeue more events. It is important that the
worker release the events and don't simply set them aside to retry the enqueue
again later, because the port has limited history list size (by default, same
as port's dequeue_depth).

Priority
~~~~~~~~

The DLB supports event priority and per-port queue service priority, as
described in the eventdev header file. The DLB does not support 'global' event
queue priority established at queue creation time.

DLB supports 4 event and queue service priority levels. For both priority types,
the PMD uses the upper three bits of the priority field to determine the DLB
priority, discarding the 5 least significant bits. But least significant bit out
of 3 priority bits is effectively ignored for binning into 4 priorities. The
discarded 5 least significant event priority bits are not preserved when an event
is enqueued.

Note that event priority only works within the same event type.
When atomic and ordered or unordered events are enqueued to same QID, priority
across the types is always equal, and both types are served in a round robin manner.

Reconfiguration
~~~~~~~~~~~~~~~

The Eventdev API allows one to reconfigure a device, its ports, and its queues
by first stopping the device, calling the configuration function(s), then
restarting the device. The DLB does not support configuring an individual queue
or port without first reconfiguring the entire device, however, so there are
certain reconfiguration sequences that are valid in the eventdev API but not
supported by the PMD.

Specifically, the PMD supports the following configuration sequence:

#. Configure and start the device

#. Stop the device

#. (Optional) Reconfigure the device
   Setup queue(s). The reconfigured queue(s) lose their previous port links.
   The reconfigured port(s) lose their previous queue links.
   Link port(s) to queue(s)

#. Restart the device. If the device is reconfigured in step 3 but one or more
   of its ports or queues are not, the PMD will apply their previous
   configuration (including port->queue links) at this time.

The PMD does not support the following configuration sequences:

#. Configure and start the device

#. Stop the device

#. Setup queue or setup port

#. Start the device

This sequence is not supported because the event device must be reconfigured
before its ports or queues can be.

Atomic Inflights Allocation
~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the last stage prior to scheduling an atomic event to a CQ, DLB holds the
inflight event in a temporary buffer that is divided among load-balanced
queues. If a queue's atomic buffer storage fills up, this can result in
head-of-line-blocking. For example:

- An LDB queue allocated N atomic buffer entries
- All N entries are filled with events from flow X, which is pinned to CQ 0.

Until CQ 0 releases 1+ events, no other atomic flows for that LDB queue can be
scheduled. The likelihood of this case depends on the eventdev configuration,
traffic behavior, event processing latency, potential for a worker to be
interrupted or otherwise delayed, etc.

By default, the PMD allocates 64 buffer entries for each load-balanced queue,
which provides an even division across all 32 queues but potentially wastes
buffer space (e.g. if not all queues are used, or aren't used for atomic
scheduling).

QID Depth Threshold
~~~~~~~~~~~~~~~~~~~

DLB supports setting and tracking queue depth thresholds. Hardware uses
the thresholds to track how full a queue is compared to its threshold.
Four buckets are used

- Less than or equal to 50% of queue depth threshold
- Greater than 50%, but less than or equal to 75% of depth threshold
- Greater than 75%, but less than or equal to 100% of depth threshold
- Greater than 100% of depth thresholds

Per queue threshold metrics are tracked in the DLB xstats, and are also
returned in the impl_opaque field of each received event.

The per qid threshold can be specified as part of the device args, and
can be applied to all queues, a range of queues, or a single queue, as
shown below.

    .. code-block:: console

       --allow ea:00.0,qid_depth_thresh=all:<threshold_value>
       --allow ea:00.0,qid_depth_thresh=qidA-qidB:<threshold_value>
       --allow ea:00.0,qid_depth_thresh=qid:<threshold_value>

Class of service
~~~~~~~~~~~~~~~~

DLB supports provisioning the DLB bandwidth into 4 classes of service.
A LDB port or range of LDB ports may be configured to use one of the classes.
If a port's COS is not defined, then it will be allocated from class 0,
class 1, class 2, or class 3, in that order, depending on availability.

The sum of the cos_bw values may not exceed 100, and no more than
16 LDB ports may be assigned to a given class of service. If port cos is
not defined on the command line, then each class is assigned 25% of the
bandwidth, and the available load balanced ports are split between the classes.
Per-port class of service and bandwidth can be specified in the devargs,
as follows.

    .. code-block:: console

       --allow ea:00.0,port_cos=Px-Py:<0-3>,cos_bw=5:10:80:5
       --allow ea:00.0,port_cos=Px:<0-3>,cos_bw=5:10:80:5

Use X86 Vector Instructions
~~~~~~~~~~~~~~~~~~~~~~~~~~~

DLB supports using x86 vector instructions to optimize the data path.

The default mode of operation is to use scalar instructions, but
the use of vector instructions can be enabled in the devargs, as
follows

    .. code-block:: console

       --allow ea:00.0,vector_opts_enabled=<y/Y>

Maximum CQ Depth
~~~~~~~~~~~~~~~~

DLB supports configuring the maximum depth of a consumer queue (CQ).
The depth must be between 32 and 128, and must be a power of 2. Note
that credit deadlocks may occur as a result of changing the default depth.
To prevent deadlock, the user may also need to configure the maximum
enqueue depth.

    .. code-block:: console

       --allow ea:00.0,max_cq_depth=<depth>

Maximum Enqueue Depth
~~~~~~~~~~~~~~~~~~~~~

DLB supports configuring the maximum enqueue depth of a producer port (PP).
The depth must be between 32 and 1024, and must be a power of 2.

    .. code-block:: console

       --allow ea:00.0,max_enqueue_depth=<depth>

Producer Coremask
~~~~~~~~~~~~~~~~~

For best performance, applications running on certain cores should use
the DLB device locally available on the same tile along with other
resources. To allocate optimal resources, probing is done for each
producer port (PP) for a given CPU and the best performing ports are
allocated to producers. The cpu used for probing is either the first
core of producer coremask DLB2 device parameter (if present) or the second core of EAL
core list. This will be extended later to probe for all CPUs in the
producer coremask or EAL core list. Producer coremask can be passed
along with the BDF of the DLB devices.

    .. code-block:: console

       -a xx:y.z,producer_coremask=<core_mask>

Default LDB Port Allocation
~~~~~~~~~~~~~~~~~~~~~~~~~~~

For optimal load balancing ports that map to one or more QIDs in common
should not be in numerical sequence. The port->QID mapping is application
dependent, but the driver interleaves port IDs as much as possible to
reduce the likelihood of sequential ports mapping to the same QID(s).

Hence, DLB uses an initial allocation of Port IDs to maximize the
average distance between an ID and its immediate neighbors. (i.e.the
distance from 1 to 0 and to 2, the distance from 2 to 1 and to 3, etc.).
Initial port allocation option can be passed through devarg. If y (or Y)
inial port allocation will be used, otherwise initial port allocation
won't be used.

    .. code-block:: console

       --allow ea:00.0,default_port_allocation=<y/Y>

QE Weight
~~~~~~~~~

DLB supports advanced scheduling mechanisms, such as CQ weight.
Each load balanced CQ has a configurable work capacity (max 256)
which corresponds to the total QE weight DLB will allow to be enqueued
to that consumer. Every load balanced event/QE carries a weight of 0, 2, 4,
or 8 and DLB will increment a (per CQ) load indicator when it schedules a
QE to that CQ. The weight is also stored in the history list. When a
completion arrives, the weight is popped from the history list and used to
decrement the load indicator. This creates a new scheduling condition - a CQ
whose load is equal to or in excess of capacity is not available for traffic.
Note that the weight may not exceed the maximum CQ depth.

Example command to enable QE Weight feature:

    .. code-block:: console

       --allow ea:00.0,enable_cq_weight=<y/Y>

Credit Handling Scenario Improvements
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It is possible for ports to hold on to unused credits and not release them
due to insufficient accumulation (i.e. less than 2 * credit quanta).
This can result in credit deadlocks situation.
DLB2 PMD makes worker ports to release all accumulated credits
when back-to-back zero poll count reaches a preset threshold
and makes producer ports release all the accumulated credits
if enqueue fails for a consecutive number of retries.

New Meson options are provided through c_args for enabling and disabling
credits handling option flags.
Credit checks are enabled by default.

Example command to use as meson option for credit handling:

    .. code-block:: console

       meson configure -Dc_args='-DDLB_SW_CREDITS_CHECKS=0 -DDLB_HW_CREDITS_CHECKS=1'

DLB History List Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Every DLB Load Balancing port
(i.e., eventdev port not using ``RTE_EVENT_PORT_CFG_SINGLE_LINK`` flag)
has a hardware resource call history list entries (HL) associated with it.
This count decides the number of events that can be inflight to the port from the DLB hardware.
DLB has 2048 total HL entries.
As DLB supports 64 load-balanced ports, by default DLB PMD assigns 32 HL entries to each port.
Following devargs arguments allow application to control HL entries overriding default mode.
DLB API ``rte_pmd_dlb2_set_port_param()`` allows setting HL entries for the DLB eventdev ports.
Please refer to section "Fine Tuning History List Entries" in DLB Programmer Guide for details.

    .. code-block:: console

       --allow ea:00.0,use_default_hl=0,alloc_hl_entries=1024

         use_default_hl: 1=Enable (default), 0=Disable
         alloc_hl_entries: [0-2048] Total HL entries

Running Eventdev Applications with DLB Device
---------------------------------------------

This section explains how to run eventdev applications
with DLB hardware as well as difference in command line parameter
to switch between a DLB hardware and a virtual eventdev device such as SW0, hence
users can run applications with or without DLB device to compare performance of
a DLB device.

In order to run eventdev applications, DLB device must be bound
to a DPDK-compatible VFIO driver, such as vfio-pci.

Example command to bind DLB device to vfio-pci driver:

    .. code-block:: console

       ../usertools/dpdk-devbind.py -b vfio-pci ea:00.0

Eventdev applications can be run with or without a DLB device.
Below examples give details of running eventdev application without DLB device
and with DLB device. Notice that the primary difference between two examples are
passing the parameter ``--vdev <driver><id>``. The first example run uses a virtual
eventdev device SW0 while second example run directly and picks DLB device from
VFIO driver.

Example command to run eventdev application without a DLB device:

	.. code-block:: console

	   sudo <build_dir>/app/dpdk-test-eventdev --vdev=event_sw0 -- \
					--test=order_queue --plcores 1 --wlcores 2,3

After binding DLB device to a supported pci driver such as vfio-pci,
eventdev applications can be run on the DLB device.

Example command to run eventdev application with a DLB device:

	.. code-block:: console

		sudo build/app/dpdk-test-eventdev -- --test=order_queue\
			--plcores=1 --wlcores=2-7 --stlist=o --worker_deq_depth=128\
			--prod_enq_burst_sz=64 --nb_flows=64 --nb_pkts=1000000

A particular DLB device can also be picked from command line by passing
	``--a`` or  ``--allow`` option:

	.. code-block:: console

		sudo build/app/dpdk-test-eventdev --allow ea:00.0 -- --test=order_queue\
			--plcores=1 --wlcores=2-7 --stlist=o --worker_deq_depth=128\
			--prod_enq_burst_sz=64 --nb_flows=64 --nb_pkts=1000000

Debugging options
~~~~~~~~~~~~~~~~~

To specify log level for a DLB device use ``--log-level=dlb,8``.
Example command to run eventdev application with a DLB device log level enabled:

	.. code-block:: console

		sudo build/app/dpdk-test-eventdev --allow ea:00.0 --log-level=dlb,8 -- --test=order_queue\
			--plcores=1 --wlcores=2-7 --stlist=o --worker_deq_depth=128\
			--prod_enq_burst_sz=64 --nb_flows=64 --nb_pkts=1000000

---

### Doc Guides Eventdevs Dpaa (`doc/guides/eventdevs/dpaa.rst`)

.. SPDX-License-Identifier: BSD-3-Clause
   Copyright 2017 NXP

NXP DPAA Eventdev Driver
========================

The dpaa eventdev is an implementation of the eventdev API, that provides a
wide range of the eventdev features. The eventdev relies on a dpaa based
platform to perform event scheduling.

More information can be found at `NXP Official Website
<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.

Features
--------

The DPAA EVENTDEV implements many features in the eventdev API;

- Hardware based event scheduler
- 4 event ports
- 4 event queues
- Parallel flows
- Atomic flows

Supported DPAA SoCs
-------------------

- LS1046A/LS1026A
- LS1043A/LS1023A

Prerequisites
-------------

See :doc:`/platform/dpaa` for setup information

Currently supported by DPDK:

- NXP SDK **2.0+** or LSDK **18.09+**
- Supported architectures:  **arm64 LE**.

- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.


Initialization
--------------

The dpaa eventdev is exposed as a vdev device which consists of a set of channels
and queues. On EAL initialization, dpaa components will be
probed and then vdev device can be created from the application code by

* Invoking ``rte_vdev_init("event_dpaa1")`` from the application

* Using ``--vdev="event_dpaa1"`` in the EAL options, which will call
  rte_vdev_init() internally

Example:

.. code-block:: console

    ./your_eventdev_application --vdev="event_dpaa1"

* Use dev arg option ``disable_intr=1`` to disable the interrupt mode

Limitations
-----------

#. DPAA eventdev can not work with DPAA PUSH mode queues configured for ethdev.
   Please configure export DPAA_NUM_PUSH_QUEUES=0

Platform Requirement
~~~~~~~~~~~~~~~~~~~~

DPAA drivers for DPDK can only work on NXP SoCs as listed in the
``Supported DPAA SoCs``.

Port-core Binding
~~~~~~~~~~~~~~~~~

DPAA EVENTDEV driver requires event port 'x' to be used on core 'x'.

---

### Doc Guides Eventdevs Dpaa2 (`doc/guides/eventdevs/dpaa2.rst`)

..  SPDX-License-Identifier: BSD-3-Clause
    Copyright 2017 NXP


NXP DPAA2 Eventdev Driver
=========================

The dpaa2 eventdev is an implementation of the eventdev API, that provides a
wide range of the eventdev features. The eventdev relies on a dpaa2 hw to
perform event scheduling.

More information can be found at `NXP Official Website
<http://www.nxp.com/products/microcontrollers-and-processors/arm-processors/qoriq-arm-processors:QORIQ-ARM>`_.

Features
--------

The DPAA2 EVENTDEV implements many features in the eventdev API;

- Hardware based event scheduler
- 8 event ports
- 8 event queues
- Parallel flows
- Atomic flows

Supported DPAA2 SoCs
--------------------

- LX2160A
- LS2084A/LS2044A
- LS2088A/LS2048A
- LS1088A/LS1048A

Prerequisites
-------------

See :doc:`/platform/dpaa2` for setup information

- Follow the DPDK :doc:`/linux_gsg/index` to setup the basic DPDK environment.

.. note::

   Some part of fslmc bus code (mc flib - object library) routines are
   dual licensed (BSD & GPLv2).


Initialization
--------------

The dpaa2 eventdev is exposed as a vdev device which consists of a set of dpcon
devices and dpci devices. On EAL initialization, dpcon and dpci devices will be
probed and then vdev device can be created from the application code by

* Invoking ``rte_vdev_init("event_dpaa2")`` from the application

* Using ``--vdev="event_dpaa2"`` in the EAL options, which will call
  rte_vdev_init() internally

Example:

.. code-block:: console

   ./your_eventdev_application --vdev="event_dpaa2"

Enabling logs
-------------

For enabling logs, use the following EAL parameter:

.. code-block:: console

   ./your_eventdev_application <EAL args> --log-level=pmd.event.dpaa2,<level>

Using ``eventdev.dpaa2`` as log matching criteria, all Event PMD logs can be
enabled which are lower than logging ``level``.

Limitations
-----------

Platform Requirement
~~~~~~~~~~~~~~~~~~~~

DPAA2 drivers for DPDK can only work on NXP SoCs as listed in the
``Supported DPAA2 SoCs``.

Port-core binding
~~~~~~~~~~~~~~~~~

DPAA2 EVENTDEV can support only one eventport per core.

---

--- METRICS ---
- Files Extracted: 151
- Estimated Token Budget: ~125128 tokens
- Canonical Reference: https://codewiki.google/github.com/DPDK/dpdk
