From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B94BFC433EF for ; Thu, 7 Apr 2022 12:02:02 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7B1C983DC2; Thu, 7 Apr 2022 14:01:49 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1649332909; bh=7aM0fcCQncFqGrabeEn2mhgIe4PiMWiwknNlziqZssE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=seH8TtVQjteBFzmvXD/feAABVGWnFaj9D6zKuKgFJTGv3OADfUBMG4cVPYMw7XaWy iqVoPGG/902N+btSsm61CP8vg9WVWtRG9w6z2JWW9tOoAuibdjLbsLz0rPRNhxVhNQ 0CZMRwJXAicfvBAI4WCIobKwhvG5agYy9g3NTXJRVYe4jYKNa3uLlaQEwWg13w68+a /4Hn3RhsO7CpyMbE8tS0j/kO+Yw6nkQ90MEQH8xp2l2LdT6AD2B6C/2iG2Engp5OvW /LAY88lRG4Qu07TO/2jXvVrZNNZMQO9RORNqMgFtfPvzSArcBPldpuiYFxPXr5v/A+ CO+F+iFUdp5Og== Received: by phobos.denx.de (Postfix, from userid 109) id 9227583C05; Thu, 7 Apr 2022 09:29:36 +0200 (CEST) Received: from mout-u-107.mailbox.org (mout-u-107.mailbox.org [IPv6:2001:67c:2050:1::465:107]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 215EE83CFF for ; Thu, 7 Apr 2022 09:12:15 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sr@denx.de Received: from smtp2.mailbox.org (unknown [91.198.250.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-u-107.mailbox.org (Postfix) with ESMTPS id 4KYsyQ69Hbz9sVy; Thu, 7 Apr 2022 09:12:14 +0200 (CEST) From: Stefan Roese To: u-boot@lists.denx.de Cc: daniel.schwierzeck@gmail.com, awilliams@marvell.com, cchavva@marvell.com Subject: [PATCH v2 01/52] mips: octeon: Add misc cvmx-* header files Date: Thu, 7 Apr 2022 09:11:03 +0200 Message-Id: <20220407071154.51997-2-sr@denx.de> In-Reply-To: <20220407071154.51997-1-sr@denx.de> References: <20220407071154.51997-1-sr@denx.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Thu, 07 Apr 2022 14:01:44 +0200 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean From: Aaron Williams 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 Signed-off-by: Stefan Roese --- 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. + * + * 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. + * + * 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