1 diff -urN linux.old/drivers/net/Kconfig linux.dev/drivers/net/Kconfig
2 --- linux.old/drivers/net/Kconfig 2006-12-14 03:13:47.000000000 +0100
3 +++ linux.dev/drivers/net/Kconfig 2006-12-14 03:18:45.000000000 +0100
6 source "drivers/net/arm/Kconfig"
9 + tristate "Korina Local Ethernet support"
10 + depends on NET_ETHERNET && ( IDT_EB434 || MIKROTIK_RB500)
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.
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-12-14 03:18:45.000000000 +0100
22 +/**************************************************************************
24 + * BRIEF MODULE DESCRIPTION
25 + * Driver for the IDT RC32434 on-chip ethernet controller.
27 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
28 + * Copyright 2006 Felix Fietkau <nbd@openwrt.org>
30 + * This program is free software; you can redistribute it and/or modify it
31 + * under the terms of the GNU General Public License as published by the
32 + * Free Software Foundation; either version 2 of the License, or (at your
33 + * option) any later version.
35 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
36 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
38 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
39 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
40 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
41 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
44 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 + * You should have received a copy of the GNU General Public License along
47 + * with this program; if not, write to the Free Software Foundation, Inc.,
48 + * 675 Mass Ave, Cambridge, MA 02139, USA.
51 + **************************************************************************
54 + * Based on the driver developed by B. Maruthanayakam, H. Kou and others.
60 + **************************************************************************
63 +#include <linux/autoconf.h>
64 +#include <linux/module.h>
65 +#include <linux/kernel.h>
66 +#include <linux/moduleparam.h>
67 +#include <linux/sched.h>
68 +#include <linux/ctype.h>
69 +#include <linux/types.h>
70 +#include <linux/fcntl.h>
71 +#include <linux/interrupt.h>
72 +#include <linux/ptrace.h>
73 +#include <linux/init.h>
74 +#include <linux/ioport.h>
75 +#include <linux/proc_fs.h>
76 +#include <linux/in.h>
77 +#include <linux/slab.h>
78 +#include <linux/string.h>
79 +#include <linux/delay.h>
80 +#include <linux/netdevice.h>
81 +#include <linux/etherdevice.h>
82 +#include <linux/skbuff.h>
83 +#include <linux/errno.h>
84 +#include <linux/platform_device.h>
85 +#include <asm/bootinfo.h>
86 +#include <asm/system.h>
87 +#include <asm/bitops.h>
88 +#include <asm/pgtable.h>
89 +#include <asm/segment.h>
93 +#include <asm/rc32434/rb.h>
94 +#include "rc32434_eth.h"
96 +#define DRIVER_VERSION "(mar2904)"
98 +#define DRIVER_NAME "rc32434 Ethernet driver. " DRIVER_VERSION
100 +#define STATION_ADDRESS_HIGH(dev) (((dev)->dev_addr[0] << 8) | \
101 + ((dev)->dev_addr[1]))
102 +#define STATION_ADDRESS_LOW(dev) (((dev)->dev_addr[2] << 24) | \
103 + ((dev)->dev_addr[3] << 16) | \
104 + ((dev)->dev_addr[4] << 8) | \
105 + ((dev)->dev_addr[5]))
107 +#define MII_CLOCK 1250000 /* no more than 2.5MHz */
108 +#define CONFIG_IDT_USE_NAPI 1
111 +static inline void rc32434_abort_tx(struct net_device *dev)
113 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
114 + rc32434_abort_dma(dev, lp->tx_dma_regs);
118 +static inline void rc32434_abort_rx(struct net_device *dev)
120 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
121 + rc32434_abort_dma(dev, lp->rx_dma_regs);
125 +static inline void rc32434_start_tx(struct rc32434_local *lp, volatile DMAD_t td)
127 + rc32434_start_dma(lp->tx_dma_regs, CPHYSADDR(td));
130 +static inline void rc32434_start_rx(struct rc32434_local *lp, volatile DMAD_t rd)
132 + rc32434_start_dma(lp->rx_dma_regs, CPHYSADDR(rd));
135 +static inline void rc32434_chain_tx(struct rc32434_local *lp, volatile DMAD_t td)
137 + rc32434_chain_dma(lp->tx_dma_regs, CPHYSADDR(td));
140 +static inline void rc32434_chain_rx(struct rc32434_local *lp, volatile DMAD_t rd)
142 + rc32434_chain_dma(lp->rx_dma_regs, CPHYSADDR(rd));
145 +#ifdef RC32434_PROC_DEBUG
146 +static int rc32434_read_proc(char *buf, char **start, off_t fpos,
147 + int length, int *eof, void *data)
149 + struct net_device *dev = (struct net_device *)data;
150 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
153 + /* print out header */
154 + len += sprintf(buf + len, "\n\tKorina Ethernet Debug\n\n");
155 + len += sprintf (buf + len,
156 + "DMA halt count = %10d, DMA run count = %10d\n",
157 + lp->dma_halt_cnt, lp->dma_run_cnt);
164 + *start = buf + fpos;
166 + if ((len -= fpos) > length)
177 + * Restart the RC32434 ethernet controller.
179 +static int rc32434_restart(struct net_device *dev)
181 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
184 + * Disable interrupts
186 + disable_irq(lp->rx_irq);
187 + disable_irq(lp->tx_irq);
188 +#ifdef RC32434_REVISION
189 + disable_irq(lp->ovr_irq);
191 + disable_irq(lp->und_irq);
193 + /* Mask F E bit in Tx DMA */
194 + __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) | DMASM_f_m | DMASM_e_m, &lp->tx_dma_regs->dmasm);
195 + /* Mask D H E bit in Rx DMA */
196 + __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) | DMASM_d_m | DMASM_h_m | DMASM_e_m, &lp->rx_dma_regs->dmasm);
199 + rc32434_multicast_list(dev);
201 + enable_irq(lp->und_irq);
202 +#ifdef RC32434_REVISION
203 + enable_irq(lp->ovr_irq);
205 + enable_irq(lp->tx_irq);
206 + enable_irq(lp->rx_irq);
211 +static int rc32434_probe(struct platform_device *pdev)
213 + struct korina_device *bif = (struct korina_device *) pdev->dev.platform_data;
214 + struct rc32434_local *lp = NULL;
215 + struct net_device *dev = NULL;
216 + struct resource *r;
219 + dev = alloc_etherdev(sizeof(struct rc32434_local));
221 + ERR("Korina_eth: alloc_etherdev failed\n");
225 + platform_set_drvdata(pdev, dev);
226 + SET_MODULE_OWNER(dev);
229 + memcpy(dev->dev_addr, bif->mac, 6);
231 + /* Initialize the device structure. */
232 + if (dev->priv == NULL) {
233 + lp = (struct rc32434_local *)kmalloc(sizeof(*lp), GFP_KERNEL);
234 + memset(lp, 0, sizeof(struct rc32434_local));
237 + lp = (struct rc32434_local *)dev->priv;
240 + lp->rx_irq = platform_get_irq_byname(pdev, "korina_rx");
241 + lp->tx_irq = platform_get_irq_byname(pdev, "korina_tx");
242 + lp->ovr_irq = platform_get_irq_byname(pdev, "korina_ovr");
243 + lp->und_irq = platform_get_irq_byname(pdev, "korina_und");
245 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_regs");
246 + dev->base_addr = r->start;
247 + lp->eth_regs = ioremap_nocache(r->start, r->end - r->start);
248 + if (!lp->eth_regs) {
249 + ERR("Can't remap eth registers\n");
251 + goto probe_err_out;
254 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
255 + lp->rx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
256 + if (!lp->rx_dma_regs) {
257 + ERR("Can't remap Rx DMA registers\n");
259 + goto probe_err_out;
262 + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
263 + lp->tx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
264 + if (!lp->tx_dma_regs) {
265 + ERR("Can't remap Tx DMA registers\n");
267 + goto probe_err_out;
270 +#ifdef RC32434_PROC_DEBUG
271 + lp->ps = create_proc_read_entry (bif->name, 0, proc_net,
272 + rc32434_read_proc, dev);
275 + lp->td_ring = (DMAD_t)kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
276 + if (!lp->td_ring) {
277 + ERR("Can't allocate descriptors\n");
279 + goto probe_err_out;
282 + dma_cache_inv((unsigned long)(lp->td_ring), TD_RING_SIZE + RD_RING_SIZE);
284 + /* now convert TD_RING pointer to KSEG1 */
285 + lp->td_ring = (DMAD_t )KSEG1ADDR(lp->td_ring);
286 + lp->rd_ring = &lp->td_ring[RC32434_NUM_TDS];
289 + spin_lock_init(&lp->lock);
291 + /* just use the rx dma irq */
292 + dev->irq = lp->rx_irq;
296 + dev->open = rc32434_open;
297 + dev->stop = rc32434_close;
298 + dev->hard_start_xmit = rc32434_send_packet;
299 + dev->get_stats = rc32434_get_stats;
300 + dev->set_multicast_list = &rc32434_multicast_list;
301 + dev->tx_timeout = rc32434_tx_timeout;
302 + dev->watchdog_timeo = RC32434_TX_TIMEOUT;
304 +#ifdef CONFIG_IDT_USE_NAPI
305 + dev->poll = rc32434_poll;
307 + printk("Using NAPI with weight %d\n",dev->weight);
309 + lp->rx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
310 + tasklet_init(lp->rx_tasklet, rc32434_rx_tasklet, (unsigned long)dev);
312 + lp->tx_tasklet = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
313 + tasklet_init(lp->tx_tasklet, rc32434_tx_tasklet, (unsigned long)dev);
315 + if ((err = register_netdev(dev))) {
316 + printk(KERN_ERR "rc32434 ethernet. Cannot register net device %d\n", err);
319 + goto probe_err_out;
322 + INFO("Rx IRQ %d, Tx IRQ %d, ", lp->rx_irq, lp->tx_irq);
323 + for (i = 0; i < 6; i++) {
324 + printk("%2.2x", dev->dev_addr[i]);
333 + rc32434_cleanup_module();
334 + ERR(" failed. Returns %d\n", retval);
339 +static int rc32434_remove(struct platform_device *pdev)
341 + struct korina_device *bif = (struct korina_device *) pdev->dev.platform_data;
343 + if (bif->dev != NULL) {
344 + struct rc32434_local *lp = (struct rc32434_local *)bif->dev->priv;
347 + iounmap((void*)lp->eth_regs);
348 + if (lp->rx_dma_regs)
349 + iounmap((void*)lp->rx_dma_regs);
350 + if (lp->tx_dma_regs)
351 + iounmap((void*)lp->tx_dma_regs);
353 + kfree((void*)KSEG0ADDR(lp->td_ring));
355 +#ifdef RC32434_PROC_DEBUG
357 + remove_proc_entry(bif->name, proc_net);
363 + platform_set_drvdata(pdev, NULL);
364 + unregister_netdev(bif->dev);
365 + free_netdev(bif->dev);
372 +static int rc32434_open(struct net_device *dev)
374 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
377 + if (rc32434_init(dev)) {
378 + ERR("Error: cannot open the Ethernet device\n");
382 + /* Install the interrupt handler that handles the Done Finished Ovr and Und Events */
383 + if (request_irq(lp->rx_irq, &rc32434_rx_dma_interrupt,
384 + SA_SHIRQ | SA_INTERRUPT,
385 + "Korina ethernet Rx", dev)) {
386 + ERR(": unable to get Rx DMA IRQ %d\n",
390 + if (request_irq(lp->tx_irq, &rc32434_tx_dma_interrupt,
391 + SA_SHIRQ | SA_INTERRUPT,
392 + "Korina ethernet Tx", dev)) {
393 + ERR(": unable to get Tx DMA IRQ %d\n",
395 + free_irq(lp->rx_irq, dev);
399 +#ifdef RC32434_REVISION
400 + /* Install handler for overrun error. */
401 + if (request_irq(lp->ovr_irq, &rc32434_ovr_interrupt,
402 + SA_SHIRQ | SA_INTERRUPT,
403 + "Ethernet Overflow", dev)) {
404 + ERR(": unable to get OVR IRQ %d\n",
406 + free_irq(lp->rx_irq, dev);
407 + free_irq(lp->tx_irq, dev);
412 + /* Install handler for underflow error. */
413 + if (request_irq(lp->und_irq, &rc32434_und_interrupt,
414 + SA_SHIRQ | SA_INTERRUPT,
415 + "Ethernet Underflow", dev)) {
416 + ERR(": unable to get UND IRQ %d\n",
418 + free_irq(lp->rx_irq, dev);
419 + free_irq(lp->tx_irq, dev);
420 +#ifdef RC32434_REVISION
421 + free_irq(lp->ovr_irq, dev);
433 +static int rc32434_close(struct net_device *dev)
435 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
438 + /* Disable interrupts */
439 + disable_irq(lp->rx_irq);
440 + disable_irq(lp->tx_irq);
441 +#ifdef RC32434_REVISION
442 + disable_irq(lp->ovr_irq);
444 + disable_irq(lp->und_irq);
446 + tmp = __raw_readl(&lp->tx_dma_regs->dmasm);
447 + tmp = tmp | DMASM_f_m | DMASM_e_m;
448 + __raw_writel(tmp, &lp->tx_dma_regs->dmasm);
450 + tmp = __raw_readl(&lp->rx_dma_regs->dmasm);
451 + tmp = tmp | DMASM_d_m | DMASM_h_m | DMASM_e_m;
452 + __raw_writel(tmp, &lp->rx_dma_regs->dmasm);
454 + free_irq(lp->rx_irq, dev);
455 + free_irq(lp->tx_irq, dev);
456 +#ifdef RC32434_REVISION
457 + free_irq(lp->ovr_irq, dev);
459 + free_irq(lp->und_irq, dev);
464 +/* transmit packet */
465 +static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev)
467 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
468 + unsigned long flags;
473 + spin_lock_irqsave(&lp->lock, flags);
475 + td = &lp->td_ring[lp->tx_chain_tail];
477 + /* stop queue when full, drop pkts if queue already full */
478 + if(lp->tx_count >= (RC32434_NUM_TDS - 2)) {
481 + if(lp->tx_count == (RC32434_NUM_TDS - 2)) {
482 + netif_stop_queue(dev);
485 + lp->stats.tx_dropped++;
486 + dev_kfree_skb_any(skb);
487 + spin_unlock_irqrestore(&lp->lock, flags);
494 + lp->tx_skb[lp->tx_chain_tail] = skb;
498 + /* Setup the transmit descriptor. */
499 + td->ca = CPHYSADDR(skb->data);
501 + if(__raw_readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
502 + if( lp->tx_chain_status == empty ) {
503 + td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */
504 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
505 + __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */
506 + lp->tx_chain_head = lp->tx_chain_tail; /* Move head to tail */
509 + td->control = DMA_COUNT(length) |DMAD_cof_m|DMAD_iof_m; /* Update tail */
510 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &= ~(DMAD_cof_m); /* Link to prev */
511 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link = CPHYSADDR(td); /* Link to prev */
512 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
513 + __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr)); /* Write to NDPTR */
514 + lp->tx_chain_head = lp->tx_chain_tail; /* Move head to tail */
515 + lp->tx_chain_status = empty;
519 + if( lp->tx_chain_status == empty ) {
520 + td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */
521 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
522 + lp->tx_chain_status = filled;
525 + td->control = DMA_COUNT(length) |DMAD_cof_m |DMAD_iof_m; /* Update tail */
526 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].control &= ~(DMAD_cof_m); /* Link to prev */
527 + lp->td_ring[(lp->tx_chain_tail-1)& RC32434_TDS_MASK].link = CPHYSADDR(td); /* Link to prev */
528 + lp->tx_chain_tail = (lp->tx_chain_tail + 1) & RC32434_TDS_MASK; /* Move tail */
532 + dev->trans_start = jiffies;
534 + spin_unlock_irqrestore(&lp->lock, flags);
540 +/* Ethernet MII-PHY Handler */
541 +static void rc32434_mii_handler(unsigned long data)
543 + struct net_device *dev = (struct net_device *)data;
544 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
545 + unsigned long flags;
546 + unsigned long duplex_status;
547 + int port_addr = (lp->rx_irq == 0x2c? 1:0) << 8;
549 + spin_lock_irqsave(&lp->lock, flags);
551 + /* Two ports are using the same MII, the difference is the PHY address */
552 + __raw_writel(0, &rc32434_eth0_regs->miimcfg);
553 + __raw_writel(0, &rc32434_eth0_regs->miimcmd);
554 + __raw_writel(port_addr |0x05, &rc32434_eth0_regs->miimaddr);
555 + __raw_writel(MIIMCMD_scn_m, &rc32434_eth0_regs->miimcmd);
556 + while(__raw_readl(&rc32434_eth0_regs->miimind) & MIIMIND_nv_m);
558 + ERR("irq:%x port_addr:%x RDD:%x\n",
559 + lp->rx_irq, port_addr, __raw_readl(&rc32434_eth0_regs->miimrdd));
560 + duplex_status = (__raw_readl(&rc32434_eth0_regs->miimrdd) & 0x140)? ETHMAC2_fd_m: 0;
561 + if(duplex_status != lp->duplex_mode) {
562 + 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);
563 + lp->duplex_mode = duplex_status;
564 + rc32434_restart(dev);
567 + lp->mii_phy_timer.expires = jiffies + 10 * HZ;
568 + add_timer(&lp->mii_phy_timer);
570 + spin_unlock_irqrestore(&lp->lock, flags);
574 +#ifdef RC32434_REVISION
575 +/* Ethernet Rx Overflow interrupt */
577 +rc32434_ovr_interrupt(int irq, void *dev_id)
579 + struct net_device *dev = (struct net_device *)dev_id;
580 + struct rc32434_local *lp;
582 + irqreturn_t retval = IRQ_NONE;
584 + ASSERT(dev != NULL);
586 + lp = (struct rc32434_local *)dev->priv;
587 + spin_lock(&lp->lock);
588 + ovr = __raw_readl(&lp->eth_regs->ethintfc);
590 + if(ovr & ETHINTFC_ovr_m) {
591 + netif_stop_queue(dev);
593 + /* clear OVR bit */
594 + __raw_writel((ovr & ~ETHINTFC_ovr_m), &lp->eth_regs->ethintfc);
596 + /* Restart interface */
597 + rc32434_restart(dev);
598 + retval = IRQ_HANDLED;
600 + spin_unlock(&lp->lock);
608 +/* Ethernet Tx Underflow interrupt */
610 +rc32434_und_interrupt(int irq, void *dev_id)
612 + struct net_device *dev = (struct net_device *)dev_id;
613 + struct rc32434_local *lp;
615 + irqreturn_t retval = IRQ_NONE;
617 + ASSERT(dev != NULL);
619 + lp = (struct rc32434_local *)dev->priv;
621 + spin_lock(&lp->lock);
623 + und = __raw_readl(&lp->eth_regs->ethintfc);
625 + if(und & ETHINTFC_und_m) {
626 + netif_stop_queue(dev);
628 + __raw_writel((und & ~ETHINTFC_und_m), &lp->eth_regs->ethintfc);
630 + /* Restart interface */
631 + rc32434_restart(dev);
632 + retval = IRQ_HANDLED;
635 + spin_unlock(&lp->lock);
641 +/* Ethernet Rx DMA interrupt */
643 +rc32434_rx_dma_interrupt(int irq, void *dev_id)
645 + struct net_device *dev = (struct net_device *)dev_id;
646 + struct rc32434_local* lp;
647 + volatile u32 dmas,dmasm;
648 + irqreturn_t retval;
650 + ASSERT(dev != NULL);
652 + lp = (struct rc32434_local *)dev->priv;
654 + spin_lock(&lp->lock);
655 + dmas = __raw_readl(&lp->rx_dma_regs->dmas);
656 + if(dmas & (DMAS_d_m|DMAS_h_m|DMAS_e_m)) {
657 + /* Mask D H E bit in Rx DMA */
658 + dmasm = __raw_readl(&lp->rx_dma_regs->dmasm);
659 + __raw_writel(dmasm | (DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm);
660 +#ifdef CONFIG_IDT_USE_NAPI
661 + if(netif_rx_schedule_prep(dev))
662 + __netif_rx_schedule(dev);
664 + tasklet_hi_schedule(lp->rx_tasklet);
667 + if (dmas & DMAS_e_m)
668 + ERR(": DMA error\n");
670 + retval = IRQ_HANDLED;
675 + spin_unlock(&lp->lock);
679 +#ifdef CONFIG_IDT_USE_NAPI
680 +static int rc32434_poll(struct net_device *rx_data_dev, int *budget)
682 +static void rc32434_rx_tasklet(unsigned long rx_data_dev)
685 + struct net_device *dev = (struct net_device *)rx_data_dev;
686 + struct rc32434_local* lp = netdev_priv(dev);
687 + volatile DMAD_t rd = &lp->rd_ring[lp->rx_next_done];
688 + struct sk_buff *skb, *skb_new;
690 + u32 devcs, count, pkt_len, pktuncrc_len;
692 +#ifdef CONFIG_IDT_USE_NAPI
694 + int rx_work_limit = min(*budget,dev->quota);
696 + unsigned long flags;
697 + spin_lock_irqsave(&lp->lock, flags);
700 + while ( (count = RC32434_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) {
701 +#ifdef CONFIG_IDT_USE_NAPI
702 + if(--rx_work_limit <0)
707 + /* init the var. used for the later operations within the while loop */
710 + pkt_len = RCVPKT_LENGTH(devcs);
711 + skb = lp->rx_skb[lp->rx_next_done];
714 + lp->stats.rx_errors++;
715 + lp->stats.rx_dropped++;
717 + else if ((devcs & ( ETHRX_ld_m)) != ETHRX_ld_m) {
718 + /* check that this is a whole packet */
719 + /* WARNING: DMA_FD bit incorrectly set in Rc32434 (errata ref #077) */
720 + lp->stats.rx_errors++;
721 + lp->stats.rx_dropped++;
723 + else if ( (devcs & ETHRX_rok_m) ) {
726 + /* must be the (first and) last descriptor then */
727 + pkt_buf = (u8*)lp->rx_skb[lp->rx_next_done]->data;
729 + pktuncrc_len = pkt_len - 4;
730 + /* invalidate the cache */
731 + dma_cache_inv((unsigned long)pkt_buf, pktuncrc_len);
733 + /* Malloc up new buffer. */
734 + skb_new = dev_alloc_skb(RC32434_RBSIZE + 2);
736 + if (skb_new != NULL){
738 + skb_put(skb, pktuncrc_len);
740 + skb->protocol = eth_type_trans(skb, dev);
742 + /* pass the packet to upper layers */
743 +#ifdef CONFIG_IDT_USE_NAPI
744 + netif_receive_skb(skb);
749 + dev->last_rx = jiffies;
750 + lp->stats.rx_packets++;
751 + lp->stats.rx_bytes += pktuncrc_len;
753 + if (IS_RCV_MP(devcs))
754 + lp->stats.multicast++;
757 + skb_reserve(skb_new, 2);
759 + skb_new->dev = dev;
760 + lp->rx_skb[lp->rx_next_done] = skb_new;
763 + ERR("no memory, dropping rx packet.\n");
764 + lp->stats.rx_errors++;
765 + lp->stats.rx_dropped++;
771 + /* This should only happen if we enable accepting broken packets */
772 + lp->stats.rx_errors++;
773 + lp->stats.rx_dropped++;
775 + /* add statistics counters */
776 + if (IS_RCV_CRC_ERR(devcs)) {
777 + DBG(2, "RX CRC error\n");
778 + lp->stats.rx_crc_errors++;
780 + else if (IS_RCV_LOR_ERR(devcs)) {
781 + DBG(2, "RX LOR error\n");
782 + lp->stats.rx_length_errors++;
784 + else if (IS_RCV_LE_ERR(devcs)) {
785 + DBG(2, "RX LE error\n");
786 + lp->stats.rx_length_errors++;
788 + else if (IS_RCV_OVR_ERR(devcs)) {
789 + lp->stats.rx_over_errors++;
791 + else if (IS_RCV_CV_ERR(devcs)) {
792 + /* code violation */
793 + DBG(2, "RX CV error\n");
794 + lp->stats.rx_frame_errors++;
796 + else if (IS_RCV_CES_ERR(devcs)) {
797 + DBG(2, "RX Preamble error\n");
803 + /* restore descriptor's curr_addr */
805 + rd->ca = CPHYSADDR(skb_new->data);
807 + rd->ca = CPHYSADDR(skb->data);
809 + rd->control = DMA_COUNT(RC32434_RBSIZE) |DMAD_cod_m |DMAD_iod_m;
810 + lp->rd_ring[(lp->rx_next_done-1)& RC32434_RDS_MASK].control &= ~(DMAD_cod_m);
812 + lp->rx_next_done = (lp->rx_next_done + 1) & RC32434_RDS_MASK;
813 + rd = &lp->rd_ring[lp->rx_next_done];
814 + __raw_writel( ~DMAS_d_m, &lp->rx_dma_regs->dmas);
816 +#ifdef CONFIG_IDT_USE_NAPI
817 + dev->quota -= received;
818 + *budget =- received;
819 + if(rx_work_limit < 0)
823 + dmas = __raw_readl(&lp->rx_dma_regs->dmas);
825 + if(dmas & DMAS_h_m) {
826 + __raw_writel( ~(DMAS_h_m | DMAS_e_m), &lp->rx_dma_regs->dmas);
827 +#ifdef RC32434_PROC_DEBUG
828 + lp->dma_halt_cnt++;
831 + skb = lp->rx_skb[lp->rx_next_done];
832 + rd->ca = CPHYSADDR(skb->data);
833 + rc32434_chain_rx(lp,rd);
836 +#ifdef CONFIG_IDT_USE_NAPI
837 + netif_rx_complete(dev);
839 + /* Enable D H E bit in Rx DMA */
840 + __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m |DMASM_e_m), &lp->rx_dma_regs->dmasm);
841 +#ifdef CONFIG_IDT_USE_NAPI
846 + spin_unlock_irqrestore(&lp->lock, flags);
855 +/* Ethernet Tx DMA interrupt */
857 +rc32434_tx_dma_interrupt(int irq, void *dev_id)
859 + struct net_device *dev = (struct net_device *)dev_id;
860 + struct rc32434_local *lp;
861 + volatile u32 dmas,dmasm;
862 + irqreturn_t retval;
864 + ASSERT(dev != NULL);
866 + lp = (struct rc32434_local *)dev->priv;
868 + spin_lock(&lp->lock);
870 + dmas = __raw_readl(&lp->tx_dma_regs->dmas);
872 + if (dmas & (DMAS_f_m | DMAS_e_m)) {
873 + dmasm = __raw_readl(&lp->tx_dma_regs->dmasm);
874 + /* Mask F E bit in Tx DMA */
875 + __raw_writel(dmasm | (DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm);
877 + tasklet_hi_schedule(lp->tx_tasklet);
879 + if(lp->tx_chain_status == filled && (__raw_readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
880 + __raw_writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &(lp->tx_dma_regs->dmandptr));
881 + lp->tx_chain_status = empty;
882 + lp->tx_chain_head = lp->tx_chain_tail;
883 + dev->trans_start = jiffies;
886 + if (dmas & DMAS_e_m)
887 + ERR(": DMA error\n");
889 + retval = IRQ_HANDLED;
894 + spin_unlock(&lp->lock);
900 +static void rc32434_tx_tasklet(unsigned long tx_data_dev)
902 + struct net_device *dev = (struct net_device *)tx_data_dev;
903 + struct rc32434_local* lp = (struct rc32434_local *)dev->priv;
904 + volatile DMAD_t td = &lp->td_ring[lp->tx_next_done];
906 + unsigned long flags;
909 + spin_lock_irqsave(&lp->lock, flags);
911 + /* process all desc that are done */
912 + while(IS_DMA_FINISHED(td->control)) {
913 + if(lp->tx_full == 1) {
914 + netif_wake_queue(dev);
918 + devcs = lp->td_ring[lp->tx_next_done].devcs;
919 + if ((devcs & (ETHTX_fd_m | ETHTX_ld_m)) != (ETHTX_fd_m | ETHTX_ld_m)) {
920 + lp->stats.tx_errors++;
921 + lp->stats.tx_dropped++;
923 + /* should never happen */
924 + DBG(1, __FUNCTION__ ": split tx ignored\n");
926 + else if (IS_TX_TOK(devcs)) {
927 + lp->stats.tx_packets++;
930 + lp->stats.tx_errors++;
931 + lp->stats.tx_dropped++;
934 + if (IS_TX_UND_ERR(devcs))
935 + lp->stats.tx_fifo_errors++;
937 + /* oversized frame */
938 + if (IS_TX_OF_ERR(devcs))
939 + lp->stats.tx_aborted_errors++;
941 + /* excessive deferrals */
942 + if (IS_TX_ED_ERR(devcs))
943 + lp->stats.tx_carrier_errors++;
945 + /* collisions: medium busy */
946 + if (IS_TX_EC_ERR(devcs))
947 + lp->stats.collisions++;
949 + /* late collision */
950 + if (IS_TX_LC_ERR(devcs))
951 + lp->stats.tx_window_errors++;
955 + /* We must always free the original skb */
956 + if (lp->tx_skb[lp->tx_next_done] != NULL) {
957 + dev_kfree_skb_any(lp->tx_skb[lp->tx_next_done]);
958 + lp->tx_skb[lp->tx_next_done] = NULL;
961 + lp->td_ring[lp->tx_next_done].control = DMAD_iof_m;
962 + lp->td_ring[lp->tx_next_done].devcs = ETHTX_fd_m | ETHTX_ld_m;
963 + lp->td_ring[lp->tx_next_done].link = 0;
964 + lp->td_ring[lp->tx_next_done].ca = 0;
967 + /* go on to next transmission */
968 + lp->tx_next_done = (lp->tx_next_done + 1) & RC32434_TDS_MASK;
969 + td = &lp->td_ring[lp->tx_next_done];
973 + dmas = __raw_readl(&lp->tx_dma_regs->dmas);
974 + __raw_writel( ~dmas, &lp->tx_dma_regs->dmas);
976 + /* Enable F E bit in Tx DMA */
977 + __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm);
978 + spin_unlock_irqrestore(&lp->lock, flags);
983 +static struct net_device_stats * rc32434_get_stats(struct net_device *dev)
985 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
991 + * Set or clear the multicast filter for this adaptor.
993 +static void rc32434_multicast_list(struct net_device *dev)
995 + /* listen to broadcasts always and to treat */
996 + /* IFF bits independantly */
997 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
998 + unsigned long flags;
999 + u32 recognise = ETHARC_ab_m; /* always accept broadcasts */
1001 + if (dev->flags & IFF_PROMISC) /* set promiscuous mode */
1002 + recognise |= ETHARC_pro_m;
1004 + if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15))
1005 + recognise |= ETHARC_am_m; /* all multicast & bcast */
1006 + else if (dev->mc_count > 0) {
1007 + DBG(2, __FUNCTION__ ": mc_count %d\n", dev->mc_count);
1008 + recognise |= ETHARC_am_m; /* for the time being */
1011 + spin_lock_irqsave(&lp->lock, flags);
1012 + __raw_writel(recognise, &lp->eth_regs->etharc);
1013 + spin_unlock_irqrestore(&lp->lock, flags);
1017 +static void rc32434_tx_timeout(struct net_device *dev)
1019 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
1020 + unsigned long flags;
1022 + spin_lock_irqsave(&lp->lock, flags);
1023 + rc32434_restart(dev);
1024 + spin_unlock_irqrestore(&lp->lock, flags);
1030 + * Initialize the RC32434 ethernet controller.
1032 +static int rc32434_init(struct net_device *dev)
1034 + struct rc32434_local *lp = (struct rc32434_local *)dev->priv;
1038 + rc32434_abort_tx(dev);
1039 + rc32434_abort_rx(dev);
1041 + /* reset ethernet logic */
1042 + __raw_writel(0, &lp->eth_regs->ethintfc);
1043 + while((__raw_readl(&lp->eth_regs->ethintfc) & ETHINTFC_rip_m))
1044 + dev->trans_start = jiffies;
1046 + /* Enable Ethernet Interface */
1047 + __raw_writel(ETHINTFC_en_m, &lp->eth_regs->ethintfc);
1049 +#ifndef CONFIG_IDT_USE_NAPI
1050 + tasklet_disable(lp->rx_tasklet);
1052 + tasklet_disable(lp->tx_tasklet);
1054 + /* Initialize the transmit Descriptors */
1055 + for (i = 0; i < RC32434_NUM_TDS; i++) {
1056 + lp->td_ring[i].control = DMAD_iof_m;
1057 + lp->td_ring[i].devcs = ETHTX_fd_m | ETHTX_ld_m;
1058 + lp->td_ring[i].ca = 0;
1059 + lp->td_ring[i].link = 0;
1060 + if (lp->tx_skb[i] != NULL) {
1061 + dev_kfree_skb_any(lp->tx_skb[i]);
1062 + lp->tx_skb[i] = NULL;
1065 + lp->tx_next_done = lp->tx_chain_head = lp->tx_chain_tail = lp->tx_full = lp->tx_count = 0;
1066 + lp-> tx_chain_status = empty;
1069 + * Initialize the receive descriptors so that they
1070 + * become a circular linked list, ie. let the last
1071 + * descriptor point to the first again.
1073 + for (i=0; i<RC32434_NUM_RDS; i++) {
1074 + struct sk_buff *skb = lp->rx_skb[i];
1076 + if (lp->rx_skb[i] == NULL) {
1077 + skb = dev_alloc_skb(RC32434_RBSIZE + 2);
1078 + if (skb == NULL) {
1079 + ERR("No memory in the system\n");
1080 + for (j = 0; j < RC32434_NUM_RDS; j ++)
1081 + if (lp->rx_skb[j] != NULL)
1082 + dev_kfree_skb_any(lp->rx_skb[j]);
1088 + skb_reserve(skb, 2);
1089 + lp->rx_skb[i] = skb;
1090 + lp->rd_ring[i].ca = CPHYSADDR(skb->data);
1094 + lp->rd_ring[i].control = DMAD_iod_m | DMA_COUNT(RC32434_RBSIZE);
1095 + lp->rd_ring[i].devcs = 0;
1096 + lp->rd_ring[i].ca = CPHYSADDR(skb->data);
1097 + lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
1101 + lp->rd_ring[RC32434_NUM_RDS-1].link = CPHYSADDR(&lp->rd_ring[0]);
1102 + lp->rx_next_done = 0;
1104 + lp->rd_ring[RC32434_NUM_RDS-1].control |= DMAD_cod_m;
1105 + lp->rx_chain_head = 0;
1106 + lp->rx_chain_tail = 0;
1107 + lp->rx_chain_status = empty;
1109 + __raw_writel(0, &lp->rx_dma_regs->dmas);
1110 + /* Start Rx DMA */
1111 + rc32434_start_rx(lp, &lp->rd_ring[0]);
1113 + /* Enable F E bit in Tx DMA */
1114 + __raw_writel(__raw_readl(&lp->tx_dma_regs->dmasm) & ~(DMASM_f_m | DMASM_e_m), &lp->tx_dma_regs->dmasm);
1115 + /* Enable D H E bit in Rx DMA */
1116 + __raw_writel(__raw_readl(&lp->rx_dma_regs->dmasm) & ~(DMASM_d_m | DMASM_h_m | DMASM_e_m), &lp->rx_dma_regs->dmasm);
1118 + /* Accept only packets destined for this Ethernet device address */
1119 + __raw_writel(ETHARC_ab_m, &lp->eth_regs->etharc);
1121 + /* Set all Ether station address registers to their initial values */
1122 + __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal0);
1123 + __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah0);
1125 + __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal1);
1126 + __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah1);
1128 + __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal2);
1129 + __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah2);
1131 + __raw_writel(STATION_ADDRESS_LOW(dev), &lp->eth_regs->ethsal3);
1132 + __raw_writel(STATION_ADDRESS_HIGH(dev), &lp->eth_regs->ethsah3);
1135 + /* Frame Length Checking, Pad Enable, CRC Enable, Full Duplex set */
1136 + __raw_writel(ETHMAC2_pe_m | ETHMAC2_cen_m | ETHMAC2_fd_m, &lp->eth_regs->ethmac2);
1137 + //ETHMAC2_flc_m ETHMAC2_fd_m lp->duplex_mode
1139 + /* Back to back inter-packet-gap */
1140 + __raw_writel(0x15, &lp->eth_regs->ethipgt);
1141 + /* Non - Back to back inter-packet-gap */
1142 + __raw_writel(0x12, &lp->eth_regs->ethipgr);
1144 + /* Management Clock Prescaler Divisor */
1145 + /* Clock independent setting */
1146 + __raw_writel(((idt_cpu_freq)/MII_CLOCK+1) & ~1,
1147 + &lp->eth_regs->ethmcp);
1149 + /* don't transmit until fifo contains 48b */
1150 + __raw_writel(48, &lp->eth_regs->ethfifott);
1152 + __raw_writel(ETHMAC1_re_m, &lp->eth_regs->ethmac1);
1154 +#ifndef CONFIG_IDT_USE_NAPI
1155 + tasklet_enable(lp->rx_tasklet);
1157 + tasklet_enable(lp->tx_tasklet);
1159 + netif_start_queue(dev);
1164 +static struct platform_driver korina_driver = {
1165 + .driver.name = "korina",
1166 + .probe = rc32434_probe,
1167 + .remove = rc32434_remove,
1170 +static int __init rc32434_init_module(void)
1172 + return platform_driver_register(&korina_driver);
1175 +static void rc32434_cleanup_module(void)
1177 + return platform_driver_unregister(&korina_driver);
1180 +module_init(rc32434_init_module);
1181 +module_exit(rc32434_cleanup_module);
1182 diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile
1183 --- linux.old/drivers/net/Makefile 2006-12-14 03:13:47.000000000 +0100
1184 +++ linux.dev/drivers/net/Makefile 2006-12-14 03:18:45.000000000 +0100
1187 obj-$(CONFIG_PLIP) += plip.o
1189 +obj-$(CONFIG_KORINA) += korina.o
1191 obj-$(CONFIG_ROADRUNNER) += rrunner.o
1193 obj-$(CONFIG_HAPPYMEAL) += sunhme.o
1194 diff -urN linux.old/drivers/net/rc32434_eth.h linux.dev/drivers/net/rc32434_eth.h
1195 --- linux.old/drivers/net/rc32434_eth.h 1970-01-01 01:00:00.000000000 +0100
1196 +++ linux.dev/drivers/net/rc32434_eth.h 2006-12-14 03:18:45.000000000 +0100
1198 +/**************************************************************************
1200 + * BRIEF MODULE DESCRIPTION
1201 + * Definitions for IDT RC32434 on-chip ethernet controller.
1203 + * Copyright 2004 IDT Inc. (rischelp@idt.com)
1205 + * This program is free software; you can redistribute it and/or modify it
1206 + * under the terms of the GNU General Public License as published by the
1207 + * Free Software Foundation; either version 2 of the License, or (at your
1208 + * option) any later version.
1210 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1211 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1212 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1213 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1214 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1215 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1216 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1217 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1218 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1219 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1221 + * You should have received a copy of the GNU General Public License along
1222 + * with this program; if not, write to the Free Software Foundation, Inc.,
1223 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1226 + **************************************************************************
1227 + * May 2004 rkt, neb
1235 + **************************************************************************
1239 +#include <asm/rc32434/rc32434.h>
1240 +#include <asm/rc32434/dma_v.h>
1241 +#include <asm/rc32434/eth_v.h>
1243 +#define CONFIG_IDT_USE_NAPI 1
1244 +#define RC32434_DEBUG 2
1245 +//#define RC32434_PROC_DEBUG
1246 +#undef RC32434_DEBUG
1248 +#ifdef RC32434_DEBUG
1250 +/* use 0 for production, 1 for verification, >2 for debug */
1251 +static int rc32434_debug = RC32434_DEBUG;
1252 +#define ASSERT(expr) \
1254 + printk( "Assertion failed! %s,%s,%s,line=%d\n", \
1255 + #expr,__FILE__,__FUNCTION__,__LINE__); }
1256 +#define DBG(lvl, format, arg...) if (rc32434_debug > lvl) printk(KERN_INFO "%s: " format, dev->name , ## arg)
1258 +#define ASSERT(expr) do {} while (0)
1259 +#define DBG(lvl, format, arg...) do {} while (0)
1262 +#define INFO(format, arg...) printk(KERN_INFO "%s: " format, dev->name , ## arg)
1263 +#define ERR(format, arg...) printk(KERN_ERR "%s: " format, dev->name , ## arg)
1264 +#define WARN(format, arg...) printk(KERN_WARNING "%s: " format, dev->name , ## arg)
1266 +/* the following must be powers of two */
1267 +#ifdef CONFIG_IDT_USE_NAPI
1268 +#define RC32434_NUM_RDS 64 /* number of receive descriptors */
1269 +#define RC32434_NUM_TDS 64 /* number of transmit descriptors */
1271 +#define RC32434_NUM_RDS 128 /* number of receive descriptors */
1272 +#define RC32434_NUM_TDS 128 /* number of transmit descriptors */
1275 +#define RC32434_RBSIZE 1536 /* size of one resource buffer = Ether MTU */
1276 +#define RC32434_RDS_MASK (RC32434_NUM_RDS-1)
1277 +#define RC32434_TDS_MASK (RC32434_NUM_TDS-1)
1278 +#define RD_RING_SIZE (RC32434_NUM_RDS * sizeof(struct DMAD_s))
1279 +#define TD_RING_SIZE (RC32434_NUM_TDS * sizeof(struct DMAD_s))
1281 +#define RC32434_TX_TIMEOUT HZ * 100
1283 +#define rc32434_eth0_regs ((ETH_t)(ETH0_VirtualAddress))
1284 +#define rc32434_eth1_regs ((ETH_t)(ETH1_VirtualAddress))
1286 +enum status { filled, empty};
1287 +#define IS_DMA_FINISHED(X) (((X) & (DMAD_f_m)) != 0)
1288 +#define IS_DMA_DONE(X) (((X) & (DMAD_d_m)) != 0)
1291 +/* Information that need to be kept for each board. */
1292 +struct rc32434_local {
1294 + DMA_Chan_t rx_dma_regs;
1295 + DMA_Chan_t tx_dma_regs;
1296 + volatile DMAD_t td_ring; /* transmit descriptor ring */
1297 + volatile DMAD_t rd_ring; /* receive descriptor ring */
1299 + struct sk_buff* tx_skb[RC32434_NUM_TDS]; /* skbuffs for pkt to trans */
1300 + struct sk_buff* rx_skb[RC32434_NUM_RDS]; /* skbuffs for pkt to trans */
1302 +#ifndef CONFIG_IDT_USE_NAPI
1303 + struct tasklet_struct * rx_tasklet;
1305 + struct tasklet_struct * tx_tasklet;
1308 + int rx_chain_head;
1309 + int rx_chain_tail;
1310 + enum status rx_chain_status;
1313 + int tx_chain_head;
1314 + int tx_chain_tail;
1315 + enum status tx_chain_status;
1319 + struct timer_list mii_phy_timer;
1320 + unsigned long duplex_mode;
1327 + struct net_device_stats stats;
1330 + /* debug /proc entry */
1331 + struct proc_dir_entry *ps;
1332 + int dma_halt_cnt; int dma_run_cnt;
1335 +extern unsigned int idt_cpu_freq;
1337 +/* Index to functions, as function prototypes. */
1338 +static int rc32434_open(struct net_device *dev);
1339 +static int rc32434_send_packet(struct sk_buff *skb, struct net_device *dev);
1340 +static void rc32434_mii_handler(unsigned long data);
1341 +static irqreturn_t rc32434_und_interrupt(int irq, void *dev_id);
1342 +static irqreturn_t rc32434_rx_dma_interrupt(int irq, void *dev_id);
1343 +static irqreturn_t rc32434_tx_dma_interrupt(int irq, void *dev_id);
1344 +#ifdef RC32434_REVISION
1345 +static irqreturn_t rc32434_ovr_interrupt(int irq, void *dev_id);
1347 +static int rc32434_close(struct net_device *dev);
1348 +static struct net_device_stats *rc32434_get_stats(struct net_device *dev);
1349 +static void rc32434_multicast_list(struct net_device *dev);
1350 +static int rc32434_init(struct net_device *dev);
1351 +static void rc32434_tx_timeout(struct net_device *dev);
1353 +static void rc32434_tx_tasklet(unsigned long tx_data_dev);
1354 +#ifdef CONFIG_IDT_USE_NAPI
1355 +static int rc32434_poll(struct net_device *rx_data_dev, int *budget);
1357 +static void rc32434_rx_tasklet(unsigned long rx_data_dev);
1359 +static void rc32434_cleanup_module(void);
1362 +static inline void rc32434_abort_dma(struct net_device *dev, DMA_Chan_t ch)
1364 + if (__raw_readl(&ch->dmac) & DMAC_run_m) {
1365 + __raw_writel(0x10, &ch->dmac);
1367 + while (!(__raw_readl(&ch->dmas) & DMAS_h_m))
1368 + dev->trans_start = jiffies;
1370 + __raw_writel(0, &ch->dmas);
1373 + __raw_writel(0, &ch->dmadptr);
1374 + __raw_writel(0, &ch->dmandptr);