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

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