stmmac: rename mac100 as dwmac100 and fix spare coding style
[pandora-kernel.git] / 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/netdevice.h>
30 #include <linux/crc32.h>
31 #include <linux/mii.h>
32 #include <linux/phy.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
46 static 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
58 static 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
94 static 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.*/
121 static 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
138 static 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. */
156 static 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
186 static 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
223 static 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. */
232 static 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_lenght++;
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
283 static void dwmac100_irq_status(unsigned long ioaddr)
284 {
285         return;
286 }
287
288 static 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
294 static 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
300 static 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 ((dev->mc_count > 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 (dev->mc_count == 0) {        /* no multicast */
316                 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
317                            MAC_CONTROL_HO | MAC_CONTROL_HP);
318         } else {
319                 int i;
320                 u32 mc_filter[2];
321                 struct dev_mc_list *mclist;
322
323                 /* Perfect filter mode for physical address and Hash
324                    filter for multicast */
325                 value |= MAC_CONTROL_HP;
326                 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR |
327                            MAC_CONTROL_IF | MAC_CONTROL_HO);
328
329                 memset(mc_filter, 0, sizeof(mc_filter));
330                 for (i = 0, mclist = dev->mc_list;
331                      mclist && i < dev->mc_count; i++, mclist = mclist->next) {
332                         /* The upper 6 bits of the calculated CRC are used to
333                          * index the contens of the hash table */
334                         int bit_nr =
335                             ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
336                         /* The most significant bit determines the register to
337                          * use (H/L) while the other 5 bits determine the bit
338                          * within the register. */
339                         mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
340                 }
341                 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
342                 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
343         }
344
345         writel(value, ioaddr + MAC_CONTROL);
346
347         DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
348             "HI 0x%08x, LO 0x%08x\n",
349             __func__, readl(ioaddr + MAC_CONTROL),
350             readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
351         return;
352 }
353
354 static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
355                              unsigned int fc, unsigned int pause_time)
356 {
357         unsigned int flow = MAC_FLOW_CTRL_ENABLE;
358
359         if (duplex)
360                 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
361         writel(flow, ioaddr + MAC_FLOW_CTRL);
362
363         return;
364 }
365
366 /* No PMT module supported for this Ethernet Controller.
367  * Tested on ST platforms only.
368  */
369 static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode)
370 {
371         return;
372 }
373
374 static void dwmac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
375                                 int disable_rx_ic)
376 {
377         int i;
378         for (i = 0; i < ring_size; i++) {
379                 p->des01.rx.own = 1;
380                 p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
381                 if (i == ring_size - 1)
382                         p->des01.rx.end_ring = 1;
383                 if (disable_rx_ic)
384                         p->des01.rx.disable_ic = 1;
385                 p++;
386         }
387         return;
388 }
389
390 static void dwmac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
391 {
392         int i;
393         for (i = 0; i < ring_size; i++) {
394                 p->des01.tx.own = 0;
395                 if (i == ring_size - 1)
396                         p->des01.tx.end_ring = 1;
397                 p++;
398         }
399         return;
400 }
401
402 static int dwmac100_get_tx_owner(struct dma_desc *p)
403 {
404         return p->des01.tx.own;
405 }
406
407 static int dwmac100_get_rx_owner(struct dma_desc *p)
408 {
409         return p->des01.rx.own;
410 }
411
412 static void dwmac100_set_tx_owner(struct dma_desc *p)
413 {
414         p->des01.tx.own = 1;
415 }
416
417 static void dwmac100_set_rx_owner(struct dma_desc *p)
418 {
419         p->des01.rx.own = 1;
420 }
421
422 static int dwmac100_get_tx_ls(struct dma_desc *p)
423 {
424         return p->des01.tx.last_segment;
425 }
426
427 static void dwmac100_release_tx_desc(struct dma_desc *p)
428 {
429         int ter = p->des01.tx.end_ring;
430
431         /* clean field used within the xmit */
432         p->des01.tx.first_segment = 0;
433         p->des01.tx.last_segment = 0;
434         p->des01.tx.buffer1_size = 0;
435
436         /* clean status reported */
437         p->des01.tx.error_summary = 0;
438         p->des01.tx.underflow_error = 0;
439         p->des01.tx.no_carrier = 0;
440         p->des01.tx.loss_carrier = 0;
441         p->des01.tx.excessive_deferral = 0;
442         p->des01.tx.excessive_collisions = 0;
443         p->des01.tx.late_collision = 0;
444         p->des01.tx.heartbeat_fail = 0;
445         p->des01.tx.deferred = 0;
446
447         /* set termination field */
448         p->des01.tx.end_ring = ter;
449
450         return;
451 }
452
453 static void dwmac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
454                                    int csum_flag)
455 {
456         p->des01.tx.first_segment = is_fs;
457         p->des01.tx.buffer1_size = len;
458 }
459
460 static void dwmac100_clear_tx_ic(struct dma_desc *p)
461 {
462         p->des01.tx.interrupt = 0;
463 }
464
465 static void dwmac100_close_tx_desc(struct dma_desc *p)
466 {
467         p->des01.tx.last_segment = 1;
468         p->des01.tx.interrupt = 1;
469 }
470
471 static int dwmac100_get_rx_frame_len(struct dma_desc *p)
472 {
473         return p->des01.rx.frame_length;
474 }
475
476 struct stmmac_ops dwmac100_ops = {
477         .core_init = dwmac100_core_init,
478         .dump_regs = dwmac100_dump_mac_regs,
479         .host_irq_status = dwmac100_irq_status,
480         .set_filter = dwmac100_set_filter,
481         .flow_ctrl = dwmac100_flow_ctrl,
482         .pmt = dwmac100_pmt,
483         .set_umac_addr = dwmac100_set_umac_addr,
484         .get_umac_addr = dwmac100_get_umac_addr,
485 };
486
487 struct stmmac_dma_ops dwmac100_dma_ops = {
488         .init = dwmac100_dma_init,
489         .dump_regs = dwmac100_dump_dma_regs,
490         .dma_mode = dwmac100_dma_operation_mode,
491         .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
492         .enable_dma_transmission = dwmac_enable_dma_transmission,
493         .enable_dma_irq = dwmac_enable_dma_irq,
494         .disable_dma_irq = dwmac_disable_dma_irq,
495         .start_tx = dwmac_dma_start_tx,
496         .stop_tx = dwmac_dma_stop_tx,
497         .start_rx = dwmac_dma_start_rx,
498         .stop_rx = dwmac_dma_stop_rx,
499         .dma_interrupt = dwmac_dma_interrupt,
500 };
501
502 struct stmmac_desc_ops dwmac100_desc_ops = {
503         .tx_status = dwmac100_get_tx_frame_status,
504         .rx_status = dwmac100_get_rx_frame_status,
505         .get_tx_len = dwmac100_get_tx_len,
506         .init_rx_desc = dwmac100_init_rx_desc,
507         .init_tx_desc = dwmac100_init_tx_desc,
508         .get_tx_owner = dwmac100_get_tx_owner,
509         .get_rx_owner = dwmac100_get_rx_owner,
510         .release_tx_desc = dwmac100_release_tx_desc,
511         .prepare_tx_desc = dwmac100_prepare_tx_desc,
512         .clear_tx_ic = dwmac100_clear_tx_ic,
513         .close_tx_desc = dwmac100_close_tx_desc,
514         .get_tx_ls = dwmac100_get_tx_ls,
515         .set_tx_owner = dwmac100_set_tx_owner,
516         .set_rx_owner = dwmac100_set_rx_owner,
517         .get_rx_frame_len = dwmac100_get_rx_frame_len,
518 };
519
520 struct mac_device_info *dwmac100_setup(unsigned long ioaddr)
521 {
522         struct mac_device_info *mac;
523
524         mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
525
526         pr_info("\tDWMAC100\n");
527
528         mac->mac = &dwmac100_ops;
529         mac->desc = &dwmac100_desc_ops;
530         mac->dma = &dwmac100_dma_ops;
531
532         mac->pmt = PMT_NOT_SUPPORTED;
533         mac->link.port = MAC_CONTROL_PS;
534         mac->link.duplex = MAC_CONTROL_F;
535         mac->link.speed = 0;
536         mac->mii.addr = MAC_MII_ADDR;
537         mac->mii.data = MAC_MII_DATA;
538
539         return mac;
540 }