[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <1400043637-9799-6-git-send-email-f.fainelli@gmail.com>
Date: Tue, 13 May 2014 22:00:31 -0700
From: Florian Fainelli <f.fainelli@...il.com>
To: netdev@...r.kernel.org
Cc: davem@...emloft.net, Florian Fainelli <f.fainelli@...il.com>,
nhorman@...driver.com, andy@...yhouse.net, tgraf@...g.ch,
dborkman@...hat.com, ogerlitz@...lanox.com, jesse@...ira.com,
pshelar@...ira.com, azhou@...ira.com, ben@...adent.org.uk,
stephen@...workplumber.org, jeffrey.t.kirsher@...el.com,
vyasevic@...hat.com, xiyou.wangcong@...il.com,
john.r.fastabend@...el.com, edumazet@...gle.com, jhs@...atatu.com,
sfeldma@...ulusnetworks.com, roopa@...ulusnetworks.com,
linville@...driver.com, jasowang@...hat.com, ebiederm@...ssion.com,
nicolas.dichtel@...nd.com, ryazanov.s.a@...il.com,
buytenh@...tstofly.org, aviadr@...lanox.com, nbd@...nwrt.org,
alexei.starovoitov@...il.com, Neil.Jerram@...aswitch.com
Subject: [RFC net-next 05/11] net: dsa: allow for more complex PHY setups
Modify the DSA slave interface to be bound to an arbitray PHY, not just
the ones that are available as child PHY devices of the switch MDIO bus.
This allows us for instance to have external PHYs connected to a
separate MDIO bus, but yet also connected to a given switch port.
Signed-off-by: Florian Fainelli <f.fainelli@...il.com>
---
net/dsa/dsa_priv.h | 4 ++++
net/dsa/slave.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index d4cf5cc747e3..a7f6f0c5fa31 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -33,6 +33,10 @@ struct dsa_slave_priv {
* to this port.
*/
struct phy_device *phy;
+ phy_interface_t phy_interface;
+ int old_link;
+ int old_pause;
+ int old_duplex;
};
/* dsa.c */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 64c5af0a10dd..d2dbd271300a 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -12,6 +12,8 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/phy.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
#include "dsa_priv.h"
/* slave mii_bus handling ***************************************************/
@@ -330,7 +332,60 @@ static const struct net_device_ops trailer_netdev_ops = {
};
#endif
+static void dsa_slave_adjust_link(struct net_device *dev)
+{
+ struct dsa_slave_priv *p = netdev_priv(dev);
+ unsigned int status_changed = 0;
+
+ if (p->old_link != p->phy->link) {
+ status_changed = 1;
+ p->old_link = p->phy->link;
+ }
+
+ if (p->old_duplex != p->phy->duplex) {
+ status_changed = 1;
+ p->old_duplex = p->phy->duplex;
+ }
+
+ if (p->old_pause != p->phy->pause) {
+ status_changed = 1;
+ p->old_pause = p->phy->pause;
+ }
+
+ if (status_changed)
+ phy_print_status(p->phy);
+}
+
/* slave device setup *******************************************************/
+static void dsa_slave_phy_setup(struct dsa_slave_priv *p,
+ struct net_device *slave_dev)
+{
+ struct dsa_switch *ds = p->parent;
+ struct dsa_chip_data *cd = ds->pd;
+ struct device_node *phy_dn;
+
+ p->phy_interface = of_get_phy_mode(cd->port_dn[p->port]);
+
+ phy_dn = of_parse_phandle(cd->port_dn[p->port], "phy-handle", 0);
+ if (phy_dn)
+ p->phy = of_phy_connect(slave_dev, phy_dn,
+ dsa_slave_adjust_link, 0,
+ p->phy_interface);
+ else
+ p->phy = of_phy_connect_fixed_link(slave_dev,
+ dsa_slave_adjust_link,
+ p->phy_interface);
+
+ /* We could not connect to a designated PHY, so use the switch internal
+ * MDIO bus instead
+ */
+ if (!p->phy)
+ p->phy = ds->slave_mii_bus->phy_map[p->port];
+ else
+ pr_info("attached PHY at address %d [%s]\n",
+ p->phy->addr, p->phy->drv->name);
+}
+
struct net_device *
dsa_slave_create(struct dsa_switch *ds, struct device *parent,
int port, char *name)
@@ -370,6 +425,7 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
BUG();
}
+ parent->of_node = ds->pd->port_dn[port];
SET_NETDEV_DEV(slave_dev, parent);
slave_dev->vlan_features = master->vlan_features;
@@ -377,7 +433,8 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
p->dev = slave_dev;
p->parent = ds;
p->port = port;
- p->phy = ds->slave_mii_bus->phy_map[port];
+
+ dsa_slave_phy_setup(p, slave_dev);
ret = register_netdev(slave_dev);
if (ret) {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists