1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Netronome Systems, Inc.
10 #include <rte_string_fns.h>
13 #include "nfp6000/nfp6000.h"
14 #include "nfp_resource.h"
17 #define NFP_RESOURCE_TBL_TARGET NFP_CPP_TARGET_MU
18 #define NFP_RESOURCE_TBL_BASE 0x8100000000ULL
20 /* NFP Resource Table self-identifier */
21 #define NFP_RESOURCE_TBL_NAME "nfp.res"
22 #define NFP_RESOURCE_TBL_KEY 0x00000000 /* Special key for entry 0 */
24 #define NFP_RESOURCE_ENTRY_NAME_SZ 8
27 * struct nfp_resource_entry - Resource table entry
28 * @owner: NFP CPP Lock, interface owner
29 * @key: NFP CPP Lock, posix_crc32(name, 8)
30 * @region: Memory region descriptor
31 * @name: ASCII, zero padded name
33 * @cpp_action: CPP Action
34 * @cpp_token: CPP Token
35 * @cpp_target: CPP Target ID
36 * @page_offset: 256-byte page offset into target's CPP address
37 * @page_size: size, in 256-byte pages
39 struct nfp_resource_entry
{
40 struct nfp_resource_entry_mutex
{
44 struct nfp_resource_entry_region
{
45 uint8_t name
[NFP_RESOURCE_ENTRY_NAME_SZ
];
55 #define NFP_RESOURCE_TBL_SIZE 4096
56 #define NFP_RESOURCE_TBL_ENTRIES (int)(NFP_RESOURCE_TBL_SIZE / \
57 sizeof(struct nfp_resource_entry))
60 char name
[NFP_RESOURCE_ENTRY_NAME_SZ
+ 1];
64 struct nfp_cpp_mutex
*mutex
;
68 nfp_cpp_resource_find(struct nfp_cpp
*cpp
, struct nfp_resource
*res
)
70 char name_pad
[NFP_RESOURCE_ENTRY_NAME_SZ
+ 2];
71 struct nfp_resource_entry entry
;
75 cpp_id
= NFP_CPP_ID(NFP_RESOURCE_TBL_TARGET
, 3, 0); /* Atomic read */
77 memset(name_pad
, 0, sizeof(name_pad
));
78 strlcpy(name_pad
, res
->name
, sizeof(name_pad
));
80 /* Search for a matching entry */
81 if (!memcmp(name_pad
, NFP_RESOURCE_TBL_NAME
"\0\0\0\0\0\0\0\0", 8)) {
82 printf("Grabbing device lock not supported\n");
85 key
= nfp_crc32_posix(name_pad
, NFP_RESOURCE_ENTRY_NAME_SZ
);
87 for (i
= 0; i
< NFP_RESOURCE_TBL_ENTRIES
; i
++) {
88 uint64_t addr
= NFP_RESOURCE_TBL_BASE
+
89 sizeof(struct nfp_resource_entry
) * i
;
91 ret
= nfp_cpp_read(cpp
, cpp_id
, addr
, &entry
, sizeof(entry
));
92 if (ret
!= sizeof(entry
))
95 if (entry
.mutex
.key
!= key
)
100 nfp_cpp_mutex_alloc(cpp
,
101 NFP_RESOURCE_TBL_TARGET
, addr
, key
);
102 res
->cpp_id
= NFP_CPP_ID(entry
.region
.cpp_target
,
103 entry
.region
.cpp_action
,
104 entry
.region
.cpp_token
);
105 res
->addr
= ((uint64_t)entry
.region
.page_offset
) << 8;
106 res
->size
= (uint64_t)entry
.region
.page_size
<< 8;
114 nfp_resource_try_acquire(struct nfp_cpp
*cpp
, struct nfp_resource
*res
,
115 struct nfp_cpp_mutex
*dev_mutex
)
119 if (nfp_cpp_mutex_lock(dev_mutex
))
122 err
= nfp_cpp_resource_find(cpp
, res
);
126 err
= nfp_cpp_mutex_trylock(res
->mutex
);
128 goto err_res_mutex_free
;
130 nfp_cpp_mutex_unlock(dev_mutex
);
135 nfp_cpp_mutex_free(res
->mutex
);
137 nfp_cpp_mutex_unlock(dev_mutex
);
143 * nfp_resource_acquire() - Acquire a resource handle
144 * @cpp: NFP CPP handle
145 * @name: Name of the resource
147 * NOTE: This function locks the acquired resource
149 * Return: NFP Resource handle, or ERR_PTR()
151 struct nfp_resource
*
152 nfp_resource_acquire(struct nfp_cpp
*cpp
, const char *name
)
154 struct nfp_cpp_mutex
*dev_mutex
;
155 struct nfp_resource
*res
;
157 struct timespec wait
;
160 res
= malloc(sizeof(*res
));
164 memset(res
, 0, sizeof(*res
));
166 strncpy(res
->name
, name
, NFP_RESOURCE_ENTRY_NAME_SZ
);
168 dev_mutex
= nfp_cpp_mutex_alloc(cpp
, NFP_RESOURCE_TBL_TARGET
,
169 NFP_RESOURCE_TBL_BASE
,
170 NFP_RESOURCE_TBL_KEY
);
177 wait
.tv_nsec
= 1000000;
181 err
= nfp_resource_try_acquire(cpp
, res
, dev_mutex
);
187 if (count
++ > 1000) {
188 printf("Error: resource %s timed out\n", name
);
193 nanosleep(&wait
, NULL
);
196 nfp_cpp_mutex_free(dev_mutex
);
201 nfp_cpp_mutex_free(dev_mutex
);
207 * nfp_resource_release() - Release a NFP Resource handle
208 * @res: NFP Resource handle
210 * NOTE: This function implictly unlocks the resource handle
213 nfp_resource_release(struct nfp_resource
*res
)
215 nfp_cpp_mutex_unlock(res
->mutex
);
216 nfp_cpp_mutex_free(res
->mutex
);
221 * nfp_resource_cpp_id() - Return the cpp_id of a resource handle
222 * @res: NFP Resource handle
227 nfp_resource_cpp_id(const struct nfp_resource
*res
)
233 * nfp_resource_name() - Return the name of a resource handle
234 * @res: NFP Resource handle
236 * Return: const char pointer to the name of the resource
239 *nfp_resource_name(const struct nfp_resource
*res
)
245 * nfp_resource_address() - Return the address of a resource handle
246 * @res: NFP Resource handle
248 * Return: Address of the resource
251 nfp_resource_address(const struct nfp_resource
*res
)
257 * nfp_resource_size() - Return the size in bytes of a resource handle
258 * @res: NFP Resource handle
260 * Return: Size of the resource in bytes
263 nfp_resource_size(const struct nfp_resource
*res
)