Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1032820/?format=api
{ "id": 1032820, "url": "http://patchwork.ozlabs.org/api/patches/1032820/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20190129150143.12681-25-mika.westerberg@linux.intel.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": "<20190129150143.12681-25-mika.westerberg@linux.intel.com>", "list_archive_url": null, "date": "2019-01-29T15:01:39", "name": "[24/28] thunderbolt: Add support for DMA tunnels", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": false, "hash": "c04edb400a90cf9ccc68d1fffe5c522f903151a4", "submitter": { "id": 14534, "url": "http://patchwork.ozlabs.org/api/people/14534/?format=api", "name": "Mika Westerberg", "email": "mika.westerberg@linux.intel.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/20190129150143.12681-25-mika.westerberg@linux.intel.com/mbox/", "series": [ { "id": 88859, "url": "http://patchwork.ozlabs.org/api/series/88859/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=88859", "date": "2019-01-29T15:01:18", "name": "thunderbolt: Software connection manager improvements", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/88859/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1032820/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1032820/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming-netdev@ozlabs.org", "Delivered-To": "patchwork-incoming-netdev@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; dmarc=none (p=none dis=none)\n\theader.from=linux.intel.com" ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 43pqVZ1npgz9sMM\n\tfor <patchwork-incoming-netdev@ozlabs.org>;\n\tWed, 30 Jan 2019 02:02:46 +1100 (AEDT)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1728829AbfA2PCl (ORCPT\n\t<rfc822;patchwork-incoming-netdev@ozlabs.org>);\n\tTue, 29 Jan 2019 10:02:41 -0500", "from mga03.intel.com ([134.134.136.65]:6191 \"EHLO mga03.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1728423AbfA2PBz (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tTue, 29 Jan 2019 10:01:55 -0500", "from fmsmga007.fm.intel.com ([10.253.24.52])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Jan 2019 07:01:54 -0800", "from black.fi.intel.com ([10.237.72.28])\n\tby fmsmga007.fm.intel.com with ESMTP; 29 Jan 2019 07:01:51 -0800", "by black.fi.intel.com (Postfix, from userid 1001)\n\tid 5786BC5A; Tue, 29 Jan 2019 17:01:45 +0200 (EET)" ], "X-Amp-Result": "SKIPPED(no attachment in message)", "X-Amp-File-Uploaded": "False", "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.56,537,1539673200\"; d=\"scan'208\";a=\"118367213\"", "From": "Mika Westerberg <mika.westerberg@linux.intel.com>", "To": "linux-kernel@vger.kernel.org", "Cc": "Michael Jamet <michael.jamet@intel.com>,\n\tYehezkel Bernat <YehezkelShB@gmail.com>,\n\tAndreas Noever <andreas.noever@gmail.com>,\n\tLukas Wunner <lukas@wunner.de>, \"David S . Miller\" <davem@davemloft.net>,\n\tMika Westerberg <mika.westerberg@linux.intel.com>,\n\tAndy Shevchenko <andriy.shevchenko@linux.intel.com>,\n\tnetdev@vger.kernel.org", "Subject": "[PATCH 24/28] thunderbolt: Add support for DMA tunnels", "Date": "Tue, 29 Jan 2019 18:01:39 +0300", "Message-Id": "<20190129150143.12681-25-mika.westerberg@linux.intel.com>", "X-Mailer": "git-send-email 2.20.1", "In-Reply-To": "<20190129150143.12681-1-mika.westerberg@linux.intel.com>", "References": "<20190129150143.12681-1-mika.westerberg@linux.intel.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "In addition to PCIe and Display Port tunnels it is also possible to\ncreate tunnels that forward DMA traffic from the host interface adapter\n(NHI) to a NULL port that is connected to another domain through a\nThunderbolt cable. These tunnels can be used to carry software messages\nsuch as networking packets.\n\nTo support this we introduce another tunnel type (TB_TUNNEL_DMA) that\nsupports paths from NHI to NULL port and back.\n\nSigned-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>\n---\n drivers/thunderbolt/path.c | 20 ++++++--\n drivers/thunderbolt/switch.c | 22 ++++++++\n drivers/thunderbolt/tb.h | 2 +\n drivers/thunderbolt/tb_regs.h | 3 ++\n drivers/thunderbolt/tunnel.c | 94 ++++++++++++++++++++++++++++++++++-\n drivers/thunderbolt/tunnel.h | 10 ++++\n 6 files changed, 147 insertions(+), 4 deletions(-)", "diff": "diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c\nindex ada60d4aa99b..afdb667fcc0d 100644\n--- a/drivers/thunderbolt/path.c\n+++ b/drivers/thunderbolt/path.c\n@@ -284,7 +284,8 @@ static void __tb_path_deallocate_nfc(struct tb_path *path, int first_hop)\n \t}\n }\n \n-static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index)\n+static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index,\n+\t\t\t\t bool clear_fc)\n {\n \tstruct tb_regs_hop hop;\n \tktime_t timeout;\n@@ -311,8 +312,20 @@ static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index)\n \t\tif (ret)\n \t\t\treturn ret;\n \n-\t\tif (!hop.pending)\n+\t\tif (!hop.pending) {\n+\t\t\tif (clear_fc) {\n+\t\t\t\t/* Clear flow control */\n+\t\t\t\thop.ingress_fc = 0;\n+\t\t\t\thop.egress_fc = 0;\n+\t\t\t\thop.ingress_shared_buffer = 0;\n+\t\t\t\thop.egress_shared_buffer = 0;\n+\n+\t\t\t\treturn tb_port_write(port, &hop, TB_CFG_HOPS,\n+\t\t\t\t\t\t 2 * hop_index, 2);\n+\t\t\t}\n+\n \t\t\treturn 0;\n+\t\t}\n \n \t\tusleep_range(10, 20);\n \t} while (ktime_before(ktime_get(), timeout));\n@@ -326,7 +339,8 @@ static void __tb_path_deactivate_hops(struct tb_path *path, int first_hop)\n \n \tfor (i = first_hop; i < path->path_length; i++) {\n \t\tres = __tb_path_deactivate_hop(path->hops[i].in_port,\n-\t\t\t\t\t path->hops[i].in_hop_index);\n+\t\t\t\t\t path->hops[i].in_hop_index,\n+\t\t\t\t\t path->clear_fc);\n \t\tif (res)\n \t\t\ttb_port_warn(path->hops[i].in_port,\n \t\t\t\t \"hop deactivation failed for hop %d, index %d\\n\",\ndiff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c\nindex 13dceddcfa48..bcf8b447facb 100644\n--- a/drivers/thunderbolt/switch.c\n+++ b/drivers/thunderbolt/switch.c\n@@ -562,6 +562,28 @@ int tb_port_add_nfc_credits(struct tb_port *port, int credits)\n \t\t\t TB_CFG_PORT, 4, 1);\n }\n \n+/**\n+ * tb_port_set_initial_credits() - Set initial port link credits allocated\n+ * @port: Port to set the initial credits\n+ * @credits: Number of credits to to allocate\n+ *\n+ * Set initial credits value to be used for ingress shared buffering.\n+ */\n+int tb_port_set_initial_credits(struct tb_port *port, u32 credits)\n+{\n+\tu32 data;\n+\tint ret;\n+\n+\tret = tb_port_read(port, &data, TB_CFG_PORT, 5, 1);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tdata &= ~TB_PORT_LCA_MASK;\n+\tdata |= (credits << TB_PORT_LCA_SHIFT) & TB_PORT_LCA_MASK;\n+\n+\treturn tb_port_write(port, &data, TB_CFG_PORT, 5, 1);\n+}\n+\n /**\n * tb_port_clear_counter() - clear a counter in TB_CFG_COUNTER\n *\ndiff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h\nindex a85b92a6936b..278b33581d68 100644\n--- a/drivers/thunderbolt/tb.h\n+++ b/drivers/thunderbolt/tb.h\n@@ -199,6 +199,7 @@ struct tb_path {\n \tint weight:4;\n \tbool drop_packages;\n \tbool activated;\n+\tbool clear_fc;\n \tstruct tb_path_hop *hops;\n \tint path_length; /* number of hops */\n };\n@@ -466,6 +467,7 @@ static inline struct tb_switch *tb_to_switch(struct device *dev)\n \n int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged);\n int tb_port_add_nfc_credits(struct tb_port *port, int credits);\n+int tb_port_set_initial_credits(struct tb_port *port, u32 credits);\n int tb_port_clear_counter(struct tb_port *port, int counter);\n int tb_port_alloc_in_hopid(struct tb_port *port, int hopid, int max_hopid);\n void tb_port_release_in_hopid(struct tb_port *port, int hopid);\ndiff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h\nindex 420d2a623f31..4591c8b1d546 100644\n--- a/drivers/thunderbolt/tb_regs.h\n+++ b/drivers/thunderbolt/tb_regs.h\n@@ -215,6 +215,9 @@ struct tb_regs_port_header {\n #define TB_PORT_NFC_CREDITS_MASK\tGENMASK(19, 0)\n #define TB_PORT_MAX_CREDITS_SHIFT\t20\n #define TB_PORT_MAX_CREDITS_MASK\tGENMASK(26, 20)\n+/* DWORD 5 */\n+#define TB_PORT_LCA_SHIFT\t\t22\n+#define TB_PORT_LCA_MASK\t\tGENMASK(28, 22)\n \n /* Display Port adapter registers */\n \ndiff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c\nindex 5dd648912032..fad18e84d475 100644\n--- a/drivers/thunderbolt/tunnel.c\n+++ b/drivers/thunderbolt/tunnel.c\n@@ -26,7 +26,10 @@\n #define TB_DP_AUX_PATH_OUT\t\t1\n #define TB_DP_AUX_PATH_IN\t\t2\n \n-static const char * const tb_tunnel_names[] = { \"PCI\", \"DP\" };\n+#define TB_DMA_PATH_OUT\t\t\t0\n+#define TB_DMA_PATH_IN\t\t\t1\n+\n+static const char * const tb_tunnel_names[] = { \"PCI\", \"DP\", \"DMA\" };\n \n #define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \\\n \tdo { \\\n@@ -461,6 +464,95 @@ struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in,\n \treturn NULL;\n }\n \n+static u32 tb_dma_credits(struct tb_port *nhi)\n+{\n+\tu32 max_credits;\n+\n+\tmax_credits = nhi->config.nfc_credits & TB_PORT_MAX_CREDITS_MASK;\n+\tmax_credits >>= TB_PORT_MAX_CREDITS_SHIFT;\n+\n+\treturn min(max_credits, 13U);\n+}\n+\n+static int tb_dma_activate(struct tb_tunnel *tunnel, bool active)\n+{\n+\tstruct tb_port *nhi = tunnel->src_port;\n+\tu32 credits;\n+\n+\tcredits = active ? tb_dma_credits(nhi) : 0;\n+\treturn tb_port_set_initial_credits(nhi, credits);\n+}\n+\n+static void tb_dma_init_path(struct tb_path *path, unsigned int isb,\n+\t\t\t unsigned int efc, u32 credits)\n+{\n+\tint i;\n+\n+\tpath->egress_fc_enable = efc;\n+\tpath->ingress_fc_enable = TB_PATH_ALL;\n+\tpath->egress_shared_buffer = TB_PATH_NONE;\n+\tpath->ingress_shared_buffer = isb;\n+\tpath->priority = 5;\n+\tpath->weight = 1;\n+\tpath->clear_fc = true;\n+\n+\tfor (i = 0; i < path->path_length; i++)\n+\t\tpath->hops[i].initial_credits = credits;\n+}\n+\n+/**\n+ * tb_tunnel_alloc_dma() - allocate a DMA tunnel\n+ * @tb: Pointer to the domain structure\n+ * @nhi: Host controller port\n+ * @dst: Destination null port which the other domain is connected to\n+ * @transmit_ring: NHI ring number used to send packets towards the\n+ *\t\t other domain\n+ * @transmit_path: HopID used for transmitting packets\n+ * @receive_ring: NHI ring number used to receive packets from the\n+ *\t\t other domain\n+ * @reveive_path: HopID used for receiving packets\n+ *\n+ * Return: Returns a tb_tunnel on success or NULL on failure.\n+ */\n+struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi,\n+\t\t\t\t struct tb_port *dst, int transmit_ring,\n+\t\t\t\t int transmit_path, int receive_ring,\n+\t\t\t\t int receive_path)\n+{\n+\tstruct tb_tunnel *tunnel;\n+\tstruct tb_path *path;\n+\tu32 credits;\n+\n+\ttunnel = tb_tunnel_alloc(tb, 2, TB_TUNNEL_DMA);\n+\tif (!tunnel)\n+\t\treturn NULL;\n+\n+\ttunnel->activate = tb_dma_activate;\n+\ttunnel->src_port = nhi;\n+\ttunnel->dst_port = dst;\n+\n+\tcredits = tb_dma_credits(nhi);\n+\n+\tpath = tb_path_alloc(tb, dst, nhi, receive_path, receive_ring, 0);\n+\tif (!path) {\n+\t\ttb_tunnel_free(tunnel);\n+\t\treturn NULL;\n+\t}\n+\ttb_dma_init_path(path, TB_PATH_NONE, TB_PATH_SOURCE | TB_PATH_INTERNAL,\n+\t\t\t credits);\n+\ttunnel->paths[TB_DMA_PATH_IN] = path;\n+\n+\tpath = tb_path_alloc(tb, nhi, dst, transmit_ring, transmit_path, 0);\n+\tif (!path) {\n+\t\ttb_tunnel_free(tunnel);\n+\t\treturn NULL;\n+\t}\n+\ttb_dma_init_path(path, TB_PATH_SOURCE, TB_PATH_ALL, credits);\n+\ttunnel->paths[TB_DMA_PATH_OUT] = path;\n+\n+\treturn tunnel;\n+}\n+\n /**\n * tb_tunnel_free() - free a tunnel\n * @tunnel: Tunnel to be freed\ndiff --git a/drivers/thunderbolt/tunnel.h b/drivers/thunderbolt/tunnel.h\nindex 07583f8247c1..fa51217e5925 100644\n--- a/drivers/thunderbolt/tunnel.h\n+++ b/drivers/thunderbolt/tunnel.h\n@@ -14,6 +14,7 @@\n enum tb_tunnel_type {\n \tTB_TUNNEL_PCI,\n \tTB_TUNNEL_DP,\n+\tTB_TUNNEL_DMA,\n };\n \n /**\n@@ -44,6 +45,10 @@ struct tb_tunnel *tb_tunnel_alloc_pci(struct tb *tb, struct tb_port *up,\n struct tb_tunnel *tb_tunnel_discover_dp(struct tb *tb, struct tb_port *in);\n struct tb_tunnel *tb_tunnel_alloc_dp(struct tb *tb, struct tb_port *in,\n \t\t\t\t struct tb_port *out);\n+struct tb_tunnel *tb_tunnel_alloc_dma(struct tb *tb, struct tb_port *nhi,\n+\t\t\t\t struct tb_port *dst, int transmit_ring,\n+\t\t\t\t int transmit_path, int receive_ring,\n+\t\t\t\t int receive_path);\n \n void tb_tunnel_free(struct tb_tunnel *tunnel);\n int tb_tunnel_activate(struct tb_tunnel *tunnel);\n@@ -61,5 +66,10 @@ static inline bool tb_tunnel_is_dp(const struct tb_tunnel *tunnel)\n \treturn tunnel->type == TB_TUNNEL_DP;\n }\n \n+static inline bool tb_tunnel_is_dma(const struct tb_tunnel *tunnel)\n+{\n+\treturn tunnel->type == TB_TUNNEL_DMA;\n+}\n+\n #endif\n \n", "prefixes": [ "24/28" ] }