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

Commit 10c56b8d authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ibmvnic-Clean-up-net-close-and-fix-reset-bug'



Thomas Falcon says:

====================
ibmvnic: Clean up net close and fix reset bug

This patch set cleans up and reorganizes the driver's net_device
close function and leverages that to fix up a bug that can occur
during some device resets. Some reset cases require the backing
adapter to be disabled before continuing, but other cases, such as
during a device failover or partition migration, do not require this
step. Since the device will not be initialized at this stage and
its command-processing queue is closed, do not send the request to
disable the device as it could result in an error or timeout
disrupting the reset.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 46e371f0 18b8d6bb
Loading
Loading
Loading
Loading
+23 −25
Original line number Diff line number Diff line
@@ -1143,14 +1143,11 @@ static void clean_tx_pools(struct ibmvnic_adapter *adapter)
	}
}

static int __ibmvnic_close(struct net_device *netdev)
static void ibmvnic_cleanup(struct net_device *netdev)
{
	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
	int rc = 0;
	int i;

	adapter->state = VNIC_CLOSING;

	/* ensure that transmissions are stopped if called by do_reset */
	if (adapter->resetting)
		netif_tx_disable(netdev);
@@ -1162,30 +1159,16 @@ static int __ibmvnic_close(struct net_device *netdev)
	if (adapter->tx_scrq) {
		for (i = 0; i < adapter->req_tx_queues; i++)
			if (adapter->tx_scrq[i]->irq) {
				netdev_dbg(adapter->netdev,
				netdev_dbg(netdev,
					   "Disabling tx_scrq[%d] irq\n", i);
				disable_irq(adapter->tx_scrq[i]->irq);
			}
	}

	rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
	if (rc)
		return rc;

	if (adapter->rx_scrq) {
		for (i = 0; i < adapter->req_rx_queues; i++) {
			int retries = 10;

			while (pending_scrq(adapter, adapter->rx_scrq[i])) {
				retries--;
				mdelay(100);

				if (retries == 0)
					break;
			}

			if (adapter->rx_scrq[i]->irq) {
				netdev_dbg(adapter->netdev,
				netdev_dbg(netdev,
					   "Disabling rx_scrq[%d] irq\n", i);
				disable_irq(adapter->rx_scrq[i]->irq);
			}
@@ -1193,8 +1176,20 @@ static int __ibmvnic_close(struct net_device *netdev)
	}
	clean_rx_pools(adapter);
	clean_tx_pools(adapter);
	adapter->state = VNIC_CLOSED;
}

static int __ibmvnic_close(struct net_device *netdev)
{
	struct ibmvnic_adapter *adapter = netdev_priv(netdev);
	int rc = 0;

	adapter->state = VNIC_CLOSING;
	rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN);
	if (rc)
		return rc;
	ibmvnic_cleanup(netdev);
	adapter->state = VNIC_CLOSED;
	return 0;
}

static int ibmvnic_close(struct net_device *netdev)
@@ -1658,11 +1653,14 @@ static int do_reset(struct ibmvnic_adapter *adapter,
		rc = ibmvnic_reenable_crq_queue(adapter);
		if (rc)
			return 0;
	}

		ibmvnic_cleanup(netdev);
	} else if (rwi->reset_reason == VNIC_RESET_FAILOVER) {
		ibmvnic_cleanup(netdev);
	} else {
		rc = __ibmvnic_close(netdev);
		if (rc)
			return rc;
	}

	if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM ||
	    adapter->wait_for_reset) {