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: Benjamin Herrenschmidt <benh@kernel.crashing.org> Tested-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2950e95292
commit
937f1ba56b
|
@ -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 */
|
||||
|
|
|
@ -214,6 +214,8 @@ struct mal_instance {
|
|||
int index;
|
||||
spinlock_t lock;
|
||||
|
||||
struct net_device dummy_dev;
|
||||
|
||||
unsigned int features;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -4430,6 +4430,45 @@ err_uninit:
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue