From patchwork Fri Dec 11 16:05:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 1415040 X-Patchwork-Delegate: daniel.schwierzeck@googlemail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=denx.de header.i=@denx.de header.a=rsa-sha256 header.s=phobos-20191101 header.b=Plo/2cSj; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CsxM90gBVz9sSn for ; Sat, 12 Dec 2020 03:39:17 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D894B8266F; Fri, 11 Dec 2020 17:38:21 +0100 (CET) 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=1607704702; bh=eWLeTXEA9lwwzZxtaZeoMmjsTiq7km0sy7k/539fGUg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Plo/2cSjl/Flfgb65LA0SCXlvrsUkwpNC3mpMDk0YzRL+eI+/SGbv6kJlmJ2esvaX dITAXd/m1iHygNKy7wDfV/JbXptQ2QhrtWVtM1BigJpeLIxXzexkSXupHSQen8Xhgd lKgpfazL3aSmGfcYCGYo6YlPjRpNaeB0SpeCtubfi28lMMlJW1rSECIHrhmQggms36 NITrdxIT+yYUNlUUkpC8wKBZYe0FjLzslRlAOIO5qXOhaYCIBGxJsqaCbttbdYIPwu Q8CU3g7Lt7lwq37C5z+TYdOBlyCORWo0PLr7qLf0MIaoBrU082yHEtb1fEMJuuOWWv NZcPLiIzM2H5w== Received: by phobos.denx.de (Postfix, from userid 109) id 19B82827A0; Fri, 11 Dec 2020 17:07:35 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mx2.mailbox.org (mx2.mailbox.org [80.241.60.215]) (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 6C1E882684 for ; Fri, 11 Dec 2020 17:06:23 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=sr@denx.de Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (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 mx2.mailbox.org (Postfix) with ESMTPS id 30E1EA0BBF; Fri, 11 Dec 2020 17:06:23 +0100 (CET) Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter05.heinlein-hosting.de (spamfilter05.heinlein-hosting.de [80.241.56.123]) (amavisd-new, port 10030) with ESMTP id EC02z1dnfDKh; Fri, 11 Dec 2020 17:06:13 +0100 (CET) From: Stefan Roese To: u-boot@lists.denx.de Cc: daniel.schwierzeck@gmail.com, awilliams@marvell.com, cchavva@marvell.com Subject: [PATCH v1 02/50] mips: octeon: Add misc cvmx-helper header files Date: Fri, 11 Dec 2020 17:05:24 +0100 Message-Id: <20201211160612.1498780-3-sr@denx.de> In-Reply-To: <20201211160612.1498780-1-sr@denx.de> References: <20201211160612.1498780-1-sr@denx.de> MIME-Version: 1.0 X-MBO-SPAM-Probability: X-Rspamd-Score: -4.76 / 15.00 / 15.00 X-Rspamd-Queue-Id: 0DD201878 X-Rspamd-UID: 9b3c1b X-Mailman-Approved-At: Fri, 11 Dec 2020 17:38:11 +0100 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 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 PCIe and networking on the MIPS Octeon II / III platforms. Signed-off-by: Aaron Williams Signed-off-by: Stefan Roese --- .../include/mach/cvmx-helper-agl.h | 68 ++ .../include/mach/cvmx-helper-bgx.h | 335 +++++++ .../include/mach/cvmx-helper-board.h | 558 +++++++++++ .../include/mach/cvmx-helper-cfg.h | 884 ++++++++++++++++++ .../include/mach/cvmx-helper-errata.h | 50 + .../include/mach/cvmx-helper-fdt.h | 568 +++++++++++ .../include/mach/cvmx-helper-fpa.h | 43 + .../include/mach/cvmx-helper-gpio.h | 427 +++++++++ .../include/mach/cvmx-helper-ilk.h | 93 ++ .../include/mach/cvmx-helper-ipd.h | 16 + .../include/mach/cvmx-helper-jtag.h | 84 ++ .../include/mach/cvmx-helper-loop.h | 37 + .../include/mach/cvmx-helper-npi.h | 42 + .../include/mach/cvmx-helper-pki.h | 319 +++++++ .../include/mach/cvmx-helper-pko.h | 51 + .../include/mach/cvmx-helper-pko3.h | 76 ++ .../include/mach/cvmx-helper-rgmii.h | 99 ++ .../include/mach/cvmx-helper-sfp.h | 437 +++++++++ .../include/mach/cvmx-helper-sgmii.h | 81 ++ .../include/mach/cvmx-helper-spi.h | 73 ++ .../include/mach/cvmx-helper-srio.h | 72 ++ .../include/mach/cvmx-helper-util.h | 412 ++++++++ .../include/mach/cvmx-helper-xaui.h | 108 +++ .../mach-octeon/include/mach/cvmx-helper.h | 565 +++++++++++ 24 files changed, 5498 insertions(+) create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-agl.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-bgx.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-board.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-cfg.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-errata.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-fpa.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-gpio.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-ilk.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-ipd.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-jtag.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-loop.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-npi.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-pki.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-pko3.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-rgmii.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-sfp.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-sgmii.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-spi.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-srio.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-util.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper-xaui.h create mode 100644 arch/mips/mach-octeon/include/mach/cvmx-helper.h diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-agl.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-agl.h new file mode 100644 index 0000000000..7a5e4d89d3 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-agl.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for AGL (RGMII) initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_AGL_H__ +#define __CVMX_HELPER_AGL_H__ + +int __cvmx_helper_agl_enumerate(int interface); + +int cvmx_helper_agl_get_port(int xiface); + +/** + * @INTERNAL + * Probe a RGMII interface and determine the number of ports + * connected to it. The RGMII interface should still be down + * after this call. + * + * @param interface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_agl_probe(int interface); + +/** + * @INTERNAL + * Bringup and enable a RGMII interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param interface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_agl_enable(int interface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_agl_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_agl_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +#endif /* __CVMX_HELPER_AGL_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-bgx.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-bgx.h new file mode 100644 index 0000000000..ead6193ec0 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-bgx.h @@ -0,0 +1,335 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions to configure the BGX MAC. + */ + +#ifndef __CVMX_HELPER_BGX_H__ +#define __CVMX_HELPER_BGX_H__ + +#define CVMX_BGX_RX_FIFO_SIZE (64 * 1024) +#define CVMX_BGX_TX_FIFO_SIZE (32 * 1024) + +int __cvmx_helper_bgx_enumerate(int xiface); + +/** + * @INTERNAL + * Disable the BGX port + * + * @param xipd_port IPD port of the BGX interface to disable + */ +void cvmx_helper_bgx_disable(int xipd_port); + +/** + * @INTERNAL + * Probe a SGMII interface and determine the number of ports + * connected to it. The SGMII/XAUI interface should still be down after + * this call. This is used by interfaces using the bgx mac. + * + * @param xiface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_bgx_probe(int xiface); + +/** + * @INTERNAL + * Bringup and enable a SGMII interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. This is used by interfaces using the + * bgx mac. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_bgx_sgmii_enable(int xiface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). This is used by + * interfaces using the bgx mac. + * + * @param xipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_bgx_sgmii_link_get(int xipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. This is used by interfaces + * using the bgx mac. + * + * @param xipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_bgx_sgmii_link_set(int xipd_port, cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * Configure a port for internal and/or external loopback. Internal loopback + * causes packets sent by the port to be received by Octeon. External loopback + * causes packets received from the wire to sent out again. This is used by + * interfaces using the bgx mac. + * + * @param xipd_port IPD/PKO port to loopback. + * @param enable_internal + * Non zero if you want internal loopback + * @param enable_external + * Non zero if you want external loopback + * + * @return Zero on success, negative on failure. + */ +int __cvmx_helper_bgx_sgmii_configure_loopback(int xipd_port, int enable_internal, + int enable_external); + +/** + * @INTERNAL + * Bringup and enable a XAUI interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. This is used by interfaces using the + * bgx mac. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_bgx_xaui_enable(int xiface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). This is used by + * interfaces using the bgx mac. + * + * @param xipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_bgx_xaui_link_get(int xipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. This is used by interfaces + * using the bgx mac. + * + * @param xipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_bgx_xaui_link_set(int xipd_port, cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * Configure a port for internal and/or external loopback. Internal loopback + * causes packets sent by the port to be received by Octeon. External loopback + * causes packets received from the wire to sent out again. This is used by + * interfaces using the bgx mac. + * + * @param xipd_port IPD/PKO port to loopback. + * @param enable_internal + * Non zero if you want internal loopback + * @param enable_external + * Non zero if you want external loopback + * + * @return Zero on success, negative on failure. + */ +int __cvmx_helper_bgx_xaui_configure_loopback(int xipd_port, int enable_internal, + int enable_external); + +int __cvmx_helper_bgx_mixed_enable(int xiface); + +cvmx_helper_link_info_t __cvmx_helper_bgx_mixed_link_get(int xipd_port); + +int __cvmx_helper_bgx_mixed_link_set(int xipd_port, cvmx_helper_link_info_t link_info); + +int __cvmx_helper_bgx_mixed_configure_loopback(int xipd_port, int enable_internal, + int enable_external); + +cvmx_helper_interface_mode_t cvmx_helper_bgx_get_mode(int xiface, int index); + +/** + * @INTERNAL + * Configure Priority-Based Flow Control (a.k.a. PFC/CBFC) + * on a specific BGX interface/port. + */ +void __cvmx_helper_bgx_xaui_config_pfc(unsigned int node, unsigned int interface, unsigned int port, + bool pfc_enable); + +/** + * This function control how the hardware handles incoming PAUSE + * packets. The most common modes of operation: + * ctl_bck = 1, ctl_drp = 1: hardware handles everything + * ctl_bck = 0, ctl_drp = 0: software sees all PAUSE frames + * ctl_bck = 0, ctl_drp = 1: all PAUSE frames are completely ignored + * @param node node number. + * @param interface interface number + * @param port port number + * @param ctl_bck 1: Forward PAUSE information to TX block + * @param ctl_drp 1: Drop control PAUSE frames. + */ +void cvmx_helper_bgx_rx_pause_ctl(unsigned int node, unsigned int interface, unsigned int port, + unsigned int ctl_bck, unsigned int ctl_drp); + +/** + * This function configures the receive action taken for multicast, broadcast + * and dmac filter match packets. + * @param node node number. + * @param interface interface number + * @param port port number + * @param cam_accept 0: reject packets on dmac filter match + * 1: accept packet on dmac filter match + * @param mcast_mode 0x0 = Force reject all multicast packets + * 0x1 = Force accept all multicast packets + * 0x2 = Use the address filter CAM + * @param bcast_accept 0 = Reject all broadcast packets + * 1 = Accept all broadcast packets + */ +void cvmx_helper_bgx_rx_adr_ctl(unsigned int node, unsigned int interface, unsigned int port, + unsigned int cam_accept, unsigned int mcast_mode, + unsigned int bcast_accept); + +/** + * Function to control the generation of FCS, padding by the BGX + * + */ +void cvmx_helper_bgx_tx_options(unsigned int node, unsigned int interface, unsigned int index, + bool fcs_enable, bool pad_enable); + +/** + * Set mac for the ipd_port + * + * @param xipd_port ipd_port to set the mac + * @param bcst If set, accept all broadcast packets + * @param mcst Multicast mode + * 0 = Force reject all multicast packets + * 1 = Force accept all multicast packets + * 2 = use the address filter CAM. + * @param mac mac address for the ipd_port + */ +void cvmx_helper_bgx_set_mac(int xipd_port, int bcst, int mcst, u64 mac); + +int __cvmx_helper_bgx_port_init(int xipd_port, int phy_pres); +void cvmx_helper_bgx_set_jabber(int xiface, unsigned int index, unsigned int size); +int cvmx_helper_bgx_shutdown_port(int xiface, int index); +int cvmx_bgx_set_backpressure_override(int xiface, unsigned int port_mask); +int __cvmx_helper_bgx_fifo_size(int xiface, unsigned int lmac); + +/** + * Returns if an interface is RGMII or not + * + * @param xiface xinterface to check + * @param index port index (must be 0 for rgmii) + * + * @return true if RGMII, false otherwise + */ +static inline bool cvmx_helper_bgx_is_rgmii(int xiface, int index) +{ + union cvmx_bgxx_cmrx_config cmr_config; + + if (!OCTEON_IS_MODEL(OCTEON_CN73XX) || index != 0) + return false; + cmr_config.u64 = csr_rd(CVMX_BGXX_CMRX_CONFIG(index, xiface)); + return cmr_config.s.lmac_type == 5; +} + +/** + * Probes the BGX Super Path (SMU/SPU) mode + * + * @param xiface global interface number + * @param index interface index + * + * @return true, if Super-MAC/PCS mode, false -- otherwise + */ +bool cvmx_helper_bgx_is_smu(int xiface, int index); + +/** + * @INTERNAL + * Configure parameters of PAUSE packet. + * + * @param xipd_port Global IPD port (node + IPD port). + * @param smac Source MAC address. + * @param dmac Destination MAC address. + * @param type PAUSE packet type. + * @param time Pause time for PAUSE packets (number of 512 bit-times). + * @param interval Interval between PAUSE packets (number of 512 bit-times). + * @return Zero on success, negative on failure. + */ +int cvmx_bgx_set_pause_pkt_param(int xipd_port, u64 smac, u64 dmac, unsigned int type, + unsigned int time, unsigned int interval); + +/** + * @INTERNAL + * Setup the BGX flow-control mode. + * + * @param xipd_port Global IPD port (node + IPD port). + * @param type Flow-control type/protocol. + * @param mode Flow-control mode. + * @return Zero on success, negative on failure. + */ +int cvmx_bgx_set_flowctl_mode(int xipd_port, cvmx_qos_proto_t qos, cvmx_qos_pkt_mode_t mode); + +/** + * Enables or disables autonegotiation for an interface. + * + * @param xiface interface to set autonegotiation + * @param index port index + * @param enable true to enable autonegotiation, false to disable it + * + * @return 0 for success, -1 on error. + */ +int cvmx_helper_set_autonegotiation(int xiface, int index, bool enable); + +/** + * Enables or disables forward error correction + * + * @param xiface interface + * @param index port index + * @param enable set to true to enable FEC, false to disable + * + * @return 0 for success, -1 on error + * + * @NOTE: If autonegotiation is enabled then autonegotiation will be + * restarted for negotiating FEC. + */ +int cvmx_helper_set_fec(int xiface, int index, bool enable); + +#ifdef CVMX_DUMP_BGX +/** + * Dump BGX configuration for node 0 + */ +int cvmx_dump_bgx_config(unsigned int bgx); +/** + * Dump BGX status for node 0 + */ +int cvmx_dump_bgx_status(unsigned int bgx); +/** + * Dump BGX configuration + */ +int cvmx_dump_bgx_config_node(unsigned int node, unsigned int bgx); +/** + * Dump BGX status + */ +int cvmx_dump_bgx_status_node(unsigned int node, unsigned int bgx); + +#endif + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h new file mode 100644 index 0000000000..d7a7b7d227 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-board.h @@ -0,0 +1,558 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper functions to abstract board specific data about + * network ports from the rest of the cvmx-helper files. + */ + +#ifndef __CVMX_HELPER_BOARD_H__ +#define __CVMX_HELPER_BOARD_H__ + +#define CVMX_VSC7224_NAME_LEN 16 + +typedef enum { + USB_CLOCK_TYPE_REF_12, + USB_CLOCK_TYPE_REF_24, + USB_CLOCK_TYPE_REF_48, + USB_CLOCK_TYPE_CRYSTAL_12, +} cvmx_helper_board_usb_clock_types_t; + +typedef enum cvmx_phy_type { + BROADCOM_GENERIC_PHY, + MARVELL_GENERIC_PHY, + CORTINA_PHY, /** Now Inphi */ + AQUANTIA_PHY, + GENERIC_8023_C22_PHY, + GENERIC_8023_C45_PHY, + INBAND_PHY, + QUALCOMM_S17, /** Qualcomm QCA833X switch */ + VITESSE_VSC8490_PHY, /** Vitesse VSC8490 is non-standard for SGMII */ + FAKE_PHY, /** Unsupported or no PHY, use GPIOs for LEDs */ +} cvmx_phy_type_t; + +/** Used to record the host mode used by the Cortina CS4321 PHY */ +typedef enum { + CVMX_PHY_HOST_MODE_UNKNOWN, + CVMX_PHY_HOST_MODE_SGMII, + CVMX_PHY_HOST_MODE_QSGMII, + CVMX_PHY_HOST_MODE_XAUI, + CVMX_PHY_HOST_MODE_RXAUI, +} cvmx_phy_host_mode_t; + +typedef enum { + set_phy_link_flags_autoneg = 0x1, + set_phy_link_flags_flow_control_dont_touch = 0x0 << 1, + set_phy_link_flags_flow_control_enable = 0x1 << 1, + set_phy_link_flags_flow_control_disable = 0x2 << 1, + set_phy_link_flags_flow_control_mask = 0x3 << 1, +} cvmx_helper_board_set_phy_link_flags_types_t; + +/** + * The EBB6600 board uses a MDIO mux device to select between the two QLM + * modules since both QLM modules share the same PHY addresses. The + * MDIO mux is controlled via GPIO by a GPIO device that is also on + * the TWSI bus rather than native OCTEON GPIO libes. + * + * To further complicate matters, the TWSI GPIO device sits behind + * a TWSI mux device as well, making accessing the MDIO devices on + * this board a very complex operation involving writing to the TWSI mux, + * followed by the MDIO mux device. + */ +/** Maximum number of GPIO devices used to control the MDIO mux */ +#define CVMX_PHY_MUX_MAX_GPIO 2 + +/** Type of MDIO mux device, currently OTHER isn't supported */ +typedef enum { + SN74CBTLV3253, /** SN74CBTLV3253 I2C device */ + OTHER /** Unknown/other */ +} cvmx_phy_mux_type_t; + +/** Type of GPIO line controlling MDIO mux */ +typedef enum { + GPIO_OCTEON, /** Native OCTEON */ + GPIO_PCA8574 /** TWSI mux device */ +} cvmx_phy_gpio_type_t; + +/* Forward declarations */ +struct cvmx_fdt_sfp_info; /** Defined in cvmx-helper-fdt.h */ +struct cvmx_vsc7224; +struct cvmx_fdt_gpio_info; /** Defined in cvmx-helper-fdt.h */ +struct cvmx_fdt_i2c_bus_info; /** Defined in cvmx-helper-fdt.h */ +struct cvmx_phy_info; +struct cvmx_fdt_i2c_bus_info; +struct cvmx_fdt_gpio_info; +struct cvmx_fdt_gpio_led; + +/** + * @INTERNAL + * This data structure is used when the port LEDs are wired up to Octeon's GPIO + * lines instead of to a traditional PHY. + */ +struct cvmx_phy_gpio_leds { + struct cvmx_phy_gpio_leds *next; /** For when ports are grouped together */ + u64 last_rx_count; /** Counters used to check for activity */ + u64 last_tx_count; /** Counters used to check for activity */ + u64 last_activity_poll_time; /** Last time activity was polled */ + u64 last_link_poll_time; /** Last time link was polled */ + int of_offset; + int link_poll_interval_ms; /** Link polling interval in ms */ + int activity_poll_interval_ms; /** Activity polling interval in ms */ + struct cvmx_fdt_gpio_led *link_status; + struct cvmx_fdt_gpio_led *error; + struct cvmx_fdt_gpio_led *rx_activity; + struct cvmx_fdt_gpio_led *tx_activity; + struct cvmx_fdt_gpio_led *identify; + + struct cvmx_fdt_gpio_info *link_status_gpio; + struct cvmx_fdt_gpio_info *error_gpio; + /** Type of GPIO for error LED */ + /** If GPIO expander, describe the bus to the expander */ + struct cvmx_fdt_gpio_info *rx_activity_gpio; + struct cvmx_fdt_gpio_info *tx_activity_gpio; + + u16 rx_activity_hz; /** RX activity blink time in hz */ + u16 tx_activity_hz; /** TX activity blink time in hz */ + /** + * Set if activity and/or link is using an Inphi/Cortina CS4343 or + * compatible phy that requires software assistance. NULL if not used. + */ + bool link_status_active_low; /** True if active link is active low */ + bool error_status_active_low; /** True if error LED is active low */ + bool error_active_low; /** True if error is active low */ + bool rx_activity_active_low; /** True if rx activity is active low */ + bool tx_activity_active_low; /** True if tx activity is active low */ + /** Set true if LEDs are shared on an interface by all ports */ + bool interface_leds; + int8_t rx_gpio_timer; /** GPIO clock generator timer [0-3] */ + int8_t tx_gpio_timer; /** GPIO clock generator timer [0-3] */ + + /** True if LOS signal activates error LED */ + bool los_generate_error; + /** True if the error LED is hooked up to a GPIO expander */ + bool error_gpio_expander; + /** True if the link and RX activity LEDs are shared */ + bool link_and_rx_activity_shared; + /** True if the link and TX activity LEDs are shared */ + bool link_and_tx_activity_shared; + /** True if the RX activity and TX activity LEDs are shared */ + bool rx_and_tx_activity_shared; + /** True if link is driven directly by the hardware */ + bool link_led_hw_link; + bool error_lit; /** True if ERROR LED is lit */ + bool quad_sfp_mode; /** True if using four SFPs for XLAUI */ + /** User-defined function to update the link LED */ + void (*update_link_led)(int xiface, int index, cvmx_helper_link_info_t result); + /** User-defined function to update the rx activity LED */ + void (*update_rx_activity_led)(struct cvmx_phy_gpio_leds *led, int xiface, int index, + bool check_time); +}; + +/** This structure contains the tap values to use for various cable lengths */ +struct cvmx_vsc7224_tap { + u16 len; /** Starting cable length for tap values */ + u16 main_tap; /** Main tap value to use */ + u16 pre_tap; /** Pre-tap value to use */ + u16 post_tap; /** Post-tap value to use */ +}; + +/** Data structure for Microsemi VSC7224 channel */ +struct cvmx_vsc7224_chan { + struct cvmx_vsc7224_chan *next, *prev; /** Used for linking */ + int ipd_port; /** IPD port this channel belongs to */ + int xiface; /** xinterface of SFP */ + int index; /** Port index of SFP */ + int lane; /** Lane on port */ + int of_offset; /** Offset of channel info in dt */ + bool is_tx; /** True if is transmit channel */ + bool maintap_disable; /** True to disable the main tap */ + bool pretap_disable; /** True to disable pre-tap */ + bool posttap_disable; /** True to disable post-tap */ + int num_taps; /** Number of tap values */ + /** (Q)SFP attached to this channel */ + struct cvmx_fdt_sfp_info *sfp_info; + struct cvmx_vsc7224 *vsc7224; /** Pointer to parent */ + /** Tap values for various lengths, must be at the end */ + struct cvmx_vsc7224_tap taps[0]; +}; + +/** Data structure for Microsemi VSC7224 reclocking chip */ +struct cvmx_vsc7224 { + const char *name; /** Name */ + /** Pointer to cannel data */ + struct cvmx_vsc7224_chan *channel[4]; + /** I2C bus device is connected to */ + struct cvmx_fdt_i2c_bus_info *i2c_bus; + /** Address of VSC7224 on i2c bus */ + int i2c_addr; + struct cvmx_fdt_gpio_info *los_gpio; /** LoS GPIO pin */ + struct cvmx_fdt_gpio_info *reset_gpio; /** Reset GPIO pin */ + int of_offset; /** Offset in device tree */ +}; + +/** Data structure for Avago AVSP5410 gearbox phy */ +struct cvmx_avsp5410 { + const char *name; /** Name */ + /** I2C bus device is connected to */ + struct cvmx_fdt_i2c_bus_info *i2c_bus; + /** Address of AVSP5410 on i2c bus */ + int i2c_addr; + int of_offset; /** Offset in device tree */ + int ipd_port; /** IPD port this phy belongs to */ + int xiface; /** xinterface of SFP */ + int index; /** Port index of SFP */ + u64 prev_temp; /** Previous temparature recorded on Phy Core */ + u64 prev_temp_mins; /** Mininutes when the prev temp check is done */ + /** (Q)SFP attached to this phy */ + struct cvmx_fdt_sfp_info *sfp_info; +}; + +struct cvmx_cs4343_info; + +/** + * @INTERNAL + * + * Data structure containing Inphi CS4343 slice information + */ +struct cvmx_cs4343_slice_info { + const char *name; /** Name of this slice in device tree */ + struct cvmx_cs4343_info *mphy; /** Pointer to mphy cs4343 */ + struct cvmx_phy_info *phy_info; + int of_offset; /** Offset in device tree */ + int slice_no; /** Slice number */ + int reg_offset; /** Offset for this slice */ + u16 sr_stx_cmode_res; /** See Rainier device tree */ + u16 sr_stx_drv_lower_cm; /** See Rainier device tree */ + u16 sr_stx_level; /** See Rainier device tree */ + u16 sr_stx_pre_peak; /** See Rainier device tree */ + u16 sr_stx_muxsubrate_sel; /** See Rainier device tree */ + u16 sr_stx_post_peak; /** See Rainier device tree */ + u16 cx_stx_cmode_res; /** See Rainier device tree */ + u16 cx_stx_drv_lower_cm; /** See Rainier device tree */ + u16 cx_stx_level; /** See Rainier device tree */ + u16 cx_stx_pre_peak; /** See Rainier device tree */ + u16 cx_stx_muxsubrate_sel; /** See Rainier device tree */ + u16 cx_stx_post_peak; /** See Rainier device tree */ + u16 basex_stx_cmode_res; /** See Rainier device tree */ + u16 basex_stx_drv_lower_cm; /** See Rainier device tree */ + u16 basex_stx_level; /** See Rainier device tree */ + u16 basex_stx_pre_peak; /** See Rainier device tree */ + u16 basex_stx_muxsubrate_sel; /** See Rainier device tree */ + u16 basex_stx_post_peak; /** See Rainier device tree */ + int link_gpio; /** Link LED gpio pin number, -1 if none */ + int error_gpio; /** Error LED GPIO pin or -1 if none */ + int los_gpio; /** LoS input GPIO or -1 if none */ + bool los_inverted; /** True if LoS input is inverted */ + bool link_inverted; /** True if link output is inverted */ + bool error_inverted; /** True if error output is inverted */ +}; + +/** + * @INTERNAL + * + * Data structure for Cortina/Inphi CS4343 device + */ +struct cvmx_cs4343_info { + const char *name; /** Name of Inphi/Cortina CS4343 in DT */ + struct cvmx_phy_info *phy_info; + struct cvmx_cs4343_slice_info slice[4]; /** Slice information */ + int of_offset; +}; + +/** + * @INTERNAL + * This data structure is used to hold PHY information and is subject to change. + * Please do not use this data structure directly. + * + * NOTE: The U-Boot OCTEON Ethernet drivers depends on this data structure for + * the mux support. + */ +typedef struct cvmx_phy_info { + int phy_addr; /** MDIO address of PHY */ + int phy_sub_addr; /** Sub-address (i.e. slice), used by Cortina */ + int ipd_port; /** IPD port number for the PHY */ + /** MDIO bus PHY connected to (even if behind mux) */ + int mdio_unit; + int direct_connect; /** 1 if PHY is directly connected */ + int gpio[CVMX_PHY_MUX_MAX_GPIO]; /** GPIOs used to control mux, -1 if not used */ + + /** Type of GPIO. It can be a local OCTEON GPIO or a TWSI GPIO */ + cvmx_phy_gpio_type_t gpio_type[CVMX_PHY_MUX_MAX_GPIO]; + + /** Address of TWSI GPIO */ + int cvmx_gpio_twsi[CVMX_PHY_MUX_MAX_GPIO]; + + /** Value to put into the GPIO lines to select MDIO bus */ + int gpio_value; + int gpio_parent_mux_twsi; /** -1 if not used, parent TWSI mux for ebb6600 */ + int gpio_parent_mux_select; /** selector to use on parent TWSI mux */ + cvmx_phy_type_t phy_type; /** Type of PHY */ + cvmx_phy_mux_type_t mux_type; /** Type of MDIO mux */ + int mux_twsi_addr; /** Address of the MDIO mux */ + cvmx_phy_host_mode_t host_mode; /** Used by Cortina PHY */ + void *phydev; /** Pointer to parent phy device */ + int fdt_offset; /** Node in flat device tree */ + int phy_i2c_bus; /** I2C bus for reclocking chips */ + int phy_i2c_addr; /** I2C address of reclocking chip */ + int num_vsc7224; /** Number of Microsemi VSC7224 devices */ + struct cvmx_vsc7224 *vsc7224; /** Info for VSC7224 devices */ + /** SFP/QSFP descriptor */ + struct cvmx_fdt_sfp_info *sfp_info; + /** CS4343 slice information for SGMII/XFI. This is NULL in XLAUI mode */ + struct cvmx_cs4343_slice_info *cs4343_slice_info; + /** CS4343 mphy information for XLAUI */ + struct cvmx_cs4343_info *cs4343_info; + /** Pointer to function to return link information */ + cvmx_helper_link_info_t (*link_function)(struct cvmx_phy_info *phy_info); + /** + * If there are LEDs driven by GPIO lines instead of by a PHY device + * then they are described here, otherwise gpio_leds should be NULL. + */ + struct cvmx_phy_gpio_leds *gpio_leds; +} cvmx_phy_info_t; + +/* Fake IPD port, the RGMII/MII interface may use different PHY, use this + macro to return appropriate MIX address to read the PHY. */ +#define CVMX_HELPER_BOARD_MGMT_IPD_PORT -10 + +/** + * Return the MII PHY address associated with the given IPD + * port. A result of -1 means there isn't a MII capable PHY + * connected to this port. On chips supporting multiple MII + * busses the bus number is encoded in bits <15:8>. + * + * This function must be modified for every new Octeon board. + * Internally it uses switch statements based on the cvmx_sysinfo + * data to determine board types and revisions. It relies on the + * fact that every Octeon board receives a unique board type + * enumeration from the bootloader. + * + * @param ipd_port Octeon IPD port to get the MII address for. + * + * @return MII PHY address and bus number or -1. + */ +int cvmx_helper_board_get_mii_address(int ipd_port); + +/** + * This function as a board specific method of changing the PHY + * speed, duplex, and autonegotiation. This programs the PHY and + * not Octeon. This can be used to force Octeon's links to + * specific settings. + * + * @param phy_addr The address of the PHY to program + * @param link_flags + * Flags to control autonegotiation. Bit 0 is autonegotiation + * enable/disable to maintain backward compatibility. + * @param link_info Link speed to program. If the speed is zero and autonegotiation + * is enabled, all possible negotiation speeds are advertised. + * + * @return Zero on success, negative on failure + */ +int cvmx_helper_board_link_set_phy(int phy_addr, + cvmx_helper_board_set_phy_link_flags_types_t link_flags, + cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * This function is the board specific method of determining an + * ethernet ports link speed. Most Octeon boards have Marvell PHYs + * and are handled by the fall through case. This function must be + * updated for boards that don't have the normal Marvell PHYs. + * + * This function must be modified for every new Octeon board. + * Internally it uses switch statements based on the cvmx_sysinfo + * data to determine board types and revisions. It relies on the + * fact that every Octeon board receives a unique board type + * enumeration from the bootloader. + * + * @param ipd_port IPD input port associated with the port we want to get link + * status for. + * + * @return The ports link status. If the link isn't fully resolved, this must + * return zero. + */ +cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port); + +/** + * @INTERNAL + * This function is called by cvmx_helper_interface_probe() after it + * determines the number of ports Octeon can support on a specific + * interface. This function is the per board location to override + * this value. It is called with the number of ports Octeon might + * support and should return the number of actual ports on the + * board. + * + * This function must be modified for every new Octeon board. + * Internally it uses switch statements based on the cvmx_sysinfo + * data to determine board types and revisions. It relies on the + * fact that every Octeon board receives a unique board type + * enumeration from the bootloader. + * + * @param interface Interface to probe + * @param supported_ports + * Number of ports Octeon supports. + * + * @return Number of ports the actual board supports. Many times this will + * simple be "support_ports". + */ +int __cvmx_helper_board_interface_probe(int interface, int supported_ports); + +/** + * @INTERNAL + * Enable packet input/output from the hardware. This function is + * called after by cvmx_helper_packet_hardware_enable() to + * perform board specific initialization. For most boards + * nothing is needed. + * + * @param interface Interface to enable + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_board_hardware_enable(int interface); + +/** + * @INTERNAL + * Gets the clock type used for the USB block based on board type. + * Used by the USB code for auto configuration of clock type. + * + * @return USB clock type enumeration + */ +cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void); + +/** + * @INTERNAL + * Adjusts the number of available USB ports on Octeon based on board + * specifics. + * + * @param supported_ports expected number of ports based on chip type; + * + * + * @return number of available usb ports, based on board specifics. + * Return value is supported_ports if function does not + * override. + */ +int __cvmx_helper_board_usb_get_num_ports(int supported_ports); + +/** + * @INTERNAL + * Returns if a port is present on an interface + * + * @param fdt_addr - address fo flat device tree + * @param ipd_port - IPD port number + * + * @return 1 if port is present, 0 if not present, -1 if error + */ +int __cvmx_helper_board_get_port_from_dt(void *fdt_addr, int ipd_port); + +/** + * Return the host mode for the PHY. Currently only the Cortina CS4321 PHY + * needs this. + * + * @param ipd_port - ipd port number to get the host mode for + * + * @return host mode for phy + */ +cvmx_phy_host_mode_t cvmx_helper_board_get_phy_host_mode(int ipd_port); + +/** + * @INTERNAL + * This function outputs the cvmx_phy_info_t data structure for the specified + * port. + * + * @param[out] - phy_info - phy info data structure + * @param ipd_port - port to get phy info for + * + * @return 0 for success, -1 if info not available + * + * NOTE: The phy_info data structure is subject to change. + */ +int cvmx_helper_board_get_phy_info(cvmx_phy_info_t *phy_info, int ipd_port); + +/** + * @INTERNAL + * Parse the device tree and set whether a port is valid or not. + * + * @param fdt_addr Pointer to device tree + * + * @return 0 for success, -1 on error. + */ +int __cvmx_helper_parse_bgx_dt(const void *fdt_addr); + +/** + * @INTERNAL + * Parse the device tree and set whether a port is valid or not. + * + * @param fdt_addr Pointer to device tree + * + * @return 0 for success, -1 on error. + */ +int __cvmx_helper_parse_bgx_rgmii_dt(const void *fdt_addr); + +/** + * @INTERNAL + * Updates any GPIO link LEDs if present + * + * @param xiface Interface number + * @param index Port index + * @param result Link status result + */ +void cvmx_helper_update_link_led(int xiface, int index, cvmx_helper_link_info_t result); +/** + * Update the RX activity LED for the specified interface and port index + * + * @param xiface Interface number + * @param index Port index + * @parma check_time True if we should bail out before the polling interval + */ +void cvmx_update_rx_activity_led(int xiface, int index, bool check_time); + +/** + * @INTERNAL + * Figure out which mod_abs changed function to use based on the phy type + * + * @param xiface xinterface number + * @param index port index on interface + * + * @return 0 for success, -1 on error + * + * This function figures out the proper mod_abs_changed function to use and + * registers the appropriate function. This should be called after the device + * tree has been fully parsed for the given port as well as after all SFP + * slots and any Microsemi VSC7224 devices have been parsed in the device tree. + */ +int cvmx_helper_phy_register_mod_abs_changed(int xiface, int index); + +/** + * @INTERNAL + * Return loss of signal + * + * @param xiface xinterface number + * @param index port index on interface + * + * @return 0 if signal present, 1 if loss of signal. + * + * @NOTE: A result of 0 is possible in some cases where the signal is + * not present. + * + * This is for use with __cvmx_qlm_rx_equilization + */ +int __cvmx_helper_get_los(int xiface, int index); + +/** + * Given the address of the MDIO registers, output the CPU node and MDIO bus + * + * @param addr 64-bit address of MDIO registers (from device tree) + * @param[out] node CPU node number (78xx) + * @param[out] bus MDIO bus number + */ +void __cvmx_mdio_addr_to_node_bus(u64 addr, int *node, int *bus); + +/** + * Turn on the error LED + * + * @param leds LEDs belonging to port + * @param error true to turn on LED, false to turn off + */ +void cvmx_helper_leds_show_error(struct cvmx_phy_gpio_leds *leds, bool error); + +#endif /* __CVMX_HELPER_BOARD_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-cfg.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-cfg.h new file mode 100644 index 0000000000..d4bd910b01 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-cfg.h @@ -0,0 +1,884 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper Functions for the Configuration Framework + * + * OCTEON_CN68XX introduces a flexible hw interface configuration + * scheme. To cope with this change and the requirements of + * configurability for other system resources, e.g., IPD/PIP pknd and + * PKO ports and queues, a configuration framework for the SDK is + * designed. It has two goals: first to recognize and establish the + * default configuration and, second, to allow the user to define key + * parameters in a high-level language. + * + * The helper functions query the QLM setup to help achieving the + * first goal. + * + * The second goal is accomplished by generating + * cvmx_helper_cfg_init() from a high-level lanaguage. + */ + +#ifndef __CVMX_HELPER_CFG_H__ +#define __CVMX_HELPER_CFG_H__ + +#include "cvmx-helper-util.h" + +#define CVMX_HELPER_CFG_MAX_PKO_PORT 128 +#define CVMX_HELPER_CFG_MAX_PIP_BPID 64 +#define CVMX_HELPER_CFG_MAX_PIP_PKND 64 +#define CVMX_HELPER_CFG_MAX_PKO_QUEUES 256 +#define CVMX_HELPER_CFG_MAX_PORT_PER_IFACE 256 + +#define CVMX_HELPER_CFG_INVALID_VALUE -1 + +#define cvmx_helper_cfg_assert(cond) \ + do { \ + if (!(cond)) { \ + debug("cvmx_helper_cfg_assert (%s) at %s:%d\n", #cond, __FILE__, \ + __LINE__); \ + } \ + } while (0) + +extern int cvmx_npi_max_pknds; + +/* + * Config Options + * + * These options have to be set via cvmx_helper_cfg_opt_set() before calling the + * routines that set up the hw. These routines process the options and set them + * correctly to take effect at runtime. + */ +enum cvmx_helper_cfg_option { + CVMX_HELPER_CFG_OPT_USE_DWB, /* + * Global option to control if + * the SDK configures units (DMA, + * SSO, and PKO) to send don't + * write back (DWB) requests for + * freed buffers. Set to 1/0 to + * enable/disable DWB. + * + * For programs that fit inside + * L2, sending DWB just causes + * more L2 operations without + * benefit. + */ + + CVMX_HELPER_CFG_OPT_MAX +}; + +typedef enum cvmx_helper_cfg_option cvmx_helper_cfg_option_t; + +struct cvmx_phy_info; +struct cvmx_fdt_sfp_info; +struct cvmx_vsc7224_chan; +struct phy_device; + +struct cvmx_srio_port_param { + /** True to override SRIO CTLE zero setting */ + bool srio_rx_ctle_zero_override : 1; + /** Equalization peaking control dft: 6 */ + u8 srio_rx_ctle_zero : 4; + /** Set true to override CTLE taps */ + bool srio_rx_ctle_agc_override : 1; + u8 srio_rx_agc_pre_ctle : 4; /** AGC pre-CTLE gain */ + u8 srio_rx_agc_post_ctle : 4; /** AGC post-CTLE gain */ + bool srio_tx_swing_override : 1; /** True to override TX Swing */ + u8 srio_tx_swing : 5; /** TX Swing */ + bool srio_tx_gain_override : 1; /** True to override TX gain */ + u8 srio_tx_gain : 3; /** TX gain */ + bool srio_tx_premptap_override : 1; /** True to override premptap values */ + u8 srio_tx_premptap_pre : 4; /** Pre premptap value */ + u8 srio_tx_premptap_post : 5; /** Post premptap value */ + bool srio_tx_vboost_override : 1; /** True to override TX vboost setting */ + bool srio_tx_vboost : 1; /** vboost setting (default 1) */ +}; + +/* + * Per physical port + * Note: This struct is passed between linux and SE apps. + */ +struct cvmx_cfg_port_param { + int port_fdt_node; /** Node offset in FDT of node */ + int phy_fdt_node; /** Node offset in FDT of PHY */ + struct cvmx_phy_info *phy_info; /** Data structure with PHY information */ + int8_t ccpp_pknd; + int8_t ccpp_bpid; + int8_t ccpp_pko_port_base; + int8_t ccpp_pko_num_ports; + u8 agl_rx_clk_skew; /** AGL rx clock skew setting (default 0) */ + u8 rgmii_tx_clk_delay; /** RGMII TX clock delay value if not bypassed */ + bool valid : 1; /** 1 = port valid, 0 = invalid */ + bool sgmii_phy_mode : 1; /** 1 = port in PHY mode, 0 = MAC mode */ + bool sgmii_1000x_mode : 1; /** 1 = 1000Base-X mode, 0 = SGMII mode */ + bool agl_rx_clk_delay_bypass : 1; /** 1 = use rx clock delay bypass for AGL mode */ + bool force_link_up : 1; /** Ignore PHY and always report link up */ + bool disable_an : 1; /** true to disable autonegotiation */ + bool link_down_pwr_dn : 1; /** Power PCS off when link is down */ + bool phy_present : 1; /** true if PHY is present */ + bool tx_clk_delay_bypass : 1; /** True to bypass the TX clock delay */ + bool enable_fec : 1; /** True to enable FEC for 10/40G links */ + /** Settings for short-run SRIO host */ + struct cvmx_srio_port_param srio_short; + /** Settings for long-run SRIO host */ + struct cvmx_srio_port_param srio_long; + u8 agl_refclk_sel; /** RGMII refclk select to use */ + /** Set if local (non-PHY) LEDs are used */ + struct cvmx_phy_gpio_leds *gpio_leds; + struct cvmx_fdt_sfp_info *sfp_info; /** SFP+/QSFP info for port */ + /** Offset of SFP/SFP+/QSFP slot in device tree */ + int sfp_of_offset; + /** Microsemi VSC7224 channel info data structure */ + struct cvmx_vsc7224_chan *vsc7224_chan; + /** Avago AVSP-5410 Phy */ + struct cvmx_avsp5410 *avsp5410; + struct phy_device *phydev; +}; + +/* + * Per pko_port + */ +struct cvmx_cfg_pko_port_param { + s16 ccppp_queue_base; + s16 ccppp_num_queues; +}; + +/* + * A map from pko_port to + * interface, + * index, and + * pko engine id + */ +struct cvmx_cfg_pko_port_map { + s16 ccppl_interface; + s16 ccppl_index; + s16 ccppl_eid; +}; + +/* + * This is for looking up pko_base_port and pko_nport for ipd_port + */ +struct cvmx_cfg_pko_port_pair { + int8_t ccppp_base_port; + int8_t ccppp_nports; +}; + +typedef union cvmx_user_static_pko_queue_config { + struct { + struct pko_queues_cfg { + unsigned queues_per_port : 11, qos_enable : 1, pfc_enable : 1; + } pko_cfg_iface[6]; + struct pko_queues_cfg pko_cfg_loop; + struct pko_queues_cfg pko_cfg_npi; + } pknd; + struct { + u8 pko_ports_per_interface[5]; + u8 pko_queues_per_port_interface[5]; + u8 pko_queues_per_port_loop; + u8 pko_queues_per_port_pci; + u8 pko_queues_per_port_srio[4]; + } non_pknd; +} cvmx_user_static_pko_queue_config_t; + +extern cvmx_user_static_pko_queue_config_t __cvmx_pko_queue_static_config[CVMX_MAX_NODES]; +extern struct cvmx_cfg_pko_port_map cvmx_cfg_pko_port_map[CVMX_HELPER_CFG_MAX_PKO_PORT]; +extern struct cvmx_cfg_port_param cvmx_cfg_port[CVMX_MAX_NODES][CVMX_HELPER_MAX_IFACE] + [CVMX_HELPER_CFG_MAX_PORT_PER_IFACE]; +extern struct cvmx_cfg_pko_port_param cvmx_pko_queue_table[]; +extern int cvmx_enable_helper_flag; + +/* + * @INTERNAL + * Return configured pknd for the port + * + * @param interface the interface number + * @param index the port's index number + * @return the pknd + */ +int __cvmx_helper_cfg_pknd(int interface, int index); + +/* + * @INTERNAL + * Return the configured bpid for the port + * + * @param interface the interface number + * @param index the port's index number + * @return the bpid + */ +int __cvmx_helper_cfg_bpid(int interface, int index); + +/** + * @INTERNAL + * Return the configured pko_port base for the port + * + * @param interface the interface number + * @param index the port's index number + * @return the pko_port base + */ +int __cvmx_helper_cfg_pko_port_base(int interface, int index); + +/* + * @INTERNAL + * Return the configured number of pko_ports for the port + * + * @param interface the interface number + * @param index the port's index number + * @return the number of pko_ports + */ +int __cvmx_helper_cfg_pko_port_num(int interface, int index); + +/* + * @INTERNAL + * Return the configured pko_queue base for the pko_port + * + * @param pko_port + * @return the pko_queue base + */ +int __cvmx_helper_cfg_pko_queue_base(int pko_port); + +/* + * @INTERNAL + * Return the configured number of pko_queues for the pko_port + * + * @param pko_port + * @return the number of pko_queues + */ +int __cvmx_helper_cfg_pko_queue_num(int pko_port); + +/* + * @INTERNAL + * Return the interface the pko_port is configured for + * + * @param pko_port + * @return the interface for the pko_port + */ +int __cvmx_helper_cfg_pko_port_interface(int pko_port); + +/* + * @INTERNAL + * Return the index of the port the pko_port is configured for + * + * @param pko_port + * @return the index of the port + */ +int __cvmx_helper_cfg_pko_port_index(int pko_port); + +/* + * @INTERNAL + * Return the pko_eid of the pko_port + * + * @param pko_port + * @return the pko_eid + */ +int __cvmx_helper_cfg_pko_port_eid(int pko_port); + +/* + * @INTERNAL + * Return the max# of pko queues allocated. + * + * @return the max# of pko queues + * + * Note: there might be holes in the queue space depending on user + * configuration. The function returns the highest queue's index in + * use. + */ +int __cvmx_helper_cfg_pko_max_queue(void); + +/* + * @INTERNAL + * Return the max# of PKO DMA engines allocated. + * + * @return the max# of DMA engines + * + * NOTE: the DMA engines are allocated contiguously and starting from + * 0. + */ +int __cvmx_helper_cfg_pko_max_engine(void); + +/* + * Get the value set for the config option ``opt''. + * + * @param opt is the config option. + * @return the value set for the option + * + * LR: only used for DWB in NPI, POW, PKO1 + */ +u64 cvmx_helper_cfg_opt_get(cvmx_helper_cfg_option_t opt); + +/* + * Set the value for a config option. + * + * @param opt is the config option. + * @param val is the value to set for the opt. + * @return 0 for success and -1 on error + * + * Note an option here is a config-time parameter and this means that + * it has to be set before calling the corresponding setup functions + * that actually sets the option in hw. + * + * LR: Not used. + */ +int cvmx_helper_cfg_opt_set(cvmx_helper_cfg_option_t opt, u64 val); + +/* + * Retrieve the pko_port base given ipd_port. + * + * @param ipd_port is the IPD eport + * @return the corresponding PKO port base for the physical port + * represented by the IPD eport or CVMX_HELPER_CFG_INVALID_VALUE. + */ +int cvmx_helper_cfg_ipd2pko_port_base(int ipd_port); + +/* + * Retrieve the number of pko_ports given ipd_port. + * + * @param ipd_port is the IPD eport + * @return the corresponding number of PKO ports for the physical port + * represented by IPD eport or CVMX_HELPER_CFG_INVALID_VALUE. + */ +int cvmx_helper_cfg_ipd2pko_port_num(int ipd_port); + +/* + * @INTERNAL + * The init function + * + * @param node + * @return 0 for success. + * + * Note: this function is meant to be called to set the ``configured + * parameters,'' e.g., pknd, bpid, etc. and therefore should be before + * any of the corresponding cvmx_helper_cfg_xxxx() functions are + * called. + */ +int __cvmx_helper_init_port_config_data(int node); + +/* + * @INTERNAL + * The local init function + * + * @param none + * @return 0 for success. + * + * Note: this function is meant to be called to set the ``configured + * parameters locally,'' e.g., pknd, bpid, etc. and therefore should be before + * any of the corresponding cvmx_helper_cfg_xxxx() functions are + * called. + */ +int __cvmx_helper_init_port_config_data_local(void); + +/* + * Set the frame max size and jabber size to 65535. + * + */ +void cvmx_helper_cfg_set_jabber_and_frame_max(void); + +/* + * Enable storing short packets only in the WQE. + */ +void cvmx_helper_cfg_store_short_packets_in_wqe(void); + +/* + * Allocated a block of internal ports and queues for the specified + * interface/port + * + * @param interface the interface for which the internal ports and queues + * are requested + * @param port the index of the port within in the interface for which + the internal ports and queues are requested. + * @param pot_count the number of internal ports requested + * @param queue_cnt the number of queues requested for each of the internal + * port. This call will allocate a total of + * (port_cnt * queue_cnt) queues + * + * @return 0 on success + * -1 on failure + * + * LR: Called ONLY from comfig-parse! + */ +int cvmx_pko_alloc_iport_and_queues(int interface, int port, int port_cnt, int queue_cnt); + +/* + * Free the queues that are associated with the specified port + * + * @param port the internal port for which the queues are freed. + * + * @return 0 on success + * -1 on failure + */ +int cvmx_pko_queue_free(u64 port); + +/* + * Initializes the pko queue range data structure. + * @return 0 on success + * -1 on failure + */ +int init_cvmx_pko_que_range(void); + +/* + * Frees up all the allocated ques. + */ +void cvmx_pko_queue_free_all(void); + +/** + * Returns if port is valid for a given interface + * + * @param xiface interface to check + * @param index port index in the interface + * + * @return status of the port present or not. + */ +int cvmx_helper_is_port_valid(int xiface, int index); + +/** + * Set whether or not a port is valid + * + * @param interface interface to set + * @param index port index to set + * @param valid set 0 to make port invalid, 1 for valid + */ +void cvmx_helper_set_port_valid(int interface, int index, bool valid); + +/** + * @INTERNAL + * Return if port is in PHY mode + * + * @param interface the interface number + * @param index the port's index number + * + * @return 1 if port is in PHY mode, 0 if port is in MAC mode + */ +bool cvmx_helper_get_mac_phy_mode(int interface, int index); +void cvmx_helper_set_mac_phy_mode(int interface, int index, bool valid); + +/** + * @INTERNAL + * Return if port is in 1000Base X mode + * + * @param interface the interface number + * @param index the port's index number + * + * @return 1 if port is in 1000Base X mode, 0 if port is in SGMII mode + */ +bool cvmx_helper_get_1000x_mode(int interface, int index); +void cvmx_helper_set_1000x_mode(int interface, int index, bool valid); + +/** + * @INTERNAL + * Return if an AGL port should bypass the RX clock delay + * + * @param interface the interface number + * @param index the port's index number + */ +bool cvmx_helper_get_agl_rx_clock_delay_bypass(int interface, int index); +void cvmx_helper_set_agl_rx_clock_delay_bypass(int interface, int index, bool valid); + +/** + * @INTERNAL + * Forces a link to always return that it is up ignoring the PHY (if present) + * + * @param interface the interface number + * @param index the port's index + */ +bool cvmx_helper_get_port_force_link_up(int interface, int index); +void cvmx_helper_set_port_force_link_up(int interface, int index, bool value); + +/** + * @INTERNAL + * Return true if PHY is present to the passed xiface + * + * @param xiface the interface number + * @param index the port's index + */ +bool cvmx_helper_get_port_phy_present(int xiface, int index); +void cvmx_helper_set_port_phy_present(int xiface, int index, bool value); + +/** + * @INTERNAL + * Return the AGL port rx clock skew, only used + * if agl_rx_clock_delay_bypass is set. + * + * @param interface the interface number + * @param index the port's index number + */ +u8 cvmx_helper_get_agl_rx_clock_skew(int interface, int index); +void cvmx_helper_set_agl_rx_clock_skew(int interface, int index, u8 value); +u8 cvmx_helper_get_agl_refclk_sel(int interface, int index); +void cvmx_helper_set_agl_refclk_sel(int interface, int index, u8 value); + +/** + * @INTERNAL + * Store the FDT node offset in the device tree of a port + * + * @param xiface node and interface + * @param index port index + * @param node_offset node offset to store + */ +void cvmx_helper_set_port_fdt_node_offset(int xiface, int index, int node_offset); + +/** + * @INTERNAL + * Return the FDT node offset in the device tree of a port + * + * @param xiface node and interface + * @param index port index + * @return node offset of port or -1 if invalid + */ +int cvmx_helper_get_port_fdt_node_offset(int xiface, int index); + +/** + * @INTERNAL + * Store the FDT node offset in the device tree of a phy + * + * @param xiface node and interface + * @param index port index + * @param node_offset node offset to store + */ +void cvmx_helper_set_phy_fdt_node_offset(int xiface, int index, int node_offset); + +/** + * @INTERNAL + * Return the FDT node offset in the device tree of a phy + * + * @param xiface node and interface + * @param index port index + * @return node offset of phy or -1 if invalid + */ +int cvmx_helper_get_phy_fdt_node_offset(int xiface, int index); + +/** + * @INTERNAL + * Override default autonegotiation for a port + * + * @param xiface node and interface + * @param index port index + * @param enable true to enable autonegotiation, false to force full + * duplex, full speed. + */ +void cvmx_helper_set_port_autonegotiation(int xiface, int index, bool enable); + +/** + * @INTERNAL + * Returns if autonegotiation is enabled or not. + * + * @param xiface node and interface + * @param index port index + * + * @return 0 if autonegotiation is disabled, 1 if enabled. + */ +bool cvmx_helper_get_port_autonegotiation(int xiface, int index); + +/** + * @INTERNAL + * Returns if forward error correction is enabled or not. + * + * @param xiface node and interface + * @param index port index + * + * @return 0 if fec is disabled, 1 if enabled. + */ +bool cvmx_helper_get_port_fec(int xiface, int index); + +/** + * @INTERNAL + * Override default forward error correction for a port + * + * @param xiface node and interface + * @param index port index + * @param enable true to enable fec, false to disable. + */ +void cvmx_helper_set_port_fec(int xiface, int index, bool enable); + +/** + * @INTERNAL + * Configure the SRIO RX interface AGC settings in host mode + * + * @param xiface node and interface + * @param index lane + * @param long_run true for long run, false for short run + * @param agc_override true to put AGC in manual mode + * @param ctle_zero RX equalizer peaking control (default 0x6) + * @param agc_pre_ctle AGC pre-CTLE gain (default 0x5) + * @param agc_post_ctle AGC post-CTLE gain (default 0x4) + * + * NOTE: This must be called before SRIO is initialized to take effect + */ +void cvmx_helper_set_srio_rx(int xiface, int index, bool long_run, bool ctle_zero_override, + u8 ctle_zero, bool agc_override, u8 agc_pre_ctle, u8 agc_post_ctle); + +/** + * @INTERNAL + * Get the SRIO RX interface AGC settings for host mode + * + * @param xiface node and interface + * @param index lane + * @param long_run true for long run, false for short run + * @param[out] ctle_zero_override true if overridden + * @param[out] ctle_zero RX equalizer peaking control (default 0x6) + * @param[out] agc_override true to put AGC in manual mode + * @param[out] agc_pre_ctle AGC pre-CTLE gain (default 0x5) + * @param[out] agc_post_ctle AGC post-CTLE gain (default 0x4) + */ +void cvmx_helper_get_srio_rx(int xiface, int index, bool long_run, bool *ctle_zero_override, + u8 *ctle_zero, bool *agc_override, u8 *agc_pre_ctle, + u8 *agc_post_ctle); + +/** + * @INTERNAL + * Configure the SRIO TX interface for host mode + * + * @param xiface node and interface + * @param index lane + * @param long_run true for long run, false for short run + * @param tx_swing tx swing value to use (default 0x7), -1 to not + * override. + * @param tx_gain PCS SDS TX gain (default 0x3), -1 to not + * override + * @param tx_premptap_override true to override preemphasis control + * @param tx_premptap_pre preemphasis pre tap value (default 0x0) + * @param tx_premptap_post preemphasis post tap value (default 0xF) + * @param tx_vboost vboost enable (1 = enable, -1 = don't override) + * hardware default is 1. + * + * NOTE: This must be called before SRIO is initialized to take effect + */ +void cvmx_helper_set_srio_tx(int xiface, int index, bool long_run, int tx_swing, int tx_gain, + bool tx_premptap_override, u8 tx_premptap_pre, u8 tx_premptap_post, + int tx_vboost); + +/** + * @INTERNAL + * Get the SRIO TX interface settings for host mode + * + * @param xiface node and interface + * @param index lane + * @param long_run true for long run, false for short run + * @param[out] tx_swing_override true to override pcs_sds_txX_swing + * @param[out] tx_swing tx swing value to use (default 0x7) + * @param[out] tx_gain_override true to override default gain + * @param[out] tx_gain PCS SDS TX gain (default 0x3) + * @param[out] tx_premptap_override true to override preemphasis control + * @param[out] tx_premptap_pre preemphasis pre tap value (default 0x0) + * @param[out] tx_premptap_post preemphasis post tap value (default 0xF) + * @param[out] tx_vboost_override override vboost setting + * @param[out] tx_vboost vboost enable (default true) + */ +void cvmx_helper_get_srio_tx(int xiface, int index, bool long_run, bool *tx_swing_override, + u8 *tx_swing, bool *tx_gain_override, u8 *tx_gain, + bool *tx_premptap_override, u8 *tx_premptap_pre, u8 *tx_premptap_post, + bool *tx_vboost_override, bool *tx_vboost); + +/** + * @INTERNAL + * Sets the PHY info data structure + * + * @param xiface node and interface + * @param index port index + * @param[in] phy_info phy information data structure pointer + */ +void cvmx_helper_set_port_phy_info(int xiface, int index, struct cvmx_phy_info *phy_info); +/** + * @INTERNAL + * Returns the PHY information data structure for a port + * + * @param xiface node and interface + * @param index port index + * + * @return pointer to PHY information data structure or NULL if not set + */ +struct cvmx_phy_info *cvmx_helper_get_port_phy_info(int xiface, int index); + +/** + * @INTERNAL + * Returns a pointer to the PHY LED configuration (if local GPIOs drive them) + * + * @param xiface node and interface + * @param index portindex + * + * @return pointer to the PHY LED information data structure or NULL if not + * present + */ +struct cvmx_phy_gpio_leds *cvmx_helper_get_port_phy_leds(int xiface, int index); + +/** + * @INTERNAL + * Sets a pointer to the PHY LED configuration (if local GPIOs drive them) + * + * @param xiface node and interface + * @param index portindex + * @param leds pointer to led data structure + */ +void cvmx_helper_set_port_phy_leds(int xiface, int index, struct cvmx_phy_gpio_leds *leds); + +/** + * @INTERNAL + * Disables RGMII TX clock bypass and sets delay value + * + * @param xiface node and interface + * @param index portindex + * @param bypass Set true to enable the clock bypass and false + * to sync clock and data synchronously. + * Default is false. + * @param clk_delay Delay value to skew TXC from TXD + */ +void cvmx_helper_cfg_set_rgmii_tx_clk_delay(int xiface, int index, bool bypass, int clk_delay); + +/** + * @INTERNAL + * Gets RGMII TX clock bypass and delay value + * + * @param xiface node and interface + * @param index portindex + * @param bypass Set true to enable the clock bypass and false + * to sync clock and data synchronously. + * Default is false. + * @param clk_delay Delay value to skew TXC from TXD, default is 0. + */ +void cvmx_helper_cfg_get_rgmii_tx_clk_delay(int xiface, int index, bool *bypass, int *clk_delay); + +/** + * @INTERNAL + * Retrieve node-specific PKO Queue configuration. + * + * @param node OCTEON3 node. + * @param pkocfg PKO Queue static configuration. + */ +int cvmx_helper_pko_queue_config_get(int node, cvmx_user_static_pko_queue_config_t *cfg); + +/** + * @INTERNAL + * Update node-specific PKO Queue configuration. + * + * @param node OCTEON3 node. + * @param pkocfg PKO Queue static configuration. + */ +int cvmx_helper_pko_queue_config_set(int node, cvmx_user_static_pko_queue_config_t *cfg); + +/** + * @INTERNAL + * Retrieve the SFP node offset in the device tree + * + * @param xiface node and interface + * @param index port index + * + * @return offset in device tree or -1 if error or not defined. + */ +int cvmx_helper_cfg_get_sfp_fdt_offset(int xiface, int index); + +/** + * Search for a port based on its FDT node offset + * + * @param of_offset Node offset of port to search for + * + * @return ipd_port or -1 if not found + */ +int cvmx_helper_cfg_get_ipd_port_by_fdt_node_offset(int of_offset); + +/** + * @INTERNAL + * Sets the SFP node offset + * + * @param xiface node and interface + * @param index port index + * @param sfp_of_offset Offset of SFP node in device tree + */ +void cvmx_helper_cfg_set_sfp_fdt_offset(int xiface, int index, int sfp_of_offset); + +/** + * Search for a port based on its FDT node offset + * + * @param of_offset Node offset of port to search for + * @param[out] xiface xinterface of match + * @param[out] index port index of match + * + * @return 0 if found, -1 if not found + */ +int cvmx_helper_cfg_get_xiface_index_by_fdt_node_offset(int of_offset, int *xiface, int *index); + +/** + * Get data structure defining the Microsemi VSC7224 channel info + * or NULL if not present + * + * @param xiface node and interface + * @param index port index + * + * @return pointer to vsc7224 data structure or NULL if not present + */ +struct cvmx_vsc7224_chan *cvmx_helper_cfg_get_vsc7224_chan_info(int xiface, int index); + +/** + * Sets the Microsemi VSC7224 channel data structure + * + * @param xiface node and interface + * @param index port index + * @param[in] vsc7224_info Microsemi VSC7224 data structure + */ +void cvmx_helper_cfg_set_vsc7224_chan_info(int xiface, int index, + struct cvmx_vsc7224_chan *vsc7224_chan_info); + +/** + * Get data structure defining the Avago AVSP5410 phy info + * or NULL if not present + * + * @param xiface node and interface + * @param index port index + * + * @return pointer to avsp5410 data structure or NULL if not present + */ +struct cvmx_avsp5410 *cvmx_helper_cfg_get_avsp5410_info(int xiface, int index); + +/** + * Sets the Avago AVSP5410 phy info data structure + * + * @param xiface node and interface + * @param index port index + * @param[in] avsp5410_info Avago AVSP5410 data structure + */ +void cvmx_helper_cfg_set_avsp5410_info(int xiface, int index, struct cvmx_avsp5410 *avsp5410_info); + +/** + * Gets the SFP data associated with a port + * + * @param xiface node and interface + * @param index port index + * + * @return pointer to SFP data structure or NULL if none + */ +struct cvmx_fdt_sfp_info *cvmx_helper_cfg_get_sfp_info(int xiface, int index); + +/** + * Sets the SFP data associated with a port + * + * @param xiface node and interface + * @param index port index + * @param[in] sfp_info port SFP data or NULL for none + */ +void cvmx_helper_cfg_set_sfp_info(int xiface, int index, struct cvmx_fdt_sfp_info *sfp_info); + +/* + * Initializes cvmx with user specified config info. + */ +int cvmx_user_static_config(void); +void cvmx_pko_queue_show(void); +int cvmx_fpa_pool_init_from_cvmx_config(void); +int __cvmx_helper_init_port_valid(void); + +/** + * Returns a pointer to the phy device associated with a port + * + * @param xiface node and interface + * @param index port index + * + * return pointer to phy device or NULL if none + */ +struct phy_device *cvmx_helper_cfg_get_phy_device(int xiface, int index); + +/** + * Sets the phy device associated with a port + * + * @param xiface node and interface + * @param index port index + * @param[in] phydev phy device to assiciate + */ +void cvmx_helper_cfg_set_phy_device(int xiface, int index, struct phy_device *phydev); + +#endif /* __CVMX_HELPER_CFG_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-errata.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-errata.h new file mode 100644 index 0000000000..9ed13c1626 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-errata.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Fixes and workaround for Octeon chip errata. This file + * contains functions called by cvmx-helper to workaround known + * chip errata. For the most part, code doesn't need to call + * these functions directly. + */ + +#ifndef __CVMX_HELPER_ERRATA_H__ +#define __CVMX_HELPER_ERRATA_H__ + +#include "cvmx-wqe.h" + +/** + * @INTERNAL + * Function to adjust internal IPD pointer alignments + * + * @return 0 on success + * !0 on failure + */ +int __cvmx_helper_errata_fix_ipd_ptr_alignment(void); + +/** + * This function needs to be called on all Octeon chips with + * errata PKI-100. + * + * The Size field is 8 too large in WQE and next pointers + * + * The Size field generated by IPD is 8 larger than it should + * be. The Size field is <55:40> of both: + * - WORD3 in the work queue entry, and + * - the next buffer pointer (which precedes the packet data + * in each buffer). + * + * @param work Work queue entry to fix + * @return Zero on success. Negative on failure + */ +int cvmx_helper_fix_ipd_packet_chain(cvmx_wqe_t *work); + +/** + * Due to errata G-720, the 2nd order CDR circuit on CN52XX pass + * 1 doesn't work properly. The following code disables 2nd order + * CDR for the specified QLM. + * + * @param qlm QLM to disable 2nd order CDR for. + */ +void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm); +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h new file mode 100644 index 0000000000..d3809aec29 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-fdt.h @@ -0,0 +1,568 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * FDT Helper functions similar to those provided to U-Boot. + * If compiled for U-Boot, just provide wrappers to the equivalent U-Boot + * functions. + */ + +#ifndef __CVMX_HELPER_FDT_H__ +#define __CVMX_HELPER_FDT_H__ + +#include +#include +#include +#include +#include + +#include + +enum cvmx_i2c_bus_type { + CVMX_I2C_BUS_OCTEON, + CVMX_I2C_MUX_PCA9540, + CVMX_I2C_MUX_PCA9542, + CVMX_I2C_MUX_PCA9543, + CVMX_I2C_MUX_PCA9544, + CVMX_I2C_MUX_PCA9545, + CVMX_I2C_MUX_PCA9546, + CVMX_I2C_MUX_PCA9547, + CVMX_I2C_MUX_PCA9548, + CVMX_I2C_MUX_OTHER +}; + +struct cvmx_sfp_mod_info; /** Defined in cvmx-helper-sfp.h */ +struct cvmx_phy_info; /** Defined in cvmx-helper-board.h */ + +/** + * This data structure holds information about various I2C muxes and switches + * that may be between a device and the Octeon chip. + */ +struct cvmx_fdt_i2c_bus_info { + /** Parent I2C bus, NULL if root */ + struct cvmx_fdt_i2c_bus_info *parent; + /** Child I2C bus or NULL if last entry in the chain */ + struct cvmx_fdt_i2c_bus_info *child; + /** Offset in device tree */ + int of_offset; + /** Type of i2c bus or mux */ + enum cvmx_i2c_bus_type type; + /** I2C address of mux */ + u8 i2c_addr; + /** Mux channel number */ + u8 channel; + /** For muxes, the bit(s) to set to enable them */ + u8 enable_bit; + /** True if mux, false if switch */ + bool is_mux; +}; + +/** + * Data structure containing information about SFP/QSFP slots + */ +struct cvmx_fdt_sfp_info { + /** Used for a linked list of slots */ + struct cvmx_fdt_sfp_info *next, *prev; + /** Used when multiple SFP ports share the same IPD port */ + struct cvmx_fdt_sfp_info *next_iface_sfp; + /** Name from device tree of slot */ + const char *name; + /** I2C bus for slot EEPROM */ + struct cvmx_fdt_i2c_bus_info *i2c_bus; + /** Data from SFP or QSFP EEPROM */ + struct cvmx_sfp_mod_info sfp_info; + /** Data structure with PHY information */ + struct cvmx_phy_info *phy_info; + /** IPD port(s) slot is connected to */ + int ipd_port[4]; + /** Offset in device tree of slot */ + int of_offset; + /** EEPROM address of SFP module (usually 0x50) */ + u8 i2c_eeprom_addr; + /** Diagnostic address of SFP module (usually 0x51) */ + u8 i2c_diag_addr; + /** True if QSFP module */ + bool is_qsfp; + /** True if EEPROM data is valid */ + bool valid; + /** SFP tx_disable GPIO descriptor */ + struct cvmx_fdt_gpio_info *tx_disable; + /** SFP mod_abs/QSFP mod_prs GPIO descriptor */ + struct cvmx_fdt_gpio_info *mod_abs; + /** SFP tx_error GPIO descriptor */ + struct cvmx_fdt_gpio_info *tx_error; + /** SFP rx_los GPIO discriptor */ + struct cvmx_fdt_gpio_info *rx_los; + /** QSFP select GPIO descriptor */ + struct cvmx_fdt_gpio_info *select; + /** QSFP reset GPIO descriptor */ + struct cvmx_fdt_gpio_info *reset; + /** QSFP interrupt GPIO descriptor */ + struct cvmx_fdt_gpio_info *interrupt; + /** QSFP lp_mode GPIO descriptor */ + struct cvmx_fdt_gpio_info *lp_mode; + /** Last mod_abs value */ + int last_mod_abs; + /** Last rx_los value */ + int last_rx_los; + /** Function to call to check mod_abs */ + int (*check_mod_abs)(struct cvmx_fdt_sfp_info *sfp_info, void *data); + /** User-defined data to pass to check_mod_abs */ + void *mod_abs_data; + /** Function to call when mod_abs changes */ + int (*mod_abs_changed)(struct cvmx_fdt_sfp_info *sfp_info, int val, void *data); + /** User-defined data to pass to mod_abs_changed */ + void *mod_abs_changed_data; + /** Function to call when rx_los changes */ + int (*rx_los_changed)(struct cvmx_fdt_sfp_info *sfp_info, int val, void *data); + /** User-defined data to pass to rx_los_changed */ + void *rx_los_changed_data; + /** True if we're connected to a Microsemi VSC7224 reclocking chip */ + bool is_vsc7224; + /** Data structure for first vsc7224 channel we're attached to */ + struct cvmx_vsc7224_chan *vsc7224_chan; + /** True if we're connected to a Avago AVSP5410 phy */ + bool is_avsp5410; + /** Data structure for avsp5410 phy we're attached to */ + struct cvmx_avsp5410 *avsp5410; + /** xinterface we're on */ + int xiface; + /** port index */ + int index; +}; + +/** + * Look up a phandle and follow it to its node then return the offset of that + * node. + * + * @param[in] fdt_addr pointer to FDT blob + * @param node node to read phandle from + * @param[in] prop_name name of property to find + * @param[in,out] lenp Number of phandles, input max number + * @param[out] nodes Array of phandle nodes + * + * @return -ve error code on error or 0 for success + */ +int cvmx_fdt_lookup_phandles(const void *fdt_addr, int node, const char *prop_name, int *lenp, + int *nodes); + +/** + * Helper to return the address property + * + * @param[in] fdt_addr pointer to FDT blob + * @param node node to read address from + * @param prop_name property name to read + * + * @return address of property or FDT_ADDR_T_NONE if not found + */ +static inline fdt_addr_t cvmx_fdt_get_addr(const void *fdt_addr, int node, const char *prop_name) +{ + return fdtdec_get_addr(fdt_addr, node, prop_name); +} + +/** + * Helper function to return an integer property + * + * @param[in] fdt_addr pointer to FDT blob + * @param node node to read integer from + * @param[in] prop_name property name to read + * @param default_val default value to return if property doesn't exist + * + * @return integer value of property or default_val if it doesn't exist. + */ +static inline int cvmx_fdt_get_int(const void *fdt_addr, int node, const char *prop_name, + int default_val) +{ + return fdtdec_get_int(fdt_addr, node, prop_name, default_val); +} + +static inline bool cvmx_fdt_get_bool(const void *fdt_addr, int node, const char *prop_name) +{ + return fdtdec_get_bool(fdt_addr, node, prop_name); +} + +static inline u64 cvmx_fdt_get_uint64(const void *fdt_addr, int node, const char *prop_name, + u64 default_val) +{ + return fdtdec_get_uint64(fdt_addr, node, prop_name, default_val); +} + +/** + * Look up a phandle and follow it to its node then return the offset of that + * node. + * + * @param[in] fdt_addr pointer to FDT blob + * @param node node to read phandle from + * @param[in] prop_name name of property to find + * + * @return node offset if found, -ve error code on error + */ +static inline int cvmx_fdt_lookup_phandle(const void *fdt_addr, int node, const char *prop_name) +{ + return fdtdec_lookup_phandle(fdt_addr, node, prop_name); +} + +/** + * Translate an address from the device tree into a CPU physical address by + * walking up the device tree and applying bus mappings along the way. + * + * This uses #size-cells and #address-cells. + * + * @param[in] fdt_addr Address of flat device tree + * @param node node to start translating from + * @param[in] in_addr Address to translate + * NOTE: in_addr must be in the native ENDIAN + * format. + * + * @return Translated address or FDT_ADDR_T_NONE if address cannot be + * translated. + */ +static inline u64 cvmx_fdt_translate_address(const void *fdt_addr, int node, const u32 *in_addr) +{ + return fdt_translate_address((void *)fdt_addr, node, in_addr); +} + +/** + * Compare compatibile strings in the flat device tree. + * + * @param[in] s1 First string to compare + * @param[in] sw Second string to compare + * + * @return 0 if no match + * 1 if only the part number matches and not the manufacturer + * 2 if both the part number and manufacturer match + */ +int cvmx_fdt_compat_match(const char *s1, const char *s2); + +/** + * Returns whether a list of strings contains the specified string + * + * @param[in] slist String list + * @param llen string list total length + * @param[in] str string to search for + * + * @return 1 if string list contains string, 0 if it does not. + */ +int cvmx_fdt_compat_list_contains(const char *slist, int llen, const char *str); + +/** + * Check if a node is compatible with the specified compat string + * + * @param[in] fdt_addr FDT address + * @param node node offset to check + * @param[in] compat compatible string to check + * + * @return 0 if compatible, 1 if not compatible, error if negative + */ +int cvmx_fdt_node_check_compatible(const void *fdt_addr, int node, const char *compat); + +/** + * @INTERNAL + * Compares a string to a compatible field. + * + * @param[in] compat compatible string + * @param[in] str string to check + * + * @return 0 if not compatible, 1 if manufacturer compatible, 2 if + * part is compatible, 3 if both part and manufacturer are + * compatible. + */ +int __cvmx_fdt_compat_match(const char *compat, const char *str); + +/** + * Given a phandle to a GPIO device return the type of GPIO device it is. + * + * @param[in] fdt_addr Address of flat device tree + * @param phandle phandle to GPIO + * @param[out] size Number of pins (optional, may be NULL) + * + * @return Type of GPIO device or PIN_ERROR if error + */ +enum cvmx_gpio_type cvmx_fdt_get_gpio_type(const void *fdt_addr, int phandle, int *size); + +/** + * Given a phandle to a GPIO node output the i2c bus and address + * + * @param[in] fdt_addr Address of FDT + * @param phandle phandle of GPIO device + * @param[out] bus TWSI bus number with node in bits 1-3, can be + * NULL for none. + * @param[out] addr TWSI address number, can be NULL for none + * + * @return 0 for success, error otherwise + */ +int cvmx_fdt_get_twsi_gpio_bus_addr(const void *fdt_addr, int phandle, int *bus, int *addr); + +/** + * Given a FDT node return the CPU node number + * + * @param[in] fdt_addr Address of FDT + * @param node FDT node number + * + * @return CPU node number or error if negative + */ +int cvmx_fdt_get_cpu_node(const void *fdt_addr, int node); + +/** + * Get the total size of the flat device tree + * + * @param[in] fdt_addr Address of FDT + * + * @return Size of flat device tree in bytes or -1 if error. + */ +int cvmx_fdt_get_fdt_size(const void *fdt_addr); + +/** + * Returns if a node is compatible with one of the items in the string list + * + * @param[in] fdt_addr Pointer to flat device tree + * @param node Node offset to check + * @param[in] strlist Array of FDT device compatibility strings, + * must end with NULL or empty string. + * + * @return 0 if at least one item matches, 1 if no matches + */ +int cvmx_fdt_node_check_compatible_list(const void *fdt_addr, int node, const char *const *strlist); + +/** + * Given a FDT node, return the next compatible node. + * + * @param[in] fdt_addr Pointer to flat device tree + * @param start_offset Starting node offset or -1 to find the first + * @param strlist Array of FDT device compatibility strings, must + * end with NULL or empty string. + * + * @return next matching node or -1 if no more matches. + */ +int cvmx_fdt_node_offset_by_compatible_list(const void *fdt_addr, int startoffset, + const char *const *strlist); + +/** + * Given the parent offset of an i2c device build up a list describing the bus + * which can contain i2c muxes and switches. + * + * @param[in] fdt_addr address of device tree + * @param of_offset Offset of the parent node of a GPIO device in + * the device tree. + * + * @return pointer to list of i2c devices starting from the root which + * can include i2c muxes and switches or NULL if error. Note that + * all entries are allocated on the heap. + * + * @see cvmx_fdt_free_i2c_bus() + */ +struct cvmx_fdt_i2c_bus_info *cvmx_fdt_get_i2c_bus(const void *fdt_addr, int of_offset); + +/** + * Return the Octeon bus number for a bus descriptor + * + * @param[in] bus bus descriptor + * + * @return Octeon twsi bus number or -1 on error + */ +int cvmx_fdt_i2c_get_root_bus(const struct cvmx_fdt_i2c_bus_info *bus); + +/** + * Frees all entries for an i2c bus descriptor + * + * @param bus bus to free + * + * @return 0 + */ +int cvmx_fdt_free_i2c_bus(struct cvmx_fdt_i2c_bus_info *bus); + +/** + * Given the bus to a device, enable it. + * + * @param[in] bus i2c bus descriptor to enable or disable + * @param enable set to true to enable, false to disable + * + * @return 0 for success or -1 for invalid bus + * + * This enables the entire bus including muxes and switches in the path. + */ +int cvmx_fdt_enable_i2c_bus(const struct cvmx_fdt_i2c_bus_info *bus, bool enable); + +/** + * Return a GPIO handle given a GPIO phandle of the form <&gpio pin flags> + * + * @param[in] fdt_addr Address of flat device tree + * @param of_offset node offset for property + * @param prop_name name of property + * + * @return pointer to GPIO handle or NULL if error + */ +struct cvmx_fdt_gpio_info *cvmx_fdt_gpio_get_info_phandle(const void *fdt_addr, int of_offset, + const char *prop_name); + +/** + * Sets a GPIO pin given the GPIO descriptor + * + * @param pin GPIO pin descriptor + * @param value value to set it to, 0 or 1 + * + * @return 0 on success, -1 on error. + * + * NOTE: If the CVMX_GPIO_ACTIVE_LOW flag is set then the output value will be + * inverted. + */ +int cvmx_fdt_gpio_set(struct cvmx_fdt_gpio_info *pin, int value); + +/** + * Given a GPIO pin descriptor, input the value of that pin + * + * @param pin GPIO pin descriptor + * + * @return 0 if low, 1 if high, -1 on error. Note that the input will be + * inverted if the CVMX_GPIO_ACTIVE_LOW flag bit is set. + */ +int cvmx_fdt_gpio_get(struct cvmx_fdt_gpio_info *pin); + +/** + * Assigns an IPD port to a SFP slot + * + * @param sfp Handle to SFP data structure + * @param ipd_port Port to assign it to + * + * @return 0 for success, -1 on error + */ +int cvmx_sfp_set_ipd_port(struct cvmx_fdt_sfp_info *sfp, int ipd_port); + +/** + * Get the IPD port of a SFP slot + * + * @param[in] sfp Handle to SFP data structure + * + * @return IPD port number for SFP slot + */ +static inline int cvmx_sfp_get_ipd_port(const struct cvmx_fdt_sfp_info *sfp) +{ + return sfp->ipd_port[0]; +} + +/** + * Get the IPD ports for a QSFP port + * + * @param[in] sfp Handle to SFP data structure + * @param[out] ipd_ports IPD ports for each lane, if running as 40G then + * only ipd_ports[0] is valid and the others will + * be set to -1. + */ +static inline void cvmx_qsfp_get_ipd_ports(const struct cvmx_fdt_sfp_info *sfp, int ipd_ports[4]) +{ + int i; + + for (i = 0; i < 4; i++) + ipd_ports[i] = sfp->ipd_port[i]; +} + +/** + * Attaches a PHY to a SFP or QSFP. + * + * @param sfp sfp to attach PHY to + * @param phy_info phy descriptor to attach or NULL to detach + */ +void cvmx_sfp_attach_phy(struct cvmx_fdt_sfp_info *sfp, struct cvmx_phy_info *phy_info); + +/** + * Returns a phy descriptor for a SFP slot + * + * @param[in] sfp SFP to get phy info from + * + * @return phy descriptor or NULL if none. + */ +static inline struct cvmx_phy_info *cvmx_sfp_get_phy_info(const struct cvmx_fdt_sfp_info *sfp) +{ + return sfp->phy_info; +} + +/** + * @INTERNAL + * Parses all instances of the Vitesse VSC7224 reclocking chip + * + * @param[in] fdt_addr Address of flat device tree + * + * @return 0 for success, error otherwise + */ +int __cvmx_fdt_parse_vsc7224(const void *fdt_addr); + +/** + * @INTERNAL + * Parses all instances of the Avago AVSP5410 gearbox phy + * + * @param[in] fdt_addr Address of flat device tree + * + * @return 0 for success, error otherwise + */ +int __cvmx_fdt_parse_avsp5410(const void *fdt_addr); + +/** + * Parse SFP information from device tree + * + * @param[in] fdt_addr Address of flat device tree + * + * @return pointer to sfp info or NULL if error + */ +struct cvmx_fdt_sfp_info *cvmx_helper_fdt_parse_sfp_info(const void *fdt_addr, int of_offset); + +/** + * @INTERNAL + * Parses either a CS4343 phy or a slice of the phy from the device tree + * @param[in] fdt_addr Address of FDT + * @param of_offset offset of slice or phy in device tree + * @param phy_info phy_info data structure to fill in + * + * @return 0 for success, -1 on error + */ +int cvmx_fdt_parse_cs4343(const void *fdt_addr, int of_offset, struct cvmx_phy_info *phy_info); + +/** + * Given an i2c bus and device address, write an 8 bit value + * + * @param bus i2c bus number + * @param addr i2c device address (7 bits) + * @param val 8-bit value to write + * + * This is just an abstraction to ease support in both U-Boot and SE. + */ +void cvmx_fdt_i2c_reg_write(int bus, int addr, u8 val); + +/** + * Read an 8-bit value from an i2c bus and device address + * + * @param bus i2c bus number + * @param addr i2c device address (7 bits) + * + * @return 8-bit value or error if negative + */ +int cvmx_fdt_i2c_reg_read(int bus, int addr); + +/** + * Write an 8-bit value to a register indexed i2c device + * + * @param bus i2c bus number to write to + * @param addr i2c device address (7 bits) + * @param reg i2c 8-bit register address + * @param val 8-bit value to write + * + * @return 0 for success, otherwise error + */ +int cvmx_fdt_i2c_write8(int bus, int addr, int reg, u8 val); + +/** + * Read an 8-bit value from a register indexed i2c device + * + * @param bus i2c bus number to write to + * @param addr i2c device address (7 bits) + * @param reg i2c 8-bit register address + * + * @return value or error if negative + */ +int cvmx_fdt_i2c_read8(int bus, int addr, int reg); + +int cvmx_sfp_vsc7224_mod_abs_changed(struct cvmx_fdt_sfp_info *sfp_info, + int val, void *data); +int cvmx_sfp_avsp5410_mod_abs_changed(struct cvmx_fdt_sfp_info *sfp_info, + int val, void *data); + +#endif /* CVMX_HELPER_FDT_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-fpa.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-fpa.h new file mode 100644 index 0000000000..8b3a89bce4 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-fpa.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper functions for FPA setup. + */ + +#ifndef __CVMX_HELPER_H_FPA__ +#define __CVMX_HELPER_H_FPA__ + +/** + * Allocate memory and initialize the FPA pools using memory + * from cvmx-bootmem. Sizes of each element in the pools is + * controlled by the cvmx-config.h header file. Specifying + * zero for any parameter will cause that FPA pool to not be + * setup. This is useful if you aren't using some of the + * hardware and want to save memory. + * + * @param packet_buffers + * Number of packet buffers to allocate + * @param work_queue_entries + * Number of work queue entries + * @param pko_buffers + * PKO Command buffers. You should at minimum have two per + * each PKO queue. + * @param tim_buffers + * TIM ring buffer command queues. At least two per timer bucket + * is recommended. + * @param dfa_buffers + * DFA command buffer. A relatively small (32 for example) + * number should work. + * @return Zero on success, non-zero if out of memory + */ +int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries, int pko_buffers, + int tim_buffers, int dfa_buffers); + +int __cvmx_helper_initialize_fpa_pool(int pool, u64 buffer_size, u64 buffers, const char *name); + +int cvmx_helper_shutdown_fpa_pools(int node); + +void cvmx_helper_fpa_dump(int node); + +#endif /* __CVMX_HELPER_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-gpio.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-gpio.h new file mode 100644 index 0000000000..787eccf4aa --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-gpio.h @@ -0,0 +1,427 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Defines some GPIO information used in multiple places + */ + +#ifndef __CVMX_HELPER_GPIO_H__ +#define __CVMX_HELPER_GPIO_H__ + +#define CVMX_GPIO_NAME_LEN 32 /** Length of name */ + +enum cvmx_gpio_type { + CVMX_GPIO_PIN_OCTEON, /** GPIO pin is directly connected to OCTEON */ + CVMX_GPIO_PIN_PCA953X, /** GPIO pin is NXP PCA953X compat chip */ + CVMX_GPIO_PIN_PCA957X, + CVMX_GPIO_PIN_PCF857X, /** GPIO pin is NXP PCF857X compat chip */ + CVMX_GPIO_PIN_PCA9698, /** GPIO pin is NXP PCA9698 compat chip */ + CVMX_GPIO_PIN_CS4343, /** Inphi/Cortina CS4343 GPIO pins */ + CVMX_GPIO_PIN_OTHER, /** GPIO pin is something else */ +}; + +enum cvmx_gpio_operation { + CVMX_GPIO_OP_CONFIG, /** Initial configuration of the GPIO pin */ + CVMX_GPIO_OP_SET, /** Set pin */ + CVMX_GPIO_OP_CLEAR, /** Clear pin */ + CVMX_GPIO_OP_READ, /** Read pin */ + CVMX_GPIO_OP_TOGGLE, /** Toggle pin */ + CVMX_GPIO_OP_BLINK_START, /** Put in blink mode (if supported) */ + CVMX_GPIO_OP_BLINK_STOP, /** Takes the pin out of blink mode */ + CVMX_GPIO_OP_SET_LINK, /** Put in link monitoring mode */ + CVMX_GPIO_OP_SET_ACT, /** Put in RX activity mode */ +}; + +/** + * Inphi CS4343 output source select values for the GPIO_GPIOX output_src_sel. + */ +enum cvmx_inphi_cs4343_gpio_gpio_output_src_sel { + GPIO_SEL_DRIVE = 0, /** Value of GPIOX_DRIVE */ + GPIO_SEL_DELAY = 1, /** Drive delayed */ + GPIO_SEL_TOGGLE = 2, /** Used for blinking */ + GPIO_SEL_EXT = 3, /** External function */ + GPIO_SEL_EXT_DELAY = 4, /** External function delayed */ +}; + +/** Inphi GPIO_GPIOX configuration register */ +union cvmx_inphi_cs4343_gpio_cfg_reg { + u16 u; + struct { +u16: 4; + /** Data source for the GPIO output */ + u16 output_src_sel : 3; + /** 1 = GPIO output is inverted before being output */ + u16 invert_output : 1; + /** 1 = GPIO input is inverted before being processed */ + u16 invert_input : 1; + /** 0 = 2.5v/1.8v signalling, 1 = 1.2v signalling */ + u16 iovddsel_1v2 : 1; + /** + * 0 = output selected by outen bit + * 1 = output controlled by selected GPIO output source + */ + u16 outen_ovr : 1; + /** 0 = GPIO is input only, 1 = GPIO output driver enabled */ + u16 outen : 1; +u16: 2; + u16 pullup_1k; /** 1 = enable 1K pad pullup */ + u16 pullup_10k; /** 1 = enable 10K pad pullup */ + } s; +}; + +#define CVMX_INPHI_CS4343_GPIO_CFG_OFFSET 0x0 + +/** + * This selects which port the GPIO gets its signals from when configured + * as an output. + */ +enum cvmx_inphi_cs4343_gpio_output_cfg_port { + PORT_0_HOST_RX = 0, /** Port pair 0 host RX */ + PORT_0_LINE_RX = 1, /** Port pair 0 line RX */ + PORT_1_HOST_RX = 2, /** Port pair 1 host RX */ + PORT_1_LINE_RX = 3, /** Port pair 1 line RX */ + PORT_3_HOST_RX = 4, /** Port pair 3 host RX */ + PORT_3_LINE_RX = 5, /** Port pair 3 line RX */ + PORT_2_HOST_RX = 6, /** Port pair 2 host RX */ + PORT_2_LINE_RX = 7, /** Port pair 2 line RX */ + COMMON = 8, /** Common */ +}; + +enum cvmx_inphi_cs4343_gpio_output_cfg_function { + RX_LOS = 0, /** Port - 1 = Receive LOS (from DSP) */ + RX_LOL = 1, /** Port - 1 = Receive LOL (inverted from MSEQ) */ + EDC_CONVERGED = 2, /** Port - 1 = EDC converged (from DSP) */ + /** Port - 1 = PRBS checker in sync (inverted from SDS) */ + RX_PRBS_SYNC = 3, + COMMON_LOGIC_0 = 0, /** Common - Logic 0 */ + COMMON_GPIO1_INPUT = 1, /** Common - GPIO 1 input */ + COMMON_GPIO2_INPUT = 2, /** Common - GPIO 2 input */ + COMMON_GPIO3_INPUT = 3, /** Common - GPIO 3 input */ + COMMON_GPIO4_INPUT = 4, /** Common - GPIO 4 input */ + COMMON_INTERR_INPUT = 5, /** Common - INTERR input */ + /** Common - Interrupt output from GLOBAL_INT register */ + COMMON_GLOBAL_INT = 6, + /** Common - Interrupt output from GPIO_INT register */ + COMMON_GPIO_INT = 7, + /** Common - Temp/voltage monitor interrupt */ + COMMON_MONITOR_INT = 8, + /** Common - Selected clock output of global clock monitor */ + COMMON_GBL_CLKMON_CLK = 9, +}; + +union cvmx_inphi_cs4343_gpio_output_cfg { + u16 u; + struct { +u16: 8; + u16 port : 4; /** port */ + u16 function : 4; /** function */ + } s; +}; + +#define CVMX_INPHI_CS4343_GPIO_OUTPUT_CFG_OFFSET 0x1 + +union cvmx_inphi_cs4343_gpio_drive { + u16 u; + struct { +u16: 15; + u16 value : 1; /** output value */ + } s; +}; + +#define CVMX_INPHI_CS4343_GPIO_DRIVE_OFFSET 0x2 + +union cvmx_inphi_cs4343_gpio_value { + u16 u; + struct { +u16: 15; + u16 value : 1; /** input value (read-only) */ + } s; +}; + +#define CVMX_INPHI_CS4343_GPIO_VALUE_OFFSET 0x3 + +union cvmx_inphi_cs4343_gpio_toggle { + u16 u; + struct { + /** Toggle rate in ms, multiply by 2 to get period in ms */ + u16 rate : 16; + } s; +}; + +#define CVMX_INPHI_CS4343_GPIO_TOGGLE_OFFSET 0x4 + +union cvmx_inphi_cs4343_gpio_delay { + u16 u; + struct { + /** On delay for GPIO output in ms when enabled */ + u16 on_delay : 16; + } s; +}; + +#define CVMX_INPHI_CS4343_GPIO_DELAY_OFFSET 0x5 + +/** + * GPIO flags associated with a GPIO pin (can be combined) + */ +enum cvmx_gpio_flags { + CVMX_GPIO_ACTIVE_HIGH = 0, /** Active high (default) */ + CVMX_GPIO_ACTIVE_LOW = 1, /** Active low (inverted) */ + CVMX_GPIO_OPEN_COLLECTOR = 2, /** Output is open-collector */ +}; + +/** Default timer number to use for outputting a frequency [0..3] */ +#define CVMX_GPIO_DEFAULT_TIMER 3 + +/** Configuration data for native Octeon GPIO pins */ +struct cvmx_octeon_gpio_data { + int cpu_node; /** CPU node for GPIO pin */ + int timer; /** Timer number used when in toggle mode, 0-3 */ +}; + +struct cvmx_pcf857x_gpio_data { + unsigned int latch_out; +}; + +#define CVMX_INPHI_CS4343_EFUSE_PDF_SKU_REG 0x19f +#define CVMX_INPHI_CS4343_SKU_CS4223 0x10 +#define CVMX_INPHI_CS4343_SKU_CS4224 0x11 +#define CVMX_INPHI_CS4343_SKU_CS4343 0x12 +#define CVMX_INPHI_CS4343_SKU_CS4221 0x13 +#define CVMX_INPHI_CS4343_SKU_CS4227 0x14 +#define CVMX_INPHI_CS4343_SKU_CS4341 0x16 + +struct cvmx_cs4343_gpio_data { + int reg_offset; /** Base register address for GPIO */ + enum cvmx_gpio_operation last_op; + u8 link_port; /** Link port number for link status */ + u16 sku; /** Value from CS4224_EFUSE_PDF_SKU register */ + u8 out_src_sel; + u8 field_func; + bool out_en; + bool is_cs4343; /** True if dual package */ + struct phy_device *phydev; +}; + +struct cvmx_fdt_gpio_info; + +/** Function called for GPIO operations */ +typedef int (*cvmx_fdt_gpio_op_func_t)(struct cvmx_fdt_gpio_info *, enum cvmx_gpio_operation); + +/** + * GPIO descriptor + */ +struct cvmx_fdt_gpio_info { + struct cvmx_fdt_gpio_info *next; /** For list of GPIOs */ + char name[CVMX_GPIO_NAME_LEN]; /** Name of GPIO */ + int pin; /** GPIO pin number */ + enum cvmx_gpio_type gpio_type; /** Type of GPIO controller */ + int of_offset; /** Offset in device tree */ + int phandle; + struct cvmx_fdt_i2c_bus_info *i2c_bus; /** I2C bus descriptor */ + int i2c_addr; /** Address on i2c bus */ + enum cvmx_gpio_flags flags; /** Flags associated with pin */ + int num_pins; /** Total number of pins */ + unsigned int latch_out; /** Latched output for 857x */ + /** Rate in ms between toggle states */ + int toggle_rate; + /** Pointer to user data for user-defined functions */ + void *data; + /** Function to set, clear, toggle, etc. */ + cvmx_fdt_gpio_op_func_t op_func; + /* Two values are used to detect the initial case where nothing has + * been configured. Initially, all of the following will be false + * which will force the initial state to be properly set. + */ + /** True if the GPIO pin is currently set, useful for toggle */ + bool is_set; + /** Set if configured to invert */ + bool invert_set; + /** Set if input is to be inverted */ + bool invert_input; + /** Set if direction is configured as output */ + bool dir_out; + /** Set if direction is configured as input */ + bool dir_in; + /** Pin is set to toggle periodically */ + bool toggle; + /** True if LED is used to indicate link status */ + bool link_led; + /** True if LED is used to indicate rx activity */ + bool rx_act_led; + /** True if LED is used to indicate tx activity */ + bool tx_act_led; + /** True if LED is used to indicate networking errors */ + bool error_led; + /** True if LED can automatically show link */ + bool hw_link; +}; + +/** LED datastructure */ +struct cvmx_fdt_gpio_led { + struct cvmx_fdt_gpio_led *next, *prev; /** List of LEDs */ + char name[CVMX_GPIO_NAME_LEN]; /** Name */ + struct cvmx_fdt_gpio_info *gpio; /** GPIO for LED */ + int of_offset; /** Device tree node */ + /** True if active low, note that GPIO contains this info */ + bool active_low; +}; + +/** + * Returns the operation function for the GPIO phandle + * + * @param[in] fdt_addr Pointer to FDT + * @param phandle phandle of GPIO entry + * + * @return Pointer to op function or NULL if not found. + */ +cvmx_fdt_gpio_op_func_t cvmx_fdt_gpio_get_op_func(const void *fdt_addr, int phandle); + +/** + * Given a phandle to a GPIO device return the type of GPIO device it is. + * + * @param[in] fdt_addr Address of flat device tree + * @param phandle phandle to GPIO + * @param[out] size Number of pins (optional, may be NULL) + * + * @return Type of GPIO device or PIN_ERROR if error + */ +enum cvmx_gpio_type cvmx_fdt_get_gpio_type(const void *fdt_addr, int phandle, int *size); + +/** + * Return a GPIO handle given a GPIO phandle of the form <&gpio pin flags> + * + * @param[in] fdt_addr Address of flat device tree + * @param of_offset node offset of GPIO device + * @param prop_name name of property + * + * @return pointer to GPIO handle or NULL if error + */ +struct cvmx_fdt_gpio_info *cvmx_fdt_gpio_get_info(const void *fdt_addr, int of_offset, + const char *prop_name); + +/** + * Return a GPIO handle given a GPIO phandle of the form <&gpio pin flags> + * + * @param[in] fdt_addr Address of flat device tree + * @param of_offset node offset for property + * @param prop_name name of property + * + * @return pointer to GPIO handle or NULL if error + */ +struct cvmx_fdt_gpio_info *cvmx_fdt_gpio_get_info_phandle(const void *fdt_addr, int of_offset, + const char *prop_name); + +/** + * Parses a GPIO entry and fills in the gpio info data structure + * + * @param[in] fdt_addr Address of FDT + * @param phandle phandle for GPIO + * @param pin pin number + * @param flags flags set (1 = invert) + * @param[out] gpio GPIO info data structure + * + * @return 0 for success, -1 on error + */ +int cvmx_fdt_parse_gpio(const void *fdt_addr, int phandle, int pin, u32 flags, + struct cvmx_fdt_gpio_info *gpio); + +/** + * @param gpio GPIO descriptor to assign timer to + * @param timer Octeon hardware timer number [0..3] + */ +void cvmx_fdt_gpio_set_timer(struct cvmx_fdt_gpio_info *gpio, int timer); + +/** + * Given a GPIO pin descriptor, input the value of that pin + * + * @param pin GPIO pin descriptor + * + * @return 0 if low, 1 if high, -1 on error. Note that the input will be + * inverted if the CVMX_GPIO_ACTIVE_LOW flag bit is set. + */ +int cvmx_fdt_gpio_get(struct cvmx_fdt_gpio_info *pin); + +/** + * Sets a GPIO pin given the GPIO descriptor + * + * @param gpio GPIO pin descriptor + * @param value value to set it to, 0 or 1 + * + * @return 0 on success, -1 on error. + * + * NOTE: If the CVMX_GPIO_ACTIVE_LOW flag is set then the output value will be + * inverted. + */ +int cvmx_fdt_gpio_set(struct cvmx_fdt_gpio_info *gpio, int value); + +/** + * Sets the blink frequency for a GPIO pin + * + * @param gpio GPIO handle + * @param freq Frequency in hz [0..500] + */ +void cvmx_fdt_gpio_set_freq(struct cvmx_fdt_gpio_info *gpio, int freq); + +/** + * Enables or disables blinking a GPIO pin + * + * @param gpio GPIO handle + * @param blink True to start blinking, false to stop + * + * @return 0 for success, -1 on error + * NOTE: Not all GPIO types support blinking. + */ +int cvmx_fdt_gpio_set_blink(struct cvmx_fdt_gpio_info *gpio, bool blink); + +/** + * Alternates between link and blink mode + * + * @param gpio GPIO handle + * @param blink True to start blinking, false to use link status + * + * @return 0 for success, -1 on error + * NOTE: Not all GPIO types support this. + */ +int cvmx_fdt_gpio_set_link_blink(struct cvmx_fdt_gpio_info *gpio, bool blink); + +static inline bool cvmx_fdt_gpio_hw_link_supported(const struct cvmx_fdt_gpio_info *gpio) +{ + return gpio->hw_link; +} + +/** + * Configures a GPIO pin as input or output + * + * @param gpio GPIO pin to configure + * @param output Set to true to make output, false for input + */ +void cvmx_fdt_gpio_set_output(struct cvmx_fdt_gpio_info *gpio, bool output); + +/** + * Allocates an LED data structure + * @param[in] name name to assign LED + * @param of_offset Device tree offset + * @param gpio GPIO assigned to LED (can be NULL) + * @param last Previous LED to build a list + * + * @return pointer to LED data structure or NULL if out of memory + */ +struct cvmx_fdt_gpio_led *cvmx_alloc_led(const char *name, int of_offset, + struct cvmx_fdt_gpio_info *gpio, + struct cvmx_fdt_gpio_led *last); + +/** + * Parses an LED in the device tree + * + * @param[in] fdt_addr Pointer to flat device tree + * @param led_of_offset Device tree offset of LED + * @param gpio GPIO data structure to use (can be NULL) + * @param last Previous LED if this is a group of LEDs + * + * @return Pointer to LED data structure or NULL if error + */ +struct cvmx_fdt_gpio_led *cvmx_fdt_parse_led(const void *fdt_addr, int led_of_offset, + struct cvmx_fdt_gpio_info *gpio, + struct cvmx_fdt_gpio_led *last); + +#endif /* __CVMX_HELPER_GPIO_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-ilk.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-ilk.h new file mode 100644 index 0000000000..29af48e7a1 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-ilk.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for ILK initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_ILK_H__ +#define __CVMX_HELPER_ILK_H__ + +int __cvmx_helper_ilk_enumerate(int interface); + +/** + * @INTERNAL + * Clear all calendar entries to the xoff state. This + * means no data is sent or received. + * + * @param interface Interface whose calendar are to be initialized. + */ +void __cvmx_ilk_clear_cal(int interface); + +/** + * @INTERNAL + * Setup the channel's tx calendar entry. + * + * @param interface Interface channel belongs to + * @param channel Channel whose calendar entry is to be updated + * @param bpid Bpid assigned to the channel + */ +void __cvmx_ilk_write_tx_cal_entry(int interface, int channel, unsigned char bpid); + +/** + * @INTERNAL + * Setup the channel's rx calendar entry. + * + * @param interface Interface channel belongs to + * @param channel Channel whose calendar entry is to be updated + * @param pipe PKO assigned to the channel + */ +void __cvmx_ilk_write_rx_cal_entry(int interface, int channel, unsigned char pipe); + +/** + * @INTERNAL + * Probe a ILK interface and determine the number of ports + * connected to it. The ILK interface should still be down after + * this call. + * + * @param xiface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_ilk_probe(int xiface); + +/** + * @INTERNAL + * Bringup and enable a ILK interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_ilk_enable(int xiface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by ILK link status. + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_ilk_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_ilk_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +void __cvmx_helper_ilk_show_stats(void); +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-ipd.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-ipd.h new file mode 100644 index 0000000000..025743d505 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-ipd.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper functions for IPD + */ + +#ifndef __CVMX_HELPER_IPD_H__ +#define __CVMX_HELPER_IPD_H__ + +void cvmx_helper_ipd_set_wqe_no_ptr_mode(bool mode); +void cvmx_helper_ipd_pkt_wqe_le_mode(bool mode); +int __cvmx_helper_ipd_global_setup(void); +int __cvmx_helper_ipd_setup_interface(int interface); + +#endif /* __CVMX_HELPER_PKI_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-jtag.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-jtag.h new file mode 100644 index 0000000000..fa379eaf55 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-jtag.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper utilities for qlm_jtag. + */ + +#ifndef __CVMX_HELPER_JTAG_H__ +#define __CVMX_HELPER_JTAG_H__ + +/** + * The JTAG chain for CN52XX and CN56XX is 4 * 268 bits long, or 1072. + * CN5XXX full chain shift is: + * new data => lane 3 => lane 2 => lane 1 => lane 0 => data out + * The JTAG chain for CN63XX is 4 * 300 bits long, or 1200. + * The JTAG chain for CN68XX is 4 * 304 bits long, or 1216. + * The JTAG chain for CN66XX/CN61XX/CNF71XX is 4 * 304 bits long, or 1216. + * CN6XXX full chain shift is: + * new data => lane 0 => lane 1 => lane 2 => lane 3 => data out + * Shift LSB first, get LSB out + */ +extern const __cvmx_qlm_jtag_field_t __cvmx_qlm_jtag_field_cn63xx[]; +extern const __cvmx_qlm_jtag_field_t __cvmx_qlm_jtag_field_cn66xx[]; +extern const __cvmx_qlm_jtag_field_t __cvmx_qlm_jtag_field_cn68xx[]; + +#define CVMX_QLM_JTAG_UINT32 40 + +typedef u32 qlm_jtag_uint32_t[CVMX_QLM_JTAG_UINT32 * 8]; + +/** + * Initialize the internal QLM JTAG logic to allow programming + * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions. + * These functions should only be used at the direction of Cavium + * Networks. Programming incorrect values into the JTAG chain + * can cause chip damage. + */ +void cvmx_helper_qlm_jtag_init(void); + +/** + * Write up to 32bits into the QLM jtag chain. Bits are shifted + * into the MSB and out the LSB, so you should shift in the low + * order bits followed by the high order bits. The JTAG chain for + * CN52XX and CN56XX is 4 * 268 bits long, or 1072. The JTAG chain + * for CN63XX is 4 * 300 bits long, or 1200. + * + * @param qlm QLM to shift value into + * @param bits Number of bits to shift in (1-32). + * @param data Data to shift in. Bit 0 enters the chain first, followed by + * bit 1, etc. + * + * @return The low order bits of the JTAG chain that shifted out of the + * circle. + */ +u32 cvmx_helper_qlm_jtag_shift(int qlm, int bits, u32 data); + +/** + * Shift long sequences of zeros into the QLM JTAG chain. It is + * common to need to shift more than 32 bits of zeros into the + * chain. This function is a convience wrapper around + * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of + * zeros at a time. + * + * @param qlm QLM to shift zeros into + * @param bits + */ +void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits); + +/** + * Program the QLM JTAG chain into all lanes of the QLM. You must + * have already shifted in the proper number of bits into the + * JTAG chain. Updating invalid values can possibly cause chip damage. + * + * @param qlm QLM to program + */ +void cvmx_helper_qlm_jtag_update(int qlm); + +/** + * Load the QLM JTAG chain with data from all lanes of the QLM. + * + * @param qlm QLM to program + */ +void cvmx_helper_qlm_jtag_capture(int qlm); + +#endif /* __CVMX_HELPER_JTAG_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-loop.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-loop.h new file mode 100644 index 0000000000..defd95551a --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-loop.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for LOOP initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_LOOP_H__ +#define __CVMX_HELPER_LOOP_H__ + +/** + * @INTERNAL + * Probe a LOOP interface and determine the number of ports + * connected to it. The LOOP interface should still be down after + * this call. + * + * @param xiface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_loop_probe(int xiface); +int __cvmx_helper_loop_enumerate(int xiface); + +/** + * @INTERNAL + * Bringup and enable a LOOP interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_loop_enable(int xiface); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-npi.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-npi.h new file mode 100644 index 0000000000..6a600a017c --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-npi.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for NPI initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_NPI_H__ +#define __CVMX_HELPER_NPI_H__ + +/** + * @INTERNAL + * Probe a NPI interface and determine the number of ports + * connected to it. The NPI interface should still be down after + * this call. + * + * @param interface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_npi_probe(int interface); + +/** + * @INTERNAL + * Bringup and enable a NPI interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_npi_enable(int xiface); + +/** + * Sets the number of pipe used by SLI packet output in the variable, + * which then later used for setting it up in HW + */ +void cvmx_npi_config_set_num_pipes(int num_pipes); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-pki.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-pki.h new file mode 100644 index 0000000000..f5933f24fa --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-pki.h @@ -0,0 +1,319 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper functions for PKI + */ + +#ifndef __CVMX_HELPER_PKI_H__ +#define __CVMX_HELPER_PKI_H__ + +#include "cvmx-pki.h" + +/* Modify this if more than 8 ilk channels need to be supported */ +#define CVMX_MAX_PORT_PER_INTERFACE 64 +#define CVMX_MAX_QOS_PRIORITY 64 +#define CVMX_PKI_FIND_AVAILABLE_RSRC (-1) + +struct cvmx_pki_qos_schd { + cvmx_fpa3_gaura_t _aura; + cvmx_fpa3_pool_t _pool; + bool pool_per_qos; + int pool_num; + char *pool_name; + u64 pool_buff_size; + u64 pool_max_buff; + bool aura_per_qos; + int aura_num; + char *aura_name; + u64 aura_buff_cnt; + bool sso_grp_per_qos; + int sso_grp; + u16 port_add; + int qpg_base; +}; + +struct cvmx_pki_prt_schd { + cvmx_fpa3_pool_t _pool; + cvmx_fpa3_gaura_t _aura; + bool cfg_port; + int style; + bool pool_per_prt; + int pool_num; + char *pool_name; + u64 pool_buff_size; + u64 pool_max_buff; + bool aura_per_prt; + int aura_num; + char *aura_name; + u64 aura_buff_cnt; + bool sso_grp_per_prt; + int sso_grp; + enum cvmx_pki_qpg_qos qpg_qos; + int qpg_base; + struct cvmx_pki_qos_schd qos_s[CVMX_MAX_QOS_PRIORITY]; +}; + +struct cvmx_pki_intf_schd { + cvmx_fpa3_pool_t _pool; + cvmx_fpa3_gaura_t _aura; + bool style_per_intf; + int style; + bool pool_per_intf; + int pool_num; + char *pool_name; + u64 pool_buff_size; + u64 pool_max_buff; + bool aura_per_intf; + int aura_num; + char *aura_name; + u64 aura_buff_cnt; + bool sso_grp_per_intf; + int sso_grp; + bool qos_share_aura; + bool qos_share_grp; + int qpg_base; + struct cvmx_pki_prt_schd prt_s[CVMX_MAX_PORT_PER_INTERFACE]; +}; + +struct cvmx_pki_global_schd { + bool setup_pool; + int pool_num; + char *pool_name; + u64 pool_buff_size; + u64 pool_max_buff; + bool setup_aura; + int aura_num; + char *aura_name; + u64 aura_buff_cnt; + bool setup_sso_grp; + int sso_grp; + cvmx_fpa3_pool_t _pool; + cvmx_fpa3_gaura_t _aura; +}; + +struct cvmx_pki_legacy_qos_watcher { + bool configured; + enum cvmx_pki_term field; + u32 data; + u32 data_mask; + u8 advance; + u8 sso_grp; +}; + +extern bool cvmx_pki_dflt_init[CVMX_MAX_NODES]; + +extern struct cvmx_pki_pool_config pki_dflt_pool[CVMX_MAX_NODES]; +extern struct cvmx_pki_aura_config pki_dflt_aura[CVMX_MAX_NODES]; +extern struct cvmx_pki_style_config pki_dflt_style[CVMX_MAX_NODES]; +extern struct cvmx_pki_pkind_config pki_dflt_pkind[CVMX_MAX_NODES]; +extern u64 pkind_style_map[CVMX_MAX_NODES][CVMX_PKI_NUM_PKIND]; +extern struct cvmx_pki_sso_grp_config pki_dflt_sso_grp[CVMX_MAX_NODES]; +extern struct cvmx_pki_legacy_qos_watcher qos_watcher[8]; + +/** + * This function Enabled the PKI hardware to + * start accepting/processing packets. + * @param node node number + */ +void cvmx_helper_pki_enable(int node); + +/** + * This function frees up PKI resources consumed by that port. + * This function should only be called if port resources + * (fpa pools aura, style qpg entry pcam entry etc.) are not shared + * @param xipd_port ipd port number for which resources need to + * be freed. + */ +int cvmx_helper_pki_port_shutdown(int xipd_port); + +/** + * This function shuts down complete PKI hardware + * and software resources. + * @param node node number where PKI needs to shutdown. + */ +void cvmx_helper_pki_shutdown(int node); + +/** + * This function calculates how mant qpf entries will be needed for + * a particular QOS. + * @param qpg_qos qos value for which entries need to be calculated. + */ +int cvmx_helper_pki_get_num_qpg_entry(enum cvmx_pki_qpg_qos qpg_qos); + +/** + * This function setups the qos table by allocating qpg entry and writing + * the provided parameters to that entry (offset). + * @param node node number. + * @param qpg_cfg pointer to struct containing qpg configuration + */ +int cvmx_helper_pki_set_qpg_entry(int node, struct cvmx_pki_qpg_config *qpg_cfg); + +/** + * This function sets up aura QOS for RED, backpressure and tail-drop. + * + * @param node node number. + * @param aura aura to configure. + * @param ena_red enable RED based on [DROP] and [PASS] levels + * 1: enable 0:disable + * @param pass_thresh pass threshold for RED. + * @param drop_thresh drop threshold for RED + * @param ena_bp enable backpressure based on [BP] level. + * 1:enable 0:disable + * @param bp_thresh backpressure threshold. + * @param ena_drop enable tail drop. + * 1:enable 0:disable + * @return Zero on success. Negative on failure + */ +int cvmx_helper_setup_aura_qos(int node, int aura, bool ena_red, bool ena_drop, u64 pass_thresh, + u64 drop_thresh, bool ena_bp, u64 bp_thresh); + +/** + * This function maps specified bpid to all the auras from which it can receive bp and + * then maps that bpid to all the channels, that bpid can asserrt bp on. + * + * @param node node number. + * @param aura aura number which will back pressure specified bpid. + * @param bpid bpid to map. + * @param chl_map array of channels to map to that bpid. + * @param chl_cnt number of channel/ports to map to that bpid. + * @return Zero on success. Negative on failure + */ +int cvmx_helper_pki_map_aura_chl_bpid(int node, u16 aura, u16 bpid, u16 chl_map[], u16 chl_cnt); + +/** + * This function sets up the global pool, aura and sso group + * resources which application can use between any interfaces + * and ports. + * @param node node number + * @param gblsch pointer to struct containing global + * scheduling parameters. + */ +int cvmx_helper_pki_set_gbl_schd(int node, struct cvmx_pki_global_schd *gblsch); + +/** + * This function sets up scheduling parameters (pool, aura, sso group etc) + * of an ipd port. + * @param xipd_port ipd port number + * @param prtsch pointer to struct containing port's + * scheduling parameters. + */ +int cvmx_helper_pki_init_port(int xipd_port, struct cvmx_pki_prt_schd *prtsch); + +/** + * This function sets up scheduling parameters (pool, aura, sso group etc) + * of an interface (all ports/channels on that interface). + * @param xiface interface number with node. + * @param intfsch pointer to struct containing interface + * scheduling parameters. + * @param gblsch pointer to struct containing global scheduling parameters + * (can be NULL if not used) + */ +int cvmx_helper_pki_init_interface(const int xiface, struct cvmx_pki_intf_schd *intfsch, + struct cvmx_pki_global_schd *gblsch); +/** + * This function gets all the PKI parameters related to that + * particular port from hardware. + * @param xipd_port ipd port number to get parameter of + * @param port_cfg pointer to structure where to store read parameters + */ +void cvmx_pki_get_port_config(int xipd_port, struct cvmx_pki_port_config *port_cfg); + +/** + * This function sets all the PKI parameters related to that + * particular port in hardware. + * @param xipd_port ipd port number to get parameter of + * @param port_cfg pointer to structure containing port parameters + */ +void cvmx_pki_set_port_config(int xipd_port, struct cvmx_pki_port_config *port_cfg); + +/** + * This function displays all the PKI parameters related to that + * particular port. + * @param xipd_port ipd port number to display parameter of + */ +void cvmx_pki_show_port_config(int xipd_port); + +/** + * Modifies maximum frame length to check. + * It modifies the global frame length set used by this port, any other + * port using the same set will get affected too. + * @param xipd_port ipd port for which to modify max len. + * @param max_size maximum frame length + */ +void cvmx_pki_set_max_frm_len(int xipd_port, u32 max_size); + +/** + * This function sets up all the ports of particular interface + * for chosen fcs mode. (only use for backward compatibility). + * New application can control it via init_interface calls. + * @param node node number. + * @param interface interface number. + * @param nports number of ports + * @param has_fcs 1 -- enable fcs check and fcs strip. + * 0 -- disable fcs check. + */ +void cvmx_helper_pki_set_fcs_op(int node, int interface, int nports, int has_fcs); + +/** + * This function sets the wqe buffer mode of all ports. First packet data buffer can reside + * either in same buffer as wqe OR it can go in separate buffer. If used the later mode, + * make sure software allocate enough buffers to now have wqe separate from packet data. + * @param node node number. + * @param pkt_outside_wqe 0 = The packet link pointer will be at word [FIRST_SKIP] + * immediately followed by packet data, in the same buffer + * as the work queue entry. + * 1 = The packet link pointer will be at word [FIRST_SKIP] in a new + * buffer separate from the work queue entry. Words following the + * WQE in the same cache line will be zeroed, other lines in the + * buffer will not be modified and will retain stale data (from the + * buffer’s previous use). This setting may decrease the peak PKI + * performance by up to half on small packets. + */ +void cvmx_helper_pki_set_wqe_mode(int node, bool pkt_outside_wqe); + +/** + * This function sets the Packet mode of all ports and styles to little-endian. + * It Changes write operations of packet data to L2C to + * be in little-endian. Does not change the WQE header format, which is + * properly endian neutral. + * @param node node number. + */ +void cvmx_helper_pki_set_little_endian(int node); + +void cvmx_helper_pki_set_dflt_pool(int node, int pool, int buffer_size, int buffer_count); +void cvmx_helper_pki_set_dflt_aura(int node, int aura, int pool, int buffer_count); +void cvmx_helper_pki_set_dflt_pool_buffer(int node, int buffer_count); + +void cvmx_helper_pki_set_dflt_aura_buffer(int node, int buffer_count); + +void cvmx_helper_pki_set_dflt_pkind_map(int node, int pkind, int style); + +void cvmx_helper_pki_get_dflt_style(int node, struct cvmx_pki_style_config *style_cfg); +void cvmx_helper_pki_set_dflt_style(int node, struct cvmx_pki_style_config *style_cfg); + +void cvmx_helper_pki_get_dflt_qpg(int node, struct cvmx_pki_qpg_config *qpg_cfg); +void cvmx_helper_pki_set_dflt_qpg(int node, struct cvmx_pki_qpg_config *qpg_cfg); + +void cvmx_helper_pki_no_dflt_init(int node); + +void cvmx_helper_pki_set_dflt_bp_en(int node, bool bp_en); + +void cvmx_pki_dump_wqe(const cvmx_wqe_78xx_t *wqp); + +int __cvmx_helper_pki_port_setup(int node, int xipd_port); + +int __cvmx_helper_pki_global_setup(int node); +void cvmx_helper_pki_show_port_config(int xipd_port); + +int __cvmx_helper_pki_install_dflt_vlan(int node); +void __cvmx_helper_pki_set_dflt_ltype_map(int node); +int cvmx_helper_pki_route_dmac(int node, int style, u64 mac_addr, u64 mac_addr_mask, + int final_style); +int cvmx_pki_clone_style(int node, int style, u64 cluster_mask); +void cvmx_helper_pki_modify_prtgrp(int xipd_port, int grp_ok, int grp_bad); +int cvmx_helper_pki_route_prt_dmac(int xipd_port, u64 mac_addr, u64 mac_addr_mask, int grp); + +void cvmx_helper_pki_errata(int node); + +#endif /* __CVMX_HELPER_PKI_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h new file mode 100644 index 0000000000..806102df22 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-pko.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * PKO helper, configuration API + */ + +#ifndef __CVMX_HELPER_PKO_H__ +#define __CVMX_HELPER_PKO_H__ + +/* CSR typedefs have been moved to cvmx-pko-defs.h */ + +/** + * cvmx_override_pko_queue_priority(int ipd_port, u64 + * priorities[16]) is a function pointer. It is meant to allow + * customization of the PKO queue priorities based on the port + * number. Users should set this pointer to a function before + * calling any cvmx-helper operations. + */ +void (*cvmx_override_pko_queue_priority)(int ipd_port, u8 *priorities); + +/** + * Gets the fpa pool number of pko pool + */ +s64 cvmx_fpa_get_pko_pool(void); + +/** + * Gets the buffer size of pko pool + */ +u64 cvmx_fpa_get_pko_pool_block_size(void); + +/** + * Gets the buffer size of pko pool + */ +u64 cvmx_fpa_get_pko_pool_buffer_count(void); + +int cvmx_helper_pko_init(void); + +/* + * This function is a no-op + * included here for backwards compatibility only. + */ +static inline int cvmx_pko_initialize_local(void) +{ + return 0; +} + +int __cvmx_helper_pko_drain(void); +int __cvmx_helper_interface_setup_pko(int interface); + +#endif /* __CVMX_HELPER_PKO_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-pko3.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-pko3.h new file mode 100644 index 0000000000..ca8d848bd1 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-pko3.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + */ + +#ifndef __CVMX_HELPER_PKO3_H__ +#define __CVMX_HELPER_PKO3_H__ + +/* + * Initialize PKO3 unit on the current node. + * + * Covers the common hardware, memory and global configuration. + * Per-interface initialization is performed separately. + * + * @return 0 on success. + * + */ +int cvmx_helper_pko3_init_global(unsigned int node); +int __cvmx_helper_pko3_init_global(unsigned int node, u16 gaura); + +/** + * Initialize a simple interface with a a given number of + * fair or prioritized queues. + * This function will assign one channel per sub-interface. + */ +int __cvmx_pko3_config_gen_interface(int xiface, u8 subif, u8 num_queues, bool prioritized); + +/* + * Configure and initialize PKO3 for an interface + * + * @param interface is the interface number to configure + * @return 0 on success. + * + */ +int cvmx_helper_pko3_init_interface(int xiface); +int __cvmx_pko3_helper_dqs_activate(int xiface, int index, bool min_pad); + +/** + * Uninitialize PKO3 interface + * + * Release all resources held by PKO for an interface. + * The shutdown code is the same for all supported interfaces. + */ +int cvmx_helper_pko3_shut_interface(int xiface); + +/** + * Shutdown PKO3 + * + * Should be called after all interfaces have been shut down on the PKO3. + * + * Disables the PKO, frees all its buffers. + */ +int cvmx_helper_pko3_shutdown(unsigned int node); + +/** + * Show integrated PKO configuration. + * + * @param node node number + */ +int cvmx_helper_pko3_config_dump(unsigned int node); + +/** + * Show integrated PKO statistics. + * + * @param node node number + */ +int cvmx_helper_pko3_stats_dump(unsigned int node); + +/** + * Clear PKO statistics. + * + * @param node node number + */ +void cvmx_helper_pko3_stats_clear(unsigned int node); + +#endif /* __CVMX_HELPER_PKO3_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-rgmii.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-rgmii.h new file mode 100644 index 0000000000..2a206a8827 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-rgmii.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for RGMII/GMII/MII initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_RGMII_H__ +#define __CVMX_HELPER_RGMII_H__ + +/** + * @INTERNAL + * Probe RGMII ports and determine the number present + * + * @param xiface Interface to probe + * + * @return Number of RGMII/GMII/MII ports (0-4). + */ +int __cvmx_helper_rgmii_probe(int xiface); + +/** + * Put an RGMII interface in loopback mode. Internal packets sent + * out will be received back again on the same port. Externally + * received packets will echo back out. + * + * @param port IPD port number to loop. + */ +void cvmx_helper_rgmii_internal_loopback(int port); + +/** + * @INTERNAL + * Configure all of the ASX, GMX, and PKO regsiters required + * to get RGMII to function on the supplied interface. + * + * @param xiface PKO Interface to configure (0 or 1) + * + * @return Zero on success + */ +int __cvmx_helper_rgmii_enable(int xiface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_gmii_link_get(int ipd_port); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_rgmii_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * Configure a port for internal and/or external loopback. Internal loopback + * causes packets sent by the port to be received by Octeon. External loopback + * causes packets received from the wire to sent out again. + * + * @param ipd_port IPD/PKO port to loopback. + * @param enable_internal + * Non zero if you want internal loopback + * @param enable_external + * Non zero if you want external loopback + * + * @return Zero on success, negative on failure. + */ +int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal, int enable_external); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-sfp.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-sfp.h new file mode 100644 index 0000000000..6fe55093b2 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-sfp.h @@ -0,0 +1,437 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper functions to abstract SFP and QSFP connectors + */ + +#ifndef __CVMX_HELPER_SFP_H__ +#define __CVMX_HELPER_SFP_H__ + +/** + * Maximum size for the SFP EEPROM. Currently only 96 bytes are used. + */ +#define CVMX_SFP_MAX_EEPROM_SIZE 0x100 + +/** + * Default address of sfp EEPROM + */ +#define CVMX_SFP_DEFAULT_I2C_ADDR 0x50 + +/** + * Default address of SFP diagnostics chip + */ +#define CVMX_SFP_DEFAULT_DIAG_I2C_ADDR 0x51 + +struct cvmx_fdt_sfp_info; +struct cvmx_fdt_gpio_info; +/** + * Connector type for module, usually we only see SFP and QSFPP + */ +enum cvmx_phy_sfp_conn_type { + CVMX_SFP_CONN_GBIC = 0x01, /** GBIC */ + CVMX_SFP_CONN_SFP = 0x03, /** SFP/SFP+/SFP28 */ + CVMX_SFP_CONN_QSFP = 0x0C, /** 1G QSFP (obsolete) */ + CVMX_SFP_CONN_QSFPP = 0x0D, /** QSFP+ or later */ + CVMX_SFP_CONN_QSFP28 = 0x11, /** QSFP28 (100Gbps) */ + CVMX_SFP_CONN_MICRO_QSFP = 0x17, /** Micro QSFP */ + CVMX_SFP_CONN_QSFP_DD = 0x18, /** QSFP-DD Double Density 8X */ + CVMX_SFP_CONN_SFP_DD = 0x1A, /** SFP-DD Double Density 2X */ +}; + +/** + * module type plugged into a SFP/SFP+/QSFP+ port + */ +enum cvmx_phy_sfp_mod_type { + CVMX_SFP_MOD_UNKNOWN = 0, /** Unknown or unspecified */ + /** Fiber optic module (LC connector) */ + CVMX_SFP_MOD_OPTICAL_LC = 0x7, + /** Multiple optical */ + CVMX_SFP_MOD_MULTIPLE_OPTICAL = 0x9, + /** Fiber optic module (pigtail, no connector) */ + CVMX_SFP_MOD_OPTICAL_PIGTAIL = 0xB, + CVMX_SFP_MOD_COPPER_PIGTAIL = 0x21, /** copper module */ + CVMX_SFP_MOD_RJ45 = 0x22, /** RJ45 (i.e. 10GBase-T) */ + /** No separable connector (SFP28/copper) */ + CVMX_SFP_MOD_NO_SEP_CONN = 0x23, + /** MXC 2X16 */ + CVMX_SFP_MOD_MXC_2X16 = 0x24, + /** CS optical connector */ + CVMX_SFP_MOD_CS_OPTICAL = 0x25, + /** Mini CS optical connector */ + CVMX_SFP_MOD_MINI_CS_OPTICAL = 0x26, + /** Unknown/other module type */ + CVMX_SFP_MOD_OTHER +}; + +/** Peak rate supported by SFP cable */ +enum cvmx_phy_sfp_rate { + CVMX_SFP_RATE_UNKNOWN, /** Unknown rate */ + CVMX_SFP_RATE_1G, /** 1Gbps */ + CVMX_SFP_RATE_10G, /** 10Gbps */ + CVMX_SFP_RATE_25G, /** 25Gbps */ + CVMX_SFP_RATE_40G, /** 40Gbps */ + CVMX_SFP_RATE_100G /** 100Gbps */ +}; + +/** + * Cable compliance specification + * See table 4-4 from SFF-8024 for the extended specification compliance codes + */ +enum cvmx_phy_sfp_cable_ext_compliance { + CVMX_SFP_CABLE_UNSPEC = 0, + CVMX_SFP_CABLE_100G_25GAUI_C2M_AOC_HIGH_BER = 0x01, /** Active optical cable */ + CVMX_SFP_CABLE_100G_SR4_25G_SR = 0x2, + CVMX_SFP_CABLE_100G_LR4_25G_LR = 0x3, + CVMX_SFP_CABLE_100G_ER4_25G_ER = 0x4, + CVMX_SFP_CABLE_100G_SR10 = 0x5, + CVMX_SFP_CABLE_100G_CWDM4_MSA = 0x6, + CVMX_SFP_CABLE_100G_PSM4 = 0x7, + CVMX_SFP_CABLE_100G_25GAUI_C2M_ACC_HIGH_BER = 0x8, + CVMX_SFP_CABLE_100G_CWDM4 = 0x9, + CVMX_SFP_CABLE_100G_CR4_25G_CR_CA_L = 0xB, + CVMX_SFP_CABLE_25G_CR_CA_S = 0xC, + CVMX_SFP_CABLE_25G_CR_CA_N = 0xD, + CVMX_SFP_CABLE_40G_ER4 = 0x10, + CVMX_SFP_CABLE_4X10G_SR = 0x11, + CVMX_SFP_CABLE_40G_PSM4 = 0x12, + CVMX_SFP_CABLE_G959_1_P1I1_2D1 = 0x13, + CVMX_SFP_CABLE_G959_1_P1S1_2D2 = 0x14, + CVMX_SFP_CABLE_G959_1_P1L1_2D2 = 0x15, + CVMX_SFP_CABLE_10GBASE_T = 0x16, + CVMX_SFP_CABLE_100G_CLR4 = 0x17, + CVMX_SFP_CABLE_100G_25GAUI_C2M_AOC_LOW_BER = 0x18, + CVMX_SFP_CABLE_100G_25GAUI_C2M_ACC_LOW_BER = 0x19, + CVMX_SFP_CABLE_100G_2_LAMBDA_DWDM = 0x1a, + CVMX_SFP_CABLE_100G_1550NM_WDM = 0x1b, + CVMX_SFP_CABLE_10GBASE_T_SR = 0x1c, + CVMX_SFP_CABLE_5GBASE_T = 0x1d, + CVMX_SFP_CABLE_2_5GBASE_T = 0x1e, + CVMX_SFP_CABLE_40G_SWDM4 = 0x1f, + CVMX_SFP_CABLE_100G_SWDM4 = 0x20, + CVMX_SFP_CABLE_100G_PAM4_BIDI = 0x21, + CVMX_SFP_CABLE_100G_4WDM_10_FEC_HOST = 0x22, + CVMX_SFP_CABLE_100G_4WDM_20_FEC_HOST = 0x23, + CVMX_SFP_CABLE_100G_4WDM_40_FEC_HOST = 0x24, + CVMX_SFP_CABLE_100GBASE_DR_CAUI4_NO_FEC = 0x25, + CVMX_SFP_CABLE_100G_FR_CAUI4_NO_FEC = 0x26, + CVMX_SFP_CABLE_100G_LR_CAUI4_NO_FEC = 0x27, + CVMX_SFP_CABLE_ACTIVE_COPPER_50_100_200GAUI_LOW_BER = 0x30, + CVMX_SFP_CABLE_ACTIVE_OPTICAL_50_100_200GAUI_LOW_BER = 0x31, + CVMX_SFP_CABLE_ACTIVE_COPPER_50_100_200GAUI_HI_BER = 0x32, + CVMX_SFP_CABLE_ACTIVE_OPTICAL_50_100_200GAUI_HI_BER = 0x33, + CVMX_SFP_CABLE_50_100_200G_CR = 0x40, + CVMX_SFP_CABLE_50_100_200G_SR = 0x41, + CVMX_SFP_CABLE_50GBASE_FR_200GBASE_DR4 = 0x42, + CVMX_SFP_CABLE_200GBASE_FR4 = 0x43, + CVMX_SFP_CABLE_200G_1550NM_PSM4 = 0x44, + CVMX_SFP_CABLE_50GBASE_LR = 0x45, + CVMX_SFP_CABLE_200GBASE_LR4 = 0x46, + CVMX_SFP_CABLE_64GFC_EA = 0x50, + CVMX_SFP_CABLE_64GFC_SW = 0x51, + CVMX_SFP_CABLE_64GFC_LW = 0x52, + CVMX_SFP_CABLE_128GFC_EA = 0x53, + CVMX_SFP_CABLE_128GFC_SW = 0x54, + CVMX_SFP_CABLE_128GFC_LW = 0x55, + +}; + +/** Optical modes module is compliant with */ +enum cvmx_phy_sfp_10g_eth_compliance { + CVMX_SFP_CABLE_10GBASE_ER = 0x80, /** 10G ER */ + CVMX_SFP_CABLE_10GBASE_LRM = 0x40, /** 10G LRM */ + CVMX_SFP_CABLE_10GBASE_LR = 0x20, /** 10G LR */ + CVMX_SFP_CABLE_10GBASE_SR = 0x10 /** 10G SR */ +}; + +/** Diagnostic ASIC compatibility */ +enum cvmx_phy_sfp_sff_8472_diag_rev { + CVMX_SFP_SFF_8472_NO_DIAG = 0x00, + CVMX_SFP_SFF_8472_REV_9_3 = 0x01, + CVMX_SFP_SFF_8472_REV_9_5 = 0x02, + CVMX_SFP_SFF_8472_REV_10_2 = 0x03, + CVMX_SFP_SFF_8472_REV_10_4 = 0x04, + CVMX_SFP_SFF_8472_REV_11_0 = 0x05, + CVMX_SFP_SFF_8472_REV_11_3 = 0x06, + CVMX_SFP_SFF_8472_REV_11_4 = 0x07, + CVMX_SFP_SFF_8472_REV_12_0 = 0x08, + CVMX_SFP_SFF_8472_REV_UNALLOCATED = 0xff +}; + +/** + * Data structure describing the current SFP or QSFP EEPROM + */ +struct cvmx_sfp_mod_info { + enum cvmx_phy_sfp_conn_type conn_type; /** Connector type */ + enum cvmx_phy_sfp_mod_type mod_type; /** Module type */ + enum cvmx_phy_sfp_rate rate; /** Rate of module */ + /** 10G Ethernet Compliance codes (logical OR) */ + enum cvmx_phy_sfp_10g_eth_compliance eth_comp; + /** Extended Cable compliance */ + enum cvmx_phy_sfp_cable_ext_compliance cable_comp; + u8 vendor_name[17]; /** Module vendor name */ + u8 vendor_oui[3]; /** vendor OUI */ + u8 vendor_pn[17]; /** Vendor part number */ + u8 vendor_rev[5]; /** Vendor revision */ + u8 vendor_sn[17]; /** Vendor serial number */ + u8 date_code[9]; /** Date code */ + bool valid; /** True if module is valid */ + bool active_cable; /** False for passive copper */ + bool copper_cable; /** True if cable is copper */ + /** True if module is limiting (i.e. not passive copper) */ + bool limiting; + /** Maximum length of copper cable in meters */ + int max_copper_cable_len; + /** Max single mode cable length in meters */ + int max_single_mode_cable_length; + /** Max 50um OM2 cable length */ + int max_50um_om2_cable_length; + /** Max 62.5um OM1 cable length */ + int max_62_5um_om1_cable_length; + /** Max 50um OM4 cable length */ + int max_50um_om4_cable_length; + /** Max 50um OM3 cable length */ + int max_50um_om3_cable_length; + /** Minimum bitrate in Mbps */ + int bitrate_min; + /** Maximum bitrate in Mbps */ + int bitrate_max; + /** + * Set to true if forward error correction is required, + * for example, a 25GBase-CR CA-S cable. + * + * FEC should only be disabled at 25G with CA-N cables. FEC is required + * with 5M and longer cables. + */ + bool fec_required; + /** True if RX output is linear */ + bool linear_rx_output; + /** Power level, can be 1, 2 or 3 */ + int power_level; + /** False if conventional cooling is used, true for active cooling */ + bool cooled_laser; + /** True if internal retimer or clock and data recovery circuit */ + bool internal_cdr; + /** True if LoS is implemented */ + bool los_implemented; + /** True if LoS is inverted from the standard */ + bool los_inverted; + /** True if TX_FAULT is implemented */ + bool tx_fault_implemented; + /** True if TX_DISABLE is implemented */ + bool tx_disable_implemented; + /** True if RATE_SELECT is implemented */ + bool rate_select_implemented; + /** True if tuneable transmitter technology is used */ + bool tuneable_transmitter; + /** True if receiver decision threshold is implemented */ + bool rx_decision_threshold_implemented; + /** True if diagnostic monitoring present */ + bool diag_monitoring; + /** True if diagnostic address 0x7f is used for selecting the page */ + bool diag_paging; + /** Diagnostic feature revision */ + enum cvmx_phy_sfp_sff_8472_diag_rev diag_rev; + /** True if an address change sequence is required for diagnostics */ + bool diag_addr_change_required; + /** True if RX power is averaged, false if OMA */ + bool diag_rx_power_averaged; + /** True if diagnostics are externally calibrated */ + bool diag_externally_calibrated; + /** True if diagnostics are internally calibrated */ + bool diag_internally_calibrated; + /** True of soft rate select control implemented per SFF-8431 */ + bool diag_soft_rate_select_control; + /** True if application select control implemented per SFF-8079 */ + bool diag_app_select_control; + /** True if soft RATE_SELECT control and moonitoring implemented */ + bool diag_soft_rate_select_implemented; + /** True if soft RX_LOS monitoring implemented */ + bool diag_soft_rx_los_implemented; + /** True if soft TX_FAULT monitoring implemented */ + bool diag_soft_tx_fault_implemented; + /** True if soft TX_DISABLE control and monitoring implemented */ + bool diag_soft_tx_disable_implemented; + /** True if alarm/warning flags implemented */ + bool diag_alarm_warning_flags_implemented; +}; + +/** + * Reads the SFP EEPROM using the i2c bus + * + * @param[out] buffer Buffer to store SFP EEPROM data in + * The buffer should be SFP_MAX_EEPROM_SIZE bytes. + * @param i2c_bus i2c bus number to read from for SFP port + * @param i2c_addr i2c address to use, 0 for default + * + * @return -1 if invalid bus or i2c read error, 0 for success + */ +int cvmx_phy_sfp_read_i2c_eeprom(u8 *buffer, int i2c_bus, int i2c_addr); + +/** + * Reads the SFP/SFP+/QSFP EEPROM and outputs the type of module or cable + * plugged in + * + * @param[out] sfp_info Info about SFP module + * @param[in] buffer SFP EEPROM buffer to parse + * + * @return 0 on success, -1 if error reading EEPROM or if EEPROM corrupt + */ +int cvmx_phy_sfp_parse_eeprom(struct cvmx_sfp_mod_info *sfp_info, const u8 *buffer); + +/** + * Prints out information about a SFP/QSFP device + * + * @param[in] sfp_info data structure to print + */ +void cvmx_phy_sfp_print_info(const struct cvmx_sfp_mod_info *sfp_info); + +/** + * Reads and parses SFP/QSFP EEPROM + * + * @param sfp sfp handle to read + * + * @return 0 for success, -1 on error. + */ +int cvmx_sfp_read_i2c_eeprom(struct cvmx_fdt_sfp_info *sfp); + +/** + * Returns the information about a SFP/QSFP device + * + * @param sfp sfp handle + * + * @return sfp_info Pointer sfp mod info data structure + */ +const struct cvmx_sfp_mod_info *cvmx_phy_get_sfp_mod_info(const struct cvmx_fdt_sfp_info *sfp); + +/** + * Function called to check and return the status of the mod_abs pin or + * mod_pres pin for QSFPs. + * + * @param sfp Handle to SFP information. + * @param data User-defined data passed to the function + * + * @return 0 if absent, 1 if present, -1 on error + */ +int cvmx_sfp_check_mod_abs(struct cvmx_fdt_sfp_info *sfp, void *data); + +/** + * Registers a function to be called to check mod_abs/mod_pres for a SFP/QSFP + * slot. + * + * @param sfp Handle to SFP data structure + * @param check_mod_abs Function to be called or NULL to remove + * @param mod_abs_data User-defined data to be passed to check_mod_abs + * + * @return 0 for success + */ +int cvmx_sfp_register_check_mod_abs(struct cvmx_fdt_sfp_info *sfp, + int (*check_mod_abs)(struct cvmx_fdt_sfp_info *sfp, void *data), + void *mod_abs_data); + +/** + * Registers a function to be called whenever the mod_abs/mod_pres signal + * changes. + * + * @param sfp Handle to SFP data structure + * @param mod_abs_changed Function called whenever mod_abs is changed + * or NULL to remove. + * @param mod_abs_changed_data User-defined data passed to + * mod_abs_changed + * + * @return 0 for success + */ +int cvmx_sfp_register_mod_abs_changed(struct cvmx_fdt_sfp_info *sfp, + int (*mod_abs_changed)(struct cvmx_fdt_sfp_info *sfp, int val, + void *data), + void *mod_abs_changed_data); + +/** + * Function called to check and return the status of the tx_fault pin + * + * @param sfp Handle to SFP information. + * @param data User-defined data passed to the function + * + * @return 0 if signal present, 1 if signal absent, -1 on error + */ +int cvmx_sfp_check_tx_fault(struct cvmx_fdt_sfp_info *sfp, void *data); + +/** + * Function called to check and return the status of the rx_los pin + * + * @param sfp Handle to SFP information. + * @param data User-defined data passed to the function + * + * @return 0 if signal present, 1 if signal absent, -1 on error + */ +int cvmx_sfp_check_rx_los(struct cvmx_fdt_sfp_info *sfp, void *data); + +/** + * Registers a function to be called whenever rx_los changes + * + * @param sfp Handle to SFP data structure + * @param rx_los_changed Function to be called when rx_los changes + * or NULL to remove the function + * @param rx_los_changed_data User-defined data passed to + * rx_los_changed + * + * @return 0 for success + */ +int cvmx_sfp_register_rx_los_changed(struct cvmx_fdt_sfp_info *sfp, + int (*rx_los_changed)(struct cvmx_fdt_sfp_info *sfp, int val, + void *data), + void *rx_los_changed_data); + +/** + * Parses the device tree for SFP and QSFP slots + * + * @param fdt_addr Address of flat device-tree + * + * @return 0 for success, -1 on error + */ +int cvmx_sfp_parse_device_tree(const void *fdt_addr); + +/** + * Given an IPD port number find the corresponding SFP or QSFP slot + * + * @param ipd_port IPD port number to search for + * + * @return pointer to SFP data structure or NULL if not found + */ +struct cvmx_fdt_sfp_info *cvmx_sfp_find_slot_by_port(int ipd_port); + +/** + * Given a fdt node offset find the corresponding SFP or QSFP slot + * + * @param of_offset flat device tree node offset + * + * @return pointer to SFP data structure or NULL if not found + */ +struct cvmx_fdt_sfp_info *cvmx_sfp_find_slot_by_fdt_node(int of_offset); + +/** + * Reads the EEPROMs of all SFP modules. + * + * @return 0 for success + */ +int cvmx_sfp_read_all_modules(void); + +/** + * Validates if the module is correct for the specified port + * + * @param[in] sfp SFP port to check + * @param mode interface mode + * + * @return true if module is valid, false if invalid + * NOTE: This will also toggle the error LED, if present + */ +bool cvmx_sfp_validate_module(struct cvmx_fdt_sfp_info *sfp, int mode); + +/** + * Prints information about the SFP module + * + * @param[in] sfp sfp data structure + */ +void cvmx_sfp_print_info(const struct cvmx_fdt_sfp_info *sfp); + +#endif /* __CVMX_HELPER_SFP_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-sgmii.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-sgmii.h new file mode 100644 index 0000000000..c5110c9513 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-sgmii.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for SGMII initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_SGMII_H__ +#define __CVMX_HELPER_SGMII_H__ + +/** + * @INTERNAL + * Probe a SGMII interface and determine the number of ports + * connected to it. The SGMII interface should still be down after + * this call. + * + * @param xiface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_sgmii_probe(int xiface); +int __cvmx_helper_sgmii_enumerate(int xiface); + +/** + * @INTERNAL + * Bringup and enable a SGMII interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_sgmii_enable(int xiface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_sgmii_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * Configure a port for internal and/or external loopback. Internal loopback + * causes packets sent by the port to be received by Octeon. External loopback + * causes packets received from the wire to sent out again. + * + * @param ipd_port IPD/PKO port to loopback. + * @param enable_internal + * Non zero if you want internal loopback + * @param enable_external + * Non zero if you want external loopback + * + * @return Zero on success, negative on failure. + */ +int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal, int enable_external); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-spi.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-spi.h new file mode 100644 index 0000000000..cae72f2172 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-spi.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for SPI initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_SPI_H__ +#define __CVMX_HELPER_SPI_H__ + +#include "cvmx-helper.h" + +/** + * @INTERNAL + * Probe a SPI interface and determine the number of ports + * connected to it. The SPI interface should still be down after + * this call. + * + * @param interface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_spi_probe(int interface); +int __cvmx_helper_spi_enumerate(int interface); + +/** + * @INTERNAL + * Bringup and enable a SPI interface. After this call packet I/O + * should be fully functional. This is called with IPD enabled but + * PKO disabled. + * + * @param interface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_spi_enable(int interface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +/** + * Sets the spi timeout in config data + * @param timeout value + */ +void cvmx_spi_config_set_timeout(int timeout); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-srio.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-srio.h new file mode 100644 index 0000000000..2b7571dced --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-srio.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for SRIO initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_SRIO_H__ +#define __CVMX_HELPER_SRIO_H__ + +/** + * @INTERNAL + * Convert interface number to sRIO link number + * per SoC model. + * + * @param xiface Interface to convert + * + * @return Srio link number + */ +int __cvmx_helper_srio_port(int xiface); + +/** + * @INTERNAL + * Probe a SRIO interface and determine the number of ports + * connected to it. The SRIO interface should still be down after + * this call. + * + * @param xiface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_srio_probe(int xiface); + +/** + * @INTERNAL + * Bringup and enable a SRIO interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_srio_enable(int xiface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by SRIO link status. + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_srio_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_srio_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-util.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-util.h new file mode 100644 index 0000000000..cf98eaeba4 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-util.h @@ -0,0 +1,412 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + */ + +#ifndef __CVMX_HELPER_UTIL_H__ +#define __CVMX_HELPER_UTIL_H__ + +#include "cvmx-mio-defs.h" +#include "cvmx-helper.h" +#include "cvmx-fpa.h" + +typedef char cvmx_pknd_t; +typedef char cvmx_bpid_t; + +#define CVMX_INVALID_PKND ((cvmx_pknd_t)-1) +#define CVMX_INVALID_BPID ((cvmx_bpid_t)-1) +#define CVMX_MAX_PKND ((cvmx_pknd_t)64) +#define CVMX_MAX_BPID ((cvmx_bpid_t)64) + +#define CVMX_HELPER_MAX_IFACE 11 +#define CVMX_HELPER_MAX_PORTS 16 + +/* Maximum range for normalized (a.k.a. IPD) port numbers (12-bit field) */ +#define CVMX_PKO3_IPD_NUM_MAX 0x1000 //FIXME- take it from someplace else ? +#define CVMX_PKO3_DQ_NUM_MAX 0x400 // 78xx has 1024 queues + +#define CVMX_PKO3_IPD_PORT_NULL (CVMX_PKO3_IPD_NUM_MAX - 1) +#define CVMX_PKO3_IPD_PORT_LOOP 0 + +struct cvmx_xport { + int node; + int port; +}; + +typedef struct cvmx_xport cvmx_xport_t; + +static inline struct cvmx_xport cvmx_helper_ipd_port_to_xport(int ipd_port) +{ + struct cvmx_xport r; + + r.port = ipd_port & (CVMX_PKO3_IPD_NUM_MAX - 1); + r.node = (ipd_port >> 12) & CVMX_NODE_MASK; + return r; +} + +static inline int cvmx_helper_node_to_ipd_port(int node, int index) +{ + return (node << 12) + index; +} + +struct cvmx_xdq { + int node; + int queue; +}; + +typedef struct cvmx_xdq cvmx_xdq_t; + +static inline struct cvmx_xdq cvmx_helper_queue_to_xdq(int queue) +{ + struct cvmx_xdq r; + + r.queue = queue & (CVMX_PKO3_DQ_NUM_MAX - 1); + r.node = (queue >> 10) & CVMX_NODE_MASK; + return r; +} + +static inline int cvmx_helper_node_to_dq(int node, int queue) +{ + return (node << 10) + queue; +} + +struct cvmx_xiface { + int node; + int interface; +}; + +typedef struct cvmx_xiface cvmx_xiface_t; + +/** + * Return node and interface number from XIFACE. + * + * @param xiface interface with node information + * + * @return struct that contains node and interface number. + */ +static inline struct cvmx_xiface cvmx_helper_xiface_to_node_interface(int xiface) +{ + cvmx_xiface_t interface_node; + + /* + * If the majic number 0xde0000 is not present in the + * interface, then assume it is node 0. + */ + + if (((xiface >> 0x8) & 0xff) == 0xde) { + interface_node.node = (xiface >> 16) & CVMX_NODE_MASK; + interface_node.interface = xiface & 0xff; + } else { + interface_node.node = cvmx_get_node_num(); + interface_node.interface = xiface & 0xff; + } + return interface_node; +} + +/* Used internally only*/ +static inline bool __cvmx_helper_xiface_is_null(int xiface) +{ + return (xiface & 0xff) == 0xff; +} + +#define __CVMX_XIFACE_NULL 0xff + +/** + * Return interface with majic number and node information (XIFACE) + * + * @param node node of the interface referred to + * @param interface interface to use. + * + * @return + */ +static inline int cvmx_helper_node_interface_to_xiface(int node, int interface) +{ + return ((node & CVMX_NODE_MASK) << 16) | (0xde << 8) | (interface & 0xff); +} + +/** + * Free the pip packet buffers contained in a work queue entry. + * The work queue entry is not freed. + * + * @param work Work queue entry with packet to free + */ +static inline void cvmx_helper_free_pip_pkt_data(cvmx_wqe_t *work) +{ + u64 number_buffers; + cvmx_buf_ptr_t buffer_ptr; + cvmx_buf_ptr_t next_buffer_ptr; + u64 start_of_buffer; + + number_buffers = work->word2.s.bufs; + if (number_buffers == 0) + return; + + buffer_ptr = work->packet_ptr; + + /* Since the number of buffers is not zero, we know this is not a dynamic + short packet. We need to check if it is a packet received with + IPD_CTL_STATUS[NO_WPTR]. If this is true, we need to free all buffers + except for the first one. The caller doesn't expect their WQE pointer + to be freed */ + start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; + if (cvmx_ptr_to_phys(work) == start_of_buffer) { + next_buffer_ptr = *(cvmx_buf_ptr_t *)cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); + buffer_ptr = next_buffer_ptr; + number_buffers--; + } + + while (number_buffers--) { + /* Remember the back pointer is in cache lines, not 64bit words */ + start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7; + /* Read pointer to next buffer before we free the current buffer. */ + next_buffer_ptr = *(cvmx_buf_ptr_t *)cvmx_phys_to_ptr(buffer_ptr.s.addr - 8); + cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer), buffer_ptr.s.pool, 0); + buffer_ptr = next_buffer_ptr; + } +} + +/** + * Free the pki packet buffers contained in a work queue entry. + * If first packet buffer contains wqe, wqe gets freed too so do not access + * wqe after calling this function. + * This function asssumes that buffers to be freed are from + * Naturally aligned pool/aura. + * It does not use don't write back. + * @param work Work queue entry with packet to free + */ +static inline void cvmx_helper_free_pki_pkt_data(cvmx_wqe_t *work) +{ + u64 number_buffers; + u64 start_of_buffer; + cvmx_buf_ptr_pki_t next_buffer_ptr; + cvmx_buf_ptr_pki_t buffer_ptr; + cvmx_wqe_78xx_t *wqe = (cvmx_wqe_78xx_t *)work; + + if (!octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) { + return; + } + /* Make sure errata pki-20776 has been applied*/ + cvmx_wqe_pki_errata_20776(work); + buffer_ptr = wqe->packet_ptr; + number_buffers = cvmx_wqe_get_bufs(work); + + while (number_buffers--) { + /* FIXME: change WQE function prototype */ + unsigned int x = cvmx_wqe_get_aura(work); + cvmx_fpa3_gaura_t aura = __cvmx_fpa3_gaura(x >> 10, x & 0x3ff); + /* XXX- assumes the buffer is cache-line aligned and naturally aligned mode*/ + start_of_buffer = (buffer_ptr.addr >> 7) << 7; + /* Read pointer to next buffer before we free the current buffer. */ + next_buffer_ptr = *(cvmx_buf_ptr_pki_t *)cvmx_phys_to_ptr(buffer_ptr.addr - 8); + /* FPA AURA comes from WQE, includes node */ + cvmx_fpa3_free(cvmx_phys_to_ptr(start_of_buffer), aura, 0); + buffer_ptr = next_buffer_ptr; + } +} + +/** + * Free the pki wqe entry buffer. + * If wqe buffers contains first packet buffer, wqe does not get freed here. + * This function asssumes that buffers to be freed are from + * Naturally aligned pool/aura. + * It does not use don't write back. + * @param work Work queue entry to free + */ +static inline void cvmx_wqe_pki_free(cvmx_wqe_t *work) +{ + cvmx_wqe_78xx_t *wqe = (cvmx_wqe_78xx_t *)work; + unsigned int x; + cvmx_fpa3_gaura_t aura; + + if (!octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) { + return; + } + /* Do nothing if the first packet buffer shares WQE buffer */ + if (!wqe->packet_ptr.packet_outside_wqe) + return; + + /* FIXME change WQE function prototype */ + x = cvmx_wqe_get_aura(work); + aura = __cvmx_fpa3_gaura(x >> 10, x & 0x3ff); + + cvmx_fpa3_free(work, aura, 0); +} + +/** + * Convert a interface mode into a human readable string + * + * @param mode Mode to convert + * + * @return String + */ +const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode); + +/** + * Debug routine to dump the packet structure to the console + * + * @param work Work queue entry containing the packet to dump + * @return + */ +int cvmx_helper_dump_packet(cvmx_wqe_t *work); + +/** + * Get the version of the CVMX libraries. + * + * @return Version string. Note this buffer is allocated statically + * and will be shared by all callers. + */ +const char *cvmx_helper_get_version(void); + +/** + * @INTERNAL + * Setup the common GMX settings that determine the number of + * ports. These setting apply to almost all configurations of all + * chips. + * + * @param xiface Interface to configure + * @param num_ports Number of ports on the interface + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_setup_gmx(int xiface, int num_ports); + +/** + * @INTERNAL + * Get the number of pko_ports on an interface. + * + * @param interface + * + * @return the number of pko_ports on the interface. + */ +int __cvmx_helper_get_num_pko_ports(int interface); + +/** + * Returns the IPD port number for a port on the given + * interface. + * + * @param interface Interface to use + * @param port Port on the interface + * + * @return IPD port number + */ +int cvmx_helper_get_ipd_port(int interface, int port); + +/** + * Returns the PKO port number for a port on the given interface, + * This is the base pko_port for o68 and ipd_port for older models. + * + * @param interface Interface to use + * @param port Port on the interface + * + * @return PKO port number and -1 on error. + */ +int cvmx_helper_get_pko_port(int interface, int port); + +/** + * Returns the IPD/PKO port number for the first port on the given + * interface. + * + * @param interface Interface to use + * + * @return IPD/PKO port number + */ +static inline int cvmx_helper_get_first_ipd_port(int interface) +{ + return cvmx_helper_get_ipd_port(interface, 0); +} + +int cvmx_helper_ports_on_interface(int interface); + +/** + * Returns the IPD/PKO port number for the last port on the given + * interface. + * + * @param interface Interface to use + * + * @return IPD/PKO port number + * + * Note: for o68, the last ipd port on an interface does not always equal to + * the first plus the number of ports as the ipd ports are not contiguous in + * some cases, e.g., SGMII. + * + * Note: code that makes the assumption of contiguous ipd port numbers needs to + * be aware of this. + */ +static inline int cvmx_helper_get_last_ipd_port(int interface) +{ + return cvmx_helper_get_ipd_port(interface, cvmx_helper_ports_on_interface(interface) - 1); +} + +/** + * Free the packet buffers contained in a work queue entry. + * The work queue entry is not freed. + * Note that this function will not free the work queue entry + * even if it contains a non-redundant data packet, and hence + * it is not really comparable to how the PKO would free a packet + * buffers if requested. + * + * @param work Work queue entry with packet to free + */ +void cvmx_helper_free_packet_data(cvmx_wqe_t *work); + +/** + * Returns the interface number for an IPD/PKO port number. + * + * @param ipd_port IPD/PKO port number + * + * @return Interface number + */ +int cvmx_helper_get_interface_num(int ipd_port); + +/** + * Returns the interface index number for an IPD/PKO port + * number. + * + * @param ipd_port IPD/PKO port number + * + * @return Interface index number + */ +int cvmx_helper_get_interface_index_num(int ipd_port); + +/** + * Get port kind for a given port in an interface. + * + * @param xiface Interface + * @param index index of the port in the interface + * + * @return port kind on sucicess and -1 on failure + */ +int cvmx_helper_get_pknd(int xiface, int index); + +/** + * Get bpid for a given port in an interface. + * + * @param interface Interface + * @param port index of the port in the interface + * + * @return port kind on sucicess and -1 on failure + */ +int cvmx_helper_get_bpid(int interface, int port); + +/** + * Internal functions. + */ +int __cvmx_helper_post_init_interfaces(void); +int cvmx_helper_setup_red(int pass_thresh, int drop_thresh); +void cvmx_helper_show_stats(int port); + +/* + * Return number of array alements + */ +#define NUM_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) + +/** + * Prints out a buffer with the address, hex bytes, and ASCII + * + * @param addr Start address to print on the left + * @param[in] buffer array of bytes to print + * @param count Number of bytes to print + */ +void cvmx_print_buffer_u8(unsigned int addr, const u8 *buffer, size_t count); + +#endif /* __CVMX_HELPER_H__ */ diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper-xaui.h b/arch/mips/mach-octeon/include/mach/cvmx-helper-xaui.h new file mode 100644 index 0000000000..6ff4576f23 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper-xaui.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Functions for XAUI initialization, configuration, + * and monitoring. + */ + +#ifndef __CVMX_HELPER_XAUI_H__ +#define __CVMX_HELPER_XAUI_H__ + +/** + * @INTERNAL + * Probe a XAUI interface and determine the number of ports + * connected to it. The XAUI interface should still be down + * after this call. + * + * @param xiface Interface to probe + * + * @return Number of ports on the interface. Zero to disable. + */ +int __cvmx_helper_xaui_probe(int xiface); +int __cvmx_helper_xaui_enumerate(int xiface); + +/** + * @INTERNAL + * Bringup and enable a XAUI interface. After this call packet + * I/O should be fully functional. This is called with IPD + * enabled but PKO disabled. + * + * @param xiface Interface to bring up + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_xaui_enable(int xiface); + +/** + * Retrain XAUI interface. + * + * GMX is disabled as part of retraining. + * While GMX is disabled, new received packets are dropped. + * If GMX was in the middle of recieving a packet when disabled, + * that packet will be received before GMX idles. + * Transmitted packets are buffered normally, but not sent. + * If GMX was in the middle of transmitting a packet when disabled, + * that packet will be transmitted before GMX idles. + * + * @param interface Interface to retrain + * + * @return Zero on success, negative on failure + */ +int cvmx_helper_xaui_link_retrain(int interface); + +/** + * Reinitialize XAUI interface. Does a probe without changing the hardware + * state. + * + * @param interface Interface to reinitialize + * + * @return 0 on success, negative on failure + */ +int cvmx_helper_xaui_link_reinit(int interface); + +/** + * @INTERNAL + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port); + +/** + * @INTERNAL + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * Configure a port for internal and/or external loopback. Internal loopback + * causes packets sent by the port to be received by Octeon. External loopback + * causes packets received from the wire to sent out again. + * + * @param ipd_port IPD/PKO port to loopback. + * @param enable_internal + * Non zero if you want internal loopback + * @param enable_external + * Non zero if you want external loopback + * + * @return Zero on success, negative on failure. + */ +int __cvmx_helper_xaui_configure_loopback(int ipd_port, int enable_internal, int enable_external); + +#endif diff --git a/arch/mips/mach-octeon/include/mach/cvmx-helper.h b/arch/mips/mach-octeon/include/mach/cvmx-helper.h new file mode 100644 index 0000000000..b82e201269 --- /dev/null +++ b/arch/mips/mach-octeon/include/mach/cvmx-helper.h @@ -0,0 +1,565 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 Marvell International Ltd. + * + * Helper functions for common, but complicated tasks. + */ + +#ifndef __CVMX_HELPER_H__ +#define __CVMX_HELPER_H__ + +#include "cvmx-wqe.h" + +/* Max number of GMXX */ +#define CVMX_HELPER_MAX_GMX \ + (OCTEON_IS_MODEL(OCTEON_CN78XX) ? \ + 6 : \ + (OCTEON_IS_MODEL(OCTEON_CN68XX) ? \ + 5 : \ + (OCTEON_IS_MODEL(OCTEON_CN73XX) ? \ + 3 : \ + (OCTEON_IS_MODEL(OCTEON_CNF75XX) ? 1 : 2)))) + +#define CVMX_HELPER_CSR_INIT0 \ + 0 /* Do not change as + CVMX_HELPER_WRITE_CSR() + assumes it */ +#define CVMX_HELPER_CSR_INIT_READ -1 + +/* + * CVMX_HELPER_WRITE_CSR--set a field in a CSR with a value. + * + * @param chcsr_init initial value of the csr (CVMX_HELPER_CSR_INIT_READ + * means to use the existing csr value as the + * initial value.) + * @param chcsr_csr the name of the csr + * @param chcsr_type the type of the csr (see the -defs.h) + * @param chcsr_chip the chip for the csr/field + * @param chcsr_fld the field in the csr + * @param chcsr_val the value for field + */ +#define CVMX_HELPER_WRITE_CSR(chcsr_init, chcsr_csr, chcsr_type, chcsr_chip, chcsr_fld, chcsr_val) \ + do { \ + chcsr_type csr; \ + if ((chcsr_init) == CVMX_HELPER_CSR_INIT_READ) \ + csr.u64 = cvmx_read_csr(chcsr_csr); \ + else \ + csr.u64 = (chcsr_init); \ + csr.chcsr_chip.chcsr_fld = (chcsr_val); \ + cvmx_write_csr((chcsr_csr), csr.u64); \ + } while (0) + +/* + * CVMX_HELPER_WRITE_CSR0--set a field in a CSR with the initial value of 0 + */ +#define CVMX_HELPER_WRITE_CSR0(chcsr_csr, chcsr_type, chcsr_chip, chcsr_fld, chcsr_val) \ + CVMX_HELPER_WRITE_CSR(CVMX_HELPER_CSR_INIT0, chcsr_csr, chcsr_type, chcsr_chip, chcsr_fld, \ + chcsr_val) + +/* + * CVMX_HELPER_WRITE_CSR1--set a field in a CSR with the initial value of + * the CSR's current value. + */ +#define CVMX_HELPER_WRITE_CSR1(chcsr_csr, chcsr_type, chcsr_chip, chcsr_fld, chcsr_val) \ + CVMX_HELPER_WRITE_CSR(CVMX_HELPER_CSR_INIT_READ, chcsr_csr, chcsr_type, chcsr_chip, \ + chcsr_fld, chcsr_val) + +/* These flags are passed to __cvmx_helper_packet_hardware_enable */ + +typedef enum { + CVMX_HELPER_INTERFACE_MODE_DISABLED, + CVMX_HELPER_INTERFACE_MODE_RGMII, + CVMX_HELPER_INTERFACE_MODE_GMII, + CVMX_HELPER_INTERFACE_MODE_SPI, + CVMX_HELPER_INTERFACE_MODE_PCIE, + CVMX_HELPER_INTERFACE_MODE_XAUI, + CVMX_HELPER_INTERFACE_MODE_SGMII, + CVMX_HELPER_INTERFACE_MODE_PICMG, + CVMX_HELPER_INTERFACE_MODE_NPI, + CVMX_HELPER_INTERFACE_MODE_LOOP, + CVMX_HELPER_INTERFACE_MODE_SRIO, + CVMX_HELPER_INTERFACE_MODE_ILK, + CVMX_HELPER_INTERFACE_MODE_RXAUI, + CVMX_HELPER_INTERFACE_MODE_QSGMII, + CVMX_HELPER_INTERFACE_MODE_AGL, + CVMX_HELPER_INTERFACE_MODE_XLAUI, + CVMX_HELPER_INTERFACE_MODE_XFI, + CVMX_HELPER_INTERFACE_MODE_10G_KR, + CVMX_HELPER_INTERFACE_MODE_40G_KR4, + CVMX_HELPER_INTERFACE_MODE_MIXED, +} cvmx_helper_interface_mode_t; + +typedef union cvmx_helper_link_info { + u64 u64; + struct { + u64 reserved_20_63 : 43; + u64 init_success : 1; + u64 link_up : 1; + u64 full_duplex : 1; + u64 speed : 18; + } s; +} cvmx_helper_link_info_t; + +/** + * Sets the back pressure configuration in internal data structure. + * @param backpressure_dis disable/enable backpressure + */ +void cvmx_rgmii_set_back_pressure(u64 backpressure_dis); + +#include "cvmx-helper-fpa.h" + +#include "cvmx-helper-agl.h" +#include "cvmx-helper-errata.h" +#include "cvmx-helper-ilk.h" +#include "cvmx-helper-loop.h" +#include "cvmx-helper-npi.h" +#include "cvmx-helper-rgmii.h" +#include "cvmx-helper-sgmii.h" +#include "cvmx-helper-spi.h" +#include "cvmx-helper-srio.h" +#include "cvmx-helper-util.h" +#include "cvmx-helper-xaui.h" + +#include "cvmx-fpa3.h" + +enum cvmx_pko_padding { + CVMX_PKO_PADDING_NONE = 0, + CVMX_PKO_PADDING_60 = 1, +}; + +/** + * This function enables the IPD and also enables the packet interfaces. + * The packet interfaces (RGMII and SPI) must be enabled after the + * IPD. This should be called by the user program after any additional + * IPD configuration changes are made if CVMX_HELPER_ENABLE_IPD + * is not set in the executive-config.h file. + * + * @return 0 on success + * -1 on failure + */ +int cvmx_helper_ipd_and_packet_input_enable_node(int node); +int cvmx_helper_ipd_and_packet_input_enable(void); + +/** + * Initialize and allocate memory for the SSO. + * + * @param wqe_entries The maximum number of work queue entries to be + * supported. + * + * @return Zero on success, non-zero on failure. + */ +int cvmx_helper_initialize_sso(int wqe_entries); + +/** + * Initialize and allocate memory for the SSO on a specific node. + * + * @param node Node SSO to initialize + * @param wqe_entries The maximum number of work queue entries to be + * supported. + * + * @return Zero on success, non-zero on failure. + */ +int cvmx_helper_initialize_sso_node(unsigned int node, int wqe_entries); + +/** + * Undo the effect of cvmx_helper_initialize_sso(). + * + * @return Zero on success, non-zero on failure. + */ +int cvmx_helper_uninitialize_sso(void); + +/** + * Undo the effect of cvmx_helper_initialize_sso_node(). + * + * @param node Node SSO to initialize + * + * @return Zero on success, non-zero on failure. + */ +int cvmx_helper_uninitialize_sso_node(unsigned int node); + +/** + * Initialize the PIP, IPD, and PKO hardware to support + * simple priority based queues for the ethernet ports. Each + * port is configured with a number of priority queues based + * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower + * priority than the previous. + * + * @return Zero on success, non-zero on failure + */ +int cvmx_helper_initialize_packet_io_global(void); +/** + * Initialize the PIP, IPD, and PKO hardware to support + * simple priority based queues for the ethernet ports. Each + * port is configured with a number of priority queues based + * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower + * priority than the previous. + * + * @param node Node on which to initialize packet io hardware + * + * @return Zero on success, non-zero on failure + */ +int cvmx_helper_initialize_packet_io_node(unsigned int node); + +/** + * Does core local initialization for packet io + * + * @return Zero on success, non-zero on failure + */ +int cvmx_helper_initialize_packet_io_local(void); + +/** + * Undo the initialization performed in + * cvmx_helper_initialize_packet_io_global(). After calling this routine and the + * local version on each core, packet IO for Octeon will be disabled and placed + * in the initial reset state. It will then be safe to call the initialize + * later on. Note that this routine does not empty the FPA pools. It frees all + * buffers used by the packet IO hardware to the FPA so a function emptying the + * FPA after shutdown should find all packet buffers in the FPA. + * + * @return Zero on success, negative on failure. + */ +int cvmx_helper_shutdown_packet_io_global(void); + +/** + * Helper function for 78xx global packet IO shutdown + */ +int cvmx_helper_shutdown_packet_io_global_cn78xx(int node); + +/** + * Does core local shutdown of packet io + * + * @return Zero on success, non-zero on failure + */ +int cvmx_helper_shutdown_packet_io_local(void); + +/** + * Returns the number of ports on the given interface. + * The interface must be initialized before the port count + * can be returned. + * + * @param interface Which interface to return port count for. + * + * @return Port count for interface + * -1 for uninitialized interface + */ +int cvmx_helper_ports_on_interface(int interface); + +/** + * Return the number of interfaces the chip has. Each interface + * may have multiple ports. Most chips support two interfaces, + * but the CNX0XX and CNX1XX are exceptions. These only support + * one interface. + * + * @return Number of interfaces on chip + */ +int cvmx_helper_get_number_of_interfaces(void); + +/** + * Get the operating mode of an interface. Depending on the Octeon + * chip and configuration, this function returns an enumeration + * of the type of packet I/O supported by an interface. + * + * @param xiface Interface to probe + * + * @return Mode of the interface. Unknown or unsupported interfaces return + * DISABLED. + */ +cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int xiface); + +/** + * Auto configure an IPD/PKO port link state and speed. This + * function basically does the equivalent of: + * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port)); + * + * @param ipd_port IPD/PKO port to auto configure + * + * @return Link state after configure + */ +cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port); + +/** + * Return the link state of an IPD/PKO port as returned by + * auto negotiation. The result of this function may not match + * Octeon's link config if auto negotiation has changed since + * the last call to cvmx_helper_link_set(). + * + * @param ipd_port IPD/PKO port to query + * + * @return Link state + */ +cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port); + +/** + * Configure an IPD/PKO port for the specified link state. This + * function does not influence auto negotiation at the PHY level. + * The passed link state must always match the link state returned + * by cvmx_helper_link_get(). It is normally best to use + * cvmx_helper_link_autoconf() instead. + * + * @param ipd_port IPD/PKO port to configure + * @param link_info The new link state + * + * @return Zero on success, negative on failure + */ +int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info); + +/** + * This function probes an interface to determine the actual number of + * hardware ports connected to it. It does some setup the ports but + * doesn't enable them. The main goal here is to set the global + * interface_port_count[interface] correctly. Final hardware setup of + * the ports will be performed later. + * + * @param xiface Interface to probe + * + * @return Zero on success, negative on failure + */ +int cvmx_helper_interface_probe(int xiface); + +/** + * Determine the actual number of hardware ports connected to an + * interface. It doesn't setup the ports or enable them. + * + * @param xiface Interface to enumerate + * + * @return Zero on success, negative on failure + */ +int cvmx_helper_interface_enumerate(int xiface); + +/** + * Configure a port for internal and/or external loopback. Internal loopback + * causes packets sent by the port to be received by Octeon. External loopback + * causes packets received from the wire to sent out again. + * + * @param ipd_port IPD/PKO port to loopback. + * @param enable_internal + * Non zero if you want internal loopback + * @param enable_external + * Non zero if you want external loopback + * + * @return Zero on success, negative on failure. + */ +int cvmx_helper_configure_loopback(int ipd_port, int enable_internal, int enable_external); + +/** + * Returns the number of ports on the given interface. + * + * @param interface Which interface to return port count for. + * + * @return Port count for interface + * -1 for uninitialized interface + */ +int __cvmx_helper_early_ports_on_interface(int interface); + +void cvmx_helper_setup_simulator_io_buffer_counts(int node, int num_packet_buffers, + int pko_buffers); + +void cvmx_helper_set_wqe_no_ptr_mode(bool mode); +void cvmx_helper_set_pkt_wqe_le_mode(bool mode); +int cvmx_helper_shutdown_fpa_pools(int node); + +/** + * Convert Ethernet QoS/PCP value to system-level priority + * + * In OCTEON, highest priority is 0, in Ethernet 802.1p PCP field + * the highest priority is 7, lowest is 1. Here is the full conversion + * table between QoS (PCP) and OCTEON priority values, per IEEE 802.1Q-2005: + * + * PCP Priority Acronym Traffic Types + * 1 7 (lowest) BK Background + * 0 6 BE Best Effort + * 2 5 EE Excellent Effort + * 3 4 CA Critical Applications + * 4 3 VI Video, < 100 ms latency and jitter + * 5 2 VO Voice, < 10 ms latency and jitter + * 6 1 IC Internetwork Control + * 7 0 (highest) NC Network Control + */ +static inline u8 cvmx_helper_qos2prio(u8 qos) +{ + static const unsigned int pcp_map = 6 << (4 * 0) | 7 << (4 * 1) | 5 << (4 * 2) | + 4 << (4 * 3) | 3 << (4 * 4) | 2 << (4 * 5) | + 1 << (4 * 6) | 0 << (4 * 7); + + return (pcp_map >> ((qos & 0x7) << 2)) & 0x7; +} + +/** + * Convert system-level priority to Ethernet QoS/PCP value + * + * Calculate the reverse of cvmx_helper_qos2prio() per IEEE 802.1Q-2005. + */ +static inline u8 cvmx_helper_prio2qos(u8 prio) +{ + static const unsigned int prio_map = 7 << (4 * 0) | 6 << (4 * 1) | 5 << (4 * 2) | + 4 << (4 * 3) | 3 << (4 * 4) | 2 << (4 * 5) | + 0 << (4 * 6) | 1 << (4 * 7); + + return (prio_map >> ((prio & 0x7) << 2)) & 0x7; +} + +/** + * @INTERNAL + * Get the number of ipd_ports on an interface. + * + * @param xiface + * + * @return the number of ipd_ports on the interface and -1 for error. + */ +int __cvmx_helper_get_num_ipd_ports(int xiface); + +enum cvmx_pko_padding __cvmx_helper_get_pko_padding(int xiface); + +/** + * @INTERNAL + * + * @param xiface + * @param num_ipd_ports is the number of ipd_ports on the interface + * @param has_fcs indicates if PKO does FCS for the ports on this + * @param pad The padding that PKO should apply. + * interface. + * + * @return 0 for success and -1 for failure + */ +int __cvmx_helper_init_interface(int xiface, int num_ipd_ports, int has_fcs, + enum cvmx_pko_padding pad); + +void __cvmx_helper_shutdown_interfaces(void); + +/* + * @INTERNAL + * Enable packet input/output from the hardware. This function is + * called after all internal setup is complete and IPD is enabled. + * After this function completes, packets will be accepted from the + * hardware ports. PKO should still be disabled to make sure packets + * aren't sent out partially setup hardware. + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_packet_hardware_enable(int xiface); + +/* + * @INTERNAL + * + * @return 0 for success and -1 for failure + */ +int __cvmx_helper_set_link_info(int xiface, int index, cvmx_helper_link_info_t link_info); + +/** + * @INTERNAL + * + * @param xiface + * @param port + * + * @return valid link_info on success or -1 on failure + */ +cvmx_helper_link_info_t __cvmx_helper_get_link_info(int xiface, int port); + +/** + * @INTERNAL + * + * @param xiface + * + * @return 0 if PKO does not do FCS and 1 otherwise. + */ +int __cvmx_helper_get_has_fcs(int xiface); + +void *cvmx_helper_mem_alloc(int node, u64 alloc_size, u64 align); +void cvmx_helper_mem_free(void *buffer, u64 size); + +#define CVMX_QOS_NUM 8 /* Number of QoS priority classes */ + +typedef enum { + CVMX_QOS_PROTO_NONE, /* Disable QOS */ + CVMX_QOS_PROTO_PAUSE, /* IEEE 802.3 PAUSE */ + CVMX_QOS_PROTO_PFC /* IEEE 802.1Qbb-2011 PFC/CBFC */ +} cvmx_qos_proto_t; + +typedef enum { + CVMX_QOS_PKT_MODE_HWONLY, /* PAUSE packets processed in Hardware only. */ + CVMX_QOS_PKT_MODE_SWONLY, /* PAUSE packets processed in Software only. */ + CVMX_QOS_PKT_MODE_HWSW, /* PAUSE packets processed in both HW and SW. */ + CVMX_QOS_PKT_MODE_DROP /* Ignore PAUSE packets. */ +} cvmx_qos_pkt_mode_t; + +typedef enum { + CVMX_QOS_POOL_PER_PORT, /* Pool per Physical Port */ + CVMX_QOS_POOL_PER_CLASS /* Pool per Priority Class */ +} cvmx_qos_pool_mode_t; + +typedef struct cvmx_qos_config { + cvmx_qos_proto_t qos_proto; /* QoS protocol.*/ + cvmx_qos_pkt_mode_t pkt_mode; /* PAUSE processing mode.*/ + cvmx_qos_pool_mode_t pool_mode; /* FPA Pool mode.*/ + int pktbuf_size; /* Packet buffer size */ + int aura_size; /* Number of buffers */ + int drop_thresh[CVMX_QOS_NUM]; /* DROP threashold in % */ + int red_thresh[CVMX_QOS_NUM]; /* RED threashold in % */ + int bp_thresh[CVMX_QOS_NUM]; /* BP threashold in % */ + int groups[CVMX_QOS_NUM]; /* Base SSO group for QOS group set. */ + int group_prio[CVMX_QOS_NUM]; /* SSO group priorities.*/ + int pko_pfc_en; /* Enable PKO PFC layout. */ + int vlan_num; /* VLAN number: 0 = 1st or 1 = 2nd. */ + int p_time; /* PAUSE packets send time (in number of 512 bit-times).*/ + int p_interval; /* PAUSE packet send interval (in number of 512 bit-times).*/ + /* Internal parameters (should not be used by application developer): */ + cvmx_fpa3_pool_t gpools[CVMX_QOS_NUM]; /* Pool to use.*/ + cvmx_fpa3_gaura_t gauras[CVMX_QOS_NUM]; /* Global auras -- one per priority class. */ + int bpids[CVMX_QOS_NUM]; /* PKI BPID.*/ + int qpg_base; /* QPG Table base index.*/ +} cvmx_qos_config_t; + +/** + * Initialize QoS configuraiton with the SDK defaults. + * + * @param qos_cfg User QOS configuration parameters. + * @return Zero on success, negative number otherwise. + */ +int cvmx_helper_qos_config_init(cvmx_qos_proto_t qos_proto, cvmx_qos_config_t *qos_cfg); + +/** + * Update the user static processor configuration. + * It should be done before any initialization of the DP units is performed. + * + * @param xipdport Global IPD port + * @param qos_cfg User QOS configuration parameters. + * @return Zero on success, negative number otherwise. + */ +int cvmx_helper_qos_port_config_update(int xipdport, cvmx_qos_config_t *qos_cfg); + +/** + * Configure the Data Path components for QOS function. + * This function is called after the global processor initialization is + * performed. + * + * @param xipdport Global IPD port + * @param qos_cfg User QOS configuration parameters. + * @return Zero on success, negative number otherwise. + */ +int cvmx_helper_qos_port_setup(int xipdport, cvmx_qos_config_t *qos_cfg); + +/** + * Configure the SSO for QOS function. + * This function is called after the global processor initialization is + * performed. + * + * @param node OCTEON3 node number. + * @param qos_cfg User QOS configuration parameters. + * @return Zero on success, negative number otherwise. + */ +int cvmx_helper_qos_sso_setup(int node, cvmx_qos_config_t *qos_cfg); + +/** + * Return PKI_CHAN_E channel name based on the provided index. + * @param chan Channel index. + * @param namebuf Name buffer (output). + * @param buflen Name maximum length. + * @return Length of name (in bytes) on success, negative number otherwise. + */ +int cvmx_helper_get_chan_e_name(int chan, char *namebuf, int buflen); + +#ifdef CVMX_DUMP_DIAGNOSTICS +void cvmx_helper_dump_for_diagnostics(int node); +#endif + +#endif /* __CVMX_HELPER_H__ */