source: trunk/target/linux/rdc-2.6/files/drivers/net/r6040.c @ 8354

Last change on this file since 8354 was 8354, checked in by florian, 10 years ago

Put back some code from the 2.4 driver, supposed to boot network perfs

File size: 28.5 KB
Line 
1/* r6040.c: A RDC R6040 FastEthernet driver for linux. */
2/*
3        Re-written 2004 by Sten Wang.
4
5        Copyright 1994-2000 by Donald Becker.
6        Copyright 1993 United States Government as represented by the
7        Director, National Security Agency.      This software may be used and
8        distributed according to the terms of the GNU General Public License,
9        incorporated herein by reference.
10
11        This driver is for RDC R6040 FastEthernet MAC series.
12        For kernel version after 2.4.22
13
14        Modification List
15        ----------      ------------------------------------------------
16        08-24-2006      Support at linux 2.6.10 above
17        03-24-2006      Support NAPI
18        03-21-2006      By Charies,change spin_lock_irqsave(lp->lock, flags) to
19                        spin_lock_irqsave(&lp->lock, flags) in set_multicast_list
20        03-15-2006      Modify the set_multicast_list ,due to when re-plug the ethernet,
21                        it will forget the previous setting
22        07-12-2005      Tim, modify the set_multicast_list
23        03-28-2005      Tim, modify some error mac register offset in
24                        function set_multicast_list
25        03-27-2005      Tim, Add the internal state machine reset
26                        Sten, If multicast address more than 4, enter PROM mode
27                        Changed rdc to r6040
28        12-22-2004      Sten Init MAC MBCR register=0x012A
29                        PHY_CAP = 0x01E1
30
31        Need to Do LIst:
32        1. If multicast address more than 4, use the multicast address hash
33*/
34
35#define DRV_NAME        "r6040"
36#define DRV_VERSION     "0.13"
37#define DRV_RELDATE     "24Aug2006"
38
39/* PHY CHIP Address */
40#define PHY1_ADDR       1       /* For MAC1 */
41#define PHY2_ADDR       2       /* For MAC2 */
42#define PHY_MODE        0x3100  /* PHY CHIP Register 0 */
43#define PHY_CAP         0x01E1  /* PHY CHIP Register 4 */
44
45/* Time in jiffies before concluding the transmitter is hung. */
46#define TX_TIMEOUT      (6000 * HZ / 1000)
47#define TIMER_WUT       (jiffies + HZ * 1)/* timer wakeup time : 1 second */
48
49/* RDC MAC ID */
50#define RDC_MAC_ID      0x6040
51
52/* RDC MAC I/O Size */
53#define R6040_IO_SIZE   256
54
55/* RDC Chip PCI Command */
56#define R6040_PCI_CMD   0x0005  /* IO, Master */
57
58/* MAX RDC MAC */
59#define MAX_MAC         2
60
61/* MAC setting */
62#define TX_DCNT         0x80    /* TX descriptor count */
63#define RX_DCNT         0x80    /* RX descriptor count */
64#define MAX_BUF_SIZE    0x600
65#define ALLOC_DESC_SIZE ((TX_DCNT+RX_DCNT)*sizeof(struct r6040_descriptor)+0x10)
66#define MBCR_DEFAULT    0x012A  /* MAC Bus Control Register */
67
68/* Debug enable or not */
69#define RDC_DEBUG       0
70
71#if RDC_DEBUG > 1
72#define RDC_DBUG(msg, value) printk("%s %x\n", msg, value);
73#else
74#define RDC_DBUG(msg, value)
75#endif
76
77
78#include <linux/module.h>
79#include <linux/version.h>
80#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
81#include <linux/moduleparam.h>
82#endif
83#include <linux/kernel.h>
84#include <linux/string.h>
85#include <linux/timer.h>
86#include <linux/errno.h>
87#include <linux/ioport.h>
88#include <linux/slab.h>
89#include <linux/interrupt.h>
90#include <linux/pci.h>
91#include <linux/netdevice.h>
92#include <linux/etherdevice.h>
93#include <linux/skbuff.h>
94#include <linux/init.h>
95#include <linux/delay.h>        /* for udelay() */
96#include <linux/mii.h>
97#include <linux/ethtool.h>
98#include <linux/crc32.h>
99#include <linux/spinlock.h>
100
101#include <asm/processor.h>
102#include <asm/bitops.h>
103#include <asm/io.h>
104#include <asm/irq.h>
105#include <asm/uaccess.h>
106
107MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>");
108MODULE_LICENSE("GPL");
109#ifdef CONFIG_R6040_NAPI
110MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet Driver");
111#else
112MODULE_DESCRIPTION("RDC R6040 PCI FastEthernet Driver");
113#endif
114
115#define R6040_INT_MASK                  0x0011
116
117struct r6040_descriptor {
118        u16     status, len;            /* 0-3 */
119        u32     buf;                    /* 4-7 */
120        u32     ndesc;                  /* 8-B */
121        u32     rev1;                   /* C-F */
122        char    *vbufp;                 /* 10-13 */
123        struct r6040_descriptor *vndescp;       /* 14-17 */
124        struct sk_buff *skb_ptr;        /* 18-1B */
125        u32     rev2;                   /* 1C-1F */
126} __attribute__(( aligned(32) ));
127
128struct r6040_private {
129        struct net_device_stats stats;
130        spinlock_t lock;
131        struct timer_list timer;
132        struct pci_dev *pdev;
133
134        struct r6040_descriptor *rx_insert_ptr;
135        struct r6040_descriptor *rx_remove_ptr;
136        struct r6040_descriptor *tx_insert_ptr;
137        struct r6040_descriptor *tx_remove_ptr;
138        u16     tx_free_desc, rx_free_desc, phy_addr, phy_mode;
139        u16     mcr0, mcr1;
140        dma_addr_t desc_dma;
141        char    *desc_pool;
142        u16     switch_sig;
143};
144
145struct r6040_chip_info {
146        const char *name;
147        u16 pci_flags;
148        int io_size;
149        int drv_flags;
150};
151
152#ifdef CONFIG_R6040_NAPI
153static int NAPI_status;
154#endif
155
156static int __devinitdata printed_version;
157#ifdef CONFIG_R6040_NAPI
158static char version[] __devinitdata =
159        KERN_INFO DRV_NAME ": RDC R6040 NAPI net driver, version "DRV_VERSION " (" DRV_RELDATE ")\n";   
160#else
161static char version[] __devinitdata =
162        KERN_INFO DRV_NAME ": RDC R6040 net driver, version "DRV_VERSION " (" DRV_RELDATE ")\n";       
163#endif
164static struct r6040_chip_info r6040_chip_info[] __devinitdata =
165{
166        { "RDC R6040 Knight", R6040_PCI_CMD, R6040_IO_SIZE, 0}
167};
168static char *parent = NULL;
169
170#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
171static int NUM_MAC_TABLE = 2 ;
172module_param(parent, charp, 0444);
173#else
174MODULE_PARM(parent, "s");
175#endif
176MODULE_PARM_DESC(parent, "Parent network device name");
177
178static int phy_table[] = { 0x1, 0x2};
179static u8 adr_table[2][8] = {{0x00, 0x00, 0x60, 0x00, 0x00, 0x01}, {0x00, 0x00, 0x60, 0x00, 0x00, 0x02}};
180
181#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
182        module_param_array(adr_table, int, &NUM_MAC_TABLE, 0644);
183#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
184        module_param_array(adr_table, int, NUM_MAC_TABLE, 0644);
185#else
186        MODULE_PARM(adr_table, "2-4i");
187#endif
188MODULE_PARM_DESC(adr_table, "MAC Address (assigned)");
189
190static int r6040_open(struct net_device *dev);
191static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev);
192static irqreturn_t r6040_interrupt(int irq, void *dev_id);
193static struct net_device_stats *r6040_get_stats(struct net_device *dev);
194static int r6040_close(struct net_device *dev);
195static void set_multicast_list(struct net_device *dev);
196static struct ethtool_ops netdev_ethtool_ops;
197static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
198static void r6040_down(struct net_device *dev);
199static void r6040_up(struct net_device *dev);
200static void r6040_tx_timeout (struct net_device *dev);
201static void r6040_timer(unsigned long);
202
203static int phy_mode_chk(struct net_device *dev);
204static int phy_read(int ioaddr, int phy_adr, int reg_idx);
205static void phy_write(int ioaddr, int phy_adr, int reg_idx, int dat);
206static void rx_buf_alloc(struct r6040_private *lp,struct net_device *dev);
207#ifdef CONFIG_R6040_NAPI
208static int r6040_poll(struct net_device *netdev, int *budget);
209#endif
210
211
212static int __devinit r6040_init_one (struct pci_dev *pdev,
213                                         const struct pci_device_id *ent)
214{
215        struct net_device *dev;
216        struct r6040_private *lp;
217        int ioaddr, io_size, err;
218        static int card_idx = -1; 
219        int chip_id = (int)ent->driver_data;
220
221        RDC_DBUG("r6040_init_one()", 0);
222
223        if (printed_version++)
224                printk(version);
225
226        if ((err = pci_enable_device (pdev)))
227                return err;
228
229        /* this should always be supported */
230        if (pci_set_dma_mask(pdev, 0xffffffff)) {
231                printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses not supported by the card!?\n");
232                return  -ENODEV;
233        }
234
235        /* IO Size check */
236        io_size = r6040_chip_info[chip_id].io_size;
237        if (pci_resource_len  (pdev, 0) < io_size) {
238                return  -ENODEV;
239        }
240
241        ioaddr = pci_resource_start (pdev, 0);  /* IO map base address */
242        pci_set_master(pdev);
243
244        dev = alloc_etherdev(sizeof(struct r6040_private));
245        if (dev == NULL)
246                return -ENOMEM;
247        SET_MODULE_OWNER(dev);
248
249        if (pci_request_regions(pdev, DRV_NAME)) {
250                printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
251                err = -ENODEV;
252                goto err_out_disable;
253        }
254
255        /* Init system & device */
256        lp = dev->priv;
257        dev->base_addr = ioaddr;
258        dev->irq = pdev->irq;
259
260        spin_lock_init(&lp->lock);
261        pci_set_drvdata(pdev, dev);
262
263        /* Set MAC address */
264        card_idx++;
265        memcpy(dev->dev_addr, (u8 *)&adr_table[card_idx][0], 6);
266
267        /* Link new device into r6040_root_dev */
268        lp->pdev = pdev;
269
270        /* Init RDC private data */
271        lp->mcr0 = 0x1002;
272        lp->phy_addr = phy_table[card_idx];
273        lp->switch_sig = 0;
274
275        /* The RDC-specific entries in the device structure. */
276        dev->open = &r6040_open;
277        dev->hard_start_xmit = &r6040_start_xmit;
278        dev->stop = &r6040_close;
279        dev->get_stats = &r6040_get_stats;
280        dev->set_multicast_list = &set_multicast_list;
281        dev->do_ioctl = &netdev_ioctl;
282        dev->ethtool_ops = &netdev_ethtool_ops;
283        dev->tx_timeout = &r6040_tx_timeout;
284        dev->watchdog_timeo = TX_TIMEOUT;
285#ifdef CONFIG_R6040_NAPI
286        dev->poll = &r6040_poll;
287        dev->weight = 64;
288#endif
289
290        /* Register net device. After this dev->name assign */
291        if ((err = register_netdev(dev))) {
292                printk(KERN_ERR DRV_NAME ": Failed to register net device\n");
293                goto err_out_res;
294        }
295
296        netif_carrier_on(dev);
297        return 0;
298
299err_out_res:
300        pci_release_regions(pdev);
301err_out_disable:
302        pci_disable_device(pdev);
303        pci_set_drvdata(pdev, NULL);
304        kfree(dev);
305
306        return err;
307}
308
309static void __devexit r6040_remove_one (struct pci_dev *pdev)
310{
311        struct net_device *dev = pci_get_drvdata(pdev);
312       
313        unregister_netdev(dev);
314        pci_release_regions(pdev);
315        kfree(dev);
316        pci_disable_device(pdev);
317        pci_set_drvdata(pdev, NULL);
318}
319
320static int
321r6040_open(struct net_device *dev)
322{
323        struct r6040_private *lp = dev->priv;
324        int i;
325
326        RDC_DBUG("r6040_open()", 0);
327
328        /* Request IRQ and Register interrupt handler */
329        i = request_irq(dev->irq, &r6040_interrupt, SA_SHIRQ, dev->name, dev);
330        if (i) return i;
331
332        /* Allocate Descriptor memory */
333        lp->desc_pool = pci_alloc_consistent(lp->pdev, ALLOC_DESC_SIZE, &lp->desc_dma); 
334        if (!lp->desc_pool) return -ENOMEM; 
335
336        r6040_up(dev);
337
338        netif_start_queue(dev);
339
340        if (lp->switch_sig != 0x0243)
341        {
342        /* set and active a timer process */
343        init_timer(&lp->timer);
344        lp->timer.expires = TIMER_WUT;
345        lp->timer.data = (unsigned long)dev;
346        lp->timer.function = &r6040_timer;
347        add_timer(&lp->timer);
348        }
349        return 0;
350}
351
352static void
353r6040_tx_timeout (struct net_device *dev)
354{
355        struct r6040_private *lp = dev->priv;
356        //int ioaddr = dev->base_addr;
357        //struct r6040_descriptor *descptr = lp->tx_remove_ptr;
358
359        RDC_DBUG("r6040_tx_timeout()", 0);
360
361        /* Transmitter timeout, serious problems. */
362        /* Sten: Nothing need to do so far. */
363        printk(KERN_ERR DRV_NAME ": Big Trobule, transmit timeout/n"); 
364        lp->stats.tx_errors++;
365        netif_stop_queue(dev);
366
367//printk("<RDC> XMT timedout: CR0 %x, CR40 %x, CR3C %x, CR2C %x, CR30 %x, CR34 %x, CR38 %x\n", inw(ioaddr), inw(ioaddr+0x40), inw(ioaddr+0x3c), inw(ioaddr+0x2c), inw(ioaddr+0x30), inw(ioaddr+0x34), inw(ioaddr+0x38));
368
369//printk("<RDC> XMT_TO: %08lx:%04x %04x %08lx %08lx %08lx %08lx\n", descptr, descptr->status, descptr->len, descptr->buf, descptr->skb_ptr, descptr->ndesc, descptr->vndescp);
370}
371
372
373static int
374r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
375{
376        struct r6040_private *lp = dev->priv;
377        struct r6040_descriptor *descptr;
378        int ioaddr = dev->base_addr;
379        unsigned long flags;
380
381        RDC_DBUG("r6040_start_xmit()", 0);
382
383        if (skb == NULL)        /* NULL skb directly return */ 
384                return 0;
385        if (skb->len >= MAX_BUF_SIZE) { /* Packet too long, drop it */
386                dev_kfree_skb(skb);
387                return 0;
388        }
389
390        /* Critical Section */
391        spin_lock_irqsave(&lp->lock, flags);
392
393        /* TX resource check */
394        if (!lp->tx_free_desc) { 
395                spin_unlock_irqrestore(&lp->lock, flags);
396                printk(KERN_ERR DRV_NAME ": NO TX DESC "); 
397                return 1;
398        }
399
400        /* Statistic Counter */
401        lp->stats.tx_packets++;
402        lp->stats.tx_bytes += skb->len;
403       
404        /* Set TX descriptor & Transmit it */
405        lp->tx_free_desc--;
406        descptr = lp->tx_insert_ptr;
407        if (skb->len < 0x3c) descptr->len = 0x3c;
408        else descptr->len = skb->len;
409        descptr->skb_ptr = skb;
410        descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
411        descptr->status = 0x8000;
412        outw(0x01, ioaddr + 0x14);
413        lp->tx_insert_ptr = descptr->vndescp;
414
415#if RDC_DEBUG
416 printk("Xmit(): %08lx:%04x %04x %08lx %08lx %08lx %08lx\n", descptr, descptr->status, descptr->len, descptr->buf, descptr->skb_ptr, descptr->ndesc, descptr->vndescp);
417#endif
418
419        /* If no tx resource, stop */
420        if (!lp->tx_free_desc) 
421                netif_stop_queue(dev);
422
423        dev->trans_start = jiffies;
424        spin_unlock_irqrestore(&lp->lock, flags);
425        return 0;
426}
427
428/* The RDC interrupt handler. */
429static irqreturn_t
430r6040_interrupt(int irq, void *dev_id)
431{
432        struct net_device *dev = dev_id;
433        struct r6040_private *lp;
434        struct r6040_descriptor *descptr;
435        struct sk_buff *skb_ptr;
436        int ioaddr, status;
437        unsigned long flags;
438#ifdef CONFIG_R6040_NAPI       
439        int handled = 1;
440#else
441        int handled = 0;
442#endif 
443
444        RDC_DBUG("r6040_interrupt()", 0);
445        if (dev == NULL) {
446                printk (KERN_ERR DRV_NAME ": INT() unknown device.\n");
447                return IRQ_RETVAL(handled);
448        }
449
450        lp = (struct r6040_private *)dev->priv;
451        spin_lock_irqsave(&lp->lock, flags);
452
453        /* Check MAC Interrupt status */
454        ioaddr = dev->base_addr;
455        outw(0x0, ioaddr + 0x40);       /* Mask Off RDC MAC interrupt */
456        status = inw(ioaddr + 0x3c);    /* Read INTR status and clear */
457       
458
459#ifdef CONFIG_R6040_NAPI               
460
461            if(netif_rx_schedule_prep(dev))     
462                {
463                NAPI_status = status ;     
464                __netif_rx_schedule(dev);
465                }
466       
467        spin_unlock_irqrestore(&lp->lock, flags);
468        return IRQ_RETVAL(handled);     
469#else           
470        /* TX interrupt request */
471        if (status & 0x10) {
472                handled = 1;
473                descptr = lp->tx_remove_ptr;
474                while(lp->tx_free_desc < TX_DCNT) {
475                        if (descptr->status & 0x8000) break; /* Not complte */
476                        skb_ptr = descptr->skb_ptr;
477                        pci_unmap_single(lp->pdev, descptr->buf, skb_ptr->len, PCI_DMA_TODEVICE);
478                        dev_kfree_skb_irq(skb_ptr); /* Free buffer */
479                        descptr->skb_ptr = 0;
480                        descptr = descptr->vndescp; /* To next descriptor */
481                        lp->tx_free_desc++;
482                }
483                lp->tx_remove_ptr = descptr;
484                if (lp->tx_free_desc) netif_wake_queue(dev);
485        } 
486
487        /* RX interrupt request */
488        if (status & 0x01) {
489                handled = 1;
490                descptr = lp->rx_remove_ptr;
491                while(lp->rx_free_desc) {
492                        if (descptr->status & 0x8000) break; /* No Rx packet */
493                        skb_ptr = descptr->skb_ptr;
494                        descptr->skb_ptr = 0;
495                        skb_ptr->dev = dev;
496                        skb_put(skb_ptr, descptr->len - 4);
497                        pci_unmap_single(lp->pdev, descptr->buf, MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
498                        skb_ptr->protocol = eth_type_trans(skb_ptr, dev);
499                        netif_rx(skb_ptr);  /* Send to upper layer */
500                        lp->stats.rx_packets++;
501                        lp->stats.rx_bytes += descptr->len;
502                        descptr = descptr->vndescp; /* To next descriptor */
503                        lp->rx_free_desc--;
504                }
505                lp->rx_remove_ptr = descptr;
506        }
507
508        /* Allocate new RX buffer */
509        if (lp->rx_free_desc < RX_DCNT) rx_buf_alloc(lp,dev);
510
511        outw(R6040_INT_MASK, ioaddr + 0x40);    /* TX/RX interrupt enable */
512        spin_unlock_irqrestore(&lp->lock, flags);
513#endif
514        return IRQ_RETVAL(handled);
515}
516
517
518static struct net_device_stats *
519r6040_get_stats(struct net_device *dev)
520{
521        struct r6040_private *lp = dev->priv;
522
523        RDC_DBUG("r6040_get_stats()", 0);
524        return &lp->stats;
525}
526
527/*
528 *     Set or clear the multicast filter for this adaptor.
529 */
530static void
531set_multicast_list(struct net_device *dev)
532{
533        struct r6040_private *lp = dev->priv;
534        struct dev_mc_list *mcptr;
535        int ioaddr = dev->base_addr;
536        u16 *adrp, i;
537        unsigned long flags;
538
539        RDC_DBUG("set_multicast_list()", 0);
540
541        /* MAC Address */       
542        adrp = (u16 *) dev->dev_addr;
543        outw(adrp[0], ioaddr + 0x68); 
544        outw(adrp[1], ioaddr + 0x6A); 
545        outw(adrp[2], ioaddr + 0x6C); 
546
547
548#if RDC_DEBUG
549        printk("MAC ADDR: %04x %04x %04x\n", adrp[0], adrp[1], adrp[2]);
550#endif
551
552        /* Promiscous Mode */
553        spin_lock_irqsave(&lp->lock, flags);
554        i = inw(ioaddr) & ~0x0120;              /* Clear AMCP & PROM */
555        if (dev->flags & IFF_PROMISC)
556            {   
557                i |= 0x0020;
558                lp->mcr0 |= 0x0020 ;
559            }
560        if (dev->mc_count > 4) i |= 0x0020;     /* Too many multicast address */
561        outw(i, ioaddr);
562        spin_unlock_irqrestore(&lp->lock, flags);
563       
564        /* Multicast Address */
565        if (dev->mc_count > 4)  /* Wait to do: Hash Table for multicast */
566                return;
567
568        /* Multicast Address 1~4 case */
569        for (i = 0, mcptr = dev->mc_list; (i<dev->mc_count) && (i<4); i++) {
570                adrp = (u16 *)mcptr->dmi_addr;
571                outw(adrp[0], ioaddr + 0x70 + 8*i); 
572                outw(adrp[1], ioaddr + 0x72 + 8*i); 
573                outw(adrp[2], ioaddr + 0x74 + 8*i); 
574                mcptr = mcptr->next;
575#if RDC_DEBUG
576        printk("M_ADDR: %04x %04x %04x\n", adrp[0], adrp[1], adrp[2]);
577#endif
578        }
579        for (i = dev->mc_count; i < 4; i++) {
580                outw(0xffff, ioaddr + 0x68 + 8*i); 
581                outw(0xffff, ioaddr + 0x6A + 8*i); 
582                outw(0xffff, ioaddr + 0x6C + 8*i); 
583        }
584}
585
586static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
587{
588        struct r6040_private *rp = dev->priv;
589
590        strcpy (info->driver, DRV_NAME);
591        strcpy (info->version, DRV_VERSION);
592        strcpy (info->bus_info, pci_name(rp->pdev));
593}
594
595static struct ethtool_ops netdev_ethtool_ops = {
596        .get_drvinfo            = netdev_get_drvinfo,
597};
598
599static int
600r6040_close(struct net_device *dev)
601{
602        struct r6040_private *lp = dev->priv;
603
604        RDC_DBUG("r6040_close()", 0);
605
606        /* deleted timer */
607        del_timer_sync(&lp->timer);
608
609        spin_lock_irq(&lp->lock);
610
611        netif_stop_queue(dev);
612
613        r6040_down(dev);
614
615        spin_unlock_irq(&lp->lock);
616
617        return 0;
618}
619
620#define DMZ_GPIO        1
621#define RDC3210_CFGREG_ADDR     0x0CF8
622#define RDC3210_CFGREG_DATA     0x0CFC
623static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
624{
625        struct r6040_private *lp = dev->priv;
626
627        RDC_DBUG("netdev_ioctl()", 0);
628        if (lp->switch_sig == 0x0243 && cmd == SIOCDEVPRIVATE)
629        {
630                unsigned long *data = (unsigned long *)rq->ifr_data, args[4];
631                int ioaddr = dev->base_addr;
632                unsigned int val;
633
634                data = (unsigned long *)rq->ifr_data;
635                if (copy_from_user(args, data, 4*sizeof(unsigned long)))
636                        return -EFAULT;
637
638                /* port priority */
639                if(args[0]&(1<<31))phy_write(ioaddr,29,19,(phy_read(ioaddr,29,19)|0x2000));     /* port 0 */
640                if(args[0]&(1<<29))phy_write(ioaddr,29,19,(phy_read(ioaddr,29,19)|0x0020));     /* port 1 */
641                if(args[0]&(1<<27))phy_write(ioaddr,29,20,(phy_read(ioaddr,29,20)|0x2000));     /* port 2 */
642                if(args[0]&(1<<25))phy_write(ioaddr,29,20,(phy_read(ioaddr,29,20)|0x0020));     /* port 3 */
643
644                /* DMZ LED */
645                val = 0x80000000 | (7 << 11) | ((0x48));
646                outl(val, RDC3210_CFGREG_ADDR);
647                udelay(10);
648                val = inl(RDC3210_CFGREG_DATA);
649
650                val |= (0x1 << DMZ_GPIO);
651                outl(val, RDC3210_CFGREG_DATA);
652                udelay(10);
653
654                val = 0x80000000 | (7 << 11) | ((0x4C));
655                outl(val, RDC3210_CFGREG_ADDR);
656                udelay(10);
657                val = inl(RDC3210_CFGREG_DATA);
658                if(args[0]&(1<<23))     /* DMZ enabled */
659                        val &= ~(0x1 << DMZ_GPIO);      /* low activated */
660                else val |= (0x1 << DMZ_GPIO);
661                outl(val, RDC3210_CFGREG_DATA);
662                udelay(10);
663        }
664        return 0;
665}
666
667/**
668        Stop RDC MAC and Free the allocated resource
669 */
670static void r6040_down(struct net_device *dev)
671{
672        struct r6040_private *lp = dev->priv;
673        int i;
674        int ioaddr = dev->base_addr;
675
676        RDC_DBUG("r6040_down()", 0);
677
678        /* Stop MAC */
679        outw(0x0000, ioaddr + 0x40);    /* Mask Off Interrupt */
680        outw(0x0001, ioaddr + 0x04);    /* Reset RDC MAC */
681        i = 0;
682        do{}while((i++ < 2048) && (inw(ioaddr + 0x04) & 0x1));
683       
684        free_irq(dev->irq, dev);
685
686        /* Free RX buffer */
687        for (i = 0; i < RX_DCNT; i++) {
688                if (lp->rx_insert_ptr->skb_ptr) {
689                        pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
690                        dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
691                        lp->rx_insert_ptr->skb_ptr = 0;
692                }
693                lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
694        }
695
696        /* Free TX buffer */
697        for (i = 0; i < TX_DCNT; i++) {
698                if (lp->tx_insert_ptr->skb_ptr) {
699                        pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, MAX_BUF_SIZE, PCI_DMA_TODEVICE);
700                        dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
701                        lp->rx_insert_ptr->skb_ptr = 0;
702                }
703                lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
704        }
705
706        /* Free Descriptor memory */
707        pci_free_consistent(lp->pdev, ALLOC_DESC_SIZE, lp->desc_pool, lp->desc_dma);
708}
709
710
711
712#ifdef CONFIG_R6040_NAPI
713static int r6040_poll(struct net_device *dev, int *budget)
714{
715        struct r6040_private *lp;
716        struct r6040_descriptor *descptr;
717        struct sk_buff *skb_ptr;
718        int ioaddr, status;
719        unsigned long flags;
720       
721       
722        ioaddr = dev->base_addr;       
723        lp = (struct r6040_private *)dev->priv;
724        unsigned long rx_work = dev->quota ;
725        unsigned long rx ;
726       
727       
728#if 1
729        /* TX interrupt request */
730        if (NAPI_status & 0x10) {
731               
732                descptr = lp->tx_remove_ptr;
733                while(lp->tx_free_desc < TX_DCNT) {
734                        if (descptr->status & 0x8000) break; /* Not complte */
735                        skb_ptr = descptr->skb_ptr;
736                        pci_unmap_single(lp->pdev, descptr->buf, skb_ptr->len, PCI_DMA_TODEVICE);
737                        dev_kfree_skb_irq(skb_ptr); /* Free buffer */
738                        descptr->skb_ptr = 0;
739                        descptr = descptr->vndescp; /* To next descriptor */
740                        lp->tx_free_desc++;
741                }
742                lp->tx_remove_ptr = descptr;
743                if (lp->tx_free_desc) netif_wake_queue(dev);
744        } 
745#endif 
746#if 1
747        /* RX interrupt request */
748        if (NAPI_status & 0x01) {               
749               
750                descptr = lp->rx_remove_ptr;
751                while(lp->rx_free_desc) {
752                        if (descptr->status & 0x8000) break; /* No Rx packet */
753                        skb_ptr = descptr->skb_ptr;
754                        descptr->skb_ptr = 0;
755                        skb_ptr->dev = dev;
756                        skb_put(skb_ptr, descptr->len - 4);
757                        pci_unmap_single(lp->pdev, descptr->buf, MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
758                        skb_ptr->protocol = eth_type_trans(skb_ptr, dev);                         
759                        netif_receive_skb(skb_ptr); /* Send to upper layer */
760                        lp->stats.rx_packets++;
761                        lp->stats.rx_bytes += descptr->len;
762                        descptr = descptr->vndescp; /* To next descriptor */
763                        lp->rx_free_desc--;
764                }
765                lp->rx_remove_ptr = descptr;
766               
767        }
768        /* Allocate new RX buffer */
769        if (lp->rx_free_desc < RX_DCNT) rx_buf_alloc(lp,dev);
770       
771        local_irq_disable();
772        netif_rx_complete(dev);
773        outw(R6040_INT_MASK,ioaddr + 0x40);     
774        local_irq_enable();
775        return 0;
776#endif         
777}
778#endif
779
780/* Init RDC MAC */
781static void r6040_up(struct net_device *dev)
782{
783        struct r6040_private *lp = dev->priv;
784        struct r6040_descriptor *descptr;
785        int i;
786        int ioaddr = dev->base_addr;
787        u32 tmp_addr;
788        dma_addr_t desc_dma, start_dma;
789       
790        RDC_DBUG("r6040_up()", 0);
791
792        /* Initilize */
793        lp->tx_free_desc = TX_DCNT;
794        lp->rx_free_desc = 0;
795
796        /* Init descriptor */
797        memset(lp->desc_pool, 0, ALLOC_DESC_SIZE); /* Let all descriptor = 0 */
798        lp->tx_insert_ptr = (struct r6040_descriptor *)lp->desc_pool;
799        lp->tx_remove_ptr = lp->tx_insert_ptr;
800        lp->rx_insert_ptr = (struct r6040_descriptor *)lp->tx_insert_ptr+TX_DCNT;
801        lp->rx_remove_ptr = lp->rx_insert_ptr;
802       
803        /* Init TX descriptor */
804        descptr = lp->tx_insert_ptr;
805        desc_dma = lp->desc_dma;
806        start_dma = desc_dma;
807        for (i = 0; i < TX_DCNT; i++) {
808                descptr->ndesc = cpu_to_le32(desc_dma + sizeof(struct r6040_descriptor));
809                descptr->vndescp = (descptr + 1);
810                descptr = (descptr + 1);
811                desc_dma += sizeof(struct r6040_descriptor);
812        }
813        (descptr - 1)->ndesc = cpu_to_le32(start_dma);
814        (descptr - 1)->vndescp = lp->tx_insert_ptr;
815
816        /* Init RX descriptor */
817        start_dma = desc_dma;
818        descptr = lp->rx_insert_ptr;
819        for (i = 0; i < RX_DCNT; i++) {
820                descptr->ndesc = cpu_to_le32(desc_dma + sizeof(struct r6040_descriptor));
821                descptr->vndescp = (descptr + 1);
822                descptr = (descptr + 1);
823                desc_dma += sizeof(struct r6040_descriptor);
824        }
825        (descptr - 1)->ndesc = cpu_to_le32(start_dma);
826        (descptr - 1)->vndescp = lp->rx_insert_ptr;
827
828        /* Allocate buffer for RX descriptor */
829        rx_buf_alloc(lp,dev);
830
831#if RDC_DEBUG
832descptr = lp->tx_insert_ptr;
833for (i = 0; i < TX_DCNT; i++) {
834 printk("%08lx:%04x %04x %08lx %08lx %08lx %08lx\n", descptr, descptr->status, descptr->len, descptr->buf, descptr->skb_ptr, descptr->ndesc, descptr->vndescp);
835 descptr = descptr->vndescp;
836}
837descptr = lp->rx_insert_ptr;
838for (i = 0; i < RX_DCNT; i++) {
839 printk("%08lx:%04x %04x %08lx %08lx %08lx %08lx\n", descptr, descptr->status, descptr->len, descptr->buf, descptr->skb_ptr, descptr->ndesc, descptr->vndescp);
840 descptr = descptr->vndescp;
841}
842#endif
843
844        /* MAC operation register */
845        outw(0x01, ioaddr+0x04);        /* Reset MAC */
846        outw(2   , ioaddr+0xAC);        /* Reset internal state machine */
847        outw(0   , ioaddr+0xAC);
848        udelay(5000);
849
850        /* TX and RX descriptor start Register */
851        tmp_addr = cpu_to_le32(lp->tx_insert_ptr);
852        tmp_addr = virt_to_bus((volatile void *)tmp_addr);
853        outw((u16) tmp_addr, ioaddr+0x2c);
854        outw(tmp_addr >> 16, ioaddr+0x30);
855        tmp_addr = cpu_to_le32(lp->rx_insert_ptr);
856        tmp_addr = virt_to_bus((volatile void *)tmp_addr);
857        outw((u16) tmp_addr, ioaddr+0x34);
858        outw(tmp_addr >> 16, ioaddr+0x38);
859
860        /* Buffer Size Register */
861        outw(MAX_BUF_SIZE, ioaddr+0x18);
862
863        if ((lp->switch_sig = phy_read(ioaddr, 0, 2)) == 0x0243)        // ICPlus IP175C Signature
864        {
865                phy_write(ioaddr, 29,31, 0x175C);       //Enable registers
866                lp->phy_mode = 0x8000;
867        } else {
868                /* PHY Mode Check */
869                phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP);
870                phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE);
871
872                if (PHY_MODE == 0x3100)
873                        lp->phy_mode = phy_mode_chk(dev);
874                else
875                        lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
876        }
877        /* MAC Bus Control Register */
878        outw(MBCR_DEFAULT, ioaddr+0x8);
879
880        /* MAC TX/RX Enable */
881        lp->mcr0 |= lp->phy_mode;
882        outw(lp->mcr0, ioaddr);
883
884        /* set interrupt waiting time and packet numbers */
885        outw(0x0802, ioaddr + 0x0C);
886        outw(0x0802, ioaddr + 0x10);
887
888        /* upgrade performance (by RDC guys) */
889        phy_write(ioaddr,30,17,(phy_read(ioaddr,30,17)|0x4000));        //bit 14=1
890        phy_write(ioaddr,30,17,~((~phy_read(ioaddr,30,17))|0x2000));    //bit 13=0
891        phy_write(ioaddr,0,19,0x0000);
892        phy_write(ioaddr,0,30,0x01F0);
893
894        /* Interrupt Mask Register */
895        outw(R6040_INT_MASK, ioaddr + 0x40);
896}
897
898/*
899  A periodic timer routine
900        Polling PHY Chip Link Status
901*/
902static void r6040_timer(unsigned long data)
903{
904        struct net_device *dev=(struct net_device *)data;
905        struct r6040_private *lp = dev->priv;
906        u16 ioaddr = dev->base_addr, phy_mode;
907 
908        RDC_DBUG("r6040_timer()", 0);
909
910        /* Polling PHY Chip Status */
911        if (PHY_MODE == 0x3100) 
912                phy_mode = phy_mode_chk(dev);
913        else phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
914
915        if (phy_mode != lp->phy_mode) {
916                lp->phy_mode = phy_mode;
917                lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode;
918                outw(lp->mcr0, ioaddr);
919                printk("<RDC> Link Change %x \n", inw(ioaddr));
920        }
921
922        /* Debug */
923//      printk("<RDC> Timer: CR0 %x CR40 %x CR3C %x\n", inw(ioaddr), inw(ioaddr+0x40), inw(ioaddr+0x3c));
924
925        /* Timer active again */
926        lp->timer.expires = TIMER_WUT;
927        add_timer(&lp->timer);
928}
929
930/* Allocate skb buffer for rx descriptor */
931static void rx_buf_alloc(struct r6040_private *lp,struct net_device *dev)
932{
933        struct r6040_descriptor *descptr;
934        int ioaddr = dev->base_addr ;
935
936        RDC_DBUG("rx_buf_alloc()", 0);
937        descptr = lp->rx_insert_ptr;
938        while(lp->rx_free_desc < RX_DCNT){
939                descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE);
940                if (!descptr->skb_ptr) break;
941                descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, descptr->skb_ptr->tail, MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
942                descptr->status = 0x8000;
943                descptr = descptr->vndescp;
944                lp->rx_free_desc++;
945                outw(lp->mcr0 | 0x0002, ioaddr);        //Trigger Rx DMA
946        }
947        lp->rx_insert_ptr = descptr;
948}
949
950/* Status of PHY CHIP */
951static int phy_mode_chk(struct net_device *dev)
952{
953        struct r6040_private *lp = dev->priv;
954        int ioaddr = dev->base_addr, phy_dat;
955
956        RDC_DBUG("phy_mode_chk()", 0);
957
958        /* PHY Link Status Check */
959        phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
960        if (!(phy_dat & 0x4)) return 0x8000;    /* Link Failed, full duplex */
961
962        /* PHY Chip Auto-Negotiation Status */
963        phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
964        if (phy_dat & 0x0020) {
965                /* Auto Negotiation Mode */
966                phy_dat = phy_read(ioaddr, lp->phy_addr, 5);
967                phy_dat &= phy_read(ioaddr, lp->phy_addr, 4);
968                if (phy_dat & 0x140) phy_dat = 0x8000;
969                else phy_dat = 0;
970        } else {
971                /* Force Mode */
972                phy_dat = phy_read(ioaddr, lp->phy_addr, 0);
973                if (phy_dat & 0x100) phy_dat = 0x8000;
974                else phy_dat = 0x0000;
975        }
976
977        return phy_dat;
978};
979
980/* Read a word data from PHY Chip */
981static int phy_read(int ioaddr, int phy_addr, int reg_idx)
982{
983        int i = 0;
984
985        RDC_DBUG("phy_read()", 0);
986        outw(0x2000 + reg_idx + (phy_addr << 8), ioaddr + 0x20);
987        do{}while( (i++ < 2048) && (inw(ioaddr + 0x20) & 0x2000) );
988
989        return inw(ioaddr + 0x24);
990}
991
992/* Write a word data from PHY Chip */
993static void phy_write(int ioaddr, int phy_addr, int reg_idx, int dat)
994{
995        int i = 0;
996
997        RDC_DBUG("phy_write()", 0);
998        outw(dat, ioaddr + 0x28);
999        outw(0x4000 + reg_idx + (phy_addr << 8), ioaddr + 0x20);
1000        do{}while( (i++ < 2048) && (inw(ioaddr + 0x20) & 0x4000) );
1001}
1002
1003enum {
1004        RDC_6040 = 0
1005};
1006
1007static struct pci_device_id r6040_pci_tbl[] = {
1008        {0x17F3, 0x6040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RDC_6040},
1009        //{0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RDC_6040},
1010        {0,}                    /* terminate list */
1011};
1012MODULE_DEVICE_TABLE(pci, r6040_pci_tbl);
1013
1014static struct pci_driver r6040_driver = {
1015        .name           = "r6040",
1016        .id_table       = r6040_pci_tbl,
1017        .probe          = r6040_init_one,
1018        .remove         = __devexit_p(r6040_remove_one),
1019};
1020
1021
1022static int __init r6040_init (void)
1023{
1024        RDC_DBUG("r6040_init()", 0);
1025
1026        printk(version);
1027        printed_version = 1;
1028
1029        if (parent != NULL)
1030        {
1031                struct net_device *the_parent = dev_get_by_name(parent);
1032
1033                if (the_parent == NULL)
1034                {
1035                        printk (KERN_ERR DRV_NAME ": Unknown device \"%s\" specified.\n", parent);
1036                        return -EINVAL;
1037                }
1038                memcpy((u8 *)&adr_table[0][0], the_parent->dev_addr, 6);
1039                memcpy((u8 *)&adr_table[1][0], the_parent->dev_addr, 6);
1040                ++*(u8 *)&adr_table[0][5];
1041        }
1042        return pci_register_driver (&r6040_driver);
1043}
1044
1045
1046static void __exit r6040_cleanup (void)
1047{
1048        RDC_DBUG("r6040_cleanup()", 0);
1049        pci_unregister_driver (&r6040_driver);
1050}
1051
1052module_init(r6040_init);
1053module_exit(r6040_cleanup);
1054
1055
1056/*
1057 * Local variables:
1058 *  compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c r6040.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
1059 *  c-indent-level: 4
1060 *  c-basic-offset: 4
1061 *  tab-width: 4
1062 * End:
1063 */
Note: See TracBrowser for help on using the repository browser.