summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorNathan Fontenot <nfont@linux.vnet.ibm.com>2017-05-26 10:31:12 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-26 15:32:47 -0400
commit57a49436f4e8a76a9125c44d084d12b2c6e6206c (patch)
tree81fe2c2e092e06277cf91b455591f8290edee0e7 /drivers
parent8c0543adca2bb17808e46a24eb6e6247181a10b1 (diff)
downloadlinux-57a49436f4e8a76a9125c44d084d12b2c6e6206c.tar.bz2
ibmvnic: Reset sub-crqs during driver reset
When the ibmvnic driver is resetting, we can just reset the sub crqs instead of releasing all of their resources and re-allocting them. Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 5661a043f5e5..8dcf58088178 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -1320,8 +1320,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
*/
adapter->state = VNIC_PROBED;
- release_sub_crqs(adapter);
-
rc = ibmvnic_init(adapter);
if (rc)
return 0;
@@ -1728,6 +1726,45 @@ static const struct ethtool_ops ibmvnic_ethtool_ops = {
/* Routines for managing CRQs/sCRQs */
+static int reset_one_sub_crq_queue(struct ibmvnic_adapter *adapter,
+ struct ibmvnic_sub_crq_queue *scrq)
+{
+ int rc;
+
+ if (scrq->irq) {
+ free_irq(scrq->irq, scrq);
+ irq_dispose_mapping(scrq->irq);
+ scrq->irq = 0;
+ }
+
+ memset(scrq->msgs, 0, 2 * PAGE_SIZE);
+ scrq->cur = 0;
+
+ rc = h_reg_sub_crq(adapter->vdev->unit_address, scrq->msg_token,
+ 4 * PAGE_SIZE, &scrq->crq_num, &scrq->hw_irq);
+ return rc;
+}
+
+static int reset_sub_crq_queues(struct ibmvnic_adapter *adapter)
+{
+ int i, rc;
+
+ for (i = 0; i < adapter->req_tx_queues; i++) {
+ rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]);
+ if (rc)
+ return rc;
+ }
+
+ for (i = 0; i < adapter->req_rx_queues; i++) {
+ rc = reset_one_sub_crq_queue(adapter, adapter->rx_scrq[i]);
+ if (rc)
+ return rc;
+ }
+
+ rc = init_sub_crq_irqs(adapter);
+ return rc;
+}
+
static void release_sub_crq_queue(struct ibmvnic_adapter *adapter,
struct ibmvnic_sub_crq_queue *scrq)
{
@@ -3607,7 +3644,10 @@ static int ibmvnic_init(struct ibmvnic_adapter *adapter)
return -1;
}
- rc = init_sub_crqs(adapter);
+ if (adapter->resetting)
+ rc = reset_sub_crq_queues(adapter);
+ else
+ rc = init_sub_crqs(adapter);
if (rc) {
dev_err(dev, "Initialization of sub crqs failed\n");
release_crq_queue(adapter);