~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/net_init.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* net_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         Modifications by Wolfgang Walter
 20                 Use dev_close cleanly so we always shut things down tidily.
 21                 
 22         Changed 29/10/95, Alan Cox to pass sockaddr's around for mac addresses.
 23         
 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. 
 26         
 27         08/11/99 - Alan Cox: Got fed up of the mess in this file and cleaned it
 28                         up. We now share common code and have regularised name
 29                         allocation setups. Abolished the 16 card limits.
 30         03/19/2000 - jgarzik and Urban Widmark: init_etherdev 32-byte align
 31 
 32 */
 33 
 34 #include <linux/config.h>
 35 #include <linux/kernel.h>
 36 #include <linux/sched.h>
 37 #include <linux/types.h>
 38 #include <linux/fs.h>
 39 #include <linux/malloc.h>
 40 #include <linux/if_ether.h>
 41 #include <linux/string.h>
 42 #include <linux/netdevice.h>
 43 #include <linux/etherdevice.h>
 44 #include <linux/fddidevice.h>
 45 #include <linux/hippidevice.h>
 46 #include <linux/trdevice.h>
 47 #include <linux/fcdevice.h>
 48 #include <linux/if_arp.h>
 49 #include <linux/if_ltalk.h>
 50 #include <linux/rtnetlink.h>
 51 #include <net/neighbour.h>
 52 
 53 /* The network devices currently exist only in the socket namespace, so these
 54    entries are unused.  The only ones that make sense are
 55     open        start the ethercard
 56     close       stop  the ethercard
 57     ioctl       To get statistics, perhaps set the interface port (AUI, BNC, etc.)
 58    One can also imagine getting raw packets using
 59     read & write
 60    but this is probably better handled by a raw packet socket.
 61 
 62    Given that almost all of these functions are handled in the current
 63    socket-based scheme, putting ethercard devices in /dev/ seems pointless.
 64    
 65    [Removed all support for /dev network devices. When someone adds
 66     streams then by magic we get them, but otherwise they are un-needed
 67         and a space waste]
 68 */
 69 
 70 
 71 static struct net_device *init_alloc_dev(int sizeof_priv)
 72 {
 73         struct net_device *dev;
 74         int alloc_size;
 75 
 76         /* ensure 32-byte alignment of the private area */
 77         alloc_size = sizeof (*dev) + sizeof_priv + 31;
 78 
 79         dev = (struct net_device *) kmalloc (alloc_size, GFP_KERNEL);
 80         if (dev == NULL)
 81         {
 82                 printk(KERN_ERR "alloc_dev: Unable to allocate device memory.\n");
 83                 return NULL;
 84         }
 85 
 86         memset(dev, 0, alloc_size);
 87 
 88         if (sizeof_priv)
 89                 dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
 90 
 91         return dev;
 92 }
 93 
 94 /* 
 95  *      Create and name a device from a prototype, then perform any needed
 96  *      setup.
 97  */
 98 
 99 static struct net_device *init_netdev(struct net_device *dev, int sizeof_priv,
100                                       char *mask, void (*setup)(struct net_device *))
101 {
102         int new_device = 0;
103 
104         /*
105          *      Allocate a device if one is not provided.
106          */
107          
108         if (dev == NULL) {
109                 dev=init_alloc_dev(sizeof_priv);
110                 if(dev==NULL)
111                         return NULL;
112                 new_device = 1;
113         }
114 
115         /*
116          *      Allocate a name
117          */
118          
119         if (dev->name[0] == '\0' || dev->name[0] == ' ') {
120                 strcpy(dev->name, mask);
121                 if (dev_alloc_name(dev, mask)<0) {
122                         if (new_device)
123                                 kfree(dev);
124                         return NULL;
125                 }
126         }
127 
128         netdev_boot_setup_check(dev);
129         
130         /*
131          *      Configure via the caller provided setup function then
132          *      register if needed.
133          */
134         
135         setup(dev);
136         
137         if (new_device) {
138                 rtnl_lock();
139                 register_netdevice(dev);
140                 rtnl_unlock();
141         }
142         return dev;
143 }
144 
145 /**
146  * init_etherdev - Register ethernet device
147  * @dev: An ethernet device structure to be filled in, or %NULL if a new
148  *      struct should be allocated.
149  * @sizeof_priv: Size of additional driver-private structure to be allocated
150  *      for this ethernet device
151  *
152  * Fill in the fields of the device structure with ethernet-generic values.
153  *
154  * If no device structure is passed, a new one is constructed, complete with
155  * a private data area of size @sizeof_priv.  A 32-byte (not bit)
156  * alignment is enforced for this private data area.
157  *
158  * If an empty string area is passed as dev->name, or a new structure is made,
159  * a new name string is constructed.
160  */
161 
162 struct net_device *init_etherdev(struct net_device *dev, int sizeof_priv)
163 {
164         return init_netdev(dev, sizeof_priv, "eth%d", ether_setup);
165 }
166 
167 
168 static int eth_mac_addr(struct net_device *dev, void *p)
169 {
170         struct sockaddr *addr=p;
171         if (netif_running(dev))
172                 return -EBUSY;
173         memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
174         return 0;
175 }
176 
177 static int eth_change_mtu(struct net_device *dev, int new_mtu)
178 {
179         if ((new_mtu < 68) || (new_mtu > 1500))
180                 return -EINVAL;
181         dev->mtu = new_mtu;
182         return 0;
183 }
184 
185 #ifdef CONFIG_FDDI
186 
187 struct net_device *init_fddidev(struct net_device *dev, int sizeof_priv)
188 {
189         return init_netdev(dev, sizeof_priv, "fddi%d", fddi_setup);
190 }
191 
192 static int fddi_change_mtu(struct net_device *dev, int new_mtu)
193 {
194         if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN))
195                 return(-EINVAL);
196         dev->mtu = new_mtu;
197         return(0);
198 }
199 
200 #endif /* CONFIG_FDDI */
201 
202 #ifdef CONFIG_HIPPI
203 
204 static int hippi_change_mtu(struct net_device *dev, int new_mtu)
205 {
206         /*
207          * HIPPI's got these nice large MTUs.
208          */
209         if ((new_mtu < 68) || (new_mtu > 65280))
210                 return -EINVAL;
211         dev->mtu = new_mtu;
212         return(0);
213 }
214 
215 
216 /*
217  * For HIPPI we will actually use the lower 4 bytes of the hardware
218  * address as the I-FIELD rather than the actual hardware address.
219  */
220 static int hippi_mac_addr(struct net_device *dev, void *p)
221 {
222         struct sockaddr *addr = p;
223         if (netif_running(dev))
224                 return -EBUSY;
225         memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
226         return 0;
227 }
228 
229 
230 struct net_device *init_hippi_dev(struct net_device *dev, int sizeof_priv)
231 {
232         return init_netdev(dev, sizeof_priv, "hip%d", hippi_setup);
233 }
234 
235 
236 void unregister_hipdev(struct net_device *dev)
237 {
238         rtnl_lock();
239         unregister_netdevice(dev);
240         rtnl_unlock();
241 }
242 
243 
244 static int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
245 {
246         /* Never send broadcast/multicast ARP messages */
247         p->mcast_probes = 0;
248  
249         /* In IPv6 unicast probes are valid even on NBMA,
250         * because they are encapsulated in normal IPv6 protocol.
251         * Should be a generic flag. 
252         */
253         if (p->tbl->family != AF_INET6)
254                 p->ucast_probes = 0;
255         return 0;
256 }
257 
258 #endif /* CONFIG_HIPPI */
259 
260 void ether_setup(struct net_device *dev)
261 {
262         /* Fill in the fields of the device structure with ethernet-generic values.
263            This should be in a common file instead of per-driver.  */
264         
265         dev->change_mtu         = eth_change_mtu;
266         dev->hard_header        = eth_header;
267         dev->rebuild_header     = eth_rebuild_header;
268         dev->set_mac_address    = eth_mac_addr;
269         dev->hard_header_cache  = eth_header_cache;
270         dev->header_cache_update= eth_header_cache_update;
271         dev->hard_header_parse  = eth_header_parse;
272 
273         dev->type               = ARPHRD_ETHER;
274         dev->hard_header_len    = ETH_HLEN;
275         dev->mtu                = 1500; /* eth_mtu */
276         dev->addr_len           = ETH_ALEN;
277         dev->tx_queue_len       = 100;  /* Ethernet wants good queues */        
278         
279         memset(dev->broadcast,0xFF, ETH_ALEN);
280 
281         /* New-style flags. */
282         dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
283 
284         dev_init_buffers(dev);
285 }
286 
287 #ifdef CONFIG_FDDI
288 
289 void fddi_setup(struct net_device *dev)
290 {
291         /*
292          * Fill in the fields of the device structure with FDDI-generic values.
293          * This should be in a common file instead of per-driver.
294          */
295         
296         dev->change_mtu                 = fddi_change_mtu;
297         dev->hard_header                = fddi_header;
298         dev->rebuild_header             = fddi_rebuild_header;
299 
300         dev->type                               = ARPHRD_FDDI;
301         dev->hard_header_len    = FDDI_K_SNAP_HLEN+3;   /* Assume 802.2 SNAP hdr len + 3 pad bytes */
302         dev->mtu                                = FDDI_K_SNAP_DLEN;             /* Assume max payload of 802.2 SNAP frame */
303         dev->addr_len                   = FDDI_K_ALEN;
304         dev->tx_queue_len               = 100;  /* Long queues on FDDI */
305         
306         memset(dev->broadcast, 0xFF, FDDI_K_ALEN);
307 
308         /* New-style flags */
309         dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
310 
311         dev_init_buffers(dev);
312         
313         return;
314 }
315 
316 #endif /* CONFIG_FDDI */
317 
318 #ifdef CONFIG_HIPPI
319 void hippi_setup(struct net_device *dev)
320 {
321         dev->set_multicast_list = NULL;
322         dev->change_mtu                 = hippi_change_mtu;
323         dev->hard_header                = hippi_header;
324         dev->rebuild_header             = hippi_rebuild_header;
325         dev->set_mac_address            = hippi_mac_addr;
326         dev->hard_header_parse          = NULL;
327         dev->hard_header_cache          = NULL;
328         dev->header_cache_update        = NULL;
329         dev->neigh_setup                = hippi_neigh_setup_dev; 
330 
331         /*
332          * We don't support HIPPI `ARP' for the time being, and probably
333          * never will unless someone else implements it. However we
334          * still need a fake ARPHRD to make ifconfig and friends play ball.
335          */
336         dev->type               = ARPHRD_HIPPI;
337         dev->hard_header_len    = HIPPI_HLEN;
338         dev->mtu                = 65280;
339         dev->addr_len           = HIPPI_ALEN;
340         dev->tx_queue_len       = 25 /* 5 */;
341         memset(dev->broadcast, 0xFF, HIPPI_ALEN);
342 
343 
344         /*
345          * HIPPI doesn't support broadcast+multicast and we only use
346          * static ARP tables. ARP is disabled by hippi_neigh_setup_dev. 
347          */
348         dev->flags = 0; 
349 
350         dev_init_buffers(dev);
351 }
352 #endif /* CONFIG_HIPPI */
353 
354 #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
355 
356 static int ltalk_change_mtu(struct net_device *dev, int mtu)
357 {
358         return -EINVAL;
359 }
360 
361 static int ltalk_mac_addr(struct net_device *dev, void *addr)
362 {       
363         return -EINVAL;
364 }
365 
366 
367 void ltalk_setup(struct net_device *dev)
368 {
369         /* Fill in the fields of the device structure with localtalk-generic values. */
370         
371         dev->change_mtu         = ltalk_change_mtu;
372         dev->hard_header        = NULL;
373         dev->rebuild_header     = NULL;
374         dev->set_mac_address    = ltalk_mac_addr;
375         dev->hard_header_cache  = NULL;
376         dev->header_cache_update= NULL;
377 
378         dev->type               = ARPHRD_LOCALTLK;
379         dev->hard_header_len    = LTALK_HLEN;
380         dev->mtu                = LTALK_MTU;
381         dev->addr_len           = LTALK_ALEN;
382         dev->tx_queue_len       = 10;   
383         
384         dev->broadcast[0]       = 0xFF;
385 
386         dev->flags              = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
387 
388         dev_init_buffers(dev);
389 }
390 
391 #endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
392 
393 int ether_config(struct net_device *dev, struct ifmap *map)
394 {
395         if (map->mem_start != (u_long)(-1))
396                 dev->mem_start = map->mem_start;
397         if (map->mem_end != (u_long)(-1))
398                 dev->mem_end = map->mem_end;
399         if (map->base_addr != (u_short)(-1))
400                 dev->base_addr = map->base_addr;
401         if (map->irq != (u_char)(-1))
402                 dev->irq = map->irq;
403         if (map->dma != (u_char)(-1))
404                 dev->dma = map->dma;
405         if (map->port != (u_char)(-1))
406                 dev->if_port = map->port;
407         return 0;
408 }
409 
410 int register_netdev(struct net_device *dev)
411 {
412         int err;
413 
414         rtnl_lock();
415 
416         /*
417          *      If the name is a format string the caller wants us to
418          *      do a name allocation
419          */
420          
421         if (strchr(dev->name, '%'))
422         {
423                 err = -EBUSY;
424                 if(dev_alloc_name(dev, dev->name)<0)
425                         goto out;
426         }
427         
428         /*
429          *      Back compatibility hook. Kill this one in 2.5
430          */
431         
432         if (dev->name[0]==0 || dev->name[0]==' ')
433         {
434                 err = -EBUSY;
435                 if(dev_alloc_name(dev, "eth%d")<0)
436                         goto out;
437         }
438                 
439                 
440         err = -EIO;
441         if (register_netdevice(dev))
442                 goto out;
443 
444         err = 0;
445 
446 out:
447         rtnl_unlock();
448         return err;
449 }
450 
451 void unregister_netdev(struct net_device *dev)
452 {
453         rtnl_lock();
454         unregister_netdevice(dev);
455         rtnl_unlock();
456 }
457 
458 
459 #ifdef CONFIG_TR
460 
461 static void tr_configure(struct net_device *dev)
462 {
463         /*
464          *      Configure and register
465          */
466         
467         dev->hard_header        = tr_header;
468         dev->rebuild_header     = tr_rebuild_header;
469 
470         dev->type               = ARPHRD_IEEE802_TR;
471         dev->hard_header_len    = TR_HLEN;
472         dev->mtu                = 2000;
473         dev->addr_len           = TR_ALEN;
474         dev->tx_queue_len       = 100;  /* Long queues on tr */
475         
476         memset(dev->broadcast,0xFF, TR_ALEN);
477 
478         /* New-style flags. */
479         dev->flags              = IFF_BROADCAST | IFF_MULTICAST ;
480 }
481 
482 struct net_device *init_trdev(struct net_device *dev, int sizeof_priv)
483 {
484         return init_netdev(dev, sizeof_priv, "tr%d", tr_configure);
485 }
486 
487 void tr_setup(struct net_device *dev)
488 {
489 }
490 
491 int register_trdev(struct net_device *dev)
492 {
493         dev_init_buffers(dev);
494         
495         if (dev->init && dev->init(dev) != 0) {
496                 unregister_trdev(dev);
497                 return -EIO;
498         }
499         return 0;
500 }
501 
502 void unregister_trdev(struct net_device *dev)
503 {
504         rtnl_lock();
505         unregister_netdevice(dev);
506         rtnl_unlock();
507 }
508 #endif /* CONFIG_TR */
509 
510 
511 #ifdef CONFIG_NET_FC
512 
513 void fc_setup(struct net_device *dev)
514 {
515         dev->hard_header        =        fc_header;
516         dev->rebuild_header     =        fc_rebuild_header;
517                 
518         dev->type               =        ARPHRD_IEEE802;
519         dev->hard_header_len    =        FC_HLEN;
520         dev->mtu                =        2024;
521         dev->addr_len           =        FC_ALEN;
522         dev->tx_queue_len       =        100; /* Long queues on fc */
523 
524         memset(dev->broadcast,0xFF, FC_ALEN);
525 
526         /* New-style flags. */
527         dev->flags              =        IFF_BROADCAST;
528         dev_init_buffers(dev);
529         return;
530 }
531 
532 
533 struct net_device *init_fcdev(struct net_device *dev, int sizeof_priv)
534 {
535         return init_netdev(dev, sizeof_priv, "fc%d", fc_setup);
536 }
537 
538 int register_fcdev(struct net_device *dev)
539 {
540         dev_init_buffers(dev);
541         if (dev->init && dev->init(dev) != 0) {
542                 unregister_fcdev(dev);
543                 return -EIO;
544         }
545         return 0;
546 }                                               
547         
548 void unregister_fcdev(struct net_device *dev)
549 {
550         rtnl_lock();
551         unregister_netdevice(dev);
552         rtnl_unlock();
553 }
554 
555 #endif /* CONFIG_NET_FC */
556 
557 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.