xref: /dpdk/drivers/net/nfp/nfpcore/nfp_cppcore.c (revision b6de43530dfa30cbf6b70857e3835099701063d4)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Netronome Systems, Inc.
3  * All rights reserved.
4  */
5 
6 #include "nfp_cpp.h"
7 
8 #include <nfp_platform.h>
9 
10 #include "nfp_logs.h"
11 #include "nfp_target.h"
12 #include "nfp6000/nfp6000.h"
13 #include "nfp6000/nfp_xpb.h"
14 #include "nfp6000_pcie.h"
15 
16 #define NFP_PL_DEVICE_PART_NFP6000              0x6200
17 #define NFP_PL_DEVICE_ID                        0x00000004
18 #define NFP_PL_DEVICE_ID_MASK                   0xff
19 #define NFP_PL_DEVICE_PART_MASK                 0xffff0000
20 #define NFP_PL_DEVICE_MODEL_MASK               (NFP_PL_DEVICE_PART_MASK | \
21 						NFP_PL_DEVICE_ID_MASK)
22 
23 /* NFP CPP handle */
24 struct nfp_cpp {
25 	void *priv;  /**< Private data of the low-level implementation */
26 
27 	uint32_t model;  /**< Chip model */
28 	uint16_t interface;  /**< Chip interface id */
29 	uint8_t serial[NFP_SERIAL_LEN];  /**< Chip serial number */
30 
31 	/** Low-level implementation ops */
32 	const struct nfp_cpp_operations *op;
33 
34 	/*
35 	 * NFP-6xxx originating island IMB CPP Address Translation. CPP Target
36 	 * ID is index into array. Values are obtained at runtime from local
37 	 * island XPB CSRs.
38 	 */
39 	uint32_t imb_cat_table[16];
40 
41 	/**< MU access type bit offset */
42 	uint32_t mu_locality_lsb;
43 
44 	bool driver_lock_needed;
45 };
46 
47 /* NFP CPP device area handle */
48 struct nfp_cpp_area {
49 	struct nfp_cpp *cpp;
50 	char *name;
51 	uint64_t offset;
52 	uint32_t size;
53 	/* Here follows the 'priv' part of nfp_cpp_area. */
54 	/* Here follows the ASCII name, pointed by @name */
55 };
56 
57 /**
58  * Set the private data of the nfp_cpp instance
59  *
60  * @param cpp
61  *   NFP CPP operations structure
62  *
63  * @return
64  *   Opaque device pointer
65  */
66 void
67 nfp_cpp_priv_set(struct nfp_cpp *cpp,
68 		void *priv)
69 {
70 	cpp->priv = priv;
71 }
72 
73 /**
74  * Return the private data of the nfp_cpp instance
75  *
76  * @param cpp
77  *   NFP CPP operations structure
78  *
79  * @return
80  *   Opaque device pointer
81  */
82 void *
83 nfp_cpp_priv(struct nfp_cpp *cpp)
84 {
85 	return cpp->priv;
86 }
87 
88 /**
89  * Set the model id
90  *
91  * @param cpp
92  *   NFP CPP operations structure
93  * @param model
94  *   Model ID
95  */
96 void
97 nfp_cpp_model_set(struct nfp_cpp *cpp,
98 		uint32_t model)
99 {
100 	cpp->model = model;
101 }
102 
103 /**
104  * Retrieve the Model ID of the NFP
105  *
106  * @param cpp
107  *   NFP CPP handle
108  *
109  * @return
110  *   NFP CPP Model ID
111  */
112 uint32_t
113 nfp_cpp_model(struct nfp_cpp *cpp)
114 {
115 	int err;
116 	uint32_t model;
117 
118 	if (cpp == NULL)
119 		return NFP_CPP_MODEL_INVALID;
120 
121 	err = nfp_cpp_model_autodetect(cpp, &model);
122 
123 	if (err < 0)
124 		return err;
125 
126 	return model;
127 }
128 
129 /**
130  * Set the private instance owned data of a nfp_cpp struct
131  *
132  * @param cpp
133  *   NFP CPP operations structure
134  * @param interface
135  *   Interface ID
136  */
137 void
138 nfp_cpp_interface_set(struct nfp_cpp *cpp,
139 		uint32_t interface)
140 {
141 	cpp->interface = interface;
142 }
143 
144 /**
145  * Retrieve the Serial ID of the NFP
146  *
147  * @param cpp
148  *   NFP CPP handle
149  * @param serial
150  *   Pointer to NFP serial number
151  *
152  * @return
153  *   Length of NFP serial number
154  */
155 uint32_t
156 nfp_cpp_serial(struct nfp_cpp *cpp,
157 		const uint8_t **serial)
158 {
159 	*serial = &cpp->serial[0];
160 
161 	return sizeof(cpp->serial);
162 }
163 
164 /**
165  * Set the private instance owned data of a nfp_cpp struct
166  *
167  * @param cpp
168  *   NFP CPP operations structure
169  * @param serial
170  *   NFP serial byte array
171  * @param serial_len
172  *   Length of the serial byte array
173  */
174 void
175 nfp_cpp_serial_set(struct nfp_cpp *cpp,
176 		const uint8_t *serial,
177 		size_t serial_len)
178 {
179 	memcpy(cpp->serial, serial, serial_len);
180 }
181 
182 /**
183  * Retrieve the Interface ID of the NFP
184  *
185  * @param cpp
186  *   NFP CPP handle
187  *
188  * @return
189  *   NFP CPP Interface ID
190  */
191 uint16_t
192 nfp_cpp_interface(struct nfp_cpp *cpp)
193 {
194 	if (cpp == NULL)
195 		return NFP_CPP_INTERFACE(NFP_CPP_INTERFACE_TYPE_INVALID, 0, 0);
196 
197 	return cpp->interface;
198 }
199 
200 /**
201  * Retrieve the driver need lock flag
202  *
203  * @param cpp
204  *   NFP CPP handle
205  *
206  * @return
207  *   The driver need lock flag
208  */
209 bool
210 nfp_cpp_driver_need_lock(const struct nfp_cpp *cpp)
211 {
212 	return cpp->driver_lock_needed;
213 }
214 
215 /**
216  * Get the privately allocated portion of a NFP CPP area handle
217  *
218  * @param cpp_area
219  *   NFP CPP area handle
220  *
221  * @return
222  *   Pointer to the private area, or NULL on failure
223  */
224 void *
225 nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area)
226 {
227 	return &cpp_area[1];
228 }
229 
230 /**
231  * Get the NFP CPP handle that is the pci_dev of a NFP CPP area handle
232  *
233  * @param cpp_area
234  *   NFP CPP area handle
235  *
236  * @return
237  *   NFP CPP handle
238  */
239 struct nfp_cpp *
240 nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area)
241 {
242 	return cpp_area->cpp;
243 }
244 
245 /**
246  * Get the name passed during allocation of the NFP CPP area handle
247  *
248  * @param cpp_area
249  *   NFP CPP area handle
250  *
251  * @return
252  *   Pointer to the area's name
253  */
254 const char *
255 nfp_cpp_area_name(struct nfp_cpp_area *cpp_area)
256 {
257 	return cpp_area->name;
258 }
259 
260 #define NFP_IMB_TGTADDRESSMODECFG_MODE_of(_x)       (((_x) >> 13) & 0x7)
261 #define NFP_IMB_TGTADDRESSMODECFG_ADDRMODE          RTE_BIT32(12)
262 
263 static int
264 nfp_cpp_set_mu_locality_lsb(struct nfp_cpp *cpp)
265 {
266 	int ret;
267 	int mode;
268 	int addr40;
269 	uint32_t imbcppat;
270 
271 	imbcppat = cpp->imb_cat_table[NFP_CPP_TARGET_MU];
272 	mode = NFP_IMB_TGTADDRESSMODECFG_MODE_of(imbcppat);
273 	addr40 = imbcppat & NFP_IMB_TGTADDRESSMODECFG_ADDRMODE;
274 
275 	ret = nfp_cppat_mu_locality_lsb(mode, addr40);
276 	if (ret < 0)
277 		return ret;
278 
279 	cpp->mu_locality_lsb = ret;
280 
281 	return 0;
282 }
283 
284 uint32_t
285 nfp_cpp_mu_locality_lsb(struct nfp_cpp *cpp)
286 {
287 	return cpp->mu_locality_lsb;
288 }
289 
290 /**
291  * Allocate and initialize a CPP area structure.
292  * The area must later be locked down with an 'acquire' before
293  * it can be safely accessed.
294  *
295  * @param cpp
296  *   CPP device handle
297  * @param dest
298  *   CPP id
299  * @param name
300  *   Name of region
301  * @param address
302  *   Address of region
303  * @param size
304  *   Size of region
305  *
306  * @return
307  *   NFP CPP area handle, or NULL
308  *
309  * NOTE: @address and @size must be 32-bit aligned values.
310  */
311 struct nfp_cpp_area *
312 nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp,
313 		uint32_t dest,
314 		const char *name,
315 		uint64_t address,
316 		uint32_t size)
317 {
318 	int err;
319 	size_t name_len;
320 	uint32_t target_id;
321 	uint64_t target_addr;
322 	struct nfp_cpp_area *area;
323 
324 	if (cpp == NULL)
325 		return NULL;
326 
327 	/* Remap from cpp_island to cpp_target */
328 	err = nfp_target_cpp(dest, address, &target_id, &target_addr,
329 			cpp->imb_cat_table);
330 	if (err < 0)
331 		return NULL;
332 
333 	if (name == NULL)
334 		name = "(reserved)";
335 
336 	name_len = strlen(name) + 1;
337 	area = calloc(1, sizeof(*area) + cpp->op->area_priv_size + name_len);
338 	if (area == NULL)
339 		return NULL;
340 
341 	area->cpp = cpp;
342 	area->name = ((char *)area) + sizeof(*area) + cpp->op->area_priv_size;
343 	memcpy(area->name, name, name_len);
344 
345 	err = cpp->op->area_init(area, target_id, target_addr, size);
346 	if (err < 0) {
347 		PMD_DRV_LOG(ERR, "Area init op failed.");
348 		free(area);
349 		return NULL;
350 	}
351 
352 	area->offset = target_addr;
353 	area->size = size;
354 
355 	return area;
356 }
357 
358 /**
359  * Allocate and initialize a CPP area structure.
360  * The area must later be locked down with an 'acquire' before
361  * it can be safely accessed.
362  *
363  * @param cpp
364  *   CPP device handle
365  * @param dest
366  *   CPP id
367  * @param address
368  *   Address of region
369  * @param size
370  *   Size of region
371  *
372  * @return
373  *   NFP CPP area handle, or NULL
374  *
375  * NOTE: @address and @size must be 32-bit aligned values.
376  */
377 struct nfp_cpp_area *
378 nfp_cpp_area_alloc(struct nfp_cpp *cpp,
379 		uint32_t dest,
380 		uint64_t address,
381 		size_t size)
382 {
383 	return nfp_cpp_area_alloc_with_name(cpp, dest, NULL, address, size);
384 }
385 
386 /**
387  * Allocate and initialize a CPP area structure, and lock it down so
388  * that it can be accessed directly.
389  *
390  * @param cpp
391  *   CPP device handle
392  * @param destination
393  *   CPP id
394  * @param address
395  *   Address of region
396  * @param size
397  *   Size of region
398  *
399  * @return
400  *   NFP CPP area handle, or NULL
401  *
402  * NOTE: @address and @size must be 32-bit aligned values.
403  *
404  * NOTE: The area must also be 'released' when the structure is freed.
405  */
406 struct nfp_cpp_area *
407 nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp,
408 		uint32_t destination,
409 		uint64_t address,
410 		size_t size)
411 {
412 	struct nfp_cpp_area *area;
413 
414 	area = nfp_cpp_area_alloc(cpp, destination, address, size);
415 	if (area == NULL) {
416 		PMD_DRV_LOG(ERR, "Failed to allocate CPP area.");
417 		return NULL;
418 	}
419 
420 	if (nfp_cpp_area_acquire(area) != 0) {
421 		PMD_DRV_LOG(ERR, "Failed to acquire CPP area.");
422 		nfp_cpp_area_free(area);
423 		return NULL;
424 	}
425 
426 	return area;
427 }
428 
429 /**
430  * Frees up memory resources held by the CPP area.
431  *
432  * @param area
433  *   CPP area handle
434  */
435 void
436 nfp_cpp_area_free(struct nfp_cpp_area *area)
437 {
438 	if (area->cpp->op->area_cleanup != NULL)
439 		area->cpp->op->area_cleanup(area);
440 	free(area);
441 }
442 
443 /**
444  * Releases CPP area and frees up memory resources held by it.
445  *
446  * @param area
447  *   CPP area handle
448  */
449 void
450 nfp_cpp_area_release_free(struct nfp_cpp_area *area)
451 {
452 	nfp_cpp_area_release(area);
453 	nfp_cpp_area_free(area);
454 }
455 
456 /**
457  * Locks down the CPP area for a potential long term activity.
458  * Area must always be locked down before being accessed.
459  *
460  * @param area
461  *   CPP area handle
462  *
463  * @return
464  *   0 on success, -1 on failure.
465  */
466 int
467 nfp_cpp_area_acquire(struct nfp_cpp_area *area)
468 {
469 	if (area->cpp->op->area_acquire != NULL) {
470 		int err = area->cpp->op->area_acquire(area);
471 		if (err < 0) {
472 			PMD_DRV_LOG(ERR, "Area acquire op failed.");
473 			return -1;
474 		}
475 	}
476 
477 	return 0;
478 }
479 
480 /**
481  * Releases a previously locked down CPP area.
482  *
483  * @param area
484  *   CPP area handle
485  */
486 void
487 nfp_cpp_area_release(struct nfp_cpp_area *area)
488 {
489 	if (area->cpp->op->area_release != NULL)
490 		area->cpp->op->area_release(area);
491 }
492 
493 /**
494  * Returns an iomem pointer for use with readl()/writel() style operations.
495  *
496  * @param area
497  *   CPP area handle
498  *
499  * @return
500  *   Pointer to the area, or NULL
501  *
502  * NOTE: Area must have been locked down with an 'acquire'.
503  */
504 void *
505 nfp_cpp_area_iomem(struct nfp_cpp_area *area)
506 {
507 	void *iomem = NULL;
508 
509 	if (area->cpp->op->area_iomem != NULL)
510 		iomem = area->cpp->op->area_iomem(area);
511 
512 	return iomem;
513 }
514 
515 /**
516  * Read data from indicated CPP region.
517  *
518  * @param area
519  *   CPP area handle
520  * @param offset
521  *   Offset into CPP area
522  * @param address
523  *   Address to put data into
524  * @param length
525  *   Number of bytes to read
526  *
527  * @return
528  *   Length of io, or -ERRNO
529  *
530  * NOTE: @offset and @length must be 32-bit aligned values.
531  * NOTE: Area must have been locked down with an 'acquire'.
532  */
533 int
534 nfp_cpp_area_read(struct nfp_cpp_area *area,
535 		uint32_t offset,
536 		void *address,
537 		size_t length)
538 {
539 	if ((offset + length) > area->size)
540 		return -EFAULT;
541 
542 	return area->cpp->op->area_read(area, address, offset, length);
543 }
544 
545 /**
546  * Write data to indicated CPP region.
547  *
548  * @param area
549  *   CPP area handle
550  * @param offset
551  *   Offset into CPP area
552  * @param address
553  *   Address to put data into
554  * @param length
555  *   Number of bytes to read
556  *
557  * @return
558  *   Length of io, or -ERRNO
559  *
560  * NOTE: @offset and @length must be 32-bit aligned values.
561  * NOTE: Area must have been locked down with an 'acquire'.
562  */
563 int
564 nfp_cpp_area_write(struct nfp_cpp_area *area,
565 		uint32_t offset,
566 		const void *address,
567 		size_t length)
568 {
569 	if ((offset + length) > area->size)
570 		return -EFAULT;
571 
572 	return area->cpp->op->area_write(area, address, offset, length);
573 }
574 
575 /*
576  * Return the correct CPP address, and fixup xpb_addr as needed,
577  * based upon NFP model.
578  */
579 static uint32_t
580 nfp_xpb_to_cpp(struct nfp_cpp *cpp,
581 		uint32_t *xpb_addr)
582 {
583 	int island;
584 	uint32_t xpb;
585 
586 	xpb = NFP_CPP_ID(14, NFP_CPP_ACTION_RW, 0);
587 
588 	/*
589 	 * Ensure that non-local XPB accesses go out through the
590 	 * global XPBM bus.
591 	 */
592 	island = (*xpb_addr >> 24) & 0x3f;
593 
594 	if (island == 0)
595 		return xpb;
596 
597 	if (island != 1) {
598 		*xpb_addr |= (1 << 30);
599 		return xpb;
600 	}
601 
602 	/*
603 	 * Accesses to the ARM Island overlay uses Island 0
604 	 * Global Bit
605 	 */
606 	*xpb_addr &= ~0x7f000000;
607 	if (*xpb_addr < 0x60000) {
608 		*xpb_addr |= (1 << 30);
609 	} else {
610 		/* And only non-ARM interfaces use island id = 1 */
611 		if (NFP_CPP_INTERFACE_TYPE_of(nfp_cpp_interface(cpp)) !=
612 				NFP_CPP_INTERFACE_TYPE_ARM)
613 			*xpb_addr |= (1 << 24);
614 	}
615 
616 	return xpb;
617 }
618 
619 /**
620  * Read a uint32_t value from an area
621  *
622  * @param area
623  *   CPP Area handle
624  * @param offset
625  *   Offset into area
626  * @param value
627  *   Pointer to read buffer
628  *
629  * @return
630  *   0 on success, or -ERRNO
631  */
632 int
633 nfp_cpp_area_readl(struct nfp_cpp_area *area,
634 		uint32_t offset,
635 		uint32_t *value)
636 {
637 	int sz;
638 	uint32_t tmp = 0;
639 
640 	sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp));
641 	if (sz != sizeof(tmp))
642 		return sz < 0 ? sz : -EIO;
643 
644 	*value = rte_le_to_cpu_32(tmp);
645 
646 	return 0;
647 }
648 
649 /**
650  * Write a uint32_t vale to an area
651  *
652  * @param area
653  *   CPP Area handle
654  * @param offset
655  *   Offset into area
656  * @param value
657  *   Value to write
658  *
659  * @return
660  *   0 on success, or -ERRNO
661  */
662 int
663 nfp_cpp_area_writel(struct nfp_cpp_area *area,
664 		uint32_t offset,
665 		uint32_t value)
666 {
667 	int sz;
668 
669 	value = rte_cpu_to_le_32(value);
670 	sz = nfp_cpp_area_write(area, offset, &value, sizeof(value));
671 	if (sz != sizeof(value))
672 		return sz < 0 ? sz : -EIO;
673 
674 	return 0;
675 }
676 
677 /**
678  * Read a uint64_t value from an area
679  *
680  * @param area
681  *   CPP Area handle
682  * @param offset
683  *   Offset into area
684  * @param value
685  *   Pointer to read buffer
686  *
687  * @return
688  *   0 on success, or -ERRNO
689  */
690 int
691 nfp_cpp_area_readq(struct nfp_cpp_area *area,
692 		uint32_t offset,
693 		uint64_t *value)
694 {
695 	int sz;
696 	uint64_t tmp = 0;
697 
698 	sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp));
699 	if (sz != sizeof(tmp))
700 		return sz < 0 ? sz : -EIO;
701 
702 	*value = rte_le_to_cpu_64(tmp);
703 
704 	return 0;
705 }
706 
707 /**
708  * Write a uint64_t vale to an area
709  *
710  * @param area
711  *   CPP Area handle
712  * @param offset
713  *   Offset into area
714  * @param value
715  *   Value to write
716  *
717  * @return
718  *   0 on success, or -ERRNO
719  */
720 int
721 nfp_cpp_area_writeq(struct nfp_cpp_area *area,
722 		uint32_t offset,
723 		uint64_t value)
724 {
725 	int sz;
726 
727 	value = rte_cpu_to_le_64(value);
728 	sz = nfp_cpp_area_write(area, offset, &value, sizeof(value));
729 	if (sz != sizeof(value))
730 		return sz < 0 ? sz : -EIO;
731 
732 	return 0;
733 }
734 
735 /**
736  * Read a uint32_t value from a CPP location
737  *
738  * @param cpp
739  *   CPP device handle
740  * @param cpp_id
741  *   CPP ID for operation
742  * @param address
743  *   Address for operation
744  * @param value
745  *   Pointer to read buffer
746  *
747  * @return
748  *   0 on success, or -ERRNO
749  */
750 int
751 nfp_cpp_readl(struct nfp_cpp *cpp,
752 		uint32_t cpp_id,
753 		uint64_t address,
754 		uint32_t *value)
755 {
756 	int sz;
757 	uint32_t tmp;
758 
759 	sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp));
760 	if (sz != sizeof(tmp))
761 		return sz < 0 ? sz : -EIO;
762 
763 	*value = rte_le_to_cpu_32(tmp);
764 
765 	return 0;
766 }
767 
768 /**
769  * Write a uint32_t value to a CPP location
770  *
771  * @param cpp
772  *   CPP device handle
773  * @param cpp_id
774  *   CPP ID for operation
775  * @param address
776  *   Address for operation
777  * @param value
778  *   Value to write
779  *
780  * @return
781  *   0 on success, or -ERRNO
782  */
783 int
784 nfp_cpp_writel(struct nfp_cpp *cpp,
785 		uint32_t cpp_id,
786 		uint64_t address,
787 		uint32_t value)
788 {
789 	int sz;
790 
791 	value = rte_cpu_to_le_32(value);
792 	sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value));
793 	if (sz != sizeof(value))
794 		return sz < 0 ? sz : -EIO;
795 
796 	return 0;
797 }
798 
799 /**
800  * Read a uint64_t value from a CPP location
801  *
802  * @param cpp
803  *   CPP device handle
804  * @param cpp_id
805  *   CPP ID for operation
806  * @param address
807  *   Address for operation
808  * @param value
809  *   Pointer to read buffer
810  *
811  * @return
812  *   0 on success, or -ERRNO
813  */
814 int
815 nfp_cpp_readq(struct nfp_cpp *cpp,
816 		uint32_t cpp_id,
817 		uint64_t address,
818 		uint64_t *value)
819 {
820 	int sz;
821 	uint64_t tmp;
822 
823 	sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp));
824 	*value = rte_le_to_cpu_64(tmp);
825 	if (sz != sizeof(tmp))
826 		return sz < 0 ? sz : -EIO;
827 
828 	return 0;
829 }
830 
831 /**
832  * Write a uint64_t value to a CPP location
833  *
834  * @param cpp
835  *   CPP device handle
836  * @param cpp_id
837  *   CPP ID for operation
838  * @param address
839  *   Address for operation
840  * @param value
841  *   Value to write
842  *
843  * @return
844  *   0 on success, or -ERRNO
845  */
846 int
847 nfp_cpp_writeq(struct nfp_cpp *cpp,
848 		uint32_t cpp_id,
849 		uint64_t address,
850 		uint64_t value)
851 {
852 	int sz;
853 
854 	value = rte_cpu_to_le_64(value);
855 	sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value));
856 	if (sz != sizeof(value))
857 		return sz < 0 ? sz : -EIO;
858 
859 	return 0;
860 }
861 
862 /**
863  * Write a uint32_t word to a XPB location
864  *
865  * @param cpp
866  *   CPP device handle
867  * @param xpb_addr
868  *   XPB target and address
869  * @param value
870  *   Value to write
871  *
872  * @return
873  *   0 on success, or -ERRNO
874  */
875 int
876 nfp_xpb_writel(struct nfp_cpp *cpp,
877 		uint32_t xpb_addr,
878 		uint32_t value)
879 {
880 	uint32_t cpp_dest;
881 
882 	cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr);
883 
884 	return nfp_cpp_writel(cpp, cpp_dest, xpb_addr, value);
885 }
886 
887 /**
888  * Read a uint32_t value from a XPB location
889  *
890  * @param cpp
891  *   CPP device handle
892  * @param xpb_addr
893  *   XPB target and address
894  * @param value
895  *   Pointer to read buffer
896  *
897  * @return
898  *   0 on success, or -ERRNO
899  */
900 int
901 nfp_xpb_readl(struct nfp_cpp *cpp,
902 		uint32_t xpb_addr,
903 		uint32_t *value)
904 {
905 	uint32_t cpp_dest;
906 
907 	cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr);
908 
909 	return nfp_cpp_readl(cpp, cpp_dest, xpb_addr, value);
910 }
911 
912 static struct nfp_cpp *
913 nfp_cpp_alloc(struct rte_pci_device *pci_dev,
914 		void *priv,
915 		bool driver_lock_needed)
916 {
917 	int err;
918 	size_t target;
919 	uint32_t xpb_addr;
920 	struct nfp_cpp *cpp;
921 	const struct nfp_cpp_operations *ops;
922 
923 	ops = nfp_cpp_transport_operations();
924 	if (ops == NULL || ops->init == NULL)
925 		return NULL;
926 
927 	cpp = calloc(1, sizeof(*cpp));
928 	if (cpp == NULL)
929 		return NULL;
930 
931 	cpp->op = ops;
932 	cpp->priv = priv;
933 	cpp->driver_lock_needed = driver_lock_needed;
934 
935 	err = ops->get_interface(pci_dev, &cpp->interface);
936 	if (err != 0) {
937 		free(cpp);
938 		return NULL;
939 	}
940 
941 	err = ops->get_serial(pci_dev, cpp->serial, NFP_SERIAL_LEN);
942 	if (err != 0) {
943 		free(cpp);
944 		return NULL;
945 	}
946 
947 	/*
948 	 * NOTE: cpp_lock is NOT locked for op->init,
949 	 * since it may call NFP CPP API operations
950 	 */
951 	err = cpp->op->init(cpp);
952 	if (err < 0) {
953 		PMD_DRV_LOG(ERR, "NFP interface initialization failed.");
954 		free(cpp);
955 		return NULL;
956 	}
957 
958 	err = nfp_cpp_model_autodetect(cpp, &cpp->model);
959 	if (err < 0) {
960 		PMD_DRV_LOG(ERR, "NFP model detection failed.");
961 		free(cpp);
962 		return NULL;
963 	}
964 
965 	for (target = 0; target < RTE_DIM(cpp->imb_cat_table); target++) {
966 		/* Hardcoded XPB IMB Base, island 0 */
967 		xpb_addr = 0x000a0000 + (target * 4);
968 		err = nfp_xpb_readl(cpp, xpb_addr, &cpp->imb_cat_table[target]);
969 		if (err < 0) {
970 			PMD_DRV_LOG(ERR, "Can not read CPP mapping from device.");
971 			free(cpp);
972 			return NULL;
973 		}
974 	}
975 
976 	err = nfp_cpp_set_mu_locality_lsb(cpp);
977 	if (err < 0) {
978 		PMD_DRV_LOG(ERR, "Can not calculate MU locality bit offset.");
979 		free(cpp);
980 		return NULL;
981 	}
982 
983 	return cpp;
984 }
985 
986 /**
987  * Free the CPP handle
988  *
989  * @param cpp
990  *   CPP handle
991  */
992 void
993 nfp_cpp_free(struct nfp_cpp *cpp)
994 {
995 	if (cpp->op != NULL && cpp->op->free != NULL)
996 		cpp->op->free(cpp);
997 
998 	free(cpp);
999 }
1000 
1001 /**
1002  * Create a NFP CPP handle from device
1003  *
1004  * @param dev
1005  *   PCI device
1006  * @param priv
1007  *   Private data of low-level implementation
1008  * @param driver_lock_needed
1009  *   Driver lock flag
1010  *
1011  * @return
1012  *   NFP CPP handle on success, NULL on failure
1013  *
1014  * NOTE: On failure, cpp_ops->free will be called!
1015  */
1016 struct nfp_cpp *
1017 nfp_cpp_from_device_name(struct rte_pci_device *dev,
1018 		void *priv,
1019 		bool driver_lock_needed)
1020 {
1021 	return nfp_cpp_alloc(dev, priv, driver_lock_needed);
1022 }
1023 
1024 /**
1025  * Read from CPP target
1026  *
1027  * @param cpp
1028  *   CPP handle
1029  * @param destination
1030  *   CPP id
1031  * @param offset
1032  *   Offset into CPP target
1033  * @param address
1034  *   Buffer for result
1035  * @param length
1036  *   Number of bytes to read
1037  *
1038  * @return
1039  *   Length of io, or -ERRNO
1040  */
1041 int
1042 nfp_cpp_read(struct nfp_cpp *cpp,
1043 		uint32_t destination,
1044 		uint64_t offset,
1045 		void *address,
1046 		size_t length)
1047 {
1048 	int err;
1049 	struct nfp_cpp_area *area;
1050 
1051 	area = nfp_cpp_area_alloc_acquire(cpp, destination, offset, length);
1052 	if (area == NULL) {
1053 		PMD_DRV_LOG(ERR, "Area allocation/acquire failed for read.");
1054 		return -EACCES;
1055 	}
1056 
1057 	err = nfp_cpp_area_read(area, 0, address, length);
1058 
1059 	nfp_cpp_area_release_free(area);
1060 	return err;
1061 }
1062 
1063 /**
1064  * Write to CPP target
1065  *
1066  * @param cpp
1067  *   CPP handle
1068  * @param destination
1069  *   CPP id
1070  * @param offset
1071  *   Offset into CPP target
1072  * @param address
1073  *   Buffer to read from
1074  * @param length
1075  *   Number of bytes to write
1076  *
1077  * @return
1078  *   Length of io, or -ERRNO
1079  */
1080 int
1081 nfp_cpp_write(struct nfp_cpp *cpp,
1082 		uint32_t destination,
1083 		uint64_t offset,
1084 		const void *address,
1085 		size_t length)
1086 {
1087 	int err;
1088 	struct nfp_cpp_area *area;
1089 
1090 	area = nfp_cpp_area_alloc_acquire(cpp, destination, offset, length);
1091 	if (area == NULL) {
1092 		PMD_DRV_LOG(ERR, "Area allocation/acquire failed for write.");
1093 		return -EACCES;
1094 	}
1095 
1096 	err = nfp_cpp_area_write(area, 0, address, length);
1097 
1098 	nfp_cpp_area_release_free(area);
1099 	return err;
1100 }
1101 
1102 /*
1103  * NOTE: This code should not use nfp_xpb_* functions,
1104  * as those are model-specific
1105  */
1106 uint32_t
1107 nfp_cpp_model_autodetect(struct nfp_cpp *cpp,
1108 		uint32_t *model)
1109 {
1110 	int err;
1111 	uint32_t reg;
1112 
1113 	err = nfp_xpb_readl(cpp, NFP_XPB_DEVICE(1, 1, 16) + NFP_PL_DEVICE_ID,
1114 			&reg);
1115 	if (err < 0)
1116 		return err;
1117 
1118 	*model = reg & NFP_PL_DEVICE_MODEL_MASK;
1119 	/* Disambiguate the NFP4000/NFP5000/NFP6000 chips */
1120 	if (FIELD_GET(NFP_PL_DEVICE_PART_MASK, reg) ==
1121 			NFP_PL_DEVICE_PART_NFP6000) {
1122 		if ((*model & NFP_PL_DEVICE_ID_MASK) != 0)
1123 			*model -= 0x10;
1124 	}
1125 
1126 	return 0;
1127 }
1128 
1129 /**
1130  * Map an area of IOMEM access.
1131  * To undo the effect of this function call @nfp_cpp_area_release_free(*area).
1132  *
1133  * @param cpp
1134  *   NFP CPP handler
1135  * @param cpp_id
1136  *   CPP id
1137  * @param addr
1138  *   CPP address
1139  * @param size
1140  *   Size of the area
1141  * @param area
1142  *   Area handle (output)
1143  *
1144  * @return
1145  *   Pointer to memory mapped area or NULL
1146  */
1147 uint8_t *
1148 nfp_cpp_map_area(struct nfp_cpp *cpp,
1149 		uint32_t cpp_id,
1150 		uint64_t addr,
1151 		uint32_t size,
1152 		struct nfp_cpp_area **area)
1153 {
1154 	uint8_t *res;
1155 
1156 	*area = nfp_cpp_area_alloc_acquire(cpp, cpp_id, addr, size);
1157 	if (*area == NULL) {
1158 		PMD_DRV_LOG(ERR, "Area allocation/acquire failed for map.");
1159 		goto err_eio;
1160 	}
1161 
1162 	res = nfp_cpp_area_iomem(*area);
1163 	if (res == NULL)
1164 		goto err_release_free;
1165 
1166 	return res;
1167 
1168 err_release_free:
1169 	nfp_cpp_area_release_free(*area);
1170 err_eio:
1171 	return NULL;
1172 }
1173