From patchwork Thu Apr 7 07:11:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roese X-Patchwork-Id: 1614269 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=iupF2Pnn; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (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 bilbo.ozlabs.org (Postfix) with ESMTPS id 4KYt0S3QcLz9sGJ for ; Thu, 7 Apr 2022 17:14:00 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D0E7C83DB2; Thu, 7 Apr 2022 09:13:11 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1649315592; bh=ijNS4pk/ew18a9i3QUqV0JB/xWnX7USib8WXRLyFBYE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=iupF2PnnaqEXoxbtAsxPbbtSgsv+hd6UW+O+l9RLgIDJ6HUTxJAOKHGS3gLrcpv6N fUl2IHhK2WiHEsCKy24QqKIfqQHrCBEKvkWFFnSc2gAKn990d4zS2h+6kJMpmonRsP qdJIuq+gGoiwuGC91L9b9v0VC+SahIaN9pzi5Np1yUw3qZYrw6lclDLbc2lKMYYsXP 735bJmv7apLiaBeUNgwRQNCYgZaIdNoy2uvWHjnGH6Um2TsXWOjW1GVcuAH5ew4d9V BIIQJA9WXPKh+xoukp2pPid5Uz6ZsDhGyfHeVXefgXBGcdSmFyOJk4Qk69oBiH15tG x3GB0DF3oTHsg== Received: by phobos.denx.de (Postfix, from userid 109) id C191F83D44; Thu, 7 Apr 2022 09:12:44 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_NEUTRAL,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from mout-u-107.mailbox.org (mout-u-107.mailbox.org [IPv6:2001:67c:2050:1::465:107]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 09CBA83B42 for ; Thu, 7 Apr 2022 09:12:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=denx.de Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sr@denx.de Received: from smtp2.mailbox.org (unknown [91.198.250.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-u-107.mailbox.org (Postfix) with ESMTPS id 4KYsyC6bbJz9sWB; Thu, 7 Apr 2022 09:12:03 +0200 (CEST) From: Stefan Roese To: u-boot@lists.denx.de Cc: daniel.schwierzeck@gmail.com, awilliams@marvell.com, cchavva@marvell.com Subject: [PATCH v2 14/52] mips: octeon: Add cvmx-helper-ipd.c Date: Thu, 7 Apr 2022 09:11:16 +0200 Message-Id: <20220407071154.51997-15-sr@denx.de> In-Reply-To: <20220407071154.51997-1-sr@denx.de> References: <20220407071154.51997-1-sr@denx.de> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean From: Aaron Williams Import cvmx-helper-ipd.c from 2013 U-Boot. It will be used by the later added drivers to support networking on the MIPS Octeon II / III platforms. Signed-off-by: Aaron Williams Signed-off-by: Stefan Roese --- arch/mips/mach-octeon/cvmx-helper-ipd.c | 286 ++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 arch/mips/mach-octeon/cvmx-helper-ipd.c diff --git a/arch/mips/mach-octeon/cvmx-helper-ipd.c b/arch/mips/mach-octeon/cvmx-helper-ipd.c new file mode 100644 index 000000000000..cb04b63b9b07 --- /dev/null +++ b/arch/mips/mach-octeon/cvmx-helper-ipd.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018-2022 Marvell International Ltd. + * + * IPD helper functions. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/** It allocate pools for packet and wqe pools + * and sets up the FPA hardware + */ +int __cvmx_helper_ipd_setup_fpa_pools(void) +{ + cvmx_fpa_global_initialize(); + if (cvmx_ipd_cfg.packet_pool.buffer_count == 0) + return 0; + __cvmx_helper_initialize_fpa_pool(cvmx_ipd_cfg.packet_pool.pool_num, + cvmx_ipd_cfg.packet_pool.buffer_size, + cvmx_ipd_cfg.packet_pool.buffer_count, + "Packet Buffers"); + if (cvmx_ipd_cfg.wqe_pool.buffer_count == 0) + return 0; + __cvmx_helper_initialize_fpa_pool(cvmx_ipd_cfg.wqe_pool.pool_num, + cvmx_ipd_cfg.wqe_pool.buffer_size, + cvmx_ipd_cfg.wqe_pool.buffer_count, + "WQE Buffers"); + return 0; +} + +/** + * @INTERNAL + * Setup global setting for IPD/PIP not related to a specific + * interface or port. This must be called before IPD is enabled. + * + * @return Zero on success, negative on failure. + */ +int __cvmx_helper_ipd_global_setup(void) +{ + /* Setup the packet and wqe pools*/ + __cvmx_helper_ipd_setup_fpa_pools(); + /* Setup the global packet input options */ + cvmx_ipd_config(cvmx_ipd_cfg.packet_pool.buffer_size / 8, + cvmx_ipd_cfg.first_mbuf_skip / 8, + cvmx_ipd_cfg.not_first_mbuf_skip / 8, + /* The +8 is to account for the next ptr */ + (cvmx_ipd_cfg.first_mbuf_skip + 8) / 128, + /* The +8 is to account for the next ptr */ + (cvmx_ipd_cfg.not_first_mbuf_skip + 8) / 128, + cvmx_ipd_cfg.wqe_pool.pool_num, + (cvmx_ipd_mode_t)(cvmx_ipd_cfg.cache_mode), 1); + return 0; +} + +/** + * Enable or disable FCS stripping for all the ports on an interface. + * + * @param xiface + * @param nports number of ports + * @param has_fcs 0 for disable and !0 for enable + */ +static int cvmx_helper_fcs_op(int xiface, int nports, int has_fcs) +{ + u64 port_bit; + int index; + int pknd; + union cvmx_pip_sub_pkind_fcsx pkind_fcsx; + union cvmx_pip_prt_cfgx port_cfg; + struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface); + + if (!octeon_has_feature(OCTEON_FEATURE_PKND)) + return 0; + if (octeon_has_feature(OCTEON_FEATURE_PKI)) { + cvmx_helper_pki_set_fcs_op(xi.node, xi.interface, nports, + has_fcs); + return 0; + } + + port_bit = 0; + for (index = 0; index < nports; index++) + port_bit |= ((u64)1 << cvmx_helper_get_pknd(xiface, index)); + + pkind_fcsx.u64 = csr_rd(CVMX_PIP_SUB_PKIND_FCSX(0)); + if (has_fcs) + pkind_fcsx.s.port_bit |= port_bit; + else + pkind_fcsx.s.port_bit &= ~port_bit; + csr_wr(CVMX_PIP_SUB_PKIND_FCSX(0), pkind_fcsx.u64); + + for (pknd = 0; pknd < 64; pknd++) { + if ((1ull << pknd) & port_bit) { + port_cfg.u64 = csr_rd(CVMX_PIP_PRT_CFGX(pknd)); + port_cfg.s.crc_en = (has_fcs) ? 1 : 0; + csr_wr(CVMX_PIP_PRT_CFGX(pknd), port_cfg.u64); + } + } + + return 0; +} + +/** + * @INTERNAL + * Configure the IPD/PIP tagging and QoS options for a specific + * port. This function determines the POW work queue entry + * contents for a port. The setup performed here is controlled by + * the defines in executive-config.h. + * + * @param ipd_port Port/Port kind to configure. This follows the IPD numbering, + * not the per interface numbering + * + * @return Zero on success, negative on failure + */ +static int __cvmx_helper_ipd_port_setup(int ipd_port) +{ + union cvmx_pip_prt_cfgx port_config; + union cvmx_pip_prt_tagx tag_config; + + if (octeon_has_feature(OCTEON_FEATURE_PKND)) { + int xiface, index, pknd; + union cvmx_pip_prt_cfgbx prt_cfgbx; + + xiface = cvmx_helper_get_interface_num(ipd_port); + index = cvmx_helper_get_interface_index_num(ipd_port); + pknd = cvmx_helper_get_pknd(xiface, index); + + port_config.u64 = csr_rd(CVMX_PIP_PRT_CFGX(pknd)); + tag_config.u64 = csr_rd(CVMX_PIP_PRT_TAGX(pknd)); + + port_config.s.qos = pknd & 0x7; + + /* Default BPID to use for packets on this port-kind */ + prt_cfgbx.u64 = csr_rd(CVMX_PIP_PRT_CFGBX(pknd)); + prt_cfgbx.s.bpid = pknd; + csr_wr(CVMX_PIP_PRT_CFGBX(pknd), prt_cfgbx.u64); + } else { + port_config.u64 = csr_rd(CVMX_PIP_PRT_CFGX(ipd_port)); + tag_config.u64 = csr_rd(CVMX_PIP_PRT_TAGX(ipd_port)); + + /* Have each port go to a different POW queue */ + port_config.s.qos = ipd_port & 0x7; + } + + /* Process the headers and place the IP header in the work queue */ + port_config.s.mode = + (cvmx_pip_port_parse_mode_t)cvmx_ipd_cfg.port_config.parse_mode; + + tag_config.s.ip6_src_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv6_src_ip; + tag_config.s.ip6_dst_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv6_dst_ip; + tag_config.s.ip6_sprt_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv6_src_port; + tag_config.s.ip6_dprt_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv6_dst_port; + tag_config.s.ip6_nxth_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv6_next_header; + tag_config.s.ip4_src_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv4_src_ip; + tag_config.s.ip4_dst_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv4_dst_ip; + tag_config.s.ip4_sprt_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv4_src_port; + tag_config.s.ip4_dprt_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv4_dst_port; + tag_config.s.ip4_pctl_flag = + cvmx_ipd_cfg.port_config.tag_fields.ipv4_protocol; + tag_config.s.inc_prt_flag = + cvmx_ipd_cfg.port_config.tag_fields.input_port; + tag_config.s.tcp6_tag_type = + (cvmx_pow_tag_type_t)cvmx_ipd_cfg.port_config.tag_type; + tag_config.s.tcp4_tag_type = + (cvmx_pow_tag_type_t)cvmx_ipd_cfg.port_config.tag_type; + tag_config.s.ip6_tag_type = + (cvmx_pow_tag_type_t)cvmx_ipd_cfg.port_config.tag_type; + tag_config.s.ip4_tag_type = + (cvmx_pow_tag_type_t)cvmx_ipd_cfg.port_config.tag_type; + tag_config.s.non_tag_type = + (cvmx_pow_tag_type_t)cvmx_ipd_cfg.port_config.tag_type; + + /* Put all packets in group 0. Other groups can be used by the app */ + tag_config.s.grp = 0; + + cvmx_pip_config_port(ipd_port, port_config, tag_config); + + /* Give the user a chance to override our setting for each port */ + if (cvmx_override_ipd_port_setup) + cvmx_override_ipd_port_setup(ipd_port); + + return 0; +} + +/** + * @INTERNAL + * Setup the IPD/PIP for the ports on an interface. Packet + * classification and tagging are set for every port on the + * interface. The number of ports on the interface must already + * have been probed. + * + * @param xiface to setup IPD/PIP for + * + * @return Zero on success, negative on failure + */ +int __cvmx_helper_ipd_setup_interface(int xiface) +{ + cvmx_helper_interface_mode_t mode; + int num_ports = cvmx_helper_ports_on_interface(xiface); + struct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface); + int ipd_port = cvmx_helper_get_ipd_port(xiface, 0); + int delta; + + if (num_ports == CVMX_HELPER_CFG_INVALID_VALUE) + return 0; + + delta = 1; + if (octeon_has_feature(OCTEON_FEATURE_PKND)) { + if (xi.interface < CVMX_HELPER_MAX_GMX) + delta = 16; + } + + while (num_ports--) { + if (!cvmx_helper_is_port_valid(xiface, num_ports)) + continue; + if (octeon_has_feature(OCTEON_FEATURE_PKI)) + __cvmx_helper_pki_port_setup(xi.node, ipd_port); + else + __cvmx_helper_ipd_port_setup(ipd_port); + ipd_port += delta; + } + /* FCS settings */ + cvmx_helper_fcs_op(xiface, cvmx_helper_ports_on_interface(xiface), + __cvmx_helper_get_has_fcs(xiface)); + + mode = cvmx_helper_interface_get_mode(xiface); + + if (mode == CVMX_HELPER_INTERFACE_MODE_LOOP) + __cvmx_helper_loop_enable(xiface); + + return 0; +}