0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/device.h>
0012 #include <linux/err.h>
0013 #include <linux/fwnode_mdio.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/netdevice.h>
0017 #include <linux/of.h>
0018 #include <linux/of_irq.h>
0019 #include <linux/of_mdio.h>
0020 #include <linux/of_net.h>
0021 #include <linux/phy.h>
0022 #include <linux/phy_fixed.h>
0023
0024 #define DEFAULT_GPIO_RESET_DELAY 10
0025
0026 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
0027 MODULE_LICENSE("GPL");
0028
0029
0030
0031 static int of_get_phy_id(struct device_node *device, u32 *phy_id)
0032 {
0033 return fwnode_get_phy_id(of_fwnode_handle(device), phy_id);
0034 }
0035
0036 int of_mdiobus_phy_device_register(struct mii_bus *mdio, struct phy_device *phy,
0037 struct device_node *child, u32 addr)
0038 {
0039 return fwnode_mdiobus_phy_device_register(mdio, phy,
0040 of_fwnode_handle(child),
0041 addr);
0042 }
0043 EXPORT_SYMBOL(of_mdiobus_phy_device_register);
0044
0045 static int of_mdiobus_register_phy(struct mii_bus *mdio,
0046 struct device_node *child, u32 addr)
0047 {
0048 return fwnode_mdiobus_register_phy(mdio, of_fwnode_handle(child), addr);
0049 }
0050
0051 static int of_mdiobus_register_device(struct mii_bus *mdio,
0052 struct device_node *child, u32 addr)
0053 {
0054 struct fwnode_handle *fwnode = of_fwnode_handle(child);
0055 struct mdio_device *mdiodev;
0056 int rc;
0057
0058 mdiodev = mdio_device_create(mdio, addr);
0059 if (IS_ERR(mdiodev))
0060 return PTR_ERR(mdiodev);
0061
0062
0063
0064
0065 fwnode_handle_get(fwnode);
0066 device_set_node(&mdiodev->dev, fwnode);
0067
0068
0069 rc = mdio_device_register(mdiodev);
0070 if (rc) {
0071 mdio_device_free(mdiodev);
0072 of_node_put(child);
0073 return rc;
0074 }
0075
0076 dev_dbg(&mdio->dev, "registered mdio device %pOFn at address %i\n",
0077 child, addr);
0078 return 0;
0079 }
0080
0081
0082
0083
0084
0085
0086
0087 static const struct of_device_id whitelist_phys[] = {
0088 { .compatible = "brcm,40nm-ephy" },
0089 { .compatible = "broadcom,bcm5241" },
0090 { .compatible = "marvell,88E1111", },
0091 { .compatible = "marvell,88e1116", },
0092 { .compatible = "marvell,88e1118", },
0093 { .compatible = "marvell,88e1145", },
0094 { .compatible = "marvell,88e1149r", },
0095 { .compatible = "marvell,88e1310", },
0096 { .compatible = "marvell,88E1510", },
0097 { .compatible = "marvell,88E1514", },
0098 { .compatible = "moxa,moxart-rtl8201cp", },
0099 {}
0100 };
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 bool of_mdiobus_child_is_phy(struct device_node *child)
0114 {
0115 u32 phy_id;
0116
0117 if (of_get_phy_id(child, &phy_id) != -EINVAL)
0118 return true;
0119
0120 if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"))
0121 return true;
0122
0123 if (of_device_is_compatible(child, "ethernet-phy-ieee802.3-c22"))
0124 return true;
0125
0126 if (of_match_node(whitelist_phys, child)) {
0127 pr_warn(FW_WARN
0128 "%pOF: Whitelisted compatible string. Please remove\n",
0129 child);
0130 return true;
0131 }
0132
0133 if (!of_find_property(child, "compatible", NULL))
0134 return true;
0135
0136 return false;
0137 }
0138 EXPORT_SYMBOL(of_mdiobus_child_is_phy);
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
0149 {
0150 struct device_node *child;
0151 bool scanphys = false;
0152 int addr, rc;
0153
0154 if (!np)
0155 return mdiobus_register(mdio);
0156
0157
0158 if (!of_device_is_available(np))
0159 return -ENODEV;
0160
0161
0162
0163 mdio->phy_mask = ~0;
0164
0165 device_set_node(&mdio->dev, of_fwnode_handle(np));
0166
0167
0168 mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY;
0169 of_property_read_u32(np, "reset-delay-us", &mdio->reset_delay_us);
0170 mdio->reset_post_delay_us = 0;
0171 of_property_read_u32(np, "reset-post-delay-us", &mdio->reset_post_delay_us);
0172
0173
0174 rc = mdiobus_register(mdio);
0175 if (rc)
0176 return rc;
0177
0178
0179 for_each_available_child_of_node(np, child) {
0180 addr = of_mdio_parse_addr(&mdio->dev, child);
0181 if (addr < 0) {
0182 scanphys = true;
0183 continue;
0184 }
0185
0186 if (of_mdiobus_child_is_phy(child))
0187 rc = of_mdiobus_register_phy(mdio, child, addr);
0188 else
0189 rc = of_mdiobus_register_device(mdio, child, addr);
0190
0191 if (rc == -ENODEV)
0192 dev_err(&mdio->dev,
0193 "MDIO device at address %d is missing.\n",
0194 addr);
0195 else if (rc)
0196 goto unregister;
0197 }
0198
0199 if (!scanphys)
0200 return 0;
0201
0202
0203 for_each_available_child_of_node(np, child) {
0204
0205 if (of_find_property(child, "reg", NULL))
0206 continue;
0207
0208 for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
0209
0210 if (mdiobus_is_registered_device(mdio, addr))
0211 continue;
0212
0213
0214 dev_info(&mdio->dev, "scan phy %pOFn at address %i\n",
0215 child, addr);
0216
0217 if (of_mdiobus_child_is_phy(child)) {
0218
0219
0220
0221
0222 rc = of_mdiobus_register_phy(mdio, child, addr);
0223 if (!rc)
0224 break;
0225 if (rc != -ENODEV)
0226 goto unregister;
0227 }
0228 }
0229 }
0230
0231 return 0;
0232
0233 unregister:
0234 of_node_put(child);
0235 mdiobus_unregister(mdio);
0236 return rc;
0237 }
0238 EXPORT_SYMBOL(of_mdiobus_register);
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 struct mdio_device *of_mdio_find_device(struct device_node *np)
0249 {
0250 return fwnode_mdio_find_device(of_fwnode_handle(np));
0251 }
0252 EXPORT_SYMBOL(of_mdio_find_device);
0253
0254
0255
0256
0257
0258
0259
0260
0261 struct phy_device *of_phy_find_device(struct device_node *phy_np)
0262 {
0263 return fwnode_phy_find_device(of_fwnode_handle(phy_np));
0264 }
0265 EXPORT_SYMBOL(of_phy_find_device);
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 struct phy_device *of_phy_connect(struct net_device *dev,
0280 struct device_node *phy_np,
0281 void (*hndlr)(struct net_device *), u32 flags,
0282 phy_interface_t iface)
0283 {
0284 struct phy_device *phy = of_phy_find_device(phy_np);
0285 int ret;
0286
0287 if (!phy)
0288 return NULL;
0289
0290 phy->dev_flags |= flags;
0291
0292 ret = phy_connect_direct(dev, phy, hndlr, iface);
0293
0294
0295 put_device(&phy->mdio.dev);
0296
0297 return ret ? NULL : phy;
0298 }
0299 EXPORT_SYMBOL(of_phy_connect);
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 struct phy_device *of_phy_get_and_connect(struct net_device *dev,
0313 struct device_node *np,
0314 void (*hndlr)(struct net_device *))
0315 {
0316 phy_interface_t iface;
0317 struct device_node *phy_np;
0318 struct phy_device *phy;
0319 int ret;
0320
0321 ret = of_get_phy_mode(np, &iface);
0322 if (ret)
0323 return NULL;
0324 if (of_phy_is_fixed_link(np)) {
0325 ret = of_phy_register_fixed_link(np);
0326 if (ret < 0) {
0327 netdev_err(dev, "broken fixed-link specification\n");
0328 return NULL;
0329 }
0330 phy_np = of_node_get(np);
0331 } else {
0332 phy_np = of_parse_phandle(np, "phy-handle", 0);
0333 if (!phy_np)
0334 return NULL;
0335 }
0336
0337 phy = of_phy_connect(dev, phy_np, hndlr, 0, iface);
0338
0339 of_node_put(phy_np);
0340
0341 return phy;
0342 }
0343 EXPORT_SYMBOL(of_phy_get_and_connect);
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 bool of_phy_is_fixed_link(struct device_node *np)
0354 {
0355 struct device_node *dn;
0356 int len, err;
0357 const char *managed;
0358
0359
0360 dn = of_get_child_by_name(np, "fixed-link");
0361 if (dn) {
0362 of_node_put(dn);
0363 return true;
0364 }
0365
0366 err = of_property_read_string(np, "managed", &managed);
0367 if (err == 0 && strcmp(managed, "auto") != 0)
0368 return true;
0369
0370
0371 if (of_get_property(np, "fixed-link", &len) &&
0372 len == (5 * sizeof(__be32)))
0373 return true;
0374
0375 return false;
0376 }
0377 EXPORT_SYMBOL(of_phy_is_fixed_link);
0378
0379 int of_phy_register_fixed_link(struct device_node *np)
0380 {
0381 struct fixed_phy_status status = {};
0382 struct device_node *fixed_link_node;
0383 u32 fixed_link_prop[5];
0384 const char *managed;
0385
0386 if (of_property_read_string(np, "managed", &managed) == 0 &&
0387 strcmp(managed, "in-band-status") == 0) {
0388
0389 goto register_phy;
0390 }
0391
0392
0393 fixed_link_node = of_get_child_by_name(np, "fixed-link");
0394 if (fixed_link_node) {
0395 status.link = 1;
0396 status.duplex = of_property_read_bool(fixed_link_node,
0397 "full-duplex");
0398 if (of_property_read_u32(fixed_link_node, "speed",
0399 &status.speed)) {
0400 of_node_put(fixed_link_node);
0401 return -EINVAL;
0402 }
0403 status.pause = of_property_read_bool(fixed_link_node, "pause");
0404 status.asym_pause = of_property_read_bool(fixed_link_node,
0405 "asym-pause");
0406 of_node_put(fixed_link_node);
0407
0408 goto register_phy;
0409 }
0410
0411
0412 if (of_property_read_u32_array(np, "fixed-link", fixed_link_prop,
0413 ARRAY_SIZE(fixed_link_prop)) == 0) {
0414 status.link = 1;
0415 status.duplex = fixed_link_prop[1];
0416 status.speed = fixed_link_prop[2];
0417 status.pause = fixed_link_prop[3];
0418 status.asym_pause = fixed_link_prop[4];
0419 goto register_phy;
0420 }
0421
0422 return -ENODEV;
0423
0424 register_phy:
0425 return PTR_ERR_OR_ZERO(fixed_phy_register(PHY_POLL, &status, np));
0426 }
0427 EXPORT_SYMBOL(of_phy_register_fixed_link);
0428
0429 void of_phy_deregister_fixed_link(struct device_node *np)
0430 {
0431 struct phy_device *phydev;
0432
0433 phydev = of_phy_find_device(np);
0434 if (!phydev)
0435 return;
0436
0437 fixed_phy_unregister(phydev);
0438
0439 put_device(&phydev->mdio.dev);
0440 phy_device_free(phydev);
0441 }
0442 EXPORT_SYMBOL(of_phy_deregister_fixed_link);