finally move buildroot-ng to trunk
[openwrt.git] / target / linux / rb532-2.6 / patches / 110-korina_ethernet.patch
1 diff -urN linux.old/drivers/net/Kconfig linux.dev/drivers/net/Kconfig
2 --- linux.old/drivers/net/Kconfig       2006-06-08 20:21:20.000000000 +0200
3 +++ linux.dev/drivers/net/Kconfig       2006-06-08 20:19:40.000000000 +0200
4 @@ -310,6 +310,13 @@
5  
6  source "drivers/net/arm/Kconfig"
7  
8 +config KORINA
9 +       tristate "Korina Local Ethernet support"
10 +       depends on NET_ETHERNET && ( IDT_EB434 || MIKROTIK_RB500)
11 +       help
12 +       IDT RC32434 has one local ethernet port. Say Y here to enable it.
13 +       To compile this driver as a module, choose M here.
14 +
15  config MACE
16         tristate "MACE (Power Mac ethernet) support"
17         depends on NET_ETHERNET && PPC_PMAC && PPC32
18 diff -urN linux.old/drivers/net/korina.c linux.dev/drivers/net/korina.c
19 --- linux.old/drivers/net/korina.c      1970-01-01 01:00:00.000000000 +0100
20 +++ linux.dev/drivers/net/korina.c      2006-06-09 00:48:40.000000000 +0200
21 @@ -0,0 +1,1159 @@
22 +/**************************************************************************
23 + *
24 + *  BRIEF MODULE DESCRIPTION
25 + *     Driver for the IDT RC32434 on-chip ethernet controller.
26 + *
27 + *  Copyright 2004 IDT Inc. (rischelp@idt.com)
28 + *         
29 + *  This program is free software; you can redistribute  it and/or modify it
30 + *  under  the terms of  the GNU General  Public License as published by the
31 + *  Free Software Foundation;  either version 2 of the  License, or (at your
32 + *  option) any later version.
33 + *
34 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
35 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
36 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
37 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
38 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
39 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
40 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
42 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 + *
45 + *  You should have received a copy of the  GNU General Public License along
46 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
47 + *  675 Mass Ave, Cambridge, MA 02139, USA.
48 + *
49 + *
50 + **************************************************************************
51 + * May 2004 rkt, neb
52 + *
53 + * Based on the driver developed by B. Maruthanayakam, H. Kou and others.
54 + *
55 + * Aug 2004 Sadik
56 + *
57 + * Added NAPI
58 + *
59 + **************************************************************************
60 + */
61 +
62 +#include <linux/config.h>
63 +#include <linux/module.h>
64 +#include <linux/kernel.h>
65 +#include <linux/moduleparam.h>
66 +#include <linux/sched.h>
67 +#include <linux/ctype.h>
68 +#include <linux/types.h>
69 +#include <linux/fcntl.h>
70 +#include <linux/interrupt.h>
71 +#include <linux/ptrace.h>
72 +#include <linux/init.h>
73 +#include <linux/ioport.h>
74 +#include <linux/proc_fs.h>
75 +#include <linux/in.h>
76 +#include <linux/slab.h>
77 +#include <linux/string.h>
78 +#include <linux/delay.h>
79 +#include <linux/netdevice.h>
80 +#include <linux/etherdevice.h>
81 +#include <linux/skbuff.h>
82 +#include <linux/errno.h>
83 +#include <linux/platform_device.h>
84 +#include <asm/bootinfo.h>
85 +#include <asm/system.h>
86 +#include <asm/bitops.h>
87 +#include <asm/pgtable.h>
88 +#include <asm/segment.h>
89 +#include <asm/io.h>
90 +#include <asm/dma.h>
91 +
92 +#include <asm/rc32434/rb.h>
93 +#include "rc32434_eth.h"
94 +
95 +#define DRIVER_VERSION "(mar2904)"
96 +
97 +#define DRIVER_NAME "rc32434 Ethernet driver. " DRIVER_VERSION
98 +
99 +#define STATION_ADDRESS_HIGH(dev) (((dev)->dev_addr[0] << 8) | \
100 +                                  ((dev)->dev_addr[1]))
101 +#define STATION_ADDRESS_LOW(dev)  (((dev)->dev_addr[2] << 24) | \
102 +                                  ((dev)->dev_addr[3] << 16) | \
103 +                                  ((dev)->dev_addr[4] << 8)  | \
104 +                                  ((dev)->dev_addr[5]))
105 +
106 +#define MII_CLOCK 1250000                              /* no more than 2.5MHz */
107 +#define CONFIG_IDT_USE_NAPI 1
108 +
109 +
110 +static inline void rc32434_abort_tx(struct net_device *dev)
111 +{
112 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
113 +       rc32434_abort_dma(dev, lp->tx_dma_regs);
114 +       
115 +}
116 +
117 +static inline void rc32434_abort_rx(struct net_device *dev)
118 +{
119 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
120 +       rc32434_abort_dma(dev, lp->rx_dma_regs);
121 +       
122 +}
123 +
124 +static inline void rc32434_start_tx(struct rc32434_local *lp,  volatile DMAD_t td)
125 +{
126 +       rc32434_start_dma(lp->tx_dma_regs, CPHYSADDR(td));
127 +}
128 +
129 +static inline void rc32434_start_rx(struct rc32434_local *lp, volatile DMAD_t rd)
130 +{
131 +       rc32434_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
132 +}
133 +
134 +static inline void rc32434_chain_tx(struct rc32434_local *lp, volatile DMAD_t td)
135 +{
136 +       rc32434_chain_dma(lp->tx_dma_regs, CPHYSADDR(td));
137 +}
138 +
139 +static inline void rc32434_chain_rx(struct rc32434_local *lp, volatile DMAD_t rd)
140 +{
141 +       rc32434_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
142 +}
143 +
144 +#ifdef RC32434_PROC_DEBUG
145 +static int rc32434_read_proc(char *buf, char **start, off_t fpos,
146 +                            int length, int *eof, void *data)
147 +{
148 +       struct net_device *dev = (struct net_device *)data;
149 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
150 +       int len = 0;
151 +       
152 +       /* print out header */
153 +       len += sprintf(buf + len, "\n\tKorina Ethernet Debug\n\n");
154 +       len += sprintf (buf + len,
155 +                       "DMA halt count      = %10d, DMA run count = %10d\n",
156 +                       lp->dma_halt_cnt, lp->dma_run_cnt);
157 +       
158 +       if (fpos >= len) {
159 +               *start = buf;
160 +               *eof = 1;
161 +               return 0;
162 +       }
163 +       *start = buf + fpos;
164 +       
165 +       if ((len -= fpos) > length) 
166 +               return length;  
167 +       *eof = 1;
168 +       
169 +       return len;
170 +       
171 +}
172 +#endif
173 +
174 +
175 +/*
176 + * Restart the RC32434 ethernet controller. 
177 + */
178 +static int rc32434_restart(struct net_device *dev)
179 +{
180 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
181 +       
182 +       /*
183 +        * Disable interrupts
184 +        */
185 +       disable_irq(lp->rx_irq);
186 +       disable_irq(lp->tx_irq);
187 +#ifdef RC32434_REVISION
188 +       disable_irq(lp->ovr_irq);
189 +#endif 
190 +       disable_irq(lp->und_irq);
191 +       
192 +       /* Mask F E bit in Tx DMA */
193 +       __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) | DMASM_f_m | DMASM_e_m, &lp->tx_dma_regs->dmasm);
194 +       /* Mask D H E bit in Rx DMA */
195 +       __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) | DMASM_d_m | DMASM_h_m | DMASM_e_m, &lp->rx_dma_regs->dmasm);
196 +       
197 +       rc32434_init(dev);
198 +       rc32434_multicast_list(dev);
199 +       
200 +       enable_irq(lp->und_irq);
201 +#ifdef RC32434_REVISION
202 +       enable_irq(lp->ovr_irq);
203 +#endif
204 +       enable_irq(lp->tx_irq);
205 +       enable_irq(lp->rx_irq);
206 +       
207 +       return 0;
208 +}
209 +
210 +static int rc32434_probe(struct platform_device *pdev)
211 +{
212 +       struct korina_device *bif = (struct korina_device *) pdev->dev.platform_data;
213 +       struct rc32434_local *lp = NULL;
214 +       struct net_device *dev = NULL;
215 +       struct resource *r;
216 +       int i, retval,err;
217 +       
218 +       dev = alloc_etherdev(sizeof(struct rc32434_local));
219 +       if(!dev) {
220 +               ERR("Korina_eth: alloc_etherdev failed\n");
221 +               return -1;
222 +       }
223 +
224 +       platform_set_drvdata(pdev, dev);
225 +       SET_MODULE_OWNER(dev);
226 +       bif->dev = dev;
227 +       
228 +       memcpy(dev->dev_addr, bif->mac, 6);
229 +
230 +       /* Initialize the device structure. */
231 +       if (dev->priv == NULL) {
232 +               lp = (struct rc32434_local *)kmalloc(sizeof(*lp), GFP_KERNEL);
233 +               memset(lp, 0, sizeof(struct rc32434_local));
234 +       } 
235 +       else {
236 +               lp = (struct rc32434_local *)dev->priv;
237 +       }
238 +       
239 +       lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
240 +       lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
241 +       lp->ovr_irq = platform_get_irq_byname(pdev, "korina_ovr");
242 +       lp->und_irq = platform_get_irq_byname(pdev, "korina_und");
243 +
244 +       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
245 +       dev->base_addr = r->start;
246 +       lp->eth_regs = ioremap_nocache(r->start, r->end - r->start);
247 +       if (!lp->eth_regs) {
248 +               ERR("Can't remap eth registers\n");
249 +               retval = -ENXIO;
250 +               goto probe_err_out;
251 +       }
252 +
253 +       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
254 +       lp->rx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
255 +       if (!lp->rx_dma_regs) {
256 +               ERR("Can't remap Rx DMA registers\n");
257 +               retval = -ENXIO;
258 +               goto probe_err_out;
259 +       }
260 +
261 +       r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
262 +       lp->tx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
263 +       if (!lp->tx_dma_regs) {
264 +               ERR("Can't remap Tx DMA registers\n");
265 +               retval = -ENXIO;
266 +               goto probe_err_out;
267 +       }
268 +       
269 +#ifdef RC32434_PROC_DEBUG
270 +       lp->ps = create_proc_read_entry (bif->name, 0, proc_net,
271 +                                        rc32434_read_proc, dev);
272 +#endif
273 +       
274 +       lp->td_ring =   (DMAD_t)kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
275 +       if (!lp->td_ring) {
276 +               ERR("Can't allocate descriptors\n");
277 +               retval = -ENOMEM;
278 +               goto probe_err_out;
279 +       }
280 +       
281 +       dma_cache_inv((unsigned long)(lp->td_ring), TD_RING_SIZE + RD_RING_SIZE);
282 +       
283 +       /* now convert TD_RING pointer to KSEG1 */
284 +       lp->td_ring = (DMAD_t )KSEG1ADDR(lp->td_ring);
285 +       lp->rd_ring = &lp->td_ring[RC32434_NUM_TDS];
286 +       
287 +       
288 +       spin_lock_init(&lp->lock);
289 +       
290 +       /* just use the rx dma irq */
291 +       dev->irq = lp->rx_irq;
292 +       
293 +       dev->priv = lp;
294 +       
295 +       dev->open = rc32434_open;
296 +       dev->stop = rc32434_close;
297 +       dev->hard_start_xmit = rc32434_send_packet;
298 +       dev->get_stats  = rc32434_get_stats;
299 +       dev->set_multicast_list = &rc32434_multicast_list;
300 +       dev->tx_timeout = rc32434_tx_timeout;
301 +       dev->watchdog_timeo = RC32434_TX_TIMEOUT;
302 +
303 +#ifdef CONFIG_IDT_USE_NAPI
304 +       dev->poll = rc32434_poll;
305 +       dev->weight = 64;
306 +       printk("Using NAPI with weight %d\n",dev->weight);
307 +#else
308 +       lp->rx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
309 +       tasklet_init(lp->rx_tasklet, rc32434_rx_tasklet, (unsigned long)dev);
310 +#endif
311 +       lp->tx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
312 +       tasklet_init(lp->tx_tasklet, rc32434_tx_tasklet, (unsigned long)dev);
313 +       
314 +       if ((err = register_netdev(dev))) {
315 +               printk(KERN_ERR "rc32434 ethernet. Cannot register net device %d\n", err);
316 +               free_netdev(dev);
317 +               retval = -EINVAL;
318 +               goto probe_err_out;
319 +       }
320 +       
321 +       INFO("Rx IRQ %d, Tx IRQ %d, ", lp->rx_irq, lp->tx_irq);
322 +       for (i = 0; i < 6; i++) {
323 +               printk("%2.2x", dev->dev_addr[i]);
324 +               if (i<5)
325 +                       printk(":");
326 +       }
327 +       printk("\n");
328 +       
329 +       return 0;
330 +       
331 + probe_err_out:
332 +       rc32434_cleanup_module();
333 +       ERR(" failed.  Returns %d\n", retval);
334 +       return retval;
335 +       
336 +}
337 +
338 +static int rc32434_remove(struct platform_device *pdev)
339 +{
340 +       struct korina_device *bif = (struct korina_device *) pdev->dev.platform_data;
341 +       
342 +       if (bif->dev != NULL) {
343 +               struct rc32434_local *lp = (struct rc32434_local *)bif->dev->priv;
344 +               if (lp != NULL) {
345 +                       if (lp->eth_regs)
346 +                               iounmap((void*)lp->eth_regs);
347 +                       if (lp->rx_dma_regs)
348 +                               iounmap((void*)lp->rx_dma_regs);
349 +                       if (lp->tx_dma_regs)
350 +                               iounmap((void*)lp->tx_dma_regs);
351 +                       if (lp->td_ring)
352 +                               kfree((void*)KSEG0ADDR(lp->td_ring));
353 +                       
354 +#ifdef RC32434_PROC_DEBUG
355 +                       if (lp->ps) {
356 +                               remove_proc_entry(bif->name, proc_net);
357 +                       }
358 +#endif
359 +                       kfree(lp);
360 +               }
361 +               
362 +               platform_set_drvdata(pdev, NULL);
363 +               unregister_netdev(bif->dev);
364 +               free_netdev(bif->dev);
365 +               kfree(bif->dev);
366 +       }
367 +       return 0;
368 +}
369 +
370 +
371 +static int rc32434_open(struct net_device *dev)
372 +{
373 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
374 +       
375 +       /* Initialize */
376 +       if (rc32434_init(dev)) {
377 +               ERR("Error: cannot open the Ethernet device\n");
378 +               return -EAGAIN;
379 +       }
380 +       
381 +       /* Install the interrupt handler that handles the Done Finished Ovr and Und Events */   
382 +       if (request_irq(lp->rx_irq, &rc32434_rx_dma_interrupt,
383 +                 SA_SHIRQ | SA_INTERRUPT,
384 +                       "Korina ethernet Rx", dev)) {
385 +               ERR(": unable to get Rx DMA IRQ %d\n",
386 +                   lp->rx_irq);
387 +               return -EAGAIN;
388 +       }
389 +       if (request_irq(lp->tx_irq, &rc32434_tx_dma_interrupt,
390 +                 SA_SHIRQ | SA_INTERRUPT,
391 +                       "Korina ethernet Tx", dev)) {
392 +               ERR(": unable to get Tx DMA IRQ %d\n",
393 +                   lp->tx_irq);
394 +               free_irq(lp->rx_irq, dev);
395 +               return -EAGAIN;
396 +       }
397 +       
398 +#ifdef RC32434_REVISION
399 +       /* Install handler for overrun error. */
400 +       if (request_irq(lp->ovr_irq, &rc32434_ovr_interrupt,
401 +                       SA_SHIRQ | SA_INTERRUPT,
402 +                       "Ethernet Overflow", dev)) {
403 +               ERR(": unable to get OVR IRQ %d\n",
404 +                   lp->ovr_irq);
405 +               free_irq(lp->rx_irq, dev);
406 +               free_irq(lp->tx_irq, dev);
407 +               return -EAGAIN;
408 +       }
409 +#endif
410 +       
411 +       /* Install handler for underflow error. */
412 +       if (request_irq(lp->und_irq, &rc32434_und_interrupt,
413 +                       SA_SHIRQ | SA_INTERRUPT,
414 +                       "Ethernet Underflow", dev)) {
415 +               ERR(": unable to get UND IRQ %d\n",
416 +                   lp->und_irq);
417 +               free_irq(lp->rx_irq, dev);
418 +               free_irq(lp->tx_irq, dev);
419 +#ifdef RC32434_REVISION                
420 +               free_irq(lp->ovr_irq, dev);             
421 +#endif
422 +               return -EAGAIN;
423 +       }
424 +       
425 +       
426 +       return 0;
427 +}
428 +
429 +
430 +
431 +
432 +static int rc32434_close(struct net_device *dev)
433 +{
434 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
435 +       u32 tmp;
436 +       
437 +       /* Disable interrupts */
438 +       disable_irq(lp->rx_irq);
439 +       disable_irq(lp->tx_irq);
440 +#ifdef RC32434_REVISION
441 +       disable_irq(lp->ovr_irq);
442 +#endif
443 +       disable_irq(lp->und_irq);
444 +       
445 +       tmp = __raw_readl(&lp->tx_dma_regs->dmasm);
446 +       tmp = tmp | DMASM_f_m | DMASM_e_m;
447 +       __raw_writel(tmp, &lp->tx_dma_regs->dmasm);
448 +       
449 +       tmp = __raw_readl(&lp->rx_dma_regs->dmasm);
450 +       tmp = tmp | DMASM_d_m | DMASM_h_m | DMASM_e_m;
451 +       __raw_writel(tmp, &lp->rx_dma_regs->dmasm);
452 +       
453 +       free_irq(lp->rx_irq, dev);
454 +       free_irq(lp->tx_irq, dev);
455 +#ifdef RC32434_REVISION        
456 +       free_irq(lp->ovr_irq, dev);
457 +#endif
458 +       free_irq(lp->und_irq, dev);
459 +       return 0;
460 +}
461 +
462 +
463 +/* transmit packet */
464 +static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev)
465 +{
466 +       struct rc32434_local            *lp = (struct rc32434_local *)dev->priv;
467 +       unsigned long                   flags;
468 +       u32                                     length;
469 +       DMAD_t                          td;
470 +       
471 +       
472 +       spin_lock_irqsave(&lp->lock, flags);
473 +       
474 +       td = &lp->td_ring[lp->tx_chain_tail];
475 +       
476 +       /* stop queue when full, drop pkts if queue already full */
477 +       if(lp->tx_count >= (RC32434_NUM_TDS - 2)) {
478 +               lp->tx_full = 1;
479 +               
480 +               if(lp->tx_count == (RC32434_NUM_TDS - 2)) {
481 +                       netif_stop_queue(dev);
482 +               }
483 +               else {
484 +                       lp->stats.tx_dropped++;
485 +                       dev_kfree_skb_any(skb);
486 +                       spin_unlock_irqrestore(&lp->lock, flags);
487 +                       return 1;
488 +               }          
489 +       }        
490 +       
491 +       lp->tx_count ++;
492 +       
493 +       lp->tx_skb[lp->tx_chain_tail] = skb;
494 +       
495 +       length = skb->len;
496 +       
497 +       /* Setup the transmit descriptor. */
498 +       td->ca = CPHYSADDR(skb->data);
499 +       
500 +       if(__raw_readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
501 +               if( lp->tx_chain_status == empty ) {
502 +                       td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m;                                /*  Update tail      */
503 +                       lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK;                          /*   Move tail       */
504 +                       __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR    */
505 +                       lp->tx_chain_head = lp->tx_chain_tail;                                                  /* Move head to tail */
506 +               }
507 +               else {
508 +                       td->control = DMA_COUNT(length) |DMAD_cof_m|DMAD_iof_m;                                 /* Update tail */
509 +                       lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &=  ~(DMAD_cof_m);          /* Link to prev */
510 +                       lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link =  CPHYSADDR(td);              /* Link to prev */
511 +                       lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK;                          /* Move tail */
512 +                       __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */
513 +                       lp->tx_chain_head = lp->tx_chain_tail;                                                  /* Move head to tail */
514 +                       lp->tx_chain_status = empty;
515 +               }
516 +       }
517 +       else {
518 +               if( lp->tx_chain_status == empty ) {
519 +                       td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m;                                /* Update tail */
520 +                       lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK;                          /* Move tail */
521 +                       lp->tx_chain_status = filled;
522 +               }
523 +               else {
524 +                       td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m;                                /* Update tail */
525 +                       lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &=  ~(DMAD_cof_m);          /* Link to prev */
526 +                       lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link =  CPHYSADDR(td);              /* Link to prev */
527 +                       lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK;                          /* Move tail */
528 +               }
529 +       }
530 +       
531 +       dev->trans_start = jiffies;                             
532 +       
533 +       spin_unlock_irqrestore(&lp->lock, flags);
534 +       
535 +       return 0;
536 +}
537 +
538 +
539 +/* Ethernet MII-PHY Handler */
540 +static void rc32434_mii_handler(unsigned long data)
541 +{
542 +       struct net_device *dev = (struct net_device *)data;             
543 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
544 +       unsigned long   flags;
545 +       unsigned long duplex_status;
546 +       int port_addr = (lp->rx_irq == 0x2c? 1:0) << 8;
547 +       
548 +       spin_lock_irqsave(&lp->lock, flags);
549 +       
550 +       /* Two ports are using the same MII, the difference is the PHY address */
551 +       __raw_writel(0, &rc32434_eth0_regs->miimcfg);  
552 +       __raw_writel(0, &rc32434_eth0_regs->miimcmd);  
553 +       __raw_writel(port_addr |0x05, &rc32434_eth0_regs->miimaddr);  
554 +       __raw_writel(MIIMCMD_scn_m, &rc32434_eth0_regs->miimcmd);  
555 +       while(__raw_readl(&rc32434_eth0_regs->miimind) & MIIMIND_nv_m);
556 +       
557 +       ERR("irq:%x             port_addr:%x    RDD:%x\n", 
558 +           lp->rx_irq, port_addr, __raw_readl(&rc32434_eth0_regs->miimrdd));
559 +       duplex_status = (__raw_readl(&rc32434_eth0_regs->miimrdd) & 0x140)? ETHMAC2_fd_m: 0;
560 +       if(duplex_status != lp->duplex_mode) {
561 +               ERR("The MII-PHY is Auto-negotiated to %s-Duplex mode for Eth-%x\n", duplex_status? "Full":"Half", lp->rx_irq == 0x2c? 1:0);            
562 +               lp->duplex_mode = duplex_status;
563 +               rc32434_restart(dev);           
564 +       }
565 +       
566 +       lp->mii_phy_timer.expires = jiffies + 10 * HZ;  
567 +       add_timer(&lp->mii_phy_timer);
568 +       
569 +       spin_unlock_irqrestore(&lp->lock, flags);
570 +       
571 +}
572 +
573 +#ifdef RC32434_REVISION        
574 +/* Ethernet Rx Overflow interrupt */
575 +static irqreturn_t
576 +rc32434_ovr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
577 +{
578 +       struct net_device *dev = (struct net_device *)dev_id;
579 +       struct rc32434_local *lp;
580 +       unsigned int ovr;
581 +       irqreturn_t retval = IRQ_NONE;
582 +       
583 +       ASSERT(dev != NULL);
584 +       
585 +       lp = (struct rc32434_local *)dev->priv;
586 +       spin_lock(&lp->lock);
587 +       ovr = __raw_readl(&lp->eth_regs->ethintfc);
588 +       
589 +       if(ovr & ETHINTFC_ovr_m) {
590 +               netif_stop_queue(dev);
591 +               
592 +               /* clear OVR bit */
593 +               __raw_writel((ovr & ~ETHINTFC_ovr_m), &lp->eth_regs->ethintfc);
594 +               
595 +               /* Restart interface */
596 +               rc32434_restart(dev);
597 +               retval = IRQ_HANDLED;
598 +       }
599 +       spin_unlock(&lp->lock);
600 +       
601 +       return retval;
602 +}
603 +
604 +#endif
605 +
606 +
607 +/* Ethernet Tx Underflow interrupt */
608 +static irqreturn_t
609 +rc32434_und_interrupt(int irq, void *dev_id, struct pt_regs * regs)
610 +{
611 +       struct net_device *dev = (struct net_device *)dev_id;
612 +       struct rc32434_local *lp;
613 +       unsigned int und;
614 +       irqreturn_t retval = IRQ_NONE;
615 +       
616 +       ASSERT(dev != NULL);
617 +       
618 +       lp = (struct rc32434_local *)dev->priv;
619 +       
620 +       spin_lock(&lp->lock);
621 +       
622 +       und = __raw_readl(&lp->eth_regs->ethintfc);
623 +       
624 +       if(und & ETHINTFC_und_m) {
625 +               netif_stop_queue(dev);
626 +               
627 +               __raw_writel((und & ~ETHINTFC_und_m), &lp->eth_regs->ethintfc);
628 +               
629 +               /* Restart interface */
630 +               rc32434_restart(dev);
631 +               retval = IRQ_HANDLED;
632 +       }
633 +       
634 +       spin_unlock(&lp->lock);
635 +       
636 +       return retval;
637 +}
638 +
639 +
640 +/* Ethernet Rx DMA interrupt */
641 +static irqreturn_t
642 +rc32434_rx_dma_interrupt(int irq, void *dev_id, struct pt_regs * regs)
643 +{
644 +       struct net_device *dev = (struct net_device *)dev_id;
645 +       struct rc32434_local* lp;
646 +       volatile u32 dmas,dmasm;
647 +       irqreturn_t retval;
648 +       
649 +       ASSERT(dev != NULL);
650 +       
651 +       lp = (struct rc32434_local *)dev->priv;
652 +       
653 +       spin_lock(&lp->lock);
654 +       dmas = __raw_readl(&lp->rx_dma_regs->dmas);
655 +       if(dmas & (DMAS_d_m|DMAS_h_m|DMAS_e_m)) {
656 +               /* Mask D H E bit in Rx DMA */
657 +               dmasm = __raw_readl(&lp->rx_dma_regs->dmasm);
658 +               __raw_writel(dmasm | (DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm);
659 +#ifdef CONFIG_IDT_USE_NAPI
660 +               if(netif_rx_schedule_prep(dev))
661 +                        __netif_rx_schedule(dev);
662 +#else
663 +               tasklet_hi_schedule(lp->rx_tasklet);
664 +#endif
665 +               
666 +               if (dmas & DMAS_e_m)
667 +                       ERR(": DMA error\n");
668 +               
669 +               retval = IRQ_HANDLED;
670 +       }
671 +       else
672 +               retval = IRQ_NONE;
673 +       
674 +       spin_unlock(&lp->lock);
675 +       return retval;
676 +}
677 +
678 +#ifdef CONFIG_IDT_USE_NAPI
679 +static int rc32434_poll(struct net_device *rx_data_dev, int *budget)
680 +#else
681 +static void rc32434_rx_tasklet(unsigned long rx_data_dev)
682 +#endif
683 +{
684 +       struct net_device *dev = (struct net_device *)rx_data_dev;      
685 +       struct rc32434_local* lp = netdev_priv(dev);
686 +       volatile DMAD_t  rd = &lp->rd_ring[lp->rx_next_done];
687 +       struct sk_buff *skb, *skb_new;
688 +       u8* pkt_buf;
689 +       u32 devcs, count, pkt_len, pktuncrc_len;
690 +       volatile u32 dmas;
691 +#ifdef CONFIG_IDT_USE_NAPI
692 +       u32 received = 0;
693 +       int rx_work_limit = min(*budget,dev->quota);
694 +#else
695 +       unsigned long   flags;
696 +       spin_lock_irqsave(&lp->lock, flags);
697 +#endif
698 +       
699 +       while ( (count = RC32434_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) {
700 +#ifdef CONFIG_IDT_USE_NAPI
701 +               if(--rx_work_limit <0)
702 +                {
703 +                        break;
704 +                }
705 +#endif
706 +               /* init the var. used for the later operations within the while loop */
707 +               skb_new = NULL;
708 +               devcs = rd->devcs;
709 +               pkt_len = RCVPKT_LENGTH(devcs);
710 +               skb = lp->rx_skb[lp->rx_next_done];
711 +      
712 +               if (count < 64) {
713 +                       lp->stats.rx_errors++;
714 +                       lp->stats.rx_dropped++;                 
715 +               }
716 +               else if ((devcs & ( ETHRX_ld_m)) !=     ETHRX_ld_m) {
717 +                       /* check that this is a whole packet */
718 +                       /* WARNING: DMA_FD bit incorrectly set in Rc32434 (errata ref #077) */
719 +                       lp->stats.rx_errors++;
720 +                       lp->stats.rx_dropped++;
721 +               }
722 +               else if ( (devcs & ETHRX_rok_m)  ) {
723 +                       
724 +                       {
725 +                               /* must be the (first and) last descriptor then */
726 +                               pkt_buf = (u8*)lp->rx_skb[lp->rx_next_done]->data;
727 +                               
728 +                               pktuncrc_len = pkt_len - 4;
729 +                               /* invalidate the cache */
730 +                               dma_cache_inv((unsigned long)pkt_buf, pktuncrc_len);
731 +                               
732 +                               /* Malloc up new buffer. */                                       
733 +                               skb_new = dev_alloc_skb(RC32434_RBSIZE + 2);                                                    
734 +                               
735 +                               if (skb_new != NULL){
736 +                                       /* Make room */
737 +                                       skb_put(skb, pktuncrc_len);                 
738 +                                       
739 +                                       skb->protocol = eth_type_trans(skb, dev);
740 +                                       
741 +                                       /* pass the packet to upper layers */
742 +#ifdef CONFIG_IDT_USE_NAPI
743 +                                       netif_receive_skb(skb);
744 +#else
745 +                                       netif_rx(skb);
746 +#endif
747 +                                       
748 +                                       dev->last_rx = jiffies;
749 +                                       lp->stats.rx_packets++;
750 +                                       lp->stats.rx_bytes += pktuncrc_len;
751 +                                       
752 +                                       if (IS_RCV_MP(devcs))
753 +                                               lp->stats.multicast++;
754 +                                       
755 +                                       /* 16 bit align */                                                
756 +                                       skb_reserve(skb_new, 2);        
757 +                                       
758 +                                       skb_new->dev = dev;
759 +                                       lp->rx_skb[lp->rx_next_done] = skb_new;
760 +                               }
761 +                               else {
762 +                                       ERR("no memory, dropping rx packet.\n");
763 +                                       lp->stats.rx_errors++;          
764 +                                       lp->stats.rx_dropped++;                                 
765 +                               }
766 +                       }
767 +                       
768 +               }                       
769 +               else {
770 +                       /* This should only happen if we enable accepting broken packets */
771 +                       lp->stats.rx_errors++;
772 +                       lp->stats.rx_dropped++;
773 +                       
774 +                       /* add statistics counters */
775 +                       if (IS_RCV_CRC_ERR(devcs)) {
776 +                               DBG(2, "RX CRC error\n");
777 +                               lp->stats.rx_crc_errors++;
778 +                       } 
779 +                       else if (IS_RCV_LOR_ERR(devcs)) {
780 +                               DBG(2, "RX LOR error\n");
781 +                               lp->stats.rx_length_errors++;
782 +                       }                               
783 +                       else if (IS_RCV_LE_ERR(devcs)) {
784 +                               DBG(2, "RX LE error\n");
785 +                               lp->stats.rx_length_errors++;
786 +                       }
787 +                       else if (IS_RCV_OVR_ERR(devcs)) {
788 +                               lp->stats.rx_over_errors++;
789 +                       }
790 +                       else if (IS_RCV_CV_ERR(devcs)) {
791 +                               /* code violation */
792 +                               DBG(2, "RX CV error\n");
793 +                               lp->stats.rx_frame_errors++;
794 +                       }
795 +                       else if (IS_RCV_CES_ERR(devcs)) {
796 +                               DBG(2, "RX Preamble error\n");
797 +                       }
798 +               }
799 +               
800 +               rd->devcs = 0;
801 +               
802 +               /* restore descriptor's curr_addr */
803 +               if(skb_new)
804 +                       rd->ca = CPHYSADDR(skb_new->data); 
805 +               else
806 +                       rd->ca = CPHYSADDR(skb->data);
807 +               
808 +               rd->control = DMA_COUNT(RC32434_RBSIZE) |DMAD_cod_m |DMAD_iod_m;
809 +               lp->rd_ring[(lp->rx_next_done-1)& RC32434_RDS_MASK].control &=  ~(DMAD_cod_m);  
810 +               
811 +               lp->rx_next_done = (lp->rx_next_done + 1) & RC32434_RDS_MASK;
812 +               rd = &lp->rd_ring[lp->rx_next_done];
813 +               __raw_writel( ~DMAS_d_m, &lp->rx_dma_regs->dmas);
814 +       }       
815 +#ifdef CONFIG_IDT_USE_NAPI
816 +        dev->quota -= received;
817 +        *budget =- received;
818 +        if(rx_work_limit < 0)
819 +                goto not_done;
820 +#endif
821 +       
822 +       dmas = __raw_readl(&lp->rx_dma_regs->dmas);
823 +       
824 +       if(dmas & DMAS_h_m) {
825 +               __raw_writel( ~(DMAS_h_m | DMAS_e_m), &lp->rx_dma_regs->dmas);
826 +#ifdef RC32434_PROC_DEBUG
827 +               lp->dma_halt_cnt++;
828 +#endif
829 +               rd->devcs = 0;
830 +               skb = lp->rx_skb[lp->rx_next_done];
831 +               rd->ca = CPHYSADDR(skb->data);
832 +               rc32434_chain_rx(lp,rd);
833 +       }
834 +       
835 +#ifdef CONFIG_IDT_USE_NAPI
836 +       netif_rx_complete(dev);
837 +#endif
838 +       /* Enable D H E bit in Rx DMA */
839 +       __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m |DMASM_e_m), &lp->rx_dma_regs->dmasm); 
840 +#ifdef CONFIG_IDT_USE_NAPI
841 +       return 0;
842 + not_done:
843 +       return 1;
844 +#else
845 +       spin_unlock_irqrestore(&lp->lock, flags);
846 +       return;
847 +#endif
848 +
849 +       
850 +}      
851 +
852 +
853 +
854 +/* Ethernet Tx DMA interrupt */
855 +static irqreturn_t
856 +rc32434_tx_dma_interrupt(int irq, void *dev_id, struct pt_regs * regs)
857 +{
858 +       struct net_device *dev = (struct net_device *)dev_id;
859 +       struct rc32434_local *lp;
860 +       volatile u32 dmas,dmasm;
861 +       irqreturn_t retval;
862 +       
863 +       ASSERT(dev != NULL);
864 +       
865 +       lp = (struct rc32434_local *)dev->priv;
866 +       
867 +       spin_lock(&lp->lock);
868 +       
869 +       dmas = __raw_readl(&lp->tx_dma_regs->dmas);
870 +       
871 +       if (dmas & (DMAS_f_m | DMAS_e_m)) {
872 +               dmasm = __raw_readl(&lp->tx_dma_regs->dmasm);
873 +               /* Mask F E bit in Tx DMA */
874 +               __raw_writel(dmasm | (DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm);
875 +               
876 +               tasklet_hi_schedule(lp->tx_tasklet);
877 +               
878 +               if(lp->tx_chain_status == filled && (__raw_readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
879 +                       __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr));                 
880 +                       lp->tx_chain_status = empty;
881 +                       lp->tx_chain_head = lp->tx_chain_tail;
882 +                       dev->trans_start = jiffies;
883 +               }
884 +               
885 +               if (dmas & DMAS_e_m)
886 +                       ERR(": DMA error\n");
887 +               
888 +               retval = IRQ_HANDLED;
889 +       }
890 +       else
891 +               retval = IRQ_NONE;
892 +       
893 +       spin_unlock(&lp->lock);
894 +       
895 +       return retval;
896 +}
897 +
898 +
899 +static void rc32434_tx_tasklet(unsigned long tx_data_dev)
900 +{
901 +       struct net_device *dev = (struct net_device *)tx_data_dev;      
902 +       struct rc32434_local* lp = (struct rc32434_local *)dev->priv;
903 +       volatile DMAD_t td = &lp->td_ring[lp->tx_next_done];
904 +       u32 devcs;
905 +       unsigned long   flags;
906 +       volatile u32 dmas;
907 +       
908 +       spin_lock_irqsave(&lp->lock, flags);
909 +       
910 +       /* process all desc that are done */
911 +       while(IS_DMA_FINISHED(td->control)) {
912 +               if(lp->tx_full == 1) {
913 +                       netif_wake_queue(dev);
914 +                       lp->tx_full = 0;
915 +               }
916 +               
917 +               devcs = lp->td_ring[lp->tx_next_done].devcs;    
918 +               if ((devcs & (ETHTX_fd_m | ETHTX_ld_m)) != (ETHTX_fd_m | ETHTX_ld_m)) {
919 +                       lp->stats.tx_errors++;
920 +                       lp->stats.tx_dropped++;                         
921 +                       
922 +                       /* should never happen */
923 +                       DBG(1, __FUNCTION__ ": split tx ignored\n");
924 +               }
925 +               else if (IS_TX_TOK(devcs)) {
926 +                       lp->stats.tx_packets++;
927 +               }
928 +               else {
929 +                       lp->stats.tx_errors++;
930 +                       lp->stats.tx_dropped++;                         
931 +                       
932 +                       /* underflow */
933 +                       if (IS_TX_UND_ERR(devcs)) 
934 +                               lp->stats.tx_fifo_errors++;
935 +                       
936 +                       /* oversized frame */
937 +                       if (IS_TX_OF_ERR(devcs))
938 +                               lp->stats.tx_aborted_errors++;
939 +                       
940 +                       /* excessive deferrals */
941 +                       if (IS_TX_ED_ERR(devcs))
942 +                               lp->stats.tx_carrier_errors++;
943 +                       
944 +                       /* collisions: medium busy */
945 +                       if (IS_TX_EC_ERR(devcs))
946 +                               lp->stats.collisions++;
947 +                       
948 +                       /* late collision */
949 +                       if (IS_TX_LC_ERR(devcs))
950 +                               lp->stats.tx_window_errors++;
951 +                       
952 +               }
953 +               
954 +               /* We must always free the original skb */
955 +               if (lp->tx_skb[lp->tx_next_done] != NULL) {
956 +                       dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]);
957 +                       lp->tx_skb[lp->tx_next_done] = NULL;
958 +               }
959 +               
960 +               lp->td_ring[lp->tx_next_done].control = DMAD_iof_m;
961 +               lp->td_ring[lp->tx_next_done].devcs = ETHTX_fd_m | ETHTX_ld_m;  
962 +               lp->td_ring[lp->tx_next_done].link = 0;
963 +               lp->td_ring[lp->tx_next_done].ca = 0;
964 +               lp->tx_count --;
965 +               
966 +               /* go on to next transmission */
967 +               lp->tx_next_done = (lp->tx_next_done + 1) & RC32434_TDS_MASK;
968 +               td = &lp->td_ring[lp->tx_next_done];
969 +               
970 +       }
971 +       
972 +       dmas = __raw_readl(&lp->tx_dma_regs->dmas);
973 +       __raw_writel( ~dmas, &lp->tx_dma_regs->dmas);
974 +       
975 +       /* Enable F E bit in Tx DMA */
976 +       __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm); 
977 +       spin_unlock_irqrestore(&lp->lock, flags);
978 +       
979 +}
980 +
981 +
982 +static struct net_device_stats * rc32434_get_stats(struct net_device *dev)
983 +{
984 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
985 +       return &lp->stats;
986 +}
987 +
988 +
989 +/*
990 + * Set or clear the multicast filter for this adaptor.
991 + */
992 +static void rc32434_multicast_list(struct net_device *dev)
993 +{   
994 +       /* listen to broadcasts always and to treat     */
995 +       /*       IFF bits independantly */
996 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
997 +       unsigned long flags;
998 +       u32 recognise = ETHARC_ab_m;            /* always accept broadcasts */
999 +       
1000 +       if (dev->flags & IFF_PROMISC)                   /* set promiscuous mode */
1001 +               recognise |= ETHARC_pro_m;
1002 +       
1003 +       if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15))
1004 +               recognise |= ETHARC_am_m;               /* all multicast & bcast */
1005 +       else if (dev->mc_count > 0) {
1006 +               DBG(2, __FUNCTION__ ": mc_count %d\n", dev->mc_count);
1007 +               recognise |= ETHARC_am_m;               /* for the time being */
1008 +       }
1009 +       
1010 +       spin_lock_irqsave(&lp->lock, flags);
1011 +       __raw_writel(recognise, &lp->eth_regs->etharc);
1012 +       spin_unlock_irqrestore(&lp->lock, flags);
1013 +}
1014 +
1015 +
1016 +static void rc32434_tx_timeout(struct net_device *dev)
1017 +{
1018 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
1019 +       unsigned long flags;
1020 +       
1021 +       spin_lock_irqsave(&lp->lock, flags);
1022 +       rc32434_restart(dev);
1023 +       spin_unlock_irqrestore(&lp->lock, flags);
1024 +       
1025 +}
1026 +
1027 +
1028 +/*
1029 + * Initialize the RC32434 ethernet controller.
1030 + */
1031 +static int rc32434_init(struct net_device *dev)
1032 +{
1033 +       struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
1034 +       int i, j;
1035 +       
1036 +       /* Disable DMA */       
1037 +       rc32434_abort_tx(dev);
1038 +       rc32434_abort_rx(dev); 
1039 +       
1040 +       /* reset ethernet logic */ 
1041 +       __raw_writel(0, &lp->eth_regs->ethintfc);
1042 +       while((__raw_readl(&lp->eth_regs->ethintfc) & ETHINTFC_rip_m))
1043 +               dev->trans_start = jiffies;     
1044 +       
1045 +       /* Enable Ethernet Interface */ 
1046 +       __raw_writel(ETHINTFC_en_m, &lp->eth_regs->ethintfc); 
1047 +       
1048 +#ifndef CONFIG_IDT_USE_NAPI
1049 +       tasklet_disable(lp->rx_tasklet);
1050 +#endif
1051 +       tasklet_disable(lp->tx_tasklet);
1052 +       
1053 +       /* Initialize the transmit Descriptors */
1054 +       for (i = 0; i < RC32434_NUM_TDS; i++) {
1055 +               lp->td_ring[i].control = DMAD_iof_m;
1056 +               lp->td_ring[i].devcs = ETHTX_fd_m | ETHTX_ld_m;
1057 +               lp->td_ring[i].ca = 0;
1058 +               lp->td_ring[i].link = 0;
1059 +               if (lp->tx_skb[i] != NULL) {
1060 +                       dev_kfree_skb_any(lp->tx_skb[i]);
1061 +                       lp->tx_skb[i] = NULL;
1062 +               }
1063 +       }
1064 +       lp->tx_next_done = lp->tx_chain_head = lp->tx_chain_tail =      lp->tx_full = lp->tx_count = 0;
1065 +       lp->    tx_chain_status = empty;
1066 +       
1067 +       /*
1068 +        * Initialize the receive descriptors so that they
1069 +        * become a circular linked list, ie. let the last
1070 +        * descriptor point to the first again.
1071 +        */
1072 +       for (i=0; i<RC32434_NUM_RDS; i++) {
1073 +               struct sk_buff *skb = lp->rx_skb[i];
1074 +               
1075 +               if (lp->rx_skb[i] == NULL) {
1076 +                       skb = dev_alloc_skb(RC32434_RBSIZE + 2);
1077 +                       if (skb == NULL) {
1078 +                               ERR("No memory in the system\n");
1079 +                               for (j = 0; j < RC32434_NUM_RDS; j ++)
1080 +                                       if (lp->rx_skb[j] != NULL) 
1081 +                                               dev_kfree_skb_any(lp->rx_skb[j]);
1082 +                               
1083 +                               return 1;
1084 +                       }
1085 +                       else {
1086 +                               skb->dev = dev;
1087 +                               skb_reserve(skb, 2);
1088 +                               lp->rx_skb[i] = skb;
1089 +                               lp->rd_ring[i].ca = CPHYSADDR(skb->data); 
1090 +                               
1091 +                       }
1092 +               }
1093 +               lp->rd_ring[i].control =        DMAD_iod_m | DMA_COUNT(RC32434_RBSIZE);
1094 +               lp->rd_ring[i].devcs = 0;
1095 +               lp->rd_ring[i].ca = CPHYSADDR(skb->data);
1096 +               lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
1097 +               
1098 +       }
1099 +       /* loop back */
1100 +       lp->rd_ring[RC32434_NUM_RDS-1].link = CPHYSADDR(&lp->rd_ring[0]);
1101 +       lp->rx_next_done   = 0;
1102 +       
1103 +       lp->rd_ring[RC32434_NUM_RDS-1].control |= DMAD_cod_m;
1104 +       lp->rx_chain_head = 0;
1105 +       lp->rx_chain_tail = 0;
1106 +       lp->rx_chain_status = empty;
1107 +       
1108 +       __raw_writel(0, &lp->rx_dma_regs->dmas);
1109 +       /* Start Rx DMA */
1110 +       rc32434_start_rx(lp, &lp->rd_ring[0]);
1111 +       
1112 +       /* Enable F E bit in Tx DMA */
1113 +       __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm); 
1114 +       /* Enable D H E bit in Rx DMA */
1115 +       __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm); 
1116 +       
1117 +       /* Accept only packets destined for this Ethernet device address */
1118 +       __raw_writel(ETHARC_ab_m, &lp->eth_regs->etharc); 
1119 +       
1120 +       /* Set all Ether station address registers to their initial values */ 
1121 +       __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal0); 
1122 +       __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah0);
1123 +       
1124 +       __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal1); 
1125 +       __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah1);
1126 +       
1127 +       __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal2); 
1128 +       __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah2);
1129 +       
1130 +       __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal3); 
1131 +       __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah3); 
1132 +       
1133 +       
1134 +       /* Frame Length Checking, Pad Enable, CRC Enable, Full Duplex set */ 
1135 +       __raw_writel(ETHMAC2_pe_m | ETHMAC2_cen_m | ETHMAC2_fd_m, &lp->eth_regs->ethmac2);  
1136 +       //ETHMAC2_flc_m         ETHMAC2_fd_m    lp->duplex_mode
1137 +       
1138 +       /* Back to back inter-packet-gap */ 
1139 +       __raw_writel(0x15, &lp->eth_regs->ethipgt); 
1140 +       /* Non - Back to back inter-packet-gap */ 
1141 +       __raw_writel(0x12, &lp->eth_regs->ethipgr); 
1142 +       
1143 +       /* Management Clock Prescaler Divisor */
1144 +       /* Clock independent setting */
1145 +       __raw_writel(((idt_cpu_freq)/MII_CLOCK+1) & ~1,
1146 +                      &lp->eth_regs->ethmcp);
1147 +       
1148 +       /* don't transmit until fifo contains 48b */
1149 +       __raw_writel(48, &lp->eth_regs->ethfifott);
1150 +       
1151 +       __raw_writel(ETHMAC1_re_m, &lp->eth_regs->ethmac1);
1152 +       
1153 +#ifndef CONFIG_IDT_USE_NAPI
1154 +       tasklet_enable(lp->rx_tasklet);
1155 +#endif
1156 +       tasklet_enable(lp->tx_tasklet);
1157 +       
1158 +       netif_start_queue(dev);
1159 +       
1160 +       return 0; 
1161 +}
1162 +
1163 +static struct platform_driver korina_driver = {
1164 +       .driver.name = "korina",
1165 +       .probe = rc32434_probe,
1166 +       .remove = rc32434_remove,
1167 +};
1168 +
1169 +static int __init rc32434_init_module(void)
1170 +{
1171 +       return platform_driver_register(&korina_driver);
1172 +}
1173 +
1174 +static void rc32434_cleanup_module(void)
1175 +{
1176 +       return platform_driver_unregister(&korina_driver);
1177 +}
1178 +
1179 +module_init(rc32434_init_module);
1180 +module_exit(rc32434_cleanup_module);
1181 diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile
1182 --- linux.old/drivers/net/Makefile      2006-06-08 20:21:20.000000000 +0200
1183 +++ linux.dev/drivers/net/Makefile      2006-06-08 20:19:40.000000000 +0200
1184 @@ -23,6 +23,8 @@
1185  #
1186  obj-$(CONFIG_PLIP) += plip.o
1187  
1188 +obj-$(CONFIG_KORINA) += korina.o
1189 +
1190  obj-$(CONFIG_ROADRUNNER) += rrunner.o
1191  
1192  obj-$(CONFIG_HAPPYMEAL) += sunhme.o
1193 diff -urN linux.old/drivers/net/rc32434_eth.h linux.dev/drivers/net/rc32434_eth.h
1194 --- linux.old/drivers/net/rc32434_eth.h 1970-01-01 01:00:00.000000000 +0100
1195 +++ linux.dev/drivers/net/rc32434_eth.h 2006-06-08 21:57:12.000000000 +0200
1196 @@ -0,0 +1,178 @@
1197 +/**************************************************************************
1198 + *
1199 + *  BRIEF MODULE DESCRIPTION
1200 + *     Definitions for IDT RC32434 on-chip ethernet controller.
1201 + *
1202 + *  Copyright 2004 IDT Inc. (rischelp@idt.com)
1203 + *         
1204 + *  This program is free software; you can redistribute  it and/or modify it
1205 + *  under  the terms of  the GNU General  Public License as published by the
1206 + *  Free Software Foundation;  either version 2 of the  License, or (at your
1207 + *  option) any later version.
1208 + *
1209 + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
1210 + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
1211 + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
1212 + *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
1213 + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1214 + *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
1215 + *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1216 + *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
1217 + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1218 + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1219 + *
1220 + *  You should have received a copy of the  GNU General Public License along
1221 + *  with this program; if not, write  to the Free Software Foundation, Inc.,
1222 + *  675 Mass Ave, Cambridge, MA 02139, USA.
1223 + *
1224 + *
1225 + **************************************************************************
1226 + * May 2004 rkt, neb
1227 + *
1228 + * Initial Release
1229 + *
1230 + * Aug 2004
1231 + *
1232 + * Added NAPI
1233 + *
1234 + **************************************************************************
1235 + */
1236 +
1237 +
1238 +#include  <asm/rc32434/rc32434.h>
1239 +#include  <asm/rc32434/dma_v.h>
1240 +#include  <asm/rc32434/eth_v.h>
1241 +
1242 +#define CONFIG_IDT_USE_NAPI 1
1243 +#define RC32434_DEBUG  2
1244 +//#define RC32434_PROC_DEBUG
1245 +#undef RC32434_DEBUG
1246 +
1247 +#ifdef RC32434_DEBUG
1248 +
1249 +/* use 0 for production, 1 for verification, >2 for debug */
1250 +static int rc32434_debug = RC32434_DEBUG;
1251 +#define ASSERT(expr) \
1252 +       if(!(expr)) {   \
1253 +               printk( "Assertion failed! %s,%s,%s,line=%d\n", \
1254 +               #expr,__FILE__,__FUNCTION__,__LINE__);          }
1255 +#define DBG(lvl, format, arg...) if (rc32434_debug > lvl) printk(KERN_INFO "%s: " format, dev->name , ## arg)
1256 +#else
1257 +#define ASSERT(expr) do {} while (0)
1258 +#define DBG(lvl, format, arg...) do {} while (0)
1259 +#endif
1260 +
1261 +#define INFO(format, arg...) printk(KERN_INFO "%s: " format, dev->name , ## arg)
1262 +#define ERR(format, arg...) printk(KERN_ERR "%s: " format, dev->name , ## arg)
1263 +#define WARN(format, arg...) printk(KERN_WARNING "%s: " format, dev->name , ## arg)            
1264 +
1265 +/* the following must be powers of two */
1266 +#ifdef CONFIG_IDT_USE_NAPI
1267 +#define RC32434_NUM_RDS    64                  /* number of receive descriptors */
1268 +#define RC32434_NUM_TDS    64                  /* number of transmit descriptors */
1269 +#else
1270 +#define RC32434_NUM_RDS    128                 /* number of receive descriptors */
1271 +#define RC32434_NUM_TDS    128                 /* number of transmit descriptors */
1272 +#endif
1273 +
1274 +#define RC32434_RBSIZE     1536                /* size of one resource buffer = Ether MTU */
1275 +#define RC32434_RDS_MASK   (RC32434_NUM_RDS-1)
1276 +#define RC32434_TDS_MASK   (RC32434_NUM_TDS-1)
1277 +#define RD_RING_SIZE (RC32434_NUM_RDS * sizeof(struct DMAD_s))
1278 +#define TD_RING_SIZE (RC32434_NUM_TDS * sizeof(struct DMAD_s))
1279 +
1280 +#define RC32434_TX_TIMEOUT HZ * 100
1281 +
1282 +#define rc32434_eth0_regs ((ETH_t)(ETH0_VirtualAddress))
1283 +#define rc32434_eth1_regs ((ETH_t)(ETH1_VirtualAddress))
1284 +
1285 +enum status    { filled,       empty};
1286 +#define IS_DMA_FINISHED(X)   (((X) & (DMAD_f_m)) != 0)
1287 +#define IS_DMA_DONE(X)   (((X) & (DMAD_d_m)) != 0)
1288 +
1289 +
1290 +/* Information that need to be kept for each board. */
1291 +struct rc32434_local {
1292 +       ETH_t  eth_regs;
1293 +       DMA_Chan_t  rx_dma_regs;
1294 +       DMA_Chan_t  tx_dma_regs;
1295 +       volatile DMAD_t   td_ring;                      /* transmit descriptor ring */ 
1296 +       volatile DMAD_t   rd_ring;                      /* receive descriptor ring  */
1297 +       
1298 +       struct sk_buff* tx_skb[RC32434_NUM_TDS];        /* skbuffs for pkt to trans */
1299 +       struct sk_buff* rx_skb[RC32434_NUM_RDS];        /* skbuffs for pkt to trans */
1300 +       
1301 +#ifndef CONFIG_IDT_USE_NAPI
1302 +       struct tasklet_struct * rx_tasklet;
1303 +#endif
1304 +       struct tasklet_struct * tx_tasklet;
1305 +       
1306 +       int     rx_next_done;
1307 +       int     rx_chain_head;
1308 +       int     rx_chain_tail;
1309 +       enum status     rx_chain_status;
1310 +       
1311 +       int     tx_next_done;
1312 +       int     tx_chain_head;
1313 +       int     tx_chain_tail;
1314 +       enum status     tx_chain_status;
1315 +       int tx_count;                   
1316 +       int     tx_full;
1317 +       
1318 +       struct timer_list    mii_phy_timer;
1319 +       unsigned long duplex_mode;
1320 +       
1321 +       int     rx_irq;
1322 +       int    tx_irq;
1323 +       int    ovr_irq;
1324 +       int    und_irq;
1325 +       
1326 +       struct net_device_stats stats;
1327 +       spinlock_t lock; 
1328 +       
1329 +       /* debug /proc entry */
1330 +       struct proc_dir_entry *ps;
1331 +       int dma_halt_cnt;  int dma_run_cnt;
1332 +};
1333 +
1334 +extern unsigned int idt_cpu_freq;
1335 +
1336 +/* Index to functions, as function prototypes. */
1337 +static int rc32434_open(struct net_device *dev);
1338 +static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev);
1339 +static void rc32434_mii_handler(unsigned long data);
1340 +static irqreturn_t  rc32434_und_interrupt(int irq, void *dev_id, struct pt_regs * regs);
1341 +static irqreturn_t rc32434_rx_dma_interrupt(int irq, void *dev_id, struct pt_regs * regs);
1342 +static irqreturn_t rc32434_tx_dma_interrupt(int irq, void *dev_id, struct pt_regs * regs);
1343 +#ifdef RC32434_REVISION        
1344 +static irqreturn_t rc32434_ovr_interrupt(int irq, void *dev_id, struct pt_regs * regs);
1345 +#endif
1346 +static int  rc32434_close(struct net_device *dev);
1347 +static struct net_device_stats *rc32434_get_stats(struct net_device *dev);
1348 +static void rc32434_multicast_list(struct net_device *dev);
1349 +static int  rc32434_init(struct net_device *dev);
1350 +static void rc32434_tx_timeout(struct net_device *dev);
1351 +
1352 +static void rc32434_tx_tasklet(unsigned long tx_data_dev);
1353 +#ifdef CONFIG_IDT_USE_NAPI
1354 +static int rc32434_poll(struct net_device *rx_data_dev, int *budget);
1355 +#else
1356 +static void rc32434_rx_tasklet(unsigned long rx_data_dev);
1357 +#endif
1358 +static void rc32434_cleanup_module(void);
1359 +
1360 +
1361 +static inline void rc32434_abort_dma(struct net_device *dev, DMA_Chan_t ch)
1362 +{
1363 +       if (__raw_readl(&ch->dmac) & DMAC_run_m) {
1364 +               __raw_writel(0x10, &ch->dmac); 
1365 +               
1366 +               while (!(__raw_readl(&ch->dmas) & DMAS_h_m))
1367 +                       dev->trans_start = jiffies;             
1368 +               
1369 +               __raw_writel(0, &ch->dmas);  
1370 +       }
1371 +       
1372 +       __raw_writel(0, &ch->dmadptr); 
1373 +       __raw_writel(0, &ch->dmandptr); 
1374 +}
1375