aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2011-12-20 22:58:19 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-21 15:44:34 -0500
commitbfab27a146ed4d722c6d399f844f955f29cd2b81 (patch)
treee433b5c075920229274a3229e0f06b8c6a2d19b2
parent225d9b89c937633dfeec502741a174fe0bab5b9f (diff)
stmmac: add the experimental PCI support
This patch adds the PCI support (as EXPERIMENTAL) this has been also tested on XLINX XC2V3000 FF1152AMT0221 D1215994A VIRTEX FPGA board. To support the PCI bus the main part has been reworked and both the platform and the PCI specific parts have been moved into different files. Signed-off-by: Rayagond Kokatanur <rayagond@vayavyalabs.com> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Kconfig27
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Makefile2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h7
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c418
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c221
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c198
9 files changed, 612 insertions, 290 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 22745d7bf530..036428348faa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -12,11 +12,36 @@ config STMMAC_ETH
12 12
13if STMMAC_ETH 13if STMMAC_ETH
14 14
15config STMMAC_PLATFORM
16 tristate "STMMAC platform bus support"
17 depends on STMMAC_ETH
18 default y
19 ---help---
20 This selects the platform specific bus support for
21 the stmmac device driver. This is the driver used
22 on many embedded STM platforms based on ARM and SuperH
23 processors.
24 If you have a controller with this interface, say Y or M here.
25
26 If unsure, say N.
27
28config STMMAC_PCI
29 tristate "STMMAC support on PCI bus (EXPERIMENTAL)"
30 depends on STMMAC_ETH && PCI && EXPERIMENTAL
31 ---help---
32 This is to select the Synopsys DWMAC available on PCI devices,
33 if you have a controller with this interface, say Y or M here.
34
35 This PCI support is tested on XLINX XC2V3000 FF1152AMT0221
36 D1215994A VIRTEX FPGA board.
37
38 If unsure, say N.
39
15config STMMAC_DEBUG_FS 40config STMMAC_DEBUG_FS
16 bool "Enable monitoring via sysFS " 41 bool "Enable monitoring via sysFS "
17 default n 42 default n
18 depends on STMMAC_ETH && DEBUG_FS 43 depends on STMMAC_ETH && DEBUG_FS
19 -- help 44 ---help---
20 The stmmac entry in /sys reports DMA TX/RX rings 45 The stmmac entry in /sys reports DMA TX/RX rings
21 or (if supported) the HW cap register. 46 or (if supported) the HW cap register.
22 47
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index d7c45164ea79..bc965ac9e025 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -2,6 +2,8 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o 2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
3stmmac-$(CONFIG_STMMAC_RING) += ring_mode.o 3stmmac-$(CONFIG_STMMAC_RING) += ring_mode.o
4stmmac-$(CONFIG_STMMAC_CHAINED) += chain_mode.o 4stmmac-$(CONFIG_STMMAC_CHAINED) += chain_mode.o
5stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
6stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
5stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \ 7stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
6 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ 8 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
7 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ 9 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 2cc119295821..d0b814ef0675 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -22,7 +22,11 @@
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/ 23*******************************************************************************/
24 24
25#include <linux/etherdevice.h>
25#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/phy.h>
28#include <linux/module.h>
29#include <linux/init.h>
26#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 30#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
27#define STMMAC_VLAN_TAG_USED 31#define STMMAC_VLAN_TAG_USED
28#include <linux/if_vlan.h> 32#include <linux/if_vlan.h>
@@ -315,5 +319,8 @@ extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
315 unsigned int high, unsigned int low); 319 unsigned int high, unsigned int low);
316extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, 320extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
317 unsigned int high, unsigned int low); 321 unsigned int high, unsigned int low);
322
323extern void stmmac_set_mac(void __iomem *ioaddr, bool enable);
324
318extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); 325extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
319extern const struct stmmac_ring_mode_ops ring_mode_ops; 326extern const struct stmmac_ring_mode_ops ring_mode_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index e25093510b0c..f20aa12931d0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -238,6 +238,19 @@ void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
238 writel(data, ioaddr + low); 238 writel(data, ioaddr + low);
239} 239}
240 240
241/* Enable disable MAC RX/TX */
242void stmmac_set_mac(void __iomem *ioaddr, bool enable)
243{
244 u32 value = readl(ioaddr + MAC_CTRL_REG);
245
246 if (enable)
247 value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
248 else
249 value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
250
251 writel(value, ioaddr + MAC_CTRL_REG);
252}
253
241void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, 254void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
242 unsigned int high, unsigned int low) 255 unsigned int high, unsigned int low)
243{ 256{
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index a140a8fbf051..120740020e2c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -20,7 +20,8 @@
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/ 21*******************************************************************************/
22 22
23#define DRV_MODULE_VERSION "Oct_2011" 23#define STMMAC_RESOURCE_NAME "stmmaceth"
24#define DRV_MODULE_VERSION "Dec_2011"
24#include <linux/stmmac.h> 25#include <linux/stmmac.h>
25#include <linux/phy.h> 26#include <linux/phy.h>
26#include "common.h" 27#include "common.h"
@@ -82,8 +83,18 @@ struct stmmac_priv {
82 int hw_cap_support; 83 int hw_cap_support;
83}; 84};
84 85
86extern int phyaddr;
87
85extern int stmmac_mdio_unregister(struct net_device *ndev); 88extern int stmmac_mdio_unregister(struct net_device *ndev);
86extern int stmmac_mdio_register(struct net_device *ndev); 89extern int stmmac_mdio_register(struct net_device *ndev);
87extern void stmmac_set_ethtool_ops(struct net_device *netdev); 90extern void stmmac_set_ethtool_ops(struct net_device *netdev);
88extern const struct stmmac_desc_ops enh_desc_ops; 91extern const struct stmmac_desc_ops enh_desc_ops;
89extern const struct stmmac_desc_ops ndesc_ops; 92extern const struct stmmac_desc_ops ndesc_ops;
93
94int stmmac_freeze(struct net_device *ndev);
95int stmmac_restore(struct net_device *ndev);
96int stmmac_resume(struct net_device *ndev);
97int stmmac_suspend(struct net_device *ndev);
98int stmmac_dvr_remove(struct net_device *ndev);
99struct stmmac_priv *stmmac_dvr_probe(struct device *device,
100 struct plat_stmmacenet_data *plat_dat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 24c2bf697118..b314592b5eea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -28,12 +28,8 @@
28 https://bugzilla.stlinux.com/ 28 https://bugzilla.stlinux.com/
29*******************************************************************************/ 29*******************************************************************************/
30 30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/kernel.h> 31#include <linux/kernel.h>
34#include <linux/interrupt.h> 32#include <linux/interrupt.h>
35#include <linux/etherdevice.h>
36#include <linux/platform_device.h>
37#include <linux/ip.h> 33#include <linux/ip.h>
38#include <linux/tcp.h> 34#include <linux/tcp.h>
39#include <linux/skbuff.h> 35#include <linux/skbuff.h>
@@ -52,8 +48,6 @@
52#endif 48#endif
53#include "stmmac.h" 49#include "stmmac.h"
54 50
55#define STMMAC_RESOURCE_NAME "stmmaceth"
56
57#undef STMMAC_DEBUG 51#undef STMMAC_DEBUG
58/*#define STMMAC_DEBUG*/ 52/*#define STMMAC_DEBUG*/
59#ifdef STMMAC_DEBUG 53#ifdef STMMAC_DEBUG
@@ -93,7 +87,7 @@ static int debug = -1; /* -1: default, 0: no output, 16: all */
93module_param(debug, int, S_IRUGO | S_IWUSR); 87module_param(debug, int, S_IRUGO | S_IWUSR);
94MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)"); 88MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
95 89
96static int phyaddr = -1; 90int phyaddr = -1;
97module_param(phyaddr, int, S_IRUGO); 91module_param(phyaddr, int, S_IRUGO);
98MODULE_PARM_DESC(phyaddr, "Physical device address"); 92MODULE_PARM_DESC(phyaddr, "Physical device address");
99 93
@@ -141,6 +135,11 @@ static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
141 135
142static irqreturn_t stmmac_interrupt(int irq, void *dev_id); 136static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
143 137
138#ifdef CONFIG_STMMAC_DEBUG_FS
139static int stmmac_init_fs(struct net_device *dev);
140static void stmmac_exit_fs(void);
141#endif
142
144/** 143/**
145 * stmmac_verify_args - verify the driver parameters. 144 * stmmac_verify_args - verify the driver parameters.
146 * Description: it verifies if some wrong parameter is passed to the driver. 145 * Description: it verifies if some wrong parameter is passed to the driver.
@@ -345,22 +344,6 @@ static int stmmac_init_phy(struct net_device *dev)
345 return 0; 344 return 0;
346} 345}
347 346
348static inline void stmmac_enable_mac(void __iomem *ioaddr)
349{
350 u32 value = readl(ioaddr + MAC_CTRL_REG);
351
352 value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
353 writel(value, ioaddr + MAC_CTRL_REG);
354}
355
356static inline void stmmac_disable_mac(void __iomem *ioaddr)
357{
358 u32 value = readl(ioaddr + MAC_CTRL_REG);
359
360 value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
361 writel(value, ioaddr + MAC_CTRL_REG);
362}
363
364/** 347/**
365 * display_ring 348 * display_ring
366 * @p: pointer to the ring. 349 * @p: pointer to the ring.
@@ -887,6 +870,53 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv)
887} 870}
888 871
889/** 872/**
873 * stmmac_mac_device_setup
874 * @dev : device pointer
875 * Description: this is to attach the GMAC or MAC 10/100
876 * main core structures that will be completed during the
877 * open step.
878 */
879static int stmmac_mac_device_setup(struct net_device *dev)
880{
881 struct stmmac_priv *priv = netdev_priv(dev);
882
883 struct mac_device_info *device;
884
885 if (priv->plat->has_gmac)
886 device = dwmac1000_setup(priv->ioaddr);
887 else
888 device = dwmac100_setup(priv->ioaddr);
889
890 if (!device)
891 return -ENOMEM;
892
893 priv->hw = device;
894 priv->hw->ring = &ring_mode_ops;
895
896 if (device_can_wakeup(priv->device)) {
897 priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
898 enable_irq_wake(priv->wol_irq);
899 }
900
901 return 0;
902}
903
904static void stmmac_check_ether_addr(struct stmmac_priv *priv)
905{
906 /* verify if the MAC address is valid, in case of failures it
907 * generates a random MAC address */
908 if (!is_valid_ether_addr(priv->dev->dev_addr)) {
909 priv->hw->mac->get_umac_addr((void __iomem *)
910 priv->dev->base_addr,
911 priv->dev->dev_addr, 0);
912 if (!is_valid_ether_addr(priv->dev->dev_addr))
913 random_ether_addr(priv->dev->dev_addr);
914 }
915 pr_warning("%s: device MAC address %pM\n", priv->dev->name,
916 priv->dev->dev_addr);
917}
918
919/**
890 * stmmac_open - open entry point of the driver 920 * stmmac_open - open entry point of the driver
891 * @dev : pointer to the device structure. 921 * @dev : pointer to the device structure.
892 * Description: 922 * Description:
@@ -900,18 +930,28 @@ static int stmmac_open(struct net_device *dev)
900 struct stmmac_priv *priv = netdev_priv(dev); 930 struct stmmac_priv *priv = netdev_priv(dev);
901 int ret; 931 int ret;
902 932
903 /* Check that the MAC address is valid. If its not, refuse 933 /* MAC HW device setup */
904 * to bring the device up. The user must specify an 934 ret = stmmac_mac_device_setup(dev);
905 * address using the following linux command: 935 if (ret < 0)
906 * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */ 936 return ret;
907 if (!is_valid_ether_addr(dev->dev_addr)) { 937
908 random_ether_addr(dev->dev_addr); 938 stmmac_check_ether_addr(priv);
909 pr_warning("%s: generated random MAC address %pM\n", dev->name,
910 dev->dev_addr);
911 }
912 939
913 stmmac_verify_args(); 940 stmmac_verify_args();
914 941
942 /* Override with kernel parameters if supplied XXX CRS XXX
943 * this needs to have multiple instances */
944 if ((phyaddr >= 0) && (phyaddr <= 31))
945 priv->plat->phy_addr = phyaddr;
946
947 /* MDIO bus Registration */
948 ret = stmmac_mdio_register(dev);
949 if (ret < 0) {
950 pr_debug("%s: MDIO bus (id: %d) registration failed",
951 __func__, priv->plat->bus_id);
952 return ret;
953 }
954
915#ifdef CONFIG_STMMAC_TIMER 955#ifdef CONFIG_STMMAC_TIMER
916 priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); 956 priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
917 if (unlikely(priv->tm == NULL)) { 957 if (unlikely(priv->tm == NULL)) {
@@ -1008,7 +1048,7 @@ static int stmmac_open(struct net_device *dev)
1008 } 1048 }
1009 1049
1010 /* Enable the MAC Rx/Tx */ 1050 /* Enable the MAC Rx/Tx */
1011 stmmac_enable_mac(priv->ioaddr); 1051 stmmac_set_mac(priv->ioaddr, true);
1012 1052
1013 /* Set the HW DMA mode and the COE */ 1053 /* Set the HW DMA mode and the COE */
1014 stmmac_dma_operation_mode(priv); 1054 stmmac_dma_operation_mode(priv);
@@ -1019,6 +1059,11 @@ static int stmmac_open(struct net_device *dev)
1019 1059
1020 stmmac_mmc_setup(priv); 1060 stmmac_mmc_setup(priv);
1021 1061
1062#ifdef CONFIG_STMMAC_DEBUG_FS
1063 ret = stmmac_init_fs(dev);
1064 if (ret < 0)
1065 pr_warning("\tFailed debugFS registration");
1066#endif
1022 /* Start the ball rolling... */ 1067 /* Start the ball rolling... */
1023 DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); 1068 DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
1024 priv->hw->dma->start_tx(priv->ioaddr); 1069 priv->hw->dma->start_tx(priv->ioaddr);
@@ -1091,10 +1136,15 @@ static int stmmac_release(struct net_device *dev)
1091 free_dma_desc_resources(priv); 1136 free_dma_desc_resources(priv);
1092 1137
1093 /* Disable the MAC Rx/Tx */ 1138 /* Disable the MAC Rx/Tx */
1094 stmmac_disable_mac(priv->ioaddr); 1139 stmmac_set_mac(priv->ioaddr, false);
1095 1140
1096 netif_carrier_off(dev); 1141 netif_carrier_off(dev);
1097 1142
1143#ifdef CONFIG_STMMAC_DEBUG_FS
1144 stmmac_exit_fs();
1145#endif
1146 stmmac_mdio_unregister(dev);
1147
1098 return 0; 1148 return 0;
1099} 1149}
1100 1150
@@ -1739,28 +1789,41 @@ static const struct net_device_ops stmmac_netdev_ops = {
1739}; 1789};
1740 1790
1741/** 1791/**
1742 * stmmac_probe - Initialization of the adapter . 1792 * stmmac_dvr_probe
1743 * @dev : device pointer 1793 * @device: device pointer
1744 * Description: The function initializes the network device structure for 1794 * Description: this is the main probe function used to
1745 * the STMMAC driver. It also calls the low level routines 1795 * call the alloc_etherdev, allocate the priv structure.
1746 * in order to init the HW (i.e. the DMA engine)
1747 */ 1796 */
1748static int stmmac_probe(struct net_device *dev) 1797struct stmmac_priv *stmmac_dvr_probe(struct device *device,
1798 struct plat_stmmacenet_data *plat_dat)
1749{ 1799{
1750 int ret = 0; 1800 int ret = 0;
1751 struct stmmac_priv *priv = netdev_priv(dev); 1801 struct net_device *ndev = NULL;
1802 struct stmmac_priv *priv;
1752 1803
1753 ether_setup(dev); 1804 ndev = alloc_etherdev(sizeof(struct stmmac_priv));
1805 if (!ndev) {
1806 pr_err("%s: ERROR: allocating the device\n", __func__);
1807 return NULL;
1808 }
1809
1810 SET_NETDEV_DEV(ndev, device);
1811
1812 priv = netdev_priv(ndev);
1813 priv->device = device;
1814 priv->dev = ndev;
1754 1815
1755 dev->netdev_ops = &stmmac_netdev_ops; 1816 ether_setup(ndev);
1756 stmmac_set_ethtool_ops(dev);
1757 1817
1758 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; 1818 ndev->netdev_ops = &stmmac_netdev_ops;
1759 dev->features |= dev->hw_features | NETIF_F_HIGHDMA; 1819 stmmac_set_ethtool_ops(ndev);
1760 dev->watchdog_timeo = msecs_to_jiffies(watchdog); 1820
1821 ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
1822 ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
1823 ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
1761#ifdef STMMAC_VLAN_TAG_USED 1824#ifdef STMMAC_VLAN_TAG_USED
1762 /* Both mac100 and gmac support receive VLAN tag detection */ 1825 /* Both mac100 and gmac support receive VLAN tag detection */
1763 dev->features |= NETIF_F_HW_VLAN_RX; 1826 ndev->features |= NETIF_F_HW_VLAN_RX;
1764#endif 1827#endif
1765 priv->msg_enable = netif_msg_init(debug, default_msg_level); 1828 priv->msg_enable = netif_msg_init(debug, default_msg_level);
1766 1829
@@ -1768,248 +1831,60 @@ static int stmmac_probe(struct net_device *dev)
1768 priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ 1831 priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
1769 1832
1770 priv->pause = pause; 1833 priv->pause = pause;
1771 netif_napi_add(dev, &priv->napi, stmmac_poll, 64); 1834 priv->plat = plat_dat;
1772 1835 netif_napi_add(ndev, &priv->napi, stmmac_poll, 64);
1773 /* Get the MAC address */
1774 priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
1775 dev->dev_addr, 0);
1776
1777 if (!is_valid_ether_addr(dev->dev_addr))
1778 pr_warning("\tno valid MAC address;"
1779 "please, use ifconfig or nwhwconfig!\n");
1780 1836
1781 spin_lock_init(&priv->lock); 1837 spin_lock_init(&priv->lock);
1782 spin_lock_init(&priv->tx_lock); 1838 spin_lock_init(&priv->tx_lock);
1783 1839
1784 ret = register_netdev(dev); 1840 ret = register_netdev(ndev);
1785 if (ret) { 1841 if (ret) {
1786 pr_err("%s: ERROR %i registering the device\n", 1842 pr_err("%s: ERROR %i registering the device\n",
1787 __func__, ret); 1843 __func__, ret);
1788 return -ENODEV; 1844 goto error;
1789 } 1845 }
1790 1846
1791 DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n", 1847 DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
1792 dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", 1848 ndev->name, (ndev->features & NETIF_F_SG) ? "on" : "off",
1793 (dev->features & NETIF_F_IP_CSUM) ? "on" : "off"); 1849 (ndev->features & NETIF_F_IP_CSUM) ? "on" : "off");
1794 1850
1795 return ret; 1851 return priv;
1796}
1797 1852
1798/** 1853error:
1799 * stmmac_mac_device_setup 1854 netif_napi_del(&priv->napi);
1800 * @dev : device pointer
1801 * Description: select and initialise the mac device (mac100 or Gmac).
1802 */
1803static int stmmac_mac_device_setup(struct net_device *dev)
1804{
1805 struct stmmac_priv *priv = netdev_priv(dev);
1806 1855
1807 struct mac_device_info *device;
1808
1809 if (priv->plat->has_gmac) {
1810 dev->priv_flags |= IFF_UNICAST_FLT;
1811 device = dwmac1000_setup(priv->ioaddr);
1812 } else {
1813 device = dwmac100_setup(priv->ioaddr);
1814 }
1815
1816 if (!device)
1817 return -ENOMEM;
1818
1819 priv->hw = device;
1820 priv->hw->ring = &ring_mode_ops;
1821
1822 if (device_can_wakeup(priv->device)) {
1823 priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
1824 enable_irq_wake(priv->wol_irq);
1825 }
1826
1827 return 0;
1828}
1829
1830/**
1831 * stmmac_dvr_probe
1832 * @pdev: platform device pointer
1833 * Description: the driver is initialized through platform_device.
1834 */
1835static int stmmac_dvr_probe(struct platform_device *pdev)
1836{
1837 int ret = 0;
1838 struct resource *res;
1839 void __iomem *addr = NULL;
1840 struct net_device *ndev = NULL;
1841 struct stmmac_priv *priv = NULL;
1842 struct plat_stmmacenet_data *plat_dat;
1843
1844 pr_info("STMMAC driver:\n\tplatform registration... ");
1845 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1846 if (!res)
1847 return -ENODEV;
1848 pr_info("\tdone!\n");
1849
1850 if (!request_mem_region(res->start, resource_size(res),
1851 pdev->name)) {
1852 pr_err("%s: ERROR: memory allocation failed"
1853 "cannot get the I/O addr 0x%x\n",
1854 __func__, (unsigned int)res->start);
1855 return -EBUSY;
1856 }
1857
1858 addr = ioremap(res->start, resource_size(res));
1859 if (!addr) {
1860 pr_err("%s: ERROR: memory mapping failed\n", __func__);
1861 ret = -ENOMEM;
1862 goto out_release_region;
1863 }
1864
1865 ndev = alloc_etherdev(sizeof(struct stmmac_priv));
1866 if (!ndev) {
1867 pr_err("%s: ERROR: allocating the device\n", __func__);
1868 ret = -ENOMEM;
1869 goto out_unmap;
1870 }
1871
1872 SET_NETDEV_DEV(ndev, &pdev->dev);
1873
1874 /* Get the MAC information */
1875 ndev->irq = platform_get_irq_byname(pdev, "macirq");
1876 if (ndev->irq == -ENXIO) {
1877 pr_err("%s: ERROR: MAC IRQ configuration "
1878 "information not found\n", __func__);
1879 ret = -ENXIO;
1880 goto out_free_ndev;
1881 }
1882
1883 priv = netdev_priv(ndev);
1884 priv->device = &(pdev->dev);
1885 priv->dev = ndev;
1886 plat_dat = pdev->dev.platform_data;
1887
1888 priv->plat = plat_dat;
1889
1890 priv->ioaddr = addr;
1891
1892 /*
1893 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
1894 * The external wake up irq can be passed through the platform code
1895 * named as "eth_wake_irq"
1896 *
1897 * In case the wake up interrupt is not passed from the platform
1898 * so the driver will continue to use the mac irq (ndev->irq)
1899 */
1900 priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
1901 if (priv->wol_irq == -ENXIO)
1902 priv->wol_irq = ndev->irq;
1903
1904 platform_set_drvdata(pdev, ndev);
1905
1906 /* Set the I/O base addr */
1907 ndev->base_addr = (unsigned long)addr;
1908
1909 /* Custom initialisation */
1910 if (priv->plat->init) {
1911 ret = priv->plat->init(pdev);
1912 if (unlikely(ret))
1913 goto out_free_ndev;
1914 }
1915
1916 /* MAC HW device detection */
1917 ret = stmmac_mac_device_setup(ndev);
1918 if (ret < 0)
1919 goto out_plat_exit;
1920
1921 /* Network Device Registration */
1922 ret = stmmac_probe(ndev);
1923 if (ret < 0)
1924 goto out_plat_exit;
1925
1926 /* Override with kernel parameters if supplied XXX CRS XXX
1927 * this needs to have multiple instances */
1928 if ((phyaddr >= 0) && (phyaddr <= 31))
1929 priv->plat->phy_addr = phyaddr;
1930
1931 pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
1932 "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
1933 pdev->id, ndev->irq, addr);
1934
1935 /* MDIO bus Registration */
1936 pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
1937 ret = stmmac_mdio_register(ndev);
1938 if (ret < 0)
1939 goto out_unregister;
1940 pr_debug("registered!\n");
1941
1942#ifdef CONFIG_STMMAC_DEBUG_FS
1943 ret = stmmac_init_fs(ndev);
1944 if (ret < 0)
1945 pr_warning("\tFailed debugFS registration");
1946#endif
1947
1948 return 0;
1949
1950out_unregister:
1951 unregister_netdev(ndev); 1856 unregister_netdev(ndev);
1952out_plat_exit:
1953 if (priv->plat->exit)
1954 priv->plat->exit(pdev);
1955out_free_ndev:
1956 free_netdev(ndev); 1857 free_netdev(ndev);
1957 platform_set_drvdata(pdev, NULL);
1958out_unmap:
1959 iounmap(addr);
1960out_release_region:
1961 release_mem_region(res->start, resource_size(res));
1962 1858
1963 return ret; 1859 return NULL;
1964} 1860}
1965 1861
1966/** 1862/**
1967 * stmmac_dvr_remove 1863 * stmmac_dvr_remove
1968 * @pdev: platform device pointer 1864 * @ndev: net device pointer
1969 * Description: this function resets the TX/RX processes, disables the MAC RX/TX 1865 * Description: this function resets the TX/RX processes, disables the MAC RX/TX
1970 * changes the link status, releases the DMA descriptor rings, 1866 * changes the link status, releases the DMA descriptor rings.
1971 * unregisters the MDIO bus and unmaps the allocated memory.
1972 */ 1867 */
1973static int stmmac_dvr_remove(struct platform_device *pdev) 1868int stmmac_dvr_remove(struct net_device *ndev)
1974{ 1869{
1975 struct net_device *ndev = platform_get_drvdata(pdev);
1976 struct stmmac_priv *priv = netdev_priv(ndev); 1870 struct stmmac_priv *priv = netdev_priv(ndev);
1977 struct resource *res;
1978 1871
1979 pr_info("%s:\n\tremoving driver", __func__); 1872 pr_info("%s:\n\tremoving driver", __func__);
1980 1873
1981 priv->hw->dma->stop_rx(priv->ioaddr); 1874 priv->hw->dma->stop_rx(priv->ioaddr);
1982 priv->hw->dma->stop_tx(priv->ioaddr); 1875 priv->hw->dma->stop_tx(priv->ioaddr);
1983 1876
1984 stmmac_disable_mac(priv->ioaddr); 1877 stmmac_set_mac(priv->ioaddr, false);
1985
1986 netif_carrier_off(ndev); 1878 netif_carrier_off(ndev);
1987
1988 stmmac_mdio_unregister(ndev);
1989
1990 if (priv->plat->exit)
1991 priv->plat->exit(pdev);
1992
1993 platform_set_drvdata(pdev, NULL);
1994 unregister_netdev(ndev); 1879 unregister_netdev(ndev);
1995
1996 iounmap((void *)priv->ioaddr);
1997 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1998 release_mem_region(res->start, resource_size(res));
1999
2000#ifdef CONFIG_STMMAC_DEBUG_FS
2001 stmmac_exit_fs();
2002#endif
2003
2004 free_netdev(ndev); 1880 free_netdev(ndev);
2005 1881
2006 return 0; 1882 return 0;
2007} 1883}
2008 1884
2009#ifdef CONFIG_PM 1885#ifdef CONFIG_PM
2010static int stmmac_suspend(struct device *dev) 1886int stmmac_suspend(struct net_device *ndev)
2011{ 1887{
2012 struct net_device *ndev = dev_get_drvdata(dev);
2013 struct stmmac_priv *priv = netdev_priv(ndev); 1888 struct stmmac_priv *priv = netdev_priv(ndev);
2014 int dis_ic = 0; 1889 int dis_ic = 0;
2015 1890
@@ -2043,15 +1918,14 @@ static int stmmac_suspend(struct device *dev)
2043 if (device_may_wakeup(priv->device)) 1918 if (device_may_wakeup(priv->device))
2044 priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 1919 priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
2045 else 1920 else
2046 stmmac_disable_mac(priv->ioaddr); 1921 stmmac_set_mac(priv->ioaddr, false);
2047 1922
2048 spin_unlock(&priv->lock); 1923 spin_unlock(&priv->lock);
2049 return 0; 1924 return 0;
2050} 1925}
2051 1926
2052static int stmmac_resume(struct device *dev) 1927int stmmac_resume(struct net_device *ndev)
2053{ 1928{
2054 struct net_device *ndev = dev_get_drvdata(dev);
2055 struct stmmac_priv *priv = netdev_priv(ndev); 1929 struct stmmac_priv *priv = netdev_priv(ndev);
2056 1930
2057 if (!netif_running(ndev)) 1931 if (!netif_running(ndev))
@@ -2070,7 +1944,7 @@ static int stmmac_resume(struct device *dev)
2070 netif_device_attach(ndev); 1944 netif_device_attach(ndev);
2071 1945
2072 /* Enable the MAC and DMA */ 1946 /* Enable the MAC and DMA */
2073 stmmac_enable_mac(priv->ioaddr); 1947 stmmac_set_mac(priv->ioaddr, true);
2074 priv->hw->dma->start_tx(priv->ioaddr); 1948 priv->hw->dma->start_tx(priv->ioaddr);
2075 priv->hw->dma->start_rx(priv->ioaddr); 1949 priv->hw->dma->start_rx(priv->ioaddr);
2076 1950
@@ -2090,47 +1964,23 @@ static int stmmac_resume(struct device *dev)
2090 return 0; 1964 return 0;
2091} 1965}
2092 1966
2093static int stmmac_freeze(struct device *dev) 1967int stmmac_freeze(struct net_device *ndev)
2094{ 1968{
2095 struct net_device *ndev = dev_get_drvdata(dev);
2096
2097 if (!ndev || !netif_running(ndev)) 1969 if (!ndev || !netif_running(ndev))
2098 return 0; 1970 return 0;
2099 1971
2100 return stmmac_release(ndev); 1972 return stmmac_release(ndev);
2101} 1973}
2102 1974
2103static int stmmac_restore(struct device *dev) 1975int stmmac_restore(struct net_device *ndev)
2104{ 1976{
2105 struct net_device *ndev = dev_get_drvdata(dev);
2106
2107 if (!ndev || !netif_running(ndev)) 1977 if (!ndev || !netif_running(ndev))
2108 return 0; 1978 return 0;
2109 1979
2110 return stmmac_open(ndev); 1980 return stmmac_open(ndev);
2111} 1981}
2112
2113static const struct dev_pm_ops stmmac_pm_ops = {
2114 .suspend = stmmac_suspend,
2115 .resume = stmmac_resume,
2116 .freeze = stmmac_freeze,
2117 .thaw = stmmac_restore,
2118 .restore = stmmac_restore,
2119};
2120#else
2121static const struct dev_pm_ops stmmac_pm_ops;
2122#endif /* CONFIG_PM */ 1982#endif /* CONFIG_PM */
2123 1983
2124static struct platform_driver stmmac_driver = {
2125 .probe = stmmac_dvr_probe,
2126 .remove = stmmac_dvr_remove,
2127 .driver = {
2128 .name = STMMAC_RESOURCE_NAME,
2129 .owner = THIS_MODULE,
2130 .pm = &stmmac_pm_ops,
2131 },
2132};
2133
2134#ifndef MODULE 1984#ifndef MODULE
2135static int __init stmmac_cmdline_opt(char *str) 1985static int __init stmmac_cmdline_opt(char *str)
2136{ 1986{
@@ -2189,9 +2039,3 @@ err:
2189 2039
2190__setup("stmmaceth=", stmmac_cmdline_opt); 2040__setup("stmmaceth=", stmmac_cmdline_opt);
2191#endif 2041#endif
2192
2193module_platform_driver(stmmac_driver);
2194
2195MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
2196MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
2197MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 9c3b9d5c3411..51f441233962 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -109,6 +109,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
109 */ 109 */
110static int stmmac_mdio_reset(struct mii_bus *bus) 110static int stmmac_mdio_reset(struct mii_bus *bus)
111{ 111{
112#if defined(CONFIG_STMMAC_PLATFORM)
112 struct net_device *ndev = bus->priv; 113 struct net_device *ndev = bus->priv;
113 struct stmmac_priv *priv = netdev_priv(ndev); 114 struct stmmac_priv *priv = netdev_priv(ndev);
114 unsigned int mii_address = priv->hw->mii.addr; 115 unsigned int mii_address = priv->hw->mii.addr;
@@ -123,7 +124,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus)
123 * on MDC, so perform a dummy mdio read. 124 * on MDC, so perform a dummy mdio read.
124 */ 125 */
125 writel(0, priv->ioaddr + mii_address); 126 writel(0, priv->ioaddr + mii_address);
126 127#endif
127 return 0; 128 return 0;
128} 129}
129 130
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
new file mode 100644
index 000000000000..54a819a36487
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -0,0 +1,221 @@
1/*******************************************************************************
2 This contains the functions to handle the pci driver.
3
4 Copyright (C) 2011-2012 Vayavya Labs Pvt Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Rayagond Kokatanur <rayagond@vayavyalabs.com>
23 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
24*******************************************************************************/
25
26#include <linux/pci.h>
27#include "stmmac.h"
28
29struct plat_stmmacenet_data plat_dat;
30struct stmmac_mdio_bus_data mdio_data;
31
32static void stmmac_default_data(void)
33{
34 memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data));
35 plat_dat.bus_id = 1;
36 plat_dat.phy_addr = 0;
37 plat_dat.interface = PHY_INTERFACE_MODE_GMII;
38 plat_dat.pbl = 32;
39 plat_dat.clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */
40 plat_dat.has_gmac = 1;
41 plat_dat.force_sf_dma_mode = 1;
42
43 mdio_data.bus_id = 1;
44 mdio_data.phy_reset = NULL;
45 mdio_data.phy_mask = 0;
46 plat_dat.mdio_bus_data = &mdio_data;
47}
48
49/**
50 * stmmac_pci_probe
51 *
52 * @pdev: pci device pointer
53 * @id: pointer to table of device id/id's.
54 *
55 * Description: This probing function gets called for all PCI devices which
56 * match the ID table and are not "owned" by other driver yet. This function
57 * gets passed a "struct pci_dev *" for each device whose entry in the ID table
58 * matches the device. The probe functions returns zero when the driver choose
59 * to take "ownership" of the device or an error code(-ve no) otherwise.
60 */
61static int __devinit stmmac_pci_probe(struct pci_dev *pdev,
62 const struct pci_device_id *id)
63{
64 int ret = 0;
65 void __iomem *addr = NULL;
66 struct stmmac_priv *priv = NULL;
67 int i;
68
69 /* Enable pci device */
70 ret = pci_enable_device(pdev);
71 if (ret) {
72 pr_err("%s : ERROR: failed to enable %s device\n", __func__,
73 pci_name(pdev));
74 return ret;
75 }
76 if (pci_request_regions(pdev, STMMAC_RESOURCE_NAME)) {
77 pr_err("%s: ERROR: failed to get PCI region\n", __func__);
78 ret = -ENODEV;
79 goto err_out_req_reg_failed;
80 }
81
82 /* Get the base address of device */
83 for (i = 0; i <= 5; i++) {
84 if (pci_resource_len(pdev, i) == 0)
85 continue;
86 addr = pci_iomap(pdev, i, 0);
87 if (addr == NULL) {
88 pr_err("%s: ERROR: cannot map regiser memory, aborting",
89 __func__);
90 ret = -EIO;
91 goto err_out_map_failed;
92 }
93 break;
94 }
95 pci_set_master(pdev);
96
97 stmmac_default_data();
98
99 priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat);
100 if (!priv) {
101 pr_err("%s: main drivr probe failed", __func__);
102 goto err_out;
103 }
104 priv->ioaddr = addr;
105 priv->dev->base_addr = (unsigned long)addr;
106 priv->dev->irq = pdev->irq;
107 priv->wol_irq = pdev->irq;
108
109 pci_set_drvdata(pdev, priv->dev);
110
111 pr_debug("STMMAC platform driver registration completed");
112
113 return 0;
114
115err_out:
116 pci_clear_master(pdev);
117err_out_map_failed:
118 pci_release_regions(pdev);
119err_out_req_reg_failed:
120 pci_disable_device(pdev);
121
122 return ret;
123}
124
125/**
126 * stmmac_dvr_remove
127 *
128 * @pdev: platform device pointer
129 * Description: this function calls the main to free the net resources
130 * and releases the PCI resources.
131 */
132static void __devexit stmmac_pci_remove(struct pci_dev *pdev)
133{
134 struct net_device *ndev = pci_get_drvdata(pdev);
135 struct stmmac_priv *priv = netdev_priv(ndev);
136
137 stmmac_dvr_remove(ndev);
138
139 pci_set_drvdata(pdev, NULL);
140 pci_iounmap(pdev, priv->ioaddr);
141 pci_release_regions(pdev);
142 pci_disable_device(pdev);
143}
144
145#ifdef CONFIG_PM
146static int stmmac_pci_suspend(struct pci_dev *pdev, pm_message_t state)
147{
148 struct net_device *ndev = pci_get_drvdata(pdev);
149 int ret;
150
151 ret = stmmac_suspend(ndev);
152 pci_save_state(pdev);
153 pci_set_power_state(pdev, pci_choose_state(pdev, state));
154
155 return ret;
156}
157
158static int stmmac_pci_resume(struct pci_dev *pdev)
159{
160 struct net_device *ndev = pci_get_drvdata(pdev);
161
162 pci_set_power_state(pdev, PCI_D0);
163 pci_restore_state(pdev);
164
165 return stmmac_resume(ndev);
166}
167#endif
168
169#define STMMAC_VENDOR_ID 0x700
170#define STMMAC_DEVICE_ID 0x1108
171
172static DEFINE_PCI_DEVICE_TABLE(stmmac_id_table) = {
173 {
174 PCI_DEVICE(STMMAC_VENDOR_ID, STMMAC_DEVICE_ID)}, {
175 }
176};
177
178MODULE_DEVICE_TABLE(pci, stmmac_id_table);
179
180static struct pci_driver stmmac_driver = {
181 .name = STMMAC_RESOURCE_NAME,
182 .id_table = stmmac_id_table,
183 .probe = stmmac_pci_probe,
184 .remove = __devexit_p(stmmac_pci_remove),
185#ifdef CONFIG_PM
186 .suspend = stmmac_pci_suspend,
187 .resume = stmmac_pci_resume,
188#endif
189};
190
191/**
192 * stmmac_init_module - Entry point for the driver
193 * Description: This function is the entry point for the driver.
194 */
195static int __init stmmac_init_module(void)
196{
197 int ret;
198
199 ret = pci_register_driver(&stmmac_driver);
200 if (ret < 0)
201 pr_err("%s: ERROR: driver registration failed\n", __func__);
202
203 return ret;
204}
205
206/**
207 * stmmac_cleanup_module - Cleanup routine for the driver
208 * Description: This function is the cleanup routine for the driver.
209 */
210static void __exit stmmac_cleanup_module(void)
211{
212 pci_unregister_driver(&stmmac_driver);
213}
214
215module_init(stmmac_init_module);
216module_exit(stmmac_cleanup_module);
217
218MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PCI driver");
219MODULE_AUTHOR("Rayagond Kokatanur <rayagond.kokatanur@vayavyalabs.com>");
220MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
221MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
new file mode 100644
index 000000000000..7b1594f4944e
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -0,0 +1,198 @@
1/*******************************************************************************
2 This contains the functions to handle the platform driver.
3
4 Copyright (C) 2007-2011 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/platform_device.h>
26#include <linux/io.h>
27#include "stmmac.h"
28
29/**
30 * stmmac_pltfr_probe
31 * @pdev: platform device pointer
32 * Description: platform_device probe function. It allocates
33 * the necessary resources and invokes the main to init
34 * the net device, register the mdio bus etc.
35 */
36static int stmmac_pltfr_probe(struct platform_device *pdev)
37{
38 int ret = 0;
39 struct resource *res;
40 void __iomem *addr = NULL;
41 struct stmmac_priv *priv = NULL;
42 struct plat_stmmacenet_data *plat_dat;
43
44 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
45 if (!res)
46 return -ENODEV;
47
48 if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
49 pr_err("%s: ERROR: memory allocation failed"
50 "cannot get the I/O addr 0x%x\n",
51 __func__, (unsigned int)res->start);
52 return -EBUSY;
53 }
54
55 addr = ioremap(res->start, resource_size(res));
56 if (!addr) {
57 pr_err("%s: ERROR: memory mapping failed", __func__);
58 ret = -ENOMEM;
59 goto out_release_region;
60 }
61 plat_dat = pdev->dev.platform_data;
62 priv = stmmac_dvr_probe(&(pdev->dev), plat_dat);
63 if (!priv) {
64 pr_err("%s: main drivr probe failed", __func__);
65 goto out_release_region;
66 }
67
68 priv->ioaddr = addr;
69 /* Set the I/O base addr */
70 priv->dev->base_addr = (unsigned long)addr;
71
72 /* Get the MAC information */
73 priv->dev->irq = platform_get_irq_byname(pdev, "macirq");
74 if (priv->dev->irq == -ENXIO) {
75 pr_err("%s: ERROR: MAC IRQ configuration "
76 "information not found\n", __func__);
77 ret = -ENXIO;
78 goto out_unmap;
79 }
80
81 /*
82 * On some platforms e.g. SPEAr the wake up irq differs from the mac irq
83 * The external wake up irq can be passed through the platform code
84 * named as "eth_wake_irq"
85 *
86 * In case the wake up interrupt is not passed from the platform
87 * so the driver will continue to use the mac irq (ndev->irq)
88 */
89 priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
90 if (priv->wol_irq == -ENXIO)
91 priv->wol_irq = priv->dev->irq;
92
93 platform_set_drvdata(pdev, priv->dev);
94
95 /* Custom initialisation */
96 if (priv->plat->init) {
97 ret = priv->plat->init(pdev);
98 if (unlikely(ret))
99 goto out_unmap;
100 }
101
102 pr_debug("STMMAC platform driver registration completed");
103
104 return 0;
105
106out_unmap:
107 iounmap(addr);
108 platform_set_drvdata(pdev, NULL);
109
110out_release_region:
111 release_mem_region(res->start, resource_size(res));
112
113 return ret;
114}
115
116/**
117 * stmmac_pltfr_remove
118 * @pdev: platform device pointer
119 * Description: this function calls the main to free the net resources
120 * and calls the platforms hook and release the resources (e.g. mem).
121 */
122static int stmmac_pltfr_remove(struct platform_device *pdev)
123{
124 struct net_device *ndev = platform_get_drvdata(pdev);
125 struct stmmac_priv *priv = netdev_priv(ndev);
126 struct resource *res;
127 int ret = stmmac_dvr_remove(ndev);
128
129 if (priv->plat->exit)
130 priv->plat->exit(pdev);
131
132 if (priv->plat->exit)
133 priv->plat->exit(pdev);
134
135 platform_set_drvdata(pdev, NULL);
136
137 iounmap((void *)priv->ioaddr);
138 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
139 release_mem_region(res->start, resource_size(res));
140
141 return ret;
142}
143
144#ifdef CONFIG_PM
145static int stmmac_pltfr_suspend(struct device *dev)
146{
147 struct net_device *ndev = dev_get_drvdata(dev);
148
149 return stmmac_suspend(ndev);
150}
151
152static int stmmac_pltfr_resume(struct device *dev)
153{
154 struct net_device *ndev = dev_get_drvdata(dev);
155
156 return stmmac_resume(ndev);
157}
158
159int stmmac_pltfr_freeze(struct device *dev)
160{
161 struct net_device *ndev = dev_get_drvdata(dev);
162
163 return stmmac_freeze(ndev);
164}
165
166int stmmac_pltfr_restore(struct device *dev)
167{
168 struct net_device *ndev = dev_get_drvdata(dev);
169
170 return stmmac_restore(ndev);
171}
172
173static const struct dev_pm_ops stmmac_pltfr_pm_ops = {
174 .suspend = stmmac_pltfr_suspend,
175 .resume = stmmac_pltfr_resume,
176 .freeze = stmmac_pltfr_freeze,
177 .thaw = stmmac_pltfr_restore,
178 .restore = stmmac_pltfr_restore,
179};
180#else
181static const struct dev_pm_ops stmmac_pltfr_pm_ops;
182#endif /* CONFIG_PM */
183
184static struct platform_driver stmmac_driver = {
185 .probe = stmmac_pltfr_probe,
186 .remove = stmmac_pltfr_remove,
187 .driver = {
188 .name = STMMAC_RESOURCE_NAME,
189 .owner = THIS_MODULE,
190 .pm = &stmmac_pltfr_pm_ops,
191 },
192};
193
194module_platform_driver(stmmac_driver);
195
196MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver");
197MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
198MODULE_LICENSE("GPL");