[PATCH 01/52] mips: octeon: Add misc cvmx-* header files

Stefan Roese sr at denx.de
Wed Mar 30 12:06:37 CEST 2022


From: Aaron Williams <awilliams at marvell.com>

Import misc cvmx-helper header files from 2013 U-Boot. They will be used
by the later added drivers to support networking on the MIPS Octeon II /
III platforms.

Signed-off-by: Aaron Williams <awilliams at marvell.com>
Signed-off-by: Stefan Roese <sr at denx.de>
---
 arch/mips/mach-octeon/include/mach/cvmx-agl.h |   45 +
 .../mach-octeon/include/mach/cvmx-config.h    |  128 ++
 arch/mips/mach-octeon/include/mach/cvmx-fau.h |  581 +++++++++
 .../mips/mach-octeon/include/mach/cvmx-mdio.h |  516 ++++++++
 .../include/mach/cvmx-pki-cluster.h           |  343 ++++++
 arch/mips/mach-octeon/include/mach/cvmx-pko.h |  213 ++++
 .../include/mach/cvmx-pko3-resources.h        |   36 +
 .../mips/mach-octeon/include/mach/cvmx-pko3.h | 1052 +++++++++++++++++
 .../mach-octeon/include/mach/cvmx-range.h     |   23 +
 9 files changed, 2937 insertions(+)
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-agl.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-config.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-fau.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-mdio.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-pki-cluster.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-pko.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-pko3-resources.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-pko3.h
 create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-range.h

diff --git a/arch/mips/mach-octeon/include/mach/cvmx-agl.h b/arch/mips/mach-octeon/include/mach/cvmx-agl.h
new file mode 100644
index 000000000000..4afb3a48bfdc
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-agl.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ *
+ * Functions for AGL (RGMII) commong initialization, configuration.
+ */
+
+#ifndef __CVMX_AGL_H__
+#define __CVMX_AGL_H__
+
+/*
+ * @param port to enable
+ *
+ * @return Zero on success, negative on failure
+ */
+int cvmx_agl_enable(int port);
+
+cvmx_helper_link_info_t cvmx_agl_link_get(int port);
+
+/*
+ * Set MII/RGMII link based on mode.
+ *
+ * @param port   interface port to set the link.
+ * @param link_info  Link status
+ *
+ * @return       0 on success and 1 on failure
+ */
+int cvmx_agl_link_set(int port, cvmx_helper_link_info_t link_info);
+
+/**
+ * Disables the sending of flow control (pause) frames on the specified
+ * AGL (RGMII) port(s).
+ *
+ * @param interface Which interface (0 or 1)
+ * @param port_mask Mask (4bits) of which ports on the interface to disable
+ *                  backpressure on.
+ *                  1 => disable backpressure
+ *                  0 => enable backpressure
+ *
+ * @return 0 on success
+ *         -1 on error
+ */
+int cvmx_agl_set_backpressure_override(u32 interface, uint32_t port_mask);
+
+#endif /* __CVMX_AGL_H__ */
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-config.h b/arch/mips/mach-octeon/include/mach/cvmx-config.h
new file mode 100644
index 000000000000..4f66a3cce524
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-config.h
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ */
+
+#ifndef __CVMX_CONFIG_H__
+#define __CVMX_CONFIG_H__
+
+/************************* Config Specific Defines ************************/
+#define CVMX_LLM_NUM_PORTS 1
+
+/**< PKO queues per port for interface 0 (ports 0-15) */
+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 1
+
+/**< PKO queues per port for interface 1 (ports 16-31) */
+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 1
+
+/**< PKO queues per port for interface 4 (AGL) */
+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE4 1
+
+/**< Limit on the number of PKO ports enabled for interface 0 */
+#define CVMX_PKO_MAX_PORTS_INTERFACE0 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
+
+/**< Limit on the number of PKO ports enabled for interface 1 */
+#define CVMX_PKO_MAX_PORTS_INTERFACE1 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
+
+/**< PKO queues per port for PCI (ports 32-35) */
+#define CVMX_PKO_QUEUES_PER_PORT_PCI 1
+
+/**< PKO queues per port for Loop devices (ports 36-39) */
+#define CVMX_PKO_QUEUES_PER_PORT_LOOP 1
+
+/**< PKO queues per port for SRIO0 devices (ports 40-41) */
+#define CVMX_PKO_QUEUES_PER_PORT_SRIO0 1
+
+/**< PKO queues per port for SRIO1 devices (ports 42-43) */
+#define CVMX_PKO_QUEUES_PER_PORT_SRIO1 1
+
+/************************* FPA allocation *********************************/
+/* Pool sizes in bytes, must be multiple of a cache line */
+#define CVMX_FPA_POOL_0_SIZE (16 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_1_SIZE (1 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_2_SIZE (8 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_3_SIZE (2 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_4_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_5_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_6_SIZE (8 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_7_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+
+/* Pools in use */
+/**< Packet buffers */
+#define CVMX_FPA_PACKET_POOL (0)
+#ifndef CVMX_FPA_PACKET_POOL_SIZE
+#define CVMX_FPA_PACKET_POOL_SIZE CVMX_FPA_POOL_0_SIZE
+#endif
+
+/**< Work queue entries */
+#define CVMX_FPA_WQE_POOL      (1)
+#define CVMX_FPA_WQE_POOL_SIZE CVMX_FPA_POOL_1_SIZE
+
+/**< PKO queue command buffers */
+#define CVMX_FPA_OUTPUT_BUFFER_POOL	 (2)
+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE CVMX_FPA_POOL_2_SIZE
+
+/**< BCH queue command buffers */
+#define CVMX_FPA_BCH_POOL      (6)
+#define CVMX_FPA_BCH_POOL_SIZE CVMX_FPA_POOL6_SIZE
+
+/*************************  FAU allocation ********************************/
+/* The fetch and add registers are allocated here.  They are arranged
+ * in order of descending size so that all alignment constraints are
+ * automatically met.
+ * The enums are linked so that the following enum continues allocating
+ * where the previous one left off, so the numbering within each
+ * enum always starts with zero.  The macros take care of the address
+ * increment size, so the values entered always increase by 1.
+ * FAU registers are accessed with byte addresses.
+ */
+
+#define CVMX_FAU_REG_64_ADDR(x) (((x) << 3) + CVMX_FAU_REG_64_START)
+typedef enum {
+	CVMX_FAU_REG_64_START = 0,
+	/**< FAU registers for the position in PKO command buffers */
+	CVMX_FAU_REG_OQ_ADDR_INDEX = CVMX_FAU_REG_64_ADDR(0),
+	/* Array of 36 */
+	CVMX_FAU_REG_64_END = CVMX_FAU_REG_64_ADDR(36),
+} cvmx_fau_reg_64_t;
+
+#define CVMX_FAU_REG_32_ADDR(x) (((x) << 2) + CVMX_FAU_REG_32_START)
+typedef enum {
+	CVMX_FAU_REG_32_START = CVMX_FAU_REG_64_END,
+	CVMX_FAU_REG_32_END = CVMX_FAU_REG_32_ADDR(0),
+} cvmx_fau_reg_32_t;
+
+#define CVMX_FAU_REG_16_ADDR(x) (((x) << 1) + CVMX_FAU_REG_16_START)
+typedef enum {
+	CVMX_FAU_REG_16_START = CVMX_FAU_REG_32_END,
+	CVMX_FAU_REG_16_END = CVMX_FAU_REG_16_ADDR(0),
+} cvmx_fau_reg_16_t;
+
+#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START)
+typedef enum {
+	CVMX_FAU_REG_8_START = CVMX_FAU_REG_16_END,
+	CVMX_FAU_REG_8_END = CVMX_FAU_REG_8_ADDR(0),
+} cvmx_fau_reg_8_t;
+
+/* The name CVMX_FAU_REG_AVAIL_BASE is provided to indicate the first available
+ * FAU address that is not allocated in cvmx-config.h. This is 64 bit aligned.
+ */
+#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL))
+#define CVMX_FAU_REG_END	(2048)
+
+/********************** scratch memory allocation *************************/
+/* Scratchpad memory allocation.  Note that these are byte memory addresses.
+ * Some uses of scratchpad (IOBDMA for example) require the use of 8-byte
+ * aligned addresses, so proper alignment needs to be taken into account.
+ */
+
+/**< Pre allocation for PKO queue command buffers */
+#define CVMX_SCR_OQ_BUF_PRE_ALLOC (0)
+
+/**< Generic scratch iobdma area */
+#define CVMX_SCR_SCRATCH (8)
+
+/**< First location available after cvmx-config.h allocated region. */
+#define CVMX_SCR_REG_AVAIL_BASE (16)
+
+#endif /* __CVMX_CONFIG_H__ */
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-fau.h b/arch/mips/mach-octeon/include/mach/cvmx-fau.h
new file mode 100644
index 000000000000..d795ff6e9b06
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-fau.h
@@ -0,0 +1,581 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ *
+ * Interface to the hardware Fetch and Add Unit.
+ */
+
+#ifndef __CVMX_FAU_H__
+#define __CVMX_FAU_H__
+
+extern u8 *cvmx_fau_regs_ptr;
+
+/**
+ * Initializes fau, on devices with FAU hw this is a noop.
+ */
+int cvmx_fau_init(void);
+
+/**
+ * Return the location of emulated FAU register
+ */
+static inline u8 *__cvmx_fau_sw_addr(int reg)
+{
+	if (cvmx_unlikely(!cvmx_fau_regs_ptr))
+		cvmx_fau_init();
+	return (cvmx_fau_regs_ptr + reg);
+}
+
+/**
+ * Perform an atomic 64 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @param value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * @return Value of the register before the update
+ */
+static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg64_t reg,
+					       int64_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_fetch_and_add64(reg, value);
+
+	return __atomic_fetch_add(CASTPTR(int64_t, __cvmx_fau_sw_addr(reg)),
+				  value, __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 32 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * @return Value of the register before the update
+ */
+static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg32_t reg,
+					       int32_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_fetch_and_add32(reg, value);
+
+	reg ^= SWIZZLE_32;
+	return __atomic_fetch_add(CASTPTR(int32_t, __cvmx_fau_sw_addr(reg)),
+				  value, __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 16 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @param value   Signed value to add.
+ * @return Value of the register before the update
+ */
+static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg16_t reg,
+					       int16_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_fetch_and_add16(reg, value);
+
+	reg ^= SWIZZLE_16;
+	return __atomic_fetch_add(CASTPTR(int16_t, __cvmx_fau_sw_addr(reg)),
+				  value, __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 8 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ * @param value   Signed value to add.
+ * @return Value of the register before the update
+ */
+static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg8_t reg, int8_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_fetch_and_add8(reg, value);
+
+	reg ^= SWIZZLE_8;
+	return __atomic_fetch_add(CASTPTR(int8_t, __cvmx_fau_sw_addr(reg)),
+				  value, __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 64 bit add after the current tag switch
+ * completes
+ *
+ * @param reg    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 8 for 64 bit access.
+ * @param value  Signed value to add.
+ *               Note: Only the low 22 bits are available.
+ * @return If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait64_t
+cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg64_t reg, int64_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_tagwait_fetch_and_add64(reg, value);
+
+	/* not implemented yet.*/
+	return (cvmx_fau_tagwait64_t){ 1, 0 };
+}
+
+/**
+ * Perform an atomic 32 bit add after the current tag switch
+ * completes
+ *
+ * @param reg    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 4 for 32 bit access.
+ * @param value  Signed value to add.
+ *               Note: Only the low 22 bits are available.
+ * @return If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait32_t
+cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg32_t reg, int32_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_tagwait_fetch_and_add32(reg, value);
+
+	/* not implemented yet.*/
+	return (cvmx_fau_tagwait32_t){ 1, 0 };
+}
+
+/**
+ * Perform an atomic 16 bit add after the current tag switch
+ * completes
+ *
+ * @param reg    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 2 for 16 bit access.
+ * @param value  Signed value to add.
+ * @return If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait16_t
+cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg16_t reg, int16_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_tagwait_fetch_and_add16(reg, value);
+
+	/* not implemented yet.*/
+	return (cvmx_fau_tagwait16_t){ 1, 0 };
+}
+
+/**
+ * Perform an atomic 8 bit add after the current tag switch
+ * completes
+ *
+ * @param reg    FAU atomic register to access. 0 <= reg < 2048.
+ * @param value  Signed value to add.
+ * @return If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait8_t
+cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg8_t reg, int8_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU))
+		return cvmx_hwfau_tagwait_fetch_and_add8(reg, value);
+
+	/* not implemented yet.*/
+	return (cvmx_fau_tagwait8_t){ 1, 0 };
+}
+
+/**
+ * Perform an async atomic 64 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @param value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * @return Placed in the scratch pad register
+ */
+static inline void
+cvmx_fau_async_fetch_and_add64(u64 scraddr, cvmx_fau_reg64_t reg, int64_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_fetch_and_add64(scraddr, reg, value);
+		return;
+	}
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int64_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 32 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * @return Placed in the scratch pad register
+ */
+static inline void
+cvmx_fau_async_fetch_and_add32(u64 scraddr, cvmx_fau_reg32_t reg, int32_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_fetch_and_add32(scraddr, reg, value);
+		return;
+	}
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int32_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 16 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @param value   Signed value to add.
+ * @return Placed in the scratch pad register
+ */
+static inline void
+cvmx_fau_async_fetch_and_add16(u64 scraddr, cvmx_fau_reg16_t reg, int16_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_fetch_and_add16(scraddr, reg, value);
+		return;
+	}
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int16_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 8 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ * @param value   Signed value to add.
+ * @return Placed in the scratch pad register
+ */
+static inline void
+cvmx_fau_async_fetch_and_add8(u64 scraddr, cvmx_fau_reg8_t reg, int8_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_fetch_and_add8(scraddr, reg, value);
+		return;
+	}
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int8_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 64 bit add after the current tag
+ * switch completes.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ *                If a timeout occurs, the error bit (63) will be set. Otherwise
+ *                the value of the register before the update will be
+ *                returned
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @param value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * @return Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add64(u64 scraddr,
+							  cvmx_fau_reg64_t reg,
+							  int64_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_tagwait_fetch_and_add64(scraddr, reg, value);
+		return;
+	}
+
+	/* Broken.  Where is the tag wait? */
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int64_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 32 bit add after the current tag
+ * switch completes.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ *                If a timeout occurs, the error bit (63) will be set. Otherwise
+ *                the value of the register before the update will be
+ *                returned
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * @return Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add32(u64 scraddr,
+							  cvmx_fau_reg32_t reg,
+							  int32_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_tagwait_fetch_and_add32(scraddr, reg, value);
+		return;
+	}
+	/* Broken.  Where is the tag wait? */
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int32_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 16 bit add after the current tag
+ * switch completes.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ *                If a timeout occurs, the error bit (63) will be set. Otherwise
+ *                the value of the register before the update will be
+ *                returned
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @param value   Signed value to add.
+ * @return Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add16(u64 scraddr,
+							  cvmx_fau_reg16_t reg,
+							  int16_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_tagwait_fetch_and_add16(scraddr, reg, value);
+		return;
+	}
+	/* Broken.  Where is the tag wait? */
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int16_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an async atomic 8 bit add after the current tag
+ * switch completes.
+ *
+ * @param scraddr Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ *                If a timeout occurs, the error bit (63) will be set. Otherwise
+ *                the value of the register before the update will be
+ *                returned
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ * @param value   Signed value to add.
+ * @return Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add8(u64 scraddr,
+							 cvmx_fau_reg8_t reg,
+							 int8_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_async_tagwait_fetch_and_add8(scraddr, reg, value);
+		return;
+	}
+	/* Broken.  Where is the tag wait? */
+	cvmx_scratch_write64(
+		scraddr,
+		__atomic_fetch_add(CASTPTR(int8_t, __cvmx_fau_sw_addr(reg)),
+				   value, __ATOMIC_SEQ_CST));
+}
+
+/**
+ * Perform an atomic 64 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @param value   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add64(cvmx_fau_reg64_t reg, int64_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_add64(reg, value);
+		return;
+	}
+	/* Ignored fetch values should be optimized away */
+	__atomic_add_fetch(CASTPTR(int64_t, __cvmx_fau_sw_addr(reg)), value,
+			   __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 32 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add32(cvmx_fau_reg32_t reg, int32_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_add32(reg, value);
+		return;
+	}
+	reg ^= SWIZZLE_32;
+	/* Ignored fetch values should be optimized away */
+	__atomic_add_fetch(CASTPTR(int32_t, __cvmx_fau_sw_addr(reg)), value,
+			   __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 16 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @param value   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add16(cvmx_fau_reg16_t reg, int16_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_add16(reg, value);
+		return;
+	}
+	reg ^= SWIZZLE_16;
+	/* Ignored fetch values should be optimized away */
+	__atomic_add_fetch(CASTPTR(int16_t, __cvmx_fau_sw_addr(reg)), value,
+			   __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 8 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ * @param value   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add8(cvmx_fau_reg8_t reg, int8_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_add8(reg, value);
+		return;
+	}
+	reg ^= SWIZZLE_8;
+	/* Ignored fetch values should be optimized away */
+	__atomic_add_fetch(CASTPTR(int8_t, __cvmx_fau_sw_addr(reg)), value,
+			   __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 64 bit write
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @param value   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write64(cvmx_fau_reg64_t reg, int64_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_write64(reg, value);
+		return;
+	}
+	__atomic_store_n(CASTPTR(int64_t, __cvmx_fau_sw_addr(reg)), value,
+			 __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 32 bit write
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write32(cvmx_fau_reg32_t reg, int32_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_write32(reg, value);
+		return;
+	}
+	reg ^= SWIZZLE_32;
+	__atomic_store_n(CASTPTR(int32_t, __cvmx_fau_sw_addr(reg)), value,
+			 __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 16 bit write
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @param value   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write16(cvmx_fau_reg16_t reg, int16_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_write16(reg, value);
+		return;
+	}
+	reg ^= SWIZZLE_16;
+	__atomic_store_n(CASTPTR(int16_t, __cvmx_fau_sw_addr(reg)), value,
+			 __ATOMIC_SEQ_CST);
+}
+
+/**
+ * Perform an atomic 8 bit write
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 2048.
+ * @param value   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write8(cvmx_fau_reg8_t reg, int8_t value)
+{
+	if (octeon_has_feature(OCTEON_FEATURE_FAU)) {
+		cvmx_hwfau_atomic_write8(reg, value);
+		return;
+	}
+	reg ^= SWIZZLE_8;
+	__atomic_store_n(CASTPTR(int8_t, __cvmx_fau_sw_addr(reg)), value,
+			 __ATOMIC_SEQ_CST);
+}
+
+/** Allocates 64bit FAU register.
+ *  @param reserve base address to reserve
+ *  @return value is the base address of allocated FAU register
+ */
+int cvmx_fau64_alloc(int reserve);
+
+/** Allocates 32bit FAU register.
+ *  @param reserve base address to reserve
+ *  @return value is the base address of allocated FAU register
+ */
+int cvmx_fau32_alloc(int reserve);
+
+/** Allocates 16bit FAU register.
+ *  @param reserve base address to reserve
+ *  @return value is the base address of allocated FAU register
+ */
+int cvmx_fau16_alloc(int reserve);
+
+/** Allocates 8bit FAU register.
+ *  @param reserve base address to reserve
+ *  @return value is the base address of allocated FAU register
+ */
+int cvmx_fau8_alloc(int reserve);
+
+/** Frees the specified FAU register.
+ *  @param address base address of register to release.
+ *  @return 0 on success; -1 on failure
+ */
+int cvmx_fau_free(int address);
+
+/** Display the fau registers array
+ */
+void cvmx_fau_show(void);
+
+#endif /* __CVMX_FAU_H__ */
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-mdio.h b/arch/mips/mach-octeon/include/mach/cvmx-mdio.h
new file mode 100644
index 000000000000..9bc138fa2770
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-mdio.h
@@ -0,0 +1,516 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ *
+ * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
+ * clause 22 and clause 45 operations.
+ */
+
+#ifndef __CVMX_MIO_H__
+#define __CVMX_MIO_H__
+
+/**
+ * PHY register 0 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_CONTROL 0
+
+typedef union {
+	u16 u16;
+	struct {
+		u16 reset : 1;
+		u16 loopback : 1;
+		u16 speed_lsb : 1;
+		u16 autoneg_enable : 1;
+		u16 power_down : 1;
+		u16 isolate : 1;
+		u16 restart_autoneg : 1;
+		u16 duplex : 1;
+		u16 collision_test : 1;
+		u16 speed_msb : 1;
+		u16 unidirectional_enable : 1;
+		u16 reserved_0_4 : 5;
+	} s;
+} cvmx_mdio_phy_reg_control_t;
+
+/**
+ * PHY register 1 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_STATUS 1
+typedef union {
+	u16 u16;
+	struct {
+		u16 capable_100base_t4 : 1;
+		u16 capable_100base_x_full : 1;
+		u16 capable_100base_x_half : 1;
+		u16 capable_10_full : 1;
+		u16 capable_10_half : 1;
+		u16 capable_100base_t2_full : 1;
+		u16 capable_100base_t2_half : 1;
+		u16 capable_extended_status : 1;
+		u16 capable_unidirectional : 1;
+		u16 capable_mf_preamble_suppression : 1;
+		u16 autoneg_complete : 1;
+		u16 remote_fault : 1;
+		u16 capable_autoneg : 1;
+		u16 link_status : 1;
+		u16 jabber_detect : 1;
+		u16 capable_extended_registers : 1;
+
+	} s;
+} cvmx_mdio_phy_reg_status_t;
+
+/**
+ * PHY register 2 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_ID1 2
+typedef union {
+	u16 u16;
+	struct {
+		u16 oui_bits_3_18;
+	} s;
+} cvmx_mdio_phy_reg_id1_t;
+
+/**
+ * PHY register 3 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_ID2 3
+typedef union {
+	u16 u16;
+	struct {
+		u16 oui_bits_19_24 : 6;
+		u16 model : 6;
+		u16 revision : 4;
+	} s;
+} cvmx_mdio_phy_reg_id2_t;
+
+/**
+ * PHY register 4 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
+typedef union {
+	u16 u16;
+	struct {
+		u16 next_page : 1;
+		u16 reserved_14 : 1;
+		u16 remote_fault : 1;
+		u16 reserved_12 : 1;
+		u16 asymmetric_pause : 1;
+		u16 pause : 1;
+		u16 advert_100base_t4 : 1;
+		u16 advert_100base_tx_full : 1;
+		u16 advert_100base_tx_half : 1;
+		u16 advert_10base_tx_full : 1;
+		u16 advert_10base_tx_half : 1;
+		u16 selector : 5;
+	} s;
+} cvmx_mdio_phy_reg_autoneg_adver_t;
+
+/**
+ * PHY register 5 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
+typedef union {
+	u16 u16;
+	struct {
+		u16 next_page : 1;
+		u16 ack : 1;
+		u16 remote_fault : 1;
+		u16 reserved_12 : 1;
+		u16 asymmetric_pause : 1;
+		u16 pause : 1;
+		u16 advert_100base_t4 : 1;
+		u16 advert_100base_tx_full : 1;
+		u16 advert_100base_tx_half : 1;
+		u16 advert_10base_tx_full : 1;
+		u16 advert_10base_tx_half : 1;
+		u16 selector : 5;
+	} s;
+} cvmx_mdio_phy_reg_link_partner_ability_t;
+
+/**
+ * PHY register 6 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
+typedef union {
+	u16 u16;
+	struct {
+		u16 reserved_5_15 : 11;
+		u16 parallel_detection_fault : 1;
+		u16 link_partner_next_page_capable : 1;
+		u16 local_next_page_capable : 1;
+		u16 page_received : 1;
+		u16 link_partner_autoneg_capable : 1;
+
+	} s;
+} cvmx_mdio_phy_reg_autoneg_expansion_t;
+
+/**
+ * PHY register 9 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
+typedef union {
+	u16 u16;
+	struct {
+		u16 test_mode : 3;
+		u16 manual_master_slave : 1;
+		u16 master : 1;
+		u16 port_type : 1;
+		u16 advert_1000base_t_full : 1;
+		u16 advert_1000base_t_half : 1;
+		u16 reserved_0_7 : 8;
+	} s;
+} cvmx_mdio_phy_reg_control_1000_t;
+
+/**
+ * PHY register 10 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_STATUS_1000 10
+typedef union {
+	u16 u16;
+	struct {
+		u16 master_slave_fault : 1;
+		u16 is_master : 1;
+		u16 local_receiver_ok : 1;
+		u16 remote_receiver_ok : 1;
+		u16 remote_capable_1000base_t_full : 1;
+		u16 remote_capable_1000base_t_half : 1;
+		u16 reserved_8_9 : 2;
+		u16 idle_error_count : 8;
+	} s;
+} cvmx_mdio_phy_reg_status_1000_t;
+
+/**
+ * PHY register 15 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
+typedef union {
+	u16 u16;
+	struct {
+		u16 capable_1000base_x_full : 1;
+		u16 capable_1000base_x_half : 1;
+		u16 capable_1000base_t_full : 1;
+		u16 capable_1000base_t_half : 1;
+		u16 reserved_0_11 : 12;
+	} s;
+} cvmx_mdio_phy_reg_extended_status_t;
+
+/**
+ * PHY register 13 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
+typedef union {
+	u16 u16;
+	struct {
+		u16 function : 2;
+		u16 reserved_5_13 : 9;
+		u16 devad : 5;
+	} s;
+} cvmx_mdio_phy_reg_mmd_control_t;
+
+/**
+ * PHY register 14 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
+typedef union {
+	u16 u16;
+	struct {
+		u16 address_data : 16;
+	} s;
+} cvmx_mdio_phy_reg_mmd_address_data_t;
+
+/* Operating request encodings. */
+#define MDIO_CLAUSE_22_WRITE 0
+#define MDIO_CLAUSE_22_READ  1
+
+#define MDIO_CLAUSE_45_ADDRESS	0
+#define MDIO_CLAUSE_45_WRITE	1
+#define MDIO_CLAUSE_45_READ_INC 2
+#define MDIO_CLAUSE_45_READ	3
+
+/* MMD identifiers, mostly for accessing devices within XENPAK modules. */
+#define CVMX_MMD_DEVICE_PMA_PMD	 1
+#define CVMX_MMD_DEVICE_WIS	 2
+#define CVMX_MMD_DEVICE_PCS	 3
+#define CVMX_MMD_DEVICE_PHY_XS	 4
+#define CVMX_MMD_DEVICE_DTS_XS	 5
+#define CVMX_MMD_DEVICE_TC	 6
+#define CVMX_MMD_DEVICE_CL22_EXT 29
+#define CVMX_MMD_DEVICE_VENDOR_1 30
+#define CVMX_MMD_DEVICE_VENDOR_2 31
+
+#define CVMX_MDIO_TIMEOUT 100000 /* 100 millisec */
+
+static inline int cvmx_mdio_bus_id_to_node(int bus_id)
+{
+	if (OCTEON_IS_MODEL(OCTEON_CN78XX))
+		return (bus_id >> 2) & CVMX_NODE_MASK;
+	else
+		return 0;
+}
+
+static inline int cvmx_mdio_bus_id_to_bus(int bus_id)
+{
+	if (OCTEON_IS_MODEL(OCTEON_CN78XX))
+		return bus_id & 3;
+	else
+		return bus_id;
+}
+
+/* Helper function to put MDIO interface into clause 45 mode */
+static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
+{
+	cvmx_smix_clk_t smi_clk;
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+
+	/* Put bus into clause 45 mode */
+	smi_clk.u64 = csr_rd_node(node, CVMX_SMIX_CLK(bus));
+	smi_clk.s.mode = 1;
+	smi_clk.s.preamble = 1;
+	csr_wr_node(node, CVMX_SMIX_CLK(bus), smi_clk.u64);
+}
+
+/* Helper function to put MDIO interface into clause 22 mode */
+static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
+{
+	cvmx_smix_clk_t smi_clk;
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+
+	/* Put bus into clause 22 mode */
+	smi_clk.u64 = csr_rd_node(node, CVMX_SMIX_CLK(bus));
+	smi_clk.s.mode = 0;
+	csr_wr_node(node, CVMX_SMIX_CLK(bus), smi_clk.u64);
+}
+
+/**
+ * @INTERNAL
+ * Function to read SMIX_RD_DAT and check for timeouts. This
+ * code sequence is done fairly often, so put in one spot.
+ *
+ * @param bus_id SMI/MDIO bus to read
+ *
+ * @return Value of SMIX_RD_DAT. pending will be set on
+ *         a timeout.
+ */
+static inline cvmx_smix_rd_dat_t __cvmx_mdio_read_rd_dat(int bus_id)
+{
+	cvmx_smix_rd_dat_t smi_rd;
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+	u64 done;
+
+	done = get_timer(0);
+
+	do {
+		mdelay(1);
+		smi_rd.u64 = csr_rd_node(node, CVMX_SMIX_RD_DAT(bus));
+		if (get_timer(done) > (CVMX_MDIO_TIMEOUT / 1000))
+			break;
+	} while (smi_rd.s.pending);
+
+	return smi_rd;
+}
+
+/**
+ * Perform an MII read. This function is used to read PHY
+ * registers controlling auto negotiation.
+ *
+ * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @param phy_id   The MII phy id
+ * @param location Register location to read
+ *
+ * @return Result from the read or -1 on failure
+ */
+static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
+{
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+	cvmx_smix_cmd_t smi_cmd;
+	cvmx_smix_rd_dat_t smi_rd;
+
+	if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		__cvmx_mdio_set_clause22_mode(bus_id);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = location;
+	csr_wr_node(node, CVMX_SMIX_CMD(bus), smi_cmd.u64);
+
+	smi_rd = __cvmx_mdio_read_rd_dat(bus_id);
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+	else
+		return -1;
+}
+
+/**
+ * Perform an MII write. This function is used to write PHY
+ * registers controlling auto negotiation.
+ *
+ * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @param phy_id   The MII phy id
+ * @param location Register location to write
+ * @param val      Value to write
+ *
+ * @return -1 on error
+ *         0 on success
+ */
+static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
+{
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+	cvmx_smix_cmd_t smi_cmd;
+	cvmx_smix_wr_dat_t smi_wr;
+
+	if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		__cvmx_mdio_set_clause22_mode(bus_id);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	csr_wr_node(node, CVMX_SMIX_WR_DAT(bus), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = location;
+	csr_wr_node(node, CVMX_SMIX_CMD(bus), smi_cmd.u64);
+
+	if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_SMIX_WR_DAT(bus),
+				       cvmx_smix_wr_dat_t, pending, ==, 0,
+				       CVMX_MDIO_TIMEOUT))
+		return -1;
+
+	return 0;
+}
+
+/**
+ * Perform an IEEE 802.3 clause 45 MII read. This function is used to read PHY
+ * registers controlling auto negotiation.
+ *
+ * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @param phy_id   The MII phy id
+ * @param device   MDIO Manageable Device (MMD) id
+ * @param location Register location to read
+ *
+ * @return Result from the read or -1 on failure
+ */
+
+static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
+				    int location)
+{
+	cvmx_smix_cmd_t smi_cmd;
+	cvmx_smix_rd_dat_t smi_rd;
+	cvmx_smix_wr_dat_t smi_wr;
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+
+	if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		return -1;
+
+	__cvmx_mdio_set_clause45_mode(bus_id);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = location;
+	csr_wr_node(node, CVMX_SMIX_WR_DAT(bus), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	csr_wr_node(node, CVMX_SMIX_CMD(bus), smi_cmd.u64);
+
+	if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_SMIX_WR_DAT(bus),
+				       cvmx_smix_wr_dat_t, pending, ==, 0,
+				       CVMX_MDIO_TIMEOUT)) {
+		debug("cvmx_mdio_45_read: bus_id %d phy_id %2d device %2d register %2d   TIME OUT(address)\n",
+		      bus_id, phy_id, device, location);
+		return -1;
+	}
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	csr_wr_node(node, CVMX_SMIX_CMD(bus), smi_cmd.u64);
+
+	smi_rd = __cvmx_mdio_read_rd_dat(bus_id);
+	if (smi_rd.s.pending) {
+		debug("cvmx_mdio_45_read: bus_id %d phy_id %2d device %2d register %2d   TIME OUT(data)\n",
+		      bus_id, phy_id, device, location);
+		return -1;
+	}
+
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+
+	debug("cvmx_mdio_45_read: bus_id %d phy_id %2d device %2d register %2d   INVALID READ\n",
+	      bus_id, phy_id, device, location);
+	return -1;
+}
+
+/**
+ * Perform an IEEE 802.3 clause 45 MII write. This function is used to write PHY
+ * registers controlling auto negotiation.
+ *
+ * @param bus_id   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @param phy_id   The MII phy id
+ * @param device   MDIO Manageable Device (MMD) id
+ * @param location Register location to write
+ * @param val      Value to write
+ *
+ * @return -1 on error
+ *         0 on success
+ */
+static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
+				     int location, int val)
+{
+	cvmx_smix_cmd_t smi_cmd;
+	cvmx_smix_wr_dat_t smi_wr;
+	int node = cvmx_mdio_bus_id_to_node(bus_id);
+	int bus = cvmx_mdio_bus_id_to_bus(bus_id);
+
+	if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		return -1;
+
+	__cvmx_mdio_set_clause45_mode(bus_id);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = location;
+	csr_wr_node(node, CVMX_SMIX_WR_DAT(bus), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	csr_wr_node(node, CVMX_SMIX_CMD(bus), smi_cmd.u64);
+
+	if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_SMIX_WR_DAT(bus),
+				       cvmx_smix_wr_dat_t, pending, ==, 0,
+				       CVMX_MDIO_TIMEOUT))
+		return -1;
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	csr_wr_node(node, CVMX_SMIX_WR_DAT(bus), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	csr_wr_node(node, CVMX_SMIX_CMD(bus), smi_cmd.u64);
+
+	if (CVMX_WAIT_FOR_FIELD64_NODE(node, CVMX_SMIX_WR_DAT(bus),
+				       cvmx_smix_wr_dat_t, pending, ==, 0,
+				       CVMX_MDIO_TIMEOUT))
+		return -1;
+
+	return 0;
+}
+
+#endif
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-pki-cluster.h b/arch/mips/mach-octeon/include/mach/cvmx-pki-cluster.h
new file mode 100644
index 000000000000..4d5a9d4ec829
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-pki-cluster.h
@@ -0,0 +1,343 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ */
+
+/* L4_PORT_CHECK_DISABLE_LF tag */
+/* This file is autogenerated from ipemainc.elf */
+const int cvmx_pki_cluster_code_length = 997;
+const u64 cvmx_pki_cluster_code_default[] = {
+	0x000000000a000000ull, 0x0000413a68024070ull, 0x0000813800200020ull,
+	0x900081b800200020ull, 0x0004da00ffff0001ull, 0x000455ab68010b0eull,
+	0x00045fba46010000ull, 0x9046898120002000ull, 0x0004418068010028ull,
+	0x90665300680100f0ull, 0x0004413f68004070ull, 0x00065380680100f0ull,
+	0x00045a346803a0f0ull, 0x000401b448000001ull, 0x00045cb968030870ull,
+	0x0007debd00100010ull, 0x0000813b80008000ull, 0x000441bb68004070ull,
+	0xd001c00000000000ull, 0xd021c00000000000ull, 0x00045f80680100f0ull,
+	0x0004c639ff000200ull, 0x0004403f72010000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x000041ba68034078ull, 0x0000512268030870ull,
+	0x000041bc68034070ull, 0x00005d3a68030870ull, 0x00045cb942080000ull,
+	0x0004552a4e09312dull, 0x00045cb968082868ull, 0x0004410246090000ull,
+	0x0000813800800080ull, 0x000401a486000005ull, 0x000615ab74000123ull,
+	0x0007122448000004ull, 0x0000813901000000ull, 0x000481b800010001ull,
+	0x000685b800020002ull, 0xa006823800010001ull, 0x0006c639ff000400ull,
+	0x00085f3e68010a00ull, 0xa0885f3e68010f01ull, 0x00085f3e68010405ull,
+	0x00085f3e68010906ull, 0xa0485f3e68010e07ull, 0xa061c00000000000ull,
+	0xa4085f3e68010b28ull, 0xa421c00000000000ull, 0x00095f3e68010940ull,
+	0xa066403e72010000ull, 0x000941be68034039ull, 0x00085f3e68010305ull,
+	0xa4685f3e68010028ull, 0x00095f3e68030030ull, 0x00095f3e68010416ull,
+	0x0001c00000000000ull, 0x00065cb942080000ull, 0xa046552a4e09312dull,
+	0xa446c639ff000500ull, 0x0006debd00010001ull, 0x0006403e72010001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x00065cb942080000ull, 0x0006552a4e09312dull,
+	0x00065cb968082868ull, 0x0006410246090000ull, 0x9060813901000000ull,
+	0x0004c639ff000800ull, 0x0004400072010000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x00045cb942080000ull,
+	0x9084552a4e09312dull, 0x90a4c639ff000900ull, 0x00045f80680100f0ull,
+	0x0004403f72010001ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x00045cb942080000ull, 0x9004552a4e09312dull,
+	0x0004c639ff000a00ull, 0x0004400072010000ull, 0x00048181ff00ff00ull,
+	0x0007820101000100ull, 0x0006898100ff00ffull, 0x00048301ffff0180ull,
+	0x0008d5ab10001000ull, 0x0004d4a900010001ull, 0x0001c00000000000ull,
+	0x00045cb942080000ull, 0x9024552a4e09312dull, 0x0004c639ff000b00ull,
+	0x90445f80680100f0ull, 0x000459b368020070ull, 0x000401024000000cull,
+	0x0006823fffffffffull, 0x00088281ffffffffull, 0x000ad5ab20002000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0004403f72010001ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x000c8b3fffffc200ull, 0x000c8b01ffff0001ull,
+	0x000ddebd00020002ull, 0x00045cb942080000ull, 0x0004552a4e09312dull,
+	0x00045cb968082868ull, 0x0004410246090000ull, 0x0000813901000000ull,
+	0x000481b800080008ull, 0x9846c639ff001200ull, 0x9861c00000000000ull,
+	0x00064180680100f0ull, 0x0006400372010000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x000683891f000200ull,
+	0x000ed52a00800080ull, 0x000e5e3c68020070ull, 0x00065cb942080000ull,
+	0x0006552a4e09312dull, 0x00065cb968082868ull, 0x0006410246090000ull,
+	0x0000813d00020002ull, 0x0004893901000000ull, 0x9004893800040004ull,
+	0x9024c639ff001300ull, 0x00044180680100f0ull, 0x9044400372010001ull,
+	0x0001c00000000000ull, 0x00045f3e68010044ull, 0x0004debd00040004ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x000483891f000200ull, 0x000ed52a00800080ull, 0x000e5e3c68020070ull,
+	0x00045cb942080000ull, 0x0004552a4e09312dull, 0x00045cb968082868ull,
+	0x0004410246090000ull, 0x000581b902000000ull, 0x9826c639ff001800ull,
+	0x9801c00000000000ull, 0x00064180680100f0ull, 0x0006400172030000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x000682091f000200ull, 0x000883aa00800080ull, 0x000ed52a00400040ull,
+	0x000e5e3c68020870ull, 0x000fd52a00800080ull, 0x000f5e3c68020070ull,
+	0x000983891f000000ull, 0x000f54a968090148ull, 0x000f59b368020870ull,
+	0x00065cb942080000ull, 0x0006552a4e09312dull, 0x00065cb968082868ull,
+	0x0006410246090000ull, 0x000081b902000000ull, 0x9826c639ff001900ull,
+	0x9801c00000000000ull, 0x00064180680100f0ull, 0x0006400172030001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x000682091f000200ull, 0x000883aa00800080ull, 0x000ed52a00400040ull,
+	0x000e5e3c68020870ull, 0x000fd52a00800080ull, 0x000f5e3c68020070ull,
+	0x000983891f000000ull, 0x000f54a968090148ull, 0x000f59b368020870ull,
+	0x00065cb942080000ull, 0x0006552a4e09312dull, 0x00065cb968082868ull,
+	0x0006410246090000ull, 0x000081b902000000ull, 0x9826c639ff001a00ull,
+	0x9801c00000000000ull, 0x00064180680100f0ull, 0x0006400172030000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x000682091f000200ull, 0x000883aa00800080ull, 0x000ed52a00400040ull,
+	0x000e5e3c68020870ull, 0x000fd52a00800080ull, 0x000f5e3c68020070ull,
+	0x000983891f000000ull, 0x000f54a968090148ull, 0x000f59b368020870ull,
+	0x00065cb942080000ull, 0x0006552a4e09312dull, 0x00065cb968082868ull,
+	0x0006410246090000ull, 0x000081b902000000ull, 0x9826c639ff001b00ull,
+	0x9801c00000000000ull, 0x00064180680100f0ull, 0x0006400172030001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x000682091f000200ull, 0x000883aa00800080ull, 0x000ed52a00400040ull,
+	0x000e5e3c68020870ull, 0x000fd52a00800080ull, 0x000f5e3c68020070ull,
+	0x000983891f000000ull, 0x000f54a968090148ull, 0x000f59b368020870ull,
+	0x00065cb942080000ull, 0x0006552a4e09312dull, 0x00065cb968082868ull,
+	0x0006410246090000ull, 0x9000813902000000ull, 0x000481b800400040ull,
+	0x00068981ffff8847ull, 0x00068581ffff8848ull, 0x0006debd00080008ull,
+	0x0006c639ff001e00ull, 0x0006010240000002ull, 0x9801c00000000000ull,
+	0x9821c00000000000ull, 0x00065f80680100f0ull, 0x0006403f72010000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x00065cb942080000ull, 0x0006552a4e09312dull, 0x00065cb968082868ull,
+	0x0006010240000004ull, 0x0006823902000000ull, 0x00065f3e68010629ull,
+	0xac28828101000100ull, 0x000b010240000004ull, 0xa42b820101000100ull,
+	0x0009010240000004ull, 0xac29828101000100ull, 0x000b010240000004ull,
+	0xa42b820101000100ull, 0x0009010240000004ull, 0xac29828101000100ull,
+	0x000b010240000004ull, 0x0006823904000000ull, 0x0008d4a907c00200ull,
+	0x0008593268020070ull, 0x0008dcb902000200ull, 0x9000813902000000ull,
+	0x0001c00000000000ull, 0x00040181840005ffull, 0x0006010240000008ull,
+	0x9801c00000000000ull, 0x0006debd00200020ull, 0x00048181ffff0806ull,
+	0x0006d4a907c00180ull, 0x00048201ffff8035ull, 0x00068581ffff8035ull,
+	0x0008d4a907c001c0ull, 0x0006dcb97c007c00ull, 0x00048201ffff0800ull,
+	0x00088601ffff86ddull, 0x00068581ffff0800ull, 0x00068581ffff86ddull,
+	0x0008d4a907c00200ull, 0x0009dcb97c007c00ull, 0x0007823d00200020ull,
+	0x000685bd00200020ull, 0x0008d4a907c00140ull, 0x0004010240000002ull,
+	0x0006593268020070ull, 0x000042a486020000ull, 0x000a15ab74000124ull,
+	0x9000813904000000ull, 0x0001c00000000000ull, 0x00048181f0004000ull,
+	0x9886593268020070ull, 0x0006d4a907c00200ull, 0x00068201ff000000ull,
+	0xa40815ab74000345ull, 0x0009debd01000100ull, 0xa429418068010038ull,
+	0x00095a3468010870ull, 0x0009028386000005ull, 0x000a068186000014ull,
+	0xacca15ab74000343ull, 0xacebc639ff002200ull, 0x000b5f80680100f0ull,
+	0xac8b403f72010000ull, 0x000b8203000f0005ull, 0x000b5a3468010070ull,
+	0x0009d4a907c00240ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x000b5cb942080000ull, 0xad0b552a4e09312dull,
+	0xad2bc639ff002700ull, 0x000b5f80680100f0ull, 0xac6b403f72010001ull,
+	0x0001c00000000000ull, 0x000b82013fff0000ull, 0x0009d52a00010001ull,
+	0x0009d4a9f8006800ull, 0x0009593268020870ull, 0x0006418068030230ull,
+	0x000b5cb942080000ull, 0x000b552a4e09312dull, 0x0006410240030000ull,
+	0x9c01c00000000000ull, 0x0001c00000000000ull, 0x00078201f0006000ull,
+	0x0008593268020070ull, 0x0008d4a907c00280ull, 0xa069d4a907c00000ull,
+	0x00085a3468010874ull, 0x0008818100ff0000ull, 0x000615ab74000345ull,
+	0x00075a3468010078ull, 0x9c8741b9680040f0ull, 0x9ca7c603ff001f00ull,
+	0x00075f80680100f0ull, 0x0007403f72010001ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0007418342080000ull,
+	0x9cc7552a4e09312dull, 0x9ce7c603ff002000ull, 0x00075f80680100f0ull,
+	0x0007403f72010000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0007418342080000ull, 0x9d07552a4e09312dull,
+	0x9d27c603ff002100ull, 0x00075f80680100f0ull, 0x0007403f72010001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0007418342080000ull, 0x0007552a4e09312dull, 0x9d475c80680300f0ull,
+	0x9d67c639ff002200ull, 0x00075f80680100f0ull, 0x0007403f72010000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x00075cb942080000ull, 0x0007552a4e09312dull, 0x9d8741b9680040f0ull,
+	0x9da7c603ff002400ull, 0x00075f80680100f0ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0007403f72010000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0007418342080000ull, 0x9dc7552a4e09312dull,
+	0x9de7c603ff002500ull, 0x00075f80680100f0ull, 0x0007403f72010001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0007418342080000ull, 0x0007552a4e09312dull, 0x0007010240000020ull,
+	0x9c01c00000000000ull, 0x9c27c603ff002600ull, 0x00075f80680100f0ull,
+	0x0007403f72010000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0007418342080000ull, 0x0007552a4e09312dull,
+	0x9c475c80680300f0ull, 0x9c67c639ff002700ull, 0x00075f80680100f0ull,
+	0x0007403f72010001ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x00075cb942080000ull, 0x0007552a4e09312dull,
+	0x0007010240000008ull, 0xa80782b400ff0000ull, 0x000ad4a907c002c0ull,
+	0x000a5a3468010078ull, 0x000a410244010000ull, 0xa80782b400ff003cull,
+	0x000ad4a907c002c0ull, 0x000a5a3468010078ull, 0x000a410244010000ull,
+	0xa80782b400ff002bull, 0x000ad4a907c002c0ull, 0x000a5a3468010078ull,
+	0x000a410244010000ull, 0xa80782b400ff002cull, 0x000ad4a9ffc06ac0ull,
+	0x000a593268020870ull, 0x000ad52a00010001ull, 0x000a5a3468010078ull,
+	0x000a010240000008ull, 0x0007debd01000100ull, 0x000481bd01000100ull,
+	0x0006c639ff002300ull, 0x000641aa68034000ull, 0x000641a968034846ull,
+	0x0006403472030001ull, 0x0004822907000200ull, 0x000915ab74000341ull,
+	0x000082aa00010001ull, 0x000a86ab00ff0045ull, 0x000adcb978007800ull,
+	0x0000822907000200ull, 0x00088a3908000000ull, 0x00065cb942080000ull,
+	0x0006552a4e09312dull, 0x00065cb968082868ull, 0x0006410246090000ull,
+	0x000042a486020000ull, 0x000a15ab74000343ull, 0x000081b940004000ull,
+	0x000685a907c00000ull, 0x000782b807000100ull, 0x000a41b268004070ull,
+	0x000a410040030000ull, 0x000a41ba68004078ull, 0x000a410240030000ull,
+	0xa801c00000000000ull, 0xa821c00000000000ull, 0x000a4180680100f0ull,
+	0x000ac639ff003900ull, 0x000a400372010001ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x000a83891f000000ull,
+	0x000f542868090a48ull, 0x000f583068020070ull, 0x000a5cb942080000ull,
+	0x000a552a4e09312dull, 0x000a5cb968082868ull, 0x000a410246090000ull,
+	0x982881b400ff0011ull, 0x9881c00000000000ull, 0x00064180680100f0ull,
+	0x00068283ffff12b5ull, 0x000a8a8108000800ull, 0x000ad4a9f8009800ull,
+	0x00068303ffff17c1ull, 0x000c8b01c0000000ull, 0xb0ac5bb768010a58ull,
+	0x000cd4a9f800b800ull, 0x000c8281ffff6558ull, 0x000adbb701000100ull,
+	0x000c8281ffff86ddull, 0x000a8681ffff0800ull, 0x000adbb702000200ull,
+	0x000682a9c8009800ull, 0x000adebd02000200ull, 0x000a593268020870ull,
+	0x000a010240000008ull, 0x9c21c00000000000ull, 0x0007813400ff002full,
+	0x90048201ffff6558ull, 0x00098381ffff0800ull, 0x00088281b0002000ull,
+	0x000a593268020870ull, 0x000ad4a9f800a800ull, 0x000adebd02000200ull,
+	0x000e593268020870ull, 0x000ed4a9f800a000ull, 0x000e010240000004ull,
+	0x000e828180008000ull, 0x000a010240000004ull, 0x000e828120002000ull,
+	0x000a010240000004ull, 0x000e828110001000ull, 0x000a010240000004ull,
+	0x000082bd02000200ull, 0xa80ac639ff002800ull, 0xa861c00000000000ull,
+	0x000a418368010526ull, 0xa84a418368010878ull, 0x000a5bb768030078ull,
+	0x000a400172030000ull, 0x000a5b00680100f0ull, 0x000041b468034878ull,
+	0x00005fbf68030878ull, 0x00068229c8009800ull, 0x0008010248000008ull,
+	0xa001c00000000000ull, 0x000843a486020000ull, 0x00088101ffff0000ull,
+	0x000415ab74000464ull, 0x000e15ab74000461ull, 0x0008010240000008ull,
+	0x000c41b76800425aull, 0x000c410240030000ull, 0x000a010240000008ull,
+	0x000a5cb942080000ull, 0x000a552a4e09312dull, 0x000a5cb968082868ull,
+	0x000a410246090000ull, 0x0000422486020000ull, 0x000815ab74000461ull,
+	0x000081b940004000ull, 0x000685a9f8000000ull, 0x000782b807000200ull,
+	0x000a41b268004078ull, 0x000a410040030000ull, 0x000a41ba68004078ull,
+	0x000a410240030000ull, 0xa801c00000000000ull, 0xa821c00000000000ull,
+	0x000a4180680100f0ull, 0x000ac639ff003900ull, 0x000a400372010001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x000a83891f000000ull, 0x000f542868090a48ull, 0x000f583068020070ull,
+	0x000a5cb942080000ull, 0x000a552a4e09312dull, 0x000a5cb968082868ull,
+	0x000a410246090000ull, 0x000081a9f800b800ull, 0x000689b701000100ull,
+	0x000685a9f8009800ull, 0x000685a9f800a800ull, 0x00078229f800b800ull,
+	0x000601024000000cull, 0x9801c00000000000ull, 0x00088a3702000200ull,
+	0x00088629f800a000ull, 0x00068101ffff8100ull, 0x0004010240000004ull,
+	0x9801c00000000000ull, 0x0009dcb910001000ull, 0x00068101ffff86ddull,
+	0x00048501ffff0800ull, 0x0005dcb978003800ull, 0x0006010240000002ull,
+	0x000081a9f8000000ull, 0x9007813910000000ull, 0x0001c00000000000ull,
+	0x00048181f0004000ull, 0x988658b168020070ull, 0x0006d428001f0008ull,
+	0x00068201ff000000ull, 0xa40815ab74000545ull, 0x0009debd04000400ull,
+	0xa429418068010038ull, 0x00095a3468010870ull, 0x0009028386000005ull,
+	0xac8a068186000014ull, 0x000a15ab74000543ull, 0x000b5a3468010070ull,
+	0xac6b8303000f0005ull, 0x000dd428001f0009ull, 0x000b83013fff0000ull,
+	0x000dd42803e001a0ull, 0x000d58b168020870ull, 0x000ddcb960006000ull,
+	0x0006418068030230ull, 0x0006410240030000ull, 0x9c01c00000000000ull,
+	0x0001c00000000000ull, 0x00078201f0006000ull, 0x000858b168020070ull,
+	0xa068d428001f000aull, 0x00085a3468010874ull, 0x0008818100ff0000ull,
+	0x000615ab74000545ull, 0x00075a3468010078ull, 0x0007010240000028ull,
+	0xa80782b400ff0000ull, 0x000ad428001f000bull, 0x000a5a3468010078ull,
+	0x000a410244010000ull, 0xa80782b400ff003cull, 0x000ad428001f000bull,
+	0x000a5a3468010078ull, 0x000a410244010000ull, 0xa80782b400ff002bull,
+	0x000ad428001f000bull, 0x000a5a3468010078ull, 0x000a410244010000ull,
+	0xa80782b400ff002cull, 0x000ad42803ff01abull, 0x000adcb960006000ull,
+	0x000a58b168020870ull, 0x000a5a3468010078ull, 0x000a010240000008ull,
+	0x0007debd04000400ull, 0x000481bd04000400ull, 0x0006c639ff002b00ull,
+	0x0006832803e001a0ull, 0x000cc18300010001ull, 0x000dc18300010000ull,
+	0x000641a868034840ull, 0x0006403472030001ull, 0x00048228001c0008ull,
+	0x000915ab74000541ull, 0x000082ab00ff0045ull, 0x000adcb960006000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x00065cb942080000ull,
+	0x0006552a4e09312dull, 0x00065cb968082868ull, 0x0006410246090000ull,
+	0x000042a486020000ull, 0x000a15ab74000543ull, 0x000081b940004000ull,
+	0x000685a8001f0000ull, 0x000782b807000300ull, 0x000a41b168004070ull,
+	0x000a410040030000ull, 0x000a41ba68004078ull, 0x000a410240030000ull,
+	0xa801c00000000000ull, 0xa821c00000000000ull, 0x000a4180680100f0ull,
+	0x000ac639ff003900ull, 0x000a400372010001ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x000a83891f000000ull,
+	0x000f542868090a48ull, 0x000f583068020070ull, 0x000a5cb942080000ull,
+	0x000a552a4e09312dull, 0x000a5cb968082868ull, 0x000a410246090000ull,
+	0x00008329ff000200ull, 0x000c8728001c0008ull, 0x000c813920000000ull,
+	0x000481b400ff006cull, 0x0006d42803e001c0ull, 0x000658b168020870ull,
+	0xa047823400ff0033ull, 0x0008d42803e00180ull, 0xa0685f80680100f0ull,
+	0xa007823400ff0032ull, 0x0008d42803e00180ull, 0xa0285f80680100f0ull,
+	0x0007822803e00180ull, 0x0008c639ff002e00ull, 0x0008403f72010000ull,
+	0x000858b168020870ull, 0x00085abf680040f0ull, 0x00085d80680100f0ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x00085cb942080000ull, 0x0008552a4e09312dull, 0x00085cb968082868ull,
+	0x0008410246090000ull, 0x986981b400ff002full, 0x0006d42803e00280ull,
+	0x00065a80680100f0ull, 0x000658b168020870ull, 0x000481b400ff0084ull,
+	0x0006d42803e00240ull, 0x0004823400ff0011ull, 0x0008d42803e00220ull,
+	0x98c481b400ff0006ull, 0x0006d42803e00200ull, 0x00065ebd68010b31ull,
+	0x000641806801003cull, 0x0006028386000005ull, 0x000a15ab74000661ull,
+	0x0006418068030230ull, 0x0008c180ffff0008ull, 0x0008863400ff0006ull,
+	0x0008418240030000ull, 0x000842a486030000ull, 0x000a15ab74000661ull,
+	0x9008863400ff0084ull, 0x0004c639ff002f00ull, 0x0004400072010001ull,
+	0x000858b168020870ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x00085cb942080000ull, 0x9028552a4e09312dull,
+	0x0004c639ff003000ull, 0x0004403472010000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x000858b168020870ull, 0x0001c00000000000ull,
+	0x000081b940004000ull, 0x000685a803e00000ull, 0x00045cb942080000ull,
+	0x0004552a4e09312dull, 0x00045cb968082868ull, 0x0004410246090000ull,
+	0x000483891f000000ull, 0x000f542868090a48ull, 0x000f583068020070ull,
+	0x000042a486020000ull, 0x000a15ab74000661ull, 0x000782b807000400ull,
+	0x000a41b168004078ull, 0x000a410040030000ull, 0x000a41ba68004078ull,
+	0x000a410240030000ull, 0xa801c00000000000ull, 0xa821c00000000000ull,
+	0x000a4180680100f0ull, 0x000ac639ff003900ull, 0x000a400372010001ull,
+	0x0001c00000000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull, 0x000041bf68034878ull, 0x00005a3468030878ull,
+	0x000a83891f000000ull, 0x000f542868090a48ull, 0x000f583068020070ull,
+	0x000a5cb942080000ull, 0x000a552a4e09312dull, 0x000a5cb968082868ull,
+	0x000a410246090000ull, 0x00005fb968004250ull, 0x0000003f70000000ull,
+	0x000041b968034070ull, 0x0000512268030070ull, 0x0000813800200020ull,
+	0x0004413a68024070ull, 0x9001c00000000000ull, 0x000081b800200020ull,
+	0x9026898180008000ull, 0x0004890110001000ull, 0x000456ad680100a0ull,
+	0x0006898180008000ull, 0x000652a56801001dull, 0x000456ad68090b5bull,
+	0x00055680680900f0ull, 0x0005debd00400040ull, 0x00005600680800f0ull,
+	0x0000833d00200020ull, 0x000c872907c00000ull, 0x000dd62c20000000ull,
+	0x0000822902800280ull, 0x000841b268034070ull, 0x000982a8000a000aull,
+	0x000a41b168034070ull, 0x000b822907c00000ull, 0x0000003f70000800ull,
+	0x000941b268034070ull, 0x0000418048030000ull, 0x0000018340000008ull,
+	0x0009018348000004ull, 0x000050a168030c20ull, 0x000082aa00800080ull,
+	0x000850a168080c2bull, 0x0000820800010001ull, 0x000850a168000c20ull,
+	0x000752a56808001eull, 0x000a822a00400040ull, 0x00088a0900010001ull,
+	0x000841bc68034078ull, 0x000941bc68034070ull, 0x000a583068030870ull,
+	0x0000813d00400000ull, 0x0005c180ffff0000ull, 0x00058288001e0000ull,
+	0x000b8208001e0008ull, 0x00085d2168004030ull, 0x00098308001e0010ull,
+	0x00088608001e0010ull, 0x000c5d2168004070ull, 0x0008418068080025ull,
+	0x000841ba6803a0f0ull, 0x000856ad40030000ull, 0x0008c180ffff0000ull,
+	0x0005820807000500ull, 0x00088a3d00010001ull, 0x000841be68004050ull,
+	0x0005828807000300ull, 0x000a8abd00040004ull, 0x000a41be68004040ull,
+	0x0005820807000100ull, 0x00088a2a00800080ull, 0x0008413068004078ull,
+	0xa021c00000000000ull, 0x0005828807000200ull, 0x000841806801002dull,
+	0x000a8abd00080008ull, 0x000a41be68004026ull, 0x0005820807000400ull,
+	0x00088a2907000200ull, 0x000841b46800405aull, 0x000556ad40030000ull,
+	0x000081bd00100010ull, 0x0006c180ffff0000ull, 0x0006822a00800080ull,
+	0x00088a0900100010ull, 0x0008413c68024070ull, 0xa021c00000000000ull,
+	0x0006832907000200ull, 0x0008c181f0008000ull, 0x000841834c00ffffull,
+	0x0006822a00400040ull, 0x00088a0900200020ull, 0x0008413c68024078ull,
+	0xa021c00000000000ull, 0x000c8b0900400040ull, 0x0008dc01f0008000ull,
+	0x000841b84c03ffffull, 0x000c8b2a00010000ull, 0x000c41b44c0300ffull,
+	0x000682a9f800a800ull, 0x000a86a9f8009800ull, 0x000a8a8904000400ull,
+	0x000a41b64c03ffffull, 0x000a41b74c0300ffull, 0x0000828901000100ull,
+	0x000a822803e00180ull, 0x0008413168024078ull, 0x0008833400ff0033ull,
+	0x000c010240000004ull, 0xa001c00000000000ull, 0xa021c00000000000ull,
+	0x000841814c03ffffull, 0x000841814c03ffffull, 0x000a822803e00280ull,
+	0x000841b54c03ffffull, 0x000682287c005800ull, 0x00088a0902000200ull,
+	0x0008413068024070ull, 0xa001c00000000000ull, 0x0006830900020002ull,
+	0x00088281e0002000ull, 0xa84a868108000800ull, 0xa861c00000000000ull,
+	0x000a41814c03ffffull, 0x000a41814c03ffffull, 0x00065380680300f0ull,
+	0x000c5321680040b0ull, 0x000dd3260fff0fffull, 0x0006810900800080ull,
+	0x0000003f70000400ull, 0x000082a907000200ull, 0x000a413268024070ull,
+	0xa50a822902800280ull, 0x0004893d08000800ull, 0x00098301ffffffffull,
+	0xa4c98381f000e000ull, 0x00095f00680100f0ull, 0xa5295f3e64010000ull,
+	0x0001c00000000000ull, 0xa4ec8b01ffffffffull, 0x00095d00680100f0ull,
+	0xa1895d3a64010000ull, 0x000cd5ab80008000ull, 0x00088a01ff00ff00ull,
+	0x0008d5ab40004000ull, 0x000ed5ab40004000ull, 0x0004893d40000000ull,
+	0x00005700680800f0ull, 0x00005780680900f0ull, 0x00008229f800a000ull,
+	0x0008c180ffff0018ull, 0x000857af680320f0ull, 0x0007d72ef1ff0000ull,
+	0x0007d7aff0000000ull, 0x0004d72e00fc0000ull, 0x0000812c00020002ull,
+	0x0004892907c00200ull, 0x000441a7680040f0ull, 0x000441be4c03ffffull,
+	0x000441ba4c03ffffull, 0x000481a803c00200ull, 0x0006413168024078ull,
+	0x9801c00000000000ull, 0x9821c00000000000ull, 0x00065f80680100f0ull,
+	0x00065fbf64010000ull, 0x000641bf4c03ffffull, 0x000452a568030250ull,
+	0x0000000008000000ull, 0x0001c00000000000ull, 0x0001c00000000000ull,
+	0x0001c00000000000ull
+};
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-pko.h b/arch/mips/mach-octeon/include/mach/cvmx-pko.h
new file mode 100644
index 000000000000..26e7a9adf4b3
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-pko.h
@@ -0,0 +1,213 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ *
+ * Backward compatibility for packet transmission using legacy PKO command.
+ */
+
+#ifndef __CVMX_PKO_H__
+#define __CVMX_PKO_H__
+
+extern cvmx_pko_return_value_t
+cvmx_pko3_legacy_xmit(unsigned int dq, cvmx_pko_command_word0_t pko_command,
+		      cvmx_buf_ptr_t packet, uint64_t addr, bool tag_sw);
+
+/**
+ * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
+ * once before this, and the same parameters must be passed to both
+ * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish().
+ *
+ * WARNING: This function may have to look up the proper PKO port in
+ * the IPD port to PKO port map, and is thus slower than calling
+ * cvmx_pko_send_packet_finish_pkoid() directly if the PKO port
+ * identifier is known.
+ *
+ * @param ipd_port   The IPD port corresponding the to pko port the packet is for
+ * @param queue  Queue to use
+ * @param pko_command
+ *               PKO HW command word
+ * @param packet to send
+ * @param use_locking
+ *               CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
+ *               or CVMX_PKO_LOCK_CMD_QUEUE
+ *
+ * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
+ */
+static inline cvmx_pko_return_value_t
+cvmx_pko_send_packet_finish(u64 ipd_port, uint64_t queue,
+			    cvmx_pko_command_word0_t pko_command,
+			    cvmx_buf_ptr_t packet, cvmx_pko_lock_t use_locking)
+{
+	cvmx_cmd_queue_result_t result;
+
+	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
+		return cvmx_pko3_legacy_xmit(queue, pko_command, packet, 0,
+					     use_locking ==
+						     CVMX_PKO_LOCK_ATOMIC_TAG);
+	}
+
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
+		cvmx_pow_tag_sw_wait();
+
+	result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
+				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
+				       pko_command.u64, packet.u64);
+	if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
+		cvmx_pko_doorbell(ipd_port, queue, 2);
+		return CVMX_PKO_SUCCESS;
+	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
+		   (result == CVMX_CMD_QUEUE_FULL)) {
+		return CVMX_PKO_NO_MEMORY;
+	} else {
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+}
+
+/**
+ * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
+ * once before this, and the same parameters must be passed to both
+ * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish().
+ *
+ * WARNING: This function may have to look up the proper PKO port in
+ * the IPD port to PKO port map, and is thus slower than calling
+ * cvmx_pko_send_packet_finish3_pkoid() directly if the PKO port
+ * identifier is known.
+ *
+ * @param ipd_port   The IPD port corresponding the to pko port the packet is for
+ * @param queue  Queue to use
+ * @param pko_command
+ *               PKO HW command word
+ * @param packet to send
+ * @param addr   Physical address of a work queue entry or physical address to zero
+ *               on complete.
+ * @param use_locking
+ *               CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
+ *               or CVMX_PKO_LOCK_CMD_QUEUE
+ *
+ * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
+ */
+static inline cvmx_pko_return_value_t
+cvmx_pko_send_packet_finish3(u64 ipd_port, uint64_t queue,
+			     cvmx_pko_command_word0_t pko_command,
+			     cvmx_buf_ptr_t packet, uint64_t addr,
+			     cvmx_pko_lock_t use_locking)
+{
+	cvmx_cmd_queue_result_t result;
+
+	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
+		return cvmx_pko3_legacy_xmit(queue, pko_command, packet, addr,
+					     use_locking ==
+						     CVMX_PKO_LOCK_ATOMIC_TAG);
+	}
+
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
+		cvmx_pow_tag_sw_wait();
+
+	result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
+				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
+				       pko_command.u64, packet.u64, addr);
+	if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
+		cvmx_pko_doorbell(ipd_port, queue, 3);
+		return CVMX_PKO_SUCCESS;
+	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
+		   (result == CVMX_CMD_QUEUE_FULL)) {
+		return CVMX_PKO_NO_MEMORY;
+	} else {
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+}
+
+/**
+ * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
+ * once before this, and the same parameters must be passed to both
+ * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish_pkoid().
+ *
+ * @param pko_port   Port to send it on
+ * @param queue  Queue to use
+ * @param pko_command
+ *               PKO HW command word
+ * @param packet to send
+ * @param use_locking
+ *               CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
+ *               or CVMX_PKO_LOCK_CMD_QUEUE
+ *
+ * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
+ */
+static inline cvmx_pko_return_value_t
+cvmx_pko_send_packet_finish_pkoid(int pko_port, uint64_t queue,
+				  cvmx_pko_command_word0_t pko_command,
+				  cvmx_buf_ptr_t packet, cvmx_pko_lock_t use_locking)
+{
+	cvmx_cmd_queue_result_t result;
+
+	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
+		return cvmx_pko3_legacy_xmit(queue, pko_command, packet, 0,
+					     use_locking ==
+						     CVMX_PKO_LOCK_ATOMIC_TAG);
+	}
+
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
+		cvmx_pow_tag_sw_wait();
+	result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
+				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
+				       pko_command.u64, packet.u64);
+	if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
+		cvmx_pko_doorbell_pkoid(pko_port, queue, 2);
+		return CVMX_PKO_SUCCESS;
+	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
+		   (result == CVMX_CMD_QUEUE_FULL)) {
+		return CVMX_PKO_NO_MEMORY;
+	} else {
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+}
+
+/**
+ * Complete packet output. cvmx_pko_send_packet_prepare() must be called exactly
+ * once before this, and the same parameters must be passed to both
+ * cvmx_pko_send_packet_prepare() and cvmx_pko_send_packet_finish_pkoid().
+ *
+ * @param pko_port   The PKO port the packet is for
+ * @param queue  Queue to use
+ * @param pko_command
+ *               PKO HW command word
+ * @param packet to send
+ * @param addr   Plysical address of a work queue entry or physical address to zero
+ *               on complete.
+ * @param use_locking
+ *               CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG,
+ *               or CVMX_PKO_LOCK_CMD_QUEUE
+ *
+ * @return returns CVMX_PKO_SUCCESS on success, or error code on failure of output
+ */
+static inline cvmx_pko_return_value_t
+cvmx_pko_send_packet_finish3_pkoid(u64 pko_port, uint64_t queue,
+				   cvmx_pko_command_word0_t pko_command,
+				   cvmx_buf_ptr_t packet, uint64_t addr,
+				   cvmx_pko_lock_t use_locking)
+{
+	cvmx_cmd_queue_result_t result;
+
+	if (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {
+		return cvmx_pko3_legacy_xmit(queue, pko_command, packet, addr,
+					     use_locking ==
+						     CVMX_PKO_LOCK_ATOMIC_TAG);
+	}
+
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
+		cvmx_pow_tag_sw_wait();
+	result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
+				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
+				       pko_command.u64, packet.u64, addr);
+	if (cvmx_likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
+		cvmx_pko_doorbell_pkoid(pko_port, queue, 3);
+		return CVMX_PKO_SUCCESS;
+	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY) ||
+		   (result == CVMX_CMD_QUEUE_FULL)) {
+		return CVMX_PKO_NO_MEMORY;
+	} else {
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+}
+
+#endif /* __CVMX_PKO_H__ */
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-pko3-resources.h b/arch/mips/mach-octeon/include/mach/cvmx-pko3-resources.h
new file mode 100644
index 000000000000..cc9f37500b0e
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-pko3-resources.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ */
+
+#ifndef __CVMX_PKO3_RESOURCES_H__
+#define __CVMX_PKO3_RESOURCES_H__
+
+/*
+ * Allocate or reserve contiguous list of PKO queues.
+ *
+ * @param node is the node number for PKO queues.
+ * @param level is the PKO queue level.
+ * @param owner is the owner of PKO queue resources.
+ * @param base_queue is the PKO queue base number(specify -1 to allocate).
+ * @param num_queues is the number of PKO queues that have to be reserved or allocated.
+ * @return returns queue_base if successful or -1 on failure.
+ */
+int cvmx_pko_alloc_queues(int node, int level, int owner, int base_queue,
+			  int num_queues);
+
+/**
+ * Free an allocated/reserved PKO queues for a certain level and owner
+ *
+ * @param node on which to allocate/reserve PKO queues
+ * @param level of PKO queue
+ * @param owner of reserved/allocated resources
+ * @return 0 on success, -1 on failure
+ */
+int cvmx_pko_free_queues(int node, int level, int owner);
+
+int __cvmx_pko3_dq_param_setup(unsigned node);
+
+int cvmx_pko3_num_level_queues(enum cvmx_pko3_level_e level);
+
+#endif /* __CVMX_PKO3_RESOURCES_H__ */
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-pko3.h b/arch/mips/mach-octeon/include/mach/cvmx-pko3.h
new file mode 100644
index 000000000000..86f89be855fe
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-pko3.h
@@ -0,0 +1,1052 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ *
+ */
+
+#ifndef __CVMX_PKO3_H__
+#define __CVMX_PKO3_H__
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Use full LMTDMA when PARAMETER_CHECKINS is enabled */
+#undef CVMX_ENABLE_PARAMETER_CHECKING
+#define CVMX_ENABLE_PARAMETER_CHECKING 0
+
+/*
+ * CVMSEG, scratch line for LMTDMA/LMTST operations:
+ * 1. It should differ from other CVMSEG uses, e.g. IOBDMA,
+ * 2. It must agree with the setting of CvmCtl[LMTLINE] control register.
+ * Contains 16 words, words 1-15 are cleared when word 0 is written to.
+ */
+#define CVMX_PKO_LMTLINE 2ull
+
+/* PKO3 queue level identifier */
+enum cvmx_pko3_level_e {
+	CVMX_PKO_LEVEL_INVAL = 0,
+	CVMX_PKO_PORT_QUEUES = 0xd1,
+	CVMX_PKO_L2_QUEUES = 0xc2,
+	CVMX_PKO_L3_QUEUES = 0xb3,
+	CVMX_PKO_L4_QUEUES = 0xa4,
+	CVMX_PKO_L5_QUEUES = 0x95,
+	CVMX_PKO_DESCR_QUEUES = 0x86,
+};
+
+enum cvmx_pko_dqop {
+	CVMX_PKO_DQ_SEND = 0ULL,
+	CVMX_PKO_DQ_OPEN = 1ULL,
+	CVMX_PKO_DQ_CLOSE = 2ULL,
+	CVMX_PKO_DQ_QUERY = 3ULL
+};
+
+/**
+ * Returns the PKO DQ..L2 Shaper Time-Wheel clock rate for specified node.
+ */
+static inline u64 cvmx_pko3_dq_tw_clock_rate_node(int node)
+{
+	return gd->bus_clk / 768;
+}
+
+/**
+ * Returns the PKO Port Shaper Time-Wheel clock rate for specified node.
+ */
+static inline u64 cvmx_pko3_pq_tw_clock_rate_node(int node)
+{
+	int div;
+
+	if (OCTEON_IS_MODEL(OCTEON_CN78XX))
+		div = 96;
+	else
+		div = 48;
+	return gd->bus_clk / div;
+}
+
+/**
+ * @INTERNAL
+ * Return the number of MACs in the PKO (exclusing the NULL MAC)
+ * in a model-dependent manner.
+ */
+static inline unsigned int __cvmx_pko3_num_macs(void)
+{
+	if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
+		return 10;
+	if (OCTEON_IS_MODEL(OCTEON_CN73XX))
+		return 14;
+	if (OCTEON_IS_MODEL(OCTEON_CN78XX))
+		return 28;
+	return 0;
+}
+
+/**
+ * @INTERNAL
+ * Return the number of queue levels, depending on SoC model
+ */
+static inline int __cvmx_pko3_sq_lvl_max(void)
+{
+	if (OCTEON_IS_MODEL(OCTEON_CN73XX))
+		return CVMX_PKO_L3_QUEUES;
+	if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
+		return CVMX_PKO_L3_QUEUES;
+	if (OCTEON_IS_MODEL(OCTEON_CN78XX))
+		return CVMX_PKO_L5_QUEUES;
+	return -1;
+}
+
+/**
+ * @INTERNAL
+ * Return the next (lower) queue level for a given level
+ */
+static inline enum cvmx_pko3_level_e
+__cvmx_pko3_sq_lvl_next(enum cvmx_pko3_level_e level)
+{
+	switch (level) {
+	default:
+		return CVMX_PKO_LEVEL_INVAL;
+	case CVMX_PKO_PORT_QUEUES:
+		return CVMX_PKO_L2_QUEUES;
+	case CVMX_PKO_L2_QUEUES:
+		return CVMX_PKO_L3_QUEUES;
+	case CVMX_PKO_L3_QUEUES:
+		if (OCTEON_IS_MODEL(OCTEON_CN73XX) ||
+		    OCTEON_IS_MODEL(OCTEON_CNF75XX))
+			return CVMX_PKO_DESCR_QUEUES;
+		return CVMX_PKO_L4_QUEUES;
+	case CVMX_PKO_L4_QUEUES:
+		if (OCTEON_IS_MODEL(OCTEON_CN73XX) ||
+		    OCTEON_IS_MODEL(OCTEON_CNF75XX))
+			return CVMX_PKO_LEVEL_INVAL;
+		return CVMX_PKO_L5_QUEUES;
+	case CVMX_PKO_L5_QUEUES:
+		if (OCTEON_IS_MODEL(OCTEON_CN73XX) ||
+		    OCTEON_IS_MODEL(OCTEON_CNF75XX))
+			return CVMX_PKO_LEVEL_INVAL;
+		return CVMX_PKO_DESCR_QUEUES;
+	}
+}
+
+/**
+ * @INTERNAL
+ * Return an SQ identifier string, for debug messages.
+ */
+static inline char *__cvmx_pko3_sq_str(char *buf, enum cvmx_pko3_level_e level,
+				       unsigned int q)
+{
+	char *p;
+
+	switch (level) {
+	default:
+		strcpy(buf, "ERR-SQ/");
+		break;
+	case CVMX_PKO_PORT_QUEUES:
+		strcpy(buf, "PQ_L1/");
+		break;
+	case CVMX_PKO_L2_QUEUES:
+		strcpy(buf, "SQ_L2/");
+		break;
+	case CVMX_PKO_L3_QUEUES:
+		strcpy(buf, "SQ_L3/");
+		break;
+	case CVMX_PKO_L4_QUEUES:
+		strcpy(buf, "SQ_L4/");
+		break;
+	case CVMX_PKO_L5_QUEUES:
+		strcpy(buf, "SQ_L5/");
+		break;
+	case CVMX_PKO_DESCR_QUEUES:
+		strcpy(buf, "DQ/");
+		break;
+	}
+
+	for (p = buf; *p; p++)
+		;
+	*p++ = '0' + q / 1000;
+	q -= (q / 1000) * 1000;
+	*p++ = '0' + q / 100;
+	q -= (q / 100) * 100;
+	*p++ = '0' + q / 10;
+	q -= (q / 10) * 10;
+	*p++ = '0' + q;
+	*p++ = ':';
+	*p++ = '\0';
+	return buf;
+}
+
+union cvmx_pko_query_rtn {
+	u64 u64;
+	struct {
+		u64 dqstatus : 4;
+		u64 rsvd_50_59 : 10;
+		u64 dqop : 2;
+		u64 depth : 48;
+	} s;
+};
+
+typedef union cvmx_pko_query_rtn cvmx_pko_query_rtn_t;
+
+/* PKO_QUERY_RTN_S[DQSTATUS] - cvmx_pko_query_rtn_t->s.dqstatus */
+enum pko_query_dqstatus {
+	PKO_DQSTATUS_PASS = 0,	       /* No error */
+	PKO_DQSTATUS_BADSTATE = 0x8,   /* queue was not ready to enqueue */
+	PKO_DQSTATUS_NOFPABUF = 0x9,   /* FPA out of buffers */
+	PKO_DQSTATUS_NOPKOBUF = 0xA,   /* PKO out of buffers */
+	PKO_DQSTATUS_FAILRTNPTR = 0xB, /* can't return buffer ptr to FPA */
+	PKO_DQSTATUS_ALREADY = 0xC,    /* already created */
+	PKO_DQSTATUS_NOTCREATED = 0xD, /* not created */
+	PKO_DQSTATUS_NOTEMPTY = 0xE,   /* queue not empty */
+	PKO_DQSTATUS_SENDPKTDROP = 0xF /* packet dropped, illegal construct */
+};
+
+typedef enum pko_query_dqstatus pko_query_dqstatus_t;
+
+/* Sub-command three bit codes (SUBDC3) */
+#define CVMX_PKO_SENDSUBDC_LINK	  0x0
+#define CVMX_PKO_SENDSUBDC_GATHER 0x1
+#define CVMX_PKO_SENDSUBDC_JUMP	  0x2
+/* Sub-command four bit codes (SUBDC4) */
+#define CVMX_PKO_SENDSUBDC_TSO	0x8
+#define CVMX_PKO_SENDSUBDC_FREE 0x9
+#define CVMX_PKO_SENDSUBDC_WORK 0xA
+#define CVMX_PKO_SENDSUBDC_AURA 0xB
+#define CVMX_PKO_SENDSUBDC_MEM	0xC
+#define CVMX_PKO_SENDSUBDC_EXT	0xD
+#define CVMX_PKO_SENDSUBDC_CRC	0xE
+#define CVMX_PKO_SENDSUBDC_IMM	0xF
+
+/**
+ * pko buf ptr
+ * This is good for LINK_S, GATHER_S and PKI_BUFLINK_S structure use.
+ * It can also be used for JUMP_S with F-bit represented by "i" field,
+ * and the size limited to 8-bit.
+ */
+
+union cvmx_pko_buf_ptr {
+	u64 u64;
+	struct {
+		u64 size : 16;
+		u64 subdc3 : 3;
+		u64 i : 1;
+		u64 rsvd_42_43 : 2;
+		u64 addr : 42;
+	} s;
+};
+
+typedef union cvmx_pko_buf_ptr cvmx_pko_buf_ptr_t;
+
+/**
+ * pko_auraalg_e
+ */
+enum pko_auraalg_e {
+	AURAALG_NOP = 0x0,    /* aura_cnt = No change */
+	AURAALG_SUB = 0x3,    /* aura_cnt -= pko_send_aura_t.offset */
+	AURAALG_SUBLEN = 0x7, /* aura_cnt -= pko_send_aura_t.offset +
+			       *		pko_send_hdr_t.total_bytes
+			       */
+	AURAALG_SUBMBUF = 0xB /* aura_cnt -= pko_send_aura_t.offset +
+			       *		mbufs_freed
+			       */
+};
+
+/**
+ * PKO_CKL4ALG_E
+ */
+enum pko_clk4alg_e {
+	CKL4ALG_NONE = 0x0, /* No checksum. */
+	CKL4ALG_UDP = 0x1,  /* UDP L4 checksum. */
+	CKL4ALG_TCP = 0x2,  /* TCP L4 checksum. */
+	CKL4ALG_SCTP = 0x3, /* SCTP L4 checksum. */
+};
+
+/**
+ * pko_send_aura
+ */
+union cvmx_pko_send_aura {
+	u64 u64;
+	struct {
+		u64 rsvd_60_63 : 4;
+		u64 aura : 12; /* NODE+LAURA */
+		u64 subdc4 : 4;
+		u64 alg : 4; /* pko_auraalg_e */
+		u64 rsvd_08_39 : 32;
+		u64 offset : 8;
+	} s;
+};
+
+typedef union cvmx_pko_send_aura cvmx_pko_send_aura_t;
+
+/**
+ * pko_send_tso
+ */
+union cvmx_pko_send_tso {
+	u64 u64;
+	struct {
+		u64 l2len : 8;
+		u64 rsvd_48_55 : 8;
+		u64 subdc4 : 4; /* 0x8 */
+		u64 rsvd_32_43 : 12;
+		u64 sb : 8;
+		u64 mss : 16;
+		u64 eom : 1;
+		u64 fn : 7;
+	} s;
+};
+
+typedef union cvmx_pko_send_tso cvmx_pko_send_tso_t;
+
+/**
+ * pko_send_free
+ */
+union cvmx_pko_send_free {
+	u64 u64;
+	struct {
+		u64 rsvd_48_63 : 16;
+		u64 subdc4 : 4; /* 0x9 */
+		u64 rsvd : 2;
+		u64 addr : 42;
+	} s;
+};
+
+typedef union cvmx_pko_send_free cvmx_pko_send_free_t;
+
+/* PKO_SEND_HDR_S - PKO header subcommand */
+union cvmx_pko_send_hdr {
+	u64 u64;
+	struct {
+		u64 rsvd_60_63 : 4;
+		u64 aura : 12;
+		u64 ckl4 : 2; /* PKO_CKL4ALG_E */
+		u64 ckl3 : 1;
+		u64 ds : 1;
+		u64 le : 1;
+		u64 n2 : 1;
+		u64 ii : 1;
+		u64 df : 1;
+		u64 rsvd_39 : 1;
+		u64 format : 7;
+		u64 l4ptr : 8;
+		u64 l3ptr : 8;
+		u64 total : 16;
+	} s;
+};
+
+typedef union cvmx_pko_send_hdr cvmx_pko_send_hdr_t;
+
+/* PKO_SEND_EXT_S - extended header subcommand */
+union cvmx_pko_send_ext {
+	u64 u64;
+	struct {
+		u64 rsvd_48_63 : 16;
+		u64 subdc4 : 4; /* _SENDSUBDC_EXT */
+		u64 col : 2;	/* _COLORALG_E */
+		u64 ra : 2;	/* _REDALG_E */
+		u64 tstmp : 1;
+		u64 rsvd_24_38 : 15;
+		u64 markptr : 8;
+		u64 rsvd_9_15 : 7;
+		u64 shapechg : 9;
+	} s;
+};
+
+typedef union cvmx_pko_send_ext cvmx_pko_send_ext_t;
+
+/* PKO_MEMDSZ_E */
+enum cvmx_pko_memdsz_e {
+	MEMDSZ_B64 = 0,
+	MEMDSZ_B32 = 1,
+	MEMDSZ_B16 = 2, /* Not in HRM, assumed unsupported */
+	MEMDSZ_B8 = 3
+};
+
+/* PKO_MEMALG_E */
+enum cvmx_pko_memalg_e {
+	MEMALG_SET = 0,	      /* Set mem = PKO_SEND_MEM_S[OFFSET] */
+	MEMALG_SETTSTMP = 1,  /* Set the memory location to the timestamp
+			       *  PKO_SEND_MEM_S[DSZ] must be B64 and a
+			       *  PKO_SEND_EXT_S subdescriptor must be in
+			       *  the descriptor with PKO_SEND_EXT_S[TSTMP]=1
+			       */
+	MEMALG_SETRSLT = 2,   /* [DSZ] = B64; mem = PKO_MEM_RESULT_S.  */
+	MEMALG_ADD = 8,	      /* mem = mem + PKO_SEND_MEM_S[OFFSET] */
+	MEMALG_SUB = 9,	      /* mem = mem – PKO_SEND_MEM_S[OFFSET] */
+	MEMALG_ADDLEN = 0xA,  /* mem += [OFFSET] + PKO_SEND_HDR_S[TOTAL] */
+	MEMALG_SUBLEN = 0xB,  /* mem -= [OFFSET] + PKO_SEND_HDR_S[TOTAL] */
+	MEMALG_ADDMBUF = 0xC, /* mem += [OFFSET] + mbufs_freed */
+	MEMALG_SUBMBUF = 0xD  /* mem -= [OFFSET] + mbufs_freed */
+};
+
+union cvmx_pko_send_mem {
+	u64 u64;
+	struct {
+		u64 rsvd_63 : 1;
+		u64 wmem : 1;
+		u64 dsz : 2;
+		u64 alg : 4;
+		u64 offset : 8;
+		u64 subdc4 : 4;
+		u64 rsvd_42_43 : 2;
+		u64 addr : 42;
+	} s;
+};
+
+typedef union cvmx_pko_send_mem cvmx_pko_send_mem_t;
+
+union cvmx_pko_send_work {
+	u64 u64;
+	struct {
+		u64 rsvd_62_63 : 2;
+		u64 grp : 10;
+		u64 tt : 2;
+		u64 rsvd_48_49 : 2;
+		u64 subdc4 : 4;
+		u64 rsvd_42_43 : 2;
+		u64 addr : 42;
+	} s;
+};
+
+typedef union cvmx_pko_send_work cvmx_pko_send_work_t;
+
+/*** PKO_SEND_DMA_S - format of IOBDMA/LMTDMA data word ***/
+union cvmx_pko_lmtdma_data {
+	u64 u64;
+	struct {
+		u64 scraddr : 8;
+		u64 rtnlen : 8;
+		u64 did : 8; /* 0x51 */
+		u64 node : 4;
+		u64 rsvd_34_35 : 2;
+		u64 dqop : 2; /* PKO_DQOP_E */
+		u64 rsvd_26_31 : 6;
+		u64 dq : 10;
+		u64 rsvd_0_15 : 16;
+	} s;
+};
+
+typedef union cvmx_pko_lmtdma_data cvmx_pko_lmtdma_data_t;
+
+typedef struct cvmx_pko3_dq_params_s {
+	s32 depth;
+	s32 limit;
+	u64 pad[15];
+} cvmx_pko3_dq_params_t;
+
+/* DQ depth cached value */
+extern cvmx_pko3_dq_params_t *__cvmx_pko3_dq_params[CVMX_MAX_NODES];
+
+int cvmx_pko3_internal_buffer_count(unsigned int node);
+
+/**
+ * @INTERNAL
+ * PKO3 DQ parameter location
+ * @param node      node
+ * @param dq        dq
+ */
+static inline cvmx_pko3_dq_params_t *cvmx_pko3_dq_parameters(unsigned int node,
+							     unsigned int dq)
+{
+	cvmx_pko3_dq_params_t *pparam = NULL;
+	static cvmx_pko3_dq_params_t dummy;
+
+	dummy.depth = 0;
+	dummy.limit = (1 << 16);
+
+	if (cvmx_likely(node < CVMX_MAX_NODES))
+		pparam = __cvmx_pko3_dq_params[node];
+
+	if (cvmx_likely(pparam))
+		pparam += dq;
+	else
+		pparam = &dummy;
+
+	return pparam;
+}
+
+static inline void cvmx_pko3_dq_set_limit(unsigned int node, unsigned int dq,
+					  unsigned int limit)
+{
+	cvmx_pko3_dq_params_t *pparam;
+
+	pparam = cvmx_pko3_dq_parameters(node, dq);
+	pparam->limit = limit;
+}
+
+/**
+ * PKO descriptor queue operation error string
+ *
+ * @param dqstatus is the enumeration returned from hardware,
+ *	  PKO_QUERY_RTN_S[DQSTATUS].
+ *
+ * @return static constant string error description
+ */
+const char *pko_dqstatus_error(pko_query_dqstatus_t dqstatus);
+
+/*
+ * This function gets PKO mac num for a interface/port.
+ *
+ * @param interface is the interface number.
+ * @param index is the port number.
+ * @return returns mac number if successful or -1 on failure.
+ */
+static inline int __cvmx_pko3_get_mac_num(int xiface, int index)
+{
+	struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);
+	cvmx_helper_interface_mode_t mode;
+	int interface_index;
+	int ilk_mac_base = -1, bgx_mac_base = -1, bgx_ports = 4;
+
+	if (OCTEON_IS_MODEL(OCTEON_CN73XX))
+		bgx_mac_base = 2;
+
+	if (OCTEON_IS_MODEL(OCTEON_CNF75XX))
+		bgx_mac_base = 2;
+
+	if (OCTEON_IS_MODEL(OCTEON_CN78XX)) {
+		ilk_mac_base = 2;
+		bgx_mac_base = 4;
+	}
+
+	mode = cvmx_helper_interface_get_mode(xiface);
+	switch (mode) {
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		return 0;
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+		return 1;
+	case CVMX_HELPER_INTERFACE_MODE_ILK:
+		if (ilk_mac_base < 0)
+			return -1;
+		interface_index = (xi.interface - CVMX_ILK_GBL_BASE());
+		if (interface_index < 0)
+			return -1;
+		return (ilk_mac_base + interface_index);
+	case CVMX_HELPER_INTERFACE_MODE_SRIO:
+		return (4 + 2 * xi.interface + index);
+	default:
+		if (xi.interface >= CVMX_ILK_GBL_BASE() && ilk_mac_base >= 0)
+			return -1;
+		/* All other modes belong to BGX */
+		return (bgx_mac_base + bgx_ports * xi.interface + index);
+	}
+}
+
+/**
+ * @INTERNAL
+ *
+ * Get scratch offset for LMTDMA/LMTST data buffer
+ *
+ */
+static inline unsigned int cvmx_pko3_lmtdma_scr_base(void)
+{
+	return CVMX_PKO_LMTLINE * CVMX_CACHE_LINE_SIZE;
+}
+
+/**
+ * @INTERNAL
+ *
+ * Get address for LMTDMA/LMTST data buffer
+ *
+ */
+static inline u64 *cvmx_pko3_cvmseg_addr(void)
+{
+	const unsigned int scr = cvmx_pko3_lmtdma_scr_base();
+
+	return (u64 *)(CVMX_SCRATCH_BASE + scr);
+}
+
+/**
+ * Save scratchpad area
+ * @param buf storage buffer for saving previous scratchpad contents.
+ *
+ * This function should be used whenever the cache line is used
+ * from a context that might preempt another context that too uses
+ * the same cache line designated for LMTST/LMTDMA and Wide-Atomic
+ * operations, such as the hard interrupt context in Linux kernel,
+ * that could preempt a user-space application on the same processor
+ * core also using the same scratchpad.
+ * 'cvmx_lmtline_save()' should be called upon entry into the
+ * potentially interrupting context, and 'cvmx_lmtline_restore()' should
+ * be called prior to exitting that context.
+ */
+static inline void cvmx_lmtline_save(u64 buf[16])
+{
+	unsigned int i, scr_off = cvmx_pko3_lmtdma_scr_base();
+	unsigned int sz = CVMX_CACHE_LINE_SIZE / sizeof(u64);
+
+	/* wait LMTDMA to finish (if any) */
+	CVMX_SYNCIOBDMA;
+
+	/* Copy LMTLINE to user-provided buffer */
+	for (i = 0; i < sz; i++)
+		buf[i] = cvmx_scratch_read64(scr_off + i * sizeof(u64));
+}
+
+/**
+ * Restore scratchpad area
+ * @param buf storage buffer containing the previous content of scratchpad.
+ */
+static inline void cvmx_lmtline_restore(const u64 buf[16])
+{
+	unsigned int i, scr_off = cvmx_pko3_lmtdma_scr_base();
+	unsigned int sz = CVMX_CACHE_LINE_SIZE / sizeof(u64);
+
+	/* wait LMTDMA to finsh (if any) */
+	CVMX_SYNCIOBDMA;
+
+	/* restore scratchpad area from buf[] */
+	for (i = 0; i < sz; i++)
+		cvmx_scratch_write64(scr_off + i * sizeof(u64), buf[i]);
+}
+
+/*
+ * @INTERNAL
+ * Deliver PKO SEND commands via CVMSEG LM and LMTDMA/LMTST.
+ * The command should be already stored in the CVMSEG address.
+ *
+ * @param node is the destination node
+ * @param dq is the destination descriptor queue.
+ * @param numwords is the number of outgoing words
+ * @param tag_wait Wait to finish tag switch just before issueing LMTDMA
+ * @return the PKO3 native query result structure.
+ *
+ * <numwords> must be between 1 and 15 for CVMX_PKO_DQ_SEND command
+ *
+ * NOTE: Internal use only.
+ */
+static inline cvmx_pko_query_rtn_t
+__cvmx_pko3_lmtdma(u8 node, uint16_t dq, unsigned int numwords, bool tag_wait)
+{
+	const enum cvmx_pko_dqop dqop = CVMX_PKO_DQ_SEND;
+	cvmx_pko_query_rtn_t pko_status;
+	cvmx_pko_lmtdma_data_t pko_send_dma_data;
+	u64 dma_addr;
+	unsigned int scr_base = cvmx_pko3_lmtdma_scr_base();
+	unsigned int scr_off;
+	cvmx_pko3_dq_params_t *pparam;
+
+	if (cvmx_unlikely(numwords < 1 || numwords > 15)) {
+		debug("%s: ERROR: Internal error\n", __func__);
+		pko_status.u64 = ~0ull;
+		return pko_status;
+	}
+
+	pparam = cvmx_pko3_dq_parameters(node, dq);
+
+	pko_status.u64 = 0;
+	pko_send_dma_data.u64 = 0;
+
+	/* LMTDMA address offset is (nWords-1) */
+	dma_addr = CVMX_LMTDMA_ORDERED_IO_ADDR;
+	dma_addr += (numwords - 1) << 3;
+
+	scr_off = scr_base + numwords * sizeof(u64);
+
+	/* Write all-ones into the return area */
+	cvmx_scratch_write64(scr_off, ~0ull);
+
+	/* Barrier: make sure all prior writes complete before the following */
+	CVMX_SYNCWS;
+
+	/* If cached depth exceeds limit, check the real depth */
+	if (cvmx_unlikely(pparam->depth > pparam->limit)) {
+		cvmx_pko_dqx_wm_cnt_t wm_cnt;
+
+		wm_cnt.u64 = csr_rd_node(node, CVMX_PKO_DQX_WM_CNT(dq));
+		pko_status.s.depth = wm_cnt.s.count;
+		pparam->depth = pko_status.s.depth;
+
+		if (pparam->depth > pparam->limit) {
+			pko_status.s.dqop = dqop;
+			pko_status.s.dqstatus = PKO_DQSTATUS_NOFPABUF;
+			return pko_status;
+		}
+	} else {
+		cvmx_atomic_add32_nosync(&pparam->depth, 1);
+	}
+
+	if (CVMX_ENABLE_PARAMETER_CHECKING) {
+		/* Request one return word */
+		pko_send_dma_data.s.rtnlen = 1;
+	} else {
+		/* Do not expect a return word */
+		pko_send_dma_data.s.rtnlen = 0;
+	}
+
+	/* build store data for DMA */
+	pko_send_dma_data.s.scraddr = scr_off >> 3;
+	pko_send_dma_data.s.did = 0x51;
+	pko_send_dma_data.s.node = node;
+	pko_send_dma_data.s.dqop = dqop;
+	pko_send_dma_data.s.dq = dq;
+
+	/* Wait to finish tag switch just before issueing LMTDMA */
+	if (tag_wait)
+		cvmx_pow_tag_sw_wait();
+
+	/* issue PKO DMA */
+	cvmx_write64_uint64(dma_addr, pko_send_dma_data.u64);
+
+	if (cvmx_unlikely(pko_send_dma_data.s.rtnlen)) {
+		/* Wait for LMTDMA completion */
+		CVMX_SYNCIOBDMA;
+
+		/* Retrieve real result */
+		pko_status.u64 = cvmx_scratch_read64(scr_off);
+		pparam->depth = pko_status.s.depth;
+	} else {
+		/* Fake positive result */
+		pko_status.s.dqop = dqop;
+		pko_status.s.dqstatus = PKO_DQSTATUS_PASS;
+	}
+
+	return pko_status;
+}
+
+/*
+ * @INTERNAL
+ * Sends PKO descriptor commands via CVMSEG LM and LMTDMA.
+ * @param node is the destination node
+ * @param dq is the destination descriptor queue.
+ * @param cmds[] is an array of 64-bit PKO3 headers/subheaders
+ * @param numwords is the number of outgoing words
+ * @param dqop is the operation code
+ * @return the PKO3 native query result structure.
+ *
+ * <numwords> must be between 1 and 15 for CVMX_PKO_DQ_SEND command
+ * otherwise it must be 0.
+ *
+ * NOTE: Internal use only.
+ */
+static inline cvmx_pko_query_rtn_t __cvmx_pko3_do_dma(u8 node, uint16_t dq,
+						      u64 cmds[],
+						      unsigned int numwords,
+						      enum cvmx_pko_dqop dqop)
+{
+	const unsigned int scr_base = cvmx_pko3_lmtdma_scr_base();
+	cvmx_pko_query_rtn_t pko_status;
+	cvmx_pko_lmtdma_data_t pko_send_dma_data;
+	u64 dma_addr;
+	unsigned int i, scr_off;
+	cvmx_pko3_dq_params_t *pparam;
+
+	pparam = cvmx_pko3_dq_parameters(node, dq);
+	CVMX_PREFETCH0(pparam);
+	/* Push WB */
+	CVMX_SYNCWS;
+
+	pko_status.u64 = 0;
+	pko_send_dma_data.u64 = 0;
+
+	if (cvmx_unlikely(numwords > 15)) {
+		debug("%s: ERROR: Internal error\n", __func__);
+		pko_status.u64 = ~0ull;
+		return pko_status;
+	}
+
+	/* Store the command words into CVMSEG LM */
+	for (i = 0, scr_off = scr_base; i < numwords; i++) {
+		cvmx_scratch_write64(scr_off, cmds[i]);
+		scr_off += sizeof(cmds[0]);
+	}
+
+	/* With 0 data to send, this is an IOBDMA, else LMTDMA operation */
+	if (numwords == 0) {
+		dma_addr = CVMX_IOBDMA_ORDERED_IO_ADDR;
+	} else {
+		/* LMTDMA address offset is (nWords-1) */
+		dma_addr = CVMX_LMTDMA_ORDERED_IO_ADDR;
+		dma_addr += (numwords - 1) << 3;
+	}
+
+	if (cvmx_likely(dqop == CVMX_PKO_DQ_SEND)) {
+		if (cvmx_unlikely(pparam->depth > pparam->limit)) {
+			cvmx_pko_dqx_wm_cnt_t wm_cnt;
+
+			wm_cnt.u64 = csr_rd_node(node, CVMX_PKO_DQX_WM_CNT(dq));
+			pko_status.s.depth = wm_cnt.s.count;
+			pparam->depth = pko_status.s.depth;
+		}
+
+		if (cvmx_unlikely(pparam->depth > pparam->limit)) {
+			pko_status.s.dqop = dqop;
+			pko_status.s.dqstatus = PKO_DQSTATUS_NOFPABUF;
+			return pko_status;
+		}
+
+		cvmx_atomic_add32_nosync(&pparam->depth, 1);
+	}
+
+	if (cvmx_unlikely(dqop != CVMX_PKO_DQ_SEND) ||
+	    CVMX_ENABLE_PARAMETER_CHECKING) {
+		/* Request one return word */
+		pko_send_dma_data.s.rtnlen = 1;
+		/* Write all-ones into the return area */
+		cvmx_scratch_write64(scr_off, ~0ull);
+	} else {
+		/* Do not expext a return word */
+		pko_send_dma_data.s.rtnlen = 0;
+	}
+
+	/* build store data for DMA */
+	pko_send_dma_data.s.scraddr = scr_off >> 3;
+	pko_send_dma_data.s.did = 0x51;
+	pko_send_dma_data.s.node = node;
+	pko_send_dma_data.s.dqop = dqop;
+	pko_send_dma_data.s.dq = dq;
+
+	/* Barrier: make sure all prior writes complete before the following */
+	CVMX_SYNCWS;
+
+	/* Wait to finish tag switch just before issueing LMTDMA */
+	cvmx_pow_tag_sw_wait();
+
+	/* issue PKO DMA */
+	cvmx_write64_uint64(dma_addr, pko_send_dma_data.u64);
+
+	if (pko_send_dma_data.s.rtnlen) {
+		/* Wait LMTDMA for completion */
+		CVMX_SYNCIOBDMA;
+
+		/* Retrieve real result */
+		pko_status.u64 = cvmx_scratch_read64(scr_off);
+		pparam->depth = pko_status.s.depth;
+	} else {
+		/* Fake positive result */
+		pko_status.s.dqop = dqop;
+		pko_status.s.dqstatus = PKO_DQSTATUS_PASS;
+	}
+
+	return pko_status;
+}
+
+/*
+ * Transmit packets through PKO, simplified API
+ *
+ * @INTERNAL
+ *
+ * @param dq is a global destination queue number
+ * @param pki_ptr specifies packet first linked pointer as returned from
+ * 'cvmx_wqe_get_pki_pkt_ptr()'.
+ * @param len is the total number of bytes in the packet.
+ * @param gaura is the aura to free packet buffers after trasnmit.
+ * @param pCounter is an address of a 64-bit counter to atomically
+ * @param ptag is a Flow Tag pointer for packet odering or NULL
+ * decrement when packet transmission is complete.
+ *
+ * @return returns 0 if successful and -1 on failure.
+ *
+ *
+ * NOTE: This is a provisional API, and is subject to change.
+ */
+static inline int cvmx_pko3_xmit_link_buf(int dq, cvmx_buf_ptr_pki_t pki_ptr,
+					  unsigned int len, int gaura,
+					  u64 *pcounter, u32 *ptag)
+{
+	cvmx_pko_query_rtn_t pko_status;
+	cvmx_pko_send_hdr_t hdr_s;
+	cvmx_pko_buf_ptr_t gtr_s;
+	unsigned int node, nwords;
+	unsigned int scr_base = cvmx_pko3_lmtdma_scr_base();
+
+	/* Separate global DQ# into node and local DQ */
+	node = dq >> 10;
+	dq &= (1 << 10) - 1;
+
+	/* Fill in header */
+	hdr_s.u64 = 0;
+	hdr_s.s.total = len;
+	hdr_s.s.df = (gaura < 0);
+	hdr_s.s.ii = 1;
+	hdr_s.s.aura = (gaura >= 0) ? gaura : 0;
+
+	/* Fill in gather */
+	gtr_s.u64 = 0;
+	gtr_s.s.subdc3 = CVMX_PKO_SENDSUBDC_LINK;
+	gtr_s.s.addr = pki_ptr.addr;
+	gtr_s.s.size = pki_ptr.size;
+
+	/* Setup command word pointers */
+	cvmx_scratch_write64(scr_base + sizeof(u64) * 0, hdr_s.u64);
+	cvmx_scratch_write64(scr_base + sizeof(u64) * 1, gtr_s.u64);
+	nwords = 2;
+
+	/* Conditionally setup an atomic decrement counter */
+	if (pcounter) {
+		cvmx_pko_send_mem_t mem_s;
+
+		mem_s.s.subdc4 = CVMX_PKO_SENDSUBDC_MEM;
+		mem_s.s.dsz = MEMDSZ_B64;
+		mem_s.s.alg = MEMALG_SUB;
+		mem_s.s.offset = 1;
+		mem_s.s.wmem = 0;
+		mem_s.s.addr = cvmx_ptr_to_phys(CASTPTR(void, pcounter));
+		cvmx_scratch_write64(scr_base + sizeof(u64) * nwords++,
+				     mem_s.u64);
+	}
+
+	/* To preserve packet order, go atomic with DQ-specific tag */
+	if (ptag)
+		cvmx_pow_tag_sw(*ptag ^ dq, CVMX_POW_TAG_TYPE_ATOMIC);
+
+	/* Do LMTDMA */
+	pko_status = __cvmx_pko3_lmtdma(node, dq, nwords, ptag);
+
+	if (cvmx_likely(pko_status.s.dqstatus == PKO_DQSTATUS_PASS))
+		return 0;
+	else
+		return -1;
+}
+
+/**
+ * @INTERNAL
+ *
+ * Retrieve PKO internal AURA from register.
+ */
+static inline unsigned int __cvmx_pko3_aura_get(unsigned int node)
+{
+	static s16 aura = -1;
+	cvmx_pko_dpfi_fpa_aura_t pko_aura;
+
+	if (aura >= 0)
+		return aura;
+
+	pko_aura.u64 = csr_rd_node(node, CVMX_PKO_DPFI_FPA_AURA);
+
+	aura = (pko_aura.s.node << 10) | pko_aura.s.laura;
+	return aura;
+}
+
+/** Open configured descriptor queues before queueing packets into them.
+ *
+ * @param node is to specify the node to which this configuration is applied.
+ * @param dq is the descriptor queue number to be opened.
+ * @return returns 0 on success or -1 on failure.
+ */
+int cvmx_pko_dq_open(int node, int dq);
+
+/** Close a descriptor queue
+ *
+ * @param node is to specify the node to which this configuration is applied.
+ * @param dq is the descriptor queue number to be opened.
+ * @return returns 0 on success or -1 on failure.
+ *
+ * This should be called before changing the DQ parent link, topology,
+ * or when shutting down the PKO.
+ */
+int cvmx_pko3_dq_close(int node, int dq);
+
+/** Query a descriptor queue
+ *
+ * @param node is to specify the node to which this configuration is applied.
+ * @param dq is the descriptor queue number to be opened.
+ * @return returns the descriptor queue depth on success or -1 on failure.
+ *
+ * This should be called before changing the DQ parent link, topology,
+ * or when shutting down the PKO.
+ */
+int cvmx_pko3_dq_query(int node, int dq);
+
+/** Drain a descriptor queue
+ *
+ * Before closing a DQ, this call will drain all pending traffic
+ * on the DQ to the NULL MAC, which will circumvent any traffic
+ * shaping and flow control to quickly reclaim all packet buffers.
+ */
+void cvmx_pko3_dq_drain(int node, int dq);
+
+/*
+ * PKO global initialization for 78XX.
+ *
+ * @param node is the node on which PKO block is initialized.
+ * @param aura is the 12-bit AURA (including node) for PKO internal use.
+ * @return none.
+ */
+int cvmx_pko3_hw_init_global(int node, uint16_t aura);
+
+/**
+ * Shutdown the entire PKO
+ */
+int cvmx_pko3_hw_disable(int node);
+
+/* Define legacy type here to break circular dependency */
+typedef struct cvmx_pko_port_status cvmx_pko_port_status_t;
+
+/**
+ * @INTERNAL
+ * Backward compatibility for collecting statistics from PKO3
+ *
+ */
+void cvmx_pko3_get_legacy_port_stats(u16 ipd_port, unsigned int clear,
+				     cvmx_pko_port_status_t *status);
+
+/** Set MAC options
+ *
+ * The options supported are the parameters below:
+ *
+ * @param xiface The physical interface number
+ * @param index The physical sub-interface port
+ * @param fcs_enable Enable FCS generation
+ * @param pad_enable Enable padding to minimum packet size
+ * @param fcs_sop_off Number of bytes at start of packet to exclude from FCS
+ *
+ * The typical use for `fcs_sop_off` is when the interface is configured
+ * to use a header such as HighGig to precede every Ethernet packet,
+ * such a header usually does not partake in the CRC32 computation stream,
+ * and its size must be set with this parameter.
+ *
+ * @return Returns 0 on success, -1 if interface/port is invalid.
+ */
+int cvmx_pko3_interface_options(int xiface, int index, bool fcs_enable,
+				bool pad_enable, unsigned int fcs_sop_off);
+
+/** Set Descriptor Queue options
+ *
+ * The `min_pad` parameter must be in agreement with the interface-level
+ * padding option for all descriptor queues assigned to that particular
+ * interface/port.
+ */
+void cvmx_pko3_dq_options(unsigned int node, unsigned int dq, bool min_pad);
+
+int cvmx_pko3_port_fifo_size(unsigned int xiface, unsigned int index);
+int cvmx_pko3_channel_credit_level(int node, enum cvmx_pko3_level_e level);
+int cvmx_pko3_port_xoff(unsigned int xiface, unsigned int index);
+int cvmx_pko3_port_xon(unsigned int xiface, unsigned int index);
+
+/* Packet descriptor - PKO3 command buffer + internal state */
+typedef struct cvmx_pko3_pdesc_s {
+	u64 *jump_buf;		/**< jump buffer vaddr */
+	s16 last_aura;		/**< AURA of the latest LINK_S/GATHER_S */
+	unsigned num_words : 5, /**< valid words in word array 2..16 */
+		headroom : 10,	/**< free bytes at start of 1st buf */
+		hdr_offsets : 1, pki_word4_present : 1;
+	/* PKO3 command buffer: */
+	cvmx_pko_send_hdr_t *hdr_s;
+	u64 word[16]; /**< header and subcommands buffer */
+	/* Bookkeeping fields: */
+	u64 send_work_s; /**< SEND_WORK_S must be the very last subdc */
+	s16 jb_aura;	 /**< AURA where the jump buffer belongs */
+	u16 mem_s_ix;	 /**< index of first MEM_S subcommand */
+	u8 ckl4_alg;	 /**< L3/L4 alg to use if recalc is needed */
+	/* Fields saved from WQE for later inspection */
+	cvmx_pki_wqe_word4_t pki_word4;
+	cvmx_pki_wqe_word2_t pki_word2;
+} cvmx_pko3_pdesc_t;
+
+void cvmx_pko3_pdesc_init(cvmx_pko3_pdesc_t *pdesc);
+int cvmx_pko3_pdesc_from_wqe(cvmx_pko3_pdesc_t *pdesc, cvmx_wqe_78xx_t *wqe,
+			     bool free_bufs);
+int cvmx_pko3_pdesc_transmit(cvmx_pko3_pdesc_t *pdesc, uint16_t dq,
+			     u32 *flow_tag);
+int cvmx_pko3_pdesc_notify_decrement(cvmx_pko3_pdesc_t *pdesc,
+				     volatile u64 *p_counter);
+int cvmx_pko3_pdesc_notify_wqe(cvmx_pko3_pdesc_t *pdesc, cvmx_wqe_78xx_t *wqe,
+			       u8 node, uint8_t group, uint8_t tt, u32 tag);
+int cvmx_pko3_pdesc_buf_append(cvmx_pko3_pdesc_t *pdesc, void *p_data,
+			       unsigned int data_bytes, unsigned int gaura);
+int cvmx_pko3_pdesc_append_free(cvmx_pko3_pdesc_t *pdesc, u64 addr,
+				unsigned int gaura);
+int cvmx_pko3_pdesc_hdr_push(cvmx_pko3_pdesc_t *pdesc, const void *p_data,
+			     u8 data_bytes, uint8_t layer);
+int cvmx_pko3_pdesc_hdr_pop(cvmx_pko3_pdesc_t *pdesc, void *hdr_buf,
+			    unsigned int num_bytes);
+int cvmx_pko3_pdesc_hdr_peek(cvmx_pko3_pdesc_t *pdesc, void *hdr_buf,
+			     unsigned int num_bytes, unsigned int offset);
+void cvmx_pko3_pdesc_set_free(cvmx_pko3_pdesc_t *pdesc, bool free_bufs);
+
+#endif /* __CVMX_PKO3_H__ */
diff --git a/arch/mips/mach-octeon/include/mach/cvmx-range.h b/arch/mips/mach-octeon/include/mach/cvmx-range.h
new file mode 100644
index 000000000000..f0c1307e6173
--- /dev/null
+++ b/arch/mips/mach-octeon/include/mach/cvmx-range.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018-2022 Marvell International Ltd.
+ */
+
+#ifndef __CVMX_RANGE_H__
+#define __CVMX_RANGE_H__
+
+int cvmx_range_init(u64 range_addr, int size);
+int cvmx_range_alloc(u64 range_addr, uint64_t owner, uint64_t cnt, int align);
+int cvmx_range_alloc_ordered(u64 range_addr, uint64_t owner, u64 cnt, int align,
+			     int reverse);
+int cvmx_range_alloc_non_contiguos(u64 range_addr, uint64_t owner, u64 cnt,
+				   int elements[]);
+int cvmx_range_reserve(u64 range_addr, uint64_t owner, u64 base, uint64_t cnt);
+int cvmx_range_free_with_base(u64 range_addr, int base, int cnt);
+int cvmx_range_free_with_owner(u64 range_addr, uint64_t owner);
+u64 cvmx_range_get_owner(u64 range_addr, uint64_t base);
+void cvmx_range_show(uint64_t range_addr);
+int cvmx_range_memory_size(int nelements);
+int cvmx_range_free_mutiple(u64 range_addr, int bases[], int count);
+
+#endif // __CVMX_RANGE_H__
-- 
2.35.1



More information about the U-Boot mailing list