aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/net/cdns-emac.txt23
-rw-r--r--drivers/net/ethernet/cadence/at91_ether.c73
2 files changed, 89 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/net/cdns-emac.txt b/Documentation/devicetree/bindings/net/cdns-emac.txt
new file mode 100644
index 000000000000..09055c2495f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/cdns-emac.txt
@@ -0,0 +1,23 @@
1* Cadence EMAC Ethernet controller
2
3Required properties:
4- compatible: Should be "cdns,[<chip>-]{emac}"
5 Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
6 or the generic form: "cdns,emac".
7- reg: Address and length of the register set for the device
8- interrupts: Should contain macb interrupt
9- phy-mode: String, operation mode of the PHY interface.
10 Supported values are: "mii", "rmii".
11
12Optional properties:
13- local-mac-address: 6 bytes, mac address
14
15Examples:
16
17 macb0: ethernet@fffc4000 {
18 compatible = "cdns,at91rm9200-emac";
19 reg = <0xfffc4000 0x4000>;
20 interrupts = <21>;
21 phy-mode = "rmii";
22 local-mac-address = [3a 0e 03 04 05 06];
23 };
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c
index 0d6392d24ff7..039e7ef6c50e 100644
--- a/drivers/net/ethernet/cadence/at91_ether.c
+++ b/drivers/net/ethernet/cadence/at91_ether.c
@@ -31,6 +31,9 @@
31#include <linux/gfp.h> 31#include <linux/gfp.h>
32#include <linux/phy.h> 32#include <linux/phy.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/of.h>
35#include <linux/of_device.h>
36#include <linux/of_net.h>
34 37
35#include "macb.h" 38#include "macb.h"
36 39
@@ -443,6 +446,50 @@ static const struct net_device_ops at91ether_netdev_ops = {
443#endif 446#endif
444}; 447};
445 448
449#if defined(CONFIG_OF)
450static const struct of_device_id at91ether_dt_ids[] = {
451 { .compatible = "cdns,at91rm9200-emac" },
452 { .compatible = "cdns,emac" },
453 { /* sentinel */ }
454};
455
456MODULE_DEVICE_TABLE(of, at91ether_dt_ids);
457
458static int at91ether_get_phy_mode_dt(struct platform_device *pdev)
459{
460 struct device_node *np = pdev->dev.of_node;
461
462 if (np)
463 return of_get_phy_mode(np);
464
465 return -ENODEV;
466}
467
468static int at91ether_get_hwaddr_dt(struct macb *bp)
469{
470 struct device_node *np = bp->pdev->dev.of_node;
471
472 if (np) {
473 const char *mac = of_get_mac_address(np);
474 if (mac) {
475 memcpy(bp->dev->dev_addr, mac, ETH_ALEN);
476 return 0;
477 }
478 }
479
480 return -ENODEV;
481}
482#else
483static int at91ether_get_phy_mode_dt(struct platform_device *pdev)
484{
485 return -ENODEV;
486}
487static int at91ether_get_hwaddr_dt(struct macb *bp)
488{
489 return -ENODEV;
490}
491#endif
492
446/* 493/*
447 * Detect MAC & PHY and perform ethernet interface initialization 494 * Detect MAC & PHY and perform ethernet interface initialization
448 */ 495 */
@@ -466,7 +513,8 @@ static int __init at91ether_probe(struct platform_device *pdev)
466 lp = netdev_priv(dev); 513 lp = netdev_priv(dev);
467 lp->pdev = pdev; 514 lp->pdev = pdev;
468 lp->dev = dev; 515 lp->dev = dev;
469 lp->board_data = *board_data; 516 if (board_data)
517 lp->board_data = *board_data;
470 spin_lock_init(&lp->lock); 518 spin_lock_init(&lp->lock);
471 519
472 dev->base_addr = regs->start; /* physical base address */ 520 dev->base_addr = regs->start; /* physical base address */
@@ -496,18 +544,28 @@ static int __init at91ether_probe(struct platform_device *pdev)
496 platform_set_drvdata(pdev, dev); 544 platform_set_drvdata(pdev, dev);
497 SET_NETDEV_DEV(dev, &pdev->dev); 545 SET_NETDEV_DEV(dev, &pdev->dev);
498 546
499 get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */ 547 res = at91ether_get_hwaddr_dt(lp);
548 if (res < 0)
549 get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */
550
500 update_mac_address(dev); /* Program ethernet address into MAC */ 551 update_mac_address(dev); /* Program ethernet address into MAC */
501 552
553 res = at91ether_get_phy_mode_dt(pdev);
554 if (res < 0) {
555 if (board_data && board_data->is_rmii)
556 lp->phy_interface = PHY_INTERFACE_MODE_RMII;
557 else
558 lp->phy_interface = PHY_INTERFACE_MODE_MII;
559 } else {
560 lp->phy_interface = res;
561 }
562
502 macb_writel(lp, NCR, 0); 563 macb_writel(lp, NCR, 0);
503 564
504 if (board_data->is_rmii) { 565 if (lp->phy_interface == PHY_INTERFACE_MODE_RMII)
505 macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG) | MACB_BIT(RM9200_RMII)); 566 macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG) | MACB_BIT(RM9200_RMII));
506 lp->phy_interface = PHY_INTERFACE_MODE_RMII; 567 else
507 } else {
508 macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG)); 568 macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG));
509 lp->phy_interface = PHY_INTERFACE_MODE_MII;
510 }
511 569
512 /* Register the network interface */ 570 /* Register the network interface */
513 res = register_netdev(dev); 571 res = register_netdev(dev);
@@ -602,6 +660,7 @@ static struct platform_driver at91ether_driver = {
602 .driver = { 660 .driver = {
603 .name = DRV_NAME, 661 .name = DRV_NAME,
604 .owner = THIS_MODULE, 662 .owner = THIS_MODULE,
663 .of_match_table = of_match_ptr(at91ether_dt_ids),
605 }, 664 },
606}; 665};
607 666