get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/27989/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 27989,
    "url": "https://patches.dpdk.org/api/patches/27989/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1503673046-30651-5-git-send-email-radu.nicolau@intel.com/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1503673046-30651-5-git-send-email-radu.nicolau@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1503673046-30651-5-git-send-email-radu.nicolau@intel.com",
    "date": "2017-08-25T14:57:25",
    "name": "[dpdk-dev,RFC,4/5] ixgbe: enable inline ipsec",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "67ee437a9dbbd8b6a812cb85f570ad5633e295c9",
    "submitter": {
        "id": 743,
        "url": "https://patches.dpdk.org/api/people/743/?format=api",
        "name": "Radu Nicolau",
        "email": "radu.nicolau@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1503673046-30651-5-git-send-email-radu.nicolau@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/27989/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/27989/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id C19857D83;\n\tFri, 25 Aug 2017 17:01:24 +0200 (CEST)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id 0480C7D22\n\tfor <dev@dpdk.org>; Fri, 25 Aug 2017 17:01:20 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby orsmga105.jf.intel.com with ESMTP; 25 Aug 2017 08:01:20 -0700",
            "from silpixa00383879.ir.intel.com (HELO\n\tsilpixa00383879.ger.corp.intel.com) ([10.237.223.127])\n\tby fmsmga005.fm.intel.com with ESMTP; 25 Aug 2017 08:01:18 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.41,426,1498546800\"; d=\"scan'208\";a=\"143899022\"",
        "From": "Radu Nicolau <radu.nicolau@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Radu Nicolau <radu.nicolau@intel.com>",
        "Date": "Fri, 25 Aug 2017 15:57:25 +0100",
        "Message-Id": "<1503673046-30651-5-git-send-email-radu.nicolau@intel.com>",
        "X-Mailer": "git-send-email 2.7.5",
        "In-Reply-To": "<1503673046-30651-1-git-send-email-radu.nicolau@intel.com>",
        "References": "<1503673046-30651-1-git-send-email-radu.nicolau@intel.com>",
        "Subject": "[dpdk-dev] [RFC PATCH 4/5] ixgbe: enable inline ipsec",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>\n---\n config/common_base                     |   1 +\n drivers/net/ixgbe/Makefile             |   4 +-\n drivers/net/ixgbe/ixgbe_ethdev.c       |   3 +\n drivers/net/ixgbe/ixgbe_ethdev.h       |  10 +-\n drivers/net/ixgbe/ixgbe_ipsec.c        | 617 +++++++++++++++++++++++++++++++++\n drivers/net/ixgbe/ixgbe_ipsec.h        | 142 ++++++++\n drivers/net/ixgbe/ixgbe_rxtx.c         |  33 +-\n drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c |  44 +++\n 8 files changed, 850 insertions(+), 4 deletions(-)\n create mode 100644 drivers/net/ixgbe/ixgbe_ipsec.c\n create mode 100644 drivers/net/ixgbe/ixgbe_ipsec.h",
    "diff": "diff --git a/config/common_base b/config/common_base\nindex 5e97a08..2084609 100644\n--- a/config/common_base\n+++ b/config/common_base\n@@ -179,6 +179,7 @@ CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n\n CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n\n CONFIG_RTE_IXGBE_INC_VECTOR=y\n CONFIG_RTE_LIBRTE_IXGBE_BYPASS=n\n+CONFIG_RTE_LIBRTE_IXGBE_IPSEC=y\n \n #\n # Compile burst-oriented I40E PMD driver\ndiff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile\nindex 5e57cb3..1180900 100644\n--- a/drivers/net/ixgbe/Makefile\n+++ b/drivers/net/ixgbe/Makefile\n@@ -118,11 +118,13 @@ SRCS-$(CONFIG_RTE_IXGBE_INC_VECTOR) += ixgbe_rxtx_vec_neon.c\n else\n SRCS-$(CONFIG_RTE_IXGBE_INC_VECTOR) += ixgbe_rxtx_vec_sse.c\n endif\n-\n ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_BYPASS),y)\n SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_bypass.c\n SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_82599_bypass.c\n endif\n+ifeq ($(CONFIG_RTE_LIBRTE_IXGBE_IPSEC),y)\n+SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_ipsec.c\n+endif\n SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += rte_pmd_ixgbe.c\n SRCS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe_tm.c\n \ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c\nindex 22171d8..73de5e6 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.c\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.c\n@@ -1135,6 +1135,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)\n \tPMD_INIT_FUNC_TRACE();\n \n \teth_dev->dev_ops = &ixgbe_eth_dev_ops;\n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\teth_dev->sec_ops = &ixgbe_security_ops;\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n \teth_dev->rx_pkt_burst = &ixgbe_recv_pkts;\n \teth_dev->tx_pkt_burst = &ixgbe_xmit_pkts;\n \teth_dev->tx_pkt_prepare = &ixgbe_prep_pkts;\ndiff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h\nindex caa50c8..d1a84e2 100644\n--- a/drivers/net/ixgbe/ixgbe_ethdev.h\n+++ b/drivers/net/ixgbe/ixgbe_ethdev.h\n@@ -38,6 +38,9 @@\n #include \"base/ixgbe_dcb_82599.h\"\n #include \"base/ixgbe_dcb_82598.h\"\n #include \"ixgbe_bypass.h\"\n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+#include \"ixgbe_ipsec.h\"\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n #include <rte_time.h>\n #include <rte_hash.h>\n #include <rte_pci.h>\n@@ -529,7 +532,9 @@ struct ixgbe_adapter {\n \tstruct ixgbe_filter_info    filter;\n \tstruct ixgbe_l2_tn_info     l2_tn;\n \tstruct ixgbe_bw_conf        bw_conf;\n-\n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\tstruct ixgbe_ipsec          ipsec;\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n \tbool rx_bulk_alloc_allowed;\n \tbool rx_vec_allowed;\n \tstruct rte_timecounter      systime_tc;\n@@ -586,6 +591,9 @@ struct ixgbe_adapter {\n #define IXGBE_DEV_PRIVATE_TO_TM_CONF(adapter) \\\n \t(&((struct ixgbe_adapter *)adapter)->tm_conf)\n \n+#define IXGBE_DEV_PRIVATE_TO_IPSEC(adapter)\\\n+\t(&((struct ixgbe_adapter *)adapter)->ipsec)\n+\n /*\n  * RX/TX function prototypes\n  */\ndiff --git a/drivers/net/ixgbe/ixgbe_ipsec.c b/drivers/net/ixgbe/ixgbe_ipsec.c\nnew file mode 100644\nindex 0000000..d866cd8\n--- /dev/null\n+++ b/drivers/net/ixgbe/ixgbe_ipsec.c\n@@ -0,0 +1,617 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *\t * Redistributions of source code must retain the above copyright\n+ *\t notice, this list of conditions and the following disclaimer.\n+ *\t * Redistributions in binary form must reproduce the above copyright\n+ *\t notice, this list of conditions and the following disclaimer in\n+ *\t the documentation and/or other materials provided with the\n+ *\t distribution.\n+ *\t * Neither the name of Intel Corporation nor the names of its\n+ *\t contributors may be used to endorse or promote products derived\n+ *\t from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <rte_ethdev.h>\n+#include <rte_ethdev_pci.h>\n+#include <rte_security.h>\n+#include <rte_ip.h>\n+#include <rte_jhash.h>\n+#include <rte_cryptodev_pmd.h>\n+\n+#include \"base/ixgbe_type.h\"\n+#include \"base/ixgbe_api.h\"\n+#include \"ixgbe_ethdev.h\"\n+#include \"ixgbe_ipsec.h\"\n+\n+\n+#define IXGBE_WAIT_RW(__reg, __rw)\t\t\t\\\n+{\t\t\t\t\t\t\t\\\n+\tIXGBE_WRITE_REG(hw, (__reg), reg);\t\t\\\n+\twhile ((IXGBE_READ_REG(hw, (__reg))) & (__rw))\t\\\n+\t;\t\t\t\t\t\t\\\n+}\n+#define IXGBE_WAIT_RREAD  IXGBE_WAIT_RW(IXGBE_IPSRXIDX, IPSRXIDX_READ)\n+#define IXGBE_WAIT_RWRITE IXGBE_WAIT_RW(IXGBE_IPSRXIDX, IPSRXIDX_WRITE)\n+#define IXGBE_WAIT_TREAD  IXGBE_WAIT_RW(IXGBE_IPSTXIDX, IPSRXIDX_READ)\n+#define IXGBE_WAIT_TWRITE IXGBE_WAIT_RW(IXGBE_IPSTXIDX, IPSRXIDX_WRITE)\n+\n+#define CMP_IP(a, b)\t\\\n+\t\t((a).ipv6[0] == (b).ipv6[0] && (a).ipv6[1] == (b).ipv6[1] && \\\n+\t\t(a).ipv6[2] == (b).ipv6[2] && (a).ipv6[3] == (b).ipv6[3])\n+\n+\n+static void\n+ixgbe_crypto_clear_ipsec_tables(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tint i = 0;\n+\n+\t/* clear Rx IP table*/\n+\tfor (i = 0; i < IPSEC_MAX_RX_IP_COUNT; i++) {\n+\t\tuint16_t index = i << 3;\n+\t\tuint32_t reg = IPSRXIDX_WRITE | IPSRXIDX_TABLE_IP | index;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(0), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(1), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(2), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(3), 0);\n+\t\tIXGBE_WAIT_RWRITE;\n+\t}\n+\n+\t/* clear Rx SPI and Rx/Tx SA tables*/\n+\tfor (i = 0; i < IPSEC_MAX_SA_COUNT; i++) {\n+\t\tuint32_t index = i << 3;\n+\t\tuint32_t reg = IPSRXIDX_WRITE | IPSRXIDX_TABLE_SPI | index;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXSPI, 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPIDX, 0);\n+\t\tIXGBE_WAIT_RWRITE;\n+\t\treg = IPSRXIDX_WRITE | IPSRXIDX_TABLE_KEY | index;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(0), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(1), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(2), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(3), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT, 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD, 0);\n+\t\tIXGBE_WAIT_RWRITE;\n+\t\treg = IPSRXIDX_WRITE | index;\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(0), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(1), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(2), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(3), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT, 0);\n+\t\tIXGBE_WAIT_TWRITE;\n+\t}\n+}\n+\n+static int\n+ixgbe_crypto_enable_ipsec(struct rte_eth_dev *dev)\n+{\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct rte_eth_link link;\n+\tuint32_t reg;\n+\n+\t/* Halt the data paths */\n+\treg = IXGBE_SECTXCTRL_TX_DIS;\n+\tIXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);\n+\treg = IXGBE_SECRXCTRL_RX_DIS;\n+\tIXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);\n+\n+\t/* Wait for Tx path to empty */\n+\tdo {\n+\t\trte_eth_link_get_nowait(dev->data->port_id, &link);\n+\t\tif (link.link_status != ETH_LINK_UP) {\n+\t\t\t/* Fix for HSD:4426139\n+\t\t\t * If the Tx FIFO has data but no link,\n+\t\t\t * we can't clear the Tx Sec block. So set MAC\n+\t\t\t * loopback before block clear\n+\t\t\t */\n+\t\t\treg = IXGBE_READ_REG(hw, IXGBE_MACC);\n+\t\t\treg |= IXGBE_MACC_FLU;\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_MACC, reg);\n+\n+\t\t\treg = IXGBE_READ_REG(hw, IXGBE_HLREG0);\n+\t\t\treg |= IXGBE_HLREG0_LPBK;\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);\n+\t\t\tstruct timespec time;\n+\t\t\ttime.tv_sec = 0;\n+\t\t\ttime.tv_nsec = 1000000 * 3;\n+\t\t\tnanosleep(&time, NULL);\n+\t\t}\n+\n+\t\treg = IXGBE_READ_REG(hw, IXGBE_SECTXSTAT);\n+\n+\t\trte_eth_link_get_nowait(dev->data->port_id, &link);\n+\t\tif (link.link_status != ETH_LINK_UP) {\n+\t\t\treg = IXGBE_READ_REG(hw, IXGBE_MACC);\n+\t\t\treg &= ~(IXGBE_MACC_FLU);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_MACC, reg);\n+\n+\t\t\treg = IXGBE_READ_REG(hw, IXGBE_HLREG0);\n+\t\t\treg &= ~(IXGBE_HLREG0_LPBK);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);\n+\t\t}\n+\t} while (!(reg & IXGBE_SECTXSTAT_SECTX_RDY));\n+\n+\t/* Wait for Rx path to empty*/\n+\tdo {\n+\t\treg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);\n+\t} while (!(reg & IXGBE_SECRXSTAT_SECRX_RDY));\n+\n+\t/* Set IXGBE_SECTXBUFFAF to 0x15 as required in the datasheet*/\n+\tIXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, 0x15);\n+\n+\t/* IFG needs to be set to 3 when we are using security. Otherwise a Tx\n+\t * hang will occur with heavy traffic.\n+\t */\n+\treg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);\n+\treg = (reg & 0xFFFFFFF0) | 0x3;\n+\tIXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);\n+\n+\treg = IXGBE_READ_REG(hw, IXGBE_HLREG0);\n+\treg |= IXGBE_HLREG0_TXCRCEN | IXGBE_HLREG0_RXCRCSTRP;\n+\tIXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);\n+\n+\t/* Enable the Tx crypto engine and restart the Tx data path;\n+\t * set the STORE_FORWARD bit for IPSec.\n+\t */\n+\tIXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_STORE_FORWARD);\n+\n+\t/* Enable the Rx crypto engine and restart the Rx data path*/\n+\tIXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, 0);\n+\n+\t/* Test if crypto was enabled */\n+\treg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);\n+\tif (reg != IXGBE_SECTXCTRL_STORE_FORWARD) {\n+\t\tPMD_DRV_LOG(ERR, \"Error enabling Tx Crypto\");\n+\t\treturn -1;\n+\t}\n+\treg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);\n+\tif (reg != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Error enabling Rx Crypto\");\n+\t\treturn -1;\n+\t}\n+\n+\tixgbe_crypto_clear_ipsec_tables(dev);\n+\n+\t/* create hash table*/\n+\t{\n+\t\tstruct ixgbe_ipsec *internals = IXGBE_DEV_PRIVATE_TO_IPSEC(\n+\t\t\t\tdev->data->dev_private);\n+\t\tstruct rte_hash_parameters params = { 0 };\n+\t\tparams.entries = IPSEC_MAX_SA_COUNT;\n+\t\tparams.key_len = sizeof(uint32_t);\n+\t\tparams.hash_func = rte_jhash;\n+\t\tparams.hash_func_init_val = 0;\n+\t\tparams.socket_id = rte_socket_id();\n+\t\tparams.name = \"tx_spi_sai_hash\";\n+\t\tinternals->tx_spi_sai_hash = rte_hash_create(&params);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+static int\n+ixgbe_crypto_add_sa(struct ixgbe_crypto_session *sess)\n+{\n+\tstruct rte_eth_dev *dev = sess->dev;\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_ipsec *priv = IXGBE_DEV_PRIVATE_TO_IPSEC(\n+\t\t\tdev->data->dev_private);\n+\tuint32_t reg;\n+\tint sa_index = -1;\n+\n+\tif (!(priv->flags & IS_INITIALIZED)) {\n+\t\tif (ixgbe_crypto_enable_ipsec(dev) == 0)\n+\t\t\tpriv->flags |= IS_INITIALIZED;\n+\t}\n+\n+\tif (sess->op == IXGBE_OP_AUTHENTICATED_DECRYPTION) {\n+\t\tint i, ip_index = -1;\n+\n+\t\t/* Find a match in the IP table*/\n+\t\tfor (i = 0; i < IPSEC_MAX_RX_IP_COUNT; i++) {\n+\t\t\tif (CMP_IP(priv->rx_ip_table[i].ip,\n+\t\t\t\t sess->dst_ip)) {\n+\t\t\t\tip_index = i;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* If no match, find a free entry in the IP table*/\n+\t\tif (ip_index < 0) {\n+\t\t\tfor (i = 0; i < IPSEC_MAX_RX_IP_COUNT; i++) {\n+\t\t\t\tif (priv->rx_ip_table[i].ref_count == 0) {\n+\t\t\t\t\tip_index = i;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Fail if no match and no free entries*/\n+\t\tif (ip_index < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"No free entry left \"\n+\t\t\t\t\t\"in the Rx IP table\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/* Find a free entry in the SA table*/\n+\t\tfor (i = 0; i < IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (priv->rx_sa_table[i].used == 0) {\n+\t\t\t\tsa_index = i;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* Fail if no free entries*/\n+\t\tif (sa_index < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"No free entry left in \"\n+\t\t\t\t\t\"the Rx SA table\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tpriv->rx_ip_table[ip_index].ip.ipv6[0] =\n+\t\t\t\trte_cpu_to_be_32(sess->dst_ip.ipv6[0]);\n+\t\tpriv->rx_ip_table[ip_index].ip.ipv6[1] =\n+\t\t\t\trte_cpu_to_be_32(sess->dst_ip.ipv6[1]);\n+\t\tpriv->rx_ip_table[ip_index].ip.ipv6[2] =\n+\t\t\t\trte_cpu_to_be_32(sess->dst_ip.ipv6[2]);\n+\t\tpriv->rx_ip_table[ip_index].ip.ipv6[3] =\n+\t\t\t\trte_cpu_to_be_32(sess->dst_ip.ipv6[3]);\n+\t\tpriv->rx_ip_table[ip_index].ref_count++;\n+\n+\t\tpriv->rx_sa_table[sa_index].spi =\n+\t\t\t\trte_cpu_to_be_32(sess->spi);\n+\t\tpriv->rx_sa_table[sa_index].ip_index = ip_index;\n+\t\tpriv->rx_sa_table[sa_index].key[3] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[0]);\n+\t\tpriv->rx_sa_table[sa_index].key[2] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[4]);\n+\t\tpriv->rx_sa_table[sa_index].key[1] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[8]);\n+\t\tpriv->rx_sa_table[sa_index].key[0] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[12]);\n+\t\tpriv->rx_sa_table[sa_index].salt =\n+\t\t\t\trte_cpu_to_be_32(sess->salt);\n+\t\tpriv->rx_sa_table[sa_index].mode = IPSRXMOD_VALID;\n+\t\tif (sess->op == IXGBE_OP_AUTHENTICATED_DECRYPTION)\n+\t\t\tpriv->rx_sa_table[sa_index].mode |=\n+\t\t\t\t\t(IPSRXMOD_PROTO | IPSRXMOD_DECRYPT);\n+\t\tif (sess->dst_ip.type == IPv6)\n+\t\t\tpriv->rx_sa_table[sa_index].mode |= IPSRXMOD_IPV6;\n+\t\tpriv->rx_sa_table[sa_index].used = 1;\n+\n+\t\t/* write IP table entry*/\n+\t\treg = IPSRXIDX_RX_EN | IPSRXIDX_WRITE\n+\t\t\t\t| IPSRXIDX_TABLE_IP | (ip_index << 3);\n+\t\tif (priv->rx_ip_table[ip_index].ip.type == IPv4) {\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(0), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(1), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(2), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(3),\n+\t\t\t\t\tpriv->rx_ip_table[ip_index].ip.ipv4);\n+\t\t} else {\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(0),\n+\t\t\t\t\tpriv->rx_ip_table[ip_index].ip.ipv6[0]);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(1),\n+\t\t\t\t\tpriv->rx_ip_table[ip_index].ip.ipv6[1]);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(2),\n+\t\t\t\t\tpriv->rx_ip_table[ip_index].ip.ipv6[2]);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(3),\n+\t\t\t\t\tpriv->rx_ip_table[ip_index].ip.ipv6[3]);\n+\t\t}\n+\t\tIXGBE_WAIT_RWRITE;\n+\n+\t\t/* write SPI table entry*/\n+\t\treg = IPSRXIDX_RX_EN | IPSRXIDX_WRITE\n+\t\t\t\t| IPSRXIDX_TABLE_SPI | (sa_index << 3);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXSPI,\n+\t\t\t\tpriv->rx_sa_table[sa_index].spi);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPIDX,\n+\t\t\t\tpriv->rx_sa_table[sa_index].ip_index);\n+\t\tIXGBE_WAIT_RWRITE;\n+\n+\t\t/* write Key table entry*/\n+\t\treg = IPSRXIDX_RX_EN | IPSRXIDX_WRITE\n+\t\t\t\t| IPSRXIDX_TABLE_KEY | (sa_index << 3);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(0),\n+\t\t\t\tpriv->rx_sa_table[sa_index].key[0]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(1),\n+\t\t\t\tpriv->rx_sa_table[sa_index].key[1]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(2),\n+\t\t\t\tpriv->rx_sa_table[sa_index].key[2]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(3),\n+\t\t\t\tpriv->rx_sa_table[sa_index].key[3]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT,\n+\t\t\t\tpriv->rx_sa_table[sa_index].salt);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD,\n+\t\t\t\tpriv->rx_sa_table[sa_index].mode);\n+\t\tIXGBE_WAIT_RWRITE;\n+\n+\t} else { /* sess->dir == RTE_CRYPTO_OUTBOUND */\n+\t\tint i;\n+\n+\t\t/* Find a free entry in the SA table*/\n+\t\tfor (i = 0; i < IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (priv->tx_sa_table[i].used == 0) {\n+\t\t\t\tsa_index = i;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* Fail if no free entries*/\n+\t\tif (sa_index < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"No free entry left in \"\n+\t\t\t\t\t\"the Tx SA table\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tpriv->tx_sa_table[sa_index].spi =\n+\t\t\t\trte_cpu_to_be_32(sess->spi);\n+\t\tpriv->tx_sa_table[sa_index].key[3] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[0]);\n+\t\tpriv->tx_sa_table[sa_index].key[2] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[4]);\n+\t\tpriv->tx_sa_table[sa_index].key[1] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[8]);\n+\t\tpriv->tx_sa_table[sa_index].key[0] =\n+\t\t\t\trte_cpu_to_be_32(*(uint32_t *)&sess->key[12]);\n+\t\tpriv->tx_sa_table[sa_index].salt =\n+\t\t\t\trte_cpu_to_be_32(sess->salt);\n+\n+\t\treg = IPSRXIDX_RX_EN | IPSRXIDX_WRITE | (sa_index << 3);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(0),\n+\t\t\t\tpriv->tx_sa_table[sa_index].key[0]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(1),\n+\t\t\t\tpriv->tx_sa_table[sa_index].key[1]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(2),\n+\t\t\t\tpriv->tx_sa_table[sa_index].key[2]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(3),\n+\t\t\t\tpriv->tx_sa_table[sa_index].key[3]);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT,\n+\t\t\t\tpriv->tx_sa_table[sa_index].salt);\n+\t\tIXGBE_WAIT_TWRITE;\n+\n+\t\trte_hash_add_key_data(priv->tx_spi_sai_hash,\n+\t\t\t\t&priv->tx_sa_table[sa_index].spi,\n+\t\t\t\t(void *)(uint64_t)sa_index);\n+\t\tpriv->tx_sa_table[i].used = 1;\n+\t\tsess->sa_index = sa_index;\n+\t}\n+\n+\treturn sa_index;\n+}\n+\n+static int\n+ixgbe_crypto_remove_sa(struct rte_eth_dev *dev,\n+\t\t     struct ixgbe_crypto_session *sess)\n+{\n+\tstruct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);\n+\tstruct ixgbe_ipsec *priv = IXGBE_DEV_PRIVATE_TO_IPSEC(\n+\t\t\tdev->data->dev_private);\n+\tuint32_t reg;\n+\tint sa_index = -1;\n+\n+\tif (sess->op == IXGBE_OP_AUTHENTICATED_DECRYPTION) {\n+\t\tint i, ip_index = -1;\n+\n+\t\t/* Find a match in the IP table*/\n+\t\tfor (i = 0; i < IPSEC_MAX_RX_IP_COUNT; i++) {\n+\t\t\tif (CMP_IP(priv->rx_ip_table[i].ip, sess->dst_ip)) {\n+\t\t\t\tip_index = i;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Fail if no match*/\n+\t\tif (ip_index < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Entry not found in the Rx IP table\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/* Find a free entry in the SA table*/\n+\t\tfor (i = 0; i < IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (priv->rx_sa_table[i].spi ==\n+\t\t\t\t\trte_cpu_to_be_32(sess->spi)) {\n+\t\t\t\tsa_index = i;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\t/* Fail if no match*/\n+\t\tif (sa_index < 0) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Entry not found in the Rx SA table\\n\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t/* Disable and clear Rx SPI and key table table entryes*/\n+\t\treg = IPSRXIDX_WRITE | IPSRXIDX_TABLE_SPI | (sa_index << 3);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXSPI, 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPIDX, 0);\n+\t\tIXGBE_WAIT_RWRITE;\n+\t\treg = IPSRXIDX_WRITE | IPSRXIDX_TABLE_KEY | (sa_index << 3);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(0), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(1), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(2), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(3), 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT, 0);\n+\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD, 0);\n+\t\tIXGBE_WAIT_RWRITE;\n+\t\tpriv->rx_sa_table[sa_index].used = 0;\n+\n+\t\t/* If last used then clear the IP table entry*/\n+\t\tpriv->rx_ip_table[ip_index].ref_count--;\n+\t\tif (priv->rx_ip_table[ip_index].ref_count == 0) {\n+\t\t\treg = IPSRXIDX_WRITE | IPSRXIDX_TABLE_IP\n+\t\t\t\t\t| (ip_index << 3);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(0), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(1), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(2), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(3), 0);\n+\t\t}\n+\t\t} else { /* sess->dir == RTE_CRYPTO_OUTBOUND */\n+\t\t\tint i;\n+\n+\t\t\t/* Find a match in the SA table*/\n+\t\t\tfor (i = 0; i < IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\t\tif (priv->tx_sa_table[i].spi ==\n+\t\t\t\t\t\trte_cpu_to_be_32(sess->spi)) {\n+\t\t\t\t\tsa_index = i;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\t/* Fail if no match entries*/\n+\t\t\tif (sa_index < 0) {\n+\t\t\t\tPMD_DRV_LOG(ERR, \"Entry not found in the \"\n+\t\t\t\t\t\t\"Tx SA table\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\treg = IPSRXIDX_WRITE | (sa_index << 3);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(0), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(1), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(2), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(3), 0);\n+\t\t\tIXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT, 0);\n+\t\t\tIXGBE_WAIT_TWRITE;\n+\n+\t\t\tpriv->tx_sa_table[sa_index].used = 0;\n+\t\t\trte_hash_del_key(priv->tx_spi_sai_hash,\n+\t\t\t\t\t&priv->tx_sa_table[sa_index].spi);\n+\t\t}\n+\n+\treturn 0;\n+}\n+\n+static int\n+ixgbe_crypto_create_session(void *dev,\n+\t\tstruct rte_security_sess_conf *sess_conf,\n+\t\tstruct rte_security_session *sess,\n+\t\tstruct rte_mempool *mempool)\n+{\n+\tstruct ixgbe_crypto_session *session = NULL;\n+\tstruct rte_security_ipsec_xform *ipsec_xform = sess_conf->ipsec_xform;\n+\n+\tif (rte_mempool_get(mempool, (void **)&session)) {\n+\t\tPMD_DRV_LOG(ERR, \"Cannot get object from session mempool\");\n+\t\treturn -ENOMEM;\n+\t}\n+\tif (ipsec_xform->aead_alg != RTE_CRYPTO_AEAD_AES_GCM) {\n+\t\tPMD_DRV_LOG(ERR, \"Unsupported IPsec mode\\n\");\n+\t\treturn -ENOTSUP;\n+\t}\n+\n+\tsession->op = (ipsec_xform->op == RTE_SECURITY_IPSEC_OP_DECAP) ?\n+\t\t\tIXGBE_OP_AUTHENTICATED_DECRYPTION :\n+\t\t\tIXGBE_OP_AUTHENTICATED_ENCRYPTION;\n+\tsession->key = ipsec_xform->aead_key.data;\n+\tmemcpy(&session->salt,\n+\t     &ipsec_xform->aead_key.data[ipsec_xform->aead_key.length], 4);\n+\tsession->spi = ipsec_xform->spi;\n+\n+\tif (ipsec_xform->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {\n+\t\tuint32_t sip = ipsec_xform->tunnel.ipv4.src_ip.s_addr;\n+\t\tuint32_t dip = ipsec_xform->tunnel.ipv4.dst_ip.s_addr;\n+\t\tsession->src_ip.type = IPv4;\n+\t\tsession->dst_ip.type = IPv4;\n+\t\tsession->src_ip.ipv4 = rte_cpu_to_be_32(sip);\n+\t\tsession->dst_ip.ipv4 = rte_cpu_to_be_32(dip);\n+\n+\t} else {\n+\t\tuint32_t *sip = (uint32_t *)&ipsec_xform->tunnel.ipv6.src_addr;\n+\t\tuint32_t *dip = (uint32_t *)&ipsec_xform->tunnel.ipv6.dst_addr;\n+\t\tsession->src_ip.type = IPv6;\n+\t\tsession->dst_ip.type = IPv6;\n+\t\tsession->src_ip.ipv6[0] = rte_cpu_to_be_32(sip[0]);\n+\t\tsession->src_ip.ipv6[1] = rte_cpu_to_be_32(sip[1]);\n+\t\tsession->src_ip.ipv6[2] = rte_cpu_to_be_32(sip[2]);\n+\t\tsession->src_ip.ipv6[3] = rte_cpu_to_be_32(sip[3]);\n+\t\tsession->dst_ip.ipv6[0] = rte_cpu_to_be_32(dip[0]);\n+\t\tsession->dst_ip.ipv6[1] = rte_cpu_to_be_32(dip[1]);\n+\t\tsession->dst_ip.ipv6[2] = rte_cpu_to_be_32(dip[2]);\n+\t\tsession->dst_ip.ipv6[3] = rte_cpu_to_be_32(dip[3]);\n+\t}\n+\n+\tsession->dev = (struct rte_eth_dev *)dev;\n+\tset_sec_session_private_data(sess, 0, session);\n+\n+\tif (ixgbe_crypto_add_sa(session)) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to add SA\\n\");\n+\t\treturn -EPERM;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void\n+ixgbe_crypto_remove_session(void *dev,\n+\t\tstruct rte_security_session *session)\n+{\n+\tstruct ixgbe_crypto_session *sess =\n+\t\t(struct ixgbe_crypto_session *)\n+\t\tget_sec_session_private_data(session, 0);\n+\tif (dev != sess->dev) {\n+\t\tPMD_DRV_LOG(ERR, \"Session not bound to this device\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (ixgbe_crypto_remove_sa(dev, sess)) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to remove session\\n\");\n+\t\treturn;\n+\t}\n+\n+\trte_free(session);\n+}\n+\n+uint64_t\n+ixgbe_crypto_get_txdesc_flags(uint16_t port_id, struct rte_mbuf *mb) {\n+\tstruct rte_eth_dev *dev = &rte_eth_devices[port_id];\n+\tstruct ixgbe_ipsec *priv =\n+\t\t\tIXGBE_DEV_PRIVATE_TO_IPSEC(dev->data->dev_private);\n+\tstruct ipv4_hdr *ip4 =\n+\t\t\trte_pktmbuf_mtod_offset(mb, struct ipv4_hdr*,\n+\t\t\t\t\t\tsizeof(struct ether_hdr));\n+\tuint32_t spi = 0;\n+\tuintptr_t sa_index;\n+\tstruct ixgbe_crypto_tx_desc_metadata mdata = {0};\n+\n+\tif (ip4->version_ihl == 0x45)\n+\t\tspi = *rte_pktmbuf_mtod_offset(mb, uint32_t*,\n+\t\t\t\t\tsizeof(struct ether_hdr) +\n+\t\t\t\t\tsizeof(struct ipv4_hdr));\n+\telse\n+\t\tspi = *rte_pktmbuf_mtod_offset(mb, uint32_t*,\n+\t\t\t\t\tsizeof(struct ether_hdr) +\n+\t\t\t\t\tsizeof(struct ipv6_hdr));\n+\n+\tif (priv->tx_spi_sai_hash &&\n+\t\t\trte_hash_lookup_data(priv->tx_spi_sai_hash, &spi,\n+\t\t\t\t\t(void **)&sa_index) == 0) {\n+\t\tmdata.enc = 1;\n+\t\tmdata.sa_idx = (uint32_t)sa_index;\n+\t\tmdata.pad_len = *rte_pktmbuf_mtod_offset(mb, uint8_t *,\n+\t\t\t\t\trte_pktmbuf_pkt_len(mb) - 18);\n+\t}\n+\n+\treturn mdata.data;\n+}\n+\n+\n+struct rte_security_ops ixgbe_security_ops = {\n+\t\t.session_configure = ixgbe_crypto_create_session,\n+\t\t.session_clear = ixgbe_crypto_remove_session,\n+};\ndiff --git a/drivers/net/ixgbe/ixgbe_ipsec.h b/drivers/net/ixgbe/ixgbe_ipsec.h\nnew file mode 100644\nindex 0000000..fd479eb\n--- /dev/null\n+++ b/drivers/net/ixgbe/ixgbe_ipsec.h\n@@ -0,0 +1,142 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef IXGBE_IPSEC_H_\n+#define IXGBE_IPSEC_H_\n+\n+#include <rte_security.h>\n+\n+#define IPSRXIDX_RX_EN                                    0x00000001\n+#define IPSRXIDX_TABLE_IP                                 0x00000002\n+#define IPSRXIDX_TABLE_SPI                                0x00000004\n+#define IPSRXIDX_TABLE_KEY                                0x00000006\n+#define IPSRXIDX_WRITE                                    0x80000000\n+#define IPSRXIDX_READ                                     0x40000000\n+#define IPSRXMOD_VALID                                    0x00000001\n+#define IPSRXMOD_PROTO                                    0x00000004\n+#define IPSRXMOD_DECRYPT                                  0x00000008\n+#define IPSRXMOD_IPV6                                     0x00000010\n+#define IXGBE_ADVTXD_POPTS_IPSEC                          0x00000400\n+#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP                 0x00002000\n+#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN               0x00004000\n+#define IXGBE_RXDADV_IPSEC_STATUS_SECP                    0x00020000\n+#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK                 0x18000000\n+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL         0x08000000\n+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH           0x10000000\n+#define IXGBE_RXDADV_IPSEC_ERROR_AUTHENTICATION_FAILED    0x18000000\n+\n+#define IPSEC_MAX_RX_IP_COUNT           128\n+#define IPSEC_MAX_SA_COUNT              1024\n+\n+enum ixgbe_operation {\n+\tIXGBE_OP_AUTHENTICATED_ENCRYPTION, IXGBE_OP_AUTHENTICATED_DECRYPTION\n+};\n+\n+enum ixgbe_gcm_key {\n+\tIXGBE_GCM_KEY_128, IXGBE_GCM_KEY_256\n+};\n+\n+/**\n+ * Generic IP address structure\n+ * TODO: Find better location for this rte_net.h possibly.\n+ **/\n+struct ipaddr {\n+\tenum ipaddr_type {\n+\t\tIPv4, IPv6\n+\t} type;\n+\t/**< IP Address Type - IPv4/IPv6 */\n+\n+\tunion {\n+\t\tuint32_t ipv4;\n+\t\tuint32_t ipv6[4];\n+\t};\n+};\n+\n+/** inline crypto crypto private session structure */\n+struct ixgbe_crypto_session {\n+\tenum ixgbe_operation op;\n+\tuint8_t *key;\n+\tuint32_t salt;\n+\tuint32_t sa_index;\n+\tuint32_t spi;\n+\tstruct ipaddr src_ip;\n+\tstruct ipaddr dst_ip;\n+\tstruct rte_eth_dev *dev;\n+} __rte_cache_aligned;\n+\n+struct ixgbe_crypto_rx_ip_table {\n+\tstruct ipaddr ip;\n+\tuint16_t ref_count;\n+};\n+struct ixgbe_crypto_rx_sa_table {\n+\tuint32_t spi;\n+\tuint32_t ip_index;\n+\tuint32_t key[4];\n+\tuint32_t salt;\n+\tuint8_t mode;\n+\tuint8_t used;\n+};\n+\n+struct ixgbe_crypto_tx_sa_table {\n+\tuint32_t spi;\n+\tuint32_t key[4];\n+\tuint32_t salt;\n+\tuint8_t used;\n+};\n+\n+struct ixgbe_crypto_tx_desc_metadata {\n+\tunion {\n+\t\tuint64_t data;\n+\t\tstruct {\n+\t\t\tuint32_t sa_idx;\n+\t\t\tuint8_t pad_len;\n+\t\t\tuint8_t enc;\n+\t\t};\n+\t};\n+};\n+\n+struct ixgbe_ipsec {\n+#define IS_INITIALIZED (1 << 0)\n+\tuint8_t flags;\n+\tstruct ixgbe_crypto_rx_ip_table rx_ip_table[IPSEC_MAX_RX_IP_COUNT];\n+\tstruct ixgbe_crypto_rx_sa_table rx_sa_table[IPSEC_MAX_SA_COUNT];\n+\tstruct ixgbe_crypto_tx_sa_table tx_sa_table[IPSEC_MAX_SA_COUNT];\n+\tstruct rte_hash *tx_spi_sai_hash;\n+};\n+\n+extern struct rte_security_ops ixgbe_security_ops;\n+\n+uint64_t ixgbe_crypto_get_txdesc_flags(uint16_t port_id, struct rte_mbuf *mb);\n+\n+\n+#endif /*IXGBE_IPSEC_H_*/\ndiff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c\nindex 64bff25..76be27a 100644\n--- a/drivers/net/ixgbe/ixgbe_rxtx.c\n+++ b/drivers/net/ixgbe/ixgbe_rxtx.c\n@@ -395,7 +395,8 @@ ixgbe_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,\n static inline void\n ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,\n \t\tvolatile struct ixgbe_adv_tx_context_desc *ctx_txd,\n-\t\tuint64_t ol_flags, union ixgbe_tx_offload tx_offload)\n+\t\tuint64_t ol_flags, union ixgbe_tx_offload tx_offload,\n+\t\t__rte_unused struct rte_mbuf *mb)\n {\n \tuint32_t type_tucmd_mlhl;\n \tuint32_t mss_l4len_idx = 0;\n@@ -479,6 +480,20 @@ ixgbe_set_xmit_ctx(struct ixgbe_tx_queue *txq,\n \t\tseqnum_seed |= tx_offload.l2_len\n \t\t\t       << IXGBE_ADVTXD_TUNNEL_LEN;\n \t}\n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\tif (mb->ol_flags & PKT_TX_SECURITY_OFFLOAD) {\n+\t\tstruct ixgbe_crypto_tx_desc_metadata mdata = {\n+\t\t\t.data = ixgbe_crypto_get_txdesc_flags(txq->port_id, mb),\n+\t\t};\n+\t\tseqnum_seed |=\n+\t\t\t(IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK & mdata.sa_idx);\n+\t\ttype_tucmd_mlhl |= mdata.enc ?\n+\t\t\t(IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |\n+\t\t\t\tIXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN) : 0;\n+\t\ttype_tucmd_mlhl |=\n+\t\t\t(mdata.pad_len & IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK);\n+\t}\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n \n \ttxq->ctx_cache[ctx_idx].flags = ol_flags;\n \ttxq->ctx_cache[ctx_idx].tx_offload.data[0]  =\n@@ -855,7 +870,7 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\t\t}\n \n \t\t\t\tixgbe_set_xmit_ctx(txq, ctx_txd, tx_ol_req,\n-\t\t\t\t\ttx_offload);\n+\t\t\t\t\ttx_offload, tx_pkt);\n \n \t\t\t\ttxe->last_id = tx_last;\n \t\t\t\ttx_id = txe->next_id;\n@@ -872,7 +887,13 @@ ixgbe_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,\n \t\t\tolinfo_status |= ctx << IXGBE_ADVTXD_IDX_SHIFT;\n \t\t}\n \n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\t\tolinfo_status |= ((pkt_len << IXGBE_ADVTXD_PAYLEN_SHIFT) |\n+\t\t\t\t(((ol_flags & PKT_TX_SECURITY_OFFLOAD) != 0)\n+\t\t\t\t\t* IXGBE_ADVTXD_POPTS_IPSEC));\n+#else /* RTE_LIBRTE_IXGBE_IPSEC */\n \t\tolinfo_status |= (pkt_len << IXGBE_ADVTXD_PAYLEN_SHIFT);\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n \n \t\tm_seg = tx_pkt;\n \t\tdo {\n@@ -1447,6 +1468,14 @@ rx_desc_error_to_pkt_flags(uint32_t rx_status)\n \t\tpkt_flags |= PKT_RX_EIP_CKSUM_BAD;\n \t}\n \n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\tif (rx_status & IXGBE_RXD_STAT_SECP) {\n+\t\tpkt_flags |= PKT_RX_SECURITY_OFFLOAD;\n+\t\tif (rx_status & IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG)\n+\t\t\tpkt_flags |= PKT_RX_SECURITY_OFFLOAD_FAILED;\n+\t}\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n+\n \treturn pkt_flags;\n }\n \ndiff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c\nindex e704a7f..8673a01 100644\n--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c\n+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c\n@@ -128,6 +128,9 @@ desc_to_olflags_v(__m128i descs[4], __m128i mbuf_init, uint8_t vlan_flags,\n {\n \t__m128i ptype0, ptype1, vtag0, vtag1, csum;\n \t__m128i rearm0, rearm1, rearm2, rearm3;\n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\t__m128i sterr0, sterr1, sterr2, sterr3, tmp1, tmp2;\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n \n \t/* mask everything except rss type */\n \tconst __m128i rsstype_msk = _mm_set_epi16(\n@@ -174,6 +177,19 @@ desc_to_olflags_v(__m128i descs[4], __m128i mbuf_init, uint8_t vlan_flags,\n \t\t0, PKT_RX_L4_CKSUM_GOOD >> sizeof(uint8_t), 0,\n \t\tPKT_RX_L4_CKSUM_GOOD >> sizeof(uint8_t));\n \n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\tconst __m128i ipsec_sterr_msk = _mm_set_epi32(\n+\t\t0, IXGBE_RXD_STAT_SECP | IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG,\n+\t\t0, 0);\n+\tconst __m128i ipsec_proc_msk  = _mm_set_epi32(\n+\t\t0, IXGBE_RXD_STAT_SECP, 0, 0);\n+\tconst __m128i ipsec_err_flag  = _mm_set_epi32(\n+\t\t0, PKT_RX_SECURITY_OFFLOAD_FAILED | PKT_RX_SECURITY_OFFLOAD,\n+\t\t0, 0);\n+\tconst __m128i ipsec_proc_flag = _mm_set_epi32(\n+\t\t0, PKT_RX_SECURITY_OFFLOAD, 0, 0);\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n+\n \tptype0 = _mm_unpacklo_epi16(descs[0], descs[1]);\n \tptype1 = _mm_unpacklo_epi16(descs[2], descs[3]);\n \tvtag0 = _mm_unpackhi_epi16(descs[0], descs[1]);\n@@ -221,6 +237,34 @@ desc_to_olflags_v(__m128i descs[4], __m128i mbuf_init, uint8_t vlan_flags,\n \trearm2 = _mm_blend_epi16(mbuf_init, _mm_slli_si128(vtag1, 4), 0x10);\n \trearm3 = _mm_blend_epi16(mbuf_init, _mm_slli_si128(vtag1, 2), 0x10);\n \n+#ifdef RTE_LIBRTE_IXGBE_IPSEC\n+\t/*inline ipsec, extract the flags from the descriptors*/\n+\tsterr0 = _mm_and_si128(descs[0], ipsec_sterr_msk);\n+\tsterr1 = _mm_and_si128(descs[1], ipsec_sterr_msk);\n+\tsterr2 = _mm_and_si128(descs[2], ipsec_sterr_msk);\n+\tsterr3 = _mm_and_si128(descs[3], ipsec_sterr_msk);\n+\ttmp1 = _mm_cmpeq_epi32(sterr0, ipsec_sterr_msk);\n+\ttmp2 = _mm_cmpeq_epi32(sterr0, ipsec_proc_msk);\n+\tsterr0 = _mm_or_si128(_mm_and_si128(tmp1, ipsec_err_flag),\n+\t\t\t\t_mm_and_si128(tmp2, ipsec_proc_flag));\n+\ttmp1 = _mm_cmpeq_epi32(sterr1, ipsec_sterr_msk);\n+\ttmp2 = _mm_cmpeq_epi32(sterr1, ipsec_proc_msk);\n+\tsterr1 = _mm_or_si128(_mm_and_si128(tmp1, ipsec_err_flag),\n+\t\t\t\t_mm_and_si128(tmp2, ipsec_proc_flag));\n+\ttmp1 = _mm_cmpeq_epi32(sterr2, ipsec_sterr_msk);\n+\ttmp2 = _mm_cmpeq_epi32(sterr2, ipsec_proc_msk);\n+\tsterr2 = _mm_or_si128(_mm_and_si128(tmp1, ipsec_err_flag),\n+\t\t\t\t_mm_and_si128(tmp2, ipsec_proc_flag));\n+\ttmp1 = _mm_cmpeq_epi32(sterr3, ipsec_sterr_msk);\n+\ttmp2 = _mm_cmpeq_epi32(sterr3, ipsec_proc_msk);\n+\tsterr3 = _mm_or_si128(_mm_and_si128(tmp1, ipsec_err_flag),\n+\t\t\t\t_mm_and_si128(tmp2, ipsec_proc_flag));\n+\trearm0 = _mm_or_si128(rearm0, sterr0);\n+\trearm1 = _mm_or_si128(rearm1, sterr1);\n+\trearm2 = _mm_or_si128(rearm2, sterr2);\n+\trearm3 = _mm_or_si128(rearm3, sterr3);\n+#endif /* RTE_LIBRTE_IXGBE_IPSEC */\n+\n \t/* write the rearm data and the olflags in one write */\n \tRTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=\n \t\t\toffsetof(struct rte_mbuf, rearm_data) + 8);\n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "4/5"
    ]
}