In some cases, the device or firmware may be busy when the
driver attempts to perform the CRQ initialization handshake.
If the partner is busy, the hypervisor will return the H_CLOSED
return code. The aim of this patch is that, if the device is not
ready, to query the device a number of times, with a small wait
time in between queries. If all initialization requests fail,
the driver will remain in a dormant state, awaiting a signal
from the device that it is ready for operation.

Signed-off-by: Thomas Falcon <tlfal...@linux.ibm.com>
---
 drivers/net/ethernet/ibm/ibmvnic.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 86a83e5..9943586 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3566,14 +3566,31 @@ static int ibmvnic_send_crq(struct ibmvnic_adapter 
*adapter,
 
 static int ibmvnic_send_crq_init(struct ibmvnic_adapter *adapter)
 {
+       struct device *dev = &adapter->vdev->dev;
        union ibmvnic_crq crq;
+       int retries = 100;
+       int rc;
 
        memset(&crq, 0, sizeof(crq));
        crq.generic.first = IBMVNIC_CRQ_INIT_CMD;
        crq.generic.cmd = IBMVNIC_CRQ_INIT;
        netdev_dbg(adapter->netdev, "Sending CRQ init\n");
 
-       return ibmvnic_send_crq(adapter, &crq);
+       do {
+               rc = ibmvnic_send_crq(adapter, &crq);
+               if (rc != H_CLOSED)
+                       break;
+               retries--;
+               msleep(50);
+
+       } while (retries > 0);
+
+       if (rc) {
+               dev_err(dev, "Failed to send init request, rc = %d\n", rc);
+               return rc;
+       }
+
+       return 0;
 }
 
 static int send_version_xchg(struct ibmvnic_adapter *adapter)
-- 
1.8.3.1

Reply via email to