diff options
Diffstat (limited to 'drivers/net/ethernet/arc/emac_main.c')
| -rw-r--r-- | drivers/net/ethernet/arc/emac_main.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index eeecc29cf5b7..d647a7d115ac 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c | |||
| @@ -574,6 +574,18 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) | |||
| 574 | return NETDEV_TX_OK; | 574 | return NETDEV_TX_OK; |
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | static void arc_emac_set_address_internal(struct net_device *ndev) | ||
| 578 | { | ||
| 579 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
| 580 | unsigned int addr_low, addr_hi; | ||
| 581 | |||
| 582 | addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]); | ||
| 583 | addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]); | ||
| 584 | |||
| 585 | arc_reg_set(priv, R_ADDRL, addr_low); | ||
| 586 | arc_reg_set(priv, R_ADDRH, addr_hi); | ||
| 587 | } | ||
| 588 | |||
| 577 | /** | 589 | /** |
| 578 | * arc_emac_set_address - Set the MAC address for this device. | 590 | * arc_emac_set_address - Set the MAC address for this device. |
| 579 | * @ndev: Pointer to net_device structure. | 591 | * @ndev: Pointer to net_device structure. |
| @@ -587,9 +599,7 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) | |||
| 587 | */ | 599 | */ |
| 588 | static int arc_emac_set_address(struct net_device *ndev, void *p) | 600 | static int arc_emac_set_address(struct net_device *ndev, void *p) |
| 589 | { | 601 | { |
| 590 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
| 591 | struct sockaddr *addr = p; | 602 | struct sockaddr *addr = p; |
| 592 | unsigned int addr_low, addr_hi; | ||
| 593 | 603 | ||
| 594 | if (netif_running(ndev)) | 604 | if (netif_running(ndev)) |
| 595 | return -EBUSY; | 605 | return -EBUSY; |
| @@ -599,11 +609,7 @@ static int arc_emac_set_address(struct net_device *ndev, void *p) | |||
| 599 | 609 | ||
| 600 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); | 610 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); |
| 601 | 611 | ||
| 602 | addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]); | 612 | arc_emac_set_address_internal(ndev); |
| 603 | addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]); | ||
| 604 | |||
| 605 | arc_reg_set(priv, R_ADDRL, addr_low); | ||
| 606 | arc_reg_set(priv, R_ADDRH, addr_hi); | ||
| 607 | 613 | ||
| 608 | return 0; | 614 | return 0; |
| 609 | } | 615 | } |
| @@ -643,13 +649,6 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 643 | return -ENODEV; | 649 | return -ENODEV; |
| 644 | } | 650 | } |
| 645 | 651 | ||
| 646 | /* Get CPU clock frequency from device tree */ | ||
| 647 | if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", | ||
| 648 | &clock_frequency)) { | ||
| 649 | dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n"); | ||
| 650 | return -EINVAL; | ||
| 651 | } | ||
| 652 | |||
| 653 | /* Get IRQ from device tree */ | 652 | /* Get IRQ from device tree */ |
| 654 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); | 653 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
| 655 | if (!irq) { | 654 | if (!irq) { |
| @@ -677,17 +676,36 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 677 | priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs); | 676 | priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs); |
| 678 | if (IS_ERR(priv->regs)) { | 677 | if (IS_ERR(priv->regs)) { |
| 679 | err = PTR_ERR(priv->regs); | 678 | err = PTR_ERR(priv->regs); |
| 680 | goto out; | 679 | goto out_netdev; |
| 681 | } | 680 | } |
| 682 | dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs); | 681 | dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs); |
| 683 | 682 | ||
| 683 | priv->clk = of_clk_get(pdev->dev.of_node, 0); | ||
| 684 | if (IS_ERR(priv->clk)) { | ||
| 685 | /* Get CPU clock frequency from device tree */ | ||
| 686 | if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", | ||
| 687 | &clock_frequency)) { | ||
| 688 | dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n"); | ||
| 689 | err = -EINVAL; | ||
| 690 | goto out_netdev; | ||
| 691 | } | ||
| 692 | } else { | ||
| 693 | err = clk_prepare_enable(priv->clk); | ||
| 694 | if (err) { | ||
| 695 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
| 696 | goto out_clkget; | ||
| 697 | } | ||
| 698 | |||
| 699 | clock_frequency = clk_get_rate(priv->clk); | ||
| 700 | } | ||
| 701 | |||
| 684 | id = arc_reg_get(priv, R_ID); | 702 | id = arc_reg_get(priv, R_ID); |
| 685 | 703 | ||
| 686 | /* Check for EMAC revision 5 or 7, magic number */ | 704 | /* Check for EMAC revision 5 or 7, magic number */ |
| 687 | if (!(id == 0x0005fd02 || id == 0x0007fd02)) { | 705 | if (!(id == 0x0005fd02 || id == 0x0007fd02)) { |
| 688 | dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id); | 706 | dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id); |
| 689 | err = -ENODEV; | 707 | err = -ENODEV; |
| 690 | goto out; | 708 | goto out_clken; |
| 691 | } | 709 | } |
| 692 | dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id); | 710 | dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id); |
| 693 | 711 | ||
| @@ -702,7 +720,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 702 | ndev->name, ndev); | 720 | ndev->name, ndev); |
| 703 | if (err) { | 721 | if (err) { |
| 704 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 722 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
| 705 | goto out; | 723 | goto out_clken; |
| 706 | } | 724 | } |
| 707 | 725 | ||
| 708 | /* Get MAC address from device tree */ | 726 | /* Get MAC address from device tree */ |
| @@ -713,6 +731,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 713 | else | 731 | else |
| 714 | eth_hw_addr_random(ndev); | 732 | eth_hw_addr_random(ndev); |
| 715 | 733 | ||
| 734 | arc_emac_set_address_internal(ndev); | ||
| 716 | dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr); | 735 | dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr); |
| 717 | 736 | ||
| 718 | /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */ | 737 | /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */ |
| @@ -722,7 +741,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 722 | if (!priv->rxbd) { | 741 | if (!priv->rxbd) { |
| 723 | dev_err(&pdev->dev, "failed to allocate data buffers\n"); | 742 | dev_err(&pdev->dev, "failed to allocate data buffers\n"); |
| 724 | err = -ENOMEM; | 743 | err = -ENOMEM; |
| 725 | goto out; | 744 | goto out_clken; |
| 726 | } | 745 | } |
| 727 | 746 | ||
| 728 | priv->txbd = priv->rxbd + RX_BD_NUM; | 747 | priv->txbd = priv->rxbd + RX_BD_NUM; |
| @@ -734,7 +753,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 734 | err = arc_mdio_probe(pdev, priv); | 753 | err = arc_mdio_probe(pdev, priv); |
| 735 | if (err) { | 754 | if (err) { |
| 736 | dev_err(&pdev->dev, "failed to probe MII bus\n"); | 755 | dev_err(&pdev->dev, "failed to probe MII bus\n"); |
| 737 | goto out; | 756 | goto out_clken; |
| 738 | } | 757 | } |
| 739 | 758 | ||
| 740 | priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, | 759 | priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, |
| @@ -742,7 +761,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 742 | if (!priv->phy_dev) { | 761 | if (!priv->phy_dev) { |
| 743 | dev_err(&pdev->dev, "of_phy_connect() failed\n"); | 762 | dev_err(&pdev->dev, "of_phy_connect() failed\n"); |
| 744 | err = -ENODEV; | 763 | err = -ENODEV; |
| 745 | goto out; | 764 | goto out_mdio; |
| 746 | } | 765 | } |
| 747 | 766 | ||
| 748 | dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n", | 767 | dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n", |
| @@ -752,14 +771,25 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
| 752 | 771 | ||
| 753 | err = register_netdev(ndev); | 772 | err = register_netdev(ndev); |
| 754 | if (err) { | 773 | if (err) { |
| 755 | netif_napi_del(&priv->napi); | ||
| 756 | dev_err(&pdev->dev, "failed to register network device\n"); | 774 | dev_err(&pdev->dev, "failed to register network device\n"); |
| 757 | goto out; | 775 | goto out_netif_api; |
| 758 | } | 776 | } |
| 759 | 777 | ||
| 760 | return 0; | 778 | return 0; |
| 761 | 779 | ||
| 762 | out: | 780 | out_netif_api: |
| 781 | netif_napi_del(&priv->napi); | ||
| 782 | phy_disconnect(priv->phy_dev); | ||
| 783 | priv->phy_dev = NULL; | ||
| 784 | out_mdio: | ||
| 785 | arc_mdio_remove(priv); | ||
| 786 | out_clken: | ||
| 787 | if (!IS_ERR(priv->clk)) | ||
| 788 | clk_disable_unprepare(priv->clk); | ||
| 789 | out_clkget: | ||
| 790 | if (!IS_ERR(priv->clk)) | ||
| 791 | clk_put(priv->clk); | ||
| 792 | out_netdev: | ||
| 763 | free_netdev(ndev); | 793 | free_netdev(ndev); |
| 764 | return err; | 794 | return err; |
| 765 | } | 795 | } |
| @@ -774,6 +804,12 @@ static int arc_emac_remove(struct platform_device *pdev) | |||
| 774 | arc_mdio_remove(priv); | 804 | arc_mdio_remove(priv); |
| 775 | unregister_netdev(ndev); | 805 | unregister_netdev(ndev); |
| 776 | netif_napi_del(&priv->napi); | 806 | netif_napi_del(&priv->napi); |
| 807 | |||
| 808 | if (!IS_ERR(priv->clk)) { | ||
| 809 | clk_disable_unprepare(priv->clk); | ||
| 810 | clk_put(priv->clk); | ||
| 811 | } | ||
| 812 | |||
| 777 | free_netdev(ndev); | 813 | free_netdev(ndev); |
| 778 | 814 | ||
| 779 | return 0; | 815 | return 0; |
