Annotation of Gnu-Mach/linux/src/drivers/net/net_init.c, revision 1.1.1.1

1.1       root        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 [email protected] 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 <[email protected]>:
                     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: 
                     26:        August 12, 1996 - Lawrence V. Stefani: Added fddi_change_mtu() and
                     27:                                          fddi_setup() functions.
                     28:        Sept. 10, 1996  - Lawrence V. Stefani: Increased hard_header_len to
                     29:                                          include 3 pad bytes.
                     30: */
                     31: 
                     32: #include <linux/config.h>
                     33: #include <linux/kernel.h>
                     34: #include <linux/sched.h>
                     35: #include <linux/types.h>
                     36: #include <linux/fs.h>
                     37: #include <linux/malloc.h>
                     38: #include <linux/if_ether.h>
                     39: #include <linux/string.h>
                     40: #include <linux/netdevice.h>
                     41: #include <linux/etherdevice.h>
                     42: #include <linux/fddidevice.h>
                     43: #include <linux/trdevice.h>
                     44: #include <linux/if_arp.h>
                     45: #ifdef CONFIG_NET_ALIAS
                     46: #include <linux/net_alias.h>
                     47: #endif
                     48: 
                     49: /* The network devices currently exist only in the socket namespace, so these
                     50:    entries are unused.  The only ones that make sense are
                     51:     open       start the ethercard
                     52:     close      stop  the ethercard
                     53:     ioctl      To get statistics, perhaps set the interface port (AUI, BNC, etc.)
                     54:    One can also imagine getting raw packets using
                     55:     read & write
                     56:    but this is probably better handled by a raw packet socket.
                     57: 
                     58:    Given that almost all of these functions are handled in the current
                     59:    socket-based scheme, putting ethercard devices in /dev/ seems pointless.
                     60:    
                     61:    [Removed all support for /dev network devices. When someone adds
                     62:     streams then by magic we get them, but otherwise they are un-needed
                     63:        and a space waste]
                     64: */
                     65: 
                     66: /* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
                     67: #define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
                     68: static struct device *ethdev_index[MAX_ETH_CARDS];
                     69: 
                     70: 
                     71: /* Fill in the fields of the device structure with ethernet-generic values.
                     72: 
                     73:    If no device structure is passed, a new one is constructed, complete with
                     74:    a SIZEOF_PRIVATE private data area.
                     75: 
                     76:    If an empty string area is passed as dev->name, or a new structure is made,
                     77:    a new name string is constructed.  The passed string area should be 8 bytes
                     78:    long.
                     79:  */
                     80: 
                     81: struct device *
                     82: init_etherdev(struct device *dev, int sizeof_priv)
                     83: {
                     84:        int new_device = 0;
                     85:        int i;
                     86: 
                     87:        /* Use an existing correctly named device in Space.c:dev_base. */
                     88:        if (dev == NULL) {
                     89:                int alloc_size = sizeof(struct device) + sizeof("eth%d  ")
                     90:                        + sizeof_priv + 3;
                     91:                struct device *cur_dev;
                     92:                char pname[8];          /* Putative name for the device.  */
                     93: 
                     94:                for (i = 0; i < MAX_ETH_CARDS; ++i)
                     95:                        if (ethdev_index[i] == NULL) {
                     96:                                sprintf(pname, "eth%d", i);
                     97:                                for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
                     98:                                        if (strcmp(pname, cur_dev->name) == 0) {
                     99:                                                dev = cur_dev;
                    100:                                                dev->init = NULL;
                    101:                                                sizeof_priv = (sizeof_priv + 3) & ~3;
                    102:                                                dev->priv = sizeof_priv
                    103:                                                          ? kmalloc(sizeof_priv, GFP_KERNEL)
                    104:                                                          :     NULL;
                    105:                                                if (dev->priv) memset(dev->priv, 0, sizeof_priv);
                    106:                                                goto found;
                    107:                                        }
                    108:                        }
                    109: 
                    110:                alloc_size &= ~3;               /* Round to dword boundary. */
                    111: 
                    112:                dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
                    113:                memset(dev, 0, alloc_size);
                    114:                if (sizeof_priv)
                    115:                        dev->priv = (void *) (dev + 1);
                    116:                dev->name = sizeof_priv + (char *)(dev + 1);
                    117:                new_device = 1;
                    118:        }
                    119: 
                    120:        found:                                          /* From the double loop above. */
                    121: 
                    122:        if (dev->name &&
                    123:                ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
                    124:                for (i = 0; i < MAX_ETH_CARDS; ++i)
                    125:                        if (ethdev_index[i] == NULL) {
                    126:                                sprintf(dev->name, "eth%d", i);
                    127:                                ethdev_index[i] = dev;
                    128:                                break;
                    129:                        }
                    130:        }
                    131: 
                    132:        ether_setup(dev);       /* Hmmm, should this be called here? */
                    133:        
                    134:        if (new_device) {
                    135:                /* Append the device to the device queue. */
                    136:                struct device **old_devp = &dev_base;
                    137:                while ((*old_devp)->next)
                    138:                        old_devp = & (*old_devp)->next;
                    139:                (*old_devp)->next = dev;
                    140:                dev->next = 0;
                    141:        }
                    142:        return dev;
                    143: }
                    144: 
                    145: 
                    146: static int eth_mac_addr(struct device *dev, void *p)
                    147: {
                    148:        struct sockaddr *addr=p;
                    149:        if(dev->start)
                    150:                return -EBUSY;
                    151:        memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
                    152:        return 0;
                    153: }
                    154: 
                    155: static int eth_change_mtu(struct device *dev, int new_mtu)
                    156: {
                    157:        if ((new_mtu < 68) || (new_mtu > 1500))
                    158:                return -EINVAL;
                    159:        dev->mtu = new_mtu;
                    160:        return 0;
                    161: }
                    162: 
                    163: #ifdef CONFIG_FDDI
                    164: 
                    165: static int fddi_change_mtu(struct device *dev, int new_mtu)
                    166: {
                    167:        if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN))
                    168:                return(-EINVAL);
                    169:        dev->mtu = new_mtu;
                    170:        return(0);
                    171: }
                    172: 
                    173: #endif
                    174: 
                    175: void ether_setup(struct device *dev)
                    176: {
                    177:        int i;
                    178:        /* Fill in the fields of the device structure with ethernet-generic values.
                    179:           This should be in a common file instead of per-driver.  */
                    180:        for (i = 0; i < DEV_NUMBUFFS; i++)
                    181:                skb_queue_head_init(&dev->buffs[i]);
                    182: 
                    183:        /* register boot-defined "eth" devices */
                    184:        if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
                    185:                i = simple_strtoul(dev->name + 3, NULL, 0);
                    186:                if (ethdev_index[i] == NULL) {
                    187:                        ethdev_index[i] = dev;
                    188:                }
                    189:                else if (dev != ethdev_index[i]) {
                    190:                        /* Really shouldn't happen! */
                    191:                        printk("ether_setup: Ouch! Someone else took %s\n",
                    192:                                dev->name);
                    193:                }
                    194:        }
                    195: 
                    196:        dev->change_mtu         = eth_change_mtu;
                    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_bind  = eth_header_cache_bind;
                    201:        dev->header_cache_update= eth_header_cache_update;
                    202: 
                    203:        dev->type               = ARPHRD_ETHER;
                    204:        dev->hard_header_len    = ETH_HLEN;
                    205:        dev->mtu                = 1500; /* eth_mtu */
                    206:        dev->addr_len           = ETH_ALEN;
                    207:        dev->tx_queue_len       = 100;  /* Ethernet wants good queues */        
                    208:        
                    209:        memset(dev->broadcast,0xFF, ETH_ALEN);
                    210: 
                    211:        /* New-style flags. */
                    212:        dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
                    213:        dev->family             = AF_INET;
                    214:        dev->pa_addr    = 0;
                    215:        dev->pa_brdaddr = 0;
                    216:        dev->pa_mask    = 0;
                    217:        dev->pa_alen    = 4;
                    218: }
                    219: 
                    220: #ifdef CONFIG_TR
                    221: 
                    222: void tr_setup(struct device *dev)
                    223: {
                    224:        int i;
                    225:        /* Fill in the fields of the device structure with ethernet-generic values.
                    226:           This should be in a common file instead of per-driver.  */
                    227:        for (i = 0; i < DEV_NUMBUFFS; i++)
                    228:                skb_queue_head_init(&dev->buffs[i]);
                    229: 
                    230:        dev->hard_header        = tr_header;
                    231:        dev->rebuild_header     = tr_rebuild_header;
                    232: 
                    233:        dev->type               = ARPHRD_IEEE802;
                    234:        dev->hard_header_len    = TR_HLEN;
                    235:        dev->mtu                = 2000; /* bug in fragmenter...*/
                    236:        dev->addr_len           = TR_ALEN;
                    237:        dev->tx_queue_len       = 100;  /* Long queues on tr */
                    238:        
                    239:        memset(dev->broadcast,0xFF, TR_ALEN);
                    240: 
                    241:        /* New-style flags. */
                    242:        dev->flags              = IFF_BROADCAST;
                    243:        dev->family             = AF_INET;
                    244:        dev->pa_addr    = 0;
                    245:        dev->pa_brdaddr = 0;
                    246:        dev->pa_mask    = 0;
                    247:        dev->pa_alen    = 4;
                    248: }
                    249: 
                    250: #endif
                    251: 
                    252: #ifdef CONFIG_FDDI
                    253: 
                    254: void fddi_setup(struct device *dev)
                    255:        {
                    256:        int i;
                    257: 
                    258:        /*
                    259:         * Fill in the fields of the device structure with FDDI-generic values.
                    260:         * This should be in a common file instead of per-driver.
                    261:         */
                    262:        for (i=0; i < DEV_NUMBUFFS; i++)
                    263:                skb_queue_head_init(&dev->buffs[i]);
                    264: 
                    265:        dev->change_mtu                 = fddi_change_mtu;
                    266:        dev->hard_header                = fddi_header;
                    267:        dev->rebuild_header             = fddi_rebuild_header;
                    268: 
                    269:        dev->type                               = ARPHRD_FDDI;
                    270:        dev->hard_header_len    = FDDI_K_SNAP_HLEN+3;   /* Assume 802.2 SNAP hdr len + 3 pad bytes */
                    271:        dev->mtu                                = FDDI_K_SNAP_DLEN;             /* Assume max payload of 802.2 SNAP frame */
                    272:        dev->addr_len                   = FDDI_K_ALEN;
                    273:        dev->tx_queue_len               = 100;  /* Long queues on FDDI */
                    274:        
                    275:        memset(dev->broadcast, 0xFF, FDDI_K_ALEN);
                    276: 
                    277:        /* New-style flags */
                    278:        dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
                    279:        dev->family             = AF_INET;
                    280:        dev->pa_addr    = 0;
                    281:        dev->pa_brdaddr = 0;
                    282:        dev->pa_mask    = 0;
                    283:        dev->pa_alen    = 4;
                    284:        return;
                    285:        }
                    286: 
                    287: #endif
                    288: 
                    289: int ether_config(struct device *dev, struct ifmap *map)
                    290: {
                    291:        if (map->mem_start != (u_long)(-1))
                    292:                dev->mem_start = map->mem_start;
                    293:        if (map->mem_end != (u_long)(-1))
                    294:                dev->mem_end = map->mem_end;
                    295:        if (map->base_addr != (u_short)(-1))
                    296:                dev->base_addr = map->base_addr;
                    297:        if (map->irq != (u_char)(-1))
                    298:                dev->irq = map->irq;
                    299:        if (map->dma != (u_char)(-1))
                    300:                dev->dma = map->dma;
                    301:        if (map->port != (u_char)(-1))
                    302:                dev->if_port = map->port;
                    303:        return 0;
                    304: }
                    305: 
                    306: int register_netdev(struct device *dev)
                    307: {
                    308:        struct device *d = dev_base;
                    309:        unsigned long flags;
                    310:        int i=MAX_ETH_CARDS;
                    311: 
                    312:        save_flags(flags);
                    313:        cli();
                    314: 
                    315:        if (dev && dev->init) {
                    316:                if (dev->name &&
                    317:                        ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
                    318:                        for (i = 0; i < MAX_ETH_CARDS; ++i)
                    319:                                if (ethdev_index[i] == NULL) {
                    320:                                        sprintf(dev->name, "eth%d", i);
                    321: /*                                     printk("loading device '%s'...\n", dev->name);*/
                    322:                                        ethdev_index[i] = dev;
                    323:                                        break;
                    324:                                }
                    325:                }
                    326: 
                    327:                sti();  /* device probes assume interrupts enabled */
                    328:                if (dev->init(dev) != 0) {
                    329:                    if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
                    330:                        restore_flags(flags);
                    331:                        return -EIO;
                    332:                }
                    333:                cli();
                    334: 
                    335:                /* Add device to end of chain */
                    336:                if (dev_base) {
                    337:                        while (d->next)
                    338:                                d = d->next;
                    339:                        d->next = dev;
                    340:                }
                    341:                else
                    342:                        dev_base = dev;
                    343:                dev->next = NULL;
                    344:        }
                    345:        restore_flags(flags);
                    346:        return 0;
                    347: }
                    348: 
                    349: void unregister_netdev(struct device *dev)
                    350: {
                    351:        struct device *d = dev_base;
                    352:        unsigned long flags;
                    353:        int i;
                    354: 
                    355:        save_flags(flags);
                    356:        cli();
                    357: 
                    358:        if (dev == NULL) 
                    359:        {
                    360:                printk("was NULL\n");
                    361:                restore_flags(flags);
                    362:                return;
                    363:        }
                    364:        /* else */
                    365:        if (dev->start)
                    366:                printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
                    367: 
                    368:        /*
                    369:         *      must jump over main_device+aliases
                    370:         *      avoid alias devices unregistration so that only
                    371:         *      net_alias module manages them
                    372:         */
                    373: #ifdef CONFIG_NET_ALIAS                
                    374:        if (dev_base == dev)
                    375:                dev_base = net_alias_nextdev(dev);
                    376:        else
                    377:        {
                    378:                while(d && (net_alias_nextdev(d) != dev)) /* skip aliases */
                    379:                        d = net_alias_nextdev(d);
                    380:          
                    381:                if (d && (net_alias_nextdev(d) == dev))
                    382:                {
                    383:                        /*
                    384:                         *      Critical: Bypass by consider devices as blocks (maindev+aliases)
                    385:                         */
                    386:                        net_alias_nextdev_set(d, net_alias_nextdev(dev)); 
                    387:                }
                    388: #else
                    389:        if (dev_base == dev)
                    390:                dev_base = dev->next;
                    391:        else 
                    392:        {
                    393:                while (d && (d->next != dev))
                    394:                        d = d->next;
                    395:                
                    396:                if (d && (d->next == dev)) 
                    397:                {
                    398:                        d->next = dev->next;
                    399:                }
                    400: #endif
                    401:                else 
                    402:                {
                    403:                        printk("unregister_netdev: '%s' not found\n", dev->name);
                    404:                        restore_flags(flags);
                    405:                        return;
                    406:                }
                    407:        }
                    408:        for (i = 0; i < MAX_ETH_CARDS; ++i) 
                    409:        {
                    410:                if (ethdev_index[i] == dev) 
                    411:                {
                    412:                        ethdev_index[i] = NULL;
                    413:                        break;
                    414:                }
                    415:        }
                    416: 
                    417:        restore_flags(flags);
                    418: 
                    419:        /*
                    420:         *      You can i.e use a interfaces in a route though it is not up.
                    421:         *      We call close_dev (which is changed: it will down a device even if
                    422:         *      dev->flags==0 (but it will not call dev->stop if IFF_UP
                    423:         *      is not set).
                    424:         *      This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
                    425:         *      dev_mc_discard(dev), ....
                    426:         */
                    427:         
                    428:        dev_close(dev);
                    429: }
                    430: 
                    431: 
                    432: /*
                    433:  * Local variables:
                    434:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
                    435:  *  version-control: t
                    436:  *  kept-new-versions: 5
                    437:  *  tab-width: 4
                    438:  * End:
                    439:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.