get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 847671,
    "url": "http://patchwork.ozlabs.org/api/patches/847671/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1513121823-27944-6-git-send-email-shannon.nelson@oracle.com/",
    "project": {
        "id": 46,
        "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api",
        "name": "Intel Wired Ethernet development",
        "link_name": "intel-wired-lan",
        "list_id": "intel-wired-lan.osuosl.org",
        "list_email": "intel-wired-lan@osuosl.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1513121823-27944-6-git-send-email-shannon.nelson@oracle.com>",
    "list_archive_url": null,
    "date": "2017-12-12T23:36:58",
    "name": "[v2,next-queue,05/10] ixgbe: add ipsec offload add and remove SA",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "d84ee382930bb6327242c27d9734c45eaa9ad959",
    "submitter": {
        "id": 70766,
        "url": "http://patchwork.ozlabs.org/api/people/70766/?format=api",
        "name": "Shannon Nelson",
        "email": "shannon.nelson@oracle.com"
    },
    "delegate": {
        "id": 68,
        "url": "http://patchwork.ozlabs.org/api/users/68/?format=api",
        "username": "jtkirshe",
        "first_name": "Jeff",
        "last_name": "Kirsher",
        "email": "jeffrey.t.kirsher@intel.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1513121823-27944-6-git-send-email-shannon.nelson@oracle.com/mbox/",
    "series": [
        {
            "id": 18198,
            "url": "http://patchwork.ozlabs.org/api/series/18198/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=18198",
            "date": "2017-12-12T23:36:53",
            "name": "ixgbe: Add ipsec offload",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/18198/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/847671/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/847671/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@osuosl.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "intel-wired-lan@lists.osuosl.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "intel-wired-lan@lists.osuosl.org"
        ],
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.136; helo=silver.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=oracle.com header.i=@oracle.com\n\theader.b=\"p+HJfHRO\"; dkim-atps=neutral"
        ],
        "Received": [
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3yxGT55CXHz9t3R\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed, 13 Dec 2017 10:37:29 +1100 (AEDT)",
            "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id B02212FCF1;\n\tTue, 12 Dec 2017 23:37:27 +0000 (UTC)",
            "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id beGyvXlEAWGG; Tue, 12 Dec 2017 23:37:25 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id 027C12FC67;\n\tTue, 12 Dec 2017 23:37:25 +0000 (UTC)",
            "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id D5FDC1BF54B\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Dec 2017 23:37:23 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id D1D87882F3\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Dec 2017 23:37:23 +0000 (UTC)",
            "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id Y3LUVEFmb9Pt for <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Dec 2017 23:37:22 +0000 (UTC)",
            "from userp2120.oracle.com (userp2120.oracle.com [156.151.31.85])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id CE34888319\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tTue, 12 Dec 2017 23:37:22 +0000 (UTC)",
            "from pps.filterd (userp2120.oracle.com [127.0.0.1])\n\tby userp2120.oracle.com (8.16.0.21/8.16.0.21) with SMTP id\n\tvBCNQs3J095614; Tue, 12 Dec 2017 23:37:21 GMT",
            "from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234])\n\tby userp2120.oracle.com with ESMTP id 2etrm3g4nr-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256\n\tverify=OK); Tue, 12 Dec 2017 23:37:20 +0000",
            "from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236])\n\tby aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id\n\tvBCNbJMq016313\n\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256\n\tverify=OK); Tue, 12 Dec 2017 23:37:20 GMT",
            "from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7])\n\tby aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id vBCNbJb9017528; \n\tTue, 12 Dec 2017 23:37:19 GMT",
            "from slnelson-mint18.us.oracle.com (/10.159.225.160)\n\tby default (Oracle Beehive Gateway v4.0)\n\twith ESMTP ; Tue, 12 Dec 2017 15:37:19 -0800"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com;\n\th=from : to : cc :\n\tsubject : date : message-id : in-reply-to : references;\n\ts=corp-2017-10-26; \n\tbh=9o8gzWxbo5xf433yzYNI1Hqt8AsVMDRK5tjlbti4mTU=;\n\tb=p+HJfHRORaLYLAnaRmZOx8cME1G7Mid15gPOXDdZqyxW2/YwPTGM4UpCCQ5Hr7eK+7JV\n\tx8/55GrwUXuhK9cml7ziwYtgWEuab29pVbJG3g8hRV9qYUapxdNsrQKs2ucK5VOd1HVp\n\tdBJGzPC6qUcwWZwLMvUS5A4wE45Mewn5k7zB8Qgp0A7Og8wvVVo2YB55ZIv/v8AahD5g\n\tDtAJhyErtFXqIubtxNvp2WzZFq+lVXjxsZWzi6u6EKW+XrX58QOJ17LtIB10PGHffc9a\n\t7rVH1ww7jW/CMmxjVsW6AnX0FcCQi7uYyAt+spC3AdsrvZi3l9m8etGktxRTErGS2/H7\n\tiQ== ",
        "From": "Shannon Nelson <shannon.nelson@oracle.com>",
        "To": "intel-wired-lan@lists.osuosl.org, jeffrey.t.kirsher@intel.com",
        "Date": "Tue, 12 Dec 2017 15:36:58 -0800",
        "Message-Id": "<1513121823-27944-6-git-send-email-shannon.nelson@oracle.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1513121823-27944-1-git-send-email-shannon.nelson@oracle.com>",
        "References": "<1513121823-27944-1-git-send-email-shannon.nelson@oracle.com>",
        "X-Proofpoint-Virus-Version": "vendor=nai engine=5900 definitions=8743\n\tsignatures=668646",
        "X-Proofpoint-Spam-Details": "rule=notspam policy=default score=0 suspectscore=0\n\tmalwarescore=0\n\tphishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999\n\tadultscore=0 classifier=spam adjust=0 reason=mlx scancount=1\n\tengine=8.0.1-1711220000 definitions=main-1712120331",
        "Subject": "[Intel-wired-lan] [PATCH v2 next-queue 05/10] ixgbe: add ipsec\n\toffload add and remove SA",
        "X-BeenThere": "intel-wired-lan@osuosl.org",
        "X-Mailman-Version": "2.1.24",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>",
        "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>",
        "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>",
        "Cc": "steffen.klassert@secunet.com, netdev@vger.kernel.org,\n\tsowmini.varadhan@oracle.com",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "intel-wired-lan-bounces@osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>"
    },
    "content": "Add the functions for setting up and removing offloaded SAs (Security\nAssociations) with the x540 hardware.  We set up the callback structure\nbut we don't yet set the hardware feature bit to be sure the XFRM service\nwon't actually try to use us for an offload yet.\n\nThe software tables are made up to mimic the hardware tables to make it\neasier to track what's in the hardware, and the SA table index is used\nfor the XFRM offload handle.  However, there is a hashing field in the\nRx SA tracking that will be used to facilitate faster table searches in\nthe Rx fast path.\n\nSigned-off-by: Shannon Nelson <shannon.nelson@oracle.com>\n---\nv2: fix use of num_rx_sa that should be num_tx_sa\n    change aes_gcm_name to a const array\n    tighten up the key parsing code\n    add another label to the init error handling\n    move table deletion to a separate function\n\n drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   2 +\n drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 394 ++++++++++++++++++++++++-\n drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +\n 3 files changed, 396 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\nindex 9487750..8f41508 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h\n@@ -1009,7 +1009,9 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,\n \t\t       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);\n #ifdef CONFIG_XFRM_OFFLOAD\n void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);\n+void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);\n #else\n static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };\n+static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };\n #endif /* CONFIG_XFRM_OFFLOAD */\n #endif /* _IXGBE_H_ */\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c\nindex a45e6b7..72b1d29 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c\n@@ -26,6 +26,8 @@\n  ******************************************************************************/\n \n #include \"ixgbe.h\"\n+#include <net/xfrm.h>\n+#include <crypto/aead.h>\n \n /**\n  * ixgbe_ipsec_set_tx_sa - set the Tx SA registers\n@@ -131,6 +133,7 @@ static void ixgbe_ipsec_set_rx_ip(struct ixgbe_hw *hw, u16 idx, __be32 addr[])\n  **/\n void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)\n {\n+\tstruct ixgbe_ipsec *ipsec = adapter->ipsec;\n \tstruct ixgbe_hw *hw = &adapter->hw;\n \tu32 buf[4] = {0, 0, 0, 0};\n \tu16 idx;\n@@ -149,6 +152,9 @@ void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)\n \t\tixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);\n \t\tixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);\n \t}\n+\n+\tipsec->num_rx_sa = 0;\n+\tipsec->num_tx_sa = 0;\n }\n \n /**\n@@ -293,11 +299,397 @@ static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)\n }\n \n /**\n+ * ixgbe_ipsec_find_empty_idx - find the first unused security parameter index\n+ * @ipsec: pointer to ipsec struct\n+ * @rxtable: true if we need to look in the Rx table\n+ *\n+ * Returns the first unused index in either the Rx or Tx SA table\n+ **/\n+static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable)\n+{\n+\tu32 i;\n+\n+\tif (rxtable) {\n+\t\tif (ipsec->num_rx_sa == IXGBE_IPSEC_MAX_SA_COUNT)\n+\t\t\treturn -ENOSPC;\n+\n+\t\t/* search rx sa table */\n+\t\tfor (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (!ipsec->rx_tbl[i].used)\n+\t\t\t\treturn i;\n+\t\t}\n+\t} else {\n+\t\tif (ipsec->num_tx_sa == IXGBE_IPSEC_MAX_SA_COUNT)\n+\t\t\treturn -ENOSPC;\n+\n+\t\t/* search tx sa table */\n+\t\tfor (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {\n+\t\t\tif (!ipsec->tx_tbl[i].used)\n+\t\t\t\treturn i;\n+\t\t}\n+\t}\n+\n+\treturn -ENOSPC;\n+}\n+\n+/**\n+ * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol\n+ * @xs: pointer to xfrm_state struct\n+ * @mykey: pointer to key array to populate\n+ * @mysalt: pointer to salt value to populate\n+ *\n+ * This copies the protocol keys and salt to our own data tables.  The\n+ * 82599 family only supports the one algorithm.\n+ **/\n+static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,\n+\t\t\t\t\tu32 *mykey, u32 *mysalt)\n+{\n+\tstruct net_device *dev = xs->xso.dev;\n+\tunsigned char *key_data;\n+\tchar *alg_name = NULL;\n+\tconst char aes_gcm_name[] = \"rfc4106(gcm(aes))\";\n+\tint key_len;\n+\n+\tif (xs->aead) {\n+\t\tkey_data = &xs->aead->alg_key[0];\n+\t\tkey_len = xs->aead->alg_key_len;\n+\t\talg_name = xs->aead->alg_name;\n+\t} else {\n+\t\tnetdev_err(dev, \"Unsupported IPsec algorithm\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (strcmp(alg_name, aes_gcm_name)) {\n+\t\tnetdev_err(dev, \"Unsupported IPsec algorithm - please use %s\\n\",\n+\t\t\t   aes_gcm_name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* The key bytes come down in a bigendian array of bytes, so\n+\t * we don't need to do any byteswapping.\n+\t * 160 accounts for 16 byte key and 4 byte salt\n+\t */\n+\tif (key_len == 160) {\n+\t\t*mysalt = ((u32 *)key_data)[4];\n+\t} else if (key_len != 128) {\n+\t\tnetdev_err(dev, \"IPsec hw offload only supports keys up to 128 bits with a 32 bit salt\\n\");\n+\t\treturn -EINVAL;\n+\t} else {\n+\t\tnetdev_info(dev, \"IPsec hw offload parameters missing 32 bit salt value\\n\");\n+\t\t*mysalt = 0;\n+\t}\n+\tmemcpy(mykey, key_data, 16);\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ixgbe_ipsec_add_sa - program device with a security association\n+ * @xs: pointer to transformer state struct\n+ **/\n+static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)\n+{\n+\tstruct net_device *dev = xs->xso.dev;\n+\tstruct ixgbe_adapter *adapter = netdev_priv(dev);\n+\tstruct ixgbe_ipsec *ipsec = adapter->ipsec;\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tint checked, match, first;\n+\tu16 sa_idx;\n+\tint ret;\n+\tint i;\n+\n+\tif (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {\n+\t\tnetdev_err(dev, \"Unsupported protocol 0x%04x for ipsec offload\\n\",\n+\t\t\t   xs->id.proto);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {\n+\t\tstruct rx_sa rsa;\n+\n+\t\tif (xs->calg) {\n+\t\t\tnetdev_err(dev, \"Compression offload not supported\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\t/* find the first unused index */\n+\t\tret = ixgbe_ipsec_find_empty_idx(ipsec, true);\n+\t\tif (ret < 0) {\n+\t\t\tnetdev_err(dev, \"No space for SA in Rx table!\\n\");\n+\t\t\treturn ret;\n+\t\t}\n+\t\tsa_idx = (u16)ret;\n+\n+\t\tmemset(&rsa, 0, sizeof(rsa));\n+\t\trsa.used = true;\n+\t\trsa.xs = xs;\n+\n+\t\tif (rsa.xs->id.proto & IPPROTO_ESP)\n+\t\t\trsa.decrypt = xs->ealg || xs->aead;\n+\n+\t\t/* get the key and salt */\n+\t\tret = ixgbe_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);\n+\t\tif (ret) {\n+\t\t\tnetdev_err(dev, \"Failed to get key data for Rx SA table\\n\");\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\t/* get ip for rx sa table */\n+\t\tif (xs->xso.flags & XFRM_OFFLOAD_IPV6)\n+\t\t\tmemcpy(rsa.ipaddr, &xs->id.daddr.a6, 16);\n+\t\telse\n+\t\t\tmemcpy(&rsa.ipaddr[3], &xs->id.daddr.a4, 4);\n+\n+\t\t/* The HW does not have a 1:1 mapping from keys to IP addrs, so\n+\t\t * check for a matching IP addr entry in the table.  If the addr\n+\t\t * already exists, use it; else find an unused slot and add the\n+\t\t * addr.  If one does not exist and there are no unused table\n+\t\t * entries, fail the request.\n+\t\t */\n+\n+\t\t/* Find an existing match or first not used, and stop looking\n+\t\t * after we've checked all we know we have.\n+\t\t */\n+\t\tchecked = 0;\n+\t\tmatch = -1;\n+\t\tfirst = -1;\n+\t\tfor (i = 0;\n+\t\t     i < IXGBE_IPSEC_MAX_RX_IP_COUNT &&\n+\t\t     (checked < ipsec->num_rx_sa || first < 0);\n+\t\t     i++) {\n+\t\t\tif (ipsec->ip_tbl[i].used) {\n+\t\t\t\tif (!memcmp(ipsec->ip_tbl[i].ipaddr,\n+\t\t\t\t\t    rsa.ipaddr, sizeof(rsa.ipaddr))) {\n+\t\t\t\t\tmatch = i;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tchecked++;\n+\t\t\t} else if (first < 0) {\n+\t\t\t\tfirst = i;  /* track the first empty seen */\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (ipsec->num_rx_sa == 0)\n+\t\t\tfirst = 0;\n+\n+\t\tif (match >= 0) {\n+\t\t\t/* addrs are the same, we should use this one */\n+\t\t\trsa.iptbl_ind = match;\n+\t\t\tipsec->ip_tbl[match].ref_cnt++;\n+\n+\t\t} else if (first >= 0) {\n+\t\t\t/* no matches, but here's an empty slot */\n+\t\t\trsa.iptbl_ind = first;\n+\n+\t\t\tmemcpy(ipsec->ip_tbl[first].ipaddr,\n+\t\t\t       rsa.ipaddr, sizeof(rsa.ipaddr));\n+\t\t\tipsec->ip_tbl[first].ref_cnt = 1;\n+\t\t\tipsec->ip_tbl[first].used = true;\n+\n+\t\t\tixgbe_ipsec_set_rx_ip(hw, rsa.iptbl_ind, rsa.ipaddr);\n+\n+\t\t} else {\n+\t\t\t/* no match and no empty slot */\n+\t\t\tnetdev_err(dev, \"No space for SA in Rx IP SA table\\n\");\n+\t\t\tmemset(&rsa, 0, sizeof(rsa));\n+\t\t\treturn -ENOSPC;\n+\t\t}\n+\n+\t\trsa.mode = IXGBE_RXMOD_VALID;\n+\t\tif (rsa.xs->id.proto & IPPROTO_ESP)\n+\t\t\trsa.mode |= IXGBE_RXMOD_PROTO_ESP;\n+\t\tif (rsa.decrypt)\n+\t\t\trsa.mode |= IXGBE_RXMOD_DECRYPT;\n+\t\tif (rsa.xs->xso.flags & XFRM_OFFLOAD_IPV6)\n+\t\t\trsa.mode |= IXGBE_RXMOD_IPV6;\n+\n+\t\t/* the preparations worked, so save the info */\n+\t\tmemcpy(&ipsec->rx_tbl[sa_idx], &rsa, sizeof(rsa));\n+\n+\t\tixgbe_ipsec_set_rx_sa(hw, sa_idx, rsa.xs->id.spi, rsa.key,\n+\t\t\t\t      rsa.salt, rsa.mode, rsa.iptbl_ind);\n+\t\txs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_RX_INDEX;\n+\n+\t\tipsec->num_rx_sa++;\n+\n+\t\t/* hash the new entry for faster search in Rx path */\n+\t\thash_add_rcu(ipsec->rx_sa_list, &ipsec->rx_tbl[sa_idx].hlist,\n+\t\t\t     rsa.xs->id.spi);\n+\t} else {\n+\t\tstruct tx_sa tsa;\n+\n+\t\t/* find the first unused index */\n+\t\tret = ixgbe_ipsec_find_empty_idx(ipsec, false);\n+\t\tif (ret < 0) {\n+\t\t\tnetdev_err(dev, \"No space for SA in Tx table\\n\");\n+\t\t\treturn ret;\n+\t\t}\n+\t\tsa_idx = (u16)ret;\n+\n+\t\tmemset(&tsa, 0, sizeof(tsa));\n+\t\ttsa.used = true;\n+\t\ttsa.xs = xs;\n+\n+\t\tif (xs->id.proto & IPPROTO_ESP)\n+\t\t\ttsa.encrypt = xs->ealg || xs->aead;\n+\n+\t\tret = ixgbe_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);\n+\t\tif (ret) {\n+\t\t\tnetdev_err(dev, \"Failed to get key data for Tx SA table\\n\");\n+\t\t\tmemset(&tsa, 0, sizeof(tsa));\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\t/* the preparations worked, so save the info */\n+\t\tmemcpy(&ipsec->tx_tbl[sa_idx], &tsa, sizeof(tsa));\n+\n+\t\tixgbe_ipsec_set_tx_sa(hw, sa_idx, tsa.key, tsa.salt);\n+\n+\t\txs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_TX_INDEX;\n+\n+\t\tipsec->num_tx_sa++;\n+\t}\n+\n+\t/* enable the engine if not already warmed up */\n+\tif (!(adapter->flags2 & IXGBE_FLAG2_IPSEC_ENABLED)) {\n+\t\tixgbe_ipsec_start_engine(adapter);\n+\t\tadapter->flags2 |= IXGBE_FLAG2_IPSEC_ENABLED;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * ixgbe_ipsec_del_sa - clear out this specific SA\n+ * @xs: pointer to transformer state struct\n+ **/\n+static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)\n+{\n+\tstruct net_device *dev = xs->xso.dev;\n+\tstruct ixgbe_adapter *adapter = netdev_priv(dev);\n+\tstruct ixgbe_ipsec *ipsec = adapter->ipsec;\n+\tstruct ixgbe_hw *hw = &adapter->hw;\n+\tu32 zerobuf[4] = {0, 0, 0, 0};\n+\tu16 sa_idx;\n+\n+\tif (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {\n+\t\tstruct rx_sa *rsa;\n+\t\tu8 ipi;\n+\n+\t\tsa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX;\n+\t\trsa = &ipsec->rx_tbl[sa_idx];\n+\n+\t\tif (!rsa->used) {\n+\t\t\tnetdev_err(dev, \"Invalid Rx SA selected sa_idx=%d offload_handle=%lu\\n\",\n+\t\t\t\t   sa_idx, xs->xso.offload_handle);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tixgbe_ipsec_set_rx_sa(hw, sa_idx, 0, zerobuf, 0, 0, 0);\n+\t\thash_del_rcu(&rsa->hlist);\n+\n+\t\t/* if the IP table entry is referenced by only this SA,\n+\t\t * i.e. ref_cnt is only 1, clear the IP table entry as well\n+\t\t */\n+\t\tipi = rsa->iptbl_ind;\n+\t\tif (ipsec->ip_tbl[ipi].ref_cnt > 0) {\n+\t\t\tipsec->ip_tbl[ipi].ref_cnt--;\n+\n+\t\t\tif (!ipsec->ip_tbl[ipi].ref_cnt) {\n+\t\t\t\tmemset(&ipsec->ip_tbl[ipi], 0,\n+\t\t\t\t       sizeof(struct rx_ip_sa));\n+\t\t\t\tixgbe_ipsec_set_rx_ip(hw, ipi, zerobuf);\n+\t\t\t}\n+\t\t}\n+\n+\t\tmemset(rsa, 0, sizeof(struct rx_sa));\n+\t\tipsec->num_rx_sa--;\n+\t} else {\n+\t\tsa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;\n+\n+\t\tif (!ipsec->tx_tbl[sa_idx].used) {\n+\t\t\tnetdev_err(dev, \"Invalid Tx SA selected sa_idx=%d offload_handle=%lu\\n\",\n+\t\t\t\t   sa_idx, xs->xso.offload_handle);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tixgbe_ipsec_set_tx_sa(hw, sa_idx, zerobuf, 0);\n+\t\tmemset(&ipsec->tx_tbl[sa_idx], 0, sizeof(struct tx_sa));\n+\t\tipsec->num_tx_sa--;\n+\t}\n+\n+\t/* if there are no SAs left, stop the engine to save energy */\n+\tif (ipsec->num_rx_sa == 0 && ipsec->num_tx_sa == 0) {\n+\t\tadapter->flags2 &= ~IXGBE_FLAG2_IPSEC_ENABLED;\n+\t\tixgbe_ipsec_stop_engine(adapter);\n+\t}\n+}\n+\n+static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {\n+\t.xdo_dev_state_add = ixgbe_ipsec_add_sa,\n+\t.xdo_dev_state_delete = ixgbe_ipsec_del_sa,\n+};\n+\n+/**\n  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation\n  * @adapter: board private structure\n  **/\n void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)\n {\n-\tixgbe_ipsec_clear_hw_tables(adapter);\n+\tstruct ixgbe_ipsec *ipsec;\n+\tsize_t size;\n+\n+\tipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL);\n+\tif (!ipsec)\n+\t\tgoto err1;\n+\thash_init(ipsec->rx_sa_list);\n+\n+\tsize = sizeof(struct rx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;\n+\tipsec->rx_tbl = kzalloc(size, GFP_KERNEL);\n+\tif (!ipsec->rx_tbl)\n+\t\tgoto err2;\n+\n+\tsize = sizeof(struct tx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;\n+\tipsec->tx_tbl = kzalloc(size, GFP_KERNEL);\n+\tif (!ipsec->tx_tbl)\n+\t\tgoto err2;\n+\n+\tsize = sizeof(struct rx_ip_sa) * IXGBE_IPSEC_MAX_RX_IP_COUNT;\n+\tipsec->ip_tbl = kzalloc(size, GFP_KERNEL);\n+\tif (!ipsec->ip_tbl)\n+\t\tgoto err2;\n+\n+\tipsec->num_rx_sa = 0;\n+\tipsec->num_tx_sa = 0;\n+\n+\tadapter->ipsec = ipsec;\n \tixgbe_ipsec_stop_engine(adapter);\n+\tixgbe_ipsec_clear_hw_tables(adapter);\n+\n+\treturn;\n+\n+err2:\n+\tkfree(ipsec->ip_tbl);\n+\tkfree(ipsec->rx_tbl);\n+\tkfree(ipsec->tx_tbl);\n+err1:\n+\tkfree(adapter->ipsec);\n+\tnetdev_err(adapter->netdev, \"Unable to allocate memory for SA tables\");\n+}\n+\n+/**\n+ * ixgbe_stop_ipsec_offload - tear down the ipsec offload\n+ * @adapter: board private structure\n+ **/\n+void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter)\n+{\n+\tstruct ixgbe_ipsec *ipsec = adapter->ipsec;\n+\n+\tadapter->ipsec = NULL;\n+\tif (ipsec) {\n+\t\tkfree(ipsec->ip_tbl);\n+\t\tkfree(ipsec->rx_tbl);\n+\t\tkfree(ipsec->tx_tbl);\n+\t\tkfree(ipsec);\n+\t}\n }\ndiff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\nindex 51fb3cf..2b3da0c 100644\n--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c\n@@ -10565,6 +10565,7 @@ static void ixgbe_remove(struct pci_dev *pdev)\n \tif (netdev->reg_state == NETREG_REGISTERED)\n \t\tunregister_netdev(netdev);\n \n+\tixgbe_stop_ipsec_offload(adapter);\n \tixgbe_clear_interrupt_scheme(adapter);\n \n \tixgbe_release_hw_control(adapter);\n",
    "prefixes": [
        "v2",
        "next-queue",
        "05/10"
    ]
}