~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/jazzsonic.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * sonic.c
  3  *
  4  * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de)
  5  * 
  6  * This driver is based on work from Andreas Busse, but most of
  7  * the code is rewritten.
  8  * 
  9  * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de)
 10  *
 11  * A driver for the onboard Sonic ethernet controller on Mips Jazz
 12  * systems (Acer Pica-61, Mips Magnum 4000, Olivetti M700 and
 13  * perhaps others, too)
 14  */
 15 
 16 #include <linux/kernel.h>
 17 #include <linux/sched.h>
 18 #include <linux/types.h>
 19 #include <linux/fcntl.h>
 20 #include <linux/interrupt.h>
 21 #include <linux/ptrace.h>
 22 #include <linux/init.h>
 23 #include <linux/ioport.h>
 24 #include <linux/in.h>
 25 #include <linux/malloc.h>
 26 #include <linux/string.h>
 27 #include <linux/delay.h>
 28 #include <asm/bootinfo.h>
 29 #include <asm/system.h>
 30 #include <asm/bitops.h>
 31 #include <asm/pgtable.h>
 32 #include <asm/segment.h>
 33 #include <asm/io.h>
 34 #include <asm/dma.h>
 35 #include <asm/jazz.h>
 36 #include <asm/jazzdma.h>
 37 #include <linux/errno.h>
 38 
 39 #include <linux/netdevice.h>
 40 #include <linux/etherdevice.h>
 41 #include <linux/skbuff.h>
 42 
 43 #define SREGS_PAD(n)    u16 n;
 44 
 45 #include "sonic.h"
 46 
 47 /*
 48  * Macros to access SONIC registers
 49  */
 50 #define SONIC_READ(reg) \
 51         *((volatile unsigned int *)base_addr+reg)
 52 
 53 #define SONIC_WRITE(reg,val) \
 54         *((volatile unsigned int *)base_addr+reg) = val
 55 
 56 
 57 /* use 0 for production, 1 for verification, >2 for debug */
 58 #ifdef SONIC_DEBUG
 59 static unsigned int sonic_debug = SONIC_DEBUG;
 60 #else 
 61 static unsigned int sonic_debug = 1;
 62 #endif
 63 
 64 /*
 65  * Base address and interupt of the SONIC controller on JAZZ boards
 66  */
 67 static struct {
 68     unsigned int port;
 69     unsigned int irq;
 70 } sonic_portlist[] = { {JAZZ_ETHERNET_BASE, JAZZ_ETHERNET_IRQ}, {0, 0}};
 71 
 72 /*
 73  * We cannot use station (ethernet) address prefixes to detect the
 74  * sonic controller since these are board manufacturer depended.
 75  * So we check for known Silicon Revision IDs instead. 
 76  */
 77 static unsigned short known_revisions[] =
 78 {
 79   0x04,                         /* Mips Magnum 4000 */
 80   0xffff                        /* end of list */
 81 };
 82 
 83 /* Index to functions, as function prototypes. */
 84 
 85 extern int sonic_probe(struct net_device *dev);
 86 static int sonic_probe1(struct net_device *dev, unsigned int base_addr, unsigned int irq);
 87 
 88 
 89 /*
 90  * Probe for a SONIC ethernet controller on a Mips Jazz board.
 91  * Actually probing is superfluous but we're paranoid.
 92  */
 93 int __init sonic_probe(struct net_device *dev)
 94 {
 95     unsigned int base_addr = dev ? dev->base_addr : 0;
 96     int i;
 97 
 98     /*
 99      * Don't probe if we're not running on a Jazz board.
100      */
101     if (mips_machgroup != MACH_GROUP_JAZZ)
102         return -ENODEV;
103     if (base_addr >= KSEG0)     /* Check a single specified location. */
104         return sonic_probe1(dev, base_addr, dev->irq);
105     else if (base_addr != 0)    /* Don't probe at all. */
106         return -ENXIO;
107     
108     for (i = 0; sonic_portlist[i].port; i++) {
109         int base_addr = sonic_portlist[i].port;
110         if (check_region(base_addr, 0x100))
111             continue;
112         if (sonic_probe1(dev, base_addr, sonic_portlist[i].irq) == 0)
113             return 0;
114     }
115     return -ENODEV;
116 }
117 
118 static int __init sonic_probe1(struct net_device *dev,
119                                unsigned int base_addr, unsigned int irq)
120 {
121     static unsigned version_printed = 0;
122     unsigned int silicon_revision;
123     unsigned int val;
124     struct sonic_local *lp;
125     int i;
126     
127     /*
128      * get the Silicon Revision ID. If this is one of the known
129      * one assume that we found a SONIC ethernet controller at
130      * the expected location.
131      */
132     silicon_revision = SONIC_READ(SONIC_SR);
133     if (sonic_debug > 1)
134       printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);
135 
136     i = 0;
137     while ((known_revisions[i] != 0xffff) &&
138            (known_revisions[i] != silicon_revision))
139       i++;
140         
141     if (known_revisions[i] == 0xffff) {
142         printk("SONIC ethernet controller not found (0x%4x)\n",
143                silicon_revision);
144         return -ENODEV;
145     }
146     
147     if (!request_region(base_addr, 0x100, dev->name))
148         return -EBUSY;
149     
150     if (sonic_debug  &&  version_printed++ == 0)
151       printk(version);
152 
153     printk("%s: %s found at 0x%08x, ",
154            dev->name, "SONIC ethernet", base_addr);
155 
156     /* Fill in the 'dev' fields. */
157     dev->base_addr = base_addr;
158     dev->irq = irq;
159 
160     /*
161      * Put the sonic into software reset, then
162      * retrieve and print the ethernet address.
163      */
164     SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
165     SONIC_WRITE(SONIC_CEP,0);
166     for (i=0; i<3; i++) {
167         val = SONIC_READ(SONIC_CAP0-i);
168         dev->dev_addr[i*2] = val;
169         dev->dev_addr[i*2+1] = val >> 8;
170     }
171 
172     printk("HW Address ");
173     for (i = 0; i < 6; i++) {
174         printk("%2.2x", dev->dev_addr[i]);
175         if (i<5)
176           printk(":");
177     }
178     
179     printk(" IRQ %d\n", irq);
180     
181     /* Initialize the device structure. */
182     if (dev->priv == NULL) {
183         /*
184          * the memory be located in the same 64kb segment
185          */
186         lp = NULL;
187         i = 0;
188         do {
189             lp = (struct sonic_local *)kmalloc(sizeof(*lp), GFP_KERNEL);
190             if ((unsigned long)lp >> 16 != ((unsigned long)lp + sizeof(*lp) ) >> 16) {
191                 /* FIXME, free the memory later */
192                 kfree (lp);
193                 lp = NULL;
194             }
195         } while (lp == NULL && i++ < 20);
196         
197         if (lp == NULL) {
198             printk ("%s: couldn't allocate memory for descriptors\n",
199                     dev->name);
200             return -ENOMEM;
201         }
202         
203         memset(lp, 0, sizeof(struct sonic_local));
204         
205         /* get the virtual dma address */
206         lp->cda_laddr = vdma_alloc(PHYSADDR(lp),sizeof(*lp));
207         if (lp->cda_laddr == ~0UL) {
208             printk ("%s: couldn't get DMA page entry for descriptors\n",
209                     dev->name);
210             return -ENOMEM;
211         }
212 
213         lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda);
214         lp->rra_laddr = lp->tda_laddr + sizeof (lp->tda);
215         lp->rda_laddr = lp->rra_laddr + sizeof (lp->rra);
216         
217         /* allocate receive buffer area */
218         /* FIXME, maybe we should use skbs */
219         if ((lp->rba = (char *)kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL)) == NULL) {
220             printk ("%s: couldn't allocate receive buffers\n",dev->name);
221             return -ENOMEM;
222         }
223         
224         /* get virtual dma address */
225         if ((lp->rba_laddr = vdma_alloc(PHYSADDR(lp->rba),SONIC_NUM_RRS * SONIC_RBSIZE)) == ~0UL) {
226             printk ("%s: couldn't get DMA page entry for receive buffers\n",dev->name);
227             return -ENOMEM;
228         }
229         
230         /* now convert pointer to KSEG1 pointer */
231         lp->rba = (char *)KSEG1ADDR(lp->rba);
232         flush_cache_all();
233         dev->priv = (struct sonic_local *)KSEG1ADDR(lp);
234     }
235 
236     lp = (struct sonic_local *)dev->priv;
237     dev->open = sonic_open;
238     dev->stop = sonic_close;
239     dev->hard_start_xmit = sonic_send_packet;
240     dev->get_stats      = sonic_get_stats;
241     dev->set_multicast_list = &sonic_multicast_list;
242 
243     /*
244      * clear tally counter
245      */
246     SONIC_WRITE(SONIC_CRCT,0xffff);
247     SONIC_WRITE(SONIC_FAET,0xffff);
248     SONIC_WRITE(SONIC_MPT,0xffff);
249 
250     /* Fill in the fields of the device structure with ethernet values. */
251     ether_setup(dev);
252     return 0;
253 }
254 
255 /*
256  *      SONIC uses a normal IRQ
257  */
258 #define sonic_request_irq       request_irq
259 #define sonic_free_irq          free_irq
260 
261 #define sonic_chiptomem(x)      KSEG1ADDR(vdma_log2phys(x))
262 
263 #include "sonic.c"
264 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.