diff options
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 | 249 | ||||
| -rw-r--r-- | drivers/net/stmmac/dwmac1000_dma.c | 154 | ||||
| -rw-r--r-- | drivers/net/stmmac/dwmac100_core.c | 203 | ||||
| -rw-r--r-- | drivers/net/stmmac/dwmac100_dma.c | 142 | ||||
| -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 | 93 | ||||
| -rw-r--r-- | drivers/net/stmmac/stmmac_ethtool.c | 380 | ||||
| -rw-r--r-- | drivers/net/stmmac/stmmac_main.c | 1995 | ||||
| -rw-r--r-- | drivers/net/stmmac/stmmac_mdio.c | 215 | ||||
| -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, 5337 deletions
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig deleted file mode 100644 index 7df7df4e79c..00000000000 --- 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 9691733ddb8..00000000000 --- 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 375ea193e13..00000000000 --- 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 63a03e26469..00000000000 --- 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 7c6d857a9cc..00000000000 --- 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 cfcef0ea0fa..00000000000 --- 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 6ae4c3f4c63..00000000000 --- a/drivers/net/stmmac/dwmac1000_core.c +++ /dev/null @@ -1,249 +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 "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; -	} else 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 2c47712d45d..00000000000 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ /dev/null @@ -1,154 +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 "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 c724fc36a24..00000000000 --- a/drivers/net/stmmac/dwmac100_core.c +++ /dev/null @@ -1,203 +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 "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 e3e224b7d9e..00000000000 --- a/drivers/net/stmmac/dwmac100_dma.c +++ /dev/null @@ -1,142 +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 "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 da3f5ccf83d..00000000000 --- 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 d65fab1ba79..00000000000 --- 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 DBG(fmt, args...)  printk(fmt, ## args) -#else -#define 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); - -	DBG(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)) { -		DBG(INFO, "CSR5[15] DMA ABNORMAL IRQ: "); -		if (unlikely(intr_status & DMA_STATUS_UNF)) { -			DBG(INFO, "transmit underflow\n"); -			ret = tx_hard_error_bump_tc; -			x->tx_undeflow_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_TJT)) { -			DBG(INFO, "transmit jabber\n"); -			x->tx_jabber_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_OVF)) { -			DBG(INFO, "recv overflow\n"); -			x->rx_overflow_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_RU)) { -			DBG(INFO, "receive buffer unavailable\n"); -			x->rx_buf_unav_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_RPS)) { -			DBG(INFO, "receive process stopped\n"); -			x->rx_process_stopped_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_RWT)) { -			DBG(INFO, "receive watchdog\n"); -			x->rx_watchdog_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_ETI)) { -			DBG(INFO, "transmit early interrupt\n"); -			x->tx_early_irq++; -		} -		if (unlikely(intr_status & DMA_STATUS_TPS)) { -			DBG(INFO, "transmit process stopped\n"); -			x->tx_process_stopped_irq++; -			ret = tx_hard_error; -		} -		if (unlikely(intr_status & DMA_STATUS_FBI)) { -			DBG(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); - -	DBG(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 e5dfb6a3018..00000000000 --- 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 cd0cc76f7a1..00000000000 --- 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 becasue 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 5f06c4706ab..00000000000 --- a/drivers/net/stmmac/stmmac.h +++ /dev/null @@ -1,93 +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	"Nov_2010" -#include <linux/platform_device.h> -#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; - -	phy_interface_t phy_interface; -	int phy_addr; -	int phy_mask; -	int (*phy_reset) (void *priv); -	int rx_coe; -	int no_csum_insertion; - -	int phy_irq; -	struct phy_device *phydev; -	int oldlink; -	int speed; -	int oldduplex; -	unsigned int flow_ctrl; -	unsigned int pause; -	struct mii_bus *mii; - -	u32 msg_enable; -	spinlock_t lock; -	int wolopts; -	int wolenabled; -#ifdef CONFIG_STMMAC_TIMER -	struct stmmac_timer *tm; -#endif -#ifdef STMMAC_VLAN_TAG_USED -	struct vlan_group *vlgrp; -#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 fd719edc7f7..00000000000 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ /dev/null @@ -1,380 +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/mii.h> -#include <linux/phy.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 u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) -{ -	struct stmmac_priv *priv = netdev_priv(dev); - -	return priv->rx_coe; -} - -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; - -	if (phy->autoneg) { -		if (netif_running(netdev)) { -			struct ethtool_cmd cmd; -			/* auto-negotiation automatically restarted */ -			cmd.cmd = ETHTOOL_NWAY_RST; -			cmd.supported = phy->supported; -			cmd.advertising = phy->advertising; -			cmd.autoneg = phy->autoneg; -			cmd.speed = phy->speed; -			cmd.duplex = phy->duplex; -			cmd.phy_address = phy->addr; -			ret = phy_ethtool_sset(phy, &cmd); -		} -	} 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; -		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; - -	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_rx_csum = stmmac_ethtool_get_rx_csum, -	.get_tx_csum = ethtool_op_get_tx_csum, -	.set_tx_csum = ethtool_op_set_tx_ipv6_csum, -	.get_sg = ethtool_op_get_sg, -	.set_sg = ethtool_op_set_sg, -	.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, -	.get_tso = ethtool_op_get_tso, -	.set_tso = ethtool_op_set_tso, -}; - -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 bfc2d125150..00000000000 --- a/drivers/net/stmmac/stmmac_main.c +++ /dev/null @@ -1,1995 +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 "stmmac.h" - -#define STMMAC_RESOURCE_NAME	"stmmaceth" -#define PHY_RESOURCE_NAME	"stmmacphy" - -#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"); - -#define RX_NO_COALESCE	1	/* Always interrupt on completion */ -#define TX_NO_COALESCE	-1	/* No moderation by default */ - -/* 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); -static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev); - -/** - * 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; - -	if (priv->phy_addr == -1) { -		/* We don't have a PHY, so do nothing */ -		return 0; -	} - -	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->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->phy_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->tx_coe) && (!priv->no_csum_insertion))) { -		/* In case of GMAC, SF mode has to be enabled -		 * to perform the TX COE. 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; -		} -		stmmac_tx_err(priv); -	} 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(); - -	ret = stmmac_init_phy(dev); -	if (unlikely(ret)) { -		pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); -		return ret; -	} - -	/* 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); -		return ret; -	} - -#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 - -	/* 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 */ -	if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, -					 priv->dma_tx_phy, -					 priv->dma_rx_phy) < 0)) { - -		pr_err("%s: DMA initialization failed\n", __func__); -		return -1; -	} - -	/* 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"); - -	/* 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); - -	/* 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; -} - -/** - *  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; -} - -/* - * To perform emulated hardware segmentation on skb. - */ -static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb) -{ -	struct sk_buff *segs, *curr_skb; -	int gso_segs = skb_shinfo(skb)->gso_segs; - -	/* Estimate the number of fragments in the worst case */ -	if (unlikely(stmmac_tx_avail(priv) < gso_segs)) { -		netif_stop_queue(priv->dev); -		TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n", -		       __func__); -		if (stmmac_tx_avail(priv) < gso_segs) -			return NETDEV_TX_BUSY; - -		netif_wake_queue(priv->dev); -	} -	TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n", -	       skb, skb->len); - -	segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO); -	if (unlikely(IS_ERR(segs))) -		goto sw_tso_end; - -	do { -		curr_skb = segs; -		segs = segs->next; -		TX_DBG("\t\tcurrent skb->len: %d, *curr %p," -		       "*next %p\n", curr_skb->len, curr_skb, segs); -		curr_skb->next = NULL; -		stmmac_xmit(curr_skb, priv->dev); -	} while (segs); - -sw_tso_end: -	dev_kfree_skb(skb); - -	return NETDEV_TX_OK; -} - -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 - -	if (unlikely(skb_is_gso(skb))) -		return stmmac_sw_tso(priv, skb); - -	if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { -		if (unlikely((!priv->plat->tx_coe) || -			     (priv->no_csum_insertion))) -			skb_checksum_help(skb); -		else -			csum_insertion = 1; -	} - -	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); -		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 -	/* 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; - -	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); -		} -		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; -	} - -	/* 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) && (priv->dev->mtu > ETH_DATA_LEN)) -		priv->no_csum_insertion = 1; -	else -		priv->no_csum_insertion = 0; - -	dev->mtu = new_mtu; - -	return 0; -} - -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; -} - -#ifdef STMMAC_VLAN_TAG_USED -static void stmmac_vlan_rx_register(struct net_device *dev, -				    struct vlan_group *grp) -{ -	struct stmmac_priv *priv = netdev_priv(dev); - -	DBG(probe, INFO, "%s: Setting vlgrp to %p\n", dev->name, grp); - -	spin_lock(&priv->lock); -	priv->vlgrp = grp; -	spin_unlock(&priv->lock); -} -#endif - -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_set_multicast_list = stmmac_multicast_list, -	.ndo_tx_timeout = stmmac_tx_timeout, -	.ndo_do_ioctl = stmmac_ioctl, -	.ndo_set_config = stmmac_config, -#ifdef STMMAC_VLAN_TAG_USED -	.ndo_vlan_rx_register = stmmac_vlan_rx_register, -#endif -#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->features |= NETIF_F_SG | NETIF_F_HIGHDMA | -		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; -	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"); - -	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"); - -	spin_lock_init(&priv->lock); - -	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 */ - -	return 0; -} - -static int stmmacphy_dvr_probe(struct platform_device *pdev) -{ -	struct plat_stmmacphy_data *plat_dat = pdev->dev.platform_data; - -	pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n", -	       plat_dat->bus_id); - -	return 0; -} - -static int stmmacphy_dvr_remove(struct platform_device *pdev) -{ -	return 0; -} - -static struct platform_driver stmmacphy_driver = { -	.driver = { -		   .name = PHY_RESOURCE_NAME, -		   }, -	.probe = stmmacphy_dvr_probe, -	.remove = stmmacphy_dvr_remove, -}; - -/** - * stmmac_associate_phy - * @dev: pointer to device structure - * @data: points to the private structure. - * Description: Scans through all the PHYs we have registered and checks if - * any are associated with our MAC.  If so, then just fill in - * the blanks in our local context structure - */ -static int stmmac_associate_phy(struct device *dev, void *data) -{ -	struct stmmac_priv *priv = (struct stmmac_priv *)data; -	struct plat_stmmacphy_data *plat_dat = dev->platform_data; - -	DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__, -		plat_dat->bus_id); - -	/* Check that this phy is for the MAC being initialised */ -	if (priv->plat->bus_id != plat_dat->bus_id) -		return 0; - -	/* OK, this PHY is connected to the MAC. -	   Go ahead and get the parameters */ -	DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__); -	priv->phy_irq = -	    platform_get_irq_byname(to_platform_device(dev), "phyirq"); -	DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__, -	    plat_dat->bus_id, priv->phy_irq); - -	/* Override with kernel parameters if supplied XXX CRS XXX -	 * this needs to have multiple instances */ -	if ((phyaddr >= 0) && (phyaddr <= 31)) -		plat_dat->phy_addr = phyaddr; - -	priv->phy_addr = plat_dat->phy_addr; -	priv->phy_mask = plat_dat->phy_mask; -	priv->phy_interface = plat_dat->interface; -	priv->phy_reset = plat_dat->phy_reset; - -	DBG(probe, DEBUG, "%s: exiting\n", __func__); -	return 1;	/* forces exit of driver_for_each_device() */ -} - -/** - * 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) { -		ret = -ENODEV; -		goto out; -	} -	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); -		ret = -EBUSY; -		goto out; -	} - -	addr = ioremap(res->start, resource_size(res)); -	if (!addr) { -		pr_err("%s: ERROR: memory mapping failed\n", __func__); -		ret = -ENOMEM; -		goto out; -	} - -	ndev = alloc_etherdev(sizeof(struct stmmac_priv)); -	if (!ndev) { -		pr_err("%s: ERROR: allocating the device\n", __func__); -		ret = -ENOMEM; -		goto out; -	} - -	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 = -ENODEV; -		goto out; -	} - -	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; -	} - -	/* MAC HW revice detection */ -	ret = stmmac_mac_device_setup(ndev); -	if (ret < 0) -		goto out; - -	/* Network Device Registration */ -	ret = stmmac_probe(ndev); -	if (ret < 0) -		goto out; - -	/* associate a PHY - it is provided by another platform bus */ -	if (!driver_for_each_device -	    (&(stmmacphy_driver.driver), NULL, (void *)priv, -	     stmmac_associate_phy)) { -		pr_err("No PHY device is associated with this MAC!\n"); -		ret = -ENODEV; -		goto out; -	} - -	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; -	pr_debug("registered!\n"); - -out: -	if (ret < 0) { -		if (priv->plat->exit) -			priv->plat->exit(pdev); - -		platform_set_drvdata(pdev, NULL); -		release_mem_region(res->start, resource_size(res)); -		if (addr != NULL) -			iounmap(addr); -	} - -	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; - -	if (platform_driver_register(&stmmacphy_driver)) { -		pr_err("No PHY devices registered!\n"); -		return -ENODEV; -	} - -	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(&stmmacphy_driver); -	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)) -			strict_strtoul(opt + 6, 0, (unsigned long *)&debug); -		else if (!strncmp(opt, "phyaddr:", 8)) -			strict_strtoul(opt + 8, 0, (unsigned long *)&phyaddr); -		else if (!strncmp(opt, "dma_txsize:", 11)) -			strict_strtoul(opt + 11, 0, -				       (unsigned long *)&dma_txsize); -		else if (!strncmp(opt, "dma_rxsize:", 11)) -			strict_strtoul(opt + 11, 0, -				       (unsigned long *)&dma_rxsize); -		else if (!strncmp(opt, "buf_sz:", 7)) -			strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz); -		else if (!strncmp(opt, "tc:", 3)) -			strict_strtoul(opt + 3, 0, (unsigned long *)&tc); -		else if (!strncmp(opt, "watchdog:", 9)) -			strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog); -		else if (!strncmp(opt, "flow_ctrl:", 10)) -			strict_strtoul(opt + 10, 0, -				       (unsigned long *)&flow_ctrl); -		else if (!strncmp(opt, "pause:", 6)) -			strict_strtoul(opt + 6, 0, (unsigned long *)&pause); -#ifdef CONFIG_STMMAC_TIMER -		else if (!strncmp(opt, "tmrate:", 7)) -			strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate); -#endif -	} -	return 0; -} - -__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 234b4068a1f..00000000000 --- a/drivers/net/stmmac/stmmac_mdio.c +++ /dev/null @@ -1,215 +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 "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->phy_reset) { -		pr_debug("stmmac_mdio_reset: calling phy_reset\n"); -		priv->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); -	int addr, found; - -	new_bus = mdiobus_alloc(); -	if (new_bus == NULL) -		return -ENOMEM; - -	irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); -	if (irqlist == NULL) { -		err = -ENOMEM; -		goto irqlist_alloc_fail; -	} - -	/* Assign IRQ to phy at address phy_addr */ -	if (priv->phy_addr != -1) -		irqlist[priv->phy_addr] = priv->phy_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", priv->plat->bus_id); -	new_bus->priv = ndev; -	new_bus->irq = irqlist; -	new_bus->phy_mask = priv->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 < 32; addr++) { -		struct phy_device *phydev = new_bus->phy_map[addr]; -		if (phydev) { -			if (priv->phy_addr == -1) { -				priv->phy_addr = addr; -				phydev->irq = priv->phy_irq; -				irqlist[addr] = priv->phy_irq; -			} -			pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n", -			       ndev->name, phydev->phy_id, addr, -			       phydev->irq, dev_name(&phydev->dev), -			       (addr == priv->phy_addr) ? " active" : ""); -			found = 1; -		} -	} - -	if (!found) -		pr_warning("%s: No PHY found\n", ndev->name); - -	return 0; -bus_register_fail: -	kfree(irqlist); -irqlist_alloc_fail: -	kfree(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; -	kfree(priv->mii); - -	return 0; -} diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c deleted file mode 100644 index 2a0e1abde7e..00000000000 --- 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 6863590d184..00000000000 --- 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  | 
