1 /* skeleton.c: A network driver outline for linux. */
2 /*
3 Written 1993-94 by Donald Becker.
4
5 Copyright 1993 United States Government as represented by the
6 Director, National Security Agency.
7
8 This software may be used and distributed according to the terms
9 of the GNU Public License, incorporated herein by reference.
10
11 The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
12 Center of Excellence in Space Data and Information Sciences
13 Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
14
15 This file is an outline for writing a network device driver for the
16 the Linux operating system.
17
18 To write (or understand) a driver, have a look at the "loopback.c" file to
19 get a feel of what is going on, and then use the code below as a skeleton
20 for the new driver.
21
22 */
23
24 static const char *version =
25 "skeleton.c:v1.51 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
26
27 /* Always include 'config.h' first in case the user wants to turn on
28 or override something. */
29 #include <linux/config.h>
30
31 /*
32 Sources:
33 List your sources of programming information to document that
34 the driver is your own creation, and give due credit to others
35 that contributed to the work. Remember that GNU project code
36 cannot use proprietary or trade secret information. Interface
37 definitions are generally considered non-copyrightable to the
38 extent that the same names and structures must be used to be
39 compatible.
40
41 Finally, keep in mind that the Linux kernel is has an API, not
42 ABI. Proprietary object-code-only distributions are not permitted
43 under the GPL.
44 */
45
46 #ifdef MODULE
47 #include <linux/module.h>
48 #include <linux/version.h>
49 #else
50 #define MOD_INC_USE_COUNT do {} while (0)
51 #define MOD_DEC_USE_COUNT do {} while (0)
52 #endif
53
54 #include <linux/kernel.h>
55 #include <linux/sched.h>
56 #include <linux/types.h>
57 #include <linux/fcntl.h>
58 #include <linux/interrupt.h>
59 #include <linux/ptrace.h>
60 #include <linux/ioport.h>
61 #include <linux/in.h>
62 #include <linux/malloc.h>
63 #include <linux/string.h>
64 #include <asm/system.h>
65 #include <asm/bitops.h>
66 #include <asm/io.h>
67 #include <asm/dma.h>
68 #include <linux/errno.h>
69
70 #include <linux/netdevice.h>
71 #include <linux/etherdevice.h>
72 #include <linux/skbuff.h>
73
74 /* The name of the card. Is used for messages and in the requests for
75 * io regions, irqs and dma channels
76 */
77 static const char* cardname = "netcard";
78
79 /* First, a few definitions that the brave might change. */
80 /* A zero-terminated list of I/O addresses to be probed. */
81 static unsigned int netcard_portlist[] =
82 { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
83
84 /* use 0 for production, 1 for verification, >2 for debug */
85 #ifndef NET_DEBUG
86 #define NET_DEBUG 2
87 #endif
88 static unsigned int net_debug = NET_DEBUG;
89
90 /* The number of low I/O ports used by the ethercard. */
91 #define NETCARD_IO_EXTENT 32
92
93 /* Information that need to be kept for each board. */
94 struct net_local {
95 struct enet_statistics stats;
96 long open_time; /* Useless example local info. */
97 };
98
99 /* The station (ethernet) address prefix, used for IDing the board. */
100 #define SA_ADDR0 0x00
101 #define SA_ADDR1 0x42
102 #define SA_ADDR2 0x65
103
104 /* Index to functions, as function prototypes. */
105
106 extern int netcard_probe(struct device *dev);
107
108 static int netcard_probe1(struct device *dev, int ioaddr);
109 static int net_open(struct device *dev);
110 static int net_send_packet(struct sk_buff *skb, struct device *dev);
111 static void net_interrupt(int irq, struct pt_regs *regs);
112 static void net_rx(struct device *dev);
113 static int net_close(struct device *dev);
114 static struct enet_statistics *net_get_stats(struct device *dev);
115 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
116
117 /* Example routines you must write ;->. */
118 #define tx_done(dev) 1
119 extern void hardware_send_packet(short ioaddr, char *buf, int length);
120 extern void chipset_init(struct device *dev, int startp);
121
122
123 /* Check for a network adaptor of this type, and return '0' iff one exists.
124 If dev->base_addr == 0, probe all likely locations.
125 If dev->base_addr == 1, always return failure.
126 If dev->base_addr == 2, allocate space for the device and return success
127 (detachable devices only).
128 */
129 #ifdef HAVE_DEVLIST
130 /* Support for a alternate probe manager, which will eliminate the
131 boilerplate below. */
132 struct netdev_entry netcard_drv =
133 {cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist};
134 #else
135 int
136 netcard_probe(struct device *dev)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
137 {
138 int i;
139 int base_addr = dev ? dev->base_addr : 0;
140
141 if (base_addr > 0x1ff) /* Check a single specified location. */
142 return netcard_probe1(dev, base_addr);
143 else if (base_addr != 0) /* Don't probe at all. */
144 return -ENXIO;
145
146 for (i = 0; netcard_portlist[i]; i++) {
147 int ioaddr = netcard_portlist[i];
148 if (check_region(ioaddr, NETCARD_IO_EXTENT))
149 continue;
150 if (netcard_probe1(dev, ioaddr) == 0)
151 return 0;
152 }
153
154 return -ENODEV;
155 }
156 #endif
157
158 /* This is the real probe routine. Linux has a history of friendly device
159 probes on the ISA bus. A good device probes avoids doing writes, and
160 verifies that the correct device exists and functions. */
161
162 static int netcard_probe1(struct device *dev, int ioaddr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
163 {
164 static unsigned version_printed = 0;
165 int i;
166
167 /* For ethernet adaptors the first three octets of the station address
168 contains the manufacturer's unique code. That might be a good probe
169 method. Ideally you would add additional checks. */
170 if (inb(ioaddr + 0) != SA_ADDR0
171 || inb(ioaddr + 1) != SA_ADDR1
172 || inb(ioaddr + 2) != SA_ADDR2) {
173 return -ENODEV;
174 }
175
176 /* Allocate a new 'dev' if needed. */
177 if (dev == NULL) {
178 /* Don't allocate the private data here, it is done later
179 * This makes it easier to free the memory when this driver
180 * is used as a module.
181 */
182 dev = init_etherdev(0, 0);
183 if (dev == NULL)
184 return -ENOMEM;
185 }
186
187 if (net_debug && version_printed++ == 0)
188 printk(KERN_DEBUG "%s", version);
189
190 printk(KERN_INFO "%s: %s found at %#3x, ", dev->name, cardname, ioaddr);
191
192 /* Fill in the 'dev' fields. */
193 dev->base_addr = ioaddr;
194
195 /* Retrieve and print the ethernet address. */
196 for (i = 0; i < 6; i++)
197 printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
198
199 #ifdef jumpered_interrupts
200 /* If this board has jumpered interrupts, snarf the interrupt vector
201 now. There is no point in waiting since no other device can use
202 the interrupt, and this marks the irq as busy.
203 Jumpered interrupts are typically not reported by the boards, and
204 we must used autoIRQ to find them. */
205
206 if (dev->irq == -1)
207 ; /* Do nothing: a user-level program will set it. */
208 else if (dev->irq < 2) { /* "Auto-IRQ" */
209 autoirq_setup(0);
210 /* Trigger an interrupt here. */
211
212 dev->irq = autoirq_report(0);
213 if (net_debug >= 2)
214 printk(" autoirq is %d", dev->irq);
215 } else if (dev->irq == 2)
216 /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
217 * or don't know which one to set.
218 */
219 dev->irq = 9;
220
221 {
222 int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname);
223 if (irqval) {
224 printk("%s: unable to get IRQ %d (irqval=%d).\n",
225 dev->name, dev->irq, irqval);
226 return -EAGAIN;
227 }
228 }
229 #endif /* jumpered interrupt */
230 #ifdef jumpered_dma
231 /* If we use a jumpered DMA channel, that should be probed for and
232 allocated here as well. See lance.c for an example. */
233 if (dev->dma == 0) {
234 if (request_dma(dev->dma, cardname)) {
235 printk("DMA %d allocation failed.\n", dev->dma);
236 return -EAGAIN;
237 } else
238 printk(", assigned DMA %d.\n", dev->dma);
239 } else {
240 short dma_status, new_dma_status;
241
242 /* Read the DMA channel status registers. */
243 dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
244 (inb(DMA2_STAT_REG) & 0xf0);
245 /* Trigger a DMA request, perhaps pause a bit. */
246 outw(0x1234, ioaddr + 8);
247 /* Re-read the DMA status registers. */
248 new_dma_status = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
249 (inb(DMA2_STAT_REG) & 0xf0);
250 /* Eliminate the old and floating requests and DMA4, the cascade. */
251 new_dma_status ^= dma_status;
252 new_dma_status &= ~0x10;
253 for (i = 7; i > 0; i--)
254 if (test_bit(i, &new_dma_status)) {
255 dev->dma = i;
256 break;
257 }
258 if (i <= 0) {
259 printk("DMA probe failed.\n");
260 return -EAGAIN;
261 }
262 if (request_dma(dev->dma, cardname)) {
263 printk("probed DMA %d allocation failed.\n", dev->dma);
264 return -EAGAIN;
265 }
266 }
267 #endif /* jumpered DMA */
268
269 /* Initialize the device structure. */
270 if (dev->priv == NULL) {
271 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
272 if (dev->priv == NULL)
273 return -ENOMEM;
274 }
275
276 memset(dev->priv, 0, sizeof(struct net_local));
277
278 /* Grab the region so that no one else tries to probe our ioports. */
279 request_region(ioaddr, NETCARD_IO_EXTENT, cardname);
280
281 dev->open = net_open;
282 dev->stop = net_close;
283 dev->hard_start_xmit = net_send_packet;
284 dev->get_stats = net_get_stats;
285 dev->set_multicast_list = &set_multicast_list;
286
287 /* Fill in the fields of the device structure with ethernet values. */
288 ether_setup(dev);
289
290 return 0;
291 }
292
293
294 /* Open/initialize the board. This is called (in the current kernel)
295 sometime after booting when the 'ifconfig' program is run.
296
297 This routine should set everything up anew at each open, even
298 registers that "should" only need to be set once at boot, so that
299 there is non-reboot way to recover if something goes wrong.
300 */
301 static int
302 net_open(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
303 {
304 struct net_local *lp = (struct net_local *)dev->priv;
305 int ioaddr = dev->base_addr;
306
307 /* This is used if the interrupt line can turned off (shared).
308 See 3c503.c for an example of selecting the IRQ at config-time. */
309 if (request_irq(dev->irq, &net_interrupt, 0, cardname)) {
310 return -EAGAIN;
311 }
312
313 /* Always snarf the DMA channel after the IRQ, and clean up on failure. */
314 if (request_dma(dev->dma, cardname)) {
315 free_irq(dev->irq);
316 return -EAGAIN;
317 }
318 irq2dev_map[dev->irq] = dev;
319
320 /* Reset the hardware here. Don't forget to set the station address. */
321 /*chipset_init(dev, 1);*/
322 outb(0x00, ioaddr);
323 lp->open_time = jiffies;
324
325 dev->tbusy = 0;
326 dev->interrupt = 0;
327 dev->start = 1;
328
329 MOD_INC_USE_COUNT;
330
331 return 0;
332 }
333
334 static int
335 net_send_packet(struct sk_buff *skb, struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
336 {
337 struct net_local *lp = (struct net_local *)dev->priv;
338 int ioaddr = dev->base_addr;
339
340 if (dev->tbusy) {
341 /* If we get here, some higher level has decided we are broken.
342 There should really be a "kick me" function call instead. */
343 int tickssofar = jiffies - dev->trans_start;
344 if (tickssofar < 5)
345 return 1;
346 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
347 tx_done(dev) ? "IRQ conflict" : "network cable problem");
348 /* Try to restart the adaptor. */
349 chipset_init(dev, 1);
350 dev->tbusy=0;
351 dev->trans_start = jiffies;
352 }
353
354 /* If some higher layer thinks we've missed an tx-done interrupt
355 we are passed NULL. Caution: dev_tint() handles the cli()/sti()
356 itself. */
357 if (skb == NULL) {
358 dev_tint(dev);
359 return 0;
360 }
361
362 /* Block a timer-based transmit from overlapping. This could better be
363 done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
364 if (set_bit(0, (void*)&dev->tbusy) != 0)
365 printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
366 else {
367 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
368 unsigned char *buf = skb->data;
369
370 hardware_send_packet(ioaddr, buf, length);
371 dev->trans_start = jiffies;
372 }
373 dev_kfree_skb (skb, FREE_WRITE);
374
375 /* You might need to clean up and record Tx statistics here. */
376 if (inw(ioaddr) == /*RU*/81)
377 lp->stats.tx_aborted_errors++;
378
379 return 0;
380 }
381
382 /* The typical workload of the driver:
383 Handle the network interface interrupts. */
384 static void
385 net_interrupt(int irq, struct pt_regs * regs)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
386 {
387 struct device *dev = (struct device *)(irq2dev_map[irq]);
388 struct net_local *lp;
389 int ioaddr, status, boguscount = 0;
390
391 if (dev == NULL) {
392 printk(KERN_WARNING "%s: irq %d for unknown device.\n", cardname, irq);
393 return;
394 }
395 dev->interrupt = 1;
396
397 ioaddr = dev->base_addr;
398 lp = (struct net_local *)dev->priv;
399 status = inw(ioaddr + 0);
400
401 do {
402 if (status /*& RX_INTR*/) {
403 /* Got a packet(s). */
404 net_rx(dev);
405 }
406 if (status /*& TX_INTR*/) {
407 lp->stats.tx_packets++;
408 dev->tbusy = 0;
409 mark_bh(NET_BH); /* Inform upper layers. */
410 }
411 if (status /*& COUNTERS_INTR*/) {
412 /* Increment the appropriate 'localstats' field. */
413 lp->stats.tx_window_errors++;
414 }
415 } while (++boguscount < 20) ;
416
417 dev->interrupt = 0;
418 return;
419 }
420
421 /* We have a good packet(s), get it/them out of the buffers. */
422 static void
423 net_rx(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
424 {
425 struct net_local *lp = (struct net_local *)dev->priv;
426 int ioaddr = dev->base_addr;
427 int boguscount = 10;
428
429 do {
430 int status = inw(ioaddr);
431 int pkt_len = inw(ioaddr);
432
433 if (pkt_len == 0) /* Read all the frames? */
434 break; /* Done for now */
435
436 if (status & 0x40) { /* There was an error. */
437 lp->stats.rx_errors++;
438 if (status & 0x20) lp->stats.rx_frame_errors++;
439 if (status & 0x10) lp->stats.rx_over_errors++;
440 if (status & 0x08) lp->stats.rx_crc_errors++;
441 if (status & 0x04) lp->stats.rx_fifo_errors++;
442 } else {
443 /* Malloc up new buffer. */
444 struct sk_buff *skb;
445
446 skb = dev_alloc_skb(pkt_len);
447 if (skb == NULL) {
448 printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
449 dev->name);
450 lp->stats.rx_dropped++;
451 break;
452 }
453 skb->dev = dev;
454
455 /* 'skb->data' points to the start of sk_buff data area. */
456 memcpy(skb_put(skb,pkt_len), (void*)dev->rmem_start,
457 pkt_len);
458 /* or */
459 insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
460
461 netif_rx(skb);
462 lp->stats.rx_packets++;
463 }
464 } while (--boguscount);
465
466 /* If any worth-while packets have been received, dev_rint()
467 has done a mark_bh(NET_BH) for us and will work on them
468 when we get to the bottom-half routine. */
469 return;
470 }
471
472 /* The inverse routine to net_open(). */
473 static int
474 net_close(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
475 {
476 struct net_local *lp = (struct net_local *)dev->priv;
477 int ioaddr = dev->base_addr;
478
479 lp->open_time = 0;
480
481 dev->tbusy = 1;
482 dev->start = 0;
483
484 /* Flush the Tx and disable Rx here. */
485
486 disable_dma(dev->dma);
487
488 /* If not IRQ or DMA jumpered, free up the line. */
489 outw(0x00, ioaddr+0); /* Release the physical interrupt line. */
490
491 free_irq(dev->irq);
492 free_dma(dev->dma);
493
494 irq2dev_map[dev->irq] = 0;
495
496 /* Update the statistics here. */
497
498 MOD_DEC_USE_COUNT;
499
500 return 0;
501
502 }
503
504 /* Get the current statistics. This may be called with the card open or
505 closed. */
506 static struct enet_statistics *
507 net_get_stats(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
508 {
509 struct net_local *lp = (struct net_local *)dev->priv;
510 short ioaddr = dev->base_addr;
511
512 cli();
513 /* Update the statistics from the device registers. */
514 lp->stats.rx_missed_errors = inw(ioaddr+1);
515 sti();
516
517 return &lp->stats;
518 }
519
520 /* Set or clear the multicast filter for this adaptor.
521 num_addrs == -1 Promiscuous mode, receive all packets
522 num_addrs == 0 Normal mode, clear multicast list
523 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
524 best-effort filtering.
525 */
526 static void
527 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
528 {
529 short ioaddr = dev->base_addr;
530 if (num_addrs) {
531 outw(69, ioaddr); /* Enable promiscuous mode */
532 } else
533 outw(99, ioaddr); /* Disable promiscuous mode, use normal mode */
534 }
535
536 #ifdef MODULE
537
538 char kernel_version[] = UTS_RELEASE;
539 static char devicename[9] = { 0, };
540 static struct device this_device = {
541 devicename, /* device name is inserted by linux/drivers/net/net_init.c */
542 0, 0, 0, 0,
543 0, 0, /* I/O address, IRQ */
544 0, 0, 0, NULL, netcard_probe };
545
546 int io = 0x300;
547 int irq = 0;
548 int dma = 0;
549 int mem = 0;
550
551 int init_module(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
552 {
553 int result;
554
555 if (io == 0)
556 printk(KERN_WARNING "%s: You shouldn't use auto-probing with insmod!\n",
557 cardname);
558
559 /* copy the parameters from insmod into the device structure */
560 this_device.base_addr = io;
561 this_device.irq = irq;
562 this_device.dma = dma;
563 this_device.mem_start = mem;
564
565 if ((result = register_netdev(&this_device)) != 0)
566 return result;
567
568 return 0;
569 }
570
571 void
572 cleanup_module(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
573 {
574 /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
575
576 unregister_netdev(&this_device);
577
578 /* If we don't do this, we can't re-insmod it later. */
579 /* Release irq/dma here, when you have jumpered versions and snarfed
580 * them in net_probe1().
581 */
582 /*
583 free_irq(this_device.irq);
584 free_dma(this_device.dma);
585 */
586 release_region(this_device.base_addr, NETCARD_IO_EXTENT);
587
588 if (this_device.priv)
589 kfree_s(this_device.priv, sizeof(struct net_local));
590 }
591
592 #endif /* MODULE */
593
594 /*
595 * Local variables:
596 * compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -Wwrite-strings -Wredundant-decls -O2 -m486 -c skeleton.c"
597 * version-control: t
598 * kept-new-versions: 5
599 * tab-width: 4
600 * c-indent-level: 4
601 * End:
602 */