Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1415022/?format=api
{ "id": 1415022, "url": "http://patchwork.ozlabs.org/api/patches/1415022/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20201211160612.1498780-41-sr@denx.de/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20201211160612.1498780-41-sr@denx.de>", "list_archive_url": null, "date": "2020-12-11T16:06:02", "name": "[v1,40/50] mips: octeon: Add cvmx-helper.c", "commit_ref": "a6d4ffc5653a7d5be029e1b772d4b26446d9da44", "pull_url": null, "state": "accepted", "archived": false, "hash": "7228c184f19e360a0a216d204f43987a9a32aa0a", "submitter": { "id": 13, "url": "http://patchwork.ozlabs.org/api/people/13/?format=api", "name": "Stefan Roese", "email": "sr@denx.de" }, "delegate": { "id": 4307, "url": "http://patchwork.ozlabs.org/api/users/4307/?format=api", "username": "danielschwierzeck", "first_name": "Daniel", "last_name": "Schwierzeck", "email": "daniel.schwierzeck@googlemail.com" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20201211160612.1498780-41-sr@denx.de/mbox/", "series": [ { "id": 220054, "url": "http://patchwork.ozlabs.org/api/series/220054/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=220054", "date": "2020-12-11T16:05:23", "name": "mips: octeon: Add serdes and device helper support incl. DM PCIe driver", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/220054/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1415022/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1415022/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=<UNKNOWN>)", "ozlabs.org;\n dmarc=none (p=none dis=none) header.from=denx.de", "ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=denx.de header.i=@denx.de header.a=rsa-sha256\n header.s=phobos-20191101 header.b=vZ3axeya;\n\tdkim-atps=neutral", "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=denx.de", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n dmarc=none (p=none dis=none) header.from=denx.de", "phobos.denx.de; spf=none smtp.mailfrom=sr@denx.de" ], "Received": [ "from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange X25519 server-signature RSA-PSS (4096 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 4Cswr15447z9sSs\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 12 Dec 2020 03:15:45 +1100 (AEDT)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 1992182611;\n\tFri, 11 Dec 2020 17:09:42 +0100 (CET)", "by phobos.denx.de (Postfix, from userid 109)\n id 5E51A827CA; Fri, 11 Dec 2020 17:08:56 +0100 (CET)", "from mx2.mailbox.org (mx2a.mailbox.org\n [IPv6:2001:67c:2050:104:0:2:25:2])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 905988276F\n for <u-boot@lists.denx.de>; Fri, 11 Dec 2020 17:06:31 +0100 (CET)", "from smtp1.mailbox.org (smtp1.mailbox.org\n [IPv6:2001:67c:2050:105:465:1:1:0])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest\n SHA256) (No client certificate requested)\n by mx2.mailbox.org (Postfix) with ESMTPS id 0DD39A0E6B;\n Fri, 11 Dec 2020 17:06:31 +0100 (CET)", "from smtp1.mailbox.org ([80.241.60.240])\n by spamfilter05.heinlein-hosting.de (spamfilter05.heinlein-hosting.de\n [80.241.56.123]) (amavisd-new, port 10030)\n with ESMTP id 275EGxvyVjgo; Fri, 11 Dec 2020 17:06:25 +0100 (CET)" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de;\n\ts=phobos-20191101; t=1607702982;\n\tbh=v4erdX2mx59L6jg34ZYKvxHgQtpcHGcWmWVZ9YKbrCY=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id:\n\t List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe:\n\t From;\n\tb=vZ3axeyaub/WJ2t/B1ZEqRMuTOyHuAnu7ZV/UW/nr8r5PROCqocDZoGfxRYkLfVqE\n\t PVjPtSah8xiZF2vjqKl/4eUhyR8zaakBTt6oP+H4Q3rPx8CEE5y36u3T3f6tPk6TCM\n\t KlN63WoZ46+IHFkassORf8L6PbgGmoMR2MS+qqOv8ghYwlag1iiiUQG93aFbV+tWCx\n\t vwV4rB5uv4TQQziUlcHp2ysU5R1/Gdpe08pM/Qss9ORNfRPmCQcVPzf+i42HD/jNkg\n\t xN1Tv3njXYtOKH4v3WRm1khD59jJYLitAWvNmZEPXzd+rxjSz08hpxqivrW0FS/z5H\n\t 1BA9kW6kd7WEw==", "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,\n SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2", "From": "Stefan Roese <sr@denx.de>", "To": "u-boot@lists.denx.de", "Cc": "daniel.schwierzeck@gmail.com, awilliams@marvell.com, cchavva@marvell.com", "Subject": "[PATCH v1 40/50] mips: octeon: Add cvmx-helper.c", "Date": "Fri, 11 Dec 2020 17:06:02 +0100", "Message-Id": "<20201211160612.1498780-41-sr@denx.de>", "In-Reply-To": "<20201211160612.1498780-1-sr@denx.de>", "References": "<20201211160612.1498780-1-sr@denx.de>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-MBO-SPAM-Probability": "", "X-Rspamd-Score": "-0.76 / 15.00 / 15.00", "X-Rspamd-Queue-Id": "EDE931879", "X-Rspamd-UID": "491ce6", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.34", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.102.3 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "From: Aaron Williams <awilliams@marvell.com>\n\nImport cvmx-helper.c from 2013 U-Boot. It will be used by the later\nadded drivers to support PCIe and networking on the MIPS Octeon II / III\nplatforms.\n\nSigned-off-by: Aaron Williams <awilliams@marvell.com>\nSigned-off-by: Stefan Roese <sr@denx.de>\n---\n\n arch/mips/mach-octeon/cvmx-helper.c | 2611 +++++++++++++++++++++++++++\n 1 file changed, 2611 insertions(+)\n create mode 100644 arch/mips/mach-octeon/cvmx-helper.c", "diff": "diff --git a/arch/mips/mach-octeon/cvmx-helper.c b/arch/mips/mach-octeon/cvmx-helper.c\nnew file mode 100644\nindex 0000000000..529e03a147\n--- /dev/null\n+++ b/arch/mips/mach-octeon/cvmx-helper.c\n@@ -0,0 +1,2611 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (C) 2020 Marvell International Ltd.\n+ *\n+ * Helper functions for common, but complicated tasks.\n+ */\n+\n+#include <log.h>\n+#include <linux/delay.h>\n+\n+#include <mach/cvmx-regs.h>\n+#include <mach/cvmx-csr.h>\n+#include <mach/cvmx-bootmem.h>\n+#include <mach/octeon-model.h>\n+#include <mach/cvmx-fuse.h>\n+#include <mach/octeon-feature.h>\n+#include <mach/cvmx-qlm.h>\n+#include <mach/octeon_qlm.h>\n+#include <mach/cvmx-pcie.h>\n+#include <mach/cvmx-coremask.h>\n+\n+#include <mach/cvmx-agl-defs.h>\n+#include <mach/cvmx-asxx-defs.h>\n+#include <mach/cvmx-bgxx-defs.h>\n+#include <mach/cvmx-dbg-defs.h>\n+#include <mach/cvmx-gmxx-defs.h>\n+#include <mach/cvmx-gserx-defs.h>\n+#include <mach/cvmx-ipd-defs.h>\n+#include <mach/cvmx-l2c-defs.h>\n+#include <mach/cvmx-npi-defs.h>\n+#include <mach/cvmx-pcsx-defs.h>\n+#include <mach/cvmx-pexp-defs.h>\n+#include <mach/cvmx-pki-defs.h>\n+#include <mach/cvmx-pko-defs.h>\n+#include <mach/cvmx-smix-defs.h>\n+#include <mach/cvmx-sriox-defs.h>\n+#include <mach/cvmx-helper.h>\n+#include <mach/cvmx-helper-board.h>\n+#include <mach/cvmx-helper-fdt.h>\n+#include <mach/cvmx-helper-bgx.h>\n+#include <mach/cvmx-helper-cfg.h>\n+#include <mach/cvmx-helper-ipd.h>\n+#include <mach/cvmx-helper-util.h>\n+#include <mach/cvmx-helper-pki.h>\n+#include <mach/cvmx-helper-pko.h>\n+#include <mach/cvmx-helper-pko3.h>\n+#include <mach/cvmx-global-resources.h>\n+#include <mach/cvmx-pko-internal-ports-range.h>\n+#include <mach/cvmx-pko3-queue.h>\n+#include <mach/cvmx-gmx.h>\n+#include <mach/cvmx-hwpko.h>\n+#include <mach/cvmx-ilk.h>\n+#include <mach/cvmx-ipd.h>\n+#include <mach/cvmx-pip.h>\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by an interface.\n+ *\n+ * @param mode\t\tInterface mode.\n+ *\n+ * @param enumerate\tMethod the get number of interface ports.\n+ *\n+ * @param probe\t\tMethod to probe an interface to get the number of\n+ *\t\t\tconnected ports.\n+ *\n+ * @param enable\tMethod to enable an interface\n+ *\n+ * @param link_get\tMethod to get the state of an interface link.\n+ *\n+ * @param link_set\tMethod to configure an interface link to the specified\n+ *\t\t\tstate.\n+ *\n+ * @param loopback\tMethod to configure a port in loopback.\n+ */\n+struct iface_ops {\n+\tcvmx_helper_interface_mode_t mode;\n+\tint (*enumerate)(int xiface);\n+\tint (*probe)(int xiface);\n+\tint (*enable)(int xiface);\n+\tcvmx_helper_link_info_t (*link_get)(int ipd_port);\n+\tint (*link_set)(int ipd_port, cvmx_helper_link_info_t link_info);\n+\tint (*loopback)(int ipd_port, int en_in, int en_ex);\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure is used by disabled interfaces.\n+ */\n+static const struct iface_ops iface_ops_dis = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_DISABLED,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as gmii.\n+ */\n+static const struct iface_ops iface_ops_gmii = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_GMII,\n+\t.enumerate = __cvmx_helper_rgmii_probe,\n+\t.probe = __cvmx_helper_rgmii_probe,\n+\t.enable = __cvmx_helper_rgmii_enable,\n+\t.link_get = __cvmx_helper_gmii_link_get,\n+\t.link_set = __cvmx_helper_rgmii_link_set,\n+\t.loopback = __cvmx_helper_rgmii_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as rgmii.\n+ */\n+static const struct iface_ops iface_ops_rgmii = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_RGMII,\n+\t.enumerate = __cvmx_helper_rgmii_probe,\n+\t.probe = __cvmx_helper_rgmii_probe,\n+\t.enable = __cvmx_helper_rgmii_enable,\n+\t.link_get = __cvmx_helper_rgmii_link_get,\n+\t.link_set = __cvmx_helper_rgmii_link_set,\n+\t.loopback = __cvmx_helper_rgmii_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as sgmii that use the gmx mac.\n+ */\n+static const struct iface_ops iface_ops_sgmii = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_SGMII,\n+\t.enumerate = __cvmx_helper_sgmii_enumerate,\n+\t.probe = __cvmx_helper_sgmii_probe,\n+\t.enable = __cvmx_helper_sgmii_enable,\n+\t.link_get = __cvmx_helper_sgmii_link_get,\n+\t.link_set = __cvmx_helper_sgmii_link_set,\n+\t.loopback = __cvmx_helper_sgmii_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as sgmii that use the bgx mac.\n+ */\n+static const struct iface_ops iface_ops_bgx_sgmii = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_SGMII,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_sgmii_enable,\n+\t.link_get = __cvmx_helper_bgx_sgmii_link_get,\n+\t.link_set = __cvmx_helper_bgx_sgmii_link_set,\n+\t.loopback = __cvmx_helper_bgx_sgmii_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as qsgmii.\n+ */\n+static const struct iface_ops iface_ops_qsgmii = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_QSGMII,\n+\t.enumerate = __cvmx_helper_sgmii_enumerate,\n+\t.probe = __cvmx_helper_sgmii_probe,\n+\t.enable = __cvmx_helper_sgmii_enable,\n+\t.link_get = __cvmx_helper_sgmii_link_get,\n+\t.link_set = __cvmx_helper_sgmii_link_set,\n+\t.loopback = __cvmx_helper_sgmii_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as xaui using the gmx mac.\n+ */\n+static const struct iface_ops iface_ops_xaui = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_XAUI,\n+\t.enumerate = __cvmx_helper_xaui_enumerate,\n+\t.probe = __cvmx_helper_xaui_probe,\n+\t.enable = __cvmx_helper_xaui_enable,\n+\t.link_get = __cvmx_helper_xaui_link_get,\n+\t.link_set = __cvmx_helper_xaui_link_set,\n+\t.loopback = __cvmx_helper_xaui_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as xaui using the gmx mac.\n+ */\n+static const struct iface_ops iface_ops_bgx_xaui = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_XAUI,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_xaui_enable,\n+\t.link_get = __cvmx_helper_bgx_xaui_link_get,\n+\t.link_set = __cvmx_helper_bgx_xaui_link_set,\n+\t.loopback = __cvmx_helper_bgx_xaui_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as rxaui.\n+ */\n+static const struct iface_ops iface_ops_rxaui = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_RXAUI,\n+\t.enumerate = __cvmx_helper_xaui_enumerate,\n+\t.probe = __cvmx_helper_xaui_probe,\n+\t.enable = __cvmx_helper_xaui_enable,\n+\t.link_get = __cvmx_helper_xaui_link_get,\n+\t.link_set = __cvmx_helper_xaui_link_set,\n+\t.loopback = __cvmx_helper_xaui_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as xaui using the gmx mac.\n+ */\n+static const struct iface_ops iface_ops_bgx_rxaui = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_RXAUI,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_xaui_enable,\n+\t.link_get = __cvmx_helper_bgx_xaui_link_get,\n+\t.link_set = __cvmx_helper_bgx_xaui_link_set,\n+\t.loopback = __cvmx_helper_bgx_xaui_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as xlaui.\n+ */\n+static const struct iface_ops iface_ops_bgx_xlaui = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_XLAUI,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_xaui_enable,\n+\t.link_get = __cvmx_helper_bgx_xaui_link_get,\n+\t.link_set = __cvmx_helper_bgx_xaui_link_set,\n+\t.loopback = __cvmx_helper_bgx_xaui_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as xfi.\n+ */\n+static const struct iface_ops iface_ops_bgx_xfi = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_XFI,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_xaui_enable,\n+\t.link_get = __cvmx_helper_bgx_xaui_link_get,\n+\t.link_set = __cvmx_helper_bgx_xaui_link_set,\n+\t.loopback = __cvmx_helper_bgx_xaui_configure_loopback,\n+};\n+\n+static const struct iface_ops iface_ops_bgx_10G_KR = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_10G_KR,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_xaui_enable,\n+\t.link_get = __cvmx_helper_bgx_xaui_link_get,\n+\t.link_set = __cvmx_helper_bgx_xaui_link_set,\n+\t.loopback = __cvmx_helper_bgx_xaui_configure_loopback,\n+};\n+\n+static const struct iface_ops iface_ops_bgx_40G_KR4 = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_40G_KR4,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_xaui_enable,\n+\t.link_get = __cvmx_helper_bgx_xaui_link_get,\n+\t.link_set = __cvmx_helper_bgx_xaui_link_set,\n+\t.loopback = __cvmx_helper_bgx_xaui_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as ilk.\n+ */\n+static const struct iface_ops iface_ops_ilk = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_ILK,\n+\t.enumerate = __cvmx_helper_ilk_enumerate,\n+\t.probe = __cvmx_helper_ilk_probe,\n+\t.enable = __cvmx_helper_ilk_enable,\n+\t.link_get = __cvmx_helper_ilk_link_get,\n+\t.link_set = __cvmx_helper_ilk_link_set,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as npi.\n+ */\n+static const struct iface_ops iface_ops_npi = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_NPI,\n+\t.enumerate = __cvmx_helper_npi_probe,\n+\t.probe = __cvmx_helper_npi_probe,\n+\t.enable = __cvmx_helper_npi_enable,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as srio.\n+ */\n+static const struct iface_ops iface_ops_srio = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_SRIO,\n+\t.enumerate = __cvmx_helper_srio_probe,\n+\t.probe = __cvmx_helper_srio_probe,\n+\t.enable = __cvmx_helper_srio_enable,\n+\t.link_get = __cvmx_helper_srio_link_get,\n+\t.link_set = __cvmx_helper_srio_link_set,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as agl.\n+ */\n+static const struct iface_ops iface_ops_agl = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_AGL,\n+\t.enumerate = __cvmx_helper_agl_enumerate,\n+\t.probe = __cvmx_helper_agl_probe,\n+\t.enable = __cvmx_helper_agl_enable,\n+\t.link_get = __cvmx_helper_agl_link_get,\n+\t.link_set = __cvmx_helper_agl_link_set,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as mixed mode, some ports are sgmii and some are xfi.\n+ */\n+static const struct iface_ops iface_ops_bgx_mixed = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_MIXED,\n+\t.enumerate = __cvmx_helper_bgx_enumerate,\n+\t.probe = __cvmx_helper_bgx_probe,\n+\t.enable = __cvmx_helper_bgx_mixed_enable,\n+\t.link_get = __cvmx_helper_bgx_mixed_link_get,\n+\t.link_set = __cvmx_helper_bgx_mixed_link_set,\n+\t.loopback = __cvmx_helper_bgx_mixed_configure_loopback,\n+};\n+\n+/**\n+ * @INTERNAL\n+ * This structure specifies the interface methods used by interfaces\n+ * configured as loop.\n+ */\n+static const struct iface_ops iface_ops_loop = {\n+\t.mode = CVMX_HELPER_INTERFACE_MODE_LOOP,\n+\t.enumerate = __cvmx_helper_loop_enumerate,\n+\t.probe = __cvmx_helper_loop_probe,\n+};\n+\n+const struct iface_ops *iface_node_ops[CVMX_MAX_NODES][CVMX_HELPER_MAX_IFACE];\n+#define iface_ops iface_node_ops[0]\n+\n+struct cvmx_iface {\n+\tint cvif_ipd_nports;\n+\tint cvif_has_fcs; /* PKO fcs for this interface. */\n+\tenum cvmx_pko_padding cvif_padding;\n+\tcvmx_helper_link_info_t *cvif_ipd_port_link_info;\n+};\n+\n+/*\n+ * This has to be static as u-boot expects to probe an interface and\n+ * gets the number of its ports.\n+ */\n+static struct cvmx_iface cvmx_interfaces[CVMX_MAX_NODES][CVMX_HELPER_MAX_IFACE];\n+\n+int __cvmx_helper_get_num_ipd_ports(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tstruct cvmx_iface *piface;\n+\n+\tif (xi.interface >= cvmx_helper_get_number_of_interfaces())\n+\t\treturn -1;\n+\n+\tpiface = &cvmx_interfaces[xi.node][xi.interface];\n+\treturn piface->cvif_ipd_nports;\n+}\n+\n+enum cvmx_pko_padding __cvmx_helper_get_pko_padding(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tstruct cvmx_iface *piface;\n+\n+\tif (xi.interface >= cvmx_helper_get_number_of_interfaces())\n+\t\treturn CVMX_PKO_PADDING_NONE;\n+\n+\tpiface = &cvmx_interfaces[xi.node][xi.interface];\n+\treturn piface->cvif_padding;\n+}\n+\n+int __cvmx_helper_init_interface(int xiface, int num_ipd_ports, int has_fcs,\n+\t\t\t\t enum cvmx_pko_padding pad)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tstruct cvmx_iface *piface;\n+\tcvmx_helper_link_info_t *p;\n+\tint i;\n+\tint sz;\n+\tu64 addr;\n+\tchar name[32];\n+\n+\tif (xi.interface >= cvmx_helper_get_number_of_interfaces())\n+\t\treturn -1;\n+\n+\tpiface = &cvmx_interfaces[xi.node][xi.interface];\n+\tpiface->cvif_ipd_nports = num_ipd_ports;\n+\tpiface->cvif_padding = pad;\n+\n+\tpiface->cvif_has_fcs = has_fcs;\n+\n+\t/*\n+\t * allocate the per-ipd_port link_info structure\n+\t */\n+\tsz = piface->cvif_ipd_nports * sizeof(cvmx_helper_link_info_t);\n+\tsnprintf(name, sizeof(name), \"__int_%d_link_info\", xi.interface);\n+\taddr = CAST64(cvmx_bootmem_alloc_named_range_once(sz, 0, 0,\n+\t\t\t\t\t\t\t __alignof(cvmx_helper_link_info_t),\n+\t\t\t\t\t\t\t name, NULL));\n+\tpiface->cvif_ipd_port_link_info =\n+\t\t(cvmx_helper_link_info_t *)__cvmx_phys_addr_to_ptr(addr, sz);\n+\tif (!piface->cvif_ipd_port_link_info) {\n+\t\tif (sz != 0)\n+\t\t\tdebug(\"iface %d failed to alloc link info\\n\", xi.interface);\n+\t\treturn -1;\n+\t}\n+\n+\t/* Initialize them */\n+\tp = piface->cvif_ipd_port_link_info;\n+\n+\tfor (i = 0; i < piface->cvif_ipd_nports; i++) {\n+\t\t(*p).u64 = 0;\n+\t\tp++;\n+\t}\n+\treturn 0;\n+}\n+\n+/*\n+ * Shut down the interfaces; free the resources.\n+ * @INTERNAL\n+ */\n+void __cvmx_helper_shutdown_interfaces_node(unsigned int node)\n+{\n+\tint i;\n+\tint nifaces; /* number of interfaces */\n+\tstruct cvmx_iface *piface;\n+\n+\tnifaces = cvmx_helper_get_number_of_interfaces();\n+\tfor (i = 0; i < nifaces; i++) {\n+\t\tpiface = &cvmx_interfaces[node][i];\n+\n+\t\t/*\n+\t\t * For SE apps, bootmem was meant to be allocated and never\n+\t\t * freed.\n+\t\t */\n+\t\tpiface->cvif_ipd_port_link_info = 0;\n+\t}\n+}\n+\n+void __cvmx_helper_shutdown_interfaces(void)\n+{\n+\tunsigned int node = cvmx_get_node_num();\n+\n+\t__cvmx_helper_shutdown_interfaces_node(node);\n+}\n+\n+int __cvmx_helper_set_link_info(int xiface, int index, cvmx_helper_link_info_t link_info)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tstruct cvmx_iface *piface;\n+\n+\tif (xi.interface >= cvmx_helper_get_number_of_interfaces())\n+\t\treturn -1;\n+\n+\tpiface = &cvmx_interfaces[xi.node][xi.interface];\n+\n+\tif (piface->cvif_ipd_port_link_info) {\n+\t\tpiface->cvif_ipd_port_link_info[index] = link_info;\n+\t\treturn 0;\n+\t}\n+\n+\treturn -1;\n+}\n+\n+cvmx_helper_link_info_t __cvmx_helper_get_link_info(int xiface, int port)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tstruct cvmx_iface *piface;\n+\tcvmx_helper_link_info_t err;\n+\n+\terr.u64 = 0;\n+\n+\tif (xi.interface >= cvmx_helper_get_number_of_interfaces())\n+\t\treturn err;\n+\tpiface = &cvmx_interfaces[xi.node][xi.interface];\n+\n+\tif (piface->cvif_ipd_port_link_info)\n+\t\treturn piface->cvif_ipd_port_link_info[port];\n+\n+\treturn err;\n+}\n+\n+/**\n+ * Returns if FCS is enabled for the specified interface and port\n+ *\n+ * @param xiface - interface to check\n+ *\n+ * @return zero if FCS is not used, otherwise FCS is used.\n+ */\n+int __cvmx_helper_get_has_fcs(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\treturn cvmx_interfaces[xi.node][xi.interface].cvif_has_fcs;\n+}\n+\n+u64 cvmx_rgmii_backpressure_dis = 1;\n+\n+typedef int (*cvmx_export_config_t)(void);\n+cvmx_export_config_t cvmx_export_app_config;\n+\n+void cvmx_rgmii_set_back_pressure(uint64_t backpressure_dis)\n+{\n+\tcvmx_rgmii_backpressure_dis = backpressure_dis;\n+}\n+\n+/*\n+ * internal functions that are not exported in the .h file but must be\n+ * declared to make gcc happy.\n+ */\n+extern cvmx_helper_link_info_t __cvmx_helper_get_link_info(int interface, int port);\n+\n+/**\n+ * cvmx_override_iface_phy_mode(int interface, int index) is a function pointer.\n+ * It is meant to allow customization of interfaces which do not have a PHY.\n+ *\n+ * @returns 0 if MAC decides TX_CONFIG_REG or 1 if PHY decides TX_CONFIG_REG.\n+ *\n+ * If this function pointer is NULL then it defaults to the MAC.\n+ */\n+int (*cvmx_override_iface_phy_mode)(int interface, int index);\n+\n+/**\n+ * cvmx_override_ipd_port_setup(int ipd_port) is a function\n+ * pointer. It is meant to allow customization of the IPD\n+ * port/port kind setup before packet input/output comes online.\n+ * It is called after cvmx-helper does the default IPD configuration,\n+ * but before IPD is enabled. Users should set this pointer to a\n+ * function before calling any cvmx-helper operations.\n+ */\n+void (*cvmx_override_ipd_port_setup)(int ipd_port) = NULL;\n+\n+/**\n+ * Return the number of interfaces the chip has. Each interface\n+ * may have multiple ports. Most chips support two interfaces,\n+ * but the CNX0XX and CNX1XX are exceptions. These only support\n+ * one interface.\n+ *\n+ * @return Number of interfaces on chip\n+ */\n+int cvmx_helper_get_number_of_interfaces(void)\n+{\n+\tif (OCTEON_IS_MODEL(OCTEON_CN68XX))\n+\t\treturn 9;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN66XX))\n+\t\tif (OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0))\n+\t\t\treturn 7;\n+\t\telse\n+\t\t\treturn 8;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN63XX))\n+\t\treturn 6;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN61XX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))\n+\t\treturn 4;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN70XX))\n+\t\treturn 5;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN78XX))\n+\t\treturn 10;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CNF75XX))\n+\t\treturn 5;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN73XX))\n+\t\treturn 5;\n+\telse\n+\t\treturn 3;\n+}\n+\n+int __cvmx_helper_early_ports_on_interface(int interface)\n+{\n+\tint ports;\n+\n+\tif (octeon_has_feature(OCTEON_FEATURE_PKND))\n+\t\treturn cvmx_helper_interface_enumerate(interface);\n+\n+\tports = cvmx_helper_interface_enumerate(interface);\n+\tports = __cvmx_helper_board_interface_probe(interface, ports);\n+\n+\treturn ports;\n+}\n+\n+/**\n+ * Return the number of ports on an interface. Depending on the\n+ * chip and configuration, this can be 1-16. A value of 0\n+ * specifies that the interface doesn't exist or isn't usable.\n+ *\n+ * @param xiface xiface to get the port count for\n+ *\n+ * @return Number of ports on interface. Can be Zero.\n+ */\n+int cvmx_helper_ports_on_interface(int xiface)\n+{\n+\tif (octeon_has_feature(OCTEON_FEATURE_PKND))\n+\t\treturn cvmx_helper_interface_enumerate(xiface);\n+\telse\n+\t\treturn __cvmx_helper_get_num_ipd_ports(xiface);\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Return interface mode for CN70XX.\n+ */\n+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn70xx(int interface)\n+{\n+\t/* SGMII/RXAUI/QSGMII */\n+\tif (interface < 2) {\n+\t\tenum cvmx_qlm_mode qlm_mode =\n+\t\t\tcvmx_qlm_get_dlm_mode(0, interface);\n+\n+\t\tif (qlm_mode == CVMX_QLM_MODE_SGMII)\n+\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\telse if (qlm_mode == CVMX_QLM_MODE_QSGMII)\n+\t\t\tiface_ops[interface] = &iface_ops_qsgmii;\n+\t\telse if (qlm_mode == CVMX_QLM_MODE_RXAUI)\n+\t\t\tiface_ops[interface] = &iface_ops_rxaui;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} else if (interface == 2) { /* DPI */\n+\t\tiface_ops[interface] = &iface_ops_npi;\n+\t} else if (interface == 3) { /* LOOP */\n+\t\tiface_ops[interface] = &iface_ops_loop;\n+\t} else if (interface == 4) { /* RGMII (AGL) */\n+\t\tcvmx_agl_prtx_ctl_t prtx_ctl;\n+\n+\t\tprtx_ctl.u64 = csr_rd(CVMX_AGL_PRTX_CTL(0));\n+\t\tif (prtx_ctl.s.mode == 0)\n+\t\t\tiface_ops[interface] = &iface_ops_agl;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} else {\n+\t\tiface_ops[interface] = &iface_ops_dis;\n+\t}\n+\n+\treturn iface_ops[interface]->mode;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Return interface mode for CN78XX.\n+ */\n+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn78xx(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\t/* SGMII/RXAUI/XAUI */\n+\tif (xi.interface < 6) {\n+\t\tint qlm = cvmx_qlm_lmac(xiface, 0);\n+\t\tenum cvmx_qlm_mode qlm_mode;\n+\n+\t\tif (qlm == -1) {\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_dis;\n+\t\t\treturn iface_node_ops[xi.node][xi.interface]->mode;\n+\t\t}\n+\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, qlm);\n+\n+\t\tif (qlm_mode == CVMX_QLM_MODE_SGMII)\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_sgmii;\n+\t\telse if (qlm_mode == CVMX_QLM_MODE_XAUI)\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_xaui;\n+\t\telse if (qlm_mode == CVMX_QLM_MODE_XLAUI)\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_xlaui;\n+\t\telse if (qlm_mode == CVMX_QLM_MODE_XFI)\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_xfi;\n+\t\telse if (qlm_mode == CVMX_QLM_MODE_RXAUI)\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_bgx_rxaui;\n+\t\telse\n+\t\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_dis;\n+\t} else if (xi.interface < 8) {\n+\t\tenum cvmx_qlm_mode qlm_mode;\n+\t\tint found = 0;\n+\t\tint i;\n+\t\tint intf, lane_mask;\n+\n+\t\tif (xi.interface == 6) {\n+\t\t\tintf = 6;\n+\t\t\tlane_mask = cvmx_ilk_lane_mask[xi.node][0];\n+\t\t} else {\n+\t\t\tintf = 7;\n+\t\t\tlane_mask = cvmx_ilk_lane_mask[xi.node][1];\n+\t\t}\n+\t\tswitch (lane_mask) {\n+\t\tdefault:\n+\t\tcase 0x0:\n+\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xf:\n+\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 4);\n+\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xff:\n+\t\t\tfound = 0;\n+\t\t\tfor (i = 4; i < 6; i++) {\n+\t\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);\n+\t\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\t\tfound++;\n+\t\t\t}\n+\t\t\tif (found == 2)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xfff:\n+\t\t\tfound = 0;\n+\t\t\tfor (i = 4; i < 7; i++) {\n+\t\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);\n+\t\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\t\tfound++;\n+\t\t\t}\n+\t\t\tif (found == 3)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xff00:\n+\t\t\tfound = 0;\n+\t\t\tfor (i = 6; i < 8; i++) {\n+\t\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);\n+\t\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\t\tfound++;\n+\t\t\t}\n+\t\t\tif (found == 2)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xf0:\n+\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 5);\n+\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xf00:\n+\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 6);\n+\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xf000:\n+\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, 7);\n+\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\tcase 0xfff0:\n+\t\t\tfound = 0;\n+\t\t\tfor (i = 5; i < 8; i++) {\n+\t\t\t\tqlm_mode = cvmx_qlm_get_mode_cn78xx(xi.node, i);\n+\t\t\t\tif (qlm_mode == CVMX_QLM_MODE_ILK)\n+\t\t\t\t\tfound++;\n+\t\t\t}\n+\t\t\tif (found == 3)\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_ilk;\n+\t\t\telse\n+\t\t\t\tiface_node_ops[xi.node][intf] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\t}\n+\t} else if (xi.interface == 8) { /* DPI */\n+\t\tint qlm = 0;\n+\n+\t\tfor (qlm = 0; qlm < 5; qlm++) {\n+\t\t\t/* if GSERX_CFG[pcie] == 1, then enable npi */\n+\t\t\tif (csr_rd_node(xi.node, CVMX_GSERX_CFG(qlm)) & 0x1) {\n+\t\t\t\tiface_node_ops[xi.node][xi.interface] =\n+\t\t\t\t\t&iface_ops_npi;\n+\t\t\t\treturn iface_node_ops[xi.node][xi.interface]->mode;\n+\t\t\t}\n+\t\t}\n+\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_dis;\n+\t} else if (xi.interface == 9) { /* LOOP */\n+\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_loop;\n+\t} else {\n+\t\tiface_node_ops[xi.node][xi.interface] = &iface_ops_dis;\n+\t}\n+\n+\treturn iface_node_ops[xi.node][xi.interface]->mode;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Return interface mode for CN73XX.\n+ */\n+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn73xx(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tint interface = xi.interface;\n+\n+\t/* SGMII/XAUI/XLAUI/XFI */\n+\tif (interface < 3) {\n+\t\tint qlm = cvmx_qlm_lmac(xiface, 0);\n+\t\tenum cvmx_qlm_mode qlm_mode;\n+\n+\t\tif (qlm == -1) {\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\treturn iface_ops[interface]->mode;\n+\t\t}\n+\t\tqlm_mode = cvmx_qlm_get_mode(qlm);\n+\n+\t\tswitch (qlm_mode) {\n+\t\tcase CVMX_QLM_MODE_SGMII:\n+\t\tcase CVMX_QLM_MODE_SGMII_2X1:\n+\t\tcase CVMX_QLM_MODE_RGMII_SGMII:\n+\t\tcase CVMX_QLM_MODE_RGMII_SGMII_1X1:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_sgmii;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XAUI:\n+\t\tcase CVMX_QLM_MODE_RGMII_XAUI:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_xaui;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_RXAUI:\n+\t\tcase CVMX_QLM_MODE_RXAUI_1X2:\n+\t\tcase CVMX_QLM_MODE_RGMII_RXAUI:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_rxaui;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XLAUI:\n+\t\tcase CVMX_QLM_MODE_RGMII_XLAUI:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_xlaui;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XFI:\n+\t\tcase CVMX_QLM_MODE_XFI_1X2:\n+\t\tcase CVMX_QLM_MODE_RGMII_XFI:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_xfi;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_10G_KR:\n+\t\tcase CVMX_QLM_MODE_10G_KR_1X2:\n+\t\tcase CVMX_QLM_MODE_RGMII_10G_KR:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_10G_KR;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_40G_KR4:\n+\t\tcase CVMX_QLM_MODE_RGMII_40G_KR4:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_40G_KR4;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_MIXED:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_mixed;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\t}\n+\t} else if (interface == 3) { /* DPI */\n+\t\tiface_ops[interface] = &iface_ops_npi;\n+\t} else if (interface == 4) { /* LOOP */\n+\t\tiface_ops[interface] = &iface_ops_loop;\n+\t} else {\n+\t\tiface_ops[interface] = &iface_ops_dis;\n+\t}\n+\n+\treturn iface_ops[interface]->mode;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Return interface mode for CNF75XX.\n+ *\n+ * CNF75XX has a single BGX block, which is attached to two DLMs,\n+ * the first, GSER4 only supports SGMII mode, while the second,\n+ * GSER5 supports 1G/10G single late modes, i.e. SGMII, XFI, 10G-KR.\n+ * Each half-BGX is thus designated as a separate interface with two ports each.\n+ */\n+static cvmx_helper_interface_mode_t __cvmx_get_mode_cnf75xx(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tint interface = xi.interface;\n+\n+\t/* BGX0: SGMII (DLM4/DLM5)/XFI(DLM5) */\n+\tif (interface < 1) {\n+\t\tenum cvmx_qlm_mode qlm_mode;\n+\t\tint qlm = cvmx_qlm_lmac(xiface, 0);\n+\n+\t\tif (qlm == -1) {\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\treturn iface_ops[interface]->mode;\n+\t\t}\n+\t\tqlm_mode = cvmx_qlm_get_mode(qlm);\n+\n+\t\tswitch (qlm_mode) {\n+\t\tcase CVMX_QLM_MODE_SGMII:\n+\t\tcase CVMX_QLM_MODE_SGMII_2X1:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_sgmii;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_XFI_1X2:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_xfi;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_10G_KR_1X2:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_10G_KR;\n+\t\t\tbreak;\n+\t\tcase CVMX_QLM_MODE_MIXED:\n+\t\t\tiface_ops[interface] = &iface_ops_bgx_mixed;\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\tbreak;\n+\t\t}\n+\t} else if ((interface < 3) && OCTEON_IS_MODEL(OCTEON_CNF75XX)) {\n+\t\tcvmx_sriox_status_reg_t sriox_status_reg;\n+\t\tint srio_port = interface - 1;\n+\n+\t\tsriox_status_reg.u64 = csr_rd(CVMX_SRIOX_STATUS_REG(srio_port));\n+\n+\t\tif (sriox_status_reg.s.srio)\n+\t\t\tiface_ops[interface] = &iface_ops_srio;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} else if (interface == 3) { /* DPI */\n+\t\tiface_ops[interface] = &iface_ops_npi;\n+\t} else if (interface == 4) { /* LOOP */\n+\t\tiface_ops[interface] = &iface_ops_loop;\n+\t} else {\n+\t\tiface_ops[interface] = &iface_ops_dis;\n+\t}\n+\n+\treturn iface_ops[interface]->mode;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Return interface mode for CN68xx.\n+ */\n+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)\n+{\n+\tunion cvmx_mio_qlmx_cfg qlm_cfg;\n+\n+\tswitch (interface) {\n+\tcase 0:\n+\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));\n+\t\t/* QLM is disabled when QLM SPD is 15. */\n+\t\tif (qlm_cfg.s.qlm_spd == 15)\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 7)\n+\t\t\tiface_ops[interface] = &iface_ops_rxaui;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 2)\n+\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 3)\n+\t\t\tiface_ops[interface] = &iface_ops_xaui;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\tbreak;\n+\n+\tcase 1:\n+\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));\n+\t\t/* QLM is disabled when QLM SPD is 15. */\n+\t\tif (qlm_cfg.s.qlm_spd == 15)\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 7)\n+\t\t\tiface_ops[interface] = &iface_ops_rxaui;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\tbreak;\n+\n+\tcase 2:\n+\tcase 3:\n+\tcase 4:\n+\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(interface));\n+\t\t/* QLM is disabled when QLM SPD is 15. */\n+\t\tif (qlm_cfg.s.qlm_spd == 15)\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 2)\n+\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 3)\n+\t\t\tiface_ops[interface] = &iface_ops_xaui;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\tbreak;\n+\n+\tcase 5:\n+\tcase 6:\n+\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(interface - 4));\n+\t\t/* QLM is disabled when QLM SPD is 15. */\n+\t\tif (qlm_cfg.s.qlm_spd == 15)\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 1)\n+\t\t\tiface_ops[interface] = &iface_ops_ilk;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\tbreak;\n+\n+\tcase 7: {\n+\t\tunion cvmx_mio_qlmx_cfg qlm_cfg1;\n+\t\t/* Check if PCIe0/PCIe1 is configured for PCIe */\n+\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(3));\n+\t\tqlm_cfg1.u64 = csr_rd(CVMX_MIO_QLMX_CFG(1));\n+\t\t/* QLM is disabled when QLM SPD is 15. */\n+\t\tif ((qlm_cfg.s.qlm_spd != 15 && qlm_cfg.s.qlm_cfg == 0) ||\n+\t\t (qlm_cfg1.s.qlm_spd != 15 && qlm_cfg1.s.qlm_cfg == 0))\n+\t\t\tiface_ops[interface] = &iface_ops_npi;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} break;\n+\n+\tcase 8:\n+\t\tiface_ops[interface] = &iface_ops_loop;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\tbreak;\n+\t}\n+\n+\treturn iface_ops[interface]->mode;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Return interface mode for an Octeon II\n+ */\n+static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)\n+{\n+\tunion cvmx_gmxx_inf_mode mode;\n+\n+\tif (OCTEON_IS_MODEL(OCTEON_CN68XX))\n+\t\treturn __cvmx_get_mode_cn68xx(interface);\n+\n+\tif (interface == 2) {\n+\t\tiface_ops[interface] = &iface_ops_npi;\n+\t} else if (interface == 3) {\n+\t\tiface_ops[interface] = &iface_ops_loop;\n+\t} else if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&\n+\t\t (interface == 4 || interface == 5)) ||\n+\t\t (OCTEON_IS_MODEL(OCTEON_CN66XX) && interface >= 4 &&\n+\t\t interface <= 7)) {\n+\t\t/* Only present in CN63XX & CN66XX Octeon model */\n+\t\tunion cvmx_sriox_status_reg sriox_status_reg;\n+\n+\t\t/* cn66xx pass1.0 has only 2 SRIO interfaces. */\n+\t\tif ((interface == 5 || interface == 7) &&\n+\t\t OCTEON_IS_MODEL(OCTEON_CN66XX_PASS1_0)) {\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t} else if (interface == 5 && OCTEON_IS_MODEL(OCTEON_CN66XX)) {\n+\t\t\t/*\n+\t\t\t * Later passes of cn66xx support SRIO0 - x4/x2/x1,\n+\t\t\t * SRIO2 - x2/x1, SRIO3 - x1\n+\t\t\t */\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t} else {\n+\t\t\tsriox_status_reg.u64 =\n+\t\t\t\tcsr_rd(CVMX_SRIOX_STATUS_REG(interface - 4));\n+\t\t\tif (sriox_status_reg.s.srio)\n+\t\t\t\tiface_ops[interface] = &iface_ops_srio;\n+\t\t\telse\n+\t\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t}\n+\t} else if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {\n+\t\tunion cvmx_mio_qlmx_cfg mio_qlm_cfg;\n+\n+\t\t/* QLM2 is SGMII0 and QLM1 is SGMII1 */\n+\t\tif (interface == 0) {\n+\t\t\tmio_qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(2));\n+\t\t} else if (interface == 1) {\n+\t\t\tmio_qlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(1));\n+\t\t} else {\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\treturn iface_ops[interface]->mode;\n+\t\t}\n+\n+\t\tif (mio_qlm_cfg.s.qlm_spd == 15)\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\telse if (mio_qlm_cfg.s.qlm_cfg == 9)\n+\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\telse if (mio_qlm_cfg.s.qlm_cfg == 11)\n+\t\t\tiface_ops[interface] = &iface_ops_xaui;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {\n+\t\tunion cvmx_mio_qlmx_cfg qlm_cfg;\n+\n+\t\tif (interface == 0) {\n+\t\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(2));\n+\t\t} else if (interface == 1) {\n+\t\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));\n+\t\t} else {\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\treturn iface_ops[interface]->mode;\n+\t\t}\n+\n+\t\tif (qlm_cfg.s.qlm_spd == 15)\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 2)\n+\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\telse if (qlm_cfg.s.qlm_cfg == 3)\n+\t\t\tiface_ops[interface] = &iface_ops_xaui;\n+\t\telse\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {\n+\t\tif (interface == 0) {\n+\t\t\tunion cvmx_mio_qlmx_cfg qlm_cfg;\n+\n+\t\t\tqlm_cfg.u64 = csr_rd(CVMX_MIO_QLMX_CFG(0));\n+\t\t\tif (qlm_cfg.s.qlm_cfg == 2)\n+\t\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\t\telse\n+\t\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t} else {\n+\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t}\n+\t} else if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX)) {\n+\t\tiface_ops[interface] = &iface_ops_dis;\n+\t} else {\n+\t\tmode.u64 = csr_rd(CVMX_GMXX_INF_MODE(interface));\n+\n+\t\tif (OCTEON_IS_MODEL(OCTEON_CN63XX)) {\n+\t\t\tswitch (mode.cn63xx.mode) {\n+\t\t\tcase 0:\n+\t\t\t\tiface_ops[interface] = &iface_ops_sgmii;\n+\t\t\t\tbreak;\n+\n+\t\t\tcase 1:\n+\t\t\t\tiface_ops[interface] = &iface_ops_xaui;\n+\t\t\t\tbreak;\n+\n+\t\t\tdefault:\n+\t\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tif (!mode.s.en)\n+\t\t\t\tiface_ops[interface] = &iface_ops_dis;\n+\t\t\telse if (mode.s.type)\n+\t\t\t\tiface_ops[interface] = &iface_ops_gmii;\n+\t\t\telse\n+\t\t\t\tiface_ops[interface] = &iface_ops_rgmii;\n+\t\t}\n+\t}\n+\n+\treturn iface_ops[interface]->mode;\n+}\n+\n+/**\n+ * Get the operating mode of an interface. Depending on the Octeon\n+ * chip and configuration, this function returns an enumeration\n+ * of the type of packet I/O supported by an interface.\n+ *\n+ * @param xiface Interface to probe\n+ *\n+ * @return Mode of the interface. Unknown or unsupported interfaces return\n+ * DISABLED.\n+ */\n+cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\n+\tif (xi.interface < 0 ||\n+\t xi.interface >= cvmx_helper_get_number_of_interfaces())\n+\t\treturn CVMX_HELPER_INTERFACE_MODE_DISABLED;\n+\n+\t/*\n+\t * Check if the interface mode has been already cached. If it has,\n+\t * simply return it. Otherwise, fall through the rest of the code to\n+\t * determine the interface mode and cache it in iface_ops.\n+\t */\n+\tif (iface_node_ops[xi.node][xi.interface]) {\n+\t\tcvmx_helper_interface_mode_t mode;\n+\n+\t\tmode = iface_node_ops[xi.node][xi.interface]->mode;\n+\t\treturn mode;\n+\t}\n+\n+\t/*\n+\t * OCTEON III models\n+\t */\n+\tif (OCTEON_IS_MODEL(OCTEON_CN70XX))\n+\t\treturn __cvmx_get_mode_cn70xx(xi.interface);\n+\n+\tif (OCTEON_IS_MODEL(OCTEON_CN78XX))\n+\t\treturn __cvmx_get_mode_cn78xx(xiface);\n+\n+\tif (OCTEON_IS_MODEL(OCTEON_CNF75XX)) {\n+\t\tcvmx_helper_interface_mode_t mode;\n+\n+\t\tmode = __cvmx_get_mode_cnf75xx(xiface);\n+\t\treturn mode;\n+\t}\n+\n+\tif (OCTEON_IS_MODEL(OCTEON_CN73XX)) {\n+\t\tcvmx_helper_interface_mode_t mode;\n+\n+\t\tmode = __cvmx_get_mode_cn73xx(xiface);\n+\t\treturn mode;\n+\t}\n+\n+\t/*\n+\t * Octeon II models\n+\t */\n+\tif (OCTEON_IS_OCTEON2())\n+\t\treturn __cvmx_get_mode_octeon2(xi.interface);\n+\n+\t/*\n+\t * Octeon and Octeon Plus models\n+\t */\n+\tif (xi.interface == 2) {\n+\t\tiface_ops[xi.interface] = &iface_ops_npi;\n+\t} else if (xi.interface == 3) {\n+\t\tiface_ops[xi.interface] = &iface_ops_dis;\n+\t} else {\n+\t\tunion cvmx_gmxx_inf_mode mode;\n+\n+\t\tmode.u64 = csr_rd(CVMX_GMXX_INF_MODE(xi.interface));\n+\n+\t\tif (!mode.s.en)\n+\t\t\tiface_ops[xi.interface] = &iface_ops_dis;\n+\t\telse if (mode.s.type)\n+\t\t\tiface_ops[xi.interface] = &iface_ops_gmii;\n+\t\telse\n+\t\t\tiface_ops[xi.interface] = &iface_ops_rgmii;\n+\t}\n+\n+\treturn iface_ops[xi.interface]->mode;\n+}\n+\n+/**\n+ * Determine the actual number of hardware ports connected to an\n+ * interface. It doesn't setup the ports or enable them.\n+ *\n+ * @param xiface Interface to enumerate\n+ *\n+ * @return The number of ports on the interface, negative on failure\n+ */\n+int cvmx_helper_interface_enumerate(int xiface)\n+{\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tint result = 0;\n+\n+\tcvmx_helper_interface_get_mode(xiface);\n+\tif (iface_node_ops[xi.node][xi.interface]->enumerate)\n+\t\tresult = iface_node_ops[xi.node][xi.interface]->enumerate(xiface);\n+\n+\treturn result;\n+}\n+\n+/**\n+ * This function probes an interface to determine the actual number of\n+ * hardware ports connected to it. It does some setup the ports but\n+ * doesn't enable them. The main goal here is to set the global\n+ * interface_port_count[interface] correctly. Final hardware setup of\n+ * the ports will be performed later.\n+ *\n+ * @param xiface Interface to probe\n+ *\n+ * @return Zero on success, negative on failure\n+ */\n+int cvmx_helper_interface_probe(int xiface)\n+{\n+\t/*\n+\t * At this stage in the game we don't want packets to be\n+\t * moving yet. The following probe calls should perform\n+\t * hardware setup needed to determine port counts. Receive\n+\t * must still be disabled.\n+\t */\n+\tint nports;\n+\tint has_fcs;\n+\tenum cvmx_pko_padding padding = CVMX_PKO_PADDING_NONE;\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\n+\tnports = -1;\n+\thas_fcs = 0;\n+\n+\tcvmx_helper_interface_get_mode(xiface);\n+\tif (iface_node_ops[xi.node][xi.interface]->probe)\n+\t\tnports = iface_node_ops[xi.node][xi.interface]->probe(xiface);\n+\n+\tswitch (iface_node_ops[xi.node][xi.interface]->mode) {\n+\t\t/* These types don't support ports to IPD/PKO */\n+\tcase CVMX_HELPER_INTERFACE_MODE_DISABLED:\n+\tcase CVMX_HELPER_INTERFACE_MODE_PCIE:\n+\t\tnports = 0;\n+\t\tbreak;\n+\t\t/* XAUI is a single high speed port */\n+\tcase CVMX_HELPER_INTERFACE_MODE_XAUI:\n+\tcase CVMX_HELPER_INTERFACE_MODE_RXAUI:\n+\tcase CVMX_HELPER_INTERFACE_MODE_XLAUI:\n+\tcase CVMX_HELPER_INTERFACE_MODE_XFI:\n+\tcase CVMX_HELPER_INTERFACE_MODE_10G_KR:\n+\tcase CVMX_HELPER_INTERFACE_MODE_40G_KR4:\n+\tcase CVMX_HELPER_INTERFACE_MODE_MIXED:\n+\t\thas_fcs = 1;\n+\t\tpadding = CVMX_PKO_PADDING_60;\n+\t\tbreak;\n+\t\t/*\n+\t\t * RGMII/GMII/MII are all treated about the same. Most\n+\t\t * functions refer to these ports as RGMII.\n+\t\t */\n+\tcase CVMX_HELPER_INTERFACE_MODE_RGMII:\n+\tcase CVMX_HELPER_INTERFACE_MODE_GMII:\n+\t\tpadding = CVMX_PKO_PADDING_60;\n+\t\tbreak;\n+\t\t/*\n+\t\t * SPI4 can have 1-16 ports depending on the device at\n+\t\t * the other end.\n+\t\t */\n+\tcase CVMX_HELPER_INTERFACE_MODE_SPI:\n+\t\tpadding = CVMX_PKO_PADDING_60;\n+\t\tbreak;\n+\t\t/*\n+\t\t * SGMII can have 1-4 ports depending on how many are\n+\t\t * hooked up.\n+\t\t */\n+\tcase CVMX_HELPER_INTERFACE_MODE_SGMII:\n+\tcase CVMX_HELPER_INTERFACE_MODE_QSGMII:\n+\t\tpadding = CVMX_PKO_PADDING_60;\n+\tcase CVMX_HELPER_INTERFACE_MODE_PICMG:\n+\t\thas_fcs = 1;\n+\t\tbreak;\n+\t\t/* PCI target Network Packet Interface */\n+\tcase CVMX_HELPER_INTERFACE_MODE_NPI:\n+\t\tbreak;\n+\t\t/*\n+\t\t * Special loopback only ports. These are not the same\n+\t\t * as other ports in loopback mode.\n+\t\t */\n+\tcase CVMX_HELPER_INTERFACE_MODE_LOOP:\n+\t\tbreak;\n+\t\t/* SRIO has 2^N ports, where N is number of interfaces */\n+\tcase CVMX_HELPER_INTERFACE_MODE_SRIO:\n+\t\tbreak;\n+\tcase CVMX_HELPER_INTERFACE_MODE_ILK:\n+\t\tpadding = CVMX_PKO_PADDING_60;\n+\t\thas_fcs = 1;\n+\t\tbreak;\n+\tcase CVMX_HELPER_INTERFACE_MODE_AGL:\n+\t\thas_fcs = 1;\n+\t\tbreak;\n+\t}\n+\n+\tif (nports == -1)\n+\t\treturn -1;\n+\n+\tif (!octeon_has_feature(OCTEON_FEATURE_PKND))\n+\t\thas_fcs = 0;\n+\n+\tnports = __cvmx_helper_board_interface_probe(xiface, nports);\n+\t__cvmx_helper_init_interface(xiface, nports, has_fcs, padding);\n+\t/* Make sure all global variables propagate to other cores */\n+\tCVMX_SYNCWS;\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Setup backpressure.\n+ *\n+ * @return Zero on success, negative on failure\n+ */\n+static int __cvmx_helper_global_setup_backpressure(int node)\n+{\n+\tcvmx_qos_proto_t qos_proto;\n+\tcvmx_qos_pkt_mode_t qos_mode;\n+\tint port, xipdport;\n+\tunsigned int bpmask;\n+\tint interface, xiface, ports;\n+\tint num_interfaces = cvmx_helper_get_number_of_interfaces();\n+\n+\tif (cvmx_rgmii_backpressure_dis) {\n+\t\tqos_proto = CVMX_QOS_PROTO_NONE;\n+\t\tqos_mode = CVMX_QOS_PKT_MODE_DROP;\n+\t} else {\n+\t\tqos_proto = CVMX_QOS_PROTO_PAUSE;\n+\t\tqos_mode = CVMX_QOS_PKT_MODE_HWONLY;\n+\t}\n+\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\txiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\t\tports = cvmx_helper_ports_on_interface(xiface);\n+\n+\t\tswitch (cvmx_helper_interface_get_mode(xiface)) {\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_DISABLED:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_PCIE:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SRIO:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_ILK:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_NPI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_PICMG:\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_LOOP:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RXAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XLAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XFI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_10G_KR:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_40G_KR4:\n+\t\t\tbpmask = (cvmx_rgmii_backpressure_dis) ? 0xF : 0;\n+\t\t\tif (octeon_has_feature(OCTEON_FEATURE_BGX)) {\n+\t\t\t\tfor (port = 0; port < ports; port++) {\n+\t\t\t\t\txipdport = cvmx_helper_get_ipd_port(xiface, port);\n+\t\t\t\t\tcvmx_bgx_set_flowctl_mode(xipdport, qos_proto, qos_mode);\n+\t\t\t\t}\n+\t\t\t\tcvmx_bgx_set_backpressure_override(xiface, bpmask);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_GMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SPI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_QSGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_MIXED:\n+\t\t\tbpmask = (cvmx_rgmii_backpressure_dis) ? 0xF : 0;\n+\t\t\tif (octeon_has_feature(OCTEON_FEATURE_BGX)) {\n+\t\t\t\tfor (port = 0; port < ports; port++) {\n+\t\t\t\t\txipdport = cvmx_helper_get_ipd_port(xiface, port);\n+\t\t\t\t\tcvmx_bgx_set_flowctl_mode(xipdport, qos_proto, qos_mode);\n+\t\t\t\t}\n+\t\t\t\tcvmx_bgx_set_backpressure_override(xiface, bpmask);\n+\t\t\t} else {\n+\t\t\t\tcvmx_gmx_set_backpressure_override(interface, bpmask);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_AGL:\n+\t\t\tbpmask = (cvmx_rgmii_backpressure_dis) ? 0x1 : 0;\n+\t\t\tcvmx_agl_set_backpressure_override(interface, bpmask);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Verify the per port IPD backpressure is aligned properly.\n+ * @return Zero if working, non zero if misaligned\n+ */\n+int __cvmx_helper_backpressure_is_misaligned(void)\n+{\n+\treturn 0;\n+}\n+\n+/**\n+ * @INTERNAL\n+ * Enable packet input/output from the hardware. This function is\n+ * called after all internal setup is complete and IPD is enabled.\n+ * After this function completes, packets will be accepted from the\n+ * hardware ports. PKO should still be disabled to make sure packets\n+ * aren't sent out partially setup hardware.\n+ *\n+ * @param xiface Interface to enable\n+ *\n+ * @return Zero on success, negative on failure\n+ */\n+int __cvmx_helper_packet_hardware_enable(int xiface)\n+{\n+\tint result = 0;\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\n+\tif (iface_node_ops[xi.node][xi.interface]->enable)\n+\t\tresult = iface_node_ops[xi.node][xi.interface]->enable(xiface);\n+\tresult |= __cvmx_helper_board_hardware_enable(xiface);\n+\treturn result;\n+}\n+\n+int cvmx_helper_ipd_and_packet_input_enable(void)\n+{\n+\treturn cvmx_helper_ipd_and_packet_input_enable_node(cvmx_get_node_num());\n+}\n+\n+/**\n+ * Called after all internal packet IO paths are setup. This\n+ * function enables IPD/PIP and begins packet input and output.\n+ *\n+ * @return Zero on success, negative on failure\n+ */\n+int cvmx_helper_ipd_and_packet_input_enable_node(int node)\n+{\n+\tint num_interfaces;\n+\tint interface;\n+\tint num_ports;\n+\n+\tif (octeon_has_feature(OCTEON_FEATURE_PKI)) {\n+\t\tcvmx_helper_pki_enable(node);\n+\t} else {\n+\t\t/* Enable IPD */\n+\t\tcvmx_ipd_enable();\n+\t}\n+\n+\t/*\n+\t * Time to enable hardware ports packet input and output. Note\n+\t * that at this point IPD/PIP must be fully functional and PKO\n+\t * must be disabled .\n+\t */\n+\tnum_interfaces = cvmx_helper_get_number_of_interfaces();\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\n+\t\tnum_ports = cvmx_helper_ports_on_interface(xiface);\n+\t\tif (num_ports > 0)\n+\t\t\t__cvmx_helper_packet_hardware_enable(xiface);\n+\t}\n+\n+\t/* Finally enable PKO now that the entire path is up and running */\n+\t/* enable pko */\n+\tif (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))\n+\t\t; // cvmx_pko_enable_78xx(0); already enabled\n+\telse\n+\t\tcvmx_pko_enable();\n+\n+\treturn 0;\n+}\n+\n+/**\n+ * Initialize the PIP, IPD, and PKO hardware to support\n+ * simple priority based queues for the ethernet ports. Each\n+ * port is configured with a number of priority queues based\n+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower\n+ * priority than the previous.\n+ *\n+ * @return Zero on success, non-zero on failure\n+ */\n+int cvmx_helper_initialize_packet_io_node(unsigned int node)\n+{\n+\tint result = 0;\n+\tint interface;\n+\tint xiface;\n+\tunion cvmx_l2c_cfg l2c_cfg;\n+\tunion cvmx_smix_en smix_en;\n+\tconst int num_interfaces = cvmx_helper_get_number_of_interfaces();\n+\n+\t/*\n+\t * Tell L2 to give the IOB statically higher priority compared\n+\t * to the cores. This avoids conditions where IO blocks might\n+\t * be starved under very high L2 loads.\n+\t */\n+\tif (OCTEON_IS_OCTEON2() || OCTEON_IS_OCTEON3()) {\n+\t\tunion cvmx_l2c_ctl l2c_ctl;\n+\n+\t\tl2c_ctl.u64 = csr_rd_node(node, CVMX_L2C_CTL);\n+\t\tl2c_ctl.s.rsp_arb_mode = 1;\n+\t\tl2c_ctl.s.xmc_arb_mode = 0;\n+\t\tcsr_wr_node(node, CVMX_L2C_CTL, l2c_ctl.u64);\n+\t} else {\n+\t\tl2c_cfg.u64 = csr_rd(CVMX_L2C_CFG);\n+\t\tl2c_cfg.s.lrf_arb_mode = 0;\n+\t\tl2c_cfg.s.rfb_arb_mode = 0;\n+\t\tcsr_wr(CVMX_L2C_CFG, l2c_cfg.u64);\n+\t}\n+\n+\tint smi_inf;\n+\tint i;\n+\n+\t/* Newer chips have more than one SMI/MDIO interface */\n+\tif (OCTEON_IS_MODEL(OCTEON_CN68XX) || OCTEON_IS_MODEL(OCTEON_CN78XX))\n+\t\tsmi_inf = 4;\n+\telse if (OCTEON_IS_MODEL(OCTEON_CN73XX) || OCTEON_IS_MODEL(OCTEON_CNF75XX))\n+\t\tsmi_inf = 2;\n+\telse\n+\t\tsmi_inf = 2;\n+\n+\tfor (i = 0; i < smi_inf; i++) {\n+\t\t/* Make sure SMI/MDIO is enabled so we can query PHYs */\n+\t\tsmix_en.u64 = csr_rd_node(node, CVMX_SMIX_EN(i));\n+\t\tif (!smix_en.s.en) {\n+\t\t\tsmix_en.s.en = 1;\n+\t\t\tcsr_wr_node(node, CVMX_SMIX_EN(i), smix_en.u64);\n+\t\t}\n+\t}\n+\n+\t//vinita_to_do ask it need to be modify for multinode\n+\t__cvmx_helper_init_port_valid();\n+\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\txiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\t\tresult |= cvmx_helper_interface_probe(xiface);\n+\t}\n+\n+\t/* PKO3 init precedes that of interfaces */\n+\tif (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {\n+\t\t__cvmx_helper_init_port_config_data(node);\n+\t\tresult = cvmx_helper_pko3_init_global(node);\n+\t} else {\n+\t\tresult = cvmx_helper_pko_init();\n+\t}\n+\n+\t/* Errata SSO-29000, Disabling power saving SSO conditional clocking */\n+\tif (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE)) {\n+\t\tcvmx_sso_ws_cfg_t cfg;\n+\n+\t\tcfg.u64 = csr_rd_node(node, CVMX_SSO_WS_CFG);\n+\t\tcfg.s.sso_cclk_dis = 1;\n+\t\tcsr_wr_node(node, CVMX_SSO_WS_CFG, cfg.u64);\n+\t}\n+\n+\tif (result < 0)\n+\t\treturn result;\n+\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\txiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\t\t/* Skip invalid/disabled interfaces */\n+\t\tif (cvmx_helper_ports_on_interface(xiface) <= 0)\n+\t\t\tcontinue;\n+\t\tprintf(\"Node %d Interface %d has %d ports (%s)\\n\", node, interface,\n+\t\t cvmx_helper_ports_on_interface(xiface),\n+\t\t cvmx_helper_interface_mode_to_string(\n+\t\t\t cvmx_helper_interface_get_mode(xiface)));\n+\n+\t\tresult |= __cvmx_helper_ipd_setup_interface(xiface);\n+\t\tif (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))\n+\t\t\tresult |= cvmx_helper_pko3_init_interface(xiface);\n+\t\telse\n+\t\t\tresult |= __cvmx_helper_interface_setup_pko(interface);\n+\t}\n+\n+\tif (octeon_has_feature(OCTEON_FEATURE_PKI))\n+\t\tresult |= __cvmx_helper_pki_global_setup(node);\n+\telse\n+\t\tresult |= __cvmx_helper_ipd_global_setup();\n+\n+\t/* Enable any flow control and backpressure */\n+\tresult |= __cvmx_helper_global_setup_backpressure(node);\n+\n+\t/* export app config if set */\n+\tif (cvmx_export_app_config)\n+\t\tresult |= (*cvmx_export_app_config)();\n+\n+\tif (cvmx_ipd_cfg.ipd_enable && cvmx_pki_dflt_init[node])\n+\t\tresult |= cvmx_helper_ipd_and_packet_input_enable_node(node);\n+\treturn result;\n+}\n+\n+/**\n+ * Initialize the PIP, IPD, and PKO hardware to support\n+ * simple priority based queues for the ethernet ports. Each\n+ * port is configured with a number of priority queues based\n+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower\n+ * priority than the previous.\n+ *\n+ * @return Zero on success, non-zero on failure\n+ */\n+int cvmx_helper_initialize_packet_io_global(void)\n+{\n+\tunsigned int node = cvmx_get_node_num();\n+\n+\treturn cvmx_helper_initialize_packet_io_node(node);\n+}\n+\n+/**\n+ * Does core local initialization for packet io\n+ *\n+ * @return Zero on success, non-zero on failure\n+ */\n+int cvmx_helper_initialize_packet_io_local(void)\n+{\n+\tif (octeon_has_feature(OCTEON_FEATURE_CN78XX_WQE))\n+\t\t__cvmx_pko3_dq_table_setup();\n+\n+\treturn 0;\n+}\n+\n+struct cvmx_buffer_list {\n+\tstruct cvmx_buffer_list *next;\n+};\n+\n+/**\n+ * Disables the sending of flow control (pause) frames on the specified\n+ * GMX port(s).\n+ *\n+ * @param interface Which interface (0 or 1)\n+ * @param port_mask Mask (4bits) of which ports on the interface to disable\n+ * backpressure on.\n+ * 1 => disable backpressure\n+ * 0 => enable backpressure\n+ *\n+ * @return 0 on success\n+ * -1 on error\n+ */\n+int cvmx_gmx_set_backpressure_override(u32 interface, uint32_t port_mask)\n+{\n+\tunion cvmx_gmxx_tx_ovr_bp gmxx_tx_ovr_bp;\n+\t/* Check for valid arguments */\n+\tif (port_mask & ~0xf || interface & ~0x1)\n+\t\treturn -1;\n+\tif (interface >= CVMX_HELPER_MAX_GMX)\n+\t\treturn -1;\n+\n+\tgmxx_tx_ovr_bp.u64 = 0;\n+\tgmxx_tx_ovr_bp.s.en = port_mask; /* Per port Enable back pressure override */\n+\tgmxx_tx_ovr_bp.s.ign_full = port_mask; /* Ignore the RX FIFO full when computing BP */\n+\tcsr_wr(CVMX_GMXX_TX_OVR_BP(interface), gmxx_tx_ovr_bp.u64);\n+\treturn 0;\n+}\n+\n+/**\n+ * Disables the sending of flow control (pause) frames on the specified\n+ * AGL (RGMII) port(s).\n+ *\n+ * @param interface Which interface (0 or 1)\n+ * @param port_mask Mask (4bits) of which ports on the interface to disable\n+ * backpressure on.\n+ * 1 => disable backpressure\n+ * 0 => enable backpressure\n+ *\n+ * @return 0 on success\n+ * -1 on error\n+ */\n+int cvmx_agl_set_backpressure_override(u32 interface, uint32_t port_mask)\n+{\n+\tunion cvmx_agl_gmx_tx_ovr_bp agl_gmx_tx_ovr_bp;\n+\tint port = cvmx_helper_agl_get_port(interface);\n+\n+\tif (port == -1)\n+\t\treturn -1;\n+\t/* Check for valid arguments */\n+\tagl_gmx_tx_ovr_bp.u64 = 0;\n+\t/* Per port Enable back pressure override */\n+\tagl_gmx_tx_ovr_bp.s.en = port_mask;\n+\t/* Ignore the RX FIFO full when computing BP */\n+\tagl_gmx_tx_ovr_bp.s.ign_full = port_mask;\n+\tcsr_wr(CVMX_GMXX_TX_OVR_BP(port), agl_gmx_tx_ovr_bp.u64);\n+\treturn 0;\n+}\n+\n+/**\n+ * Helper function for global packet IO shutdown\n+ */\n+int cvmx_helper_shutdown_packet_io_global_cn78xx(int node)\n+{\n+\tint num_interfaces = cvmx_helper_get_number_of_interfaces();\n+\tcvmx_wqe_t *work;\n+\tint interface;\n+\tint result = 0;\n+\n+\t/* Shut down all interfaces and disable TX and RX on all ports */\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\t\tint index;\n+\t\tint num_ports = cvmx_helper_ports_on_interface(xiface);\n+\n+\t\tif (num_ports > 4)\n+\t\t\tnum_ports = 4;\n+\n+\t\tcvmx_bgx_set_backpressure_override(xiface, 0);\n+\t\tfor (index = 0; index < num_ports; index++) {\n+\t\t\tcvmx_helper_link_info_t link_info;\n+\n+\t\t\tif (!cvmx_helper_is_port_valid(xiface, index))\n+\t\t\t\tcontinue;\n+\n+\t\t\tcvmx_helper_bgx_shutdown_port(xiface, index);\n+\n+\t\t\t/* Turn off link LEDs */\n+\t\t\tlink_info.u64 = 0;\n+\t\t\tcvmx_helper_update_link_led(xiface, index, link_info);\n+\t\t}\n+\t}\n+\n+\t/* Stop input first */\n+\tcvmx_helper_pki_shutdown(node);\n+\n+\t/* Retrieve all packets from the SSO and free them */\n+\tresult = 0;\n+\twhile ((work = cvmx_pow_work_request_sync(CVMX_POW_WAIT))) {\n+\t\tcvmx_helper_free_pki_pkt_data(work);\n+\t\tcvmx_wqe_pki_free(work);\n+\t\tresult++;\n+\t}\n+\n+\tif (result > 0)\n+\t\tdebug(\"%s: Purged %d packets from SSO\\n\", __func__, result);\n+\n+\t/*\n+\t * No need to wait for PKO queues to drain,\n+\t * dq_close() drains the queues to NULL.\n+\t */\n+\n+\t/* Shutdown PKO interfaces */\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\n+\t\tcvmx_helper_pko3_shut_interface(xiface);\n+\t}\n+\n+\t/* Disable MAC address filtering */\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\n+\t\tswitch (cvmx_helper_interface_get_mode(xiface)) {\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RXAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XLAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XFI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_10G_KR:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_40G_KR4:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_MIXED: {\n+\t\t\tint index;\n+\t\t\tint num_ports = cvmx_helper_ports_on_interface(xiface);\n+\n+\t\t\tfor (index = 0; index < num_ports; index++) {\n+\t\t\t\tif (!cvmx_helper_is_port_valid(xiface, index))\n+\t\t\t\t\tcontinue;\n+\n+\t\t\t\t/* Reset MAC filtering */\n+\t\t\t\tcvmx_helper_bgx_rx_adr_ctl(node, interface, index, 0, 0, 0);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint index;\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\t\tint num_ports = cvmx_helper_ports_on_interface(xiface);\n+\n+\t\tfor (index = 0; index < num_ports; index++) {\n+\t\t\t/* Doing this twice should clear it since no packets\n+\t\t\t * can be received.\n+\t\t\t */\n+\t\t\tcvmx_update_rx_activity_led(xiface, index, false);\n+\t\t\tcvmx_update_rx_activity_led(xiface, index, false);\n+\t\t}\n+\t}\n+\n+\t/* Shutdown the PKO unit */\n+\tresult = cvmx_helper_pko3_shutdown(node);\n+\n+\t/* Release interface structures */\n+\t__cvmx_helper_shutdown_interfaces();\n+\n+\treturn result;\n+}\n+\n+/**\n+ * Undo the initialization performed in\n+ * cvmx_helper_initialize_packet_io_global(). After calling this routine and the\n+ * local version on each core, packet IO for Octeon will be disabled and placed\n+ * in the initial reset state. It will then be safe to call the initialize\n+ * later on. Note that this routine does not empty the FPA pools. It frees all\n+ * buffers used by the packet IO hardware to the FPA so a function emptying the\n+ * FPA after shutdown should find all packet buffers in the FPA.\n+ *\n+ * @return Zero on success, negative on failure.\n+ */\n+int cvmx_helper_shutdown_packet_io_global(void)\n+{\n+\tconst int timeout = 5; /* Wait up to 5 seconds for timeouts */\n+\tint result = 0;\n+\tint num_interfaces = cvmx_helper_get_number_of_interfaces();\n+\tint interface;\n+\tint num_ports;\n+\tint index;\n+\tstruct cvmx_buffer_list *pool0_buffers;\n+\tstruct cvmx_buffer_list *pool0_buffers_tail;\n+\tcvmx_wqe_t *work;\n+\tunion cvmx_ipd_ctl_status ipd_ctl_status;\n+\tint wqe_pool = (int)cvmx_fpa_get_wqe_pool();\n+\tint node = cvmx_get_node_num();\n+\tcvmx_pcsx_mrx_control_reg_t control_reg;\n+\n+\tif (octeon_has_feature(OCTEON_FEATURE_BGX))\n+\t\treturn cvmx_helper_shutdown_packet_io_global_cn78xx(node);\n+\n+\t/* Step 1: Disable all backpressure */\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tcvmx_helper_interface_mode_t mode =\n+\t\t\tcvmx_helper_interface_get_mode(interface);\n+\n+\t\tif (mode == CVMX_HELPER_INTERFACE_MODE_AGL)\n+\t\t\tcvmx_agl_set_backpressure_override(interface, 0x1);\n+\t\telse if (mode != CVMX_HELPER_INTERFACE_MODE_DISABLED)\n+\t\t\tcvmx_gmx_set_backpressure_override(interface, 0xf);\n+\t}\n+\n+\t/* Step 2: Wait for the PKO queues to drain */\n+\tresult = __cvmx_helper_pko_drain();\n+\tif (result < 0) {\n+\t\tdebug(\"WARNING: %s: Failed to drain some PKO queues\\n\",\n+\t\t __func__);\n+\t}\n+\n+\t/* Step 3: Disable TX and RX on all ports */\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node,\n+\t\t\t\t\t\t\t\t interface);\n+\n+\t\tswitch (cvmx_helper_interface_get_mode(interface)) {\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_DISABLED:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_PCIE:\n+\t\t\t/* Not a packet interface */\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_NPI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SRIO:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_ILK:\n+\t\t\t/*\n+\t\t\t * We don't handle the NPI/NPEI/SRIO packet\n+\t\t\t * engines. The caller must know these are\n+\t\t\t * idle.\n+\t\t\t */\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_LOOP:\n+\t\t\t/*\n+\t\t\t * Nothing needed. Once PKO is idle, the\n+\t\t\t * loopback devices must be idle.\n+\t\t\t */\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SPI:\n+\t\t\t/*\n+\t\t\t * SPI cannot be disabled from Octeon. It is\n+\t\t\t * the responsibility of the caller to make\n+\t\t\t * sure SPI is idle before doing shutdown.\n+\t\t\t *\n+\t\t\t * Fall through and do the same processing as\n+\t\t\t * RGMII/GMII.\n+\t\t\t */\n+\t\t\tfallthrough;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_GMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RGMII:\n+\t\t\t/* Disable outermost RX at the ASX block */\n+\t\t\tcsr_wr(CVMX_ASXX_RX_PRT_EN(interface), 0);\n+\t\t\tnum_ports = cvmx_helper_ports_on_interface(xiface);\n+\t\t\tif (num_ports > 4)\n+\t\t\t\tnum_ports = 4;\n+\t\t\tfor (index = 0; index < num_ports; index++) {\n+\t\t\t\tunion cvmx_gmxx_prtx_cfg gmx_cfg;\n+\n+\t\t\t\tif (!cvmx_helper_is_port_valid(interface, index))\n+\t\t\t\t\tcontinue;\n+\t\t\t\tgmx_cfg.u64 = csr_rd(CVMX_GMXX_PRTX_CFG(index, interface));\n+\t\t\t\tgmx_cfg.s.en = 0;\n+\t\t\t\tcsr_wr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);\n+\t\t\t\t/* Poll the GMX state machine waiting for it to become idle */\n+\t\t\t\tcsr_wr(CVMX_NPI_DBG_SELECT,\n+\t\t\t\t interface * 0x800 + index * 0x100 + 0x880);\n+\t\t\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data,\n+\t\t\t\t\t\t\t data & 7, ==, 0, timeout * 1000000)) {\n+\t\t\t\t\tdebug(\"GMX RX path timeout waiting for idle\\n\");\n+\t\t\t\t\tresult = -1;\n+\t\t\t\t}\n+\t\t\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data,\n+\t\t\t\t\t\t\t data & 0xf, ==, 0, timeout * 1000000)) {\n+\t\t\t\t\tdebug(\"GMX TX path timeout waiting for idle\\n\");\n+\t\t\t\t\tresult = -1;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\t/* Disable outermost TX at the ASX block */\n+\t\t\tcsr_wr(CVMX_ASXX_TX_PRT_EN(interface), 0);\n+\t\t\t/* Disable interrupts for interface */\n+\t\t\tcsr_wr(CVMX_ASXX_INT_EN(interface), 0);\n+\t\t\tcsr_wr(CVMX_GMXX_TX_INT_EN(interface), 0);\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RXAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_QSGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_PICMG:\n+\t\t\tnum_ports = cvmx_helper_ports_on_interface(xiface);\n+\t\t\tif (num_ports > 4)\n+\t\t\t\tnum_ports = 4;\n+\t\t\tfor (index = 0; index < num_ports; index++) {\n+\t\t\t\tunion cvmx_gmxx_prtx_cfg gmx_cfg;\n+\n+\t\t\t\tif (!cvmx_helper_is_port_valid(interface, index))\n+\t\t\t\t\tcontinue;\n+\t\t\t\tgmx_cfg.u64 = csr_rd(CVMX_GMXX_PRTX_CFG(index, interface));\n+\t\t\t\tgmx_cfg.s.en = 0;\n+\t\t\t\tcsr_wr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);\n+\t\t\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),\n+\t\t\t\t\t\t\t union cvmx_gmxx_prtx_cfg, rx_idle, ==, 1,\n+\t\t\t\t\t\t\t timeout * 1000000)) {\n+\t\t\t\t\tdebug(\"GMX RX path timeout waiting for idle\\n\");\n+\t\t\t\t\tresult = -1;\n+\t\t\t\t}\n+\t\t\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),\n+\t\t\t\t\t\t\t union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1,\n+\t\t\t\t\t\t\t timeout * 1000000)) {\n+\t\t\t\t\tdebug(\"GMX TX path timeout waiting for idle\\n\");\n+\t\t\t\t\tresult = -1;\n+\t\t\t\t}\n+\t\t\t\t/* For SGMII some PHYs require that the PCS\n+\t\t\t\t * interface be powered down and reset (i.e.\n+\t\t\t\t * Atheros/Qualcomm PHYs).\n+\t\t\t\t */\n+\t\t\t\tif (cvmx_helper_interface_get_mode(interface) ==\n+\t\t\t\t CVMX_HELPER_INTERFACE_MODE_SGMII) {\n+\t\t\t\t\tu64 reg;\n+\n+\t\t\t\t\treg = CVMX_PCSX_MRX_CONTROL_REG(index, interface);\n+\t\t\t\t\t/* Power down the interface */\n+\t\t\t\t\tcontrol_reg.u64 = csr_rd(reg);\n+\t\t\t\t\tcontrol_reg.s.pwr_dn = 1;\n+\t\t\t\t\tcsr_wr(reg, control_reg.u64);\n+\t\t\t\t\tcsr_rd(reg);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_AGL: {\n+\t\t\tint port = cvmx_helper_agl_get_port(interface);\n+\t\t\tunion cvmx_agl_gmx_prtx_cfg agl_gmx_cfg;\n+\n+\t\t\tagl_gmx_cfg.u64 = csr_rd(CVMX_AGL_GMX_PRTX_CFG(port));\n+\t\t\tagl_gmx_cfg.s.en = 0;\n+\t\t\tcsr_wr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_cfg.u64);\n+\t\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_AGL_GMX_PRTX_CFG(port),\n+\t\t\t\t\t\t union cvmx_agl_gmx_prtx_cfg, rx_idle, ==, 1,\n+\t\t\t\t\t\t timeout * 1000000)) {\n+\t\t\t\tdebug(\"AGL RX path timeout waiting for idle\\n\");\n+\t\t\t\tresult = -1;\n+\t\t\t}\n+\t\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_AGL_GMX_PRTX_CFG(port),\n+\t\t\t\t\t\t union cvmx_agl_gmx_prtx_cfg, tx_idle, ==, 1,\n+\t\t\t\t\t\t timeout * 1000000)) {\n+\t\t\t\tdebug(\"AGL TX path timeout waiting for idle\\n\");\n+\t\t\t\tresult = -1;\n+\t\t\t}\n+\t\t} break;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Step 4: Retrieve all packets from the POW and free them */\n+\twhile ((work = cvmx_pow_work_request_sync(CVMX_POW_WAIT))) {\n+\t\tcvmx_helper_free_packet_data(work);\n+\t\tcvmx_fpa1_free(work, wqe_pool, 0);\n+\t}\n+\n+\t/* Step 5 */\n+\tcvmx_ipd_disable();\n+\n+\t/*\n+\t * Step 6: Drain all prefetched buffers from IPD/PIP. Note that IPD/PIP\n+\t * have not been reset yet\n+\t */\n+\t__cvmx_ipd_free_ptr();\n+\n+\t/* Step 7: Free the PKO command buffers and put PKO in reset */\n+\tcvmx_pko_shutdown();\n+\n+\t/* Step 8: Disable MAC address filtering */\n+\tfor (interface = 0; interface < num_interfaces; interface++) {\n+\t\tint xiface = cvmx_helper_node_interface_to_xiface(node, interface);\n+\n+\t\tswitch (cvmx_helper_interface_get_mode(interface)) {\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_DISABLED:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_PCIE:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SRIO:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_ILK:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_NPI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_LOOP:\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_XAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RXAUI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_GMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_RGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SPI:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_SGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_QSGMII:\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_PICMG:\n+\t\t\tnum_ports = cvmx_helper_ports_on_interface(xiface);\n+\t\t\tif (num_ports > 4)\n+\t\t\t\tnum_ports = 4;\n+\t\t\tfor (index = 0; index < num_ports; index++) {\n+\t\t\t\tif (!cvmx_helper_is_port_valid(interface, index))\n+\t\t\t\t\tcontinue;\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CTL(index, interface), 1);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 0);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), 0);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), 0);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), 0);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), 0);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), 0);\n+\t\t\t\tcsr_wr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), 0);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase CVMX_HELPER_INTERFACE_MODE_AGL: {\n+\t\t\tint port = cvmx_helper_agl_get_port(interface);\n+\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CTL(port), 1);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), 0);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), 0);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), 0);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), 0);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), 0);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), 0);\n+\t\t\tcsr_wr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), 0);\n+\t\t} break;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Step 9: Drain all FPA buffers out of pool 0 before we reset\n+\t * IPD/PIP. This is needed to keep IPD_QUE0_FREE_PAGE_CNT in\n+\t * sync. We temporarily keep the buffers in the pool0_buffers\n+\t * list.\n+\t */\n+\tpool0_buffers = NULL;\n+\tpool0_buffers_tail = NULL;\n+\twhile (1) {\n+\t\tstruct cvmx_buffer_list *buffer = cvmx_fpa1_alloc(0);\n+\n+\t\tif (buffer) {\n+\t\t\tbuffer->next = NULL;\n+\n+\t\t\tif (!pool0_buffers)\n+\t\t\t\tpool0_buffers = buffer;\n+\t\t\telse\n+\t\t\t\tpool0_buffers_tail->next = buffer;\n+\n+\t\t\tpool0_buffers_tail = buffer;\n+\t\t} else {\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Step 10: Reset IPD and PIP */\n+\tipd_ctl_status.u64 = csr_rd(CVMX_IPD_CTL_STATUS);\n+\tipd_ctl_status.s.reset = 1;\n+\tcsr_wr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);\n+\n+\t/* Make sure IPD has finished reset. */\n+\tif (OCTEON_IS_OCTEON2() || OCTEON_IS_MODEL(OCTEON_CN70XX)) {\n+\t\tif (CVMX_WAIT_FOR_FIELD64(CVMX_IPD_CTL_STATUS, union cvmx_ipd_ctl_status, rst_done,\n+\t\t\t\t\t ==, 0, 1000)) {\n+\t\t\tdebug(\"IPD reset timeout waiting for idle\\n\");\n+\t\t\tresult = -1;\n+\t\t}\n+\t}\n+\n+\t/* Step 11: Restore the FPA buffers into pool 0 */\n+\twhile (pool0_buffers) {\n+\t\tstruct cvmx_buffer_list *n = pool0_buffers->next;\n+\n+\t\tcvmx_fpa1_free(pool0_buffers, 0, 0);\n+\t\tpool0_buffers = n;\n+\t}\n+\n+\t/* Step 12: Release interface structures */\n+\t__cvmx_helper_shutdown_interfaces();\n+\n+\treturn result;\n+}\n+\n+/**\n+ * Does core local shutdown of packet io\n+ *\n+ * @return Zero on success, non-zero on failure\n+ */\n+int cvmx_helper_shutdown_packet_io_local(void)\n+{\n+\t/*\n+\t * Currently there is nothing to do per core. This may change\n+\t * in the future.\n+\t */\n+\treturn 0;\n+}\n+\n+/**\n+ * Auto configure an IPD/PKO port link state and speed. This\n+ * function basically does the equivalent of:\n+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));\n+ *\n+ * @param xipd_port IPD/PKO port to auto configure\n+ *\n+ * @return Link state after configure\n+ */\n+cvmx_helper_link_info_t cvmx_helper_link_autoconf(int xipd_port)\n+{\n+\tcvmx_helper_link_info_t link_info;\n+\tint xiface = cvmx_helper_get_interface_num(xipd_port);\n+\tint index = cvmx_helper_get_interface_index_num(xipd_port);\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tint interface = xi.interface;\n+\n+\tif (interface == -1 || index == -1 || index >= cvmx_helper_ports_on_interface(xiface)) {\n+\t\tlink_info.u64 = 0;\n+\t\treturn link_info;\n+\t}\n+\n+\tlink_info = cvmx_helper_link_get(xipd_port);\n+\tif (link_info.u64 == (__cvmx_helper_get_link_info(xiface, index)).u64)\n+\t\treturn link_info;\n+\n+\tif (!link_info.s.link_up)\n+\t\tcvmx_error_disable_group(CVMX_ERROR_GROUP_ETHERNET, xipd_port);\n+\n+\t/* If we fail to set the link speed, port_link_info will not change */\n+\tcvmx_helper_link_set(xipd_port, link_info);\n+\n+\tif (link_info.s.link_up)\n+\t\tcvmx_error_enable_group(CVMX_ERROR_GROUP_ETHERNET, xipd_port);\n+\n+\treturn link_info;\n+}\n+\n+/**\n+ * Return the link state of an IPD/PKO port as returned by\n+ * auto negotiation. The result of this function may not match\n+ * Octeon's link config if auto negotiation has changed since\n+ * the last call to cvmx_helper_link_set().\n+ *\n+ * @param xipd_port IPD/PKO port to query\n+ *\n+ * @return Link state\n+ */\n+cvmx_helper_link_info_t cvmx_helper_link_get(int xipd_port)\n+{\n+\tcvmx_helper_link_info_t result;\n+\tint xiface = cvmx_helper_get_interface_num(xipd_port);\n+\tint index = cvmx_helper_get_interface_index_num(xipd_port);\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tstruct cvmx_fdt_sfp_info *sfp_info;\n+\n+\t/*\n+\t * The default result will be a down link unless the code\n+\t * below changes it.\n+\t */\n+\tresult.u64 = 0;\n+\n+\tif (__cvmx_helper_xiface_is_null(xiface) || index == -1 ||\n+\t index >= cvmx_helper_ports_on_interface(xiface)) {\n+\t\treturn result;\n+\t}\n+\n+\tif (iface_node_ops[xi.node][xi.interface]->link_get)\n+\t\tresult = iface_node_ops[xi.node][xi.interface]->link_get(xipd_port);\n+\n+\tif (xipd_port >= 0) {\n+\t\tcvmx_helper_update_link_led(xiface, index, result);\n+\n+\t\tsfp_info = cvmx_helper_cfg_get_sfp_info(xiface, index);\n+\n+\t\twhile (sfp_info) {\n+\t\t\tif ((!result.s.link_up || (result.s.link_up && sfp_info->last_mod_abs)))\n+\t\t\t\tcvmx_sfp_check_mod_abs(sfp_info, sfp_info->mod_abs_data);\n+\t\t\tsfp_info = sfp_info->next_iface_sfp;\n+\t\t}\n+\t}\n+\n+\treturn result;\n+}\n+\n+/**\n+ * Configure an IPD/PKO port for the specified link state. This\n+ * function does not influence auto negotiation at the PHY level.\n+ * The passed link state must always match the link state returned\n+ * by cvmx_helper_link_get(). It is normally best to use\n+ * cvmx_helper_link_autoconf() instead.\n+ *\n+ * @param xipd_port IPD/PKO port to configure\n+ * @param link_info The new link state\n+ *\n+ * @return Zero on success, negative on failure\n+ */\n+int cvmx_helper_link_set(int xipd_port, cvmx_helper_link_info_t link_info)\n+{\n+\tint result = -1;\n+\tint xiface = cvmx_helper_get_interface_num(xipd_port);\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tint index = cvmx_helper_get_interface_index_num(xipd_port);\n+\n+\tif (__cvmx_helper_xiface_is_null(xiface) || index == -1 ||\n+\t index >= cvmx_helper_ports_on_interface(xiface))\n+\t\treturn -1;\n+\n+\tif (iface_node_ops[xi.node][xi.interface]->link_set)\n+\t\tresult = iface_node_ops[xi.node][xi.interface]->link_set(xipd_port, link_info);\n+\n+\t/*\n+\t * Set the port_link_info here so that the link status is\n+\t * updated no matter how cvmx_helper_link_set is called. We\n+\t * don't change the value if link_set failed.\n+\t */\n+\tif (result == 0)\n+\t\t__cvmx_helper_set_link_info(xiface, index, link_info);\n+\treturn result;\n+}\n+\n+/**\n+ * Configure a port for internal and/or external loopback. Internal loopback\n+ * causes packets sent by the port to be received by Octeon. External loopback\n+ * causes packets received from the wire to sent out again.\n+ *\n+ * @param xipd_port IPD/PKO port to loopback.\n+ * @param enable_internal\n+ * Non zero if you want internal loopback\n+ * @param enable_external\n+ * Non zero if you want external loopback\n+ *\n+ * @return Zero on success, negative on failure.\n+ */\n+int cvmx_helper_configure_loopback(int xipd_port, int enable_internal, int enable_external)\n+{\n+\tint result = -1;\n+\tint xiface = cvmx_helper_get_interface_num(xipd_port);\n+\tstruct cvmx_xiface xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tint index = cvmx_helper_get_interface_index_num(xipd_port);\n+\n+\tif (index >= cvmx_helper_ports_on_interface(xiface))\n+\t\treturn -1;\n+\n+\tcvmx_helper_interface_get_mode(xiface);\n+\tif (iface_node_ops[xi.node][xi.interface]->loopback)\n+\t\tresult = iface_node_ops[xi.node][xi.interface]->loopback(xipd_port, enable_internal,\n+\t\t\t\t\t\t\t\t\t enable_external);\n+\n+\treturn result;\n+}\n+\n+void cvmx_helper_setup_simulator_io_buffer_counts(int node, int num_packet_buffers, int pko_buffers)\n+{\n+\tif (octeon_has_feature(OCTEON_FEATURE_PKI)) {\n+\t\tcvmx_helper_pki_set_dflt_pool_buffer(node, num_packet_buffers);\n+\t\tcvmx_helper_pki_set_dflt_aura_buffer(node, num_packet_buffers);\n+\n+\t} else {\n+\t\tcvmx_ipd_set_packet_pool_buffer_count(num_packet_buffers);\n+\t\tcvmx_ipd_set_wqe_pool_buffer_count(num_packet_buffers);\n+\t\tcvmx_pko_set_cmd_queue_pool_buffer_count(pko_buffers);\n+\t}\n+}\n+\n+void *cvmx_helper_mem_alloc(int node, uint64_t alloc_size, uint64_t align)\n+{\n+\ts64 paddr;\n+\n+\tpaddr = cvmx_bootmem_phy_alloc_range(alloc_size, align, cvmx_addr_on_node(node, 0ull),\n+\t\t\t\t\t cvmx_addr_on_node(node, 0xffffffffff));\n+\tif (paddr <= 0ll) {\n+\t\tprintf(\"ERROR: %s failed size %u\\n\", __func__, (unsigned int)alloc_size);\n+\t\treturn NULL;\n+\t}\n+\treturn cvmx_phys_to_ptr(paddr);\n+}\n+\n+void cvmx_helper_mem_free(void *buffer, uint64_t size)\n+{\n+\t__cvmx_bootmem_phy_free(cvmx_ptr_to_phys(buffer), size, 0);\n+}\n+\n+int cvmx_helper_qos_config_init(cvmx_qos_proto_t qos_proto, cvmx_qos_config_t *qos_cfg)\n+{\n+\tint i;\n+\n+\tmemset(qos_cfg, 0, sizeof(cvmx_qos_config_t));\n+\tqos_cfg->pkt_mode = CVMX_QOS_PKT_MODE_HWONLY; /* Process PAUSEs in hardware only.*/\n+\tqos_cfg->pool_mode = CVMX_QOS_POOL_PER_PORT; /* One Pool per BGX:LMAC.*/\n+\tqos_cfg->pktbuf_size = 2048;\t\t /* Fit WQE + MTU in one buffer.*/\n+\tqos_cfg->aura_size = 1024;\t/* 1K buffers typically enough for any application.*/\n+\tqos_cfg->pko_pfc_en = 1;\t/* Enable PKO layout for PFC feature. */\n+\tqos_cfg->vlan_num = 1;\t\t/* For Stacked VLAN, use 2nd VLAN in the QPG algorithm.*/\n+\tqos_cfg->qos_proto = qos_proto; /* Use PFC flow-control protocol.*/\n+\tqos_cfg->qpg_base = -1;\t\t/* QPG Table index is undefined.*/\n+\tqos_cfg->p_time = 0x60;\t\t/* PAUSE packets time window.*/\n+\tqos_cfg->p_interval = 0x10;\t/* PAUSE packets interval.*/\n+\tfor (i = 0; i < CVMX_QOS_NUM; i++) {\n+\t\tqos_cfg->groups[i] = i;\t /* SSO Groups = 0...7 */\n+\t\tqos_cfg->group_prio[i] = i; /* SSO Group priority = QOS. */\n+\t\tqos_cfg->drop_thresh[i] = 99; /* 99% of the Aura size.*/\n+\t\tqos_cfg->red_thresh[i] = 90; /* 90% of the Aura size.*/\n+\t\tqos_cfg->bp_thresh[i] = 70; /* 70% of the Aura size.*/\n+\t}\n+\treturn 0;\n+}\n+\n+int cvmx_helper_qos_port_config_update(int xipdport, cvmx_qos_config_t *qos_cfg)\n+{\n+\tcvmx_user_static_pko_queue_config_t pkocfg;\n+\tcvmx_xport_t xp = cvmx_helper_ipd_port_to_xport(xipdport);\n+\tint xiface = cvmx_helper_get_interface_num(xipdport);\n+\tcvmx_xiface_t xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\n+\t/* Configure PKO port for PFC SQ layout: */\n+\tcvmx_helper_pko_queue_config_get(xp.node, &pkocfg);\n+\tpkocfg.pknd.pko_cfg_iface[xi.interface].pfc_enable = 1;\n+\tcvmx_helper_pko_queue_config_set(xp.node, &pkocfg);\n+\treturn 0;\n+}\n+\n+int cvmx_helper_qos_port_setup(int xipdport, cvmx_qos_config_t *qos_cfg)\n+{\n+\tconst int channles = CVMX_QOS_NUM;\n+\tint bufsize = qos_cfg->pktbuf_size;\n+\tint aura_size = qos_cfg->aura_size;\n+\tcvmx_xport_t xp = cvmx_helper_ipd_port_to_xport(xipdport);\n+\tint node = xp.node;\n+\tint ipdport = xp.port;\n+\tint port = cvmx_helper_get_interface_index_num(xp.port);\n+\tint xiface = cvmx_helper_get_interface_num(xipdport);\n+\tcvmx_xiface_t xi = cvmx_helper_xiface_to_node_interface(xiface);\n+\tcvmx_fpa3_pool_t gpool;\n+\tcvmx_fpa3_gaura_t gaura;\n+\tcvmx_bgxx_cmr_rx_ovr_bp_t ovrbp;\n+\tstruct cvmx_pki_qpg_config qpgcfg;\n+\tstruct cvmx_pki_style_config stcfg, stcfg_dflt;\n+\tstruct cvmx_pki_pkind_config pkcfg;\n+\tint chan, bpid, group, qpg;\n+\tint bpen, reden, dropen, passthr, dropthr, bpthr;\n+\tint nbufs, pkind, style;\n+\tchar name[32];\n+\n+\tif (qos_cfg->pool_mode == CVMX_QOS_POOL_PER_PORT) {\n+\t\t/* Allocate and setup packet Pool: */\n+\t\tnbufs = aura_size * channles;\n+\t\tsprintf(name, \"QOS.P%d\", ipdport);\n+\t\tgpool = cvmx_fpa3_setup_fill_pool(node, -1 /*auto*/, name, bufsize, nbufs, NULL);\n+\t\tif (!__cvmx_fpa3_pool_valid(gpool)) {\n+\t\t\tprintf(\"%s: Failed to setup FPA Pool\\n\", __func__);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tfor (chan = 0; chan < channles; chan++)\n+\t\t\tqos_cfg->gpools[chan] = gpool;\n+\t} else {\n+\t\tprintf(\"%s: Invalid pool_mode %d\\n\", __func__, qos_cfg->pool_mode);\n+\t\treturn -1;\n+\t}\n+\t/* Allocate QPG entries: */\n+\tqos_cfg->qpg_base = cvmx_pki_qpg_entry_alloc(node, -1 /*auto*/, channles);\n+\tif (qos_cfg->qpg_base < 0) {\n+\t\tprintf(\"%s: Failed to allocate QPG entry\\n\", __func__);\n+\t\treturn -1;\n+\t}\n+\tfor (chan = 0; chan < channles; chan++) {\n+\t\t/* Allocate and setup Aura, setup BP threshold: */\n+\t\tgpool = qos_cfg->gpools[chan];\n+\t\tsprintf(name, \"QOS.A%d\", ipdport + chan);\n+\t\tgaura = cvmx_fpa3_set_aura_for_pool(gpool, -1 /*auto*/, name, bufsize, aura_size);\n+\t\tif (!__cvmx_fpa3_aura_valid(gaura)) {\n+\t\t\tprintf(\"%s: Failed to setup FPA Aura for Channel %d\\n\", __func__, chan);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tqos_cfg->gauras[chan] = gaura;\n+\t\tbpen = 1;\n+\t\treden = 1;\n+\t\tdropen = 1;\n+\t\tdropthr = (qos_cfg->drop_thresh[chan] * 10 * aura_size) / 1000;\n+\t\tpassthr = (qos_cfg->red_thresh[chan] * 10 * aura_size) / 1000;\n+\t\tbpthr = (qos_cfg->bp_thresh[chan] * 10 * aura_size) / 1000;\n+\t\tcvmx_fpa3_setup_aura_qos(gaura, reden, passthr, dropthr, bpen, bpthr);\n+\t\tcvmx_pki_enable_aura_qos(node, gaura.laura, reden, dropen, bpen);\n+\n+\t\t/* Allocate BPID, link Aura and Channel using BPID: */\n+\t\tbpid = cvmx_pki_bpid_alloc(node, -1 /*auto*/);\n+\t\tif (bpid < 0) {\n+\t\t\tprintf(\"%s: Failed to allocate BPID for channel %d\\n\",\n+\t\t\t __func__, chan);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tqos_cfg->bpids[chan] = bpid;\n+\t\tcvmx_pki_write_aura_bpid(node, gaura.laura, bpid);\n+\t\tcvmx_pki_write_channel_bpid(node, ipdport + chan, bpid);\n+\n+\t\t/* Setup QPG entries: */\n+\t\tgroup = qos_cfg->groups[chan];\n+\t\tqpg = qos_cfg->qpg_base + chan;\n+\t\tcvmx_pki_read_qpg_entry(node, qpg, &qpgcfg);\n+\t\tqpgcfg.port_add = chan;\n+\t\tqpgcfg.aura_num = gaura.laura;\n+\t\tqpgcfg.grp_ok = (node << CVMX_WQE_GRP_NODE_SHIFT) | group;\n+\t\tqpgcfg.grp_bad = (node << CVMX_WQE_GRP_NODE_SHIFT) | group;\n+\t\tqpgcfg.grptag_ok = (node << CVMX_WQE_GRP_NODE_SHIFT) | 0;\n+\t\tqpgcfg.grptag_bad = (node << CVMX_WQE_GRP_NODE_SHIFT) | 0;\n+\t\tcvmx_pki_write_qpg_entry(node, qpg, &qpgcfg);\n+\t}\n+\t/* Allocate and setup STYLE: */\n+\tcvmx_helper_pki_get_dflt_style(node, &stcfg_dflt);\n+\tstyle = cvmx_pki_style_alloc(node, -1 /*auto*/);\n+\tcvmx_pki_read_style_config(node, style, CVMX_PKI_CLUSTER_ALL, &stcfg);\n+\tstcfg.tag_cfg = stcfg_dflt.tag_cfg;\n+\tstcfg.parm_cfg.tag_type = CVMX_POW_TAG_TYPE_ORDERED;\n+\tstcfg.parm_cfg.qpg_qos = CVMX_PKI_QPG_QOS_VLAN;\n+\tstcfg.parm_cfg.qpg_base = qos_cfg->qpg_base;\n+\tstcfg.parm_cfg.qpg_port_msb = 0;\n+\tstcfg.parm_cfg.qpg_port_sh = 0;\n+\tstcfg.parm_cfg.qpg_dis_grptag = 1;\n+\tstcfg.parm_cfg.fcs_strip = 1;\n+\tstcfg.parm_cfg.mbuff_size = bufsize - 64; /* Do not use 100% of the buffer. */\n+\tstcfg.parm_cfg.force_drop = 0;\n+\tstcfg.parm_cfg.nodrop = 0;\n+\tstcfg.parm_cfg.rawdrp = 0;\n+\tstcfg.parm_cfg.cache_mode = 2; /* 1st buffer in L2 */\n+\tstcfg.parm_cfg.wqe_vs = qos_cfg->vlan_num;\n+\tcvmx_pki_write_style_config(node, style, CVMX_PKI_CLUSTER_ALL, &stcfg);\n+\n+\t/* Setup PKIND: */\n+\tpkind = cvmx_helper_get_pknd(xiface, port);\n+\tcvmx_pki_read_pkind_config(node, pkind, &pkcfg);\n+\tpkcfg.cluster_grp = 0; /* OCTEON3 has only one cluster group = 0 */\n+\tpkcfg.initial_style = style;\n+\tpkcfg.initial_parse_mode = CVMX_PKI_PARSE_LA_TO_LG;\n+\tcvmx_pki_write_pkind_config(node, pkind, &pkcfg);\n+\n+\t/* Setup parameters of the QOS packet and enable QOS flow-control: */\n+\tcvmx_bgx_set_pause_pkt_param(xipdport, 0, 0x0180c2000001, 0x8808, qos_cfg->p_time,\n+\t\t\t\t qos_cfg->p_interval);\n+\tcvmx_bgx_set_flowctl_mode(xipdport, qos_cfg->qos_proto, qos_cfg->pkt_mode);\n+\n+\t/* Enable PKI channel backpressure in the BGX: */\n+\tovrbp.u64 = csr_rd_node(node, CVMX_BGXX_CMR_RX_OVR_BP(xi.interface));\n+\tovrbp.s.en &= ~(1 << port);\n+\tovrbp.s.ign_fifo_bp &= ~(1 << port);\n+\tcsr_wr_node(node, CVMX_BGXX_CMR_RX_OVR_BP(xi.interface), ovrbp.u64);\n+\treturn 0;\n+}\n+\n+int cvmx_helper_qos_sso_setup(int xipdport, cvmx_qos_config_t *qos_cfg)\n+{\n+\tconst int channels = CVMX_QOS_NUM;\n+\tcvmx_sso_grpx_pri_t grppri;\n+\tint chan, qos, group;\n+\tcvmx_xport_t xp = cvmx_helper_ipd_port_to_xport(xipdport);\n+\tint node = xp.node;\n+\n+\tfor (chan = 0; chan < channels; chan++) {\n+\t\tqos = cvmx_helper_qos2prio(chan);\n+\t\tgroup = qos_cfg->groups[qos];\n+\t\tgrppri.u64 = csr_rd_node(node, CVMX_SSO_GRPX_PRI(group));\n+\t\tgrppri.s.pri = qos_cfg->group_prio[chan];\n+\t\tcsr_wr_node(node, CVMX_SSO_GRPX_PRI(group), grppri.u64);\n+\t}\n+\treturn 0;\n+}\n+\n+int cvmx_helper_get_chan_e_name(int chan, char *namebuf, int buflen)\n+{\n+\tint n, dpichans;\n+\n+\tif ((unsigned int)chan >= CVMX_PKO3_IPD_NUM_MAX) {\n+\t\tprintf(\"%s: Channel %d is out of range (0..4095)\\n\", __func__, chan);\n+\t\treturn -1;\n+\t}\n+\tif (OCTEON_IS_MODEL(OCTEON_CN78XX))\n+\t\tdpichans = 64;\n+\telse\n+\t\tdpichans = 128;\n+\n+\tif (chan >= 0 && chan < 64)\n+\t\tn = snprintf(namebuf, buflen, \"LBK%d\", chan);\n+\telse if (chan >= 0x100 && chan < (0x100 + dpichans))\n+\t\tn = snprintf(namebuf, buflen, \"DPI%d\", chan - 0x100);\n+\telse if (chan == 0x200)\n+\t\tn = snprintf(namebuf, buflen, \"NQM\");\n+\telse if (chan >= 0x240 && chan < (0x240 + (1 << 1) + 2))\n+\t\tn = snprintf(namebuf, buflen, \"SRIO%d:%d\", (chan - 0x240) >> 1,\n+\t\t\t (chan - 0x240) & 0x1);\n+\telse if (chan >= 0x400 && chan < (0x400 + (1 << 8) + 256))\n+\t\tn = snprintf(namebuf, buflen, \"ILK%d:%d\", (chan - 0x400) >> 8,\n+\t\t\t (chan - 0x400) & 0xFF);\n+\telse if (chan >= 0x800 && chan < (0x800 + (5 << 8) + (3 << 4) + 16))\n+\t\tn = snprintf(namebuf, buflen, \"BGX%d:%d:%d\", (chan - 0x800) >> 8,\n+\t\t\t ((chan - 0x800) >> 4) & 0x3, (chan - 0x800) & 0xF);\n+\telse\n+\t\tn = snprintf(namebuf, buflen, \"--\");\n+\treturn n;\n+}\n+\n+#ifdef CVMX_DUMP_DIAGNOSTICS\n+void cvmx_helper_dump_for_diagnostics(int node)\n+{\n+\tif (!(OCTEON_IS_OCTEON3() && !OCTEON_IS_MODEL(OCTEON_CN70XX))) {\n+\t\tprintf(\"Diagnostics are not implemented for this model\\n\");\n+\t\treturn;\n+\t}\n+#ifdef CVMX_DUMP_GSER\n+\t{\n+\t\tint qlm, num_qlms;\n+\n+\t\tnum_qlms = cvmx_qlm_get_num();\n+\t\tfor (qlm = 0; qlm < num_qlms; qlm++) {\n+\t\t\tcvmx_dump_gser_config_node(node, qlm);\n+\t\t\tcvmx_dump_gser_status_node(node, qlm);\n+\t\t}\n+\t}\n+#endif\n+#ifdef CVMX_DUMP_BGX\n+\t{\n+\t\tint bgx;\n+\n+\t\tfor (bgx = 0; bgx < CVMX_HELPER_MAX_GMX; bgx++) {\n+\t\t\tcvmx_dump_bgx_config_node(node, bgx);\n+\t\t\tcvmx_dump_bgx_status_node(node, bgx);\n+\t\t}\n+\t}\n+#endif\n+#ifdef CVMX_DUMP_PKI\n+\tcvmx_pki_config_dump(node);\n+\tcvmx_pki_stats_dump(node);\n+#endif\n+#ifdef CVMX_DUMP_PKO\n+\tcvmx_helper_pko3_config_dump(node);\n+\tcvmx_helper_pko3_stats_dump(node);\n+#endif\n+#ifdef CVMX_DUMO_SSO\n+\tcvmx_sso_config_dump(node);\n+#endif\n+}\n+#endif\n", "prefixes": [ "v1", "40/50" ] }