|
@@ -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);
|