forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_rtsym.c
....@@ -1,35 +1,5 @@
1
-/*
2
- * Copyright (C) 2015-2017 Netronome Systems, Inc.
3
- *
4
- * This software is dual licensed under the GNU General License Version 2,
5
- * June 1991 as shown in the file COPYING in the top-level directory of this
6
- * source tree or the BSD 2-Clause License provided below. You have the
7
- * option to license this software under the complete terms of either license.
8
- *
9
- * The BSD 2-Clause License:
10
- *
11
- * Redistribution and use in source and binary forms, with or
12
- * without modification, are permitted provided that the following
13
- * conditions are met:
14
- *
15
- * 1. Redistributions of source code must retain the above
16
- * copyright notice, this list of conditions and the following
17
- * disclaimer.
18
- *
19
- * 2. Redistributions in binary form must reproduce the above
20
- * copyright notice, this list of conditions and the following
21
- * disclaimer in the documentation and/or other materials
22
- * provided with the distribution.
23
- *
24
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
- * SOFTWARE.
32
- */
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2
+/* Copyright (C) 2015-2018 Netronome Systems, Inc. */
333
344 /*
355 * nfp_rtsym.c
....@@ -39,6 +9,8 @@
399 * Espen Skoglund <espen.skoglund@netronome.com>
4010 * Francois H. Theron <francois.theron@netronome.com>
4111 */
12
+
13
+#include <asm/unaligned.h>
4214 #include <linux/kernel.h>
4315 #include <linux/module.h>
4416 #include <linux/slab.h>
....@@ -233,6 +205,229 @@
233205 return NULL;
234206 }
235207
208
+u64 nfp_rtsym_size(const struct nfp_rtsym *sym)
209
+{
210
+ switch (sym->type) {
211
+ case NFP_RTSYM_TYPE_NONE:
212
+ pr_err("rtsym '%s': type NONE\n", sym->name);
213
+ return 0;
214
+ default:
215
+ pr_warn("rtsym '%s': unknown type: %d\n", sym->name, sym->type);
216
+ fallthrough;
217
+ case NFP_RTSYM_TYPE_OBJECT:
218
+ case NFP_RTSYM_TYPE_FUNCTION:
219
+ return sym->size;
220
+ case NFP_RTSYM_TYPE_ABS:
221
+ return sizeof(u64);
222
+ }
223
+}
224
+
225
+static int
226
+nfp_rtsym_to_dest(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
227
+ u8 action, u8 token, u64 off, u32 *cpp_id, u64 *addr)
228
+{
229
+ if (sym->type != NFP_RTSYM_TYPE_OBJECT) {
230
+ nfp_err(cpp, "rtsym '%s': direct access to non-object rtsym\n",
231
+ sym->name);
232
+ return -EINVAL;
233
+ }
234
+
235
+ *addr = sym->addr + off;
236
+
237
+ if (sym->target == NFP_RTSYM_TARGET_EMU_CACHE) {
238
+ int locality_off = nfp_cpp_mu_locality_lsb(cpp);
239
+
240
+ *addr &= ~(NFP_MU_ADDR_ACCESS_TYPE_MASK << locality_off);
241
+ *addr |= NFP_MU_ADDR_ACCESS_TYPE_DIRECT << locality_off;
242
+
243
+ *cpp_id = NFP_CPP_ISLAND_ID(NFP_CPP_TARGET_MU, action, token,
244
+ sym->domain);
245
+ } else if (sym->target < 0) {
246
+ nfp_err(cpp, "rtsym '%s': unhandled target encoding: %d\n",
247
+ sym->name, sym->target);
248
+ return -EINVAL;
249
+ } else {
250
+ *cpp_id = NFP_CPP_ISLAND_ID(sym->target, action, token,
251
+ sym->domain);
252
+ }
253
+
254
+ return 0;
255
+}
256
+
257
+int __nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
258
+ u8 action, u8 token, u64 off, void *buf, size_t len)
259
+{
260
+ u64 sym_size = nfp_rtsym_size(sym);
261
+ u32 cpp_id;
262
+ u64 addr;
263
+ int err;
264
+
265
+ if (off > sym_size) {
266
+ nfp_err(cpp, "rtsym '%s': read out of bounds: off: %lld + len: %zd > size: %lld\n",
267
+ sym->name, off, len, sym_size);
268
+ return -ENXIO;
269
+ }
270
+ len = min_t(size_t, len, sym_size - off);
271
+
272
+ if (sym->type == NFP_RTSYM_TYPE_ABS) {
273
+ u8 tmp[8];
274
+
275
+ put_unaligned_le64(sym->addr, tmp);
276
+ memcpy(buf, &tmp[off], len);
277
+
278
+ return len;
279
+ }
280
+
281
+ err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
282
+ if (err)
283
+ return err;
284
+
285
+ return nfp_cpp_read(cpp, cpp_id, addr, buf, len);
286
+}
287
+
288
+int nfp_rtsym_read(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
289
+ void *buf, size_t len)
290
+{
291
+ return __nfp_rtsym_read(cpp, sym, NFP_CPP_ACTION_RW, 0, off, buf, len);
292
+}
293
+
294
+int __nfp_rtsym_readl(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
295
+ u8 action, u8 token, u64 off, u32 *value)
296
+{
297
+ u32 cpp_id;
298
+ u64 addr;
299
+ int err;
300
+
301
+ if (off + 4 > nfp_rtsym_size(sym)) {
302
+ nfp_err(cpp, "rtsym '%s': readl out of bounds: off: %lld + 4 > size: %lld\n",
303
+ sym->name, off, nfp_rtsym_size(sym));
304
+ return -ENXIO;
305
+ }
306
+
307
+ err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
308
+ if (err)
309
+ return err;
310
+
311
+ return nfp_cpp_readl(cpp, cpp_id, addr, value);
312
+}
313
+
314
+int nfp_rtsym_readl(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
315
+ u32 *value)
316
+{
317
+ return __nfp_rtsym_readl(cpp, sym, NFP_CPP_ACTION_RW, 0, off, value);
318
+}
319
+
320
+int __nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
321
+ u8 action, u8 token, u64 off, u64 *value)
322
+{
323
+ u32 cpp_id;
324
+ u64 addr;
325
+ int err;
326
+
327
+ if (off + 8 > nfp_rtsym_size(sym)) {
328
+ nfp_err(cpp, "rtsym '%s': readq out of bounds: off: %lld + 8 > size: %lld\n",
329
+ sym->name, off, nfp_rtsym_size(sym));
330
+ return -ENXIO;
331
+ }
332
+
333
+ if (sym->type == NFP_RTSYM_TYPE_ABS) {
334
+ *value = sym->addr;
335
+ return 0;
336
+ }
337
+
338
+ err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
339
+ if (err)
340
+ return err;
341
+
342
+ return nfp_cpp_readq(cpp, cpp_id, addr, value);
343
+}
344
+
345
+int nfp_rtsym_readq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
346
+ u64 *value)
347
+{
348
+ return __nfp_rtsym_readq(cpp, sym, NFP_CPP_ACTION_RW, 0, off, value);
349
+}
350
+
351
+int __nfp_rtsym_write(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
352
+ u8 action, u8 token, u64 off, void *buf, size_t len)
353
+{
354
+ u64 sym_size = nfp_rtsym_size(sym);
355
+ u32 cpp_id;
356
+ u64 addr;
357
+ int err;
358
+
359
+ if (off > sym_size) {
360
+ nfp_err(cpp, "rtsym '%s': write out of bounds: off: %lld + len: %zd > size: %lld\n",
361
+ sym->name, off, len, sym_size);
362
+ return -ENXIO;
363
+ }
364
+ len = min_t(size_t, len, sym_size - off);
365
+
366
+ err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
367
+ if (err)
368
+ return err;
369
+
370
+ return nfp_cpp_write(cpp, cpp_id, addr, buf, len);
371
+}
372
+
373
+int nfp_rtsym_write(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
374
+ void *buf, size_t len)
375
+{
376
+ return __nfp_rtsym_write(cpp, sym, NFP_CPP_ACTION_RW, 0, off, buf, len);
377
+}
378
+
379
+int __nfp_rtsym_writel(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
380
+ u8 action, u8 token, u64 off, u32 value)
381
+{
382
+ u32 cpp_id;
383
+ u64 addr;
384
+ int err;
385
+
386
+ if (off + 4 > nfp_rtsym_size(sym)) {
387
+ nfp_err(cpp, "rtsym '%s': writel out of bounds: off: %lld + 4 > size: %lld\n",
388
+ sym->name, off, nfp_rtsym_size(sym));
389
+ return -ENXIO;
390
+ }
391
+
392
+ err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
393
+ if (err)
394
+ return err;
395
+
396
+ return nfp_cpp_writel(cpp, cpp_id, addr, value);
397
+}
398
+
399
+int nfp_rtsym_writel(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
400
+ u32 value)
401
+{
402
+ return __nfp_rtsym_writel(cpp, sym, NFP_CPP_ACTION_RW, 0, off, value);
403
+}
404
+
405
+int __nfp_rtsym_writeq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym,
406
+ u8 action, u8 token, u64 off, u64 value)
407
+{
408
+ u32 cpp_id;
409
+ u64 addr;
410
+ int err;
411
+
412
+ if (off + 8 > nfp_rtsym_size(sym)) {
413
+ nfp_err(cpp, "rtsym '%s': writeq out of bounds: off: %lld + 8 > size: %lld\n",
414
+ sym->name, off, nfp_rtsym_size(sym));
415
+ return -ENXIO;
416
+ }
417
+
418
+ err = nfp_rtsym_to_dest(cpp, sym, action, token, off, &cpp_id, &addr);
419
+ if (err)
420
+ return err;
421
+
422
+ return nfp_cpp_writeq(cpp, cpp_id, addr, value);
423
+}
424
+
425
+int nfp_rtsym_writeq(struct nfp_cpp *cpp, const struct nfp_rtsym *sym, u64 off,
426
+ u64 value)
427
+{
428
+ return __nfp_rtsym_writeq(cpp, sym, NFP_CPP_ACTION_RW, 0, off, value);
429
+}
430
+
236431 /**
237432 * nfp_rtsym_read_le() - Read a simple unsigned scalar value from symbol
238433 * @rtbl: NFP RTsym table
....@@ -249,7 +444,7 @@
249444 int *error)
250445 {
251446 const struct nfp_rtsym *sym;
252
- u32 val32, id;
447
+ u32 val32;
253448 u64 val;
254449 int err;
255450
....@@ -259,20 +454,18 @@
259454 goto exit;
260455 }
261456
262
- id = NFP_CPP_ISLAND_ID(sym->target, NFP_CPP_ACTION_RW, 0, sym->domain);
263
-
264
- switch (sym->size) {
457
+ switch (nfp_rtsym_size(sym)) {
265458 case 4:
266
- err = nfp_cpp_readl(rtbl->cpp, id, sym->addr, &val32);
459
+ err = nfp_rtsym_readl(rtbl->cpp, sym, 0, &val32);
267460 val = val32;
268461 break;
269462 case 8:
270
- err = nfp_cpp_readq(rtbl->cpp, id, sym->addr, &val);
463
+ err = nfp_rtsym_readq(rtbl->cpp, sym, 0, &val);
271464 break;
272465 default:
273466 nfp_err(rtbl->cpp,
274
- "rtsym '%s' unsupported or non-scalar size: %lld\n",
275
- name, sym->size);
467
+ "rtsym '%s': unsupported or non-scalar size: %lld\n",
468
+ name, nfp_rtsym_size(sym));
276469 err = -EINVAL;
277470 break;
278471 }
....@@ -303,25 +496,22 @@
303496 {
304497 const struct nfp_rtsym *sym;
305498 int err;
306
- u32 id;
307499
308500 sym = nfp_rtsym_lookup(rtbl, name);
309501 if (!sym)
310502 return -ENOENT;
311503
312
- id = NFP_CPP_ISLAND_ID(sym->target, NFP_CPP_ACTION_RW, 0, sym->domain);
313
-
314
- switch (sym->size) {
504
+ switch (nfp_rtsym_size(sym)) {
315505 case 4:
316
- err = nfp_cpp_writel(rtbl->cpp, id, sym->addr, value);
506
+ err = nfp_rtsym_writel(rtbl->cpp, sym, 0, value);
317507 break;
318508 case 8:
319
- err = nfp_cpp_writeq(rtbl->cpp, id, sym->addr, value);
509
+ err = nfp_rtsym_writeq(rtbl->cpp, sym, 0, value);
320510 break;
321511 default:
322512 nfp_err(rtbl->cpp,
323
- "rtsym '%s' unsupported or non-scalar size: %lld\n",
324
- name, sym->size);
513
+ "rtsym '%s': unsupported or non-scalar size: %lld\n",
514
+ name, nfp_rtsym_size(sym));
325515 err = -EINVAL;
326516 break;
327517 }
....@@ -335,20 +525,29 @@
335525 {
336526 const struct nfp_rtsym *sym;
337527 u8 __iomem *mem;
528
+ u32 cpp_id;
529
+ u64 addr;
530
+ int err;
338531
339532 sym = nfp_rtsym_lookup(rtbl, name);
340533 if (!sym)
341534 return (u8 __iomem *)ERR_PTR(-ENOENT);
342535
536
+ err = nfp_rtsym_to_dest(rtbl->cpp, sym, NFP_CPP_ACTION_RW, 0, 0,
537
+ &cpp_id, &addr);
538
+ if (err) {
539
+ nfp_err(rtbl->cpp, "rtsym '%s': mapping failed\n", name);
540
+ return (u8 __iomem *)ERR_PTR(err);
541
+ }
542
+
343543 if (sym->size < min_size) {
344
- nfp_err(rtbl->cpp, "Symbol %s too small\n", name);
544
+ nfp_err(rtbl->cpp, "rtsym '%s': too small\n", name);
345545 return (u8 __iomem *)ERR_PTR(-EINVAL);
346546 }
347547
348
- mem = nfp_cpp_map_area(rtbl->cpp, id, sym->domain, sym->target,
349
- sym->addr, sym->size, area);
548
+ mem = nfp_cpp_map_area(rtbl->cpp, id, cpp_id, addr, sym->size, area);
350549 if (IS_ERR(mem)) {
351
- nfp_err(rtbl->cpp, "Failed to map symbol %s: %ld\n",
550
+ nfp_err(rtbl->cpp, "rtysm '%s': failed to map: %ld\n",
352551 name, PTR_ERR(mem));
353552 return mem;
354553 }