aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mscc/ocelot_board.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot_board.c')
-rw-r--r--drivers/net/ethernet/mscc/ocelot_board.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c
index dca205e0ef75..953b32677383 100644
--- a/drivers/net/ethernet/mscc/ocelot_board.c
+++ b/drivers/net/ethernet/mscc/ocelot_board.c
@@ -6,6 +6,7 @@
*/
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/of_net.h>
#include <linux/netdevice.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
@@ -253,18 +254,12 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&ocelot->multicast);
ocelot_init(ocelot);
- ocelot_rmw(ocelot, HSIO_HW_CFG_DEV1G_4_MODE |
- HSIO_HW_CFG_DEV1G_6_MODE |
- HSIO_HW_CFG_DEV1G_9_MODE,
- HSIO_HW_CFG_DEV1G_4_MODE |
- HSIO_HW_CFG_DEV1G_6_MODE |
- HSIO_HW_CFG_DEV1G_9_MODE,
- HSIO_HW_CFG);
-
for_each_available_child_of_node(ports, portnp) {
struct device_node *phy_node;
struct phy_device *phy;
struct resource *res;
+ struct phy *serdes;
+ enum phy_mode phy_mode;
void __iomem *regs;
char res_name[8];
u32 port;
@@ -289,10 +284,45 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
continue;
err = ocelot_probe_port(ocelot, port, regs, phy);
- if (err) {
- dev_err(&pdev->dev, "failed to probe ports\n");
+ if (err)
+ return err;
+
+ err = of_get_phy_mode(portnp);
+ if (err < 0)
+ ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA;
+ else
+ ocelot->ports[port]->phy_mode = err;
+
+ switch (ocelot->ports[port]->phy_mode) {
+ case PHY_INTERFACE_MODE_NA:
+ continue;
+ case PHY_INTERFACE_MODE_SGMII:
+ phy_mode = PHY_MODE_SGMII;
+ break;
+ case PHY_INTERFACE_MODE_QSGMII:
+ phy_mode = PHY_MODE_QSGMII;
+ break;
+ default:
+ dev_err(ocelot->dev,
+ "invalid phy mode for port%d, (Q)SGMII only\n",
+ port);
+ return -EINVAL;
+ }
+
+ serdes = devm_of_phy_get(ocelot->dev, portnp, NULL);
+ if (IS_ERR(serdes)) {
+ err = PTR_ERR(serdes);
+ if (err == -EPROBE_DEFER)
+ dev_dbg(ocelot->dev, "deferring probe\n");
+ else
+ dev_err(ocelot->dev,
+ "missing SerDes phys for port%d\n",
+ port);
+
goto err_probe_ports;
}
+
+ ocelot->ports[port]->serdes = serdes;
}
register_netdevice_notifier(&ocelot_netdevice_nb);