From patchwork Thu Jan 12 03:41:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Fainelli X-Patchwork-Id: 9512017 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6BA0E60710 for ; Thu, 12 Jan 2017 03:43:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C1892864B for ; Thu, 12 Jan 2017 03:43:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4EF1B2865F; Thu, 12 Jan 2017 03:43:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E748F2864B for ; Thu, 12 Jan 2017 03:43:40 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cRWIe-0000no-Ew; Thu, 12 Jan 2017 03:43:40 +0000 Received: from mail-oi0-x244.google.com ([2607:f8b0:4003:c06::244]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cRWHM-000749-Cj for linux-arm-kernel@lists.infradead.org; Thu, 12 Jan 2017 03:42:27 +0000 Received: by mail-oi0-x244.google.com with SMTP id x84so1138662oix.2 for ; Wed, 11 Jan 2017 19:42:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=khWEMgxAmI8YFLxTjCRszJG/POM9B8I20JKGCBPEigE=; b=WiADkM8r3wYgQ5joULpCL5ow6qWVlcFhlMxDG7Ir1RPMNYS7HyuAVeNhgwCHIpbX1o Wf1EgWWcVZFyq7bbeUirRvZ1jW6+vPzLIOOWTcn+PIAIcV2bLH4R6bV5hgJzlIFCFNj/ GDU3pWMckGKsTBdA5yO6MqPRC0HVuieB1HvdZpgZ+SNNh/n4ZTa0mx2UEf3pi4Gnkijx P0uIErzV4cFNGWtROb0OrSXeWiAcncLI7LOLEwf/tacDg+zizh2KechWi51FecCQ5Njv oUO3clEyeAKplLpOQizsKWSTnBPdXkgA5fnc38ixjPWcKqu3IWVswbOgX+QAHAPaV8X6 OM3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=khWEMgxAmI8YFLxTjCRszJG/POM9B8I20JKGCBPEigE=; b=sv412Kalehhte7qZ59xEiFMXWv1S6xLE7qZAYiUAcZd9de7WZiaGvAEBCzq49/vww5 xD4smRjH5iTd1UF1/craECCYTRBNlhw9KZ8DhTURkmCBUDuSUYGhH+xRVJtRpjpeCIAP LTDr2ims1eHrICt1xhHZG6xNJNMillLf11SblQMy4Fsb6RyO8imAECWJZp9qLeZAMTcj KJjZE7Wz013qKHQOFa7ox6BzKUkRFg0lpPVlXK/1M083oHjbLTVkTk+ad3XZ1lhEoRGz WJ2Xr4+qgcw6TUlFr9g5riSQX70KFsfRBkbltFdYG/tIEKvWuVZYwJdVHStErMbBmdu2 BWSg== X-Gm-Message-State: AIkVDXKE85uCSDZNN5vw1gwBGOhGsvAPoW+MOJrarkvh6EMCp4eF5Vv9MrV8hTXMIvDsVg== X-Received: by 10.157.21.119 with SMTP id z52mr6254774otz.46.1484192520764; Wed, 11 Jan 2017 19:42:00 -0800 (PST) Received: from fainelli-laptop.lan ([2001:470:d:73f:b16f:f382:be58:4136]) by smtp.gmail.com with ESMTPSA id f7sm3585543otb.34.2017.01.11.19.41.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Jan 2017 19:42:00 -0800 (PST) From: Florian Fainelli To: netdev@vger.kernel.org Subject: [PATCH net-next v2 08/10] net: dsa: Add support for platform data Date: Wed, 11 Jan 2017 19:41:19 -0800 Message-Id: <20170112034121.27697-9-f.fainelli@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170112034121.27697-1-f.fainelli@gmail.com> References: <20170112034121.27697-1-f.fainelli@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170111_194220_775330_064F50BF X-CRM114-Status: GOOD ( 19.50 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Lunn , Florian Fainelli , Jason Cooper , Vivien Didelot , gregkh@linuxfoundation.org, Russell King , open list , Gregory Clement , "David S. Miller" , "moderated list:ARM SUB-ARCHITECTURES" , Sebastian Hesselbarth MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Allow drivers to use the new DSA API with platform data. Most of the code in net/dsa/dsa2.c does not rely so much on device_nodes and can get the same information from platform_data instead. We purposely do not support distributed configurations with platform data, so drivers should be providing a pointer to a 'struct dsa_chip_data' structure if they wish to communicate per-port layout. Multiple CPUs port could potentially be supported and dsa_chip_data is extended to receive up to one reference to an upstream network device per port described by a dsa_chip_data structure. Signed-off-by: Florian Fainelli --- include/net/dsa.h | 6 ++++ net/dsa/dsa2.c | 95 ++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index 16a502a6c26a..491008792e4d 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -42,6 +42,11 @@ struct dsa_chip_data { struct device *host_dev; int sw_addr; + /* + * Reference to network devices + */ + struct device *netdev[DSA_MAX_PORTS]; + /* set to size of eeprom if supported by the switch */ int eeprom_len; @@ -140,6 +145,7 @@ struct dsa_switch_tree { }; struct dsa_port { + const char *name; struct net_device *netdev; struct device_node *dn; unsigned int ageing_time; diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index cd91070b5467..d326fc4afad7 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -81,17 +81,23 @@ static void dsa_dst_del_ds(struct dsa_switch_tree *dst, static bool dsa_port_is_valid(struct dsa_port *port) { - return !!port->dn; + return !!(port->dn || port->name); } static bool dsa_port_is_dsa(struct dsa_port *port) { - return !!of_parse_phandle(port->dn, "link", 0); + if (port->name && !strcmp(port->name, "dsa")) + return true; + else + return !!of_parse_phandle(port->dn, "link", 0); } static bool dsa_port_is_cpu(struct dsa_port *port) { - return !!of_parse_phandle(port->dn, "ethernet", 0); + if (port->name && !strcmp(port->name, "cpu")) + return true; + else + return !!of_parse_phandle(port->dn, "ethernet", 0); } static bool dsa_ds_find_port_dn(struct dsa_switch *ds, @@ -251,10 +257,11 @@ static void dsa_cpu_port_unapply(struct dsa_port *port, u32 index, static int dsa_user_port_apply(struct dsa_port *port, u32 index, struct dsa_switch *ds) { - const char *name; + const char *name = port->name; int err; - name = of_get_property(port->dn, "label", NULL); + if (port->dn) + name = of_get_property(port->dn, "label", NULL); if (!name) name = "eth%d"; @@ -439,11 +446,15 @@ static int dsa_cpu_parse(struct dsa_port *port, u32 index, struct net_device *ethernet_dev; struct device_node *ethernet; - ethernet = of_parse_phandle(port->dn, "ethernet", 0); - if (!ethernet) - return -EINVAL; + if (port->dn) { + ethernet = of_parse_phandle(port->dn, "ethernet", 0); + if (!ethernet) + return -EINVAL; + ethernet_dev = of_find_net_device_by_node(ethernet); + } else { + ethernet_dev = dev_to_net_device(ds->cd->netdev[index]); + } - ethernet_dev = of_find_net_device_by_node(ethernet); if (!ethernet_dev) return -EPROBE_DEFER; @@ -546,6 +557,33 @@ static int dsa_parse_ports_dn(struct device_node *ports, struct dsa_switch *ds) return 0; } +static int dsa_parse_ports(struct dsa_chip_data *cd, struct dsa_switch *ds) +{ + bool valid_name_found = false; + unsigned int i; + + for (i = 0; i < DSA_MAX_PORTS; i++) { + if (!cd->port_names[i]) + continue; + + ds->ports[i].name = cd->port_names[i]; + + /* Initialize enabled_port_mask now for drv->setup() + * to have access to a correct value, just like what + * net/dsa/dsa.c::dsa_switch_setup_one does. + */ + if (!dsa_port_is_cpu(&ds->ports[i])) + ds->enabled_port_mask |= 1 << i; + + valid_name_found= true; + } + + if (!valid_name_found && i == DSA_MAX_PORTS) + return -EINVAL; + + return 0; +} + static int dsa_parse_member_dn(struct device_node *np, u32 *tree, u32 *index) { int err; @@ -570,6 +608,15 @@ static int dsa_parse_member_dn(struct device_node *np, u32 *tree, u32 *index) return 0; } +static int dsa_parse_member(struct dsa_chip_data *pd, u32 *tree, u32 *index) +{ + /* We do not support complex trees with dsa_chip_data */ + *tree = 0; + *index = 0; + + return 0; +} + static struct device_node *dsa_get_ports(struct dsa_switch *ds, struct device_node *np) { @@ -586,23 +633,34 @@ static struct device_node *dsa_get_ports(struct dsa_switch *ds, static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev) { + struct dsa_chip_data *pdata = dev->platform_data; struct device_node *np = dev->of_node; struct dsa_switch_tree *dst; struct device_node *ports; u32 tree, index; int i, err; - err = dsa_parse_member_dn(np, &tree, &index); - if (err) - return err; + if (np) { + err = dsa_parse_member_dn(np, &tree, &index); + if (err) + return err; - ports = dsa_get_ports(ds, np); - if (IS_ERR(ports)) - return PTR_ERR(ports); + ports = dsa_get_ports(ds, np); + if (IS_ERR(ports)) + return PTR_ERR(ports); - err = dsa_parse_ports_dn(ports, ds); - if (err) - return err; + err = dsa_parse_ports_dn(ports, ds); + if (err) + return err; + } else { + err = dsa_parse_member(pdata, &tree, &index); + if (err) + return err; + + err = dsa_parse_ports(pdata, ds); + if (err) + return err; + } dst = dsa_get_dst(tree); if (!dst) { @@ -618,6 +676,7 @@ static int _dsa_register_switch(struct dsa_switch *ds, struct device *dev) ds->dst = dst; ds->index = index; + ds->cd = pdata; /* Initialize the routing table */ for (i = 0; i < DSA_MAX_SWITCHES; ++i)