3 * This program is the Moxa CPU ethernet device driver.
7 * 06-15-2005 Victor Yu. Create it. Make it for Faraday demo board.
8 * 11-04-2005 Victor Yu. Modify it to support Moxa CPU demo board.
11 #include <linux/config.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/fcntl.h>
16 #include <linux/interrupt.h>
17 #include <linux/ioport.h>
19 #include <linux/slab.h>
20 #include <linux/string.h>
21 #include <linux/errno.h>
22 #include <linux/init.h>
23 #include <linux/netdevice.h>
24 #include <linux/etherdevice.h>
25 #include <linux/spinlock.h>
26 #include <linux/skbuff.h>
27 #include <linux/device.h>
28 #include <linux/dma-mapping.h>
29 #include <linux/delay.h>
30 #include <linux/workqueue.h>
31 #include <asm/uaccess.h>
32 #include <asm/system.h>
33 #include <asm/bitops.h>
37 #include <linux/skbuff.h>
38 #include "moxacpu_mac.h"
40 //#define MCPU_MAC_DEBUG
41 //#define USE_SCHEDULE_WORK
44 #define dbg_printk(x...) printk(x)
45 #else // MCPU_MAC_DEBUG
46 #define dbg_printk(x...)
47 #endif // MCPU_MAC_DEBUG
49 #define TX_DESC_NUM 64
50 #define TX_DESC_NUM_MASK (TX_DESC_NUM-1)
51 //#define RX_DESC_NUM 64
52 #define RX_DESC_NUM_MASK (RX_DESC_NUM-1)
53 #define TX_BUF_SIZE 1600
54 #define RX_BUF_SIZE 1600
55 #if TX_BUF_SIZE >= TXBUF_SIZE_MAX
56 #error Moxa CPU ethernet device driver Tx buffer size too large !
58 #if RX_BUF_SIZE >= RXBUF_SIZE_MAX
59 #error Moxa CPU ethernet device driver Rx buffer size too large !
62 static mcpu_mac_priv_t mcpu_mac_priv;
63 #ifdef CONFIG_ARCH_MOXACPU
65 #if ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 ) || ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
66 static mcpu_mac_priv_t mcpu_mac_priv2;
69 #endif // CONFIG_ARCH_MOXACPU
73 static int crc32( char * s, int length )
78 /* crc polynomial for Ethernet */
79 const unsigned long poly=0xedb88320;
80 /* crc value - preinitialized to all 1's */
81 unsigned long crc_value=0xffffffff;
83 for ( perByte = 0; perByte < length; perByte ++ ) {
87 for ( perBit = 0; perBit < 8; perBit++ ) {
88 crc_value = (crc_value>>1)^
89 (((crc_value^c)&0x01)?poly:0);
96 static void mcpu_mac_setmulticast(unsigned int ioaddr, int count, struct dev_mc_list * addrs )
98 struct dev_mc_list *cur_addr;
101 for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next ) {
102 if ( !( *cur_addr->dmi_addr & 1 ) )
104 crc_val = crc32( cur_addr->dmi_addr, 6 );
105 crc_val = (crc_val>>26)&0x3f; // ยจรบ MSB 6 bit
107 outl(inl(ioaddr+MATH1_REG_OFFSET) | (1UL<<(crc_val-32)), ioaddr+MATH1_REG_OFFSET);
109 outl(inl(ioaddr+MATH0_REG_OFFSET) | (1UL<<crc_val), ioaddr+MATH0_REG_OFFSET);
113 static void mcpu_mac_set_multicast_list(struct net_device *dev)
115 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
120 #ifdef USE_SCHEDULE_WORK
121 spin_lock(&priv->rxlock);
123 spin_lock(&priv->txlock);
125 if ( dev->flags & IFF_PROMISC )
126 priv->maccr |= RCV_ALL;
128 priv->maccr &= ~RCV_ALL;
130 if ( dev->flags & IFF_ALLMULTI )
131 priv->maccr |= RX_MULTIPKT;
133 priv->maccr &= ~RX_MULTIPKT;
135 if ( dev->mc_count ) {
136 priv->maccr |= RX_MULTIPKT; //add by Johnson.Liu 2007/07/06
137 priv->maccr |= HT_MULTI_EN;
138 mcpu_mac_setmulticast(dev->base_addr, dev->mc_count, dev->mc_list);
140 priv->maccr &= ~RX_MULTIPKT; //add by Johnson.Liu 2007/07/06
141 priv->maccr &= ~HT_MULTI_EN;
144 outl(priv->maccr, dev->base_addr+MACCR_REG_OFFSET);
146 spin_unlock(&priv->txlock);
147 #ifdef USE_SCHEDULE_WORK
148 spin_unlock(&priv->rxlock);
150 restore_flags(flags);
152 #endif // HAVE_MULTICAST
154 #if 1 // add by Victor Yu. 07-04-2005
155 static void mywordcopy(void *dest, void *source, int len)
157 unsigned short *pd=(unsigned short *)dest;
158 unsigned short *ps=(unsigned short *)source;
166 *(unsigned char *)pd = *(unsigned char *)ps;
170 static void mcpu_mac_recv(void *ptr)
172 struct net_device *dev=(struct net_device *)ptr;
173 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
176 //struct sk_buff *skb;
179 #if 1 // add by Victor Yu. 07-04-2005
181 int rxnow=priv->RxDescNow;
183 #ifndef USE_SCHEDULE_WORK
184 int loops=RX_DESC_NUM;
185 #endif // USE_SCHEDULE_WORK
187 dbg_printk("mcpu_mac_recv test01\n");
191 dbg_printk("RxDescNow=%d, desc phy=0x%x, virt=0x%x, buf phy=0x%x, virt=0x%x\n", priv->RxDescNow, priv->phyRxDescBaseAddr+(priv->RxDescNow*sizeof(rx_desc_t)), (unsigned int)&priv->virtRxDescBaseAddr[priv->RxDescNow], priv->virtRxDescBaseAddr[priv->RxDescNow].rxdes2.phyRxBufBaseAddr, (unsigned int)priv->virtRxDescBaseAddr[priv->RxDescNow].rxdes2.virtRxBufBaseAddr);
192 dbg_printk("Now Rx desc des0=0x%x, des1=0x%x\n", priv->virtRxDescBaseAddr[priv->RxDescNow].rxdes0.ui, priv->virtRxDescBaseAddr[priv->RxDescNow].rxdes1.ui);
197 #ifdef USE_SCHEDULE_WORK
198 spin_lock(&priv->rxlock);
199 #endif // USE_SCHEDULE_WORK
201 rxdesc = &priv->virtRxDescBaseAddr[rxnow];
202 #if 0 // mask by Victor Yu. 07-04-2005
203 if ( rxdesc->rxdes0.ubit.RxDMAOwn ) {
204 #else // add by Victor Yu. 07-04-2005
205 ui = rxdesc->rxdes0.ui;
206 if ( ui & RXDMA_OWN ) {
208 #ifdef USE_SCHEDULE_WORK
209 spin_unlock(&priv->rxlock);
211 #ifdef MCPU_MAC_DEBUG
212 if ( loops == RX_DESC_NUM )
213 printk("Bad receive packet !\n");
214 #endif // MCPU_MAC_DEBUG
215 #endif // USE_SCHEDULE_WORK
218 #if 0 // mask by Victor Yu. 07-04-2005
219 if ( rxdesc->rxdes0.ubit.RxErr ||
220 rxdesc->rxdes0.ubit.CRCErr ||
221 rxdesc->rxdes0.ubit.Ftl ||
222 rxdesc->rxdes0.ubit.Runt ||
223 rxdesc->rxdes0.ubit.RxOddNb ) {
224 #else // add by Victor Yu. 07-04-2005
225 if ( ui & (RX_ERR|CRC_ERR|FTL|RUNT|RX_ODD_NB) ) {
227 dbg_printk("Ethernet receive packet error !\n");
228 priv->stats.rx_dropped++;
229 priv->stats.rx_errors++;
232 #if 0 // mask by Victor Yu. 07-04-2005
233 len = rxdesc->rxdes0.ubit.RecvFrameLen > RX_BUF_SIZE ? RX_BUF_SIZE : rxdesc->rxdes0.ubit.RecvFrameLen;
234 #else // add by Victor Yu. 07-04-2005
236 if ( len > RX_BUF_SIZE )
240 data=skb_put(priv->virtRxBufBaseAddr[rxnow], len);
241 priv->virtRxBufBaseAddr[rxnow]->dev=dev;
243 skb = dev_alloc_skb(len+2);
245 dbg_printk("Allocate memory fail !\n");
246 priv->stats.rx_dropped++;
251 data = skb_put(skb, len);
253 dbg_printk/*printk*/("receive data pointer = 0x%x:%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", (unsigned int)data, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
254 #if 0 // mask by Victor Yu. 07-04-2005
255 memcpy(data, rxdesc->rxdes2.virtRxBufBaseAddr, len);
256 #else // add by Victor Yu. 07-04-2005
257 //mywordcopy((void *)data, (void *)rxdesc->rxdes2.virtRxBufBaseAddr, len);
259 //skb->protocol = eth_type_trans(skb, dev);
260 priv->virtRxBufBaseAddr[rxnow]->protocol = eth_type_trans(priv->virtRxBufBaseAddr[rxnow], dev);
262 if(netif_rx(priv->virtRxBufBaseAddr[rxnow])==NET_RX_DROP)
263 printk("netif_rx recv error.\n");
264 priv->stats.rx_packets++;
265 priv->stats.rx_bytes += len;
266 if ( ui & MULTICAST_RXDES0 )
267 priv->stats.multicast++;
268 dbg_printk("Receive a good packet.\n");
270 priv->virtRxBufBaseAddr[rxnow]=dev_alloc_skb(RX_BUF_SIZE+2);
271 if (priv->virtRxBufBaseAddr[rxnow]){
272 //skb_reserve(priv->virtRxBufBaseAddr[rxnow], 2); /* align IP on 16B boundary */
273 rxdesc->rxdes2.phyRxBufBaseAddr = (unsigned int)__virt_to_phys(priv->virtRxBufBaseAddr[rxnow]->data);
274 rxdesc->rxdes2.virtRxBufBaseAddr = (unsigned char *)priv->virtRxBufBaseAddr[rxnow]->data;
275 }else goto recv_finish1;
278 #if 0 // mask by Victor Yu. 07-04-2005
279 rxdesc->rxdes0.ui = 0;
280 rxdesc->rxdes0.ubit.RxDMAOwn = 1;
281 rxdesc->rxdes1.ubit.RxBufSize = RX_BUF_SIZE;
282 #else // add by Victor Yu. 07-04-2005
283 rxdesc->rxdes0.ui = RXDMA_OWN;
288 rxnow &= RX_DESC_NUM_MASK;
289 priv->RxDescNow = rxnow;
291 #ifdef USE_SCHEDULE_WORK
293 #else // USE_SCHEDULE_WORK
296 #endif // USE_SCHEDULE_WORK
298 #ifdef USE_SCHEDULE_WORK
299 spin_unlock(&priv->rxlock);
300 #endif // USE_SCHEDULE_WORK
306 static void mcpu_mac_free_memory(struct net_device *dev)
309 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
311 if ( priv->virtTxDescBaseAddr )
312 dma_free_coherent(NULL, sizeof(tx_desc_t)*TX_DESC_NUM, priv->virtTxDescBaseAddr, priv->phyTxDescBaseAddr);
313 if ( priv->virtRxDescBaseAddr )
314 dma_free_coherent(NULL, sizeof(rx_desc_t)*RX_DESC_NUM, priv->virtRxDescBaseAddr, priv->phyRxDescBaseAddr);
315 if ( priv->virtTxBufBaseAddr )
316 dma_free_coherent(NULL, TX_BUF_SIZE*TX_DESC_NUM, priv->virtTxBufBaseAddr, priv->phyTxBufBaseAddr);
317 for(i=0;i<RX_DESC_NUM;i++){
318 if (priv->virtRxBufBaseAddr[i])
319 //dma_free_coherent(NULL, RX_BUF_SIZE, priv->virtRxBufBaseAddr[i], priv->phyRxBufBaseAddr[i]);
320 kfree_skb(priv->virtRxBufBaseAddr[i]);
324 static void mcpu_mac_setup_desc_ring(struct net_device *dev)
326 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
330 unsigned char *virtbuf;
333 virtbuf = priv->virtTxBufBaseAddr;
334 phybuf = priv->phyTxBufBaseAddr;
335 for ( i=0; i<TX_DESC_NUM; i++, virtbuf+=TX_BUF_SIZE, phybuf+=TX_BUF_SIZE ) {
336 txdesc = &priv->virtTxDescBaseAddr[i];
337 memset(txdesc, 0, sizeof(tx_desc_t));
338 txdesc->txdes2.phyTxBufBaseAddr = phybuf;
339 txdesc->txdes2.virtTxBufBaseAddr = virtbuf;
341 priv->virtTxDescBaseAddr[TX_DESC_NUM-1].txdes1.ubit.Edotr = 1;
343 //virtbuf = priv->virtRxBufBaseAddr;
344 //phybuf = priv->phyRxBufBaseAddr;
345 for ( i=0; i<RX_DESC_NUM; i++/*, virtbuf+=RX_BUF_SIZE, phybuf+=RX_BUF_SIZE*/ ) {
346 rxdesc = &priv->virtRxDescBaseAddr[i];
347 memset(rxdesc, 0, sizeof(rx_desc_t));
348 rxdesc->rxdes0.ubit.RxDMAOwn = 1;
349 rxdesc->rxdes1.ubit.RxBufSize = RX_BUF_SIZE;
350 rxdesc->rxdes2.phyRxBufBaseAddr = (unsigned int)__virt_to_phys(priv->virtRxBufBaseAddr[i]->data);
351 rxdesc->rxdes2.virtRxBufBaseAddr = (unsigned char *)priv->virtRxBufBaseAddr[i]->data;
353 priv->virtRxDescBaseAddr[RX_DESC_NUM-1].rxdes1.ubit.Edorr = 1;
354 //dbg_printk("First Rx desc des0=0x%x, des1=%x\n", priv->virtRxDescBaseAddr[0].rxdes0.ui, priv->virtRxDescBaseAddr[0].rxdes1.ui);
356 priv->TxDescNow = priv->RxDescNow = 0;
358 // reset the MAC controler Tx/Rx desciptor base address
359 outl(priv->phyTxDescBaseAddr, dev->base_addr+TXR_BADR_REG_OFFSET);
360 outl(priv->phyRxDescBaseAddr, dev->base_addr+RXR_BADR_REG_OFFSET);
362 dbg_printk("Tx/Rx desc phy=0x%x,0x%x, virt=0x%x,0x%x\n", priv->phyTxDescBaseAddr, priv->phyRxDescBaseAddr, (unsigned int)priv->virtTxDescBaseAddr, (unsigned int)priv->virtRxDescBaseAddr);
363 dbg_printk("set Tx desc base address=0x%x, Rx=0x%x\n", inl(dev->base_addr+TXR_BADR_REG_OFFSET), inl(dev->base_addr+RXR_BADR_REG_OFFSET));
367 static void mcpu_mac_reset(struct net_device *dev)
369 unsigned int reg=dev->base_addr+MACCR_REG_OFFSET;
371 outl(SW_RST, reg); // software reset
372 while ( inl(reg) & SW_RST ) mdelay(10);
373 // maybe we need to disable the all interrupt
374 outl(0, dev->base_addr+IMR_REG_OFFSET);
375 // ((mcpu_mac_priv_t *)dev->priv)->maccr = RX_BROADPKT | FULLDUP | CRC_APD;
376 ((mcpu_mac_priv_t *)dev->priv)->maccr = RX_BROADPKT | ENRX_IN_HALFTX | CRC_APD;
380 static void mcpu_mac_set_mac_address(unsigned int base, unsigned char *macaddr)
384 val = (((u32)macaddr[0] << 8) &0xff00) | ((u32)macaddr[1] & 0xff);
386 val = (((u32)macaddr[2]<<24) & 0xff000000) |
387 (((u32)macaddr[3]<<16) & 0x00ff0000) |
388 (((u32)macaddr[4]<<8) & 0x0000ff00) |
389 (((u32)macaddr[5]) & 0x000000ff);
393 #ifdef MCPU_MAC_DEBUG // add by Victor Yu. 03-14-2006
394 static void mcpu_mac_get_mac_address(unsigned int base, unsigned char *macaddr)
399 macaddr[0] = (val >> 8) & 0xff;
400 macaddr[1] = val & 0xff;
402 macaddr[2] = (val >> 24) & 0xff;
403 macaddr[3] = (val >> 16) & 0xff;
404 macaddr[4] = (val >> 8) & 0xff;
405 macaddr[5] = val & 0xff;
409 static void mcpu_mac_enable(struct net_device *dev)
411 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
412 unsigned int base=dev->base_addr;
414 outl(0x00001010, base+ITC_REG_OFFSET);
415 outl(0x00000001, base+APTC_REG_OFFSET);
416 outl(0x00000390, base+DBLAC_REG_OFFSET);
417 #ifdef MCPU_MAC_DEBUG
418 outl(RPKT_FINISH_M|NORXBUF_M|AHB_ERR_M, base+IMR_REG_OFFSET);
420 outl(RPKT_FINISH_M, base+IMR_REG_OFFSET);
422 priv->maccr |= (RCV_EN | XMT_EN | RDMA_EN | XDMA_EN);
423 outl(priv->maccr, base+MACCR_REG_OFFSET);
426 static void mcpu_mac_tx_timeout(struct net_device *dev)
428 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
431 dbg_printk("mcpu_mac_tx_timeout test01\n");
434 #ifdef USE_SCHEDULE_WORK
435 spin_lock(&priv->rxlock);
437 spin_lock(&priv->txlock);
439 mcpu_mac_set_mac_address(dev->base_addr+MAC_MADR_REG_OFFSET, dev->dev_addr);
440 mcpu_mac_setup_desc_ring(dev);
441 mcpu_mac_enable(dev);
442 spin_unlock(&priv->txlock);
443 #ifdef USE_SCHEDULE_WORK
444 spin_unlock(&priv->rxlock);
446 restore_flags(flags);
447 netif_wake_queue(dev);
448 dev->trans_start = jiffies;
451 static int mcpu_mac_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
453 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
456 int txnow=priv->TxDescNow;
458 dbg_printk("mcpu_mac_hard_start_xmit test01\n");
459 spin_lock(&priv->txlock);
461 // first check the Tx buffer is enough or not
462 txdesc = &priv->virtTxDescBaseAddr[txnow];
463 if ( txdesc->txdes0.ubit.TxDMAOwn ) {
464 dbg_printk("No Tx space to transmit the packet !\n");
465 priv->stats.tx_dropped++;
470 #if 0 // mask by Victor Yu. 07-04-2005
471 len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
472 len = len > TX_BUF_SIZE ? TX_BUF_SIZE : len;
473 #else // add by Victor Yu. 07-04-2005
474 len = skb->len > TX_BUF_SIZE ? TX_BUF_SIZE : skb->len;
476 #if 0 // mask by Victor Yu. 07-04-2005
477 memcpy(txdesc->txdes2.virtTxBufBaseAddr, skb->data, len);
478 #else // add by Victor Yu. 07-04-2005
479 mywordcopy((void *)txdesc->txdes2.virtTxBufBaseAddr, (void *)skb->data, len);
481 dbg_printk("transmit data pointer = 0x%x\n", (unsigned long)skb->data);
482 #if 1 // add by Victor Yu. 07-04-2005
483 if ( skb->len < ETH_ZLEN ) {
484 memset(&txdesc->txdes2.virtTxBufBaseAddr[skb->len], 0, ETH_ZLEN-skb->len);
488 txdesc->txdes1.ubit.Lts = 1;
489 txdesc->txdes1.ubit.Fts = 1;
490 txdesc->txdes1.ubit.Tx2fic = 0;
491 txdesc->txdes1.ubit.Txic = 0;
492 txdesc->txdes1.ubit.TxBufSize = len;
493 #if 0 // mask by Victor Yu. 07-04-2005
494 txdesc->txdes0.ui = 0;
495 txdesc->txdes0.ubit.TxDMAOwn = 1;
496 #else // add by Victor Yu. 07-04-2005
497 txdesc->txdes0.ui = TXDMA_OWN;
500 outl(0xffffffff, dev->base_addr+TXPD_REG_OFFSET); // start to send packet
502 dbg_printk("TxDescNow=%d, address=0x%x, des0=0x%x, des1=0x%x\n", priv->TxDescNow, (unsigned int)&priv->virtTxDescBaseAddr[priv->TxDescNow], txdesc->txdes0.ui, txdesc->txdes1.ui);
503 dbg_printk("Buffer phy address=0x%x, virt=0x%x\n", txdesc->txdes2.phyTxBufBaseAddr, (unsigned int)txdesc->txdes2.virtTxBufBaseAddr);
504 dbg_printk("TxDescNow-1=%d, address=0x%x, des0=0x%x\n", (priv->TxDescNow-1)&TX_DESC_NUM_MASK, (unsigned int)&priv->virtTxDescBaseAddr[(priv->TxDescNow-1)&TX_DESC_NUM_MASK], priv->virtTxDescBaseAddr[(priv->TxDescNow-1)&TX_DESC_NUM_MASK].txdes0.ui);
507 txnow &= TX_DESC_NUM_MASK;
508 priv->TxDescNow = txnow;
509 dev->trans_start = jiffies;
510 priv->stats.tx_packets++;
511 priv->stats.tx_bytes += len;
514 spin_unlock(&priv->txlock);
515 dev_kfree_skb_any(skb);
520 static int mcpu_mac_open(struct net_device *dev)
522 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
525 dbg_printk("mcpu_mac_open test01\n");
529 #ifdef USE_SCHEDULE_WORK
530 spin_lock(&priv->rxlock);
532 spin_lock(&priv->txlock);
534 mcpu_mac_set_mac_address(dev->base_addr+MAC_MADR_REG_OFFSET, dev->dev_addr);
535 mcpu_mac_setup_desc_ring(dev);
536 mcpu_mac_enable(dev);
537 spin_unlock(&priv->txlock);
538 #ifdef USE_SCHEDULE_WORK
539 spin_unlock(&priv->rxlock);
541 restore_flags(flags);
542 netif_start_queue(dev);
543 dbg_printk("IMR=0x%x, MACCR=0x%x\n", inl(dev->base_addr+IMR_REG_OFFSET), inl(dev->base_addr+MACCR_REG_OFFSET));
544 #ifdef MCPU_MAC_DEBUG
546 unsigned char macaddr[6];
548 mcpu_mac_get_mac_address(dev->base_addr+MAC_MADR_REG_OFFSET, macaddr);
549 printk("Get MAC address = ");
550 for ( i=0; i<6; i++ )
551 printk("%02X ", macaddr[i]);
559 static int mcpu_mac_stop(struct net_device *dev)
561 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
564 dbg_printk("mcpu_mac_stop test01\n");
565 netif_stop_queue(dev);
568 #ifdef USE_SCHEDULE_WORK
569 spin_lock(&priv->rxlock);
571 spin_lock(&priv->txlock);
572 outl(0, dev->base_addr+IMR_REG_OFFSET); // disable all interrupt
573 outl(0, dev->base_addr+MACCR_REG_OFFSET); // disable all function
574 spin_unlock(&priv->txlock);
575 #ifdef USE_SCHEDULE_WORK
576 spin_unlock(&priv->rxlock);
578 restore_flags(flags);
583 static struct net_device_stats *mcpu_mac_get_stats(struct net_device *dev)
585 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
587 dbg_printk("mcpu_mac_get_stats test01\n");
590 unsigned int base=dev->base_addr;
591 int desc=priv->RxDescNow;
592 dbg_printk("RxDescNow=%d, desc phy=0x%x, virt=0x%x, buf phy=0x%x, virt=0x%x\n", desc, priv->phyRxDescBaseAddr+(desc*sizeof(rx_desc_t)), (unsigned int)&priv->virtRxDescBaseAddr[desc], priv->virtRxDescBaseAddr[desc].rxdes2.phyRxBufBaseAddr, (unsigned int)priv->virtRxDescBaseAddr[desc].rxdes2.virtRxBufBaseAddr);
593 dbg_printk("Now Rx desc des0=0x%x, des1=0x%x\n", priv->virtRxDescBaseAddr[desc].rxdes0.ui, priv->virtRxDescBaseAddr[desc].rxdes1.ui);
595 desc &= RX_DESC_NUM_MASK;
596 dbg_printk("Next RxDescNow=%d, desc phy=0x%x, virt=0x%x, buf phy=0x%x, virt=0x%x\n", desc, priv->phyRxDescBaseAddr+(desc*sizeof(rx_desc_t)), (unsigned int)&priv->virtRxDescBaseAddr[desc], priv->virtRxDescBaseAddr[desc].rxdes2.phyRxBufBaseAddr, (unsigned int)priv->virtRxDescBaseAddr[desc].rxdes2.virtRxBufBaseAddr);
597 dbg_printk("Next Now Rx desc des0=0x%x, des1=0x%x\n", priv->virtRxDescBaseAddr[desc].rxdes0.ui, priv->virtRxDescBaseAddr[desc].rxdes1.ui);
598 printk("TX_MCOL_TX_SCOL register = 0x%x\n", inl(base+TX_MCOL_TX_SCOL_REG_OFFSET));
599 printk("RPF_AEP register = 0x%x\n", inl(base+RPF_AEP_REG_OFFSET));
600 printk("XM_PG register = 0x%x\n", inl(base+XM_PG_REG_OFFSET));
601 printk("RUNT_CNT_TLCC register = 0x%x\n", inl(base+RUNT_CNT_TLCC_REG_OFFSET));
602 printk("CRCER_CNT_FTL_CNT register = 0x%x\n", inl(base+CRCER_CNT_FTL_CNT_REG_OFFSET));
603 printk("RLC_RCC register = 0x%x\n", inl(base+RLC_RCC_REG_OFFSET));
604 printk("BROC register = 0x%x\n", inl(base+BROC_REG_OFFSET));
605 printk("MUCLA register = 0x%x\n", inl(base+MULCA_REG_OFFSET));
606 printk("RP register = 0x%x\n", inl(base+RP_REG_OFFSET));
607 printk("XP register = 0x%x\n", inl(base+XP_REG_OFFSET));
615 static irqreturn_t mcpu_mac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
617 struct net_device *dev=(struct net_device *)dev_id;
619 #ifdef USE_SCHEDULE_WORK
620 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
624 //dbg_printk("mcpu_mac_interrupt test01\n");
625 ists = inl(dev->base_addr+ISR_REG_OFFSET);
626 if ( ists & RPKT_FINISH ) {
627 #ifdef USE_SCHEDULE_WORK
628 schedule_work(&priv->rqueue);
630 mcpu_mac_recv((void *)dev);
633 #ifdef MCPU_MAC_DEBUG
634 if ( ists & NORXBUF ) {
635 printk("Receiver no Rx buffer interrupt\n");
636 outl(inl(dev->base_addr+IMR_REG_OFFSET)&~NORXBUF_M, dev->base_addr+IMR_REG_OFFSET);
637 //return IRQ_HANDLED;
639 if ( ists & AHB_ERR ) {
640 printk("Receiver AHB error interrupt.\n");
641 //return IRQ_HANDLED;
650 static int mcpu_mac_init(struct net_device *dev)
653 mcpu_mac_priv_t *priv=(mcpu_mac_priv_t *)dev->priv;
655 dbg_printk("mcpu_mac_init test01\n");
657 // first initialize the private variable to zero
658 memset((void *)priv, 0, sizeof(mcpu_mac_priv_t));
659 spin_lock_init(&priv->txlock);
660 spin_lock_init(&priv->rxlock);
662 #ifdef USE_SCHEDULE_WORK
664 //#if 1 // add by Victor Yu. 07-04-2005
665 INIT_WORK(&priv->rqueue, &mcpu_mac_recv, (void *)dev);
668 // allocate the descriptor and buffer memory
669 priv->virtTxDescBaseAddr = (tx_desc_t *)dma_alloc_coherent(NULL, sizeof(tx_desc_t)*TX_DESC_NUM, (dma_addr_t *)&priv->phyTxDescBaseAddr, GFP_DMA|GFP_KERNEL);
670 if ( priv->virtTxDescBaseAddr == NULL || (priv->phyTxDescBaseAddr & 0x0f) ) {
671 dbg_printk("Allocate the Tx descriptor memory fail !\n");
674 priv->virtRxDescBaseAddr = (rx_desc_t *)dma_alloc_coherent(NULL, sizeof(rx_desc_t)*RX_DESC_NUM, (dma_addr_t *)&priv->phyRxDescBaseAddr, GFP_DMA|GFP_KERNEL);
675 if ( priv->virtRxDescBaseAddr == NULL || (priv->phyRxDescBaseAddr & 0x0f) ) {
676 dbg_printk("Allocate the Rx descriptor memory fail !\n");
679 priv->virtTxBufBaseAddr = (unsigned char *)dma_alloc_coherent(NULL, TX_BUF_SIZE*TX_DESC_NUM, (dma_addr_t *)&priv->phyTxBufBaseAddr, GFP_DMA|GFP_KERNEL);
680 if ( priv->virtTxBufBaseAddr == NULL || (priv->phyTxBufBaseAddr & 0x03) ) {
681 dbg_printk("Allocate the Tx buffer memory fail !\n");
684 for(i=0;i<RX_DESC_NUM;i++){
685 //priv->virtRxBufBaseAddr[i]= (unsigned char *)dma_alloc_coherent(NULL, RX_BUF_SIZE, (dma_addr_t *)&priv->phyRxBufBaseAddr[i], GFP_DMA|GFP_KERNEL);
686 priv->virtRxBufBaseAddr[i]=dev_alloc_skb(RX_BUF_SIZE+2);
687 if ( priv->virtRxBufBaseAddr[i] == NULL /*|| (priv->phyRxBufBaseAddr[i] & 0x03)*/ ) {
688 dbg_printk("Allocate the Rx buffer memory fail !\n");
691 //skb_reserve(priv->virtRxBufBaseAddr[i], 2); /* align IP on 16B boundary */
694 // setup the thernet basic
699 mcpu_mac_setup_desc_ring(dev);
701 // we need to get the MAC address from the hardware and set to the device
702 #ifdef CONFIG_ARCH_CPE
703 dev->dev_addr[0] = 0x00;
704 dev->dev_addr[1] = 0x90;
705 dev->dev_addr[2] = 0xE8;
706 dev->dev_addr[3] = 0x72;
707 dev->dev_addr[4] = 0x20;
708 dev->dev_addr[5] = 0x01;
709 #endif // CONFIG_ARCH_CPE
710 #ifdef CONFIG_ARCH_MOXACPU
712 #include <linux/mtd/mtd.h>
713 struct mtd_info *mtd;
715 mtd = get_mtd_device(NULL, 0);
716 if ( priv == (void *)&mcpu_mac_priv ) { // LAN 1
718 #if 0 // mask by Victor Yu. 03-21-2006
719 dev->dev_addr[0] = 0x00;
720 dev->dev_addr[1] = 0x90;
721 dev->dev_addr[2] = 0xe8;
722 dev->dev_addr[3] = 0x10;
723 dev->dev_addr[4] = 0x02;
724 dev->dev_addr[5] = 0x40;
725 #else // add by Victor Yu. 03-21-2006
726 #if ( defined CONFIG_ARCH_W341 ) || ( defined CONFIG_ARCH_W345 ) || ( defined CONFIG_ARCH_UC_7112_LX_PLUS ) || ( defined CONFIG_ARCH_W311 ) || ( defined CONFIG_ARCH_W321 ) || ( defined CONFIG_ARCH_W315 ) || ( defined CONFIG_ARCH_W325 )
727 memcpy(dev->dev_addr, (char *)(CPE_FLASH_VA_BASE+0x50), 6);
728 #elif ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )
729 memcpy(dev->dev_addr, (char *)(CPE_FLASH_VA_BASE+0x56), 6);
735 #if ( defined CONFIG_ARCH_W341 ) || ( defined CONFIG_ARCH_W345 ) || ( defined CONFIG_ARCH_UC_7112_LX_PLUS ) || ( defined CONFIG_ARCH_W311 ) || ( defined CONFIG_ARCH_W321 ) || ( defined CONFIG_ARCH_W315 ) || ( defined CONFIG_ARCH_W325 )
737 mtd->read(mtd, 0x50, 6, &len, dev->dev_addr);
738 #elif ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )
739 mtd->read(mtd, 0x56, 6, &len, dev->dev_addr);
746 #if 0 // mask by Victor Yu. 03-21-2006
747 dev->dev_addr[0] = 0x00;
748 dev->dev_addr[1] = 0x90;
749 dev->dev_addr[2] = 0xe8;
750 dev->dev_addr[3] = 0x10;
751 dev->dev_addr[4] = 0x02;
752 dev->dev_addr[5] = 0x41;
753 #else // add by Victor Yu. 03-21-2006
755 #if ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
756 memcpy(dev->dev_addr, (char *)(CPE_FLASH_VA_BASE+0x56), 6);
757 #elif ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )
758 memcpy(dev->dev_addr, (char *)(CPE_FLASH_VA_BASE+0x50), 6);
764 #if ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
765 mtd->read(mtd, 0x56, 6, &len, dev->dev_addr);
766 #elif ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )
767 mtd->read(mtd, 0x50, 6, &len, dev->dev_addr);
772 #endif // CONFIG_ARCH_MOXACPU
774 // setup the low lever interrupt for Moxa CPU
775 #include <asm/arch/cpe_int.h>
776 cpe_int_set_irq(dev->irq, LEVEL, H_ACTIVE);
777 if ( request_irq(dev->irq, &mcpu_mac_interrupt, SA_INTERRUPT, dev->name, dev) ) {
778 dbg_printk("Request interrupt service fail !\n");
785 mcpu_mac_free_memory(dev);
789 static struct net_device mcpu_mac_dev = {
790 #ifdef CONFIG_ARCH_MOXACPU
792 #if ( defined CONFIG_ARCH_W341 ) || ( defined CONFIG_ARCH_W345 ) || ( defined CONFIG_ARCH_UC_7112_LX_PLUS ) || ( defined CONFIG_ARCH_W311 ) || ( defined CONFIG_ARCH_W321 ) || ( defined CONFIG_ARCH_W315 ) || ( defined CONFIG_ARCH_W325 )
794 #elif ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )
799 .base_addr = IO_ADDRESS(CPE_FTMAC_BASE),
801 .init = &mcpu_mac_init,
802 .get_stats = &mcpu_mac_get_stats,
803 .open = &mcpu_mac_open,
804 .stop = &mcpu_mac_stop,
805 .hard_start_xmit= &mcpu_mac_hard_start_xmit,
806 .priv = (void *)&mcpu_mac_priv,
807 .tx_timeout = &mcpu_mac_tx_timeout,
808 #ifdef HAVE_MULTICAST
809 .set_multicast_list = &mcpu_mac_set_multicast_list,
813 #ifdef CONFIG_ARCH_MOXACPU
816 #if ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 ) || ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
817 static struct net_device mcpu_mac_dev2 = {
818 #if ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )
820 #elif ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
823 .base_addr = IO_ADDRESS(CPE_FTMAC2_BASE),
825 .init = &mcpu_mac_init,
826 .get_stats = &mcpu_mac_get_stats,
827 .open = &mcpu_mac_open,
828 .stop = &mcpu_mac_stop,
829 .hard_start_xmit= &mcpu_mac_hard_start_xmit,
830 .priv = (void *)&mcpu_mac_priv2,
831 .tx_timeout = &mcpu_mac_tx_timeout,
832 #ifdef HAVE_MULTICAST
833 .set_multicast_list = &mcpu_mac_set_multicast_list,
838 #endif // CONFIG_ARCH_MOXACPU
840 static int __init mcpu_mac_init_module(void)
843 printk("Moxa CPU Ethernet Device Driver Version 1.0 load ");
844 ret = register_netdev(&mcpu_mac_dev);
850 #ifdef CONFIG_ARCH_MOXACPU
853 #if ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 ) || ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
855 ret = register_netdev(&mcpu_mac_dev2);
857 mcpu_mac_free_memory(&mcpu_mac_dev);
858 free_irq(mcpu_mac_dev.irq, &mcpu_mac_dev);
859 unregister_netdev(&mcpu_mac_dev);
866 #endif // CONFIG_ARCH_MOXACPU
873 static void __exit mcpu_mac_cleanup_module(void)
875 printk("Moxa CPU Ethernet Device Driver unload.\n");
876 mcpu_mac_free_memory(&mcpu_mac_dev);
877 free_irq(mcpu_mac_dev.irq, &mcpu_mac_dev);
878 unregister_netdev(&mcpu_mac_dev);
880 #ifdef CONFIG_ARCH_MOXACPU
882 #if ( defined CONFIG_ARCH_IA240 ) || ( defined CONFIG_ARCH_IA241 )|| ( defined CONFIG_ARCH_UC_7112_LX_PLUS )
883 mcpu_mac_free_memory(&mcpu_mac_dev2);
884 free_irq(mcpu_mac_dev2.irq, &mcpu_mac_dev2);
885 unregister_netdev(&mcpu_mac_dev2);
888 #endif // CONFIG_ARCH_MOXACPU
891 module_init(mcpu_mac_init_module);
892 module_exit(mcpu_mac_cleanup_module);