diff options
author | David S. Miller <davem@davemloft.net> | 2017-09-13 13:29:13 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-09-13 13:29:13 -0700 |
commit | d371465e81fc740cfa67ef47fbf692350c6b0113 (patch) | |
tree | 1db0fcbf574d3374f19777428d5cb5edad1661e0 /drivers/net/ethernet/netronome/nfp/nfp_main.c | |
parent | 255cd50f207ae8ec7b22663246c833407744e634 (diff) | |
parent | 7dbd5b7517376c4395a9ed0b26cf6b4db80d8415 (diff) |
Merge branch 'nfp-card-init'
Jakub Kicinski says:
====================
nfp: wait more carefully for card init
The first patch is a small fix for flower offload, we need a whitelist
of supported matches, otherwise the unsupported ones will be ignored.
The second and the third patch are adding wait/polling to the probe path.
We had reports of driver failing probe because it couldn't find the
control process (NSP) on the card. Turns out the NSP will only announce
its existence after it's fully initialized. Until now we assumed it
will be reachable, just not processing commands (hence we wait for
a NOOP command to execute successfully).
v2:
- fix a bad merge which resulted in a build warning and retest.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfp_main.c')
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_main.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index f055b1774d65..f8fa63b66739 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -74,6 +74,45 @@ static const struct pci_device_id nfp_pci_device_ids[] = { }; MODULE_DEVICE_TABLE(pci, nfp_pci_device_ids); +static bool nfp_board_ready(struct nfp_pf *pf) +{ + const char *cp; + long state; + int err; + + cp = nfp_hwinfo_lookup(pf->hwinfo, "board.state"); + if (!cp) + return false; + + err = kstrtol(cp, 0, &state); + if (err < 0) + return false; + + return state == 15; +} + +static int nfp_pf_board_state_wait(struct nfp_pf *pf) +{ + const unsigned long wait_until = jiffies + 10 * HZ; + + while (!nfp_board_ready(pf)) { + if (time_is_before_eq_jiffies(wait_until)) { + nfp_err(pf->cpp, "NFP board initialization timeout\n"); + return -EINVAL; + } + + nfp_info(pf->cpp, "waiting for board initialization\n"); + if (msleep_interruptible(500)) + return -ERESTARTSYS; + + /* Refresh cached information */ + kfree(pf->hwinfo); + pf->hwinfo = nfp_hwinfo_read(pf->cpp); + } + + return 0; +} + static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf) { int err; @@ -312,6 +351,10 @@ static int nfp_nsp_init(struct pci_dev *pdev, struct nfp_pf *pf) struct nfp_nsp *nsp; int err; + err = nfp_resource_wait(pf->cpp, NFP_RESOURCE_NSP, 30); + if (err) + return err; + nsp = nfp_nsp_open(pf->cpp); if (IS_ERR(nsp)) { err = PTR_ERR(nsp); @@ -425,6 +468,10 @@ static int nfp_pci_probe(struct pci_dev *pdev, nfp_hwinfo_lookup(pf->hwinfo, "assembly.revision"), nfp_hwinfo_lookup(pf->hwinfo, "cpld.version")); + err = nfp_pf_board_state_wait(pf); + if (err) + goto err_hwinfo_free; + err = devlink_register(devlink, &pdev->dev); if (err) goto err_hwinfo_free; |