mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
cnic: Refine registration with bnx2.
Register and unregister with bnx2 during NETDEV_UP and NETDEV_DOWN events. This simplifies the sequence of events and allows locking fixes in the next patch. Signed-off-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Benjamin Li <benli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
64c6460875
commit
a3059b12ad
1 changed files with 37 additions and 14 deletions
|
@ -2393,6 +2393,37 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cnic_register_netdev(struct cnic_dev *dev)
|
||||||
|
{
|
||||||
|
struct cnic_local *cp = dev->cnic_priv;
|
||||||
|
struct cnic_eth_dev *ethdev = cp->ethdev;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!ethdev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (ethdev->drv_state & CNIC_DRV_STATE_REGD)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
|
||||||
|
if (err)
|
||||||
|
printk(KERN_ERR PFX "%s: register_cnic failed\n",
|
||||||
|
dev->netdev->name);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cnic_unregister_netdev(struct cnic_dev *dev)
|
||||||
|
{
|
||||||
|
struct cnic_local *cp = dev->cnic_priv;
|
||||||
|
struct cnic_eth_dev *ethdev = cp->ethdev;
|
||||||
|
|
||||||
|
if (!ethdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ethdev->drv_unregister_cnic(dev->netdev);
|
||||||
|
}
|
||||||
|
|
||||||
static int cnic_start_hw(struct cnic_dev *dev)
|
static int cnic_start_hw(struct cnic_dev *dev)
|
||||||
{
|
{
|
||||||
struct cnic_local *cp = dev->cnic_priv;
|
struct cnic_local *cp = dev->cnic_priv;
|
||||||
|
@ -2402,13 +2433,6 @@ static int cnic_start_hw(struct cnic_dev *dev)
|
||||||
if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
|
if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
|
|
||||||
err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
|
|
||||||
if (err) {
|
|
||||||
printk(KERN_ERR PFX "%s: register_cnic failed\n",
|
|
||||||
dev->netdev->name);
|
|
||||||
goto err2;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->regview = ethdev->io_base;
|
dev->regview = ethdev->io_base;
|
||||||
cp->chip_id = ethdev->chip_id;
|
cp->chip_id = ethdev->chip_id;
|
||||||
pci_dev_get(dev->pcidev);
|
pci_dev_get(dev->pcidev);
|
||||||
|
@ -2438,18 +2462,13 @@ static int cnic_start_hw(struct cnic_dev *dev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err1:
|
err1:
|
||||||
ethdev->drv_unregister_cnic(dev->netdev);
|
|
||||||
cp->free_resc(dev);
|
cp->free_resc(dev);
|
||||||
pci_dev_put(dev->pcidev);
|
pci_dev_put(dev->pcidev);
|
||||||
err2:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
|
static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
|
||||||
{
|
{
|
||||||
struct cnic_local *cp = dev->cnic_priv;
|
|
||||||
struct cnic_eth_dev *ethdev = cp->ethdev;
|
|
||||||
|
|
||||||
cnic_disable_bnx2_int_sync(dev);
|
cnic_disable_bnx2_int_sync(dev);
|
||||||
|
|
||||||
cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
|
cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
|
||||||
|
@ -2461,8 +2480,6 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
|
||||||
cnic_setup_5709_context(dev, 0);
|
cnic_setup_5709_context(dev, 0);
|
||||||
cnic_free_irq(dev);
|
cnic_free_irq(dev);
|
||||||
|
|
||||||
ethdev->drv_unregister_cnic(dev->netdev);
|
|
||||||
|
|
||||||
cnic_free_resc(dev);
|
cnic_free_resc(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2646,6 +2663,10 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
|
||||||
else if (event == NETDEV_UNREGISTER)
|
else if (event == NETDEV_UNREGISTER)
|
||||||
cnic_ulp_exit(dev);
|
cnic_ulp_exit(dev);
|
||||||
else if (event == NETDEV_UP) {
|
else if (event == NETDEV_UP) {
|
||||||
|
if (cnic_register_netdev(dev) != 0) {
|
||||||
|
cnic_put(dev);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
mutex_lock(&cnic_lock);
|
mutex_lock(&cnic_lock);
|
||||||
if (!cnic_start_hw(dev))
|
if (!cnic_start_hw(dev))
|
||||||
cnic_ulp_start(dev);
|
cnic_ulp_start(dev);
|
||||||
|
@ -2672,6 +2693,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
|
||||||
cnic_ulp_stop(dev);
|
cnic_ulp_stop(dev);
|
||||||
cnic_stop_hw(dev);
|
cnic_stop_hw(dev);
|
||||||
mutex_unlock(&cnic_lock);
|
mutex_unlock(&cnic_lock);
|
||||||
|
cnic_unregister_netdev(dev);
|
||||||
} else if (event == NETDEV_UNREGISTER) {
|
} else if (event == NETDEV_UNREGISTER) {
|
||||||
write_lock(&cnic_dev_lock);
|
write_lock(&cnic_dev_lock);
|
||||||
list_del_init(&dev->list);
|
list_del_init(&dev->list);
|
||||||
|
@ -2703,6 +2725,7 @@ static void cnic_release(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
cnic_ulp_exit(dev);
|
cnic_ulp_exit(dev);
|
||||||
|
cnic_unregister_netdev(dev);
|
||||||
list_del_init(&dev->list);
|
list_del_init(&dev->list);
|
||||||
cnic_free_dev(dev);
|
cnic_free_dev(dev);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue