Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 937f1ba5 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by David S. Miller
Browse files

net: Add init_dummy_netdev() and fix EMAC driver using it



This adds an init_dummy_netdev() function that gets a network device
structure (allocation and lifetime entirely under caller's control) and
initialize the minimum amount of fields so it can be used to schedule
NAPI polls without registering a full blown interface. This is to be
used by drivers that need to tie several hardware interfaces to a single
NAPI poll scheduler due to HW limitations.

It also updates the ibm_newemac driver to use that, this fixing the
oops on 2.6.29 due to passing NULL as "dev" to netif_napi_add()

Symbol is exported GPL only a I don't think we want binary drivers doing
that sort of acrobatics (if we want them at all).

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tested-by: default avatarGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2950e952
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -613,7 +613,9 @@ static int __devinit mal_probe(struct of_device *ofdev,
	INIT_LIST_HEAD(&mal->list);
	spin_lock_init(&mal->lock);

	netif_napi_add(NULL, &mal->napi, mal_poll,
	init_dummy_netdev(&mal->dummy_dev);

	netif_napi_add(&mal->dummy_dev, &mal->napi, mal_poll,
		       CONFIG_IBM_NEW_EMAC_POLL_WEIGHT);

	/* Load power-on reset defaults */
+2 −0
Original line number Diff line number Diff line
@@ -214,6 +214,8 @@ struct mal_instance {
	int			index;
	spinlock_t		lock;

	struct net_device	dummy_dev;

	unsigned int features;
};

+3 −0
Original line number Diff line number Diff line
@@ -795,6 +795,7 @@ struct net_device
	       NETREG_UNREGISTERING,	/* called unregister_netdevice */
	       NETREG_UNREGISTERED,	/* completed unregister todo */
	       NETREG_RELEASED,		/* called free_netdev */
	       NETREG_DUMMY,		/* dummy device for NAPI poll */
	} reg_state;

	/* Called from unregister, can be used to call free_netdev */
@@ -1077,6 +1078,8 @@ extern void free_netdev(struct net_device *dev);
extern void		synchronize_net(void);
extern int 		register_netdevice_notifier(struct notifier_block *nb);
extern int		unregister_netdevice_notifier(struct notifier_block *nb);
extern int		init_dummy_netdev(struct net_device *dev);

extern int call_netdevice_notifiers(unsigned long val, struct net_device *dev);
extern struct net_device	*dev_get_by_index(struct net *net, int ifindex);
extern struct net_device	*__dev_get_by_index(struct net *net, int ifindex);
+39 −0
Original line number Diff line number Diff line
@@ -4430,6 +4430,45 @@ int register_netdevice(struct net_device *dev)
	goto out;
}

/**
 *	init_dummy_netdev	- init a dummy network device for NAPI
 *	@dev: device to init
 *
 *	This takes a network device structure and initialize the minimum
 *	amount of fields so it can be used to schedule NAPI polls without
 *	registering a full blown interface. This is to be used by drivers
 *	that need to tie several hardware interfaces to a single NAPI
 *	poll scheduler due to HW limitations.
 */
int init_dummy_netdev(struct net_device *dev)
{
	/* Clear everything. Note we don't initialize spinlocks
	 * are they aren't supposed to be taken by any of the
	 * NAPI code and this dummy netdev is supposed to be
	 * only ever used for NAPI polls
	 */
	memset(dev, 0, sizeof(struct net_device));

	/* make sure we BUG if trying to hit standard
	 * register/unregister code path
	 */
	dev->reg_state = NETREG_DUMMY;

	/* initialize the ref count */
	atomic_set(&dev->refcnt, 1);

	/* NAPI wants this */
	INIT_LIST_HEAD(&dev->napi_list);

	/* a dummy interface is started by default */
	set_bit(__LINK_STATE_PRESENT, &dev->state);
	set_bit(__LINK_STATE_START, &dev->state);

	return 0;
}
EXPORT_SYMBOL_GPL(init_dummy_netdev);


/**
 *	register_netdev	- register a network device
 *	@dev: device to register