Skip to content

Commit ea22d51

Browse files
tlfalcondavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 88eb98a commit ea22d51

File tree

1 file changed

+103
-56
lines changed

1 file changed

+103
-56
lines changed

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 103 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
8989
static int ibmvnic_version = IBMVNIC_INITIAL_VERSION;
9090
static int ibmvnic_remove(struct vio_dev *);
9191
static void release_sub_crqs(struct ibmvnic_adapter *);
92+
static void release_sub_crqs_no_irqs(struct ibmvnic_adapter *);
9293
static int ibmvnic_reset_crq(struct ibmvnic_adapter *);
9394
static int ibmvnic_send_crq_init(struct ibmvnic_adapter *);
9495
static 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
12131214
goto reg_failed;
12141215
}
12151216

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-
12221217
scrq->adapter = adapter;
12231218
scrq->size = 4 * PAGE_SIZE / sizeof(*scrq->msgs);
12241219
scrq->cur = 0;
@@ -1231,12 +1226,6 @@ static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter
12311226

12321227
return scrq;
12331228

1234-
map_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));
12401229
reg_failed:
12411230
dma_unmap_single(dev, scrq->msg_token, 4 * PAGE_SIZE,
12421231
DMA_BIDIRECTIONAL);
@@ -1279,6 +1268,29 @@ static void release_sub_crqs(struct ibmvnic_adapter *adapter)
12791268
adapter->requested_caps = 0;
12801269
}
12811270

1271+
static 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+
12821294
static int disable_scrq_irq(struct ibmvnic_adapter *adapter,
12831295
struct ibmvnic_sub_crq_queue *scrq)
12841296
{
@@ -1398,6 +1410,66 @@ static irqreturn_t ibmvnic_interrupt_rx(int irq, void *instance)
13981410
return IRQ_HANDLED;
13991411
}
14001412

1413+
static 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+
1460+
req_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;
1465+
req_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+
14011473
static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
14021474
{
14031475
struct device *dev = &adapter->vdev->dev;
@@ -1406,8 +1478,7 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
14061478
union ibmvnic_crq crq;
14071479
int total_queues;
14081480
int more = 0;
1409-
int i, j;
1410-
int rc;
1481+
int i;
14111482

14121483
if (!retry) {
14131484
/* Sub-CRQ entries are 32 byte long */
@@ -1486,13 +1557,6 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
14861557
for (i = 0; i < adapter->req_tx_queues; i++) {
14871558
adapter->tx_scrq[i] = allqueues[i];
14881559
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-
}
14961560
}
14971561

14981562
adapter->rx_scrq = kcalloc(adapter->req_rx_queues,
@@ -1503,13 +1567,6 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
15031567
for (i = 0; i < adapter->req_rx_queues; i++) {
15041568
adapter->rx_scrq[i] = allqueues[i + adapter->req_tx_queues];
15051569
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-
}
15131570
}
15141571

15151572
memset(&crq, 0, sizeof(crq));
@@ -1562,15 +1619,6 @@ static void init_sub_crqs(struct ibmvnic_adapter *adapter, int retry)
15621619

15631620
return;
15641621

1565-
req_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;
1569-
req_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;
15741622
rx_failed:
15751623
kfree(adapter->tx_scrq);
15761624
adapter->tx_scrq = NULL;
@@ -2351,9 +2399,9 @@ static void handle_request_cap_rsp(union ibmvnic_crq *crq,
23512399
*req_value,
23522400
(long int)be32_to_cpu(crq->request_capability_rsp.
23532401
number), name);
2354-
release_sub_crqs(adapter);
2402+
release_sub_crqs_no_irqs(adapter);
23552403
*req_value = be32_to_cpu(crq->request_capability_rsp.number);
2356-
complete(&adapter->init_done);
2404+
init_sub_crqs(adapter, 1);
23572405
return;
23582406
default:
23592407
dev_err(dev, "Error %d in request cap rsp\n",
@@ -2662,7 +2710,7 @@ static void handle_query_cap_rsp(union ibmvnic_crq *crq,
26622710

26632711
out:
26642712
if (atomic_read(&adapter->running_cap_queries) == 0)
2665-
complete(&adapter->init_done);
2713+
init_sub_crqs(adapter, 0);
26662714
/* We're done querying the capabilities, initialize sub-crqs */
26672715
}
26682716

@@ -3560,6 +3608,7 @@ static const struct file_operations ibmvnic_dump_ops = {
35603608

35613609
static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
35623610
{
3611+
unsigned long timeout = msecs_to_jiffies(30000);
35633612
struct ibmvnic_adapter *adapter;
35643613
struct net_device *netdev;
35653614
unsigned char *mac_addr_p;
@@ -3638,43 +3687,41 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
36383687
ibmvnic_send_crq_init(adapter);
36393688

36403689
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;
36423692

36433693
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-
36503694
if (adapter->renegotiate) {
3651-
release_sub_crqs(adapter);
3695+
adapter->renegotiate = false;
3696+
release_sub_crqs_no_irqs(adapter);
36523697
send_cap_queries(adapter);
36533698

36543699
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;
36563703
}
36573704
} while (adapter->renegotiate);
36583705

3659-
/* if init_sub_crqs is partially successful, retry */
3660-
while (!adapter->tx_scrq || !adapter->rx_scrq) {
3661-
init_sub_crqs(adapter, 1);
3662-
3663-
reinit_completion(&adapter->init_done);
3664-
wait_for_completion(&adapter->init_done);
3706+
rc = init_sub_crq_irqs(adapter);
3707+
if (rc) {
3708+
dev_err(&dev->dev, "failed to initialize sub crq irqs\n");
3709+
goto free_debugfs;
36653710
}
36663711

36673712
netdev->real_num_tx_queues = adapter->req_tx_queues;
36683713

36693714
rc = register_netdev(netdev);
36703715
if (rc) {
36713716
dev_err(&dev->dev, "failed to register netdev rc=%d\n", rc);
3672-
goto free_debugfs;
3717+
goto free_sub_crqs;
36733718
}
36743719
dev_info(&dev->dev, "ibmvnic registered\n");
36753720

36763721
return 0;
36773722

3723+
free_sub_crqs:
3724+
release_sub_crqs(adapter);
36783725
free_debugfs:
36793726
if (adapter->debugfs_dir && !IS_ERR(adapter->debugfs_dir))
36803727
debugfs_remove_recursive(adapter->debugfs_dir);

0 commit comments

Comments
 (0)