aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/stmicro')
-rw-r--r--drivers/net/ethernet/stmicro/Kconfig22
-rw-r--r--drivers/net/ethernet/stmicro/Makefile5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Kconfig57
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Makefile5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h252
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/descs.h163
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100.h121
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000.h208
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c251
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c155
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c204
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c143
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h108
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c258
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/enh_desc.c337
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/norm_desc.c221
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h85
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c359
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c1895
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c247
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c134
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h42
22 files changed, 5272 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/Kconfig b/drivers/net/ethernet/stmicro/Kconfig
new file mode 100644
index 000000000000..e40df6433860
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/Kconfig
@@ -0,0 +1,22 @@
1#
2# STMicroelectronics device configuration
3#
4
5config NET_VENDOR_STMICRO
6 bool "STMicroelectronics devices"
7 depends on HAS_IOMEM
8 ---help---
9 If you have a network (Ethernet) card belonging to this class, say Y
10 and read the Ethernet-HOWTO, available from
11 <http://www.tldp.org/docs.html#howto>.
12
13 Note that the answer to this question doesn't directly affect the
14 kernel: saying N will just cause the configurator to skip all
15 the questions about STMicroelectronics cards. If you say Y, you will
16 be asked for your specific card in the following questions.
17
18if NET_VENDOR_STMICRO
19
20source "drivers/net/ethernet/stmicro/stmmac/Kconfig"
21
22endif # NET_VENDOR_STMICRO
diff --git a/drivers/net/ethernet/stmicro/Makefile b/drivers/net/ethernet/stmicro/Makefile
new file mode 100644
index 000000000000..9b3bfddda7dd
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the STMicroelectronics device drivers.
3#
4
5obj-$(CONFIG_STMMAC_ETH) += stmmac/
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
new file mode 100644
index 000000000000..cda61e37c357
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -0,0 +1,57 @@
1config STMMAC_ETH
2 tristate "STMicroelectronics 10/100/1000 Ethernet driver"
3 depends on HAS_IOMEM
4 select MII
5 select PHYLIB
6 select CRC32
7 ---help---
8 This is the driver for the Ethernet IPs are built around a
9 Synopsys IP Core and only tested on the STMicroelectronics
10 platforms.
11
12if STMMAC_ETH
13
14config STMMAC_DA
15 bool "STMMAC DMA arbitration scheme"
16 default n
17 ---help---
18 Selecting this option, rx has priority over Tx (only for Giga
19 Ethernet device).
20 By default, the DMA arbitration scheme is based on Round-robin
21 (rx:tx priority is 1:1).
22
23config STMMAC_DUAL_MAC
24 bool "STMMAC: dual mac support (EXPERIMENTAL)"
25 default n
26 depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
27 ---help---
28 Some ST SoCs (for example the stx7141 and stx7200c2) have two
29 Ethernet Controllers. This option turns on the second Ethernet
30 device on this kind of platforms.
31
32config STMMAC_TIMER
33 bool "STMMAC Timer optimisation"
34 default n
35 depends on RTC_HCTOSYS_DEVICE
36 ---help---
37 Use an external timer for mitigating the number of network
38 interrupts. Currently, for SH architectures, it is possible
39 to use the TMU channel 2 and the SH-RTC device.
40
41choice
42 prompt "Select Timer device"
43 depends on STMMAC_TIMER
44
45config STMMAC_TMU_TIMER
46 bool "TMU channel 2"
47 depends on CPU_SH4
48 ---help---
49
50config STMMAC_RTC_TIMER
51 bool "Real time clock"
52 depends on RTC_CLASS
53 ---help---
54
55endchoice
56
57endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
new file mode 100644
index 000000000000..9691733ddb8e
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
5 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o $(stmmac-y)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
new file mode 100644
index 000000000000..375ea193e139
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -0,0 +1,252 @@
1/*******************************************************************************
2 STMMAC Common Header File
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/netdevice.h>
26#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
27#define STMMAC_VLAN_TAG_USED
28#include <linux/if_vlan.h>
29#endif
30
31#include "descs.h"
32
33#undef CHIP_DEBUG_PRINT
34/* Turn-on extra printk debug for MAC core, dma and descriptors */
35/* #define CHIP_DEBUG_PRINT */
36
37#ifdef CHIP_DEBUG_PRINT
38#define CHIP_DBG(fmt, args...) printk(fmt, ## args)
39#else
40#define CHIP_DBG(fmt, args...) do { } while (0)
41#endif
42
43#undef FRAME_FILTER_DEBUG
44/* #define FRAME_FILTER_DEBUG */
45
46struct stmmac_extra_stats {
47 /* Transmit errors */
48 unsigned long tx_underflow ____cacheline_aligned;
49 unsigned long tx_carrier;
50 unsigned long tx_losscarrier;
51 unsigned long tx_heartbeat;
52 unsigned long tx_deferred;
53 unsigned long tx_vlan;
54 unsigned long tx_jabber;
55 unsigned long tx_frame_flushed;
56 unsigned long tx_payload_error;
57 unsigned long tx_ip_header_error;
58 /* Receive errors */
59 unsigned long rx_desc;
60 unsigned long rx_partial;
61 unsigned long rx_runt;
62 unsigned long rx_toolong;
63 unsigned long rx_collision;
64 unsigned long rx_crc;
65 unsigned long rx_length;
66 unsigned long rx_mii;
67 unsigned long rx_multicast;
68 unsigned long rx_gmac_overflow;
69 unsigned long rx_watchdog;
70 unsigned long da_rx_filter_fail;
71 unsigned long sa_rx_filter_fail;
72 unsigned long rx_missed_cntr;
73 unsigned long rx_overflow_cntr;
74 unsigned long rx_vlan;
75 /* Tx/Rx IRQ errors */
76 unsigned long tx_undeflow_irq;
77 unsigned long tx_process_stopped_irq;
78 unsigned long tx_jabber_irq;
79 unsigned long rx_overflow_irq;
80 unsigned long rx_buf_unav_irq;
81 unsigned long rx_process_stopped_irq;
82 unsigned long rx_watchdog_irq;
83 unsigned long tx_early_irq;
84 unsigned long fatal_bus_error_irq;
85 /* Extra info */
86 unsigned long threshold;
87 unsigned long tx_pkt_n;
88 unsigned long rx_pkt_n;
89 unsigned long poll_n;
90 unsigned long sched_timer_n;
91 unsigned long normal_irq_n;
92};
93
94#define HASH_TABLE_SIZE 64
95#define PAUSE_TIME 0x200
96
97/* Flow Control defines */
98#define FLOW_OFF 0
99#define FLOW_RX 1
100#define FLOW_TX 2
101#define FLOW_AUTO (FLOW_TX | FLOW_RX)
102
103#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
104
105enum rx_frame_status { /* IPC status */
106 good_frame = 0,
107 discard_frame = 1,
108 csum_none = 2,
109 llc_snap = 4,
110};
111
112enum tx_dma_irq_status {
113 tx_hard_error = 1,
114 tx_hard_error_bump_tc = 2,
115 handle_tx_rx = 3,
116};
117
118/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
119#define BUF_SIZE_16KiB 16384
120#define BUF_SIZE_8KiB 8192
121#define BUF_SIZE_4KiB 4096
122#define BUF_SIZE_2KiB 2048
123
124/* Power Down and WOL */
125#define PMT_NOT_SUPPORTED 0
126#define PMT_SUPPORTED 1
127
128/* Common MAC defines */
129#define MAC_CTRL_REG 0x00000000 /* MAC Control */
130#define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */
131#define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */
132
133/* MAC Management Counters register */
134#define MMC_CONTROL 0x00000100 /* MMC Control */
135#define MMC_HIGH_INTR 0x00000104 /* MMC High Interrupt */
136#define MMC_LOW_INTR 0x00000108 /* MMC Low Interrupt */
137#define MMC_HIGH_INTR_MASK 0x0000010c /* MMC High Interrupt Mask */
138#define MMC_LOW_INTR_MASK 0x00000110 /* MMC Low Interrupt Mask */
139
140#define MMC_CONTROL_MAX_FRM_MASK 0x0003ff8 /* Maximum Frame Size */
141#define MMC_CONTROL_MAX_FRM_SHIFT 3
142#define MMC_CONTROL_MAX_FRAME 0x7FF
143
144struct stmmac_desc_ops {
145 /* DMA RX descriptor ring initialization */
146 void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
147 int disable_rx_ic);
148 /* DMA TX descriptor ring initialization */
149 void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
150
151 /* Invoked by the xmit function to prepare the tx descriptor */
152 void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
153 int csum_flag);
154 /* Set/get the owner of the descriptor */
155 void (*set_tx_owner) (struct dma_desc *p);
156 int (*get_tx_owner) (struct dma_desc *p);
157 /* Invoked by the xmit function to close the tx descriptor */
158 void (*close_tx_desc) (struct dma_desc *p);
159 /* Clean the tx descriptor as soon as the tx irq is received */
160 void (*release_tx_desc) (struct dma_desc *p);
161 /* Clear interrupt on tx frame completion. When this bit is
162 * set an interrupt happens as soon as the frame is transmitted */
163 void (*clear_tx_ic) (struct dma_desc *p);
164 /* Last tx segment reports the transmit status */
165 int (*get_tx_ls) (struct dma_desc *p);
166 /* Return the transmit status looking at the TDES1 */
167 int (*tx_status) (void *data, struct stmmac_extra_stats *x,
168 struct dma_desc *p, void __iomem *ioaddr);
169 /* Get the buffer size from the descriptor */
170 int (*get_tx_len) (struct dma_desc *p);
171 /* Handle extra events on specific interrupts hw dependent */
172 int (*get_rx_owner) (struct dma_desc *p);
173 void (*set_rx_owner) (struct dma_desc *p);
174 /* Get the receive frame size */
175 int (*get_rx_frame_len) (struct dma_desc *p);
176 /* Return the reception status looking at the RDES1 */
177 int (*rx_status) (void *data, struct stmmac_extra_stats *x,
178 struct dma_desc *p);
179};
180
181struct stmmac_dma_ops {
182 /* DMA core initialization */
183 int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
184 /* Dump DMA registers */
185 void (*dump_regs) (void __iomem *ioaddr);
186 /* Set tx/rx threshold in the csr6 register
187 * An invalid value enables the store-and-forward mode */
188 void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode);
189 /* To track extra statistic (if supported) */
190 void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
191 void __iomem *ioaddr);
192 void (*enable_dma_transmission) (void __iomem *ioaddr);
193 void (*enable_dma_irq) (void __iomem *ioaddr);
194 void (*disable_dma_irq) (void __iomem *ioaddr);
195 void (*start_tx) (void __iomem *ioaddr);
196 void (*stop_tx) (void __iomem *ioaddr);
197 void (*start_rx) (void __iomem *ioaddr);
198 void (*stop_rx) (void __iomem *ioaddr);
199 int (*dma_interrupt) (void __iomem *ioaddr,
200 struct stmmac_extra_stats *x);
201};
202
203struct stmmac_ops {
204 /* MAC core initialization */
205 void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned;
206 /* Support checksum offload engine */
207 int (*rx_coe) (void __iomem *ioaddr);
208 /* Dump MAC registers */
209 void (*dump_regs) (void __iomem *ioaddr);
210 /* Handle extra events on specific interrupts hw dependent */
211 void (*host_irq_status) (void __iomem *ioaddr);
212 /* Multicast filter setting */
213 void (*set_filter) (struct net_device *dev);
214 /* Flow control setting */
215 void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
216 unsigned int fc, unsigned int pause_time);
217 /* Set power management mode (e.g. magic frame) */
218 void (*pmt) (void __iomem *ioaddr, unsigned long mode);
219 /* Set/Get Unicast MAC addresses */
220 void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
221 unsigned int reg_n);
222 void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr,
223 unsigned int reg_n);
224};
225
226struct mac_link {
227 int port;
228 int duplex;
229 int speed;
230};
231
232struct mii_regs {
233 unsigned int addr; /* MII Address */
234 unsigned int data; /* MII Data */
235};
236
237struct mac_device_info {
238 const struct stmmac_ops *mac;
239 const struct stmmac_desc_ops *desc;
240 const struct stmmac_dma_ops *dma;
241 struct mii_regs mii; /* MII register Addresses */
242 struct mac_link link;
243};
244
245struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr);
246struct mac_device_info *dwmac100_setup(void __iomem *ioaddr);
247
248extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
249 unsigned int high, unsigned int low);
250extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
251 unsigned int high, unsigned int low);
252extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h
new file mode 100644
index 000000000000..63a03e264694
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/descs.h
@@ -0,0 +1,163 @@
1/*******************************************************************************
2 Header File to describe the DMA descriptors.
3 Enhanced descriptors have been in case of DWMAC1000 Cores.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms and conditions of the GNU General Public License,
7 version 2, as published by the Free Software Foundation.
8
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17
18 The full GNU General Public License is included in this distribution in
19 the file called "COPYING".
20
21 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
22*******************************************************************************/
23struct dma_desc {
24 /* Receive descriptor */
25 union {
26 struct {
27 /* RDES0 */
28 u32 reserved1:1;
29 u32 crc_error:1;
30 u32 dribbling:1;
31 u32 mii_error:1;
32 u32 receive_watchdog:1;
33 u32 frame_type:1;
34 u32 collision:1;
35 u32 frame_too_long:1;
36 u32 last_descriptor:1;
37 u32 first_descriptor:1;
38 u32 multicast_frame:1;
39 u32 run_frame:1;
40 u32 length_error:1;
41 u32 partial_frame_error:1;
42 u32 descriptor_error:1;
43 u32 error_summary:1;
44 u32 frame_length:14;
45 u32 filtering_fail:1;
46 u32 own:1;
47 /* RDES1 */
48 u32 buffer1_size:11;
49 u32 buffer2_size:11;
50 u32 reserved2:2;
51 u32 second_address_chained:1;
52 u32 end_ring:1;
53 u32 reserved3:5;
54 u32 disable_ic:1;
55 } rx;
56 struct {
57 /* RDES0 */
58 u32 payload_csum_error:1;
59 u32 crc_error:1;
60 u32 dribbling:1;
61 u32 error_gmii:1;
62 u32 receive_watchdog:1;
63 u32 frame_type:1;
64 u32 late_collision:1;
65 u32 ipc_csum_error:1;
66 u32 last_descriptor:1;
67 u32 first_descriptor:1;
68 u32 vlan_tag:1;
69 u32 overflow_error:1;
70 u32 length_error:1;
71 u32 sa_filter_fail:1;
72 u32 descriptor_error:1;
73 u32 error_summary:1;
74 u32 frame_length:14;
75 u32 da_filter_fail:1;
76 u32 own:1;
77 /* RDES1 */
78 u32 buffer1_size:13;
79 u32 reserved1:1;
80 u32 second_address_chained:1;
81 u32 end_ring:1;
82 u32 buffer2_size:13;
83 u32 reserved2:2;
84 u32 disable_ic:1;
85 } erx; /* -- enhanced -- */
86
87 /* Transmit descriptor */
88 struct {
89 /* TDES0 */
90 u32 deferred:1;
91 u32 underflow_error:1;
92 u32 excessive_deferral:1;
93 u32 collision_count:4;
94 u32 heartbeat_fail:1;
95 u32 excessive_collisions:1;
96 u32 late_collision:1;
97 u32 no_carrier:1;
98 u32 loss_carrier:1;
99 u32 reserved1:3;
100 u32 error_summary:1;
101 u32 reserved2:15;
102 u32 own:1;
103 /* TDES1 */
104 u32 buffer1_size:11;
105 u32 buffer2_size:11;
106 u32 reserved3:1;
107 u32 disable_padding:1;
108 u32 second_address_chained:1;
109 u32 end_ring:1;
110 u32 crc_disable:1;
111 u32 reserved4:2;
112 u32 first_segment:1;
113 u32 last_segment:1;
114 u32 interrupt:1;
115 } tx;
116 struct {
117 /* TDES0 */
118 u32 deferred:1;
119 u32 underflow_error:1;
120 u32 excessive_deferral:1;
121 u32 collision_count:4;
122 u32 vlan_frame:1;
123 u32 excessive_collisions:1;
124 u32 late_collision:1;
125 u32 no_carrier:1;
126 u32 loss_carrier:1;
127 u32 payload_error:1;
128 u32 frame_flushed:1;
129 u32 jabber_timeout:1;
130 u32 error_summary:1;
131 u32 ip_header_error:1;
132 u32 time_stamp_status:1;
133 u32 reserved1:2;
134 u32 second_address_chained:1;
135 u32 end_ring:1;
136 u32 checksum_insertion:2;
137 u32 reserved2:1;
138 u32 time_stamp_enable:1;
139 u32 disable_padding:1;
140 u32 crc_disable:1;
141 u32 first_segment:1;
142 u32 last_segment:1;
143 u32 interrupt:1;
144 u32 own:1;
145 /* TDES1 */
146 u32 buffer1_size:13;
147 u32 reserved3:3;
148 u32 buffer2_size:13;
149 u32 reserved4:3;
150 } etx; /* -- enhanced -- */
151 } des01;
152 unsigned int des2;
153 unsigned int des3;
154};
155
156/* Transmit checksum insertion control */
157enum tdes_csum_insertion {
158 cic_disabled = 0, /* Checksum Insertion Control */
159 cic_only_ip = 1, /* Only IP header */
160 cic_no_pseudoheader = 2, /* IP header but pseudoheader
161 * is not calculated */
162 cic_full = 3, /* IP header and pseudoheader */
163};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h
new file mode 100644
index 000000000000..7c6d857a9cc7
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h
@@ -0,0 +1,121 @@
1/*******************************************************************************
2 MAC 10/100 Header File
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/phy.h>
26#include "common.h"
27
28/*----------------------------------------------------------------------------
29 * MAC BLOCK defines
30 *---------------------------------------------------------------------------*/
31/* MAC CSR offset */
32#define MAC_CONTROL 0x00000000 /* MAC Control */
33#define MAC_ADDR_HIGH 0x00000004 /* MAC Address High */
34#define MAC_ADDR_LOW 0x00000008 /* MAC Address Low */
35#define MAC_HASH_HIGH 0x0000000c /* Multicast Hash Table High */
36#define MAC_HASH_LOW 0x00000010 /* Multicast Hash Table Low */
37#define MAC_MII_ADDR 0x00000014 /* MII Address */
38#define MAC_MII_DATA 0x00000018 /* MII Data */
39#define MAC_FLOW_CTRL 0x0000001c /* Flow Control */
40#define MAC_VLAN1 0x00000020 /* VLAN1 Tag */
41#define MAC_VLAN2 0x00000024 /* VLAN2 Tag */
42
43/* MAC CTRL defines */
44#define MAC_CONTROL_RA 0x80000000 /* Receive All Mode */
45#define MAC_CONTROL_BLE 0x40000000 /* Endian Mode */
46#define MAC_CONTROL_HBD 0x10000000 /* Heartbeat Disable */
47#define MAC_CONTROL_PS 0x08000000 /* Port Select */
48#define MAC_CONTROL_DRO 0x00800000 /* Disable Receive Own */
49#define MAC_CONTROL_EXT_LOOPBACK 0x00400000 /* Reserved (ext loopback?) */
50#define MAC_CONTROL_OM 0x00200000 /* Loopback Operating Mode */
51#define MAC_CONTROL_F 0x00100000 /* Full Duplex Mode */
52#define MAC_CONTROL_PM 0x00080000 /* Pass All Multicast */
53#define MAC_CONTROL_PR 0x00040000 /* Promiscuous Mode */
54#define MAC_CONTROL_IF 0x00020000 /* Inverse Filtering */
55#define MAC_CONTROL_PB 0x00010000 /* Pass Bad Frames */
56#define MAC_CONTROL_HO 0x00008000 /* Hash Only Filtering Mode */
57#define MAC_CONTROL_HP 0x00002000 /* Hash/Perfect Filtering Mode */
58#define MAC_CONTROL_LCC 0x00001000 /* Late Collision Control */
59#define MAC_CONTROL_DBF 0x00000800 /* Disable Broadcast Frames */
60#define MAC_CONTROL_DRTY 0x00000400 /* Disable Retry */
61#define MAC_CONTROL_ASTP 0x00000100 /* Automatic Pad Stripping */
62#define MAC_CONTROL_BOLMT_10 0x00000000 /* Back Off Limit 10 */
63#define MAC_CONTROL_BOLMT_8 0x00000040 /* Back Off Limit 8 */
64#define MAC_CONTROL_BOLMT_4 0x00000080 /* Back Off Limit 4 */
65#define MAC_CONTROL_BOLMT_1 0x000000c0 /* Back Off Limit 1 */
66#define MAC_CONTROL_DC 0x00000020 /* Deferral Check */
67#define MAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
68#define MAC_CONTROL_RE 0x00000004 /* Receiver Enable */
69
70#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
71
72/* MAC FLOW CTRL defines */
73#define MAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */
74#define MAC_FLOW_CTRL_PT_SHIFT 16
75#define MAC_FLOW_CTRL_PASS 0x00000004 /* Pass Control Frames */
76#define MAC_FLOW_CTRL_ENABLE 0x00000002 /* Flow Control Enable */
77#define MAC_FLOW_CTRL_PAUSE 0x00000001 /* Flow Control Busy ... */
78
79/* MII ADDR defines */
80#define MAC_MII_ADDR_WRITE 0x00000002 /* MII Write */
81#define MAC_MII_ADDR_BUSY 0x00000001 /* MII Busy */
82
83/*----------------------------------------------------------------------------
84 * DMA BLOCK defines
85 *---------------------------------------------------------------------------*/
86
87/* DMA Bus Mode register defines */
88#define DMA_BUS_MODE_DBO 0x00100000 /* Descriptor Byte Ordering */
89#define DMA_BUS_MODE_BLE 0x00000080 /* Big Endian/Little Endian */
90#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */
91#define DMA_BUS_MODE_PBL_SHIFT 8
92#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */
93#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */
94#define DMA_BUS_MODE_BAR_BUS 0x00000002 /* Bar-Bus Arbitration */
95#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
96#define DMA_BUS_MODE_DEFAULT 0x00000000
97
98/* DMA Control register defines */
99#define DMA_CONTROL_SF 0x00200000 /* Store And Forward */
100
101/* Transmit Threshold Control */
102enum ttc_control {
103 DMA_CONTROL_TTC_DEFAULT = 0x00000000, /* Threshold is 32 DWORDS */
104 DMA_CONTROL_TTC_64 = 0x00004000, /* Threshold is 64 DWORDS */
105 DMA_CONTROL_TTC_128 = 0x00008000, /* Threshold is 128 DWORDS */
106 DMA_CONTROL_TTC_256 = 0x0000c000, /* Threshold is 256 DWORDS */
107 DMA_CONTROL_TTC_18 = 0x00400000, /* Threshold is 18 DWORDS */
108 DMA_CONTROL_TTC_24 = 0x00404000, /* Threshold is 24 DWORDS */
109 DMA_CONTROL_TTC_32 = 0x00408000, /* Threshold is 32 DWORDS */
110 DMA_CONTROL_TTC_40 = 0x0040c000, /* Threshold is 40 DWORDS */
111 DMA_CONTROL_SE = 0x00000008, /* Stop On Empty */
112 DMA_CONTROL_OSF = 0x00000004, /* Operate On 2nd Frame */
113};
114
115/* STMAC110 DMA Missed Frame Counter register defines */
116#define DMA_MISSED_FRAME_OVE 0x10000000 /* FIFO Overflow Overflow */
117#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */
118#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */
119#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */
120
121extern const struct stmmac_dma_ops dwmac100_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
new file mode 100644
index 000000000000..cfcef0ea0fa5
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -0,0 +1,208 @@
1/*******************************************************************************
2 Copyright (C) 2007-2009 STMicroelectronics Ltd
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms and conditions of the GNU General Public License,
6 version 2, as published by the Free Software Foundation.
7
8 This program is distributed in the hope it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16
17 The full GNU General Public License is included in this distribution in
18 the file called "COPYING".
19
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/
22
23#include <linux/phy.h>
24#include "common.h"
25
26#define GMAC_CONTROL 0x00000000 /* Configuration */
27#define GMAC_FRAME_FILTER 0x00000004 /* Frame Filter */
28#define GMAC_HASH_HIGH 0x00000008 /* Multicast Hash Table High */
29#define GMAC_HASH_LOW 0x0000000c /* Multicast Hash Table Low */
30#define GMAC_MII_ADDR 0x00000010 /* MII Address */
31#define GMAC_MII_DATA 0x00000014 /* MII Data */
32#define GMAC_FLOW_CTRL 0x00000018 /* Flow Control */
33#define GMAC_VLAN_TAG 0x0000001c /* VLAN Tag */
34#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
35#define GMAC_WAKEUP_FILTER 0x00000028 /* Wake-up Frame Filter */
36
37#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */
38enum dwmac1000_irq_status {
39 time_stamp_irq = 0x0200,
40 mmc_rx_csum_offload_irq = 0x0080,
41 mmc_tx_irq = 0x0040,
42 mmc_rx_irq = 0x0020,
43 mmc_irq = 0x0010,
44 pmt_irq = 0x0008,
45 pcs_ane_irq = 0x0004,
46 pcs_link_irq = 0x0002,
47 rgmii_irq = 0x0001,
48};
49#define GMAC_INT_MASK 0x0000003c /* interrupt mask register */
50
51/* PMT Control and Status */
52#define GMAC_PMT 0x0000002c
53enum power_event {
54 pointer_reset = 0x80000000,
55 global_unicast = 0x00000200,
56 wake_up_rx_frame = 0x00000040,
57 magic_frame = 0x00000020,
58 wake_up_frame_en = 0x00000004,
59 magic_pkt_en = 0x00000002,
60 power_down = 0x00000001,
61};
62
63/* GMAC HW ADDR regs */
64#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8))
65#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8))
66#define GMAC_MAX_UNICAST_ADDRESSES 16
67
68#define GMAC_AN_CTRL 0x000000c0 /* AN control */
69#define GMAC_AN_STATUS 0x000000c4 /* AN status */
70#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */
71#define GMAC_ANE_LINK 0x000000cc /* Auto-Neg. link partener ability */
72#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */
73#define GMAC_TBI 0x000000d4 /* TBI extend status */
74#define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */
75
76/* GMAC Configuration defines */
77#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
78#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on receive */
79#define GMAC_CONTROL_JD 0x00400000 /* Jabber disable */
80#define GMAC_CONTROL_BE 0x00200000 /* Frame Burst Enable */
81#define GMAC_CONTROL_JE 0x00100000 /* Jumbo frame */
82enum inter_frame_gap {
83 GMAC_CONTROL_IFG_88 = 0x00040000,
84 GMAC_CONTROL_IFG_80 = 0x00020000,
85 GMAC_CONTROL_IFG_40 = 0x000e0000,
86};
87#define GMAC_CONTROL_DCRS 0x00010000 /* Disable carrier sense during tx */
88#define GMAC_CONTROL_PS 0x00008000 /* Port Select 0:GMI 1:MII */
89#define GMAC_CONTROL_FES 0x00004000 /* Speed 0:10 1:100 */
90#define GMAC_CONTROL_DO 0x00002000 /* Disable Rx Own */
91#define GMAC_CONTROL_LM 0x00001000 /* Loop-back mode */
92#define GMAC_CONTROL_DM 0x00000800 /* Duplex Mode */
93#define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */
94#define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */
95#define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */
96#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad/FCS Stripping */
97#define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */
98#define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
99#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
100
101#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
102 GMAC_CONTROL_JE | GMAC_CONTROL_BE)
103
104/* GMAC Frame Filter defines */
105#define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
106#define GMAC_FRAME_FILTER_HUC 0x00000002 /* Hash Unicast */
107#define GMAC_FRAME_FILTER_HMC 0x00000004 /* Hash Multicast */
108#define GMAC_FRAME_FILTER_DAIF 0x00000008 /* DA Inverse Filtering */
109#define GMAC_FRAME_FILTER_PM 0x00000010 /* Pass all multicast */
110#define GMAC_FRAME_FILTER_DBF 0x00000020 /* Disable Broadcast frames */
111#define GMAC_FRAME_FILTER_SAIF 0x00000100 /* Inverse Filtering */
112#define GMAC_FRAME_FILTER_SAF 0x00000200 /* Source Address Filter */
113#define GMAC_FRAME_FILTER_HPF 0x00000400 /* Hash or perfect Filter */
114#define GMAC_FRAME_FILTER_RA 0x80000000 /* Receive all mode */
115/* GMII ADDR defines */
116#define GMAC_MII_ADDR_WRITE 0x00000002 /* MII Write */
117#define GMAC_MII_ADDR_BUSY 0x00000001 /* MII Busy */
118/* GMAC FLOW CTRL defines */
119#define GMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */
120#define GMAC_FLOW_CTRL_PT_SHIFT 16
121#define GMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */
122#define GMAC_FLOW_CTRL_TFE 0x00000002 /* Tx Flow Control Enable */
123#define GMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */
124
125/*--- DMA BLOCK defines ---*/
126/* DMA Bus Mode register defines */
127#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
128#define DMA_BUS_MODE_DA 0x00000002 /* Arbitration scheme */
129#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */
130#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */
131/* Programmable burst length (passed thorugh platform)*/
132#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */
133#define DMA_BUS_MODE_PBL_SHIFT 8
134
135enum rx_tx_priority_ratio {
136 double_ratio = 0x00004000, /*2:1 */
137 triple_ratio = 0x00008000, /*3:1 */
138 quadruple_ratio = 0x0000c000, /*4:1 */
139};
140
141#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */
142#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */
143#define DMA_BUS_MODE_RPBL_SHIFT 17
144#define DMA_BUS_MODE_USP 0x00800000
145#define DMA_BUS_MODE_4PBL 0x01000000
146#define DMA_BUS_MODE_AAL 0x02000000
147
148/* DMA CRS Control and Status Register Mapping */
149#define DMA_HOST_TX_DESC 0x00001048 /* Current Host Tx descriptor */
150#define DMA_HOST_RX_DESC 0x0000104c /* Current Host Rx descriptor */
151/* DMA Bus Mode register defines */
152#define DMA_BUS_PR_RATIO_MASK 0x0000c000 /* Rx/Tx priority ratio */
153#define DMA_BUS_PR_RATIO_SHIFT 14
154#define DMA_BUS_FB 0x00010000 /* Fixed Burst */
155
156/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
157#define DMA_CONTROL_DT 0x04000000 /* Disable Drop TCP/IP csum error */
158#define DMA_CONTROL_RSF 0x02000000 /* Receive Store and Forward */
159#define DMA_CONTROL_DFF 0x01000000 /* Disaable flushing */
160/* Threshold for Activating the FC */
161enum rfa {
162 act_full_minus_1 = 0x00800000,
163 act_full_minus_2 = 0x00800200,
164 act_full_minus_3 = 0x00800400,
165 act_full_minus_4 = 0x00800600,
166};
167/* Threshold for Deactivating the FC */
168enum rfd {
169 deac_full_minus_1 = 0x00400000,
170 deac_full_minus_2 = 0x00400800,
171 deac_full_minus_3 = 0x00401000,
172 deac_full_minus_4 = 0x00401800,
173};
174#define DMA_CONTROL_TSF 0x00200000 /* Transmit Store and Forward */
175
176enum ttc_control {
177 DMA_CONTROL_TTC_64 = 0x00000000,
178 DMA_CONTROL_TTC_128 = 0x00004000,
179 DMA_CONTROL_TTC_192 = 0x00008000,
180 DMA_CONTROL_TTC_256 = 0x0000c000,
181 DMA_CONTROL_TTC_40 = 0x00010000,
182 DMA_CONTROL_TTC_32 = 0x00014000,
183 DMA_CONTROL_TTC_24 = 0x00018000,
184 DMA_CONTROL_TTC_16 = 0x0001c000,
185};
186#define DMA_CONTROL_TC_TX_MASK 0xfffe3fff
187
188#define DMA_CONTROL_EFC 0x00000100
189#define DMA_CONTROL_FEF 0x00000080
190#define DMA_CONTROL_FUF 0x00000040
191
192enum rtc_control {
193 DMA_CONTROL_RTC_64 = 0x00000000,
194 DMA_CONTROL_RTC_32 = 0x00000008,
195 DMA_CONTROL_RTC_96 = 0x00000010,
196 DMA_CONTROL_RTC_128 = 0x00000018,
197};
198#define DMA_CONTROL_TC_RX_MASK 0xffffffe7
199
200#define DMA_CONTROL_OSF 0x00000004 /* Operate on second frame */
201
202/* MMC registers offset */
203#define GMAC_MMC_CTRL 0x100
204#define GMAC_MMC_RX_INTR 0x104
205#define GMAC_MMC_TX_INTR 0x108
206#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
207
208extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
new file mode 100644
index 000000000000..0f63b3c83c19
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -0,0 +1,251 @@
1/*******************************************************************************
2 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code.
5
6 This only implements the mac core functions for this chip.
7
8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23 The full GNU General Public License is included in this distribution in
24 the file called "COPYING".
25
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/
28
29#include <linux/crc32.h>
30#include <linux/slab.h>
31#include <asm/io.h>
32#include "dwmac1000.h"
33
34static void dwmac1000_core_init(void __iomem *ioaddr)
35{
36 u32 value = readl(ioaddr + GMAC_CONTROL);
37 value |= GMAC_CORE_INIT;
38 writel(value, ioaddr + GMAC_CONTROL);
39
40 /* STBus Bridge Configuration */
41 /*writel(0xc5608, ioaddr + 0x00007000);*/
42
43 /* Freeze MMC counters */
44 writel(0x8, ioaddr + GMAC_MMC_CTRL);
45 /* Mask GMAC interrupts */
46 writel(0x207, ioaddr + GMAC_INT_MASK);
47
48#ifdef STMMAC_VLAN_TAG_USED
49 /* Tag detection without filtering */
50 writel(0x0, ioaddr + GMAC_VLAN_TAG);
51#endif
52}
53
54static int dwmac1000_rx_coe_supported(void __iomem *ioaddr)
55{
56 u32 value = readl(ioaddr + GMAC_CONTROL);
57
58 value |= GMAC_CONTROL_IPC;
59 writel(value, ioaddr + GMAC_CONTROL);
60
61 value = readl(ioaddr + GMAC_CONTROL);
62
63 return !!(value & GMAC_CONTROL_IPC);
64}
65
66static void dwmac1000_dump_regs(void __iomem *ioaddr)
67{
68 int i;
69 pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
70
71 for (i = 0; i < 55; i++) {
72 int offset = i * 4;
73 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
74 offset, readl(ioaddr + offset));
75 }
76}
77
78static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
79 unsigned int reg_n)
80{
81 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
82 GMAC_ADDR_LOW(reg_n));
83}
84
85static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
86 unsigned int reg_n)
87{
88 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
89 GMAC_ADDR_LOW(reg_n));
90}
91
92static void dwmac1000_set_filter(struct net_device *dev)
93{
94 void __iomem *ioaddr = (void __iomem *) dev->base_addr;
95 unsigned int value = 0;
96
97 CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
98 __func__, netdev_mc_count(dev), netdev_uc_count(dev));
99
100 if (dev->flags & IFF_PROMISC)
101 value = GMAC_FRAME_FILTER_PR;
102 else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
103 || (dev->flags & IFF_ALLMULTI)) {
104 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
105 writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
106 writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
107 } else if (!netdev_mc_empty(dev)) {
108 u32 mc_filter[2];
109 struct netdev_hw_addr *ha;
110
111 /* Hash filter for multicast */
112 value = GMAC_FRAME_FILTER_HMC;
113
114 memset(mc_filter, 0, sizeof(mc_filter));
115 netdev_for_each_mc_addr(ha, dev) {
116 /* The upper 6 bits of the calculated CRC are used to
117 index the contens of the hash table */
118 int bit_nr =
119 bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;
120 /* The most significant bit determines the register to
121 * use (H/L) while the other 5 bits determine the bit
122 * within the register. */
123 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
124 }
125 writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
126 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
127 }
128
129 /* Handle multiple unicast addresses (perfect filtering)*/
130 if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
131 /* Switch to promiscuous mode is more than 16 addrs
132 are required */
133 value |= GMAC_FRAME_FILTER_PR;
134 else {
135 int reg = 1;
136 struct netdev_hw_addr *ha;
137
138 netdev_for_each_uc_addr(ha, dev) {
139 dwmac1000_set_umac_addr(ioaddr, ha->addr, reg);
140 reg++;
141 }
142 }
143
144#ifdef FRAME_FILTER_DEBUG
145 /* Enable Receive all mode (to debug filtering_fail errors) */
146 value |= GMAC_FRAME_FILTER_RA;
147#endif
148 writel(value, ioaddr + GMAC_FRAME_FILTER);
149
150 CHIP_DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
151 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
152 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
153}
154
155static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
156 unsigned int fc, unsigned int pause_time)
157{
158 unsigned int flow = 0;
159
160 CHIP_DBG(KERN_DEBUG "GMAC Flow-Control:\n");
161 if (fc & FLOW_RX) {
162 CHIP_DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
163 flow |= GMAC_FLOW_CTRL_RFE;
164 }
165 if (fc & FLOW_TX) {
166 CHIP_DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
167 flow |= GMAC_FLOW_CTRL_TFE;
168 }
169
170 if (duplex) {
171 CHIP_DBG(KERN_DEBUG "\tduplex mode: PAUSE %d\n", pause_time);
172 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
173 }
174
175 writel(flow, ioaddr + GMAC_FLOW_CTRL);
176}
177
178static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode)
179{
180 unsigned int pmt = 0;
181
182 if (mode & WAKE_MAGIC) {
183 CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
184 pmt |= power_down | magic_pkt_en;
185 }
186 if (mode & WAKE_UCAST) {
187 CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
188 pmt |= global_unicast;
189 }
190
191 writel(pmt, ioaddr + GMAC_PMT);
192}
193
194
195static void dwmac1000_irq_status(void __iomem *ioaddr)
196{
197 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
198
199 /* Not used events (e.g. MMC interrupts) are not handled. */
200 if ((intr_status & mmc_tx_irq))
201 CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
202 readl(ioaddr + GMAC_MMC_TX_INTR));
203 if (unlikely(intr_status & mmc_rx_irq))
204 CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
205 readl(ioaddr + GMAC_MMC_RX_INTR));
206 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
207 CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
208 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
209 if (unlikely(intr_status & pmt_irq)) {
210 CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n");
211 /* clear the PMT bits 5 and 6 by reading the PMT
212 * status register. */
213 readl(ioaddr + GMAC_PMT);
214 }
215}
216
217static const struct stmmac_ops dwmac1000_ops = {
218 .core_init = dwmac1000_core_init,
219 .rx_coe = dwmac1000_rx_coe_supported,
220 .dump_regs = dwmac1000_dump_regs,
221 .host_irq_status = dwmac1000_irq_status,
222 .set_filter = dwmac1000_set_filter,
223 .flow_ctrl = dwmac1000_flow_ctrl,
224 .pmt = dwmac1000_pmt,
225 .set_umac_addr = dwmac1000_set_umac_addr,
226 .get_umac_addr = dwmac1000_get_umac_addr,
227};
228
229struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr)
230{
231 struct mac_device_info *mac;
232 u32 uid = readl(ioaddr + GMAC_VERSION);
233
234 pr_info("\tDWMAC1000 - user ID: 0x%x, Synopsys ID: 0x%x\n",
235 ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
236
237 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
238 if (!mac)
239 return NULL;
240
241 mac->mac = &dwmac1000_ops;
242 mac->dma = &dwmac1000_dma_ops;
243
244 mac->link.port = GMAC_CONTROL_PS;
245 mac->link.duplex = GMAC_CONTROL_DM;
246 mac->link.speed = GMAC_CONTROL_FES;
247 mac->mii.addr = GMAC_MII_ADDR;
248 mac->mii.data = GMAC_MII_DATA;
249
250 return mac;
251}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
new file mode 100644
index 000000000000..3dbeea619085
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -0,0 +1,155 @@
1/*******************************************************************************
2 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code.
5
6 This contains the functions to handle the dma.
7
8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23 The full GNU General Public License is included in this distribution in
24 the file called "COPYING".
25
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/
28
29#include <asm/io.h>
30#include "dwmac1000.h"
31#include "dwmac_dma.h"
32
33static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
34 u32 dma_rx)
35{
36 u32 value = readl(ioaddr + DMA_BUS_MODE);
37 int limit;
38
39 /* DMA SW reset */
40 value |= DMA_BUS_MODE_SFT_RESET;
41 writel(value, ioaddr + DMA_BUS_MODE);
42 limit = 15000;
43 while (limit--) {
44 if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
45 break;
46 }
47 if (limit < 0)
48 return -EBUSY;
49
50 value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
51 ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
52 (pbl << DMA_BUS_MODE_RPBL_SHIFT));
53
54#ifdef CONFIG_STMMAC_DA
55 value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */
56#endif
57 writel(value, ioaddr + DMA_BUS_MODE);
58
59 /* Mask interrupts by writing to CSR7 */
60 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
61
62 /* The base address of the RX/TX descriptor lists must be written into
63 * DMA CSR3 and CSR4, respectively. */
64 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
65 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
66
67 return 0;
68}
69
70static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
71 int rxmode)
72{
73 u32 csr6 = readl(ioaddr + DMA_CONTROL);
74
75 if (txmode == SF_DMA_MODE) {
76 CHIP_DBG(KERN_DEBUG "GMAC: enable TX store and forward mode\n");
77 /* Transmit COE type 2 cannot be done in cut-through mode. */
78 csr6 |= DMA_CONTROL_TSF;
79 /* Operating on second frame increase the performance
80 * especially when transmit store-and-forward is used.*/
81 csr6 |= DMA_CONTROL_OSF;
82 } else {
83 CHIP_DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
84 " (threshold = %d)\n", txmode);
85 csr6 &= ~DMA_CONTROL_TSF;
86 csr6 &= DMA_CONTROL_TC_TX_MASK;
87 /* Set the transmit threshold */
88 if (txmode <= 32)
89 csr6 |= DMA_CONTROL_TTC_32;
90 else if (txmode <= 64)
91 csr6 |= DMA_CONTROL_TTC_64;
92 else if (txmode <= 128)
93 csr6 |= DMA_CONTROL_TTC_128;
94 else if (txmode <= 192)
95 csr6 |= DMA_CONTROL_TTC_192;
96 else
97 csr6 |= DMA_CONTROL_TTC_256;
98 }
99
100 if (rxmode == SF_DMA_MODE) {
101 CHIP_DBG(KERN_DEBUG "GMAC: enable RX store and forward mode\n");
102 csr6 |= DMA_CONTROL_RSF;
103 } else {
104 CHIP_DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
105 " (threshold = %d)\n", rxmode);
106 csr6 &= ~DMA_CONTROL_RSF;
107 csr6 &= DMA_CONTROL_TC_RX_MASK;
108 if (rxmode <= 32)
109 csr6 |= DMA_CONTROL_RTC_32;
110 else if (rxmode <= 64)
111 csr6 |= DMA_CONTROL_RTC_64;
112 else if (rxmode <= 96)
113 csr6 |= DMA_CONTROL_RTC_96;
114 else
115 csr6 |= DMA_CONTROL_RTC_128;
116 }
117
118 writel(csr6, ioaddr + DMA_CONTROL);
119}
120
121/* Not yet implemented --- no RMON module */
122static void dwmac1000_dma_diagnostic_fr(void *data,
123 struct stmmac_extra_stats *x, void __iomem *ioaddr)
124{
125 return;
126}
127
128static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
129{
130 int i;
131 pr_info(" DMA registers\n");
132 for (i = 0; i < 22; i++) {
133 if ((i < 9) || (i > 17)) {
134 int offset = i * 4;
135 pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
136 (DMA_BUS_MODE + offset),
137 readl(ioaddr + DMA_BUS_MODE + offset));
138 }
139 }
140}
141
142const struct stmmac_dma_ops dwmac1000_dma_ops = {
143 .init = dwmac1000_dma_init,
144 .dump_regs = dwmac1000_dump_dma_regs,
145 .dma_mode = dwmac1000_dma_operation_mode,
146 .dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
147 .enable_dma_transmission = dwmac_enable_dma_transmission,
148 .enable_dma_irq = dwmac_enable_dma_irq,
149 .disable_dma_irq = dwmac_disable_dma_irq,
150 .start_tx = dwmac_dma_start_tx,
151 .stop_tx = dwmac_dma_stop_tx,
152 .start_rx = dwmac_dma_start_rx,
153 .stop_rx = dwmac_dma_stop_rx,
154 .dma_interrupt = dwmac_dma_interrupt,
155};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
new file mode 100644
index 000000000000..743a58017637
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -0,0 +1,204 @@
1/*******************************************************************************
2 This is the driver for the MAC 10/100 on-chip Ethernet controller
3 currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
4
5 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
6 this code.
7
8 This only implements the mac core functions for this chip.
9
10 Copyright (C) 2007-2009 STMicroelectronics Ltd
11
12 This program is free software; you can redistribute it and/or modify it
13 under the terms and conditions of the GNU General Public License,
14 version 2, as published by the Free Software Foundation.
15
16 This program is distributed in the hope it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 more details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
24
25 The full GNU General Public License is included in this distribution in
26 the file called "COPYING".
27
28 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
29*******************************************************************************/
30
31#include <linux/crc32.h>
32#include <asm/io.h>
33#include "dwmac100.h"
34
35static void dwmac100_core_init(void __iomem *ioaddr)
36{
37 u32 value = readl(ioaddr + MAC_CONTROL);
38
39 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
40
41#ifdef STMMAC_VLAN_TAG_USED
42 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
43#endif
44}
45
46static int dwmac100_rx_coe_supported(void __iomem *ioaddr)
47{
48 return 0;
49}
50
51static void dwmac100_dump_mac_regs(void __iomem *ioaddr)
52{
53 pr_info("\t----------------------------------------------\n"
54 "\t DWMAC 100 CSR (base addr = 0x%p)\n"
55 "\t----------------------------------------------\n",
56 ioaddr);
57 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
58 readl(ioaddr + MAC_CONTROL));
59 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
60 readl(ioaddr + MAC_ADDR_HIGH));
61 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
62 readl(ioaddr + MAC_ADDR_LOW));
63 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
64 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
65 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
66 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
67 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
68 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
69 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
70 readl(ioaddr + MAC_VLAN1));
71 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
72 readl(ioaddr + MAC_VLAN2));
73 pr_info("\n\tMAC management counter registers\n");
74 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
75 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
76 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
77 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
78 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
79 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
80 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
81 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
82 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
83 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
84}
85
86static void dwmac100_irq_status(void __iomem *ioaddr)
87{
88 return;
89}
90
91static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
92 unsigned int reg_n)
93{
94 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
95}
96
97static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
98 unsigned int reg_n)
99{
100 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
101}
102
103static void dwmac100_set_filter(struct net_device *dev)
104{
105 void __iomem *ioaddr = (void __iomem *) dev->base_addr;
106 u32 value = readl(ioaddr + MAC_CONTROL);
107
108 if (dev->flags & IFF_PROMISC) {
109 value |= MAC_CONTROL_PR;
110 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
111 MAC_CONTROL_HP);
112 } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
113 || (dev->flags & IFF_ALLMULTI)) {
114 value |= MAC_CONTROL_PM;
115 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
116 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
117 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
118 } else if (netdev_mc_empty(dev)) { /* no multicast */
119 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
120 MAC_CONTROL_HO | MAC_CONTROL_HP);
121 } else {
122 u32 mc_filter[2];
123 struct netdev_hw_addr *ha;
124
125 /* Perfect filter mode for physical address and Hash
126 filter for multicast */
127 value |= MAC_CONTROL_HP;
128 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
129 MAC_CONTROL_IF | MAC_CONTROL_HO);
130
131 memset(mc_filter, 0, sizeof(mc_filter));
132 netdev_for_each_mc_addr(ha, dev) {
133 /* The upper 6 bits of the calculated CRC are used to
134 * index the contens of the hash table */
135 int bit_nr =
136 ether_crc(ETH_ALEN, ha->addr) >> 26;
137 /* The most significant bit determines the register to
138 * use (H/L) while the other 5 bits determine the bit
139 * within the register. */
140 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
141 }
142 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
143 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
144 }
145
146 writel(value, ioaddr + MAC_CONTROL);
147
148 CHIP_DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
149 "HI 0x%08x, LO 0x%08x\n",
150 __func__, readl(ioaddr + MAC_CONTROL),
151 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
152}
153
154static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex,
155 unsigned int fc, unsigned int pause_time)
156{
157 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
158
159 if (duplex)
160 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
161 writel(flow, ioaddr + MAC_FLOW_CTRL);
162}
163
164/* No PMT module supported for this Ethernet Controller.
165 * Tested on ST platforms only.
166 */
167static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode)
168{
169 return;
170}
171
172static const struct stmmac_ops dwmac100_ops = {
173 .core_init = dwmac100_core_init,
174 .rx_coe = dwmac100_rx_coe_supported,
175 .dump_regs = dwmac100_dump_mac_regs,
176 .host_irq_status = dwmac100_irq_status,
177 .set_filter = dwmac100_set_filter,
178 .flow_ctrl = dwmac100_flow_ctrl,
179 .pmt = dwmac100_pmt,
180 .set_umac_addr = dwmac100_set_umac_addr,
181 .get_umac_addr = dwmac100_get_umac_addr,
182};
183
184struct mac_device_info *dwmac100_setup(void __iomem *ioaddr)
185{
186 struct mac_device_info *mac;
187
188 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
189 if (!mac)
190 return NULL;
191
192 pr_info("\tDWMAC100\n");
193
194 mac->mac = &dwmac100_ops;
195 mac->dma = &dwmac100_dma_ops;
196
197 mac->link.port = MAC_CONTROL_PS;
198 mac->link.duplex = MAC_CONTROL_F;
199 mac->link.speed = 0;
200 mac->mii.addr = MAC_MII_ADDR;
201 mac->mii.data = MAC_MII_DATA;
202
203 return mac;
204}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
new file mode 100644
index 000000000000..627f656b0f3c
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -0,0 +1,143 @@
1/*******************************************************************************
2 This is the driver for the MAC 10/100 on-chip Ethernet controller
3 currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
4
5 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
6 this code.
7
8 This contains the functions to handle the dma.
9
10 Copyright (C) 2007-2009 STMicroelectronics Ltd
11
12 This program is free software; you can redistribute it and/or modify it
13 under the terms and conditions of the GNU General Public License,
14 version 2, as published by the Free Software Foundation.
15
16 This program is distributed in the hope it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 more details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
24
25 The full GNU General Public License is included in this distribution in
26 the file called "COPYING".
27
28 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
29*******************************************************************************/
30
31#include <asm/io.h>
32#include "dwmac100.h"
33#include "dwmac_dma.h"
34
35static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx,
36 u32 dma_rx)
37{
38 u32 value = readl(ioaddr + DMA_BUS_MODE);
39 int limit;
40
41 /* DMA SW reset */
42 value |= DMA_BUS_MODE_SFT_RESET;
43 writel(value, ioaddr + DMA_BUS_MODE);
44 limit = 15000;
45 while (limit--) {
46 if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
47 break;
48 }
49 if (limit < 0)
50 return -EBUSY;
51
52 /* Enable Application Access by writing to DMA CSR0 */
53 writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
54 ioaddr + DMA_BUS_MODE);
55
56 /* Mask interrupts by writing to CSR7 */
57 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
58
59 /* The base address of the RX/TX descriptor lists must be written into
60 * DMA CSR3 and CSR4, respectively. */
61 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
62 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
63
64 return 0;
65}
66
67/* Store and Forward capability is not used at all..
68 * The transmit threshold can be programmed by
69 * setting the TTC bits in the DMA control register.*/
70static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
71 int rxmode)
72{
73 u32 csr6 = readl(ioaddr + DMA_CONTROL);
74
75 if (txmode <= 32)
76 csr6 |= DMA_CONTROL_TTC_32;
77 else if (txmode <= 64)
78 csr6 |= DMA_CONTROL_TTC_64;
79 else
80 csr6 |= DMA_CONTROL_TTC_128;
81
82 writel(csr6, ioaddr + DMA_CONTROL);
83}
84
85static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
86{
87 int i;
88
89 CHIP_DBG(KERN_DEBUG "DWMAC 100 DMA CSR\n");
90 for (i = 0; i < 9; i++)
91 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
92 (DMA_BUS_MODE + i * 4),
93 readl(ioaddr + DMA_BUS_MODE + i * 4));
94 CHIP_DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
95 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
96 CHIP_DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
97 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
98}
99
100/* DMA controller has two counters to track the number of
101 * the receive missed frames. */
102static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
103 void __iomem *ioaddr)
104{
105 struct net_device_stats *stats = (struct net_device_stats *)data;
106 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
107
108 if (unlikely(csr8)) {
109 if (csr8 & DMA_MISSED_FRAME_OVE) {
110 stats->rx_over_errors += 0x800;
111 x->rx_overflow_cntr += 0x800;
112 } else {
113 unsigned int ove_cntr;
114 ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
115 stats->rx_over_errors += ove_cntr;
116 x->rx_overflow_cntr += ove_cntr;
117 }
118
119 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
120 stats->rx_missed_errors += 0xffff;
121 x->rx_missed_cntr += 0xffff;
122 } else {
123 unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
124 stats->rx_missed_errors += miss_f;
125 x->rx_missed_cntr += miss_f;
126 }
127 }
128}
129
130const struct stmmac_dma_ops dwmac100_dma_ops = {
131 .init = dwmac100_dma_init,
132 .dump_regs = dwmac100_dump_dma_regs,
133 .dma_mode = dwmac100_dma_operation_mode,
134 .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
135 .enable_dma_transmission = dwmac_enable_dma_transmission,
136 .enable_dma_irq = dwmac_enable_dma_irq,
137 .disable_dma_irq = dwmac_disable_dma_irq,
138 .start_tx = dwmac_dma_start_tx,
139 .stop_tx = dwmac_dma_stop_tx,
140 .start_rx = dwmac_dma_start_rx,
141 .stop_rx = dwmac_dma_stop_rx,
142 .dma_interrupt = dwmac_dma_interrupt,
143};
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
new file mode 100644
index 000000000000..da3f5ccf83d3
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -0,0 +1,108 @@
1/*******************************************************************************
2 DWMAC DMA Header file.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25/* DMA CRS Control and Status Register Mapping */
26#define DMA_BUS_MODE 0x00001000 /* Bus Mode */
27#define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */
28#define DMA_RCV_POLL_DEMAND 0x00001008 /* Received Poll Demand */
29#define DMA_RCV_BASE_ADDR 0x0000100c /* Receive List Base */
30#define DMA_TX_BASE_ADDR 0x00001010 /* Transmit List Base */
31#define DMA_STATUS 0x00001014 /* Status Register */
32#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
33#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
34#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
35#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
36#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
37
38/* DMA Control register defines */
39#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
40#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */
41
42/* DMA Normal interrupt */
43#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */
44#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */
45#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavailable */
46#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */
47#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */
48
49#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
50 DMA_INTR_ENA_TIE)
51
52/* DMA Abnormal interrupt */
53#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */
54#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */
55#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */
56#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */
57#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */
58#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */
59#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */
60#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */
61#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */
62#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */
63
64#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
65 DMA_INTR_ENA_UNE)
66
67/* DMA default interrupt mask */
68#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
69
70/* DMA Status register defines */
71#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */
72#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */
73#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */
74#define DMA_STATUS_GMI 0x08000000
75#define DMA_STATUS_GLI 0x04000000
76#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */
77#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */
78#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */
79#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */
80#define DMA_STATUS_TS_SHIFT 20
81#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */
82#define DMA_STATUS_RS_SHIFT 17
83#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */
84#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */
85#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */
86#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */
87#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */
88#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */
89#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */
90#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */
91#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */
92#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */
93#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */
94#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */
95#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */
96#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */
97#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
98#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
99
100extern void dwmac_enable_dma_transmission(void __iomem *ioaddr);
101extern void dwmac_enable_dma_irq(void __iomem *ioaddr);
102extern void dwmac_disable_dma_irq(void __iomem *ioaddr);
103extern void dwmac_dma_start_tx(void __iomem *ioaddr);
104extern void dwmac_dma_stop_tx(void __iomem *ioaddr);
105extern void dwmac_dma_start_rx(void __iomem *ioaddr);
106extern void dwmac_dma_stop_rx(void __iomem *ioaddr);
107extern int dwmac_dma_interrupt(void __iomem *ioaddr,
108 struct stmmac_extra_stats *x);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
new file mode 100644
index 000000000000..e25093510b0c
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -0,0 +1,258 @@
1/*******************************************************************************
2 Copyright (C) 2007-2009 STMicroelectronics Ltd
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms and conditions of the GNU General Public License,
6 version 2, as published by the Free Software Foundation.
7
8 This program is distributed in the hope it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16
17 The full GNU General Public License is included in this distribution in
18 the file called "COPYING".
19
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/
22
23#include <linux/io.h>
24#include "common.h"
25#include "dwmac_dma.h"
26
27#undef DWMAC_DMA_DEBUG
28#ifdef DWMAC_DMA_DEBUG
29#define DWMAC_LIB_DBG(fmt, args...) printk(fmt, ## args)
30#else
31#define DWMAC_LIB_DBG(fmt, args...) do { } while (0)
32#endif
33
34/* CSR1 enables the transmit DMA to check for new descriptor */
35void dwmac_enable_dma_transmission(void __iomem *ioaddr)
36{
37 writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
38}
39
40void dwmac_enable_dma_irq(void __iomem *ioaddr)
41{
42 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
43}
44
45void dwmac_disable_dma_irq(void __iomem *ioaddr)
46{
47 writel(0, ioaddr + DMA_INTR_ENA);
48}
49
50void dwmac_dma_start_tx(void __iomem *ioaddr)
51{
52 u32 value = readl(ioaddr + DMA_CONTROL);
53 value |= DMA_CONTROL_ST;
54 writel(value, ioaddr + DMA_CONTROL);
55}
56
57void dwmac_dma_stop_tx(void __iomem *ioaddr)
58{
59 u32 value = readl(ioaddr + DMA_CONTROL);
60 value &= ~DMA_CONTROL_ST;
61 writel(value, ioaddr + DMA_CONTROL);
62}
63
64void dwmac_dma_start_rx(void __iomem *ioaddr)
65{
66 u32 value = readl(ioaddr + DMA_CONTROL);
67 value |= DMA_CONTROL_SR;
68 writel(value, ioaddr + DMA_CONTROL);
69}
70
71void dwmac_dma_stop_rx(void __iomem *ioaddr)
72{
73 u32 value = readl(ioaddr + DMA_CONTROL);
74 value &= ~DMA_CONTROL_SR;
75 writel(value, ioaddr + DMA_CONTROL);
76}
77
78#ifdef DWMAC_DMA_DEBUG
79static void show_tx_process_state(unsigned int status)
80{
81 unsigned int state;
82 state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
83
84 switch (state) {
85 case 0:
86 pr_info("- TX (Stopped): Reset or Stop command\n");
87 break;
88 case 1:
89 pr_info("- TX (Running):Fetching the Tx desc\n");
90 break;
91 case 2:
92 pr_info("- TX (Running): Waiting for end of tx\n");
93 break;
94 case 3:
95 pr_info("- TX (Running): Reading the data "
96 "and queuing the data into the Tx buf\n");
97 break;
98 case 6:
99 pr_info("- TX (Suspended): Tx Buff Underflow "
100 "or an unavailable Transmit descriptor\n");
101 break;
102 case 7:
103 pr_info("- TX (Running): Closing Tx descriptor\n");
104 break;
105 default:
106 break;
107 }
108}
109
110static void show_rx_process_state(unsigned int status)
111{
112 unsigned int state;
113 state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
114
115 switch (state) {
116 case 0:
117 pr_info("- RX (Stopped): Reset or Stop command\n");
118 break;
119 case 1:
120 pr_info("- RX (Running): Fetching the Rx desc\n");
121 break;
122 case 2:
123 pr_info("- RX (Running):Checking for end of pkt\n");
124 break;
125 case 3:
126 pr_info("- RX (Running): Waiting for Rx pkt\n");
127 break;
128 case 4:
129 pr_info("- RX (Suspended): Unavailable Rx buf\n");
130 break;
131 case 5:
132 pr_info("- RX (Running): Closing Rx descriptor\n");
133 break;
134 case 6:
135 pr_info("- RX(Running): Flushing the current frame"
136 " from the Rx buf\n");
137 break;
138 case 7:
139 pr_info("- RX (Running): Queuing the Rx frame"
140 " from the Rx buf into memory\n");
141 break;
142 default:
143 break;
144 }
145}
146#endif
147
148int dwmac_dma_interrupt(void __iomem *ioaddr,
149 struct stmmac_extra_stats *x)
150{
151 int ret = 0;
152 /* read the status register (CSR5) */
153 u32 intr_status = readl(ioaddr + DMA_STATUS);
154
155 DWMAC_LIB_DBG(KERN_INFO "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
156#ifdef DWMAC_DMA_DEBUG
157 /* It displays the DMA process states (CSR5 register) */
158 show_tx_process_state(intr_status);
159 show_rx_process_state(intr_status);
160#endif
161 /* ABNORMAL interrupts */
162 if (unlikely(intr_status & DMA_STATUS_AIS)) {
163 DWMAC_LIB_DBG(KERN_INFO "CSR5[15] DMA ABNORMAL IRQ: ");
164 if (unlikely(intr_status & DMA_STATUS_UNF)) {
165 DWMAC_LIB_DBG(KERN_INFO "transmit underflow\n");
166 ret = tx_hard_error_bump_tc;
167 x->tx_undeflow_irq++;
168 }
169 if (unlikely(intr_status & DMA_STATUS_TJT)) {
170 DWMAC_LIB_DBG(KERN_INFO "transmit jabber\n");
171 x->tx_jabber_irq++;
172 }
173 if (unlikely(intr_status & DMA_STATUS_OVF)) {
174 DWMAC_LIB_DBG(KERN_INFO "recv overflow\n");
175 x->rx_overflow_irq++;
176 }
177 if (unlikely(intr_status & DMA_STATUS_RU)) {
178 DWMAC_LIB_DBG(KERN_INFO "receive buffer unavailable\n");
179 x->rx_buf_unav_irq++;
180 }
181 if (unlikely(intr_status & DMA_STATUS_RPS)) {
182 DWMAC_LIB_DBG(KERN_INFO "receive process stopped\n");
183 x->rx_process_stopped_irq++;
184 }
185 if (unlikely(intr_status & DMA_STATUS_RWT)) {
186 DWMAC_LIB_DBG(KERN_INFO "receive watchdog\n");
187 x->rx_watchdog_irq++;
188 }
189 if (unlikely(intr_status & DMA_STATUS_ETI)) {
190 DWMAC_LIB_DBG(KERN_INFO "transmit early interrupt\n");
191 x->tx_early_irq++;
192 }
193 if (unlikely(intr_status & DMA_STATUS_TPS)) {
194 DWMAC_LIB_DBG(KERN_INFO "transmit process stopped\n");
195 x->tx_process_stopped_irq++;
196 ret = tx_hard_error;
197 }
198 if (unlikely(intr_status & DMA_STATUS_FBI)) {
199 DWMAC_LIB_DBG(KERN_INFO "fatal bus error\n");
200 x->fatal_bus_error_irq++;
201 ret = tx_hard_error;
202 }
203 }
204 /* TX/RX NORMAL interrupts */
205 if (intr_status & DMA_STATUS_NIS) {
206 x->normal_irq_n++;
207 if (likely((intr_status & DMA_STATUS_RI) ||
208 (intr_status & (DMA_STATUS_TI))))
209 ret = handle_tx_rx;
210 }
211 /* Optional hardware blocks, interrupts should be disabled */
212 if (unlikely(intr_status &
213 (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
214 pr_info("%s: unexpected status %08x\n", __func__, intr_status);
215 /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
216 writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
217
218 DWMAC_LIB_DBG(KERN_INFO "\n\n");
219 return ret;
220}
221
222void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr)
223{
224 u32 csr6 = readl(ioaddr + DMA_CONTROL);
225 writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
226
227 do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
228}
229
230void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
231 unsigned int high, unsigned int low)
232{
233 unsigned long data;
234
235 data = (addr[5] << 8) | addr[4];
236 writel(data, ioaddr + high);
237 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
238 writel(data, ioaddr + low);
239}
240
241void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
242 unsigned int high, unsigned int low)
243{
244 unsigned int hi_addr, lo_addr;
245
246 /* Read the MAC address from the hardware */
247 hi_addr = readl(ioaddr + high);
248 lo_addr = readl(ioaddr + low);
249
250 /* Extract the MAC address from the high and low words */
251 addr[0] = lo_addr & 0xff;
252 addr[1] = (lo_addr >> 8) & 0xff;
253 addr[2] = (lo_addr >> 16) & 0xff;
254 addr[3] = (lo_addr >> 24) & 0xff;
255 addr[4] = hi_addr & 0xff;
256 addr[5] = (hi_addr >> 8) & 0xff;
257}
258
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
new file mode 100644
index 000000000000..e5dfb6a30182
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -0,0 +1,337 @@
1/*******************************************************************************
2 This contains the functions to handle the enhanced descriptors.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include "common.h"
26
27static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x,
28 struct dma_desc *p, void __iomem *ioaddr)
29{
30 int ret = 0;
31 struct net_device_stats *stats = (struct net_device_stats *)data;
32
33 if (unlikely(p->des01.etx.error_summary)) {
34 CHIP_DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
35 if (unlikely(p->des01.etx.jabber_timeout)) {
36 CHIP_DBG(KERN_ERR "\tjabber_timeout error\n");
37 x->tx_jabber++;
38 }
39
40 if (unlikely(p->des01.etx.frame_flushed)) {
41 CHIP_DBG(KERN_ERR "\tframe_flushed error\n");
42 x->tx_frame_flushed++;
43 dwmac_dma_flush_tx_fifo(ioaddr);
44 }
45
46 if (unlikely(p->des01.etx.loss_carrier)) {
47 CHIP_DBG(KERN_ERR "\tloss_carrier error\n");
48 x->tx_losscarrier++;
49 stats->tx_carrier_errors++;
50 }
51 if (unlikely(p->des01.etx.no_carrier)) {
52 CHIP_DBG(KERN_ERR "\tno_carrier error\n");
53 x->tx_carrier++;
54 stats->tx_carrier_errors++;
55 }
56 if (unlikely(p->des01.etx.late_collision)) {
57 CHIP_DBG(KERN_ERR "\tlate_collision error\n");
58 stats->collisions += p->des01.etx.collision_count;
59 }
60 if (unlikely(p->des01.etx.excessive_collisions)) {
61 CHIP_DBG(KERN_ERR "\texcessive_collisions\n");
62 stats->collisions += p->des01.etx.collision_count;
63 }
64 if (unlikely(p->des01.etx.excessive_deferral)) {
65 CHIP_DBG(KERN_INFO "\texcessive tx_deferral\n");
66 x->tx_deferred++;
67 }
68
69 if (unlikely(p->des01.etx.underflow_error)) {
70 CHIP_DBG(KERN_ERR "\tunderflow error\n");
71 dwmac_dma_flush_tx_fifo(ioaddr);
72 x->tx_underflow++;
73 }
74
75 if (unlikely(p->des01.etx.ip_header_error)) {
76 CHIP_DBG(KERN_ERR "\tTX IP header csum error\n");
77 x->tx_ip_header_error++;
78 }
79
80 if (unlikely(p->des01.etx.payload_error)) {
81 CHIP_DBG(KERN_ERR "\tAddr/Payload csum error\n");
82 x->tx_payload_error++;
83 dwmac_dma_flush_tx_fifo(ioaddr);
84 }
85
86 ret = -1;
87 }
88
89 if (unlikely(p->des01.etx.deferred)) {
90 CHIP_DBG(KERN_INFO "GMAC TX status: tx deferred\n");
91 x->tx_deferred++;
92 }
93#ifdef STMMAC_VLAN_TAG_USED
94 if (p->des01.etx.vlan_frame) {
95 CHIP_DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
96 x->tx_vlan++;
97 }
98#endif
99
100 return ret;
101}
102
103static int enh_desc_get_tx_len(struct dma_desc *p)
104{
105 return p->des01.etx.buffer1_size;
106}
107
108static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err)
109{
110 int ret = good_frame;
111 u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
112
113 /* bits 5 7 0 | Frame status
114 * ----------------------------------------------------------
115 * 0 0 0 | IEEE 802.3 Type frame (length < 1536 octects)
116 * 1 0 0 | IPv4/6 No CSUM errorS.
117 * 1 0 1 | IPv4/6 CSUM PAYLOAD error
118 * 1 1 0 | IPv4/6 CSUM IP HR error
119 * 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
120 * 0 0 1 | IPv4/6 unsupported IP PAYLOAD
121 * 0 1 1 | COE bypassed.. no IPv4/6 frame
122 * 0 1 0 | Reserved.
123 */
124 if (status == 0x0) {
125 CHIP_DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
126 ret = llc_snap;
127 } else if (status == 0x4) {
128 CHIP_DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
129 ret = good_frame;
130 } else if (status == 0x5) {
131 CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
132 ret = csum_none;
133 } else if (status == 0x6) {
134 CHIP_DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
135 ret = csum_none;
136 } else if (status == 0x7) {
137 CHIP_DBG(KERN_ERR
138 "RX Des0 status: IPv4/6 Header and Payload Error.\n");
139 ret = csum_none;
140 } else if (status == 0x1) {
141 CHIP_DBG(KERN_ERR
142 "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
143 ret = discard_frame;
144 } else if (status == 0x3) {
145 CHIP_DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
146 ret = discard_frame;
147 }
148 return ret;
149}
150
151static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x,
152 struct dma_desc *p)
153{
154 int ret = good_frame;
155 struct net_device_stats *stats = (struct net_device_stats *)data;
156
157 if (unlikely(p->des01.erx.error_summary)) {
158 CHIP_DBG(KERN_ERR "GMAC RX Error Summary 0x%08x\n",
159 p->des01.erx);
160 if (unlikely(p->des01.erx.descriptor_error)) {
161 CHIP_DBG(KERN_ERR "\tdescriptor error\n");
162 x->rx_desc++;
163 stats->rx_length_errors++;
164 }
165 if (unlikely(p->des01.erx.overflow_error)) {
166 CHIP_DBG(KERN_ERR "\toverflow error\n");
167 x->rx_gmac_overflow++;
168 }
169
170 if (unlikely(p->des01.erx.ipc_csum_error))
171 CHIP_DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
172
173 if (unlikely(p->des01.erx.late_collision)) {
174 CHIP_DBG(KERN_ERR "\tlate_collision error\n");
175 stats->collisions++;
176 stats->collisions++;
177 }
178 if (unlikely(p->des01.erx.receive_watchdog)) {
179 CHIP_DBG(KERN_ERR "\treceive_watchdog error\n");
180 x->rx_watchdog++;
181 }
182 if (unlikely(p->des01.erx.error_gmii)) {
183 CHIP_DBG(KERN_ERR "\tReceive Error\n");
184 x->rx_mii++;
185 }
186 if (unlikely(p->des01.erx.crc_error)) {
187 CHIP_DBG(KERN_ERR "\tCRC error\n");
188 x->rx_crc++;
189 stats->rx_crc_errors++;
190 }
191 ret = discard_frame;
192 }
193
194 /* After a payload csum error, the ES bit is set.
195 * It doesn't match with the information reported into the databook.
196 * At any rate, we need to understand if the CSUM hw computation is ok
197 * and report this info to the upper layers. */
198 ret = enh_desc_coe_rdes0(p->des01.erx.ipc_csum_error,
199 p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
200
201 if (unlikely(p->des01.erx.dribbling)) {
202 CHIP_DBG(KERN_ERR "GMAC RX: dribbling error\n");
203 ret = discard_frame;
204 }
205 if (unlikely(p->des01.erx.sa_filter_fail)) {
206 CHIP_DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
207 x->sa_rx_filter_fail++;
208 ret = discard_frame;
209 }
210 if (unlikely(p->des01.erx.da_filter_fail)) {
211 CHIP_DBG(KERN_ERR "GMAC RX : Dest Address filter fail\n");
212 x->da_rx_filter_fail++;
213 ret = discard_frame;
214 }
215 if (unlikely(p->des01.erx.length_error)) {
216 CHIP_DBG(KERN_ERR "GMAC RX: length_error error\n");
217 x->rx_length++;
218 ret = discard_frame;
219 }
220#ifdef STMMAC_VLAN_TAG_USED
221 if (p->des01.erx.vlan_tag) {
222 CHIP_DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
223 x->rx_vlan++;
224 }
225#endif
226 return ret;
227}
228
229static void enh_desc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
230 int disable_rx_ic)
231{
232 int i;
233 for (i = 0; i < ring_size; i++) {
234 p->des01.erx.own = 1;
235 p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
236 /* To support jumbo frames */
237 p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
238 if (i == ring_size - 1)
239 p->des01.erx.end_ring = 1;
240 if (disable_rx_ic)
241 p->des01.erx.disable_ic = 1;
242 p++;
243 }
244}
245
246static void enh_desc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
247{
248 int i;
249
250 for (i = 0; i < ring_size; i++) {
251 p->des01.etx.own = 0;
252 if (i == ring_size - 1)
253 p->des01.etx.end_ring = 1;
254 p++;
255 }
256}
257
258static int enh_desc_get_tx_owner(struct dma_desc *p)
259{
260 return p->des01.etx.own;
261}
262
263static int enh_desc_get_rx_owner(struct dma_desc *p)
264{
265 return p->des01.erx.own;
266}
267
268static void enh_desc_set_tx_owner(struct dma_desc *p)
269{
270 p->des01.etx.own = 1;
271}
272
273static void enh_desc_set_rx_owner(struct dma_desc *p)
274{
275 p->des01.erx.own = 1;
276}
277
278static int enh_desc_get_tx_ls(struct dma_desc *p)
279{
280 return p->des01.etx.last_segment;
281}
282
283static void enh_desc_release_tx_desc(struct dma_desc *p)
284{
285 int ter = p->des01.etx.end_ring;
286
287 memset(p, 0, offsetof(struct dma_desc, des2));
288 p->des01.etx.end_ring = ter;
289}
290
291static void enh_desc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
292 int csum_flag)
293{
294 p->des01.etx.first_segment = is_fs;
295 if (unlikely(len > BUF_SIZE_4KiB)) {
296 p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
297 p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
298 } else {
299 p->des01.etx.buffer1_size = len;
300 }
301 if (likely(csum_flag))
302 p->des01.etx.checksum_insertion = cic_full;
303}
304
305static void enh_desc_clear_tx_ic(struct dma_desc *p)
306{
307 p->des01.etx.interrupt = 0;
308}
309
310static void enh_desc_close_tx_desc(struct dma_desc *p)
311{
312 p->des01.etx.last_segment = 1;
313 p->des01.etx.interrupt = 1;
314}
315
316static int enh_desc_get_rx_frame_len(struct dma_desc *p)
317{
318 return p->des01.erx.frame_length;
319}
320
321const struct stmmac_desc_ops enh_desc_ops = {
322 .tx_status = enh_desc_get_tx_status,
323 .rx_status = enh_desc_get_rx_status,
324 .get_tx_len = enh_desc_get_tx_len,
325 .init_rx_desc = enh_desc_init_rx_desc,
326 .init_tx_desc = enh_desc_init_tx_desc,
327 .get_tx_owner = enh_desc_get_tx_owner,
328 .get_rx_owner = enh_desc_get_rx_owner,
329 .release_tx_desc = enh_desc_release_tx_desc,
330 .prepare_tx_desc = enh_desc_prepare_tx_desc,
331 .clear_tx_ic = enh_desc_clear_tx_ic,
332 .close_tx_desc = enh_desc_close_tx_desc,
333 .get_tx_ls = enh_desc_get_tx_ls,
334 .set_tx_owner = enh_desc_set_tx_owner,
335 .set_rx_owner = enh_desc_set_rx_owner,
336 .get_rx_frame_len = enh_desc_get_rx_frame_len,
337};
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
new file mode 100644
index 000000000000..029c2a2cf524
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -0,0 +1,221 @@
1/*******************************************************************************
2 This contains the functions to handle the normal descriptors.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include "common.h"
26
27static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
28 struct dma_desc *p, void __iomem *ioaddr)
29{
30 int ret = 0;
31 struct net_device_stats *stats = (struct net_device_stats *)data;
32
33 if (unlikely(p->des01.tx.error_summary)) {
34 if (unlikely(p->des01.tx.underflow_error)) {
35 x->tx_underflow++;
36 stats->tx_fifo_errors++;
37 }
38 if (unlikely(p->des01.tx.no_carrier)) {
39 x->tx_carrier++;
40 stats->tx_carrier_errors++;
41 }
42 if (unlikely(p->des01.tx.loss_carrier)) {
43 x->tx_losscarrier++;
44 stats->tx_carrier_errors++;
45 }
46 if (unlikely((p->des01.tx.excessive_deferral) ||
47 (p->des01.tx.excessive_collisions) ||
48 (p->des01.tx.late_collision)))
49 stats->collisions += p->des01.tx.collision_count;
50 ret = -1;
51 }
52 if (unlikely(p->des01.tx.heartbeat_fail)) {
53 x->tx_heartbeat++;
54 stats->tx_heartbeat_errors++;
55 ret = -1;
56 }
57 if (unlikely(p->des01.tx.deferred))
58 x->tx_deferred++;
59
60 return ret;
61}
62
63static int ndesc_get_tx_len(struct dma_desc *p)
64{
65 return p->des01.tx.buffer1_size;
66}
67
68/* This function verifies if each incoming frame has some errors
69 * and, if required, updates the multicast statistics.
70 * In case of success, it returns csum_none because the device
71 * is not able to compute the csum in HW. */
72static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
73 struct dma_desc *p)
74{
75 int ret = csum_none;
76 struct net_device_stats *stats = (struct net_device_stats *)data;
77
78 if (unlikely(p->des01.rx.last_descriptor == 0)) {
79 pr_warning("ndesc Error: Oversized Ethernet "
80 "frame spanned multiple buffers\n");
81 stats->rx_length_errors++;
82 return discard_frame;
83 }
84
85 if (unlikely(p->des01.rx.error_summary)) {
86 if (unlikely(p->des01.rx.descriptor_error))
87 x->rx_desc++;
88 if (unlikely(p->des01.rx.partial_frame_error))
89 x->rx_partial++;
90 if (unlikely(p->des01.rx.run_frame))
91 x->rx_runt++;
92 if (unlikely(p->des01.rx.frame_too_long))
93 x->rx_toolong++;
94 if (unlikely(p->des01.rx.collision)) {
95 x->rx_collision++;
96 stats->collisions++;
97 }
98 if (unlikely(p->des01.rx.crc_error)) {
99 x->rx_crc++;
100 stats->rx_crc_errors++;
101 }
102 ret = discard_frame;
103 }
104 if (unlikely(p->des01.rx.dribbling))
105 ret = discard_frame;
106
107 if (unlikely(p->des01.rx.length_error)) {
108 x->rx_length++;
109 ret = discard_frame;
110 }
111 if (unlikely(p->des01.rx.mii_error)) {
112 x->rx_mii++;
113 ret = discard_frame;
114 }
115 if (p->des01.rx.multicast_frame) {
116 x->rx_multicast++;
117 stats->multicast++;
118 }
119 return ret;
120}
121
122static void ndesc_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
123 int disable_rx_ic)
124{
125 int i;
126 for (i = 0; i < ring_size; i++) {
127 p->des01.rx.own = 1;
128 p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
129 if (i == ring_size - 1)
130 p->des01.rx.end_ring = 1;
131 if (disable_rx_ic)
132 p->des01.rx.disable_ic = 1;
133 p++;
134 }
135}
136
137static void ndesc_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
138{
139 int i;
140 for (i = 0; i < ring_size; i++) {
141 p->des01.tx.own = 0;
142 if (i == ring_size - 1)
143 p->des01.tx.end_ring = 1;
144 p++;
145 }
146}
147
148static int ndesc_get_tx_owner(struct dma_desc *p)
149{
150 return p->des01.tx.own;
151}
152
153static int ndesc_get_rx_owner(struct dma_desc *p)
154{
155 return p->des01.rx.own;
156}
157
158static void ndesc_set_tx_owner(struct dma_desc *p)
159{
160 p->des01.tx.own = 1;
161}
162
163static void ndesc_set_rx_owner(struct dma_desc *p)
164{
165 p->des01.rx.own = 1;
166}
167
168static int ndesc_get_tx_ls(struct dma_desc *p)
169{
170 return p->des01.tx.last_segment;
171}
172
173static void ndesc_release_tx_desc(struct dma_desc *p)
174{
175 int ter = p->des01.tx.end_ring;
176
177 memset(p, 0, offsetof(struct dma_desc, des2));
178 /* set termination field */
179 p->des01.tx.end_ring = ter;
180}
181
182static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
183 int csum_flag)
184{
185 p->des01.tx.first_segment = is_fs;
186 p->des01.tx.buffer1_size = len;
187}
188
189static void ndesc_clear_tx_ic(struct dma_desc *p)
190{
191 p->des01.tx.interrupt = 0;
192}
193
194static void ndesc_close_tx_desc(struct dma_desc *p)
195{
196 p->des01.tx.last_segment = 1;
197 p->des01.tx.interrupt = 1;
198}
199
200static int ndesc_get_rx_frame_len(struct dma_desc *p)
201{
202 return p->des01.rx.frame_length;
203}
204
205const struct stmmac_desc_ops ndesc_ops = {
206 .tx_status = ndesc_get_tx_status,
207 .rx_status = ndesc_get_rx_status,
208 .get_tx_len = ndesc_get_tx_len,
209 .init_rx_desc = ndesc_init_rx_desc,
210 .init_tx_desc = ndesc_init_tx_desc,
211 .get_tx_owner = ndesc_get_tx_owner,
212 .get_rx_owner = ndesc_get_rx_owner,
213 .release_tx_desc = ndesc_release_tx_desc,
214 .prepare_tx_desc = ndesc_prepare_tx_desc,
215 .clear_tx_ic = ndesc_clear_tx_ic,
216 .close_tx_desc = ndesc_close_tx_desc,
217 .get_tx_ls = ndesc_get_tx_ls,
218 .set_tx_owner = ndesc_set_tx_owner,
219 .set_rx_owner = ndesc_set_rx_owner,
220 .get_rx_frame_len = ndesc_get_rx_frame_len,
221};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
new file mode 100644
index 000000000000..de1929b2641b
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -0,0 +1,85 @@
1/*******************************************************************************
2 Copyright (C) 2007-2009 STMicroelectronics Ltd
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms and conditions of the GNU General Public License,
6 version 2, as published by the Free Software Foundation.
7
8 This program is distributed in the hope it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16
17 The full GNU General Public License is included in this distribution in
18 the file called "COPYING".
19
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/
22
23#define DRV_MODULE_VERSION "July_2011"
24#include <linux/stmmac.h>
25
26#include "common.h"
27#ifdef CONFIG_STMMAC_TIMER
28#include "stmmac_timer.h"
29#endif
30
31struct stmmac_priv {
32 /* Frequently used values are kept adjacent for cache effect */
33 struct dma_desc *dma_tx ____cacheline_aligned;
34 dma_addr_t dma_tx_phy;
35 struct sk_buff **tx_skbuff;
36 unsigned int cur_tx;
37 unsigned int dirty_tx;
38 unsigned int dma_tx_size;
39 int tx_coalesce;
40
41 struct dma_desc *dma_rx ;
42 unsigned int cur_rx;
43 unsigned int dirty_rx;
44 struct sk_buff **rx_skbuff;
45 dma_addr_t *rx_skbuff_dma;
46 struct sk_buff_head rx_recycle;
47
48 struct net_device *dev;
49 dma_addr_t dma_rx_phy;
50 unsigned int dma_rx_size;
51 unsigned int dma_buf_sz;
52 struct device *device;
53 struct mac_device_info *hw;
54 void __iomem *ioaddr;
55
56 struct stmmac_extra_stats xstats;
57 struct napi_struct napi;
58
59 int rx_coe;
60 int no_csum_insertion;
61
62 struct phy_device *phydev;
63 int oldlink;
64 int speed;
65 int oldduplex;
66 unsigned int flow_ctrl;
67 unsigned int pause;
68 struct mii_bus *mii;
69 int mii_irq[PHY_MAX_ADDR];
70
71 u32 msg_enable;
72 spinlock_t lock;
73 int wolopts;
74 int wolenabled;
75#ifdef CONFIG_STMMAC_TIMER
76 struct stmmac_timer *tm;
77#endif
78 struct plat_stmmacenet_data *plat;
79};
80
81extern int stmmac_mdio_unregister(struct net_device *ndev);
82extern int stmmac_mdio_register(struct net_device *ndev);
83extern void stmmac_set_ethtool_ops(struct net_device *netdev);
84extern const struct stmmac_desc_ops enh_desc_ops;
85extern const struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
new file mode 100644
index 000000000000..7ed8fb6c2117
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -0,0 +1,359 @@
1/*******************************************************************************
2 STMMAC Ethtool support
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/etherdevice.h>
26#include <linux/ethtool.h>
27#include <linux/interrupt.h>
28#include <linux/mii.h>
29#include <linux/phy.h>
30#include <asm/io.h>
31
32#include "stmmac.h"
33#include "dwmac_dma.h"
34
35#define REG_SPACE_SIZE 0x1054
36#define MAC100_ETHTOOL_NAME "st_mac100"
37#define GMAC_ETHTOOL_NAME "st_gmac"
38
39struct stmmac_stats {
40 char stat_string[ETH_GSTRING_LEN];
41 int sizeof_stat;
42 int stat_offset;
43};
44
45#define STMMAC_STAT(m) \
46 { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m), \
47 offsetof(struct stmmac_priv, xstats.m)}
48
49static const struct stmmac_stats stmmac_gstrings_stats[] = {
50 STMMAC_STAT(tx_underflow),
51 STMMAC_STAT(tx_carrier),
52 STMMAC_STAT(tx_losscarrier),
53 STMMAC_STAT(tx_heartbeat),
54 STMMAC_STAT(tx_deferred),
55 STMMAC_STAT(tx_vlan),
56 STMMAC_STAT(rx_vlan),
57 STMMAC_STAT(tx_jabber),
58 STMMAC_STAT(tx_frame_flushed),
59 STMMAC_STAT(tx_payload_error),
60 STMMAC_STAT(tx_ip_header_error),
61 STMMAC_STAT(rx_desc),
62 STMMAC_STAT(rx_partial),
63 STMMAC_STAT(rx_runt),
64 STMMAC_STAT(rx_toolong),
65 STMMAC_STAT(rx_collision),
66 STMMAC_STAT(rx_crc),
67 STMMAC_STAT(rx_length),
68 STMMAC_STAT(rx_mii),
69 STMMAC_STAT(rx_multicast),
70 STMMAC_STAT(rx_gmac_overflow),
71 STMMAC_STAT(rx_watchdog),
72 STMMAC_STAT(da_rx_filter_fail),
73 STMMAC_STAT(sa_rx_filter_fail),
74 STMMAC_STAT(rx_missed_cntr),
75 STMMAC_STAT(rx_overflow_cntr),
76 STMMAC_STAT(tx_undeflow_irq),
77 STMMAC_STAT(tx_process_stopped_irq),
78 STMMAC_STAT(tx_jabber_irq),
79 STMMAC_STAT(rx_overflow_irq),
80 STMMAC_STAT(rx_buf_unav_irq),
81 STMMAC_STAT(rx_process_stopped_irq),
82 STMMAC_STAT(rx_watchdog_irq),
83 STMMAC_STAT(tx_early_irq),
84 STMMAC_STAT(fatal_bus_error_irq),
85 STMMAC_STAT(threshold),
86 STMMAC_STAT(tx_pkt_n),
87 STMMAC_STAT(rx_pkt_n),
88 STMMAC_STAT(poll_n),
89 STMMAC_STAT(sched_timer_n),
90 STMMAC_STAT(normal_irq_n),
91};
92#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
93
94static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
95 struct ethtool_drvinfo *info)
96{
97 struct stmmac_priv *priv = netdev_priv(dev);
98
99 if (!priv->plat->has_gmac)
100 strcpy(info->driver, MAC100_ETHTOOL_NAME);
101 else
102 strcpy(info->driver, GMAC_ETHTOOL_NAME);
103
104 strcpy(info->version, DRV_MODULE_VERSION);
105 info->fw_version[0] = '\0';
106 info->n_stats = STMMAC_STATS_LEN;
107}
108
109static int stmmac_ethtool_getsettings(struct net_device *dev,
110 struct ethtool_cmd *cmd)
111{
112 struct stmmac_priv *priv = netdev_priv(dev);
113 struct phy_device *phy = priv->phydev;
114 int rc;
115 if (phy == NULL) {
116 pr_err("%s: %s: PHY is not registered\n",
117 __func__, dev->name);
118 return -ENODEV;
119 }
120 if (!netif_running(dev)) {
121 pr_err("%s: interface is disabled: we cannot track "
122 "link speed / duplex setting\n", dev->name);
123 return -EBUSY;
124 }
125 cmd->transceiver = XCVR_INTERNAL;
126 spin_lock_irq(&priv->lock);
127 rc = phy_ethtool_gset(phy, cmd);
128 spin_unlock_irq(&priv->lock);
129 return rc;
130}
131
132static int stmmac_ethtool_setsettings(struct net_device *dev,
133 struct ethtool_cmd *cmd)
134{
135 struct stmmac_priv *priv = netdev_priv(dev);
136 struct phy_device *phy = priv->phydev;
137 int rc;
138
139 spin_lock(&priv->lock);
140 rc = phy_ethtool_sset(phy, cmd);
141 spin_unlock(&priv->lock);
142
143 return rc;
144}
145
146static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
147{
148 struct stmmac_priv *priv = netdev_priv(dev);
149 return priv->msg_enable;
150}
151
152static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
153{
154 struct stmmac_priv *priv = netdev_priv(dev);
155 priv->msg_enable = level;
156
157}
158
159static int stmmac_check_if_running(struct net_device *dev)
160{
161 if (!netif_running(dev))
162 return -EBUSY;
163 return 0;
164}
165
166static int stmmac_ethtool_get_regs_len(struct net_device *dev)
167{
168 return REG_SPACE_SIZE;
169}
170
171static void stmmac_ethtool_gregs(struct net_device *dev,
172 struct ethtool_regs *regs, void *space)
173{
174 int i;
175 u32 *reg_space = (u32 *) space;
176
177 struct stmmac_priv *priv = netdev_priv(dev);
178
179 memset(reg_space, 0x0, REG_SPACE_SIZE);
180
181 if (!priv->plat->has_gmac) {
182 /* MAC registers */
183 for (i = 0; i < 12; i++)
184 reg_space[i] = readl(priv->ioaddr + (i * 4));
185 /* DMA registers */
186 for (i = 0; i < 9; i++)
187 reg_space[i + 12] =
188 readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
189 reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR);
190 reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR);
191 } else {
192 /* MAC registers */
193 for (i = 0; i < 55; i++)
194 reg_space[i] = readl(priv->ioaddr + (i * 4));
195 /* DMA registers */
196 for (i = 0; i < 22; i++)
197 reg_space[i + 55] =
198 readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
199 }
200}
201
202static void
203stmmac_get_pauseparam(struct net_device *netdev,
204 struct ethtool_pauseparam *pause)
205{
206 struct stmmac_priv *priv = netdev_priv(netdev);
207
208 spin_lock(&priv->lock);
209
210 pause->rx_pause = 0;
211 pause->tx_pause = 0;
212 pause->autoneg = priv->phydev->autoneg;
213
214 if (priv->flow_ctrl & FLOW_RX)
215 pause->rx_pause = 1;
216 if (priv->flow_ctrl & FLOW_TX)
217 pause->tx_pause = 1;
218
219 spin_unlock(&priv->lock);
220}
221
222static int
223stmmac_set_pauseparam(struct net_device *netdev,
224 struct ethtool_pauseparam *pause)
225{
226 struct stmmac_priv *priv = netdev_priv(netdev);
227 struct phy_device *phy = priv->phydev;
228 int new_pause = FLOW_OFF;
229 int ret = 0;
230
231 spin_lock(&priv->lock);
232
233 if (pause->rx_pause)
234 new_pause |= FLOW_RX;
235 if (pause->tx_pause)
236 new_pause |= FLOW_TX;
237
238 priv->flow_ctrl = new_pause;
239 phy->autoneg = pause->autoneg;
240
241 if (phy->autoneg) {
242 if (netif_running(netdev))
243 ret = phy_start_aneg(phy);
244 } else
245 priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
246 priv->flow_ctrl, priv->pause);
247 spin_unlock(&priv->lock);
248 return ret;
249}
250
251static void stmmac_get_ethtool_stats(struct net_device *dev,
252 struct ethtool_stats *dummy, u64 *data)
253{
254 struct stmmac_priv *priv = netdev_priv(dev);
255 int i;
256
257 /* Update HW stats if supported */
258 priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
259 priv->ioaddr);
260
261 for (i = 0; i < STMMAC_STATS_LEN; i++) {
262 char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
263 data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
264 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
265 }
266}
267
268static int stmmac_get_sset_count(struct net_device *netdev, int sset)
269{
270 switch (sset) {
271 case ETH_SS_STATS:
272 return STMMAC_STATS_LEN;
273 default:
274 return -EOPNOTSUPP;
275 }
276}
277
278static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
279{
280 int i;
281 u8 *p = data;
282
283 switch (stringset) {
284 case ETH_SS_STATS:
285 for (i = 0; i < STMMAC_STATS_LEN; i++) {
286 memcpy(p, stmmac_gstrings_stats[i].stat_string,
287 ETH_GSTRING_LEN);
288 p += ETH_GSTRING_LEN;
289 }
290 break;
291 default:
292 WARN_ON(1);
293 break;
294 }
295}
296
297/* Currently only support WOL through Magic packet. */
298static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
299{
300 struct stmmac_priv *priv = netdev_priv(dev);
301
302 spin_lock_irq(&priv->lock);
303 if (device_can_wakeup(priv->device)) {
304 wol->supported = WAKE_MAGIC | WAKE_UCAST;
305 wol->wolopts = priv->wolopts;
306 }
307 spin_unlock_irq(&priv->lock);
308}
309
310static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
311{
312 struct stmmac_priv *priv = netdev_priv(dev);
313 u32 support = WAKE_MAGIC | WAKE_UCAST;
314
315 if (!device_can_wakeup(priv->device))
316 return -EINVAL;
317
318 if (wol->wolopts & ~support)
319 return -EINVAL;
320
321 if (wol->wolopts) {
322 pr_info("stmmac: wakeup enable\n");
323 device_set_wakeup_enable(priv->device, 1);
324 enable_irq_wake(dev->irq);
325 } else {
326 device_set_wakeup_enable(priv->device, 0);
327 disable_irq_wake(dev->irq);
328 }
329
330 spin_lock_irq(&priv->lock);
331 priv->wolopts = wol->wolopts;
332 spin_unlock_irq(&priv->lock);
333
334 return 0;
335}
336
337static struct ethtool_ops stmmac_ethtool_ops = {
338 .begin = stmmac_check_if_running,
339 .get_drvinfo = stmmac_ethtool_getdrvinfo,
340 .get_settings = stmmac_ethtool_getsettings,
341 .set_settings = stmmac_ethtool_setsettings,
342 .get_msglevel = stmmac_ethtool_getmsglevel,
343 .set_msglevel = stmmac_ethtool_setmsglevel,
344 .get_regs = stmmac_ethtool_gregs,
345 .get_regs_len = stmmac_ethtool_get_regs_len,
346 .get_link = ethtool_op_get_link,
347 .get_pauseparam = stmmac_get_pauseparam,
348 .set_pauseparam = stmmac_set_pauseparam,
349 .get_ethtool_stats = stmmac_get_ethtool_stats,
350 .get_strings = stmmac_get_strings,
351 .get_wol = stmmac_get_wol,
352 .set_wol = stmmac_set_wol,
353 .get_sset_count = stmmac_get_sset_count,
354};
355
356void stmmac_set_ethtool_ops(struct net_device *netdev)
357{
358 SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
359}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
new file mode 100644
index 000000000000..c6e567e04eff
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -0,0 +1,1895 @@
1/*******************************************************************************
2 This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
3 ST Ethernet IPs are built around a Synopsys IP Core.
4
5 Copyright (C) 2007-2009 STMicroelectronics Ltd
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms and conditions of the GNU General Public License,
9 version 2, as published by the Free Software Foundation.
10
11 This program is distributed in the hope it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19
20 The full GNU General Public License is included in this distribution in
21 the file called "COPYING".
22
23 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
24
25 Documentation available at:
26 http://www.stlinux.com
27 Support available at:
28 https://bugzilla.stlinux.com/
29*******************************************************************************/
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/kernel.h>
34#include <linux/interrupt.h>
35#include <linux/etherdevice.h>
36#include <linux/platform_device.h>
37#include <linux/ip.h>
38#include <linux/tcp.h>
39#include <linux/skbuff.h>
40#include <linux/ethtool.h>
41#include <linux/if_ether.h>
42#include <linux/crc32.h>
43#include <linux/mii.h>
44#include <linux/phy.h>
45#include <linux/if_vlan.h>
46#include <linux/dma-mapping.h>
47#include <linux/slab.h>
48#include <linux/prefetch.h>
49#include "stmmac.h"
50
51#define STMMAC_RESOURCE_NAME "stmmaceth"
52
53#undef STMMAC_DEBUG
54/*#define STMMAC_DEBUG*/
55#ifdef STMMAC_DEBUG
56#define DBG(nlevel, klevel, fmt, args...) \
57 ((void)(netif_msg_##nlevel(priv) && \
58 printk(KERN_##klevel fmt, ## args)))
59#else
60#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
61#endif
62
63#undef STMMAC_RX_DEBUG
64/*#define STMMAC_RX_DEBUG*/
65#ifdef STMMAC_RX_DEBUG
66#define RX_DBG(fmt, args...) printk(fmt, ## args)
67#else
68#define RX_DBG(fmt, args...) do { } while (0)
69#endif
70
71#undef STMMAC_XMIT_DEBUG
72/*#define STMMAC_XMIT_DEBUG*/
73#ifdef STMMAC_TX_DEBUG
74#define TX_DBG(fmt, args...) printk(fmt, ## args)
75#else
76#define TX_DBG(fmt, args...) do { } while (0)
77#endif
78
79#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
80#define JUMBO_LEN 9000
81
82/* Module parameters */
83#define TX_TIMEO 5000 /* default 5 seconds */
84static int watchdog = TX_TIMEO;
85module_param(watchdog, int, S_IRUGO | S_IWUSR);
86MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
87
88static int debug = -1; /* -1: default, 0: no output, 16: all */
89module_param(debug, int, S_IRUGO | S_IWUSR);
90MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
91
92static int phyaddr = -1;
93module_param(phyaddr, int, S_IRUGO);
94MODULE_PARM_DESC(phyaddr, "Physical device address");
95
96#define DMA_TX_SIZE 256
97static int dma_txsize = DMA_TX_SIZE;
98module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
99MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
100
101#define DMA_RX_SIZE 256
102static int dma_rxsize = DMA_RX_SIZE;
103module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
104MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
105
106static int flow_ctrl = FLOW_OFF;
107module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
108MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
109
110static int pause = PAUSE_TIME;
111module_param(pause, int, S_IRUGO | S_IWUSR);
112MODULE_PARM_DESC(pause, "Flow Control Pause Time");
113
114#define TC_DEFAULT 64
115static int tc = TC_DEFAULT;
116module_param(tc, int, S_IRUGO | S_IWUSR);
117MODULE_PARM_DESC(tc, "DMA threshold control value");
118
119/* Pay attention to tune this parameter; take care of both
120 * hardware capability and network stabitily/performance impact.
121 * Many tests showed that ~4ms latency seems to be good enough. */
122#ifdef CONFIG_STMMAC_TIMER
123#define DEFAULT_PERIODIC_RATE 256
124static int tmrate = DEFAULT_PERIODIC_RATE;
125module_param(tmrate, int, S_IRUGO | S_IWUSR);
126MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
127#endif
128
129#define DMA_BUFFER_SIZE BUF_SIZE_2KiB
130static int buf_sz = DMA_BUFFER_SIZE;
131module_param(buf_sz, int, S_IRUGO | S_IWUSR);
132MODULE_PARM_DESC(buf_sz, "DMA buffer size");
133
134static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
135 NETIF_MSG_LINK | NETIF_MSG_IFUP |
136 NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
137
138static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
139
140/**
141 * stmmac_verify_args - verify the driver parameters.
142 * Description: it verifies if some wrong parameter is passed to the driver.
143 * Note that wrong parameters are replaced with the default values.
144 */
145static void stmmac_verify_args(void)
146{
147 if (unlikely(watchdog < 0))
148 watchdog = TX_TIMEO;
149 if (unlikely(dma_rxsize < 0))
150 dma_rxsize = DMA_RX_SIZE;
151 if (unlikely(dma_txsize < 0))
152 dma_txsize = DMA_TX_SIZE;
153 if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
154 buf_sz = DMA_BUFFER_SIZE;
155 if (unlikely(flow_ctrl > 1))
156 flow_ctrl = FLOW_AUTO;
157 else if (likely(flow_ctrl < 0))
158 flow_ctrl = FLOW_OFF;
159 if (unlikely((pause < 0) || (pause > 0xffff)))
160 pause = PAUSE_TIME;
161}
162
163#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
164static void print_pkt(unsigned char *buf, int len)
165{
166 int j;
167 pr_info("len = %d byte, buf addr: 0x%p", len, buf);
168 for (j = 0; j < len; j++) {
169 if ((j % 16) == 0)
170 pr_info("\n %03x:", j);
171 pr_info(" %02x", buf[j]);
172 }
173 pr_info("\n");
174}
175#endif
176
177/* minimum number of free TX descriptors required to wake up TX process */
178#define STMMAC_TX_THRESH(x) (x->dma_tx_size/4)
179
180static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
181{
182 return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
183}
184
185/* On some ST platforms, some HW system configuraton registers have to be
186 * set according to the link speed negotiated.
187 */
188static inline void stmmac_hw_fix_mac_speed(struct stmmac_priv *priv)
189{
190 struct phy_device *phydev = priv->phydev;
191
192 if (likely(priv->plat->fix_mac_speed))
193 priv->plat->fix_mac_speed(priv->plat->bsp_priv,
194 phydev->speed);
195}
196
197/**
198 * stmmac_adjust_link
199 * @dev: net device structure
200 * Description: it adjusts the link parameters.
201 */
202static void stmmac_adjust_link(struct net_device *dev)
203{
204 struct stmmac_priv *priv = netdev_priv(dev);
205 struct phy_device *phydev = priv->phydev;
206 unsigned long flags;
207 int new_state = 0;
208 unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
209
210 if (phydev == NULL)
211 return;
212
213 DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n",
214 phydev->addr, phydev->link);
215
216 spin_lock_irqsave(&priv->lock, flags);
217 if (phydev->link) {
218 u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
219
220 /* Now we make sure that we can be in full duplex mode.
221 * If not, we operate in half-duplex mode. */
222 if (phydev->duplex != priv->oldduplex) {
223 new_state = 1;
224 if (!(phydev->duplex))
225 ctrl &= ~priv->hw->link.duplex;
226 else
227 ctrl |= priv->hw->link.duplex;
228 priv->oldduplex = phydev->duplex;
229 }
230 /* Flow Control operation */
231 if (phydev->pause)
232 priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex,
233 fc, pause_time);
234
235 if (phydev->speed != priv->speed) {
236 new_state = 1;
237 switch (phydev->speed) {
238 case 1000:
239 if (likely(priv->plat->has_gmac))
240 ctrl &= ~priv->hw->link.port;
241 stmmac_hw_fix_mac_speed(priv);
242 break;
243 case 100:
244 case 10:
245 if (priv->plat->has_gmac) {
246 ctrl |= priv->hw->link.port;
247 if (phydev->speed == SPEED_100) {
248 ctrl |= priv->hw->link.speed;
249 } else {
250 ctrl &= ~(priv->hw->link.speed);
251 }
252 } else {
253 ctrl &= ~priv->hw->link.port;
254 }
255 stmmac_hw_fix_mac_speed(priv);
256 break;
257 default:
258 if (netif_msg_link(priv))
259 pr_warning("%s: Speed (%d) is not 10"
260 " or 100!\n", dev->name, phydev->speed);
261 break;
262 }
263
264 priv->speed = phydev->speed;
265 }
266
267 writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
268
269 if (!priv->oldlink) {
270 new_state = 1;
271 priv->oldlink = 1;
272 }
273 } else if (priv->oldlink) {
274 new_state = 1;
275 priv->oldlink = 0;
276 priv->speed = 0;
277 priv->oldduplex = -1;
278 }
279
280 if (new_state && netif_msg_link(priv))
281 phy_print_status(phydev);
282
283 spin_unlock_irqrestore(&priv->lock, flags);
284
285 DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
286}
287
288/**
289 * stmmac_init_phy - PHY initialization
290 * @dev: net device structure
291 * Description: it initializes the driver's PHY state, and attaches the PHY
292 * to the mac driver.
293 * Return value:
294 * 0 on success
295 */
296static int stmmac_init_phy(struct net_device *dev)
297{
298 struct stmmac_priv *priv = netdev_priv(dev);
299 struct phy_device *phydev;
300 char phy_id[MII_BUS_ID_SIZE + 3];
301 char bus_id[MII_BUS_ID_SIZE];
302
303 priv->oldlink = 0;
304 priv->speed = 0;
305 priv->oldduplex = -1;
306
307 snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id);
308 snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
309 priv->plat->phy_addr);
310 pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
311
312 phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
313 priv->plat->interface);
314
315 if (IS_ERR(phydev)) {
316 pr_err("%s: Could not attach to PHY\n", dev->name);
317 return PTR_ERR(phydev);
318 }
319
320 /*
321 * Broken HW is sometimes missing the pull-up resistor on the
322 * MDIO line, which results in reads to non-existent devices returning
323 * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
324 * device as well.
325 * Note: phydev->phy_id is the result of reading the UID PHY registers.
326 */
327 if (phydev->phy_id == 0) {
328 phy_disconnect(phydev);
329 return -ENODEV;
330 }
331 pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)"
332 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
333
334 priv->phydev = phydev;
335
336 return 0;
337}
338
339static inline void stmmac_enable_mac(void __iomem *ioaddr)
340{
341 u32 value = readl(ioaddr + MAC_CTRL_REG);
342
343 value |= MAC_RNABLE_RX | MAC_ENABLE_TX;
344 writel(value, ioaddr + MAC_CTRL_REG);
345}
346
347static inline void stmmac_disable_mac(void __iomem *ioaddr)
348{
349 u32 value = readl(ioaddr + MAC_CTRL_REG);
350
351 value &= ~(MAC_ENABLE_TX | MAC_RNABLE_RX);
352 writel(value, ioaddr + MAC_CTRL_REG);
353}
354
355/**
356 * display_ring
357 * @p: pointer to the ring.
358 * @size: size of the ring.
359 * Description: display all the descriptors within the ring.
360 */
361static void display_ring(struct dma_desc *p, int size)
362{
363 struct tmp_s {
364 u64 a;
365 unsigned int b;
366 unsigned int c;
367 };
368 int i;
369 for (i = 0; i < size; i++) {
370 struct tmp_s *x = (struct tmp_s *)(p + i);
371 pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
372 i, (unsigned int)virt_to_phys(&p[i]),
373 (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
374 x->b, x->c);
375 pr_info("\n");
376 }
377}
378
379/**
380 * init_dma_desc_rings - init the RX/TX descriptor rings
381 * @dev: net device structure
382 * Description: this function initializes the DMA RX/TX descriptors
383 * and allocates the socket buffers.
384 */
385static void init_dma_desc_rings(struct net_device *dev)
386{
387 int i;
388 struct stmmac_priv *priv = netdev_priv(dev);
389 struct sk_buff *skb;
390 unsigned int txsize = priv->dma_tx_size;
391 unsigned int rxsize = priv->dma_rx_size;
392 unsigned int bfsize = priv->dma_buf_sz;
393 int buff2_needed = 0, dis_ic = 0;
394
395 /* Set the Buffer size according to the MTU;
396 * indeed, in case of jumbo we need to bump-up the buffer sizes.
397 */
398 if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
399 bfsize = BUF_SIZE_16KiB;
400 else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
401 bfsize = BUF_SIZE_8KiB;
402 else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
403 bfsize = BUF_SIZE_4KiB;
404 else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
405 bfsize = BUF_SIZE_2KiB;
406 else
407 bfsize = DMA_BUFFER_SIZE;
408
409#ifdef CONFIG_STMMAC_TIMER
410 /* Disable interrupts on completion for the reception if timer is on */
411 if (likely(priv->tm->enable))
412 dis_ic = 1;
413#endif
414 /* If the MTU exceeds 8k so use the second buffer in the chain */
415 if (bfsize >= BUF_SIZE_8KiB)
416 buff2_needed = 1;
417
418 DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
419 txsize, rxsize, bfsize);
420
421 priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
422 priv->rx_skbuff =
423 kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
424 priv->dma_rx =
425 (struct dma_desc *)dma_alloc_coherent(priv->device,
426 rxsize *
427 sizeof(struct dma_desc),
428 &priv->dma_rx_phy,
429 GFP_KERNEL);
430 priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
431 GFP_KERNEL);
432 priv->dma_tx =
433 (struct dma_desc *)dma_alloc_coherent(priv->device,
434 txsize *
435 sizeof(struct dma_desc),
436 &priv->dma_tx_phy,
437 GFP_KERNEL);
438
439 if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
440 pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
441 return;
442 }
443
444 DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
445 "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
446 dev->name, priv->dma_rx, priv->dma_tx,
447 (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
448
449 /* RX INITIALIZATION */
450 DBG(probe, INFO, "stmmac: SKB addresses:\n"
451 "skb\t\tskb data\tdma data\n");
452
453 for (i = 0; i < rxsize; i++) {
454 struct dma_desc *p = priv->dma_rx + i;
455
456 skb = netdev_alloc_skb_ip_align(dev, bfsize);
457 if (unlikely(skb == NULL)) {
458 pr_err("%s: Rx init fails; skb is NULL\n", __func__);
459 break;
460 }
461 priv->rx_skbuff[i] = skb;
462 priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
463 bfsize, DMA_FROM_DEVICE);
464
465 p->des2 = priv->rx_skbuff_dma[i];
466 if (unlikely(buff2_needed))
467 p->des3 = p->des2 + BUF_SIZE_8KiB;
468 DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
469 priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
470 }
471 priv->cur_rx = 0;
472 priv->dirty_rx = (unsigned int)(i - rxsize);
473 priv->dma_buf_sz = bfsize;
474 buf_sz = bfsize;
475
476 /* TX INITIALIZATION */
477 for (i = 0; i < txsize; i++) {
478 priv->tx_skbuff[i] = NULL;
479 priv->dma_tx[i].des2 = 0;
480 }
481 priv->dirty_tx = 0;
482 priv->cur_tx = 0;
483
484 /* Clear the Rx/Tx descriptors */
485 priv->hw->desc->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
486 priv->hw->desc->init_tx_desc(priv->dma_tx, txsize);
487
488 if (netif_msg_hw(priv)) {
489 pr_info("RX descriptor ring:\n");
490 display_ring(priv->dma_rx, rxsize);
491 pr_info("TX descriptor ring:\n");
492 display_ring(priv->dma_tx, txsize);
493 }
494}
495
496static void dma_free_rx_skbufs(struct stmmac_priv *priv)
497{
498 int i;
499
500 for (i = 0; i < priv->dma_rx_size; i++) {
501 if (priv->rx_skbuff[i]) {
502 dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
503 priv->dma_buf_sz, DMA_FROM_DEVICE);
504 dev_kfree_skb_any(priv->rx_skbuff[i]);
505 }
506 priv->rx_skbuff[i] = NULL;
507 }
508}
509
510static void dma_free_tx_skbufs(struct stmmac_priv *priv)
511{
512 int i;
513
514 for (i = 0; i < priv->dma_tx_size; i++) {
515 if (priv->tx_skbuff[i] != NULL) {
516 struct dma_desc *p = priv->dma_tx + i;
517 if (p->des2)
518 dma_unmap_single(priv->device, p->des2,
519 priv->hw->desc->get_tx_len(p),
520 DMA_TO_DEVICE);
521 dev_kfree_skb_any(priv->tx_skbuff[i]);
522 priv->tx_skbuff[i] = NULL;
523 }
524 }
525}
526
527static void free_dma_desc_resources(struct stmmac_priv *priv)
528{
529 /* Release the DMA TX/RX socket buffers */
530 dma_free_rx_skbufs(priv);
531 dma_free_tx_skbufs(priv);
532
533 /* Free the region of consistent memory previously allocated for
534 * the DMA */
535 dma_free_coherent(priv->device,
536 priv->dma_tx_size * sizeof(struct dma_desc),
537 priv->dma_tx, priv->dma_tx_phy);
538 dma_free_coherent(priv->device,
539 priv->dma_rx_size * sizeof(struct dma_desc),
540 priv->dma_rx, priv->dma_rx_phy);
541 kfree(priv->rx_skbuff_dma);
542 kfree(priv->rx_skbuff);
543 kfree(priv->tx_skbuff);
544}
545
546/**
547 * stmmac_dma_operation_mode - HW DMA operation mode
548 * @priv : pointer to the private device structure.
549 * Description: it sets the DMA operation mode: tx/rx DMA thresholds
550 * or Store-And-Forward capability.
551 */
552static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
553{
554 if (likely(priv->plat->force_sf_dma_mode ||
555 ((priv->plat->tx_coe) && (!priv->no_csum_insertion)))) {
556 /*
557 * In case of GMAC, SF mode can be enabled
558 * to perform the TX COE in HW. This depends on:
559 * 1) TX COE if actually supported
560 * 2) There is no bugged Jumbo frame support
561 * that needs to not insert csum in the TDES.
562 */
563 priv->hw->dma->dma_mode(priv->ioaddr,
564 SF_DMA_MODE, SF_DMA_MODE);
565 tc = SF_DMA_MODE;
566 } else
567 priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
568}
569
570/**
571 * stmmac_tx:
572 * @priv: private driver structure
573 * Description: it reclaims resources after transmission completes.
574 */
575static void stmmac_tx(struct stmmac_priv *priv)
576{
577 unsigned int txsize = priv->dma_tx_size;
578
579 while (priv->dirty_tx != priv->cur_tx) {
580 int last;
581 unsigned int entry = priv->dirty_tx % txsize;
582 struct sk_buff *skb = priv->tx_skbuff[entry];
583 struct dma_desc *p = priv->dma_tx + entry;
584
585 /* Check if the descriptor is owned by the DMA. */
586 if (priv->hw->desc->get_tx_owner(p))
587 break;
588
589 /* Verify tx error by looking at the last segment */
590 last = priv->hw->desc->get_tx_ls(p);
591 if (likely(last)) {
592 int tx_error =
593 priv->hw->desc->tx_status(&priv->dev->stats,
594 &priv->xstats, p,
595 priv->ioaddr);
596 if (likely(tx_error == 0)) {
597 priv->dev->stats.tx_packets++;
598 priv->xstats.tx_pkt_n++;
599 } else
600 priv->dev->stats.tx_errors++;
601 }
602 TX_DBG("%s: curr %d, dirty %d\n", __func__,
603 priv->cur_tx, priv->dirty_tx);
604
605 if (likely(p->des2))
606 dma_unmap_single(priv->device, p->des2,
607 priv->hw->desc->get_tx_len(p),
608 DMA_TO_DEVICE);
609 if (unlikely(p->des3))
610 p->des3 = 0;
611
612 if (likely(skb != NULL)) {
613 /*
614 * If there's room in the queue (limit it to size)
615 * we add this skb back into the pool,
616 * if it's the right size.
617 */
618 if ((skb_queue_len(&priv->rx_recycle) <
619 priv->dma_rx_size) &&
620 skb_recycle_check(skb, priv->dma_buf_sz))
621 __skb_queue_head(&priv->rx_recycle, skb);
622 else
623 dev_kfree_skb(skb);
624
625 priv->tx_skbuff[entry] = NULL;
626 }
627
628 priv->hw->desc->release_tx_desc(p);
629
630 entry = (++priv->dirty_tx) % txsize;
631 }
632 if (unlikely(netif_queue_stopped(priv->dev) &&
633 stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
634 netif_tx_lock(priv->dev);
635 if (netif_queue_stopped(priv->dev) &&
636 stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
637 TX_DBG("%s: restart transmit\n", __func__);
638 netif_wake_queue(priv->dev);
639 }
640 netif_tx_unlock(priv->dev);
641 }
642}
643
644static inline void stmmac_enable_irq(struct stmmac_priv *priv)
645{
646#ifdef CONFIG_STMMAC_TIMER
647 if (likely(priv->tm->enable))
648 priv->tm->timer_start(tmrate);
649 else
650#endif
651 priv->hw->dma->enable_dma_irq(priv->ioaddr);
652}
653
654static inline void stmmac_disable_irq(struct stmmac_priv *priv)
655{
656#ifdef CONFIG_STMMAC_TIMER
657 if (likely(priv->tm->enable))
658 priv->tm->timer_stop();
659 else
660#endif
661 priv->hw->dma->disable_dma_irq(priv->ioaddr);
662}
663
664static int stmmac_has_work(struct stmmac_priv *priv)
665{
666 unsigned int has_work = 0;
667 int rxret, tx_work = 0;
668
669 rxret = priv->hw->desc->get_rx_owner(priv->dma_rx +
670 (priv->cur_rx % priv->dma_rx_size));
671
672 if (priv->dirty_tx != priv->cur_tx)
673 tx_work = 1;
674
675 if (likely(!rxret || tx_work))
676 has_work = 1;
677
678 return has_work;
679}
680
681static inline void _stmmac_schedule(struct stmmac_priv *priv)
682{
683 if (likely(stmmac_has_work(priv))) {
684 stmmac_disable_irq(priv);
685 napi_schedule(&priv->napi);
686 }
687}
688
689#ifdef CONFIG_STMMAC_TIMER
690void stmmac_schedule(struct net_device *dev)
691{
692 struct stmmac_priv *priv = netdev_priv(dev);
693
694 priv->xstats.sched_timer_n++;
695
696 _stmmac_schedule(priv);
697}
698
699static void stmmac_no_timer_started(unsigned int x)
700{;
701};
702
703static void stmmac_no_timer_stopped(void)
704{;
705};
706#endif
707
708/**
709 * stmmac_tx_err:
710 * @priv: pointer to the private device structure
711 * Description: it cleans the descriptors and restarts the transmission
712 * in case of errors.
713 */
714static void stmmac_tx_err(struct stmmac_priv *priv)
715{
716
717 netif_stop_queue(priv->dev);
718
719 priv->hw->dma->stop_tx(priv->ioaddr);
720 dma_free_tx_skbufs(priv);
721 priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
722 priv->dirty_tx = 0;
723 priv->cur_tx = 0;
724 priv->hw->dma->start_tx(priv->ioaddr);
725
726 priv->dev->stats.tx_errors++;
727 netif_wake_queue(priv->dev);
728}
729
730
731static void stmmac_dma_interrupt(struct stmmac_priv *priv)
732{
733 int status;
734
735 status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats);
736 if (likely(status == handle_tx_rx))
737 _stmmac_schedule(priv);
738
739 else if (unlikely(status == tx_hard_error_bump_tc)) {
740 /* Try to bump up the dma threshold on this failure */
741 if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) {
742 tc += 64;
743 priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE);
744 priv->xstats.threshold = tc;
745 }
746 } else if (unlikely(status == tx_hard_error))
747 stmmac_tx_err(priv);
748}
749
750/**
751 * stmmac_open - open entry point of the driver
752 * @dev : pointer to the device structure.
753 * Description:
754 * This function is the open entry point of the driver.
755 * Return value:
756 * 0 on success and an appropriate (-)ve integer as defined in errno.h
757 * file on failure.
758 */
759static int stmmac_open(struct net_device *dev)
760{
761 struct stmmac_priv *priv = netdev_priv(dev);
762 int ret;
763
764 /* Check that the MAC address is valid. If its not, refuse
765 * to bring the device up. The user must specify an
766 * address using the following linux command:
767 * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */
768 if (!is_valid_ether_addr(dev->dev_addr)) {
769 random_ether_addr(dev->dev_addr);
770 pr_warning("%s: generated random MAC address %pM\n", dev->name,
771 dev->dev_addr);
772 }
773
774 stmmac_verify_args();
775
776#ifdef CONFIG_STMMAC_TIMER
777 priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
778 if (unlikely(priv->tm == NULL)) {
779 pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
780 return -ENOMEM;
781 }
782 priv->tm->freq = tmrate;
783
784 /* Test if the external timer can be actually used.
785 * In case of failure continue without timer. */
786 if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
787 pr_warning("stmmaceth: cannot attach the external timer.\n");
788 priv->tm->freq = 0;
789 priv->tm->timer_start = stmmac_no_timer_started;
790 priv->tm->timer_stop = stmmac_no_timer_stopped;
791 } else
792 priv->tm->enable = 1;
793#endif
794 ret = stmmac_init_phy(dev);
795 if (unlikely(ret)) {
796 pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
797 goto open_error;
798 }
799
800 /* Create and initialize the TX/RX descriptors chains. */
801 priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
802 priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
803 priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
804 init_dma_desc_rings(dev);
805
806 /* DMA initialization and SW reset */
807 ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl,
808 priv->dma_tx_phy, priv->dma_rx_phy);
809 if (ret < 0) {
810 pr_err("%s: DMA initialization failed\n", __func__);
811 goto open_error;
812 }
813
814 /* Copy the MAC addr into the HW */
815 priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0);
816 /* If required, perform hw setup of the bus. */
817 if (priv->plat->bus_setup)
818 priv->plat->bus_setup(priv->ioaddr);
819 /* Initialize the MAC Core */
820 priv->hw->mac->core_init(priv->ioaddr);
821
822 priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr);
823 if (priv->rx_coe)
824 pr_info("stmmac: Rx Checksum Offload Engine supported\n");
825 if (priv->plat->tx_coe)
826 pr_info("\tTX Checksum insertion supported\n");
827 netdev_update_features(dev);
828
829 /* Initialise the MMC (if present) to disable all interrupts. */
830 writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
831 writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
832
833 /* Request the IRQ lines */
834 ret = request_irq(dev->irq, stmmac_interrupt,
835 IRQF_SHARED, dev->name, dev);
836 if (unlikely(ret < 0)) {
837 pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
838 __func__, dev->irq, ret);
839 goto open_error;
840 }
841
842 /* Enable the MAC Rx/Tx */
843 stmmac_enable_mac(priv->ioaddr);
844
845 /* Set the HW DMA mode and the COE */
846 stmmac_dma_operation_mode(priv);
847
848 /* Extra statistics */
849 memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
850 priv->xstats.threshold = tc;
851
852 /* Start the ball rolling... */
853 DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
854 priv->hw->dma->start_tx(priv->ioaddr);
855 priv->hw->dma->start_rx(priv->ioaddr);
856
857#ifdef CONFIG_STMMAC_TIMER
858 priv->tm->timer_start(tmrate);
859#endif
860 /* Dump DMA/MAC registers */
861 if (netif_msg_hw(priv)) {
862 priv->hw->mac->dump_regs(priv->ioaddr);
863 priv->hw->dma->dump_regs(priv->ioaddr);
864 }
865
866 if (priv->phydev)
867 phy_start(priv->phydev);
868
869 napi_enable(&priv->napi);
870 skb_queue_head_init(&priv->rx_recycle);
871 netif_start_queue(dev);
872
873 return 0;
874
875open_error:
876#ifdef CONFIG_STMMAC_TIMER
877 kfree(priv->tm);
878#endif
879 if (priv->phydev)
880 phy_disconnect(priv->phydev);
881
882 return ret;
883}
884
885/**
886 * stmmac_release - close entry point of the driver
887 * @dev : device pointer.
888 * Description:
889 * This is the stop entry point of the driver.
890 */
891static int stmmac_release(struct net_device *dev)
892{
893 struct stmmac_priv *priv = netdev_priv(dev);
894
895 /* Stop and disconnect the PHY */
896 if (priv->phydev) {
897 phy_stop(priv->phydev);
898 phy_disconnect(priv->phydev);
899 priv->phydev = NULL;
900 }
901
902 netif_stop_queue(dev);
903
904#ifdef CONFIG_STMMAC_TIMER
905 /* Stop and release the timer */
906 stmmac_close_ext_timer();
907 if (priv->tm != NULL)
908 kfree(priv->tm);
909#endif
910 napi_disable(&priv->napi);
911 skb_queue_purge(&priv->rx_recycle);
912
913 /* Free the IRQ lines */
914 free_irq(dev->irq, dev);
915
916 /* Stop TX/RX DMA and clear the descriptors */
917 priv->hw->dma->stop_tx(priv->ioaddr);
918 priv->hw->dma->stop_rx(priv->ioaddr);
919
920 /* Release and free the Rx/Tx resources */
921 free_dma_desc_resources(priv);
922
923 /* Disable the MAC Rx/Tx */
924 stmmac_disable_mac(priv->ioaddr);
925
926 netif_carrier_off(dev);
927
928 return 0;
929}
930
931static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
932 struct net_device *dev,
933 int csum_insertion)
934{
935 struct stmmac_priv *priv = netdev_priv(dev);
936 unsigned int nopaged_len = skb_headlen(skb);
937 unsigned int txsize = priv->dma_tx_size;
938 unsigned int entry = priv->cur_tx % txsize;
939 struct dma_desc *desc = priv->dma_tx + entry;
940
941 if (nopaged_len > BUF_SIZE_8KiB) {
942
943 int buf2_size = nopaged_len - BUF_SIZE_8KiB;
944
945 desc->des2 = dma_map_single(priv->device, skb->data,
946 BUF_SIZE_8KiB, DMA_TO_DEVICE);
947 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
948 priv->hw->desc->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
949 csum_insertion);
950
951 entry = (++priv->cur_tx) % txsize;
952 desc = priv->dma_tx + entry;
953
954 desc->des2 = dma_map_single(priv->device,
955 skb->data + BUF_SIZE_8KiB,
956 buf2_size, DMA_TO_DEVICE);
957 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
958 priv->hw->desc->prepare_tx_desc(desc, 0, buf2_size,
959 csum_insertion);
960 priv->hw->desc->set_tx_owner(desc);
961 priv->tx_skbuff[entry] = NULL;
962 } else {
963 desc->des2 = dma_map_single(priv->device, skb->data,
964 nopaged_len, DMA_TO_DEVICE);
965 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
966 priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
967 csum_insertion);
968 }
969 return entry;
970}
971
972/**
973 * stmmac_xmit:
974 * @skb : the socket buffer
975 * @dev : device pointer
976 * Description : Tx entry point of the driver.
977 */
978static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
979{
980 struct stmmac_priv *priv = netdev_priv(dev);
981 unsigned int txsize = priv->dma_tx_size;
982 unsigned int entry;
983 int i, csum_insertion = 0;
984 int nfrags = skb_shinfo(skb)->nr_frags;
985 struct dma_desc *desc, *first;
986
987 if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
988 if (!netif_queue_stopped(dev)) {
989 netif_stop_queue(dev);
990 /* This is a hard error, log it. */
991 pr_err("%s: BUG! Tx Ring full when queue awake\n",
992 __func__);
993 }
994 return NETDEV_TX_BUSY;
995 }
996
997 entry = priv->cur_tx % txsize;
998
999#ifdef STMMAC_XMIT_DEBUG
1000 if ((skb->len > ETH_FRAME_LEN) || nfrags)
1001 pr_info("stmmac xmit:\n"
1002 "\tskb addr %p - len: %d - nopaged_len: %d\n"
1003 "\tn_frags: %d - ip_summed: %d - %s gso\n",
1004 skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
1005 !skb_is_gso(skb) ? "isn't" : "is");
1006#endif
1007
1008 csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
1009
1010 desc = priv->dma_tx + entry;
1011 first = desc;
1012
1013#ifdef STMMAC_XMIT_DEBUG
1014 if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
1015 pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
1016 "\t\tn_frags: %d, ip_summed: %d\n",
1017 skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
1018#endif
1019 priv->tx_skbuff[entry] = skb;
1020 if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
1021 entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
1022 desc = priv->dma_tx + entry;
1023 } else {
1024 unsigned int nopaged_len = skb_headlen(skb);
1025 desc->des2 = dma_map_single(priv->device, skb->data,
1026 nopaged_len, DMA_TO_DEVICE);
1027 priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
1028 csum_insertion);
1029 }
1030
1031 for (i = 0; i < nfrags; i++) {
1032 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1033 int len = frag->size;
1034
1035 entry = (++priv->cur_tx) % txsize;
1036 desc = priv->dma_tx + entry;
1037
1038 TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
1039 desc->des2 = dma_map_page(priv->device, frag->page,
1040 frag->page_offset,
1041 len, DMA_TO_DEVICE);
1042 priv->tx_skbuff[entry] = NULL;
1043 priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion);
1044 wmb();
1045 priv->hw->desc->set_tx_owner(desc);
1046 }
1047
1048 /* Interrupt on completition only for the latest segment */
1049 priv->hw->desc->close_tx_desc(desc);
1050
1051#ifdef CONFIG_STMMAC_TIMER
1052 /* Clean IC while using timer */
1053 if (likely(priv->tm->enable))
1054 priv->hw->desc->clear_tx_ic(desc);
1055#endif
1056
1057 wmb();
1058
1059 /* To avoid raise condition */
1060 priv->hw->desc->set_tx_owner(first);
1061
1062 priv->cur_tx++;
1063
1064#ifdef STMMAC_XMIT_DEBUG
1065 if (netif_msg_pktdata(priv)) {
1066 pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
1067 "first=%p, nfrags=%d\n",
1068 (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
1069 entry, first, nfrags);
1070 display_ring(priv->dma_tx, txsize);
1071 pr_info(">>> frame to be transmitted: ");
1072 print_pkt(skb->data, skb->len);
1073 }
1074#endif
1075 if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
1076 TX_DBG("%s: stop transmitted packets\n", __func__);
1077 netif_stop_queue(dev);
1078 }
1079
1080 dev->stats.tx_bytes += skb->len;
1081
1082 skb_tx_timestamp(skb);
1083
1084 priv->hw->dma->enable_dma_transmission(priv->ioaddr);
1085
1086 return NETDEV_TX_OK;
1087}
1088
1089static inline void stmmac_rx_refill(struct stmmac_priv *priv)
1090{
1091 unsigned int rxsize = priv->dma_rx_size;
1092 int bfsize = priv->dma_buf_sz;
1093 struct dma_desc *p = priv->dma_rx;
1094
1095 for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
1096 unsigned int entry = priv->dirty_rx % rxsize;
1097 if (likely(priv->rx_skbuff[entry] == NULL)) {
1098 struct sk_buff *skb;
1099
1100 skb = __skb_dequeue(&priv->rx_recycle);
1101 if (skb == NULL)
1102 skb = netdev_alloc_skb_ip_align(priv->dev,
1103 bfsize);
1104
1105 if (unlikely(skb == NULL))
1106 break;
1107
1108 priv->rx_skbuff[entry] = skb;
1109 priv->rx_skbuff_dma[entry] =
1110 dma_map_single(priv->device, skb->data, bfsize,
1111 DMA_FROM_DEVICE);
1112
1113 (p + entry)->des2 = priv->rx_skbuff_dma[entry];
1114 if (unlikely(priv->plat->has_gmac)) {
1115 if (bfsize >= BUF_SIZE_8KiB)
1116 (p + entry)->des3 =
1117 (p + entry)->des2 + BUF_SIZE_8KiB;
1118 }
1119 RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
1120 }
1121 wmb();
1122 priv->hw->desc->set_rx_owner(p + entry);
1123 }
1124}
1125
1126static int stmmac_rx(struct stmmac_priv *priv, int limit)
1127{
1128 unsigned int rxsize = priv->dma_rx_size;
1129 unsigned int entry = priv->cur_rx % rxsize;
1130 unsigned int next_entry;
1131 unsigned int count = 0;
1132 struct dma_desc *p = priv->dma_rx + entry;
1133 struct dma_desc *p_next;
1134
1135#ifdef STMMAC_RX_DEBUG
1136 if (netif_msg_hw(priv)) {
1137 pr_debug(">>> stmmac_rx: descriptor ring:\n");
1138 display_ring(priv->dma_rx, rxsize);
1139 }
1140#endif
1141 count = 0;
1142 while (!priv->hw->desc->get_rx_owner(p)) {
1143 int status;
1144
1145 if (count >= limit)
1146 break;
1147
1148 count++;
1149
1150 next_entry = (++priv->cur_rx) % rxsize;
1151 p_next = priv->dma_rx + next_entry;
1152 prefetch(p_next);
1153
1154 /* read the status of the incoming frame */
1155 status = (priv->hw->desc->rx_status(&priv->dev->stats,
1156 &priv->xstats, p));
1157 if (unlikely(status == discard_frame))
1158 priv->dev->stats.rx_errors++;
1159 else {
1160 struct sk_buff *skb;
1161 int frame_len;
1162
1163 frame_len = priv->hw->desc->get_rx_frame_len(p);
1164 /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
1165 * Type frames (LLC/LLC-SNAP) */
1166 if (unlikely(status != llc_snap))
1167 frame_len -= ETH_FCS_LEN;
1168#ifdef STMMAC_RX_DEBUG
1169 if (frame_len > ETH_FRAME_LEN)
1170 pr_debug("\tRX frame size %d, COE status: %d\n",
1171 frame_len, status);
1172
1173 if (netif_msg_hw(priv))
1174 pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
1175 p, entry, p->des2);
1176#endif
1177 skb = priv->rx_skbuff[entry];
1178 if (unlikely(!skb)) {
1179 pr_err("%s: Inconsistent Rx descriptor chain\n",
1180 priv->dev->name);
1181 priv->dev->stats.rx_dropped++;
1182 break;
1183 }
1184 prefetch(skb->data - NET_IP_ALIGN);
1185 priv->rx_skbuff[entry] = NULL;
1186
1187 skb_put(skb, frame_len);
1188 dma_unmap_single(priv->device,
1189 priv->rx_skbuff_dma[entry],
1190 priv->dma_buf_sz, DMA_FROM_DEVICE);
1191#ifdef STMMAC_RX_DEBUG
1192 if (netif_msg_pktdata(priv)) {
1193 pr_info(" frame received (%dbytes)", frame_len);
1194 print_pkt(skb->data, frame_len);
1195 }
1196#endif
1197 skb->protocol = eth_type_trans(skb, priv->dev);
1198
1199 if (unlikely(status == csum_none)) {
1200 /* always for the old mac 10/100 */
1201 skb_checksum_none_assert(skb);
1202 netif_receive_skb(skb);
1203 } else {
1204 skb->ip_summed = CHECKSUM_UNNECESSARY;
1205 napi_gro_receive(&priv->napi, skb);
1206 }
1207
1208 priv->dev->stats.rx_packets++;
1209 priv->dev->stats.rx_bytes += frame_len;
1210 }
1211 entry = next_entry;
1212 p = p_next; /* use prefetched values */
1213 }
1214
1215 stmmac_rx_refill(priv);
1216
1217 priv->xstats.rx_pkt_n += count;
1218
1219 return count;
1220}
1221
1222/**
1223 * stmmac_poll - stmmac poll method (NAPI)
1224 * @napi : pointer to the napi structure.
1225 * @budget : maximum number of packets that the current CPU can receive from
1226 * all interfaces.
1227 * Description :
1228 * This function implements the the reception process.
1229 * Also it runs the TX completion thread
1230 */
1231static int stmmac_poll(struct napi_struct *napi, int budget)
1232{
1233 struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
1234 int work_done = 0;
1235
1236 priv->xstats.poll_n++;
1237 stmmac_tx(priv);
1238 work_done = stmmac_rx(priv, budget);
1239
1240 if (work_done < budget) {
1241 napi_complete(napi);
1242 stmmac_enable_irq(priv);
1243 }
1244 return work_done;
1245}
1246
1247/**
1248 * stmmac_tx_timeout
1249 * @dev : Pointer to net device structure
1250 * Description: this function is called when a packet transmission fails to
1251 * complete within a reasonable tmrate. The driver will mark the error in the
1252 * netdev structure and arrange for the device to be reset to a sane state
1253 * in order to transmit a new packet.
1254 */
1255static void stmmac_tx_timeout(struct net_device *dev)
1256{
1257 struct stmmac_priv *priv = netdev_priv(dev);
1258
1259 /* Clear Tx resources and restart transmitting again */
1260 stmmac_tx_err(priv);
1261}
1262
1263/* Configuration changes (passed on by ifconfig) */
1264static int stmmac_config(struct net_device *dev, struct ifmap *map)
1265{
1266 if (dev->flags & IFF_UP) /* can't act on a running interface */
1267 return -EBUSY;
1268
1269 /* Don't allow changing the I/O address */
1270 if (map->base_addr != dev->base_addr) {
1271 pr_warning("%s: can't change I/O address\n", dev->name);
1272 return -EOPNOTSUPP;
1273 }
1274
1275 /* Don't allow changing the IRQ */
1276 if (map->irq != dev->irq) {
1277 pr_warning("%s: can't change IRQ number %d\n",
1278 dev->name, dev->irq);
1279 return -EOPNOTSUPP;
1280 }
1281
1282 /* ignore other fields */
1283 return 0;
1284}
1285
1286/**
1287 * stmmac_multicast_list - entry point for multicast addressing
1288 * @dev : pointer to the device structure
1289 * Description:
1290 * This function is a driver entry point which gets called by the kernel
1291 * whenever multicast addresses must be enabled/disabled.
1292 * Return value:
1293 * void.
1294 */
1295static void stmmac_multicast_list(struct net_device *dev)
1296{
1297 struct stmmac_priv *priv = netdev_priv(dev);
1298
1299 spin_lock(&priv->lock);
1300 priv->hw->mac->set_filter(dev);
1301 spin_unlock(&priv->lock);
1302}
1303
1304/**
1305 * stmmac_change_mtu - entry point to change MTU size for the device.
1306 * @dev : device pointer.
1307 * @new_mtu : the new MTU size for the device.
1308 * Description: the Maximum Transfer Unit (MTU) is used by the network layer
1309 * to drive packet transmission. Ethernet has an MTU of 1500 octets
1310 * (ETH_DATA_LEN). This value can be changed with ifconfig.
1311 * Return value:
1312 * 0 on success and an appropriate (-)ve integer as defined in errno.h
1313 * file on failure.
1314 */
1315static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
1316{
1317 struct stmmac_priv *priv = netdev_priv(dev);
1318 int max_mtu;
1319
1320 if (netif_running(dev)) {
1321 pr_err("%s: must be stopped to change its MTU\n", dev->name);
1322 return -EBUSY;
1323 }
1324
1325 if (priv->plat->has_gmac)
1326 max_mtu = JUMBO_LEN;
1327 else
1328 max_mtu = ETH_DATA_LEN;
1329
1330 if ((new_mtu < 46) || (new_mtu > max_mtu)) {
1331 pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
1332 return -EINVAL;
1333 }
1334
1335 dev->mtu = new_mtu;
1336 netdev_update_features(dev);
1337
1338 return 0;
1339}
1340
1341static u32 stmmac_fix_features(struct net_device *dev, u32 features)
1342{
1343 struct stmmac_priv *priv = netdev_priv(dev);
1344
1345 if (!priv->rx_coe)
1346 features &= ~NETIF_F_RXCSUM;
1347 if (!priv->plat->tx_coe)
1348 features &= ~NETIF_F_ALL_CSUM;
1349
1350 /* Some GMAC devices have a bugged Jumbo frame support that
1351 * needs to have the Tx COE disabled for oversized frames
1352 * (due to limited buffer sizes). In this case we disable
1353 * the TX csum insertionin the TDES and not use SF. */
1354 if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
1355 features &= ~NETIF_F_ALL_CSUM;
1356
1357 return features;
1358}
1359
1360static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
1361{
1362 struct net_device *dev = (struct net_device *)dev_id;
1363 struct stmmac_priv *priv = netdev_priv(dev);
1364
1365 if (unlikely(!dev)) {
1366 pr_err("%s: invalid dev pointer\n", __func__);
1367 return IRQ_NONE;
1368 }
1369
1370 if (priv->plat->has_gmac)
1371 /* To handle GMAC own interrupts */
1372 priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr);
1373
1374 stmmac_dma_interrupt(priv);
1375
1376 return IRQ_HANDLED;
1377}
1378
1379#ifdef CONFIG_NET_POLL_CONTROLLER
1380/* Polling receive - used by NETCONSOLE and other diagnostic tools
1381 * to allow network I/O with interrupts disabled. */
1382static void stmmac_poll_controller(struct net_device *dev)
1383{
1384 disable_irq(dev->irq);
1385 stmmac_interrupt(dev->irq, dev);
1386 enable_irq(dev->irq);
1387}
1388#endif
1389
1390/**
1391 * stmmac_ioctl - Entry point for the Ioctl
1392 * @dev: Device pointer.
1393 * @rq: An IOCTL specefic structure, that can contain a pointer to
1394 * a proprietary structure used to pass information to the driver.
1395 * @cmd: IOCTL command
1396 * Description:
1397 * Currently there are no special functionality supported in IOCTL, just the
1398 * phy_mii_ioctl(...) can be invoked.
1399 */
1400static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1401{
1402 struct stmmac_priv *priv = netdev_priv(dev);
1403 int ret;
1404
1405 if (!netif_running(dev))
1406 return -EINVAL;
1407
1408 if (!priv->phydev)
1409 return -EINVAL;
1410
1411 spin_lock(&priv->lock);
1412 ret = phy_mii_ioctl(priv->phydev, rq, cmd);
1413 spin_unlock(&priv->lock);
1414
1415 return ret;
1416}
1417
1418static const struct net_device_ops stmmac_netdev_ops = {
1419 .ndo_open = stmmac_open,
1420 .ndo_start_xmit = stmmac_xmit,
1421 .ndo_stop = stmmac_release,
1422 .ndo_change_mtu = stmmac_change_mtu,
1423 .ndo_fix_features = stmmac_fix_features,
1424 .ndo_set_multicast_list = stmmac_multicast_list,
1425 .ndo_tx_timeout = stmmac_tx_timeout,
1426 .ndo_do_ioctl = stmmac_ioctl,
1427 .ndo_set_config = stmmac_config,
1428#ifdef CONFIG_NET_POLL_CONTROLLER
1429 .ndo_poll_controller = stmmac_poll_controller,
1430#endif
1431 .ndo_set_mac_address = eth_mac_addr,
1432};
1433
1434/**
1435 * stmmac_probe - Initialization of the adapter .
1436 * @dev : device pointer
1437 * Description: The function initializes the network device structure for
1438 * the STMMAC driver. It also calls the low level routines
1439 * in order to init the HW (i.e. the DMA engine)
1440 */
1441static int stmmac_probe(struct net_device *dev)
1442{
1443 int ret = 0;
1444 struct stmmac_priv *priv = netdev_priv(dev);
1445
1446 ether_setup(dev);
1447
1448 dev->netdev_ops = &stmmac_netdev_ops;
1449 stmmac_set_ethtool_ops(dev);
1450
1451 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
1452 dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
1453 dev->watchdog_timeo = msecs_to_jiffies(watchdog);
1454#ifdef STMMAC_VLAN_TAG_USED
1455 /* Both mac100 and gmac support receive VLAN tag detection */
1456 dev->features |= NETIF_F_HW_VLAN_RX;
1457#endif
1458 priv->msg_enable = netif_msg_init(debug, default_msg_level);
1459
1460 if (flow_ctrl)
1461 priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
1462
1463 priv->pause = pause;
1464 netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
1465
1466 /* Get the MAC address */
1467 priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr,
1468 dev->dev_addr, 0);
1469
1470 if (!is_valid_ether_addr(dev->dev_addr))
1471 pr_warning("\tno valid MAC address;"
1472 "please, use ifconfig or nwhwconfig!\n");
1473
1474 spin_lock_init(&priv->lock);
1475
1476 ret = register_netdev(dev);
1477 if (ret) {
1478 pr_err("%s: ERROR %i registering the device\n",
1479 __func__, ret);
1480 return -ENODEV;
1481 }
1482
1483 DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
1484 dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
1485 (dev->features & NETIF_F_IP_CSUM) ? "on" : "off");
1486
1487 return ret;
1488}
1489
1490/**
1491 * stmmac_mac_device_setup
1492 * @dev : device pointer
1493 * Description: select and initialise the mac device (mac100 or Gmac).
1494 */
1495static int stmmac_mac_device_setup(struct net_device *dev)
1496{
1497 struct stmmac_priv *priv = netdev_priv(dev);
1498
1499 struct mac_device_info *device;
1500
1501 if (priv->plat->has_gmac)
1502 device = dwmac1000_setup(priv->ioaddr);
1503 else
1504 device = dwmac100_setup(priv->ioaddr);
1505
1506 if (!device)
1507 return -ENOMEM;
1508
1509 if (priv->plat->enh_desc) {
1510 device->desc = &enh_desc_ops;
1511 pr_info("\tEnhanced descriptor structure\n");
1512 } else
1513 device->desc = &ndesc_ops;
1514
1515 priv->hw = device;
1516
1517 if (device_can_wakeup(priv->device)) {
1518 priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */
1519 enable_irq_wake(dev->irq);
1520 }
1521
1522 return 0;
1523}
1524
1525/**
1526 * stmmac_dvr_probe
1527 * @pdev: platform device pointer
1528 * Description: the driver is initialized through platform_device.
1529 */
1530static int stmmac_dvr_probe(struct platform_device *pdev)
1531{
1532 int ret = 0;
1533 struct resource *res;
1534 void __iomem *addr = NULL;
1535 struct net_device *ndev = NULL;
1536 struct stmmac_priv *priv = NULL;
1537 struct plat_stmmacenet_data *plat_dat;
1538
1539 pr_info("STMMAC driver:\n\tplatform registration... ");
1540 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1541 if (!res)
1542 return -ENODEV;
1543 pr_info("\tdone!\n");
1544
1545 if (!request_mem_region(res->start, resource_size(res),
1546 pdev->name)) {
1547 pr_err("%s: ERROR: memory allocation failed"
1548 "cannot get the I/O addr 0x%x\n",
1549 __func__, (unsigned int)res->start);
1550 return -EBUSY;
1551 }
1552
1553 addr = ioremap(res->start, resource_size(res));
1554 if (!addr) {
1555 pr_err("%s: ERROR: memory mapping failed\n", __func__);
1556 ret = -ENOMEM;
1557 goto out_release_region;
1558 }
1559
1560 ndev = alloc_etherdev(sizeof(struct stmmac_priv));
1561 if (!ndev) {
1562 pr_err("%s: ERROR: allocating the device\n", __func__);
1563 ret = -ENOMEM;
1564 goto out_unmap;
1565 }
1566
1567 SET_NETDEV_DEV(ndev, &pdev->dev);
1568
1569 /* Get the MAC information */
1570 ndev->irq = platform_get_irq_byname(pdev, "macirq");
1571 if (ndev->irq == -ENXIO) {
1572 pr_err("%s: ERROR: MAC IRQ configuration "
1573 "information not found\n", __func__);
1574 ret = -ENXIO;
1575 goto out_free_ndev;
1576 }
1577
1578 priv = netdev_priv(ndev);
1579 priv->device = &(pdev->dev);
1580 priv->dev = ndev;
1581 plat_dat = pdev->dev.platform_data;
1582
1583 priv->plat = plat_dat;
1584
1585 priv->ioaddr = addr;
1586
1587 /* PMT module is not integrated in all the MAC devices. */
1588 if (plat_dat->pmt) {
1589 pr_info("\tPMT module supported\n");
1590 device_set_wakeup_capable(&pdev->dev, 1);
1591 }
1592
1593 platform_set_drvdata(pdev, ndev);
1594
1595 /* Set the I/O base addr */
1596 ndev->base_addr = (unsigned long)addr;
1597
1598 /* Custom initialisation */
1599 if (priv->plat->init) {
1600 ret = priv->plat->init(pdev);
1601 if (unlikely(ret))
1602 goto out_free_ndev;
1603 }
1604
1605 /* MAC HW revice detection */
1606 ret = stmmac_mac_device_setup(ndev);
1607 if (ret < 0)
1608 goto out_plat_exit;
1609
1610 /* Network Device Registration */
1611 ret = stmmac_probe(ndev);
1612 if (ret < 0)
1613 goto out_plat_exit;
1614
1615 /* Override with kernel parameters if supplied XXX CRS XXX
1616 * this needs to have multiple instances */
1617 if ((phyaddr >= 0) && (phyaddr <= 31))
1618 priv->plat->phy_addr = phyaddr;
1619
1620 pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
1621 "\tIO base addr: 0x%p)\n", ndev->name, pdev->name,
1622 pdev->id, ndev->irq, addr);
1623
1624 /* MDIO bus Registration */
1625 pr_debug("\tMDIO bus (id: %d)...", priv->plat->bus_id);
1626 ret = stmmac_mdio_register(ndev);
1627 if (ret < 0)
1628 goto out_unregister;
1629 pr_debug("registered!\n");
1630 return 0;
1631
1632out_unregister:
1633 unregister_netdev(ndev);
1634out_plat_exit:
1635 if (priv->plat->exit)
1636 priv->plat->exit(pdev);
1637out_free_ndev:
1638 free_netdev(ndev);
1639 platform_set_drvdata(pdev, NULL);
1640out_unmap:
1641 iounmap(addr);
1642out_release_region:
1643 release_mem_region(res->start, resource_size(res));
1644
1645 return ret;
1646}
1647
1648/**
1649 * stmmac_dvr_remove
1650 * @pdev: platform device pointer
1651 * Description: this function resets the TX/RX processes, disables the MAC RX/TX
1652 * changes the link status, releases the DMA descriptor rings,
1653 * unregisters the MDIO bus and unmaps the allocated memory.
1654 */
1655static int stmmac_dvr_remove(struct platform_device *pdev)
1656{
1657 struct net_device *ndev = platform_get_drvdata(pdev);
1658 struct stmmac_priv *priv = netdev_priv(ndev);
1659 struct resource *res;
1660
1661 pr_info("%s:\n\tremoving driver", __func__);
1662
1663 priv->hw->dma->stop_rx(priv->ioaddr);
1664 priv->hw->dma->stop_tx(priv->ioaddr);
1665
1666 stmmac_disable_mac(priv->ioaddr);
1667
1668 netif_carrier_off(ndev);
1669
1670 stmmac_mdio_unregister(ndev);
1671
1672 if (priv->plat->exit)
1673 priv->plat->exit(pdev);
1674
1675 platform_set_drvdata(pdev, NULL);
1676 unregister_netdev(ndev);
1677
1678 iounmap((void *)priv->ioaddr);
1679 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1680 release_mem_region(res->start, resource_size(res));
1681
1682 free_netdev(ndev);
1683
1684 return 0;
1685}
1686
1687#ifdef CONFIG_PM
1688static int stmmac_suspend(struct device *dev)
1689{
1690 struct net_device *ndev = dev_get_drvdata(dev);
1691 struct stmmac_priv *priv = netdev_priv(ndev);
1692 int dis_ic = 0;
1693
1694 if (!ndev || !netif_running(ndev))
1695 return 0;
1696
1697 spin_lock(&priv->lock);
1698
1699 netif_device_detach(ndev);
1700 netif_stop_queue(ndev);
1701 if (priv->phydev)
1702 phy_stop(priv->phydev);
1703
1704#ifdef CONFIG_STMMAC_TIMER
1705 priv->tm->timer_stop();
1706 if (likely(priv->tm->enable))
1707 dis_ic = 1;
1708#endif
1709 napi_disable(&priv->napi);
1710
1711 /* Stop TX/RX DMA */
1712 priv->hw->dma->stop_tx(priv->ioaddr);
1713 priv->hw->dma->stop_rx(priv->ioaddr);
1714 /* Clear the Rx/Tx descriptors */
1715 priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
1716 dis_ic);
1717 priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
1718
1719 /* Enable Power down mode by programming the PMT regs */
1720 if (device_may_wakeup(priv->device))
1721 priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
1722 else
1723 stmmac_disable_mac(priv->ioaddr);
1724
1725 spin_unlock(&priv->lock);
1726 return 0;
1727}
1728
1729static int stmmac_resume(struct device *dev)
1730{
1731 struct net_device *ndev = dev_get_drvdata(dev);
1732 struct stmmac_priv *priv = netdev_priv(ndev);
1733
1734 if (!netif_running(ndev))
1735 return 0;
1736
1737 spin_lock(&priv->lock);
1738
1739 /* Power Down bit, into the PM register, is cleared
1740 * automatically as soon as a magic packet or a Wake-up frame
1741 * is received. Anyway, it's better to manually clear
1742 * this bit because it can generate problems while resuming
1743 * from another devices (e.g. serial console). */
1744 if (device_may_wakeup(priv->device))
1745 priv->hw->mac->pmt(priv->ioaddr, 0);
1746
1747 netif_device_attach(ndev);
1748
1749 /* Enable the MAC and DMA */
1750 stmmac_enable_mac(priv->ioaddr);
1751 priv->hw->dma->start_tx(priv->ioaddr);
1752 priv->hw->dma->start_rx(priv->ioaddr);
1753
1754#ifdef CONFIG_STMMAC_TIMER
1755 if (likely(priv->tm->enable))
1756 priv->tm->timer_start(tmrate);
1757#endif
1758 napi_enable(&priv->napi);
1759
1760 if (priv->phydev)
1761 phy_start(priv->phydev);
1762
1763 netif_start_queue(ndev);
1764
1765 spin_unlock(&priv->lock);
1766 return 0;
1767}
1768
1769static int stmmac_freeze(struct device *dev)
1770{
1771 struct net_device *ndev = dev_get_drvdata(dev);
1772
1773 if (!ndev || !netif_running(ndev))
1774 return 0;
1775
1776 return stmmac_release(ndev);
1777}
1778
1779static int stmmac_restore(struct device *dev)
1780{
1781 struct net_device *ndev = dev_get_drvdata(dev);
1782
1783 if (!ndev || !netif_running(ndev))
1784 return 0;
1785
1786 return stmmac_open(ndev);
1787}
1788
1789static const struct dev_pm_ops stmmac_pm_ops = {
1790 .suspend = stmmac_suspend,
1791 .resume = stmmac_resume,
1792 .freeze = stmmac_freeze,
1793 .thaw = stmmac_restore,
1794 .restore = stmmac_restore,
1795};
1796#else
1797static const struct dev_pm_ops stmmac_pm_ops;
1798#endif /* CONFIG_PM */
1799
1800static struct platform_driver stmmac_driver = {
1801 .probe = stmmac_dvr_probe,
1802 .remove = stmmac_dvr_remove,
1803 .driver = {
1804 .name = STMMAC_RESOURCE_NAME,
1805 .owner = THIS_MODULE,
1806 .pm = &stmmac_pm_ops,
1807 },
1808};
1809
1810/**
1811 * stmmac_init_module - Entry point for the driver
1812 * Description: This function is the entry point for the driver.
1813 */
1814static int __init stmmac_init_module(void)
1815{
1816 int ret;
1817
1818 ret = platform_driver_register(&stmmac_driver);
1819 return ret;
1820}
1821
1822/**
1823 * stmmac_cleanup_module - Cleanup routine for the driver
1824 * Description: This function is the cleanup routine for the driver.
1825 */
1826static void __exit stmmac_cleanup_module(void)
1827{
1828 platform_driver_unregister(&stmmac_driver);
1829}
1830
1831#ifndef MODULE
1832static int __init stmmac_cmdline_opt(char *str)
1833{
1834 char *opt;
1835
1836 if (!str || !*str)
1837 return -EINVAL;
1838 while ((opt = strsep(&str, ",")) != NULL) {
1839 if (!strncmp(opt, "debug:", 6)) {
1840 if (strict_strtoul(opt + 6, 0, (unsigned long *)&debug))
1841 goto err;
1842 } else if (!strncmp(opt, "phyaddr:", 8)) {
1843 if (strict_strtoul(opt + 8, 0,
1844 (unsigned long *)&phyaddr))
1845 goto err;
1846 } else if (!strncmp(opt, "dma_txsize:", 11)) {
1847 if (strict_strtoul(opt + 11, 0,
1848 (unsigned long *)&dma_txsize))
1849 goto err;
1850 } else if (!strncmp(opt, "dma_rxsize:", 11)) {
1851 if (strict_strtoul(opt + 11, 0,
1852 (unsigned long *)&dma_rxsize))
1853 goto err;
1854 } else if (!strncmp(opt, "buf_sz:", 7)) {
1855 if (strict_strtoul(opt + 7, 0,
1856 (unsigned long *)&buf_sz))
1857 goto err;
1858 } else if (!strncmp(opt, "tc:", 3)) {
1859 if (strict_strtoul(opt + 3, 0, (unsigned long *)&tc))
1860 goto err;
1861 } else if (!strncmp(opt, "watchdog:", 9)) {
1862 if (strict_strtoul(opt + 9, 0,
1863 (unsigned long *)&watchdog))
1864 goto err;
1865 } else if (!strncmp(opt, "flow_ctrl:", 10)) {
1866 if (strict_strtoul(opt + 10, 0,
1867 (unsigned long *)&flow_ctrl))
1868 goto err;
1869 } else if (!strncmp(opt, "pause:", 6)) {
1870 if (strict_strtoul(opt + 6, 0, (unsigned long *)&pause))
1871 goto err;
1872#ifdef CONFIG_STMMAC_TIMER
1873 } else if (!strncmp(opt, "tmrate:", 7)) {
1874 if (strict_strtoul(opt + 7, 0,
1875 (unsigned long *)&tmrate))
1876 goto err;
1877#endif
1878 }
1879 }
1880 return 0;
1881
1882err:
1883 pr_err("%s: ERROR broken module parameter conversion", __func__);
1884 return -EINVAL;
1885}
1886
1887__setup("stmmaceth=", stmmac_cmdline_opt);
1888#endif
1889
1890module_init(stmmac_init_module);
1891module_exit(stmmac_cleanup_module);
1892
1893MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
1894MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
1895MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
new file mode 100644
index 000000000000..9c3b9d5c3411
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -0,0 +1,247 @@
1/*******************************************************************************
2 STMMAC Ethernet Driver -- MDIO bus implementation
3 Provides Bus interface for MII registers
4
5 Copyright (C) 2007-2009 STMicroelectronics Ltd
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms and conditions of the GNU General Public License,
9 version 2, as published by the Free Software Foundation.
10
11 This program is distributed in the hope it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19
20 The full GNU General Public License is included in this distribution in
21 the file called "COPYING".
22
23 Author: Carl Shaw <carl.shaw@st.com>
24 Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
25*******************************************************************************/
26
27#include <linux/mii.h>
28#include <linux/phy.h>
29#include <linux/slab.h>
30#include <asm/io.h>
31
32#include "stmmac.h"
33
34#define MII_BUSY 0x00000001
35#define MII_WRITE 0x00000002
36
37/**
38 * stmmac_mdio_read
39 * @bus: points to the mii_bus structure
40 * @phyaddr: MII addr reg bits 15-11
41 * @phyreg: MII addr reg bits 10-6
42 * Description: it reads data from the MII register from within the phy device.
43 * For the 7111 GMAC, we must set the bit 0 in the MII address register while
44 * accessing the PHY registers.
45 * Fortunately, it seems this has no drawback for the 7109 MAC.
46 */
47static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
48{
49 struct net_device *ndev = bus->priv;
50 struct stmmac_priv *priv = netdev_priv(ndev);
51 unsigned int mii_address = priv->hw->mii.addr;
52 unsigned int mii_data = priv->hw->mii.data;
53
54 int data;
55 u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
56 ((phyreg << 6) & (0x000007C0)));
57 regValue |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
58
59 do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
60 writel(regValue, priv->ioaddr + mii_address);
61 do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
62
63 /* Read the data from the MII data register */
64 data = (int)readl(priv->ioaddr + mii_data);
65
66 return data;
67}
68
69/**
70 * stmmac_mdio_write
71 * @bus: points to the mii_bus structure
72 * @phyaddr: MII addr reg bits 15-11
73 * @phyreg: MII addr reg bits 10-6
74 * @phydata: phy data
75 * Description: it writes the data into the MII register from within the device.
76 */
77static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
78 u16 phydata)
79{
80 struct net_device *ndev = bus->priv;
81 struct stmmac_priv *priv = netdev_priv(ndev);
82 unsigned int mii_address = priv->hw->mii.addr;
83 unsigned int mii_data = priv->hw->mii.data;
84
85 u16 value =
86 (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
87 | MII_WRITE;
88
89 value |= MII_BUSY | ((priv->plat->clk_csr & 7) << 2);
90
91
92 /* Wait until any existing MII operation is complete */
93 do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
94
95 /* Set the MII address register to write */
96 writel(phydata, priv->ioaddr + mii_data);
97 writel(value, priv->ioaddr + mii_address);
98
99 /* Wait until any existing MII operation is complete */
100 do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1);
101
102 return 0;
103}
104
105/**
106 * stmmac_mdio_reset
107 * @bus: points to the mii_bus structure
108 * Description: reset the MII bus
109 */
110static int stmmac_mdio_reset(struct mii_bus *bus)
111{
112 struct net_device *ndev = bus->priv;
113 struct stmmac_priv *priv = netdev_priv(ndev);
114 unsigned int mii_address = priv->hw->mii.addr;
115
116 if (priv->plat->mdio_bus_data->phy_reset) {
117 pr_debug("stmmac_mdio_reset: calling phy_reset\n");
118 priv->plat->mdio_bus_data->phy_reset(priv->plat->bsp_priv);
119 }
120
121 /* This is a workaround for problems with the STE101P PHY.
122 * It doesn't complete its reset until at least one clock cycle
123 * on MDC, so perform a dummy mdio read.
124 */
125 writel(0, priv->ioaddr + mii_address);
126
127 return 0;
128}
129
130/**
131 * stmmac_mdio_register
132 * @ndev: net device structure
133 * Description: it registers the MII bus
134 */
135int stmmac_mdio_register(struct net_device *ndev)
136{
137 int err = 0;
138 struct mii_bus *new_bus;
139 int *irqlist;
140 struct stmmac_priv *priv = netdev_priv(ndev);
141 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
142 int addr, found;
143
144 if (!mdio_bus_data)
145 return 0;
146
147 new_bus = mdiobus_alloc();
148 if (new_bus == NULL)
149 return -ENOMEM;
150
151 if (mdio_bus_data->irqs)
152 irqlist = mdio_bus_data->irqs;
153 else
154 irqlist = priv->mii_irq;
155
156 new_bus->name = "STMMAC MII Bus";
157 new_bus->read = &stmmac_mdio_read;
158 new_bus->write = &stmmac_mdio_write;
159 new_bus->reset = &stmmac_mdio_reset;
160 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id);
161 new_bus->priv = ndev;
162 new_bus->irq = irqlist;
163 new_bus->phy_mask = mdio_bus_data->phy_mask;
164 new_bus->parent = priv->device;
165 err = mdiobus_register(new_bus);
166 if (err != 0) {
167 pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
168 goto bus_register_fail;
169 }
170
171 priv->mii = new_bus;
172
173 found = 0;
174 for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
175 struct phy_device *phydev = new_bus->phy_map[addr];
176 if (phydev) {
177 int act = 0;
178 char irq_num[4];
179 char *irq_str;
180
181 /*
182 * If an IRQ was provided to be assigned after
183 * the bus probe, do it here.
184 */
185 if ((mdio_bus_data->irqs == NULL) &&
186 (mdio_bus_data->probed_phy_irq > 0)) {
187 irqlist[addr] = mdio_bus_data->probed_phy_irq;
188 phydev->irq = mdio_bus_data->probed_phy_irq;
189 }
190
191 /*
192 * If we're going to bind the MAC to this PHY bus,
193 * and no PHY number was provided to the MAC,
194 * use the one probed here.
195 */
196 if ((priv->plat->bus_id == mdio_bus_data->bus_id) &&
197 (priv->plat->phy_addr == -1))
198 priv->plat->phy_addr = addr;
199
200 act = (priv->plat->bus_id == mdio_bus_data->bus_id) &&
201 (priv->plat->phy_addr == addr);
202 switch (phydev->irq) {
203 case PHY_POLL:
204 irq_str = "POLL";
205 break;
206 case PHY_IGNORE_INTERRUPT:
207 irq_str = "IGNORE";
208 break;
209 default:
210 sprintf(irq_num, "%d", phydev->irq);
211 irq_str = irq_num;
212 break;
213 }
214 pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
215 ndev->name, phydev->phy_id, addr,
216 irq_str, dev_name(&phydev->dev),
217 act ? " active" : "");
218 found = 1;
219 }
220 }
221
222 if (!found)
223 pr_warning("%s: No PHY found\n", ndev->name);
224
225 return 0;
226
227bus_register_fail:
228 mdiobus_free(new_bus);
229 return err;
230}
231
232/**
233 * stmmac_mdio_unregister
234 * @ndev: net device structure
235 * Description: it unregisters the MII bus
236 */
237int stmmac_mdio_unregister(struct net_device *ndev)
238{
239 struct stmmac_priv *priv = netdev_priv(ndev);
240
241 mdiobus_unregister(priv->mii);
242 priv->mii->priv = NULL;
243 mdiobus_free(priv->mii);
244 priv->mii = NULL;
245
246 return 0;
247}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
new file mode 100644
index 000000000000..2a0e1abde7e7
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
@@ -0,0 +1,134 @@
1/*******************************************************************************
2 STMMAC external timer support.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/kernel.h>
26#include <linux/etherdevice.h>
27#include "stmmac_timer.h"
28
29static void stmmac_timer_handler(void *data)
30{
31 struct net_device *dev = (struct net_device *)data;
32
33 stmmac_schedule(dev);
34}
35
36#define STMMAC_TIMER_MSG(timer, freq) \
37printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
38
39#if defined(CONFIG_STMMAC_RTC_TIMER)
40#include <linux/rtc.h>
41static struct rtc_device *stmmac_rtc;
42static rtc_task_t stmmac_task;
43
44static void stmmac_rtc_start(unsigned int new_freq)
45{
46 rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
47 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
48}
49
50static void stmmac_rtc_stop(void)
51{
52 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
53}
54
55int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
56{
57 stmmac_task.private_data = dev;
58 stmmac_task.func = stmmac_timer_handler;
59
60 stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
61 if (stmmac_rtc == NULL) {
62 pr_err("open rtc device failed\n");
63 return -ENODEV;
64 }
65
66 rtc_irq_register(stmmac_rtc, &stmmac_task);
67
68 /* Periodic mode is not supported */
69 if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
70 pr_err("set periodic failed\n");
71 rtc_irq_unregister(stmmac_rtc, &stmmac_task);
72 rtc_class_close(stmmac_rtc);
73 return -1;
74 }
75
76 STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
77
78 tm->timer_start = stmmac_rtc_start;
79 tm->timer_stop = stmmac_rtc_stop;
80
81 return 0;
82}
83
84int stmmac_close_ext_timer(void)
85{
86 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
87 rtc_irq_unregister(stmmac_rtc, &stmmac_task);
88 rtc_class_close(stmmac_rtc);
89 return 0;
90}
91
92#elif defined(CONFIG_STMMAC_TMU_TIMER)
93#include <linux/clk.h>
94#define TMU_CHANNEL "tmu2_clk"
95static struct clk *timer_clock;
96
97static void stmmac_tmu_start(unsigned int new_freq)
98{
99 clk_set_rate(timer_clock, new_freq);
100 clk_enable(timer_clock);
101}
102
103static void stmmac_tmu_stop(void)
104{
105 clk_disable(timer_clock);
106}
107
108int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
109{
110 timer_clock = clk_get(NULL, TMU_CHANNEL);
111
112 if (timer_clock == NULL)
113 return -1;
114
115 if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
116 timer_clock = NULL;
117 return -1;
118 }
119
120 STMMAC_TIMER_MSG("TMU2", tm->freq);
121 tm->timer_start = stmmac_tmu_start;
122 tm->timer_stop = stmmac_tmu_stop;
123
124 return 0;
125}
126
127int stmmac_close_ext_timer(void)
128{
129 clk_disable(timer_clock);
130 tmu2_unregister_user();
131 clk_put(timer_clock);
132 return 0;
133}
134#endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h
new file mode 100644
index 000000000000..6863590d184b
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h
@@ -0,0 +1,42 @@
1/*******************************************************************************
2 STMMAC external timer Header File.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25struct stmmac_timer {
26 void (*timer_start) (unsigned int new_freq);
27 void (*timer_stop) (void);
28 unsigned int freq;
29 unsigned int enable;
30};
31
32/* Open the HW timer device and return 0 in case of success */
33int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
34/* Stop the timer and release it */
35int stmmac_close_ext_timer(void);
36/* Function used for scheduling task within the stmmac */
37void stmmac_schedule(struct net_device *dev);
38
39#if defined(CONFIG_STMMAC_TMU_TIMER)
40extern int tmu2_register_user(void *fnt, void *data);
41extern void tmu2_unregister_user(void);
42#endif