1 /**************************************************************************
3 * BRIEF MODULE DESCRIPTION
4 * Driver for the IDT RC32434 on-chip ethernet controller.
6 * Copyright 2004 IDT Inc. (rischelp@idt.com)
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 **************************************************************************
32 * Based on the driver developed by B. Maruthanayakam, H. Kou and others.
38 **************************************************************************
41 #include <linux/autoconf.h>
42 #include <linux/version.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
45 #include <linux/moduleparam.h>
46 #include <linux/sched.h>
47 #include <linux/ctype.h>
48 #include <linux/types.h>
49 #include <linux/fcntl.h>
50 #include <linux/interrupt.h>
51 #include <linux/ptrace.h>
52 #include <linux/init.h>
53 #include <linux/ioport.h>
54 #include <linux/proc_fs.h>
56 #include <linux/slab.h>
57 #include <linux/string.h>
58 #include <linux/delay.h>
59 #include <linux/netdevice.h>
60 #include <linux/etherdevice.h>
61 #include <linux/skbuff.h>
62 #include <linux/errno.h>
63 #include <asm/bootinfo.h>
64 #include <asm/system.h>
65 #include <asm/bitops.h>
66 #include <asm/pgtable.h>
67 #include <asm/segment.h>
71 #include "rc32434_eth.h"
73 #define DRIVER_VERSION "(mar2904)"
75 #define DRIVER_NAME "rc32434 Ethernet driver. " DRIVER_VERSION
78 #define STATION_ADDRESS_HIGH(dev) (((dev)->dev_addr[0] << 8) | \
80 #define STATION_ADDRESS_LOW(dev) (((dev)->dev_addr[2] << 24) | \
81 ((dev)->dev_addr[3] << 16) | \
82 ((dev)->dev_addr[4] << 8) | \
85 #define MII_CLOCK 1250000 /* no more than 2.5MHz */
86 static char mac0
[18] = "08:00:06:05:40:01";
88 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,52)
89 module_param_string(mac0
, mac0
, 18, 0);
91 MODULE_PARM(mac0
, "c18");
93 MODULE_PARM_DESC(mac0
, "MAC address for RC32434 ethernet0");
95 static struct rc32434_if_t
{
97 struct net_device
*dev
;
110 "rc32434_eth0", NULL
, mac0
,
112 ETH0_PhysicalAddress
,
123 static int parse_mac_addr(struct net_device
*dev
, char* macstr
)
126 unsigned char result
, value
;
128 for (i
=0; i
<6; i
++) {
130 if (i
!= 5 && *(macstr
+2) != ':') {
131 ERR("invalid mac address format: %d %c\n",
135 for (j
=0; j
<2; j
++) {
136 if (isxdigit(*macstr
) && (value
= isdigit(*macstr
) ? *macstr
-'0' :
137 toupper(*macstr
)-'A'+10) < 16) {
138 result
= result
*16 + value
;
142 ERR("invalid mac address "
143 "character: %c\n", *macstr
);
149 dev
->dev_addr
[i
] = result
;
157 static inline void rc32434_abort_tx(struct net_device
*dev
)
159 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
160 rc32434_abort_dma(dev
, lp
->tx_dma_regs
);
164 static inline void rc32434_abort_rx(struct net_device
*dev
)
166 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
167 rc32434_abort_dma(dev
, lp
->rx_dma_regs
);
171 static inline void rc32434_start_tx(struct rc32434_local
*lp
, volatile DMAD_t td
)
173 rc32434_start_dma(lp
->tx_dma_regs
, CPHYSADDR(td
));
176 static inline void rc32434_start_rx(struct rc32434_local
*lp
, volatile DMAD_t rd
)
178 rc32434_start_dma(lp
->rx_dma_regs
, CPHYSADDR(rd
));
181 static inline void rc32434_chain_tx(struct rc32434_local
*lp
, volatile DMAD_t td
)
183 rc32434_chain_dma(lp
->tx_dma_regs
, CPHYSADDR(td
));
186 static inline void rc32434_chain_rx(struct rc32434_local
*lp
, volatile DMAD_t rd
)
188 rc32434_chain_dma(lp
->rx_dma_regs
, CPHYSADDR(rd
));
191 #ifdef RC32434_PROC_DEBUG
192 static int rc32434_read_proc(char *buf
, char **start
, off_t fpos
,
193 int length
, int *eof
, void *data
)
195 struct net_device
*dev
= (struct net_device
*)data
;
196 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
199 /* print out header */
200 len
+= sprintf(buf
+ len
, "\n\tRC32434 Ethernet Debug\n\n");
201 len
+= sprintf (buf
+ len
,
202 "DMA halt count = %10d, DMA run count = %10d\n",
203 lp
->dma_halt_cnt
, lp
->dma_run_cnt
);
212 if ((len
-= fpos
) > length
)
223 * Restart the RC32434 ethernet controller.
225 static int rc32434_restart(struct net_device
*dev
)
227 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
232 disable_irq(lp
->rx_irq
);
233 disable_irq(lp
->tx_irq
);
234 #ifdef RC32434_REVISION
235 disable_irq(lp
->ovr_irq
);
237 disable_irq(lp
->und_irq
);
239 /* Mask F E bit in Tx DMA */
240 rc32434_writel(rc32434_readl(&lp
->tx_dma_regs
->dmasm
) | DMASM_f_m
| DMASM_e_m
, &lp
->tx_dma_regs
->dmasm
);
241 /* Mask D H E bit in Rx DMA */
242 rc32434_writel(rc32434_readl(&lp
->rx_dma_regs
->dmasm
) | DMASM_d_m
| DMASM_h_m
| DMASM_e_m
, &lp
->rx_dma_regs
->dmasm
);
245 rc32434_multicast_list(dev
);
247 enable_irq(lp
->und_irq
);
248 #ifdef RC32434_REVISION
249 enable_irq(lp
->ovr_irq
);
251 enable_irq(lp
->tx_irq
);
252 enable_irq(lp
->rx_irq
);
257 int rc32434_init_module(void)
259 #ifdef CONFIG_MACH_ARUBA
260 if (mips_machtype
!= MACH_ARUBA_AP70
)
264 printk(KERN_INFO DRIVER_NAME
" \n");
265 return rc32434_probe(0);
268 static int rc32434_probe(int port_num
)
270 struct rc32434_if_t
*bif
= &rc32434_iflist
[port_num
];
271 struct rc32434_local
*lp
= NULL
;
272 struct net_device
*dev
= NULL
;
275 dev
= alloc_etherdev(sizeof(struct rc32434_local
));
277 ERR("rc32434_eth: alloc_etherdev failed\n");
281 SET_MODULE_OWNER(dev
);
284 #ifdef CONFIG_MACH_ARUBA
286 extern char * getenv(char *e
);
287 memcpy(bif
->mac_str
, getenv("ethaddr"), 17);
291 printk("mac: %s\n", bif
->mac_str
);
292 if ((retval
= parse_mac_addr(dev
, bif
->mac_str
))) {
293 ERR("MAC address parse failed\n");
299 /* Initialize the device structure. */
300 if (dev
->priv
== NULL
) {
301 lp
= (struct rc32434_local
*)kmalloc(sizeof(*lp
), GFP_KERNEL
);
302 memset(lp
, 0, sizeof(struct rc32434_local
));
305 lp
= (struct rc32434_local
*)dev
->priv
;
308 lp
->rx_irq
= bif
->rx_dma_irq
;
309 lp
->tx_irq
= bif
->tx_dma_irq
;
310 lp
->ovr_irq
= bif
->rx_ovr_irq
;
311 lp
->und_irq
= bif
->tx_und_irq
;
313 lp
->eth_regs
= ioremap_nocache(bif
->iobase
, sizeof(*lp
->eth_regs
));
316 ERR("Can't remap eth registers\n");
321 lp
->rx_dma_regs
= ioremap_nocache(bif
->rxdmabase
, sizeof(struct DMA_Chan_s
));
323 if (!lp
->rx_dma_regs
) {
324 ERR("Can't remap Rx DMA registers\n");
328 lp
->tx_dma_regs
= ioremap_nocache(bif
->txdmabase
,sizeof(struct DMA_Chan_s
));
330 if (!lp
->tx_dma_regs
) {
331 ERR("Can't remap Tx DMA registers\n");
336 #ifdef RC32434_PROC_DEBUG
337 lp
->ps
= create_proc_read_entry (bif
->name
, 0, proc_net
,
338 rc32434_read_proc
, dev
);
341 lp
->td_ring
= (DMAD_t
)kmalloc(TD_RING_SIZE
+ RD_RING_SIZE
, GFP_KERNEL
);
343 ERR("Can't allocate descriptors\n");
348 dma_cache_inv((unsigned long)(lp
->td_ring
), TD_RING_SIZE
+ RD_RING_SIZE
);
350 /* now convert TD_RING pointer to KSEG1 */
351 lp
->td_ring
= (DMAD_t
)KSEG1ADDR(lp
->td_ring
);
352 lp
->rd_ring
= &lp
->td_ring
[RC32434_NUM_TDS
];
355 spin_lock_init(&lp
->lock
);
357 dev
->base_addr
= bif
->iobase
;
358 /* just use the rx dma irq */
359 dev
->irq
= bif
->rx_dma_irq
;
363 dev
->open
= rc32434_open
;
364 dev
->stop
= rc32434_close
;
365 dev
->hard_start_xmit
= rc32434_send_packet
;
366 dev
->get_stats
= rc32434_get_stats
;
367 dev
->set_multicast_list
= &rc32434_multicast_list
;
368 dev
->tx_timeout
= rc32434_tx_timeout
;
369 dev
->watchdog_timeo
= RC32434_TX_TIMEOUT
;
371 #ifdef CONFIG_IDT_USE_NAPI
372 dev
->poll
= rc32434_poll
;
373 dev
->weight
= bif
->weight
;
374 printk("Using NAPI with weight %d\n",dev
->weight
);
376 lp
->rx_tasklet
= kmalloc(sizeof(struct tasklet_struct
), GFP_KERNEL
);
377 tasklet_init(lp
->rx_tasklet
, rc32434_rx_tasklet
, (unsigned long)dev
);
379 lp
->tx_tasklet
= kmalloc(sizeof(struct tasklet_struct
), GFP_KERNEL
);
380 tasklet_init(lp
->tx_tasklet
, rc32434_tx_tasklet
, (unsigned long)dev
);
382 if ((err
= register_netdev(dev
))) {
383 printk(KERN_ERR
"rc32434 ethernet. Cannot register net device %d\n", err
);
389 INFO("Rx IRQ %d, Tx IRQ %d, ", bif
->rx_dma_irq
, bif
->tx_dma_irq
);
390 for (i
= 0; i
< 6; i
++) {
391 printk("%2.2x", dev
->dev_addr
[i
]);
400 rc32434_cleanup_module();
401 ERR(" failed. Returns %d\n", retval
);
407 static void rc32434_cleanup_module(void)
411 for (i
= 0; rc32434_iflist
[i
].iobase
; i
++) {
412 struct rc32434_if_t
* bif
= &rc32434_iflist
[i
];
413 if (bif
->dev
!= NULL
) {
414 struct rc32434_local
*lp
= (struct rc32434_local
*)bif
->dev
->priv
;
417 iounmap((void*)lp
->eth_regs
);
419 iounmap((void*)lp
->rx_dma_regs
);
421 iounmap((void*)lp
->tx_dma_regs
);
423 kfree((void*)KSEG0ADDR(lp
->td_ring
));
425 #ifdef RC32434_PROC_DEBUG
427 remove_proc_entry(bif
->name
, proc_net
);
433 unregister_netdev(bif
->dev
);
434 free_netdev(bif
->dev
);
442 static int rc32434_open(struct net_device
*dev
)
444 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
447 if (rc32434_init(dev
)) {
448 ERR("Error: cannot open the Ethernet device\n");
452 /* Install the interrupt handler that handles the Done Finished Ovr and Und Events */
453 if (request_irq(lp
->rx_irq
, &rc32434_rx_dma_interrupt
,
454 SA_SHIRQ
| SA_INTERRUPT
,
455 "rc32434 ethernet Rx", dev
)) {
456 ERR(": unable to get Rx DMA IRQ %d\n",
460 if (request_irq(lp
->tx_irq
, &rc32434_tx_dma_interrupt
,
461 SA_SHIRQ
| SA_INTERRUPT
,
462 "rc32434 ethernet Tx", dev
)) {
463 ERR(": unable to get Tx DMA IRQ %d\n",
465 free_irq(lp
->rx_irq
, dev
);
469 #ifdef RC32434_REVISION
470 /* Install handler for overrun error. */
471 if (request_irq(lp
->ovr_irq
, &rc32434_ovr_interrupt
,
472 SA_SHIRQ
| SA_INTERRUPT
,
473 "Ethernet Overflow", dev
)) {
474 ERR(": unable to get OVR IRQ %d\n",
476 free_irq(lp
->rx_irq
, dev
);
477 free_irq(lp
->tx_irq
, dev
);
482 /* Install handler for underflow error. */
483 if (request_irq(lp
->und_irq
, &rc32434_und_interrupt
,
484 SA_SHIRQ
| SA_INTERRUPT
,
485 "Ethernet Underflow", dev
)) {
486 ERR(": unable to get UND IRQ %d\n",
488 free_irq(lp
->rx_irq
, dev
);
489 free_irq(lp
->tx_irq
, dev
);
490 #ifdef RC32434_REVISION
491 free_irq(lp
->ovr_irq
, dev
);
503 static int rc32434_close(struct net_device
*dev
)
505 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
508 /* Disable interrupts */
509 disable_irq(lp
->rx_irq
);
510 disable_irq(lp
->tx_irq
);
511 #ifdef RC32434_REVISION
512 disable_irq(lp
->ovr_irq
);
514 disable_irq(lp
->und_irq
);
516 tmp
= rc32434_readl(&lp
->tx_dma_regs
->dmasm
);
517 tmp
= tmp
| DMASM_f_m
| DMASM_e_m
;
518 rc32434_writel(tmp
, &lp
->tx_dma_regs
->dmasm
);
520 tmp
= rc32434_readl(&lp
->rx_dma_regs
->dmasm
);
521 tmp
= tmp
| DMASM_d_m
| DMASM_h_m
| DMASM_e_m
;
522 rc32434_writel(tmp
, &lp
->rx_dma_regs
->dmasm
);
524 free_irq(lp
->rx_irq
, dev
);
525 free_irq(lp
->tx_irq
, dev
);
526 #ifdef RC32434_REVISION
527 free_irq(lp
->ovr_irq
, dev
);
529 free_irq(lp
->und_irq
, dev
);
534 /* transmit packet */
535 static int rc32434_send_packet(struct sk_buff
*skb
, struct net_device
*dev
)
537 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
543 spin_lock_irqsave(&lp
->lock
, flags
);
545 td
= &lp
->td_ring
[lp
->tx_chain_tail
];
547 /* stop queue when full, drop pkts if queue already full */
548 if(lp
->tx_count
>= (RC32434_NUM_TDS
- 2)) {
551 if(lp
->tx_count
== (RC32434_NUM_TDS
- 2)) {
552 netif_stop_queue(dev
);
555 lp
->stats
.tx_dropped
++;
556 dev_kfree_skb_any(skb
);
557 spin_unlock_irqrestore(&lp
->lock
, flags
);
564 lp
->tx_skb
[lp
->tx_chain_tail
] = skb
;
568 /* Setup the transmit descriptor. */
569 td
->ca
= CPHYSADDR(skb
->data
);
571 if(rc32434_readl(&(lp
->tx_dma_regs
->dmandptr
)) == 0) {
572 if( lp
->tx_chain_status
== empty
) {
573 td
->control
= DMA_COUNT(length
) |DMAD_cof_m
|DMAD_iof_m
; /* Update tail */
574 lp
->tx_chain_tail
= (lp
->tx_chain_tail
+ 1) & RC32434_TDS_MASK
; /* Move tail */
575 rc32434_writel(CPHYSADDR(&lp
->td_ring
[lp
->tx_chain_head
]), &(lp
->tx_dma_regs
->dmandptr
)); /* Write to NDPTR */
576 lp
->tx_chain_head
= lp
->tx_chain_tail
; /* Move head to tail */
579 td
->control
= DMA_COUNT(length
) |DMAD_cof_m
|DMAD_iof_m
; /* Update tail */
580 lp
->td_ring
[(lp
->tx_chain_tail
-1)& RC32434_TDS_MASK
].control
&= ~(DMAD_cof_m
); /* Link to prev */
581 lp
->td_ring
[(lp
->tx_chain_tail
-1)& RC32434_TDS_MASK
].link
= CPHYSADDR(td
); /* Link to prev */
582 lp
->tx_chain_tail
= (lp
->tx_chain_tail
+ 1) & RC32434_TDS_MASK
; /* Move tail */
583 rc32434_writel(CPHYSADDR(&lp
->td_ring
[lp
->tx_chain_head
]), &(lp
->tx_dma_regs
->dmandptr
)); /* Write to NDPTR */
584 lp
->tx_chain_head
= lp
->tx_chain_tail
; /* Move head to tail */
585 lp
->tx_chain_status
= empty
;
589 if( lp
->tx_chain_status
== empty
) {
590 td
->control
= DMA_COUNT(length
) |DMAD_cof_m
|DMAD_iof_m
; /* Update tail */
591 lp
->tx_chain_tail
= (lp
->tx_chain_tail
+ 1) & RC32434_TDS_MASK
; /* Move tail */
592 lp
->tx_chain_status
= filled
;
595 td
->control
= DMA_COUNT(length
) |DMAD_cof_m
|DMAD_iof_m
; /* Update tail */
596 lp
->td_ring
[(lp
->tx_chain_tail
-1)& RC32434_TDS_MASK
].control
&= ~(DMAD_cof_m
); /* Link to prev */
597 lp
->td_ring
[(lp
->tx_chain_tail
-1)& RC32434_TDS_MASK
].link
= CPHYSADDR(td
); /* Link to prev */
598 lp
->tx_chain_tail
= (lp
->tx_chain_tail
+ 1) & RC32434_TDS_MASK
; /* Move tail */
602 dev
->trans_start
= jiffies
;
604 spin_unlock_irqrestore(&lp
->lock
, flags
);
610 /* Ethernet MII-PHY Handler */
611 static void rc32434_mii_handler(unsigned long data
)
613 struct net_device
*dev
= (struct net_device
*)data
;
614 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
616 unsigned long duplex_status
;
617 int port_addr
= (lp
->rx_irq
== 0x2c? 1:0) << 8;
619 spin_lock_irqsave(&lp
->lock
, flags
);
621 /* Two ports are using the same MII, the difference is the PHY address */
622 rc32434_writel(0, &rc32434_eth0_regs
->miimcfg
);
623 rc32434_writel(0, &rc32434_eth0_regs
->miimcmd
);
624 rc32434_writel(port_addr
|0x05, &rc32434_eth0_regs
->miimaddr
);
625 rc32434_writel(MIIMCMD_scn_m
, &rc32434_eth0_regs
->miimcmd
);
626 while(rc32434_readl(&rc32434_eth0_regs
->miimind
) & MIIMIND_nv_m
);
628 ERR("irq:%x port_addr:%x RDD:%x\n",
629 lp
->rx_irq
, port_addr
, rc32434_readl(&rc32434_eth0_regs
->miimrdd
));
630 duplex_status
= (rc32434_readl(&rc32434_eth0_regs
->miimrdd
) & 0x140)? ETHMAC2_fd_m
: 0;
631 if(duplex_status
!= lp
->duplex_mode
) {
632 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);
633 lp
->duplex_mode
= duplex_status
;
634 rc32434_restart(dev
);
637 lp
->mii_phy_timer
.expires
= jiffies
+ 10 * HZ
;
638 add_timer(&lp
->mii_phy_timer
);
640 spin_unlock_irqrestore(&lp
->lock
, flags
);
644 #ifdef RC32434_REVISION
645 /* Ethernet Rx Overflow interrupt */
647 rc32434_ovr_interrupt(int irq
, void *dev_id
)
649 struct net_device
*dev
= (struct net_device
*)dev_id
;
650 struct rc32434_local
*lp
;
652 irqreturn_t retval
= IRQ_NONE
;
656 lp
= (struct rc32434_local
*)dev
->priv
;
657 spin_lock(&lp
->lock
);
658 ovr
= rc32434_readl(&lp
->eth_regs
->ethintfc
);
660 if(ovr
& ETHINTFC_ovr_m
) {
661 netif_stop_queue(dev
);
664 rc32434_writel((ovr
& ~ETHINTFC_ovr_m
), &lp
->eth_regs
->ethintfc
);
666 /* Restart interface */
667 rc32434_restart(dev
);
668 retval
= IRQ_HANDLED
;
670 spin_unlock(&lp
->lock
);
678 /* Ethernet Tx Underflow interrupt */
680 rc32434_und_interrupt(int irq
, void *dev_id
)
682 struct net_device
*dev
= (struct net_device
*)dev_id
;
683 struct rc32434_local
*lp
;
685 irqreturn_t retval
= IRQ_NONE
;
689 lp
= (struct rc32434_local
*)dev
->priv
;
691 spin_lock(&lp
->lock
);
693 und
= rc32434_readl(&lp
->eth_regs
->ethintfc
);
695 if(und
& ETHINTFC_und_m
) {
696 netif_stop_queue(dev
);
698 rc32434_writel((und
& ~ETHINTFC_und_m
), &lp
->eth_regs
->ethintfc
);
700 /* Restart interface */
701 rc32434_restart(dev
);
702 retval
= IRQ_HANDLED
;
705 spin_unlock(&lp
->lock
);
711 /* Ethernet Rx DMA interrupt */
713 rc32434_rx_dma_interrupt(int irq
, void *dev_id
)
715 struct net_device
*dev
= (struct net_device
*)dev_id
;
716 struct rc32434_local
* lp
;
717 volatile u32 dmas
,dmasm
;
722 lp
= (struct rc32434_local
*)dev
->priv
;
724 spin_lock(&lp
->lock
);
725 dmas
= rc32434_readl(&lp
->rx_dma_regs
->dmas
);
726 if(dmas
& (DMAS_d_m
|DMAS_h_m
|DMAS_e_m
)) {
727 /* Mask D H E bit in Rx DMA */
728 dmasm
= rc32434_readl(&lp
->rx_dma_regs
->dmasm
);
729 rc32434_writel(dmasm
| (DMASM_d_m
| DMASM_h_m
| DMASM_e_m
), &lp
->rx_dma_regs
->dmasm
);
730 #ifdef CONFIG_IDT_USE_NAPI
731 if(netif_rx_schedule_prep(dev
))
732 __netif_rx_schedule(dev
);
734 tasklet_hi_schedule(lp
->rx_tasklet
);
738 ERR(": DMA error\n");
740 retval
= IRQ_HANDLED
;
745 spin_unlock(&lp
->lock
);
749 #ifdef CONFIG_IDT_USE_NAPI
750 static int rc32434_poll(struct net_device
*rx_data_dev
, int *budget
)
752 static void rc32434_rx_tasklet(unsigned long rx_data_dev
)
755 struct net_device
*dev
= (struct net_device
*)rx_data_dev
;
756 struct rc32434_local
* lp
= netdev_priv(dev
);
757 volatile DMAD_t rd
= &lp
->rd_ring
[lp
->rx_next_done
];
758 struct sk_buff
*skb
, *skb_new
;
760 u32 devcs
, count
, pkt_len
, pktuncrc_len
;
762 #ifdef CONFIG_IDT_USE_NAPI
764 int rx_work_limit
= min(*budget
,dev
->quota
);
767 spin_lock_irqsave(&lp
->lock
, flags
);
770 while ( (count
= RC32434_RBSIZE
- (u32
)DMA_COUNT(rd
->control
)) != 0) {
771 #ifdef CONFIG_IDT_USE_NAPI
772 if(--rx_work_limit
<0)
777 /* init the var. used for the later operations within the while loop */
780 pkt_len
= RCVPKT_LENGTH(devcs
);
781 skb
= lp
->rx_skb
[lp
->rx_next_done
];
784 lp
->stats
.rx_errors
++;
785 lp
->stats
.rx_dropped
++;
787 else if ((devcs
& ( ETHRX_ld_m
)) != ETHRX_ld_m
) {
788 /* check that this is a whole packet */
789 /* WARNING: DMA_FD bit incorrectly set in Rc32434 (errata ref #077) */
790 lp
->stats
.rx_errors
++;
791 lp
->stats
.rx_dropped
++;
793 else if ( (devcs
& ETHRX_rok_m
) ) {
796 /* must be the (first and) last descriptor then */
797 pkt_buf
= (u8
*)lp
->rx_skb
[lp
->rx_next_done
]->data
;
799 pktuncrc_len
= pkt_len
- 4;
800 /* invalidate the cache */
801 dma_cache_inv((unsigned long)pkt_buf
, pktuncrc_len
);
803 /* Malloc up new buffer. */
804 skb_new
= dev_alloc_skb(RC32434_RBSIZE
+ 2);
806 if (skb_new
!= NULL
){
808 skb_put(skb
, pktuncrc_len
);
810 skb
->protocol
= eth_type_trans(skb
, dev
);
812 /* pass the packet to upper layers */
813 #ifdef CONFIG_IDT_USE_NAPI
814 netif_receive_skb(skb
);
819 dev
->last_rx
= jiffies
;
820 lp
->stats
.rx_packets
++;
821 lp
->stats
.rx_bytes
+= pktuncrc_len
;
823 if (IS_RCV_MP(devcs
))
824 lp
->stats
.multicast
++;
827 skb_reserve(skb_new
, 2);
830 lp
->rx_skb
[lp
->rx_next_done
] = skb_new
;
833 ERR("no memory, dropping rx packet.\n");
834 lp
->stats
.rx_errors
++;
835 lp
->stats
.rx_dropped
++;
841 /* This should only happen if we enable accepting broken packets */
842 lp
->stats
.rx_errors
++;
843 lp
->stats
.rx_dropped
++;
845 /* add statistics counters */
846 if (IS_RCV_CRC_ERR(devcs
)) {
847 DBG(2, "RX CRC error\n");
848 lp
->stats
.rx_crc_errors
++;
850 else if (IS_RCV_LOR_ERR(devcs
)) {
851 DBG(2, "RX LOR error\n");
852 lp
->stats
.rx_length_errors
++;
854 else if (IS_RCV_LE_ERR(devcs
)) {
855 DBG(2, "RX LE error\n");
856 lp
->stats
.rx_length_errors
++;
858 else if (IS_RCV_OVR_ERR(devcs
)) {
859 lp
->stats
.rx_over_errors
++;
861 else if (IS_RCV_CV_ERR(devcs
)) {
863 DBG(2, "RX CV error\n");
864 lp
->stats
.rx_frame_errors
++;
866 else if (IS_RCV_CES_ERR(devcs
)) {
867 DBG(2, "RX Preamble error\n");
873 /* restore descriptor's curr_addr */
875 rd
->ca
= CPHYSADDR(skb_new
->data
);
877 rd
->ca
= CPHYSADDR(skb
->data
);
879 rd
->control
= DMA_COUNT(RC32434_RBSIZE
) |DMAD_cod_m
|DMAD_iod_m
;
880 lp
->rd_ring
[(lp
->rx_next_done
-1)& RC32434_RDS_MASK
].control
&= ~(DMAD_cod_m
);
882 lp
->rx_next_done
= (lp
->rx_next_done
+ 1) & RC32434_RDS_MASK
;
883 rd
= &lp
->rd_ring
[lp
->rx_next_done
];
884 rc32434_writel( ~DMAS_d_m
, &lp
->rx_dma_regs
->dmas
);
886 #ifdef CONFIG_IDT_USE_NAPI
887 dev
->quota
-= received
;
889 if(rx_work_limit
< 0)
893 dmas
= rc32434_readl(&lp
->rx_dma_regs
->dmas
);
895 if(dmas
& DMAS_h_m
) {
896 rc32434_writel( ~(DMAS_h_m
| DMAS_e_m
), &lp
->rx_dma_regs
->dmas
);
897 #ifdef RC32434_PROC_DEBUG
901 skb
= lp
->rx_skb
[lp
->rx_next_done
];
902 rd
->ca
= CPHYSADDR(skb
->data
);
903 rc32434_chain_rx(lp
,rd
);
906 #ifdef CONFIG_IDT_USE_NAPI
907 netif_rx_complete(dev
);
909 /* Enable D H E bit in Rx DMA */
910 rc32434_writel(rc32434_readl(&lp
->rx_dma_regs
->dmasm
) & ~(DMASM_d_m
| DMASM_h_m
|DMASM_e_m
), &lp
->rx_dma_regs
->dmasm
);
911 #ifdef CONFIG_IDT_USE_NAPI
916 spin_unlock_irqrestore(&lp
->lock
, flags
);
925 /* Ethernet Tx DMA interrupt */
927 rc32434_tx_dma_interrupt(int irq
, void *dev_id
)
929 struct net_device
*dev
= (struct net_device
*)dev_id
;
930 struct rc32434_local
*lp
;
931 volatile u32 dmas
,dmasm
;
936 lp
= (struct rc32434_local
*)dev
->priv
;
938 spin_lock(&lp
->lock
);
940 dmas
= rc32434_readl(&lp
->tx_dma_regs
->dmas
);
942 if (dmas
& (DMAS_f_m
| DMAS_e_m
)) {
943 dmasm
= rc32434_readl(&lp
->tx_dma_regs
->dmasm
);
944 /* Mask F E bit in Tx DMA */
945 rc32434_writel(dmasm
| (DMASM_f_m
| DMASM_e_m
), &lp
->tx_dma_regs
->dmasm
);
947 tasklet_hi_schedule(lp
->tx_tasklet
);
949 if(lp
->tx_chain_status
== filled
&& (rc32434_readl(&(lp
->tx_dma_regs
->dmandptr
)) == 0)) {
950 rc32434_writel(CPHYSADDR(&lp
->td_ring
[lp
->tx_chain_head
]), &(lp
->tx_dma_regs
->dmandptr
));
951 lp
->tx_chain_status
= empty
;
952 lp
->tx_chain_head
= lp
->tx_chain_tail
;
953 dev
->trans_start
= jiffies
;
957 ERR(": DMA error\n");
959 retval
= IRQ_HANDLED
;
964 spin_unlock(&lp
->lock
);
970 static void rc32434_tx_tasklet(unsigned long tx_data_dev
)
972 struct net_device
*dev
= (struct net_device
*)tx_data_dev
;
973 struct rc32434_local
* lp
= (struct rc32434_local
*)dev
->priv
;
974 volatile DMAD_t td
= &lp
->td_ring
[lp
->tx_next_done
];
979 spin_lock_irqsave(&lp
->lock
, flags
);
981 /* process all desc that are done */
982 while(IS_DMA_FINISHED(td
->control
)) {
983 if(lp
->tx_full
== 1) {
984 netif_wake_queue(dev
);
988 devcs
= lp
->td_ring
[lp
->tx_next_done
].devcs
;
989 if ((devcs
& (ETHTX_fd_m
| ETHTX_ld_m
)) != (ETHTX_fd_m
| ETHTX_ld_m
)) {
990 lp
->stats
.tx_errors
++;
991 lp
->stats
.tx_dropped
++;
993 /* should never happen */
994 DBG(1, __FUNCTION__
": split tx ignored\n");
996 else if (IS_TX_TOK(devcs
)) {
997 lp
->stats
.tx_packets
++;
1000 lp
->stats
.tx_errors
++;
1001 lp
->stats
.tx_dropped
++;
1004 if (IS_TX_UND_ERR(devcs
))
1005 lp
->stats
.tx_fifo_errors
++;
1007 /* oversized frame */
1008 if (IS_TX_OF_ERR(devcs
))
1009 lp
->stats
.tx_aborted_errors
++;
1011 /* excessive deferrals */
1012 if (IS_TX_ED_ERR(devcs
))
1013 lp
->stats
.tx_carrier_errors
++;
1015 /* collisions: medium busy */
1016 if (IS_TX_EC_ERR(devcs
))
1017 lp
->stats
.collisions
++;
1019 /* late collision */
1020 if (IS_TX_LC_ERR(devcs
))
1021 lp
->stats
.tx_window_errors
++;
1025 /* We must always free the original skb */
1026 if (lp
->tx_skb
[lp
->tx_next_done
] != NULL
) {
1027 dev_kfree_skb_any(lp
->tx_skb
[lp
->tx_next_done
]);
1028 lp
->tx_skb
[lp
->tx_next_done
] = NULL
;
1031 lp
->td_ring
[lp
->tx_next_done
].control
= DMAD_iof_m
;
1032 lp
->td_ring
[lp
->tx_next_done
].devcs
= ETHTX_fd_m
| ETHTX_ld_m
;
1033 lp
->td_ring
[lp
->tx_next_done
].link
= 0;
1034 lp
->td_ring
[lp
->tx_next_done
].ca
= 0;
1037 /* go on to next transmission */
1038 lp
->tx_next_done
= (lp
->tx_next_done
+ 1) & RC32434_TDS_MASK
;
1039 td
= &lp
->td_ring
[lp
->tx_next_done
];
1043 dmas
= rc32434_readl(&lp
->tx_dma_regs
->dmas
);
1044 rc32434_writel( ~dmas
, &lp
->tx_dma_regs
->dmas
);
1046 /* Enable F E bit in Tx DMA */
1047 rc32434_writel(rc32434_readl(&lp
->tx_dma_regs
->dmasm
) & ~(DMASM_f_m
| DMASM_e_m
), &lp
->tx_dma_regs
->dmasm
);
1048 spin_unlock_irqrestore(&lp
->lock
, flags
);
1053 static struct net_device_stats
* rc32434_get_stats(struct net_device
*dev
)
1055 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
1061 * Set or clear the multicast filter for this adaptor.
1063 static void rc32434_multicast_list(struct net_device
*dev
)
1065 /* listen to broadcasts always and to treat */
1066 /* IFF bits independantly */
1067 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
1068 unsigned long flags
;
1069 u32 recognise
= ETHARC_ab_m
; /* always accept broadcasts */
1071 if (dev
->flags
& IFF_PROMISC
) /* set promiscuous mode */
1072 recognise
|= ETHARC_pro_m
;
1074 if ((dev
->flags
& IFF_ALLMULTI
) || (dev
->mc_count
> 15))
1075 recognise
|= ETHARC_am_m
; /* all multicast & bcast */
1076 else if (dev
->mc_count
> 0) {
1077 DBG(2, __FUNCTION__
": mc_count %d\n", dev
->mc_count
);
1078 recognise
|= ETHARC_am_m
; /* for the time being */
1081 spin_lock_irqsave(&lp
->lock
, flags
);
1082 rc32434_writel(recognise
, &lp
->eth_regs
->etharc
);
1083 spin_unlock_irqrestore(&lp
->lock
, flags
);
1087 static void rc32434_tx_timeout(struct net_device
*dev
)
1089 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
1090 unsigned long flags
;
1092 spin_lock_irqsave(&lp
->lock
, flags
);
1093 rc32434_restart(dev
);
1094 spin_unlock_irqrestore(&lp
->lock
, flags
);
1100 * Initialize the RC32434 ethernet controller.
1102 static int rc32434_init(struct net_device
*dev
)
1104 struct rc32434_local
*lp
= (struct rc32434_local
*)dev
->priv
;
1108 rc32434_abort_tx(dev
);
1109 rc32434_abort_rx(dev
);
1111 /* reset ethernet logic */
1112 rc32434_writel(0, &lp
->eth_regs
->ethintfc
);
1113 while((rc32434_readl(&lp
->eth_regs
->ethintfc
) & ETHINTFC_rip_m
))
1114 dev
->trans_start
= jiffies
;
1116 /* Enable Ethernet Interface */
1117 rc32434_writel(ETHINTFC_en_m
, &lp
->eth_regs
->ethintfc
);
1119 #ifndef CONFIG_IDT_USE_NAPI
1120 tasklet_disable(lp
->rx_tasklet
);
1122 tasklet_disable(lp
->tx_tasklet
);
1124 /* Initialize the transmit Descriptors */
1125 for (i
= 0; i
< RC32434_NUM_TDS
; i
++) {
1126 lp
->td_ring
[i
].control
= DMAD_iof_m
;
1127 lp
->td_ring
[i
].devcs
= ETHTX_fd_m
| ETHTX_ld_m
;
1128 lp
->td_ring
[i
].ca
= 0;
1129 lp
->td_ring
[i
].link
= 0;
1130 if (lp
->tx_skb
[i
] != NULL
) {
1131 dev_kfree_skb_any(lp
->tx_skb
[i
]);
1132 lp
->tx_skb
[i
] = NULL
;
1135 lp
->tx_next_done
= lp
->tx_chain_head
= lp
->tx_chain_tail
= lp
->tx_full
= lp
->tx_count
= 0;
1136 lp
-> tx_chain_status
= empty
;
1139 * Initialize the receive descriptors so that they
1140 * become a circular linked list, ie. let the last
1141 * descriptor point to the first again.
1143 for (i
=0; i
<RC32434_NUM_RDS
; i
++) {
1144 struct sk_buff
*skb
= lp
->rx_skb
[i
];
1146 if (lp
->rx_skb
[i
] == NULL
) {
1147 skb
= dev_alloc_skb(RC32434_RBSIZE
+ 2);
1149 ERR("No memory in the system\n");
1150 for (j
= 0; j
< RC32434_NUM_RDS
; j
++)
1151 if (lp
->rx_skb
[j
] != NULL
)
1152 dev_kfree_skb_any(lp
->rx_skb
[j
]);
1158 skb_reserve(skb
, 2);
1159 lp
->rx_skb
[i
] = skb
;
1160 lp
->rd_ring
[i
].ca
= CPHYSADDR(skb
->data
);
1164 lp
->rd_ring
[i
].control
= DMAD_iod_m
| DMA_COUNT(RC32434_RBSIZE
);
1165 lp
->rd_ring
[i
].devcs
= 0;
1166 lp
->rd_ring
[i
].ca
= CPHYSADDR(skb
->data
);
1167 lp
->rd_ring
[i
].link
= CPHYSADDR(&lp
->rd_ring
[i
+1]);
1171 lp
->rd_ring
[RC32434_NUM_RDS
-1].link
= CPHYSADDR(&lp
->rd_ring
[0]);
1172 lp
->rx_next_done
= 0;
1174 lp
->rd_ring
[RC32434_NUM_RDS
-1].control
|= DMAD_cod_m
;
1175 lp
->rx_chain_head
= 0;
1176 lp
->rx_chain_tail
= 0;
1177 lp
->rx_chain_status
= empty
;
1179 rc32434_writel(0, &lp
->rx_dma_regs
->dmas
);
1181 rc32434_start_rx(lp
, &lp
->rd_ring
[0]);
1183 /* Enable F E bit in Tx DMA */
1184 rc32434_writel(rc32434_readl(&lp
->tx_dma_regs
->dmasm
) & ~(DMASM_f_m
| DMASM_e_m
), &lp
->tx_dma_regs
->dmasm
);
1185 /* Enable D H E bit in Rx DMA */
1186 rc32434_writel(rc32434_readl(&lp
->rx_dma_regs
->dmasm
) & ~(DMASM_d_m
| DMASM_h_m
| DMASM_e_m
), &lp
->rx_dma_regs
->dmasm
);
1188 /* Accept only packets destined for this Ethernet device address */
1189 rc32434_writel(ETHARC_ab_m
, &lp
->eth_regs
->etharc
);
1191 /* Set all Ether station address registers to their initial values */
1192 rc32434_writel(STATION_ADDRESS_LOW(dev
), &lp
->eth_regs
->ethsal0
);
1193 rc32434_writel(STATION_ADDRESS_HIGH(dev
), &lp
->eth_regs
->ethsah0
);
1195 rc32434_writel(STATION_ADDRESS_LOW(dev
), &lp
->eth_regs
->ethsal1
);
1196 rc32434_writel(STATION_ADDRESS_HIGH(dev
), &lp
->eth_regs
->ethsah1
);
1198 rc32434_writel(STATION_ADDRESS_LOW(dev
), &lp
->eth_regs
->ethsal2
);
1199 rc32434_writel(STATION_ADDRESS_HIGH(dev
), &lp
->eth_regs
->ethsah2
);
1201 rc32434_writel(STATION_ADDRESS_LOW(dev
), &lp
->eth_regs
->ethsal3
);
1202 rc32434_writel(STATION_ADDRESS_HIGH(dev
), &lp
->eth_regs
->ethsah3
);
1205 /* Frame Length Checking, Pad Enable, CRC Enable, Full Duplex set */
1206 rc32434_writel(ETHMAC2_pe_m
| ETHMAC2_cen_m
| ETHMAC2_fd_m
, &lp
->eth_regs
->ethmac2
);
1207 //ETHMAC2_flc_m ETHMAC2_fd_m lp->duplex_mode
1209 /* Back to back inter-packet-gap */
1210 rc32434_writel(0x15, &lp
->eth_regs
->ethipgt
);
1211 /* Non - Back to back inter-packet-gap */
1212 rc32434_writel(0x12, &lp
->eth_regs
->ethipgr
);
1214 /* Management Clock Prescaler Divisor */
1215 /* Clock independent setting */
1216 rc32434_writel(((idt_cpu_freq
)/MII_CLOCK
+1) & ~1,
1217 &lp
->eth_regs
->ethmcp
);
1219 /* don't transmit until fifo contains 48b */
1220 rc32434_writel(48, &lp
->eth_regs
->ethfifott
);
1222 rc32434_writel(ETHMAC1_re_m
, &lp
->eth_regs
->ethmac1
);
1224 #ifndef CONFIG_IDT_USE_NAPI
1225 tasklet_enable(lp
->rx_tasklet
);
1227 tasklet_enable(lp
->tx_tasklet
);
1229 netif_start_queue(dev
);
1239 static int __init
rc32434_setup(char *options
)
1241 /* no options yet */
1245 static int __init
rc32434_setup_ethaddr0(char *options
)
1247 memcpy(mac0
, options
, 17);
1252 __setup("rc32434eth=", rc32434_setup
);
1253 __setup("ethaddr0=", rc32434_setup_ethaddr0
);
1258 module_init(rc32434_init_module
);
1259 module_exit(rc32434_cleanup_module
);
This page took 0.113658 seconds and 5 git commands to generate.