root/drivers/net/skeleton.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. netcard_probe
  2. netcard_probe1
  3. net_open
  4. net_send_packet
  5. net_interrupt
  6. net_rx
  7. net_close
  8. net_get_stats
  9. set_multicast_list
  10. init_module
  11. cleanup_module

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

/* [previous][next][first][last][top][bottom][index][help] */