1 | /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ |
2 | /* Copyright (C) 2015-2018 Netronome Systems, Inc. */ |
3 | |
4 | /* |
5 | * nfp_cpp.h |
6 | * Interface for low-level NFP CPP access. |
7 | * Authors: Jason McMullan <jason.mcmullan@netronome.com> |
8 | * Rolf Neugebauer <rolf.neugebauer@netronome.com> |
9 | */ |
10 | #ifndef __NFP_CPP_H__ |
11 | #define __NFP_CPP_H__ |
12 | |
13 | #include <linux/ctype.h> |
14 | #include <linux/types.h> |
15 | #include <linux/sizes.h> |
16 | |
17 | #ifndef NFP_SUBSYS |
18 | #define NFP_SUBSYS "nfp" |
19 | #endif |
20 | |
21 | #define nfp_err(cpp, fmt, args...) \ |
22 | dev_err(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args) |
23 | #define nfp_warn(cpp, fmt, args...) \ |
24 | dev_warn(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args) |
25 | #define nfp_info(cpp, fmt, args...) \ |
26 | dev_info(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args) |
27 | #define nfp_dbg(cpp, fmt, args...) \ |
28 | dev_dbg(nfp_cpp_device(cpp)->parent, NFP_SUBSYS ": " fmt, ## args) |
29 | #define nfp_printk(level, cpp, fmt, args...) \ |
30 | dev_printk(level, nfp_cpp_device(cpp)->parent, \ |
31 | NFP_SUBSYS ": " fmt, ## args) |
32 | |
33 | #define PCI_64BIT_BAR_COUNT 3 |
34 | |
35 | #define NFP_CPP_NUM_TARGETS 16 |
36 | /* Max size of area it should be safe to request */ |
37 | #define NFP_CPP_SAFE_AREA_SIZE SZ_2M |
38 | |
39 | /* NFP_MUTEX_WAIT_* are timeouts in seconds when waiting for a mutex */ |
40 | #define NFP_MUTEX_WAIT_FIRST_WARN 15 |
41 | #define NFP_MUTEX_WAIT_NEXT_WARN 5 |
42 | #define NFP_MUTEX_WAIT_ERROR 60 |
43 | |
44 | struct device; |
45 | |
46 | struct nfp_cpp_area; |
47 | struct nfp_cpp; |
48 | struct resource; |
49 | |
50 | /* Wildcard indicating a CPP read or write action |
51 | * |
52 | * The action used will be either read or write depending on whether a |
53 | * read or write instruction/call is performed on the NFP_CPP_ID. It |
54 | * is recomended that the RW action is used even if all actions to be |
55 | * performed on a NFP_CPP_ID are known to be only reads or writes. |
56 | * Doing so will in many cases save NFP CPP internal software |
57 | * resources. |
58 | */ |
59 | #define NFP_CPP_ACTION_RW 32 |
60 | |
61 | #define NFP_CPP_TARGET_ID_MASK 0x1f |
62 | |
63 | #define NFP_CPP_ATOMIC_RD(target, island) \ |
64 | NFP_CPP_ISLAND_ID((target), 3, 0, (island)) |
65 | #define NFP_CPP_ATOMIC_WR(target, island) \ |
66 | NFP_CPP_ISLAND_ID((target), 4, 0, (island)) |
67 | |
68 | /** |
69 | * NFP_CPP_ID() - pack target, token, and action into a CPP ID. |
70 | * @target: NFP CPP target id |
71 | * @action: NFP CPP action id |
72 | * @token: NFP CPP token id |
73 | * |
74 | * Create a 32-bit CPP identifier representing the access to be made. |
75 | * These identifiers are used as parameters to other NFP CPP |
76 | * functions. Some CPP devices may allow wildcard identifiers to be |
77 | * specified. |
78 | * |
79 | * Return: NFP CPP ID |
80 | */ |
81 | #define NFP_CPP_ID(target, action, token) \ |
82 | ((((target) & 0x7f) << 24) | (((token) & 0xff) << 16) | \ |
83 | (((action) & 0xff) << 8)) |
84 | |
85 | /** |
86 | * NFP_CPP_ISLAND_ID() - pack target, token, action, and island into a CPP ID. |
87 | * @target: NFP CPP target id |
88 | * @action: NFP CPP action id |
89 | * @token: NFP CPP token id |
90 | * @island: NFP CPP island id |
91 | * |
92 | * Create a 32-bit CPP identifier representing the access to be made. |
93 | * These identifiers are used as parameters to other NFP CPP |
94 | * functions. Some CPP devices may allow wildcard identifiers to be |
95 | * specified. |
96 | * |
97 | * Return: NFP CPP ID |
98 | */ |
99 | #define NFP_CPP_ISLAND_ID(target, action, token, island) \ |
100 | ((((target) & 0x7f) << 24) | (((token) & 0xff) << 16) | \ |
101 | (((action) & 0xff) << 8) | (((island) & 0xff) << 0)) |
102 | |
103 | /** |
104 | * NFP_CPP_ID_TARGET_of() - Return the NFP CPP target of a NFP CPP ID |
105 | * @id: NFP CPP ID |
106 | * |
107 | * Return: NFP CPP target |
108 | */ |
109 | static inline u8 NFP_CPP_ID_TARGET_of(u32 id) |
110 | { |
111 | return (id >> 24) & NFP_CPP_TARGET_ID_MASK; |
112 | } |
113 | |
114 | /** |
115 | * NFP_CPP_ID_TOKEN_of() - Return the NFP CPP token of a NFP CPP ID |
116 | * @id: NFP CPP ID |
117 | * Return: NFP CPP token |
118 | */ |
119 | static inline u8 NFP_CPP_ID_TOKEN_of(u32 id) |
120 | { |
121 | return (id >> 16) & 0xff; |
122 | } |
123 | |
124 | /** |
125 | * NFP_CPP_ID_ACTION_of() - Return the NFP CPP action of a NFP CPP ID |
126 | * @id: NFP CPP ID |
127 | * |
128 | * Return: NFP CPP action |
129 | */ |
130 | static inline u8 NFP_CPP_ID_ACTION_of(u32 id) |
131 | { |
132 | return (id >> 8) & 0xff; |
133 | } |
134 | |
135 | /** |
136 | * NFP_CPP_ID_ISLAND_of() - Return the NFP CPP island of a NFP CPP ID |
137 | * @id: NFP CPP ID |
138 | * |
139 | * Return: NFP CPP island |
140 | */ |
141 | static inline u8 NFP_CPP_ID_ISLAND_of(u32 id) |
142 | { |
143 | return (id >> 0) & 0xff; |
144 | } |
145 | |
146 | /* NFP Interface types - logical interface for this CPP connection |
147 | * 4 bits are reserved for interface type. |
148 | */ |
149 | #define NFP_CPP_INTERFACE_TYPE_INVALID 0x0 |
150 | #define NFP_CPP_INTERFACE_TYPE_PCI 0x1 |
151 | #define NFP_CPP_INTERFACE_TYPE_ARM 0x2 |
152 | #define NFP_CPP_INTERFACE_TYPE_RPC 0x3 |
153 | #define NFP_CPP_INTERFACE_TYPE_ILA 0x4 |
154 | |
155 | /** |
156 | * NFP_CPP_INTERFACE() - Construct a 16-bit NFP Interface ID |
157 | * @type: NFP Interface Type |
158 | * @unit: Unit identifier for the interface type |
159 | * @channel: Channel identifier for the interface unit |
160 | * |
161 | * Interface IDs consists of 4 bits of interface type, |
162 | * 4 bits of unit identifier, and 8 bits of channel identifier. |
163 | * |
164 | * The NFP Interface ID is used in the implementation of |
165 | * NFP CPP API mutexes, which use the MU Atomic CompareAndWrite |
166 | * operation - hence the limit to 16 bits to be able to |
167 | * use the NFP Interface ID as a lock owner. |
168 | * |
169 | * Return: Interface ID |
170 | */ |
171 | #define NFP_CPP_INTERFACE(type, unit, channel) \ |
172 | ((((type) & 0xf) << 12) | \ |
173 | (((unit) & 0xf) << 8) | \ |
174 | (((channel) & 0xff) << 0)) |
175 | |
176 | /** |
177 | * NFP_CPP_INTERFACE_TYPE_of() - Get the interface type |
178 | * @interface: NFP Interface ID |
179 | * Return: NFP Interface ID's type |
180 | */ |
181 | #define NFP_CPP_INTERFACE_TYPE_of(interface) (((interface) >> 12) & 0xf) |
182 | |
183 | /** |
184 | * NFP_CPP_INTERFACE_UNIT_of() - Get the interface unit |
185 | * @interface: NFP Interface ID |
186 | * Return: NFP Interface ID's unit |
187 | */ |
188 | #define NFP_CPP_INTERFACE_UNIT_of(interface) (((interface) >> 8) & 0xf) |
189 | |
190 | /** |
191 | * NFP_CPP_INTERFACE_CHANNEL_of() - Get the interface channel |
192 | * @interface: NFP Interface ID |
193 | * Return: NFP Interface ID's channel |
194 | */ |
195 | #define NFP_CPP_INTERFACE_CHANNEL_of(interface) (((interface) >> 0) & 0xff) |
196 | |
197 | /* Implemented in nfp_cppcore.c */ |
198 | void nfp_cpp_free(struct nfp_cpp *cpp); |
199 | u32 nfp_cpp_model(struct nfp_cpp *cpp); |
200 | u16 nfp_cpp_interface(struct nfp_cpp *cpp); |
201 | int nfp_cpp_serial(struct nfp_cpp *cpp, const u8 **serial); |
202 | unsigned int nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp); |
203 | |
204 | struct nfp_cpp_area *nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, |
205 | u32 cpp_id, |
206 | const char *name, |
207 | unsigned long long address, |
208 | unsigned long size); |
209 | struct nfp_cpp_area *nfp_cpp_area_alloc(struct nfp_cpp *cpp, u32 cpp_id, |
210 | unsigned long long address, |
211 | unsigned long size); |
212 | struct nfp_cpp_area * |
213 | nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, const char *name, u32 cpp_id, |
214 | unsigned long long address, unsigned long size); |
215 | void nfp_cpp_area_free(struct nfp_cpp_area *area); |
216 | int nfp_cpp_area_acquire(struct nfp_cpp_area *area); |
217 | int nfp_cpp_area_acquire_nonblocking(struct nfp_cpp_area *area); |
218 | void nfp_cpp_area_release(struct nfp_cpp_area *area); |
219 | void nfp_cpp_area_release_free(struct nfp_cpp_area *area); |
220 | int nfp_cpp_area_read(struct nfp_cpp_area *area, unsigned long offset, |
221 | void *buffer, size_t length); |
222 | int nfp_cpp_area_write(struct nfp_cpp_area *area, unsigned long offset, |
223 | const void *buffer, size_t length); |
224 | size_t nfp_cpp_area_size(struct nfp_cpp_area *area); |
225 | const char *nfp_cpp_area_name(struct nfp_cpp_area *cpp_area); |
226 | void *nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area); |
227 | struct nfp_cpp *nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area); |
228 | struct resource *nfp_cpp_area_resource(struct nfp_cpp_area *area); |
229 | phys_addr_t nfp_cpp_area_phys(struct nfp_cpp_area *area); |
230 | void __iomem *nfp_cpp_area_iomem(struct nfp_cpp_area *area); |
231 | |
232 | int nfp_cpp_area_readl(struct nfp_cpp_area *area, unsigned long offset, |
233 | u32 *value); |
234 | int nfp_cpp_area_writel(struct nfp_cpp_area *area, unsigned long offset, |
235 | u32 value); |
236 | int nfp_cpp_area_readq(struct nfp_cpp_area *area, unsigned long offset, |
237 | u64 *value); |
238 | int nfp_cpp_area_writeq(struct nfp_cpp_area *area, unsigned long offset, |
239 | u64 value); |
240 | int nfp_cpp_area_fill(struct nfp_cpp_area *area, unsigned long offset, |
241 | u32 value, size_t length); |
242 | |
243 | int nfp_xpb_readl(struct nfp_cpp *cpp, u32 xpb_tgt, u32 *value); |
244 | int nfp_xpb_writel(struct nfp_cpp *cpp, u32 xpb_tgt, u32 value); |
245 | int nfp_xpb_writelm(struct nfp_cpp *cpp, u32 xpb_tgt, u32 mask, u32 value); |
246 | |
247 | /* Implemented in nfp_cpplib.c */ |
248 | int nfp_cpp_read(struct nfp_cpp *cpp, u32 cpp_id, |
249 | unsigned long long address, void *kernel_vaddr, size_t length); |
250 | int nfp_cpp_write(struct nfp_cpp *cpp, u32 cpp_id, |
251 | unsigned long long address, const void *kernel_vaddr, |
252 | size_t length); |
253 | int nfp_cpp_readl(struct nfp_cpp *cpp, u32 cpp_id, |
254 | unsigned long long address, u32 *value); |
255 | int nfp_cpp_writel(struct nfp_cpp *cpp, u32 cpp_id, |
256 | unsigned long long address, u32 value); |
257 | int nfp_cpp_readq(struct nfp_cpp *cpp, u32 cpp_id, |
258 | unsigned long long address, u64 *value); |
259 | int nfp_cpp_writeq(struct nfp_cpp *cpp, u32 cpp_id, |
260 | unsigned long long address, u64 value); |
261 | |
262 | u8 __iomem * |
263 | nfp_cpp_map_area(struct nfp_cpp *cpp, const char *name, u32 cpp_id, u64 addr, |
264 | unsigned long size, struct nfp_cpp_area **area); |
265 | |
266 | struct nfp_cpp_mutex; |
267 | |
268 | int nfp_cpp_mutex_init(struct nfp_cpp *cpp, int target, |
269 | unsigned long long address, u32 key_id); |
270 | struct nfp_cpp_mutex *nfp_cpp_mutex_alloc(struct nfp_cpp *cpp, int target, |
271 | unsigned long long address, |
272 | u32 key_id); |
273 | void nfp_cpp_mutex_free(struct nfp_cpp_mutex *mutex); |
274 | int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex); |
275 | int nfp_cpp_mutex_unlock(struct nfp_cpp_mutex *mutex); |
276 | int nfp_cpp_mutex_trylock(struct nfp_cpp_mutex *mutex); |
277 | int nfp_cpp_mutex_reclaim(struct nfp_cpp *cpp, int target, |
278 | unsigned long long address); |
279 | |
280 | /** |
281 | * nfp_cppcore_pcie_unit() - Get PCI Unit of a CPP handle |
282 | * @cpp: CPP handle |
283 | * |
284 | * Return: PCI unit for the NFP CPP handle |
285 | */ |
286 | static inline u8 nfp_cppcore_pcie_unit(struct nfp_cpp *cpp) |
287 | { |
288 | return NFP_CPP_INTERFACE_UNIT_of(nfp_cpp_interface(cpp)); |
289 | } |
290 | |
291 | struct nfp_cpp_explicit; |
292 | |
293 | struct nfp_cpp_explicit_command { |
294 | u32 cpp_id; |
295 | u16 data_ref; |
296 | u8 data_master; |
297 | u8 len; |
298 | u8 byte_mask; |
299 | u8 signal_master; |
300 | u8 signal_ref; |
301 | u8 posted; |
302 | u8 siga; |
303 | u8 sigb; |
304 | s8 siga_mode; |
305 | s8 sigb_mode; |
306 | }; |
307 | |
308 | #define NFP_SERIAL_LEN 6 |
309 | |
310 | /** |
311 | * struct nfp_cpp_operations - NFP CPP operations structure |
312 | * @area_priv_size: Size of the nfp_cpp_area private data |
313 | * @owner: Owner module |
314 | * @init: Initialize the NFP CPP bus |
315 | * @free: Free the bus |
316 | * @read_serial: Read serial number to memory provided |
317 | * @get_interface: Return CPP interface |
318 | * @area_init: Initialize a new NFP CPP area (not serialized) |
319 | * @area_cleanup: Clean up a NFP CPP area (not serialized) |
320 | * @area_acquire: Acquire the NFP CPP area (serialized) |
321 | * @area_release: Release area (serialized) |
322 | * @area_resource: Get resource range of area (not serialized) |
323 | * @area_phys: Get physical address of area (not serialized) |
324 | * @area_iomem: Get iomem of area (not serialized) |
325 | * @area_read: Perform a read from a NFP CPP area (serialized) |
326 | * @area_write: Perform a write to a NFP CPP area (serialized) |
327 | * @explicit_priv_size: Size of an explicit's private area |
328 | * @explicit_acquire: Acquire an explicit area |
329 | * @explicit_release: Release an explicit area |
330 | * @explicit_put: Write data to send |
331 | * @explicit_get: Read data received |
332 | * @explicit_do: Perform the transaction |
333 | */ |
334 | struct nfp_cpp_operations { |
335 | size_t area_priv_size; |
336 | struct module *owner; |
337 | |
338 | int (*init)(struct nfp_cpp *cpp); |
339 | void (*free)(struct nfp_cpp *cpp); |
340 | |
341 | int (*read_serial)(struct device *dev, u8 *serial); |
342 | int (*get_interface)(struct device *dev); |
343 | |
344 | int (*area_init)(struct nfp_cpp_area *area, |
345 | u32 dest, unsigned long long address, |
346 | unsigned long size); |
347 | void (*area_cleanup)(struct nfp_cpp_area *area); |
348 | int (*area_acquire)(struct nfp_cpp_area *area); |
349 | void (*area_release)(struct nfp_cpp_area *area); |
350 | struct resource *(*area_resource)(struct nfp_cpp_area *area); |
351 | phys_addr_t (*area_phys)(struct nfp_cpp_area *area); |
352 | void __iomem *(*area_iomem)(struct nfp_cpp_area *area); |
353 | int (*area_read)(struct nfp_cpp_area *area, void *kernel_vaddr, |
354 | unsigned long offset, unsigned int length); |
355 | int (*area_write)(struct nfp_cpp_area *area, const void *kernel_vaddr, |
356 | unsigned long offset, unsigned int length); |
357 | |
358 | size_t explicit_priv_size; |
359 | int (*explicit_acquire)(struct nfp_cpp_explicit *expl); |
360 | void (*explicit_release)(struct nfp_cpp_explicit *expl); |
361 | int (*explicit_put)(struct nfp_cpp_explicit *expl, |
362 | const void *buff, size_t len); |
363 | int (*explicit_get)(struct nfp_cpp_explicit *expl, |
364 | void *buff, size_t len); |
365 | int (*explicit_do)(struct nfp_cpp_explicit *expl, |
366 | const struct nfp_cpp_explicit_command *cmd, |
367 | u64 address); |
368 | }; |
369 | |
370 | struct nfp_cpp * |
371 | nfp_cpp_from_operations(const struct nfp_cpp_operations *ops, |
372 | struct device *parent, void *priv); |
373 | void *nfp_cpp_priv(struct nfp_cpp *priv); |
374 | |
375 | int nfp_cpp_area_cache_add(struct nfp_cpp *cpp, size_t size); |
376 | |
377 | /* The following section contains extensions to the |
378 | * NFP CPP API, to be used in a Linux kernel-space context. |
379 | */ |
380 | |
381 | /* Use this channel ID for multiple virtual channel interfaces |
382 | * (ie ARM and PCIe) when setting up the interface field. |
383 | */ |
384 | #define NFP_CPP_INTERFACE_CHANNEL_PEROPENER 255 |
385 | struct device *nfp_cpp_device(struct nfp_cpp *cpp); |
386 | |
387 | /* Return code masks for nfp_cpp_explicit_do() |
388 | */ |
389 | #define NFP_SIGNAL_MASK_A BIT(0) /* Signal A fired */ |
390 | #define NFP_SIGNAL_MASK_B BIT(1) /* Signal B fired */ |
391 | |
392 | enum nfp_cpp_explicit_signal_mode { |
393 | NFP_SIGNAL_NONE = 0, |
394 | NFP_SIGNAL_PUSH = 1, |
395 | NFP_SIGNAL_PUSH_OPTIONAL = -1, |
396 | NFP_SIGNAL_PULL = 2, |
397 | NFP_SIGNAL_PULL_OPTIONAL = -2, |
398 | }; |
399 | |
400 | struct nfp_cpp_explicit *nfp_cpp_explicit_acquire(struct nfp_cpp *cpp); |
401 | int nfp_cpp_explicit_set_target(struct nfp_cpp_explicit *expl, u32 cpp_id, |
402 | u8 len, u8 mask); |
403 | int nfp_cpp_explicit_set_data(struct nfp_cpp_explicit *expl, |
404 | u8 data_master, u16 data_ref); |
405 | int nfp_cpp_explicit_set_signal(struct nfp_cpp_explicit *expl, |
406 | u8 signal_master, u8 signal_ref); |
407 | int nfp_cpp_explicit_set_posted(struct nfp_cpp_explicit *expl, int posted, |
408 | u8 siga, |
409 | enum nfp_cpp_explicit_signal_mode siga_mode, |
410 | u8 sigb, |
411 | enum nfp_cpp_explicit_signal_mode sigb_mode); |
412 | int nfp_cpp_explicit_put(struct nfp_cpp_explicit *expl, |
413 | const void *buff, size_t len); |
414 | int nfp_cpp_explicit_do(struct nfp_cpp_explicit *expl, u64 address); |
415 | int nfp_cpp_explicit_get(struct nfp_cpp_explicit *expl, void *buff, size_t len); |
416 | void nfp_cpp_explicit_release(struct nfp_cpp_explicit *expl); |
417 | struct nfp_cpp *nfp_cpp_explicit_cpp(struct nfp_cpp_explicit *expl); |
418 | void *nfp_cpp_explicit_priv(struct nfp_cpp_explicit *cpp_explicit); |
419 | |
420 | /* Implemented in nfp_cpplib.c */ |
421 | |
422 | int nfp_cpp_model_autodetect(struct nfp_cpp *cpp, u32 *model); |
423 | |
424 | int nfp_cpp_explicit_read(struct nfp_cpp *cpp, u32 cpp_id, |
425 | u64 addr, void *buff, size_t len, |
426 | int width_read); |
427 | |
428 | int nfp_cpp_explicit_write(struct nfp_cpp *cpp, u32 cpp_id, |
429 | u64 addr, const void *buff, size_t len, |
430 | int width_write); |
431 | |
432 | #endif /* !__NFP_CPP_H__ */ |
433 | |