📄 net_init.c
字号:
* We don't support HIPPI `ARP' for the time being, and probably
* never will unless someone else implements it. However we
* still need a fake ARPHRD to make ifconfig and friends play ball.
*/
dev->type = ARPHRD_HIPPI;
dev->hard_header_len = HIPPI_HLEN;
dev->mtu = 65280;
dev->addr_len = HIPPI_ALEN;
dev->tx_queue_len = 25 /* 5 */;
memset(dev->broadcast, 0xFF, HIPPI_ALEN);
/*
* HIPPI doesn't support broadcast+multicast and we only use
* static ARP tables. ARP is disabled by hippi_neigh_setup_dev.
*/
dev->flags = 0;
dev_init_buffers(dev);
}
#endif
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
static int ltalk_change_mtu(struct device *dev, int mtu)
{
return -EINVAL;
}
static int ltalk_mac_addr(struct device *dev, void *addr)
{
return -EINVAL;
}
void ltalk_setup(struct device *dev)
{
/* Fill in the fields of the device structure with localtalk-generic values. */
dev->change_mtu = ltalk_change_mtu;
dev->hard_header = NULL;
dev->rebuild_header = NULL;
dev->set_mac_address = ltalk_mac_addr;
dev->hard_header_cache = NULL;
dev->header_cache_update= NULL;
dev->type = ARPHRD_LOCALTLK;
dev->hard_header_len = LTALK_HLEN;
dev->mtu = LTALK_MTU;
dev->addr_len = LTALK_ALEN;
dev->tx_queue_len = 10;
dev->broadcast[0] = 0xFF;
dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP;
dev_init_buffers(dev);
}
#endif
int ether_config(struct device *dev, struct ifmap *map)
{
if (map->mem_start != (u_long)(-1))
dev->mem_start = map->mem_start;
if (map->mem_end != (u_long)(-1))
dev->mem_end = map->mem_end;
if (map->base_addr != (u_short)(-1))
dev->base_addr = map->base_addr;
if (map->irq != (u_char)(-1))
dev->irq = map->irq;
if (map->dma != (u_char)(-1))
dev->dma = map->dma;
if (map->port != (u_char)(-1))
dev->if_port = map->port;
return 0;
}
static int etherdev_get_index(struct device *dev)
{
int i=MAX_ETH_CARDS;
for (i = 0; i < MAX_ETH_CARDS; ++i) {
if (ethdev_index[i] == NULL) {
sprintf(dev->name, "eth%d", i);
/* printk("loading device '%s'...\n", dev->name);*/
ethdev_index[i] = dev;
return i;
}
}
return -1;
}
static void etherdev_put_index(struct device *dev)
{
int i;
for (i = 0; i < MAX_ETH_CARDS; ++i) {
if (ethdev_index[i] == dev) {
ethdev_index[i] = NULL;
break;
}
}
}
int register_netdev(struct device *dev)
{
int i=-1;
rtnl_lock();
if (dev->name &&
(dev->name[0] == '\0' || dev->name[0] == ' '))
i = etherdev_get_index(dev);
if (register_netdevice(dev)) {
if (i >= 0)
etherdev_put_index(dev);
rtnl_unlock();
return -EIO;
}
rtnl_unlock();
return 0;
}
void unregister_netdev(struct device *dev)
{
rtnl_lock();
unregister_netdevice(dev);
etherdev_put_index(dev);
rtnl_unlock();
}
#ifdef CONFIG_TR
/* The list of used and available "tr" slots */
#define MAX_TR_CARDS 16
static struct device *trdev_index[MAX_TR_CARDS];
struct device *init_trdev(struct device *dev, int sizeof_priv)
{
int new_device = 0;
int i;
/* Use an existing correctly named device in Space.c:dev_base. */
if (dev == NULL) {
int alloc_size = sizeof(struct device) + sizeof("tr%d ")
+ sizeof_priv + 3;
struct device *cur_dev;
char pname[8]; /* Putative name for the device. */
for (i = 0; i < MAX_TR_CARDS; ++i)
if (trdev_index[i] == NULL) {
sprintf(pname, "tr%d", i);
for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
if (strcmp(pname, cur_dev->name) == 0) {
dev = cur_dev;
dev->init = NULL;
sizeof_priv = (sizeof_priv + 3) & ~3;
dev->priv = sizeof_priv
? kmalloc(sizeof_priv, GFP_KERNEL)
: NULL;
if (dev->priv) memset(dev->priv, 0, sizeof_priv);
goto trfound;
}
}
alloc_size &= ~3; /* Round to dword boundary. */
dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
if(dev==NULL)
return NULL;
memset(dev, 0, alloc_size);
if (sizeof_priv)
dev->priv = (void *) (dev + 1);
dev->name = sizeof_priv + (char *)(dev + 1);
new_device = 1;
}
trfound: /* From the double loop above. */
for (i = 0; i < MAX_TR_CARDS; ++i)
if (trdev_index[i] == NULL) {
sprintf(dev->name, "tr%d", i);
trdev_index[i] = dev;
break;
}
dev->hard_header = tr_header;
dev->rebuild_header = tr_rebuild_header;
dev->type = ARPHRD_IEEE802;
dev->hard_header_len = TR_HLEN;
dev->mtu = 2000; /* bug in fragmenter...*/
dev->addr_len = TR_ALEN;
dev->tx_queue_len = 100; /* Long queues on tr */
memset(dev->broadcast,0xFF, TR_ALEN);
/* New-style flags. */
dev->flags = IFF_BROADCAST | IFF_MULTICAST ;
if (new_device)
register_netdevice(dev);
return dev;
}
void tr_setup(struct device *dev)
{
int i;
/* register boot-defined "tr" devices */
if (dev->name && (strncmp(dev->name, "tr", 2) == 0)) {
i = simple_strtoul(dev->name + 2, NULL, 0);
if (trdev_index[i] == NULL) {
trdev_index[i] = dev;
}
else if (dev != trdev_index[i]) {
/* Really shouldn't happen! */
printk("tr_setup: Ouch! Someone else took %s\n",
dev->name);
}
}
}
void tr_freedev(struct device *dev)
{
int i;
for (i = 0; i < MAX_TR_CARDS; ++i)
{
if (trdev_index[i] == dev)
{
trdev_index[i] = NULL;
break;
}
}
}
int register_trdev(struct device *dev)
{
dev_init_buffers(dev);
if (dev->init && dev->init(dev) != 0) {
unregister_trdev(dev);
return -EIO;
}
return 0;
}
void unregister_trdev(struct device *dev)
{
rtnl_lock();
unregister_netdevice(dev);
rtnl_unlock();
tr_freedev(dev);
}
#endif
#ifdef CONFIG_NET_FC
#define MAX_FC_CARDS 2
static struct device *fcdev_index[MAX_FC_CARDS];
void fc_setup(struct device *dev)
{
int i;
/* register boot-defined "fc" devices */
if (dev->name && (strncmp(dev->name, "fc", 2) == 0)) {
i = simple_strtoul(dev->name + 2, NULL, 0);
if (fcdev_index[i] == NULL) {
fcdev_index[i] = dev;
}
else if (dev != fcdev_index[i]) {
/* Really shouldn't happen! */
printk("fc_setup: Ouch! Someone else took %s\n",
dev->name);
}
}
dev->hard_header = fc_header;
dev->rebuild_header = fc_rebuild_header;
dev->type = ARPHRD_IEEE802;
dev->hard_header_len = FC_HLEN;
dev->mtu = 2024;
dev->addr_len = FC_ALEN;
dev->tx_queue_len = 100; /* Long queues on fc */
memset(dev->broadcast,0xFF, FC_ALEN);
/* New-style flags. */
dev->flags = IFF_BROADCAST;
dev_init_buffers(dev);
return;
}
struct device *init_fcdev(struct device *dev, int sizeof_priv)
{
int new_device = 0;
int i;
/* Use an existing correctly named device in Space.c:dev_base. */
if (dev == NULL) {
int alloc_size = sizeof(struct device) + sizeof("fc%d ") + sizeof_priv + 3;
struct device *cur_dev;
char pname[8]; /* Putative name for the device. */
for (i = 0; i < MAX_FC_CARDS; ++i)
if (fcdev_index[i] == NULL) {
sprintf(pname, "fc%d", i);
for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
if (strcmp(pname, cur_dev->name) == 0) {
dev = cur_dev;
dev->init = NULL;
sizeof_priv = (sizeof_priv + 3) &~3;
dev->priv = sizeof_priv
? kmalloc(sizeof_priv, GFP_KERNEL)
: NULL;
if (dev->priv) memset(dev->priv, 0, sizeof_priv);
goto fcfound;
}
}
alloc_size &= ~3; /* Round to dword boundary. */
dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
memset(dev, 0, alloc_size);
if (sizeof_priv)
dev->priv = (void *) (dev + 1);
dev->name = sizeof_priv + (char *)(dev + 1);
new_device = 1;
}
fcfound: /* From the double loop */
for (i = 0; i < MAX_FC_CARDS; ++i)
if (fcdev_index[i] == NULL) {
sprintf(dev->name, "fc%d", i);
fcdev_index[i] = dev;
break;
}
fc_setup(dev);
if (new_device)
register_netdevice(dev);
return dev;
}
void fc_freedev(struct device *dev)
{
int i;
for (i = 0; i < MAX_FC_CARDS; ++i) {
if (fcdev_index[i] == dev) {
fcdev_index[i] = NULL;
break;
}
}
}
int register_fcdev(struct device *dev)
{
dev_init_buffers(dev);
if (dev->init && dev->init(dev) != 0) {
unregister_fcdev(dev);
return -EIO;
}
return 0;
}
void unregister_fcdev(struct device *dev)
{
rtnl_lock();
unregister_netdevice(dev);
rtnl_unlock();
fc_freedev(dev);
}
#endif /* CONFIG_NET_FC */
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
* version-control: t
* kept-new-versions: 5
* End:
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -