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

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