1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Netronome Systems, Inc.
11 #include "nfp6000/nfp6000.h"
12 #include "nfp_resource.h"
15 #define NFP_RESOURCE_TBL_TARGET NFP_CPP_TARGET_MU
16 #define NFP_RESOURCE_TBL_BASE 0x8100000000ULL
18 /* NFP Resource Table self-identifier */
19 #define NFP_RESOURCE_TBL_NAME "nfp.res"
20 #define NFP_RESOURCE_TBL_KEY 0x00000000 /* Special key for entry 0 */
22 #define NFP_RESOURCE_ENTRY_NAME_SZ 8
25 * struct nfp_resource_entry - Resource table entry
26 * @owner: NFP CPP Lock, interface owner
27 * @key: NFP CPP Lock, posix_crc32(name, 8)
28 * @region: Memory region descriptor
29 * @name: ASCII, zero padded name
31 * @cpp_action: CPP Action
32 * @cpp_token: CPP Token
33 * @cpp_target: CPP Target ID
34 * @page_offset: 256-byte page offset into target's CPP address
35 * @page_size: size, in 256-byte pages
37 struct nfp_resource_entry {
38 struct nfp_resource_entry_mutex {
42 struct nfp_resource_entry_region {
43 uint8_t name[NFP_RESOURCE_ENTRY_NAME_SZ];
53 #define NFP_RESOURCE_TBL_SIZE 4096
54 #define NFP_RESOURCE_TBL_ENTRIES (int)(NFP_RESOURCE_TBL_SIZE / \
55 sizeof(struct nfp_resource_entry))
58 char name[NFP_RESOURCE_ENTRY_NAME_SZ + 1];
62 struct nfp_cpp_mutex *mutex;
66 nfp_cpp_resource_find(struct nfp_cpp *cpp, struct nfp_resource *res)
68 char name_pad[NFP_RESOURCE_ENTRY_NAME_SZ] = {};
69 struct nfp_resource_entry entry;
73 cpp_id = NFP_CPP_ID(NFP_RESOURCE_TBL_TARGET, 3, 0); /* Atomic read */
75 memset(name_pad, 0, NFP_RESOURCE_ENTRY_NAME_SZ);
76 strncpy(name_pad, res->name, sizeof(name_pad));
78 /* Search for a matching entry */
79 if (!memcmp(name_pad, NFP_RESOURCE_TBL_NAME "\0\0\0\0\0\0\0\0", 8)) {
80 printf("Grabbing device lock not supported\n");
83 key = nfp_crc32_posix(name_pad, sizeof(name_pad));
85 for (i = 0; i < NFP_RESOURCE_TBL_ENTRIES; i++) {
86 uint64_t addr = NFP_RESOURCE_TBL_BASE +
87 sizeof(struct nfp_resource_entry) * i;
89 ret = nfp_cpp_read(cpp, cpp_id, addr, &entry, sizeof(entry));
90 if (ret != sizeof(entry))
93 if (entry.mutex.key != key)
98 nfp_cpp_mutex_alloc(cpp,
99 NFP_RESOURCE_TBL_TARGET, addr, key);
100 res->cpp_id = NFP_CPP_ID(entry.region.cpp_target,
101 entry.region.cpp_action,
102 entry.region.cpp_token);
103 res->addr = ((uint64_t)entry.region.page_offset) << 8;
104 res->size = (uint64_t)entry.region.page_size << 8;
112 nfp_resource_try_acquire(struct nfp_cpp *cpp, struct nfp_resource *res,
113 struct nfp_cpp_mutex *dev_mutex)
117 if (nfp_cpp_mutex_lock(dev_mutex))
120 err = nfp_cpp_resource_find(cpp, res);
124 err = nfp_cpp_mutex_trylock(res->mutex);
126 goto err_res_mutex_free;
128 nfp_cpp_mutex_unlock(dev_mutex);
133 nfp_cpp_mutex_free(res->mutex);
135 nfp_cpp_mutex_unlock(dev_mutex);
141 * nfp_resource_acquire() - Acquire a resource handle
142 * @cpp: NFP CPP handle
143 * @name: Name of the resource
145 * NOTE: This function locks the acquired resource
147 * Return: NFP Resource handle, or ERR_PTR()
149 struct nfp_resource *
150 nfp_resource_acquire(struct nfp_cpp *cpp, const char *name)
152 struct nfp_cpp_mutex *dev_mutex;
153 struct nfp_resource *res;
155 struct timespec wait;
158 res = malloc(sizeof(*res));
162 memset(res, 0, sizeof(*res));
164 strncpy(res->name, name, NFP_RESOURCE_ENTRY_NAME_SZ);
166 dev_mutex = nfp_cpp_mutex_alloc(cpp, NFP_RESOURCE_TBL_TARGET,
167 NFP_RESOURCE_TBL_BASE,
168 NFP_RESOURCE_TBL_KEY);
175 wait.tv_nsec = 1000000;
179 err = nfp_resource_try_acquire(cpp, res, dev_mutex);
185 if (count++ > 1000) {
186 printf("Error: resource %s timed out\n", name);
191 nanosleep(&wait, NULL);
194 nfp_cpp_mutex_free(dev_mutex);
199 nfp_cpp_mutex_free(dev_mutex);
205 * nfp_resource_release() - Release a NFP Resource handle
206 * @res: NFP Resource handle
208 * NOTE: This function implictly unlocks the resource handle
211 nfp_resource_release(struct nfp_resource *res)
213 nfp_cpp_mutex_unlock(res->mutex);
214 nfp_cpp_mutex_free(res->mutex);
219 * nfp_resource_cpp_id() - Return the cpp_id of a resource handle
220 * @res: NFP Resource handle
225 nfp_resource_cpp_id(const struct nfp_resource *res)
231 * nfp_resource_name() - Return the name of a resource handle
232 * @res: NFP Resource handle
234 * Return: const char pointer to the name of the resource
237 *nfp_resource_name(const struct nfp_resource *res)
243 * nfp_resource_address() - Return the address of a resource handle
244 * @res: NFP Resource handle
246 * Return: Address of the resource
249 nfp_resource_address(const struct nfp_resource *res)
255 * nfp_resource_size() - Return the size in bytes of a resource handle
256 * @res: NFP Resource handle
258 * Return: Size of the resource in bytes
261 nfp_resource_size(const struct nfp_resource *res)