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. eth_mac_addr
  4. ether_setup
  5. tr_setup
  6. ether_config
  7. register_netdev
  8. 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/if_arp.h>
  28 #include <linux/string.h>
  29 #include <linux/netdevice.h>
  30 #include <linux/etherdevice.h>
  31 #include <linux/trdevice.h>
  32 
  33 /* The network devices currently exist only in the socket namespace, so these
  34    entries are unused.  The only ones that make sense are
  35     open        start the ethercard
  36     close       stop  the ethercard
  37     ioctl       To get statistics, perhaps set the interface port (AUI, BNC, etc.)
  38    One can also imagine getting raw packets using
  39     read & write
  40    but this is probably better handled by a raw packet socket.
  41 
  42    Given that almost all of these functions are handled in the current
  43    socket-based scheme, putting ethercard devices in /dev/ seems pointless.
  44    
  45    [Removed all support for /dev network devices. When someone adds
  46     streams then by magic we get them, but otherwise they are un-needed
  47         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 unsigned long dec21040_init(unsigned long mem_start, unsigned long mem_end);
  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         /* Network device initialization for devices that must allocate
  69            low-memory or contiguous DMA buffers.
  70            */
  71 #if defined(CONFIG_LANCE)
  72         mem_start = lance_init(mem_start, mem_end);
  73 #endif
  74 #if defined(CONFIG_PI)
  75         mem_start = pi_init(mem_start, mem_end);
  76 #endif  
  77 #if defined(CONFIG_DEC_ELCP)
  78         mem_start = dec21040_init(mem_start, mem_end);
  79 #endif  
  80         return mem_start;
  81 }
  82 
  83 /* Fill in the fields of the device structure with ethernet-generic values.
  84 
  85    If no device structure is passed, a new one is constructed, complete with
  86    a SIZEOF_PRIVATE private data area.
  87 
  88    If an empty string area is passed as dev->name, or a new structure is made,
  89    a new name string is constructed.  The passed string area should be 8 bytes
  90    long.
  91  */
  92 
  93 struct device *
  94 init_etherdev(struct device *dev, int sizeof_priv, unsigned long *mem_startp)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         int new_device = 0;
  97         int i;
  98 
  99         /* Use an existing correctly named device in Space.c:dev_base. */
 100         if (dev == NULL) {
 101                 int alloc_size = sizeof(struct device) + sizeof("eth%d  ")
 102                         + sizeof_priv + 3;
 103                 struct device *cur_dev;
 104                 char pname[8];          /* Putative name for the device.  */
 105 
 106                 for (i = 0; i < MAX_ETH_CARDS; ++i)
 107                         if (ethdev_index[i] == NULL) {
 108                                 sprintf(pname, "eth%d", i);
 109                                 for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
 110                                         if (strcmp(pname, cur_dev->name) == 0) {
 111                                                 dev = cur_dev;
 112                                                 dev->init = NULL;
 113                                                 sizeof_priv = (sizeof_priv + 3) & ~3;
 114                                                 if (mem_startp && *mem_startp ) {
 115                                                         dev->priv = (void*) *mem_startp;
 116                                                         *mem_startp += sizeof_priv;
 117                                                 } else
 118                                                         dev->priv = sizeof_priv
 119                                                           ? kmalloc(sizeof_priv, GFP_KERNEL)
 120                                                           :     NULL;
 121                                                 if (dev->priv) memset(dev->priv, 0, sizeof_priv);
 122                                                 goto found;
 123                                         }
 124                         }
 125 
 126                 alloc_size &= ~3;               /* Round to dword boundary. */
 127 
 128                 if (mem_startp && *mem_startp ) {
 129                         dev = (struct device *)*mem_startp;
 130                         *mem_startp += alloc_size;
 131                 } else
 132                         dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
 133                 memset(dev, 0, alloc_size);
 134                 if (sizeof_priv)
 135                         dev->priv = (void *) (dev + 1);
 136                 dev->name = sizeof_priv + (char *)(dev + 1);
 137                 new_device = 1;
 138         }
 139 
 140         found:                                          /* From the double loop above. */
 141 
 142         if (dev->name &&
 143                 ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 144                 for (i = 0; i < MAX_ETH_CARDS; ++i)
 145                         if (ethdev_index[i] == NULL) {
 146                                 sprintf(dev->name, "eth%d", i);
 147                                 ethdev_index[i] = dev;
 148                                 break;
 149                         }
 150         }
 151 
 152         ether_setup(dev);       /* Hmmm, should this be called here? */
 153         
 154         if (new_device) {
 155                 /* Append the device to the device queue. */
 156                 struct device **old_devp = &dev_base;
 157                 while ((*old_devp)->next)
 158                         old_devp = & (*old_devp)->next;
 159                 (*old_devp)->next = dev;
 160                 dev->next = 0;
 161         }
 162         return dev;
 163 }
 164 
 165 
 166 static int eth_mac_addr(struct device *dev, void * addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168         struct ifreq * ifr = (struct ifreq *) addr;
 169 
 170         if(dev->start)
 171                 return -EBUSY;
 172         memcpy(dev->dev_addr, ifr->ifr_hwaddr.sa_data,dev->hard_header_len);
 173         return 0;
 174 }
 175 
 176 void ether_setup(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         int i;
 179         /* Fill in the fields of the device structure with ethernet-generic values.
 180            This should be in a common file instead of per-driver.  */
 181         for (i = 0; i < DEV_NUMBUFFS; i++)
 182                 skb_queue_head_init(&dev->buffs[i]);
 183 
 184         /* register boot-defined "eth" devices */
 185         if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
 186                 i = simple_strtoul(dev->name + 3, NULL, 0);
 187                 if (ethdev_index[i] == NULL) {
 188                         ethdev_index[i] = dev;
 189                 }
 190                 else if (dev != ethdev_index[i]) {
 191                         /* Really shouldn't happen! */
 192                         printk("ether_setup: Ouch! Someone else took %s\n",
 193                                 dev->name);
 194                 }
 195         }
 196 
 197         dev->hard_header        = eth_header;
 198         dev->rebuild_header = eth_rebuild_header;
 199         dev->set_mac_address = eth_mac_addr;
 200         dev->header_cache = eth_header_cache;
 201 
 202         dev->type               = ARPHRD_ETHER;
 203         dev->hard_header_len = ETH_HLEN;
 204         dev->mtu                = 1500; /* eth_mtu */
 205         dev->addr_len   = ETH_ALEN;
 206         for (i = 0; i < ETH_ALEN; i++) {
 207                 dev->broadcast[i]=0xff;
 208         }
 209 
 210         /* New-style flags. */
 211         dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
 212         dev->family             = AF_INET;
 213         dev->pa_addr    = 0;
 214         dev->pa_brdaddr = 0;
 215         dev->pa_mask    = 0;
 216         dev->pa_alen    = 4;
 217 }
 218 
 219 #ifdef CONFIG_TR
 220 
 221 void tr_setup(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223         int i;
 224         /* Fill in the fields of the device structure with ethernet-generic values.
 225            This should be in a common file instead of per-driver.  */
 226         for (i = 0; i < DEV_NUMBUFFS; i++)
 227                 skb_queue_head_init(&dev->buffs[i]);
 228 
 229         dev->hard_header        = tr_header;
 230         dev->rebuild_header = tr_rebuild_header;
 231 
 232         dev->type               = ARPHRD_IEEE802;
 233         dev->hard_header_len = TR_HLEN;
 234         dev->mtu                = 2000; /* bug in fragmenter...*/
 235         dev->addr_len   = TR_ALEN;
 236         for (i = 0; i < TR_ALEN; i++) {
 237                 dev->broadcast[i]=0xff;
 238         }
 239 
 240         /* New-style flags. */
 241         dev->flags              = IFF_BROADCAST;
 242         dev->family             = AF_INET;
 243         dev->pa_addr    = 0;
 244         dev->pa_brdaddr = 0;
 245         dev->pa_mask    = 0;
 246         dev->pa_alen    = 4;
 247 }
 248 
 249 #endif
 250 
 251 int ether_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
 252 {
 253         if (map->mem_start != (u_long)(-1))
 254                 dev->mem_start = map->mem_start;
 255         if (map->mem_end != (u_long)(-1))
 256                 dev->mem_end = map->mem_end;
 257         if (map->base_addr != (u_short)(-1))
 258                 dev->base_addr = map->base_addr;
 259         if (map->irq != (u_char)(-1))
 260                 dev->irq = map->irq;
 261         if (map->dma != (u_char)(-1))
 262                 dev->dma = map->dma;
 263         if (map->port != (u_char)(-1))
 264                 dev->if_port = map->port;
 265         return 0;
 266 }
 267 
 268 int register_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270         struct device *d = dev_base;
 271         unsigned long flags;
 272         int i=MAX_ETH_CARDS;
 273 
 274         save_flags(flags);
 275         cli();
 276 
 277         if (dev && dev->init) {
 278                 if (dev->name &&
 279                         ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
 280                         for (i = 0; i < MAX_ETH_CARDS; ++i)
 281                                 if (ethdev_index[i] == NULL) {
 282                                         sprintf(dev->name, "eth%d", i);
 283                                         printk("loading device '%s'...\n", dev->name);
 284                                         ethdev_index[i] = dev;
 285                                         break;
 286                                 }
 287                 }
 288 
 289                 if (dev->init(dev) != 0) {
 290                     if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
 291                         restore_flags(flags);
 292                         return -EIO;
 293                 }
 294 
 295                 /* Add device to end of chain */
 296                 if (dev_base) {
 297                         while (d->next)
 298                                 d = d->next;
 299                         d->next = dev;
 300                 }
 301                 else
 302                         dev_base = dev;
 303                 dev->next = NULL;
 304         }
 305         restore_flags(flags);
 306         return 0;
 307 }
 308 
 309 void unregister_netdev(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311         struct device *d = dev_base;
 312         unsigned long flags;
 313         int i;
 314 
 315         save_flags(flags);
 316         cli();
 317 
 318         if (dev == NULL) 
 319         {
 320                 printk("was NULL\n");
 321                 restore_flags(flags);
 322                 return;
 323         }
 324         /* else */
 325         if (dev->start)
 326                 printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
 327         if (dev_base == dev)
 328                 dev_base = dev->next;
 329         else 
 330         {
 331                 while (d && (d->next != dev))
 332                         d = d->next;
 333                         
 334                 if (d && (d->next == dev)) 
 335                 {
 336                         d->next = dev->next;
 337                 }
 338                 else 
 339                 {
 340                         printk("unregister_netdev: '%s' not found\n", dev->name);
 341                         restore_flags(flags);
 342                         return;
 343                 }
 344                 for (i = 0; i < MAX_ETH_CARDS; ++i) 
 345                 {
 346                         if (ethdev_index[i] == dev) 
 347                         {
 348                                 ethdev_index[i] = NULL;
 349                                 break;
 350                         }
 351                 }
 352         }
 353         restore_flags(flags);
 354 }
 355 
 356 
 357 
 358 /*
 359  * Local variables:
 360  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
 361  *  version-control: t
 362  *  kept-new-versions: 5
 363  *  tab-width: 4
 364  * End:
 365  */

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