diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-05-16 00:05:19 -0700 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-11 16:29:01 -0700 |
commit | 7ac6653a085b41405758bc16b2525db56ee0a23f (patch) | |
tree | 1a3fc878f338778dd8a9ee8b06dab899a4ec5a87 /drivers/net/stmmac | |
parent | ef7f54297df683665145859501f63c801f6c7ea8 (diff) | |
download | linux-7ac6653a085b41405758bc16b2525db56ee0a23f.tar.gz linux-7ac6653a085b41405758bc16b2525db56ee0a23f.tar.bz2 linux-7ac6653a085b41405758bc16b2525db56ee0a23f.zip |
stmmac: Move the STMicroelectronics driver
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>
Diffstat (limited to 'drivers/net/stmmac')
-rw-r--r-- | drivers/net/stmmac/Kconfig | 57 | ||||
-rw-r--r-- | drivers/net/stmmac/Makefile | 5 | ||||
-rw-r--r-- | drivers/net/stmmac/common.h | 252 | ||||
-rw-r--r-- | drivers/net/stmmac/descs.h | 163 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac100.h | 121 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac1000.h | 208 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac1000_core.c | 251 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac1000_dma.c | 155 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac100_core.c | 204 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac100_dma.c | 143 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac_dma.h | 108 | ||||
-rw-r--r-- | drivers/net/stmmac/dwmac_lib.c | 258 | ||||
-rw-r--r-- | drivers/net/stmmac/enh_desc.c | 337 | ||||
-rw-r--r-- | drivers/net/stmmac/norm_desc.c | 221 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac.h | 85 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_ethtool.c | 359 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_main.c | 1895 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_mdio.c | 247 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_timer.c | 134 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_timer.h | 42 |
20 files changed, 0 insertions, 5245 deletions
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig deleted file mode 100644 index 7df7df4e79c5..000000000000 --- a/drivers/net/stmmac/Kconfig +++ /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 index 9691733ddb8e..000000000000 --- a/drivers/net/stmmac/Makefile +++ /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 index 375ea193e139..000000000000 --- a/drivers/net/stmmac/common.h +++ /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 index 63a03e264694..000000000000 --- a/drivers/net/stmmac/descs.h +++ /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 index 7c6d857a9cc7..000000000000 --- a/drivers/net/stmmac/dwmac100.h +++ /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 index cfcef0ea0fa5..000000000000 --- a/drivers/net/stmmac/dwmac1000.h +++ /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 index 0f63b3c83c19..000000000000 --- a/drivers/net/stmmac/dwmac1000_core.c +++ /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 index 3dbeea619085..000000000000 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ /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 index 743a58017637..000000000000 --- a/drivers/net/stmmac/dwmac100_core.c +++ /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 index 627f656b0f3c..000000000000 --- a/drivers/net/stmmac/dwmac100_dma.c +++ /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 index da3f5ccf83d3..000000000000 --- a/drivers/net/stmmac/dwmac_dma.h +++ /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 index e25093510b0c..000000000000 --- a/drivers/net/stmmac/dwmac_lib.c +++ /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 index e5dfb6a30182..000000000000 --- a/drivers/net/stmmac/enh_desc.c +++ /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 index 029c2a2cf524..000000000000 --- a/drivers/net/stmmac/norm_desc.c +++ /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 index de1929b2641b..000000000000 --- a/drivers/net/stmmac/stmmac.h +++ /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 index 7ed8fb6c2117..000000000000 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ /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 index c6e567e04eff..000000000000 --- a/drivers/net/stmmac/stmmac_main.c +++ /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 index 9c3b9d5c3411..000000000000 --- a/drivers/net/stmmac/stmmac_mdio.c +++ /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 index 2a0e1abde7e7..000000000000 --- a/drivers/net/stmmac/stmmac_timer.c +++ /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 index 6863590d184b..000000000000 --- a/drivers/net/stmmac/stmmac_timer.h +++ /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 |