aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2017-09-13 13:16:00 -0400
committerDavid S. Miller <davem@davemloft.net>2017-09-13 16:29:13 -0400
commit7dbd5b7517376c4395a9ed0b26cf6b4db80d8415 (patch)
tree1db0fcbf574d3374f19777428d5cb5edad1661e0
parent4cbe94f2af25bf8f4d5dea56c770937d896342bf (diff)
nfp: wait for the NSP resource to appear on boot
The control process (NSP) may take some time to complete its initialization. This is not a problem on most servers, but on very fast-booting machines it may not be ready for operation when driver probes the device. There is also a version of the flash in the wild where NSP tries to train the links as part of init. To wait for NSP initialization we should make sure its resource has already been added to the resource table. NSP adds itself there as last step of init. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_main.c4
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h2
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c45
3 files changed, 51 insertions, 0 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 424707d41fbd..f8fa63b66739 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -351,6 +351,10 @@ static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf)
351 struct nfp_nsp *nsp; 351 struct nfp_nsp *nsp;
352 int err; 352 int err;
353 353
354 err = nfp_resource_wait(pf->cpp, NFP_RESOURCE_NSP, 30);
355 if (err)
356 return err;
357
354 nsp = nfp_nsp_open(pf->cpp); 358 nsp = nfp_nsp_open(pf->cpp);
355 if (IS_ERR(nsp)) { 359 if (IS_ERR(nsp)) {
356 err = PTR_ERR(nsp); 360 err = PTR_ERR(nsp);
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
index 1a8d04a1e113..3ce51f03126f 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp.h
@@ -97,6 +97,8 @@ nfp_resource_acquire(struct nfp_cpp *cpp, const char *name);
97 97
98void nfp_resource_release(struct nfp_resource *res); 98void nfp_resource_release(struct nfp_resource *res);
99 99
100int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs);
101
100u32 nfp_resource_cpp_id(struct nfp_resource *res); 102u32 nfp_resource_cpp_id(struct nfp_resource *res);
101 103
102const char *nfp_resource_name(struct nfp_resource *res); 104const char *nfp_resource_name(struct nfp_resource *res);
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
index 072612263dab..b1dd13ff282b 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
@@ -250,6 +250,51 @@ void nfp_resource_release(struct nfp_resource *res)
250} 250}
251 251
252/** 252/**
253 * nfp_resource_wait() - Wait for resource to appear
254 * @cpp: NFP CPP handle
255 * @name: Name of the resource
256 * @secs: Number of seconds to wait
257 *
258 * Wait for resource to appear in the resource table, grab and release
259 * its lock. The wait is jiffies-based, don't expect fine granularity.
260 *
261 * Return: 0 on success, errno otherwise.
262 */
263int nfp_resource_wait(struct nfp_cpp *cpp, const char *name, unsigned int secs)
264{
265 unsigned long warn_at = jiffies + NFP_MUTEX_WAIT_FIRST_WARN * HZ;
266 unsigned long err_at = jiffies + secs * HZ;
267 struct nfp_resource *res;
268
269 while (true) {
270 res = nfp_resource_acquire(cpp, name);
271 if (!IS_ERR(res)) {
272 nfp_resource_release(res);
273 return 0;
274 }
275
276 if (PTR_ERR(res) != -ENOENT) {
277 nfp_err(cpp, "error waiting for resource %s: %ld\n",
278 name, PTR_ERR(res));
279 return PTR_ERR(res);
280 }
281 if (time_is_before_eq_jiffies(err_at)) {
282 nfp_err(cpp, "timeout waiting for resource %s\n", name);
283 return -ETIMEDOUT;
284 }
285 if (time_is_before_eq_jiffies(warn_at)) {
286 warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
287 nfp_info(cpp, "waiting for NFP resource %s\n", name);
288 }
289 if (msleep_interruptible(10)) {
290 nfp_err(cpp, "wait for resource %s interrupted\n",
291 name);
292 return -ERESTARTSYS;
293 }
294 }
295}
296
297/**
253 * nfp_resource_cpp_id() - Return the cpp_id of a resource handle 298 * nfp_resource_cpp_id() - Return the cpp_id of a resource handle
254 * @res: NFP Resource handle 299 * @res: NFP Resource handle
255 * 300 *