Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: bcmgenet: enable driver to work without a device tree

Modify bcmgenet driver so that it can be used on Broadcom 7xxx
MIPS-based STB platforms without a device tree.

Signed-off-by: Petri Gynther <pgynther@google.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Petri Gynther and committed by
David S. Miller
b0ba512e c3582a2c

+143 -33
-1
drivers/net/ethernet/broadcom/Kconfig
··· 62 62 63 63 config BCMGENET 64 64 tristate "Broadcom GENET internal MAC support" 65 - depends on OF 66 65 select MII 67 66 select PHYLIB 68 67 select FIXED_PHY if BCMGENET=y
+21 -10
drivers/net/ethernet/broadcom/genet/bcmgenet.c
··· 42 42 #include <linux/ip.h> 43 43 #include <linux/ipv6.h> 44 44 #include <linux/phy.h> 45 + #include <linux/platform_data/bcmgenet.h> 45 46 46 47 #include <asm/unaligned.h> 47 48 ··· 2587 2586 2588 2587 static int bcmgenet_probe(struct platform_device *pdev) 2589 2588 { 2589 + struct bcmgenet_platform_data *pd = pdev->dev.platform_data; 2590 2590 struct device_node *dn = pdev->dev.of_node; 2591 - const struct of_device_id *of_id; 2591 + const struct of_device_id *of_id = NULL; 2592 2592 struct bcmgenet_priv *priv; 2593 2593 struct net_device *dev; 2594 2594 const void *macaddr; ··· 2603 2601 return -ENOMEM; 2604 2602 } 2605 2603 2606 - of_id = of_match_node(bcmgenet_match, dn); 2607 - if (!of_id) 2608 - return -EINVAL; 2604 + if (dn) { 2605 + of_id = of_match_node(bcmgenet_match, dn); 2606 + if (!of_id) 2607 + return -EINVAL; 2608 + } 2609 2609 2610 2610 priv = netdev_priv(dev); 2611 2611 priv->irq0 = platform_get_irq(pdev, 0); ··· 2619 2615 goto err; 2620 2616 } 2621 2617 2622 - macaddr = of_get_mac_address(dn); 2623 - if (!macaddr) { 2624 - dev_err(&pdev->dev, "can't find MAC address\n"); 2625 - err = -EINVAL; 2626 - goto err; 2618 + if (dn) { 2619 + macaddr = of_get_mac_address(dn); 2620 + if (!macaddr) { 2621 + dev_err(&pdev->dev, "can't find MAC address\n"); 2622 + err = -EINVAL; 2623 + goto err; 2624 + } 2625 + } else { 2626 + macaddr = pd->mac_address; 2627 2627 } 2628 2628 2629 2629 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 2667 2659 2668 2660 priv->dev = dev; 2669 2661 priv->pdev = pdev; 2670 - priv->version = (enum bcmgenet_version)of_id->data; 2662 + if (of_id) 2663 + priv->version = (enum bcmgenet_version)of_id->data; 2664 + else 2665 + priv->version = pd->genet_version; 2671 2666 2672 2667 priv->clk = devm_clk_get(&priv->pdev->dev, "enet"); 2673 2668 if (IS_ERR(priv->clk))
+104 -22
drivers/net/ethernet/broadcom/genet/bcmmii.c
··· 23 23 #include <linux/of.h> 24 24 #include <linux/of_net.h> 25 25 #include <linux/of_mdio.h> 26 + #include <linux/platform_data/bcmgenet.h> 26 27 27 28 #include "bcmgenet.h" 28 29 ··· 313 312 u32 phy_flags; 314 313 int ret; 315 314 316 - if (priv->phydev) { 317 - pr_info("PHY already attached\n"); 318 - return 0; 319 - } 320 - 321 - /* In the case of a fixed PHY, the DT node associated 322 - * to the PHY is the Ethernet MAC DT node. 323 - */ 324 - if (!priv->phy_dn && of_phy_is_fixed_link(dn)) { 325 - ret = of_phy_register_fixed_link(dn); 326 - if (ret) 327 - return ret; 328 - 329 - priv->phy_dn = of_node_get(dn); 330 - } 331 - 332 315 /* Communicate the integrated PHY revision */ 333 316 phy_flags = priv->gphy_rev; 334 317 ··· 322 337 priv->old_duplex = -1; 323 338 priv->old_pause = -1; 324 339 325 - phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, 326 - phy_flags, priv->phy_interface); 327 - if (!phydev) { 328 - pr_err("could not attach to PHY\n"); 329 - return -ENODEV; 340 + if (dn) { 341 + if (priv->phydev) { 342 + pr_info("PHY already attached\n"); 343 + return 0; 344 + } 345 + 346 + /* In the case of a fixed PHY, the DT node associated 347 + * to the PHY is the Ethernet MAC DT node. 348 + */ 349 + if (!priv->phy_dn && of_phy_is_fixed_link(dn)) { 350 + ret = of_phy_register_fixed_link(dn); 351 + if (ret) 352 + return ret; 353 + 354 + priv->phy_dn = of_node_get(dn); 355 + } 356 + 357 + phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, 358 + phy_flags, priv->phy_interface); 359 + if (!phydev) { 360 + pr_err("could not attach to PHY\n"); 361 + return -ENODEV; 362 + } 363 + } else { 364 + phydev = priv->phydev; 365 + phydev->dev_flags = phy_flags; 366 + 367 + ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, 368 + priv->phy_interface); 369 + if (ret) { 370 + pr_err("could not attach to PHY\n"); 371 + return -ENODEV; 372 + } 330 373 } 331 374 332 375 priv->phydev = phydev; ··· 451 438 return 0; 452 439 } 453 440 441 + static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) 442 + { 443 + struct device *kdev = &priv->pdev->dev; 444 + struct bcmgenet_platform_data *pd = kdev->platform_data; 445 + struct mii_bus *mdio = priv->mii_bus; 446 + struct phy_device *phydev; 447 + int ret; 448 + 449 + if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) { 450 + /* 451 + * Internal or external PHY with MDIO access 452 + */ 453 + if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR) 454 + mdio->phy_mask = ~(1 << pd->phy_address); 455 + else 456 + mdio->phy_mask = 0; 457 + 458 + ret = mdiobus_register(mdio); 459 + if (ret) { 460 + dev_err(kdev, "failed to register MDIO bus\n"); 461 + return ret; 462 + } 463 + 464 + if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR) 465 + phydev = mdio->phy_map[pd->phy_address]; 466 + else 467 + phydev = phy_find_first(mdio); 468 + 469 + if (!phydev) { 470 + dev_err(kdev, "failed to register PHY device\n"); 471 + mdiobus_unregister(mdio); 472 + return -ENODEV; 473 + } 474 + } else { 475 + /* 476 + * MoCA port or no MDIO access. 477 + * Use fixed PHY to represent the link layer. 478 + */ 479 + struct fixed_phy_status fphy_status = { 480 + .link = 1, 481 + .speed = pd->phy_speed, 482 + .duplex = pd->phy_duplex, 483 + .pause = 0, 484 + .asym_pause = 0, 485 + }; 486 + 487 + phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); 488 + if (!phydev || IS_ERR(phydev)) { 489 + dev_err(kdev, "failed to register fixed PHY device\n"); 490 + return -ENODEV; 491 + } 492 + } 493 + 494 + priv->phydev = phydev; 495 + priv->phy_interface = pd->phy_interface; 496 + 497 + return 0; 498 + } 499 + 500 + static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv) 501 + { 502 + struct device_node *dn = priv->pdev->dev.of_node; 503 + 504 + if (dn) 505 + return bcmgenet_mii_of_init(priv); 506 + else 507 + return bcmgenet_mii_pd_init(priv); 508 + } 509 + 454 510 int bcmgenet_mii_init(struct net_device *dev) 455 511 { 456 512 struct bcmgenet_priv *priv = netdev_priv(dev); ··· 529 447 if (ret) 530 448 return ret; 531 449 532 - ret = bcmgenet_mii_of_init(priv); 450 + ret = bcmgenet_mii_bus_init(priv); 533 451 if (ret) 534 452 goto out_free; 535 453
+18
include/linux/platform_data/bcmgenet.h
··· 1 + #ifndef __LINUX_PLATFORM_DATA_BCMGENET_H__ 2 + #define __LINUX_PLATFORM_DATA_BCMGENET_H__ 3 + 4 + #include <linux/types.h> 5 + #include <linux/if_ether.h> 6 + #include <linux/phy.h> 7 + 8 + struct bcmgenet_platform_data { 9 + bool mdio_enabled; 10 + phy_interface_t phy_interface; 11 + int phy_address; 12 + int phy_speed; 13 + int phy_duplex; 14 + u8 mac_address[ETH_ALEN]; 15 + int genet_version; 16 + }; 17 + 18 + #endif