net/nfp: support CPP
[dpdk.git] / drivers / net / nfp / nfpcore / nfp_cppcore.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Netronome Systems, Inc.
3  * All rights reserved.
4  */
5
6 #include <assert.h>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <errno.h>
12 #include <sys/types.h>
13
14 #include <rte_byteorder.h>
15
16 #include "nfp_cpp.h"
17 #include "nfp_target.h"
18 #include "nfp6000/nfp6000.h"
19 #include "nfp6000/nfp_xpb.h"
20 #include "nfp_nffw.h"
21
22 #define NFP_PL_DEVICE_ID                        0x00000004
23 #define NFP_PL_DEVICE_ID_MASK                   0xff
24
25 #define NFP6000_ARM_GCSR_SOFTMODEL0             0x00400144
26
27 void
28 nfp_cpp_priv_set(struct nfp_cpp *cpp, void *priv)
29 {
30         cpp->priv = priv;
31 }
32
33 void *
34 nfp_cpp_priv(struct nfp_cpp *cpp)
35 {
36         return cpp->priv;
37 }
38
39 void
40 nfp_cpp_model_set(struct nfp_cpp *cpp, uint32_t model)
41 {
42         cpp->model = model;
43 }
44
45 uint32_t
46 nfp_cpp_model(struct nfp_cpp *cpp)
47 {
48         if (!cpp)
49                 return NFP_CPP_MODEL_INVALID;
50
51         if (cpp->model == 0)
52                 cpp->model = __nfp_cpp_model_autodetect(cpp);
53
54         return cpp->model;
55 }
56
57 void
58 nfp_cpp_interface_set(struct nfp_cpp *cpp, uint32_t interface)
59 {
60         cpp->interface = interface;
61 }
62
63 int
64 nfp_cpp_serial(struct nfp_cpp *cpp, const uint8_t **serial)
65 {
66         *serial = cpp->serial;
67         return cpp->serial_len;
68 }
69
70 int
71 nfp_cpp_serial_set(struct nfp_cpp *cpp, const uint8_t *serial,
72                    size_t serial_len)
73 {
74         if (cpp->serial_len)
75                 free(cpp->serial);
76
77         cpp->serial = malloc(serial_len);
78         if (!cpp->serial)
79                 return -1;
80
81         memcpy(cpp->serial, serial, serial_len);
82         cpp->serial_len = serial_len;
83
84         return 0;
85 }
86
87 uint16_t
88 nfp_cpp_interface(struct nfp_cpp *cpp)
89 {
90         if (!cpp)
91                 return NFP_CPP_INTERFACE(NFP_CPP_INTERFACE_TYPE_INVALID, 0, 0);
92
93         return cpp->interface;
94 }
95
96 void *
97 nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area)
98 {
99         return &cpp_area[1];
100 }
101
102 struct nfp_cpp *
103 nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area)
104 {
105         return cpp_area->cpp;
106 }
107
108 const char *
109 nfp_cpp_area_name(struct nfp_cpp_area *cpp_area)
110 {
111         return cpp_area->name;
112 }
113
114 /*
115  * nfp_cpp_area_alloc - allocate a new CPP area
116  * @cpp:    CPP handle
117  * @dest:   CPP id
118  * @address:    start address on CPP target
119  * @size:   size of area in bytes
120  *
121  * Allocate and initialize a CPP area structure.  The area must later
122  * be locked down with an 'acquire' before it can be safely accessed.
123  *
124  * NOTE: @address and @size must be 32-bit aligned values.
125  */
126 struct nfp_cpp_area *
127 nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, uint32_t dest,
128                               const char *name, unsigned long long address,
129                               unsigned long size)
130 {
131         struct nfp_cpp_area *area;
132         uint64_t tmp64 = (uint64_t)address;
133         int tmp, err;
134
135         if (!cpp)
136                 return NULL;
137
138         /* CPP bus uses only a 40-bit address */
139         if ((address + size) > (1ULL << 40))
140                 return NFP_ERRPTR(EFAULT);
141
142         /* Remap from cpp_island to cpp_target */
143         err = nfp_target_cpp(dest, tmp64, &dest, &tmp64, cpp->imb_cat_table);
144         if (err < 0)
145                 return NULL;
146
147         address = (unsigned long long)tmp64;
148
149         if (!name)
150                 name = "";
151
152         area = calloc(1, sizeof(*area) + cpp->op->area_priv_size +
153                       strlen(name) + 1);
154         if (!area)
155                 return NULL;
156
157         area->cpp = cpp;
158         area->name = ((char *)area) + sizeof(*area) + cpp->op->area_priv_size;
159         memcpy(area->name, name, strlen(name) + 1);
160
161         /*
162          * Preserve errno around the call to area_init, since most
163          * implementations will blindly call nfp_target_action_width()for both
164          * read or write modes, and that will set errno to EINVAL.
165          */
166         tmp = errno;
167
168         err = cpp->op->area_init(area, dest, address, size);
169         if (err < 0) {
170                 free(area);
171                 return NULL;
172         }
173
174         /* Restore errno */
175         errno = tmp;
176
177         area->offset = address;
178         area->size = size;
179
180         return area;
181 }
182
183 struct nfp_cpp_area *
184 nfp_cpp_area_alloc(struct nfp_cpp *cpp, uint32_t dest,
185                     unsigned long long address, unsigned long size)
186 {
187         return nfp_cpp_area_alloc_with_name(cpp, dest, NULL, address, size);
188 }
189
190 /*
191  * nfp_cpp_area_alloc_acquire - allocate a new CPP area and lock it down
192  *
193  * @cpp:    CPP handle
194  * @dest:   CPP id
195  * @address:    start address on CPP target
196  * @size:   size of area
197  *
198  * Allocate and initilizae a CPP area structure, and lock it down so
199  * that it can be accessed directly.
200  *
201  * NOTE: @address and @size must be 32-bit aligned values.
202  *
203  * NOTE: The area must also be 'released' when the structure is freed.
204  */
205 struct nfp_cpp_area *
206 nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, uint32_t destination,
207                             unsigned long long address, unsigned long size)
208 {
209         struct nfp_cpp_area *area;
210
211         area = nfp_cpp_area_alloc(cpp, destination, address, size);
212         if (!area)
213                 return NULL;
214
215         if (nfp_cpp_area_acquire(area)) {
216                 nfp_cpp_area_free(area);
217                 return NULL;
218         }
219
220         return area;
221 }
222
223 /*
224  * nfp_cpp_area_free - free up the CPP area
225  * area:    CPP area handle
226  *
227  * Frees up memory resources held by the CPP area.
228  */
229 void
230 nfp_cpp_area_free(struct nfp_cpp_area *area)
231 {
232         if (area->cpp->op->area_cleanup)
233                 area->cpp->op->area_cleanup(area);
234         free(area);
235 }
236
237 /*
238  * nfp_cpp_area_release_free - release CPP area and free it
239  * area:    CPP area handle
240  *
241  * Releases CPP area and frees up memory resources held by the it.
242  */
243 void
244 nfp_cpp_area_release_free(struct nfp_cpp_area *area)
245 {
246         nfp_cpp_area_release(area);
247         nfp_cpp_area_free(area);
248 }
249
250 /*
251  * nfp_cpp_area_acquire - lock down a CPP area for access
252  * @area:   CPP area handle
253  *
254  * Locks down the CPP area for a potential long term activity.  Area
255  * must always be locked down before being accessed.
256  */
257 int
258 nfp_cpp_area_acquire(struct nfp_cpp_area *area)
259 {
260         if (area->cpp->op->area_acquire) {
261                 int err = area->cpp->op->area_acquire(area);
262
263                 if (err < 0)
264                         return -1;
265         }
266
267         return 0;
268 }
269
270 /*
271  * nfp_cpp_area_release - release a locked down CPP area
272  * @area:   CPP area handle
273  *
274  * Releases a previously locked down CPP area.
275  */
276 void
277 nfp_cpp_area_release(struct nfp_cpp_area *area)
278 {
279         if (area->cpp->op->area_release)
280                 area->cpp->op->area_release(area);
281 }
282
283 /*
284  * nfp_cpp_area_iomem() - get IOMEM region for CPP area
285  *
286  * @area:       CPP area handle
287  *
288  * Returns an iomem pointer for use with readl()/writel() style operations.
289  *
290  * NOTE: Area must have been locked down with an 'acquire'.
291  *
292  * Return: pointer to the area, or NULL
293  */
294 void *
295 nfp_cpp_area_iomem(struct nfp_cpp_area *area)
296 {
297         void *iomem = NULL;
298
299         if (area->cpp->op->area_iomem)
300                 iomem = area->cpp->op->area_iomem(area);
301
302         return iomem;
303 }
304
305 /*
306  * nfp_cpp_area_read - read data from CPP area
307  *
308  * @area:       CPP area handle
309  * @offset:     offset into CPP area
310  * @kernel_vaddr:   kernel address to put data into
311  * @length:     number of bytes to read
312  *
313  * Read data from indicated CPP region.
314  *
315  * NOTE: @offset and @length must be 32-bit aligned values.
316  *
317  * NOTE: Area must have been locked down with an 'acquire'.
318  */
319 int
320 nfp_cpp_area_read(struct nfp_cpp_area *area, unsigned long offset,
321                   void *kernel_vaddr, size_t length)
322 {
323         if ((offset + length) > area->size)
324                 return NFP_ERRNO(EFAULT);
325
326         return area->cpp->op->area_read(area, kernel_vaddr, offset, length);
327 }
328
329 /*
330  * nfp_cpp_area_write - write data to CPP area
331  *
332  * @area:       CPP area handle
333  * @offset:     offset into CPP area
334  * @kernel_vaddr:   kernel address to read data from
335  * @length:     number of bytes to write
336  *
337  * Write data to indicated CPP region.
338  *
339  * NOTE: @offset and @length must be 32-bit aligned values.
340  *
341  * NOTE: Area must have been locked down with an 'acquire'.
342  */
343 int
344 nfp_cpp_area_write(struct nfp_cpp_area *area, unsigned long offset,
345                    const void *kernel_vaddr, size_t length)
346 {
347         if ((offset + length) > area->size)
348                 return NFP_ERRNO(EFAULT);
349
350         return area->cpp->op->area_write(area, kernel_vaddr, offset, length);
351 }
352
353 void *
354 nfp_cpp_area_mapped(struct nfp_cpp_area *area)
355 {
356         if (area->cpp->op->area_mapped)
357                 return area->cpp->op->area_mapped(area);
358         return NULL;
359 }
360
361 /*
362  * nfp_cpp_area_check_range - check if address range fits in CPP area
363  *
364  * @area:   CPP area handle
365  * @offset: offset into CPP area
366  * @length: size of address range in bytes
367  *
368  * Check if address range fits within CPP area.  Return 0 if area fits
369  * or -1 on error.
370  */
371 int
372 nfp_cpp_area_check_range(struct nfp_cpp_area *area, unsigned long long offset,
373                          unsigned long length)
374 {
375         if (((offset + length) > area->size))
376                 return NFP_ERRNO(EFAULT);
377
378         return 0;
379 }
380
381 /*
382  * Return the correct CPP address, and fixup xpb_addr as needed,
383  * based upon NFP model.
384  */
385 static uint32_t
386 nfp_xpb_to_cpp(struct nfp_cpp *cpp, uint32_t *xpb_addr)
387 {
388         uint32_t xpb;
389         int island;
390
391         if (!NFP_CPP_MODEL_IS_6000(cpp->model))
392                 return 0;
393
394         xpb = NFP_CPP_ID(14, NFP_CPP_ACTION_RW, 0);
395
396         /*
397          * Ensure that non-local XPB accesses go out through the
398          * global XPBM bus.
399          */
400         island = ((*xpb_addr) >> 24) & 0x3f;
401
402         if (!island)
403                 return xpb;
404
405         if (island == 1) {
406                 /*
407                  * Accesses to the ARM Island overlay uses Island 0
408                  * Global Bit
409                  */
410                 (*xpb_addr) &= ~0x7f000000;
411                 if (*xpb_addr < 0x60000)
412                         *xpb_addr |= (1 << 30);
413                 else
414                         /* And only non-ARM interfaces use island id = 1 */
415                         if (NFP_CPP_INTERFACE_TYPE_of(nfp_cpp_interface(cpp)) !=
416                             NFP_CPP_INTERFACE_TYPE_ARM)
417                                 *xpb_addr |= (1 << 24);
418         } else {
419                 (*xpb_addr) |= (1 << 30);
420         }
421
422         return xpb;
423 }
424
425 int
426 nfp_cpp_area_readl(struct nfp_cpp_area *area, unsigned long offset,
427                    uint32_t *value)
428 {
429         int sz;
430         uint32_t tmp = 0;
431
432         sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp));
433         *value = rte_le_to_cpu_32(tmp);
434
435         return (sz == sizeof(*value)) ? 0 : -1;
436 }
437
438 int
439 nfp_cpp_area_writel(struct nfp_cpp_area *area, unsigned long offset,
440                     uint32_t value)
441 {
442         int sz;
443
444         value = rte_cpu_to_le_32(value);
445         sz = nfp_cpp_area_write(area, offset, &value, sizeof(value));
446         return (sz == sizeof(value)) ? 0 : -1;
447 }
448
449 int
450 nfp_cpp_area_readq(struct nfp_cpp_area *area, unsigned long offset,
451                    uint64_t *value)
452 {
453         int sz;
454         uint64_t tmp = 0;
455
456         sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp));
457         *value = rte_le_to_cpu_64(tmp);
458
459         return (sz == sizeof(*value)) ? 0 : -1;
460 }
461
462 int
463 nfp_cpp_area_writeq(struct nfp_cpp_area *area, unsigned long offset,
464                     uint64_t value)
465 {
466         int sz;
467
468         value = rte_cpu_to_le_64(value);
469         sz = nfp_cpp_area_write(area, offset, &value, sizeof(value));
470
471         return (sz == sizeof(value)) ? 0 : -1;
472 }
473
474 int
475 nfp_cpp_readl(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
476               uint32_t *value)
477 {
478         int sz;
479         uint32_t tmp;
480
481         sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp));
482         *value = rte_le_to_cpu_32(tmp);
483
484         return (sz == sizeof(*value)) ? 0 : -1;
485 }
486
487 int
488 nfp_cpp_writel(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
489                uint32_t value)
490 {
491         int sz;
492
493         value = rte_cpu_to_le_32(value);
494         sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value));
495
496         return (sz == sizeof(value)) ? 0 : -1;
497 }
498
499 int
500 nfp_cpp_readq(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
501               uint64_t *value)
502 {
503         int sz;
504         uint64_t tmp;
505
506         sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp));
507         *value = rte_le_to_cpu_64(tmp);
508
509         return (sz == sizeof(*value)) ? 0 : -1;
510 }
511
512 int
513 nfp_cpp_writeq(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address,
514                uint64_t value)
515 {
516         int sz;
517
518         value = rte_cpu_to_le_64(value);
519         sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value));
520
521         return (sz == sizeof(value)) ? 0 : -1;
522 }
523
524 int
525 nfp_xpb_writel(struct nfp_cpp *cpp, uint32_t xpb_addr, uint32_t value)
526 {
527         uint32_t cpp_dest;
528
529         cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr);
530
531         return nfp_cpp_writel(cpp, cpp_dest, xpb_addr, value);
532 }
533
534 int
535 nfp_xpb_readl(struct nfp_cpp *cpp, uint32_t xpb_addr, uint32_t *value)
536 {
537         uint32_t cpp_dest;
538
539         cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr);
540
541         return nfp_cpp_readl(cpp, cpp_dest, xpb_addr, value);
542 }
543
544 static struct nfp_cpp *
545 nfp_cpp_alloc(const char *devname)
546 {
547         const struct nfp_cpp_operations *ops;
548         struct nfp_cpp *cpp;
549         int err;
550
551         ops = nfp_cpp_transport_operations();
552
553         if (!ops || !ops->init)
554                 return NFP_ERRPTR(EINVAL);
555
556         cpp = calloc(1, sizeof(*cpp));
557         if (!cpp)
558                 return NULL;
559
560         cpp->op = ops;
561
562         if (cpp->op->init) {
563                 err = cpp->op->init(cpp, devname);
564                 if (err < 0) {
565                         free(cpp);
566                         return NULL;
567                 }
568         }
569
570         if (NFP_CPP_MODEL_IS_6000(nfp_cpp_model(cpp))) {
571                 uint32_t xpbaddr;
572                 size_t tgt;
573
574                 for (tgt = 0; tgt < ARRAY_SIZE(cpp->imb_cat_table); tgt++) {
575                         /* Hardcoded XPB IMB Base, island 0 */
576                         xpbaddr = 0x000a0000 + (tgt * 4);
577                         err = nfp_xpb_readl(cpp, xpbaddr,
578                                 (uint32_t *)&cpp->imb_cat_table[tgt]);
579                         if (err < 0) {
580                                 free(cpp);
581                                 return NULL;
582                         }
583                 }
584         }
585
586         return cpp;
587 }
588
589 /*
590  * nfp_cpp_free - free the CPP handle
591  * @cpp:    CPP handle
592  */
593 void
594 nfp_cpp_free(struct nfp_cpp *cpp)
595 {
596         if (cpp->op && cpp->op->free)
597                 cpp->op->free(cpp);
598
599         if (cpp->serial_len)
600                 free(cpp->serial);
601
602         free(cpp);
603 }
604
605 struct nfp_cpp *
606 nfp_cpp_from_device_name(const char *devname)
607 {
608         return nfp_cpp_alloc(devname);
609 }
610
611 /*
612  * Modify bits of a 32-bit value from the XPB bus
613  *
614  * @param cpp           NFP CPP device handle
615  * @param xpb_tgt       XPB target and address
616  * @param mask          mask of bits to alter
617  * @param value         value to modify
618  *
619  * @return 0 on success, or -1 on failure (and set errno accordingly).
620  */
621 int
622 nfp_xpb_writelm(struct nfp_cpp *cpp, uint32_t xpb_tgt, uint32_t mask,
623                 uint32_t value)
624 {
625         int err;
626         uint32_t tmp;
627
628         err = nfp_xpb_readl(cpp, xpb_tgt, &tmp);
629         if (err < 0)
630                 return err;
631
632         tmp &= ~mask;
633         tmp |= (mask & value);
634         return nfp_xpb_writel(cpp, xpb_tgt, tmp);
635 }
636
637 /*
638  * Modify bits of a 32-bit value from the XPB bus
639  *
640  * @param cpp           NFP CPP device handle
641  * @param xpb_tgt       XPB target and address
642  * @param mask          mask of bits to alter
643  * @param value         value to monitor for
644  * @param timeout_us    maximum number of us to wait (-1 for forever)
645  *
646  * @return >= 0 on success, or -1 on failure (and set errno accordingly).
647  */
648 int
649 nfp_xpb_waitlm(struct nfp_cpp *cpp, uint32_t xpb_tgt, uint32_t mask,
650                uint32_t value, int timeout_us)
651 {
652         uint32_t tmp;
653         int err;
654
655         do {
656                 err = nfp_xpb_readl(cpp, xpb_tgt, &tmp);
657                 if (err < 0)
658                         goto exit;
659
660                 if ((tmp & mask) == (value & mask)) {
661                         if (timeout_us < 0)
662                                 timeout_us = 0;
663                         break;
664                 }
665
666                 if (timeout_us < 0)
667                         continue;
668
669                 timeout_us -= 100;
670                 usleep(100);
671         } while (timeout_us >= 0);
672
673         if (timeout_us < 0)
674                 err = NFP_ERRNO(ETIMEDOUT);
675         else
676                 err = timeout_us;
677
678 exit:
679         return err;
680 }
681
682 /*
683  * nfp_cpp_read - read from CPP target
684  * @cpp:        CPP handle
685  * @destination:    CPP id
686  * @address:        offset into CPP target
687  * @kernel_vaddr:   kernel buffer for result
688  * @length:     number of bytes to read
689  */
690 int
691 nfp_cpp_read(struct nfp_cpp *cpp, uint32_t destination,
692              unsigned long long address, void *kernel_vaddr, size_t length)
693 {
694         struct nfp_cpp_area *area;
695         int err;
696
697         area = nfp_cpp_area_alloc_acquire(cpp, destination, address, length);
698         if (!area) {
699                 printf("Area allocation/acquire failed\n");
700                 return -1;
701         }
702
703         err = nfp_cpp_area_read(area, 0, kernel_vaddr, length);
704
705         nfp_cpp_area_release_free(area);
706         return err;
707 }
708
709 /*
710  * nfp_cpp_write - write to CPP target
711  * @cpp:        CPP handle
712  * @destination:    CPP id
713  * @address:        offset into CPP target
714  * @kernel_vaddr:   kernel buffer to read from
715  * @length:     number of bytes to write
716  */
717 int
718 nfp_cpp_write(struct nfp_cpp *cpp, uint32_t destination,
719               unsigned long long address, const void *kernel_vaddr,
720               size_t length)
721 {
722         struct nfp_cpp_area *area;
723         int err;
724
725         area = nfp_cpp_area_alloc_acquire(cpp, destination, address, length);
726         if (!area)
727                 return -1;
728
729         err = nfp_cpp_area_write(area, 0, kernel_vaddr, length);
730
731         nfp_cpp_area_release_free(area);
732         return err;
733 }
734
735 /*
736  * nfp_cpp_area_fill - fill a CPP area with a value
737  * @area:       CPP area
738  * @offset:     offset into CPP area
739  * @value:      value to fill with
740  * @length:     length of area to fill
741  */
742 int
743 nfp_cpp_area_fill(struct nfp_cpp_area *area, unsigned long offset,
744                   uint32_t value, size_t length)
745 {
746         int err;
747         size_t i;
748         uint64_t value64;
749
750         value = rte_cpu_to_le_32(value);
751         value64 = ((uint64_t)value << 32) | value;
752
753         if ((offset + length) > area->size)
754                 return NFP_ERRNO(EINVAL);
755
756         if ((area->offset + offset) & 3)
757                 return NFP_ERRNO(EINVAL);
758
759         if (((area->offset + offset) & 7) == 4 && length >= 4) {
760                 err = nfp_cpp_area_write(area, offset, &value, sizeof(value));
761                 if (err < 0)
762                         return err;
763                 if (err != sizeof(value))
764                         return NFP_ERRNO(ENOSPC);
765                 offset += sizeof(value);
766                 length -= sizeof(value);
767         }
768
769         for (i = 0; (i + sizeof(value)) < length; i += sizeof(value64)) {
770                 err =
771                     nfp_cpp_area_write(area, offset + i, &value64,
772                                        sizeof(value64));
773                 if (err < 0)
774                         return err;
775                 if (err != sizeof(value64))
776                         return NFP_ERRNO(ENOSPC);
777         }
778
779         if ((i + sizeof(value)) <= length) {
780                 err =
781                     nfp_cpp_area_write(area, offset + i, &value, sizeof(value));
782                 if (err < 0)
783                         return err;
784                 if (err != sizeof(value))
785                         return NFP_ERRNO(ENOSPC);
786                 i += sizeof(value);
787         }
788
789         return (int)i;
790 }
791
792 /*
793  * NOTE: This code should not use nfp_xpb_* functions,
794  * as those are model-specific
795  */
796 uint32_t
797 __nfp_cpp_model_autodetect(struct nfp_cpp *cpp)
798 {
799         uint32_t arm_id = NFP_CPP_ID(NFP_CPP_TARGET_ARM, 0, 0);
800         uint32_t model = 0;
801
802         nfp_cpp_readl(cpp, arm_id, NFP6000_ARM_GCSR_SOFTMODEL0, &model);
803
804         if (NFP_CPP_MODEL_IS_6000(model)) {
805                 uint32_t tmp;
806
807                 nfp_cpp_model_set(cpp, model);
808
809                 /* The PL's PluDeviceID revision code is authoratative */
810                 model &= ~0xff;
811                 nfp_xpb_readl(cpp, NFP_XPB_DEVICE(1, 1, 16) +
812                                    NFP_PL_DEVICE_ID, &tmp);
813                 model |= (NFP_PL_DEVICE_ID_MASK & tmp) - 0x10;
814         }
815
816         return model;
817 }
818
819 /*
820  * nfp_cpp_map_area() - Helper function to map an area
821  * @cpp:    NFP CPP handler
822  * @domain: CPP domain
823  * @target: CPP target
824  * @addr:   CPP address
825  * @size:   Size of the area
826  * @area:   Area handle (output)
827  *
828  * Map an area of IOMEM access.  To undo the effect of this function call
829  * @nfp_cpp_area_release_free(*area).
830  *
831  * Return: Pointer to memory mapped area or ERR_PTR
832  */
833 uint8_t *
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)
836 {
837         uint8_t *res;
838         uint32_t dest;
839
840         dest = NFP_CPP_ISLAND_ID(target, NFP_CPP_ACTION_RW, 0, domain);
841
842         *area = nfp_cpp_area_alloc_acquire(cpp, dest, addr, size);
843         if (!*area)
844                 goto err_eio;
845
846         res = nfp_cpp_area_iomem(*area);
847         if (!res)
848                 goto err_release_free;
849
850         return res;
851
852 err_release_free:
853         nfp_cpp_area_release_free(*area);
854 err_eio:
855         return NULL;
856 }