Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/818166/?format=api
{ "id": 818166, "url": "http://patchwork.ozlabs.org/api/patches/818166/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1506335021-32024-5-git-send-email-simon.horman@netronome.com/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1506335021-32024-5-git-send-email-simon.horman@netronome.com>", "list_archive_url": null, "date": "2017-09-25T10:23:38", "name": "[net-next,4/7] nfp: offload flower vxlan endpoint MAC addresses", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": true, "hash": "cca1291fa6cd49df02f4ff3b8cd17b71e26a3567", "submitter": { "id": 64714, "url": "http://patchwork.ozlabs.org/api/people/64714/?format=api", "name": "Simon Horman", "email": "simon.horman@netronome.com" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1506335021-32024-5-git-send-email-simon.horman@netronome.com/mbox/", "series": [ { "id": 4932, "url": "http://patchwork.ozlabs.org/api/series/4932/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=4932", "date": "2017-09-25T10:23:34", "name": "nfp: flower vxlan tunnel offload", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/4932/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/818166/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/818166/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=netronome-com.20150623.gappssmtp.com\n\theader.i=@netronome-com.20150623.gappssmtp.com\n\theader.b=\"ODsuGLxj\"; dkim-atps=neutral" ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3y10ZQ0v1dz9tX3\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 25 Sep 2017 20:24:46 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S934572AbdIYKYj (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 25 Sep 2017 06:24:39 -0400", "from mail-wm0-f53.google.com ([74.125.82.53]:46497 \"EHLO\n\tmail-wm0-f53.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S933358AbdIYKYF (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 25 Sep 2017 06:24:05 -0400", "by mail-wm0-f53.google.com with SMTP id m72so17916029wmc.1\n\tfor <netdev@vger.kernel.org>; Mon, 25 Sep 2017 03:24:05 -0700 (PDT)", "from penelope.horms.nl ([217.111.208.18])\n\tby smtp.gmail.com with ESMTPSA id\n\t10sm6816818wrt.59.2017.09.25.03.24.02\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tMon, 25 Sep 2017 03:24:03 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=netronome-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=C5RB7YasHjl48Ep3SglOBJOoKtSHWmzX1Nv1wdv2hNM=;\n\tb=ODsuGLxjdu3A+qNWqhGSuipy7uw5V5JnZtt6YSIZtpllYnEelcCNmLHaHWyYfNvKVF\n\tsRDI2AUGDdLxrWo6lSF729R+uVYNXdBP8ZfBhrY3yCPq2yja92NW5EVfmfMsc8y0Fohf\n\tpfifFJwbeW4aRU4fDGWKUysX60m4/px+MQ4hR/FvuvM4nll2WZwjIz/+QJxDRzbjnhXB\n\tANhsxMTAJpBQuIWYbvmxjw2MKkXlxUBY+6RiQmSHsVZK2C0FosJqBAKn8BLGZ9k9DZ2j\n\tYRVucPhQGG0TXaYW10GPV177VyaZ4+dDJyt7Stq+4Hsj17qVOp+0kJxnhqXf9fiemly6\n\tRpgw==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=C5RB7YasHjl48Ep3SglOBJOoKtSHWmzX1Nv1wdv2hNM=;\n\tb=YnUzpQIOr1X1a81N79TruHhWPttIhlodXD88ysaMsWGq25LPJKdCEZ8UNESuSztzgP\n\tYSRzRqML+bIal1QBI9wrO44VHgo7Adzdujj4X/17aeYWdTdejLUtIGVOFuL6PhrdyvBg\n\tRZXRztDN0BQvO22veWHvJp0kPqNm2ALbqdaY5bzODMuRFXjARuND4tsi1vBvo4MkO9lT\n\tgVrwGSdpbtaQNqlpqoXnPFUdfJ9YTRkfjIhlQliYMislfkR9D16ZKXwD2vdQV3t/bX8I\n\tnFPHRWHbO2zTClIywo4mnoQJCdfo6M1F4XiPd8ofRhOvWbvcd24yja6m3OUx5sJXnlzh\n\tHrYg==", "X-Gm-Message-State": "AHPjjUirS7XFRsEbIG8t0z5SGJIbxc1JvC4BcGJaFgK0VXcv/fK/kJND\n\tvIt1NWJdw3AWhKfdiEgPijnA2Q==", "X-Google-Smtp-Source": "AOwi7QCuCzGjiM4inW+tJeoLvvlPRy7RYjuDi1XHXz6lXR+73BEfstaZfPoUb8hPQew+i437oWRlYg==", "X-Received": "by 10.28.107.17 with SMTP id g17mr41812wmc.58.1506335044195;\n\tMon, 25 Sep 2017 03:24:04 -0700 (PDT)", "From": "Simon Horman <simon.horman@netronome.com>", "To": "David Miller <davem@davemloft.net>,\n\tJakub Kicinski <jakub.kicinski@netronome.com>", "Cc": "netdev@vger.kernel.org, oss-drivers@netronome.com,\n\tJohn Hurley <john.hurley@netronome.com>,\n\tSimon Horman <simon.horman@netronome.com>", "Subject": "[PATCH net-next 4/7] nfp: offload flower vxlan endpoint MAC\n\taddresses", "Date": "Mon, 25 Sep 2017 12:23:38 +0200", "Message-Id": "<1506335021-32024-5-git-send-email-simon.horman@netronome.com>", "X-Mailer": "git-send-email 2.1.4", "In-Reply-To": "<1506335021-32024-1-git-send-email-simon.horman@netronome.com>", "References": "<1506335021-32024-1-git-send-email-simon.horman@netronome.com>", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "From: John Hurley <john.hurley@netronome.com>\n\nGenerate a list of MAC addresses of netdevs that could be used as VXLAN\ntunnel end points. Give offloaded MACs an index for storage on the NFP in\nthe ranges:\n0x100-0x1ff physical port representors\n0x200-0x2ff VF port representors\n0x300-0x3ff other offloads (e.g. vxlan netdevs, ovs bridges)\n\nAssign phys and vf indexes based on unique 8 bit values in the port num.\nMaintain list of other netdevs to ensure same netdev is not offloaded\ntwice and each gets a unique ID without exhausting the entries. Because\nthe IDs are unique but constant for a netdev, any changes are implemented\nby overwriting the index on NFP.\n\nSigned-off-by: John Hurley <john.hurley@netronome.com>\nSigned-off-by: Simon Horman <simon.horman@netronome.com>\n---\n drivers/net/ethernet/netronome/nfp/Makefile | 3 +-\n drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 7 -\n drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 9 +\n drivers/net/ethernet/netronome/nfp/flower/main.c | 13 +\n drivers/net/ethernet/netronome/nfp/flower/main.h | 18 +\n drivers/net/ethernet/netronome/nfp/flower/match.c | 7 +\n .../ethernet/netronome/nfp/flower/tunnel_conf.c | 374 +++++++++++++++++++++\n 7 files changed, 423 insertions(+), 8 deletions(-)\n create mode 100644 drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c", "diff": "diff --git a/drivers/net/ethernet/netronome/nfp/Makefile b/drivers/net/ethernet/netronome/nfp/Makefile\nindex 96e579a15cbe..becaacf1554d 100644\n--- a/drivers/net/ethernet/netronome/nfp/Makefile\n+++ b/drivers/net/ethernet/netronome/nfp/Makefile\n@@ -37,7 +37,8 @@ nfp-objs += \\\n \t flower/main.o \\\n \t flower/match.o \\\n \t flower/metadata.o \\\n-\t flower/offload.o\n+\t flower/offload.o \\\n+\t flower/tunnel_conf.o\n endif\n \n ifeq ($(CONFIG_BPF_SYSCALL),y)\ndiff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c\nindex c3ca05d10fe1..b756006dba6f 100644\n--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c\n+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c\n@@ -38,17 +38,10 @@\n #include <net/dst_metadata.h>\n \n #include \"main.h\"\n-#include \"../nfpcore/nfp_cpp.h\"\n #include \"../nfp_net.h\"\n #include \"../nfp_net_repr.h\"\n #include \"./cmsg.h\"\n \n-#define nfp_flower_cmsg_warn(app, fmt, args...)\t\t\t\t\\\n-\tdo {\t\t\t\t\t\t\t\t\\\n-\t\tif (net_ratelimit())\t\t\t\t\t\\\n-\t\t\tnfp_warn((app)->cpp, fmt, ## args);\t\t\\\n-\t} while (0)\n-\n static struct nfp_flower_cmsg_hdr *\n nfp_flower_cmsg_get_hdr(struct sk_buff *skb)\n {\ndiff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h\nindex ff42ce8a1e9c..dc248193c996 100644\n--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h\n+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h\n@@ -39,6 +39,7 @@\n #include <linux/types.h>\n \n #include \"../nfp_app.h\"\n+#include \"../nfpcore/nfp_cpp.h\"\n \n #define NFP_FLOWER_LAYER_META\t\tBIT(0)\n #define NFP_FLOWER_LAYER_PORT\t\tBIT(1)\n@@ -90,6 +91,12 @@\n #define NFP_FL_IPV4_TUNNEL_TYPE\t\tGENMASK(7, 4)\n #define NFP_FL_IPV4_PRE_TUN_INDEX\tGENMASK(2, 0)\n \n+#define nfp_flower_cmsg_warn(app, fmt, args...) \\\n+\tdo { \\\n+\t\tif (net_ratelimit()) \\\n+\t\t\tnfp_warn((app)->cpp, fmt, ## args); \\\n+\t} while (0)\n+\n enum nfp_flower_tun_type {\n \tNFP_FL_TUNNEL_NONE =\t0,\n \tNFP_FL_TUNNEL_VXLAN =\t2,\n@@ -310,6 +317,7 @@ enum nfp_flower_cmsg_type_port {\n \tNFP_FLOWER_CMSG_TYPE_FLOW_DEL =\t\t2,\n \tNFP_FLOWER_CMSG_TYPE_MAC_REPR =\t\t7,\n \tNFP_FLOWER_CMSG_TYPE_PORT_MOD =\t\t8,\n+\tNFP_FLOWER_CMSG_TYPE_TUN_MAC =\t\t11,\n \tNFP_FLOWER_CMSG_TYPE_FLOW_STATS =\t15,\n \tNFP_FLOWER_CMSG_TYPE_PORT_ECHO =\t16,\n \tNFP_FLOWER_CMSG_TYPE_MAX =\t\t32,\n@@ -343,6 +351,7 @@ enum nfp_flower_cmsg_port_type {\n \tNFP_FLOWER_CMSG_PORT_TYPE_UNSPEC =\t0x0,\n \tNFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT =\t0x1,\n \tNFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT =\t0x2,\n+\tNFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT = 0x3,\n };\n \n enum nfp_flower_cmsg_port_vnic_type {\ndiff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c\nindex 91fe03617106..e46e7c60d491 100644\n--- a/drivers/net/ethernet/netronome/nfp/flower/main.c\n+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c\n@@ -436,6 +436,16 @@ static void nfp_flower_clean(struct nfp_app *app)\n \tapp->priv = NULL;\n }\n \n+static int nfp_flower_start(struct nfp_app *app)\n+{\n+\treturn nfp_tunnel_config_start(app);\n+}\n+\n+static void nfp_flower_stop(struct nfp_app *app)\n+{\n+\tnfp_tunnel_config_stop(app);\n+}\n+\n const struct nfp_app_type app_flower = {\n \t.id\t\t= NFP_APP_FLOWER_NIC,\n \t.name\t\t= \"flower\",\n@@ -453,6 +463,9 @@ const struct nfp_app_type app_flower = {\n \t.repr_open\t= nfp_flower_repr_netdev_open,\n \t.repr_stop\t= nfp_flower_repr_netdev_stop,\n \n+\t.start\t\t= nfp_flower_start,\n+\t.stop\t\t= nfp_flower_stop,\n+\n \t.ctrl_msg_rx\t= nfp_flower_cmsg_rx,\n \n \t.sriov_enable\t= nfp_flower_sriov_enable,\ndiff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h\nindex cd695eabce02..9de375acc254 100644\n--- a/drivers/net/ethernet/netronome/nfp/flower/main.h\n+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h\n@@ -84,6 +84,13 @@ struct nfp_fl_stats_id {\n * @flow_table:\t\tHash table used to store flower rules\n * @cmsg_work:\t\tWorkqueue for control messages processing\n * @cmsg_skbs:\t\tList of skbs for control message processing\n+ * @nfp_mac_off_list:\tList of MAC addresses to offload\n+ * @nfp_mac_index_list:\tList of unique 8-bit indexes for non NFP netdevs\n+ * @nfp_mac_off_lock:\tLock for the MAC address list\n+ * @nfp_mac_index_lock:\tLock for the MAC index list\n+ * @nfp_mac_off_ids:\tIDA to manage id assignment for offloaded macs\n+ * @nfp_mac_off_count:\tNumber of MACs in address list\n+ * @nfp_tun_mac_nb:\tNotifier to monitor link state\n */\n struct nfp_flower_priv {\n \tstruct nfp_app *app;\n@@ -96,6 +103,13 @@ struct nfp_flower_priv {\n \tDECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);\n \tstruct work_struct cmsg_work;\n \tstruct sk_buff_head cmsg_skbs;\n+\tstruct list_head nfp_mac_off_list;\n+\tstruct list_head nfp_mac_index_list;\n+\tstruct mutex nfp_mac_off_lock;\n+\tstruct mutex nfp_mac_index_lock;\n+\tstruct ida nfp_mac_off_ids;\n+\tint nfp_mac_off_count;\n+\tstruct notifier_block nfp_tun_mac_nb;\n };\n \n struct nfp_fl_key_ls {\n@@ -165,4 +179,8 @@ nfp_flower_remove_fl_table(struct nfp_app *app, unsigned long tc_flower_cookie);\n \n void nfp_flower_rx_flow_stats(struct nfp_app *app, struct sk_buff *skb);\n \n+int nfp_tunnel_config_start(struct nfp_app *app);\n+void nfp_tunnel_config_stop(struct nfp_app *app);\n+void nfp_tunnel_write_macs(struct nfp_app *app);\n+\n #endif\ndiff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c\nindex 1fd1bab0611f..cb3ff6c126e8 100644\n--- a/drivers/net/ethernet/netronome/nfp/flower/match.c\n+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c\n@@ -232,6 +232,7 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,\n \t\t\t\t struct nfp_fl_payload *nfp_flow)\n {\n \tenum nfp_flower_tun_type tun_type = NFP_FL_TUNNEL_NONE;\n+\tstruct nfp_repr *netdev_repr;\n \tint err;\n \tu8 *ext;\n \tu8 *msk;\n@@ -341,6 +342,12 @@ int nfp_flower_compile_flow_match(struct tc_cls_flower_offload *flow,\n \t\t\t\t\t flow, true);\n \t\text += sizeof(struct nfp_flower_vxlan);\n \t\tmsk += sizeof(struct nfp_flower_vxlan);\n+\n+\t\t/* Configure tunnel end point MAC. */\n+\t\tif (nfp_netdev_is_nfp_repr(netdev)) {\n+\t\t\tnetdev_repr = netdev_priv(netdev);\n+\t\t\tnfp_tunnel_write_macs(netdev_repr->app);\n+\t\t}\n \t}\n \n \treturn 0;\ndiff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c\nnew file mode 100644\nindex 000000000000..34be85803020\n--- /dev/null\n+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c\n@@ -0,0 +1,374 @@\n+/*\n+ * Copyright (C) 2017 Netronome Systems, Inc.\n+ *\n+ * This software is dual licensed under the GNU General License Version 2,\n+ * June 1991 as shown in the file COPYING in the top-level directory of this\n+ * source tree or the BSD 2-Clause License provided below. You have the\n+ * option to license this software under the complete terms of either license.\n+ *\n+ * The BSD 2-Clause License:\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * 1. Redistributions of source code must retain the above\n+ * copyright notice, this list of conditions and the following\n+ * disclaimer.\n+ *\n+ * 2. Redistributions in binary form must reproduce the above\n+ * copyright notice, this list of conditions and the following\n+ * disclaimer in the documentation and/or other materials\n+ * provided with the distribution.\n+ *\n+ * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n+ * SOFTWARE.\n+ */\n+\n+#include <linux/etherdevice.h>\n+#include <linux/idr.h>\n+#include <net/dst_metadata.h>\n+\n+#include \"cmsg.h\"\n+#include \"main.h\"\n+#include \"../nfp_net_repr.h\"\n+#include \"../nfp_net.h\"\n+\n+/**\n+ * struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP\n+ * @reserved:\treserved for future use\n+ * @count:\tnumber of MAC addresses in the message\n+ * @index:\tindex of MAC address in the lookup table\n+ * @addr:\tinterface MAC address\n+ * @addresses:\tseries of MACs to offload\n+ */\n+struct nfp_tun_mac_addr {\n+\t__be16 reserved;\n+\t__be16 count;\n+\tstruct index_mac_addr {\n+\t\t__be16 index;\n+\t\tu8 addr[ETH_ALEN];\n+\t} addresses[];\n+};\n+\n+/**\n+ * struct nfp_tun_mac_offload_entry - list of MACs to offload\n+ * @index:\tindex of MAC address for offloading\n+ * @addr:\tinterface MAC address\n+ * @list:\tlist pointer\n+ */\n+struct nfp_tun_mac_offload_entry {\n+\t__be16 index;\n+\tu8 addr[ETH_ALEN];\n+\tstruct list_head list;\n+};\n+\n+#define NFP_MAX_MAC_INDEX 0xff\n+\n+/**\n+ * struct nfp_tun_mac_non_nfp_idx - converts non NFP netdev ifindex to 8-bit id\n+ * @ifindex:\tnetdev ifindex of the device\n+ * @index:\tindex of netdevs mac on NFP\n+ * @list:\tlist pointer\n+ */\n+struct nfp_tun_mac_non_nfp_idx {\n+\tint ifindex;\n+\tu8 index;\n+\tstruct list_head list;\n+};\n+\n+static bool nfp_tun_is_netdev_to_offload(struct net_device *netdev)\n+{\n+\tif (!netdev->rtnl_link_ops)\n+\t\treturn false;\n+\tif (!strcmp(netdev->rtnl_link_ops->kind, \"openvswitch\"))\n+\t\treturn true;\n+\tif (!strcmp(netdev->rtnl_link_ops->kind, \"vxlan\"))\n+\t\treturn true;\n+\n+\treturn false;\n+}\n+\n+static int\n+nfp_flower_xmit_tun_conf(struct nfp_app *app, u8 mtype, u16 plen, void *pdata)\n+{\n+\tstruct sk_buff *skb;\n+\tunsigned char *msg;\n+\n+\tskb = nfp_flower_cmsg_alloc(app, plen, mtype);\n+\tif (!skb)\n+\t\treturn -ENOMEM;\n+\n+\tmsg = nfp_flower_cmsg_get_data(skb);\n+\tmemcpy(msg, pdata, nfp_flower_cmsg_get_data_len(skb));\n+\n+\tnfp_ctrl_tx(app->ctrl, skb);\n+\treturn 0;\n+}\n+\n+void nfp_tunnel_write_macs(struct nfp_app *app)\n+{\n+\tstruct nfp_flower_priv *priv = app->priv;\n+\tstruct nfp_tun_mac_offload_entry *entry;\n+\tstruct nfp_tun_mac_addr *payload;\n+\tstruct list_head *ptr, *storage;\n+\tint mac_count, err, pay_size;\n+\n+\tmutex_lock(&priv->nfp_mac_off_lock);\n+\tif (!priv->nfp_mac_off_count) {\n+\t\tmutex_unlock(&priv->nfp_mac_off_lock);\n+\t\treturn;\n+\t}\n+\n+\tpay_size = sizeof(struct nfp_tun_mac_addr) +\n+\t\t sizeof(struct index_mac_addr) * priv->nfp_mac_off_count;\n+\n+\tpayload = kzalloc(pay_size, GFP_KERNEL);\n+\tif (!payload) {\n+\t\tmutex_unlock(&priv->nfp_mac_off_lock);\n+\t\treturn;\n+\t}\n+\n+\tpayload->count = cpu_to_be16(priv->nfp_mac_off_count);\n+\n+\tmac_count = 0;\n+\tlist_for_each_safe(ptr, storage, &priv->nfp_mac_off_list) {\n+\t\tentry = list_entry(ptr, struct nfp_tun_mac_offload_entry,\n+\t\t\t\t list);\n+\t\tpayload->addresses[mac_count].index = entry->index;\n+\t\tether_addr_copy(payload->addresses[mac_count].addr,\n+\t\t\t\tentry->addr);\n+\t\tmac_count++;\n+\t}\n+\n+\terr = nfp_flower_xmit_tun_conf(app, NFP_FLOWER_CMSG_TYPE_TUN_MAC,\n+\t\t\t\t pay_size, payload);\n+\n+\tkfree(payload);\n+\n+\tif (err) {\n+\t\tmutex_unlock(&priv->nfp_mac_off_lock);\n+\t\t/* Write failed so retain list for future retry. */\n+\t\treturn;\n+\t}\n+\n+\t/* If list was successfully offloaded, flush it. */\n+\tlist_for_each_safe(ptr, storage, &priv->nfp_mac_off_list) {\n+\t\tentry = list_entry(ptr, struct nfp_tun_mac_offload_entry,\n+\t\t\t\t list);\n+\t\tlist_del(&entry->list);\n+\t\tkfree(entry);\n+\t}\n+\n+\tpriv->nfp_mac_off_count = 0;\n+\tmutex_unlock(&priv->nfp_mac_off_lock);\n+}\n+\n+static int nfp_tun_get_mac_idx(struct nfp_app *app, int ifindex)\n+{\n+\tstruct nfp_flower_priv *priv = app->priv;\n+\tstruct nfp_tun_mac_non_nfp_idx *entry;\n+\tstruct list_head *ptr, *storage;\n+\tint idx;\n+\n+\tmutex_lock(&priv->nfp_mac_index_lock);\n+\tlist_for_each_safe(ptr, storage, &priv->nfp_mac_index_list) {\n+\t\tentry = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx, list);\n+\t\tif (entry->ifindex == ifindex) {\n+\t\t\tidx = entry->index;\n+\t\t\tmutex_unlock(&priv->nfp_mac_index_lock);\n+\t\t\treturn idx;\n+\t\t}\n+\t}\n+\n+\tidx = ida_simple_get(&priv->nfp_mac_off_ids, 0,\n+\t\t\t NFP_MAX_MAC_INDEX, GFP_KERNEL);\n+\tif (idx < 0) {\n+\t\tmutex_unlock(&priv->nfp_mac_index_lock);\n+\t\treturn idx;\n+\t}\n+\n+\tentry = kmalloc(sizeof(*entry), GFP_KERNEL);\n+\tif (!entry) {\n+\t\tmutex_unlock(&priv->nfp_mac_index_lock);\n+\t\treturn -ENOMEM;\n+\t}\n+\tentry->ifindex = ifindex;\n+\tentry->index = idx;\n+\tlist_add_tail(&entry->list, &priv->nfp_mac_index_list);\n+\tmutex_unlock(&priv->nfp_mac_index_lock);\n+\n+\treturn idx;\n+}\n+\n+static void nfp_tun_del_mac_idx(struct nfp_app *app, int ifindex)\n+{\n+\tstruct nfp_flower_priv *priv = app->priv;\n+\tstruct nfp_tun_mac_non_nfp_idx *entry;\n+\tstruct list_head *ptr, *storage;\n+\n+\tmutex_lock(&priv->nfp_mac_index_lock);\n+\tlist_for_each_safe(ptr, storage, &priv->nfp_mac_index_list) {\n+\t\tentry = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx, list);\n+\t\tif (entry->ifindex == ifindex) {\n+\t\t\tida_simple_remove(&priv->nfp_mac_off_ids,\n+\t\t\t\t\t entry->index);\n+\t\t\tlist_del(&entry->list);\n+\t\t\tkfree(entry);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tmutex_unlock(&priv->nfp_mac_index_lock);\n+}\n+\n+static void nfp_tun_add_to_mac_offload_list(struct net_device *netdev,\n+\t\t\t\t\t struct nfp_app *app)\n+{\n+\tstruct nfp_flower_priv *priv = app->priv;\n+\tstruct nfp_tun_mac_offload_entry *entry;\n+\tu16 nfp_mac_idx;\n+\tint port = 0;\n+\n+\t/* Check if MAC should be offloaded. */\n+\tif (!is_valid_ether_addr(netdev->dev_addr))\n+\t\treturn;\n+\n+\tif (nfp_netdev_is_nfp_repr(netdev))\n+\t\tport = nfp_repr_get_port_id(netdev);\n+\telse if (!nfp_tun_is_netdev_to_offload(netdev))\n+\t\treturn;\n+\n+\tentry = kmalloc(sizeof(*entry), GFP_KERNEL);\n+\tif (!entry) {\n+\t\tnfp_flower_cmsg_warn(app, \"Mem fail when offloading MAC.\\n\");\n+\t\treturn;\n+\t}\n+\n+\tif (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) ==\n+\t NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT) {\n+\t\tnfp_mac_idx = port << 8 | NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT;\n+\t} else if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port) ==\n+\t\t NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT) {\n+\t\tport = FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC, port);\n+\t\tnfp_mac_idx = port << 8 | NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT;\n+\t} else {\n+\t\t/* Must assign our own unique 8-bit index. */\n+\t\tint idx = nfp_tun_get_mac_idx(app, netdev->ifindex);\n+\n+\t\tif (idx < 0) {\n+\t\t\tnfp_flower_cmsg_warn(app, \"Can't assign non-repr MAC index.\\n\");\n+\t\t\tkfree(entry);\n+\t\t\treturn;\n+\t\t}\n+\t\tnfp_mac_idx = idx << 8 | NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT;\n+\t}\n+\n+\tentry->index = cpu_to_be16(nfp_mac_idx);\n+\tether_addr_copy(entry->addr, netdev->dev_addr);\n+\n+\tmutex_lock(&priv->nfp_mac_off_lock);\n+\tpriv->nfp_mac_off_count++;\n+\tlist_add_tail(&entry->list, &priv->nfp_mac_off_list);\n+\tmutex_unlock(&priv->nfp_mac_off_lock);\n+}\n+\n+static int nfp_tun_mac_event_handler(struct notifier_block *nb,\n+\t\t\t\t unsigned long event, void *ptr)\n+{\n+\tstruct nfp_flower_priv *app_priv;\n+\tstruct net_device *netdev;\n+\tstruct nfp_app *app;\n+\n+\tif (event == NETDEV_DOWN || event == NETDEV_UNREGISTER) {\n+\t\tapp_priv = container_of(nb, struct nfp_flower_priv,\n+\t\t\t\t\tnfp_tun_mac_nb);\n+\t\tapp = app_priv->app;\n+\t\tnetdev = netdev_notifier_info_to_dev(ptr);\n+\n+\t\t/* If non-nfp netdev then free its offload index. */\n+\t\tif (nfp_tun_is_netdev_to_offload(netdev))\n+\t\t\tnfp_tun_del_mac_idx(app, netdev->ifindex);\n+\t} else if (event == NETDEV_UP || event == NETDEV_CHANGEADDR ||\n+\t\t event == NETDEV_REGISTER) {\n+\t\tapp_priv = container_of(nb, struct nfp_flower_priv,\n+\t\t\t\t\tnfp_tun_mac_nb);\n+\t\tapp = app_priv->app;\n+\t\tnetdev = netdev_notifier_info_to_dev(ptr);\n+\n+\t\tnfp_tun_add_to_mac_offload_list(netdev, app);\n+\n+\t\t/* Force a list write to keep NFP up to date. */\n+\t\tnfp_tunnel_write_macs(app);\n+\t}\n+\treturn NOTIFY_OK;\n+}\n+\n+int nfp_tunnel_config_start(struct nfp_app *app)\n+{\n+\tstruct nfp_flower_priv *priv = app->priv;\n+\tstruct net_device *netdev;\n+\tint err;\n+\n+\t/* Initialise priv data for MAC offloading. */\n+\tpriv->nfp_mac_off_count = 0;\n+\tmutex_init(&priv->nfp_mac_off_lock);\n+\tINIT_LIST_HEAD(&priv->nfp_mac_off_list);\n+\tpriv->nfp_tun_mac_nb.notifier_call = nfp_tun_mac_event_handler;\n+\tmutex_init(&priv->nfp_mac_index_lock);\n+\tINIT_LIST_HEAD(&priv->nfp_mac_index_list);\n+\tida_init(&priv->nfp_mac_off_ids);\n+\n+\terr = register_netdevice_notifier(&priv->nfp_tun_mac_nb);\n+\tif (err)\n+\t\tgoto err_free_mac_ida;\n+\n+\t/* Parse netdevs already registered for MACs that need offloaded. */\n+\trtnl_lock();\n+\tfor_each_netdev(&init_net, netdev)\n+\t\tnfp_tun_add_to_mac_offload_list(netdev, app);\n+\trtnl_unlock();\n+\n+\treturn 0;\n+\n+err_free_mac_ida:\n+\tida_destroy(&priv->nfp_mac_off_ids);\n+\treturn err;\n+}\n+\n+void nfp_tunnel_config_stop(struct nfp_app *app)\n+{\n+\tstruct nfp_tun_mac_offload_entry *mac_entry;\n+\tstruct nfp_flower_priv *priv = app->priv;\n+\tstruct nfp_tun_mac_non_nfp_idx *mac_idx;\n+\tstruct list_head *ptr, *storage;\n+\n+\tunregister_netdevice_notifier(&priv->nfp_tun_mac_nb);\n+\n+\t/* Free any memory that may be occupied by MAC list. */\n+\tmutex_lock(&priv->nfp_mac_off_lock);\n+\tlist_for_each_safe(ptr, storage, &priv->nfp_mac_off_list) {\n+\t\tmac_entry = list_entry(ptr, struct nfp_tun_mac_offload_entry,\n+\t\t\t\t list);\n+\t\tlist_del(&mac_entry->list);\n+\t\tkfree(mac_entry);\n+\t}\n+\tmutex_unlock(&priv->nfp_mac_off_lock);\n+\n+\t/* Free any memory that may be occupied by MAC index list. */\n+\tmutex_lock(&priv->nfp_mac_index_lock);\n+\tlist_for_each_safe(ptr, storage, &priv->nfp_mac_index_list) {\n+\t\tmac_idx = list_entry(ptr, struct nfp_tun_mac_non_nfp_idx,\n+\t\t\t\t list);\n+\t\tlist_del(&mac_idx->list);\n+\t\tkfree(mac_idx);\n+\t}\n+\tmutex_unlock(&priv->nfp_mac_index_lock);\n+\n+\tida_destroy(&priv->nfp_mac_off_ids);\n+}\n", "prefixes": [ "net-next", "4/7" ] }