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 reg_ptr);
 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 reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360         int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 361         struct device *dev = (struct device *)(irq2dev_map[irq]);
 362         struct net_local *lp;
 363         int ioaddr, status, boguscount = 0;
 364 
 365         if (dev == NULL) {
 366                 printk ("net_interrupt(): irq %d for unknown device.\n", irq);
 367                 return;
 368         }
 369         dev->interrupt = 1;
 370 
 371         ioaddr = dev->base_addr;
 372         lp = (struct net_local *)dev->priv;
 373         status = inw(ioaddr + 0);
 374 
 375         do {
 376                 if (status /*& RX_INTR*/) {
 377                         /* Got a packet(s). */
 378                         net_rx(dev);
 379                 }
 380                 if (status /*& TX_INTR*/) {
 381                         lp->stats.tx_packets++;
 382                         dev->tbusy = 0;
 383                         mark_bh(NET_BH);        /* Inform upper layers. */
 384                 }
 385                 if (status /*& COUNTERS_INTR*/) {
 386                         /* Increment the appropriate 'localstats' field. */
 387                         lp->stats.tx_window_errors++;
 388                 }
 389         } while (++boguscount < 20) ;
 390 
 391         dev->interrupt = 0;
 392         return;
 393 }
 394 
 395 /* We have a good packet(s), get it/them out of the buffers. */
 396 static void
 397 net_rx(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {
 399         struct net_local *lp = (struct net_local *)dev->priv;
 400         int ioaddr = dev->base_addr;
 401         int boguscount = 10;
 402 
 403         do {
 404                 int status = inw(ioaddr);
 405                 int pkt_len = inw(ioaddr);
 406           
 407                 if (pkt_len == 0)               /* Read all the frames? */
 408                         break;                  /* Done for now */
 409 
 410                 if (status & 0x40) {    /* There was an error. */
 411                         lp->stats.rx_errors++;
 412                         if (status & 0x20) lp->stats.rx_frame_errors++;
 413                         if (status & 0x10) lp->stats.rx_over_errors++;
 414                         if (status & 0x08) lp->stats.rx_crc_errors++;
 415                         if (status & 0x04) lp->stats.rx_fifo_errors++;
 416                 } else {
 417                         /* Malloc up new buffer. */
 418                         struct sk_buff *skb;
 419 
 420                         skb = alloc_skb(pkt_len, GFP_ATOMIC);
 421                         if (skb == NULL) {
 422                                 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 423                                 lp->stats.rx_dropped++;
 424                                 break;
 425                         }
 426                         skb->len = pkt_len;
 427                         skb->dev = dev;
 428 
 429                         /* 'skb->data' points to the start of sk_buff data area. */
 430                         memcpy(skb->data, (void*)dev->rmem_start,
 431                                    pkt_len);
 432                         /* or */
 433                         insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
 434 
 435                         netif_rx(skb);
 436                         lp->stats.rx_packets++;
 437                 }
 438         } while (--boguscount);
 439 
 440         /* If any worth-while packets have been received, dev_rint()
 441            has done a mark_bh(NET_BH) for us and will work on them
 442            when we get to the bottom-half routine. */
 443         return;
 444 }
 445 
 446 /* The inverse routine to net_open(). */
 447 static int
 448 net_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450         struct net_local *lp = (struct net_local *)dev->priv;
 451         int ioaddr = dev->base_addr;
 452 
 453         lp->open_time = 0;
 454 
 455         dev->tbusy = 1;
 456         dev->start = 0;
 457 
 458         /* Flush the Tx and disable Rx here. */
 459 
 460         disable_dma(dev->dma);
 461 
 462         /* If not IRQ or DMA jumpered, free up the line. */
 463         outw(0x00, ioaddr+0);           /* Release the physical interrupt line. */
 464 
 465         free_irq(dev->irq);
 466         free_dma(dev->dma);
 467 
 468         irq2dev_map[dev->irq] = 0;
 469 
 470         /* Update the statistics here. */
 471 
 472         return 0;
 473 
 474 }
 475 
 476 /* Get the current statistics.  This may be called with the card open or
 477    closed. */
 478 static struct enet_statistics *
 479 net_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 480 {
 481         struct net_local *lp = (struct net_local *)dev->priv;
 482         short ioaddr = dev->base_addr;
 483 
 484         cli();
 485         /* Update the statistics from the device registers. */
 486         lp->stats.rx_missed_errors = inw(ioaddr+1);
 487         sti();
 488 
 489         return &lp->stats;
 490 }
 491 
 492 /* Set or clear the multicast filter for this adaptor.
 493    num_addrs == -1      Promiscuous mode, receive all packets
 494    num_addrs == 0       Normal mode, clear multicast list
 495    num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 496                         best-effort filtering.
 497  */
 498 static void
 499 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 500 {
 501         short ioaddr = dev->base_addr;
 502         if (num_addrs) {
 503                 outw(69, ioaddr);               /* Enable promiscuous mode */
 504         } else
 505                 outw(99, ioaddr);               /* Disable promiscuous mode, use normal mode */
 506 }
 507 
 508 /*
 509  * Local variables:
 510  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
 511  *  version-control: t
 512  *  kept-new-versions: 5
 513  *  tab-width: 4
 514  * End:
 515  */

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