stmmac: Move the STMicroelectronics driver
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 16 May 2011 07:05:19 +0000 (00:05 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Thu, 11 Aug 2011 23:29:01 +0000 (16:29 -0700)
Move the STMicroelectronics driver into driver/net/ethernet/stmicro/ and
make the necessary Kconfig and Makefile changes.

CC: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
47 files changed:
MAINTAINERS
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/stmicro/Kconfig [new file with mode: 0644]
drivers/net/ethernet/stmicro/Makefile [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/Kconfig [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/Makefile [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/common.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/descs.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac100.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/enh_desc.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/norm_desc.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/stmmac.h [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h [new file with mode: 0644]
drivers/net/stmmac/Kconfig [deleted file]
drivers/net/stmmac/Makefile [deleted file]
drivers/net/stmmac/common.h [deleted file]
drivers/net/stmmac/descs.h [deleted file]
drivers/net/stmmac/dwmac100.h [deleted file]
drivers/net/stmmac/dwmac1000.h [deleted file]
drivers/net/stmmac/dwmac1000_core.c [deleted file]
drivers/net/stmmac/dwmac1000_dma.c [deleted file]
drivers/net/stmmac/dwmac100_core.c [deleted file]
drivers/net/stmmac/dwmac100_dma.c [deleted file]
drivers/net/stmmac/dwmac_dma.h [deleted file]
drivers/net/stmmac/dwmac_lib.c [deleted file]
drivers/net/stmmac/enh_desc.c [deleted file]
drivers/net/stmmac/norm_desc.c [deleted file]
drivers/net/stmmac/stmmac.h [deleted file]
drivers/net/stmmac/stmmac_ethtool.c [deleted file]
drivers/net/stmmac/stmmac_main.c [deleted file]
drivers/net/stmmac/stmmac_mdio.c [deleted file]
drivers/net/stmmac/stmmac_timer.c [deleted file]
drivers/net/stmmac/stmmac_timer.h [deleted file]

index c789b6fbdd90540e00d845a21134da4d1749462b..5dffc8ed4af68d069bbd0e03ca9a32c783ed0056 100644 (file)
@@ -2029,7 +2029,7 @@ M:        Giuseppe Cavallaro <peppe.cavallaro@st.com>
 L:     netdev@vger.kernel.org
 W:     http://www.stlinux.com
 S:     Supported
-F:     drivers/net/stmmac/
+F:     drivers/net/ethernet/stmicro/stmmac/
 
 CYBERPRO FB DRIVER
 M:     Russell King <linux@arm.linux.org.uk>
index d3d2febeda172399c7bd2bed2a00c265cc6a0ff7..a7ec50f197fc0be64157aafaccb481b404a63689 100644 (file)
@@ -1406,8 +1406,6 @@ config S6GMAC
          To compile this driver as a module, choose M here. The module
          will be called s6gmac.
 
-source "drivers/net/stmmac/Kconfig"
-
 config PCH_GBE
        tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GbE"
        depends on PCI
index 8d2d677da2ee970f1e8784a9f90bff6265c00ae0..b54e308fc19b7fc3491ad51c3866c1072a7b79de 100644 (file)
@@ -67,7 +67,6 @@ obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
 obj-$(CONFIG_RIONET) += rionet.o
 obj-$(CONFIG_SH_ETH) += sh_eth.o
-obj-$(CONFIG_STMMAC_ETH) += stmmac/
 
 #
 # end link order section
index 8375b8b5dd7329f07dbcc7d6831890c76abc8ebe..c38e9026fe075fac9b1e8ee4c0c104a9fb3b88ab 100644 (file)
@@ -30,6 +30,7 @@ source "drivers/net/ethernet/qlogic/Kconfig"
 source "drivers/net/ethernet/racal/Kconfig"
 source "drivers/net/ethernet/sfc/Kconfig"
 source "drivers/net/ethernet/smsc/Kconfig"
+source "drivers/net/ethernet/stmicro/Kconfig"
 source "drivers/net/ethernet/sun/Kconfig"
 source "drivers/net/ethernet/tehuti/Kconfig"
 
index 26324a115905f59d438671ec6f09cb723d9a1bbd..75d7a0280c5332a355baa17f4fcb6aca27835a8d 100644 (file)
@@ -21,5 +21,6 @@ obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
 obj-$(CONFIG_NET_VENDOR_RACAL) += racal/
 obj-$(CONFIG_SFC) += sfc/
 obj-$(CONFIG_NET_VENDOR_SMSC) += smsc/
+obj-$(CONFIG_NET_VENDOR_STMICRO) += stmicro/
 obj-$(CONFIG_NET_VENDOR_SUN) += sun/
 obj-$(CONFIG_NET_VENDOR_TEHUTI) += tehuti/
diff --git a/drivers/net/ethernet/stmicro/Kconfig b/drivers/net/ethernet/stmicro/Kconfig
new file mode 100644 (file)
index 0000000..e40df64
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# STMicroelectronics device configuration
+#
+
+config NET_VENDOR_STMICRO
+       bool "STMicroelectronics devices"
+       depends on HAS_IOMEM
+       ---help---
+         If you have a network (Ethernet) card belonging to this class, say Y
+         and read the Ethernet-HOWTO, available from
+         <http://www.tldp.org/docs.html#howto>.
+
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+         the questions about STMicroelectronics cards. If you say Y, you will
+         be asked for your specific card in the following questions.
+
+if NET_VENDOR_STMICRO
+
+source "drivers/net/ethernet/stmicro/stmmac/Kconfig"
+
+endif # NET_VENDOR_STMICRO
diff --git a/drivers/net/ethernet/stmicro/Makefile b/drivers/net/ethernet/stmicro/Makefile
new file mode 100644 (file)
index 0000000..9b3bfdd
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for the STMicroelectronics device drivers.
+#
+
+obj-$(CONFIG_STMMAC_ETH) += stmmac/
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
new file mode 100644 (file)
index 0000000..cda61e3
--- /dev/null
@@ -0,0 +1,57 @@
+config STMMAC_ETH
+       tristate "STMicroelectronics 10/100/1000 Ethernet driver"
+       depends on HAS_IOMEM
+       select MII
+       select PHYLIB
+       select CRC32
+       ---help---
+         This is the driver for the Ethernet IPs are built around a
+         Synopsys IP Core and only tested on the STMicroelectronics
+         platforms.
+
+if STMMAC_ETH
+
+config STMMAC_DA
+       bool "STMMAC DMA arbitration scheme"
+       default n
+       ---help---
+         Selecting this option, rx has priority over Tx (only for Giga
+         Ethernet device).
+         By default, the DMA arbitration scheme is based on Round-robin
+         (rx:tx priority is 1:1).
+
+config STMMAC_DUAL_MAC
+       bool "STMMAC: dual mac support (EXPERIMENTAL)"
+       default n
+        depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
+       ---help---
+         Some ST SoCs (for example the stx7141 and stx7200c2) have two
+         Ethernet Controllers. This option turns on the second Ethernet
+         device on this kind of platforms.
+
+config STMMAC_TIMER
+       bool "STMMAC Timer optimisation"
+       default n
+       depends on RTC_HCTOSYS_DEVICE
+       ---help---
+         Use an external timer for mitigating the number of network
+         interrupts. Currently, for SH architectures, it is possible
+         to use the TMU channel 2 and the SH-RTC device.
+
+choice
+        prompt "Select Timer device"
+        depends on STMMAC_TIMER
+
+config STMMAC_TMU_TIMER
+        bool "TMU channel 2"
+        depends on CPU_SH4
+       ---help---
+
+config STMMAC_RTC_TIMER
+        bool "Real time clock"
+        depends on RTC_CLASS
+       ---help---
+
+endchoice
+
+endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
new file mode 100644 (file)
index 0000000..9691733
--- /dev/null
@@ -0,0 +1,5 @@
+obj-$(CONFIG_STMMAC_ETH) += stmmac.o
+stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
+stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o     \
+             dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o     \
+             dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o $(stmmac-y)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
new file mode 100644 (file)
index 0000000..375ea19
--- /dev/null
@@ -0,0 +1,252 @@
+/*******************************************************************************
+  STMMAC Common Header File
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/netdevice.h>
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define STMMAC_VLAN_TAG_USED
+#include <linux/if_vlan.h>
+#endif
+
+#include "descs.h"
+
+#undef CHIP_DEBUG_PRINT
+/* Turn-on extra printk debug for MAC core, dma and descriptors */
+/* #define CHIP_DEBUG_PRINT */
+
+#ifdef CHIP_DEBUG_PRINT
+#define CHIP_DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define CHIP_DBG(fmt, args...)  do { } while (0)
+#endif
+
+#undef FRAME_FILTER_DEBUG
+/* #define FRAME_FILTER_DEBUG */
+
+struct stmmac_extra_stats {
+       /* Transmit errors */
+       unsigned long tx_underflow ____cacheline_aligned;
+       unsigned long tx_carrier;
+       unsigned long tx_losscarrier;
+       unsigned long tx_heartbeat;
+       unsigned long tx_deferred;
+       unsigned long tx_vlan;
+       unsigned long tx_jabber;
+       unsigned long tx_frame_flushed;
+       unsigned long tx_payload_error;
+       unsigned long tx_ip_header_error;
+       /* Receive errors */
+       unsigned long rx_desc;
+       unsigned long rx_partial;
+       unsigned long rx_runt;
+       unsigned long rx_toolong;
+       unsigned long rx_collision;
+       unsigned long rx_crc;
+       unsigned long rx_length;
+       unsigned long rx_mii;
+       unsigned long rx_multicast;
+       unsigned long rx_gmac_overflow;
+       unsigned long rx_watchdog;
+       unsigned long da_rx_filter_fail;
+       unsigned long sa_rx_filter_fail;
+       unsigned long rx_missed_cntr;
+       unsigned long rx_overflow_cntr;
+       unsigned long rx_vlan;
+       /* Tx/Rx IRQ errors */
+       unsigned long tx_undeflow_irq;
+       unsigned long tx_process_stopped_irq;
+       unsigned long tx_jabber_irq;
+       unsigned long rx_overflow_irq;
+       unsigned long rx_buf_unav_irq;
+       unsigned long rx_process_stopped_irq;
+       unsigned long rx_watchdog_irq;
+       unsigned long tx_early_irq;
+       unsigned long fatal_bus_error_irq;
+       /* Extra info */
+       unsigned long threshold;
+       unsigned long tx_pkt_n;
+       unsigned long rx_pkt_n;
+       unsigned long poll_n;
+       unsigned long sched_timer_n;
+       unsigned long normal_irq_n;
+};
+
+#define HASH_TABLE_SIZE 64
+#define PAUSE_TIME 0x200
+
+/* Flow Control defines */
+#define FLOW_OFF       0
+#define FLOW_RX                1
+#define FLOW_TX                2
+#define FLOW_AUTO      (FLOW_TX | FLOW_RX)
+
+#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
+
+enum rx_frame_status { /* IPC status */
+       good_frame = 0,
+       discard_frame = 1,
+       csum_none = 2,
+       llc_snap = 4,
+};
+
+enum tx_dma_irq_status {
+       tx_hard_error = 1,
+       tx_hard_error_bump_tc = 2,
+       handle_tx_rx = 3,
+};
+
+/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
+#define BUF_SIZE_16KiB 16384
+#define BUF_SIZE_8KiB 8192
+#define BUF_SIZE_4KiB 4096
+#define BUF_SIZE_2KiB 2048
+
+/* Power Down and WOL */
+#define PMT_NOT_SUPPORTED 0
+#define PMT_SUPPORTED 1
+
+/* Common MAC defines */
+#define MAC_CTRL_REG           0x00000000      /* MAC Control */
+#define MAC_ENABLE_TX          0x00000008      /* Transmitter Enable */
+#define MAC_RNABLE_RX          0x00000004      /* Receiver Enable */
+
+/* MAC Management Counters register */
+#define MMC_CONTROL            0x00000100      /* MMC Control */
+#define MMC_HIGH_INTR          0x00000104      /* MMC High Interrupt */
+#define MMC_LOW_INTR           0x00000108      /* MMC Low Interrupt */
+#define MMC_HIGH_INTR_MASK     0x0000010c      /* MMC High Interrupt Mask */
+#define MMC_LOW_INTR_MASK      0x00000110      /* MMC Low Interrupt Mask */
+
+#define MMC_CONTROL_MAX_FRM_MASK       0x0003ff8       /* Maximum Frame Size */
+#define MMC_CONTROL_MAX_FRM_SHIFT      3
+#define MMC_CONTROL_MAX_FRAME          0x7FF
+
+struct stmmac_desc_ops {
+       /* DMA RX descriptor ring initialization */
+       void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
+                             int disable_rx_ic);
+       /* DMA TX descriptor ring initialization */
+       void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
+
+       /* Invoked by the xmit function to prepare the tx descriptor */
+       void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
+                                int csum_flag);
+       /* Set/get the owner of the descriptor */
+       void (*set_tx_owner) (struct dma_desc *p);
+       int (*get_tx_owner) (struct dma_desc *p);
+       /* Invoked by the xmit function to close the tx descriptor */
+       void (*close_tx_desc) (struct dma_desc *p);
+       /* Clean the tx descriptor as soon as the tx irq is received */
+       void (*release_tx_desc) (struct dma_desc *p);
+       /* Clear interrupt on tx frame completion. When this bit is
+        * set an interrupt happens as soon as the frame is transmitted */
+       void (*clear_tx_ic) (struct dma_desc *p);
+       /* Last tx segment reports the transmit status */
+       int (*get_tx_ls) (struct dma_desc *p);
+       /* Return the transmit status looking at the TDES1 */
+       int (*tx_status) (void *data, struct stmmac_extra_stats *x,
+                         struct dma_desc *p, void __iomem *ioaddr);
+       /* Get the buffer size from the descriptor */
+       int (*get_tx_len) (struct dma_desc *p);
+       /* Handle extra events on specific interrupts hw dependent */
+       int (*get_rx_owner) (struct dma_desc *p);
+       void (*set_rx_owner) (struct dma_desc *p);
+       /* Get the receive frame size */
+       int (*get_rx_frame_len) (struct dma_desc *p);
+       /* Return the reception status looking at the RDES1 */
+       int (*rx_status) (void *data, struct stmmac_extra_stats *x,
+                         struct dma_desc *p);
+};
+
+struct stmmac_dma_ops {
+       /* DMA core initialization */
+       int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
+       /* Dump DMA registers */
+       void (*dump_regs) (void __iomem *ioaddr);
+       /* Set tx/rx threshold in the csr6 register
+        * An invalid value enables the store-and-forward mode */
+       void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode);
+       /* To track extra statistic (if supported) */
+       void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
+                                  void __iomem *ioaddr);
+       void (*enable_dma_transmission) (void __iomem *ioaddr);
+       void (*enable_dma_irq) (void __iomem *ioaddr);
+       void (*disable_dma_irq) (void __iomem *ioaddr);
+       void (*start_tx) (void __iomem *ioaddr);
+       void (*stop_tx) (void __iomem *ioaddr);
+       void (*start_rx) (void __iomem *ioaddr);
+       void (*stop_rx) (void __iomem *ioaddr);
+       int (*dma_interrupt) (void __iomem *ioaddr,
+                             struct stmmac_extra_stats *x);
+};
+
+struct stmmac_ops {
+       /* MAC core initialization */
+       void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
+       /* Support checksum offload engine */
+       int  (*rx_coe) (void __iomem *ioaddr);
+       /* Dump MAC registers */
+       void (*dump_regs) (void __iomem *ioaddr);
+       /* Handle extra events on specific interrupts hw dependent */
+       void (*host_irq_status) (void __iomem *ioaddr);
+       /* Multicast filter setting */
+       void (*set_filter) (struct net_device *dev);
+       /* Flow control setting */
+       void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
+                          unsigned int fc, unsigned int pause_time);
+       /* Set power management mode (e.g. magic frame) */
+       void (*pmt) (void __iomem *ioaddr, unsigned long mode);
+       /* Set/Get Unicast MAC addresses */
+       void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
+                              unsigned int reg_n);
+       void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
+                              unsigned int reg_n);
+};
+
+struct mac_link {
+       int port;
+       int duplex;
+       int speed;
+};
+
+struct mii_regs {
+       unsigned int addr;      /* MII Address */
+       unsigned int data;      /* MII Data */
+};
+
+struct mac_device_info {
+       const struct stmmac_ops         *mac;
+       const struct stmmac_desc_ops    *desc;
+       const struct stmmac_dma_ops     *dma;
+       struct mii_regs mii;    /* MII register Addresses */
+       struct mac_link link;
+};
+
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
+struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
+
+extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
+                               unsigned int high, unsigned int low);
+extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
+                               unsigned int high, unsigned int low);
+extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h
new file mode 100644 (file)
index 0000000..63a03e2
--- /dev/null
@@ -0,0 +1,163 @@
+/*******************************************************************************
+  Header File to describe the DMA descriptors.
+  Enhanced descriptors have been in case of DWMAC1000 Cores.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+struct dma_desc {
+       /* Receive descriptor */
+       union {
+               struct {
+                       /* RDES0 */
+                       u32 reserved1:1;
+                       u32 crc_error:1;
+                       u32 dribbling:1;
+                       u32 mii_error:1;
+                       u32 receive_watchdog:1;
+                       u32 frame_type:1;
+                       u32 collision:1;
+                       u32 frame_too_long:1;
+                       u32 last_descriptor:1;
+                       u32 first_descriptor:1;
+                       u32 multicast_frame:1;
+                       u32 run_frame:1;
+                       u32 length_error:1;
+                       u32 partial_frame_error:1;
+                       u32 descriptor_error:1;
+                       u32 error_summary:1;
+                       u32 frame_length:14;
+                       u32 filtering_fail:1;
+                       u32 own:1;
+                       /* RDES1 */
+                       u32 buffer1_size:11;
+                       u32 buffer2_size:11;
+                       u32 reserved2:2;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 reserved3:5;
+                       u32 disable_ic:1;
+               } rx;
+               struct {
+                       /* RDES0 */
+                       u32 payload_csum_error:1;
+                       u32 crc_error:1;
+                       u32 dribbling:1;
+                       u32 error_gmii:1;
+                       u32 receive_watchdog:1;
+                       u32 frame_type:1;
+                       u32 late_collision:1;
+                       u32 ipc_csum_error:1;
+                       u32 last_descriptor:1;
+                       u32 first_descriptor:1;
+                       u32 vlan_tag:1;
+                       u32 overflow_error:1;
+                       u32 length_error:1;
+                       u32 sa_filter_fail:1;
+                       u32 descriptor_error:1;
+                       u32 error_summary:1;
+                       u32 frame_length:14;
+                       u32 da_filter_fail:1;
+                       u32 own:1;
+                       /* RDES1 */
+                       u32 buffer1_size:13;
+                       u32 reserved1:1;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 buffer2_size:13;
+                       u32 reserved2:2;
+                       u32 disable_ic:1;
+               } erx;          /* -- enhanced -- */
+
+               /* Transmit descriptor */
+               struct {
+                       /* TDES0 */
+                       u32 deferred:1;
+                       u32 underflow_error:1;
+                       u32 excessive_deferral:1;
+                       u32 collision_count:4;
+                       u32 heartbeat_fail:1;
+                       u32 excessive_collisions:1;
+                       u32 late_collision:1;
+                       u32 no_carrier:1;
+                       u32 loss_carrier:1;
+                       u32 reserved1:3;
+                       u32 error_summary:1;
+                       u32 reserved2:15;
+                       u32 own:1;
+                       /* TDES1 */
+                       u32 buffer1_size:11;
+                       u32 buffer2_size:11;
+                       u32 reserved3:1;
+                       u32 disable_padding:1;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 crc_disable:1;
+                       u32 reserved4:2;
+                       u32 first_segment:1;
+                       u32 last_segment:1;
+                       u32 interrupt:1;
+               } tx;
+               struct {
+                       /* TDES0 */
+                       u32 deferred:1;
+                       u32 underflow_error:1;
+                       u32 excessive_deferral:1;
+                       u32 collision_count:4;
+                       u32 vlan_frame:1;
+                       u32 excessive_collisions:1;
+                       u32 late_collision:1;
+                       u32 no_carrier:1;
+                       u32 loss_carrier:1;
+                       u32 payload_error:1;
+                       u32 frame_flushed:1;
+                       u32 jabber_timeout:1;
+                       u32 error_summary:1;
+                       u32 ip_header_error:1;
+                       u32 time_stamp_status:1;
+                       u32 reserved1:2;
+                       u32 second_address_chained:1;
+                       u32 end_ring:1;
+                       u32 checksum_insertion:2;
+                       u32 reserved2:1;
+                       u32 time_stamp_enable:1;
+                       u32 disable_padding:1;
+                       u32 crc_disable:1;
+                       u32 first_segment:1;
+                       u32 last_segment:1;
+                       u32 interrupt:1;
+                       u32 own:1;
+                       /* TDES1 */
+                       u32 buffer1_size:13;
+                       u32 reserved3:3;
+                       u32 buffer2_size:13;
+                       u32 reserved4:3;
+               } etx;          /* -- enhanced -- */
+       } des01;
+       unsigned int des2;
+       unsigned int des3;
+};
+
+/* Transmit checksum insertion control */
+enum tdes_csum_insertion {
+       cic_disabled = 0,       /* Checksum Insertion Control */
+       cic_only_ip = 1,        /* Only IP header */
+       cic_no_pseudoheader = 2,        /* IP header but pseudoheader
+                                        * is not calculated */
+       cic_full = 3,           /* IP header and pseudoheader */
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h
new file mode 100644 (file)
index 0000000..7c6d857
--- /dev/null
@@ -0,0 +1,121 @@
+/*******************************************************************************
+  MAC 10/100 Header File
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/phy.h>
+#include "common.h"
+
+/*----------------------------------------------------------------------------
+ *                             MAC BLOCK defines
+ *---------------------------------------------------------------------------*/
+/* MAC CSR offset */
+#define MAC_CONTROL    0x00000000      /* MAC Control */
+#define MAC_ADDR_HIGH  0x00000004      /* MAC Address High */
+#define MAC_ADDR_LOW   0x00000008      /* MAC Address Low */
+#define MAC_HASH_HIGH  0x0000000c      /* Multicast Hash Table High */
+#define MAC_HASH_LOW   0x00000010      /* Multicast Hash Table Low */
+#define MAC_MII_ADDR   0x00000014      /* MII Address */
+#define MAC_MII_DATA   0x00000018      /* MII Data */
+#define MAC_FLOW_CTRL  0x0000001c      /* Flow Control */
+#define MAC_VLAN1      0x00000020      /* VLAN1 Tag */
+#define MAC_VLAN2      0x00000024      /* VLAN2 Tag */
+
+/* MAC CTRL defines */
+#define MAC_CONTROL_RA 0x80000000      /* Receive All Mode */
+#define MAC_CONTROL_BLE        0x40000000      /* Endian Mode */
+#define MAC_CONTROL_HBD        0x10000000      /* Heartbeat Disable */
+#define MAC_CONTROL_PS 0x08000000      /* Port Select */
+#define MAC_CONTROL_DRO        0x00800000      /* Disable Receive Own */
+#define MAC_CONTROL_EXT_LOOPBACK 0x00400000    /* Reserved (ext loopback?) */
+#define MAC_CONTROL_OM 0x00200000      /* Loopback Operating Mode */
+#define MAC_CONTROL_F  0x00100000      /* Full Duplex Mode */
+#define MAC_CONTROL_PM 0x00080000      /* Pass All Multicast */
+#define MAC_CONTROL_PR 0x00040000      /* Promiscuous Mode */
+#define MAC_CONTROL_IF 0x00020000      /* Inverse Filtering */
+#define MAC_CONTROL_PB 0x00010000      /* Pass Bad Frames */
+#define MAC_CONTROL_HO 0x00008000      /* Hash Only Filtering Mode */
+#define MAC_CONTROL_HP 0x00002000      /* Hash/Perfect Filtering Mode */
+#define MAC_CONTROL_LCC        0x00001000      /* Late Collision Control */
+#define MAC_CONTROL_DBF        0x00000800      /* Disable Broadcast Frames */
+#define MAC_CONTROL_DRTY       0x00000400      /* Disable Retry */
+#define MAC_CONTROL_ASTP       0x00000100      /* Automatic Pad Stripping */
+#define MAC_CONTROL_BOLMT_10   0x00000000      /* Back Off Limit 10 */
+#define MAC_CONTROL_BOLMT_8    0x00000040      /* Back Off Limit 8 */
+#define MAC_CONTROL_BOLMT_4    0x00000080      /* Back Off Limit 4 */
+#define MAC_CONTROL_BOLMT_1    0x000000c0      /* Back Off Limit 1 */
+#define MAC_CONTROL_DC         0x00000020      /* Deferral Check */
+#define MAC_CONTROL_TE         0x00000008      /* Transmitter Enable */
+#define MAC_CONTROL_RE         0x00000004      /* Receiver Enable */
+
+#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
+
+/* MAC FLOW CTRL defines */
+#define MAC_FLOW_CTRL_PT_MASK  0xffff0000      /* Pause Time Mask */
+#define MAC_FLOW_CTRL_PT_SHIFT 16
+#define MAC_FLOW_CTRL_PASS     0x00000004      /* Pass Control Frames */
+#define MAC_FLOW_CTRL_ENABLE   0x00000002      /* Flow Control Enable */
+#define MAC_FLOW_CTRL_PAUSE    0x00000001      /* Flow Control Busy ... */
+
+/* MII ADDR  defines */
+#define MAC_MII_ADDR_WRITE     0x00000002      /* MII Write */
+#define MAC_MII_ADDR_BUSY      0x00000001      /* MII Busy */
+
+/*----------------------------------------------------------------------------
+ *                             DMA BLOCK defines
+ *---------------------------------------------------------------------------*/
+
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_DBO       0x00100000      /* Descriptor Byte Ordering */
+#define DMA_BUS_MODE_BLE       0x00000080      /* Big Endian/Little Endian */
+#define DMA_BUS_MODE_PBL_MASK  0x00003f00      /* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT 8
+#define DMA_BUS_MODE_DSL_MASK  0x0000007c      /* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT 2       /*   (in DWORDS)      */
+#define DMA_BUS_MODE_BAR_BUS   0x00000002      /* Bar-Bus Arbitration */
+#define DMA_BUS_MODE_SFT_RESET 0x00000001      /* Software Reset */
+#define DMA_BUS_MODE_DEFAULT   0x00000000
+
+/* DMA Control register defines */
+#define DMA_CONTROL_SF         0x00200000      /* Store And Forward */
+
+/* Transmit Threshold Control */
+enum ttc_control {
+       DMA_CONTROL_TTC_DEFAULT = 0x00000000,   /* Threshold is 32 DWORDS */
+       DMA_CONTROL_TTC_64 = 0x00004000,        /* Threshold is 64 DWORDS */
+       DMA_CONTROL_TTC_128 = 0x00008000,       /* Threshold is 128 DWORDS */
+       DMA_CONTROL_TTC_256 = 0x0000c000,       /* Threshold is 256 DWORDS */
+       DMA_CONTROL_TTC_18 = 0x00400000,        /* Threshold is 18 DWORDS */
+       DMA_CONTROL_TTC_24 = 0x00404000,        /* Threshold is 24 DWORDS */
+       DMA_CONTROL_TTC_32 = 0x00408000,        /* Threshold is 32 DWORDS */
+       DMA_CONTROL_TTC_40 = 0x0040c000,        /* Threshold is 40 DWORDS */
+       DMA_CONTROL_SE = 0x00000008,    /* Stop On Empty */
+       DMA_CONTROL_OSF = 0x00000004,   /* Operate On 2nd Frame */
+};
+
+/* STMAC110 DMA Missed Frame Counter register defines */
+#define DMA_MISSED_FRAME_OVE   0x10000000      /* FIFO Overflow Overflow */
+#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000   /* Overflow Frame Counter */
+#define DMA_MISSED_FRAME_OVE_M 0x00010000      /* Missed Frame Overflow */
+#define DMA_MISSED_FRAME_M_CNTR        0x0000ffff      /* Missed Frame Couinter */
+
+extern const struct stmmac_dma_ops dwmac100_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
new file mode 100644 (file)
index 0000000..cfcef0e
--- /dev/null
@@ -0,0 +1,208 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/phy.h>
+#include "common.h"
+
+#define GMAC_CONTROL           0x00000000      /* Configuration */
+#define GMAC_FRAME_FILTER      0x00000004      /* Frame Filter */
+#define GMAC_HASH_HIGH         0x00000008      /* Multicast Hash Table High */
+#define GMAC_HASH_LOW          0x0000000c      /* Multicast Hash Table Low */
+#define GMAC_MII_ADDR          0x00000010      /* MII Address */
+#define GMAC_MII_DATA          0x00000014      /* MII Data */
+#define GMAC_FLOW_CTRL         0x00000018      /* Flow Control */
+#define GMAC_VLAN_TAG          0x0000001c      /* VLAN Tag */
+#define GMAC_VERSION           0x00000020      /* GMAC CORE Version */
+#define GMAC_WAKEUP_FILTER     0x00000028      /* Wake-up Frame Filter */
+
+#define GMAC_INT_STATUS                0x00000038      /* interrupt status register */
+enum dwmac1000_irq_status {
+       time_stamp_irq = 0x0200,
+       mmc_rx_csum_offload_irq = 0x0080,
+       mmc_tx_irq = 0x0040,
+       mmc_rx_irq = 0x0020,
+       mmc_irq = 0x0010,
+       pmt_irq = 0x0008,
+       pcs_ane_irq = 0x0004,
+       pcs_link_irq = 0x0002,
+       rgmii_irq = 0x0001,
+};
+#define GMAC_INT_MASK          0x0000003c      /* interrupt mask register */
+
+/* PMT Control and Status */
+#define GMAC_PMT               0x0000002c
+enum power_event {
+       pointer_reset = 0x80000000,
+       global_unicast = 0x00000200,
+       wake_up_rx_frame = 0x00000040,
+       magic_frame = 0x00000020,
+       wake_up_frame_en = 0x00000004,
+       magic_pkt_en = 0x00000002,
+       power_down = 0x00000001,
+};
+
+/* GMAC HW ADDR regs */
+#define GMAC_ADDR_HIGH(reg)            (0x00000040+(reg * 8))
+#define GMAC_ADDR_LOW(reg)             (0x00000044+(reg * 8))
+#define GMAC_MAX_UNICAST_ADDRESSES     16
+
+#define GMAC_AN_CTRL   0x000000c0      /* AN control */
+#define GMAC_AN_STATUS 0x000000c4      /* AN status */
+#define GMAC_ANE_ADV   0x000000c8      /* Auto-Neg. Advertisement */
+#define GMAC_ANE_LINK  0x000000cc      /* Auto-Neg. link partener ability */
+#define GMAC_ANE_EXP   0x000000d0      /* ANE expansion */
+#define GMAC_TBI       0x000000d4      /* TBI extend status */
+#define GMAC_GMII_STATUS 0x000000d8    /* S/R-GMII status */
+
+/* GMAC Configuration defines */
+#define GMAC_CONTROL_TC        0x01000000      /* Transmit Conf. in RGMII/SGMII */
+#define GMAC_CONTROL_WD        0x00800000      /* Disable Watchdog on receive */
+#define GMAC_CONTROL_JD        0x00400000      /* Jabber disable */
+#define GMAC_CONTROL_BE        0x00200000      /* Frame Burst Enable */
+#define GMAC_CONTROL_JE        0x00100000      /* Jumbo frame */
+enum inter_frame_gap {
+       GMAC_CONTROL_IFG_88 = 0x00040000,
+       GMAC_CONTROL_IFG_80 = 0x00020000,
+       GMAC_CONTROL_IFG_40 = 0x000e0000,
+};
+#define GMAC_CONTROL_DCRS      0x00010000 /* Disable carrier sense during tx */
+#define GMAC_CONTROL_PS                0x00008000 /* Port Select 0:GMI 1:MII */
+#define GMAC_CONTROL_FES       0x00004000 /* Speed 0:10 1:100 */
+#define GMAC_CONTROL_DO                0x00002000 /* Disable Rx Own */
+#define GMAC_CONTROL_LM                0x00001000 /* Loop-back mode */
+#define GMAC_CONTROL_DM                0x00000800 /* Duplex Mode */
+#define GMAC_CONTROL_IPC       0x00000400 /* Checksum Offload */
+#define GMAC_CONTROL_DR                0x00000200 /* Disable Retry */
+#define GMAC_CONTROL_LUD       0x00000100 /* Link up/down */
+#define GMAC_CONTROL_ACS       0x00000080 /* Automatic Pad/FCS Stripping */
+#define GMAC_CONTROL_DC                0x00000010 /* Deferral Check */
+#define GMAC_CONTROL_TE                0x00000008 /* Transmitter Enable */
+#define GMAC_CONTROL_RE                0x00000004 /* Receiver Enable */
+
+#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
+                       GMAC_CONTROL_JE | GMAC_CONTROL_BE)
+
+/* GMAC Frame Filter defines */
+#define GMAC_FRAME_FILTER_PR   0x00000001      /* Promiscuous Mode */
+#define GMAC_FRAME_FILTER_HUC  0x00000002      /* Hash Unicast */
+#define GMAC_FRAME_FILTER_HMC  0x00000004      /* Hash Multicast */
+#define GMAC_FRAME_FILTER_DAIF 0x00000008      /* DA Inverse Filtering */
+#define GMAC_FRAME_FILTER_PM   0x00000010      /* Pass all multicast */
+#define GMAC_FRAME_FILTER_DBF  0x00000020      /* Disable Broadcast frames */
+#define GMAC_FRAME_FILTER_SAIF 0x00000100      /* Inverse Filtering */
+#define GMAC_FRAME_FILTER_SAF  0x00000200      /* Source Address Filter */
+#define GMAC_FRAME_FILTER_HPF  0x00000400      /* Hash or perfect Filter */
+#define GMAC_FRAME_FILTER_RA   0x80000000      /* Receive all mode */
+/* GMII ADDR  defines */
+#define GMAC_MII_ADDR_WRITE    0x00000002      /* MII Write */
+#define GMAC_MII_ADDR_BUSY     0x00000001      /* MII Busy */
+/* GMAC FLOW CTRL defines */
+#define GMAC_FLOW_CTRL_PT_MASK 0xffff0000      /* Pause Time Mask */
+#define GMAC_FLOW_CTRL_PT_SHIFT        16
+#define GMAC_FLOW_CTRL_RFE     0x00000004      /* Rx Flow Control Enable */
+#define GMAC_FLOW_CTRL_TFE     0x00000002      /* Tx Flow Control Enable */
+#define GMAC_FLOW_CTRL_FCB_BPA 0x00000001      /* Flow Control Busy ... */
+
+/*--- DMA BLOCK defines ---*/
+/* DMA Bus Mode register defines */
+#define DMA_BUS_MODE_SFT_RESET 0x00000001      /* Software Reset */
+#define DMA_BUS_MODE_DA                0x00000002      /* Arbitration scheme */
+#define DMA_BUS_MODE_DSL_MASK  0x0000007c      /* Descriptor Skip Length */
+#define DMA_BUS_MODE_DSL_SHIFT 2       /*   (in DWORDS)      */
+/* Programmable burst length (passed thorugh platform)*/
+#define DMA_BUS_MODE_PBL_MASK  0x00003f00      /* Programmable Burst Len */
+#define DMA_BUS_MODE_PBL_SHIFT 8
+
+enum rx_tx_priority_ratio {
+       double_ratio = 0x00004000,      /*2:1 */
+       triple_ratio = 0x00008000,      /*3:1 */
+       quadruple_ratio = 0x0000c000,   /*4:1 */
+};
+
+#define DMA_BUS_MODE_FB                0x00010000      /* Fixed burst */
+#define DMA_BUS_MODE_RPBL_MASK 0x003e0000      /* Rx-Programmable Burst Len */
+#define DMA_BUS_MODE_RPBL_SHIFT        17
+#define DMA_BUS_MODE_USP       0x00800000
+#define DMA_BUS_MODE_4PBL      0x01000000
+#define DMA_BUS_MODE_AAL       0x02000000
+
+/* DMA CRS Control and Status Register Mapping */
+#define DMA_HOST_TX_DESC         0x00001048    /* Current Host Tx descriptor */
+#define DMA_HOST_RX_DESC         0x0000104c    /* Current Host Rx descriptor */
+/*  DMA Bus Mode register defines */
+#define DMA_BUS_PR_RATIO_MASK    0x0000c000    /* Rx/Tx priority ratio */
+#define DMA_BUS_PR_RATIO_SHIFT   14
+#define DMA_BUS_FB               0x00010000    /* Fixed Burst */
+
+/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
+#define DMA_CONTROL_DT         0x04000000 /* Disable Drop TCP/IP csum error */
+#define DMA_CONTROL_RSF                0x02000000 /* Receive Store and Forward */
+#define DMA_CONTROL_DFF                0x01000000 /* Disaable flushing */
+/* Threshold for Activating the FC */
+enum rfa {
+       act_full_minus_1 = 0x00800000,
+       act_full_minus_2 = 0x00800200,
+       act_full_minus_3 = 0x00800400,
+       act_full_minus_4 = 0x00800600,
+};
+/* Threshold for Deactivating the FC */
+enum rfd {
+       deac_full_minus_1 = 0x00400000,
+       deac_full_minus_2 = 0x00400800,
+       deac_full_minus_3 = 0x00401000,
+       deac_full_minus_4 = 0x00401800,
+};
+#define DMA_CONTROL_TSF                0x00200000 /* Transmit  Store and Forward */
+
+enum ttc_control {
+       DMA_CONTROL_TTC_64 = 0x00000000,
+       DMA_CONTROL_TTC_128 = 0x00004000,
+       DMA_CONTROL_TTC_192 = 0x00008000,
+       DMA_CONTROL_TTC_256 = 0x0000c000,
+       DMA_CONTROL_TTC_40 = 0x00010000,
+       DMA_CONTROL_TTC_32 = 0x00014000,
+       DMA_CONTROL_TTC_24 = 0x00018000,
+       DMA_CONTROL_TTC_16 = 0x0001c000,
+};
+#define DMA_CONTROL_TC_TX_MASK 0xfffe3fff
+
+#define DMA_CONTROL_EFC                0x00000100
+#define DMA_CONTROL_FEF                0x00000080
+#define DMA_CONTROL_FUF                0x00000040
+
+enum rtc_control {
+       DMA_CONTROL_RTC_64 = 0x00000000,
+       DMA_CONTROL_RTC_32 = 0x00000008,
+       DMA_CONTROL_RTC_96 = 0x00000010,
+       DMA_CONTROL_RTC_128 = 0x00000018,
+};
+#define DMA_CONTROL_TC_RX_MASK 0xffffffe7
+
+#define DMA_CONTROL_OSF        0x00000004      /* Operate on second frame */
+
+/* MMC registers offset */
+#define GMAC_MMC_CTRL      0x100
+#define GMAC_MMC_RX_INTR   0x104
+#define GMAC_MMC_TX_INTR   0x108
+#define GMAC_MMC_RX_CSUM_OFFLOAD   0x208
+
+extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
new file mode 100644 (file)
index 0000000..0f63b3c
--- /dev/null
@@ -0,0 +1,251 @@
+/*******************************************************************************
+  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
+  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
+  developing this code.
+
+  This only implements the mac core functions for this chip.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/crc32.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include "dwmac1000.h"
+
+static void dwmac1000_core_init(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + GMAC_CONTROL);
+       value |= GMAC_CORE_INIT;
+       writel(value, ioaddr + GMAC_CONTROL);
+
+       /* STBus Bridge Configuration */
+       /*writel(0xc5608, ioaddr + 0x00007000);*/
+
+       /* Freeze MMC counters */
+       writel(0x8, ioaddr + GMAC_MMC_CTRL);
+       /* Mask GMAC interrupts */
+       writel(0x207, ioaddr + GMAC_INT_MASK);
+
+#ifdef STMMAC_VLAN_TAG_USED
+       /* Tag detection without filtering */
+       writel(0x0, ioaddr + GMAC_VLAN_TAG);
+#endif
+}
+
+static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + GMAC_CONTROL);
+
+       value |= GMAC_CONTROL_IPC;
+       writel(value, ioaddr + GMAC_CONTROL);
+
+       value = readl(ioaddr + GMAC_CONTROL);
+
+       return !!(value & GMAC_CONTROL_IPC);
+}
+
+static void dwmac1000_dump_regs(void __iomem *ioaddr)
+{
+       int i;
+       pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
+
+       for (i = 0; i < 55; i++) {
+               int offset = i * 4;
+               pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
+                       offset, readl(ioaddr + offset));
+       }
+}
+
+static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+                               unsigned int reg_n)
+{
+       stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+                               GMAC_ADDR_LOW(reg_n));
+}
+
+static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+                               unsigned int reg_n)
+{
+       stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
+                               GMAC_ADDR_LOW(reg_n));
+}
+
+static void dwmac1000_set_filter(struct net_device *dev)
+{
+       void __iomem *ioaddr = (void __iomem *) dev->base_addr;
+       unsigned int value = 0;
+
+       CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
+                __func__, netdev_mc_count(dev), netdev_uc_count(dev));
+
+       if (dev->flags & IFF_PROMISC)
+               value = GMAC_FRAME_FILTER_PR;
+       else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
+                  || (dev->flags & IFF_ALLMULTI)) {
+               value = GMAC_FRAME_FILTER_PM;   /* pass all multi */
+               writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
+               writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
+       } else if (!netdev_mc_empty(dev)) {
+               u32 mc_filter[2];
+               struct netdev_hw_addr *ha;
+
+               /* Hash filter for multicast */
+               value = GMAC_FRAME_FILTER_HMC;
+
+               memset(mc_filter, 0, sizeof(mc_filter));
+               netdev_for_each_mc_addr(ha, dev) {
+                       /* The upper 6 bits of the calculated CRC are used to
+                          index the contens of the hash table */
+                       int bit_nr =
+                           bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;
+                       /* The most significant bit determines the register to
+                        * use (H/L) while the other 5 bits determine the bit
+                        * within the register. */
+                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+               }
+               writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
+               writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
+       }
+
+       /* Handle multiple unicast addresses (perfect filtering)*/
+       if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
+               /* Switch to promiscuous mode is more than 16 addrs
+                  are required */
+               value |= GMAC_FRAME_FILTER_PR;
+       else {
+               int reg = 1;
+               struct netdev_hw_addr *ha;
+
+               netdev_for_each_uc_addr(ha, dev) {
+                       dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
+                       reg++;
+               }
+       }
+
+#ifdef FRAME_FILTER_DEBUG
+       /* Enable Receive all mode (to debug filtering_fail errors) */
+       value |= GMAC_FRAME_FILTER_RA;
+#endif
+       writel(value, ioaddr + GMAC_FRAME_FILTER);
+
+       CHIP_DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
+           "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
+           readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
+}
+
+static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
+                          unsigned int fc, unsigned int pause_time)
+{
+       unsigned int flow = 0;
+
+       CHIP_DBG(KERN_DEBUG "GMAC Flow-Control:\n");
+       if (fc & FLOW_RX) {
+               CHIP_DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
+               flow |= GMAC_FLOW_CTRL_RFE;
+       }
+       if (fc & FLOW_TX) {
+               CHIP_DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
+               flow |= GMAC_FLOW_CTRL_TFE;
+       }
+
+       if (duplex) {
+               CHIP_DBG(KERN_DEBUG "\tduplex mode: PAUSE %d\n", pause_time);
+               flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
+       }
+
+       writel(flow, ioaddr + GMAC_FLOW_CTRL);
+}
+
+static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
+{
+       unsigned int pmt = 0;
+
+       if (mode & WAKE_MAGIC) {
+               CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
+               pmt |= power_down | magic_pkt_en;
+       }
+       if (mode & WAKE_UCAST) {
+               CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
+               pmt |= global_unicast;
+       }
+
+       writel(pmt, ioaddr + GMAC_PMT);
+}
+
+
+static void dwmac1000_irq_status(void __iomem *ioaddr)
+{
+       u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
+
+       /* Not used events (e.g. MMC interrupts) are not handled. */
+       if ((intr_status & mmc_tx_irq))
+               CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
+                   readl(ioaddr + GMAC_MMC_TX_INTR));
+       if (unlikely(intr_status & mmc_rx_irq))
+               CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
+                   readl(ioaddr + GMAC_MMC_RX_INTR));
+       if (unlikely(intr_status & mmc_rx_csum_offload_irq))
+               CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
+                   readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
+       if (unlikely(intr_status & pmt_irq)) {
+               CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n");
+               /* clear the PMT bits 5 and 6 by reading the PMT
+                * status register. */
+               readl(ioaddr + GMAC_PMT);
+       }
+}
+
+static const struct stmmac_ops dwmac1000_ops = {
+       .core_init = dwmac1000_core_init,
+       .rx_coe = dwmac1000_rx_coe_supported,
+       .dump_regs = dwmac1000_dump_regs,
+       .host_irq_status = dwmac1000_irq_status,
+       .set_filter = dwmac1000_set_filter,
+       .flow_ctrl = dwmac1000_flow_ctrl,
+       .pmt = dwmac1000_pmt,
+       .set_umac_addr = dwmac1000_set_umac_addr,
+       .get_umac_addr = dwmac1000_get_umac_addr,
+};
+
+struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
+{
+       struct mac_device_info *mac;
+       u32 uid = readl(ioaddr + GMAC_VERSION);
+
+       pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
+               ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
+
+       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+       if (!mac)
+               return NULL;
+
+       mac->mac = &dwmac1000_ops;
+       mac->dma = &dwmac1000_dma_ops;
+
+       mac->link.port = GMAC_CONTROL_PS;
+       mac->link.duplex = GMAC_CONTROL_DM;
+       mac->link.speed = GMAC_CONTROL_FES;
+       mac->mii.addr = GMAC_MII_ADDR;
+       mac->mii.data = GMAC_MII_DATA;
+
+       return mac;
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
new file mode 100644 (file)
index 0000000..3dbeea6
--- /dev/null
@@ -0,0 +1,155 @@
+/*******************************************************************************
+  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
+  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
+  developing this code.
+
+  This contains the functions to handle the dma.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <asm/io.h>
+#include "dwmac1000.h"
+#include "dwmac_dma.h"
+
+static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
+                             u32 dma_rx)
+{
+       u32 value = readl(ioaddr + DMA_BUS_MODE);
+       int limit;
+
+       /* DMA SW reset */
+       value |= DMA_BUS_MODE_SFT_RESET;
+       writel(value, ioaddr + DMA_BUS_MODE);
+       limit = 15000;
+       while (limit--) {
+               if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
+                       break;
+       }
+       if (limit < 0)
+               return -EBUSY;
+
+       value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
+           ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
+            (pbl << DMA_BUS_MODE_RPBL_SHIFT));
+
+#ifdef CONFIG_STMMAC_DA
+       value |= DMA_BUS_MODE_DA;       /* Rx has priority over tx */
+#endif
+       writel(value, ioaddr + DMA_BUS_MODE);
+
+       /* Mask interrupts by writing to CSR7 */
+       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+       /* The base address of the RX/TX descriptor lists must be written into
+        * DMA CSR3 and CSR4, respectively. */
+       writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+       writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+       return 0;
+}
+
+static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
+                                   int rxmode)
+{
+       u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+       if (txmode == SF_DMA_MODE) {
+               CHIP_DBG(KERN_DEBUG "GMAC: enable TX store and forward mode\n");
+               /* Transmit COE type 2 cannot be done in cut-through mode. */
+               csr6 |= DMA_CONTROL_TSF;
+               /* Operating on second frame increase the performance
+                * especially when transmit store-and-forward is used.*/
+               csr6 |= DMA_CONTROL_OSF;
+       } else {
+               CHIP_DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
+                             " (threshold = %d)\n", txmode);
+               csr6 &= ~DMA_CONTROL_TSF;
+               csr6 &= DMA_CONTROL_TC_TX_MASK;
+               /* Set the transmit threshold */
+               if (txmode <= 32)
+                       csr6 |= DMA_CONTROL_TTC_32;
+               else if (txmode <= 64)
+                       csr6 |= DMA_CONTROL_TTC_64;
+               else if (txmode <= 128)
+                       csr6 |= DMA_CONTROL_TTC_128;
+               else if (txmode <= 192)
+                       csr6 |= DMA_CONTROL_TTC_192;
+               else
+                       csr6 |= DMA_CONTROL_TTC_256;
+       }
+
+       if (rxmode == SF_DMA_MODE) {
+               CHIP_DBG(KERN_DEBUG "GMAC: enable RX store and forward mode\n");
+               csr6 |= DMA_CONTROL_RSF;
+       } else {
+               CHIP_DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
+                             " (threshold = %d)\n", rxmode);
+               csr6 &= ~DMA_CONTROL_RSF;
+               csr6 &= DMA_CONTROL_TC_RX_MASK;
+               if (rxmode <= 32)
+                       csr6 |= DMA_CONTROL_RTC_32;
+               else if (rxmode <= 64)
+                       csr6 |= DMA_CONTROL_RTC_64;
+               else if (rxmode <= 96)
+                       csr6 |= DMA_CONTROL_RTC_96;
+               else
+                       csr6 |= DMA_CONTROL_RTC_128;
+       }
+
+       writel(csr6, ioaddr + DMA_CONTROL);
+}
+
+/* Not yet implemented --- no RMON module */
+static void dwmac1000_dma_diagnostic_fr(void *data,
+                 struct stmmac_extra_stats *x, void __iomem *ioaddr)
+{
+       return;
+}
+
+static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
+{
+       int i;
+       pr_info(" DMA registers\n");
+       for (i = 0; i < 22; i++) {
+               if ((i < 9) || (i > 17)) {
+                       int offset = i * 4;
+                       pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
+                              (DMA_BUS_MODE + offset),
+                              readl(ioaddr + DMA_BUS_MODE + offset));
+               }
+       }
+}
+
+const struct stmmac_dma_ops dwmac1000_dma_ops = {
+       .init = dwmac1000_dma_init,
+       .dump_regs = dwmac1000_dump_dma_regs,
+       .dma_mode = dwmac1000_dma_operation_mode,
+       .dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
+       .enable_dma_transmission = dwmac_enable_dma_transmission,
+       .enable_dma_irq = dwmac_enable_dma_irq,
+       .disable_dma_irq = dwmac_disable_dma_irq,
+       .start_tx = dwmac_dma_start_tx,
+       .stop_tx = dwmac_dma_stop_tx,
+       .start_rx = dwmac_dma_start_rx,
+       .stop_rx = dwmac_dma_stop_rx,
+       .dma_interrupt = dwmac_dma_interrupt,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
new file mode 100644 (file)
index 0000000..743a580
--- /dev/null
@@ -0,0 +1,204 @@
+/*******************************************************************************
+  This is the driver for the MAC 10/100 on-chip Ethernet controller
+  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
+
+  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
+  this code.
+
+  This only implements the mac core functions for this chip.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/crc32.h>
+#include <asm/io.h>
+#include "dwmac100.h"
+
+static void dwmac100_core_init(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CONTROL);
+
+       writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
+
+#ifdef STMMAC_VLAN_TAG_USED
+       writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
+#endif
+}
+
+static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
+{
+       return 0;
+}
+
+static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
+{
+       pr_info("\t----------------------------------------------\n"
+               "\t  DWMAC 100 CSR (base addr = 0x%p)\n"
+               "\t----------------------------------------------\n",
+               ioaddr);
+       pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
+               readl(ioaddr + MAC_CONTROL));
+       pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
+               readl(ioaddr + MAC_ADDR_HIGH));
+       pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
+               readl(ioaddr + MAC_ADDR_LOW));
+       pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
+               MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
+       pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
+               MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
+       pr_info("\tflow control (offset 0x%x): 0x%08x\n",
+               MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
+       pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
+               readl(ioaddr + MAC_VLAN1));
+       pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
+               readl(ioaddr + MAC_VLAN2));
+       pr_info("\n\tMAC management counter registers\n");
+       pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
+               MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
+       pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
+               MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
+       pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
+               MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
+       pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
+               MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
+       pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
+               MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
+}
+
+static void dwmac100_irq_status(void __iomem *ioaddr)
+{
+       return;
+}
+
+static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+                                  unsigned int reg_n)
+{
+       stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
+                                  unsigned int reg_n)
+{
+       stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
+}
+
+static void dwmac100_set_filter(struct net_device *dev)
+{
+       void __iomem *ioaddr = (void __iomem *) dev->base_addr;
+       u32 value = readl(ioaddr + MAC_CONTROL);
+
+       if (dev->flags & IFF_PROMISC) {
+               value |= MAC_CONTROL_PR;
+               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
+                          MAC_CONTROL_HP);
+       } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
+                  || (dev->flags & IFF_ALLMULTI)) {
+               value |= MAC_CONTROL_PM;
+               value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
+               writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
+               writel(0xffffffff, ioaddr + MAC_HASH_LOW);
+       } else if (netdev_mc_empty(dev)) {      /* no multicast */
+               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
+                          MAC_CONTROL_HO | MAC_CONTROL_HP);
+       } else {
+               u32 mc_filter[2];
+               struct netdev_hw_addr *ha;
+
+               /* Perfect filter mode for physical address and Hash
+                  filter for multicast */
+               value |= MAC_CONTROL_HP;
+               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
+                          MAC_CONTROL_IF | MAC_CONTROL_HO);
+
+               memset(mc_filter, 0, sizeof(mc_filter));
+               netdev_for_each_mc_addr(ha, dev) {
+                       /* The upper 6 bits of the calculated CRC are used to
+                        * index the contens of the hash table */
+                       int bit_nr =
+                           ether_crc(ETH_ALEN, ha->addr) >> 26;
+                       /* The most significant bit determines the register to
+                        * use (H/L) while the other 5 bits determine the bit
+                        * within the register. */
+                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+               }
+               writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
+               writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
+       }
+
+       writel(value, ioaddr + MAC_CONTROL);
+
+       CHIP_DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
+           "HI 0x%08x, LO 0x%08x\n",
+           __func__, readl(ioaddr + MAC_CONTROL),
+           readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
+}
+
+static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
+                              unsigned int fc, unsigned int pause_time)
+{
+       unsigned int flow = MAC_FLOW_CTRL_ENABLE;
+
+       if (duplex)
+               flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
+       writel(flow, ioaddr + MAC_FLOW_CTRL);
+}
+
+/* No PMT module supported for this Ethernet Controller.
+ * Tested on ST platforms only.
+ */
+static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
+{
+       return;
+}
+
+static const struct stmmac_ops dwmac100_ops = {
+       .core_init = dwmac100_core_init,
+       .rx_coe = dwmac100_rx_coe_supported,
+       .dump_regs = dwmac100_dump_mac_regs,
+       .host_irq_status = dwmac100_irq_status,
+       .set_filter = dwmac100_set_filter,
+       .flow_ctrl = dwmac100_flow_ctrl,
+       .pmt = dwmac100_pmt,
+       .set_umac_addr = dwmac100_set_umac_addr,
+       .get_umac_addr = dwmac100_get_umac_addr,
+};
+
+struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
+{
+       struct mac_device_info *mac;
+
+       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
+       if (!mac)
+               return NULL;
+
+       pr_info("\tDWMAC100\n");
+
+       mac->mac = &dwmac100_ops;
+       mac->dma = &dwmac100_dma_ops;
+
+       mac->link.port = MAC_CONTROL_PS;
+       mac->link.duplex = MAC_CONTROL_F;
+       mac->link.speed = 0;
+       mac->mii.addr = MAC_MII_ADDR;
+       mac->mii.data = MAC_MII_DATA;
+
+       return mac;
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
new file mode 100644 (file)
index 0000000..627f656
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************
+  This is the driver for the MAC 10/100 on-chip Ethernet controller
+  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
+
+  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
+  this code.
+
+  This contains the functions to handle the dma.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <asm/io.h>
+#include "dwmac100.h"
+#include "dwmac_dma.h"
+
+static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
+                            u32 dma_rx)
+{
+       u32 value = readl(ioaddr + DMA_BUS_MODE);
+       int limit;
+
+       /* DMA SW reset */
+       value |= DMA_BUS_MODE_SFT_RESET;
+       writel(value, ioaddr + DMA_BUS_MODE);
+       limit = 15000;
+       while (limit--) {
+               if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
+                       break;
+       }
+       if (limit < 0)
+               return -EBUSY;
+
+       /* Enable Application Access by writing to DMA CSR0 */
+       writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
+              ioaddr + DMA_BUS_MODE);
+
+       /* Mask interrupts by writing to CSR7 */
+       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+
+       /* The base address of the RX/TX descriptor lists must be written into
+        * DMA CSR3 and CSR4, respectively. */
+       writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
+       writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
+
+       return 0;
+}
+
+/* Store and Forward capability is not used at all..
+ * The transmit threshold can be programmed by
+ * setting the TTC bits in the DMA control register.*/
+static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
+                                       int rxmode)
+{
+       u32 csr6 = readl(ioaddr + DMA_CONTROL);
+
+       if (txmode <= 32)
+               csr6 |= DMA_CONTROL_TTC_32;
+       else if (txmode <= 64)
+               csr6 |= DMA_CONTROL_TTC_64;
+       else
+               csr6 |= DMA_CONTROL_TTC_128;
+
+       writel(csr6, ioaddr + DMA_CONTROL);
+}
+
+static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
+{
+       int i;
+
+       CHIP_DBG(KERN_DEBUG "DWMAC 100 DMA CSR\n");
+       for (i = 0; i < 9; i++)
+               pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
+                      (DMA_BUS_MODE + i * 4),
+                      readl(ioaddr + DMA_BUS_MODE + i * 4));
+       CHIP_DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
+           DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
+       CHIP_DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
+           DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
+}
+
+/* DMA controller has two counters to track the number of
+ * the receive missed frames. */
+static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
+                                      void __iomem *ioaddr)
+{
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+       u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
+
+       if (unlikely(csr8)) {
+               if (csr8 & DMA_MISSED_FRAME_OVE) {
+                       stats->rx_over_errors += 0x800;
+                       x->rx_overflow_cntr += 0x800;
+               } else {
+                       unsigned int ove_cntr;
+                       ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
+                       stats->rx_over_errors += ove_cntr;
+                       x->rx_overflow_cntr += ove_cntr;
+               }
+
+               if (csr8 & DMA_MISSED_FRAME_OVE_M) {
+                       stats->rx_missed_errors += 0xffff;
+                       x->rx_missed_cntr += 0xffff;
+               } else {
+                       unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
+                       stats->rx_missed_errors += miss_f;
+                       x->rx_missed_cntr += miss_f;
+               }
+       }
+}
+
+const struct stmmac_dma_ops dwmac100_dma_ops = {
+       .init = dwmac100_dma_init,
+       .dump_regs = dwmac100_dump_dma_regs,
+       .dma_mode = dwmac100_dma_operation_mode,
+       .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
+       .enable_dma_transmission = dwmac_enable_dma_transmission,
+       .enable_dma_irq = dwmac_enable_dma_irq,
+       .disable_dma_irq = dwmac_disable_dma_irq,
+       .start_tx = dwmac_dma_start_tx,
+       .stop_tx = dwmac_dma_stop_tx,
+       .start_rx = dwmac_dma_start_rx,
+       .stop_rx = dwmac_dma_stop_rx,
+       .dma_interrupt = dwmac_dma_interrupt,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
new file mode 100644 (file)
index 0000000..da3f5cc
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************
+  DWMAC DMA Header file.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+/* DMA CRS Control and Status Register Mapping */
+#define DMA_BUS_MODE           0x00001000      /* Bus Mode */
+#define DMA_XMT_POLL_DEMAND    0x00001004      /* Transmit Poll Demand */
+#define DMA_RCV_POLL_DEMAND    0x00001008      /* Received Poll Demand */
+#define DMA_RCV_BASE_ADDR      0x0000100c      /* Receive List Base */
+#define DMA_TX_BASE_ADDR       0x00001010      /* Transmit List Base */
+#define DMA_STATUS             0x00001014      /* Status Register */
+#define DMA_CONTROL            0x00001018      /* Ctrl (Operational Mode) */
+#define DMA_INTR_ENA           0x0000101c      /* Interrupt Enable */
+#define DMA_MISSED_FRAME_CTR   0x00001020      /* Missed Frame Counter */
+#define DMA_CUR_TX_BUF_ADDR    0x00001050      /* Current Host Tx Buffer */
+#define DMA_CUR_RX_BUF_ADDR    0x00001054      /* Current Host Rx Buffer */
+
+/* DMA Control register defines */
+#define DMA_CONTROL_ST         0x00002000      /* Start/Stop Transmission */
+#define DMA_CONTROL_SR         0x00000002      /* Start/Stop Receive */
+
+/* DMA Normal interrupt */
+#define DMA_INTR_ENA_NIE 0x00010000    /* Normal Summary */
+#define DMA_INTR_ENA_TIE 0x00000001    /* Transmit Interrupt */
+#define DMA_INTR_ENA_TUE 0x00000004    /* Transmit Buffer Unavailable */
+#define DMA_INTR_ENA_RIE 0x00000040    /* Receive Interrupt */
+#define DMA_INTR_ENA_ERE 0x00004000    /* Early Receive */
+
+#define DMA_INTR_NORMAL        (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
+                       DMA_INTR_ENA_TIE)
+
+/* DMA Abnormal interrupt */
+#define DMA_INTR_ENA_AIE 0x00008000    /* Abnormal Summary */
+#define DMA_INTR_ENA_FBE 0x00002000    /* Fatal Bus Error */
+#define DMA_INTR_ENA_ETE 0x00000400    /* Early Transmit */
+#define DMA_INTR_ENA_RWE 0x00000200    /* Receive Watchdog */
+#define DMA_INTR_ENA_RSE 0x00000100    /* Receive Stopped */
+#define DMA_INTR_ENA_RUE 0x00000080    /* Receive Buffer Unavailable */
+#define DMA_INTR_ENA_UNE 0x00000020    /* Tx Underflow */
+#define DMA_INTR_ENA_OVE 0x00000010    /* Receive Overflow */
+#define DMA_INTR_ENA_TJE 0x00000008    /* Transmit Jabber */
+#define DMA_INTR_ENA_TSE 0x00000002    /* Transmit Stopped */
+
+#define DMA_INTR_ABNORMAL      (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
+                               DMA_INTR_ENA_UNE)
+
+/* DMA default interrupt mask */
+#define DMA_INTR_DEFAULT_MASK  (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
+
+/* DMA Status register defines */
+#define DMA_STATUS_GPI         0x10000000      /* PMT interrupt */
+#define DMA_STATUS_GMI         0x08000000      /* MMC interrupt */
+#define DMA_STATUS_GLI         0x04000000      /* GMAC Line interface int */
+#define DMA_STATUS_GMI         0x08000000
+#define DMA_STATUS_GLI         0x04000000
+#define DMA_STATUS_EB_MASK     0x00380000      /* Error Bits Mask */
+#define DMA_STATUS_EB_TX_ABORT 0x00080000      /* Error Bits - TX Abort */
+#define DMA_STATUS_EB_RX_ABORT 0x00100000      /* Error Bits - RX Abort */
+#define DMA_STATUS_TS_MASK     0x00700000      /* Transmit Process State */
+#define DMA_STATUS_TS_SHIFT    20
+#define DMA_STATUS_RS_MASK     0x000e0000      /* Receive Process State */
+#define DMA_STATUS_RS_SHIFT    17
+#define DMA_STATUS_NIS 0x00010000      /* Normal Interrupt Summary */
+#define DMA_STATUS_AIS 0x00008000      /* Abnormal Interrupt Summary */
+#define DMA_STATUS_ERI 0x00004000      /* Early Receive Interrupt */
+#define DMA_STATUS_FBI 0x00002000      /* Fatal Bus Error Interrupt */
+#define DMA_STATUS_ETI 0x00000400      /* Early Transmit Interrupt */
+#define DMA_STATUS_RWT 0x00000200      /* Receive Watchdog Timeout */
+#define DMA_STATUS_RPS 0x00000100      /* Receive Process Stopped */
+#define DMA_STATUS_RU  0x00000080      /* Receive Buffer Unavailable */
+#define DMA_STATUS_RI  0x00000040      /* Receive Interrupt */
+#define DMA_STATUS_UNF 0x00000020      /* Transmit Underflow */
+#define DMA_STATUS_OVF 0x00000010      /* Receive Overflow */
+#define DMA_STATUS_TJT 0x00000008      /* Transmit Jabber Timeout */
+#define DMA_STATUS_TU  0x00000004      /* Transmit Buffer Unavailable */
+#define DMA_STATUS_TPS 0x00000002      /* Transmit Process Stopped */
+#define DMA_STATUS_TI  0x00000001      /* Transmit Interrupt */
+#define DMA_CONTROL_FTF                0x00100000 /* Flush transmit FIFO */
+
+extern void dwmac_enable_dma_transmission(void __iomem *ioaddr);
+extern void dwmac_enable_dma_irq(void __iomem *ioaddr);
+extern void dwmac_disable_dma_irq(void __iomem *ioaddr);
+extern void dwmac_dma_start_tx(void __iomem *ioaddr);
+extern void dwmac_dma_stop_tx(void __iomem *ioaddr);
+extern void dwmac_dma_start_rx(void __iomem *ioaddr);
+extern void dwmac_dma_stop_rx(void __iomem *ioaddr);
+extern int dwmac_dma_interrupt(void __iomem *ioaddr,
+                               struct stmmac_extra_stats *x);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
new file mode 100644 (file)
index 0000000..e250935
--- /dev/null
@@ -0,0 +1,258 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/io.h>
+#include "common.h"
+#include "dwmac_dma.h"
+
+#undef DWMAC_DMA_DEBUG
+#ifdef DWMAC_DMA_DEBUG
+#define DWMAC_LIB_DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define DWMAC_LIB_DBG(fmt, args...)  do { } while (0)
+#endif
+
+/* CSR1 enables the transmit DMA to check for new descriptor */
+void dwmac_enable_dma_transmission(void __iomem *ioaddr)
+{
+       writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
+}
+
+void dwmac_enable_dma_irq(void __iomem *ioaddr)
+{
+       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
+}
+
+void dwmac_disable_dma_irq(void __iomem *ioaddr)
+{
+       writel(0, ioaddr + DMA_INTR_ENA);
+}
+
+void dwmac_dma_start_tx(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value |= DMA_CONTROL_ST;
+       writel(value, ioaddr + DMA_CONTROL);
+}
+
+void dwmac_dma_stop_tx(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value &= ~DMA_CONTROL_ST;
+       writel(value, ioaddr + DMA_CONTROL);
+}
+
+void dwmac_dma_start_rx(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value |= DMA_CONTROL_SR;
+       writel(value, ioaddr + DMA_CONTROL);
+}
+
+void dwmac_dma_stop_rx(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + DMA_CONTROL);
+       value &= ~DMA_CONTROL_SR;
+       writel(value, ioaddr + DMA_CONTROL);
+}
+
+#ifdef DWMAC_DMA_DEBUG
+static void show_tx_process_state(unsigned int status)
+{
+       unsigned int state;
+       state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
+
+       switch (state) {
+       case 0:
+               pr_info("- TX (Stopped): Reset or Stop command\n");
+               break;
+       case 1:
+               pr_info("- TX (Running):Fetching the Tx desc\n");
+               break;
+       case 2:
+               pr_info("- TX (Running): Waiting for end of tx\n");
+               break;
+       case 3:
+               pr_info("- TX (Running): Reading the data "
+                      "and queuing the data into the Tx buf\n");
+               break;
+       case 6:
+               pr_info("- TX (Suspended): Tx Buff Underflow "
+                      "or an unavailable Transmit descriptor\n");
+               break;
+       case 7:
+               pr_info("- TX (Running): Closing Tx descriptor\n");
+               break;
+       default:
+               break;
+       }
+}
+
+static void show_rx_process_state(unsigned int status)
+{
+       unsigned int state;
+       state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
+
+       switch (state) {
+       case 0:
+               pr_info("- RX (Stopped): Reset or Stop command\n");
+               break;
+       case 1:
+               pr_info("- RX (Running): Fetching the Rx desc\n");
+               break;
+       case 2:
+               pr_info("- RX (Running):Checking for end of pkt\n");
+               break;
+       case 3:
+               pr_info("- RX (Running): Waiting for Rx pkt\n");
+               break;
+       case 4:
+               pr_info("- RX (Suspended): Unavailable Rx buf\n");
+               break;
+       case 5:
+               pr_info("- RX (Running): Closing Rx descriptor\n");
+               break;
+       case 6:
+               pr_info("- RX(Running): Flushing the current frame"
+                      " from the Rx buf\n");
+               break;
+       case 7:
+               pr_info("- RX (Running): Queuing the Rx frame"
+                      " from the Rx buf into memory\n");
+               break;
+       default:
+               break;
+       }
+}
+#endif
+
+int dwmac_dma_interrupt(void __iomem *ioaddr,
+                       struct stmmac_extra_stats *x)
+{
+       int ret = 0;
+       /* read the status register (CSR5) */
+       u32 intr_status = readl(ioaddr + DMA_STATUS);
+
+       DWMAC_LIB_DBG(KERN_INFO "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
+#ifdef DWMAC_DMA_DEBUG
+       /* It displays the DMA process states (CSR5 register) */
+       show_tx_process_state(intr_status);
+       show_rx_process_state(intr_status);
+#endif
+       /* ABNORMAL interrupts */
+       if (unlikely(intr_status & DMA_STATUS_AIS)) {
+               DWMAC_LIB_DBG(KERN_INFO "CSR5[15] DMA ABNORMAL IRQ: ");
+               if (unlikely(intr_status & DMA_STATUS_UNF)) {
+                       DWMAC_LIB_DBG(KERN_INFO "transmit underflow\n");
+                       ret = tx_hard_error_bump_tc;
+                       x->tx_undeflow_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_TJT)) {
+                       DWMAC_LIB_DBG(KERN_INFO "transmit jabber\n");
+                       x->tx_jabber_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_OVF)) {
+                       DWMAC_LIB_DBG(KERN_INFO "recv overflow\n");
+                       x->rx_overflow_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_RU)) {
+                       DWMAC_LIB_DBG(KERN_INFO "receive buffer unavailable\n");
+                       x->rx_buf_unav_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_RPS)) {
+                       DWMAC_LIB_DBG(KERN_INFO "receive process stopped\n");
+                       x->rx_process_stopped_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_RWT)) {
+                       DWMAC_LIB_DBG(KERN_INFO "receive watchdog\n");
+                       x->rx_watchdog_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_ETI)) {
+                       DWMAC_LIB_DBG(KERN_INFO "transmit early interrupt\n");
+                       x->tx_early_irq++;
+               }
+               if (unlikely(intr_status & DMA_STATUS_TPS)) {
+                       DWMAC_LIB_DBG(KERN_INFO "transmit process stopped\n");
+                       x->tx_process_stopped_irq++;
+                       ret = tx_hard_error;
+               }
+               if (unlikely(intr_status & DMA_STATUS_FBI)) {
+                       DWMAC_LIB_DBG(KERN_INFO "fatal bus error\n");
+                       x->fatal_bus_error_irq++;
+                       ret = tx_hard_error;
+               }
+       }
+       /* TX/RX NORMAL interrupts */
+       if (intr_status & DMA_STATUS_NIS) {
+               x->normal_irq_n++;
+               if (likely((intr_status & DMA_STATUS_RI) ||
+                        (intr_status & (DMA_STATUS_TI))))
+                               ret = handle_tx_rx;
+       }
+       /* Optional hardware blocks, interrupts should be disabled */
+       if (unlikely(intr_status &
+                    (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
+               pr_info("%s: unexpected status %08x\n", __func__, intr_status);
+       /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
+       writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
+
+       DWMAC_LIB_DBG(KERN_INFO "\n\n");
+       return ret;
+}
+
+void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
+{
+       u32 csr6 = readl(ioaddr + DMA_CONTROL);
+       writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
+
+       do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
+}
+
+void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
+                        unsigned int high, unsigned int low)
+{
+       unsigned long data;
+
+       data = (addr[5] << 8) | addr[4];
+       writel(data, ioaddr + high);
+       data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
+       writel(data, ioaddr + low);
+}
+
+void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
+                        unsigned int high, unsigned int low)
+{
+       unsigned int hi_addr, lo_addr;
+
+       /* Read the MAC address from the hardware */
+       hi_addr = readl(ioaddr + high);
+       lo_addr = readl(ioaddr + low);
+
+       /* Extract the MAC address from the high and low words */
+       addr[0] = lo_addr & 0xff;
+       addr[1] = (lo_addr >> 8) & 0xff;
+       addr[2] = (lo_addr >> 16) & 0xff;
+       addr[3] = (lo_addr >> 24) & 0xff;
+       addr[4] = hi_addr & 0xff;
+       addr[5] = (hi_addr >> 8) & 0xff;
+}
+
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
new file mode 100644 (file)
index 0000000..e5dfb6a
--- /dev/null
@@ -0,0 +1,337 @@
+/*******************************************************************************
+  This contains the functions to handle the enhanced descriptors.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "common.h"
+
+static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
+                                 struct dma_desc *p, void __iomem *ioaddr)
+{
+       int ret = 0;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.etx.error_summary)) {
+               CHIP_DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
+               if (unlikely(p->des01.etx.jabber_timeout)) {
+                       CHIP_DBG(KERN_ERR "\tjabber_timeout error\n");
+                       x->tx_jabber++;
+               }
+
+               if (unlikely(p->des01.etx.frame_flushed)) {
+                       CHIP_DBG(KERN_ERR "\tframe_flushed error\n");
+                       x->tx_frame_flushed++;
+                       dwmac_dma_flush_tx_fifo(ioaddr);
+               }
+
+               if (unlikely(p->des01.etx.loss_carrier)) {
+                       CHIP_DBG(KERN_ERR "\tloss_carrier error\n");
+                       x->tx_losscarrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely(p->des01.etx.no_carrier)) {
+                       CHIP_DBG(KERN_ERR "\tno_carrier error\n");
+                       x->tx_carrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely(p->des01.etx.late_collision)) {
+                       CHIP_DBG(KERN_ERR "\tlate_collision error\n");
+                       stats->collisions += p->des01.etx.collision_count;
+               }
+               if (unlikely(p->des01.etx.excessive_collisions)) {
+                       CHIP_DBG(KERN_ERR "\texcessive_collisions\n");
+                       stats->collisions += p->des01.etx.collision_count;
+               }
+               if (unlikely(p->des01.etx.excessive_deferral)) {
+                       CHIP_DBG(KERN_INFO "\texcessive tx_deferral\n");
+                       x->tx_deferred++;
+               }
+
+               if (unlikely(p->des01.etx.underflow_error)) {
+                       CHIP_DBG(KERN_ERR "\tunderflow error\n");
+                       dwmac_dma_flush_tx_fifo(ioaddr);
+                       x->tx_underflow++;
+               }
+
+               if (unlikely(p->des01.etx.ip_header_error)) {
+                       CHIP_DBG(KERN_ERR "\tTX IP header csum error\n");
+                       x->tx_ip_header_error++;
+               }
+
+               if (unlikely(p->des01.etx.payload_error)) {
+                       CHIP_DBG(KERN_ERR "\tAddr/Payload csum error\n");
+                       x->tx_payload_error++;
+                       dwmac_dma_flush_tx_fifo(ioaddr);
+               }
+
+               ret = -1;
+       }
+
+       if (unlikely(p->des01.etx.deferred)) {
+               CHIP_DBG(KERN_INFO "GMAC TX status: tx deferred\n");
+               x->tx_deferred++;
+       }
+#ifdef STMMAC_VLAN_TAG_USED
+       if (p->des01.etx.vlan_frame) {
+               CHIP_DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
+               x->tx_vlan++;
+       }
+#endif
+
+       return ret;
+}
+
+static int enh_desc_get_tx_len(struct dma_desc *p)
+{
+       return p->des01.etx.buffer1_size;
+}
+
+static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err)
+{
+       int ret = good_frame;
+       u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
+
+       /* bits 5 7 0 | Frame status
+        * ----------------------------------------------------------
+        *      0 0 0 | IEEE 802.3 Type frame (length < 1536 octects)
+        *      1 0 0 | IPv4/6 No CSUM errorS.
+        *      1 0 1 | IPv4/6 CSUM PAYLOAD error
+        *      1 1 0 | IPv4/6 CSUM IP HR error
+        *      1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
+        *      0 0 1 | IPv4/6 unsupported IP PAYLOAD
+        *      0 1 1 | COE bypassed.. no IPv4/6 frame
+        *      0 1 0 | Reserved.
+        */
+       if (status == 0x0) {
+               CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
+               ret = llc_snap;
+       } else if (status == 0x4) {
+               CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
+               ret = good_frame;
+       } else if (status == 0x5) {
+               CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
+               ret = csum_none;
+       } else if (status == 0x6) {
+               CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
+               ret = csum_none;
+       } else if (status == 0x7) {
+               CHIP_DBG(KERN_ERR
+                   "RX Des0 status: IPv4/6 Header and Payload Error.\n");
+               ret = csum_none;
+       } else if (status == 0x1) {
+               CHIP_DBG(KERN_ERR
+                   "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
+               ret = discard_frame;
+       } else if (status == 0x3) {
+               CHIP_DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
+               ret = discard_frame;
+       }
+       return ret;
+}
+
+static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
+                                 struct dma_desc *p)
+{
+       int ret = good_frame;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.erx.error_summary)) {
+               CHIP_DBG(KERN_ERR "GMAC RX Error Summary 0x%08x\n",
+                                 p->des01.erx);
+               if (unlikely(p->des01.erx.descriptor_error)) {
+                       CHIP_DBG(KERN_ERR "\tdescriptor error\n");
+                       x->rx_desc++;
+                       stats->rx_length_errors++;
+               }
+               if (unlikely(p->des01.erx.overflow_error)) {
+                       CHIP_DBG(KERN_ERR "\toverflow error\n");
+                       x->rx_gmac_overflow++;
+               }
+
+               if (unlikely(p->des01.erx.ipc_csum_error))
+                       CHIP_DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
+
+               if (unlikely(p->des01.erx.late_collision)) {
+                       CHIP_DBG(KERN_ERR "\tlate_collision error\n");
+                       stats->collisions++;
+                       stats->collisions++;
+               }
+               if (unlikely(p->des01.erx.receive_watchdog)) {
+                       CHIP_DBG(KERN_ERR "\treceive_watchdog error\n");
+                       x->rx_watchdog++;
+               }
+               if (unlikely(p->des01.erx.error_gmii)) {
+                       CHIP_DBG(KERN_ERR "\tReceive Error\n");
+                       x->rx_mii++;
+               }
+               if (unlikely(p->des01.erx.crc_error)) {
+                       CHIP_DBG(KERN_ERR "\tCRC error\n");
+                       x->rx_crc++;
+                       stats->rx_crc_errors++;
+               }
+               ret = discard_frame;
+       }
+
+       /* After a payload csum error, the ES bit is set.
+        * It doesn't match with the information reported into the databook.
+        * At any rate, we need to understand if the CSUM hw computation is ok
+        * and report this info to the upper layers. */
+       ret = enh_desc_coe_rdes0(p->des01.erx.ipc_csum_error,
+               p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
+
+       if (unlikely(p->des01.erx.dribbling)) {
+               CHIP_DBG(KERN_ERR "GMAC RX: dribbling error\n");
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.erx.sa_filter_fail)) {
+               CHIP_DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
+               x->sa_rx_filter_fail++;
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.erx.da_filter_fail)) {
+               CHIP_DBG(KERN_ERR "GMAC RX : Dest Address filter fail\n");
+               x->da_rx_filter_fail++;
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.erx.length_error)) {
+               CHIP_DBG(KERN_ERR "GMAC RX: length_error error\n");
+               x->rx_length++;
+               ret = discard_frame;
+       }
+#ifdef STMMAC_VLAN_TAG_USED
+       if (p->des01.erx.vlan_tag) {
+               CHIP_DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
+               x->rx_vlan++;
+       }
+#endif
+       return ret;
+}
+
+static void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+                                 int disable_rx_ic)
+{
+       int i;
+       for (i = 0; i < ring_size; i++) {
+               p->des01.erx.own = 1;
+               p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
+               /* To support jumbo frames */
+               p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
+               if (i == ring_size - 1)
+                       p->des01.erx.end_ring = 1;
+               if (disable_rx_ic)
+                       p->des01.erx.disable_ic = 1;
+               p++;
+       }
+}
+
+static void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+       int i;
+
+       for (i = 0; i < ring_size; i++) {
+               p->des01.etx.own = 0;
+               if (i == ring_size - 1)
+                       p->des01.etx.end_ring = 1;
+               p++;
+       }
+}
+
+static int enh_desc_get_tx_owner(struct dma_desc *p)
+{
+       return p->des01.etx.own;
+}
+
+static int enh_desc_get_rx_owner(struct dma_desc *p)
+{
+       return p->des01.erx.own;
+}
+
+static void enh_desc_set_tx_owner(struct dma_desc *p)
+{
+       p->des01.etx.own = 1;
+}
+
+static void enh_desc_set_rx_owner(struct dma_desc *p)
+{
+       p->des01.erx.own = 1;
+}
+
+static int enh_desc_get_tx_ls(struct dma_desc *p)
+{
+       return p->des01.etx.last_segment;
+}
+
+static void enh_desc_release_tx_desc(struct dma_desc *p)
+{
+       int ter = p->des01.etx.end_ring;
+
+       memset(p, 0, offsetof(struct dma_desc, des2));
+       p->des01.etx.end_ring = ter;
+}
+
+static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+                                    int csum_flag)
+{
+       p->des01.etx.first_segment = is_fs;
+       if (unlikely(len > BUF_SIZE_4KiB)) {
+               p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
+               p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
+       } else {
+               p->des01.etx.buffer1_size = len;
+       }
+       if (likely(csum_flag))
+               p->des01.etx.checksum_insertion = cic_full;
+}
+
+static void enh_desc_clear_tx_ic(struct dma_desc *p)
+{
+       p->des01.etx.interrupt = 0;
+}
+
+static void enh_desc_close_tx_desc(struct dma_desc *p)
+{
+       p->des01.etx.last_segment = 1;
+       p->des01.etx.interrupt = 1;
+}
+
+static int enh_desc_get_rx_frame_len(struct dma_desc *p)
+{
+       return p->des01.erx.frame_length;
+}
+
+const struct stmmac_desc_ops enh_desc_ops = {
+       .tx_status = enh_desc_get_tx_status,
+       .rx_status = enh_desc_get_rx_status,
+       .get_tx_len = enh_desc_get_tx_len,
+       .init_rx_desc = enh_desc_init_rx_desc,
+       .init_tx_desc = enh_desc_init_tx_desc,
+       .get_tx_owner = enh_desc_get_tx_owner,
+       .get_rx_owner = enh_desc_get_rx_owner,
+       .release_tx_desc = enh_desc_release_tx_desc,
+       .prepare_tx_desc = enh_desc_prepare_tx_desc,
+       .clear_tx_ic = enh_desc_clear_tx_ic,
+       .close_tx_desc = enh_desc_close_tx_desc,
+       .get_tx_ls = enh_desc_get_tx_ls,
+       .set_tx_owner = enh_desc_set_tx_owner,
+       .set_rx_owner = enh_desc_set_rx_owner,
+       .get_rx_frame_len = enh_desc_get_rx_frame_len,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
new file mode 100644 (file)
index 0000000..029c2a2
--- /dev/null
@@ -0,0 +1,221 @@
+/*******************************************************************************
+  This contains the functions to handle the normal descriptors.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include "common.h"
+
+static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
+                              struct dma_desc *p, void __iomem *ioaddr)
+{
+       int ret = 0;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.tx.error_summary)) {
+               if (unlikely(p->des01.tx.underflow_error)) {
+                       x->tx_underflow++;
+                       stats->tx_fifo_errors++;
+               }
+               if (unlikely(p->des01.tx.no_carrier)) {
+                       x->tx_carrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely(p->des01.tx.loss_carrier)) {
+                       x->tx_losscarrier++;
+                       stats->tx_carrier_errors++;
+               }
+               if (unlikely((p->des01.tx.excessive_deferral) ||
+                            (p->des01.tx.excessive_collisions) ||
+                            (p->des01.tx.late_collision)))
+                       stats->collisions += p->des01.tx.collision_count;
+               ret = -1;
+       }
+       if (unlikely(p->des01.tx.heartbeat_fail)) {
+               x->tx_heartbeat++;
+               stats->tx_heartbeat_errors++;
+               ret = -1;
+       }
+       if (unlikely(p->des01.tx.deferred))
+               x->tx_deferred++;
+
+       return ret;
+}
+
+static int ndesc_get_tx_len(struct dma_desc *p)
+{
+       return p->des01.tx.buffer1_size;
+}
+
+/* This function verifies if each incoming frame has some errors
+ * and, if required, updates the multicast statistics.
+ * In case of success, it returns csum_none because the device
+ * is not able to compute the csum in HW. */
+static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
+                              struct dma_desc *p)
+{
+       int ret = csum_none;
+       struct net_device_stats *stats = (struct net_device_stats *)data;
+
+       if (unlikely(p->des01.rx.last_descriptor == 0)) {
+               pr_warning("ndesc Error: Oversized Ethernet "
+                          "frame spanned multiple buffers\n");
+               stats->rx_length_errors++;
+               return discard_frame;
+       }
+
+       if (unlikely(p->des01.rx.error_summary)) {
+               if (unlikely(p->des01.rx.descriptor_error))
+                       x->rx_desc++;
+               if (unlikely(p->des01.rx.partial_frame_error))
+                       x->rx_partial++;
+               if (unlikely(p->des01.rx.run_frame))
+                       x->rx_runt++;
+               if (unlikely(p->des01.rx.frame_too_long))
+                       x->rx_toolong++;
+               if (unlikely(p->des01.rx.collision)) {
+                       x->rx_collision++;
+                       stats->collisions++;
+               }
+               if (unlikely(p->des01.rx.crc_error)) {
+                       x->rx_crc++;
+                       stats->rx_crc_errors++;
+               }
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.rx.dribbling))
+               ret = discard_frame;
+
+       if (unlikely(p->des01.rx.length_error)) {
+               x->rx_length++;
+               ret = discard_frame;
+       }
+       if (unlikely(p->des01.rx.mii_error)) {
+               x->rx_mii++;
+               ret = discard_frame;
+       }
+       if (p->des01.rx.multicast_frame) {
+               x->rx_multicast++;
+               stats->multicast++;
+       }
+       return ret;
+}
+
+static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
+                              int disable_rx_ic)
+{
+       int i;
+       for (i = 0; i < ring_size; i++) {
+               p->des01.rx.own = 1;
+               p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
+               if (i == ring_size - 1)
+                       p->des01.rx.end_ring = 1;
+               if (disable_rx_ic)
+                       p->des01.rx.disable_ic = 1;
+               p++;
+       }
+}
+
+static void ndesc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
+{
+       int i;
+       for (i = 0; i < ring_size; i++) {
+               p->des01.tx.own = 0;
+               if (i == ring_size - 1)
+                       p->des01.tx.end_ring = 1;
+               p++;
+       }
+}
+
+static int ndesc_get_tx_owner(struct dma_desc *p)
+{
+       return p->des01.tx.own;
+}
+
+static int ndesc_get_rx_owner(struct dma_desc *p)
+{
+       return p->des01.rx.own;
+}
+
+static void ndesc_set_tx_owner(struct dma_desc *p)
+{
+       p->des01.tx.own = 1;
+}
+
+static void ndesc_set_rx_owner(struct dma_desc *p)
+{
+       p->des01.rx.own = 1;
+}
+
+static int ndesc_get_tx_ls(struct dma_desc *p)
+{
+       return p->des01.tx.last_segment;
+}
+
+static void ndesc_release_tx_desc(struct dma_desc *p)
+{
+       int ter = p->des01.tx.end_ring;
+
+       memset(p, 0, offsetof(struct dma_desc, des2));
+       /* set termination field */
+       p->des01.tx.end_ring = ter;
+}
+
+static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
+                                 int csum_flag)
+{
+       p->des01.tx.first_segment = is_fs;
+       p->des01.tx.buffer1_size = len;
+}
+
+static void ndesc_clear_tx_ic(struct dma_desc *p)
+{
+       p->des01.tx.interrupt = 0;
+}
+
+static void ndesc_close_tx_desc(struct dma_desc *p)
+{
+       p->des01.tx.last_segment = 1;
+       p->des01.tx.interrupt = 1;
+}
+
+static int ndesc_get_rx_frame_len(struct dma_desc *p)
+{
+       return p->des01.rx.frame_length;
+}
+
+const struct stmmac_desc_ops ndesc_ops = {
+       .tx_status = ndesc_get_tx_status,
+       .rx_status = ndesc_get_rx_status,
+       .get_tx_len = ndesc_get_tx_len,
+       .init_rx_desc = ndesc_init_rx_desc,
+       .init_tx_desc = ndesc_init_tx_desc,
+       .get_tx_owner = ndesc_get_tx_owner,
+       .get_rx_owner = ndesc_get_rx_owner,
+       .release_tx_desc = ndesc_release_tx_desc,
+       .prepare_tx_desc = ndesc_prepare_tx_desc,
+       .clear_tx_ic = ndesc_clear_tx_ic,
+       .close_tx_desc = ndesc_close_tx_desc,
+       .get_tx_ls = ndesc_get_tx_ls,
+       .set_tx_owner = ndesc_set_tx_owner,
+       .set_rx_owner = ndesc_set_rx_owner,
+       .get_rx_frame_len = ndesc_get_rx_frame_len,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
new file mode 100644 (file)
index 0000000..de1929b
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#define DRV_MODULE_VERSION     "July_2011"
+#include <linux/stmmac.h>
+
+#include "common.h"
+#ifdef CONFIG_STMMAC_TIMER
+#include "stmmac_timer.h"
+#endif
+
+struct stmmac_priv {
+       /* Frequently used values are kept adjacent for cache effect */
+       struct dma_desc *dma_tx ____cacheline_aligned;
+       dma_addr_t dma_tx_phy;
+       struct sk_buff **tx_skbuff;
+       unsigned int cur_tx;
+       unsigned int dirty_tx;
+       unsigned int dma_tx_size;
+       int tx_coalesce;
+
+       struct dma_desc *dma_rx ;
+       unsigned int cur_rx;
+       unsigned int dirty_rx;
+       struct sk_buff **rx_skbuff;
+       dma_addr_t *rx_skbuff_dma;
+       struct sk_buff_head rx_recycle;
+
+       struct net_device *dev;
+       dma_addr_t dma_rx_phy;
+       unsigned int dma_rx_size;
+       unsigned int dma_buf_sz;
+       struct device *device;
+       struct mac_device_info *hw;
+       void __iomem *ioaddr;
+
+       struct stmmac_extra_stats xstats;
+       struct napi_struct napi;
+
+       int rx_coe;
+       int no_csum_insertion;
+
+       struct phy_device *phydev;
+       int oldlink;
+       int speed;
+       int oldduplex;
+       unsigned int flow_ctrl;
+       unsigned int pause;
+       struct mii_bus *mii;
+       int mii_irq[PHY_MAX_ADDR];
+
+       u32 msg_enable;
+       spinlock_t lock;
+       int wolopts;
+       int wolenabled;
+#ifdef CONFIG_STMMAC_TIMER
+       struct stmmac_timer *tm;
+#endif
+       struct plat_stmmacenet_data *plat;
+};
+
+extern int stmmac_mdio_unregister(struct net_device *ndev);
+extern int stmmac_mdio_register(struct net_device *ndev);
+extern void stmmac_set_ethtool_ops(struct net_device *netdev);
+extern const struct stmmac_desc_ops enh_desc_ops;
+extern const struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
new file mode 100644 (file)
index 0000000..7ed8fb6
--- /dev/null
@@ -0,0 +1,359 @@
+/*******************************************************************************
+  STMMAC Ethtool support
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/interrupt.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <asm/io.h>
+
+#include "stmmac.h"
+#include "dwmac_dma.h"
+
+#define REG_SPACE_SIZE 0x1054
+#define MAC100_ETHTOOL_NAME    "st_mac100"
+#define GMAC_ETHTOOL_NAME      "st_gmac"
+
+struct stmmac_stats {
+       char stat_string[ETH_GSTRING_LEN];
+       int sizeof_stat;
+       int stat_offset;
+};
+
+#define STMMAC_STAT(m) \
+       { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m),       \
+       offsetof(struct stmmac_priv, xstats.m)}
+
+static const struct  stmmac_stats stmmac_gstrings_stats[] = {
+       STMMAC_STAT(tx_underflow),
+       STMMAC_STAT(tx_carrier),
+       STMMAC_STAT(tx_losscarrier),
+       STMMAC_STAT(tx_heartbeat),
+       STMMAC_STAT(tx_deferred),
+       STMMAC_STAT(tx_vlan),
+       STMMAC_STAT(rx_vlan),
+       STMMAC_STAT(tx_jabber),
+       STMMAC_STAT(tx_frame_flushed),
+       STMMAC_STAT(tx_payload_error),
+       STMMAC_STAT(tx_ip_header_error),
+       STMMAC_STAT(rx_desc),
+       STMMAC_STAT(rx_partial),
+       STMMAC_STAT(rx_runt),
+       STMMAC_STAT(rx_toolong),
+       STMMAC_STAT(rx_collision),
+       STMMAC_STAT(rx_crc),
+       STMMAC_STAT(rx_length),
+       STMMAC_STAT(rx_mii),
+       STMMAC_STAT(rx_multicast),
+       STMMAC_STAT(rx_gmac_overflow),
+       STMMAC_STAT(rx_watchdog),
+       STMMAC_STAT(da_rx_filter_fail),
+       STMMAC_STAT(sa_rx_filter_fail),
+       STMMAC_STAT(rx_missed_cntr),
+       STMMAC_STAT(rx_overflow_cntr),
+       STMMAC_STAT(tx_undeflow_irq),
+       STMMAC_STAT(tx_process_stopped_irq),
+       STMMAC_STAT(tx_jabber_irq),
+       STMMAC_STAT(rx_overflow_irq),
+       STMMAC_STAT(rx_buf_unav_irq),
+       STMMAC_STAT(rx_process_stopped_irq),
+       STMMAC_STAT(rx_watchdog_irq),
+       STMMAC_STAT(tx_early_irq),
+       STMMAC_STAT(fatal_bus_error_irq),
+       STMMAC_STAT(threshold),
+       STMMAC_STAT(tx_pkt_n),
+       STMMAC_STAT(rx_pkt_n),
+       STMMAC_STAT(poll_n),
+       STMMAC_STAT(sched_timer_n),
+       STMMAC_STAT(normal_irq_n),
+};
+#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
+
+static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
+                                     struct ethtool_drvinfo *info)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       if (!priv->plat->has_gmac)
+               strcpy(info->driver, MAC100_ETHTOOL_NAME);
+       else
+               strcpy(info->driver, GMAC_ETHTOOL_NAME);
+
+       strcpy(info->version, DRV_MODULE_VERSION);
+       info->fw_version[0] = '\0';
+       info->n_stats = STMMAC_STATS_LEN;
+}
+
+static int stmmac_ethtool_getsettings(struct net_device *dev,
+                                     struct ethtool_cmd *cmd)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phy = priv->phydev;
+       int rc;
+       if (phy == NULL) {
+               pr_err("%s: %s: PHY is not registered\n",
+                      __func__, dev->name);
+               return -ENODEV;
+       }
+       if (!netif_running(dev)) {
+               pr_err("%s: interface is disabled: we cannot track "
+               "link speed / duplex setting\n", dev->name);
+               return -EBUSY;
+       }
+       cmd->transceiver = XCVR_INTERNAL;
+       spin_lock_irq(&priv->lock);
+       rc = phy_ethtool_gset(phy, cmd);
+       spin_unlock_irq(&priv->lock);
+       return rc;
+}
+
+static int stmmac_ethtool_setsettings(struct net_device *dev,
+                                     struct ethtool_cmd *cmd)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phy = priv->phydev;
+       int rc;
+
+       spin_lock(&priv->lock);
+       rc = phy_ethtool_sset(phy, cmd);
+       spin_unlock(&priv->lock);
+
+       return rc;
+}
+
+static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       return priv->msg_enable;
+}
+
+static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       priv->msg_enable = level;
+
+}
+
+static int stmmac_check_if_running(struct net_device *dev)
+{
+       if (!netif_running(dev))
+               return -EBUSY;
+       return 0;
+}
+
+static int stmmac_ethtool_get_regs_len(struct net_device *dev)
+{
+       return REG_SPACE_SIZE;
+}
+
+static void stmmac_ethtool_gregs(struct net_device *dev,
+                         struct ethtool_regs *regs, void *space)
+{
+       int i;
+       u32 *reg_space = (u32 *) space;
+
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       memset(reg_space, 0x0, REG_SPACE_SIZE);
+
+       if (!priv->plat->has_gmac) {
+               /* MAC registers */
+               for (i = 0; i < 12; i++)
+                       reg_space[i] = readl(priv->ioaddr + (i * 4));
+               /* DMA registers */
+               for (i = 0; i < 9; i++)
+                       reg_space[i + 12] =
+                           readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
+               reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR);
+               reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR);
+       } else {
+               /* MAC registers */
+               for (i = 0; i < 55; i++)
+                       reg_space[i] = readl(priv->ioaddr + (i * 4));
+               /* DMA registers */
+               for (i = 0; i < 22; i++)
+                       reg_space[i + 55] =
+                           readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
+       }
+}
+
+static void
+stmmac_get_pauseparam(struct net_device *netdev,
+                     struct ethtool_pauseparam *pause)
+{
+       struct stmmac_priv *priv = netdev_priv(netdev);
+
+       spin_lock(&priv->lock);
+
+       pause->rx_pause = 0;
+       pause->tx_pause = 0;
+       pause->autoneg = priv->phydev->autoneg;
+
+       if (priv->flow_ctrl & FLOW_RX)
+               pause->rx_pause = 1;
+       if (priv->flow_ctrl & FLOW_TX)
+               pause->tx_pause = 1;
+
+       spin_unlock(&priv->lock);
+}
+
+static int
+stmmac_set_pauseparam(struct net_device *netdev,
+                     struct ethtool_pauseparam *pause)
+{
+       struct stmmac_priv *priv = netdev_priv(netdev);
+       struct phy_device *phy = priv->phydev;
+       int new_pause = FLOW_OFF;
+       int ret = 0;
+
+       spin_lock(&priv->lock);
+
+       if (pause->rx_pause)
+               new_pause |= FLOW_RX;
+       if (pause->tx_pause)
+               new_pause |= FLOW_TX;
+
+       priv->flow_ctrl = new_pause;
+       phy->autoneg = pause->autoneg;
+
+       if (phy->autoneg) {
+               if (netif_running(netdev))
+                       ret = phy_start_aneg(phy);
+       } else
+               priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
+                                        priv->flow_ctrl, priv->pause);
+       spin_unlock(&priv->lock);
+       return ret;
+}
+
+static void stmmac_get_ethtool_stats(struct net_device *dev,
+                                struct ethtool_stats *dummy, u64 *data)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int i;
+
+       /* Update HW stats if supported */
+       priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
+                                        priv->ioaddr);
+
+       for (i = 0; i < STMMAC_STATS_LEN; i++) {
+               char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
+               data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
+               sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
+       }
+}
+
+static int stmmac_get_sset_count(struct net_device *netdev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return STMMAC_STATS_LEN;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+       int i;
+       u8 *p = data;
+
+       switch (stringset) {
+       case ETH_SS_STATS:
+               for (i = 0; i < STMMAC_STATS_LEN; i++) {
+                       memcpy(p, stmmac_gstrings_stats[i].stat_string,
+                               ETH_GSTRING_LEN);
+                       p += ETH_GSTRING_LEN;
+               }
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+}
+
+/* Currently only support WOL through Magic packet. */
+static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       spin_lock_irq(&priv->lock);
+       if (device_can_wakeup(priv->device)) {
+               wol->supported = WAKE_MAGIC | WAKE_UCAST;
+               wol->wolopts = priv->wolopts;
+       }
+       spin_unlock_irq(&priv->lock);
+}
+
+static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       u32 support = WAKE_MAGIC | WAKE_UCAST;
+
+       if (!device_can_wakeup(priv->device))
+               return -EINVAL;
+
+       if (wol->wolopts & ~support)
+               return -EINVAL;
+
+       if (wol->wolopts) {
+               pr_info("stmmac: wakeup enable\n");
+               device_set_wakeup_enable(priv->device, 1);
+               enable_irq_wake(dev->irq);
+       } else {
+               device_set_wakeup_enable(priv->device, 0);
+               disable_irq_wake(dev->irq);
+       }
+
+       spin_lock_irq(&priv->lock);
+       priv->wolopts = wol->wolopts;
+       spin_unlock_irq(&priv->lock);
+
+       return 0;
+}
+
+static struct ethtool_ops stmmac_ethtool_ops = {
+       .begin = stmmac_check_if_running,
+       .get_drvinfo = stmmac_ethtool_getdrvinfo,
+       .get_settings = stmmac_ethtool_getsettings,
+       .set_settings = stmmac_ethtool_setsettings,
+       .get_msglevel = stmmac_ethtool_getmsglevel,
+       .set_msglevel = stmmac_ethtool_setmsglevel,
+       .get_regs = stmmac_ethtool_gregs,
+       .get_regs_len = stmmac_ethtool_get_regs_len,
+       .get_link = ethtool_op_get_link,
+       .get_pauseparam = stmmac_get_pauseparam,
+       .set_pauseparam = stmmac_set_pauseparam,
+       .get_ethtool_stats = stmmac_get_ethtool_stats,
+       .get_strings = stmmac_get_strings,
+       .get_wol = stmmac_get_wol,
+       .set_wol = stmmac_set_wol,
+       .get_sset_count = stmmac_get_sset_count,
+};
+
+void stmmac_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
new file mode 100644 (file)
index 0000000..c6e567e
--- /dev/null
@@ -0,0 +1,1895 @@
+/*******************************************************************************
+  This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
+  ST Ethernet IPs are built around a Synopsys IP Core.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+
+  Documentation available at:
+       http://www.stlinux.com
+  Support available at:
+       https://bugzilla.stlinux.com/
+*******************************************************************************/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/if_ether.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/if_vlan.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/prefetch.h>
+#include "stmmac.h"
+
+#define STMMAC_RESOURCE_NAME   "stmmaceth"
+
+#undef STMMAC_DEBUG
+/*#define STMMAC_DEBUG*/
+#ifdef STMMAC_DEBUG
+#define DBG(nlevel, klevel, fmt, args...) \
+               ((void)(netif_msg_##nlevel(priv) && \
+               printk(KERN_##klevel fmt, ## args)))
+#else
+#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
+#endif
+
+#undef STMMAC_RX_DEBUG
+/*#define STMMAC_RX_DEBUG*/
+#ifdef STMMAC_RX_DEBUG
+#define RX_DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define RX_DBG(fmt, args...)  do { } while (0)
+#endif
+
+#undef STMMAC_XMIT_DEBUG
+/*#define STMMAC_XMIT_DEBUG*/
+#ifdef STMMAC_TX_DEBUG
+#define TX_DBG(fmt, args...)  printk(fmt, ## args)
+#else
+#define TX_DBG(fmt, args...)  do { } while (0)
+#endif
+
+#define STMMAC_ALIGN(x)        L1_CACHE_ALIGN(x)
+#define JUMBO_LEN      9000
+
+/* Module parameters */
+#define TX_TIMEO 5000 /* default 5 seconds */
+static int watchdog = TX_TIMEO;
+module_param(watchdog, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
+
+static int debug = -1;         /* -1: default, 0: no output, 16:  all */
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
+
+static int phyaddr = -1;
+module_param(phyaddr, int, S_IRUGO);
+MODULE_PARM_DESC(phyaddr, "Physical device address");
+
+#define DMA_TX_SIZE 256
+static int dma_txsize = DMA_TX_SIZE;
+module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
+
+#define DMA_RX_SIZE 256
+static int dma_rxsize = DMA_RX_SIZE;
+module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
+
+static int flow_ctrl = FLOW_OFF;
+module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
+
+static int pause = PAUSE_TIME;
+module_param(pause, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(pause, "Flow Control Pause Time");
+
+#define TC_DEFAULT 64
+static int tc = TC_DEFAULT;
+module_param(tc, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tc, "DMA threshold control value");
+
+/* Pay attention to tune this parameter; take care of both
+ * hardware capability and network stabitily/performance impact.
+ * Many tests showed that ~4ms latency seems to be good enough. */
+#ifdef CONFIG_STMMAC_TIMER
+#define DEFAULT_PERIODIC_RATE  256
+static int tmrate = DEFAULT_PERIODIC_RATE;
+module_param(tmrate, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
+#endif
+
+#define DMA_BUFFER_SIZE        BUF_SIZE_2KiB
+static int buf_sz = DMA_BUFFER_SIZE;
+module_param(buf_sz, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(buf_sz, "DMA buffer size");
+
+static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
+                                     NETIF_MSG_LINK | NETIF_MSG_IFUP |
+                                     NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
+
+static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
+
+/**
+ * stmmac_verify_args - verify the driver parameters.
+ * Description: it verifies if some wrong parameter is passed to the driver.
+ * Note that wrong parameters are replaced with the default values.
+ */
+static void stmmac_verify_args(void)
+{
+       if (unlikely(watchdog < 0))
+               watchdog = TX_TIMEO;
+       if (unlikely(dma_rxsize < 0))
+               dma_rxsize = DMA_RX_SIZE;
+       if (unlikely(dma_txsize < 0))
+               dma_txsize = DMA_TX_SIZE;
+       if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
+               buf_sz = DMA_BUFFER_SIZE;
+       if (unlikely(flow_ctrl > 1))
+               flow_ctrl = FLOW_AUTO;
+       else if (likely(flow_ctrl < 0))
+               flow_ctrl = FLOW_OFF;
+       if (unlikely((pause < 0) || (pause > 0xffff)))
+               pause = PAUSE_TIME;
+}
+
+#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
+static void print_pkt(unsigned char *buf, int len)
+{
+       int j;
+       pr_info("len = %d byte, buf addr: 0x%p", len, buf);
+       for (j = 0; j < len; j++) {
+               if ((j % 16) == 0)
+                       pr_info("\n %03x:", j);
+               pr_info(" %02x", buf[j]);
+       }
+       pr_info("\n");
+}
+#endif
+
+/* minimum number of free TX descriptors required to wake up TX process */
+#define STMMAC_TX_THRESH(x)    (x->dma_tx_size/4)
+
+static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
+{
+       return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
+}
+
+/* On some ST platforms, some HW system configuraton registers have to be
+ * set according to the link speed negotiated.
+ */
+static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
+{
+       struct phy_device *phydev = priv->phydev;
+
+       if (likely(priv->plat->fix_mac_speed))
+               priv->plat->fix_mac_speed(priv->plat->bsp_priv,
+                                         phydev->speed);
+}
+
+/**
+ * stmmac_adjust_link
+ * @dev: net device structure
+ * Description: it adjusts the link parameters.
+ */
+static void stmmac_adjust_link(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev = priv->phydev;
+       unsigned long flags;
+       int new_state = 0;
+       unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
+
+       if (phydev == NULL)
+               return;
+
+       DBG(probe, DEBUG, "stmmac_adjust_link: called.  address %d link %d\n",
+           phydev->addr, phydev->link);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (phydev->link) {
+               u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
+
+               /* Now we make sure that we can be in full duplex mode.
+                * If not, we operate in half-duplex mode. */
+               if (phydev->duplex != priv->oldduplex) {
+                       new_state = 1;
+                       if (!(phydev->duplex))
+                               ctrl &= ~priv->hw->link.duplex;
+                       else
+                               ctrl |= priv->hw->link.duplex;
+                       priv->oldduplex = phydev->duplex;
+               }
+               /* Flow Control operation */
+               if (phydev->pause)
+                       priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
+                                                fc, pause_time);
+
+               if (phydev->speed != priv->speed) {
+                       new_state = 1;
+                       switch (phydev->speed) {
+                       case 1000:
+                               if (likely(priv->plat->has_gmac))
+                                       ctrl &= ~priv->hw->link.port;
+                               stmmac_hw_fix_mac_speed(priv);
+                               break;
+                       case 100:
+                       case 10:
+                               if (priv->plat->has_gmac) {
+                                       ctrl |= priv->hw->link.port;
+                                       if (phydev->speed == SPEED_100) {
+                                               ctrl |= priv->hw->link.speed;
+                                       } else {
+                                               ctrl &= ~(priv->hw->link.speed);
+                                       }
+                               } else {
+                                       ctrl &= ~priv->hw->link.port;
+                               }
+                               stmmac_hw_fix_mac_speed(priv);
+                               break;
+                       default:
+                               if (netif_msg_link(priv))
+                                       pr_warning("%s: Speed (%d) is not 10"
+                                      " or 100!\n", dev->name, phydev->speed);
+                               break;
+                       }
+
+                       priv->speed = phydev->speed;
+               }
+
+               writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
+
+               if (!priv->oldlink) {
+                       new_state = 1;
+                       priv->oldlink = 1;
+               }
+       } else if (priv->oldlink) {
+               new_state = 1;
+               priv->oldlink = 0;
+               priv->speed = 0;
+               priv->oldduplex = -1;
+       }
+
+       if (new_state && netif_msg_link(priv))
+               phy_print_status(phydev);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
+}
+
+/**
+ * stmmac_init_phy - PHY initialization
+ * @dev: net device structure
+ * Description: it initializes the driver's PHY state, and attaches the PHY
+ * to the mac driver.
+ *  Return value:
+ *  0 on success
+ */
+static int stmmac_init_phy(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev;
+       char phy_id[MII_BUS_ID_SIZE + 3];
+       char bus_id[MII_BUS_ID_SIZE];
+
+       priv->oldlink = 0;
+       priv->speed = 0;
+       priv->oldduplex = -1;
+
+       snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
+       snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
+                priv->plat->phy_addr);
+       pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id);
+
+       phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
+                            priv->plat->interface);
+
+       if (IS_ERR(phydev)) {
+               pr_err("%s: Could not attach to PHY\n", dev->name);
+               return PTR_ERR(phydev);
+       }
+
+       /*
+        * Broken HW is sometimes missing the pull-up resistor on the
+        * MDIO line, which results in reads to non-existent devices returning
+        * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
+        * device as well.
+        * Note: phydev->phy_id is the result of reading the UID PHY registers.
+        */
+       if (phydev->phy_id == 0) {
+               phy_disconnect(phydev);
+               return -ENODEV;
+       }
+       pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
+                " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
+
+       priv->phydev = phydev;
+
+       return 0;
+}
+
+static inline void stmmac_enable_mac(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CTRL_REG);
+
+       value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
+       writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+static inline void stmmac_disable_mac(void __iomem *ioaddr)
+{
+       u32 value = readl(ioaddr + MAC_CTRL_REG);
+
+       value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
+       writel(value, ioaddr + MAC_CTRL_REG);
+}
+
+/**
+ * display_ring
+ * @p: pointer to the ring.
+ * @size: size of the ring.
+ * Description: display all the descriptors within the ring.
+ */
+static void display_ring(struct dma_desc *p, int size)
+{
+       struct tmp_s {
+               u64 a;
+               unsigned int b;
+               unsigned int c;
+       };
+       int i;
+       for (i = 0; i < size; i++) {
+               struct tmp_s *x = (struct tmp_s *)(p + i);
+               pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
+                      i, (unsigned int)virt_to_phys(&p[i]),
+                      (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
+                      x->b, x->c);
+               pr_info("\n");
+       }
+}
+
+/**
+ * init_dma_desc_rings - init the RX/TX descriptor rings
+ * @dev: net device structure
+ * Description:  this function initializes the DMA RX/TX descriptors
+ * and allocates the socket buffers.
+ */
+static void init_dma_desc_rings(struct net_device *dev)
+{
+       int i;
+       struct stmmac_priv *priv = netdev_priv(dev);
+       struct sk_buff *skb;
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int rxsize = priv->dma_rx_size;
+       unsigned int bfsize = priv->dma_buf_sz;
+       int buff2_needed = 0, dis_ic = 0;
+
+       /* Set the Buffer size according to the MTU;
+        * indeed, in case of jumbo we need to bump-up the buffer sizes.
+        */
+       if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
+               bfsize = BUF_SIZE_16KiB;
+       else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
+               bfsize = BUF_SIZE_8KiB;
+       else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
+               bfsize = BUF_SIZE_4KiB;
+       else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
+               bfsize = BUF_SIZE_2KiB;
+       else
+               bfsize = DMA_BUFFER_SIZE;
+
+#ifdef CONFIG_STMMAC_TIMER
+       /* Disable interrupts on completion for the reception if timer is on */
+       if (likely(priv->tm->enable))
+               dis_ic = 1;
+#endif
+       /* If the MTU exceeds 8k so use the second buffer in the chain */
+       if (bfsize >= BUF_SIZE_8KiB)
+               buff2_needed = 1;
+
+       DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
+           txsize, rxsize, bfsize);
+
+       priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
+       priv->rx_skbuff =
+           kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
+       priv->dma_rx =
+           (struct dma_desc *)dma_alloc_coherent(priv->device,
+                                                 rxsize *
+                                                 sizeof(struct dma_desc),
+                                                 &priv->dma_rx_phy,
+                                                 GFP_KERNEL);
+       priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
+                                      GFP_KERNEL);
+       priv->dma_tx =
+           (struct dma_desc *)dma_alloc_coherent(priv->device,
+                                                 txsize *
+                                                 sizeof(struct dma_desc),
+                                                 &priv->dma_tx_phy,
+                                                 GFP_KERNEL);
+
+       if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
+               pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
+               return;
+       }
+
+       DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
+           "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
+           dev->name, priv->dma_rx, priv->dma_tx,
+           (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
+
+       /* RX INITIALIZATION */
+       DBG(probe, INFO, "stmmac: SKB addresses:\n"
+                        "skb\t\tskb data\tdma data\n");
+
+       for (i = 0; i < rxsize; i++) {
+               struct dma_desc *p = priv->dma_rx + i;
+
+               skb = netdev_alloc_skb_ip_align(dev, bfsize);
+               if (unlikely(skb == NULL)) {
+                       pr_err("%s: Rx init fails; skb is NULL\n", __func__);
+                       break;
+               }
+               priv->rx_skbuff[i] = skb;
+               priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
+                                               bfsize, DMA_FROM_DEVICE);
+
+               p->des2 = priv->rx_skbuff_dma[i];
+               if (unlikely(buff2_needed))
+                       p->des3 = p->des2 + BUF_SIZE_8KiB;
+               DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
+                       priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
+       }
+       priv->cur_rx = 0;
+       priv->dirty_rx = (unsigned int)(i - rxsize);
+       priv->dma_buf_sz = bfsize;
+       buf_sz = bfsize;
+
+       /* TX INITIALIZATION */
+       for (i = 0; i < txsize; i++) {
+               priv->tx_skbuff[i] = NULL;
+               priv->dma_tx[i].des2 = 0;
+       }
+       priv->dirty_tx = 0;
+       priv->cur_tx = 0;
+
+       /* Clear the Rx/Tx descriptors */
+       priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
+       priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
+
+       if (netif_msg_hw(priv)) {
+               pr_info("RX descriptor ring:\n");
+               display_ring(priv->dma_rx, rxsize);
+               pr_info("TX descriptor ring:\n");
+               display_ring(priv->dma_tx, txsize);
+       }
+}
+
+static void dma_free_rx_skbufs(struct stmmac_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->dma_rx_size; i++) {
+               if (priv->rx_skbuff[i]) {
+                       dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
+                                        priv->dma_buf_sz, DMA_FROM_DEVICE);
+                       dev_kfree_skb_any(priv->rx_skbuff[i]);
+               }
+               priv->rx_skbuff[i] = NULL;
+       }
+}
+
+static void dma_free_tx_skbufs(struct stmmac_priv *priv)
+{
+       int i;
+
+       for (i = 0; i < priv->dma_tx_size; i++) {
+               if (priv->tx_skbuff[i] != NULL) {
+                       struct dma_desc *p = priv->dma_tx + i;
+                       if (p->des2)
+                               dma_unmap_single(priv->device, p->des2,
+                                                priv->hw->desc->get_tx_len(p),
+                                                DMA_TO_DEVICE);
+                       dev_kfree_skb_any(priv->tx_skbuff[i]);
+                       priv->tx_skbuff[i] = NULL;
+               }
+       }
+}
+
+static void free_dma_desc_resources(struct stmmac_priv *priv)
+{
+       /* Release the DMA TX/RX socket buffers */
+       dma_free_rx_skbufs(priv);
+       dma_free_tx_skbufs(priv);
+
+       /* Free the region of consistent memory previously allocated for
+        * the DMA */
+       dma_free_coherent(priv->device,
+                         priv->dma_tx_size * sizeof(struct dma_desc),
+                         priv->dma_tx, priv->dma_tx_phy);
+       dma_free_coherent(priv->device,
+                         priv->dma_rx_size * sizeof(struct dma_desc),
+                         priv->dma_rx, priv->dma_rx_phy);
+       kfree(priv->rx_skbuff_dma);
+       kfree(priv->rx_skbuff);
+       kfree(priv->tx_skbuff);
+}
+
+/**
+ *  stmmac_dma_operation_mode - HW DMA operation mode
+ *  @priv : pointer to the private device structure.
+ *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
+ *  or Store-And-Forward capability.
+ */
+static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
+{
+       if (likely(priv->plat->force_sf_dma_mode ||
+               ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) {
+               /*
+                * In case of GMAC, SF mode can be enabled
+                * to perform the TX COE in HW. This depends on:
+                * 1) TX COE if actually supported
+                * 2) There is no bugged Jumbo frame support
+                *    that needs to not insert csum in the TDES.
+                */
+               priv->hw->dma->dma_mode(priv->ioaddr,
+                                       SF_DMA_MODE, SF_DMA_MODE);
+               tc = SF_DMA_MODE;
+       } else
+               priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
+}
+
+/**
+ * stmmac_tx:
+ * @priv: private driver structure
+ * Description: it reclaims resources after transmission completes.
+ */
+static void stmmac_tx(struct stmmac_priv *priv)
+{
+       unsigned int txsize = priv->dma_tx_size;
+
+       while (priv->dirty_tx != priv->cur_tx) {
+               int last;
+               unsigned int entry = priv->dirty_tx % txsize;
+               struct sk_buff *skb = priv->tx_skbuff[entry];
+               struct dma_desc *p = priv->dma_tx + entry;
+
+               /* Check if the descriptor is owned by the DMA. */
+               if (priv->hw->desc->get_tx_owner(p))
+                       break;
+
+               /* Verify tx error by looking at the last segment */
+               last = priv->hw->desc->get_tx_ls(p);
+               if (likely(last)) {
+                       int tx_error =
+                               priv->hw->desc->tx_status(&priv->dev->stats,
+                                                         &priv->xstats, p,
+                                                         priv->ioaddr);
+                       if (likely(tx_error == 0)) {
+                               priv->dev->stats.tx_packets++;
+                               priv->xstats.tx_pkt_n++;
+                       } else
+                               priv->dev->stats.tx_errors++;
+               }
+               TX_DBG("%s: curr %d, dirty %d\n", __func__,
+                       priv->cur_tx, priv->dirty_tx);
+
+               if (likely(p->des2))
+                       dma_unmap_single(priv->device, p->des2,
+                                        priv->hw->desc->get_tx_len(p),
+                                        DMA_TO_DEVICE);
+               if (unlikely(p->des3))
+                       p->des3 = 0;
+
+               if (likely(skb != NULL)) {
+                       /*
+                        * If there's room in the queue (limit it to size)
+                        * we add this skb back into the pool,
+                        * if it's the right size.
+                        */
+                       if ((skb_queue_len(&priv->rx_recycle) <
+                               priv->dma_rx_size) &&
+                               skb_recycle_check(skb, priv->dma_buf_sz))
+                               __skb_queue_head(&priv->rx_recycle, skb);
+                       else
+                               dev_kfree_skb(skb);
+
+                       priv->tx_skbuff[entry] = NULL;
+               }
+
+               priv->hw->desc->release_tx_desc(p);
+
+               entry = (++priv->dirty_tx) % txsize;
+       }
+       if (unlikely(netif_queue_stopped(priv->dev) &&
+                    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
+               netif_tx_lock(priv->dev);
+               if (netif_queue_stopped(priv->dev) &&
+                    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
+                       TX_DBG("%s: restart transmit\n", __func__);
+                       netif_wake_queue(priv->dev);
+               }
+               netif_tx_unlock(priv->dev);
+       }
+}
+
+static inline void stmmac_enable_irq(struct stmmac_priv *priv)
+{
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_start(tmrate);
+       else
+#endif
+               priv->hw->dma->enable_dma_irq(priv->ioaddr);
+}
+
+static inline void stmmac_disable_irq(struct stmmac_priv *priv)
+{
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_stop();
+       else
+#endif
+               priv->hw->dma->disable_dma_irq(priv->ioaddr);
+}
+
+static int stmmac_has_work(struct stmmac_priv *priv)
+{
+       unsigned int has_work = 0;
+       int rxret, tx_work = 0;
+
+       rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
+               (priv->cur_rx % priv->dma_rx_size));
+
+       if (priv->dirty_tx != priv->cur_tx)
+               tx_work = 1;
+
+       if (likely(!rxret || tx_work))
+               has_work = 1;
+
+       return has_work;
+}
+
+static inline void _stmmac_schedule(struct stmmac_priv *priv)
+{
+       if (likely(stmmac_has_work(priv))) {
+               stmmac_disable_irq(priv);
+               napi_schedule(&priv->napi);
+       }
+}
+
+#ifdef CONFIG_STMMAC_TIMER
+void stmmac_schedule(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       priv->xstats.sched_timer_n++;
+
+       _stmmac_schedule(priv);
+}
+
+static void stmmac_no_timer_started(unsigned int x)
+{;
+};
+
+static void stmmac_no_timer_stopped(void)
+{;
+};
+#endif
+
+/**
+ * stmmac_tx_err:
+ * @priv: pointer to the private device structure
+ * Description: it cleans the descriptors and restarts the transmission
+ * in case of errors.
+ */
+static void stmmac_tx_err(struct stmmac_priv *priv)
+{
+
+       netif_stop_queue(priv->dev);
+
+       priv->hw->dma->stop_tx(priv->ioaddr);
+       dma_free_tx_skbufs(priv);
+       priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
+       priv->dirty_tx = 0;
+       priv->cur_tx = 0;
+       priv->hw->dma->start_tx(priv->ioaddr);
+
+       priv->dev->stats.tx_errors++;
+       netif_wake_queue(priv->dev);
+}
+
+
+static void stmmac_dma_interrupt(struct stmmac_priv *priv)
+{
+       int status;
+
+       status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
+       if (likely(status == handle_tx_rx))
+               _stmmac_schedule(priv);
+
+       else if (unlikely(status == tx_hard_error_bump_tc)) {
+               /* Try to bump up the dma threshold on this failure */
+               if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
+                       tc += 64;
+                       priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
+                       priv->xstats.threshold = tc;
+               }
+       } else if (unlikely(status == tx_hard_error))
+               stmmac_tx_err(priv);
+}
+
+/**
+ *  stmmac_open - open entry point of the driver
+ *  @dev : pointer to the device structure.
+ *  Description:
+ *  This function is the open entry point of the driver.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_open(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int ret;
+
+       /* Check that the MAC address is valid.  If its not, refuse
+        * to bring the device up. The user must specify an
+        * address using the following linux command:
+        *      ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx  */
+       if (!is_valid_ether_addr(dev->dev_addr)) {
+               random_ether_addr(dev->dev_addr);
+               pr_warning("%s: generated random MAC address %pM\n", dev->name,
+                       dev->dev_addr);
+       }
+
+       stmmac_verify_args();
+
+#ifdef CONFIG_STMMAC_TIMER
+       priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
+       if (unlikely(priv->tm == NULL)) {
+               pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
+               return -ENOMEM;
+       }
+       priv->tm->freq = tmrate;
+
+       /* Test if the external timer can be actually used.
+        * In case of failure continue without timer. */
+       if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
+               pr_warning("stmmaceth: cannot attach the external timer.\n");
+               priv->tm->freq = 0;
+               priv->tm->timer_start = stmmac_no_timer_started;
+               priv->tm->timer_stop = stmmac_no_timer_stopped;
+       } else
+               priv->tm->enable = 1;
+#endif
+       ret = stmmac_init_phy(dev);
+       if (unlikely(ret)) {
+               pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
+               goto open_error;
+       }
+
+       /* Create and initialize the TX/RX descriptors chains. */
+       priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
+       priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
+       priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
+       init_dma_desc_rings(dev);
+
+       /* DMA initialization and SW reset */
+       ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
+                                 priv->dma_tx_phy, priv->dma_rx_phy);
+       if (ret < 0) {
+               pr_err("%s: DMA initialization failed\n", __func__);
+               goto open_error;
+       }
+
+       /* Copy the MAC addr into the HW  */
+       priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
+       /* If required, perform hw setup of the bus. */
+       if (priv->plat->bus_setup)
+               priv->plat->bus_setup(priv->ioaddr);
+       /* Initialize the MAC Core */
+       priv->hw->mac->core_init(priv->ioaddr);
+
+       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
+       if (priv->rx_coe)
+               pr_info("stmmac: Rx Checksum Offload Engine supported\n");
+       if (priv->plat->tx_coe)
+               pr_info("\tTX Checksum insertion supported\n");
+       netdev_update_features(dev);
+
+       /* Initialise the MMC (if present) to disable all interrupts. */
+       writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
+       writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
+
+       /* Request the IRQ lines */
+       ret = request_irq(dev->irq, stmmac_interrupt,
+                        IRQF_SHARED, dev->name, dev);
+       if (unlikely(ret < 0)) {
+               pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
+                      __func__, dev->irq, ret);
+               goto open_error;
+       }
+
+       /* Enable the MAC Rx/Tx */
+       stmmac_enable_mac(priv->ioaddr);
+
+       /* Set the HW DMA mode and the COE */
+       stmmac_dma_operation_mode(priv);
+
+       /* Extra statistics */
+       memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
+       priv->xstats.threshold = tc;
+
+       /* Start the ball rolling... */
+       DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
+       priv->hw->dma->start_tx(priv->ioaddr);
+       priv->hw->dma->start_rx(priv->ioaddr);
+
+#ifdef CONFIG_STMMAC_TIMER
+       priv->tm->timer_start(tmrate);
+#endif
+       /* Dump DMA/MAC registers */
+       if (netif_msg_hw(priv)) {
+               priv->hw->mac->dump_regs(priv->ioaddr);
+               priv->hw->dma->dump_regs(priv->ioaddr);
+       }
+
+       if (priv->phydev)
+               phy_start(priv->phydev);
+
+       napi_enable(&priv->napi);
+       skb_queue_head_init(&priv->rx_recycle);
+       netif_start_queue(dev);
+
+       return 0;
+
+open_error:
+#ifdef CONFIG_STMMAC_TIMER
+       kfree(priv->tm);
+#endif
+       if (priv->phydev)
+               phy_disconnect(priv->phydev);
+
+       return ret;
+}
+
+/**
+ *  stmmac_release - close entry point of the driver
+ *  @dev : device pointer.
+ *  Description:
+ *  This is the stop entry point of the driver.
+ */
+static int stmmac_release(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       /* Stop and disconnect the PHY */
+       if (priv->phydev) {
+               phy_stop(priv->phydev);
+               phy_disconnect(priv->phydev);
+               priv->phydev = NULL;
+       }
+
+       netif_stop_queue(dev);
+
+#ifdef CONFIG_STMMAC_TIMER
+       /* Stop and release the timer */
+       stmmac_close_ext_timer();
+       if (priv->tm != NULL)
+               kfree(priv->tm);
+#endif
+       napi_disable(&priv->napi);
+       skb_queue_purge(&priv->rx_recycle);
+
+       /* Free the IRQ lines */
+       free_irq(dev->irq, dev);
+
+       /* Stop TX/RX DMA and clear the descriptors */
+       priv->hw->dma->stop_tx(priv->ioaddr);
+       priv->hw->dma->stop_rx(priv->ioaddr);
+
+       /* Release and free the Rx/Tx resources */
+       free_dma_desc_resources(priv);
+
+       /* Disable the MAC Rx/Tx */
+       stmmac_disable_mac(priv->ioaddr);
+
+       netif_carrier_off(dev);
+
+       return 0;
+}
+
+static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
+                                              struct net_device *dev,
+                                              int csum_insertion)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned int nopaged_len = skb_headlen(skb);
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int entry = priv->cur_tx % txsize;
+       struct dma_desc *desc = priv->dma_tx + entry;
+
+       if (nopaged_len > BUF_SIZE_8KiB) {
+
+               int buf2_size = nopaged_len - BUF_SIZE_8KiB;
+
+               desc->des2 = dma_map_single(priv->device, skb->data,
+                                           BUF_SIZE_8KiB, DMA_TO_DEVICE);
+               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+               priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
+                                               csum_insertion);
+
+               entry = (++priv->cur_tx) % txsize;
+               desc = priv->dma_tx + entry;
+
+               desc->des2 = dma_map_single(priv->device,
+                                       skb->data + BUF_SIZE_8KiB,
+                                       buf2_size, DMA_TO_DEVICE);
+               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+               priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
+                                               csum_insertion);
+               priv->hw->desc->set_tx_owner(desc);
+               priv->tx_skbuff[entry] = NULL;
+       } else {
+               desc->des2 = dma_map_single(priv->device, skb->data,
+                                       nopaged_len, DMA_TO_DEVICE);
+               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
+               priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
+                                               csum_insertion);
+       }
+       return entry;
+}
+
+/**
+ *  stmmac_xmit:
+ *  @skb : the socket buffer
+ *  @dev : device pointer
+ *  Description : Tx entry point of the driver.
+ */
+static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       unsigned int txsize = priv->dma_tx_size;
+       unsigned int entry;
+       int i, csum_insertion = 0;
+       int nfrags = skb_shinfo(skb)->nr_frags;
+       struct dma_desc *desc, *first;
+
+       if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
+               if (!netif_queue_stopped(dev)) {
+                       netif_stop_queue(dev);
+                       /* This is a hard error, log it. */
+                       pr_err("%s: BUG! Tx Ring full when queue awake\n",
+                               __func__);
+               }
+               return NETDEV_TX_BUSY;
+       }
+
+       entry = priv->cur_tx % txsize;
+
+#ifdef STMMAC_XMIT_DEBUG
+       if ((skb->len > ETH_FRAME_LEN) || nfrags)
+               pr_info("stmmac xmit:\n"
+                      "\tskb addr %p - len: %d - nopaged_len: %d\n"
+                      "\tn_frags: %d - ip_summed: %d - %s gso\n",
+                      skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
+                      !skb_is_gso(skb) ? "isn't" : "is");
+#endif
+
+       csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
+
+       desc = priv->dma_tx + entry;
+       first = desc;
+
+#ifdef STMMAC_XMIT_DEBUG
+       if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
+               pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
+                      "\t\tn_frags: %d, ip_summed: %d\n",
+                      skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
+#endif
+       priv->tx_skbuff[entry] = skb;
+       if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
+               entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
+               desc = priv->dma_tx + entry;
+       } else {
+               unsigned int nopaged_len = skb_headlen(skb);
+               desc->des2 = dma_map_single(priv->device, skb->data,
+                                       nopaged_len, DMA_TO_DEVICE);
+               priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
+                                               csum_insertion);
+       }
+
+       for (i = 0; i < nfrags; i++) {
+               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+               int len = frag->size;
+
+               entry = (++priv->cur_tx) % txsize;
+               desc = priv->dma_tx + entry;
+
+               TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
+               desc->des2 = dma_map_page(priv->device, frag->page,
+                                         frag->page_offset,
+                                         len, DMA_TO_DEVICE);
+               priv->tx_skbuff[entry] = NULL;
+               priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
+               wmb();
+               priv->hw->desc->set_tx_owner(desc);
+       }
+
+       /* Interrupt on completition only for the latest segment */
+       priv->hw->desc->close_tx_desc(desc);
+
+#ifdef CONFIG_STMMAC_TIMER
+       /* Clean IC while using timer */
+       if (likely(priv->tm->enable))
+               priv->hw->desc->clear_tx_ic(desc);
+#endif
+
+       wmb();
+
+       /* To avoid raise condition */
+       priv->hw->desc->set_tx_owner(first);
+
+       priv->cur_tx++;
+
+#ifdef STMMAC_XMIT_DEBUG
+       if (netif_msg_pktdata(priv)) {
+               pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
+                      "first=%p, nfrags=%d\n",
+                      (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
+                      entry, first, nfrags);
+               display_ring(priv->dma_tx, txsize);
+               pr_info(">>> frame to be transmitted: ");
+               print_pkt(skb->data, skb->len);
+       }
+#endif
+       if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
+               TX_DBG("%s: stop transmitted packets\n", __func__);
+               netif_stop_queue(dev);
+       }
+
+       dev->stats.tx_bytes += skb->len;
+
+       skb_tx_timestamp(skb);
+
+       priv->hw->dma->enable_dma_transmission(priv->ioaddr);
+
+       return NETDEV_TX_OK;
+}
+
+static inline void stmmac_rx_refill(struct stmmac_priv *priv)
+{
+       unsigned int rxsize = priv->dma_rx_size;
+       int bfsize = priv->dma_buf_sz;
+       struct dma_desc *p = priv->dma_rx;
+
+       for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
+               unsigned int entry = priv->dirty_rx % rxsize;
+               if (likely(priv->rx_skbuff[entry] == NULL)) {
+                       struct sk_buff *skb;
+
+                       skb = __skb_dequeue(&priv->rx_recycle);
+                       if (skb == NULL)
+                               skb = netdev_alloc_skb_ip_align(priv->dev,
+                                                               bfsize);
+
+                       if (unlikely(skb == NULL))
+                               break;
+
+                       priv->rx_skbuff[entry] = skb;
+                       priv->rx_skbuff_dma[entry] =
+                           dma_map_single(priv->device, skb->data, bfsize,
+                                          DMA_FROM_DEVICE);
+
+                       (p + entry)->des2 = priv->rx_skbuff_dma[entry];
+                       if (unlikely(priv->plat->has_gmac)) {
+                               if (bfsize >= BUF_SIZE_8KiB)
+                                       (p + entry)->des3 =
+                                           (p + entry)->des2 + BUF_SIZE_8KiB;
+                       }
+                       RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
+               }
+               wmb();
+               priv->hw->desc->set_rx_owner(p + entry);
+       }
+}
+
+static int stmmac_rx(struct stmmac_priv *priv, int limit)
+{
+       unsigned int rxsize = priv->dma_rx_size;
+       unsigned int entry = priv->cur_rx % rxsize;
+       unsigned int next_entry;
+       unsigned int count = 0;
+       struct dma_desc *p = priv->dma_rx + entry;
+       struct dma_desc *p_next;
+
+#ifdef STMMAC_RX_DEBUG
+       if (netif_msg_hw(priv)) {
+               pr_debug(">>> stmmac_rx: descriptor ring:\n");
+               display_ring(priv->dma_rx, rxsize);
+       }
+#endif
+       count = 0;
+       while (!priv->hw->desc->get_rx_owner(p)) {
+               int status;
+
+               if (count >= limit)
+                       break;
+
+               count++;
+
+               next_entry = (++priv->cur_rx) % rxsize;
+               p_next = priv->dma_rx + next_entry;
+               prefetch(p_next);
+
+               /* read the status of the incoming frame */
+               status = (priv->hw->desc->rx_status(&priv->dev->stats,
+                                                   &priv->xstats, p));
+               if (unlikely(status == discard_frame))
+                       priv->dev->stats.rx_errors++;
+               else {
+                       struct sk_buff *skb;
+                       int frame_len;
+
+                       frame_len = priv->hw->desc->get_rx_frame_len(p);
+                       /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
+                        * Type frames (LLC/LLC-SNAP) */
+                       if (unlikely(status != llc_snap))
+                               frame_len -= ETH_FCS_LEN;
+#ifdef STMMAC_RX_DEBUG
+                       if (frame_len > ETH_FRAME_LEN)
+                               pr_debug("\tRX frame size %d, COE status: %d\n",
+                                       frame_len, status);
+
+                       if (netif_msg_hw(priv))
+                               pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
+                                       p, entry, p->des2);
+#endif
+                       skb = priv->rx_skbuff[entry];
+                       if (unlikely(!skb)) {
+                               pr_err("%s: Inconsistent Rx descriptor chain\n",
+                                       priv->dev->name);
+                               priv->dev->stats.rx_dropped++;
+                               break;
+                       }
+                       prefetch(skb->data - NET_IP_ALIGN);
+                       priv->rx_skbuff[entry] = NULL;
+
+                       skb_put(skb, frame_len);
+                       dma_unmap_single(priv->device,
+                                        priv->rx_skbuff_dma[entry],
+                                        priv->dma_buf_sz, DMA_FROM_DEVICE);
+#ifdef STMMAC_RX_DEBUG
+                       if (netif_msg_pktdata(priv)) {
+                               pr_info(" frame received (%dbytes)", frame_len);
+                               print_pkt(skb->data, frame_len);
+                       }
+#endif
+                       skb->protocol = eth_type_trans(skb, priv->dev);
+
+                       if (unlikely(status == csum_none)) {
+                               /* always for the old mac 10/100 */
+                               skb_checksum_none_assert(skb);
+                               netif_receive_skb(skb);
+                       } else {
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+                               napi_gro_receive(&priv->napi, skb);
+                       }
+
+                       priv->dev->stats.rx_packets++;
+                       priv->dev->stats.rx_bytes += frame_len;
+               }
+               entry = next_entry;
+               p = p_next;     /* use prefetched values */
+       }
+
+       stmmac_rx_refill(priv);
+
+       priv->xstats.rx_pkt_n += count;
+
+       return count;
+}
+
+/**
+ *  stmmac_poll - stmmac poll method (NAPI)
+ *  @napi : pointer to the napi structure.
+ *  @budget : maximum number of packets that the current CPU can receive from
+ *           all interfaces.
+ *  Description :
+ *   This function implements the the reception process.
+ *   Also it runs the TX completion thread
+ */
+static int stmmac_poll(struct napi_struct *napi, int budget)
+{
+       struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
+       int work_done = 0;
+
+       priv->xstats.poll_n++;
+       stmmac_tx(priv);
+       work_done = stmmac_rx(priv, budget);
+
+       if (work_done < budget) {
+               napi_complete(napi);
+               stmmac_enable_irq(priv);
+       }
+       return work_done;
+}
+
+/**
+ *  stmmac_tx_timeout
+ *  @dev : Pointer to net device structure
+ *  Description: this function is called when a packet transmission fails to
+ *   complete within a reasonable tmrate. The driver will mark the error in the
+ *   netdev structure and arrange for the device to be reset to a sane state
+ *   in order to transmit a new packet.
+ */
+static void stmmac_tx_timeout(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       /* Clear Tx resources and restart transmitting again */
+       stmmac_tx_err(priv);
+}
+
+/* Configuration changes (passed on by ifconfig) */
+static int stmmac_config(struct net_device *dev, struct ifmap *map)
+{
+       if (dev->flags & IFF_UP)        /* can't act on a running interface */
+               return -EBUSY;
+
+       /* Don't allow changing the I/O address */
+       if (map->base_addr != dev->base_addr) {
+               pr_warning("%s: can't change I/O address\n", dev->name);
+               return -EOPNOTSUPP;
+       }
+
+       /* Don't allow changing the IRQ */
+       if (map->irq != dev->irq) {
+               pr_warning("%s: can't change IRQ number %d\n",
+                      dev->name, dev->irq);
+               return -EOPNOTSUPP;
+       }
+
+       /* ignore other fields */
+       return 0;
+}
+
+/**
+ *  stmmac_multicast_list - entry point for multicast addressing
+ *  @dev : pointer to the device structure
+ *  Description:
+ *  This function is a driver entry point which gets called by the kernel
+ *  whenever multicast addresses must be enabled/disabled.
+ *  Return value:
+ *  void.
+ */
+static void stmmac_multicast_list(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       spin_lock(&priv->lock);
+       priv->hw->mac->set_filter(dev);
+       spin_unlock(&priv->lock);
+}
+
+/**
+ *  stmmac_change_mtu - entry point to change MTU size for the device.
+ *  @dev : device pointer.
+ *  @new_mtu : the new MTU size for the device.
+ *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
+ *  to drive packet transmission. Ethernet has an MTU of 1500 octets
+ *  (ETH_DATA_LEN). This value can be changed with ifconfig.
+ *  Return value:
+ *  0 on success and an appropriate (-)ve integer as defined in errno.h
+ *  file on failure.
+ */
+static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int max_mtu;
+
+       if (netif_running(dev)) {
+               pr_err("%s: must be stopped to change its MTU\n", dev->name);
+               return -EBUSY;
+       }
+
+       if (priv->plat->has_gmac)
+               max_mtu = JUMBO_LEN;
+       else
+               max_mtu = ETH_DATA_LEN;
+
+       if ((new_mtu < 46) || (new_mtu > max_mtu)) {
+               pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
+               return -EINVAL;
+       }
+
+       dev->mtu = new_mtu;
+       netdev_update_features(dev);
+
+       return 0;
+}
+
+static u32 stmmac_fix_features(struct net_device *dev, u32 features)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       if (!priv->rx_coe)
+               features &= ~NETIF_F_RXCSUM;
+       if (!priv->plat->tx_coe)
+               features &= ~NETIF_F_ALL_CSUM;
+
+       /* Some GMAC devices have a bugged Jumbo frame support that
+        * needs to have the Tx COE disabled for oversized frames
+        * (due to limited buffer sizes). In this case we disable
+        * the TX csum insertionin the TDES and not use SF. */
+       if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
+               features &= ~NETIF_F_ALL_CSUM;
+
+       return features;
+}
+
+static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = (struct net_device *)dev_id;
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       if (unlikely(!dev)) {
+               pr_err("%s: invalid dev pointer\n", __func__);
+               return IRQ_NONE;
+       }
+
+       if (priv->plat->has_gmac)
+               /* To handle GMAC own interrupts */
+               priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
+
+       stmmac_dma_interrupt(priv);
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/* Polling receive - used by NETCONSOLE and other diagnostic tools
+ * to allow network I/O with interrupts disabled. */
+static void stmmac_poll_controller(struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       stmmac_interrupt(dev->irq, dev);
+       enable_irq(dev->irq);
+}
+#endif
+
+/**
+ *  stmmac_ioctl - Entry point for the Ioctl
+ *  @dev: Device pointer.
+ *  @rq: An IOCTL specefic structure, that can contain a pointer to
+ *  a proprietary structure used to pass information to the driver.
+ *  @cmd: IOCTL command
+ *  Description:
+ *  Currently there are no special functionality supported in IOCTL, just the
+ *  phy_mii_ioctl(...) can be invoked.
+ */
+static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int ret;
+
+       if (!netif_running(dev))
+               return -EINVAL;
+
+       if (!priv->phydev)
+               return -EINVAL;
+
+       spin_lock(&priv->lock);
+       ret = phy_mii_ioctl(priv->phydev, rq, cmd);
+       spin_unlock(&priv->lock);
+
+       return ret;
+}
+
+static const struct net_device_ops stmmac_netdev_ops = {
+       .ndo_open = stmmac_open,
+       .ndo_start_xmit = stmmac_xmit,
+       .ndo_stop = stmmac_release,
+       .ndo_change_mtu = stmmac_change_mtu,
+       .ndo_fix_features = stmmac_fix_features,
+       .ndo_set_multicast_list = stmmac_multicast_list,
+       .ndo_tx_timeout = stmmac_tx_timeout,
+       .ndo_do_ioctl = stmmac_ioctl,
+       .ndo_set_config = stmmac_config,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller = stmmac_poll_controller,
+#endif
+       .ndo_set_mac_address = eth_mac_addr,
+};
+
+/**
+ * stmmac_probe - Initialization of the adapter .
+ * @dev : device pointer
+ * Description: The function initializes the network device structure for
+ * the STMMAC driver. It also calls the low level routines
+ * in order to init the HW (i.e. the DMA engine)
+ */
+static int stmmac_probe(struct net_device *dev)
+{
+       int ret = 0;
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       ether_setup(dev);
+
+       dev->netdev_ops = &stmmac_netdev_ops;
+       stmmac_set_ethtool_ops(dev);
+
+       dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+       dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
+       dev->watchdog_timeo = msecs_to_jiffies(watchdog);
+#ifdef STMMAC_VLAN_TAG_USED
+       /* Both mac100 and gmac support receive VLAN tag detection */
+       dev->features |= NETIF_F_HW_VLAN_RX;
+#endif
+       priv->msg_enable = netif_msg_init(debug, default_msg_level);
+
+       if (flow_ctrl)
+               priv->flow_ctrl = FLOW_AUTO;    /* RX/TX pause on */
+
+       priv->pause = pause;
+       netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
+
+       /* Get the MAC address */
+       priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
+                                    dev->dev_addr, 0);
+
+       if (!is_valid_ether_addr(dev->dev_addr))
+               pr_warning("\tno valid MAC address;"
+                       "please, use ifconfig or nwhwconfig!\n");
+
+       spin_lock_init(&priv->lock);
+
+       ret = register_netdev(dev);
+       if (ret) {
+               pr_err("%s: ERROR %i registering the device\n",
+                      __func__, ret);
+               return -ENODEV;
+       }
+
+       DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
+           dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
+           (dev->features & NETIF_F_IP_CSUM) ? "on" : "off");
+
+       return ret;
+}
+
+/**
+ * stmmac_mac_device_setup
+ * @dev : device pointer
+ * Description: select and initialise the mac device (mac100 or Gmac).
+ */
+static int stmmac_mac_device_setup(struct net_device *dev)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       struct mac_device_info *device;
+
+       if (priv->plat->has_gmac)
+               device = dwmac1000_setup(priv->ioaddr);
+       else
+               device = dwmac100_setup(priv->ioaddr);
+
+       if (!device)
+               return -ENOMEM;
+
+       if (priv->plat->enh_desc) {
+               device->desc = &enh_desc_ops;
+               pr_info("\tEnhanced descriptor structure\n");
+       } else
+               device->desc = &ndesc_ops;
+
+       priv->hw = device;
+
+       if (device_can_wakeup(priv->device)) {
+               priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
+               enable_irq_wake(dev->irq);
+       }
+
+       return 0;
+}
+
+/**
+ * stmmac_dvr_probe
+ * @pdev: platform device pointer
+ * Description: the driver is initialized through platform_device.
+ */
+static int stmmac_dvr_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct resource *res;
+       void __iomem *addr = NULL;
+       struct net_device *ndev = NULL;
+       struct stmmac_priv *priv = NULL;
+       struct plat_stmmacenet_data *plat_dat;
+
+       pr_info("STMMAC driver:\n\tplatform registration... ");
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+       pr_info("\tdone!\n");
+
+       if (!request_mem_region(res->start, resource_size(res),
+                               pdev->name)) {
+               pr_err("%s: ERROR: memory allocation failed"
+                      "cannot get the I/O addr 0x%x\n",
+                      __func__, (unsigned int)res->start);
+               return -EBUSY;
+       }
+
+       addr = ioremap(res->start, resource_size(res));
+       if (!addr) {
+               pr_err("%s: ERROR: memory mapping failed\n", __func__);
+               ret = -ENOMEM;
+               goto out_release_region;
+       }
+
+       ndev = alloc_etherdev(sizeof(struct stmmac_priv));
+       if (!ndev) {
+               pr_err("%s: ERROR: allocating the device\n", __func__);
+               ret = -ENOMEM;
+               goto out_unmap;
+       }
+
+       SET_NETDEV_DEV(ndev, &pdev->dev);
+
+       /* Get the MAC information */
+       ndev->irq = platform_get_irq_byname(pdev, "macirq");
+       if (ndev->irq == -ENXIO) {
+               pr_err("%s: ERROR: MAC IRQ configuration "
+                      "information not found\n", __func__);
+               ret = -ENXIO;
+               goto out_free_ndev;
+       }
+
+       priv = netdev_priv(ndev);
+       priv->device = &(pdev->dev);
+       priv->dev = ndev;
+       plat_dat = pdev->dev.platform_data;
+
+       priv->plat = plat_dat;
+
+       priv->ioaddr = addr;
+
+       /* PMT module is not integrated in all the MAC devices. */
+       if (plat_dat->pmt) {
+               pr_info("\tPMT module supported\n");
+               device_set_wakeup_capable(&pdev->dev, 1);
+       }
+
+       platform_set_drvdata(pdev, ndev);
+
+       /* Set the I/O base addr */
+       ndev->base_addr = (unsigned long)addr;
+
+       /* Custom initialisation */
+       if (priv->plat->init) {
+               ret = priv->plat->init(pdev);
+               if (unlikely(ret))
+                       goto out_free_ndev;
+       }
+
+       /* MAC HW revice detection */
+       ret = stmmac_mac_device_setup(ndev);
+       if (ret < 0)
+               goto out_plat_exit;
+
+       /* Network Device Registration */
+       ret = stmmac_probe(ndev);
+       if (ret < 0)
+               goto out_plat_exit;
+
+       /* Override with kernel parameters if supplied XXX CRS XXX
+        * this needs to have multiple instances */
+       if ((phyaddr >= 0) && (phyaddr <= 31))
+               priv->plat->phy_addr = phyaddr;
+
+       pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
+              "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
+              pdev->id, ndev->irq, addr);
+
+       /* MDIO bus Registration */
+       pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
+       ret = stmmac_mdio_register(ndev);
+       if (ret < 0)
+               goto out_unregister;
+       pr_debug("registered!\n");
+       return 0;
+
+out_unregister:
+       unregister_netdev(ndev);
+out_plat_exit:
+       if (priv->plat->exit)
+               priv->plat->exit(pdev);
+out_free_ndev:
+       free_netdev(ndev);
+       platform_set_drvdata(pdev, NULL);
+out_unmap:
+       iounmap(addr);
+out_release_region:
+       release_mem_region(res->start, resource_size(res));
+
+       return ret;
+}
+
+/**
+ * stmmac_dvr_remove
+ * @pdev: platform device pointer
+ * Description: this function resets the TX/RX processes, disables the MAC RX/TX
+ * changes the link status, releases the DMA descriptor rings,
+ * unregisters the MDIO bus and unmaps the allocated memory.
+ */
+static int stmmac_dvr_remove(struct platform_device *pdev)
+{
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       struct resource *res;
+
+       pr_info("%s:\n\tremoving driver", __func__);
+
+       priv->hw->dma->stop_rx(priv->ioaddr);
+       priv->hw->dma->stop_tx(priv->ioaddr);
+
+       stmmac_disable_mac(priv->ioaddr);
+
+       netif_carrier_off(ndev);
+
+       stmmac_mdio_unregister(ndev);
+
+       if (priv->plat->exit)
+               priv->plat->exit(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+       unregister_netdev(ndev);
+
+       iounmap((void *)priv->ioaddr);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, resource_size(res));
+
+       free_netdev(ndev);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int stmmac_suspend(struct device *dev)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       int dis_ic = 0;
+
+       if (!ndev || !netif_running(ndev))
+               return 0;
+
+       spin_lock(&priv->lock);
+
+       netif_device_detach(ndev);
+       netif_stop_queue(ndev);
+       if (priv->phydev)
+               phy_stop(priv->phydev);
+
+#ifdef CONFIG_STMMAC_TIMER
+       priv->tm->timer_stop();
+       if (likely(priv->tm->enable))
+               dis_ic = 1;
+#endif
+       napi_disable(&priv->napi);
+
+       /* Stop TX/RX DMA */
+       priv->hw->dma->stop_tx(priv->ioaddr);
+       priv->hw->dma->stop_rx(priv->ioaddr);
+       /* Clear the Rx/Tx descriptors */
+       priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
+                                    dis_ic);
+       priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
+
+       /* Enable Power down mode by programming the PMT regs */
+       if (device_may_wakeup(priv->device))
+               priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
+       else
+               stmmac_disable_mac(priv->ioaddr);
+
+       spin_unlock(&priv->lock);
+       return 0;
+}
+
+static int stmmac_resume(struct device *dev)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct stmmac_priv *priv = netdev_priv(ndev);
+
+       if (!netif_running(ndev))
+               return 0;
+
+       spin_lock(&priv->lock);
+
+       /* Power Down bit, into the PM register, is cleared
+        * automatically as soon as a magic packet or a Wake-up frame
+        * is received. Anyway, it's better to manually clear
+        * this bit because it can generate problems while resuming
+        * from another devices (e.g. serial console). */
+       if (device_may_wakeup(priv->device))
+               priv->hw->mac->pmt(priv->ioaddr, 0);
+
+       netif_device_attach(ndev);
+
+       /* Enable the MAC and DMA */
+       stmmac_enable_mac(priv->ioaddr);
+       priv->hw->dma->start_tx(priv->ioaddr);
+       priv->hw->dma->start_rx(priv->ioaddr);
+
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_start(tmrate);
+#endif
+       napi_enable(&priv->napi);
+
+       if (priv->phydev)
+               phy_start(priv->phydev);
+
+       netif_start_queue(ndev);
+
+       spin_unlock(&priv->lock);
+       return 0;
+}
+
+static int stmmac_freeze(struct device *dev)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+
+       if (!ndev || !netif_running(ndev))
+               return 0;
+
+       return stmmac_release(ndev);
+}
+
+static int stmmac_restore(struct device *dev)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+
+       if (!ndev || !netif_running(ndev))
+               return 0;
+
+       return stmmac_open(ndev);
+}
+
+static const struct dev_pm_ops stmmac_pm_ops = {
+       .suspend = stmmac_suspend,
+       .resume = stmmac_resume,
+       .freeze = stmmac_freeze,
+       .thaw = stmmac_restore,
+       .restore = stmmac_restore,
+};
+#else
+static const struct dev_pm_ops stmmac_pm_ops;
+#endif /* CONFIG_PM */
+
+static struct platform_driver stmmac_driver = {
+       .probe = stmmac_dvr_probe,
+       .remove = stmmac_dvr_remove,
+       .driver = {
+               .name = STMMAC_RESOURCE_NAME,
+               .owner = THIS_MODULE,
+               .pm = &stmmac_pm_ops,
+       },
+};
+
+/**
+ * stmmac_init_module - Entry point for the driver
+ * Description: This function is the entry point for the driver.
+ */
+static int __init stmmac_init_module(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&stmmac_driver);
+       return ret;
+}
+
+/**
+ * stmmac_cleanup_module - Cleanup routine for the driver
+ * Description: This function is the cleanup routine for the driver.
+ */
+static void __exit stmmac_cleanup_module(void)
+{
+       platform_driver_unregister(&stmmac_driver);
+}
+
+#ifndef MODULE
+static int __init stmmac_cmdline_opt(char *str)
+{
+       char *opt;
+
+       if (!str || !*str)
+               return -EINVAL;
+       while ((opt = strsep(&str, ",")) != NULL) {
+               if (!strncmp(opt, "debug:", 6)) {
+                       if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug))
+                               goto err;
+               } else if (!strncmp(opt, "phyaddr:", 8)) {
+                       if (strict_strtoul(opt + 8, 0,
+                                          (unsigned long *)&phyaddr))
+                               goto err;
+               } else if (!strncmp(opt, "dma_txsize:", 11)) {
+                       if (strict_strtoul(opt + 11, 0,
+                                          (unsigned long *)&dma_txsize))
+                               goto err;
+               } else if (!strncmp(opt, "dma_rxsize:", 11)) {
+                       if (strict_strtoul(opt + 11, 0,
+                                          (unsigned long *)&dma_rxsize))
+                               goto err;
+               } else if (!strncmp(opt, "buf_sz:", 7)) {
+                       if (strict_strtoul(opt + 7, 0,
+                                          (unsigned long *)&buf_sz))
+                               goto err;
+               } else if (!strncmp(opt, "tc:", 3)) {
+                       if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc))
+                               goto err;
+               } else if (!strncmp(opt, "watchdog:", 9)) {
+                       if (strict_strtoul(opt + 9, 0,
+                                          (unsigned long *)&watchdog))
+                               goto err;
+               } else if (!strncmp(opt, "flow_ctrl:", 10)) {
+                       if (strict_strtoul(opt + 10, 0,
+                                          (unsigned long *)&flow_ctrl))
+                               goto err;
+               } else if (!strncmp(opt, "pause:", 6)) {
+                       if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause))
+                               goto err;
+#ifdef CONFIG_STMMAC_TIMER
+               } else if (!strncmp(opt, "tmrate:", 7)) {
+                       if (strict_strtoul(opt + 7, 0,
+                                          (unsigned long *)&tmrate))
+                               goto err;
+#endif
+               }
+       }
+       return 0;
+
+err:
+       pr_err("%s: ERROR broken module parameter conversion", __func__);
+       return -EINVAL;
+}
+
+__setup("stmmaceth=", stmmac_cmdline_opt);
+#endif
+
+module_init(stmmac_init_module);
+module_exit(stmmac_cleanup_module);
+
+MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
+MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
new file mode 100644 (file)
index 0000000..9c3b9d5
--- /dev/null
@@ -0,0 +1,247 @@
+/*******************************************************************************
+  STMMAC Ethernet Driver -- MDIO bus implementation
+  Provides Bus interface for MII registers
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Carl Shaw <carl.shaw@st.com>
+  Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+
+#include "stmmac.h"
+
+#define MII_BUSY 0x00000001
+#define MII_WRITE 0x00000002
+
+/**
+ * stmmac_mdio_read
+ * @bus: points to the mii_bus structure
+ * @phyaddr: MII addr reg bits 15-11
+ * @phyreg: MII addr reg bits 10-6
+ * Description: it reads data from the MII register from within the phy device.
+ * For the 7111 GMAC, we must set the bit 0 in the MII address register while
+ * accessing the PHY registers.
+ * Fortunately, it seems this has no drawback for the 7109 MAC.
+ */
+static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+{
+       struct net_device *ndev = bus->priv;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned int mii_address = priv->hw->mii.addr;
+       unsigned int mii_data = priv->hw->mii.data;
+
+       int data;
+       u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
+                       ((phyreg << 6) & (0x000007C0)));
+       regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
+
+       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+       writel(regValue, priv->ioaddr + mii_address);
+       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+
+       /* Read the data from the MII data register */
+       data = (int)readl(priv->ioaddr + mii_data);
+
+       return data;
+}
+
+/**
+ * stmmac_mdio_write
+ * @bus: points to the mii_bus structure
+ * @phyaddr: MII addr reg bits 15-11
+ * @phyreg: MII addr reg bits 10-6
+ * @phydata: phy data
+ * Description: it writes the data into the MII register from within the device.
+ */
+static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
+                            u16 phydata)
+{
+       struct net_device *ndev = bus->priv;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned int mii_address = priv->hw->mii.addr;
+       unsigned int mii_data = priv->hw->mii.data;
+
+       u16 value =
+           (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
+           | MII_WRITE;
+
+       value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
+
+
+       /* Wait until any existing MII operation is complete */
+       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+
+       /* Set the MII address register to write */
+       writel(phydata, priv->ioaddr + mii_data);
+       writel(value, priv->ioaddr + mii_address);
+
+       /* Wait until any existing MII operation is complete */
+       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
+
+       return 0;
+}
+
+/**
+ * stmmac_mdio_reset
+ * @bus: points to the mii_bus structure
+ * Description: reset the MII bus
+ */
+static int stmmac_mdio_reset(struct mii_bus *bus)
+{
+       struct net_device *ndev = bus->priv;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       unsigned int mii_address = priv->hw->mii.addr;
+
+       if (priv->plat->mdio_bus_data->phy_reset) {
+               pr_debug("stmmac_mdio_reset: calling phy_reset\n");
+               priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv);
+       }
+
+       /* This is a workaround for problems with the STE101P PHY.
+        * It doesn't complete its reset until at least one clock cycle
+        * on MDC, so perform a dummy mdio read.
+        */
+       writel(0, priv->ioaddr + mii_address);
+
+       return 0;
+}
+
+/**
+ * stmmac_mdio_register
+ * @ndev: net device structure
+ * Description: it registers the MII bus
+ */
+int stmmac_mdio_register(struct net_device *ndev)
+{
+       int err = 0;
+       struct mii_bus *new_bus;
+       int *irqlist;
+       struct stmmac_priv *priv = netdev_priv(ndev);
+       struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
+       int addr, found;
+
+       if (!mdio_bus_data)
+               return 0;
+
+       new_bus = mdiobus_alloc();
+       if (new_bus == NULL)
+               return -ENOMEM;
+
+       if (mdio_bus_data->irqs)
+               irqlist = mdio_bus_data->irqs;
+       else
+               irqlist = priv->mii_irq;
+
+       new_bus->name = "STMMAC MII Bus";
+       new_bus->read = &stmmac_mdio_read;
+       new_bus->write = &stmmac_mdio_write;
+       new_bus->reset = &stmmac_mdio_reset;
+       snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id);
+       new_bus->priv = ndev;
+       new_bus->irq = irqlist;
+       new_bus->phy_mask = mdio_bus_data->phy_mask;
+       new_bus->parent = priv->device;
+       err = mdiobus_register(new_bus);
+       if (err != 0) {
+               pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
+               goto bus_register_fail;
+       }
+
+       priv->mii = new_bus;
+
+       found = 0;
+       for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+               struct phy_device *phydev = new_bus->phy_map[addr];
+               if (phydev) {
+                       int act = 0;
+                       char irq_num[4];
+                       char *irq_str;
+
+                       /*
+                        * If an IRQ was provided to be assigned after
+                        * the bus probe, do it here.
+                        */
+                       if ((mdio_bus_data->irqs == NULL) &&
+                           (mdio_bus_data->probed_phy_irq > 0)) {
+                               irqlist[addr] = mdio_bus_data->probed_phy_irq;
+                               phydev->irq = mdio_bus_data->probed_phy_irq;
+                       }
+
+                       /*
+                        * If we're  going to bind the MAC to this PHY bus,
+                        * and no PHY number was provided to the MAC,
+                        * use the one probed here.
+                        */
+                       if ((priv->plat->bus_id == mdio_bus_data->bus_id) &&
+                           (priv->plat->phy_addr == -1))
+                               priv->plat->phy_addr = addr;
+
+                       act = (priv->plat->bus_id == mdio_bus_data->bus_id) &&
+                               (priv->plat->phy_addr == addr);
+                       switch (phydev->irq) {
+                       case PHY_POLL:
+                               irq_str = "POLL";
+                               break;
+                       case PHY_IGNORE_INTERRUPT:
+                               irq_str = "IGNORE";
+                               break;
+                       default:
+                               sprintf(irq_num, "%d", phydev->irq);
+                               irq_str = irq_num;
+                               break;
+                       }
+                       pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
+                               ndev->name, phydev->phy_id, addr,
+                               irq_str, dev_name(&phydev->dev),
+                               act ? " active" : "");
+                       found = 1;
+               }
+       }
+
+       if (!found)
+               pr_warning("%s: No PHY found\n", ndev->name);
+
+       return 0;
+
+bus_register_fail:
+       mdiobus_free(new_bus);
+       return err;
+}
+
+/**
+ * stmmac_mdio_unregister
+ * @ndev: net device structure
+ * Description: it unregisters the MII bus
+ */
+int stmmac_mdio_unregister(struct net_device *ndev)
+{
+       struct stmmac_priv *priv = netdev_priv(ndev);
+
+       mdiobus_unregister(priv->mii);
+       priv->mii->priv = NULL;
+       mdiobus_free(priv->mii);
+       priv->mii = NULL;
+
+       return 0;
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
new file mode 100644 (file)
index 0000000..2a0e1ab
--- /dev/null
@@ -0,0 +1,134 @@
+/*******************************************************************************
+  STMMAC external timer support.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/etherdevice.h>
+#include "stmmac_timer.h"
+
+static void stmmac_timer_handler(void *data)
+{
+       struct net_device *dev = (struct net_device *)data;
+
+       stmmac_schedule(dev);
+}
+
+#define STMMAC_TIMER_MSG(timer, freq) \
+printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
+
+#if defined(CONFIG_STMMAC_RTC_TIMER)
+#include <linux/rtc.h>
+static struct rtc_device *stmmac_rtc;
+static rtc_task_t stmmac_task;
+
+static void stmmac_rtc_start(unsigned int new_freq)
+{
+       rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
+       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
+}
+
+static void stmmac_rtc_stop(void)
+{
+       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+}
+
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
+{
+       stmmac_task.private_data = dev;
+       stmmac_task.func = stmmac_timer_handler;
+
+       stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+       if (stmmac_rtc == NULL) {
+               pr_err("open rtc device failed\n");
+               return -ENODEV;
+       }
+
+       rtc_irq_register(stmmac_rtc, &stmmac_task);
+
+       /* Periodic mode is not supported */
+       if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
+               pr_err("set periodic failed\n");
+               rtc_irq_unregister(stmmac_rtc, &stmmac_task);
+               rtc_class_close(stmmac_rtc);
+               return -1;
+       }
+
+       STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
+
+       tm->timer_start = stmmac_rtc_start;
+       tm->timer_stop = stmmac_rtc_stop;
+
+       return 0;
+}
+
+int stmmac_close_ext_timer(void)
+{
+       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+       rtc_irq_unregister(stmmac_rtc, &stmmac_task);
+       rtc_class_close(stmmac_rtc);
+       return 0;
+}
+
+#elif defined(CONFIG_STMMAC_TMU_TIMER)
+#include <linux/clk.h>
+#define TMU_CHANNEL "tmu2_clk"
+static struct clk *timer_clock;
+
+static void stmmac_tmu_start(unsigned int new_freq)
+{
+       clk_set_rate(timer_clock, new_freq);
+       clk_enable(timer_clock);
+}
+
+static void stmmac_tmu_stop(void)
+{
+       clk_disable(timer_clock);
+}
+
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
+{
+       timer_clock = clk_get(NULL, TMU_CHANNEL);
+
+       if (timer_clock == NULL)
+               return -1;
+
+       if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
+               timer_clock = NULL;
+               return -1;
+       }
+
+       STMMAC_TIMER_MSG("TMU2", tm->freq);
+       tm->timer_start = stmmac_tmu_start;
+       tm->timer_stop = stmmac_tmu_stop;
+
+       return 0;
+}
+
+int stmmac_close_ext_timer(void)
+{
+       clk_disable(timer_clock);
+       tmu2_unregister_user();
+       clk_put(timer_clock);
+       return 0;
+}
+#endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h
new file mode 100644 (file)
index 0000000..6863590
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************
+  STMMAC external timer Header File.
+
+  Copyright (C) 2007-2009  STMicroelectronics Ltd
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+*******************************************************************************/
+
+struct stmmac_timer {
+       void (*timer_start) (unsigned int new_freq);
+       void (*timer_stop) (void);
+       unsigned int freq;
+       unsigned int enable;
+};
+
+/* Open the HW timer device and return 0 in case of success */
+int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
+/* Stop the timer and release it */
+int stmmac_close_ext_timer(void);
+/* Function used for scheduling task within the stmmac */
+void stmmac_schedule(struct net_device *dev);
+
+#if defined(CONFIG_STMMAC_TMU_TIMER)
+extern int tmu2_register_user(void *fnt, void *data);
+extern void tmu2_unregister_user(void);
+#endif
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
deleted file mode 100644 (file)
index 7df7df4..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-config STMMAC_ETH
-       tristate "STMicroelectronics 10/100/1000 Ethernet driver"
-       select MII
-       select PHYLIB
-       select CRC32
-       depends on NETDEVICES && HAS_IOMEM
-       help
-         This is the driver for the Ethernet IPs are built around a
-         Synopsys IP Core and only tested on the STMicroelectronics
-         platforms.
-
-if STMMAC_ETH
-
-config STMMAC_DA
-       bool "STMMAC DMA arbitration scheme"
-       default n
-       help
-         Selecting this option, rx has priority over Tx (only for Giga
-         Ethernet device).
-         By default, the DMA arbitration scheme is based on Round-robin
-         (rx:tx priority is 1:1).
-
-config STMMAC_DUAL_MAC
-       bool "STMMAC: dual mac support (EXPERIMENTAL)"
-       default n
-        depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
-       help
-         Some ST SoCs (for example the stx7141 and stx7200c2) have two
-         Ethernet Controllers. This option turns on the second Ethernet
-         device on this kind of platforms.
-
-config STMMAC_TIMER
-       bool "STMMAC Timer optimisation"
-       default n
-       depends on RTC_HCTOSYS_DEVICE
-       help
-         Use an external timer for mitigating the number of network
-         interrupts. Currently, for SH architectures, it is possible
-         to use the TMU channel 2 and the SH-RTC device.
-
-choice
-        prompt "Select Timer device"
-        depends on STMMAC_TIMER
-
-config STMMAC_TMU_TIMER
-        bool "TMU channel 2"
-        depends on CPU_SH4
-       help
-
-config STMMAC_RTC_TIMER
-        bool "Real time clock"
-        depends on RTC_CLASS
-       help
-
-endchoice
-
-endif
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
deleted file mode 100644 (file)
index 9691733..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-obj-$(CONFIG_STMMAC_ETH) += stmmac.o
-stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
-stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o     \
-             dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o     \
-             dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
deleted file mode 100644 (file)
index 375ea19..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-/*******************************************************************************
-  STMMAC Common Header File
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/netdevice.h>
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define STMMAC_VLAN_TAG_USED
-#include <linux/if_vlan.h>
-#endif
-
-#include "descs.h"
-
-#undef CHIP_DEBUG_PRINT
-/* Turn-on extra printk debug for MAC core, dma and descriptors */
-/* #define CHIP_DEBUG_PRINT */
-
-#ifdef CHIP_DEBUG_PRINT
-#define CHIP_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define CHIP_DBG(fmt, args...)  do { } while (0)
-#endif
-
-#undef FRAME_FILTER_DEBUG
-/* #define FRAME_FILTER_DEBUG */
-
-struct stmmac_extra_stats {
-       /* Transmit errors */
-       unsigned long tx_underflow ____cacheline_aligned;
-       unsigned long tx_carrier;
-       unsigned long tx_losscarrier;
-       unsigned long tx_heartbeat;
-       unsigned long tx_deferred;
-       unsigned long tx_vlan;
-       unsigned long tx_jabber;
-       unsigned long tx_frame_flushed;
-       unsigned long tx_payload_error;
-       unsigned long tx_ip_header_error;
-       /* Receive errors */
-       unsigned long rx_desc;
-       unsigned long rx_partial;
-       unsigned long rx_runt;
-       unsigned long rx_toolong;
-       unsigned long rx_collision;
-       unsigned long rx_crc;
-       unsigned long rx_length;
-       unsigned long rx_mii;
-       unsigned long rx_multicast;
-       unsigned long rx_gmac_overflow;
-       unsigned long rx_watchdog;
-       unsigned long da_rx_filter_fail;
-       unsigned long sa_rx_filter_fail;
-       unsigned long rx_missed_cntr;
-       unsigned long rx_overflow_cntr;
-       unsigned long rx_vlan;
-       /* Tx/Rx IRQ errors */
-       unsigned long tx_undeflow_irq;
-       unsigned long tx_process_stopped_irq;
-       unsigned long tx_jabber_irq;
-       unsigned long rx_overflow_irq;
-       unsigned long rx_buf_unav_irq;
-       unsigned long rx_process_stopped_irq;
-       unsigned long rx_watchdog_irq;
-       unsigned long tx_early_irq;
-       unsigned long fatal_bus_error_irq;
-       /* Extra info */
-       unsigned long threshold;
-       unsigned long tx_pkt_n;
-       unsigned long rx_pkt_n;
-       unsigned long poll_n;
-       unsigned long sched_timer_n;
-       unsigned long normal_irq_n;
-};
-
-#define HASH_TABLE_SIZE 64
-#define PAUSE_TIME 0x200
-
-/* Flow Control defines */
-#define FLOW_OFF       0
-#define FLOW_RX                1
-#define FLOW_TX                2
-#define FLOW_AUTO      (FLOW_TX | FLOW_RX)
-
-#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
-
-enum rx_frame_status { /* IPC status */
-       good_frame = 0,
-       discard_frame = 1,
-       csum_none = 2,
-       llc_snap = 4,
-};
-
-enum tx_dma_irq_status {
-       tx_hard_error = 1,
-       tx_hard_error_bump_tc = 2,
-       handle_tx_rx = 3,
-};
-
-/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
-#define BUF_SIZE_16KiB 16384
-#define BUF_SIZE_8KiB 8192
-#define BUF_SIZE_4KiB 4096
-#define BUF_SIZE_2KiB 2048
-
-/* Power Down and WOL */
-#define PMT_NOT_SUPPORTED 0
-#define PMT_SUPPORTED 1
-
-/* Common MAC defines */
-#define MAC_CTRL_REG           0x00000000      /* MAC Control */
-#define MAC_ENABLE_TX          0x00000008      /* Transmitter Enable */
-#define MAC_RNABLE_RX          0x00000004      /* Receiver Enable */
-
-/* MAC Management Counters register */
-#define MMC_CONTROL            0x00000100      /* MMC Control */
-#define MMC_HIGH_INTR          0x00000104      /* MMC High Interrupt */
-#define MMC_LOW_INTR           0x00000108      /* MMC Low Interrupt */
-#define MMC_HIGH_INTR_MASK     0x0000010c      /* MMC High Interrupt Mask */
-#define MMC_LOW_INTR_MASK      0x00000110      /* MMC Low Interrupt Mask */
-
-#define MMC_CONTROL_MAX_FRM_MASK       0x0003ff8       /* Maximum Frame Size */
-#define MMC_CONTROL_MAX_FRM_SHIFT      3
-#define MMC_CONTROL_MAX_FRAME          0x7FF
-
-struct stmmac_desc_ops {
-       /* DMA RX descriptor ring initialization */
-       void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
-                             int disable_rx_ic);
-       /* DMA TX descriptor ring initialization */
-       void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
-
-       /* Invoked by the xmit function to prepare the tx descriptor */
-       void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
-                                int csum_flag);
-       /* Set/get the owner of the descriptor */
-       void (*set_tx_owner) (struct dma_desc *p);
-       int (*get_tx_owner) (struct dma_desc *p);
-       /* Invoked by the xmit function to close the tx descriptor */
-       void (*close_tx_desc) (struct dma_desc *p);
-       /* Clean the tx descriptor as soon as the tx irq is received */
-       void (*release_tx_desc) (struct dma_desc *p);
-       /* Clear interrupt on tx frame completion. When this bit is
-        * set an interrupt happens as soon as the frame is transmitted */
-       void (*clear_tx_ic) (struct dma_desc *p);
-       /* Last tx segment reports the transmit status */
-       int (*get_tx_ls) (struct dma_desc *p);
-       /* Return the transmit status looking at the TDES1 */
-       int (*tx_status) (void *data, struct stmmac_extra_stats *x,
-                         struct dma_desc *p, void __iomem *ioaddr);
-       /* Get the buffer size from the descriptor */
-       int (*get_tx_len) (struct dma_desc *p);
-       /* Handle extra events on specific interrupts hw dependent */
-       int (*get_rx_owner) (struct dma_desc *p);
-       void (*set_rx_owner) (struct dma_desc *p);
-       /* Get the receive frame size */
-       int (*get_rx_frame_len) (struct dma_desc *p);
-       /* Return the reception status looking at the RDES1 */
-       int (*rx_status) (void *data, struct stmmac_extra_stats *x,
-                         struct dma_desc *p);
-};
-
-struct stmmac_dma_ops {
-       /* DMA core initialization */
-       int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
-       /* Dump DMA registers */
-       void (*dump_regs) (void __iomem *ioaddr);
-       /* Set tx/rx threshold in the csr6 register
-        * An invalid value enables the store-and-forward mode */
-       void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode);
-       /* To track extra statistic (if supported) */
-       void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
-                                  void __iomem *ioaddr);
-       void (*enable_dma_transmission) (void __iomem *ioaddr);
-       void (*enable_dma_irq) (void __iomem *ioaddr);
-       void (*disable_dma_irq) (void __iomem *ioaddr);
-       void (*start_tx) (void __iomem *ioaddr);
-       void (*stop_tx) (void __iomem *ioaddr);
-       void (*start_rx) (void __iomem *ioaddr);
-       void (*stop_rx) (void __iomem *ioaddr);
-       int (*dma_interrupt) (void __iomem *ioaddr,
-                             struct stmmac_extra_stats *x);
-};
-
-struct stmmac_ops {
-       /* MAC core initialization */
-       void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
-       /* Support checksum offload engine */
-       int  (*rx_coe) (void __iomem *ioaddr);
-       /* Dump MAC registers */
-       void (*dump_regs) (void __iomem *ioaddr);
-       /* Handle extra events on specific interrupts hw dependent */
-       void (*host_irq_status) (void __iomem *ioaddr);
-       /* Multicast filter setting */
-       void (*set_filter) (struct net_device *dev);
-       /* Flow control setting */
-       void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
-                          unsigned int fc, unsigned int pause_time);
-       /* Set power management mode (e.g. magic frame) */
-       void (*pmt) (void __iomem *ioaddr, unsigned long mode);
-       /* Set/Get Unicast MAC addresses */
-       void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
-                              unsigned int reg_n);
-       void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
-                              unsigned int reg_n);
-};
-
-struct mac_link {
-       int port;
-       int duplex;
-       int speed;
-};
-
-struct mii_regs {
-       unsigned int addr;      /* MII Address */
-       unsigned int data;      /* MII Data */
-};
-
-struct mac_device_info {
-       const struct stmmac_ops         *mac;
-       const struct stmmac_desc_ops    *desc;
-       const struct stmmac_dma_ops     *dma;
-       struct mii_regs mii;    /* MII register Addresses */
-       struct mac_link link;
-};
-
-struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
-struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
-
-extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
-                               unsigned int high, unsigned int low);
-extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
-                               unsigned int high, unsigned int low);
-extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
diff --git a/drivers/net/stmmac/descs.h b/drivers/net/stmmac/descs.h
deleted file mode 100644 (file)
index 63a03e2..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*******************************************************************************
-  Header File to describe the DMA descriptors.
-  Enhanced descriptors have been in case of DWMAC1000 Cores.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-struct dma_desc {
-       /* Receive descriptor */
-       union {
-               struct {
-                       /* RDES0 */
-                       u32 reserved1:1;
-                       u32 crc_error:1;
-                       u32 dribbling:1;
-                       u32 mii_error:1;
-                       u32 receive_watchdog:1;
-                       u32 frame_type:1;
-                       u32 collision:1;
-                       u32 frame_too_long:1;
-                       u32 last_descriptor:1;
-                       u32 first_descriptor:1;
-                       u32 multicast_frame:1;
-                       u32 run_frame:1;
-                       u32 length_error:1;
-                       u32 partial_frame_error:1;
-                       u32 descriptor_error:1;
-                       u32 error_summary:1;
-                       u32 frame_length:14;
-                       u32 filtering_fail:1;
-                       u32 own:1;
-                       /* RDES1 */
-                       u32 buffer1_size:11;
-                       u32 buffer2_size:11;
-                       u32 reserved2:2;
-                       u32 second_address_chained:1;
-                       u32 end_ring:1;
-                       u32 reserved3:5;
-                       u32 disable_ic:1;
-               } rx;
-               struct {
-                       /* RDES0 */
-                       u32 payload_csum_error:1;
-                       u32 crc_error:1;
-                       u32 dribbling:1;
-                       u32 error_gmii:1;
-                       u32 receive_watchdog:1;
-                       u32 frame_type:1;
-                       u32 late_collision:1;
-                       u32 ipc_csum_error:1;
-                       u32 last_descriptor:1;
-                       u32 first_descriptor:1;
-                       u32 vlan_tag:1;
-                       u32 overflow_error:1;
-                       u32 length_error:1;
-                       u32 sa_filter_fail:1;
-                       u32 descriptor_error:1;
-                       u32 error_summary:1;
-                       u32 frame_length:14;
-                       u32 da_filter_fail:1;
-                       u32 own:1;
-                       /* RDES1 */
-                       u32 buffer1_size:13;
-                       u32 reserved1:1;
-                       u32 second_address_chained:1;
-                       u32 end_ring:1;
-                       u32 buffer2_size:13;
-                       u32 reserved2:2;
-                       u32 disable_ic:1;
-               } erx;          /* -- enhanced -- */
-
-               /* Transmit descriptor */
-               struct {
-                       /* TDES0 */
-                       u32 deferred:1;
-                       u32 underflow_error:1;
-                       u32 excessive_deferral:1;
-                       u32 collision_count:4;
-                       u32 heartbeat_fail:1;
-                       u32 excessive_collisions:1;
-                       u32 late_collision:1;
-                       u32 no_carrier:1;
-                       u32 loss_carrier:1;
-                       u32 reserved1:3;
-                       u32 error_summary:1;
-                       u32 reserved2:15;
-                       u32 own:1;
-                       /* TDES1 */
-                       u32 buffer1_size:11;
-                       u32 buffer2_size:11;
-                       u32 reserved3:1;
-                       u32 disable_padding:1;
-                       u32 second_address_chained:1;
-                       u32 end_ring:1;
-                       u32 crc_disable:1;
-                       u32 reserved4:2;
-                       u32 first_segment:1;
-                       u32 last_segment:1;
-                       u32 interrupt:1;
-               } tx;
-               struct {
-                       /* TDES0 */
-                       u32 deferred:1;
-                       u32 underflow_error:1;
-                       u32 excessive_deferral:1;
-                       u32 collision_count:4;
-                       u32 vlan_frame:1;
-                       u32 excessive_collisions:1;
-                       u32 late_collision:1;
-                       u32 no_carrier:1;
-                       u32 loss_carrier:1;
-                       u32 payload_error:1;
-                       u32 frame_flushed:1;
-                       u32 jabber_timeout:1;
-                       u32 error_summary:1;
-                       u32 ip_header_error:1;
-                       u32 time_stamp_status:1;
-                       u32 reserved1:2;
-                       u32 second_address_chained:1;
-                       u32 end_ring:1;
-                       u32 checksum_insertion:2;
-                       u32 reserved2:1;
-                       u32 time_stamp_enable:1;
-                       u32 disable_padding:1;
-                       u32 crc_disable:1;
-                       u32 first_segment:1;
-                       u32 last_segment:1;
-                       u32 interrupt:1;
-                       u32 own:1;
-                       /* TDES1 */
-                       u32 buffer1_size:13;
-                       u32 reserved3:3;
-                       u32 buffer2_size:13;
-                       u32 reserved4:3;
-               } etx;          /* -- enhanced -- */
-       } des01;
-       unsigned int des2;
-       unsigned int des3;
-};
-
-/* Transmit checksum insertion control */
-enum tdes_csum_insertion {
-       cic_disabled = 0,       /* Checksum Insertion Control */
-       cic_only_ip = 1,        /* Only IP header */
-       cic_no_pseudoheader = 2,        /* IP header but pseudoheader
-                                        * is not calculated */
-       cic_full = 3,           /* IP header and pseudoheader */
-};
diff --git a/drivers/net/stmmac/dwmac100.h b/drivers/net/stmmac/dwmac100.h
deleted file mode 100644 (file)
index 7c6d857..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*******************************************************************************
-  MAC 10/100 Header File
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/phy.h>
-#include "common.h"
-
-/*----------------------------------------------------------------------------
- *                             MAC BLOCK defines
- *---------------------------------------------------------------------------*/
-/* MAC CSR offset */
-#define MAC_CONTROL    0x00000000      /* MAC Control */
-#define MAC_ADDR_HIGH  0x00000004      /* MAC Address High */
-#define MAC_ADDR_LOW   0x00000008      /* MAC Address Low */
-#define MAC_HASH_HIGH  0x0000000c      /* Multicast Hash Table High */
-#define MAC_HASH_LOW   0x00000010      /* Multicast Hash Table Low */
-#define MAC_MII_ADDR   0x00000014      /* MII Address */
-#define MAC_MII_DATA   0x00000018      /* MII Data */
-#define MAC_FLOW_CTRL  0x0000001c      /* Flow Control */
-#define MAC_VLAN1      0x00000020      /* VLAN1 Tag */
-#define MAC_VLAN2      0x00000024      /* VLAN2 Tag */
-
-/* MAC CTRL defines */
-#define MAC_CONTROL_RA 0x80000000      /* Receive All Mode */
-#define MAC_CONTROL_BLE        0x40000000      /* Endian Mode */
-#define MAC_CONTROL_HBD        0x10000000      /* Heartbeat Disable */
-#define MAC_CONTROL_PS 0x08000000      /* Port Select */
-#define MAC_CONTROL_DRO        0x00800000      /* Disable Receive Own */
-#define MAC_CONTROL_EXT_LOOPBACK 0x00400000    /* Reserved (ext loopback?) */
-#define MAC_CONTROL_OM 0x00200000      /* Loopback Operating Mode */
-#define MAC_CONTROL_F  0x00100000      /* Full Duplex Mode */
-#define MAC_CONTROL_PM 0x00080000      /* Pass All Multicast */
-#define MAC_CONTROL_PR 0x00040000      /* Promiscuous Mode */
-#define MAC_CONTROL_IF 0x00020000      /* Inverse Filtering */
-#define MAC_CONTROL_PB 0x00010000      /* Pass Bad Frames */
-#define MAC_CONTROL_HO 0x00008000      /* Hash Only Filtering Mode */
-#define MAC_CONTROL_HP 0x00002000      /* Hash/Perfect Filtering Mode */
-#define MAC_CONTROL_LCC        0x00001000      /* Late Collision Control */
-#define MAC_CONTROL_DBF        0x00000800      /* Disable Broadcast Frames */
-#define MAC_CONTROL_DRTY       0x00000400      /* Disable Retry */
-#define MAC_CONTROL_ASTP       0x00000100      /* Automatic Pad Stripping */
-#define MAC_CONTROL_BOLMT_10   0x00000000      /* Back Off Limit 10 */
-#define MAC_CONTROL_BOLMT_8    0x00000040      /* Back Off Limit 8 */
-#define MAC_CONTROL_BOLMT_4    0x00000080      /* Back Off Limit 4 */
-#define MAC_CONTROL_BOLMT_1    0x000000c0      /* Back Off Limit 1 */
-#define MAC_CONTROL_DC         0x00000020      /* Deferral Check */
-#define MAC_CONTROL_TE         0x00000008      /* Transmitter Enable */
-#define MAC_CONTROL_RE         0x00000004      /* Receiver Enable */
-
-#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
-
-/* MAC FLOW CTRL defines */
-#define MAC_FLOW_CTRL_PT_MASK  0xffff0000      /* Pause Time Mask */
-#define MAC_FLOW_CTRL_PT_SHIFT 16
-#define MAC_FLOW_CTRL_PASS     0x00000004      /* Pass Control Frames */
-#define MAC_FLOW_CTRL_ENABLE   0x00000002      /* Flow Control Enable */
-#define MAC_FLOW_CTRL_PAUSE    0x00000001      /* Flow Control Busy ... */
-
-/* MII ADDR  defines */
-#define MAC_MII_ADDR_WRITE     0x00000002      /* MII Write */
-#define MAC_MII_ADDR_BUSY      0x00000001      /* MII Busy */
-
-/*----------------------------------------------------------------------------
- *                             DMA BLOCK defines
- *---------------------------------------------------------------------------*/
-
-/* DMA Bus Mode register defines */
-#define DMA_BUS_MODE_DBO       0x00100000      /* Descriptor Byte Ordering */
-#define DMA_BUS_MODE_BLE       0x00000080      /* Big Endian/Little Endian */
-#define DMA_BUS_MODE_PBL_MASK  0x00003f00      /* Programmable Burst Len */
-#define DMA_BUS_MODE_PBL_SHIFT 8
-#define DMA_BUS_MODE_DSL_MASK  0x0000007c      /* Descriptor Skip Length */
-#define DMA_BUS_MODE_DSL_SHIFT 2       /*   (in DWORDS)      */
-#define DMA_BUS_MODE_BAR_BUS   0x00000002      /* Bar-Bus Arbitration */
-#define DMA_BUS_MODE_SFT_RESET 0x00000001      /* Software Reset */
-#define DMA_BUS_MODE_DEFAULT   0x00000000
-
-/* DMA Control register defines */
-#define DMA_CONTROL_SF         0x00200000      /* Store And Forward */
-
-/* Transmit Threshold Control */
-enum ttc_control {
-       DMA_CONTROL_TTC_DEFAULT = 0x00000000,   /* Threshold is 32 DWORDS */
-       DMA_CONTROL_TTC_64 = 0x00004000,        /* Threshold is 64 DWORDS */
-       DMA_CONTROL_TTC_128 = 0x00008000,       /* Threshold is 128 DWORDS */
-       DMA_CONTROL_TTC_256 = 0x0000c000,       /* Threshold is 256 DWORDS */
-       DMA_CONTROL_TTC_18 = 0x00400000,        /* Threshold is 18 DWORDS */
-       DMA_CONTROL_TTC_24 = 0x00404000,        /* Threshold is 24 DWORDS */
-       DMA_CONTROL_TTC_32 = 0x00408000,        /* Threshold is 32 DWORDS */
-       DMA_CONTROL_TTC_40 = 0x0040c000,        /* Threshold is 40 DWORDS */
-       DMA_CONTROL_SE = 0x00000008,    /* Stop On Empty */
-       DMA_CONTROL_OSF = 0x00000004,   /* Operate On 2nd Frame */
-};
-
-/* STMAC110 DMA Missed Frame Counter register defines */
-#define DMA_MISSED_FRAME_OVE   0x10000000      /* FIFO Overflow Overflow */
-#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000   /* Overflow Frame Counter */
-#define DMA_MISSED_FRAME_OVE_M 0x00010000      /* Missed Frame Overflow */
-#define DMA_MISSED_FRAME_M_CNTR        0x0000ffff      /* Missed Frame Couinter */
-
-extern const struct stmmac_dma_ops dwmac100_dma_ops;
diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h
deleted file mode 100644 (file)
index cfcef0e..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/*******************************************************************************
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/phy.h>
-#include "common.h"
-
-#define GMAC_CONTROL           0x00000000      /* Configuration */
-#define GMAC_FRAME_FILTER      0x00000004      /* Frame Filter */
-#define GMAC_HASH_HIGH         0x00000008      /* Multicast Hash Table High */
-#define GMAC_HASH_LOW          0x0000000c      /* Multicast Hash Table Low */
-#define GMAC_MII_ADDR          0x00000010      /* MII Address */
-#define GMAC_MII_DATA          0x00000014      /* MII Data */
-#define GMAC_FLOW_CTRL         0x00000018      /* Flow Control */
-#define GMAC_VLAN_TAG          0x0000001c      /* VLAN Tag */
-#define GMAC_VERSION           0x00000020      /* GMAC CORE Version */
-#define GMAC_WAKEUP_FILTER     0x00000028      /* Wake-up Frame Filter */
-
-#define GMAC_INT_STATUS                0x00000038      /* interrupt status register */
-enum dwmac1000_irq_status {
-       time_stamp_irq = 0x0200,
-       mmc_rx_csum_offload_irq = 0x0080,
-       mmc_tx_irq = 0x0040,
-       mmc_rx_irq = 0x0020,
-       mmc_irq = 0x0010,
-       pmt_irq = 0x0008,
-       pcs_ane_irq = 0x0004,
-       pcs_link_irq = 0x0002,
-       rgmii_irq = 0x0001,
-};
-#define GMAC_INT_MASK          0x0000003c      /* interrupt mask register */
-
-/* PMT Control and Status */
-#define GMAC_PMT               0x0000002c
-enum power_event {
-       pointer_reset = 0x80000000,
-       global_unicast = 0x00000200,
-       wake_up_rx_frame = 0x00000040,
-       magic_frame = 0x00000020,
-       wake_up_frame_en = 0x00000004,
-       magic_pkt_en = 0x00000002,
-       power_down = 0x00000001,
-};
-
-/* GMAC HW ADDR regs */
-#define GMAC_ADDR_HIGH(reg)            (0x00000040+(reg * 8))
-#define GMAC_ADDR_LOW(reg)             (0x00000044+(reg * 8))
-#define GMAC_MAX_UNICAST_ADDRESSES     16
-
-#define GMAC_AN_CTRL   0x000000c0      /* AN control */
-#define GMAC_AN_STATUS 0x000000c4      /* AN status */
-#define GMAC_ANE_ADV   0x000000c8      /* Auto-Neg. Advertisement */
-#define GMAC_ANE_LINK  0x000000cc      /* Auto-Neg. link partener ability */
-#define GMAC_ANE_EXP   0x000000d0      /* ANE expansion */
-#define GMAC_TBI       0x000000d4      /* TBI extend status */
-#define GMAC_GMII_STATUS 0x000000d8    /* S/R-GMII status */
-
-/* GMAC Configuration defines */
-#define GMAC_CONTROL_TC        0x01000000      /* Transmit Conf. in RGMII/SGMII */
-#define GMAC_CONTROL_WD        0x00800000      /* Disable Watchdog on receive */
-#define GMAC_CONTROL_JD        0x00400000      /* Jabber disable */
-#define GMAC_CONTROL_BE        0x00200000      /* Frame Burst Enable */
-#define GMAC_CONTROL_JE        0x00100000      /* Jumbo frame */
-enum inter_frame_gap {
-       GMAC_CONTROL_IFG_88 = 0x00040000,
-       GMAC_CONTROL_IFG_80 = 0x00020000,
-       GMAC_CONTROL_IFG_40 = 0x000e0000,
-};
-#define GMAC_CONTROL_DCRS      0x00010000 /* Disable carrier sense during tx */
-#define GMAC_CONTROL_PS                0x00008000 /* Port Select 0:GMI 1:MII */
-#define GMAC_CONTROL_FES       0x00004000 /* Speed 0:10 1:100 */
-#define GMAC_CONTROL_DO                0x00002000 /* Disable Rx Own */
-#define GMAC_CONTROL_LM                0x00001000 /* Loop-back mode */
-#define GMAC_CONTROL_DM                0x00000800 /* Duplex Mode */
-#define GMAC_CONTROL_IPC       0x00000400 /* Checksum Offload */
-#define GMAC_CONTROL_DR                0x00000200 /* Disable Retry */
-#define GMAC_CONTROL_LUD       0x00000100 /* Link up/down */
-#define GMAC_CONTROL_ACS       0x00000080 /* Automatic Pad/FCS Stripping */
-#define GMAC_CONTROL_DC                0x00000010 /* Deferral Check */
-#define GMAC_CONTROL_TE                0x00000008 /* Transmitter Enable */
-#define GMAC_CONTROL_RE                0x00000004 /* Receiver Enable */
-
-#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
-                       GMAC_CONTROL_JE | GMAC_CONTROL_BE)
-
-/* GMAC Frame Filter defines */
-#define GMAC_FRAME_FILTER_PR   0x00000001      /* Promiscuous Mode */
-#define GMAC_FRAME_FILTER_HUC  0x00000002      /* Hash Unicast */
-#define GMAC_FRAME_FILTER_HMC  0x00000004      /* Hash Multicast */
-#define GMAC_FRAME_FILTER_DAIF 0x00000008      /* DA Inverse Filtering */
-#define GMAC_FRAME_FILTER_PM   0x00000010      /* Pass all multicast */
-#define GMAC_FRAME_FILTER_DBF  0x00000020      /* Disable Broadcast frames */
-#define GMAC_FRAME_FILTER_SAIF 0x00000100      /* Inverse Filtering */
-#define GMAC_FRAME_FILTER_SAF  0x00000200      /* Source Address Filter */
-#define GMAC_FRAME_FILTER_HPF  0x00000400      /* Hash or perfect Filter */
-#define GMAC_FRAME_FILTER_RA   0x80000000      /* Receive all mode */
-/* GMII ADDR  defines */
-#define GMAC_MII_ADDR_WRITE    0x00000002      /* MII Write */
-#define GMAC_MII_ADDR_BUSY     0x00000001      /* MII Busy */
-/* GMAC FLOW CTRL defines */
-#define GMAC_FLOW_CTRL_PT_MASK 0xffff0000      /* Pause Time Mask */
-#define GMAC_FLOW_CTRL_PT_SHIFT        16
-#define GMAC_FLOW_CTRL_RFE     0x00000004      /* Rx Flow Control Enable */
-#define GMAC_FLOW_CTRL_TFE     0x00000002      /* Tx Flow Control Enable */
-#define GMAC_FLOW_CTRL_FCB_BPA 0x00000001      /* Flow Control Busy ... */
-
-/*--- DMA BLOCK defines ---*/
-/* DMA Bus Mode register defines */
-#define DMA_BUS_MODE_SFT_RESET 0x00000001      /* Software Reset */
-#define DMA_BUS_MODE_DA                0x00000002      /* Arbitration scheme */
-#define DMA_BUS_MODE_DSL_MASK  0x0000007c      /* Descriptor Skip Length */
-#define DMA_BUS_MODE_DSL_SHIFT 2       /*   (in DWORDS)      */
-/* Programmable burst length (passed thorugh platform)*/
-#define DMA_BUS_MODE_PBL_MASK  0x00003f00      /* Programmable Burst Len */
-#define DMA_BUS_MODE_PBL_SHIFT 8
-
-enum rx_tx_priority_ratio {
-       double_ratio = 0x00004000,      /*2:1 */
-       triple_ratio = 0x00008000,      /*3:1 */
-       quadruple_ratio = 0x0000c000,   /*4:1 */
-};
-
-#define DMA_BUS_MODE_FB                0x00010000      /* Fixed burst */
-#define DMA_BUS_MODE_RPBL_MASK 0x003e0000      /* Rx-Programmable Burst Len */
-#define DMA_BUS_MODE_RPBL_SHIFT        17
-#define DMA_BUS_MODE_USP       0x00800000
-#define DMA_BUS_MODE_4PBL      0x01000000
-#define DMA_BUS_MODE_AAL       0x02000000
-
-/* DMA CRS Control and Status Register Mapping */
-#define DMA_HOST_TX_DESC         0x00001048    /* Current Host Tx descriptor */
-#define DMA_HOST_RX_DESC         0x0000104c    /* Current Host Rx descriptor */
-/*  DMA Bus Mode register defines */
-#define DMA_BUS_PR_RATIO_MASK    0x0000c000    /* Rx/Tx priority ratio */
-#define DMA_BUS_PR_RATIO_SHIFT   14
-#define DMA_BUS_FB               0x00010000    /* Fixed Burst */
-
-/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
-#define DMA_CONTROL_DT         0x04000000 /* Disable Drop TCP/IP csum error */
-#define DMA_CONTROL_RSF                0x02000000 /* Receive Store and Forward */
-#define DMA_CONTROL_DFF                0x01000000 /* Disaable flushing */
-/* Threshold for Activating the FC */
-enum rfa {
-       act_full_minus_1 = 0x00800000,
-       act_full_minus_2 = 0x00800200,
-       act_full_minus_3 = 0x00800400,
-       act_full_minus_4 = 0x00800600,
-};
-/* Threshold for Deactivating the FC */
-enum rfd {
-       deac_full_minus_1 = 0x00400000,
-       deac_full_minus_2 = 0x00400800,
-       deac_full_minus_3 = 0x00401000,
-       deac_full_minus_4 = 0x00401800,
-};
-#define DMA_CONTROL_TSF                0x00200000 /* Transmit  Store and Forward */
-
-enum ttc_control {
-       DMA_CONTROL_TTC_64 = 0x00000000,
-       DMA_CONTROL_TTC_128 = 0x00004000,
-       DMA_CONTROL_TTC_192 = 0x00008000,
-       DMA_CONTROL_TTC_256 = 0x0000c000,
-       DMA_CONTROL_TTC_40 = 0x00010000,
-       DMA_CONTROL_TTC_32 = 0x00014000,
-       DMA_CONTROL_TTC_24 = 0x00018000,
-       DMA_CONTROL_TTC_16 = 0x0001c000,
-};
-#define DMA_CONTROL_TC_TX_MASK 0xfffe3fff
-
-#define DMA_CONTROL_EFC                0x00000100
-#define DMA_CONTROL_FEF                0x00000080
-#define DMA_CONTROL_FUF                0x00000040
-
-enum rtc_control {
-       DMA_CONTROL_RTC_64 = 0x00000000,
-       DMA_CONTROL_RTC_32 = 0x00000008,
-       DMA_CONTROL_RTC_96 = 0x00000010,
-       DMA_CONTROL_RTC_128 = 0x00000018,
-};
-#define DMA_CONTROL_TC_RX_MASK 0xffffffe7
-
-#define DMA_CONTROL_OSF        0x00000004      /* Operate on second frame */
-
-/* MMC registers offset */
-#define GMAC_MMC_CTRL      0x100
-#define GMAC_MMC_RX_INTR   0x104
-#define GMAC_MMC_TX_INTR   0x108
-#define GMAC_MMC_RX_CSUM_OFFLOAD   0x208
-
-extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
deleted file mode 100644 (file)
index 0f63b3c..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*******************************************************************************
-  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
-  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
-  developing this code.
-
-  This only implements the mac core functions for this chip.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/crc32.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include "dwmac1000.h"
-
-static void dwmac1000_core_init(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + GMAC_CONTROL);
-       value |= GMAC_CORE_INIT;
-       writel(value, ioaddr + GMAC_CONTROL);
-
-       /* STBus Bridge Configuration */
-       /*writel(0xc5608, ioaddr + 0x00007000);*/
-
-       /* Freeze MMC counters */
-       writel(0x8, ioaddr + GMAC_MMC_CTRL);
-       /* Mask GMAC interrupts */
-       writel(0x207, ioaddr + GMAC_INT_MASK);
-
-#ifdef STMMAC_VLAN_TAG_USED
-       /* Tag detection without filtering */
-       writel(0x0, ioaddr + GMAC_VLAN_TAG);
-#endif
-}
-
-static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + GMAC_CONTROL);
-
-       value |= GMAC_CONTROL_IPC;
-       writel(value, ioaddr + GMAC_CONTROL);
-
-       value = readl(ioaddr + GMAC_CONTROL);
-
-       return !!(value & GMAC_CONTROL_IPC);
-}
-
-static void dwmac1000_dump_regs(void __iomem *ioaddr)
-{
-       int i;
-       pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
-
-       for (i = 0; i < 55; i++) {
-               int offset = i * 4;
-               pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
-                       offset, readl(ioaddr + offset));
-       }
-}
-
-static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
-                               unsigned int reg_n)
-{
-       stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
-                               GMAC_ADDR_LOW(reg_n));
-}
-
-static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
-                               unsigned int reg_n)
-{
-       stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
-                               GMAC_ADDR_LOW(reg_n));
-}
-
-static void dwmac1000_set_filter(struct net_device *dev)
-{
-       void __iomem *ioaddr = (void __iomem *) dev->base_addr;
-       unsigned int value = 0;
-
-       CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
-                __func__, netdev_mc_count(dev), netdev_uc_count(dev));
-
-       if (dev->flags & IFF_PROMISC)
-               value = GMAC_FRAME_FILTER_PR;
-       else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
-                  || (dev->flags & IFF_ALLMULTI)) {
-               value = GMAC_FRAME_FILTER_PM;   /* pass all multi */
-               writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
-               writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
-       } else if (!netdev_mc_empty(dev)) {
-               u32 mc_filter[2];
-               struct netdev_hw_addr *ha;
-
-               /* Hash filter for multicast */
-               value = GMAC_FRAME_FILTER_HMC;
-
-               memset(mc_filter, 0, sizeof(mc_filter));
-               netdev_for_each_mc_addr(ha, dev) {
-                       /* The upper 6 bits of the calculated CRC are used to
-                          index the contens of the hash table */
-                       int bit_nr =
-                           bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;
-                       /* The most significant bit determines the register to
-                        * use (H/L) while the other 5 bits determine the bit
-                        * within the register. */
-                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-               }
-               writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
-               writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
-       }
-
-       /* Handle multiple unicast addresses (perfect filtering)*/
-       if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
-               /* Switch to promiscuous mode is more than 16 addrs
-                  are required */
-               value |= GMAC_FRAME_FILTER_PR;
-       else {
-               int reg = 1;
-               struct netdev_hw_addr *ha;
-
-               netdev_for_each_uc_addr(ha, dev) {
-                       dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
-                       reg++;
-               }
-       }
-
-#ifdef FRAME_FILTER_DEBUG
-       /* Enable Receive all mode (to debug filtering_fail errors) */
-       value |= GMAC_FRAME_FILTER_RA;
-#endif
-       writel(value, ioaddr + GMAC_FRAME_FILTER);
-
-       CHIP_DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
-           "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
-           readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
-}
-
-static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
-                          unsigned int fc, unsigned int pause_time)
-{
-       unsigned int flow = 0;
-
-       CHIP_DBG(KERN_DEBUG "GMAC Flow-Control:\n");
-       if (fc & FLOW_RX) {
-               CHIP_DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
-               flow |= GMAC_FLOW_CTRL_RFE;
-       }
-       if (fc & FLOW_TX) {
-               CHIP_DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
-               flow |= GMAC_FLOW_CTRL_TFE;
-       }
-
-       if (duplex) {
-               CHIP_DBG(KERN_DEBUG "\tduplex mode: PAUSE %d\n", pause_time);
-               flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
-       }
-
-       writel(flow, ioaddr + GMAC_FLOW_CTRL);
-}
-
-static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
-{
-       unsigned int pmt = 0;
-
-       if (mode & WAKE_MAGIC) {
-               CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
-               pmt |= power_down | magic_pkt_en;
-       }
-       if (mode & WAKE_UCAST) {
-               CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
-               pmt |= global_unicast;
-       }
-
-       writel(pmt, ioaddr + GMAC_PMT);
-}
-
-
-static void dwmac1000_irq_status(void __iomem *ioaddr)
-{
-       u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
-
-       /* Not used events (e.g. MMC interrupts) are not handled. */
-       if ((intr_status & mmc_tx_irq))
-               CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
-                   readl(ioaddr + GMAC_MMC_TX_INTR));
-       if (unlikely(intr_status & mmc_rx_irq))
-               CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
-                   readl(ioaddr + GMAC_MMC_RX_INTR));
-       if (unlikely(intr_status & mmc_rx_csum_offload_irq))
-               CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
-                   readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
-       if (unlikely(intr_status & pmt_irq)) {
-               CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n");
-               /* clear the PMT bits 5 and 6 by reading the PMT
-                * status register. */
-               readl(ioaddr + GMAC_PMT);
-       }
-}
-
-static const struct stmmac_ops dwmac1000_ops = {
-       .core_init = dwmac1000_core_init,
-       .rx_coe = dwmac1000_rx_coe_supported,
-       .dump_regs = dwmac1000_dump_regs,
-       .host_irq_status = dwmac1000_irq_status,
-       .set_filter = dwmac1000_set_filter,
-       .flow_ctrl = dwmac1000_flow_ctrl,
-       .pmt = dwmac1000_pmt,
-       .set_umac_addr = dwmac1000_set_umac_addr,
-       .get_umac_addr = dwmac1000_get_umac_addr,
-};
-
-struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
-{
-       struct mac_device_info *mac;
-       u32 uid = readl(ioaddr + GMAC_VERSION);
-
-       pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
-               ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
-
-       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-       if (!mac)
-               return NULL;
-
-       mac->mac = &dwmac1000_ops;
-       mac->dma = &dwmac1000_dma_ops;
-
-       mac->link.port = GMAC_CONTROL_PS;
-       mac->link.duplex = GMAC_CONTROL_DM;
-       mac->link.speed = GMAC_CONTROL_FES;
-       mac->mii.addr = GMAC_MII_ADDR;
-       mac->mii.data = GMAC_MII_DATA;
-
-       return mac;
-}
diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c
deleted file mode 100644 (file)
index 3dbeea6..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************
-  This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
-  DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
-  developing this code.
-
-  This contains the functions to handle the dma.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <asm/io.h>
-#include "dwmac1000.h"
-#include "dwmac_dma.h"
-
-static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
-                             u32 dma_rx)
-{
-       u32 value = readl(ioaddr + DMA_BUS_MODE);
-       int limit;
-
-       /* DMA SW reset */
-       value |= DMA_BUS_MODE_SFT_RESET;
-       writel(value, ioaddr + DMA_BUS_MODE);
-       limit = 15000;
-       while (limit--) {
-               if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
-                       break;
-       }
-       if (limit < 0)
-               return -EBUSY;
-
-       value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
-           ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
-            (pbl << DMA_BUS_MODE_RPBL_SHIFT));
-
-#ifdef CONFIG_STMMAC_DA
-       value |= DMA_BUS_MODE_DA;       /* Rx has priority over tx */
-#endif
-       writel(value, ioaddr + DMA_BUS_MODE);
-
-       /* Mask interrupts by writing to CSR7 */
-       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
-
-       /* The base address of the RX/TX descriptor lists must be written into
-        * DMA CSR3 and CSR4, respectively. */
-       writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
-       writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
-
-       return 0;
-}
-
-static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
-                                   int rxmode)
-{
-       u32 csr6 = readl(ioaddr + DMA_CONTROL);
-
-       if (txmode == SF_DMA_MODE) {
-               CHIP_DBG(KERN_DEBUG "GMAC: enable TX store and forward mode\n");
-               /* Transmit COE type 2 cannot be done in cut-through mode. */
-               csr6 |= DMA_CONTROL_TSF;
-               /* Operating on second frame increase the performance
-                * especially when transmit store-and-forward is used.*/
-               csr6 |= DMA_CONTROL_OSF;
-       } else {
-               CHIP_DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
-                             " (threshold = %d)\n", txmode);
-               csr6 &= ~DMA_CONTROL_TSF;
-               csr6 &= DMA_CONTROL_TC_TX_MASK;
-               /* Set the transmit threshold */
-               if (txmode <= 32)
-                       csr6 |= DMA_CONTROL_TTC_32;
-               else if (txmode <= 64)
-                       csr6 |= DMA_CONTROL_TTC_64;
-               else if (txmode <= 128)
-                       csr6 |= DMA_CONTROL_TTC_128;
-               else if (txmode <= 192)
-                       csr6 |= DMA_CONTROL_TTC_192;
-               else
-                       csr6 |= DMA_CONTROL_TTC_256;
-       }
-
-       if (rxmode == SF_DMA_MODE) {
-               CHIP_DBG(KERN_DEBUG "GMAC: enable RX store and forward mode\n");
-               csr6 |= DMA_CONTROL_RSF;
-       } else {
-               CHIP_DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
-                             " (threshold = %d)\n", rxmode);
-               csr6 &= ~DMA_CONTROL_RSF;
-               csr6 &= DMA_CONTROL_TC_RX_MASK;
-               if (rxmode <= 32)
-                       csr6 |= DMA_CONTROL_RTC_32;
-               else if (rxmode <= 64)
-                       csr6 |= DMA_CONTROL_RTC_64;
-               else if (rxmode <= 96)
-                       csr6 |= DMA_CONTROL_RTC_96;
-               else
-                       csr6 |= DMA_CONTROL_RTC_128;
-       }
-
-       writel(csr6, ioaddr + DMA_CONTROL);
-}
-
-/* Not yet implemented --- no RMON module */
-static void dwmac1000_dma_diagnostic_fr(void *data,
-                 struct stmmac_extra_stats *x, void __iomem *ioaddr)
-{
-       return;
-}
-
-static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
-{
-       int i;
-       pr_info(" DMA registers\n");
-       for (i = 0; i < 22; i++) {
-               if ((i < 9) || (i > 17)) {
-                       int offset = i * 4;
-                       pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
-                              (DMA_BUS_MODE + offset),
-                              readl(ioaddr + DMA_BUS_MODE + offset));
-               }
-       }
-}
-
-const struct stmmac_dma_ops dwmac1000_dma_ops = {
-       .init = dwmac1000_dma_init,
-       .dump_regs = dwmac1000_dump_dma_regs,
-       .dma_mode = dwmac1000_dma_operation_mode,
-       .dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
-       .enable_dma_transmission = dwmac_enable_dma_transmission,
-       .enable_dma_irq = dwmac_enable_dma_irq,
-       .disable_dma_irq = dwmac_disable_dma_irq,
-       .start_tx = dwmac_dma_start_tx,
-       .stop_tx = dwmac_dma_stop_tx,
-       .start_rx = dwmac_dma_start_rx,
-       .stop_rx = dwmac_dma_stop_rx,
-       .dma_interrupt = dwmac_dma_interrupt,
-};
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
deleted file mode 100644 (file)
index 743a580..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*******************************************************************************
-  This is the driver for the MAC 10/100 on-chip Ethernet controller
-  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
-
-  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
-  this code.
-
-  This only implements the mac core functions for this chip.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/crc32.h>
-#include <asm/io.h>
-#include "dwmac100.h"
-
-static void dwmac100_core_init(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + MAC_CONTROL);
-
-       writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
-
-#ifdef STMMAC_VLAN_TAG_USED
-       writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
-#endif
-}
-
-static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
-{
-       return 0;
-}
-
-static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
-{
-       pr_info("\t----------------------------------------------\n"
-               "\t  DWMAC 100 CSR (base addr = 0x%p)\n"
-               "\t----------------------------------------------\n",
-               ioaddr);
-       pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
-               readl(ioaddr + MAC_CONTROL));
-       pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
-               readl(ioaddr + MAC_ADDR_HIGH));
-       pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
-               readl(ioaddr + MAC_ADDR_LOW));
-       pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
-               MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
-       pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
-               MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
-       pr_info("\tflow control (offset 0x%x): 0x%08x\n",
-               MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
-       pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
-               readl(ioaddr + MAC_VLAN1));
-       pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
-               readl(ioaddr + MAC_VLAN2));
-       pr_info("\n\tMAC management counter registers\n");
-       pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
-               MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
-       pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
-               MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
-       pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
-               MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
-       pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
-               MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
-       pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
-               MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
-}
-
-static void dwmac100_irq_status(void __iomem *ioaddr)
-{
-       return;
-}
-
-static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
-                                  unsigned int reg_n)
-{
-       stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
-}
-
-static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
-                                  unsigned int reg_n)
-{
-       stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
-}
-
-static void dwmac100_set_filter(struct net_device *dev)
-{
-       void __iomem *ioaddr = (void __iomem *) dev->base_addr;
-       u32 value = readl(ioaddr + MAC_CONTROL);
-
-       if (dev->flags & IFF_PROMISC) {
-               value |= MAC_CONTROL_PR;
-               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
-                          MAC_CONTROL_HP);
-       } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
-                  || (dev->flags & IFF_ALLMULTI)) {
-               value |= MAC_CONTROL_PM;
-               value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
-               writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
-               writel(0xffffffff, ioaddr + MAC_HASH_LOW);
-       } else if (netdev_mc_empty(dev)) {      /* no multicast */
-               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
-                          MAC_CONTROL_HO | MAC_CONTROL_HP);
-       } else {
-               u32 mc_filter[2];
-               struct netdev_hw_addr *ha;
-
-               /* Perfect filter mode for physical address and Hash
-                  filter for multicast */
-               value |= MAC_CONTROL_HP;
-               value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
-                          MAC_CONTROL_IF | MAC_CONTROL_HO);
-
-               memset(mc_filter, 0, sizeof(mc_filter));
-               netdev_for_each_mc_addr(ha, dev) {
-                       /* The upper 6 bits of the calculated CRC are used to
-                        * index the contens of the hash table */
-                       int bit_nr =
-                           ether_crc(ETH_ALEN, ha->addr) >> 26;
-                       /* The most significant bit determines the register to
-                        * use (H/L) while the other 5 bits determine the bit
-                        * within the register. */
-                       mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-               }
-               writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
-               writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
-       }
-
-       writel(value, ioaddr + MAC_CONTROL);
-
-       CHIP_DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
-           "HI 0x%08x, LO 0x%08x\n",
-           __func__, readl(ioaddr + MAC_CONTROL),
-           readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
-}
-
-static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
-                              unsigned int fc, unsigned int pause_time)
-{
-       unsigned int flow = MAC_FLOW_CTRL_ENABLE;
-
-       if (duplex)
-               flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
-       writel(flow, ioaddr + MAC_FLOW_CTRL);
-}
-
-/* No PMT module supported for this Ethernet Controller.
- * Tested on ST platforms only.
- */
-static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
-{
-       return;
-}
-
-static const struct stmmac_ops dwmac100_ops = {
-       .core_init = dwmac100_core_init,
-       .rx_coe = dwmac100_rx_coe_supported,
-       .dump_regs = dwmac100_dump_mac_regs,
-       .host_irq_status = dwmac100_irq_status,
-       .set_filter = dwmac100_set_filter,
-       .flow_ctrl = dwmac100_flow_ctrl,
-       .pmt = dwmac100_pmt,
-       .set_umac_addr = dwmac100_set_umac_addr,
-       .get_umac_addr = dwmac100_get_umac_addr,
-};
-
-struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
-{
-       struct mac_device_info *mac;
-
-       mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
-       if (!mac)
-               return NULL;
-
-       pr_info("\tDWMAC100\n");
-
-       mac->mac = &dwmac100_ops;
-       mac->dma = &dwmac100_dma_ops;
-
-       mac->link.port = MAC_CONTROL_PS;
-       mac->link.duplex = MAC_CONTROL_F;
-       mac->link.speed = 0;
-       mac->mii.addr = MAC_MII_ADDR;
-       mac->mii.data = MAC_MII_DATA;
-
-       return mac;
-}
diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c
deleted file mode 100644 (file)
index 627f656..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*******************************************************************************
-  This is the driver for the MAC 10/100 on-chip Ethernet controller
-  currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
-
-  DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
-  this code.
-
-  This contains the functions to handle the dma.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <asm/io.h>
-#include "dwmac100.h"
-#include "dwmac_dma.h"
-
-static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
-                            u32 dma_rx)
-{
-       u32 value = readl(ioaddr + DMA_BUS_MODE);
-       int limit;
-
-       /* DMA SW reset */
-       value |= DMA_BUS_MODE_SFT_RESET;
-       writel(value, ioaddr + DMA_BUS_MODE);
-       limit = 15000;
-       while (limit--) {
-               if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
-                       break;
-       }
-       if (limit < 0)
-               return -EBUSY;
-
-       /* Enable Application Access by writing to DMA CSR0 */
-       writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
-              ioaddr + DMA_BUS_MODE);
-
-       /* Mask interrupts by writing to CSR7 */
-       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
-
-       /* The base address of the RX/TX descriptor lists must be written into
-        * DMA CSR3 and CSR4, respectively. */
-       writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
-       writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
-
-       return 0;
-}
-
-/* Store and Forward capability is not used at all..
- * The transmit threshold can be programmed by
- * setting the TTC bits in the DMA control register.*/
-static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
-                                       int rxmode)
-{
-       u32 csr6 = readl(ioaddr + DMA_CONTROL);
-
-       if (txmode <= 32)
-               csr6 |= DMA_CONTROL_TTC_32;
-       else if (txmode <= 64)
-               csr6 |= DMA_CONTROL_TTC_64;
-       else
-               csr6 |= DMA_CONTROL_TTC_128;
-
-       writel(csr6, ioaddr + DMA_CONTROL);
-}
-
-static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
-{
-       int i;
-
-       CHIP_DBG(KERN_DEBUG "DWMAC 100 DMA CSR\n");
-       for (i = 0; i < 9; i++)
-               pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
-                      (DMA_BUS_MODE + i * 4),
-                      readl(ioaddr + DMA_BUS_MODE + i * 4));
-       CHIP_DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
-           DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
-       CHIP_DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
-           DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
-}
-
-/* DMA controller has two counters to track the number of
- * the receive missed frames. */
-static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
-                                      void __iomem *ioaddr)
-{
-       struct net_device_stats *stats = (struct net_device_stats *)data;
-       u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
-
-       if (unlikely(csr8)) {
-               if (csr8 & DMA_MISSED_FRAME_OVE) {
-                       stats->rx_over_errors += 0x800;
-                       x->rx_overflow_cntr += 0x800;
-               } else {
-                       unsigned int ove_cntr;
-                       ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
-                       stats->rx_over_errors += ove_cntr;
-                       x->rx_overflow_cntr += ove_cntr;
-               }
-
-               if (csr8 & DMA_MISSED_FRAME_OVE_M) {
-                       stats->rx_missed_errors += 0xffff;
-                       x->rx_missed_cntr += 0xffff;
-               } else {
-                       unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
-                       stats->rx_missed_errors += miss_f;
-                       x->rx_missed_cntr += miss_f;
-               }
-       }
-}
-
-const struct stmmac_dma_ops dwmac100_dma_ops = {
-       .init = dwmac100_dma_init,
-       .dump_regs = dwmac100_dump_dma_regs,
-       .dma_mode = dwmac100_dma_operation_mode,
-       .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
-       .enable_dma_transmission = dwmac_enable_dma_transmission,
-       .enable_dma_irq = dwmac_enable_dma_irq,
-       .disable_dma_irq = dwmac_disable_dma_irq,
-       .start_tx = dwmac_dma_start_tx,
-       .stop_tx = dwmac_dma_stop_tx,
-       .start_rx = dwmac_dma_start_rx,
-       .stop_rx = dwmac_dma_stop_rx,
-       .dma_interrupt = dwmac_dma_interrupt,
-};
diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h
deleted file mode 100644 (file)
index da3f5cc..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
-  DWMAC DMA Header file.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-/* DMA CRS Control and Status Register Mapping */
-#define DMA_BUS_MODE           0x00001000      /* Bus Mode */
-#define DMA_XMT_POLL_DEMAND    0x00001004      /* Transmit Poll Demand */
-#define DMA_RCV_POLL_DEMAND    0x00001008      /* Received Poll Demand */
-#define DMA_RCV_BASE_ADDR      0x0000100c      /* Receive List Base */
-#define DMA_TX_BASE_ADDR       0x00001010      /* Transmit List Base */
-#define DMA_STATUS             0x00001014      /* Status Register */
-#define DMA_CONTROL            0x00001018      /* Ctrl (Operational Mode) */
-#define DMA_INTR_ENA           0x0000101c      /* Interrupt Enable */
-#define DMA_MISSED_FRAME_CTR   0x00001020      /* Missed Frame Counter */
-#define DMA_CUR_TX_BUF_ADDR    0x00001050      /* Current Host Tx Buffer */
-#define DMA_CUR_RX_BUF_ADDR    0x00001054      /* Current Host Rx Buffer */
-
-/* DMA Control register defines */
-#define DMA_CONTROL_ST         0x00002000      /* Start/Stop Transmission */
-#define DMA_CONTROL_SR         0x00000002      /* Start/Stop Receive */
-
-/* DMA Normal interrupt */
-#define DMA_INTR_ENA_NIE 0x00010000    /* Normal Summary */
-#define DMA_INTR_ENA_TIE 0x00000001    /* Transmit Interrupt */
-#define DMA_INTR_ENA_TUE 0x00000004    /* Transmit Buffer Unavailable */
-#define DMA_INTR_ENA_RIE 0x00000040    /* Receive Interrupt */
-#define DMA_INTR_ENA_ERE 0x00004000    /* Early Receive */
-
-#define DMA_INTR_NORMAL        (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
-                       DMA_INTR_ENA_TIE)
-
-/* DMA Abnormal interrupt */
-#define DMA_INTR_ENA_AIE 0x00008000    /* Abnormal Summary */
-#define DMA_INTR_ENA_FBE 0x00002000    /* Fatal Bus Error */
-#define DMA_INTR_ENA_ETE 0x00000400    /* Early Transmit */
-#define DMA_INTR_ENA_RWE 0x00000200    /* Receive Watchdog */
-#define DMA_INTR_ENA_RSE 0x00000100    /* Receive Stopped */
-#define DMA_INTR_ENA_RUE 0x00000080    /* Receive Buffer Unavailable */
-#define DMA_INTR_ENA_UNE 0x00000020    /* Tx Underflow */
-#define DMA_INTR_ENA_OVE 0x00000010    /* Receive Overflow */
-#define DMA_INTR_ENA_TJE 0x00000008    /* Transmit Jabber */
-#define DMA_INTR_ENA_TSE 0x00000002    /* Transmit Stopped */
-
-#define DMA_INTR_ABNORMAL      (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
-                               DMA_INTR_ENA_UNE)
-
-/* DMA default interrupt mask */
-#define DMA_INTR_DEFAULT_MASK  (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
-
-/* DMA Status register defines */
-#define DMA_STATUS_GPI         0x10000000      /* PMT interrupt */
-#define DMA_STATUS_GMI         0x08000000      /* MMC interrupt */
-#define DMA_STATUS_GLI         0x04000000      /* GMAC Line interface int */
-#define DMA_STATUS_GMI         0x08000000
-#define DMA_STATUS_GLI         0x04000000
-#define DMA_STATUS_EB_MASK     0x00380000      /* Error Bits Mask */
-#define DMA_STATUS_EB_TX_ABORT 0x00080000      /* Error Bits - TX Abort */
-#define DMA_STATUS_EB_RX_ABORT 0x00100000      /* Error Bits - RX Abort */
-#define DMA_STATUS_TS_MASK     0x00700000      /* Transmit Process State */
-#define DMA_STATUS_TS_SHIFT    20
-#define DMA_STATUS_RS_MASK     0x000e0000      /* Receive Process State */
-#define DMA_STATUS_RS_SHIFT    17
-#define DMA_STATUS_NIS 0x00010000      /* Normal Interrupt Summary */
-#define DMA_STATUS_AIS 0x00008000      /* Abnormal Interrupt Summary */
-#define DMA_STATUS_ERI 0x00004000      /* Early Receive Interrupt */
-#define DMA_STATUS_FBI 0x00002000      /* Fatal Bus Error Interrupt */
-#define DMA_STATUS_ETI 0x00000400      /* Early Transmit Interrupt */
-#define DMA_STATUS_RWT 0x00000200      /* Receive Watchdog Timeout */
-#define DMA_STATUS_RPS 0x00000100      /* Receive Process Stopped */
-#define DMA_STATUS_RU  0x00000080      /* Receive Buffer Unavailable */
-#define DMA_STATUS_RI  0x00000040      /* Receive Interrupt */
-#define DMA_STATUS_UNF 0x00000020      /* Transmit Underflow */
-#define DMA_STATUS_OVF 0x00000010      /* Receive Overflow */
-#define DMA_STATUS_TJT 0x00000008      /* Transmit Jabber Timeout */
-#define DMA_STATUS_TU  0x00000004      /* Transmit Buffer Unavailable */
-#define DMA_STATUS_TPS 0x00000002      /* Transmit Process Stopped */
-#define DMA_STATUS_TI  0x00000001      /* Transmit Interrupt */
-#define DMA_CONTROL_FTF                0x00100000 /* Flush transmit FIFO */
-
-extern void dwmac_enable_dma_transmission(void __iomem *ioaddr);
-extern void dwmac_enable_dma_irq(void __iomem *ioaddr);
-extern void dwmac_disable_dma_irq(void __iomem *ioaddr);
-extern void dwmac_dma_start_tx(void __iomem *ioaddr);
-extern void dwmac_dma_stop_tx(void __iomem *ioaddr);
-extern void dwmac_dma_start_rx(void __iomem *ioaddr);
-extern void dwmac_dma_stop_rx(void __iomem *ioaddr);
-extern int dwmac_dma_interrupt(void __iomem *ioaddr,
-                               struct stmmac_extra_stats *x);
diff --git a/drivers/net/stmmac/dwmac_lib.c b/drivers/net/stmmac/dwmac_lib.c
deleted file mode 100644 (file)
index e250935..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*******************************************************************************
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/io.h>
-#include "common.h"
-#include "dwmac_dma.h"
-
-#undef DWMAC_DMA_DEBUG
-#ifdef DWMAC_DMA_DEBUG
-#define DWMAC_LIB_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define DWMAC_LIB_DBG(fmt, args...)  do { } while (0)
-#endif
-
-/* CSR1 enables the transmit DMA to check for new descriptor */
-void dwmac_enable_dma_transmission(void __iomem *ioaddr)
-{
-       writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
-}
-
-void dwmac_enable_dma_irq(void __iomem *ioaddr)
-{
-       writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
-}
-
-void dwmac_disable_dma_irq(void __iomem *ioaddr)
-{
-       writel(0, ioaddr + DMA_INTR_ENA);
-}
-
-void dwmac_dma_start_tx(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + DMA_CONTROL);
-       value |= DMA_CONTROL_ST;
-       writel(value, ioaddr + DMA_CONTROL);
-}
-
-void dwmac_dma_stop_tx(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + DMA_CONTROL);
-       value &= ~DMA_CONTROL_ST;
-       writel(value, ioaddr + DMA_CONTROL);
-}
-
-void dwmac_dma_start_rx(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + DMA_CONTROL);
-       value |= DMA_CONTROL_SR;
-       writel(value, ioaddr + DMA_CONTROL);
-}
-
-void dwmac_dma_stop_rx(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + DMA_CONTROL);
-       value &= ~DMA_CONTROL_SR;
-       writel(value, ioaddr + DMA_CONTROL);
-}
-
-#ifdef DWMAC_DMA_DEBUG
-static void show_tx_process_state(unsigned int status)
-{
-       unsigned int state;
-       state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
-
-       switch (state) {
-       case 0:
-               pr_info("- TX (Stopped): Reset or Stop command\n");
-               break;
-       case 1:
-               pr_info("- TX (Running):Fetching the Tx desc\n");
-               break;
-       case 2:
-               pr_info("- TX (Running): Waiting for end of tx\n");
-               break;
-       case 3:
-               pr_info("- TX (Running): Reading the data "
-                      "and queuing the data into the Tx buf\n");
-               break;
-       case 6:
-               pr_info("- TX (Suspended): Tx Buff Underflow "
-                      "or an unavailable Transmit descriptor\n");
-               break;
-       case 7:
-               pr_info("- TX (Running): Closing Tx descriptor\n");
-               break;
-       default:
-               break;
-       }
-}
-
-static void show_rx_process_state(unsigned int status)
-{
-       unsigned int state;
-       state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
-
-       switch (state) {
-       case 0:
-               pr_info("- RX (Stopped): Reset or Stop command\n");
-               break;
-       case 1:
-               pr_info("- RX (Running): Fetching the Rx desc\n");
-               break;
-       case 2:
-               pr_info("- RX (Running):Checking for end of pkt\n");
-               break;
-       case 3:
-               pr_info("- RX (Running): Waiting for Rx pkt\n");
-               break;
-       case 4:
-               pr_info("- RX (Suspended): Unavailable Rx buf\n");
-               break;
-       case 5:
-               pr_info("- RX (Running): Closing Rx descriptor\n");
-               break;
-       case 6:
-               pr_info("- RX(Running): Flushing the current frame"
-                      " from the Rx buf\n");
-               break;
-       case 7:
-               pr_info("- RX (Running): Queuing the Rx frame"
-                      " from the Rx buf into memory\n");
-               break;
-       default:
-               break;
-       }
-}
-#endif
-
-int dwmac_dma_interrupt(void __iomem *ioaddr,
-                       struct stmmac_extra_stats *x)
-{
-       int ret = 0;
-       /* read the status register (CSR5) */
-       u32 intr_status = readl(ioaddr + DMA_STATUS);
-
-       DWMAC_LIB_DBG(KERN_INFO "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
-#ifdef DWMAC_DMA_DEBUG
-       /* It displays the DMA process states (CSR5 register) */
-       show_tx_process_state(intr_status);
-       show_rx_process_state(intr_status);
-#endif
-       /* ABNORMAL interrupts */
-       if (unlikely(intr_status & DMA_STATUS_AIS)) {
-               DWMAC_LIB_DBG(KERN_INFO "CSR5[15] DMA ABNORMAL IRQ: ");
-               if (unlikely(intr_status & DMA_STATUS_UNF)) {
-                       DWMAC_LIB_DBG(KERN_INFO "transmit underflow\n");
-                       ret = tx_hard_error_bump_tc;
-                       x->tx_undeflow_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_TJT)) {
-                       DWMAC_LIB_DBG(KERN_INFO "transmit jabber\n");
-                       x->tx_jabber_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_OVF)) {
-                       DWMAC_LIB_DBG(KERN_INFO "recv overflow\n");
-                       x->rx_overflow_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_RU)) {
-                       DWMAC_LIB_DBG(KERN_INFO "receive buffer unavailable\n");
-                       x->rx_buf_unav_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_RPS)) {
-                       DWMAC_LIB_DBG(KERN_INFO "receive process stopped\n");
-                       x->rx_process_stopped_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_RWT)) {
-                       DWMAC_LIB_DBG(KERN_INFO "receive watchdog\n");
-                       x->rx_watchdog_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_ETI)) {
-                       DWMAC_LIB_DBG(KERN_INFO "transmit early interrupt\n");
-                       x->tx_early_irq++;
-               }
-               if (unlikely(intr_status & DMA_STATUS_TPS)) {
-                       DWMAC_LIB_DBG(KERN_INFO "transmit process stopped\n");
-                       x->tx_process_stopped_irq++;
-                       ret = tx_hard_error;
-               }
-               if (unlikely(intr_status & DMA_STATUS_FBI)) {
-                       DWMAC_LIB_DBG(KERN_INFO "fatal bus error\n");
-                       x->fatal_bus_error_irq++;
-                       ret = tx_hard_error;
-               }
-       }
-       /* TX/RX NORMAL interrupts */
-       if (intr_status & DMA_STATUS_NIS) {
-               x->normal_irq_n++;
-               if (likely((intr_status & DMA_STATUS_RI) ||
-                        (intr_status & (DMA_STATUS_TI))))
-                               ret = handle_tx_rx;
-       }
-       /* Optional hardware blocks, interrupts should be disabled */
-       if (unlikely(intr_status &
-                    (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
-               pr_info("%s: unexpected status %08x\n", __func__, intr_status);
-       /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
-       writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
-
-       DWMAC_LIB_DBG(KERN_INFO "\n\n");
-       return ret;
-}
-
-void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
-{
-       u32 csr6 = readl(ioaddr + DMA_CONTROL);
-       writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
-
-       do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
-}
-
-void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
-                        unsigned int high, unsigned int low)
-{
-       unsigned long data;
-
-       data = (addr[5] << 8) | addr[4];
-       writel(data, ioaddr + high);
-       data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
-       writel(data, ioaddr + low);
-}
-
-void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
-                        unsigned int high, unsigned int low)
-{
-       unsigned int hi_addr, lo_addr;
-
-       /* Read the MAC address from the hardware */
-       hi_addr = readl(ioaddr + high);
-       lo_addr = readl(ioaddr + low);
-
-       /* Extract the MAC address from the high and low words */
-       addr[0] = lo_addr & 0xff;
-       addr[1] = (lo_addr >> 8) & 0xff;
-       addr[2] = (lo_addr >> 16) & 0xff;
-       addr[3] = (lo_addr >> 24) & 0xff;
-       addr[4] = hi_addr & 0xff;
-       addr[5] = (hi_addr >> 8) & 0xff;
-}
-
diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c
deleted file mode 100644 (file)
index e5dfb6a..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/*******************************************************************************
-  This contains the functions to handle the enhanced descriptors.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include "common.h"
-
-static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
-                                 struct dma_desc *p, void __iomem *ioaddr)
-{
-       int ret = 0;
-       struct net_device_stats *stats = (struct net_device_stats *)data;
-
-       if (unlikely(p->des01.etx.error_summary)) {
-               CHIP_DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
-               if (unlikely(p->des01.etx.jabber_timeout)) {
-                       CHIP_DBG(KERN_ERR "\tjabber_timeout error\n");
-                       x->tx_jabber++;
-               }
-
-               if (unlikely(p->des01.etx.frame_flushed)) {
-                       CHIP_DBG(KERN_ERR "\tframe_flushed error\n");
-                       x->tx_frame_flushed++;
-                       dwmac_dma_flush_tx_fifo(ioaddr);
-               }
-
-               if (unlikely(p->des01.etx.loss_carrier)) {
-                       CHIP_DBG(KERN_ERR "\tloss_carrier error\n");
-                       x->tx_losscarrier++;
-                       stats->tx_carrier_errors++;
-               }
-               if (unlikely(p->des01.etx.no_carrier)) {
-                       CHIP_DBG(KERN_ERR "\tno_carrier error\n");
-                       x->tx_carrier++;
-                       stats->tx_carrier_errors++;
-               }
-               if (unlikely(p->des01.etx.late_collision)) {
-                       CHIP_DBG(KERN_ERR "\tlate_collision error\n");
-                       stats->collisions += p->des01.etx.collision_count;
-               }
-               if (unlikely(p->des01.etx.excessive_collisions)) {
-                       CHIP_DBG(KERN_ERR "\texcessive_collisions\n");
-                       stats->collisions += p->des01.etx.collision_count;
-               }
-               if (unlikely(p->des01.etx.excessive_deferral)) {
-                       CHIP_DBG(KERN_INFO "\texcessive tx_deferral\n");
-                       x->tx_deferred++;
-               }
-
-               if (unlikely(p->des01.etx.underflow_error)) {
-                       CHIP_DBG(KERN_ERR "\tunderflow error\n");
-                       dwmac_dma_flush_tx_fifo(ioaddr);
-                       x->tx_underflow++;
-               }
-
-               if (unlikely(p->des01.etx.ip_header_error)) {
-                       CHIP_DBG(KERN_ERR "\tTX IP header csum error\n");
-                       x->tx_ip_header_error++;
-               }
-
-               if (unlikely(p->des01.etx.payload_error)) {
-                       CHIP_DBG(KERN_ERR "\tAddr/Payload csum error\n");
-                       x->tx_payload_error++;
-                       dwmac_dma_flush_tx_fifo(ioaddr);
-               }
-
-               ret = -1;
-       }
-
-       if (unlikely(p->des01.etx.deferred)) {
-               CHIP_DBG(KERN_INFO "GMAC TX status: tx deferred\n");
-               x->tx_deferred++;
-       }
-#ifdef STMMAC_VLAN_TAG_USED
-       if (p->des01.etx.vlan_frame) {
-               CHIP_DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
-               x->tx_vlan++;
-       }
-#endif
-
-       return ret;
-}
-
-static int enh_desc_get_tx_len(struct dma_desc *p)
-{
-       return p->des01.etx.buffer1_size;
-}
-
-static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err)
-{
-       int ret = good_frame;
-       u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
-
-       /* bits 5 7 0 | Frame status
-        * ----------------------------------------------------------
-        *      0 0 0 | IEEE 802.3 Type frame (length < 1536 octects)
-        *      1 0 0 | IPv4/6 No CSUM errorS.
-        *      1 0 1 | IPv4/6 CSUM PAYLOAD error
-        *      1 1 0 | IPv4/6 CSUM IP HR error
-        *      1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
-        *      0 0 1 | IPv4/6 unsupported IP PAYLOAD
-        *      0 1 1 | COE bypassed.. no IPv4/6 frame
-        *      0 1 0 | Reserved.
-        */
-       if (status == 0x0) {
-               CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
-               ret = llc_snap;
-       } else if (status == 0x4) {
-               CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
-               ret = good_frame;
-       } else if (status == 0x5) {
-               CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
-               ret = csum_none;
-       } else if (status == 0x6) {
-               CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
-               ret = csum_none;
-       } else if (status == 0x7) {
-               CHIP_DBG(KERN_ERR
-                   "RX Des0 status: IPv4/6 Header and Payload Error.\n");
-               ret = csum_none;
-       } else if (status == 0x1) {
-               CHIP_DBG(KERN_ERR
-                   "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
-               ret = discard_frame;
-       } else if (status == 0x3) {
-               CHIP_DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
-               ret = discard_frame;
-       }
-       return ret;
-}
-
-static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
-                                 struct dma_desc *p)
-{
-       int ret = good_frame;
-       struct net_device_stats *stats = (struct net_device_stats *)data;
-
-       if (unlikely(p->des01.erx.error_summary)) {
-               CHIP_DBG(KERN_ERR "GMAC RX Error Summary 0x%08x\n",
-                                 p->des01.erx);
-               if (unlikely(p->des01.erx.descriptor_error)) {
-                       CHIP_DBG(KERN_ERR "\tdescriptor error\n");
-                       x->rx_desc++;
-                       stats->rx_length_errors++;
-               }
-               if (unlikely(p->des01.erx.overflow_error)) {
-                       CHIP_DBG(KERN_ERR "\toverflow error\n");
-                       x->rx_gmac_overflow++;
-               }
-
-               if (unlikely(p->des01.erx.ipc_csum_error))
-                       CHIP_DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
-
-               if (unlikely(p->des01.erx.late_collision)) {
-                       CHIP_DBG(KERN_ERR "\tlate_collision error\n");
-                       stats->collisions++;
-                       stats->collisions++;
-               }
-               if (unlikely(p->des01.erx.receive_watchdog)) {
-                       CHIP_DBG(KERN_ERR "\treceive_watchdog error\n");
-                       x->rx_watchdog++;
-               }
-               if (unlikely(p->des01.erx.error_gmii)) {
-                       CHIP_DBG(KERN_ERR "\tReceive Error\n");
-                       x->rx_mii++;
-               }
-               if (unlikely(p->des01.erx.crc_error)) {
-                       CHIP_DBG(KERN_ERR "\tCRC error\n");
-                       x->rx_crc++;
-                       stats->rx_crc_errors++;
-               }
-               ret = discard_frame;
-       }
-
-       /* After a payload csum error, the ES bit is set.
-        * It doesn't match with the information reported into the databook.
-        * At any rate, we need to understand if the CSUM hw computation is ok
-        * and report this info to the upper layers. */
-       ret = enh_desc_coe_rdes0(p->des01.erx.ipc_csum_error,
-               p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
-
-       if (unlikely(p->des01.erx.dribbling)) {
-               CHIP_DBG(KERN_ERR "GMAC RX: dribbling error\n");
-               ret = discard_frame;
-       }
-       if (unlikely(p->des01.erx.sa_filter_fail)) {
-               CHIP_DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
-               x->sa_rx_filter_fail++;
-               ret = discard_frame;
-       }
-       if (unlikely(p->des01.erx.da_filter_fail)) {
-               CHIP_DBG(KERN_ERR "GMAC RX : Dest Address filter fail\n");
-               x->da_rx_filter_fail++;
-               ret = discard_frame;
-       }
-       if (unlikely(p->des01.erx.length_error)) {
-               CHIP_DBG(KERN_ERR "GMAC RX: length_error error\n");
-               x->rx_length++;
-               ret = discard_frame;
-       }
-#ifdef STMMAC_VLAN_TAG_USED
-       if (p->des01.erx.vlan_tag) {
-               CHIP_DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
-               x->rx_vlan++;
-       }
-#endif
-       return ret;
-}
-
-static void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
-                                 int disable_rx_ic)
-{
-       int i;
-       for (i = 0; i < ring_size; i++) {
-               p->des01.erx.own = 1;
-               p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
-               /* To support jumbo frames */
-               p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
-               if (i == ring_size - 1)
-                       p->des01.erx.end_ring = 1;
-               if (disable_rx_ic)
-                       p->des01.erx.disable_ic = 1;
-               p++;
-       }
-}
-
-static void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
-{
-       int i;
-
-       for (i = 0; i < ring_size; i++) {
-               p->des01.etx.own = 0;
-               if (i == ring_size - 1)
-                       p->des01.etx.end_ring = 1;
-               p++;
-       }
-}
-
-static int enh_desc_get_tx_owner(struct dma_desc *p)
-{
-       return p->des01.etx.own;
-}
-
-static int enh_desc_get_rx_owner(struct dma_desc *p)
-{
-       return p->des01.erx.own;
-}
-
-static void enh_desc_set_tx_owner(struct dma_desc *p)
-{
-       p->des01.etx.own = 1;
-}
-
-static void enh_desc_set_rx_owner(struct dma_desc *p)
-{
-       p->des01.erx.own = 1;
-}
-
-static int enh_desc_get_tx_ls(struct dma_desc *p)
-{
-       return p->des01.etx.last_segment;
-}
-
-static void enh_desc_release_tx_desc(struct dma_desc *p)
-{
-       int ter = p->des01.etx.end_ring;
-
-       memset(p, 0, offsetof(struct dma_desc, des2));
-       p->des01.etx.end_ring = ter;
-}
-
-static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
-                                    int csum_flag)
-{
-       p->des01.etx.first_segment = is_fs;
-       if (unlikely(len > BUF_SIZE_4KiB)) {
-               p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
-               p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
-       } else {
-               p->des01.etx.buffer1_size = len;
-       }
-       if (likely(csum_flag))
-               p->des01.etx.checksum_insertion = cic_full;
-}
-
-static void enh_desc_clear_tx_ic(struct dma_desc *p)
-{
-       p->des01.etx.interrupt = 0;
-}
-
-static void enh_desc_close_tx_desc(struct dma_desc *p)
-{
-       p->des01.etx.last_segment = 1;
-       p->des01.etx.interrupt = 1;
-}
-
-static int enh_desc_get_rx_frame_len(struct dma_desc *p)
-{
-       return p->des01.erx.frame_length;
-}
-
-const struct stmmac_desc_ops enh_desc_ops = {
-       .tx_status = enh_desc_get_tx_status,
-       .rx_status = enh_desc_get_rx_status,
-       .get_tx_len = enh_desc_get_tx_len,
-       .init_rx_desc = enh_desc_init_rx_desc,
-       .init_tx_desc = enh_desc_init_tx_desc,
-       .get_tx_owner = enh_desc_get_tx_owner,
-       .get_rx_owner = enh_desc_get_rx_owner,
-       .release_tx_desc = enh_desc_release_tx_desc,
-       .prepare_tx_desc = enh_desc_prepare_tx_desc,
-       .clear_tx_ic = enh_desc_clear_tx_ic,
-       .close_tx_desc = enh_desc_close_tx_desc,
-       .get_tx_ls = enh_desc_get_tx_ls,
-       .set_tx_owner = enh_desc_set_tx_owner,
-       .set_rx_owner = enh_desc_set_rx_owner,
-       .get_rx_frame_len = enh_desc_get_rx_frame_len,
-};
diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c
deleted file mode 100644 (file)
index 029c2a2..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*******************************************************************************
-  This contains the functions to handle the normal descriptors.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include "common.h"
-
-static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
-                              struct dma_desc *p, void __iomem *ioaddr)
-{
-       int ret = 0;
-       struct net_device_stats *stats = (struct net_device_stats *)data;
-
-       if (unlikely(p->des01.tx.error_summary)) {
-               if (unlikely(p->des01.tx.underflow_error)) {
-                       x->tx_underflow++;
-                       stats->tx_fifo_errors++;
-               }
-               if (unlikely(p->des01.tx.no_carrier)) {
-                       x->tx_carrier++;
-                       stats->tx_carrier_errors++;
-               }
-               if (unlikely(p->des01.tx.loss_carrier)) {
-                       x->tx_losscarrier++;
-                       stats->tx_carrier_errors++;
-               }
-               if (unlikely((p->des01.tx.excessive_deferral) ||
-                            (p->des01.tx.excessive_collisions) ||
-                            (p->des01.tx.late_collision)))
-                       stats->collisions += p->des01.tx.collision_count;
-               ret = -1;
-       }
-       if (unlikely(p->des01.tx.heartbeat_fail)) {
-               x->tx_heartbeat++;
-               stats->tx_heartbeat_errors++;
-               ret = -1;
-       }
-       if (unlikely(p->des01.tx.deferred))
-               x->tx_deferred++;
-
-       return ret;
-}
-
-static int ndesc_get_tx_len(struct dma_desc *p)
-{
-       return p->des01.tx.buffer1_size;
-}
-
-/* This function verifies if each incoming frame has some errors
- * and, if required, updates the multicast statistics.
- * In case of success, it returns csum_none because the device
- * is not able to compute the csum in HW. */
-static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
-                              struct dma_desc *p)
-{
-       int ret = csum_none;
-       struct net_device_stats *stats = (struct net_device_stats *)data;
-
-       if (unlikely(p->des01.rx.last_descriptor == 0)) {
-               pr_warning("ndesc Error: Oversized Ethernet "
-                          "frame spanned multiple buffers\n");
-               stats->rx_length_errors++;
-               return discard_frame;
-       }
-
-       if (unlikely(p->des01.rx.error_summary)) {
-               if (unlikely(p->des01.rx.descriptor_error))
-                       x->rx_desc++;
-               if (unlikely(p->des01.rx.partial_frame_error))
-                       x->rx_partial++;
-               if (unlikely(p->des01.rx.run_frame))
-                       x->rx_runt++;
-               if (unlikely(p->des01.rx.frame_too_long))
-                       x->rx_toolong++;
-               if (unlikely(p->des01.rx.collision)) {
-                       x->rx_collision++;
-                       stats->collisions++;
-               }
-               if (unlikely(p->des01.rx.crc_error)) {
-                       x->rx_crc++;
-                       stats->rx_crc_errors++;
-               }
-               ret = discard_frame;
-       }
-       if (unlikely(p->des01.rx.dribbling))
-               ret = discard_frame;
-
-       if (unlikely(p->des01.rx.length_error)) {
-               x->rx_length++;
-               ret = discard_frame;
-       }
-       if (unlikely(p->des01.rx.mii_error)) {
-               x->rx_mii++;
-               ret = discard_frame;
-       }
-       if (p->des01.rx.multicast_frame) {
-               x->rx_multicast++;
-               stats->multicast++;
-       }
-       return ret;
-}
-
-static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
-                              int disable_rx_ic)
-{
-       int i;
-       for (i = 0; i < ring_size; i++) {
-               p->des01.rx.own = 1;
-               p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
-               if (i == ring_size - 1)
-                       p->des01.rx.end_ring = 1;
-               if (disable_rx_ic)
-                       p->des01.rx.disable_ic = 1;
-               p++;
-       }
-}
-
-static void ndesc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
-{
-       int i;
-       for (i = 0; i < ring_size; i++) {
-               p->des01.tx.own = 0;
-               if (i == ring_size - 1)
-                       p->des01.tx.end_ring = 1;
-               p++;
-       }
-}
-
-static int ndesc_get_tx_owner(struct dma_desc *p)
-{
-       return p->des01.tx.own;
-}
-
-static int ndesc_get_rx_owner(struct dma_desc *p)
-{
-       return p->des01.rx.own;
-}
-
-static void ndesc_set_tx_owner(struct dma_desc *p)
-{
-       p->des01.tx.own = 1;
-}
-
-static void ndesc_set_rx_owner(struct dma_desc *p)
-{
-       p->des01.rx.own = 1;
-}
-
-static int ndesc_get_tx_ls(struct dma_desc *p)
-{
-       return p->des01.tx.last_segment;
-}
-
-static void ndesc_release_tx_desc(struct dma_desc *p)
-{
-       int ter = p->des01.tx.end_ring;
-
-       memset(p, 0, offsetof(struct dma_desc, des2));
-       /* set termination field */
-       p->des01.tx.end_ring = ter;
-}
-
-static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
-                                 int csum_flag)
-{
-       p->des01.tx.first_segment = is_fs;
-       p->des01.tx.buffer1_size = len;
-}
-
-static void ndesc_clear_tx_ic(struct dma_desc *p)
-{
-       p->des01.tx.interrupt = 0;
-}
-
-static void ndesc_close_tx_desc(struct dma_desc *p)
-{
-       p->des01.tx.last_segment = 1;
-       p->des01.tx.interrupt = 1;
-}
-
-static int ndesc_get_rx_frame_len(struct dma_desc *p)
-{
-       return p->des01.rx.frame_length;
-}
-
-const struct stmmac_desc_ops ndesc_ops = {
-       .tx_status = ndesc_get_tx_status,
-       .rx_status = ndesc_get_rx_status,
-       .get_tx_len = ndesc_get_tx_len,
-       .init_rx_desc = ndesc_init_rx_desc,
-       .init_tx_desc = ndesc_init_tx_desc,
-       .get_tx_owner = ndesc_get_tx_owner,
-       .get_rx_owner = ndesc_get_rx_owner,
-       .release_tx_desc = ndesc_release_tx_desc,
-       .prepare_tx_desc = ndesc_prepare_tx_desc,
-       .clear_tx_ic = ndesc_clear_tx_ic,
-       .close_tx_desc = ndesc_close_tx_desc,
-       .get_tx_ls = ndesc_get_tx_ls,
-       .set_tx_owner = ndesc_set_tx_owner,
-       .set_rx_owner = ndesc_set_rx_owner,
-       .get_rx_frame_len = ndesc_get_rx_frame_len,
-};
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
deleted file mode 100644 (file)
index de1929b..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#define DRV_MODULE_VERSION     "July_2011"
-#include <linux/stmmac.h>
-
-#include "common.h"
-#ifdef CONFIG_STMMAC_TIMER
-#include "stmmac_timer.h"
-#endif
-
-struct stmmac_priv {
-       /* Frequently used values are kept adjacent for cache effect */
-       struct dma_desc *dma_tx ____cacheline_aligned;
-       dma_addr_t dma_tx_phy;
-       struct sk_buff **tx_skbuff;
-       unsigned int cur_tx;
-       unsigned int dirty_tx;
-       unsigned int dma_tx_size;
-       int tx_coalesce;
-
-       struct dma_desc *dma_rx ;
-       unsigned int cur_rx;
-       unsigned int dirty_rx;
-       struct sk_buff **rx_skbuff;
-       dma_addr_t *rx_skbuff_dma;
-       struct sk_buff_head rx_recycle;
-
-       struct net_device *dev;
-       dma_addr_t dma_rx_phy;
-       unsigned int dma_rx_size;
-       unsigned int dma_buf_sz;
-       struct device *device;
-       struct mac_device_info *hw;
-       void __iomem *ioaddr;
-
-       struct stmmac_extra_stats xstats;
-       struct napi_struct napi;
-
-       int rx_coe;
-       int no_csum_insertion;
-
-       struct phy_device *phydev;
-       int oldlink;
-       int speed;
-       int oldduplex;
-       unsigned int flow_ctrl;
-       unsigned int pause;
-       struct mii_bus *mii;
-       int mii_irq[PHY_MAX_ADDR];
-
-       u32 msg_enable;
-       spinlock_t lock;
-       int wolopts;
-       int wolenabled;
-#ifdef CONFIG_STMMAC_TIMER
-       struct stmmac_timer *tm;
-#endif
-       struct plat_stmmacenet_data *plat;
-};
-
-extern int stmmac_mdio_unregister(struct net_device *ndev);
-extern int stmmac_mdio_register(struct net_device *ndev);
-extern void stmmac_set_ethtool_ops(struct net_device *netdev);
-extern const struct stmmac_desc_ops enh_desc_ops;
-extern const struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
deleted file mode 100644 (file)
index 7ed8fb6..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-/*******************************************************************************
-  STMMAC Ethtool support
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/interrupt.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <asm/io.h>
-
-#include "stmmac.h"
-#include "dwmac_dma.h"
-
-#define REG_SPACE_SIZE 0x1054
-#define MAC100_ETHTOOL_NAME    "st_mac100"
-#define GMAC_ETHTOOL_NAME      "st_gmac"
-
-struct stmmac_stats {
-       char stat_string[ETH_GSTRING_LEN];
-       int sizeof_stat;
-       int stat_offset;
-};
-
-#define STMMAC_STAT(m) \
-       { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m),       \
-       offsetof(struct stmmac_priv, xstats.m)}
-
-static const struct  stmmac_stats stmmac_gstrings_stats[] = {
-       STMMAC_STAT(tx_underflow),
-       STMMAC_STAT(tx_carrier),
-       STMMAC_STAT(tx_losscarrier),
-       STMMAC_STAT(tx_heartbeat),
-       STMMAC_STAT(tx_deferred),
-       STMMAC_STAT(tx_vlan),
-       STMMAC_STAT(rx_vlan),
-       STMMAC_STAT(tx_jabber),
-       STMMAC_STAT(tx_frame_flushed),
-       STMMAC_STAT(tx_payload_error),
-       STMMAC_STAT(tx_ip_header_error),
-       STMMAC_STAT(rx_desc),
-       STMMAC_STAT(rx_partial),
-       STMMAC_STAT(rx_runt),
-       STMMAC_STAT(rx_toolong),
-       STMMAC_STAT(rx_collision),
-       STMMAC_STAT(rx_crc),
-       STMMAC_STAT(rx_length),
-       STMMAC_STAT(rx_mii),
-       STMMAC_STAT(rx_multicast),
-       STMMAC_STAT(rx_gmac_overflow),
-       STMMAC_STAT(rx_watchdog),
-       STMMAC_STAT(da_rx_filter_fail),
-       STMMAC_STAT(sa_rx_filter_fail),
-       STMMAC_STAT(rx_missed_cntr),
-       STMMAC_STAT(rx_overflow_cntr),
-       STMMAC_STAT(tx_undeflow_irq),
-       STMMAC_STAT(tx_process_stopped_irq),
-       STMMAC_STAT(tx_jabber_irq),
-       STMMAC_STAT(rx_overflow_irq),
-       STMMAC_STAT(rx_buf_unav_irq),
-       STMMAC_STAT(rx_process_stopped_irq),
-       STMMAC_STAT(rx_watchdog_irq),
-       STMMAC_STAT(tx_early_irq),
-       STMMAC_STAT(fatal_bus_error_irq),
-       STMMAC_STAT(threshold),
-       STMMAC_STAT(tx_pkt_n),
-       STMMAC_STAT(rx_pkt_n),
-       STMMAC_STAT(poll_n),
-       STMMAC_STAT(sched_timer_n),
-       STMMAC_STAT(normal_irq_n),
-};
-#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
-
-static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
-                                     struct ethtool_drvinfo *info)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       if (!priv->plat->has_gmac)
-               strcpy(info->driver, MAC100_ETHTOOL_NAME);
-       else
-               strcpy(info->driver, GMAC_ETHTOOL_NAME);
-
-       strcpy(info->version, DRV_MODULE_VERSION);
-       info->fw_version[0] = '\0';
-       info->n_stats = STMMAC_STATS_LEN;
-}
-
-static int stmmac_ethtool_getsettings(struct net_device *dev,
-                                     struct ethtool_cmd *cmd)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       struct phy_device *phy = priv->phydev;
-       int rc;
-       if (phy == NULL) {
-               pr_err("%s: %s: PHY is not registered\n",
-                      __func__, dev->name);
-               return -ENODEV;
-       }
-       if (!netif_running(dev)) {
-               pr_err("%s: interface is disabled: we cannot track "
-               "link speed / duplex setting\n", dev->name);
-               return -EBUSY;
-       }
-       cmd->transceiver = XCVR_INTERNAL;
-       spin_lock_irq(&priv->lock);
-       rc = phy_ethtool_gset(phy, cmd);
-       spin_unlock_irq(&priv->lock);
-       return rc;
-}
-
-static int stmmac_ethtool_setsettings(struct net_device *dev,
-                                     struct ethtool_cmd *cmd)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       struct phy_device *phy = priv->phydev;
-       int rc;
-
-       spin_lock(&priv->lock);
-       rc = phy_ethtool_sset(phy, cmd);
-       spin_unlock(&priv->lock);
-
-       return rc;
-}
-
-static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       return priv->msg_enable;
-}
-
-static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       priv->msg_enable = level;
-
-}
-
-static int stmmac_check_if_running(struct net_device *dev)
-{
-       if (!netif_running(dev))
-               return -EBUSY;
-       return 0;
-}
-
-static int stmmac_ethtool_get_regs_len(struct net_device *dev)
-{
-       return REG_SPACE_SIZE;
-}
-
-static void stmmac_ethtool_gregs(struct net_device *dev,
-                         struct ethtool_regs *regs, void *space)
-{
-       int i;
-       u32 *reg_space = (u32 *) space;
-
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       memset(reg_space, 0x0, REG_SPACE_SIZE);
-
-       if (!priv->plat->has_gmac) {
-               /* MAC registers */
-               for (i = 0; i < 12; i++)
-                       reg_space[i] = readl(priv->ioaddr + (i * 4));
-               /* DMA registers */
-               for (i = 0; i < 9; i++)
-                       reg_space[i + 12] =
-                           readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
-               reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR);
-               reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR);
-       } else {
-               /* MAC registers */
-               for (i = 0; i < 55; i++)
-                       reg_space[i] = readl(priv->ioaddr + (i * 4));
-               /* DMA registers */
-               for (i = 0; i < 22; i++)
-                       reg_space[i + 55] =
-                           readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
-       }
-}
-
-static void
-stmmac_get_pauseparam(struct net_device *netdev,
-                     struct ethtool_pauseparam *pause)
-{
-       struct stmmac_priv *priv = netdev_priv(netdev);
-
-       spin_lock(&priv->lock);
-
-       pause->rx_pause = 0;
-       pause->tx_pause = 0;
-       pause->autoneg = priv->phydev->autoneg;
-
-       if (priv->flow_ctrl & FLOW_RX)
-               pause->rx_pause = 1;
-       if (priv->flow_ctrl & FLOW_TX)
-               pause->tx_pause = 1;
-
-       spin_unlock(&priv->lock);
-}
-
-static int
-stmmac_set_pauseparam(struct net_device *netdev,
-                     struct ethtool_pauseparam *pause)
-{
-       struct stmmac_priv *priv = netdev_priv(netdev);
-       struct phy_device *phy = priv->phydev;
-       int new_pause = FLOW_OFF;
-       int ret = 0;
-
-       spin_lock(&priv->lock);
-
-       if (pause->rx_pause)
-               new_pause |= FLOW_RX;
-       if (pause->tx_pause)
-               new_pause |= FLOW_TX;
-
-       priv->flow_ctrl = new_pause;
-       phy->autoneg = pause->autoneg;
-
-       if (phy->autoneg) {
-               if (netif_running(netdev))
-                       ret = phy_start_aneg(phy);
-       } else
-               priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
-                                        priv->flow_ctrl, priv->pause);
-       spin_unlock(&priv->lock);
-       return ret;
-}
-
-static void stmmac_get_ethtool_stats(struct net_device *dev,
-                                struct ethtool_stats *dummy, u64 *data)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       int i;
-
-       /* Update HW stats if supported */
-       priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
-                                        priv->ioaddr);
-
-       for (i = 0; i < STMMAC_STATS_LEN; i++) {
-               char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
-               data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
-               sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
-       }
-}
-
-static int stmmac_get_sset_count(struct net_device *netdev, int sset)
-{
-       switch (sset) {
-       case ETH_SS_STATS:
-               return STMMAC_STATS_LEN;
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-{
-       int i;
-       u8 *p = data;
-
-       switch (stringset) {
-       case ETH_SS_STATS:
-               for (i = 0; i < STMMAC_STATS_LEN; i++) {
-                       memcpy(p, stmmac_gstrings_stats[i].stat_string,
-                               ETH_GSTRING_LEN);
-                       p += ETH_GSTRING_LEN;
-               }
-               break;
-       default:
-               WARN_ON(1);
-               break;
-       }
-}
-
-/* Currently only support WOL through Magic packet. */
-static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       spin_lock_irq(&priv->lock);
-       if (device_can_wakeup(priv->device)) {
-               wol->supported = WAKE_MAGIC | WAKE_UCAST;
-               wol->wolopts = priv->wolopts;
-       }
-       spin_unlock_irq(&priv->lock);
-}
-
-static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       u32 support = WAKE_MAGIC | WAKE_UCAST;
-
-       if (!device_can_wakeup(priv->device))
-               return -EINVAL;
-
-       if (wol->wolopts & ~support)
-               return -EINVAL;
-
-       if (wol->wolopts) {
-               pr_info("stmmac: wakeup enable\n");
-               device_set_wakeup_enable(priv->device, 1);
-               enable_irq_wake(dev->irq);
-       } else {
-               device_set_wakeup_enable(priv->device, 0);
-               disable_irq_wake(dev->irq);
-       }
-
-       spin_lock_irq(&priv->lock);
-       priv->wolopts = wol->wolopts;
-       spin_unlock_irq(&priv->lock);
-
-       return 0;
-}
-
-static struct ethtool_ops stmmac_ethtool_ops = {
-       .begin = stmmac_check_if_running,
-       .get_drvinfo = stmmac_ethtool_getdrvinfo,
-       .get_settings = stmmac_ethtool_getsettings,
-       .set_settings = stmmac_ethtool_setsettings,
-       .get_msglevel = stmmac_ethtool_getmsglevel,
-       .set_msglevel = stmmac_ethtool_setmsglevel,
-       .get_regs = stmmac_ethtool_gregs,
-       .get_regs_len = stmmac_ethtool_get_regs_len,
-       .get_link = ethtool_op_get_link,
-       .get_pauseparam = stmmac_get_pauseparam,
-       .set_pauseparam = stmmac_set_pauseparam,
-       .get_ethtool_stats = stmmac_get_ethtool_stats,
-       .get_strings = stmmac_get_strings,
-       .get_wol = stmmac_get_wol,
-       .set_wol = stmmac_set_wol,
-       .get_sset_count = stmmac_get_sset_count,
-};
-
-void stmmac_set_ethtool_ops(struct net_device *netdev)
-{
-       SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
-}
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
deleted file mode 100644 (file)
index c6e567e..0000000
+++ /dev/null
@@ -1,1895 +0,0 @@
-/*******************************************************************************
-  This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
-  ST Ethernet IPs are built around a Synopsys IP Core.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-
-  Documentation available at:
-       http://www.stlinux.com
-  Support available at:
-       https://bugzilla.stlinux.com/
-*******************************************************************************/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/etherdevice.h>
-#include <linux/platform_device.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/if_ether.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/if_vlan.h>
-#include <linux/dma-mapping.h>
-#include <linux/slab.h>
-#include <linux/prefetch.h>
-#include "stmmac.h"
-
-#define STMMAC_RESOURCE_NAME   "stmmaceth"
-
-#undef STMMAC_DEBUG
-/*#define STMMAC_DEBUG*/
-#ifdef STMMAC_DEBUG
-#define DBG(nlevel, klevel, fmt, args...) \
-               ((void)(netif_msg_##nlevel(priv) && \
-               printk(KERN_##klevel fmt, ## args)))
-#else
-#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
-#endif
-
-#undef STMMAC_RX_DEBUG
-/*#define STMMAC_RX_DEBUG*/
-#ifdef STMMAC_RX_DEBUG
-#define RX_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define RX_DBG(fmt, args...)  do { } while (0)
-#endif
-
-#undef STMMAC_XMIT_DEBUG
-/*#define STMMAC_XMIT_DEBUG*/
-#ifdef STMMAC_TX_DEBUG
-#define TX_DBG(fmt, args...)  printk(fmt, ## args)
-#else
-#define TX_DBG(fmt, args...)  do { } while (0)
-#endif
-
-#define STMMAC_ALIGN(x)        L1_CACHE_ALIGN(x)
-#define JUMBO_LEN      9000
-
-/* Module parameters */
-#define TX_TIMEO 5000 /* default 5 seconds */
-static int watchdog = TX_TIMEO;
-module_param(watchdog, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
-
-static int debug = -1;         /* -1: default, 0: no output, 16:  all */
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
-
-static int phyaddr = -1;
-module_param(phyaddr, int, S_IRUGO);
-MODULE_PARM_DESC(phyaddr, "Physical device address");
-
-#define DMA_TX_SIZE 256
-static int dma_txsize = DMA_TX_SIZE;
-module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
-
-#define DMA_RX_SIZE 256
-static int dma_rxsize = DMA_RX_SIZE;
-module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
-
-static int flow_ctrl = FLOW_OFF;
-module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
-
-static int pause = PAUSE_TIME;
-module_param(pause, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(pause, "Flow Control Pause Time");
-
-#define TC_DEFAULT 64
-static int tc = TC_DEFAULT;
-module_param(tc, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(tc, "DMA threshold control value");
-
-/* Pay attention to tune this parameter; take care of both
- * hardware capability and network stabitily/performance impact.
- * Many tests showed that ~4ms latency seems to be good enough. */
-#ifdef CONFIG_STMMAC_TIMER
-#define DEFAULT_PERIODIC_RATE  256
-static int tmrate = DEFAULT_PERIODIC_RATE;
-module_param(tmrate, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
-#endif
-
-#define DMA_BUFFER_SIZE        BUF_SIZE_2KiB
-static int buf_sz = DMA_BUFFER_SIZE;
-module_param(buf_sz, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(buf_sz, "DMA buffer size");
-
-static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
-                                     NETIF_MSG_LINK | NETIF_MSG_IFUP |
-                                     NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
-
-static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
-
-/**
- * stmmac_verify_args - verify the driver parameters.
- * Description: it verifies if some wrong parameter is passed to the driver.
- * Note that wrong parameters are replaced with the default values.
- */
-static void stmmac_verify_args(void)
-{
-       if (unlikely(watchdog < 0))
-               watchdog = TX_TIMEO;
-       if (unlikely(dma_rxsize < 0))
-               dma_rxsize = DMA_RX_SIZE;
-       if (unlikely(dma_txsize < 0))
-               dma_txsize = DMA_TX_SIZE;
-       if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
-               buf_sz = DMA_BUFFER_SIZE;
-       if (unlikely(flow_ctrl > 1))
-               flow_ctrl = FLOW_AUTO;
-       else if (likely(flow_ctrl < 0))
-               flow_ctrl = FLOW_OFF;
-       if (unlikely((pause < 0) || (pause > 0xffff)))
-               pause = PAUSE_TIME;
-}
-
-#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
-static void print_pkt(unsigned char *buf, int len)
-{
-       int j;
-       pr_info("len = %d byte, buf addr: 0x%p", len, buf);
-       for (j = 0; j < len; j++) {
-               if ((j % 16) == 0)
-                       pr_info("\n %03x:", j);
-               pr_info(" %02x", buf[j]);
-       }
-       pr_info("\n");
-}
-#endif
-
-/* minimum number of free TX descriptors required to wake up TX process */
-#define STMMAC_TX_THRESH(x)    (x->dma_tx_size/4)
-
-static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
-{
-       return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
-}
-
-/* On some ST platforms, some HW system configuraton registers have to be
- * set according to the link speed negotiated.
- */
-static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
-{
-       struct phy_device *phydev = priv->phydev;
-
-       if (likely(priv->plat->fix_mac_speed))
-               priv->plat->fix_mac_speed(priv->plat->bsp_priv,
-                                         phydev->speed);
-}
-
-/**
- * stmmac_adjust_link
- * @dev: net device structure
- * Description: it adjusts the link parameters.
- */
-static void stmmac_adjust_link(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       struct phy_device *phydev = priv->phydev;
-       unsigned long flags;
-       int new_state = 0;
-       unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
-
-       if (phydev == NULL)
-               return;
-
-       DBG(probe, DEBUG, "stmmac_adjust_link: called.  address %d link %d\n",
-           phydev->addr, phydev->link);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       if (phydev->link) {
-               u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
-
-               /* Now we make sure that we can be in full duplex mode.
-                * If not, we operate in half-duplex mode. */
-               if (phydev->duplex != priv->oldduplex) {
-                       new_state = 1;
-                       if (!(phydev->duplex))
-                               ctrl &= ~priv->hw->link.duplex;
-                       else
-                               ctrl |= priv->hw->link.duplex;
-                       priv->oldduplex = phydev->duplex;
-               }
-               /* Flow Control operation */
-               if (phydev->pause)
-                       priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
-                                                fc, pause_time);
-
-               if (phydev->speed != priv->speed) {
-                       new_state = 1;
-                       switch (phydev->speed) {
-                       case 1000:
-                               if (likely(priv->plat->has_gmac))
-                                       ctrl &= ~priv->hw->link.port;
-                               stmmac_hw_fix_mac_speed(priv);
-                               break;
-                       case 100:
-                       case 10:
-                               if (priv->plat->has_gmac) {
-                                       ctrl |= priv->hw->link.port;
-                                       if (phydev->speed == SPEED_100) {
-                                               ctrl |= priv->hw->link.speed;
-                                       } else {
-                                               ctrl &= ~(priv->hw->link.speed);
-                                       }
-                               } else {
-                                       ctrl &= ~priv->hw->link.port;
-                               }
-                               stmmac_hw_fix_mac_speed(priv);
-                               break;
-                       default:
-                               if (netif_msg_link(priv))
-                                       pr_warning("%s: Speed (%d) is not 10"
-                                      " or 100!\n", dev->name, phydev->speed);
-                               break;
-                       }
-
-                       priv->speed = phydev->speed;
-               }
-
-               writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
-
-               if (!priv->oldlink) {
-                       new_state = 1;
-                       priv->oldlink = 1;
-               }
-       } else if (priv->oldlink) {
-               new_state = 1;
-               priv->oldlink = 0;
-               priv->speed = 0;
-               priv->oldduplex = -1;
-       }
-
-       if (new_state && netif_msg_link(priv))
-               phy_print_status(phydev);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
-}
-
-/**
- * stmmac_init_phy - PHY initialization
- * @dev: net device structure
- * Description: it initializes the driver's PHY state, and attaches the PHY
- * to the mac driver.
- *  Return value:
- *  0 on success
- */
-static int stmmac_init_phy(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       struct phy_device *phydev;
-       char phy_id[MII_BUS_ID_SIZE + 3];
-       char bus_id[MII_BUS_ID_SIZE];
-
-       priv->oldlink = 0;
-       priv->speed = 0;
-       priv->oldduplex = -1;
-
-       snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
-       snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
-                priv->plat->phy_addr);
-       pr_debug("stmmac_init_phy:  trying to attach to %s\n", phy_id);
-
-       phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
-                            priv->plat->interface);
-
-       if (IS_ERR(phydev)) {
-               pr_err("%s: Could not attach to PHY\n", dev->name);
-               return PTR_ERR(phydev);
-       }
-
-       /*
-        * Broken HW is sometimes missing the pull-up resistor on the
-        * MDIO line, which results in reads to non-existent devices returning
-        * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
-        * device as well.
-        * Note: phydev->phy_id is the result of reading the UID PHY registers.
-        */
-       if (phydev->phy_id == 0) {
-               phy_disconnect(phydev);
-               return -ENODEV;
-       }
-       pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
-                " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
-
-       priv->phydev = phydev;
-
-       return 0;
-}
-
-static inline void stmmac_enable_mac(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + MAC_CTRL_REG);
-
-       value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
-       writel(value, ioaddr + MAC_CTRL_REG);
-}
-
-static inline void stmmac_disable_mac(void __iomem *ioaddr)
-{
-       u32 value = readl(ioaddr + MAC_CTRL_REG);
-
-       value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
-       writel(value, ioaddr + MAC_CTRL_REG);
-}
-
-/**
- * display_ring
- * @p: pointer to the ring.
- * @size: size of the ring.
- * Description: display all the descriptors within the ring.
- */
-static void display_ring(struct dma_desc *p, int size)
-{
-       struct tmp_s {
-               u64 a;
-               unsigned int b;
-               unsigned int c;
-       };
-       int i;
-       for (i = 0; i < size; i++) {
-               struct tmp_s *x = (struct tmp_s *)(p + i);
-               pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
-                      i, (unsigned int)virt_to_phys(&p[i]),
-                      (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
-                      x->b, x->c);
-               pr_info("\n");
-       }
-}
-
-/**
- * init_dma_desc_rings - init the RX/TX descriptor rings
- * @dev: net device structure
- * Description:  this function initializes the DMA RX/TX descriptors
- * and allocates the socket buffers.
- */
-static void init_dma_desc_rings(struct net_device *dev)
-{
-       int i;
-       struct stmmac_priv *priv = netdev_priv(dev);
-       struct sk_buff *skb;
-       unsigned int txsize = priv->dma_tx_size;
-       unsigned int rxsize = priv->dma_rx_size;
-       unsigned int bfsize = priv->dma_buf_sz;
-       int buff2_needed = 0, dis_ic = 0;
-
-       /* Set the Buffer size according to the MTU;
-        * indeed, in case of jumbo we need to bump-up the buffer sizes.
-        */
-       if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
-               bfsize = BUF_SIZE_16KiB;
-       else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
-               bfsize = BUF_SIZE_8KiB;
-       else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
-               bfsize = BUF_SIZE_4KiB;
-       else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
-               bfsize = BUF_SIZE_2KiB;
-       else
-               bfsize = DMA_BUFFER_SIZE;
-
-#ifdef CONFIG_STMMAC_TIMER
-       /* Disable interrupts on completion for the reception if timer is on */
-       if (likely(priv->tm->enable))
-               dis_ic = 1;
-#endif
-       /* If the MTU exceeds 8k so use the second buffer in the chain */
-       if (bfsize >= BUF_SIZE_8KiB)
-               buff2_needed = 1;
-
-       DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
-           txsize, rxsize, bfsize);
-
-       priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
-       priv->rx_skbuff =
-           kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
-       priv->dma_rx =
-           (struct dma_desc *)dma_alloc_coherent(priv->device,
-                                                 rxsize *
-                                                 sizeof(struct dma_desc),
-                                                 &priv->dma_rx_phy,
-                                                 GFP_KERNEL);
-       priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
-                                      GFP_KERNEL);
-       priv->dma_tx =
-           (struct dma_desc *)dma_alloc_coherent(priv->device,
-                                                 txsize *
-                                                 sizeof(struct dma_desc),
-                                                 &priv->dma_tx_phy,
-                                                 GFP_KERNEL);
-
-       if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
-               pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
-               return;
-       }
-
-       DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
-           "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
-           dev->name, priv->dma_rx, priv->dma_tx,
-           (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
-
-       /* RX INITIALIZATION */
-       DBG(probe, INFO, "stmmac: SKB addresses:\n"
-                        "skb\t\tskb data\tdma data\n");
-
-       for (i = 0; i < rxsize; i++) {
-               struct dma_desc *p = priv->dma_rx + i;
-
-               skb = netdev_alloc_skb_ip_align(dev, bfsize);
-               if (unlikely(skb == NULL)) {
-                       pr_err("%s: Rx init fails; skb is NULL\n", __func__);
-                       break;
-               }
-               priv->rx_skbuff[i] = skb;
-               priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
-                                               bfsize, DMA_FROM_DEVICE);
-
-               p->des2 = priv->rx_skbuff_dma[i];
-               if (unlikely(buff2_needed))
-                       p->des3 = p->des2 + BUF_SIZE_8KiB;
-               DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
-                       priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
-       }
-       priv->cur_rx = 0;
-       priv->dirty_rx = (unsigned int)(i - rxsize);
-       priv->dma_buf_sz = bfsize;
-       buf_sz = bfsize;
-
-       /* TX INITIALIZATION */
-       for (i = 0; i < txsize; i++) {
-               priv->tx_skbuff[i] = NULL;
-               priv->dma_tx[i].des2 = 0;
-       }
-       priv->dirty_tx = 0;
-       priv->cur_tx = 0;
-
-       /* Clear the Rx/Tx descriptors */
-       priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
-       priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
-
-       if (netif_msg_hw(priv)) {
-               pr_info("RX descriptor ring:\n");
-               display_ring(priv->dma_rx, rxsize);
-               pr_info("TX descriptor ring:\n");
-               display_ring(priv->dma_tx, txsize);
-       }
-}
-
-static void dma_free_rx_skbufs(struct stmmac_priv *priv)
-{
-       int i;
-
-       for (i = 0; i < priv->dma_rx_size; i++) {
-               if (priv->rx_skbuff[i]) {
-                       dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
-                                        priv->dma_buf_sz, DMA_FROM_DEVICE);
-                       dev_kfree_skb_any(priv->rx_skbuff[i]);
-               }
-               priv->rx_skbuff[i] = NULL;
-       }
-}
-
-static void dma_free_tx_skbufs(struct stmmac_priv *priv)
-{
-       int i;
-
-       for (i = 0; i < priv->dma_tx_size; i++) {
-               if (priv->tx_skbuff[i] != NULL) {
-                       struct dma_desc *p = priv->dma_tx + i;
-                       if (p->des2)
-                               dma_unmap_single(priv->device, p->des2,
-                                                priv->hw->desc->get_tx_len(p),
-                                                DMA_TO_DEVICE);
-                       dev_kfree_skb_any(priv->tx_skbuff[i]);
-                       priv->tx_skbuff[i] = NULL;
-               }
-       }
-}
-
-static void free_dma_desc_resources(struct stmmac_priv *priv)
-{
-       /* Release the DMA TX/RX socket buffers */
-       dma_free_rx_skbufs(priv);
-       dma_free_tx_skbufs(priv);
-
-       /* Free the region of consistent memory previously allocated for
-        * the DMA */
-       dma_free_coherent(priv->device,
-                         priv->dma_tx_size * sizeof(struct dma_desc),
-                         priv->dma_tx, priv->dma_tx_phy);
-       dma_free_coherent(priv->device,
-                         priv->dma_rx_size * sizeof(struct dma_desc),
-                         priv->dma_rx, priv->dma_rx_phy);
-       kfree(priv->rx_skbuff_dma);
-       kfree(priv->rx_skbuff);
-       kfree(priv->tx_skbuff);
-}
-
-/**
- *  stmmac_dma_operation_mode - HW DMA operation mode
- *  @priv : pointer to the private device structure.
- *  Description: it sets the DMA operation mode: tx/rx DMA thresholds
- *  or Store-And-Forward capability.
- */
-static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
-{
-       if (likely(priv->plat->force_sf_dma_mode ||
-               ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) {
-               /*
-                * In case of GMAC, SF mode can be enabled
-                * to perform the TX COE in HW. This depends on:
-                * 1) TX COE if actually supported
-                * 2) There is no bugged Jumbo frame support
-                *    that needs to not insert csum in the TDES.
-                */
-               priv->hw->dma->dma_mode(priv->ioaddr,
-                                       SF_DMA_MODE, SF_DMA_MODE);
-               tc = SF_DMA_MODE;
-       } else
-               priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
-}
-
-/**
- * stmmac_tx:
- * @priv: private driver structure
- * Description: it reclaims resources after transmission completes.
- */
-static void stmmac_tx(struct stmmac_priv *priv)
-{
-       unsigned int txsize = priv->dma_tx_size;
-
-       while (priv->dirty_tx != priv->cur_tx) {
-               int last;
-               unsigned int entry = priv->dirty_tx % txsize;
-               struct sk_buff *skb = priv->tx_skbuff[entry];
-               struct dma_desc *p = priv->dma_tx + entry;
-
-               /* Check if the descriptor is owned by the DMA. */
-               if (priv->hw->desc->get_tx_owner(p))
-                       break;
-
-               /* Verify tx error by looking at the last segment */
-               last = priv->hw->desc->get_tx_ls(p);
-               if (likely(last)) {
-                       int tx_error =
-                               priv->hw->desc->tx_status(&priv->dev->stats,
-                                                         &priv->xstats, p,
-                                                         priv->ioaddr);
-                       if (likely(tx_error == 0)) {
-                               priv->dev->stats.tx_packets++;
-                               priv->xstats.tx_pkt_n++;
-                       } else
-                               priv->dev->stats.tx_errors++;
-               }
-               TX_DBG("%s: curr %d, dirty %d\n", __func__,
-                       priv->cur_tx, priv->dirty_tx);
-
-               if (likely(p->des2))
-                       dma_unmap_single(priv->device, p->des2,
-                                        priv->hw->desc->get_tx_len(p),
-                                        DMA_TO_DEVICE);
-               if (unlikely(p->des3))
-                       p->des3 = 0;
-
-               if (likely(skb != NULL)) {
-                       /*
-                        * If there's room in the queue (limit it to size)
-                        * we add this skb back into the pool,
-                        * if it's the right size.
-                        */
-                       if ((skb_queue_len(&priv->rx_recycle) <
-                               priv->dma_rx_size) &&
-                               skb_recycle_check(skb, priv->dma_buf_sz))
-                               __skb_queue_head(&priv->rx_recycle, skb);
-                       else
-                               dev_kfree_skb(skb);
-
-                       priv->tx_skbuff[entry] = NULL;
-               }
-
-               priv->hw->desc->release_tx_desc(p);
-
-               entry = (++priv->dirty_tx) % txsize;
-       }
-       if (unlikely(netif_queue_stopped(priv->dev) &&
-                    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
-               netif_tx_lock(priv->dev);
-               if (netif_queue_stopped(priv->dev) &&
-                    stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
-                       TX_DBG("%s: restart transmit\n", __func__);
-                       netif_wake_queue(priv->dev);
-               }
-               netif_tx_unlock(priv->dev);
-       }
-}
-
-static inline void stmmac_enable_irq(struct stmmac_priv *priv)
-{
-#ifdef CONFIG_STMMAC_TIMER
-       if (likely(priv->tm->enable))
-               priv->tm->timer_start(tmrate);
-       else
-#endif
-               priv->hw->dma->enable_dma_irq(priv->ioaddr);
-}
-
-static inline void stmmac_disable_irq(struct stmmac_priv *priv)
-{
-#ifdef CONFIG_STMMAC_TIMER
-       if (likely(priv->tm->enable))
-               priv->tm->timer_stop();
-       else
-#endif
-               priv->hw->dma->disable_dma_irq(priv->ioaddr);
-}
-
-static int stmmac_has_work(struct stmmac_priv *priv)
-{
-       unsigned int has_work = 0;
-       int rxret, tx_work = 0;
-
-       rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
-               (priv->cur_rx % priv->dma_rx_size));
-
-       if (priv->dirty_tx != priv->cur_tx)
-               tx_work = 1;
-
-       if (likely(!rxret || tx_work))
-               has_work = 1;
-
-       return has_work;
-}
-
-static inline void _stmmac_schedule(struct stmmac_priv *priv)
-{
-       if (likely(stmmac_has_work(priv))) {
-               stmmac_disable_irq(priv);
-               napi_schedule(&priv->napi);
-       }
-}
-
-#ifdef CONFIG_STMMAC_TIMER
-void stmmac_schedule(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       priv->xstats.sched_timer_n++;
-
-       _stmmac_schedule(priv);
-}
-
-static void stmmac_no_timer_started(unsigned int x)
-{;
-};
-
-static void stmmac_no_timer_stopped(void)
-{;
-};
-#endif
-
-/**
- * stmmac_tx_err:
- * @priv: pointer to the private device structure
- * Description: it cleans the descriptors and restarts the transmission
- * in case of errors.
- */
-static void stmmac_tx_err(struct stmmac_priv *priv)
-{
-
-       netif_stop_queue(priv->dev);
-
-       priv->hw->dma->stop_tx(priv->ioaddr);
-       dma_free_tx_skbufs(priv);
-       priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
-       priv->dirty_tx = 0;
-       priv->cur_tx = 0;
-       priv->hw->dma->start_tx(priv->ioaddr);
-
-       priv->dev->stats.tx_errors++;
-       netif_wake_queue(priv->dev);
-}
-
-
-static void stmmac_dma_interrupt(struct stmmac_priv *priv)
-{
-       int status;
-
-       status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
-       if (likely(status == handle_tx_rx))
-               _stmmac_schedule(priv);
-
-       else if (unlikely(status == tx_hard_error_bump_tc)) {
-               /* Try to bump up the dma threshold on this failure */
-               if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
-                       tc += 64;
-                       priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
-                       priv->xstats.threshold = tc;
-               }
-       } else if (unlikely(status == tx_hard_error))
-               stmmac_tx_err(priv);
-}
-
-/**
- *  stmmac_open - open entry point of the driver
- *  @dev : pointer to the device structure.
- *  Description:
- *  This function is the open entry point of the driver.
- *  Return value:
- *  0 on success and an appropriate (-)ve integer as defined in errno.h
- *  file on failure.
- */
-static int stmmac_open(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       int ret;
-
-       /* Check that the MAC address is valid.  If its not, refuse
-        * to bring the device up. The user must specify an
-        * address using the following linux command:
-        *      ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx  */
-       if (!is_valid_ether_addr(dev->dev_addr)) {
-               random_ether_addr(dev->dev_addr);
-               pr_warning("%s: generated random MAC address %pM\n", dev->name,
-                       dev->dev_addr);
-       }
-
-       stmmac_verify_args();
-
-#ifdef CONFIG_STMMAC_TIMER
-       priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
-       if (unlikely(priv->tm == NULL)) {
-               pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
-               return -ENOMEM;
-       }
-       priv->tm->freq = tmrate;
-
-       /* Test if the external timer can be actually used.
-        * In case of failure continue without timer. */
-       if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
-               pr_warning("stmmaceth: cannot attach the external timer.\n");
-               priv->tm->freq = 0;
-               priv->tm->timer_start = stmmac_no_timer_started;
-               priv->tm->timer_stop = stmmac_no_timer_stopped;
-       } else
-               priv->tm->enable = 1;
-#endif
-       ret = stmmac_init_phy(dev);
-       if (unlikely(ret)) {
-               pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
-               goto open_error;
-       }
-
-       /* Create and initialize the TX/RX descriptors chains. */
-       priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
-       priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
-       priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
-       init_dma_desc_rings(dev);
-
-       /* DMA initialization and SW reset */
-       ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
-                                 priv->dma_tx_phy, priv->dma_rx_phy);
-       if (ret < 0) {
-               pr_err("%s: DMA initialization failed\n", __func__);
-               goto open_error;
-       }
-
-       /* Copy the MAC addr into the HW  */
-       priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
-       /* If required, perform hw setup of the bus. */
-       if (priv->plat->bus_setup)
-               priv->plat->bus_setup(priv->ioaddr);
-       /* Initialize the MAC Core */
-       priv->hw->mac->core_init(priv->ioaddr);
-
-       priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
-       if (priv->rx_coe)
-               pr_info("stmmac: Rx Checksum Offload Engine supported\n");
-       if (priv->plat->tx_coe)
-               pr_info("\tTX Checksum insertion supported\n");
-       netdev_update_features(dev);
-
-       /* Initialise the MMC (if present) to disable all interrupts. */
-       writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
-       writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
-
-       /* Request the IRQ lines */
-       ret = request_irq(dev->irq, stmmac_interrupt,
-                        IRQF_SHARED, dev->name, dev);
-       if (unlikely(ret < 0)) {
-               pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
-                      __func__, dev->irq, ret);
-               goto open_error;
-       }
-
-       /* Enable the MAC Rx/Tx */
-       stmmac_enable_mac(priv->ioaddr);
-
-       /* Set the HW DMA mode and the COE */
-       stmmac_dma_operation_mode(priv);
-
-       /* Extra statistics */
-       memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
-       priv->xstats.threshold = tc;
-
-       /* Start the ball rolling... */
-       DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
-       priv->hw->dma->start_tx(priv->ioaddr);
-       priv->hw->dma->start_rx(priv->ioaddr);
-
-#ifdef CONFIG_STMMAC_TIMER
-       priv->tm->timer_start(tmrate);
-#endif
-       /* Dump DMA/MAC registers */
-       if (netif_msg_hw(priv)) {
-               priv->hw->mac->dump_regs(priv->ioaddr);
-               priv->hw->dma->dump_regs(priv->ioaddr);
-       }
-
-       if (priv->phydev)
-               phy_start(priv->phydev);
-
-       napi_enable(&priv->napi);
-       skb_queue_head_init(&priv->rx_recycle);
-       netif_start_queue(dev);
-
-       return 0;
-
-open_error:
-#ifdef CONFIG_STMMAC_TIMER
-       kfree(priv->tm);
-#endif
-       if (priv->phydev)
-               phy_disconnect(priv->phydev);
-
-       return ret;
-}
-
-/**
- *  stmmac_release - close entry point of the driver
- *  @dev : device pointer.
- *  Description:
- *  This is the stop entry point of the driver.
- */
-static int stmmac_release(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       /* Stop and disconnect the PHY */
-       if (priv->phydev) {
-               phy_stop(priv->phydev);
-               phy_disconnect(priv->phydev);
-               priv->phydev = NULL;
-       }
-
-       netif_stop_queue(dev);
-
-#ifdef CONFIG_STMMAC_TIMER
-       /* Stop and release the timer */
-       stmmac_close_ext_timer();
-       if (priv->tm != NULL)
-               kfree(priv->tm);
-#endif
-       napi_disable(&priv->napi);
-       skb_queue_purge(&priv->rx_recycle);
-
-       /* Free the IRQ lines */
-       free_irq(dev->irq, dev);
-
-       /* Stop TX/RX DMA and clear the descriptors */
-       priv->hw->dma->stop_tx(priv->ioaddr);
-       priv->hw->dma->stop_rx(priv->ioaddr);
-
-       /* Release and free the Rx/Tx resources */
-       free_dma_desc_resources(priv);
-
-       /* Disable the MAC Rx/Tx */
-       stmmac_disable_mac(priv->ioaddr);
-
-       netif_carrier_off(dev);
-
-       return 0;
-}
-
-static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
-                                              struct net_device *dev,
-                                              int csum_insertion)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       unsigned int nopaged_len = skb_headlen(skb);
-       unsigned int txsize = priv->dma_tx_size;
-       unsigned int entry = priv->cur_tx % txsize;
-       struct dma_desc *desc = priv->dma_tx + entry;
-
-       if (nopaged_len > BUF_SIZE_8KiB) {
-
-               int buf2_size = nopaged_len - BUF_SIZE_8KiB;
-
-               desc->des2 = dma_map_single(priv->device, skb->data,
-                                           BUF_SIZE_8KiB, DMA_TO_DEVICE);
-               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
-               priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
-                                               csum_insertion);
-
-               entry = (++priv->cur_tx) % txsize;
-               desc = priv->dma_tx + entry;
-
-               desc->des2 = dma_map_single(priv->device,
-                                       skb->data + BUF_SIZE_8KiB,
-                                       buf2_size, DMA_TO_DEVICE);
-               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
-               priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
-                                               csum_insertion);
-               priv->hw->desc->set_tx_owner(desc);
-               priv->tx_skbuff[entry] = NULL;
-       } else {
-               desc->des2 = dma_map_single(priv->device, skb->data,
-                                       nopaged_len, DMA_TO_DEVICE);
-               desc->des3 = desc->des2 + BUF_SIZE_4KiB;
-               priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
-                                               csum_insertion);
-       }
-       return entry;
-}
-
-/**
- *  stmmac_xmit:
- *  @skb : the socket buffer
- *  @dev : device pointer
- *  Description : Tx entry point of the driver.
- */
-static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       unsigned int txsize = priv->dma_tx_size;
-       unsigned int entry;
-       int i, csum_insertion = 0;
-       int nfrags = skb_shinfo(skb)->nr_frags;
-       struct dma_desc *desc, *first;
-
-       if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
-               if (!netif_queue_stopped(dev)) {
-                       netif_stop_queue(dev);
-                       /* This is a hard error, log it. */
-                       pr_err("%s: BUG! Tx Ring full when queue awake\n",
-                               __func__);
-               }
-               return NETDEV_TX_BUSY;
-       }
-
-       entry = priv->cur_tx % txsize;
-
-#ifdef STMMAC_XMIT_DEBUG
-       if ((skb->len > ETH_FRAME_LEN) || nfrags)
-               pr_info("stmmac xmit:\n"
-                      "\tskb addr %p - len: %d - nopaged_len: %d\n"
-                      "\tn_frags: %d - ip_summed: %d - %s gso\n",
-                      skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
-                      !skb_is_gso(skb) ? "isn't" : "is");
-#endif
-
-       csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
-
-       desc = priv->dma_tx + entry;
-       first = desc;
-
-#ifdef STMMAC_XMIT_DEBUG
-       if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
-               pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
-                      "\t\tn_frags: %d, ip_summed: %d\n",
-                      skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
-#endif
-       priv->tx_skbuff[entry] = skb;
-       if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
-               entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
-               desc = priv->dma_tx + entry;
-       } else {
-               unsigned int nopaged_len = skb_headlen(skb);
-               desc->des2 = dma_map_single(priv->device, skb->data,
-                                       nopaged_len, DMA_TO_DEVICE);
-               priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
-                                               csum_insertion);
-       }
-
-       for (i = 0; i < nfrags; i++) {
-               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-               int len = frag->size;
-
-               entry = (++priv->cur_tx) % txsize;
-               desc = priv->dma_tx + entry;
-
-               TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
-               desc->des2 = dma_map_page(priv->device, frag->page,
-                                         frag->page_offset,
-                                         len, DMA_TO_DEVICE);
-               priv->tx_skbuff[entry] = NULL;
-               priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
-               wmb();
-               priv->hw->desc->set_tx_owner(desc);
-       }
-
-       /* Interrupt on completition only for the latest segment */
-       priv->hw->desc->close_tx_desc(desc);
-
-#ifdef CONFIG_STMMAC_TIMER
-       /* Clean IC while using timer */
-       if (likely(priv->tm->enable))
-               priv->hw->desc->clear_tx_ic(desc);
-#endif
-
-       wmb();
-
-       /* To avoid raise condition */
-       priv->hw->desc->set_tx_owner(first);
-
-       priv->cur_tx++;
-
-#ifdef STMMAC_XMIT_DEBUG
-       if (netif_msg_pktdata(priv)) {
-               pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
-                      "first=%p, nfrags=%d\n",
-                      (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
-                      entry, first, nfrags);
-               display_ring(priv->dma_tx, txsize);
-               pr_info(">>> frame to be transmitted: ");
-               print_pkt(skb->data, skb->len);
-       }
-#endif
-       if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
-               TX_DBG("%s: stop transmitted packets\n", __func__);
-               netif_stop_queue(dev);
-       }
-
-       dev->stats.tx_bytes += skb->len;
-
-       skb_tx_timestamp(skb);
-
-       priv->hw->dma->enable_dma_transmission(priv->ioaddr);
-
-       return NETDEV_TX_OK;
-}
-
-static inline void stmmac_rx_refill(struct stmmac_priv *priv)
-{
-       unsigned int rxsize = priv->dma_rx_size;
-       int bfsize = priv->dma_buf_sz;
-       struct dma_desc *p = priv->dma_rx;
-
-       for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
-               unsigned int entry = priv->dirty_rx % rxsize;
-               if (likely(priv->rx_skbuff[entry] == NULL)) {
-                       struct sk_buff *skb;
-
-                       skb = __skb_dequeue(&priv->rx_recycle);
-                       if (skb == NULL)
-                               skb = netdev_alloc_skb_ip_align(priv->dev,
-                                                               bfsize);
-
-                       if (unlikely(skb == NULL))
-                               break;
-
-                       priv->rx_skbuff[entry] = skb;
-                       priv->rx_skbuff_dma[entry] =
-                           dma_map_single(priv->device, skb->data, bfsize,
-                                          DMA_FROM_DEVICE);
-
-                       (p + entry)->des2 = priv->rx_skbuff_dma[entry];
-                       if (unlikely(priv->plat->has_gmac)) {
-                               if (bfsize >= BUF_SIZE_8KiB)
-                                       (p + entry)->des3 =
-                                           (p + entry)->des2 + BUF_SIZE_8KiB;
-                       }
-                       RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
-               }
-               wmb();
-               priv->hw->desc->set_rx_owner(p + entry);
-       }
-}
-
-static int stmmac_rx(struct stmmac_priv *priv, int limit)
-{
-       unsigned int rxsize = priv->dma_rx_size;
-       unsigned int entry = priv->cur_rx % rxsize;
-       unsigned int next_entry;
-       unsigned int count = 0;
-       struct dma_desc *p = priv->dma_rx + entry;
-       struct dma_desc *p_next;
-
-#ifdef STMMAC_RX_DEBUG
-       if (netif_msg_hw(priv)) {
-               pr_debug(">>> stmmac_rx: descriptor ring:\n");
-               display_ring(priv->dma_rx, rxsize);
-       }
-#endif
-       count = 0;
-       while (!priv->hw->desc->get_rx_owner(p)) {
-               int status;
-
-               if (count >= limit)
-                       break;
-
-               count++;
-
-               next_entry = (++priv->cur_rx) % rxsize;
-               p_next = priv->dma_rx + next_entry;
-               prefetch(p_next);
-
-               /* read the status of the incoming frame */
-               status = (priv->hw->desc->rx_status(&priv->dev->stats,
-                                                   &priv->xstats, p));
-               if (unlikely(status == discard_frame))
-                       priv->dev->stats.rx_errors++;
-               else {
-                       struct sk_buff *skb;
-                       int frame_len;
-
-                       frame_len = priv->hw->desc->get_rx_frame_len(p);
-                       /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
-                        * Type frames (LLC/LLC-SNAP) */
-                       if (unlikely(status != llc_snap))
-                               frame_len -= ETH_FCS_LEN;
-#ifdef STMMAC_RX_DEBUG
-                       if (frame_len > ETH_FRAME_LEN)
-                               pr_debug("\tRX frame size %d, COE status: %d\n",
-                                       frame_len, status);
-
-                       if (netif_msg_hw(priv))
-                               pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
-                                       p, entry, p->des2);
-#endif
-                       skb = priv->rx_skbuff[entry];
-                       if (unlikely(!skb)) {
-                               pr_err("%s: Inconsistent Rx descriptor chain\n",
-                                       priv->dev->name);
-                               priv->dev->stats.rx_dropped++;
-                               break;
-                       }
-                       prefetch(skb->data - NET_IP_ALIGN);
-                       priv->rx_skbuff[entry] = NULL;
-
-                       skb_put(skb, frame_len);
-                       dma_unmap_single(priv->device,
-                                        priv->rx_skbuff_dma[entry],
-                                        priv->dma_buf_sz, DMA_FROM_DEVICE);
-#ifdef STMMAC_RX_DEBUG
-                       if (netif_msg_pktdata(priv)) {
-                               pr_info(" frame received (%dbytes)", frame_len);
-                               print_pkt(skb->data, frame_len);
-                       }
-#endif
-                       skb->protocol = eth_type_trans(skb, priv->dev);
-
-                       if (unlikely(status == csum_none)) {
-                               /* always for the old mac 10/100 */
-                               skb_checksum_none_assert(skb);
-                               netif_receive_skb(skb);
-                       } else {
-                               skb->ip_summed = CHECKSUM_UNNECESSARY;
-                               napi_gro_receive(&priv->napi, skb);
-                       }
-
-                       priv->dev->stats.rx_packets++;
-                       priv->dev->stats.rx_bytes += frame_len;
-               }
-               entry = next_entry;
-               p = p_next;     /* use prefetched values */
-       }
-
-       stmmac_rx_refill(priv);
-
-       priv->xstats.rx_pkt_n += count;
-
-       return count;
-}
-
-/**
- *  stmmac_poll - stmmac poll method (NAPI)
- *  @napi : pointer to the napi structure.
- *  @budget : maximum number of packets that the current CPU can receive from
- *           all interfaces.
- *  Description :
- *   This function implements the the reception process.
- *   Also it runs the TX completion thread
- */
-static int stmmac_poll(struct napi_struct *napi, int budget)
-{
-       struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
-       int work_done = 0;
-
-       priv->xstats.poll_n++;
-       stmmac_tx(priv);
-       work_done = stmmac_rx(priv, budget);
-
-       if (work_done < budget) {
-               napi_complete(napi);
-               stmmac_enable_irq(priv);
-       }
-       return work_done;
-}
-
-/**
- *  stmmac_tx_timeout
- *  @dev : Pointer to net device structure
- *  Description: this function is called when a packet transmission fails to
- *   complete within a reasonable tmrate. The driver will mark the error in the
- *   netdev structure and arrange for the device to be reset to a sane state
- *   in order to transmit a new packet.
- */
-static void stmmac_tx_timeout(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       /* Clear Tx resources and restart transmitting again */
-       stmmac_tx_err(priv);
-}
-
-/* Configuration changes (passed on by ifconfig) */
-static int stmmac_config(struct net_device *dev, struct ifmap *map)
-{
-       if (dev->flags & IFF_UP)        /* can't act on a running interface */
-               return -EBUSY;
-
-       /* Don't allow changing the I/O address */
-       if (map->base_addr != dev->base_addr) {
-               pr_warning("%s: can't change I/O address\n", dev->name);
-               return -EOPNOTSUPP;
-       }
-
-       /* Don't allow changing the IRQ */
-       if (map->irq != dev->irq) {
-               pr_warning("%s: can't change IRQ number %d\n",
-                      dev->name, dev->irq);
-               return -EOPNOTSUPP;
-       }
-
-       /* ignore other fields */
-       return 0;
-}
-
-/**
- *  stmmac_multicast_list - entry point for multicast addressing
- *  @dev : pointer to the device structure
- *  Description:
- *  This function is a driver entry point which gets called by the kernel
- *  whenever multicast addresses must be enabled/disabled.
- *  Return value:
- *  void.
- */
-static void stmmac_multicast_list(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       spin_lock(&priv->lock);
-       priv->hw->mac->set_filter(dev);
-       spin_unlock(&priv->lock);
-}
-
-/**
- *  stmmac_change_mtu - entry point to change MTU size for the device.
- *  @dev : device pointer.
- *  @new_mtu : the new MTU size for the device.
- *  Description: the Maximum Transfer Unit (MTU) is used by the network layer
- *  to drive packet transmission. Ethernet has an MTU of 1500 octets
- *  (ETH_DATA_LEN). This value can be changed with ifconfig.
- *  Return value:
- *  0 on success and an appropriate (-)ve integer as defined in errno.h
- *  file on failure.
- */
-static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       int max_mtu;
-
-       if (netif_running(dev)) {
-               pr_err("%s: must be stopped to change its MTU\n", dev->name);
-               return -EBUSY;
-       }
-
-       if (priv->plat->has_gmac)
-               max_mtu = JUMBO_LEN;
-       else
-               max_mtu = ETH_DATA_LEN;
-
-       if ((new_mtu < 46) || (new_mtu > max_mtu)) {
-               pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
-               return -EINVAL;
-       }
-
-       dev->mtu = new_mtu;
-       netdev_update_features(dev);
-
-       return 0;
-}
-
-static u32 stmmac_fix_features(struct net_device *dev, u32 features)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       if (!priv->rx_coe)
-               features &= ~NETIF_F_RXCSUM;
-       if (!priv->plat->tx_coe)
-               features &= ~NETIF_F_ALL_CSUM;
-
-       /* Some GMAC devices have a bugged Jumbo frame support that
-        * needs to have the Tx COE disabled for oversized frames
-        * (due to limited buffer sizes). In this case we disable
-        * the TX csum insertionin the TDES and not use SF. */
-       if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
-               features &= ~NETIF_F_ALL_CSUM;
-
-       return features;
-}
-
-static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = (struct net_device *)dev_id;
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       if (unlikely(!dev)) {
-               pr_err("%s: invalid dev pointer\n", __func__);
-               return IRQ_NONE;
-       }
-
-       if (priv->plat->has_gmac)
-               /* To handle GMAC own interrupts */
-               priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
-
-       stmmac_dma_interrupt(priv);
-
-       return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Polling receive - used by NETCONSOLE and other diagnostic tools
- * to allow network I/O with interrupts disabled. */
-static void stmmac_poll_controller(struct net_device *dev)
-{
-       disable_irq(dev->irq);
-       stmmac_interrupt(dev->irq, dev);
-       enable_irq(dev->irq);
-}
-#endif
-
-/**
- *  stmmac_ioctl - Entry point for the Ioctl
- *  @dev: Device pointer.
- *  @rq: An IOCTL specefic structure, that can contain a pointer to
- *  a proprietary structure used to pass information to the driver.
- *  @cmd: IOCTL command
- *  Description:
- *  Currently there are no special functionality supported in IOCTL, just the
- *  phy_mii_ioctl(...) can be invoked.
- */
-static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-       int ret;
-
-       if (!netif_running(dev))
-               return -EINVAL;
-
-       if (!priv->phydev)
-               return -EINVAL;
-
-       spin_lock(&priv->lock);
-       ret = phy_mii_ioctl(priv->phydev, rq, cmd);
-       spin_unlock(&priv->lock);
-
-       return ret;
-}
-
-static const struct net_device_ops stmmac_netdev_ops = {
-       .ndo_open = stmmac_open,
-       .ndo_start_xmit = stmmac_xmit,
-       .ndo_stop = stmmac_release,
-       .ndo_change_mtu = stmmac_change_mtu,
-       .ndo_fix_features = stmmac_fix_features,
-       .ndo_set_multicast_list = stmmac_multicast_list,
-       .ndo_tx_timeout = stmmac_tx_timeout,
-       .ndo_do_ioctl = stmmac_ioctl,
-       .ndo_set_config = stmmac_config,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller = stmmac_poll_controller,
-#endif
-       .ndo_set_mac_address = eth_mac_addr,
-};
-
-/**
- * stmmac_probe - Initialization of the adapter .
- * @dev : device pointer
- * Description: The function initializes the network device structure for
- * the STMMAC driver. It also calls the low level routines
- * in order to init the HW (i.e. the DMA engine)
- */
-static int stmmac_probe(struct net_device *dev)
-{
-       int ret = 0;
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       ether_setup(dev);
-
-       dev->netdev_ops = &stmmac_netdev_ops;
-       stmmac_set_ethtool_ops(dev);
-
-       dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-       dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
-       dev->watchdog_timeo = msecs_to_jiffies(watchdog);
-#ifdef STMMAC_VLAN_TAG_USED
-       /* Both mac100 and gmac support receive VLAN tag detection */
-       dev->features |= NETIF_F_HW_VLAN_RX;
-#endif
-       priv->msg_enable = netif_msg_init(debug, default_msg_level);
-
-       if (flow_ctrl)
-               priv->flow_ctrl = FLOW_AUTO;    /* RX/TX pause on */
-
-       priv->pause = pause;
-       netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
-
-       /* Get the MAC address */
-       priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
-                                    dev->dev_addr, 0);
-
-       if (!is_valid_ether_addr(dev->dev_addr))
-               pr_warning("\tno valid MAC address;"
-                       "please, use ifconfig or nwhwconfig!\n");
-
-       spin_lock_init(&priv->lock);
-
-       ret = register_netdev(dev);
-       if (ret) {
-               pr_err("%s: ERROR %i registering the device\n",
-                      __func__, ret);
-               return -ENODEV;
-       }
-
-       DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
-           dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
-           (dev->features & NETIF_F_IP_CSUM) ? "on" : "off");
-
-       return ret;
-}
-
-/**
- * stmmac_mac_device_setup
- * @dev : device pointer
- * Description: select and initialise the mac device (mac100 or Gmac).
- */
-static int stmmac_mac_device_setup(struct net_device *dev)
-{
-       struct stmmac_priv *priv = netdev_priv(dev);
-
-       struct mac_device_info *device;
-
-       if (priv->plat->has_gmac)
-               device = dwmac1000_setup(priv->ioaddr);
-       else
-               device = dwmac100_setup(priv->ioaddr);
-
-       if (!device)
-               return -ENOMEM;
-
-       if (priv->plat->enh_desc) {
-               device->desc = &enh_desc_ops;
-               pr_info("\tEnhanced descriptor structure\n");
-       } else
-               device->desc = &ndesc_ops;
-
-       priv->hw = device;
-
-       if (device_can_wakeup(priv->device)) {
-               priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
-               enable_irq_wake(dev->irq);
-       }
-
-       return 0;
-}
-
-/**
- * stmmac_dvr_probe
- * @pdev: platform device pointer
- * Description: the driver is initialized through platform_device.
- */
-static int stmmac_dvr_probe(struct platform_device *pdev)
-{
-       int ret = 0;
-       struct resource *res;
-       void __iomem *addr = NULL;
-       struct net_device *ndev = NULL;
-       struct stmmac_priv *priv = NULL;
-       struct plat_stmmacenet_data *plat_dat;
-
-       pr_info("STMMAC driver:\n\tplatform registration... ");
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENODEV;
-       pr_info("\tdone!\n");
-
-       if (!request_mem_region(res->start, resource_size(res),
-                               pdev->name)) {
-               pr_err("%s: ERROR: memory allocation failed"
-                      "cannot get the I/O addr 0x%x\n",
-                      __func__, (unsigned int)res->start);
-               return -EBUSY;
-       }
-
-       addr = ioremap(res->start, resource_size(res));
-       if (!addr) {
-               pr_err("%s: ERROR: memory mapping failed\n", __func__);
-               ret = -ENOMEM;
-               goto out_release_region;
-       }
-
-       ndev = alloc_etherdev(sizeof(struct stmmac_priv));
-       if (!ndev) {
-               pr_err("%s: ERROR: allocating the device\n", __func__);
-               ret = -ENOMEM;
-               goto out_unmap;
-       }
-
-       SET_NETDEV_DEV(ndev, &pdev->dev);
-
-       /* Get the MAC information */
-       ndev->irq = platform_get_irq_byname(pdev, "macirq");
-       if (ndev->irq == -ENXIO) {
-               pr_err("%s: ERROR: MAC IRQ configuration "
-                      "information not found\n", __func__);
-               ret = -ENXIO;
-               goto out_free_ndev;
-       }
-
-       priv = netdev_priv(ndev);
-       priv->device = &(pdev->dev);
-       priv->dev = ndev;
-       plat_dat = pdev->dev.platform_data;
-
-       priv->plat = plat_dat;
-
-       priv->ioaddr = addr;
-
-       /* PMT module is not integrated in all the MAC devices. */
-       if (plat_dat->pmt) {
-               pr_info("\tPMT module supported\n");
-               device_set_wakeup_capable(&pdev->dev, 1);
-       }
-
-       platform_set_drvdata(pdev, ndev);
-
-       /* Set the I/O base addr */
-       ndev->base_addr = (unsigned long)addr;
-
-       /* Custom initialisation */
-       if (priv->plat->init) {
-               ret = priv->plat->init(pdev);
-               if (unlikely(ret))
-                       goto out_free_ndev;
-       }
-
-       /* MAC HW revice detection */
-       ret = stmmac_mac_device_setup(ndev);
-       if (ret < 0)
-               goto out_plat_exit;
-
-       /* Network Device Registration */
-       ret = stmmac_probe(ndev);
-       if (ret < 0)
-               goto out_plat_exit;
-
-       /* Override with kernel parameters if supplied XXX CRS XXX
-        * this needs to have multiple instances */
-       if ((phyaddr >= 0) && (phyaddr <= 31))
-               priv->plat->phy_addr = phyaddr;
-
-       pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
-              "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
-              pdev->id, ndev->irq, addr);
-
-       /* MDIO bus Registration */
-       pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
-       ret = stmmac_mdio_register(ndev);
-       if (ret < 0)
-               goto out_unregister;
-       pr_debug("registered!\n");
-       return 0;
-
-out_unregister:
-       unregister_netdev(ndev);
-out_plat_exit:
-       if (priv->plat->exit)
-               priv->plat->exit(pdev);
-out_free_ndev:
-       free_netdev(ndev);
-       platform_set_drvdata(pdev, NULL);
-out_unmap:
-       iounmap(addr);
-out_release_region:
-       release_mem_region(res->start, resource_size(res));
-
-       return ret;
-}
-
-/**
- * stmmac_dvr_remove
- * @pdev: platform device pointer
- * Description: this function resets the TX/RX processes, disables the MAC RX/TX
- * changes the link status, releases the DMA descriptor rings,
- * unregisters the MDIO bus and unmaps the allocated memory.
- */
-static int stmmac_dvr_remove(struct platform_device *pdev)
-{
-       struct net_device *ndev = platform_get_drvdata(pdev);
-       struct stmmac_priv *priv = netdev_priv(ndev);
-       struct resource *res;
-
-       pr_info("%s:\n\tremoving driver", __func__);
-
-       priv->hw->dma->stop_rx(priv->ioaddr);
-       priv->hw->dma->stop_tx(priv->ioaddr);
-
-       stmmac_disable_mac(priv->ioaddr);
-
-       netif_carrier_off(ndev);
-
-       stmmac_mdio_unregister(ndev);
-
-       if (priv->plat->exit)
-               priv->plat->exit(pdev);
-
-       platform_set_drvdata(pdev, NULL);
-       unregister_netdev(ndev);
-
-       iounmap((void *)priv->ioaddr);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, resource_size(res));
-
-       free_netdev(ndev);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int stmmac_suspend(struct device *dev)
-{
-       struct net_device *ndev = dev_get_drvdata(dev);
-       struct stmmac_priv *priv = netdev_priv(ndev);
-       int dis_ic = 0;
-
-       if (!ndev || !netif_running(ndev))
-               return 0;
-
-       spin_lock(&priv->lock);
-
-       netif_device_detach(ndev);
-       netif_stop_queue(ndev);
-       if (priv->phydev)
-               phy_stop(priv->phydev);
-
-#ifdef CONFIG_STMMAC_TIMER
-       priv->tm->timer_stop();
-       if (likely(priv->tm->enable))
-               dis_ic = 1;
-#endif
-       napi_disable(&priv->napi);
-
-       /* Stop TX/RX DMA */
-       priv->hw->dma->stop_tx(priv->ioaddr);
-       priv->hw->dma->stop_rx(priv->ioaddr);
-       /* Clear the Rx/Tx descriptors */
-       priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
-                                    dis_ic);
-       priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
-
-       /* Enable Power down mode by programming the PMT regs */
-       if (device_may_wakeup(priv->device))
-               priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
-       else
-               stmmac_disable_mac(priv->ioaddr);
-
-       spin_unlock(&priv->lock);
-       return 0;
-}
-
-static int stmmac_resume(struct device *dev)
-{
-       struct net_device *ndev = dev_get_drvdata(dev);
-       struct stmmac_priv *priv = netdev_priv(ndev);
-
-       if (!netif_running(ndev))
-               return 0;
-
-       spin_lock(&priv->lock);
-
-       /* Power Down bit, into the PM register, is cleared
-        * automatically as soon as a magic packet or a Wake-up frame
-        * is received. Anyway, it's better to manually clear
-        * this bit because it can generate problems while resuming
-        * from another devices (e.g. serial console). */
-       if (device_may_wakeup(priv->device))
-               priv->hw->mac->pmt(priv->ioaddr, 0);
-
-       netif_device_attach(ndev);
-
-       /* Enable the MAC and DMA */
-       stmmac_enable_mac(priv->ioaddr);
-       priv->hw->dma->start_tx(priv->ioaddr);
-       priv->hw->dma->start_rx(priv->ioaddr);
-
-#ifdef CONFIG_STMMAC_TIMER
-       if (likely(priv->tm->enable))
-               priv->tm->timer_start(tmrate);
-#endif
-       napi_enable(&priv->napi);
-
-       if (priv->phydev)
-               phy_start(priv->phydev);
-
-       netif_start_queue(ndev);
-
-       spin_unlock(&priv->lock);
-       return 0;
-}
-
-static int stmmac_freeze(struct device *dev)
-{
-       struct net_device *ndev = dev_get_drvdata(dev);
-
-       if (!ndev || !netif_running(ndev))
-               return 0;
-
-       return stmmac_release(ndev);
-}
-
-static int stmmac_restore(struct device *dev)
-{
-       struct net_device *ndev = dev_get_drvdata(dev);
-
-       if (!ndev || !netif_running(ndev))
-               return 0;
-
-       return stmmac_open(ndev);
-}
-
-static const struct dev_pm_ops stmmac_pm_ops = {
-       .suspend = stmmac_suspend,
-       .resume = stmmac_resume,
-       .freeze = stmmac_freeze,
-       .thaw = stmmac_restore,
-       .restore = stmmac_restore,
-};
-#else
-static const struct dev_pm_ops stmmac_pm_ops;
-#endif /* CONFIG_PM */
-
-static struct platform_driver stmmac_driver = {
-       .probe = stmmac_dvr_probe,
-       .remove = stmmac_dvr_remove,
-       .driver = {
-               .name = STMMAC_RESOURCE_NAME,
-               .owner = THIS_MODULE,
-               .pm = &stmmac_pm_ops,
-       },
-};
-
-/**
- * stmmac_init_module - Entry point for the driver
- * Description: This function is the entry point for the driver.
- */
-static int __init stmmac_init_module(void)
-{
-       int ret;
-
-       ret = platform_driver_register(&stmmac_driver);
-       return ret;
-}
-
-/**
- * stmmac_cleanup_module - Cleanup routine for the driver
- * Description: This function is the cleanup routine for the driver.
- */
-static void __exit stmmac_cleanup_module(void)
-{
-       platform_driver_unregister(&stmmac_driver);
-}
-
-#ifndef MODULE
-static int __init stmmac_cmdline_opt(char *str)
-{
-       char *opt;
-
-       if (!str || !*str)
-               return -EINVAL;
-       while ((opt = strsep(&str, ",")) != NULL) {
-               if (!strncmp(opt, "debug:", 6)) {
-                       if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug))
-                               goto err;
-               } else if (!strncmp(opt, "phyaddr:", 8)) {
-                       if (strict_strtoul(opt + 8, 0,
-                                          (unsigned long *)&phyaddr))
-                               goto err;
-               } else if (!strncmp(opt, "dma_txsize:", 11)) {
-                       if (strict_strtoul(opt + 11, 0,
-                                          (unsigned long *)&dma_txsize))
-                               goto err;
-               } else if (!strncmp(opt, "dma_rxsize:", 11)) {
-                       if (strict_strtoul(opt + 11, 0,
-                                          (unsigned long *)&dma_rxsize))
-                               goto err;
-               } else if (!strncmp(opt, "buf_sz:", 7)) {
-                       if (strict_strtoul(opt + 7, 0,
-                                          (unsigned long *)&buf_sz))
-                               goto err;
-               } else if (!strncmp(opt, "tc:", 3)) {
-                       if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc))
-                               goto err;
-               } else if (!strncmp(opt, "watchdog:", 9)) {
-                       if (strict_strtoul(opt + 9, 0,
-                                          (unsigned long *)&watchdog))
-                               goto err;
-               } else if (!strncmp(opt, "flow_ctrl:", 10)) {
-                       if (strict_strtoul(opt + 10, 0,
-                                          (unsigned long *)&flow_ctrl))
-                               goto err;
-               } else if (!strncmp(opt, "pause:", 6)) {
-                       if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause))
-                               goto err;
-#ifdef CONFIG_STMMAC_TIMER
-               } else if (!strncmp(opt, "tmrate:", 7)) {
-                       if (strict_strtoul(opt + 7, 0,
-                                          (unsigned long *)&tmrate))
-                               goto err;
-#endif
-               }
-       }
-       return 0;
-
-err:
-       pr_err("%s: ERROR broken module parameter conversion", __func__);
-       return -EINVAL;
-}
-
-__setup("stmmaceth=", stmmac_cmdline_opt);
-#endif
-
-module_init(stmmac_init_module);
-module_exit(stmmac_cleanup_module);
-
-MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
-MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
deleted file mode 100644 (file)
index 9c3b9d5..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*******************************************************************************
-  STMMAC Ethernet Driver -- MDIO bus implementation
-  Provides Bus interface for MII registers
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Carl Shaw <carl.shaw@st.com>
-  Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-
-#include "stmmac.h"
-
-#define MII_BUSY 0x00000001
-#define MII_WRITE 0x00000002
-
-/**
- * stmmac_mdio_read
- * @bus: points to the mii_bus structure
- * @phyaddr: MII addr reg bits 15-11
- * @phyreg: MII addr reg bits 10-6
- * Description: it reads data from the MII register from within the phy device.
- * For the 7111 GMAC, we must set the bit 0 in the MII address register while
- * accessing the PHY registers.
- * Fortunately, it seems this has no drawback for the 7109 MAC.
- */
-static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
-{
-       struct net_device *ndev = bus->priv;
-       struct stmmac_priv *priv = netdev_priv(ndev);
-       unsigned int mii_address = priv->hw->mii.addr;
-       unsigned int mii_data = priv->hw->mii.data;
-
-       int data;
-       u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
-                       ((phyreg << 6) & (0x000007C0)));
-       regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
-
-       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
-       writel(regValue, priv->ioaddr + mii_address);
-       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
-
-       /* Read the data from the MII data register */
-       data = (int)readl(priv->ioaddr + mii_data);
-
-       return data;
-}
-
-/**
- * stmmac_mdio_write
- * @bus: points to the mii_bus structure
- * @phyaddr: MII addr reg bits 15-11
- * @phyreg: MII addr reg bits 10-6
- * @phydata: phy data
- * Description: it writes the data into the MII register from within the device.
- */
-static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
-                            u16 phydata)
-{
-       struct net_device *ndev = bus->priv;
-       struct stmmac_priv *priv = netdev_priv(ndev);
-       unsigned int mii_address = priv->hw->mii.addr;
-       unsigned int mii_data = priv->hw->mii.data;
-
-       u16 value =
-           (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
-           | MII_WRITE;
-
-       value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
-
-
-       /* Wait until any existing MII operation is complete */
-       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
-
-       /* Set the MII address register to write */
-       writel(phydata, priv->ioaddr + mii_data);
-       writel(value, priv->ioaddr + mii_address);
-
-       /* Wait until any existing MII operation is complete */
-       do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
-
-       return 0;
-}
-
-/**
- * stmmac_mdio_reset
- * @bus: points to the mii_bus structure
- * Description: reset the MII bus
- */
-static int stmmac_mdio_reset(struct mii_bus *bus)
-{
-       struct net_device *ndev = bus->priv;
-       struct stmmac_priv *priv = netdev_priv(ndev);
-       unsigned int mii_address = priv->hw->mii.addr;
-
-       if (priv->plat->mdio_bus_data->phy_reset) {
-               pr_debug("stmmac_mdio_reset: calling phy_reset\n");
-               priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv);
-       }
-
-       /* This is a workaround for problems with the STE101P PHY.
-        * It doesn't complete its reset until at least one clock cycle
-        * on MDC, so perform a dummy mdio read.
-        */
-       writel(0, priv->ioaddr + mii_address);
-
-       return 0;
-}
-
-/**
- * stmmac_mdio_register
- * @ndev: net device structure
- * Description: it registers the MII bus
- */
-int stmmac_mdio_register(struct net_device *ndev)
-{
-       int err = 0;
-       struct mii_bus *new_bus;
-       int *irqlist;
-       struct stmmac_priv *priv = netdev_priv(ndev);
-       struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
-       int addr, found;
-
-       if (!mdio_bus_data)
-               return 0;
-
-       new_bus = mdiobus_alloc();
-       if (new_bus == NULL)
-               return -ENOMEM;
-
-       if (mdio_bus_data->irqs)
-               irqlist = mdio_bus_data->irqs;
-       else
-               irqlist = priv->mii_irq;
-
-       new_bus->name = "STMMAC MII Bus";
-       new_bus->read = &stmmac_mdio_read;
-       new_bus->write = &stmmac_mdio_write;
-       new_bus->reset = &stmmac_mdio_reset;
-       snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id);
-       new_bus->priv = ndev;
-       new_bus->irq = irqlist;
-       new_bus->phy_mask = mdio_bus_data->phy_mask;
-       new_bus->parent = priv->device;
-       err = mdiobus_register(new_bus);
-       if (err != 0) {
-               pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
-               goto bus_register_fail;
-       }
-
-       priv->mii = new_bus;
-
-       found = 0;
-       for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
-               struct phy_device *phydev = new_bus->phy_map[addr];
-               if (phydev) {
-                       int act = 0;
-                       char irq_num[4];
-                       char *irq_str;
-
-                       /*
-                        * If an IRQ was provided to be assigned after
-                        * the bus probe, do it here.
-                        */
-                       if ((mdio_bus_data->irqs == NULL) &&
-                           (mdio_bus_data->probed_phy_irq > 0)) {
-                               irqlist[addr] = mdio_bus_data->probed_phy_irq;
-                               phydev->irq = mdio_bus_data->probed_phy_irq;
-                       }
-
-                       /*
-                        * If we're  going to bind the MAC to this PHY bus,
-                        * and no PHY number was provided to the MAC,
-                        * use the one probed here.
-                        */
-                       if ((priv->plat->bus_id == mdio_bus_data->bus_id) &&
-                           (priv->plat->phy_addr == -1))
-                               priv->plat->phy_addr = addr;
-
-                       act = (priv->plat->bus_id == mdio_bus_data->bus_id) &&
-                               (priv->plat->phy_addr == addr);
-                       switch (phydev->irq) {
-                       case PHY_POLL:
-                               irq_str = "POLL";
-                               break;
-                       case PHY_IGNORE_INTERRUPT:
-                               irq_str = "IGNORE";
-                               break;
-                       default:
-                               sprintf(irq_num, "%d", phydev->irq);
-                               irq_str = irq_num;
-                               break;
-                       }
-                       pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
-                               ndev->name, phydev->phy_id, addr,
-                               irq_str, dev_name(&phydev->dev),
-                               act ? " active" : "");
-                       found = 1;
-               }
-       }
-
-       if (!found)
-               pr_warning("%s: No PHY found\n", ndev->name);
-
-       return 0;
-
-bus_register_fail:
-       mdiobus_free(new_bus);
-       return err;
-}
-
-/**
- * stmmac_mdio_unregister
- * @ndev: net device structure
- * Description: it unregisters the MII bus
- */
-int stmmac_mdio_unregister(struct net_device *ndev)
-{
-       struct stmmac_priv *priv = netdev_priv(ndev);
-
-       mdiobus_unregister(priv->mii);
-       priv->mii->priv = NULL;
-       mdiobus_free(priv->mii);
-       priv->mii = NULL;
-
-       return 0;
-}
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
deleted file mode 100644 (file)
index 2a0e1ab..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*******************************************************************************
-  STMMAC external timer support.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/etherdevice.h>
-#include "stmmac_timer.h"
-
-static void stmmac_timer_handler(void *data)
-{
-       struct net_device *dev = (struct net_device *)data;
-
-       stmmac_schedule(dev);
-}
-
-#define STMMAC_TIMER_MSG(timer, freq) \
-printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
-
-#if defined(CONFIG_STMMAC_RTC_TIMER)
-#include <linux/rtc.h>
-static struct rtc_device *stmmac_rtc;
-static rtc_task_t stmmac_task;
-
-static void stmmac_rtc_start(unsigned int new_freq)
-{
-       rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
-       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
-}
-
-static void stmmac_rtc_stop(void)
-{
-       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
-}
-
-int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
-{
-       stmmac_task.private_data = dev;
-       stmmac_task.func = stmmac_timer_handler;
-
-       stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-       if (stmmac_rtc == NULL) {
-               pr_err("open rtc device failed\n");
-               return -ENODEV;
-       }
-
-       rtc_irq_register(stmmac_rtc, &stmmac_task);
-
-       /* Periodic mode is not supported */
-       if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
-               pr_err("set periodic failed\n");
-               rtc_irq_unregister(stmmac_rtc, &stmmac_task);
-               rtc_class_close(stmmac_rtc);
-               return -1;
-       }
-
-       STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
-
-       tm->timer_start = stmmac_rtc_start;
-       tm->timer_stop = stmmac_rtc_stop;
-
-       return 0;
-}
-
-int stmmac_close_ext_timer(void)
-{
-       rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
-       rtc_irq_unregister(stmmac_rtc, &stmmac_task);
-       rtc_class_close(stmmac_rtc);
-       return 0;
-}
-
-#elif defined(CONFIG_STMMAC_TMU_TIMER)
-#include <linux/clk.h>
-#define TMU_CHANNEL "tmu2_clk"
-static struct clk *timer_clock;
-
-static void stmmac_tmu_start(unsigned int new_freq)
-{
-       clk_set_rate(timer_clock, new_freq);
-       clk_enable(timer_clock);
-}
-
-static void stmmac_tmu_stop(void)
-{
-       clk_disable(timer_clock);
-}
-
-int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
-{
-       timer_clock = clk_get(NULL, TMU_CHANNEL);
-
-       if (timer_clock == NULL)
-               return -1;
-
-       if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
-               timer_clock = NULL;
-               return -1;
-       }
-
-       STMMAC_TIMER_MSG("TMU2", tm->freq);
-       tm->timer_start = stmmac_tmu_start;
-       tm->timer_stop = stmmac_tmu_stop;
-
-       return 0;
-}
-
-int stmmac_close_ext_timer(void)
-{
-       clk_disable(timer_clock);
-       tmu2_unregister_user();
-       clk_put(timer_clock);
-       return 0;
-}
-#endif
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h
deleted file mode 100644 (file)
index 6863590..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
-  STMMAC external timer Header File.
-
-  Copyright (C) 2007-2009  STMicroelectronics Ltd
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-  more details.
-
-  You should have received a copy of the GNU General Public License along with
-  this program; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
-*******************************************************************************/
-
-struct stmmac_timer {
-       void (*timer_start) (unsigned int new_freq);
-       void (*timer_stop) (void);
-       unsigned int freq;
-       unsigned int enable;
-};
-
-/* Open the HW timer device and return 0 in case of success */
-int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
-/* Stop the timer and release it */
-int stmmac_close_ext_timer(void);
-/* Function used for scheduling task within the stmmac */
-void stmmac_schedule(struct net_device *dev);
-
-#if defined(CONFIG_STMMAC_TMU_TIMER)
-extern int tmu2_register_user(void *fnt, void *data);
-extern void tmu2_unregister_user(void);
-#endif
This page took 0.142395 seconds and 5 git commands to generate.