int enic_dev_enable(struct enic *enic)
{
- int err;
+ int err = 0;
spin_lock_bh(&enic->devcmd_lock);
- err = vnic_dev_enable_wait(enic->vdev);
+ if (enic->enable_count == 0)
+ err = vnic_dev_enable_wait(enic->vdev);
+ if (!err)
+ enic->enable_count++;
spin_unlock_bh(&enic->devcmd_lock);
return err;
int enic_dev_disable(struct enic *enic)
{
- int err;
+ int err = 0;
spin_lock_bh(&enic->devcmd_lock);
- err = vnic_dev_disable(enic->vdev);
+ if (enic->enable_count == 0) {
+ spin_unlock_bh(&enic->devcmd_lock);
+ return 0;
+ }
+ enic->enable_count--;
+ if (enic->enable_count == 0)
+ err = vnic_dev_disable(enic->vdev);
spin_unlock_bh(&enic->devcmd_lock);
return err;
if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
for (i = 0; i < enic->wq_count; i++)
napi_enable(&enic->napi[enic_cq_wq(enic, i)]);
- enic_dev_enable(enic);
+ err = enic_dev_enable(enic);
+ if (err) {
+ netdev_err(netdev, "Failed to enable device: %d\n", err);
+ goto err_out_dev_enable;
+ }
for (i = 0; i < enic->intr_count; i++)
vnic_intr_unmask(&enic->intr[i]);
return 0;
+err_out_dev_enable:
+ for (i = 0; i < enic->rq_count; i++)
+ napi_disable(&enic->napi[i]);
+ if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
+ for (i = 0; i < enic->wq_count; i++)
+ napi_disable(&enic->napi[enic_cq_wq(enic, i)]);
+ netif_tx_disable(netdev);
+ if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
+ enic_dev_del_station_addr(enic);
+ for (i = 0; i < enic->wq_count; i++)
+ vnic_wq_disable(&enic->wq[i].vwq);
err_out_free_rq:
for (i = 0; i < enic->rq_count; i++) {
ret = vnic_rq_disable(&enic->rq[i].vrq);