stmmac: fix 'lenght' typo in comments and code
[safe/jmp/linux-2.6] / drivers / net / stmmac / dwmac1000_dma.c
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 and descriptors.
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 "dwmac1000.h"
30 #include "dwmac_dma.h"
31
32 static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
33                               u32 dma_rx)
34 {
35         u32 value = readl(ioaddr + DMA_BUS_MODE);
36         /* DMA SW reset */
37         value |= DMA_BUS_MODE_SFT_RESET;
38         writel(value, ioaddr + DMA_BUS_MODE);
39         do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
40
41         value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
42             ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
43              (pbl << DMA_BUS_MODE_RPBL_SHIFT));
44
45 #ifdef CONFIG_STMMAC_DA
46         value |= DMA_BUS_MODE_DA;       /* Rx has priority over tx */
47 #endif
48         writel(value, ioaddr + DMA_BUS_MODE);
49
50         /* Mask interrupts by writing to CSR7 */
51         writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
52
53         /* The base address of the RX/TX descriptor lists must be written into
54          * DMA CSR3 and CSR4, respectively. */
55         writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
56         writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
57
58         return 0;
59 }
60
61 /* Transmit FIFO flush operation */
62 static 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
70 static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode,
71                                     int rxmode)
72 {
73         u32 csr6 = readl(ioaddr + DMA_CONTROL);
74
75         if (txmode == SF_DMA_MODE) {
76                 DBG(KERN_DEBUG "GMAC: enabling 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                 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                 DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n");
102                 csr6 |= DMA_CONTROL_RSF;
103         } else {
104                 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         return;
120 }
121
122 /* Not yet implemented --- no RMON module */
123 static void dwmac1000_dma_diagnostic_fr(void *data,
124                   struct stmmac_extra_stats *x, unsigned long ioaddr)
125 {
126         return;
127 }
128
129 static void dwmac1000_dump_dma_regs(unsigned long ioaddr)
130 {
131         int i;
132         pr_info(" DMA registers\n");
133         for (i = 0; i < 22; i++) {
134                 if ((i < 9) || (i > 17)) {
135                         int offset = i * 4;
136                         pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
137                                (DMA_BUS_MODE + offset),
138                                readl(ioaddr + DMA_BUS_MODE + offset));
139                 }
140         }
141         return;
142 }
143
144 static 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
221 static int dwmac1000_get_tx_len(struct dma_desc *p)
222 {
223         return p->des01.etx.buffer1_size;
224 }
225
226 static 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
269 static 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
346 static 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
364 static 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
378 static int dwmac1000_get_tx_owner(struct dma_desc *p)
379 {
380         return p->des01.etx.own;
381 }
382
383 static int dwmac1000_get_rx_owner(struct dma_desc *p)
384 {
385         return p->des01.erx.own;
386 }
387
388 static void dwmac1000_set_tx_owner(struct dma_desc *p)
389 {
390         p->des01.etx.own = 1;
391 }
392
393 static void dwmac1000_set_rx_owner(struct dma_desc *p)
394 {
395         p->des01.erx.own = 1;
396 }
397
398 static int dwmac1000_get_tx_ls(struct dma_desc *p)
399 {
400         return p->des01.etx.last_segment;
401 }
402
403 static 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
413 static 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
427 static void dwmac1000_clear_tx_ic(struct dma_desc *p)
428 {
429         p->des01.etx.interrupt = 0;
430 }
431
432 static 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
438 static int dwmac1000_get_rx_frame_len(struct dma_desc *p)
439 {
440         return p->des01.erx.frame_length;
441 }
442
443 struct stmmac_dma_ops dwmac1000_dma_ops = {
444         .init = dwmac1000_dma_init,
445         .dump_regs = dwmac1000_dump_dma_regs,
446         .dma_mode = dwmac1000_dma_operation_mode,
447         .dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
448         .enable_dma_transmission = dwmac_enable_dma_transmission,
449         .enable_dma_irq = dwmac_enable_dma_irq,
450         .disable_dma_irq = dwmac_disable_dma_irq,
451         .start_tx = dwmac_dma_start_tx,
452         .stop_tx = dwmac_dma_stop_tx,
453         .start_rx = dwmac_dma_start_rx,
454         .stop_rx = dwmac_dma_stop_rx,
455         .dma_interrupt = dwmac_dma_interrupt,
456 };
457
458 struct 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 };