MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / ftmac100.c
blob8e6238b086aece25b9d9b61d21b29926e4bcb01f
1 /**************************************************
2 2002/11/29: lmc83
3 2004/8/26 19:29: ivan wang modified
4 ***************************************************/
5 #include <linux/module.h>
6 #include <linux/version.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/fcntl.h>
11 #include <linux/interrupt.h>
12 #include <linux/ptrace.h>
13 #include <linux/ioport.h>
14 #include <linux/in.h>
15 #include <linux/slab.h>
16 #include <linux/string.h>
17 #include <linux/init.h>
18 #include <linux/proc_fs.h>
19 #include <asm/bitops.h>
20 #include <asm/io.h>
21 #include <asm/hardware.h>
22 #include <linux/pci.h>
23 #include <linux/errno.h>
24 #include <linux/delay.h>
25 #include <linux/netdevice.h>
26 #include <linux/etherdevice.h>
27 #include <linux/skbuff.h>
28 #include <asm/arch/cpe/cpe.h>
29 #include <asm/arch/cpe_int.h>
30 #include "ftmac100.h"
32 #define FTMAC100_DEBUG 1
33 #define MAX_MAC100_NUM 2
34 #define CARDNAME "FTMAC100"
35 static const char version[]="Faraday FTMAC100 Driver,(Linux Kernel 2.4) 10/18/02 - by Faraday\n";
36 volatile int trans_busy=0;
37 //static struct proc_dir_entry *proc_ftmac100;
40 void put_mac(int base, char *mac_addr)
42 int val;
44 val = ((u32)mac_addr[0])<<8 | (u32)mac_addr[1];
45 outl(val, base);
46 val = ((((u32)mac_addr[2])<<24)&0xff000000) |
47 ((((u32)mac_addr[3])<<16)&0xff0000) |
48 ((((u32)mac_addr[4])<<8)&0xff00) |
49 ((((u32)mac_addr[5])<<0)&0xff);
50 outl(val, base+4);
53 void get_mac(int base, char *mac_addr)
55 int val;
57 //printk("+get_mac\n");
59 val = inl(base);
60 mac_addr[0] = (val>>8)&0xff;
61 mac_addr[1] = val&0xff;
62 val = inl(base+4); //john add +4
63 mac_addr[2] = (val>>24)&0xff;
64 mac_addr[3] = (val>>16)&0xff;
65 mac_addr[4] = (val>>8)&0xff;
66 mac_addr[5] = val&0xff;
69 // --------------------------------------------------------------------
70 // Print the Ethernet address
71 // --------------------------------------------------------------------
72 void print_mac(char *mac_addr)
74 int i;
76 printk("ADDR: ");
77 for (i = 0; i < 5; i++)
79 printk("%2.2x:", mac_addr[i] );
81 printk("%2.2x \n", mac_addr[5] );
86 // --------------------------------------------------------------------
87 // Finds the CRC32 of a set of bytes.
88 // Again, from Peter Cammaert's code.
89 // --------------------------------------------------------------------
90 static int crc32( char * s, int length )
92 /* indices */
93 int perByte;
94 int perBit;
95 /* crc polynomial for Ethernet */
96 const unsigned long poly = 0xedb88320;
97 /* crc value - preinitialized to all 1's */
98 unsigned long crc_value = 0xffffffff;
100 //printk("+crc32\n");
102 for ( perByte = 0; perByte < length; perByte ++ ) {
103 unsigned char c;
105 c = *(s++);
106 for ( perBit = 0; perBit < 8; perBit++ ) {
107 crc_value = (crc_value>>1)^
108 (((crc_value^c)&0x01)?poly:0);
109 c >>= 1;
112 return crc_value;
116 static void ftmac100_reset( struct net_device* dev )
118 unsigned int ioaddr = dev->base_addr;
120 //printk("+ftmac100_reset\n");
122 outl( SW_RST_bit, ioaddr + MACCR_REG );
124 /* this should pause enough for the chip to be happy */
125 for (; (inl( ioaddr + MACCR_REG ) & SW_RST_bit) != 0; )
126 mdelay(10);
128 outl( 0, ioaddr + IMR_REG ); /* Disable all interrupts */
133 . Function: ftmac100_enable
134 . Purpose: let the chip talk to the outside work
135 . Method:
136 . 1. Enable the transmitter
137 . 2. Enable the receiver
138 . 3. Enable interrupts
140 static void ftmac100_enable( struct net_device *dev )
142 unsigned int ioaddr = dev->base_addr;
143 int i;
144 struct ftmac100_local *lp = (struct ftmac100_local *)dev->priv;
145 char mac_addr[6];
147 //printk("+ftmac100_enable\n");
148 //printk("%s:ftmac100_enable\n", dev->name);
150 for (i=0; i<RXDES_NUM; ++i)
152 lp->rx_descs[i].RXDMA_OWN = OWNBY_FTMAC100; // owned by FTMAC100
154 lp->rx_idx = 0;
156 for (i=0; i<TXDES_NUM; ++i)
158 lp->tx_descs[i].TXDMA_OWN = OWNBY_SOFTWARE; // owned by software
160 lp->tx_idx = 0;
163 /* set the MAC address */
164 put_mac(ioaddr + MAC_MADR_REG, dev->dev_addr);
166 //john add
167 get_mac(ioaddr + MAC_MADR_REG, mac_addr);
168 print_mac(mac_addr);
170 outl( lp->rx_descs_dma, ioaddr + RXR_BADR_REG);
171 outl( lp->tx_descs_dma, ioaddr + TXR_BADR_REG);
172 outl( 0x00001010, ioaddr + ITC_REG);
173 outl( (0UL<<TXPOLL_CNT)|(0x1<<RXPOLL_CNT), ioaddr + APTC_REG);
174 outl( 0x1df, ioaddr + DBLAC_REG );
176 /* now, enable interrupts */
177 outl( AHB_ERR_bit|NORXBUF_bit|RPKT_FINISH_bit,ioaddr + IMR_REG);
179 /// enable trans/recv,...
180 outl(lp->maccr_val, ioaddr + MACCR_REG );
184 . Function: ftmac100_shutdown
185 . Purpose: closes down the SMC91xxx chip.
186 . Method:
187 . 1. zero the interrupt mask
188 . 2. clear the enable receive flag
189 . 3. clear the enable xmit flags
191 . TODO:
192 . (1) maybe utilize power down mode.
193 . Why not yet? Because while the chip will go into power down mode,
194 . the manual says that it will wake up in response to any I/O requests
195 . in the register space. Empirical results do not show this working.
197 static void ftmac100_shutdown( unsigned int ioaddr )
199 //printk("+ftmac100_shutdown\n");
201 outl( 0, ioaddr + IMR_REG );
202 outl( 0, ioaddr + MACCR_REG );
206 . Function: ftmac100_wait_to_send_packet( struct sk_buff * skb, struct device * )
207 . Purpose:
208 . Attempt to allocate memory for a packet, if chip-memory is not
209 . available, then tell the card to generate an interrupt when it
210 . is available.
212 . Algorithm:
214 . o if the saved_skb is not currently null, then drop this packet
215 . on the floor. This should never happen, because of TBUSY.
216 . o if the saved_skb is null, then replace it with the current packet,
217 . o See if I can sending it now.
218 . o (NO): Enable interrupts and let the interrupt handler deal with it.
219 . o (YES):Send it now.
221 static int ftmac100_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
223 struct ftmac100_local *lp=(struct ftmac100_local *)dev->priv;
224 unsigned int ioaddr=dev->base_addr;
225 volatile TX_DESC *cur_desc;
226 int length;
227 unsigned long flags;
229 //printk("+ftmac100_wait_to_send_packet\n");
231 spin_lock_irqsave(&lp->lock, flags);
232 if (skb==NULL)
234 printk("%s(%d): NULL skb???\n", __FILE__,__LINE__);
235 spin_unlock_irqrestore(&lp->lock, flags);
236 return 0;
239 cur_desc = &lp->tx_descs[lp->tx_idx];
241 for (; cur_desc->TXDMA_OWN != OWNBY_SOFTWARE;)
242 ;//printk("no empty TX descriptor:0x%x:0x%x\n",(unsigned int)cur_desc,(unsigned int)cur_desc[0]);
243 length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
244 length = min(length, TX_BUF_SIZE);
247 #if FTMAC100_DEBUG > 2
248 printk("Transmitting Packet at 0x%x\n",(unsigned int)cur_desc->VIR_TXBUF_BADR);
249 print_packet( skb->data, length );
250 #endif
251 memcpy((char *)cur_desc->VIR_TXBUF_BADR, skb->data, length); /// waiting to do: ±N data ¤Á¦¨³\¦h segment
253 cur_desc->TXBUF_Size = length;
254 cur_desc->LTS = 1;
255 cur_desc->FTS = 1;
256 cur_desc->TX2FIC = 0;
257 cur_desc->TXIC = 0;
258 cur_desc->TXDMA_OWN = OWNBY_FTMAC100;
259 outl( 0xffffffff, ioaddr + TXPD_REG);
260 lp->tx_idx = (lp->tx_idx + 1) % TXDES_NUM;
261 lp->stats.tx_packets++;
262 dev_kfree_skb_any (skb);
263 dev->trans_start = jiffies;
264 spin_unlock_irqrestore(&lp->lock, flags);
265 return 0;
268 /*-------------------------------------------------------------------------
270 | ftmac100_init( struct device * dev )
271 | Input parameters:
272 | dev->base_addr == 0, try to find all possible locations
273 | dev->base_addr == 1, return failure code
274 | dev->base_addr == 2, always allocate space, and return success
275 | dev->base_addr == <anything else> this is the address to check
277 | Output:
278 | 0 --> there is a device
279 | anything else, error
281 ---------------------------------------------------------------------------
283 int __init ftmac100_init(struct net_device *dev,u32 irq, u32 base_addr)
285 //static int inited=0;
287 //printk("+ftmac100_init\n");
289 SET_MODULE_OWNER (dev);
291 /* john
292 if (inited != 0)
294 return -ENODEV; // no more device
296 ++inited;
299 dev->irq = irq;
300 dev->base_addr = base_addr;
301 return ftmac100_probe(dev, dev->base_addr);
304 int FTCmac_probe(struct net_device *dev)
306 static int initialized;
307 u32 irq, base_addr;
309 //printk("+FTCmac_probe : dev = 0x%x\n",dev);
311 if (initialized >= MAX_MAC100_NUM) /* Already initialized? */
312 return 1;
313 initialized++;
315 if (initialized == 1) {
316 irq = IRQ_MAC;
317 base_addr = IO_ADDRESS(CPE_FTMAC_BASE);
319 else {
320 irq = IRQ_A321_MAC2;
321 base_addr = IO_ADDRESS(CPE_FTMAC2_BASE);
324 return ftmac100_init(dev,irq,base_addr);
327 /*-------------------------------------------------------------------------
329 | ftmac100_destructor( struct device * dev )
330 | Input parameters:
331 | dev, pointer to the device structure
333 | Output:
334 | None.
336 ---------------------------------------------------------------------------
338 void ftmac100_destructor(struct net_device *dev)
340 //printk("+ftmac100_destructor\n");
342 return;
346 void ftmac100_ringbuf_alloc(struct ftmac100_local *lp)
348 int i;
350 //printk("+ftmac100_ringbuf_alloc\n");
352 lp->rx_descs = consistent_alloc( GFP_DMA|GFP_KERNEL, sizeof(RX_DESC)*RXDES_NUM, &(lp->rx_descs_dma) );
354 if (lp->rx_descs == NULL || (( (u32)lp->rx_descs & 0xf)!=0))
356 printk("Receive Ring Buffer allocation error\n");
357 BUG();
359 memset((unsigned int *)lp->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM);
361 lp->rx_buf=consistent_alloc(GFP_DMA|GFP_KERNEL,RX_BUF_SIZE*RXDES_NUM,&(lp->rx_buf_dma));
362 if (lp->rx_buf == NULL || (( (u32)lp->rx_buf % 4)!=0))
364 printk("Receive Ring Buffer allocation error\n");
365 BUG();
368 for (i=0; i<RXDES_NUM; ++i)
370 lp->rx_descs[i].RXBUF_Size = RX_BUF_SIZE;
371 lp->rx_descs[i].EDOTR = 0; // not last descriptor
372 lp->rx_descs[i].RXBUF_BADR = lp->rx_buf_dma+RX_BUF_SIZE*i;
373 lp->rx_descs[i].VIR_RXBUF_BADR=(unsigned int)lp->rx_buf+RX_BUF_SIZE*i;
375 lp->rx_descs[RXDES_NUM-1].EDOTR = 1; // is last descriptor
377 lp->tx_descs = consistent_alloc( GFP_DMA|GFP_KERNEL, sizeof(TX_DESC)*TXDES_NUM, &(lp->tx_descs_dma) );
378 if (lp->tx_descs == NULL || (( (u32)lp->tx_descs & 0xf)!=0))
380 printk("Transmit Ring Buffer allocation error\n");
381 BUG();
383 memset((void *)lp->tx_descs,0,sizeof(TX_DESC)*TXDES_NUM);
384 lp->tx_buf = consistent_alloc( GFP_DMA|GFP_KERNEL, TX_BUF_SIZE*TXDES_NUM, &(lp->tx_buf_dma) );
385 if (lp->tx_buf == NULL || (( (u32)lp->tx_buf % 4)!=0))
387 printk("Transmit Ring Buffer allocation error\n");
388 BUG();
392 for (i=0; i<TXDES_NUM; ++i)
394 lp->tx_descs[i].EDOTR = 0; // not last descriptor
395 lp->tx_descs[i].TXBUF_BADR=lp->tx_buf_dma+TX_BUF_SIZE*i;
396 lp->tx_descs[i].VIR_TXBUF_BADR=(unsigned int)lp->tx_buf+TX_BUF_SIZE*i;
398 lp->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor
399 #if 0
400 PRINTK("lp->rx_descs = %x, lp->rx_rx_descs_dma = %x\n",lp->rx_descs, lp->rx_descs_dma);
401 PRINTK("lp->rx_buf = %x, lp->rx_buf_dma = %x\n",lp->rx_buf, lp->rx_buf_dma);
402 PRINTK("lp->tx_descs = %x, lp->tx_rx_descs_dma = %x\n", lp->tx_descs, lp->tx_descs_dma);
403 PRINTK("lp->tx_buf = %x, lp->tx_buf_dma = %x\n", lp->tx_buf, lp->tx_buf_dma);
404 #endif
407 #if 0
408 static int ftmac100_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
410 struct net_device *dev = (struct net_device *)data;
411 struct ftmac100_local *lp = (struct ftmac100_local *)dev->priv;
412 int num;
413 int i;
415 //printk("+ftmac100_read_proc\n");
417 num = sprintf(page, "lp->rx_idx = %d\n", lp->rx_idx);
418 for (i=0; i<RXDES_NUM; ++i)
419 num += sprintf(page + num, "[%d].RXDMA_OWN = %d\n", i, lp->rx_descs[i].RXDMA_OWN);
420 return num;
422 #endif
424 /*----------------------------------------------------------------------
425 . Function: ftmac100_probe( unsigned int ioaddr )
427 . Purpose:
428 . Tests to see if a given ioaddr points to an ftmac100 chip.
429 . Returns a 0 on success
430 .---------------------------------------------------------------------
432 static int __init ftmac100_probe(struct net_device *dev, unsigned int ioaddr )
434 int retval;
435 static unsigned version_printed = 0;
436 struct ftmac100_local *lp;
438 //printk("+ftmac100_probe\n");
440 if (version_printed++ == 0)
441 printk("%s", version);
442 dev->base_addr = ioaddr;
444 /* now, print out the card info, in a short format.. */
445 printk("%s: device at %#3x IRQ:%d NOWAIT:%d\n",dev->name, ioaddr, dev->irq, dev->dma);
447 dev->priv = kmalloc(sizeof(struct ftmac100_local), GFP_KERNEL);
448 if (dev->priv == NULL)
450 retval = -ENOMEM;
451 goto err_out;
454 memset(dev->priv, 0, sizeof(struct ftmac100_local));
455 lp = (struct ftmac100_local *)dev->priv;
456 spin_lock_init(&lp->lock);
457 lp->maccr_val = FULLDUP_bit | CRC_APD_bit | MDC_SEL_bit | RCV_EN_bit | XMT_EN_bit | RDMA_EN_bit | XDMA_EN_bit ;
458 ftmac100_ringbuf_alloc(lp);
461 /* now, reset the chip, and put it into a known state */
462 ftmac100_reset( dev );
464 /* Fill in the fields of the device structure with ethernet values. */
465 ether_setup(dev);
467 cpe_int_set_irq(dev->irq, LEVEL, H_ACTIVE);
468 /* Grab the IRQ */
469 retval = request_irq(dev->irq, &ftmac100_interrupt, SA_INTERRUPT, dev->name, dev);
470 if (retval)
472 printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, retval);
473 kfree (dev->priv);
474 dev->priv = NULL;
475 goto err_out;
478 dev->open = ftmac100_open;
479 dev->stop = ftmac100_close;
480 dev->hard_start_xmit = ftmac100_wait_to_send_packet;
481 dev->tx_timeout = ftmac100_timeout;
482 dev->get_stats = ftmac100_query_statistics;
483 #ifdef HAVE_MULTICAST
484 dev->set_multicast_list = &ftmac100_set_multicast_list;
485 #endif
486 #if 0
487 if ((proc_ftmac100 = create_proc_entry( "ftmac100", 0, 0 )))
489 proc_ftmac100->read_proc = ftmac100_read_proc;
490 proc_ftmac100->data = dev;
491 proc_ftmac100->owner = THIS_MODULE;
493 #endif
494 return 0;
496 err_out:
497 return retval;
501 #if FTMAC100_DEBUG > 2
502 static void print_packet( unsigned char * buf, int length )
504 #if FTMAC100_DEBUG > 3
505 int i;
506 int remainder;
507 int lines;
508 #endif
510 // printk("Packet of length %d \n", length );
512 #if FTMAC100_DEBUG > 3
513 lines = length / 16;
514 remainder = length % 16;
516 for ( i = 0; i < lines ; i ++ )
518 int cur;
520 for ( cur = 0; cur < 8; cur ++ )
522 unsigned char a, b;
524 a = *(buf ++ );
525 b = *(buf ++ );
526 printk("%02x%02x ", a, b );
528 printk("\n");
530 for ( i = 0; i < remainder/2 ; i++ )
532 unsigned char a, b;
534 a = *(buf ++ );
535 b = *(buf ++ );
536 printk("%02x%02x ", a, b );
538 printk("\n");
539 #endif
541 #endif
545 * Open and Initialize the board
547 * Set up everything, reset the card, etc ..
550 static int ftmac100_open(struct net_device *dev)
552 //printk("+%s:ftmac100_open\n", dev->name);
554 netif_start_queue(dev);
556 #ifdef MODULE
557 MOD_INC_USE_COUNT;
558 #endif
560 /* reset the hardware */
561 ftmac100_reset( dev );
562 ftmac100_enable( dev );
564 /* Configure the PHY */
565 ftmac100_phy_configure(dev);
567 netif_start_queue(dev);
568 return 0;
572 /*--------------------------------------------------------
573 . Called by the kernel to send a packet out into the void
574 . of the net. This routine is largely based on
575 . skeleton.c, from Becker.
576 .--------------------------------------------------------
578 static void ftmac100_timeout (struct net_device *dev)
580 /* If we get here, some higher level has decided we are broken.
581 There should really be a "kick me" function call instead. */
582 printk(KERN_WARNING "%s: transmit timed out?\n",dev->name);
584 //printk("+ftmac100_timeout\n");
586 ftmac100_reset( dev );
587 ftmac100_enable( dev );
588 ftmac100_phy_configure(dev);
589 netif_wake_queue(dev);
590 dev->trans_start = jiffies;
594 /*--------------------------------------------------------------------
596 . This is the main routine of the driver, to handle the net_device when
597 . it needs some attention.
599 . So:
600 . first, save state of the chipset
601 . branch off into routines to handle each case, and acknowledge
602 . each to the interrupt register
603 . and finally restore state.
605 ---------------------------------------------------------------------*/
606 static void ftmac100_interrupt(int irq, void * dev_id, struct pt_regs * regs)
608 struct net_device *dev=dev_id;
609 unsigned int ioaddr=dev->base_addr;
610 unsigned char status; // interrupt status
611 unsigned char mask; // interrupt mask
612 int timeout;
613 struct ftmac100_local *lp = (struct ftmac100_local *)dev->priv;
615 //printk("+ftmac100_interrupt\n");
617 if (dev == NULL)
619 printk(KERN_WARNING "%s: irq %d for unknown device.\n", dev->name, irq);
620 return;
623 /* read the interrupt status register */
624 mask = inl( ioaddr + IMR_REG );
626 /* set a timeout value, so I don't stay here forever */
628 // PRINTK(KERN_WARNING "%s: MASK IS %x \n", dev->name, mask);
629 for (timeout=1; timeout>0; --timeout)
631 /* read the status flag, and mask it */
632 status = inl( ioaddr + ISR_REG ) & mask;
633 if (!status )
634 break;
636 if ( status & RPKT_FINISH_bit )
637 ftmac100_rcv(dev);
638 else if (status & NORXBUF_bit) // CPU ¨Ó¤£¤Î³B²z, packet °eªº¤Ó§Ö
640 ///printk("NORXBUF \n");
641 //printk("<0x%x:NORXBUF>",status);
642 outl( mask & ~NORXBUF_bit, ioaddr + IMR_REG); /// ¼È®ÉÃö±¼ NORXBUF interrupt
643 trans_busy = 1;
644 lp->rcv_tq.sync = 0;
645 lp->rcv_tq.routine=ftmac100_rcv;
646 lp->rcv_tq.data = dev;
647 queue_task(&lp->rcv_tq, &tq_timer);
649 else if (status & AHB_ERR_bit)
650 printk("<0x%x:AHB_ERR>",status);
652 return;
657 /*-------------------------------------------------------------
659 . ftmac100_rcv - receive a packet from the card
661 . There is ( at least ) a packet waiting to be read from
662 . chip-memory.
664 . o Read the status
665 . o If an error, record it
666 . o otherwise, read in the packet
667 --------------------------------------------------------------
670 static void ftmac100_rcv(void *devp)
672 struct net_device *dev=(struct net_device *)devp;
673 struct ftmac100_local *lp = (struct ftmac100_local *)dev->priv;
674 unsigned int ioaddr=dev->base_addr;
675 int packet_length;
676 int rcv_cnt;
677 volatile RX_DESC *cur_desc;
678 int cpy_length;
679 int cur_idx;
680 int seg_length;
681 int have_package;
682 int have_frs;
683 int start_idx;
685 //printk("+ftmac100_rcv\n");
687 start_idx = lp->rx_idx;
689 for (rcv_cnt=0; rcv_cnt<8 ; ++rcv_cnt)
691 packet_length = 0;
692 cur_idx = lp->rx_idx;
694 have_package = 0;
695 have_frs = 0;
696 for (; (cur_desc = &lp->rx_descs[lp->rx_idx])->RXDMA_OWN==0; )
698 have_package = 1;
699 lp->rx_idx = (lp->rx_idx+1)%RXDES_NUM;
700 if (cur_desc->FRS)
702 have_frs = 1;
703 if (cur_desc->RX_ERR || cur_desc->CRC_ERR || cur_desc->FTL || cur_desc->RUNT || cur_desc->RX_ODD_NB)
705 lp->stats.rx_errors++; // error frame....
706 break;
708 if (cur_desc->MULTICAST)
709 lp->stats.multicast++;
710 packet_length = cur_desc->ReceiveFrameLength; // normal frame
712 if ( cur_desc->LRS ) // packet's last frame
713 break;
715 if (have_package==0)
716 goto done;
717 if (have_frs == 0)
718 lp->stats.rx_over_errors++;
720 if (packet_length>0)
722 struct sk_buff * skb;
723 unsigned char * data;
725 // Allocate enough memory for entire receive frame, to be safe
726 skb = dev_alloc_skb( packet_length+2 );
728 if ( skb == NULL )
730 printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", dev->name);
731 lp->stats.rx_dropped++;
732 goto done;
735 skb_reserve( skb, 2 ); /* 16 bit alignment */
736 skb->dev = dev;
738 data = skb_put( skb, packet_length);
739 cpy_length = 0;
740 for (; cur_idx!=lp->rx_idx; cur_idx=(cur_idx+1)%RXDES_NUM)
742 seg_length = min(packet_length - cpy_length, RX_BUF_SIZE);
743 memcpy(data+cpy_length, (char *)lp->rx_descs[cur_idx].VIR_RXBUF_BADR, seg_length);
744 cpy_length += seg_length;
747 skb->protocol = eth_type_trans(skb, dev );
748 netif_rx(skb);
749 lp->stats.rx_packets++;
753 done:
754 if (start_idx != lp->rx_idx)
756 for (cur_idx = (start_idx+1)%RXDES_NUM; cur_idx != lp->rx_idx; cur_idx = (cur_idx+1)%RXDES_NUM)
758 lp->rx_descs[cur_idx].RXDMA_OWN = 1; /// ¦¹ frame ¤w³B²z§¹²¦, ÁÙµ¹ hardware
760 lp->rx_descs[start_idx].RXDMA_OWN = 1;
762 if (trans_busy == 1)
764 outl( lp->maccr_val, ioaddr + MACCR_REG );
765 outl( inl(ioaddr + IMR_REG) | NORXBUF_bit, ioaddr + IMR_REG);
767 return;
772 /*----------------------------------------------------
773 . ftmac100_close
775 . this makes the board clean up everything that it can
776 . and not talk to the outside world. Caused by
777 . an 'ifconfig ethX down'
779 -----------------------------------------------------*/
780 static int ftmac100_close(struct net_device *dev)
782 //printk("+ftmac100_close\n");
784 netif_stop_queue(dev);
786 ftmac100_shutdown( dev->base_addr );
787 #ifdef MODULE
788 MOD_DEC_USE_COUNT;
789 #endif
790 return 0;
793 /*------------------------------------------------------------
794 . Get the current statistics.
795 . This may be called with the card open or closed.
796 .-------------------------------------------------------------*/
797 static struct net_device_stats* ftmac100_query_statistics(struct net_device *dev)
799 struct ftmac100_local *lp = (struct ftmac100_local *)dev->priv;
801 //printk("+ftmac100_query_statistics\n");
803 return &lp->stats;
807 #ifdef HAVE_MULTICAST
810 . Function: ftmac100_setmulticast( unsigned int ioaddr, int count, dev_mc_list * adds )
811 . Purpose:
812 . This sets the internal hardware table to filter out unwanted multicast
813 . packets before they take up memory.
816 static void ftmac100_setmulticast( unsigned int ioaddr, int count, struct dev_mc_list * addrs )
818 struct dev_mc_list * cur_addr;
819 int crc_val;
821 //printk("+ftmac100_setmulticast\n");
823 for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next )
825 if ( !( *cur_addr->dmi_addr & 1 ) )
826 continue;
827 crc_val = crc32( cur_addr->dmi_addr, 6 );
828 crc_val = (crc_val>>26)&0x3f; // ¨ú MSB 6 bit
829 if (crc_val >= 32)
830 outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
831 else
832 outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
837 /*-----------------------------------------------------------
838 . ftmac100_set_multicast_list
840 . This routine will, depending on the values passed to it,
841 . either make it accept multicast packets, go into
842 . promiscuous mode ( for TCPDUMP and cousins ) or accept
843 . a select set of multicast packets
845 static void ftmac100_set_multicast_list(struct net_device *dev)
847 unsigned int ioaddr = dev->base_addr;
848 struct ftmac100_local *lp = (struct ftmac100_local *)dev->priv;
850 //printk("+ftmac100_set_multicast_list\n");
852 if (dev->flags & IFF_PROMISC)
853 lp->maccr_val |= RCV_ALL_bit;
854 else
855 lp->maccr_val &= ~RCV_ALL_bit;
857 if ( !(dev->flags & IFF_ALLMULTI) )
858 lp->maccr_val |= RX_MULTIPKT_bit;
859 else
860 lp->maccr_val &= ~RX_MULTIPKT_bit;
862 if (dev->mc_count)
864 lp->maccr_val |= HT_MULTI_EN_bit;
865 ftmac100_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
867 else
868 lp->maccr_val &= ~HT_MULTI_EN_bit;
870 outl( lp->maccr_val, ioaddr + MACCR_REG );
872 #endif
875 #if 0
876 //#ifdef MODULE
877 static struct net_device devFMAC;
878 static int io = 0;
879 static int irq = 0;
880 static int nowait = 0;
882 MODULE_PARM(io, "i");
883 MODULE_PARM(irq, "i");
884 MODULE_PARM(nowait, "i");
886 /*------------------------------------------------------------
887 . Module initialization function
888 .-------------------------------------------------------------*/
889 int init_module(void)
891 int result;
893 //printk("+init_module\n");
895 /* copy the parameters from insmod into the device structure */
896 devFMAC.base_addr=io;
897 devFMAC.irq=irq;
898 devFMAC.dma=nowait; // Use DMA field for nowait
899 devFMAC.init=FTCmac_probe; //john ftmac100_init;/* Kernel 2.4 Changes - Pramod */
900 if ((result = register_netdev(&devFMAC)) != 0)
901 return result;
903 return 0;
906 /*------------------------------------------------------------
907 . Cleanup when module is removed with rmmod
908 .-------------------------------------------------------------*/
909 void cleanup_module(void)
911 //printk("+cleanup_module\n");
913 /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
914 unregister_netdev(&devFMAC);
916 free_irq(devFMAC.irq, &devFMAC);
917 release_region(devFMAC.base_addr, SMC_IO_EXTENT);
919 if (devFMAC.priv)
920 kfree(devFMAC.priv); /* Kernel 2.4 Changes - Pramod */
923 #endif /* MODULE */
926 #if 0
927 /*------------------------------------------------------------
928 . Reads a register from the MII Management serial interface
929 .-------------------------------------------------------------*/
930 static word ftmac100_read_phy_register(unsigned int ioaddr, unsigned char phyaddr, unsigned char phyreg)
932 return 0;
936 /*------------------------------------------------------------
937 . Writes a register to the MII Management serial interface
938 .-------------------------------------------------------------*/
939 static void ftmac100_write_phy_register(unsigned int ioaddr,
940 unsigned char phyaddr, unsigned char phyreg, word phydata)
945 #endif
946 /*------------------------------------------------------------
947 . Configures the specified PHY using Autonegotiation.
948 .-------------------------------------------------------------*/
949 static void ftmac100_phy_configure(struct net_device* dev)
951 return;