Annotation of Gnu-Mach/linux/dev/drivers/net/net_init.c, revision 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: #ifdef MACH
        !           192:                        panic("ether_setup: Ouch! Someone else took %s\n",
        !           193:                                dev->name);
        !           194: #else
        !           195:                        printk("ether_setup: Ouch! Someone else took %s\n",
        !           196:                                dev->name);
        !           197: #endif
        !           198:                }
        !           199:        }
        !           200: 
        !           201: #ifndef MACH
        !           202:        dev->change_mtu         = eth_change_mtu;
        !           203:        dev->hard_header        = eth_header;
        !           204:        dev->rebuild_header     = eth_rebuild_header;
        !           205:        dev->set_mac_address    = eth_mac_addr;
        !           206:        dev->header_cache_bind  = eth_header_cache_bind;
        !           207:        dev->header_cache_update= eth_header_cache_update;
        !           208: #endif
        !           209:        
        !           210:        dev->type               = ARPHRD_ETHER;
        !           211:        dev->hard_header_len    = ETH_HLEN;
        !           212:        dev->mtu                = 1500; /* eth_mtu */
        !           213:        dev->addr_len           = ETH_ALEN;
        !           214:        dev->tx_queue_len       = 100;  /* Ethernet wants good queues */        
        !           215:        
        !           216:        memset(dev->broadcast,0xFF, ETH_ALEN);
        !           217: 
        !           218:        /* New-style flags. */
        !           219:        dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
        !           220:        dev->family             = AF_INET;
        !           221:        dev->pa_addr    = 0;
        !           222:        dev->pa_brdaddr = 0;
        !           223:        dev->pa_mask    = 0;
        !           224:        dev->pa_alen    = 4;
        !           225: }
        !           226: 
        !           227: #ifdef CONFIG_TR
        !           228: 
        !           229: void tr_setup(struct device *dev)
        !           230: {
        !           231:        int i;
        !           232:        /* Fill in the fields of the device structure with ethernet-generic values.
        !           233:           This should be in a common file instead of per-driver.  */
        !           234:        for (i = 0; i < DEV_NUMBUFFS; i++)
        !           235:                skb_queue_head_init(&dev->buffs[i]);
        !           236: 
        !           237:        dev->hard_header        = tr_header;
        !           238:        dev->rebuild_header     = tr_rebuild_header;
        !           239: 
        !           240:        dev->type               = ARPHRD_IEEE802;
        !           241:        dev->hard_header_len    = TR_HLEN;
        !           242:        dev->mtu                = 2000; /* bug in fragmenter...*/
        !           243:        dev->addr_len           = TR_ALEN;
        !           244:        dev->tx_queue_len       = 100;  /* Long queues on tr */
        !           245:        
        !           246:        memset(dev->broadcast,0xFF, TR_ALEN);
        !           247: 
        !           248:        /* New-style flags. */
        !           249:        dev->flags              = IFF_BROADCAST;
        !           250:        dev->family             = AF_INET;
        !           251:        dev->pa_addr    = 0;
        !           252:        dev->pa_brdaddr = 0;
        !           253:        dev->pa_mask    = 0;
        !           254:        dev->pa_alen    = 4;
        !           255: }
        !           256: 
        !           257: #endif
        !           258: 
        !           259: #ifdef CONFIG_FDDI
        !           260: 
        !           261: void fddi_setup(struct device *dev)
        !           262:        {
        !           263:        int i;
        !           264: 
        !           265:        /*
        !           266:         * Fill in the fields of the device structure with FDDI-generic values.
        !           267:         * This should be in a common file instead of per-driver.
        !           268:         */
        !           269:        for (i=0; i < DEV_NUMBUFFS; i++)
        !           270:                skb_queue_head_init(&dev->buffs[i]);
        !           271: 
        !           272:        dev->change_mtu                 = fddi_change_mtu;
        !           273:        dev->hard_header                = fddi_header;
        !           274:        dev->rebuild_header             = fddi_rebuild_header;
        !           275: 
        !           276:        dev->type                               = ARPHRD_FDDI;
        !           277:        dev->hard_header_len    = FDDI_K_SNAP_HLEN+3;   /* Assume 802.2 SNAP hdr len + 3 pad bytes */
        !           278:        dev->mtu                                = FDDI_K_SNAP_DLEN;             /* Assume max payload of 802.2 SNAP frame */
        !           279:        dev->addr_len                   = FDDI_K_ALEN;
        !           280:        dev->tx_queue_len               = 100;  /* Long queues on FDDI */
        !           281:        
        !           282:        memset(dev->broadcast, 0xFF, FDDI_K_ALEN);
        !           283: 
        !           284:        /* New-style flags */
        !           285:        dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
        !           286:        dev->family             = AF_INET;
        !           287:        dev->pa_addr    = 0;
        !           288:        dev->pa_brdaddr = 0;
        !           289:        dev->pa_mask    = 0;
        !           290:        dev->pa_alen    = 4;
        !           291:        return;
        !           292:        }
        !           293: 
        !           294: #endif
        !           295: 
        !           296: int ether_config(struct device *dev, struct ifmap *map)
        !           297: {
        !           298:        if (map->mem_start != (u_long)(-1))
        !           299:                dev->mem_start = map->mem_start;
        !           300:        if (map->mem_end != (u_long)(-1))
        !           301:                dev->mem_end = map->mem_end;
        !           302:        if (map->base_addr != (u_short)(-1))
        !           303:                dev->base_addr = map->base_addr;
        !           304:        if (map->irq != (u_char)(-1))
        !           305:                dev->irq = map->irq;
        !           306:        if (map->dma != (u_char)(-1))
        !           307:                dev->dma = map->dma;
        !           308:        if (map->port != (u_char)(-1))
        !           309:                dev->if_port = map->port;
        !           310:        return 0;
        !           311: }
        !           312: 
        !           313: int register_netdev(struct device *dev)
        !           314: {
        !           315:        struct device *d = dev_base;
        !           316:        unsigned long flags;
        !           317:        int i=MAX_ETH_CARDS;
        !           318: 
        !           319:        save_flags(flags);
        !           320:        cli();
        !           321: 
        !           322:        if (dev && dev->init) {
        !           323:                if (dev->name &&
        !           324:                        ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
        !           325:                        for (i = 0; i < MAX_ETH_CARDS; ++i)
        !           326:                                if (ethdev_index[i] == NULL) {
        !           327:                                        sprintf(dev->name, "eth%d", i);
        !           328:                                        printk("loading device '%s'...\n", dev->name);
        !           329:                                        ethdev_index[i] = dev;
        !           330:                                        break;
        !           331:                                }
        !           332:                }
        !           333: 
        !           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;
        !           339:                }
        !           340:                cli();
        !           341: 
        !           342:                /* Add device to end of chain */
        !           343:                if (dev_base) {
        !           344:                        while (d->next)
        !           345:                                d = d->next;
        !           346:                        d->next = dev;
        !           347:                }
        !           348:                else
        !           349:                        dev_base = dev;
        !           350:                dev->next = NULL;
        !           351:        }
        !           352:        restore_flags(flags);
        !           353:        return 0;
        !           354: }
        !           355: 
        !           356: void unregister_netdev(struct device *dev)
        !           357: {
        !           358:        struct device *d = dev_base;
        !           359:        unsigned long flags;
        !           360:        int i;
        !           361: 
        !           362:        save_flags(flags);
        !           363:        cli();
        !           364: 
        !           365:        if (dev == NULL) 
        !           366:        {
        !           367:                printk("was NULL\n");
        !           368:                restore_flags(flags);
        !           369:                return;
        !           370:        }
        !           371:        /* else */
        !           372:        if (dev->start)
        !           373:                printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
        !           374: 
        !           375:        /*
        !           376:         *      must jump over main_device+aliases
        !           377:         *      avoid alias devices unregistration so that only
        !           378:         *      net_alias module manages them
        !           379:         */
        !           380: #ifdef CONFIG_NET_ALIAS                
        !           381:        if (dev_base == dev)
        !           382:                dev_base = net_alias_nextdev(dev);
        !           383:        else
        !           384:        {
        !           385:                while(d && (net_alias_nextdev(d) != dev)) /* skip aliases */
        !           386:                        d = net_alias_nextdev(d);
        !           387:          
        !           388:                if (d && (net_alias_nextdev(d) == dev))
        !           389:                {
        !           390:                        /*
        !           391:                         *      Critical: Bypass by consider devices as blocks (maindev+aliases)
        !           392:                         */
        !           393:                        net_alias_nextdev_set(d, net_alias_nextdev(dev)); 
        !           394:                }
        !           395: #else
        !           396:        if (dev_base == dev)
        !           397:                dev_base = dev->next;
        !           398:        else 
        !           399:        {
        !           400:                while (d && (d->next != dev))
        !           401:                        d = d->next;
        !           402:                
        !           403:                if (d && (d->next == dev)) 
        !           404:                {
        !           405:                        d->next = dev->next;
        !           406:                }
        !           407: #endif
        !           408:                else 
        !           409:                {
        !           410:                        printk("unregister_netdev: '%s' not found\n", dev->name);
        !           411:                        restore_flags(flags);
        !           412:                        return;
        !           413:                }
        !           414:        }
        !           415:        for (i = 0; i < MAX_ETH_CARDS; ++i) 
        !           416:        {
        !           417:                if (ethdev_index[i] == dev) 
        !           418:                {
        !           419:                        ethdev_index[i] = NULL;
        !           420:                        break;
        !           421:                }
        !           422:        }
        !           423: 
        !           424:        restore_flags(flags);
        !           425: 
        !           426:        /*
        !           427:         *      You can i.e use a interfaces in a route though it is not up.
        !           428:         *      We call close_dev (which is changed: it will down a device even if
        !           429:         *      dev->flags==0 (but it will not call dev->stop if IFF_UP
        !           430:         *      is not set).
        !           431:         *      This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
        !           432:         *      dev_mc_discard(dev), ....
        !           433:         */
        !           434:         
        !           435:        dev_close(dev);
        !           436: }
        !           437: 
        !           438: 
        !           439: /*
        !           440:  * Local variables:
        !           441:  *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
        !           442:  *  version-control: t
        !           443:  *  kept-new-versions: 5
        !           444:  *  tab-width: 4
        !           445:  * End:
        !           446:  */

unix.superglobalmegacorp.com

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