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 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 streams then
  44     by magic we get them, but otherwise they are un-needed and a space waste]
  45 */
  46 
  47 /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
  48 #define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
  49 static struct device *ethdev_index[MAX_ETH_CARDS];
  50 
  51 unsigned long lance_init(unsigned long mem_start, unsigned long mem_end);
  52 unsigned long pi_init(unsigned long mem_start, unsigned long mem_end);
  53 unsigned long apricot_init(unsigned long mem_start, unsigned long mem_end);
  54 
  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 #if defined(CONFIG_APRICOT)
  72         mem_start = apricot_init(mem_start, mem_end);
  73 #endif  
  74         return mem_start;
  75 }
  76 
  77 /* Fill in the fields of the device structure with ethernet-generic values.
  78 
  79    If no device structure is passed, a new one is constructed, complete with
  80    a SIZEOF_PRIVATE private data area.
  81 
  82    If an empty string area is passed as dev->name, or a new structure is made,
  83    a new name string is constructed.  The passed string area should be 8 bytes
  84    long.
  85  */
  86 
  87 struct device *
  88 init_etherdev(struct device *dev, int sizeof_private, unsigned long *mem_startp)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90         int new_device = 0;
  91         int i;
  92 
  93         if (dev == NULL) {
  94                 int alloc_size = sizeof(struct device) + sizeof("eth%d  ")
  95                         + sizeof_private + 3;
  96 
  97                 alloc_size &= ~3;               /* Round to dword boundary. */
  98 
  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, alloc_size);
 105                 if (sizeof_private)
 106                         dev->priv = (void *) (dev + 1);
 107                 dev->name = sizeof_private + (char *)(dev + 1);
 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|IFF_MULTICAST;
 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=MAX_ETH_CARDS;
 198 
 199         save_flags(flags);
 200         cli();
 201 
 202         if (dev && dev->init) {
 203                 if (dev->name &&
 204                         ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 205                         for (i = 0; i < MAX_ETH_CARDS; ++i)
 206                                 if (ethdev_index[i] == NULL) {
 207                                         sprintf(dev->name, "eth%d", i);
 208                                         printk("loading device '%s'...\n", dev->name);
 209                                         ethdev_index[i] = dev;
 210                                         break;
 211                                 }
 212                 }
 213 
 214                 if (dev->init(dev) != 0) {
 215                     if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
 216                         restore_flags(flags);
 217                         return -EIO;
 218                 }
 219 
 220                 /* Add device to end of chain */
 221                 if (dev_base) {
 222                         while (d->next)
 223                                 d = d->next;
 224                         d->next = dev;
 225                 }
 226                 else
 227                         dev_base = dev;
 228                 dev->next = NULL;
 229         }
 230         restore_flags(flags);
 231         return 0;
 232 }
 233 
 234 void unregister_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 235 {
 236         struct device *d = dev_base;
 237         unsigned long flags;
 238         int i;
 239 
 240         save_flags(flags);
 241         cli();
 242 
 243         printk("unregister_netdev: device ");
 244 
 245         if (dev == NULL) {
 246                 printk("was NULL\n");
 247                 restore_flags(flags);
 248                 return;
 249         }
 250         /* else */
 251         if (dev->start)
 252                 printk("'%s' busy\n", dev->name);
 253         else {
 254                 if (dev_base == dev)
 255                         dev_base = dev->next;
 256                 else {
 257                         while (d && (d->next != dev))
 258                                 d = d->next;
 259 
 260                         if (d && (d->next == dev)) {
 261                                 d->next = dev->next;
 262                                 printk("'%s' unlinked\n", dev->name);
 263                         }
 264                         else {
 265                                 printk("'%s' not found\n", dev->name);
 266                                 restore_flags(flags);
 267                                 return;
 268                         }
 269                 }
 270                 for (i = 0; i < MAX_ETH_CARDS; ++i) {
 271                         if (ethdev_index[i] == dev) {
 272                                 ethdev_index[i] = NULL;
 273                                 break;
 274                         }
 275                 }
 276         }
 277         restore_flags(flags);
 278 }
 279 
 280 
 281 
 282 /*
 283  * Local variables:
 284  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
 285  *  version-control: t
 286  *  kept-new-versions: 5
 287  *  tab-width: 4
 288  * End:
 289  */

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