Merge tag 'perf-urgent-for-mingo-4.14-20170928' of git://git.kernel.org/pub/scm/linux...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / netronome / nfp / nfp_main.c
index f055b1774d65312a492010dd92b790559435c71c..f8fa63b66739dfcc081b623ff7de717bb5928445 100644 (file)
@@ -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;