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 staticconstchar *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 #ifdefMODULE 47 #include <linux/module.h>
48 #include <linux/version.h>
49 #else 50 #defineMOD_INC_USE_COUNTdo{}while (0)
51 #defineMOD_DEC_USE_COUNTdo{}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 staticconstchar* 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 staticunsignedintnetcard_portlist[] =
82 { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
83
84 /* use 0 for production, 1 for verification, >2 for debug */ 85 #ifndefNET_DEBUG 86 #defineNET_DEBUG 2
87 #endif 88 staticunsignedintnet_debug = NET_DEBUG;
89
90 /* The number of low I/O ports used by the ethercard. */ 91 #defineNETCARD_IO_EXTENT 32
92
93 /* Information that need to be kept for each board. */ 94 structnet_local{ 95 structenet_statisticsstats;
96 longopen_time; /* Useless example local info. */ 97 };
98
99 /* The station (ethernet) address prefix, used for IDing the board. */ 100 #defineSA_ADDR0 0x00
101 #defineSA_ADDR1 0x42
102 #defineSA_ADDR2 0x65
103
104 /* Index to functions, as function prototypes. */ 105
106 externintnetcard_probe(structdevice *dev);
107
108 staticintnetcard_probe1(structdevice *dev, intioaddr);
109 staticintnet_open(structdevice *dev);
110 staticintnet_send_packet(structsk_buff *skb, structdevice *dev);
111 staticvoidnet_interrupt(intirq, structpt_regs *regs);
112 staticvoidnet_rx(structdevice *dev);
113 staticintnet_close(structdevice *dev);
114 staticstructenet_statistics *net_get_stats(structdevice *dev);
115 staticvoidset_multicast_list(structdevice *dev, intnum_addrs, void *addrs);
116
117 /* Example routines you must write ;->. */ 118 #definetx_done(dev) 1
119 externvoidhardware_send_packet(shortioaddr, char *buf, intlength);
120 externvoidchipset_init(structdevice *dev, intstartp);
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 #ifdefHAVE_DEVLIST 130 /* Support for a alternate probe manager, which will eliminate the 131 boilerplate below. */ 132 structnetdev_entrynetcard_drv =
133 {cardname, netcard_probe1, NETCARD_IO_EXTENT, netcard_portlist};
134 #else 135 int 136 netcard_probe(structdevice *dev)
/* */ 137 { 138 inti;
139 intbase_addr = dev ? dev->base_addr : 0;
140
141 if (base_addr > 0x1ff) /* Check a single specified location. */ 142 returnnetcard_probe1(dev, base_addr);
143 elseif (base_addr != 0) /* Don't probe at all. */ 144 return -ENXIO;
145
146 for (i = 0; netcard_portlist[i]; i++) { 147 intioaddr = 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 staticintnetcard_probe1(structdevice *dev, intioaddr)
/* */ 163 { 164 staticunsignedversion_printed = 0;
165 inti;
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, 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 elseif (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 }elseif (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 intirqval = 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 shortdma_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(structnet_local), GFP_KERNEL);
272 if (dev->priv == NULL)
273 return -ENOMEM;
274 } 275
276 memset(dev->priv, 0, sizeof(structnet_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 staticint 302 net_open(structdevice *dev)
/* */ 303 { 304 structnet_local *lp = (structnet_local *)dev->priv;
305 intioaddr = 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 staticint 335 net_send_packet(structsk_buff *skb, structdevice *dev)
/* */ 336 { 337 structnet_local *lp = (structnet_local *)dev->priv;
338 intioaddr = 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 inttickssofar = 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 shortlength = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
368 unsignedchar *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 staticvoid 385 net_interrupt(intirq, structpt_regs * regs)
/* */ 386 { 387 structdevice *dev = (structdevice *)(irq2dev_map[irq]);
388 structnet_local *lp;
389 intioaddr, 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 = (structnet_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 staticvoid 423 net_rx(structdevice *dev)
/* */ 424 { 425 structnet_local *lp = (structnet_local *)dev->priv;
426 intioaddr = dev->base_addr;
427 intboguscount = 10;
428
429 do{ 430 intstatus = inw(ioaddr);
431 intpkt_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 structsk_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 staticint 474 net_close(structdevice *dev)
/* */ 475 { 476 structnet_local *lp = (structnet_local *)dev->priv;
477 intioaddr = 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 staticstructenet_statistics *
507 net_get_stats(structdevice *dev)
/* */ 508 { 509 structnet_local *lp = (structnet_local *)dev->priv;
510 shortioaddr = 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 staticvoid 527 set_multicast_list(structdevice *dev, intnum_addrs, void *addrs)
/* */ 528 { 529 shortioaddr = 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 #ifdefMODULE 537
538 charkernel_version[] = UTS_RELEASE;
539 staticchardevicename[9] = { 0, };
540 staticstructdevicethis_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 intio = 0x300;
547 intirq = 0;
548 intdma = 0;
549 intmem = 0;
550
551 intinit_module(void)
/* */ 552 { 553 intresult;
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 returnresult;
567
568 return 0;
569 } 570
571 void 572 cleanup_module(void)
/* */ 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(structnet_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 */