aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/ibm
diff options
context:
space:
mode:
authorThomas Falcon <tlfalcon@linux.vnet.ibm.com>2016-07-06 16:35:17 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-09 17:42:10 -0400
commitea22d51a7831b062978fcf07c3c5ac7ecbb6cbeb (patch)
tree795cdfad488a8a09a17b0c32c836395f7817fdf3 /drivers/net/ethernet/ibm
parent88eb98a0178219e1d6e9037b71d293f19b89eef2 (diff)
ibmvnic: simplify and improve driver probe function
This patch creates a function that handles sub-CRQ IRQ creation separately from sub-CRQ initialization. Another function is then needed to release sub-CRQ resources prior to sub-CRQ IRQ creation. These additions allow the driver probe function to be simplified, specifically during the VNIC Server login process. A timeout is also included while waiting for completion of the login process in case the VNIC Server is not available or some other error occurs. Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ibm')
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c159
1 files changed, 103 insertions, 56 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 79d2ab360805..52b0c07d3ca4 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -89,6 +89,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
89static int ibmvnic_version = IBMVNIC_INITIAL_VERSION; 89static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
90static int ibmvnic_remove(struct vio_dev *); 90static int ibmvnic_remove(struct vio_dev *);
91static void release_sub_crqs(struct ibmvnic_adapter *); 91static void release_sub_crqs(struct ibmvnic_adapter *);
92static void release_sub_crqs_no_irqs(struct ibmvnic_adapter *);
92static int ibmvnic_reset_crq(struct ibmvnic_adapter *); 93static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
93static int ibmvnic_send_crq_init(struct ibmvnic_adapter *); 94static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
94static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *); 95static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter *);
@@ -1213,12 +1214,6 @@ static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter
1213 goto reg_failed; 1214 goto reg_failed;
1214 } 1215 }
1215 1216
1216 scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
1217 if (scrq->irq == NO_IRQ) {
1218 dev_err(dev, "Error mapping irq\n");
1219 goto map_irq_failed;
1220 }
1221
1222 scrq->adapter = adapter; 1217 scrq->adapter = adapter;
1223 scrq->size = 4 * PAGE_SIZE / sizeof(*scrq->msgs); 1218 scrq->size = 4 * PAGE_SIZE / sizeof(*scrq->msgs);
1224 scrq->cur = 0; 1219 scrq->cur = 0;
@@ -1231,12 +1226,6 @@ static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter
1231 1226
1232 return scrq; 1227 return scrq;
1233 1228
1234map_irq_failed:
1235 do {
1236 rc = plpar_hcall_norets(H_FREE_SUB_CRQ,
1237 adapter->vdev->unit_address,
1238 scrq->crq_num);
1239 } while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
1240reg_failed: 1229reg_failed:
1241 dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE, 1230 dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
1242 DMA_BIDIRECTIONAL); 1231 DMA_BIDIRECTIONAL);
@@ -1279,6 +1268,29 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
1279 adapter->requested_caps = 0; 1268 adapter->requested_caps = 0;
1280} 1269}
1281 1270
1271static void release_sub_crqs_no_irqs(struct ibmvnic_adapter *adapter)
1272{
1273 int i;
1274
1275 if (adapter->tx_scrq) {
1276 for (i = 0; i < adapter->req_tx_queues; i++)
1277 if (adapter->tx_scrq[i])
1278 release_sub_crq_queue(adapter,
1279 adapter->tx_scrq[i]);
1280 adapter->tx_scrq = NULL;
1281 }
1282
1283 if (adapter->rx_scrq) {
1284 for (i = 0; i < adapter->req_rx_queues; i++)
1285 if (adapter->rx_scrq[i])
1286 release_sub_crq_queue(adapter,
1287 adapter->rx_scrq[i]);
1288 adapter->rx_scrq = NULL;
1289 }
1290
1291 adapter->requested_caps = 0;
1292}
1293
1282static int disable_scrq_irq(struct ibmvnic_adapter *adapter, 1294static int disable_scrq_irq(struct ibmvnic_adapter *adapter,
1283 struct ibmvnic_sub_crq_queue *scrq) 1295 struct ibmvnic_sub_crq_queue *scrq)
1284{ 1296{
@@ -1398,6 +1410,66 @@ static irqreturn_t ibmvnic_interrupt_rx(int irq, void *instance)
1398 return IRQ_HANDLED; 1410 return IRQ_HANDLED;
1399} 1411}
1400 1412
1413static int init_sub_crq_irqs(struct ibmvnic_adapter *adapter)
1414{
1415 struct device *dev = &adapter->vdev->dev;
1416 struct ibmvnic_sub_crq_queue *scrq;
1417 int i = 0, j = 0;
1418 int rc = 0;
1419
1420 for (i = 0; i < adapter->req_tx_queues; i++) {
1421 scrq = adapter->tx_scrq[i];
1422 scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
1423
1424 if (scrq->irq == NO_IRQ) {
1425 rc = -EINVAL;
1426 dev_err(dev, "Error mapping irq\n");
1427 goto req_tx_irq_failed;
1428 }
1429
1430 rc = request_irq(scrq->irq, ibmvnic_interrupt_tx,
1431 0, "ibmvnic_tx", scrq);
1432
1433 if (rc) {
1434 dev_err(dev, "Couldn't register tx irq 0x%x. rc=%d\n",
1435 scrq->irq, rc);
1436 irq_dispose_mapping(scrq->irq);
1437 goto req_rx_irq_failed;
1438 }
1439 }
1440
1441 for (i = 0; i < adapter->req_rx_queues; i++) {
1442 scrq = adapter->rx_scrq[i];
1443 scrq->irq = irq_create_mapping(NULL, scrq->hw_irq);
1444 if (scrq->irq == NO_IRQ) {
1445 rc = -EINVAL;
1446 dev_err(dev, "Error mapping irq\n");
1447 goto req_rx_irq_failed;
1448 }
1449 rc = request_irq(scrq->irq, ibmvnic_interrupt_rx,
1450 0, "ibmvnic_rx", scrq);
1451 if (rc) {
1452 dev_err(dev, "Couldn't register rx irq 0x%x. rc=%d\n",
1453 scrq->irq, rc);
1454 irq_dispose_mapping(scrq->irq);
1455 goto req_rx_irq_failed;
1456 }
1457 }
1458 return rc;
1459
1460req_rx_irq_failed:
1461 for (j = 0; j < i; j++)
1462 free_irq(adapter->rx_scrq[j]->irq, adapter->rx_scrq[j]);
1463 irq_dispose_mapping(adapter->rx_scrq[j]->irq);
1464 i = adapter->req_tx_queues;
1465req_tx_irq_failed:
1466 for (j = 0; j < i; j++)
1467 free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]);
1468 irq_dispose_mapping(adapter->rx_scrq[j]->irq);
1469 release_sub_crqs_no_irqs(adapter);
1470 return rc;
1471}
1472
1401static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry) 1473static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
1402{ 1474{
1403 struct device *dev = &adapter->vdev->dev; 1475 struct device *dev = &adapter->vdev->dev;
@@ -1406,8 +1478,7 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
1406 union ibmvnic_crq crq; 1478 union ibmvnic_crq crq;
1407 int total_queues; 1479 int total_queues;
1408 int more = 0; 1480 int more = 0;
1409 int i, j; 1481 int i;
1410 int rc;
1411 1482
1412 if (!retry) { 1483 if (!retry) {
1413 /* Sub-CRQ entries are 32 byte long */ 1484 /* Sub-CRQ entries are 32 byte long */
@@ -1486,13 +1557,6 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
1486 for (i = 0; i < adapter->req_tx_queues; i++) { 1557 for (i = 0; i < adapter->req_tx_queues; i++) {
1487 adapter->tx_scrq[i] = allqueues[i]; 1558 adapter->tx_scrq[i] = allqueues[i];
1488 adapter->tx_scrq[i]->pool_index = i; 1559 adapter->tx_scrq[i]->pool_index = i;
1489 rc = request_irq(adapter->tx_scrq[i]->irq, ibmvnic_interrupt_tx,
1490 0, "ibmvnic_tx", adapter->tx_scrq[i]);
1491 if (rc) {
1492 dev_err(dev, "Couldn't register tx irq 0x%x. rc=%d\n",
1493 adapter->tx_scrq[i]->irq, rc);
1494 goto req_tx_irq_failed;
1495 }
1496 } 1560 }
1497 1561
1498 adapter->rx_scrq = kcalloc(adapter->req_rx_queues, 1562 adapter->rx_scrq = kcalloc(adapter->req_rx_queues,
@@ -1503,13 +1567,6 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
1503 for (i = 0; i < adapter->req_rx_queues; i++) { 1567 for (i = 0; i < adapter->req_rx_queues; i++) {
1504 adapter->rx_scrq[i] = allqueues[i + adapter->req_tx_queues]; 1568 adapter->rx_scrq[i] = allqueues[i + adapter->req_tx_queues];
1505 adapter->rx_scrq[i]->scrq_num = i; 1569 adapter->rx_scrq[i]->scrq_num = i;
1506 rc = request_irq(adapter->rx_scrq[i]->irq, ibmvnic_interrupt_rx,
1507 0, "ibmvnic_rx", adapter->rx_scrq[i]);
1508 if (rc) {
1509 dev_err(dev, "Couldn't register rx irq 0x%x. rc=%d\n",
1510 adapter->rx_scrq[i]->irq, rc);
1511 goto req_rx_irq_failed;
1512 }
1513 } 1570 }
1514 1571
1515 memset(&crq, 0, sizeof(crq)); 1572 memset(&crq, 0, sizeof(crq));
@@ -1562,15 +1619,6 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
1562 1619
1563 return; 1620 return;
1564 1621
1565req_rx_irq_failed:
1566 for (j = 0; j < i; j++)
1567 free_irq(adapter->rx_scrq[j]->irq, adapter->rx_scrq[j]);
1568 i = adapter->req_tx_queues;
1569req_tx_irq_failed:
1570 for (j = 0; j < i; j++)
1571 free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]);
1572 kfree(adapter->rx_scrq);
1573 adapter->rx_scrq = NULL;
1574rx_failed: 1622rx_failed:
1575 kfree(adapter->tx_scrq); 1623 kfree(adapter->tx_scrq);
1576 adapter->tx_scrq = NULL; 1624 adapter->tx_scrq = NULL;
@@ -2351,9 +2399,9 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq,
2351 *req_value, 2399 *req_value,
2352 (long int)be32_to_cpu(crq->request_capability_rsp. 2400 (long int)be32_to_cpu(crq->request_capability_rsp.
2353 number), name); 2401 number), name);
2354 release_sub_crqs(adapter); 2402 release_sub_crqs_no_irqs(adapter);
2355 *req_value = be32_to_cpu(crq->request_capability_rsp.number); 2403 *req_value = be32_to_cpu(crq->request_capability_rsp.number);
2356 complete(&adapter->init_done); 2404 init_sub_crqs(adapter, 1);
2357 return; 2405 return;
2358 default: 2406 default:
2359 dev_err(dev, "Error %d in request cap rsp\n", 2407 dev_err(dev, "Error %d in request cap rsp\n",
@@ -2662,7 +2710,7 @@ static void handle_query_cap_rsp(union ibmvnic_crq *crq,
2662 2710
2663out: 2711out:
2664 if (atomic_read(&adapter->running_cap_queries) == 0) 2712 if (atomic_read(&adapter->running_cap_queries) == 0)
2665 complete(&adapter->init_done); 2713 init_sub_crqs(adapter, 0);
2666 /* We're done querying the capabilities, initialize sub-crqs */ 2714 /* We're done querying the capabilities, initialize sub-crqs */
2667} 2715}
2668 2716
@@ -3560,6 +3608,7 @@ static const struct file_operations ibmvnic_dump_ops = {
3560 3608
3561static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) 3609static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
3562{ 3610{
3611 unsigned long timeout = msecs_to_jiffies(30000);
3563 struct ibmvnic_adapter *adapter; 3612 struct ibmvnic_adapter *adapter;
3564 struct net_device *netdev; 3613 struct net_device *netdev;
3565 unsigned char *mac_addr_p; 3614 unsigned char *mac_addr_p;
@@ -3638,30 +3687,26 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
3638 ibmvnic_send_crq_init(adapter); 3687 ibmvnic_send_crq_init(adapter);
3639 3688
3640 init_completion(&adapter->init_done); 3689 init_completion(&adapter->init_done);
3641 wait_for_completion(&adapter->init_done); 3690 if (!wait_for_completion_timeout(&adapter->init_done, timeout))
3691 return 0;
3642 3692
3643 do { 3693 do {
3644 adapter->renegotiate = false;
3645
3646 init_sub_crqs(adapter, 0);
3647 reinit_completion(&adapter->init_done);
3648 wait_for_completion(&adapter->init_done);
3649
3650 if (adapter->renegotiate) { 3694 if (adapter->renegotiate) {
3651 release_sub_crqs(adapter); 3695 adapter->renegotiate = false;
3696 release_sub_crqs_no_irqs(adapter);
3652 send_cap_queries(adapter); 3697 send_cap_queries(adapter);
3653 3698
3654 reinit_completion(&adapter->init_done); 3699 reinit_completion(&adapter->init_done);
3655 wait_for_completion(&adapter->init_done); 3700 if (!wait_for_completion_timeout(&adapter->init_done,
3701 timeout))
3702 return 0;
3656 } 3703 }
3657 } while (adapter->renegotiate); 3704 } while (adapter->renegotiate);
3658 3705
3659 /* if init_sub_crqs is partially successful, retry */ 3706 rc = init_sub_crq_irqs(adapter);
3660 while (!adapter->tx_scrq || !adapter->rx_scrq) { 3707 if (rc) {
3661 init_sub_crqs(adapter, 1); 3708 dev_err(&dev->dev, "failed to initialize sub crq irqs\n");
3662 3709 goto free_debugfs;
3663 reinit_completion(&adapter->init_done);
3664 wait_for_completion(&adapter->init_done);
3665 } 3710 }
3666 3711
3667 netdev->real_num_tx_queues = adapter->req_tx_queues; 3712 netdev->real_num_tx_queues = adapter->req_tx_queues;
@@ -3669,12 +3714,14 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
3669 rc = register_netdev(netdev); 3714 rc = register_netdev(netdev);
3670 if (rc) { 3715 if (rc) {
3671 dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc); 3716 dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
3672 goto free_debugfs; 3717 goto free_sub_crqs;
3673 } 3718 }
3674 dev_info(&dev->dev, "ibmvnic registered\n"); 3719 dev_info(&dev->dev, "ibmvnic registered\n");
3675 3720
3676 return 0; 3721 return 0;
3677 3722
3723free_sub_crqs:
3724 release_sub_crqs(adapter);
3678free_debugfs: 3725free_debugfs:
3679 if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir)) 3726 if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir))
3680 debugfs_remove_recursive(adapter->debugfs_dir); 3727 debugfs_remove_recursive(adapter->debugfs_dir);