X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fnfp%2Fnfpcore%2Fnfp_cpp_pcie_ops.c;h=0b9db974e12cc265e967d4a8e2a89ad3f854ae22;hb=c59e2faf147339e9b8375e2698919b8c053b0666;hp=c68d9400f9b9d79111230dba97f57ae476ba63c2;hpb=342a7bdd6e413cbb360289811601c516ec8b56a0;p=dpdk.git diff --git a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c index c68d9400f9..0b9db974e1 100644 --- a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c +++ b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c @@ -16,7 +16,9 @@ #include #include +#if defined(RTE_BACKTRACE) #include +#endif #include #include #include @@ -112,6 +114,7 @@ struct nfp_pcie_user { int device; int lock; + int secondary_lock; char busdev[BUSDEV_SZ]; int barsz; char *cfg; @@ -290,14 +293,32 @@ nfp_reconfigure_bar(struct nfp_pcie_user *nfp, struct nfp_bar *bar, int tgt, * already mapped. * * BAR0.0: Reserved for General Mapping (for MSI-X access to PCIe SRAM) + * + * Halving PCItoCPPBars for primary and secondary processes. + * NFP PMD just requires two fixed slots, one for configuration BAR, + * and another for accessing the hw queues. Another slot is needed + * for setting the link up or down. Secondary processes do not need + * to map the first two slots again, but it requires one slot for + * accessing the link, even if it is not likely the secondary process + * starting the port. This implies a limit of secondary processes + * supported. Due to this requirement and future extensions requiring + * new slots per process, only one secondary process is supported by + * now. */ static int nfp_enable_bars(struct nfp_pcie_user *nfp) { struct nfp_bar *bar; - int x; + int x, start, end; - for (x = ARRAY_SIZE(nfp->bar); x > 0; x--) { + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + start = 4; + end = 1; + } else { + start = 7; + end = 4; + } + for (x = start; x > end; x--) { bar = &nfp->bar[x - 1]; bar->barcfg = 0; bar->nfp = nfp; @@ -320,9 +341,16 @@ static struct nfp_bar * nfp_alloc_bar(struct nfp_pcie_user *nfp) { struct nfp_bar *bar; - int x; + int x, start, end; - for (x = ARRAY_SIZE(nfp->bar); x > 0; x--) { + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + start = 4; + end = 1; + } else { + start = 7; + end = 4; + } + for (x = start; x > end; x--) { bar = &nfp->bar[x - 1]; if (!bar->lock) { bar->lock = 1; @@ -336,9 +364,17 @@ static void nfp_disable_bars(struct nfp_pcie_user *nfp) { struct nfp_bar *bar; - int x; + int x, start, end; - for (x = ARRAY_SIZE(nfp->bar); x > 0; x--) { + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + start = 4; + end = 1; + } else { + start = 7; + end = 4; + } + + for (x = start; x > end; x--) { bar = &nfp->bar[x - 1]; if (bar->iomem) { bar->iomem = NULL; @@ -633,6 +669,52 @@ nfp_acquire_process_lock(struct nfp_pcie_user *desc) return 0; } +static int +nfp_acquire_secondary_process_lock(struct nfp_pcie_user *desc) +{ + int rc; + struct flock lock; + const char *lockname = "/.lock_nfp_secondary"; + char *home_path; + char *lockfile; + + memset(&lock, 0, sizeof(lock)); + + /* + * Using user's home directory. Note this can be called in a DPDK app + * being executed as non-root. This is not the case for the previous + * function nfp_acquire_process_lock which is invoked only when UIO + * driver is used because that implies root user. + */ + home_path = getenv("HOME"); + lockfile = calloc(strlen(home_path) + strlen(lockname) + 1, + sizeof(char)); + + if (!lockfile) + return -ENOMEM; + + strcat(lockfile, home_path); + strcat(lockfile, "/.lock_nfp_secondary"); + desc->secondary_lock = open(lockfile, O_RDWR | O_CREAT | O_NONBLOCK, + 0666); + if (desc->secondary_lock < 0) { + RTE_LOG(ERR, PMD, "NFP lock for secondary process failed\n"); + free(lockfile); + return desc->secondary_lock; + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + rc = fcntl(desc->secondary_lock, F_SETLK, &lock); + if (rc < 0) { + RTE_LOG(ERR, PMD, "NFP lock for secondary process failed\n"); + close(desc->secondary_lock); + } + + free(lockfile); + return rc; +} + static int nfp6000_set_model(struct rte_pci_device *dev, struct nfp_cpp *cpp) { @@ -774,7 +856,6 @@ static int nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev) { int ret = 0; - uint32_t model; struct nfp_pcie_user *desc; desc = malloc(sizeof(*desc)); @@ -785,20 +866,28 @@ nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev) memset(desc->busdev, 0, BUSDEV_SZ); strlcpy(desc->busdev, dev->device.name, sizeof(desc->busdev)); - if (cpp->driver_lock_needed) { + if (rte_eal_process_type() == RTE_PROC_PRIMARY && + cpp->driver_lock_needed) { ret = nfp_acquire_process_lock(desc); if (ret) - return -1; + goto error; + } + + /* Just support for one secondary process */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + ret = nfp_acquire_secondary_process_lock(desc); + if (ret) + goto error; } if (nfp6000_set_model(dev, cpp) < 0) - return -1; + goto error; if (nfp6000_set_interface(dev, cpp) < 0) - return -1; + goto error; if (nfp6000_set_serial(dev, cpp) < 0) - return -1; + goto error; if (nfp6000_set_barsz(dev, desc) < 0) - return -1; + goto error; desc->cfg = (char *)dev->mem_resource[0].addr; @@ -806,10 +895,11 @@ nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev) nfp_cpp_priv_set(cpp, desc); - model = __nfp_cpp_model_autodetect(cpp); - nfp_cpp_model_set(cpp, model); + return 0; - return ret; +error: + free(desc); + return -1; } static void @@ -820,6 +910,8 @@ nfp6000_free(struct nfp_cpp *cpp) nfp_disable_bars(desc); if (cpp->driver_lock_needed) close(desc->lock); + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + close(desc->secondary_lock); close(desc->device); free(desc); }