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

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