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 unsigned long pi_init(unsigned long mem_start, unsigned long mem_end);
  56 unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end);
  57 
  58 
  59 /*
  60   net_dev_init() is our network device initialization routine.
  61   It's called from init/main.c with the start and end of free memory,
  62   and returns the new start of free memory.
  63   */
  64 
  65 unsigned long net_dev_init (unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67 
  68 #if defined(CONFIG_LANCE)                       /* Note this is _not_ CONFIG_AT1500. */
  69         mem_start = lance_init(mem_start, mem_end);
  70 #endif
  71 #if defined(CONFIG_PI)
  72         mem_start = pi_init(mem_start, mem_end);
  73 #endif  
  74 #if defined(CONFIG_APRICOT)
  75         mem_start = apricot_init(mem_start, mem_end);
  76 #endif  
  77         return mem_start;
  78 }
  79 
  80 /* Fill in the fields of the device structure with ethernet-generic values.
  81 
  82    If no device structure is passed, a new one is constructed, complete with
  83    a SIZEOF_PRIVATE private data area.
  84 
  85    If an empty string area is passed as dev->name, or a new structure is made,
  86    a new name string is constructed.  The passed string area should be 8 bytes
  87    long.
  88  */
  89 
  90 struct device *
  91 init_etherdev(struct device *dev, int sizeof_private, unsigned long *mem_startp)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         int new_device = 0;
  94         int i;
  95 
  96         if (dev == NULL) {
  97                 int alloc_size = sizeof(struct device) + sizeof("eth%d ")
  98                         + sizeof_private;
  99                 if (mem_startp && *mem_startp ) {
 100                         dev = (struct device *)*mem_startp;
 101                         *mem_startp += alloc_size;
 102                 } else
 103                         dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
 104                 memset(dev, 0, sizeof(alloc_size));
 105                 dev->name = (char *)(dev + 1);
 106                 if (sizeof_private)
 107                         dev->priv = dev->name + sizeof("eth%d ");
 108                 new_device = 1;
 109         }
 110 
 111         if (dev->name &&
 112                 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 113                 for (i = 0; i < MAX_ETH_CARDS; ++i)
 114                         if (ethdev_index[i] == NULL) {
 115                                 sprintf(dev->name, "eth%d", i);
 116                                 ethdev_index[i] = dev;
 117                                 break;
 118                         }
 119         }
 120 
 121         ether_setup(dev); /* should this be called here? */
 122         
 123         if (new_device) {
 124                 /* Append the device to the device queue. */
 125                 struct device **old_devp = &dev_base;
 126                 while ((*old_devp)->next)
 127                         old_devp = & (*old_devp)->next;
 128                 (*old_devp)->next = dev;
 129                 dev->next = 0;
 130         }
 131         return dev;
 132 }
 133 
 134 void ether_setup(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 135 {
 136         int i;
 137         /* Fill in the fields of the device structure with ethernet-generic values.
 138            This should be in a common file instead of per-driver.  */
 139         for (i = 0; i < DEV_NUMBUFFS; i++)
 140                 skb_queue_head_init(&dev->buffs[i]);
 141 
 142         /* register boot-defined "eth" devices */
 143         if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
 144                 i = simple_strtoul(dev->name + 3, NULL, 0);
 145                 if (ethdev_index[i] == NULL) {
 146                         ethdev_index[i] = dev;
 147                 }
 148                 else if (dev != ethdev_index[i]) {
 149                         /* Really shouldn't happen! */
 150                         printk("ether_setup: Ouch! Someone else took %s\n",
 151                                 dev->name);
 152                 }
 153         }
 154 
 155         dev->hard_header        = eth_header;
 156         dev->rebuild_header = eth_rebuild_header;
 157         dev->type_trans = eth_type_trans;
 158 
 159         dev->type               = ARPHRD_ETHER;
 160         dev->hard_header_len = ETH_HLEN;
 161         dev->mtu                = 1500; /* eth_mtu */
 162         dev->addr_len   = ETH_ALEN;
 163         for (i = 0; i < ETH_ALEN; i++) {
 164                 dev->broadcast[i]=0xff;
 165         }
 166 
 167         /* New-style flags. */
 168         dev->flags              = IFF_BROADCAST;
 169         dev->family             = AF_INET;
 170         dev->pa_addr    = 0;
 171         dev->pa_brdaddr = 0;
 172         dev->pa_mask    = 0;
 173         dev->pa_alen    = sizeof(unsigned long);
 174 }
 175 
 176 int ether_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         if (map->mem_start != (u_long)(-1))
 179                 dev->mem_start = map->mem_start;
 180         if (map->mem_end != (u_long)(-1))
 181                 dev->mem_end = map->mem_end;
 182         if (map->base_addr != (u_short)(-1))
 183                 dev->base_addr = map->base_addr;
 184         if (map->irq != (u_char)(-1))
 185                 dev->irq = map->irq;
 186         if (map->dma != (u_char)(-1))
 187                 dev->dma = map->dma;
 188         if (map->port != (u_char)(-1))
 189                 dev->if_port = map->port;
 190         return 0;
 191 }
 192 
 193 int register_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195         struct device *d = dev_base;
 196         unsigned long flags;
 197         int i;
 198 
 199         save_flags(flags);
 200         cli();
 201 
 202         if (dev && dev->init) {
 203                 if (dev->init(dev) != 0) {
 204                         restore_flags(flags);
 205                         return -EIO;
 206                 }
 207 
 208                 if (dev->name &&
 209                         ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 210                         for (i = 0; i < MAX_ETH_CARDS; ++i)
 211                                 if (ethdev_index[i] == NULL) {
 212                                         sprintf(dev->name, "eth%d", i);
 213                                         printk("device '%s' loaded\n", dev->name);
 214                                         ethdev_index[i] = dev;
 215                                         break;
 216                                 }
 217                 }
 218 
 219                 /* Add device to end of chain */
 220                 if (dev_base) {
 221                         while (d->next)
 222                                 d = d->next;
 223                         d->next = dev;
 224                 }
 225                 else
 226                         dev_base = dev;
 227                 dev->next = NULL;
 228         }
 229         restore_flags(flags);
 230         return 0;
 231 }
 232 
 233 void unregister_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235         struct device *d = dev_base;
 236         unsigned long flags;
 237         int i;
 238 
 239         save_flags(flags);
 240         cli();
 241 
 242         printk("unregister_netdev: device ");
 243 
 244         if (dev == NULL) {
 245                 printk("was NULL\n");
 246                 restore_flags(flags);
 247                 return;
 248         }
 249         /* else */
 250         if (dev->start)
 251                 printk("'%s' busy\n", dev->name);
 252         else {
 253                 if (dev_base == dev)
 254                         dev_base = dev->next;
 255                 else {
 256                         while (d && (d->next != dev))
 257                                 d = d->next;
 258 
 259                         if (d && (d->next == dev)) {
 260                                 d->next = dev->next;
 261                                 printk("'%s' unlinked\n", dev->name);
 262                         }
 263                         else {
 264                                 printk("'%s' not found\n", dev->name);
 265                                 restore_flags(flags);
 266                                 return;
 267                         }
 268                 }
 269                 for (i = 0; i < MAX_ETH_CARDS; ++i) {
 270                         if (ethdev_index[i] == dev) {
 271                                 ethdev_index[i] = NULL;
 272                                 break;
 273                         }
 274                 }
 275         }
 276         restore_flags(flags);
 277 }
 278 
 279 
 280 
 281 /*
 282  * Local variables:
 283  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
 284  *  version-control: t
 285  *  kept-new-versions: 5
 286  *  tab-width: 4
 287  * End:
 288  */

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