root/drivers/net/net_init.c

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

DEFINITIONS

This source file includes following definitions.
  1. net_dev_init
  2. init_etherdev
  3. ether_setup
  4. ether_config
  5. register_netdev
  6. unregister_netdev

   1 /* netdrv_init.c: Initialization for network devices. */
   2 /*
   3         Written 1993 by Donald Becker.
   4         Copyright 1993 United States Government as represented by the Director,
   5         National Security Agency.  This software may only be used and distributed
   6         according to the terms of the GNU Public License as modified by SRC,
   7         incorported herein by reference.
   8 
   9         The author may be reached as becker@super.org or
  10         C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
  11 
  12         This file contains the initialization for the "pl14+" style ethernet
  13         drivers.  It should eventually replace most of drivers/net/Space.c.
  14         It's primary advantage is that it's able to allocate low-memory buffers.
  15         A secondary advantage is that the dangerous NE*000 netcards can reserve
  16         their I/O port region before the SCSI probes start.
  17 
  18         Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
  19                 ethdev_index[MAX_ETH_CARDS]
  20                 register_netdev() / unregister_netdev()
  21 */
  22 
  23 #include <linux/config.h>
  24 #include <linux/kernel.h>
  25 #include <linux/sched.h>
  26 #include <linux/types.h>
  27 #include <linux/fs.h>
  28 #include <linux/malloc.h>
  29 #include <linux/if_ether.h>
  30 #include <linux/string.h>
  31 #include <linux/netdevice.h>
  32 #include <linux/etherdevice.h>
  33 
  34 /* The network devices currently exist only in the socket namespace, so these
  35    entries are unused.  The only ones that make sense are
  36     open        start the ethercard
  37     close       stop  the ethercard
  38     ioctl       To get statistics, perhaps set the interface port (AUI, BNC, etc.)
  39    One can also imagine getting raw packets using
  40     read & write
  41    but this is probably better handled by a raw packet socket.
  42 
  43    Given that almost all of these functions are handled in the current
  44    socket-based scheme, putting ethercard devices in /dev/ seems pointless.
  45    
  46    [Removed all support for /dev network devices. When someone adds streams then
  47     by magic we get them, but otherwise they are un-needed and a space waste]
  48 */
  49 
  50 /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
  51 #define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
  52 static struct device *ethdev_index[MAX_ETH_CARDS];
  53 
  54 unsigned long lance_init(unsigned long mem_start, unsigned long mem_end);
  55 
  56 /*
  57   net_dev_init() is our network device initialization routine.
  58   It's called from init/main.c with the start and end of free memory,
  59   and returns the new start of free memory.
  60   */
  61 
  62 unsigned long net_dev_init (unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64 
  65 #if defined(CONFIG_LANCE)                       /* Note this is _not_ CONFIG_AT1500. */
  66         mem_start = lance_init(mem_start, mem_end);
  67 #endif
  68 #if defined(CONFIG_PI)
  69         mem_start = pi_init(mem_start, mem_end);
  70 #endif  
  71         return mem_start;
  72 }
  73 
  74 /* Fill in the fields of the device structure with ethernet-generic values.
  75 
  76    If no device structure is passed, a new one is constructed, complete with
  77    a SIZEOF_PRIVATE private data area.
  78 
  79    If an empty string area is passed as dev->name, or a new structure is made,
  80    a new name string is constructed.  The passed string area should be 8 bytes
  81    long.
  82  */
  83 
  84 struct device *
  85 init_etherdev(struct device *dev, int sizeof_private, unsigned long *mem_startp)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87         int new_device = 0;
  88         int i;
  89 
  90         if (dev == NULL) {
  91                 int alloc_size = sizeof(struct device) + sizeof("eth%d ")
  92                         + sizeof_private;
  93                 if (mem_startp && *mem_startp ) {
  94                         dev = (struct device *)*mem_startp;
  95                         *mem_startp += alloc_size;
  96                 } else
  97                         dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
  98                 memset(dev, 0, sizeof(alloc_size));
  99                 dev->name = (char *)(dev + 1);
 100                 if (sizeof_private)
 101                         dev->priv = dev->name + sizeof("eth%d ");
 102                 new_device = 1;
 103         }
 104 
 105         if (dev->name &&
 106                 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 107                 for (i = 0; i < MAX_ETH_CARDS; ++i)
 108                         if (ethdev_index[i] == NULL) {
 109                                 sprintf(dev->name, "eth%d", i);
 110                                 ethdev_index[i] = dev;
 111                                 break;
 112                         }
 113         }
 114 
 115         ether_setup(dev); /* should this be called here? */
 116         
 117         if (new_device) {
 118                 /* Append the device to the device queue. */
 119                 struct device **old_devp = &dev_base;
 120                 while ((*old_devp)->next)
 121                         old_devp = & (*old_devp)->next;
 122                 (*old_devp)->next = dev;
 123                 dev->next = 0;
 124         }
 125         return dev;
 126 }
 127 
 128 void ether_setup(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130         int i;
 131         /* Fill in the fields of the device structure with ethernet-generic values.
 132            This should be in a common file instead of per-driver.  */
 133         for (i = 0; i < DEV_NUMBUFFS; i++)
 134                 skb_queue_head_init(&dev->buffs[i]);
 135 
 136         /* register boot-defined "eth" devices */
 137         if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
 138                 i = simple_strtoul(dev->name + 3, NULL, 0);
 139                 if (ethdev_index[i] == NULL) {
 140                         ethdev_index[i] = dev;
 141                 }
 142                 else if (dev != ethdev_index[i]) {
 143                         /* Really shouldn't happen! */
 144                         printk("ether_setup: Ouch! Someone else took %s\n",
 145                                 dev->name);
 146                 }
 147         }
 148 
 149         dev->hard_header        = eth_header;
 150         dev->rebuild_header = eth_rebuild_header;
 151         dev->type_trans = eth_type_trans;
 152 
 153         dev->type               = ARPHRD_ETHER;
 154         dev->hard_header_len = ETH_HLEN;
 155         dev->mtu                = 1500; /* eth_mtu */
 156         dev->addr_len   = ETH_ALEN;
 157         for (i = 0; i < ETH_ALEN; i++) {
 158                 dev->broadcast[i]=0xff;
 159         }
 160 
 161         /* New-style flags. */
 162         dev->flags              = IFF_BROADCAST;
 163         dev->family             = AF_INET;
 164         dev->pa_addr    = 0;
 165         dev->pa_brdaddr = 0;
 166         dev->pa_mask    = 0;
 167         dev->pa_alen    = sizeof(unsigned long);
 168 }
 169 
 170 int ether_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
 171 {
 172         if (map->mem_start != (u_long)(-1))
 173                 dev->mem_start = map->mem_start;
 174         if (map->mem_end != (u_long)(-1))
 175                 dev->mem_end = map->mem_end;
 176         if (map->base_addr != (u_short)(-1))
 177                 dev->base_addr = map->base_addr;
 178         if (map->irq != (u_char)(-1))
 179                 dev->irq = map->irq;
 180         if (map->dma != (u_char)(-1))
 181                 dev->dma = map->dma;
 182         if (map->port != (u_char)(-1))
 183                 dev->if_port = map->port;
 184         return 0;
 185 }
 186 
 187 int register_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189         struct device *d = dev_base;
 190         unsigned long flags;
 191         int i;
 192 
 193         save_flags(flags);
 194         cli();
 195 
 196         if (dev && dev->init) {
 197                 if (dev->init(dev) != 0) {
 198                         restore_flags(flags);
 199                         return -EIO;
 200                 }
 201 
 202                 if (dev->name &&
 203                         ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 204                         for (i = 0; i < MAX_ETH_CARDS; ++i)
 205                                 if (ethdev_index[i] == NULL) {
 206                                         sprintf(dev->name, "eth%d", i);
 207                                         printk("device '%s' loaded\n", dev->name);
 208                                         ethdev_index[i] = dev;
 209                                         break;
 210                                 }
 211                 }
 212 
 213                 /* Add device to end of chain */
 214                 if (dev_base) {
 215                         while (d->next)
 216                                 d = d->next;
 217                         d->next = dev;
 218                 }
 219                 else
 220                         dev_base = dev;
 221                 dev->next = NULL;
 222         }
 223         restore_flags(flags);
 224         return 0;
 225 }
 226 
 227 void unregister_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229         struct device *d = dev_base;
 230         unsigned long flags;
 231         int i;
 232 
 233         save_flags(flags);
 234         cli();
 235 
 236         printk("unregister_netdev: device ");
 237 
 238         if (dev == NULL) {
 239                 printk("was NULL\n");
 240                 restore_flags(flags);
 241                 return;
 242         }
 243         /* else */
 244         if (dev->start)
 245                 printk("'%s' busy\n", dev->name);
 246         else {
 247                 if (dev_base == dev)
 248                         dev_base = dev->next;
 249                 else {
 250                         while (d && (d->next != dev))
 251                                 d = d->next;
 252 
 253                         if (d && (d->next == dev)) {
 254                                 d->next = dev->next;
 255                                 printk("'%s' unlinked\n", dev->name);
 256                         }
 257                         else {
 258                                 printk("'%s' not found\n", dev->name);
 259                                 restore_flags(flags);
 260                                 return;
 261                         }
 262                 }
 263                 for (i = 0; i < MAX_ETH_CARDS; ++i) {
 264                         if (ethdev_index[i] == dev) {
 265                                 ethdev_index[i] = NULL;
 266                                 break;
 267                         }
 268                 }
 269         }
 270         restore_flags(flags);
 271 }
 272 
 273 
 274 
 275 /*
 276  * Local variables:
 277  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
 278  *  version-control: t
 279  *  kept-new-versions: 5
 280  *  tab-width: 4
 281  * End:
 282  */

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