stmmac: fix 'lenght' typo in comments and code
[safe/jmp/linux-2.6] / drivers / net / stmmac / dwmac100.c
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
33 #include "common.h"
34 #include "dwmac100.h"
35 #include "dwmac_dma.h"
36
37 #undef DWMAC100_DEBUG
38 /*#define DWMAC100_DEBUG*/
39 #ifdef DWMAC100_DEBUG
40 #define DBG(fmt, args...)  printk(fmt, ## args)
41 #else
42 #define DBG(fmt, args...)  do { } while (0)
43 #endif
44
45 static void dwmac100_core_init(unsigned long ioaddr)
46 {
47         u32 value = readl(ioaddr + MAC_CONTROL);
48
49         writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
50
51 #ifdef STMMAC_VLAN_TAG_USED
52         writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
53 #endif
54         return;
55 }
56
57 static void dwmac100_dump_mac_regs(unsigned long ioaddr)
58 {
59         pr_info("\t----------------------------------------------\n"
60                 "\t  DWMAC 100 CSR (base addr = 0x%8x)\n"
61                 "\t----------------------------------------------\n",
62                 (unsigned int)ioaddr);
63         pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
64                 readl(ioaddr + MAC_CONTROL));
65         pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
66                 readl(ioaddr + MAC_ADDR_HIGH));
67         pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
68                 readl(ioaddr + MAC_ADDR_LOW));
69         pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
70                 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
71         pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
72                 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
73         pr_info("\tflow control (offset 0x%x): 0x%08x\n",
74                 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
75         pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
76                 readl(ioaddr + MAC_VLAN1));
77         pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
78                 readl(ioaddr + MAC_VLAN2));
79         pr_info("\n\tMAC management counter registers\n");
80         pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
81                 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
82         pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
83                 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
84         pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
85                 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
86         pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
87                 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
88         pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
89                 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
90         return;
91 }
92
93 static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
94                            u32 dma_rx)
95 {
96         u32 value = readl(ioaddr + DMA_BUS_MODE);
97         /* DMA SW reset */
98         value |= DMA_BUS_MODE_SFT_RESET;
99         writel(value, ioaddr + DMA_BUS_MODE);
100         do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
101
102         /* Enable Application Access by writing to DMA CSR0 */
103         writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
104                ioaddr + DMA_BUS_MODE);
105
106         /* Mask interrupts by writing to CSR7 */
107         writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
108
109         /* The base address of the RX/TX descriptor lists must be written into
110          * DMA CSR3 and CSR4, respectively. */
111         writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
112         writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
113
114         return 0;
115 }
116
117 /* Store and Forward capability is not used at all..
118  * The transmit threshold can be programmed by
119  * setting the TTC bits in the DMA control register.*/
120 static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode,
121                                       int rxmode)
122 {
123         u32 csr6 = readl(ioaddr + DMA_CONTROL);
124
125         if (txmode <= 32)
126                 csr6 |= DMA_CONTROL_TTC_32;
127         else if (txmode <= 64)
128                 csr6 |= DMA_CONTROL_TTC_64;
129         else
130                 csr6 |= DMA_CONTROL_TTC_128;
131
132         writel(csr6, ioaddr + DMA_CONTROL);
133
134         return;
135 }
136
137 static void dwmac100_dump_dma_regs(unsigned long ioaddr)
138 {
139         int i;
140
141         DBG(KERN_DEBUG "DWMAC 100 DMA CSR \n");
142         for (i = 0; i < 9; i++)
143                 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
144                        (DMA_BUS_MODE + i * 4),
145                        readl(ioaddr + DMA_BUS_MODE + i * 4));
146         DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
147             DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
148         DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
149             DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
150         return;
151 }
152
153 /* DMA controller has two counters to track the number of
154  * the receive missed frames. */
155 static void dwmac100_dma_diagnostic_fr(void *data,
156                                      struct stmmac_extra_stats *x,
157                                      unsigned long ioaddr)
158 {
159         struct net_device_stats *stats = (struct net_device_stats *)data;
160         u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
161
162         if (unlikely(csr8)) {
163                 if (csr8 & DMA_MISSED_FRAME_OVE) {
164                         stats->rx_over_errors += 0x800;
165                         x->rx_overflow_cntr += 0x800;
166                 } else {
167                         unsigned int ove_cntr;
168                         ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
169                         stats->rx_over_errors += ove_cntr;
170                         x->rx_overflow_cntr += ove_cntr;
171                 }
172
173                 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
174                         stats->rx_missed_errors += 0xffff;
175                         x->rx_missed_cntr += 0xffff;
176                 } else {
177                         unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
178                         stats->rx_missed_errors += miss_f;
179                         x->rx_missed_cntr += miss_f;
180                 }
181         }
182         return;
183 }
184
185 static int dwmac100_get_tx_frame_status(void *data,
186                                       struct stmmac_extra_stats *x,
187                                       struct dma_desc *p, unsigned long ioaddr)
188 {
189         int ret = 0;
190         struct net_device_stats *stats = (struct net_device_stats *)data;
191
192         if (unlikely(p->des01.tx.error_summary)) {
193                 if (unlikely(p->des01.tx.underflow_error)) {
194                         x->tx_underflow++;
195                         stats->tx_fifo_errors++;
196                 }
197                 if (unlikely(p->des01.tx.no_carrier)) {
198                         x->tx_carrier++;
199                         stats->tx_carrier_errors++;
200                 }
201                 if (unlikely(p->des01.tx.loss_carrier)) {
202                         x->tx_losscarrier++;
203                         stats->tx_carrier_errors++;
204                 }
205                 if (unlikely((p->des01.tx.excessive_deferral) ||
206                              (p->des01.tx.excessive_collisions) ||
207                              (p->des01.tx.late_collision)))
208                         stats->collisions += p->des01.tx.collision_count;
209                 ret = -1;
210         }
211         if (unlikely(p->des01.tx.heartbeat_fail)) {
212                 x->tx_heartbeat++;
213                 stats->tx_heartbeat_errors++;
214                 ret = -1;
215         }
216         if (unlikely(p->des01.tx.deferred))
217                 x->tx_deferred++;
218
219         return ret;
220 }
221
222 static int dwmac100_get_tx_len(struct dma_desc *p)
223 {
224         return p->des01.tx.buffer1_size;
225 }
226
227 /* This function verifies if each incoming frame has some errors
228  * and, if required, updates the multicast statistics.
229  * In case of success, it returns csum_none becasue the device
230  * is not able to compute the csum in HW. */
231 static int dwmac100_get_rx_frame_status(void *data,
232                                       struct stmmac_extra_stats *x,
233                                       struct dma_desc *p)
234 {
235         int ret = csum_none;
236         struct net_device_stats *stats = (struct net_device_stats *)data;
237
238         if (unlikely(p->des01.rx.last_descriptor == 0)) {
239                 pr_warning("dwmac100 Error: Oversized Ethernet "
240                            "frame spanned multiple buffers\n");
241                 stats->rx_length_errors++;
242                 return discard_frame;
243         }
244
245         if (unlikely(p->des01.rx.error_summary)) {
246                 if (unlikely(p->des01.rx.descriptor_error))
247                         x->rx_desc++;
248                 if (unlikely(p->des01.rx.partial_frame_error))
249                         x->rx_partial++;
250                 if (unlikely(p->des01.rx.run_frame))
251                         x->rx_runt++;
252                 if (unlikely(p->des01.rx.frame_too_long))
253                         x->rx_toolong++;
254                 if (unlikely(p->des01.rx.collision)) {
255                         x->rx_collision++;
256                         stats->collisions++;
257                 }
258                 if (unlikely(p->des01.rx.crc_error)) {
259                         x->rx_crc++;
260                         stats->rx_crc_errors++;
261                 }
262                 ret = discard_frame;
263         }
264         if (unlikely(p->des01.rx.dribbling))
265                 ret = discard_frame;
266
267         if (unlikely(p->des01.rx.length_error)) {
268                 x->rx_length++;
269                 ret = discard_frame;
270         }
271         if (unlikely(p->des01.rx.mii_error)) {
272                 x->rx_mii++;
273                 ret = discard_frame;
274         }
275         if (p->des01.rx.multicast_frame) {
276                 x->rx_multicast++;
277                 stats->multicast++;
278         }
279         return ret;
280 }
281
282 static void dwmac100_irq_status(unsigned long ioaddr)
283 {
284         return;
285 }
286
287 static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
288                           unsigned int reg_n)
289 {
290         stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
291 }
292
293 static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
294                           unsigned int reg_n)
295 {
296         stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
297 }
298
299 static void dwmac100_set_filter(struct net_device *dev)
300 {
301         unsigned long ioaddr = dev->base_addr;
302         u32 value = readl(ioaddr + MAC_CONTROL);
303
304         if (dev->flags & IFF_PROMISC) {
305                 value |= MAC_CONTROL_PR;
306                 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
307                            MAC_CONTROL_HP);
308         } else if ((dev->mc_count > HASH_TABLE_SIZE)
309                    || (dev->flags & IFF_ALLMULTI)) {
310                 value |= MAC_CONTROL_PM;
311                 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
312                 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
313                 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
314         } else if (dev->mc_count == 0) {        /* no multicast */
315                 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
316                            MAC_CONTROL_HO | MAC_CONTROL_HP);
317         } else {
318                 int i;
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                 for (i = 0, mclist = dev->mc_list;
330                      mclist && i < dev->mc_count; i++, mclist = mclist->next) {
331                         /* The upper 6 bits of the calculated CRC are used to
332                          * index the contens of the hash table */
333                         int bit_nr =
334                             ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
335                         /* The most significant bit determines the register to
336                          * use (H/L) while the other 5 bits determine the bit
337                          * within the register. */
338                         mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
339                 }
340                 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
341                 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
342         }
343
344         writel(value, ioaddr + MAC_CONTROL);
345
346         DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
347             "HI 0x%08x, LO 0x%08x\n",
348             __func__, readl(ioaddr + MAC_CONTROL),
349             readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
350         return;
351 }
352
353 static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
354                              unsigned int fc, unsigned int pause_time)
355 {
356         unsigned int flow = MAC_FLOW_CTRL_ENABLE;
357
358         if (duplex)
359                 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
360         writel(flow, ioaddr + MAC_FLOW_CTRL);
361
362         return;
363 }
364
365 /* No PMT module supported for this Ethernet Controller.
366  * Tested on ST platforms only.
367  */
368 static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
369 {
370         return;
371 }
372
373 static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
374                                 int disable_rx_ic)
375 {
376         int i;
377         for (i = 0; i < ring_size; i++) {
378                 p->des01.rx.own = 1;
379                 p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
380                 if (i == ring_size - 1)
381                         p->des01.rx.end_ring = 1;
382                 if (disable_rx_ic)
383                         p->des01.rx.disable_ic = 1;
384                 p++;
385         }
386         return;
387 }
388
389 static void dwmac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
390 {
391         int i;
392         for (i = 0; i < ring_size; i++) {
393                 p->des01.tx.own = 0;
394                 if (i == ring_size - 1)
395                         p->des01.tx.end_ring = 1;
396                 p++;
397         }
398         return;
399 }
400
401 static int dwmac100_get_tx_owner(struct dma_desc *p)
402 {
403         return p->des01.tx.own;
404 }
405
406 static int dwmac100_get_rx_owner(struct dma_desc *p)
407 {
408         return p->des01.rx.own;
409 }
410
411 static void dwmac100_set_tx_owner(struct dma_desc *p)
412 {
413         p->des01.tx.own = 1;
414 }
415
416 static void dwmac100_set_rx_owner(struct dma_desc *p)
417 {
418         p->des01.rx.own = 1;
419 }
420
421 static int dwmac100_get_tx_ls(struct dma_desc *p)
422 {
423         return p->des01.tx.last_segment;
424 }
425
426 static void dwmac100_release_tx_desc(struct dma_desc *p)
427 {
428         int ter = p->des01.tx.end_ring;
429
430         /* clean field used within the xmit */
431         p->des01.tx.first_segment = 0;
432         p->des01.tx.last_segment = 0;
433         p->des01.tx.buffer1_size = 0;
434
435         /* clean status reported */
436         p->des01.tx.error_summary = 0;
437         p->des01.tx.underflow_error = 0;
438         p->des01.tx.no_carrier = 0;
439         p->des01.tx.loss_carrier = 0;
440         p->des01.tx.excessive_deferral = 0;
441         p->des01.tx.excessive_collisions = 0;
442         p->des01.tx.late_collision = 0;
443         p->des01.tx.heartbeat_fail = 0;
444         p->des01.tx.deferred = 0;
445
446         /* set termination field */
447         p->des01.tx.end_ring = ter;
448
449         return;
450 }
451
452 static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
453                                    int csum_flag)
454 {
455         p->des01.tx.first_segment = is_fs;
456         p->des01.tx.buffer1_size = len;
457 }
458
459 static void dwmac100_clear_tx_ic(struct dma_desc *p)
460 {
461         p->des01.tx.interrupt = 0;
462 }
463
464 static void dwmac100_close_tx_desc(struct dma_desc *p)
465 {
466         p->des01.tx.last_segment = 1;
467         p->des01.tx.interrupt = 1;
468 }
469
470 static int dwmac100_get_rx_frame_len(struct dma_desc *p)
471 {
472         return p->des01.rx.frame_length;
473 }
474
475 struct stmmac_ops dwmac100_ops = {
476         .core_init = dwmac100_core_init,
477         .dump_regs = dwmac100_dump_mac_regs,
478         .host_irq_status = dwmac100_irq_status,
479         .set_filter = dwmac100_set_filter,
480         .flow_ctrl = dwmac100_flow_ctrl,
481         .pmt = dwmac100_pmt,
482         .set_umac_addr = dwmac100_set_umac_addr,
483         .get_umac_addr = dwmac100_get_umac_addr,
484 };
485
486 struct stmmac_dma_ops dwmac100_dma_ops = {
487         .init = dwmac100_dma_init,
488         .dump_regs = dwmac100_dump_dma_regs,
489         .dma_mode = dwmac100_dma_operation_mode,
490         .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
491         .enable_dma_transmission = dwmac_enable_dma_transmission,
492         .enable_dma_irq = dwmac_enable_dma_irq,
493         .disable_dma_irq = dwmac_disable_dma_irq,
494         .start_tx = dwmac_dma_start_tx,
495         .stop_tx = dwmac_dma_stop_tx,
496         .start_rx = dwmac_dma_start_rx,
497         .stop_rx = dwmac_dma_stop_rx,
498         .dma_interrupt = dwmac_dma_interrupt,
499 };
500
501 struct stmmac_desc_ops dwmac100_desc_ops = {
502         .tx_status = dwmac100_get_tx_frame_status,
503         .rx_status = dwmac100_get_rx_frame_status,
504         .get_tx_len = dwmac100_get_tx_len,
505         .init_rx_desc = dwmac100_init_rx_desc,
506         .init_tx_desc = dwmac100_init_tx_desc,
507         .get_tx_owner = dwmac100_get_tx_owner,
508         .get_rx_owner = dwmac100_get_rx_owner,
509         .release_tx_desc = dwmac100_release_tx_desc,
510         .prepare_tx_desc = dwmac100_prepare_tx_desc,
511         .clear_tx_ic = dwmac100_clear_tx_ic,
512         .close_tx_desc = dwmac100_close_tx_desc,
513         .get_tx_ls = dwmac100_get_tx_ls,
514         .set_tx_owner = dwmac100_set_tx_owner,
515         .set_rx_owner = dwmac100_set_rx_owner,
516         .get_rx_frame_len = dwmac100_get_rx_frame_len,
517 };
518
519 struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
520 {
521         struct mac_device_info *mac;
522
523         mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
524
525         pr_info("\tDWMAC100\n");
526
527         mac->mac = &dwmac100_ops;
528         mac->desc = &dwmac100_desc_ops;
529         mac->dma = &dwmac100_dma_ops;
530
531         mac->pmt = PMT_NOT_SUPPORTED;
532         mac->link.port = MAC_CONTROL_PS;
533         mac->link.duplex = MAC_CONTROL_F;
534         mac->link.speed = 0;
535         mac->mii.addr = MAC_MII_ADDR;
536         mac->mii.data = MAC_MII_DATA;
537
538         return mac;
539 }