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

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

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