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