aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Kan <fkan@apm.com>2015-01-06 17:41:33 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-06 17:43:13 -0500
commitde7b5b3d790a2524c3f992d357983600635c441b (patch)
treeb5928d566a4f526d535fbf0983b987e56840b2f7
parent1fcf77c87ad659a92e1dcfb883388cb43baeaab6 (diff)
net: eth: xgene: change APM X-Gene SoC platform ethernet to support ACPI
This adds support for APM X-Gene ethernet driver to use ACPI table to derive ethernet driver parameter. Signed-off-by: Feng Kan <fkan@apm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_hw.c94
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.c97
-rw-r--r--drivers/net/ethernet/apm/xgene/xgene_enet_main.h3
3 files changed, 150 insertions, 44 deletions
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index 7ba83ffb08ac..869d97fcf781 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -593,10 +593,12 @@ static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
593 if (!xgene_ring_mgr_init(pdata)) 593 if (!xgene_ring_mgr_init(pdata))
594 return -ENODEV; 594 return -ENODEV;
595 595
596 clk_prepare_enable(pdata->clk); 596 if (!efi_enabled(EFI_BOOT)) {
597 clk_disable_unprepare(pdata->clk); 597 clk_prepare_enable(pdata->clk);
598 clk_prepare_enable(pdata->clk); 598 clk_disable_unprepare(pdata->clk);
599 xgene_enet_ecc_init(pdata); 599 clk_prepare_enable(pdata->clk);
600 xgene_enet_ecc_init(pdata);
601 }
600 xgene_enet_config_ring_if_assoc(pdata); 602 xgene_enet_config_ring_if_assoc(pdata);
601 603
602 /* Enable auto-incr for scanning */ 604 /* Enable auto-incr for scanning */
@@ -663,15 +665,20 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
663 struct phy_device *phy_dev; 665 struct phy_device *phy_dev;
664 struct device *dev = &pdata->pdev->dev; 666 struct device *dev = &pdata->pdev->dev;
665 667
666 phy_np = of_parse_phandle(dev->of_node, "phy-handle", 0); 668 if (dev->of_node) {
667 if (!phy_np) { 669 phy_np = of_parse_phandle(dev->of_node, "phy-handle", 0);
668 netdev_dbg(ndev, "No phy-handle found\n"); 670 if (!phy_np) {
669 return -ENODEV; 671 netdev_dbg(ndev, "No phy-handle found in DT\n");
672 return -ENODEV;
673 }
674 pdata->phy_dev = of_phy_find_device(phy_np);
670 } 675 }
671 676
672 phy_dev = of_phy_connect(ndev, phy_np, &xgene_enet_adjust_link, 677 phy_dev = pdata->phy_dev;
673 0, pdata->phy_mode); 678
674 if (!phy_dev) { 679 if (!phy_dev ||
680 phy_connect_direct(ndev, phy_dev, &xgene_enet_adjust_link,
681 pdata->phy_mode)) {
675 netdev_err(ndev, "Could not connect to PHY\n"); 682 netdev_err(ndev, "Could not connect to PHY\n");
676 return -ENODEV; 683 return -ENODEV;
677 } 684 }
@@ -681,32 +688,71 @@ static int xgene_enet_phy_connect(struct net_device *ndev)
681 ~SUPPORTED_100baseT_Half & 688 ~SUPPORTED_100baseT_Half &
682 ~SUPPORTED_1000baseT_Half; 689 ~SUPPORTED_1000baseT_Half;
683 phy_dev->advertising = phy_dev->supported; 690 phy_dev->advertising = phy_dev->supported;
684 pdata->phy_dev = phy_dev;
685 691
686 return 0; 692 return 0;
687} 693}
688 694
689int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata) 695static int xgene_mdiobus_register(struct xgene_enet_pdata *pdata,
696 struct mii_bus *mdio)
690{ 697{
691 struct net_device *ndev = pdata->ndev;
692 struct device *dev = &pdata->pdev->dev; 698 struct device *dev = &pdata->pdev->dev;
699 struct net_device *ndev = pdata->ndev;
700 struct phy_device *phy;
693 struct device_node *child_np; 701 struct device_node *child_np;
694 struct device_node *mdio_np = NULL; 702 struct device_node *mdio_np = NULL;
695 struct mii_bus *mdio_bus;
696 int ret; 703 int ret;
704 u32 phy_id;
705
706 if (dev->of_node) {
707 for_each_child_of_node(dev->of_node, child_np) {
708 if (of_device_is_compatible(child_np,
709 "apm,xgene-mdio")) {
710 mdio_np = child_np;
711 break;
712 }
713 }
697 714
698 for_each_child_of_node(dev->of_node, child_np) { 715 if (!mdio_np) {
699 if (of_device_is_compatible(child_np, "apm,xgene-mdio")) { 716 netdev_dbg(ndev, "No mdio node in the dts\n");
700 mdio_np = child_np; 717 return -ENXIO;
701 break;
702 } 718 }
703 }
704 719
705 if (!mdio_np) { 720 return of_mdiobus_register(mdio, mdio_np);
706 netdev_dbg(ndev, "No mdio node in the dts\n");
707 return -ENXIO;
708 } 721 }
709 722
723 /* Mask out all PHYs from auto probing. */
724 mdio->phy_mask = ~0;
725
726 /* Register the MDIO bus */
727 ret = mdiobus_register(mdio);
728 if (ret)
729 return ret;
730
731 ret = device_property_read_u32(dev, "phy-channel", &phy_id);
732 if (ret)
733 ret = device_property_read_u32(dev, "phy-addr", &phy_id);
734 if (ret)
735 return -EINVAL;
736
737 phy = get_phy_device(mdio, phy_id, true);
738 if (!phy || IS_ERR(phy))
739 return -EIO;
740
741 ret = phy_device_register(phy);
742 if (ret)
743 phy_device_free(phy);
744 else
745 pdata->phy_dev = phy;
746
747 return ret;
748}
749
750int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
751{
752 struct net_device *ndev = pdata->ndev;
753 struct mii_bus *mdio_bus;
754 int ret;
755
710 mdio_bus = mdiobus_alloc(); 756 mdio_bus = mdiobus_alloc();
711 if (!mdio_bus) 757 if (!mdio_bus)
712 return -ENOMEM; 758 return -ENOMEM;
@@ -720,7 +766,7 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
720 mdio_bus->priv = pdata; 766 mdio_bus->priv = pdata;
721 mdio_bus->parent = &ndev->dev; 767 mdio_bus->parent = &ndev->dev;
722 768
723 ret = of_mdiobus_register(mdio_bus, mdio_np); 769 ret = xgene_mdiobus_register(pdata, mdio_bus);
724 if (ret) { 770 if (ret) {
725 netdev_err(ndev, "Failed to register MDIO bus\n"); 771 netdev_err(ndev, "Failed to register MDIO bus\n");
726 mdiobus_free(mdio_bus); 772 mdiobus_free(mdio_bus);
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 83a50280bb70..1e56bf30366f 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -24,6 +24,10 @@
24#include "xgene_enet_sgmac.h" 24#include "xgene_enet_sgmac.h"
25#include "xgene_enet_xgmac.h" 25#include "xgene_enet_xgmac.h"
26 26
27#define RES_ENET_CSR 0
28#define RES_RING_CSR 1
29#define RES_RING_CMD 2
30
27static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool) 31static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool)
28{ 32{
29 struct xgene_enet_raw_desc16 *raw_desc; 33 struct xgene_enet_raw_desc16 *raw_desc;
@@ -746,6 +750,41 @@ static const struct net_device_ops xgene_ndev_ops = {
746 .ndo_set_mac_address = xgene_enet_set_mac_address, 750 .ndo_set_mac_address = xgene_enet_set_mac_address,
747}; 751};
748 752
753static int xgene_get_mac_address(struct device *dev,
754 unsigned char *addr)
755{
756 int ret;
757
758 ret = device_property_read_u8_array(dev, "local-mac-address", addr, 6);
759 if (ret)
760 ret = device_property_read_u8_array(dev, "mac-address",
761 addr, 6);
762 if (ret)
763 return -ENODEV;
764
765 return ETH_ALEN;
766}
767
768static int xgene_get_phy_mode(struct device *dev)
769{
770 int i, ret;
771 char *modestr;
772
773 ret = device_property_read_string(dev, "phy-connection-type",
774 (const char **)&modestr);
775 if (ret)
776 ret = device_property_read_string(dev, "phy-mode",
777 (const char **)&modestr);
778 if (ret)
779 return -ENODEV;
780
781 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
782 if (!strcasecmp(modestr, phy_modes(i)))
783 return i;
784 }
785 return -ENODEV;
786}
787
749static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) 788static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
750{ 789{
751 struct platform_device *pdev; 790 struct platform_device *pdev;
@@ -753,29 +792,42 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
753 struct device *dev; 792 struct device *dev;
754 struct resource *res; 793 struct resource *res;
755 void __iomem *base_addr; 794 void __iomem *base_addr;
756 const char *mac;
757 int ret; 795 int ret;
758 796
759 pdev = pdata->pdev; 797 pdev = pdata->pdev;
760 dev = &pdev->dev; 798 dev = &pdev->dev;
761 ndev = pdata->ndev; 799 ndev = pdata->ndev;
762 800
763 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "enet_csr"); 801 res = platform_get_resource(pdev, IORESOURCE_MEM, RES_ENET_CSR);
764 pdata->base_addr = devm_ioremap_resource(dev, res); 802 if (!res) {
803 dev_err(dev, "Resource enet_csr not defined\n");
804 return -ENODEV;
805 }
806 pdata->base_addr = devm_ioremap(dev, res->start, resource_size(res));
765 if (IS_ERR(pdata->base_addr)) { 807 if (IS_ERR(pdata->base_addr)) {
766 dev_err(dev, "Unable to retrieve ENET Port CSR region\n"); 808 dev_err(dev, "Unable to retrieve ENET Port CSR region\n");
767 return PTR_ERR(pdata->base_addr); 809 return PTR_ERR(pdata->base_addr);
768 } 810 }
769 811
770 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_csr"); 812 res = platform_get_resource(pdev, IORESOURCE_MEM, RES_RING_CSR);
771 pdata->ring_csr_addr = devm_ioremap_resource(dev, res); 813 if (!res) {
814 dev_err(dev, "Resource ring_csr not defined\n");
815 return -ENODEV;
816 }
817 pdata->ring_csr_addr = devm_ioremap(dev, res->start,
818 resource_size(res));
772 if (IS_ERR(pdata->ring_csr_addr)) { 819 if (IS_ERR(pdata->ring_csr_addr)) {
773 dev_err(dev, "Unable to retrieve ENET Ring CSR region\n"); 820 dev_err(dev, "Unable to retrieve ENET Ring CSR region\n");
774 return PTR_ERR(pdata->ring_csr_addr); 821 return PTR_ERR(pdata->ring_csr_addr);
775 } 822 }
776 823
777 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_cmd"); 824 res = platform_get_resource(pdev, IORESOURCE_MEM, RES_RING_CMD);
778 pdata->ring_cmd_addr = devm_ioremap_resource(dev, res); 825 if (!res) {
826 dev_err(dev, "Resource ring_cmd not defined\n");
827 return -ENODEV;
828 }
829 pdata->ring_cmd_addr = devm_ioremap(dev, res->start,
830 resource_size(res));
779 if (IS_ERR(pdata->ring_cmd_addr)) { 831 if (IS_ERR(pdata->ring_cmd_addr)) {
780 dev_err(dev, "Unable to retrieve ENET Ring command region\n"); 832 dev_err(dev, "Unable to retrieve ENET Ring command region\n");
781 return PTR_ERR(pdata->ring_cmd_addr); 833 return PTR_ERR(pdata->ring_cmd_addr);
@@ -789,14 +841,12 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
789 } 841 }
790 pdata->rx_irq = ret; 842 pdata->rx_irq = ret;
791 843
792 mac = of_get_mac_address(dev->of_node); 844 if (xgene_get_mac_address(dev, ndev->dev_addr) != ETH_ALEN)
793 if (mac)
794 memcpy(ndev->dev_addr, mac, ndev->addr_len);
795 else
796 eth_hw_addr_random(ndev); 845 eth_hw_addr_random(ndev);
846
797 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); 847 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
798 848
799 pdata->phy_mode = of_get_phy_mode(pdev->dev.of_node); 849 pdata->phy_mode = xgene_get_phy_mode(dev);
800 if (pdata->phy_mode < 0) { 850 if (pdata->phy_mode < 0) {
801 dev_err(dev, "Unable to get phy-connection-type\n"); 851 dev_err(dev, "Unable to get phy-connection-type\n");
802 return pdata->phy_mode; 852 return pdata->phy_mode;
@@ -809,11 +859,9 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
809 } 859 }
810 860
811 pdata->clk = devm_clk_get(&pdev->dev, NULL); 861 pdata->clk = devm_clk_get(&pdev->dev, NULL);
812 ret = IS_ERR(pdata->clk);
813 if (IS_ERR(pdata->clk)) { 862 if (IS_ERR(pdata->clk)) {
814 dev_err(&pdev->dev, "can't get clock\n"); 863 /* Firmware may have set up the clock already. */
815 ret = PTR_ERR(pdata->clk); 864 pdata->clk = NULL;
816 return ret;
817 } 865 }
818 866
819 base_addr = pdata->base_addr; 867 base_addr = pdata->base_addr;
@@ -924,7 +972,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
924 goto err; 972 goto err;
925 } 973 }
926 974
927 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); 975 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
928 if (ret) { 976 if (ret) {
929 netdev_err(ndev, "No usable DMA configuration\n"); 977 netdev_err(ndev, "No usable DMA configuration\n");
930 goto err; 978 goto err;
@@ -972,17 +1020,26 @@ static int xgene_enet_remove(struct platform_device *pdev)
972 return 0; 1020 return 0;
973} 1021}
974 1022
975static struct of_device_id xgene_enet_match[] = { 1023#ifdef CONFIG_ACPI
1024static const struct acpi_device_id xgene_enet_acpi_match[] = {
1025 { "APMC0D05", },
1026 { }
1027};
1028MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
1029#endif
1030
1031static struct of_device_id xgene_enet_of_match[] = {
976 {.compatible = "apm,xgene-enet",}, 1032 {.compatible = "apm,xgene-enet",},
977 {}, 1033 {},
978}; 1034};
979 1035
980MODULE_DEVICE_TABLE(of, xgene_enet_match); 1036MODULE_DEVICE_TABLE(of, xgene_enet_of_match);
981 1037
982static struct platform_driver xgene_enet_driver = { 1038static struct platform_driver xgene_enet_driver = {
983 .driver = { 1039 .driver = {
984 .name = "xgene-enet", 1040 .name = "xgene-enet",
985 .of_match_table = xgene_enet_match, 1041 .of_match_table = of_match_ptr(xgene_enet_of_match),
1042 .acpi_match_table = ACPI_PTR(xgene_enet_acpi_match),
986 }, 1043 },
987 .probe = xgene_enet_probe, 1044 .probe = xgene_enet_probe,
988 .remove = xgene_enet_remove, 1045 .remove = xgene_enet_remove,
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index f9958fae6ffd..c2d465c3db66 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -22,7 +22,10 @@
22#ifndef __XGENE_ENET_MAIN_H__ 22#ifndef __XGENE_ENET_MAIN_H__
23#define __XGENE_ENET_MAIN_H__ 23#define __XGENE_ENET_MAIN_H__
24 24
25#include <linux/acpi.h>
25#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/efi.h>
28#include <linux/io.h>
26#include <linux/of_platform.h> 29#include <linux/of_platform.h>
27#include <linux/of_net.h> 30#include <linux/of_net.h>
28#include <linux/of_mdio.h> 31#include <linux/of_mdio.h>