Import 2.1.15
[davej-history.git] / drivers / net / net_init.c
blob322df02d6fddb38cc1d3d1fabd8efa2080e3bbd7
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.
27 #include <linux/config.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/types.h>
31 #include <linux/fs.h>
32 #include <linux/malloc.h>
33 #include <linux/if_ether.h>
34 #include <linux/string.h>
35 #include <linux/netdevice.h>
36 #include <linux/etherdevice.h>
37 #include <linux/trdevice.h>
38 #include <linux/if_arp.h>
39 #include <linux/fddidevice.h>
40 #ifdef CONFIG_NET_ALIAS
41 #include <linux/net_alias.h>
42 #endif
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/* same as the number if irq's in irq2dev[] */
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. */
176 for(i =0; i < DEV_NUMBUFFS; i++)
177 skb_queue_head_init(&dev->buffs[i]);
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_TR
218 voidtr_setup(struct device *dev)
220 int i;
221 /* Fill in the fields of the device structure with ethernet-generic values.
222 This should be in a common file instead of per-driver. */
223 for(i =0; i < DEV_NUMBUFFS; i++)
224 skb_queue_head_init(&dev->buffs[i]);
226 dev->hard_header = tr_header;
227 dev->rebuild_header = tr_rebuild_header;
229 dev->type = ARPHRD_IEEE802;
230 dev->hard_header_len = TR_HLEN;
231 dev->mtu =2000;/* bug in fragmenter...*/
232 dev->addr_len = TR_ALEN;
233 dev->tx_queue_len =100;/* Long queues on tr */
235 memset(dev->broadcast,0xFF, TR_ALEN);
237 /* New-style flags. */
238 dev->flags = IFF_BROADCAST;
239 dev->family = AF_INET;
240 dev->pa_addr =0;
241 dev->pa_brdaddr =0;
242 dev->pa_mask =0;
243 dev->pa_alen =4;
246 #endif
248 #ifdef CONFIG_FDDI
250 voidfddi_setup(struct device *dev)
252 int i;
255 * Fill in the fields of the device structure with FDDI-generic values.
256 * This should be in a common file instead of per-driver.
258 for(i=0; i < DEV_NUMBUFFS; i++)
259 skb_queue_head_init(&dev->buffs[i]);
261 dev->change_mtu = fddi_change_mtu;
262 dev->hard_header = fddi_header;
263 dev->rebuild_header = fddi_rebuild_header;
265 dev->type = ARPHRD_FDDI;
266 dev->hard_header_len = FDDI_K_SNAP_HLEN+3;/* Assume 802.2 SNAP hdr len + 3 pad bytes */
267 dev->mtu = FDDI_K_SNAP_DLEN;/* Assume max payload of 802.2 SNAP frame */
268 dev->addr_len = FDDI_K_ALEN;
269 dev->tx_queue_len =100;/* Long queues on FDDI */
271 memset(dev->broadcast,0xFF, FDDI_K_ALEN);
273 /* New-style flags */
274 dev->flags = IFF_BROADCAST | IFF_MULTICAST;
275 dev->family = AF_INET;
276 dev->pa_addr =0;
277 dev->pa_brdaddr =0;
278 dev->pa_mask =0;
279 dev->pa_alen =4;
280 return;
283 #endif
285 intether_config(struct device *dev,struct ifmap *map)
287 if(map->mem_start != (u_long)(-1))
288 dev->mem_start = map->mem_start;
289 if(map->mem_end != (u_long)(-1))
290 dev->mem_end = map->mem_end;
291 if(map->base_addr != (u_short)(-1))
292 dev->base_addr = map->base_addr;
293 if(map->irq != (u_char)(-1))
294 dev->irq = map->irq;
295 if(map->dma != (u_char)(-1))
296 dev->dma = map->dma;
297 if(map->port != (u_char)(-1))
298 dev->if_port = map->port;
299 return0;
302 intregister_netdev(struct device *dev)
304 struct device *d = dev_base;
305 unsigned long flags;
306 int i=MAX_ETH_CARDS;
308 save_flags(flags);
309 cli();
311 if(dev && dev->init) {
312 if(dev->name &&
313 ((dev->name[0] =='\0') || (dev->name[0] ==' '))) {
314 for(i =0; i < MAX_ETH_CARDS; ++i)
315 if(ethdev_index[i] == NULL) {
316 sprintf(dev->name,"eth%d", i);
317 printk("loading device '%s'...\n", dev->name);
318 ethdev_index[i] = dev;
319 break;
323 sti();/* device probes assume interrupts enabled */
324 if(dev->init(dev) !=0) {
325 if(i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
326 restore_flags(flags);
327 return-EIO;
329 cli();
331 /* Add device to end of chain */
332 if(dev_base) {
333 while(d->next)
334 d = d->next;
335 d->next = dev;
337 else
338 dev_base = dev;
339 dev->next = NULL;
341 restore_flags(flags);
342 return0;
345 voidunregister_netdev(struct device *dev)
347 struct device *d = dev_base;
348 unsigned long flags;
349 int i;
351 save_flags(flags);
352 cli();
354 if(dev == NULL)
356 printk("was NULL\n");
357 restore_flags(flags);
358 return;
360 /* else */
361 if(dev->start)
362 printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
365 * must jump over main_device+aliases
366 * avoid alias devices unregistration so that only
367 * net_alias module manages them
369 #ifdef CONFIG_NET_ALIAS
370 if(dev_base == dev)
371 dev_base =net_alias_nextdev(dev);
372 else
374 while(d && (net_alias_nextdev(d) != dev))/* skip aliases */
375 d =net_alias_nextdev(d);
377 if(d && (net_alias_nextdev(d) == dev))
380 * Critical: Bypass by consider devices as blocks (maindev+aliases)
382 net_alias_nextdev_set(d,net_alias_nextdev(dev));
384 #else
385 if(dev_base == dev)
386 dev_base = dev->next;
387 else
389 while(d && (d->next != dev))
390 d = d->next;
392 if(d && (d->next == dev))
394 d->next = dev->next;
396 #endif
397 else
399 printk("unregister_netdev: '%s' not found\n", dev->name);
400 restore_flags(flags);
401 return;
404 for(i =0; i < MAX_ETH_CARDS; ++i)
406 if(ethdev_index[i] == dev)
408 ethdev_index[i] = NULL;
409 break;
413 restore_flags(flags);
416 * You can i.e use a interfaces in a route though it is not up.
417 * We call close_dev (which is changed: it will down a device even if
418 * dev->flags==0 (but it will not call dev->stop if IFF_UP
419 * is not set).
420 * This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
421 * dev_mc_discard(dev), ....
424 dev_close(dev);
429 * Local variables:
430 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
431 * version-control: t
432 * kept-new-versions: 5
433 * tab-width: 4
434 * End:
close