aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/stmmac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/stmmac')
-rw-r--r--drivers/net/stmmac/Makefile2
-rw-r--r--drivers/net/stmmac/common.h21
-rw-r--r--drivers/net/stmmac/dwmac100.c538
-rw-r--r--drivers/net/stmmac/dwmac100.h5
-rw-r--r--drivers/net/stmmac/dwmac1000.h12
-rw-r--r--drivers/net/stmmac/dwmac1000_core.c41
-rw-r--r--drivers/net/stmmac/dwmac1000_dma.c338
-rw-r--r--drivers/net/stmmac/dwmac100_core.c196
-rw-r--r--drivers/net/stmmac/dwmac100_dma.c134
-rw-r--r--drivers/net/stmmac/dwmac_dma.h1
-rw-r--r--drivers/net/stmmac/dwmac_lib.c19
-rw-r--r--drivers/net/stmmac/enh_desc.c337
-rw-r--r--drivers/net/stmmac/norm_desc.c236
-rw-r--r--drivers/net/stmmac/stmmac.h10
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c7
-rw-r--r--drivers/net/stmmac/stmmac_main.c32
-rw-r--r--drivers/net/stmmac/stmmac_timer.c6
17 files changed, 970 insertions, 965 deletions
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
index c776af15fe1a..9691733ddb8e 100644
--- a/drivers/net/stmmac/Makefile
+++ b/drivers/net/stmmac/Makefile
@@ -2,4 +2,4 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o 2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \ 3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ 4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
5 dwmac100.o $(stmmac-y) 5 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 2a58172e986a..144f76fd3e39 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -22,8 +22,26 @@
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/ 23*******************************************************************************/
24 24
25#include "descs.h"
26#include <linux/netdevice.h> 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 */
27 45
28struct stmmac_extra_stats { 46struct stmmac_extra_stats {
29 /* Transmit errors */ 47 /* Transmit errors */
@@ -231,3 +249,4 @@ extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
231 unsigned int high, unsigned int low); 249 unsigned int high, unsigned int low);
232extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr, 250extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
233 unsigned int high, unsigned int low); 251 unsigned int high, unsigned int low);
252extern void dwmac_dma_flush_tx_fifo(unsigned long ioaddr);
diff --git a/drivers/net/stmmac/dwmac100.c b/drivers/net/stmmac/dwmac100.c
deleted file mode 100644
index 4cacca614fc1..000000000000
--- a/drivers/net/stmmac/dwmac100.c
+++ /dev/null
@@ -1,538 +0,0 @@
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 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/mii.h>
31#include <linux/phy.h>
32#include <linux/slab.h>
33
34#include "common.h"
35#include "dwmac100.h"
36#include "dwmac_dma.h"
37
38#undef DWMAC100_DEBUG
39/*#define DWMAC100_DEBUG*/
40#ifdef DWMAC100_DEBUG
41#define DBG(fmt, args...) printk(fmt, ## args)
42#else
43#define DBG(fmt, args...) do { } while (0)
44#endif
45
46static void dwmac100_core_init(unsigned long ioaddr)
47{
48 u32 value = readl(ioaddr + MAC_CONTROL);
49
50 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
51
52#ifdef STMMAC_VLAN_TAG_USED
53 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
54#endif
55 return;
56}
57
58static void dwmac100_dump_mac_regs(unsigned long ioaddr)
59{
60 pr_info("\t----------------------------------------------\n"
61 "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
62 "\t----------------------------------------------\n",
63 (unsigned int)ioaddr);
64 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
65 readl(ioaddr + MAC_CONTROL));
66 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
67 readl(ioaddr + MAC_ADDR_HIGH));
68 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
69 readl(ioaddr + MAC_ADDR_LOW));
70 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
71 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
72 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
73 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
74 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
75 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
76 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
77 readl(ioaddr + MAC_VLAN1));
78 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
79 readl(ioaddr + MAC_VLAN2));
80 pr_info("\n\tMAC management counter registers\n");
81 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
82 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
83 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
84 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
85 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
86 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
87 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
88 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
89 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
90 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
91 return;
92}
93
94static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
95 u32 dma_rx)
96{
97 u32 value = readl(ioaddr + DMA_BUS_MODE);
98 /* DMA SW reset */
99 value |= DMA_BUS_MODE_SFT_RESET;
100 writel(value, ioaddr + DMA_BUS_MODE);
101 do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
102
103 /* Enable Application Access by writing to DMA CSR0 */
104 writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
105 ioaddr + DMA_BUS_MODE);
106
107 /* Mask interrupts by writing to CSR7 */
108 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
109
110 /* The base address of the RX/TX descriptor lists must be written into
111 * DMA CSR3 and CSR4, respectively. */
112 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
113 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
114
115 return 0;
116}
117
118/* Store and Forward capability is not used at all..
119 * The transmit threshold can be programmed by
120 * setting the TTC bits in the DMA control register.*/
121static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
122 int rxmode)
123{
124 u32 csr6 = readl(ioaddr + DMA_CONTROL);
125
126 if (txmode <= 32)
127 csr6 |= DMA_CONTROL_TTC_32;
128 else if (txmode <= 64)
129 csr6 |= DMA_CONTROL_TTC_64;
130 else
131 csr6 |= DMA_CONTROL_TTC_128;
132
133 writel(csr6, ioaddr + DMA_CONTROL);
134
135 return;
136}
137
138static void dwmac100_dump_dma_regs(unsigned long ioaddr)
139{
140 int i;
141
142 DBG(KERN_DEBUG "DWMAC 100 DMA CSR \n");
143 for (i = 0; i < 9; i++)
144 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
145 (DMA_BUS_MODE + i * 4),
146 readl(ioaddr + DMA_BUS_MODE + i * 4));
147 DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
148 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
149 DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
150 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
151 return;
152}
153
154/* DMA controller has two counters to track the number of
155 * the receive missed frames. */
156static void dwmac100_dma_diagnostic_fr(void *data,
157 struct stmmac_extra_stats *x,
158 unsigned long ioaddr)
159{
160 struct net_device_stats *stats = (struct net_device_stats *)data;
161 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
162
163 if (unlikely(csr8)) {
164 if (csr8 & DMA_MISSED_FRAME_OVE) {
165 stats->rx_over_errors += 0x800;
166 x->rx_overflow_cntr += 0x800;
167 } else {
168 unsigned int ove_cntr;
169 ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
170 stats->rx_over_errors += ove_cntr;
171 x->rx_overflow_cntr += ove_cntr;
172 }
173
174 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
175 stats->rx_missed_errors += 0xffff;
176 x->rx_missed_cntr += 0xffff;
177 } else {
178 unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
179 stats->rx_missed_errors += miss_f;
180 x->rx_missed_cntr += miss_f;
181 }
182 }
183 return;
184}
185
186static int dwmac100_get_tx_frame_status(void *data,
187 struct stmmac_extra_stats *x,
188 struct dma_desc *p, unsigned long ioaddr)
189{
190 int ret = 0;
191 struct net_device_stats *stats = (struct net_device_stats *)data;
192
193 if (unlikely(p->des01.tx.error_summary)) {
194 if (unlikely(p->des01.tx.underflow_error)) {
195 x->tx_underflow++;
196 stats->tx_fifo_errors++;
197 }
198 if (unlikely(p->des01.tx.no_carrier)) {
199 x->tx_carrier++;
200 stats->tx_carrier_errors++;
201 }
202 if (unlikely(p->des01.tx.loss_carrier)) {
203 x->tx_losscarrier++;
204 stats->tx_carrier_errors++;
205 }
206 if (unlikely((p->des01.tx.excessive_deferral) ||
207 (p->des01.tx.excessive_collisions) ||
208 (p->des01.tx.late_collision)))
209 stats->collisions += p->des01.tx.collision_count;
210 ret = -1;
211 }
212 if (unlikely(p->des01.tx.heartbeat_fail)) {
213 x->tx_heartbeat++;
214 stats->tx_heartbeat_errors++;
215 ret = -1;
216 }
217 if (unlikely(p->des01.tx.deferred))
218 x->tx_deferred++;
219
220 return ret;
221}
222
223static int dwmac100_get_tx_len(struct dma_desc *p)
224{
225 return p->des01.tx.buffer1_size;
226}
227
228/* This function verifies if each incoming frame has some errors
229 * and, if required, updates the multicast statistics.
230 * In case of success, it returns csum_none becasue the device
231 * is not able to compute the csum in HW. */
232static int dwmac100_get_rx_frame_status(void *data,
233 struct stmmac_extra_stats *x,
234 struct dma_desc *p)
235{
236 int ret = csum_none;
237 struct net_device_stats *stats = (struct net_device_stats *)data;
238
239 if (unlikely(p->des01.rx.last_descriptor == 0)) {
240 pr_warning("dwmac100 Error: Oversized Ethernet "
241 "frame spanned multiple buffers\n");
242 stats->rx_length_errors++;
243 return discard_frame;
244 }
245
246 if (unlikely(p->des01.rx.error_summary)) {
247 if (unlikely(p->des01.rx.descriptor_error))
248 x->rx_desc++;
249 if (unlikely(p->des01.rx.partial_frame_error))
250 x->rx_partial++;
251 if (unlikely(p->des01.rx.run_frame))
252 x->rx_runt++;
253 if (unlikely(p->des01.rx.frame_too_long))
254 x->rx_toolong++;
255 if (unlikely(p->des01.rx.collision)) {
256 x->rx_collision++;
257 stats->collisions++;
258 }
259 if (unlikely(p->des01.rx.crc_error)) {
260 x->rx_crc++;
261 stats->rx_crc_errors++;
262 }
263 ret = discard_frame;
264 }
265 if (unlikely(p->des01.rx.dribbling))
266 ret = discard_frame;
267
268 if (unlikely(p->des01.rx.length_error)) {
269 x->rx_length++;
270 ret = discard_frame;
271 }
272 if (unlikely(p->des01.rx.mii_error)) {
273 x->rx_mii++;
274 ret = discard_frame;
275 }
276 if (p->des01.rx.multicast_frame) {
277 x->rx_multicast++;
278 stats->multicast++;
279 }
280 return ret;
281}
282
283static void dwmac100_irq_status(unsigned long ioaddr)
284{
285 return;
286}
287
288static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
289 unsigned int reg_n)
290{
291 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
292}
293
294static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
295 unsigned int reg_n)
296{
297 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
298}
299
300static void dwmac100_set_filter(struct net_device *dev)
301{
302 unsigned long ioaddr = dev->base_addr;
303 u32 value = readl(ioaddr + MAC_CONTROL);
304
305 if (dev->flags & IFF_PROMISC) {
306 value |= MAC_CONTROL_PR;
307 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
308 MAC_CONTROL_HP);
309 } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
310 || (dev->flags & IFF_ALLMULTI)) {
311 value |= MAC_CONTROL_PM;
312 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
313 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
314 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
315 } else if (netdev_mc_empty(dev)) { /* no multicast */
316 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
317 MAC_CONTROL_HO | MAC_CONTROL_HP);
318 } else {
319 u32 mc_filter[2];
320 struct dev_mc_list *mclist;
321
322 /* Perfect filter mode for physical address and Hash
323 filter for multicast */
324 value |= MAC_CONTROL_HP;
325 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
326 MAC_CONTROL_IF | MAC_CONTROL_HO);
327
328 memset(mc_filter, 0, sizeof(mc_filter));
329 netdev_for_each_mc_addr(mclist, dev) {
330 /* The upper 6 bits of the calculated CRC are used to
331 * index the contens of the hash table */
332 int bit_nr =
333 ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
334 /* The most significant bit determines the register to
335 * use (H/L) while the other 5 bits determine the bit
336 * within the register. */
337 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
338 }
339 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
340 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
341 }
342
343 writel(value, ioaddr + MAC_CONTROL);
344
345 DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
346 "HI 0x%08x, LO 0x%08x\n",
347 __func__, readl(ioaddr + MAC_CONTROL),
348 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
349 return;
350}
351
352static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
353 unsigned int fc, unsigned int pause_time)
354{
355 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
356
357 if (duplex)
358 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
359 writel(flow, ioaddr + MAC_FLOW_CTRL);
360
361 return;
362}
363
364/* No PMT module supported for this Ethernet Controller.
365 * Tested on ST platforms only.
366 */
367static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
368{
369 return;
370}
371
372static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
373 int disable_rx_ic)
374{
375 int i;
376 for (i = 0; i < ring_size; i++) {
377 p->des01.rx.own = 1;
378 p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
379 if (i == ring_size - 1)
380 p->des01.rx.end_ring = 1;
381 if (disable_rx_ic)
382 p->des01.rx.disable_ic = 1;
383 p++;
384 }
385 return;
386}
387
388static void dwmac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
389{
390 int i;
391 for (i = 0; i < ring_size; i++) {
392 p->des01.tx.own = 0;
393 if (i == ring_size - 1)
394 p->des01.tx.end_ring = 1;
395 p++;
396 }
397 return;
398}
399
400static int dwmac100_get_tx_owner(struct dma_desc *p)
401{
402 return p->des01.tx.own;
403}
404
405static int dwmac100_get_rx_owner(struct dma_desc *p)
406{
407 return p->des01.rx.own;
408}
409
410static void dwmac100_set_tx_owner(struct dma_desc *p)
411{
412 p->des01.tx.own = 1;
413}
414
415static void dwmac100_set_rx_owner(struct dma_desc *p)
416{
417 p->des01.rx.own = 1;
418}
419
420static int dwmac100_get_tx_ls(struct dma_desc *p)
421{
422 return p->des01.tx.last_segment;
423}
424
425static void dwmac100_release_tx_desc(struct dma_desc *p)
426{
427 int ter = p->des01.tx.end_ring;
428
429 /* clean field used within the xmit */
430 p->des01.tx.first_segment = 0;
431 p->des01.tx.last_segment = 0;
432 p->des01.tx.buffer1_size = 0;
433
434 /* clean status reported */
435 p->des01.tx.error_summary = 0;
436 p->des01.tx.underflow_error = 0;
437 p->des01.tx.no_carrier = 0;
438 p->des01.tx.loss_carrier = 0;
439 p->des01.tx.excessive_deferral = 0;
440 p->des01.tx.excessive_collisions = 0;
441 p->des01.tx.late_collision = 0;
442 p->des01.tx.heartbeat_fail = 0;
443 p->des01.tx.deferred = 0;
444
445 /* set termination field */
446 p->des01.tx.end_ring = ter;
447
448 return;
449}
450
451static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
452 int csum_flag)
453{
454 p->des01.tx.first_segment = is_fs;
455 p->des01.tx.buffer1_size = len;
456}
457
458static void dwmac100_clear_tx_ic(struct dma_desc *p)
459{
460 p->des01.tx.interrupt = 0;
461}
462
463static void dwmac100_close_tx_desc(struct dma_desc *p)
464{
465 p->des01.tx.last_segment = 1;
466 p->des01.tx.interrupt = 1;
467}
468
469static int dwmac100_get_rx_frame_len(struct dma_desc *p)
470{
471 return p->des01.rx.frame_length;
472}
473
474struct stmmac_ops dwmac100_ops = {
475 .core_init = dwmac100_core_init,
476 .dump_regs = dwmac100_dump_mac_regs,
477 .host_irq_status = dwmac100_irq_status,
478 .set_filter = dwmac100_set_filter,
479 .flow_ctrl = dwmac100_flow_ctrl,
480 .pmt = dwmac100_pmt,
481 .set_umac_addr = dwmac100_set_umac_addr,
482 .get_umac_addr = dwmac100_get_umac_addr,
483};
484
485struct stmmac_dma_ops dwmac100_dma_ops = {
486 .init = dwmac100_dma_init,
487 .dump_regs = dwmac100_dump_dma_regs,
488 .dma_mode = dwmac100_dma_operation_mode,
489 .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
490 .enable_dma_transmission = dwmac_enable_dma_transmission,
491 .enable_dma_irq = dwmac_enable_dma_irq,
492 .disable_dma_irq = dwmac_disable_dma_irq,
493 .start_tx = dwmac_dma_start_tx,
494 .stop_tx = dwmac_dma_stop_tx,
495 .start_rx = dwmac_dma_start_rx,
496 .stop_rx = dwmac_dma_stop_rx,
497 .dma_interrupt = dwmac_dma_interrupt,
498};
499
500struct stmmac_desc_ops dwmac100_desc_ops = {
501 .tx_status = dwmac100_get_tx_frame_status,
502 .rx_status = dwmac100_get_rx_frame_status,
503 .get_tx_len = dwmac100_get_tx_len,
504 .init_rx_desc = dwmac100_init_rx_desc,
505 .init_tx_desc = dwmac100_init_tx_desc,
506 .get_tx_owner = dwmac100_get_tx_owner,
507 .get_rx_owner = dwmac100_get_rx_owner,
508 .release_tx_desc = dwmac100_release_tx_desc,
509 .prepare_tx_desc = dwmac100_prepare_tx_desc,
510 .clear_tx_ic = dwmac100_clear_tx_ic,
511 .close_tx_desc = dwmac100_close_tx_desc,
512 .get_tx_ls = dwmac100_get_tx_ls,
513 .set_tx_owner = dwmac100_set_tx_owner,
514 .set_rx_owner = dwmac100_set_rx_owner,
515 .get_rx_frame_len = dwmac100_get_rx_frame_len,
516};
517
518struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
519{
520 struct mac_device_info *mac;
521
522 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
523
524 pr_info("\tDWMAC100\n");
525
526 mac->mac = &dwmac100_ops;
527 mac->desc = &dwmac100_desc_ops;
528 mac->dma = &dwmac100_dma_ops;
529
530 mac->pmt = PMT_NOT_SUPPORTED;
531 mac->link.port = MAC_CONTROL_PS;
532 mac->link.duplex = MAC_CONTROL_F;
533 mac->link.speed = 0;
534 mac->mii.addr = MAC_MII_ADDR;
535 mac->mii.data = MAC_MII_DATA;
536
537 return mac;
538}
diff --git a/drivers/net/stmmac/dwmac100.h b/drivers/net/stmmac/dwmac100.h
index 0f8f110d004a..97956cbf1cb4 100644
--- a/drivers/net/stmmac/dwmac100.h
+++ b/drivers/net/stmmac/dwmac100.h
@@ -22,6 +22,9 @@
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/ 23*******************************************************************************/
24 24
25#include <linux/phy.h>
26#include "common.h"
27
25/*---------------------------------------------------------------------------- 28/*----------------------------------------------------------------------------
26 * MAC BLOCK defines 29 * MAC BLOCK defines
27 *---------------------------------------------------------------------------*/ 30 *---------------------------------------------------------------------------*/
@@ -114,3 +117,5 @@ enum ttc_control {
114#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */ 117#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */
115#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */ 118#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */
116#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ 119#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */
120
121extern struct stmmac_dma_ops dwmac100_dma_ops;
diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h
index 62dca0e384e7..d8d0f3553770 100644
--- a/drivers/net/stmmac/dwmac1000.h
+++ b/drivers/net/stmmac/dwmac1000.h
@@ -172,7 +172,6 @@ enum rfd {
172 deac_full_minus_4 = 0x00401800, 172 deac_full_minus_4 = 0x00401800,
173}; 173};
174#define DMA_CONTROL_TSF 0x00200000 /* Transmit Store and Forward */ 174#define DMA_CONTROL_TSF 0x00200000 /* Transmit Store and Forward */
175#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
176 175
177enum ttc_control { 176enum ttc_control {
178 DMA_CONTROL_TTC_64 = 0x00000000, 177 DMA_CONTROL_TTC_64 = 0x00000000,
@@ -206,15 +205,4 @@ enum rtc_control {
206#define GMAC_MMC_TX_INTR 0x108 205#define GMAC_MMC_TX_INTR 0x108
207#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 206#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
208 207
209#undef DWMAC1000_DEBUG
210/* #define DWMAC1000__DEBUG */
211#undef FRAME_FILTER_DEBUG
212/* #define FRAME_FILTER_DEBUG */
213#ifdef DWMAC1000__DEBUG
214#define DBG(fmt, args...) printk(fmt, ## args)
215#else
216#define DBG(fmt, args...) do { } while (0)
217#endif
218
219extern struct stmmac_dma_ops dwmac1000_dma_ops; 208extern struct stmmac_dma_ops dwmac1000_dma_ops;
220extern struct stmmac_desc_ops dwmac1000_desc_ops;
diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c
index 5bd95ebfe498..917b4e16923b 100644
--- a/drivers/net/stmmac/dwmac1000_core.c
+++ b/drivers/net/stmmac/dwmac1000_core.c
@@ -48,7 +48,6 @@ static void dwmac1000_core_init(unsigned long ioaddr)
48 /* Tag detection without filtering */ 48 /* Tag detection without filtering */
49 writel(0x0, ioaddr + GMAC_VLAN_TAG); 49 writel(0x0, ioaddr + GMAC_VLAN_TAG);
50#endif 50#endif
51 return;
52} 51}
53 52
54static void dwmac1000_dump_regs(unsigned long ioaddr) 53static void dwmac1000_dump_regs(unsigned long ioaddr)
@@ -61,7 +60,6 @@ static void dwmac1000_dump_regs(unsigned long ioaddr)
61 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i, 60 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
62 offset, readl(ioaddr + offset)); 61 offset, readl(ioaddr + offset));
63 } 62 }
64 return;
65} 63}
66 64
67static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr, 65static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
@@ -83,8 +81,8 @@ static void dwmac1000_set_filter(struct net_device *dev)
83 unsigned long ioaddr = dev->base_addr; 81 unsigned long ioaddr = dev->base_addr;
84 unsigned int value = 0; 82 unsigned int value = 0;
85 83
86 DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n", 84 CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
87 __func__, netdev_mc_count(dev), netdev_uc_count(dev)); 85 __func__, netdev_mc_count(dev), netdev_uc_count(dev));
88 86
89 if (dev->flags & IFF_PROMISC) 87 if (dev->flags & IFF_PROMISC)
90 value = GMAC_FRAME_FILTER_PR; 88 value = GMAC_FRAME_FILTER_PR;
@@ -95,17 +93,17 @@ static void dwmac1000_set_filter(struct net_device *dev)
95 writel(0xffffffff, ioaddr + GMAC_HASH_LOW); 93 writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
96 } else if (!netdev_mc_empty(dev)) { 94 } else if (!netdev_mc_empty(dev)) {
97 u32 mc_filter[2]; 95 u32 mc_filter[2];
98 struct dev_mc_list *mclist; 96 struct netdev_hw_addr *ha;
99 97
100 /* Hash filter for multicast */ 98 /* Hash filter for multicast */
101 value = GMAC_FRAME_FILTER_HMC; 99 value = GMAC_FRAME_FILTER_HMC;
102 100
103 memset(mc_filter, 0, sizeof(mc_filter)); 101 memset(mc_filter, 0, sizeof(mc_filter));
104 netdev_for_each_mc_addr(mclist, dev) { 102 netdev_for_each_mc_addr(ha, dev) {
105 /* The upper 6 bits of the calculated CRC are used to 103 /* The upper 6 bits of the calculated CRC are used to
106 index the contens of the hash table */ 104 index the contens of the hash table */
107 int bit_nr = 105 int bit_nr =
108 bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26; 106 bitrev32(~crc32_le(~0, ha->addr, 6)) >> 26;
109 /* The most significant bit determines the register to 107 /* The most significant bit determines the register to
110 * use (H/L) while the other 5 bits determine the bit 108 * use (H/L) while the other 5 bits determine the bit
111 * within the register. */ 109 * within the register. */
@@ -136,11 +134,9 @@ static void dwmac1000_set_filter(struct net_device *dev)
136#endif 134#endif
137 writel(value, ioaddr + GMAC_FRAME_FILTER); 135 writel(value, ioaddr + GMAC_FRAME_FILTER);
138 136
139 DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: " 137 CHIP_DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
140 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER), 138 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
141 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW)); 139 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
142
143 return;
144} 140}
145 141
146static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex, 142static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
@@ -148,23 +144,22 @@ static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
148{ 144{
149 unsigned int flow = 0; 145 unsigned int flow = 0;
150 146
151 DBG(KERN_DEBUG "GMAC Flow-Control:\n"); 147 CHIP_DBG(KERN_DEBUG "GMAC Flow-Control:\n");
152 if (fc & FLOW_RX) { 148 if (fc & FLOW_RX) {
153 DBG(KERN_DEBUG "\tReceive Flow-Control ON\n"); 149 CHIP_DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
154 flow |= GMAC_FLOW_CTRL_RFE; 150 flow |= GMAC_FLOW_CTRL_RFE;
155 } 151 }
156 if (fc & FLOW_TX) { 152 if (fc & FLOW_TX) {
157 DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n"); 153 CHIP_DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
158 flow |= GMAC_FLOW_CTRL_TFE; 154 flow |= GMAC_FLOW_CTRL_TFE;
159 } 155 }
160 156
161 if (duplex) { 157 if (duplex) {
162 DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time); 158 CHIP_DBG(KERN_DEBUG "\tduplex mode: PAUSE %d\n", pause_time);
163 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT); 159 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
164 } 160 }
165 161
166 writel(flow, ioaddr + GMAC_FLOW_CTRL); 162 writel(flow, ioaddr + GMAC_FLOW_CTRL);
167 return;
168} 163}
169 164
170static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode) 165static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
@@ -172,15 +167,14 @@ static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode)
172 unsigned int pmt = 0; 167 unsigned int pmt = 0;
173 168
174 if (mode == WAKE_MAGIC) { 169 if (mode == WAKE_MAGIC) {
175 DBG(KERN_DEBUG "GMAC: WOL Magic frame\n"); 170 CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
176 pmt |= power_down | magic_pkt_en; 171 pmt |= power_down | magic_pkt_en;
177 } else if (mode == WAKE_UCAST) { 172 } else if (mode == WAKE_UCAST) {
178 DBG(KERN_DEBUG "GMAC: WOL on global unicast\n"); 173 CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
179 pmt |= global_unicast; 174 pmt |= global_unicast;
180 } 175 }
181 176
182 writel(pmt, ioaddr + GMAC_PMT); 177 writel(pmt, ioaddr + GMAC_PMT);
183 return;
184} 178}
185 179
186 180
@@ -190,22 +184,20 @@ static void dwmac1000_irq_status(unsigned long ioaddr)
190 184
191 /* Not used events (e.g. MMC interrupts) are not handled. */ 185 /* Not used events (e.g. MMC interrupts) are not handled. */
192 if ((intr_status & mmc_tx_irq)) 186 if ((intr_status & mmc_tx_irq))
193 DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n", 187 CHIP_DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
194 readl(ioaddr + GMAC_MMC_TX_INTR)); 188 readl(ioaddr + GMAC_MMC_TX_INTR));
195 if (unlikely(intr_status & mmc_rx_irq)) 189 if (unlikely(intr_status & mmc_rx_irq))
196 DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n", 190 CHIP_DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
197 readl(ioaddr + GMAC_MMC_RX_INTR)); 191 readl(ioaddr + GMAC_MMC_RX_INTR));
198 if (unlikely(intr_status & mmc_rx_csum_offload_irq)) 192 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
199 DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n", 193 CHIP_DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
200 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD)); 194 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
201 if (unlikely(intr_status & pmt_irq)) { 195 if (unlikely(intr_status & pmt_irq)) {
202 DBG(KERN_DEBUG "GMAC: received Magic frame\n"); 196 CHIP_DBG(KERN_DEBUG "GMAC: received Magic frame\n");
203 /* clear the PMT bits 5 and 6 by reading the PMT 197 /* clear the PMT bits 5 and 6 by reading the PMT
204 * status register. */ 198 * status register. */
205 readl(ioaddr + GMAC_PMT); 199 readl(ioaddr + GMAC_PMT);
206 } 200 }
207
208 return;
209} 201}
210 202
211struct stmmac_ops dwmac1000_ops = { 203struct stmmac_ops dwmac1000_ops = {
@@ -230,7 +222,6 @@ struct mac_device_info *dwmac1000_setup(unsigned long ioaddr)
230 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL); 222 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
231 223
232 mac->mac = &dwmac1000_ops; 224 mac->mac = &dwmac1000_ops;
233 mac->desc = &dwmac1000_desc_ops;
234 mac->dma = &dwmac1000_dma_ops; 225 mac->dma = &dwmac1000_dma_ops;
235 226
236 mac->pmt = PMT_SUPPORTED; 227 mac->pmt = PMT_SUPPORTED;
diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c
index 39d436a2da68..415805057cb0 100644
--- a/drivers/net/stmmac/dwmac1000_dma.c
+++ b/drivers/net/stmmac/dwmac1000_dma.c
@@ -3,7 +3,7 @@
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for 3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code. 4 developing this code.
5 5
6 This contains the functions to handle the dma and descriptors. 6 This contains the functions to handle the dma.
7 7
8 Copyright (C) 2007-2009 STMicroelectronics Ltd 8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9 9
@@ -58,29 +58,20 @@ static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
58 return 0; 58 return 0;
59} 59}
60 60
61/* Transmit FIFO flush operation */
62static void dwmac1000_flush_tx_fifo(unsigned long ioaddr)
63{
64 u32 csr6 = readl(ioaddr + DMA_CONTROL);
65 writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
66
67 do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
68}
69
70static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode, 61static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
71 int rxmode) 62 int rxmode)
72{ 63{
73 u32 csr6 = readl(ioaddr + DMA_CONTROL); 64 u32 csr6 = readl(ioaddr + DMA_CONTROL);
74 65
75 if (txmode == SF_DMA_MODE) { 66 if (txmode == SF_DMA_MODE) {
76 DBG(KERN_DEBUG "GMAC: enabling TX store and forward mode\n"); 67 CHIP_DBG(KERN_DEBUG "GMAC: enable TX store and forward mode\n");
77 /* Transmit COE type 2 cannot be done in cut-through mode. */ 68 /* Transmit COE type 2 cannot be done in cut-through mode. */
78 csr6 |= DMA_CONTROL_TSF; 69 csr6 |= DMA_CONTROL_TSF;
79 /* Operating on second frame increase the performance 70 /* Operating on second frame increase the performance
80 * especially when transmit store-and-forward is used.*/ 71 * especially when transmit store-and-forward is used.*/
81 csr6 |= DMA_CONTROL_OSF; 72 csr6 |= DMA_CONTROL_OSF;
82 } else { 73 } else {
83 DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode" 74 CHIP_DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
84 " (threshold = %d)\n", txmode); 75 " (threshold = %d)\n", txmode);
85 csr6 &= ~DMA_CONTROL_TSF; 76 csr6 &= ~DMA_CONTROL_TSF;
86 csr6 &= DMA_CONTROL_TC_TX_MASK; 77 csr6 &= DMA_CONTROL_TC_TX_MASK;
@@ -98,10 +89,10 @@ static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
98 } 89 }
99 90
100 if (rxmode == SF_DMA_MODE) { 91 if (rxmode == SF_DMA_MODE) {
101 DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n"); 92 CHIP_DBG(KERN_DEBUG "GMAC: enable RX store and forward mode\n");
102 csr6 |= DMA_CONTROL_RSF; 93 csr6 |= DMA_CONTROL_RSF;
103 } else { 94 } else {
104 DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode" 95 CHIP_DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
105 " (threshold = %d)\n", rxmode); 96 " (threshold = %d)\n", rxmode);
106 csr6 &= ~DMA_CONTROL_RSF; 97 csr6 &= ~DMA_CONTROL_RSF;
107 csr6 &= DMA_CONTROL_TC_RX_MASK; 98 csr6 &= DMA_CONTROL_TC_RX_MASK;
@@ -116,7 +107,6 @@ static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
116 } 107 }
117 108
118 writel(csr6, ioaddr + DMA_CONTROL); 109 writel(csr6, ioaddr + DMA_CONTROL);
119 return;
120} 110}
121 111
122/* Not yet implemented --- no RMON module */ 112/* Not yet implemented --- no RMON module */
@@ -138,306 +128,6 @@ static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
138 readl(ioaddr + DMA_BUS_MODE + offset)); 128 readl(ioaddr + DMA_BUS_MODE + offset));
139 } 129 }
140 } 130 }
141 return;
142}
143
144static int dwmac1000_get_tx_frame_status(void *data,
145 struct stmmac_extra_stats *x,
146 struct dma_desc *p, unsigned long ioaddr)
147{
148 int ret = 0;
149 struct net_device_stats *stats = (struct net_device_stats *)data;
150
151 if (unlikely(p->des01.etx.error_summary)) {
152 DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
153 if (unlikely(p->des01.etx.jabber_timeout)) {
154 DBG(KERN_ERR "\tjabber_timeout error\n");
155 x->tx_jabber++;
156 }
157
158 if (unlikely(p->des01.etx.frame_flushed)) {
159 DBG(KERN_ERR "\tframe_flushed error\n");
160 x->tx_frame_flushed++;
161 dwmac1000_flush_tx_fifo(ioaddr);
162 }
163
164 if (unlikely(p->des01.etx.loss_carrier)) {
165 DBG(KERN_ERR "\tloss_carrier error\n");
166 x->tx_losscarrier++;
167 stats->tx_carrier_errors++;
168 }
169 if (unlikely(p->des01.etx.no_carrier)) {
170 DBG(KERN_ERR "\tno_carrier error\n");
171 x->tx_carrier++;
172 stats->tx_carrier_errors++;
173 }
174 if (unlikely(p->des01.etx.late_collision)) {
175 DBG(KERN_ERR "\tlate_collision error\n");
176 stats->collisions += p->des01.etx.collision_count;
177 }
178 if (unlikely(p->des01.etx.excessive_collisions)) {
179 DBG(KERN_ERR "\texcessive_collisions\n");
180 stats->collisions += p->des01.etx.collision_count;
181 }
182 if (unlikely(p->des01.etx.excessive_deferral)) {
183 DBG(KERN_INFO "\texcessive tx_deferral\n");
184 x->tx_deferred++;
185 }
186
187 if (unlikely(p->des01.etx.underflow_error)) {
188 DBG(KERN_ERR "\tunderflow error\n");
189 dwmac1000_flush_tx_fifo(ioaddr);
190 x->tx_underflow++;
191 }
192
193 if (unlikely(p->des01.etx.ip_header_error)) {
194 DBG(KERN_ERR "\tTX IP header csum error\n");
195 x->tx_ip_header_error++;
196 }
197
198 if (unlikely(p->des01.etx.payload_error)) {
199 DBG(KERN_ERR "\tAddr/Payload csum error\n");
200 x->tx_payload_error++;
201 dwmac1000_flush_tx_fifo(ioaddr);
202 }
203
204 ret = -1;
205 }
206
207 if (unlikely(p->des01.etx.deferred)) {
208 DBG(KERN_INFO "GMAC TX status: tx deferred\n");
209 x->tx_deferred++;
210 }
211#ifdef STMMAC_VLAN_TAG_USED
212 if (p->des01.etx.vlan_frame) {
213 DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
214 x->tx_vlan++;
215 }
216#endif
217
218 return ret;
219}
220
221static int dwmac1000_get_tx_len(struct dma_desc *p)
222{
223 return p->des01.etx.buffer1_size;
224}
225
226static int dwmac1000_coe_rdes0(int ipc_err, int type, int payload_err)
227{
228 int ret = good_frame;
229 u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
230
231 /* bits 5 7 0 | Frame status
232 * ----------------------------------------------------------
233 * 0 0 0 | IEEE 802.3 Type frame (length < 1536 octects)
234 * 1 0 0 | IPv4/6 No CSUM errorS.
235 * 1 0 1 | IPv4/6 CSUM PAYLOAD error
236 * 1 1 0 | IPv4/6 CSUM IP HR error
237 * 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
238 * 0 0 1 | IPv4/6 unsupported IP PAYLOAD
239 * 0 1 1 | COE bypassed.. no IPv4/6 frame
240 * 0 1 0 | Reserved.
241 */
242 if (status == 0x0) {
243 DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
244 ret = good_frame;
245 } else if (status == 0x4) {
246 DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
247 ret = good_frame;
248 } else if (status == 0x5) {
249 DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
250 ret = csum_none;
251 } else if (status == 0x6) {
252 DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
253 ret = csum_none;
254 } else if (status == 0x7) {
255 DBG(KERN_ERR
256 "RX Des0 status: IPv4/6 Header and Payload Error.\n");
257 ret = csum_none;
258 } else if (status == 0x1) {
259 DBG(KERN_ERR
260 "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
261 ret = discard_frame;
262 } else if (status == 0x3) {
263 DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
264 ret = discard_frame;
265 }
266 return ret;
267}
268
269static int dwmac1000_get_rx_frame_status(void *data,
270 struct stmmac_extra_stats *x, struct dma_desc *p)
271{
272 int ret = good_frame;
273 struct net_device_stats *stats = (struct net_device_stats *)data;
274
275 if (unlikely(p->des01.erx.error_summary)) {
276 DBG(KERN_ERR "GMAC RX Error Summary... 0x%08x\n", p->des01.erx);
277 if (unlikely(p->des01.erx.descriptor_error)) {
278 DBG(KERN_ERR "\tdescriptor error\n");
279 x->rx_desc++;
280 stats->rx_length_errors++;
281 }
282 if (unlikely(p->des01.erx.overflow_error)) {
283 DBG(KERN_ERR "\toverflow error\n");
284 x->rx_gmac_overflow++;
285 }
286
287 if (unlikely(p->des01.erx.ipc_csum_error))
288 DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
289
290 if (unlikely(p->des01.erx.late_collision)) {
291 DBG(KERN_ERR "\tlate_collision error\n");
292 stats->collisions++;
293 stats->collisions++;
294 }
295 if (unlikely(p->des01.erx.receive_watchdog)) {
296 DBG(KERN_ERR "\treceive_watchdog error\n");
297 x->rx_watchdog++;
298 }
299 if (unlikely(p->des01.erx.error_gmii)) {
300 DBG(KERN_ERR "\tReceive Error\n");
301 x->rx_mii++;
302 }
303 if (unlikely(p->des01.erx.crc_error)) {
304 DBG(KERN_ERR "\tCRC error\n");
305 x->rx_crc++;
306 stats->rx_crc_errors++;
307 }
308 ret = discard_frame;
309 }
310
311 /* After a payload csum error, the ES bit is set.
312 * It doesn't match with the information reported into the databook.
313 * At any rate, we need to understand if the CSUM hw computation is ok
314 * and report this info to the upper layers. */
315 ret = dwmac1000_coe_rdes0(p->des01.erx.ipc_csum_error,
316 p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
317
318 if (unlikely(p->des01.erx.dribbling)) {
319 DBG(KERN_ERR "GMAC RX: dribbling error\n");
320 ret = discard_frame;
321 }
322 if (unlikely(p->des01.erx.sa_filter_fail)) {
323 DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
324 x->sa_rx_filter_fail++;
325 ret = discard_frame;
326 }
327 if (unlikely(p->des01.erx.da_filter_fail)) {
328 DBG(KERN_ERR "GMAC RX : Destination Address filter fail\n");
329 x->da_rx_filter_fail++;
330 ret = discard_frame;
331 }
332 if (unlikely(p->des01.erx.length_error)) {
333 DBG(KERN_ERR "GMAC RX: length_error error\n");
334 x->rx_length++;
335 ret = discard_frame;
336 }
337#ifdef STMMAC_VLAN_TAG_USED
338 if (p->des01.erx.vlan_tag) {
339 DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
340 x->rx_vlan++;
341 }
342#endif
343 return ret;
344}
345
346static void dwmac1000_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
347 int disable_rx_ic)
348{
349 int i;
350 for (i = 0; i < ring_size; i++) {
351 p->des01.erx.own = 1;
352 p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
353 /* To support jumbo frames */
354 p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
355 if (i == ring_size - 1)
356 p->des01.erx.end_ring = 1;
357 if (disable_rx_ic)
358 p->des01.erx.disable_ic = 1;
359 p++;
360 }
361 return;
362}
363
364static void dwmac1000_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
365{
366 int i;
367
368 for (i = 0; i < ring_size; i++) {
369 p->des01.etx.own = 0;
370 if (i == ring_size - 1)
371 p->des01.etx.end_ring = 1;
372 p++;
373 }
374
375 return;
376}
377
378static int dwmac1000_get_tx_owner(struct dma_desc *p)
379{
380 return p->des01.etx.own;
381}
382
383static int dwmac1000_get_rx_owner(struct dma_desc *p)
384{
385 return p->des01.erx.own;
386}
387
388static void dwmac1000_set_tx_owner(struct dma_desc *p)
389{
390 p->des01.etx.own = 1;
391}
392
393static void dwmac1000_set_rx_owner(struct dma_desc *p)
394{
395 p->des01.erx.own = 1;
396}
397
398static int dwmac1000_get_tx_ls(struct dma_desc *p)
399{
400 return p->des01.etx.last_segment;
401}
402
403static void dwmac1000_release_tx_desc(struct dma_desc *p)
404{
405 int ter = p->des01.etx.end_ring;
406
407 memset(p, 0, sizeof(struct dma_desc));
408 p->des01.etx.end_ring = ter;
409
410 return;
411}
412
413static void dwmac1000_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
414 int csum_flag)
415{
416 p->des01.etx.first_segment = is_fs;
417 if (unlikely(len > BUF_SIZE_4KiB)) {
418 p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
419 p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
420 } else {
421 p->des01.etx.buffer1_size = len;
422 }
423 if (likely(csum_flag))
424 p->des01.etx.checksum_insertion = cic_full;
425}
426
427static void dwmac1000_clear_tx_ic(struct dma_desc *p)
428{
429 p->des01.etx.interrupt = 0;
430}
431
432static void dwmac1000_close_tx_desc(struct dma_desc *p)
433{
434 p->des01.etx.last_segment = 1;
435 p->des01.etx.interrupt = 1;
436}
437
438static int dwmac1000_get_rx_frame_len(struct dma_desc *p)
439{
440 return p->des01.erx.frame_length;
441} 131}
442 132
443struct stmmac_dma_ops dwmac1000_dma_ops = { 133struct stmmac_dma_ops dwmac1000_dma_ops = {
@@ -454,21 +144,3 @@ struct stmmac_dma_ops dwmac1000_dma_ops = {
454 .stop_rx = dwmac_dma_stop_rx, 144 .stop_rx = dwmac_dma_stop_rx,
455 .dma_interrupt = dwmac_dma_interrupt, 145 .dma_interrupt = dwmac_dma_interrupt,
456}; 146};
457
458struct stmmac_desc_ops dwmac1000_desc_ops = {
459 .tx_status = dwmac1000_get_tx_frame_status,
460 .rx_status = dwmac1000_get_rx_frame_status,
461 .get_tx_len = dwmac1000_get_tx_len,
462 .init_rx_desc = dwmac1000_init_rx_desc,
463 .init_tx_desc = dwmac1000_init_tx_desc,
464 .get_tx_owner = dwmac1000_get_tx_owner,
465 .get_rx_owner = dwmac1000_get_rx_owner,
466 .release_tx_desc = dwmac1000_release_tx_desc,
467 .prepare_tx_desc = dwmac1000_prepare_tx_desc,
468 .clear_tx_ic = dwmac1000_clear_tx_ic,
469 .close_tx_desc = dwmac1000_close_tx_desc,
470 .get_tx_ls = dwmac1000_get_tx_ls,
471 .set_tx_owner = dwmac1000_set_tx_owner,
472 .set_rx_owner = dwmac1000_set_rx_owner,
473 .get_rx_frame_len = dwmac1000_get_rx_frame_len,
474};
diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c
new file mode 100644
index 000000000000..6f270a0e151a
--- /dev/null
+++ b/drivers/net/stmmac/dwmac100_core.c
@@ -0,0 +1,196 @@
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 "dwmac100.h"
33
34static void dwmac100_core_init(unsigned long ioaddr)
35{
36 u32 value = readl(ioaddr + MAC_CONTROL);
37
38 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
39
40#ifdef STMMAC_VLAN_TAG_USED
41 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
42#endif
43}
44
45static void dwmac100_dump_mac_regs(unsigned long ioaddr)
46{
47 pr_info("\t----------------------------------------------\n"
48 "\t DWMAC 100 CSR (base addr = 0x%8x)\n"
49 "\t----------------------------------------------\n",
50 (unsigned int)ioaddr);
51 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
52 readl(ioaddr + MAC_CONTROL));
53 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
54 readl(ioaddr + MAC_ADDR_HIGH));
55 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
56 readl(ioaddr + MAC_ADDR_LOW));
57 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
58 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
59 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
60 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
61 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
62 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
63 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
64 readl(ioaddr + MAC_VLAN1));
65 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
66 readl(ioaddr + MAC_VLAN2));
67 pr_info("\n\tMAC management counter registers\n");
68 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
69 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
70 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
71 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
72 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
73 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
74 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
75 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
76 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
77 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
78}
79
80static void dwmac100_irq_status(unsigned long ioaddr)
81{
82 return;
83}
84
85static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
86 unsigned int reg_n)
87{
88 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
89}
90
91static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
92 unsigned int reg_n)
93{
94 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
95}
96
97static void dwmac100_set_filter(struct net_device *dev)
98{
99 unsigned long ioaddr = dev->base_addr;
100 u32 value = readl(ioaddr + MAC_CONTROL);
101
102 if (dev->flags & IFF_PROMISC) {
103 value |= MAC_CONTROL_PR;
104 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
105 MAC_CONTROL_HP);
106 } else if ((netdev_mc_count(dev) > HASH_TABLE_SIZE)
107 || (dev->flags & IFF_ALLMULTI)) {
108 value |= MAC_CONTROL_PM;
109 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
110 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
111 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
112 } else if (netdev_mc_empty(dev)) { /* no multicast */
113 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
114 MAC_CONTROL_HO | MAC_CONTROL_HP);
115 } else {
116 u32 mc_filter[2];
117 struct netdev_hw_addr *ha;
118
119 /* Perfect filter mode for physical address and Hash
120 filter for multicast */
121 value |= MAC_CONTROL_HP;
122 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
123 MAC_CONTROL_IF | MAC_CONTROL_HO);
124
125 memset(mc_filter, 0, sizeof(mc_filter));
126 netdev_for_each_mc_addr(ha, dev) {
127 /* The upper 6 bits of the calculated CRC are used to
128 * index the contens of the hash table */
129 int bit_nr =
130 ether_crc(ETH_ALEN, ha->addr) >> 26;
131 /* The most significant bit determines the register to
132 * use (H/L) while the other 5 bits determine the bit
133 * within the register. */
134 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
135 }
136 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
137 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
138 }
139
140 writel(value, ioaddr + MAC_CONTROL);
141
142 CHIP_DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
143 "HI 0x%08x, LO 0x%08x\n",
144 __func__, readl(ioaddr + MAC_CONTROL),
145 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
146}
147
148static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
149 unsigned int fc, unsigned int pause_time)
150{
151 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
152
153 if (duplex)
154 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
155 writel(flow, ioaddr + MAC_FLOW_CTRL);
156}
157
158/* No PMT module supported for this Ethernet Controller.
159 * Tested on ST platforms only.
160 */
161static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
162{
163 return;
164}
165
166struct stmmac_ops dwmac100_ops = {
167 .core_init = dwmac100_core_init,
168 .dump_regs = dwmac100_dump_mac_regs,
169 .host_irq_status = dwmac100_irq_status,
170 .set_filter = dwmac100_set_filter,
171 .flow_ctrl = dwmac100_flow_ctrl,
172 .pmt = dwmac100_pmt,
173 .set_umac_addr = dwmac100_set_umac_addr,
174 .get_umac_addr = dwmac100_get_umac_addr,
175};
176
177struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
178{
179 struct mac_device_info *mac;
180
181 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
182
183 pr_info("\tDWMAC100\n");
184
185 mac->mac = &dwmac100_ops;
186 mac->dma = &dwmac100_dma_ops;
187
188 mac->pmt = PMT_NOT_SUPPORTED;
189 mac->link.port = MAC_CONTROL_PS;
190 mac->link.duplex = MAC_CONTROL_F;
191 mac->link.speed = 0;
192 mac->mii.addr = MAC_MII_ADDR;
193 mac->mii.data = MAC_MII_DATA;
194
195 return mac;
196}
diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c
new file mode 100644
index 000000000000..2fece7b72727
--- /dev/null
+++ b/drivers/net/stmmac/dwmac100_dma.c
@@ -0,0 +1,134 @@
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 "dwmac100.h"
32#include "dwmac_dma.h"
33
34static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
35 u32 dma_rx)
36{
37 u32 value = readl(ioaddr + DMA_BUS_MODE);
38 /* DMA SW reset */
39 value |= DMA_BUS_MODE_SFT_RESET;
40 writel(value, ioaddr + DMA_BUS_MODE);
41 do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
42
43 /* Enable Application Access by writing to DMA CSR0 */
44 writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
45 ioaddr + DMA_BUS_MODE);
46
47 /* Mask interrupts by writing to CSR7 */
48 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
49
50 /* The base address of the RX/TX descriptor lists must be written into
51 * DMA CSR3 and CSR4, respectively. */
52 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
53 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
54
55 return 0;
56}
57
58/* Store and Forward capability is not used at all..
59 * The transmit threshold can be programmed by
60 * setting the TTC bits in the DMA control register.*/
61static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
62 int rxmode)
63{
64 u32 csr6 = readl(ioaddr + DMA_CONTROL);
65
66 if (txmode <= 32)
67 csr6 |= DMA_CONTROL_TTC_32;
68 else if (txmode <= 64)
69 csr6 |= DMA_CONTROL_TTC_64;
70 else
71 csr6 |= DMA_CONTROL_TTC_128;
72
73 writel(csr6, ioaddr + DMA_CONTROL);
74}
75
76static void dwmac100_dump_dma_regs(unsigned long ioaddr)
77{
78 int i;
79
80 CHIP_DBG(KERN_DEBUG "DWMAC 100 DMA CSR\n");
81 for (i = 0; i < 9; i++)
82 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
83 (DMA_BUS_MODE + i * 4),
84 readl(ioaddr + DMA_BUS_MODE + i * 4));
85 CHIP_DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
86 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
87 CHIP_DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
88 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
89}
90
91/* DMA controller has two counters to track the number of
92 * the receive missed frames. */
93static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
94 unsigned long ioaddr)
95{
96 struct net_device_stats *stats = (struct net_device_stats *)data;
97 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
98
99 if (unlikely(csr8)) {
100 if (csr8 & DMA_MISSED_FRAME_OVE) {
101 stats->rx_over_errors += 0x800;
102 x->rx_overflow_cntr += 0x800;
103 } else {
104 unsigned int ove_cntr;
105 ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
106 stats->rx_over_errors += ove_cntr;
107 x->rx_overflow_cntr += ove_cntr;
108 }
109
110 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
111 stats->rx_missed_errors += 0xffff;
112 x->rx_missed_cntr += 0xffff;
113 } else {
114 unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
115 stats->rx_missed_errors += miss_f;
116 x->rx_missed_cntr += miss_f;
117 }
118 }
119}
120
121struct stmmac_dma_ops dwmac100_dma_ops = {
122 .init = dwmac100_dma_init,
123 .dump_regs = dwmac100_dump_dma_regs,
124 .dma_mode = dwmac100_dma_operation_mode,
125 .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
126 .enable_dma_transmission = dwmac_enable_dma_transmission,
127 .enable_dma_irq = dwmac_enable_dma_irq,
128 .disable_dma_irq = dwmac_disable_dma_irq,
129 .start_tx = dwmac_dma_start_tx,
130 .stop_tx = dwmac_dma_stop_tx,
131 .start_rx = dwmac_dma_start_rx,
132 .stop_rx = dwmac_dma_stop_rx,
133 .dma_interrupt = dwmac_dma_interrupt,
134};
diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h
index de848d9f6060..7b815a1b7b8c 100644
--- a/drivers/net/stmmac/dwmac_dma.h
+++ b/drivers/net/stmmac/dwmac_dma.h
@@ -95,6 +95,7 @@
95#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */ 95#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */
96#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */ 96#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */
97#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ 97#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
98#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
98 99
99extern void dwmac_enable_dma_transmission(unsigned long ioaddr); 100extern void dwmac_enable_dma_transmission(unsigned long ioaddr);
100extern void dwmac_enable_dma_irq(unsigned long ioaddr); 101extern void dwmac_enable_dma_irq(unsigned long ioaddr);
diff --git a/drivers/net/stmmac/dwmac_lib.c b/drivers/net/stmmac/dwmac_lib.c
index d4adb1eaa447..a85415216ef4 100644
--- a/drivers/net/stmmac/dwmac_lib.c
+++ b/drivers/net/stmmac/dwmac_lib.c
@@ -52,7 +52,6 @@ void dwmac_dma_start_tx(unsigned long ioaddr)
52 u32 value = readl(ioaddr + DMA_CONTROL); 52 u32 value = readl(ioaddr + DMA_CONTROL);
53 value |= DMA_CONTROL_ST; 53 value |= DMA_CONTROL_ST;
54 writel(value, ioaddr + DMA_CONTROL); 54 writel(value, ioaddr + DMA_CONTROL);
55 return;
56} 55}
57 56
58void dwmac_dma_stop_tx(unsigned long ioaddr) 57void dwmac_dma_stop_tx(unsigned long ioaddr)
@@ -60,7 +59,6 @@ void dwmac_dma_stop_tx(unsigned long ioaddr)
60 u32 value = readl(ioaddr + DMA_CONTROL); 59 u32 value = readl(ioaddr + DMA_CONTROL);
61 value &= ~DMA_CONTROL_ST; 60 value &= ~DMA_CONTROL_ST;
62 writel(value, ioaddr + DMA_CONTROL); 61 writel(value, ioaddr + DMA_CONTROL);
63 return;
64} 62}
65 63
66void dwmac_dma_start_rx(unsigned long ioaddr) 64void dwmac_dma_start_rx(unsigned long ioaddr)
@@ -68,8 +66,6 @@ void dwmac_dma_start_rx(unsigned long ioaddr)
68 u32 value = readl(ioaddr + DMA_CONTROL); 66 u32 value = readl(ioaddr + DMA_CONTROL);
69 value |= DMA_CONTROL_SR; 67 value |= DMA_CONTROL_SR;
70 writel(value, ioaddr + DMA_CONTROL); 68 writel(value, ioaddr + DMA_CONTROL);
71
72 return;
73} 69}
74 70
75void dwmac_dma_stop_rx(unsigned long ioaddr) 71void dwmac_dma_stop_rx(unsigned long ioaddr)
@@ -77,8 +73,6 @@ void dwmac_dma_stop_rx(unsigned long ioaddr)
77 u32 value = readl(ioaddr + DMA_CONTROL); 73 u32 value = readl(ioaddr + DMA_CONTROL);
78 value &= ~DMA_CONTROL_SR; 74 value &= ~DMA_CONTROL_SR;
79 writel(value, ioaddr + DMA_CONTROL); 75 writel(value, ioaddr + DMA_CONTROL);
80
81 return;
82} 76}
83 77
84#ifdef DWMAC_DMA_DEBUG 78#ifdef DWMAC_DMA_DEBUG
@@ -111,7 +105,6 @@ static void show_tx_process_state(unsigned int status)
111 default: 105 default:
112 break; 106 break;
113 } 107 }
114 return;
115} 108}
116 109
117static void show_rx_process_state(unsigned int status) 110static void show_rx_process_state(unsigned int status)
@@ -149,7 +142,6 @@ static void show_rx_process_state(unsigned int status)
149 default: 142 default:
150 break; 143 break;
151 } 144 }
152 return;
153} 145}
154#endif 146#endif
155 147
@@ -227,6 +219,13 @@ int dwmac_dma_interrupt(unsigned long ioaddr,
227 return ret; 219 return ret;
228} 220}
229 221
222void dwmac_dma_flush_tx_fifo(unsigned long 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}
230 229
231void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], 230void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
232 unsigned int high, unsigned int low) 231 unsigned int high, unsigned int low)
@@ -237,8 +236,6 @@ void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
237 writel(data, ioaddr + high); 236 writel(data, ioaddr + high);
238 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; 237 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
239 writel(data, ioaddr + low); 238 writel(data, ioaddr + low);
240
241 return;
242} 239}
243 240
244void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr, 241void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
@@ -257,7 +254,5 @@ void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr,
257 addr[3] = (lo_addr >> 24) & 0xff; 254 addr[3] = (lo_addr >> 24) & 0xff;
258 addr[4] = hi_addr & 0xff; 255 addr[4] = hi_addr & 0xff;
259 addr[5] = (hi_addr >> 8) & 0xff; 256 addr[5] = (hi_addr >> 8) & 0xff;
260
261 return;
262} 257}
263 258
diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c
new file mode 100644
index 000000000000..3c18ebece043
--- /dev/null
+++ b/drivers/net/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, unsigned long 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 = good_frame;
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, sizeof(struct dma_desc));
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
321struct 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/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c
new file mode 100644
index 000000000000..31ad53643792
--- /dev/null
+++ b/drivers/net/stmmac/norm_desc.c
@@ -0,0 +1,236 @@
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, unsigned long 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 becasue 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 /* clean field used within the xmit */
178 p->des01.tx.first_segment = 0;
179 p->des01.tx.last_segment = 0;
180 p->des01.tx.buffer1_size = 0;
181
182 /* clean status reported */
183 p->des01.tx.error_summary = 0;
184 p->des01.tx.underflow_error = 0;
185 p->des01.tx.no_carrier = 0;
186 p->des01.tx.loss_carrier = 0;
187 p->des01.tx.excessive_deferral = 0;
188 p->des01.tx.excessive_collisions = 0;
189 p->des01.tx.late_collision = 0;
190 p->des01.tx.heartbeat_fail = 0;
191 p->des01.tx.deferred = 0;
192
193 /* set termination field */
194 p->des01.tx.end_ring = ter;
195}
196
197static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
198 int csum_flag)
199{
200 p->des01.tx.first_segment = is_fs;
201 p->des01.tx.buffer1_size = len;
202}
203
204static void ndesc_clear_tx_ic(struct dma_desc *p)
205{
206 p->des01.tx.interrupt = 0;
207}
208
209static void ndesc_close_tx_desc(struct dma_desc *p)
210{
211 p->des01.tx.last_segment = 1;
212 p->des01.tx.interrupt = 1;
213}
214
215static int ndesc_get_rx_frame_len(struct dma_desc *p)
216{
217 return p->des01.rx.frame_length;
218}
219
220struct stmmac_desc_ops ndesc_ops = {
221 .tx_status = ndesc_get_tx_status,
222 .rx_status = ndesc_get_rx_status,
223 .get_tx_len = ndesc_get_tx_len,
224 .init_rx_desc = ndesc_init_rx_desc,
225 .init_tx_desc = ndesc_init_tx_desc,
226 .get_tx_owner = ndesc_get_tx_owner,
227 .get_rx_owner = ndesc_get_rx_owner,
228 .release_tx_desc = ndesc_release_tx_desc,
229 .prepare_tx_desc = ndesc_prepare_tx_desc,
230 .clear_tx_ic = ndesc_clear_tx_ic,
231 .close_tx_desc = ndesc_close_tx_desc,
232 .get_tx_ls = ndesc_get_tx_ls,
233 .set_tx_owner = ndesc_set_tx_owner,
234 .set_rx_owner = ndesc_set_rx_owner,
235 .get_rx_frame_len = ndesc_get_rx_frame_len,
236};
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index ba35e6943cf4..ebebc644b1b8 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -20,14 +20,9 @@
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/ 21*******************************************************************************/
22 22
23#define DRV_MODULE_VERSION "Jan_2010" 23#define DRV_MODULE_VERSION "Apr_2010"
24#include <linux/stmmac.h> 24#include <linux/stmmac.h>
25 25
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 "common.h" 26#include "common.h"
32#ifdef CONFIG_STMMAC_TIMER 27#ifdef CONFIG_STMMAC_TIMER
33#include "stmmac_timer.h" 28#include "stmmac_timer.h"
@@ -93,6 +88,7 @@ struct stmmac_priv {
93#ifdef STMMAC_VLAN_TAG_USED 88#ifdef STMMAC_VLAN_TAG_USED
94 struct vlan_group *vlgrp; 89 struct vlan_group *vlgrp;
95#endif 90#endif
91 int enh_desc;
96}; 92};
97 93
98#ifdef CONFIG_STM_DRIVERS 94#ifdef CONFIG_STM_DRIVERS
@@ -120,3 +116,5 @@ static inline int stmmac_claim_resource(struct platform_device *pdev)
120extern int stmmac_mdio_unregister(struct net_device *ndev); 116extern int stmmac_mdio_unregister(struct net_device *ndev);
121extern int stmmac_mdio_register(struct net_device *ndev); 117extern int stmmac_mdio_register(struct net_device *ndev);
122extern void stmmac_set_ethtool_ops(struct net_device *netdev); 118extern void stmmac_set_ethtool_ops(struct net_device *netdev);
119extern struct stmmac_desc_ops enh_desc_ops;
120extern struct stmmac_desc_ops ndesc_ops;
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index c021eaa3ca69..f080509923f0 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -102,7 +102,6 @@ void stmmac_ethtool_getdrvinfo(struct net_device *dev,
102 strcpy(info->version, DRV_MODULE_VERSION); 102 strcpy(info->version, DRV_MODULE_VERSION);
103 info->fw_version[0] = '\0'; 103 info->fw_version[0] = '\0';
104 info->n_stats = STMMAC_STATS_LEN; 104 info->n_stats = STMMAC_STATS_LEN;
105 return;
106} 105}
107 106
108int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) 107int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -194,8 +193,6 @@ void stmmac_ethtool_gregs(struct net_device *dev,
194 reg_space[i + 55] = 193 reg_space[i + 55] =
195 readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); 194 readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
196 } 195 }
197
198 return;
199} 196}
200 197
201int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) 198int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
@@ -233,7 +230,6 @@ stmmac_get_pauseparam(struct net_device *netdev,
233 pause->tx_pause = 1; 230 pause->tx_pause = 1;
234 231
235 spin_unlock(&priv->lock); 232 spin_unlock(&priv->lock);
236 return;
237} 233}
238 234
239static int 235static int
@@ -292,8 +288,6 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
292 data[i] = (stmmac_gstrings_stats[i].sizeof_stat == 288 data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
293 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p); 289 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
294 } 290 }
295
296 return;
297} 291}
298 292
299static int stmmac_get_sset_count(struct net_device *netdev, int sset) 293static int stmmac_get_sset_count(struct net_device *netdev, int sset)
@@ -323,7 +317,6 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
323 WARN_ON(1); 317 WARN_ON(1);
324 break; 318 break;
325 } 319 }
326 return;
327} 320}
328 321
329/* Currently only support WOL through Magic packet. */ 322/* Currently only support WOL through Magic packet. */
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 4111a85ec80e..a31d580f306d 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -169,8 +169,6 @@ static void stmmac_verify_args(void)
169 flow_ctrl = FLOW_OFF; 169 flow_ctrl = FLOW_OFF;
170 if (unlikely((pause < 0) || (pause > 0xffff))) 170 if (unlikely((pause < 0) || (pause > 0xffff)))
171 pause = PAUSE_TIME; 171 pause = PAUSE_TIME;
172
173 return;
174} 172}
175 173
176#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG) 174#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
@@ -184,7 +182,6 @@ static void print_pkt(unsigned char *buf, int len)
184 pr_info(" %02x", buf[j]); 182 pr_info(" %02x", buf[j]);
185 } 183 }
186 pr_info("\n"); 184 pr_info("\n");
187 return;
188} 185}
189#endif 186#endif
190 187
@@ -514,7 +511,6 @@ static void init_dma_desc_rings(struct net_device *dev)
514 pr_info("TX descriptor ring:\n"); 511 pr_info("TX descriptor ring:\n");
515 display_ring(priv->dma_tx, txsize); 512 display_ring(priv->dma_tx, txsize);
516 } 513 }
517 return;
518} 514}
519 515
520static void dma_free_rx_skbufs(struct stmmac_priv *priv) 516static void dma_free_rx_skbufs(struct stmmac_priv *priv)
@@ -529,7 +525,6 @@ static void dma_free_rx_skbufs(struct stmmac_priv *priv)
529 } 525 }
530 priv->rx_skbuff[i] = NULL; 526 priv->rx_skbuff[i] = NULL;
531 } 527 }
532 return;
533} 528}
534 529
535static void dma_free_tx_skbufs(struct stmmac_priv *priv) 530static void dma_free_tx_skbufs(struct stmmac_priv *priv)
@@ -547,7 +542,6 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv)
547 priv->tx_skbuff[i] = NULL; 542 priv->tx_skbuff[i] = NULL;
548 } 543 }
549 } 544 }
550 return;
551} 545}
552 546
553static void free_dma_desc_resources(struct stmmac_priv *priv) 547static void free_dma_desc_resources(struct stmmac_priv *priv)
@@ -567,8 +561,6 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
567 kfree(priv->rx_skbuff_dma); 561 kfree(priv->rx_skbuff_dma);
568 kfree(priv->rx_skbuff); 562 kfree(priv->rx_skbuff);
569 kfree(priv->tx_skbuff); 563 kfree(priv->tx_skbuff);
570
571 return;
572} 564}
573 565
574/** 566/**
@@ -598,8 +590,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
598 } 590 }
599 } 591 }
600 tx_coe = priv->tx_coe; 592 tx_coe = priv->tx_coe;
601
602 return;
603} 593}
604 594
605/** 595/**
@@ -675,7 +665,6 @@ static void stmmac_tx(struct stmmac_priv *priv)
675 } 665 }
676 netif_tx_unlock(priv->dev); 666 netif_tx_unlock(priv->dev);
677 } 667 }
678 return;
679} 668}
680 669
681static inline void stmmac_enable_irq(struct stmmac_priv *priv) 670static inline void stmmac_enable_irq(struct stmmac_priv *priv)
@@ -731,8 +720,6 @@ void stmmac_schedule(struct net_device *dev)
731 priv->xstats.sched_timer_n++; 720 priv->xstats.sched_timer_n++;
732 721
733 _stmmac_schedule(priv); 722 _stmmac_schedule(priv);
734
735 return;
736} 723}
737 724
738static void stmmac_no_timer_started(unsigned int x) 725static void stmmac_no_timer_started(unsigned int x)
@@ -763,8 +750,6 @@ static void stmmac_tx_err(struct stmmac_priv *priv)
763 750
764 priv->dev->stats.tx_errors++; 751 priv->dev->stats.tx_errors++;
765 netif_wake_queue(priv->dev); 752 netif_wake_queue(priv->dev);
766
767 return;
768} 753}
769 754
770 755
@@ -788,8 +773,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
788 stmmac_tx_err(priv); 773 stmmac_tx_err(priv);
789 } else if (unlikely(status == tx_hard_error)) 774 } else if (unlikely(status == tx_hard_error))
790 stmmac_tx_err(priv); 775 stmmac_tx_err(priv);
791
792 return;
793} 776}
794 777
795/** 778/**
@@ -837,7 +820,7 @@ static int stmmac_open(struct net_device *dev)
837#ifdef CONFIG_STMMAC_TIMER 820#ifdef CONFIG_STMMAC_TIMER
838 priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); 821 priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
839 if (unlikely(priv->tm == NULL)) { 822 if (unlikely(priv->tm == NULL)) {
840 pr_err("%s: ERROR: timer memory alloc failed \n", __func__); 823 pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
841 return -ENOMEM; 824 return -ENOMEM;
842 } 825 }
843 priv->tm->freq = tmrate; 826 priv->tm->freq = tmrate;
@@ -1197,7 +1180,6 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
1197 } 1180 }
1198 priv->hw->desc->set_rx_owner(p + entry); 1181 priv->hw->desc->set_rx_owner(p + entry);
1199 } 1182 }
1200 return;
1201} 1183}
1202 1184
1203static int stmmac_rx(struct stmmac_priv *priv, int limit) 1185static int stmmac_rx(struct stmmac_priv *priv, int limit)
@@ -1280,7 +1262,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
1280 1262
1281 priv->dev->stats.rx_packets++; 1263 priv->dev->stats.rx_packets++;
1282 priv->dev->stats.rx_bytes += frame_len; 1264 priv->dev->stats.rx_bytes += frame_len;
1283 priv->dev->last_rx = jiffies;
1284 } 1265 }
1285 entry = next_entry; 1266 entry = next_entry;
1286 p = p_next; /* use prefetched values */ 1267 p = p_next; /* use prefetched values */
@@ -1332,7 +1313,6 @@ static void stmmac_tx_timeout(struct net_device *dev)
1332 1313
1333 /* Clear Tx resources and restart transmitting again */ 1314 /* Clear Tx resources and restart transmitting again */
1334 stmmac_tx_err(priv); 1315 stmmac_tx_err(priv);
1335 return;
1336} 1316}
1337 1317
1338/* Configuration changes (passed on by ifconfig) */ 1318/* Configuration changes (passed on by ifconfig) */
@@ -1374,7 +1354,6 @@ static void stmmac_multicast_list(struct net_device *dev)
1374 spin_lock(&priv->lock); 1354 spin_lock(&priv->lock);
1375 priv->hw->mac->set_filter(dev); 1355 priv->hw->mac->set_filter(dev);
1376 spin_unlock(&priv->lock); 1356 spin_unlock(&priv->lock);
1377 return;
1378} 1357}
1379 1358
1380/** 1359/**
@@ -1490,8 +1469,6 @@ static void stmmac_vlan_rx_register(struct net_device *dev,
1490 spin_lock(&priv->lock); 1469 spin_lock(&priv->lock);
1491 priv->vlgrp = grp; 1470 priv->vlgrp = grp;
1492 spin_unlock(&priv->lock); 1471 spin_unlock(&priv->lock);
1493
1494 return;
1495} 1472}
1496#endif 1473#endif
1497 1474
@@ -1587,6 +1564,12 @@ static int stmmac_mac_device_setup(struct net_device *dev)
1587 else 1564 else
1588 device = dwmac100_setup(ioaddr); 1565 device = dwmac100_setup(ioaddr);
1589 1566
1567 if (priv->enh_desc) {
1568 device->desc = &enh_desc_ops;
1569 pr_info("\tEnhanced descriptor structure\n");
1570 } else
1571 device->desc = &ndesc_ops;
1572
1590 if (!device) 1573 if (!device)
1591 return -ENOMEM; 1574 return -ENOMEM;
1592 1575
@@ -1727,6 +1710,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
1727 priv->bus_id = plat_dat->bus_id; 1710 priv->bus_id = plat_dat->bus_id;
1728 priv->pbl = plat_dat->pbl; /* TLI */ 1711 priv->pbl = plat_dat->pbl; /* TLI */
1729 priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ 1712 priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
1713 priv->enh_desc = plat_dat->enh_desc;
1730 1714
1731 platform_set_drvdata(pdev, ndev); 1715 platform_set_drvdata(pdev, ndev);
1732 1716
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
index 679f61ffb1f8..2a0e1abde7e7 100644
--- a/drivers/net/stmmac/stmmac_timer.c
+++ b/drivers/net/stmmac/stmmac_timer.c
@@ -31,8 +31,6 @@ static void stmmac_timer_handler(void *data)
31 struct net_device *dev = (struct net_device *)data; 31 struct net_device *dev = (struct net_device *)data;
32 32
33 stmmac_schedule(dev); 33 stmmac_schedule(dev);
34
35 return;
36} 34}
37 35
38#define STMMAC_TIMER_MSG(timer, freq) \ 36#define STMMAC_TIMER_MSG(timer, freq) \
@@ -47,13 +45,11 @@ static void stmmac_rtc_start(unsigned int new_freq)
47{ 45{
48 rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq); 46 rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
49 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1); 47 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
50 return;
51} 48}
52 49
53static void stmmac_rtc_stop(void) 50static void stmmac_rtc_stop(void)
54{ 51{
55 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0); 52 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
56 return;
57} 53}
58 54
59int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) 55int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
@@ -102,13 +98,11 @@ static void stmmac_tmu_start(unsigned int new_freq)
102{ 98{
103 clk_set_rate(timer_clock, new_freq); 99 clk_set_rate(timer_clock, new_freq);
104 clk_enable(timer_clock); 100 clk_enable(timer_clock);
105 return;
106} 101}
107 102
108static void stmmac_tmu_stop(void) 103static void stmmac_tmu_stop(void)
109{ 104{
110 clk_disable(timer_clock); 105 clk_disable(timer_clock);
111 return;
112} 106}
113 107
114int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) 108int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)