1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Netronome Systems, Inc.
12 #include <sys/types.h>
14 #include <rte_byteorder.h>
15 #include <ethdev_pci.h>
18 #include "nfp_target.h"
19 #include "nfp6000/nfp6000.h"
20 #include "nfp6000/nfp_xpb.h"
23 #define NFP_PL_DEVICE_ID 0x00000004
24 #define NFP_PL_DEVICE_ID_MASK 0xff
25 #define NFP_PL_DEVICE_PART_MASK 0xffff0000
26 #define NFP_PL_DEVICE_MODEL_MASK (NFP_PL_DEVICE_PART_MASK | \
27 NFP_PL_DEVICE_ID_MASK)
30 nfp_cpp_priv_set(struct nfp_cpp *cpp, void *priv)
36 nfp_cpp_priv(struct nfp_cpp *cpp)
42 nfp_cpp_model_set(struct nfp_cpp *cpp, uint32_t model)
48 nfp_cpp_model(struct nfp_cpp *cpp)
54 return NFP_CPP_MODEL_INVALID;
56 err = __nfp_cpp_model_autodetect(cpp, &model);
65 nfp_cpp_interface_set(struct nfp_cpp *cpp, uint32_t interface)
67 cpp->interface = interface;
71 nfp_cpp_serial(struct nfp_cpp *cpp, const uint8_t **serial)
73 *serial = cpp->serial;
74 return cpp->serial_len;
78 nfp_cpp_serial_set(struct nfp_cpp *cpp, const uint8_t *serial,
84 cpp->serial = malloc(serial_len);
88 memcpy(cpp->serial, serial, serial_len);
89 cpp->serial_len = serial_len;
95 nfp_cpp_interface(struct nfp_cpp *cpp)
98 return NFP_CPP_INTERFACE(NFP_CPP_INTERFACE_TYPE_INVALID, 0, 0);
100 return cpp->interface;
104 nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area)
110 nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area)
112 return cpp_area->cpp;
116 nfp_cpp_area_name(struct nfp_cpp_area *cpp_area)
118 return cpp_area->name;
122 * nfp_cpp_area_alloc - allocate a new CPP area
125 * @address: start address on CPP target
126 * @size: size of area in bytes
128 * Allocate and initialize a CPP area structure. The area must later
129 * be locked down with an 'acquire' before it can be safely accessed.
131 * NOTE: @address and @size must be 32-bit aligned values.
133 struct nfp_cpp_area *
134 nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, uint32_t dest,
135 const char *name, unsigned long long address,
138 struct nfp_cpp_area *area;
139 uint64_t tmp64 = (uint64_t)address;
145 /* CPP bus uses only a 40-bit address */
146 if ((address + size) > (1ULL << 40))
147 return NFP_ERRPTR(EFAULT);
149 /* Remap from cpp_island to cpp_target */
150 err = nfp_target_cpp(dest, tmp64, &dest, &tmp64, cpp->imb_cat_table);
154 address = (unsigned long long)tmp64;
159 area = calloc(1, sizeof(*area) + cpp->op->area_priv_size +
165 area->name = ((char *)area) + sizeof(*area) + cpp->op->area_priv_size;
166 memcpy(area->name, name, strlen(name) + 1);
169 * Preserve errno around the call to area_init, since most
170 * implementations will blindly call nfp_target_action_width()for both
171 * read or write modes, and that will set errno to EINVAL.
175 err = cpp->op->area_init(area, dest, address, size);
184 area->offset = address;
190 struct nfp_cpp_area *
191 nfp_cpp_area_alloc(struct nfp_cpp *cpp, uint32_t dest,
192 unsigned long long address, unsigned long size)
194 return nfp_cpp_area_alloc_with_name(cpp, dest, NULL, address, size);
198 * nfp_cpp_area_alloc_acquire - allocate a new CPP area and lock it down
202 * @address: start address on CPP target
203 * @size: size of area
205 * Allocate and initilizae a CPP area structure, and lock it down so
206 * that it can be accessed directly.
208 * NOTE: @address and @size must be 32-bit aligned values.
210 * NOTE: The area must also be 'released' when the structure is freed.
212 struct nfp_cpp_area *
213 nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, uint32_t destination,
214 unsigned long long address, unsigned long size)
216 struct nfp_cpp_area *area;
218 area = nfp_cpp_area_alloc(cpp, destination, address, size);
222 if (nfp_cpp_area_acquire(area)) {
223 nfp_cpp_area_free(area);
231 * nfp_cpp_area_free - free up the CPP area
232 * area: CPP area handle
234 * Frees up memory resources held by the CPP area.
237 nfp_cpp_area_free(struct nfp_cpp_area *area)
239 if (area->cpp->op->area_cleanup)
240 area->cpp->op->area_cleanup(area);
245 * nfp_cpp_area_release_free - release CPP area and free it
246 * area: CPP area handle
248 * Releases CPP area and frees up memory resources held by the it.
251 nfp_cpp_area_release_free(struct nfp_cpp_area *area)
253 nfp_cpp_area_release(area);
254 nfp_cpp_area_free(area);
258 * nfp_cpp_area_acquire - lock down a CPP area for access
259 * @area: CPP area handle
261 * Locks down the CPP area for a potential long term activity. Area
262 * must always be locked down before being accessed.
265 nfp_cpp_area_acquire(struct nfp_cpp_area *area)
267 if (area->cpp->op->area_acquire) {
268 int err = area->cpp->op->area_acquire(area);
278 * nfp_cpp_area_release - release a locked down CPP area
279 * @area: CPP area handle
281 * Releases a previously locked down CPP area.
284 nfp_cpp_area_release(struct nfp_cpp_area *area)
286 if (area->cpp->op->area_release)
287 area->cpp->op->area_release(area);
291 * nfp_cpp_area_iomem() - get IOMEM region for CPP area
293 * @area: CPP area handle
295 * Returns an iomem pointer for use with readl()/writel() style operations.
297 * NOTE: Area must have been locked down with an 'acquire'.
299 * Return: pointer to the area, or NULL
302 nfp_cpp_area_iomem(struct nfp_cpp_area *area)
306 if (area->cpp->op->area_iomem)
307 iomem = area->cpp->op->area_iomem(area);
313 * nfp_cpp_area_read - read data from CPP area
315 * @area: CPP area handle
316 * @offset: offset into CPP area
317 * @kernel_vaddr: kernel address to put data into
318 * @length: number of bytes to read
320 * Read data from indicated CPP region.
322 * NOTE: @offset and @length must be 32-bit aligned values.
324 * NOTE: Area must have been locked down with an 'acquire'.
327 nfp_cpp_area_read(struct nfp_cpp_area *area, unsigned long offset,
328 void *kernel_vaddr, size_t length)
330 if ((offset + length) > area->size)
331 return NFP_ERRNO(EFAULT);
333 return area->cpp->op->area_read(area, kernel_vaddr, offset, length);
337 * nfp_cpp_area_write - write data to CPP area
339 * @area: CPP area handle
340 * @offset: offset into CPP area
341 * @kernel_vaddr: kernel address to read data from
342 * @length: number of bytes to write
344 * Write data to indicated CPP region.
346 * NOTE: @offset and @length must be 32-bit aligned values.
348 * NOTE: Area must have been locked down with an 'acquire'.
351 nfp_cpp_area_write(struct nfp_cpp_area *area, unsigned long offset,
352 const void *kernel_vaddr, size_t length)
354 if ((offset + length) > area->size)
355 return NFP_ERRNO(EFAULT);
357 return area->cpp->op->area_write(area, kernel_vaddr, offset, length);
361 nfp_cpp_area_mapped(struct nfp_cpp_area *area)
363 if (area->cpp->op->area_mapped)
364 return area->cpp->op->area_mapped(area);
369 * nfp_cpp_area_check_range - check if address range fits in CPP area
371 * @area: CPP area handle
372 * @offset: offset into CPP area
373 * @length: size of address range in bytes
375 * Check if address range fits within CPP area. Return 0 if area fits
379 nfp_cpp_area_check_range(struct nfp_cpp_area *area, unsigned long long offset,
380 unsigned long length)
382 if (((offset + length) > area->size))
383 return NFP_ERRNO(EFAULT);
389 * Return the correct CPP address, and fixup xpb_addr as needed,
390 * based upon NFP model.
393 nfp_xpb_to_cpp(struct nfp_cpp *cpp, uint32_t *xpb_addr)
398 xpb = NFP_CPP_ID(14, NFP_CPP_ACTION_RW, 0);
401 * Ensure that non-local XPB accesses go out through the
404 island = ((*xpb_addr) >> 24) & 0x3f;
411 * Accesses to the ARM Island overlay uses Island 0
414 (*xpb_addr) &= ~0x7f000000;
415 if (*xpb_addr < 0x60000)
416 *xpb_addr |= (1 << 30);
418 /* And only non-ARM interfaces use island id = 1 */
419 if (NFP_CPP_INTERFACE_TYPE_of(nfp_cpp_interface(cpp)) !=
420 NFP_CPP_INTERFACE_TYPE_ARM)
421 *xpb_addr |= (1 << 24);
423 (*xpb_addr) |= (1 << 30);
430 nfp_cpp_area_readl(struct nfp_cpp_area *area, unsigned long offset,
436 sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp));
437 *value = rte_le_to_cpu_32(tmp);
439 return (sz == sizeof(*value)) ? 0 : -1;
443 nfp_cpp_area_writel(struct nfp_cpp_area *area, unsigned long offset,
448 value = rte_cpu_to_le_32(value);
449 sz = nfp_cpp_area_write(area, offset, &value, sizeof(value));
450 return (sz == sizeof(value)) ? 0 : -1;
454 nfp_cpp_area_readq(struct nfp_cpp_area *area, unsigned long offset,
460 sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp));
461 *value = rte_le_to_cpu_64(tmp);
463 return (sz == sizeof(*value)) ? 0 : -1;
467 nfp_cpp_area_writeq(struct nfp_cpp_area *area, unsigned long offset,
472 value = rte_cpu_to_le_64(value);
473 sz = nfp_cpp_area_write(area, offset, &value, sizeof(value));
475 return (sz == sizeof(value)) ? 0 : -1;
479 nfp_cpp_readl(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
485 sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp));
486 *value = rte_le_to_cpu_32(tmp);
488 return (sz == sizeof(*value)) ? 0 : -1;
492 nfp_cpp_writel(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
497 value = rte_cpu_to_le_32(value);
498 sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value));
500 return (sz == sizeof(value)) ? 0 : -1;
504 nfp_cpp_readq(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
510 sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp));
511 *value = rte_le_to_cpu_64(tmp);
513 return (sz == sizeof(*value)) ? 0 : -1;
517 nfp_cpp_writeq(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
522 value = rte_cpu_to_le_64(value);
523 sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value));
525 return (sz == sizeof(value)) ? 0 : -1;
529 nfp_xpb_writel(struct nfp_cpp *cpp, uint32_t xpb_addr, uint32_t value)
533 cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr);
535 return nfp_cpp_writel(cpp, cpp_dest, xpb_addr, value);
539 nfp_xpb_readl(struct nfp_cpp *cpp, uint32_t xpb_addr, uint32_t *value)
543 cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr);
545 return nfp_cpp_readl(cpp, cpp_dest, xpb_addr, value);
548 static struct nfp_cpp *
549 nfp_cpp_alloc(struct rte_pci_device *dev, int driver_lock_needed)
551 const struct nfp_cpp_operations *ops;
555 ops = nfp_cpp_transport_operations();
557 if (!ops || !ops->init)
558 return NFP_ERRPTR(EINVAL);
560 cpp = calloc(1, sizeof(*cpp));
565 cpp->driver_lock_needed = driver_lock_needed;
568 err = cpp->op->init(cpp, dev);
575 if (NFP_CPP_MODEL_IS_6000(nfp_cpp_model(cpp))) {
579 for (tgt = 0; tgt < ARRAY_SIZE(cpp->imb_cat_table); tgt++) {
580 /* Hardcoded XPB IMB Base, island 0 */
581 xpbaddr = 0x000a0000 + (tgt * 4);
582 err = nfp_xpb_readl(cpp, xpbaddr,
583 (uint32_t *)&cpp->imb_cat_table[tgt]);
595 * nfp_cpp_free - free the CPP handle
599 nfp_cpp_free(struct nfp_cpp *cpp)
601 if (cpp->op && cpp->op->free)
611 nfp_cpp_from_device_name(struct rte_pci_device *dev, int driver_lock_needed)
613 return nfp_cpp_alloc(dev, driver_lock_needed);
617 * Modify bits of a 32-bit value from the XPB bus
619 * @param cpp NFP CPP device handle
620 * @param xpb_tgt XPB target and address
621 * @param mask mask of bits to alter
622 * @param value value to modify
624 * @return 0 on success, or -1 on failure (and set errno accordingly).
627 nfp_xpb_writelm(struct nfp_cpp *cpp, uint32_t xpb_tgt, uint32_t mask,
633 err = nfp_xpb_readl(cpp, xpb_tgt, &tmp);
638 tmp |= (mask & value);
639 return nfp_xpb_writel(cpp, xpb_tgt, tmp);
643 * Modify bits of a 32-bit value from the XPB bus
645 * @param cpp NFP CPP device handle
646 * @param xpb_tgt XPB target and address
647 * @param mask mask of bits to alter
648 * @param value value to monitor for
649 * @param timeout_us maximum number of us to wait (-1 for forever)
651 * @return >= 0 on success, or -1 on failure (and set errno accordingly).
654 nfp_xpb_waitlm(struct nfp_cpp *cpp, uint32_t xpb_tgt, uint32_t mask,
655 uint32_t value, int timeout_us)
661 err = nfp_xpb_readl(cpp, xpb_tgt, &tmp);
665 if ((tmp & mask) == (value & mask)) {
676 } while (timeout_us >= 0);
679 err = NFP_ERRNO(ETIMEDOUT);
688 * nfp_cpp_read - read from CPP target
690 * @destination: CPP id
691 * @address: offset into CPP target
692 * @kernel_vaddr: kernel buffer for result
693 * @length: number of bytes to read
696 nfp_cpp_read(struct nfp_cpp *cpp, uint32_t destination,
697 unsigned long long address, void *kernel_vaddr, size_t length)
699 struct nfp_cpp_area *area;
702 area = nfp_cpp_area_alloc_acquire(cpp, destination, address, length);
704 printf("Area allocation/acquire failed\n");
708 err = nfp_cpp_area_read(area, 0, kernel_vaddr, length);
710 nfp_cpp_area_release_free(area);
715 * nfp_cpp_write - write to CPP target
717 * @destination: CPP id
718 * @address: offset into CPP target
719 * @kernel_vaddr: kernel buffer to read from
720 * @length: number of bytes to write
723 nfp_cpp_write(struct nfp_cpp *cpp, uint32_t destination,
724 unsigned long long address, const void *kernel_vaddr,
727 struct nfp_cpp_area *area;
730 area = nfp_cpp_area_alloc_acquire(cpp, destination, address, length);
734 err = nfp_cpp_area_write(area, 0, kernel_vaddr, length);
736 nfp_cpp_area_release_free(area);
741 * nfp_cpp_area_fill - fill a CPP area with a value
743 * @offset: offset into CPP area
744 * @value: value to fill with
745 * @length: length of area to fill
748 nfp_cpp_area_fill(struct nfp_cpp_area *area, unsigned long offset,
749 uint32_t value, size_t length)
755 value = rte_cpu_to_le_32(value);
756 value64 = ((uint64_t)value << 32) | value;
758 if ((offset + length) > area->size)
759 return NFP_ERRNO(EINVAL);
761 if ((area->offset + offset) & 3)
762 return NFP_ERRNO(EINVAL);
764 if (((area->offset + offset) & 7) == 4 && length >= 4) {
765 err = nfp_cpp_area_write(area, offset, &value, sizeof(value));
768 if (err != sizeof(value))
769 return NFP_ERRNO(ENOSPC);
770 offset += sizeof(value);
771 length -= sizeof(value);
774 for (i = 0; (i + sizeof(value)) < length; i += sizeof(value64)) {
776 nfp_cpp_area_write(area, offset + i, &value64,
780 if (err != sizeof(value64))
781 return NFP_ERRNO(ENOSPC);
784 if ((i + sizeof(value)) <= length) {
786 nfp_cpp_area_write(area, offset + i, &value, sizeof(value));
789 if (err != sizeof(value))
790 return NFP_ERRNO(ENOSPC);
798 * NOTE: This code should not use nfp_xpb_* functions,
799 * as those are model-specific
802 __nfp_cpp_model_autodetect(struct nfp_cpp *cpp, uint32_t *model)
807 err = nfp_xpb_readl(cpp, NFP_XPB_DEVICE(1, 1, 16) + NFP_PL_DEVICE_ID,
812 *model = reg & NFP_PL_DEVICE_MODEL_MASK;
813 if (*model & NFP_PL_DEVICE_ID_MASK)
820 * nfp_cpp_map_area() - Helper function to map an area
821 * @cpp: NFP CPP handler
822 * @domain: CPP domain
823 * @target: CPP target
825 * @size: Size of the area
826 * @area: Area handle (output)
828 * Map an area of IOMEM access. To undo the effect of this function call
829 * @nfp_cpp_area_release_free(*area).
831 * Return: Pointer to memory mapped area or ERR_PTR
834 nfp_cpp_map_area(struct nfp_cpp *cpp, int domain, int target, uint64_t addr,
835 unsigned long size, struct nfp_cpp_area **area)
840 dest = NFP_CPP_ISLAND_ID(target, NFP_CPP_ACTION_RW, 0, domain);
842 *area = nfp_cpp_area_alloc_acquire(cpp, dest, addr, size);
846 res = nfp_cpp_area_iomem(*area);
848 goto err_release_free;
853 nfp_cpp_area_release_free(*area);