summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/Space.c29
-rw-r--r--drivers/net/loopback.c72
-rw-r--r--net/core/dev.c70
3 files changed, 50 insertions, 121 deletions
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index a8a92838db26..470cae32a543 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -39,9 +39,6 @@
#include <linux/netlink.h>
#include <linux/divert.h>
-#define NEXT_DEV NULL
-
-
/* A unified ethernet device probe. This is the easiest way to have every
ethernet adaptor have the name "eth[0123...]".
*/
@@ -438,11 +435,23 @@ static __init int trif_probe(void)
}
#endif
+
+/*
+ * The loopback device is global so it can be directly referenced
+ * by the network code. Also, it must be first on device list.
+ */
+extern int loopback_init(void);
+
/* Statically configured drivers -- order matters here. */
void __init probe_old_netdevs(void)
{
int num;
+ if (loopback_init()) {
+ printk(KERN_ERR "Network loopback device setup failed\n");
+ }
+
+
#ifdef CONFIG_SBNI
for (num = 0; num < 8; ++num)
if (sbni_probe())
@@ -477,18 +486,6 @@ static struct net_device dev_ltpc = {
#undef NEXT_DEV
#define NEXT_DEV (&dev_ltpc)
#endif /* LTPC */
-
-/*
- * The loopback device is global so it can be directly referenced
- * by the network code. Also, it must be first on device list.
- */
-
-extern int loopback_init(struct net_device *dev);
-struct net_device loopback_dev = {
- .name = "lo",
- .next = NEXT_DEV,
- .init = loopback_init
-};
/*
* The @dev_base list is protected by @dev_base_lock and the rtln
@@ -509,6 +506,6 @@ struct net_device loopback_dev = {
* unregister_netdevice(), which must be called with the rtnl
* semaphore held.
*/
-struct net_device *dev_base = &loopback_dev;
+struct net_device *dev_base;
rwlock_t dev_base_lock = RW_LOCK_UNLOCKED;
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 7382804af6b0..5dd2b3393edc 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -55,6 +55,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
+
#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
/* KISS: just allocate small chunks and copy bits.
@@ -152,10 +153,12 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->last_rx = jiffies;
- stats->rx_bytes+=skb->len;
- stats->tx_bytes+=skb->len;
- stats->rx_packets++;
- stats->tx_packets++;
+ if (likely(stats)) {
+ stats->rx_bytes+=skb->len;
+ stats->tx_bytes+=skb->len;
+ stats->rx_packets++;
+ stats->tx_packets++;
+ }
netif_rx(skb);
@@ -167,36 +170,35 @@ static struct net_device_stats *get_stats(struct net_device *dev)
return (struct net_device_stats *)dev->priv;
}
-/* Initialize the rest of the LOOPBACK device. */
-int __init loopback_init(struct net_device *dev)
-{
- dev->mtu = (16 * 1024) + 20 + 20 + 12;
- dev->hard_start_xmit = loopback_xmit;
- dev->hard_header = eth_header;
- dev->hard_header_cache = eth_header_cache;
- dev->header_cache_update= eth_header_cache_update;
- dev->hard_header_len = ETH_HLEN; /* 14 */
- dev->addr_len = ETH_ALEN; /* 6 */
- dev->tx_queue_len = 0;
- dev->type = ARPHRD_LOOPBACK; /* 0x0001 */
- dev->rebuild_header = eth_rebuild_header;
- dev->flags = IFF_LOOPBACK;
- dev->features = NETIF_F_SG|NETIF_F_FRAGLIST|NETIF_F_NO_CSUM|NETIF_F_HIGHDMA;
-
- /* Current netfilter will die with oom linearizing large skbs,
- * however this will be cured before 2.5.x is done.
- */
- dev->features |= NETIF_F_TSO;
-
- dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_device_stats));
- dev->get_stats = get_stats;
+struct net_device loopback_dev = {
+ .name = "lo",
+ .mtu = (16 * 1024) + 20 + 20 + 12,
+ .hard_start_xmit = loopback_xmit,
+ .hard_header = eth_header,
+ .hard_header_cache = eth_header_cache,
+ .header_cache_update = eth_header_cache_update,
+ .hard_header_len = ETH_HLEN, /* 14 */
+ .addr_len = ETH_ALEN, /* 6 */
+ .tx_queue_len = 0,
+ .type = ARPHRD_LOOPBACK, /* 0x0001*/
+ .rebuild_header = eth_rebuild_header,
+ .flags = IFF_LOOPBACK,
+ .features = NETIF_F_SG|NETIF_F_FRAGLIST
+ |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA|NETIF_F_TSO,
+};
- /*
- * Fill in the generic fields of the device structure.
- */
-
- return(0);
+/* Setup and register the of the LOOPBACK device. */
+int __init loopback_init(void)
+{
+ struct net_device_stats *stats;
+
+ /* Can survive without statistics */
+ stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
+ if (stats) {
+ memset(stats, 0, sizeof(struct net_device_stats));
+ loopback_dev.priv = stats;
+ loopback_dev.get_stats = &get_stats;
+ }
+
+ return register_netdev(&loopback_dev);
};
diff --git a/net/core/dev.c b/net/core/dev.c
index 1ac07dc5077e..8a598f7f300c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2981,7 +2981,6 @@ int unregister_netdevice(struct net_device *dev)
*/
static int __init net_dev_init(void)
{
- struct net_device *dev, **dp;
int i, rc = -ENOMEM;
BUG_ON(!dev_boot_phase);
@@ -3027,75 +3026,6 @@ static int __init net_dev_init(void)
add_timer(&samp_timer);
#endif
- /*
- * Add the devices.
- * If the call to dev->init fails, the dev is removed
- * from the chain disconnecting the device until the
- * next reboot.
- *
- * NB At boot phase networking is dead. No locking is required.
- * But we still preserve dev_base_lock for sanity.
- */
-
- dp = &dev_base;
- while ((dev = *dp) != NULL) {
- spin_lock_init(&dev->queue_lock);
- spin_lock_init(&dev->xmit_lock);
-#ifdef CONFIG_NET_FASTROUTE
- dev->fastpath_lock = RW_LOCK_UNLOCKED;
-#endif
- dev->xmit_lock_owner = -1;
- dev->iflink = -1;
- dev_hold(dev);
-
- /*
- * Allocate name. If the init() fails
- * the name will be reissued correctly.
- */
- if (strchr(dev->name, '%'))
- dev_alloc_name(dev, dev->name);
-
- /*
- * Check boot time settings for the device.
- */
- netdev_boot_setup_check(dev);
-
- if ( (dev->init && dev->init(dev)) ||
- netdev_register_sysfs(dev) ) {
- /*
- * It failed to come up. It will be unhooked later.
- * dev_alloc_name can now advance to next suitable
- * name that is checked next.
- */
- dp = &dev->next;
- } else {
- dp = &dev->next;
- dev->ifindex = dev_new_index();
- dev->reg_state = NETREG_REGISTERED;
- if (dev->iflink == -1)
- dev->iflink = dev->ifindex;
- if (!dev->rebuild_header)
- dev->rebuild_header = default_rebuild_header;
- dev_init_scheduler(dev);
- set_bit(__LINK_STATE_PRESENT, &dev->state);
- }
- }
-
- /*
- * Unhook devices that failed to come up
- */
- dp = &dev_base;
- while ((dev = *dp) != NULL) {
- if (dev->reg_state != NETREG_REGISTERED) {
- write_lock_bh(&dev_base_lock);
- *dp = dev->next;
- write_unlock_bh(&dev_base_lock);
- dev_put(dev);
- } else {
- dp = &dev->next;
- }
- }
-
dev_boot_phase = 0;
probe_old_netdevs();