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.
19 #if defined(RTE_BACKTRACE)
36 #include <rte_ethdev_pci.h>
37 #include <rte_string_fns.h>
40 #include "nfp_target.h"
41 #include "nfp6000/nfp6000.h"
43 #define NFP_PCIE_BAR(_pf) (0x30000 + ((_pf) & 7) * 0xc0)
45 #define NFP_PCIE_BAR_PCIE2CPP_ACTION_BASEADDRESS(_x) (((_x) & 0x1f) << 16)
46 #define NFP_PCIE_BAR_PCIE2CPP_BASEADDRESS(_x) (((_x) & 0xffff) << 0)
47 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT(_x) (((_x) & 0x3) << 27)
48 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_32BIT 0
49 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_64BIT 1
50 #define NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_0BYTE 3
51 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE(_x) (((_x) & 0x7) << 29)
52 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_OF(_x) (((_x) >> 29) & 0x7)
53 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_FIXED 0
54 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_BULK 1
55 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_TARGET 2
56 #define NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_GENERAL 3
57 #define NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS(_x) (((_x) & 0xf) << 23)
58 #define NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS(_x) (((_x) & 0x3) << 21)
61 * Minimal size of the PCIe cfg memory we depend on being mapped,
62 * queue controller and DMA controller don't have to be covered.
64 #define NFP_PCI_MIN_MAP_SIZE 0x080000
66 #define NFP_PCIE_P2C_FIXED_SIZE(bar) (1 << (bar)->bitsize)
67 #define NFP_PCIE_P2C_BULK_SIZE(bar) (1 << (bar)->bitsize)
68 #define NFP_PCIE_P2C_GENERAL_TARGET_OFFSET(bar, x) ((x) << ((bar)->bitsize - 2))
69 #define NFP_PCIE_P2C_GENERAL_TOKEN_OFFSET(bar, x) ((x) << ((bar)->bitsize - 4))
70 #define NFP_PCIE_P2C_GENERAL_SIZE(bar) (1 << ((bar)->bitsize - 4))
72 #define NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(bar, slot) \
73 (NFP_PCIE_BAR(0) + ((bar) * 8 + (slot)) * 4)
75 #define NFP_PCIE_CPP_BAR_PCIETOCPPEXPBAR(bar, slot) \
76 (((bar) * 8 + (slot)) * 4)
79 * Define to enable a bit more verbose debug output.
80 * Set to 1 to enable a bit more verbose debug output.
83 struct nfp6000_area_priv
;
86 * struct nfp_bar - describes BAR configuration and usage
87 * @nfp: backlink to owner
88 * @barcfg: cached contents of BAR config CSR
89 * @base: the BAR's base CPP offset
90 * @mask: mask for the BAR aperture (read only)
91 * @bitsize: bitsize of BAR aperture (read only)
92 * @index: index of the BAR
93 * @lock: lock to specify if bar is in use
94 * @refcnt: number of current users
95 * @iomem: mapped IO memory
99 struct nfp_pcie_user
*nfp
;
101 uint64_t base
; /* CPP address base */
102 uint64_t mask
; /* Bit mask of the bar */
103 uint32_t bitsize
; /* Bit size of the bar */
112 struct nfp_pcie_user
{
113 struct nfp_bar bar
[NFP_BAR_MAX
];
118 char busdev
[BUSDEV_SZ
];
124 nfp_bar_maptype(struct nfp_bar
*bar
)
126 return NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_OF(bar
->barcfg
);
129 #define TARGET_WIDTH_32 4
130 #define TARGET_WIDTH_64 8
133 nfp_compute_bar(const struct nfp_bar
*bar
, uint32_t *bar_config
,
134 uint64_t *bar_base
, int tgt
, int act
, int tok
,
135 uint64_t offset
, size_t size
, int width
)
147 NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT
148 (NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_64BIT
);
152 NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT
153 (NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_32BIT
);
157 NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT
158 (NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_0BYTE
);
164 if (act
!= NFP_CPP_ACTION_RW
&& act
!= 0) {
165 /* Fixed CPP mapping with specific action */
166 mask
= ~(NFP_PCIE_P2C_FIXED_SIZE(bar
) - 1);
169 NFP_PCIE_BAR_PCIE2CPP_MAPTYPE
170 (NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_FIXED
);
171 newcfg
|= NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS(tgt
);
172 newcfg
|= NFP_PCIE_BAR_PCIE2CPP_ACTION_BASEADDRESS(act
);
173 newcfg
|= NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS(tok
);
175 if ((offset
& mask
) != ((offset
+ size
- 1) & mask
)) {
176 printf("BAR%d: Won't use for Fixed mapping\n",
178 printf("\t<%#llx,%#llx>, action=%d\n",
179 (unsigned long long)offset
,
180 (unsigned long long)(offset
+ size
), act
);
181 printf("\tBAR too small (0x%llx).\n",
182 (unsigned long long)mask
);
188 printf("BAR%d: Created Fixed mapping\n", bar
->index
);
189 printf("\t%d:%d:%d:0x%#llx-0x%#llx>\n", tgt
, act
, tok
,
190 (unsigned long long)offset
,
191 (unsigned long long)(offset
+ mask
));
196 mask
= ~(NFP_PCIE_P2C_BULK_SIZE(bar
) - 1);
200 NFP_PCIE_BAR_PCIE2CPP_MAPTYPE
201 (NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_BULK
);
203 newcfg
|= NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS(tgt
);
204 newcfg
|= NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS(tok
);
206 if ((offset
& mask
) != ((offset
+ size
- 1) & mask
)) {
207 printf("BAR%d: Won't use for bulk mapping\n",
209 printf("\t<%#llx,%#llx>\n", (unsigned long long)offset
,
210 (unsigned long long)(offset
+ size
));
211 printf("\ttarget=%d, token=%d\n", tgt
, tok
);
212 printf("\tBAR too small (%#llx) - (%#llx != %#llx).\n",
213 (unsigned long long)mask
,
214 (unsigned long long)(offset
& mask
),
215 (unsigned long long)(offset
+ size
- 1) & mask
);
223 printf("BAR%d: Created bulk mapping %d:x:%d:%#llx-%#llx\n",
224 bar
->index
, tgt
, tok
, (unsigned long long)offset
,
225 (unsigned long long)(offset
+ ~mask
));
231 if (bar
->bitsize
< bitsize
) {
232 printf("BAR%d: Too small for %d:%d:%d\n", bar
->index
, tgt
, tok
,
237 newcfg
|= offset
>> bitsize
;
243 *bar_config
= newcfg
;
249 nfp_bar_write(struct nfp_pcie_user
*nfp
, struct nfp_bar
*bar
,
254 base
= bar
->index
>> 3;
255 slot
= bar
->index
& 7;
260 bar
->csr
= nfp
->cfg
+
261 NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(base
, slot
);
263 *(uint32_t *)(bar
->csr
) = newcfg
;
265 bar
->barcfg
= newcfg
;
267 printf("BAR%d: updated to 0x%08x\n", bar
->index
, newcfg
);
274 nfp_reconfigure_bar(struct nfp_pcie_user
*nfp
, struct nfp_bar
*bar
, int tgt
,
275 int act
, int tok
, uint64_t offset
, size_t size
, int width
)
281 err
= nfp_compute_bar(bar
, &newcfg
, &newbase
, tgt
, act
, tok
, offset
,
288 return nfp_bar_write(nfp
, bar
, newcfg
);
292 * Map all PCI bars. We assume that the BAR with the PCIe config block is
295 * BAR0.0: Reserved for General Mapping (for MSI-X access to PCIe SRAM)
297 * Halving PCItoCPPBars for primary and secondary processes.
298 * NFP PMD just requires two fixed slots, one for configuration BAR,
299 * and another for accessing the hw queues. Another slot is needed
300 * for setting the link up or down. Secondary processes do not need
301 * to map the first two slots again, but it requires one slot for
302 * accessing the link, even if it is not likely the secondary process
303 * starting the port. This implies a limit of secondary processes
304 * supported. Due to this requirement and future extensions requiring
305 * new slots per process, only one secondary process is supported by
309 nfp_enable_bars(struct nfp_pcie_user
*nfp
)
314 if (rte_eal_process_type() == RTE_PROC_PRIMARY
) {
321 for (x
= start
; x
> end
; x
--) {
322 bar
= &nfp
->bar
[x
- 1];
326 bar
->mask
= (1 << (nfp
->barsz
- 3)) - 1;
327 bar
->bitsize
= nfp
->barsz
- 3;
331 bar
->csr
= nfp
->cfg
+
332 NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(bar
->index
>> 3,
335 bar
->iomem
= nfp
->cfg
+ (bar
->index
<< bar
->bitsize
);
340 static struct nfp_bar
*
341 nfp_alloc_bar(struct nfp_pcie_user
*nfp
)
346 if (rte_eal_process_type() == RTE_PROC_PRIMARY
) {
353 for (x
= start
; x
> end
; x
--) {
354 bar
= &nfp
->bar
[x
- 1];
364 nfp_disable_bars(struct nfp_pcie_user
*nfp
)
369 if (rte_eal_process_type() == RTE_PROC_PRIMARY
) {
377 for (x
= start
; x
> end
; x
--) {
378 bar
= &nfp
->bar
[x
- 1];
387 * Generic CPP bus access interface.
390 struct nfp6000_area_priv
{
408 nfp6000_area_init(struct nfp_cpp_area
*area
, uint32_t dest
,
409 unsigned long long address
, unsigned long size
)
411 struct nfp_pcie_user
*nfp
= nfp_cpp_priv(nfp_cpp_area_cpp(area
));
412 struct nfp6000_area_priv
*priv
= nfp_cpp_area_priv(area
);
413 uint32_t target
= NFP_CPP_ID_TARGET_of(dest
);
414 uint32_t action
= NFP_CPP_ID_ACTION_of(dest
);
415 uint32_t token
= NFP_CPP_ID_TOKEN_of(dest
);
418 pp
= nfp6000_target_pushpull(NFP_CPP_ID(target
, action
, token
),
423 priv
->width
.read
= PUSH_WIDTH(pp
);
424 priv
->width
.write
= PULL_WIDTH(pp
);
426 if (priv
->width
.read
> 0 &&
427 priv
->width
.write
> 0 && priv
->width
.read
!= priv
->width
.write
)
430 if (priv
->width
.read
> 0)
431 priv
->width
.bar
= priv
->width
.read
;
433 priv
->width
.bar
= priv
->width
.write
;
435 priv
->bar
= nfp_alloc_bar(nfp
);
436 if (priv
->bar
== NULL
)
439 priv
->target
= target
;
440 priv
->action
= action
;
442 priv
->offset
= address
;
445 ret
= nfp_reconfigure_bar(nfp
, priv
->bar
, priv
->target
, priv
->action
,
446 priv
->token
, priv
->offset
, priv
->size
,
453 nfp6000_area_acquire(struct nfp_cpp_area
*area
)
455 struct nfp6000_area_priv
*priv
= nfp_cpp_area_priv(area
);
457 /* Calculate offset into BAR. */
458 if (nfp_bar_maptype(priv
->bar
) ==
459 NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_GENERAL
) {
460 priv
->bar_offset
= priv
->offset
&
461 (NFP_PCIE_P2C_GENERAL_SIZE(priv
->bar
) - 1);
463 NFP_PCIE_P2C_GENERAL_TARGET_OFFSET(priv
->bar
,
466 NFP_PCIE_P2C_GENERAL_TOKEN_OFFSET(priv
->bar
, priv
->token
);
468 priv
->bar_offset
= priv
->offset
& priv
->bar
->mask
;
471 /* Must have been too big. Sub-allocate. */
472 if (!priv
->bar
->iomem
)
475 priv
->iomem
= priv
->bar
->iomem
+ priv
->bar_offset
;
481 nfp6000_area_mapped(struct nfp_cpp_area
*area
)
483 struct nfp6000_area_priv
*area_priv
= nfp_cpp_area_priv(area
);
485 if (!area_priv
->iomem
)
488 return area_priv
->iomem
;
492 nfp6000_area_release(struct nfp_cpp_area
*area
)
494 struct nfp6000_area_priv
*priv
= nfp_cpp_area_priv(area
);
501 nfp6000_area_iomem(struct nfp_cpp_area
*area
)
503 struct nfp6000_area_priv
*priv
= nfp_cpp_area_priv(area
);
508 nfp6000_area_read(struct nfp_cpp_area
*area
, void *kernel_vaddr
,
509 unsigned long offset
, unsigned int length
)
511 uint64_t *wrptr64
= kernel_vaddr
;
512 const volatile uint64_t *rdptr64
;
513 struct nfp6000_area_priv
*priv
;
514 uint32_t *wrptr32
= kernel_vaddr
;
515 const volatile uint32_t *rdptr32
;
520 priv
= nfp_cpp_area_priv(area
);
521 rdptr64
= (uint64_t *)(priv
->iomem
+ offset
);
522 rdptr32
= (uint32_t *)(priv
->iomem
+ offset
);
524 if (offset
+ length
> priv
->size
)
527 width
= priv
->width
.read
;
532 /* Unaligned? Translate to an explicit access */
533 if ((priv
->offset
+ offset
) & (width
- 1)) {
534 printf("aread_read unaligned!!!\n");
538 is_64
= width
== TARGET_WIDTH_64
;
540 /* MU reads via a PCIe2CPP BAR supports 32bit (and other) lengths */
541 if (priv
->target
== (NFP_CPP_TARGET_ID_MASK
& NFP_CPP_TARGET_MU
) &&
542 priv
->action
== NFP_CPP_ACTION_RW
) {
547 if (offset
% sizeof(uint64_t) != 0 ||
548 length
% sizeof(uint64_t) != 0)
551 if (offset
% sizeof(uint32_t) != 0 ||
552 length
% sizeof(uint32_t) != 0)
560 for (n
= 0; n
< length
; n
+= sizeof(uint64_t)) {
566 for (n
= 0; n
< length
; n
+= sizeof(uint32_t)) {
576 nfp6000_area_write(struct nfp_cpp_area
*area
, const void *kernel_vaddr
,
577 unsigned long offset
, unsigned int length
)
579 const uint64_t *rdptr64
= kernel_vaddr
;
581 const uint32_t *rdptr32
= kernel_vaddr
;
582 struct nfp6000_area_priv
*priv
;
588 priv
= nfp_cpp_area_priv(area
);
589 wrptr64
= (uint64_t *)(priv
->iomem
+ offset
);
590 wrptr32
= (uint32_t *)(priv
->iomem
+ offset
);
592 if (offset
+ length
> priv
->size
)
595 width
= priv
->width
.write
;
600 /* Unaligned? Translate to an explicit access */
601 if ((priv
->offset
+ offset
) & (width
- 1))
604 is_64
= width
== TARGET_WIDTH_64
;
606 /* MU writes via a PCIe2CPP BAR supports 32bit (and other) lengths */
607 if (priv
->target
== (NFP_CPP_TARGET_ID_MASK
& NFP_CPP_TARGET_MU
) &&
608 priv
->action
== NFP_CPP_ACTION_RW
)
612 if (offset
% sizeof(uint64_t) != 0 ||
613 length
% sizeof(uint64_t) != 0)
616 if (offset
% sizeof(uint32_t) != 0 ||
617 length
% sizeof(uint32_t) != 0)
625 for (n
= 0; n
< length
; n
+= sizeof(uint64_t)) {
631 for (n
= 0; n
< length
; n
+= sizeof(uint32_t)) {
640 #define PCI_DEVICES "/sys/bus/pci/devices"
643 nfp_acquire_process_lock(struct nfp_pcie_user
*desc
)
649 memset(&lock
, 0, sizeof(lock
));
651 snprintf(lockname
, sizeof(lockname
), "/var/lock/nfp_%s", desc
->busdev
);
652 desc
->lock
= open(lockname
, O_RDWR
| O_CREAT
, 0666);
656 lock
.l_type
= F_WRLCK
;
657 lock
.l_whence
= SEEK_SET
;
660 rc
= fcntl(desc
->lock
, F_SETLKW
, &lock
);
662 if (errno
!= EAGAIN
&& errno
!= EACCES
) {
673 nfp_acquire_secondary_process_lock(struct nfp_pcie_user
*desc
)
677 const char *lockname
= "/.lock_nfp_secondary";
681 memset(&lock
, 0, sizeof(lock
));
684 * Using user's home directory. Note this can be called in a DPDK app
685 * being executed as non-root. This is not the case for the previous
686 * function nfp_acquire_process_lock which is invoked only when UIO
687 * driver is used because that implies root user.
689 home_path
= getenv("HOME");
690 lockfile
= calloc(strlen(home_path
) + strlen(lockname
) + 1,
696 strcat(lockfile
, home_path
);
697 strcat(lockfile
, "/.lock_nfp_secondary");
698 desc
->secondary_lock
= open(lockfile
, O_RDWR
| O_CREAT
| O_NONBLOCK
,
700 if (desc
->secondary_lock
< 0) {
701 RTE_LOG(ERR
, PMD
, "NFP lock for secondary process failed\n");
703 return desc
->secondary_lock
;
706 lock
.l_type
= F_WRLCK
;
707 lock
.l_whence
= SEEK_SET
;
708 rc
= fcntl(desc
->secondary_lock
, F_SETLK
, &lock
);
710 RTE_LOG(ERR
, PMD
, "NFP lock for secondary process failed\n");
711 close(desc
->secondary_lock
);
719 nfp6000_set_model(struct rte_pci_device
*dev
, struct nfp_cpp
*cpp
)
723 if (rte_pci_read_config(dev
, &model
, 4, 0x2e) < 0) {
724 printf("nfp set model failed\n");
729 nfp_cpp_model_set(cpp
, model
);
735 nfp6000_set_interface(struct rte_pci_device
*dev
, struct nfp_cpp
*cpp
)
739 if (rte_pci_read_config(dev
, &interface
, 2, 0x154) < 0) {
740 printf("nfp set interface failed\n");
744 nfp_cpp_interface_set(cpp
, interface
);
749 #define PCI_CFG_SPACE_SIZE 256
750 #define PCI_CFG_SPACE_EXP_SIZE 4096
751 #define PCI_EXT_CAP_ID(header) (int)(header & 0x0000ffff)
752 #define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
753 #define PCI_EXT_CAP_ID_DSN 0x03
755 nfp_pci_find_next_ext_capability(struct rte_pci_device
*dev
, int cap
)
759 int pos
= PCI_CFG_SPACE_SIZE
;
761 /* minimum 8 bytes per capability */
762 ttl
= (PCI_CFG_SPACE_EXP_SIZE
- PCI_CFG_SPACE_SIZE
) / 8;
764 if (rte_pci_read_config(dev
, &header
, 4, pos
) < 0) {
765 printf("nfp error reading extended capabilities\n");
770 * If we have no capabilities, this is indicated by cap ID,
771 * cap version and next pointer all being 0.
777 if (PCI_EXT_CAP_ID(header
) == cap
)
780 pos
= PCI_EXT_CAP_NEXT(header
);
781 if (pos
< PCI_CFG_SPACE_SIZE
)
784 if (rte_pci_read_config(dev
, &header
, 4, pos
) < 0) {
785 printf("nfp error reading extended capabilities\n");
794 nfp6000_set_serial(struct rte_pci_device
*dev
, struct nfp_cpp
*cpp
)
801 pos
= nfp_pci_find_next_ext_capability(dev
, PCI_EXT_CAP_ID_DSN
);
803 printf("PCI_EXT_CAP_ID_DSN not found. nfp set serial failed\n");
809 if (rte_pci_read_config(dev
, &tmp
, 2, pos
) < 0) {
810 printf("nfp set serial failed\n");
814 serial
[4] = (uint8_t)((tmp
>> 8) & 0xff);
815 serial
[5] = (uint8_t)(tmp
& 0xff);
818 if (rte_pci_read_config(dev
, &tmp
, 2, pos
) < 0) {
819 printf("nfp set serial failed\n");
823 serial
[2] = (uint8_t)((tmp
>> 8) & 0xff);
824 serial
[3] = (uint8_t)(tmp
& 0xff);
827 if (rte_pci_read_config(dev
, &tmp
, 2, pos
) < 0) {
828 printf("nfp set serial failed\n");
832 serial
[0] = (uint8_t)((tmp
>> 8) & 0xff);
833 serial
[1] = (uint8_t)(tmp
& 0xff);
835 nfp_cpp_serial_set(cpp
, serial
, serial_len
);
841 nfp6000_set_barsz(struct rte_pci_device
*dev
, struct nfp_pcie_user
*desc
)
846 tmp
= dev
->mem_resource
[0].len
;
856 nfp6000_init(struct nfp_cpp
*cpp
, struct rte_pci_device
*dev
)
859 struct nfp_pcie_user
*desc
;
861 desc
= malloc(sizeof(*desc
));
866 memset(desc
->busdev
, 0, BUSDEV_SZ
);
867 strlcpy(desc
->busdev
, dev
->device
.name
, sizeof(desc
->busdev
));
869 if (rte_eal_process_type() == RTE_PROC_PRIMARY
&&
870 cpp
->driver_lock_needed
) {
871 ret
= nfp_acquire_process_lock(desc
);
876 /* Just support for one secondary process */
877 if (rte_eal_process_type() != RTE_PROC_PRIMARY
) {
878 ret
= nfp_acquire_secondary_process_lock(desc
);
883 if (nfp6000_set_model(dev
, cpp
) < 0)
885 if (nfp6000_set_interface(dev
, cpp
) < 0)
887 if (nfp6000_set_serial(dev
, cpp
) < 0)
889 if (nfp6000_set_barsz(dev
, desc
) < 0)
892 desc
->cfg
= (char *)dev
->mem_resource
[0].addr
;
894 nfp_enable_bars(desc
);
896 nfp_cpp_priv_set(cpp
, desc
);
906 nfp6000_free(struct nfp_cpp
*cpp
)
908 struct nfp_pcie_user
*desc
= nfp_cpp_priv(cpp
);
910 nfp_disable_bars(desc
);
911 if (cpp
->driver_lock_needed
)
913 if (rte_eal_process_type() != RTE_PROC_PRIMARY
)
914 close(desc
->secondary_lock
);
919 static const struct nfp_cpp_operations nfp6000_pcie_ops
= {
920 .init
= nfp6000_init
,
921 .free
= nfp6000_free
,
923 .area_priv_size
= sizeof(struct nfp6000_area_priv
),
924 .area_init
= nfp6000_area_init
,
925 .area_acquire
= nfp6000_area_acquire
,
926 .area_release
= nfp6000_area_release
,
927 .area_mapped
= nfp6000_area_mapped
,
928 .area_read
= nfp6000_area_read
,
929 .area_write
= nfp6000_area_write
,
930 .area_iomem
= nfp6000_area_iomem
,
934 nfp_cpp_operations
*nfp_cpp_transport_operations(void)
936 return &nfp6000_pcie_ops
;