{"id":815633,"url":"http://patchwork.ozlabs.org/api/patches/815633/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/20170919155700.14474-5-vivien.didelot@savoirfairelinux.com/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/projects/7/?format=json","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":"<20170919155700.14474-5-vivien.didelot@savoirfairelinux.com>","list_archive_url":null,"date":"2017-09-19T15:57:00","name":"[net-next,4/4] net: dsa: move master ethtool code","commit_ref":null,"pull_url":null,"state":"accepted","archived":true,"hash":"c7cb90130557e55e45877cddb6761c387b5302fd","submitter":{"id":15889,"url":"http://patchwork.ozlabs.org/api/people/15889/?format=json","name":"Vivien Didelot","email":"vivien.didelot@savoirfairelinux.com"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/20170919155700.14474-5-vivien.didelot@savoirfairelinux.com/mbox/","series":[{"id":3916,"url":"http://patchwork.ozlabs.org/api/series/3916/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=3916","date":"2017-09-19T15:56:59","name":"net: dsa: move master ethtool code","version":1,"mbox":"http://patchwork.ozlabs.org/series/3916/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/815633/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/815633/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>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xxSLX0sLTz9s7h\n\tfor <patchwork-incoming@ozlabs.org>;\n\tWed, 20 Sep 2017 02:02:12 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751862AbdISQB4 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tTue, 19 Sep 2017 12:01:56 -0400","from mail.savoirfairelinux.com ([208.88.110.44]:46214 \"EHLO\n\tmail.savoirfairelinux.com\" rhost-flags-OK-OK-OK-OK) by\n\tvger.kernel.org with ESMTP id S1751394AbdISQAq (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Tue, 19 Sep 2017 12:00:46 -0400","from localhost (localhost [127.0.0.1])\n\tby mail.savoirfairelinux.com (Postfix) with ESMTP id 076189C2C4A;\n\tTue, 19 Sep 2017 12:00:46 -0400 (EDT)","from mail.savoirfairelinux.com ([127.0.0.1])\n\tby localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavisd-new,\n\tport 10032)\n\twith ESMTP id GabrJ6ppPl7v; Tue, 19 Sep 2017 12:00:45 -0400 (EDT)","from localhost (localhost [127.0.0.1])\n\tby mail.savoirfairelinux.com (Postfix) with ESMTP id E8BCE9C2C65;\n\tTue, 19 Sep 2017 12:00:44 -0400 (EDT)","from mail.savoirfairelinux.com ([127.0.0.1])\n\tby localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavisd-new,\n\tport 10026)\n\twith ESMTP id JD7xZpwegRGI; Tue, 19 Sep 2017 12:00:44 -0400 (EDT)","from weeman.mtl.sfl (unknown [192.168.49.104])\n\tby mail.savoirfairelinux.com (Postfix) with ESMTPSA id B7C439C2C9C;\n\tTue, 19 Sep 2017 12:00:44 -0400 (EDT)"],"X-Virus-Scanned":"amavisd-new at mail.savoirfairelinux.com","From":"Vivien Didelot <vivien.didelot@savoirfairelinux.com>","To":"netdev@vger.kernel.org","Cc":"linux-kernel@vger.kernel.org, kernel@savoirfairelinux.com,\n\t\"David S. Miller\" <davem@davemloft.net>,\n\tFlorian Fainelli <f.fainelli@gmail.com>, Andrew Lunn <andrew@lunn.ch>,\n\tVivien Didelot <vivien.didelot@savoirfairelinux.com>","Subject":"[PATCH net-next 4/4] net: dsa: move master ethtool code","Date":"Tue, 19 Sep 2017 11:57:00 -0400","Message-Id":"<20170919155700.14474-5-vivien.didelot@savoirfairelinux.com>","X-Mailer":"git-send-email 2.14.1","In-Reply-To":"<20170919155700.14474-1-vivien.didelot@savoirfairelinux.com>","References":"<20170919155700.14474-1-vivien.didelot@savoirfairelinux.com>","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"DSA overrides the master device ethtool ops, so that it can inject stats\nfrom its dedicated switch CPU port as well.\n\nThe related code is currently split in dsa.c and slave.c, but it only\nscopes the master net device. Move it to a new master.c DSA core file.\n\nThis file will be later extented with master net device specific code.\n\nSigned-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>\n---\n net/dsa/Makefile   |   2 +-\n net/dsa/dsa.c      |  28 -------------\n net/dsa/dsa2.c     |   4 +-\n net/dsa/dsa_priv.h |   7 ++--\n net/dsa/legacy.c   |   4 +-\n net/dsa/master.c   | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n net/dsa/slave.c    |  83 ------------------------------------\n 7 files changed, 129 insertions(+), 119 deletions(-)\n create mode 100644 net/dsa/master.c","diff":"diff --git a/net/dsa/Makefile b/net/dsa/Makefile\nindex fcce25da937c..2e7ac8bab19d 100644\n--- a/net/dsa/Makefile\n+++ b/net/dsa/Makefile\n@@ -1,6 +1,6 @@\n # the core\n obj-$(CONFIG_NET_DSA) += dsa_core.o\n-dsa_core-y += dsa.o dsa2.o legacy.o port.o slave.o switch.o\n+dsa_core-y += dsa.o dsa2.o legacy.o master.o port.o slave.o switch.o\n \n # tagging formats\n dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o\ndiff --git a/net/dsa/dsa.c b/net/dsa/dsa.c\nindex abadf7b49236..81c852e32821 100644\n--- a/net/dsa/dsa.c\n+++ b/net/dsa/dsa.c\n@@ -112,34 +112,6 @@ const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol)\n \treturn ops;\n }\n \n-int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp)\n-{\n-\tstruct dsa_switch *ds = cpu_dp->ds;\n-\tstruct net_device *master;\n-\tstruct ethtool_ops *cpu_ops;\n-\n-\tmaster = cpu_dp->netdev;\n-\n-\tcpu_ops = devm_kzalloc(ds->dev, sizeof(*cpu_ops), GFP_KERNEL);\n-\tif (!cpu_ops)\n-\t\treturn -ENOMEM;\n-\n-\tcpu_dp->orig_ethtool_ops = master->ethtool_ops;\n-\tif (cpu_dp->orig_ethtool_ops)\n-\t\tmemcpy(cpu_ops, cpu_dp->orig_ethtool_ops, sizeof(*cpu_ops));\n-\n-\tdsa_cpu_port_ethtool_init(cpu_ops);\n-\tmaster->ethtool_ops = cpu_ops;\n-\n-\treturn 0;\n-}\n-\n-void dsa_cpu_port_ethtool_restore(struct dsa_port *cpu_dp)\n-{\n-\tcpu_dp->netdev->ethtool_ops = cpu_dp->orig_ethtool_ops;\n-\tcpu_dp->orig_ethtool_ops = NULL;\n-}\n-\n void dsa_cpu_dsa_destroy(struct dsa_port *port)\n {\n \tstruct device_node *port_dn = port->dn;\ndiff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c\nindex 032f8bc3e788..dcccaebde708 100644\n--- a/net/dsa/dsa2.c\n+++ b/net/dsa/dsa2.c\n@@ -440,7 +440,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)\n \twmb();\n \tdst->cpu_dp->netdev->dsa_ptr = dst;\n \n-\terr = dsa_cpu_port_ethtool_setup(dst->cpu_dp);\n+\terr = dsa_master_ethtool_setup(dst->cpu_dp->netdev);\n \tif (err)\n \t\treturn err;\n \n@@ -457,7 +457,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)\n \tif (!dst->applied)\n \t\treturn;\n \n-\tdsa_cpu_port_ethtool_restore(dst->cpu_dp);\n+\tdsa_master_ethtool_restore(dst->cpu_dp->netdev);\n \n \tdst->cpu_dp->netdev->dsa_ptr = NULL;\n \ndiff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h\nindex 9c3eeb72462d..f616b3444418 100644\n--- a/net/dsa/dsa_priv.h\n+++ b/net/dsa/dsa_priv.h\n@@ -97,8 +97,6 @@ struct dsa_slave_priv {\n int dsa_cpu_dsa_setup(struct dsa_port *port);\n void dsa_cpu_dsa_destroy(struct dsa_port *dport);\n const struct dsa_device_ops *dsa_resolve_tag_protocol(int tag_protocol);\n-int dsa_cpu_port_ethtool_setup(struct dsa_port *cpu_dp);\n-void dsa_cpu_port_ethtool_restore(struct dsa_port *cpu_dp);\n bool dsa_schedule_work(struct work_struct *work);\n \n /* legacy.c */\n@@ -112,6 +110,10 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],\n \t\t       struct net_device *dev,\n \t\t       const unsigned char *addr, u16 vid);\n \n+/* master.c */\n+int dsa_master_ethtool_setup(struct net_device *dev);\n+void dsa_master_ethtool_restore(struct net_device *dev);\n+\n /* port.c */\n int dsa_port_set_state(struct dsa_port *dp, u8 state,\n \t\t       struct switchdev_trans *trans);\n@@ -139,7 +141,6 @@ int dsa_port_vlan_del(struct dsa_port *dp,\n /* slave.c */\n extern const struct dsa_device_ops notag_netdev_ops;\n void dsa_slave_mii_bus_init(struct dsa_switch *ds);\n-void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops);\n int dsa_slave_create(struct dsa_port *port, const char *name);\n void dsa_slave_destroy(struct net_device *slave_dev);\n int dsa_slave_suspend(struct net_device *slave_dev);\ndiff --git a/net/dsa/legacy.c b/net/dsa/legacy.c\nindex 163910699db7..ae505d8e4417 100644\n--- a/net/dsa/legacy.c\n+++ b/net/dsa/legacy.c\n@@ -602,7 +602,7 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,\n \twmb();\n \tdev->dsa_ptr = dst;\n \n-\treturn dsa_cpu_port_ethtool_setup(dst->cpu_dp);\n+\treturn dsa_master_ethtool_setup(dst->cpu_dp->netdev);\n }\n \n static int dsa_probe(struct platform_device *pdev)\n@@ -667,7 +667,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)\n {\n \tint i;\n \n-\tdsa_cpu_port_ethtool_restore(dst->cpu_dp);\n+\tdsa_master_ethtool_restore(dst->cpu_dp->netdev);\n \n \tdst->cpu_dp->netdev->dsa_ptr = NULL;\n \ndiff --git a/net/dsa/master.c b/net/dsa/master.c\nnew file mode 100644\nindex 000000000000..5e5147ec5a44\n--- /dev/null\n+++ b/net/dsa/master.c\n@@ -0,0 +1,120 @@\n+/*\n+ * Handling of a master device, switching frames via its switch fabric CPU port\n+ *\n+ * Copyright (c) 2017 Savoir-faire Linux Inc.\n+ *\tVivien Didelot <vivien.didelot@savoirfairelinux.com>\n+ *\n+ * This program is free software; you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License as published by\n+ * the Free Software Foundation; either version 2 of the License, or\n+ * (at your option) any later version.\n+ */\n+\n+#include \"dsa_priv.h\"\n+\n+static void dsa_master_get_ethtool_stats(struct net_device *dev,\n+\t\t\t\t\t struct ethtool_stats *stats,\n+\t\t\t\t\t uint64_t *data)\n+{\n+\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n+\tstruct dsa_port *port = dst->cpu_dp;\n+\tstruct dsa_switch *ds = port->ds;\n+\tconst struct ethtool_ops *ops = port->orig_ethtool_ops;\n+\tint count = 0;\n+\n+\tif (ops && ops->get_sset_count && ops->get_ethtool_stats) {\n+\t\tcount = ops->get_sset_count(dev, ETH_SS_STATS);\n+\t\tops->get_ethtool_stats(dev, stats, data);\n+\t}\n+\n+\tif (ds->ops->get_ethtool_stats)\n+\t\tds->ops->get_ethtool_stats(ds, port->index, data + count);\n+}\n+\n+static int dsa_master_get_sset_count(struct net_device *dev, int sset)\n+{\n+\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n+\tstruct dsa_port *port = dst->cpu_dp;\n+\tstruct dsa_switch *ds = port->ds;\n+\tconst struct ethtool_ops *ops = port->orig_ethtool_ops;\n+\tint count = 0;\n+\n+\tif (ops && ops->get_sset_count)\n+\t\tcount += ops->get_sset_count(dev, sset);\n+\n+\tif (sset == ETH_SS_STATS && ds->ops->get_sset_count)\n+\t\tcount += ds->ops->get_sset_count(ds);\n+\n+\treturn count;\n+}\n+\n+static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset,\n+\t\t\t\t   uint8_t *data)\n+{\n+\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n+\tstruct dsa_port *port = dst->cpu_dp;\n+\tstruct dsa_switch *ds = port->ds;\n+\tconst struct ethtool_ops *ops = port->orig_ethtool_ops;\n+\tint len = ETH_GSTRING_LEN;\n+\tint mcount = 0, count;\n+\tunsigned int i;\n+\tuint8_t pfx[4];\n+\tuint8_t *ndata;\n+\n+\tsnprintf(pfx, sizeof(pfx), \"p%.2d\", port->index);\n+\t/* We do not want to be NULL-terminated, since this is a prefix */\n+\tpfx[sizeof(pfx) - 1] = '_';\n+\n+\tif (ops && ops->get_sset_count && ops->get_strings) {\n+\t\tmcount = ops->get_sset_count(dev, ETH_SS_STATS);\n+\t\tops->get_strings(dev, stringset, data);\n+\t}\n+\n+\tif (stringset == ETH_SS_STATS && ds->ops->get_strings) {\n+\t\tndata = data + mcount * len;\n+\t\t/* This function copies ETH_GSTRINGS_LEN bytes, we will mangle\n+\t\t * the output after to prepend our CPU port prefix we\n+\t\t * constructed earlier\n+\t\t */\n+\t\tds->ops->get_strings(ds, port->index, ndata);\n+\t\tcount = ds->ops->get_sset_count(ds);\n+\t\tfor (i = 0; i < count; i++) {\n+\t\t\tmemmove(ndata + (i * len + sizeof(pfx)),\n+\t\t\t\tndata + i * len, len - sizeof(pfx));\n+\t\t\tmemcpy(ndata + i * len, pfx, sizeof(pfx));\n+\t\t}\n+\t}\n+}\n+\n+int dsa_master_ethtool_setup(struct net_device *dev)\n+{\n+\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n+\tstruct dsa_port *port = dst->cpu_dp;\n+\tstruct dsa_switch *ds = port->ds;\n+\tstruct ethtool_ops *ops;\n+\n+\tops = devm_kzalloc(ds->dev, sizeof(*ops), GFP_KERNEL);\n+\tif (!ops)\n+\t\treturn -ENOMEM;\n+\n+\tport->orig_ethtool_ops = dev->ethtool_ops;\n+\tif (port->orig_ethtool_ops)\n+\t\tmemcpy(ops, port->orig_ethtool_ops, sizeof(*ops));\n+\n+\tops->get_sset_count = dsa_master_get_sset_count;\n+\tops->get_ethtool_stats = dsa_master_get_ethtool_stats;\n+\tops->get_strings = dsa_master_get_strings;\n+\n+\tdev->ethtool_ops = ops;\n+\n+\treturn 0;\n+}\n+\n+void dsa_master_ethtool_restore(struct net_device *dev)\n+{\n+\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n+\tstruct dsa_port *port = dst->cpu_dp;\n+\n+\tdev->ethtool_ops = port->orig_ethtool_ops;\n+\tport->orig_ethtool_ops = NULL;\n+}\ndiff --git a/net/dsa/slave.c b/net/dsa/slave.c\nindex 2ff4f907d137..d51b10450e1b 100644\n--- a/net/dsa/slave.c\n+++ b/net/dsa/slave.c\n@@ -567,82 +567,6 @@ static void dsa_slave_get_strings(struct net_device *dev,\n \t}\n }\n \n-static void dsa_cpu_port_get_ethtool_stats(struct net_device *dev,\n-\t\t\t\t\t   struct ethtool_stats *stats,\n-\t\t\t\t\t   uint64_t *data)\n-{\n-\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n-\tstruct dsa_port *cpu_dp = dsa_get_cpu_port(dst);\n-\tstruct dsa_switch *ds = cpu_dp->ds;\n-\tconst struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;\n-\ts8 cpu_port = cpu_dp->index;\n-\tint count = 0;\n-\n-\tif (ops && ops->get_sset_count && ops->get_ethtool_stats) {\n-\t\tcount = ops->get_sset_count(dev, ETH_SS_STATS);\n-\t\tops->get_ethtool_stats(dev, stats, data);\n-\t}\n-\n-\tif (ds->ops->get_ethtool_stats)\n-\t\tds->ops->get_ethtool_stats(ds, cpu_port, data + count);\n-}\n-\n-static int dsa_cpu_port_get_sset_count(struct net_device *dev, int sset)\n-{\n-\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n-\tstruct dsa_port *cpu_dp = dsa_get_cpu_port(dst);\n-\tstruct dsa_switch *ds = cpu_dp->ds;\n-\tconst struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;\n-\tint count = 0;\n-\n-\tif (ops && ops->get_sset_count)\n-\t\tcount += ops->get_sset_count(dev, sset);\n-\n-\tif (sset == ETH_SS_STATS && ds->ops->get_sset_count)\n-\t\tcount += ds->ops->get_sset_count(ds);\n-\n-\treturn count;\n-}\n-\n-static void dsa_cpu_port_get_strings(struct net_device *dev,\n-\t\t\t\t     uint32_t stringset, uint8_t *data)\n-{\n-\tstruct dsa_switch_tree *dst = dev->dsa_ptr;\n-\tstruct dsa_port *cpu_dp = dsa_get_cpu_port(dst);\n-\tstruct dsa_switch *ds = cpu_dp->ds;\n-\tconst struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops;\n-\ts8 cpu_port = cpu_dp->index;\n-\tint len = ETH_GSTRING_LEN;\n-\tint mcount = 0, count;\n-\tunsigned int i;\n-\tuint8_t pfx[4];\n-\tuint8_t *ndata;\n-\n-\tsnprintf(pfx, sizeof(pfx), \"p%.2d\", cpu_port);\n-\t/* We do not want to be NULL-terminated, since this is a prefix */\n-\tpfx[sizeof(pfx) - 1] = '_';\n-\n-\tif (ops && ops->get_sset_count && ops->get_strings) {\n-\t\tmcount = ops->get_sset_count(dev, ETH_SS_STATS);\n-\t\tops->get_strings(dev, stringset, data);\n-\t}\n-\n-\tif (stringset == ETH_SS_STATS && ds->ops->get_strings) {\n-\t\tndata = data + mcount * len;\n-\t\t/* This function copies ETH_GSTRINGS_LEN bytes, we will mangle\n-\t\t * the output after to prepend our CPU port prefix we\n-\t\t * constructed earlier\n-\t\t */\n-\t\tds->ops->get_strings(ds, cpu_port, ndata);\n-\t\tcount = ds->ops->get_sset_count(ds);\n-\t\tfor (i = 0; i < count; i++) {\n-\t\t\tmemmove(ndata + (i * len + sizeof(pfx)),\n-\t\t\t\tndata + i * len, len - sizeof(pfx));\n-\t\t\tmemcpy(ndata + i * len, pfx, sizeof(pfx));\n-\t\t}\n-\t}\n-}\n-\n static void dsa_slave_get_ethtool_stats(struct net_device *dev,\n \t\t\t\t\tstruct ethtool_stats *stats,\n \t\t\t\t\tuint64_t *data)\n@@ -979,13 +903,6 @@ static void dsa_slave_get_stats64(struct net_device *dev,\n \t}\n }\n \n-void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops)\n-{\n-\tops->get_sset_count = dsa_cpu_port_get_sset_count;\n-\tops->get_ethtool_stats = dsa_cpu_port_get_ethtool_stats;\n-\tops->get_strings = dsa_cpu_port_get_strings;\n-}\n-\n static int dsa_slave_get_rxnfc(struct net_device *dev,\n \t\t\t       struct ethtool_rxnfc *nfc, u32 *rule_locs)\n {\n","prefixes":["net-next","4/4"]}