Import 2.1.62
[davej-history.git] / drivers / net / net_init.c
blobae57553a3b6a1cfd4ca8d61d716863b31465b3bd
1 /* netdrv_init.c: Initialization for network devices. */
2 /*
3 Written 1993,1994,1995 by Donald Becker.
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
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.
15 Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
16 ethdev_index[MAX_ETH_CARDS]
17 register_netdev() / unregister_netdev()
19 Modifications by Wolfgang Walter
20 Use dev_close cleanly so we always shut things down tidily.
22 Changed 29/10/95, Alan Cox to pass sockaddr's around for mac addresses.
24 14/06/96 - Paul Gortmaker: Add generic eth_change_mtu() function.
25 24/09/96 - Paul Norton: Add token-ring variants of the netdev functions.
28 #include <linux/config.h>
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/types.h>
32 #include <linux/fs.h>
33 #include <linux/malloc.h>
34 #include <linux/if_ether.h>
35 #include <linux/string.h>
36 #include <linux/netdevice.h>
37 #include <linux/etherdevice.h>
38 #include <linux/trdevice.h>
39 #include <linux/if_arp.h>
40 #include <linux/fddidevice.h>
41 #include <linux/net_alias.h>
42 #include <linux/if_ltalk.h>
44 /* The network devices currently exist only in the socket namespace, so these
45 entries are unused. The only ones that make sense are
46 open start the ethercard
47 close stop the ethercard
48 ioctl To get statistics, perhaps set the interface port (AUI, BNC, etc.)
49 One can also imagine getting raw packets using
50 read & write
51 but this is probably better handled by a raw packet socket.
53 Given that almost all of these functions are handled in the current
54 socket-based scheme, putting ethercard devices in /dev/ seems pointless.
56 [Removed all support for /dev network devices. When someone adds
57 streams then by magic we get them, but otherwise they are un-needed
58 and a space waste]
61 /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
62 #define MAX_ETH_CARDS 16
63 static struct device *ethdev_index[MAX_ETH_CARDS];
66 /* Fill in the fields of the device structure with ethernet-generic values.
68 If no device structure is passed, a new one is constructed, complete with
69 a SIZEOF_PRIVATE private data area.
71 If an empty string area is passed as dev->name, or a new structure is made,
72 a new name string is constructed. The passed string area should be 8 bytes
73 long.
76 struct device *
77 init_etherdev(struct device *dev,int sizeof_priv)
79 int new_device =0;
80 int i;
82 /* Use an existing correctly named device in Space.c:dev_base. */
83 if(dev == NULL) {
84 int alloc_size =sizeof(struct device) +sizeof("eth%d ")
85 + sizeof_priv +3;
86 struct device *cur_dev;
87 char pname[8];/* Putative name for the device. */
89 for(i =0; i < MAX_ETH_CARDS; ++i)
90 if(ethdev_index[i] == NULL) {
91 sprintf(pname,"eth%d", i);
92 for(cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
93 if(strcmp(pname, cur_dev->name) ==0) {
94 dev = cur_dev;
95 dev->init = NULL;
96 sizeof_priv = (sizeof_priv +3) & ~3;
97 dev->priv = sizeof_priv
98 ?kmalloc(sizeof_priv, GFP_KERNEL)
99 : NULL;
100 if(dev->priv)memset(dev->priv,0, sizeof_priv);
101 goto found;
105 alloc_size &= ~3;/* Round to dword boundary. */
107 dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
108 memset(dev,0, alloc_size);
109 if(sizeof_priv)
110 dev->priv = (void*) (dev +1);
111 dev->name = sizeof_priv + (char*)(dev +1);
112 new_device =1;
115 found:/* From the double loop above. */
117 if(dev->name &&
118 ((dev->name[0] =='\0') || (dev->name[0] ==' '))) {
119 for(i =0; i < MAX_ETH_CARDS; ++i)
120 if(ethdev_index[i] == NULL) {
121 sprintf(dev->name,"eth%d", i);
122 ethdev_index[i] = dev;
123 break;
127 ether_setup(dev);/* Hmmm, should this be called here? */
129 if(new_device) {
130 /* Append the device to the device queue. */
131 struct device **old_devp = &dev_base;
132 while((*old_devp)->next)
133 old_devp = & (*old_devp)->next;
134 (*old_devp)->next = dev;
135 dev->next =0;
137 return dev;
141 static inteth_mac_addr(struct device *dev,void*p)
143 struct sockaddr *addr=p;
144 if(dev->start)
145 return-EBUSY;
146 memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
147 return0;
150 static inteth_change_mtu(struct device *dev,int new_mtu)
152 if((new_mtu <68) || (new_mtu >1500))
153 return-EINVAL;
154 dev->mtu = new_mtu;
155 return0;
158 #ifdef CONFIG_FDDI
160 static intfddi_change_mtu(struct device *dev,int new_mtu)
162 if((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN))
163 return(-EINVAL);
164 dev->mtu = new_mtu;
165 return(0);
168 #endif
171 voidether_setup(struct device *dev)
173 int i;
174 /* Fill in the fields of the device structure with ethernet-generic values.
175 This should be in a common file instead of per-driver. */
177 dev_init_buffers(dev);
179 /* register boot-defined "eth" devices */
180 if(dev->name && (strncmp(dev->name,"eth",3) ==0)) {
181 i =simple_strtoul(dev->name +3, NULL,0);
182 if(ethdev_index[i] == NULL) {
183 ethdev_index[i] = dev;
185 else if(dev != ethdev_index[i]) {
186 /* Really shouldn't happen! */
187 printk("ether_setup: Ouch! Someone else took %s\n",
188 dev->name);
192 dev->change_mtu = eth_change_mtu;
193 dev->hard_header = eth_header;
194 dev->rebuild_header = eth_rebuild_header;
195 dev->set_mac_address = eth_mac_addr;
196 dev->hard_header_cache = eth_header_cache;
197 dev->header_cache_update= eth_header_cache_update;
199 dev->type = ARPHRD_ETHER;
200 dev->hard_header_len = ETH_HLEN;
201 dev->mtu =1500;/* eth_mtu */
202 dev->addr_len = ETH_ALEN;
203 dev->tx_queue_len =100;/* Ethernet wants good queues */
205 memset(dev->broadcast,0xFF, ETH_ALEN);
207 /* New-style flags. */
208 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
209 dev->family = AF_INET;
210 dev->pa_addr =0;
211 dev->pa_brdaddr =0;
212 dev->pa_mask =0;
213 dev->pa_alen =4;
216 #ifdef CONFIG_FDDI
218 voidfddi_setup(struct device *dev)
221 * Fill in the fields of the device structure with FDDI-generic values.
222 * This should be in a common file instead of per-driver.
225 dev_init_buffers(dev);
227 dev->change_mtu = fddi_change_mtu;
228 dev->hard_header = fddi_header;
229 dev->rebuild_header = fddi_rebuild_header;
231 dev->type = ARPHRD_FDDI;
232 dev->hard_header_len = FDDI_K_SNAP_HLEN+3;/* Assume 802.2 SNAP hdr len + 3 pad bytes */
233 dev->mtu = FDDI_K_SNAP_DLEN;/* Assume max payload of 802.2 SNAP frame */
234 dev->addr_len = FDDI_K_ALEN;
235 dev->tx_queue_len =100;/* Long queues on FDDI */
237 memset(dev->broadcast,0xFF, FDDI_K_ALEN);
239 /* New-style flags */
240 dev->flags = IFF_BROADCAST | IFF_MULTICAST;
241 dev->family = AF_INET;
242 dev->pa_addr =0;
243 dev->pa_brdaddr =0;
244 dev->pa_mask =0;
245 dev->pa_alen =4;
246 return;
249 #endif
251 #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
253 static intltalk_change_mtu(struct device *dev,int mtu)
255 return-EINVAL;
258 static intltalk_mac_addr(struct device *dev,void*addr)
260 return-EINVAL;
264 voidltalk_setup(struct device *dev)
266 /* Fill in the fields of the device structure with localtalk-generic values. */
268 dev_init_buffers(dev);
270 dev->change_mtu = ltalk_change_mtu;
271 dev->hard_header = NULL;
272 dev->rebuild_header = NULL;
273 dev->set_mac_address = ltalk_mac_addr;
274 dev->hard_header_cache = NULL;
275 dev->header_cache_update= NULL;
277 dev->type = ARPHRD_LOCALTLK;
278 dev->hard_header_len = LTALK_HLEN;
279 dev->mtu = LTALK_MTU;
280 dev->addr_len = LTALK_ALEN;
281 dev->tx_queue_len =10;
283 dev->broadcast[0] =0xFF;
285 dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
286 dev->family = AF_APPLETALK;
287 dev->pa_addr =0;
288 dev->pa_brdaddr =0;
289 dev->pa_mask =0;
290 dev->pa_alen =1;
293 #endif
295 intether_config(struct device *dev,struct ifmap *map)
297 if(map->mem_start != (u_long)(-1))
298 dev->mem_start = map->mem_start;
299 if(map->mem_end != (u_long)(-1))
300 dev->mem_end = map->mem_end;
301 if(map->base_addr != (u_short)(-1))
302 dev->base_addr = map->base_addr;
303 if(map->irq != (u_char)(-1))
304 dev->irq = map->irq;
305 if(map->dma != (u_char)(-1))
306 dev->dma = map->dma;
307 if(map->port != (u_char)(-1))
308 dev->if_port = map->port;
309 return0;
312 intregister_netdev(struct device *dev)
314 struct device *d = dev_base;
315 unsigned long flags;
316 int i=MAX_ETH_CARDS;
318 save_flags(flags);
319 cli();
321 if(dev) {
322 if(dev->name &&
323 ((dev->name[0] =='\0') || (dev->name[0] ==' '))) {
324 for(i =0; i < MAX_ETH_CARDS; ++i)
325 if(ethdev_index[i] == NULL) {
326 sprintf(dev->name,"eth%d", i);
327 printk("loading device '%s'...\n", dev->name);
328 ethdev_index[i] = dev;
329 break;
333 if(dev->init) {
334 sti();/* device probes assume interrupts enabled */
335 if(dev->init(dev) !=0) {
336 if(i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
337 restore_flags(flags);
338 return-EIO;
340 cli();
343 /* Add device to end of chain */
344 if(dev_base) {
345 while(d->next)
346 d = d->next;
347 d->next = dev;
349 else
350 dev_base = dev;
351 dev->next = NULL;
352 dev->ifindex =dev_new_index();
354 restore_flags(flags);
355 return0;
358 voidunregister_netdev(struct device *dev)
360 struct device *d = dev_base;
361 unsigned long flags;
362 int i;
364 save_flags(flags);
365 cli();
367 if(dev == NULL)
369 printk("was NULL\n");
370 restore_flags(flags);
371 return;
373 /* else */
374 if(dev->start)
375 printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
378 * must jump over main_device+aliases
379 * avoid alias devices unregistration so that only
380 * net_alias module manages them
382 #ifdef CONFIG_NET_ALIAS
383 if(dev_base == dev)
384 dev_base =net_alias_nextdev(dev);
385 else
387 while(d && (net_alias_nextdev(d) != dev))/* skip aliases */
388 d =net_alias_nextdev(d);
390 if(d && (net_alias_nextdev(d) == dev))
393 * Critical: Bypass by consider devices as blocks (maindev+aliases)
395 net_alias_nextdev_set(d,net_alias_nextdev(dev));
397 #else
398 if(dev_base == dev)
399 dev_base = dev->next;
400 else
402 while(d && (d->next != dev))
403 d = d->next;
405 if(d && (d->next == dev))
407 d->next = dev->next;
409 #endif
410 else
412 printk("unregister_netdev: '%s' not found\n", dev->name);
413 restore_flags(flags);
414 return;
417 for(i =0; i < MAX_ETH_CARDS; ++i)
419 if(ethdev_index[i] == dev)
421 ethdev_index[i] = NULL;
422 break;
426 restore_flags(flags);
429 * You can i.e use a interfaces in a route though it is not up.
430 * We call close_dev (which is changed: it will down a device even if
431 * dev->flags==0 (but it will not call dev->stop if IFF_UP
432 * is not set).
433 * This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
434 * dev_mc_discard(dev), ....
437 dev_close(dev);
440 #ifdef CONFIG_TR
441 /* The list of used and available "tr" slots */
442 #define MAX_TR_CARDS 16
443 static struct device *trdev_index[MAX_TR_CARDS];
445 struct device *init_trdev(struct device *dev,int sizeof_priv)
447 int new_device =0;
448 int i;
450 /* Use an existing correctly named device in Space.c:dev_base. */
451 if(dev == NULL) {
452 int alloc_size =sizeof(struct device) +sizeof("tr%d ")
453 + sizeof_priv +3;
454 struct device *cur_dev;
455 char pname[8];/* Putative name for the device. */
457 for(i =0; i < MAX_TR_CARDS; ++i)
458 if(trdev_index[i] == NULL) {
459 sprintf(pname,"tr%d", i);
460 for(cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
461 if(strcmp(pname, cur_dev->name) ==0) {
462 dev = cur_dev;
463 dev->init = NULL;
464 sizeof_priv = (sizeof_priv +3) & ~3;
465 dev->priv = sizeof_priv
466 ?kmalloc(sizeof_priv, GFP_KERNEL)
467 : NULL;
468 if(dev->priv)memset(dev->priv,0, sizeof_priv);
469 goto trfound;
473 alloc_size &= ~3;/* Round to dword boundary. */
474 dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
475 memset(dev,0, alloc_size);
476 if(sizeof_priv)
477 dev->priv = (void*) (dev +1);
478 dev->name = sizeof_priv + (char*)(dev +1);
479 new_device =1;
482 trfound:/* From the double loop above. */
484 for(i =0; i < MAX_TR_CARDS; ++i)
485 if(trdev_index[i] == NULL) {
486 sprintf(dev->name,"tr%d", i);
487 trdev_index[i] = dev;
488 break;
491 if(new_device) {
492 /* Append the device to the device queue. */
493 struct device **old_devp = &dev_base;
495 while((*old_devp)->next)
496 old_devp = & (*old_devp)->next;
497 (*old_devp)->next = dev;
498 dev->next =0;
501 dev->hard_header = tr_header;
502 dev->rebuild_header = tr_rebuild_header;
504 dev->type = ARPHRD_IEEE802;
505 dev->hard_header_len = TR_HLEN;
506 dev->mtu =2000;/* bug in fragmenter...*/
507 dev->addr_len = TR_ALEN;
508 dev->tx_queue_len =100;/* Long queues on tr */
510 memset(dev->broadcast,0xFF, TR_ALEN);
512 /* New-style flags. */
513 dev->flags = IFF_BROADCAST;
514 dev->family = AF_INET;
515 dev->pa_addr =0;
516 dev->pa_brdaddr =0;
517 dev->pa_mask =0;
518 dev->pa_alen =4;
520 return dev;
523 voidtr_setup(struct device *dev)
525 int i;
527 /* register boot-defined "tr" devices */
528 if(dev->name && (strncmp(dev->name,"tr",2) ==0)) {
529 i =simple_strtoul(dev->name +2, NULL,0);
530 if(trdev_index[i] == NULL) {
531 trdev_index[i] = dev;
533 else if(dev != trdev_index[i]) {
534 /* Really shouldn't happen! */
535 printk("tr_setup: Ouch! Someone else took %s\n",
536 dev->name);
541 voidtr_freedev(struct device *dev)
543 int i;
544 for(i =0; i < MAX_TR_CARDS; ++i)
546 if(trdev_index[i] == dev)
548 trdev_index[i] = NULL;
549 break;
554 intregister_trdev(struct device *dev)
556 unsigned long flags;
558 dev_init_buffers(dev);
560 save_flags(flags);
562 if(dev && dev->init) {
563 sti();/* device probes assume interrupts enabled */
564 if(dev->init(dev) !=0) {
565 unregister_trdev(dev);
566 restore_flags(flags);
567 return-EIO;
569 cli();
572 restore_flags(flags);
573 return0;
576 voidunregister_trdev(struct device *dev)
578 struct device *d = dev_base;
579 unsigned long flags;
581 save_flags(flags);
582 cli();
584 if(dev == NULL)
586 printk("was NULL\n");
587 restore_flags(flags);
588 return;
590 /* else */
591 if(dev->start)
592 printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
595 * must jump over main_device+aliases
596 * avoid alias devices unregistration so that only
597 * net_alias module manages them
599 #ifdef CONFIG_NET_ALIAS
600 if(dev_base == dev)
601 dev_base =net_alias_nextdev(dev);
602 else
604 while(d && (net_alias_nextdev(d) != dev))/* skip aliases */
605 d =net_alias_nextdev(d);
607 if(d && (net_alias_nextdev(d) == dev))
610 * Critical: Bypass by consider devices as blocks (maindev+aliases)
612 net_alias_nextdev_set(d,net_alias_nextdev(dev));
614 #else
615 if(dev_base == dev)
616 dev_base = dev->next;
617 else
619 while(d && (d->next != dev))
620 d = d->next;
622 if(d && (d->next == dev))
624 d->next = dev->next;
626 #endif
627 else
629 printk("unregister_trdev: '%s' not found\n", dev->name);
630 restore_flags(flags);
631 return;
635 tr_freedev(dev);
637 restore_flags(flags);
640 * You can i.e use a interfaces in a route though it is not up.
641 * We call close_dev (which is changed: it will down a device even if
642 * dev->flags==0 (but it will not call dev->stop if IFF_UP
643 * is not set).
644 * This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
645 * dev_mc_discard(dev), ....
648 dev_close(dev);
650 #endif
654 * Local variables:
655 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
656 * version-control: t
657 * kept-new-versions: 5
658 * tab-width: 4
659 * End:
close