aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/loopback.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/loopback.c')
-rw-r--r--drivers/net/loopback.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 588092e13186..4b6f7b2abea5 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -202,44 +202,60 @@ static const struct ethtool_ops loopback_ethtool_ops = {
202 * The loopback device is special. There is only one instance and 202 * The loopback device is special. There is only one instance and
203 * it is statically allocated. Don't do this for other devices. 203 * it is statically allocated. Don't do this for other devices.
204 */ 204 */
205struct net_device __loopback_dev = { 205static void loopback_setup(struct net_device *dev)
206 .name = "lo", 206{
207 .get_stats = &get_stats, 207 dev->get_stats = &get_stats;
208 .mtu = (16 * 1024) + 20 + 20 + 12, 208 dev->mtu = (16 * 1024) + 20 + 20 + 12;
209 .hard_start_xmit = loopback_xmit, 209 dev->hard_start_xmit = loopback_xmit;
210 .hard_header = eth_header, 210 dev->hard_header = eth_header;
211 .hard_header_cache = eth_header_cache, 211 dev->hard_header_cache = eth_header_cache;
212 .header_cache_update = eth_header_cache_update, 212 dev->header_cache_update = eth_header_cache_update;
213 .hard_header_len = ETH_HLEN, /* 14 */ 213 dev->hard_header_len = ETH_HLEN; /* 14 */
214 .addr_len = ETH_ALEN, /* 6 */ 214 dev->addr_len = ETH_ALEN; /* 6 */
215 .tx_queue_len = 0, 215 dev->tx_queue_len = 0;
216 .type = ARPHRD_LOOPBACK, /* 0x0001*/ 216 dev->type = ARPHRD_LOOPBACK; /* 0x0001*/
217 .rebuild_header = eth_rebuild_header, 217 dev->rebuild_header = eth_rebuild_header;
218 .flags = IFF_LOOPBACK, 218 dev->flags = IFF_LOOPBACK;
219 .features = NETIF_F_SG | NETIF_F_FRAGLIST 219 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
220#ifdef LOOPBACK_TSO 220#ifdef LOOPBACK_TSO
221 | NETIF_F_TSO 221 | NETIF_F_TSO
222#endif 222#endif
223 | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA 223 | NETIF_F_NO_CSUM
224 | NETIF_F_LLTX 224 | NETIF_F_HIGHDMA
225 | NETIF_F_NETNS_LOCAL, 225 | NETIF_F_LLTX
226 .ethtool_ops = &loopback_ethtool_ops, 226 | NETIF_F_NETNS_LOCAL,
227 .nd_net = &init_net, 227 dev->ethtool_ops = &loopback_ethtool_ops;
228}; 228}
229
230struct net_device *loopback_dev = &__loopback_dev;
231 229
232/* Setup and register the loopback device. */ 230/* Setup and register the loopback device. */
233static int __init loopback_init(void) 231static int __init loopback_init(void)
234{ 232{
235 int err = register_netdev(loopback_dev); 233 struct net_device *dev;
234 int err;
235
236 err = -ENOMEM;
237 dev = alloc_netdev(0, "lo", loopback_setup);
238 if (!dev)
239 goto out;
236 240
241 err = register_netdev(dev);
237 if (err) 242 if (err)
238 panic("loopback: Failed to register netdevice: %d\n", err); 243 goto out_free_netdev;
239 244
245 err = 0;
246 loopback_dev = dev;
247
248out:
249 if (err)
250 panic("loopback: Failed to register netdevice: %d\n", err);
240 return err; 251 return err;
241};
242 252
243module_init(loopback_init); 253out_free_netdev:
254 free_netdev(dev);
255 goto out;
256}
257
258fs_initcall(loopback_init);
244 259
260struct net_device *loopback_dev;
245EXPORT_SYMBOL(loopback_dev); 261EXPORT_SYMBOL(loopback_dev);