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

Commit a3059b12 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

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: default avatarMichael Chan <mchan@broadcom.com>
Reviewed-by: default avatarBenjamin Li <benli@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 64c64608
Loading
Loading
Loading
Loading
+36 −13
Original line number Original line Diff line number Diff line
@@ -2393,22 +2393,46 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
	return 0;
	return 0;
}
}


static int cnic_start_hw(struct cnic_dev *dev)
static int cnic_register_netdev(struct cnic_dev *dev)
{
{
	struct cnic_local *cp = dev->cnic_priv;
	struct cnic_local *cp = dev->cnic_priv;
	struct cnic_eth_dev *ethdev = cp->ethdev;
	struct cnic_eth_dev *ethdev = cp->ethdev;
	int err;
	int err;


	if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
	if (!ethdev)
		return -EALREADY;
		return -ENODEV;

	if (ethdev->drv_state & CNIC_DRV_STATE_REGD)
		return 0;


	err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
	err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
	if (err) {
	if (err)
		printk(KERN_ERR PFX "%s: register_cnic failed\n",
		printk(KERN_ERR PFX "%s: register_cnic failed\n",
		       dev->netdev->name);
		       dev->netdev->name);
		goto err2;

	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)
{
	struct cnic_local *cp = dev->cnic_priv;
	struct cnic_eth_dev *ethdev = cp->ethdev;
	int err;

	if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
		return -EALREADY;

	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);
	}
	}