1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Netronome Systems, Inc.
8 * Authors: Vinayak Tammineedi <vinayak.tammineedi@netronome.com>
10 * Multiplexes the NFP BARs between NFP internal resources and
11 * implements the PCIe specific interface for generic CPP bus access.
13 * The BARs are managed and allocated if they are available.
14 * The generic CPP bus abstraction builds upon this BAR interface.
33 #include <ethdev_pci.h>
34 #include <rte_string_fns.h>
37 #include "nfp_target.h"
38 #include "nfp6000/nfp6000.h"
40 #define NFP_PCIE_BAR(_pf) (0x30000 + ((_pf) & 7) * 0xc0)
42 #define NFP_PCIE_BAR_PCIE2CPP_ACTION_BASEADDRESS(_x) (((_x) & 0x1f) << 16)
43 #define NFP_PCIE_BAR_PCIE2CPP_BASEADDRESS(_x) (((_x) & 0xffff) << 0)
44 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT(_x) (((_x) & 0x3) << 27)
45 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_32BIT 0
46 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_64BIT 1
47 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_0BYTE 3
48 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE(_x) (((_x) & 0x7) << 29)
49 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_OF(_x) (((_x) >> 29) & 0x7)
50 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_FIXED 0
51 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_BULK 1
52 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_TARGET 2
53 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_GENERAL 3
54 #define NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS(_x) (((_x) & 0xf) << 23)
55 #define NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS(_x) (((_x) & 0x3) << 21)
58 * Minimal size of the PCIe cfg memory we depend on being mapped,
59 * queue controller and DMA controller don't have to be covered.
61 #define NFP_PCI_MIN_MAP_SIZE 0x080000
63 #define NFP_PCIE_P2C_FIXED_SIZE(bar) (1 << (bar)->bitsize)
64 #define NFP_PCIE_P2C_BULK_SIZE(bar) (1 << (bar)->bitsize)
65 #define NFP_PCIE_P2C_GENERAL_TARGET_OFFSET(bar, x) ((x) << ((bar)->bitsize - 2))
66 #define NFP_PCIE_P2C_GENERAL_TOKEN_OFFSET(bar, x) ((x) << ((bar)->bitsize - 4))
67 #define NFP_PCIE_P2C_GENERAL_SIZE(bar) (1 << ((bar)->bitsize - 4))
69 #define NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(bar, slot) \
70 (NFP_PCIE_BAR(0) + ((bar) * 8 + (slot)) * 4)
72 #define NFP_PCIE_CPP_BAR_PCIETOCPPEXPBAR(bar, slot) \
73 (((bar) * 8 + (slot)) * 4)
76 * Define to enable a bit more verbose debug output.
77 * Set to 1 to enable a bit more verbose debug output.
80 struct nfp6000_area_priv;
83 * struct nfp_bar - describes BAR configuration and usage
84 * @nfp: backlink to owner
85 * @barcfg: cached contents of BAR config CSR
86 * @base: the BAR's base CPP offset
87 * @mask: mask for the BAR aperture (read only)
88 * @bitsize: bitsize of BAR aperture (read only)
89 * @index: index of the BAR
90 * @lock: lock to specify if bar is in use
91 * @refcnt: number of current users
92 * @iomem: mapped IO memory
96 struct nfp_pcie_user *nfp;
98 uint64_t base; /* CPP address base */
99 uint64_t mask; /* Bit mask of the bar */
100 uint32_t bitsize; /* Bit size of the bar */
109 struct nfp_pcie_user {
110 struct nfp_bar bar[NFP_BAR_MAX];
115 char busdev[BUSDEV_SZ];
121 nfp_bar_maptype(struct nfp_bar *bar)
123 return NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_OF(bar->barcfg);
126 #define TARGET_WIDTH_32 4
127 #define TARGET_WIDTH_64 8
130 nfp_compute_bar(const struct nfp_bar *bar, uint32_t *bar_config,
131 uint64_t *bar_base, int tgt, int act, int tok,
132 uint64_t offset, size_t size, int width)
144 NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT
145 (NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_64BIT);
149 NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT
150 (NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_32BIT);
154 NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT
155 (NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_0BYTE);
161 if (act != NFP_CPP_ACTION_RW && act != 0) {
162 /* Fixed CPP mapping with specific action */
163 mask = ~(NFP_PCIE_P2C_FIXED_SIZE(bar) - 1);
166 NFP_PCIE_BAR_PCIE2CPP_MAPTYPE
167 (NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_FIXED);
168 newcfg |= NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS(tgt);
169 newcfg |= NFP_PCIE_BAR_PCIE2CPP_ACTION_BASEADDRESS(act);
170 newcfg |= NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS(tok);
172 if ((offset & mask) != ((offset + size - 1) & mask)) {
173 printf("BAR%d: Won't use for Fixed mapping\n",
175 printf("\t<%#llx,%#llx>, action=%d\n",
176 (unsigned long long)offset,
177 (unsigned long long)(offset + size), act);
178 printf("\tBAR too small (0x%llx).\n",
179 (unsigned long long)mask);
185 printf("BAR%d: Created Fixed mapping\n", bar->index);
186 printf("\t%d:%d:%d:0x%#llx-0x%#llx>\n", tgt, act, tok,
187 (unsigned long long)offset,
188 (unsigned long long)(offset + mask));
193 mask = ~(NFP_PCIE_P2C_BULK_SIZE(bar) - 1);
197 NFP_PCIE_BAR_PCIE2CPP_MAPTYPE
198 (NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_BULK);
200 newcfg |= NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS(tgt);
201 newcfg |= NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS(tok);
203 if ((offset & mask) != ((offset + size - 1) & mask)) {
204 printf("BAR%d: Won't use for bulk mapping\n",
206 printf("\t<%#llx,%#llx>\n", (unsigned long long)offset,
207 (unsigned long long)(offset + size));
208 printf("\ttarget=%d, token=%d\n", tgt, tok);
209 printf("\tBAR too small (%#llx) - (%#llx != %#llx).\n",
210 (unsigned long long)mask,
211 (unsigned long long)(offset & mask),
212 (unsigned long long)(offset + size - 1) & mask);
220 printf("BAR%d: Created bulk mapping %d:x:%d:%#llx-%#llx\n",
221 bar->index, tgt, tok, (unsigned long long)offset,
222 (unsigned long long)(offset + ~mask));
228 if (bar->bitsize < bitsize) {
229 printf("BAR%d: Too small for %d:%d:%d\n", bar->index, tgt, tok,
234 newcfg |= offset >> bitsize;
240 *bar_config = newcfg;
246 nfp_bar_write(struct nfp_pcie_user *nfp, struct nfp_bar *bar,
251 base = bar->index >> 3;
252 slot = bar->index & 7;
257 bar->csr = nfp->cfg +
258 NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(base, slot);
260 *(uint32_t *)(bar->csr) = newcfg;
262 bar->barcfg = newcfg;
264 printf("BAR%d: updated to 0x%08x\n", bar->index, newcfg);
271 nfp_reconfigure_bar(struct nfp_pcie_user *nfp, struct nfp_bar *bar, int tgt,
272 int act, int tok, uint64_t offset, size_t size, int width)
278 err = nfp_compute_bar(bar, &newcfg, &newbase, tgt, act, tok, offset,
285 return nfp_bar_write(nfp, bar, newcfg);
289 * Map all PCI bars. We assume that the BAR with the PCIe config block is
292 * BAR0.0: Reserved for General Mapping (for MSI-X access to PCIe SRAM)
294 * Halving PCItoCPPBars for primary and secondary processes.
295 * NFP PMD just requires two fixed slots, one for configuration BAR,
296 * and another for accessing the hw queues. Another slot is needed
297 * for setting the link up or down. Secondary processes do not need
298 * to map the first two slots again, but it requires one slot for
299 * accessing the link, even if it is not likely the secondary process
300 * starting the port. This implies a limit of secondary processes
301 * supported. Due to this requirement and future extensions requiring
302 * new slots per process, only one secondary process is supported by
306 nfp_enable_bars(struct nfp_pcie_user *nfp)
311 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
318 for (x = start; x > end; x--) {
319 bar = &nfp->bar[x - 1];
323 bar->mask = (1 << (nfp->barsz - 3)) - 1;
324 bar->bitsize = nfp->barsz - 3;
328 bar->csr = nfp->cfg +
329 NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(bar->index >> 3,
332 bar->iomem = nfp->cfg + (bar->index << bar->bitsize);
337 static struct nfp_bar *
338 nfp_alloc_bar(struct nfp_pcie_user *nfp)
343 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
350 for (x = start; x > end; x--) {
351 bar = &nfp->bar[x - 1];
361 nfp_disable_bars(struct nfp_pcie_user *nfp)
366 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
374 for (x = start; x > end; x--) {
375 bar = &nfp->bar[x - 1];
384 * Generic CPP bus access interface.
387 struct nfp6000_area_priv {
405 nfp6000_area_init(struct nfp_cpp_area *area, uint32_t dest,
406 unsigned long long address, unsigned long size)
408 struct nfp_pcie_user *nfp = nfp_cpp_priv(nfp_cpp_area_cpp(area));
409 struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
410 uint32_t target = NFP_CPP_ID_TARGET_of(dest);
411 uint32_t action = NFP_CPP_ID_ACTION_of(dest);
412 uint32_t token = NFP_CPP_ID_TOKEN_of(dest);
415 pp = nfp6000_target_pushpull(NFP_CPP_ID(target, action, token),
420 priv->width.read = PUSH_WIDTH(pp);
421 priv->width.write = PULL_WIDTH(pp);
423 if (priv->width.read > 0 &&
424 priv->width.write > 0 && priv->width.read != priv->width.write)
427 if (priv->width.read > 0)
428 priv->width.bar = priv->width.read;
430 priv->width.bar = priv->width.write;
432 priv->bar = nfp_alloc_bar(nfp);
433 if (priv->bar == NULL)
436 priv->target = target;
437 priv->action = action;
439 priv->offset = address;
442 ret = nfp_reconfigure_bar(nfp, priv->bar, priv->target, priv->action,
443 priv->token, priv->offset, priv->size,
450 nfp6000_area_acquire(struct nfp_cpp_area *area)
452 struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
454 /* Calculate offset into BAR. */
455 if (nfp_bar_maptype(priv->bar) ==
456 NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_GENERAL) {
457 priv->bar_offset = priv->offset &
458 (NFP_PCIE_P2C_GENERAL_SIZE(priv->bar) - 1);
460 NFP_PCIE_P2C_GENERAL_TARGET_OFFSET(priv->bar,
463 NFP_PCIE_P2C_GENERAL_TOKEN_OFFSET(priv->bar, priv->token);
465 priv->bar_offset = priv->offset & priv->bar->mask;
468 /* Must have been too big. Sub-allocate. */
469 if (!priv->bar->iomem)
472 priv->iomem = priv->bar->iomem + priv->bar_offset;
478 nfp6000_area_mapped(struct nfp_cpp_area *area)
480 struct nfp6000_area_priv *area_priv = nfp_cpp_area_priv(area);
482 if (!area_priv->iomem)
485 return area_priv->iomem;
489 nfp6000_area_release(struct nfp_cpp_area *area)
491 struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
498 nfp6000_area_iomem(struct nfp_cpp_area *area)
500 struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
505 nfp6000_area_read(struct nfp_cpp_area *area, void *kernel_vaddr,
506 unsigned long offset, unsigned int length)
508 uint64_t *wrptr64 = kernel_vaddr;
509 const volatile uint64_t *rdptr64;
510 struct nfp6000_area_priv *priv;
511 uint32_t *wrptr32 = kernel_vaddr;
512 const volatile uint32_t *rdptr32;
517 priv = nfp_cpp_area_priv(area);
518 rdptr64 = (uint64_t *)(priv->iomem + offset);
519 rdptr32 = (uint32_t *)(priv->iomem + offset);
521 if (offset + length > priv->size)
524 width = priv->width.read;
529 /* Unaligned? Translate to an explicit access */
530 if ((priv->offset + offset) & (width - 1)) {
531 printf("aread_read unaligned!!!\n");
535 is_64 = width == TARGET_WIDTH_64;
537 /* MU reads via a PCIe2CPP BAR supports 32bit (and other) lengths */
538 if (priv->target == (NFP_CPP_TARGET_ID_MASK & NFP_CPP_TARGET_MU) &&
539 priv->action == NFP_CPP_ACTION_RW) {
544 if (offset % sizeof(uint64_t) != 0 ||
545 length % sizeof(uint64_t) != 0)
548 if (offset % sizeof(uint32_t) != 0 ||
549 length % sizeof(uint32_t) != 0)
557 for (n = 0; n < length; n += sizeof(uint64_t)) {
563 for (n = 0; n < length; n += sizeof(uint32_t)) {
573 nfp6000_area_write(struct nfp_cpp_area *area, const void *kernel_vaddr,
574 unsigned long offset, unsigned int length)
576 const uint64_t *rdptr64 = kernel_vaddr;
578 const uint32_t *rdptr32 = kernel_vaddr;
579 struct nfp6000_area_priv *priv;
585 priv = nfp_cpp_area_priv(area);
586 wrptr64 = (uint64_t *)(priv->iomem + offset);
587 wrptr32 = (uint32_t *)(priv->iomem + offset);
589 if (offset + length > priv->size)
592 width = priv->width.write;
597 /* Unaligned? Translate to an explicit access */
598 if ((priv->offset + offset) & (width - 1))
601 is_64 = width == TARGET_WIDTH_64;
603 /* MU writes via a PCIe2CPP BAR supports 32bit (and other) lengths */
604 if (priv->target == (NFP_CPP_TARGET_ID_MASK & NFP_CPP_TARGET_MU) &&
605 priv->action == NFP_CPP_ACTION_RW)
609 if (offset % sizeof(uint64_t) != 0 ||
610 length % sizeof(uint64_t) != 0)
613 if (offset % sizeof(uint32_t) != 0 ||
614 length % sizeof(uint32_t) != 0)
622 for (n = 0; n < length; n += sizeof(uint64_t)) {
628 for (n = 0; n < length; n += sizeof(uint32_t)) {
637 #define PCI_DEVICES "/sys/bus/pci/devices"
640 nfp_acquire_process_lock(struct nfp_pcie_user *desc)
646 memset(&lock, 0, sizeof(lock));
648 snprintf(lockname, sizeof(lockname), "/var/lock/nfp_%s", desc->busdev);
649 desc->lock = open(lockname, O_RDWR | O_CREAT, 0666);
653 lock.l_type = F_WRLCK;
654 lock.l_whence = SEEK_SET;
657 rc = fcntl(desc->lock, F_SETLKW, &lock);
659 if (errno != EAGAIN && errno != EACCES) {
670 nfp_acquire_secondary_process_lock(struct nfp_pcie_user *desc)
674 const char *lockname = "/.lock_nfp_secondary";
678 memset(&lock, 0, sizeof(lock));
681 * Using user's home directory. Note this can be called in a DPDK app
682 * being executed as non-root. This is not the case for the previous
683 * function nfp_acquire_process_lock which is invoked only when UIO
684 * driver is used because that implies root user.
686 home_path = getenv("HOME");
687 lockfile = calloc(strlen(home_path) + strlen(lockname) + 1,
693 strcat(lockfile, home_path);
694 strcat(lockfile, "/.lock_nfp_secondary");
695 desc->secondary_lock = open(lockfile, O_RDWR | O_CREAT | O_NONBLOCK,
697 if (desc->secondary_lock < 0) {
698 RTE_LOG(ERR, PMD, "NFP lock for secondary process failed\n");
700 return desc->secondary_lock;
703 lock.l_type = F_WRLCK;
704 lock.l_whence = SEEK_SET;
705 rc = fcntl(desc->secondary_lock, F_SETLK, &lock);
707 RTE_LOG(ERR, PMD, "NFP lock for secondary process failed\n");
708 close(desc->secondary_lock);
716 nfp6000_set_model(struct rte_pci_device *dev, struct nfp_cpp *cpp)
720 if (rte_pci_read_config(dev, &model, 4, 0x2e) < 0) {
721 printf("nfp set model failed\n");
726 nfp_cpp_model_set(cpp, model);
732 nfp6000_set_interface(struct rte_pci_device *dev, struct nfp_cpp *cpp)
736 if (rte_pci_read_config(dev, &interface, 2, 0x154) < 0) {
737 printf("nfp set interface failed\n");
741 nfp_cpp_interface_set(cpp, interface);
747 nfp6000_set_serial(struct rte_pci_device *dev, struct nfp_cpp *cpp)
754 pos = rte_pci_find_ext_capability(dev, RTE_PCI_EXT_CAP_ID_DSN);
756 printf("PCI_EXT_CAP_ID_DSN not found. nfp set serial failed\n");
762 if (rte_pci_read_config(dev, &tmp, 2, pos) < 0) {
763 printf("nfp set serial failed\n");
767 serial[4] = (uint8_t)((tmp >> 8) & 0xff);
768 serial[5] = (uint8_t)(tmp & 0xff);
771 if (rte_pci_read_config(dev, &tmp, 2, pos) < 0) {
772 printf("nfp set serial failed\n");
776 serial[2] = (uint8_t)((tmp >> 8) & 0xff);
777 serial[3] = (uint8_t)(tmp & 0xff);
780 if (rte_pci_read_config(dev, &tmp, 2, pos) < 0) {
781 printf("nfp set serial failed\n");
785 serial[0] = (uint8_t)((tmp >> 8) & 0xff);
786 serial[1] = (uint8_t)(tmp & 0xff);
788 nfp_cpp_serial_set(cpp, serial, serial_len);
794 nfp6000_set_barsz(struct rte_pci_device *dev, struct nfp_pcie_user *desc)
799 tmp = dev->mem_resource[0].len;
809 nfp6000_init(struct nfp_cpp *cpp, struct rte_pci_device *dev)
812 struct nfp_pcie_user *desc;
814 desc = malloc(sizeof(*desc));
819 memset(desc->busdev, 0, BUSDEV_SZ);
820 strlcpy(desc->busdev, dev->device.name, sizeof(desc->busdev));
822 if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
823 cpp->driver_lock_needed) {
824 ret = nfp_acquire_process_lock(desc);
829 /* Just support for one secondary process */
830 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
831 ret = nfp_acquire_secondary_process_lock(desc);
836 if (nfp6000_set_model(dev, cpp) < 0)
838 if (nfp6000_set_interface(dev, cpp) < 0)
840 if (nfp6000_set_serial(dev, cpp) < 0)
842 if (nfp6000_set_barsz(dev, desc) < 0)
845 desc->cfg = (char *)dev->mem_resource[0].addr;
847 nfp_enable_bars(desc);
849 nfp_cpp_priv_set(cpp, desc);
859 nfp6000_free(struct nfp_cpp *cpp)
861 struct nfp_pcie_user *desc = nfp_cpp_priv(cpp);
863 nfp_disable_bars(desc);
864 if (cpp->driver_lock_needed)
866 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
867 close(desc->secondary_lock);
872 static const struct nfp_cpp_operations nfp6000_pcie_ops = {
873 .init = nfp6000_init,
874 .free = nfp6000_free,
876 .area_priv_size = sizeof(struct nfp6000_area_priv),
877 .area_init = nfp6000_area_init,
878 .area_acquire = nfp6000_area_acquire,
879 .area_release = nfp6000_area_release,
880 .area_mapped = nfp6000_area_mapped,
881 .area_read = nfp6000_area_read,
882 .area_write = nfp6000_area_write,
883 .area_iomem = nfp6000_area_iomem,
887 nfp_cpp_operations *nfp_cpp_transport_operations(void)
889 return &nfp6000_pcie_ops;