DPDK patches and discussions
 help / color / mirror / Atom feed
From: Chaoyong He <chaoyong.he@corigine.com>
To: dev@dpdk.org
Cc: oss-drivers@corigine.com, niklas.soderlund@corigine.com,
	Chaoyong He <chaoyong.he@corigine.com>
Subject: [PATCH 02/13] net/nfp: move shared target logic to own source file
Date: Mon, 10 Apr 2023 19:00:04 +0800	[thread overview]
Message-ID: <20230410110015.2973660-3-chaoyong.he@corigine.com> (raw)
In-Reply-To: <20230410110015.2973660-1-chaoyong.he@corigine.com>

Move the needed logic of nfp_target.h and nfp_cppat.h
to a new source file nfp_target.c, and delete the logic
which are not used at all.

The code is moved verbatim from the header file to the source
file, no functional change.

This mainly to mimic the source file structure in the kernel
driver, and also gives a nice decrease in driver size.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
 drivers/net/nfp/meson.build                   |   1 +
 .../net/nfp/nfpcore/nfp-common/nfp_cppat.h    | 725 -------------
 drivers/net/nfp/nfpcore/nfp6000/nfp6000.h     |  20 +
 drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c    |   3 +-
 drivers/net/nfp/nfpcore/nfp_cppcore.c         |   1 -
 drivers/net/nfp/nfpcore/nfp_target.c          | 994 ++++++++++++++++++
 drivers/net/nfp/nfpcore/nfp_target.h          |   1 -
 7 files changed, 1016 insertions(+), 729 deletions(-)
 delete mode 100644 drivers/net/nfp/nfpcore/nfp-common/nfp_cppat.h
 create mode 100644 drivers/net/nfp/nfpcore/nfp_target.c

diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index b60eaed2b7..6d122f5ce9 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -22,6 +22,7 @@ sources = files(
         'nfpcore/nfp_mutex.c',
         'nfpcore/nfp_nsp_eth.c',
         'nfpcore/nfp_hwinfo.c',
+        'nfpcore/nfp_target.c',
         'nfp_common.c',
         'nfp_rxtx.c',
         'nfp_cpp_bridge.c',
diff --git a/drivers/net/nfp/nfpcore/nfp-common/nfp_cppat.h b/drivers/net/nfp/nfpcore/nfp-common/nfp_cppat.h
deleted file mode 100644
index 538f882bf2..0000000000
--- a/drivers/net/nfp/nfpcore/nfp-common/nfp_cppat.h
+++ /dev/null
@@ -1,725 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Netronome Systems, Inc.
- * All rights reserved.
- */
-
-#ifndef __NFP_CPPAT_H__
-#define __NFP_CPPAT_H__
-
-#include "nfp_platform.h"
-#include "nfp_resid.h"
-
-/* This file contains helpers for creating CPP commands
- *
- * All magic NFP-6xxx IMB 'mode' numbers here are from:
- * Databook (1 August 2013)
- * - System Overview and Connectivity
- * -- Internal Connectivity
- * --- Distributed Switch Fabric - Command Push/Pull (DSF-CPP) Bus
- * ---- CPP addressing
- * ----- Table 3.6. CPP Address Translation Mode Commands
- */
-
-#define _NIC_NFP6000_MU_LOCALITY_DIRECT 2
-
-static inline int
-_nfp6000_decode_basic(uint64_t addr, int *dest_island, int cpp_tgt, int mode,
-		      int addr40, int isld1, int isld0);
-
-static uint64_t
-_nic_mask64(int msb, int lsb, int at0)
-{
-	uint64_t v;
-	int w = msb - lsb + 1;
-
-	if (w == 64)
-		return ~(uint64_t)0;
-
-	if ((lsb + w) > 64)
-		return 0;
-
-	v = (UINT64_C(1) << w) - 1;
-
-	if (at0)
-		return v;
-
-	return v << lsb;
-}
-
-/* For VQDR, we may not modify the Channel bits, which might overlap
- * with the Index bit. When it does, we need to ensure that isld0 == isld1.
- */
-static inline int
-_nfp6000_encode_basic(uint64_t *addr, int dest_island, int cpp_tgt, int mode,
-		      int addr40, int isld1, int isld0)
-{
-	uint64_t _u64;
-	int iid_lsb, idx_lsb;
-	int i, v = 0;
-	int isld[2];
-
-	isld[0] = isld0;
-	isld[1] = isld1;
-
-	switch (cpp_tgt) {
-	case NFP6000_CPPTGT_MU:
-		/* This function doesn't handle MU */
-		return NFP_ERRNO(EINVAL);
-	case NFP6000_CPPTGT_CTXPB:
-		/* This function doesn't handle CTXPB */
-		return NFP_ERRNO(EINVAL);
-	default:
-		break;
-	}
-
-	switch (mode) {
-	case 0:
-		if (cpp_tgt == NFP6000_CPPTGT_VQDR && !addr40) {
-			/*
-			 * In this specific mode we'd rather not modify the
-			 * address but we can verify if the existing contents
-			 * will point to a valid island.
-			 */
-			i = _nfp6000_decode_basic(*addr, &v, cpp_tgt, mode,
-						  addr40, isld1,
-						  isld0);
-			if (i != 0)
-				/* Full Island ID and channel bits overlap */
-				return i;
-
-			/*
-			 * If dest_island is invalid, the current address won't
-			 * go where expected.
-			 */
-			if (dest_island != -1 && dest_island != v)
-				return NFP_ERRNO(EINVAL);
-
-			/* If dest_island was -1, we don't care */
-			return 0;
-		}
-
-		iid_lsb = (addr40) ? 34 : 26;
-
-		/* <39:34> or <31:26> */
-		_u64 = _nic_mask64((iid_lsb + 5), iid_lsb, 0);
-		*addr &= ~_u64;
-		*addr |= (((uint64_t)dest_island) << iid_lsb) & _u64;
-		return 0;
-	case 1:
-		if (cpp_tgt == NFP6000_CPPTGT_VQDR && !addr40) {
-			i = _nfp6000_decode_basic(*addr, &v, cpp_tgt, mode,
-						  addr40, isld1, isld0);
-			if (i != 0)
-				/* Full Island ID and channel bits overlap */
-				return i;
-
-			/*
-			 * If dest_island is invalid, the current address won't
-			 * go where expected.
-			 */
-			if (dest_island != -1 && dest_island != v)
-				return NFP_ERRNO(EINVAL);
-
-			/* If dest_island was -1, we don't care */
-			return 0;
-		}
-
-		idx_lsb = (addr40) ? 39 : 31;
-		if (dest_island == isld0) {
-			/* Only need to clear the Index bit */
-			*addr &= ~_nic_mask64(idx_lsb, idx_lsb, 0);
-			return 0;
-		}
-
-		if (dest_island == isld1) {
-			/* Only need to set the Index bit */
-			*addr |= (UINT64_C(1) << idx_lsb);
-			return 0;
-		}
-
-		return NFP_ERRNO(ENODEV);
-	case 2:
-		if (cpp_tgt == NFP6000_CPPTGT_VQDR && !addr40) {
-			/* iid<0> = addr<30> = channel<0> */
-			/* channel<1> = addr<31> = Index */
-
-			/*
-			 * Special case where we allow channel bits to be set
-			 * before hand and with them select an island.
-			 * So we need to confirm that it's at least plausible.
-			 */
-			i = _nfp6000_decode_basic(*addr, &v, cpp_tgt, mode,
-						  addr40, isld1, isld0);
-			if (i != 0)
-				/* Full Island ID and channel bits overlap */
-				return i;
-
-			/*
-			 * If dest_island is invalid, the current address won't
-			 * go where expected.
-			 */
-			if (dest_island != -1 && dest_island != v)
-				return NFP_ERRNO(EINVAL);
-
-			/* If dest_island was -1, we don't care */
-			return 0;
-		}
-
-		/*
-		 * Make sure we compare against isldN values by clearing the
-		 * LSB. This is what the silicon does.
-		 **/
-		isld[0] &= ~1;
-		isld[1] &= ~1;
-
-		idx_lsb = (addr40) ? 39 : 31;
-		iid_lsb = idx_lsb - 1;
-
-		/*
-		 * Try each option, take first one that fits. Not sure if we
-		 * would want to do some smarter searching and prefer 0 or non-0
-		 * island IDs.
-		 */
-
-		for (i = 0; i < 2; i++) {
-			for (v = 0; v < 2; v++) {
-				if (dest_island != (isld[i] | v))
-					continue;
-				*addr &= ~_nic_mask64(idx_lsb, iid_lsb, 0);
-				*addr |= (((uint64_t)i) << idx_lsb);
-				*addr |= (((uint64_t)v) << iid_lsb);
-				return 0;
-			}
-		}
-
-		return NFP_ERRNO(ENODEV);
-	case 3:
-		if (cpp_tgt == NFP6000_CPPTGT_VQDR && !addr40) {
-			/*
-			 * iid<0> = addr<29> = data
-			 * iid<1> = addr<30> = channel<0>
-			 * channel<1> = addr<31> = Index
-			 */
-			i = _nfp6000_decode_basic(*addr, &v, cpp_tgt, mode,
-						  addr40, isld1, isld0);
-			if (i != 0)
-				/* Full Island ID and channel bits overlap */
-				return i;
-
-			if (dest_island != -1 && dest_island != v)
-				return NFP_ERRNO(EINVAL);
-
-			/* If dest_island was -1, we don't care */
-			return 0;
-		}
-
-		isld[0] &= ~3;
-		isld[1] &= ~3;
-
-		idx_lsb = (addr40) ? 39 : 31;
-		iid_lsb = idx_lsb - 2;
-
-		for (i = 0; i < 2; i++) {
-			for (v = 0; v < 4; v++) {
-				if (dest_island != (isld[i] | v))
-					continue;
-				*addr &= ~_nic_mask64(idx_lsb, iid_lsb, 0);
-				*addr |= (((uint64_t)i) << idx_lsb);
-				*addr |= (((uint64_t)v) << iid_lsb);
-				return 0;
-			}
-		}
-		return NFP_ERRNO(ENODEV);
-	default:
-		break;
-	}
-
-	return NFP_ERRNO(EINVAL);
-}
-
-static inline int
-_nfp6000_decode_basic(uint64_t addr, int *dest_island, int cpp_tgt, int mode,
-		      int addr40, int isld1, int isld0)
-{
-	int iid_lsb, idx_lsb;
-
-	switch (cpp_tgt) {
-	case NFP6000_CPPTGT_MU:
-		/* This function doesn't handle MU */
-		return NFP_ERRNO(EINVAL);
-	case NFP6000_CPPTGT_CTXPB:
-		/* This function doesn't handle CTXPB */
-		return NFP_ERRNO(EINVAL);
-	default:
-		break;
-	}
-
-	switch (mode) {
-	case 0:
-		/*
-		 * For VQDR, in this mode for 32-bit addressing it would be
-		 * islands 0, 16, 32 and 48 depending on channel and upper
-		 * address bits. Since those are not all valid islands, most
-		 * decode cases would result in bad island IDs, but we do them
-		 * anyway since this is decoding an address that is already
-		 * assumed to be used as-is to get to sram.
-		 */
-		iid_lsb = (addr40) ? 34 : 26;
-		*dest_island = (int)(addr >> iid_lsb) & 0x3F;
-		return 0;
-	case 1:
-		/*
-		 * For VQDR 32-bit, this would decode as:
-		 *	Channel 0: island#0
-		 *	Channel 1: island#0
-		 *	Channel 2: island#1
-		 *	Channel 3: island#1
-		 *
-		 * That would be valid as long as both islands have VQDR.
-		 * Let's allow this.
-		 */
-
-		idx_lsb = (addr40) ? 39 : 31;
-		if (addr & _nic_mask64(idx_lsb, idx_lsb, 0))
-			*dest_island = isld1;
-		else
-			*dest_island = isld0;
-
-		return 0;
-	case 2:
-		/*
-		 * For VQDR 32-bit:
-		 *	Channel 0: (island#0 | 0)
-		 *	Channel 1: (island#0 | 1)
-		 *	Channel 2: (island#1 | 0)
-		 *	Channel 3: (island#1 | 1)
-		 *
-		 * Make sure we compare against isldN values by clearing the
-		 * LSB. This is what the silicon does.
-		 */
-		isld0 &= ~1;
-		isld1 &= ~1;
-
-		idx_lsb = (addr40) ? 39 : 31;
-		iid_lsb = idx_lsb - 1;
-
-		if (addr & _nic_mask64(idx_lsb, idx_lsb, 0))
-			*dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
-		else
-			*dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
-
-		return 0;
-	case 3:
-		/*
-		 * In this mode the data address starts to affect the island ID
-		 * so rather not allow it. In some really specific case one
-		 * could use this to send the upper half of the VQDR channel to
-		 * another MU, but this is getting very specific. However, as
-		 * above for mode 0, this is the decoder and the caller should
-		 * validate the resulting IID. This blindly does what the
-		 * silicon would do.
-		 */
-
-		isld0 &= ~3;
-		isld1 &= ~3;
-
-		idx_lsb = (addr40) ? 39 : 31;
-		iid_lsb = idx_lsb - 2;
-
-		if (addr & _nic_mask64(idx_lsb, idx_lsb, 0))
-			*dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
-		else
-			*dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
-
-		return 0;
-	default:
-		break;
-	}
-
-	return NFP_ERRNO(EINVAL);
-}
-
-static inline int
-_nfp6000_cppat_mu_locality_lsb(int mode, int addr40)
-{
-	switch (mode) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-		return (addr40) ? 38 : 30;
-	default:
-		break;
-	}
-	return NFP_ERRNO(EINVAL);
-}
-
-static inline int
-_nfp6000_encode_mu(uint64_t *addr, int dest_island, int mode, int addr40,
-		   int isld1, int isld0)
-{
-	uint64_t _u64;
-	int iid_lsb, idx_lsb, locality_lsb;
-	int i, v;
-	int isld[2];
-	int da;
-
-	isld[0] = isld0;
-	isld[1] = isld1;
-	locality_lsb = _nfp6000_cppat_mu_locality_lsb(mode, addr40);
-
-	if (locality_lsb < 0)
-		return NFP_ERRNO(EINVAL);
-
-	if (((*addr >> locality_lsb) & 3) == _NIC_NFP6000_MU_LOCALITY_DIRECT)
-		da = 1;
-	else
-		da = 0;
-
-	switch (mode) {
-	case 0:
-		iid_lsb = (addr40) ? 32 : 24;
-		_u64 = _nic_mask64((iid_lsb + 5), iid_lsb, 0);
-		*addr &= ~_u64;
-		*addr |= (((uint64_t)dest_island) << iid_lsb) & _u64;
-		return 0;
-	case 1:
-		if (da) {
-			iid_lsb = (addr40) ? 32 : 24;
-			_u64 = _nic_mask64((iid_lsb + 5), iid_lsb, 0);
-			*addr &= ~_u64;
-			*addr |= (((uint64_t)dest_island) << iid_lsb) & _u64;
-			return 0;
-		}
-
-		idx_lsb = (addr40) ? 37 : 29;
-		if (dest_island == isld0) {
-			*addr &= ~_nic_mask64(idx_lsb, idx_lsb, 0);
-			return 0;
-		}
-
-		if (dest_island == isld1) {
-			*addr |= (UINT64_C(1) << idx_lsb);
-			return 0;
-		}
-
-		return NFP_ERRNO(ENODEV);
-	case 2:
-		if (da) {
-			iid_lsb = (addr40) ? 32 : 24;
-			_u64 = _nic_mask64((iid_lsb + 5), iid_lsb, 0);
-			*addr &= ~_u64;
-			*addr |= (((uint64_t)dest_island) << iid_lsb) & _u64;
-			return 0;
-		}
-
-		/*
-		 * Make sure we compare against isldN values by clearing the
-		 * LSB. This is what the silicon does.
-		 */
-		isld[0] &= ~1;
-		isld[1] &= ~1;
-
-		idx_lsb = (addr40) ? 37 : 29;
-		iid_lsb = idx_lsb - 1;
-
-		/*
-		 * Try each option, take first one that fits. Not sure if we
-		 * would want to do some smarter searching and prefer 0 or
-		 * non-0 island IDs.
-		 */
-
-		for (i = 0; i < 2; i++) {
-			for (v = 0; v < 2; v++) {
-				if (dest_island != (isld[i] | v))
-					continue;
-				*addr &= ~_nic_mask64(idx_lsb, iid_lsb, 0);
-				*addr |= (((uint64_t)i) << idx_lsb);
-				*addr |= (((uint64_t)v) << iid_lsb);
-				return 0;
-			}
-		}
-		return NFP_ERRNO(ENODEV);
-	case 3:
-		/*
-		 * Only the EMU will use 40 bit addressing. Silently set the
-		 * direct locality bit for everyone else. The SDK toolchain
-		 * uses dest_island <= 0 to test for atypical address encodings
-		 * to support access to local-island CTM with a 32-but address
-		 * (high-locality is effectively ignored and just used for
-		 * routing to island #0).
-		 */
-		if (dest_island > 0 &&
-		    (dest_island < 24 || dest_island > 26)) {
-			*addr |= ((uint64_t)_NIC_NFP6000_MU_LOCALITY_DIRECT)
-				 << locality_lsb;
-			da = 1;
-		}
-
-		if (da) {
-			iid_lsb = (addr40) ? 32 : 24;
-			_u64 = _nic_mask64((iid_lsb + 5), iid_lsb, 0);
-			*addr &= ~_u64;
-			*addr |= (((uint64_t)dest_island) << iid_lsb) & _u64;
-			return 0;
-		}
-
-		isld[0] &= ~3;
-		isld[1] &= ~3;
-
-		idx_lsb = (addr40) ? 37 : 29;
-		iid_lsb = idx_lsb - 2;
-
-		for (i = 0; i < 2; i++) {
-			for (v = 0; v < 4; v++) {
-				if (dest_island != (isld[i] | v))
-					continue;
-				*addr &= ~_nic_mask64(idx_lsb, iid_lsb, 0);
-				*addr |= (((uint64_t)i) << idx_lsb);
-				*addr |= (((uint64_t)v) << iid_lsb);
-				return 0;
-			}
-		}
-
-		return NFP_ERRNO(ENODEV);
-	default:
-		break;
-	}
-
-	return NFP_ERRNO(EINVAL);
-}
-
-static inline int
-_nfp6000_decode_mu(uint64_t addr, int *dest_island, int mode, int addr40,
-		   int isld1, int isld0)
-{
-	int iid_lsb, idx_lsb, locality_lsb;
-	int da;
-
-	locality_lsb = _nfp6000_cppat_mu_locality_lsb(mode, addr40);
-
-	if (((addr >> locality_lsb) & 3) == _NIC_NFP6000_MU_LOCALITY_DIRECT)
-		da = 1;
-	else
-		da = 0;
-
-	switch (mode) {
-	case 0:
-		iid_lsb = (addr40) ? 32 : 24;
-		*dest_island = (int)(addr >> iid_lsb) & 0x3F;
-		return 0;
-	case 1:
-		if (da) {
-			iid_lsb = (addr40) ? 32 : 24;
-			*dest_island = (int)(addr >> iid_lsb) & 0x3F;
-			return 0;
-		}
-
-		idx_lsb = (addr40) ? 37 : 29;
-
-		if (addr & _nic_mask64(idx_lsb, idx_lsb, 0))
-			*dest_island = isld1;
-		else
-			*dest_island = isld0;
-
-		return 0;
-	case 2:
-		if (da) {
-			iid_lsb = (addr40) ? 32 : 24;
-			*dest_island = (int)(addr >> iid_lsb) & 0x3F;
-			return 0;
-		}
-		/*
-		 * Make sure we compare against isldN values by clearing the
-		 * LSB. This is what the silicon does.
-		 */
-		isld0 &= ~1;
-		isld1 &= ~1;
-
-		idx_lsb = (addr40) ? 37 : 29;
-		iid_lsb = idx_lsb - 1;
-
-		if (addr & _nic_mask64(idx_lsb, idx_lsb, 0))
-			*dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
-		else
-			*dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
-
-		return 0;
-	case 3:
-		if (da) {
-			iid_lsb = (addr40) ? 32 : 24;
-			*dest_island = (int)(addr >> iid_lsb) & 0x3F;
-			return 0;
-		}
-
-		isld0 &= ~3;
-		isld1 &= ~3;
-
-		idx_lsb = (addr40) ? 37 : 29;
-		iid_lsb = idx_lsb - 2;
-
-		if (addr & _nic_mask64(idx_lsb, idx_lsb, 0))
-			*dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
-		else
-			*dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
-
-		return 0;
-	default:
-		break;
-	}
-
-	return NFP_ERRNO(EINVAL);
-}
-
-static inline int
-_nfp6000_cppat_addr_encode(uint64_t *addr, int dest_island, int cpp_tgt,
-			   int mode, int addr40, int isld1, int isld0)
-{
-	switch (cpp_tgt) {
-	case NFP6000_CPPTGT_NBI:
-	case NFP6000_CPPTGT_VQDR:
-	case NFP6000_CPPTGT_ILA:
-	case NFP6000_CPPTGT_PCIE:
-	case NFP6000_CPPTGT_ARM:
-	case NFP6000_CPPTGT_CRYPTO:
-	case NFP6000_CPPTGT_CLS:
-		return _nfp6000_encode_basic(addr, dest_island, cpp_tgt, mode,
-					     addr40, isld1, isld0);
-
-	case NFP6000_CPPTGT_MU:
-		return _nfp6000_encode_mu(addr, dest_island, mode, addr40,
-					  isld1, isld0);
-
-	case NFP6000_CPPTGT_CTXPB:
-		if (mode != 1 || addr40 != 0)
-			return NFP_ERRNO(EINVAL);
-
-		*addr &= ~_nic_mask64(29, 24, 0);
-		*addr |= (((uint64_t)dest_island) << 24) &
-			  _nic_mask64(29, 24, 0);
-		return 0;
-	default:
-		break;
-	}
-
-	return NFP_ERRNO(EINVAL);
-}
-
-static inline int
-_nfp6000_cppat_addr_decode(uint64_t addr, int *dest_island, int cpp_tgt,
-			   int mode, int addr40, int isld1, int isld0)
-{
-	switch (cpp_tgt) {
-	case NFP6000_CPPTGT_NBI:
-	case NFP6000_CPPTGT_VQDR:
-	case NFP6000_CPPTGT_ILA:
-	case NFP6000_CPPTGT_PCIE:
-	case NFP6000_CPPTGT_ARM:
-	case NFP6000_CPPTGT_CRYPTO:
-	case NFP6000_CPPTGT_CLS:
-		return _nfp6000_decode_basic(addr, dest_island, cpp_tgt, mode,
-					     addr40, isld1, isld0);
-
-	case NFP6000_CPPTGT_MU:
-		return _nfp6000_decode_mu(addr, dest_island, mode, addr40,
-					  isld1, isld0);
-
-	case NFP6000_CPPTGT_CTXPB:
-		if (mode != 1 || addr40 != 0)
-			return -EINVAL;
-		*dest_island = (int)(addr >> 24) & 0x3F;
-		return 0;
-	default:
-		break;
-	}
-
-	return -EINVAL;
-}
-
-static inline int
-_nfp6000_cppat_addr_iid_clear(uint64_t *addr, int cpp_tgt, int mode, int addr40)
-{
-	int iid_lsb, locality_lsb, da;
-
-	switch (cpp_tgt) {
-	case NFP6000_CPPTGT_NBI:
-	case NFP6000_CPPTGT_VQDR:
-	case NFP6000_CPPTGT_ILA:
-	case NFP6000_CPPTGT_PCIE:
-	case NFP6000_CPPTGT_ARM:
-	case NFP6000_CPPTGT_CRYPTO:
-	case NFP6000_CPPTGT_CLS:
-		switch (mode) {
-		case 0:
-			iid_lsb = (addr40) ? 34 : 26;
-			*addr &= ~(UINT64_C(0x3F) << iid_lsb);
-			return 0;
-		case 1:
-			iid_lsb = (addr40) ? 39 : 31;
-			*addr &= ~_nic_mask64(iid_lsb, iid_lsb, 0);
-			return 0;
-		case 2:
-			iid_lsb = (addr40) ? 38 : 30;
-			*addr &= ~_nic_mask64(iid_lsb + 1, iid_lsb, 0);
-			return 0;
-		case 3:
-			iid_lsb = (addr40) ? 37 : 29;
-			*addr &= ~_nic_mask64(iid_lsb + 2, iid_lsb, 0);
-			return 0;
-		default:
-			break;
-		}
-	case NFP6000_CPPTGT_MU:
-		locality_lsb = _nfp6000_cppat_mu_locality_lsb(mode, addr40);
-		da = (((*addr >> locality_lsb) & 3) ==
-		      _NIC_NFP6000_MU_LOCALITY_DIRECT);
-		switch (mode) {
-		case 0:
-			iid_lsb = (addr40) ? 32 : 24;
-			*addr &= ~(UINT64_C(0x3F) << iid_lsb);
-			return 0;
-		case 1:
-			if (da) {
-				iid_lsb = (addr40) ? 32 : 24;
-				*addr &= ~(UINT64_C(0x3F) << iid_lsb);
-				return 0;
-			}
-			iid_lsb = (addr40) ? 37 : 29;
-			*addr &= ~_nic_mask64(iid_lsb, iid_lsb, 0);
-			return 0;
-		case 2:
-			if (da) {
-				iid_lsb = (addr40) ? 32 : 24;
-				*addr &= ~(UINT64_C(0x3F) << iid_lsb);
-				return 0;
-			}
-
-			iid_lsb = (addr40) ? 36 : 28;
-			*addr &= ~_nic_mask64(iid_lsb + 1, iid_lsb, 0);
-			return 0;
-		case 3:
-			if (da) {
-				iid_lsb = (addr40) ? 32 : 24;
-				*addr &= ~(UINT64_C(0x3F) << iid_lsb);
-				return 0;
-			}
-
-			iid_lsb = (addr40) ? 35 : 27;
-			*addr &= ~_nic_mask64(iid_lsb + 2, iid_lsb, 0);
-			return 0;
-		default:
-			break;
-		}
-	case NFP6000_CPPTGT_CTXPB:
-		if (mode != 1 || addr40 != 0)
-			return 0;
-		*addr &= ~(UINT64_C(0x3F) << 24);
-		return 0;
-	default:
-		break;
-	}
-
-	return NFP_ERRNO(EINVAL);
-}
-
-#endif /* __NFP_CPPAT_H__ */
diff --git a/drivers/net/nfp/nfpcore/nfp6000/nfp6000.h b/drivers/net/nfp/nfpcore/nfp6000/nfp6000.h
index 47e1ddaeed..7750a0218e 100644
--- a/drivers/net/nfp/nfpcore/nfp6000/nfp6000.h
+++ b/drivers/net/nfp/nfpcore/nfp6000/nfp6000.h
@@ -26,6 +26,21 @@
 #define NFP_MU_ADDR_ACCESS_TYPE_MASK    3ULL
 #define NFP_MU_ADDR_ACCESS_TYPE_DIRECT  2ULL
 
+#define PUSHPULL(pull, push)       (((pull) << 4) | ((push) << 0))
+#define PUSH_WIDTH(push_pull)      pushpull_width((push_pull) >> 0)
+#define PULL_WIDTH(push_pull)      pushpull_width((push_pull) >> 4)
+
+static inline int
+pushpull_width(int pp)
+{
+	pp &= 0xf;
+	if (pp == 0)
+		return -EINVAL;
+
+	return 2 << pp;
+}
+
+
 static inline int
 nfp_cppat_mu_locality_lsb(int mode, int addr40)
 {
@@ -37,4 +52,9 @@ nfp_cppat_mu_locality_lsb(int mode, int addr40)
 	}
 }
 
+int nfp_target_pushpull(uint32_t cpp_id, uint64_t address);
+int nfp_target_cpp(uint32_t cpp_island_id, uint64_t cpp_island_address,
+		uint32_t *cpp_target_id, uint64_t *cpp_target_address,
+		const uint32_t *imb_table);
+
 #endif /* NFP_NFP6000_H */
diff --git a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c
index 6029bd6c3a..edf4088747 100644
--- a/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c
+++ b/drivers/net/nfp/nfpcore/nfp_cpp_pcie_ops.c
@@ -34,7 +34,6 @@
 
 #include "nfp_cpp.h"
 #include "nfp_logs.h"
-#include "nfp_target.h"
 #include "nfp6000/nfp6000.h"
 #include "../nfp_logs.h"
 
@@ -406,7 +405,7 @@ nfp6000_area_init(struct nfp_cpp_area *area, uint32_t dest,
 	uint32_t token = NFP_CPP_ID_TOKEN_of(dest);
 	int pp, ret = 0;
 
-	pp = nfp6000_target_pushpull(NFP_CPP_ID(target, action, token),
+	pp = nfp_target_pushpull(NFP_CPP_ID(target, action, token),
 				     address);
 	if (pp < 0)
 		return pp;
diff --git a/drivers/net/nfp/nfpcore/nfp_cppcore.c b/drivers/net/nfp/nfpcore/nfp_cppcore.c
index 72f50ace38..1d2468ad7a 100644
--- a/drivers/net/nfp/nfpcore/nfp_cppcore.c
+++ b/drivers/net/nfp/nfpcore/nfp_cppcore.c
@@ -16,7 +16,6 @@
 
 #include "nfp_cpp.h"
 #include "nfp_logs.h"
-#include "nfp_target.h"
 #include "nfp6000/nfp6000.h"
 #include "nfp6000/nfp_xpb.h"
 #include "nfp_nffw.h"
diff --git a/drivers/net/nfp/nfpcore/nfp_target.c b/drivers/net/nfp/nfpcore/nfp_target.c
new file mode 100644
index 0000000000..3f7ddfb5e9
--- /dev/null
+++ b/drivers/net/nfp/nfpcore/nfp_target.c
@@ -0,0 +1,994 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Corigine, Inc.
+ * All rights reserved.
+ */
+
+#include "nfp_cpp.h"
+#include "nfp6000/nfp6000.h"
+
+#define P32 1
+#define P64 2
+
+/*
+ * All magic NFP-6xxx IMB 'mode' numbers here are from:
+ * Databook (1 August 2013)
+ * - System Overview and Connectivity
+ * -- Internal Connectivity
+ * --- Distributed Switch Fabric - Command Push/Pull (DSF-CPP) Bus
+ * ---- CPP addressing
+ * ----- Table 3.6. CPP Address Translation Mode Commands
+ */
+#define NFP6000_MU_LOCALITY_DIRECT 2
+
+static int
+target_rw(uint32_t cpp_id,
+		int pp,
+		int start,
+		int len)
+{
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island != 0 && (island < start || island > (start + len)))
+		return -EINVAL;
+
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 0):
+		return PUSHPULL(0, pp);
+	case NFP_CPP_ID(0, 1, 0):
+		return PUSHPULL(pp, 0);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
+		return PUSHPULL(pp, pp);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp6000_nbi_dma(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 0): /* Read NBI DMA */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 1, 0): /* Write NBI DMA */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
+		return PUSHPULL(P64, P64);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp6000_nbi_stats(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 0): /* Read NBI Stats */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 1, 0): /* Write NBI Stats */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
+		return PUSHPULL(P32, P32);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp6000_nbi_tm(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 0): /* Read NBI TM */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 1, 0): /* Write NBI TM */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
+		return PUSHPULL(P64, P64);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp6000_nbi_ppc(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 0): /* Read NBI Preclassifier */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 1, 0): /* Write NBI Preclassifier */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0):
+		return PUSHPULL(P64, P64);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp6000_nbi(uint32_t cpp_id,
+		uint64_t address)
+{
+	uint8_t island;
+	uint64_t rel_addr;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island != 8 && island != 9)
+		return -EINVAL;
+
+	rel_addr = address & 0x3FFFFF;
+	if (rel_addr < (1 << 20))        /* [0x000000, 0x100000) */
+		return nfp6000_nbi_dma(cpp_id);
+	else if (rel_addr < (2 << 20))   /* [0x100000, 0x200000) */
+		return nfp6000_nbi_stats(cpp_id);
+	else if (rel_addr < (3 << 20))   /* [0x200000, 0x300000) */
+		return nfp6000_nbi_tm(cpp_id);
+	else                             /* [0x300000, 0x400000) */
+		return nfp6000_nbi_ppc(cpp_id);
+}
+
+/*
+ * This structure ONLY includes items that can be done with a read or write of
+ * 32-bit or 64-bit words. All others are not listed.
+ */
+static int
+nfp6000_mu_common(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 0): /* read_be/write_be */
+		return PUSHPULL(P64, P64);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 1): /* read_le/write_le */
+		return PUSHPULL(P64, P64);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 2): /* read_swap_be/write_swap_be */
+		return PUSHPULL(P64, P64);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 3): /* read_swap_le/write_swap_le */
+		return PUSHPULL(P64, P64);
+	case NFP_CPP_ID(0, 0, 0): /* read_be */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 0, 1): /* read_le */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 0, 2): /* read_swap_be */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 0, 3): /* read_swap_le */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 1, 0): /* write_be */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, 1, 1): /* write_le */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, 1, 2): /* write_swap_be */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, 1, 3): /* write_swap_le */
+		return PUSHPULL(P64, 0);
+	case NFP_CPP_ID(0, 3, 0): /* atomic_read */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 3, 2): /* mask_compare_write */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 4, 0): /* atomic_write */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 4, 2): /* atomic_write_imm */
+		return PUSHPULL(0, 0);
+	case NFP_CPP_ID(0, 4, 3): /* swap_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 5, 0): /* set */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 5, 3): /* test_set_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 6, 0): /* clr */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 6, 3): /* test_clr_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 7, 0): /* add */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 7, 3): /* test_add_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 8, 0): /* addsat */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 8, 3): /* test_subsat_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 9, 0): /* sub */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 9, 3): /* test_sub_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 10, 0): /* subsat */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 10, 3): /* test_subsat_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 13, 0): /* microq128_get */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 13, 1): /* microq128_pop */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 13, 2): /* microq128_put */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 15, 0): /* xor */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 15, 3): /* test_xor_imm */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 28, 0): /* read32_be */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 28, 1): /* read32_le */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 28, 2): /* read32_swap_be */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 28, 3): /* read32_swap_le */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 31, 0): /* write32_be */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 31, 1): /* write32_le */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 31, 2): /* write32_swap_be */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 31, 3): /* write32_swap_le */
+		return PUSHPULL(P32, 0);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp6000_mu_ctm(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 16, 1): /* packet_read_packet_status */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 17, 1): /* packet_credit_get */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 17, 3): /* packet_add_thread */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 18, 2): /* packet_free_and_return_pointer */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 18, 3): /* packet_return_pointer */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 21, 0): /* pe_dma_to_memory_indirect */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 21, 1): /* pe_dma_to_memory_indirect_swap */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 21, 2): /* pe_dma_to_memory_indirect_free */
+		return PUSHPULL(0, P64);
+	case NFP_CPP_ID(0, 21, 3): /* pe_dma_to_memory_indirect_free_swap */
+		return PUSHPULL(0, P64);
+	default:
+		return nfp6000_mu_common(cpp_id);
+	}
+}
+
+static int
+nfp6000_mu_emu(uint32_t cpp_id)
+{
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 18, 0): /* read_queue */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 18, 1): /* read_queue_ring */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 18, 2): /* write_queue */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 18, 3): /* write_queue_ring */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 20, 2): /* journal */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 21, 0): /* get */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 21, 1): /* get_eop */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 21, 2): /* get_freely */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 22, 0): /* pop */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 22, 1): /* pop_eop */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 22, 2): /* pop_freely */
+		return PUSHPULL(0, P32);
+	default:
+		return nfp6000_mu_common(cpp_id);
+	}
+}
+
+static int
+nfp6000_mu_imu(uint32_t cpp_id)
+{
+	return nfp6000_mu_common(cpp_id);
+}
+
+static int
+nfp6000_mu(uint32_t cpp_id,
+		uint64_t address)
+{
+	int pp;
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island == 0) {
+		if (address < 0x2000000000ULL)
+			pp = nfp6000_mu_ctm(cpp_id);
+		else if (address < 0x8000000000ULL)
+			pp = nfp6000_mu_emu(cpp_id);
+		else if (address < 0x9800000000ULL)
+			pp = nfp6000_mu_ctm(cpp_id);
+		else if (address < 0x9C00000000ULL)
+			pp = nfp6000_mu_emu(cpp_id);
+		else if (address < 0xA000000000ULL)
+			pp = nfp6000_mu_imu(cpp_id);
+		else
+			pp = nfp6000_mu_ctm(cpp_id);
+	} else if (island >= 24 && island <= 27) {
+		pp = nfp6000_mu_emu(cpp_id);
+	} else if (island >= 28 && island <= 31) {
+		pp = nfp6000_mu_imu(cpp_id);
+	} else if (island == 1 ||
+			(island >= 4 && island <= 7) ||
+			(island >= 12 && island <= 13) ||
+			(island >= 32 && island <= 47) ||
+			(island >= 48 && island <= 51)) {
+		pp = nfp6000_mu_ctm(cpp_id);
+	} else {
+		pp = -EINVAL;
+	}
+
+	return pp;
+}
+
+static int
+nfp6000_ila(uint32_t cpp_id)
+{
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island != 0 && (island < 48 || island > 51))
+		return -EINVAL;
+
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 1): /* read_check_error */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 2, 0): /* read_int */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 3, 0): /* write_int */
+		return PUSHPULL(P32, 0);
+	default:
+		return target_rw(cpp_id, P32, 48, 4);
+	}
+}
+
+static int
+nfp6000_pci(uint32_t cpp_id)
+{
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island != 0 && (island < 4 || island > 7))
+		return -EINVAL;
+
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 2, 0):
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 3, 0):
+		return PUSHPULL(P32, 0);
+	default:
+		return target_rw(cpp_id, P32, 4, 4);
+	}
+}
+
+static int
+nfp6000_crypto(uint32_t cpp_id)
+{
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island != 0 && (island < 12 || island > 15))
+		return -EINVAL;
+
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 2, 0):
+		return PUSHPULL(P64, 0);
+	default:
+		return target_rw(cpp_id, P64, 12, 4);
+	}
+}
+
+static int
+nfp6000_cap_xpb(uint32_t cpp_id)
+{
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island > 63)
+		return -EINVAL;
+
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 1): /* RingGet */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 0, 2): /* Interthread Signal */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 1, 1): /* RingPut */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 1, 2): /* CTNNWr */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 2, 0): /* ReflectRd, signal none */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 2, 1): /* ReflectRd, signal self */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 2, 2): /* ReflectRd, signal remote */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 2, 3): /* ReflectRd, signal both */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 3, 0): /* ReflectWr, signal none */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 3, 1): /* ReflectWr, signal self */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 3, 2): /* ReflectWr, signal remote */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 3, 3): /* ReflectWr, signal both */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, NFP_CPP_ACTION_RW, 1):
+		return PUSHPULL(P32, P32);
+	default:
+		return target_rw(cpp_id, P32, 1, 63);
+	}
+}
+
+static int
+nfp6000_cls(uint32_t cpp_id)
+{
+	uint8_t island;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_id);
+	if (island > 63)
+		return -EINVAL;
+
+	switch (cpp_id & NFP_CPP_ID(0, ~0, ~0)) {
+	case NFP_CPP_ID(0, 0, 3): /* xor */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 2, 0): /* set */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 2, 1): /* clr */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 4, 0): /* add */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 4, 1): /* add64 */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 6, 0): /* sub */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 6, 1): /* sub64 */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 6, 2): /* subsat */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 8, 2): /* hash_mask */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 8, 3): /* hash_clear */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 9, 0): /* ring_get */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 9, 1): /* ring_pop */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 9, 2): /* ring_get_freely */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 9, 3): /* ring_pop_freely */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 10, 0): /* ring_put */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 10, 2): /* ring_journal */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 14, 0): /* reflect_write_sig_local */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 15, 1):  /* reflect_read_sig_local */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 17, 2): /* statistic */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 24, 0): /* ring_read */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 24, 1): /* ring_write */
+		return PUSHPULL(P32, 0);
+	case NFP_CPP_ID(0, 25, 0): /* ring_workq_add_thread */
+		return PUSHPULL(0, P32);
+	case NFP_CPP_ID(0, 25, 1): /* ring_workq_add_work */
+		return PUSHPULL(P32, 0);
+	default:
+		return target_rw(cpp_id, P32, 0, 64);
+	}
+}
+
+int
+nfp_target_pushpull(uint32_t cpp_id,
+		uint64_t address)
+{
+	switch (NFP_CPP_ID_TARGET_of(cpp_id)) {
+	case NFP6000_CPPTGT_NBI:
+		return nfp6000_nbi(cpp_id, address);
+	case NFP6000_CPPTGT_VQDR:
+		return target_rw(cpp_id, P32, 24, 4);
+	case NFP6000_CPPTGT_ILA:
+		return nfp6000_ila(cpp_id);
+	case NFP6000_CPPTGT_MU:
+		return nfp6000_mu(cpp_id, address);
+	case NFP6000_CPPTGT_PCIE:
+		return nfp6000_pci(cpp_id);
+	case NFP6000_CPPTGT_ARM:
+		if (address < 0x10000)
+			return target_rw(cpp_id, P64, 1, 1);
+		else
+			return target_rw(cpp_id, P32, 1, 1);
+	case NFP6000_CPPTGT_CRYPTO:
+		return nfp6000_crypto(cpp_id);
+	case NFP6000_CPPTGT_CTXPB:
+		return nfp6000_cap_xpb(cpp_id);
+	case NFP6000_CPPTGT_CLS:
+		return nfp6000_cls(cpp_id);
+	case 0:
+		return target_rw(cpp_id, P32, 4, 4);
+	default:
+		return -EINVAL;
+	}
+}
+
+static uint64_t
+nfp_mask64(int msb,
+		int lsb)
+{
+	int width;
+
+	if (msb < 0 || lsb < 0)
+		return 0;
+
+	width = msb - lsb + 1;
+	if (width < 0)
+		return 0;
+
+	if (width == 64)
+		return ~(uint64_t)0;
+
+	if ((lsb + width) > 64)
+		return 0;
+
+	return (RTE_BIT64(width) - 1) << lsb;
+}
+
+static int
+nfp_decode_basic(uint64_t addr,
+		int *dest_island,
+		int cpp_tgt,
+		int mode,
+		int addr40,
+		int isld1,
+		int isld0)
+{
+	int iid_lsb;
+	int idx_lsb;
+
+	/* This function doesn't handle MU or CTXBP */
+	if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
+		return -EINVAL;
+
+	switch (mode) {
+	case 0:
+		/*
+		 * For VQDR, in this mode for 32-bit addressing it would be
+		 * islands 0, 16, 32 and 48 depending on channel and upper
+		 * address bits. Since those are not all valid islands, most
+		 * decode cases would result in bad island IDs, but we do them
+		 * anyway since this is decoding an address that is already
+		 * assumed to be used as-is to get to sram.
+		 */
+		iid_lsb = (addr40) ? 34 : 26;
+		*dest_island = (int)(addr >> iid_lsb) & 0x3F;
+
+		return 0;
+	case 1:
+		/*
+		 * For VQDR 32-bit, this would decode as:
+		 *	Channel 0: island#0
+		 *	Channel 1: island#0
+		 *	Channel 2: island#1
+		 *	Channel 3: island#1
+		 *
+		 * That would be valid as long as both islands have VQDR.
+		 * Let's allow this.
+		 */
+		idx_lsb = (addr40) ? 39 : 31;
+		if ((addr & nfp_mask64(idx_lsb, idx_lsb)) != 0)
+			*dest_island = isld1;
+		else
+			*dest_island = isld0;
+
+		return 0;
+	case 2:
+		/*
+		 * For VQDR 32-bit:
+		 *	Channel 0: (island#0 | 0)
+		 *	Channel 1: (island#0 | 1)
+		 *	Channel 2: (island#1 | 0)
+		 *	Channel 3: (island#1 | 1)
+		 *
+		 * Make sure we compare against isldN values by clearing the
+		 * LSB. This is what the silicon does.
+		 */
+		isld0 &= ~1;
+		isld1 &= ~1;
+
+		idx_lsb = (addr40) ? 39 : 31;
+		iid_lsb = idx_lsb - 1;
+
+		if ((addr & nfp_mask64(idx_lsb, idx_lsb)) != 0)
+			*dest_island = isld1 | (int)((addr >> iid_lsb) & 1);
+		else
+			*dest_island = isld0 | (int)((addr >> iid_lsb) & 1);
+
+		return 0;
+	case 3:
+		/*
+		 * In this mode the data address starts to affect the island ID
+		 * so rather not allow it. In some really specific case one
+		 * could use this to send the upper half of the VQDR channel to
+		 * another MU, but this is getting very specific. However, as
+		 * above for mode 0, this is the decoder and the caller should
+		 * validate the resulting IID. This blindly does what the
+		 * silicon would do.
+		 */
+		isld0 &= ~3;
+		isld1 &= ~3;
+
+		idx_lsb = (addr40) ? 39 : 31;
+		iid_lsb = idx_lsb - 2;
+
+		if ((addr & nfp_mask64(idx_lsb, idx_lsb)) != 0)
+			*dest_island = isld1 | (int)((addr >> iid_lsb) & 3);
+		else
+			*dest_island = isld0 | (int)((addr >> iid_lsb) & 3);
+
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp_encode_basic_qdr(uint64_t addr,
+		int dest_island,
+		int cpp_tgt,
+		int mode,
+		int addr40,
+		int isld1,
+		int isld0)
+{
+	int v;
+	int ret;
+
+	/* Full Island ID and channel bits overlap? */
+	ret = nfp_decode_basic(addr, &v, cpp_tgt, mode, addr40, isld1, isld0);
+	if (ret != 0)
+		return ret;
+
+	/* The current address won't go where expected? */
+	if (dest_island != -1 && dest_island != v)
+		return -EINVAL;
+
+	/* If dest_island was -1, we don't care where it goes. */
+	return 0;
+}
+
+/*
+ * Try each option, take first one that fits.
+ * Not sure if we would want to do some smarter
+ * searching and prefer 0 or non-0 island IDs.
+ */
+static int
+nfp_encode_basic_search(uint64_t *addr,
+		int dest_island,
+		int *isld,
+		int iid_lsb,
+		int idx_lsb,
+		int v_max)
+{
+	int i;
+	int v;
+
+	for (i = 0; i < 2; i++)
+		for (v = 0; v < v_max; v++) {
+			if (dest_island != (isld[i] | v))
+				continue;
+
+			*addr &= ~nfp_mask64(idx_lsb, iid_lsb);
+			*addr |= ((uint64_t)i << idx_lsb);
+			*addr |= ((uint64_t)v << iid_lsb);
+			return 0;
+		}
+
+	return -ENODEV;
+}
+
+/*
+ * For VQDR, we may not modify the Channel bits, which might overlap
+ * with the Index bit. When it does, we need to ensure that isld0 == isld1.
+ */
+static int
+nfp_encode_basic(uint64_t *addr,
+		int dest_island,
+		int cpp_tgt,
+		int mode,
+		int addr40,
+		int isld1,
+		int isld0)
+{
+	int iid_lsb;
+	int idx_lsb;
+	int isld[2];
+	uint64_t value;
+
+	isld[0] = isld0;
+	isld[1] = isld1;
+
+	/* This function doesn't handle MU or CTXBP */
+	if (cpp_tgt == NFP_CPP_TARGET_MU || cpp_tgt == NFP_CPP_TARGET_CT_XPB)
+		return -EINVAL;
+
+	switch (mode) {
+	case 0:
+		if (cpp_tgt == NFP6000_CPPTGT_VQDR && addr40 == 0) {
+			/*
+			 * In this specific mode we'd rather not modify the
+			 * address but we can verify if the existing contents
+			 * will point to a valid island.
+			 */
+			return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
+					mode, addr40, isld1, isld0);
+		}
+
+		iid_lsb = (addr40) ? 34 : 26;
+
+		/* <39:34> or <31:26> */
+		value = nfp_mask64((iid_lsb + 5), iid_lsb);
+		*addr &= ~value;
+		*addr |= (((uint64_t)dest_island) << iid_lsb) & value;
+		return 0;
+	case 1:
+		if (cpp_tgt == NFP6000_CPPTGT_VQDR && addr40 == 0) {
+			return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
+					mode, addr40, isld1, isld0);
+		}
+
+		idx_lsb = (addr40) ? 39 : 31;
+		if (dest_island == isld0) {
+			/* Only need to clear the Index bit */
+			*addr &= ~nfp_mask64(idx_lsb, idx_lsb);
+			return 0;
+		}
+
+		if (dest_island == isld1) {
+			/* Only need to set the Index bit */
+			*addr |= (UINT64_C(1) << idx_lsb);
+			return 0;
+		}
+
+		return -ENODEV;
+	case 2:
+		if (cpp_tgt == NFP6000_CPPTGT_VQDR && addr40 == 0) {
+			/* iid<0> = addr<30> = channel<0> */
+			/* channel<1> = addr<31> = Index */
+			return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
+					mode, addr40, isld1, isld0);
+		}
+
+		/*
+		 * Make sure we compare against isldN values by clearing the
+		 * LSB. This is what the silicon does.
+		 **/
+		isld[0] &= ~1;
+		isld[1] &= ~1;
+
+		idx_lsb = (addr40) ? 39 : 31;
+		iid_lsb = idx_lsb - 1;
+
+		return nfp_encode_basic_search(addr, dest_island, isld,
+				iid_lsb, idx_lsb, 2);
+	case 3:
+		if (cpp_tgt == NFP6000_CPPTGT_VQDR && addr40 == 0) {
+			/*
+			 * iid<0> = addr<29> = data
+			 * iid<1> = addr<30> = channel<0>
+			 * channel<1> = addr<31> = Index
+			 */
+			return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
+					mode, addr40, isld1, isld0);
+		}
+
+		isld[0] &= ~3;
+		isld[1] &= ~3;
+
+		idx_lsb = (addr40) ? 39 : 31;
+		iid_lsb = idx_lsb - 2;
+
+		return nfp_encode_basic_search(addr, dest_island, isld,
+				iid_lsb, idx_lsb, 4);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp_encode_mu(uint64_t *addr,
+		int dest_island,
+		int mode,
+		int addr40,
+		int isld1,
+		int isld0)
+{
+	int da;
+	int iid_lsb;
+	int idx_lsb;
+	int isld[2];
+	uint64_t value;
+	int locality_lsb;
+
+	isld[0] = isld0;
+	isld[1] = isld1;
+
+	locality_lsb = nfp_cppat_mu_locality_lsb(mode, addr40);
+	if (locality_lsb < 0)
+		return -EINVAL;
+
+	if (((*addr >> locality_lsb) & 3) == NFP6000_MU_LOCALITY_DIRECT)
+		da = 1;
+	else
+		da = 0;
+
+	switch (mode) {
+	case 0:
+		iid_lsb = (addr40 != 0) ? 32 : 24;
+		value = nfp_mask64((iid_lsb + 5), iid_lsb);
+		*addr &= ~value;
+		*addr |= (((uint64_t)dest_island) << iid_lsb) & value;
+		return 0;
+	case 1:
+		if (da == 1) {
+			iid_lsb = (addr40 != 0) ? 32 : 24;
+			value = nfp_mask64((iid_lsb + 5), iid_lsb);
+			*addr &= ~value;
+			*addr |= (((uint64_t)dest_island) << iid_lsb) & value;
+			return 0;
+		}
+
+		idx_lsb = (addr40 != 0) ? 37 : 29;
+		if (dest_island == isld0) {
+			*addr &= ~nfp_mask64(idx_lsb, idx_lsb);
+			return 0;
+		}
+
+		if (dest_island == isld1) {
+			*addr |= (UINT64_C(1) << idx_lsb);
+			return 0;
+		}
+
+		return -ENODEV;
+	case 2:
+		if (da == 1) {
+			iid_lsb = (addr40 != 0) ? 32 : 24;
+			value = nfp_mask64((iid_lsb + 5), iid_lsb);
+			*addr &= ~value;
+			*addr |= (((uint64_t)dest_island) << iid_lsb) & value;
+			return 0;
+		}
+
+		/*
+		 * Make sure we compare against isldN values by clearing the
+		 * LSB. This is what the silicon does.
+		 */
+		isld[0] &= ~1;
+		isld[1] &= ~1;
+
+		idx_lsb = (addr40 != 0) ? 37 : 29;
+		iid_lsb = idx_lsb - 1;
+
+		return nfp_encode_basic_search(addr, dest_island, isld,
+				iid_lsb, idx_lsb, 2);
+	case 3:
+		/*
+		 * Only the EMU will use 40 bit addressing. Silently set the
+		 * direct locality bit for everyone else. The SDK toolchain
+		 * uses dest_island <= 0 to test for atypical address encodings
+		 * to support access to local-island CTM with a 32-but address
+		 * (high-locality is effectively ignored and just used for
+		 * routing to island #0).
+		 */
+		if (dest_island > 0 && (dest_island < 24 || dest_island > 26)) {
+			*addr |= ((uint64_t)NFP6000_MU_LOCALITY_DIRECT)
+					<< locality_lsb;
+			da = 1;
+		}
+
+		if (da == 1) {
+			iid_lsb = (addr40 != 0) ? 32 : 24;
+			value = nfp_mask64((iid_lsb + 5), iid_lsb);
+			*addr &= ~value;
+			*addr |= (((uint64_t)dest_island) << iid_lsb) & value;
+			return 0;
+		}
+
+		isld[0] &= ~3;
+		isld[1] &= ~3;
+
+		idx_lsb = (addr40 != 0) ? 37 : 29;
+		iid_lsb = idx_lsb - 2;
+
+		return nfp_encode_basic_search(addr, dest_island, isld,
+				iid_lsb, idx_lsb, 4);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int
+nfp_cppat_addr_encode(uint64_t *addr,
+		int dest_island,
+		int cpp_tgt,
+		int mode,
+		int addr40,
+		int isld1,
+		int isld0)
+{
+	uint64_t value;
+
+	switch (cpp_tgt) {
+	case NFP6000_CPPTGT_NBI:
+	case NFP6000_CPPTGT_VQDR:
+	case NFP6000_CPPTGT_ILA:
+	case NFP6000_CPPTGT_PCIE:
+	case NFP6000_CPPTGT_ARM:
+	case NFP6000_CPPTGT_CRYPTO:
+	case NFP6000_CPPTGT_CLS:
+		return nfp_encode_basic(addr, dest_island, cpp_tgt, mode,
+				addr40, isld1, isld0);
+	case NFP6000_CPPTGT_MU:
+		return nfp_encode_mu(addr, dest_island, mode, addr40,
+				isld1, isld0);
+	case NFP6000_CPPTGT_CTXPB:
+		if (mode != 1 || addr40 != 0)
+			return -EINVAL;
+
+		value = nfp_mask64(29, 24);
+		*addr &= ~value;
+		*addr |= (((uint64_t)dest_island) << 24) & value;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int
+nfp_target_cpp(uint32_t cpp_island_id,
+		uint64_t cpp_island_address,
+		uint32_t *cpp_target_id,
+		uint64_t *cpp_target_address,
+		const uint32_t *imb_table)
+{
+	int err;
+	uint32_t imb;
+	uint8_t island;
+	uint8_t target;
+
+	target = NFP_CPP_ID_TARGET_of(cpp_island_id);
+	if (target >= 16)
+		return -EINVAL;
+
+	island = NFP_CPP_ID_ISLAND_of(cpp_island_id);
+	if (island == 0) {
+		/* Already translated */
+		*cpp_target_id = cpp_island_id;
+		*cpp_target_address = cpp_island_address;
+		return 0;
+	}
+
+	/* CPP + Island only allowed on systems with IMB tables */
+	if (imb_table == NULL)
+		return -EINVAL;
+
+	imb = imb_table[target];
+
+	*cpp_target_address = cpp_island_address;
+	err = nfp_cppat_addr_encode(cpp_target_address, island, target,
+			((imb >> 13) & 7), ((imb >> 12) & 1),
+			((imb >> 6) & 0x3f), ((imb >> 0) & 0x3f));
+	if (err != 0)
+		return err;
+
+	*cpp_target_id = NFP_CPP_ID(target,
+			NFP_CPP_ID_ACTION_of(cpp_island_id),
+			NFP_CPP_ID_TOKEN_of(cpp_island_id));
+
+	return 0;
+}
diff --git a/drivers/net/nfp/nfpcore/nfp_target.h b/drivers/net/nfp/nfpcore/nfp_target.h
index d1e5a50b14..24417fb315 100644
--- a/drivers/net/nfp/nfpcore/nfp_target.h
+++ b/drivers/net/nfp/nfpcore/nfp_target.h
@@ -7,7 +7,6 @@
 #define NFP_TARGET_H
 
 #include "nfp-common/nfp_resid.h"
-#include "nfp-common/nfp_cppat.h"
 #include "nfp-common/nfp_platform.h"
 #include "nfp_cpp.h"
 
-- 
2.39.1


  parent reply	other threads:[~2023-04-10 11:01 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-10 11:00 [PATCH 00/13] Sync the kernel driver logic Chaoyong He
2023-04-10 11:00 ` [PATCH 01/13] net/nfp: define correct size for configuration BAR Chaoyong He
2023-04-10 11:00 ` Chaoyong He [this message]
2023-04-10 11:00 ` [PATCH 03/13] net/nfp: remove the redundant macro about CPP target Chaoyong He
2023-04-10 11:00 ` [PATCH 04/13] net/nfp: drop usage of return error helpers Chaoyong He
2023-04-10 11:00 ` [PATCH 05/13] net/nfp: use generic macros for array size and to set bits Chaoyong He
2023-04-10 11:00 ` [PATCH 06/13] net/nfp: remove dead code related to CPP Chaoyong He
2023-04-10 11:00 ` [PATCH 07/13] net/nfp: remove duplicated nffw defines Chaoyong He
2023-04-10 11:00 ` [PATCH 08/13] net/nfp: move NFD3 logic to own source file Chaoyong He
2023-04-10 11:00 ` [PATCH 09/13] net/nfp: adjust the coding style for NFD3 Chaoyong He
2023-04-10 11:00 ` [PATCH 10/13] net/nfp: rename macro name of NFD3 Tx descriptor Chaoyong He
2023-04-10 11:00 ` [PATCH 11/13] net/nfp: move NFDk logic to own source file Chaoyong He
2023-04-10 11:00 ` [PATCH 12/13] net/nfp: adjust the coding style for NFDk Chaoyong He
2023-04-10 11:00 ` [PATCH 13/13] net/nfp: modify the logic of some NFDk function Chaoyong He
2023-05-11 14:47 ` [PATCH 00/13] Sync the kernel driver logic Niklas Söderlund
2023-05-12 14:37 ` Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230410110015.2973660-3-chaoyong.he@corigine.com \
    --to=chaoyong.he@corigine.com \
    --cc=dev@dpdk.org \
    --cc=niklas.soderlund@corigine.com \
    --cc=oss-drivers@corigine.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).